diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-09-22 12:31:08 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-09-22 12:31:08 -0400 |
commit | 3d98c21d064bfbb8c6fddc659471acb4950320fa (patch) | |
tree | a506fbe4cca3616f328cdf761a45d0a09ce38237 | |
parent | 99df18b31db389ec6abc8ad5415c14e7bb752b58 (diff) | |
parent | ddfb43f3881edb47aa0083651ad31983cdc42c33 (diff) |
Merge tag 'asoc-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v3.7
Lots and lots of driver specific cleanups and enhancements but the only
substantial framework feature this time round is the compressed API
binding:
- Addition of ASoC bindings for the compressed API, used by the mid-x86
drivers.
- Lots of cleanups and API refreshes for CODEC drivers and DaVinci.
- Conversion of OMAP to dmaengine.
- New machine driver for Wolfson Microelectronics Bells.
- New CODEC driver for Wolfson Microelectronics WM0010.
726 files changed, 10130 insertions, 5448 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci index 34f51100f029..dff1f48d252d 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci | |||
@@ -210,3 +210,15 @@ Users: | |||
210 | firmware assigned instance number of the PCI | 210 | firmware assigned instance number of the PCI |
211 | device that can help in understanding the firmware | 211 | device that can help in understanding the firmware |
212 | intended order of the PCI device. | 212 | intended order of the PCI device. |
213 | |||
214 | What: /sys/bus/pci/devices/.../d3cold_allowed | ||
215 | Date: July 2012 | ||
216 | Contact: Huang Ying <ying.huang@intel.com> | ||
217 | Description: | ||
218 | d3cold_allowed is bit to control whether the corresponding PCI | ||
219 | device can be put into D3Cold state. If it is cleared, the | ||
220 | device will never be put into D3Cold state. If it is set, the | ||
221 | device may be put into D3Cold state if other requirements are | ||
222 | satisfied too. Reading this attribute will show the current | ||
223 | value of d3cold_allowed bit. Writing this attribute will set | ||
224 | the value of d3cold_allowed bit. | ||
diff --git a/Documentation/devicetree/bindings/mfd/twl4030-audio.txt b/Documentation/devicetree/bindings/mfd/twl4030-audio.txt new file mode 100644 index 000000000000..414d2ae0adf6 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/twl4030-audio.txt | |||
@@ -0,0 +1,46 @@ | |||
1 | Texas Instruments TWL family (twl4030) audio module | ||
2 | |||
3 | The audio module inside the TWL family consist of an audio codec and a vibra | ||
4 | driver. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible : must be "ti,twl4030-audio" | ||
8 | |||
9 | Optional properties, nodes: | ||
10 | |||
11 | Audio functionality: | ||
12 | - codec { }: Need to be present if the audio functionality is used. Within this | ||
13 | section the following options can be used: | ||
14 | - ti,digimic_delay: Delay need after enabling the digimic to reduce artifacts | ||
15 | from the start of the recorded sample (in ms) | ||
16 | -ti,ramp_delay_value: HS ramp delay configuration to reduce pop noise | ||
17 | -ti,hs_extmute: Use external mute for HS pop reduction | ||
18 | -ti,hs_extmute_gpio: Use external GPIO to control the external mute | ||
19 | -ti,offset_cncl_path: Offset cancellation path selection, refer to TRM for the | ||
20 | valid values. | ||
21 | |||
22 | Vibra functionality | ||
23 | - ti,enable-vibra: Need to be set to <1> if the vibra functionality is used. if | ||
24 | missing or it is 0, the vibra functionality is disabled. | ||
25 | |||
26 | Example: | ||
27 | &i2c1 { | ||
28 | clock-frequency = <2600000>; | ||
29 | |||
30 | twl: twl@48 { | ||
31 | reg = <0x48>; | ||
32 | interrupts = <7>; /* SYS_NIRQ cascaded to intc */ | ||
33 | interrupt-parent = <&intc>; | ||
34 | |||
35 | twl_audio: audio { | ||
36 | compatible = "ti,twl4030-audio"; | ||
37 | |||
38 | ti,enable-vibra = <1>; | ||
39 | |||
40 | codec { | ||
41 | ti,ramp_delay_value = <3>; | ||
42 | }; | ||
43 | |||
44 | }; | ||
45 | }; | ||
46 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/cs4270.txt b/Documentation/devicetree/bindings/sound/cs4270.txt new file mode 100644 index 000000000000..6b222f9b8ef5 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/cs4270.txt | |||
@@ -0,0 +1,21 @@ | |||
1 | CS4270 audio CODEC | ||
2 | |||
3 | The driver for this device currently only supports I2C. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : "cirrus,cs4270" | ||
8 | |||
9 | - reg : the I2C address of the device for I2C | ||
10 | |||
11 | Optional properties: | ||
12 | |||
13 | - reset-gpio : a GPIO spec for the reset pin. If specified, it will be | ||
14 | deasserted before communication to the codec starts. | ||
15 | |||
16 | Example: | ||
17 | |||
18 | codec: cs4270@48 { | ||
19 | compatible = "cirrus,cs4270"; | ||
20 | reg = <0x48>; | ||
21 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt new file mode 100644 index 000000000000..374e145c2ef1 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt | |||
@@ -0,0 +1,45 @@ | |||
1 | Texas Instruments McASP controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : | ||
5 | "ti,dm646x-mcasp-audio" : for DM646x platforms | ||
6 | "ti,da830-mcasp-audio" : for both DA830 & DA850 platforms | ||
7 | "ti,omap2-mcasp-audio" : for OMAP2 platforms (TI81xx, AM33xx) | ||
8 | |||
9 | - reg : Should contain McASP registers offset and length | ||
10 | - interrupts : Interrupt number for McASP | ||
11 | - op-mode : I2S/DIT ops mode. | ||
12 | - tdm-slots : Slots for TDM operation. | ||
13 | - num-serializer : Serializers used by McASP. | ||
14 | - serial-dir : A list of serializer pin mode. The list number should be equal | ||
15 | to "num-serializer" parameter. Each entry is a number indication | ||
16 | serializer pin direction. (0 - INACTIVE, 1 - TX, 2 - RX) | ||
17 | |||
18 | |||
19 | Optional properties: | ||
20 | |||
21 | - ti,hwmods : Must be "mcasp<n>", n is controller instance starting 0 | ||
22 | - tx-num-evt : FIFO levels. | ||
23 | - rx-num-evt : FIFO levels. | ||
24 | - sram-size-playback : size of sram to be allocated during playback | ||
25 | - sram-size-capture : size of sram to be allocated during capture | ||
26 | |||
27 | Example: | ||
28 | |||
29 | mcasp0: mcasp0@1d00000 { | ||
30 | compatible = "ti,da830-mcasp-audio"; | ||
31 | #address-cells = <1>; | ||
32 | #size-cells = <0>; | ||
33 | reg = <0x100000 0x3000>; | ||
34 | interrupts = <82 83>; | ||
35 | op-mode = <0>; /* MCASP_IIS_MODE */ | ||
36 | tdm-slots = <2>; | ||
37 | num-serializer = <16>; | ||
38 | serial-dir = < | ||
39 | 0 0 0 0 /* 0: INACTIVE, 1: TX, 2: RX */ | ||
40 | 0 0 0 0 | ||
41 | 0 0 0 1 | ||
42 | 2 0 0 0 >; | ||
43 | tx-num-evt = <1>; | ||
44 | rx-num-evt = <1>; | ||
45 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt b/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt new file mode 100644 index 000000000000..65dec876cb2d --- /dev/null +++ b/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt | |||
@@ -0,0 +1,91 @@ | |||
1 | * Texas Instruments OMAP4+ and twl6040 based audio setups | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "ti,abe-twl6040" | ||
5 | - ti,model: Name of the sound card ( for example "SDP4430") | ||
6 | - ti,mclk-freq: MCLK frequency for HPPLL operation | ||
7 | - ti,mcpdm: phandle for the McPDM node | ||
8 | - ti,twl6040: phandle for the twl6040 core node | ||
9 | - ti,audio-routing: List of connections between audio components. | ||
10 | Each entry is a pair of strings, the first being the connection's sink, | ||
11 | the second being the connection's source. | ||
12 | |||
13 | Optional properties: | ||
14 | - ti,dmic: phandle for the OMAP dmic node if the machine have it connected | ||
15 | - ti,jack_detection: Need to be set to <1> if the board capable to detect jack | ||
16 | insertion, removal. | ||
17 | |||
18 | Available audio endpoints for the audio-routing table: | ||
19 | |||
20 | Board connectors: | ||
21 | * Headset Stereophone | ||
22 | * Earphone Spk | ||
23 | * Ext Spk | ||
24 | * Line Out | ||
25 | * Vibrator | ||
26 | * Headset Mic | ||
27 | * Main Handset Mic | ||
28 | * Sub Handset Mic | ||
29 | * Line In | ||
30 | * Digital Mic | ||
31 | |||
32 | twl6040 pins: | ||
33 | * HSOL | ||
34 | * HSOR | ||
35 | * EP | ||
36 | * HFL | ||
37 | * HFR | ||
38 | * AUXL | ||
39 | * AUXR | ||
40 | * VIBRAL | ||
41 | * VIBRAR | ||
42 | * HSMIC | ||
43 | * MAINMIC | ||
44 | * SUBMIC | ||
45 | * AFML | ||
46 | * AFMR | ||
47 | |||
48 | * Headset Mic Bias | ||
49 | * Main Mic Bias | ||
50 | * Digital Mic1 Bias | ||
51 | * Digital Mic2 Bias | ||
52 | |||
53 | Digital mic pins: | ||
54 | * DMic | ||
55 | |||
56 | Example: | ||
57 | |||
58 | sound { | ||
59 | compatible = "ti,abe-twl6040"; | ||
60 | ti,model = "SDP4430"; | ||
61 | |||
62 | ti,jack-detection = <1>; | ||
63 | ti,mclk-freq = <38400000>; | ||
64 | |||
65 | ti,mcpdm = <&mcpdm>; | ||
66 | ti,dmic = <&dmic>; | ||
67 | |||
68 | ti,twl6040 = <&twl6040>; | ||
69 | |||
70 | /* Audio routing */ | ||
71 | ti,audio-routing = | ||
72 | "Headset Stereophone", "HSOL", | ||
73 | "Headset Stereophone", "HSOR", | ||
74 | "Earphone Spk", "EP", | ||
75 | "Ext Spk", "HFL", | ||
76 | "Ext Spk", "HFR", | ||
77 | "Line Out", "AUXL", | ||
78 | "Line Out", "AUXR", | ||
79 | "Vibrator", "VIBRAL", | ||
80 | "Vibrator", "VIBRAR", | ||
81 | "HSMIC", "Headset Mic", | ||
82 | "Headset Mic", "Headset Mic Bias", | ||
83 | "MAINMIC", "Main Handset Mic", | ||
84 | "Main Handset Mic", "Main Mic Bias", | ||
85 | "SUBMIC", "Sub Handset Mic", | ||
86 | "Sub Handset Mic", "Main Mic Bias", | ||
87 | "AFML", "Line In", | ||
88 | "AFMR", "Line In", | ||
89 | "DMic", "Digital Mic", | ||
90 | "Digital Mic", "Digital Mic1 Bias"; | ||
91 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/omap-mcbsp.txt b/Documentation/devicetree/bindings/sound/omap-mcbsp.txt new file mode 100644 index 000000000000..17cce4490456 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/omap-mcbsp.txt | |||
@@ -0,0 +1,37 @@ | |||
1 | * Texas Instruments OMAP2+ McBSP module | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "ti,omap2420-mcbsp" for McBSP on OMAP2420 | ||
5 | "ti,omap2430-mcbsp" for McBSP on OMAP2430 | ||
6 | "ti,omap3-mcbsp" for McBSP on OMAP3 | ||
7 | "ti,omap4-mcbsp" for McBSP on OMAP4 and newer SoC | ||
8 | - reg: Register location and size, for OMAP4+ as an array: | ||
9 | <MPU access base address, size>, | ||
10 | <L3 interconnect address, size>; | ||
11 | - reg-names: Array of strings associated with the address space | ||
12 | - interrupts: Interrupt numbers for the McBSP port, as an array in case the | ||
13 | McBSP IP have more interrupt lines: | ||
14 | <OCP compliant irq>, | ||
15 | <TX irq>, | ||
16 | <RX irq>; | ||
17 | - interrupt-names: Array of strings associated with the interrupt numbers | ||
18 | - interrupt-parent: The parent interrupt controller | ||
19 | - ti,buffer-size: Size of the FIFO on the port (OMAP2430 and newer SoC) | ||
20 | - ti,hwmods: Name of the hwmod associated to the McBSP port | ||
21 | |||
22 | Example: | ||
23 | |||
24 | mcbsp2: mcbsp@49022000 { | ||
25 | compatible = "ti,omap3-mcbsp"; | ||
26 | reg = <0x49022000 0xff>, | ||
27 | <0x49028000 0xff>; | ||
28 | reg-names = "mpu", "sidetone"; | ||
29 | interrupts = <0 17 0x4>, /* OCP compliant interrupt */ | ||
30 | <0 62 0x4>, /* TX interrupt */ | ||
31 | <0 63 0x4>, /* RX interrupt */ | ||
32 | <0 4 0x4>; /* Sidetone */ | ||
33 | interrupt-names = "common", "tx", "rx", "sidetone"; | ||
34 | interrupt-parent = <&intc>; | ||
35 | ti,buffer-size = <1280>; | ||
36 | ti,hwmods = "mcbsp2"; | ||
37 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/omap-twl4030.txt b/Documentation/devicetree/bindings/sound/omap-twl4030.txt new file mode 100644 index 000000000000..6fae51c7f766 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/omap-twl4030.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | * Texas Instruments SoC with twl4030 based audio setups | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "ti,omap-twl4030" | ||
5 | - ti,model: Name of the sound card (for example "omap3beagle") | ||
6 | - ti,mcbsp: phandle for the McBSP node | ||
7 | - ti,codec: phandle for the twl4030 audio node | ||
8 | |||
9 | Example: | ||
10 | |||
11 | sound { | ||
12 | compatible = "ti,omap-twl4030"; | ||
13 | ti,model = "omap3beagle"; | ||
14 | |||
15 | ti,mcbsp = <&mcbsp2>; | ||
16 | ti,codec = <&twl_audio>; | ||
17 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt new file mode 100644 index 000000000000..e7b98f41fa5f --- /dev/null +++ b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt | |||
@@ -0,0 +1,20 @@ | |||
1 | Texas Instruments - tlv320aic3x Codec module | ||
2 | |||
3 | The tlv320aic3x serial control bus communicates through I2C protocols | ||
4 | |||
5 | Required properties: | ||
6 | - compatible - "string" - "ti,tlv320aic3x" | ||
7 | - reg - <int> - I2C slave address | ||
8 | |||
9 | |||
10 | Optional properties: | ||
11 | |||
12 | - gpio-reset - gpio pin number used for codec reset | ||
13 | - ai3x-gpio-func - <array of 2 int> - AIC3X_GPIO1 & AIC3X_GPIO2 Functionality | ||
14 | |||
15 | Example: | ||
16 | |||
17 | tlv320aic3x: tlv320aic3x@1b { | ||
18 | compatible = "ti,tlv320aic3x"; | ||
19 | reg = <0x1b>; | ||
20 | }; | ||
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index afaff312bf41..f4d8c7105fcd 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -579,7 +579,7 @@ Why: KVM tracepoints provide mostly equivalent information in a much more | |||
579 | ---------------------------- | 579 | ---------------------------- |
580 | 580 | ||
581 | What: at91-mci driver ("CONFIG_MMC_AT91") | 581 | What: at91-mci driver ("CONFIG_MMC_AT91") |
582 | When: 3.7 | 582 | When: 3.8 |
583 | Why: There are two mci drivers: at91-mci and atmel-mci. The PDC support | 583 | Why: There are two mci drivers: at91-mci and atmel-mci. The PDC support |
584 | was added to atmel-mci as a first step to support more chips. | 584 | was added to atmel-mci as a first step to support more chips. |
585 | Then at91-mci was kept only for old IP versions (on at91rm9200 and | 585 | Then at91-mci was kept only for old IP versions (on at91rm9200 and |
diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801 index 615142da4ef6..157416e78cc4 100644 --- a/Documentation/i2c/busses/i2c-i801 +++ b/Documentation/i2c/busses/i2c-i801 | |||
@@ -21,6 +21,7 @@ Supported adapters: | |||
21 | * Intel DH89xxCC (PCH) | 21 | * Intel DH89xxCC (PCH) |
22 | * Intel Panther Point (PCH) | 22 | * Intel Panther Point (PCH) |
23 | * Intel Lynx Point (PCH) | 23 | * Intel Lynx Point (PCH) |
24 | * Intel Lynx Point-LP (PCH) | ||
24 | Datasheets: Publicly available at the Intel website | 25 | Datasheets: Publicly available at the Intel website |
25 | 26 | ||
26 | On Intel Patsburg and later chipsets, both the normal host SMBus controller | 27 | On Intel Patsburg and later chipsets, both the normal host SMBus controller |
diff --git a/MAINTAINERS b/MAINTAINERS index fdc0119963e7..53cc13c82cb1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -3388,7 +3388,7 @@ M: "Wolfram Sang (embedded platforms)" <w.sang@pengutronix.de> | |||
3388 | L: linux-i2c@vger.kernel.org | 3388 | L: linux-i2c@vger.kernel.org |
3389 | W: http://i2c.wiki.kernel.org/ | 3389 | W: http://i2c.wiki.kernel.org/ |
3390 | T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/ | 3390 | T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/ |
3391 | T: git git://git.fluff.org/bjdooks/linux.git | 3391 | T: git git://git.pengutronix.de/git/wsa/linux.git |
3392 | S: Maintained | 3392 | S: Maintained |
3393 | F: Documentation/i2c/ | 3393 | F: Documentation/i2c/ |
3394 | F: drivers/i2c/ | 3394 | F: drivers/i2c/ |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 3 | 1 | VERSION = 3 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = -rc3 | 4 | EXTRAVERSION = -rc6 |
5 | NAME = Saber-toothed Squirrel | 5 | NAME = Saber-toothed Squirrel |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c5f9ae5dbd1a..2f88d8d97701 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -6,7 +6,7 @@ config ARM | |||
6 | select HAVE_DMA_API_DEBUG | 6 | select HAVE_DMA_API_DEBUG |
7 | select HAVE_IDE if PCI || ISA || PCMCIA | 7 | select HAVE_IDE if PCI || ISA || PCMCIA |
8 | select HAVE_DMA_ATTRS | 8 | select HAVE_DMA_ATTRS |
9 | select HAVE_DMA_CONTIGUOUS if (CPU_V6 || CPU_V6K || CPU_V7) | 9 | select HAVE_DMA_CONTIGUOUS if MMU |
10 | select HAVE_MEMBLOCK | 10 | select HAVE_MEMBLOCK |
11 | select RTC_LIB | 11 | select RTC_LIB |
12 | select SYS_SUPPORTS_APM_EMULATION | 12 | select SYS_SUPPORTS_APM_EMULATION |
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index f15f82bf3a50..e968a52e4881 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
@@ -356,15 +356,15 @@ choice | |||
356 | is nothing connected to read from the DCC. | 356 | is nothing connected to read from the DCC. |
357 | 357 | ||
358 | config DEBUG_SEMIHOSTING | 358 | config DEBUG_SEMIHOSTING |
359 | bool "Kernel low-level debug output via semihosting I" | 359 | bool "Kernel low-level debug output via semihosting I/O" |
360 | help | 360 | help |
361 | Semihosting enables code running on an ARM target to use | 361 | Semihosting enables code running on an ARM target to use |
362 | the I/O facilities on a host debugger/emulator through a | 362 | the I/O facilities on a host debugger/emulator through a |
363 | simple SVC calls. The host debugger or emulator must have | 363 | simple SVC call. The host debugger or emulator must have |
364 | semihosting enabled for the special svc call to be trapped | 364 | semihosting enabled for the special svc call to be trapped |
365 | otherwise the kernel will crash. | 365 | otherwise the kernel will crash. |
366 | 366 | ||
367 | This is known to work with OpenOCD, as wellas | 367 | This is known to work with OpenOCD, as well as |
368 | ARM's Fast Models, or any other controlling environment | 368 | ARM's Fast Models, or any other controlling environment |
369 | that implements semihosting. | 369 | that implements semihosting. |
370 | 370 | ||
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 30eae87ead6d..a051dfbdd7db 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
@@ -284,10 +284,10 @@ zImage Image xipImage bootpImage uImage: vmlinux | |||
284 | zinstall uinstall install: vmlinux | 284 | zinstall uinstall install: vmlinux |
285 | $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ | 285 | $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ |
286 | 286 | ||
287 | %.dtb: | 287 | %.dtb: scripts |
288 | $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ | 288 | $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ |
289 | 289 | ||
290 | dtbs: | 290 | dtbs: scripts |
291 | $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ | 291 | $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ |
292 | 292 | ||
293 | # We use MRPROPER_FILES and CLEAN_FILES now | 293 | # We use MRPROPER_FILES and CLEAN_FILES now |
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index b8c64b80bafc..81769c1341fa 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
@@ -659,10 +659,14 @@ __armv7_mmu_cache_on: | |||
659 | #ifdef CONFIG_CPU_ENDIAN_BE8 | 659 | #ifdef CONFIG_CPU_ENDIAN_BE8 |
660 | orr r0, r0, #1 << 25 @ big-endian page tables | 660 | orr r0, r0, #1 << 25 @ big-endian page tables |
661 | #endif | 661 | #endif |
662 | mrcne p15, 0, r6, c2, c0, 2 @ read ttb control reg | ||
662 | orrne r0, r0, #1 @ MMU enabled | 663 | orrne r0, r0, #1 @ MMU enabled |
663 | movne r1, #0xfffffffd @ domain 0 = client | 664 | movne r1, #0xfffffffd @ domain 0 = client |
665 | bic r6, r6, #1 << 31 @ 32-bit translation system | ||
666 | bic r6, r6, #3 << 0 @ use only ttbr0 | ||
664 | mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer | 667 | mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer |
665 | mcrne p15, 0, r1, c3, c0, 0 @ load domain access control | 668 | mcrne p15, 0, r1, c3, c0, 0 @ load domain access control |
669 | mcrne p15, 0, r6, c2, c0, 2 @ load ttb control | ||
666 | #endif | 670 | #endif |
667 | mcr p15, 0, r0, c7, c5, 4 @ ISB | 671 | mcr p15, 0, r0, c7, c5, 4 @ ISB |
668 | mcr p15, 0, r0, c1, c0, 0 @ load control register | 672 | mcr p15, 0, r0, c1, c0, 0 @ load control register |
diff --git a/arch/arm/boot/dts/at91sam9g25ek.dts b/arch/arm/boot/dts/at91sam9g25ek.dts index 7829a4d0cb22..96514c134e54 100644 --- a/arch/arm/boot/dts/at91sam9g25ek.dts +++ b/arch/arm/boot/dts/at91sam9g25ek.dts | |||
@@ -15,7 +15,7 @@ | |||
15 | compatible = "atmel,at91sam9g25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; | 15 | compatible = "atmel,at91sam9g25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; |
16 | 16 | ||
17 | chosen { | 17 | chosen { |
18 | bootargs = "128M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs"; | 18 | bootargs = "console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs"; |
19 | }; | 19 | }; |
20 | 20 | ||
21 | ahb { | 21 | ahb { |
diff --git a/arch/arm/configs/armadillo800eva_defconfig b/arch/arm/configs/armadillo800eva_defconfig index 7d8718468e0d..90610c7030f7 100644 --- a/arch/arm/configs/armadillo800eva_defconfig +++ b/arch/arm/configs/armadillo800eva_defconfig | |||
@@ -33,7 +33,7 @@ CONFIG_AEABI=y | |||
33 | CONFIG_FORCE_MAX_ZONEORDER=13 | 33 | CONFIG_FORCE_MAX_ZONEORDER=13 |
34 | CONFIG_ZBOOT_ROM_TEXT=0x0 | 34 | CONFIG_ZBOOT_ROM_TEXT=0x0 |
35 | CONFIG_ZBOOT_ROM_BSS=0x0 | 35 | CONFIG_ZBOOT_ROM_BSS=0x0 |
36 | CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 earlyprintk=sh-sci.1,115200 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096" | 36 | CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 earlyprintk=sh-sci.1,115200 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096 rw" |
37 | CONFIG_CMDLINE_FORCE=y | 37 | CONFIG_CMDLINE_FORCE=y |
38 | CONFIG_KEXEC=y | 38 | CONFIG_KEXEC=y |
39 | CONFIG_VFP=y | 39 | CONFIG_VFP=y |
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 03fb93621d0d..5c8b3bf4d825 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h | |||
@@ -320,4 +320,12 @@ | |||
320 | .size \name , . - \name | 320 | .size \name , . - \name |
321 | .endm | 321 | .endm |
322 | 322 | ||
323 | .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req | ||
324 | #ifndef CONFIG_CPU_USE_DOMAINS | ||
325 | adds \tmp, \addr, #\size - 1 | ||
326 | sbcccs \tmp, \tmp, \limit | ||
327 | bcs \bad | ||
328 | #endif | ||
329 | .endm | ||
330 | |||
323 | #endif /* __ASM_ASSEMBLER_H__ */ | 331 | #endif /* __ASM_ASSEMBLER_H__ */ |
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index 2ae842df4551..5c44dcb0987b 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h | |||
@@ -203,6 +203,13 @@ static inline void dma_free_writecombine(struct device *dev, size_t size, | |||
203 | } | 203 | } |
204 | 204 | ||
205 | /* | 205 | /* |
206 | * This can be called during early boot to increase the size of the atomic | ||
207 | * coherent DMA pool above the default value of 256KiB. It must be called | ||
208 | * before postcore_initcall. | ||
209 | */ | ||
210 | extern void __init init_dma_coherent_pool_size(unsigned long size); | ||
211 | |||
212 | /* | ||
206 | * This can be called during boot to increase the size of the consistent | 213 | * This can be called during boot to increase the size of the consistent |
207 | * DMA region above it's default value of 2MB. It must be called before the | 214 | * DMA region above it's default value of 2MB. It must be called before the |
208 | * memory allocator is initialised, i.e. before any core_initcall. | 215 | * memory allocator is initialised, i.e. before any core_initcall. |
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index e965f1b560f1..5f6ddcc56452 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h | |||
@@ -187,6 +187,7 @@ static inline unsigned long __phys_to_virt(unsigned long x) | |||
187 | #define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET) | 187 | #define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET) |
188 | #endif | 188 | #endif |
189 | #endif | 189 | #endif |
190 | #endif /* __ASSEMBLY__ */ | ||
190 | 191 | ||
191 | #ifndef PHYS_OFFSET | 192 | #ifndef PHYS_OFFSET |
192 | #ifdef PLAT_PHYS_OFFSET | 193 | #ifdef PLAT_PHYS_OFFSET |
@@ -196,6 +197,8 @@ static inline unsigned long __phys_to_virt(unsigned long x) | |||
196 | #endif | 197 | #endif |
197 | #endif | 198 | #endif |
198 | 199 | ||
200 | #ifndef __ASSEMBLY__ | ||
201 | |||
199 | /* | 202 | /* |
200 | * PFNs are used to describe any physical page; this means | 203 | * PFNs are used to describe any physical page; this means |
201 | * PFN 0 == physical address 0. | 204 | * PFN 0 == physical address 0. |
diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h index 314d4664eae7..99a19512ee26 100644 --- a/arch/arm/include/asm/tlb.h +++ b/arch/arm/include/asm/tlb.h | |||
@@ -199,6 +199,9 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, | |||
199 | { | 199 | { |
200 | pgtable_page_dtor(pte); | 200 | pgtable_page_dtor(pte); |
201 | 201 | ||
202 | #ifdef CONFIG_ARM_LPAE | ||
203 | tlb_add_flush(tlb, addr); | ||
204 | #else | ||
202 | /* | 205 | /* |
203 | * With the classic ARM MMU, a pte page has two corresponding pmd | 206 | * With the classic ARM MMU, a pte page has two corresponding pmd |
204 | * entries, each covering 1MB. | 207 | * entries, each covering 1MB. |
@@ -206,6 +209,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, | |||
206 | addr &= PMD_MASK; | 209 | addr &= PMD_MASK; |
207 | tlb_add_flush(tlb, addr + SZ_1M - PAGE_SIZE); | 210 | tlb_add_flush(tlb, addr + SZ_1M - PAGE_SIZE); |
208 | tlb_add_flush(tlb, addr + SZ_1M); | 211 | tlb_add_flush(tlb, addr + SZ_1M); |
212 | #endif | ||
209 | 213 | ||
210 | tlb_remove_page(tlb, pte); | 214 | tlb_remove_page(tlb, pte); |
211 | } | 215 | } |
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index 479a6352e0b5..77bd79f2ffdb 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h | |||
@@ -101,28 +101,39 @@ extern int __get_user_1(void *); | |||
101 | extern int __get_user_2(void *); | 101 | extern int __get_user_2(void *); |
102 | extern int __get_user_4(void *); | 102 | extern int __get_user_4(void *); |
103 | 103 | ||
104 | #define __get_user_x(__r2,__p,__e,__s,__i...) \ | 104 | #define __GUP_CLOBBER_1 "lr", "cc" |
105 | #ifdef CONFIG_CPU_USE_DOMAINS | ||
106 | #define __GUP_CLOBBER_2 "ip", "lr", "cc" | ||
107 | #else | ||
108 | #define __GUP_CLOBBER_2 "lr", "cc" | ||
109 | #endif | ||
110 | #define __GUP_CLOBBER_4 "lr", "cc" | ||
111 | |||
112 | #define __get_user_x(__r2,__p,__e,__l,__s) \ | ||
105 | __asm__ __volatile__ ( \ | 113 | __asm__ __volatile__ ( \ |
106 | __asmeq("%0", "r0") __asmeq("%1", "r2") \ | 114 | __asmeq("%0", "r0") __asmeq("%1", "r2") \ |
115 | __asmeq("%3", "r1") \ | ||
107 | "bl __get_user_" #__s \ | 116 | "bl __get_user_" #__s \ |
108 | : "=&r" (__e), "=r" (__r2) \ | 117 | : "=&r" (__e), "=r" (__r2) \ |
109 | : "0" (__p) \ | 118 | : "0" (__p), "r" (__l) \ |
110 | : __i, "cc") | 119 | : __GUP_CLOBBER_##__s) |
111 | 120 | ||
112 | #define get_user(x,p) \ | 121 | #define __get_user_check(x,p) \ |
113 | ({ \ | 122 | ({ \ |
123 | unsigned long __limit = current_thread_info()->addr_limit - 1; \ | ||
114 | register const typeof(*(p)) __user *__p asm("r0") = (p);\ | 124 | register const typeof(*(p)) __user *__p asm("r0") = (p);\ |
115 | register unsigned long __r2 asm("r2"); \ | 125 | register unsigned long __r2 asm("r2"); \ |
126 | register unsigned long __l asm("r1") = __limit; \ | ||
116 | register int __e asm("r0"); \ | 127 | register int __e asm("r0"); \ |
117 | switch (sizeof(*(__p))) { \ | 128 | switch (sizeof(*(__p))) { \ |
118 | case 1: \ | 129 | case 1: \ |
119 | __get_user_x(__r2, __p, __e, 1, "lr"); \ | 130 | __get_user_x(__r2, __p, __e, __l, 1); \ |
120 | break; \ | 131 | break; \ |
121 | case 2: \ | 132 | case 2: \ |
122 | __get_user_x(__r2, __p, __e, 2, "r3", "lr"); \ | 133 | __get_user_x(__r2, __p, __e, __l, 2); \ |
123 | break; \ | 134 | break; \ |
124 | case 4: \ | 135 | case 4: \ |
125 | __get_user_x(__r2, __p, __e, 4, "lr"); \ | 136 | __get_user_x(__r2, __p, __e, __l, 4); \ |
126 | break; \ | 137 | break; \ |
127 | default: __e = __get_user_bad(); break; \ | 138 | default: __e = __get_user_bad(); break; \ |
128 | } \ | 139 | } \ |
@@ -130,42 +141,57 @@ extern int __get_user_4(void *); | |||
130 | __e; \ | 141 | __e; \ |
131 | }) | 142 | }) |
132 | 143 | ||
144 | #define get_user(x,p) \ | ||
145 | ({ \ | ||
146 | might_fault(); \ | ||
147 | __get_user_check(x,p); \ | ||
148 | }) | ||
149 | |||
133 | extern int __put_user_1(void *, unsigned int); | 150 | extern int __put_user_1(void *, unsigned int); |
134 | extern int __put_user_2(void *, unsigned int); | 151 | extern int __put_user_2(void *, unsigned int); |
135 | extern int __put_user_4(void *, unsigned int); | 152 | extern int __put_user_4(void *, unsigned int); |
136 | extern int __put_user_8(void *, unsigned long long); | 153 | extern int __put_user_8(void *, unsigned long long); |
137 | 154 | ||
138 | #define __put_user_x(__r2,__p,__e,__s) \ | 155 | #define __put_user_x(__r2,__p,__e,__l,__s) \ |
139 | __asm__ __volatile__ ( \ | 156 | __asm__ __volatile__ ( \ |
140 | __asmeq("%0", "r0") __asmeq("%2", "r2") \ | 157 | __asmeq("%0", "r0") __asmeq("%2", "r2") \ |
158 | __asmeq("%3", "r1") \ | ||
141 | "bl __put_user_" #__s \ | 159 | "bl __put_user_" #__s \ |
142 | : "=&r" (__e) \ | 160 | : "=&r" (__e) \ |
143 | : "0" (__p), "r" (__r2) \ | 161 | : "0" (__p), "r" (__r2), "r" (__l) \ |
144 | : "ip", "lr", "cc") | 162 | : "ip", "lr", "cc") |
145 | 163 | ||
146 | #define put_user(x,p) \ | 164 | #define __put_user_check(x,p) \ |
147 | ({ \ | 165 | ({ \ |
166 | unsigned long __limit = current_thread_info()->addr_limit - 1; \ | ||
148 | register const typeof(*(p)) __r2 asm("r2") = (x); \ | 167 | register const typeof(*(p)) __r2 asm("r2") = (x); \ |
149 | register const typeof(*(p)) __user *__p asm("r0") = (p);\ | 168 | register const typeof(*(p)) __user *__p asm("r0") = (p);\ |
169 | register unsigned long __l asm("r1") = __limit; \ | ||
150 | register int __e asm("r0"); \ | 170 | register int __e asm("r0"); \ |
151 | switch (sizeof(*(__p))) { \ | 171 | switch (sizeof(*(__p))) { \ |
152 | case 1: \ | 172 | case 1: \ |
153 | __put_user_x(__r2, __p, __e, 1); \ | 173 | __put_user_x(__r2, __p, __e, __l, 1); \ |
154 | break; \ | 174 | break; \ |
155 | case 2: \ | 175 | case 2: \ |
156 | __put_user_x(__r2, __p, __e, 2); \ | 176 | __put_user_x(__r2, __p, __e, __l, 2); \ |
157 | break; \ | 177 | break; \ |
158 | case 4: \ | 178 | case 4: \ |
159 | __put_user_x(__r2, __p, __e, 4); \ | 179 | __put_user_x(__r2, __p, __e, __l, 4); \ |
160 | break; \ | 180 | break; \ |
161 | case 8: \ | 181 | case 8: \ |
162 | __put_user_x(__r2, __p, __e, 8); \ | 182 | __put_user_x(__r2, __p, __e, __l, 8); \ |
163 | break; \ | 183 | break; \ |
164 | default: __e = __put_user_bad(); break; \ | 184 | default: __e = __put_user_bad(); break; \ |
165 | } \ | 185 | } \ |
166 | __e; \ | 186 | __e; \ |
167 | }) | 187 | }) |
168 | 188 | ||
189 | #define put_user(x,p) \ | ||
190 | ({ \ | ||
191 | might_fault(); \ | ||
192 | __put_user_check(x,p); \ | ||
193 | }) | ||
194 | |||
169 | #else /* CONFIG_MMU */ | 195 | #else /* CONFIG_MMU */ |
170 | 196 | ||
171 | /* | 197 | /* |
@@ -219,6 +245,7 @@ do { \ | |||
219 | unsigned long __gu_addr = (unsigned long)(ptr); \ | 245 | unsigned long __gu_addr = (unsigned long)(ptr); \ |
220 | unsigned long __gu_val; \ | 246 | unsigned long __gu_val; \ |
221 | __chk_user_ptr(ptr); \ | 247 | __chk_user_ptr(ptr); \ |
248 | might_fault(); \ | ||
222 | switch (sizeof(*(ptr))) { \ | 249 | switch (sizeof(*(ptr))) { \ |
223 | case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \ | 250 | case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \ |
224 | case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \ | 251 | case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \ |
@@ -300,6 +327,7 @@ do { \ | |||
300 | unsigned long __pu_addr = (unsigned long)(ptr); \ | 327 | unsigned long __pu_addr = (unsigned long)(ptr); \ |
301 | __typeof__(*(ptr)) __pu_val = (x); \ | 328 | __typeof__(*(ptr)) __pu_val = (x); \ |
302 | __chk_user_ptr(ptr); \ | 329 | __chk_user_ptr(ptr); \ |
330 | might_fault(); \ | ||
303 | switch (sizeof(*(ptr))) { \ | 331 | switch (sizeof(*(ptr))) { \ |
304 | case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \ | 332 | case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \ |
305 | case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \ | 333 | case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \ |
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index ba386bd94107..281bf3301241 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c | |||
@@ -159,6 +159,12 @@ static int debug_arch_supported(void) | |||
159 | arch >= ARM_DEBUG_ARCH_V7_1; | 159 | arch >= ARM_DEBUG_ARCH_V7_1; |
160 | } | 160 | } |
161 | 161 | ||
162 | /* Can we determine the watchpoint access type from the fsr? */ | ||
163 | static int debug_exception_updates_fsr(void) | ||
164 | { | ||
165 | return 0; | ||
166 | } | ||
167 | |||
162 | /* Determine number of WRP registers available. */ | 168 | /* Determine number of WRP registers available. */ |
163 | static int get_num_wrp_resources(void) | 169 | static int get_num_wrp_resources(void) |
164 | { | 170 | { |
@@ -604,13 +610,14 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) | |||
604 | /* Aligned */ | 610 | /* Aligned */ |
605 | break; | 611 | break; |
606 | case 1: | 612 | case 1: |
607 | /* Allow single byte watchpoint. */ | ||
608 | if (info->ctrl.len == ARM_BREAKPOINT_LEN_1) | ||
609 | break; | ||
610 | case 2: | 613 | case 2: |
611 | /* Allow halfword watchpoints and breakpoints. */ | 614 | /* Allow halfword watchpoints and breakpoints. */ |
612 | if (info->ctrl.len == ARM_BREAKPOINT_LEN_2) | 615 | if (info->ctrl.len == ARM_BREAKPOINT_LEN_2) |
613 | break; | 616 | break; |
617 | case 3: | ||
618 | /* Allow single byte watchpoint. */ | ||
619 | if (info->ctrl.len == ARM_BREAKPOINT_LEN_1) | ||
620 | break; | ||
614 | default: | 621 | default: |
615 | ret = -EINVAL; | 622 | ret = -EINVAL; |
616 | goto out; | 623 | goto out; |
@@ -619,18 +626,35 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) | |||
619 | info->address &= ~alignment_mask; | 626 | info->address &= ~alignment_mask; |
620 | info->ctrl.len <<= offset; | 627 | info->ctrl.len <<= offset; |
621 | 628 | ||
622 | /* | 629 | if (!bp->overflow_handler) { |
623 | * Currently we rely on an overflow handler to take | 630 | /* |
624 | * care of single-stepping the breakpoint when it fires. | 631 | * Mismatch breakpoints are required for single-stepping |
625 | * In the case of userspace breakpoints on a core with V7 debug, | 632 | * breakpoints. |
626 | * we can use the mismatch feature as a poor-man's hardware | 633 | */ |
627 | * single-step, but this only works for per-task breakpoints. | 634 | if (!core_has_mismatch_brps()) |
628 | */ | 635 | return -EINVAL; |
629 | if (!bp->overflow_handler && (arch_check_bp_in_kernelspace(bp) || | 636 | |
630 | !core_has_mismatch_brps() || !bp->hw.bp_target)) { | 637 | /* We don't allow mismatch breakpoints in kernel space. */ |
631 | pr_warning("overflow handler required but none found\n"); | 638 | if (arch_check_bp_in_kernelspace(bp)) |
632 | ret = -EINVAL; | 639 | return -EPERM; |
640 | |||
641 | /* | ||
642 | * Per-cpu breakpoints are not supported by our stepping | ||
643 | * mechanism. | ||
644 | */ | ||
645 | if (!bp->hw.bp_target) | ||
646 | return -EINVAL; | ||
647 | |||
648 | /* | ||
649 | * We only support specific access types if the fsr | ||
650 | * reports them. | ||
651 | */ | ||
652 | if (!debug_exception_updates_fsr() && | ||
653 | (info->ctrl.type == ARM_BREAKPOINT_LOAD || | ||
654 | info->ctrl.type == ARM_BREAKPOINT_STORE)) | ||
655 | return -EINVAL; | ||
633 | } | 656 | } |
657 | |||
634 | out: | 658 | out: |
635 | return ret; | 659 | return ret; |
636 | } | 660 | } |
@@ -706,10 +730,12 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr, | |||
706 | goto unlock; | 730 | goto unlock; |
707 | 731 | ||
708 | /* Check that the access type matches. */ | 732 | /* Check that the access type matches. */ |
709 | access = (fsr & ARM_FSR_ACCESS_MASK) ? HW_BREAKPOINT_W : | 733 | if (debug_exception_updates_fsr()) { |
710 | HW_BREAKPOINT_R; | 734 | access = (fsr & ARM_FSR_ACCESS_MASK) ? |
711 | if (!(access & hw_breakpoint_type(wp))) | 735 | HW_BREAKPOINT_W : HW_BREAKPOINT_R; |
712 | goto unlock; | 736 | if (!(access & hw_breakpoint_type(wp))) |
737 | goto unlock; | ||
738 | } | ||
713 | 739 | ||
714 | /* We have a winner. */ | 740 | /* We have a winner. */ |
715 | info->trigger = addr; | 741 | info->trigger = addr; |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index f7945218b8c6..b0179b89a04c 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -420,20 +420,23 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) | |||
420 | #endif | 420 | #endif |
421 | instr = *(u32 *) pc; | 421 | instr = *(u32 *) pc; |
422 | } else if (thumb_mode(regs)) { | 422 | } else if (thumb_mode(regs)) { |
423 | get_user(instr, (u16 __user *)pc); | 423 | if (get_user(instr, (u16 __user *)pc)) |
424 | goto die_sig; | ||
424 | if (is_wide_instruction(instr)) { | 425 | if (is_wide_instruction(instr)) { |
425 | unsigned int instr2; | 426 | unsigned int instr2; |
426 | get_user(instr2, (u16 __user *)pc+1); | 427 | if (get_user(instr2, (u16 __user *)pc+1)) |
428 | goto die_sig; | ||
427 | instr <<= 16; | 429 | instr <<= 16; |
428 | instr |= instr2; | 430 | instr |= instr2; |
429 | } | 431 | } |
430 | } else { | 432 | } else if (get_user(instr, (u32 __user *)pc)) { |
431 | get_user(instr, (u32 __user *)pc); | 433 | goto die_sig; |
432 | } | 434 | } |
433 | 435 | ||
434 | if (call_undef_hook(regs, instr) == 0) | 436 | if (call_undef_hook(regs, instr) == 0) |
435 | return; | 437 | return; |
436 | 438 | ||
439 | die_sig: | ||
437 | #ifdef CONFIG_DEBUG_USER | 440 | #ifdef CONFIG_DEBUG_USER |
438 | if (user_debug & UDBG_UNDEFINED) { | 441 | if (user_debug & UDBG_UNDEFINED) { |
439 | printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n", | 442 | printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n", |
diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c index d6dacc69254e..395d5fbb8fa2 100644 --- a/arch/arm/lib/delay.c +++ b/arch/arm/lib/delay.c | |||
@@ -59,6 +59,7 @@ void __init init_current_timer_delay(unsigned long freq) | |||
59 | { | 59 | { |
60 | pr_info("Switching to timer-based delay loop\n"); | 60 | pr_info("Switching to timer-based delay loop\n"); |
61 | lpj_fine = freq / HZ; | 61 | lpj_fine = freq / HZ; |
62 | loops_per_jiffy = lpj_fine; | ||
62 | arm_delay_ops.delay = __timer_delay; | 63 | arm_delay_ops.delay = __timer_delay; |
63 | arm_delay_ops.const_udelay = __timer_const_udelay; | 64 | arm_delay_ops.const_udelay = __timer_const_udelay; |
64 | arm_delay_ops.udelay = __timer_udelay; | 65 | arm_delay_ops.udelay = __timer_udelay; |
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S index 11093a7c3e32..9b06bb41fca6 100644 --- a/arch/arm/lib/getuser.S +++ b/arch/arm/lib/getuser.S | |||
@@ -16,8 +16,9 @@ | |||
16 | * __get_user_X | 16 | * __get_user_X |
17 | * | 17 | * |
18 | * Inputs: r0 contains the address | 18 | * Inputs: r0 contains the address |
19 | * r1 contains the address limit, which must be preserved | ||
19 | * Outputs: r0 is the error code | 20 | * Outputs: r0 is the error code |
20 | * r2, r3 contains the zero-extended value | 21 | * r2 contains the zero-extended value |
21 | * lr corrupted | 22 | * lr corrupted |
22 | * | 23 | * |
23 | * No other registers must be altered. (see <asm/uaccess.h> | 24 | * No other registers must be altered. (see <asm/uaccess.h> |
@@ -27,33 +28,39 @@ | |||
27 | * Note also that it is intended that __get_user_bad is not global. | 28 | * Note also that it is intended that __get_user_bad is not global. |
28 | */ | 29 | */ |
29 | #include <linux/linkage.h> | 30 | #include <linux/linkage.h> |
31 | #include <asm/assembler.h> | ||
30 | #include <asm/errno.h> | 32 | #include <asm/errno.h> |
31 | #include <asm/domain.h> | 33 | #include <asm/domain.h> |
32 | 34 | ||
33 | ENTRY(__get_user_1) | 35 | ENTRY(__get_user_1) |
36 | check_uaccess r0, 1, r1, r2, __get_user_bad | ||
34 | 1: TUSER(ldrb) r2, [r0] | 37 | 1: TUSER(ldrb) r2, [r0] |
35 | mov r0, #0 | 38 | mov r0, #0 |
36 | mov pc, lr | 39 | mov pc, lr |
37 | ENDPROC(__get_user_1) | 40 | ENDPROC(__get_user_1) |
38 | 41 | ||
39 | ENTRY(__get_user_2) | 42 | ENTRY(__get_user_2) |
40 | #ifdef CONFIG_THUMB2_KERNEL | 43 | check_uaccess r0, 2, r1, r2, __get_user_bad |
41 | 2: TUSER(ldrb) r2, [r0] | 44 | #ifdef CONFIG_CPU_USE_DOMAINS |
42 | 3: TUSER(ldrb) r3, [r0, #1] | 45 | rb .req ip |
46 | 2: ldrbt r2, [r0], #1 | ||
47 | 3: ldrbt rb, [r0], #0 | ||
43 | #else | 48 | #else |
44 | 2: TUSER(ldrb) r2, [r0], #1 | 49 | rb .req r0 |
45 | 3: TUSER(ldrb) r3, [r0] | 50 | 2: ldrb r2, [r0] |
51 | 3: ldrb rb, [r0, #1] | ||
46 | #endif | 52 | #endif |
47 | #ifndef __ARMEB__ | 53 | #ifndef __ARMEB__ |
48 | orr r2, r2, r3, lsl #8 | 54 | orr r2, r2, rb, lsl #8 |
49 | #else | 55 | #else |
50 | orr r2, r3, r2, lsl #8 | 56 | orr r2, rb, r2, lsl #8 |
51 | #endif | 57 | #endif |
52 | mov r0, #0 | 58 | mov r0, #0 |
53 | mov pc, lr | 59 | mov pc, lr |
54 | ENDPROC(__get_user_2) | 60 | ENDPROC(__get_user_2) |
55 | 61 | ||
56 | ENTRY(__get_user_4) | 62 | ENTRY(__get_user_4) |
63 | check_uaccess r0, 4, r1, r2, __get_user_bad | ||
57 | 4: TUSER(ldr) r2, [r0] | 64 | 4: TUSER(ldr) r2, [r0] |
58 | mov r0, #0 | 65 | mov r0, #0 |
59 | mov pc, lr | 66 | mov pc, lr |
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S index 7db25990c589..3d73dcb959b0 100644 --- a/arch/arm/lib/putuser.S +++ b/arch/arm/lib/putuser.S | |||
@@ -16,6 +16,7 @@ | |||
16 | * __put_user_X | 16 | * __put_user_X |
17 | * | 17 | * |
18 | * Inputs: r0 contains the address | 18 | * Inputs: r0 contains the address |
19 | * r1 contains the address limit, which must be preserved | ||
19 | * r2, r3 contains the value | 20 | * r2, r3 contains the value |
20 | * Outputs: r0 is the error code | 21 | * Outputs: r0 is the error code |
21 | * lr corrupted | 22 | * lr corrupted |
@@ -27,16 +28,19 @@ | |||
27 | * Note also that it is intended that __put_user_bad is not global. | 28 | * Note also that it is intended that __put_user_bad is not global. |
28 | */ | 29 | */ |
29 | #include <linux/linkage.h> | 30 | #include <linux/linkage.h> |
31 | #include <asm/assembler.h> | ||
30 | #include <asm/errno.h> | 32 | #include <asm/errno.h> |
31 | #include <asm/domain.h> | 33 | #include <asm/domain.h> |
32 | 34 | ||
33 | ENTRY(__put_user_1) | 35 | ENTRY(__put_user_1) |
36 | check_uaccess r0, 1, r1, ip, __put_user_bad | ||
34 | 1: TUSER(strb) r2, [r0] | 37 | 1: TUSER(strb) r2, [r0] |
35 | mov r0, #0 | 38 | mov r0, #0 |
36 | mov pc, lr | 39 | mov pc, lr |
37 | ENDPROC(__put_user_1) | 40 | ENDPROC(__put_user_1) |
38 | 41 | ||
39 | ENTRY(__put_user_2) | 42 | ENTRY(__put_user_2) |
43 | check_uaccess r0, 2, r1, ip, __put_user_bad | ||
40 | mov ip, r2, lsr #8 | 44 | mov ip, r2, lsr #8 |
41 | #ifdef CONFIG_THUMB2_KERNEL | 45 | #ifdef CONFIG_THUMB2_KERNEL |
42 | #ifndef __ARMEB__ | 46 | #ifndef __ARMEB__ |
@@ -60,12 +64,14 @@ ENTRY(__put_user_2) | |||
60 | ENDPROC(__put_user_2) | 64 | ENDPROC(__put_user_2) |
61 | 65 | ||
62 | ENTRY(__put_user_4) | 66 | ENTRY(__put_user_4) |
67 | check_uaccess r0, 4, r1, ip, __put_user_bad | ||
63 | 4: TUSER(str) r2, [r0] | 68 | 4: TUSER(str) r2, [r0] |
64 | mov r0, #0 | 69 | mov r0, #0 |
65 | mov pc, lr | 70 | mov pc, lr |
66 | ENDPROC(__put_user_4) | 71 | ENDPROC(__put_user_4) |
67 | 72 | ||
68 | ENTRY(__put_user_8) | 73 | ENTRY(__put_user_8) |
74 | check_uaccess r0, 8, r1, ip, __put_user_bad | ||
69 | #ifdef CONFIG_THUMB2_KERNEL | 75 | #ifdef CONFIG_THUMB2_KERNEL |
70 | 5: TUSER(str) r2, [r0] | 76 | 5: TUSER(str) r2, [r0] |
71 | 6: TUSER(str) r3, [r0, #4] | 77 | 6: TUSER(str) r3, [r0, #4] |
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c index 104ca40d8d18..aaa443b48c91 100644 --- a/arch/arm/mach-at91/at91rm9200_time.c +++ b/arch/arm/mach-at91/at91rm9200_time.c | |||
@@ -197,7 +197,7 @@ void __init at91rm9200_timer_init(void) | |||
197 | at91_st_read(AT91_ST_SR); | 197 | at91_st_read(AT91_ST_SR); |
198 | 198 | ||
199 | /* Make IRQs happen for the system timer */ | 199 | /* Make IRQs happen for the system timer */ |
200 | setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq); | 200 | setup_irq(NR_IRQS_LEGACY + AT91_ID_SYS, &at91rm9200_timer_irq); |
201 | 201 | ||
202 | /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used | 202 | /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used |
203 | * directly for the clocksource and all clockevents, after adjusting | 203 | * directly for the clocksource and all clockevents, after adjusting |
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 7b9c2ba396ed..bce572a530ef 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c | |||
@@ -726,6 +726,8 @@ static struct resource rtt_resources[] = { | |||
726 | .flags = IORESOURCE_MEM, | 726 | .flags = IORESOURCE_MEM, |
727 | }, { | 727 | }, { |
728 | .flags = IORESOURCE_MEM, | 728 | .flags = IORESOURCE_MEM, |
729 | }, { | ||
730 | .flags = IORESOURCE_IRQ, | ||
729 | }, | 731 | }, |
730 | }; | 732 | }; |
731 | 733 | ||
@@ -744,10 +746,12 @@ static void __init at91_add_device_rtt_rtc(void) | |||
744 | * The second resource is needed: | 746 | * The second resource is needed: |
745 | * GPBR will serve as the storage for RTC time offset | 747 | * GPBR will serve as the storage for RTC time offset |
746 | */ | 748 | */ |
747 | at91sam9260_rtt_device.num_resources = 2; | 749 | at91sam9260_rtt_device.num_resources = 3; |
748 | rtt_resources[1].start = AT91SAM9260_BASE_GPBR + | 750 | rtt_resources[1].start = AT91SAM9260_BASE_GPBR + |
749 | 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; | 751 | 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; |
750 | rtt_resources[1].end = rtt_resources[1].start + 3; | 752 | rtt_resources[1].end = rtt_resources[1].start + 3; |
753 | rtt_resources[2].start = NR_IRQS_LEGACY + AT91_ID_SYS; | ||
754 | rtt_resources[2].end = NR_IRQS_LEGACY + AT91_ID_SYS; | ||
751 | } | 755 | } |
752 | #else | 756 | #else |
753 | static void __init at91_add_device_rtt_rtc(void) | 757 | static void __init at91_add_device_rtt_rtc(void) |
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 8df5c1bdff92..bc2590d712d0 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c | |||
@@ -609,6 +609,8 @@ static struct resource rtt_resources[] = { | |||
609 | .flags = IORESOURCE_MEM, | 609 | .flags = IORESOURCE_MEM, |
610 | }, { | 610 | }, { |
611 | .flags = IORESOURCE_MEM, | 611 | .flags = IORESOURCE_MEM, |
612 | }, { | ||
613 | .flags = IORESOURCE_IRQ, | ||
612 | } | 614 | } |
613 | }; | 615 | }; |
614 | 616 | ||
@@ -626,10 +628,12 @@ static void __init at91_add_device_rtt_rtc(void) | |||
626 | * The second resource is needed: | 628 | * The second resource is needed: |
627 | * GPBR will serve as the storage for RTC time offset | 629 | * GPBR will serve as the storage for RTC time offset |
628 | */ | 630 | */ |
629 | at91sam9261_rtt_device.num_resources = 2; | 631 | at91sam9261_rtt_device.num_resources = 3; |
630 | rtt_resources[1].start = AT91SAM9261_BASE_GPBR + | 632 | rtt_resources[1].start = AT91SAM9261_BASE_GPBR + |
631 | 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; | 633 | 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; |
632 | rtt_resources[1].end = rtt_resources[1].start + 3; | 634 | rtt_resources[1].end = rtt_resources[1].start + 3; |
635 | rtt_resources[2].start = NR_IRQS_LEGACY + AT91_ID_SYS; | ||
636 | rtt_resources[2].end = NR_IRQS_LEGACY + AT91_ID_SYS; | ||
633 | } | 637 | } |
634 | #else | 638 | #else |
635 | static void __init at91_add_device_rtt_rtc(void) | 639 | static void __init at91_add_device_rtt_rtc(void) |
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index eb6bbf86fb9f..9b6ca734f1a9 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c | |||
@@ -990,6 +990,8 @@ static struct resource rtt0_resources[] = { | |||
990 | .flags = IORESOURCE_MEM, | 990 | .flags = IORESOURCE_MEM, |
991 | }, { | 991 | }, { |
992 | .flags = IORESOURCE_MEM, | 992 | .flags = IORESOURCE_MEM, |
993 | }, { | ||
994 | .flags = IORESOURCE_IRQ, | ||
993 | } | 995 | } |
994 | }; | 996 | }; |
995 | 997 | ||
@@ -1006,6 +1008,8 @@ static struct resource rtt1_resources[] = { | |||
1006 | .flags = IORESOURCE_MEM, | 1008 | .flags = IORESOURCE_MEM, |
1007 | }, { | 1009 | }, { |
1008 | .flags = IORESOURCE_MEM, | 1010 | .flags = IORESOURCE_MEM, |
1011 | }, { | ||
1012 | .flags = IORESOURCE_IRQ, | ||
1009 | } | 1013 | } |
1010 | }; | 1014 | }; |
1011 | 1015 | ||
@@ -1027,14 +1031,14 @@ static void __init at91_add_device_rtt_rtc(void) | |||
1027 | * The second resource is needed only for the chosen RTT: | 1031 | * The second resource is needed only for the chosen RTT: |
1028 | * GPBR will serve as the storage for RTC time offset | 1032 | * GPBR will serve as the storage for RTC time offset |
1029 | */ | 1033 | */ |
1030 | at91sam9263_rtt0_device.num_resources = 2; | 1034 | at91sam9263_rtt0_device.num_resources = 3; |
1031 | at91sam9263_rtt1_device.num_resources = 1; | 1035 | at91sam9263_rtt1_device.num_resources = 1; |
1032 | pdev = &at91sam9263_rtt0_device; | 1036 | pdev = &at91sam9263_rtt0_device; |
1033 | r = rtt0_resources; | 1037 | r = rtt0_resources; |
1034 | break; | 1038 | break; |
1035 | case 1: | 1039 | case 1: |
1036 | at91sam9263_rtt0_device.num_resources = 1; | 1040 | at91sam9263_rtt0_device.num_resources = 1; |
1037 | at91sam9263_rtt1_device.num_resources = 2; | 1041 | at91sam9263_rtt1_device.num_resources = 3; |
1038 | pdev = &at91sam9263_rtt1_device; | 1042 | pdev = &at91sam9263_rtt1_device; |
1039 | r = rtt1_resources; | 1043 | r = rtt1_resources; |
1040 | break; | 1044 | break; |
@@ -1047,6 +1051,8 @@ static void __init at91_add_device_rtt_rtc(void) | |||
1047 | pdev->name = "rtc-at91sam9"; | 1051 | pdev->name = "rtc-at91sam9"; |
1048 | r[1].start = AT91SAM9263_BASE_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; | 1052 | r[1].start = AT91SAM9263_BASE_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; |
1049 | r[1].end = r[1].start + 3; | 1053 | r[1].end = r[1].start + 3; |
1054 | r[2].start = NR_IRQS_LEGACY + AT91_ID_SYS; | ||
1055 | r[2].end = NR_IRQS_LEGACY + AT91_ID_SYS; | ||
1050 | } | 1056 | } |
1051 | #else | 1057 | #else |
1052 | static void __init at91_add_device_rtt_rtc(void) | 1058 | static void __init at91_add_device_rtt_rtc(void) |
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 06073996a382..1b47319ca00b 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c | |||
@@ -1293,6 +1293,8 @@ static struct resource rtt_resources[] = { | |||
1293 | .flags = IORESOURCE_MEM, | 1293 | .flags = IORESOURCE_MEM, |
1294 | }, { | 1294 | }, { |
1295 | .flags = IORESOURCE_MEM, | 1295 | .flags = IORESOURCE_MEM, |
1296 | }, { | ||
1297 | .flags = IORESOURCE_IRQ, | ||
1296 | } | 1298 | } |
1297 | }; | 1299 | }; |
1298 | 1300 | ||
@@ -1310,10 +1312,12 @@ static void __init at91_add_device_rtt_rtc(void) | |||
1310 | * The second resource is needed: | 1312 | * The second resource is needed: |
1311 | * GPBR will serve as the storage for RTC time offset | 1313 | * GPBR will serve as the storage for RTC time offset |
1312 | */ | 1314 | */ |
1313 | at91sam9g45_rtt_device.num_resources = 2; | 1315 | at91sam9g45_rtt_device.num_resources = 3; |
1314 | rtt_resources[1].start = AT91SAM9G45_BASE_GPBR + | 1316 | rtt_resources[1].start = AT91SAM9G45_BASE_GPBR + |
1315 | 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; | 1317 | 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; |
1316 | rtt_resources[1].end = rtt_resources[1].start + 3; | 1318 | rtt_resources[1].end = rtt_resources[1].start + 3; |
1319 | rtt_resources[2].start = NR_IRQS_LEGACY + AT91_ID_SYS; | ||
1320 | rtt_resources[2].end = NR_IRQS_LEGACY + AT91_ID_SYS; | ||
1317 | } | 1321 | } |
1318 | #else | 1322 | #else |
1319 | static void __init at91_add_device_rtt_rtc(void) | 1323 | static void __init at91_add_device_rtt_rtc(void) |
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index f09fff932172..b3d365dadef5 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c | |||
@@ -688,6 +688,8 @@ static struct resource rtt_resources[] = { | |||
688 | .flags = IORESOURCE_MEM, | 688 | .flags = IORESOURCE_MEM, |
689 | }, { | 689 | }, { |
690 | .flags = IORESOURCE_MEM, | 690 | .flags = IORESOURCE_MEM, |
691 | }, { | ||
692 | .flags = IORESOURCE_IRQ, | ||
691 | } | 693 | } |
692 | }; | 694 | }; |
693 | 695 | ||
@@ -705,10 +707,12 @@ static void __init at91_add_device_rtt_rtc(void) | |||
705 | * The second resource is needed: | 707 | * The second resource is needed: |
706 | * GPBR will serve as the storage for RTC time offset | 708 | * GPBR will serve as the storage for RTC time offset |
707 | */ | 709 | */ |
708 | at91sam9rl_rtt_device.num_resources = 2; | 710 | at91sam9rl_rtt_device.num_resources = 3; |
709 | rtt_resources[1].start = AT91SAM9RL_BASE_GPBR + | 711 | rtt_resources[1].start = AT91SAM9RL_BASE_GPBR + |
710 | 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; | 712 | 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; |
711 | rtt_resources[1].end = rtt_resources[1].start + 3; | 713 | rtt_resources[1].end = rtt_resources[1].start + 3; |
714 | rtt_resources[2].start = NR_IRQS_LEGACY + AT91_ID_SYS; | ||
715 | rtt_resources[2].end = NR_IRQS_LEGACY + AT91_ID_SYS; | ||
712 | } | 716 | } |
713 | #else | 717 | #else |
714 | static void __init at91_add_device_rtt_rtc(void) | 718 | static void __init at91_add_device_rtt_rtc(void) |
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index de2ec6b8fea7..188c82971ebd 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c | |||
@@ -63,6 +63,12 @@ EXPORT_SYMBOL_GPL(at91_pmc_base); | |||
63 | 63 | ||
64 | #define cpu_has_300M_plla() (cpu_is_at91sam9g10()) | 64 | #define cpu_has_300M_plla() (cpu_is_at91sam9g10()) |
65 | 65 | ||
66 | #define cpu_has_240M_plla() (cpu_is_at91sam9261() \ | ||
67 | || cpu_is_at91sam9263() \ | ||
68 | || cpu_is_at91sam9rl()) | ||
69 | |||
70 | #define cpu_has_210M_plla() (cpu_is_at91sam9260()) | ||
71 | |||
66 | #define cpu_has_pllb() (!(cpu_is_at91sam9rl() \ | 72 | #define cpu_has_pllb() (!(cpu_is_at91sam9rl() \ |
67 | || cpu_is_at91sam9g45() \ | 73 | || cpu_is_at91sam9g45() \ |
68 | || cpu_is_at91sam9x5() \ | 74 | || cpu_is_at91sam9x5() \ |
@@ -706,6 +712,12 @@ static int __init at91_pmc_init(unsigned long main_clock) | |||
706 | } else if (cpu_has_800M_plla()) { | 712 | } else if (cpu_has_800M_plla()) { |
707 | if (plla.rate_hz > 800000000) | 713 | if (plla.rate_hz > 800000000) |
708 | pll_overclock = true; | 714 | pll_overclock = true; |
715 | } else if (cpu_has_240M_plla()) { | ||
716 | if (plla.rate_hz > 240000000) | ||
717 | pll_overclock = true; | ||
718 | } else if (cpu_has_210M_plla()) { | ||
719 | if (plla.rate_hz > 210000000) | ||
720 | pll_overclock = true; | ||
709 | } else { | 721 | } else { |
710 | if (plla.rate_hz > 209000000) | 722 | if (plla.rate_hz > 209000000) |
711 | pll_overclock = true; | 723 | pll_overclock = true; |
diff --git a/arch/arm/mach-davinci/asp.h b/arch/arm/mach-davinci/asp.h new file mode 100644 index 000000000000..d9b2acd12393 --- /dev/null +++ b/arch/arm/mach-davinci/asp.h | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * TI DaVinci Audio definitions | ||
3 | */ | ||
4 | #ifndef __ASM_ARCH_DAVINCI_ASP_H | ||
5 | #define __ASM_ARCH_DAVINCI_ASP_H | ||
6 | |||
7 | /* Bases of dm644x and dm355 register banks */ | ||
8 | #define DAVINCI_ASP0_BASE 0x01E02000 | ||
9 | #define DAVINCI_ASP1_BASE 0x01E04000 | ||
10 | |||
11 | /* Bases of dm365 register banks */ | ||
12 | #define DAVINCI_DM365_ASP0_BASE 0x01D02000 | ||
13 | |||
14 | /* Bases of dm646x register banks */ | ||
15 | #define DAVINCI_DM646X_MCASP0_REG_BASE 0x01D01000 | ||
16 | #define DAVINCI_DM646X_MCASP1_REG_BASE 0x01D01800 | ||
17 | |||
18 | /* Bases of da850/da830 McASP0 register banks */ | ||
19 | #define DAVINCI_DA8XX_MCASP0_REG_BASE 0x01D00000 | ||
20 | |||
21 | /* Bases of da830 McASP1 register banks */ | ||
22 | #define DAVINCI_DA830_MCASP1_REG_BASE 0x01D04000 | ||
23 | |||
24 | /* EDMA channels of dm644x and dm355 */ | ||
25 | #define DAVINCI_DMA_ASP0_TX 2 | ||
26 | #define DAVINCI_DMA_ASP0_RX 3 | ||
27 | #define DAVINCI_DMA_ASP1_TX 8 | ||
28 | #define DAVINCI_DMA_ASP1_RX 9 | ||
29 | |||
30 | /* EDMA channels of dm646x */ | ||
31 | #define DAVINCI_DM646X_DMA_MCASP0_AXEVT0 6 | ||
32 | #define DAVINCI_DM646X_DMA_MCASP0_AREVT0 9 | ||
33 | #define DAVINCI_DM646X_DMA_MCASP1_AXEVT1 12 | ||
34 | |||
35 | /* EDMA channels of da850/da830 McASP0 */ | ||
36 | #define DAVINCI_DA8XX_DMA_MCASP0_AREVT 0 | ||
37 | #define DAVINCI_DA8XX_DMA_MCASP0_AXEVT 1 | ||
38 | |||
39 | /* EDMA channels of da830 McASP1 */ | ||
40 | #define DAVINCI_DA830_DMA_MCASP1_AREVT 2 | ||
41 | #define DAVINCI_DA830_DMA_MCASP1_AXEVT 3 | ||
42 | |||
43 | /* Interrupts */ | ||
44 | #define DAVINCI_ASP0_RX_INT IRQ_MBRINT | ||
45 | #define DAVINCI_ASP0_TX_INT IRQ_MBXINT | ||
46 | #define DAVINCI_ASP1_RX_INT IRQ_MBRINT | ||
47 | #define DAVINCI_ASP1_TX_INT IRQ_MBXINT | ||
48 | |||
49 | #endif /* __ASM_ARCH_DAVINCI_ASP_H */ | ||
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h index 8db0fc6809dd..8661b2013527 100644 --- a/arch/arm/mach-davinci/davinci.h +++ b/arch/arm/mach-davinci/davinci.h | |||
@@ -22,10 +22,11 @@ | |||
22 | #include <linux/davinci_emac.h> | 22 | #include <linux/davinci_emac.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/spi/spi.h> | 24 | #include <linux/spi/spi.h> |
25 | #include <linux/platform_data/davinci_asp.h> | ||
25 | 26 | ||
26 | #include <mach/asp.h> | ||
27 | #include <mach/keyscan.h> | 27 | #include <mach/keyscan.h> |
28 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
29 | #include <mach/edma.h> | ||
29 | 30 | ||
30 | #include <media/davinci/vpfe_capture.h> | 31 | #include <media/davinci/vpfe_capture.h> |
31 | #include <media/davinci/vpif_types.h> | 32 | #include <media/davinci/vpif_types.h> |
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 783eab6845c4..bd2f72b414bc 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <mach/cpuidle.h> | 24 | #include <mach/cpuidle.h> |
25 | 25 | ||
26 | #include "clock.h" | 26 | #include "clock.h" |
27 | #include "asp.h" | ||
27 | 28 | ||
28 | #define DA8XX_TPCC_BASE 0x01c00000 | 29 | #define DA8XX_TPCC_BASE 0x01c00000 |
29 | #define DA8XX_TPTC0_BASE 0x01c08000 | 30 | #define DA8XX_TPTC0_BASE 0x01c08000 |
@@ -505,15 +506,8 @@ static struct platform_device da850_mcasp_device = { | |||
505 | .resource = da850_mcasp_resources, | 506 | .resource = da850_mcasp_resources, |
506 | }; | 507 | }; |
507 | 508 | ||
508 | static struct platform_device davinci_pcm_device = { | ||
509 | .name = "davinci-pcm-audio", | ||
510 | .id = -1, | ||
511 | }; | ||
512 | |||
513 | void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata) | 509 | void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata) |
514 | { | 510 | { |
515 | platform_device_register(&davinci_pcm_device); | ||
516 | |||
517 | /* DA830/OMAP-L137 has 3 instances of McASP */ | 511 | /* DA830/OMAP-L137 has 3 instances of McASP */ |
518 | if (cpu_is_davinci_da830() && id == 1) { | 512 | if (cpu_is_davinci_da830() && id == 1) { |
519 | da830_mcasp1_device.dev.platform_data = pdata; | 513 | da830_mcasp1_device.dev.platform_data = pdata; |
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index d2f9666284a7..70056fb8cc06 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c | |||
@@ -313,16 +313,6 @@ static void davinci_init_wdt(void) | |||
313 | 313 | ||
314 | /*-------------------------------------------------------------------------*/ | 314 | /*-------------------------------------------------------------------------*/ |
315 | 315 | ||
316 | static struct platform_device davinci_pcm_device = { | ||
317 | .name = "davinci-pcm-audio", | ||
318 | .id = -1, | ||
319 | }; | ||
320 | |||
321 | static void davinci_init_pcm(void) | ||
322 | { | ||
323 | platform_device_register(&davinci_pcm_device); | ||
324 | } | ||
325 | |||
326 | /*-------------------------------------------------------------------------*/ | 316 | /*-------------------------------------------------------------------------*/ |
327 | 317 | ||
328 | struct davinci_timer_instance davinci_timer_instance[2] = { | 318 | struct davinci_timer_instance davinci_timer_instance[2] = { |
@@ -345,7 +335,6 @@ static int __init davinci_init_devices(void) | |||
345 | /* please keep these calls, and their implementations above, | 335 | /* please keep these calls, and their implementations above, |
346 | * in alphabetical order so they're easier to sort through. | 336 | * in alphabetical order so they're easier to sort through. |
347 | */ | 337 | */ |
348 | davinci_init_pcm(); | ||
349 | davinci_init_wdt(); | 338 | davinci_init_wdt(); |
350 | 339 | ||
351 | return 0; | 340 | return 0; |
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 678cd99b7336..e47a3f0e8ac4 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c | |||
@@ -26,13 +26,13 @@ | |||
26 | #include <mach/time.h> | 26 | #include <mach/time.h> |
27 | #include <mach/serial.h> | 27 | #include <mach/serial.h> |
28 | #include <mach/common.h> | 28 | #include <mach/common.h> |
29 | #include <mach/asp.h> | ||
30 | #include <mach/spi.h> | 29 | #include <mach/spi.h> |
31 | #include <mach/gpio-davinci.h> | 30 | #include <mach/gpio-davinci.h> |
32 | 31 | ||
33 | #include "davinci.h" | 32 | #include "davinci.h" |
34 | #include "clock.h" | 33 | #include "clock.h" |
35 | #include "mux.h" | 34 | #include "mux.h" |
35 | #include "asp.h" | ||
36 | 36 | ||
37 | #define DM355_UART2_BASE (IO_PHYS + 0x206000) | 37 | #define DM355_UART2_BASE (IO_PHYS + 0x206000) |
38 | 38 | ||
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index a50d49de1883..f473745d6e3c 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <mach/time.h> | 29 | #include <mach/time.h> |
30 | #include <mach/serial.h> | 30 | #include <mach/serial.h> |
31 | #include <mach/common.h> | 31 | #include <mach/common.h> |
32 | #include <mach/asp.h> | ||
33 | #include <mach/keyscan.h> | 32 | #include <mach/keyscan.h> |
34 | #include <mach/spi.h> | 33 | #include <mach/spi.h> |
35 | #include <mach/gpio-davinci.h> | 34 | #include <mach/gpio-davinci.h> |
@@ -37,6 +36,7 @@ | |||
37 | #include "davinci.h" | 36 | #include "davinci.h" |
38 | #include "clock.h" | 37 | #include "clock.h" |
39 | #include "mux.h" | 38 | #include "mux.h" |
39 | #include "asp.h" | ||
40 | 40 | ||
41 | #define DM365_REF_FREQ 24000000 /* 24 MHz on the DM365 EVM */ | 41 | #define DM365_REF_FREQ 24000000 /* 24 MHz on the DM365 EVM */ |
42 | 42 | ||
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index c8b866657fcb..0755d466221a 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c | |||
@@ -23,12 +23,12 @@ | |||
23 | #include <mach/time.h> | 23 | #include <mach/time.h> |
24 | #include <mach/serial.h> | 24 | #include <mach/serial.h> |
25 | #include <mach/common.h> | 25 | #include <mach/common.h> |
26 | #include <mach/asp.h> | ||
27 | #include <mach/gpio-davinci.h> | 26 | #include <mach/gpio-davinci.h> |
28 | 27 | ||
29 | #include "davinci.h" | 28 | #include "davinci.h" |
30 | #include "clock.h" | 29 | #include "clock.h" |
31 | #include "mux.h" | 30 | #include "mux.h" |
31 | #include "asp.h" | ||
32 | 32 | ||
33 | /* | 33 | /* |
34 | * Device specific clocks | 34 | * Device specific clocks |
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 9eb87c1d1edd..97c0f8e555bd 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c | |||
@@ -24,12 +24,12 @@ | |||
24 | #include <mach/time.h> | 24 | #include <mach/time.h> |
25 | #include <mach/serial.h> | 25 | #include <mach/serial.h> |
26 | #include <mach/common.h> | 26 | #include <mach/common.h> |
27 | #include <mach/asp.h> | ||
28 | #include <mach/gpio-davinci.h> | 27 | #include <mach/gpio-davinci.h> |
29 | 28 | ||
30 | #include "davinci.h" | 29 | #include "davinci.h" |
31 | #include "clock.h" | 30 | #include "clock.h" |
32 | #include "mux.h" | 31 | #include "mux.h" |
32 | #include "asp.h" | ||
33 | 33 | ||
34 | #define DAVINCI_VPIF_BASE (0x01C12000) | 34 | #define DAVINCI_VPIF_BASE (0x01C12000) |
35 | 35 | ||
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index a2f1f274f189..c74a6abef187 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h | |||
@@ -16,11 +16,11 @@ | |||
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/davinci_emac.h> | 17 | #include <linux/davinci_emac.h> |
18 | #include <linux/spi/spi.h> | 18 | #include <linux/spi/spi.h> |
19 | #include <linux/platform_data/davinci_asp.h> | ||
19 | 20 | ||
20 | #include <mach/serial.h> | 21 | #include <mach/serial.h> |
21 | #include <mach/edma.h> | 22 | #include <mach/edma.h> |
22 | #include <mach/i2c.h> | 23 | #include <mach/i2c.h> |
23 | #include <mach/asp.h> | ||
24 | #include <mach/mmc.h> | 24 | #include <mach/mmc.h> |
25 | #include <mach/usb.h> | 25 | #include <mach/usb.h> |
26 | #include <mach/pm.h> | 26 | #include <mach/pm.h> |
diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c index ca70e5fcc7ac..020852d3bdd8 100644 --- a/arch/arm/mach-gemini/irq.c +++ b/arch/arm/mach-gemini/irq.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
18 | #include <asm/irq.h> | 18 | #include <asm/irq.h> |
19 | #include <asm/mach/irq.h> | 19 | #include <asm/mach/irq.h> |
20 | #include <asm/system_misc.h> | ||
20 | #include <mach/hardware.h> | 21 | #include <mach/hardware.h> |
21 | 22 | ||
22 | #define IRQ_SOURCE(base_addr) (base_addr + 0x00) | 23 | #define IRQ_SOURCE(base_addr) (base_addr + 0x00) |
diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c index fdd8cc87c9fe..4431a62fff5b 100644 --- a/arch/arm/mach-imx/clk-imx25.c +++ b/arch/arm/mach-imx/clk-imx25.c | |||
@@ -222,10 +222,8 @@ int __init mx25_clocks_init(void) | |||
222 | clk_register_clkdev(clk[lcdc_ipg], "ipg", "imx-fb.0"); | 222 | clk_register_clkdev(clk[lcdc_ipg], "ipg", "imx-fb.0"); |
223 | clk_register_clkdev(clk[lcdc_ahb], "ahb", "imx-fb.0"); | 223 | clk_register_clkdev(clk[lcdc_ahb], "ahb", "imx-fb.0"); |
224 | clk_register_clkdev(clk[wdt_ipg], NULL, "imx2-wdt.0"); | 224 | clk_register_clkdev(clk[wdt_ipg], NULL, "imx2-wdt.0"); |
225 | clk_register_clkdev(clk[ssi1_ipg_per], "per", "imx-ssi.0"); | 225 | clk_register_clkdev(clk[ssi1_ipg], NULL, "imx-ssi.0"); |
226 | clk_register_clkdev(clk[ssi1_ipg], "ipg", "imx-ssi.0"); | 226 | clk_register_clkdev(clk[ssi2_ipg], NULL, "imx-ssi.1"); |
227 | clk_register_clkdev(clk[ssi2_ipg_per], "per", "imx-ssi.1"); | ||
228 | clk_register_clkdev(clk[ssi2_ipg], "ipg", "imx-ssi.1"); | ||
229 | clk_register_clkdev(clk[esdhc1_ipg_per], "per", "sdhci-esdhc-imx25.0"); | 227 | clk_register_clkdev(clk[esdhc1_ipg_per], "per", "sdhci-esdhc-imx25.0"); |
230 | clk_register_clkdev(clk[esdhc1_ipg], "ipg", "sdhci-esdhc-imx25.0"); | 228 | clk_register_clkdev(clk[esdhc1_ipg], "ipg", "sdhci-esdhc-imx25.0"); |
231 | clk_register_clkdev(clk[esdhc1_ahb], "ahb", "sdhci-esdhc-imx25.0"); | 229 | clk_register_clkdev(clk[esdhc1_ahb], "ahb", "sdhci-esdhc-imx25.0"); |
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index c6422fb10bae..65fb8bcd86cb 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c | |||
@@ -230,10 +230,8 @@ int __init mx35_clocks_init() | |||
230 | clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb"); | 230 | clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb"); |
231 | clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1"); | 231 | clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1"); |
232 | clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma"); | 232 | clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma"); |
233 | clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.0"); | 233 | clk_register_clkdev(clk[ssi1_gate], NULL, "imx-ssi.0"); |
234 | clk_register_clkdev(clk[ssi1_div_post], "per", "imx-ssi.0"); | 234 | clk_register_clkdev(clk[ssi2_gate], NULL, "imx-ssi.1"); |
235 | clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.1"); | ||
236 | clk_register_clkdev(clk[ssi2_div_post], "per", "imx-ssi.1"); | ||
237 | /* i.mx35 has the i.mx21 type uart */ | 235 | /* i.mx35 has the i.mx21 type uart */ |
238 | clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0"); | 236 | clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0"); |
239 | clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0"); | 237 | clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0"); |
diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c index f264ddddd47c..562722959666 100644 --- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/dma-mapping.h> | 33 | #include <linux/dma-mapping.h> |
34 | #include <linux/leds.h> | 34 | #include <linux/leds.h> |
35 | #include <linux/memblock.h> | 35 | #include <linux/memblock.h> |
36 | #include <linux/platform_data/asoc-mx27vis.h> | ||
36 | #include <media/soc_camera.h> | 37 | #include <media/soc_camera.h> |
37 | #include <sound/tlv320aic32x4.h> | 38 | #include <sound/tlv320aic32x4.h> |
38 | #include <asm/mach-types.h> | 39 | #include <asm/mach-types.h> |
@@ -58,6 +59,11 @@ | |||
58 | #define EXPBOARD_BIT1 (GPIO_PORTD + 27) | 59 | #define EXPBOARD_BIT1 (GPIO_PORTD + 27) |
59 | #define EXPBOARD_BIT0 (GPIO_PORTD + 28) | 60 | #define EXPBOARD_BIT0 (GPIO_PORTD + 28) |
60 | 61 | ||
62 | #define AMP_GAIN_0 (GPIO_PORTF + 9) | ||
63 | #define AMP_GAIN_1 (GPIO_PORTF + 8) | ||
64 | #define AMP_MUTE_SDL (GPIO_PORTE + 5) | ||
65 | #define AMP_MUTE_SDR (GPIO_PORTF + 7) | ||
66 | |||
61 | static const int visstrim_m10_pins[] __initconst = { | 67 | static const int visstrim_m10_pins[] __initconst = { |
62 | /* UART1 (console) */ | 68 | /* UART1 (console) */ |
63 | PE12_PF_UART1_TXD, | 69 | PE12_PF_UART1_TXD, |
@@ -139,6 +145,11 @@ static const int visstrim_m10_pins[] __initconst = { | |||
139 | EXPBOARD_BIT2 | GPIO_GPIO | GPIO_IN | GPIO_PUEN, | 145 | EXPBOARD_BIT2 | GPIO_GPIO | GPIO_IN | GPIO_PUEN, |
140 | EXPBOARD_BIT1 | GPIO_GPIO | GPIO_IN | GPIO_PUEN, | 146 | EXPBOARD_BIT1 | GPIO_GPIO | GPIO_IN | GPIO_PUEN, |
141 | EXPBOARD_BIT0 | GPIO_GPIO | GPIO_IN | GPIO_PUEN, | 147 | EXPBOARD_BIT0 | GPIO_GPIO | GPIO_IN | GPIO_PUEN, |
148 | /* Audio AMP control */ | ||
149 | AMP_GAIN_0 | GPIO_GPIO | GPIO_OUT, | ||
150 | AMP_GAIN_1 | GPIO_GPIO | GPIO_OUT, | ||
151 | AMP_MUTE_SDL | GPIO_GPIO | GPIO_OUT, | ||
152 | AMP_MUTE_SDR | GPIO_GPIO | GPIO_OUT, | ||
142 | }; | 153 | }; |
143 | 154 | ||
144 | static struct gpio visstrim_m10_version_gpios[] = { | 155 | static struct gpio visstrim_m10_version_gpios[] = { |
@@ -166,6 +177,26 @@ static const struct gpio visstrim_m10_gpios[] __initconst = { | |||
166 | .flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW, | 177 | .flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW, |
167 | .label = "usbotg_cs", | 178 | .label = "usbotg_cs", |
168 | }, | 179 | }, |
180 | { | ||
181 | .gpio = AMP_GAIN_0, | ||
182 | .flags = GPIOF_DIR_OUT, | ||
183 | .label = "amp-gain-0", | ||
184 | }, | ||
185 | { | ||
186 | .gpio = AMP_GAIN_1, | ||
187 | .flags = GPIOF_DIR_OUT, | ||
188 | .label = "amp-gain-1", | ||
189 | }, | ||
190 | { | ||
191 | .gpio = AMP_MUTE_SDL, | ||
192 | .flags = GPIOF_DIR_OUT, | ||
193 | .label = "amp-mute-sdl", | ||
194 | }, | ||
195 | { | ||
196 | .gpio = AMP_MUTE_SDR, | ||
197 | .flags = GPIOF_DIR_OUT, | ||
198 | .label = "amp-mute-sdr", | ||
199 | }, | ||
169 | }; | 200 | }; |
170 | 201 | ||
171 | /* Camera */ | 202 | /* Camera */ |
@@ -405,6 +436,14 @@ static const struct imx_ssi_platform_data visstrim_m10_ssi_pdata __initconst = { | |||
405 | .flags = IMX_SSI_DMA | IMX_SSI_SYN, | 436 | .flags = IMX_SSI_DMA | IMX_SSI_SYN, |
406 | }; | 437 | }; |
407 | 438 | ||
439 | /* Audio */ | ||
440 | static const struct snd_mx27vis_platform_data snd_mx27vis_pdata __initconst = { | ||
441 | .amp_gain0_gpio = AMP_GAIN_0, | ||
442 | .amp_gain1_gpio = AMP_GAIN_1, | ||
443 | .amp_mutel_gpio = AMP_MUTE_SDL, | ||
444 | .amp_muter_gpio = AMP_MUTE_SDR, | ||
445 | }; | ||
446 | |||
408 | static void __init visstrim_m10_revision(void) | 447 | static void __init visstrim_m10_revision(void) |
409 | { | 448 | { |
410 | int exp_version = 0; | 449 | int exp_version = 0; |
@@ -463,7 +502,8 @@ static void __init visstrim_m10_board_init(void) | |||
463 | imx27_add_fec(NULL); | 502 | imx27_add_fec(NULL); |
464 | imx_add_gpio_keys(&visstrim_gpio_keys_platform_data); | 503 | imx_add_gpio_keys(&visstrim_gpio_keys_platform_data); |
465 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); | 504 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); |
466 | imx_add_platform_device("mx27vis", 0, NULL, 0, NULL, 0); | 505 | imx_add_platform_device("mx27vis", 0, NULL, 0, &snd_mx27vis_pdata, |
506 | sizeof(snd_mx27vis_pdata)); | ||
467 | platform_device_register_resndata(NULL, "soc-camera-pdrv", 0, NULL, 0, | 507 | platform_device_register_resndata(NULL, "soc-camera-pdrv", 0, NULL, 0, |
468 | &iclink_tvp5150, sizeof(iclink_tvp5150)); | 508 | &iclink_tvp5150, sizeof(iclink_tvp5150)); |
469 | gpio_led_register_device(0, &visstrim_m10_led_data); | 509 | gpio_led_register_device(0, &visstrim_m10_led_data); |
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 3226077735b1..1201191d7f1b 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c | |||
@@ -517,6 +517,13 @@ void __init kirkwood_wdt_init(void) | |||
517 | void __init kirkwood_init_early(void) | 517 | void __init kirkwood_init_early(void) |
518 | { | 518 | { |
519 | orion_time_set_base(TIMER_VIRT_BASE); | 519 | orion_time_set_base(TIMER_VIRT_BASE); |
520 | |||
521 | /* | ||
522 | * Some Kirkwood devices allocate their coherent buffers from atomic | ||
523 | * context. Increase size of atomic coherent pool to make sure such | ||
524 | * the allocations won't fail. | ||
525 | */ | ||
526 | init_dma_coherent_pool_size(SZ_1M); | ||
520 | } | 527 | } |
521 | 528 | ||
522 | int kirkwood_tclk; | 529 | int kirkwood_tclk; |
diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c index d93359379598..be90b7d0e10b 100644 --- a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c +++ b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/sizes.h> | ||
13 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
14 | #include <linux/mtd/partitions.h> | 15 | #include <linux/mtd/partitions.h> |
15 | #include <linux/ata_platform.h> | 16 | #include <linux/ata_platform.h> |
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index fcd4e85c4ddc..346fd26f3aa6 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -232,10 +232,11 @@ config MACH_OMAP3_PANDORA | |||
232 | select OMAP_PACKAGE_CBB | 232 | select OMAP_PACKAGE_CBB |
233 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | 233 | select REGULATOR_FIXED_VOLTAGE if REGULATOR |
234 | 234 | ||
235 | config MACH_OMAP3_TOUCHBOOK | 235 | config MACH_TOUCHBOOK |
236 | bool "OMAP3 Touch Book" | 236 | bool "OMAP3 Touch Book" |
237 | depends on ARCH_OMAP3 | 237 | depends on ARCH_OMAP3 |
238 | default y | 238 | default y |
239 | select OMAP_PACKAGE_CBB | ||
239 | 240 | ||
240 | config MACH_OMAP_3430SDP | 241 | config MACH_OMAP_3430SDP |
241 | bool "OMAP 3430 SDP board" | 242 | bool "OMAP 3430 SDP board" |
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index f6a24b3f9c4f..34c2c7f59f0a 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
@@ -255,7 +255,7 @@ obj-$(CONFIG_MACH_OMAP_3630SDP) += board-zoom-display.o | |||
255 | obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o | 255 | obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o |
256 | obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o | 256 | obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o |
257 | obj-$(CONFIG_MACH_IGEP0020) += board-igep0020.o | 257 | obj-$(CONFIG_MACH_IGEP0020) += board-igep0020.o |
258 | obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK) += board-omap3touchbook.o | 258 | obj-$(CONFIG_MACH_TOUCHBOOK) += board-omap3touchbook.o |
259 | obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o | 259 | obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o |
260 | obj-$(CONFIG_MACH_OMAP4_PANDA) += board-omap4panda.o | 260 | obj-$(CONFIG_MACH_OMAP4_PANDA) += board-omap4panda.o |
261 | 261 | ||
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 18f601096ce1..592812af84da 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c | |||
@@ -264,6 +264,16 @@ static __init void am3517_evm_musb_init(void) | |||
264 | usb_musb_init(&musb_board_data); | 264 | usb_musb_init(&musb_board_data); |
265 | } | 265 | } |
266 | 266 | ||
267 | static __init void am3517_evm_mcbsp1_init(void) | ||
268 | { | ||
269 | u32 devconf0; | ||
270 | |||
271 | /* McBSP1 CLKR/FSR signal to be connected to CLKX/FSX pin */ | ||
272 | devconf0 = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | ||
273 | devconf0 |= OMAP2_MCBSP1_CLKR_MASK | OMAP2_MCBSP1_FSR_MASK; | ||
274 | omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0); | ||
275 | } | ||
276 | |||
267 | static const struct usbhs_omap_board_data usbhs_bdata __initconst = { | 277 | static const struct usbhs_omap_board_data usbhs_bdata __initconst = { |
268 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 278 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
269 | #if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \ | 279 | #if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \ |
@@ -373,6 +383,9 @@ static void __init am3517_evm_init(void) | |||
373 | /* MUSB */ | 383 | /* MUSB */ |
374 | am3517_evm_musb_init(); | 384 | am3517_evm_musb_init(); |
375 | 385 | ||
386 | /* McBSP1 */ | ||
387 | am3517_evm_mcbsp1_init(); | ||
388 | |||
376 | /* MMC init function */ | 389 | /* MMC init function */ |
377 | omap_hsmmc_init(mmc); | 390 | omap_hsmmc_init(mmc); |
378 | } | 391 | } |
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 97d719047af3..188cc4eb0a79 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c | |||
@@ -731,6 +731,7 @@ static void __init cm_t3x_common_init(void) | |||
731 | cm_t35_init_ethernet(); | 731 | cm_t35_init_ethernet(); |
732 | cm_t35_init_led(); | 732 | cm_t35_init_led(); |
733 | cm_t35_init_display(); | 733 | cm_t35_init_display(); |
734 | omap_twl4030_audio_init("cm-t3x"); | ||
734 | 735 | ||
735 | usb_musb_init(NULL); | 736 | usb_musb_init(NULL); |
736 | cm_t35_init_usbh(); | 737 | cm_t35_init_usbh(); |
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index 6567c1cd5572..4cd804f615a5 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c | |||
@@ -630,6 +630,7 @@ static void __init devkit8000_init(void) | |||
630 | usbhs_init(&usbhs_bdata); | 630 | usbhs_init(&usbhs_bdata); |
631 | omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions, | 631 | omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions, |
632 | ARRAY_SIZE(devkit8000_nand_partitions)); | 632 | ARRAY_SIZE(devkit8000_nand_partitions)); |
633 | omap_twl4030_audio_init("omap3beagle"); | ||
633 | 634 | ||
634 | /* Ensure SDRC pins are mux'd for self-refresh */ | 635 | /* Ensure SDRC pins are mux'd for self-refresh */ |
635 | omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); | 636 | omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); |
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 28214483aaba..3613d1493c84 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c | |||
@@ -628,6 +628,7 @@ static void __init igep_init(void) | |||
628 | 628 | ||
629 | igep_flash_init(); | 629 | igep_flash_init(); |
630 | igep_leds_init(); | 630 | igep_leds_init(); |
631 | omap_twl4030_audio_init("igep2"); | ||
631 | 632 | ||
632 | /* | 633 | /* |
633 | * WLAN-BT combo module from MuRata which has a Marvell WLAN | 634 | * WLAN-BT combo module from MuRata which has a Marvell WLAN |
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 6202fc76e490..3ccfa5b23a24 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c | |||
@@ -519,6 +519,7 @@ static void __init omap3_beagle_init(void) | |||
519 | usbhs_init(&usbhs_bdata); | 519 | usbhs_init(&usbhs_bdata); |
520 | omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions, | 520 | omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions, |
521 | ARRAY_SIZE(omap3beagle_nand_partitions)); | 521 | ARRAY_SIZE(omap3beagle_nand_partitions)); |
522 | omap_twl4030_audio_init("omap3beagle"); | ||
522 | 523 | ||
523 | /* Ensure msecure is mux'd to be able to set the RTC. */ | 524 | /* Ensure msecure is mux'd to be able to set the RTC. */ |
524 | omap_mux_init_signal("sys_drm_msecure", OMAP_PIN_OFF_OUTPUT_HIGH); | 525 | omap_mux_init_signal("sys_drm_msecure", OMAP_PIN_OFF_OUTPUT_HIGH); |
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index 0d362e9f9cb9..164570053f71 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c | |||
@@ -737,6 +737,7 @@ static void __init omap3_evm_init(void) | |||
737 | omap3evm_init_smsc911x(); | 737 | omap3evm_init_smsc911x(); |
738 | omap3_evm_display_init(); | 738 | omap3_evm_display_init(); |
739 | omap3_evm_wl12xx_init(); | 739 | omap3_evm_wl12xx_init(); |
740 | omap_twl4030_audio_init("omap3evm"); | ||
740 | } | 741 | } |
741 | 742 | ||
742 | MACHINE_START(OMAP3EVM, "OMAP3 EVM") | 743 | MACHINE_START(OMAP3EVM, "OMAP3 EVM") |
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index 779734d8ba37..fe674d0c6c04 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c | |||
@@ -509,6 +509,7 @@ static void __init overo_init(void) | |||
509 | overo_display_init(); | 509 | overo_display_init(); |
510 | overo_init_led(); | 510 | overo_init_led(); |
511 | overo_init_keys(); | 511 | overo_init_keys(); |
512 | omap_twl4030_audio_init("overo"); | ||
512 | 513 | ||
513 | /* Ensure SDRC pins are mux'd for self-refresh */ | 514 | /* Ensure SDRC pins are mux'd for self-refresh */ |
514 | omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); | 515 | omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); |
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index b797cb279618..a7d3b0480744 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "common-board-devices.h" | 34 | #include "common-board-devices.h" |
35 | 35 | ||
36 | #define OMAP_ZOOM_WLAN_PMENA_GPIO (101) | 36 | #define OMAP_ZOOM_WLAN_PMENA_GPIO (101) |
37 | #define ZOOM2_HEADSET_EXTMUTE_GPIO (153) | ||
37 | #define OMAP_ZOOM_WLAN_IRQ_GPIO (162) | 38 | #define OMAP_ZOOM_WLAN_IRQ_GPIO (162) |
38 | 39 | ||
39 | #define LCD_PANEL_ENABLE_GPIO (7 + OMAP_MAX_GPIO_LINES) | 40 | #define LCD_PANEL_ENABLE_GPIO (7 + OMAP_MAX_GPIO_LINES) |
@@ -244,12 +245,6 @@ static int zoom_twl_gpio_setup(struct device *dev, | |||
244 | return ret; | 245 | return ret; |
245 | } | 246 | } |
246 | 247 | ||
247 | /* EXTMUTE callback function */ | ||
248 | static void zoom2_set_hs_extmute(int mute) | ||
249 | { | ||
250 | gpio_set_value(ZOOM2_HEADSET_EXTMUTE_GPIO, mute); | ||
251 | } | ||
252 | |||
253 | static struct twl4030_gpio_platform_data zoom_gpio_data = { | 248 | static struct twl4030_gpio_platform_data zoom_gpio_data = { |
254 | .gpio_base = OMAP_MAX_GPIO_LINES, | 249 | .gpio_base = OMAP_MAX_GPIO_LINES, |
255 | .irq_base = TWL4030_GPIO_IRQ_BASE, | 250 | .irq_base = TWL4030_GPIO_IRQ_BASE, |
@@ -279,7 +274,7 @@ static int __init omap_i2c_init(void) | |||
279 | 274 | ||
280 | codec_data->ramp_delay_value = 3; /* 161 ms */ | 275 | codec_data->ramp_delay_value = 3; /* 161 ms */ |
281 | codec_data->hs_extmute = 1; | 276 | codec_data->hs_extmute = 1; |
282 | codec_data->set_hs_extmute = zoom2_set_hs_extmute; | 277 | codec_data->hs_extmute_gpio = ZOOM2_HEADSET_EXTMUTE_GPIO; |
283 | } | 278 | } |
284 | omap_pmic_init(1, 2400, "twl5030", INT_34XX_SYS_NIRQ, &zoom_twldata); | 279 | omap_pmic_init(1, 2400, "twl5030", INT_34XX_SYS_NIRQ, &zoom_twldata); |
285 | omap_register_i2c_bus(2, 400, NULL, 0); | 280 | omap_register_i2c_bus(2, 400, NULL, 0); |
diff --git a/arch/arm/mach-omap2/clock33xx_data.c b/arch/arm/mach-omap2/clock33xx_data.c index 25bbcc7ca4dc..ae27de8899a6 100644 --- a/arch/arm/mach-omap2/clock33xx_data.c +++ b/arch/arm/mach-omap2/clock33xx_data.c | |||
@@ -1036,13 +1036,13 @@ static struct omap_clk am33xx_clks[] = { | |||
1036 | CLK(NULL, "mmu_fck", &mmu_fck, CK_AM33XX), | 1036 | CLK(NULL, "mmu_fck", &mmu_fck, CK_AM33XX), |
1037 | CLK(NULL, "smartreflex0_fck", &smartreflex0_fck, CK_AM33XX), | 1037 | CLK(NULL, "smartreflex0_fck", &smartreflex0_fck, CK_AM33XX), |
1038 | CLK(NULL, "smartreflex1_fck", &smartreflex1_fck, CK_AM33XX), | 1038 | CLK(NULL, "smartreflex1_fck", &smartreflex1_fck, CK_AM33XX), |
1039 | CLK(NULL, "gpt1_fck", &timer1_fck, CK_AM33XX), | 1039 | CLK(NULL, "timer1_fck", &timer1_fck, CK_AM33XX), |
1040 | CLK(NULL, "gpt2_fck", &timer2_fck, CK_AM33XX), | 1040 | CLK(NULL, "timer2_fck", &timer2_fck, CK_AM33XX), |
1041 | CLK(NULL, "gpt3_fck", &timer3_fck, CK_AM33XX), | 1041 | CLK(NULL, "timer3_fck", &timer3_fck, CK_AM33XX), |
1042 | CLK(NULL, "gpt4_fck", &timer4_fck, CK_AM33XX), | 1042 | CLK(NULL, "timer4_fck", &timer4_fck, CK_AM33XX), |
1043 | CLK(NULL, "gpt5_fck", &timer5_fck, CK_AM33XX), | 1043 | CLK(NULL, "timer5_fck", &timer5_fck, CK_AM33XX), |
1044 | CLK(NULL, "gpt6_fck", &timer6_fck, CK_AM33XX), | 1044 | CLK(NULL, "timer6_fck", &timer6_fck, CK_AM33XX), |
1045 | CLK(NULL, "gpt7_fck", &timer7_fck, CK_AM33XX), | 1045 | CLK(NULL, "timer7_fck", &timer7_fck, CK_AM33XX), |
1046 | CLK(NULL, "usbotg_fck", &usbotg_fck, CK_AM33XX), | 1046 | CLK(NULL, "usbotg_fck", &usbotg_fck, CK_AM33XX), |
1047 | CLK(NULL, "ieee5000_fck", &ieee5000_fck, CK_AM33XX), | 1047 | CLK(NULL, "ieee5000_fck", &ieee5000_fck, CK_AM33XX), |
1048 | CLK(NULL, "wdt1_fck", &wdt1_fck, CK_AM33XX), | 1048 | CLK(NULL, "wdt1_fck", &wdt1_fck, CK_AM33XX), |
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c index a0d68dbecfa3..f99e65cfb862 100644 --- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c +++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c | |||
@@ -241,6 +241,52 @@ static void omap3_clkdm_deny_idle(struct clockdomain *clkdm) | |||
241 | _clkdm_del_autodeps(clkdm); | 241 | _clkdm_del_autodeps(clkdm); |
242 | } | 242 | } |
243 | 243 | ||
244 | static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm) | ||
245 | { | ||
246 | bool hwsup = false; | ||
247 | |||
248 | if (!clkdm->clktrctrl_mask) | ||
249 | return 0; | ||
250 | |||
251 | hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
252 | clkdm->clktrctrl_mask); | ||
253 | |||
254 | if (hwsup) { | ||
255 | /* Disable HW transitions when we are changing deps */ | ||
256 | _disable_hwsup(clkdm); | ||
257 | _clkdm_add_autodeps(clkdm); | ||
258 | _enable_hwsup(clkdm); | ||
259 | } else { | ||
260 | if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) | ||
261 | omap3_clkdm_wakeup(clkdm); | ||
262 | } | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm) | ||
268 | { | ||
269 | bool hwsup = false; | ||
270 | |||
271 | if (!clkdm->clktrctrl_mask) | ||
272 | return 0; | ||
273 | |||
274 | hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
275 | clkdm->clktrctrl_mask); | ||
276 | |||
277 | if (hwsup) { | ||
278 | /* Disable HW transitions when we are changing deps */ | ||
279 | _disable_hwsup(clkdm); | ||
280 | _clkdm_del_autodeps(clkdm); | ||
281 | _enable_hwsup(clkdm); | ||
282 | } else { | ||
283 | if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP) | ||
284 | omap3_clkdm_sleep(clkdm); | ||
285 | } | ||
286 | |||
287 | return 0; | ||
288 | } | ||
289 | |||
244 | struct clkdm_ops omap2_clkdm_operations = { | 290 | struct clkdm_ops omap2_clkdm_operations = { |
245 | .clkdm_add_wkdep = omap2_clkdm_add_wkdep, | 291 | .clkdm_add_wkdep = omap2_clkdm_add_wkdep, |
246 | .clkdm_del_wkdep = omap2_clkdm_del_wkdep, | 292 | .clkdm_del_wkdep = omap2_clkdm_del_wkdep, |
@@ -267,6 +313,6 @@ struct clkdm_ops omap3_clkdm_operations = { | |||
267 | .clkdm_wakeup = omap3_clkdm_wakeup, | 313 | .clkdm_wakeup = omap3_clkdm_wakeup, |
268 | .clkdm_allow_idle = omap3_clkdm_allow_idle, | 314 | .clkdm_allow_idle = omap3_clkdm_allow_idle, |
269 | .clkdm_deny_idle = omap3_clkdm_deny_idle, | 315 | .clkdm_deny_idle = omap3_clkdm_deny_idle, |
270 | .clkdm_clk_enable = omap2_clkdm_clk_enable, | 316 | .clkdm_clk_enable = omap3xxx_clkdm_clk_enable, |
271 | .clkdm_clk_disable = omap2_clkdm_clk_disable, | 317 | .clkdm_clk_disable = omap3xxx_clkdm_clk_disable, |
272 | }; | 318 | }; |
diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h index 766338fe4d34..975f6bda0e0b 100644 --- a/arch/arm/mach-omap2/cm-regbits-34xx.h +++ b/arch/arm/mach-omap2/cm-regbits-34xx.h | |||
@@ -67,6 +67,7 @@ | |||
67 | #define OMAP3430_EN_IVA2_DPLL_MASK (0x7 << 0) | 67 | #define OMAP3430_EN_IVA2_DPLL_MASK (0x7 << 0) |
68 | 68 | ||
69 | /* CM_IDLEST_IVA2 */ | 69 | /* CM_IDLEST_IVA2 */ |
70 | #define OMAP3430_ST_IVA2_SHIFT 0 | ||
70 | #define OMAP3430_ST_IVA2_MASK (1 << 0) | 71 | #define OMAP3430_ST_IVA2_MASK (1 << 0) |
71 | 72 | ||
72 | /* CM_IDLEST_PLL_IVA2 */ | 73 | /* CM_IDLEST_PLL_IVA2 */ |
diff --git a/arch/arm/mach-omap2/include/mach/board-zoom.h b/arch/arm/mach-omap2/include/mach/board-zoom.h index 775fdc3b000b..2e9486940ead 100644 --- a/arch/arm/mach-omap2/include/mach/board-zoom.h +++ b/arch/arm/mach-omap2/include/mach/board-zoom.h | |||
@@ -8,5 +8,3 @@ | |||
8 | extern int __init zoom_debugboard_init(void); | 8 | extern int __init zoom_debugboard_init(void); |
9 | extern void __init zoom_peripherals_init(void); | 9 | extern void __init zoom_peripherals_init(void); |
10 | extern void __init zoom_display_init(void); | 10 | extern void __init zoom_display_init(void); |
11 | |||
12 | #define ZOOM2_HEADSET_EXTMUTE_GPIO 153 | ||
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index 577cb77db26c..d57a3578bf03 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/clk.h> | 15 | #include <linux/clk.h> |
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/of.h> | ||
18 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
19 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
20 | 21 | ||
@@ -25,8 +26,6 @@ | |||
25 | #include <plat/omap_device.h> | 26 | #include <plat/omap_device.h> |
26 | #include <linux/pm_runtime.h> | 27 | #include <linux/pm_runtime.h> |
27 | 28 | ||
28 | #include "control.h" | ||
29 | |||
30 | /* | 29 | /* |
31 | * FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle. | 30 | * FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle. |
32 | * Sidetone needs non-gated ICLK and sidetone autoidle is broken. | 31 | * Sidetone needs non-gated ICLK and sidetone autoidle is broken. |
@@ -34,112 +33,6 @@ | |||
34 | #include "cm2xxx_3xxx.h" | 33 | #include "cm2xxx_3xxx.h" |
35 | #include "cm-regbits-34xx.h" | 34 | #include "cm-regbits-34xx.h" |
36 | 35 | ||
37 | /* McBSP1 internal signal muxing function for OMAP2/3 */ | ||
38 | static int omap2_mcbsp1_mux_rx_clk(struct device *dev, const char *signal, | ||
39 | const char *src) | ||
40 | { | ||
41 | u32 v; | ||
42 | |||
43 | v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | ||
44 | |||
45 | if (!strcmp(signal, "clkr")) { | ||
46 | if (!strcmp(src, "clkr")) | ||
47 | v &= ~OMAP2_MCBSP1_CLKR_MASK; | ||
48 | else if (!strcmp(src, "clkx")) | ||
49 | v |= OMAP2_MCBSP1_CLKR_MASK; | ||
50 | else | ||
51 | return -EINVAL; | ||
52 | } else if (!strcmp(signal, "fsr")) { | ||
53 | if (!strcmp(src, "fsr")) | ||
54 | v &= ~OMAP2_MCBSP1_FSR_MASK; | ||
55 | else if (!strcmp(src, "fsx")) | ||
56 | v |= OMAP2_MCBSP1_FSR_MASK; | ||
57 | else | ||
58 | return -EINVAL; | ||
59 | } else { | ||
60 | return -EINVAL; | ||
61 | } | ||
62 | |||
63 | omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | /* McBSP4 internal signal muxing function for OMAP4 */ | ||
69 | #define OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_FSX (1 << 31) | ||
70 | #define OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_CLKX (1 << 30) | ||
71 | static int omap4_mcbsp4_mux_rx_clk(struct device *dev, const char *signal, | ||
72 | const char *src) | ||
73 | { | ||
74 | u32 v; | ||
75 | |||
76 | /* | ||
77 | * In CONTROL_MCBSPLP register only bit 30 (CLKR mux), and bit 31 (FSR | ||
78 | * mux) is used */ | ||
79 | v = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP); | ||
80 | |||
81 | if (!strcmp(signal, "clkr")) { | ||
82 | if (!strcmp(src, "clkr")) | ||
83 | v &= ~OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_CLKX; | ||
84 | else if (!strcmp(src, "clkx")) | ||
85 | v |= OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_CLKX; | ||
86 | else | ||
87 | return -EINVAL; | ||
88 | } else if (!strcmp(signal, "fsr")) { | ||
89 | if (!strcmp(src, "fsr")) | ||
90 | v &= ~OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_FSX; | ||
91 | else if (!strcmp(src, "fsx")) | ||
92 | v |= OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_FSX; | ||
93 | else | ||
94 | return -EINVAL; | ||
95 | } else { | ||
96 | return -EINVAL; | ||
97 | } | ||
98 | |||
99 | omap4_ctrl_pad_writel(v, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | /* McBSP CLKS source switching function */ | ||
105 | static int omap2_mcbsp_set_clk_src(struct device *dev, struct clk *clk, | ||
106 | const char *src) | ||
107 | { | ||
108 | struct clk *fck_src; | ||
109 | char *fck_src_name; | ||
110 | int r; | ||
111 | |||
112 | if (!strcmp(src, "clks_ext")) | ||
113 | fck_src_name = "pad_fck"; | ||
114 | else if (!strcmp(src, "clks_fclk")) | ||
115 | fck_src_name = "prcm_fck"; | ||
116 | else | ||
117 | return -EINVAL; | ||
118 | |||
119 | fck_src = clk_get(dev, fck_src_name); | ||
120 | if (IS_ERR_OR_NULL(fck_src)) { | ||
121 | pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks", | ||
122 | fck_src_name); | ||
123 | return -EINVAL; | ||
124 | } | ||
125 | |||
126 | pm_runtime_put_sync(dev); | ||
127 | |||
128 | r = clk_set_parent(clk, fck_src); | ||
129 | if (IS_ERR_VALUE(r)) { | ||
130 | pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n", | ||
131 | "clks", fck_src_name); | ||
132 | clk_put(fck_src); | ||
133 | return -EINVAL; | ||
134 | } | ||
135 | |||
136 | pm_runtime_get_sync(dev); | ||
137 | |||
138 | clk_put(fck_src); | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static int omap3_enable_st_clock(unsigned int id, bool enable) | 36 | static int omap3_enable_st_clock(unsigned int id, bool enable) |
144 | { | 37 | { |
145 | unsigned int w; | 38 | unsigned int w; |
@@ -181,17 +74,11 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) | |||
181 | pdata->reg_size = 4; | 74 | pdata->reg_size = 4; |
182 | pdata->has_ccr = true; | 75 | pdata->has_ccr = true; |
183 | } | 76 | } |
184 | pdata->set_clk_src = omap2_mcbsp_set_clk_src; | ||
185 | |||
186 | /* On OMAP2/3 the McBSP1 port has 6 pin configuration */ | ||
187 | if (id == 1 && oh->class->rev < MCBSP_CONFIG_TYPE4) | ||
188 | pdata->mux_signal = omap2_mcbsp1_mux_rx_clk; | ||
189 | 77 | ||
190 | /* On OMAP4 the McBSP4 port has 6 pin configuration */ | 78 | if (oh->class->rev == MCBSP_CONFIG_TYPE2) { |
191 | if (id == 4 && oh->class->rev == MCBSP_CONFIG_TYPE4) | 79 | /* The FIFO has 128 locations */ |
192 | pdata->mux_signal = omap4_mcbsp4_mux_rx_clk; | 80 | pdata->buffer_size = 0x80; |
193 | 81 | } else if (oh->class->rev == MCBSP_CONFIG_TYPE3) { | |
194 | if (oh->class->rev == MCBSP_CONFIG_TYPE3) { | ||
195 | if (id == 2) | 82 | if (id == 2) |
196 | /* The FIFO has 1024 + 256 locations */ | 83 | /* The FIFO has 1024 + 256 locations */ |
197 | pdata->buffer_size = 0x500; | 84 | pdata->buffer_size = 0x500; |
@@ -227,7 +114,8 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) | |||
227 | 114 | ||
228 | static int __init omap2_mcbsp_init(void) | 115 | static int __init omap2_mcbsp_init(void) |
229 | { | 116 | { |
230 | omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL); | 117 | if (!of_have_populated_dt()) |
118 | omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL); | ||
231 | 119 | ||
232 | return 0; | 120 | return 0; |
233 | } | 121 | } |
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index 05fdebfaa195..330d4c6e746b 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c | |||
@@ -46,7 +46,7 @@ | |||
46 | static void __iomem *wakeupgen_base; | 46 | static void __iomem *wakeupgen_base; |
47 | static void __iomem *sar_base; | 47 | static void __iomem *sar_base; |
48 | static DEFINE_SPINLOCK(wakeupgen_lock); | 48 | static DEFINE_SPINLOCK(wakeupgen_lock); |
49 | static unsigned int irq_target_cpu[NR_IRQS]; | 49 | static unsigned int irq_target_cpu[MAX_IRQS]; |
50 | static unsigned int irq_banks = MAX_NR_REG_BANKS; | 50 | static unsigned int irq_banks = MAX_NR_REG_BANKS; |
51 | static unsigned int max_irqs = MAX_IRQS; | 51 | static unsigned int max_irqs = MAX_IRQS; |
52 | static unsigned int omap_secure_apis; | 52 | static unsigned int omap_secure_apis; |
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 6ca8e519968d..37afbd173c2c 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -1889,6 +1889,7 @@ static int _enable(struct omap_hwmod *oh) | |||
1889 | _enable_sysc(oh); | 1889 | _enable_sysc(oh); |
1890 | } | 1890 | } |
1891 | } else { | 1891 | } else { |
1892 | _omap4_disable_module(oh); | ||
1892 | _disable_clocks(oh); | 1893 | _disable_clocks(oh); |
1893 | pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n", | 1894 | pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n", |
1894 | oh->name, r); | 1895 | oh->name, r); |
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index c9e38200216b..ce7e6068768f 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | |||
@@ -100,9 +100,9 @@ static struct omap_hwmod omap3xxx_mpu_hwmod = { | |||
100 | 100 | ||
101 | /* IVA2 (IVA2) */ | 101 | /* IVA2 (IVA2) */ |
102 | static struct omap_hwmod_rst_info omap3xxx_iva_resets[] = { | 102 | static struct omap_hwmod_rst_info omap3xxx_iva_resets[] = { |
103 | { .name = "logic", .rst_shift = 0 }, | 103 | { .name = "logic", .rst_shift = 0, .st_shift = 8 }, |
104 | { .name = "seq0", .rst_shift = 1 }, | 104 | { .name = "seq0", .rst_shift = 1, .st_shift = 9 }, |
105 | { .name = "seq1", .rst_shift = 2 }, | 105 | { .name = "seq1", .rst_shift = 2, .st_shift = 10 }, |
106 | }; | 106 | }; |
107 | 107 | ||
108 | static struct omap_hwmod omap3xxx_iva_hwmod = { | 108 | static struct omap_hwmod omap3xxx_iva_hwmod = { |
@@ -112,6 +112,15 @@ static struct omap_hwmod omap3xxx_iva_hwmod = { | |||
112 | .rst_lines = omap3xxx_iva_resets, | 112 | .rst_lines = omap3xxx_iva_resets, |
113 | .rst_lines_cnt = ARRAY_SIZE(omap3xxx_iva_resets), | 113 | .rst_lines_cnt = ARRAY_SIZE(omap3xxx_iva_resets), |
114 | .main_clk = "iva2_ck", | 114 | .main_clk = "iva2_ck", |
115 | .prcm = { | ||
116 | .omap2 = { | ||
117 | .module_offs = OMAP3430_IVA2_MOD, | ||
118 | .prcm_reg_id = 1, | ||
119 | .module_bit = OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT, | ||
120 | .idlest_reg_id = 1, | ||
121 | .idlest_idle_bit = OMAP3430_ST_IVA2_SHIFT, | ||
122 | } | ||
123 | }, | ||
115 | }; | 124 | }; |
116 | 125 | ||
117 | /* timer class */ | 126 | /* timer class */ |
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 242aee498ceb..2984ffaaee1f 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c | |||
@@ -4210,7 +4210,7 @@ static struct omap_hwmod_ocp_if omap44xx_dsp__iva = { | |||
4210 | }; | 4210 | }; |
4211 | 4211 | ||
4212 | /* dsp -> sl2if */ | 4212 | /* dsp -> sl2if */ |
4213 | static struct omap_hwmod_ocp_if omap44xx_dsp__sl2if = { | 4213 | static struct omap_hwmod_ocp_if __maybe_unused omap44xx_dsp__sl2if = { |
4214 | .master = &omap44xx_dsp_hwmod, | 4214 | .master = &omap44xx_dsp_hwmod, |
4215 | .slave = &omap44xx_sl2if_hwmod, | 4215 | .slave = &omap44xx_sl2if_hwmod, |
4216 | .clk = "dpll_iva_m5x2_ck", | 4216 | .clk = "dpll_iva_m5x2_ck", |
@@ -4828,7 +4828,7 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iss = { | |||
4828 | }; | 4828 | }; |
4829 | 4829 | ||
4830 | /* iva -> sl2if */ | 4830 | /* iva -> sl2if */ |
4831 | static struct omap_hwmod_ocp_if omap44xx_iva__sl2if = { | 4831 | static struct omap_hwmod_ocp_if __maybe_unused omap44xx_iva__sl2if = { |
4832 | .master = &omap44xx_iva_hwmod, | 4832 | .master = &omap44xx_iva_hwmod, |
4833 | .slave = &omap44xx_sl2if_hwmod, | 4833 | .slave = &omap44xx_sl2if_hwmod, |
4834 | .clk = "dpll_iva_m5x2_ck", | 4834 | .clk = "dpll_iva_m5x2_ck", |
@@ -5059,6 +5059,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__mcbsp4 = { | |||
5059 | 5059 | ||
5060 | static struct omap_hwmod_addr_space omap44xx_mcpdm_addrs[] = { | 5060 | static struct omap_hwmod_addr_space omap44xx_mcpdm_addrs[] = { |
5061 | { | 5061 | { |
5062 | .name = "mpu", | ||
5062 | .pa_start = 0x40132000, | 5063 | .pa_start = 0x40132000, |
5063 | .pa_end = 0x4013207f, | 5064 | .pa_end = 0x4013207f, |
5064 | .flags = ADDR_TYPE_RT | 5065 | .flags = ADDR_TYPE_RT |
@@ -5077,6 +5078,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcpdm = { | |||
5077 | 5078 | ||
5078 | static struct omap_hwmod_addr_space omap44xx_mcpdm_dma_addrs[] = { | 5079 | static struct omap_hwmod_addr_space omap44xx_mcpdm_dma_addrs[] = { |
5079 | { | 5080 | { |
5081 | .name = "dma", | ||
5080 | .pa_start = 0x49032000, | 5082 | .pa_start = 0x49032000, |
5081 | .pa_end = 0x4903207f, | 5083 | .pa_end = 0x4903207f, |
5082 | .flags = ADDR_TYPE_RT | 5084 | .flags = ADDR_TYPE_RT |
@@ -5362,7 +5364,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_wkup__scrm = { | |||
5362 | }; | 5364 | }; |
5363 | 5365 | ||
5364 | /* l3_main_2 -> sl2if */ | 5366 | /* l3_main_2 -> sl2if */ |
5365 | static struct omap_hwmod_ocp_if omap44xx_l3_main_2__sl2if = { | 5367 | static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l3_main_2__sl2if = { |
5366 | .master = &omap44xx_l3_main_2_hwmod, | 5368 | .master = &omap44xx_l3_main_2_hwmod, |
5367 | .slave = &omap44xx_sl2if_hwmod, | 5369 | .slave = &omap44xx_sl2if_hwmod, |
5368 | .clk = "l3_div_ck", | 5370 | .clk = "l3_div_ck", |
@@ -6032,7 +6034,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { | |||
6032 | &omap44xx_l4_abe__dmic, | 6034 | &omap44xx_l4_abe__dmic, |
6033 | &omap44xx_l4_abe__dmic_dma, | 6035 | &omap44xx_l4_abe__dmic_dma, |
6034 | &omap44xx_dsp__iva, | 6036 | &omap44xx_dsp__iva, |
6035 | &omap44xx_dsp__sl2if, | 6037 | /* &omap44xx_dsp__sl2if, */ |
6036 | &omap44xx_l4_cfg__dsp, | 6038 | &omap44xx_l4_cfg__dsp, |
6037 | &omap44xx_l3_main_2__dss, | 6039 | &omap44xx_l3_main_2__dss, |
6038 | &omap44xx_l4_per__dss, | 6040 | &omap44xx_l4_per__dss, |
@@ -6068,7 +6070,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { | |||
6068 | &omap44xx_l4_per__i2c4, | 6070 | &omap44xx_l4_per__i2c4, |
6069 | &omap44xx_l3_main_2__ipu, | 6071 | &omap44xx_l3_main_2__ipu, |
6070 | &omap44xx_l3_main_2__iss, | 6072 | &omap44xx_l3_main_2__iss, |
6071 | &omap44xx_iva__sl2if, | 6073 | /* &omap44xx_iva__sl2if, */ |
6072 | &omap44xx_l3_main_2__iva, | 6074 | &omap44xx_l3_main_2__iva, |
6073 | &omap44xx_l4_wkup__kbd, | 6075 | &omap44xx_l4_wkup__kbd, |
6074 | &omap44xx_l4_cfg__mailbox, | 6076 | &omap44xx_l4_cfg__mailbox, |
@@ -6099,7 +6101,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { | |||
6099 | &omap44xx_l4_cfg__cm_core, | 6101 | &omap44xx_l4_cfg__cm_core, |
6100 | &omap44xx_l4_wkup__prm, | 6102 | &omap44xx_l4_wkup__prm, |
6101 | &omap44xx_l4_wkup__scrm, | 6103 | &omap44xx_l4_wkup__scrm, |
6102 | &omap44xx_l3_main_2__sl2if, | 6104 | /* &omap44xx_l3_main_2__sl2if, */ |
6103 | &omap44xx_l4_abe__slimbus1, | 6105 | &omap44xx_l4_abe__slimbus1, |
6104 | &omap44xx_l4_abe__slimbus1_dma, | 6106 | &omap44xx_l4_abe__slimbus1_dma, |
6105 | &omap44xx_l4_per__slimbus2, | 6107 | &omap44xx_l4_per__slimbus2, |
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 2ff6d41ec6c6..2ba4f57dda86 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c | |||
@@ -260,6 +260,7 @@ static u32 notrace dmtimer_read_sched_clock(void) | |||
260 | return 0; | 260 | return 0; |
261 | } | 261 | } |
262 | 262 | ||
263 | #ifdef CONFIG_OMAP_32K_TIMER | ||
263 | /* Setup free-running counter for clocksource */ | 264 | /* Setup free-running counter for clocksource */ |
264 | static int __init omap2_sync32k_clocksource_init(void) | 265 | static int __init omap2_sync32k_clocksource_init(void) |
265 | { | 266 | { |
@@ -299,6 +300,12 @@ static int __init omap2_sync32k_clocksource_init(void) | |||
299 | 300 | ||
300 | return ret; | 301 | return ret; |
301 | } | 302 | } |
303 | #else | ||
304 | static inline int omap2_sync32k_clocksource_init(void) | ||
305 | { | ||
306 | return -ENODEV; | ||
307 | } | ||
308 | #endif | ||
302 | 309 | ||
303 | static void __init omap2_gptimer_clocksource_init(int gptimer_id, | 310 | static void __init omap2_gptimer_clocksource_init(int gptimer_id, |
304 | const char *fck_source) | 311 | const char *fck_source) |
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index db5ff6642375..bd81bf40e711 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c | |||
@@ -538,3 +538,30 @@ void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data, | |||
538 | pmic_data->v2v1 = &omap4_v2v1_idata; | 538 | pmic_data->v2v1 = &omap4_v2v1_idata; |
539 | } | 539 | } |
540 | #endif /* CONFIG_ARCH_OMAP4 */ | 540 | #endif /* CONFIG_ARCH_OMAP4 */ |
541 | |||
542 | #if defined(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) || \ | ||
543 | defined(CONFIG_SND_OMAP_SOC_OMAP_TWL4030_MODULE) | ||
544 | #include <linux/platform_data/omap-twl4030.h> | ||
545 | |||
546 | static struct omap_tw4030_pdata omap_twl4030_audio_data; | ||
547 | |||
548 | static struct platform_device audio_device = { | ||
549 | .name = "omap-twl4030", | ||
550 | .id = -1, | ||
551 | .dev = { | ||
552 | .platform_data = &omap_twl4030_audio_data, | ||
553 | }, | ||
554 | }; | ||
555 | |||
556 | void __init omap_twl4030_audio_init(char *card_name) | ||
557 | { | ||
558 | omap_twl4030_audio_data.card_name = card_name; | ||
559 | platform_device_register(&audio_device); | ||
560 | } | ||
561 | |||
562 | #else /* SOC_OMAP_TWL4030 */ | ||
563 | void __init omap_twl4030_audio_init(char *card_name) | ||
564 | { | ||
565 | return; | ||
566 | } | ||
567 | #endif /* SOC_OMAP_TWL4030 */ | ||
diff --git a/arch/arm/mach-omap2/twl-common.h b/arch/arm/mach-omap2/twl-common.h index 8fe71cfd002c..cb25b43317a7 100644 --- a/arch/arm/mach-omap2/twl-common.h +++ b/arch/arm/mach-omap2/twl-common.h | |||
@@ -59,4 +59,6 @@ void omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, | |||
59 | void omap4_pmic_get_config(struct twl4030_platform_data *pmic_data, | 59 | void omap4_pmic_get_config(struct twl4030_platform_data *pmic_data, |
60 | u32 pdata_flags, u32 regulators_flags); | 60 | u32 pdata_flags, u32 regulators_flags); |
61 | 61 | ||
62 | void omap_twl4030_audio_init(char *card_name); | ||
63 | |||
62 | #endif /* __OMAP_PMIC_COMMON__ */ | 64 | #endif /* __OMAP_PMIC_COMMON__ */ |
diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index cf10f92856dc..453a6e50db8b 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c | |||
@@ -520,13 +520,14 @@ static struct platform_device hdmi_lcdc_device = { | |||
520 | }; | 520 | }; |
521 | 521 | ||
522 | /* GPIO KEY */ | 522 | /* GPIO KEY */ |
523 | #define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 } | 523 | #define GPIO_KEY(c, g, d, ...) \ |
524 | { .code = c, .gpio = g, .desc = d, .active_low = 1, __VA_ARGS__ } | ||
524 | 525 | ||
525 | static struct gpio_keys_button gpio_buttons[] = { | 526 | static struct gpio_keys_button gpio_buttons[] = { |
526 | GPIO_KEY(KEY_POWER, GPIO_PORT99, "SW1"), | 527 | GPIO_KEY(KEY_POWER, GPIO_PORT99, "SW3", .wakeup = 1), |
527 | GPIO_KEY(KEY_BACK, GPIO_PORT100, "SW2"), | 528 | GPIO_KEY(KEY_BACK, GPIO_PORT100, "SW4"), |
528 | GPIO_KEY(KEY_MENU, GPIO_PORT97, "SW3"), | 529 | GPIO_KEY(KEY_MENU, GPIO_PORT97, "SW5"), |
529 | GPIO_KEY(KEY_HOME, GPIO_PORT98, "SW4"), | 530 | GPIO_KEY(KEY_HOME, GPIO_PORT98, "SW6"), |
530 | }; | 531 | }; |
531 | 532 | ||
532 | static struct gpio_keys_platform_data gpio_key_info = { | 533 | static struct gpio_keys_platform_data gpio_key_info = { |
@@ -901,8 +902,8 @@ static struct platform_device *eva_devices[] __initdata = { | |||
901 | &camera_device, | 902 | &camera_device, |
902 | &ceu0_device, | 903 | &ceu0_device, |
903 | &fsi_device, | 904 | &fsi_device, |
904 | &fsi_hdmi_device, | ||
905 | &fsi_wm8978_device, | 905 | &fsi_wm8978_device, |
906 | &fsi_hdmi_device, | ||
906 | }; | 907 | }; |
907 | 908 | ||
908 | static void __init eva_clock_init(void) | 909 | static void __init eva_clock_init(void) |
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 7ea2b31e3199..c129542f6aed 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c | |||
@@ -695,6 +695,7 @@ static struct platform_device usbhs0_device = { | |||
695 | * - J30 "open" | 695 | * - J30 "open" |
696 | * - modify usbhs1_get_id() USBHS_HOST -> USBHS_GADGET | 696 | * - modify usbhs1_get_id() USBHS_HOST -> USBHS_GADGET |
697 | * - add .get_vbus = usbhs_get_vbus in usbhs1_private | 697 | * - add .get_vbus = usbhs_get_vbus in usbhs1_private |
698 | * - check usbhs0_device(pio)/usbhs1_device(irq) order in mackerel_devices. | ||
698 | */ | 699 | */ |
699 | #define IRQ8 evt2irq(0x0300) | 700 | #define IRQ8 evt2irq(0x0300) |
700 | #define USB_PHY_MODE (1 << 4) | 701 | #define USB_PHY_MODE (1 << 4) |
@@ -1325,8 +1326,8 @@ static struct platform_device *mackerel_devices[] __initdata = { | |||
1325 | &nor_flash_device, | 1326 | &nor_flash_device, |
1326 | &smc911x_device, | 1327 | &smc911x_device, |
1327 | &lcdc_device, | 1328 | &lcdc_device, |
1328 | &usbhs1_device, | ||
1329 | &usbhs0_device, | 1329 | &usbhs0_device, |
1330 | &usbhs1_device, | ||
1330 | &leds_device, | 1331 | &leds_device, |
1331 | &fsi_device, | 1332 | &fsi_device, |
1332 | &fsi_ak4643_device, | 1333 | &fsi_ak4643_device, |
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index 3a528cf4366c..fcf5a47f4772 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c | |||
@@ -67,7 +67,7 @@ static struct smsc911x_platform_config smsc911x_platdata = { | |||
67 | 67 | ||
68 | static struct platform_device eth_device = { | 68 | static struct platform_device eth_device = { |
69 | .name = "smsc911x", | 69 | .name = "smsc911x", |
70 | .id = 0, | 70 | .id = -1, |
71 | .dev = { | 71 | .dev = { |
72 | .platform_data = &smsc911x_platdata, | 72 | .platform_data = &smsc911x_platdata, |
73 | }, | 73 | }, |
diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c index ee447404c857..588555a67d9c 100644 --- a/arch/arm/mach-shmobile/intc-sh73a0.c +++ b/arch/arm/mach-shmobile/intc-sh73a0.c | |||
@@ -259,9 +259,9 @@ static int sh73a0_set_wake(struct irq_data *data, unsigned int on) | |||
259 | return 0; /* always allow wakeup */ | 259 | return 0; /* always allow wakeup */ |
260 | } | 260 | } |
261 | 261 | ||
262 | #define RELOC_BASE 0x1000 | 262 | #define RELOC_BASE 0x1200 |
263 | 263 | ||
264 | /* INTCA IRQ pins at INTCS + 0x1000 to make space for GIC+INTC handling */ | 264 | /* INTCA IRQ pins at INTCS + RELOC_BASE to make space for GIC+INTC handling */ |
265 | #define INTCS_VECT_RELOC(n, vect) INTCS_VECT((n), (vect) + RELOC_BASE) | 265 | #define INTCS_VECT_RELOC(n, vect) INTCS_VECT((n), (vect) + RELOC_BASE) |
266 | 266 | ||
267 | INTC_IRQ_PINS_32(intca_irq_pins, 0xe6900000, | 267 | INTC_IRQ_PINS_32(intca_irq_pins, 0xe6900000, |
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index 119bc52ab93e..4e07eec1270d 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c | |||
@@ -63,10 +63,11 @@ static int contextidr_notifier(struct notifier_block *unused, unsigned long cmd, | |||
63 | pid = task_pid_nr(thread->task) << ASID_BITS; | 63 | pid = task_pid_nr(thread->task) << ASID_BITS; |
64 | asm volatile( | 64 | asm volatile( |
65 | " mrc p15, 0, %0, c13, c0, 1\n" | 65 | " mrc p15, 0, %0, c13, c0, 1\n" |
66 | " bfi %1, %0, #0, %2\n" | 66 | " and %0, %0, %2\n" |
67 | " mcr p15, 0, %1, c13, c0, 1\n" | 67 | " orr %0, %0, %1\n" |
68 | " mcr p15, 0, %0, c13, c0, 1\n" | ||
68 | : "=r" (contextidr), "+r" (pid) | 69 | : "=r" (contextidr), "+r" (pid) |
69 | : "I" (ASID_BITS)); | 70 | : "I" (~ASID_MASK)); |
70 | isb(); | 71 | isb(); |
71 | 72 | ||
72 | return NOTIFY_OK; | 73 | return NOTIFY_OK; |
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 4e7d1182e8a3..e59c4ab71bcb 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -267,17 +267,19 @@ static void __dma_free_remap(void *cpu_addr, size_t size) | |||
267 | vunmap(cpu_addr); | 267 | vunmap(cpu_addr); |
268 | } | 268 | } |
269 | 269 | ||
270 | #define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K | ||
271 | |||
270 | struct dma_pool { | 272 | struct dma_pool { |
271 | size_t size; | 273 | size_t size; |
272 | spinlock_t lock; | 274 | spinlock_t lock; |
273 | unsigned long *bitmap; | 275 | unsigned long *bitmap; |
274 | unsigned long nr_pages; | 276 | unsigned long nr_pages; |
275 | void *vaddr; | 277 | void *vaddr; |
276 | struct page *page; | 278 | struct page **pages; |
277 | }; | 279 | }; |
278 | 280 | ||
279 | static struct dma_pool atomic_pool = { | 281 | static struct dma_pool atomic_pool = { |
280 | .size = SZ_256K, | 282 | .size = DEFAULT_DMA_COHERENT_POOL_SIZE, |
281 | }; | 283 | }; |
282 | 284 | ||
283 | static int __init early_coherent_pool(char *p) | 285 | static int __init early_coherent_pool(char *p) |
@@ -287,6 +289,21 @@ static int __init early_coherent_pool(char *p) | |||
287 | } | 289 | } |
288 | early_param("coherent_pool", early_coherent_pool); | 290 | early_param("coherent_pool", early_coherent_pool); |
289 | 291 | ||
292 | void __init init_dma_coherent_pool_size(unsigned long size) | ||
293 | { | ||
294 | /* | ||
295 | * Catch any attempt to set the pool size too late. | ||
296 | */ | ||
297 | BUG_ON(atomic_pool.vaddr); | ||
298 | |||
299 | /* | ||
300 | * Set architecture specific coherent pool size only if | ||
301 | * it has not been changed by kernel command line parameter. | ||
302 | */ | ||
303 | if (atomic_pool.size == DEFAULT_DMA_COHERENT_POOL_SIZE) | ||
304 | atomic_pool.size = size; | ||
305 | } | ||
306 | |||
290 | /* | 307 | /* |
291 | * Initialise the coherent pool for atomic allocations. | 308 | * Initialise the coherent pool for atomic allocations. |
292 | */ | 309 | */ |
@@ -297,6 +314,7 @@ static int __init atomic_pool_init(void) | |||
297 | unsigned long nr_pages = pool->size >> PAGE_SHIFT; | 314 | unsigned long nr_pages = pool->size >> PAGE_SHIFT; |
298 | unsigned long *bitmap; | 315 | unsigned long *bitmap; |
299 | struct page *page; | 316 | struct page *page; |
317 | struct page **pages; | ||
300 | void *ptr; | 318 | void *ptr; |
301 | int bitmap_size = BITS_TO_LONGS(nr_pages) * sizeof(long); | 319 | int bitmap_size = BITS_TO_LONGS(nr_pages) * sizeof(long); |
302 | 320 | ||
@@ -304,21 +322,31 @@ static int __init atomic_pool_init(void) | |||
304 | if (!bitmap) | 322 | if (!bitmap) |
305 | goto no_bitmap; | 323 | goto no_bitmap; |
306 | 324 | ||
325 | pages = kzalloc(nr_pages * sizeof(struct page *), GFP_KERNEL); | ||
326 | if (!pages) | ||
327 | goto no_pages; | ||
328 | |||
307 | if (IS_ENABLED(CONFIG_CMA)) | 329 | if (IS_ENABLED(CONFIG_CMA)) |
308 | ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page); | 330 | ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page); |
309 | else | 331 | else |
310 | ptr = __alloc_remap_buffer(NULL, pool->size, GFP_KERNEL, prot, | 332 | ptr = __alloc_remap_buffer(NULL, pool->size, GFP_KERNEL, prot, |
311 | &page, NULL); | 333 | &page, NULL); |
312 | if (ptr) { | 334 | if (ptr) { |
335 | int i; | ||
336 | |||
337 | for (i = 0; i < nr_pages; i++) | ||
338 | pages[i] = page + i; | ||
339 | |||
313 | spin_lock_init(&pool->lock); | 340 | spin_lock_init(&pool->lock); |
314 | pool->vaddr = ptr; | 341 | pool->vaddr = ptr; |
315 | pool->page = page; | 342 | pool->pages = pages; |
316 | pool->bitmap = bitmap; | 343 | pool->bitmap = bitmap; |
317 | pool->nr_pages = nr_pages; | 344 | pool->nr_pages = nr_pages; |
318 | pr_info("DMA: preallocated %u KiB pool for atomic coherent allocations\n", | 345 | pr_info("DMA: preallocated %u KiB pool for atomic coherent allocations\n", |
319 | (unsigned)pool->size / 1024); | 346 | (unsigned)pool->size / 1024); |
320 | return 0; | 347 | return 0; |
321 | } | 348 | } |
349 | no_pages: | ||
322 | kfree(bitmap); | 350 | kfree(bitmap); |
323 | no_bitmap: | 351 | no_bitmap: |
324 | pr_err("DMA: failed to allocate %u KiB pool for atomic coherent allocation\n", | 352 | pr_err("DMA: failed to allocate %u KiB pool for atomic coherent allocation\n", |
@@ -443,27 +471,45 @@ static void *__alloc_from_pool(size_t size, struct page **ret_page) | |||
443 | if (pageno < pool->nr_pages) { | 471 | if (pageno < pool->nr_pages) { |
444 | bitmap_set(pool->bitmap, pageno, count); | 472 | bitmap_set(pool->bitmap, pageno, count); |
445 | ptr = pool->vaddr + PAGE_SIZE * pageno; | 473 | ptr = pool->vaddr + PAGE_SIZE * pageno; |
446 | *ret_page = pool->page + pageno; | 474 | *ret_page = pool->pages[pageno]; |
475 | } else { | ||
476 | pr_err_once("ERROR: %u KiB atomic DMA coherent pool is too small!\n" | ||
477 | "Please increase it with coherent_pool= kernel parameter!\n", | ||
478 | (unsigned)pool->size / 1024); | ||
447 | } | 479 | } |
448 | spin_unlock_irqrestore(&pool->lock, flags); | 480 | spin_unlock_irqrestore(&pool->lock, flags); |
449 | 481 | ||
450 | return ptr; | 482 | return ptr; |
451 | } | 483 | } |
452 | 484 | ||
485 | static bool __in_atomic_pool(void *start, size_t size) | ||
486 | { | ||
487 | struct dma_pool *pool = &atomic_pool; | ||
488 | void *end = start + size; | ||
489 | void *pool_start = pool->vaddr; | ||
490 | void *pool_end = pool->vaddr + pool->size; | ||
491 | |||
492 | if (start < pool_start || start >= pool_end) | ||
493 | return false; | ||
494 | |||
495 | if (end <= pool_end) | ||
496 | return true; | ||
497 | |||
498 | WARN(1, "Wrong coherent size(%p-%p) from atomic pool(%p-%p)\n", | ||
499 | start, end - 1, pool_start, pool_end - 1); | ||
500 | |||
501 | return false; | ||
502 | } | ||
503 | |||
453 | static int __free_from_pool(void *start, size_t size) | 504 | static int __free_from_pool(void *start, size_t size) |
454 | { | 505 | { |
455 | struct dma_pool *pool = &atomic_pool; | 506 | struct dma_pool *pool = &atomic_pool; |
456 | unsigned long pageno, count; | 507 | unsigned long pageno, count; |
457 | unsigned long flags; | 508 | unsigned long flags; |
458 | 509 | ||
459 | if (start < pool->vaddr || start > pool->vaddr + pool->size) | 510 | if (!__in_atomic_pool(start, size)) |
460 | return 0; | 511 | return 0; |
461 | 512 | ||
462 | if (start + size > pool->vaddr + pool->size) { | ||
463 | WARN(1, "freeing wrong coherent size from pool\n"); | ||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | pageno = (start - pool->vaddr) >> PAGE_SHIFT; | 513 | pageno = (start - pool->vaddr) >> PAGE_SHIFT; |
468 | count = size >> PAGE_SHIFT; | 514 | count = size >> PAGE_SHIFT; |
469 | 515 | ||
@@ -1090,10 +1136,22 @@ static int __iommu_remove_mapping(struct device *dev, dma_addr_t iova, size_t si | |||
1090 | return 0; | 1136 | return 0; |
1091 | } | 1137 | } |
1092 | 1138 | ||
1139 | static struct page **__atomic_get_pages(void *addr) | ||
1140 | { | ||
1141 | struct dma_pool *pool = &atomic_pool; | ||
1142 | struct page **pages = pool->pages; | ||
1143 | int offs = (addr - pool->vaddr) >> PAGE_SHIFT; | ||
1144 | |||
1145 | return pages + offs; | ||
1146 | } | ||
1147 | |||
1093 | static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs) | 1148 | static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs) |
1094 | { | 1149 | { |
1095 | struct vm_struct *area; | 1150 | struct vm_struct *area; |
1096 | 1151 | ||
1152 | if (__in_atomic_pool(cpu_addr, PAGE_SIZE)) | ||
1153 | return __atomic_get_pages(cpu_addr); | ||
1154 | |||
1097 | if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) | 1155 | if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) |
1098 | return cpu_addr; | 1156 | return cpu_addr; |
1099 | 1157 | ||
@@ -1103,6 +1161,34 @@ static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs) | |||
1103 | return NULL; | 1161 | return NULL; |
1104 | } | 1162 | } |
1105 | 1163 | ||
1164 | static void *__iommu_alloc_atomic(struct device *dev, size_t size, | ||
1165 | dma_addr_t *handle) | ||
1166 | { | ||
1167 | struct page *page; | ||
1168 | void *addr; | ||
1169 | |||
1170 | addr = __alloc_from_pool(size, &page); | ||
1171 | if (!addr) | ||
1172 | return NULL; | ||
1173 | |||
1174 | *handle = __iommu_create_mapping(dev, &page, size); | ||
1175 | if (*handle == DMA_ERROR_CODE) | ||
1176 | goto err_mapping; | ||
1177 | |||
1178 | return addr; | ||
1179 | |||
1180 | err_mapping: | ||
1181 | __free_from_pool(addr, size); | ||
1182 | return NULL; | ||
1183 | } | ||
1184 | |||
1185 | static void __iommu_free_atomic(struct device *dev, struct page **pages, | ||
1186 | dma_addr_t handle, size_t size) | ||
1187 | { | ||
1188 | __iommu_remove_mapping(dev, handle, size); | ||
1189 | __free_from_pool(page_address(pages[0]), size); | ||
1190 | } | ||
1191 | |||
1106 | static void *arm_iommu_alloc_attrs(struct device *dev, size_t size, | 1192 | static void *arm_iommu_alloc_attrs(struct device *dev, size_t size, |
1107 | dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs) | 1193 | dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs) |
1108 | { | 1194 | { |
@@ -1113,6 +1199,9 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size, | |||
1113 | *handle = DMA_ERROR_CODE; | 1199 | *handle = DMA_ERROR_CODE; |
1114 | size = PAGE_ALIGN(size); | 1200 | size = PAGE_ALIGN(size); |
1115 | 1201 | ||
1202 | if (gfp & GFP_ATOMIC) | ||
1203 | return __iommu_alloc_atomic(dev, size, handle); | ||
1204 | |||
1116 | pages = __iommu_alloc_buffer(dev, size, gfp); | 1205 | pages = __iommu_alloc_buffer(dev, size, gfp); |
1117 | if (!pages) | 1206 | if (!pages) |
1118 | return NULL; | 1207 | return NULL; |
@@ -1179,6 +1268,11 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr, | |||
1179 | return; | 1268 | return; |
1180 | } | 1269 | } |
1181 | 1270 | ||
1271 | if (__in_atomic_pool(cpu_addr, size)) { | ||
1272 | __iommu_free_atomic(dev, pages, handle, size); | ||
1273 | return; | ||
1274 | } | ||
1275 | |||
1182 | if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) { | 1276 | if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) { |
1183 | unmap_kernel_range((unsigned long)cpu_addr, size); | 1277 | unmap_kernel_range((unsigned long)cpu_addr, size); |
1184 | vunmap(cpu_addr); | 1278 | vunmap(cpu_addr); |
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index 6776160618ef..a8ee92da3544 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h | |||
@@ -55,6 +55,9 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page | |||
55 | /* permanent static mappings from iotable_init() */ | 55 | /* permanent static mappings from iotable_init() */ |
56 | #define VM_ARM_STATIC_MAPPING 0x40000000 | 56 | #define VM_ARM_STATIC_MAPPING 0x40000000 |
57 | 57 | ||
58 | /* empty mapping */ | ||
59 | #define VM_ARM_EMPTY_MAPPING 0x20000000 | ||
60 | |||
58 | /* mapping type (attributes) for permanent static mappings */ | 61 | /* mapping type (attributes) for permanent static mappings */ |
59 | #define VM_ARM_MTYPE(mt) ((mt) << 20) | 62 | #define VM_ARM_MTYPE(mt) ((mt) << 20) |
60 | #define VM_ARM_MTYPE_MASK (0x1f << 20) | 63 | #define VM_ARM_MTYPE_MASK (0x1f << 20) |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 4c2d0451e84a..c2fa21d0103e 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -807,7 +807,7 @@ static void __init pmd_empty_section_gap(unsigned long addr) | |||
807 | vm = early_alloc_aligned(sizeof(*vm), __alignof__(*vm)); | 807 | vm = early_alloc_aligned(sizeof(*vm), __alignof__(*vm)); |
808 | vm->addr = (void *)addr; | 808 | vm->addr = (void *)addr; |
809 | vm->size = SECTION_SIZE; | 809 | vm->size = SECTION_SIZE; |
810 | vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING; | 810 | vm->flags = VM_IOREMAP | VM_ARM_EMPTY_MAPPING; |
811 | vm->caller = pmd_empty_section_gap; | 811 | vm->caller = pmd_empty_section_gap; |
812 | vm_area_add_early(vm); | 812 | vm_area_add_early(vm); |
813 | } | 813 | } |
@@ -820,7 +820,7 @@ static void __init fill_pmd_gaps(void) | |||
820 | 820 | ||
821 | /* we're still single threaded hence no lock needed here */ | 821 | /* we're still single threaded hence no lock needed here */ |
822 | for (vm = vmlist; vm; vm = vm->next) { | 822 | for (vm = vmlist; vm; vm = vm->next) { |
823 | if (!(vm->flags & VM_ARM_STATIC_MAPPING)) | 823 | if (!(vm->flags & (VM_ARM_STATIC_MAPPING | VM_ARM_EMPTY_MAPPING))) |
824 | continue; | 824 | continue; |
825 | addr = (unsigned long)vm->addr; | 825 | addr = (unsigned long)vm->addr; |
826 | if (addr < next) | 826 | if (addr < next) |
@@ -961,8 +961,8 @@ void __init sanity_check_meminfo(void) | |||
961 | * Check whether this memory bank would partially overlap | 961 | * Check whether this memory bank would partially overlap |
962 | * the vmalloc area. | 962 | * the vmalloc area. |
963 | */ | 963 | */ |
964 | if (__va(bank->start + bank->size) > vmalloc_min || | 964 | if (__va(bank->start + bank->size - 1) >= vmalloc_min || |
965 | __va(bank->start + bank->size) < __va(bank->start)) { | 965 | __va(bank->start + bank->size - 1) <= __va(bank->start)) { |
966 | unsigned long newsize = vmalloc_min - __va(bank->start); | 966 | unsigned long newsize = vmalloc_min - __va(bank->start); |
967 | printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx " | 967 | printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx " |
968 | "to -%.8llx (vmalloc region overlap).\n", | 968 | "to -%.8llx (vmalloc region overlap).\n", |
diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h index 18814127809a..c78d90b28b19 100644 --- a/arch/arm/plat-omap/include/plat/mcbsp.h +++ b/arch/arm/plat-omap/include/plat/mcbsp.h | |||
@@ -47,8 +47,6 @@ struct omap_mcbsp_platform_data { | |||
47 | bool has_wakeup; /* Wakeup capability */ | 47 | bool has_wakeup; /* Wakeup capability */ |
48 | bool has_ccr; /* Transceiver has configuration control registers */ | 48 | bool has_ccr; /* Transceiver has configuration control registers */ |
49 | int (*enable_st_clock)(unsigned int, bool); | 49 | int (*enable_st_clock)(unsigned int, bool); |
50 | int (*set_clk_src)(struct device *dev, struct clk *clk, const char *src); | ||
51 | int (*mux_signal)(struct device *dev, const char *signal, const char *src); | ||
52 | }; | 50 | }; |
53 | 51 | ||
54 | /** | 52 | /** |
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 766181cb5c95..024f3b08db29 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c | |||
@@ -68,6 +68,7 @@ | |||
68 | 68 | ||
69 | static unsigned long omap_sram_start; | 69 | static unsigned long omap_sram_start; |
70 | static void __iomem *omap_sram_base; | 70 | static void __iomem *omap_sram_base; |
71 | static unsigned long omap_sram_skip; | ||
71 | static unsigned long omap_sram_size; | 72 | static unsigned long omap_sram_size; |
72 | static void __iomem *omap_sram_ceil; | 73 | static void __iomem *omap_sram_ceil; |
73 | 74 | ||
@@ -106,6 +107,7 @@ static int is_sram_locked(void) | |||
106 | */ | 107 | */ |
107 | static void __init omap_detect_sram(void) | 108 | static void __init omap_detect_sram(void) |
108 | { | 109 | { |
110 | omap_sram_skip = SRAM_BOOTLOADER_SZ; | ||
109 | if (cpu_class_is_omap2()) { | 111 | if (cpu_class_is_omap2()) { |
110 | if (is_sram_locked()) { | 112 | if (is_sram_locked()) { |
111 | if (cpu_is_omap34xx()) { | 113 | if (cpu_is_omap34xx()) { |
@@ -113,6 +115,7 @@ static void __init omap_detect_sram(void) | |||
113 | if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) || | 115 | if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) || |
114 | (omap_type() == OMAP2_DEVICE_TYPE_SEC)) { | 116 | (omap_type() == OMAP2_DEVICE_TYPE_SEC)) { |
115 | omap_sram_size = 0x7000; /* 28K */ | 117 | omap_sram_size = 0x7000; /* 28K */ |
118 | omap_sram_skip += SZ_16K; | ||
116 | } else { | 119 | } else { |
117 | omap_sram_size = 0x8000; /* 32K */ | 120 | omap_sram_size = 0x8000; /* 32K */ |
118 | } | 121 | } |
@@ -175,8 +178,10 @@ static void __init omap_map_sram(void) | |||
175 | return; | 178 | return; |
176 | 179 | ||
177 | #ifdef CONFIG_OMAP4_ERRATA_I688 | 180 | #ifdef CONFIG_OMAP4_ERRATA_I688 |
181 | if (cpu_is_omap44xx()) { | ||
178 | omap_sram_start += PAGE_SIZE; | 182 | omap_sram_start += PAGE_SIZE; |
179 | omap_sram_size -= SZ_16K; | 183 | omap_sram_size -= SZ_16K; |
184 | } | ||
180 | #endif | 185 | #endif |
181 | if (cpu_is_omap34xx()) { | 186 | if (cpu_is_omap34xx()) { |
182 | /* | 187 | /* |
@@ -203,8 +208,8 @@ static void __init omap_map_sram(void) | |||
203 | * Looks like we need to preserve some bootloader code at the | 208 | * Looks like we need to preserve some bootloader code at the |
204 | * beginning of SRAM for jumping to flash for reboot to work... | 209 | * beginning of SRAM for jumping to flash for reboot to work... |
205 | */ | 210 | */ |
206 | memset_io(omap_sram_base + SRAM_BOOTLOADER_SZ, 0, | 211 | memset_io(omap_sram_base + omap_sram_skip, 0, |
207 | omap_sram_size - SRAM_BOOTLOADER_SZ); | 212 | omap_sram_size - omap_sram_skip); |
208 | } | 213 | } |
209 | 214 | ||
210 | /* | 215 | /* |
@@ -218,7 +223,7 @@ void *omap_sram_push_address(unsigned long size) | |||
218 | { | 223 | { |
219 | unsigned long available, new_ceil = (unsigned long)omap_sram_ceil; | 224 | unsigned long available, new_ceil = (unsigned long)omap_sram_ceil; |
220 | 225 | ||
221 | available = omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ); | 226 | available = omap_sram_ceil - (omap_sram_base + omap_sram_skip); |
222 | 227 | ||
223 | if (size > available) { | 228 | if (size > available) { |
224 | pr_err("Not enough space in SRAM\n"); | 229 | pr_err("Not enough space in SRAM\n"); |
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index f34861920634..c7092e6057c5 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig | |||
@@ -38,6 +38,7 @@ config BLACKFIN | |||
38 | select GENERIC_ATOMIC64 | 38 | select GENERIC_ATOMIC64 |
39 | select GENERIC_IRQ_PROBE | 39 | select GENERIC_IRQ_PROBE |
40 | select IRQ_PER_CPU if SMP | 40 | select IRQ_PER_CPU if SMP |
41 | select USE_GENERIC_SMP_HELPERS if SMP | ||
41 | select HAVE_NMI_WATCHDOG if NMI_WATCHDOG | 42 | select HAVE_NMI_WATCHDOG if NMI_WATCHDOG |
42 | select GENERIC_SMP_IDLE_THREAD | 43 | select GENERIC_SMP_IDLE_THREAD |
43 | select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS | 44 | select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS |
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index d3d7e64ca96d..66cf00095b84 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile | |||
@@ -20,7 +20,6 @@ endif | |||
20 | KBUILD_AFLAGS += $(call cc-option,-mno-fdpic) | 20 | KBUILD_AFLAGS += $(call cc-option,-mno-fdpic) |
21 | KBUILD_CFLAGS_MODULE += -mlong-calls | 21 | KBUILD_CFLAGS_MODULE += -mlong-calls |
22 | LDFLAGS += -m elf32bfin | 22 | LDFLAGS += -m elf32bfin |
23 | KALLSYMS += --symbol-prefix=_ | ||
24 | 23 | ||
25 | KBUILD_DEFCONFIG := BF537-STAMP_defconfig | 24 | KBUILD_DEFCONFIG := BF537-STAMP_defconfig |
26 | 25 | ||
diff --git a/arch/blackfin/include/asm/smp.h b/arch/blackfin/include/asm/smp.h index dc3d144b4bb5..9631598dcc5d 100644 --- a/arch/blackfin/include/asm/smp.h +++ b/arch/blackfin/include/asm/smp.h | |||
@@ -18,6 +18,8 @@ | |||
18 | #define raw_smp_processor_id() blackfin_core_id() | 18 | #define raw_smp_processor_id() blackfin_core_id() |
19 | 19 | ||
20 | extern void bfin_relocate_coreb_l1_mem(void); | 20 | extern void bfin_relocate_coreb_l1_mem(void); |
21 | extern void arch_send_call_function_single_ipi(int cpu); | ||
22 | extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); | ||
21 | 23 | ||
22 | #if defined(CONFIG_SMP) && defined(CONFIG_ICACHE_FLUSH_L1) | 24 | #if defined(CONFIG_SMP) && defined(CONFIG_ICACHE_FLUSH_L1) |
23 | asmlinkage void blackfin_icache_flush_range_l1(unsigned long *ptr); | 25 | asmlinkage void blackfin_icache_flush_range_l1(unsigned long *ptr); |
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index fc179ca07799..29f16e5c37b9 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c | |||
@@ -587,6 +587,21 @@ static struct platform_device bfin_tdm = { | |||
587 | }; | 587 | }; |
588 | #endif | 588 | #endif |
589 | 589 | ||
590 | #if defined(CONFIG_SND_BF5XX_SOC_AD1836) \ | ||
591 | || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) | ||
592 | static const char * const ad1836_link[] = { | ||
593 | "bfin-tdm.0", | ||
594 | "spi0.4", | ||
595 | }; | ||
596 | static struct platform_device bfin_ad1836_machine = { | ||
597 | .name = "bfin-snd-ad1836", | ||
598 | .id = -1, | ||
599 | .dev = { | ||
600 | .platform_data = (void *)ad1836_link, | ||
601 | }, | ||
602 | }; | ||
603 | #endif | ||
604 | |||
590 | static struct spi_board_info bfin_spi_board_info[] __initdata = { | 605 | static struct spi_board_info bfin_spi_board_info[] __initdata = { |
591 | #if defined(CONFIG_MTD_M25P80) \ | 606 | #if defined(CONFIG_MTD_M25P80) \ |
592 | || defined(CONFIG_MTD_M25P80_MODULE) | 607 | || defined(CONFIG_MTD_M25P80_MODULE) |
@@ -1269,6 +1284,11 @@ static struct platform_device *stamp_devices[] __initdata = { | |||
1269 | #if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) | 1284 | #if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) |
1270 | &bfin_tdm, | 1285 | &bfin_tdm, |
1271 | #endif | 1286 | #endif |
1287 | |||
1288 | #if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \ | ||
1289 | defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) | ||
1290 | &bfin_ad1836_machine, | ||
1291 | #endif | ||
1272 | }; | 1292 | }; |
1273 | 1293 | ||
1274 | static int __init ezkit_init(void) | 1294 | static int __init ezkit_init(void) |
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index ce88a7165b62..6fca8698bf3b 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c | |||
@@ -617,6 +617,21 @@ static struct platform_device bfin_ac97_pcm = { | |||
617 | }; | 617 | }; |
618 | #endif | 618 | #endif |
619 | 619 | ||
620 | #if defined(CONFIG_SND_BF5XX_SOC_AD1836) \ | ||
621 | || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) | ||
622 | static const char * const ad1836_link[] = { | ||
623 | "bfin-tdm.0", | ||
624 | "spi0.4", | ||
625 | }; | ||
626 | static struct platform_device bfin_ad1836_machine = { | ||
627 | .name = "bfin-snd-ad1836", | ||
628 | .id = -1, | ||
629 | .dev = { | ||
630 | .platform_data = (void *)ad1836_link, | ||
631 | }, | ||
632 | }; | ||
633 | #endif | ||
634 | |||
620 | #if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \ | 635 | #if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \ |
621 | defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE) | 636 | defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE) |
622 | static const unsigned ad73311_gpio[] = { | 637 | static const unsigned ad73311_gpio[] = { |
@@ -754,6 +769,11 @@ static struct platform_device *stamp_devices[] __initdata = { | |||
754 | &bfin_ac97_pcm, | 769 | &bfin_ac97_pcm, |
755 | #endif | 770 | #endif |
756 | 771 | ||
772 | #if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \ | ||
773 | defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) | ||
774 | &bfin_ad1836_machine, | ||
775 | #endif | ||
776 | |||
757 | #if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \ | 777 | #if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \ |
758 | defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE) | 778 | defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE) |
759 | &bfin_ad73311_machine, | 779 | &bfin_ad73311_machine, |
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 5ed654ae66e1..307bd7e62f43 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c | |||
@@ -2641,6 +2641,21 @@ static struct platform_device bfin_ac97_pcm = { | |||
2641 | }; | 2641 | }; |
2642 | #endif | 2642 | #endif |
2643 | 2643 | ||
2644 | #if defined(CONFIG_SND_BF5XX_SOC_AD1836) \ | ||
2645 | || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) | ||
2646 | static const char * const ad1836_link[] = { | ||
2647 | "bfin-tdm.0", | ||
2648 | "spi0.4", | ||
2649 | }; | ||
2650 | static struct platform_device bfin_ad1836_machine = { | ||
2651 | .name = "bfin-snd-ad1836", | ||
2652 | .id = -1, | ||
2653 | .dev = { | ||
2654 | .platform_data = (void *)ad1836_link, | ||
2655 | }, | ||
2656 | }; | ||
2657 | #endif | ||
2658 | |||
2644 | #if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \ | 2659 | #if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \ |
2645 | defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE) | 2660 | defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE) |
2646 | static const unsigned ad73311_gpio[] = { | 2661 | static const unsigned ad73311_gpio[] = { |
@@ -2927,6 +2942,11 @@ static struct platform_device *stamp_devices[] __initdata = { | |||
2927 | &bfin_ac97_pcm, | 2942 | &bfin_ac97_pcm, |
2928 | #endif | 2943 | #endif |
2929 | 2944 | ||
2945 | #if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \ | ||
2946 | defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) | ||
2947 | &bfin_ad1836_machine, | ||
2948 | #endif | ||
2949 | |||
2930 | #if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \ | 2950 | #if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \ |
2931 | defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE) | 2951 | defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE) |
2932 | &bfin_ad73311_machine, | 2952 | &bfin_ad73311_machine, |
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c index 7c36777c6455..551f866172cf 100644 --- a/arch/blackfin/mach-bf561/boards/ezkit.c +++ b/arch/blackfin/mach-bf561/boards/ezkit.c | |||
@@ -539,6 +539,21 @@ static struct platform_device bfin_ac97 = { | |||
539 | }; | 539 | }; |
540 | #endif | 540 | #endif |
541 | 541 | ||
542 | #if defined(CONFIG_SND_BF5XX_SOC_AD1836) \ | ||
543 | || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) | ||
544 | static const char * const ad1836_link[] = { | ||
545 | "bfin-tdm.0", | ||
546 | "spi0.4", | ||
547 | }; | ||
548 | static struct platform_device bfin_ad1836_machine = { | ||
549 | .name = "bfin-snd-ad1836", | ||
550 | .id = -1, | ||
551 | .dev = { | ||
552 | .platform_data = (void *)ad1836_link, | ||
553 | }, | ||
554 | }; | ||
555 | #endif | ||
556 | |||
542 | static struct platform_device *ezkit_devices[] __initdata = { | 557 | static struct platform_device *ezkit_devices[] __initdata = { |
543 | 558 | ||
544 | &bfin_dpmc, | 559 | &bfin_dpmc, |
@@ -603,6 +618,11 @@ static struct platform_device *ezkit_devices[] __initdata = { | |||
603 | #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) | 618 | #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) |
604 | &bfin_ac97, | 619 | &bfin_ac97, |
605 | #endif | 620 | #endif |
621 | |||
622 | #if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \ | ||
623 | defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) | ||
624 | &bfin_ad1836_machine, | ||
625 | #endif | ||
606 | }; | 626 | }; |
607 | 627 | ||
608 | static int __init net2272_init(void) | 628 | static int __init net2272_init(void) |
diff --git a/arch/blackfin/mach-bf609/boards/ezkit.c b/arch/blackfin/mach-bf609/boards/ezkit.c index c2cf1ae31189..61c1f47a4bf2 100644 --- a/arch/blackfin/mach-bf609/boards/ezkit.c +++ b/arch/blackfin/mach-bf609/boards/ezkit.c | |||
@@ -818,6 +818,21 @@ static struct platform_device bfin_i2s = { | |||
818 | }; | 818 | }; |
819 | #endif | 819 | #endif |
820 | 820 | ||
821 | #if defined(CONFIG_SND_BF5XX_SOC_AD1836) \ | ||
822 | || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) | ||
823 | static const char * const ad1836_link[] = { | ||
824 | "bfin-tdm.0", | ||
825 | "spi0.76", | ||
826 | }; | ||
827 | static struct platform_device bfin_ad1836_machine = { | ||
828 | .name = "bfin-snd-ad1836", | ||
829 | .id = -1, | ||
830 | .dev = { | ||
831 | .platform_data = (void *)ad1836_link, | ||
832 | }, | ||
833 | }; | ||
834 | #endif | ||
835 | |||
821 | #if defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61) || \ | 836 | #if defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61) || \ |
822 | defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61_MODULE) | 837 | defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61_MODULE) |
823 | static struct platform_device adau1761_device = { | 838 | static struct platform_device adau1761_device = { |
@@ -1557,6 +1572,10 @@ static struct platform_device *ezkit_devices[] __initdata = { | |||
1557 | defined(CONFIG_SND_BF6XX_SOC_I2S_MODULE) | 1572 | defined(CONFIG_SND_BF6XX_SOC_I2S_MODULE) |
1558 | &bfin_i2s, | 1573 | &bfin_i2s, |
1559 | #endif | 1574 | #endif |
1575 | #if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \ | ||
1576 | defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) | ||
1577 | &bfin_ad1836_machine, | ||
1578 | #endif | ||
1560 | #if defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61) || \ | 1579 | #if defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61) || \ |
1561 | defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61_MODULE) | 1580 | defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61_MODULE) |
1562 | &adau1761_device, | 1581 | &adau1761_device, |
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index 00bbe672b3b3..a40151306b77 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c | |||
@@ -48,10 +48,13 @@ unsigned long blackfin_iflush_l1_entry[NR_CPUS]; | |||
48 | 48 | ||
49 | struct blackfin_initial_pda __cpuinitdata initial_pda_coreb; | 49 | struct blackfin_initial_pda __cpuinitdata initial_pda_coreb; |
50 | 50 | ||
51 | #define BFIN_IPI_TIMER 0 | 51 | enum ipi_message_type { |
52 | #define BFIN_IPI_RESCHEDULE 1 | 52 | BFIN_IPI_TIMER, |
53 | #define BFIN_IPI_CALL_FUNC 2 | 53 | BFIN_IPI_RESCHEDULE, |
54 | #define BFIN_IPI_CPU_STOP 3 | 54 | BFIN_IPI_CALL_FUNC, |
55 | BFIN_IPI_CALL_FUNC_SINGLE, | ||
56 | BFIN_IPI_CPU_STOP, | ||
57 | }; | ||
55 | 58 | ||
56 | struct blackfin_flush_data { | 59 | struct blackfin_flush_data { |
57 | unsigned long start; | 60 | unsigned long start; |
@@ -60,35 +63,20 @@ struct blackfin_flush_data { | |||
60 | 63 | ||
61 | void *secondary_stack; | 64 | void *secondary_stack; |
62 | 65 | ||
63 | |||
64 | struct smp_call_struct { | ||
65 | void (*func)(void *info); | ||
66 | void *info; | ||
67 | int wait; | ||
68 | cpumask_t *waitmask; | ||
69 | }; | ||
70 | |||
71 | static struct blackfin_flush_data smp_flush_data; | 66 | static struct blackfin_flush_data smp_flush_data; |
72 | 67 | ||
73 | static DEFINE_SPINLOCK(stop_lock); | 68 | static DEFINE_SPINLOCK(stop_lock); |
74 | 69 | ||
75 | struct ipi_message { | ||
76 | unsigned long type; | ||
77 | struct smp_call_struct call_struct; | ||
78 | }; | ||
79 | |||
80 | /* A magic number - stress test shows this is safe for common cases */ | 70 | /* A magic number - stress test shows this is safe for common cases */ |
81 | #define BFIN_IPI_MSGQ_LEN 5 | 71 | #define BFIN_IPI_MSGQ_LEN 5 |
82 | 72 | ||
83 | /* Simple FIFO buffer, overflow leads to panic */ | 73 | /* Simple FIFO buffer, overflow leads to panic */ |
84 | struct ipi_message_queue { | 74 | struct ipi_data { |
85 | spinlock_t lock; | ||
86 | unsigned long count; | 75 | unsigned long count; |
87 | unsigned long head; /* head of the queue */ | 76 | unsigned long bits; |
88 | struct ipi_message ipi_message[BFIN_IPI_MSGQ_LEN]; | ||
89 | }; | 77 | }; |
90 | 78 | ||
91 | static DEFINE_PER_CPU(struct ipi_message_queue, ipi_msg_queue); | 79 | static DEFINE_PER_CPU(struct ipi_data, bfin_ipi); |
92 | 80 | ||
93 | static void ipi_cpu_stop(unsigned int cpu) | 81 | static void ipi_cpu_stop(unsigned int cpu) |
94 | { | 82 | { |
@@ -129,28 +117,6 @@ static void ipi_flush_icache(void *info) | |||
129 | blackfin_icache_flush_range(fdata->start, fdata->end); | 117 | blackfin_icache_flush_range(fdata->start, fdata->end); |
130 | } | 118 | } |
131 | 119 | ||
132 | static void ipi_call_function(unsigned int cpu, struct ipi_message *msg) | ||
133 | { | ||
134 | int wait; | ||
135 | void (*func)(void *info); | ||
136 | void *info; | ||
137 | func = msg->call_struct.func; | ||
138 | info = msg->call_struct.info; | ||
139 | wait = msg->call_struct.wait; | ||
140 | func(info); | ||
141 | if (wait) { | ||
142 | #ifdef __ARCH_SYNC_CORE_DCACHE | ||
143 | /* | ||
144 | * 'wait' usually means synchronization between CPUs. | ||
145 | * Invalidate D cache in case shared data was changed | ||
146 | * by func() to ensure cache coherence. | ||
147 | */ | ||
148 | resync_core_dcache(); | ||
149 | #endif | ||
150 | cpumask_clear_cpu(cpu, msg->call_struct.waitmask); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | /* Use IRQ_SUPPLE_0 to request reschedule. | 120 | /* Use IRQ_SUPPLE_0 to request reschedule. |
155 | * When returning from interrupt to user space, | 121 | * When returning from interrupt to user space, |
156 | * there is chance to reschedule */ | 122 | * there is chance to reschedule */ |
@@ -172,152 +138,95 @@ void ipi_timer(void) | |||
172 | 138 | ||
173 | static irqreturn_t ipi_handler_int1(int irq, void *dev_instance) | 139 | static irqreturn_t ipi_handler_int1(int irq, void *dev_instance) |
174 | { | 140 | { |
175 | struct ipi_message *msg; | 141 | struct ipi_data *bfin_ipi_data; |
176 | struct ipi_message_queue *msg_queue; | ||
177 | unsigned int cpu = smp_processor_id(); | 142 | unsigned int cpu = smp_processor_id(); |
178 | unsigned long flags; | 143 | unsigned long pending; |
144 | unsigned long msg; | ||
179 | 145 | ||
180 | platform_clear_ipi(cpu, IRQ_SUPPLE_1); | 146 | platform_clear_ipi(cpu, IRQ_SUPPLE_1); |
181 | 147 | ||
182 | msg_queue = &__get_cpu_var(ipi_msg_queue); | 148 | bfin_ipi_data = &__get_cpu_var(bfin_ipi); |
183 | 149 | ||
184 | spin_lock_irqsave(&msg_queue->lock, flags); | 150 | while ((pending = xchg(&bfin_ipi_data->bits, 0)) != 0) { |
185 | 151 | msg = 0; | |
186 | while (msg_queue->count) { | 152 | do { |
187 | msg = &msg_queue->ipi_message[msg_queue->head]; | 153 | msg = find_next_bit(&pending, BITS_PER_LONG, msg + 1); |
188 | switch (msg->type) { | 154 | switch (msg) { |
189 | case BFIN_IPI_TIMER: | 155 | case BFIN_IPI_TIMER: |
190 | ipi_timer(); | 156 | ipi_timer(); |
191 | break; | 157 | break; |
192 | case BFIN_IPI_RESCHEDULE: | 158 | case BFIN_IPI_RESCHEDULE: |
193 | scheduler_ipi(); | 159 | scheduler_ipi(); |
194 | break; | 160 | break; |
195 | case BFIN_IPI_CALL_FUNC: | 161 | case BFIN_IPI_CALL_FUNC: |
196 | ipi_call_function(cpu, msg); | 162 | generic_smp_call_function_interrupt(); |
197 | break; | 163 | break; |
198 | case BFIN_IPI_CPU_STOP: | 164 | |
199 | ipi_cpu_stop(cpu); | 165 | case BFIN_IPI_CALL_FUNC_SINGLE: |
200 | break; | 166 | generic_smp_call_function_single_interrupt(); |
201 | default: | 167 | break; |
202 | printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%lx\n", | 168 | |
203 | cpu, msg->type); | 169 | case BFIN_IPI_CPU_STOP: |
204 | break; | 170 | ipi_cpu_stop(cpu); |
205 | } | 171 | break; |
206 | msg_queue->head++; | 172 | } |
207 | msg_queue->head %= BFIN_IPI_MSGQ_LEN; | 173 | } while (msg < BITS_PER_LONG); |
208 | msg_queue->count--; | 174 | |
175 | smp_mb(); | ||
209 | } | 176 | } |
210 | spin_unlock_irqrestore(&msg_queue->lock, flags); | ||
211 | return IRQ_HANDLED; | 177 | return IRQ_HANDLED; |
212 | } | 178 | } |
213 | 179 | ||
214 | static void ipi_queue_init(void) | 180 | static void bfin_ipi_init(void) |
215 | { | 181 | { |
216 | unsigned int cpu; | 182 | unsigned int cpu; |
217 | struct ipi_message_queue *msg_queue; | 183 | struct ipi_data *bfin_ipi_data; |
218 | for_each_possible_cpu(cpu) { | 184 | for_each_possible_cpu(cpu) { |
219 | msg_queue = &per_cpu(ipi_msg_queue, cpu); | 185 | bfin_ipi_data = &per_cpu(bfin_ipi, cpu); |
220 | spin_lock_init(&msg_queue->lock); | 186 | bfin_ipi_data->bits = 0; |
221 | msg_queue->count = 0; | 187 | bfin_ipi_data->count = 0; |
222 | msg_queue->head = 0; | ||
223 | } | 188 | } |
224 | } | 189 | } |
225 | 190 | ||
226 | static inline void smp_send_message(cpumask_t callmap, unsigned long type, | 191 | void send_ipi(const struct cpumask *cpumask, enum ipi_message_type msg) |
227 | void (*func) (void *info), void *info, int wait) | ||
228 | { | 192 | { |
229 | unsigned int cpu; | 193 | unsigned int cpu; |
230 | struct ipi_message_queue *msg_queue; | 194 | struct ipi_data *bfin_ipi_data; |
231 | struct ipi_message *msg; | 195 | unsigned long flags; |
232 | unsigned long flags, next_msg; | 196 | |
233 | cpumask_t waitmask; /* waitmask is shared by all cpus */ | 197 | local_irq_save(flags); |
234 | 198 | ||
235 | cpumask_copy(&waitmask, &callmap); | 199 | for_each_cpu(cpu, cpumask) { |
236 | for_each_cpu(cpu, &callmap) { | 200 | bfin_ipi_data = &per_cpu(bfin_ipi, cpu); |
237 | msg_queue = &per_cpu(ipi_msg_queue, cpu); | 201 | smp_mb(); |
238 | spin_lock_irqsave(&msg_queue->lock, flags); | 202 | set_bit(msg, &bfin_ipi_data->bits); |
239 | if (msg_queue->count < BFIN_IPI_MSGQ_LEN) { | 203 | bfin_ipi_data->count++; |
240 | next_msg = (msg_queue->head + msg_queue->count) | ||
241 | % BFIN_IPI_MSGQ_LEN; | ||
242 | msg = &msg_queue->ipi_message[next_msg]; | ||
243 | msg->type = type; | ||
244 | if (type == BFIN_IPI_CALL_FUNC) { | ||
245 | msg->call_struct.func = func; | ||
246 | msg->call_struct.info = info; | ||
247 | msg->call_struct.wait = wait; | ||
248 | msg->call_struct.waitmask = &waitmask; | ||
249 | } | ||
250 | msg_queue->count++; | ||
251 | } else | ||
252 | panic("IPI message queue overflow\n"); | ||
253 | spin_unlock_irqrestore(&msg_queue->lock, flags); | ||
254 | platform_send_ipi_cpu(cpu, IRQ_SUPPLE_1); | 204 | platform_send_ipi_cpu(cpu, IRQ_SUPPLE_1); |
255 | } | 205 | } |
256 | 206 | ||
257 | if (wait) { | 207 | local_irq_restore(flags); |
258 | while (!cpumask_empty(&waitmask)) | ||
259 | blackfin_dcache_invalidate_range( | ||
260 | (unsigned long)(&waitmask), | ||
261 | (unsigned long)(&waitmask)); | ||
262 | #ifdef __ARCH_SYNC_CORE_DCACHE | ||
263 | /* | ||
264 | * Invalidate D cache in case shared data was changed by | ||
265 | * other processors to ensure cache coherence. | ||
266 | */ | ||
267 | resync_core_dcache(); | ||
268 | #endif | ||
269 | } | ||
270 | } | 208 | } |
271 | 209 | ||
272 | int smp_call_function(void (*func)(void *info), void *info, int wait) | 210 | void arch_send_call_function_single_ipi(int cpu) |
273 | { | 211 | { |
274 | cpumask_t callmap; | 212 | send_ipi(cpumask_of(cpu), BFIN_IPI_CALL_FUNC_SINGLE); |
275 | |||
276 | preempt_disable(); | ||
277 | cpumask_copy(&callmap, cpu_online_mask); | ||
278 | cpumask_clear_cpu(smp_processor_id(), &callmap); | ||
279 | if (!cpumask_empty(&callmap)) | ||
280 | smp_send_message(callmap, BFIN_IPI_CALL_FUNC, func, info, wait); | ||
281 | |||
282 | preempt_enable(); | ||
283 | |||
284 | return 0; | ||
285 | } | 213 | } |
286 | EXPORT_SYMBOL_GPL(smp_call_function); | ||
287 | 214 | ||
288 | int smp_call_function_single(int cpuid, void (*func) (void *info), void *info, | 215 | void arch_send_call_function_ipi_mask(const struct cpumask *mask) |
289 | int wait) | ||
290 | { | 216 | { |
291 | unsigned int cpu = cpuid; | 217 | send_ipi(mask, BFIN_IPI_CALL_FUNC); |
292 | cpumask_t callmap; | ||
293 | |||
294 | if (cpu_is_offline(cpu)) | ||
295 | return 0; | ||
296 | cpumask_clear(&callmap); | ||
297 | cpumask_set_cpu(cpu, &callmap); | ||
298 | |||
299 | smp_send_message(callmap, BFIN_IPI_CALL_FUNC, func, info, wait); | ||
300 | |||
301 | return 0; | ||
302 | } | 218 | } |
303 | EXPORT_SYMBOL_GPL(smp_call_function_single); | ||
304 | 219 | ||
305 | void smp_send_reschedule(int cpu) | 220 | void smp_send_reschedule(int cpu) |
306 | { | 221 | { |
307 | cpumask_t callmap; | 222 | send_ipi(cpumask_of(cpu), BFIN_IPI_RESCHEDULE); |
308 | /* simply trigger an ipi */ | ||
309 | |||
310 | cpumask_clear(&callmap); | ||
311 | cpumask_set_cpu(cpu, &callmap); | ||
312 | |||
313 | smp_send_message(callmap, BFIN_IPI_RESCHEDULE, NULL, NULL, 0); | ||
314 | 223 | ||
315 | return; | 224 | return; |
316 | } | 225 | } |
317 | 226 | ||
318 | void smp_send_msg(const struct cpumask *mask, unsigned long type) | 227 | void smp_send_msg(const struct cpumask *mask, unsigned long type) |
319 | { | 228 | { |
320 | smp_send_message(*mask, type, NULL, NULL, 0); | 229 | send_ipi(mask, type); |
321 | } | 230 | } |
322 | 231 | ||
323 | void smp_timer_broadcast(const struct cpumask *mask) | 232 | void smp_timer_broadcast(const struct cpumask *mask) |
@@ -333,7 +242,7 @@ void smp_send_stop(void) | |||
333 | cpumask_copy(&callmap, cpu_online_mask); | 242 | cpumask_copy(&callmap, cpu_online_mask); |
334 | cpumask_clear_cpu(smp_processor_id(), &callmap); | 243 | cpumask_clear_cpu(smp_processor_id(), &callmap); |
335 | if (!cpumask_empty(&callmap)) | 244 | if (!cpumask_empty(&callmap)) |
336 | smp_send_message(callmap, BFIN_IPI_CPU_STOP, NULL, NULL, 0); | 245 | send_ipi(&callmap, BFIN_IPI_CPU_STOP); |
337 | 246 | ||
338 | preempt_enable(); | 247 | preempt_enable(); |
339 | 248 | ||
@@ -436,7 +345,7 @@ void __init smp_prepare_boot_cpu(void) | |||
436 | void __init smp_prepare_cpus(unsigned int max_cpus) | 345 | void __init smp_prepare_cpus(unsigned int max_cpus) |
437 | { | 346 | { |
438 | platform_prepare_cpus(max_cpus); | 347 | platform_prepare_cpus(max_cpus); |
439 | ipi_queue_init(); | 348 | bfin_ipi_init(); |
440 | platform_request_ipi(IRQ_SUPPLE_0, ipi_handler_int0); | 349 | platform_request_ipi(IRQ_SUPPLE_0, ipi_handler_int0); |
441 | platform_request_ipi(IRQ_SUPPLE_1, ipi_handler_int1); | 350 | platform_request_ipi(IRQ_SUPPLE_1, ipi_handler_int1); |
442 | } | 351 | } |
diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h index 6c6defc24619..af9cf30ed474 100644 --- a/arch/parisc/include/asm/atomic.h +++ b/arch/parisc/include/asm/atomic.h | |||
@@ -141,7 +141,7 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) | |||
141 | 141 | ||
142 | #define atomic_sub_and_test(i,v) (atomic_sub_return((i),(v)) == 0) | 142 | #define atomic_sub_and_test(i,v) (atomic_sub_return((i),(v)) == 0) |
143 | 143 | ||
144 | #define ATOMIC_INIT(i) ((atomic_t) { (i) }) | 144 | #define ATOMIC_INIT(i) { (i) } |
145 | 145 | ||
146 | #define smp_mb__before_atomic_dec() smp_mb() | 146 | #define smp_mb__before_atomic_dec() smp_mb() |
147 | #define smp_mb__after_atomic_dec() smp_mb() | 147 | #define smp_mb__after_atomic_dec() smp_mb() |
@@ -150,7 +150,7 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) | |||
150 | 150 | ||
151 | #ifdef CONFIG_64BIT | 151 | #ifdef CONFIG_64BIT |
152 | 152 | ||
153 | #define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) | 153 | #define ATOMIC64_INIT(i) { (i) } |
154 | 154 | ||
155 | static __inline__ s64 | 155 | static __inline__ s64 |
156 | __atomic64_add_return(s64 i, atomic64_t *v) | 156 | __atomic64_add_return(s64 i, atomic64_t *v) |
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index d4b94b395c16..2c05a9292a81 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c | |||
@@ -309,7 +309,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp, | |||
309 | cregs->ksp = (unsigned long)stack | 309 | cregs->ksp = (unsigned long)stack |
310 | + (pregs->gr[21] & (THREAD_SIZE - 1)); | 310 | + (pregs->gr[21] & (THREAD_SIZE - 1)); |
311 | cregs->gr[30] = usp; | 311 | cregs->gr[30] = usp; |
312 | if (p->personality == PER_HPUX) { | 312 | if (personality(p->personality) == PER_HPUX) { |
313 | #ifdef CONFIG_HPUX | 313 | #ifdef CONFIG_HPUX |
314 | cregs->kpc = (unsigned long) &hpux_child_return; | 314 | cregs->kpc = (unsigned long) &hpux_child_return; |
315 | #else | 315 | #else |
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index c9b932260f47..7426e40699bd 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c | |||
@@ -225,12 +225,12 @@ long parisc_personality(unsigned long personality) | |||
225 | long err; | 225 | long err; |
226 | 226 | ||
227 | if (personality(current->personality) == PER_LINUX32 | 227 | if (personality(current->personality) == PER_LINUX32 |
228 | && personality == PER_LINUX) | 228 | && personality(personality) == PER_LINUX) |
229 | personality = PER_LINUX32; | 229 | personality = (personality & ~PER_MASK) | PER_LINUX32; |
230 | 230 | ||
231 | err = sys_personality(personality); | 231 | err = sys_personality(personality); |
232 | if (err == PER_LINUX32) | 232 | if (personality(err) == PER_LINUX32) |
233 | err = PER_LINUX; | 233 | err = (err & ~PER_MASK) | PER_LINUX; |
234 | 234 | ||
235 | return err; | 235 | return err; |
236 | } | 236 | } |
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 53b6dfa83344..54b73a28c205 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h | |||
@@ -386,6 +386,7 @@ extern unsigned long cpuidle_disable; | |||
386 | enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF}; | 386 | enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF}; |
387 | 387 | ||
388 | extern int powersave_nap; /* set if nap mode can be used in idle loop */ | 388 | extern int powersave_nap; /* set if nap mode can be used in idle loop */ |
389 | extern void power7_nap(void); | ||
389 | 390 | ||
390 | #ifdef CONFIG_PSERIES_IDLE | 391 | #ifdef CONFIG_PSERIES_IDLE |
391 | extern void update_smt_snooze_delay(int snooze); | 392 | extern void update_smt_snooze_delay(int snooze); |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 85b05c463fae..e8995727b1c1 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -76,6 +76,7 @@ int main(void) | |||
76 | DEFINE(SIGSEGV, SIGSEGV); | 76 | DEFINE(SIGSEGV, SIGSEGV); |
77 | DEFINE(NMI_MASK, NMI_MASK); | 77 | DEFINE(NMI_MASK, NMI_MASK); |
78 | DEFINE(THREAD_DSCR, offsetof(struct thread_struct, dscr)); | 78 | DEFINE(THREAD_DSCR, offsetof(struct thread_struct, dscr)); |
79 | DEFINE(THREAD_DSCR_INHERIT, offsetof(struct thread_struct, dscr_inherit)); | ||
79 | #else | 80 | #else |
80 | DEFINE(THREAD_INFO, offsetof(struct task_struct, stack)); | 81 | DEFINE(THREAD_INFO, offsetof(struct task_struct, stack)); |
81 | #endif /* CONFIG_PPC64 */ | 82 | #endif /* CONFIG_PPC64 */ |
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c index 5b25c8060fd6..a892680668d8 100644 --- a/arch/powerpc/kernel/dbell.c +++ b/arch/powerpc/kernel/dbell.c | |||
@@ -28,6 +28,8 @@ void doorbell_setup_this_cpu(void) | |||
28 | 28 | ||
29 | void doorbell_cause_ipi(int cpu, unsigned long data) | 29 | void doorbell_cause_ipi(int cpu, unsigned long data) |
30 | { | 30 | { |
31 | /* Order previous accesses vs. msgsnd, which is treated as a store */ | ||
32 | mb(); | ||
31 | ppc_msgsnd(PPC_DBELL, 0, data); | 33 | ppc_msgsnd(PPC_DBELL, 0, data); |
32 | } | 34 | } |
33 | 35 | ||
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 4b01a25e29ef..b40e0b4815b3 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -370,6 +370,12 @@ _GLOBAL(ret_from_fork) | |||
370 | li r3,0 | 370 | li r3,0 |
371 | b syscall_exit | 371 | b syscall_exit |
372 | 372 | ||
373 | .section ".toc","aw" | ||
374 | DSCR_DEFAULT: | ||
375 | .tc dscr_default[TC],dscr_default | ||
376 | |||
377 | .section ".text" | ||
378 | |||
373 | /* | 379 | /* |
374 | * This routine switches between two different tasks. The process | 380 | * This routine switches between two different tasks. The process |
375 | * state of one is saved on its kernel stack. Then the state | 381 | * state of one is saved on its kernel stack. Then the state |
@@ -509,9 +515,6 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) | |||
509 | mr r1,r8 /* start using new stack pointer */ | 515 | mr r1,r8 /* start using new stack pointer */ |
510 | std r7,PACAKSAVE(r13) | 516 | std r7,PACAKSAVE(r13) |
511 | 517 | ||
512 | ld r6,_CCR(r1) | ||
513 | mtcrf 0xFF,r6 | ||
514 | |||
515 | #ifdef CONFIG_ALTIVEC | 518 | #ifdef CONFIG_ALTIVEC |
516 | BEGIN_FTR_SECTION | 519 | BEGIN_FTR_SECTION |
517 | ld r0,THREAD_VRSAVE(r4) | 520 | ld r0,THREAD_VRSAVE(r4) |
@@ -520,14 +523,22 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
520 | #endif /* CONFIG_ALTIVEC */ | 523 | #endif /* CONFIG_ALTIVEC */ |
521 | #ifdef CONFIG_PPC64 | 524 | #ifdef CONFIG_PPC64 |
522 | BEGIN_FTR_SECTION | 525 | BEGIN_FTR_SECTION |
526 | lwz r6,THREAD_DSCR_INHERIT(r4) | ||
527 | ld r7,DSCR_DEFAULT@toc(2) | ||
523 | ld r0,THREAD_DSCR(r4) | 528 | ld r0,THREAD_DSCR(r4) |
524 | cmpd r0,r25 | 529 | cmpwi r6,0 |
525 | beq 1f | 530 | bne 1f |
531 | ld r0,0(r7) | ||
532 | 1: cmpd r0,r25 | ||
533 | beq 2f | ||
526 | mtspr SPRN_DSCR,r0 | 534 | mtspr SPRN_DSCR,r0 |
527 | 1: | 535 | 2: |
528 | END_FTR_SECTION_IFSET(CPU_FTR_DSCR) | 536 | END_FTR_SECTION_IFSET(CPU_FTR_DSCR) |
529 | #endif | 537 | #endif |
530 | 538 | ||
539 | ld r6,_CCR(r1) | ||
540 | mtcrf 0xFF,r6 | ||
541 | |||
531 | /* r3-r13 are destroyed -- Cort */ | 542 | /* r3-r13 are destroyed -- Cort */ |
532 | REST_8GPRS(14, r1) | 543 | REST_8GPRS(14, r1) |
533 | REST_10GPRS(22, r1) | 544 | REST_10GPRS(22, r1) |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index e894515e77bb..39aa97d3ff88 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -186,7 +186,7 @@ hardware_interrupt_hv: | |||
186 | KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x800) | 186 | KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x800) |
187 | 187 | ||
188 | MASKABLE_EXCEPTION_PSERIES(0x900, 0x900, decrementer) | 188 | MASKABLE_EXCEPTION_PSERIES(0x900, 0x900, decrementer) |
189 | MASKABLE_EXCEPTION_HV(0x980, 0x982, decrementer) | 189 | STD_EXCEPTION_HV(0x980, 0x982, hdecrementer) |
190 | 190 | ||
191 | STD_EXCEPTION_PSERIES(0xa00, 0xa00, trap_0a) | 191 | STD_EXCEPTION_PSERIES(0xa00, 0xa00, trap_0a) |
192 | KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xa00) | 192 | KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xa00) |
@@ -486,6 +486,7 @@ machine_check_common: | |||
486 | 486 | ||
487 | STD_EXCEPTION_COMMON_ASYNC(0x500, hardware_interrupt, do_IRQ) | 487 | STD_EXCEPTION_COMMON_ASYNC(0x500, hardware_interrupt, do_IRQ) |
488 | STD_EXCEPTION_COMMON_ASYNC(0x900, decrementer, .timer_interrupt) | 488 | STD_EXCEPTION_COMMON_ASYNC(0x900, decrementer, .timer_interrupt) |
489 | STD_EXCEPTION_COMMON(0x980, hdecrementer, .hdec_interrupt) | ||
489 | STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception) | 490 | STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception) |
490 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) | 491 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) |
491 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) | 492 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) |
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S index 7140d838339e..e11863f4e595 100644 --- a/arch/powerpc/kernel/idle_power7.S +++ b/arch/powerpc/kernel/idle_power7.S | |||
@@ -28,7 +28,9 @@ _GLOBAL(power7_idle) | |||
28 | lwz r4,ADDROFF(powersave_nap)(r3) | 28 | lwz r4,ADDROFF(powersave_nap)(r3) |
29 | cmpwi 0,r4,0 | 29 | cmpwi 0,r4,0 |
30 | beqlr | 30 | beqlr |
31 | /* fall through */ | ||
31 | 32 | ||
33 | _GLOBAL(power7_nap) | ||
32 | /* NAP is a state loss, we create a regs frame on the | 34 | /* NAP is a state loss, we create a regs frame on the |
33 | * stack, fill it up with the state we care about and | 35 | * stack, fill it up with the state we care about and |
34 | * stick a pointer to it in PACAR1. We really only | 36 | * stick a pointer to it in PACAR1. We really only |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 710f400476de..1a1f2ddfb581 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -802,16 +802,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
802 | #endif /* CONFIG_PPC_STD_MMU_64 */ | 802 | #endif /* CONFIG_PPC_STD_MMU_64 */ |
803 | #ifdef CONFIG_PPC64 | 803 | #ifdef CONFIG_PPC64 |
804 | if (cpu_has_feature(CPU_FTR_DSCR)) { | 804 | if (cpu_has_feature(CPU_FTR_DSCR)) { |
805 | if (current->thread.dscr_inherit) { | 805 | p->thread.dscr_inherit = current->thread.dscr_inherit; |
806 | p->thread.dscr_inherit = 1; | 806 | p->thread.dscr = current->thread.dscr; |
807 | p->thread.dscr = current->thread.dscr; | ||
808 | } else if (0 != dscr_default) { | ||
809 | p->thread.dscr_inherit = 1; | ||
810 | p->thread.dscr = dscr_default; | ||
811 | } else { | ||
812 | p->thread.dscr_inherit = 0; | ||
813 | p->thread.dscr = 0; | ||
814 | } | ||
815 | } | 807 | } |
816 | #endif | 808 | #endif |
817 | 809 | ||
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 0321007086f7..8d4214afc21d 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -198,8 +198,15 @@ void smp_muxed_ipi_message_pass(int cpu, int msg) | |||
198 | struct cpu_messages *info = &per_cpu(ipi_message, cpu); | 198 | struct cpu_messages *info = &per_cpu(ipi_message, cpu); |
199 | char *message = (char *)&info->messages; | 199 | char *message = (char *)&info->messages; |
200 | 200 | ||
201 | /* | ||
202 | * Order previous accesses before accesses in the IPI handler. | ||
203 | */ | ||
204 | smp_mb(); | ||
201 | message[msg] = 1; | 205 | message[msg] = 1; |
202 | mb(); | 206 | /* |
207 | * cause_ipi functions are required to include a full barrier | ||
208 | * before doing whatever causes the IPI. | ||
209 | */ | ||
203 | smp_ops->cause_ipi(cpu, info->data); | 210 | smp_ops->cause_ipi(cpu, info->data); |
204 | } | 211 | } |
205 | 212 | ||
@@ -211,7 +218,7 @@ irqreturn_t smp_ipi_demux(void) | |||
211 | mb(); /* order any irq clear */ | 218 | mb(); /* order any irq clear */ |
212 | 219 | ||
213 | do { | 220 | do { |
214 | all = xchg_local(&info->messages, 0); | 221 | all = xchg(&info->messages, 0); |
215 | 222 | ||
216 | #ifdef __BIG_ENDIAN | 223 | #ifdef __BIG_ENDIAN |
217 | if (all & (1 << (24 - 8 * PPC_MSG_CALL_FUNCTION))) | 224 | if (all & (1 << (24 - 8 * PPC_MSG_CALL_FUNCTION))) |
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 3529446c2abd..8302af649219 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c | |||
@@ -194,6 +194,14 @@ static ssize_t show_dscr_default(struct device *dev, | |||
194 | return sprintf(buf, "%lx\n", dscr_default); | 194 | return sprintf(buf, "%lx\n", dscr_default); |
195 | } | 195 | } |
196 | 196 | ||
197 | static void update_dscr(void *dummy) | ||
198 | { | ||
199 | if (!current->thread.dscr_inherit) { | ||
200 | current->thread.dscr = dscr_default; | ||
201 | mtspr(SPRN_DSCR, dscr_default); | ||
202 | } | ||
203 | } | ||
204 | |||
197 | static ssize_t __used store_dscr_default(struct device *dev, | 205 | static ssize_t __used store_dscr_default(struct device *dev, |
198 | struct device_attribute *attr, const char *buf, | 206 | struct device_attribute *attr, const char *buf, |
199 | size_t count) | 207 | size_t count) |
@@ -206,6 +214,8 @@ static ssize_t __used store_dscr_default(struct device *dev, | |||
206 | return -EINVAL; | 214 | return -EINVAL; |
207 | dscr_default = val; | 215 | dscr_default = val; |
208 | 216 | ||
217 | on_each_cpu(update_dscr, NULL, 1); | ||
218 | |||
209 | return count; | 219 | return count; |
210 | } | 220 | } |
211 | 221 | ||
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index be171ee73bf8..e49e93191b69 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -535,6 +535,15 @@ void timer_interrupt(struct pt_regs * regs) | |||
535 | trace_timer_interrupt_exit(regs); | 535 | trace_timer_interrupt_exit(regs); |
536 | } | 536 | } |
537 | 537 | ||
538 | /* | ||
539 | * Hypervisor decrementer interrupts shouldn't occur but are sometimes | ||
540 | * left pending on exit from a KVM guest. We don't need to do anything | ||
541 | * to clear them, as they are edge-triggered. | ||
542 | */ | ||
543 | void hdec_interrupt(struct pt_regs *regs) | ||
544 | { | ||
545 | } | ||
546 | |||
538 | #ifdef CONFIG_SUSPEND | 547 | #ifdef CONFIG_SUSPEND |
539 | static void generic_suspend_disable_irqs(void) | 548 | static void generic_suspend_disable_irqs(void) |
540 | { | 549 | { |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 158972341a2d..ae0843fa7a61 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -972,8 +972,9 @@ static int emulate_instruction(struct pt_regs *regs) | |||
972 | cpu_has_feature(CPU_FTR_DSCR)) { | 972 | cpu_has_feature(CPU_FTR_DSCR)) { |
973 | PPC_WARN_EMULATED(mtdscr, regs); | 973 | PPC_WARN_EMULATED(mtdscr, regs); |
974 | rd = (instword >> 21) & 0x1f; | 974 | rd = (instword >> 21) & 0x1f; |
975 | mtspr(SPRN_DSCR, regs->gpr[rd]); | 975 | current->thread.dscr = regs->gpr[rd]; |
976 | current->thread.dscr_inherit = 1; | 976 | current->thread.dscr_inherit = 1; |
977 | mtspr(SPRN_DSCR, current->thread.dscr); | ||
977 | return 0; | 978 | return 0; |
978 | } | 979 | } |
979 | #endif | 980 | #endif |
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index dd223b3eb333..17e5b2364312 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c | |||
@@ -20,7 +20,7 @@ int patch_instruction(unsigned int *addr, unsigned int instr) | |||
20 | { | 20 | { |
21 | int err; | 21 | int err; |
22 | 22 | ||
23 | err = __put_user(instr, addr); | 23 | __put_user_size(instr, addr, 4, err); |
24 | if (err) | 24 | if (err) |
25 | return err; | 25 | return err; |
26 | asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (addr)); | 26 | asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (addr)); |
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 39b159751c35..59213cfaeca9 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
@@ -1436,11 +1436,11 @@ static long vphn_get_associativity(unsigned long cpu, | |||
1436 | 1436 | ||
1437 | /* | 1437 | /* |
1438 | * Update the node maps and sysfs entries for each cpu whose home node | 1438 | * Update the node maps and sysfs entries for each cpu whose home node |
1439 | * has changed. | 1439 | * has changed. Returns 1 when the topology has changed, and 0 otherwise. |
1440 | */ | 1440 | */ |
1441 | int arch_update_cpu_topology(void) | 1441 | int arch_update_cpu_topology(void) |
1442 | { | 1442 | { |
1443 | int cpu, nid, old_nid; | 1443 | int cpu, nid, old_nid, changed = 0; |
1444 | unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0}; | 1444 | unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0}; |
1445 | struct device *dev; | 1445 | struct device *dev; |
1446 | 1446 | ||
@@ -1466,9 +1466,10 @@ int arch_update_cpu_topology(void) | |||
1466 | dev = get_cpu_device(cpu); | 1466 | dev = get_cpu_device(cpu); |
1467 | if (dev) | 1467 | if (dev) |
1468 | kobject_uevent(&dev->kobj, KOBJ_CHANGE); | 1468 | kobject_uevent(&dev->kobj, KOBJ_CHANGE); |
1469 | changed = 1; | ||
1469 | } | 1470 | } |
1470 | 1471 | ||
1471 | return 1; | 1472 | return changed; |
1472 | } | 1473 | } |
1473 | 1474 | ||
1474 | static void topology_work_fn(struct work_struct *work) | 1475 | static void topology_work_fn(struct work_struct *work) |
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index 3ef46254c35b..7698b6e13c57 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c | |||
@@ -106,14 +106,6 @@ static void pnv_smp_cpu_kill_self(void) | |||
106 | { | 106 | { |
107 | unsigned int cpu; | 107 | unsigned int cpu; |
108 | 108 | ||
109 | /* If powersave_nap is enabled, use NAP mode, else just | ||
110 | * spin aimlessly | ||
111 | */ | ||
112 | if (!powersave_nap) { | ||
113 | generic_mach_cpu_die(); | ||
114 | return; | ||
115 | } | ||
116 | |||
117 | /* Standard hot unplug procedure */ | 109 | /* Standard hot unplug procedure */ |
118 | local_irq_disable(); | 110 | local_irq_disable(); |
119 | idle_task_exit(); | 111 | idle_task_exit(); |
@@ -128,7 +120,7 @@ static void pnv_smp_cpu_kill_self(void) | |||
128 | */ | 120 | */ |
129 | mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1); | 121 | mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1); |
130 | while (!generic_check_cpu_restart(cpu)) { | 122 | while (!generic_check_cpu_restart(cpu)) { |
131 | power7_idle(); | 123 | power7_nap(); |
132 | if (!generic_check_cpu_restart(cpu)) { | 124 | if (!generic_check_cpu_restart(cpu)) { |
133 | DBG("CPU%d Unexpected exit while offline !\n", cpu); | 125 | DBG("CPU%d Unexpected exit while offline !\n", cpu); |
134 | /* We may be getting an IPI, so we re-enable | 126 | /* We may be getting an IPI, so we re-enable |
diff --git a/arch/powerpc/sysdev/xics/icp-hv.c b/arch/powerpc/sysdev/xics/icp-hv.c index 14469cf9df68..df0fc5821469 100644 --- a/arch/powerpc/sysdev/xics/icp-hv.c +++ b/arch/powerpc/sysdev/xics/icp-hv.c | |||
@@ -65,7 +65,11 @@ static inline void icp_hv_set_xirr(unsigned int value) | |||
65 | static inline void icp_hv_set_qirr(int n_cpu , u8 value) | 65 | static inline void icp_hv_set_qirr(int n_cpu , u8 value) |
66 | { | 66 | { |
67 | int hw_cpu = get_hard_smp_processor_id(n_cpu); | 67 | int hw_cpu = get_hard_smp_processor_id(n_cpu); |
68 | long rc = plpar_hcall_norets(H_IPI, hw_cpu, value); | 68 | long rc; |
69 | |||
70 | /* Make sure all previous accesses are ordered before IPI sending */ | ||
71 | mb(); | ||
72 | rc = plpar_hcall_norets(H_IPI, hw_cpu, value); | ||
69 | if (rc != H_SUCCESS) { | 73 | if (rc != H_SUCCESS) { |
70 | pr_err("%s: bad return code qirr cpu=%d hw_cpu=%d mfrr=0x%x " | 74 | pr_err("%s: bad return code qirr cpu=%d hw_cpu=%d mfrr=0x%x " |
71 | "returned %ld\n", __func__, n_cpu, hw_cpu, value, rc); | 75 | "returned %ld\n", __func__, n_cpu, hw_cpu, value, rc); |
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index 32e8449640fa..9b94a160fe7f 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h | |||
@@ -180,7 +180,8 @@ extern char elf_platform[]; | |||
180 | #define ELF_PLATFORM (elf_platform) | 180 | #define ELF_PLATFORM (elf_platform) |
181 | 181 | ||
182 | #ifndef CONFIG_64BIT | 182 | #ifndef CONFIG_64BIT |
183 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX) | 183 | #define SET_PERSONALITY(ex) \ |
184 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))) | ||
184 | #else /* CONFIG_64BIT */ | 185 | #else /* CONFIG_64BIT */ |
185 | #define SET_PERSONALITY(ex) \ | 186 | #define SET_PERSONALITY(ex) \ |
186 | do { \ | 187 | do { \ |
diff --git a/arch/s390/include/asm/posix_types.h b/arch/s390/include/asm/posix_types.h index 7bcc14e395f0..bf2a2ad2f800 100644 --- a/arch/s390/include/asm/posix_types.h +++ b/arch/s390/include/asm/posix_types.h | |||
@@ -13,6 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | typedef unsigned long __kernel_size_t; | 15 | typedef unsigned long __kernel_size_t; |
16 | typedef long __kernel_ssize_t; | ||
16 | #define __kernel_size_t __kernel_size_t | 17 | #define __kernel_size_t __kernel_size_t |
17 | 18 | ||
18 | typedef unsigned short __kernel_old_dev_t; | 19 | typedef unsigned short __kernel_old_dev_t; |
@@ -25,7 +26,6 @@ typedef unsigned short __kernel_mode_t; | |||
25 | typedef unsigned short __kernel_ipc_pid_t; | 26 | typedef unsigned short __kernel_ipc_pid_t; |
26 | typedef unsigned short __kernel_uid_t; | 27 | typedef unsigned short __kernel_uid_t; |
27 | typedef unsigned short __kernel_gid_t; | 28 | typedef unsigned short __kernel_gid_t; |
28 | typedef int __kernel_ssize_t; | ||
29 | typedef int __kernel_ptrdiff_t; | 29 | typedef int __kernel_ptrdiff_t; |
30 | 30 | ||
31 | #else /* __s390x__ */ | 31 | #else /* __s390x__ */ |
@@ -35,7 +35,6 @@ typedef unsigned int __kernel_mode_t; | |||
35 | typedef int __kernel_ipc_pid_t; | 35 | typedef int __kernel_ipc_pid_t; |
36 | typedef unsigned int __kernel_uid_t; | 36 | typedef unsigned int __kernel_uid_t; |
37 | typedef unsigned int __kernel_gid_t; | 37 | typedef unsigned int __kernel_gid_t; |
38 | typedef long __kernel_ssize_t; | ||
39 | typedef long __kernel_ptrdiff_t; | 38 | typedef long __kernel_ptrdiff_t; |
40 | typedef unsigned long __kernel_sigset_t; /* at least 32 bits */ | 39 | typedef unsigned long __kernel_sigset_t; /* at least 32 bits */ |
41 | 40 | ||
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index a0a8340daafa..ce26ac3cb162 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h | |||
@@ -44,6 +44,7 @@ static inline void smp_call_online_cpu(void (*func)(void *), void *data) | |||
44 | } | 44 | } |
45 | 45 | ||
46 | static inline int smp_find_processor_id(int address) { return 0; } | 46 | static inline int smp_find_processor_id(int address) { return 0; } |
47 | static inline int smp_store_status(int cpu) { return 0; } | ||
47 | static inline int smp_vcpu_scheduled(int cpu) { return 1; } | 48 | static inline int smp_vcpu_scheduled(int cpu) { return 1; } |
48 | static inline void smp_yield_cpu(int cpu) { } | 49 | static inline void smp_yield_cpu(int cpu) { } |
49 | static inline void smp_yield(void) { } | 50 | static inline void smp_yield(void) { } |
diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c index a1e9d69a9c90..584b93674ea4 100644 --- a/arch/s390/oprofile/init.c +++ b/arch/s390/oprofile/init.c | |||
@@ -169,7 +169,7 @@ static ssize_t hw_interval_write(struct file *file, char const __user *buf, | |||
169 | if (*offset) | 169 | if (*offset) |
170 | return -EINVAL; | 170 | return -EINVAL; |
171 | retval = oprofilefs_ulong_from_user(&val, buf, count); | 171 | retval = oprofilefs_ulong_from_user(&val, buf, count); |
172 | if (retval) | 172 | if (retval <= 0) |
173 | return retval; | 173 | return retval; |
174 | if (val < oprofile_min_interval) | 174 | if (val < oprofile_min_interval) |
175 | oprofile_hw_interval = oprofile_min_interval; | 175 | oprofile_hw_interval = oprofile_min_interval; |
@@ -212,7 +212,7 @@ static ssize_t hwsampler_zero_write(struct file *file, char const __user *buf, | |||
212 | return -EINVAL; | 212 | return -EINVAL; |
213 | 213 | ||
214 | retval = oprofilefs_ulong_from_user(&val, buf, count); | 214 | retval = oprofilefs_ulong_from_user(&val, buf, count); |
215 | if (retval) | 215 | if (retval <= 0) |
216 | return retval; | 216 | return retval; |
217 | if (val != 0) | 217 | if (val != 0) |
218 | return -EINVAL; | 218 | return -EINVAL; |
@@ -243,7 +243,7 @@ static ssize_t hwsampler_kernel_write(struct file *file, char const __user *buf, | |||
243 | return -EINVAL; | 243 | return -EINVAL; |
244 | 244 | ||
245 | retval = oprofilefs_ulong_from_user(&val, buf, count); | 245 | retval = oprofilefs_ulong_from_user(&val, buf, count); |
246 | if (retval) | 246 | if (retval <= 0) |
247 | return retval; | 247 | return retval; |
248 | 248 | ||
249 | if (val != 0 && val != 1) | 249 | if (val != 0 && val != 1) |
@@ -278,7 +278,7 @@ static ssize_t hwsampler_user_write(struct file *file, char const __user *buf, | |||
278 | return -EINVAL; | 278 | return -EINVAL; |
279 | 279 | ||
280 | retval = oprofilefs_ulong_from_user(&val, buf, count); | 280 | retval = oprofilefs_ulong_from_user(&val, buf, count); |
281 | if (retval) | 281 | if (retval <= 0) |
282 | return retval; | 282 | return retval; |
283 | 283 | ||
284 | if (val != 0 && val != 1) | 284 | if (val != 0 && val != 1) |
@@ -317,7 +317,7 @@ static ssize_t timer_enabled_write(struct file *file, char const __user *buf, | |||
317 | return -EINVAL; | 317 | return -EINVAL; |
318 | 318 | ||
319 | retval = oprofilefs_ulong_from_user(&val, buf, count); | 319 | retval = oprofilefs_ulong_from_user(&val, buf, count); |
320 | if (retval) | 320 | if (retval <= 0) |
321 | return retval; | 321 | return retval; |
322 | 322 | ||
323 | if (val != 0 && val != 1) | 323 | if (val != 0 && val != 1) |
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index f60238559af3..0748fe0c8a73 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c | |||
@@ -114,7 +114,7 @@ static void deliver_alarm(void) | |||
114 | skew += this_tick - last_tick; | 114 | skew += this_tick - last_tick; |
115 | 115 | ||
116 | while (skew >= one_tick) { | 116 | while (skew >= one_tick) { |
117 | alarm_handler(SIGVTALRM, NULL); | 117 | alarm_handler(SIGVTALRM, NULL, NULL); |
118 | skew -= one_tick; | 118 | skew -= one_tick; |
119 | } | 119 | } |
120 | 120 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 7f2739e03e79..0d3d63afa76a 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -2008,6 +2008,7 @@ __init int intel_pmu_init(void) | |||
2008 | break; | 2008 | break; |
2009 | 2009 | ||
2010 | case 28: /* Atom */ | 2010 | case 28: /* Atom */ |
2011 | case 54: /* Cedariew */ | ||
2011 | memcpy(hw_cache_event_ids, atom_hw_cache_event_ids, | 2012 | memcpy(hw_cache_event_ids, atom_hw_cache_event_ids, |
2012 | sizeof(hw_cache_event_ids)); | 2013 | sizeof(hw_cache_event_ids)); |
2013 | 2014 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c index 520b4265fcd2..da02e9cc3754 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c +++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c | |||
@@ -686,7 +686,8 @@ void intel_pmu_lbr_init_atom(void) | |||
686 | * to have an operational LBR which can freeze | 686 | * to have an operational LBR which can freeze |
687 | * on PMU interrupt | 687 | * on PMU interrupt |
688 | */ | 688 | */ |
689 | if (boot_cpu_data.x86_mask < 10) { | 689 | if (boot_cpu_data.x86_model == 28 |
690 | && boot_cpu_data.x86_mask < 10) { | ||
690 | pr_cont("LBR disabled due to erratum"); | 691 | pr_cont("LBR disabled due to erratum"); |
691 | return; | 692 | return; |
692 | } | 693 | } |
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index 4873e62db6a1..9e5bcf1e2376 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c | |||
@@ -225,6 +225,9 @@ static ssize_t microcode_write(struct file *file, const char __user *buf, | |||
225 | if (do_microcode_update(buf, len) == 0) | 225 | if (do_microcode_update(buf, len) == 0) |
226 | ret = (ssize_t)len; | 226 | ret = (ssize_t)len; |
227 | 227 | ||
228 | if (ret > 0) | ||
229 | perf_check_microcode(); | ||
230 | |||
228 | mutex_unlock(µcode_mutex); | 231 | mutex_unlock(µcode_mutex); |
229 | put_online_cpus(); | 232 | put_online_cpus(); |
230 | 233 | ||
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index e498b18f010c..9fc9aa7ac703 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c | |||
@@ -318,7 +318,7 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val) | |||
318 | if (val & 0x10) { | 318 | if (val & 0x10) { |
319 | u8 edge_irr = s->irr & ~s->elcr; | 319 | u8 edge_irr = s->irr & ~s->elcr; |
320 | int i; | 320 | int i; |
321 | bool found; | 321 | bool found = false; |
322 | struct kvm_vcpu *vcpu; | 322 | struct kvm_vcpu *vcpu; |
323 | 323 | ||
324 | s->init4 = val & 1; | 324 | s->init4 = val & 1; |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index c00f03de1b79..b1eb202ee76a 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -3619,6 +3619,7 @@ static void seg_setup(int seg) | |||
3619 | 3619 | ||
3620 | static int alloc_apic_access_page(struct kvm *kvm) | 3620 | static int alloc_apic_access_page(struct kvm *kvm) |
3621 | { | 3621 | { |
3622 | struct page *page; | ||
3622 | struct kvm_userspace_memory_region kvm_userspace_mem; | 3623 | struct kvm_userspace_memory_region kvm_userspace_mem; |
3623 | int r = 0; | 3624 | int r = 0; |
3624 | 3625 | ||
@@ -3633,7 +3634,13 @@ static int alloc_apic_access_page(struct kvm *kvm) | |||
3633 | if (r) | 3634 | if (r) |
3634 | goto out; | 3635 | goto out; |
3635 | 3636 | ||
3636 | kvm->arch.apic_access_page = gfn_to_page(kvm, 0xfee00); | 3637 | page = gfn_to_page(kvm, 0xfee00); |
3638 | if (is_error_page(page)) { | ||
3639 | r = -EFAULT; | ||
3640 | goto out; | ||
3641 | } | ||
3642 | |||
3643 | kvm->arch.apic_access_page = page; | ||
3637 | out: | 3644 | out: |
3638 | mutex_unlock(&kvm->slots_lock); | 3645 | mutex_unlock(&kvm->slots_lock); |
3639 | return r; | 3646 | return r; |
@@ -3641,6 +3648,7 @@ out: | |||
3641 | 3648 | ||
3642 | static int alloc_identity_pagetable(struct kvm *kvm) | 3649 | static int alloc_identity_pagetable(struct kvm *kvm) |
3643 | { | 3650 | { |
3651 | struct page *page; | ||
3644 | struct kvm_userspace_memory_region kvm_userspace_mem; | 3652 | struct kvm_userspace_memory_region kvm_userspace_mem; |
3645 | int r = 0; | 3653 | int r = 0; |
3646 | 3654 | ||
@@ -3656,8 +3664,13 @@ static int alloc_identity_pagetable(struct kvm *kvm) | |||
3656 | if (r) | 3664 | if (r) |
3657 | goto out; | 3665 | goto out; |
3658 | 3666 | ||
3659 | kvm->arch.ept_identity_pagetable = gfn_to_page(kvm, | 3667 | page = gfn_to_page(kvm, kvm->arch.ept_identity_map_addr >> PAGE_SHIFT); |
3660 | kvm->arch.ept_identity_map_addr >> PAGE_SHIFT); | 3668 | if (is_error_page(page)) { |
3669 | r = -EFAULT; | ||
3670 | goto out; | ||
3671 | } | ||
3672 | |||
3673 | kvm->arch.ept_identity_pagetable = page; | ||
3661 | out: | 3674 | out: |
3662 | mutex_unlock(&kvm->slots_lock); | 3675 | mutex_unlock(&kvm->slots_lock); |
3663 | return r; | 3676 | return r; |
@@ -6575,7 +6588,7 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) | |||
6575 | /* Exposing INVPCID only when PCID is exposed */ | 6588 | /* Exposing INVPCID only when PCID is exposed */ |
6576 | best = kvm_find_cpuid_entry(vcpu, 0x7, 0); | 6589 | best = kvm_find_cpuid_entry(vcpu, 0x7, 0); |
6577 | if (vmx_invpcid_supported() && | 6590 | if (vmx_invpcid_supported() && |
6578 | best && (best->ecx & bit(X86_FEATURE_INVPCID)) && | 6591 | best && (best->ebx & bit(X86_FEATURE_INVPCID)) && |
6579 | guest_cpuid_has_pcid(vcpu)) { | 6592 | guest_cpuid_has_pcid(vcpu)) { |
6580 | exec_control |= SECONDARY_EXEC_ENABLE_INVPCID; | 6593 | exec_control |= SECONDARY_EXEC_ENABLE_INVPCID; |
6581 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, | 6594 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, |
@@ -6585,7 +6598,7 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) | |||
6585 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, | 6598 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, |
6586 | exec_control); | 6599 | exec_control); |
6587 | if (best) | 6600 | if (best) |
6588 | best->ecx &= ~bit(X86_FEATURE_INVPCID); | 6601 | best->ebx &= ~bit(X86_FEATURE_INVPCID); |
6589 | } | 6602 | } |
6590 | } | 6603 | } |
6591 | 6604 | ||
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index dce75b760312..2966c847d489 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -2000,6 +2000,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) | |||
2000 | case MSR_KVM_STEAL_TIME: | 2000 | case MSR_KVM_STEAL_TIME: |
2001 | data = vcpu->arch.st.msr_val; | 2001 | data = vcpu->arch.st.msr_val; |
2002 | break; | 2002 | break; |
2003 | case MSR_KVM_PV_EOI_EN: | ||
2004 | data = vcpu->arch.pv_eoi.msr_val; | ||
2005 | break; | ||
2003 | case MSR_IA32_P5_MC_ADDR: | 2006 | case MSR_IA32_P5_MC_ADDR: |
2004 | case MSR_IA32_P5_MC_TYPE: | 2007 | case MSR_IA32_P5_MC_TYPE: |
2005 | case MSR_IA32_MCG_CAP: | 2008 | case MSR_IA32_MCG_CAP: |
@@ -5110,17 +5113,20 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu) | |||
5110 | !kvm_event_needs_reinjection(vcpu); | 5113 | !kvm_event_needs_reinjection(vcpu); |
5111 | } | 5114 | } |
5112 | 5115 | ||
5113 | static void vapic_enter(struct kvm_vcpu *vcpu) | 5116 | static int vapic_enter(struct kvm_vcpu *vcpu) |
5114 | { | 5117 | { |
5115 | struct kvm_lapic *apic = vcpu->arch.apic; | 5118 | struct kvm_lapic *apic = vcpu->arch.apic; |
5116 | struct page *page; | 5119 | struct page *page; |
5117 | 5120 | ||
5118 | if (!apic || !apic->vapic_addr) | 5121 | if (!apic || !apic->vapic_addr) |
5119 | return; | 5122 | return 0; |
5120 | 5123 | ||
5121 | page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT); | 5124 | page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT); |
5125 | if (is_error_page(page)) | ||
5126 | return -EFAULT; | ||
5122 | 5127 | ||
5123 | vcpu->arch.apic->vapic_page = page; | 5128 | vcpu->arch.apic->vapic_page = page; |
5129 | return 0; | ||
5124 | } | 5130 | } |
5125 | 5131 | ||
5126 | static void vapic_exit(struct kvm_vcpu *vcpu) | 5132 | static void vapic_exit(struct kvm_vcpu *vcpu) |
@@ -5427,7 +5433,11 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) | |||
5427 | } | 5433 | } |
5428 | 5434 | ||
5429 | vcpu->srcu_idx = srcu_read_lock(&kvm->srcu); | 5435 | vcpu->srcu_idx = srcu_read_lock(&kvm->srcu); |
5430 | vapic_enter(vcpu); | 5436 | r = vapic_enter(vcpu); |
5437 | if (r) { | ||
5438 | srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx); | ||
5439 | return r; | ||
5440 | } | ||
5431 | 5441 | ||
5432 | r = 1; | 5442 | r = 1; |
5433 | while (r > 0) { | 5443 | while (r > 0) { |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index b65a76133f4f..5141d808e751 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -1283,7 +1283,7 @@ static void xen_flush_tlb_others(const struct cpumask *cpus, | |||
1283 | cpumask_clear_cpu(smp_processor_id(), to_cpumask(args->mask)); | 1283 | cpumask_clear_cpu(smp_processor_id(), to_cpumask(args->mask)); |
1284 | 1284 | ||
1285 | args->op.cmd = MMUEXT_TLB_FLUSH_MULTI; | 1285 | args->op.cmd = MMUEXT_TLB_FLUSH_MULTI; |
1286 | if (start != TLB_FLUSH_ALL && (end - start) <= PAGE_SIZE) { | 1286 | if (end != TLB_FLUSH_ALL && (end - start) <= PAGE_SIZE) { |
1287 | args->op.cmd = MMUEXT_INVLPG_MULTI; | 1287 | args->op.cmd = MMUEXT_INVLPG_MULTI; |
1288 | args->op.arg1.linear_addr = start; | 1288 | args->op.arg1.linear_addr = start; |
1289 | } | 1289 | } |
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index d4b255463253..76ba0e97e530 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c | |||
@@ -599,7 +599,7 @@ bool __init early_can_reuse_p2m_middle(unsigned long set_pfn, unsigned long set_ | |||
599 | if (p2m_index(set_pfn)) | 599 | if (p2m_index(set_pfn)) |
600 | return false; | 600 | return false; |
601 | 601 | ||
602 | for (pfn = 0; pfn <= MAX_DOMAIN_PAGES; pfn += P2M_PER_PAGE) { | 602 | for (pfn = 0; pfn < MAX_DOMAIN_PAGES; pfn += P2M_PER_PAGE) { |
603 | topidx = p2m_top_index(pfn); | 603 | topidx = p2m_top_index(pfn); |
604 | 604 | ||
605 | if (!p2m_top[topidx]) | 605 | if (!p2m_top[topidx]) |
diff --git a/crypto/authenc.c b/crypto/authenc.c index 5ef7ba6b6a76..d0583a4489e6 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c | |||
@@ -336,7 +336,7 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv, | |||
336 | cryptlen += ivsize; | 336 | cryptlen += ivsize; |
337 | } | 337 | } |
338 | 338 | ||
339 | if (sg_is_last(assoc)) { | 339 | if (req->assoclen && sg_is_last(assoc)) { |
340 | authenc_ahash_fn = crypto_authenc_ahash; | 340 | authenc_ahash_fn = crypto_authenc_ahash; |
341 | sg_init_table(asg, 2); | 341 | sg_init_table(asg, 2); |
342 | sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset); | 342 | sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset); |
@@ -490,7 +490,7 @@ static int crypto_authenc_iverify(struct aead_request *req, u8 *iv, | |||
490 | cryptlen += ivsize; | 490 | cryptlen += ivsize; |
491 | } | 491 | } |
492 | 492 | ||
493 | if (sg_is_last(assoc)) { | 493 | if (req->assoclen && sg_is_last(assoc)) { |
494 | authenc_ahash_fn = crypto_authenc_ahash; | 494 | authenc_ahash_fn = crypto_authenc_ahash; |
495 | sg_init_table(asg, 2); | 495 | sg_init_table(asg, 2); |
496 | sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset); | 496 | sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset); |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 9628652e080c..e0596954290b 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -237,6 +237,16 @@ static int __acpi_bus_get_power(struct acpi_device *device, int *state) | |||
237 | } else if (result == ACPI_STATE_D3_HOT) { | 237 | } else if (result == ACPI_STATE_D3_HOT) { |
238 | result = ACPI_STATE_D3; | 238 | result = ACPI_STATE_D3; |
239 | } | 239 | } |
240 | |||
241 | /* | ||
242 | * If we were unsure about the device parent's power state up to this | ||
243 | * point, the fact that the device is in D0 implies that the parent has | ||
244 | * to be in D0 too. | ||
245 | */ | ||
246 | if (device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN | ||
247 | && result == ACPI_STATE_D0) | ||
248 | device->parent->power.state = ACPI_STATE_D0; | ||
249 | |||
240 | *state = result; | 250 | *state = result; |
241 | 251 | ||
242 | out: | 252 | out: |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index fc1803414629..40e38a06ba85 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -107,6 +107,7 @@ struct acpi_power_resource { | |||
107 | 107 | ||
108 | /* List of devices relying on this power resource */ | 108 | /* List of devices relying on this power resource */ |
109 | struct acpi_power_resource_device *devices; | 109 | struct acpi_power_resource_device *devices; |
110 | struct mutex devices_lock; | ||
110 | }; | 111 | }; |
111 | 112 | ||
112 | static struct list_head acpi_power_resource_list; | 113 | static struct list_head acpi_power_resource_list; |
@@ -225,7 +226,6 @@ static void acpi_power_on_device(struct acpi_power_managed_device *device) | |||
225 | 226 | ||
226 | static int __acpi_power_on(struct acpi_power_resource *resource) | 227 | static int __acpi_power_on(struct acpi_power_resource *resource) |
227 | { | 228 | { |
228 | struct acpi_power_resource_device *device_list = resource->devices; | ||
229 | acpi_status status = AE_OK; | 229 | acpi_status status = AE_OK; |
230 | 230 | ||
231 | status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); | 231 | status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); |
@@ -238,19 +238,15 @@ static int __acpi_power_on(struct acpi_power_resource *resource) | |||
238 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n", | 238 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n", |
239 | resource->name)); | 239 | resource->name)); |
240 | 240 | ||
241 | while (device_list) { | ||
242 | acpi_power_on_device(device_list->device); | ||
243 | |||
244 | device_list = device_list->next; | ||
245 | } | ||
246 | |||
247 | return 0; | 241 | return 0; |
248 | } | 242 | } |
249 | 243 | ||
250 | static int acpi_power_on(acpi_handle handle) | 244 | static int acpi_power_on(acpi_handle handle) |
251 | { | 245 | { |
252 | int result = 0; | 246 | int result = 0; |
247 | bool resume_device = false; | ||
253 | struct acpi_power_resource *resource = NULL; | 248 | struct acpi_power_resource *resource = NULL; |
249 | struct acpi_power_resource_device *device_list; | ||
254 | 250 | ||
255 | result = acpi_power_get_context(handle, &resource); | 251 | result = acpi_power_get_context(handle, &resource); |
256 | if (result) | 252 | if (result) |
@@ -266,10 +262,25 @@ static int acpi_power_on(acpi_handle handle) | |||
266 | result = __acpi_power_on(resource); | 262 | result = __acpi_power_on(resource); |
267 | if (result) | 263 | if (result) |
268 | resource->ref_count--; | 264 | resource->ref_count--; |
265 | else | ||
266 | resume_device = true; | ||
269 | } | 267 | } |
270 | 268 | ||
271 | mutex_unlock(&resource->resource_lock); | 269 | mutex_unlock(&resource->resource_lock); |
272 | 270 | ||
271 | if (!resume_device) | ||
272 | return result; | ||
273 | |||
274 | mutex_lock(&resource->devices_lock); | ||
275 | |||
276 | device_list = resource->devices; | ||
277 | while (device_list) { | ||
278 | acpi_power_on_device(device_list->device); | ||
279 | device_list = device_list->next; | ||
280 | } | ||
281 | |||
282 | mutex_unlock(&resource->devices_lock); | ||
283 | |||
273 | return result; | 284 | return result; |
274 | } | 285 | } |
275 | 286 | ||
@@ -355,7 +366,7 @@ static void __acpi_power_resource_unregister_device(struct device *dev, | |||
355 | if (acpi_power_get_context(res_handle, &resource)) | 366 | if (acpi_power_get_context(res_handle, &resource)) |
356 | return; | 367 | return; |
357 | 368 | ||
358 | mutex_lock(&resource->resource_lock); | 369 | mutex_lock(&resource->devices_lock); |
359 | prev = NULL; | 370 | prev = NULL; |
360 | curr = resource->devices; | 371 | curr = resource->devices; |
361 | while (curr) { | 372 | while (curr) { |
@@ -372,7 +383,7 @@ static void __acpi_power_resource_unregister_device(struct device *dev, | |||
372 | prev = curr; | 383 | prev = curr; |
373 | curr = curr->next; | 384 | curr = curr->next; |
374 | } | 385 | } |
375 | mutex_unlock(&resource->resource_lock); | 386 | mutex_unlock(&resource->devices_lock); |
376 | } | 387 | } |
377 | 388 | ||
378 | /* Unlink dev from all power resources in _PR0 */ | 389 | /* Unlink dev from all power resources in _PR0 */ |
@@ -414,10 +425,10 @@ static int __acpi_power_resource_register_device( | |||
414 | 425 | ||
415 | power_resource_device->device = powered_device; | 426 | power_resource_device->device = powered_device; |
416 | 427 | ||
417 | mutex_lock(&resource->resource_lock); | 428 | mutex_lock(&resource->devices_lock); |
418 | power_resource_device->next = resource->devices; | 429 | power_resource_device->next = resource->devices; |
419 | resource->devices = power_resource_device; | 430 | resource->devices = power_resource_device; |
420 | mutex_unlock(&resource->resource_lock); | 431 | mutex_unlock(&resource->devices_lock); |
421 | 432 | ||
422 | return 0; | 433 | return 0; |
423 | } | 434 | } |
@@ -462,7 +473,7 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle) | |||
462 | return ret; | 473 | return ret; |
463 | 474 | ||
464 | no_power_resource: | 475 | no_power_resource: |
465 | printk(KERN_WARNING PREFIX "Invalid Power Resource to register!"); | 476 | printk(KERN_DEBUG PREFIX "Invalid Power Resource to register!"); |
466 | return -ENODEV; | 477 | return -ENODEV; |
467 | } | 478 | } |
468 | EXPORT_SYMBOL_GPL(acpi_power_resource_register_device); | 479 | EXPORT_SYMBOL_GPL(acpi_power_resource_register_device); |
@@ -721,6 +732,7 @@ static int acpi_power_add(struct acpi_device *device) | |||
721 | 732 | ||
722 | resource->device = device; | 733 | resource->device = device; |
723 | mutex_init(&resource->resource_lock); | 734 | mutex_init(&resource->resource_lock); |
735 | mutex_init(&resource->devices_lock); | ||
724 | strcpy(resource->name, device->pnp.bus_id); | 736 | strcpy(resource->name, device->pnp.bus_id); |
725 | strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); | 737 | strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); |
726 | strcpy(acpi_device_class(device), ACPI_POWER_CLASS); | 738 | strcpy(acpi_device_class(device), ACPI_POWER_CLASS); |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 50d5dea0ff59..7862d17976b7 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -268,6 +268,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
268 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ | 268 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
269 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 269 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
270 | PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr }, | 270 | PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr }, |
271 | /* JMicron 362B and 362C have an AHCI function with IDE class code */ | ||
272 | { PCI_VDEVICE(JMICRON, 0x2362), board_ahci_ign_iferr }, | ||
273 | { PCI_VDEVICE(JMICRON, 0x236f), board_ahci_ign_iferr }, | ||
271 | 274 | ||
272 | /* ATI */ | 275 | /* ATI */ |
273 | { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ | 276 | { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ |
@@ -393,6 +396,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
393 | .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ | 396 | .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ |
394 | { PCI_DEVICE(0x1b4b, 0x917a), | 397 | { PCI_DEVICE(0x1b4b, 0x917a), |
395 | .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ | 398 | .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ |
399 | { PCI_DEVICE(0x1b4b, 0x9192), | ||
400 | .driver_data = board_ahci_yes_fbs }, /* 88se9172 on some Gigabyte */ | ||
396 | { PCI_DEVICE(0x1b4b, 0x91a3), | 401 | { PCI_DEVICE(0x1b4b, 0x91a3), |
397 | .driver_data = board_ahci_yes_fbs }, | 402 | .driver_data = board_ahci_yes_fbs }, |
398 | 403 | ||
@@ -400,7 +405,10 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
400 | { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ | 405 | { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ |
401 | 406 | ||
402 | /* Asmedia */ | 407 | /* Asmedia */ |
403 | { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1061 */ | 408 | { PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci }, /* ASM1060 */ |
409 | { PCI_VDEVICE(ASMEDIA, 0x0602), board_ahci }, /* ASM1060 */ | ||
410 | { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci }, /* ASM1061 */ | ||
411 | { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ | ||
404 | 412 | ||
405 | /* Generic, PCI class code for AHCI */ | 413 | /* Generic, PCI class code for AHCI */ |
406 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 414 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c index 78efb0306a44..34d94c762a1e 100644 --- a/drivers/base/dma-contiguous.c +++ b/drivers/base/dma-contiguous.c | |||
@@ -250,7 +250,7 @@ int __init dma_declare_contiguous(struct device *dev, unsigned long size, | |||
250 | return -EINVAL; | 250 | return -EINVAL; |
251 | 251 | ||
252 | /* Sanitise input arguments */ | 252 | /* Sanitise input arguments */ |
253 | alignment = PAGE_SIZE << max(MAX_ORDER, pageblock_order); | 253 | alignment = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order); |
254 | base = ALIGN(base, alignment); | 254 | base = ALIGN(base, alignment); |
255 | size = ALIGN(size, alignment); | 255 | size = ALIGN(size, alignment); |
256 | limit &= ~(alignment - 1); | 256 | limit &= ~(alignment - 1); |
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 11f36e502136..fc2de5528dcc 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -86,6 +86,7 @@ static struct usb_device_id ath3k_table[] = { | |||
86 | 86 | ||
87 | /* Atheros AR5BBU22 with sflash firmware */ | 87 | /* Atheros AR5BBU22 with sflash firmware */ |
88 | { USB_DEVICE(0x0489, 0xE03C) }, | 88 | { USB_DEVICE(0x0489, 0xE03C) }, |
89 | { USB_DEVICE(0x0489, 0xE036) }, | ||
89 | 90 | ||
90 | { } /* Terminating entry */ | 91 | { } /* Terminating entry */ |
91 | }; | 92 | }; |
@@ -109,6 +110,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { | |||
109 | 110 | ||
110 | /* Atheros AR5BBU22 with sflash firmware */ | 111 | /* Atheros AR5BBU22 with sflash firmware */ |
111 | { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, | 112 | { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, |
113 | { USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 }, | ||
112 | 114 | ||
113 | { } /* Terminating entry */ | 115 | { } /* Terminating entry */ |
114 | }; | 116 | }; |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index cef3bac1a543..654e248763ef 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -52,6 +52,9 @@ static struct usb_device_id btusb_table[] = { | |||
52 | /* Generic Bluetooth USB device */ | 52 | /* Generic Bluetooth USB device */ |
53 | { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, | 53 | { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, |
54 | 54 | ||
55 | /* Apple-specific (Broadcom) devices */ | ||
56 | { USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) }, | ||
57 | |||
55 | /* Broadcom SoftSailing reporting vendor specific */ | 58 | /* Broadcom SoftSailing reporting vendor specific */ |
56 | { USB_DEVICE(0x0a5c, 0x21e1) }, | 59 | { USB_DEVICE(0x0a5c, 0x21e1) }, |
57 | 60 | ||
@@ -94,16 +97,14 @@ static struct usb_device_id btusb_table[] = { | |||
94 | 97 | ||
95 | /* Broadcom BCM20702A0 */ | 98 | /* Broadcom BCM20702A0 */ |
96 | { USB_DEVICE(0x0489, 0xe042) }, | 99 | { USB_DEVICE(0x0489, 0xe042) }, |
97 | { USB_DEVICE(0x0a5c, 0x21e3) }, | ||
98 | { USB_DEVICE(0x0a5c, 0x21e6) }, | ||
99 | { USB_DEVICE(0x0a5c, 0x21e8) }, | ||
100 | { USB_DEVICE(0x0a5c, 0x21f3) }, | ||
101 | { USB_DEVICE(0x0a5c, 0x21f4) }, | ||
102 | { USB_DEVICE(0x413c, 0x8197) }, | 100 | { USB_DEVICE(0x413c, 0x8197) }, |
103 | 101 | ||
104 | /* Foxconn - Hon Hai */ | 102 | /* Foxconn - Hon Hai */ |
105 | { USB_DEVICE(0x0489, 0xe033) }, | 103 | { USB_DEVICE(0x0489, 0xe033) }, |
106 | 104 | ||
105 | /*Broadcom devices with vendor specific id */ | ||
106 | { USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) }, | ||
107 | |||
107 | { } /* Terminating entry */ | 108 | { } /* Terminating entry */ |
108 | }; | 109 | }; |
109 | 110 | ||
@@ -141,6 +142,7 @@ static struct usb_device_id blacklist_table[] = { | |||
141 | 142 | ||
142 | /* Atheros AR5BBU12 with sflash firmware */ | 143 | /* Atheros AR5BBU12 with sflash firmware */ |
143 | { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, | 144 | { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, |
145 | { USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 }, | ||
144 | 146 | ||
145 | /* Broadcom BCM2035 */ | 147 | /* Broadcom BCM2035 */ |
146 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, | 148 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, |
diff --git a/drivers/crypto/caam/key_gen.c b/drivers/crypto/caam/key_gen.c index 002888185f17..d216cd3cc569 100644 --- a/drivers/crypto/caam/key_gen.c +++ b/drivers/crypto/caam/key_gen.c | |||
@@ -120,3 +120,4 @@ u32 gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len, | |||
120 | 120 | ||
121 | return ret; | 121 | return ret; |
122 | } | 122 | } |
123 | EXPORT_SYMBOL(gen_split_key); | ||
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 3934fcc4e00b..7e5f6b65c651 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c | |||
@@ -841,12 +841,13 @@ atc_dma_cyclic_fill_desc(struct dma_chan *chan, struct at_desc *desc, | |||
841 | * @buf_len: total number of bytes for the entire buffer | 841 | * @buf_len: total number of bytes for the entire buffer |
842 | * @period_len: number of bytes for each period | 842 | * @period_len: number of bytes for each period |
843 | * @direction: transfer direction, to or from device | 843 | * @direction: transfer direction, to or from device |
844 | * @flags: tx descriptor status flags | ||
844 | * @context: transfer context (ignored) | 845 | * @context: transfer context (ignored) |
845 | */ | 846 | */ |
846 | static struct dma_async_tx_descriptor * | 847 | static struct dma_async_tx_descriptor * |
847 | atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, | 848 | atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, |
848 | size_t period_len, enum dma_transfer_direction direction, | 849 | size_t period_len, enum dma_transfer_direction direction, |
849 | void *context) | 850 | unsigned long flags, void *context) |
850 | { | 851 | { |
851 | struct at_dma_chan *atchan = to_at_dma_chan(chan); | 852 | struct at_dma_chan *atchan = to_at_dma_chan(chan); |
852 | struct at_dma_slave *atslave = chan->private; | 853 | struct at_dma_slave *atslave = chan->private; |
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c index c64917ec313d..493735b9b2c9 100644 --- a/drivers/dma/ep93xx_dma.c +++ b/drivers/dma/ep93xx_dma.c | |||
@@ -1120,6 +1120,7 @@ fail: | |||
1120 | * @buf_len: length of the buffer (in bytes) | 1120 | * @buf_len: length of the buffer (in bytes) |
1121 | * @period_len: lenght of a single period | 1121 | * @period_len: lenght of a single period |
1122 | * @dir: direction of the operation | 1122 | * @dir: direction of the operation |
1123 | * @flags: tx descriptor status flags | ||
1123 | * @context: operation context (ignored) | 1124 | * @context: operation context (ignored) |
1124 | * | 1125 | * |
1125 | * Prepares a descriptor for cyclic DMA operation. This means that once the | 1126 | * Prepares a descriptor for cyclic DMA operation. This means that once the |
@@ -1133,7 +1134,8 @@ fail: | |||
1133 | static struct dma_async_tx_descriptor * | 1134 | static struct dma_async_tx_descriptor * |
1134 | ep93xx_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t dma_addr, | 1135 | ep93xx_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t dma_addr, |
1135 | size_t buf_len, size_t period_len, | 1136 | size_t buf_len, size_t period_len, |
1136 | enum dma_transfer_direction dir, void *context) | 1137 | enum dma_transfer_direction dir, unsigned long flags, |
1138 | void *context) | ||
1137 | { | 1139 | { |
1138 | struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan); | 1140 | struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan); |
1139 | struct ep93xx_dma_desc *desc, *first; | 1141 | struct ep93xx_dma_desc *desc, *first; |
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index 5084975d793c..41b4376eb614 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c | |||
@@ -801,7 +801,7 @@ static struct dma_async_tx_descriptor *imxdma_prep_slave_sg( | |||
801 | static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic( | 801 | static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic( |
802 | struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len, | 802 | struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len, |
803 | size_t period_len, enum dma_transfer_direction direction, | 803 | size_t period_len, enum dma_transfer_direction direction, |
804 | void *context) | 804 | unsigned long flags, void *context) |
805 | { | 805 | { |
806 | struct imxdma_channel *imxdmac = to_imxdma_chan(chan); | 806 | struct imxdma_channel *imxdmac = to_imxdma_chan(chan); |
807 | struct imxdma_engine *imxdma = imxdmac->imxdma; | 807 | struct imxdma_engine *imxdma = imxdmac->imxdma; |
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 1dc2a4ad0026..2c5fd3e9880c 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c | |||
@@ -1012,7 +1012,7 @@ err_out: | |||
1012 | static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( | 1012 | static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( |
1013 | struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len, | 1013 | struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len, |
1014 | size_t period_len, enum dma_transfer_direction direction, | 1014 | size_t period_len, enum dma_transfer_direction direction, |
1015 | void *context) | 1015 | unsigned long flags, void *context) |
1016 | { | 1016 | { |
1017 | struct sdma_channel *sdmac = to_sdma_chan(chan); | 1017 | struct sdma_channel *sdmac = to_sdma_chan(chan); |
1018 | struct sdma_engine *sdma = sdmac->sdma; | 1018 | struct sdma_engine *sdma = sdmac->sdma; |
diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c index 8a15cf2163dc..6d52bd43a527 100644 --- a/drivers/dma/mmp_tdma.c +++ b/drivers/dma/mmp_tdma.c | |||
@@ -358,7 +358,7 @@ struct mmp_tdma_desc *mmp_tdma_alloc_descriptor(struct mmp_tdma_chan *tdmac) | |||
358 | static struct dma_async_tx_descriptor *mmp_tdma_prep_dma_cyclic( | 358 | static struct dma_async_tx_descriptor *mmp_tdma_prep_dma_cyclic( |
359 | struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len, | 359 | struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len, |
360 | size_t period_len, enum dma_transfer_direction direction, | 360 | size_t period_len, enum dma_transfer_direction direction, |
361 | void *context) | 361 | unsigned long flags, void *context) |
362 | { | 362 | { |
363 | struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); | 363 | struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); |
364 | struct mmp_tdma_desc *desc; | 364 | struct mmp_tdma_desc *desc; |
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c index 7f41b25805fa..734a4eb84d65 100644 --- a/drivers/dma/mxs-dma.c +++ b/drivers/dma/mxs-dma.c | |||
@@ -531,7 +531,7 @@ err_out: | |||
531 | static struct dma_async_tx_descriptor *mxs_dma_prep_dma_cyclic( | 531 | static struct dma_async_tx_descriptor *mxs_dma_prep_dma_cyclic( |
532 | struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len, | 532 | struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len, |
533 | size_t period_len, enum dma_transfer_direction direction, | 533 | size_t period_len, enum dma_transfer_direction direction, |
534 | void *context) | 534 | unsigned long flags, void *context) |
535 | { | 535 | { |
536 | struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan); | 536 | struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan); |
537 | struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma; | 537 | struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma; |
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index ae0561826137..f59f244f60fc 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c | |||
@@ -34,6 +34,7 @@ struct omap_chan { | |||
34 | struct dma_slave_config cfg; | 34 | struct dma_slave_config cfg; |
35 | unsigned dma_sig; | 35 | unsigned dma_sig; |
36 | bool cyclic; | 36 | bool cyclic; |
37 | bool paused; | ||
37 | 38 | ||
38 | int dma_ch; | 39 | int dma_ch; |
39 | struct omap_desc *desc; | 40 | struct omap_desc *desc; |
@@ -365,7 +366,8 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg( | |||
365 | 366 | ||
366 | static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic( | 367 | static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic( |
367 | struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, | 368 | struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, |
368 | size_t period_len, enum dma_transfer_direction dir, void *context) | 369 | size_t period_len, enum dma_transfer_direction dir, unsigned long flags, |
370 | void *context) | ||
369 | { | 371 | { |
370 | struct omap_chan *c = to_omap_dma_chan(chan); | 372 | struct omap_chan *c = to_omap_dma_chan(chan); |
371 | enum dma_slave_buswidth dev_width; | 373 | enum dma_slave_buswidth dev_width; |
@@ -413,7 +415,10 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic( | |||
413 | d->dev_addr = dev_addr; | 415 | d->dev_addr = dev_addr; |
414 | d->fi = burst; | 416 | d->fi = burst; |
415 | d->es = es; | 417 | d->es = es; |
416 | d->sync_mode = OMAP_DMA_SYNC_PACKET; | 418 | if (burst) |
419 | d->sync_mode = OMAP_DMA_SYNC_PACKET; | ||
420 | else | ||
421 | d->sync_mode = OMAP_DMA_SYNC_ELEMENT; | ||
417 | d->sync_type = sync_type; | 422 | d->sync_type = sync_type; |
418 | d->periph_port = OMAP_DMA_PORT_MPUI; | 423 | d->periph_port = OMAP_DMA_PORT_MPUI; |
419 | d->sg[0].addr = buf_addr; | 424 | d->sg[0].addr = buf_addr; |
@@ -424,7 +429,10 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic( | |||
424 | if (!c->cyclic) { | 429 | if (!c->cyclic) { |
425 | c->cyclic = true; | 430 | c->cyclic = true; |
426 | omap_dma_link_lch(c->dma_ch, c->dma_ch); | 431 | omap_dma_link_lch(c->dma_ch, c->dma_ch); |
427 | omap_enable_dma_irq(c->dma_ch, OMAP_DMA_FRAME_IRQ); | 432 | |
433 | if (flags & DMA_PREP_INTERRUPT) | ||
434 | omap_enable_dma_irq(c->dma_ch, OMAP_DMA_FRAME_IRQ); | ||
435 | |||
428 | omap_disable_dma_irq(c->dma_ch, OMAP_DMA_BLOCK_IRQ); | 436 | omap_disable_dma_irq(c->dma_ch, OMAP_DMA_BLOCK_IRQ); |
429 | } | 437 | } |
430 | 438 | ||
@@ -433,7 +441,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic( | |||
433 | omap_set_dma_dest_burst_mode(c->dma_ch, OMAP_DMA_DATA_BURST_16); | 441 | omap_set_dma_dest_burst_mode(c->dma_ch, OMAP_DMA_DATA_BURST_16); |
434 | } | 442 | } |
435 | 443 | ||
436 | return vchan_tx_prep(&c->vc, &d->vd, DMA_CTRL_ACK | DMA_PREP_INTERRUPT); | 444 | return vchan_tx_prep(&c->vc, &d->vd, flags); |
437 | } | 445 | } |
438 | 446 | ||
439 | static int omap_dma_slave_config(struct omap_chan *c, struct dma_slave_config *cfg) | 447 | static int omap_dma_slave_config(struct omap_chan *c, struct dma_slave_config *cfg) |
@@ -467,11 +475,14 @@ static int omap_dma_terminate_all(struct omap_chan *c) | |||
467 | */ | 475 | */ |
468 | if (c->desc) { | 476 | if (c->desc) { |
469 | c->desc = NULL; | 477 | c->desc = NULL; |
470 | omap_stop_dma(c->dma_ch); | 478 | /* Avoid stopping the dma twice */ |
479 | if (!c->paused) | ||
480 | omap_stop_dma(c->dma_ch); | ||
471 | } | 481 | } |
472 | 482 | ||
473 | if (c->cyclic) { | 483 | if (c->cyclic) { |
474 | c->cyclic = false; | 484 | c->cyclic = false; |
485 | c->paused = false; | ||
475 | omap_dma_unlink_lch(c->dma_ch, c->dma_ch); | 486 | omap_dma_unlink_lch(c->dma_ch, c->dma_ch); |
476 | } | 487 | } |
477 | 488 | ||
@@ -484,14 +495,30 @@ static int omap_dma_terminate_all(struct omap_chan *c) | |||
484 | 495 | ||
485 | static int omap_dma_pause(struct omap_chan *c) | 496 | static int omap_dma_pause(struct omap_chan *c) |
486 | { | 497 | { |
487 | /* FIXME: not supported by platform private API */ | 498 | /* Pause/Resume only allowed with cyclic mode */ |
488 | return -EINVAL; | 499 | if (!c->cyclic) |
500 | return -EINVAL; | ||
501 | |||
502 | if (!c->paused) { | ||
503 | omap_stop_dma(c->dma_ch); | ||
504 | c->paused = true; | ||
505 | } | ||
506 | |||
507 | return 0; | ||
489 | } | 508 | } |
490 | 509 | ||
491 | static int omap_dma_resume(struct omap_chan *c) | 510 | static int omap_dma_resume(struct omap_chan *c) |
492 | { | 511 | { |
493 | /* FIXME: not supported by platform private API */ | 512 | /* Pause/Resume only allowed with cyclic mode */ |
494 | return -EINVAL; | 513 | if (!c->cyclic) |
514 | return -EINVAL; | ||
515 | |||
516 | if (c->paused) { | ||
517 | omap_start_dma(c->dma_ch); | ||
518 | c->paused = false; | ||
519 | } | ||
520 | |||
521 | return 0; | ||
495 | } | 522 | } |
496 | 523 | ||
497 | static int omap_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | 524 | static int omap_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, |
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index e4feba6b03c0..00356458e399 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c | |||
@@ -2683,7 +2683,7 @@ static inline int get_burst_len(struct dma_pl330_desc *desc, size_t len) | |||
2683 | static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( | 2683 | static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( |
2684 | struct dma_chan *chan, dma_addr_t dma_addr, size_t len, | 2684 | struct dma_chan *chan, dma_addr_t dma_addr, size_t len, |
2685 | size_t period_len, enum dma_transfer_direction direction, | 2685 | size_t period_len, enum dma_transfer_direction direction, |
2686 | void *context) | 2686 | unsigned long flags, void *context) |
2687 | { | 2687 | { |
2688 | struct dma_pl330_desc *desc; | 2688 | struct dma_pl330_desc *desc; |
2689 | struct dma_pl330_chan *pch = to_pchan(chan); | 2689 | struct dma_pl330_chan *pch = to_pchan(chan); |
diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c index f5a73606217e..b893159c1ecb 100644 --- a/drivers/dma/sa11x0-dma.c +++ b/drivers/dma/sa11x0-dma.c | |||
@@ -614,7 +614,7 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg( | |||
614 | 614 | ||
615 | static struct dma_async_tx_descriptor *sa11x0_dma_prep_dma_cyclic( | 615 | static struct dma_async_tx_descriptor *sa11x0_dma_prep_dma_cyclic( |
616 | struct dma_chan *chan, dma_addr_t addr, size_t size, size_t period, | 616 | struct dma_chan *chan, dma_addr_t addr, size_t size, size_t period, |
617 | enum dma_transfer_direction dir, void *context) | 617 | enum dma_transfer_direction dir, unsigned long flags, void *context) |
618 | { | 618 | { |
619 | struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); | 619 | struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); |
620 | struct sa11x0_dma_desc *txd; | 620 | struct sa11x0_dma_desc *txd; |
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c index 434ad31174f2..3eed8b35b0f1 100644 --- a/drivers/dma/sirf-dma.c +++ b/drivers/dma/sirf-dma.c | |||
@@ -489,7 +489,7 @@ err_dir: | |||
489 | static struct dma_async_tx_descriptor * | 489 | static struct dma_async_tx_descriptor * |
490 | sirfsoc_dma_prep_cyclic(struct dma_chan *chan, dma_addr_t addr, | 490 | sirfsoc_dma_prep_cyclic(struct dma_chan *chan, dma_addr_t addr, |
491 | size_t buf_len, size_t period_len, | 491 | size_t buf_len, size_t period_len, |
492 | enum dma_transfer_direction direction, void *context) | 492 | enum dma_transfer_direction direction, unsigned long flags, void *context) |
493 | { | 493 | { |
494 | struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan); | 494 | struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan); |
495 | struct sirfsoc_dma_desc *sdesc = NULL; | 495 | struct sirfsoc_dma_desc *sdesc = NULL; |
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 000d309602b2..eee8d9b9a20b 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c | |||
@@ -2347,7 +2347,8 @@ static struct dma_async_tx_descriptor *d40_prep_slave_sg(struct dma_chan *chan, | |||
2347 | static struct dma_async_tx_descriptor * | 2347 | static struct dma_async_tx_descriptor * |
2348 | dma40_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t dma_addr, | 2348 | dma40_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t dma_addr, |
2349 | size_t buf_len, size_t period_len, | 2349 | size_t buf_len, size_t period_len, |
2350 | enum dma_transfer_direction direction, void *context) | 2350 | enum dma_transfer_direction direction, unsigned long flags, |
2351 | void *context) | ||
2351 | { | 2352 | { |
2352 | unsigned int periods = buf_len / period_len; | 2353 | unsigned int periods = buf_len / period_len; |
2353 | struct dma_async_tx_descriptor *txd; | 2354 | struct dma_async_tx_descriptor *txd; |
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 24acd711e032..b42b6ffb75ad 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c | |||
@@ -990,7 +990,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg( | |||
990 | struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic( | 990 | struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic( |
991 | struct dma_chan *dc, dma_addr_t buf_addr, size_t buf_len, | 991 | struct dma_chan *dc, dma_addr_t buf_addr, size_t buf_len, |
992 | size_t period_len, enum dma_transfer_direction direction, | 992 | size_t period_len, enum dma_transfer_direction direction, |
993 | void *context) | 993 | unsigned long flags, void *context) |
994 | { | 994 | { |
995 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); | 995 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); |
996 | struct tegra_dma_desc *dma_desc = NULL; | 996 | struct tegra_dma_desc *dma_desc = NULL; |
diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index 920a609b2c35..38f9e52f358b 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c | |||
@@ -669,13 +669,18 @@ static int __devinit max77693_muic_probe(struct platform_device *pdev) | |||
669 | } | 669 | } |
670 | info->dev = &pdev->dev; | 670 | info->dev = &pdev->dev; |
671 | info->max77693 = max77693; | 671 | info->max77693 = max77693; |
672 | info->max77693->regmap_muic = regmap_init_i2c(info->max77693->muic, | 672 | if (info->max77693->regmap_muic) |
673 | &max77693_muic_regmap_config); | 673 | dev_dbg(&pdev->dev, "allocate register map\n"); |
674 | if (IS_ERR(info->max77693->regmap_muic)) { | 674 | else { |
675 | ret = PTR_ERR(info->max77693->regmap_muic); | 675 | info->max77693->regmap_muic = devm_regmap_init_i2c( |
676 | dev_err(max77693->dev, | 676 | info->max77693->muic, |
677 | "failed to allocate register map: %d\n", ret); | 677 | &max77693_muic_regmap_config); |
678 | goto err_regmap; | 678 | if (IS_ERR(info->max77693->regmap_muic)) { |
679 | ret = PTR_ERR(info->max77693->regmap_muic); | ||
680 | dev_err(max77693->dev, | ||
681 | "failed to allocate register map: %d\n", ret); | ||
682 | goto err_regmap; | ||
683 | } | ||
679 | } | 684 | } |
680 | platform_set_drvdata(pdev, info); | 685 | platform_set_drvdata(pdev, info); |
681 | mutex_init(&info->mutex); | 686 | mutex_init(&info->mutex); |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index b16c8a72a2e2..ba7926f5c099 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -294,7 +294,7 @@ config GPIO_MAX732X_IRQ | |||
294 | 294 | ||
295 | config GPIO_MC9S08DZ60 | 295 | config GPIO_MC9S08DZ60 |
296 | bool "MX35 3DS BOARD MC9S08DZ60 GPIO functions" | 296 | bool "MX35 3DS BOARD MC9S08DZ60 GPIO functions" |
297 | depends on I2C && MACH_MX35_3DS | 297 | depends on I2C=y && MACH_MX35_3DS |
298 | help | 298 | help |
299 | Select this to enable the MC9S08DZ60 GPIO driver | 299 | Select this to enable the MC9S08DZ60 GPIO driver |
300 | 300 | ||
diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index ae37181798b3..ec48ed512628 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c | |||
@@ -247,9 +247,9 @@ static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p) | |||
247 | 247 | ||
248 | p->irq_base = irq_alloc_descs(pdata->irq_base, 0, | 248 | p->irq_base = irq_alloc_descs(pdata->irq_base, 0, |
249 | pdata->number_of_pins, numa_node_id()); | 249 | pdata->number_of_pins, numa_node_id()); |
250 | if (IS_ERR_VALUE(p->irq_base)) { | 250 | if (p->irq_base < 0) { |
251 | dev_err(&pdev->dev, "cannot get irq_desc\n"); | 251 | dev_err(&pdev->dev, "cannot get irq_desc\n"); |
252 | return -ENXIO; | 252 | return p->irq_base; |
253 | } | 253 | } |
254 | pr_debug("gio: hw base = %d, nr = %d, sw base = %d\n", | 254 | pr_debug("gio: hw base = %d, nr = %d, sw base = %d\n", |
255 | pdata->gpio_base, pdata->number_of_pins, p->irq_base); | 255 | pdata->gpio_base, pdata->number_of_pins, p->irq_base); |
diff --git a/drivers/gpio/gpio-rdc321x.c b/drivers/gpio/gpio-rdc321x.c index e97016af6443..b62d443e9a59 100644 --- a/drivers/gpio/gpio-rdc321x.c +++ b/drivers/gpio/gpio-rdc321x.c | |||
@@ -170,6 +170,7 @@ static int __devinit rdc321x_gpio_probe(struct platform_device *pdev) | |||
170 | rdc321x_gpio_dev->reg2_data_base = r->start + 0x4; | 170 | rdc321x_gpio_dev->reg2_data_base = r->start + 0x4; |
171 | 171 | ||
172 | rdc321x_gpio_dev->chip.label = "rdc321x-gpio"; | 172 | rdc321x_gpio_dev->chip.label = "rdc321x-gpio"; |
173 | rdc321x_gpio_dev->chip.owner = THIS_MODULE; | ||
173 | rdc321x_gpio_dev->chip.direction_input = rdc_gpio_direction_input; | 174 | rdc321x_gpio_dev->chip.direction_input = rdc_gpio_direction_input; |
174 | rdc321x_gpio_dev->chip.direction_output = rdc_gpio_config; | 175 | rdc321x_gpio_dev->chip.direction_output = rdc_gpio_config; |
175 | rdc321x_gpio_dev->chip.get = rdc_gpio_get_value; | 176 | rdc321x_gpio_dev->chip.get = rdc_gpio_get_value; |
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index a18c4aa68b1e..f1a45997aea8 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c | |||
@@ -82,7 +82,7 @@ int of_get_named_gpio_flags(struct device_node *np, const char *propname, | |||
82 | gpiochip_find(&gg_data, of_gpiochip_find_and_xlate); | 82 | gpiochip_find(&gg_data, of_gpiochip_find_and_xlate); |
83 | 83 | ||
84 | of_node_put(gg_data.gpiospec.np); | 84 | of_node_put(gg_data.gpiospec.np); |
85 | pr_debug("%s exited with status %d\n", __func__, ret); | 85 | pr_debug("%s exited with status %d\n", __func__, gg_data.out_gpio); |
86 | return gg_data.out_gpio; | 86 | return gg_data.out_gpio; |
87 | } | 87 | } |
88 | EXPORT_SYMBOL(of_get_named_gpio_flags); | 88 | EXPORT_SYMBOL(of_get_named_gpio_flags); |
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index d0c4574ef49c..36164806b9d4 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c | |||
@@ -193,6 +193,9 @@ static const struct file_operations ast_fops = { | |||
193 | .mmap = ast_mmap, | 193 | .mmap = ast_mmap, |
194 | .poll = drm_poll, | 194 | .poll = drm_poll, |
195 | .fasync = drm_fasync, | 195 | .fasync = drm_fasync, |
196 | #ifdef CONFIG_COMPAT | ||
197 | .compat_ioctl = drm_compat_ioctl, | ||
198 | #endif | ||
196 | .read = drm_read, | 199 | .read = drm_read, |
197 | }; | 200 | }; |
198 | 201 | ||
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 7282c081fb53..a712cafcfa1d 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c | |||
@@ -841,7 +841,7 @@ int ast_cursor_init(struct drm_device *dev) | |||
841 | 841 | ||
842 | ast->cursor_cache = obj; | 842 | ast->cursor_cache = obj; |
843 | ast->cursor_cache_gpu_addr = gpu_addr; | 843 | ast->cursor_cache_gpu_addr = gpu_addr; |
844 | DRM_ERROR("pinned cursor cache at %llx\n", ast->cursor_cache_gpu_addr); | 844 | DRM_DEBUG_KMS("pinned cursor cache at %llx\n", ast->cursor_cache_gpu_addr); |
845 | return 0; | 845 | return 0; |
846 | fail: | 846 | fail: |
847 | return ret; | 847 | return ret; |
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c index 7053140c6596..b83a2d7ddd1a 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.c +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c | |||
@@ -74,6 +74,9 @@ static const struct file_operations cirrus_driver_fops = { | |||
74 | .unlocked_ioctl = drm_ioctl, | 74 | .unlocked_ioctl = drm_ioctl, |
75 | .mmap = cirrus_mmap, | 75 | .mmap = cirrus_mmap, |
76 | .poll = drm_poll, | 76 | .poll = drm_poll, |
77 | #ifdef CONFIG_COMPAT | ||
78 | .compat_ioctl = drm_compat_ioctl, | ||
79 | #endif | ||
77 | .fasync = drm_fasync, | 80 | .fasync = drm_fasync, |
78 | }; | 81 | }; |
79 | static struct drm_driver driver = { | 82 | static struct drm_driver driver = { |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 08a7aa722d6b..6fbfc244748f 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -1981,7 +1981,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev, | |||
1981 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 1981 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
1982 | return -EINVAL; | 1982 | return -EINVAL; |
1983 | 1983 | ||
1984 | if (!req->flags) | 1984 | if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags)) |
1985 | return -EINVAL; | 1985 | return -EINVAL; |
1986 | 1986 | ||
1987 | mutex_lock(&dev->mode_config.mutex); | 1987 | mutex_lock(&dev->mode_config.mutex); |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index a8743c399e83..b7ee230572b7 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -87,6 +87,9 @@ static struct edid_quirk { | |||
87 | int product_id; | 87 | int product_id; |
88 | u32 quirks; | 88 | u32 quirks; |
89 | } edid_quirk_list[] = { | 89 | } edid_quirk_list[] = { |
90 | /* ASUS VW222S */ | ||
91 | { "ACI", 0x22a2, EDID_QUIRK_FORCE_REDUCED_BLANKING }, | ||
92 | |||
90 | /* Acer AL1706 */ | 93 | /* Acer AL1706 */ |
91 | { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 }, | 94 | { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 }, |
92 | /* Acer F51 */ | 95 | /* Acer F51 */ |
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index 7f5096763b7d..59a26e577b57 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig | |||
@@ -36,6 +36,6 @@ config DRM_EXYNOS_VIDI | |||
36 | 36 | ||
37 | config DRM_EXYNOS_G2D | 37 | config DRM_EXYNOS_G2D |
38 | bool "Exynos DRM G2D" | 38 | bool "Exynos DRM G2D" |
39 | depends on DRM_EXYNOS | 39 | depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_G2D |
40 | help | 40 | help |
41 | Choose this option if you want to use Exynos G2D for DRM. | 41 | Choose this option if you want to use Exynos G2D for DRM. |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index 613bf8a5d9b2..ae13febe0eaa 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | |||
@@ -163,6 +163,12 @@ static void exynos_gem_dmabuf_kunmap(struct dma_buf *dma_buf, | |||
163 | /* TODO */ | 163 | /* TODO */ |
164 | } | 164 | } |
165 | 165 | ||
166 | static int exynos_gem_dmabuf_mmap(struct dma_buf *dma_buf, | ||
167 | struct vm_area_struct *vma) | ||
168 | { | ||
169 | return -ENOTTY; | ||
170 | } | ||
171 | |||
166 | static struct dma_buf_ops exynos_dmabuf_ops = { | 172 | static struct dma_buf_ops exynos_dmabuf_ops = { |
167 | .map_dma_buf = exynos_gem_map_dma_buf, | 173 | .map_dma_buf = exynos_gem_map_dma_buf, |
168 | .unmap_dma_buf = exynos_gem_unmap_dma_buf, | 174 | .unmap_dma_buf = exynos_gem_unmap_dma_buf, |
@@ -170,6 +176,7 @@ static struct dma_buf_ops exynos_dmabuf_ops = { | |||
170 | .kmap_atomic = exynos_gem_dmabuf_kmap_atomic, | 176 | .kmap_atomic = exynos_gem_dmabuf_kmap_atomic, |
171 | .kunmap = exynos_gem_dmabuf_kunmap, | 177 | .kunmap = exynos_gem_dmabuf_kunmap, |
172 | .kunmap_atomic = exynos_gem_dmabuf_kunmap_atomic, | 178 | .kunmap_atomic = exynos_gem_dmabuf_kunmap_atomic, |
179 | .mmap = exynos_gem_dmabuf_mmap, | ||
173 | .release = exynos_dmabuf_release, | 180 | .release = exynos_dmabuf_release, |
174 | }; | 181 | }; |
175 | 182 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index ebacec6f1e48..d07071937453 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
@@ -160,7 +160,6 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) | |||
160 | if (!file_priv) | 160 | if (!file_priv) |
161 | return -ENOMEM; | 161 | return -ENOMEM; |
162 | 162 | ||
163 | drm_prime_init_file_private(&file->prime); | ||
164 | file->driver_priv = file_priv; | 163 | file->driver_priv = file_priv; |
165 | 164 | ||
166 | return exynos_drm_subdrv_open(dev, file); | 165 | return exynos_drm_subdrv_open(dev, file); |
@@ -184,7 +183,6 @@ static void exynos_drm_preclose(struct drm_device *dev, | |||
184 | e->base.destroy(&e->base); | 183 | e->base.destroy(&e->base); |
185 | } | 184 | } |
186 | } | 185 | } |
187 | drm_prime_destroy_file_private(&file->prime); | ||
188 | spin_unlock_irqrestore(&dev->event_lock, flags); | 186 | spin_unlock_irqrestore(&dev->event_lock, flags); |
189 | 187 | ||
190 | exynos_drm_subdrv_close(dev, file); | 188 | exynos_drm_subdrv_close(dev, file); |
@@ -241,6 +239,9 @@ static const struct file_operations exynos_drm_driver_fops = { | |||
241 | .poll = drm_poll, | 239 | .poll = drm_poll, |
242 | .read = drm_read, | 240 | .read = drm_read, |
243 | .unlocked_ioctl = drm_ioctl, | 241 | .unlocked_ioctl = drm_ioctl, |
242 | #ifdef CONFIG_COMPAT | ||
243 | .compat_ioctl = drm_compat_ioctl, | ||
244 | #endif | ||
244 | .release = drm_release, | 245 | .release = drm_release, |
245 | }; | 246 | }; |
246 | 247 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index a68d2b313f03..b19cd93e7047 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
@@ -831,11 +831,6 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
831 | } | 831 | } |
832 | 832 | ||
833 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 833 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
834 | if (!res) { | ||
835 | dev_err(dev, "failed to find registers\n"); | ||
836 | ret = -ENOENT; | ||
837 | goto err_clk; | ||
838 | } | ||
839 | 834 | ||
840 | ctx->regs = devm_request_and_ioremap(&pdev->dev, res); | 835 | ctx->regs = devm_request_and_ioremap(&pdev->dev, res); |
841 | if (!ctx->regs) { | 836 | if (!ctx->regs) { |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index d2d88f22a037..1065e90d0919 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c | |||
@@ -129,7 +129,6 @@ struct g2d_runqueue_node { | |||
129 | struct g2d_data { | 129 | struct g2d_data { |
130 | struct device *dev; | 130 | struct device *dev; |
131 | struct clk *gate_clk; | 131 | struct clk *gate_clk; |
132 | struct resource *regs_res; | ||
133 | void __iomem *regs; | 132 | void __iomem *regs; |
134 | int irq; | 133 | int irq; |
135 | struct workqueue_struct *g2d_workq; | 134 | struct workqueue_struct *g2d_workq; |
@@ -751,7 +750,7 @@ static int __devinit g2d_probe(struct platform_device *pdev) | |||
751 | struct exynos_drm_subdrv *subdrv; | 750 | struct exynos_drm_subdrv *subdrv; |
752 | int ret; | 751 | int ret; |
753 | 752 | ||
754 | g2d = kzalloc(sizeof(*g2d), GFP_KERNEL); | 753 | g2d = devm_kzalloc(&pdev->dev, sizeof(*g2d), GFP_KERNEL); |
755 | if (!g2d) { | 754 | if (!g2d) { |
756 | dev_err(dev, "failed to allocate driver data\n"); | 755 | dev_err(dev, "failed to allocate driver data\n"); |
757 | return -ENOMEM; | 756 | return -ENOMEM; |
@@ -759,10 +758,8 @@ static int __devinit g2d_probe(struct platform_device *pdev) | |||
759 | 758 | ||
760 | g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab", | 759 | g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab", |
761 | sizeof(struct g2d_runqueue_node), 0, 0, NULL); | 760 | sizeof(struct g2d_runqueue_node), 0, 0, NULL); |
762 | if (!g2d->runqueue_slab) { | 761 | if (!g2d->runqueue_slab) |
763 | ret = -ENOMEM; | 762 | return -ENOMEM; |
764 | goto err_free_mem; | ||
765 | } | ||
766 | 763 | ||
767 | g2d->dev = dev; | 764 | g2d->dev = dev; |
768 | 765 | ||
@@ -794,38 +791,26 @@ static int __devinit g2d_probe(struct platform_device *pdev) | |||
794 | pm_runtime_enable(dev); | 791 | pm_runtime_enable(dev); |
795 | 792 | ||
796 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 793 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
797 | if (!res) { | ||
798 | dev_err(dev, "failed to get I/O memory\n"); | ||
799 | ret = -ENOENT; | ||
800 | goto err_put_clk; | ||
801 | } | ||
802 | 794 | ||
803 | g2d->regs_res = request_mem_region(res->start, resource_size(res), | 795 | g2d->regs = devm_request_and_ioremap(&pdev->dev, res); |
804 | dev_name(dev)); | ||
805 | if (!g2d->regs_res) { | ||
806 | dev_err(dev, "failed to request I/O memory\n"); | ||
807 | ret = -ENOENT; | ||
808 | goto err_put_clk; | ||
809 | } | ||
810 | |||
811 | g2d->regs = ioremap(res->start, resource_size(res)); | ||
812 | if (!g2d->regs) { | 796 | if (!g2d->regs) { |
813 | dev_err(dev, "failed to remap I/O memory\n"); | 797 | dev_err(dev, "failed to remap I/O memory\n"); |
814 | ret = -ENXIO; | 798 | ret = -ENXIO; |
815 | goto err_release_res; | 799 | goto err_put_clk; |
816 | } | 800 | } |
817 | 801 | ||
818 | g2d->irq = platform_get_irq(pdev, 0); | 802 | g2d->irq = platform_get_irq(pdev, 0); |
819 | if (g2d->irq < 0) { | 803 | if (g2d->irq < 0) { |
820 | dev_err(dev, "failed to get irq\n"); | 804 | dev_err(dev, "failed to get irq\n"); |
821 | ret = g2d->irq; | 805 | ret = g2d->irq; |
822 | goto err_unmap_base; | 806 | goto err_put_clk; |
823 | } | 807 | } |
824 | 808 | ||
825 | ret = request_irq(g2d->irq, g2d_irq_handler, 0, "drm_g2d", g2d); | 809 | ret = devm_request_irq(&pdev->dev, g2d->irq, g2d_irq_handler, 0, |
810 | "drm_g2d", g2d); | ||
826 | if (ret < 0) { | 811 | if (ret < 0) { |
827 | dev_err(dev, "irq request failed\n"); | 812 | dev_err(dev, "irq request failed\n"); |
828 | goto err_unmap_base; | 813 | goto err_put_clk; |
829 | } | 814 | } |
830 | 815 | ||
831 | platform_set_drvdata(pdev, g2d); | 816 | platform_set_drvdata(pdev, g2d); |
@@ -838,7 +823,7 @@ static int __devinit g2d_probe(struct platform_device *pdev) | |||
838 | ret = exynos_drm_subdrv_register(subdrv); | 823 | ret = exynos_drm_subdrv_register(subdrv); |
839 | if (ret < 0) { | 824 | if (ret < 0) { |
840 | dev_err(dev, "failed to register drm g2d device\n"); | 825 | dev_err(dev, "failed to register drm g2d device\n"); |
841 | goto err_free_irq; | 826 | goto err_put_clk; |
842 | } | 827 | } |
843 | 828 | ||
844 | dev_info(dev, "The exynos g2d(ver %d.%d) successfully probed\n", | 829 | dev_info(dev, "The exynos g2d(ver %d.%d) successfully probed\n", |
@@ -846,13 +831,6 @@ static int __devinit g2d_probe(struct platform_device *pdev) | |||
846 | 831 | ||
847 | return 0; | 832 | return 0; |
848 | 833 | ||
849 | err_free_irq: | ||
850 | free_irq(g2d->irq, g2d); | ||
851 | err_unmap_base: | ||
852 | iounmap(g2d->regs); | ||
853 | err_release_res: | ||
854 | release_resource(g2d->regs_res); | ||
855 | kfree(g2d->regs_res); | ||
856 | err_put_clk: | 834 | err_put_clk: |
857 | pm_runtime_disable(dev); | 835 | pm_runtime_disable(dev); |
858 | clk_put(g2d->gate_clk); | 836 | clk_put(g2d->gate_clk); |
@@ -862,8 +840,6 @@ err_destroy_workqueue: | |||
862 | destroy_workqueue(g2d->g2d_workq); | 840 | destroy_workqueue(g2d->g2d_workq); |
863 | err_destroy_slab: | 841 | err_destroy_slab: |
864 | kmem_cache_destroy(g2d->runqueue_slab); | 842 | kmem_cache_destroy(g2d->runqueue_slab); |
865 | err_free_mem: | ||
866 | kfree(g2d); | ||
867 | return ret; | 843 | return ret; |
868 | } | 844 | } |
869 | 845 | ||
@@ -873,24 +849,18 @@ static int __devexit g2d_remove(struct platform_device *pdev) | |||
873 | 849 | ||
874 | cancel_work_sync(&g2d->runqueue_work); | 850 | cancel_work_sync(&g2d->runqueue_work); |
875 | exynos_drm_subdrv_unregister(&g2d->subdrv); | 851 | exynos_drm_subdrv_unregister(&g2d->subdrv); |
876 | free_irq(g2d->irq, g2d); | ||
877 | 852 | ||
878 | while (g2d->runqueue_node) { | 853 | while (g2d->runqueue_node) { |
879 | g2d_free_runqueue_node(g2d, g2d->runqueue_node); | 854 | g2d_free_runqueue_node(g2d, g2d->runqueue_node); |
880 | g2d->runqueue_node = g2d_get_runqueue_node(g2d); | 855 | g2d->runqueue_node = g2d_get_runqueue_node(g2d); |
881 | } | 856 | } |
882 | 857 | ||
883 | iounmap(g2d->regs); | ||
884 | release_resource(g2d->regs_res); | ||
885 | kfree(g2d->regs_res); | ||
886 | |||
887 | pm_runtime_disable(&pdev->dev); | 858 | pm_runtime_disable(&pdev->dev); |
888 | clk_put(g2d->gate_clk); | 859 | clk_put(g2d->gate_clk); |
889 | 860 | ||
890 | g2d_fini_cmdlist(g2d); | 861 | g2d_fini_cmdlist(g2d); |
891 | destroy_workqueue(g2d->g2d_workq); | 862 | destroy_workqueue(g2d->g2d_workq); |
892 | kmem_cache_destroy(g2d->runqueue_slab); | 863 | kmem_cache_destroy(g2d->runqueue_slab); |
893 | kfree(g2d); | ||
894 | 864 | ||
895 | return 0; | 865 | return 0; |
896 | } | 866 | } |
@@ -924,7 +894,7 @@ static int g2d_resume(struct device *dev) | |||
924 | } | 894 | } |
925 | #endif | 895 | #endif |
926 | 896 | ||
927 | SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume); | 897 | static SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume); |
928 | 898 | ||
929 | struct platform_driver g2d_driver = { | 899 | struct platform_driver g2d_driver = { |
930 | .probe = g2d_probe, | 900 | .probe = g2d_probe, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index f9efde40c097..a38051c95ec4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c | |||
@@ -122,7 +122,7 @@ fail: | |||
122 | __free_page(pages[i]); | 122 | __free_page(pages[i]); |
123 | 123 | ||
124 | drm_free_large(pages); | 124 | drm_free_large(pages); |
125 | return ERR_PTR(PTR_ERR(p)); | 125 | return ERR_CAST(p); |
126 | } | 126 | } |
127 | 127 | ||
128 | static void exynos_gem_put_pages(struct drm_gem_object *obj, | 128 | static void exynos_gem_put_pages(struct drm_gem_object *obj, |
@@ -662,7 +662,7 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv, | |||
662 | */ | 662 | */ |
663 | 663 | ||
664 | args->pitch = args->width * ((args->bpp + 7) / 8); | 664 | args->pitch = args->width * ((args->bpp + 7) / 8); |
665 | args->size = PAGE_ALIGN(args->pitch * args->height); | 665 | args->size = args->pitch * args->height; |
666 | 666 | ||
667 | exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size); | 667 | exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size); |
668 | if (IS_ERR(exynos_gem_obj)) | 668 | if (IS_ERR(exynos_gem_obj)) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 8ffcdf8b9e22..3fdf0b65f47e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c | |||
@@ -345,7 +345,7 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev) | |||
345 | 345 | ||
346 | DRM_DEBUG_KMS("%s\n", __FILE__); | 346 | DRM_DEBUG_KMS("%s\n", __FILE__); |
347 | 347 | ||
348 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | 348 | ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); |
349 | if (!ctx) { | 349 | if (!ctx) { |
350 | DRM_LOG_KMS("failed to alloc common hdmi context.\n"); | 350 | DRM_LOG_KMS("failed to alloc common hdmi context.\n"); |
351 | return -ENOMEM; | 351 | return -ENOMEM; |
@@ -371,7 +371,6 @@ static int __devexit exynos_drm_hdmi_remove(struct platform_device *pdev) | |||
371 | DRM_DEBUG_KMS("%s\n", __FILE__); | 371 | DRM_DEBUG_KMS("%s\n", __FILE__); |
372 | 372 | ||
373 | exynos_drm_subdrv_unregister(&ctx->subdrv); | 373 | exynos_drm_subdrv_unregister(&ctx->subdrv); |
374 | kfree(ctx); | ||
375 | 374 | ||
376 | return 0; | 375 | return 0; |
377 | } | 376 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index b89829e5043a..e1f94b746bd7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c | |||
@@ -29,7 +29,6 @@ static const uint32_t formats[] = { | |||
29 | DRM_FORMAT_XRGB8888, | 29 | DRM_FORMAT_XRGB8888, |
30 | DRM_FORMAT_ARGB8888, | 30 | DRM_FORMAT_ARGB8888, |
31 | DRM_FORMAT_NV12, | 31 | DRM_FORMAT_NV12, |
32 | DRM_FORMAT_NV12M, | ||
33 | DRM_FORMAT_NV12MT, | 32 | DRM_FORMAT_NV12MT, |
34 | }; | 33 | }; |
35 | 34 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index bb1550c4dd57..537027a74fd5 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c | |||
@@ -633,7 +633,7 @@ static int __devinit vidi_probe(struct platform_device *pdev) | |||
633 | 633 | ||
634 | DRM_DEBUG_KMS("%s\n", __FILE__); | 634 | DRM_DEBUG_KMS("%s\n", __FILE__); |
635 | 635 | ||
636 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | 636 | ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); |
637 | if (!ctx) | 637 | if (!ctx) |
638 | return -ENOMEM; | 638 | return -ENOMEM; |
639 | 639 | ||
@@ -673,8 +673,6 @@ static int __devexit vidi_remove(struct platform_device *pdev) | |||
673 | ctx->raw_edid = NULL; | 673 | ctx->raw_edid = NULL; |
674 | } | 674 | } |
675 | 675 | ||
676 | kfree(ctx); | ||
677 | |||
678 | return 0; | 676 | return 0; |
679 | } | 677 | } |
680 | 678 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 409e2ec1207c..a6aea6f3ea1a 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
@@ -2172,7 +2172,7 @@ static int __devinit hdmi_resources_init(struct hdmi_context *hdata) | |||
2172 | 2172 | ||
2173 | DRM_DEBUG_KMS("HDMI resource init\n"); | 2173 | DRM_DEBUG_KMS("HDMI resource init\n"); |
2174 | 2174 | ||
2175 | memset(res, 0, sizeof *res); | 2175 | memset(res, 0, sizeof(*res)); |
2176 | 2176 | ||
2177 | /* get clocks, power */ | 2177 | /* get clocks, power */ |
2178 | res->hdmi = clk_get(dev, "hdmi"); | 2178 | res->hdmi = clk_get(dev, "hdmi"); |
@@ -2204,7 +2204,7 @@ static int __devinit hdmi_resources_init(struct hdmi_context *hdata) | |||
2204 | clk_set_parent(res->sclk_hdmi, res->sclk_pixel); | 2204 | clk_set_parent(res->sclk_hdmi, res->sclk_pixel); |
2205 | 2205 | ||
2206 | res->regul_bulk = kzalloc(ARRAY_SIZE(supply) * | 2206 | res->regul_bulk = kzalloc(ARRAY_SIZE(supply) * |
2207 | sizeof res->regul_bulk[0], GFP_KERNEL); | 2207 | sizeof(res->regul_bulk[0]), GFP_KERNEL); |
2208 | if (!res->regul_bulk) { | 2208 | if (!res->regul_bulk) { |
2209 | DRM_ERROR("failed to get memory for regulators\n"); | 2209 | DRM_ERROR("failed to get memory for regulators\n"); |
2210 | goto fail; | 2210 | goto fail; |
@@ -2243,7 +2243,7 @@ static int hdmi_resources_cleanup(struct hdmi_context *hdata) | |||
2243 | clk_put(res->sclk_hdmi); | 2243 | clk_put(res->sclk_hdmi); |
2244 | if (!IS_ERR_OR_NULL(res->hdmi)) | 2244 | if (!IS_ERR_OR_NULL(res->hdmi)) |
2245 | clk_put(res->hdmi); | 2245 | clk_put(res->hdmi); |
2246 | memset(res, 0, sizeof *res); | 2246 | memset(res, 0, sizeof(*res)); |
2247 | 2247 | ||
2248 | return 0; | 2248 | return 0; |
2249 | } | 2249 | } |
@@ -2312,11 +2312,6 @@ static int __devinit hdmi_probe(struct platform_device *pdev) | |||
2312 | } | 2312 | } |
2313 | 2313 | ||
2314 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2314 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2315 | if (!res) { | ||
2316 | DRM_ERROR("failed to find registers\n"); | ||
2317 | ret = -ENOENT; | ||
2318 | goto err_resource; | ||
2319 | } | ||
2320 | 2315 | ||
2321 | hdata->regs = devm_request_and_ioremap(&pdev->dev, res); | 2316 | hdata->regs = devm_request_and_ioremap(&pdev->dev, res); |
2322 | if (!hdata->regs) { | 2317 | if (!hdata->regs) { |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 30fcc12f81dd..25b97d5e5fcb 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
@@ -236,11 +236,11 @@ static inline void vp_filter_set(struct mixer_resources *res, | |||
236 | static void vp_default_filter(struct mixer_resources *res) | 236 | static void vp_default_filter(struct mixer_resources *res) |
237 | { | 237 | { |
238 | vp_filter_set(res, VP_POLY8_Y0_LL, | 238 | vp_filter_set(res, VP_POLY8_Y0_LL, |
239 | filter_y_horiz_tap8, sizeof filter_y_horiz_tap8); | 239 | filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8)); |
240 | vp_filter_set(res, VP_POLY4_Y0_LL, | 240 | vp_filter_set(res, VP_POLY4_Y0_LL, |
241 | filter_y_vert_tap4, sizeof filter_y_vert_tap4); | 241 | filter_y_vert_tap4, sizeof(filter_y_vert_tap4)); |
242 | vp_filter_set(res, VP_POLY4_C0_LL, | 242 | vp_filter_set(res, VP_POLY4_C0_LL, |
243 | filter_cr_horiz_tap4, sizeof filter_cr_horiz_tap4); | 243 | filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4)); |
244 | } | 244 | } |
245 | 245 | ||
246 | static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) | 246 | static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) |
diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c index 0f9b7db80f6b..cf49ba5a54bf 100644 --- a/drivers/gpu/drm/gma500/oaktrail_device.c +++ b/drivers/gpu/drm/gma500/oaktrail_device.c | |||
@@ -476,6 +476,7 @@ static const struct psb_offset oaktrail_regmap[2] = { | |||
476 | .pos = DSPAPOS, | 476 | .pos = DSPAPOS, |
477 | .surf = DSPASURF, | 477 | .surf = DSPASURF, |
478 | .addr = MRST_DSPABASE, | 478 | .addr = MRST_DSPABASE, |
479 | .base = MRST_DSPABASE, | ||
479 | .status = PIPEASTAT, | 480 | .status = PIPEASTAT, |
480 | .linoff = DSPALINOFF, | 481 | .linoff = DSPALINOFF, |
481 | .tileoff = DSPATILEOFF, | 482 | .tileoff = DSPATILEOFF, |
@@ -499,6 +500,7 @@ static const struct psb_offset oaktrail_regmap[2] = { | |||
499 | .pos = DSPBPOS, | 500 | .pos = DSPBPOS, |
500 | .surf = DSPBSURF, | 501 | .surf = DSPBSURF, |
501 | .addr = DSPBBASE, | 502 | .addr = DSPBBASE, |
503 | .base = DSPBBASE, | ||
502 | .status = PIPEBSTAT, | 504 | .status = PIPEBSTAT, |
503 | .linoff = DSPBLINOFF, | 505 | .linoff = DSPBLINOFF, |
504 | .tileoff = DSPBTILEOFF, | 506 | .tileoff = DSPBTILEOFF, |
diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 30dc22a7156c..8033526bb53b 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c | |||
@@ -1362,6 +1362,9 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe, | |||
1362 | (struct drm_connector **) (psb_intel_crtc + 1); | 1362 | (struct drm_connector **) (psb_intel_crtc + 1); |
1363 | psb_intel_crtc->mode_set.num_connectors = 0; | 1363 | psb_intel_crtc->mode_set.num_connectors = 0; |
1364 | psb_intel_cursor_init(dev, psb_intel_crtc); | 1364 | psb_intel_cursor_init(dev, psb_intel_crtc); |
1365 | |||
1366 | /* Set to true so that the pipe is forced off on initial config. */ | ||
1367 | psb_intel_crtc->active = true; | ||
1365 | } | 1368 | } |
1366 | 1369 | ||
1367 | int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 1370 | int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 57d892eaaa6e..463ec6871fe9 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
@@ -115,6 +115,9 @@ static const struct file_operations i810_buffer_fops = { | |||
115 | .unlocked_ioctl = drm_ioctl, | 115 | .unlocked_ioctl = drm_ioctl, |
116 | .mmap = i810_mmap_buffers, | 116 | .mmap = i810_mmap_buffers, |
117 | .fasync = drm_fasync, | 117 | .fasync = drm_fasync, |
118 | #ifdef CONFIG_COMPAT | ||
119 | .compat_ioctl = drm_compat_ioctl, | ||
120 | #endif | ||
118 | .llseek = noop_llseek, | 121 | .llseek = noop_llseek, |
119 | }; | 122 | }; |
120 | 123 | ||
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c index f9924ad04d09..48cfcca2b350 100644 --- a/drivers/gpu/drm/i810/i810_drv.c +++ b/drivers/gpu/drm/i810/i810_drv.c | |||
@@ -51,6 +51,9 @@ static const struct file_operations i810_driver_fops = { | |||
51 | .mmap = drm_mmap, | 51 | .mmap = drm_mmap, |
52 | .poll = drm_poll, | 52 | .poll = drm_poll, |
53 | .fasync = drm_fasync, | 53 | .fasync = drm_fasync, |
54 | #ifdef CONFIG_COMPAT | ||
55 | .compat_ioctl = drm_compat_ioctl, | ||
56 | #endif | ||
54 | .llseek = noop_llseek, | 57 | .llseek = noop_llseek, |
55 | }; | 58 | }; |
56 | 59 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9cf7dfe022b9..914c0dfabe60 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1587,6 +1587,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1587 | spin_lock_init(&dev_priv->irq_lock); | 1587 | spin_lock_init(&dev_priv->irq_lock); |
1588 | spin_lock_init(&dev_priv->error_lock); | 1588 | spin_lock_init(&dev_priv->error_lock); |
1589 | spin_lock_init(&dev_priv->rps_lock); | 1589 | spin_lock_init(&dev_priv->rps_lock); |
1590 | spin_lock_init(&dev_priv->dpio_lock); | ||
1590 | 1591 | ||
1591 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) | 1592 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) |
1592 | dev_priv->num_pipe = 3; | 1593 | dev_priv->num_pipe = 3; |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index d9a5372ec56f..60815b861ec2 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -72,7 +72,7 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) | |||
72 | /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 | 72 | /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 |
73 | * entries. For aliasing ppgtt support we just steal them at the end for | 73 | * entries. For aliasing ppgtt support we just steal them at the end for |
74 | * now. */ | 74 | * now. */ |
75 | first_pd_entry_in_global_pt = 512*1024 - I915_PPGTT_PD_ENTRIES; | 75 | first_pd_entry_in_global_pt = dev_priv->mm.gtt->gtt_total_entries - I915_PPGTT_PD_ENTRIES; |
76 | 76 | ||
77 | ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); | 77 | ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); |
78 | if (!ppgtt) | 78 | if (!ppgtt) |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8a3828528b9d..5249640cce13 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -2700,9 +2700,6 @@ void intel_irq_init(struct drm_device *dev) | |||
2700 | dev->driver->irq_handler = i8xx_irq_handler; | 2700 | dev->driver->irq_handler = i8xx_irq_handler; |
2701 | dev->driver->irq_uninstall = i8xx_irq_uninstall; | 2701 | dev->driver->irq_uninstall = i8xx_irq_uninstall; |
2702 | } else if (INTEL_INFO(dev)->gen == 3) { | 2702 | } else if (INTEL_INFO(dev)->gen == 3) { |
2703 | /* IIR "flip pending" means done if this bit is set */ | ||
2704 | I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); | ||
2705 | |||
2706 | dev->driver->irq_preinstall = i915_irq_preinstall; | 2703 | dev->driver->irq_preinstall = i915_irq_preinstall; |
2707 | dev->driver->irq_postinstall = i915_irq_postinstall; | 2704 | dev->driver->irq_postinstall = i915_irq_postinstall; |
2708 | dev->driver->irq_uninstall = i915_irq_uninstall; | 2705 | dev->driver->irq_uninstall = i915_irq_uninstall; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a69a3d0d3acf..bc2ad348e5d8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1376,7 +1376,8 @@ static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, | |||
1376 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", | 1376 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", |
1377 | reg, pipe_name(pipe)); | 1377 | reg, pipe_name(pipe)); |
1378 | 1378 | ||
1379 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT), | 1379 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & DP_PORT_EN) == 0 |
1380 | && (val & DP_PIPEB_SELECT), | ||
1380 | "IBX PCH dp port still using transcoder B\n"); | 1381 | "IBX PCH dp port still using transcoder B\n"); |
1381 | } | 1382 | } |
1382 | 1383 | ||
@@ -1384,11 +1385,12 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, | |||
1384 | enum pipe pipe, int reg) | 1385 | enum pipe pipe, int reg) |
1385 | { | 1386 | { |
1386 | u32 val = I915_READ(reg); | 1387 | u32 val = I915_READ(reg); |
1387 | WARN(hdmi_pipe_enabled(dev_priv, val, pipe), | 1388 | WARN(hdmi_pipe_enabled(dev_priv, pipe, val), |
1388 | "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", | 1389 | "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", |
1389 | reg, pipe_name(pipe)); | 1390 | reg, pipe_name(pipe)); |
1390 | 1391 | ||
1391 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT), | 1392 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & PORT_ENABLE) == 0 |
1393 | && (val & SDVO_PIPE_B_SELECT), | ||
1392 | "IBX PCH hdmi port still using transcoder B\n"); | 1394 | "IBX PCH hdmi port still using transcoder B\n"); |
1393 | } | 1395 | } |
1394 | 1396 | ||
@@ -1404,13 +1406,13 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, | |||
1404 | 1406 | ||
1405 | reg = PCH_ADPA; | 1407 | reg = PCH_ADPA; |
1406 | val = I915_READ(reg); | 1408 | val = I915_READ(reg); |
1407 | WARN(adpa_pipe_enabled(dev_priv, val, pipe), | 1409 | WARN(adpa_pipe_enabled(dev_priv, pipe, val), |
1408 | "PCH VGA enabled on transcoder %c, should be disabled\n", | 1410 | "PCH VGA enabled on transcoder %c, should be disabled\n", |
1409 | pipe_name(pipe)); | 1411 | pipe_name(pipe)); |
1410 | 1412 | ||
1411 | reg = PCH_LVDS; | 1413 | reg = PCH_LVDS; |
1412 | val = I915_READ(reg); | 1414 | val = I915_READ(reg); |
1413 | WARN(lvds_pipe_enabled(dev_priv, val, pipe), | 1415 | WARN(lvds_pipe_enabled(dev_priv, pipe, val), |
1414 | "PCH LVDS enabled on transcoder %c, should be disabled\n", | 1416 | "PCH LVDS enabled on transcoder %c, should be disabled\n", |
1415 | pipe_name(pipe)); | 1417 | pipe_name(pipe)); |
1416 | 1418 | ||
@@ -1872,7 +1874,7 @@ static void disable_pch_hdmi(struct drm_i915_private *dev_priv, | |||
1872 | enum pipe pipe, int reg) | 1874 | enum pipe pipe, int reg) |
1873 | { | 1875 | { |
1874 | u32 val = I915_READ(reg); | 1876 | u32 val = I915_READ(reg); |
1875 | if (hdmi_pipe_enabled(dev_priv, val, pipe)) { | 1877 | if (hdmi_pipe_enabled(dev_priv, pipe, val)) { |
1876 | DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", | 1878 | DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", |
1877 | reg, pipe); | 1879 | reg, pipe); |
1878 | I915_WRITE(reg, val & ~PORT_ENABLE); | 1880 | I915_WRITE(reg, val & ~PORT_ENABLE); |
@@ -1894,12 +1896,12 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, | |||
1894 | 1896 | ||
1895 | reg = PCH_ADPA; | 1897 | reg = PCH_ADPA; |
1896 | val = I915_READ(reg); | 1898 | val = I915_READ(reg); |
1897 | if (adpa_pipe_enabled(dev_priv, val, pipe)) | 1899 | if (adpa_pipe_enabled(dev_priv, pipe, val)) |
1898 | I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); | 1900 | I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); |
1899 | 1901 | ||
1900 | reg = PCH_LVDS; | 1902 | reg = PCH_LVDS; |
1901 | val = I915_READ(reg); | 1903 | val = I915_READ(reg); |
1902 | if (lvds_pipe_enabled(dev_priv, val, pipe)) { | 1904 | if (lvds_pipe_enabled(dev_priv, pipe, val)) { |
1903 | DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val); | 1905 | DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val); |
1904 | I915_WRITE(reg, val & ~LVDS_PORT_EN); | 1906 | I915_WRITE(reg, val & ~LVDS_PORT_EN); |
1905 | POSTING_READ(reg); | 1907 | POSTING_READ(reg); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a6c426afaa7a..ace757af9133 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -2533,14 +2533,10 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
2533 | break; | 2533 | break; |
2534 | } | 2534 | } |
2535 | 2535 | ||
2536 | intel_dp_i2c_init(intel_dp, intel_connector, name); | ||
2537 | |||
2538 | /* Cache some DPCD data in the eDP case */ | 2536 | /* Cache some DPCD data in the eDP case */ |
2539 | if (is_edp(intel_dp)) { | 2537 | if (is_edp(intel_dp)) { |
2540 | bool ret; | ||
2541 | struct edp_power_seq cur, vbt; | 2538 | struct edp_power_seq cur, vbt; |
2542 | u32 pp_on, pp_off, pp_div; | 2539 | u32 pp_on, pp_off, pp_div; |
2543 | struct edid *edid; | ||
2544 | 2540 | ||
2545 | pp_on = I915_READ(PCH_PP_ON_DELAYS); | 2541 | pp_on = I915_READ(PCH_PP_ON_DELAYS); |
2546 | pp_off = I915_READ(PCH_PP_OFF_DELAYS); | 2542 | pp_off = I915_READ(PCH_PP_OFF_DELAYS); |
@@ -2591,6 +2587,13 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
2591 | 2587 | ||
2592 | DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", | 2588 | DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", |
2593 | intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); | 2589 | intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); |
2590 | } | ||
2591 | |||
2592 | intel_dp_i2c_init(intel_dp, intel_connector, name); | ||
2593 | |||
2594 | if (is_edp(intel_dp)) { | ||
2595 | bool ret; | ||
2596 | struct edid *edid; | ||
2594 | 2597 | ||
2595 | ironlake_edp_panel_vdd_on(intel_dp); | 2598 | ironlake_edp_panel_vdd_on(intel_dp); |
2596 | ret = intel_dp_get_dpcd(intel_dp); | 2599 | ret = intel_dp_get_dpcd(intel_dp); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index e05c0d3e3440..e9a6f6aaed85 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -780,6 +780,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
780 | DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"), | 780 | DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"), |
781 | }, | 781 | }, |
782 | }, | 782 | }, |
783 | { | ||
784 | .callback = intel_no_lvds_dmi_callback, | ||
785 | .ident = "Gigabyte GA-D525TUD", | ||
786 | .matches = { | ||
787 | DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), | ||
788 | DMI_MATCH(DMI_BOARD_NAME, "D525TUD"), | ||
789 | }, | ||
790 | }, | ||
783 | 791 | ||
784 | { } /* terminating entry */ | 792 | { } /* terminating entry */ |
785 | }; | 793 | }; |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 3df4f5fa892a..e019b2369861 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -162,19 +162,12 @@ static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv) | |||
162 | return val; | 162 | return val; |
163 | } | 163 | } |
164 | 164 | ||
165 | u32 intel_panel_get_max_backlight(struct drm_device *dev) | 165 | static u32 _intel_panel_get_max_backlight(struct drm_device *dev) |
166 | { | 166 | { |
167 | struct drm_i915_private *dev_priv = dev->dev_private; | 167 | struct drm_i915_private *dev_priv = dev->dev_private; |
168 | u32 max; | 168 | u32 max; |
169 | 169 | ||
170 | max = i915_read_blc_pwm_ctl(dev_priv); | 170 | max = i915_read_blc_pwm_ctl(dev_priv); |
171 | if (max == 0) { | ||
172 | /* XXX add code here to query mode clock or hardware clock | ||
173 | * and program max PWM appropriately. | ||
174 | */ | ||
175 | pr_warn_once("fixme: max PWM is zero\n"); | ||
176 | return 1; | ||
177 | } | ||
178 | 171 | ||
179 | if (HAS_PCH_SPLIT(dev)) { | 172 | if (HAS_PCH_SPLIT(dev)) { |
180 | max >>= 16; | 173 | max >>= 16; |
@@ -188,6 +181,22 @@ u32 intel_panel_get_max_backlight(struct drm_device *dev) | |||
188 | max *= 0xff; | 181 | max *= 0xff; |
189 | } | 182 | } |
190 | 183 | ||
184 | return max; | ||
185 | } | ||
186 | |||
187 | u32 intel_panel_get_max_backlight(struct drm_device *dev) | ||
188 | { | ||
189 | u32 max; | ||
190 | |||
191 | max = _intel_panel_get_max_backlight(dev); | ||
192 | if (max == 0) { | ||
193 | /* XXX add code here to query mode clock or hardware clock | ||
194 | * and program max PWM appropriately. | ||
195 | */ | ||
196 | pr_warn_once("fixme: max PWM is zero\n"); | ||
197 | return 1; | ||
198 | } | ||
199 | |||
191 | DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); | 200 | DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); |
192 | return max; | 201 | return max; |
193 | } | 202 | } |
@@ -424,7 +433,11 @@ int intel_panel_setup_backlight(struct drm_device *dev) | |||
424 | 433 | ||
425 | memset(&props, 0, sizeof(props)); | 434 | memset(&props, 0, sizeof(props)); |
426 | props.type = BACKLIGHT_RAW; | 435 | props.type = BACKLIGHT_RAW; |
427 | props.max_brightness = intel_panel_get_max_backlight(dev); | 436 | props.max_brightness = _intel_panel_get_max_backlight(dev); |
437 | if (props.max_brightness == 0) { | ||
438 | DRM_ERROR("Failed to get maximum backlight value\n"); | ||
439 | return -ENODEV; | ||
440 | } | ||
428 | dev_priv->backlight = | 441 | dev_priv->backlight = |
429 | backlight_device_register("intel_backlight", | 442 | backlight_device_register("intel_backlight", |
430 | &connector->kdev, dev, | 443 | &connector->kdev, dev, |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 1881c8c83f0e..ba8a27b1757a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -3672,6 +3672,9 @@ static void gen3_init_clock_gating(struct drm_device *dev) | |||
3672 | 3672 | ||
3673 | if (IS_PINEVIEW(dev)) | 3673 | if (IS_PINEVIEW(dev)) |
3674 | I915_WRITE(ECOSKPD, _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY)); | 3674 | I915_WRITE(ECOSKPD, _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY)); |
3675 | |||
3676 | /* IIR "flip pending" means done if this bit is set */ | ||
3677 | I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); | ||
3675 | } | 3678 | } |
3676 | 3679 | ||
3677 | static void i85x_init_clock_gating(struct drm_device *dev) | 3680 | static void i85x_init_clock_gating(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d81bb0bf2885..123afd357611 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -2573,7 +2573,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2573 | hotplug_mask = intel_sdvo->is_sdvob ? | 2573 | hotplug_mask = intel_sdvo->is_sdvob ? |
2574 | SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915; | 2574 | SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915; |
2575 | } | 2575 | } |
2576 | dev_priv->hotplug_supported_mask |= hotplug_mask; | ||
2577 | 2576 | ||
2578 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); | 2577 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); |
2579 | 2578 | ||
@@ -2581,14 +2580,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2581 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) | 2580 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) |
2582 | goto err; | 2581 | goto err; |
2583 | 2582 | ||
2584 | /* Set up hotplug command - note paranoia about contents of reply. | ||
2585 | * We assume that the hardware is in a sane state, and only touch | ||
2586 | * the bits we think we understand. | ||
2587 | */ | ||
2588 | intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, | ||
2589 | &intel_sdvo->hotplug_active, 2); | ||
2590 | intel_sdvo->hotplug_active[0] &= ~0x3; | ||
2591 | |||
2592 | if (intel_sdvo_output_setup(intel_sdvo, | 2583 | if (intel_sdvo_output_setup(intel_sdvo, |
2593 | intel_sdvo->caps.output_flags) != true) { | 2584 | intel_sdvo->caps.output_flags) != true) { |
2594 | DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", | 2585 | DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", |
@@ -2596,6 +2587,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2596 | goto err; | 2587 | goto err; |
2597 | } | 2588 | } |
2598 | 2589 | ||
2590 | /* Only enable the hotplug irq if we need it, to work around noisy | ||
2591 | * hotplug lines. | ||
2592 | */ | ||
2593 | if (intel_sdvo->hotplug_active[0]) | ||
2594 | dev_priv->hotplug_supported_mask |= hotplug_mask; | ||
2595 | |||
2599 | intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); | 2596 | intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); |
2600 | 2597 | ||
2601 | /* Set the input timing to the screen. Assume always input 0. */ | 2598 | /* Set the input timing to the screen. Assume always input 0. */ |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index cc8df4de2d92..7644f31a3778 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
@@ -60,11 +60,11 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
60 | 60 | ||
61 | switch (fb->pixel_format) { | 61 | switch (fb->pixel_format) { |
62 | case DRM_FORMAT_XBGR8888: | 62 | case DRM_FORMAT_XBGR8888: |
63 | sprctl |= SPRITE_FORMAT_RGBX888; | 63 | sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; |
64 | pixel_size = 4; | 64 | pixel_size = 4; |
65 | break; | 65 | break; |
66 | case DRM_FORMAT_XRGB8888: | 66 | case DRM_FORMAT_XRGB8888: |
67 | sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; | 67 | sprctl |= SPRITE_FORMAT_RGBX888; |
68 | pixel_size = 4; | 68 | pixel_size = 4; |
69 | break; | 69 | break; |
70 | case DRM_FORMAT_YUYV: | 70 | case DRM_FORMAT_YUYV: |
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index ea1024d79974..e5f145d2cb3b 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c | |||
@@ -84,6 +84,9 @@ static const struct file_operations mgag200_driver_fops = { | |||
84 | .mmap = mgag200_mmap, | 84 | .mmap = mgag200_mmap, |
85 | .poll = drm_poll, | 85 | .poll = drm_poll, |
86 | .fasync = drm_fasync, | 86 | .fasync = drm_fasync, |
87 | #ifdef CONFIG_COMPAT | ||
88 | .compat_ioctl = drm_compat_ioctl, | ||
89 | #endif | ||
87 | .read = drm_read, | 90 | .read = drm_read, |
88 | }; | 91 | }; |
89 | 92 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 69688ef5cf46..7e16dc5e6467 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
@@ -598,7 +598,7 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, | |||
598 | args->size = args->pitch * args->height; | 598 | args->size = args->pitch * args->height; |
599 | args->size = roundup(args->size, PAGE_SIZE); | 599 | args->size = roundup(args->size, PAGE_SIZE); |
600 | 600 | ||
601 | ret = nouveau_gem_new(dev, args->size, 0, TTM_PL_FLAG_VRAM, 0, 0, &bo); | 601 | ret = nouveau_gem_new(dev, args->size, 0, NOUVEAU_GEM_DOMAIN_VRAM, 0, 0, &bo); |
602 | if (ret) | 602 | if (ret) |
603 | return ret; | 603 | return ret; |
604 | 604 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 1866dbb49979..c61014442aa9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -736,9 +736,11 @@ nouveau_card_init(struct drm_device *dev) | |||
736 | } | 736 | } |
737 | break; | 737 | break; |
738 | case NV_C0: | 738 | case NV_C0: |
739 | nvc0_copy_create(dev, 1); | 739 | if (!(nv_rd32(dev, 0x022500) & 0x00000200)) |
740 | nvc0_copy_create(dev, 1); | ||
740 | case NV_D0: | 741 | case NV_D0: |
741 | nvc0_copy_create(dev, 0); | 742 | if (!(nv_rd32(dev, 0x022500) & 0x00000100)) |
743 | nvc0_copy_create(dev, 0); | ||
742 | break; | 744 | break; |
743 | default: | 745 | default: |
744 | break; | 746 | break; |
diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c index f429e6a8ca7a..f03490534893 100644 --- a/drivers/gpu/drm/nouveau/nv50_gpio.c +++ b/drivers/gpu/drm/nouveau/nv50_gpio.c | |||
@@ -115,6 +115,9 @@ nv50_gpio_init(struct drm_device *dev) | |||
115 | { | 115 | { |
116 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 116 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
117 | 117 | ||
118 | /* initialise gpios and routing to vbios defaults */ | ||
119 | nouveau_gpio_reset(dev); | ||
120 | |||
118 | /* disable, and ack any pending gpio interrupts */ | 121 | /* disable, and ack any pending gpio interrupts */ |
119 | nv_wr32(dev, 0xe050, 0x00000000); | 122 | nv_wr32(dev, 0xe050, 0x00000000); |
120 | nv_wr32(dev, 0xe054, 0xffffffff); | 123 | nv_wr32(dev, 0xe054, 0xffffffff); |
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index dac525b2994e..8a2fc89b7763 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c | |||
@@ -1510,10 +1510,10 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, | |||
1510 | case OUTPUT_DP: | 1510 | case OUTPUT_DP: |
1511 | if (nv_connector->base.display_info.bpc == 6) { | 1511 | if (nv_connector->base.display_info.bpc == 6) { |
1512 | nv_encoder->dp.datarate = mode->clock * 18 / 8; | 1512 | nv_encoder->dp.datarate = mode->clock * 18 / 8; |
1513 | syncs |= 0x00000140; | 1513 | syncs |= 0x00000002 << 6; |
1514 | } else { | 1514 | } else { |
1515 | nv_encoder->dp.datarate = mode->clock * 24 / 8; | 1515 | nv_encoder->dp.datarate = mode->clock * 24 / 8; |
1516 | syncs |= 0x00000180; | 1516 | syncs |= 0x00000005 << 6; |
1517 | } | 1517 | } |
1518 | 1518 | ||
1519 | if (nv_encoder->dcb->sorconf.link & 1) | 1519 | if (nv_encoder->dcb->sorconf.link & 1) |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index f4d4505fe831..e721e3087b99 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -258,7 +258,6 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
258 | radeon_crtc->enabled = true; | 258 | radeon_crtc->enabled = true; |
259 | /* adjust pm to dpms changes BEFORE enabling crtcs */ | 259 | /* adjust pm to dpms changes BEFORE enabling crtcs */ |
260 | radeon_pm_compute_clocks(rdev); | 260 | radeon_pm_compute_clocks(rdev); |
261 | /* disable crtc pair power gating before programming */ | ||
262 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) | 261 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) |
263 | atombios_powergate_crtc(crtc, ATOM_DISABLE); | 262 | atombios_powergate_crtc(crtc, ATOM_DISABLE); |
264 | atombios_enable_crtc(crtc, ATOM_ENABLE); | 263 | atombios_enable_crtc(crtc, ATOM_ENABLE); |
@@ -278,25 +277,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
278 | atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); | 277 | atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); |
279 | atombios_enable_crtc(crtc, ATOM_DISABLE); | 278 | atombios_enable_crtc(crtc, ATOM_DISABLE); |
280 | radeon_crtc->enabled = false; | 279 | radeon_crtc->enabled = false; |
281 | /* power gating is per-pair */ | 280 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) |
282 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) { | 281 | atombios_powergate_crtc(crtc, ATOM_ENABLE); |
283 | struct drm_crtc *other_crtc; | ||
284 | struct radeon_crtc *other_radeon_crtc; | ||
285 | list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) { | ||
286 | other_radeon_crtc = to_radeon_crtc(other_crtc); | ||
287 | if (((radeon_crtc->crtc_id == 0) && (other_radeon_crtc->crtc_id == 1)) || | ||
288 | ((radeon_crtc->crtc_id == 1) && (other_radeon_crtc->crtc_id == 0)) || | ||
289 | ((radeon_crtc->crtc_id == 2) && (other_radeon_crtc->crtc_id == 3)) || | ||
290 | ((radeon_crtc->crtc_id == 3) && (other_radeon_crtc->crtc_id == 2)) || | ||
291 | ((radeon_crtc->crtc_id == 4) && (other_radeon_crtc->crtc_id == 5)) || | ||
292 | ((radeon_crtc->crtc_id == 5) && (other_radeon_crtc->crtc_id == 4))) { | ||
293 | /* if both crtcs in the pair are off, enable power gating */ | ||
294 | if (other_radeon_crtc->enabled == false) | ||
295 | atombios_powergate_crtc(crtc, ATOM_ENABLE); | ||
296 | break; | ||
297 | } | ||
298 | } | ||
299 | } | ||
300 | /* adjust pm to dpms changes AFTER disabling crtcs */ | 282 | /* adjust pm to dpms changes AFTER disabling crtcs */ |
301 | radeon_pm_compute_clocks(rdev); | 283 | radeon_pm_compute_clocks(rdev); |
302 | break; | 284 | break; |
@@ -1497,14 +1479,98 @@ static void radeon_legacy_atom_fixup(struct drm_crtc *crtc) | |||
1497 | } | 1479 | } |
1498 | } | 1480 | } |
1499 | 1481 | ||
1482 | /** | ||
1483 | * radeon_get_pll_use_mask - look up a mask of which pplls are in use | ||
1484 | * | ||
1485 | * @crtc: drm crtc | ||
1486 | * | ||
1487 | * Returns the mask of which PPLLs (Pixel PLLs) are in use. | ||
1488 | */ | ||
1489 | static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc) | ||
1490 | { | ||
1491 | struct drm_device *dev = crtc->dev; | ||
1492 | struct drm_crtc *test_crtc; | ||
1493 | struct radeon_crtc *radeon_test_crtc; | ||
1494 | u32 pll_in_use = 0; | ||
1495 | |||
1496 | list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { | ||
1497 | if (crtc == test_crtc) | ||
1498 | continue; | ||
1499 | |||
1500 | radeon_test_crtc = to_radeon_crtc(test_crtc); | ||
1501 | if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID) | ||
1502 | pll_in_use |= (1 << radeon_test_crtc->pll_id); | ||
1503 | } | ||
1504 | return pll_in_use; | ||
1505 | } | ||
1506 | |||
1507 | /** | ||
1508 | * radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP | ||
1509 | * | ||
1510 | * @crtc: drm crtc | ||
1511 | * | ||
1512 | * Returns the PPLL (Pixel PLL) used by another crtc/encoder which is | ||
1513 | * also in DP mode. For DP, a single PPLL can be used for all DP | ||
1514 | * crtcs/encoders. | ||
1515 | */ | ||
1516 | static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc) | ||
1517 | { | ||
1518 | struct drm_device *dev = crtc->dev; | ||
1519 | struct drm_encoder *test_encoder; | ||
1520 | struct radeon_crtc *radeon_test_crtc; | ||
1521 | |||
1522 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { | ||
1523 | if (test_encoder->crtc && (test_encoder->crtc != crtc)) { | ||
1524 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { | ||
1525 | /* for DP use the same PLL for all */ | ||
1526 | radeon_test_crtc = to_radeon_crtc(test_encoder->crtc); | ||
1527 | if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID) | ||
1528 | return radeon_test_crtc->pll_id; | ||
1529 | } | ||
1530 | } | ||
1531 | } | ||
1532 | return ATOM_PPLL_INVALID; | ||
1533 | } | ||
1534 | |||
1535 | /** | ||
1536 | * radeon_atom_pick_pll - Allocate a PPLL for use by the crtc. | ||
1537 | * | ||
1538 | * @crtc: drm crtc | ||
1539 | * | ||
1540 | * Returns the PPLL (Pixel PLL) to be used by the crtc. For DP monitors | ||
1541 | * a single PPLL can be used for all DP crtcs/encoders. For non-DP | ||
1542 | * monitors a dedicated PPLL must be used. If a particular board has | ||
1543 | * an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming | ||
1544 | * as there is no need to program the PLL itself. If we are not able to | ||
1545 | * allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to | ||
1546 | * avoid messing up an existing monitor. | ||
1547 | * | ||
1548 | * Asic specific PLL information | ||
1549 | * | ||
1550 | * DCE 6.1 | ||
1551 | * - PPLL2 is only available to UNIPHYA (both DP and non-DP) | ||
1552 | * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP) | ||
1553 | * | ||
1554 | * DCE 6.0 | ||
1555 | * - PPLL0 is available to all UNIPHY (DP only) | ||
1556 | * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC | ||
1557 | * | ||
1558 | * DCE 5.0 | ||
1559 | * - DCPLL is available to all UNIPHY (DP only) | ||
1560 | * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC | ||
1561 | * | ||
1562 | * DCE 3.0/4.0/4.1 | ||
1563 | * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC | ||
1564 | * | ||
1565 | */ | ||
1500 | static int radeon_atom_pick_pll(struct drm_crtc *crtc) | 1566 | static int radeon_atom_pick_pll(struct drm_crtc *crtc) |
1501 | { | 1567 | { |
1502 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1568 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1503 | struct drm_device *dev = crtc->dev; | 1569 | struct drm_device *dev = crtc->dev; |
1504 | struct radeon_device *rdev = dev->dev_private; | 1570 | struct radeon_device *rdev = dev->dev_private; |
1505 | struct drm_encoder *test_encoder; | 1571 | struct drm_encoder *test_encoder; |
1506 | struct drm_crtc *test_crtc; | 1572 | u32 pll_in_use; |
1507 | uint32_t pll_in_use = 0; | 1573 | int pll; |
1508 | 1574 | ||
1509 | if (ASIC_IS_DCE61(rdev)) { | 1575 | if (ASIC_IS_DCE61(rdev)) { |
1510 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { | 1576 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { |
@@ -1516,32 +1582,40 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1516 | 1582 | ||
1517 | if ((test_radeon_encoder->encoder_id == | 1583 | if ((test_radeon_encoder->encoder_id == |
1518 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY) && | 1584 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY) && |
1519 | (dig->linkb == false)) /* UNIPHY A uses PPLL2 */ | 1585 | (dig->linkb == false)) |
1586 | /* UNIPHY A uses PPLL2 */ | ||
1520 | return ATOM_PPLL2; | 1587 | return ATOM_PPLL2; |
1588 | else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { | ||
1589 | /* UNIPHY B/C/D/E/F */ | ||
1590 | if (rdev->clock.dp_extclk) | ||
1591 | /* skip PPLL programming if using ext clock */ | ||
1592 | return ATOM_PPLL_INVALID; | ||
1593 | else { | ||
1594 | /* use the same PPLL for all DP monitors */ | ||
1595 | pll = radeon_get_shared_dp_ppll(crtc); | ||
1596 | if (pll != ATOM_PPLL_INVALID) | ||
1597 | return pll; | ||
1598 | } | ||
1599 | } | ||
1600 | break; | ||
1521 | } | 1601 | } |
1522 | } | 1602 | } |
1523 | /* UNIPHY B/C/D/E/F */ | 1603 | /* UNIPHY B/C/D/E/F */ |
1524 | list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { | 1604 | pll_in_use = radeon_get_pll_use_mask(crtc); |
1525 | struct radeon_crtc *radeon_test_crtc; | 1605 | if (!(pll_in_use & (1 << ATOM_PPLL0))) |
1526 | |||
1527 | if (crtc == test_crtc) | ||
1528 | continue; | ||
1529 | |||
1530 | radeon_test_crtc = to_radeon_crtc(test_crtc); | ||
1531 | if ((radeon_test_crtc->pll_id == ATOM_PPLL0) || | ||
1532 | (radeon_test_crtc->pll_id == ATOM_PPLL1)) | ||
1533 | pll_in_use |= (1 << radeon_test_crtc->pll_id); | ||
1534 | } | ||
1535 | if (!(pll_in_use & 4)) | ||
1536 | return ATOM_PPLL0; | 1606 | return ATOM_PPLL0; |
1537 | return ATOM_PPLL1; | 1607 | if (!(pll_in_use & (1 << ATOM_PPLL1))) |
1608 | return ATOM_PPLL1; | ||
1609 | DRM_ERROR("unable to allocate a PPLL\n"); | ||
1610 | return ATOM_PPLL_INVALID; | ||
1538 | } else if (ASIC_IS_DCE4(rdev)) { | 1611 | } else if (ASIC_IS_DCE4(rdev)) { |
1539 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { | 1612 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { |
1540 | if (test_encoder->crtc && (test_encoder->crtc == crtc)) { | 1613 | if (test_encoder->crtc && (test_encoder->crtc == crtc)) { |
1541 | /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock, | 1614 | /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock, |
1542 | * depending on the asic: | 1615 | * depending on the asic: |
1543 | * DCE4: PPLL or ext clock | 1616 | * DCE4: PPLL or ext clock |
1544 | * DCE5: DCPLL or ext clock | 1617 | * DCE5: PPLL, DCPLL, or ext clock |
1618 | * DCE6: PPLL, PPLL0, or ext clock | ||
1545 | * | 1619 | * |
1546 | * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip | 1620 | * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip |
1547 | * PPLL/DCPLL programming and only program the DP DTO for the | 1621 | * PPLL/DCPLL programming and only program the DP DTO for the |
@@ -1549,31 +1623,34 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1549 | */ | 1623 | */ |
1550 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { | 1624 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { |
1551 | if (rdev->clock.dp_extclk) | 1625 | if (rdev->clock.dp_extclk) |
1626 | /* skip PPLL programming if using ext clock */ | ||
1552 | return ATOM_PPLL_INVALID; | 1627 | return ATOM_PPLL_INVALID; |
1553 | else if (ASIC_IS_DCE6(rdev)) | 1628 | else if (ASIC_IS_DCE6(rdev)) |
1629 | /* use PPLL0 for all DP */ | ||
1554 | return ATOM_PPLL0; | 1630 | return ATOM_PPLL0; |
1555 | else if (ASIC_IS_DCE5(rdev)) | 1631 | else if (ASIC_IS_DCE5(rdev)) |
1632 | /* use DCPLL for all DP */ | ||
1556 | return ATOM_DCPLL; | 1633 | return ATOM_DCPLL; |
1634 | else { | ||
1635 | /* use the same PPLL for all DP monitors */ | ||
1636 | pll = radeon_get_shared_dp_ppll(crtc); | ||
1637 | if (pll != ATOM_PPLL_INVALID) | ||
1638 | return pll; | ||
1639 | } | ||
1557 | } | 1640 | } |
1641 | break; | ||
1558 | } | 1642 | } |
1559 | } | 1643 | } |
1560 | 1644 | /* all other cases */ | |
1561 | /* otherwise, pick one of the plls */ | 1645 | pll_in_use = radeon_get_pll_use_mask(crtc); |
1562 | list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { | 1646 | if (!(pll_in_use & (1 << ATOM_PPLL2))) |
1563 | struct radeon_crtc *radeon_test_crtc; | 1647 | return ATOM_PPLL2; |
1564 | 1648 | if (!(pll_in_use & (1 << ATOM_PPLL1))) | |
1565 | if (crtc == test_crtc) | ||
1566 | continue; | ||
1567 | |||
1568 | radeon_test_crtc = to_radeon_crtc(test_crtc); | ||
1569 | if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) && | ||
1570 | (radeon_test_crtc->pll_id <= ATOM_PPLL2)) | ||
1571 | pll_in_use |= (1 << radeon_test_crtc->pll_id); | ||
1572 | } | ||
1573 | if (!(pll_in_use & 1)) | ||
1574 | return ATOM_PPLL1; | 1649 | return ATOM_PPLL1; |
1575 | return ATOM_PPLL2; | 1650 | DRM_ERROR("unable to allocate a PPLL\n"); |
1651 | return ATOM_PPLL_INVALID; | ||
1576 | } else | 1652 | } else |
1653 | /* use PPLL1 or PPLL2 */ | ||
1577 | return radeon_crtc->crtc_id; | 1654 | return radeon_crtc->crtc_id; |
1578 | 1655 | ||
1579 | } | 1656 | } |
@@ -1682,9 +1759,22 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) | |||
1682 | struct drm_device *dev = crtc->dev; | 1759 | struct drm_device *dev = crtc->dev; |
1683 | struct radeon_device *rdev = dev->dev_private; | 1760 | struct radeon_device *rdev = dev->dev_private; |
1684 | struct radeon_atom_ss ss; | 1761 | struct radeon_atom_ss ss; |
1762 | int i; | ||
1685 | 1763 | ||
1686 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | 1764 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
1687 | 1765 | ||
1766 | for (i = 0; i < rdev->num_crtc; i++) { | ||
1767 | if (rdev->mode_info.crtcs[i] && | ||
1768 | rdev->mode_info.crtcs[i]->enabled && | ||
1769 | i != radeon_crtc->crtc_id && | ||
1770 | radeon_crtc->pll_id == rdev->mode_info.crtcs[i]->pll_id) { | ||
1771 | /* one other crtc is using this pll don't turn | ||
1772 | * off the pll | ||
1773 | */ | ||
1774 | goto done; | ||
1775 | } | ||
1776 | } | ||
1777 | |||
1688 | switch (radeon_crtc->pll_id) { | 1778 | switch (radeon_crtc->pll_id) { |
1689 | case ATOM_PPLL1: | 1779 | case ATOM_PPLL1: |
1690 | case ATOM_PPLL2: | 1780 | case ATOM_PPLL2: |
@@ -1701,7 +1791,8 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) | |||
1701 | default: | 1791 | default: |
1702 | break; | 1792 | break; |
1703 | } | 1793 | } |
1704 | radeon_crtc->pll_id = -1; | 1794 | done: |
1795 | radeon_crtc->pll_id = ATOM_PPLL_INVALID; | ||
1705 | } | 1796 | } |
1706 | 1797 | ||
1707 | static const struct drm_crtc_helper_funcs atombios_helper_funcs = { | 1798 | static const struct drm_crtc_helper_funcs atombios_helper_funcs = { |
@@ -1750,6 +1841,6 @@ void radeon_atombios_init_crtc(struct drm_device *dev, | |||
1750 | else | 1841 | else |
1751 | radeon_crtc->crtc_offset = 0; | 1842 | radeon_crtc->crtc_offset = 0; |
1752 | } | 1843 | } |
1753 | radeon_crtc->pll_id = -1; | 1844 | radeon_crtc->pll_id = ATOM_PPLL_INVALID; |
1754 | drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); | 1845 | drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); |
1755 | } | 1846 | } |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 7712cf5ab33b..3623b98ed3fe 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -577,30 +577,25 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, | |||
577 | struct radeon_device *rdev = dev->dev_private; | 577 | struct radeon_device *rdev = dev->dev_private; |
578 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 578 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
579 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | 579 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
580 | u16 dp_bridge = radeon_connector_encoder_get_dp_bridge_encoder_id(connector); | ||
581 | u8 tmp; | ||
580 | 582 | ||
581 | if (!ASIC_IS_DCE4(rdev)) | 583 | if (!ASIC_IS_DCE4(rdev)) |
582 | return panel_mode; | 584 | return panel_mode; |
583 | 585 | ||
584 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == | 586 | if (dp_bridge != ENCODER_OBJECT_ID_NONE) { |
585 | ENCODER_OBJECT_ID_NUTMEG) | 587 | /* DP bridge chips */ |
586 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | 588 | tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); |
587 | else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == | 589 | if (tmp & 1) |
588 | ENCODER_OBJECT_ID_TRAVIS) { | 590 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
589 | u8 id[6]; | 591 | else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || |
590 | int i; | 592 | (dp_bridge == ENCODER_OBJECT_ID_TRAVIS)) |
591 | for (i = 0; i < 6; i++) | ||
592 | id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 + i); | ||
593 | if (id[0] == 0x73 && | ||
594 | id[1] == 0x69 && | ||
595 | id[2] == 0x76 && | ||
596 | id[3] == 0x61 && | ||
597 | id[4] == 0x72 && | ||
598 | id[5] == 0x54) | ||
599 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | 593 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; |
600 | else | 594 | else |
601 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 595 | panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
602 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 596 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
603 | u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); | 597 | /* eDP */ |
598 | tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); | ||
604 | if (tmp & 1) | 599 | if (tmp & 1) |
605 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 600 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
606 | } | 601 | } |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index f9bc27fe269a..6e8803a1170c 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
@@ -1379,6 +1379,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
1379 | struct drm_device *dev = encoder->dev; | 1379 | struct drm_device *dev = encoder->dev; |
1380 | struct radeon_device *rdev = dev->dev_private; | 1380 | struct radeon_device *rdev = dev->dev_private; |
1381 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1381 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1382 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
1383 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
1382 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | 1384 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
1383 | struct radeon_connector *radeon_connector = NULL; | 1385 | struct radeon_connector *radeon_connector = NULL; |
1384 | struct radeon_connector_atom_dig *radeon_dig_connector = NULL; | 1386 | struct radeon_connector_atom_dig *radeon_dig_connector = NULL; |
@@ -1390,19 +1392,37 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
1390 | 1392 | ||
1391 | switch (mode) { | 1393 | switch (mode) { |
1392 | case DRM_MODE_DPMS_ON: | 1394 | case DRM_MODE_DPMS_ON: |
1393 | /* some early dce3.2 boards have a bug in their transmitter control table */ | 1395 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { |
1394 | if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) || | 1396 | if (!connector) |
1395 | ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { | 1397 | dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
1396 | if (ASIC_IS_DCE6(rdev)) { | 1398 | else |
1397 | /* It seems we need to call ATOM_ENCODER_CMD_SETUP again | 1399 | dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); |
1398 | * before reenabling encoder on DPMS ON, otherwise we never | 1400 | |
1399 | * get picture | 1401 | /* setup and enable the encoder */ |
1400 | */ | 1402 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); |
1401 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | 1403 | atombios_dig_encoder_setup(encoder, |
1404 | ATOM_ENCODER_CMD_SETUP_PANEL_MODE, | ||
1405 | dig->panel_mode); | ||
1406 | if (ext_encoder) { | ||
1407 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) | ||
1408 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1409 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); | ||
1402 | } | 1410 | } |
1403 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | 1411 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
1404 | } else { | 1412 | } else if (ASIC_IS_DCE4(rdev)) { |
1413 | /* setup and enable the encoder */ | ||
1414 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
1415 | /* enable the transmitter */ | ||
1416 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1405 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | 1417 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
1418 | } else { | ||
1419 | /* setup and enable the encoder and transmitter */ | ||
1420 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); | ||
1421 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | ||
1422 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1423 | /* some early dce3.2 boards have a bug in their transmitter control table */ | ||
1424 | if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730)) | ||
1425 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | ||
1406 | } | 1426 | } |
1407 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | 1427 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { |
1408 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 1428 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
@@ -1420,10 +1440,19 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
1420 | case DRM_MODE_DPMS_STANDBY: | 1440 | case DRM_MODE_DPMS_STANDBY: |
1421 | case DRM_MODE_DPMS_SUSPEND: | 1441 | case DRM_MODE_DPMS_SUSPEND: |
1422 | case DRM_MODE_DPMS_OFF: | 1442 | case DRM_MODE_DPMS_OFF: |
1423 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) | 1443 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { |
1444 | /* disable the transmitter */ | ||
1424 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | 1445 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
1425 | else | 1446 | } else if (ASIC_IS_DCE4(rdev)) { |
1447 | /* disable the transmitter */ | ||
1448 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
1449 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1450 | } else { | ||
1451 | /* disable the encoder and transmitter */ | ||
1426 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | 1452 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); |
1453 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1454 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
1455 | } | ||
1427 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | 1456 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { |
1428 | if (ASIC_IS_DCE4(rdev)) | 1457 | if (ASIC_IS_DCE4(rdev)) |
1429 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); | 1458 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); |
@@ -1740,13 +1769,34 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | |||
1740 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | 1769 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
1741 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1770 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1742 | struct drm_encoder *test_encoder; | 1771 | struct drm_encoder *test_encoder; |
1743 | struct radeon_encoder_atom_dig *dig; | 1772 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
1744 | uint32_t dig_enc_in_use = 0; | 1773 | uint32_t dig_enc_in_use = 0; |
1745 | 1774 | ||
1746 | /* DCE4/5 */ | 1775 | if (ASIC_IS_DCE6(rdev)) { |
1747 | if (ASIC_IS_DCE4(rdev)) { | 1776 | /* DCE6 */ |
1748 | dig = radeon_encoder->enc_priv; | 1777 | switch (radeon_encoder->encoder_id) { |
1749 | if (ASIC_IS_DCE41(rdev)) { | 1778 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
1779 | if (dig->linkb) | ||
1780 | return 1; | ||
1781 | else | ||
1782 | return 0; | ||
1783 | break; | ||
1784 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1785 | if (dig->linkb) | ||
1786 | return 3; | ||
1787 | else | ||
1788 | return 2; | ||
1789 | break; | ||
1790 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1791 | if (dig->linkb) | ||
1792 | return 5; | ||
1793 | else | ||
1794 | return 4; | ||
1795 | break; | ||
1796 | } | ||
1797 | } else if (ASIC_IS_DCE4(rdev)) { | ||
1798 | /* DCE4/5 */ | ||
1799 | if (ASIC_IS_DCE41(rdev) && !ASIC_IS_DCE61(rdev)) { | ||
1750 | /* ontario follows DCE4 */ | 1800 | /* ontario follows DCE4 */ |
1751 | if (rdev->family == CHIP_PALM) { | 1801 | if (rdev->family == CHIP_PALM) { |
1752 | if (dig->linkb) | 1802 | if (dig->linkb) |
@@ -1848,10 +1898,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1848 | struct drm_device *dev = encoder->dev; | 1898 | struct drm_device *dev = encoder->dev; |
1849 | struct radeon_device *rdev = dev->dev_private; | 1899 | struct radeon_device *rdev = dev->dev_private; |
1850 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1900 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1851 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
1852 | 1901 | ||
1853 | radeon_encoder->pixel_clock = adjusted_mode->clock; | 1902 | radeon_encoder->pixel_clock = adjusted_mode->clock; |
1854 | 1903 | ||
1904 | /* need to call this here rather than in prepare() since we need some crtc info */ | ||
1905 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
1906 | |||
1855 | if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) { | 1907 | if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) { |
1856 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) | 1908 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) |
1857 | atombios_yuv_setup(encoder, true); | 1909 | atombios_yuv_setup(encoder, true); |
@@ -1870,38 +1922,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1870 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 1922 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
1871 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1923 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
1872 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1924 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
1873 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { | 1925 | /* handled in dpms */ |
1874 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
1875 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
1876 | |||
1877 | if (!connector) | ||
1878 | dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | ||
1879 | else | ||
1880 | dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); | ||
1881 | |||
1882 | /* setup and enable the encoder */ | ||
1883 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
1884 | atombios_dig_encoder_setup(encoder, | ||
1885 | ATOM_ENCODER_CMD_SETUP_PANEL_MODE, | ||
1886 | dig->panel_mode); | ||
1887 | } else if (ASIC_IS_DCE4(rdev)) { | ||
1888 | /* disable the transmitter */ | ||
1889 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1890 | /* setup and enable the encoder */ | ||
1891 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
1892 | |||
1893 | /* enable the transmitter */ | ||
1894 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1895 | } else { | ||
1896 | /* disable the encoder and transmitter */ | ||
1897 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1898 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
1899 | |||
1900 | /* setup and enable the encoder and transmitter */ | ||
1901 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); | ||
1902 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | ||
1903 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1904 | } | ||
1905 | break; | 1926 | break; |
1906 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | 1927 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
1907 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | 1928 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: |
@@ -1922,14 +1943,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1922 | break; | 1943 | break; |
1923 | } | 1944 | } |
1924 | 1945 | ||
1925 | if (ext_encoder) { | ||
1926 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) | ||
1927 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1928 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); | ||
1929 | else | ||
1930 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); | ||
1931 | } | ||
1932 | |||
1933 | atombios_apply_encoder_quirks(encoder, adjusted_mode); | 1946 | atombios_apply_encoder_quirks(encoder, adjusted_mode); |
1934 | 1947 | ||
1935 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { | 1948 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { |
@@ -2116,7 +2129,6 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | |||
2116 | } | 2129 | } |
2117 | 2130 | ||
2118 | radeon_atom_output_lock(encoder, true); | 2131 | radeon_atom_output_lock(encoder, true); |
2119 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
2120 | 2132 | ||
2121 | if (connector) { | 2133 | if (connector) { |
2122 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 2134 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
@@ -2137,6 +2149,7 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | |||
2137 | 2149 | ||
2138 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) | 2150 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) |
2139 | { | 2151 | { |
2152 | /* need to call this here as we need the crtc set up */ | ||
2140 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON); | 2153 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON); |
2141 | radeon_atom_output_lock(encoder, false); | 2154 | radeon_atom_output_lock(encoder, false); |
2142 | } | 2155 | } |
@@ -2177,14 +2190,7 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) | |||
2177 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 2190 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
2178 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 2191 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
2179 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 2192 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
2180 | if (ASIC_IS_DCE4(rdev)) | 2193 | /* handled in dpms */ |
2181 | /* disable the transmitter */ | ||
2182 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
2183 | else { | ||
2184 | /* disable the encoder and transmitter */ | ||
2185 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
2186 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
2187 | } | ||
2188 | break; | 2194 | break; |
2189 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | 2195 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
2190 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | 2196 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index ab74e6b149e7..f37676d7f217 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -63,6 +63,7 @@ struct r600_cs_track { | |||
63 | u32 cb_color_size_idx[8]; /* unused */ | 63 | u32 cb_color_size_idx[8]; /* unused */ |
64 | u32 cb_target_mask; | 64 | u32 cb_target_mask; |
65 | u32 cb_shader_mask; /* unused */ | 65 | u32 cb_shader_mask; /* unused */ |
66 | bool is_resolve; | ||
66 | u32 cb_color_size[8]; | 67 | u32 cb_color_size[8]; |
67 | u32 vgt_strmout_en; | 68 | u32 vgt_strmout_en; |
68 | u32 vgt_strmout_buffer_en; | 69 | u32 vgt_strmout_buffer_en; |
@@ -315,7 +316,15 @@ static void r600_cs_track_init(struct r600_cs_track *track) | |||
315 | track->cb_color_bo[i] = NULL; | 316 | track->cb_color_bo[i] = NULL; |
316 | track->cb_color_bo_offset[i] = 0xFFFFFFFF; | 317 | track->cb_color_bo_offset[i] = 0xFFFFFFFF; |
317 | track->cb_color_bo_mc[i] = 0xFFFFFFFF; | 318 | track->cb_color_bo_mc[i] = 0xFFFFFFFF; |
318 | } | 319 | track->cb_color_frag_bo[i] = NULL; |
320 | track->cb_color_frag_offset[i] = 0xFFFFFFFF; | ||
321 | track->cb_color_tile_bo[i] = NULL; | ||
322 | track->cb_color_tile_offset[i] = 0xFFFFFFFF; | ||
323 | track->cb_color_mask[i] = 0xFFFFFFFF; | ||
324 | } | ||
325 | track->is_resolve = false; | ||
326 | track->nsamples = 16; | ||
327 | track->log_nsamples = 4; | ||
319 | track->cb_target_mask = 0xFFFFFFFF; | 328 | track->cb_target_mask = 0xFFFFFFFF; |
320 | track->cb_shader_mask = 0xFFFFFFFF; | 329 | track->cb_shader_mask = 0xFFFFFFFF; |
321 | track->cb_dirty = true; | 330 | track->cb_dirty = true; |
@@ -352,6 +361,8 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
352 | volatile u32 *ib = p->ib.ptr; | 361 | volatile u32 *ib = p->ib.ptr; |
353 | unsigned array_mode; | 362 | unsigned array_mode; |
354 | u32 format; | 363 | u32 format; |
364 | /* When resolve is used, the second colorbuffer has always 1 sample. */ | ||
365 | unsigned nsamples = track->is_resolve && i == 1 ? 1 : track->nsamples; | ||
355 | 366 | ||
356 | size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i]; | 367 | size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i]; |
357 | format = G_0280A0_FORMAT(track->cb_color_info[i]); | 368 | format = G_0280A0_FORMAT(track->cb_color_info[i]); |
@@ -375,7 +386,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
375 | array_check.group_size = track->group_size; | 386 | array_check.group_size = track->group_size; |
376 | array_check.nbanks = track->nbanks; | 387 | array_check.nbanks = track->nbanks; |
377 | array_check.npipes = track->npipes; | 388 | array_check.npipes = track->npipes; |
378 | array_check.nsamples = track->nsamples; | 389 | array_check.nsamples = nsamples; |
379 | array_check.blocksize = r600_fmt_get_blocksize(format); | 390 | array_check.blocksize = r600_fmt_get_blocksize(format); |
380 | if (r600_get_array_mode_alignment(&array_check, | 391 | if (r600_get_array_mode_alignment(&array_check, |
381 | &pitch_align, &height_align, &depth_align, &base_align)) { | 392 | &pitch_align, &height_align, &depth_align, &base_align)) { |
@@ -421,7 +432,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
421 | 432 | ||
422 | /* check offset */ | 433 | /* check offset */ |
423 | tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * | 434 | tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * |
424 | r600_fmt_get_blocksize(format) * track->nsamples; | 435 | r600_fmt_get_blocksize(format) * nsamples; |
425 | switch (array_mode) { | 436 | switch (array_mode) { |
426 | default: | 437 | default: |
427 | case V_0280A0_ARRAY_LINEAR_GENERAL: | 438 | case V_0280A0_ARRAY_LINEAR_GENERAL: |
@@ -792,6 +803,12 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
792 | */ | 803 | */ |
793 | if (track->cb_dirty) { | 804 | if (track->cb_dirty) { |
794 | tmp = track->cb_target_mask; | 805 | tmp = track->cb_target_mask; |
806 | |||
807 | /* We must check both colorbuffers for RESOLVE. */ | ||
808 | if (track->is_resolve) { | ||
809 | tmp |= 0xff; | ||
810 | } | ||
811 | |||
795 | for (i = 0; i < 8; i++) { | 812 | for (i = 0; i < 8; i++) { |
796 | if ((tmp >> (i * 4)) & 0xF) { | 813 | if ((tmp >> (i * 4)) & 0xF) { |
797 | /* at least one component is enabled */ | 814 | /* at least one component is enabled */ |
@@ -1281,6 +1298,11 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1281 | track->nsamples = 1 << tmp; | 1298 | track->nsamples = 1 << tmp; |
1282 | track->cb_dirty = true; | 1299 | track->cb_dirty = true; |
1283 | break; | 1300 | break; |
1301 | case R_028808_CB_COLOR_CONTROL: | ||
1302 | tmp = G_028808_SPECIAL_OP(radeon_get_ib_value(p, idx)); | ||
1303 | track->is_resolve = tmp == V_028808_SPECIAL_RESOLVE_BOX; | ||
1304 | track->cb_dirty = true; | ||
1305 | break; | ||
1284 | case R_0280A0_CB_COLOR0_INFO: | 1306 | case R_0280A0_CB_COLOR0_INFO: |
1285 | case R_0280A4_CB_COLOR1_INFO: | 1307 | case R_0280A4_CB_COLOR1_INFO: |
1286 | case R_0280A8_CB_COLOR2_INFO: | 1308 | case R_0280A8_CB_COLOR2_INFO: |
@@ -1416,7 +1438,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1416 | case R_028118_CB_COLOR6_MASK: | 1438 | case R_028118_CB_COLOR6_MASK: |
1417 | case R_02811C_CB_COLOR7_MASK: | 1439 | case R_02811C_CB_COLOR7_MASK: |
1418 | tmp = (reg - R_028100_CB_COLOR0_MASK) / 4; | 1440 | tmp = (reg - R_028100_CB_COLOR0_MASK) / 4; |
1419 | track->cb_color_mask[tmp] = ib[idx]; | 1441 | track->cb_color_mask[tmp] = radeon_get_ib_value(p, idx); |
1420 | if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { | 1442 | if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { |
1421 | track->cb_dirty = true; | 1443 | track->cb_dirty = true; |
1422 | } | 1444 | } |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index bdb69a63062f..fa6f37099ba9 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -66,6 +66,14 @@ | |||
66 | #define CC_RB_BACKEND_DISABLE 0x98F4 | 66 | #define CC_RB_BACKEND_DISABLE 0x98F4 |
67 | #define BACKEND_DISABLE(x) ((x) << 16) | 67 | #define BACKEND_DISABLE(x) ((x) << 16) |
68 | 68 | ||
69 | #define R_028808_CB_COLOR_CONTROL 0x28808 | ||
70 | #define S_028808_SPECIAL_OP(x) (((x) & 0x7) << 4) | ||
71 | #define G_028808_SPECIAL_OP(x) (((x) >> 4) & 0x7) | ||
72 | #define C_028808_SPECIAL_OP 0xFFFFFF8F | ||
73 | #define V_028808_SPECIAL_NORMAL 0x00 | ||
74 | #define V_028808_SPECIAL_DISABLE 0x01 | ||
75 | #define V_028808_SPECIAL_RESOLVE_BOX 0x07 | ||
76 | |||
69 | #define CB_COLOR0_BASE 0x28040 | 77 | #define CB_COLOR0_BASE 0x28040 |
70 | #define CB_COLOR1_BASE 0x28044 | 78 | #define CB_COLOR1_BASE 0x28044 |
71 | #define CB_COLOR2_BASE 0x28048 | 79 | #define CB_COLOR2_BASE 0x28048 |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index d2e243867ac6..7a3daebd732d 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -1051,7 +1051,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1051 | if (rdev->flags & RADEON_IS_AGP) | 1051 | if (rdev->flags & RADEON_IS_AGP) |
1052 | rdev->need_dma32 = true; | 1052 | rdev->need_dma32 = true; |
1053 | if ((rdev->flags & RADEON_IS_PCI) && | 1053 | if ((rdev->flags & RADEON_IS_PCI) && |
1054 | (rdev->family < CHIP_RS400)) | 1054 | (rdev->family <= CHIP_RS740)) |
1055 | rdev->need_dma32 = true; | 1055 | rdev->need_dma32 = true; |
1056 | 1056 | ||
1057 | dma_bits = rdev->need_dma32 ? 32 : 40; | 1057 | dma_bits = rdev->need_dma32 ? 32 : 40; |
@@ -1346,12 +1346,15 @@ retry: | |||
1346 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 1346 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
1347 | radeon_ring_restore(rdev, &rdev->ring[i], | 1347 | radeon_ring_restore(rdev, &rdev->ring[i], |
1348 | ring_sizes[i], ring_data[i]); | 1348 | ring_sizes[i], ring_data[i]); |
1349 | ring_sizes[i] = 0; | ||
1350 | ring_data[i] = NULL; | ||
1349 | } | 1351 | } |
1350 | 1352 | ||
1351 | r = radeon_ib_ring_tests(rdev); | 1353 | r = radeon_ib_ring_tests(rdev); |
1352 | if (r) { | 1354 | if (r) { |
1353 | dev_err(rdev->dev, "ib ring test failed (%d).\n", r); | 1355 | dev_err(rdev->dev, "ib ring test failed (%d).\n", r); |
1354 | if (saved) { | 1356 | if (saved) { |
1357 | saved = false; | ||
1355 | radeon_suspend(rdev); | 1358 | radeon_suspend(rdev); |
1356 | goto retry; | 1359 | goto retry; |
1357 | } | 1360 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 27d22d709c90..8c593ea82c41 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -63,9 +63,10 @@ | |||
63 | * 2.19.0 - r600-eg: MSAA textures | 63 | * 2.19.0 - r600-eg: MSAA textures |
64 | * 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query | 64 | * 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query |
65 | * 2.21.0 - r600-r700: FMASK and CMASK | 65 | * 2.21.0 - r600-r700: FMASK and CMASK |
66 | * 2.22.0 - r600 only: RESOLVE_BOX allowed | ||
66 | */ | 67 | */ |
67 | #define KMS_DRIVER_MAJOR 2 | 68 | #define KMS_DRIVER_MAJOR 2 |
68 | #define KMS_DRIVER_MINOR 21 | 69 | #define KMS_DRIVER_MINOR 22 |
69 | #define KMS_DRIVER_PATCHLEVEL 0 | 70 | #define KMS_DRIVER_PATCHLEVEL 0 |
70 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 71 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
71 | int radeon_driver_unload_kms(struct drm_device *dev); | 72 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 7b737b9339ad..2a59375dbe52 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -131,7 +131,7 @@ int radeon_fence_emit(struct radeon_device *rdev, | |||
131 | */ | 131 | */ |
132 | void radeon_fence_process(struct radeon_device *rdev, int ring) | 132 | void radeon_fence_process(struct radeon_device *rdev, int ring) |
133 | { | 133 | { |
134 | uint64_t seq, last_seq; | 134 | uint64_t seq, last_seq, last_emitted; |
135 | unsigned count_loop = 0; | 135 | unsigned count_loop = 0; |
136 | bool wake = false; | 136 | bool wake = false; |
137 | 137 | ||
@@ -158,13 +158,15 @@ void radeon_fence_process(struct radeon_device *rdev, int ring) | |||
158 | */ | 158 | */ |
159 | last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq); | 159 | last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq); |
160 | do { | 160 | do { |
161 | last_emitted = rdev->fence_drv[ring].sync_seq[ring]; | ||
161 | seq = radeon_fence_read(rdev, ring); | 162 | seq = radeon_fence_read(rdev, ring); |
162 | seq |= last_seq & 0xffffffff00000000LL; | 163 | seq |= last_seq & 0xffffffff00000000LL; |
163 | if (seq < last_seq) { | 164 | if (seq < last_seq) { |
164 | seq += 0x100000000LL; | 165 | seq &= 0xffffffff; |
166 | seq |= last_emitted & 0xffffffff00000000LL; | ||
165 | } | 167 | } |
166 | 168 | ||
167 | if (seq == last_seq) { | 169 | if (seq <= last_seq || seq > last_emitted) { |
168 | break; | 170 | break; |
169 | } | 171 | } |
170 | /* If we loop over we don't want to return without | 172 | /* If we loop over we don't want to return without |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600 index f93e45d869f4..20bfbda7b3f1 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r600 +++ b/drivers/gpu/drm/radeon/reg_srcs/r600 | |||
@@ -744,7 +744,6 @@ r600 0x9400 | |||
744 | 0x00028C38 CB_CLRCMP_DST | 744 | 0x00028C38 CB_CLRCMP_DST |
745 | 0x00028C3C CB_CLRCMP_MSK | 745 | 0x00028C3C CB_CLRCMP_MSK |
746 | 0x00028C34 CB_CLRCMP_SRC | 746 | 0x00028C34 CB_CLRCMP_SRC |
747 | 0x00028808 CB_COLOR_CONTROL | ||
748 | 0x0002842C CB_FOG_BLUE | 747 | 0x0002842C CB_FOG_BLUE |
749 | 0x00028428 CB_FOG_GREEN | 748 | 0x00028428 CB_FOG_GREEN |
750 | 0x00028424 CB_FOG_RED | 749 | 0x00028424 CB_FOG_RED |
diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c index d31d4cca9a4c..c5a164337bd5 100644 --- a/drivers/gpu/drm/savage/savage_drv.c +++ b/drivers/gpu/drm/savage/savage_drv.c | |||
@@ -43,6 +43,9 @@ static const struct file_operations savage_driver_fops = { | |||
43 | .mmap = drm_mmap, | 43 | .mmap = drm_mmap, |
44 | .poll = drm_poll, | 44 | .poll = drm_poll, |
45 | .fasync = drm_fasync, | 45 | .fasync = drm_fasync, |
46 | #ifdef CONFIG_COMPAT | ||
47 | .compat_ioctl = drm_compat_ioctl, | ||
48 | #endif | ||
46 | .llseek = noop_llseek, | 49 | .llseek = noop_llseek, |
47 | }; | 50 | }; |
48 | 51 | ||
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 7f119870147c..867dc03000e6 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c | |||
@@ -74,6 +74,9 @@ static const struct file_operations sis_driver_fops = { | |||
74 | .mmap = drm_mmap, | 74 | .mmap = drm_mmap, |
75 | .poll = drm_poll, | 75 | .poll = drm_poll, |
76 | .fasync = drm_fasync, | 76 | .fasync = drm_fasync, |
77 | #ifdef CONFIG_COMPAT | ||
78 | .compat_ioctl = drm_compat_ioctl, | ||
79 | #endif | ||
77 | .llseek = noop_llseek, | 80 | .llseek = noop_llseek, |
78 | }; | 81 | }; |
79 | 82 | ||
diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c index 90f6b13acfac..a7f4d6bd1330 100644 --- a/drivers/gpu/drm/tdfx/tdfx_drv.c +++ b/drivers/gpu/drm/tdfx/tdfx_drv.c | |||
@@ -49,6 +49,9 @@ static const struct file_operations tdfx_driver_fops = { | |||
49 | .mmap = drm_mmap, | 49 | .mmap = drm_mmap, |
50 | .poll = drm_poll, | 50 | .poll = drm_poll, |
51 | .fasync = drm_fasync, | 51 | .fasync = drm_fasync, |
52 | #ifdef CONFIG_COMPAT | ||
53 | .compat_ioctl = drm_compat_ioctl, | ||
54 | #endif | ||
52 | .llseek = noop_llseek, | 55 | .llseek = noop_llseek, |
53 | }; | 56 | }; |
54 | 57 | ||
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 6e52069894b3..9f84128505bb 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c | |||
@@ -66,6 +66,9 @@ static const struct file_operations udl_driver_fops = { | |||
66 | .unlocked_ioctl = drm_ioctl, | 66 | .unlocked_ioctl = drm_ioctl, |
67 | .release = drm_release, | 67 | .release = drm_release, |
68 | .fasync = drm_fasync, | 68 | .fasync = drm_fasync, |
69 | #ifdef CONFIG_COMPAT | ||
70 | .compat_ioctl = drm_compat_ioctl, | ||
71 | #endif | ||
69 | .llseek = noop_llseek, | 72 | .llseek = noop_llseek, |
70 | }; | 73 | }; |
71 | 74 | ||
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c index e927b4c052f5..af1b914b17e3 100644 --- a/drivers/gpu/drm/via/via_drv.c +++ b/drivers/gpu/drm/via/via_drv.c | |||
@@ -65,6 +65,9 @@ static const struct file_operations via_driver_fops = { | |||
65 | .mmap = drm_mmap, | 65 | .mmap = drm_mmap, |
66 | .poll = drm_poll, | 66 | .poll = drm_poll, |
67 | .fasync = drm_fasync, | 67 | .fasync = drm_fasync, |
68 | #ifdef CONFIG_COMPAT | ||
69 | .compat_ioctl = drm_compat_ioctl, | ||
70 | #endif | ||
68 | .llseek = noop_llseek, | 71 | .llseek = noop_llseek, |
69 | }; | 72 | }; |
70 | 73 | ||
diff --git a/drivers/gpu/drm/vmwgfx/Kconfig b/drivers/gpu/drm/vmwgfx/Kconfig index 794ff67c5701..b71bcd0bfbbf 100644 --- a/drivers/gpu/drm/vmwgfx/Kconfig +++ b/drivers/gpu/drm/vmwgfx/Kconfig | |||
@@ -12,3 +12,11 @@ config DRM_VMWGFX | |||
12 | This is a KMS enabled DRM driver for the VMware SVGA2 | 12 | This is a KMS enabled DRM driver for the VMware SVGA2 |
13 | virtual hardware. | 13 | virtual hardware. |
14 | The compiled module will be called "vmwgfx.ko". | 14 | The compiled module will be called "vmwgfx.ko". |
15 | |||
16 | config DRM_VMWGFX_FBCON | ||
17 | depends on DRM_VMWGFX | ||
18 | bool "Enable framebuffer console under vmwgfx by default" | ||
19 | help | ||
20 | Choose this option if you are shipping a new vmwgfx | ||
21 | userspace driver that supports using the kernel driver. | ||
22 | |||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 4d9edead01ac..ba2c35dbf10e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -182,8 +182,9 @@ static struct pci_device_id vmw_pci_id_list[] = { | |||
182 | {0x15ad, 0x0405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VMWGFX_CHIP_SVGAII}, | 182 | {0x15ad, 0x0405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VMWGFX_CHIP_SVGAII}, |
183 | {0, 0, 0} | 183 | {0, 0, 0} |
184 | }; | 184 | }; |
185 | MODULE_DEVICE_TABLE(pci, vmw_pci_id_list); | ||
185 | 186 | ||
186 | static int enable_fbdev; | 187 | static int enable_fbdev = IS_ENABLED(CONFIG_DRM_VMWGFX_FBCON); |
187 | 188 | ||
188 | static int vmw_probe(struct pci_dev *, const struct pci_device_id *); | 189 | static int vmw_probe(struct pci_dev *, const struct pci_device_id *); |
189 | static void vmw_master_init(struct vmw_master *); | 190 | static void vmw_master_init(struct vmw_master *); |
@@ -1154,6 +1155,11 @@ static struct drm_driver driver = { | |||
1154 | .open = vmw_driver_open, | 1155 | .open = vmw_driver_open, |
1155 | .preclose = vmw_preclose, | 1156 | .preclose = vmw_preclose, |
1156 | .postclose = vmw_postclose, | 1157 | .postclose = vmw_postclose, |
1158 | |||
1159 | .dumb_create = vmw_dumb_create, | ||
1160 | .dumb_map_offset = vmw_dumb_map_offset, | ||
1161 | .dumb_destroy = vmw_dumb_destroy, | ||
1162 | |||
1157 | .fops = &vmwgfx_driver_fops, | 1163 | .fops = &vmwgfx_driver_fops, |
1158 | .name = VMWGFX_DRIVER_NAME, | 1164 | .name = VMWGFX_DRIVER_NAME, |
1159 | .desc = VMWGFX_DRIVER_DESC, | 1165 | .desc = VMWGFX_DRIVER_DESC, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index d0f2c079ee27..29c984ff7f23 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -645,6 +645,16 @@ int vmw_kms_readback(struct vmw_private *dev_priv, | |||
645 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | 645 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, |
646 | struct drm_file *file_priv); | 646 | struct drm_file *file_priv); |
647 | 647 | ||
648 | int vmw_dumb_create(struct drm_file *file_priv, | ||
649 | struct drm_device *dev, | ||
650 | struct drm_mode_create_dumb *args); | ||
651 | |||
652 | int vmw_dumb_map_offset(struct drm_file *file_priv, | ||
653 | struct drm_device *dev, uint32_t handle, | ||
654 | uint64_t *offset); | ||
655 | int vmw_dumb_destroy(struct drm_file *file_priv, | ||
656 | struct drm_device *dev, | ||
657 | uint32_t handle); | ||
648 | /** | 658 | /** |
649 | * Overlay control - vmwgfx_overlay.c | 659 | * Overlay control - vmwgfx_overlay.c |
650 | */ | 660 | */ |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 22bf9a21ec71..2c6ffe0e2c07 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
@@ -1917,3 +1917,76 @@ err_ref: | |||
1917 | vmw_resource_unreference(&res); | 1917 | vmw_resource_unreference(&res); |
1918 | return ret; | 1918 | return ret; |
1919 | } | 1919 | } |
1920 | |||
1921 | |||
1922 | int vmw_dumb_create(struct drm_file *file_priv, | ||
1923 | struct drm_device *dev, | ||
1924 | struct drm_mode_create_dumb *args) | ||
1925 | { | ||
1926 | struct vmw_private *dev_priv = vmw_priv(dev); | ||
1927 | struct vmw_master *vmaster = vmw_master(file_priv->master); | ||
1928 | struct vmw_user_dma_buffer *vmw_user_bo; | ||
1929 | struct ttm_buffer_object *tmp; | ||
1930 | int ret; | ||
1931 | |||
1932 | args->pitch = args->width * ((args->bpp + 7) / 8); | ||
1933 | args->size = args->pitch * args->height; | ||
1934 | |||
1935 | vmw_user_bo = kzalloc(sizeof(*vmw_user_bo), GFP_KERNEL); | ||
1936 | if (vmw_user_bo == NULL) | ||
1937 | return -ENOMEM; | ||
1938 | |||
1939 | ret = ttm_read_lock(&vmaster->lock, true); | ||
1940 | if (ret != 0) { | ||
1941 | kfree(vmw_user_bo); | ||
1942 | return ret; | ||
1943 | } | ||
1944 | |||
1945 | ret = vmw_dmabuf_init(dev_priv, &vmw_user_bo->dma, args->size, | ||
1946 | &vmw_vram_sys_placement, true, | ||
1947 | &vmw_user_dmabuf_destroy); | ||
1948 | if (ret != 0) | ||
1949 | goto out_no_dmabuf; | ||
1950 | |||
1951 | tmp = ttm_bo_reference(&vmw_user_bo->dma.base); | ||
1952 | ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile, | ||
1953 | &vmw_user_bo->base, | ||
1954 | false, | ||
1955 | ttm_buffer_type, | ||
1956 | &vmw_user_dmabuf_release, NULL); | ||
1957 | if (unlikely(ret != 0)) | ||
1958 | goto out_no_base_object; | ||
1959 | |||
1960 | args->handle = vmw_user_bo->base.hash.key; | ||
1961 | |||
1962 | out_no_base_object: | ||
1963 | ttm_bo_unref(&tmp); | ||
1964 | out_no_dmabuf: | ||
1965 | ttm_read_unlock(&vmaster->lock); | ||
1966 | return ret; | ||
1967 | } | ||
1968 | |||
1969 | int vmw_dumb_map_offset(struct drm_file *file_priv, | ||
1970 | struct drm_device *dev, uint32_t handle, | ||
1971 | uint64_t *offset) | ||
1972 | { | ||
1973 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; | ||
1974 | struct vmw_dma_buffer *out_buf; | ||
1975 | int ret; | ||
1976 | |||
1977 | ret = vmw_user_dmabuf_lookup(tfile, handle, &out_buf); | ||
1978 | if (ret != 0) | ||
1979 | return -EINVAL; | ||
1980 | |||
1981 | *offset = out_buf->base.addr_space_offset; | ||
1982 | vmw_dmabuf_unreference(&out_buf); | ||
1983 | return 0; | ||
1984 | } | ||
1985 | |||
1986 | int vmw_dumb_destroy(struct drm_file *file_priv, | ||
1987 | struct drm_device *dev, | ||
1988 | uint32_t handle) | ||
1989 | { | ||
1990 | return ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile, | ||
1991 | handle, TTM_REF_USAGE); | ||
1992 | } | ||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 8bf8a64e5115..8bcd168fffae 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -996,7 +996,8 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field, | |||
996 | struct hid_driver *hdrv = hid->driver; | 996 | struct hid_driver *hdrv = hid->driver; |
997 | int ret; | 997 | int ret; |
998 | 998 | ||
999 | hid_dump_input(hid, usage, value); | 999 | if (!list_empty(&hid->debug_list)) |
1000 | hid_dump_input(hid, usage, value); | ||
1000 | 1001 | ||
1001 | if (hdrv && hdrv->event && hid_match_usage(hid, usage)) { | 1002 | if (hdrv && hdrv->event && hid_match_usage(hid, usage)) { |
1002 | ret = hdrv->event(hid, field, usage, value); | 1003 | ret = hdrv->event(hid, field, usage, value); |
@@ -1558,7 +1559,9 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1558 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, | 1559 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, |
1559 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, | 1560 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, |
1560 | { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, | 1561 | { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, |
1561 | { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) }, | 1562 | #if IS_ENABLED(CONFIG_HID_LENOVO_TPKBD) |
1563 | { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) }, | ||
1564 | #endif | ||
1562 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, | 1565 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, |
1563 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, | 1566 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, |
1564 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, | 1567 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, |
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 0f9c146fc00d..4d524b5f52f5 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c | |||
@@ -439,7 +439,7 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) | |||
439 | struct dj_report *dj_report; | 439 | struct dj_report *dj_report; |
440 | int retval; | 440 | int retval; |
441 | 441 | ||
442 | dj_report = kzalloc(sizeof(dj_report), GFP_KERNEL); | 442 | dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL); |
443 | if (!dj_report) | 443 | if (!dj_report) |
444 | return -ENOMEM; | 444 | return -ENOMEM; |
445 | dj_report->report_id = REPORT_ID_DJ_SHORT; | 445 | dj_report->report_id = REPORT_ID_DJ_SHORT; |
@@ -456,7 +456,7 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, | |||
456 | struct dj_report *dj_report; | 456 | struct dj_report *dj_report; |
457 | int retval; | 457 | int retval; |
458 | 458 | ||
459 | dj_report = kzalloc(sizeof(dj_report), GFP_KERNEL); | 459 | dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL); |
460 | if (!dj_report) | 460 | if (!dj_report) |
461 | return -ENOMEM; | 461 | return -ENOMEM; |
462 | dj_report->report_id = REPORT_ID_DJ_SHORT; | 462 | dj_report->report_id = REPORT_ID_DJ_SHORT; |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 903eef3d3e10..991e85c7325c 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -70,6 +70,7 @@ static const struct hid_blacklist { | |||
70 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, | 70 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, |
71 | { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, | 71 | { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, |
72 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, | 72 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, |
73 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, | ||
73 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, | 74 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, |
74 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, | 75 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, |
75 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS }, | 76 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS }, |
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index 7f3f4a385729..602148299f68 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c | |||
@@ -69,22 +69,6 @@ struct ina2xx_data { | |||
69 | u16 regs[INA2XX_MAX_REGISTERS]; | 69 | u16 regs[INA2XX_MAX_REGISTERS]; |
70 | }; | 70 | }; |
71 | 71 | ||
72 | int ina2xx_read_word(struct i2c_client *client, int reg) | ||
73 | { | ||
74 | int val = i2c_smbus_read_word_data(client, reg); | ||
75 | if (unlikely(val < 0)) { | ||
76 | dev_dbg(&client->dev, | ||
77 | "Failed to read register: %d\n", reg); | ||
78 | return val; | ||
79 | } | ||
80 | return be16_to_cpu(val); | ||
81 | } | ||
82 | |||
83 | void ina2xx_write_word(struct i2c_client *client, int reg, int data) | ||
84 | { | ||
85 | i2c_smbus_write_word_data(client, reg, cpu_to_be16(data)); | ||
86 | } | ||
87 | |||
88 | static struct ina2xx_data *ina2xx_update_device(struct device *dev) | 72 | static struct ina2xx_data *ina2xx_update_device(struct device *dev) |
89 | { | 73 | { |
90 | struct i2c_client *client = to_i2c_client(dev); | 74 | struct i2c_client *client = to_i2c_client(dev); |
@@ -102,7 +86,7 @@ static struct ina2xx_data *ina2xx_update_device(struct device *dev) | |||
102 | 86 | ||
103 | /* Read all registers */ | 87 | /* Read all registers */ |
104 | for (i = 0; i < data->registers; i++) { | 88 | for (i = 0; i < data->registers; i++) { |
105 | int rv = ina2xx_read_word(client, i); | 89 | int rv = i2c_smbus_read_word_swapped(client, i); |
106 | if (rv < 0) { | 90 | if (rv < 0) { |
107 | ret = ERR_PTR(rv); | 91 | ret = ERR_PTR(rv); |
108 | goto abort; | 92 | goto abort; |
@@ -279,22 +263,26 @@ static int ina2xx_probe(struct i2c_client *client, | |||
279 | switch (data->kind) { | 263 | switch (data->kind) { |
280 | case ina219: | 264 | case ina219: |
281 | /* device configuration */ | 265 | /* device configuration */ |
282 | ina2xx_write_word(client, INA2XX_CONFIG, INA219_CONFIG_DEFAULT); | 266 | i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, |
267 | INA219_CONFIG_DEFAULT); | ||
283 | 268 | ||
284 | /* set current LSB to 1mA, shunt is in uOhms */ | 269 | /* set current LSB to 1mA, shunt is in uOhms */ |
285 | /* (equation 13 in datasheet) */ | 270 | /* (equation 13 in datasheet) */ |
286 | ina2xx_write_word(client, INA2XX_CALIBRATION, 40960000 / shunt); | 271 | i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, |
272 | 40960000 / shunt); | ||
287 | dev_info(&client->dev, | 273 | dev_info(&client->dev, |
288 | "power monitor INA219 (Rshunt = %li uOhm)\n", shunt); | 274 | "power monitor INA219 (Rshunt = %li uOhm)\n", shunt); |
289 | data->registers = INA219_REGISTERS; | 275 | data->registers = INA219_REGISTERS; |
290 | break; | 276 | break; |
291 | case ina226: | 277 | case ina226: |
292 | /* device configuration */ | 278 | /* device configuration */ |
293 | ina2xx_write_word(client, INA2XX_CONFIG, INA226_CONFIG_DEFAULT); | 279 | i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, |
280 | INA226_CONFIG_DEFAULT); | ||
294 | 281 | ||
295 | /* set current LSB to 1mA, shunt is in uOhms */ | 282 | /* set current LSB to 1mA, shunt is in uOhms */ |
296 | /* (equation 1 in datasheet)*/ | 283 | /* (equation 1 in datasheet)*/ |
297 | ina2xx_write_word(client, INA2XX_CALIBRATION, 5120000 / shunt); | 284 | i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, |
285 | 5120000 / shunt); | ||
298 | dev_info(&client->dev, | 286 | dev_info(&client->dev, |
299 | "power monitor INA226 (Rshunt = %li uOhm)\n", shunt); | 287 | "power monitor INA226 (Rshunt = %li uOhm)\n", shunt); |
300 | data->registers = INA226_REGISTERS; | 288 | data->registers = INA226_REGISTERS; |
diff --git a/drivers/hwmon/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c index 0018c7dd0097..1a174f0a3cde 100644 --- a/drivers/hwmon/twl4030-madc-hwmon.c +++ b/drivers/hwmon/twl4030-madc-hwmon.c | |||
@@ -44,12 +44,13 @@ static ssize_t madc_read(struct device *dev, | |||
44 | struct device_attribute *devattr, char *buf) | 44 | struct device_attribute *devattr, char *buf) |
45 | { | 45 | { |
46 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 46 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
47 | struct twl4030_madc_request req; | 47 | struct twl4030_madc_request req = { |
48 | .channels = 1 << attr->index, | ||
49 | .method = TWL4030_MADC_SW2, | ||
50 | .type = TWL4030_MADC_WAIT, | ||
51 | }; | ||
48 | long val; | 52 | long val; |
49 | 53 | ||
50 | req.channels = (1 << attr->index); | ||
51 | req.method = TWL4030_MADC_SW2; | ||
52 | req.func_cb = NULL; | ||
53 | val = twl4030_madc_conversion(&req); | 54 | val = twl4030_madc_conversion(&req); |
54 | if (val < 0) | 55 | if (val < 0) |
55 | return val; | 56 | return val; |
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index 73133b1063f0..6f5f98d69af7 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c | |||
@@ -476,17 +476,17 @@ static int pca_init(struct i2c_adapter *adap) | |||
476 | /* To avoid integer overflow, use clock/100 for calculations */ | 476 | /* To avoid integer overflow, use clock/100 for calculations */ |
477 | clock = pca_clock(pca_data) / 100; | 477 | clock = pca_clock(pca_data) / 100; |
478 | 478 | ||
479 | if (pca_data->i2c_clock > 10000) { | 479 | if (pca_data->i2c_clock > 1000000) { |
480 | mode = I2C_PCA_MODE_TURBO; | 480 | mode = I2C_PCA_MODE_TURBO; |
481 | min_tlow = 14; | 481 | min_tlow = 14; |
482 | min_thi = 5; | 482 | min_thi = 5; |
483 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ | 483 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ |
484 | } else if (pca_data->i2c_clock > 4000) { | 484 | } else if (pca_data->i2c_clock > 400000) { |
485 | mode = I2C_PCA_MODE_FASTP; | 485 | mode = I2C_PCA_MODE_FASTP; |
486 | min_tlow = 17; | 486 | min_tlow = 17; |
487 | min_thi = 9; | 487 | min_thi = 9; |
488 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ | 488 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ |
489 | } else if (pca_data->i2c_clock > 1000) { | 489 | } else if (pca_data->i2c_clock > 100000) { |
490 | mode = I2C_PCA_MODE_FAST; | 490 | mode = I2C_PCA_MODE_FAST; |
491 | min_tlow = 44; | 491 | min_tlow = 44; |
492 | min_thi = 20; | 492 | min_thi = 20; |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index b4aaa1bd6728..970a1612e795 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -104,6 +104,7 @@ config I2C_I801 | |||
104 | DH89xxCC (PCH) | 104 | DH89xxCC (PCH) |
105 | Panther Point (PCH) | 105 | Panther Point (PCH) |
106 | Lynx Point (PCH) | 106 | Lynx Point (PCH) |
107 | Lynx Point-LP (PCH) | ||
107 | 108 | ||
108 | This driver can also be built as a module. If so, the module | 109 | This driver can also be built as a module. If so, the module |
109 | will be called i2c-i801. | 110 | will be called i2c-i801. |
@@ -354,9 +355,13 @@ config I2C_DAVINCI | |||
354 | devices such as DaVinci NIC. | 355 | devices such as DaVinci NIC. |
355 | For details please see http://www.ti.com/davinci | 356 | For details please see http://www.ti.com/davinci |
356 | 357 | ||
358 | config I2C_DESIGNWARE_CORE | ||
359 | tristate | ||
360 | |||
357 | config I2C_DESIGNWARE_PLATFORM | 361 | config I2C_DESIGNWARE_PLATFORM |
358 | tristate "Synopsys DesignWare Platform" | 362 | tristate "Synopsys DesignWare Platform" |
359 | depends on HAVE_CLK | 363 | depends on HAVE_CLK |
364 | select I2C_DESIGNWARE_CORE | ||
360 | help | 365 | help |
361 | If you say yes to this option, support will be included for the | 366 | If you say yes to this option, support will be included for the |
362 | Synopsys DesignWare I2C adapter. Only master mode is supported. | 367 | Synopsys DesignWare I2C adapter. Only master mode is supported. |
@@ -367,6 +372,7 @@ config I2C_DESIGNWARE_PLATFORM | |||
367 | config I2C_DESIGNWARE_PCI | 372 | config I2C_DESIGNWARE_PCI |
368 | tristate "Synopsys DesignWare PCI" | 373 | tristate "Synopsys DesignWare PCI" |
369 | depends on PCI | 374 | depends on PCI |
375 | select I2C_DESIGNWARE_CORE | ||
370 | help | 376 | help |
371 | If you say yes to this option, support will be included for the | 377 | If you say yes to this option, support will be included for the |
372 | Synopsys DesignWare I2C adapter. Only master mode is supported. | 378 | Synopsys DesignWare I2C adapter. Only master mode is supported. |
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index ce3c2be7fb40..37c4182cc98b 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile | |||
@@ -33,10 +33,11 @@ obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o | |||
33 | obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o | 33 | obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o |
34 | obj-$(CONFIG_I2C_CPM) += i2c-cpm.o | 34 | obj-$(CONFIG_I2C_CPM) += i2c-cpm.o |
35 | obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o | 35 | obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o |
36 | obj-$(CONFIG_I2C_DESIGNWARE_CORE) += i2c-designware-core.o | ||
36 | obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o | 37 | obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o |
37 | i2c-designware-platform-objs := i2c-designware-platdrv.o i2c-designware-core.o | 38 | i2c-designware-platform-objs := i2c-designware-platdrv.o |
38 | obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o | 39 | obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o |
39 | i2c-designware-pci-objs := i2c-designware-pcidrv.o i2c-designware-core.o | 40 | i2c-designware-pci-objs := i2c-designware-pcidrv.o |
40 | obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o | 41 | obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o |
41 | obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o | 42 | obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o |
42 | obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o | 43 | obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o |
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 1e48bec80edf..7b8ebbefb581 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c | |||
@@ -25,6 +25,7 @@ | |||
25 | * ---------------------------------------------------------------------------- | 25 | * ---------------------------------------------------------------------------- |
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | #include <linux/export.h> | ||
28 | #include <linux/clk.h> | 29 | #include <linux/clk.h> |
29 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
30 | #include <linux/err.h> | 31 | #include <linux/err.h> |
@@ -316,6 +317,7 @@ int i2c_dw_init(struct dw_i2c_dev *dev) | |||
316 | dw_writel(dev, dev->master_cfg , DW_IC_CON); | 317 | dw_writel(dev, dev->master_cfg , DW_IC_CON); |
317 | return 0; | 318 | return 0; |
318 | } | 319 | } |
320 | EXPORT_SYMBOL_GPL(i2c_dw_init); | ||
319 | 321 | ||
320 | /* | 322 | /* |
321 | * Waiting for bus not busy | 323 | * Waiting for bus not busy |
@@ -568,12 +570,14 @@ done: | |||
568 | 570 | ||
569 | return ret; | 571 | return ret; |
570 | } | 572 | } |
573 | EXPORT_SYMBOL_GPL(i2c_dw_xfer); | ||
571 | 574 | ||
572 | u32 i2c_dw_func(struct i2c_adapter *adap) | 575 | u32 i2c_dw_func(struct i2c_adapter *adap) |
573 | { | 576 | { |
574 | struct dw_i2c_dev *dev = i2c_get_adapdata(adap); | 577 | struct dw_i2c_dev *dev = i2c_get_adapdata(adap); |
575 | return dev->functionality; | 578 | return dev->functionality; |
576 | } | 579 | } |
580 | EXPORT_SYMBOL_GPL(i2c_dw_func); | ||
577 | 581 | ||
578 | static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) | 582 | static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) |
579 | { | 583 | { |
@@ -678,17 +682,20 @@ tx_aborted: | |||
678 | 682 | ||
679 | return IRQ_HANDLED; | 683 | return IRQ_HANDLED; |
680 | } | 684 | } |
685 | EXPORT_SYMBOL_GPL(i2c_dw_isr); | ||
681 | 686 | ||
682 | void i2c_dw_enable(struct dw_i2c_dev *dev) | 687 | void i2c_dw_enable(struct dw_i2c_dev *dev) |
683 | { | 688 | { |
684 | /* Enable the adapter */ | 689 | /* Enable the adapter */ |
685 | dw_writel(dev, 1, DW_IC_ENABLE); | 690 | dw_writel(dev, 1, DW_IC_ENABLE); |
686 | } | 691 | } |
692 | EXPORT_SYMBOL_GPL(i2c_dw_enable); | ||
687 | 693 | ||
688 | u32 i2c_dw_is_enabled(struct dw_i2c_dev *dev) | 694 | u32 i2c_dw_is_enabled(struct dw_i2c_dev *dev) |
689 | { | 695 | { |
690 | return dw_readl(dev, DW_IC_ENABLE); | 696 | return dw_readl(dev, DW_IC_ENABLE); |
691 | } | 697 | } |
698 | EXPORT_SYMBOL_GPL(i2c_dw_is_enabled); | ||
692 | 699 | ||
693 | void i2c_dw_disable(struct dw_i2c_dev *dev) | 700 | void i2c_dw_disable(struct dw_i2c_dev *dev) |
694 | { | 701 | { |
@@ -699,18 +706,22 @@ void i2c_dw_disable(struct dw_i2c_dev *dev) | |||
699 | dw_writel(dev, 0, DW_IC_INTR_MASK); | 706 | dw_writel(dev, 0, DW_IC_INTR_MASK); |
700 | dw_readl(dev, DW_IC_CLR_INTR); | 707 | dw_readl(dev, DW_IC_CLR_INTR); |
701 | } | 708 | } |
709 | EXPORT_SYMBOL_GPL(i2c_dw_disable); | ||
702 | 710 | ||
703 | void i2c_dw_clear_int(struct dw_i2c_dev *dev) | 711 | void i2c_dw_clear_int(struct dw_i2c_dev *dev) |
704 | { | 712 | { |
705 | dw_readl(dev, DW_IC_CLR_INTR); | 713 | dw_readl(dev, DW_IC_CLR_INTR); |
706 | } | 714 | } |
715 | EXPORT_SYMBOL_GPL(i2c_dw_clear_int); | ||
707 | 716 | ||
708 | void i2c_dw_disable_int(struct dw_i2c_dev *dev) | 717 | void i2c_dw_disable_int(struct dw_i2c_dev *dev) |
709 | { | 718 | { |
710 | dw_writel(dev, 0, DW_IC_INTR_MASK); | 719 | dw_writel(dev, 0, DW_IC_INTR_MASK); |
711 | } | 720 | } |
721 | EXPORT_SYMBOL_GPL(i2c_dw_disable_int); | ||
712 | 722 | ||
713 | u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev) | 723 | u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev) |
714 | { | 724 | { |
715 | return dw_readl(dev, DW_IC_COMP_PARAM_1); | 725 | return dw_readl(dev, DW_IC_COMP_PARAM_1); |
716 | } | 726 | } |
727 | EXPORT_SYMBOL_GPL(i2c_dw_read_comp_param); | ||
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 898dcf9c7ade..33e9b0c09af2 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -52,6 +52,7 @@ | |||
52 | DH89xxCC (PCH) 0x2330 32 hard yes yes yes | 52 | DH89xxCC (PCH) 0x2330 32 hard yes yes yes |
53 | Panther Point (PCH) 0x1e22 32 hard yes yes yes | 53 | Panther Point (PCH) 0x1e22 32 hard yes yes yes |
54 | Lynx Point (PCH) 0x8c22 32 hard yes yes yes | 54 | Lynx Point (PCH) 0x8c22 32 hard yes yes yes |
55 | Lynx Point-LP (PCH) 0x9c22 32 hard yes yes yes | ||
55 | 56 | ||
56 | Features supported by this driver: | 57 | Features supported by this driver: |
57 | Software PEC no | 58 | Software PEC no |
@@ -155,6 +156,7 @@ | |||
155 | #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 | 156 | #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 |
156 | #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 | 157 | #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 |
157 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 | 158 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 |
159 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22 | ||
158 | 160 | ||
159 | struct i801_priv { | 161 | struct i801_priv { |
160 | struct i2c_adapter adapter; | 162 | struct i2c_adapter adapter; |
@@ -771,6 +773,7 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids) = { | |||
771 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) }, | 773 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) }, |
772 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) }, | 774 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) }, |
773 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) }, | 775 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) }, |
776 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS) }, | ||
774 | { 0, } | 777 | { 0, } |
775 | }; | 778 | }; |
776 | 779 | ||
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 088c5c1ed17d..51f05b8520ed 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c | |||
@@ -365,10 +365,6 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c) | |||
365 | struct device_node *node = dev->of_node; | 365 | struct device_node *node = dev->of_node; |
366 | int ret; | 366 | int ret; |
367 | 367 | ||
368 | if (!node) | ||
369 | return -EINVAL; | ||
370 | |||
371 | i2c->speed = &mxs_i2c_95kHz_config; | ||
372 | ret = of_property_read_u32(node, "clock-frequency", &speed); | 368 | ret = of_property_read_u32(node, "clock-frequency", &speed); |
373 | if (ret) | 369 | if (ret) |
374 | dev_warn(dev, "No I2C speed selected, using 100kHz\n"); | 370 | dev_warn(dev, "No I2C speed selected, using 100kHz\n"); |
@@ -419,10 +415,13 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev) | |||
419 | return err; | 415 | return err; |
420 | 416 | ||
421 | i2c->dev = dev; | 417 | i2c->dev = dev; |
418 | i2c->speed = &mxs_i2c_95kHz_config; | ||
422 | 419 | ||
423 | err = mxs_i2c_get_ofdata(i2c); | 420 | if (dev->of_node) { |
424 | if (err) | 421 | err = mxs_i2c_get_ofdata(i2c); |
425 | return err; | 422 | if (err) |
423 | return err; | ||
424 | } | ||
426 | 425 | ||
427 | platform_set_drvdata(pdev, i2c); | 426 | platform_set_drvdata(pdev, i2c); |
428 | 427 | ||
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 5d54416770b0..8488bddfe465 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c | |||
@@ -48,8 +48,9 @@ enum { | |||
48 | mcntrl_afie = 0x00000002, | 48 | mcntrl_afie = 0x00000002, |
49 | mcntrl_naie = 0x00000004, | 49 | mcntrl_naie = 0x00000004, |
50 | mcntrl_drmie = 0x00000008, | 50 | mcntrl_drmie = 0x00000008, |
51 | mcntrl_daie = 0x00000020, | 51 | mcntrl_drsie = 0x00000010, |
52 | mcntrl_rffie = 0x00000040, | 52 | mcntrl_rffie = 0x00000020, |
53 | mcntrl_daie = 0x00000040, | ||
53 | mcntrl_tffie = 0x00000080, | 54 | mcntrl_tffie = 0x00000080, |
54 | mcntrl_reset = 0x00000100, | 55 | mcntrl_reset = 0x00000100, |
55 | mcntrl_cdbmode = 0x00000400, | 56 | mcntrl_cdbmode = 0x00000400, |
@@ -290,31 +291,37 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data) | |||
290 | * or we didn't 'ask' for it yet. | 291 | * or we didn't 'ask' for it yet. |
291 | */ | 292 | */ |
292 | if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { | 293 | if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { |
293 | dev_dbg(&alg_data->adapter.dev, | 294 | /* 'Asking' is done asynchronously, e.g. dummy TX of several |
294 | "%s(): Write dummy data to fill Rx-fifo...\n", | 295 | * bytes is done before the first actual RX arrives in FIFO. |
295 | __func__); | 296 | * Therefore, ordered bytes (via TX) are counted separately. |
297 | */ | ||
298 | if (alg_data->mif.order) { | ||
299 | dev_dbg(&alg_data->adapter.dev, | ||
300 | "%s(): Write dummy data to fill Rx-fifo...\n", | ||
301 | __func__); | ||
296 | 302 | ||
297 | if (alg_data->mif.len == 1) { | 303 | if (alg_data->mif.order == 1) { |
298 | /* Last byte, do not acknowledge next rcv. */ | 304 | /* Last byte, do not acknowledge next rcv. */ |
299 | val |= stop_bit; | 305 | val |= stop_bit; |
306 | |||
307 | /* | ||
308 | * Enable interrupt RFDAIE (data in Rx fifo), | ||
309 | * and disable DRMIE (need data for Tx) | ||
310 | */ | ||
311 | ctl = ioread32(I2C_REG_CTL(alg_data)); | ||
312 | ctl |= mcntrl_rffie | mcntrl_daie; | ||
313 | ctl &= ~mcntrl_drmie; | ||
314 | iowrite32(ctl, I2C_REG_CTL(alg_data)); | ||
315 | } | ||
300 | 316 | ||
301 | /* | 317 | /* |
302 | * Enable interrupt RFDAIE (data in Rx fifo), | 318 | * Now we'll 'ask' for data: |
303 | * and disable DRMIE (need data for Tx) | 319 | * For each byte we want to receive, we must |
320 | * write a (dummy) byte to the Tx-FIFO. | ||
304 | */ | 321 | */ |
305 | ctl = ioread32(I2C_REG_CTL(alg_data)); | 322 | iowrite32(val, I2C_REG_TX(alg_data)); |
306 | ctl |= mcntrl_rffie | mcntrl_daie; | 323 | alg_data->mif.order--; |
307 | ctl &= ~mcntrl_drmie; | ||
308 | iowrite32(ctl, I2C_REG_CTL(alg_data)); | ||
309 | } | 324 | } |
310 | |||
311 | /* | ||
312 | * Now we'll 'ask' for data: | ||
313 | * For each byte we want to receive, we must | ||
314 | * write a (dummy) byte to the Tx-FIFO. | ||
315 | */ | ||
316 | iowrite32(val, I2C_REG_TX(alg_data)); | ||
317 | |||
318 | return 0; | 325 | return 0; |
319 | } | 326 | } |
320 | 327 | ||
@@ -514,6 +521,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
514 | 521 | ||
515 | alg_data->mif.buf = pmsg->buf; | 522 | alg_data->mif.buf = pmsg->buf; |
516 | alg_data->mif.len = pmsg->len; | 523 | alg_data->mif.len = pmsg->len; |
524 | alg_data->mif.order = pmsg->len; | ||
517 | alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ? | 525 | alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ? |
518 | I2C_SMBUS_READ : I2C_SMBUS_WRITE; | 526 | I2C_SMBUS_READ : I2C_SMBUS_WRITE; |
519 | alg_data->mif.ret = 0; | 527 | alg_data->mif.ret = 0; |
@@ -566,6 +574,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
566 | /* Cleanup to be sure... */ | 574 | /* Cleanup to be sure... */ |
567 | alg_data->mif.buf = NULL; | 575 | alg_data->mif.buf = NULL; |
568 | alg_data->mif.len = 0; | 576 | alg_data->mif.len = 0; |
577 | alg_data->mif.order = 0; | ||
569 | 578 | ||
570 | dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n", | 579 | dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n", |
571 | __func__, ioread32(I2C_REG_STS(alg_data))); | 580 | __func__, ioread32(I2C_REG_STS(alg_data))); |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 2efa56c5ff2c..2091ae8f539a 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -637,6 +637,22 @@ static void i2c_adapter_dev_release(struct device *dev) | |||
637 | } | 637 | } |
638 | 638 | ||
639 | /* | 639 | /* |
640 | * This function is only needed for mutex_lock_nested, so it is never | ||
641 | * called unless locking correctness checking is enabled. Thus we | ||
642 | * make it inline to avoid a compiler warning. That's what gcc ends up | ||
643 | * doing anyway. | ||
644 | */ | ||
645 | static inline unsigned int i2c_adapter_depth(struct i2c_adapter *adapter) | ||
646 | { | ||
647 | unsigned int depth = 0; | ||
648 | |||
649 | while ((adapter = i2c_parent_is_i2c_adapter(adapter))) | ||
650 | depth++; | ||
651 | |||
652 | return depth; | ||
653 | } | ||
654 | |||
655 | /* | ||
640 | * Let users instantiate I2C devices through sysfs. This can be used when | 656 | * Let users instantiate I2C devices through sysfs. This can be used when |
641 | * platform initialization code doesn't contain the proper data for | 657 | * platform initialization code doesn't contain the proper data for |
642 | * whatever reason. Also useful for drivers that do device detection and | 658 | * whatever reason. Also useful for drivers that do device detection and |
@@ -726,7 +742,8 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr, | |||
726 | 742 | ||
727 | /* Make sure the device was added through sysfs */ | 743 | /* Make sure the device was added through sysfs */ |
728 | res = -ENOENT; | 744 | res = -ENOENT; |
729 | mutex_lock(&adap->userspace_clients_lock); | 745 | mutex_lock_nested(&adap->userspace_clients_lock, |
746 | i2c_adapter_depth(adap)); | ||
730 | list_for_each_entry_safe(client, next, &adap->userspace_clients, | 747 | list_for_each_entry_safe(client, next, &adap->userspace_clients, |
731 | detected) { | 748 | detected) { |
732 | if (client->addr == addr) { | 749 | if (client->addr == addr) { |
@@ -1073,7 +1090,8 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
1073 | return res; | 1090 | return res; |
1074 | 1091 | ||
1075 | /* Remove devices instantiated from sysfs */ | 1092 | /* Remove devices instantiated from sysfs */ |
1076 | mutex_lock(&adap->userspace_clients_lock); | 1093 | mutex_lock_nested(&adap->userspace_clients_lock, |
1094 | i2c_adapter_depth(adap)); | ||
1077 | list_for_each_entry_safe(client, next, &adap->userspace_clients, | 1095 | list_for_each_entry_safe(client, next, &adap->userspace_clients, |
1078 | detected) { | 1096 | detected) { |
1079 | dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name, | 1097 | dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name, |
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index f61780a02374..3bd5540238a7 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c | |||
@@ -617,7 +617,7 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) | |||
617 | st->adc_clk = clk_get(&pdev->dev, "adc_op_clk"); | 617 | st->adc_clk = clk_get(&pdev->dev, "adc_op_clk"); |
618 | if (IS_ERR(st->adc_clk)) { | 618 | if (IS_ERR(st->adc_clk)) { |
619 | dev_err(&pdev->dev, "Failed to get the ADC clock.\n"); | 619 | dev_err(&pdev->dev, "Failed to get the ADC clock.\n"); |
620 | ret = PTR_ERR(st->clk); | 620 | ret = PTR_ERR(st->adc_clk); |
621 | goto error_disable_clk; | 621 | goto error_disable_clk; |
622 | } | 622 | } |
623 | 623 | ||
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index ff4c0a87a25f..ce68e361558c 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c | |||
@@ -358,6 +358,7 @@ static void imx_keypad_inhibit(struct imx_keypad *keypad) | |||
358 | /* Inhibit KDI and KRI interrupts. */ | 358 | /* Inhibit KDI and KRI interrupts. */ |
359 | reg_val = readw(keypad->mmio_base + KPSR); | 359 | reg_val = readw(keypad->mmio_base + KPSR); |
360 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); | 360 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); |
361 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD; | ||
361 | writew(reg_val, keypad->mmio_base + KPSR); | 362 | writew(reg_val, keypad->mmio_base + KPSR); |
362 | 363 | ||
363 | /* Colums as open drain and disable all rows */ | 364 | /* Colums as open drain and disable all rows */ |
@@ -515,7 +516,9 @@ static int __devinit imx_keypad_probe(struct platform_device *pdev) | |||
515 | input_set_drvdata(input_dev, keypad); | 516 | input_set_drvdata(input_dev, keypad); |
516 | 517 | ||
517 | /* Ensure that the keypad will stay dormant until opened */ | 518 | /* Ensure that the keypad will stay dormant until opened */ |
519 | clk_enable(keypad->clk); | ||
518 | imx_keypad_inhibit(keypad); | 520 | imx_keypad_inhibit(keypad); |
521 | clk_disable(keypad->clk); | ||
519 | 522 | ||
520 | error = request_irq(irq, imx_keypad_irq_handler, 0, | 523 | error = request_irq(irq, imx_keypad_irq_handler, 0, |
521 | pdev->name, keypad); | 524 | pdev->name, keypad); |
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c index fc0ed9b43424..2194a3c7236a 100644 --- a/drivers/input/misc/twl4030-vibra.c +++ b/drivers/input/misc/twl4030-vibra.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/jiffies.h> | 27 | #include <linux/jiffies.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/of.h> | ||
29 | #include <linux/workqueue.h> | 30 | #include <linux/workqueue.h> |
30 | #include <linux/i2c/twl.h> | 31 | #include <linux/i2c/twl.h> |
31 | #include <linux/mfd/twl4030-audio.h> | 32 | #include <linux/mfd/twl4030-audio.h> |
@@ -194,13 +195,26 @@ static int twl4030_vibra_resume(struct device *dev) | |||
194 | static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, | 195 | static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, |
195 | twl4030_vibra_suspend, twl4030_vibra_resume); | 196 | twl4030_vibra_suspend, twl4030_vibra_resume); |
196 | 197 | ||
198 | static bool twl4030_vibra_check_coexist(struct twl4030_vibra_data *pdata, | ||
199 | struct device_node *node) | ||
200 | { | ||
201 | if (pdata && pdata->coexist) | ||
202 | return true; | ||
203 | |||
204 | if (of_find_node_by_name(node, "codec")) | ||
205 | return true; | ||
206 | |||
207 | return false; | ||
208 | } | ||
209 | |||
197 | static int __devinit twl4030_vibra_probe(struct platform_device *pdev) | 210 | static int __devinit twl4030_vibra_probe(struct platform_device *pdev) |
198 | { | 211 | { |
199 | struct twl4030_vibra_data *pdata = pdev->dev.platform_data; | 212 | struct twl4030_vibra_data *pdata = pdev->dev.platform_data; |
213 | struct device_node *twl4030_core_node = pdev->dev.parent->of_node; | ||
200 | struct vibra_info *info; | 214 | struct vibra_info *info; |
201 | int ret; | 215 | int ret; |
202 | 216 | ||
203 | if (!pdata) { | 217 | if (!pdata && !twl4030_core_node) { |
204 | dev_dbg(&pdev->dev, "platform_data not available\n"); | 218 | dev_dbg(&pdev->dev, "platform_data not available\n"); |
205 | return -EINVAL; | 219 | return -EINVAL; |
206 | } | 220 | } |
@@ -210,7 +224,7 @@ static int __devinit twl4030_vibra_probe(struct platform_device *pdev) | |||
210 | return -ENOMEM; | 224 | return -ENOMEM; |
211 | 225 | ||
212 | info->dev = &pdev->dev; | 226 | info->dev = &pdev->dev; |
213 | info->coexist = pdata->coexist; | 227 | info->coexist = twl4030_vibra_check_coexist(pdata, twl4030_core_node); |
214 | INIT_WORK(&info->play_work, vibra_play_work); | 228 | INIT_WORK(&info->play_work, vibra_play_work); |
215 | 229 | ||
216 | info->input_dev = input_allocate_device(); | 230 | info->input_dev = input_allocate_device(); |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 5ec774d6c82b..6918773ce024 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -177,6 +177,20 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { | |||
177 | }, | 177 | }, |
178 | }, | 178 | }, |
179 | { | 179 | { |
180 | /* Gigabyte T1005 - defines wrong chassis type ("Other") */ | ||
181 | .matches = { | ||
182 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), | ||
183 | DMI_MATCH(DMI_PRODUCT_NAME, "T1005"), | ||
184 | }, | ||
185 | }, | ||
186 | { | ||
187 | /* Gigabyte T1005M/P - defines wrong chassis type ("Other") */ | ||
188 | .matches = { | ||
189 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), | ||
190 | DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"), | ||
191 | }, | ||
192 | }, | ||
193 | { | ||
180 | .matches = { | 194 | .matches = { |
181 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 195 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
182 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), | 196 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 002041975de9..532d067a9e07 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -1848,7 +1848,10 @@ static const struct wacom_features wacom_features_0x2A = | |||
1848 | { "Wacom Intuos5 M", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, | 1848 | { "Wacom Intuos5 M", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, |
1849 | 63, INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 1849 | 63, INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
1850 | static const struct wacom_features wacom_features_0xF4 = | 1850 | static const struct wacom_features wacom_features_0xF4 = |
1851 | { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, | 1851 | { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, |
1852 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1853 | static const struct wacom_features wacom_features_0xF8 = | ||
1854 | { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, | ||
1852 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 1855 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
1853 | static const struct wacom_features wacom_features_0x3F = | 1856 | static const struct wacom_features wacom_features_0x3F = |
1854 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, | 1857 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, |
@@ -2091,6 +2094,7 @@ const struct usb_device_id wacom_ids[] = { | |||
2091 | { USB_DEVICE_WACOM(0xEF) }, | 2094 | { USB_DEVICE_WACOM(0xEF) }, |
2092 | { USB_DEVICE_WACOM(0x47) }, | 2095 | { USB_DEVICE_WACOM(0x47) }, |
2093 | { USB_DEVICE_WACOM(0xF4) }, | 2096 | { USB_DEVICE_WACOM(0xF4) }, |
2097 | { USB_DEVICE_WACOM(0xF8) }, | ||
2094 | { USB_DEVICE_WACOM(0xFA) }, | 2098 | { USB_DEVICE_WACOM(0xFA) }, |
2095 | { USB_DEVICE_LENOVO(0x6004) }, | 2099 | { USB_DEVICE_LENOVO(0x6004) }, |
2096 | { } | 2100 | { } |
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 9afc777a40a7..b06a5e3a665e 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c | |||
@@ -602,6 +602,7 @@ edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata) | |||
602 | { | 602 | { |
603 | if (tsdata->debug_dir) | 603 | if (tsdata->debug_dir) |
604 | debugfs_remove_recursive(tsdata->debug_dir); | 604 | debugfs_remove_recursive(tsdata->debug_dir); |
605 | kfree(tsdata->raw_buffer); | ||
605 | } | 606 | } |
606 | 607 | ||
607 | #else | 608 | #else |
@@ -843,7 +844,6 @@ static int __devexit edt_ft5x06_ts_remove(struct i2c_client *client) | |||
843 | if (gpio_is_valid(pdata->reset_pin)) | 844 | if (gpio_is_valid(pdata->reset_pin)) |
844 | gpio_free(pdata->reset_pin); | 845 | gpio_free(pdata->reset_pin); |
845 | 846 | ||
846 | kfree(tsdata->raw_buffer); | ||
847 | kfree(tsdata); | 847 | kfree(tsdata); |
848 | 848 | ||
849 | return 0; | 849 | return 0; |
diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c index fa6ca4733725..dceaec821b0e 100644 --- a/drivers/isdn/hardware/mISDN/avmfritz.c +++ b/drivers/isdn/hardware/mISDN/avmfritz.c | |||
@@ -857,8 +857,9 @@ avm_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) | |||
857 | switch (cmd) { | 857 | switch (cmd) { |
858 | case CLOSE_CHANNEL: | 858 | case CLOSE_CHANNEL: |
859 | test_and_clear_bit(FLG_OPEN, &bch->Flags); | 859 | test_and_clear_bit(FLG_OPEN, &bch->Flags); |
860 | cancel_work_sync(&bch->workq); | ||
860 | spin_lock_irqsave(&fc->lock, flags); | 861 | spin_lock_irqsave(&fc->lock, flags); |
861 | mISDN_freebchannel(bch); | 862 | mISDN_clear_bchannel(bch); |
862 | modehdlc(bch, ISDN_P_NONE); | 863 | modehdlc(bch, ISDN_P_NONE); |
863 | spin_unlock_irqrestore(&fc->lock, flags); | 864 | spin_unlock_irqrestore(&fc->lock, flags); |
864 | ch->protocol = ISDN_P_NONE; | 865 | ch->protocol = ISDN_P_NONE; |
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index 5e402cf2e795..f02794203bb1 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c | |||
@@ -5059,6 +5059,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev, | |||
5059 | printk(KERN_INFO | 5059 | printk(KERN_INFO |
5060 | "HFC-E1 #%d has overlapping B-channels on fragment #%d\n", | 5060 | "HFC-E1 #%d has overlapping B-channels on fragment #%d\n", |
5061 | E1_cnt + 1, pt); | 5061 | E1_cnt + 1, pt); |
5062 | kfree(hc); | ||
5062 | return -EINVAL; | 5063 | return -EINVAL; |
5063 | } | 5064 | } |
5064 | maskcheck |= hc->bmask[pt]; | 5065 | maskcheck |= hc->bmask[pt]; |
@@ -5086,6 +5087,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev, | |||
5086 | if ((poll >> 1) > sizeof(hc->silence_data)) { | 5087 | if ((poll >> 1) > sizeof(hc->silence_data)) { |
5087 | printk(KERN_ERR "HFCMULTI error: silence_data too small, " | 5088 | printk(KERN_ERR "HFCMULTI error: silence_data too small, " |
5088 | "please fix\n"); | 5089 | "please fix\n"); |
5090 | kfree(hc); | ||
5089 | return -EINVAL; | 5091 | return -EINVAL; |
5090 | } | 5092 | } |
5091 | for (i = 0; i < (poll >> 1); i++) | 5093 | for (i = 0; i < (poll >> 1); i++) |
diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c index 752e0825591f..ccd7d851be26 100644 --- a/drivers/isdn/hardware/mISDN/mISDNipac.c +++ b/drivers/isdn/hardware/mISDN/mISDNipac.c | |||
@@ -1406,8 +1406,9 @@ hscx_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) | |||
1406 | switch (cmd) { | 1406 | switch (cmd) { |
1407 | case CLOSE_CHANNEL: | 1407 | case CLOSE_CHANNEL: |
1408 | test_and_clear_bit(FLG_OPEN, &bch->Flags); | 1408 | test_and_clear_bit(FLG_OPEN, &bch->Flags); |
1409 | cancel_work_sync(&bch->workq); | ||
1409 | spin_lock_irqsave(hx->ip->hwlock, flags); | 1410 | spin_lock_irqsave(hx->ip->hwlock, flags); |
1410 | mISDN_freebchannel(bch); | 1411 | mISDN_clear_bchannel(bch); |
1411 | hscx_mode(hx, ISDN_P_NONE); | 1412 | hscx_mode(hx, ISDN_P_NONE); |
1412 | spin_unlock_irqrestore(hx->ip->hwlock, flags); | 1413 | spin_unlock_irqrestore(hx->ip->hwlock, flags); |
1413 | ch->protocol = ISDN_P_NONE; | 1414 | ch->protocol = ISDN_P_NONE; |
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c index be5973ded6d6..182ecf0626c2 100644 --- a/drivers/isdn/hardware/mISDN/mISDNisar.c +++ b/drivers/isdn/hardware/mISDN/mISDNisar.c | |||
@@ -1588,8 +1588,9 @@ isar_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) | |||
1588 | switch (cmd) { | 1588 | switch (cmd) { |
1589 | case CLOSE_CHANNEL: | 1589 | case CLOSE_CHANNEL: |
1590 | test_and_clear_bit(FLG_OPEN, &bch->Flags); | 1590 | test_and_clear_bit(FLG_OPEN, &bch->Flags); |
1591 | cancel_work_sync(&bch->workq); | ||
1591 | spin_lock_irqsave(ich->is->hwlock, flags); | 1592 | spin_lock_irqsave(ich->is->hwlock, flags); |
1592 | mISDN_freebchannel(bch); | 1593 | mISDN_clear_bchannel(bch); |
1593 | modeisar(ich, ISDN_P_NONE); | 1594 | modeisar(ich, ISDN_P_NONE); |
1594 | spin_unlock_irqrestore(ich->is->hwlock, flags); | 1595 | spin_unlock_irqrestore(ich->is->hwlock, flags); |
1595 | ch->protocol = ISDN_P_NONE; | 1596 | ch->protocol = ISDN_P_NONE; |
diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c index c3e3e7686273..9bcade59eb73 100644 --- a/drivers/isdn/hardware/mISDN/netjet.c +++ b/drivers/isdn/hardware/mISDN/netjet.c | |||
@@ -812,8 +812,9 @@ nj_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) | |||
812 | switch (cmd) { | 812 | switch (cmd) { |
813 | case CLOSE_CHANNEL: | 813 | case CLOSE_CHANNEL: |
814 | test_and_clear_bit(FLG_OPEN, &bch->Flags); | 814 | test_and_clear_bit(FLG_OPEN, &bch->Flags); |
815 | cancel_work_sync(&bch->workq); | ||
815 | spin_lock_irqsave(&card->lock, flags); | 816 | spin_lock_irqsave(&card->lock, flags); |
816 | mISDN_freebchannel(bch); | 817 | mISDN_clear_bchannel(bch); |
817 | mode_tiger(bc, ISDN_P_NONE); | 818 | mode_tiger(bc, ISDN_P_NONE); |
818 | spin_unlock_irqrestore(&card->lock, flags); | 819 | spin_unlock_irqrestore(&card->lock, flags); |
819 | ch->protocol = ISDN_P_NONE; | 820 | ch->protocol = ISDN_P_NONE; |
diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c index 26a86b846099..335fe6455002 100644 --- a/drivers/isdn/hardware/mISDN/w6692.c +++ b/drivers/isdn/hardware/mISDN/w6692.c | |||
@@ -1054,8 +1054,9 @@ w6692_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) | |||
1054 | switch (cmd) { | 1054 | switch (cmd) { |
1055 | case CLOSE_CHANNEL: | 1055 | case CLOSE_CHANNEL: |
1056 | test_and_clear_bit(FLG_OPEN, &bch->Flags); | 1056 | test_and_clear_bit(FLG_OPEN, &bch->Flags); |
1057 | cancel_work_sync(&bch->workq); | ||
1057 | spin_lock_irqsave(&card->lock, flags); | 1058 | spin_lock_irqsave(&card->lock, flags); |
1058 | mISDN_freebchannel(bch); | 1059 | mISDN_clear_bchannel(bch); |
1059 | w6692_mode(bc, ISDN_P_NONE); | 1060 | w6692_mode(bc, ISDN_P_NONE); |
1060 | spin_unlock_irqrestore(&card->lock, flags); | 1061 | spin_unlock_irqrestore(&card->lock, flags); |
1061 | ch->protocol = ISDN_P_NONE; | 1062 | ch->protocol = ISDN_P_NONE; |
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c index ef34fd40867c..2602be23f341 100644 --- a/drivers/isdn/mISDN/hwchannel.c +++ b/drivers/isdn/mISDN/hwchannel.c | |||
@@ -148,17 +148,16 @@ mISDN_clear_bchannel(struct bchannel *ch) | |||
148 | ch->next_minlen = ch->init_minlen; | 148 | ch->next_minlen = ch->init_minlen; |
149 | ch->maxlen = ch->init_maxlen; | 149 | ch->maxlen = ch->init_maxlen; |
150 | ch->next_maxlen = ch->init_maxlen; | 150 | ch->next_maxlen = ch->init_maxlen; |
151 | skb_queue_purge(&ch->rqueue); | ||
152 | ch->rcount = 0; | ||
151 | } | 153 | } |
152 | EXPORT_SYMBOL(mISDN_clear_bchannel); | 154 | EXPORT_SYMBOL(mISDN_clear_bchannel); |
153 | 155 | ||
154 | int | 156 | void |
155 | mISDN_freebchannel(struct bchannel *ch) | 157 | mISDN_freebchannel(struct bchannel *ch) |
156 | { | 158 | { |
159 | cancel_work_sync(&ch->workq); | ||
157 | mISDN_clear_bchannel(ch); | 160 | mISDN_clear_bchannel(ch); |
158 | skb_queue_purge(&ch->rqueue); | ||
159 | ch->rcount = 0; | ||
160 | flush_work_sync(&ch->workq); | ||
161 | return 0; | ||
162 | } | 161 | } |
163 | EXPORT_SYMBOL(mISDN_freebchannel); | 162 | EXPORT_SYMBOL(mISDN_freebchannel); |
164 | 163 | ||
diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c index b67a3018b136..ce229ea933d1 100644 --- a/drivers/mfd/88pm800.c +++ b/drivers/mfd/88pm800.c | |||
@@ -470,7 +470,8 @@ static int __devinit device_800_init(struct pm80x_chip *chip, | |||
470 | 470 | ||
471 | ret = | 471 | ret = |
472 | mfd_add_devices(chip->dev, 0, &onkey_devs[0], | 472 | mfd_add_devices(chip->dev, 0, &onkey_devs[0], |
473 | ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0); | 473 | ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0, |
474 | NULL); | ||
474 | if (ret < 0) { | 475 | if (ret < 0) { |
475 | dev_err(chip->dev, "Failed to add onkey subdev\n"); | 476 | dev_err(chip->dev, "Failed to add onkey subdev\n"); |
476 | goto out_dev; | 477 | goto out_dev; |
@@ -481,7 +482,7 @@ static int __devinit device_800_init(struct pm80x_chip *chip, | |||
481 | rtc_devs[0].platform_data = pdata->rtc; | 482 | rtc_devs[0].platform_data = pdata->rtc; |
482 | rtc_devs[0].pdata_size = sizeof(struct pm80x_rtc_pdata); | 483 | rtc_devs[0].pdata_size = sizeof(struct pm80x_rtc_pdata); |
483 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], | 484 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], |
484 | ARRAY_SIZE(rtc_devs), NULL, 0); | 485 | ARRAY_SIZE(rtc_devs), NULL, 0, NULL); |
485 | if (ret < 0) { | 486 | if (ret < 0) { |
486 | dev_err(chip->dev, "Failed to add rtc subdev\n"); | 487 | dev_err(chip->dev, "Failed to add rtc subdev\n"); |
487 | goto out_dev; | 488 | goto out_dev; |
diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c index 6146583589f6..c20a31136f04 100644 --- a/drivers/mfd/88pm805.c +++ b/drivers/mfd/88pm805.c | |||
@@ -216,7 +216,8 @@ static int __devinit device_805_init(struct pm80x_chip *chip) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], | 218 | ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], |
219 | ARRAY_SIZE(codec_devs), &codec_resources[0], 0); | 219 | ARRAY_SIZE(codec_devs), &codec_resources[0], 0, |
220 | NULL); | ||
220 | if (ret < 0) { | 221 | if (ret < 0) { |
221 | dev_err(chip->dev, "Failed to add codec subdev\n"); | 222 | dev_err(chip->dev, "Failed to add codec subdev\n"); |
222 | goto out_codec; | 223 | goto out_codec; |
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index d09918cf1b15..b73f033b2c60 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c | |||
@@ -637,7 +637,7 @@ static void __devinit device_bk_init(struct pm860x_chip *chip, | |||
637 | bk_devs[i].resources = &bk_resources[j]; | 637 | bk_devs[i].resources = &bk_resources[j]; |
638 | ret = mfd_add_devices(chip->dev, 0, | 638 | ret = mfd_add_devices(chip->dev, 0, |
639 | &bk_devs[i], 1, | 639 | &bk_devs[i], 1, |
640 | &bk_resources[j], 0); | 640 | &bk_resources[j], 0, NULL); |
641 | if (ret < 0) { | 641 | if (ret < 0) { |
642 | dev_err(chip->dev, "Failed to add " | 642 | dev_err(chip->dev, "Failed to add " |
643 | "backlight subdev\n"); | 643 | "backlight subdev\n"); |
@@ -672,7 +672,7 @@ static void __devinit device_led_init(struct pm860x_chip *chip, | |||
672 | led_devs[i].resources = &led_resources[j], | 672 | led_devs[i].resources = &led_resources[j], |
673 | ret = mfd_add_devices(chip->dev, 0, | 673 | ret = mfd_add_devices(chip->dev, 0, |
674 | &led_devs[i], 1, | 674 | &led_devs[i], 1, |
675 | &led_resources[j], 0); | 675 | &led_resources[j], 0, NULL); |
676 | if (ret < 0) { | 676 | if (ret < 0) { |
677 | dev_err(chip->dev, "Failed to add " | 677 | dev_err(chip->dev, "Failed to add " |
678 | "led subdev\n"); | 678 | "led subdev\n"); |
@@ -709,7 +709,7 @@ static void __devinit device_regulator_init(struct pm860x_chip *chip, | |||
709 | regulator_devs[i].resources = ®ulator_resources[seq]; | 709 | regulator_devs[i].resources = ®ulator_resources[seq]; |
710 | 710 | ||
711 | ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[i], 1, | 711 | ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[i], 1, |
712 | ®ulator_resources[seq], 0); | 712 | ®ulator_resources[seq], 0, NULL); |
713 | if (ret < 0) { | 713 | if (ret < 0) { |
714 | dev_err(chip->dev, "Failed to add regulator subdev\n"); | 714 | dev_err(chip->dev, "Failed to add regulator subdev\n"); |
715 | goto out; | 715 | goto out; |
@@ -733,7 +733,7 @@ static void __devinit device_rtc_init(struct pm860x_chip *chip, | |||
733 | rtc_devs[0].resources = &rtc_resources[0]; | 733 | rtc_devs[0].resources = &rtc_resources[0]; |
734 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], | 734 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], |
735 | ARRAY_SIZE(rtc_devs), &rtc_resources[0], | 735 | ARRAY_SIZE(rtc_devs), &rtc_resources[0], |
736 | chip->irq_base); | 736 | chip->irq_base, NULL); |
737 | if (ret < 0) | 737 | if (ret < 0) |
738 | dev_err(chip->dev, "Failed to add rtc subdev\n"); | 738 | dev_err(chip->dev, "Failed to add rtc subdev\n"); |
739 | } | 739 | } |
@@ -752,7 +752,7 @@ static void __devinit device_touch_init(struct pm860x_chip *chip, | |||
752 | touch_devs[0].resources = &touch_resources[0]; | 752 | touch_devs[0].resources = &touch_resources[0]; |
753 | ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], | 753 | ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], |
754 | ARRAY_SIZE(touch_devs), &touch_resources[0], | 754 | ARRAY_SIZE(touch_devs), &touch_resources[0], |
755 | chip->irq_base); | 755 | chip->irq_base, NULL); |
756 | if (ret < 0) | 756 | if (ret < 0) |
757 | dev_err(chip->dev, "Failed to add touch subdev\n"); | 757 | dev_err(chip->dev, "Failed to add touch subdev\n"); |
758 | } | 758 | } |
@@ -770,7 +770,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip, | |||
770 | power_devs[0].num_resources = ARRAY_SIZE(battery_resources); | 770 | power_devs[0].num_resources = ARRAY_SIZE(battery_resources); |
771 | power_devs[0].resources = &battery_resources[0], | 771 | power_devs[0].resources = &battery_resources[0], |
772 | ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 1, | 772 | ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 1, |
773 | &battery_resources[0], chip->irq_base); | 773 | &battery_resources[0], chip->irq_base, NULL); |
774 | if (ret < 0) | 774 | if (ret < 0) |
775 | dev_err(chip->dev, "Failed to add battery subdev\n"); | 775 | dev_err(chip->dev, "Failed to add battery subdev\n"); |
776 | 776 | ||
@@ -779,7 +779,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip, | |||
779 | power_devs[1].num_resources = ARRAY_SIZE(charger_resources); | 779 | power_devs[1].num_resources = ARRAY_SIZE(charger_resources); |
780 | power_devs[1].resources = &charger_resources[0], | 780 | power_devs[1].resources = &charger_resources[0], |
781 | ret = mfd_add_devices(chip->dev, 0, &power_devs[1], 1, | 781 | ret = mfd_add_devices(chip->dev, 0, &power_devs[1], 1, |
782 | &charger_resources[0], chip->irq_base); | 782 | &charger_resources[0], chip->irq_base, NULL); |
783 | if (ret < 0) | 783 | if (ret < 0) |
784 | dev_err(chip->dev, "Failed to add charger subdev\n"); | 784 | dev_err(chip->dev, "Failed to add charger subdev\n"); |
785 | 785 | ||
@@ -788,7 +788,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip, | |||
788 | power_devs[2].num_resources = ARRAY_SIZE(preg_resources); | 788 | power_devs[2].num_resources = ARRAY_SIZE(preg_resources); |
789 | power_devs[2].resources = &preg_resources[0], | 789 | power_devs[2].resources = &preg_resources[0], |
790 | ret = mfd_add_devices(chip->dev, 0, &power_devs[2], 1, | 790 | ret = mfd_add_devices(chip->dev, 0, &power_devs[2], 1, |
791 | &preg_resources[0], chip->irq_base); | 791 | &preg_resources[0], chip->irq_base, NULL); |
792 | if (ret < 0) | 792 | if (ret < 0) |
793 | dev_err(chip->dev, "Failed to add preg subdev\n"); | 793 | dev_err(chip->dev, "Failed to add preg subdev\n"); |
794 | } | 794 | } |
@@ -802,7 +802,7 @@ static void __devinit device_onkey_init(struct pm860x_chip *chip, | |||
802 | onkey_devs[0].resources = &onkey_resources[0], | 802 | onkey_devs[0].resources = &onkey_resources[0], |
803 | ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], | 803 | ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], |
804 | ARRAY_SIZE(onkey_devs), &onkey_resources[0], | 804 | ARRAY_SIZE(onkey_devs), &onkey_resources[0], |
805 | chip->irq_base); | 805 | chip->irq_base, NULL); |
806 | if (ret < 0) | 806 | if (ret < 0) |
807 | dev_err(chip->dev, "Failed to add onkey subdev\n"); | 807 | dev_err(chip->dev, "Failed to add onkey subdev\n"); |
808 | } | 808 | } |
@@ -815,7 +815,8 @@ static void __devinit device_codec_init(struct pm860x_chip *chip, | |||
815 | codec_devs[0].num_resources = ARRAY_SIZE(codec_resources); | 815 | codec_devs[0].num_resources = ARRAY_SIZE(codec_resources); |
816 | codec_devs[0].resources = &codec_resources[0], | 816 | codec_devs[0].resources = &codec_resources[0], |
817 | ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], | 817 | ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], |
818 | ARRAY_SIZE(codec_devs), &codec_resources[0], 0); | 818 | ARRAY_SIZE(codec_devs), &codec_resources[0], 0, |
819 | NULL); | ||
819 | if (ret < 0) | 820 | if (ret < 0) |
820 | dev_err(chip->dev, "Failed to add codec subdev\n"); | 821 | dev_err(chip->dev, "Failed to add codec subdev\n"); |
821 | } | 822 | } |
diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c index 44a3fdbadef4..f1beb4971f87 100644 --- a/drivers/mfd/aat2870-core.c +++ b/drivers/mfd/aat2870-core.c | |||
@@ -424,7 +424,7 @@ static int aat2870_i2c_probe(struct i2c_client *client, | |||
424 | } | 424 | } |
425 | 425 | ||
426 | ret = mfd_add_devices(aat2870->dev, 0, aat2870_devs, | 426 | ret = mfd_add_devices(aat2870->dev, 0, aat2870_devs, |
427 | ARRAY_SIZE(aat2870_devs), NULL, 0); | 427 | ARRAY_SIZE(aat2870_devs), NULL, 0, NULL); |
428 | if (ret != 0) { | 428 | if (ret != 0) { |
429 | dev_err(aat2870->dev, "Failed to add subdev: %d\n", ret); | 429 | dev_err(aat2870->dev, "Failed to add subdev: %d\n", ret); |
430 | goto out_disable; | 430 | goto out_disable; |
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index 78fca2902c8d..01781ae5d0d7 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c | |||
@@ -946,7 +946,7 @@ static int __devinit ab3100_probe(struct i2c_client *client, | |||
946 | } | 946 | } |
947 | 947 | ||
948 | err = mfd_add_devices(&client->dev, 0, ab3100_devs, | 948 | err = mfd_add_devices(&client->dev, 0, ab3100_devs, |
949 | ARRAY_SIZE(ab3100_devs), NULL, 0); | 949 | ARRAY_SIZE(ab3100_devs), NULL, 0, NULL); |
950 | 950 | ||
951 | ab3100_setup_debugfs(ab3100); | 951 | ab3100_setup_debugfs(ab3100); |
952 | 952 | ||
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 626b4ecaf647..47adf800024e 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -1418,25 +1418,25 @@ static int __devinit ab8500_probe(struct platform_device *pdev) | |||
1418 | 1418 | ||
1419 | ret = mfd_add_devices(ab8500->dev, 0, abx500_common_devs, | 1419 | ret = mfd_add_devices(ab8500->dev, 0, abx500_common_devs, |
1420 | ARRAY_SIZE(abx500_common_devs), NULL, | 1420 | ARRAY_SIZE(abx500_common_devs), NULL, |
1421 | ab8500->irq_base); | 1421 | ab8500->irq_base, ab8500->domain); |
1422 | if (ret) | 1422 | if (ret) |
1423 | goto out_freeirq; | 1423 | goto out_freeirq; |
1424 | 1424 | ||
1425 | if (is_ab9540(ab8500)) | 1425 | if (is_ab9540(ab8500)) |
1426 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, | 1426 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, |
1427 | ARRAY_SIZE(ab9540_devs), NULL, | 1427 | ARRAY_SIZE(ab9540_devs), NULL, |
1428 | ab8500->irq_base); | 1428 | ab8500->irq_base, ab8500->domain); |
1429 | else | 1429 | else |
1430 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs, | 1430 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs, |
1431 | ARRAY_SIZE(ab8500_devs), NULL, | 1431 | ARRAY_SIZE(ab8500_devs), NULL, |
1432 | ab8500->irq_base); | 1432 | ab8500->irq_base, ab8500->domain); |
1433 | if (ret) | 1433 | if (ret) |
1434 | goto out_freeirq; | 1434 | goto out_freeirq; |
1435 | 1435 | ||
1436 | if (is_ab9540(ab8500) || is_ab8505(ab8500)) | 1436 | if (is_ab9540(ab8500) || is_ab8505(ab8500)) |
1437 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_ab8505_devs, | 1437 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_ab8505_devs, |
1438 | ARRAY_SIZE(ab9540_ab8505_devs), NULL, | 1438 | ARRAY_SIZE(ab9540_ab8505_devs), NULL, |
1439 | ab8500->irq_base); | 1439 | ab8500->irq_base, ab8500->domain); |
1440 | if (ret) | 1440 | if (ret) |
1441 | goto out_freeirq; | 1441 | goto out_freeirq; |
1442 | 1442 | ||
@@ -1444,7 +1444,7 @@ static int __devinit ab8500_probe(struct platform_device *pdev) | |||
1444 | /* Add battery management devices */ | 1444 | /* Add battery management devices */ |
1445 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs, | 1445 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs, |
1446 | ARRAY_SIZE(ab8500_bm_devs), NULL, | 1446 | ARRAY_SIZE(ab8500_bm_devs), NULL, |
1447 | ab8500->irq_base); | 1447 | ab8500->irq_base, ab8500->domain); |
1448 | if (ret) | 1448 | if (ret) |
1449 | dev_err(ab8500->dev, "error adding bm devices\n"); | 1449 | dev_err(ab8500->dev, "error adding bm devices\n"); |
1450 | } | 1450 | } |
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index c7983e862549..1b48f2094806 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c | |||
@@ -316,7 +316,7 @@ int __devinit arizona_dev_init(struct arizona *arizona) | |||
316 | } | 316 | } |
317 | 317 | ||
318 | ret = mfd_add_devices(arizona->dev, -1, early_devs, | 318 | ret = mfd_add_devices(arizona->dev, -1, early_devs, |
319 | ARRAY_SIZE(early_devs), NULL, 0); | 319 | ARRAY_SIZE(early_devs), NULL, 0, NULL); |
320 | if (ret != 0) { | 320 | if (ret != 0) { |
321 | dev_err(dev, "Failed to add early children: %d\n", ret); | 321 | dev_err(dev, "Failed to add early children: %d\n", ret); |
322 | return ret; | 322 | return ret; |
@@ -516,11 +516,11 @@ int __devinit arizona_dev_init(struct arizona *arizona) | |||
516 | switch (arizona->type) { | 516 | switch (arizona->type) { |
517 | case WM5102: | 517 | case WM5102: |
518 | ret = mfd_add_devices(arizona->dev, -1, wm5102_devs, | 518 | ret = mfd_add_devices(arizona->dev, -1, wm5102_devs, |
519 | ARRAY_SIZE(wm5102_devs), NULL, 0); | 519 | ARRAY_SIZE(wm5102_devs), NULL, 0, NULL); |
520 | break; | 520 | break; |
521 | case WM5110: | 521 | case WM5110: |
522 | ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, | 522 | ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, |
523 | ARRAY_SIZE(wm5102_devs), NULL, 0); | 523 | ARRAY_SIZE(wm5102_devs), NULL, 0, NULL); |
524 | break; | 524 | break; |
525 | } | 525 | } |
526 | 526 | ||
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 683e18a23329..62f0883a7630 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
@@ -913,14 +913,14 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, | |||
913 | if (pdata->clock_rate) { | 913 | if (pdata->clock_rate) { |
914 | ds1wm_pdata.clock_rate = pdata->clock_rate; | 914 | ds1wm_pdata.clock_rate = pdata->clock_rate; |
915 | ret = mfd_add_devices(&pdev->dev, pdev->id, | 915 | ret = mfd_add_devices(&pdev->dev, pdev->id, |
916 | &asic3_cell_ds1wm, 1, mem, asic->irq_base); | 916 | &asic3_cell_ds1wm, 1, mem, asic->irq_base, NULL); |
917 | if (ret < 0) | 917 | if (ret < 0) |
918 | goto out; | 918 | goto out; |
919 | } | 919 | } |
920 | 920 | ||
921 | if (mem_sdio && (irq >= 0)) { | 921 | if (mem_sdio && (irq >= 0)) { |
922 | ret = mfd_add_devices(&pdev->dev, pdev->id, | 922 | ret = mfd_add_devices(&pdev->dev, pdev->id, |
923 | &asic3_cell_mmc, 1, mem_sdio, irq); | 923 | &asic3_cell_mmc, 1, mem_sdio, irq, NULL); |
924 | if (ret < 0) | 924 | if (ret < 0) |
925 | goto out; | 925 | goto out; |
926 | } | 926 | } |
@@ -934,7 +934,7 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, | |||
934 | asic3_cell_leds[i].pdata_size = sizeof(pdata->leds[i]); | 934 | asic3_cell_leds[i].pdata_size = sizeof(pdata->leds[i]); |
935 | } | 935 | } |
936 | ret = mfd_add_devices(&pdev->dev, 0, | 936 | ret = mfd_add_devices(&pdev->dev, 0, |
937 | asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0); | 937 | asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0, NULL); |
938 | } | 938 | } |
939 | 939 | ||
940 | out: | 940 | out: |
diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c index 3419e726de47..2b282133c725 100644 --- a/drivers/mfd/cs5535-mfd.c +++ b/drivers/mfd/cs5535-mfd.c | |||
@@ -149,7 +149,7 @@ static int __devinit cs5535_mfd_probe(struct pci_dev *pdev, | |||
149 | } | 149 | } |
150 | 150 | ||
151 | err = mfd_add_devices(&pdev->dev, -1, cs5535_mfd_cells, | 151 | err = mfd_add_devices(&pdev->dev, -1, cs5535_mfd_cells, |
152 | ARRAY_SIZE(cs5535_mfd_cells), NULL, 0); | 152 | ARRAY_SIZE(cs5535_mfd_cells), NULL, 0, NULL); |
153 | if (err) { | 153 | if (err) { |
154 | dev_err(&pdev->dev, "MFD add devices failed: %d\n", err); | 154 | dev_err(&pdev->dev, "MFD add devices failed: %d\n", err); |
155 | goto err_disable; | 155 | goto err_disable; |
diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c index 2544910e1fd6..a0a62b24621b 100644 --- a/drivers/mfd/da9052-core.c +++ b/drivers/mfd/da9052-core.c | |||
@@ -803,7 +803,7 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id) | |||
803 | dev_err(da9052->dev, "DA9052 ADC IRQ failed ret=%d\n", ret); | 803 | dev_err(da9052->dev, "DA9052 ADC IRQ failed ret=%d\n", ret); |
804 | 804 | ||
805 | ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, | 805 | ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, |
806 | ARRAY_SIZE(da9052_subdev_info), NULL, 0); | 806 | ARRAY_SIZE(da9052_subdev_info), NULL, 0, NULL); |
807 | if (ret) | 807 | if (ret) |
808 | goto err; | 808 | goto err; |
809 | 809 | ||
diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c index 4e2af2cb2d26..45e83a68641b 100644 --- a/drivers/mfd/davinci_voicecodec.c +++ b/drivers/mfd/davinci_voicecodec.c | |||
@@ -129,7 +129,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev) | |||
129 | cell->pdata_size = sizeof(*davinci_vc); | 129 | cell->pdata_size = sizeof(*davinci_vc); |
130 | 130 | ||
131 | ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, | 131 | ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, |
132 | DAVINCI_VC_CELLS, NULL, 0); | 132 | DAVINCI_VC_CELLS, NULL, 0, NULL); |
133 | if (ret != 0) { | 133 | if (ret != 0) { |
134 | dev_err(&pdev->dev, "fail to register client devices\n"); | 134 | dev_err(&pdev->dev, "fail to register client devices\n"); |
135 | goto fail4; | 135 | goto fail4; |
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 7040a0081130..0e63cdd9b52a 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -3010,7 +3010,7 @@ static int __devinit db8500_prcmu_probe(struct platform_device *pdev) | |||
3010 | prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); | 3010 | prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); |
3011 | 3011 | ||
3012 | err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, | 3012 | err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, |
3013 | ARRAY_SIZE(db8500_prcmu_devs), NULL, 0); | 3013 | ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, NULL); |
3014 | if (err) { | 3014 | if (err) { |
3015 | pr_err("prcmu: Failed to add subdevices\n"); | 3015 | pr_err("prcmu: Failed to add subdevices\n"); |
3016 | return err; | 3016 | return err; |
diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c index 04c7093d6499..9e5453d21a68 100644 --- a/drivers/mfd/htc-pasic3.c +++ b/drivers/mfd/htc-pasic3.c | |||
@@ -168,7 +168,7 @@ static int __init pasic3_probe(struct platform_device *pdev) | |||
168 | /* the first 5 PASIC3 registers control the DS1WM */ | 168 | /* the first 5 PASIC3 registers control the DS1WM */ |
169 | ds1wm_resources[0].end = (5 << asic->bus_shift) - 1; | 169 | ds1wm_resources[0].end = (5 << asic->bus_shift) - 1; |
170 | ret = mfd_add_devices(&pdev->dev, pdev->id, | 170 | ret = mfd_add_devices(&pdev->dev, pdev->id, |
171 | &ds1wm_cell, 1, r, irq); | 171 | &ds1wm_cell, 1, r, irq, NULL); |
172 | if (ret < 0) | 172 | if (ret < 0) |
173 | dev_warn(dev, "failed to register DS1WM\n"); | 173 | dev_warn(dev, "failed to register DS1WM\n"); |
174 | } | 174 | } |
@@ -176,7 +176,8 @@ static int __init pasic3_probe(struct platform_device *pdev) | |||
176 | if (pdata && pdata->led_pdata) { | 176 | if (pdata && pdata->led_pdata) { |
177 | led_cell.platform_data = pdata->led_pdata; | 177 | led_cell.platform_data = pdata->led_pdata; |
178 | led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo); | 178 | led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo); |
179 | ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0); | 179 | ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, |
180 | 0, NULL); | ||
180 | if (ret < 0) | 181 | if (ret < 0) |
181 | dev_warn(dev, "failed to register LED device\n"); | 182 | dev_warn(dev, "failed to register LED device\n"); |
182 | } | 183 | } |
diff --git a/drivers/mfd/intel_msic.c b/drivers/mfd/intel_msic.c index 59df5584cb58..266bdc5bd96d 100644 --- a/drivers/mfd/intel_msic.c +++ b/drivers/mfd/intel_msic.c | |||
@@ -344,13 +344,13 @@ static int __devinit intel_msic_init_devices(struct intel_msic *msic) | |||
344 | continue; | 344 | continue; |
345 | 345 | ||
346 | ret = mfd_add_devices(&pdev->dev, -1, &msic_devs[i], 1, NULL, | 346 | ret = mfd_add_devices(&pdev->dev, -1, &msic_devs[i], 1, NULL, |
347 | pdata->irq[i]); | 347 | pdata->irq[i], NULL); |
348 | if (ret) | 348 | if (ret) |
349 | goto fail; | 349 | goto fail; |
350 | } | 350 | } |
351 | 351 | ||
352 | ret = mfd_add_devices(&pdev->dev, 0, msic_other_devs, | 352 | ret = mfd_add_devices(&pdev->dev, 0, msic_other_devs, |
353 | ARRAY_SIZE(msic_other_devs), NULL, 0); | 353 | ARRAY_SIZE(msic_other_devs), NULL, 0, NULL); |
354 | if (ret) | 354 | if (ret) |
355 | goto fail; | 355 | goto fail; |
356 | 356 | ||
diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c index 2ea99989551a..965c4801df8a 100644 --- a/drivers/mfd/janz-cmodio.c +++ b/drivers/mfd/janz-cmodio.c | |||
@@ -147,7 +147,7 @@ static int __devinit cmodio_probe_submodules(struct cmodio_device *priv) | |||
147 | } | 147 | } |
148 | 148 | ||
149 | return mfd_add_devices(&pdev->dev, 0, priv->cells, | 149 | return mfd_add_devices(&pdev->dev, 0, priv->cells, |
150 | num_probed, NULL, pdev->irq); | 150 | num_probed, NULL, pdev->irq, NULL); |
151 | } | 151 | } |
152 | 152 | ||
153 | /* | 153 | /* |
diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c index 87662a17dec6..c6b6d7dda517 100644 --- a/drivers/mfd/jz4740-adc.c +++ b/drivers/mfd/jz4740-adc.c | |||
@@ -287,7 +287,8 @@ static int __devinit jz4740_adc_probe(struct platform_device *pdev) | |||
287 | writeb(0xff, adc->base + JZ_REG_ADC_CTRL); | 287 | writeb(0xff, adc->base + JZ_REG_ADC_CTRL); |
288 | 288 | ||
289 | ret = mfd_add_devices(&pdev->dev, 0, jz4740_adc_cells, | 289 | ret = mfd_add_devices(&pdev->dev, 0, jz4740_adc_cells, |
290 | ARRAY_SIZE(jz4740_adc_cells), mem_base, irq_base); | 290 | ARRAY_SIZE(jz4740_adc_cells), mem_base, |
291 | irq_base, NULL); | ||
291 | if (ret < 0) | 292 | if (ret < 0) |
292 | goto err_clk_put; | 293 | goto err_clk_put; |
293 | 294 | ||
diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c index 0b2879b87fd9..24212f45b201 100644 --- a/drivers/mfd/lm3533-core.c +++ b/drivers/mfd/lm3533-core.c | |||
@@ -393,7 +393,8 @@ static int __devinit lm3533_device_als_init(struct lm3533 *lm3533) | |||
393 | lm3533_als_devs[0].platform_data = pdata->als; | 393 | lm3533_als_devs[0].platform_data = pdata->als; |
394 | lm3533_als_devs[0].pdata_size = sizeof(*pdata->als); | 394 | lm3533_als_devs[0].pdata_size = sizeof(*pdata->als); |
395 | 395 | ||
396 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL, 0); | 396 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL, |
397 | 0, NULL); | ||
397 | if (ret) { | 398 | if (ret) { |
398 | dev_err(lm3533->dev, "failed to add ALS device\n"); | 399 | dev_err(lm3533->dev, "failed to add ALS device\n"); |
399 | return ret; | 400 | return ret; |
@@ -422,7 +423,7 @@ static int __devinit lm3533_device_bl_init(struct lm3533 *lm3533) | |||
422 | } | 423 | } |
423 | 424 | ||
424 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_bl_devs, | 425 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_bl_devs, |
425 | pdata->num_backlights, NULL, 0); | 426 | pdata->num_backlights, NULL, 0, NULL); |
426 | if (ret) { | 427 | if (ret) { |
427 | dev_err(lm3533->dev, "failed to add backlight devices\n"); | 428 | dev_err(lm3533->dev, "failed to add backlight devices\n"); |
428 | return ret; | 429 | return ret; |
@@ -451,7 +452,7 @@ static int __devinit lm3533_device_led_init(struct lm3533 *lm3533) | |||
451 | } | 452 | } |
452 | 453 | ||
453 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs, | 454 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs, |
454 | pdata->num_leds, NULL, 0); | 455 | pdata->num_leds, NULL, 0, NULL); |
455 | if (ret) { | 456 | if (ret) { |
456 | dev_err(lm3533->dev, "failed to add LED devices\n"); | 457 | dev_err(lm3533->dev, "failed to add LED devices\n"); |
457 | return ret; | 458 | return ret; |
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c index 027cc8f86132..092ad4b44b6d 100644 --- a/drivers/mfd/lpc_ich.c +++ b/drivers/mfd/lpc_ich.c | |||
@@ -750,7 +750,7 @@ gpe0_done: | |||
750 | 750 | ||
751 | lpc_ich_finalize_cell(&lpc_ich_cells[LPC_GPIO], id); | 751 | lpc_ich_finalize_cell(&lpc_ich_cells[LPC_GPIO], id); |
752 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_GPIO], | 752 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_GPIO], |
753 | 1, NULL, 0); | 753 | 1, NULL, 0, NULL); |
754 | 754 | ||
755 | gpio_done: | 755 | gpio_done: |
756 | if (acpi_conflict) | 756 | if (acpi_conflict) |
@@ -765,7 +765,6 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev, | |||
765 | u32 base_addr_cfg; | 765 | u32 base_addr_cfg; |
766 | u32 base_addr; | 766 | u32 base_addr; |
767 | int ret; | 767 | int ret; |
768 | bool acpi_conflict = false; | ||
769 | struct resource *res; | 768 | struct resource *res; |
770 | 769 | ||
771 | /* Setup power management base register */ | 770 | /* Setup power management base register */ |
@@ -780,20 +779,11 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev, | |||
780 | res = wdt_io_res(ICH_RES_IO_TCO); | 779 | res = wdt_io_res(ICH_RES_IO_TCO); |
781 | res->start = base_addr + ACPIBASE_TCO_OFF; | 780 | res->start = base_addr + ACPIBASE_TCO_OFF; |
782 | res->end = base_addr + ACPIBASE_TCO_END; | 781 | res->end = base_addr + ACPIBASE_TCO_END; |
783 | ret = acpi_check_resource_conflict(res); | ||
784 | if (ret) { | ||
785 | acpi_conflict = true; | ||
786 | goto wdt_done; | ||
787 | } | ||
788 | 782 | ||
789 | res = wdt_io_res(ICH_RES_IO_SMI); | 783 | res = wdt_io_res(ICH_RES_IO_SMI); |
790 | res->start = base_addr + ACPIBASE_SMI_OFF; | 784 | res->start = base_addr + ACPIBASE_SMI_OFF; |
791 | res->end = base_addr + ACPIBASE_SMI_END; | 785 | res->end = base_addr + ACPIBASE_SMI_END; |
792 | ret = acpi_check_resource_conflict(res); | 786 | |
793 | if (ret) { | ||
794 | acpi_conflict = true; | ||
795 | goto wdt_done; | ||
796 | } | ||
797 | lpc_ich_enable_acpi_space(dev); | 787 | lpc_ich_enable_acpi_space(dev); |
798 | 788 | ||
799 | /* | 789 | /* |
@@ -813,21 +803,13 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev, | |||
813 | res = wdt_mem_res(ICH_RES_MEM_GCS); | 803 | res = wdt_mem_res(ICH_RES_MEM_GCS); |
814 | res->start = base_addr + ACPIBASE_GCS_OFF; | 804 | res->start = base_addr + ACPIBASE_GCS_OFF; |
815 | res->end = base_addr + ACPIBASE_GCS_END; | 805 | res->end = base_addr + ACPIBASE_GCS_END; |
816 | ret = acpi_check_resource_conflict(res); | ||
817 | if (ret) { | ||
818 | acpi_conflict = true; | ||
819 | goto wdt_done; | ||
820 | } | ||
821 | } | 806 | } |
822 | 807 | ||
823 | lpc_ich_finalize_cell(&lpc_ich_cells[LPC_WDT], id); | 808 | lpc_ich_finalize_cell(&lpc_ich_cells[LPC_WDT], id); |
824 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_WDT], | 809 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_WDT], |
825 | 1, NULL, 0); | 810 | 1, NULL, 0, NULL); |
826 | 811 | ||
827 | wdt_done: | 812 | wdt_done: |
828 | if (acpi_conflict) | ||
829 | pr_warn("Resource conflict(s) found affecting %s\n", | ||
830 | lpc_ich_cells[LPC_WDT].name); | ||
831 | return ret; | 813 | return ret; |
832 | } | 814 | } |
833 | 815 | ||
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c index 9f20abc5e393..f6b9c5c96b24 100644 --- a/drivers/mfd/lpc_sch.c +++ b/drivers/mfd/lpc_sch.c | |||
@@ -127,7 +127,8 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev, | |||
127 | lpc_sch_cells[i].id = id->device; | 127 | lpc_sch_cells[i].id = id->device; |
128 | 128 | ||
129 | ret = mfd_add_devices(&dev->dev, 0, | 129 | ret = mfd_add_devices(&dev->dev, 0, |
130 | lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0); | 130 | lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, |
131 | 0, NULL); | ||
131 | if (ret) | 132 | if (ret) |
132 | goto out_dev; | 133 | goto out_dev; |
133 | 134 | ||
@@ -153,7 +154,8 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev, | |||
153 | tunnelcreek_cells[i].id = id->device; | 154 | tunnelcreek_cells[i].id = id->device; |
154 | 155 | ||
155 | ret = mfd_add_devices(&dev->dev, 0, tunnelcreek_cells, | 156 | ret = mfd_add_devices(&dev->dev, 0, tunnelcreek_cells, |
156 | ARRAY_SIZE(tunnelcreek_cells), NULL, 0); | 157 | ARRAY_SIZE(tunnelcreek_cells), NULL, |
158 | 0, NULL); | ||
157 | } | 159 | } |
158 | 160 | ||
159 | return ret; | 161 | return ret; |
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index c03e12b51924..d9e24c849a00 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c | |||
@@ -126,7 +126,7 @@ static int max77686_i2c_probe(struct i2c_client *i2c, | |||
126 | max77686_irq_init(max77686); | 126 | max77686_irq_init(max77686); |
127 | 127 | ||
128 | ret = mfd_add_devices(max77686->dev, -1, max77686_devs, | 128 | ret = mfd_add_devices(max77686->dev, -1, max77686_devs, |
129 | ARRAY_SIZE(max77686_devs), NULL, 0); | 129 | ARRAY_SIZE(max77686_devs), NULL, 0, NULL); |
130 | 130 | ||
131 | if (ret < 0) | 131 | if (ret < 0) |
132 | goto err_mfd; | 132 | goto err_mfd; |
diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c index 2b403569e0a6..1029d018c739 100644 --- a/drivers/mfd/max77693-irq.c +++ b/drivers/mfd/max77693-irq.c | |||
@@ -137,6 +137,9 @@ static void max77693_irq_mask(struct irq_data *data) | |||
137 | const struct max77693_irq_data *irq_data = | 137 | const struct max77693_irq_data *irq_data = |
138 | irq_to_max77693_irq(max77693, data->irq); | 138 | irq_to_max77693_irq(max77693, data->irq); |
139 | 139 | ||
140 | if (irq_data->group >= MAX77693_IRQ_GROUP_NR) | ||
141 | return; | ||
142 | |||
140 | if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) | 143 | if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) |
141 | max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask; | 144 | max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask; |
142 | else | 145 | else |
@@ -149,6 +152,9 @@ static void max77693_irq_unmask(struct irq_data *data) | |||
149 | const struct max77693_irq_data *irq_data = | 152 | const struct max77693_irq_data *irq_data = |
150 | irq_to_max77693_irq(max77693, data->irq); | 153 | irq_to_max77693_irq(max77693, data->irq); |
151 | 154 | ||
155 | if (irq_data->group >= MAX77693_IRQ_GROUP_NR) | ||
156 | return; | ||
157 | |||
152 | if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) | 158 | if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) |
153 | max77693->irq_masks_cur[irq_data->group] |= irq_data->mask; | 159 | max77693->irq_masks_cur[irq_data->group] |= irq_data->mask; |
154 | else | 160 | else |
@@ -200,7 +206,7 @@ static irqreturn_t max77693_irq_thread(int irq, void *data) | |||
200 | 206 | ||
201 | if (irq_src & MAX77693_IRQSRC_MUIC) | 207 | if (irq_src & MAX77693_IRQSRC_MUIC) |
202 | /* MUIC INT1 ~ INT3 */ | 208 | /* MUIC INT1 ~ INT3 */ |
203 | max77693_bulk_read(max77693->regmap, MAX77693_MUIC_REG_INT1, | 209 | max77693_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1, |
204 | MAX77693_NUM_IRQ_MUIC_REGS, &irq_reg[MUIC_INT1]); | 210 | MAX77693_NUM_IRQ_MUIC_REGS, &irq_reg[MUIC_INT1]); |
205 | 211 | ||
206 | /* Apply masking */ | 212 | /* Apply masking */ |
@@ -255,7 +261,8 @@ int max77693_irq_init(struct max77693_dev *max77693) | |||
255 | { | 261 | { |
256 | struct irq_domain *domain; | 262 | struct irq_domain *domain; |
257 | int i; | 263 | int i; |
258 | int ret; | 264 | int ret = 0; |
265 | u8 intsrc_mask; | ||
259 | 266 | ||
260 | mutex_init(&max77693->irqlock); | 267 | mutex_init(&max77693->irqlock); |
261 | 268 | ||
@@ -287,19 +294,38 @@ int max77693_irq_init(struct max77693_dev *max77693) | |||
287 | &max77693_irq_domain_ops, max77693); | 294 | &max77693_irq_domain_ops, max77693); |
288 | if (!domain) { | 295 | if (!domain) { |
289 | dev_err(max77693->dev, "could not create irq domain\n"); | 296 | dev_err(max77693->dev, "could not create irq domain\n"); |
290 | return -ENODEV; | 297 | ret = -ENODEV; |
298 | goto err_irq; | ||
291 | } | 299 | } |
292 | max77693->irq_domain = domain; | 300 | max77693->irq_domain = domain; |
293 | 301 | ||
302 | /* Unmask max77693 interrupt */ | ||
303 | ret = max77693_read_reg(max77693->regmap, | ||
304 | MAX77693_PMIC_REG_INTSRC_MASK, &intsrc_mask); | ||
305 | if (ret < 0) { | ||
306 | dev_err(max77693->dev, "fail to read PMIC register\n"); | ||
307 | goto err_irq; | ||
308 | } | ||
309 | |||
310 | intsrc_mask &= ~(MAX77693_IRQSRC_CHG); | ||
311 | intsrc_mask &= ~(MAX77693_IRQSRC_FLASH); | ||
312 | intsrc_mask &= ~(MAX77693_IRQSRC_MUIC); | ||
313 | ret = max77693_write_reg(max77693->regmap, | ||
314 | MAX77693_PMIC_REG_INTSRC_MASK, intsrc_mask); | ||
315 | if (ret < 0) { | ||
316 | dev_err(max77693->dev, "fail to write PMIC register\n"); | ||
317 | goto err_irq; | ||
318 | } | ||
319 | |||
294 | ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread, | 320 | ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread, |
295 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 321 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
296 | "max77693-irq", max77693); | 322 | "max77693-irq", max77693); |
297 | |||
298 | if (ret) | 323 | if (ret) |
299 | dev_err(max77693->dev, "Failed to request IRQ %d: %d\n", | 324 | dev_err(max77693->dev, "Failed to request IRQ %d: %d\n", |
300 | max77693->irq, ret); | 325 | max77693->irq, ret); |
301 | 326 | ||
302 | return 0; | 327 | err_irq: |
328 | return ret; | ||
303 | } | 329 | } |
304 | 330 | ||
305 | void max77693_irq_exit(struct max77693_dev *max77693) | 331 | void max77693_irq_exit(struct max77693_dev *max77693) |
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index a1811cb50ec7..cc5155e20494 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c | |||
@@ -152,6 +152,20 @@ static int max77693_i2c_probe(struct i2c_client *i2c, | |||
152 | max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); | 152 | max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); |
153 | i2c_set_clientdata(max77693->haptic, max77693); | 153 | i2c_set_clientdata(max77693->haptic, max77693); |
154 | 154 | ||
155 | /* | ||
156 | * Initialize register map for MUIC device because use regmap-muic | ||
157 | * instance of MUIC device when irq of max77693 is initialized | ||
158 | * before call max77693-muic probe() function. | ||
159 | */ | ||
160 | max77693->regmap_muic = devm_regmap_init_i2c(max77693->muic, | ||
161 | &max77693_regmap_config); | ||
162 | if (IS_ERR(max77693->regmap_muic)) { | ||
163 | ret = PTR_ERR(max77693->regmap_muic); | ||
164 | dev_err(max77693->dev, | ||
165 | "failed to allocate register map: %d\n", ret); | ||
166 | goto err_regmap; | ||
167 | } | ||
168 | |||
155 | ret = max77693_irq_init(max77693); | 169 | ret = max77693_irq_init(max77693); |
156 | if (ret < 0) | 170 | if (ret < 0) |
157 | goto err_irq; | 171 | goto err_irq; |
@@ -159,7 +173,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c, | |||
159 | pm_runtime_set_active(max77693->dev); | 173 | pm_runtime_set_active(max77693->dev); |
160 | 174 | ||
161 | ret = mfd_add_devices(max77693->dev, -1, max77693_devs, | 175 | ret = mfd_add_devices(max77693->dev, -1, max77693_devs, |
162 | ARRAY_SIZE(max77693_devs), NULL, 0); | 176 | ARRAY_SIZE(max77693_devs), NULL, 0, NULL); |
163 | if (ret < 0) | 177 | if (ret < 0) |
164 | goto err_mfd; | 178 | goto err_mfd; |
165 | 179 | ||
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index 825a7f06d9ba..ee53757beca7 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c | |||
@@ -598,7 +598,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
598 | 598 | ||
599 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], | 599 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], |
600 | ARRAY_SIZE(rtc_devs), | 600 | ARRAY_SIZE(rtc_devs), |
601 | &rtc_resources[0], chip->irq_base); | 601 | &rtc_resources[0], chip->irq_base, NULL); |
602 | if (ret < 0) { | 602 | if (ret < 0) { |
603 | dev_err(chip->dev, "Failed to add rtc subdev\n"); | 603 | dev_err(chip->dev, "Failed to add rtc subdev\n"); |
604 | goto out; | 604 | goto out; |
@@ -606,7 +606,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
606 | 606 | ||
607 | ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], | 607 | ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], |
608 | ARRAY_SIZE(onkey_devs), | 608 | ARRAY_SIZE(onkey_devs), |
609 | &onkey_resources[0], 0); | 609 | &onkey_resources[0], 0, NULL); |
610 | if (ret < 0) { | 610 | if (ret < 0) { |
611 | dev_err(chip->dev, "Failed to add onkey subdev\n"); | 611 | dev_err(chip->dev, "Failed to add onkey subdev\n"); |
612 | goto out_dev; | 612 | goto out_dev; |
@@ -615,7 +615,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
615 | if (pdata) { | 615 | if (pdata) { |
616 | ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[0], | 616 | ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[0], |
617 | ARRAY_SIZE(regulator_devs), | 617 | ARRAY_SIZE(regulator_devs), |
618 | ®ulator_resources[0], 0); | 618 | ®ulator_resources[0], 0, NULL); |
619 | if (ret < 0) { | 619 | if (ret < 0) { |
620 | dev_err(chip->dev, "Failed to add regulator subdev\n"); | 620 | dev_err(chip->dev, "Failed to add regulator subdev\n"); |
621 | goto out_dev; | 621 | goto out_dev; |
@@ -625,7 +625,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
625 | if (pdata && pdata->backlight) { | 625 | if (pdata && pdata->backlight) { |
626 | ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0], | 626 | ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0], |
627 | ARRAY_SIZE(backlight_devs), | 627 | ARRAY_SIZE(backlight_devs), |
628 | &backlight_resources[0], 0); | 628 | &backlight_resources[0], 0, NULL); |
629 | if (ret < 0) { | 629 | if (ret < 0) { |
630 | dev_err(chip->dev, "Failed to add backlight subdev\n"); | 630 | dev_err(chip->dev, "Failed to add backlight subdev\n"); |
631 | goto out_dev; | 631 | goto out_dev; |
@@ -635,7 +635,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
635 | if (pdata && pdata->power) { | 635 | if (pdata && pdata->power) { |
636 | ret = mfd_add_devices(chip->dev, 0, &power_devs[0], | 636 | ret = mfd_add_devices(chip->dev, 0, &power_devs[0], |
637 | ARRAY_SIZE(power_devs), | 637 | ARRAY_SIZE(power_devs), |
638 | &power_supply_resources[0], 0); | 638 | &power_supply_resources[0], 0, NULL); |
639 | if (ret < 0) { | 639 | if (ret < 0) { |
640 | dev_err(chip->dev, "Failed to add power supply " | 640 | dev_err(chip->dev, "Failed to add power supply " |
641 | "subdev\n"); | 641 | "subdev\n"); |
@@ -646,7 +646,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
646 | if (pdata && pdata->touch) { | 646 | if (pdata && pdata->touch) { |
647 | ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], | 647 | ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], |
648 | ARRAY_SIZE(touch_devs), | 648 | ARRAY_SIZE(touch_devs), |
649 | &touch_resources[0], 0); | 649 | &touch_resources[0], 0, NULL); |
650 | if (ret < 0) { | 650 | if (ret < 0) { |
651 | dev_err(chip->dev, "Failed to add touch subdev\n"); | 651 | dev_err(chip->dev, "Failed to add touch subdev\n"); |
652 | goto out_dev; | 652 | goto out_dev; |
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 10b629c245b6..f123517065ec 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c | |||
@@ -160,7 +160,7 @@ static int max8997_i2c_probe(struct i2c_client *i2c, | |||
160 | 160 | ||
161 | mfd_add_devices(max8997->dev, -1, max8997_devs, | 161 | mfd_add_devices(max8997->dev, -1, max8997_devs, |
162 | ARRAY_SIZE(max8997_devs), | 162 | ARRAY_SIZE(max8997_devs), |
163 | NULL, 0); | 163 | NULL, 0, NULL); |
164 | 164 | ||
165 | /* | 165 | /* |
166 | * TODO: enable others (flash, muic, rtc, battery, ...) and | 166 | * TODO: enable others (flash, muic, rtc, battery, ...) and |
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index 6ef56d28c056..d7218cc90945 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c | |||
@@ -161,13 +161,13 @@ static int max8998_i2c_probe(struct i2c_client *i2c, | |||
161 | switch (id->driver_data) { | 161 | switch (id->driver_data) { |
162 | case TYPE_LP3974: | 162 | case TYPE_LP3974: |
163 | ret = mfd_add_devices(max8998->dev, -1, | 163 | ret = mfd_add_devices(max8998->dev, -1, |
164 | lp3974_devs, ARRAY_SIZE(lp3974_devs), | 164 | lp3974_devs, ARRAY_SIZE(lp3974_devs), |
165 | NULL, 0); | 165 | NULL, 0, NULL); |
166 | break; | 166 | break; |
167 | case TYPE_MAX8998: | 167 | case TYPE_MAX8998: |
168 | ret = mfd_add_devices(max8998->dev, -1, | 168 | ret = mfd_add_devices(max8998->dev, -1, |
169 | max8998_devs, ARRAY_SIZE(max8998_devs), | 169 | max8998_devs, ARRAY_SIZE(max8998_devs), |
170 | NULL, 0); | 170 | NULL, 0, NULL); |
171 | break; | 171 | break; |
172 | default: | 172 | default: |
173 | ret = -EINVAL; | 173 | ret = -EINVAL; |
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index b801dc72f041..1ec79b54bd2f 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c | |||
@@ -612,7 +612,7 @@ static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx, | |||
612 | if (!cell.name) | 612 | if (!cell.name) |
613 | return -ENOMEM; | 613 | return -ENOMEM; |
614 | 614 | ||
615 | return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0); | 615 | return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0, NULL); |
616 | } | 616 | } |
617 | 617 | ||
618 | static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) | 618 | static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) |
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 0c3a01cde2f7..f8b77711ad2d 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c | |||
@@ -74,12 +74,11 @@ static int mfd_platform_add_cell(struct platform_device *pdev, | |||
74 | static int mfd_add_device(struct device *parent, int id, | 74 | static int mfd_add_device(struct device *parent, int id, |
75 | const struct mfd_cell *cell, | 75 | const struct mfd_cell *cell, |
76 | struct resource *mem_base, | 76 | struct resource *mem_base, |
77 | int irq_base) | 77 | int irq_base, struct irq_domain *domain) |
78 | { | 78 | { |
79 | struct resource *res; | 79 | struct resource *res; |
80 | struct platform_device *pdev; | 80 | struct platform_device *pdev; |
81 | struct device_node *np = NULL; | 81 | struct device_node *np = NULL; |
82 | struct irq_domain *domain = NULL; | ||
83 | int ret = -ENOMEM; | 82 | int ret = -ENOMEM; |
84 | int r; | 83 | int r; |
85 | 84 | ||
@@ -97,7 +96,6 @@ static int mfd_add_device(struct device *parent, int id, | |||
97 | for_each_child_of_node(parent->of_node, np) { | 96 | for_each_child_of_node(parent->of_node, np) { |
98 | if (of_device_is_compatible(np, cell->of_compatible)) { | 97 | if (of_device_is_compatible(np, cell->of_compatible)) { |
99 | pdev->dev.of_node = np; | 98 | pdev->dev.of_node = np; |
100 | domain = irq_find_host(parent->of_node); | ||
101 | break; | 99 | break; |
102 | } | 100 | } |
103 | } | 101 | } |
@@ -177,7 +175,7 @@ fail_alloc: | |||
177 | int mfd_add_devices(struct device *parent, int id, | 175 | int mfd_add_devices(struct device *parent, int id, |
178 | struct mfd_cell *cells, int n_devs, | 176 | struct mfd_cell *cells, int n_devs, |
179 | struct resource *mem_base, | 177 | struct resource *mem_base, |
180 | int irq_base) | 178 | int irq_base, struct irq_domain *domain) |
181 | { | 179 | { |
182 | int i; | 180 | int i; |
183 | int ret = 0; | 181 | int ret = 0; |
@@ -191,7 +189,8 @@ int mfd_add_devices(struct device *parent, int id, | |||
191 | for (i = 0; i < n_devs; i++) { | 189 | for (i = 0; i < n_devs; i++) { |
192 | atomic_set(&cnts[i], 0); | 190 | atomic_set(&cnts[i], 0); |
193 | cells[i].usage_count = &cnts[i]; | 191 | cells[i].usage_count = &cnts[i]; |
194 | ret = mfd_add_device(parent, id, cells + i, mem_base, irq_base); | 192 | ret = mfd_add_device(parent, id, cells + i, mem_base, |
193 | irq_base, domain); | ||
195 | if (ret) | 194 | if (ret) |
196 | break; | 195 | break; |
197 | } | 196 | } |
@@ -247,7 +246,8 @@ int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones) | |||
247 | for (i = 0; i < n_clones; i++) { | 246 | for (i = 0; i < n_clones; i++) { |
248 | cell_entry.name = clones[i]; | 247 | cell_entry.name = clones[i]; |
249 | /* don't give up if a single call fails; just report error */ | 248 | /* don't give up if a single call fails; just report error */ |
250 | if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0)) | 249 | if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0, |
250 | NULL)) | ||
251 | dev_err(dev, "failed to create platform device '%s'\n", | 251 | dev_err(dev, "failed to create platform device '%s'\n", |
252 | clones[i]); | 252 | clones[i]); |
253 | } | 253 | } |
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index c4a69f193a1d..a345f9bb7b47 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c | |||
@@ -453,7 +453,8 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c, | |||
453 | 453 | ||
454 | ret = mfd_add_devices(palmas->dev, -1, | 454 | ret = mfd_add_devices(palmas->dev, -1, |
455 | children, ARRAY_SIZE(palmas_children), | 455 | children, ARRAY_SIZE(palmas_children), |
456 | NULL, regmap_irq_chip_get_base(palmas->irq_data)); | 456 | NULL, regmap_irq_chip_get_base(palmas->irq_data), |
457 | NULL); | ||
457 | kfree(children); | 458 | kfree(children); |
458 | 459 | ||
459 | if (ret < 0) | 460 | if (ret < 0) |
diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c index cdc1df7fa0e9..3a8fa88567b1 100644 --- a/drivers/mfd/rc5t583.c +++ b/drivers/mfd/rc5t583.c | |||
@@ -289,7 +289,7 @@ static int __devinit rc5t583_i2c_probe(struct i2c_client *i2c, | |||
289 | } | 289 | } |
290 | 290 | ||
291 | ret = mfd_add_devices(rc5t583->dev, -1, rc5t583_subdevs, | 291 | ret = mfd_add_devices(rc5t583->dev, -1, rc5t583_subdevs, |
292 | ARRAY_SIZE(rc5t583_subdevs), NULL, 0); | 292 | ARRAY_SIZE(rc5t583_subdevs), NULL, 0, NULL); |
293 | if (ret) { | 293 | if (ret) { |
294 | dev_err(&i2c->dev, "add mfd devices failed: %d\n", ret); | 294 | dev_err(&i2c->dev, "add mfd devices failed: %d\n", ret); |
295 | goto err_add_devs; | 295 | goto err_add_devs; |
diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c index 685d61e431ad..0f70dce61160 100644 --- a/drivers/mfd/rdc321x-southbridge.c +++ b/drivers/mfd/rdc321x-southbridge.c | |||
@@ -87,7 +87,8 @@ static int __devinit rdc321x_sb_probe(struct pci_dev *pdev, | |||
87 | rdc321x_wdt_pdata.sb_pdev = pdev; | 87 | rdc321x_wdt_pdata.sb_pdev = pdev; |
88 | 88 | ||
89 | return mfd_add_devices(&pdev->dev, -1, | 89 | return mfd_add_devices(&pdev->dev, -1, |
90 | rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), NULL, 0); | 90 | rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), |
91 | NULL, 0, NULL); | ||
91 | } | 92 | } |
92 | 93 | ||
93 | static void __devexit rdc321x_sb_remove(struct pci_dev *pdev) | 94 | static void __devexit rdc321x_sb_remove(struct pci_dev *pdev) |
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index 2988efde11eb..49d361a618d0 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c | |||
@@ -141,19 +141,19 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
141 | switch (sec_pmic->device_type) { | 141 | switch (sec_pmic->device_type) { |
142 | case S5M8751X: | 142 | case S5M8751X: |
143 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8751_devs, | 143 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8751_devs, |
144 | ARRAY_SIZE(s5m8751_devs), NULL, 0); | 144 | ARRAY_SIZE(s5m8751_devs), NULL, 0, NULL); |
145 | break; | 145 | break; |
146 | case S5M8763X: | 146 | case S5M8763X: |
147 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8763_devs, | 147 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8763_devs, |
148 | ARRAY_SIZE(s5m8763_devs), NULL, 0); | 148 | ARRAY_SIZE(s5m8763_devs), NULL, 0, NULL); |
149 | break; | 149 | break; |
150 | case S5M8767X: | 150 | case S5M8767X: |
151 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8767_devs, | 151 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8767_devs, |
152 | ARRAY_SIZE(s5m8767_devs), NULL, 0); | 152 | ARRAY_SIZE(s5m8767_devs), NULL, 0, NULL); |
153 | break; | 153 | break; |
154 | case S2MPS11X: | 154 | case S2MPS11X: |
155 | ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs, | 155 | ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs, |
156 | ARRAY_SIZE(s2mps11_devs), NULL, 0); | 156 | ARRAY_SIZE(s2mps11_devs), NULL, 0, NULL); |
157 | break; | 157 | break; |
158 | default: | 158 | default: |
159 | /* If this happens the probe function is problem */ | 159 | /* If this happens the probe function is problem */ |
diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c index d31fed07aefb..d35da6820bea 100644 --- a/drivers/mfd/sta2x11-mfd.c +++ b/drivers/mfd/sta2x11-mfd.c | |||
@@ -407,7 +407,7 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev, | |||
407 | sta2x11_mfd_bar0, | 407 | sta2x11_mfd_bar0, |
408 | ARRAY_SIZE(sta2x11_mfd_bar0), | 408 | ARRAY_SIZE(sta2x11_mfd_bar0), |
409 | &pdev->resource[0], | 409 | &pdev->resource[0], |
410 | 0); | 410 | 0, NULL); |
411 | if (err) { | 411 | if (err) { |
412 | dev_err(&pdev->dev, "mfd_add_devices[0] failed: %d\n", err); | 412 | dev_err(&pdev->dev, "mfd_add_devices[0] failed: %d\n", err); |
413 | goto err_disable; | 413 | goto err_disable; |
@@ -417,7 +417,7 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev, | |||
417 | sta2x11_mfd_bar1, | 417 | sta2x11_mfd_bar1, |
418 | ARRAY_SIZE(sta2x11_mfd_bar1), | 418 | ARRAY_SIZE(sta2x11_mfd_bar1), |
419 | &pdev->resource[1], | 419 | &pdev->resource[1], |
420 | 0); | 420 | 0, NULL); |
421 | if (err) { | 421 | if (err) { |
422 | dev_err(&pdev->dev, "mfd_add_devices[1] failed: %d\n", err); | 422 | dev_err(&pdev->dev, "mfd_add_devices[1] failed: %d\n", err); |
423 | goto err_disable; | 423 | goto err_disable; |
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 2dd8d49cb30b..c94f521f392c 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c | |||
@@ -962,7 +962,7 @@ static int __devinit stmpe_add_device(struct stmpe *stmpe, | |||
962 | struct mfd_cell *cell, int irq) | 962 | struct mfd_cell *cell, int irq) |
963 | { | 963 | { |
964 | return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1, | 964 | return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1, |
965 | NULL, stmpe->irq_base + irq); | 965 | NULL, stmpe->irq_base + irq, NULL); |
966 | } | 966 | } |
967 | 967 | ||
968 | static int __devinit stmpe_devices_init(struct stmpe *stmpe) | 968 | static int __devinit stmpe_devices_init(struct stmpe *stmpe) |
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index 2d9e8799e733..b32940ec9034 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c | |||
@@ -388,7 +388,7 @@ static int t7l66xb_probe(struct platform_device *dev) | |||
388 | 388 | ||
389 | ret = mfd_add_devices(&dev->dev, dev->id, | 389 | ret = mfd_add_devices(&dev->dev, dev->id, |
390 | t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells), | 390 | t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells), |
391 | iomem, t7l66xb->irq_base); | 391 | iomem, t7l66xb->irq_base, NULL); |
392 | 392 | ||
393 | if (!ret) | 393 | if (!ret) |
394 | return 0; | 394 | return 0; |
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c index 048bf0532a09..b56ba6b43294 100644 --- a/drivers/mfd/tc3589x.c +++ b/drivers/mfd/tc3589x.c | |||
@@ -262,8 +262,8 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x) | |||
262 | 262 | ||
263 | if (blocks & TC3589x_BLOCK_GPIO) { | 263 | if (blocks & TC3589x_BLOCK_GPIO) { |
264 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio, | 264 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio, |
265 | ARRAY_SIZE(tc3589x_dev_gpio), NULL, | 265 | ARRAY_SIZE(tc3589x_dev_gpio), NULL, |
266 | tc3589x->irq_base); | 266 | tc3589x->irq_base, NULL); |
267 | if (ret) { | 267 | if (ret) { |
268 | dev_err(tc3589x->dev, "failed to add gpio child\n"); | 268 | dev_err(tc3589x->dev, "failed to add gpio child\n"); |
269 | return ret; | 269 | return ret; |
@@ -273,8 +273,8 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x) | |||
273 | 273 | ||
274 | if (blocks & TC3589x_BLOCK_KEYPAD) { | 274 | if (blocks & TC3589x_BLOCK_KEYPAD) { |
275 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad, | 275 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad, |
276 | ARRAY_SIZE(tc3589x_dev_keypad), NULL, | 276 | ARRAY_SIZE(tc3589x_dev_keypad), NULL, |
277 | tc3589x->irq_base); | 277 | tc3589x->irq_base, NULL); |
278 | if (ret) { | 278 | if (ret) { |
279 | dev_err(tc3589x->dev, "failed to keypad child\n"); | 279 | dev_err(tc3589x->dev, "failed to keypad child\n"); |
280 | return ret; | 280 | return ret; |
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c index d20a284ad4ba..413c891102f8 100644 --- a/drivers/mfd/tc6387xb.c +++ b/drivers/mfd/tc6387xb.c | |||
@@ -192,7 +192,7 @@ static int __devinit tc6387xb_probe(struct platform_device *dev) | |||
192 | printk(KERN_INFO "Toshiba tc6387xb initialised\n"); | 192 | printk(KERN_INFO "Toshiba tc6387xb initialised\n"); |
193 | 193 | ||
194 | ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells, | 194 | ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells, |
195 | ARRAY_SIZE(tc6387xb_cells), iomem, irq); | 195 | ARRAY_SIZE(tc6387xb_cells), iomem, irq, NULL); |
196 | 196 | ||
197 | if (!ret) | 197 | if (!ret) |
198 | return 0; | 198 | return 0; |
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 9612264f0e6d..dcab026fcbb2 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c | |||
@@ -700,8 +700,8 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) | |||
700 | tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data); | 700 | tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data); |
701 | 701 | ||
702 | ret = mfd_add_devices(&dev->dev, dev->id, | 702 | ret = mfd_add_devices(&dev->dev, dev->id, |
703 | tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), | 703 | tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), |
704 | iomem, tcpd->irq_base); | 704 | iomem, tcpd->irq_base, NULL); |
705 | 705 | ||
706 | if (!ret) | 706 | if (!ret) |
707 | return 0; | 707 | return 0; |
diff --git a/drivers/mfd/ti-ssp.c b/drivers/mfd/ti-ssp.c index 4fb0e6c8e8fe..7c3675a74f93 100644 --- a/drivers/mfd/ti-ssp.c +++ b/drivers/mfd/ti-ssp.c | |||
@@ -412,7 +412,7 @@ static int __devinit ti_ssp_probe(struct platform_device *pdev) | |||
412 | cells[id].data_size = data->pdata_size; | 412 | cells[id].data_size = data->pdata_size; |
413 | } | 413 | } |
414 | 414 | ||
415 | error = mfd_add_devices(dev, 0, cells, 2, NULL, 0); | 415 | error = mfd_add_devices(dev, 0, cells, 2, NULL, 0, NULL); |
416 | if (error < 0) { | 416 | if (error < 0) { |
417 | dev_err(dev, "cannot add mfd cells\n"); | 417 | dev_err(dev, "cannot add mfd cells\n"); |
418 | goto error_enable; | 418 | goto error_enable; |
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c index a447f4ec11fb..cccc626c83c8 100644 --- a/drivers/mfd/timberdale.c +++ b/drivers/mfd/timberdale.c | |||
@@ -757,25 +757,25 @@ static int __devinit timb_probe(struct pci_dev *dev, | |||
757 | err = mfd_add_devices(&dev->dev, -1, | 757 | err = mfd_add_devices(&dev->dev, -1, |
758 | timberdale_cells_bar0_cfg0, | 758 | timberdale_cells_bar0_cfg0, |
759 | ARRAY_SIZE(timberdale_cells_bar0_cfg0), | 759 | ARRAY_SIZE(timberdale_cells_bar0_cfg0), |
760 | &dev->resource[0], msix_entries[0].vector); | 760 | &dev->resource[0], msix_entries[0].vector, NULL); |
761 | break; | 761 | break; |
762 | case TIMB_HW_VER1: | 762 | case TIMB_HW_VER1: |
763 | err = mfd_add_devices(&dev->dev, -1, | 763 | err = mfd_add_devices(&dev->dev, -1, |
764 | timberdale_cells_bar0_cfg1, | 764 | timberdale_cells_bar0_cfg1, |
765 | ARRAY_SIZE(timberdale_cells_bar0_cfg1), | 765 | ARRAY_SIZE(timberdale_cells_bar0_cfg1), |
766 | &dev->resource[0], msix_entries[0].vector); | 766 | &dev->resource[0], msix_entries[0].vector, NULL); |
767 | break; | 767 | break; |
768 | case TIMB_HW_VER2: | 768 | case TIMB_HW_VER2: |
769 | err = mfd_add_devices(&dev->dev, -1, | 769 | err = mfd_add_devices(&dev->dev, -1, |
770 | timberdale_cells_bar0_cfg2, | 770 | timberdale_cells_bar0_cfg2, |
771 | ARRAY_SIZE(timberdale_cells_bar0_cfg2), | 771 | ARRAY_SIZE(timberdale_cells_bar0_cfg2), |
772 | &dev->resource[0], msix_entries[0].vector); | 772 | &dev->resource[0], msix_entries[0].vector, NULL); |
773 | break; | 773 | break; |
774 | case TIMB_HW_VER3: | 774 | case TIMB_HW_VER3: |
775 | err = mfd_add_devices(&dev->dev, -1, | 775 | err = mfd_add_devices(&dev->dev, -1, |
776 | timberdale_cells_bar0_cfg3, | 776 | timberdale_cells_bar0_cfg3, |
777 | ARRAY_SIZE(timberdale_cells_bar0_cfg3), | 777 | ARRAY_SIZE(timberdale_cells_bar0_cfg3), |
778 | &dev->resource[0], msix_entries[0].vector); | 778 | &dev->resource[0], msix_entries[0].vector, NULL); |
779 | break; | 779 | break; |
780 | default: | 780 | default: |
781 | dev_err(&dev->dev, "Uknown IP setup: %d.%d.%d\n", | 781 | dev_err(&dev->dev, "Uknown IP setup: %d.%d.%d\n", |
@@ -792,7 +792,7 @@ static int __devinit timb_probe(struct pci_dev *dev, | |||
792 | 792 | ||
793 | err = mfd_add_devices(&dev->dev, 0, | 793 | err = mfd_add_devices(&dev->dev, 0, |
794 | timberdale_cells_bar1, ARRAY_SIZE(timberdale_cells_bar1), | 794 | timberdale_cells_bar1, ARRAY_SIZE(timberdale_cells_bar1), |
795 | &dev->resource[1], msix_entries[0].vector); | 795 | &dev->resource[1], msix_entries[0].vector, NULL); |
796 | if (err) { | 796 | if (err) { |
797 | dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err); | 797 | dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err); |
798 | goto err_mfd2; | 798 | goto err_mfd2; |
@@ -803,7 +803,7 @@ static int __devinit timb_probe(struct pci_dev *dev, | |||
803 | ((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER3)) { | 803 | ((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER3)) { |
804 | err = mfd_add_devices(&dev->dev, 1, timberdale_cells_bar2, | 804 | err = mfd_add_devices(&dev->dev, 1, timberdale_cells_bar2, |
805 | ARRAY_SIZE(timberdale_cells_bar2), | 805 | ARRAY_SIZE(timberdale_cells_bar2), |
806 | &dev->resource[2], msix_entries[0].vector); | 806 | &dev->resource[2], msix_entries[0].vector, NULL); |
807 | if (err) { | 807 | if (err) { |
808 | dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err); | 808 | dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err); |
809 | goto err_mfd2; | 809 | goto err_mfd2; |
diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c index a293b978e27c..14051bdc714b 100644 --- a/drivers/mfd/tps6105x.c +++ b/drivers/mfd/tps6105x.c | |||
@@ -188,7 +188,7 @@ static int __devinit tps6105x_probe(struct i2c_client *client, | |||
188 | } | 188 | } |
189 | 189 | ||
190 | ret = mfd_add_devices(&client->dev, 0, tps6105x_cells, | 190 | ret = mfd_add_devices(&client->dev, 0, tps6105x_cells, |
191 | ARRAY_SIZE(tps6105x_cells), NULL, 0); | 191 | ARRAY_SIZE(tps6105x_cells), NULL, 0, NULL); |
192 | if (ret) | 192 | if (ret) |
193 | goto fail; | 193 | goto fail; |
194 | 194 | ||
diff --git a/drivers/mfd/tps6507x.c b/drivers/mfd/tps6507x.c index 33ba7723c967..1b203499c744 100644 --- a/drivers/mfd/tps6507x.c +++ b/drivers/mfd/tps6507x.c | |||
@@ -100,7 +100,7 @@ static int tps6507x_i2c_probe(struct i2c_client *i2c, | |||
100 | 100 | ||
101 | ret = mfd_add_devices(tps6507x->dev, -1, | 101 | ret = mfd_add_devices(tps6507x->dev, -1, |
102 | tps6507x_devs, ARRAY_SIZE(tps6507x_devs), | 102 | tps6507x_devs, ARRAY_SIZE(tps6507x_devs), |
103 | NULL, 0); | 103 | NULL, 0, NULL); |
104 | 104 | ||
105 | if (ret < 0) | 105 | if (ret < 0) |
106 | goto err; | 106 | goto err; |
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c index 80e24f4b47bf..50fd87c87a1c 100644 --- a/drivers/mfd/tps65090.c +++ b/drivers/mfd/tps65090.c | |||
@@ -292,7 +292,7 @@ static int __devinit tps65090_i2c_probe(struct i2c_client *client, | |||
292 | } | 292 | } |
293 | 293 | ||
294 | ret = mfd_add_devices(tps65090->dev, -1, tps65090s, | 294 | ret = mfd_add_devices(tps65090->dev, -1, tps65090s, |
295 | ARRAY_SIZE(tps65090s), NULL, 0); | 295 | ARRAY_SIZE(tps65090s), NULL, 0, NULL); |
296 | if (ret) { | 296 | if (ret) { |
297 | dev_err(&client->dev, "add mfd devices failed with err: %d\n", | 297 | dev_err(&client->dev, "add mfd devices failed with err: %d\n", |
298 | ret); | 298 | ret); |
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c index 61c097a98f5d..a95e9421b735 100644 --- a/drivers/mfd/tps65217.c +++ b/drivers/mfd/tps65217.c | |||
@@ -24,11 +24,18 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/regmap.h> | 25 | #include <linux/regmap.h> |
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <linux/regulator/of_regulator.h> | 27 | #include <linux/of.h> |
28 | #include <linux/of_device.h> | ||
28 | 29 | ||
29 | #include <linux/mfd/core.h> | 30 | #include <linux/mfd/core.h> |
30 | #include <linux/mfd/tps65217.h> | 31 | #include <linux/mfd/tps65217.h> |
31 | 32 | ||
33 | static struct mfd_cell tps65217s[] = { | ||
34 | { | ||
35 | .name = "tps65217-pmic", | ||
36 | }, | ||
37 | }; | ||
38 | |||
32 | /** | 39 | /** |
33 | * tps65217_reg_read: Read a single tps65217 register. | 40 | * tps65217_reg_read: Read a single tps65217 register. |
34 | * | 41 | * |
@@ -133,83 +140,48 @@ int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg, | |||
133 | } | 140 | } |
134 | EXPORT_SYMBOL_GPL(tps65217_clear_bits); | 141 | EXPORT_SYMBOL_GPL(tps65217_clear_bits); |
135 | 142 | ||
136 | #ifdef CONFIG_OF | ||
137 | static struct of_regulator_match reg_matches[] = { | ||
138 | { .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 }, | ||
139 | { .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 }, | ||
140 | { .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 }, | ||
141 | { .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 }, | ||
142 | { .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 }, | ||
143 | { .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 }, | ||
144 | { .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 }, | ||
145 | }; | ||
146 | |||
147 | static struct tps65217_board *tps65217_parse_dt(struct i2c_client *client) | ||
148 | { | ||
149 | struct device_node *node = client->dev.of_node; | ||
150 | struct tps65217_board *pdata; | ||
151 | struct device_node *regs; | ||
152 | int count = ARRAY_SIZE(reg_matches); | ||
153 | int ret, i; | ||
154 | |||
155 | regs = of_find_node_by_name(node, "regulators"); | ||
156 | if (!regs) | ||
157 | return NULL; | ||
158 | |||
159 | ret = of_regulator_match(&client->dev, regs, reg_matches, count); | ||
160 | of_node_put(regs); | ||
161 | if ((ret < 0) || (ret > count)) | ||
162 | return NULL; | ||
163 | |||
164 | count = ret; | ||
165 | pdata = devm_kzalloc(&client->dev, count * sizeof(*pdata), GFP_KERNEL); | ||
166 | if (!pdata) | ||
167 | return NULL; | ||
168 | |||
169 | for (i = 0; i < count; i++) { | ||
170 | if (!reg_matches[i].init_data || !reg_matches[i].of_node) | ||
171 | continue; | ||
172 | |||
173 | pdata->tps65217_init_data[i] = reg_matches[i].init_data; | ||
174 | pdata->of_node[i] = reg_matches[i].of_node; | ||
175 | } | ||
176 | |||
177 | return pdata; | ||
178 | } | ||
179 | |||
180 | static struct of_device_id tps65217_of_match[] = { | ||
181 | { .compatible = "ti,tps65217", }, | ||
182 | { }, | ||
183 | }; | ||
184 | #else | ||
185 | static struct tps65217_board *tps65217_parse_dt(struct i2c_client *client) | ||
186 | { | ||
187 | return NULL; | ||
188 | } | ||
189 | #endif | ||
190 | |||
191 | static struct regmap_config tps65217_regmap_config = { | 143 | static struct regmap_config tps65217_regmap_config = { |
192 | .reg_bits = 8, | 144 | .reg_bits = 8, |
193 | .val_bits = 8, | 145 | .val_bits = 8, |
194 | }; | 146 | }; |
195 | 147 | ||
148 | static const struct of_device_id tps65217_of_match[] = { | ||
149 | { .compatible = "ti,tps65217", .data = (void *)TPS65217 }, | ||
150 | { /* sentinel */ }, | ||
151 | }; | ||
152 | |||
196 | static int __devinit tps65217_probe(struct i2c_client *client, | 153 | static int __devinit tps65217_probe(struct i2c_client *client, |
197 | const struct i2c_device_id *ids) | 154 | const struct i2c_device_id *ids) |
198 | { | 155 | { |
199 | struct tps65217 *tps; | 156 | struct tps65217 *tps; |
200 | struct regulator_init_data *reg_data; | ||
201 | struct tps65217_board *pdata = client->dev.platform_data; | ||
202 | int i, ret; | ||
203 | unsigned int version; | 157 | unsigned int version; |
158 | unsigned int chip_id = ids->driver_data; | ||
159 | const struct of_device_id *match; | ||
160 | int ret; | ||
204 | 161 | ||
205 | if (!pdata && client->dev.of_node) | 162 | if (client->dev.of_node) { |
206 | pdata = tps65217_parse_dt(client); | 163 | match = of_match_device(tps65217_of_match, &client->dev); |
164 | if (!match) { | ||
165 | dev_err(&client->dev, | ||
166 | "Failed to find matching dt id\n"); | ||
167 | return -EINVAL; | ||
168 | } | ||
169 | chip_id = (unsigned int)match->data; | ||
170 | } | ||
171 | |||
172 | if (!chip_id) { | ||
173 | dev_err(&client->dev, "id is null.\n"); | ||
174 | return -ENODEV; | ||
175 | } | ||
207 | 176 | ||
208 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); | 177 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); |
209 | if (!tps) | 178 | if (!tps) |
210 | return -ENOMEM; | 179 | return -ENOMEM; |
211 | 180 | ||
212 | tps->pdata = pdata; | 181 | i2c_set_clientdata(client, tps); |
182 | tps->dev = &client->dev; | ||
183 | tps->id = chip_id; | ||
184 | |||
213 | tps->regmap = devm_regmap_init_i2c(client, &tps65217_regmap_config); | 185 | tps->regmap = devm_regmap_init_i2c(client, &tps65217_regmap_config); |
214 | if (IS_ERR(tps->regmap)) { | 186 | if (IS_ERR(tps->regmap)) { |
215 | ret = PTR_ERR(tps->regmap); | 187 | ret = PTR_ERR(tps->regmap); |
@@ -218,8 +190,12 @@ static int __devinit tps65217_probe(struct i2c_client *client, | |||
218 | return ret; | 190 | return ret; |
219 | } | 191 | } |
220 | 192 | ||
221 | i2c_set_clientdata(client, tps); | 193 | ret = mfd_add_devices(tps->dev, -1, tps65217s, |
222 | tps->dev = &client->dev; | 194 | ARRAY_SIZE(tps65217s), NULL, 0, NULL); |
195 | if (ret < 0) { | ||
196 | dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret); | ||
197 | return ret; | ||
198 | } | ||
223 | 199 | ||
224 | ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version); | 200 | ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version); |
225 | if (ret < 0) { | 201 | if (ret < 0) { |
@@ -232,41 +208,21 @@ static int __devinit tps65217_probe(struct i2c_client *client, | |||
232 | (version & TPS65217_CHIPID_CHIP_MASK) >> 4, | 208 | (version & TPS65217_CHIPID_CHIP_MASK) >> 4, |
233 | version & TPS65217_CHIPID_REV_MASK); | 209 | version & TPS65217_CHIPID_REV_MASK); |
234 | 210 | ||
235 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { | ||
236 | struct platform_device *pdev; | ||
237 | |||
238 | pdev = platform_device_alloc("tps65217-pmic", i); | ||
239 | if (!pdev) { | ||
240 | dev_err(tps->dev, "Cannot create regulator %d\n", i); | ||
241 | continue; | ||
242 | } | ||
243 | |||
244 | pdev->dev.parent = tps->dev; | ||
245 | pdev->dev.of_node = pdata->of_node[i]; | ||
246 | reg_data = pdata->tps65217_init_data[i]; | ||
247 | platform_device_add_data(pdev, reg_data, sizeof(*reg_data)); | ||
248 | tps->regulator_pdev[i] = pdev; | ||
249 | |||
250 | platform_device_add(pdev); | ||
251 | } | ||
252 | |||
253 | return 0; | 211 | return 0; |
254 | } | 212 | } |
255 | 213 | ||
256 | static int __devexit tps65217_remove(struct i2c_client *client) | 214 | static int __devexit tps65217_remove(struct i2c_client *client) |
257 | { | 215 | { |
258 | struct tps65217 *tps = i2c_get_clientdata(client); | 216 | struct tps65217 *tps = i2c_get_clientdata(client); |
259 | int i; | ||
260 | 217 | ||
261 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) | 218 | mfd_remove_devices(tps->dev); |
262 | platform_device_unregister(tps->regulator_pdev[i]); | ||
263 | 219 | ||
264 | return 0; | 220 | return 0; |
265 | } | 221 | } |
266 | 222 | ||
267 | static const struct i2c_device_id tps65217_id_table[] = { | 223 | static const struct i2c_device_id tps65217_id_table[] = { |
268 | {"tps65217", 0xF0}, | 224 | {"tps65217", TPS65217}, |
269 | {/* end of list */} | 225 | { /* sentinel */ } |
270 | }; | 226 | }; |
271 | MODULE_DEVICE_TABLE(i2c, tps65217_id_table); | 227 | MODULE_DEVICE_TABLE(i2c, tps65217_id_table); |
272 | 228 | ||
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 353c34812120..5f58370ccf55 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c | |||
@@ -493,7 +493,8 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client, | |||
493 | } | 493 | } |
494 | 494 | ||
495 | ret = mfd_add_devices(tps6586x->dev, -1, | 495 | ret = mfd_add_devices(tps6586x->dev, -1, |
496 | tps6586x_cell, ARRAY_SIZE(tps6586x_cell), NULL, 0); | 496 | tps6586x_cell, ARRAY_SIZE(tps6586x_cell), |
497 | NULL, 0, NULL); | ||
497 | if (ret < 0) { | 498 | if (ret < 0) { |
498 | dev_err(&client->dev, "mfd_add_devices failed: %d\n", ret); | 499 | dev_err(&client->dev, "mfd_add_devices failed: %d\n", ret); |
499 | goto err_mfd_add; | 500 | goto err_mfd_add; |
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 1c563792c777..d3ce4d569deb 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c | |||
@@ -254,7 +254,7 @@ static __devinit int tps65910_i2c_probe(struct i2c_client *i2c, | |||
254 | 254 | ||
255 | ret = mfd_add_devices(tps65910->dev, -1, | 255 | ret = mfd_add_devices(tps65910->dev, -1, |
256 | tps65910s, ARRAY_SIZE(tps65910s), | 256 | tps65910s, ARRAY_SIZE(tps65910s), |
257 | NULL, 0); | 257 | NULL, 0, NULL); |
258 | if (ret < 0) { | 258 | if (ret < 0) { |
259 | dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret); | 259 | dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret); |
260 | return ret; | 260 | return ret; |
diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c index 74fd8cb5f372..4658b5bdcd84 100644 --- a/drivers/mfd/tps65912-core.c +++ b/drivers/mfd/tps65912-core.c | |||
@@ -146,7 +146,7 @@ int tps65912_device_init(struct tps65912 *tps65912) | |||
146 | 146 | ||
147 | ret = mfd_add_devices(tps65912->dev, -1, | 147 | ret = mfd_add_devices(tps65912->dev, -1, |
148 | tps65912s, ARRAY_SIZE(tps65912s), | 148 | tps65912s, ARRAY_SIZE(tps65912s), |
149 | NULL, 0); | 149 | NULL, 0, NULL); |
150 | if (ret < 0) | 150 | if (ret < 0) |
151 | goto err; | 151 | goto err; |
152 | 152 | ||
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 1c32afed28aa..f162b68e78a8 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c | |||
@@ -552,6 +552,38 @@ int twl_get_version(void) | |||
552 | } | 552 | } |
553 | EXPORT_SYMBOL_GPL(twl_get_version); | 553 | EXPORT_SYMBOL_GPL(twl_get_version); |
554 | 554 | ||
555 | /** | ||
556 | * twl_get_hfclk_rate - API to get TWL external HFCLK clock rate. | ||
557 | * | ||
558 | * Api to get the TWL HFCLK rate based on BOOT_CFG register. | ||
559 | */ | ||
560 | int twl_get_hfclk_rate(void) | ||
561 | { | ||
562 | u8 ctrl; | ||
563 | int rate; | ||
564 | |||
565 | twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &ctrl, R_CFG_BOOT); | ||
566 | |||
567 | switch (ctrl & 0x3) { | ||
568 | case HFCLK_FREQ_19p2_MHZ: | ||
569 | rate = 19200000; | ||
570 | break; | ||
571 | case HFCLK_FREQ_26_MHZ: | ||
572 | rate = 26000000; | ||
573 | break; | ||
574 | case HFCLK_FREQ_38p4_MHZ: | ||
575 | rate = 38400000; | ||
576 | break; | ||
577 | default: | ||
578 | pr_err("TWL4030: HFCLK is not configured\n"); | ||
579 | rate = -EINVAL; | ||
580 | break; | ||
581 | } | ||
582 | |||
583 | return rate; | ||
584 | } | ||
585 | EXPORT_SYMBOL_GPL(twl_get_hfclk_rate); | ||
586 | |||
555 | static struct device * | 587 | static struct device * |
556 | add_numbered_child(unsigned chip, const char *name, int num, | 588 | add_numbered_child(unsigned chip, const char *name, int num, |
557 | void *pdata, unsigned pdata_len, | 589 | void *pdata, unsigned pdata_len, |
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c index 838ce4eb444e..5c11acf9e0fd 100644 --- a/drivers/mfd/twl4030-audio.c +++ b/drivers/mfd/twl4030-audio.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/of.h> | ||
32 | #include <linux/of_platform.h> | ||
31 | #include <linux/i2c/twl.h> | 33 | #include <linux/i2c/twl.h> |
32 | #include <linux/mfd/core.h> | 34 | #include <linux/mfd/core.h> |
33 | #include <linux/mfd/twl4030-audio.h> | 35 | #include <linux/mfd/twl4030-audio.h> |
@@ -156,47 +158,70 @@ unsigned int twl4030_audio_get_mclk(void) | |||
156 | } | 158 | } |
157 | EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk); | 159 | EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk); |
158 | 160 | ||
161 | static bool twl4030_audio_has_codec(struct twl4030_audio_data *pdata, | ||
162 | struct device_node *node) | ||
163 | { | ||
164 | if (pdata && pdata->codec) | ||
165 | return true; | ||
166 | |||
167 | if (of_find_node_by_name(node, "codec")) | ||
168 | return true; | ||
169 | |||
170 | return false; | ||
171 | } | ||
172 | |||
173 | static bool twl4030_audio_has_vibra(struct twl4030_audio_data *pdata, | ||
174 | struct device_node *node) | ||
175 | { | ||
176 | int vibra; | ||
177 | |||
178 | if (pdata && pdata->vibra) | ||
179 | return true; | ||
180 | |||
181 | if (!of_property_read_u32(node, "ti,enable-vibra", &vibra) && vibra) | ||
182 | return true; | ||
183 | |||
184 | return false; | ||
185 | } | ||
186 | |||
159 | static int __devinit twl4030_audio_probe(struct platform_device *pdev) | 187 | static int __devinit twl4030_audio_probe(struct platform_device *pdev) |
160 | { | 188 | { |
161 | struct twl4030_audio *audio; | 189 | struct twl4030_audio *audio; |
162 | struct twl4030_audio_data *pdata = pdev->dev.platform_data; | 190 | struct twl4030_audio_data *pdata = pdev->dev.platform_data; |
191 | struct device_node *node = pdev->dev.of_node; | ||
163 | struct mfd_cell *cell = NULL; | 192 | struct mfd_cell *cell = NULL; |
164 | int ret, childs = 0; | 193 | int ret, childs = 0; |
165 | u8 val; | 194 | u8 val; |
166 | 195 | ||
167 | if (!pdata) { | 196 | if (!pdata && !node) { |
168 | dev_err(&pdev->dev, "Platform data is missing\n"); | 197 | dev_err(&pdev->dev, "Platform data is missing\n"); |
169 | return -EINVAL; | 198 | return -EINVAL; |
170 | } | 199 | } |
171 | 200 | ||
201 | audio = devm_kzalloc(&pdev->dev, sizeof(struct twl4030_audio), | ||
202 | GFP_KERNEL); | ||
203 | if (!audio) | ||
204 | return -ENOMEM; | ||
205 | |||
206 | mutex_init(&audio->mutex); | ||
207 | audio->audio_mclk = twl_get_hfclk_rate(); | ||
208 | |||
172 | /* Configure APLL_INFREQ and disable APLL if enabled */ | 209 | /* Configure APLL_INFREQ and disable APLL if enabled */ |
173 | val = 0; | 210 | switch (audio->audio_mclk) { |
174 | switch (pdata->audio_mclk) { | ||
175 | case 19200000: | 211 | case 19200000: |
176 | val |= TWL4030_APLL_INFREQ_19200KHZ; | 212 | val = TWL4030_APLL_INFREQ_19200KHZ; |
177 | break; | 213 | break; |
178 | case 26000000: | 214 | case 26000000: |
179 | val |= TWL4030_APLL_INFREQ_26000KHZ; | 215 | val = TWL4030_APLL_INFREQ_26000KHZ; |
180 | break; | 216 | break; |
181 | case 38400000: | 217 | case 38400000: |
182 | val |= TWL4030_APLL_INFREQ_38400KHZ; | 218 | val = TWL4030_APLL_INFREQ_38400KHZ; |
183 | break; | 219 | break; |
184 | default: | 220 | default: |
185 | dev_err(&pdev->dev, "Invalid audio_mclk\n"); | 221 | dev_err(&pdev->dev, "Invalid audio_mclk\n"); |
186 | return -EINVAL; | 222 | return -EINVAL; |
187 | } | 223 | } |
188 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | 224 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, val, TWL4030_REG_APLL_CTL); |
189 | val, TWL4030_REG_APLL_CTL); | ||
190 | |||
191 | audio = kzalloc(sizeof(struct twl4030_audio), GFP_KERNEL); | ||
192 | if (!audio) | ||
193 | return -ENOMEM; | ||
194 | |||
195 | platform_set_drvdata(pdev, audio); | ||
196 | |||
197 | twl4030_audio_dev = pdev; | ||
198 | mutex_init(&audio->mutex); | ||
199 | audio->audio_mclk = pdata->audio_mclk; | ||
200 | 225 | ||
201 | /* Codec power */ | 226 | /* Codec power */ |
202 | audio->resource[TWL4030_AUDIO_RES_POWER].reg = TWL4030_REG_CODEC_MODE; | 227 | audio->resource[TWL4030_AUDIO_RES_POWER].reg = TWL4030_REG_CODEC_MODE; |
@@ -206,62 +231,72 @@ static int __devinit twl4030_audio_probe(struct platform_device *pdev) | |||
206 | audio->resource[TWL4030_AUDIO_RES_APLL].reg = TWL4030_REG_APLL_CTL; | 231 | audio->resource[TWL4030_AUDIO_RES_APLL].reg = TWL4030_REG_APLL_CTL; |
207 | audio->resource[TWL4030_AUDIO_RES_APLL].mask = TWL4030_APLL_EN; | 232 | audio->resource[TWL4030_AUDIO_RES_APLL].mask = TWL4030_APLL_EN; |
208 | 233 | ||
209 | if (pdata->codec) { | 234 | if (twl4030_audio_has_codec(pdata, node)) { |
210 | cell = &audio->cells[childs]; | 235 | cell = &audio->cells[childs]; |
211 | cell->name = "twl4030-codec"; | 236 | cell->name = "twl4030-codec"; |
212 | cell->platform_data = pdata->codec; | 237 | if (pdata) { |
213 | cell->pdata_size = sizeof(*pdata->codec); | 238 | cell->platform_data = pdata->codec; |
239 | cell->pdata_size = sizeof(*pdata->codec); | ||
240 | } | ||
214 | childs++; | 241 | childs++; |
215 | } | 242 | } |
216 | if (pdata->vibra) { | 243 | if (twl4030_audio_has_vibra(pdata, node)) { |
217 | cell = &audio->cells[childs]; | 244 | cell = &audio->cells[childs]; |
218 | cell->name = "twl4030-vibra"; | 245 | cell->name = "twl4030-vibra"; |
219 | cell->platform_data = pdata->vibra; | 246 | if (pdata) { |
220 | cell->pdata_size = sizeof(*pdata->vibra); | 247 | cell->platform_data = pdata->vibra; |
248 | cell->pdata_size = sizeof(*pdata->vibra); | ||
249 | } | ||
221 | childs++; | 250 | childs++; |
222 | } | 251 | } |
223 | 252 | ||
253 | platform_set_drvdata(pdev, audio); | ||
254 | twl4030_audio_dev = pdev; | ||
255 | |||
224 | if (childs) | 256 | if (childs) |
225 | ret = mfd_add_devices(&pdev->dev, pdev->id, audio->cells, | 257 | ret = mfd_add_devices(&pdev->dev, pdev->id, audio->cells, |
226 | childs, NULL, 0); | 258 | childs, NULL, 0, NULL); |
227 | else { | 259 | else { |
228 | dev_err(&pdev->dev, "No platform data found for childs\n"); | 260 | dev_err(&pdev->dev, "No platform data found for childs\n"); |
229 | ret = -ENODEV; | 261 | ret = -ENODEV; |
230 | } | 262 | } |
231 | 263 | ||
232 | if (!ret) | 264 | if (ret) { |
233 | return 0; | 265 | platform_set_drvdata(pdev, NULL); |
266 | twl4030_audio_dev = NULL; | ||
267 | } | ||
234 | 268 | ||
235 | platform_set_drvdata(pdev, NULL); | ||
236 | kfree(audio); | ||
237 | twl4030_audio_dev = NULL; | ||
238 | return ret; | 269 | return ret; |
239 | } | 270 | } |
240 | 271 | ||
241 | static int __devexit twl4030_audio_remove(struct platform_device *pdev) | 272 | static int __devexit twl4030_audio_remove(struct platform_device *pdev) |
242 | { | 273 | { |
243 | struct twl4030_audio *audio = platform_get_drvdata(pdev); | ||
244 | |||
245 | mfd_remove_devices(&pdev->dev); | 274 | mfd_remove_devices(&pdev->dev); |
246 | platform_set_drvdata(pdev, NULL); | 275 | platform_set_drvdata(pdev, NULL); |
247 | kfree(audio); | ||
248 | twl4030_audio_dev = NULL; | 276 | twl4030_audio_dev = NULL; |
249 | 277 | ||
250 | return 0; | 278 | return 0; |
251 | } | 279 | } |
252 | 280 | ||
253 | MODULE_ALIAS("platform:twl4030-audio"); | 281 | static const struct of_device_id twl4030_audio_of_match[] = { |
282 | {.compatible = "ti,twl4030-audio", }, | ||
283 | { }, | ||
284 | }; | ||
285 | MODULE_DEVICE_TABLE(of, twl4030_audio_of_match); | ||
254 | 286 | ||
255 | static struct platform_driver twl4030_audio_driver = { | 287 | static struct platform_driver twl4030_audio_driver = { |
256 | .probe = twl4030_audio_probe, | ||
257 | .remove = __devexit_p(twl4030_audio_remove), | ||
258 | .driver = { | 288 | .driver = { |
259 | .owner = THIS_MODULE, | 289 | .owner = THIS_MODULE, |
260 | .name = "twl4030-audio", | 290 | .name = "twl4030-audio", |
291 | .of_match_table = twl4030_audio_of_match, | ||
261 | }, | 292 | }, |
293 | .probe = twl4030_audio_probe, | ||
294 | .remove = __devexit_p(twl4030_audio_remove), | ||
262 | }; | 295 | }; |
263 | 296 | ||
264 | module_platform_driver(twl4030_audio_driver); | 297 | module_platform_driver(twl4030_audio_driver); |
265 | 298 | ||
266 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); | 299 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); |
300 | MODULE_DESCRIPTION("TWL4030 audio block MFD driver"); | ||
267 | MODULE_LICENSE("GPL"); | 301 | MODULE_LICENSE("GPL"); |
302 | MODULE_ALIAS("platform:twl4030-audio"); | ||
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c index b0fad0ffca56..3dca5c195a20 100644 --- a/drivers/mfd/twl6040-core.c +++ b/drivers/mfd/twl6040-core.c | |||
@@ -632,7 +632,7 @@ static int __devinit twl6040_probe(struct i2c_client *client, | |||
632 | } | 632 | } |
633 | 633 | ||
634 | ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, | 634 | ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, |
635 | NULL, 0); | 635 | NULL, 0, NULL); |
636 | if (ret) | 636 | if (ret) |
637 | goto mfd_err; | 637 | goto mfd_err; |
638 | 638 | ||
diff --git a/drivers/mfd/vx855.c b/drivers/mfd/vx855.c index 872aff21e4be..b9a636d44c7f 100644 --- a/drivers/mfd/vx855.c +++ b/drivers/mfd/vx855.c | |||
@@ -102,7 +102,7 @@ static __devinit int vx855_probe(struct pci_dev *pdev, | |||
102 | vx855_gpio_resources[1].end = vx855_gpio_resources[1].start + 3; | 102 | vx855_gpio_resources[1].end = vx855_gpio_resources[1].start + 3; |
103 | 103 | ||
104 | ret = mfd_add_devices(&pdev->dev, -1, vx855_cells, ARRAY_SIZE(vx855_cells), | 104 | ret = mfd_add_devices(&pdev->dev, -1, vx855_cells, ARRAY_SIZE(vx855_cells), |
105 | NULL, 0); | 105 | NULL, 0, NULL); |
106 | 106 | ||
107 | /* we always return -ENODEV here in order to enable other | 107 | /* we always return -ENODEV here in order to enable other |
108 | * drivers like old, not-yet-platform_device ported i2c-viapro */ | 108 | * drivers like old, not-yet-platform_device ported i2c-viapro */ |
diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c index f39b756df561..86e0e4309fc2 100644 --- a/drivers/mfd/wl1273-core.c +++ b/drivers/mfd/wl1273-core.c | |||
@@ -241,7 +241,7 @@ static int __devinit wl1273_core_probe(struct i2c_client *client, | |||
241 | __func__, children); | 241 | __func__, children); |
242 | 242 | ||
243 | r = mfd_add_devices(&client->dev, -1, core->cells, | 243 | r = mfd_add_devices(&client->dev, -1, core->cells, |
244 | children, NULL, 0); | 244 | children, NULL, 0, NULL); |
245 | if (r) | 245 | if (r) |
246 | goto err; | 246 | goto err; |
247 | 247 | ||
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 946698fd2dc6..301731035940 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c | |||
@@ -1813,27 +1813,27 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1813 | case WM8310: | 1813 | case WM8310: |
1814 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1814 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1815 | wm8310_devs, ARRAY_SIZE(wm8310_devs), | 1815 | wm8310_devs, ARRAY_SIZE(wm8310_devs), |
1816 | NULL, 0); | 1816 | NULL, 0, NULL); |
1817 | break; | 1817 | break; |
1818 | 1818 | ||
1819 | case WM8311: | 1819 | case WM8311: |
1820 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1820 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1821 | wm8311_devs, ARRAY_SIZE(wm8311_devs), | 1821 | wm8311_devs, ARRAY_SIZE(wm8311_devs), |
1822 | NULL, 0); | 1822 | NULL, 0, NULL); |
1823 | if (!pdata || !pdata->disable_touch) | 1823 | if (!pdata || !pdata->disable_touch) |
1824 | mfd_add_devices(wm831x->dev, wm831x_num, | 1824 | mfd_add_devices(wm831x->dev, wm831x_num, |
1825 | touch_devs, ARRAY_SIZE(touch_devs), | 1825 | touch_devs, ARRAY_SIZE(touch_devs), |
1826 | NULL, 0); | 1826 | NULL, 0, NULL); |
1827 | break; | 1827 | break; |
1828 | 1828 | ||
1829 | case WM8312: | 1829 | case WM8312: |
1830 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1830 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1831 | wm8312_devs, ARRAY_SIZE(wm8312_devs), | 1831 | wm8312_devs, ARRAY_SIZE(wm8312_devs), |
1832 | NULL, 0); | 1832 | NULL, 0, NULL); |
1833 | if (!pdata || !pdata->disable_touch) | 1833 | if (!pdata || !pdata->disable_touch) |
1834 | mfd_add_devices(wm831x->dev, wm831x_num, | 1834 | mfd_add_devices(wm831x->dev, wm831x_num, |
1835 | touch_devs, ARRAY_SIZE(touch_devs), | 1835 | touch_devs, ARRAY_SIZE(touch_devs), |
1836 | NULL, 0); | 1836 | NULL, 0, NULL); |
1837 | break; | 1837 | break; |
1838 | 1838 | ||
1839 | case WM8320: | 1839 | case WM8320: |
@@ -1842,7 +1842,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1842 | case WM8326: | 1842 | case WM8326: |
1843 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1843 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1844 | wm8320_devs, ARRAY_SIZE(wm8320_devs), | 1844 | wm8320_devs, ARRAY_SIZE(wm8320_devs), |
1845 | NULL, 0); | 1845 | NULL, 0, NULL); |
1846 | break; | 1846 | break; |
1847 | 1847 | ||
1848 | default: | 1848 | default: |
@@ -1867,7 +1867,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1867 | if (ret & WM831X_XTAL_ENA) { | 1867 | if (ret & WM831X_XTAL_ENA) { |
1868 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1868 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1869 | rtc_devs, ARRAY_SIZE(rtc_devs), | 1869 | rtc_devs, ARRAY_SIZE(rtc_devs), |
1870 | NULL, 0); | 1870 | NULL, 0, NULL); |
1871 | if (ret != 0) { | 1871 | if (ret != 0) { |
1872 | dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret); | 1872 | dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret); |
1873 | goto err_irq; | 1873 | goto err_irq; |
@@ -1880,7 +1880,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1880 | /* Treat errors as non-critical */ | 1880 | /* Treat errors as non-critical */ |
1881 | ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs, | 1881 | ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs, |
1882 | ARRAY_SIZE(backlight_devs), NULL, | 1882 | ARRAY_SIZE(backlight_devs), NULL, |
1883 | 0); | 1883 | 0, NULL); |
1884 | if (ret < 0) | 1884 | if (ret < 0) |
1885 | dev_err(wm831x->dev, "Failed to add backlight: %d\n", | 1885 | dev_err(wm831x->dev, "Failed to add backlight: %d\n", |
1886 | ret); | 1886 | ret); |
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c index 4b7d378551d5..639ca359242f 100644 --- a/drivers/mfd/wm8400-core.c +++ b/drivers/mfd/wm8400-core.c | |||
@@ -70,7 +70,7 @@ static int wm8400_register_codec(struct wm8400 *wm8400) | |||
70 | .pdata_size = sizeof(*wm8400), | 70 | .pdata_size = sizeof(*wm8400), |
71 | }; | 71 | }; |
72 | 72 | ||
73 | return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0); | 73 | return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0, NULL); |
74 | } | 74 | } |
75 | 75 | ||
76 | /* | 76 | /* |
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index eec74aa55fdf..2febf88cfce8 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
@@ -414,7 +414,7 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
414 | ret = mfd_add_devices(wm8994->dev, -1, | 414 | ret = mfd_add_devices(wm8994->dev, -1, |
415 | wm8994_regulator_devs, | 415 | wm8994_regulator_devs, |
416 | ARRAY_SIZE(wm8994_regulator_devs), | 416 | ARRAY_SIZE(wm8994_regulator_devs), |
417 | NULL, 0); | 417 | NULL, 0, NULL); |
418 | if (ret != 0) { | 418 | if (ret != 0) { |
419 | dev_err(wm8994->dev, "Failed to add children: %d\n", ret); | 419 | dev_err(wm8994->dev, "Failed to add children: %d\n", ret); |
420 | goto err; | 420 | goto err; |
@@ -648,7 +648,7 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
648 | 648 | ||
649 | ret = mfd_add_devices(wm8994->dev, -1, | 649 | ret = mfd_add_devices(wm8994->dev, -1, |
650 | wm8994_devs, ARRAY_SIZE(wm8994_devs), | 650 | wm8994_devs, ARRAY_SIZE(wm8994_devs), |
651 | NULL, 0); | 651 | NULL, 0, NULL); |
652 | if (ret != 0) { | 652 | if (ret != 0) { |
653 | dev_err(wm8994->dev, "Failed to add children: %d\n", ret); | 653 | dev_err(wm8994->dev, "Failed to add children: %d\n", ret); |
654 | goto err_irq; | 654 | goto err_irq; |
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index f1c84decb192..172a768036d8 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -1411,7 +1411,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
1411 | /* complete ongoing async transfer before issuing discard */ | 1411 | /* complete ongoing async transfer before issuing discard */ |
1412 | if (card->host->areq) | 1412 | if (card->host->areq) |
1413 | mmc_blk_issue_rw_rq(mq, NULL); | 1413 | mmc_blk_issue_rw_rq(mq, NULL); |
1414 | if (req->cmd_flags & REQ_SECURE) | 1414 | if (req->cmd_flags & REQ_SECURE && |
1415 | !(card->quirks & MMC_QUIRK_SEC_ERASE_TRIM_BROKEN)) | ||
1415 | ret = mmc_blk_issue_secdiscard_rq(mq, req); | 1416 | ret = mmc_blk_issue_secdiscard_rq(mq, req); |
1416 | else | 1417 | else |
1417 | ret = mmc_blk_issue_discard_rq(mq, req); | 1418 | ret = mmc_blk_issue_discard_rq(mq, req); |
@@ -1716,6 +1717,7 @@ force_ro_fail: | |||
1716 | #define CID_MANFID_SANDISK 0x2 | 1717 | #define CID_MANFID_SANDISK 0x2 |
1717 | #define CID_MANFID_TOSHIBA 0x11 | 1718 | #define CID_MANFID_TOSHIBA 0x11 |
1718 | #define CID_MANFID_MICRON 0x13 | 1719 | #define CID_MANFID_MICRON 0x13 |
1720 | #define CID_MANFID_SAMSUNG 0x15 | ||
1719 | 1721 | ||
1720 | static const struct mmc_fixup blk_fixups[] = | 1722 | static const struct mmc_fixup blk_fixups[] = |
1721 | { | 1723 | { |
@@ -1752,6 +1754,28 @@ static const struct mmc_fixup blk_fixups[] = | |||
1752 | MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, | 1754 | MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, |
1753 | MMC_QUIRK_LONG_READ_TIME), | 1755 | MMC_QUIRK_LONG_READ_TIME), |
1754 | 1756 | ||
1757 | /* | ||
1758 | * On these Samsung MoviNAND parts, performing secure erase or | ||
1759 | * secure trim can result in unrecoverable corruption due to a | ||
1760 | * firmware bug. | ||
1761 | */ | ||
1762 | MMC_FIXUP("M8G2FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1763 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1764 | MMC_FIXUP("MAG4FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1765 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1766 | MMC_FIXUP("MBG8FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1767 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1768 | MMC_FIXUP("MCGAFA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1769 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1770 | MMC_FIXUP("VAL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1771 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1772 | MMC_FIXUP("VYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1773 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1774 | MMC_FIXUP("KYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1775 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1776 | MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1777 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1778 | |||
1755 | END_FIXUP | 1779 | END_FIXUP |
1756 | }; | 1780 | }; |
1757 | 1781 | ||
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 322412cec4ee..a53c7c478e05 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
@@ -81,6 +81,7 @@ struct atmel_mci_caps { | |||
81 | bool has_bad_data_ordering; | 81 | bool has_bad_data_ordering; |
82 | bool need_reset_after_xfer; | 82 | bool need_reset_after_xfer; |
83 | bool need_blksz_mul_4; | 83 | bool need_blksz_mul_4; |
84 | bool need_notbusy_for_read_ops; | ||
84 | }; | 85 | }; |
85 | 86 | ||
86 | struct atmel_mci_dma { | 87 | struct atmel_mci_dma { |
@@ -1625,7 +1626,8 @@ static void atmci_tasklet_func(unsigned long priv) | |||
1625 | __func__); | 1626 | __func__); |
1626 | atmci_set_completed(host, EVENT_XFER_COMPLETE); | 1627 | atmci_set_completed(host, EVENT_XFER_COMPLETE); |
1627 | 1628 | ||
1628 | if (host->data->flags & MMC_DATA_WRITE) { | 1629 | if (host->caps.need_notbusy_for_read_ops || |
1630 | (host->data->flags & MMC_DATA_WRITE)) { | ||
1629 | atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY); | 1631 | atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY); |
1630 | state = STATE_WAITING_NOTBUSY; | 1632 | state = STATE_WAITING_NOTBUSY; |
1631 | } else if (host->mrq->stop) { | 1633 | } else if (host->mrq->stop) { |
@@ -2218,6 +2220,7 @@ static void __init atmci_get_cap(struct atmel_mci *host) | |||
2218 | host->caps.has_bad_data_ordering = 1; | 2220 | host->caps.has_bad_data_ordering = 1; |
2219 | host->caps.need_reset_after_xfer = 1; | 2221 | host->caps.need_reset_after_xfer = 1; |
2220 | host->caps.need_blksz_mul_4 = 1; | 2222 | host->caps.need_blksz_mul_4 = 1; |
2223 | host->caps.need_notbusy_for_read_ops = 0; | ||
2221 | 2224 | ||
2222 | /* keep only major version number */ | 2225 | /* keep only major version number */ |
2223 | switch (version & 0xf00) { | 2226 | switch (version & 0xf00) { |
@@ -2238,6 +2241,7 @@ static void __init atmci_get_cap(struct atmel_mci *host) | |||
2238 | case 0x200: | 2241 | case 0x200: |
2239 | host->caps.has_rwproof = 1; | 2242 | host->caps.has_rwproof = 1; |
2240 | host->caps.need_blksz_mul_4 = 0; | 2243 | host->caps.need_blksz_mul_4 = 0; |
2244 | host->caps.need_notbusy_for_read_ops = 1; | ||
2241 | case 0x100: | 2245 | case 0x100: |
2242 | host->caps.has_bad_data_ordering = 0; | 2246 | host->caps.has_bad_data_ordering = 0; |
2243 | host->caps.need_reset_after_xfer = 0; | 2247 | host->caps.need_reset_after_xfer = 0; |
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c index 03666174ca48..a17dd7363ceb 100644 --- a/drivers/mmc/host/bfin_sdh.c +++ b/drivers/mmc/host/bfin_sdh.c | |||
@@ -49,13 +49,6 @@ | |||
49 | #define bfin_write_SDH_CFG bfin_write_RSI_CFG | 49 | #define bfin_write_SDH_CFG bfin_write_RSI_CFG |
50 | #endif | 50 | #endif |
51 | 51 | ||
52 | struct dma_desc_array { | ||
53 | unsigned long start_addr; | ||
54 | unsigned short cfg; | ||
55 | unsigned short x_count; | ||
56 | short x_modify; | ||
57 | } __packed; | ||
58 | |||
59 | struct sdh_host { | 52 | struct sdh_host { |
60 | struct mmc_host *mmc; | 53 | struct mmc_host *mmc; |
61 | spinlock_t lock; | 54 | spinlock_t lock; |
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 72dc3cde646d..af40d227bece 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
@@ -627,6 +627,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot) | |||
627 | { | 627 | { |
628 | struct dw_mci *host = slot->host; | 628 | struct dw_mci *host = slot->host; |
629 | u32 div; | 629 | u32 div; |
630 | u32 clk_en_a; | ||
630 | 631 | ||
631 | if (slot->clock != host->current_speed) { | 632 | if (slot->clock != host->current_speed) { |
632 | div = host->bus_hz / slot->clock; | 633 | div = host->bus_hz / slot->clock; |
@@ -659,9 +660,11 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot) | |||
659 | mci_send_cmd(slot, | 660 | mci_send_cmd(slot, |
660 | SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0); | 661 | SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0); |
661 | 662 | ||
662 | /* enable clock */ | 663 | /* enable clock; only low power if no SDIO */ |
663 | mci_writel(host, CLKENA, ((SDMMC_CLKEN_ENABLE | | 664 | clk_en_a = SDMMC_CLKEN_ENABLE << slot->id; |
664 | SDMMC_CLKEN_LOW_PWR) << slot->id)); | 665 | if (!(mci_readl(host, INTMASK) & SDMMC_INT_SDIO(slot->id))) |
666 | clk_en_a |= SDMMC_CLKEN_LOW_PWR << slot->id; | ||
667 | mci_writel(host, CLKENA, clk_en_a); | ||
665 | 668 | ||
666 | /* inform CIU */ | 669 | /* inform CIU */ |
667 | mci_send_cmd(slot, | 670 | mci_send_cmd(slot, |
@@ -862,6 +865,30 @@ static int dw_mci_get_cd(struct mmc_host *mmc) | |||
862 | return present; | 865 | return present; |
863 | } | 866 | } |
864 | 867 | ||
868 | /* | ||
869 | * Disable lower power mode. | ||
870 | * | ||
871 | * Low power mode will stop the card clock when idle. According to the | ||
872 | * description of the CLKENA register we should disable low power mode | ||
873 | * for SDIO cards if we need SDIO interrupts to work. | ||
874 | * | ||
875 | * This function is fast if low power mode is already disabled. | ||
876 | */ | ||
877 | static void dw_mci_disable_low_power(struct dw_mci_slot *slot) | ||
878 | { | ||
879 | struct dw_mci *host = slot->host; | ||
880 | u32 clk_en_a; | ||
881 | const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id; | ||
882 | |||
883 | clk_en_a = mci_readl(host, CLKENA); | ||
884 | |||
885 | if (clk_en_a & clken_low_pwr) { | ||
886 | mci_writel(host, CLKENA, clk_en_a & ~clken_low_pwr); | ||
887 | mci_send_cmd(slot, SDMMC_CMD_UPD_CLK | | ||
888 | SDMMC_CMD_PRV_DAT_WAIT, 0); | ||
889 | } | ||
890 | } | ||
891 | |||
865 | static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb) | 892 | static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb) |
866 | { | 893 | { |
867 | struct dw_mci_slot *slot = mmc_priv(mmc); | 894 | struct dw_mci_slot *slot = mmc_priv(mmc); |
@@ -871,6 +898,14 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb) | |||
871 | /* Enable/disable Slot Specific SDIO interrupt */ | 898 | /* Enable/disable Slot Specific SDIO interrupt */ |
872 | int_mask = mci_readl(host, INTMASK); | 899 | int_mask = mci_readl(host, INTMASK); |
873 | if (enb) { | 900 | if (enb) { |
901 | /* | ||
902 | * Turn off low power mode if it was enabled. This is a bit of | ||
903 | * a heavy operation and we disable / enable IRQs a lot, so | ||
904 | * we'll leave low power mode disabled and it will get | ||
905 | * re-enabled again in dw_mci_setup_bus(). | ||
906 | */ | ||
907 | dw_mci_disable_low_power(slot); | ||
908 | |||
874 | mci_writel(host, INTMASK, | 909 | mci_writel(host, INTMASK, |
875 | (int_mask | SDMMC_INT_SDIO(slot->id))); | 910 | (int_mask | SDMMC_INT_SDIO(slot->id))); |
876 | } else { | 911 | } else { |
@@ -1429,22 +1464,10 @@ static void dw_mci_read_data_pio(struct dw_mci *host) | |||
1429 | nbytes += len; | 1464 | nbytes += len; |
1430 | remain -= len; | 1465 | remain -= len; |
1431 | } while (remain); | 1466 | } while (remain); |
1432 | sg_miter->consumed = offset; | ||
1433 | 1467 | ||
1468 | sg_miter->consumed = offset; | ||
1434 | status = mci_readl(host, MINTSTS); | 1469 | status = mci_readl(host, MINTSTS); |
1435 | mci_writel(host, RINTSTS, SDMMC_INT_RXDR); | 1470 | mci_writel(host, RINTSTS, SDMMC_INT_RXDR); |
1436 | if (status & DW_MCI_DATA_ERROR_FLAGS) { | ||
1437 | host->data_status = status; | ||
1438 | data->bytes_xfered += nbytes; | ||
1439 | sg_miter_stop(sg_miter); | ||
1440 | host->sg = NULL; | ||
1441 | smp_wmb(); | ||
1442 | |||
1443 | set_bit(EVENT_DATA_ERROR, &host->pending_events); | ||
1444 | |||
1445 | tasklet_schedule(&host->tasklet); | ||
1446 | return; | ||
1447 | } | ||
1448 | } while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/ | 1471 | } while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/ |
1449 | data->bytes_xfered += nbytes; | 1472 | data->bytes_xfered += nbytes; |
1450 | 1473 | ||
@@ -1497,23 +1520,10 @@ static void dw_mci_write_data_pio(struct dw_mci *host) | |||
1497 | nbytes += len; | 1520 | nbytes += len; |
1498 | remain -= len; | 1521 | remain -= len; |
1499 | } while (remain); | 1522 | } while (remain); |
1500 | sg_miter->consumed = offset; | ||
1501 | 1523 | ||
1524 | sg_miter->consumed = offset; | ||
1502 | status = mci_readl(host, MINTSTS); | 1525 | status = mci_readl(host, MINTSTS); |
1503 | mci_writel(host, RINTSTS, SDMMC_INT_TXDR); | 1526 | mci_writel(host, RINTSTS, SDMMC_INT_TXDR); |
1504 | if (status & DW_MCI_DATA_ERROR_FLAGS) { | ||
1505 | host->data_status = status; | ||
1506 | data->bytes_xfered += nbytes; | ||
1507 | sg_miter_stop(sg_miter); | ||
1508 | host->sg = NULL; | ||
1509 | |||
1510 | smp_wmb(); | ||
1511 | |||
1512 | set_bit(EVENT_DATA_ERROR, &host->pending_events); | ||
1513 | |||
1514 | tasklet_schedule(&host->tasklet); | ||
1515 | return; | ||
1516 | } | ||
1517 | } while (status & SDMMC_INT_TXDR); /* if TXDR write again */ | 1527 | } while (status & SDMMC_INT_TXDR); /* if TXDR write again */ |
1518 | data->bytes_xfered += nbytes; | 1528 | data->bytes_xfered += nbytes; |
1519 | 1529 | ||
@@ -1547,12 +1557,11 @@ static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status) | |||
1547 | static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) | 1557 | static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) |
1548 | { | 1558 | { |
1549 | struct dw_mci *host = dev_id; | 1559 | struct dw_mci *host = dev_id; |
1550 | u32 status, pending; | 1560 | u32 pending; |
1551 | unsigned int pass_count = 0; | 1561 | unsigned int pass_count = 0; |
1552 | int i; | 1562 | int i; |
1553 | 1563 | ||
1554 | do { | 1564 | do { |
1555 | status = mci_readl(host, RINTSTS); | ||
1556 | pending = mci_readl(host, MINTSTS); /* read-only mask reg */ | 1565 | pending = mci_readl(host, MINTSTS); /* read-only mask reg */ |
1557 | 1566 | ||
1558 | /* | 1567 | /* |
@@ -1570,7 +1579,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) | |||
1570 | 1579 | ||
1571 | if (pending & DW_MCI_CMD_ERROR_FLAGS) { | 1580 | if (pending & DW_MCI_CMD_ERROR_FLAGS) { |
1572 | mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS); | 1581 | mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS); |
1573 | host->cmd_status = status; | 1582 | host->cmd_status = pending; |
1574 | smp_wmb(); | 1583 | smp_wmb(); |
1575 | set_bit(EVENT_CMD_COMPLETE, &host->pending_events); | 1584 | set_bit(EVENT_CMD_COMPLETE, &host->pending_events); |
1576 | } | 1585 | } |
@@ -1578,18 +1587,16 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) | |||
1578 | if (pending & DW_MCI_DATA_ERROR_FLAGS) { | 1587 | if (pending & DW_MCI_DATA_ERROR_FLAGS) { |
1579 | /* if there is an error report DATA_ERROR */ | 1588 | /* if there is an error report DATA_ERROR */ |
1580 | mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS); | 1589 | mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS); |
1581 | host->data_status = status; | 1590 | host->data_status = pending; |
1582 | smp_wmb(); | 1591 | smp_wmb(); |
1583 | set_bit(EVENT_DATA_ERROR, &host->pending_events); | 1592 | set_bit(EVENT_DATA_ERROR, &host->pending_events); |
1584 | if (!(pending & (SDMMC_INT_DTO | SDMMC_INT_DCRC | | 1593 | tasklet_schedule(&host->tasklet); |
1585 | SDMMC_INT_SBE | SDMMC_INT_EBE))) | ||
1586 | tasklet_schedule(&host->tasklet); | ||
1587 | } | 1594 | } |
1588 | 1595 | ||
1589 | if (pending & SDMMC_INT_DATA_OVER) { | 1596 | if (pending & SDMMC_INT_DATA_OVER) { |
1590 | mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER); | 1597 | mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER); |
1591 | if (!host->data_status) | 1598 | if (!host->data_status) |
1592 | host->data_status = status; | 1599 | host->data_status = pending; |
1593 | smp_wmb(); | 1600 | smp_wmb(); |
1594 | if (host->dir_status == DW_MCI_RECV_STATUS) { | 1601 | if (host->dir_status == DW_MCI_RECV_STATUS) { |
1595 | if (host->sg != NULL) | 1602 | if (host->sg != NULL) |
@@ -1613,7 +1620,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) | |||
1613 | 1620 | ||
1614 | if (pending & SDMMC_INT_CMD_DONE) { | 1621 | if (pending & SDMMC_INT_CMD_DONE) { |
1615 | mci_writel(host, RINTSTS, SDMMC_INT_CMD_DONE); | 1622 | mci_writel(host, RINTSTS, SDMMC_INT_CMD_DONE); |
1616 | dw_mci_cmd_interrupt(host, status); | 1623 | dw_mci_cmd_interrupt(host, pending); |
1617 | } | 1624 | } |
1618 | 1625 | ||
1619 | if (pending & SDMMC_INT_CD) { | 1626 | if (pending & SDMMC_INT_CD) { |
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index a51f9309ffbb..ad3fcea1269e 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c | |||
@@ -285,11 +285,11 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id) | |||
285 | writel(stat & MXS_MMC_IRQ_BITS, | 285 | writel(stat & MXS_MMC_IRQ_BITS, |
286 | host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR); | 286 | host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR); |
287 | 287 | ||
288 | spin_unlock(&host->lock); | ||
289 | |||
288 | if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN)) | 290 | if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN)) |
289 | mmc_signal_sdio_irq(host->mmc); | 291 | mmc_signal_sdio_irq(host->mmc); |
290 | 292 | ||
291 | spin_unlock(&host->lock); | ||
292 | |||
293 | if (stat & BM_SSP_CTRL1_RESP_TIMEOUT_IRQ) | 293 | if (stat & BM_SSP_CTRL1_RESP_TIMEOUT_IRQ) |
294 | cmd->error = -ETIMEDOUT; | 294 | cmd->error = -ETIMEDOUT; |
295 | else if (stat & BM_SSP_CTRL1_RESP_ERR_IRQ) | 295 | else if (stat & BM_SSP_CTRL1_RESP_ERR_IRQ) |
@@ -644,11 +644,6 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | |||
644 | host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | 644 | host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); |
645 | writel(BM_SSP_CTRL1_SDIO_IRQ_EN, | 645 | writel(BM_SSP_CTRL1_SDIO_IRQ_EN, |
646 | host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET); | 646 | host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET); |
647 | |||
648 | if (readl(host->base + HW_SSP_STATUS(host)) & | ||
649 | BM_SSP_STATUS_SDIO_IRQ) | ||
650 | mmc_signal_sdio_irq(host->mmc); | ||
651 | |||
652 | } else { | 647 | } else { |
653 | writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, | 648 | writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, |
654 | host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); | 649 | host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); |
@@ -657,6 +652,11 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | |||
657 | } | 652 | } |
658 | 653 | ||
659 | spin_unlock_irqrestore(&host->lock, flags); | 654 | spin_unlock_irqrestore(&host->lock, flags); |
655 | |||
656 | if (enable && readl(host->base + HW_SSP_STATUS(host)) & | ||
657 | BM_SSP_STATUS_SDIO_IRQ) | ||
658 | mmc_signal_sdio_irq(host->mmc); | ||
659 | |||
660 | } | 660 | } |
661 | 661 | ||
662 | static const struct mmc_host_ops mxs_mmc_ops = { | 662 | static const struct mmc_host_ops mxs_mmc_ops = { |
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 50e08f03aa65..a5999a74496a 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -668,7 +668,7 @@ mmc_omap_clk_timer(unsigned long data) | |||
668 | static void | 668 | static void |
669 | mmc_omap_xfer_data(struct mmc_omap_host *host, int write) | 669 | mmc_omap_xfer_data(struct mmc_omap_host *host, int write) |
670 | { | 670 | { |
671 | int n; | 671 | int n, nwords; |
672 | 672 | ||
673 | if (host->buffer_bytes_left == 0) { | 673 | if (host->buffer_bytes_left == 0) { |
674 | host->sg_idx++; | 674 | host->sg_idx++; |
@@ -678,15 +678,23 @@ mmc_omap_xfer_data(struct mmc_omap_host *host, int write) | |||
678 | n = 64; | 678 | n = 64; |
679 | if (n > host->buffer_bytes_left) | 679 | if (n > host->buffer_bytes_left) |
680 | n = host->buffer_bytes_left; | 680 | n = host->buffer_bytes_left; |
681 | |||
682 | nwords = n / 2; | ||
683 | nwords += n & 1; /* handle odd number of bytes to transfer */ | ||
684 | |||
681 | host->buffer_bytes_left -= n; | 685 | host->buffer_bytes_left -= n; |
682 | host->total_bytes_left -= n; | 686 | host->total_bytes_left -= n; |
683 | host->data->bytes_xfered += n; | 687 | host->data->bytes_xfered += n; |
684 | 688 | ||
685 | if (write) { | 689 | if (write) { |
686 | __raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n); | 690 | __raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA), |
691 | host->buffer, nwords); | ||
687 | } else { | 692 | } else { |
688 | __raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n); | 693 | __raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA), |
694 | host->buffer, nwords); | ||
689 | } | 695 | } |
696 | |||
697 | host->buffer += nwords; | ||
690 | } | 698 | } |
691 | 699 | ||
692 | static inline void mmc_omap_report_irq(u16 status) | 700 | static inline void mmc_omap_report_irq(u16 status) |
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h index b97b2f5dafdb..d25f9ab9a54d 100644 --- a/drivers/mmc/host/sdhci-esdhc.h +++ b/drivers/mmc/host/sdhci-esdhc.h | |||
@@ -48,14 +48,14 @@ static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) | |||
48 | int div = 1; | 48 | int div = 1; |
49 | u32 temp; | 49 | u32 temp; |
50 | 50 | ||
51 | if (clock == 0) | ||
52 | goto out; | ||
53 | |||
51 | temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); | 54 | temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); |
52 | temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | 55 | temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN |
53 | | ESDHC_CLOCK_MASK); | 56 | | ESDHC_CLOCK_MASK); |
54 | sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); | 57 | sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); |
55 | 58 | ||
56 | if (clock == 0) | ||
57 | goto out; | ||
58 | |||
59 | while (host->max_clk / pre_div / 16 > clock && pre_div < 256) | 59 | while (host->max_clk / pre_div / 16 > clock && pre_div < 256) |
60 | pre_div *= 2; | 60 | pre_div *= 2; |
61 | 61 | ||
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 437bc193e170..568307cc7caf 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c | |||
@@ -340,7 +340,7 @@ retry: | |||
340 | * of this LEB as it will be deleted and freed in 'ubi_add_to_av()'. | 340 | * of this LEB as it will be deleted and freed in 'ubi_add_to_av()'. |
341 | */ | 341 | */ |
342 | err = ubi_add_to_av(ubi, ai, new_aeb->pnum, new_aeb->ec, vid_hdr, 0); | 342 | err = ubi_add_to_av(ubi, ai, new_aeb->pnum, new_aeb->ec, vid_hdr, 0); |
343 | kfree(new_aeb); | 343 | kmem_cache_free(ai->aeb_slab_cache, new_aeb); |
344 | ubi_free_vid_hdr(ubi, vid_hdr); | 344 | ubi_free_vid_hdr(ubi, vid_hdr); |
345 | return err; | 345 | return err; |
346 | 346 | ||
@@ -353,7 +353,7 @@ write_error: | |||
353 | list_add(&new_aeb->u.list, &ai->erase); | 353 | list_add(&new_aeb->u.list, &ai->erase); |
354 | goto retry; | 354 | goto retry; |
355 | } | 355 | } |
356 | kfree(new_aeb); | 356 | kmem_cache_free(ai->aeb_slab_cache, new_aeb); |
357 | out_free: | 357 | out_free: |
358 | ubi_free_vid_hdr(ubi, vid_hdr); | 358 | ubi_free_vid_hdr(ubi, vid_hdr); |
359 | return err; | 359 | return err; |
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index a580db29e503..26e7129332ab 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c | |||
@@ -83,6 +83,11 @@ | |||
83 | #define INSTRUCTION_LOAD_TXB(n) (0x40 + 2 * (n)) | 83 | #define INSTRUCTION_LOAD_TXB(n) (0x40 + 2 * (n)) |
84 | #define INSTRUCTION_READ_RXB(n) (((n) == 0) ? 0x90 : 0x94) | 84 | #define INSTRUCTION_READ_RXB(n) (((n) == 0) ? 0x90 : 0x94) |
85 | #define INSTRUCTION_RESET 0xC0 | 85 | #define INSTRUCTION_RESET 0xC0 |
86 | #define RTS_TXB0 0x01 | ||
87 | #define RTS_TXB1 0x02 | ||
88 | #define RTS_TXB2 0x04 | ||
89 | #define INSTRUCTION_RTS(n) (0x80 | ((n) & 0x07)) | ||
90 | |||
86 | 91 | ||
87 | /* MPC251x registers */ | 92 | /* MPC251x registers */ |
88 | #define CANSTAT 0x0e | 93 | #define CANSTAT 0x0e |
@@ -397,6 +402,7 @@ static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf, | |||
397 | static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame, | 402 | static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame, |
398 | int tx_buf_idx) | 403 | int tx_buf_idx) |
399 | { | 404 | { |
405 | struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); | ||
400 | u32 sid, eid, exide, rtr; | 406 | u32 sid, eid, exide, rtr; |
401 | u8 buf[SPI_TRANSFER_BUF_LEN]; | 407 | u8 buf[SPI_TRANSFER_BUF_LEN]; |
402 | 408 | ||
@@ -418,7 +424,10 @@ static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame, | |||
418 | buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc; | 424 | buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc; |
419 | memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc); | 425 | memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc); |
420 | mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx); | 426 | mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx); |
421 | mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx), TXBCTRL_TXREQ); | 427 | |
428 | /* use INSTRUCTION_RTS, to avoid "repeated frame problem" */ | ||
429 | priv->spi_tx_buf[0] = INSTRUCTION_RTS(1 << tx_buf_idx); | ||
430 | mcp251x_spi_trans(priv->spi, 1); | ||
422 | } | 431 | } |
423 | 432 | ||
424 | static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, | 433 | static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, |
diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c index 4f50145f6483..662c5f7eb0c5 100644 --- a/drivers/net/can/sja1000/sja1000_platform.c +++ b/drivers/net/can/sja1000/sja1000_platform.c | |||
@@ -109,7 +109,9 @@ static int sp_probe(struct platform_device *pdev) | |||
109 | priv = netdev_priv(dev); | 109 | priv = netdev_priv(dev); |
110 | 110 | ||
111 | dev->irq = res_irq->start; | 111 | dev->irq = res_irq->start; |
112 | priv->irq_flags = res_irq->flags & (IRQF_TRIGGER_MASK | IRQF_SHARED); | 112 | priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK; |
113 | if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE) | ||
114 | priv->irq_flags |= IRQF_SHARED; | ||
113 | priv->reg_base = addr; | 115 | priv->reg_base = addr; |
114 | /* The CAN clock frequency is half the oscillator clock frequency */ | 116 | /* The CAN clock frequency is half the oscillator clock frequency */ |
115 | priv->can.clock.freq = pdata->osc_freq / 2; | 117 | priv->can.clock.freq = pdata->osc_freq / 2; |
diff --git a/drivers/net/can/softing/softing_fw.c b/drivers/net/can/softing/softing_fw.c index 310596175676..b595d3422b9f 100644 --- a/drivers/net/can/softing/softing_fw.c +++ b/drivers/net/can/softing/softing_fw.c | |||
@@ -150,7 +150,7 @@ int softing_load_fw(const char *file, struct softing *card, | |||
150 | const uint8_t *mem, *end, *dat; | 150 | const uint8_t *mem, *end, *dat; |
151 | uint16_t type, len; | 151 | uint16_t type, len; |
152 | uint32_t addr; | 152 | uint32_t addr; |
153 | uint8_t *buf = NULL; | 153 | uint8_t *buf = NULL, *new_buf; |
154 | int buflen = 0; | 154 | int buflen = 0; |
155 | int8_t type_end = 0; | 155 | int8_t type_end = 0; |
156 | 156 | ||
@@ -199,11 +199,12 @@ int softing_load_fw(const char *file, struct softing *card, | |||
199 | if (len > buflen) { | 199 | if (len > buflen) { |
200 | /* align buflen */ | 200 | /* align buflen */ |
201 | buflen = (len + (1024-1)) & ~(1024-1); | 201 | buflen = (len + (1024-1)) & ~(1024-1); |
202 | buf = krealloc(buf, buflen, GFP_KERNEL); | 202 | new_buf = krealloc(buf, buflen, GFP_KERNEL); |
203 | if (!buf) { | 203 | if (!new_buf) { |
204 | ret = -ENOMEM; | 204 | ret = -ENOMEM; |
205 | goto failed; | 205 | goto failed; |
206 | } | 206 | } |
207 | buf = new_buf; | ||
207 | } | 208 | } |
208 | /* verify record data */ | 209 | /* verify record data */ |
209 | memcpy_fromio(buf, &dpram[addr + offset], len); | 210 | memcpy_fromio(buf, &dpram[addr + offset], len); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 463b9ec57d80..6d1a24acb77e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | |||
@@ -1708,9 +1708,6 @@ struct bnx2x_func_init_params { | |||
1708 | continue; \ | 1708 | continue; \ |
1709 | else | 1709 | else |
1710 | 1710 | ||
1711 | #define for_each_napi_rx_queue(bp, var) \ | ||
1712 | for ((var) = 0; (var) < bp->num_napi_queues; (var)++) | ||
1713 | |||
1714 | /* Skip OOO FP */ | 1711 | /* Skip OOO FP */ |
1715 | #define for_each_tx_queue(bp, var) \ | 1712 | #define for_each_tx_queue(bp, var) \ |
1716 | for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \ | 1713 | for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \ |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index e879e19eb0d6..af20c6ee2cd9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -2046,6 +2046,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
2046 | */ | 2046 | */ |
2047 | bnx2x_setup_tc(bp->dev, bp->max_cos); | 2047 | bnx2x_setup_tc(bp->dev, bp->max_cos); |
2048 | 2048 | ||
2049 | /* Add all NAPI objects */ | ||
2050 | bnx2x_add_all_napi(bp); | ||
2049 | bnx2x_napi_enable(bp); | 2051 | bnx2x_napi_enable(bp); |
2050 | 2052 | ||
2051 | /* set pf load just before approaching the MCP */ | 2053 | /* set pf load just before approaching the MCP */ |
@@ -2408,6 +2410,8 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) | |||
2408 | 2410 | ||
2409 | /* Disable HW interrupts, NAPI */ | 2411 | /* Disable HW interrupts, NAPI */ |
2410 | bnx2x_netif_stop(bp, 1); | 2412 | bnx2x_netif_stop(bp, 1); |
2413 | /* Delete all NAPI objects */ | ||
2414 | bnx2x_del_all_napi(bp); | ||
2411 | 2415 | ||
2412 | /* Release IRQs */ | 2416 | /* Release IRQs */ |
2413 | bnx2x_free_irq(bp); | 2417 | bnx2x_free_irq(bp); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index dfa757e74296..dfd86a55f1dc 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | |||
@@ -710,17 +710,15 @@ static inline u16 bnx2x_tx_avail(struct bnx2x *bp, | |||
710 | prod = txdata->tx_bd_prod; | 710 | prod = txdata->tx_bd_prod; |
711 | cons = txdata->tx_bd_cons; | 711 | cons = txdata->tx_bd_cons; |
712 | 712 | ||
713 | /* NUM_TX_RINGS = number of "next-page" entries | 713 | used = SUB_S16(prod, cons); |
714 | It will be used as a threshold */ | ||
715 | used = SUB_S16(prod, cons) + (s16)NUM_TX_RINGS; | ||
716 | 714 | ||
717 | #ifdef BNX2X_STOP_ON_ERROR | 715 | #ifdef BNX2X_STOP_ON_ERROR |
718 | WARN_ON(used < 0); | 716 | WARN_ON(used < 0); |
719 | WARN_ON(used > bp->tx_ring_size); | 717 | WARN_ON(used > txdata->tx_ring_size); |
720 | WARN_ON((bp->tx_ring_size - used) > MAX_TX_AVAIL); | 718 | WARN_ON((txdata->tx_ring_size - used) > MAX_TX_AVAIL); |
721 | #endif | 719 | #endif |
722 | 720 | ||
723 | return (s16)(bp->tx_ring_size) - used; | 721 | return (s16)(txdata->tx_ring_size) - used; |
724 | } | 722 | } |
725 | 723 | ||
726 | static inline int bnx2x_tx_queue_has_work(struct bnx2x_fp_txdata *txdata) | 724 | static inline int bnx2x_tx_queue_has_work(struct bnx2x_fp_txdata *txdata) |
@@ -792,7 +790,7 @@ static inline void bnx2x_add_all_napi(struct bnx2x *bp) | |||
792 | bp->num_napi_queues = bp->num_queues; | 790 | bp->num_napi_queues = bp->num_queues; |
793 | 791 | ||
794 | /* Add NAPI objects */ | 792 | /* Add NAPI objects */ |
795 | for_each_napi_rx_queue(bp, i) | 793 | for_each_rx_queue(bp, i) |
796 | netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), | 794 | netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), |
797 | bnx2x_poll, BNX2X_NAPI_WEIGHT); | 795 | bnx2x_poll, BNX2X_NAPI_WEIGHT); |
798 | } | 796 | } |
@@ -801,7 +799,7 @@ static inline void bnx2x_del_all_napi(struct bnx2x *bp) | |||
801 | { | 799 | { |
802 | int i; | 800 | int i; |
803 | 801 | ||
804 | for_each_napi_rx_queue(bp, i) | 802 | for_each_rx_queue(bp, i) |
805 | netif_napi_del(&bnx2x_fp(bp, i, napi)); | 803 | netif_napi_del(&bnx2x_fp(bp, i, napi)); |
806 | } | 804 | } |
807 | 805 | ||
@@ -1088,6 +1086,7 @@ static inline void bnx2x_init_txdata(struct bnx2x *bp, | |||
1088 | txdata->txq_index = txq_index; | 1086 | txdata->txq_index = txq_index; |
1089 | txdata->tx_cons_sb = tx_cons_sb; | 1087 | txdata->tx_cons_sb = tx_cons_sb; |
1090 | txdata->parent_fp = fp; | 1088 | txdata->parent_fp = fp; |
1089 | txdata->tx_ring_size = IS_FCOE_FP(fp) ? MAX_TX_AVAIL : bp->tx_ring_size; | ||
1091 | 1090 | ||
1092 | DP(NETIF_MSG_IFUP, "created tx data cid %d, txq %d\n", | 1091 | DP(NETIF_MSG_IFUP, "created tx data cid %d, txq %d\n", |
1093 | txdata->cid, txdata->txq_index); | 1092 | txdata->cid, txdata->txq_index); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h index 3e4cff9b1ebe..b926f58e983b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h | |||
@@ -401,11 +401,11 @@ static const struct reg_addr reg_addrs[] = { | |||
401 | { 0x70000, 8, RI_ALL_ONLINE }, | 401 | { 0x70000, 8, RI_ALL_ONLINE }, |
402 | { 0x70020, 8184, RI_ALL_OFFLINE }, | 402 | { 0x70020, 8184, RI_ALL_OFFLINE }, |
403 | { 0x78000, 8192, RI_E3E3B0_OFFLINE }, | 403 | { 0x78000, 8192, RI_E3E3B0_OFFLINE }, |
404 | { 0x85000, 3, RI_ALL_ONLINE }, | 404 | { 0x85000, 3, RI_ALL_OFFLINE }, |
405 | { 0x8501c, 7, RI_ALL_ONLINE }, | 405 | { 0x8501c, 7, RI_ALL_OFFLINE }, |
406 | { 0x85048, 1, RI_ALL_ONLINE }, | 406 | { 0x85048, 1, RI_ALL_OFFLINE }, |
407 | { 0x85200, 32, RI_ALL_ONLINE }, | 407 | { 0x85200, 32, RI_ALL_OFFLINE }, |
408 | { 0xb0000, 16384, RI_E1H_ONLINE }, | 408 | { 0xb0000, 16384, RI_E1H_OFFLINE }, |
409 | { 0xc1000, 7, RI_ALL_ONLINE }, | 409 | { 0xc1000, 7, RI_ALL_ONLINE }, |
410 | { 0xc103c, 2, RI_E2E3E3B0_ONLINE }, | 410 | { 0xc103c, 2, RI_E2E3E3B0_ONLINE }, |
411 | { 0xc1800, 2, RI_ALL_ONLINE }, | 411 | { 0xc1800, 2, RI_ALL_ONLINE }, |
@@ -581,17 +581,12 @@ static const struct reg_addr reg_addrs[] = { | |||
581 | { 0x140188, 3, RI_E1E1HE2E3_ONLINE }, | 581 | { 0x140188, 3, RI_E1E1HE2E3_ONLINE }, |
582 | { 0x140194, 13, RI_ALL_ONLINE }, | 582 | { 0x140194, 13, RI_ALL_ONLINE }, |
583 | { 0x140200, 6, RI_E1E1HE2E3_ONLINE }, | 583 | { 0x140200, 6, RI_E1E1HE2E3_ONLINE }, |
584 | { 0x140220, 4, RI_E2E3_ONLINE }, | ||
585 | { 0x140240, 4, RI_E2E3_ONLINE }, | ||
586 | { 0x140260, 4, RI_E2E3_ONLINE }, | 584 | { 0x140260, 4, RI_E2E3_ONLINE }, |
587 | { 0x140280, 4, RI_E2E3_ONLINE }, | 585 | { 0x140280, 4, RI_E2E3_ONLINE }, |
588 | { 0x1402a0, 4, RI_E2E3_ONLINE }, | ||
589 | { 0x1402c0, 4, RI_E2E3_ONLINE }, | ||
590 | { 0x1402e0, 2, RI_E2E3_ONLINE }, | 586 | { 0x1402e0, 2, RI_E2E3_ONLINE }, |
591 | { 0x1402e8, 2, RI_E2E3E3B0_ONLINE }, | 587 | { 0x1402e8, 2, RI_E2E3E3B0_ONLINE }, |
592 | { 0x1402f0, 9, RI_E2E3_ONLINE }, | 588 | { 0x1402f0, 9, RI_E2E3_ONLINE }, |
593 | { 0x140314, 44, RI_E3B0_ONLINE }, | 589 | { 0x140314, 44, RI_E3B0_ONLINE }, |
594 | { 0x1403d0, 70, RI_E3B0_ONLINE }, | ||
595 | { 0x144000, 4, RI_E1E1H_ONLINE }, | 590 | { 0x144000, 4, RI_E1E1H_ONLINE }, |
596 | { 0x148000, 4, RI_E1E1H_ONLINE }, | 591 | { 0x148000, 4, RI_E1E1H_ONLINE }, |
597 | { 0x14c000, 4, RI_E1E1H_ONLINE }, | 592 | { 0x14c000, 4, RI_E1E1H_ONLINE }, |
@@ -704,7 +699,6 @@ static const struct reg_addr reg_addrs[] = { | |||
704 | { 0x180398, 1, RI_E2E3E3B0_ONLINE }, | 699 | { 0x180398, 1, RI_E2E3E3B0_ONLINE }, |
705 | { 0x1803a0, 5, RI_E2E3E3B0_ONLINE }, | 700 | { 0x1803a0, 5, RI_E2E3E3B0_ONLINE }, |
706 | { 0x1803b4, 2, RI_E3E3B0_ONLINE }, | 701 | { 0x1803b4, 2, RI_E3E3B0_ONLINE }, |
707 | { 0x180400, 1, RI_ALL_ONLINE }, | ||
708 | { 0x180404, 255, RI_E1E1H_OFFLINE }, | 702 | { 0x180404, 255, RI_E1E1H_OFFLINE }, |
709 | { 0x181000, 4, RI_ALL_ONLINE }, | 703 | { 0x181000, 4, RI_ALL_ONLINE }, |
710 | { 0x181010, 1020, RI_ALL_OFFLINE }, | 704 | { 0x181010, 1020, RI_ALL_OFFLINE }, |
@@ -800,9 +794,9 @@ static const struct reg_addr reg_addrs[] = { | |||
800 | { 0x1b905c, 1, RI_E3E3B0_ONLINE }, | 794 | { 0x1b905c, 1, RI_E3E3B0_ONLINE }, |
801 | { 0x1b9064, 1, RI_E3B0_ONLINE }, | 795 | { 0x1b9064, 1, RI_E3B0_ONLINE }, |
802 | { 0x1b9080, 10, RI_E3B0_ONLINE }, | 796 | { 0x1b9080, 10, RI_E3B0_ONLINE }, |
803 | { 0x1b9400, 14, RI_E2E3E3B0_ONLINE }, | 797 | { 0x1b9400, 14, RI_E2E3E3B0_OFFLINE }, |
804 | { 0x1b943c, 19, RI_E2E3E3B0_ONLINE }, | 798 | { 0x1b943c, 19, RI_E2E3E3B0_OFFLINE }, |
805 | { 0x1b9490, 10, RI_E2E3E3B0_ONLINE }, | 799 | { 0x1b9490, 10, RI_E2E3E3B0_OFFLINE }, |
806 | { 0x1c0000, 2, RI_ALL_ONLINE }, | 800 | { 0x1c0000, 2, RI_ALL_ONLINE }, |
807 | { 0x200000, 65, RI_ALL_ONLINE }, | 801 | { 0x200000, 65, RI_ALL_ONLINE }, |
808 | { 0x20014c, 2, RI_E1HE2E3E3B0_ONLINE }, | 802 | { 0x20014c, 2, RI_E1HE2E3E3B0_ONLINE }, |
@@ -814,7 +808,6 @@ static const struct reg_addr reg_addrs[] = { | |||
814 | { 0x200398, 1, RI_E2E3E3B0_ONLINE }, | 808 | { 0x200398, 1, RI_E2E3E3B0_ONLINE }, |
815 | { 0x2003a0, 1, RI_E2E3E3B0_ONLINE }, | 809 | { 0x2003a0, 1, RI_E2E3E3B0_ONLINE }, |
816 | { 0x2003a8, 2, RI_E2E3E3B0_ONLINE }, | 810 | { 0x2003a8, 2, RI_E2E3E3B0_ONLINE }, |
817 | { 0x200400, 1, RI_ALL_ONLINE }, | ||
818 | { 0x200404, 255, RI_E1E1H_OFFLINE }, | 811 | { 0x200404, 255, RI_E1E1H_OFFLINE }, |
819 | { 0x202000, 4, RI_ALL_ONLINE }, | 812 | { 0x202000, 4, RI_ALL_ONLINE }, |
820 | { 0x202010, 2044, RI_ALL_OFFLINE }, | 813 | { 0x202010, 2044, RI_ALL_OFFLINE }, |
@@ -921,7 +914,6 @@ static const struct reg_addr reg_addrs[] = { | |||
921 | { 0x280398, 1, RI_E2E3E3B0_ONLINE }, | 914 | { 0x280398, 1, RI_E2E3E3B0_ONLINE }, |
922 | { 0x2803a0, 1, RI_E2E3E3B0_ONLINE }, | 915 | { 0x2803a0, 1, RI_E2E3E3B0_ONLINE }, |
923 | { 0x2803a8, 2, RI_E2E3E3B0_ONLINE }, | 916 | { 0x2803a8, 2, RI_E2E3E3B0_ONLINE }, |
924 | { 0x280400, 1, RI_ALL_ONLINE }, | ||
925 | { 0x280404, 255, RI_E1E1H_OFFLINE }, | 917 | { 0x280404, 255, RI_E1E1H_OFFLINE }, |
926 | { 0x282000, 4, RI_ALL_ONLINE }, | 918 | { 0x282000, 4, RI_ALL_ONLINE }, |
927 | { 0x282010, 2044, RI_ALL_OFFLINE }, | 919 | { 0x282010, 2044, RI_ALL_OFFLINE }, |
@@ -1031,7 +1023,6 @@ static const struct reg_addr reg_addrs[] = { | |||
1031 | { 0x300398, 1, RI_E2E3E3B0_ONLINE }, | 1023 | { 0x300398, 1, RI_E2E3E3B0_ONLINE }, |
1032 | { 0x3003a0, 1, RI_E2E3E3B0_ONLINE }, | 1024 | { 0x3003a0, 1, RI_E2E3E3B0_ONLINE }, |
1033 | { 0x3003a8, 2, RI_E2E3E3B0_ONLINE }, | 1025 | { 0x3003a8, 2, RI_E2E3E3B0_ONLINE }, |
1034 | { 0x300400, 1, RI_ALL_ONLINE }, | ||
1035 | { 0x300404, 255, RI_E1E1H_OFFLINE }, | 1026 | { 0x300404, 255, RI_E1E1H_OFFLINE }, |
1036 | { 0x302000, 4, RI_ALL_ONLINE }, | 1027 | { 0x302000, 4, RI_ALL_ONLINE }, |
1037 | { 0x302010, 2044, RI_ALL_OFFLINE }, | 1028 | { 0x302010, 2044, RI_ALL_OFFLINE }, |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index fc4e0e3885b0..ebf40cd7aa10 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | |||
@@ -775,7 +775,7 @@ static void bnx2x_get_regs(struct net_device *dev, | |||
775 | struct bnx2x *bp = netdev_priv(dev); | 775 | struct bnx2x *bp = netdev_priv(dev); |
776 | struct dump_hdr dump_hdr = {0}; | 776 | struct dump_hdr dump_hdr = {0}; |
777 | 777 | ||
778 | regs->version = 0; | 778 | regs->version = 1; |
779 | memset(p, 0, regs->len); | 779 | memset(p, 0, regs->len); |
780 | 780 | ||
781 | if (!netif_running(bp->dev)) | 781 | if (!netif_running(bp->dev)) |
@@ -1587,6 +1587,12 @@ static int bnx2x_set_pauseparam(struct net_device *dev, | |||
1587 | bp->link_params.req_flow_ctrl[cfg_idx] = | 1587 | bp->link_params.req_flow_ctrl[cfg_idx] = |
1588 | BNX2X_FLOW_CTRL_AUTO; | 1588 | BNX2X_FLOW_CTRL_AUTO; |
1589 | } | 1589 | } |
1590 | bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_NONE; | ||
1591 | if (epause->rx_pause) | ||
1592 | bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_RX; | ||
1593 | |||
1594 | if (epause->tx_pause) | ||
1595 | bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_TX; | ||
1590 | } | 1596 | } |
1591 | 1597 | ||
1592 | DP(BNX2X_MSG_ETHTOOL, | 1598 | DP(BNX2X_MSG_ETHTOOL, |
@@ -2888,11 +2894,9 @@ static void bnx2x_get_channels(struct net_device *dev, | |||
2888 | */ | 2894 | */ |
2889 | static void bnx2x_change_num_queues(struct bnx2x *bp, int num_rss) | 2895 | static void bnx2x_change_num_queues(struct bnx2x *bp, int num_rss) |
2890 | { | 2896 | { |
2891 | bnx2x_del_all_napi(bp); | ||
2892 | bnx2x_disable_msi(bp); | 2897 | bnx2x_disable_msi(bp); |
2893 | BNX2X_NUM_QUEUES(bp) = num_rss + NON_ETH_CONTEXT_USE; | 2898 | BNX2X_NUM_QUEUES(bp) = num_rss + NON_ETH_CONTEXT_USE; |
2894 | bnx2x_set_int_mode(bp); | 2899 | bnx2x_set_int_mode(bp); |
2895 | bnx2x_add_all_napi(bp); | ||
2896 | } | 2900 | } |
2897 | 2901 | ||
2898 | /** | 2902 | /** |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index f4beb46c4709..b046beb435b2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | |||
@@ -2667,9 +2667,11 @@ int bnx2x_update_pfc(struct link_params *params, | |||
2667 | return bnx2x_status; | 2667 | return bnx2x_status; |
2668 | 2668 | ||
2669 | DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n"); | 2669 | DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n"); |
2670 | if (CHIP_IS_E3(bp)) | 2670 | |
2671 | bnx2x_update_pfc_xmac(params, vars, 0); | 2671 | if (CHIP_IS_E3(bp)) { |
2672 | else { | 2672 | if (vars->mac_type == MAC_TYPE_XMAC) |
2673 | bnx2x_update_pfc_xmac(params, vars, 0); | ||
2674 | } else { | ||
2673 | val = REG_RD(bp, MISC_REG_RESET_REG_2); | 2675 | val = REG_RD(bp, MISC_REG_RESET_REG_2); |
2674 | if ((val & | 2676 | if ((val & |
2675 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) | 2677 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) |
@@ -5432,7 +5434,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
5432 | switch (speed_mask) { | 5434 | switch (speed_mask) { |
5433 | case GP_STATUS_10M: | 5435 | case GP_STATUS_10M: |
5434 | vars->line_speed = SPEED_10; | 5436 | vars->line_speed = SPEED_10; |
5435 | if (vars->duplex == DUPLEX_FULL) | 5437 | if (is_duplex == DUPLEX_FULL) |
5436 | vars->link_status |= LINK_10TFD; | 5438 | vars->link_status |= LINK_10TFD; |
5437 | else | 5439 | else |
5438 | vars->link_status |= LINK_10THD; | 5440 | vars->link_status |= LINK_10THD; |
@@ -5440,7 +5442,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
5440 | 5442 | ||
5441 | case GP_STATUS_100M: | 5443 | case GP_STATUS_100M: |
5442 | vars->line_speed = SPEED_100; | 5444 | vars->line_speed = SPEED_100; |
5443 | if (vars->duplex == DUPLEX_FULL) | 5445 | if (is_duplex == DUPLEX_FULL) |
5444 | vars->link_status |= LINK_100TXFD; | 5446 | vars->link_status |= LINK_100TXFD; |
5445 | else | 5447 | else |
5446 | vars->link_status |= LINK_100TXHD; | 5448 | vars->link_status |= LINK_100TXHD; |
@@ -5449,7 +5451,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
5449 | case GP_STATUS_1G: | 5451 | case GP_STATUS_1G: |
5450 | case GP_STATUS_1G_KX: | 5452 | case GP_STATUS_1G_KX: |
5451 | vars->line_speed = SPEED_1000; | 5453 | vars->line_speed = SPEED_1000; |
5452 | if (vars->duplex == DUPLEX_FULL) | 5454 | if (is_duplex == DUPLEX_FULL) |
5453 | vars->link_status |= LINK_1000TFD; | 5455 | vars->link_status |= LINK_1000TFD; |
5454 | else | 5456 | else |
5455 | vars->link_status |= LINK_1000THD; | 5457 | vars->link_status |= LINK_1000THD; |
@@ -5457,7 +5459,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
5457 | 5459 | ||
5458 | case GP_STATUS_2_5G: | 5460 | case GP_STATUS_2_5G: |
5459 | vars->line_speed = SPEED_2500; | 5461 | vars->line_speed = SPEED_2500; |
5460 | if (vars->duplex == DUPLEX_FULL) | 5462 | if (is_duplex == DUPLEX_FULL) |
5461 | vars->link_status |= LINK_2500TFD; | 5463 | vars->link_status |= LINK_2500TFD; |
5462 | else | 5464 | else |
5463 | vars->link_status |= LINK_2500THD; | 5465 | vars->link_status |= LINK_2500THD; |
@@ -5531,6 +5533,7 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, | |||
5531 | 5533 | ||
5532 | if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { | 5534 | if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { |
5533 | if (SINGLE_MEDIA_DIRECT(params)) { | 5535 | if (SINGLE_MEDIA_DIRECT(params)) { |
5536 | vars->duplex = duplex; | ||
5534 | bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status); | 5537 | bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status); |
5535 | if (phy->req_line_speed == SPEED_AUTO_NEG) | 5538 | if (phy->req_line_speed == SPEED_AUTO_NEG) |
5536 | bnx2x_xgxs_an_resolve(phy, params, vars, | 5539 | bnx2x_xgxs_an_resolve(phy, params, vars, |
@@ -5625,6 +5628,7 @@ static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy, | |||
5625 | LINK_STATUS_PARALLEL_DETECTION_USED; | 5628 | LINK_STATUS_PARALLEL_DETECTION_USED; |
5626 | } | 5629 | } |
5627 | bnx2x_ext_phy_resolve_fc(phy, params, vars); | 5630 | bnx2x_ext_phy_resolve_fc(phy, params, vars); |
5631 | vars->duplex = duplex; | ||
5628 | } | 5632 | } |
5629 | } | 5633 | } |
5630 | 5634 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 02b5a343b195..211753e01f81 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -7561,8 +7561,14 @@ int bnx2x_set_mac_one(struct bnx2x *bp, u8 *mac, | |||
7561 | } | 7561 | } |
7562 | 7562 | ||
7563 | rc = bnx2x_config_vlan_mac(bp, &ramrod_param); | 7563 | rc = bnx2x_config_vlan_mac(bp, &ramrod_param); |
7564 | if (rc < 0) | 7564 | |
7565 | if (rc == -EEXIST) { | ||
7566 | DP(BNX2X_MSG_SP, "Failed to schedule ADD operations: %d\n", rc); | ||
7567 | /* do not treat adding same MAC as error */ | ||
7568 | rc = 0; | ||
7569 | } else if (rc < 0) | ||
7565 | BNX2X_ERR("%s MAC failed\n", (set ? "Set" : "Del")); | 7570 | BNX2X_ERR("%s MAC failed\n", (set ? "Set" : "Del")); |
7571 | |||
7566 | return rc; | 7572 | return rc; |
7567 | } | 7573 | } |
7568 | 7574 | ||
@@ -8427,6 +8433,8 @@ unload_error: | |||
8427 | 8433 | ||
8428 | /* Disable HW interrupts, NAPI */ | 8434 | /* Disable HW interrupts, NAPI */ |
8429 | bnx2x_netif_stop(bp, 1); | 8435 | bnx2x_netif_stop(bp, 1); |
8436 | /* Delete all NAPI objects */ | ||
8437 | bnx2x_del_all_napi(bp); | ||
8430 | 8438 | ||
8431 | /* Release IRQs */ | 8439 | /* Release IRQs */ |
8432 | bnx2x_free_irq(bp); | 8440 | bnx2x_free_irq(bp); |
@@ -10292,13 +10300,11 @@ static void __devinit bnx2x_get_fcoe_info(struct bnx2x *bp) | |||
10292 | dev_info.port_hw_config[port]. | 10300 | dev_info.port_hw_config[port]. |
10293 | fcoe_wwn_node_name_lower); | 10301 | fcoe_wwn_node_name_lower); |
10294 | } else if (!IS_MF_SD(bp)) { | 10302 | } else if (!IS_MF_SD(bp)) { |
10295 | u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg); | ||
10296 | |||
10297 | /* | 10303 | /* |
10298 | * Read the WWN info only if the FCoE feature is enabled for | 10304 | * Read the WWN info only if the FCoE feature is enabled for |
10299 | * this function. | 10305 | * this function. |
10300 | */ | 10306 | */ |
10301 | if (cfg & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD) | 10307 | if (BNX2X_MF_EXT_PROTOCOL_FCOE(bp) && !CHIP_IS_E1x(bp)) |
10302 | bnx2x_get_ext_wwn_info(bp, func); | 10308 | bnx2x_get_ext_wwn_info(bp, func); |
10303 | 10309 | ||
10304 | } else if (IS_MF_FCOE_SD(bp)) | 10310 | } else if (IS_MF_FCOE_SD(bp)) |
@@ -11071,7 +11077,14 @@ static int bnx2x_set_uc_list(struct bnx2x *bp) | |||
11071 | netdev_for_each_uc_addr(ha, dev) { | 11077 | netdev_for_each_uc_addr(ha, dev) { |
11072 | rc = bnx2x_set_mac_one(bp, bnx2x_uc_addr(ha), mac_obj, true, | 11078 | rc = bnx2x_set_mac_one(bp, bnx2x_uc_addr(ha), mac_obj, true, |
11073 | BNX2X_UC_LIST_MAC, &ramrod_flags); | 11079 | BNX2X_UC_LIST_MAC, &ramrod_flags); |
11074 | if (rc < 0) { | 11080 | if (rc == -EEXIST) { |
11081 | DP(BNX2X_MSG_SP, | ||
11082 | "Failed to schedule ADD operations: %d\n", rc); | ||
11083 | /* do not treat adding same MAC as error */ | ||
11084 | rc = 0; | ||
11085 | |||
11086 | } else if (rc < 0) { | ||
11087 | |||
11075 | BNX2X_ERR("Failed to schedule ADD operations: %d\n", | 11088 | BNX2X_ERR("Failed to schedule ADD operations: %d\n", |
11076 | rc); | 11089 | rc); |
11077 | return rc; | 11090 | return rc; |
@@ -11229,10 +11242,12 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
11229 | static void poll_bnx2x(struct net_device *dev) | 11242 | static void poll_bnx2x(struct net_device *dev) |
11230 | { | 11243 | { |
11231 | struct bnx2x *bp = netdev_priv(dev); | 11244 | struct bnx2x *bp = netdev_priv(dev); |
11245 | int i; | ||
11232 | 11246 | ||
11233 | disable_irq(bp->pdev->irq); | 11247 | for_each_eth_queue(bp, i) { |
11234 | bnx2x_interrupt(bp->pdev->irq, dev); | 11248 | struct bnx2x_fastpath *fp = &bp->fp[i]; |
11235 | enable_irq(bp->pdev->irq); | 11249 | napi_schedule(&bnx2x_fp(bp, fp->index, napi)); |
11250 | } | ||
11236 | } | 11251 | } |
11237 | #endif | 11252 | #endif |
11238 | 11253 | ||
@@ -11899,9 +11914,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, | |||
11899 | */ | 11914 | */ |
11900 | bnx2x_set_int_mode(bp); | 11915 | bnx2x_set_int_mode(bp); |
11901 | 11916 | ||
11902 | /* Add all NAPI objects */ | ||
11903 | bnx2x_add_all_napi(bp); | ||
11904 | |||
11905 | rc = register_netdev(dev); | 11917 | rc = register_netdev(dev); |
11906 | if (rc) { | 11918 | if (rc) { |
11907 | dev_err(&pdev->dev, "Cannot register net device\n"); | 11919 | dev_err(&pdev->dev, "Cannot register net device\n"); |
@@ -11976,9 +11988,6 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) | |||
11976 | 11988 | ||
11977 | unregister_netdev(dev); | 11989 | unregister_netdev(dev); |
11978 | 11990 | ||
11979 | /* Delete all NAPI objects */ | ||
11980 | bnx2x_del_all_napi(bp); | ||
11981 | |||
11982 | /* Power on: we can't let PCI layer write to us while we are in D3 */ | 11991 | /* Power on: we can't let PCI layer write to us while we are in D3 */ |
11983 | bnx2x_set_power_state(bp, PCI_D0); | 11992 | bnx2x_set_power_state(bp, PCI_D0); |
11984 | 11993 | ||
@@ -12025,6 +12034,8 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) | |||
12025 | bnx2x_tx_disable(bp); | 12034 | bnx2x_tx_disable(bp); |
12026 | 12035 | ||
12027 | bnx2x_netif_stop(bp, 0); | 12036 | bnx2x_netif_stop(bp, 0); |
12037 | /* Delete all NAPI objects */ | ||
12038 | bnx2x_del_all_napi(bp); | ||
12028 | 12039 | ||
12029 | del_timer_sync(&bp->timer); | 12040 | del_timer_sync(&bp->timer); |
12030 | 12041 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 332db64dd5be..a1d0446b39b3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c | |||
@@ -101,6 +101,11 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp) | |||
101 | if (CHIP_REV_IS_SLOW(bp)) | 101 | if (CHIP_REV_IS_SLOW(bp)) |
102 | return; | 102 | return; |
103 | 103 | ||
104 | /* Update MCP's statistics if possible */ | ||
105 | if (bp->func_stx) | ||
106 | memcpy(bnx2x_sp(bp, func_stats), &bp->func_stats, | ||
107 | sizeof(bp->func_stats)); | ||
108 | |||
104 | /* loader */ | 109 | /* loader */ |
105 | if (bp->executer_idx) { | 110 | if (bp->executer_idx) { |
106 | int loader_idx = PMF_DMAE_C(bp); | 111 | int loader_idx = PMF_DMAE_C(bp); |
@@ -128,8 +133,6 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp) | |||
128 | 133 | ||
129 | } else if (bp->func_stx) { | 134 | } else if (bp->func_stx) { |
130 | *stats_comp = 0; | 135 | *stats_comp = 0; |
131 | memcpy(bnx2x_sp(bp, func_stats), &bp->func_stats, | ||
132 | sizeof(bp->func_stats)); | ||
133 | bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp)); | 136 | bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp)); |
134 | } | 137 | } |
135 | } | 138 | } |
@@ -1151,9 +1154,11 @@ static void bnx2x_stats_update(struct bnx2x *bp) | |||
1151 | if (bp->port.pmf) | 1154 | if (bp->port.pmf) |
1152 | bnx2x_hw_stats_update(bp); | 1155 | bnx2x_hw_stats_update(bp); |
1153 | 1156 | ||
1154 | if (bnx2x_storm_stats_update(bp) && (bp->stats_pending++ == 3)) { | 1157 | if (bnx2x_storm_stats_update(bp)) { |
1155 | BNX2X_ERR("storm stats were not updated for 3 times\n"); | 1158 | if (bp->stats_pending++ == 3) { |
1156 | bnx2x_panic(); | 1159 | BNX2X_ERR("storm stats were not updated for 3 times\n"); |
1160 | bnx2x_panic(); | ||
1161 | } | ||
1157 | return; | 1162 | return; |
1158 | } | 1163 | } |
1159 | 1164 | ||
diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c index 845b2020f291..138446957786 100644 --- a/drivers/net/ethernet/cirrus/cs89x0.c +++ b/drivers/net/ethernet/cirrus/cs89x0.c | |||
@@ -1243,6 +1243,7 @@ static void set_multicast_list(struct net_device *dev) | |||
1243 | { | 1243 | { |
1244 | struct net_local *lp = netdev_priv(dev); | 1244 | struct net_local *lp = netdev_priv(dev); |
1245 | unsigned long flags; | 1245 | unsigned long flags; |
1246 | u16 cfg; | ||
1246 | 1247 | ||
1247 | spin_lock_irqsave(&lp->lock, flags); | 1248 | spin_lock_irqsave(&lp->lock, flags); |
1248 | if (dev->flags & IFF_PROMISC) | 1249 | if (dev->flags & IFF_PROMISC) |
@@ -1260,11 +1261,10 @@ static void set_multicast_list(struct net_device *dev) | |||
1260 | /* in promiscuous mode, we accept errored packets, | 1261 | /* in promiscuous mode, we accept errored packets, |
1261 | * so we have to enable interrupts on them also | 1262 | * so we have to enable interrupts on them also |
1262 | */ | 1263 | */ |
1263 | writereg(dev, PP_RxCFG, | 1264 | cfg = lp->curr_rx_cfg; |
1264 | (lp->curr_rx_cfg | | 1265 | if (lp->rx_mode == RX_ALL_ACCEPT) |
1265 | (lp->rx_mode == RX_ALL_ACCEPT) | 1266 | cfg |= RX_CRC_ERROR_ENBL | RX_RUNT_ENBL | RX_EXTRA_DATA_ENBL; |
1266 | ? (RX_CRC_ERROR_ENBL | RX_RUNT_ENBL | RX_EXTRA_DATA_ENBL) | 1267 | writereg(dev, PP_RxCFG, cfg); |
1267 | : 0)); | ||
1268 | spin_unlock_irqrestore(&lp->lock, flags); | 1268 | spin_unlock_irqrestore(&lp->lock, flags); |
1269 | } | 1269 | } |
1270 | 1270 | ||
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 7fac97b4bb59..8c63d06ab12b 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -259,7 +259,7 @@ int be_process_mcc(struct be_adapter *adapter) | |||
259 | int num = 0, status = 0; | 259 | int num = 0, status = 0; |
260 | struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; | 260 | struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; |
261 | 261 | ||
262 | spin_lock_bh(&adapter->mcc_cq_lock); | 262 | spin_lock(&adapter->mcc_cq_lock); |
263 | while ((compl = be_mcc_compl_get(adapter))) { | 263 | while ((compl = be_mcc_compl_get(adapter))) { |
264 | if (compl->flags & CQE_FLAGS_ASYNC_MASK) { | 264 | if (compl->flags & CQE_FLAGS_ASYNC_MASK) { |
265 | /* Interpret flags as an async trailer */ | 265 | /* Interpret flags as an async trailer */ |
@@ -280,7 +280,7 @@ int be_process_mcc(struct be_adapter *adapter) | |||
280 | if (num) | 280 | if (num) |
281 | be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num); | 281 | be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num); |
282 | 282 | ||
283 | spin_unlock_bh(&adapter->mcc_cq_lock); | 283 | spin_unlock(&adapter->mcc_cq_lock); |
284 | return status; | 284 | return status; |
285 | } | 285 | } |
286 | 286 | ||
@@ -295,7 +295,9 @@ static int be_mcc_wait_compl(struct be_adapter *adapter) | |||
295 | if (be_error(adapter)) | 295 | if (be_error(adapter)) |
296 | return -EIO; | 296 | return -EIO; |
297 | 297 | ||
298 | local_bh_disable(); | ||
298 | status = be_process_mcc(adapter); | 299 | status = be_process_mcc(adapter); |
300 | local_bh_enable(); | ||
299 | 301 | ||
300 | if (atomic_read(&mcc_obj->q.used) == 0) | 302 | if (atomic_read(&mcc_obj->q.used) == 0) |
301 | break; | 303 | break; |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 90a903d83d87..78b8aa8069f0 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -3763,7 +3763,9 @@ static void be_worker(struct work_struct *work) | |||
3763 | /* when interrupts are not yet enabled, just reap any pending | 3763 | /* when interrupts are not yet enabled, just reap any pending |
3764 | * mcc completions */ | 3764 | * mcc completions */ |
3765 | if (!netif_running(adapter->netdev)) { | 3765 | if (!netif_running(adapter->netdev)) { |
3766 | local_bh_disable(); | ||
3766 | be_process_mcc(adapter); | 3767 | be_process_mcc(adapter); |
3768 | local_bh_enable(); | ||
3767 | goto reschedule; | 3769 | goto reschedule; |
3768 | } | 3770 | } |
3769 | 3771 | ||
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 4605f7246687..d3233f59a82e 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
@@ -1041,7 +1041,7 @@ static int gfar_probe(struct platform_device *ofdev) | |||
1041 | 1041 | ||
1042 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) { | 1042 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) { |
1043 | dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 1043 | dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; |
1044 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 1044 | dev->features |= NETIF_F_HW_VLAN_RX; |
1045 | } | 1045 | } |
1046 | 1046 | ||
1047 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) { | 1047 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) { |
diff --git a/drivers/net/ethernet/i825xx/znet.c b/drivers/net/ethernet/i825xx/znet.c index bd1f1ef91e19..ba4e0cea3506 100644 --- a/drivers/net/ethernet/i825xx/znet.c +++ b/drivers/net/ethernet/i825xx/znet.c | |||
@@ -139,8 +139,11 @@ struct znet_private { | |||
139 | /* Only one can be built-in;-> */ | 139 | /* Only one can be built-in;-> */ |
140 | static struct net_device *znet_dev; | 140 | static struct net_device *znet_dev; |
141 | 141 | ||
142 | #define NETIDBLK_MAGIC "NETIDBLK" | ||
143 | #define NETIDBLK_MAGIC_SIZE 8 | ||
144 | |||
142 | struct netidblk { | 145 | struct netidblk { |
143 | char magic[8]; /* The magic number (string) "NETIDBLK" */ | 146 | char magic[NETIDBLK_MAGIC_SIZE]; /* The magic number (string) "NETIDBLK" */ |
144 | unsigned char netid[8]; /* The physical station address */ | 147 | unsigned char netid[8]; /* The physical station address */ |
145 | char nettype, globalopt; | 148 | char nettype, globalopt; |
146 | char vendor[8]; /* The machine vendor and product name. */ | 149 | char vendor[8]; /* The machine vendor and product name. */ |
@@ -373,14 +376,16 @@ static int __init znet_probe (void) | |||
373 | struct znet_private *znet; | 376 | struct znet_private *znet; |
374 | struct net_device *dev; | 377 | struct net_device *dev; |
375 | char *p; | 378 | char *p; |
379 | char *plast = phys_to_virt(0x100000 - NETIDBLK_MAGIC_SIZE); | ||
376 | int err = -ENOMEM; | 380 | int err = -ENOMEM; |
377 | 381 | ||
378 | /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */ | 382 | /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */ |
379 | for(p = (char *)phys_to_virt(0xf0000); p < (char *)phys_to_virt(0x100000); p++) | 383 | for(p = (char *)phys_to_virt(0xf0000); p <= plast; p++) |
380 | if (*p == 'N' && strncmp(p, "NETIDBLK", 8) == 0) | 384 | if (*p == 'N' && |
385 | strncmp(p, NETIDBLK_MAGIC, NETIDBLK_MAGIC_SIZE) == 0) | ||
381 | break; | 386 | break; |
382 | 387 | ||
383 | if (p >= (char *)phys_to_virt(0x100000)) { | 388 | if (p > plast) { |
384 | if (znet_debug > 1) | 389 | if (znet_debug > 1) |
385 | printk(KERN_INFO "No Z-Note ethernet adaptor found.\n"); | 390 | printk(KERN_INFO "No Z-Note ethernet adaptor found.\n"); |
386 | return -ENODEV; | 391 | return -ENODEV; |
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index 9010cea68bc3..b68d28a130e6 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c | |||
@@ -472,14 +472,9 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) | |||
472 | } | 472 | } |
473 | 473 | ||
474 | if (adapter->rx_queue.queue_addr != NULL) { | 474 | if (adapter->rx_queue.queue_addr != NULL) { |
475 | if (!dma_mapping_error(dev, adapter->rx_queue.queue_dma)) { | 475 | dma_free_coherent(dev, adapter->rx_queue.queue_len, |
476 | dma_unmap_single(dev, | 476 | adapter->rx_queue.queue_addr, |
477 | adapter->rx_queue.queue_dma, | 477 | adapter->rx_queue.queue_dma); |
478 | adapter->rx_queue.queue_len, | ||
479 | DMA_BIDIRECTIONAL); | ||
480 | adapter->rx_queue.queue_dma = DMA_ERROR_CODE; | ||
481 | } | ||
482 | kfree(adapter->rx_queue.queue_addr); | ||
483 | adapter->rx_queue.queue_addr = NULL; | 478 | adapter->rx_queue.queue_addr = NULL; |
484 | } | 479 | } |
485 | 480 | ||
@@ -556,10 +551,13 @@ static int ibmveth_open(struct net_device *netdev) | |||
556 | goto err_out; | 551 | goto err_out; |
557 | } | 552 | } |
558 | 553 | ||
554 | dev = &adapter->vdev->dev; | ||
555 | |||
559 | adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * | 556 | adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * |
560 | rxq_entries; | 557 | rxq_entries; |
561 | adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len, | 558 | adapter->rx_queue.queue_addr = |
562 | GFP_KERNEL); | 559 | dma_alloc_coherent(dev, adapter->rx_queue.queue_len, |
560 | &adapter->rx_queue.queue_dma, GFP_KERNEL); | ||
563 | 561 | ||
564 | if (!adapter->rx_queue.queue_addr) { | 562 | if (!adapter->rx_queue.queue_addr) { |
565 | netdev_err(netdev, "unable to allocate rx queue pages\n"); | 563 | netdev_err(netdev, "unable to allocate rx queue pages\n"); |
@@ -567,19 +565,13 @@ static int ibmveth_open(struct net_device *netdev) | |||
567 | goto err_out; | 565 | goto err_out; |
568 | } | 566 | } |
569 | 567 | ||
570 | dev = &adapter->vdev->dev; | ||
571 | |||
572 | adapter->buffer_list_dma = dma_map_single(dev, | 568 | adapter->buffer_list_dma = dma_map_single(dev, |
573 | adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL); | 569 | adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL); |
574 | adapter->filter_list_dma = dma_map_single(dev, | 570 | adapter->filter_list_dma = dma_map_single(dev, |
575 | adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL); | 571 | adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL); |
576 | adapter->rx_queue.queue_dma = dma_map_single(dev, | ||
577 | adapter->rx_queue.queue_addr, | ||
578 | adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL); | ||
579 | 572 | ||
580 | if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || | 573 | if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || |
581 | (dma_mapping_error(dev, adapter->filter_list_dma)) || | 574 | (dma_mapping_error(dev, adapter->filter_list_dma))) { |
582 | (dma_mapping_error(dev, adapter->rx_queue.queue_dma))) { | ||
583 | netdev_err(netdev, "unable to map filter or buffer list " | 575 | netdev_err(netdev, "unable to map filter or buffer list " |
584 | "pages\n"); | 576 | "pages\n"); |
585 | rc = -ENOMEM; | 577 | rc = -ENOMEM; |
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index cd153326c3cf..cb3356c9af80 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h | |||
@@ -310,6 +310,7 @@ struct e1000_adapter { | |||
310 | */ | 310 | */ |
311 | struct e1000_ring *tx_ring /* One per active queue */ | 311 | struct e1000_ring *tx_ring /* One per active queue */ |
312 | ____cacheline_aligned_in_smp; | 312 | ____cacheline_aligned_in_smp; |
313 | u32 tx_fifo_limit; | ||
313 | 314 | ||
314 | struct napi_struct napi; | 315 | struct napi_struct napi; |
315 | 316 | ||
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 46c3b1f9ff89..d01a099475a1 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
@@ -3517,6 +3517,15 @@ void e1000e_reset(struct e1000_adapter *adapter) | |||
3517 | } | 3517 | } |
3518 | 3518 | ||
3519 | /* | 3519 | /* |
3520 | * Alignment of Tx data is on an arbitrary byte boundary with the | ||
3521 | * maximum size per Tx descriptor limited only to the transmit | ||
3522 | * allocation of the packet buffer minus 96 bytes with an upper | ||
3523 | * limit of 24KB due to receive synchronization limitations. | ||
3524 | */ | ||
3525 | adapter->tx_fifo_limit = min_t(u32, ((er32(PBA) >> 16) << 10) - 96, | ||
3526 | 24 << 10); | ||
3527 | |||
3528 | /* | ||
3520 | * Disable Adaptive Interrupt Moderation if 2 full packets cannot | 3529 | * Disable Adaptive Interrupt Moderation if 2 full packets cannot |
3521 | * fit in receive buffer. | 3530 | * fit in receive buffer. |
3522 | */ | 3531 | */ |
@@ -4785,12 +4794,9 @@ static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb) | |||
4785 | return 1; | 4794 | return 1; |
4786 | } | 4795 | } |
4787 | 4796 | ||
4788 | #define E1000_MAX_PER_TXD 8192 | ||
4789 | #define E1000_MAX_TXD_PWR 12 | ||
4790 | |||
4791 | static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb, | 4797 | static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb, |
4792 | unsigned int first, unsigned int max_per_txd, | 4798 | unsigned int first, unsigned int max_per_txd, |
4793 | unsigned int nr_frags, unsigned int mss) | 4799 | unsigned int nr_frags) |
4794 | { | 4800 | { |
4795 | struct e1000_adapter *adapter = tx_ring->adapter; | 4801 | struct e1000_adapter *adapter = tx_ring->adapter; |
4796 | struct pci_dev *pdev = adapter->pdev; | 4802 | struct pci_dev *pdev = adapter->pdev; |
@@ -5023,20 +5029,19 @@ static int __e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size) | |||
5023 | 5029 | ||
5024 | static int e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size) | 5030 | static int e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size) |
5025 | { | 5031 | { |
5032 | BUG_ON(size > tx_ring->count); | ||
5033 | |||
5026 | if (e1000_desc_unused(tx_ring) >= size) | 5034 | if (e1000_desc_unused(tx_ring) >= size) |
5027 | return 0; | 5035 | return 0; |
5028 | return __e1000_maybe_stop_tx(tx_ring, size); | 5036 | return __e1000_maybe_stop_tx(tx_ring, size); |
5029 | } | 5037 | } |
5030 | 5038 | ||
5031 | #define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1) | ||
5032 | static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | 5039 | static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, |
5033 | struct net_device *netdev) | 5040 | struct net_device *netdev) |
5034 | { | 5041 | { |
5035 | struct e1000_adapter *adapter = netdev_priv(netdev); | 5042 | struct e1000_adapter *adapter = netdev_priv(netdev); |
5036 | struct e1000_ring *tx_ring = adapter->tx_ring; | 5043 | struct e1000_ring *tx_ring = adapter->tx_ring; |
5037 | unsigned int first; | 5044 | unsigned int first; |
5038 | unsigned int max_per_txd = E1000_MAX_PER_TXD; | ||
5039 | unsigned int max_txd_pwr = E1000_MAX_TXD_PWR; | ||
5040 | unsigned int tx_flags = 0; | 5045 | unsigned int tx_flags = 0; |
5041 | unsigned int len = skb_headlen(skb); | 5046 | unsigned int len = skb_headlen(skb); |
5042 | unsigned int nr_frags; | 5047 | unsigned int nr_frags; |
@@ -5056,18 +5061,8 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | |||
5056 | } | 5061 | } |
5057 | 5062 | ||
5058 | mss = skb_shinfo(skb)->gso_size; | 5063 | mss = skb_shinfo(skb)->gso_size; |
5059 | /* | ||
5060 | * The controller does a simple calculation to | ||
5061 | * make sure there is enough room in the FIFO before | ||
5062 | * initiating the DMA for each buffer. The calc is: | ||
5063 | * 4 = ceil(buffer len/mss). To make sure we don't | ||
5064 | * overrun the FIFO, adjust the max buffer len if mss | ||
5065 | * drops. | ||
5066 | */ | ||
5067 | if (mss) { | 5064 | if (mss) { |
5068 | u8 hdr_len; | 5065 | u8 hdr_len; |
5069 | max_per_txd = min(mss << 2, max_per_txd); | ||
5070 | max_txd_pwr = fls(max_per_txd) - 1; | ||
5071 | 5066 | ||
5072 | /* | 5067 | /* |
5073 | * TSO Workaround for 82571/2/3 Controllers -- if skb->data | 5068 | * TSO Workaround for 82571/2/3 Controllers -- if skb->data |
@@ -5097,12 +5092,12 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | |||
5097 | count++; | 5092 | count++; |
5098 | count++; | 5093 | count++; |
5099 | 5094 | ||
5100 | count += TXD_USE_COUNT(len, max_txd_pwr); | 5095 | count += DIV_ROUND_UP(len, adapter->tx_fifo_limit); |
5101 | 5096 | ||
5102 | nr_frags = skb_shinfo(skb)->nr_frags; | 5097 | nr_frags = skb_shinfo(skb)->nr_frags; |
5103 | for (f = 0; f < nr_frags; f++) | 5098 | for (f = 0; f < nr_frags; f++) |
5104 | count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f]), | 5099 | count += DIV_ROUND_UP(skb_frag_size(&skb_shinfo(skb)->frags[f]), |
5105 | max_txd_pwr); | 5100 | adapter->tx_fifo_limit); |
5106 | 5101 | ||
5107 | if (adapter->hw.mac.tx_pkt_filtering) | 5102 | if (adapter->hw.mac.tx_pkt_filtering) |
5108 | e1000_transfer_dhcp_info(adapter, skb); | 5103 | e1000_transfer_dhcp_info(adapter, skb); |
@@ -5144,15 +5139,18 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | |||
5144 | tx_flags |= E1000_TX_FLAGS_NO_FCS; | 5139 | tx_flags |= E1000_TX_FLAGS_NO_FCS; |
5145 | 5140 | ||
5146 | /* if count is 0 then mapping error has occurred */ | 5141 | /* if count is 0 then mapping error has occurred */ |
5147 | count = e1000_tx_map(tx_ring, skb, first, max_per_txd, nr_frags, mss); | 5142 | count = e1000_tx_map(tx_ring, skb, first, adapter->tx_fifo_limit, |
5143 | nr_frags); | ||
5148 | if (count) { | 5144 | if (count) { |
5149 | skb_tx_timestamp(skb); | 5145 | skb_tx_timestamp(skb); |
5150 | 5146 | ||
5151 | netdev_sent_queue(netdev, skb->len); | 5147 | netdev_sent_queue(netdev, skb->len); |
5152 | e1000_tx_queue(tx_ring, tx_flags, count); | 5148 | e1000_tx_queue(tx_ring, tx_flags, count); |
5153 | /* Make sure there is space in the ring for the next send. */ | 5149 | /* Make sure there is space in the ring for the next send. */ |
5154 | e1000_maybe_stop_tx(tx_ring, MAX_SKB_FRAGS + 2); | 5150 | e1000_maybe_stop_tx(tx_ring, |
5155 | 5151 | (MAX_SKB_FRAGS * | |
5152 | DIV_ROUND_UP(PAGE_SIZE, | ||
5153 | adapter->tx_fifo_limit) + 2)); | ||
5156 | } else { | 5154 | } else { |
5157 | dev_kfree_skb_any(skb); | 5155 | dev_kfree_skb_any(skb); |
5158 | tx_ring->buffer_info[first].time_stamp = 0; | 5156 | tx_ring->buffer_info[first].time_stamp = 0; |
@@ -6327,8 +6325,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
6327 | adapter->hw.phy.autoneg_advertised = 0x2f; | 6325 | adapter->hw.phy.autoneg_advertised = 0x2f; |
6328 | 6326 | ||
6329 | /* ring size defaults */ | 6327 | /* ring size defaults */ |
6330 | adapter->rx_ring->count = 256; | 6328 | adapter->rx_ring->count = E1000_DEFAULT_RXD; |
6331 | adapter->tx_ring->count = 256; | 6329 | adapter->tx_ring->count = E1000_DEFAULT_TXD; |
6332 | 6330 | ||
6333 | /* | 6331 | /* |
6334 | * Initial Wake on LAN setting - If APM wake is enabled in | 6332 | * Initial Wake on LAN setting - If APM wake is enabled in |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 827b72dfce99..2f816c6aed72 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -1234,13 +1234,13 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1234 | mlx4_info(dev, "non-primary physical function, skipping.\n"); | 1234 | mlx4_info(dev, "non-primary physical function, skipping.\n"); |
1235 | else | 1235 | else |
1236 | mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); | 1236 | mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); |
1237 | goto unmap_bf; | 1237 | return err; |
1238 | } | 1238 | } |
1239 | 1239 | ||
1240 | err = mlx4_load_fw(dev); | 1240 | err = mlx4_load_fw(dev); |
1241 | if (err) { | 1241 | if (err) { |
1242 | mlx4_err(dev, "Failed to start FW, aborting.\n"); | 1242 | mlx4_err(dev, "Failed to start FW, aborting.\n"); |
1243 | goto unmap_bf; | 1243 | return err; |
1244 | } | 1244 | } |
1245 | 1245 | ||
1246 | mlx4_cfg.log_pg_sz_m = 1; | 1246 | mlx4_cfg.log_pg_sz_m = 1; |
@@ -1304,7 +1304,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1304 | err = mlx4_init_slave(dev); | 1304 | err = mlx4_init_slave(dev); |
1305 | if (err) { | 1305 | if (err) { |
1306 | mlx4_err(dev, "Failed to initialize slave\n"); | 1306 | mlx4_err(dev, "Failed to initialize slave\n"); |
1307 | goto unmap_bf; | 1307 | return err; |
1308 | } | 1308 | } |
1309 | 1309 | ||
1310 | err = mlx4_slave_cap(dev); | 1310 | err = mlx4_slave_cap(dev); |
@@ -1324,7 +1324,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1324 | err = mlx4_QUERY_ADAPTER(dev, &adapter); | 1324 | err = mlx4_QUERY_ADAPTER(dev, &adapter); |
1325 | if (err) { | 1325 | if (err) { |
1326 | mlx4_err(dev, "QUERY_ADAPTER command failed, aborting.\n"); | 1326 | mlx4_err(dev, "QUERY_ADAPTER command failed, aborting.\n"); |
1327 | goto err_close; | 1327 | goto unmap_bf; |
1328 | } | 1328 | } |
1329 | 1329 | ||
1330 | priv->eq_table.inta_pin = adapter.inta_pin; | 1330 | priv->eq_table.inta_pin = adapter.inta_pin; |
@@ -1332,6 +1332,9 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1332 | 1332 | ||
1333 | return 0; | 1333 | return 0; |
1334 | 1334 | ||
1335 | unmap_bf: | ||
1336 | unmap_bf_area(dev); | ||
1337 | |||
1335 | err_close: | 1338 | err_close: |
1336 | mlx4_close_hca(dev); | 1339 | mlx4_close_hca(dev); |
1337 | 1340 | ||
@@ -1344,8 +1347,6 @@ err_stop_fw: | |||
1344 | mlx4_UNMAP_FA(dev); | 1347 | mlx4_UNMAP_FA(dev); |
1345 | mlx4_free_icm(dev, priv->fw.fw_icm, 0); | 1348 | mlx4_free_icm(dev, priv->fw.fw_icm, 0); |
1346 | } | 1349 | } |
1347 | unmap_bf: | ||
1348 | unmap_bf_area(dev); | ||
1349 | return err; | 1350 | return err; |
1350 | } | 1351 | } |
1351 | 1352 | ||
@@ -1996,7 +1997,8 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1996 | } | 1997 | } |
1997 | 1998 | ||
1998 | slave_start: | 1999 | slave_start: |
1999 | if (mlx4_cmd_init(dev)) { | 2000 | err = mlx4_cmd_init(dev); |
2001 | if (err) { | ||
2000 | mlx4_err(dev, "Failed to init command interface, aborting.\n"); | 2002 | mlx4_err(dev, "Failed to init command interface, aborting.\n"); |
2001 | goto err_sriov; | 2003 | goto err_sriov; |
2002 | } | 2004 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index a018ea2a43de..e151c21baf2b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c | |||
@@ -137,11 +137,11 @@ static int mlx4_GID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, | |||
137 | return err; | 137 | return err; |
138 | } | 138 | } |
139 | 139 | ||
140 | static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 pf_num, | 140 | static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 port, |
141 | enum mlx4_steer_type steer, | 141 | enum mlx4_steer_type steer, |
142 | u32 qpn) | 142 | u32 qpn) |
143 | { | 143 | { |
144 | struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[pf_num]; | 144 | struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[port - 1]; |
145 | struct mlx4_promisc_qp *pqp; | 145 | struct mlx4_promisc_qp *pqp; |
146 | 146 | ||
147 | list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { | 147 | list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { |
@@ -182,7 +182,7 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 port, | |||
182 | /* If the given qpn is also a promisc qp, | 182 | /* If the given qpn is also a promisc qp, |
183 | * it should be inserted to duplicates list | 183 | * it should be inserted to duplicates list |
184 | */ | 184 | */ |
185 | pqp = get_promisc_qp(dev, 0, steer, qpn); | 185 | pqp = get_promisc_qp(dev, port, steer, qpn); |
186 | if (pqp) { | 186 | if (pqp) { |
187 | dqp = kmalloc(sizeof *dqp, GFP_KERNEL); | 187 | dqp = kmalloc(sizeof *dqp, GFP_KERNEL); |
188 | if (!dqp) { | 188 | if (!dqp) { |
@@ -256,7 +256,7 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 port, | |||
256 | 256 | ||
257 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 257 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
258 | 258 | ||
259 | pqp = get_promisc_qp(dev, 0, steer, qpn); | 259 | pqp = get_promisc_qp(dev, port, steer, qpn); |
260 | if (!pqp) | 260 | if (!pqp) |
261 | return 0; /* nothing to do */ | 261 | return 0; /* nothing to do */ |
262 | 262 | ||
@@ -302,7 +302,7 @@ static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port, | |||
302 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 302 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
303 | 303 | ||
304 | /* if qp is not promisc, it cannot be duplicated */ | 304 | /* if qp is not promisc, it cannot be duplicated */ |
305 | if (!get_promisc_qp(dev, 0, steer, qpn)) | 305 | if (!get_promisc_qp(dev, port, steer, qpn)) |
306 | return false; | 306 | return false; |
307 | 307 | ||
308 | /* The qp is promisc qp so it is a duplicate on this index | 308 | /* The qp is promisc qp so it is a duplicate on this index |
@@ -352,7 +352,7 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port, | |||
352 | members_count = be32_to_cpu(mgm->members_count) & 0xffffff; | 352 | members_count = be32_to_cpu(mgm->members_count) & 0xffffff; |
353 | for (i = 0; i < members_count; i++) { | 353 | for (i = 0; i < members_count; i++) { |
354 | qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK; | 354 | qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK; |
355 | if (!get_promisc_qp(dev, 0, steer, qpn) && qpn != tqpn) { | 355 | if (!get_promisc_qp(dev, port, steer, qpn) && qpn != tqpn) { |
356 | /* the qp is not promisc, the entry can't be removed */ | 356 | /* the qp is not promisc, the entry can't be removed */ |
357 | goto out; | 357 | goto out; |
358 | } | 358 | } |
@@ -398,7 +398,7 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port, | |||
398 | 398 | ||
399 | mutex_lock(&priv->mcg_table.mutex); | 399 | mutex_lock(&priv->mcg_table.mutex); |
400 | 400 | ||
401 | if (get_promisc_qp(dev, 0, steer, qpn)) { | 401 | if (get_promisc_qp(dev, port, steer, qpn)) { |
402 | err = 0; /* Noting to do, already exists */ | 402 | err = 0; /* Noting to do, already exists */ |
403 | goto out_mutex; | 403 | goto out_mutex; |
404 | } | 404 | } |
@@ -503,7 +503,7 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port, | |||
503 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 503 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
504 | mutex_lock(&priv->mcg_table.mutex); | 504 | mutex_lock(&priv->mcg_table.mutex); |
505 | 505 | ||
506 | pqp = get_promisc_qp(dev, 0, steer, qpn); | 506 | pqp = get_promisc_qp(dev, port, steer, qpn); |
507 | if (unlikely(!pqp)) { | 507 | if (unlikely(!pqp)) { |
508 | mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn); | 508 | mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn); |
509 | /* nothing to do */ | 509 | /* nothing to do */ |
@@ -650,13 +650,6 @@ static int find_entry(struct mlx4_dev *dev, u8 port, | |||
650 | return err; | 650 | return err; |
651 | } | 651 | } |
652 | 652 | ||
653 | struct mlx4_net_trans_rule_hw_ctrl { | ||
654 | __be32 ctrl; | ||
655 | __be32 vf_vep_port; | ||
656 | __be32 qpn; | ||
657 | __be32 reserved; | ||
658 | }; | ||
659 | |||
660 | static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, | 653 | static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, |
661 | struct mlx4_net_trans_rule_hw_ctrl *hw) | 654 | struct mlx4_net_trans_rule_hw_ctrl *hw) |
662 | { | 655 | { |
@@ -680,87 +673,18 @@ static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, | |||
680 | hw->qpn = cpu_to_be32(ctrl->qpn); | 673 | hw->qpn = cpu_to_be32(ctrl->qpn); |
681 | } | 674 | } |
682 | 675 | ||
683 | struct mlx4_net_trans_rule_hw_ib { | 676 | const u16 __sw_id_hw[] = { |
684 | u8 size; | 677 | [MLX4_NET_TRANS_RULE_ID_ETH] = 0xE001, |
685 | u8 rsvd1; | 678 | [MLX4_NET_TRANS_RULE_ID_IB] = 0xE005, |
686 | __be16 id; | 679 | [MLX4_NET_TRANS_RULE_ID_IPV6] = 0xE003, |
687 | u32 rsvd2; | 680 | [MLX4_NET_TRANS_RULE_ID_IPV4] = 0xE002, |
688 | __be32 qpn; | 681 | [MLX4_NET_TRANS_RULE_ID_TCP] = 0xE004, |
689 | __be32 qpn_mask; | 682 | [MLX4_NET_TRANS_RULE_ID_UDP] = 0xE006 |
690 | u8 dst_gid[16]; | ||
691 | u8 dst_gid_msk[16]; | ||
692 | } __packed; | ||
693 | |||
694 | struct mlx4_net_trans_rule_hw_eth { | ||
695 | u8 size; | ||
696 | u8 rsvd; | ||
697 | __be16 id; | ||
698 | u8 rsvd1[6]; | ||
699 | u8 dst_mac[6]; | ||
700 | u16 rsvd2; | ||
701 | u8 dst_mac_msk[6]; | ||
702 | u16 rsvd3; | ||
703 | u8 src_mac[6]; | ||
704 | u16 rsvd4; | ||
705 | u8 src_mac_msk[6]; | ||
706 | u8 rsvd5; | ||
707 | u8 ether_type_enable; | ||
708 | __be16 ether_type; | ||
709 | __be16 vlan_id_msk; | ||
710 | __be16 vlan_id; | ||
711 | } __packed; | ||
712 | |||
713 | struct mlx4_net_trans_rule_hw_tcp_udp { | ||
714 | u8 size; | ||
715 | u8 rsvd; | ||
716 | __be16 id; | ||
717 | __be16 rsvd1[3]; | ||
718 | __be16 dst_port; | ||
719 | __be16 rsvd2; | ||
720 | __be16 dst_port_msk; | ||
721 | __be16 rsvd3; | ||
722 | __be16 src_port; | ||
723 | __be16 rsvd4; | ||
724 | __be16 src_port_msk; | ||
725 | } __packed; | ||
726 | |||
727 | struct mlx4_net_trans_rule_hw_ipv4 { | ||
728 | u8 size; | ||
729 | u8 rsvd; | ||
730 | __be16 id; | ||
731 | __be32 rsvd1; | ||
732 | __be32 dst_ip; | ||
733 | __be32 dst_ip_msk; | ||
734 | __be32 src_ip; | ||
735 | __be32 src_ip_msk; | ||
736 | } __packed; | ||
737 | |||
738 | struct _rule_hw { | ||
739 | union { | ||
740 | struct { | ||
741 | u8 size; | ||
742 | u8 rsvd; | ||
743 | __be16 id; | ||
744 | }; | ||
745 | struct mlx4_net_trans_rule_hw_eth eth; | ||
746 | struct mlx4_net_trans_rule_hw_ib ib; | ||
747 | struct mlx4_net_trans_rule_hw_ipv4 ipv4; | ||
748 | struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp; | ||
749 | }; | ||
750 | }; | 683 | }; |
751 | 684 | ||
752 | static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec, | 685 | static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec, |
753 | struct _rule_hw *rule_hw) | 686 | struct _rule_hw *rule_hw) |
754 | { | 687 | { |
755 | static const u16 __sw_id_hw[] = { | ||
756 | [MLX4_NET_TRANS_RULE_ID_ETH] = 0xE001, | ||
757 | [MLX4_NET_TRANS_RULE_ID_IB] = 0xE005, | ||
758 | [MLX4_NET_TRANS_RULE_ID_IPV6] = 0xE003, | ||
759 | [MLX4_NET_TRANS_RULE_ID_IPV4] = 0xE002, | ||
760 | [MLX4_NET_TRANS_RULE_ID_TCP] = 0xE004, | ||
761 | [MLX4_NET_TRANS_RULE_ID_UDP] = 0xE006 | ||
762 | }; | ||
763 | |||
764 | static const size_t __rule_hw_sz[] = { | 688 | static const size_t __rule_hw_sz[] = { |
765 | [MLX4_NET_TRANS_RULE_ID_ETH] = | 689 | [MLX4_NET_TRANS_RULE_ID_ETH] = |
766 | sizeof(struct mlx4_net_trans_rule_hw_eth), | 690 | sizeof(struct mlx4_net_trans_rule_hw_eth), |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 4d9df8f2a126..dba69d98734a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -690,6 +690,82 @@ struct mlx4_steer { | |||
690 | struct list_head steer_entries[MLX4_NUM_STEERS]; | 690 | struct list_head steer_entries[MLX4_NUM_STEERS]; |
691 | }; | 691 | }; |
692 | 692 | ||
693 | struct mlx4_net_trans_rule_hw_ctrl { | ||
694 | __be32 ctrl; | ||
695 | __be32 vf_vep_port; | ||
696 | __be32 qpn; | ||
697 | __be32 reserved; | ||
698 | }; | ||
699 | |||
700 | struct mlx4_net_trans_rule_hw_ib { | ||
701 | u8 size; | ||
702 | u8 rsvd1; | ||
703 | __be16 id; | ||
704 | u32 rsvd2; | ||
705 | __be32 qpn; | ||
706 | __be32 qpn_mask; | ||
707 | u8 dst_gid[16]; | ||
708 | u8 dst_gid_msk[16]; | ||
709 | } __packed; | ||
710 | |||
711 | struct mlx4_net_trans_rule_hw_eth { | ||
712 | u8 size; | ||
713 | u8 rsvd; | ||
714 | __be16 id; | ||
715 | u8 rsvd1[6]; | ||
716 | u8 dst_mac[6]; | ||
717 | u16 rsvd2; | ||
718 | u8 dst_mac_msk[6]; | ||
719 | u16 rsvd3; | ||
720 | u8 src_mac[6]; | ||
721 | u16 rsvd4; | ||
722 | u8 src_mac_msk[6]; | ||
723 | u8 rsvd5; | ||
724 | u8 ether_type_enable; | ||
725 | __be16 ether_type; | ||
726 | __be16 vlan_id_msk; | ||
727 | __be16 vlan_id; | ||
728 | } __packed; | ||
729 | |||
730 | struct mlx4_net_trans_rule_hw_tcp_udp { | ||
731 | u8 size; | ||
732 | u8 rsvd; | ||
733 | __be16 id; | ||
734 | __be16 rsvd1[3]; | ||
735 | __be16 dst_port; | ||
736 | __be16 rsvd2; | ||
737 | __be16 dst_port_msk; | ||
738 | __be16 rsvd3; | ||
739 | __be16 src_port; | ||
740 | __be16 rsvd4; | ||
741 | __be16 src_port_msk; | ||
742 | } __packed; | ||
743 | |||
744 | struct mlx4_net_trans_rule_hw_ipv4 { | ||
745 | u8 size; | ||
746 | u8 rsvd; | ||
747 | __be16 id; | ||
748 | __be32 rsvd1; | ||
749 | __be32 dst_ip; | ||
750 | __be32 dst_ip_msk; | ||
751 | __be32 src_ip; | ||
752 | __be32 src_ip_msk; | ||
753 | } __packed; | ||
754 | |||
755 | struct _rule_hw { | ||
756 | union { | ||
757 | struct { | ||
758 | u8 size; | ||
759 | u8 rsvd; | ||
760 | __be16 id; | ||
761 | }; | ||
762 | struct mlx4_net_trans_rule_hw_eth eth; | ||
763 | struct mlx4_net_trans_rule_hw_ib ib; | ||
764 | struct mlx4_net_trans_rule_hw_ipv4 ipv4; | ||
765 | struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp; | ||
766 | }; | ||
767 | }; | ||
768 | |||
693 | struct mlx4_priv { | 769 | struct mlx4_priv { |
694 | struct mlx4_dev dev; | 770 | struct mlx4_dev dev; |
695 | 771 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 94ceddd17ab2..293c9e820c49 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/mlx4/cmd.h> | 42 | #include <linux/mlx4/cmd.h> |
43 | #include <linux/mlx4/qp.h> | 43 | #include <linux/mlx4/qp.h> |
44 | #include <linux/if_ether.h> | 44 | #include <linux/if_ether.h> |
45 | #include <linux/etherdevice.h> | ||
45 | 46 | ||
46 | #include "mlx4.h" | 47 | #include "mlx4.h" |
47 | #include "fw.h" | 48 | #include "fw.h" |
@@ -2776,18 +2777,133 @@ ex_put: | |||
2776 | return err; | 2777 | return err; |
2777 | } | 2778 | } |
2778 | 2779 | ||
2780 | /* | ||
2781 | * MAC validation for Flow Steering rules. | ||
2782 | * VF can attach rules only with a mac address which is assigned to it. | ||
2783 | */ | ||
2784 | static int validate_eth_header_mac(int slave, struct _rule_hw *eth_header, | ||
2785 | struct list_head *rlist) | ||
2786 | { | ||
2787 | struct mac_res *res, *tmp; | ||
2788 | __be64 be_mac; | ||
2789 | |||
2790 | /* make sure it isn't multicast or broadcast mac*/ | ||
2791 | if (!is_multicast_ether_addr(eth_header->eth.dst_mac) && | ||
2792 | !is_broadcast_ether_addr(eth_header->eth.dst_mac)) { | ||
2793 | list_for_each_entry_safe(res, tmp, rlist, list) { | ||
2794 | be_mac = cpu_to_be64(res->mac << 16); | ||
2795 | if (!memcmp(&be_mac, eth_header->eth.dst_mac, ETH_ALEN)) | ||
2796 | return 0; | ||
2797 | } | ||
2798 | pr_err("MAC %pM doesn't belong to VF %d, Steering rule rejected\n", | ||
2799 | eth_header->eth.dst_mac, slave); | ||
2800 | return -EINVAL; | ||
2801 | } | ||
2802 | return 0; | ||
2803 | } | ||
2804 | |||
2805 | /* | ||
2806 | * In case of missing eth header, append eth header with a MAC address | ||
2807 | * assigned to the VF. | ||
2808 | */ | ||
2809 | static int add_eth_header(struct mlx4_dev *dev, int slave, | ||
2810 | struct mlx4_cmd_mailbox *inbox, | ||
2811 | struct list_head *rlist, int header_id) | ||
2812 | { | ||
2813 | struct mac_res *res, *tmp; | ||
2814 | u8 port; | ||
2815 | struct mlx4_net_trans_rule_hw_ctrl *ctrl; | ||
2816 | struct mlx4_net_trans_rule_hw_eth *eth_header; | ||
2817 | struct mlx4_net_trans_rule_hw_ipv4 *ip_header; | ||
2818 | struct mlx4_net_trans_rule_hw_tcp_udp *l4_header; | ||
2819 | __be64 be_mac = 0; | ||
2820 | __be64 mac_msk = cpu_to_be64(MLX4_MAC_MASK << 16); | ||
2821 | |||
2822 | ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; | ||
2823 | port = be32_to_cpu(ctrl->vf_vep_port) & 0xff; | ||
2824 | eth_header = (struct mlx4_net_trans_rule_hw_eth *)(ctrl + 1); | ||
2825 | |||
2826 | /* Clear a space in the inbox for eth header */ | ||
2827 | switch (header_id) { | ||
2828 | case MLX4_NET_TRANS_RULE_ID_IPV4: | ||
2829 | ip_header = | ||
2830 | (struct mlx4_net_trans_rule_hw_ipv4 *)(eth_header + 1); | ||
2831 | memmove(ip_header, eth_header, | ||
2832 | sizeof(*ip_header) + sizeof(*l4_header)); | ||
2833 | break; | ||
2834 | case MLX4_NET_TRANS_RULE_ID_TCP: | ||
2835 | case MLX4_NET_TRANS_RULE_ID_UDP: | ||
2836 | l4_header = (struct mlx4_net_trans_rule_hw_tcp_udp *) | ||
2837 | (eth_header + 1); | ||
2838 | memmove(l4_header, eth_header, sizeof(*l4_header)); | ||
2839 | break; | ||
2840 | default: | ||
2841 | return -EINVAL; | ||
2842 | } | ||
2843 | list_for_each_entry_safe(res, tmp, rlist, list) { | ||
2844 | if (port == res->port) { | ||
2845 | be_mac = cpu_to_be64(res->mac << 16); | ||
2846 | break; | ||
2847 | } | ||
2848 | } | ||
2849 | if (!be_mac) { | ||
2850 | pr_err("Failed adding eth header to FS rule, Can't find matching MAC for port %d .\n", | ||
2851 | port); | ||
2852 | return -EINVAL; | ||
2853 | } | ||
2854 | |||
2855 | memset(eth_header, 0, sizeof(*eth_header)); | ||
2856 | eth_header->size = sizeof(*eth_header) >> 2; | ||
2857 | eth_header->id = cpu_to_be16(__sw_id_hw[MLX4_NET_TRANS_RULE_ID_ETH]); | ||
2858 | memcpy(eth_header->dst_mac, &be_mac, ETH_ALEN); | ||
2859 | memcpy(eth_header->dst_mac_msk, &mac_msk, ETH_ALEN); | ||
2860 | |||
2861 | return 0; | ||
2862 | |||
2863 | } | ||
2864 | |||
2779 | int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | 2865 | int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, |
2780 | struct mlx4_vhcr *vhcr, | 2866 | struct mlx4_vhcr *vhcr, |
2781 | struct mlx4_cmd_mailbox *inbox, | 2867 | struct mlx4_cmd_mailbox *inbox, |
2782 | struct mlx4_cmd_mailbox *outbox, | 2868 | struct mlx4_cmd_mailbox *outbox, |
2783 | struct mlx4_cmd_info *cmd) | 2869 | struct mlx4_cmd_info *cmd) |
2784 | { | 2870 | { |
2871 | |||
2872 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
2873 | struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; | ||
2874 | struct list_head *rlist = &tracker->slave_list[slave].res_list[RES_MAC]; | ||
2785 | int err; | 2875 | int err; |
2876 | struct mlx4_net_trans_rule_hw_ctrl *ctrl; | ||
2877 | struct _rule_hw *rule_header; | ||
2878 | int header_id; | ||
2786 | 2879 | ||
2787 | if (dev->caps.steering_mode != | 2880 | if (dev->caps.steering_mode != |
2788 | MLX4_STEERING_MODE_DEVICE_MANAGED) | 2881 | MLX4_STEERING_MODE_DEVICE_MANAGED) |
2789 | return -EOPNOTSUPP; | 2882 | return -EOPNOTSUPP; |
2790 | 2883 | ||
2884 | ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; | ||
2885 | rule_header = (struct _rule_hw *)(ctrl + 1); | ||
2886 | header_id = map_hw_to_sw_id(be16_to_cpu(rule_header->id)); | ||
2887 | |||
2888 | switch (header_id) { | ||
2889 | case MLX4_NET_TRANS_RULE_ID_ETH: | ||
2890 | if (validate_eth_header_mac(slave, rule_header, rlist)) | ||
2891 | return -EINVAL; | ||
2892 | break; | ||
2893 | case MLX4_NET_TRANS_RULE_ID_IPV4: | ||
2894 | case MLX4_NET_TRANS_RULE_ID_TCP: | ||
2895 | case MLX4_NET_TRANS_RULE_ID_UDP: | ||
2896 | pr_warn("Can't attach FS rule without L2 headers, adding L2 header.\n"); | ||
2897 | if (add_eth_header(dev, slave, inbox, rlist, header_id)) | ||
2898 | return -EINVAL; | ||
2899 | vhcr->in_modifier += | ||
2900 | sizeof(struct mlx4_net_trans_rule_hw_eth) >> 2; | ||
2901 | break; | ||
2902 | default: | ||
2903 | pr_err("Corrupted mailbox.\n"); | ||
2904 | return -EINVAL; | ||
2905 | } | ||
2906 | |||
2791 | err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, | 2907 | err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, |
2792 | vhcr->in_modifier, 0, | 2908 | vhcr->in_modifier, 0, |
2793 | MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, | 2909 | MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, |
diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c index bb8c8222122b..4d15bf413bdc 100644 --- a/drivers/net/ethernet/seeq/sgiseeq.c +++ b/drivers/net/ethernet/seeq/sgiseeq.c | |||
@@ -751,6 +751,7 @@ static int __devinit sgiseeq_probe(struct platform_device *pdev) | |||
751 | sp->srings = sr; | 751 | sp->srings = sr; |
752 | sp->rx_desc = sp->srings->rxvector; | 752 | sp->rx_desc = sp->srings->rxvector; |
753 | sp->tx_desc = sp->srings->txvector; | 753 | sp->tx_desc = sp->srings->txvector; |
754 | spin_lock_init(&sp->tx_lock); | ||
754 | 755 | ||
755 | /* A couple calculations now, saves many cycles later. */ | 756 | /* A couple calculations now, saves many cycles later. */ |
756 | setup_rx_ring(dev, sp->rx_desc, SEEQ_RX_BUFFERS); | 757 | setup_rx_ring(dev, sp->rx_desc, SEEQ_RX_BUFFERS); |
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 8cba2df82b18..5faedd855b77 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c | |||
@@ -863,8 +863,8 @@ static int efx_ethtool_get_class_rule(struct efx_nic *efx, | |||
863 | &ip_entry->ip4dst, &ip_entry->pdst); | 863 | &ip_entry->ip4dst, &ip_entry->pdst); |
864 | if (rc != 0) { | 864 | if (rc != 0) { |
865 | rc = efx_filter_get_ipv4_full( | 865 | rc = efx_filter_get_ipv4_full( |
866 | &spec, &proto, &ip_entry->ip4src, &ip_entry->psrc, | 866 | &spec, &proto, &ip_entry->ip4dst, &ip_entry->pdst, |
867 | &ip_entry->ip4dst, &ip_entry->pdst); | 867 | &ip_entry->ip4src, &ip_entry->psrc); |
868 | EFX_WARN_ON_PARANOID(rc); | 868 | EFX_WARN_ON_PARANOID(rc); |
869 | ip_mask->ip4src = ~0; | 869 | ip_mask->ip4src = ~0; |
870 | ip_mask->psrc = ~0; | 870 | ip_mask->psrc = ~0; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index e2d083228f3a..719be3912aa9 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h | |||
@@ -22,6 +22,9 @@ | |||
22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
23 | *******************************************************************************/ | 23 | *******************************************************************************/ |
24 | 24 | ||
25 | #ifndef __COMMON_H__ | ||
26 | #define __COMMON_H__ | ||
27 | |||
25 | #include <linux/etherdevice.h> | 28 | #include <linux/etherdevice.h> |
26 | #include <linux/netdevice.h> | 29 | #include <linux/netdevice.h> |
27 | #include <linux/phy.h> | 30 | #include <linux/phy.h> |
@@ -366,3 +369,5 @@ extern void stmmac_set_mac(void __iomem *ioaddr, bool enable); | |||
366 | 369 | ||
367 | extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); | 370 | extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); |
368 | extern const struct stmmac_ring_mode_ops ring_mode_ops; | 371 | extern const struct stmmac_ring_mode_ops ring_mode_ops; |
372 | |||
373 | #endif /* __COMMON_H__ */ | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/descs.h b/drivers/net/ethernet/stmicro/stmmac/descs.h index 9820ec842cc0..223adf95fd03 100644 --- a/drivers/net/ethernet/stmicro/stmmac/descs.h +++ b/drivers/net/ethernet/stmicro/stmmac/descs.h | |||
@@ -20,6 +20,10 @@ | |||
20 | 20 | ||
21 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 21 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
22 | *******************************************************************************/ | 22 | *******************************************************************************/ |
23 | |||
24 | #ifndef __DESCS_H__ | ||
25 | #define __DESCS_H__ | ||
26 | |||
23 | struct dma_desc { | 27 | struct dma_desc { |
24 | /* Receive descriptor */ | 28 | /* Receive descriptor */ |
25 | union { | 29 | union { |
@@ -166,3 +170,5 @@ enum tdes_csum_insertion { | |||
166 | * is not calculated */ | 170 | * is not calculated */ |
167 | cic_full = 3, /* IP header and pseudoheader */ | 171 | cic_full = 3, /* IP header and pseudoheader */ |
168 | }; | 172 | }; |
173 | |||
174 | #endif /* __DESCS_H__ */ | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/descs_com.h b/drivers/net/ethernet/stmicro/stmmac/descs_com.h index dd8d6e19dff6..7ee9499a6e38 100644 --- a/drivers/net/ethernet/stmicro/stmmac/descs_com.h +++ b/drivers/net/ethernet/stmicro/stmmac/descs_com.h | |||
@@ -27,6 +27,9 @@ | |||
27 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 27 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
28 | *******************************************************************************/ | 28 | *******************************************************************************/ |
29 | 29 | ||
30 | #ifndef __DESC_COM_H__ | ||
31 | #define __DESC_COM_H__ | ||
32 | |||
30 | #if defined(CONFIG_STMMAC_RING) | 33 | #if defined(CONFIG_STMMAC_RING) |
31 | static inline void ehn_desc_rx_set_on_ring_chain(struct dma_desc *p, int end) | 34 | static inline void ehn_desc_rx_set_on_ring_chain(struct dma_desc *p, int end) |
32 | { | 35 | { |
@@ -124,3 +127,5 @@ static inline void norm_set_tx_desc_len(struct dma_desc *p, int len) | |||
124 | p->des01.tx.buffer1_size = len; | 127 | p->des01.tx.buffer1_size = len; |
125 | } | 128 | } |
126 | #endif | 129 | #endif |
130 | |||
131 | #endif /* __DESC_COM_H__ */ | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100.h b/drivers/net/ethernet/stmicro/stmmac/dwmac100.h index 7c6d857a9cc7..2ec6aeae349e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100.h | |||
@@ -22,6 +22,9 @@ | |||
22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
23 | *******************************************************************************/ | 23 | *******************************************************************************/ |
24 | 24 | ||
25 | #ifndef __DWMAC100_H__ | ||
26 | #define __DWMAC100_H__ | ||
27 | |||
25 | #include <linux/phy.h> | 28 | #include <linux/phy.h> |
26 | #include "common.h" | 29 | #include "common.h" |
27 | 30 | ||
@@ -119,3 +122,5 @@ enum ttc_control { | |||
119 | #define DMA_MISSED_FRAME_M_CNTR 0x0000ffff /* Missed Frame Couinter */ | 122 | #define DMA_MISSED_FRAME_M_CNTR 0x0000ffff /* Missed Frame Couinter */ |
120 | 123 | ||
121 | extern const struct stmmac_dma_ops dwmac100_dma_ops; | 124 | extern const struct stmmac_dma_ops dwmac100_dma_ops; |
125 | |||
126 | #endif /* __DWMAC100_H__ */ | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index f90fcb5f9573..0e4cacedc1f0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | |||
@@ -19,6 +19,8 @@ | |||
19 | 19 | ||
20 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 20 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
21 | *******************************************************************************/ | 21 | *******************************************************************************/ |
22 | #ifndef __DWMAC1000_H__ | ||
23 | #define __DWMAC1000_H__ | ||
22 | 24 | ||
23 | #include <linux/phy.h> | 25 | #include <linux/phy.h> |
24 | #include "common.h" | 26 | #include "common.h" |
@@ -229,6 +231,7 @@ enum rtc_control { | |||
229 | #define GMAC_MMC_RX_CSUM_OFFLOAD 0x208 | 231 | #define GMAC_MMC_RX_CSUM_OFFLOAD 0x208 |
230 | 232 | ||
231 | /* Synopsys Core versions */ | 233 | /* Synopsys Core versions */ |
232 | #define DWMAC_CORE_3_40 34 | 234 | #define DWMAC_CORE_3_40 0x34 |
233 | 235 | ||
234 | extern const struct stmmac_dma_ops dwmac1000_dma_ops; | 236 | extern const struct stmmac_dma_ops dwmac1000_dma_ops; |
237 | #endif /* __DWMAC1000_H__ */ | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h index e678ce39d014..e49c9a0fd6ff 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h | |||
@@ -22,6 +22,9 @@ | |||
22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
23 | *******************************************************************************/ | 23 | *******************************************************************************/ |
24 | 24 | ||
25 | #ifndef __DWMAC_DMA_H__ | ||
26 | #define __DWMAC_DMA_H__ | ||
27 | |||
25 | /* DMA CRS Control and Status Register Mapping */ | 28 | /* DMA CRS Control and Status Register Mapping */ |
26 | #define DMA_BUS_MODE 0x00001000 /* Bus Mode */ | 29 | #define DMA_BUS_MODE 0x00001000 /* Bus Mode */ |
27 | #define DMA_XMT_POLL_DEMAND 0x00001004 /* Transmit Poll Demand */ | 30 | #define DMA_XMT_POLL_DEMAND 0x00001004 /* Transmit Poll Demand */ |
@@ -109,3 +112,5 @@ extern void dwmac_dma_start_rx(void __iomem *ioaddr); | |||
109 | extern void dwmac_dma_stop_rx(void __iomem *ioaddr); | 112 | extern void dwmac_dma_stop_rx(void __iomem *ioaddr); |
110 | extern int dwmac_dma_interrupt(void __iomem *ioaddr, | 113 | extern int dwmac_dma_interrupt(void __iomem *ioaddr, |
111 | struct stmmac_extra_stats *x); | 114 | struct stmmac_extra_stats *x); |
115 | |||
116 | #endif /* __DWMAC_DMA_H__ */ | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc.h b/drivers/net/ethernet/stmicro/stmmac/mmc.h index a38352024cb8..67995ef25251 100644 --- a/drivers/net/ethernet/stmicro/stmmac/mmc.h +++ b/drivers/net/ethernet/stmicro/stmmac/mmc.h | |||
@@ -22,6 +22,9 @@ | |||
22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
23 | *******************************************************************************/ | 23 | *******************************************************************************/ |
24 | 24 | ||
25 | #ifndef __MMC_H__ | ||
26 | #define __MMC_H__ | ||
27 | |||
25 | /* MMC control register */ | 28 | /* MMC control register */ |
26 | /* When set, all counter are reset */ | 29 | /* When set, all counter are reset */ |
27 | #define MMC_CNTRL_COUNTER_RESET 0x1 | 30 | #define MMC_CNTRL_COUNTER_RESET 0x1 |
@@ -129,3 +132,5 @@ struct stmmac_counters { | |||
129 | extern void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode); | 132 | extern void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode); |
130 | extern void dwmac_mmc_intr_all_mask(void __iomem *ioaddr); | 133 | extern void dwmac_mmc_intr_all_mask(void __iomem *ioaddr); |
131 | extern void dwmac_mmc_read(void __iomem *ioaddr, struct stmmac_counters *mmc); | 134 | extern void dwmac_mmc_read(void __iomem *ioaddr, struct stmmac_counters *mmc); |
135 | |||
136 | #endif /* __MMC_H__ */ | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c index c07cfe989f6e..0c74a702d461 100644 --- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #define MMC_TX_INTR 0x00000108 /* MMC TX Interrupt */ | 33 | #define MMC_TX_INTR 0x00000108 /* MMC TX Interrupt */ |
34 | #define MMC_RX_INTR_MASK 0x0000010c /* MMC Interrupt Mask */ | 34 | #define MMC_RX_INTR_MASK 0x0000010c /* MMC Interrupt Mask */ |
35 | #define MMC_TX_INTR_MASK 0x00000110 /* MMC Interrupt Mask */ | 35 | #define MMC_TX_INTR_MASK 0x00000110 /* MMC Interrupt Mask */ |
36 | #define MMC_DEFAUL_MASK 0xffffffff | 36 | #define MMC_DEFAULT_MASK 0xffffffff |
37 | 37 | ||
38 | /* MMC TX counter registers */ | 38 | /* MMC TX counter registers */ |
39 | 39 | ||
@@ -147,8 +147,8 @@ void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode) | |||
147 | /* To mask all all interrupts.*/ | 147 | /* To mask all all interrupts.*/ |
148 | void dwmac_mmc_intr_all_mask(void __iomem *ioaddr) | 148 | void dwmac_mmc_intr_all_mask(void __iomem *ioaddr) |
149 | { | 149 | { |
150 | writel(MMC_DEFAUL_MASK, ioaddr + MMC_RX_INTR_MASK); | 150 | writel(MMC_DEFAULT_MASK, ioaddr + MMC_RX_INTR_MASK); |
151 | writel(MMC_DEFAUL_MASK, ioaddr + MMC_TX_INTR_MASK); | 151 | writel(MMC_DEFAULT_MASK, ioaddr + MMC_TX_INTR_MASK); |
152 | } | 152 | } |
153 | 153 | ||
154 | /* This reads the MAC core counters (if actaully supported). | 154 | /* This reads the MAC core counters (if actaully supported). |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index f2d3665430ad..e872e1da3137 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h | |||
@@ -20,6 +20,9 @@ | |||
20 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 20 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
21 | *******************************************************************************/ | 21 | *******************************************************************************/ |
22 | 22 | ||
23 | #ifndef __STMMAC_H__ | ||
24 | #define __STMMAC_H__ | ||
25 | |||
23 | #define STMMAC_RESOURCE_NAME "stmmaceth" | 26 | #define STMMAC_RESOURCE_NAME "stmmaceth" |
24 | #define DRV_MODULE_VERSION "March_2012" | 27 | #define DRV_MODULE_VERSION "March_2012" |
25 | 28 | ||
@@ -166,3 +169,5 @@ static inline void stmmac_unregister_pci(void) | |||
166 | { | 169 | { |
167 | } | 170 | } |
168 | #endif /* CONFIG_STMMAC_PCI */ | 171 | #endif /* CONFIG_STMMAC_PCI */ |
172 | |||
173 | #endif /* __STMMAC_H__ */ | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h index 6863590d184b..aea9b14cdfbe 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h | |||
@@ -21,6 +21,8 @@ | |||
21 | 21 | ||
22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
23 | *******************************************************************************/ | 23 | *******************************************************************************/ |
24 | #ifndef __STMMAC_TIMER_H__ | ||
25 | #define __STMMAC_TIMER_H__ | ||
24 | 26 | ||
25 | struct stmmac_timer { | 27 | struct stmmac_timer { |
26 | void (*timer_start) (unsigned int new_freq); | 28 | void (*timer_start) (unsigned int new_freq); |
@@ -40,3 +42,5 @@ void stmmac_schedule(struct net_device *dev); | |||
40 | extern int tmu2_register_user(void *fnt, void *data); | 42 | extern int tmu2_register_user(void *fnt, void *data); |
41 | extern void tmu2_unregister_user(void); | 43 | extern void tmu2_unregister_user(void); |
42 | #endif | 44 | #endif |
45 | |||
46 | #endif /* __STMMAC_TIMER_H__ */ | ||
diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c index cd7ee204e94a..a9ca4a03d31b 100644 --- a/drivers/net/ethernet/ti/davinci_mdio.c +++ b/drivers/net/ethernet/ti/davinci_mdio.c | |||
@@ -394,8 +394,10 @@ static int __devexit davinci_mdio_remove(struct platform_device *pdev) | |||
394 | struct device *dev = &pdev->dev; | 394 | struct device *dev = &pdev->dev; |
395 | struct davinci_mdio_data *data = dev_get_drvdata(dev); | 395 | struct davinci_mdio_data *data = dev_get_drvdata(dev); |
396 | 396 | ||
397 | if (data->bus) | 397 | if (data->bus) { |
398 | mdiobus_unregister(data->bus); | ||
398 | mdiobus_free(data->bus); | 399 | mdiobus_free(data->bus); |
400 | } | ||
399 | 401 | ||
400 | if (data->clk) | 402 | if (data->clk) |
401 | clk_put(data->clk); | 403 | clk_put(data->clk); |
diff --git a/drivers/net/fddi/skfp/pmf.c b/drivers/net/fddi/skfp/pmf.c index 24d8566cfd8b..441b4dc79450 100644 --- a/drivers/net/fddi/skfp/pmf.c +++ b/drivers/net/fddi/skfp/pmf.c | |||
@@ -673,7 +673,7 @@ void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para, | |||
673 | sm_pm_get_ls(smc,port_to_mib(smc,port))) ; | 673 | sm_pm_get_ls(smc,port_to_mib(smc,port))) ; |
674 | break ; | 674 | break ; |
675 | case SMT_P_REASON : | 675 | case SMT_P_REASON : |
676 | * (u_long *) to = 0 ; | 676 | *(u32 *)to = 0 ; |
677 | sp_len = 4 ; | 677 | sp_len = 4 ; |
678 | goto sp_done ; | 678 | goto sp_done ; |
679 | case SMT_P1033 : /* time stamp */ | 679 | case SMT_P1033 : /* time stamp */ |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 328397c66730..b1ba68f1a049 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -297,7 +297,7 @@ static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message) | |||
297 | if (ret < 0) | 297 | if (ret < 0) |
298 | goto err; | 298 | goto err; |
299 | 299 | ||
300 | if (info->subdriver && info->subdriver->suspend) | 300 | if (intf == info->control && info->subdriver && info->subdriver->suspend) |
301 | ret = info->subdriver->suspend(intf, message); | 301 | ret = info->subdriver->suspend(intf, message); |
302 | if (ret < 0) | 302 | if (ret < 0) |
303 | usbnet_resume(intf); | 303 | usbnet_resume(intf); |
@@ -310,13 +310,14 @@ static int qmi_wwan_resume(struct usb_interface *intf) | |||
310 | struct usbnet *dev = usb_get_intfdata(intf); | 310 | struct usbnet *dev = usb_get_intfdata(intf); |
311 | struct qmi_wwan_state *info = (void *)&dev->data; | 311 | struct qmi_wwan_state *info = (void *)&dev->data; |
312 | int ret = 0; | 312 | int ret = 0; |
313 | bool callsub = (intf == info->control && info->subdriver && info->subdriver->resume); | ||
313 | 314 | ||
314 | if (info->subdriver && info->subdriver->resume) | 315 | if (callsub) |
315 | ret = info->subdriver->resume(intf); | 316 | ret = info->subdriver->resume(intf); |
316 | if (ret < 0) | 317 | if (ret < 0) |
317 | goto err; | 318 | goto err; |
318 | ret = usbnet_resume(intf); | 319 | ret = usbnet_resume(intf); |
319 | if (ret < 0 && info->subdriver && info->subdriver->resume && info->subdriver->suspend) | 320 | if (ret < 0 && callsub && info->subdriver->suspend) |
320 | info->subdriver->suspend(intf, PMSG_SUSPEND); | 321 | info->subdriver->suspend(intf, PMSG_SUSPEND); |
321 | err: | 322 | err: |
322 | return ret; | 323 | return ret; |
@@ -398,7 +399,6 @@ static const struct usb_device_id products[] = { | |||
398 | /* 4. Gobi 1000 devices */ | 399 | /* 4. Gobi 1000 devices */ |
399 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 400 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
400 | {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ | 401 | {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ |
401 | {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ | ||
402 | {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ | 402 | {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ |
403 | {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ | 403 | {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ |
404 | {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ | 404 | {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ |
@@ -413,7 +413,9 @@ static const struct usb_device_id products[] = { | |||
413 | 413 | ||
414 | /* 5. Gobi 2000 and 3000 devices */ | 414 | /* 5. Gobi 2000 and 3000 devices */ |
415 | {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ | 415 | {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ |
416 | {QMI_GOBI_DEVICE(0x413c, 0x8194)}, /* Dell Gobi 3000 Composite */ | ||
416 | {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */ | 417 | {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */ |
418 | {QMI_GOBI_DEVICE(0x05c6, 0x920d)}, /* Gobi 3000 Composite */ | ||
417 | {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ | 419 | {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ |
418 | {QMI_GOBI_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ | 420 | {QMI_GOBI_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ |
419 | {QMI_GOBI_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ | 421 | {QMI_GOBI_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ |
@@ -438,9 +440,12 @@ static const struct usb_device_id products[] = { | |||
438 | {QMI_GOBI_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ | 440 | {QMI_GOBI_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ |
439 | {QMI_GOBI_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ | 441 | {QMI_GOBI_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ |
440 | {QMI_GOBI_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ | 442 | {QMI_GOBI_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ |
443 | {QMI_GOBI_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ | ||
441 | {QMI_GOBI_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ | 444 | {QMI_GOBI_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ |
442 | {QMI_GOBI_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ | 445 | {QMI_GOBI_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ |
443 | {QMI_GOBI_DEVICE(0x1199, 0x901b)}, /* Sierra Wireless MC7770 */ | 446 | {QMI_GOBI_DEVICE(0x1199, 0x901b)}, /* Sierra Wireless MC7770 */ |
447 | {QMI_GOBI_DEVICE(0x12d1, 0x14f1)}, /* Sony Gobi 3000 Composite */ | ||
448 | {QMI_GOBI_DEVICE(0x1410, 0xa021)}, /* Foxconn Gobi 3000 Modem device (Novatel E396) */ | ||
444 | 449 | ||
445 | { } /* END */ | 450 | { } /* END */ |
446 | }; | 451 | }; |
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index 7be49ea60b6d..8e22417fa6c1 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c | |||
@@ -656,7 +656,7 @@ static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap) | |||
656 | return -EIO; | 656 | return -EIO; |
657 | } | 657 | } |
658 | 658 | ||
659 | *datap = *attrdata; | 659 | *datap = le16_to_cpu(*attrdata); |
660 | 660 | ||
661 | kfree(attrdata); | 661 | kfree(attrdata); |
662 | return result; | 662 | return result; |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 8531c1caac28..fc9f578a1e25 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -1201,19 +1201,26 @@ deferred: | |||
1201 | } | 1201 | } |
1202 | EXPORT_SYMBOL_GPL(usbnet_start_xmit); | 1202 | EXPORT_SYMBOL_GPL(usbnet_start_xmit); |
1203 | 1203 | ||
1204 | static void rx_alloc_submit(struct usbnet *dev, gfp_t flags) | 1204 | static int rx_alloc_submit(struct usbnet *dev, gfp_t flags) |
1205 | { | 1205 | { |
1206 | struct urb *urb; | 1206 | struct urb *urb; |
1207 | int i; | 1207 | int i; |
1208 | int ret = 0; | ||
1208 | 1209 | ||
1209 | /* don't refill the queue all at once */ | 1210 | /* don't refill the queue all at once */ |
1210 | for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) { | 1211 | for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) { |
1211 | urb = usb_alloc_urb(0, flags); | 1212 | urb = usb_alloc_urb(0, flags); |
1212 | if (urb != NULL) { | 1213 | if (urb != NULL) { |
1213 | if (rx_submit(dev, urb, flags) == -ENOLINK) | 1214 | ret = rx_submit(dev, urb, flags); |
1214 | return; | 1215 | if (ret) |
1216 | goto err; | ||
1217 | } else { | ||
1218 | ret = -ENOMEM; | ||
1219 | goto err; | ||
1215 | } | 1220 | } |
1216 | } | 1221 | } |
1222 | err: | ||
1223 | return ret; | ||
1217 | } | 1224 | } |
1218 | 1225 | ||
1219 | /*-------------------------------------------------------------------------*/ | 1226 | /*-------------------------------------------------------------------------*/ |
@@ -1257,7 +1264,8 @@ static void usbnet_bh (unsigned long param) | |||
1257 | int temp = dev->rxq.qlen; | 1264 | int temp = dev->rxq.qlen; |
1258 | 1265 | ||
1259 | if (temp < RX_QLEN(dev)) { | 1266 | if (temp < RX_QLEN(dev)) { |
1260 | rx_alloc_submit(dev, GFP_ATOMIC); | 1267 | if (rx_alloc_submit(dev, GFP_ATOMIC) == -ENOLINK) |
1268 | return; | ||
1261 | if (temp != dev->rxq.qlen) | 1269 | if (temp != dev->rxq.qlen) |
1262 | netif_dbg(dev, link, dev->net, | 1270 | netif_dbg(dev, link, dev->net, |
1263 | "rxqlen %d --> %d\n", | 1271 | "rxqlen %d --> %d\n", |
@@ -1573,7 +1581,7 @@ int usbnet_resume (struct usb_interface *intf) | |||
1573 | netif_device_present(dev->net) && | 1581 | netif_device_present(dev->net) && |
1574 | !timer_pending(&dev->delay) && | 1582 | !timer_pending(&dev->delay) && |
1575 | !test_bit(EVENT_RX_HALT, &dev->flags)) | 1583 | !test_bit(EVENT_RX_HALT, &dev->flags)) |
1576 | rx_alloc_submit(dev, GFP_KERNEL); | 1584 | rx_alloc_submit(dev, GFP_NOIO); |
1577 | 1585 | ||
1578 | if (!(dev->txq.qlen >= TX_QLEN(dev))) | 1586 | if (!(dev->txq.qlen >= TX_QLEN(dev))) |
1579 | netif_tx_wake_all_queues(dev->net); | 1587 | netif_tx_wake_all_queues(dev->net); |
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index aaaca9aa2293..3f575afd8cfc 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
12 | 12 | ||
13 | #include <linux/module.h> | ||
13 | #include <linux/bitops.h> | 14 | #include <linux/bitops.h> |
14 | #include <linux/cdev.h> | 15 | #include <linux/cdev.h> |
15 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 4026c906cc7b..b7e0258887e7 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c | |||
@@ -1482,7 +1482,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode) | |||
1482 | case AR5K_EEPROM_MODE_11A: | 1482 | case AR5K_EEPROM_MODE_11A: |
1483 | offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version); | 1483 | offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version); |
1484 | rate_pcal_info = ee->ee_rate_tpwr_a; | 1484 | rate_pcal_info = ee->ee_rate_tpwr_a; |
1485 | ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_CHAN; | 1485 | ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_RATE_CHAN; |
1486 | break; | 1486 | break; |
1487 | case AR5K_EEPROM_MODE_11B: | 1487 | case AR5K_EEPROM_MODE_11B: |
1488 | offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version); | 1488 | offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version); |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h index dc2bcfeadeb4..94a9bbea6874 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/drivers/net/wireless/ath/ath5k/eeprom.h | |||
@@ -182,6 +182,7 @@ | |||
182 | #define AR5K_EEPROM_EEP_DELTA 10 | 182 | #define AR5K_EEPROM_EEP_DELTA 10 |
183 | #define AR5K_EEPROM_N_MODES 3 | 183 | #define AR5K_EEPROM_N_MODES 3 |
184 | #define AR5K_EEPROM_N_5GHZ_CHAN 10 | 184 | #define AR5K_EEPROM_N_5GHZ_CHAN 10 |
185 | #define AR5K_EEPROM_N_5GHZ_RATE_CHAN 8 | ||
185 | #define AR5K_EEPROM_N_2GHZ_CHAN 3 | 186 | #define AR5K_EEPROM_N_2GHZ_CHAN 3 |
186 | #define AR5K_EEPROM_N_2GHZ_CHAN_2413 4 | 187 | #define AR5K_EEPROM_N_2GHZ_CHAN_2413 4 |
187 | #define AR5K_EEPROM_N_2GHZ_CHAN_MAX 4 | 188 | #define AR5K_EEPROM_N_2GHZ_CHAN_MAX 4 |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 2c9f7d7ed4cc..0ed3846f9cbb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c | |||
@@ -142,6 +142,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) | |||
142 | }; | 142 | }; |
143 | int training_power; | 143 | int training_power; |
144 | int i, val; | 144 | int i, val; |
145 | u32 am2pm_mask = ah->paprd_ratemask; | ||
145 | 146 | ||
146 | if (IS_CHAN_2GHZ(ah->curchan)) | 147 | if (IS_CHAN_2GHZ(ah->curchan)) |
147 | training_power = ar9003_get_training_power_2g(ah); | 148 | training_power = ar9003_get_training_power_2g(ah); |
@@ -158,10 +159,13 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) | |||
158 | } | 159 | } |
159 | ah->paprd_training_power = training_power; | 160 | ah->paprd_training_power = training_power; |
160 | 161 | ||
162 | if (AR_SREV_9330(ah)) | ||
163 | am2pm_mask = 0; | ||
164 | |||
161 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, | 165 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, |
162 | ah->paprd_ratemask); | 166 | ah->paprd_ratemask); |
163 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, | 167 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, |
164 | ah->paprd_ratemask); | 168 | am2pm_mask); |
165 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, | 169 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, |
166 | ah->paprd_ratemask_ht40); | 170 | ah->paprd_ratemask_ht40); |
167 | 171 | ||
@@ -782,6 +786,102 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) | |||
782 | } | 786 | } |
783 | EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); | 787 | EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); |
784 | 788 | ||
789 | static bool ar9003_paprd_retrain_pa_in(struct ath_hw *ah, | ||
790 | struct ath9k_hw_cal_data *caldata, | ||
791 | int chain) | ||
792 | { | ||
793 | u32 *pa_in = caldata->pa_table[chain]; | ||
794 | int capdiv_offset, quick_drop_offset; | ||
795 | int capdiv2g, quick_drop; | ||
796 | int count = 0; | ||
797 | int i; | ||
798 | |||
799 | if (!AR_SREV_9485(ah) && !AR_SREV_9330(ah)) | ||
800 | return false; | ||
801 | |||
802 | capdiv2g = REG_READ_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, | ||
803 | AR_PHY_65NM_CH0_TXRF3_CAPDIV2G); | ||
804 | |||
805 | quick_drop = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, | ||
806 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP); | ||
807 | |||
808 | if (quick_drop) | ||
809 | quick_drop -= 0x40; | ||
810 | |||
811 | for (i = 0; i < NUM_BIN + 1; i++) { | ||
812 | if (pa_in[i] == 1400) | ||
813 | count++; | ||
814 | } | ||
815 | |||
816 | if (AR_SREV_9485(ah)) { | ||
817 | if (pa_in[23] < 800) { | ||
818 | capdiv_offset = (int)((1000 - pa_in[23] + 75) / 150); | ||
819 | capdiv2g += capdiv_offset; | ||
820 | if (capdiv2g > 7) { | ||
821 | capdiv2g = 7; | ||
822 | if (pa_in[23] < 600) { | ||
823 | quick_drop++; | ||
824 | if (quick_drop > 0) | ||
825 | quick_drop = 0; | ||
826 | } | ||
827 | } | ||
828 | } else if (pa_in[23] == 1400) { | ||
829 | quick_drop_offset = min_t(int, count / 3, 2); | ||
830 | quick_drop += quick_drop_offset; | ||
831 | capdiv2g += quick_drop_offset / 2; | ||
832 | |||
833 | if (capdiv2g > 7) | ||
834 | capdiv2g = 7; | ||
835 | |||
836 | if (quick_drop > 0) { | ||
837 | quick_drop = 0; | ||
838 | capdiv2g -= quick_drop_offset; | ||
839 | if (capdiv2g < 0) | ||
840 | capdiv2g = 0; | ||
841 | } | ||
842 | } else { | ||
843 | return false; | ||
844 | } | ||
845 | } else if (AR_SREV_9330(ah)) { | ||
846 | if (pa_in[23] < 1000) { | ||
847 | capdiv_offset = (1000 - pa_in[23]) / 100; | ||
848 | capdiv2g += capdiv_offset; | ||
849 | if (capdiv_offset > 3) { | ||
850 | capdiv_offset = 1; | ||
851 | quick_drop--; | ||
852 | } | ||
853 | |||
854 | capdiv2g += capdiv_offset; | ||
855 | if (capdiv2g > 6) | ||
856 | capdiv2g = 6; | ||
857 | if (quick_drop < -4) | ||
858 | quick_drop = -4; | ||
859 | } else if (pa_in[23] == 1400) { | ||
860 | if (count > 3) { | ||
861 | quick_drop++; | ||
862 | capdiv2g -= count / 4; | ||
863 | if (quick_drop > -2) | ||
864 | quick_drop = -2; | ||
865 | } else { | ||
866 | capdiv2g--; | ||
867 | } | ||
868 | |||
869 | if (capdiv2g < 0) | ||
870 | capdiv2g = 0; | ||
871 | } else { | ||
872 | return false; | ||
873 | } | ||
874 | } | ||
875 | |||
876 | REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, | ||
877 | AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, capdiv2g); | ||
878 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, | ||
879 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, | ||
880 | quick_drop); | ||
881 | |||
882 | return true; | ||
883 | } | ||
884 | |||
785 | int ar9003_paprd_create_curve(struct ath_hw *ah, | 885 | int ar9003_paprd_create_curve(struct ath_hw *ah, |
786 | struct ath9k_hw_cal_data *caldata, int chain) | 886 | struct ath9k_hw_cal_data *caldata, int chain) |
787 | { | 887 | { |
@@ -817,6 +917,9 @@ int ar9003_paprd_create_curve(struct ath_hw *ah, | |||
817 | if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain)) | 917 | if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain)) |
818 | status = -2; | 918 | status = -2; |
819 | 919 | ||
920 | if (ar9003_paprd_retrain_pa_in(ah, caldata, chain)) | ||
921 | status = -EINPROGRESS; | ||
922 | |||
820 | REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, | 923 | REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, |
821 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); | 924 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); |
822 | 925 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 7bfbaf065a43..84d3d4956861 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -625,6 +625,10 @@ | |||
625 | #define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0) | 625 | #define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0) |
626 | #define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc) | 626 | #define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc) |
627 | 627 | ||
628 | #define AR_PHY_65NM_CH0_TXRF3 0x16048 | ||
629 | #define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G 0x0000001e | ||
630 | #define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G_S 1 | ||
631 | |||
628 | #define AR_PHY_65NM_CH0_SYNTH4 0x1608c | 632 | #define AR_PHY_65NM_CH0_SYNTH4 0x1608c |
629 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002) | 633 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002) |
630 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1) | 634 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1) |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index bacdb8fb4ef4..9f83f71742a5 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -341,7 +341,8 @@ void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) | |||
341 | { | 341 | { |
342 | struct ath_btcoex *btcoex = &sc->btcoex; | 342 | struct ath_btcoex *btcoex = &sc->btcoex; |
343 | 343 | ||
344 | ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); | 344 | if (btcoex->hw_timer_enabled) |
345 | ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); | ||
345 | } | 346 | } |
346 | 347 | ||
347 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) | 348 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 60b6a9daff7e..48af40151d23 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -463,9 +463,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
463 | ah->config.spurchans[i][1] = AR_NO_SPUR; | 463 | ah->config.spurchans[i][1] = AR_NO_SPUR; |
464 | } | 464 | } |
465 | 465 | ||
466 | /* PAPRD needs some more work to be enabled */ | ||
467 | ah->config.paprd_disable = 1; | ||
468 | |||
469 | ah->config.rx_intr_mitigation = true; | 466 | ah->config.rx_intr_mitigation = true; |
470 | ah->config.pcieSerDesWrite = true; | 467 | ah->config.pcieSerDesWrite = true; |
471 | 468 | ||
@@ -978,9 +975,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | |||
978 | else | 975 | else |
979 | imr_reg |= AR_IMR_TXOK; | 976 | imr_reg |= AR_IMR_TXOK; |
980 | 977 | ||
981 | if (opmode == NL80211_IFTYPE_AP) | ||
982 | imr_reg |= AR_IMR_MIB; | ||
983 | |||
984 | ENABLE_REGWRITE_BUFFER(ah); | 978 | ENABLE_REGWRITE_BUFFER(ah); |
985 | 979 | ||
986 | REG_WRITE(ah, AR_IMR, imr_reg); | 980 | REG_WRITE(ah, AR_IMR, imr_reg); |
@@ -1778,6 +1772,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1778 | /* Operating channel changed, reset channel calibration data */ | 1772 | /* Operating channel changed, reset channel calibration data */ |
1779 | memset(caldata, 0, sizeof(*caldata)); | 1773 | memset(caldata, 0, sizeof(*caldata)); |
1780 | ath9k_init_nfcal_hist_buffer(ah, chan); | 1774 | ath9k_init_nfcal_hist_buffer(ah, chan); |
1775 | } else if (caldata) { | ||
1776 | caldata->paprd_packet_sent = false; | ||
1781 | } | 1777 | } |
1782 | ah->noise = ath9k_hw_getchan_noise(ah, chan); | 1778 | ah->noise = ath9k_hw_getchan_noise(ah, chan); |
1783 | 1779 | ||
@@ -2502,7 +2498,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2502 | pCap->tx_desc_len = sizeof(struct ar9003_txc); | 2498 | pCap->tx_desc_len = sizeof(struct ar9003_txc); |
2503 | pCap->txs_len = sizeof(struct ar9003_txs); | 2499 | pCap->txs_len = sizeof(struct ar9003_txs); |
2504 | if (!ah->config.paprd_disable && | 2500 | if (!ah->config.paprd_disable && |
2505 | ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) | 2501 | ah->eep_ops->get_eeprom(ah, EEP_PAPRD) && |
2502 | !AR_SREV_9462(ah)) | ||
2506 | pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; | 2503 | pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; |
2507 | } else { | 2504 | } else { |
2508 | pCap->tx_desc_len = sizeof(struct ath_desc); | 2505 | pCap->tx_desc_len = sizeof(struct ath_desc); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index ce7332c64efb..6599a75f01fe 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -405,6 +405,7 @@ struct ath9k_hw_cal_data { | |||
405 | int8_t iCoff; | 405 | int8_t iCoff; |
406 | int8_t qCoff; | 406 | int8_t qCoff; |
407 | bool rtt_done; | 407 | bool rtt_done; |
408 | bool paprd_packet_sent; | ||
408 | bool paprd_done; | 409 | bool paprd_done; |
409 | bool nfcal_pending; | 410 | bool nfcal_pending; |
410 | bool nfcal_interference; | 411 | bool nfcal_interference; |
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index d4549e9aac5c..825a29cc9313 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c | |||
@@ -254,8 +254,9 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
254 | int chain_ok = 0; | 254 | int chain_ok = 0; |
255 | int chain; | 255 | int chain; |
256 | int len = 1800; | 256 | int len = 1800; |
257 | int ret; | ||
257 | 258 | ||
258 | if (!caldata) | 259 | if (!caldata || !caldata->paprd_packet_sent || caldata->paprd_done) |
259 | return; | 260 | return; |
260 | 261 | ||
261 | ath9k_ps_wakeup(sc); | 262 | ath9k_ps_wakeup(sc); |
@@ -282,13 +283,6 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
282 | continue; | 283 | continue; |
283 | 284 | ||
284 | chain_ok = 0; | 285 | chain_ok = 0; |
285 | |||
286 | ath_dbg(common, CALIBRATE, | ||
287 | "Sending PAPRD frame for thermal measurement on chain %d\n", | ||
288 | chain); | ||
289 | if (!ath_paprd_send_frame(sc, skb, chain)) | ||
290 | goto fail_paprd; | ||
291 | |||
292 | ar9003_paprd_setup_gain_table(ah, chain); | 286 | ar9003_paprd_setup_gain_table(ah, chain); |
293 | 287 | ||
294 | ath_dbg(common, CALIBRATE, | 288 | ath_dbg(common, CALIBRATE, |
@@ -302,7 +296,13 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
302 | break; | 296 | break; |
303 | } | 297 | } |
304 | 298 | ||
305 | if (ar9003_paprd_create_curve(ah, caldata, chain)) { | 299 | ret = ar9003_paprd_create_curve(ah, caldata, chain); |
300 | if (ret == -EINPROGRESS) { | ||
301 | ath_dbg(common, CALIBRATE, | ||
302 | "PAPRD curve on chain %d needs to be re-trained\n", | ||
303 | chain); | ||
304 | break; | ||
305 | } else if (ret) { | ||
306 | ath_dbg(common, CALIBRATE, | 306 | ath_dbg(common, CALIBRATE, |
307 | "PAPRD create curve failed on chain %d\n", | 307 | "PAPRD create curve failed on chain %d\n", |
308 | chain); | 308 | chain); |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 2c9da6b2ecb1..0d4155aec48d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -2018,6 +2018,9 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
2018 | 2018 | ||
2019 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); | 2019 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); |
2020 | 2020 | ||
2021 | if (sc->sc_ah->caldata) | ||
2022 | sc->sc_ah->caldata->paprd_packet_sent = true; | ||
2023 | |||
2021 | if (!(tx_flags & ATH_TX_ERROR)) | 2024 | if (!(tx_flags & ATH_TX_ERROR)) |
2022 | /* Frame was ACKed */ | 2025 | /* Frame was ACKed */ |
2023 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | 2026 | tx_info->flags |= IEEE80211_TX_STAT_ACK; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index a299d42da8e7..58f89fa9c9f8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
@@ -519,7 +519,7 @@ static void brcmf_usb_tx_complete(struct urb *urb) | |||
519 | else | 519 | else |
520 | devinfo->bus_pub.bus->dstats.tx_errors++; | 520 | devinfo->bus_pub.bus->dstats.tx_errors++; |
521 | 521 | ||
522 | dev_kfree_skb(req->skb); | 522 | brcmu_pkt_buf_free_skb(req->skb); |
523 | req->skb = NULL; | 523 | req->skb = NULL; |
524 | brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); | 524 | brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); |
525 | 525 | ||
@@ -540,7 +540,7 @@ static void brcmf_usb_rx_complete(struct urb *urb) | |||
540 | devinfo->bus_pub.bus->dstats.rx_packets++; | 540 | devinfo->bus_pub.bus->dstats.rx_packets++; |
541 | } else { | 541 | } else { |
542 | devinfo->bus_pub.bus->dstats.rx_errors++; | 542 | devinfo->bus_pub.bus->dstats.rx_errors++; |
543 | dev_kfree_skb(skb); | 543 | brcmu_pkt_buf_free_skb(skb); |
544 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | 544 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); |
545 | return; | 545 | return; |
546 | } | 546 | } |
@@ -550,13 +550,15 @@ static void brcmf_usb_rx_complete(struct urb *urb) | |||
550 | if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { | 550 | if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { |
551 | brcmf_dbg(ERROR, "rx protocol error\n"); | 551 | brcmf_dbg(ERROR, "rx protocol error\n"); |
552 | brcmu_pkt_buf_free_skb(skb); | 552 | brcmu_pkt_buf_free_skb(skb); |
553 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | ||
553 | devinfo->bus_pub.bus->dstats.rx_errors++; | 554 | devinfo->bus_pub.bus->dstats.rx_errors++; |
554 | } else { | 555 | } else { |
555 | brcmf_rx_packet(devinfo->dev, ifidx, skb); | 556 | brcmf_rx_packet(devinfo->dev, ifidx, skb); |
556 | brcmf_usb_rx_refill(devinfo, req); | 557 | brcmf_usb_rx_refill(devinfo, req); |
557 | } | 558 | } |
558 | } else { | 559 | } else { |
559 | dev_kfree_skb(skb); | 560 | brcmu_pkt_buf_free_skb(skb); |
561 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | ||
560 | } | 562 | } |
561 | return; | 563 | return; |
562 | 564 | ||
@@ -581,14 +583,13 @@ static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, | |||
581 | usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe, | 583 | usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe, |
582 | skb->data, skb_tailroom(skb), brcmf_usb_rx_complete, | 584 | skb->data, skb_tailroom(skb), brcmf_usb_rx_complete, |
583 | req); | 585 | req); |
584 | req->urb->transfer_flags |= URB_ZERO_PACKET; | ||
585 | req->devinfo = devinfo; | 586 | req->devinfo = devinfo; |
587 | brcmf_usb_enq(devinfo, &devinfo->rx_postq, req); | ||
586 | 588 | ||
587 | ret = usb_submit_urb(req->urb, GFP_ATOMIC); | 589 | ret = usb_submit_urb(req->urb, GFP_ATOMIC); |
588 | if (ret == 0) { | 590 | if (ret) { |
589 | brcmf_usb_enq(devinfo, &devinfo->rx_postq, req); | 591 | brcmf_usb_del_fromq(devinfo, req); |
590 | } else { | 592 | brcmu_pkt_buf_free_skb(req->skb); |
591 | dev_kfree_skb(req->skb); | ||
592 | req->skb = NULL; | 593 | req->skb = NULL; |
593 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | 594 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); |
594 | } | 595 | } |
@@ -683,23 +684,22 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) | |||
683 | 684 | ||
684 | req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq); | 685 | req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq); |
685 | if (!req) { | 686 | if (!req) { |
687 | brcmu_pkt_buf_free_skb(skb); | ||
686 | brcmf_dbg(ERROR, "no req to send\n"); | 688 | brcmf_dbg(ERROR, "no req to send\n"); |
687 | return -ENOMEM; | 689 | return -ENOMEM; |
688 | } | 690 | } |
689 | if (!req->urb) { | ||
690 | brcmf_dbg(ERROR, "no urb for req %p\n", req); | ||
691 | return -ENOBUFS; | ||
692 | } | ||
693 | 691 | ||
694 | req->skb = skb; | 692 | req->skb = skb; |
695 | req->devinfo = devinfo; | 693 | req->devinfo = devinfo; |
696 | usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe, | 694 | usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe, |
697 | skb->data, skb->len, brcmf_usb_tx_complete, req); | 695 | skb->data, skb->len, brcmf_usb_tx_complete, req); |
698 | req->urb->transfer_flags |= URB_ZERO_PACKET; | 696 | req->urb->transfer_flags |= URB_ZERO_PACKET; |
697 | brcmf_usb_enq(devinfo, &devinfo->tx_postq, req); | ||
699 | ret = usb_submit_urb(req->urb, GFP_ATOMIC); | 698 | ret = usb_submit_urb(req->urb, GFP_ATOMIC); |
700 | if (!ret) { | 699 | if (ret) { |
701 | brcmf_usb_enq(devinfo, &devinfo->tx_postq, req); | 700 | brcmf_dbg(ERROR, "brcmf_usb_tx usb_submit_urb FAILED\n"); |
702 | } else { | 701 | brcmf_usb_del_fromq(devinfo, req); |
702 | brcmu_pkt_buf_free_skb(req->skb); | ||
703 | req->skb = NULL; | 703 | req->skb = NULL; |
704 | brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); | 704 | brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); |
705 | } | 705 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 28c5fbb4af26..c36e92312443 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -1876,16 +1876,17 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, | |||
1876 | } | 1876 | } |
1877 | 1877 | ||
1878 | if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) { | 1878 | if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) { |
1879 | scb_val.val = cpu_to_le32(0); | 1879 | memset(&scb_val, 0, sizeof(scb_val)); |
1880 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val, | 1880 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val, |
1881 | sizeof(struct brcmf_scb_val_le)); | 1881 | sizeof(struct brcmf_scb_val_le)); |
1882 | if (err) | 1882 | if (err) { |
1883 | WL_ERR("Could not get rssi (%d)\n", err); | 1883 | WL_ERR("Could not get rssi (%d)\n", err); |
1884 | 1884 | } else { | |
1885 | rssi = le32_to_cpu(scb_val.val); | 1885 | rssi = le32_to_cpu(scb_val.val); |
1886 | sinfo->filled |= STATION_INFO_SIGNAL; | 1886 | sinfo->filled |= STATION_INFO_SIGNAL; |
1887 | sinfo->signal = rssi; | 1887 | sinfo->signal = rssi; |
1888 | WL_CONN("RSSI %d dBm\n", rssi); | 1888 | WL_CONN("RSSI %d dBm\n", rssi); |
1889 | } | ||
1889 | } | 1890 | } |
1890 | 1891 | ||
1891 | done: | 1892 | done: |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 192ad5c1fcc8..a5edebeb0b4f 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -1233,6 +1233,9 @@ uint brcms_reset(struct brcms_info *wl) | |||
1233 | /* dpc will not be rescheduled */ | 1233 | /* dpc will not be rescheduled */ |
1234 | wl->resched = false; | 1234 | wl->resched = false; |
1235 | 1235 | ||
1236 | /* inform publicly that interface is down */ | ||
1237 | wl->pub->up = false; | ||
1238 | |||
1236 | return 0; | 1239 | return 0; |
1237 | } | 1240 | } |
1238 | 1241 | ||
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 95aa8e1683ec..83324b321652 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
@@ -2042,7 +2042,8 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status) | |||
2042 | return; | 2042 | return; |
2043 | } | 2043 | } |
2044 | len = ETH_ALEN; | 2044 | len = ETH_ALEN; |
2045 | ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len); | 2045 | ret = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, bssid, |
2046 | &len); | ||
2046 | if (ret) { | 2047 | if (ret) { |
2047 | IPW_DEBUG_INFO("failed querying ordinals at line %d\n", | 2048 | IPW_DEBUG_INFO("failed querying ordinals at line %d\n", |
2048 | __LINE__); | 2049 | __LINE__); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 46782f1102ac..a47b306b522c 100644 --- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c | |||
@@ -124,6 +124,9 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
124 | const struct fw_img *img; | 124 | const struct fw_img *img; |
125 | size_t bufsz; | 125 | size_t bufsz; |
126 | 126 | ||
127 | if (!iwl_is_ready_rf(priv)) | ||
128 | return -EAGAIN; | ||
129 | |||
127 | /* default is to dump the entire data segment */ | 130 | /* default is to dump the entire data segment */ |
128 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { | 131 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { |
129 | priv->dbgfs_sram_offset = 0x800000; | 132 | priv->dbgfs_sram_offset = 0x800000; |
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index d9694c58208c..4ffc18dc3a57 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h | |||
@@ -350,7 +350,7 @@ int iwl_queue_space(const struct iwl_queue *q); | |||
350 | /***************************************************** | 350 | /***************************************************** |
351 | * Error handling | 351 | * Error handling |
352 | ******************************************************/ | 352 | ******************************************************/ |
353 | int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display); | 353 | int iwl_dump_fh(struct iwl_trans *trans, char **buf); |
354 | void iwl_dump_csr(struct iwl_trans *trans); | 354 | void iwl_dump_csr(struct iwl_trans *trans); |
355 | 355 | ||
356 | /***************************************************** | 356 | /***************************************************** |
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 39a6ca1f009c..d1a61ba6247a 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
@@ -555,7 +555,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) | |||
555 | } | 555 | } |
556 | 556 | ||
557 | iwl_dump_csr(trans); | 557 | iwl_dump_csr(trans); |
558 | iwl_dump_fh(trans, NULL, false); | 558 | iwl_dump_fh(trans, NULL); |
559 | 559 | ||
560 | iwl_op_mode_nic_error(trans->op_mode); | 560 | iwl_op_mode_nic_error(trans->op_mode); |
561 | } | 561 | } |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 939c2f78df58..1e86ea2266d4 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -1649,13 +1649,9 @@ static const char *get_fh_string(int cmd) | |||
1649 | #undef IWL_CMD | 1649 | #undef IWL_CMD |
1650 | } | 1650 | } |
1651 | 1651 | ||
1652 | int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) | 1652 | int iwl_dump_fh(struct iwl_trans *trans, char **buf) |
1653 | { | 1653 | { |
1654 | int i; | 1654 | int i; |
1655 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1656 | int pos = 0; | ||
1657 | size_t bufsz = 0; | ||
1658 | #endif | ||
1659 | static const u32 fh_tbl[] = { | 1655 | static const u32 fh_tbl[] = { |
1660 | FH_RSCSR_CHNL0_STTS_WPTR_REG, | 1656 | FH_RSCSR_CHNL0_STTS_WPTR_REG, |
1661 | FH_RSCSR_CHNL0_RBDCB_BASE_REG, | 1657 | FH_RSCSR_CHNL0_RBDCB_BASE_REG, |
@@ -1667,29 +1663,35 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) | |||
1667 | FH_TSSR_TX_STATUS_REG, | 1663 | FH_TSSR_TX_STATUS_REG, |
1668 | FH_TSSR_TX_ERROR_REG | 1664 | FH_TSSR_TX_ERROR_REG |
1669 | }; | 1665 | }; |
1670 | #ifdef CONFIG_IWLWIFI_DEBUG | 1666 | |
1671 | if (display) { | 1667 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
1672 | bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; | 1668 | if (buf) { |
1669 | int pos = 0; | ||
1670 | size_t bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; | ||
1671 | |||
1673 | *buf = kmalloc(bufsz, GFP_KERNEL); | 1672 | *buf = kmalloc(bufsz, GFP_KERNEL); |
1674 | if (!*buf) | 1673 | if (!*buf) |
1675 | return -ENOMEM; | 1674 | return -ENOMEM; |
1675 | |||
1676 | pos += scnprintf(*buf + pos, bufsz - pos, | 1676 | pos += scnprintf(*buf + pos, bufsz - pos, |
1677 | "FH register values:\n"); | 1677 | "FH register values:\n"); |
1678 | for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { | 1678 | |
1679 | for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) | ||
1679 | pos += scnprintf(*buf + pos, bufsz - pos, | 1680 | pos += scnprintf(*buf + pos, bufsz - pos, |
1680 | " %34s: 0X%08x\n", | 1681 | " %34s: 0X%08x\n", |
1681 | get_fh_string(fh_tbl[i]), | 1682 | get_fh_string(fh_tbl[i]), |
1682 | iwl_read_direct32(trans, fh_tbl[i])); | 1683 | iwl_read_direct32(trans, fh_tbl[i])); |
1683 | } | 1684 | |
1684 | return pos; | 1685 | return pos; |
1685 | } | 1686 | } |
1686 | #endif | 1687 | #endif |
1688 | |||
1687 | IWL_ERR(trans, "FH register values:\n"); | 1689 | IWL_ERR(trans, "FH register values:\n"); |
1688 | for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { | 1690 | for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) |
1689 | IWL_ERR(trans, " %34s: 0X%08x\n", | 1691 | IWL_ERR(trans, " %34s: 0X%08x\n", |
1690 | get_fh_string(fh_tbl[i]), | 1692 | get_fh_string(fh_tbl[i]), |
1691 | iwl_read_direct32(trans, fh_tbl[i])); | 1693 | iwl_read_direct32(trans, fh_tbl[i])); |
1692 | } | 1694 | |
1693 | return 0; | 1695 | return 0; |
1694 | } | 1696 | } |
1695 | 1697 | ||
@@ -1982,11 +1984,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, | |||
1982 | size_t count, loff_t *ppos) | 1984 | size_t count, loff_t *ppos) |
1983 | { | 1985 | { |
1984 | struct iwl_trans *trans = file->private_data; | 1986 | struct iwl_trans *trans = file->private_data; |
1985 | char *buf; | 1987 | char *buf = NULL; |
1986 | int pos = 0; | 1988 | int pos = 0; |
1987 | ssize_t ret = -EFAULT; | 1989 | ssize_t ret = -EFAULT; |
1988 | 1990 | ||
1989 | ret = pos = iwl_dump_fh(trans, &buf, true); | 1991 | ret = pos = iwl_dump_fh(trans, &buf); |
1990 | if (buf) { | 1992 | if (buf) { |
1991 | ret = simple_read_from_buffer(user_buf, | 1993 | ret = simple_read_from_buffer(user_buf, |
1992 | count, ppos, buf, pos); | 1994 | count, ppos, buf, pos); |
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index e970897f6ab5..4cb234349fbf 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
@@ -1326,6 +1326,11 @@ static int if_sdio_suspend(struct device *dev) | |||
1326 | 1326 | ||
1327 | mmc_pm_flag_t flags = sdio_get_host_pm_caps(func); | 1327 | mmc_pm_flag_t flags = sdio_get_host_pm_caps(func); |
1328 | 1328 | ||
1329 | /* If we're powered off anyway, just let the mmc layer remove the | ||
1330 | * card. */ | ||
1331 | if (!lbs_iface_active(card->priv)) | ||
1332 | return -ENOSYS; | ||
1333 | |||
1329 | dev_info(dev, "%s: suspend: PM flags = 0x%x\n", | 1334 | dev_info(dev, "%s: suspend: PM flags = 0x%x\n", |
1330 | sdio_func_id(func), flags); | 1335 | sdio_func_id(func), flags); |
1331 | 1336 | ||
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index c68adec3cc8b..565527aee0ea 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
@@ -170,7 +170,20 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, | |||
170 | cmd_code = le16_to_cpu(host_cmd->command); | 170 | cmd_code = le16_to_cpu(host_cmd->command); |
171 | cmd_size = le16_to_cpu(host_cmd->size); | 171 | cmd_size = le16_to_cpu(host_cmd->size); |
172 | 172 | ||
173 | skb_trim(cmd_node->cmd_skb, cmd_size); | 173 | /* Adjust skb length */ |
174 | if (cmd_node->cmd_skb->len > cmd_size) | ||
175 | /* | ||
176 | * cmd_size is less than sizeof(struct host_cmd_ds_command). | ||
177 | * Trim off the unused portion. | ||
178 | */ | ||
179 | skb_trim(cmd_node->cmd_skb, cmd_size); | ||
180 | else if (cmd_node->cmd_skb->len < cmd_size) | ||
181 | /* | ||
182 | * cmd_size is larger than sizeof(struct host_cmd_ds_command) | ||
183 | * because we have appended custom IE TLV. Increase skb length | ||
184 | * accordingly. | ||
185 | */ | ||
186 | skb_put(cmd_node->cmd_skb, cmd_size - cmd_node->cmd_skb->len); | ||
174 | 187 | ||
175 | do_gettimeofday(&tstamp); | 188 | do_gettimeofday(&tstamp); |
176 | dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," | 189 | dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 8b9dbd76a252..64328af496f5 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1611,6 +1611,7 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1611 | static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 1611 | static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
1612 | { | 1612 | { |
1613 | int retval; | 1613 | int retval; |
1614 | u32 reg; | ||
1614 | 1615 | ||
1615 | /* | 1616 | /* |
1616 | * Allocate eeprom data. | 1617 | * Allocate eeprom data. |
@@ -1624,6 +1625,14 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1624 | return retval; | 1625 | return retval; |
1625 | 1626 | ||
1626 | /* | 1627 | /* |
1628 | * Enable rfkill polling by setting GPIO direction of the | ||
1629 | * rfkill switch GPIO pin correctly. | ||
1630 | */ | ||
1631 | rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); | ||
1632 | rt2x00_set_field32(®, GPIOCSR_BIT8, 1); | ||
1633 | rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); | ||
1634 | |||
1635 | /* | ||
1627 | * Initialize hw specifications. | 1636 | * Initialize hw specifications. |
1628 | */ | 1637 | */ |
1629 | retval = rt2400pci_probe_hw_mode(rt2x00dev); | 1638 | retval = rt2400pci_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index d3a4a68cc439..7564ae992b73 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/drivers/net/wireless/rt2x00/rt2400pci.h | |||
@@ -670,6 +670,7 @@ | |||
670 | #define GPIOCSR_BIT5 FIELD32(0x00000020) | 670 | #define GPIOCSR_BIT5 FIELD32(0x00000020) |
671 | #define GPIOCSR_BIT6 FIELD32(0x00000040) | 671 | #define GPIOCSR_BIT6 FIELD32(0x00000040) |
672 | #define GPIOCSR_BIT7 FIELD32(0x00000080) | 672 | #define GPIOCSR_BIT7 FIELD32(0x00000080) |
673 | #define GPIOCSR_BIT8 FIELD32(0x00000100) | ||
673 | 674 | ||
674 | /* | 675 | /* |
675 | * BBPPCSR: BBP Pin control register. | 676 | * BBPPCSR: BBP Pin control register. |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index d2cf8a4bc8b5..3de0406735f6 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1929,6 +1929,7 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1929 | static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 1929 | static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
1930 | { | 1930 | { |
1931 | int retval; | 1931 | int retval; |
1932 | u32 reg; | ||
1932 | 1933 | ||
1933 | /* | 1934 | /* |
1934 | * Allocate eeprom data. | 1935 | * Allocate eeprom data. |
@@ -1942,6 +1943,14 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1942 | return retval; | 1943 | return retval; |
1943 | 1944 | ||
1944 | /* | 1945 | /* |
1946 | * Enable rfkill polling by setting GPIO direction of the | ||
1947 | * rfkill switch GPIO pin correctly. | ||
1948 | */ | ||
1949 | rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); | ||
1950 | rt2x00_set_field32(®, GPIOCSR_DIR0, 1); | ||
1951 | rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); | ||
1952 | |||
1953 | /* | ||
1945 | * Initialize hw specifications. | 1954 | * Initialize hw specifications. |
1946 | */ | 1955 | */ |
1947 | retval = rt2500pci_probe_hw_mode(rt2x00dev); | 1956 | retval = rt2500pci_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 3aae36bb0a9e..89fee311d8fd 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -283,7 +283,7 @@ static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
283 | u16 reg; | 283 | u16 reg; |
284 | 284 | ||
285 | rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); | 285 | rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); |
286 | return rt2x00_get_field32(reg, MAC_CSR19_BIT7); | 286 | return rt2x00_get_field16(reg, MAC_CSR19_BIT7); |
287 | } | 287 | } |
288 | 288 | ||
289 | #ifdef CONFIG_RT2X00_LIB_LEDS | 289 | #ifdef CONFIG_RT2X00_LIB_LEDS |
@@ -1768,6 +1768,7 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1768 | static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | 1768 | static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) |
1769 | { | 1769 | { |
1770 | int retval; | 1770 | int retval; |
1771 | u16 reg; | ||
1771 | 1772 | ||
1772 | /* | 1773 | /* |
1773 | * Allocate eeprom data. | 1774 | * Allocate eeprom data. |
@@ -1781,6 +1782,14 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1781 | return retval; | 1782 | return retval; |
1782 | 1783 | ||
1783 | /* | 1784 | /* |
1785 | * Enable rfkill polling by setting GPIO direction of the | ||
1786 | * rfkill switch GPIO pin correctly. | ||
1787 | */ | ||
1788 | rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); | ||
1789 | rt2x00_set_field16(®, MAC_CSR19_BIT8, 0); | ||
1790 | rt2500usb_register_write(rt2x00dev, MAC_CSR19, reg); | ||
1791 | |||
1792 | /* | ||
1784 | * Initialize hw specifications. | 1793 | * Initialize hw specifications. |
1785 | */ | 1794 | */ |
1786 | retval = rt2500usb_probe_hw_mode(rt2x00dev); | 1795 | retval = rt2500usb_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index b493306a7eed..196bd5103e4f 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h | |||
@@ -189,14 +189,15 @@ | |||
189 | * MAC_CSR19: GPIO control register. | 189 | * MAC_CSR19: GPIO control register. |
190 | */ | 190 | */ |
191 | #define MAC_CSR19 0x0426 | 191 | #define MAC_CSR19 0x0426 |
192 | #define MAC_CSR19_BIT0 FIELD32(0x0001) | 192 | #define MAC_CSR19_BIT0 FIELD16(0x0001) |
193 | #define MAC_CSR19_BIT1 FIELD32(0x0002) | 193 | #define MAC_CSR19_BIT1 FIELD16(0x0002) |
194 | #define MAC_CSR19_BIT2 FIELD32(0x0004) | 194 | #define MAC_CSR19_BIT2 FIELD16(0x0004) |
195 | #define MAC_CSR19_BIT3 FIELD32(0x0008) | 195 | #define MAC_CSR19_BIT3 FIELD16(0x0008) |
196 | #define MAC_CSR19_BIT4 FIELD32(0x0010) | 196 | #define MAC_CSR19_BIT4 FIELD16(0x0010) |
197 | #define MAC_CSR19_BIT5 FIELD32(0x0020) | 197 | #define MAC_CSR19_BIT5 FIELD16(0x0020) |
198 | #define MAC_CSR19_BIT6 FIELD32(0x0040) | 198 | #define MAC_CSR19_BIT6 FIELD16(0x0040) |
199 | #define MAC_CSR19_BIT7 FIELD32(0x0080) | 199 | #define MAC_CSR19_BIT7 FIELD16(0x0080) |
200 | #define MAC_CSR19_BIT8 FIELD16(0x0100) | ||
200 | 201 | ||
201 | /* | 202 | /* |
202 | * MAC_CSR20: LED control register. | 203 | * MAC_CSR20: LED control register. |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index cb8c2aca54e4..b93516d832fb 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -4089,6 +4089,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
4089 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | 4089 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); |
4090 | msleep(1); | 4090 | msleep(1); |
4091 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); | 4091 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); |
4092 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); | ||
4092 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); | 4093 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); |
4093 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | 4094 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); |
4094 | } | 4095 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 98aa426a3564..4765bbd654cd 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -983,6 +983,7 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
983 | static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 983 | static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
984 | { | 984 | { |
985 | int retval; | 985 | int retval; |
986 | u32 reg; | ||
986 | 987 | ||
987 | /* | 988 | /* |
988 | * Allocate eeprom data. | 989 | * Allocate eeprom data. |
@@ -996,6 +997,14 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
996 | return retval; | 997 | return retval; |
997 | 998 | ||
998 | /* | 999 | /* |
1000 | * Enable rfkill polling by setting GPIO direction of the | ||
1001 | * rfkill switch GPIO pin correctly. | ||
1002 | */ | ||
1003 | rt2x00pci_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); | ||
1004 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT2, 1); | ||
1005 | rt2x00pci_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); | ||
1006 | |||
1007 | /* | ||
999 | * Initialize hw specifications. | 1008 | * Initialize hw specifications. |
1000 | */ | 1009 | */ |
1001 | retval = rt2800_probe_hw_mode(rt2x00dev); | 1010 | retval = rt2800_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 6cf336595e25..6b4226b71618 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -667,8 +667,16 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
667 | skb_pull(entry->skb, RXINFO_DESC_SIZE); | 667 | skb_pull(entry->skb, RXINFO_DESC_SIZE); |
668 | 668 | ||
669 | /* | 669 | /* |
670 | * FIXME: we need to check for rx_pkt_len validity | 670 | * Check for rx_pkt_len validity. Return if invalid, leaving |
671 | * rxdesc->size zeroed out by the upper level. | ||
671 | */ | 672 | */ |
673 | if (unlikely(rx_pkt_len == 0 || | ||
674 | rx_pkt_len > entry->queue->data_size)) { | ||
675 | ERROR(entry->queue->rt2x00dev, | ||
676 | "Bad frame size %d, forcing to 0\n", rx_pkt_len); | ||
677 | return; | ||
678 | } | ||
679 | |||
672 | rxd = (__le32 *)(entry->skb->data + rx_pkt_len); | 680 | rxd = (__le32 *)(entry->skb->data + rx_pkt_len); |
673 | 681 | ||
674 | /* | 682 | /* |
@@ -736,6 +744,7 @@ static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
736 | static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | 744 | static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) |
737 | { | 745 | { |
738 | int retval; | 746 | int retval; |
747 | u32 reg; | ||
739 | 748 | ||
740 | /* | 749 | /* |
741 | * Allocate eeprom data. | 750 | * Allocate eeprom data. |
@@ -749,6 +758,14 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
749 | return retval; | 758 | return retval; |
750 | 759 | ||
751 | /* | 760 | /* |
761 | * Enable rfkill polling by setting GPIO direction of the | ||
762 | * rfkill switch GPIO pin correctly. | ||
763 | */ | ||
764 | rt2x00usb_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); | ||
765 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT2, 1); | ||
766 | rt2x00usb_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); | ||
767 | |||
768 | /* | ||
752 | * Initialize hw specifications. | 769 | * Initialize hw specifications. |
753 | */ | 770 | */ |
754 | retval = rt2800_probe_hw_mode(rt2x00dev); | 771 | retval = rt2800_probe_hw_mode(rt2x00dev); |
@@ -1157,6 +1174,8 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1157 | { USB_DEVICE(0x1690, 0x0744) }, | 1174 | { USB_DEVICE(0x1690, 0x0744) }, |
1158 | { USB_DEVICE(0x1690, 0x0761) }, | 1175 | { USB_DEVICE(0x1690, 0x0761) }, |
1159 | { USB_DEVICE(0x1690, 0x0764) }, | 1176 | { USB_DEVICE(0x1690, 0x0764) }, |
1177 | /* ASUS */ | ||
1178 | { USB_DEVICE(0x0b05, 0x179d) }, | ||
1160 | /* Cisco */ | 1179 | /* Cisco */ |
1161 | { USB_DEVICE(0x167b, 0x4001) }, | 1180 | { USB_DEVICE(0x167b, 0x4001) }, |
1162 | /* EnGenius */ | 1181 | /* EnGenius */ |
@@ -1222,7 +1241,6 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1222 | { USB_DEVICE(0x0b05, 0x1760) }, | 1241 | { USB_DEVICE(0x0b05, 0x1760) }, |
1223 | { USB_DEVICE(0x0b05, 0x1761) }, | 1242 | { USB_DEVICE(0x0b05, 0x1761) }, |
1224 | { USB_DEVICE(0x0b05, 0x1790) }, | 1243 | { USB_DEVICE(0x0b05, 0x1790) }, |
1225 | { USB_DEVICE(0x0b05, 0x179d) }, | ||
1226 | /* AzureWave */ | 1244 | /* AzureWave */ |
1227 | { USB_DEVICE(0x13d3, 0x3262) }, | 1245 | { USB_DEVICE(0x13d3, 0x3262) }, |
1228 | { USB_DEVICE(0x13d3, 0x3284) }, | 1246 | { USB_DEVICE(0x13d3, 0x3284) }, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index a6b88bd4a1a5..3f07e36f462b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -629,7 +629,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp) | |||
629 | */ | 629 | */ |
630 | if (unlikely(rxdesc.size == 0 || | 630 | if (unlikely(rxdesc.size == 0 || |
631 | rxdesc.size > entry->queue->data_size)) { | 631 | rxdesc.size > entry->queue->data_size)) { |
632 | WARNING(rt2x00dev, "Wrong frame size %d max %d.\n", | 632 | ERROR(rt2x00dev, "Wrong frame size %d max %d.\n", |
633 | rxdesc.size, entry->queue->data_size); | 633 | rxdesc.size, entry->queue->data_size); |
634 | dev_kfree_skb(entry->skb); | 634 | dev_kfree_skb(entry->skb); |
635 | goto renew_skb; | 635 | goto renew_skb; |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 3f7bc5cadf9a..b8ec96163922 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -2832,6 +2832,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2832 | static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 2832 | static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
2833 | { | 2833 | { |
2834 | int retval; | 2834 | int retval; |
2835 | u32 reg; | ||
2835 | 2836 | ||
2836 | /* | 2837 | /* |
2837 | * Disable power saving. | 2838 | * Disable power saving. |
@@ -2850,6 +2851,14 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2850 | return retval; | 2851 | return retval; |
2851 | 2852 | ||
2852 | /* | 2853 | /* |
2854 | * Enable rfkill polling by setting GPIO direction of the | ||
2855 | * rfkill switch GPIO pin correctly. | ||
2856 | */ | ||
2857 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); | ||
2858 | rt2x00_set_field32(®, MAC_CSR13_BIT13, 1); | ||
2859 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); | ||
2860 | |||
2861 | /* | ||
2853 | * Initialize hw specifications. | 2862 | * Initialize hw specifications. |
2854 | */ | 2863 | */ |
2855 | retval = rt61pci_probe_hw_mode(rt2x00dev); | 2864 | retval = rt61pci_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index e3cd6db76b0e..8f3da5a56766 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h | |||
@@ -372,6 +372,7 @@ struct hw_pairwise_ta_entry { | |||
372 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) | 372 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) |
373 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) | 373 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) |
374 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) | 374 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) |
375 | #define MAC_CSR13_BIT13 FIELD32(0x00002000) | ||
375 | 376 | ||
376 | /* | 377 | /* |
377 | * MAC_CSR14: LED control register. | 378 | * MAC_CSR14: LED control register. |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index ba6e434b859d..248436c13ce0 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -2177,6 +2177,7 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2177 | static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | 2177 | static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) |
2178 | { | 2178 | { |
2179 | int retval; | 2179 | int retval; |
2180 | u32 reg; | ||
2180 | 2181 | ||
2181 | /* | 2182 | /* |
2182 | * Allocate eeprom data. | 2183 | * Allocate eeprom data. |
@@ -2190,6 +2191,14 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2190 | return retval; | 2191 | return retval; |
2191 | 2192 | ||
2192 | /* | 2193 | /* |
2194 | * Enable rfkill polling by setting GPIO direction of the | ||
2195 | * rfkill switch GPIO pin correctly. | ||
2196 | */ | ||
2197 | rt2x00usb_register_read(rt2x00dev, MAC_CSR13, ®); | ||
2198 | rt2x00_set_field32(®, MAC_CSR13_BIT15, 0); | ||
2199 | rt2x00usb_register_write(rt2x00dev, MAC_CSR13, reg); | ||
2200 | |||
2201 | /* | ||
2193 | * Initialize hw specifications. | 2202 | * Initialize hw specifications. |
2194 | */ | 2203 | */ |
2195 | retval = rt73usb_probe_hw_mode(rt2x00dev); | 2204 | retval = rt73usb_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index 9f6b470414d3..df1cc116b83b 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h | |||
@@ -282,6 +282,9 @@ struct hw_pairwise_ta_entry { | |||
282 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) | 282 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) |
283 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) | 283 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) |
284 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) | 284 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) |
285 | #define MAC_CSR13_BIT13 FIELD32(0x00002000) | ||
286 | #define MAC_CSR13_BIT14 FIELD32(0x00004000) | ||
287 | #define MAC_CSR13_BIT15 FIELD32(0x00008000) | ||
285 | 288 | ||
286 | /* | 289 | /* |
287 | * MAC_CSR14: LED control register. | 290 | * MAC_CSR14: LED control register. |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 30899901aef5..650f79a1f2bd 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -57,8 +57,7 @@ | |||
57 | static const struct ethtool_ops xennet_ethtool_ops; | 57 | static const struct ethtool_ops xennet_ethtool_ops; |
58 | 58 | ||
59 | struct netfront_cb { | 59 | struct netfront_cb { |
60 | struct page *page; | 60 | int pull_to; |
61 | unsigned offset; | ||
62 | }; | 61 | }; |
63 | 62 | ||
64 | #define NETFRONT_SKB_CB(skb) ((struct netfront_cb *)((skb)->cb)) | 63 | #define NETFRONT_SKB_CB(skb) ((struct netfront_cb *)((skb)->cb)) |
@@ -867,15 +866,9 @@ static int handle_incoming_queue(struct net_device *dev, | |||
867 | struct sk_buff *skb; | 866 | struct sk_buff *skb; |
868 | 867 | ||
869 | while ((skb = __skb_dequeue(rxq)) != NULL) { | 868 | while ((skb = __skb_dequeue(rxq)) != NULL) { |
870 | struct page *page = NETFRONT_SKB_CB(skb)->page; | 869 | int pull_to = NETFRONT_SKB_CB(skb)->pull_to; |
871 | void *vaddr = page_address(page); | ||
872 | unsigned offset = NETFRONT_SKB_CB(skb)->offset; | ||
873 | |||
874 | memcpy(skb->data, vaddr + offset, | ||
875 | skb_headlen(skb)); | ||
876 | 870 | ||
877 | if (page != skb_frag_page(&skb_shinfo(skb)->frags[0])) | 871 | __pskb_pull_tail(skb, pull_to - skb_headlen(skb)); |
878 | __free_page(page); | ||
879 | 872 | ||
880 | /* Ethernet work: Delayed to here as it peeks the header. */ | 873 | /* Ethernet work: Delayed to here as it peeks the header. */ |
881 | skb->protocol = eth_type_trans(skb, dev); | 874 | skb->protocol = eth_type_trans(skb, dev); |
@@ -913,7 +906,6 @@ static int xennet_poll(struct napi_struct *napi, int budget) | |||
913 | struct sk_buff_head errq; | 906 | struct sk_buff_head errq; |
914 | struct sk_buff_head tmpq; | 907 | struct sk_buff_head tmpq; |
915 | unsigned long flags; | 908 | unsigned long flags; |
916 | unsigned int len; | ||
917 | int err; | 909 | int err; |
918 | 910 | ||
919 | spin_lock(&np->rx_lock); | 911 | spin_lock(&np->rx_lock); |
@@ -955,24 +947,13 @@ err: | |||
955 | } | 947 | } |
956 | } | 948 | } |
957 | 949 | ||
958 | NETFRONT_SKB_CB(skb)->page = | 950 | NETFRONT_SKB_CB(skb)->pull_to = rx->status; |
959 | skb_frag_page(&skb_shinfo(skb)->frags[0]); | 951 | if (NETFRONT_SKB_CB(skb)->pull_to > RX_COPY_THRESHOLD) |
960 | NETFRONT_SKB_CB(skb)->offset = rx->offset; | 952 | NETFRONT_SKB_CB(skb)->pull_to = RX_COPY_THRESHOLD; |
961 | |||
962 | len = rx->status; | ||
963 | if (len > RX_COPY_THRESHOLD) | ||
964 | len = RX_COPY_THRESHOLD; | ||
965 | skb_put(skb, len); | ||
966 | 953 | ||
967 | if (rx->status > len) { | 954 | skb_shinfo(skb)->frags[0].page_offset = rx->offset; |
968 | skb_shinfo(skb)->frags[0].page_offset = | 955 | skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status); |
969 | rx->offset + len; | 956 | skb->data_len = rx->status; |
970 | skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status - len); | ||
971 | skb->data_len = rx->status - len; | ||
972 | } else { | ||
973 | __skb_fill_page_desc(skb, 0, NULL, 0, 0); | ||
974 | skb_shinfo(skb)->nr_frags = 0; | ||
975 | } | ||
976 | 957 | ||
977 | i = xennet_fill_frags(np, skb, &tmpq); | 958 | i = xennet_fill_frags(np, skb, &tmpq); |
978 | 959 | ||
@@ -999,7 +980,7 @@ err: | |||
999 | * receive throughout using the standard receive | 980 | * receive throughout using the standard receive |
1000 | * buffer size was cut by 25%(!!!). | 981 | * buffer size was cut by 25%(!!!). |
1001 | */ | 982 | */ |
1002 | skb->truesize += skb->data_len - (RX_COPY_THRESHOLD - len); | 983 | skb->truesize += skb->data_len - RX_COPY_THRESHOLD; |
1003 | skb->len += skb->data_len; | 984 | skb->len += skb->data_len; |
1004 | 985 | ||
1005 | if (rx->flags & XEN_NETRXF_csum_blank) | 986 | if (rx->flags & XEN_NETRXF_csum_blank) |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 5270f1a99328..d6fd6b6d9d4b 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -280,8 +280,12 @@ static long local_pci_probe(void *_ddi) | |||
280 | { | 280 | { |
281 | struct drv_dev_and_id *ddi = _ddi; | 281 | struct drv_dev_and_id *ddi = _ddi; |
282 | struct device *dev = &ddi->dev->dev; | 282 | struct device *dev = &ddi->dev->dev; |
283 | struct device *parent = dev->parent; | ||
283 | int rc; | 284 | int rc; |
284 | 285 | ||
286 | /* The parent bridge must be in active state when probing */ | ||
287 | if (parent) | ||
288 | pm_runtime_get_sync(parent); | ||
285 | /* Unbound PCI devices are always set to disabled and suspended. | 289 | /* Unbound PCI devices are always set to disabled and suspended. |
286 | * During probe, the device is set to enabled and active and the | 290 | * During probe, the device is set to enabled and active and the |
287 | * usage count is incremented. If the driver supports runtime PM, | 291 | * usage count is incremented. If the driver supports runtime PM, |
@@ -298,6 +302,8 @@ static long local_pci_probe(void *_ddi) | |||
298 | pm_runtime_set_suspended(dev); | 302 | pm_runtime_set_suspended(dev); |
299 | pm_runtime_put_noidle(dev); | 303 | pm_runtime_put_noidle(dev); |
300 | } | 304 | } |
305 | if (parent) | ||
306 | pm_runtime_put(parent); | ||
301 | return rc; | 307 | return rc; |
302 | } | 308 | } |
303 | 309 | ||
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 6869009c7393..02d107b15281 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -458,6 +458,40 @@ boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
458 | } | 458 | } |
459 | struct device_attribute vga_attr = __ATTR_RO(boot_vga); | 459 | struct device_attribute vga_attr = __ATTR_RO(boot_vga); |
460 | 460 | ||
461 | static void | ||
462 | pci_config_pm_runtime_get(struct pci_dev *pdev) | ||
463 | { | ||
464 | struct device *dev = &pdev->dev; | ||
465 | struct device *parent = dev->parent; | ||
466 | |||
467 | if (parent) | ||
468 | pm_runtime_get_sync(parent); | ||
469 | pm_runtime_get_noresume(dev); | ||
470 | /* | ||
471 | * pdev->current_state is set to PCI_D3cold during suspending, | ||
472 | * so wait until suspending completes | ||
473 | */ | ||
474 | pm_runtime_barrier(dev); | ||
475 | /* | ||
476 | * Only need to resume devices in D3cold, because config | ||
477 | * registers are still accessible for devices suspended but | ||
478 | * not in D3cold. | ||
479 | */ | ||
480 | if (pdev->current_state == PCI_D3cold) | ||
481 | pm_runtime_resume(dev); | ||
482 | } | ||
483 | |||
484 | static void | ||
485 | pci_config_pm_runtime_put(struct pci_dev *pdev) | ||
486 | { | ||
487 | struct device *dev = &pdev->dev; | ||
488 | struct device *parent = dev->parent; | ||
489 | |||
490 | pm_runtime_put(dev); | ||
491 | if (parent) | ||
492 | pm_runtime_put_sync(parent); | ||
493 | } | ||
494 | |||
461 | static ssize_t | 495 | static ssize_t |
462 | pci_read_config(struct file *filp, struct kobject *kobj, | 496 | pci_read_config(struct file *filp, struct kobject *kobj, |
463 | struct bin_attribute *bin_attr, | 497 | struct bin_attribute *bin_attr, |
@@ -484,6 +518,8 @@ pci_read_config(struct file *filp, struct kobject *kobj, | |||
484 | size = count; | 518 | size = count; |
485 | } | 519 | } |
486 | 520 | ||
521 | pci_config_pm_runtime_get(dev); | ||
522 | |||
487 | if ((off & 1) && size) { | 523 | if ((off & 1) && size) { |
488 | u8 val; | 524 | u8 val; |
489 | pci_user_read_config_byte(dev, off, &val); | 525 | pci_user_read_config_byte(dev, off, &val); |
@@ -529,6 +565,8 @@ pci_read_config(struct file *filp, struct kobject *kobj, | |||
529 | --size; | 565 | --size; |
530 | } | 566 | } |
531 | 567 | ||
568 | pci_config_pm_runtime_put(dev); | ||
569 | |||
532 | return count; | 570 | return count; |
533 | } | 571 | } |
534 | 572 | ||
@@ -549,6 +587,8 @@ pci_write_config(struct file* filp, struct kobject *kobj, | |||
549 | count = size; | 587 | count = size; |
550 | } | 588 | } |
551 | 589 | ||
590 | pci_config_pm_runtime_get(dev); | ||
591 | |||
552 | if ((off & 1) && size) { | 592 | if ((off & 1) && size) { |
553 | pci_user_write_config_byte(dev, off, data[off - init_off]); | 593 | pci_user_write_config_byte(dev, off, data[off - init_off]); |
554 | off++; | 594 | off++; |
@@ -587,6 +627,8 @@ pci_write_config(struct file* filp, struct kobject *kobj, | |||
587 | --size; | 627 | --size; |
588 | } | 628 | } |
589 | 629 | ||
630 | pci_config_pm_runtime_put(dev); | ||
631 | |||
590 | return count; | 632 | return count; |
591 | } | 633 | } |
592 | 634 | ||
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index f3ea977a5b1b..ab4bf5a4c2f1 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1941,6 +1941,7 @@ void pci_pm_init(struct pci_dev *dev) | |||
1941 | dev->pm_cap = pm; | 1941 | dev->pm_cap = pm; |
1942 | dev->d3_delay = PCI_PM_D3_WAIT; | 1942 | dev->d3_delay = PCI_PM_D3_WAIT; |
1943 | dev->d3cold_delay = PCI_PM_D3COLD_WAIT; | 1943 | dev->d3cold_delay = PCI_PM_D3COLD_WAIT; |
1944 | dev->d3cold_allowed = true; | ||
1944 | 1945 | ||
1945 | dev->d1_support = false; | 1946 | dev->d1_support = false; |
1946 | dev->d2_support = false; | 1947 | dev->d2_support = false; |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 3a7eefcb270a..e76b44777dbf 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -140,9 +140,17 @@ static int pcie_port_runtime_resume(struct device *dev) | |||
140 | { | 140 | { |
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
143 | |||
144 | static int pcie_port_runtime_idle(struct device *dev) | ||
145 | { | ||
146 | /* Delay for a short while to prevent too frequent suspend/resume */ | ||
147 | pm_schedule_suspend(dev, 10); | ||
148 | return -EBUSY; | ||
149 | } | ||
143 | #else | 150 | #else |
144 | #define pcie_port_runtime_suspend NULL | 151 | #define pcie_port_runtime_suspend NULL |
145 | #define pcie_port_runtime_resume NULL | 152 | #define pcie_port_runtime_resume NULL |
153 | #define pcie_port_runtime_idle NULL | ||
146 | #endif | 154 | #endif |
147 | 155 | ||
148 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { | 156 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { |
@@ -155,6 +163,7 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { | |||
155 | .resume_noirq = pcie_port_resume_noirq, | 163 | .resume_noirq = pcie_port_resume_noirq, |
156 | .runtime_suspend = pcie_port_runtime_suspend, | 164 | .runtime_suspend = pcie_port_runtime_suspend, |
157 | .runtime_resume = pcie_port_runtime_resume, | 165 | .runtime_resume = pcie_port_runtime_resume, |
166 | .runtime_idle = pcie_port_runtime_idle, | ||
158 | }; | 167 | }; |
159 | 168 | ||
160 | #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) | 169 | #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) |
@@ -200,6 +209,11 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev, | |||
200 | return status; | 209 | return status; |
201 | 210 | ||
202 | pci_save_state(dev); | 211 | pci_save_state(dev); |
212 | /* | ||
213 | * D3cold may not work properly on some PCIe port, so disable | ||
214 | * it by default. | ||
215 | */ | ||
216 | dev->d3cold_allowed = false; | ||
203 | if (!pci_match_id(port_runtime_pm_black_list, dev)) | 217 | if (!pci_match_id(port_runtime_pm_black_list, dev)) |
204 | pm_runtime_put_noidle(&dev->dev); | 218 | pm_runtime_put_noidle(&dev->dev); |
205 | 219 | ||
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6c143b4497ca..9f8a6b79a8ec 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -144,15 +144,13 @@ static inline unsigned long decode_bar(struct pci_dev *dev, u32 bar) | |||
144 | case PCI_BASE_ADDRESS_MEM_TYPE_32: | 144 | case PCI_BASE_ADDRESS_MEM_TYPE_32: |
145 | break; | 145 | break; |
146 | case PCI_BASE_ADDRESS_MEM_TYPE_1M: | 146 | case PCI_BASE_ADDRESS_MEM_TYPE_1M: |
147 | dev_info(&dev->dev, "1M mem BAR treated as 32-bit BAR\n"); | 147 | /* 1M mem BAR treated as 32-bit BAR */ |
148 | break; | 148 | break; |
149 | case PCI_BASE_ADDRESS_MEM_TYPE_64: | 149 | case PCI_BASE_ADDRESS_MEM_TYPE_64: |
150 | flags |= IORESOURCE_MEM_64; | 150 | flags |= IORESOURCE_MEM_64; |
151 | break; | 151 | break; |
152 | default: | 152 | default: |
153 | dev_warn(&dev->dev, | 153 | /* mem unknown type treated as 32-bit BAR */ |
154 | "mem unknown type %x treated as 32-bit BAR\n", | ||
155 | mem_type); | ||
156 | break; | 154 | break; |
157 | } | 155 | } |
158 | return flags; | 156 | return flags; |
@@ -173,9 +171,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
173 | u32 l, sz, mask; | 171 | u32 l, sz, mask; |
174 | u16 orig_cmd; | 172 | u16 orig_cmd; |
175 | struct pci_bus_region region; | 173 | struct pci_bus_region region; |
174 | bool bar_too_big = false, bar_disabled = false; | ||
176 | 175 | ||
177 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; | 176 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; |
178 | 177 | ||
178 | /* No printks while decoding is disabled! */ | ||
179 | if (!dev->mmio_always_on) { | 179 | if (!dev->mmio_always_on) { |
180 | pci_read_config_word(dev, PCI_COMMAND, &orig_cmd); | 180 | pci_read_config_word(dev, PCI_COMMAND, &orig_cmd); |
181 | pci_write_config_word(dev, PCI_COMMAND, | 181 | pci_write_config_word(dev, PCI_COMMAND, |
@@ -240,8 +240,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
240 | goto fail; | 240 | goto fail; |
241 | 241 | ||
242 | if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { | 242 | if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { |
243 | dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n", | 243 | bar_too_big = true; |
244 | pos); | ||
245 | goto fail; | 244 | goto fail; |
246 | } | 245 | } |
247 | 246 | ||
@@ -252,12 +251,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
252 | region.start = 0; | 251 | region.start = 0; |
253 | region.end = sz64; | 252 | region.end = sz64; |
254 | pcibios_bus_to_resource(dev, res, ®ion); | 253 | pcibios_bus_to_resource(dev, res, ®ion); |
254 | bar_disabled = true; | ||
255 | } else { | 255 | } else { |
256 | region.start = l64; | 256 | region.start = l64; |
257 | region.end = l64 + sz64; | 257 | region.end = l64 + sz64; |
258 | pcibios_bus_to_resource(dev, res, ®ion); | 258 | pcibios_bus_to_resource(dev, res, ®ion); |
259 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", | ||
260 | pos, res); | ||
261 | } | 259 | } |
262 | } else { | 260 | } else { |
263 | sz = pci_size(l, sz, mask); | 261 | sz = pci_size(l, sz, mask); |
@@ -268,18 +266,23 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
268 | region.start = l; | 266 | region.start = l; |
269 | region.end = l + sz; | 267 | region.end = l + sz; |
270 | pcibios_bus_to_resource(dev, res, ®ion); | 268 | pcibios_bus_to_resource(dev, res, ®ion); |
271 | |||
272 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); | ||
273 | } | 269 | } |
274 | 270 | ||
275 | out: | 271 | goto out; |
272 | |||
273 | |||
274 | fail: | ||
275 | res->flags = 0; | ||
276 | out: | ||
276 | if (!dev->mmio_always_on) | 277 | if (!dev->mmio_always_on) |
277 | pci_write_config_word(dev, PCI_COMMAND, orig_cmd); | 278 | pci_write_config_word(dev, PCI_COMMAND, orig_cmd); |
278 | 279 | ||
280 | if (bar_too_big) | ||
281 | dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n", pos); | ||
282 | if (res->flags && !bar_disabled) | ||
283 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); | ||
284 | |||
279 | return (res->flags & IORESOURCE_MEM_64) ? 1 : 0; | 285 | return (res->flags & IORESOURCE_MEM_64) ? 1 : 0; |
280 | fail: | ||
281 | res->flags = 0; | ||
282 | goto out; | ||
283 | } | 286 | } |
284 | 287 | ||
285 | static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) | 288 | static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) |
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 3782e1cd3697..934d861a3235 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -2196,10 +2196,8 @@ static int __init acer_wmi_init(void) | |||
2196 | interface->capability &= ~ACER_CAP_BRIGHTNESS; | 2196 | interface->capability &= ~ACER_CAP_BRIGHTNESS; |
2197 | pr_info("Brightness must be controlled by acpi video driver\n"); | 2197 | pr_info("Brightness must be controlled by acpi video driver\n"); |
2198 | } else { | 2198 | } else { |
2199 | #ifdef CONFIG_ACPI_VIDEO | ||
2200 | pr_info("Disabling ACPI video driver\n"); | 2199 | pr_info("Disabling ACPI video driver\n"); |
2201 | acpi_video_unregister(); | 2200 | acpi_video_unregister(); |
2202 | #endif | ||
2203 | } | 2201 | } |
2204 | 2202 | ||
2205 | if (wmi_has_guid(WMID_GUID3)) { | 2203 | if (wmi_has_guid(WMID_GUID3)) { |
diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index dfb1a92ce949..db8f63841b42 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c | |||
@@ -101,7 +101,7 @@ static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int port, | |||
101 | 101 | ||
102 | for (i = 0; i < 4; i++) { | 102 | for (i = 0; i < 4; i++) { |
103 | tmpval = (val >> (i * 8)) & 0xff; | 103 | tmpval = (val >> (i * 8)) & 0xff; |
104 | outb(tmpval, port + i); | 104 | outb(tmpval, gmux_data->iostart + port + i); |
105 | } | 105 | } |
106 | } | 106 | } |
107 | 107 | ||
@@ -142,8 +142,9 @@ static u8 gmux_index_read8(struct apple_gmux_data *gmux_data, int port) | |||
142 | u8 val; | 142 | u8 val; |
143 | 143 | ||
144 | mutex_lock(&gmux_data->index_lock); | 144 | mutex_lock(&gmux_data->index_lock); |
145 | outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); | ||
146 | gmux_index_wait_ready(gmux_data); | 145 | gmux_index_wait_ready(gmux_data); |
146 | outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); | ||
147 | gmux_index_wait_complete(gmux_data); | ||
147 | val = inb(gmux_data->iostart + GMUX_PORT_VALUE); | 148 | val = inb(gmux_data->iostart + GMUX_PORT_VALUE); |
148 | mutex_unlock(&gmux_data->index_lock); | 149 | mutex_unlock(&gmux_data->index_lock); |
149 | 150 | ||
@@ -166,8 +167,9 @@ static u32 gmux_index_read32(struct apple_gmux_data *gmux_data, int port) | |||
166 | u32 val; | 167 | u32 val; |
167 | 168 | ||
168 | mutex_lock(&gmux_data->index_lock); | 169 | mutex_lock(&gmux_data->index_lock); |
169 | outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); | ||
170 | gmux_index_wait_ready(gmux_data); | 170 | gmux_index_wait_ready(gmux_data); |
171 | outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); | ||
172 | gmux_index_wait_complete(gmux_data); | ||
171 | val = inl(gmux_data->iostart + GMUX_PORT_VALUE); | 173 | val = inl(gmux_data->iostart + GMUX_PORT_VALUE); |
172 | mutex_unlock(&gmux_data->index_lock); | 174 | mutex_unlock(&gmux_data->index_lock); |
173 | 175 | ||
@@ -461,18 +463,22 @@ static int __devinit gmux_probe(struct pnp_dev *pnp, | |||
461 | ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE); | 463 | ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE); |
462 | if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) { | 464 | if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) { |
463 | if (gmux_is_indexed(gmux_data)) { | 465 | if (gmux_is_indexed(gmux_data)) { |
466 | u32 version; | ||
464 | mutex_init(&gmux_data->index_lock); | 467 | mutex_init(&gmux_data->index_lock); |
465 | gmux_data->indexed = true; | 468 | gmux_data->indexed = true; |
469 | version = gmux_read32(gmux_data, | ||
470 | GMUX_PORT_VERSION_MAJOR); | ||
471 | ver_major = (version >> 24) & 0xff; | ||
472 | ver_minor = (version >> 16) & 0xff; | ||
473 | ver_release = (version >> 8) & 0xff; | ||
466 | } else { | 474 | } else { |
467 | pr_info("gmux device not present\n"); | 475 | pr_info("gmux device not present\n"); |
468 | ret = -ENODEV; | 476 | ret = -ENODEV; |
469 | goto err_release; | 477 | goto err_release; |
470 | } | 478 | } |
471 | pr_info("Found indexed gmux\n"); | ||
472 | } else { | ||
473 | pr_info("Found gmux version %d.%d.%d\n", ver_major, ver_minor, | ||
474 | ver_release); | ||
475 | } | 479 | } |
480 | pr_info("Found gmux version %d.%d.%d [%s]\n", ver_major, ver_minor, | ||
481 | ver_release, (gmux_data->indexed ? "indexed" : "classic")); | ||
476 | 482 | ||
477 | memset(&props, 0, sizeof(props)); | 483 | memset(&props, 0, sizeof(props)); |
478 | props.type = BACKLIGHT_PLATFORM; | 484 | props.type = BACKLIGHT_PLATFORM; |
@@ -505,9 +511,7 @@ static int __devinit gmux_probe(struct pnp_dev *pnp, | |||
505 | * Disable the other backlight choices. | 511 | * Disable the other backlight choices. |
506 | */ | 512 | */ |
507 | acpi_video_dmi_promote_vendor(); | 513 | acpi_video_dmi_promote_vendor(); |
508 | #if defined (CONFIG_ACPI_VIDEO) || defined (CONFIG_ACPI_VIDEO_MODULE) | ||
509 | acpi_video_unregister(); | 514 | acpi_video_unregister(); |
510 | #endif | ||
511 | apple_bl_unregister(); | 515 | apple_bl_unregister(); |
512 | 516 | ||
513 | gmux_data->power_state = VGA_SWITCHEROO_ON; | 517 | gmux_data->power_state = VGA_SWITCHEROO_ON; |
@@ -593,9 +597,7 @@ static void __devexit gmux_remove(struct pnp_dev *pnp) | |||
593 | kfree(gmux_data); | 597 | kfree(gmux_data); |
594 | 598 | ||
595 | acpi_video_dmi_demote_vendor(); | 599 | acpi_video_dmi_demote_vendor(); |
596 | #if defined (CONFIG_ACPI_VIDEO) || defined (CONFIG_ACPI_VIDEO_MODULE) | ||
597 | acpi_video_register(); | 600 | acpi_video_register(); |
598 | #endif | ||
599 | apple_bl_register(); | 601 | apple_bl_register(); |
600 | } | 602 | } |
601 | 603 | ||
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index e38f91be0b10..4b568df56643 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
@@ -85,7 +85,7 @@ static char *wled_type = "unknown"; | |||
85 | static char *bled_type = "unknown"; | 85 | static char *bled_type = "unknown"; |
86 | 86 | ||
87 | module_param(wled_type, charp, 0444); | 87 | module_param(wled_type, charp, 0444); |
88 | MODULE_PARM_DESC(wlan_status, "Set the wled type on boot " | 88 | MODULE_PARM_DESC(wled_type, "Set the wled type on boot " |
89 | "(unknown, led or rfkill). " | 89 | "(unknown, led or rfkill). " |
90 | "default is unknown"); | 90 | "default is unknown"); |
91 | 91 | ||
@@ -863,9 +863,9 @@ static ssize_t show_infos(struct device *dev, | |||
863 | * The significance of others is yet to be found. | 863 | * The significance of others is yet to be found. |
864 | * If we don't find the method, we assume the device are present. | 864 | * If we don't find the method, we assume the device are present. |
865 | */ | 865 | */ |
866 | rv = acpi_evaluate_integer(asus->handle, "HRWS", NULL, &temp); | 866 | rv = acpi_evaluate_integer(asus->handle, "HWRS", NULL, &temp); |
867 | if (!ACPI_FAILURE(rv)) | 867 | if (!ACPI_FAILURE(rv)) |
868 | len += sprintf(page + len, "HRWS value : %#x\n", | 868 | len += sprintf(page + len, "HWRS value : %#x\n", |
869 | (uint) temp); | 869 | (uint) temp); |
870 | /* | 870 | /* |
871 | * Another value for userspace: the ASYM method returns 0x02 for | 871 | * Another value for userspace: the ASYM method returns 0x02 for |
@@ -1751,9 +1751,9 @@ static int asus_laptop_get_info(struct asus_laptop *asus) | |||
1751 | * The significance of others is yet to be found. | 1751 | * The significance of others is yet to be found. |
1752 | */ | 1752 | */ |
1753 | status = | 1753 | status = |
1754 | acpi_evaluate_integer(asus->handle, "HRWS", NULL, &hwrs_result); | 1754 | acpi_evaluate_integer(asus->handle, "HWRS", NULL, &hwrs_result); |
1755 | if (!ACPI_FAILURE(status)) | 1755 | if (!ACPI_FAILURE(status)) |
1756 | pr_notice(" HRWS returned %x", (int)hwrs_result); | 1756 | pr_notice(" HWRS returned %x", (int)hwrs_result); |
1757 | 1757 | ||
1758 | if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) | 1758 | if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) |
1759 | asus->have_rsts = true; | 1759 | asus->have_rsts = true; |
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 2eb9fe8e8efd..c0e9ff489b24 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
@@ -47,9 +47,7 @@ | |||
47 | #include <linux/thermal.h> | 47 | #include <linux/thermal.h> |
48 | #include <acpi/acpi_bus.h> | 48 | #include <acpi/acpi_bus.h> |
49 | #include <acpi/acpi_drivers.h> | 49 | #include <acpi/acpi_drivers.h> |
50 | #ifdef CONFIG_ACPI_VIDEO | ||
51 | #include <acpi/video.h> | 50 | #include <acpi/video.h> |
52 | #endif | ||
53 | 51 | ||
54 | #include "asus-wmi.h" | 52 | #include "asus-wmi.h" |
55 | 53 | ||
@@ -1704,10 +1702,8 @@ static int asus_wmi_add(struct platform_device *pdev) | |||
1704 | if (asus->driver->quirks->wmi_backlight_power) | 1702 | if (asus->driver->quirks->wmi_backlight_power) |
1705 | acpi_video_dmi_promote_vendor(); | 1703 | acpi_video_dmi_promote_vendor(); |
1706 | if (!acpi_video_backlight_support()) { | 1704 | if (!acpi_video_backlight_support()) { |
1707 | #ifdef CONFIG_ACPI_VIDEO | ||
1708 | pr_info("Disabling ACPI video driver\n"); | 1705 | pr_info("Disabling ACPI video driver\n"); |
1709 | acpi_video_unregister(); | 1706 | acpi_video_unregister(); |
1710 | #endif | ||
1711 | err = asus_wmi_backlight_init(asus); | 1707 | err = asus_wmi_backlight_init(asus); |
1712 | if (err && err != -ENODEV) | 1708 | if (err && err != -ENODEV) |
1713 | goto fail_backlight; | 1709 | goto fail_backlight; |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index dab91b48d22c..5ca264179f4e 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -610,12 +610,12 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
610 | 610 | ||
611 | if (!bus) { | 611 | if (!bus) { |
612 | pr_warn("Unable to find PCI bus 1?\n"); | 612 | pr_warn("Unable to find PCI bus 1?\n"); |
613 | goto out_unlock; | 613 | goto out_put_dev; |
614 | } | 614 | } |
615 | 615 | ||
616 | if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) { | 616 | if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) { |
617 | pr_err("Unable to read PCI config space?\n"); | 617 | pr_err("Unable to read PCI config space?\n"); |
618 | goto out_unlock; | 618 | goto out_put_dev; |
619 | } | 619 | } |
620 | 620 | ||
621 | absent = (l == 0xffffffff); | 621 | absent = (l == 0xffffffff); |
@@ -627,7 +627,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
627 | absent ? "absent" : "present"); | 627 | absent ? "absent" : "present"); |
628 | pr_warn("skipped wireless hotplug as probably " | 628 | pr_warn("skipped wireless hotplug as probably " |
629 | "inappropriate for this model\n"); | 629 | "inappropriate for this model\n"); |
630 | goto out_unlock; | 630 | goto out_put_dev; |
631 | } | 631 | } |
632 | 632 | ||
633 | if (!blocked) { | 633 | if (!blocked) { |
@@ -635,7 +635,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
635 | if (dev) { | 635 | if (dev) { |
636 | /* Device already present */ | 636 | /* Device already present */ |
637 | pci_dev_put(dev); | 637 | pci_dev_put(dev); |
638 | goto out_unlock; | 638 | goto out_put_dev; |
639 | } | 639 | } |
640 | dev = pci_scan_single_device(bus, 0); | 640 | dev = pci_scan_single_device(bus, 0); |
641 | if (dev) { | 641 | if (dev) { |
@@ -650,6 +650,8 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
650 | pci_dev_put(dev); | 650 | pci_dev_put(dev); |
651 | } | 651 | } |
652 | } | 652 | } |
653 | out_put_dev: | ||
654 | pci_dev_put(port); | ||
653 | } | 655 | } |
654 | 656 | ||
655 | out_unlock: | 657 | out_unlock: |
diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index c1ca7bcebb66..dd90d15f5210 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c | |||
@@ -26,9 +26,7 @@ | |||
26 | #include <linux/seq_file.h> | 26 | #include <linux/seq_file.h> |
27 | #include <linux/debugfs.h> | 27 | #include <linux/debugfs.h> |
28 | #include <linux/ctype.h> | 28 | #include <linux/ctype.h> |
29 | #ifdef CONFIG_ACPI_VIDEO | ||
30 | #include <acpi/video.h> | 29 | #include <acpi/video.h> |
31 | #endif | ||
32 | 30 | ||
33 | /* | 31 | /* |
34 | * This driver is needed because a number of Samsung laptops do not hook | 32 | * This driver is needed because a number of Samsung laptops do not hook |
@@ -1558,9 +1556,7 @@ static int __init samsung_init(void) | |||
1558 | samsung->handle_backlight = false; | 1556 | samsung->handle_backlight = false; |
1559 | } else if (samsung->quirks->broken_acpi_video) { | 1557 | } else if (samsung->quirks->broken_acpi_video) { |
1560 | pr_info("Disabling ACPI video driver\n"); | 1558 | pr_info("Disabling ACPI video driver\n"); |
1561 | #ifdef CONFIG_ACPI_VIDEO | ||
1562 | acpi_video_unregister(); | 1559 | acpi_video_unregister(); |
1563 | #endif | ||
1564 | } | 1560 | } |
1565 | #endif | 1561 | #endif |
1566 | 1562 | ||
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 80e377949314..52daaa816e53 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -545,7 +545,7 @@ TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY", /* 600e/x, 770e, 770x */ | |||
545 | */ | 545 | */ |
546 | 546 | ||
547 | static int acpi_evalf(acpi_handle handle, | 547 | static int acpi_evalf(acpi_handle handle, |
548 | void *res, char *method, char *fmt, ...) | 548 | int *res, char *method, char *fmt, ...) |
549 | { | 549 | { |
550 | char *fmt0 = fmt; | 550 | char *fmt0 = fmt; |
551 | struct acpi_object_list params; | 551 | struct acpi_object_list params; |
@@ -606,7 +606,7 @@ static int acpi_evalf(acpi_handle handle, | |||
606 | success = (status == AE_OK && | 606 | success = (status == AE_OK && |
607 | out_obj.type == ACPI_TYPE_INTEGER); | 607 | out_obj.type == ACPI_TYPE_INTEGER); |
608 | if (success && res) | 608 | if (success && res) |
609 | *(int *)res = out_obj.integer.value; | 609 | *res = out_obj.integer.value; |
610 | break; | 610 | break; |
611 | case 'v': /* void */ | 611 | case 'v': /* void */ |
612 | success = status == AE_OK; | 612 | success = status == AE_OK; |
@@ -7386,17 +7386,18 @@ static int fan_get_status(u8 *status) | |||
7386 | * Add TPACPI_FAN_RD_ACPI_FANS ? */ | 7386 | * Add TPACPI_FAN_RD_ACPI_FANS ? */ |
7387 | 7387 | ||
7388 | switch (fan_status_access_mode) { | 7388 | switch (fan_status_access_mode) { |
7389 | case TPACPI_FAN_RD_ACPI_GFAN: | 7389 | case TPACPI_FAN_RD_ACPI_GFAN: { |
7390 | /* 570, 600e/x, 770e, 770x */ | 7390 | /* 570, 600e/x, 770e, 770x */ |
7391 | int res; | ||
7391 | 7392 | ||
7392 | if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d"))) | 7393 | if (unlikely(!acpi_evalf(gfan_handle, &res, NULL, "d"))) |
7393 | return -EIO; | 7394 | return -EIO; |
7394 | 7395 | ||
7395 | if (likely(status)) | 7396 | if (likely(status)) |
7396 | *status = s & 0x07; | 7397 | *status = res & 0x07; |
7397 | 7398 | ||
7398 | break; | 7399 | break; |
7399 | 7400 | } | |
7400 | case TPACPI_FAN_RD_TPEC: | 7401 | case TPACPI_FAN_RD_TPEC: |
7401 | /* all except 570, 600e/x, 770e, 770x */ | 7402 | /* all except 570, 600e/x, 770e, 770x */ |
7402 | if (unlikely(!acpi_ec_read(fan_status_offset, &s))) | 7403 | if (unlikely(!acpi_ec_read(fan_status_offset, &s))) |
diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c index 0b66d0f25922..4b6688909fee 100644 --- a/drivers/pwm/pwm-tiecap.c +++ b/drivers/pwm/pwm-tiecap.c | |||
@@ -100,6 +100,13 @@ static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
100 | writel(period_cycles, pc->mmio_base + CAP3); | 100 | writel(period_cycles, pc->mmio_base + CAP3); |
101 | } | 101 | } |
102 | 102 | ||
103 | if (!test_bit(PWMF_ENABLED, &pwm->flags)) { | ||
104 | reg_val = readw(pc->mmio_base + ECCTL2); | ||
105 | /* Disable APWM mode to put APWM output Low */ | ||
106 | reg_val &= ~ECCTL2_APWM_MODE; | ||
107 | writew(reg_val, pc->mmio_base + ECCTL2); | ||
108 | } | ||
109 | |||
103 | pm_runtime_put_sync(pc->chip.dev); | 110 | pm_runtime_put_sync(pc->chip.dev); |
104 | return 0; | 111 | return 0; |
105 | } | 112 | } |
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index c3756d1be194..b1996bcd5b78 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c | |||
@@ -104,6 +104,7 @@ struct ehrpwm_pwm_chip { | |||
104 | struct pwm_chip chip; | 104 | struct pwm_chip chip; |
105 | unsigned int clk_rate; | 105 | unsigned int clk_rate; |
106 | void __iomem *mmio_base; | 106 | void __iomem *mmio_base; |
107 | unsigned long period_cycles[NUM_PWM_CHANNEL]; | ||
107 | }; | 108 | }; |
108 | 109 | ||
109 | static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) | 110 | static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) |
@@ -210,6 +211,7 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
210 | unsigned long long c; | 211 | unsigned long long c; |
211 | unsigned long period_cycles, duty_cycles; | 212 | unsigned long period_cycles, duty_cycles; |
212 | unsigned short ps_divval, tb_divval; | 213 | unsigned short ps_divval, tb_divval; |
214 | int i; | ||
213 | 215 | ||
214 | if (period_ns < 0 || duty_ns < 0 || period_ns > NSEC_PER_SEC) | 216 | if (period_ns < 0 || duty_ns < 0 || period_ns > NSEC_PER_SEC) |
215 | return -ERANGE; | 217 | return -ERANGE; |
@@ -229,6 +231,28 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
229 | duty_cycles = (unsigned long)c; | 231 | duty_cycles = (unsigned long)c; |
230 | } | 232 | } |
231 | 233 | ||
234 | /* | ||
235 | * Period values should be same for multiple PWM channels as IP uses | ||
236 | * same period register for multiple channels. | ||
237 | */ | ||
238 | for (i = 0; i < NUM_PWM_CHANNEL; i++) { | ||
239 | if (pc->period_cycles[i] && | ||
240 | (pc->period_cycles[i] != period_cycles)) { | ||
241 | /* | ||
242 | * Allow channel to reconfigure period if no other | ||
243 | * channels being configured. | ||
244 | */ | ||
245 | if (i == pwm->hwpwm) | ||
246 | continue; | ||
247 | |||
248 | dev_err(chip->dev, "Period value conflicts with channel %d\n", | ||
249 | i); | ||
250 | return -EINVAL; | ||
251 | } | ||
252 | } | ||
253 | |||
254 | pc->period_cycles[pwm->hwpwm] = period_cycles; | ||
255 | |||
232 | /* Configure clock prescaler to support Low frequency PWM wave */ | 256 | /* Configure clock prescaler to support Low frequency PWM wave */ |
233 | if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval, | 257 | if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval, |
234 | &tb_divval)) { | 258 | &tb_divval)) { |
@@ -320,10 +344,15 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) | |||
320 | 344 | ||
321 | static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) | 345 | static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) |
322 | { | 346 | { |
347 | struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); | ||
348 | |||
323 | if (test_bit(PWMF_ENABLED, &pwm->flags)) { | 349 | if (test_bit(PWMF_ENABLED, &pwm->flags)) { |
324 | dev_warn(chip->dev, "Removing PWM device without disabling\n"); | 350 | dev_warn(chip->dev, "Removing PWM device without disabling\n"); |
325 | pm_runtime_put_sync(chip->dev); | 351 | pm_runtime_put_sync(chip->dev); |
326 | } | 352 | } |
353 | |||
354 | /* set period value to zero on free */ | ||
355 | pc->period_cycles[pwm->hwpwm] = 0; | ||
327 | } | 356 | } |
328 | 357 | ||
329 | static const struct pwm_ops ehrpwm_pwm_ops = { | 358 | static const struct pwm_ops ehrpwm_pwm_ops = { |
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 6caa222af77a..ab00cab905b7 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/err.h> | 22 | #include <linux/err.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | 24 | ||
25 | #include <linux/regulator/of_regulator.h> | ||
25 | #include <linux/regulator/driver.h> | 26 | #include <linux/regulator/driver.h> |
26 | #include <linux/regulator/machine.h> | 27 | #include <linux/regulator/machine.h> |
27 | #include <linux/mfd/tps65217.h> | 28 | #include <linux/mfd/tps65217.h> |
@@ -281,37 +282,130 @@ static const struct regulator_desc regulators[] = { | |||
281 | NULL), | 282 | NULL), |
282 | }; | 283 | }; |
283 | 284 | ||
285 | #ifdef CONFIG_OF | ||
286 | static struct of_regulator_match reg_matches[] = { | ||
287 | { .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 }, | ||
288 | { .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 }, | ||
289 | { .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 }, | ||
290 | { .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 }, | ||
291 | { .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 }, | ||
292 | { .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 }, | ||
293 | { .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 }, | ||
294 | }; | ||
295 | |||
296 | static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) | ||
297 | { | ||
298 | struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); | ||
299 | struct device_node *node = tps->dev->of_node; | ||
300 | struct tps65217_board *pdata; | ||
301 | struct device_node *regs; | ||
302 | int i, count; | ||
303 | |||
304 | regs = of_find_node_by_name(node, "regulators"); | ||
305 | if (!regs) | ||
306 | return NULL; | ||
307 | |||
308 | count = of_regulator_match(pdev->dev.parent, regs, | ||
309 | reg_matches, TPS65217_NUM_REGULATOR); | ||
310 | of_node_put(regs); | ||
311 | if ((count < 0) || (count > TPS65217_NUM_REGULATOR)) | ||
312 | return NULL; | ||
313 | |||
314 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
315 | if (!pdata) | ||
316 | return NULL; | ||
317 | |||
318 | for (i = 0; i < count; i++) { | ||
319 | if (!reg_matches[i].init_data || !reg_matches[i].of_node) | ||
320 | continue; | ||
321 | |||
322 | pdata->tps65217_init_data[i] = reg_matches[i].init_data; | ||
323 | pdata->of_node[i] = reg_matches[i].of_node; | ||
324 | } | ||
325 | |||
326 | return pdata; | ||
327 | } | ||
328 | #else | ||
329 | static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) | ||
330 | { | ||
331 | return NULL; | ||
332 | } | ||
333 | #endif | ||
334 | |||
284 | static int __devinit tps65217_regulator_probe(struct platform_device *pdev) | 335 | static int __devinit tps65217_regulator_probe(struct platform_device *pdev) |
285 | { | 336 | { |
337 | struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); | ||
338 | struct tps65217_board *pdata = dev_get_platdata(tps->dev); | ||
339 | struct regulator_init_data *reg_data; | ||
286 | struct regulator_dev *rdev; | 340 | struct regulator_dev *rdev; |
287 | struct tps65217 *tps; | ||
288 | struct tps_info *info = &tps65217_pmic_regs[pdev->id]; | ||
289 | struct regulator_config config = { }; | 341 | struct regulator_config config = { }; |
342 | int i, ret; | ||
290 | 343 | ||
291 | /* Already set by core driver */ | 344 | if (tps->dev->of_node) |
292 | tps = dev_to_tps65217(pdev->dev.parent); | 345 | pdata = tps65217_parse_dt(pdev); |
293 | tps->info[pdev->id] = info; | ||
294 | 346 | ||
295 | config.dev = &pdev->dev; | 347 | if (!pdata) { |
296 | config.of_node = pdev->dev.of_node; | 348 | dev_err(&pdev->dev, "Platform data not found\n"); |
297 | config.init_data = pdev->dev.platform_data; | 349 | return -EINVAL; |
298 | config.driver_data = tps; | 350 | } |
299 | 351 | ||
300 | rdev = regulator_register(®ulators[pdev->id], &config); | 352 | if (tps65217_chip_id(tps) != TPS65217) { |
301 | if (IS_ERR(rdev)) | 353 | dev_err(&pdev->dev, "Invalid tps chip version\n"); |
302 | return PTR_ERR(rdev); | 354 | return -ENODEV; |
355 | } | ||
303 | 356 | ||
304 | platform_set_drvdata(pdev, rdev); | 357 | platform_set_drvdata(pdev, tps); |
305 | 358 | ||
359 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { | ||
360 | |||
361 | reg_data = pdata->tps65217_init_data[i]; | ||
362 | |||
363 | /* | ||
364 | * Regulator API handles empty constraints but not NULL | ||
365 | * constraints | ||
366 | */ | ||
367 | if (!reg_data) | ||
368 | continue; | ||
369 | |||
370 | /* Register the regulators */ | ||
371 | tps->info[i] = &tps65217_pmic_regs[i]; | ||
372 | |||
373 | config.dev = tps->dev; | ||
374 | config.init_data = reg_data; | ||
375 | config.driver_data = tps; | ||
376 | config.regmap = tps->regmap; | ||
377 | if (tps->dev->of_node) | ||
378 | config.of_node = pdata->of_node[i]; | ||
379 | |||
380 | rdev = regulator_register(®ulators[i], &config); | ||
381 | if (IS_ERR(rdev)) { | ||
382 | dev_err(tps->dev, "failed to register %s regulator\n", | ||
383 | pdev->name); | ||
384 | ret = PTR_ERR(rdev); | ||
385 | goto err_unregister_regulator; | ||
386 | } | ||
387 | |||
388 | /* Save regulator for cleanup */ | ||
389 | tps->rdev[i] = rdev; | ||
390 | } | ||
306 | return 0; | 391 | return 0; |
392 | |||
393 | err_unregister_regulator: | ||
394 | while (--i >= 0) | ||
395 | regulator_unregister(tps->rdev[i]); | ||
396 | |||
397 | return ret; | ||
307 | } | 398 | } |
308 | 399 | ||
309 | static int __devexit tps65217_regulator_remove(struct platform_device *pdev) | 400 | static int __devexit tps65217_regulator_remove(struct platform_device *pdev) |
310 | { | 401 | { |
311 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | 402 | struct tps65217 *tps = platform_get_drvdata(pdev); |
403 | unsigned int i; | ||
404 | |||
405 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) | ||
406 | regulator_unregister(tps->rdev[i]); | ||
312 | 407 | ||
313 | platform_set_drvdata(pdev, NULL); | 408 | platform_set_drvdata(pdev, NULL); |
314 | regulator_unregister(rdev); | ||
315 | 409 | ||
316 | return 0; | 410 | return 0; |
317 | } | 411 | } |
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 831868904e02..1dd61f402b04 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c | |||
@@ -58,6 +58,7 @@ struct sam9_rtc { | |||
58 | struct rtc_device *rtcdev; | 58 | struct rtc_device *rtcdev; |
59 | u32 imr; | 59 | u32 imr; |
60 | void __iomem *gpbr; | 60 | void __iomem *gpbr; |
61 | int irq; | ||
61 | }; | 62 | }; |
62 | 63 | ||
63 | #define rtt_readl(rtc, field) \ | 64 | #define rtt_readl(rtc, field) \ |
@@ -292,7 +293,7 @@ static int __devinit at91_rtc_probe(struct platform_device *pdev) | |||
292 | { | 293 | { |
293 | struct resource *r, *r_gpbr; | 294 | struct resource *r, *r_gpbr; |
294 | struct sam9_rtc *rtc; | 295 | struct sam9_rtc *rtc; |
295 | int ret; | 296 | int ret, irq; |
296 | u32 mr; | 297 | u32 mr; |
297 | 298 | ||
298 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 299 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -302,10 +303,18 @@ static int __devinit at91_rtc_probe(struct platform_device *pdev) | |||
302 | return -ENODEV; | 303 | return -ENODEV; |
303 | } | 304 | } |
304 | 305 | ||
306 | irq = platform_get_irq(pdev, 0); | ||
307 | if (irq < 0) { | ||
308 | dev_err(&pdev->dev, "failed to get interrupt resource\n"); | ||
309 | return irq; | ||
310 | } | ||
311 | |||
305 | rtc = kzalloc(sizeof *rtc, GFP_KERNEL); | 312 | rtc = kzalloc(sizeof *rtc, GFP_KERNEL); |
306 | if (!rtc) | 313 | if (!rtc) |
307 | return -ENOMEM; | 314 | return -ENOMEM; |
308 | 315 | ||
316 | rtc->irq = irq; | ||
317 | |||
309 | /* platform setup code should have handled this; sigh */ | 318 | /* platform setup code should have handled this; sigh */ |
310 | if (!device_can_wakeup(&pdev->dev)) | 319 | if (!device_can_wakeup(&pdev->dev)) |
311 | device_init_wakeup(&pdev->dev, 1); | 320 | device_init_wakeup(&pdev->dev, 1); |
@@ -345,11 +354,10 @@ static int __devinit at91_rtc_probe(struct platform_device *pdev) | |||
345 | } | 354 | } |
346 | 355 | ||
347 | /* register irq handler after we know what name we'll use */ | 356 | /* register irq handler after we know what name we'll use */ |
348 | ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, | 357 | ret = request_irq(rtc->irq, at91_rtc_interrupt, IRQF_SHARED, |
349 | IRQF_SHARED, | ||
350 | dev_name(&rtc->rtcdev->dev), rtc); | 358 | dev_name(&rtc->rtcdev->dev), rtc); |
351 | if (ret) { | 359 | if (ret) { |
352 | dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS); | 360 | dev_dbg(&pdev->dev, "can't share IRQ %d?\n", rtc->irq); |
353 | rtc_device_unregister(rtc->rtcdev); | 361 | rtc_device_unregister(rtc->rtcdev); |
354 | goto fail_register; | 362 | goto fail_register; |
355 | } | 363 | } |
@@ -386,7 +394,7 @@ static int __devexit at91_rtc_remove(struct platform_device *pdev) | |||
386 | 394 | ||
387 | /* disable all interrupts */ | 395 | /* disable all interrupts */ |
388 | rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); | 396 | rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); |
389 | free_irq(AT91_ID_SYS, rtc); | 397 | free_irq(rtc->irq, rtc); |
390 | 398 | ||
391 | rtc_device_unregister(rtc->rtcdev); | 399 | rtc_device_unregister(rtc->rtcdev); |
392 | 400 | ||
@@ -423,7 +431,7 @@ static int at91_rtc_suspend(struct platform_device *pdev, | |||
423 | rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); | 431 | rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); |
424 | if (rtc->imr) { | 432 | if (rtc->imr) { |
425 | if (device_may_wakeup(&pdev->dev) && (mr & AT91_RTT_ALMIEN)) { | 433 | if (device_may_wakeup(&pdev->dev) && (mr & AT91_RTT_ALMIEN)) { |
426 | enable_irq_wake(AT91_ID_SYS); | 434 | enable_irq_wake(rtc->irq); |
427 | /* don't let RTTINC cause wakeups */ | 435 | /* don't let RTTINC cause wakeups */ |
428 | if (mr & AT91_RTT_RTTINCIEN) | 436 | if (mr & AT91_RTT_RTTINCIEN) |
429 | rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); | 437 | rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); |
@@ -441,7 +449,7 @@ static int at91_rtc_resume(struct platform_device *pdev) | |||
441 | 449 | ||
442 | if (rtc->imr) { | 450 | if (rtc->imr) { |
443 | if (device_may_wakeup(&pdev->dev)) | 451 | if (device_may_wakeup(&pdev->dev)) |
444 | disable_irq_wake(AT91_ID_SYS); | 452 | disable_irq_wake(rtc->irq); |
445 | mr = rtt_readl(rtc, MR); | 453 | mr = rtt_readl(rtc, MR); |
446 | rtt_writel(rtc, MR, mr | rtc->imr); | 454 | rtt_writel(rtc, MR, mr | rtc->imr); |
447 | } | 455 | } |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 40a826a7295f..2fb2b9ea97ec 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -3804,7 +3804,7 @@ dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp) | |||
3804 | case BIODASDSYMMIO: | 3804 | case BIODASDSYMMIO: |
3805 | return dasd_symm_io(device, argp); | 3805 | return dasd_symm_io(device, argp); |
3806 | default: | 3806 | default: |
3807 | return -ENOIOCTLCMD; | 3807 | return -ENOTTY; |
3808 | } | 3808 | } |
3809 | } | 3809 | } |
3810 | 3810 | ||
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index cceae70279f6..654c6921a6d4 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -498,12 +498,9 @@ int dasd_ioctl(struct block_device *bdev, fmode_t mode, | |||
498 | break; | 498 | break; |
499 | default: | 499 | default: |
500 | /* if the discipline has an ioctl method try it. */ | 500 | /* if the discipline has an ioctl method try it. */ |
501 | if (base->discipline->ioctl) { | 501 | rc = -ENOTTY; |
502 | if (base->discipline->ioctl) | ||
502 | rc = base->discipline->ioctl(block, cmd, argp); | 503 | rc = base->discipline->ioctl(block, cmd, argp); |
503 | if (rc == -ENOIOCTLCMD) | ||
504 | rc = -EINVAL; | ||
505 | } else | ||
506 | rc = -EINVAL; | ||
507 | } | 504 | } |
508 | dasd_put_device(base); | 505 | dasd_put_device(base); |
509 | return rc; | 506 | return rc; |
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index dc27598785e5..ed38454228c6 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c | |||
@@ -4066,7 +4066,6 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
4066 | spin_lock_init(&instance->cmd_pool_lock); | 4066 | spin_lock_init(&instance->cmd_pool_lock); |
4067 | spin_lock_init(&instance->hba_lock); | 4067 | spin_lock_init(&instance->hba_lock); |
4068 | spin_lock_init(&instance->completion_lock); | 4068 | spin_lock_init(&instance->completion_lock); |
4069 | spin_lock_init(&poll_aen_lock); | ||
4070 | 4069 | ||
4071 | mutex_init(&instance->aen_mutex); | 4070 | mutex_init(&instance->aen_mutex); |
4072 | mutex_init(&instance->reset_mutex); | 4071 | mutex_init(&instance->reset_mutex); |
@@ -5392,6 +5391,8 @@ static int __init megasas_init(void) | |||
5392 | printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION, | 5391 | printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION, |
5393 | MEGASAS_EXT_VERSION); | 5392 | MEGASAS_EXT_VERSION); |
5394 | 5393 | ||
5394 | spin_lock_init(&poll_aen_lock); | ||
5395 | |||
5395 | support_poll_for_event = 2; | 5396 | support_poll_for_event = 2; |
5396 | support_device_change = 1; | 5397 | support_device_change = 1; |
5397 | 5398 | ||
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 9d46fcbe7755..b25757d1e91b 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -2424,10 +2424,13 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2424 | } | 2424 | } |
2425 | 2425 | ||
2426 | /* command line tunables for max controller queue depth */ | 2426 | /* command line tunables for max controller queue depth */ |
2427 | if (max_queue_depth != -1) | 2427 | if (max_queue_depth != -1 && max_queue_depth != 0) { |
2428 | max_request_credit = (max_queue_depth < facts->RequestCredit) | 2428 | max_request_credit = min_t(u16, max_queue_depth + |
2429 | ? max_queue_depth : facts->RequestCredit; | 2429 | ioc->hi_priority_depth + ioc->internal_depth, |
2430 | else | 2430 | facts->RequestCredit); |
2431 | if (max_request_credit > MAX_HBA_QUEUE_DEPTH) | ||
2432 | max_request_credit = MAX_HBA_QUEUE_DEPTH; | ||
2433 | } else | ||
2431 | max_request_credit = min_t(u16, facts->RequestCredit, | 2434 | max_request_credit = min_t(u16, facts->RequestCredit, |
2432 | MAX_HBA_QUEUE_DEPTH); | 2435 | MAX_HBA_QUEUE_DEPTH); |
2433 | 2436 | ||
@@ -2502,7 +2505,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2502 | /* set the scsi host can_queue depth | 2505 | /* set the scsi host can_queue depth |
2503 | * with some internal commands that could be outstanding | 2506 | * with some internal commands that could be outstanding |
2504 | */ | 2507 | */ |
2505 | ioc->shost->can_queue = ioc->scsiio_depth - (2); | 2508 | ioc->shost->can_queue = ioc->scsiio_depth; |
2506 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host: " | 2509 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host: " |
2507 | "can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue)); | 2510 | "can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue)); |
2508 | 2511 | ||
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 4a6381c87253..de2337f255a7 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -42,6 +42,8 @@ | |||
42 | 42 | ||
43 | #include <trace/events/scsi.h> | 43 | #include <trace/events/scsi.h> |
44 | 44 | ||
45 | static void scsi_eh_done(struct scsi_cmnd *scmd); | ||
46 | |||
45 | #define SENSE_TIMEOUT (10*HZ) | 47 | #define SENSE_TIMEOUT (10*HZ) |
46 | 48 | ||
47 | /* | 49 | /* |
@@ -241,6 +243,14 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) | |||
241 | if (! scsi_command_normalize_sense(scmd, &sshdr)) | 243 | if (! scsi_command_normalize_sense(scmd, &sshdr)) |
242 | return FAILED; /* no valid sense data */ | 244 | return FAILED; /* no valid sense data */ |
243 | 245 | ||
246 | if (scmd->cmnd[0] == TEST_UNIT_READY && scmd->scsi_done != scsi_eh_done) | ||
247 | /* | ||
248 | * nasty: for mid-layer issued TURs, we need to return the | ||
249 | * actual sense data without any recovery attempt. For eh | ||
250 | * issued ones, we need to try to recover and interpret | ||
251 | */ | ||
252 | return SUCCESS; | ||
253 | |||
244 | if (scsi_sense_is_deferred(&sshdr)) | 254 | if (scsi_sense_is_deferred(&sshdr)) |
245 | return NEEDS_RETRY; | 255 | return NEEDS_RETRY; |
246 | 256 | ||
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ffd77739ae3e..faa790fba134 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -776,7 +776,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
776 | } | 776 | } |
777 | 777 | ||
778 | if (req->cmd_type == REQ_TYPE_BLOCK_PC) { /* SG_IO ioctl from block level */ | 778 | if (req->cmd_type == REQ_TYPE_BLOCK_PC) { /* SG_IO ioctl from block level */ |
779 | req->errors = result; | ||
780 | if (result) { | 779 | if (result) { |
781 | if (sense_valid && req->sense) { | 780 | if (sense_valid && req->sense) { |
782 | /* | 781 | /* |
@@ -792,6 +791,10 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
792 | if (!sense_deferred) | 791 | if (!sense_deferred) |
793 | error = __scsi_error_from_host_byte(cmd, result); | 792 | error = __scsi_error_from_host_byte(cmd, result); |
794 | } | 793 | } |
794 | /* | ||
795 | * __scsi_error_from_host_byte may have reset the host_byte | ||
796 | */ | ||
797 | req->errors = cmd->result; | ||
795 | 798 | ||
796 | req->resid_len = scsi_get_resid(cmd); | 799 | req->resid_len = scsi_get_resid(cmd); |
797 | 800 | ||
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 56a93794c470..d947ffc20ceb 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -764,6 +764,16 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, | |||
764 | sdev->model = (char *) (sdev->inquiry + 16); | 764 | sdev->model = (char *) (sdev->inquiry + 16); |
765 | sdev->rev = (char *) (sdev->inquiry + 32); | 765 | sdev->rev = (char *) (sdev->inquiry + 32); |
766 | 766 | ||
767 | if (strncmp(sdev->vendor, "ATA ", 8) == 0) { | ||
768 | /* | ||
769 | * sata emulation layer device. This is a hack to work around | ||
770 | * the SATL power management specifications which state that | ||
771 | * when the SATL detects the device has gone into standby | ||
772 | * mode, it shall respond with NOT READY. | ||
773 | */ | ||
774 | sdev->allow_restart = 1; | ||
775 | } | ||
776 | |||
767 | if (*bflags & BLIST_ISROM) { | 777 | if (*bflags & BLIST_ISROM) { |
768 | sdev->type = TYPE_ROM; | 778 | sdev->type = TYPE_ROM; |
769 | sdev->removable = 1; | 779 | sdev->removable = 1; |
diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index d0cafd637199..f2ffd963f1c3 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h | |||
@@ -51,10 +51,12 @@ enum android_alarm_return_flags { | |||
51 | #define ANDROID_ALARM_WAIT _IO('a', 1) | 51 | #define ANDROID_ALARM_WAIT _IO('a', 1) |
52 | 52 | ||
53 | #define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) | 53 | #define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) |
54 | #define ALARM_IOR(c, type, size) _IOR('a', (c) | ((type) << 4), size) | ||
55 | |||
54 | /* Set alarm */ | 56 | /* Set alarm */ |
55 | #define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) | 57 | #define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) |
56 | #define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) | 58 | #define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) |
57 | #define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec) | 59 | #define ANDROID_ALARM_GET_TIME(type) ALARM_IOR(4, type, struct timespec) |
58 | #define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) | 60 | #define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) |
59 | #define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) | 61 | #define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) |
60 | #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) | 62 | #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) |
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 6c81e377262c..cc8931fde839 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c | |||
@@ -1412,6 +1412,13 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, | |||
1412 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); | 1412 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); |
1413 | return -EINVAL; | 1413 | return -EINVAL; |
1414 | } | 1414 | } |
1415 | /* | ||
1416 | * Need to 'get' the PCI device to match the 'put' in dio200_detach(). | ||
1417 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
1418 | * support for manual attachment of PCI devices via dio200_attach() | ||
1419 | * has been removed. | ||
1420 | */ | ||
1421 | pci_dev_get(pci_dev); | ||
1415 | return dio200_pci_common_attach(dev, pci_dev); | 1422 | return dio200_pci_common_attach(dev, pci_dev); |
1416 | } | 1423 | } |
1417 | 1424 | ||
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index aabba9886b7d..f50287903038 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c | |||
@@ -565,6 +565,13 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev, | |||
565 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); | 565 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); |
566 | return -EINVAL; | 566 | return -EINVAL; |
567 | } | 567 | } |
568 | /* | ||
569 | * Need to 'get' the PCI device to match the 'put' in pc236_detach(). | ||
570 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
571 | * support for manual attachment of PCI devices via pc236_attach() | ||
572 | * has been removed. | ||
573 | */ | ||
574 | pci_dev_get(pci_dev); | ||
568 | return pc236_pci_common_attach(dev, pci_dev); | 575 | return pc236_pci_common_attach(dev, pci_dev); |
569 | } | 576 | } |
570 | 577 | ||
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 40ec1ffebba6..8191c4e28e0a 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c | |||
@@ -298,6 +298,13 @@ static int __devinit pc263_attach_pci(struct comedi_device *dev, | |||
298 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); | 298 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); |
299 | return -EINVAL; | 299 | return -EINVAL; |
300 | } | 300 | } |
301 | /* | ||
302 | * Need to 'get' the PCI device to match the 'put' in pc263_detach(). | ||
303 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
304 | * support for manual attachment of PCI devices via pc263_attach() | ||
305 | * has been removed. | ||
306 | */ | ||
307 | pci_dev_get(pci_dev); | ||
301 | return pc263_pci_common_attach(dev, pci_dev); | 308 | return pc263_pci_common_attach(dev, pci_dev); |
302 | } | 309 | } |
303 | 310 | ||
diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 4e17f13e57f6..8bf109e7bb05 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c | |||
@@ -1503,6 +1503,13 @@ pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) | |||
1503 | DRIVER_NAME ": BUG! cannot determine board type!\n"); | 1503 | DRIVER_NAME ": BUG! cannot determine board type!\n"); |
1504 | return -EINVAL; | 1504 | return -EINVAL; |
1505 | } | 1505 | } |
1506 | /* | ||
1507 | * Need to 'get' the PCI device to match the 'put' in pci224_detach(). | ||
1508 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
1509 | * support for manual attachment of PCI devices via pci224_attach() | ||
1510 | * has been removed. | ||
1511 | */ | ||
1512 | pci_dev_get(pci_dev); | ||
1506 | return pci224_attach_common(dev, pci_dev, NULL); | 1513 | return pci224_attach_common(dev, pci_dev, NULL); |
1507 | } | 1514 | } |
1508 | 1515 | ||
diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 1b67d0c61fa7..66e74bd12267 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c | |||
@@ -2925,6 +2925,13 @@ static int __devinit pci230_attach_pci(struct comedi_device *dev, | |||
2925 | "amplc_pci230: BUG! cannot determine board type!\n"); | 2925 | "amplc_pci230: BUG! cannot determine board type!\n"); |
2926 | return -EINVAL; | 2926 | return -EINVAL; |
2927 | } | 2927 | } |
2928 | /* | ||
2929 | * Need to 'get' the PCI device to match the 'put' in pci230_detach(). | ||
2930 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
2931 | * support for manual attachment of PCI devices via pci230_attach() | ||
2932 | * has been removed. | ||
2933 | */ | ||
2934 | pci_dev_get(pci_dev); | ||
2928 | return pci230_attach_common(dev, pci_dev); | 2935 | return pci230_attach_common(dev, pci_dev); |
2929 | } | 2936 | } |
2930 | 2937 | ||
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 874e02e47668..67a914a10b55 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c | |||
@@ -378,7 +378,7 @@ das08jr_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, | |||
378 | int chan; | 378 | int chan; |
379 | 379 | ||
380 | lsb = data[0] & 0xff; | 380 | lsb = data[0] & 0xff; |
381 | msb = (data[0] >> 8) & 0xf; | 381 | msb = (data[0] >> 8) & 0xff; |
382 | 382 | ||
383 | chan = CR_CHAN(insn->chanspec); | 383 | chan = CR_CHAN(insn->chanspec); |
384 | 384 | ||
@@ -623,7 +623,7 @@ static const struct das08_board_struct das08_boards[] = { | |||
623 | .ai = das08_ai_rinsn, | 623 | .ai = das08_ai_rinsn, |
624 | .ai_nbits = 16, | 624 | .ai_nbits = 16, |
625 | .ai_pg = das08_pg_none, | 625 | .ai_pg = das08_pg_none, |
626 | .ai_encoding = das08_encode12, | 626 | .ai_encoding = das08_encode16, |
627 | .ao = das08jr_ao_winsn, | 627 | .ao = das08jr_ao_winsn, |
628 | .ao_nbits = 16, | 628 | .ao_nbits = 16, |
629 | .di = das08jr_di_rbits, | 629 | .di = das08jr_di_rbits, |
@@ -922,6 +922,13 @@ das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) | |||
922 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); | 922 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); |
923 | return -EINVAL; | 923 | return -EINVAL; |
924 | } | 924 | } |
925 | /* | ||
926 | * Need to 'get' the PCI device to match the 'put' in das08_detach(). | ||
927 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
928 | * support for manual attachment of PCI devices via das08_attach() | ||
929 | * has been removed. | ||
930 | */ | ||
931 | pci_dev_get(pdev); | ||
925 | return das08_pci_attach_common(dev, pdev); | 932 | return das08_pci_attach_common(dev, pdev); |
926 | } | 933 | } |
927 | 934 | ||
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 18d108fd967a..f3da59063ed2 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c | |||
@@ -121,8 +121,10 @@ static int lis3l02dq_get_buffer_element(struct iio_dev *indio_dev, | |||
121 | if (rx_array == NULL) | 121 | if (rx_array == NULL) |
122 | return -ENOMEM; | 122 | return -ENOMEM; |
123 | ret = lis3l02dq_read_all(indio_dev, rx_array); | 123 | ret = lis3l02dq_read_all(indio_dev, rx_array); |
124 | if (ret < 0) | 124 | if (ret < 0) { |
125 | kfree(rx_array); | ||
125 | return ret; | 126 | return ret; |
127 | } | ||
126 | for (i = 0; i < scan_count; i++) | 128 | for (i = 0; i < scan_count; i++) |
127 | data[i] = combine_8_to_16(rx_array[i*4+1], | 129 | data[i] = combine_8_to_16(rx_array[i*4+1], |
128 | rx_array[i*4+3]); | 130 | rx_array[i*4+3]); |
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 095837285f4f..19a064d649e3 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c | |||
@@ -647,6 +647,8 @@ static ssize_t ad7192_write_frequency(struct device *dev, | |||
647 | ret = strict_strtoul(buf, 10, &lval); | 647 | ret = strict_strtoul(buf, 10, &lval); |
648 | if (ret) | 648 | if (ret) |
649 | return ret; | 649 | return ret; |
650 | if (lval == 0) | ||
651 | return -EINVAL; | ||
650 | 652 | ||
651 | mutex_lock(&indio_dev->mlock); | 653 | mutex_lock(&indio_dev->mlock); |
652 | if (iio_buffer_enabled(indio_dev)) { | 654 | if (iio_buffer_enabled(indio_dev)) { |
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 93aa431287ac..eb8e9d69efd3 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c | |||
@@ -195,6 +195,8 @@ static ssize_t adis16260_write_frequency(struct device *dev, | |||
195 | ret = strict_strtol(buf, 10, &val); | 195 | ret = strict_strtol(buf, 10, &val); |
196 | if (ret) | 196 | if (ret) |
197 | return ret; | 197 | return ret; |
198 | if (val == 0) | ||
199 | return -EINVAL; | ||
198 | 200 | ||
199 | mutex_lock(&indio_dev->mlock); | 201 | mutex_lock(&indio_dev->mlock); |
200 | if (spi_get_device_id(st->us)) { | 202 | if (spi_get_device_id(st->us)) { |
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 1f4c17779b5a..a618327e06ed 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c | |||
@@ -234,6 +234,8 @@ static ssize_t adis16400_write_frequency(struct device *dev, | |||
234 | ret = strict_strtol(buf, 10, &val); | 234 | ret = strict_strtol(buf, 10, &val); |
235 | if (ret) | 235 | if (ret) |
236 | return ret; | 236 | return ret; |
237 | if (val == 0) | ||
238 | return -EINVAL; | ||
237 | 239 | ||
238 | mutex_lock(&indio_dev->mlock); | 240 | mutex_lock(&indio_dev->mlock); |
239 | 241 | ||
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index f04ece7fbc2f..3ccff189f258 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c | |||
@@ -425,6 +425,8 @@ static ssize_t ade7753_write_frequency(struct device *dev, | |||
425 | ret = strict_strtol(buf, 10, &val); | 425 | ret = strict_strtol(buf, 10, &val); |
426 | if (ret) | 426 | if (ret) |
427 | return ret; | 427 | return ret; |
428 | if (val == 0) | ||
429 | return -EINVAL; | ||
428 | 430 | ||
429 | mutex_lock(&indio_dev->mlock); | 431 | mutex_lock(&indio_dev->mlock); |
430 | 432 | ||
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 6cee28a5e877..abb1e9c8d094 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c | |||
@@ -445,6 +445,8 @@ static ssize_t ade7754_write_frequency(struct device *dev, | |||
445 | ret = strict_strtol(buf, 10, &val); | 445 | ret = strict_strtol(buf, 10, &val); |
446 | if (ret) | 446 | if (ret) |
447 | return ret; | 447 | return ret; |
448 | if (val == 0) | ||
449 | return -EINVAL; | ||
448 | 450 | ||
449 | mutex_lock(&indio_dev->mlock); | 451 | mutex_lock(&indio_dev->mlock); |
450 | 452 | ||
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index b3f7e0fa9612..eb0a2a98f388 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c | |||
@@ -385,6 +385,8 @@ static ssize_t ade7759_write_frequency(struct device *dev, | |||
385 | ret = strict_strtol(buf, 10, &val); | 385 | ret = strict_strtol(buf, 10, &val); |
386 | if (ret) | 386 | if (ret) |
387 | return ret; | 387 | return ret; |
388 | if (val == 0) | ||
389 | return -EINVAL; | ||
388 | 390 | ||
389 | mutex_lock(&indio_dev->mlock); | 391 | mutex_lock(&indio_dev->mlock); |
390 | 392 | ||
diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 695ea35f75b0..d0a7e408efe9 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c | |||
@@ -837,7 +837,7 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) | |||
837 | } | 837 | } |
838 | 838 | ||
839 | ret = mfd_add_devices(nvec->dev, -1, nvec_devices, | 839 | ret = mfd_add_devices(nvec->dev, -1, nvec_devices, |
840 | ARRAY_SIZE(nvec_devices), base, 0); | 840 | ARRAY_SIZE(nvec_devices), base, 0, NULL); |
841 | if (ret) | 841 | if (ret) |
842 | dev_err(nvec->dev, "error adding subdevices\n"); | 842 | dev_err(nvec->dev, "error adding subdevices\n"); |
843 | 843 | ||
diff --git a/drivers/staging/omapdrm/omap_connector.c b/drivers/staging/omapdrm/omap_connector.c index 5e2856c0e0bb..55e9c8655850 100644 --- a/drivers/staging/omapdrm/omap_connector.c +++ b/drivers/staging/omapdrm/omap_connector.c | |||
@@ -48,13 +48,20 @@ static inline void copy_timings_omap_to_drm(struct drm_display_mode *mode, | |||
48 | mode->vsync_end = mode->vsync_start + timings->vsw; | 48 | mode->vsync_end = mode->vsync_start + timings->vsw; |
49 | mode->vtotal = mode->vsync_end + timings->vbp; | 49 | mode->vtotal = mode->vsync_end + timings->vbp; |
50 | 50 | ||
51 | /* note: whether or not it is interlaced, +/- h/vsync, etc, | 51 | mode->flags = 0; |
52 | * which should be set in the mode flags, is not exposed in | 52 | |
53 | * the omap_video_timings struct.. but hdmi driver tracks | 53 | if (timings->interlace) |
54 | * those separately so all we have to have to set the mode | 54 | mode->flags |= DRM_MODE_FLAG_INTERLACE; |
55 | * is the way to recover these timings values, and the | 55 | |
56 | * omap_dss_driver would do the rest. | 56 | if (timings->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH) |
57 | */ | 57 | mode->flags |= DRM_MODE_FLAG_PHSYNC; |
58 | else | ||
59 | mode->flags |= DRM_MODE_FLAG_NHSYNC; | ||
60 | |||
61 | if (timings->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH) | ||
62 | mode->flags |= DRM_MODE_FLAG_PVSYNC; | ||
63 | else | ||
64 | mode->flags |= DRM_MODE_FLAG_NVSYNC; | ||
58 | } | 65 | } |
59 | 66 | ||
60 | static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings, | 67 | static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings, |
@@ -71,6 +78,22 @@ static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings, | |||
71 | timings->vfp = mode->vsync_start - mode->vdisplay; | 78 | timings->vfp = mode->vsync_start - mode->vdisplay; |
72 | timings->vsw = mode->vsync_end - mode->vsync_start; | 79 | timings->vsw = mode->vsync_end - mode->vsync_start; |
73 | timings->vbp = mode->vtotal - mode->vsync_end; | 80 | timings->vbp = mode->vtotal - mode->vsync_end; |
81 | |||
82 | timings->interlace = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); | ||
83 | |||
84 | if (mode->flags & DRM_MODE_FLAG_PHSYNC) | ||
85 | timings->hsync_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
86 | else | ||
87 | timings->hsync_level = OMAPDSS_SIG_ACTIVE_LOW; | ||
88 | |||
89 | if (mode->flags & DRM_MODE_FLAG_PVSYNC) | ||
90 | timings->vsync_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
91 | else | ||
92 | timings->vsync_level = OMAPDSS_SIG_ACTIVE_LOW; | ||
93 | |||
94 | timings->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; | ||
95 | timings->de_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
96 | timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; | ||
74 | } | 97 | } |
75 | 98 | ||
76 | static void omap_connector_dpms(struct drm_connector *connector, int mode) | 99 | static void omap_connector_dpms(struct drm_connector *connector, int mode) |
@@ -187,7 +210,7 @@ static int omap_connector_get_modes(struct drm_connector *connector) | |||
187 | } | 210 | } |
188 | } else { | 211 | } else { |
189 | struct drm_display_mode *mode = drm_mode_create(dev); | 212 | struct drm_display_mode *mode = drm_mode_create(dev); |
190 | struct omap_video_timings timings; | 213 | struct omap_video_timings timings = {0}; |
191 | 214 | ||
192 | dssdrv->get_timings(dssdev, &timings); | 215 | dssdrv->get_timings(dssdev, &timings); |
193 | 216 | ||
@@ -291,7 +314,7 @@ void omap_connector_mode_set(struct drm_connector *connector, | |||
291 | struct omap_connector *omap_connector = to_omap_connector(connector); | 314 | struct omap_connector *omap_connector = to_omap_connector(connector); |
292 | struct omap_dss_device *dssdev = omap_connector->dssdev; | 315 | struct omap_dss_device *dssdev = omap_connector->dssdev; |
293 | struct omap_dss_driver *dssdrv = dssdev->driver; | 316 | struct omap_dss_driver *dssdrv = dssdev->driver; |
294 | struct omap_video_timings timings; | 317 | struct omap_video_timings timings = {0}; |
295 | 318 | ||
296 | copy_timings_drm_to_omap(&timings, mode); | 319 | copy_timings_drm_to_omap(&timings, mode); |
297 | 320 | ||
diff --git a/drivers/staging/ozwpan/ozcdev.c b/drivers/staging/ozwpan/ozcdev.c index d98321945802..758ce0a8d82e 100644 --- a/drivers/staging/ozwpan/ozcdev.c +++ b/drivers/staging/ozwpan/ozcdev.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/cdev.h> | 8 | #include <linux/cdev.h> |
9 | #include <linux/uaccess.h> | 9 | #include <linux/uaccess.h> |
10 | #include <linux/netdevice.h> | 10 | #include <linux/netdevice.h> |
11 | #include <linux/etherdevice.h> | ||
11 | #include <linux/poll.h> | 12 | #include <linux/poll.h> |
12 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
13 | #include "ozconfig.h" | 14 | #include "ozconfig.h" |
@@ -213,7 +214,7 @@ static int oz_set_active_pd(u8 *addr) | |||
213 | if (old_pd) | 214 | if (old_pd) |
214 | oz_pd_put(old_pd); | 215 | oz_pd_put(old_pd); |
215 | } else { | 216 | } else { |
216 | if (!memcmp(addr, "\0\0\0\0\0\0", sizeof(addr))) { | 217 | if (is_zero_ether_addr(addr)) { |
217 | spin_lock_bh(&g_cdev.lock); | 218 | spin_lock_bh(&g_cdev.lock); |
218 | pd = g_cdev.active_pd; | 219 | pd = g_cdev.active_pd; |
219 | g_cdev.active_pd = 0; | 220 | g_cdev.active_pd = 0; |
diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c index 0e26d5f6cf2d..495ee1205e02 100644 --- a/drivers/staging/rtl8712/recv_linux.c +++ b/drivers/staging/rtl8712/recv_linux.c | |||
@@ -117,13 +117,8 @@ void r8712_recv_indicatepkt(struct _adapter *padapter, | |||
117 | if (skb == NULL) | 117 | if (skb == NULL) |
118 | goto _recv_indicatepkt_drop; | 118 | goto _recv_indicatepkt_drop; |
119 | skb->data = precv_frame->u.hdr.rx_data; | 119 | skb->data = precv_frame->u.hdr.rx_data; |
120 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | ||
121 | skb->tail = (sk_buff_data_t)(precv_frame->u.hdr.rx_tail - | ||
122 | precv_frame->u.hdr.rx_head); | ||
123 | #else | ||
124 | skb->tail = (sk_buff_data_t)precv_frame->u.hdr.rx_tail; | ||
125 | #endif | ||
126 | skb->len = precv_frame->u.hdr.len; | 120 | skb->len = precv_frame->u.hdr.len; |
121 | skb_set_tail_pointer(skb, skb->len); | ||
127 | if ((pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1)) | 122 | if ((pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1)) |
128 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 123 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
129 | else | 124 | else |
diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index e4bdf2a2b582..3aa895ec6507 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c | |||
@@ -200,7 +200,7 @@ s_vProcessRxMACHeader ( | |||
200 | } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) { | 200 | } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) { |
201 | cbHeaderSize += 6; | 201 | cbHeaderSize += 6; |
202 | pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); | 202 | pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); |
203 | if ((*pwType == cpu_to_le16(ETH_P_IPX)) || | 203 | if ((*pwType == cpu_to_be16(ETH_P_IPX)) || |
204 | (*pwType == cpu_to_le16(0xF380))) { | 204 | (*pwType == cpu_to_le16(0xF380))) { |
205 | cbHeaderSize -= 8; | 205 | cbHeaderSize -= 8; |
206 | pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); | 206 | pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); |
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index bb464527fc1b..b6e04e7b629b 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c | |||
@@ -1699,7 +1699,7 @@ s_bPacketToWirelessUsb( | |||
1699 | // 802.1H | 1699 | // 802.1H |
1700 | if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { | 1700 | if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { |
1701 | if (pDevice->dwDiagRefCount == 0) { | 1701 | if (pDevice->dwDiagRefCount == 0) { |
1702 | if ((psEthHeader->wType == cpu_to_le16(ETH_P_IPX)) || | 1702 | if ((psEthHeader->wType == cpu_to_be16(ETH_P_IPX)) || |
1703 | (psEthHeader->wType == cpu_to_le16(0xF380))) { | 1703 | (psEthHeader->wType == cpu_to_le16(0xF380))) { |
1704 | memcpy((PBYTE) (pbyPayloadHead), | 1704 | memcpy((PBYTE) (pbyPayloadHead), |
1705 | abySNAP_Bridgetunnel, 6); | 1705 | abySNAP_Bridgetunnel, 6); |
@@ -2838,10 +2838,10 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) | |||
2838 | Packet_Type = skb->data[ETH_HLEN+1]; | 2838 | Packet_Type = skb->data[ETH_HLEN+1]; |
2839 | Descriptor_type = skb->data[ETH_HLEN+1+1+2]; | 2839 | Descriptor_type = skb->data[ETH_HLEN+1+1+2]; |
2840 | Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]); | 2840 | Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]); |
2841 | if (pDevice->sTxEthHeader.wType == cpu_to_le16(ETH_P_PAE)) { | 2841 | if (pDevice->sTxEthHeader.wType == cpu_to_be16(ETH_P_PAE)) { |
2842 | /* 802.1x OR eapol-key challenge frame transfer */ | 2842 | /* 802.1x OR eapol-key challenge frame transfer */ |
2843 | if (((Protocol_Version == 1) || (Protocol_Version == 2)) && | 2843 | if (((Protocol_Version == 1) || (Protocol_Version == 2)) && |
2844 | (Packet_Type == 3)) { | 2844 | (Packet_Type == 3)) { |
2845 | bTxeapol_key = TRUE; | 2845 | bTxeapol_key = TRUE; |
2846 | if(!(Key_info & BIT3) && //WPA or RSN group-key challenge | 2846 | if(!(Key_info & BIT3) && //WPA or RSN group-key challenge |
2847 | (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key | 2847 | (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key |
@@ -2987,19 +2987,19 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) | |||
2987 | } | 2987 | } |
2988 | } | 2988 | } |
2989 | 2989 | ||
2990 | if (pDevice->sTxEthHeader.wType == cpu_to_le16(ETH_P_PAE)) { | 2990 | if (pDevice->sTxEthHeader.wType == cpu_to_be16(ETH_P_PAE)) { |
2991 | if (pDevice->byBBType != BB_TYPE_11A) { | 2991 | if (pDevice->byBBType != BB_TYPE_11A) { |
2992 | pDevice->wCurrentRate = RATE_1M; | 2992 | pDevice->wCurrentRate = RATE_1M; |
2993 | pDevice->byACKRate = RATE_1M; | 2993 | pDevice->byACKRate = RATE_1M; |
2994 | pDevice->byTopCCKBasicRate = RATE_1M; | 2994 | pDevice->byTopCCKBasicRate = RATE_1M; |
2995 | pDevice->byTopOFDMBasicRate = RATE_6M; | 2995 | pDevice->byTopOFDMBasicRate = RATE_6M; |
2996 | } else { | 2996 | } else { |
2997 | pDevice->wCurrentRate = RATE_6M; | 2997 | pDevice->wCurrentRate = RATE_6M; |
2998 | pDevice->byACKRate = RATE_6M; | 2998 | pDevice->byACKRate = RATE_6M; |
2999 | pDevice->byTopCCKBasicRate = RATE_1M; | 2999 | pDevice->byTopCCKBasicRate = RATE_1M; |
3000 | pDevice->byTopOFDMBasicRate = RATE_6M; | 3000 | pDevice->byTopOFDMBasicRate = RATE_6M; |
3001 | } | 3001 | } |
3002 | } | 3002 | } |
3003 | 3003 | ||
3004 | DBG_PRT(MSG_LEVEL_DEBUG, | 3004 | DBG_PRT(MSG_LEVEL_DEBUG, |
3005 | KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n", | 3005 | KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n", |
@@ -3015,7 +3015,7 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) | |||
3015 | 3015 | ||
3016 | if (bNeedEncryption == TRUE) { | 3016 | if (bNeedEncryption == TRUE) { |
3017 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType)); | 3017 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType)); |
3018 | if ((pDevice->sTxEthHeader.wType) == cpu_to_le16(ETH_P_PAE)) { | 3018 | if ((pDevice->sTxEthHeader.wType) == cpu_to_be16(ETH_P_PAE)) { |
3019 | bNeedEncryption = FALSE; | 3019 | bNeedEncryption = FALSE; |
3020 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType)); | 3020 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType)); |
3021 | if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { | 3021 | if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { |
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index fabff4d650ef..0970127344e6 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c | |||
@@ -327,9 +327,9 @@ int prism2_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
327 | return result; | 327 | return result; |
328 | } | 328 | } |
329 | 329 | ||
330 | int prism2_scan(struct wiphy *wiphy, struct net_device *dev, | 330 | int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) |
331 | struct cfg80211_scan_request *request) | ||
332 | { | 331 | { |
332 | struct net_device *dev = request->wdev->netdev; | ||
333 | struct prism2_wiphy_private *priv = wiphy_priv(wiphy); | 333 | struct prism2_wiphy_private *priv = wiphy_priv(wiphy); |
334 | wlandevice_t *wlandev = dev->ml_priv; | 334 | wlandevice_t *wlandev = dev->ml_priv; |
335 | struct p80211msg_dot11req_scan msg1; | 335 | struct p80211msg_dot11req_scan msg1; |
diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index c214977b4ab4..52b43b7b83d7 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c | |||
@@ -1251,13 +1251,12 @@ static int zcache_pampd_get_data_and_free(char *data, size_t *bufsize, bool raw, | |||
1251 | void *pampd, struct tmem_pool *pool, | 1251 | void *pampd, struct tmem_pool *pool, |
1252 | struct tmem_oid *oid, uint32_t index) | 1252 | struct tmem_oid *oid, uint32_t index) |
1253 | { | 1253 | { |
1254 | int ret = 0; | ||
1255 | |||
1256 | BUG_ON(!is_ephemeral(pool)); | 1254 | BUG_ON(!is_ephemeral(pool)); |
1257 | zbud_decompress((struct page *)(data), pampd); | 1255 | if (zbud_decompress((struct page *)(data), pampd) < 0) |
1256 | return -EINVAL; | ||
1258 | zbud_free_and_delist((struct zbud_hdr *)pampd); | 1257 | zbud_free_and_delist((struct zbud_hdr *)pampd); |
1259 | atomic_dec(&zcache_curr_eph_pampd_count); | 1258 | atomic_dec(&zcache_curr_eph_pampd_count); |
1260 | return ret; | 1259 | return 0; |
1261 | } | 1260 | } |
1262 | 1261 | ||
1263 | /* | 1262 | /* |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 0694d9b1bce6..6aba4395e8d8 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
@@ -221,6 +221,7 @@ static int iscsi_login_zero_tsih_s1( | |||
221 | { | 221 | { |
222 | struct iscsi_session *sess = NULL; | 222 | struct iscsi_session *sess = NULL; |
223 | struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf; | 223 | struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf; |
224 | int ret; | ||
224 | 225 | ||
225 | sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL); | 226 | sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL); |
226 | if (!sess) { | 227 | if (!sess) { |
@@ -257,9 +258,17 @@ static int iscsi_login_zero_tsih_s1( | |||
257 | return -ENOMEM; | 258 | return -ENOMEM; |
258 | } | 259 | } |
259 | spin_lock(&sess_idr_lock); | 260 | spin_lock(&sess_idr_lock); |
260 | idr_get_new(&sess_idr, NULL, &sess->session_index); | 261 | ret = idr_get_new(&sess_idr, NULL, &sess->session_index); |
261 | spin_unlock(&sess_idr_lock); | 262 | spin_unlock(&sess_idr_lock); |
262 | 263 | ||
264 | if (ret < 0) { | ||
265 | pr_err("idr_get_new() for sess_idr failed\n"); | ||
266 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
267 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
268 | kfree(sess); | ||
269 | return -ENOMEM; | ||
270 | } | ||
271 | |||
263 | sess->creation_time = get_jiffies_64(); | 272 | sess->creation_time = get_jiffies_64(); |
264 | spin_lock_init(&sess->session_stats_lock); | 273 | spin_lock_init(&sess->session_stats_lock); |
265 | /* | 274 | /* |
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 91799973081a..41641ba54828 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
@@ -218,6 +218,13 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
218 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 218 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
219 | return -EINVAL; | 219 | return -EINVAL; |
220 | } | 220 | } |
221 | if (cmd->data_length < 4) { | ||
222 | pr_warn("SET TARGET PORT GROUPS parameter list length %u too" | ||
223 | " small\n", cmd->data_length); | ||
224 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
225 | return -EINVAL; | ||
226 | } | ||
227 | |||
221 | buf = transport_kmap_data_sg(cmd); | 228 | buf = transport_kmap_data_sg(cmd); |
222 | 229 | ||
223 | /* | 230 | /* |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index cf2c66f3c116..9fc9a6006ca0 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -669,6 +669,13 @@ int target_report_luns(struct se_cmd *se_cmd) | |||
669 | unsigned char *buf; | 669 | unsigned char *buf; |
670 | u32 lun_count = 0, offset = 8, i; | 670 | u32 lun_count = 0, offset = 8, i; |
671 | 671 | ||
672 | if (se_cmd->data_length < 16) { | ||
673 | pr_warn("REPORT LUNS allocation length %u too small\n", | ||
674 | se_cmd->data_length); | ||
675 | se_cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
676 | return -EINVAL; | ||
677 | } | ||
678 | |||
672 | buf = transport_kmap_data_sg(se_cmd); | 679 | buf = transport_kmap_data_sg(se_cmd); |
673 | if (!buf) | 680 | if (!buf) |
674 | return -ENOMEM; | 681 | return -ENOMEM; |
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 76db75e836ed..9ba495477fd2 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
@@ -325,17 +325,30 @@ static int iblock_execute_unmap(struct se_cmd *cmd) | |||
325 | struct iblock_dev *ibd = dev->dev_ptr; | 325 | struct iblock_dev *ibd = dev->dev_ptr; |
326 | unsigned char *buf, *ptr = NULL; | 326 | unsigned char *buf, *ptr = NULL; |
327 | sector_t lba; | 327 | sector_t lba; |
328 | int size = cmd->data_length; | 328 | int size; |
329 | u32 range; | 329 | u32 range; |
330 | int ret = 0; | 330 | int ret = 0; |
331 | int dl, bd_dl; | 331 | int dl, bd_dl; |
332 | 332 | ||
333 | if (cmd->data_length < 8) { | ||
334 | pr_warn("UNMAP parameter list length %u too small\n", | ||
335 | cmd->data_length); | ||
336 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
337 | return -EINVAL; | ||
338 | } | ||
339 | |||
333 | buf = transport_kmap_data_sg(cmd); | 340 | buf = transport_kmap_data_sg(cmd); |
334 | 341 | ||
335 | dl = get_unaligned_be16(&buf[0]); | 342 | dl = get_unaligned_be16(&buf[0]); |
336 | bd_dl = get_unaligned_be16(&buf[2]); | 343 | bd_dl = get_unaligned_be16(&buf[2]); |
337 | 344 | ||
338 | size = min(size - 8, bd_dl); | 345 | size = cmd->data_length - 8; |
346 | if (bd_dl > size) | ||
347 | pr_warn("UNMAP parameter list length %u too small, ignoring bd_dl %u\n", | ||
348 | cmd->data_length, bd_dl); | ||
349 | else | ||
350 | size = bd_dl; | ||
351 | |||
339 | if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { | 352 | if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { |
340 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 353 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
341 | ret = -EINVAL; | 354 | ret = -EINVAL; |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 1e946502c378..956c84c6b666 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -1540,6 +1540,14 @@ static int core_scsi3_decode_spec_i_port( | |||
1540 | tidh_new->dest_local_nexus = 1; | 1540 | tidh_new->dest_local_nexus = 1; |
1541 | list_add_tail(&tidh_new->dest_list, &tid_dest_list); | 1541 | list_add_tail(&tidh_new->dest_list, &tid_dest_list); |
1542 | 1542 | ||
1543 | if (cmd->data_length < 28) { | ||
1544 | pr_warn("SPC-PR: Received PR OUT parameter list" | ||
1545 | " length too small: %u\n", cmd->data_length); | ||
1546 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
1547 | ret = -EINVAL; | ||
1548 | goto out; | ||
1549 | } | ||
1550 | |||
1543 | buf = transport_kmap_data_sg(cmd); | 1551 | buf = transport_kmap_data_sg(cmd); |
1544 | /* | 1552 | /* |
1545 | * For a PERSISTENT RESERVE OUT specify initiator ports payload, | 1553 | * For a PERSISTENT RESERVE OUT specify initiator ports payload, |
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 5552fa7426bc..9d7ce3daa262 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c | |||
@@ -667,7 +667,8 @@ static void pscsi_free_device(void *p) | |||
667 | kfree(pdv); | 667 | kfree(pdv); |
668 | } | 668 | } |
669 | 669 | ||
670 | static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) | 670 | static void pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg, |
671 | unsigned char *sense_buffer) | ||
671 | { | 672 | { |
672 | struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr; | 673 | struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr; |
673 | struct scsi_device *sd = pdv->pdv_sd; | 674 | struct scsi_device *sd = pdv->pdv_sd; |
@@ -679,7 +680,7 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) | |||
679 | * not been allocated because TCM is handling the emulation directly. | 680 | * not been allocated because TCM is handling the emulation directly. |
680 | */ | 681 | */ |
681 | if (!pt) | 682 | if (!pt) |
682 | return 0; | 683 | return; |
683 | 684 | ||
684 | cdb = &pt->pscsi_cdb[0]; | 685 | cdb = &pt->pscsi_cdb[0]; |
685 | result = pt->pscsi_result; | 686 | result = pt->pscsi_result; |
@@ -687,11 +688,11 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) | |||
687 | * Hack to make sure that Write-Protect modepage is set if R/O mode is | 688 | * Hack to make sure that Write-Protect modepage is set if R/O mode is |
688 | * forced. | 689 | * forced. |
689 | */ | 690 | */ |
691 | if (!cmd->se_deve || !cmd->data_length) | ||
692 | goto after_mode_sense; | ||
693 | |||
690 | if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) && | 694 | if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) && |
691 | (status_byte(result) << 1) == SAM_STAT_GOOD) { | 695 | (status_byte(result) << 1) == SAM_STAT_GOOD) { |
692 | if (!cmd->se_deve) | ||
693 | goto after_mode_sense; | ||
694 | |||
695 | if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) { | 696 | if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) { |
696 | unsigned char *buf = transport_kmap_data_sg(cmd); | 697 | unsigned char *buf = transport_kmap_data_sg(cmd); |
697 | 698 | ||
@@ -708,7 +709,7 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) | |||
708 | } | 709 | } |
709 | after_mode_sense: | 710 | after_mode_sense: |
710 | 711 | ||
711 | if (sd->type != TYPE_TAPE) | 712 | if (sd->type != TYPE_TAPE || !cmd->data_length) |
712 | goto after_mode_select; | 713 | goto after_mode_select; |
713 | 714 | ||
714 | /* | 715 | /* |
@@ -750,10 +751,10 @@ after_mode_sense: | |||
750 | } | 751 | } |
751 | after_mode_select: | 752 | after_mode_select: |
752 | 753 | ||
753 | if (status_byte(result) & CHECK_CONDITION) | 754 | if (sense_buffer && (status_byte(result) & CHECK_CONDITION)) { |
754 | return 1; | 755 | memcpy(sense_buffer, pt->pscsi_sense, TRANSPORT_SENSE_BUFFER); |
755 | 756 | cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE; | |
756 | return 0; | 757 | } |
757 | } | 758 | } |
758 | 759 | ||
759 | enum { | 760 | enum { |
@@ -1184,13 +1185,6 @@ fail: | |||
1184 | return -ENOMEM; | 1185 | return -ENOMEM; |
1185 | } | 1186 | } |
1186 | 1187 | ||
1187 | static unsigned char *pscsi_get_sense_buffer(struct se_cmd *cmd) | ||
1188 | { | ||
1189 | struct pscsi_plugin_task *pt = cmd->priv; | ||
1190 | |||
1191 | return pt->pscsi_sense; | ||
1192 | } | ||
1193 | |||
1194 | /* pscsi_get_device_rev(): | 1188 | /* pscsi_get_device_rev(): |
1195 | * | 1189 | * |
1196 | * | 1190 | * |
@@ -1273,7 +1267,6 @@ static struct se_subsystem_api pscsi_template = { | |||
1273 | .check_configfs_dev_params = pscsi_check_configfs_dev_params, | 1267 | .check_configfs_dev_params = pscsi_check_configfs_dev_params, |
1274 | .set_configfs_dev_params = pscsi_set_configfs_dev_params, | 1268 | .set_configfs_dev_params = pscsi_set_configfs_dev_params, |
1275 | .show_configfs_dev_params = pscsi_show_configfs_dev_params, | 1269 | .show_configfs_dev_params = pscsi_show_configfs_dev_params, |
1276 | .get_sense_buffer = pscsi_get_sense_buffer, | ||
1277 | .get_device_rev = pscsi_get_device_rev, | 1270 | .get_device_rev = pscsi_get_device_rev, |
1278 | .get_device_type = pscsi_get_device_type, | 1271 | .get_device_type = pscsi_get_device_type, |
1279 | .get_blocks = pscsi_get_blocks, | 1272 | .get_blocks = pscsi_get_blocks, |
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 4c861de538c9..388a922c8f6d 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c | |||
@@ -877,9 +877,11 @@ static int spc_emulate_modesense(struct se_cmd *cmd) | |||
877 | static int spc_emulate_request_sense(struct se_cmd *cmd) | 877 | static int spc_emulate_request_sense(struct se_cmd *cmd) |
878 | { | 878 | { |
879 | unsigned char *cdb = cmd->t_task_cdb; | 879 | unsigned char *cdb = cmd->t_task_cdb; |
880 | unsigned char *buf; | 880 | unsigned char *rbuf; |
881 | u8 ua_asc = 0, ua_ascq = 0; | 881 | u8 ua_asc = 0, ua_ascq = 0; |
882 | int err = 0; | 882 | unsigned char buf[SE_SENSE_BUF]; |
883 | |||
884 | memset(buf, 0, SE_SENSE_BUF); | ||
883 | 885 | ||
884 | if (cdb[1] & 0x01) { | 886 | if (cdb[1] & 0x01) { |
885 | pr_err("REQUEST_SENSE description emulation not" | 887 | pr_err("REQUEST_SENSE description emulation not" |
@@ -888,20 +890,21 @@ static int spc_emulate_request_sense(struct se_cmd *cmd) | |||
888 | return -ENOSYS; | 890 | return -ENOSYS; |
889 | } | 891 | } |
890 | 892 | ||
891 | buf = transport_kmap_data_sg(cmd); | 893 | rbuf = transport_kmap_data_sg(cmd); |
892 | 894 | if (cmd->scsi_sense_reason != 0) { | |
893 | if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { | 895 | /* |
896 | * Out of memory. We will fail with CHECK CONDITION, so | ||
897 | * we must not clear the unit attention condition. | ||
898 | */ | ||
899 | target_complete_cmd(cmd, CHECK_CONDITION); | ||
900 | return 0; | ||
901 | } else if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { | ||
894 | /* | 902 | /* |
895 | * CURRENT ERROR, UNIT ATTENTION | 903 | * CURRENT ERROR, UNIT ATTENTION |
896 | */ | 904 | */ |
897 | buf[0] = 0x70; | 905 | buf[0] = 0x70; |
898 | buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; | 906 | buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; |
899 | 907 | ||
900 | if (cmd->data_length < 18) { | ||
901 | buf[7] = 0x00; | ||
902 | err = -EINVAL; | ||
903 | goto end; | ||
904 | } | ||
905 | /* | 908 | /* |
906 | * The Additional Sense Code (ASC) from the UNIT ATTENTION | 909 | * The Additional Sense Code (ASC) from the UNIT ATTENTION |
907 | */ | 910 | */ |
@@ -915,11 +918,6 @@ static int spc_emulate_request_sense(struct se_cmd *cmd) | |||
915 | buf[0] = 0x70; | 918 | buf[0] = 0x70; |
916 | buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE; | 919 | buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE; |
917 | 920 | ||
918 | if (cmd->data_length < 18) { | ||
919 | buf[7] = 0x00; | ||
920 | err = -EINVAL; | ||
921 | goto end; | ||
922 | } | ||
923 | /* | 921 | /* |
924 | * NO ADDITIONAL SENSE INFORMATION | 922 | * NO ADDITIONAL SENSE INFORMATION |
925 | */ | 923 | */ |
@@ -927,8 +925,11 @@ static int spc_emulate_request_sense(struct se_cmd *cmd) | |||
927 | buf[7] = 0x0A; | 925 | buf[7] = 0x0A; |
928 | } | 926 | } |
929 | 927 | ||
930 | end: | 928 | if (rbuf) { |
931 | transport_kunmap_data_sg(cmd); | 929 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); |
930 | transport_kunmap_data_sg(cmd); | ||
931 | } | ||
932 | |||
932 | target_complete_cmd(cmd, GOOD); | 933 | target_complete_cmd(cmd, GOOD); |
933 | return 0; | 934 | return 0; |
934 | } | 935 | } |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 4de3186dc44e..269f54488397 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -567,6 +567,34 @@ static void target_complete_failure_work(struct work_struct *work) | |||
567 | transport_generic_request_failure(cmd); | 567 | transport_generic_request_failure(cmd); |
568 | } | 568 | } |
569 | 569 | ||
570 | /* | ||
571 | * Used when asking transport to copy Sense Data from the underlying | ||
572 | * Linux/SCSI struct scsi_cmnd | ||
573 | */ | ||
574 | static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd) | ||
575 | { | ||
576 | unsigned char *buffer = cmd->sense_buffer; | ||
577 | struct se_device *dev = cmd->se_dev; | ||
578 | u32 offset = 0; | ||
579 | |||
580 | WARN_ON(!cmd->se_lun); | ||
581 | |||
582 | if (!dev) | ||
583 | return NULL; | ||
584 | |||
585 | if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) | ||
586 | return NULL; | ||
587 | |||
588 | offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER); | ||
589 | |||
590 | /* Automatically padded */ | ||
591 | cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; | ||
592 | |||
593 | pr_debug("HBA_[%u]_PLUG[%s]: Requesting sense for SAM STATUS: 0x%02x\n", | ||
594 | dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status); | ||
595 | return &buffer[offset]; | ||
596 | } | ||
597 | |||
570 | void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) | 598 | void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) |
571 | { | 599 | { |
572 | struct se_device *dev = cmd->se_dev; | 600 | struct se_device *dev = cmd->se_dev; |
@@ -580,11 +608,11 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) | |||
580 | cmd->transport_state &= ~CMD_T_BUSY; | 608 | cmd->transport_state &= ~CMD_T_BUSY; |
581 | 609 | ||
582 | if (dev && dev->transport->transport_complete) { | 610 | if (dev && dev->transport->transport_complete) { |
583 | if (dev->transport->transport_complete(cmd, | 611 | dev->transport->transport_complete(cmd, |
584 | cmd->t_data_sg) != 0) { | 612 | cmd->t_data_sg, |
585 | cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE; | 613 | transport_get_sense_buffer(cmd)); |
614 | if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) | ||
586 | success = 1; | 615 | success = 1; |
587 | } | ||
588 | } | 616 | } |
589 | 617 | ||
590 | /* | 618 | /* |
@@ -1181,15 +1209,20 @@ int target_cmd_size_check(struct se_cmd *cmd, unsigned int size) | |||
1181 | /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */ | 1209 | /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */ |
1182 | goto out_invalid_cdb_field; | 1210 | goto out_invalid_cdb_field; |
1183 | } | 1211 | } |
1184 | 1212 | /* | |
1213 | * For the overflow case keep the existing fabric provided | ||
1214 | * ->data_length. Otherwise for the underflow case, reset | ||
1215 | * ->data_length to the smaller SCSI expected data transfer | ||
1216 | * length. | ||
1217 | */ | ||
1185 | if (size > cmd->data_length) { | 1218 | if (size > cmd->data_length) { |
1186 | cmd->se_cmd_flags |= SCF_OVERFLOW_BIT; | 1219 | cmd->se_cmd_flags |= SCF_OVERFLOW_BIT; |
1187 | cmd->residual_count = (size - cmd->data_length); | 1220 | cmd->residual_count = (size - cmd->data_length); |
1188 | } else { | 1221 | } else { |
1189 | cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; | 1222 | cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; |
1190 | cmd->residual_count = (cmd->data_length - size); | 1223 | cmd->residual_count = (cmd->data_length - size); |
1224 | cmd->data_length = size; | ||
1191 | } | 1225 | } |
1192 | cmd->data_length = size; | ||
1193 | } | 1226 | } |
1194 | 1227 | ||
1195 | return 0; | 1228 | return 0; |
@@ -1816,61 +1849,6 @@ execute: | |||
1816 | EXPORT_SYMBOL(target_execute_cmd); | 1849 | EXPORT_SYMBOL(target_execute_cmd); |
1817 | 1850 | ||
1818 | /* | 1851 | /* |
1819 | * Used to obtain Sense Data from underlying Linux/SCSI struct scsi_cmnd | ||
1820 | */ | ||
1821 | static int transport_get_sense_data(struct se_cmd *cmd) | ||
1822 | { | ||
1823 | unsigned char *buffer = cmd->sense_buffer, *sense_buffer = NULL; | ||
1824 | struct se_device *dev = cmd->se_dev; | ||
1825 | unsigned long flags; | ||
1826 | u32 offset = 0; | ||
1827 | |||
1828 | WARN_ON(!cmd->se_lun); | ||
1829 | |||
1830 | if (!dev) | ||
1831 | return 0; | ||
1832 | |||
1833 | spin_lock_irqsave(&cmd->t_state_lock, flags); | ||
1834 | if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { | ||
1835 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
1836 | return 0; | ||
1837 | } | ||
1838 | |||
1839 | if (!(cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)) | ||
1840 | goto out; | ||
1841 | |||
1842 | if (!dev->transport->get_sense_buffer) { | ||
1843 | pr_err("dev->transport->get_sense_buffer is NULL\n"); | ||
1844 | goto out; | ||
1845 | } | ||
1846 | |||
1847 | sense_buffer = dev->transport->get_sense_buffer(cmd); | ||
1848 | if (!sense_buffer) { | ||
1849 | pr_err("ITT 0x%08x cmd %p: Unable to locate" | ||
1850 | " sense buffer for task with sense\n", | ||
1851 | cmd->se_tfo->get_task_tag(cmd), cmd); | ||
1852 | goto out; | ||
1853 | } | ||
1854 | |||
1855 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
1856 | |||
1857 | offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER); | ||
1858 | |||
1859 | memcpy(&buffer[offset], sense_buffer, TRANSPORT_SENSE_BUFFER); | ||
1860 | |||
1861 | /* Automatically padded */ | ||
1862 | cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; | ||
1863 | |||
1864 | pr_debug("HBA_[%u]_PLUG[%s]: Set SAM STATUS: 0x%02x and sense\n", | ||
1865 | dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status); | ||
1866 | return 0; | ||
1867 | |||
1868 | out: | ||
1869 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
1870 | return -1; | ||
1871 | } | ||
1872 | |||
1873 | /* | ||
1874 | * Process all commands up to the last received ORDERED task attribute which | 1852 | * Process all commands up to the last received ORDERED task attribute which |
1875 | * requires another blocking boundary | 1853 | * requires another blocking boundary |
1876 | */ | 1854 | */ |
@@ -1985,7 +1963,7 @@ static void transport_handle_queue_full( | |||
1985 | static void target_complete_ok_work(struct work_struct *work) | 1963 | static void target_complete_ok_work(struct work_struct *work) |
1986 | { | 1964 | { |
1987 | struct se_cmd *cmd = container_of(work, struct se_cmd, work); | 1965 | struct se_cmd *cmd = container_of(work, struct se_cmd, work); |
1988 | int reason = 0, ret; | 1966 | int ret; |
1989 | 1967 | ||
1990 | /* | 1968 | /* |
1991 | * Check if we need to move delayed/dormant tasks from cmds on the | 1969 | * Check if we need to move delayed/dormant tasks from cmds on the |
@@ -2002,23 +1980,19 @@ static void target_complete_ok_work(struct work_struct *work) | |||
2002 | schedule_work(&cmd->se_dev->qf_work_queue); | 1980 | schedule_work(&cmd->se_dev->qf_work_queue); |
2003 | 1981 | ||
2004 | /* | 1982 | /* |
2005 | * Check if we need to retrieve a sense buffer from | 1983 | * Check if we need to send a sense buffer from |
2006 | * the struct se_cmd in question. | 1984 | * the struct se_cmd in question. |
2007 | */ | 1985 | */ |
2008 | if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) { | 1986 | if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) { |
2009 | if (transport_get_sense_data(cmd) < 0) | 1987 | WARN_ON(!cmd->scsi_status); |
2010 | reason = TCM_NON_EXISTENT_LUN; | 1988 | ret = transport_send_check_condition_and_sense( |
2011 | 1989 | cmd, 0, 1); | |
2012 | if (cmd->scsi_status) { | 1990 | if (ret == -EAGAIN || ret == -ENOMEM) |
2013 | ret = transport_send_check_condition_and_sense( | 1991 | goto queue_full; |
2014 | cmd, reason, 1); | ||
2015 | if (ret == -EAGAIN || ret == -ENOMEM) | ||
2016 | goto queue_full; | ||
2017 | 1992 | ||
2018 | transport_lun_remove_cmd(cmd); | 1993 | transport_lun_remove_cmd(cmd); |
2019 | transport_cmd_check_stop_to_fabric(cmd); | 1994 | transport_cmd_check_stop_to_fabric(cmd); |
2020 | return; | 1995 | return; |
2021 | } | ||
2022 | } | 1996 | } |
2023 | /* | 1997 | /* |
2024 | * Check for a callback, used by amongst other things | 1998 | * Check for a callback, used by amongst other things |
@@ -2216,7 +2190,6 @@ void *transport_kmap_data_sg(struct se_cmd *cmd) | |||
2216 | struct page **pages; | 2190 | struct page **pages; |
2217 | int i; | 2191 | int i; |
2218 | 2192 | ||
2219 | BUG_ON(!sg); | ||
2220 | /* | 2193 | /* |
2221 | * We need to take into account a possible offset here for fabrics like | 2194 | * We need to take into account a possible offset here for fabrics like |
2222 | * tcm_loop who may be using a contig buffer from the SCSI midlayer for | 2195 | * tcm_loop who may be using a contig buffer from the SCSI midlayer for |
@@ -2224,13 +2197,17 @@ void *transport_kmap_data_sg(struct se_cmd *cmd) | |||
2224 | */ | 2197 | */ |
2225 | if (!cmd->t_data_nents) | 2198 | if (!cmd->t_data_nents) |
2226 | return NULL; | 2199 | return NULL; |
2227 | else if (cmd->t_data_nents == 1) | 2200 | |
2201 | BUG_ON(!sg); | ||
2202 | if (cmd->t_data_nents == 1) | ||
2228 | return kmap(sg_page(sg)) + sg->offset; | 2203 | return kmap(sg_page(sg)) + sg->offset; |
2229 | 2204 | ||
2230 | /* >1 page. use vmap */ | 2205 | /* >1 page. use vmap */ |
2231 | pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL); | 2206 | pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL); |
2232 | if (!pages) | 2207 | if (!pages) { |
2208 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2233 | return NULL; | 2209 | return NULL; |
2210 | } | ||
2234 | 2211 | ||
2235 | /* convert sg[] to pages[] */ | 2212 | /* convert sg[] to pages[] */ |
2236 | for_each_sg(cmd->t_data_sg, sg, cmd->t_data_nents, i) { | 2213 | for_each_sg(cmd->t_data_sg, sg, cmd->t_data_nents, i) { |
@@ -2239,8 +2216,10 @@ void *transport_kmap_data_sg(struct se_cmd *cmd) | |||
2239 | 2216 | ||
2240 | cmd->t_data_vmap = vmap(pages, cmd->t_data_nents, VM_MAP, PAGE_KERNEL); | 2217 | cmd->t_data_vmap = vmap(pages, cmd->t_data_nents, VM_MAP, PAGE_KERNEL); |
2241 | kfree(pages); | 2218 | kfree(pages); |
2242 | if (!cmd->t_data_vmap) | 2219 | if (!cmd->t_data_vmap) { |
2220 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2243 | return NULL; | 2221 | return NULL; |
2222 | } | ||
2244 | 2223 | ||
2245 | return cmd->t_data_vmap + cmd->t_data_sg[0].offset; | 2224 | return cmd->t_data_vmap + cmd->t_data_sg[0].offset; |
2246 | } | 2225 | } |
@@ -2326,19 +2305,14 @@ int transport_generic_new_cmd(struct se_cmd *cmd) | |||
2326 | * into the fabric for data transfers, go ahead and complete it right | 2305 | * into the fabric for data transfers, go ahead and complete it right |
2327 | * away. | 2306 | * away. |
2328 | */ | 2307 | */ |
2329 | if (!cmd->data_length) { | 2308 | if (!cmd->data_length && |
2309 | cmd->t_task_cdb[0] != REQUEST_SENSE && | ||
2310 | cmd->se_dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) { | ||
2330 | spin_lock_irq(&cmd->t_state_lock); | 2311 | spin_lock_irq(&cmd->t_state_lock); |
2331 | cmd->t_state = TRANSPORT_COMPLETE; | 2312 | cmd->t_state = TRANSPORT_COMPLETE; |
2332 | cmd->transport_state |= CMD_T_ACTIVE; | 2313 | cmd->transport_state |= CMD_T_ACTIVE; |
2333 | spin_unlock_irq(&cmd->t_state_lock); | 2314 | spin_unlock_irq(&cmd->t_state_lock); |
2334 | 2315 | ||
2335 | if (cmd->t_task_cdb[0] == REQUEST_SENSE) { | ||
2336 | u8 ua_asc = 0, ua_ascq = 0; | ||
2337 | |||
2338 | core_scsi3_ua_clear_for_request_sense(cmd, | ||
2339 | &ua_asc, &ua_ascq); | ||
2340 | } | ||
2341 | |||
2342 | INIT_WORK(&cmd->work, target_complete_ok_work); | 2316 | INIT_WORK(&cmd->work, target_complete_ok_work); |
2343 | queue_work(target_completion_wq, &cmd->work); | 2317 | queue_work(target_completion_wq, &cmd->work); |
2344 | return 0; | 2318 | return 0; |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index d5c689d6217e..e309e8b0aaba 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -132,6 +132,7 @@ | |||
132 | #define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ | 132 | #define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ |
133 | #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ | 133 | #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ |
134 | #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ | 134 | #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ |
135 | #define UFCR_DCEDTE (1<<6) /* DCE/DTE mode select */ | ||
135 | #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ | 136 | #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ |
136 | #define UFCR_RFDIV_REG(x) (((x) < 7 ? 6 - (x) : 6) << 7) | 137 | #define UFCR_RFDIV_REG(x) (((x) < 7 ? 6 - (x) : 6) << 7) |
137 | #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ | 138 | #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ |
@@ -667,22 +668,11 @@ static void imx_break_ctl(struct uart_port *port, int break_state) | |||
667 | static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) | 668 | static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) |
668 | { | 669 | { |
669 | unsigned int val; | 670 | unsigned int val; |
670 | unsigned int ufcr_rfdiv; | ||
671 | |||
672 | /* set receiver / transmitter trigger level. | ||
673 | * RFDIV is set such way to satisfy requested uartclk value | ||
674 | */ | ||
675 | val = TXTL << 10 | RXTL; | ||
676 | ufcr_rfdiv = (clk_get_rate(sport->clk_per) + sport->port.uartclk / 2) | ||
677 | / sport->port.uartclk; | ||
678 | |||
679 | if(!ufcr_rfdiv) | ||
680 | ufcr_rfdiv = 1; | ||
681 | |||
682 | val |= UFCR_RFDIV_REG(ufcr_rfdiv); | ||
683 | 671 | ||
672 | /* set receiver / transmitter trigger level */ | ||
673 | val = readl(sport->port.membase + UFCR) & (UFCR_RFDIV | UFCR_DCEDTE); | ||
674 | val |= TXTL << UFCR_TXTL_SHF | RXTL; | ||
684 | writel(val, sport->port.membase + UFCR); | 675 | writel(val, sport->port.membase + UFCR); |
685 | |||
686 | return 0; | 676 | return 0; |
687 | } | 677 | } |
688 | 678 | ||
@@ -754,6 +744,7 @@ static int imx_startup(struct uart_port *port) | |||
754 | } | 744 | } |
755 | } | 745 | } |
756 | 746 | ||
747 | spin_lock_irqsave(&sport->port.lock, flags); | ||
757 | /* | 748 | /* |
758 | * Finally, clear and enable interrupts | 749 | * Finally, clear and enable interrupts |
759 | */ | 750 | */ |
@@ -807,7 +798,6 @@ static int imx_startup(struct uart_port *port) | |||
807 | /* | 798 | /* |
808 | * Enable modem status interrupts | 799 | * Enable modem status interrupts |
809 | */ | 800 | */ |
810 | spin_lock_irqsave(&sport->port.lock,flags); | ||
811 | imx_enable_ms(&sport->port); | 801 | imx_enable_ms(&sport->port); |
812 | spin_unlock_irqrestore(&sport->port.lock,flags); | 802 | spin_unlock_irqrestore(&sport->port.lock,flags); |
813 | 803 | ||
@@ -837,10 +827,13 @@ static void imx_shutdown(struct uart_port *port) | |||
837 | { | 827 | { |
838 | struct imx_port *sport = (struct imx_port *)port; | 828 | struct imx_port *sport = (struct imx_port *)port; |
839 | unsigned long temp; | 829 | unsigned long temp; |
830 | unsigned long flags; | ||
840 | 831 | ||
832 | spin_lock_irqsave(&sport->port.lock, flags); | ||
841 | temp = readl(sport->port.membase + UCR2); | 833 | temp = readl(sport->port.membase + UCR2); |
842 | temp &= ~(UCR2_TXEN); | 834 | temp &= ~(UCR2_TXEN); |
843 | writel(temp, sport->port.membase + UCR2); | 835 | writel(temp, sport->port.membase + UCR2); |
836 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
844 | 837 | ||
845 | if (USE_IRDA(sport)) { | 838 | if (USE_IRDA(sport)) { |
846 | struct imxuart_platform_data *pdata; | 839 | struct imxuart_platform_data *pdata; |
@@ -869,12 +862,14 @@ static void imx_shutdown(struct uart_port *port) | |||
869 | * Disable all interrupts, port and break condition. | 862 | * Disable all interrupts, port and break condition. |
870 | */ | 863 | */ |
871 | 864 | ||
865 | spin_lock_irqsave(&sport->port.lock, flags); | ||
872 | temp = readl(sport->port.membase + UCR1); | 866 | temp = readl(sport->port.membase + UCR1); |
873 | temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); | 867 | temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); |
874 | if (USE_IRDA(sport)) | 868 | if (USE_IRDA(sport)) |
875 | temp &= ~(UCR1_IREN); | 869 | temp &= ~(UCR1_IREN); |
876 | 870 | ||
877 | writel(temp, sport->port.membase + UCR1); | 871 | writel(temp, sport->port.membase + UCR1); |
872 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
878 | } | 873 | } |
879 | 874 | ||
880 | static void | 875 | static void |
@@ -1217,6 +1212,9 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
1217 | struct imx_port *sport = imx_ports[co->index]; | 1212 | struct imx_port *sport = imx_ports[co->index]; |
1218 | struct imx_port_ucrs old_ucr; | 1213 | struct imx_port_ucrs old_ucr; |
1219 | unsigned int ucr1; | 1214 | unsigned int ucr1; |
1215 | unsigned long flags; | ||
1216 | |||
1217 | spin_lock_irqsave(&sport->port.lock, flags); | ||
1220 | 1218 | ||
1221 | /* | 1219 | /* |
1222 | * First, save UCR1/2/3 and then disable interrupts | 1220 | * First, save UCR1/2/3 and then disable interrupts |
@@ -1242,6 +1240,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
1242 | while (!(readl(sport->port.membase + USR2) & USR2_TXDC)); | 1240 | while (!(readl(sport->port.membase + USR2) & USR2_TXDC)); |
1243 | 1241 | ||
1244 | imx_port_ucrs_restore(&sport->port, &old_ucr); | 1242 | imx_port_ucrs_restore(&sport->port, &old_ucr); |
1243 | |||
1244 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
1245 | } | 1245 | } |
1246 | 1246 | ||
1247 | /* | 1247 | /* |
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index c7a032a4f0c5..d214448b677e 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c | |||
@@ -78,8 +78,7 @@ static inline int ep_to_bit(struct ci13xxx *ci, int n) | |||
78 | } | 78 | } |
79 | 79 | ||
80 | /** | 80 | /** |
81 | * hw_device_state: enables/disables interrupts & starts/stops device (execute | 81 | * hw_device_state: enables/disables interrupts (execute without interruption) |
82 | * without interruption) | ||
83 | * @dma: 0 => disable, !0 => enable and set dma engine | 82 | * @dma: 0 => disable, !0 => enable and set dma engine |
84 | * | 83 | * |
85 | * This function returns an error code | 84 | * This function returns an error code |
@@ -91,9 +90,7 @@ static int hw_device_state(struct ci13xxx *ci, u32 dma) | |||
91 | /* interrupt, error, port change, reset, sleep/suspend */ | 90 | /* interrupt, error, port change, reset, sleep/suspend */ |
92 | hw_write(ci, OP_USBINTR, ~0, | 91 | hw_write(ci, OP_USBINTR, ~0, |
93 | USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI); | 92 | USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI); |
94 | hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS); | ||
95 | } else { | 93 | } else { |
96 | hw_write(ci, OP_USBCMD, USBCMD_RS, 0); | ||
97 | hw_write(ci, OP_USBINTR, ~0, 0); | 94 | hw_write(ci, OP_USBINTR, ~0, 0); |
98 | } | 95 | } |
99 | return 0; | 96 | return 0; |
@@ -774,10 +771,7 @@ __acquires(mEp->lock) | |||
774 | { | 771 | { |
775 | struct ci13xxx_req *mReq, *mReqTemp; | 772 | struct ci13xxx_req *mReq, *mReqTemp; |
776 | struct ci13xxx_ep *mEpTemp = mEp; | 773 | struct ci13xxx_ep *mEpTemp = mEp; |
777 | int uninitialized_var(retval); | 774 | int retval = 0; |
778 | |||
779 | if (list_empty(&mEp->qh.queue)) | ||
780 | return -EINVAL; | ||
781 | 775 | ||
782 | list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue, | 776 | list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue, |
783 | queue) { | 777 | queue) { |
@@ -1420,6 +1414,21 @@ static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | |||
1420 | return -ENOTSUPP; | 1414 | return -ENOTSUPP; |
1421 | } | 1415 | } |
1422 | 1416 | ||
1417 | /* Change Data+ pullup status | ||
1418 | * this func is used by usb_gadget_connect/disconnet | ||
1419 | */ | ||
1420 | static int ci13xxx_pullup(struct usb_gadget *_gadget, int is_on) | ||
1421 | { | ||
1422 | struct ci13xxx *ci = container_of(_gadget, struct ci13xxx, gadget); | ||
1423 | |||
1424 | if (is_on) | ||
1425 | hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS); | ||
1426 | else | ||
1427 | hw_write(ci, OP_USBCMD, USBCMD_RS, 0); | ||
1428 | |||
1429 | return 0; | ||
1430 | } | ||
1431 | |||
1423 | static int ci13xxx_start(struct usb_gadget *gadget, | 1432 | static int ci13xxx_start(struct usb_gadget *gadget, |
1424 | struct usb_gadget_driver *driver); | 1433 | struct usb_gadget_driver *driver); |
1425 | static int ci13xxx_stop(struct usb_gadget *gadget, | 1434 | static int ci13xxx_stop(struct usb_gadget *gadget, |
@@ -1432,6 +1441,7 @@ static int ci13xxx_stop(struct usb_gadget *gadget, | |||
1432 | static const struct usb_gadget_ops usb_gadget_ops = { | 1441 | static const struct usb_gadget_ops usb_gadget_ops = { |
1433 | .vbus_session = ci13xxx_vbus_session, | 1442 | .vbus_session = ci13xxx_vbus_session, |
1434 | .wakeup = ci13xxx_wakeup, | 1443 | .wakeup = ci13xxx_wakeup, |
1444 | .pullup = ci13xxx_pullup, | ||
1435 | .vbus_draw = ci13xxx_vbus_draw, | 1445 | .vbus_draw = ci13xxx_vbus_draw, |
1436 | .udc_start = ci13xxx_start, | 1446 | .udc_start = ci13xxx_start, |
1437 | .udc_stop = ci13xxx_stop, | 1447 | .udc_stop = ci13xxx_stop, |
@@ -1455,7 +1465,12 @@ static int init_eps(struct ci13xxx *ci) | |||
1455 | 1465 | ||
1456 | mEp->ep.name = mEp->name; | 1466 | mEp->ep.name = mEp->name; |
1457 | mEp->ep.ops = &usb_ep_ops; | 1467 | mEp->ep.ops = &usb_ep_ops; |
1458 | mEp->ep.maxpacket = CTRL_PAYLOAD_MAX; | 1468 | /* |
1469 | * for ep0: maxP defined in desc, for other | ||
1470 | * eps, maxP is set by epautoconfig() called | ||
1471 | * by gadget layer | ||
1472 | */ | ||
1473 | mEp->ep.maxpacket = (unsigned short)~0; | ||
1459 | 1474 | ||
1460 | INIT_LIST_HEAD(&mEp->qh.queue); | 1475 | INIT_LIST_HEAD(&mEp->qh.queue); |
1461 | mEp->qh.ptr = dma_pool_alloc(ci->qh_pool, GFP_KERNEL, | 1476 | mEp->qh.ptr = dma_pool_alloc(ci->qh_pool, GFP_KERNEL, |
@@ -1475,6 +1490,7 @@ static int init_eps(struct ci13xxx *ci) | |||
1475 | else | 1490 | else |
1476 | ci->ep0in = mEp; | 1491 | ci->ep0in = mEp; |
1477 | 1492 | ||
1493 | mEp->ep.maxpacket = CTRL_PAYLOAD_MAX; | ||
1478 | continue; | 1494 | continue; |
1479 | } | 1495 | } |
1480 | 1496 | ||
@@ -1484,6 +1500,17 @@ static int init_eps(struct ci13xxx *ci) | |||
1484 | return retval; | 1500 | return retval; |
1485 | } | 1501 | } |
1486 | 1502 | ||
1503 | static void destroy_eps(struct ci13xxx *ci) | ||
1504 | { | ||
1505 | int i; | ||
1506 | |||
1507 | for (i = 0; i < ci->hw_ep_max; i++) { | ||
1508 | struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i]; | ||
1509 | |||
1510 | dma_pool_free(ci->qh_pool, mEp->qh.ptr, mEp->qh.dma); | ||
1511 | } | ||
1512 | } | ||
1513 | |||
1487 | /** | 1514 | /** |
1488 | * ci13xxx_start: register a gadget driver | 1515 | * ci13xxx_start: register a gadget driver |
1489 | * @gadget: our gadget | 1516 | * @gadget: our gadget |
@@ -1691,7 +1718,7 @@ static int udc_start(struct ci13xxx *ci) | |||
1691 | if (ci->platdata->flags & CI13XXX_REQUIRE_TRANSCEIVER) { | 1718 | if (ci->platdata->flags & CI13XXX_REQUIRE_TRANSCEIVER) { |
1692 | if (ci->transceiver == NULL) { | 1719 | if (ci->transceiver == NULL) { |
1693 | retval = -ENODEV; | 1720 | retval = -ENODEV; |
1694 | goto free_pools; | 1721 | goto destroy_eps; |
1695 | } | 1722 | } |
1696 | } | 1723 | } |
1697 | 1724 | ||
@@ -1729,7 +1756,7 @@ static int udc_start(struct ci13xxx *ci) | |||
1729 | 1756 | ||
1730 | remove_trans: | 1757 | remove_trans: |
1731 | if (!IS_ERR_OR_NULL(ci->transceiver)) { | 1758 | if (!IS_ERR_OR_NULL(ci->transceiver)) { |
1732 | otg_set_peripheral(ci->transceiver->otg, &ci->gadget); | 1759 | otg_set_peripheral(ci->transceiver->otg, NULL); |
1733 | if (ci->global_phy) | 1760 | if (ci->global_phy) |
1734 | usb_put_phy(ci->transceiver); | 1761 | usb_put_phy(ci->transceiver); |
1735 | } | 1762 | } |
@@ -1742,6 +1769,8 @@ unreg_device: | |||
1742 | put_transceiver: | 1769 | put_transceiver: |
1743 | if (!IS_ERR_OR_NULL(ci->transceiver) && ci->global_phy) | 1770 | if (!IS_ERR_OR_NULL(ci->transceiver) && ci->global_phy) |
1744 | usb_put_phy(ci->transceiver); | 1771 | usb_put_phy(ci->transceiver); |
1772 | destroy_eps: | ||
1773 | destroy_eps(ci); | ||
1745 | free_pools: | 1774 | free_pools: |
1746 | dma_pool_destroy(ci->td_pool); | 1775 | dma_pool_destroy(ci->td_pool); |
1747 | free_qh_pool: | 1776 | free_qh_pool: |
@@ -1756,18 +1785,12 @@ free_qh_pool: | |||
1756 | */ | 1785 | */ |
1757 | static void udc_stop(struct ci13xxx *ci) | 1786 | static void udc_stop(struct ci13xxx *ci) |
1758 | { | 1787 | { |
1759 | int i; | ||
1760 | |||
1761 | if (ci == NULL) | 1788 | if (ci == NULL) |
1762 | return; | 1789 | return; |
1763 | 1790 | ||
1764 | usb_del_gadget_udc(&ci->gadget); | 1791 | usb_del_gadget_udc(&ci->gadget); |
1765 | 1792 | ||
1766 | for (i = 0; i < ci->hw_ep_max; i++) { | 1793 | destroy_eps(ci); |
1767 | struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i]; | ||
1768 | |||
1769 | dma_pool_free(ci->qh_pool, mEp->qh.ptr, mEp->qh.dma); | ||
1770 | } | ||
1771 | 1794 | ||
1772 | dma_pool_destroy(ci->td_pool); | 1795 | dma_pool_destroy(ci->td_pool); |
1773 | dma_pool_destroy(ci->qh_pool); | 1796 | dma_pool_destroy(ci->qh_pool); |
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 65a55abb791f..5f0cb417b736 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -109,12 +109,14 @@ static struct usb_driver wdm_driver; | |||
109 | /* return intfdata if we own the interface, else look up intf in the list */ | 109 | /* return intfdata if we own the interface, else look up intf in the list */ |
110 | static struct wdm_device *wdm_find_device(struct usb_interface *intf) | 110 | static struct wdm_device *wdm_find_device(struct usb_interface *intf) |
111 | { | 111 | { |
112 | struct wdm_device *desc = NULL; | 112 | struct wdm_device *desc; |
113 | 113 | ||
114 | spin_lock(&wdm_device_list_lock); | 114 | spin_lock(&wdm_device_list_lock); |
115 | list_for_each_entry(desc, &wdm_device_list, device_list) | 115 | list_for_each_entry(desc, &wdm_device_list, device_list) |
116 | if (desc->intf == intf) | 116 | if (desc->intf == intf) |
117 | break; | 117 | goto found; |
118 | desc = NULL; | ||
119 | found: | ||
118 | spin_unlock(&wdm_device_list_lock); | 120 | spin_unlock(&wdm_device_list_lock); |
119 | 121 | ||
120 | return desc; | 122 | return desc; |
@@ -122,12 +124,14 @@ static struct wdm_device *wdm_find_device(struct usb_interface *intf) | |||
122 | 124 | ||
123 | static struct wdm_device *wdm_find_device_by_minor(int minor) | 125 | static struct wdm_device *wdm_find_device_by_minor(int minor) |
124 | { | 126 | { |
125 | struct wdm_device *desc = NULL; | 127 | struct wdm_device *desc; |
126 | 128 | ||
127 | spin_lock(&wdm_device_list_lock); | 129 | spin_lock(&wdm_device_list_lock); |
128 | list_for_each_entry(desc, &wdm_device_list, device_list) | 130 | list_for_each_entry(desc, &wdm_device_list, device_list) |
129 | if (desc->intf->minor == minor) | 131 | if (desc->intf->minor == minor) |
130 | break; | 132 | goto found; |
133 | desc = NULL; | ||
134 | found: | ||
131 | spin_unlock(&wdm_device_list_lock); | 135 | spin_unlock(&wdm_device_list_lock); |
132 | 136 | ||
133 | return desc; | 137 | return desc; |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index f15501f4c585..e77a8e8eaa23 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -71,6 +71,10 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
71 | { USB_DEVICE(0x04b4, 0x0526), .driver_info = | 71 | { USB_DEVICE(0x04b4, 0x0526), .driver_info = |
72 | USB_QUIRK_CONFIG_INTF_STRINGS }, | 72 | USB_QUIRK_CONFIG_INTF_STRINGS }, |
73 | 73 | ||
74 | /* Microchip Joss Optical infrared touchboard device */ | ||
75 | { USB_DEVICE(0x04d8, 0x000c), .driver_info = | ||
76 | USB_QUIRK_CONFIG_INTF_STRINGS }, | ||
77 | |||
74 | /* Samsung Android phone modem - ID conflict with SPH-I500 */ | 78 | /* Samsung Android phone modem - ID conflict with SPH-I500 */ |
75 | { USB_DEVICE(0x04e8, 0x6601), .driver_info = | 79 | { USB_DEVICE(0x04e8, 0x6601), .driver_info = |
76 | USB_QUIRK_CONFIG_INTF_STRINGS }, | 80 | USB_QUIRK_CONFIG_INTF_STRINGS }, |
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index c34452a7304f..a68ff53124dc 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
@@ -436,16 +436,21 @@ static int __devinit dwc3_probe(struct platform_device *pdev) | |||
436 | dev_err(dev, "missing IRQ\n"); | 436 | dev_err(dev, "missing IRQ\n"); |
437 | return -ENODEV; | 437 | return -ENODEV; |
438 | } | 438 | } |
439 | dwc->xhci_resources[1] = *res; | 439 | dwc->xhci_resources[1].start = res->start; |
440 | dwc->xhci_resources[1].end = res->end; | ||
441 | dwc->xhci_resources[1].flags = res->flags; | ||
442 | dwc->xhci_resources[1].name = res->name; | ||
440 | 443 | ||
441 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 444 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
442 | if (!res) { | 445 | if (!res) { |
443 | dev_err(dev, "missing memory resource\n"); | 446 | dev_err(dev, "missing memory resource\n"); |
444 | return -ENODEV; | 447 | return -ENODEV; |
445 | } | 448 | } |
446 | dwc->xhci_resources[0] = *res; | 449 | dwc->xhci_resources[0].start = res->start; |
447 | dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + | 450 | dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + |
448 | DWC3_XHCI_REGS_END; | 451 | DWC3_XHCI_REGS_END; |
452 | dwc->xhci_resources[0].flags = res->flags; | ||
453 | dwc->xhci_resources[0].name = res->name; | ||
449 | 454 | ||
450 | /* | 455 | /* |
451 | * Request memory region but exclude xHCI regs, | 456 | * Request memory region but exclude xHCI regs, |
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 9b94886b66e5..e4d5ca86b9da 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c | |||
@@ -720,7 +720,6 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, | |||
720 | transferred = min_t(u32, ur->length, | 720 | transferred = min_t(u32, ur->length, |
721 | transfer_size - length); | 721 | transfer_size - length); |
722 | memcpy(ur->buf, dwc->ep0_bounce, transferred); | 722 | memcpy(ur->buf, dwc->ep0_bounce, transferred); |
723 | dwc->ep0_bounced = false; | ||
724 | } else { | 723 | } else { |
725 | transferred = ur->length - length; | 724 | transferred = ur->length - length; |
726 | } | 725 | } |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 58fdfad96b4d..c2813c2b005a 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -263,8 +263,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | |||
263 | if (req->request.status == -EINPROGRESS) | 263 | if (req->request.status == -EINPROGRESS) |
264 | req->request.status = status; | 264 | req->request.status = status; |
265 | 265 | ||
266 | usb_gadget_unmap_request(&dwc->gadget, &req->request, | 266 | if (dwc->ep0_bounced && dep->number == 0) |
267 | req->direction); | 267 | dwc->ep0_bounced = false; |
268 | else | ||
269 | usb_gadget_unmap_request(&dwc->gadget, &req->request, | ||
270 | req->direction); | ||
268 | 271 | ||
269 | dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", | 272 | dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", |
270 | req, dep->name, req->request.actual, | 273 | req, dep->name, req->request.actual, |
@@ -1026,6 +1029,7 @@ static void __dwc3_gadget_start_isoc(struct dwc3 *dwc, | |||
1026 | if (list_empty(&dep->request_list)) { | 1029 | if (list_empty(&dep->request_list)) { |
1027 | dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n", | 1030 | dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n", |
1028 | dep->name); | 1031 | dep->name); |
1032 | dep->flags |= DWC3_EP_PENDING_REQUEST; | ||
1029 | return; | 1033 | return; |
1030 | } | 1034 | } |
1031 | 1035 | ||
@@ -1089,6 +1093,17 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
1089 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { | 1093 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { |
1090 | int ret; | 1094 | int ret; |
1091 | 1095 | ||
1096 | /* | ||
1097 | * If xfernotready is already elapsed and it is a case | ||
1098 | * of isoc transfer, then issue END TRANSFER, so that | ||
1099 | * you can receive xfernotready again and can have | ||
1100 | * notion of current microframe. | ||
1101 | */ | ||
1102 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | ||
1103 | dwc3_stop_active_transfer(dwc, dep->number); | ||
1104 | return 0; | ||
1105 | } | ||
1106 | |||
1092 | ret = __dwc3_gadget_kick_transfer(dep, 0, true); | 1107 | ret = __dwc3_gadget_kick_transfer(dep, 0, true); |
1093 | if (ret && ret != -EBUSY) { | 1108 | if (ret && ret != -EBUSY) { |
1094 | struct dwc3 *dwc = dep->dwc; | 1109 | struct dwc3 *dwc = dep->dwc; |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index c9e66dfb02e6..1e35963bd4ed 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -475,8 +475,7 @@ static int at91_ep_enable(struct usb_ep *_ep, | |||
475 | unsigned long flags; | 475 | unsigned long flags; |
476 | 476 | ||
477 | if (!_ep || !ep | 477 | if (!_ep || !ep |
478 | || !desc || ep->ep.desc | 478 | || !desc || _ep->name == ep0name |
479 | || _ep->name == ep0name | ||
480 | || desc->bDescriptorType != USB_DT_ENDPOINT | 479 | || desc->bDescriptorType != USB_DT_ENDPOINT |
481 | || (maxpacket = usb_endpoint_maxp(desc)) == 0 | 480 | || (maxpacket = usb_endpoint_maxp(desc)) == 0 |
482 | || maxpacket > ep->maxpacket) { | 481 | || maxpacket > ep->maxpacket) { |
@@ -530,7 +529,6 @@ ok: | |||
530 | tmp |= AT91_UDP_EPEDS; | 529 | tmp |= AT91_UDP_EPEDS; |
531 | __raw_writel(tmp, ep->creg); | 530 | __raw_writel(tmp, ep->creg); |
532 | 531 | ||
533 | ep->ep.desc = desc; | ||
534 | ep->ep.maxpacket = maxpacket; | 532 | ep->ep.maxpacket = maxpacket; |
535 | 533 | ||
536 | /* | 534 | /* |
@@ -1635,7 +1633,6 @@ static int at91_start(struct usb_gadget *gadget, | |||
1635 | udc->driver = driver; | 1633 | udc->driver = driver; |
1636 | udc->gadget.dev.driver = &driver->driver; | 1634 | udc->gadget.dev.driver = &driver->driver; |
1637 | udc->gadget.dev.of_node = udc->pdev->dev.of_node; | 1635 | udc->gadget.dev.of_node = udc->pdev->dev.of_node; |
1638 | dev_set_drvdata(&udc->gadget.dev, &driver->driver); | ||
1639 | udc->enabled = 1; | 1636 | udc->enabled = 1; |
1640 | udc->selfpowered = 1; | 1637 | udc->selfpowered = 1; |
1641 | 1638 | ||
@@ -1656,7 +1653,6 @@ static int at91_stop(struct usb_gadget *gadget, | |||
1656 | spin_unlock_irqrestore(&udc->lock, flags); | 1653 | spin_unlock_irqrestore(&udc->lock, flags); |
1657 | 1654 | ||
1658 | udc->gadget.dev.driver = NULL; | 1655 | udc->gadget.dev.driver = NULL; |
1659 | dev_set_drvdata(&udc->gadget.dev, NULL); | ||
1660 | udc->driver = NULL; | 1656 | udc->driver = NULL; |
1661 | 1657 | ||
1662 | DBG("unbound from %s\n", driver->driver.name); | 1658 | DBG("unbound from %s\n", driver->driver.name); |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index b799106027ad..afdbb1cbf5d9 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -1916,6 +1916,27 @@ done: | |||
1916 | return retval; | 1916 | return retval; |
1917 | } | 1917 | } |
1918 | 1918 | ||
1919 | /* usb 3.0 root hub device descriptor */ | ||
1920 | struct { | ||
1921 | struct usb_bos_descriptor bos; | ||
1922 | struct usb_ss_cap_descriptor ss_cap; | ||
1923 | } __packed usb3_bos_desc = { | ||
1924 | |||
1925 | .bos = { | ||
1926 | .bLength = USB_DT_BOS_SIZE, | ||
1927 | .bDescriptorType = USB_DT_BOS, | ||
1928 | .wTotalLength = cpu_to_le16(sizeof(usb3_bos_desc)), | ||
1929 | .bNumDeviceCaps = 1, | ||
1930 | }, | ||
1931 | .ss_cap = { | ||
1932 | .bLength = USB_DT_USB_SS_CAP_SIZE, | ||
1933 | .bDescriptorType = USB_DT_DEVICE_CAPABILITY, | ||
1934 | .bDevCapabilityType = USB_SS_CAP_TYPE, | ||
1935 | .wSpeedSupported = cpu_to_le16(USB_5GBPS_OPERATION), | ||
1936 | .bFunctionalitySupport = ilog2(USB_5GBPS_OPERATION), | ||
1937 | }, | ||
1938 | }; | ||
1939 | |||
1919 | static inline void | 1940 | static inline void |
1920 | ss_hub_descriptor(struct usb_hub_descriptor *desc) | 1941 | ss_hub_descriptor(struct usb_hub_descriptor *desc) |
1921 | { | 1942 | { |
@@ -2006,6 +2027,18 @@ static int dummy_hub_control( | |||
2006 | else | 2027 | else |
2007 | hub_descriptor((struct usb_hub_descriptor *) buf); | 2028 | hub_descriptor((struct usb_hub_descriptor *) buf); |
2008 | break; | 2029 | break; |
2030 | |||
2031 | case DeviceRequest | USB_REQ_GET_DESCRIPTOR: | ||
2032 | if (hcd->speed != HCD_USB3) | ||
2033 | goto error; | ||
2034 | |||
2035 | if ((wValue >> 8) != USB_DT_BOS) | ||
2036 | goto error; | ||
2037 | |||
2038 | memcpy(buf, &usb3_bos_desc, sizeof(usb3_bos_desc)); | ||
2039 | retval = sizeof(usb3_bos_desc); | ||
2040 | break; | ||
2041 | |||
2009 | case GetHubStatus: | 2042 | case GetHubStatus: |
2010 | *(__le32 *) buf = cpu_to_le32(0); | 2043 | *(__le32 *) buf = cpu_to_le32(0); |
2011 | break; | 2044 | break; |
@@ -2503,10 +2536,8 @@ static int dummy_hcd_probe(struct platform_device *pdev) | |||
2503 | hs_hcd->has_tt = 1; | 2536 | hs_hcd->has_tt = 1; |
2504 | 2537 | ||
2505 | retval = usb_add_hcd(hs_hcd, 0, 0); | 2538 | retval = usb_add_hcd(hs_hcd, 0, 0); |
2506 | if (retval != 0) { | 2539 | if (retval) |
2507 | usb_put_hcd(hs_hcd); | 2540 | goto put_usb2_hcd; |
2508 | return retval; | ||
2509 | } | ||
2510 | 2541 | ||
2511 | if (mod_data.is_super_speed) { | 2542 | if (mod_data.is_super_speed) { |
2512 | ss_hcd = usb_create_shared_hcd(&dummy_hcd, &pdev->dev, | 2543 | ss_hcd = usb_create_shared_hcd(&dummy_hcd, &pdev->dev, |
@@ -2525,6 +2556,8 @@ static int dummy_hcd_probe(struct platform_device *pdev) | |||
2525 | put_usb3_hcd: | 2556 | put_usb3_hcd: |
2526 | usb_put_hcd(ss_hcd); | 2557 | usb_put_hcd(ss_hcd); |
2527 | dealloc_usb2_hcd: | 2558 | dealloc_usb2_hcd: |
2559 | usb_remove_hcd(hs_hcd); | ||
2560 | put_usb2_hcd: | ||
2528 | usb_put_hcd(hs_hcd); | 2561 | usb_put_hcd(hs_hcd); |
2529 | the_controller.hs_hcd = the_controller.ss_hcd = NULL; | 2562 | the_controller.hs_hcd = the_controller.ss_hcd = NULL; |
2530 | return retval; | 2563 | return retval; |
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 8adc79d1b402..829aba75a6df 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
@@ -34,11 +34,15 @@ | |||
34 | /* Debugging ****************************************************************/ | 34 | /* Debugging ****************************************************************/ |
35 | 35 | ||
36 | #ifdef VERBOSE_DEBUG | 36 | #ifdef VERBOSE_DEBUG |
37 | #ifndef pr_vdebug | ||
37 | # define pr_vdebug pr_debug | 38 | # define pr_vdebug pr_debug |
39 | #endif /* pr_vdebug */ | ||
38 | # define ffs_dump_mem(prefix, ptr, len) \ | 40 | # define ffs_dump_mem(prefix, ptr, len) \ |
39 | print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len) | 41 | print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len) |
40 | #else | 42 | #else |
43 | #ifndef pr_vdebug | ||
41 | # define pr_vdebug(...) do { } while (0) | 44 | # define pr_vdebug(...) do { } while (0) |
45 | #endif /* pr_vdebug */ | ||
42 | # define ffs_dump_mem(prefix, ptr, len) do { } while (0) | 46 | # define ffs_dump_mem(prefix, ptr, len) do { } while (0) |
43 | #endif /* VERBOSE_DEBUG */ | 47 | #endif /* VERBOSE_DEBUG */ |
44 | 48 | ||
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index b13e0bb5f5b8..0bb617e1dda2 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -3599,6 +3599,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3599 | 3599 | ||
3600 | if (hsotg->num_of_eps == 0) { | 3600 | if (hsotg->num_of_eps == 0) { |
3601 | dev_err(dev, "wrong number of EPs (zero)\n"); | 3601 | dev_err(dev, "wrong number of EPs (zero)\n"); |
3602 | ret = -EINVAL; | ||
3602 | goto err_supplies; | 3603 | goto err_supplies; |
3603 | } | 3604 | } |
3604 | 3605 | ||
@@ -3606,6 +3607,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3606 | GFP_KERNEL); | 3607 | GFP_KERNEL); |
3607 | if (!eps) { | 3608 | if (!eps) { |
3608 | dev_err(dev, "cannot get memory\n"); | 3609 | dev_err(dev, "cannot get memory\n"); |
3610 | ret = -ENOMEM; | ||
3609 | goto err_supplies; | 3611 | goto err_supplies; |
3610 | } | 3612 | } |
3611 | 3613 | ||
@@ -3622,6 +3624,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3622 | GFP_KERNEL); | 3624 | GFP_KERNEL); |
3623 | if (!hsotg->ctrl_req) { | 3625 | if (!hsotg->ctrl_req) { |
3624 | dev_err(dev, "failed to allocate ctrl req\n"); | 3626 | dev_err(dev, "failed to allocate ctrl req\n"); |
3627 | ret = -ENOMEM; | ||
3625 | goto err_ep_mem; | 3628 | goto err_ep_mem; |
3626 | } | 3629 | } |
3627 | 3630 | ||
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 5b3f5fffea92..da6d479ff9a6 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c | |||
@@ -132,11 +132,15 @@ static unsigned n_ports; | |||
132 | 132 | ||
133 | 133 | ||
134 | #ifdef VERBOSE_DEBUG | 134 | #ifdef VERBOSE_DEBUG |
135 | #ifndef pr_vdebug | ||
135 | #define pr_vdebug(fmt, arg...) \ | 136 | #define pr_vdebug(fmt, arg...) \ |
136 | pr_debug(fmt, ##arg) | 137 | pr_debug(fmt, ##arg) |
138 | #endif /* pr_vdebug */ | ||
137 | #else | 139 | #else |
140 | #ifndef pr_vdebig | ||
138 | #define pr_vdebug(fmt, arg...) \ | 141 | #define pr_vdebug(fmt, arg...) \ |
139 | ({ if (0) pr_debug(fmt, ##arg); }) | 142 | ({ if (0) pr_debug(fmt, ##arg); }) |
143 | #endif /* pr_vdebug */ | ||
140 | #endif | 144 | #endif |
141 | 145 | ||
142 | /*-------------------------------------------------------------------------*/ | 146 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 9bc39ca460c8..4b66374bdc8e 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -128,9 +128,17 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
128 | else { | 128 | else { |
129 | qtd = list_entry (qh->qtd_list.next, | 129 | qtd = list_entry (qh->qtd_list.next, |
130 | struct ehci_qtd, qtd_list); | 130 | struct ehci_qtd, qtd_list); |
131 | /* first qtd may already be partially processed */ | 131 | /* |
132 | if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) | 132 | * first qtd may already be partially processed. |
133 | * If we come here during unlink, the QH overlay region | ||
134 | * might have reference to the just unlinked qtd. The | ||
135 | * qtd is updated in qh_completions(). Update the QH | ||
136 | * overlay here. | ||
137 | */ | ||
138 | if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) { | ||
139 | qh->hw->hw_qtd_next = qtd->hw_next; | ||
133 | qtd = NULL; | 140 | qtd = NULL; |
141 | } | ||
134 | } | 142 | } |
135 | 143 | ||
136 | if (qtd) | 144 | if (qtd) |
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index a665b3eaa746..aaa8d2bce217 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -570,6 +570,16 @@ static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev) | |||
570 | 570 | ||
571 | if (pdata) { | 571 | if (pdata) { |
572 | at91_for_each_port(i) { | 572 | at91_for_each_port(i) { |
573 | /* | ||
574 | * do not configure PIO if not in relation with | ||
575 | * real USB port on board | ||
576 | */ | ||
577 | if (i >= pdata->ports) { | ||
578 | pdata->vbus_pin[i] = -EINVAL; | ||
579 | pdata->overcurrent_pin[i] = -EINVAL; | ||
580 | break; | ||
581 | } | ||
582 | |||
573 | if (!gpio_is_valid(pdata->vbus_pin[i])) | 583 | if (!gpio_is_valid(pdata->vbus_pin[i])) |
574 | continue; | 584 | continue; |
575 | gpio = pdata->vbus_pin[i]; | 585 | gpio = pdata->vbus_pin[i]; |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index c5e9e4a76f14..966d1484ee79 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -75,7 +75,9 @@ | |||
75 | #define NB_PIF0_PWRDOWN_1 0x01100013 | 75 | #define NB_PIF0_PWRDOWN_1 0x01100013 |
76 | 76 | ||
77 | #define USB_INTEL_XUSB2PR 0xD0 | 77 | #define USB_INTEL_XUSB2PR 0xD0 |
78 | #define USB_INTEL_USB2PRM 0xD4 | ||
78 | #define USB_INTEL_USB3_PSSEN 0xD8 | 79 | #define USB_INTEL_USB3_PSSEN 0xD8 |
80 | #define USB_INTEL_USB3PRM 0xDC | ||
79 | 81 | ||
80 | static struct amd_chipset_info { | 82 | static struct amd_chipset_info { |
81 | struct pci_dev *nb_dev; | 83 | struct pci_dev *nb_dev; |
@@ -772,10 +774,18 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) | |||
772 | return; | 774 | return; |
773 | } | 775 | } |
774 | 776 | ||
775 | ports_available = 0xffffffff; | 777 | /* Read USB3PRM, the USB 3.0 Port Routing Mask Register |
778 | * Indicate the ports that can be changed from OS. | ||
779 | */ | ||
780 | pci_read_config_dword(xhci_pdev, USB_INTEL_USB3PRM, | ||
781 | &ports_available); | ||
782 | |||
783 | dev_dbg(&xhci_pdev->dev, "Configurable ports to enable SuperSpeed: 0x%x\n", | ||
784 | ports_available); | ||
785 | |||
776 | /* Write USB3_PSSEN, the USB 3.0 Port SuperSpeed Enable | 786 | /* Write USB3_PSSEN, the USB 3.0 Port SuperSpeed Enable |
777 | * Register, to turn on SuperSpeed terminations for all | 787 | * Register, to turn on SuperSpeed terminations for the |
778 | * available ports. | 788 | * switchable ports. |
779 | */ | 789 | */ |
780 | pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, | 790 | pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, |
781 | cpu_to_le32(ports_available)); | 791 | cpu_to_le32(ports_available)); |
@@ -785,7 +795,16 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) | |||
785 | dev_dbg(&xhci_pdev->dev, "USB 3.0 ports that are now enabled " | 795 | dev_dbg(&xhci_pdev->dev, "USB 3.0 ports that are now enabled " |
786 | "under xHCI: 0x%x\n", ports_available); | 796 | "under xHCI: 0x%x\n", ports_available); |
787 | 797 | ||
788 | ports_available = 0xffffffff; | 798 | /* Read XUSB2PRM, xHCI USB 2.0 Port Routing Mask Register |
799 | * Indicate the USB 2.0 ports to be controlled by the xHCI host. | ||
800 | */ | ||
801 | |||
802 | pci_read_config_dword(xhci_pdev, USB_INTEL_USB2PRM, | ||
803 | &ports_available); | ||
804 | |||
805 | dev_dbg(&xhci_pdev->dev, "Configurable USB 2.0 ports to hand over to xCHI: 0x%x\n", | ||
806 | ports_available); | ||
807 | |||
789 | /* Write XUSB2PR, the xHC USB 2.0 Port Routing Register, to | 808 | /* Write XUSB2PR, the xHC USB 2.0 Port Routing Register, to |
790 | * switch the USB 2.0 power and data lines over to the xHCI | 809 | * switch the USB 2.0 power and data lines over to the xHCI |
791 | * host. | 810 | * host. |
@@ -822,12 +841,12 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | |||
822 | void __iomem *op_reg_base; | 841 | void __iomem *op_reg_base; |
823 | u32 val; | 842 | u32 val; |
824 | int timeout; | 843 | int timeout; |
844 | int len = pci_resource_len(pdev, 0); | ||
825 | 845 | ||
826 | if (!mmio_resource_enabled(pdev, 0)) | 846 | if (!mmio_resource_enabled(pdev, 0)) |
827 | return; | 847 | return; |
828 | 848 | ||
829 | base = ioremap_nocache(pci_resource_start(pdev, 0), | 849 | base = ioremap_nocache(pci_resource_start(pdev, 0), len); |
830 | pci_resource_len(pdev, 0)); | ||
831 | if (base == NULL) | 850 | if (base == NULL) |
832 | return; | 851 | return; |
833 | 852 | ||
@@ -837,9 +856,17 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | |||
837 | */ | 856 | */ |
838 | ext_cap_offset = xhci_find_next_cap_offset(base, XHCI_HCC_PARAMS_OFFSET); | 857 | ext_cap_offset = xhci_find_next_cap_offset(base, XHCI_HCC_PARAMS_OFFSET); |
839 | do { | 858 | do { |
859 | if ((ext_cap_offset + sizeof(val)) > len) { | ||
860 | /* We're reading garbage from the controller */ | ||
861 | dev_warn(&pdev->dev, | ||
862 | "xHCI controller failing to respond"); | ||
863 | return; | ||
864 | } | ||
865 | |||
840 | if (!ext_cap_offset) | 866 | if (!ext_cap_offset) |
841 | /* We've reached the end of the extended capabilities */ | 867 | /* We've reached the end of the extended capabilities */ |
842 | goto hc_init; | 868 | goto hc_init; |
869 | |||
843 | val = readl(base + ext_cap_offset); | 870 | val = readl(base + ext_cap_offset); |
844 | if (XHCI_EXT_CAPS_ID(val) == XHCI_EXT_CAPS_LEGACY) | 871 | if (XHCI_EXT_CAPS_ID(val) == XHCI_EXT_CAPS_LEGACY) |
845 | break; | 872 | break; |
@@ -870,9 +897,10 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | |||
870 | /* Disable any BIOS SMIs and clear all SMI events*/ | 897 | /* Disable any BIOS SMIs and clear all SMI events*/ |
871 | writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); | 898 | writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); |
872 | 899 | ||
900 | hc_init: | ||
873 | if (usb_is_intel_switchable_xhci(pdev)) | 901 | if (usb_is_intel_switchable_xhci(pdev)) |
874 | usb_enable_xhci_ports(pdev); | 902 | usb_enable_xhci_ports(pdev); |
875 | hc_init: | 903 | |
876 | op_reg_base = base + XHCI_HC_LENGTH(readl(base)); | 904 | op_reg_base = base + XHCI_HC_LENGTH(readl(base)); |
877 | 905 | ||
878 | /* Wait for the host controller to be ready before writing any | 906 | /* Wait for the host controller to be ready before writing any |
diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index ef004a5de20f..7f69a39163ce 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h | |||
@@ -15,6 +15,7 @@ void usb_disable_xhci_ports(struct pci_dev *xhci_pdev); | |||
15 | static inline void usb_amd_quirk_pll_disable(void) {} | 15 | static inline void usb_amd_quirk_pll_disable(void) {} |
16 | static inline void usb_amd_quirk_pll_enable(void) {} | 16 | static inline void usb_amd_quirk_pll_enable(void) {} |
17 | static inline void usb_amd_dev_put(void) {} | 17 | static inline void usb_amd_dev_put(void) {} |
18 | static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {} | ||
18 | #endif /* CONFIG_PCI */ | 19 | #endif /* CONFIG_PCI */ |
19 | 20 | ||
20 | #endif /* __LINUX_USB_PCI_QUIRKS_H */ | 21 | #endif /* __LINUX_USB_PCI_QUIRKS_H */ |
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 74bfc868b7ad..d5eb357aa5c4 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -493,11 +493,48 @@ static void xhci_hub_report_link_state(u32 *status, u32 status_reg) | |||
493 | * when this bit is set. | 493 | * when this bit is set. |
494 | */ | 494 | */ |
495 | pls |= USB_PORT_STAT_CONNECTION; | 495 | pls |= USB_PORT_STAT_CONNECTION; |
496 | } else { | ||
497 | /* | ||
498 | * If CAS bit isn't set but the Port is already at | ||
499 | * Compliance Mode, fake a connection so the USB core | ||
500 | * notices the Compliance state and resets the port. | ||
501 | * This resolves an issue generated by the SN65LVPE502CP | ||
502 | * in which sometimes the port enters compliance mode | ||
503 | * caused by a delay on the host-device negotiation. | ||
504 | */ | ||
505 | if (pls == USB_SS_PORT_LS_COMP_MOD) | ||
506 | pls |= USB_PORT_STAT_CONNECTION; | ||
496 | } | 507 | } |
508 | |||
497 | /* update status field */ | 509 | /* update status field */ |
498 | *status |= pls; | 510 | *status |= pls; |
499 | } | 511 | } |
500 | 512 | ||
513 | /* | ||
514 | * Function for Compliance Mode Quirk. | ||
515 | * | ||
516 | * This Function verifies if all xhc USB3 ports have entered U0, if so, | ||
517 | * the compliance mode timer is deleted. A port won't enter | ||
518 | * compliance mode if it has previously entered U0. | ||
519 | */ | ||
520 | void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, u16 wIndex) | ||
521 | { | ||
522 | u32 all_ports_seen_u0 = ((1 << xhci->num_usb3_ports)-1); | ||
523 | bool port_in_u0 = ((status & PORT_PLS_MASK) == XDEV_U0); | ||
524 | |||
525 | if (!(xhci->quirks & XHCI_COMP_MODE_QUIRK)) | ||
526 | return; | ||
527 | |||
528 | if ((xhci->port_status_u0 != all_ports_seen_u0) && port_in_u0) { | ||
529 | xhci->port_status_u0 |= 1 << wIndex; | ||
530 | if (xhci->port_status_u0 == all_ports_seen_u0) { | ||
531 | del_timer_sync(&xhci->comp_mode_recovery_timer); | ||
532 | xhci_dbg(xhci, "All USB3 ports have entered U0 already!\n"); | ||
533 | xhci_dbg(xhci, "Compliance Mode Recovery Timer Deleted.\n"); | ||
534 | } | ||
535 | } | ||
536 | } | ||
537 | |||
501 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | 538 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, |
502 | u16 wIndex, char *buf, u16 wLength) | 539 | u16 wIndex, char *buf, u16 wLength) |
503 | { | 540 | { |
@@ -651,6 +688,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
651 | /* Update Port Link State for super speed ports*/ | 688 | /* Update Port Link State for super speed ports*/ |
652 | if (hcd->speed == HCD_USB3) { | 689 | if (hcd->speed == HCD_USB3) { |
653 | xhci_hub_report_link_state(&status, temp); | 690 | xhci_hub_report_link_state(&status, temp); |
691 | /* | ||
692 | * Verify if all USB3 Ports Have entered U0 already. | ||
693 | * Delete Compliance Mode Timer if so. | ||
694 | */ | ||
695 | xhci_del_comp_mod_timer(xhci, temp, wIndex); | ||
654 | } | 696 | } |
655 | if (bus_state->port_c_suspend & (1 << wIndex)) | 697 | if (bus_state->port_c_suspend & (1 << wIndex)) |
656 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | 698 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; |
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 689bc18b051d..df90fe51b4aa 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c | |||
@@ -118,7 +118,7 @@ static int xhci_plat_probe(struct platform_device *pdev) | |||
118 | goto put_hcd; | 118 | goto put_hcd; |
119 | } | 119 | } |
120 | 120 | ||
121 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | 121 | hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); |
122 | if (!hcd->regs) { | 122 | if (!hcd->regs) { |
123 | dev_dbg(&pdev->dev, "error mapping memory\n"); | 123 | dev_dbg(&pdev->dev, "error mapping memory\n"); |
124 | ret = -EFAULT; | 124 | ret = -EFAULT; |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index c59d5b5b6c7d..6ece0ed288d4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/dmi.h> | ||
29 | 30 | ||
30 | #include "xhci.h" | 31 | #include "xhci.h" |
31 | 32 | ||
@@ -398,6 +399,95 @@ static void xhci_msix_sync_irqs(struct xhci_hcd *xhci) | |||
398 | 399 | ||
399 | #endif | 400 | #endif |
400 | 401 | ||
402 | static void compliance_mode_recovery(unsigned long arg) | ||
403 | { | ||
404 | struct xhci_hcd *xhci; | ||
405 | struct usb_hcd *hcd; | ||
406 | u32 temp; | ||
407 | int i; | ||
408 | |||
409 | xhci = (struct xhci_hcd *)arg; | ||
410 | |||
411 | for (i = 0; i < xhci->num_usb3_ports; i++) { | ||
412 | temp = xhci_readl(xhci, xhci->usb3_ports[i]); | ||
413 | if ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD) { | ||
414 | /* | ||
415 | * Compliance Mode Detected. Letting USB Core | ||
416 | * handle the Warm Reset | ||
417 | */ | ||
418 | xhci_dbg(xhci, "Compliance Mode Detected->Port %d!\n", | ||
419 | i + 1); | ||
420 | xhci_dbg(xhci, "Attempting Recovery routine!\n"); | ||
421 | hcd = xhci->shared_hcd; | ||
422 | |||
423 | if (hcd->state == HC_STATE_SUSPENDED) | ||
424 | usb_hcd_resume_root_hub(hcd); | ||
425 | |||
426 | usb_hcd_poll_rh_status(hcd); | ||
427 | } | ||
428 | } | ||
429 | |||
430 | if (xhci->port_status_u0 != ((1 << xhci->num_usb3_ports)-1)) | ||
431 | mod_timer(&xhci->comp_mode_recovery_timer, | ||
432 | jiffies + msecs_to_jiffies(COMP_MODE_RCVRY_MSECS)); | ||
433 | } | ||
434 | |||
435 | /* | ||
436 | * Quirk to work around issue generated by the SN65LVPE502CP USB3.0 re-driver | ||
437 | * that causes ports behind that hardware to enter compliance mode sometimes. | ||
438 | * The quirk creates a timer that polls every 2 seconds the link state of | ||
439 | * each host controller's port and recovers it by issuing a Warm reset | ||
440 | * if Compliance mode is detected, otherwise the port will become "dead" (no | ||
441 | * device connections or disconnections will be detected anymore). Becasue no | ||
442 | * status event is generated when entering compliance mode (per xhci spec), | ||
443 | * this quirk is needed on systems that have the failing hardware installed. | ||
444 | */ | ||
445 | static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci) | ||
446 | { | ||
447 | xhci->port_status_u0 = 0; | ||
448 | init_timer(&xhci->comp_mode_recovery_timer); | ||
449 | |||
450 | xhci->comp_mode_recovery_timer.data = (unsigned long) xhci; | ||
451 | xhci->comp_mode_recovery_timer.function = compliance_mode_recovery; | ||
452 | xhci->comp_mode_recovery_timer.expires = jiffies + | ||
453 | msecs_to_jiffies(COMP_MODE_RCVRY_MSECS); | ||
454 | |||
455 | set_timer_slack(&xhci->comp_mode_recovery_timer, | ||
456 | msecs_to_jiffies(COMP_MODE_RCVRY_MSECS)); | ||
457 | add_timer(&xhci->comp_mode_recovery_timer); | ||
458 | xhci_dbg(xhci, "Compliance Mode Recovery Timer Initialized.\n"); | ||
459 | } | ||
460 | |||
461 | /* | ||
462 | * This function identifies the systems that have installed the SN65LVPE502CP | ||
463 | * USB3.0 re-driver and that need the Compliance Mode Quirk. | ||
464 | * Systems: | ||
465 | * Vendor: Hewlett-Packard -> System Models: Z420, Z620 and Z820 | ||
466 | */ | ||
467 | static bool compliance_mode_recovery_timer_quirk_check(void) | ||
468 | { | ||
469 | const char *dmi_product_name, *dmi_sys_vendor; | ||
470 | |||
471 | dmi_product_name = dmi_get_system_info(DMI_PRODUCT_NAME); | ||
472 | dmi_sys_vendor = dmi_get_system_info(DMI_SYS_VENDOR); | ||
473 | |||
474 | if (!(strstr(dmi_sys_vendor, "Hewlett-Packard"))) | ||
475 | return false; | ||
476 | |||
477 | if (strstr(dmi_product_name, "Z420") || | ||
478 | strstr(dmi_product_name, "Z620") || | ||
479 | strstr(dmi_product_name, "Z820")) | ||
480 | return true; | ||
481 | |||
482 | return false; | ||
483 | } | ||
484 | |||
485 | static int xhci_all_ports_seen_u0(struct xhci_hcd *xhci) | ||
486 | { | ||
487 | return (xhci->port_status_u0 == ((1 << xhci->num_usb3_ports)-1)); | ||
488 | } | ||
489 | |||
490 | |||
401 | /* | 491 | /* |
402 | * Initialize memory for HCD and xHC (one-time init). | 492 | * Initialize memory for HCD and xHC (one-time init). |
403 | * | 493 | * |
@@ -421,6 +511,12 @@ int xhci_init(struct usb_hcd *hcd) | |||
421 | retval = xhci_mem_init(xhci, GFP_KERNEL); | 511 | retval = xhci_mem_init(xhci, GFP_KERNEL); |
422 | xhci_dbg(xhci, "Finished xhci_init\n"); | 512 | xhci_dbg(xhci, "Finished xhci_init\n"); |
423 | 513 | ||
514 | /* Initializing Compliance Mode Recovery Data If Needed */ | ||
515 | if (compliance_mode_recovery_timer_quirk_check()) { | ||
516 | xhci->quirks |= XHCI_COMP_MODE_QUIRK; | ||
517 | compliance_mode_recovery_timer_init(xhci); | ||
518 | } | ||
519 | |||
424 | return retval; | 520 | return retval; |
425 | } | 521 | } |
426 | 522 | ||
@@ -629,6 +725,11 @@ void xhci_stop(struct usb_hcd *hcd) | |||
629 | del_timer_sync(&xhci->event_ring_timer); | 725 | del_timer_sync(&xhci->event_ring_timer); |
630 | #endif | 726 | #endif |
631 | 727 | ||
728 | /* Deleting Compliance Mode Recovery Timer */ | ||
729 | if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && | ||
730 | (!(xhci_all_ports_seen_u0(xhci)))) | ||
731 | del_timer_sync(&xhci->comp_mode_recovery_timer); | ||
732 | |||
632 | if (xhci->quirks & XHCI_AMD_PLL_FIX) | 733 | if (xhci->quirks & XHCI_AMD_PLL_FIX) |
633 | usb_amd_dev_put(); | 734 | usb_amd_dev_put(); |
634 | 735 | ||
@@ -659,7 +760,7 @@ void xhci_shutdown(struct usb_hcd *hcd) | |||
659 | { | 760 | { |
660 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 761 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
661 | 762 | ||
662 | if (xhci->quirks && XHCI_SPURIOUS_REBOOT) | 763 | if (xhci->quirks & XHCI_SPURIOUS_REBOOT) |
663 | usb_disable_xhci_ports(to_pci_dev(hcd->self.controller)); | 764 | usb_disable_xhci_ports(to_pci_dev(hcd->self.controller)); |
664 | 765 | ||
665 | spin_lock_irq(&xhci->lock); | 766 | spin_lock_irq(&xhci->lock); |
@@ -806,6 +907,16 @@ int xhci_suspend(struct xhci_hcd *xhci) | |||
806 | } | 907 | } |
807 | spin_unlock_irq(&xhci->lock); | 908 | spin_unlock_irq(&xhci->lock); |
808 | 909 | ||
910 | /* | ||
911 | * Deleting Compliance Mode Recovery Timer because the xHCI Host | ||
912 | * is about to be suspended. | ||
913 | */ | ||
914 | if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && | ||
915 | (!(xhci_all_ports_seen_u0(xhci)))) { | ||
916 | del_timer_sync(&xhci->comp_mode_recovery_timer); | ||
917 | xhci_dbg(xhci, "Compliance Mode Recovery Timer Deleted!\n"); | ||
918 | } | ||
919 | |||
809 | /* step 5: remove core well power */ | 920 | /* step 5: remove core well power */ |
810 | /* synchronize irq when using MSI-X */ | 921 | /* synchronize irq when using MSI-X */ |
811 | xhci_msix_sync_irqs(xhci); | 922 | xhci_msix_sync_irqs(xhci); |
@@ -938,6 +1049,16 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
938 | usb_hcd_resume_root_hub(hcd); | 1049 | usb_hcd_resume_root_hub(hcd); |
939 | usb_hcd_resume_root_hub(xhci->shared_hcd); | 1050 | usb_hcd_resume_root_hub(xhci->shared_hcd); |
940 | } | 1051 | } |
1052 | |||
1053 | /* | ||
1054 | * If system is subject to the Quirk, Compliance Mode Timer needs to | ||
1055 | * be re-initialized Always after a system resume. Ports are subject | ||
1056 | * to suffer the Compliance Mode issue again. It doesn't matter if | ||
1057 | * ports have entered previously to U0 before system's suspension. | ||
1058 | */ | ||
1059 | if (xhci->quirks & XHCI_COMP_MODE_QUIRK) | ||
1060 | compliance_mode_recovery_timer_init(xhci); | ||
1061 | |||
941 | return retval; | 1062 | return retval; |
942 | } | 1063 | } |
943 | #endif /* CONFIG_PM */ | 1064 | #endif /* CONFIG_PM */ |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index c713256297ac..1a05908c6673 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1495,6 +1495,7 @@ struct xhci_hcd { | |||
1495 | #define XHCI_LPM_SUPPORT (1 << 11) | 1495 | #define XHCI_LPM_SUPPORT (1 << 11) |
1496 | #define XHCI_INTEL_HOST (1 << 12) | 1496 | #define XHCI_INTEL_HOST (1 << 12) |
1497 | #define XHCI_SPURIOUS_REBOOT (1 << 13) | 1497 | #define XHCI_SPURIOUS_REBOOT (1 << 13) |
1498 | #define XHCI_COMP_MODE_QUIRK (1 << 14) | ||
1498 | unsigned int num_active_eps; | 1499 | unsigned int num_active_eps; |
1499 | unsigned int limit_active_eps; | 1500 | unsigned int limit_active_eps; |
1500 | /* There are two roothubs to keep track of bus suspend info for */ | 1501 | /* There are two roothubs to keep track of bus suspend info for */ |
@@ -1511,6 +1512,11 @@ struct xhci_hcd { | |||
1511 | unsigned sw_lpm_support:1; | 1512 | unsigned sw_lpm_support:1; |
1512 | /* support xHCI 1.0 spec USB2 hardware LPM */ | 1513 | /* support xHCI 1.0 spec USB2 hardware LPM */ |
1513 | unsigned hw_lpm_support:1; | 1514 | unsigned hw_lpm_support:1; |
1515 | /* Compliance Mode Recovery Data */ | ||
1516 | struct timer_list comp_mode_recovery_timer; | ||
1517 | u32 port_status_u0; | ||
1518 | /* Compliance Mode Timer Triggered every 2 seconds */ | ||
1519 | #define COMP_MODE_RCVRY_MSECS 2000 | ||
1514 | }; | 1520 | }; |
1515 | 1521 | ||
1516 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ | 1522 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 4bb717d0bd41..1ae378d5fc6f 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -2049,7 +2049,7 @@ static int musb_urb_enqueue( | |||
2049 | * we only have work to do in the former case. | 2049 | * we only have work to do in the former case. |
2050 | */ | 2050 | */ |
2051 | spin_lock_irqsave(&musb->lock, flags); | 2051 | spin_lock_irqsave(&musb->lock, flags); |
2052 | if (hep->hcpriv) { | 2052 | if (hep->hcpriv || !next_urb(qh)) { |
2053 | /* some concurrent activity submitted another urb to hep... | 2053 | /* some concurrent activity submitted another urb to hep... |
2054 | * odd, rare, error prone, but legal. | 2054 | * odd, rare, error prone, but legal. |
2055 | */ | 2055 | */ |
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 57a608584e16..c1be687e00ec 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c | |||
@@ -388,7 +388,7 @@ dma_controller_create(struct musb *musb, void __iomem *base) | |||
388 | struct platform_device *pdev = to_platform_device(dev); | 388 | struct platform_device *pdev = to_platform_device(dev); |
389 | int irq = platform_get_irq_byname(pdev, "dma"); | 389 | int irq = platform_get_irq_byname(pdev, "dma"); |
390 | 390 | ||
391 | if (irq == 0) { | 391 | if (irq <= 0) { |
392 | dev_err(dev, "No DMA interrupt line!\n"); | 392 | dev_err(dev, "No DMA interrupt line!\n"); |
393 | return NULL; | 393 | return NULL; |
394 | } | 394 | } |
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 1a1bd9cf40c5..341625442377 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
@@ -1215,7 +1215,7 @@ static int __devinit tusb_probe(struct platform_device *pdev) | |||
1215 | ret = platform_device_add(musb); | 1215 | ret = platform_device_add(musb); |
1216 | if (ret) { | 1216 | if (ret) { |
1217 | dev_err(&pdev->dev, "failed to register musb device\n"); | 1217 | dev_err(&pdev->dev, "failed to register musb device\n"); |
1218 | goto err1; | 1218 | goto err2; |
1219 | } | 1219 | } |
1220 | 1220 | ||
1221 | return 0; | 1221 | return 0; |
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index ecd173032fd4..143c4e9e1be4 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c | |||
@@ -818,7 +818,7 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done) | |||
818 | usbhs_pipe_is_dcp(pipe)) | 818 | usbhs_pipe_is_dcp(pipe)) |
819 | goto usbhsf_pio_prepare_push; | 819 | goto usbhsf_pio_prepare_push; |
820 | 820 | ||
821 | if (len % 4) /* 32bit alignment */ | 821 | if (len & 0x7) /* 8byte alignment */ |
822 | goto usbhsf_pio_prepare_push; | 822 | goto usbhsf_pio_prepare_push; |
823 | 823 | ||
824 | if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ | 824 | if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ |
@@ -905,7 +905,7 @@ static int usbhsf_dma_try_pop(struct usbhs_pkt *pkt, int *is_done) | |||
905 | /* use PIO if packet is less than pio_dma_border */ | 905 | /* use PIO if packet is less than pio_dma_border */ |
906 | len = usbhsf_fifo_rcv_len(priv, fifo); | 906 | len = usbhsf_fifo_rcv_len(priv, fifo); |
907 | len = min(pkt->length - pkt->actual, len); | 907 | len = min(pkt->length - pkt->actual, len); |
908 | if (len % 4) /* 32bit alignment */ | 908 | if (len & 0x7) /* 8byte alignment */ |
909 | goto usbhsf_pio_prepare_pop_unselect; | 909 | goto usbhsf_pio_prepare_pop_unselect; |
910 | 910 | ||
911 | if (len < usbhs_get_dparam(priv, pio_dma_border)) | 911 | if (len < usbhs_get_dparam(priv, pio_dma_border)) |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 5620db6469e5..f906b3aec217 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -704,6 +704,7 @@ static struct usb_device_id id_table_combined [] = { | |||
704 | { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, | 704 | { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, |
705 | { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) }, | 705 | { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) }, |
706 | { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, | 706 | { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, |
707 | { USB_DEVICE(FTDI_VID, FTDI_NZR_SEM_USB_PID) }, | ||
707 | { USB_DEVICE(ICOM_VID, ICOM_ID_1_PID) }, | 708 | { USB_DEVICE(ICOM_VID, ICOM_ID_1_PID) }, |
708 | { USB_DEVICE(ICOM_VID, ICOM_OPC_U_UC_PID) }, | 709 | { USB_DEVICE(ICOM_VID, ICOM_OPC_U_UC_PID) }, |
709 | { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C1_PID) }, | 710 | { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C1_PID) }, |
@@ -804,13 +805,32 @@ static struct usb_device_id id_table_combined [] = { | |||
804 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 805 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
805 | { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID), | 806 | { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID), |
806 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 807 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
807 | { USB_DEVICE(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID) }, | 808 | { USB_DEVICE_AND_INTERFACE_INFO(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID, |
809 | USB_CLASS_VENDOR_SPEC, | ||
810 | USB_SUBCLASS_VENDOR_SPEC, 0x00) }, | ||
808 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, | 811 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, |
809 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), | 812 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), |
810 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 813 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
811 | { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, | 814 | { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, |
812 | { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, | 815 | { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, |
816 | { USB_DEVICE(FTDI_VID, PI_C865_PID) }, | ||
817 | { USB_DEVICE(FTDI_VID, PI_C857_PID) }, | ||
818 | { USB_DEVICE(PI_VID, PI_C866_PID) }, | ||
819 | { USB_DEVICE(PI_VID, PI_C663_PID) }, | ||
820 | { USB_DEVICE(PI_VID, PI_C725_PID) }, | ||
821 | { USB_DEVICE(PI_VID, PI_E517_PID) }, | ||
822 | { USB_DEVICE(PI_VID, PI_C863_PID) }, | ||
813 | { USB_DEVICE(PI_VID, PI_E861_PID) }, | 823 | { USB_DEVICE(PI_VID, PI_E861_PID) }, |
824 | { USB_DEVICE(PI_VID, PI_C867_PID) }, | ||
825 | { USB_DEVICE(PI_VID, PI_E609_PID) }, | ||
826 | { USB_DEVICE(PI_VID, PI_E709_PID) }, | ||
827 | { USB_DEVICE(PI_VID, PI_100F_PID) }, | ||
828 | { USB_DEVICE(PI_VID, PI_1011_PID) }, | ||
829 | { USB_DEVICE(PI_VID, PI_1012_PID) }, | ||
830 | { USB_DEVICE(PI_VID, PI_1013_PID) }, | ||
831 | { USB_DEVICE(PI_VID, PI_1014_PID) }, | ||
832 | { USB_DEVICE(PI_VID, PI_1015_PID) }, | ||
833 | { USB_DEVICE(PI_VID, PI_1016_PID) }, | ||
814 | { USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) }, | 834 | { USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) }, |
815 | { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, | 835 | { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, |
816 | { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), | 836 | { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 5dd96ca6c380..41fe5826100c 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -75,6 +75,9 @@ | |||
75 | #define FTDI_OPENDCC_GATEWAY_PID 0xBFDB | 75 | #define FTDI_OPENDCC_GATEWAY_PID 0xBFDB |
76 | #define FTDI_OPENDCC_GBM_PID 0xBFDC | 76 | #define FTDI_OPENDCC_GBM_PID 0xBFDC |
77 | 77 | ||
78 | /* NZR SEM 16+ USB (http://www.nzr.de) */ | ||
79 | #define FTDI_NZR_SEM_USB_PID 0xC1E0 /* NZR SEM-LOG16+ */ | ||
80 | |||
78 | /* | 81 | /* |
79 | * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) | 82 | * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) |
80 | */ | 83 | */ |
@@ -539,7 +542,10 @@ | |||
539 | /* | 542 | /* |
540 | * Microchip Technology, Inc. | 543 | * Microchip Technology, Inc. |
541 | * | 544 | * |
542 | * MICROCHIP_VID (0x04D8) and MICROCHIP_USB_BOARD_PID (0x000A) are also used by: | 545 | * MICROCHIP_VID (0x04D8) and MICROCHIP_USB_BOARD_PID (0x000A) are |
546 | * used by single function CDC ACM class based firmware demo | ||
547 | * applications. The VID/PID has also been used in firmware | ||
548 | * emulating FTDI serial chips by: | ||
543 | * Hornby Elite - Digital Command Control Console | 549 | * Hornby Elite - Digital Command Control Console |
544 | * http://www.hornby.com/hornby-dcc/controllers/ | 550 | * http://www.hornby.com/hornby-dcc/controllers/ |
545 | */ | 551 | */ |
@@ -791,8 +797,27 @@ | |||
791 | * Physik Instrumente | 797 | * Physik Instrumente |
792 | * http://www.physikinstrumente.com/en/products/ | 798 | * http://www.physikinstrumente.com/en/products/ |
793 | */ | 799 | */ |
800 | /* These two devices use the VID of FTDI */ | ||
801 | #define PI_C865_PID 0xe0a0 /* PI C-865 Piezomotor Controller */ | ||
802 | #define PI_C857_PID 0xe0a1 /* PI Encoder Trigger Box */ | ||
803 | |||
794 | #define PI_VID 0x1a72 /* Vendor ID */ | 804 | #define PI_VID 0x1a72 /* Vendor ID */ |
795 | #define PI_E861_PID 0x1008 /* E-861 piezo controller USB connection */ | 805 | #define PI_C866_PID 0x1000 /* PI C-866 Piezomotor Controller */ |
806 | #define PI_C663_PID 0x1001 /* PI C-663 Mercury-Step */ | ||
807 | #define PI_C725_PID 0x1002 /* PI C-725 Piezomotor Controller */ | ||
808 | #define PI_E517_PID 0x1005 /* PI E-517 Digital Piezo Controller Operation Module */ | ||
809 | #define PI_C863_PID 0x1007 /* PI C-863 */ | ||
810 | #define PI_E861_PID 0x1008 /* PI E-861 Piezomotor Controller */ | ||
811 | #define PI_C867_PID 0x1009 /* PI C-867 Piezomotor Controller */ | ||
812 | #define PI_E609_PID 0x100D /* PI E-609 Digital Piezo Controller */ | ||
813 | #define PI_E709_PID 0x100E /* PI E-709 Digital Piezo Controller */ | ||
814 | #define PI_100F_PID 0x100F /* PI Digital Piezo Controller */ | ||
815 | #define PI_1011_PID 0x1011 /* PI Digital Piezo Controller */ | ||
816 | #define PI_1012_PID 0x1012 /* PI Motion Controller */ | ||
817 | #define PI_1013_PID 0x1013 /* PI Motion Controller */ | ||
818 | #define PI_1014_PID 0x1014 /* PI Device */ | ||
819 | #define PI_1015_PID 0x1015 /* PI Device */ | ||
820 | #define PI_1016_PID 0x1016 /* PI Digital Servo Module */ | ||
796 | 821 | ||
797 | /* | 822 | /* |
798 | * Kondo Kagaku Co.Ltd. | 823 | * Kondo Kagaku Co.Ltd. |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index cc40f47ecea1..5ce88d1bc6f1 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -886,8 +886,6 @@ static const struct usb_device_id option_ids[] = { | |||
886 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), | 886 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), |
887 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 887 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
888 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, | 888 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, |
889 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1018, 0xff, 0xff, 0xff), | ||
890 | .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, | ||
891 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, | 889 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, |
892 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, | 890 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, |
893 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, | 891 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, |
@@ -1092,6 +1090,10 @@ static const struct usb_device_id option_ids[] = { | |||
1092 | .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, | 1090 | .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, |
1093 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), | 1091 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), |
1094 | .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, | 1092 | .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, |
1093 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, | ||
1094 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, | ||
1095 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, | ||
1096 | |||
1095 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 1097 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
1096 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | 1098 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, |
1097 | { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ | 1099 | { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ |
diff --git a/drivers/video/auo_k190x.c b/drivers/video/auo_k190x.c index 77da6a2f43dc..c03ecdd31e4c 100644 --- a/drivers/video/auo_k190x.c +++ b/drivers/video/auo_k190x.c | |||
@@ -987,7 +987,6 @@ err_regfb: | |||
987 | fb_dealloc_cmap(&info->cmap); | 987 | fb_dealloc_cmap(&info->cmap); |
988 | err_cmap: | 988 | err_cmap: |
989 | fb_deferred_io_cleanup(info); | 989 | fb_deferred_io_cleanup(info); |
990 | kfree(info->fbdefio); | ||
991 | err_defio: | 990 | err_defio: |
992 | vfree((void *)info->screen_base); | 991 | vfree((void *)info->screen_base); |
993 | err_irq: | 992 | err_irq: |
@@ -1022,7 +1021,6 @@ int __devexit auok190x_common_remove(struct platform_device *pdev) | |||
1022 | fb_dealloc_cmap(&info->cmap); | 1021 | fb_dealloc_cmap(&info->cmap); |
1023 | 1022 | ||
1024 | fb_deferred_io_cleanup(info); | 1023 | fb_deferred_io_cleanup(info); |
1025 | kfree(info->fbdefio); | ||
1026 | 1024 | ||
1027 | vfree((void *)info->screen_base); | 1025 | vfree((void *)info->screen_base); |
1028 | 1026 | ||
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c index 28b1a834906b..61b182bf32a2 100644 --- a/drivers/video/console/bitblit.c +++ b/drivers/video/console/bitblit.c | |||
@@ -162,7 +162,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, | |||
162 | image.depth = 1; | 162 | image.depth = 1; |
163 | 163 | ||
164 | if (attribute) { | 164 | if (attribute) { |
165 | buf = kmalloc(cellsize, GFP_KERNEL); | 165 | buf = kmalloc(cellsize, GFP_ATOMIC); |
166 | if (!buf) | 166 | if (!buf) |
167 | return; | 167 | return; |
168 | } | 168 | } |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 88e92041d8f0..fdefa8fd72c4 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -449,7 +449,7 @@ static int __init fb_console_setup(char *this_opt) | |||
449 | 449 | ||
450 | while ((options = strsep(&this_opt, ",")) != NULL) { | 450 | while ((options = strsep(&this_opt, ",")) != NULL) { |
451 | if (!strncmp(options, "font:", 5)) | 451 | if (!strncmp(options, "font:", 5)) |
452 | strcpy(fontname, options + 5); | 452 | strlcpy(fontname, options + 5, sizeof(fontname)); |
453 | 453 | ||
454 | if (!strncmp(options, "scrollback:", 11)) { | 454 | if (!strncmp(options, "scrollback:", 11)) { |
455 | options += 11; | 455 | options += 11; |
diff --git a/drivers/video/mb862xx/mb862xxfbdrv.c b/drivers/video/mb862xx/mb862xxfbdrv.c index 00ce1f34b496..57d940be5f3d 100644 --- a/drivers/video/mb862xx/mb862xxfbdrv.c +++ b/drivers/video/mb862xx/mb862xxfbdrv.c | |||
@@ -328,6 +328,8 @@ static int mb862xxfb_ioctl(struct fb_info *fbi, unsigned int cmd, | |||
328 | case MB862XX_L1_SET_CFG: | 328 | case MB862XX_L1_SET_CFG: |
329 | if (copy_from_user(l1_cfg, argp, sizeof(*l1_cfg))) | 329 | if (copy_from_user(l1_cfg, argp, sizeof(*l1_cfg))) |
330 | return -EFAULT; | 330 | return -EFAULT; |
331 | if (l1_cfg->dh == 0 || l1_cfg->dw == 0) | ||
332 | return -EINVAL; | ||
331 | if ((l1_cfg->sw >= l1_cfg->dw) && (l1_cfg->sh >= l1_cfg->dh)) { | 333 | if ((l1_cfg->sw >= l1_cfg->dw) && (l1_cfg->sh >= l1_cfg->dh)) { |
332 | /* downscaling */ | 334 | /* downscaling */ |
333 | outreg(cap, GC_CAP_CSC, | 335 | outreg(cap, GC_CAP_CSC, |
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 5d31699fbd3c..f43bfe17b3b6 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c | |||
@@ -105,6 +105,20 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) | |||
105 | 105 | ||
106 | sdi_config_lcd_manager(dssdev); | 106 | sdi_config_lcd_manager(dssdev); |
107 | 107 | ||
108 | /* | ||
109 | * LCLK and PCLK divisors are located in shadow registers, and we | ||
110 | * normally write them to DISPC registers when enabling the output. | ||
111 | * However, SDI uses pck-free as source clock for its PLL, and pck-free | ||
112 | * is affected by the divisors. And as we need the PLL before enabling | ||
113 | * the output, we need to write the divisors early. | ||
114 | * | ||
115 | * It seems just writing to the DISPC register is enough, and we don't | ||
116 | * need to care about the shadow register mechanism for pck-free. The | ||
117 | * exact reason for this is unknown. | ||
118 | */ | ||
119 | dispc_mgr_set_clock_div(dssdev->manager->id, | ||
120 | &sdi.mgr_config.clock_info); | ||
121 | |||
108 | dss_sdi_init(dssdev->phy.sdi.datapairs); | 122 | dss_sdi_init(dssdev->phy.sdi.datapairs); |
109 | r = dss_sdi_enable(); | 123 | r = dss_sdi_enable(); |
110 | if (r) | 124 | if (r) |
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 08ec1a7103f2..fc671d3d8004 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c | |||
@@ -1192,7 +1192,7 @@ static int _setcolreg(struct fb_info *fbi, u_int regno, u_int red, u_int green, | |||
1192 | break; | 1192 | break; |
1193 | 1193 | ||
1194 | if (regno < 16) { | 1194 | if (regno < 16) { |
1195 | u16 pal; | 1195 | u32 pal; |
1196 | pal = ((red >> (16 - var->red.length)) << | 1196 | pal = ((red >> (16 - var->red.length)) << |
1197 | var->red.offset) | | 1197 | var->red.offset) | |
1198 | ((green >> (16 - var->green.length)) << | 1198 | ((green >> (16 - var->green.length)) << |
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 1afb4fba11b4..4d519488d304 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c | |||
@@ -232,7 +232,7 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, | |||
232 | return ret; | 232 | return ret; |
233 | 233 | ||
234 | if (hwdev && hwdev->coherent_dma_mask) | 234 | if (hwdev && hwdev->coherent_dma_mask) |
235 | dma_mask = hwdev->coherent_dma_mask; | 235 | dma_mask = dma_alloc_coherent_mask(hwdev, flags); |
236 | 236 | ||
237 | phys = virt_to_phys(ret); | 237 | phys = virt_to_phys(ret); |
238 | dev_addr = xen_phys_to_bus(phys); | 238 | dev_addr = xen_phys_to_bus(phys); |
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 097e536e8672..03342728bf23 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c | |||
@@ -353,16 +353,16 @@ static int __devinit pcistub_init_device(struct pci_dev *dev) | |||
353 | if (err) | 353 | if (err) |
354 | goto config_release; | 354 | goto config_release; |
355 | 355 | ||
356 | dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n"); | ||
357 | __pci_reset_function_locked(dev); | ||
358 | |||
359 | /* We need the device active to save the state. */ | 356 | /* We need the device active to save the state. */ |
360 | dev_dbg(&dev->dev, "save state of device\n"); | 357 | dev_dbg(&dev->dev, "save state of device\n"); |
361 | pci_save_state(dev); | 358 | pci_save_state(dev); |
362 | dev_data->pci_saved_state = pci_store_saved_state(dev); | 359 | dev_data->pci_saved_state = pci_store_saved_state(dev); |
363 | if (!dev_data->pci_saved_state) | 360 | if (!dev_data->pci_saved_state) |
364 | dev_err(&dev->dev, "Could not store PCI conf saved state!\n"); | 361 | dev_err(&dev->dev, "Could not store PCI conf saved state!\n"); |
365 | 362 | else { | |
363 | dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n"); | ||
364 | __pci_reset_function_locked(dev); | ||
365 | } | ||
366 | /* Now disable the device (this also ensures some private device | 366 | /* Now disable the device (this also ensures some private device |
367 | * data is setup before we export) | 367 | * data is setup before we export) |
368 | */ | 368 | */ |
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 38b42e7bc91d..b65015581744 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c | |||
@@ -1371,10 +1371,8 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, | |||
1371 | 1371 | ||
1372 | if (srcid) { | 1372 | if (srcid) { |
1373 | srcgroup = find_qgroup_rb(fs_info, srcid); | 1373 | srcgroup = find_qgroup_rb(fs_info, srcid); |
1374 | if (!srcgroup) { | 1374 | if (!srcgroup) |
1375 | ret = -EINVAL; | ||
1376 | goto unlock; | 1375 | goto unlock; |
1377 | } | ||
1378 | dstgroup->rfer = srcgroup->rfer - level_size; | 1376 | dstgroup->rfer = srcgroup->rfer - level_size; |
1379 | dstgroup->rfer_cmpr = srcgroup->rfer_cmpr - level_size; | 1377 | dstgroup->rfer_cmpr = srcgroup->rfer_cmpr - level_size; |
1380 | srcgroup->excl = level_size; | 1378 | srcgroup->excl = level_size; |
@@ -1383,10 +1381,8 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, | |||
1383 | qgroup_dirty(fs_info, srcgroup); | 1381 | qgroup_dirty(fs_info, srcgroup); |
1384 | } | 1382 | } |
1385 | 1383 | ||
1386 | if (!inherit) { | 1384 | if (!inherit) |
1387 | ret = -EINVAL; | ||
1388 | goto unlock; | 1385 | goto unlock; |
1389 | } | ||
1390 | 1386 | ||
1391 | i_qgroups = (u64 *)(inherit + 1); | 1387 | i_qgroups = (u64 *)(inherit + 1); |
1392 | for (i = 0; i < inherit->num_qgroups; ++i) { | 1388 | for (i = 0; i < inherit->num_qgroups; ++i) { |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 074923ce593d..f0cf934ba877 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -1576,9 +1576,14 @@ cifs_readv_callback(struct mid_q_entry *mid) | |||
1576 | /* result already set, check signature */ | 1576 | /* result already set, check signature */ |
1577 | if (server->sec_mode & | 1577 | if (server->sec_mode & |
1578 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { | 1578 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { |
1579 | if (cifs_verify_signature(rdata->iov, rdata->nr_iov, | 1579 | int rc = 0; |
1580 | server, mid->sequence_number + 1)) | 1580 | |
1581 | cERROR(1, "Unexpected SMB signature"); | 1581 | rc = cifs_verify_signature(rdata->iov, rdata->nr_iov, |
1582 | server, | ||
1583 | mid->sequence_number + 1); | ||
1584 | if (rc) | ||
1585 | cERROR(1, "SMB signature verification returned " | ||
1586 | "error = %d", rc); | ||
1582 | } | 1587 | } |
1583 | /* FIXME: should this be counted toward the initiating task? */ | 1588 | /* FIXME: should this be counted toward the initiating task? */ |
1584 | task_io_account_read(rdata->bytes); | 1589 | task_io_account_read(rdata->bytes); |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index cbe709ad6663..781025be48bc 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -356,19 +356,12 @@ cifs_create_get_file_info: | |||
356 | cifs_create_set_dentry: | 356 | cifs_create_set_dentry: |
357 | if (rc != 0) { | 357 | if (rc != 0) { |
358 | cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); | 358 | cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); |
359 | CIFSSMBClose(xid, tcon, *fileHandle); | ||
359 | goto out; | 360 | goto out; |
360 | } | 361 | } |
361 | d_drop(direntry); | 362 | d_drop(direntry); |
362 | d_add(direntry, newinode); | 363 | d_add(direntry, newinode); |
363 | 364 | ||
364 | /* ENOENT for create? How weird... */ | ||
365 | rc = -ENOENT; | ||
366 | if (!newinode) { | ||
367 | CIFSSMBClose(xid, tcon, *fileHandle); | ||
368 | goto out; | ||
369 | } | ||
370 | rc = 0; | ||
371 | |||
372 | out: | 365 | out: |
373 | kfree(buf); | 366 | kfree(buf); |
374 | kfree(full_path); | 367 | kfree(full_path); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 9154192b0683..71e9ad9f5961 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -917,7 +917,7 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile) | |||
917 | if (!buf) { | 917 | if (!buf) { |
918 | mutex_unlock(&cinode->lock_mutex); | 918 | mutex_unlock(&cinode->lock_mutex); |
919 | free_xid(xid); | 919 | free_xid(xid); |
920 | return rc; | 920 | return -ENOMEM; |
921 | } | 921 | } |
922 | 922 | ||
923 | for (i = 0; i < 2; i++) { | 923 | for (i = 0; i < 2; i++) { |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 7354877fa3bd..cb79c7edecb0 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -124,10 +124,10 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) | |||
124 | { | 124 | { |
125 | struct cifsInodeInfo *cifs_i = CIFS_I(inode); | 125 | struct cifsInodeInfo *cifs_i = CIFS_I(inode); |
126 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 126 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
127 | unsigned long oldtime = cifs_i->time; | ||
128 | 127 | ||
129 | cifs_revalidate_cache(inode, fattr); | 128 | cifs_revalidate_cache(inode, fattr); |
130 | 129 | ||
130 | spin_lock(&inode->i_lock); | ||
131 | inode->i_atime = fattr->cf_atime; | 131 | inode->i_atime = fattr->cf_atime; |
132 | inode->i_mtime = fattr->cf_mtime; | 132 | inode->i_mtime = fattr->cf_mtime; |
133 | inode->i_ctime = fattr->cf_ctime; | 133 | inode->i_ctime = fattr->cf_ctime; |
@@ -148,9 +148,6 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) | |||
148 | else | 148 | else |
149 | cifs_i->time = jiffies; | 149 | cifs_i->time = jiffies; |
150 | 150 | ||
151 | cFYI(1, "inode 0x%p old_time=%ld new_time=%ld", inode, | ||
152 | oldtime, cifs_i->time); | ||
153 | |||
154 | cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING; | 151 | cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING; |
155 | 152 | ||
156 | cifs_i->server_eof = fattr->cf_eof; | 153 | cifs_i->server_eof = fattr->cf_eof; |
@@ -158,7 +155,6 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) | |||
158 | * Can't safely change the file size here if the client is writing to | 155 | * Can't safely change the file size here if the client is writing to |
159 | * it due to potential races. | 156 | * it due to potential races. |
160 | */ | 157 | */ |
161 | spin_lock(&inode->i_lock); | ||
162 | if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) { | 158 | if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) { |
163 | i_size_write(inode, fattr->cf_eof); | 159 | i_size_write(inode, fattr->cf_eof); |
164 | 160 | ||
@@ -859,12 +855,14 @@ struct inode *cifs_root_iget(struct super_block *sb) | |||
859 | 855 | ||
860 | if (rc && tcon->ipc) { | 856 | if (rc && tcon->ipc) { |
861 | cFYI(1, "ipc connection - fake read inode"); | 857 | cFYI(1, "ipc connection - fake read inode"); |
858 | spin_lock(&inode->i_lock); | ||
862 | inode->i_mode |= S_IFDIR; | 859 | inode->i_mode |= S_IFDIR; |
863 | set_nlink(inode, 2); | 860 | set_nlink(inode, 2); |
864 | inode->i_op = &cifs_ipc_inode_ops; | 861 | inode->i_op = &cifs_ipc_inode_ops; |
865 | inode->i_fop = &simple_dir_operations; | 862 | inode->i_fop = &simple_dir_operations; |
866 | inode->i_uid = cifs_sb->mnt_uid; | 863 | inode->i_uid = cifs_sb->mnt_uid; |
867 | inode->i_gid = cifs_sb->mnt_gid; | 864 | inode->i_gid = cifs_sb->mnt_gid; |
865 | spin_unlock(&inode->i_lock); | ||
868 | } else if (rc) { | 866 | } else if (rc) { |
869 | iget_failed(inode); | 867 | iget_failed(inode); |
870 | inode = ERR_PTR(rc); | 868 | inode = ERR_PTR(rc); |
@@ -1110,6 +1108,15 @@ undo_setattr: | |||
1110 | goto out_close; | 1108 | goto out_close; |
1111 | } | 1109 | } |
1112 | 1110 | ||
1111 | /* copied from fs/nfs/dir.c with small changes */ | ||
1112 | static void | ||
1113 | cifs_drop_nlink(struct inode *inode) | ||
1114 | { | ||
1115 | spin_lock(&inode->i_lock); | ||
1116 | if (inode->i_nlink > 0) | ||
1117 | drop_nlink(inode); | ||
1118 | spin_unlock(&inode->i_lock); | ||
1119 | } | ||
1113 | 1120 | ||
1114 | /* | 1121 | /* |
1115 | * If dentry->d_inode is null (usually meaning the cached dentry | 1122 | * If dentry->d_inode is null (usually meaning the cached dentry |
@@ -1166,13 +1173,13 @@ retry_std_delete: | |||
1166 | psx_del_no_retry: | 1173 | psx_del_no_retry: |
1167 | if (!rc) { | 1174 | if (!rc) { |
1168 | if (inode) | 1175 | if (inode) |
1169 | drop_nlink(inode); | 1176 | cifs_drop_nlink(inode); |
1170 | } else if (rc == -ENOENT) { | 1177 | } else if (rc == -ENOENT) { |
1171 | d_drop(dentry); | 1178 | d_drop(dentry); |
1172 | } else if (rc == -ETXTBSY) { | 1179 | } else if (rc == -ETXTBSY) { |
1173 | rc = cifs_rename_pending_delete(full_path, dentry, xid); | 1180 | rc = cifs_rename_pending_delete(full_path, dentry, xid); |
1174 | if (rc == 0) | 1181 | if (rc == 0) |
1175 | drop_nlink(inode); | 1182 | cifs_drop_nlink(inode); |
1176 | } else if ((rc == -EACCES) && (dosattr == 0) && inode) { | 1183 | } else if ((rc == -EACCES) && (dosattr == 0) && inode) { |
1177 | attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); | 1184 | attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); |
1178 | if (attrs == NULL) { | 1185 | if (attrs == NULL) { |
@@ -1241,9 +1248,10 @@ cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode, | |||
1241 | * setting nlink not necessary except in cases where we failed to get it | 1248 | * setting nlink not necessary except in cases where we failed to get it |
1242 | * from the server or was set bogus | 1249 | * from the server or was set bogus |
1243 | */ | 1250 | */ |
1251 | spin_lock(&dentry->d_inode->i_lock); | ||
1244 | if ((dentry->d_inode) && (dentry->d_inode->i_nlink < 2)) | 1252 | if ((dentry->d_inode) && (dentry->d_inode->i_nlink < 2)) |
1245 | set_nlink(dentry->d_inode, 2); | 1253 | set_nlink(dentry->d_inode, 2); |
1246 | 1254 | spin_unlock(&dentry->d_inode->i_lock); | |
1247 | mode &= ~current_umask(); | 1255 | mode &= ~current_umask(); |
1248 | /* must turn on setgid bit if parent dir has it */ | 1256 | /* must turn on setgid bit if parent dir has it */ |
1249 | if (inode->i_mode & S_ISGID) | 1257 | if (inode->i_mode & S_ISGID) |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 09e4b3ae4564..e6ce3b112875 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -433,7 +433,9 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, | |||
433 | if (old_file->d_inode) { | 433 | if (old_file->d_inode) { |
434 | cifsInode = CIFS_I(old_file->d_inode); | 434 | cifsInode = CIFS_I(old_file->d_inode); |
435 | if (rc == 0) { | 435 | if (rc == 0) { |
436 | spin_lock(&old_file->d_inode->i_lock); | ||
436 | inc_nlink(old_file->d_inode); | 437 | inc_nlink(old_file->d_inode); |
438 | spin_unlock(&old_file->d_inode->i_lock); | ||
437 | /* BB should we make this contingent on superblock flag NOATIME? */ | 439 | /* BB should we make this contingent on superblock flag NOATIME? */ |
438 | /* old_file->d_inode->i_ctime = CURRENT_TIME;*/ | 440 | /* old_file->d_inode->i_ctime = CURRENT_TIME;*/ |
439 | /* parent dir timestamps will update from srv | 441 | /* parent dir timestamps will update from srv |
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index a4ff5d547554..e4d3b9964167 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c | |||
@@ -52,7 +52,8 @@ check_smb2_hdr(struct smb2_hdr *hdr, __u64 mid) | |||
52 | cERROR(1, "Bad protocol string signature header %x", | 52 | cERROR(1, "Bad protocol string signature header %x", |
53 | *(unsigned int *) hdr->ProtocolId); | 53 | *(unsigned int *) hdr->ProtocolId); |
54 | if (mid != hdr->MessageId) | 54 | if (mid != hdr->MessageId) |
55 | cERROR(1, "Mids do not match"); | 55 | cERROR(1, "Mids do not match: %llu and %llu", mid, |
56 | hdr->MessageId); | ||
56 | } | 57 | } |
57 | cERROR(1, "Bad SMB detected. The Mid=%llu", hdr->MessageId); | 58 | cERROR(1, "Bad SMB detected. The Mid=%llu", hdr->MessageId); |
58 | return 1; | 59 | return 1; |
@@ -107,7 +108,7 @@ smb2_check_message(char *buf, unsigned int length) | |||
107 | * ie Validate the wct via smb2_struct_sizes table above | 108 | * ie Validate the wct via smb2_struct_sizes table above |
108 | */ | 109 | */ |
109 | 110 | ||
110 | if (length < 2 + sizeof(struct smb2_hdr)) { | 111 | if (length < sizeof(struct smb2_pdu)) { |
111 | if ((length >= sizeof(struct smb2_hdr)) && (hdr->Status != 0)) { | 112 | if ((length >= sizeof(struct smb2_hdr)) && (hdr->Status != 0)) { |
112 | pdu->StructureSize2 = 0; | 113 | pdu->StructureSize2 = 0; |
113 | /* | 114 | /* |
@@ -121,15 +122,15 @@ smb2_check_message(char *buf, unsigned int length) | |||
121 | return 1; | 122 | return 1; |
122 | } | 123 | } |
123 | if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE - 4) { | 124 | if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE - 4) { |
124 | cERROR(1, "SMB length greater than maximum, mid=%lld", mid); | 125 | cERROR(1, "SMB length greater than maximum, mid=%llu", mid); |
125 | return 1; | 126 | return 1; |
126 | } | 127 | } |
127 | 128 | ||
128 | if (check_smb2_hdr(hdr, mid)) | 129 | if (check_smb2_hdr(hdr, mid)) |
129 | return 1; | 130 | return 1; |
130 | 131 | ||
131 | if (hdr->StructureSize != SMB2_HEADER_SIZE) { | 132 | if (hdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) { |
132 | cERROR(1, "Illegal structure size %d", | 133 | cERROR(1, "Illegal structure size %u", |
133 | le16_to_cpu(hdr->StructureSize)); | 134 | le16_to_cpu(hdr->StructureSize)); |
134 | return 1; | 135 | return 1; |
135 | } | 136 | } |
@@ -161,8 +162,9 @@ smb2_check_message(char *buf, unsigned int length) | |||
161 | if (4 + len != clc_len) { | 162 | if (4 + len != clc_len) { |
162 | cFYI(1, "Calculated size %u length %u mismatch mid %llu", | 163 | cFYI(1, "Calculated size %u length %u mismatch mid %llu", |
163 | clc_len, 4 + len, mid); | 164 | clc_len, 4 + len, mid); |
164 | if (clc_len == 4 + len + 1) /* BB FIXME (fix samba) */ | 165 | /* server can return one byte more */ |
165 | return 0; /* BB workaround Samba 3 bug SessSetup rsp */ | 166 | if (clc_len == 4 + len + 1) |
167 | return 0; | ||
166 | return 1; | 168 | return 1; |
167 | } | 169 | } |
168 | return 0; | 170 | return 0; |
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index f37a1b41b402..15dc8eea8273 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
@@ -87,10 +87,6 @@ | |||
87 | 87 | ||
88 | #define SMB2_PROTO_NUMBER __constant_cpu_to_le32(0x424d53fe) | 88 | #define SMB2_PROTO_NUMBER __constant_cpu_to_le32(0x424d53fe) |
89 | 89 | ||
90 | #define SMB2_HEADER_SIZE __constant_le16_to_cpu(64) | ||
91 | |||
92 | #define SMB2_ERROR_STRUCTURE_SIZE2 __constant_le16_to_cpu(9) | ||
93 | |||
94 | /* | 90 | /* |
95 | * SMB2 Header Definition | 91 | * SMB2 Header Definition |
96 | * | 92 | * |
@@ -99,6 +95,9 @@ | |||
99 | * "PDU" : "Protocol Data Unit" (ie a network "frame") | 95 | * "PDU" : "Protocol Data Unit" (ie a network "frame") |
100 | * | 96 | * |
101 | */ | 97 | */ |
98 | |||
99 | #define SMB2_HEADER_STRUCTURE_SIZE __constant_cpu_to_le16(64) | ||
100 | |||
102 | struct smb2_hdr { | 101 | struct smb2_hdr { |
103 | __be32 smb2_buf_length; /* big endian on wire */ | 102 | __be32 smb2_buf_length; /* big endian on wire */ |
104 | /* length is only two or three bytes - with | 103 | /* length is only two or three bytes - with |
@@ -140,6 +139,9 @@ struct smb2_pdu { | |||
140 | * command code name for the struct. Note that structures must be packed. | 139 | * command code name for the struct. Note that structures must be packed. |
141 | * | 140 | * |
142 | */ | 141 | */ |
142 | |||
143 | #define SMB2_ERROR_STRUCTURE_SIZE2 __constant_cpu_to_le16(9) | ||
144 | |||
143 | struct smb2_err_rsp { | 145 | struct smb2_err_rsp { |
144 | struct smb2_hdr hdr; | 146 | struct smb2_hdr hdr; |
145 | __le16 StructureSize; | 147 | __le16 StructureSize; |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 83867ef348df..d9b639b95fa8 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -503,13 +503,16 @@ cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server, | |||
503 | /* convert the length into a more usable form */ | 503 | /* convert the length into a more usable form */ |
504 | if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { | 504 | if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { |
505 | struct kvec iov; | 505 | struct kvec iov; |
506 | int rc = 0; | ||
506 | 507 | ||
507 | iov.iov_base = mid->resp_buf; | 508 | iov.iov_base = mid->resp_buf; |
508 | iov.iov_len = len; | 509 | iov.iov_len = len; |
509 | /* FIXME: add code to kill session */ | 510 | /* FIXME: add code to kill session */ |
510 | if (cifs_verify_signature(&iov, 1, server, | 511 | rc = cifs_verify_signature(&iov, 1, server, |
511 | mid->sequence_number + 1) != 0) | 512 | mid->sequence_number + 1); |
512 | cERROR(1, "Unexpected SMB signature"); | 513 | if (rc) |
514 | cERROR(1, "SMB signature verification returned error = " | ||
515 | "%d", rc); | ||
513 | } | 516 | } |
514 | 517 | ||
515 | /* BB special case reconnect tid and uid here? */ | 518 | /* BB special case reconnect tid and uid here? */ |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 44ce5c6a541d..d45ba4568128 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -275,8 +275,14 @@ out: | |||
275 | 275 | ||
276 | static int ecryptfs_flush(struct file *file, fl_owner_t td) | 276 | static int ecryptfs_flush(struct file *file, fl_owner_t td) |
277 | { | 277 | { |
278 | return file->f_mode & FMODE_WRITE | 278 | struct file *lower_file = ecryptfs_file_to_lower(file); |
279 | ? filemap_write_and_wait(file->f_mapping) : 0; | 279 | |
280 | if (lower_file->f_op && lower_file->f_op->flush) { | ||
281 | filemap_write_and_wait(file->f_mapping); | ||
282 | return lower_file->f_op->flush(lower_file, td); | ||
283 | } | ||
284 | |||
285 | return 0; | ||
280 | } | 286 | } |
281 | 287 | ||
282 | static int ecryptfs_release(struct inode *inode, struct file *file) | 288 | static int ecryptfs_release(struct inode *inode, struct file *file) |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 534b129ea676..cc7709e7c508 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -619,6 +619,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
619 | struct dentry *lower_old_dir_dentry; | 619 | struct dentry *lower_old_dir_dentry; |
620 | struct dentry *lower_new_dir_dentry; | 620 | struct dentry *lower_new_dir_dentry; |
621 | struct dentry *trap = NULL; | 621 | struct dentry *trap = NULL; |
622 | struct inode *target_inode; | ||
622 | 623 | ||
623 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); | 624 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); |
624 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); | 625 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); |
@@ -626,6 +627,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
626 | dget(lower_new_dentry); | 627 | dget(lower_new_dentry); |
627 | lower_old_dir_dentry = dget_parent(lower_old_dentry); | 628 | lower_old_dir_dentry = dget_parent(lower_old_dentry); |
628 | lower_new_dir_dentry = dget_parent(lower_new_dentry); | 629 | lower_new_dir_dentry = dget_parent(lower_new_dentry); |
630 | target_inode = new_dentry->d_inode; | ||
629 | trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); | 631 | trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); |
630 | /* source should not be ancestor of target */ | 632 | /* source should not be ancestor of target */ |
631 | if (trap == lower_old_dentry) { | 633 | if (trap == lower_old_dentry) { |
@@ -641,6 +643,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
641 | lower_new_dir_dentry->d_inode, lower_new_dentry); | 643 | lower_new_dir_dentry->d_inode, lower_new_dentry); |
642 | if (rc) | 644 | if (rc) |
643 | goto out_lock; | 645 | goto out_lock; |
646 | if (target_inode) | ||
647 | fsstack_copy_attr_all(target_inode, | ||
648 | ecryptfs_inode_to_lower(target_inode)); | ||
644 | fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode); | 649 | fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode); |
645 | if (new_dir != old_dir) | 650 | if (new_dir != old_dir) |
646 | fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); | 651 | fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 2768138eefee..9b627c15010a 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -162,6 +162,7 @@ void ecryptfs_put_lower_file(struct inode *inode) | |||
162 | inode_info = ecryptfs_inode_to_private(inode); | 162 | inode_info = ecryptfs_inode_to_private(inode); |
163 | if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count, | 163 | if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count, |
164 | &inode_info->lower_file_mutex)) { | 164 | &inode_info->lower_file_mutex)) { |
165 | filemap_write_and_wait(inode->i_mapping); | ||
165 | fput(inode_info->lower_file); | 166 | fput(inode_info->lower_file); |
166 | inode_info->lower_file = NULL; | 167 | inode_info->lower_file = NULL; |
167 | mutex_unlock(&inode_info->lower_file_mutex); | 168 | mutex_unlock(&inode_info->lower_file_mutex); |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index a07597307fd1..ff574b4e345e 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -3072,6 +3072,8 @@ static int ext3_do_update_inode(handle_t *handle, | |||
3072 | struct ext3_inode_info *ei = EXT3_I(inode); | 3072 | struct ext3_inode_info *ei = EXT3_I(inode); |
3073 | struct buffer_head *bh = iloc->bh; | 3073 | struct buffer_head *bh = iloc->bh; |
3074 | int err = 0, rc, block; | 3074 | int err = 0, rc, block; |
3075 | int need_datasync = 0; | ||
3076 | __le32 disksize; | ||
3075 | uid_t i_uid; | 3077 | uid_t i_uid; |
3076 | gid_t i_gid; | 3078 | gid_t i_gid; |
3077 | 3079 | ||
@@ -3113,7 +3115,11 @@ again: | |||
3113 | raw_inode->i_gid_high = 0; | 3115 | raw_inode->i_gid_high = 0; |
3114 | } | 3116 | } |
3115 | raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); | 3117 | raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); |
3116 | raw_inode->i_size = cpu_to_le32(ei->i_disksize); | 3118 | disksize = cpu_to_le32(ei->i_disksize); |
3119 | if (disksize != raw_inode->i_size) { | ||
3120 | need_datasync = 1; | ||
3121 | raw_inode->i_size = disksize; | ||
3122 | } | ||
3117 | raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec); | 3123 | raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec); |
3118 | raw_inode->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec); | 3124 | raw_inode->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec); |
3119 | raw_inode->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec); | 3125 | raw_inode->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec); |
@@ -3129,8 +3135,11 @@ again: | |||
3129 | if (!S_ISREG(inode->i_mode)) { | 3135 | if (!S_ISREG(inode->i_mode)) { |
3130 | raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl); | 3136 | raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl); |
3131 | } else { | 3137 | } else { |
3132 | raw_inode->i_size_high = | 3138 | disksize = cpu_to_le32(ei->i_disksize >> 32); |
3133 | cpu_to_le32(ei->i_disksize >> 32); | 3139 | if (disksize != raw_inode->i_size_high) { |
3140 | raw_inode->i_size_high = disksize; | ||
3141 | need_datasync = 1; | ||
3142 | } | ||
3134 | if (ei->i_disksize > 0x7fffffffULL) { | 3143 | if (ei->i_disksize > 0x7fffffffULL) { |
3135 | struct super_block *sb = inode->i_sb; | 3144 | struct super_block *sb = inode->i_sb; |
3136 | if (!EXT3_HAS_RO_COMPAT_FEATURE(sb, | 3145 | if (!EXT3_HAS_RO_COMPAT_FEATURE(sb, |
@@ -3183,6 +3192,8 @@ again: | |||
3183 | ext3_clear_inode_state(inode, EXT3_STATE_NEW); | 3192 | ext3_clear_inode_state(inode, EXT3_STATE_NEW); |
3184 | 3193 | ||
3185 | atomic_set(&ei->i_sync_tid, handle->h_transaction->t_tid); | 3194 | atomic_set(&ei->i_sync_tid, handle->h_transaction->t_tid); |
3195 | if (need_datasync) | ||
3196 | atomic_set(&ei->i_datasync_tid, handle->h_transaction->t_tid); | ||
3186 | out_brelse: | 3197 | out_brelse: |
3187 | brelse (bh); | 3198 | brelse (bh); |
3188 | ext3_std_error(inode->i_sb, err); | 3199 | ext3_std_error(inode->i_sb, err); |
diff --git a/fs/fuse/control.c b/fs/fuse/control.c index 03ff5b1eba93..75a20c092dd4 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c | |||
@@ -117,7 +117,7 @@ static ssize_t fuse_conn_max_background_write(struct file *file, | |||
117 | const char __user *buf, | 117 | const char __user *buf, |
118 | size_t count, loff_t *ppos) | 118 | size_t count, loff_t *ppos) |
119 | { | 119 | { |
120 | unsigned val; | 120 | unsigned uninitialized_var(val); |
121 | ssize_t ret; | 121 | ssize_t ret; |
122 | 122 | ||
123 | ret = fuse_conn_limit_write(file, buf, count, ppos, &val, | 123 | ret = fuse_conn_limit_write(file, buf, count, ppos, &val, |
@@ -154,7 +154,7 @@ static ssize_t fuse_conn_congestion_threshold_write(struct file *file, | |||
154 | const char __user *buf, | 154 | const char __user *buf, |
155 | size_t count, loff_t *ppos) | 155 | size_t count, loff_t *ppos) |
156 | { | 156 | { |
157 | unsigned val; | 157 | unsigned uninitialized_var(val); |
158 | ssize_t ret; | 158 | ssize_t ret; |
159 | 159 | ||
160 | ret = fuse_conn_limit_write(file, buf, count, ppos, &val, | 160 | ret = fuse_conn_limit_write(file, buf, count, ppos, &val, |
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c index 3426521f3205..ee8d55042298 100644 --- a/fs/fuse/cuse.c +++ b/fs/fuse/cuse.c | |||
@@ -396,7 +396,7 @@ err_device: | |||
396 | err_region: | 396 | err_region: |
397 | unregister_chrdev_region(devt, 1); | 397 | unregister_chrdev_region(devt, 1); |
398 | err: | 398 | err: |
399 | fc->conn_error = 1; | 399 | fuse_conn_kill(fc); |
400 | goto out; | 400 | goto out; |
401 | } | 401 | } |
402 | 402 | ||
@@ -532,8 +532,6 @@ static int cuse_channel_release(struct inode *inode, struct file *file) | |||
532 | cdev_del(cc->cdev); | 532 | cdev_del(cc->cdev); |
533 | } | 533 | } |
534 | 534 | ||
535 | /* kill connection and shutdown channel */ | ||
536 | fuse_conn_kill(&cc->fc); | ||
537 | rc = fuse_dev_release(inode, file); /* puts the base reference */ | 535 | rc = fuse_dev_release(inode, file); /* puts the base reference */ |
538 | 536 | ||
539 | return rc; | 537 | return rc; |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 7df2b5e8fbe1..f4246cfc8d87 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -1576,6 +1576,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, | |||
1576 | req->pages[req->num_pages] = page; | 1576 | req->pages[req->num_pages] = page; |
1577 | req->num_pages++; | 1577 | req->num_pages++; |
1578 | 1578 | ||
1579 | offset = 0; | ||
1579 | num -= this_num; | 1580 | num -= this_num; |
1580 | total_len += this_num; | 1581 | total_len += this_num; |
1581 | index++; | 1582 | index++; |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index ce0a2838ccd0..fca222dabe3c 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -367,11 +367,6 @@ void fuse_conn_kill(struct fuse_conn *fc) | |||
367 | wake_up_all(&fc->waitq); | 367 | wake_up_all(&fc->waitq); |
368 | wake_up_all(&fc->blocked_waitq); | 368 | wake_up_all(&fc->blocked_waitq); |
369 | wake_up_all(&fc->reserved_req_waitq); | 369 | wake_up_all(&fc->reserved_req_waitq); |
370 | mutex_lock(&fuse_mutex); | ||
371 | list_del(&fc->entry); | ||
372 | fuse_ctl_remove_conn(fc); | ||
373 | mutex_unlock(&fuse_mutex); | ||
374 | fuse_bdi_destroy(fc); | ||
375 | } | 370 | } |
376 | EXPORT_SYMBOL_GPL(fuse_conn_kill); | 371 | EXPORT_SYMBOL_GPL(fuse_conn_kill); |
377 | 372 | ||
@@ -380,7 +375,14 @@ static void fuse_put_super(struct super_block *sb) | |||
380 | struct fuse_conn *fc = get_fuse_conn_super(sb); | 375 | struct fuse_conn *fc = get_fuse_conn_super(sb); |
381 | 376 | ||
382 | fuse_send_destroy(fc); | 377 | fuse_send_destroy(fc); |
378 | |||
383 | fuse_conn_kill(fc); | 379 | fuse_conn_kill(fc); |
380 | mutex_lock(&fuse_mutex); | ||
381 | list_del(&fc->entry); | ||
382 | fuse_ctl_remove_conn(fc); | ||
383 | mutex_unlock(&fuse_mutex); | ||
384 | fuse_bdi_destroy(fc); | ||
385 | |||
384 | fuse_conn_put(fc); | 386 | fuse_conn_put(fc); |
385 | } | 387 | } |
386 | 388 | ||
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index d1d791ef38de..382000ffac1f 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -323,6 +323,29 @@ static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
323 | } | 323 | } |
324 | 324 | ||
325 | /** | 325 | /** |
326 | * gfs2_size_hint - Give a hint to the size of a write request | ||
327 | * @file: The struct file | ||
328 | * @offset: The file offset of the write | ||
329 | * @size: The length of the write | ||
330 | * | ||
331 | * When we are about to do a write, this function records the total | ||
332 | * write size in order to provide a suitable hint to the lower layers | ||
333 | * about how many blocks will be required. | ||
334 | * | ||
335 | */ | ||
336 | |||
337 | static void gfs2_size_hint(struct file *filep, loff_t offset, size_t size) | ||
338 | { | ||
339 | struct inode *inode = filep->f_dentry->d_inode; | ||
340 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
341 | struct gfs2_inode *ip = GFS2_I(inode); | ||
342 | size_t blks = (size + sdp->sd_sb.sb_bsize - 1) >> sdp->sd_sb.sb_bsize_shift; | ||
343 | int hint = min_t(size_t, INT_MAX, blks); | ||
344 | |||
345 | atomic_set(&ip->i_res->rs_sizehint, hint); | ||
346 | } | ||
347 | |||
348 | /** | ||
326 | * gfs2_allocate_page_backing - Use bmap to allocate blocks | 349 | * gfs2_allocate_page_backing - Use bmap to allocate blocks |
327 | * @page: The (locked) page to allocate backing for | 350 | * @page: The (locked) page to allocate backing for |
328 | * | 351 | * |
@@ -382,8 +405,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
382 | if (ret) | 405 | if (ret) |
383 | return ret; | 406 | return ret; |
384 | 407 | ||
385 | atomic_set(&ip->i_res->rs_sizehint, | 408 | gfs2_size_hint(vma->vm_file, pos, PAGE_CACHE_SIZE); |
386 | PAGE_CACHE_SIZE >> sdp->sd_sb.sb_bsize_shift); | ||
387 | 409 | ||
388 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 410 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
389 | ret = gfs2_glock_nq(&gh); | 411 | ret = gfs2_glock_nq(&gh); |
@@ -663,7 +685,8 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
663 | if (ret) | 685 | if (ret) |
664 | return ret; | 686 | return ret; |
665 | 687 | ||
666 | atomic_set(&ip->i_res->rs_sizehint, writesize >> sdp->sd_sb.sb_bsize_shift); | 688 | gfs2_size_hint(file, pos, writesize); |
689 | |||
667 | if (file->f_flags & O_APPEND) { | 690 | if (file->f_flags & O_APPEND) { |
668 | struct gfs2_holder gh; | 691 | struct gfs2_holder gh; |
669 | 692 | ||
@@ -789,7 +812,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, | |||
789 | if (unlikely(error)) | 812 | if (unlikely(error)) |
790 | goto out_uninit; | 813 | goto out_uninit; |
791 | 814 | ||
792 | atomic_set(&ip->i_res->rs_sizehint, len >> sdp->sd_sb.sb_bsize_shift); | 815 | gfs2_size_hint(file, offset, len); |
793 | 816 | ||
794 | while (len > 0) { | 817 | while (len > 0) { |
795 | if (len < bytes) | 818 | if (len < bytes) |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 4ce22e547308..753af3d86bbc 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -1722,7 +1722,9 @@ static int gfs2_setxattr(struct dentry *dentry, const char *name, | |||
1722 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 1722 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
1723 | ret = gfs2_glock_nq(&gh); | 1723 | ret = gfs2_glock_nq(&gh); |
1724 | if (ret == 0) { | 1724 | if (ret == 0) { |
1725 | ret = generic_setxattr(dentry, name, data, size, flags); | 1725 | ret = gfs2_rs_alloc(ip); |
1726 | if (ret == 0) | ||
1727 | ret = generic_setxattr(dentry, name, data, size, flags); | ||
1726 | gfs2_glock_dq(&gh); | 1728 | gfs2_glock_dq(&gh); |
1727 | } | 1729 | } |
1728 | gfs2_holder_uninit(&gh); | 1730 | gfs2_holder_uninit(&gh); |
@@ -1757,7 +1759,9 @@ static int gfs2_removexattr(struct dentry *dentry, const char *name) | |||
1757 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 1759 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
1758 | ret = gfs2_glock_nq(&gh); | 1760 | ret = gfs2_glock_nq(&gh); |
1759 | if (ret == 0) { | 1761 | if (ret == 0) { |
1760 | ret = generic_removexattr(dentry, name); | 1762 | ret = gfs2_rs_alloc(ip); |
1763 | if (ret == 0) | ||
1764 | ret = generic_removexattr(dentry, name); | ||
1761 | gfs2_glock_dq(&gh); | 1765 | gfs2_glock_dq(&gh); |
1762 | } | 1766 | } |
1763 | gfs2_holder_uninit(&gh); | 1767 | gfs2_holder_uninit(&gh); |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 4d34887a601d..c9ed814eeb6f 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -1961,7 +1961,7 @@ static void gfs2_rgrp_error(struct gfs2_rgrpd *rgd) | |||
1961 | * @dinode: 1 if this block is a dinode block, otherwise data block | 1961 | * @dinode: 1 if this block is a dinode block, otherwise data block |
1962 | * @nblocks: desired extent length | 1962 | * @nblocks: desired extent length |
1963 | * | 1963 | * |
1964 | * Lay claim to previously allocated block reservation blocks. | 1964 | * Lay claim to previously reserved blocks. |
1965 | * Returns: Starting block number of the blocks claimed. | 1965 | * Returns: Starting block number of the blocks claimed. |
1966 | * Sets *nblocks to the actual extent length allocated. | 1966 | * Sets *nblocks to the actual extent length allocated. |
1967 | */ | 1967 | */ |
@@ -1970,19 +1970,17 @@ static u64 claim_reserved_blks(struct gfs2_inode *ip, bool dinode, | |||
1970 | { | 1970 | { |
1971 | struct gfs2_blkreserv *rs = ip->i_res; | 1971 | struct gfs2_blkreserv *rs = ip->i_res; |
1972 | struct gfs2_rgrpd *rgd = rs->rs_rgd; | 1972 | struct gfs2_rgrpd *rgd = rs->rs_rgd; |
1973 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1974 | struct gfs2_bitmap *bi; | 1973 | struct gfs2_bitmap *bi; |
1975 | u64 start_block = gfs2_rs_startblk(rs); | 1974 | u64 start_block = gfs2_rs_startblk(rs); |
1976 | const unsigned int elen = *nblocks; | 1975 | const unsigned int elen = *nblocks; |
1977 | 1976 | ||
1978 | /*BUG_ON(!gfs2_glock_is_locked_by_me(ip->i_gl));*/ | ||
1979 | gfs2_assert_withdraw(sdp, rgd); | ||
1980 | /*BUG_ON(!gfs2_glock_is_locked_by_me(rgd->rd_gl));*/ | ||
1981 | bi = rs->rs_bi; | 1977 | bi = rs->rs_bi; |
1982 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | 1978 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); |
1983 | 1979 | ||
1984 | for (*nblocks = 0; *nblocks < elen && rs->rs_free; (*nblocks)++) { | 1980 | for (*nblocks = 0; *nblocks < elen && rs->rs_free; (*nblocks)++) { |
1985 | /* Make sure the bitmap hasn't changed */ | 1981 | if (gfs2_testbit(rgd, bi->bi_bh->b_data + bi->bi_offset, |
1982 | bi->bi_len, rs->rs_biblk) != GFS2_BLKST_FREE) | ||
1983 | break; | ||
1986 | gfs2_setbit(rgd, bi->bi_clone, bi, rs->rs_biblk, | 1984 | gfs2_setbit(rgd, bi->bi_clone, bi, rs->rs_biblk, |
1987 | dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); | 1985 | dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); |
1988 | rs->rs_biblk++; | 1986 | rs->rs_biblk++; |
@@ -1991,20 +1989,12 @@ static u64 claim_reserved_blks(struct gfs2_inode *ip, bool dinode, | |||
1991 | BUG_ON(!rgd->rd_reserved); | 1989 | BUG_ON(!rgd->rd_reserved); |
1992 | rgd->rd_reserved--; | 1990 | rgd->rd_reserved--; |
1993 | dinode = false; | 1991 | dinode = false; |
1994 | trace_gfs2_rs(ip, rs, TRACE_RS_CLAIM); | ||
1995 | } | 1992 | } |
1996 | 1993 | ||
1997 | if (!rs->rs_free) { | 1994 | trace_gfs2_rs(ip, rs, TRACE_RS_CLAIM); |
1998 | struct gfs2_rgrpd *rgd = ip->i_res->rs_rgd; | 1995 | if (!rs->rs_free || *nblocks != elen) |
1999 | |||
2000 | gfs2_rs_deltree(rs); | 1996 | gfs2_rs_deltree(rs); |
2001 | /* -nblocks because we haven't returned to do the math yet. | 1997 | |
2002 | I'm doing the math backwards to prevent negative numbers, | ||
2003 | but think of it as: | ||
2004 | if (unclaimed_blocks(rgd) - *nblocks >= RGRP_RSRV_MINBLKS */ | ||
2005 | if (unclaimed_blocks(rgd) >= RGRP_RSRV_MINBLKS + *nblocks) | ||
2006 | rg_mblk_search(rgd, ip); | ||
2007 | } | ||
2008 | return start_block; | 1998 | return start_block; |
2009 | } | 1999 | } |
2010 | 2000 | ||
@@ -2037,34 +2027,34 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks, | |||
2037 | if (ip->i_res->rs_requested == 0) | 2027 | if (ip->i_res->rs_requested == 0) |
2038 | return -ECANCELED; | 2028 | return -ECANCELED; |
2039 | 2029 | ||
2040 | /* Check if we have a multi-block reservation, and if so, claim the | 2030 | /* If we have a reservation, claim blocks from it. */ |
2041 | next free block from it. */ | ||
2042 | if (gfs2_rs_active(ip->i_res)) { | 2031 | if (gfs2_rs_active(ip->i_res)) { |
2043 | BUG_ON(!ip->i_res->rs_free); | 2032 | BUG_ON(!ip->i_res->rs_free); |
2044 | rgd = ip->i_res->rs_rgd; | 2033 | rgd = ip->i_res->rs_rgd; |
2045 | block = claim_reserved_blks(ip, dinode, nblocks); | 2034 | block = claim_reserved_blks(ip, dinode, nblocks); |
2046 | } else { | 2035 | if (*nblocks) |
2047 | rgd = ip->i_rgd; | 2036 | goto found_blocks; |
2037 | } | ||
2048 | 2038 | ||
2049 | if (!dinode && rgrp_contains_block(rgd, ip->i_goal)) | 2039 | rgd = ip->i_rgd; |
2050 | goal = ip->i_goal - rgd->rd_data0; | ||
2051 | else | ||
2052 | goal = rgd->rd_last_alloc; | ||
2053 | |||
2054 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, &bi); | ||
2055 | |||
2056 | /* Since all blocks are reserved in advance, this shouldn't | ||
2057 | happen */ | ||
2058 | if (blk == BFITNOENT) { | ||
2059 | printk(KERN_WARNING "BFITNOENT, nblocks=%u\n", | ||
2060 | *nblocks); | ||
2061 | printk(KERN_WARNING "FULL=%d\n", | ||
2062 | test_bit(GBF_FULL, &rgd->rd_bits->bi_flags)); | ||
2063 | goto rgrp_error; | ||
2064 | } | ||
2065 | 2040 | ||
2066 | block = gfs2_alloc_extent(rgd, bi, blk, dinode, nblocks); | 2041 | if (!dinode && rgrp_contains_block(rgd, ip->i_goal)) |
2042 | goal = ip->i_goal - rgd->rd_data0; | ||
2043 | else | ||
2044 | goal = rgd->rd_last_alloc; | ||
2045 | |||
2046 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, &bi); | ||
2047 | |||
2048 | /* Since all blocks are reserved in advance, this shouldn't happen */ | ||
2049 | if (blk == BFITNOENT) { | ||
2050 | printk(KERN_WARNING "BFITNOENT, nblocks=%u\n", *nblocks); | ||
2051 | printk(KERN_WARNING "FULL=%d\n", | ||
2052 | test_bit(GBF_FULL, &rgd->rd_bits->bi_flags)); | ||
2053 | goto rgrp_error; | ||
2067 | } | 2054 | } |
2055 | |||
2056 | block = gfs2_alloc_extent(rgd, bi, blk, dinode, nblocks); | ||
2057 | found_blocks: | ||
2068 | ndata = *nblocks; | 2058 | ndata = *nblocks; |
2069 | if (dinode) | 2059 | if (dinode) |
2070 | ndata--; | 2060 | ndata--; |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 75d6d0a3d32e..6a7fcab7ecb3 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -287,10 +287,12 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) | |||
287 | struct inode *inode = file->f_path.dentry->d_inode; | 287 | struct inode *inode = file->f_path.dentry->d_inode; |
288 | 288 | ||
289 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); | 289 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); |
290 | if (ret != 0) | ||
291 | goto out; | ||
290 | mutex_lock(&inode->i_mutex); | 292 | mutex_lock(&inode->i_mutex); |
291 | ret = nfs_file_fsync_commit(file, start, end, datasync); | 293 | ret = nfs_file_fsync_commit(file, start, end, datasync); |
292 | mutex_unlock(&inode->i_mutex); | 294 | mutex_unlock(&inode->i_mutex); |
293 | 295 | out: | |
294 | return ret; | 296 | return ret; |
295 | } | 297 | } |
296 | 298 | ||
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index c6e895f0fbf3..9b47610338f5 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -154,7 +154,7 @@ static void nfs_zap_caches_locked(struct inode *inode) | |||
154 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); | 154 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); |
155 | nfsi->attrtimeo_timestamp = jiffies; | 155 | nfsi->attrtimeo_timestamp = jiffies; |
156 | 156 | ||
157 | memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); | 157 | memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf)); |
158 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) | 158 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) |
159 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; | 159 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; |
160 | else | 160 | else |
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index d6b3b5f2d779..69322096c325 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
@@ -643,7 +643,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
643 | u64 cookie, struct page **pages, unsigned int count, int plus) | 643 | u64 cookie, struct page **pages, unsigned int count, int plus) |
644 | { | 644 | { |
645 | struct inode *dir = dentry->d_inode; | 645 | struct inode *dir = dentry->d_inode; |
646 | __be32 *verf = NFS_COOKIEVERF(dir); | 646 | __be32 *verf = NFS_I(dir)->cookieverf; |
647 | struct nfs3_readdirargs arg = { | 647 | struct nfs3_readdirargs arg = { |
648 | .fh = NFS_FH(dir), | 648 | .fh = NFS_FH(dir), |
649 | .cookie = cookie, | 649 | .cookie = cookie, |
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index acb65e7887f8..eb5eb8eef4d3 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c | |||
@@ -96,13 +96,15 @@ nfs4_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) | |||
96 | struct inode *inode = file->f_path.dentry->d_inode; | 96 | struct inode *inode = file->f_path.dentry->d_inode; |
97 | 97 | ||
98 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); | 98 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); |
99 | if (ret != 0) | ||
100 | goto out; | ||
99 | mutex_lock(&inode->i_mutex); | 101 | mutex_lock(&inode->i_mutex); |
100 | ret = nfs_file_fsync_commit(file, start, end, datasync); | 102 | ret = nfs_file_fsync_commit(file, start, end, datasync); |
101 | if (!ret && !datasync) | 103 | if (!ret && !datasync) |
102 | /* application has asked for meta-data sync */ | 104 | /* application has asked for meta-data sync */ |
103 | ret = pnfs_layoutcommit_inode(inode, true); | 105 | ret = pnfs_layoutcommit_inode(inode, true); |
104 | mutex_unlock(&inode->i_mutex); | 106 | mutex_unlock(&inode->i_mutex); |
105 | 107 | out: | |
106 | return ret; | 108 | return ret; |
107 | } | 109 | } |
108 | 110 | ||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 635274140b18..1e50326d00dd 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -3215,11 +3215,11 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
3215 | dentry->d_parent->d_name.name, | 3215 | dentry->d_parent->d_name.name, |
3216 | dentry->d_name.name, | 3216 | dentry->d_name.name, |
3217 | (unsigned long long)cookie); | 3217 | (unsigned long long)cookie); |
3218 | nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); | 3218 | nfs4_setup_readdir(cookie, NFS_I(dir)->cookieverf, dentry, &args); |
3219 | res.pgbase = args.pgbase; | 3219 | res.pgbase = args.pgbase; |
3220 | status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &msg, &args.seq_args, &res.seq_res, 0); | 3220 | status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &msg, &args.seq_args, &res.seq_res, 0); |
3221 | if (status >= 0) { | 3221 | if (status >= 0) { |
3222 | memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); | 3222 | memcpy(NFS_I(dir)->cookieverf, res.verifier.data, NFS4_VERIFIER_SIZE); |
3223 | status += args.pgbase; | 3223 | status += args.pgbase; |
3224 | } | 3224 | } |
3225 | 3225 | ||
@@ -3653,11 +3653,11 @@ static inline int nfs4_server_supports_acls(struct nfs_server *server) | |||
3653 | && (server->acl_bitmask & ACL4_SUPPORT_DENY_ACL); | 3653 | && (server->acl_bitmask & ACL4_SUPPORT_DENY_ACL); |
3654 | } | 3654 | } |
3655 | 3655 | ||
3656 | /* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_CACHE_SIZE, and that | 3656 | /* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_SIZE, and that |
3657 | * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_CACHE_SIZE) bytes on | 3657 | * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_SIZE) bytes on |
3658 | * the stack. | 3658 | * the stack. |
3659 | */ | 3659 | */ |
3660 | #define NFS4ACL_MAXPAGES (XATTR_SIZE_MAX >> PAGE_CACHE_SHIFT) | 3660 | #define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE) |
3661 | 3661 | ||
3662 | static int buf_to_pages_noslab(const void *buf, size_t buflen, | 3662 | static int buf_to_pages_noslab(const void *buf, size_t buflen, |
3663 | struct page **pages, unsigned int *pgbase) | 3663 | struct page **pages, unsigned int *pgbase) |
@@ -3668,7 +3668,7 @@ static int buf_to_pages_noslab(const void *buf, size_t buflen, | |||
3668 | spages = pages; | 3668 | spages = pages; |
3669 | 3669 | ||
3670 | do { | 3670 | do { |
3671 | len = min_t(size_t, PAGE_CACHE_SIZE, buflen); | 3671 | len = min_t(size_t, PAGE_SIZE, buflen); |
3672 | newpage = alloc_page(GFP_KERNEL); | 3672 | newpage = alloc_page(GFP_KERNEL); |
3673 | 3673 | ||
3674 | if (newpage == NULL) | 3674 | if (newpage == NULL) |
@@ -3739,7 +3739,7 @@ static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size | |||
3739 | struct nfs4_cached_acl *acl; | 3739 | struct nfs4_cached_acl *acl; |
3740 | size_t buflen = sizeof(*acl) + acl_len; | 3740 | size_t buflen = sizeof(*acl) + acl_len; |
3741 | 3741 | ||
3742 | if (pages && buflen <= PAGE_SIZE) { | 3742 | if (buflen <= PAGE_SIZE) { |
3743 | acl = kmalloc(buflen, GFP_KERNEL); | 3743 | acl = kmalloc(buflen, GFP_KERNEL); |
3744 | if (acl == NULL) | 3744 | if (acl == NULL) |
3745 | goto out; | 3745 | goto out; |
@@ -3782,17 +3782,15 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu | |||
3782 | .rpc_argp = &args, | 3782 | .rpc_argp = &args, |
3783 | .rpc_resp = &res, | 3783 | .rpc_resp = &res, |
3784 | }; | 3784 | }; |
3785 | int ret = -ENOMEM, npages, i; | 3785 | unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); |
3786 | size_t acl_len = 0; | 3786 | int ret = -ENOMEM, i; |
3787 | 3787 | ||
3788 | npages = (buflen + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
3789 | /* As long as we're doing a round trip to the server anyway, | 3788 | /* As long as we're doing a round trip to the server anyway, |
3790 | * let's be prepared for a page of acl data. */ | 3789 | * let's be prepared for a page of acl data. */ |
3791 | if (npages == 0) | 3790 | if (npages == 0) |
3792 | npages = 1; | 3791 | npages = 1; |
3793 | 3792 | if (npages > ARRAY_SIZE(pages)) | |
3794 | /* Add an extra page to handle the bitmap returned */ | 3793 | return -ERANGE; |
3795 | npages++; | ||
3796 | 3794 | ||
3797 | for (i = 0; i < npages; i++) { | 3795 | for (i = 0; i < npages; i++) { |
3798 | pages[i] = alloc_page(GFP_KERNEL); | 3796 | pages[i] = alloc_page(GFP_KERNEL); |
@@ -3808,11 +3806,6 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu | |||
3808 | args.acl_len = npages * PAGE_SIZE; | 3806 | args.acl_len = npages * PAGE_SIZE; |
3809 | args.acl_pgbase = 0; | 3807 | args.acl_pgbase = 0; |
3810 | 3808 | ||
3811 | /* Let decode_getfacl know not to fail if the ACL data is larger than | ||
3812 | * the page we send as a guess */ | ||
3813 | if (buf == NULL) | ||
3814 | res.acl_flags |= NFS4_ACL_LEN_REQUEST; | ||
3815 | |||
3816 | dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", | 3809 | dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", |
3817 | __func__, buf, buflen, npages, args.acl_len); | 3810 | __func__, buf, buflen, npages, args.acl_len); |
3818 | ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), | 3811 | ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), |
@@ -3820,20 +3813,19 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu | |||
3820 | if (ret) | 3813 | if (ret) |
3821 | goto out_free; | 3814 | goto out_free; |
3822 | 3815 | ||
3823 | acl_len = res.acl_len; | 3816 | /* Handle the case where the passed-in buffer is too short */ |
3824 | if (acl_len > args.acl_len) | 3817 | if (res.acl_flags & NFS4_ACL_TRUNC) { |
3825 | nfs4_write_cached_acl(inode, NULL, 0, acl_len); | 3818 | /* Did the user only issue a request for the acl length? */ |
3826 | else | 3819 | if (buf == NULL) |
3827 | nfs4_write_cached_acl(inode, pages, res.acl_data_offset, | 3820 | goto out_ok; |
3828 | acl_len); | ||
3829 | if (buf) { | ||
3830 | ret = -ERANGE; | 3821 | ret = -ERANGE; |
3831 | if (acl_len > buflen) | 3822 | goto out_free; |
3832 | goto out_free; | ||
3833 | _copy_from_pages(buf, pages, res.acl_data_offset, | ||
3834 | acl_len); | ||
3835 | } | 3823 | } |
3836 | ret = acl_len; | 3824 | nfs4_write_cached_acl(inode, pages, res.acl_data_offset, res.acl_len); |
3825 | if (buf) | ||
3826 | _copy_from_pages(buf, pages, res.acl_data_offset, res.acl_len); | ||
3827 | out_ok: | ||
3828 | ret = res.acl_len; | ||
3837 | out_free: | 3829 | out_free: |
3838 | for (i = 0; i < npages; i++) | 3830 | for (i = 0; i < npages; i++) |
3839 | if (pages[i]) | 3831 | if (pages[i]) |
@@ -3891,10 +3883,13 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl | |||
3891 | .rpc_argp = &arg, | 3883 | .rpc_argp = &arg, |
3892 | .rpc_resp = &res, | 3884 | .rpc_resp = &res, |
3893 | }; | 3885 | }; |
3886 | unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); | ||
3894 | int ret, i; | 3887 | int ret, i; |
3895 | 3888 | ||
3896 | if (!nfs4_server_supports_acls(server)) | 3889 | if (!nfs4_server_supports_acls(server)) |
3897 | return -EOPNOTSUPP; | 3890 | return -EOPNOTSUPP; |
3891 | if (npages > ARRAY_SIZE(pages)) | ||
3892 | return -ERANGE; | ||
3898 | i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase); | 3893 | i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase); |
3899 | if (i < 0) | 3894 | if (i < 0) |
3900 | return i; | 3895 | return i; |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 1bfbd67c556d..8dba6bd48557 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -5072,18 +5072,14 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, | |||
5072 | * are stored with the acl data to handle the problem of | 5072 | * are stored with the acl data to handle the problem of |
5073 | * variable length bitmaps.*/ | 5073 | * variable length bitmaps.*/ |
5074 | res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset; | 5074 | res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset; |
5075 | |||
5076 | /* We ignore &savep and don't do consistency checks on | ||
5077 | * the attr length. Let userspace figure it out.... */ | ||
5078 | res->acl_len = attrlen; | 5075 | res->acl_len = attrlen; |
5079 | if (attrlen > (xdr->nwords << 2)) { | 5076 | |
5080 | if (res->acl_flags & NFS4_ACL_LEN_REQUEST) { | 5077 | /* Check for receive buffer overflow */ |
5081 | /* getxattr interface called with a NULL buf */ | 5078 | if (res->acl_len > (xdr->nwords << 2) || |
5082 | goto out; | 5079 | res->acl_len + res->acl_data_offset > xdr->buf->page_len) { |
5083 | } | 5080 | res->acl_flags |= NFS4_ACL_TRUNC; |
5084 | dprintk("NFS: acl reply: attrlen %u > page_len %u\n", | 5081 | dprintk("NFS: acl reply: attrlen %u > page_len %u\n", |
5085 | attrlen, xdr->nwords << 2); | 5082 | attrlen, xdr->nwords << 2); |
5086 | return -EINVAL; | ||
5087 | } | 5083 | } |
5088 | } else | 5084 | } else |
5089 | status = -EOPNOTSUPP; | 5085 | status = -EOPNOTSUPP; |
@@ -6229,7 +6225,8 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
6229 | status = decode_open(xdr, res); | 6225 | status = decode_open(xdr, res); |
6230 | if (status) | 6226 | if (status) |
6231 | goto out; | 6227 | goto out; |
6232 | if (decode_getfh(xdr, &res->fh) != 0) | 6228 | status = decode_getfh(xdr, &res->fh); |
6229 | if (status) | ||
6233 | goto out; | 6230 | goto out; |
6234 | decode_getfattr(xdr, res->f_attr, res->server); | 6231 | decode_getfattr(xdr, res->f_attr, res->server); |
6235 | out: | 6232 | out: |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 239aff7338eb..b8eda700584b 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -1867,6 +1867,7 @@ static int nfs23_validate_mount_data(void *options, | |||
1867 | 1867 | ||
1868 | memcpy(sap, &data->addr, sizeof(data->addr)); | 1868 | memcpy(sap, &data->addr, sizeof(data->addr)); |
1869 | args->nfs_server.addrlen = sizeof(data->addr); | 1869 | args->nfs_server.addrlen = sizeof(data->addr); |
1870 | args->nfs_server.port = ntohs(data->addr.sin_port); | ||
1870 | if (!nfs_verify_server_address(sap)) | 1871 | if (!nfs_verify_server_address(sap)) |
1871 | goto out_no_address; | 1872 | goto out_no_address; |
1872 | 1873 | ||
@@ -2564,6 +2565,7 @@ static int nfs4_validate_mount_data(void *options, | |||
2564 | return -EFAULT; | 2565 | return -EFAULT; |
2565 | if (!nfs_verify_server_address(sap)) | 2566 | if (!nfs_verify_server_address(sap)) |
2566 | goto out_no_address; | 2567 | goto out_no_address; |
2568 | args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port); | ||
2567 | 2569 | ||
2568 | if (data->auth_flavourlen) { | 2570 | if (data->auth_flavourlen) { |
2569 | if (data->auth_flavourlen > 1) | 2571 | if (data->auth_flavourlen > 1) |
@@ -58,7 +58,7 @@ EXPORT_SYMBOL(vfs_getattr); | |||
58 | int vfs_fstat(unsigned int fd, struct kstat *stat) | 58 | int vfs_fstat(unsigned int fd, struct kstat *stat) |
59 | { | 59 | { |
60 | int fput_needed; | 60 | int fput_needed; |
61 | struct file *f = fget_light(fd, &fput_needed); | 61 | struct file *f = fget_raw_light(fd, &fput_needed); |
62 | int error = -EBADF; | 62 | int error = -EBADF; |
63 | 63 | ||
64 | if (f) { | 64 | if (f) { |
diff --git a/fs/udf/file.c b/fs/udf/file.c index 7f3f7ba3df6e..d1c6093fd3d3 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -39,20 +39,24 @@ | |||
39 | #include "udf_i.h" | 39 | #include "udf_i.h" |
40 | #include "udf_sb.h" | 40 | #include "udf_sb.h" |
41 | 41 | ||
42 | static int udf_adinicb_readpage(struct file *file, struct page *page) | 42 | static void __udf_adinicb_readpage(struct page *page) |
43 | { | 43 | { |
44 | struct inode *inode = page->mapping->host; | 44 | struct inode *inode = page->mapping->host; |
45 | char *kaddr; | 45 | char *kaddr; |
46 | struct udf_inode_info *iinfo = UDF_I(inode); | 46 | struct udf_inode_info *iinfo = UDF_I(inode); |
47 | 47 | ||
48 | BUG_ON(!PageLocked(page)); | ||
49 | |||
50 | kaddr = kmap(page); | 48 | kaddr = kmap(page); |
51 | memset(kaddr, 0, PAGE_CACHE_SIZE); | ||
52 | memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, inode->i_size); | 49 | memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, inode->i_size); |
50 | memset(kaddr + inode->i_size, 0, PAGE_CACHE_SIZE - inode->i_size); | ||
53 | flush_dcache_page(page); | 51 | flush_dcache_page(page); |
54 | SetPageUptodate(page); | 52 | SetPageUptodate(page); |
55 | kunmap(page); | 53 | kunmap(page); |
54 | } | ||
55 | |||
56 | static int udf_adinicb_readpage(struct file *file, struct page *page) | ||
57 | { | ||
58 | BUG_ON(!PageLocked(page)); | ||
59 | __udf_adinicb_readpage(page); | ||
56 | unlock_page(page); | 60 | unlock_page(page); |
57 | 61 | ||
58 | return 0; | 62 | return 0; |
@@ -77,6 +81,25 @@ static int udf_adinicb_writepage(struct page *page, | |||
77 | return 0; | 81 | return 0; |
78 | } | 82 | } |
79 | 83 | ||
84 | static int udf_adinicb_write_begin(struct file *file, | ||
85 | struct address_space *mapping, loff_t pos, | ||
86 | unsigned len, unsigned flags, struct page **pagep, | ||
87 | void **fsdata) | ||
88 | { | ||
89 | struct page *page; | ||
90 | |||
91 | if (WARN_ON_ONCE(pos >= PAGE_CACHE_SIZE)) | ||
92 | return -EIO; | ||
93 | page = grab_cache_page_write_begin(mapping, 0, flags); | ||
94 | if (!page) | ||
95 | return -ENOMEM; | ||
96 | *pagep = page; | ||
97 | |||
98 | if (!PageUptodate(page) && len != PAGE_CACHE_SIZE) | ||
99 | __udf_adinicb_readpage(page); | ||
100 | return 0; | ||
101 | } | ||
102 | |||
80 | static int udf_adinicb_write_end(struct file *file, | 103 | static int udf_adinicb_write_end(struct file *file, |
81 | struct address_space *mapping, | 104 | struct address_space *mapping, |
82 | loff_t pos, unsigned len, unsigned copied, | 105 | loff_t pos, unsigned len, unsigned copied, |
@@ -98,8 +121,8 @@ static int udf_adinicb_write_end(struct file *file, | |||
98 | const struct address_space_operations udf_adinicb_aops = { | 121 | const struct address_space_operations udf_adinicb_aops = { |
99 | .readpage = udf_adinicb_readpage, | 122 | .readpage = udf_adinicb_readpage, |
100 | .writepage = udf_adinicb_writepage, | 123 | .writepage = udf_adinicb_writepage, |
101 | .write_begin = simple_write_begin, | 124 | .write_begin = udf_adinicb_write_begin, |
102 | .write_end = udf_adinicb_write_end, | 125 | .write_end = udf_adinicb_write_end, |
103 | }; | 126 | }; |
104 | 127 | ||
105 | static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | 128 | static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index ced362533e3c..bfacf0d5a225 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
@@ -118,7 +118,8 @@ enum drm_mode_status { | |||
118 | .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \ | 118 | .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \ |
119 | .htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \ | 119 | .htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \ |
120 | .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \ | 120 | .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \ |
121 | .vscan = (vs), .flags = (f), .vrefresh = 0 | 121 | .vscan = (vs), .flags = (f), .vrefresh = 0, \ |
122 | .base.type = DRM_MODE_OBJECT_MODE | ||
122 | 123 | ||
123 | #define CRTC_INTERLACE_HALVE_V 0x1 /* halve V values for interlacing */ | 124 | #define CRTC_INTERLACE_HALVE_V 0x1 /* halve V values for interlacing */ |
124 | 125 | ||
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h index bdf0152cbbe9..f4621184a9b4 100644 --- a/include/drm/drm_fourcc.h +++ b/include/drm/drm_fourcc.h | |||
@@ -107,8 +107,7 @@ | |||
107 | #define DRM_FORMAT_NV16 fourcc_code('N', 'V', '1', '6') /* 2x1 subsampled Cr:Cb plane */ | 107 | #define DRM_FORMAT_NV16 fourcc_code('N', 'V', '1', '6') /* 2x1 subsampled Cr:Cb plane */ |
108 | #define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */ | 108 | #define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */ |
109 | 109 | ||
110 | /* 2 non contiguous plane YCbCr */ | 110 | /* special NV12 tiled format */ |
111 | #define DRM_FORMAT_NV12M fourcc_code('N', 'M', '1', '2') /* 2x2 subsampled Cr:Cb plane */ | ||
112 | #define DRM_FORMAT_NV12MT fourcc_code('T', 'M', '1', '2') /* 2x2 subsampled Cr:Cb plane 64x32 macroblocks */ | 111 | #define DRM_FORMAT_NV12MT fourcc_code('T', 'M', '1', '2') /* 2x2 subsampled Cr:Cb plane 64x32 macroblocks */ |
113 | 112 | ||
114 | /* | 113 | /* |
@@ -131,7 +130,4 @@ | |||
131 | #define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */ | 130 | #define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */ |
132 | #define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */ | 131 | #define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */ |
133 | 132 | ||
134 | /* 3 non contiguous plane YCbCr */ | ||
135 | #define DRM_FORMAT_YUV420M fourcc_code('Y', 'M', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes */ | ||
136 | |||
137 | #endif /* DRM_FOURCC_H */ | 133 | #endif /* DRM_FOURCC_H */ |
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index 5581980b14f6..3d6301b6ec16 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h | |||
@@ -359,8 +359,9 @@ struct drm_mode_mode_cmd { | |||
359 | struct drm_mode_modeinfo mode; | 359 | struct drm_mode_modeinfo mode; |
360 | }; | 360 | }; |
361 | 361 | ||
362 | #define DRM_MODE_CURSOR_BO (1<<0) | 362 | #define DRM_MODE_CURSOR_BO 0x01 |
363 | #define DRM_MODE_CURSOR_MOVE (1<<1) | 363 | #define DRM_MODE_CURSOR_MOVE 0x02 |
364 | #define DRM_MODE_CURSOR_FLAGS 0x03 | ||
364 | 365 | ||
365 | /* | 366 | /* |
366 | * depending on the value in flags different members are used. | 367 | * depending on the value in flags different members are used. |
diff --git a/include/linux/atmel-ssc.h b/include/linux/atmel-ssc.h index 06023393fba9..4eb31752e2b7 100644 --- a/include/linux/atmel-ssc.h +++ b/include/linux/atmel-ssc.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/platform_device.h> | 4 | #include <linux/platform_device.h> |
5 | #include <linux/list.h> | 5 | #include <linux/list.h> |
6 | #include <linux/io.h> | ||
6 | 7 | ||
7 | struct ssc_device { | 8 | struct ssc_device { |
8 | struct list_head list; | 9 | struct list_head list; |
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 9c02a4508b25..09da4e565297 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h | |||
@@ -591,7 +591,7 @@ struct dma_device { | |||
591 | struct dma_async_tx_descriptor *(*device_prep_dma_cyclic)( | 591 | struct dma_async_tx_descriptor *(*device_prep_dma_cyclic)( |
592 | struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, | 592 | struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, |
593 | size_t period_len, enum dma_transfer_direction direction, | 593 | size_t period_len, enum dma_transfer_direction direction, |
594 | void *context); | 594 | unsigned long flags, void *context); |
595 | struct dma_async_tx_descriptor *(*device_prep_interleaved_dma)( | 595 | struct dma_async_tx_descriptor *(*device_prep_interleaved_dma)( |
596 | struct dma_chan *chan, struct dma_interleaved_template *xt, | 596 | struct dma_chan *chan, struct dma_interleaved_template *xt, |
597 | unsigned long flags); | 597 | unsigned long flags); |
@@ -656,7 +656,7 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_cyclic( | |||
656 | size_t period_len, enum dma_transfer_direction dir) | 656 | size_t period_len, enum dma_transfer_direction dir) |
657 | { | 657 | { |
658 | return chan->device->device_prep_dma_cyclic(chan, buf_addr, buf_len, | 658 | return chan->device->device_prep_dma_cyclic(chan, buf_addr, buf_len, |
659 | period_len, dir, NULL); | 659 | period_len, dir, flags, NULL); |
660 | } | 660 | } |
661 | 661 | ||
662 | static inline int dmaengine_terminate_all(struct dma_chan *chan) | 662 | static inline int dmaengine_terminate_all(struct dma_chan *chan) |
diff --git a/include/linux/i2c-pnx.h b/include/linux/i2c-pnx.h index 1bc74afe7a35..49ed17fdf055 100644 --- a/include/linux/i2c-pnx.h +++ b/include/linux/i2c-pnx.h | |||
@@ -22,6 +22,7 @@ struct i2c_pnx_mif { | |||
22 | struct timer_list timer; /* Timeout */ | 22 | struct timer_list timer; /* Timeout */ |
23 | u8 * buf; /* Data buffer */ | 23 | u8 * buf; /* Data buffer */ |
24 | int len; /* Length of data buffer */ | 24 | int len; /* Length of data buffer */ |
25 | int order; /* RX Bytes to order via TX */ | ||
25 | }; | 26 | }; |
26 | 27 | ||
27 | struct i2c_pnx_algo_data { | 28 | struct i2c_pnx_algo_data { |
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 7ea898c55a60..a4885a6cd10d 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h | |||
@@ -188,6 +188,7 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); | |||
188 | 188 | ||
189 | int twl_get_type(void); | 189 | int twl_get_type(void); |
190 | int twl_get_version(void); | 190 | int twl_get_version(void); |
191 | int twl_get_hfclk_rate(void); | ||
191 | 192 | ||
192 | int twl6030_interrupt_unmask(u8 bit_mask, u8 offset); | 193 | int twl6030_interrupt_unmask(u8 bit_mask, u8 offset); |
193 | int twl6030_interrupt_mask(u8 bit_mask, u8 offset); | 194 | int twl6030_interrupt_mask(u8 bit_mask, u8 offset); |
@@ -666,7 +667,7 @@ struct twl4030_codec_data { | |||
666 | unsigned int check_defaults:1; | 667 | unsigned int check_defaults:1; |
667 | unsigned int reset_registers:1; | 668 | unsigned int reset_registers:1; |
668 | unsigned int hs_extmute:1; | 669 | unsigned int hs_extmute:1; |
669 | void (*set_hs_extmute)(int mute); | 670 | int hs_extmute_gpio; |
670 | }; | 671 | }; |
671 | 672 | ||
672 | struct twl4030_vibra_data { | 673 | struct twl4030_vibra_data { |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 604382143bcf..594b419b7d20 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -82,10 +82,18 @@ | |||
82 | __x - (__x % (y)); \ | 82 | __x - (__x % (y)); \ |
83 | } \ | 83 | } \ |
84 | ) | 84 | ) |
85 | |||
86 | /* | ||
87 | * Divide positive or negative dividend by positive divisor and round | ||
88 | * to closest integer. Result is undefined for negative divisors. | ||
89 | */ | ||
85 | #define DIV_ROUND_CLOSEST(x, divisor)( \ | 90 | #define DIV_ROUND_CLOSEST(x, divisor)( \ |
86 | { \ | 91 | { \ |
87 | typeof(divisor) __divisor = divisor; \ | 92 | typeof(x) __x = x; \ |
88 | (((x) + ((__divisor) / 2)) / (__divisor)); \ | 93 | typeof(divisor) __d = divisor; \ |
94 | (((typeof(x))-1) >= 0 || (__x) >= 0) ? \ | ||
95 | (((__x) + ((__d) / 2)) / (__d)) : \ | ||
96 | (((__x) - ((__d) / 2)) / (__d)); \ | ||
89 | } \ | 97 | } \ |
90 | ) | 98 | ) |
91 | 99 | ||
diff --git a/include/linux/kobject.h b/include/linux/kobject.h index fc615a97e2d3..1e57449395b1 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h | |||
@@ -224,7 +224,7 @@ static inline int kobject_uevent_env(struct kobject *kobj, | |||
224 | 224 | ||
225 | static inline __printf(2, 3) | 225 | static inline __printf(2, 3) |
226 | int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...) | 226 | int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...) |
227 | { return 0; } | 227 | { return -ENOMEM; } |
228 | 228 | ||
229 | static inline int kobject_action_type(const char *buf, size_t count, | 229 | static inline int kobject_action_type(const char *buf, size_t count, |
230 | enum kobject_action *type) | 230 | enum kobject_action *type) |
diff --git a/include/linux/mISDNhw.h b/include/linux/mISDNhw.h index d0752eca9b44..9d96d5d4dfed 100644 --- a/include/linux/mISDNhw.h +++ b/include/linux/mISDNhw.h | |||
@@ -183,7 +183,7 @@ extern int mISDN_initbchannel(struct bchannel *, unsigned short, | |||
183 | unsigned short); | 183 | unsigned short); |
184 | extern int mISDN_freedchannel(struct dchannel *); | 184 | extern int mISDN_freedchannel(struct dchannel *); |
185 | extern void mISDN_clear_bchannel(struct bchannel *); | 185 | extern void mISDN_clear_bchannel(struct bchannel *); |
186 | extern int mISDN_freebchannel(struct bchannel *); | 186 | extern void mISDN_freebchannel(struct bchannel *); |
187 | extern int mISDN_ctrl_bchannel(struct bchannel *, struct mISDN_ctrl_req *); | 187 | extern int mISDN_ctrl_bchannel(struct bchannel *, struct mISDN_ctrl_req *); |
188 | extern void queue_ch_frame(struct mISDNchannel *, u_int, | 188 | extern void queue_ch_frame(struct mISDNchannel *, u_int, |
189 | int, struct sk_buff *); | 189 | int, struct sk_buff *); |
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h index 3a8435a8058f..cebe97ee98b8 100644 --- a/include/linux/mfd/core.h +++ b/include/linux/mfd/core.h | |||
@@ -16,6 +16,8 @@ | |||
16 | 16 | ||
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | 18 | ||
19 | struct irq_domain; | ||
20 | |||
19 | /* | 21 | /* |
20 | * This struct describes the MFD part ("cell"). | 22 | * This struct describes the MFD part ("cell"). |
21 | * After registration the copy of this structure will become the platform data | 23 | * After registration the copy of this structure will become the platform data |
@@ -98,7 +100,7 @@ static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev) | |||
98 | extern int mfd_add_devices(struct device *parent, int id, | 100 | extern int mfd_add_devices(struct device *parent, int id, |
99 | struct mfd_cell *cells, int n_devs, | 101 | struct mfd_cell *cells, int n_devs, |
100 | struct resource *mem_base, | 102 | struct resource *mem_base, |
101 | int irq_base); | 103 | int irq_base, struct irq_domain *irq_domain); |
102 | 104 | ||
103 | extern void mfd_remove_devices(struct device *parent); | 105 | extern void mfd_remove_devices(struct device *parent); |
104 | 106 | ||
diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h index 12c06870829a..7cd83d826ed8 100644 --- a/include/linux/mfd/tps65217.h +++ b/include/linux/mfd/tps65217.h | |||
@@ -22,6 +22,9 @@ | |||
22 | #include <linux/regulator/driver.h> | 22 | #include <linux/regulator/driver.h> |
23 | #include <linux/regulator/machine.h> | 23 | #include <linux/regulator/machine.h> |
24 | 24 | ||
25 | /* TPS chip id list */ | ||
26 | #define TPS65217 0xF0 | ||
27 | |||
25 | /* I2C ID for TPS65217 part */ | 28 | /* I2C ID for TPS65217 part */ |
26 | #define TPS65217_I2C_ID 0x24 | 29 | #define TPS65217_I2C_ID 0x24 |
27 | 30 | ||
@@ -248,13 +251,11 @@ struct tps_info { | |||
248 | struct tps65217 { | 251 | struct tps65217 { |
249 | struct device *dev; | 252 | struct device *dev; |
250 | struct tps65217_board *pdata; | 253 | struct tps65217_board *pdata; |
254 | unsigned int id; | ||
251 | struct regulator_desc desc[TPS65217_NUM_REGULATOR]; | 255 | struct regulator_desc desc[TPS65217_NUM_REGULATOR]; |
252 | struct regulator_dev *rdev[TPS65217_NUM_REGULATOR]; | 256 | struct regulator_dev *rdev[TPS65217_NUM_REGULATOR]; |
253 | struct tps_info *info[TPS65217_NUM_REGULATOR]; | 257 | struct tps_info *info[TPS65217_NUM_REGULATOR]; |
254 | struct regmap *regmap; | 258 | struct regmap *regmap; |
255 | |||
256 | /* Client devices */ | ||
257 | struct platform_device *regulator_pdev[TPS65217_NUM_REGULATOR]; | ||
258 | }; | 259 | }; |
259 | 260 | ||
260 | static inline struct tps65217 *dev_to_tps65217(struct device *dev) | 261 | static inline struct tps65217 *dev_to_tps65217(struct device *dev) |
@@ -262,6 +263,11 @@ static inline struct tps65217 *dev_to_tps65217(struct device *dev) | |||
262 | return dev_get_drvdata(dev); | 263 | return dev_get_drvdata(dev); |
263 | } | 264 | } |
264 | 265 | ||
266 | static inline int tps65217_chip_id(struct tps65217 *tps65217) | ||
267 | { | ||
268 | return tps65217->id; | ||
269 | } | ||
270 | |||
265 | int tps65217_reg_read(struct tps65217 *tps, unsigned int reg, | 271 | int tps65217_reg_read(struct tps65217 *tps, unsigned int reg, |
266 | unsigned int *val); | 272 | unsigned int *val); |
267 | int tps65217_reg_write(struct tps65217 *tps, unsigned int reg, | 273 | int tps65217_reg_write(struct tps65217 *tps, unsigned int reg, |
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index f0361c031927..fc87be4fdc25 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h | |||
@@ -164,6 +164,10 @@ struct wm8994_pdata { | |||
164 | int num_micd_rates; | 164 | int num_micd_rates; |
165 | struct wm8958_micd_rate *micd_rates; | 165 | struct wm8958_micd_rate *micd_rates; |
166 | 166 | ||
167 | /* Power up delays to add after microphone bias power up (ms) */ | ||
168 | int micb1_delay; | ||
169 | int micb2_delay; | ||
170 | |||
167 | /* LINEOUT can be differential or single ended */ | 171 | /* LINEOUT can be differential or single ended */ |
168 | unsigned int lineout1_diff:1; | 172 | unsigned int lineout1_diff:1; |
169 | unsigned int lineout2_diff:1; | 173 | unsigned int lineout2_diff:1; |
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index bd6c9fcdf2dd..6e1b0f973a03 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h | |||
@@ -796,6 +796,19 @@ enum mlx4_net_trans_rule_id { | |||
796 | MLX4_NET_TRANS_RULE_NUM, /* should be last */ | 796 | MLX4_NET_TRANS_RULE_NUM, /* should be last */ |
797 | }; | 797 | }; |
798 | 798 | ||
799 | extern const u16 __sw_id_hw[]; | ||
800 | |||
801 | static inline int map_hw_to_sw_id(u16 header_id) | ||
802 | { | ||
803 | |||
804 | int i; | ||
805 | for (i = 0; i < MLX4_NET_TRANS_RULE_NUM; i++) { | ||
806 | if (header_id == __sw_id_hw[i]) | ||
807 | return i; | ||
808 | } | ||
809 | return -EINVAL; | ||
810 | } | ||
811 | |||
799 | enum mlx4_net_trans_promisc_mode { | 812 | enum mlx4_net_trans_promisc_mode { |
800 | MLX4_FS_PROMISC_NONE = 0, | 813 | MLX4_FS_PROMISC_NONE = 0, |
801 | MLX4_FS_PROMISC_UPLINK, | 814 | MLX4_FS_PROMISC_UPLINK, |
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 111aca5e97f3..4b27f9f503e4 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
@@ -239,6 +239,7 @@ struct mmc_card { | |||
239 | #define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */ | 239 | #define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */ |
240 | #define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */ | 240 | #define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */ |
241 | #define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */ | 241 | #define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */ |
242 | #define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10) /* Skip secure for erase/trim */ | ||
242 | /* byte mode */ | 243 | /* byte mode */ |
243 | unsigned int poweroff_notify_state; /* eMMC4.5 notify feature */ | 244 | unsigned int poweroff_notify_state; /* eMMC4.5 notify feature */ |
244 | #define MMC_NO_POWER_NOTIFICATION 0 | 245 | #define MMC_NO_POWER_NOTIFICATION 0 |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 1f8fc7f9bcd8..4b03f56e280e 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
@@ -265,11 +265,6 @@ static inline const struct nfs_rpc_ops *NFS_PROTO(const struct inode *inode) | |||
265 | return NFS_SERVER(inode)->nfs_client->rpc_ops; | 265 | return NFS_SERVER(inode)->nfs_client->rpc_ops; |
266 | } | 266 | } |
267 | 267 | ||
268 | static inline __be32 *NFS_COOKIEVERF(const struct inode *inode) | ||
269 | { | ||
270 | return NFS_I(inode)->cookieverf; | ||
271 | } | ||
272 | |||
273 | static inline unsigned NFS_MINATTRTIMEO(const struct inode *inode) | 268 | static inline unsigned NFS_MINATTRTIMEO(const struct inode *inode) |
274 | { | 269 | { |
275 | struct nfs_server *nfss = NFS_SERVER(inode); | 270 | struct nfs_server *nfss = NFS_SERVER(inode); |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index ac7c8ae254f2..be9cf3c7e79e 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -652,7 +652,7 @@ struct nfs_getaclargs { | |||
652 | }; | 652 | }; |
653 | 653 | ||
654 | /* getxattr ACL interface flags */ | 654 | /* getxattr ACL interface flags */ |
655 | #define NFS4_ACL_LEN_REQUEST 0x0001 /* zero length getxattr buffer */ | 655 | #define NFS4_ACL_TRUNC 0x0001 /* ACL was truncated */ |
656 | struct nfs_getaclres { | 656 | struct nfs_getaclres { |
657 | size_t acl_len; | 657 | size_t acl_len; |
658 | size_t acl_data_offset; | 658 | size_t acl_data_offset; |
diff --git a/include/linux/of.h b/include/linux/of.h index 1b1163225f3b..5c7a15836996 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
@@ -315,6 +315,12 @@ static inline const char* of_node_full_name(struct device_node *np) | |||
315 | return "<no-node>"; | 315 | return "<no-node>"; |
316 | } | 316 | } |
317 | 317 | ||
318 | static inline struct device_node *of_find_node_by_name(struct device_node *from, | ||
319 | const char *name) | ||
320 | { | ||
321 | return NULL; | ||
322 | } | ||
323 | |||
318 | static inline bool of_have_populated_dt(void) | 324 | static inline bool of_have_populated_dt(void) |
319 | { | 325 | { |
320 | return false; | 326 | return false; |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index fc3526077348..6b4565c440c8 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -2149,7 +2149,7 @@ | |||
2149 | #define PCI_DEVICE_ID_TIGON3_5704S 0x16a8 | 2149 | #define PCI_DEVICE_ID_TIGON3_5704S 0x16a8 |
2150 | #define PCI_DEVICE_ID_NX2_57800_VF 0x16a9 | 2150 | #define PCI_DEVICE_ID_NX2_57800_VF 0x16a9 |
2151 | #define PCI_DEVICE_ID_NX2_5706S 0x16aa | 2151 | #define PCI_DEVICE_ID_NX2_5706S 0x16aa |
2152 | #define PCI_DEVICE_ID_NX2_57840_MF 0x16ab | 2152 | #define PCI_DEVICE_ID_NX2_57840_MF 0x16a4 |
2153 | #define PCI_DEVICE_ID_NX2_5708S 0x16ac | 2153 | #define PCI_DEVICE_ID_NX2_5708S 0x16ac |
2154 | #define PCI_DEVICE_ID_NX2_57840_VF 0x16ad | 2154 | #define PCI_DEVICE_ID_NX2_57840_VF 0x16ad |
2155 | #define PCI_DEVICE_ID_NX2_57810_MF 0x16ae | 2155 | #define PCI_DEVICE_ID_NX2_57810_MF 0x16ae |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 7602ccb3f40e..33ed9d605f91 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
@@ -926,7 +926,7 @@ struct perf_event { | |||
926 | struct hw_perf_event hw; | 926 | struct hw_perf_event hw; |
927 | 927 | ||
928 | struct perf_event_context *ctx; | 928 | struct perf_event_context *ctx; |
929 | struct file *filp; | 929 | atomic_long_t refcount; |
930 | 930 | ||
931 | /* | 931 | /* |
932 | * These accumulate total time (in nanoseconds) that children | 932 | * These accumulate total time (in nanoseconds) that children |
@@ -1296,6 +1296,7 @@ extern int perf_swevent_get_recursion_context(void); | |||
1296 | extern void perf_swevent_put_recursion_context(int rctx); | 1296 | extern void perf_swevent_put_recursion_context(int rctx); |
1297 | extern void perf_event_enable(struct perf_event *event); | 1297 | extern void perf_event_enable(struct perf_event *event); |
1298 | extern void perf_event_disable(struct perf_event *event); | 1298 | extern void perf_event_disable(struct perf_event *event); |
1299 | extern int __perf_event_disable(void *info); | ||
1299 | extern void perf_event_task_tick(void); | 1300 | extern void perf_event_task_tick(void); |
1300 | #else | 1301 | #else |
1301 | static inline void | 1302 | static inline void |
@@ -1334,6 +1335,7 @@ static inline int perf_swevent_get_recursion_context(void) { return -1; } | |||
1334 | static inline void perf_swevent_put_recursion_context(int rctx) { } | 1335 | static inline void perf_swevent_put_recursion_context(int rctx) { } |
1335 | static inline void perf_event_enable(struct perf_event *event) { } | 1336 | static inline void perf_event_enable(struct perf_event *event) { } |
1336 | static inline void perf_event_disable(struct perf_event *event) { } | 1337 | static inline void perf_event_disable(struct perf_event *event) { } |
1338 | static inline int __perf_event_disable(void *info) { return -1; } | ||
1337 | static inline void perf_event_task_tick(void) { } | 1339 | static inline void perf_event_task_tick(void) { } |
1338 | #endif | 1340 | #endif |
1339 | 1341 | ||
diff --git a/include/linux/platform_data/asoc-mx27vis.h b/include/linux/platform_data/asoc-mx27vis.h new file mode 100644 index 000000000000..409adcd04d04 --- /dev/null +++ b/include/linux/platform_data/asoc-mx27vis.h | |||
@@ -0,0 +1,11 @@ | |||
1 | #ifndef __PLATFORM_DATA_ASOC_MX27VIS_H | ||
2 | #define __PLATFORM_DATA_ASOC_MX27VIS_H | ||
3 | |||
4 | struct snd_mx27vis_platform_data { | ||
5 | int amp_gain0_gpio; | ||
6 | int amp_gain1_gpio; | ||
7 | int amp_mutel_gpio; | ||
8 | int amp_muter_gpio; | ||
9 | }; | ||
10 | |||
11 | #endif /* __PLATFORM_DATA_ASOC_MX27VIS_H */ | ||
diff --git a/arch/arm/mach-davinci/include/mach/asp.h b/include/linux/platform_data/davinci_asp.h index 9aa240909a2c..d0c5825876f8 100644 --- a/arch/arm/mach-davinci/include/mach/asp.h +++ b/include/linux/platform_data/davinci_asp.h | |||
@@ -1,59 +1,26 @@ | |||
1 | /* | 1 | /* |
2 | * <mach/asp.h> - DaVinci Audio Serial Port support | 2 | * TI DaVinci Audio Serial Port support |
3 | * | ||
4 | * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation version 2. | ||
9 | * | ||
10 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
11 | * kind, whether express or implied; without even the implied warranty | ||
12 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
3 | */ | 14 | */ |
4 | #ifndef __ASM_ARCH_DAVINCI_ASP_H | ||
5 | #define __ASM_ARCH_DAVINCI_ASP_H | ||
6 | 15 | ||
7 | #include <mach/irqs.h> | 16 | #ifndef __DAVINCI_ASP_H |
8 | #include <mach/edma.h> | 17 | #define __DAVINCI_ASP_H |
9 | |||
10 | /* Bases of dm644x and dm355 register banks */ | ||
11 | #define DAVINCI_ASP0_BASE 0x01E02000 | ||
12 | #define DAVINCI_ASP1_BASE 0x01E04000 | ||
13 | |||
14 | /* Bases of dm365 register banks */ | ||
15 | #define DAVINCI_DM365_ASP0_BASE 0x01D02000 | ||
16 | |||
17 | /* Bases of dm646x register banks */ | ||
18 | #define DAVINCI_DM646X_MCASP0_REG_BASE 0x01D01000 | ||
19 | #define DAVINCI_DM646X_MCASP1_REG_BASE 0x01D01800 | ||
20 | |||
21 | /* Bases of da850/da830 McASP0 register banks */ | ||
22 | #define DAVINCI_DA8XX_MCASP0_REG_BASE 0x01D00000 | ||
23 | |||
24 | /* Bases of da830 McASP1 register banks */ | ||
25 | #define DAVINCI_DA830_MCASP1_REG_BASE 0x01D04000 | ||
26 | |||
27 | /* EDMA channels of dm644x and dm355 */ | ||
28 | #define DAVINCI_DMA_ASP0_TX 2 | ||
29 | #define DAVINCI_DMA_ASP0_RX 3 | ||
30 | #define DAVINCI_DMA_ASP1_TX 8 | ||
31 | #define DAVINCI_DMA_ASP1_RX 9 | ||
32 | |||
33 | /* EDMA channels of dm646x */ | ||
34 | #define DAVINCI_DM646X_DMA_MCASP0_AXEVT0 6 | ||
35 | #define DAVINCI_DM646X_DMA_MCASP0_AREVT0 9 | ||
36 | #define DAVINCI_DM646X_DMA_MCASP1_AXEVT1 12 | ||
37 | |||
38 | /* EDMA channels of da850/da830 McASP0 */ | ||
39 | #define DAVINCI_DA8XX_DMA_MCASP0_AREVT 0 | ||
40 | #define DAVINCI_DA8XX_DMA_MCASP0_AXEVT 1 | ||
41 | |||
42 | /* EDMA channels of da830 McASP1 */ | ||
43 | #define DAVINCI_DA830_DMA_MCASP1_AREVT 2 | ||
44 | #define DAVINCI_DA830_DMA_MCASP1_AXEVT 3 | ||
45 | |||
46 | /* Interrupts */ | ||
47 | #define DAVINCI_ASP0_RX_INT IRQ_MBRINT | ||
48 | #define DAVINCI_ASP0_TX_INT IRQ_MBXINT | ||
49 | #define DAVINCI_ASP1_RX_INT IRQ_MBRINT | ||
50 | #define DAVINCI_ASP1_TX_INT IRQ_MBXINT | ||
51 | 18 | ||
52 | struct snd_platform_data { | 19 | struct snd_platform_data { |
53 | u32 tx_dma_offset; | 20 | u32 tx_dma_offset; |
54 | u32 rx_dma_offset; | 21 | u32 rx_dma_offset; |
55 | enum dma_event_q asp_chan_q; /* event queue number for ASP channel */ | 22 | int asp_chan_q; /* event queue number for ASP channel */ |
56 | enum dma_event_q ram_chan_q; /* event queue number for RAM channel */ | 23 | int ram_chan_q; /* event queue number for RAM channel */ |
57 | unsigned int codec_fmt; | 24 | unsigned int codec_fmt; |
58 | /* | 25 | /* |
59 | * Allowing this is more efficient and eliminates left and right swaps | 26 | * Allowing this is more efficient and eliminates left and right swaps |
@@ -70,7 +37,7 @@ struct snd_platform_data { | |||
70 | * and MCBSP_CLKS. | 37 | * and MCBSP_CLKS. |
71 | * Depending on different hardware connections it is possible | 38 | * Depending on different hardware connections it is possible |
72 | * to use this setting to change the behaviour of McBSP | 39 | * to use this setting to change the behaviour of McBSP |
73 | * driver. The dm365_clk_input_pin enum is available for dm365 | 40 | * driver. |
74 | */ | 41 | */ |
75 | int clk_input_pin; | 42 | int clk_input_pin; |
76 | 43 | ||
@@ -120,10 +87,11 @@ struct snd_platform_data { | |||
120 | enum { | 87 | enum { |
121 | MCASP_VERSION_1 = 0, /* DM646x */ | 88 | MCASP_VERSION_1 = 0, /* DM646x */ |
122 | MCASP_VERSION_2, /* DA8xx/OMAPL1x */ | 89 | MCASP_VERSION_2, /* DA8xx/OMAPL1x */ |
90 | MCASP_VERSION_3, /* TI81xx/AM33xx */ | ||
123 | }; | 91 | }; |
124 | 92 | ||
125 | enum dm365_clk_input_pin { | 93 | enum mcbsp_clk_input_pin { |
126 | MCBSP_CLKR = 0, /* DM365 */ | 94 | MCBSP_CLKR = 0, /* as in DM365 */ |
127 | MCBSP_CLKS, | 95 | MCBSP_CLKS, |
128 | }; | 96 | }; |
129 | 97 | ||
@@ -134,4 +102,4 @@ enum dm365_clk_input_pin { | |||
134 | #define DAVINCI_MCASP_IIS_MODE 0 | 102 | #define DAVINCI_MCASP_IIS_MODE 0 |
135 | #define DAVINCI_MCASP_DIT_MODE 1 | 103 | #define DAVINCI_MCASP_DIT_MODE 1 |
136 | 104 | ||
137 | #endif /* __ASM_ARCH_DAVINCI_ASP_H */ | 105 | #endif |
diff --git a/include/linux/platform_data/omap-twl4030.h b/include/linux/platform_data/omap-twl4030.h new file mode 100644 index 000000000000..c7bef788daab --- /dev/null +++ b/include/linux/platform_data/omap-twl4030.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /** | ||
2 | * omap-twl4030.h - ASoC machine driver for TI SoC based boards with twl4030 | ||
3 | * codec, header. | ||
4 | * | ||
5 | * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * Author: Peter Ujfalusi <peter.ujfalusi@ti.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * version 2 as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
22 | * 02110-1301 USA | ||
23 | */ | ||
24 | |||
25 | #ifndef _OMAP_TWL4030_H_ | ||
26 | #define _OMAP_TWL4030_H_ | ||
27 | |||
28 | struct omap_tw4030_pdata { | ||
29 | const char *card_name; | ||
30 | }; | ||
31 | |||
32 | #endif /* _OMAP_TWL4030_H_ */ | ||
diff --git a/include/linux/sched.h b/include/linux/sched.h index b8c86648a2f9..23bddac4bad8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -954,7 +954,6 @@ struct sched_domain { | |||
954 | unsigned int smt_gain; | 954 | unsigned int smt_gain; |
955 | int flags; /* See SD_* */ | 955 | int flags; /* See SD_* */ |
956 | int level; | 956 | int level; |
957 | int idle_buddy; /* cpu assigned to select_idle_sibling() */ | ||
958 | 957 | ||
959 | /* Runtime fields. */ | 958 | /* Runtime fields. */ |
960 | unsigned long last_balance; /* init to jiffies. units in jiffies */ | 959 | unsigned long last_balance; /* init to jiffies. units in jiffies */ |
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index cff40aa7db62..bf8c49ff7530 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h | |||
@@ -114,6 +114,7 @@ struct rpc_xprt_ops { | |||
114 | void (*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize); | 114 | void (*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize); |
115 | int (*reserve_xprt)(struct rpc_xprt *xprt, struct rpc_task *task); | 115 | int (*reserve_xprt)(struct rpc_xprt *xprt, struct rpc_task *task); |
116 | void (*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task); | 116 | void (*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task); |
117 | void (*alloc_slot)(struct rpc_xprt *xprt, struct rpc_task *task); | ||
117 | void (*rpcbind)(struct rpc_task *task); | 118 | void (*rpcbind)(struct rpc_task *task); |
118 | void (*set_port)(struct rpc_xprt *xprt, unsigned short port); | 119 | void (*set_port)(struct rpc_xprt *xprt, unsigned short port); |
119 | void (*connect)(struct rpc_task *task); | 120 | void (*connect)(struct rpc_task *task); |
@@ -281,6 +282,8 @@ void xprt_connect(struct rpc_task *task); | |||
281 | void xprt_reserve(struct rpc_task *task); | 282 | void xprt_reserve(struct rpc_task *task); |
282 | int xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task); | 283 | int xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task); |
283 | int xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task); | 284 | int xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task); |
285 | void xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task); | ||
286 | void xprt_lock_and_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task); | ||
284 | int xprt_prepare_transmit(struct rpc_task *task); | 287 | int xprt_prepare_transmit(struct rpc_task *task); |
285 | void xprt_transmit(struct rpc_task *task); | 288 | void xprt_transmit(struct rpc_task *task); |
286 | void xprt_end_transmit(struct rpc_task *task); | 289 | void xprt_end_transmit(struct rpc_task *task); |
diff --git a/include/linux/time.h b/include/linux/time.h index b0bbd8f0130d..b51e664c83e7 100644 --- a/include/linux/time.h +++ b/include/linux/time.h | |||
@@ -125,6 +125,13 @@ static inline bool timespec_valid(const struct timespec *ts) | |||
125 | /* Can't have more nanoseconds then a second */ | 125 | /* Can't have more nanoseconds then a second */ |
126 | if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) | 126 | if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) |
127 | return false; | 127 | return false; |
128 | return true; | ||
129 | } | ||
130 | |||
131 | static inline bool timespec_valid_strict(const struct timespec *ts) | ||
132 | { | ||
133 | if (!timespec_valid(ts)) | ||
134 | return false; | ||
128 | /* Disallow values that could overflow ktime_t */ | 135 | /* Disallow values that could overflow ktime_t */ |
129 | if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX) | 136 | if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX) |
130 | return false; | 137 | return false; |
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h index ca356a734920..8b27927b2a55 100644 --- a/include/net/bluetooth/smp.h +++ b/include/net/bluetooth/smp.h | |||
@@ -136,7 +136,7 @@ struct smp_chan { | |||
136 | }; | 136 | }; |
137 | 137 | ||
138 | /* SMP Commands */ | 138 | /* SMP Commands */ |
139 | int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level); | 139 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); |
140 | int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb); | 140 | int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb); |
141 | int smp_distribute_keys(struct l2cap_conn *conn, __u8 force); | 141 | int smp_distribute_keys(struct l2cap_conn *conn, __u8 force); |
142 | int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); | 142 | int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); |
diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h index e1ce1048fe5f..4a045cda9c60 100644 --- a/include/net/netfilter/nf_conntrack_ecache.h +++ b/include/net/netfilter/nf_conntrack_ecache.h | |||
@@ -18,6 +18,7 @@ struct nf_conntrack_ecache { | |||
18 | u16 ctmask; /* bitmask of ct events to be delivered */ | 18 | u16 ctmask; /* bitmask of ct events to be delivered */ |
19 | u16 expmask; /* bitmask of expect events to be delivered */ | 19 | u16 expmask; /* bitmask of expect events to be delivered */ |
20 | u32 pid; /* netlink pid of destroyer */ | 20 | u32 pid; /* netlink pid of destroyer */ |
21 | struct timer_list timeout; | ||
21 | }; | 22 | }; |
22 | 23 | ||
23 | static inline struct nf_conntrack_ecache * | 24 | static inline struct nf_conntrack_ecache * |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 976a81abe1a2..639dd1316d37 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -273,6 +273,9 @@ struct xfrm_replay { | |||
273 | int (*check)(struct xfrm_state *x, | 273 | int (*check)(struct xfrm_state *x, |
274 | struct sk_buff *skb, | 274 | struct sk_buff *skb, |
275 | __be32 net_seq); | 275 | __be32 net_seq); |
276 | int (*recheck)(struct xfrm_state *x, | ||
277 | struct sk_buff *skb, | ||
278 | __be32 net_seq); | ||
276 | void (*notify)(struct xfrm_state *x, int event); | 279 | void (*notify)(struct xfrm_state *x, int event); |
277 | int (*overflow)(struct xfrm_state *x, struct sk_buff *skb); | 280 | int (*overflow)(struct xfrm_state *x, struct sk_buff *skb); |
278 | }; | 281 | }; |
diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h index 48f2a1ff2bbc..f2912abacdf3 100644 --- a/include/sound/compress_driver.h +++ b/include/sound/compress_driver.h | |||
@@ -61,6 +61,7 @@ struct snd_compr_runtime { | |||
61 | u64 total_bytes_available; | 61 | u64 total_bytes_available; |
62 | u64 total_bytes_transferred; | 62 | u64 total_bytes_transferred; |
63 | wait_queue_head_t sleep; | 63 | wait_queue_head_t sleep; |
64 | void *private_data; | ||
64 | }; | 65 | }; |
65 | 66 | ||
66 | /** | 67 | /** |
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 1f69e0af2941..628db7bca4fd 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | struct snd_pcm_substream; | 19 | struct snd_pcm_substream; |
20 | struct snd_soc_dapm_widget; | 20 | struct snd_soc_dapm_widget; |
21 | struct snd_compr_stream; | ||
21 | 22 | ||
22 | /* | 23 | /* |
23 | * DAI hardware audio formats. | 24 | * DAI hardware audio formats. |
@@ -205,6 +206,8 @@ struct snd_soc_dai_driver { | |||
205 | int (*remove)(struct snd_soc_dai *dai); | 206 | int (*remove)(struct snd_soc_dai *dai); |
206 | int (*suspend)(struct snd_soc_dai *dai); | 207 | int (*suspend)(struct snd_soc_dai *dai); |
207 | int (*resume)(struct snd_soc_dai *dai); | 208 | int (*resume)(struct snd_soc_dai *dai); |
209 | /* compress dai */ | ||
210 | bool compress_dai; | ||
208 | 211 | ||
209 | /* ops */ | 212 | /* ops */ |
210 | const struct snd_soc_dai_ops *ops; | 213 | const struct snd_soc_dai_ops *ops; |
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index abe373d57adc..c96bf5ae80a6 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h | |||
@@ -244,10 +244,11 @@ struct device; | |||
244 | { .id = snd_soc_dapm_supply, .name = wname, .reg = wreg, \ | 244 | { .id = snd_soc_dapm_supply, .name = wname, .reg = wreg, \ |
245 | .shift = wshift, .invert = winvert, .event = wevent, \ | 245 | .shift = wshift, .invert = winvert, .event = wevent, \ |
246 | .event_flags = wflags} | 246 | .event_flags = wflags} |
247 | #define SND_SOC_DAPM_REGULATOR_SUPPLY(wname, wdelay) \ | 247 | #define SND_SOC_DAPM_REGULATOR_SUPPLY(wname, wdelay, wflags) \ |
248 | { .id = snd_soc_dapm_regulator_supply, .name = wname, \ | 248 | { .id = snd_soc_dapm_regulator_supply, .name = wname, \ |
249 | .reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \ | 249 | .reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \ |
250 | .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD } | 250 | .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \ |
251 | .invert = wflags} | ||
251 | 252 | ||
252 | 253 | ||
253 | /* dapm kcontrol types */ | 254 | /* dapm kcontrol types */ |
@@ -412,6 +413,7 @@ void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec); | |||
412 | 413 | ||
413 | /* Mostly internal - should not normally be used */ | 414 | /* Mostly internal - should not normally be used */ |
414 | void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason); | 415 | void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason); |
416 | void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm); | ||
415 | 417 | ||
416 | /* dapm path query */ | 418 | /* dapm path query */ |
417 | int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, | 419 | int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, |
@@ -510,7 +512,6 @@ struct snd_soc_dapm_widget { | |||
510 | /* dapm control */ | 512 | /* dapm control */ |
511 | int reg; /* negative reg = no direct dapm */ | 513 | int reg; /* negative reg = no direct dapm */ |
512 | unsigned char shift; /* bits to shift */ | 514 | unsigned char shift; /* bits to shift */ |
513 | unsigned int saved_value; /* widget saved value */ | ||
514 | unsigned int value; /* widget current value */ | 515 | unsigned int value; /* widget current value */ |
515 | unsigned int mask; /* non-shifted mask */ | 516 | unsigned int mask; /* non-shifted mask */ |
516 | unsigned int on_val; /* on state value */ | 517 | unsigned int on_val; /* on state value */ |
diff --git a/include/sound/soc.h b/include/sound/soc.h index e063380f63a2..91244a096c19 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -20,8 +20,10 @@ | |||
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/regmap.h> | 22 | #include <linux/regmap.h> |
23 | #include <linux/log2.h> | ||
23 | #include <sound/core.h> | 24 | #include <sound/core.h> |
24 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
26 | #include <sound/compress_driver.h> | ||
25 | #include <sound/control.h> | 27 | #include <sound/control.h> |
26 | #include <sound/ac97_codec.h> | 28 | #include <sound/ac97_codec.h> |
27 | 29 | ||
@@ -159,7 +161,8 @@ | |||
159 | .platform_max = xmax} } | 161 | .platform_max = xmax} } |
160 | #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \ | 162 | #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \ |
161 | { .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ | 163 | { .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ |
162 | .max = xmax, .texts = xtexts } | 164 | .max = xmax, .texts = xtexts, \ |
165 | .mask = xmax ? roundup_pow_of_two(xmax) - 1 : 0} | ||
163 | #define SOC_ENUM_SINGLE(xreg, xshift, xmax, xtexts) \ | 166 | #define SOC_ENUM_SINGLE(xreg, xshift, xmax, xtexts) \ |
164 | SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmax, xtexts) | 167 | SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmax, xtexts) |
165 | #define SOC_ENUM_SINGLE_EXT(xmax, xtexts) \ | 168 | #define SOC_ENUM_SINGLE_EXT(xmax, xtexts) \ |
@@ -399,6 +402,7 @@ int snd_soc_platform_read(struct snd_soc_platform *platform, | |||
399 | int snd_soc_platform_write(struct snd_soc_platform *platform, | 402 | int snd_soc_platform_write(struct snd_soc_platform *platform, |
400 | unsigned int reg, unsigned int val); | 403 | unsigned int reg, unsigned int val); |
401 | int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num); | 404 | int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num); |
405 | int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num); | ||
402 | 406 | ||
403 | struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, | 407 | struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, |
404 | const char *dai_link, int stream); | 408 | const char *dai_link, int stream); |
@@ -632,6 +636,13 @@ struct snd_soc_ops { | |||
632 | int (*trigger)(struct snd_pcm_substream *, int); | 636 | int (*trigger)(struct snd_pcm_substream *, int); |
633 | }; | 637 | }; |
634 | 638 | ||
639 | struct snd_soc_compr_ops { | ||
640 | int (*startup)(struct snd_compr_stream *); | ||
641 | void (*shutdown)(struct snd_compr_stream *); | ||
642 | int (*set_params)(struct snd_compr_stream *); | ||
643 | int (*trigger)(struct snd_compr_stream *); | ||
644 | }; | ||
645 | |||
635 | /* SoC cache ops */ | 646 | /* SoC cache ops */ |
636 | struct snd_soc_cache_ops { | 647 | struct snd_soc_cache_ops { |
637 | const char *name; | 648 | const char *name; |
@@ -787,9 +798,12 @@ struct snd_soc_platform_driver { | |||
787 | snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *, | 798 | snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *, |
788 | struct snd_soc_dai *); | 799 | struct snd_soc_dai *); |
789 | 800 | ||
790 | /* platform stream ops */ | 801 | /* platform stream pcm ops */ |
791 | struct snd_pcm_ops *ops; | 802 | struct snd_pcm_ops *ops; |
792 | 803 | ||
804 | /* platform stream compress ops */ | ||
805 | struct snd_compr_ops *compr_ops; | ||
806 | |||
793 | /* platform stream completion event */ | 807 | /* platform stream completion event */ |
794 | int (*stream_event)(struct snd_soc_dapm_context *dapm, int event); | 808 | int (*stream_event)(struct snd_soc_dapm_context *dapm, int event); |
795 | 809 | ||
@@ -891,6 +905,7 @@ struct snd_soc_dai_link { | |||
891 | 905 | ||
892 | /* machine stream operations */ | 906 | /* machine stream operations */ |
893 | struct snd_soc_ops *ops; | 907 | struct snd_soc_ops *ops; |
908 | struct snd_soc_compr_ops *compr_ops; | ||
894 | }; | 909 | }; |
895 | 910 | ||
896 | struct snd_soc_codec_conf { | 911 | struct snd_soc_codec_conf { |
@@ -1027,6 +1042,7 @@ struct snd_soc_pcm_runtime { | |||
1027 | 1042 | ||
1028 | /* runtime devices */ | 1043 | /* runtime devices */ |
1029 | struct snd_pcm *pcm; | 1044 | struct snd_pcm *pcm; |
1045 | struct snd_compr *compr; | ||
1030 | struct snd_soc_codec *codec; | 1046 | struct snd_soc_codec *codec; |
1031 | struct snd_soc_platform *platform; | 1047 | struct snd_soc_platform *platform; |
1032 | struct snd_soc_dai *codec_dai; | 1048 | struct snd_soc_dai *codec_dai; |
diff --git a/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h b/include/sound/tegra_wm8903.h index 9d293344a7ff..57b202ee97c3 100644 --- a/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h +++ b/include/sound/tegra_wm8903.h | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h | ||
3 | * | ||
4 | * Copyright 2011 NVIDIA, Inc. | 2 | * Copyright 2011 NVIDIA, Inc. |
5 | * | 3 | * |
6 | * This software is licensed under the terms of the GNU General Public | 4 | * This software is licensed under the terms of the GNU General Public |
@@ -14,6 +12,9 @@ | |||
14 | * | 12 | * |
15 | */ | 13 | */ |
16 | 14 | ||
15 | #ifndef __SOUND_TEGRA_WM38903_H | ||
16 | #define __SOUND_TEGRA_WM38903_H | ||
17 | |||
17 | struct tegra_wm8903_platform_data { | 18 | struct tegra_wm8903_platform_data { |
18 | int gpio_spkr_en; | 19 | int gpio_spkr_en; |
19 | int gpio_hp_det; | 20 | int gpio_hp_det; |
@@ -21,3 +22,5 @@ struct tegra_wm8903_platform_data { | |||
21 | int gpio_int_mic_en; | 22 | int gpio_int_mic_en; |
22 | int gpio_ext_mic_en; | 23 | int gpio_ext_mic_en; |
23 | }; | 24 | }; |
25 | |||
26 | #endif | ||
diff --git a/include/sound/wm0010.h b/include/sound/wm0010.h new file mode 100644 index 000000000000..3261e90815af --- /dev/null +++ b/include/sound/wm0010.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * wm0010.h -- Platform data for WM0010 DSP Driver | ||
3 | * | ||
4 | * Copyright 2012 Wolfson Microelectronics PLC. | ||
5 | * | ||
6 | * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #ifndef WM0010_PDATA_H | ||
15 | #define WM0010_PDATA_H | ||
16 | |||
17 | struct wm0010_pdata { | ||
18 | int gpio_reset; | ||
19 | |||
20 | /* Set if there is an inverter between the GPIO controlling | ||
21 | * the reset signal and the device. | ||
22 | */ | ||
23 | int reset_active_high; | ||
24 | int irq_flags; | ||
25 | }; | ||
26 | |||
27 | #endif | ||
diff --git a/include/sound/wm8960.h b/include/sound/wm8960.h index 74e9a95529c5..e8ce8ee7d62d 100644 --- a/include/sound/wm8960.h +++ b/include/sound/wm8960.h | |||
@@ -18,7 +18,7 @@ | |||
18 | struct wm8960_data { | 18 | struct wm8960_data { |
19 | bool capless; /* Headphone outputs configured in capless mode */ | 19 | bool capless; /* Headphone outputs configured in capless mode */ |
20 | 20 | ||
21 | int dres; /* Discharge resistance for headphone outputs */ | 21 | bool shared_lrclk; /* DAC and ADC LRCLKs are wired together */ |
22 | }; | 22 | }; |
23 | 23 | ||
24 | #endif | 24 | #endif |
diff --git a/include/sound/wm8993.h b/include/sound/wm8993.h index eee19f63c0d8..8016fd826f5a 100644 --- a/include/sound/wm8993.h +++ b/include/sound/wm8993.h | |||
@@ -32,6 +32,10 @@ struct wm8993_platform_data { | |||
32 | unsigned int lineout1fb:1; | 32 | unsigned int lineout1fb:1; |
33 | unsigned int lineout2fb:1; | 33 | unsigned int lineout2fb:1; |
34 | 34 | ||
35 | /* Delay to add for microphones to stabalise after power up */ | ||
36 | int micbias1_delay; | ||
37 | int micbias2_delay; | ||
38 | |||
35 | /* Microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */ | 39 | /* Microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */ |
36 | unsigned int micbias1_lvl:1; | 40 | unsigned int micbias1_lvl:1; |
37 | unsigned int micbias2_lvl:1; | 41 | unsigned int micbias2_lvl:1; |
diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index f1405d335a96..941c84bf1065 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h | |||
@@ -23,7 +23,9 @@ struct se_subsystem_api { | |||
23 | struct se_device *(*create_virtdevice)(struct se_hba *, | 23 | struct se_device *(*create_virtdevice)(struct se_hba *, |
24 | struct se_subsystem_dev *, void *); | 24 | struct se_subsystem_dev *, void *); |
25 | void (*free_device)(void *); | 25 | void (*free_device)(void *); |
26 | int (*transport_complete)(struct se_cmd *cmd, struct scatterlist *); | 26 | void (*transport_complete)(struct se_cmd *cmd, |
27 | struct scatterlist *, | ||
28 | unsigned char *); | ||
27 | 29 | ||
28 | int (*parse_cdb)(struct se_cmd *cmd); | 30 | int (*parse_cdb)(struct se_cmd *cmd); |
29 | ssize_t (*check_configfs_dev_params)(struct se_hba *, | 31 | ssize_t (*check_configfs_dev_params)(struct se_hba *, |
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 015cea01ae39..5be89373ceac 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
@@ -121,6 +121,7 @@ | |||
121 | 121 | ||
122 | #define SE_INQUIRY_BUF 512 | 122 | #define SE_INQUIRY_BUF 512 |
123 | #define SE_MODE_PAGE_BUF 512 | 123 | #define SE_MODE_PAGE_BUF 512 |
124 | #define SE_SENSE_BUF 96 | ||
124 | 125 | ||
125 | /* struct se_hba->hba_flags */ | 126 | /* struct se_hba->hba_flags */ |
126 | enum hba_flags_table { | 127 | enum hba_flags_table { |
diff --git a/kernel/events/core.c b/kernel/events/core.c index b7935fcec7d9..7fee567153f0 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -1253,7 +1253,7 @@ retry: | |||
1253 | /* | 1253 | /* |
1254 | * Cross CPU call to disable a performance event | 1254 | * Cross CPU call to disable a performance event |
1255 | */ | 1255 | */ |
1256 | static int __perf_event_disable(void *info) | 1256 | int __perf_event_disable(void *info) |
1257 | { | 1257 | { |
1258 | struct perf_event *event = info; | 1258 | struct perf_event *event = info; |
1259 | struct perf_event_context *ctx = event->ctx; | 1259 | struct perf_event_context *ctx = event->ctx; |
@@ -2935,12 +2935,12 @@ EXPORT_SYMBOL_GPL(perf_event_release_kernel); | |||
2935 | /* | 2935 | /* |
2936 | * Called when the last reference to the file is gone. | 2936 | * Called when the last reference to the file is gone. |
2937 | */ | 2937 | */ |
2938 | static int perf_release(struct inode *inode, struct file *file) | 2938 | static void put_event(struct perf_event *event) |
2939 | { | 2939 | { |
2940 | struct perf_event *event = file->private_data; | ||
2941 | struct task_struct *owner; | 2940 | struct task_struct *owner; |
2942 | 2941 | ||
2943 | file->private_data = NULL; | 2942 | if (!atomic_long_dec_and_test(&event->refcount)) |
2943 | return; | ||
2944 | 2944 | ||
2945 | rcu_read_lock(); | 2945 | rcu_read_lock(); |
2946 | owner = ACCESS_ONCE(event->owner); | 2946 | owner = ACCESS_ONCE(event->owner); |
@@ -2975,7 +2975,13 @@ static int perf_release(struct inode *inode, struct file *file) | |||
2975 | put_task_struct(owner); | 2975 | put_task_struct(owner); |
2976 | } | 2976 | } |
2977 | 2977 | ||
2978 | return perf_event_release_kernel(event); | 2978 | perf_event_release_kernel(event); |
2979 | } | ||
2980 | |||
2981 | static int perf_release(struct inode *inode, struct file *file) | ||
2982 | { | ||
2983 | put_event(file->private_data); | ||
2984 | return 0; | ||
2979 | } | 2985 | } |
2980 | 2986 | ||
2981 | u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) | 2987 | u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) |
@@ -3227,7 +3233,7 @@ unlock: | |||
3227 | 3233 | ||
3228 | static const struct file_operations perf_fops; | 3234 | static const struct file_operations perf_fops; |
3229 | 3235 | ||
3230 | static struct perf_event *perf_fget_light(int fd, int *fput_needed) | 3236 | static struct file *perf_fget_light(int fd, int *fput_needed) |
3231 | { | 3237 | { |
3232 | struct file *file; | 3238 | struct file *file; |
3233 | 3239 | ||
@@ -3241,7 +3247,7 @@ static struct perf_event *perf_fget_light(int fd, int *fput_needed) | |||
3241 | return ERR_PTR(-EBADF); | 3247 | return ERR_PTR(-EBADF); |
3242 | } | 3248 | } |
3243 | 3249 | ||
3244 | return file->private_data; | 3250 | return file; |
3245 | } | 3251 | } |
3246 | 3252 | ||
3247 | static int perf_event_set_output(struct perf_event *event, | 3253 | static int perf_event_set_output(struct perf_event *event, |
@@ -3273,19 +3279,21 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
3273 | 3279 | ||
3274 | case PERF_EVENT_IOC_SET_OUTPUT: | 3280 | case PERF_EVENT_IOC_SET_OUTPUT: |
3275 | { | 3281 | { |
3282 | struct file *output_file = NULL; | ||
3276 | struct perf_event *output_event = NULL; | 3283 | struct perf_event *output_event = NULL; |
3277 | int fput_needed = 0; | 3284 | int fput_needed = 0; |
3278 | int ret; | 3285 | int ret; |
3279 | 3286 | ||
3280 | if (arg != -1) { | 3287 | if (arg != -1) { |
3281 | output_event = perf_fget_light(arg, &fput_needed); | 3288 | output_file = perf_fget_light(arg, &fput_needed); |
3282 | if (IS_ERR(output_event)) | 3289 | if (IS_ERR(output_file)) |
3283 | return PTR_ERR(output_event); | 3290 | return PTR_ERR(output_file); |
3291 | output_event = output_file->private_data; | ||
3284 | } | 3292 | } |
3285 | 3293 | ||
3286 | ret = perf_event_set_output(event, output_event); | 3294 | ret = perf_event_set_output(event, output_event); |
3287 | if (output_event) | 3295 | if (output_event) |
3288 | fput_light(output_event->filp, fput_needed); | 3296 | fput_light(output_file, fput_needed); |
3289 | 3297 | ||
3290 | return ret; | 3298 | return ret; |
3291 | } | 3299 | } |
@@ -5950,6 +5958,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, | |||
5950 | 5958 | ||
5951 | mutex_init(&event->mmap_mutex); | 5959 | mutex_init(&event->mmap_mutex); |
5952 | 5960 | ||
5961 | atomic_long_set(&event->refcount, 1); | ||
5953 | event->cpu = cpu; | 5962 | event->cpu = cpu; |
5954 | event->attr = *attr; | 5963 | event->attr = *attr; |
5955 | event->group_leader = group_leader; | 5964 | event->group_leader = group_leader; |
@@ -6260,12 +6269,12 @@ SYSCALL_DEFINE5(perf_event_open, | |||
6260 | return event_fd; | 6269 | return event_fd; |
6261 | 6270 | ||
6262 | if (group_fd != -1) { | 6271 | if (group_fd != -1) { |
6263 | group_leader = perf_fget_light(group_fd, &fput_needed); | 6272 | group_file = perf_fget_light(group_fd, &fput_needed); |
6264 | if (IS_ERR(group_leader)) { | 6273 | if (IS_ERR(group_file)) { |
6265 | err = PTR_ERR(group_leader); | 6274 | err = PTR_ERR(group_file); |
6266 | goto err_fd; | 6275 | goto err_fd; |
6267 | } | 6276 | } |
6268 | group_file = group_leader->filp; | 6277 | group_leader = group_file->private_data; |
6269 | if (flags & PERF_FLAG_FD_OUTPUT) | 6278 | if (flags & PERF_FLAG_FD_OUTPUT) |
6270 | output_event = group_leader; | 6279 | output_event = group_leader; |
6271 | if (flags & PERF_FLAG_FD_NO_GROUP) | 6280 | if (flags & PERF_FLAG_FD_NO_GROUP) |
@@ -6402,7 +6411,6 @@ SYSCALL_DEFINE5(perf_event_open, | |||
6402 | put_ctx(gctx); | 6411 | put_ctx(gctx); |
6403 | } | 6412 | } |
6404 | 6413 | ||
6405 | event->filp = event_file; | ||
6406 | WARN_ON_ONCE(ctx->parent_ctx); | 6414 | WARN_ON_ONCE(ctx->parent_ctx); |
6407 | mutex_lock(&ctx->mutex); | 6415 | mutex_lock(&ctx->mutex); |
6408 | 6416 | ||
@@ -6496,7 +6504,6 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, | |||
6496 | goto err_free; | 6504 | goto err_free; |
6497 | } | 6505 | } |
6498 | 6506 | ||
6499 | event->filp = NULL; | ||
6500 | WARN_ON_ONCE(ctx->parent_ctx); | 6507 | WARN_ON_ONCE(ctx->parent_ctx); |
6501 | mutex_lock(&ctx->mutex); | 6508 | mutex_lock(&ctx->mutex); |
6502 | perf_install_in_context(ctx, event, cpu); | 6509 | perf_install_in_context(ctx, event, cpu); |
@@ -6578,7 +6585,7 @@ static void sync_child_event(struct perf_event *child_event, | |||
6578 | * Release the parent event, if this was the last | 6585 | * Release the parent event, if this was the last |
6579 | * reference to it. | 6586 | * reference to it. |
6580 | */ | 6587 | */ |
6581 | fput(parent_event->filp); | 6588 | put_event(parent_event); |
6582 | } | 6589 | } |
6583 | 6590 | ||
6584 | static void | 6591 | static void |
@@ -6654,9 +6661,8 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn) | |||
6654 | * | 6661 | * |
6655 | * __perf_event_exit_task() | 6662 | * __perf_event_exit_task() |
6656 | * sync_child_event() | 6663 | * sync_child_event() |
6657 | * fput(parent_event->filp) | 6664 | * put_event() |
6658 | * perf_release() | 6665 | * mutex_lock(&ctx->mutex) |
6659 | * mutex_lock(&ctx->mutex) | ||
6660 | * | 6666 | * |
6661 | * But since its the parent context it won't be the same instance. | 6667 | * But since its the parent context it won't be the same instance. |
6662 | */ | 6668 | */ |
@@ -6724,7 +6730,7 @@ static void perf_free_event(struct perf_event *event, | |||
6724 | list_del_init(&event->child_list); | 6730 | list_del_init(&event->child_list); |
6725 | mutex_unlock(&parent->child_mutex); | 6731 | mutex_unlock(&parent->child_mutex); |
6726 | 6732 | ||
6727 | fput(parent->filp); | 6733 | put_event(parent); |
6728 | 6734 | ||
6729 | perf_group_detach(event); | 6735 | perf_group_detach(event); |
6730 | list_del_event(event, ctx); | 6736 | list_del_event(event, ctx); |
@@ -6804,6 +6810,12 @@ inherit_event(struct perf_event *parent_event, | |||
6804 | NULL, NULL); | 6810 | NULL, NULL); |
6805 | if (IS_ERR(child_event)) | 6811 | if (IS_ERR(child_event)) |
6806 | return child_event; | 6812 | return child_event; |
6813 | |||
6814 | if (!atomic_long_inc_not_zero(&parent_event->refcount)) { | ||
6815 | free_event(child_event); | ||
6816 | return NULL; | ||
6817 | } | ||
6818 | |||
6807 | get_ctx(child_ctx); | 6819 | get_ctx(child_ctx); |
6808 | 6820 | ||
6809 | /* | 6821 | /* |
@@ -6845,14 +6857,6 @@ inherit_event(struct perf_event *parent_event, | |||
6845 | raw_spin_unlock_irqrestore(&child_ctx->lock, flags); | 6857 | raw_spin_unlock_irqrestore(&child_ctx->lock, flags); |
6846 | 6858 | ||
6847 | /* | 6859 | /* |
6848 | * Get a reference to the parent filp - we will fput it | ||
6849 | * when the child event exits. This is safe to do because | ||
6850 | * we are in the parent and we know that the filp still | ||
6851 | * exists and has a nonzero count: | ||
6852 | */ | ||
6853 | atomic_long_inc(&parent_event->filp->f_count); | ||
6854 | |||
6855 | /* | ||
6856 | * Link this into the parent event's child list | 6860 | * Link this into the parent event's child list |
6857 | */ | 6861 | */ |
6858 | WARN_ON_ONCE(parent_event->ctx->parent_ctx); | 6862 | WARN_ON_ONCE(parent_event->ctx->parent_ctx); |
diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c index bb38c4d3ee12..9a7b487c6fe2 100644 --- a/kernel/events/hw_breakpoint.c +++ b/kernel/events/hw_breakpoint.c | |||
@@ -453,7 +453,16 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att | |||
453 | int old_type = bp->attr.bp_type; | 453 | int old_type = bp->attr.bp_type; |
454 | int err = 0; | 454 | int err = 0; |
455 | 455 | ||
456 | perf_event_disable(bp); | 456 | /* |
457 | * modify_user_hw_breakpoint can be invoked with IRQs disabled and hence it | ||
458 | * will not be possible to raise IPIs that invoke __perf_event_disable. | ||
459 | * So call the function directly after making sure we are targeting the | ||
460 | * current task. | ||
461 | */ | ||
462 | if (irqs_disabled() && bp->ctx && bp->ctx->task == current) | ||
463 | __perf_event_disable(bp); | ||
464 | else | ||
465 | perf_event_disable(bp); | ||
457 | 466 | ||
458 | bp->attr.bp_addr = attr->bp_addr; | 467 | bp->attr.bp_addr = attr->bp_addr; |
459 | bp->attr.bp_type = attr->bp_type; | 468 | bp->attr.bp_type = attr->bp_type; |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index fbf1fd098dc6..649c9f876cb1 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -5304,27 +5304,17 @@ void idle_task_exit(void) | |||
5304 | } | 5304 | } |
5305 | 5305 | ||
5306 | /* | 5306 | /* |
5307 | * While a dead CPU has no uninterruptible tasks queued at this point, | 5307 | * Since this CPU is going 'away' for a while, fold any nr_active delta |
5308 | * it might still have a nonzero ->nr_uninterruptible counter, because | 5308 | * we might have. Assumes we're called after migrate_tasks() so that the |
5309 | * for performance reasons the counter is not stricly tracking tasks to | 5309 | * nr_active count is stable. |
5310 | * their home CPUs. So we just add the counter to another CPU's counter, | 5310 | * |
5311 | * to keep the global sum constant after CPU-down: | 5311 | * Also see the comment "Global load-average calculations". |
5312 | */ | ||
5313 | static void migrate_nr_uninterruptible(struct rq *rq_src) | ||
5314 | { | ||
5315 | struct rq *rq_dest = cpu_rq(cpumask_any(cpu_active_mask)); | ||
5316 | |||
5317 | rq_dest->nr_uninterruptible += rq_src->nr_uninterruptible; | ||
5318 | rq_src->nr_uninterruptible = 0; | ||
5319 | } | ||
5320 | |||
5321 | /* | ||
5322 | * remove the tasks which were accounted by rq from calc_load_tasks. | ||
5323 | */ | 5312 | */ |
5324 | static void calc_global_load_remove(struct rq *rq) | 5313 | static void calc_load_migrate(struct rq *rq) |
5325 | { | 5314 | { |
5326 | atomic_long_sub(rq->calc_load_active, &calc_load_tasks); | 5315 | long delta = calc_load_fold_active(rq); |
5327 | rq->calc_load_active = 0; | 5316 | if (delta) |
5317 | atomic_long_add(delta, &calc_load_tasks); | ||
5328 | } | 5318 | } |
5329 | 5319 | ||
5330 | /* | 5320 | /* |
@@ -5352,9 +5342,6 @@ static void migrate_tasks(unsigned int dead_cpu) | |||
5352 | */ | 5342 | */ |
5353 | rq->stop = NULL; | 5343 | rq->stop = NULL; |
5354 | 5344 | ||
5355 | /* Ensure any throttled groups are reachable by pick_next_task */ | ||
5356 | unthrottle_offline_cfs_rqs(rq); | ||
5357 | |||
5358 | for ( ; ; ) { | 5345 | for ( ; ; ) { |
5359 | /* | 5346 | /* |
5360 | * There's this thread running, bail when that's the only | 5347 | * There's this thread running, bail when that's the only |
@@ -5618,8 +5605,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
5618 | BUG_ON(rq->nr_running != 1); /* the migration thread */ | 5605 | BUG_ON(rq->nr_running != 1); /* the migration thread */ |
5619 | raw_spin_unlock_irqrestore(&rq->lock, flags); | 5606 | raw_spin_unlock_irqrestore(&rq->lock, flags); |
5620 | 5607 | ||
5621 | migrate_nr_uninterruptible(rq); | 5608 | calc_load_migrate(rq); |
5622 | calc_global_load_remove(rq); | ||
5623 | break; | 5609 | break; |
5624 | #endif | 5610 | #endif |
5625 | } | 5611 | } |
@@ -6028,11 +6014,6 @@ static void destroy_sched_domains(struct sched_domain *sd, int cpu) | |||
6028 | * SD_SHARE_PKG_RESOURCE set (Last Level Cache Domain) for this | 6014 | * SD_SHARE_PKG_RESOURCE set (Last Level Cache Domain) for this |
6029 | * allows us to avoid some pointer chasing select_idle_sibling(). | 6015 | * allows us to avoid some pointer chasing select_idle_sibling(). |
6030 | * | 6016 | * |
6031 | * Iterate domains and sched_groups downward, assigning CPUs to be | ||
6032 | * select_idle_sibling() hw buddy. Cross-wiring hw makes bouncing | ||
6033 | * due to random perturbation self canceling, ie sw buddies pull | ||
6034 | * their counterpart to their CPU's hw counterpart. | ||
6035 | * | ||
6036 | * Also keep a unique ID per domain (we use the first cpu number in | 6017 | * Also keep a unique ID per domain (we use the first cpu number in |
6037 | * the cpumask of the domain), this allows us to quickly tell if | 6018 | * the cpumask of the domain), this allows us to quickly tell if |
6038 | * two cpus are in the same cache domain, see cpus_share_cache(). | 6019 | * two cpus are in the same cache domain, see cpus_share_cache(). |
@@ -6046,40 +6027,8 @@ static void update_top_cache_domain(int cpu) | |||
6046 | int id = cpu; | 6027 | int id = cpu; |
6047 | 6028 | ||
6048 | sd = highest_flag_domain(cpu, SD_SHARE_PKG_RESOURCES); | 6029 | sd = highest_flag_domain(cpu, SD_SHARE_PKG_RESOURCES); |
6049 | if (sd) { | 6030 | if (sd) |
6050 | struct sched_domain *tmp = sd; | ||
6051 | struct sched_group *sg, *prev; | ||
6052 | bool right; | ||
6053 | |||
6054 | /* | ||
6055 | * Traverse to first CPU in group, and count hops | ||
6056 | * to cpu from there, switching direction on each | ||
6057 | * hop, never ever pointing the last CPU rightward. | ||
6058 | */ | ||
6059 | do { | ||
6060 | id = cpumask_first(sched_domain_span(tmp)); | ||
6061 | prev = sg = tmp->groups; | ||
6062 | right = 1; | ||
6063 | |||
6064 | while (cpumask_first(sched_group_cpus(sg)) != id) | ||
6065 | sg = sg->next; | ||
6066 | |||
6067 | while (!cpumask_test_cpu(cpu, sched_group_cpus(sg))) { | ||
6068 | prev = sg; | ||
6069 | sg = sg->next; | ||
6070 | right = !right; | ||
6071 | } | ||
6072 | |||
6073 | /* A CPU went down, never point back to domain start. */ | ||
6074 | if (right && cpumask_first(sched_group_cpus(sg->next)) == id) | ||
6075 | right = false; | ||
6076 | |||
6077 | sg = right ? sg->next : prev; | ||
6078 | tmp->idle_buddy = cpumask_first(sched_group_cpus(sg)); | ||
6079 | } while ((tmp = tmp->child)); | ||
6080 | |||
6081 | id = cpumask_first(sched_domain_span(sd)); | 6031 | id = cpumask_first(sched_domain_span(sd)); |
6082 | } | ||
6083 | 6032 | ||
6084 | rcu_assign_pointer(per_cpu(sd_llc, cpu), sd); | 6033 | rcu_assign_pointer(per_cpu(sd_llc, cpu), sd); |
6085 | per_cpu(sd_llc_id, cpu) = id; | 6034 | per_cpu(sd_llc_id, cpu) = id; |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index c219bf8d704c..96e2b18b6283 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -2052,7 +2052,7 @@ static void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b) | |||
2052 | hrtimer_cancel(&cfs_b->slack_timer); | 2052 | hrtimer_cancel(&cfs_b->slack_timer); |
2053 | } | 2053 | } |
2054 | 2054 | ||
2055 | void unthrottle_offline_cfs_rqs(struct rq *rq) | 2055 | static void unthrottle_offline_cfs_rqs(struct rq *rq) |
2056 | { | 2056 | { |
2057 | struct cfs_rq *cfs_rq; | 2057 | struct cfs_rq *cfs_rq; |
2058 | 2058 | ||
@@ -2106,7 +2106,7 @@ static inline struct cfs_bandwidth *tg_cfs_bandwidth(struct task_group *tg) | |||
2106 | return NULL; | 2106 | return NULL; |
2107 | } | 2107 | } |
2108 | static inline void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b) {} | 2108 | static inline void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b) {} |
2109 | void unthrottle_offline_cfs_rqs(struct rq *rq) {} | 2109 | static inline void unthrottle_offline_cfs_rqs(struct rq *rq) {} |
2110 | 2110 | ||
2111 | #endif /* CONFIG_CFS_BANDWIDTH */ | 2111 | #endif /* CONFIG_CFS_BANDWIDTH */ |
2112 | 2112 | ||
@@ -2637,6 +2637,8 @@ static int select_idle_sibling(struct task_struct *p, int target) | |||
2637 | int cpu = smp_processor_id(); | 2637 | int cpu = smp_processor_id(); |
2638 | int prev_cpu = task_cpu(p); | 2638 | int prev_cpu = task_cpu(p); |
2639 | struct sched_domain *sd; | 2639 | struct sched_domain *sd; |
2640 | struct sched_group *sg; | ||
2641 | int i; | ||
2640 | 2642 | ||
2641 | /* | 2643 | /* |
2642 | * If the task is going to be woken-up on this cpu and if it is | 2644 | * If the task is going to be woken-up on this cpu and if it is |
@@ -2653,17 +2655,29 @@ static int select_idle_sibling(struct task_struct *p, int target) | |||
2653 | return prev_cpu; | 2655 | return prev_cpu; |
2654 | 2656 | ||
2655 | /* | 2657 | /* |
2656 | * Otherwise, check assigned siblings to find an elegible idle cpu. | 2658 | * Otherwise, iterate the domains and find an elegible idle cpu. |
2657 | */ | 2659 | */ |
2658 | sd = rcu_dereference(per_cpu(sd_llc, target)); | 2660 | sd = rcu_dereference(per_cpu(sd_llc, target)); |
2659 | |||
2660 | for_each_lower_domain(sd) { | 2661 | for_each_lower_domain(sd) { |
2661 | if (!cpumask_test_cpu(sd->idle_buddy, tsk_cpus_allowed(p))) | 2662 | sg = sd->groups; |
2662 | continue; | 2663 | do { |
2663 | if (idle_cpu(sd->idle_buddy)) | 2664 | if (!cpumask_intersects(sched_group_cpus(sg), |
2664 | return sd->idle_buddy; | 2665 | tsk_cpus_allowed(p))) |
2665 | } | 2666 | goto next; |
2666 | 2667 | ||
2668 | for_each_cpu(i, sched_group_cpus(sg)) { | ||
2669 | if (!idle_cpu(i)) | ||
2670 | goto next; | ||
2671 | } | ||
2672 | |||
2673 | target = cpumask_first_and(sched_group_cpus(sg), | ||
2674 | tsk_cpus_allowed(p)); | ||
2675 | goto done; | ||
2676 | next: | ||
2677 | sg = sg->next; | ||
2678 | } while (sg != sd->groups); | ||
2679 | } | ||
2680 | done: | ||
2667 | return target; | 2681 | return target; |
2668 | } | 2682 | } |
2669 | 2683 | ||
@@ -3658,7 +3672,6 @@ fix_small_capacity(struct sched_domain *sd, struct sched_group *group) | |||
3658 | * @group: sched_group whose statistics are to be updated. | 3672 | * @group: sched_group whose statistics are to be updated. |
3659 | * @load_idx: Load index of sched_domain of this_cpu for load calc. | 3673 | * @load_idx: Load index of sched_domain of this_cpu for load calc. |
3660 | * @local_group: Does group contain this_cpu. | 3674 | * @local_group: Does group contain this_cpu. |
3661 | * @cpus: Set of cpus considered for load balancing. | ||
3662 | * @balance: Should we balance. | 3675 | * @balance: Should we balance. |
3663 | * @sgs: variable to hold the statistics for this group. | 3676 | * @sgs: variable to hold the statistics for this group. |
3664 | */ | 3677 | */ |
@@ -3805,7 +3818,6 @@ static bool update_sd_pick_busiest(struct lb_env *env, | |||
3805 | /** | 3818 | /** |
3806 | * update_sd_lb_stats - Update sched_domain's statistics for load balancing. | 3819 | * update_sd_lb_stats - Update sched_domain's statistics for load balancing. |
3807 | * @env: The load balancing environment. | 3820 | * @env: The load balancing environment. |
3808 | * @cpus: Set of cpus considered for load balancing. | ||
3809 | * @balance: Should we balance. | 3821 | * @balance: Should we balance. |
3810 | * @sds: variable to hold the statistics for this sched_domain. | 3822 | * @sds: variable to hold the statistics for this sched_domain. |
3811 | */ | 3823 | */ |
@@ -4956,6 +4968,9 @@ static void rq_online_fair(struct rq *rq) | |||
4956 | static void rq_offline_fair(struct rq *rq) | 4968 | static void rq_offline_fair(struct rq *rq) |
4957 | { | 4969 | { |
4958 | update_sysctl(); | 4970 | update_sysctl(); |
4971 | |||
4972 | /* Ensure any throttled groups are reachable by pick_next_task */ | ||
4973 | unthrottle_offline_cfs_rqs(rq); | ||
4959 | } | 4974 | } |
4960 | 4975 | ||
4961 | #endif /* CONFIG_SMP */ | 4976 | #endif /* CONFIG_SMP */ |
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 944cb68420e9..e0b7ba9c040f 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c | |||
@@ -691,6 +691,7 @@ balanced: | |||
691 | * runtime - in which case borrowing doesn't make sense. | 691 | * runtime - in which case borrowing doesn't make sense. |
692 | */ | 692 | */ |
693 | rt_rq->rt_runtime = RUNTIME_INF; | 693 | rt_rq->rt_runtime = RUNTIME_INF; |
694 | rt_rq->rt_throttled = 0; | ||
694 | raw_spin_unlock(&rt_rq->rt_runtime_lock); | 695 | raw_spin_unlock(&rt_rq->rt_runtime_lock); |
695 | raw_spin_unlock(&rt_b->rt_runtime_lock); | 696 | raw_spin_unlock(&rt_b->rt_runtime_lock); |
696 | } | 697 | } |
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index f6714d009e77..0848fa36c383 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h | |||
@@ -1144,7 +1144,6 @@ extern void print_rt_stats(struct seq_file *m, int cpu); | |||
1144 | 1144 | ||
1145 | extern void init_cfs_rq(struct cfs_rq *cfs_rq); | 1145 | extern void init_cfs_rq(struct cfs_rq *cfs_rq); |
1146 | extern void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq); | 1146 | extern void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq); |
1147 | extern void unthrottle_offline_cfs_rqs(struct rq *rq); | ||
1148 | 1147 | ||
1149 | extern void account_cfs_bandwidth_used(int enabled, int was_enabled); | 1148 | extern void account_cfs_bandwidth_used(int enabled, int was_enabled); |
1150 | 1149 | ||
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 024540f97f74..3a9e5d5c1091 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -573,6 +573,7 @@ static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now) | |||
573 | tick_do_update_jiffies64(now); | 573 | tick_do_update_jiffies64(now); |
574 | update_cpu_load_nohz(); | 574 | update_cpu_load_nohz(); |
575 | 575 | ||
576 | calc_load_exit_idle(); | ||
576 | touch_softlockup_watchdog(); | 577 | touch_softlockup_watchdog(); |
577 | /* | 578 | /* |
578 | * Cancel the scheduled timer and restore the tick | 579 | * Cancel the scheduled timer and restore the tick |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 0c1485e42be6..34e5eac81424 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -428,7 +428,7 @@ int do_settimeofday(const struct timespec *tv) | |||
428 | struct timespec ts_delta, xt; | 428 | struct timespec ts_delta, xt; |
429 | unsigned long flags; | 429 | unsigned long flags; |
430 | 430 | ||
431 | if (!timespec_valid(tv)) | 431 | if (!timespec_valid_strict(tv)) |
432 | return -EINVAL; | 432 | return -EINVAL; |
433 | 433 | ||
434 | write_seqlock_irqsave(&tk->lock, flags); | 434 | write_seqlock_irqsave(&tk->lock, flags); |
@@ -476,7 +476,7 @@ int timekeeping_inject_offset(struct timespec *ts) | |||
476 | 476 | ||
477 | /* Make sure the proposed value is valid */ | 477 | /* Make sure the proposed value is valid */ |
478 | tmp = timespec_add(tk_xtime(tk), *ts); | 478 | tmp = timespec_add(tk_xtime(tk), *ts); |
479 | if (!timespec_valid(&tmp)) { | 479 | if (!timespec_valid_strict(&tmp)) { |
480 | ret = -EINVAL; | 480 | ret = -EINVAL; |
481 | goto error; | 481 | goto error; |
482 | } | 482 | } |
@@ -659,7 +659,7 @@ void __init timekeeping_init(void) | |||
659 | struct timespec now, boot, tmp; | 659 | struct timespec now, boot, tmp; |
660 | 660 | ||
661 | read_persistent_clock(&now); | 661 | read_persistent_clock(&now); |
662 | if (!timespec_valid(&now)) { | 662 | if (!timespec_valid_strict(&now)) { |
663 | pr_warn("WARNING: Persistent clock returned invalid value!\n" | 663 | pr_warn("WARNING: Persistent clock returned invalid value!\n" |
664 | " Check your CMOS/BIOS settings.\n"); | 664 | " Check your CMOS/BIOS settings.\n"); |
665 | now.tv_sec = 0; | 665 | now.tv_sec = 0; |
@@ -667,7 +667,7 @@ void __init timekeeping_init(void) | |||
667 | } | 667 | } |
668 | 668 | ||
669 | read_boot_clock(&boot); | 669 | read_boot_clock(&boot); |
670 | if (!timespec_valid(&boot)) { | 670 | if (!timespec_valid_strict(&boot)) { |
671 | pr_warn("WARNING: Boot clock returned invalid value!\n" | 671 | pr_warn("WARNING: Boot clock returned invalid value!\n" |
672 | " Check your CMOS/BIOS settings.\n"); | 672 | " Check your CMOS/BIOS settings.\n"); |
673 | boot.tv_sec = 0; | 673 | boot.tv_sec = 0; |
@@ -713,7 +713,7 @@ static struct timespec timekeeping_suspend_time; | |||
713 | static void __timekeeping_inject_sleeptime(struct timekeeper *tk, | 713 | static void __timekeeping_inject_sleeptime(struct timekeeper *tk, |
714 | struct timespec *delta) | 714 | struct timespec *delta) |
715 | { | 715 | { |
716 | if (!timespec_valid(delta)) { | 716 | if (!timespec_valid_strict(delta)) { |
717 | printk(KERN_WARNING "__timekeeping_inject_sleeptime: Invalid " | 717 | printk(KERN_WARNING "__timekeeping_inject_sleeptime: Invalid " |
718 | "sleep delta value!\n"); | 718 | "sleep delta value!\n"); |
719 | return; | 719 | return; |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 692d97628a10..1e1373bcb3e3 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -66,6 +66,7 @@ enum { | |||
66 | 66 | ||
67 | /* pool flags */ | 67 | /* pool flags */ |
68 | POOL_MANAGE_WORKERS = 1 << 0, /* need to manage workers */ | 68 | POOL_MANAGE_WORKERS = 1 << 0, /* need to manage workers */ |
69 | POOL_MANAGING_WORKERS = 1 << 1, /* managing workers */ | ||
69 | 70 | ||
70 | /* worker flags */ | 71 | /* worker flags */ |
71 | WORKER_STARTED = 1 << 0, /* started */ | 72 | WORKER_STARTED = 1 << 0, /* started */ |
@@ -652,7 +653,7 @@ static bool need_to_manage_workers(struct worker_pool *pool) | |||
652 | /* Do we have too many workers and should some go away? */ | 653 | /* Do we have too many workers and should some go away? */ |
653 | static bool too_many_workers(struct worker_pool *pool) | 654 | static bool too_many_workers(struct worker_pool *pool) |
654 | { | 655 | { |
655 | bool managing = mutex_is_locked(&pool->manager_mutex); | 656 | bool managing = pool->flags & POOL_MANAGING_WORKERS; |
656 | int nr_idle = pool->nr_idle + managing; /* manager is considered idle */ | 657 | int nr_idle = pool->nr_idle + managing; /* manager is considered idle */ |
657 | int nr_busy = pool->nr_workers - nr_idle; | 658 | int nr_busy = pool->nr_workers - nr_idle; |
658 | 659 | ||
@@ -1326,6 +1327,15 @@ static void idle_worker_rebind(struct worker *worker) | |||
1326 | 1327 | ||
1327 | /* we did our part, wait for rebind_workers() to finish up */ | 1328 | /* we did our part, wait for rebind_workers() to finish up */ |
1328 | wait_event(gcwq->rebind_hold, !(worker->flags & WORKER_REBIND)); | 1329 | wait_event(gcwq->rebind_hold, !(worker->flags & WORKER_REBIND)); |
1330 | |||
1331 | /* | ||
1332 | * rebind_workers() shouldn't finish until all workers passed the | ||
1333 | * above WORKER_REBIND wait. Tell it when done. | ||
1334 | */ | ||
1335 | spin_lock_irq(&worker->pool->gcwq->lock); | ||
1336 | if (!--worker->idle_rebind->cnt) | ||
1337 | complete(&worker->idle_rebind->done); | ||
1338 | spin_unlock_irq(&worker->pool->gcwq->lock); | ||
1329 | } | 1339 | } |
1330 | 1340 | ||
1331 | /* | 1341 | /* |
@@ -1396,12 +1406,15 @@ retry: | |||
1396 | /* set REBIND and kick idle ones, we'll wait for these later */ | 1406 | /* set REBIND and kick idle ones, we'll wait for these later */ |
1397 | for_each_worker_pool(pool, gcwq) { | 1407 | for_each_worker_pool(pool, gcwq) { |
1398 | list_for_each_entry(worker, &pool->idle_list, entry) { | 1408 | list_for_each_entry(worker, &pool->idle_list, entry) { |
1409 | unsigned long worker_flags = worker->flags; | ||
1410 | |||
1399 | if (worker->flags & WORKER_REBIND) | 1411 | if (worker->flags & WORKER_REBIND) |
1400 | continue; | 1412 | continue; |
1401 | 1413 | ||
1402 | /* morph UNBOUND to REBIND */ | 1414 | /* morph UNBOUND to REBIND atomically */ |
1403 | worker->flags &= ~WORKER_UNBOUND; | 1415 | worker_flags &= ~WORKER_UNBOUND; |
1404 | worker->flags |= WORKER_REBIND; | 1416 | worker_flags |= WORKER_REBIND; |
1417 | ACCESS_ONCE(worker->flags) = worker_flags; | ||
1405 | 1418 | ||
1406 | idle_rebind.cnt++; | 1419 | idle_rebind.cnt++; |
1407 | worker->idle_rebind = &idle_rebind; | 1420 | worker->idle_rebind = &idle_rebind; |
@@ -1419,25 +1432,15 @@ retry: | |||
1419 | goto retry; | 1432 | goto retry; |
1420 | } | 1433 | } |
1421 | 1434 | ||
1422 | /* | 1435 | /* all idle workers are rebound, rebind busy workers */ |
1423 | * All idle workers are rebound and waiting for %WORKER_REBIND to | ||
1424 | * be cleared inside idle_worker_rebind(). Clear and release. | ||
1425 | * Clearing %WORKER_REBIND from this foreign context is safe | ||
1426 | * because these workers are still guaranteed to be idle. | ||
1427 | */ | ||
1428 | for_each_worker_pool(pool, gcwq) | ||
1429 | list_for_each_entry(worker, &pool->idle_list, entry) | ||
1430 | worker->flags &= ~WORKER_REBIND; | ||
1431 | |||
1432 | wake_up_all(&gcwq->rebind_hold); | ||
1433 | |||
1434 | /* rebind busy workers */ | ||
1435 | for_each_busy_worker(worker, i, pos, gcwq) { | 1436 | for_each_busy_worker(worker, i, pos, gcwq) { |
1436 | struct work_struct *rebind_work = &worker->rebind_work; | 1437 | struct work_struct *rebind_work = &worker->rebind_work; |
1438 | unsigned long worker_flags = worker->flags; | ||
1437 | 1439 | ||
1438 | /* morph UNBOUND to REBIND */ | 1440 | /* morph UNBOUND to REBIND atomically */ |
1439 | worker->flags &= ~WORKER_UNBOUND; | 1441 | worker_flags &= ~WORKER_UNBOUND; |
1440 | worker->flags |= WORKER_REBIND; | 1442 | worker_flags |= WORKER_REBIND; |
1443 | ACCESS_ONCE(worker->flags) = worker_flags; | ||
1441 | 1444 | ||
1442 | if (test_and_set_bit(WORK_STRUCT_PENDING_BIT, | 1445 | if (test_and_set_bit(WORK_STRUCT_PENDING_BIT, |
1443 | work_data_bits(rebind_work))) | 1446 | work_data_bits(rebind_work))) |
@@ -1449,6 +1452,34 @@ retry: | |||
1449 | worker->scheduled.next, | 1452 | worker->scheduled.next, |
1450 | work_color_to_flags(WORK_NO_COLOR)); | 1453 | work_color_to_flags(WORK_NO_COLOR)); |
1451 | } | 1454 | } |
1455 | |||
1456 | /* | ||
1457 | * All idle workers are rebound and waiting for %WORKER_REBIND to | ||
1458 | * be cleared inside idle_worker_rebind(). Clear and release. | ||
1459 | * Clearing %WORKER_REBIND from this foreign context is safe | ||
1460 | * because these workers are still guaranteed to be idle. | ||
1461 | * | ||
1462 | * We need to make sure all idle workers passed WORKER_REBIND wait | ||
1463 | * in idle_worker_rebind() before returning; otherwise, workers can | ||
1464 | * get stuck at the wait if hotplug cycle repeats. | ||
1465 | */ | ||
1466 | idle_rebind.cnt = 1; | ||
1467 | INIT_COMPLETION(idle_rebind.done); | ||
1468 | |||
1469 | for_each_worker_pool(pool, gcwq) { | ||
1470 | list_for_each_entry(worker, &pool->idle_list, entry) { | ||
1471 | worker->flags &= ~WORKER_REBIND; | ||
1472 | idle_rebind.cnt++; | ||
1473 | } | ||
1474 | } | ||
1475 | |||
1476 | wake_up_all(&gcwq->rebind_hold); | ||
1477 | |||
1478 | if (--idle_rebind.cnt) { | ||
1479 | spin_unlock_irq(&gcwq->lock); | ||
1480 | wait_for_completion(&idle_rebind.done); | ||
1481 | spin_lock_irq(&gcwq->lock); | ||
1482 | } | ||
1452 | } | 1483 | } |
1453 | 1484 | ||
1454 | static struct worker *alloc_worker(void) | 1485 | static struct worker *alloc_worker(void) |
@@ -1794,9 +1825,45 @@ static bool manage_workers(struct worker *worker) | |||
1794 | struct worker_pool *pool = worker->pool; | 1825 | struct worker_pool *pool = worker->pool; |
1795 | bool ret = false; | 1826 | bool ret = false; |
1796 | 1827 | ||
1797 | if (!mutex_trylock(&pool->manager_mutex)) | 1828 | if (pool->flags & POOL_MANAGING_WORKERS) |
1798 | return ret; | 1829 | return ret; |
1799 | 1830 | ||
1831 | pool->flags |= POOL_MANAGING_WORKERS; | ||
1832 | |||
1833 | /* | ||
1834 | * To simplify both worker management and CPU hotplug, hold off | ||
1835 | * management while hotplug is in progress. CPU hotplug path can't | ||
1836 | * grab %POOL_MANAGING_WORKERS to achieve this because that can | ||
1837 | * lead to idle worker depletion (all become busy thinking someone | ||
1838 | * else is managing) which in turn can result in deadlock under | ||
1839 | * extreme circumstances. Use @pool->manager_mutex to synchronize | ||
1840 | * manager against CPU hotplug. | ||
1841 | * | ||
1842 | * manager_mutex would always be free unless CPU hotplug is in | ||
1843 | * progress. trylock first without dropping @gcwq->lock. | ||
1844 | */ | ||
1845 | if (unlikely(!mutex_trylock(&pool->manager_mutex))) { | ||
1846 | spin_unlock_irq(&pool->gcwq->lock); | ||
1847 | mutex_lock(&pool->manager_mutex); | ||
1848 | /* | ||
1849 | * CPU hotplug could have happened while we were waiting | ||
1850 | * for manager_mutex. Hotplug itself can't handle us | ||
1851 | * because manager isn't either on idle or busy list, and | ||
1852 | * @gcwq's state and ours could have deviated. | ||
1853 | * | ||
1854 | * As hotplug is now excluded via manager_mutex, we can | ||
1855 | * simply try to bind. It will succeed or fail depending | ||
1856 | * on @gcwq's current state. Try it and adjust | ||
1857 | * %WORKER_UNBOUND accordingly. | ||
1858 | */ | ||
1859 | if (worker_maybe_bind_and_lock(worker)) | ||
1860 | worker->flags &= ~WORKER_UNBOUND; | ||
1861 | else | ||
1862 | worker->flags |= WORKER_UNBOUND; | ||
1863 | |||
1864 | ret = true; | ||
1865 | } | ||
1866 | |||
1800 | pool->flags &= ~POOL_MANAGE_WORKERS; | 1867 | pool->flags &= ~POOL_MANAGE_WORKERS; |
1801 | 1868 | ||
1802 | /* | 1869 | /* |
@@ -1806,6 +1873,7 @@ static bool manage_workers(struct worker *worker) | |||
1806 | ret |= maybe_destroy_workers(pool); | 1873 | ret |= maybe_destroy_workers(pool); |
1807 | ret |= maybe_create_worker(pool); | 1874 | ret |= maybe_create_worker(pool); |
1808 | 1875 | ||
1876 | pool->flags &= ~POOL_MANAGING_WORKERS; | ||
1809 | mutex_unlock(&pool->manager_mutex); | 1877 | mutex_unlock(&pool->manager_mutex); |
1810 | return ret; | 1878 | return ret; |
1811 | } | 1879 | } |
diff --git a/lib/digsig.c b/lib/digsig.c index 286d558033e2..8c0e62975c88 100644 --- a/lib/digsig.c +++ b/lib/digsig.c | |||
@@ -163,9 +163,11 @@ static int digsig_verify_rsa(struct key *key, | |||
163 | memcpy(out1 + head, p, l); | 163 | memcpy(out1 + head, p, l); |
164 | 164 | ||
165 | err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len); | 165 | err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len); |
166 | if (err) | ||
167 | goto err; | ||
166 | 168 | ||
167 | if (!err && len == hlen) | 169 | if (len != hlen || memcmp(out2, h, hlen)) |
168 | err = memcmp(out2, h, hlen); | 170 | err = -EINVAL; |
169 | 171 | ||
170 | err: | 172 | err: |
171 | mpi_free(in); | 173 | mpi_free(in); |
diff --git a/mm/memblock.c b/mm/memblock.c index 4d9393c7edc9..82aa349d2f7a 100644 --- a/mm/memblock.c +++ b/mm/memblock.c | |||
@@ -246,7 +246,7 @@ static int __init_memblock memblock_double_array(struct memblock_type *type, | |||
246 | min(new_area_start, memblock.current_limit), | 246 | min(new_area_start, memblock.current_limit), |
247 | new_alloc_size, PAGE_SIZE); | 247 | new_alloc_size, PAGE_SIZE); |
248 | 248 | ||
249 | new_array = addr ? __va(addr) : 0; | 249 | new_array = addr ? __va(addr) : NULL; |
250 | } | 250 | } |
251 | if (!addr) { | 251 | if (!addr) { |
252 | pr_err("memblock: Failed to double %s array from %ld to %ld entries !\n", | 252 | pr_err("memblock: Failed to double %s array from %ld to %ld entries !\n", |
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index bd92431d4c49..4ada3be6e252 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -2562,7 +2562,7 @@ int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol, int no_context) | |||
2562 | break; | 2562 | break; |
2563 | 2563 | ||
2564 | default: | 2564 | default: |
2565 | BUG(); | 2565 | return -EINVAL; |
2566 | } | 2566 | } |
2567 | 2567 | ||
2568 | l = strlen(policy_modes[mode]); | 2568 | l = strlen(policy_modes[mode]); |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 5ad7da217474..3c094e78dde9 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <net/bluetooth/bluetooth.h> | 29 | #include <net/bluetooth/bluetooth.h> |
30 | #include <net/bluetooth/hci_core.h> | 30 | #include <net/bluetooth/hci_core.h> |
31 | #include <net/bluetooth/a2mp.h> | 31 | #include <net/bluetooth/a2mp.h> |
32 | #include <net/bluetooth/smp.h> | ||
32 | 33 | ||
33 | static void hci_le_connect(struct hci_conn *conn) | 34 | static void hci_le_connect(struct hci_conn *conn) |
34 | { | 35 | { |
@@ -619,6 +620,9 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | |||
619 | { | 620 | { |
620 | BT_DBG("hcon %p", conn); | 621 | BT_DBG("hcon %p", conn); |
621 | 622 | ||
623 | if (conn->type == LE_LINK) | ||
624 | return smp_conn_security(conn, sec_level); | ||
625 | |||
622 | /* For sdp we don't need the link key. */ | 626 | /* For sdp we don't need the link key. */ |
623 | if (sec_level == BT_SECURITY_SDP) | 627 | if (sec_level == BT_SECURITY_SDP) |
624 | return 1; | 628 | return 1; |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index daa149b7003c..4ea1710a4783 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -1199,14 +1199,15 @@ clean: | |||
1199 | static void l2cap_conn_ready(struct l2cap_conn *conn) | 1199 | static void l2cap_conn_ready(struct l2cap_conn *conn) |
1200 | { | 1200 | { |
1201 | struct l2cap_chan *chan; | 1201 | struct l2cap_chan *chan; |
1202 | struct hci_conn *hcon = conn->hcon; | ||
1202 | 1203 | ||
1203 | BT_DBG("conn %p", conn); | 1204 | BT_DBG("conn %p", conn); |
1204 | 1205 | ||
1205 | if (!conn->hcon->out && conn->hcon->type == LE_LINK) | 1206 | if (!hcon->out && hcon->type == LE_LINK) |
1206 | l2cap_le_conn_ready(conn); | 1207 | l2cap_le_conn_ready(conn); |
1207 | 1208 | ||
1208 | if (conn->hcon->out && conn->hcon->type == LE_LINK) | 1209 | if (hcon->out && hcon->type == LE_LINK) |
1209 | smp_conn_security(conn, conn->hcon->pending_sec_level); | 1210 | smp_conn_security(hcon, hcon->pending_sec_level); |
1210 | 1211 | ||
1211 | mutex_lock(&conn->chan_lock); | 1212 | mutex_lock(&conn->chan_lock); |
1212 | 1213 | ||
@@ -1219,8 +1220,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) | |||
1219 | continue; | 1220 | continue; |
1220 | } | 1221 | } |
1221 | 1222 | ||
1222 | if (conn->hcon->type == LE_LINK) { | 1223 | if (hcon->type == LE_LINK) { |
1223 | if (smp_conn_security(conn, chan->sec_level)) | 1224 | if (smp_conn_security(hcon, chan->sec_level)) |
1224 | l2cap_chan_ready(chan); | 1225 | l2cap_chan_ready(chan); |
1225 | 1226 | ||
1226 | } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { | 1227 | } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 1497edd191a2..34bbe1c5e389 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -616,7 +616,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
616 | break; | 616 | break; |
617 | } | 617 | } |
618 | 618 | ||
619 | if (smp_conn_security(conn, sec.level)) | 619 | if (smp_conn_security(conn->hcon, sec.level)) |
620 | break; | 620 | break; |
621 | sk->sk_state = BT_CONFIG; | 621 | sk->sk_state = BT_CONFIG; |
622 | chan->state = BT_CONFIG; | 622 | chan->state = BT_CONFIG; |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 901a616c8083..8c225ef349cd 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -267,10 +267,10 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send) | |||
267 | mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type, | 267 | mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type, |
268 | hcon->dst_type, reason); | 268 | hcon->dst_type, reason); |
269 | 269 | ||
270 | if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { | 270 | cancel_delayed_work_sync(&conn->security_timer); |
271 | cancel_delayed_work_sync(&conn->security_timer); | 271 | |
272 | if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) | ||
272 | smp_chan_destroy(conn); | 273 | smp_chan_destroy(conn); |
273 | } | ||
274 | } | 274 | } |
275 | 275 | ||
276 | #define JUST_WORKS 0x00 | 276 | #define JUST_WORKS 0x00 |
@@ -760,9 +760,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
760 | return 0; | 760 | return 0; |
761 | } | 761 | } |
762 | 762 | ||
763 | int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) | 763 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) |
764 | { | 764 | { |
765 | struct hci_conn *hcon = conn->hcon; | 765 | struct l2cap_conn *conn = hcon->l2cap_data; |
766 | struct smp_chan *smp = conn->smp_chan; | 766 | struct smp_chan *smp = conn->smp_chan; |
767 | __u8 authreq; | 767 | __u8 authreq; |
768 | 768 | ||
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index f88ee537fb2b..92de5e5f9db2 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c | |||
@@ -80,7 +80,7 @@ ebt_log_packet(u_int8_t pf, unsigned int hooknum, | |||
80 | unsigned int bitmask; | 80 | unsigned int bitmask; |
81 | 81 | ||
82 | spin_lock_bh(&ebt_log_lock); | 82 | spin_lock_bh(&ebt_log_lock); |
83 | printk("<%c>%s IN=%s OUT=%s MAC source = %pM MAC dest = %pM proto = 0x%04x", | 83 | printk(KERN_SOH "%c%s IN=%s OUT=%s MAC source = %pM MAC dest = %pM proto = 0x%04x", |
84 | '0' + loginfo->u.log.level, prefix, | 84 | '0' + loginfo->u.log.level, prefix, |
85 | in ? in->name : "", out ? out->name : "", | 85 | in ? in->name : "", out ? out->name : "", |
86 | eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, | 86 | eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, |
diff --git a/net/caif/cfsrvl.c b/net/caif/cfsrvl.c index dd485f6128e8..ba217e90765e 100644 --- a/net/caif/cfsrvl.c +++ b/net/caif/cfsrvl.c | |||
@@ -211,9 +211,10 @@ void caif_client_register_refcnt(struct cflayer *adapt_layer, | |||
211 | void (*put)(struct cflayer *lyr)) | 211 | void (*put)(struct cflayer *lyr)) |
212 | { | 212 | { |
213 | struct cfsrvl *service; | 213 | struct cfsrvl *service; |
214 | service = container_of(adapt_layer->dn, struct cfsrvl, layer); | ||
215 | 214 | ||
216 | WARN_ON(adapt_layer == NULL || adapt_layer->dn == NULL); | 215 | if (WARN_ON(adapt_layer == NULL || adapt_layer->dn == NULL)) |
216 | return; | ||
217 | service = container_of(adapt_layer->dn, struct cfsrvl, layer); | ||
217 | service->hold = hold; | 218 | service->hold = hold; |
218 | service->put = put; | 219 | service->put = put; |
219 | } | 220 | } |
diff --git a/net/core/dev.c b/net/core/dev.c index 83988362805e..d7fe32c946c1 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2647,15 +2647,16 @@ void __skb_get_rxhash(struct sk_buff *skb) | |||
2647 | if (!skb_flow_dissect(skb, &keys)) | 2647 | if (!skb_flow_dissect(skb, &keys)) |
2648 | return; | 2648 | return; |
2649 | 2649 | ||
2650 | if (keys.ports) { | 2650 | if (keys.ports) |
2651 | if ((__force u16)keys.port16[1] < (__force u16)keys.port16[0]) | ||
2652 | swap(keys.port16[0], keys.port16[1]); | ||
2653 | skb->l4_rxhash = 1; | 2651 | skb->l4_rxhash = 1; |
2654 | } | ||
2655 | 2652 | ||
2656 | /* get a consistent hash (same value on both flow directions) */ | 2653 | /* get a consistent hash (same value on both flow directions) */ |
2657 | if ((__force u32)keys.dst < (__force u32)keys.src) | 2654 | if (((__force u32)keys.dst < (__force u32)keys.src) || |
2655 | (((__force u32)keys.dst == (__force u32)keys.src) && | ||
2656 | ((__force u16)keys.port16[1] < (__force u16)keys.port16[0]))) { | ||
2658 | swap(keys.dst, keys.src); | 2657 | swap(keys.dst, keys.src); |
2658 | swap(keys.port16[0], keys.port16[1]); | ||
2659 | } | ||
2659 | 2660 | ||
2660 | hash = jhash_3words((__force u32)keys.dst, | 2661 | hash = jhash_3words((__force u32)keys.dst, |
2661 | (__force u32)keys.src, | 2662 | (__force u32)keys.src, |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 346b1eb83a1f..e4ba3e70c174 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -168,24 +168,16 @@ static void poll_napi(struct net_device *dev) | |||
168 | struct napi_struct *napi; | 168 | struct napi_struct *napi; |
169 | int budget = 16; | 169 | int budget = 16; |
170 | 170 | ||
171 | WARN_ON_ONCE(!irqs_disabled()); | ||
172 | |||
173 | list_for_each_entry(napi, &dev->napi_list, dev_list) { | 171 | list_for_each_entry(napi, &dev->napi_list, dev_list) { |
174 | local_irq_enable(); | ||
175 | if (napi->poll_owner != smp_processor_id() && | 172 | if (napi->poll_owner != smp_processor_id() && |
176 | spin_trylock(&napi->poll_lock)) { | 173 | spin_trylock(&napi->poll_lock)) { |
177 | rcu_read_lock_bh(); | ||
178 | budget = poll_one_napi(rcu_dereference_bh(dev->npinfo), | 174 | budget = poll_one_napi(rcu_dereference_bh(dev->npinfo), |
179 | napi, budget); | 175 | napi, budget); |
180 | rcu_read_unlock_bh(); | ||
181 | spin_unlock(&napi->poll_lock); | 176 | spin_unlock(&napi->poll_lock); |
182 | 177 | ||
183 | if (!budget) { | 178 | if (!budget) |
184 | local_irq_disable(); | ||
185 | break; | 179 | break; |
186 | } | ||
187 | } | 180 | } |
188 | local_irq_disable(); | ||
189 | } | 181 | } |
190 | } | 182 | } |
191 | 183 | ||
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index cce9e53528b1..148e73d2c451 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -2721,7 +2721,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
2721 | /* Eth + IPh + UDPh + mpls */ | 2721 | /* Eth + IPh + UDPh + mpls */ |
2722 | datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 - | 2722 | datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 - |
2723 | pkt_dev->pkt_overhead; | 2723 | pkt_dev->pkt_overhead; |
2724 | if (datalen < sizeof(struct pktgen_hdr)) | 2724 | if (datalen < 0 || datalen < sizeof(struct pktgen_hdr)) |
2725 | datalen = sizeof(struct pktgen_hdr); | 2725 | datalen = sizeof(struct pktgen_hdr); |
2726 | 2726 | ||
2727 | udph->source = htons(pkt_dev->cur_udp_src); | 2727 | udph->source = htons(pkt_dev->cur_udp_src); |
diff --git a/net/core/sock.c b/net/core/sock.c index 8f67ced8d6a8..305792076121 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -1523,7 +1523,14 @@ EXPORT_SYMBOL(sock_rfree); | |||
1523 | 1523 | ||
1524 | void sock_edemux(struct sk_buff *skb) | 1524 | void sock_edemux(struct sk_buff *skb) |
1525 | { | 1525 | { |
1526 | sock_put(skb->sk); | 1526 | struct sock *sk = skb->sk; |
1527 | |||
1528 | #ifdef CONFIG_INET | ||
1529 | if (sk->sk_state == TCP_TIME_WAIT) | ||
1530 | inet_twsk_put(inet_twsk(sk)); | ||
1531 | else | ||
1532 | #endif | ||
1533 | sock_put(sk); | ||
1527 | } | 1534 | } |
1528 | EXPORT_SYMBOL(sock_edemux); | 1535 | EXPORT_SYMBOL(sock_edemux); |
1529 | 1536 | ||
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 8eec8f4a0536..ebdf06f938bf 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -124,6 +124,8 @@ static DEFINE_SPINLOCK(mfc_unres_lock); | |||
124 | static struct kmem_cache *mrt_cachep __read_mostly; | 124 | static struct kmem_cache *mrt_cachep __read_mostly; |
125 | 125 | ||
126 | static struct mr_table *ipmr_new_table(struct net *net, u32 id); | 126 | static struct mr_table *ipmr_new_table(struct net *net, u32 id); |
127 | static void ipmr_free_table(struct mr_table *mrt); | ||
128 | |||
127 | static int ip_mr_forward(struct net *net, struct mr_table *mrt, | 129 | static int ip_mr_forward(struct net *net, struct mr_table *mrt, |
128 | struct sk_buff *skb, struct mfc_cache *cache, | 130 | struct sk_buff *skb, struct mfc_cache *cache, |
129 | int local); | 131 | int local); |
@@ -131,6 +133,7 @@ static int ipmr_cache_report(struct mr_table *mrt, | |||
131 | struct sk_buff *pkt, vifi_t vifi, int assert); | 133 | struct sk_buff *pkt, vifi_t vifi, int assert); |
132 | static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, | 134 | static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, |
133 | struct mfc_cache *c, struct rtmsg *rtm); | 135 | struct mfc_cache *c, struct rtmsg *rtm); |
136 | static void mroute_clean_tables(struct mr_table *mrt); | ||
134 | static void ipmr_expire_process(unsigned long arg); | 137 | static void ipmr_expire_process(unsigned long arg); |
135 | 138 | ||
136 | #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES | 139 | #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES |
@@ -271,7 +274,7 @@ static void __net_exit ipmr_rules_exit(struct net *net) | |||
271 | 274 | ||
272 | list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) { | 275 | list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) { |
273 | list_del(&mrt->list); | 276 | list_del(&mrt->list); |
274 | kfree(mrt); | 277 | ipmr_free_table(mrt); |
275 | } | 278 | } |
276 | fib_rules_unregister(net->ipv4.mr_rules_ops); | 279 | fib_rules_unregister(net->ipv4.mr_rules_ops); |
277 | } | 280 | } |
@@ -299,7 +302,7 @@ static int __net_init ipmr_rules_init(struct net *net) | |||
299 | 302 | ||
300 | static void __net_exit ipmr_rules_exit(struct net *net) | 303 | static void __net_exit ipmr_rules_exit(struct net *net) |
301 | { | 304 | { |
302 | kfree(net->ipv4.mrt); | 305 | ipmr_free_table(net->ipv4.mrt); |
303 | } | 306 | } |
304 | #endif | 307 | #endif |
305 | 308 | ||
@@ -336,6 +339,13 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id) | |||
336 | return mrt; | 339 | return mrt; |
337 | } | 340 | } |
338 | 341 | ||
342 | static void ipmr_free_table(struct mr_table *mrt) | ||
343 | { | ||
344 | del_timer_sync(&mrt->ipmr_expire_timer); | ||
345 | mroute_clean_tables(mrt); | ||
346 | kfree(mrt); | ||
347 | } | ||
348 | |||
339 | /* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */ | 349 | /* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */ |
340 | 350 | ||
341 | static void ipmr_del_tunnel(struct net_device *dev, struct vifctl *v) | 351 | static void ipmr_del_tunnel(struct net_device *dev, struct vifctl *v) |
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c index 4ad9cf173992..9c87cde28ff8 100644 --- a/net/ipv4/netfilter/nf_nat_sip.c +++ b/net/ipv4/netfilter/nf_nat_sip.c | |||
@@ -502,7 +502,10 @@ static unsigned int ip_nat_sdp_media(struct sk_buff *skb, unsigned int dataoff, | |||
502 | ret = nf_ct_expect_related(rtcp_exp); | 502 | ret = nf_ct_expect_related(rtcp_exp); |
503 | if (ret == 0) | 503 | if (ret == 0) |
504 | break; | 504 | break; |
505 | else if (ret != -EBUSY) { | 505 | else if (ret == -EBUSY) { |
506 | nf_ct_unexpect_related(rtp_exp); | ||
507 | continue; | ||
508 | } else if (ret < 0) { | ||
506 | nf_ct_unexpect_related(rtp_exp); | 509 | nf_ct_unexpect_related(rtp_exp); |
507 | port = 0; | 510 | port = 0; |
508 | break; | 511 | break; |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index fd9ecb52c66b..82cf2a722b23 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -934,12 +934,14 @@ static u32 __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) | |||
934 | if (mtu < ip_rt_min_pmtu) | 934 | if (mtu < ip_rt_min_pmtu) |
935 | mtu = ip_rt_min_pmtu; | 935 | mtu = ip_rt_min_pmtu; |
936 | 936 | ||
937 | rcu_read_lock(); | ||
937 | if (fib_lookup(dev_net(rt->dst.dev), fl4, &res) == 0) { | 938 | if (fib_lookup(dev_net(rt->dst.dev), fl4, &res) == 0) { |
938 | struct fib_nh *nh = &FIB_RES_NH(res); | 939 | struct fib_nh *nh = &FIB_RES_NH(res); |
939 | 940 | ||
940 | update_or_create_fnhe(nh, fl4->daddr, 0, mtu, | 941 | update_or_create_fnhe(nh, fl4->daddr, 0, mtu, |
941 | jiffies + ip_rt_mtu_expires); | 942 | jiffies + ip_rt_mtu_expires); |
942 | } | 943 | } |
944 | rcu_read_unlock(); | ||
943 | return mtu; | 945 | return mtu; |
944 | } | 946 | } |
945 | 947 | ||
@@ -956,7 +958,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, | |||
956 | dst->obsolete = DST_OBSOLETE_KILL; | 958 | dst->obsolete = DST_OBSOLETE_KILL; |
957 | } else { | 959 | } else { |
958 | rt->rt_pmtu = mtu; | 960 | rt->rt_pmtu = mtu; |
959 | dst_set_expires(&rt->dst, ip_rt_mtu_expires); | 961 | rt->dst.expires = max(1UL, jiffies + ip_rt_mtu_expires); |
960 | } | 962 | } |
961 | } | 963 | } |
962 | 964 | ||
@@ -1263,7 +1265,7 @@ static void ipv4_dst_destroy(struct dst_entry *dst) | |||
1263 | { | 1265 | { |
1264 | struct rtable *rt = (struct rtable *) dst; | 1266 | struct rtable *rt = (struct rtable *) dst; |
1265 | 1267 | ||
1266 | if (dst->flags & DST_NOCACHE) { | 1268 | if (!list_empty(&rt->rt_uncached)) { |
1267 | spin_lock_bh(&rt_uncached_lock); | 1269 | spin_lock_bh(&rt_uncached_lock); |
1268 | list_del(&rt->rt_uncached); | 1270 | list_del(&rt->rt_uncached); |
1269 | spin_unlock_bh(&rt_uncached_lock); | 1271 | spin_unlock_bh(&rt_uncached_lock); |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 85308b90df80..6e38c6c23caa 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -2926,13 +2926,14 @@ static void tcp_enter_recovery(struct sock *sk, bool ece_ack) | |||
2926 | * tcp_xmit_retransmit_queue(). | 2926 | * tcp_xmit_retransmit_queue(). |
2927 | */ | 2927 | */ |
2928 | static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, | 2928 | static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, |
2929 | int newly_acked_sacked, bool is_dupack, | 2929 | int prior_sacked, bool is_dupack, |
2930 | int flag) | 2930 | int flag) |
2931 | { | 2931 | { |
2932 | struct inet_connection_sock *icsk = inet_csk(sk); | 2932 | struct inet_connection_sock *icsk = inet_csk(sk); |
2933 | struct tcp_sock *tp = tcp_sk(sk); | 2933 | struct tcp_sock *tp = tcp_sk(sk); |
2934 | int do_lost = is_dupack || ((flag & FLAG_DATA_SACKED) && | 2934 | int do_lost = is_dupack || ((flag & FLAG_DATA_SACKED) && |
2935 | (tcp_fackets_out(tp) > tp->reordering)); | 2935 | (tcp_fackets_out(tp) > tp->reordering)); |
2936 | int newly_acked_sacked = 0; | ||
2936 | int fast_rexmit = 0; | 2937 | int fast_rexmit = 0; |
2937 | 2938 | ||
2938 | if (WARN_ON(!tp->packets_out && tp->sacked_out)) | 2939 | if (WARN_ON(!tp->packets_out && tp->sacked_out)) |
@@ -2992,6 +2993,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, | |||
2992 | tcp_add_reno_sack(sk); | 2993 | tcp_add_reno_sack(sk); |
2993 | } else | 2994 | } else |
2994 | do_lost = tcp_try_undo_partial(sk, pkts_acked); | 2995 | do_lost = tcp_try_undo_partial(sk, pkts_acked); |
2996 | newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked; | ||
2995 | break; | 2997 | break; |
2996 | case TCP_CA_Loss: | 2998 | case TCP_CA_Loss: |
2997 | if (flag & FLAG_DATA_ACKED) | 2999 | if (flag & FLAG_DATA_ACKED) |
@@ -3013,6 +3015,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, | |||
3013 | if (is_dupack) | 3015 | if (is_dupack) |
3014 | tcp_add_reno_sack(sk); | 3016 | tcp_add_reno_sack(sk); |
3015 | } | 3017 | } |
3018 | newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked; | ||
3016 | 3019 | ||
3017 | if (icsk->icsk_ca_state <= TCP_CA_Disorder) | 3020 | if (icsk->icsk_ca_state <= TCP_CA_Disorder) |
3018 | tcp_try_undo_dsack(sk); | 3021 | tcp_try_undo_dsack(sk); |
@@ -3590,7 +3593,6 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | |||
3590 | int prior_packets; | 3593 | int prior_packets; |
3591 | int prior_sacked = tp->sacked_out; | 3594 | int prior_sacked = tp->sacked_out; |
3592 | int pkts_acked = 0; | 3595 | int pkts_acked = 0; |
3593 | int newly_acked_sacked = 0; | ||
3594 | bool frto_cwnd = false; | 3596 | bool frto_cwnd = false; |
3595 | 3597 | ||
3596 | /* If the ack is older than previous acks | 3598 | /* If the ack is older than previous acks |
@@ -3666,8 +3668,6 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | |||
3666 | flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una); | 3668 | flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una); |
3667 | 3669 | ||
3668 | pkts_acked = prior_packets - tp->packets_out; | 3670 | pkts_acked = prior_packets - tp->packets_out; |
3669 | newly_acked_sacked = (prior_packets - prior_sacked) - | ||
3670 | (tp->packets_out - tp->sacked_out); | ||
3671 | 3671 | ||
3672 | if (tp->frto_counter) | 3672 | if (tp->frto_counter) |
3673 | frto_cwnd = tcp_process_frto(sk, flag); | 3673 | frto_cwnd = tcp_process_frto(sk, flag); |
@@ -3681,7 +3681,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | |||
3681 | tcp_may_raise_cwnd(sk, flag)) | 3681 | tcp_may_raise_cwnd(sk, flag)) |
3682 | tcp_cong_avoid(sk, ack, prior_in_flight); | 3682 | tcp_cong_avoid(sk, ack, prior_in_flight); |
3683 | is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP)); | 3683 | is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP)); |
3684 | tcp_fastretrans_alert(sk, pkts_acked, newly_acked_sacked, | 3684 | tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, |
3685 | is_dupack, flag); | 3685 | is_dupack, flag); |
3686 | } else { | 3686 | } else { |
3687 | if ((flag & FLAG_DATA_ACKED) && !frto_cwnd) | 3687 | if ((flag & FLAG_DATA_ACKED) && !frto_cwnd) |
@@ -3698,7 +3698,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | |||
3698 | no_queue: | 3698 | no_queue: |
3699 | /* If data was DSACKed, see if we can undo a cwnd reduction. */ | 3699 | /* If data was DSACKed, see if we can undo a cwnd reduction. */ |
3700 | if (flag & FLAG_DSACKING_ACK) | 3700 | if (flag & FLAG_DSACKING_ACK) |
3701 | tcp_fastretrans_alert(sk, pkts_acked, newly_acked_sacked, | 3701 | tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, |
3702 | is_dupack, flag); | 3702 | is_dupack, flag); |
3703 | /* If this ack opens up a zero window, clear backoff. It was | 3703 | /* If this ack opens up a zero window, clear backoff. It was |
3704 | * being used to time the probes, and is probably far higher than | 3704 | * being used to time the probes, and is probably far higher than |
@@ -3718,8 +3718,7 @@ old_ack: | |||
3718 | */ | 3718 | */ |
3719 | if (TCP_SKB_CB(skb)->sacked) { | 3719 | if (TCP_SKB_CB(skb)->sacked) { |
3720 | flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una); | 3720 | flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una); |
3721 | newly_acked_sacked = tp->sacked_out - prior_sacked; | 3721 | tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, |
3722 | tcp_fastretrans_alert(sk, pkts_acked, newly_acked_sacked, | ||
3723 | is_dupack, flag); | 3722 | is_dupack, flag); |
3724 | } | 3723 | } |
3725 | 3724 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 6f6d1aca3c3d..2814f66dac64 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1226,6 +1226,11 @@ try_again: | |||
1226 | 1226 | ||
1227 | if (unlikely(err)) { | 1227 | if (unlikely(err)) { |
1228 | trace_kfree_skb(skb, udp_recvmsg); | 1228 | trace_kfree_skb(skb, udp_recvmsg); |
1229 | if (!peeked) { | ||
1230 | atomic_inc(&sk->sk_drops); | ||
1231 | UDP_INC_STATS_USER(sock_net(sk), | ||
1232 | UDP_MIB_INERRORS, is_udplite); | ||
1233 | } | ||
1229 | goto out_free; | 1234 | goto out_free; |
1230 | } | 1235 | } |
1231 | 1236 | ||
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 6dc7fd353ef5..282f3723ee19 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -167,8 +167,6 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
167 | struct esp_data *esp = x->data; | 167 | struct esp_data *esp = x->data; |
168 | 168 | ||
169 | /* skb is pure payload to encrypt */ | 169 | /* skb is pure payload to encrypt */ |
170 | err = -ENOMEM; | ||
171 | |||
172 | aead = esp->aead; | 170 | aead = esp->aead; |
173 | alen = crypto_aead_authsize(aead); | 171 | alen = crypto_aead_authsize(aead); |
174 | 172 | ||
@@ -203,8 +201,10 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
203 | } | 201 | } |
204 | 202 | ||
205 | tmp = esp_alloc_tmp(aead, nfrags + sglists, seqhilen); | 203 | tmp = esp_alloc_tmp(aead, nfrags + sglists, seqhilen); |
206 | if (!tmp) | 204 | if (!tmp) { |
205 | err = -ENOMEM; | ||
207 | goto error; | 206 | goto error; |
207 | } | ||
208 | 208 | ||
209 | seqhi = esp_tmp_seqhi(tmp); | 209 | seqhi = esp_tmp_seqhi(tmp); |
210 | iv = esp_tmp_iv(aead, tmp, seqhilen); | 210 | iv = esp_tmp_iv(aead, tmp, seqhilen); |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index a3e60cc04a8a..acd32e3f1b68 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -403,8 +403,9 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
403 | tp->mtu_info = ntohl(info); | 403 | tp->mtu_info = ntohl(info); |
404 | if (!sock_owned_by_user(sk)) | 404 | if (!sock_owned_by_user(sk)) |
405 | tcp_v6_mtu_reduced(sk); | 405 | tcp_v6_mtu_reduced(sk); |
406 | else | 406 | else if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, |
407 | set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags); | 407 | &tp->tsq_flags)) |
408 | sock_hold(sk); | ||
408 | goto out; | 409 | goto out; |
409 | } | 410 | } |
410 | 411 | ||
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 99d0077b56b8..07e2bfef6845 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -394,6 +394,17 @@ try_again: | |||
394 | } | 394 | } |
395 | if (unlikely(err)) { | 395 | if (unlikely(err)) { |
396 | trace_kfree_skb(skb, udpv6_recvmsg); | 396 | trace_kfree_skb(skb, udpv6_recvmsg); |
397 | if (!peeked) { | ||
398 | atomic_inc(&sk->sk_drops); | ||
399 | if (is_udp4) | ||
400 | UDP_INC_STATS_USER(sock_net(sk), | ||
401 | UDP_MIB_INERRORS, | ||
402 | is_udplite); | ||
403 | else | ||
404 | UDP6_INC_STATS_USER(sock_net(sk), | ||
405 | UDP_MIB_INERRORS, | ||
406 | is_udplite); | ||
407 | } | ||
397 | goto out_free; | 408 | goto out_free; |
398 | } | 409 | } |
399 | if (!peeked) { | 410 | if (!peeked) { |
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 393355d37b47..1a9f3723c13c 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -1347,11 +1347,10 @@ static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel) | |||
1347 | /* Remove from tunnel list */ | 1347 | /* Remove from tunnel list */ |
1348 | spin_lock_bh(&pn->l2tp_tunnel_list_lock); | 1348 | spin_lock_bh(&pn->l2tp_tunnel_list_lock); |
1349 | list_del_rcu(&tunnel->list); | 1349 | list_del_rcu(&tunnel->list); |
1350 | kfree_rcu(tunnel, rcu); | ||
1350 | spin_unlock_bh(&pn->l2tp_tunnel_list_lock); | 1351 | spin_unlock_bh(&pn->l2tp_tunnel_list_lock); |
1351 | synchronize_rcu(); | ||
1352 | 1352 | ||
1353 | atomic_dec(&l2tp_tunnel_count); | 1353 | atomic_dec(&l2tp_tunnel_count); |
1354 | kfree(tunnel); | ||
1355 | } | 1354 | } |
1356 | 1355 | ||
1357 | /* Create a socket for the tunnel, if one isn't set up by | 1356 | /* Create a socket for the tunnel, if one isn't set up by |
@@ -1502,6 +1501,8 @@ out: | |||
1502 | return err; | 1501 | return err; |
1503 | } | 1502 | } |
1504 | 1503 | ||
1504 | static struct lock_class_key l2tp_socket_class; | ||
1505 | |||
1505 | int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, struct l2tp_tunnel **tunnelp) | 1506 | int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, struct l2tp_tunnel **tunnelp) |
1506 | { | 1507 | { |
1507 | struct l2tp_tunnel *tunnel = NULL; | 1508 | struct l2tp_tunnel *tunnel = NULL; |
@@ -1606,6 +1607,8 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 | |||
1606 | tunnel->old_sk_destruct = sk->sk_destruct; | 1607 | tunnel->old_sk_destruct = sk->sk_destruct; |
1607 | sk->sk_destruct = &l2tp_tunnel_destruct; | 1608 | sk->sk_destruct = &l2tp_tunnel_destruct; |
1608 | tunnel->sock = sk; | 1609 | tunnel->sock = sk; |
1610 | lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class, "l2tp_sock"); | ||
1611 | |||
1609 | sk->sk_allocation = GFP_ATOMIC; | 1612 | sk->sk_allocation = GFP_ATOMIC; |
1610 | 1613 | ||
1611 | /* Add tunnel to our list */ | 1614 | /* Add tunnel to our list */ |
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index a38ec6cdeee1..56d583e083a7 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h | |||
@@ -163,6 +163,7 @@ struct l2tp_tunnel_cfg { | |||
163 | 163 | ||
164 | struct l2tp_tunnel { | 164 | struct l2tp_tunnel { |
165 | int magic; /* Should be L2TP_TUNNEL_MAGIC */ | 165 | int magic; /* Should be L2TP_TUNNEL_MAGIC */ |
166 | struct rcu_head rcu; | ||
166 | rwlock_t hlist_lock; /* protect session_hlist */ | 167 | rwlock_t hlist_lock; /* protect session_hlist */ |
167 | struct hlist_head session_hlist[L2TP_HASH_SIZE]; | 168 | struct hlist_head session_hlist[L2TP_HASH_SIZE]; |
168 | /* hashed list of sessions, | 169 | /* hashed list of sessions, |
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index f9ee74deeac2..3bfb34aaee29 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c | |||
@@ -153,7 +153,7 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, | |||
153 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, skb->data, length); | 153 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, skb->data, length); |
154 | } | 154 | } |
155 | 155 | ||
156 | if (!pskb_may_pull(skb, sizeof(ETH_HLEN))) | 156 | if (!pskb_may_pull(skb, ETH_HLEN)) |
157 | goto error; | 157 | goto error; |
158 | 158 | ||
159 | secpath_reset(skb); | 159 | secpath_reset(skb); |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d41974aacf51..a58c0b649ba1 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1378,6 +1378,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, | |||
1378 | else | 1378 | else |
1379 | memset(next_hop, 0, ETH_ALEN); | 1379 | memset(next_hop, 0, ETH_ALEN); |
1380 | 1380 | ||
1381 | memset(pinfo, 0, sizeof(*pinfo)); | ||
1382 | |||
1381 | pinfo->generation = mesh_paths_generation; | 1383 | pinfo->generation = mesh_paths_generation; |
1382 | 1384 | ||
1383 | pinfo->filled = MPATH_INFO_FRAME_QLEN | | 1385 | pinfo->filled = MPATH_INFO_FRAME_QLEN | |
@@ -1396,7 +1398,6 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, | |||
1396 | pinfo->discovery_timeout = | 1398 | pinfo->discovery_timeout = |
1397 | jiffies_to_msecs(mpath->discovery_timeout); | 1399 | jiffies_to_msecs(mpath->discovery_timeout); |
1398 | pinfo->discovery_retries = mpath->discovery_retries; | 1400 | pinfo->discovery_retries = mpath->discovery_retries; |
1399 | pinfo->flags = 0; | ||
1400 | if (mpath->flags & MESH_PATH_ACTIVE) | 1401 | if (mpath->flags & MESH_PATH_ACTIVE) |
1401 | pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE; | 1402 | pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE; |
1402 | if (mpath->flags & MESH_PATH_RESOLVING) | 1403 | if (mpath->flags & MESH_PATH_RESOLVING) |
@@ -1405,10 +1406,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, | |||
1405 | pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID; | 1406 | pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID; |
1406 | if (mpath->flags & MESH_PATH_FIXED) | 1407 | if (mpath->flags & MESH_PATH_FIXED) |
1407 | pinfo->flags |= NL80211_MPATH_FLAG_FIXED; | 1408 | pinfo->flags |= NL80211_MPATH_FLAG_FIXED; |
1408 | if (mpath->flags & MESH_PATH_RESOLVING) | 1409 | if (mpath->flags & MESH_PATH_RESOLVED) |
1409 | pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING; | 1410 | pinfo->flags |= NL80211_MPATH_FLAG_RESOLVED; |
1410 | |||
1411 | pinfo->flags = mpath->flags; | ||
1412 | } | 1411 | } |
1413 | 1412 | ||
1414 | static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev, | 1413 | static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev, |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index a4a5acdbaa4d..f76b83341cf9 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -3248,6 +3248,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
3248 | goto out_unlock; | 3248 | goto out_unlock; |
3249 | 3249 | ||
3250 | err_clear: | 3250 | err_clear: |
3251 | memset(ifmgd->bssid, 0, ETH_ALEN); | ||
3252 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); | ||
3251 | ifmgd->auth_data = NULL; | 3253 | ifmgd->auth_data = NULL; |
3252 | err_free: | 3254 | err_free: |
3253 | kfree(auth_data); | 3255 | kfree(auth_data); |
@@ -3439,6 +3441,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3439 | err = 0; | 3441 | err = 0; |
3440 | goto out; | 3442 | goto out; |
3441 | err_clear: | 3443 | err_clear: |
3444 | memset(ifmgd->bssid, 0, ETH_ALEN); | ||
3445 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); | ||
3442 | ifmgd->assoc_data = NULL; | 3446 | ifmgd->assoc_data = NULL; |
3443 | err_free: | 3447 | err_free: |
3444 | kfree(assoc_data); | 3448 | kfree(assoc_data); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index acf712ffb5e6..c5e8c9c31f76 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1811,37 +1811,31 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1811 | meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, | 1811 | meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, |
1812 | sdata, NULL, NULL); | 1812 | sdata, NULL, NULL); |
1813 | } else { | 1813 | } else { |
1814 | int is_mesh_mcast = 1; | 1814 | /* DS -> MBSS (802.11-2012 13.11.3.3). |
1815 | const u8 *mesh_da; | 1815 | * For unicast with unknown forwarding information, |
1816 | * destination might be in the MBSS or if that fails | ||
1817 | * forwarded to another mesh gate. In either case | ||
1818 | * resolution will be handled in ieee80211_xmit(), so | ||
1819 | * leave the original DA. This also works for mcast */ | ||
1820 | const u8 *mesh_da = skb->data; | ||
1821 | |||
1822 | if (mppath) | ||
1823 | mesh_da = mppath->mpp; | ||
1824 | else if (mpath) | ||
1825 | mesh_da = mpath->dst; | ||
1826 | rcu_read_unlock(); | ||
1816 | 1827 | ||
1817 | if (is_multicast_ether_addr(skb->data)) | ||
1818 | /* DA TA mSA AE:SA */ | ||
1819 | mesh_da = skb->data; | ||
1820 | else { | ||
1821 | static const u8 bcast[ETH_ALEN] = | ||
1822 | { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | ||
1823 | if (mppath) { | ||
1824 | /* RA TA mDA mSA AE:DA SA */ | ||
1825 | mesh_da = mppath->mpp; | ||
1826 | is_mesh_mcast = 0; | ||
1827 | } else if (mpath) { | ||
1828 | mesh_da = mpath->dst; | ||
1829 | is_mesh_mcast = 0; | ||
1830 | } else { | ||
1831 | /* DA TA mSA AE:SA */ | ||
1832 | mesh_da = bcast; | ||
1833 | } | ||
1834 | } | ||
1835 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, | 1828 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, |
1836 | mesh_da, sdata->vif.addr); | 1829 | mesh_da, sdata->vif.addr); |
1837 | rcu_read_unlock(); | 1830 | if (is_multicast_ether_addr(mesh_da)) |
1838 | if (is_mesh_mcast) | 1831 | /* DA TA mSA AE:SA */ |
1839 | meshhdrlen = | 1832 | meshhdrlen = |
1840 | ieee80211_new_mesh_header(&mesh_hdr, | 1833 | ieee80211_new_mesh_header(&mesh_hdr, |
1841 | sdata, | 1834 | sdata, |
1842 | skb->data + ETH_ALEN, | 1835 | skb->data + ETH_ALEN, |
1843 | NULL); | 1836 | NULL); |
1844 | else | 1837 | else |
1838 | /* RA TA mDA mSA AE:DA SA */ | ||
1845 | meshhdrlen = | 1839 | meshhdrlen = |
1846 | ieee80211_new_mesh_header(&mesh_hdr, | 1840 | ieee80211_new_mesh_header(&mesh_hdr, |
1847 | sdata, | 1841 | sdata, |
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 72bf32a84874..f51013c07b9f 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
@@ -1171,8 +1171,10 @@ ip_vs_add_service(struct net *net, struct ip_vs_service_user_kern *u, | |||
1171 | goto out_err; | 1171 | goto out_err; |
1172 | } | 1172 | } |
1173 | svc->stats.cpustats = alloc_percpu(struct ip_vs_cpu_stats); | 1173 | svc->stats.cpustats = alloc_percpu(struct ip_vs_cpu_stats); |
1174 | if (!svc->stats.cpustats) | 1174 | if (!svc->stats.cpustats) { |
1175 | ret = -ENOMEM; | ||
1175 | goto out_err; | 1176 | goto out_err; |
1177 | } | ||
1176 | 1178 | ||
1177 | /* I'm the first user of the service */ | 1179 | /* I'm the first user of the service */ |
1178 | atomic_set(&svc->usecnt, 0); | 1180 | atomic_set(&svc->usecnt, 0); |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index cf4875565d67..2ceec64b19f9 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -249,12 +249,15 @@ static void death_by_event(unsigned long ul_conntrack) | |||
249 | { | 249 | { |
250 | struct nf_conn *ct = (void *)ul_conntrack; | 250 | struct nf_conn *ct = (void *)ul_conntrack; |
251 | struct net *net = nf_ct_net(ct); | 251 | struct net *net = nf_ct_net(ct); |
252 | struct nf_conntrack_ecache *ecache = nf_ct_ecache_find(ct); | ||
253 | |||
254 | BUG_ON(ecache == NULL); | ||
252 | 255 | ||
253 | if (nf_conntrack_event(IPCT_DESTROY, ct) < 0) { | 256 | if (nf_conntrack_event(IPCT_DESTROY, ct) < 0) { |
254 | /* bad luck, let's retry again */ | 257 | /* bad luck, let's retry again */ |
255 | ct->timeout.expires = jiffies + | 258 | ecache->timeout.expires = jiffies + |
256 | (random32() % net->ct.sysctl_events_retry_timeout); | 259 | (random32() % net->ct.sysctl_events_retry_timeout); |
257 | add_timer(&ct->timeout); | 260 | add_timer(&ecache->timeout); |
258 | return; | 261 | return; |
259 | } | 262 | } |
260 | /* we've got the event delivered, now it's dying */ | 263 | /* we've got the event delivered, now it's dying */ |
@@ -268,6 +271,9 @@ static void death_by_event(unsigned long ul_conntrack) | |||
268 | void nf_ct_insert_dying_list(struct nf_conn *ct) | 271 | void nf_ct_insert_dying_list(struct nf_conn *ct) |
269 | { | 272 | { |
270 | struct net *net = nf_ct_net(ct); | 273 | struct net *net = nf_ct_net(ct); |
274 | struct nf_conntrack_ecache *ecache = nf_ct_ecache_find(ct); | ||
275 | |||
276 | BUG_ON(ecache == NULL); | ||
271 | 277 | ||
272 | /* add this conntrack to the dying list */ | 278 | /* add this conntrack to the dying list */ |
273 | spin_lock_bh(&nf_conntrack_lock); | 279 | spin_lock_bh(&nf_conntrack_lock); |
@@ -275,10 +281,10 @@ void nf_ct_insert_dying_list(struct nf_conn *ct) | |||
275 | &net->ct.dying); | 281 | &net->ct.dying); |
276 | spin_unlock_bh(&nf_conntrack_lock); | 282 | spin_unlock_bh(&nf_conntrack_lock); |
277 | /* set a new timer to retry event delivery */ | 283 | /* set a new timer to retry event delivery */ |
278 | setup_timer(&ct->timeout, death_by_event, (unsigned long)ct); | 284 | setup_timer(&ecache->timeout, death_by_event, (unsigned long)ct); |
279 | ct->timeout.expires = jiffies + | 285 | ecache->timeout.expires = jiffies + |
280 | (random32() % net->ct.sysctl_events_retry_timeout); | 286 | (random32() % net->ct.sysctl_events_retry_timeout); |
281 | add_timer(&ct->timeout); | 287 | add_timer(&ecache->timeout); |
282 | } | 288 | } |
283 | EXPORT_SYMBOL_GPL(nf_ct_insert_dying_list); | 289 | EXPORT_SYMBOL_GPL(nf_ct_insert_dying_list); |
284 | 290 | ||
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index da4fc37a8578..9807f3278fcb 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -2790,7 +2790,8 @@ static int __init ctnetlink_init(void) | |||
2790 | goto err_unreg_subsys; | 2790 | goto err_unreg_subsys; |
2791 | } | 2791 | } |
2792 | 2792 | ||
2793 | if (register_pernet_subsys(&ctnetlink_net_ops)) { | 2793 | ret = register_pernet_subsys(&ctnetlink_net_ops); |
2794 | if (ret < 0) { | ||
2794 | pr_err("ctnetlink_init: cannot register pernet operations\n"); | 2795 | pr_err("ctnetlink_init: cannot register pernet operations\n"); |
2795 | goto err_unreg_exp_subsys; | 2796 | goto err_unreg_exp_subsys; |
2796 | } | 2797 | } |
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index a5ac11ebef33..e046b3756aab 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c | |||
@@ -158,21 +158,18 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = { | |||
158 | * sCL -> sSS | 158 | * sCL -> sSS |
159 | */ | 159 | */ |
160 | /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2 */ | 160 | /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2 */ |
161 | /*synack*/ { sIV, sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIG, sSR }, | 161 | /*synack*/ { sIV, sIV, sSR, sIV, sIV, sIV, sIV, sIV, sIV, sSR }, |
162 | /* | 162 | /* |
163 | * sNO -> sIV Too late and no reason to do anything | 163 | * sNO -> sIV Too late and no reason to do anything |
164 | * sSS -> sIV Client can't send SYN and then SYN/ACK | 164 | * sSS -> sIV Client can't send SYN and then SYN/ACK |
165 | * sS2 -> sSR SYN/ACK sent to SYN2 in simultaneous open | 165 | * sS2 -> sSR SYN/ACK sent to SYN2 in simultaneous open |
166 | * sSR -> sIG | 166 | * sSR -> sSR Late retransmitted SYN/ACK in simultaneous open |
167 | * sES -> sIG Error: SYNs in window outside the SYN_SENT state | 167 | * sES -> sIV Invalid SYN/ACK packets sent by the client |
168 | * are errors. Receiver will reply with RST | 168 | * sFW -> sIV |
169 | * and close the connection. | 169 | * sCW -> sIV |
170 | * Or we are not in sync and hold a dead connection. | 170 | * sLA -> sIV |
171 | * sFW -> sIG | 171 | * sTW -> sIV |
172 | * sCW -> sIG | 172 | * sCL -> sIV |
173 | * sLA -> sIG | ||
174 | * sTW -> sIG | ||
175 | * sCL -> sIG | ||
176 | */ | 173 | */ |
177 | /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2 */ | 174 | /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2 */ |
178 | /*fin*/ { sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV }, | 175 | /*fin*/ { sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV }, |
@@ -633,15 +630,9 @@ static bool tcp_in_window(const struct nf_conn *ct, | |||
633 | ack = sack = receiver->td_end; | 630 | ack = sack = receiver->td_end; |
634 | } | 631 | } |
635 | 632 | ||
636 | if (seq == end | 633 | if (tcph->rst && seq == 0 && state->state == TCP_CONNTRACK_SYN_SENT) |
637 | && (!tcph->rst | ||
638 | || (seq == 0 && state->state == TCP_CONNTRACK_SYN_SENT))) | ||
639 | /* | 634 | /* |
640 | * Packets contains no data: we assume it is valid | 635 | * RST sent answering SYN. |
641 | * and check the ack value only. | ||
642 | * However RST segments are always validated by their | ||
643 | * SEQ number, except when seq == 0 (reset sent answering | ||
644 | * SYN. | ||
645 | */ | 636 | */ |
646 | seq = end = sender->td_end; | 637 | seq = end = sender->td_end; |
647 | 638 | ||
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 169ab59ed9d4..5cfb5bedb2b8 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -381,6 +381,7 @@ __build_packet_message(struct nfulnl_instance *inst, | |||
381 | struct nlmsghdr *nlh; | 381 | struct nlmsghdr *nlh; |
382 | struct nfgenmsg *nfmsg; | 382 | struct nfgenmsg *nfmsg; |
383 | sk_buff_data_t old_tail = inst->skb->tail; | 383 | sk_buff_data_t old_tail = inst->skb->tail; |
384 | struct sock *sk; | ||
384 | 385 | ||
385 | nlh = nlmsg_put(inst->skb, 0, 0, | 386 | nlh = nlmsg_put(inst->skb, 0, 0, |
386 | NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET, | 387 | NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET, |
@@ -480,7 +481,7 @@ __build_packet_message(struct nfulnl_instance *inst, | |||
480 | } | 481 | } |
481 | 482 | ||
482 | if (indev && skb_mac_header_was_set(skb)) { | 483 | if (indev && skb_mac_header_was_set(skb)) { |
483 | if (nla_put_be32(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)) || | 484 | if (nla_put_be16(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)) || |
484 | nla_put_be16(inst->skb, NFULA_HWLEN, | 485 | nla_put_be16(inst->skb, NFULA_HWLEN, |
485 | htons(skb->dev->hard_header_len)) || | 486 | htons(skb->dev->hard_header_len)) || |
486 | nla_put(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len, | 487 | nla_put(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len, |
@@ -499,18 +500,19 @@ __build_packet_message(struct nfulnl_instance *inst, | |||
499 | } | 500 | } |
500 | 501 | ||
501 | /* UID */ | 502 | /* UID */ |
502 | if (skb->sk) { | 503 | sk = skb->sk; |
503 | read_lock_bh(&skb->sk->sk_callback_lock); | 504 | if (sk && sk->sk_state != TCP_TIME_WAIT) { |
504 | if (skb->sk->sk_socket && skb->sk->sk_socket->file) { | 505 | read_lock_bh(&sk->sk_callback_lock); |
505 | struct file *file = skb->sk->sk_socket->file; | 506 | if (sk->sk_socket && sk->sk_socket->file) { |
507 | struct file *file = sk->sk_socket->file; | ||
506 | __be32 uid = htonl(file->f_cred->fsuid); | 508 | __be32 uid = htonl(file->f_cred->fsuid); |
507 | __be32 gid = htonl(file->f_cred->fsgid); | 509 | __be32 gid = htonl(file->f_cred->fsgid); |
508 | read_unlock_bh(&skb->sk->sk_callback_lock); | 510 | read_unlock_bh(&sk->sk_callback_lock); |
509 | if (nla_put_be32(inst->skb, NFULA_UID, uid) || | 511 | if (nla_put_be32(inst->skb, NFULA_UID, uid) || |
510 | nla_put_be32(inst->skb, NFULA_GID, gid)) | 512 | nla_put_be32(inst->skb, NFULA_GID, gid)) |
511 | goto nla_put_failure; | 513 | goto nla_put_failure; |
512 | } else | 514 | } else |
513 | read_unlock_bh(&skb->sk->sk_callback_lock); | 515 | read_unlock_bh(&sk->sk_callback_lock); |
514 | } | 516 | } |
515 | 517 | ||
516 | /* local sequence number */ | 518 | /* local sequence number */ |
@@ -996,8 +998,10 @@ static int __init nfnetlink_log_init(void) | |||
996 | 998 | ||
997 | #ifdef CONFIG_PROC_FS | 999 | #ifdef CONFIG_PROC_FS |
998 | if (!proc_create("nfnetlink_log", 0440, | 1000 | if (!proc_create("nfnetlink_log", 0440, |
999 | proc_net_netfilter, &nful_file_ops)) | 1001 | proc_net_netfilter, &nful_file_ops)) { |
1002 | status = -ENOMEM; | ||
1000 | goto cleanup_logger; | 1003 | goto cleanup_logger; |
1004 | } | ||
1001 | #endif | 1005 | #endif |
1002 | return status; | 1006 | return status; |
1003 | 1007 | ||
diff --git a/net/netfilter/xt_LOG.c b/net/netfilter/xt_LOG.c index ff5f75fddb15..91e9af4d1f42 100644 --- a/net/netfilter/xt_LOG.c +++ b/net/netfilter/xt_LOG.c | |||
@@ -145,6 +145,19 @@ static int dump_tcp_header(struct sbuff *m, const struct sk_buff *skb, | |||
145 | return 0; | 145 | return 0; |
146 | } | 146 | } |
147 | 147 | ||
148 | static void dump_sk_uid_gid(struct sbuff *m, struct sock *sk) | ||
149 | { | ||
150 | if (!sk || sk->sk_state == TCP_TIME_WAIT) | ||
151 | return; | ||
152 | |||
153 | read_lock_bh(&sk->sk_callback_lock); | ||
154 | if (sk->sk_socket && sk->sk_socket->file) | ||
155 | sb_add(m, "UID=%u GID=%u ", | ||
156 | sk->sk_socket->file->f_cred->fsuid, | ||
157 | sk->sk_socket->file->f_cred->fsgid); | ||
158 | read_unlock_bh(&sk->sk_callback_lock); | ||
159 | } | ||
160 | |||
148 | /* One level of recursion won't kill us */ | 161 | /* One level of recursion won't kill us */ |
149 | static void dump_ipv4_packet(struct sbuff *m, | 162 | static void dump_ipv4_packet(struct sbuff *m, |
150 | const struct nf_loginfo *info, | 163 | const struct nf_loginfo *info, |
@@ -361,14 +374,8 @@ static void dump_ipv4_packet(struct sbuff *m, | |||
361 | } | 374 | } |
362 | 375 | ||
363 | /* Max length: 15 "UID=4294967295 " */ | 376 | /* Max length: 15 "UID=4294967295 " */ |
364 | if ((logflags & XT_LOG_UID) && !iphoff && skb->sk) { | 377 | if ((logflags & XT_LOG_UID) && !iphoff) |
365 | read_lock_bh(&skb->sk->sk_callback_lock); | 378 | dump_sk_uid_gid(m, skb->sk); |
366 | if (skb->sk->sk_socket && skb->sk->sk_socket->file) | ||
367 | sb_add(m, "UID=%u GID=%u ", | ||
368 | skb->sk->sk_socket->file->f_cred->fsuid, | ||
369 | skb->sk->sk_socket->file->f_cred->fsgid); | ||
370 | read_unlock_bh(&skb->sk->sk_callback_lock); | ||
371 | } | ||
372 | 379 | ||
373 | /* Max length: 16 "MARK=0xFFFFFFFF " */ | 380 | /* Max length: 16 "MARK=0xFFFFFFFF " */ |
374 | if (!iphoff && skb->mark) | 381 | if (!iphoff && skb->mark) |
@@ -436,8 +443,8 @@ log_packet_common(struct sbuff *m, | |||
436 | const struct nf_loginfo *loginfo, | 443 | const struct nf_loginfo *loginfo, |
437 | const char *prefix) | 444 | const char *prefix) |
438 | { | 445 | { |
439 | sb_add(m, "<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, | 446 | sb_add(m, KERN_SOH "%c%sIN=%s OUT=%s ", |
440 | prefix, | 447 | '0' + loginfo->u.log.level, prefix, |
441 | in ? in->name : "", | 448 | in ? in->name : "", |
442 | out ? out->name : ""); | 449 | out ? out->name : ""); |
443 | #ifdef CONFIG_BRIDGE_NETFILTER | 450 | #ifdef CONFIG_BRIDGE_NETFILTER |
@@ -717,14 +724,8 @@ static void dump_ipv6_packet(struct sbuff *m, | |||
717 | } | 724 | } |
718 | 725 | ||
719 | /* Max length: 15 "UID=4294967295 " */ | 726 | /* Max length: 15 "UID=4294967295 " */ |
720 | if ((logflags & XT_LOG_UID) && recurse && skb->sk) { | 727 | if ((logflags & XT_LOG_UID) && recurse) |
721 | read_lock_bh(&skb->sk->sk_callback_lock); | 728 | dump_sk_uid_gid(m, skb->sk); |
722 | if (skb->sk->sk_socket && skb->sk->sk_socket->file) | ||
723 | sb_add(m, "UID=%u GID=%u ", | ||
724 | skb->sk->sk_socket->file->f_cred->fsuid, | ||
725 | skb->sk->sk_socket->file->f_cred->fsgid); | ||
726 | read_unlock_bh(&skb->sk->sk_callback_lock); | ||
727 | } | ||
728 | 729 | ||
729 | /* Max length: 16 "MARK=0xFFFFFFFF " */ | 730 | /* Max length: 16 "MARK=0xFFFFFFFF " */ |
730 | if (!recurse && skb->mark) | 731 | if (!recurse && skb->mark) |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 1445d73533ed..527023823b5c 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1373,7 +1373,8 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1373 | dst_pid = addr->nl_pid; | 1373 | dst_pid = addr->nl_pid; |
1374 | dst_group = ffs(addr->nl_groups); | 1374 | dst_group = ffs(addr->nl_groups); |
1375 | err = -EPERM; | 1375 | err = -EPERM; |
1376 | if (dst_group && !netlink_capable(sock, NL_NONROOT_SEND)) | 1376 | if ((dst_group || dst_pid) && |
1377 | !netlink_capable(sock, NL_NONROOT_SEND)) | ||
1377 | goto out; | 1378 | goto out; |
1378 | } else { | 1379 | } else { |
1379 | dst_pid = nlk->dst_pid; | 1380 | dst_pid = nlk->dst_pid; |
@@ -2147,6 +2148,7 @@ static void __init netlink_add_usersock_entry(void) | |||
2147 | rcu_assign_pointer(nl_table[NETLINK_USERSOCK].listeners, listeners); | 2148 | rcu_assign_pointer(nl_table[NETLINK_USERSOCK].listeners, listeners); |
2148 | nl_table[NETLINK_USERSOCK].module = THIS_MODULE; | 2149 | nl_table[NETLINK_USERSOCK].module = THIS_MODULE; |
2149 | nl_table[NETLINK_USERSOCK].registered = 1; | 2150 | nl_table[NETLINK_USERSOCK].registered = 1; |
2151 | nl_table[NETLINK_USERSOCK].nl_nonroot = NL_NONROOT_SEND; | ||
2150 | 2152 | ||
2151 | netlink_table_ungrab(); | 2153 | netlink_table_ungrab(); |
2152 | } | 2154 | } |
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 06592d8b4a2b..1b9024ee963c 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
@@ -1169,7 +1169,12 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1169 | msg->msg_flags |= MSG_TRUNC; | 1169 | msg->msg_flags |= MSG_TRUNC; |
1170 | } | 1170 | } |
1171 | 1171 | ||
1172 | skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); | 1172 | er = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); |
1173 | if (er < 0) { | ||
1174 | skb_free_datagram(sk, skb); | ||
1175 | release_sock(sk); | ||
1176 | return er; | ||
1177 | } | ||
1173 | 1178 | ||
1174 | if (sax != NULL) { | 1179 | if (sax != NULL) { |
1175 | sax->sax25_family = AF_NETROM; | 1180 | sax->sax25_family = AF_NETROM; |
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index f3f96badf5aa..954405ceae9e 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
@@ -45,7 +45,7 @@ static int make_writable(struct sk_buff *skb, int write_len) | |||
45 | return pskb_expand_head(skb, 0, 0, GFP_ATOMIC); | 45 | return pskb_expand_head(skb, 0, 0, GFP_ATOMIC); |
46 | } | 46 | } |
47 | 47 | ||
48 | /* remove VLAN header from packet and update csum accrodingly. */ | 48 | /* remove VLAN header from packet and update csum accordingly. */ |
49 | static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci) | 49 | static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci) |
50 | { | 50 | { |
51 | struct vlan_hdr *vhdr; | 51 | struct vlan_hdr *vhdr; |
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index d8277d29e710..cf58cedad083 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -425,10 +425,10 @@ static int validate_sample(const struct nlattr *attr, | |||
425 | static int validate_tp_port(const struct sw_flow_key *flow_key) | 425 | static int validate_tp_port(const struct sw_flow_key *flow_key) |
426 | { | 426 | { |
427 | if (flow_key->eth.type == htons(ETH_P_IP)) { | 427 | if (flow_key->eth.type == htons(ETH_P_IP)) { |
428 | if (flow_key->ipv4.tp.src && flow_key->ipv4.tp.dst) | 428 | if (flow_key->ipv4.tp.src || flow_key->ipv4.tp.dst) |
429 | return 0; | 429 | return 0; |
430 | } else if (flow_key->eth.type == htons(ETH_P_IPV6)) { | 430 | } else if (flow_key->eth.type == htons(ETH_P_IPV6)) { |
431 | if (flow_key->ipv6.tp.src && flow_key->ipv6.tp.dst) | 431 | if (flow_key->ipv6.tp.src || flow_key->ipv6.tp.dst) |
432 | return 0; | 432 | return 0; |
433 | } | 433 | } |
434 | 434 | ||
@@ -460,7 +460,7 @@ static int validate_set(const struct nlattr *a, | |||
460 | if (flow_key->eth.type != htons(ETH_P_IP)) | 460 | if (flow_key->eth.type != htons(ETH_P_IP)) |
461 | return -EINVAL; | 461 | return -EINVAL; |
462 | 462 | ||
463 | if (!flow_key->ipv4.addr.src || !flow_key->ipv4.addr.dst) | 463 | if (!flow_key->ip.proto) |
464 | return -EINVAL; | 464 | return -EINVAL; |
465 | 465 | ||
466 | ipv4_key = nla_data(ovs_key); | 466 | ipv4_key = nla_data(ovs_key); |
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h index 9b75617ca4e0..c30df1a10c67 100644 --- a/net/openvswitch/flow.h +++ b/net/openvswitch/flow.h | |||
@@ -145,15 +145,17 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies); | |||
145 | * OVS_KEY_ATTR_PRIORITY 4 -- 4 8 | 145 | * OVS_KEY_ATTR_PRIORITY 4 -- 4 8 |
146 | * OVS_KEY_ATTR_IN_PORT 4 -- 4 8 | 146 | * OVS_KEY_ATTR_IN_PORT 4 -- 4 8 |
147 | * OVS_KEY_ATTR_ETHERNET 12 -- 4 16 | 147 | * OVS_KEY_ATTR_ETHERNET 12 -- 4 16 |
148 | * OVS_KEY_ATTR_ETHERTYPE 2 2 4 8 (outer VLAN ethertype) | ||
148 | * OVS_KEY_ATTR_8021Q 4 -- 4 8 | 149 | * OVS_KEY_ATTR_8021Q 4 -- 4 8 |
149 | * OVS_KEY_ATTR_ETHERTYPE 2 2 4 8 | 150 | * OVS_KEY_ATTR_ENCAP 0 -- 4 4 (VLAN encapsulation) |
151 | * OVS_KEY_ATTR_ETHERTYPE 2 2 4 8 (inner VLAN ethertype) | ||
150 | * OVS_KEY_ATTR_IPV6 40 -- 4 44 | 152 | * OVS_KEY_ATTR_IPV6 40 -- 4 44 |
151 | * OVS_KEY_ATTR_ICMPV6 2 2 4 8 | 153 | * OVS_KEY_ATTR_ICMPV6 2 2 4 8 |
152 | * OVS_KEY_ATTR_ND 28 -- 4 32 | 154 | * OVS_KEY_ATTR_ND 28 -- 4 32 |
153 | * ------------------------------------------------- | 155 | * ------------------------------------------------- |
154 | * total 132 | 156 | * total 144 |
155 | */ | 157 | */ |
156 | #define FLOW_BUFSIZE 132 | 158 | #define FLOW_BUFSIZE 144 |
157 | 159 | ||
158 | int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *); | 160 | int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *); |
159 | int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, | 161 | int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index aee7196aac36..c5c9e2a54218 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1273,7 +1273,7 @@ static void __fanout_unlink(struct sock *sk, struct packet_sock *po) | |||
1273 | spin_unlock(&f->lock); | 1273 | spin_unlock(&f->lock); |
1274 | } | 1274 | } |
1275 | 1275 | ||
1276 | bool match_fanout_group(struct packet_type *ptype, struct sock * sk) | 1276 | static bool match_fanout_group(struct packet_type *ptype, struct sock * sk) |
1277 | { | 1277 | { |
1278 | if (ptype->af_packet_priv == (void*)((struct packet_sock *)sk)->fanout) | 1278 | if (ptype->af_packet_priv == (void*)((struct packet_sock *)sk)->fanout) |
1279 | return true; | 1279 | return true; |
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 6aabd77d1cfd..564b9fc8efd3 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c | |||
@@ -250,10 +250,11 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) | |||
250 | else if ((cl = defmap[res.classid & TC_PRIO_MAX]) == NULL) | 250 | else if ((cl = defmap[res.classid & TC_PRIO_MAX]) == NULL) |
251 | cl = defmap[TC_PRIO_BESTEFFORT]; | 251 | cl = defmap[TC_PRIO_BESTEFFORT]; |
252 | 252 | ||
253 | if (cl == NULL || cl->level >= head->level) | 253 | if (cl == NULL) |
254 | goto fallback; | 254 | goto fallback; |
255 | } | 255 | } |
256 | 256 | if (cl->level >= head->level) | |
257 | goto fallback; | ||
257 | #ifdef CONFIG_NET_CLS_ACT | 258 | #ifdef CONFIG_NET_CLS_ACT |
258 | switch (result) { | 259 | switch (result) { |
259 | case TC_ACT_QUEUED: | 260 | case TC_ACT_QUEUED: |
diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index 9fc1c62ec80e..4e606fcb2534 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c | |||
@@ -191,7 +191,6 @@ static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
191 | 191 | ||
192 | if (list_empty(&flow->flowchain)) { | 192 | if (list_empty(&flow->flowchain)) { |
193 | list_add_tail(&flow->flowchain, &q->new_flows); | 193 | list_add_tail(&flow->flowchain, &q->new_flows); |
194 | codel_vars_init(&flow->cvars); | ||
195 | q->new_flow_count++; | 194 | q->new_flow_count++; |
196 | flow->deficit = q->quantum; | 195 | flow->deficit = q->quantum; |
197 | flow->dropped = 0; | 196 | flow->dropped = 0; |
@@ -418,6 +417,7 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt) | |||
418 | struct fq_codel_flow *flow = q->flows + i; | 417 | struct fq_codel_flow *flow = q->flows + i; |
419 | 418 | ||
420 | INIT_LIST_HEAD(&flow->flowchain); | 419 | INIT_LIST_HEAD(&flow->flowchain); |
420 | codel_vars_init(&flow->cvars); | ||
421 | } | 421 | } |
422 | } | 422 | } |
423 | if (sch->limit >= 1) | 423 | if (sch->limit >= 1) |
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index e901583e4ea5..d42234c0f13b 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c | |||
@@ -102,9 +102,8 @@ static inline int gred_wred_mode_check(struct Qdisc *sch) | |||
102 | if (q == NULL) | 102 | if (q == NULL) |
103 | continue; | 103 | continue; |
104 | 104 | ||
105 | for (n = 0; n < table->DPs; n++) | 105 | for (n = i + 1; n < table->DPs; n++) |
106 | if (table->tab[n] && table->tab[n] != q && | 106 | if (table->tab[n] && table->tab[n]->prio == q->prio) |
107 | table->tab[n]->prio == q->prio) | ||
108 | return 1; | 107 | return 1; |
109 | } | 108 | } |
110 | 109 | ||
@@ -137,6 +136,7 @@ static inline void gred_store_wred_set(struct gred_sched *table, | |||
137 | struct gred_sched_data *q) | 136 | struct gred_sched_data *q) |
138 | { | 137 | { |
139 | table->wred_set.qavg = q->vars.qavg; | 138 | table->wred_set.qavg = q->vars.qavg; |
139 | table->wred_set.qidlestart = q->vars.qidlestart; | ||
140 | } | 140 | } |
141 | 141 | ||
142 | static inline int gred_use_ecn(struct gred_sched *t) | 142 | static inline int gred_use_ecn(struct gred_sched *t) |
@@ -176,7 +176,7 @@ static int gred_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
176 | skb->tc_index = (skb->tc_index & ~GRED_VQ_MASK) | dp; | 176 | skb->tc_index = (skb->tc_index & ~GRED_VQ_MASK) | dp; |
177 | } | 177 | } |
178 | 178 | ||
179 | /* sum up all the qaves of prios <= to ours to get the new qave */ | 179 | /* sum up all the qaves of prios < ours to get the new qave */ |
180 | if (!gred_wred_mode(t) && gred_rio_mode(t)) { | 180 | if (!gred_wred_mode(t) && gred_rio_mode(t)) { |
181 | int i; | 181 | int i; |
182 | 182 | ||
@@ -260,16 +260,18 @@ static struct sk_buff *gred_dequeue(struct Qdisc *sch) | |||
260 | } else { | 260 | } else { |
261 | q->backlog -= qdisc_pkt_len(skb); | 261 | q->backlog -= qdisc_pkt_len(skb); |
262 | 262 | ||
263 | if (!q->backlog && !gred_wred_mode(t)) | 263 | if (gred_wred_mode(t)) { |
264 | red_start_of_idle_period(&q->vars); | 264 | if (!sch->qstats.backlog) |
265 | red_start_of_idle_period(&t->wred_set); | ||
266 | } else { | ||
267 | if (!q->backlog) | ||
268 | red_start_of_idle_period(&q->vars); | ||
269 | } | ||
265 | } | 270 | } |
266 | 271 | ||
267 | return skb; | 272 | return skb; |
268 | } | 273 | } |
269 | 274 | ||
270 | if (gred_wred_mode(t) && !red_is_idling(&t->wred_set)) | ||
271 | red_start_of_idle_period(&t->wred_set); | ||
272 | |||
273 | return NULL; | 275 | return NULL; |
274 | } | 276 | } |
275 | 277 | ||
@@ -291,19 +293,20 @@ static unsigned int gred_drop(struct Qdisc *sch) | |||
291 | q->backlog -= len; | 293 | q->backlog -= len; |
292 | q->stats.other++; | 294 | q->stats.other++; |
293 | 295 | ||
294 | if (!q->backlog && !gred_wred_mode(t)) | 296 | if (gred_wred_mode(t)) { |
295 | red_start_of_idle_period(&q->vars); | 297 | if (!sch->qstats.backlog) |
298 | red_start_of_idle_period(&t->wred_set); | ||
299 | } else { | ||
300 | if (!q->backlog) | ||
301 | red_start_of_idle_period(&q->vars); | ||
302 | } | ||
296 | } | 303 | } |
297 | 304 | ||
298 | qdisc_drop(skb, sch); | 305 | qdisc_drop(skb, sch); |
299 | return len; | 306 | return len; |
300 | } | 307 | } |
301 | 308 | ||
302 | if (gred_wred_mode(t) && !red_is_idling(&t->wred_set)) | ||
303 | red_start_of_idle_period(&t->wred_set); | ||
304 | |||
305 | return 0; | 309 | return 0; |
306 | |||
307 | } | 310 | } |
308 | 311 | ||
309 | static void gred_reset(struct Qdisc *sch) | 312 | static void gred_reset(struct Qdisc *sch) |
@@ -535,6 +538,7 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
535 | for (i = 0; i < MAX_DPs; i++) { | 538 | for (i = 0; i < MAX_DPs; i++) { |
536 | struct gred_sched_data *q = table->tab[i]; | 539 | struct gred_sched_data *q = table->tab[i]; |
537 | struct tc_gred_qopt opt; | 540 | struct tc_gred_qopt opt; |
541 | unsigned long qavg; | ||
538 | 542 | ||
539 | memset(&opt, 0, sizeof(opt)); | 543 | memset(&opt, 0, sizeof(opt)); |
540 | 544 | ||
@@ -566,7 +570,9 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
566 | if (gred_wred_mode(table)) | 570 | if (gred_wred_mode(table)) |
567 | gred_load_wred_set(table, q); | 571 | gred_load_wred_set(table, q); |
568 | 572 | ||
569 | opt.qave = red_calc_qavg(&q->parms, &q->vars, q->vars.qavg); | 573 | qavg = red_calc_qavg(&q->parms, &q->vars, |
574 | q->vars.qavg >> q->parms.Wlog); | ||
575 | opt.qave = qavg >> q->parms.Wlog; | ||
570 | 576 | ||
571 | append_opt: | 577 | append_opt: |
572 | if (nla_append(skb, sizeof(opt), &opt) < 0) | 578 | if (nla_append(skb, sizeof(opt), &opt) < 0) |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 838e18b4d7ea..be50aa234dcd 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -364,6 +364,25 @@ finish: | |||
364 | return retval; | 364 | return retval; |
365 | } | 365 | } |
366 | 366 | ||
367 | static void sctp_packet_release_owner(struct sk_buff *skb) | ||
368 | { | ||
369 | sk_free(skb->sk); | ||
370 | } | ||
371 | |||
372 | static void sctp_packet_set_owner_w(struct sk_buff *skb, struct sock *sk) | ||
373 | { | ||
374 | skb_orphan(skb); | ||
375 | skb->sk = sk; | ||
376 | skb->destructor = sctp_packet_release_owner; | ||
377 | |||
378 | /* | ||
379 | * The data chunks have already been accounted for in sctp_sendmsg(), | ||
380 | * therefore only reserve a single byte to keep socket around until | ||
381 | * the packet has been transmitted. | ||
382 | */ | ||
383 | atomic_inc(&sk->sk_wmem_alloc); | ||
384 | } | ||
385 | |||
367 | /* All packets are sent to the network through this function from | 386 | /* All packets are sent to the network through this function from |
368 | * sctp_outq_tail(). | 387 | * sctp_outq_tail(). |
369 | * | 388 | * |
@@ -405,7 +424,7 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
405 | /* Set the owning socket so that we know where to get the | 424 | /* Set the owning socket so that we know where to get the |
406 | * destination IP address. | 425 | * destination IP address. |
407 | */ | 426 | */ |
408 | skb_set_owner_w(nskb, sk); | 427 | sctp_packet_set_owner_w(nskb, sk); |
409 | 428 | ||
410 | if (!sctp_transport_dst_check(tp)) { | 429 | if (!sctp_transport_dst_check(tp)) { |
411 | sctp_transport_route(tp, NULL, sctp_sk(sk)); | 430 | sctp_transport_route(tp, NULL, sctp_sk(sk)); |
diff --git a/net/socket.c b/net/socket.c index a5471f804d99..edc3c4af9085 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -2604,7 +2604,7 @@ static int do_siocgstamp(struct net *net, struct socket *sock, | |||
2604 | err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv); | 2604 | err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv); |
2605 | set_fs(old_fs); | 2605 | set_fs(old_fs); |
2606 | if (!err) | 2606 | if (!err) |
2607 | err = compat_put_timeval(up, &ktv); | 2607 | err = compat_put_timeval(&ktv, up); |
2608 | 2608 | ||
2609 | return err; | 2609 | return err; |
2610 | } | 2610 | } |
@@ -2620,7 +2620,7 @@ static int do_siocgstampns(struct net *net, struct socket *sock, | |||
2620 | err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts); | 2620 | err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts); |
2621 | set_fs(old_fs); | 2621 | set_fs(old_fs); |
2622 | if (!err) | 2622 | if (!err) |
2623 | err = compat_put_timespec(up, &kts); | 2623 | err = compat_put_timespec(&kts, up); |
2624 | 2624 | ||
2625 | return err; | 2625 | return err; |
2626 | } | 2626 | } |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index a5a402a7d21f..5d7f61d7559c 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -969,11 +969,11 @@ static bool xprt_dynamic_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req) | |||
969 | return false; | 969 | return false; |
970 | } | 970 | } |
971 | 971 | ||
972 | static void xprt_alloc_slot(struct rpc_task *task) | 972 | void xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task) |
973 | { | 973 | { |
974 | struct rpc_xprt *xprt = task->tk_xprt; | ||
975 | struct rpc_rqst *req; | 974 | struct rpc_rqst *req; |
976 | 975 | ||
976 | spin_lock(&xprt->reserve_lock); | ||
977 | if (!list_empty(&xprt->free)) { | 977 | if (!list_empty(&xprt->free)) { |
978 | req = list_entry(xprt->free.next, struct rpc_rqst, rq_list); | 978 | req = list_entry(xprt->free.next, struct rpc_rqst, rq_list); |
979 | list_del(&req->rq_list); | 979 | list_del(&req->rq_list); |
@@ -994,12 +994,29 @@ static void xprt_alloc_slot(struct rpc_task *task) | |||
994 | default: | 994 | default: |
995 | task->tk_status = -EAGAIN; | 995 | task->tk_status = -EAGAIN; |
996 | } | 996 | } |
997 | spin_unlock(&xprt->reserve_lock); | ||
997 | return; | 998 | return; |
998 | out_init_req: | 999 | out_init_req: |
999 | task->tk_status = 0; | 1000 | task->tk_status = 0; |
1000 | task->tk_rqstp = req; | 1001 | task->tk_rqstp = req; |
1001 | xprt_request_init(task, xprt); | 1002 | xprt_request_init(task, xprt); |
1003 | spin_unlock(&xprt->reserve_lock); | ||
1004 | } | ||
1005 | EXPORT_SYMBOL_GPL(xprt_alloc_slot); | ||
1006 | |||
1007 | void xprt_lock_and_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task) | ||
1008 | { | ||
1009 | /* Note: grabbing the xprt_lock_write() ensures that we throttle | ||
1010 | * new slot allocation if the transport is congested (i.e. when | ||
1011 | * reconnecting a stream transport or when out of socket write | ||
1012 | * buffer space). | ||
1013 | */ | ||
1014 | if (xprt_lock_write(xprt, task)) { | ||
1015 | xprt_alloc_slot(xprt, task); | ||
1016 | xprt_release_write(xprt, task); | ||
1017 | } | ||
1002 | } | 1018 | } |
1019 | EXPORT_SYMBOL_GPL(xprt_lock_and_alloc_slot); | ||
1003 | 1020 | ||
1004 | static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req) | 1021 | static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req) |
1005 | { | 1022 | { |
@@ -1083,20 +1100,9 @@ void xprt_reserve(struct rpc_task *task) | |||
1083 | if (task->tk_rqstp != NULL) | 1100 | if (task->tk_rqstp != NULL) |
1084 | return; | 1101 | return; |
1085 | 1102 | ||
1086 | /* Note: grabbing the xprt_lock_write() here is not strictly needed, | ||
1087 | * but ensures that we throttle new slot allocation if the transport | ||
1088 | * is congested (e.g. if reconnecting or if we're out of socket | ||
1089 | * write buffer space). | ||
1090 | */ | ||
1091 | task->tk_timeout = 0; | 1103 | task->tk_timeout = 0; |
1092 | task->tk_status = -EAGAIN; | 1104 | task->tk_status = -EAGAIN; |
1093 | if (!xprt_lock_write(xprt, task)) | 1105 | xprt->ops->alloc_slot(xprt, task); |
1094 | return; | ||
1095 | |||
1096 | spin_lock(&xprt->reserve_lock); | ||
1097 | xprt_alloc_slot(task); | ||
1098 | spin_unlock(&xprt->reserve_lock); | ||
1099 | xprt_release_write(xprt, task); | ||
1100 | } | 1106 | } |
1101 | 1107 | ||
1102 | static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt) | 1108 | static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt) |
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 06cdbff79e4a..5d9202dc7cb1 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c | |||
@@ -713,6 +713,7 @@ static void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) | |||
713 | static struct rpc_xprt_ops xprt_rdma_procs = { | 713 | static struct rpc_xprt_ops xprt_rdma_procs = { |
714 | .reserve_xprt = xprt_rdma_reserve_xprt, | 714 | .reserve_xprt = xprt_rdma_reserve_xprt, |
715 | .release_xprt = xprt_release_xprt_cong, /* sunrpc/xprt.c */ | 715 | .release_xprt = xprt_release_xprt_cong, /* sunrpc/xprt.c */ |
716 | .alloc_slot = xprt_alloc_slot, | ||
716 | .release_request = xprt_release_rqst_cong, /* ditto */ | 717 | .release_request = xprt_release_rqst_cong, /* ditto */ |
717 | .set_retrans_timeout = xprt_set_retrans_timeout_def, /* ditto */ | 718 | .set_retrans_timeout = xprt_set_retrans_timeout_def, /* ditto */ |
718 | .rpcbind = rpcb_getport_async, /* sunrpc/rpcb_clnt.c */ | 719 | .rpcbind = rpcb_getport_async, /* sunrpc/rpcb_clnt.c */ |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 400567243f84..a35b8e52e551 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -2473,6 +2473,7 @@ static void bc_destroy(struct rpc_xprt *xprt) | |||
2473 | static struct rpc_xprt_ops xs_local_ops = { | 2473 | static struct rpc_xprt_ops xs_local_ops = { |
2474 | .reserve_xprt = xprt_reserve_xprt, | 2474 | .reserve_xprt = xprt_reserve_xprt, |
2475 | .release_xprt = xs_tcp_release_xprt, | 2475 | .release_xprt = xs_tcp_release_xprt, |
2476 | .alloc_slot = xprt_alloc_slot, | ||
2476 | .rpcbind = xs_local_rpcbind, | 2477 | .rpcbind = xs_local_rpcbind, |
2477 | .set_port = xs_local_set_port, | 2478 | .set_port = xs_local_set_port, |
2478 | .connect = xs_connect, | 2479 | .connect = xs_connect, |
@@ -2489,6 +2490,7 @@ static struct rpc_xprt_ops xs_udp_ops = { | |||
2489 | .set_buffer_size = xs_udp_set_buffer_size, | 2490 | .set_buffer_size = xs_udp_set_buffer_size, |
2490 | .reserve_xprt = xprt_reserve_xprt_cong, | 2491 | .reserve_xprt = xprt_reserve_xprt_cong, |
2491 | .release_xprt = xprt_release_xprt_cong, | 2492 | .release_xprt = xprt_release_xprt_cong, |
2493 | .alloc_slot = xprt_alloc_slot, | ||
2492 | .rpcbind = rpcb_getport_async, | 2494 | .rpcbind = rpcb_getport_async, |
2493 | .set_port = xs_set_port, | 2495 | .set_port = xs_set_port, |
2494 | .connect = xs_connect, | 2496 | .connect = xs_connect, |
@@ -2506,6 +2508,7 @@ static struct rpc_xprt_ops xs_udp_ops = { | |||
2506 | static struct rpc_xprt_ops xs_tcp_ops = { | 2508 | static struct rpc_xprt_ops xs_tcp_ops = { |
2507 | .reserve_xprt = xprt_reserve_xprt, | 2509 | .reserve_xprt = xprt_reserve_xprt, |
2508 | .release_xprt = xs_tcp_release_xprt, | 2510 | .release_xprt = xs_tcp_release_xprt, |
2511 | .alloc_slot = xprt_lock_and_alloc_slot, | ||
2509 | .rpcbind = rpcb_getport_async, | 2512 | .rpcbind = rpcb_getport_async, |
2510 | .set_port = xs_set_port, | 2513 | .set_port = xs_set_port, |
2511 | .connect = xs_connect, | 2514 | .connect = xs_connect, |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 97026f3b215a..1e37dbf00cb3 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -5633,8 +5633,10 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) | |||
5633 | sizeof(connect.ht_capa_mask)); | 5633 | sizeof(connect.ht_capa_mask)); |
5634 | 5634 | ||
5635 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) { | 5635 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) { |
5636 | if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) | 5636 | if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) { |
5637 | kfree(connkeys); | ||
5637 | return -EINVAL; | 5638 | return -EINVAL; |
5639 | } | ||
5638 | memcpy(&connect.ht_capa, | 5640 | memcpy(&connect.ht_capa, |
5639 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]), | 5641 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]), |
5640 | sizeof(connect.ht_capa)); | 5642 | sizeof(connect.ht_capa)); |
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 54a0dc2e2f8d..ab2bb42fe094 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
@@ -212,7 +212,7 @@ resume: | |||
212 | /* only the first xfrm gets the encap type */ | 212 | /* only the first xfrm gets the encap type */ |
213 | encap_type = 0; | 213 | encap_type = 0; |
214 | 214 | ||
215 | if (async && x->repl->check(x, skb, seq)) { | 215 | if (async && x->repl->recheck(x, skb, seq)) { |
216 | XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR); | 216 | XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR); |
217 | goto drop_unlock; | 217 | goto drop_unlock; |
218 | } | 218 | } |
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c index 2f6d11d04a2b..3efb07d3eb27 100644 --- a/net/xfrm/xfrm_replay.c +++ b/net/xfrm/xfrm_replay.c | |||
@@ -420,6 +420,18 @@ err: | |||
420 | return -EINVAL; | 420 | return -EINVAL; |
421 | } | 421 | } |
422 | 422 | ||
423 | static int xfrm_replay_recheck_esn(struct xfrm_state *x, | ||
424 | struct sk_buff *skb, __be32 net_seq) | ||
425 | { | ||
426 | if (unlikely(XFRM_SKB_CB(skb)->seq.input.hi != | ||
427 | htonl(xfrm_replay_seqhi(x, net_seq)))) { | ||
428 | x->stats.replay_window++; | ||
429 | return -EINVAL; | ||
430 | } | ||
431 | |||
432 | return xfrm_replay_check_esn(x, skb, net_seq); | ||
433 | } | ||
434 | |||
423 | static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq) | 435 | static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq) |
424 | { | 436 | { |
425 | unsigned int bitnr, nr, i; | 437 | unsigned int bitnr, nr, i; |
@@ -479,6 +491,7 @@ static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq) | |||
479 | static struct xfrm_replay xfrm_replay_legacy = { | 491 | static struct xfrm_replay xfrm_replay_legacy = { |
480 | .advance = xfrm_replay_advance, | 492 | .advance = xfrm_replay_advance, |
481 | .check = xfrm_replay_check, | 493 | .check = xfrm_replay_check, |
494 | .recheck = xfrm_replay_check, | ||
482 | .notify = xfrm_replay_notify, | 495 | .notify = xfrm_replay_notify, |
483 | .overflow = xfrm_replay_overflow, | 496 | .overflow = xfrm_replay_overflow, |
484 | }; | 497 | }; |
@@ -486,6 +499,7 @@ static struct xfrm_replay xfrm_replay_legacy = { | |||
486 | static struct xfrm_replay xfrm_replay_bmp = { | 499 | static struct xfrm_replay xfrm_replay_bmp = { |
487 | .advance = xfrm_replay_advance_bmp, | 500 | .advance = xfrm_replay_advance_bmp, |
488 | .check = xfrm_replay_check_bmp, | 501 | .check = xfrm_replay_check_bmp, |
502 | .recheck = xfrm_replay_check_bmp, | ||
489 | .notify = xfrm_replay_notify_bmp, | 503 | .notify = xfrm_replay_notify_bmp, |
490 | .overflow = xfrm_replay_overflow_bmp, | 504 | .overflow = xfrm_replay_overflow_bmp, |
491 | }; | 505 | }; |
@@ -493,6 +507,7 @@ static struct xfrm_replay xfrm_replay_bmp = { | |||
493 | static struct xfrm_replay xfrm_replay_esn = { | 507 | static struct xfrm_replay xfrm_replay_esn = { |
494 | .advance = xfrm_replay_advance_esn, | 508 | .advance = xfrm_replay_advance_esn, |
495 | .check = xfrm_replay_check_esn, | 509 | .check = xfrm_replay_check_esn, |
510 | .recheck = xfrm_replay_recheck_esn, | ||
496 | .notify = xfrm_replay_notify_bmp, | 511 | .notify = xfrm_replay_notify_bmp, |
497 | .overflow = xfrm_replay_overflow_esn, | 512 | .overflow = xfrm_replay_overflow_esn, |
498 | }; | 513 | }; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 87cd0e4d4282..210be48d8ae3 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -1994,8 +1994,10 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay) | |||
1994 | goto error; | 1994 | goto error; |
1995 | 1995 | ||
1996 | x->outer_mode = xfrm_get_mode(x->props.mode, family); | 1996 | x->outer_mode = xfrm_get_mode(x->props.mode, family); |
1997 | if (x->outer_mode == NULL) | 1997 | if (x->outer_mode == NULL) { |
1998 | err = -EPROTONOSUPPORT; | ||
1998 | goto error; | 1999 | goto error; |
2000 | } | ||
1999 | 2001 | ||
2000 | if (init_replay) { | 2002 | if (init_replay) { |
2001 | err = xfrm_init_replay(x); | 2003 | err = xfrm_init_replay(x); |
diff --git a/scripts/Makefile.fwinst b/scripts/Makefile.fwinst index 6bf8e87f1dcf..c3f69ae275d1 100644 --- a/scripts/Makefile.fwinst +++ b/scripts/Makefile.fwinst | |||
@@ -42,7 +42,7 @@ quiet_cmd_install = INSTALL $(subst $(srctree)/,,$@) | |||
42 | $(installed-fw-dirs): | 42 | $(installed-fw-dirs): |
43 | $(call cmd,mkdir) | 43 | $(call cmd,mkdir) |
44 | 44 | ||
45 | $(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/% | $(INSTALL_FW_PATH)/$$(dir %) | 45 | $(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/% | $$(dir $(INSTALL_FW_PATH)/%) |
46 | $(call cmd,install) | 46 | $(call cmd,install) |
47 | 47 | ||
48 | PHONY += __fw_install __fw_modinst FORCE | 48 | PHONY += __fw_install __fw_modinst FORCE |
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 4629038c9e5a..b3d907eb93a9 100644 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh | |||
@@ -74,8 +74,13 @@ kallsyms() | |||
74 | info KSYM ${2} | 74 | info KSYM ${2} |
75 | local kallsymopt; | 75 | local kallsymopt; |
76 | 76 | ||
77 | if [ -n "${CONFIG_SYMBOL_PREFIX}" ]; then | ||
78 | kallsymopt="${kallsymopt} \ | ||
79 | --symbol-prefix=${CONFIG_SYMBOL_PREFIX}" | ||
80 | fi | ||
81 | |||
77 | if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then | 82 | if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then |
78 | kallsymopt=--all-symbols | 83 | kallsymopt="${kallsymopt} --all-symbols" |
79 | fi | 84 | fi |
80 | 85 | ||
81 | local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ | 86 | local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ |
@@ -211,7 +216,7 @@ if [ -n "${CONFIG_KALLSYMS}" ]; then | |||
211 | 216 | ||
212 | if ! cmp -s System.map .tmp_System.map; then | 217 | if ! cmp -s System.map .tmp_System.map; then |
213 | echo >&2 Inconsistent kallsyms data | 218 | echo >&2 Inconsistent kallsyms data |
214 | echo >&2 echo Try "make KALLSYMS_EXTRA_PASS=1" as a workaround | 219 | echo >&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround |
215 | cleanup | 220 | cleanup |
216 | exit 1 | 221 | exit 1 |
217 | fi | 222 | fi |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 2a41161fa057..f09ff6c14041 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -2814,6 +2814,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = { | |||
2814 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), | 2814 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), |
2815 | SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), | 2815 | SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), |
2816 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), | 2816 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), |
2817 | SND_PCI_QUIRK(0x1043, 0x1ac3, "ASUS X53S", POS_FIX_POSBUF), | ||
2817 | SND_PCI_QUIRK(0x1043, 0x1b43, "ASUS K53E", POS_FIX_POSBUF), | 2818 | SND_PCI_QUIRK(0x1043, 0x1b43, "ASUS K53E", POS_FIX_POSBUF), |
2818 | SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), | 2819 | SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), |
2819 | SND_PCI_QUIRK(0x10de, 0xcb89, "Macbook Pro 7,1", POS_FIX_LPIB), | 2820 | SND_PCI_QUIRK(0x10de, 0xcb89, "Macbook Pro 7,1", POS_FIX_LPIB), |
diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c index 7f2b63f97e61..7bf093c51ce5 100644 --- a/sound/pci/ice1712/prodigy_hifi.c +++ b/sound/pci/ice1712/prodigy_hifi.c | |||
@@ -297,6 +297,7 @@ static int ak4396_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem | |||
297 | } | 297 | } |
298 | 298 | ||
299 | static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); | 299 | static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); |
300 | static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); | ||
300 | 301 | ||
301 | static struct snd_kcontrol_new prodigy_hd2_controls[] __devinitdata = { | 302 | static struct snd_kcontrol_new prodigy_hd2_controls[] __devinitdata = { |
302 | { | 303 | { |
@@ -307,7 +308,7 @@ static struct snd_kcontrol_new prodigy_hd2_controls[] __devinitdata = { | |||
307 | .info = ak4396_dac_vol_info, | 308 | .info = ak4396_dac_vol_info, |
308 | .get = ak4396_dac_vol_get, | 309 | .get = ak4396_dac_vol_get, |
309 | .put = ak4396_dac_vol_put, | 310 | .put = ak4396_dac_vol_put, |
310 | .tlv = { .p = db_scale_wm_dac }, | 311 | .tlv = { .p = ak4396_db_scale }, |
311 | }, | 312 | }, |
312 | }; | 313 | }; |
313 | 314 | ||
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index c5de0a84566f..5da8ca7aee05 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig | |||
@@ -9,6 +9,7 @@ menuconfig SND_SOC | |||
9 | select SND_JACK if INPUT=y || INPUT=SND | 9 | select SND_JACK if INPUT=y || INPUT=SND |
10 | select REGMAP_I2C if I2C | 10 | select REGMAP_I2C if I2C |
11 | select REGMAP_SPI if SPI_MASTER | 11 | select REGMAP_SPI if SPI_MASTER |
12 | select SND_COMPRESS_OFFLOAD | ||
12 | ---help--- | 13 | ---help--- |
13 | 14 | ||
14 | If you want ASoC support, you should say Y here and also to the | 15 | If you want ASoC support, you should say Y here and also to the |
@@ -32,9 +33,9 @@ config SND_SOC_DMAENGINE_PCM | |||
32 | source "sound/soc/atmel/Kconfig" | 33 | source "sound/soc/atmel/Kconfig" |
33 | source "sound/soc/au1x/Kconfig" | 34 | source "sound/soc/au1x/Kconfig" |
34 | source "sound/soc/blackfin/Kconfig" | 35 | source "sound/soc/blackfin/Kconfig" |
36 | source "sound/soc/cirrus/Kconfig" | ||
35 | source "sound/soc/davinci/Kconfig" | 37 | source "sound/soc/davinci/Kconfig" |
36 | source "sound/soc/dwc/Kconfig" | 38 | source "sound/soc/dwc/Kconfig" |
37 | source "sound/soc/ep93xx/Kconfig" | ||
38 | source "sound/soc/fsl/Kconfig" | 39 | source "sound/soc/fsl/Kconfig" |
39 | source "sound/soc/jz4740/Kconfig" | 40 | source "sound/soc/jz4740/Kconfig" |
40 | source "sound/soc/nuc900/Kconfig" | 41 | source "sound/soc/nuc900/Kconfig" |
diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 00a555a743b6..bcbf1d00aa85 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o | 1 | snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o |
2 | snd-soc-core-objs += soc-pcm.o soc-io.o | 2 | snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o |
3 | 3 | ||
4 | snd-soc-dmaengine-pcm-objs := soc-dmaengine-pcm.o | 4 | snd-soc-dmaengine-pcm-objs := soc-dmaengine-pcm.o |
5 | obj-$(CONFIG_SND_SOC_DMAENGINE_PCM) += snd-soc-dmaengine-pcm.o | 5 | obj-$(CONFIG_SND_SOC_DMAENGINE_PCM) += snd-soc-dmaengine-pcm.o |
@@ -10,9 +10,9 @@ obj-$(CONFIG_SND_SOC) += generic/ | |||
10 | obj-$(CONFIG_SND_SOC) += atmel/ | 10 | obj-$(CONFIG_SND_SOC) += atmel/ |
11 | obj-$(CONFIG_SND_SOC) += au1x/ | 11 | obj-$(CONFIG_SND_SOC) += au1x/ |
12 | obj-$(CONFIG_SND_SOC) += blackfin/ | 12 | obj-$(CONFIG_SND_SOC) += blackfin/ |
13 | obj-$(CONFIG_SND_SOC) += cirrus/ | ||
13 | obj-$(CONFIG_SND_SOC) += davinci/ | 14 | obj-$(CONFIG_SND_SOC) += davinci/ |
14 | obj-$(CONFIG_SND_SOC) += dwc/ | 15 | obj-$(CONFIG_SND_SOC) += dwc/ |
15 | obj-$(CONFIG_SND_SOC) += ep93xx/ | ||
16 | obj-$(CONFIG_SND_SOC) += fsl/ | 16 | obj-$(CONFIG_SND_SOC) += fsl/ |
17 | obj-$(CONFIG_SND_SOC) += jz4740/ | 17 | obj-$(CONFIG_SND_SOC) += jz4740/ |
18 | obj-$(CONFIG_SND_SOC) += mid-x86/ | 18 | obj-$(CONFIG_SND_SOC) += mid-x86/ |
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c index d542d4063771..16b9c9efd19a 100644 --- a/sound/soc/blackfin/bf5xx-ad1836.c +++ b/sound/soc/blackfin/bf5xx-ad1836.c | |||
@@ -59,62 +59,63 @@ static struct snd_soc_ops bf5xx_ad1836_ops = { | |||
59 | #define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \ | 59 | #define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \ |
60 | SND_SOC_DAIFMT_CBM_CFM) | 60 | SND_SOC_DAIFMT_CBM_CFM) |
61 | 61 | ||
62 | static struct snd_soc_dai_link bf5xx_ad1836_dai[] = { | 62 | static struct snd_soc_dai_link bf5xx_ad1836_dai = { |
63 | { | 63 | .name = "ad1836", |
64 | .name = "ad1836", | 64 | .stream_name = "AD1836", |
65 | .stream_name = "AD1836", | 65 | .codec_dai_name = "ad1836-hifi", |
66 | .cpu_dai_name = "bfin-tdm.0", | 66 | .platform_name = "bfin-tdm-pcm-audio", |
67 | .codec_dai_name = "ad1836-hifi", | 67 | .ops = &bf5xx_ad1836_ops, |
68 | .platform_name = "bfin-tdm-pcm-audio", | 68 | .dai_fmt = BF5XX_AD1836_DAIFMT, |
69 | .codec_name = "spi0.4", | ||
70 | .ops = &bf5xx_ad1836_ops, | ||
71 | .dai_fmt = BF5XX_AD1836_DAIFMT, | ||
72 | }, | ||
73 | { | ||
74 | .name = "ad1836", | ||
75 | .stream_name = "AD1836", | ||
76 | .cpu_dai_name = "bfin-tdm.1", | ||
77 | .codec_dai_name = "ad1836-hifi", | ||
78 | .platform_name = "bfin-tdm-pcm-audio", | ||
79 | .codec_name = "spi0.4", | ||
80 | .ops = &bf5xx_ad1836_ops, | ||
81 | .dai_fmt = BF5XX_AD1836_DAIFMT, | ||
82 | }, | ||
83 | }; | 69 | }; |
84 | 70 | ||
85 | static struct snd_soc_card bf5xx_ad1836 = { | 71 | static struct snd_soc_card bf5xx_ad1836 = { |
86 | .name = "bfin-ad1836", | 72 | .name = "bfin-ad1836", |
87 | .owner = THIS_MODULE, | 73 | .owner = THIS_MODULE, |
88 | .dai_link = &bf5xx_ad1836_dai[CONFIG_SND_BF5XX_SPORT_NUM], | 74 | .dai_link = &bf5xx_ad1836_dai, |
89 | .num_links = 1, | 75 | .num_links = 1, |
90 | }; | 76 | }; |
91 | 77 | ||
92 | static struct platform_device *bfxx_ad1836_snd_device; | 78 | static __devinit int bf5xx_ad1836_driver_probe(struct platform_device *pdev) |
93 | |||
94 | static int __init bf5xx_ad1836_init(void) | ||
95 | { | 79 | { |
80 | struct snd_soc_card *card = &bf5xx_ad1836; | ||
81 | const char **link_name; | ||
96 | int ret; | 82 | int ret; |
97 | 83 | ||
98 | bfxx_ad1836_snd_device = platform_device_alloc("soc-audio", -1); | 84 | link_name = pdev->dev.platform_data; |
99 | if (!bfxx_ad1836_snd_device) | 85 | if (!link_name) { |
100 | return -ENOMEM; | 86 | dev_err(&pdev->dev, "No platform data supplied\n"); |
87 | return -EINVAL; | ||
88 | } | ||
89 | bf5xx_ad1836_dai.cpu_dai_name = link_name[0]; | ||
90 | bf5xx_ad1836_dai.codec_name = link_name[1]; | ||
101 | 91 | ||
102 | platform_set_drvdata(bfxx_ad1836_snd_device, &bf5xx_ad1836); | 92 | card->dev = &pdev->dev; |
103 | ret = platform_device_add(bfxx_ad1836_snd_device); | 93 | platform_set_drvdata(pdev, card); |
104 | 94 | ||
95 | ret = snd_soc_register_card(card); | ||
105 | if (ret) | 96 | if (ret) |
106 | platform_device_put(bfxx_ad1836_snd_device); | 97 | dev_err(&pdev->dev, "Failed to register card\n"); |
107 | |||
108 | return ret; | 98 | return ret; |
109 | } | 99 | } |
110 | 100 | ||
111 | static void __exit bf5xx_ad1836_exit(void) | 101 | static int __devexit bf5xx_ad1836_driver_remove(struct platform_device *pdev) |
112 | { | 102 | { |
113 | platform_device_unregister(bfxx_ad1836_snd_device); | 103 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
104 | |||
105 | snd_soc_unregister_card(card); | ||
106 | return 0; | ||
114 | } | 107 | } |
115 | 108 | ||
116 | module_init(bf5xx_ad1836_init); | 109 | static struct platform_driver bf5xx_ad1836_driver = { |
117 | module_exit(bf5xx_ad1836_exit); | 110 | .driver = { |
111 | .name = "bfin-snd-ad1836", | ||
112 | .owner = THIS_MODULE, | ||
113 | .pm = &snd_soc_pm_ops, | ||
114 | }, | ||
115 | .probe = bf5xx_ad1836_driver_probe, | ||
116 | .remove = __devexit_p(bf5xx_ad1836_driver_remove), | ||
117 | }; | ||
118 | module_platform_driver(bf5xx_ad1836_driver); | ||
118 | 119 | ||
119 | /* Module information */ | 120 | /* Module information */ |
120 | MODULE_AUTHOR("Barry Song"); | 121 | MODULE_AUTHOR("Barry Song"); |
diff --git a/sound/soc/ep93xx/Kconfig b/sound/soc/cirrus/Kconfig index 88143db7e753..88143db7e753 100644 --- a/sound/soc/ep93xx/Kconfig +++ b/sound/soc/cirrus/Kconfig | |||
diff --git a/sound/soc/ep93xx/Makefile b/sound/soc/cirrus/Makefile index 5514146cbdf0..5514146cbdf0 100644 --- a/sound/soc/ep93xx/Makefile +++ b/sound/soc/cirrus/Makefile | |||
diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/cirrus/edb93xx.c index e01cb02abd3a..e01cb02abd3a 100644 --- a/sound/soc/ep93xx/edb93xx.c +++ b/sound/soc/cirrus/edb93xx.c | |||
diff --git a/sound/soc/ep93xx/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c index bdffab33e160..bdffab33e160 100644 --- a/sound/soc/ep93xx/ep93xx-ac97.c +++ b/sound/soc/cirrus/ep93xx-ac97.c | |||
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c index 8df8f6dc474f..8df8f6dc474f 100644 --- a/sound/soc/ep93xx/ep93xx-i2s.c +++ b/sound/soc/cirrus/ep93xx-i2s.c | |||
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/cirrus/ep93xx-pcm.c index 4eea98b42bc8..4eea98b42bc8 100644 --- a/sound/soc/ep93xx/ep93xx-pcm.c +++ b/sound/soc/cirrus/ep93xx-pcm.c | |||
diff --git a/sound/soc/ep93xx/ep93xx-pcm.h b/sound/soc/cirrus/ep93xx-pcm.h index 111e1121ecb8..111e1121ecb8 100644 --- a/sound/soc/ep93xx/ep93xx-pcm.h +++ b/sound/soc/cirrus/ep93xx-pcm.h | |||
diff --git a/sound/soc/ep93xx/simone.c b/sound/soc/cirrus/simone.c index dd997094eb30..dd997094eb30 100644 --- a/sound/soc/ep93xx/simone.c +++ b/sound/soc/cirrus/simone.c | |||
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/cirrus/snappercl15.c index a193cea3cf3c..a193cea3cf3c 100644 --- a/sound/soc/ep93xx/snappercl15.c +++ b/sound/soc/cirrus/snappercl15.c | |||
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 9f8e8594aeb9..3684255e5fba 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -70,6 +70,7 @@ config SND_SOC_ALL_CODECS | |||
70 | select SND_SOC_UDA134X | 70 | select SND_SOC_UDA134X |
71 | select SND_SOC_UDA1380 if I2C | 71 | select SND_SOC_UDA1380 if I2C |
72 | select SND_SOC_WL1273 if MFD_WL1273_CORE | 72 | select SND_SOC_WL1273 if MFD_WL1273_CORE |
73 | select SND_SOC_WM0010 if SPI_MASTER | ||
73 | select SND_SOC_WM1250_EV1 if I2C | 74 | select SND_SOC_WM1250_EV1 if I2C |
74 | select SND_SOC_WM2000 if I2C | 75 | select SND_SOC_WM2000 if I2C |
75 | select SND_SOC_WM2200 if I2C | 76 | select SND_SOC_WM2200 if I2C |
@@ -326,6 +327,9 @@ config SND_SOC_UDA1380 | |||
326 | config SND_SOC_WL1273 | 327 | config SND_SOC_WL1273 |
327 | tristate | 328 | tristate |
328 | 329 | ||
330 | config SND_SOC_WM0010 | ||
331 | tristate | ||
332 | |||
329 | config SND_SOC_WM1250_EV1 | 333 | config SND_SOC_WM1250_EV1 |
330 | tristate | 334 | tristate |
331 | 335 | ||
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 34148bb59c68..ca508b251df7 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -61,6 +61,7 @@ snd-soc-twl6040-objs := twl6040.o | |||
61 | snd-soc-uda134x-objs := uda134x.o | 61 | snd-soc-uda134x-objs := uda134x.o |
62 | snd-soc-uda1380-objs := uda1380.o | 62 | snd-soc-uda1380-objs := uda1380.o |
63 | snd-soc-wl1273-objs := wl1273.o | 63 | snd-soc-wl1273-objs := wl1273.o |
64 | snd-soc-wm0010-objs := wm0010.o | ||
64 | snd-soc-wm1250-ev1-objs := wm1250-ev1.o | 65 | snd-soc-wm1250-ev1-objs := wm1250-ev1.o |
65 | snd-soc-wm2000-objs := wm2000.o | 66 | snd-soc-wm2000-objs := wm2000.o |
66 | snd-soc-wm2200-objs := wm2200.o | 67 | snd-soc-wm2200-objs := wm2200.o |
@@ -177,6 +178,7 @@ obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o | |||
177 | obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o | 178 | obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o |
178 | obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o | 179 | obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o |
179 | obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o | 180 | obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o |
181 | obj-$(CONFIG_SND_SOC_WM0010) += snd-soc-wm0010.o | ||
180 | obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o | 182 | obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o |
181 | obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o | 183 | obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o |
182 | obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o | 184 | obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o |
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 23b40186f9b8..2c1c2524ef8c 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c | |||
@@ -390,10 +390,10 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = { | |||
390 | SND_SOC_DAPM_CLOCK_SUPPLY("audioclk"), | 390 | SND_SOC_DAPM_CLOCK_SUPPLY("audioclk"), |
391 | 391 | ||
392 | /* Regulators */ | 392 | /* Regulators */ |
393 | SND_SOC_DAPM_REGULATOR_SUPPLY("V-AUD", 0), | 393 | SND_SOC_DAPM_REGULATOR_SUPPLY("V-AUD", 0, 0), |
394 | SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC1", 0), | 394 | SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC1", 0, 0), |
395 | SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC2", 0), | 395 | SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC2", 0, 0), |
396 | SND_SOC_DAPM_REGULATOR_SUPPLY("V-DMIC", 0), | 396 | SND_SOC_DAPM_REGULATOR_SUPPLY("V-DMIC", 0, 0), |
397 | 397 | ||
398 | /* Power */ | 398 | /* Power */ |
399 | SND_SOC_DAPM_SUPPLY("Audio Power", | 399 | SND_SOC_DAPM_SUPPLY("Audio Power", |
@@ -2405,10 +2405,7 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec) | |||
2405 | dev_dbg(dev, "%s: Enter.\n", __func__); | 2405 | dev_dbg(dev, "%s: Enter.\n", __func__); |
2406 | 2406 | ||
2407 | /* Setup AB8500 according to board-settings */ | 2407 | /* Setup AB8500 according to board-settings */ |
2408 | pdata = (struct ab8500_platform_data *)dev_get_platdata(dev->parent); | 2408 | pdata = dev_get_platdata(dev->parent); |
2409 | |||
2410 | /* Inform SoC Core that we have our own I/O arrangements. */ | ||
2411 | codec->control_data = (void *)true; | ||
2412 | 2409 | ||
2413 | status = ab8500_audio_setup_mics(codec, &pdata->codec->amics); | 2410 | status = ab8500_audio_setup_mics(codec, &pdata->codec->amics); |
2414 | if (status < 0) { | 2411 | if (status < 0) { |
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index c67b50d8b317..dce6ebeef452 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c | |||
@@ -19,6 +19,8 @@ | |||
19 | #include <sound/soc.h> | 19 | #include <sound/soc.h> |
20 | #include <sound/tlv.h> | 20 | #include <sound/tlv.h> |
21 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
22 | #include <linux/regmap.h> | ||
23 | |||
22 | #include "ad1836.h" | 24 | #include "ad1836.h" |
23 | 25 | ||
24 | enum ad1836_type { | 26 | enum ad1836_type { |
@@ -30,6 +32,7 @@ enum ad1836_type { | |||
30 | /* codec private data */ | 32 | /* codec private data */ |
31 | struct ad1836_priv { | 33 | struct ad1836_priv { |
32 | enum ad1836_type type; | 34 | enum ad1836_type type; |
35 | struct regmap *regmap; | ||
33 | }; | 36 | }; |
34 | 37 | ||
35 | /* | 38 | /* |
@@ -161,8 +164,8 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream, | |||
161 | struct snd_pcm_hw_params *params, | 164 | struct snd_pcm_hw_params *params, |
162 | struct snd_soc_dai *dai) | 165 | struct snd_soc_dai *dai) |
163 | { | 166 | { |
167 | struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(dai->codec); | ||
164 | int word_len = 0; | 168 | int word_len = 0; |
165 | struct snd_soc_codec *codec = dai->codec; | ||
166 | 169 | ||
167 | /* bit size */ | 170 | /* bit size */ |
168 | switch (params_format(params)) { | 171 | switch (params_format(params)) { |
@@ -178,10 +181,12 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream, | |||
178 | break; | 181 | break; |
179 | } | 182 | } |
180 | 183 | ||
181 | snd_soc_update_bits(codec, AD1836_DAC_CTRL1, AD1836_DAC_WORD_LEN_MASK, | 184 | regmap_update_bits(ad1836->regmap, AD1836_DAC_CTRL1, |
185 | AD1836_DAC_WORD_LEN_MASK, | ||
182 | word_len << AD1836_DAC_WORD_LEN_OFFSET); | 186 | word_len << AD1836_DAC_WORD_LEN_OFFSET); |
183 | 187 | ||
184 | snd_soc_update_bits(codec, AD1836_ADC_CTRL2, AD1836_ADC_WORD_LEN_MASK, | 188 | regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2, |
189 | AD1836_ADC_WORD_LEN_MASK, | ||
185 | word_len << AD1836_ADC_WORD_OFFSET); | 190 | word_len << AD1836_ADC_WORD_OFFSET); |
186 | 191 | ||
187 | return 0; | 192 | return 0; |
@@ -223,15 +228,17 @@ static struct snd_soc_dai_driver ad183x_dais[] = { | |||
223 | #ifdef CONFIG_PM | 228 | #ifdef CONFIG_PM |
224 | static int ad1836_suspend(struct snd_soc_codec *codec) | 229 | static int ad1836_suspend(struct snd_soc_codec *codec) |
225 | { | 230 | { |
231 | struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec); | ||
226 | /* reset clock control mode */ | 232 | /* reset clock control mode */ |
227 | return snd_soc_update_bits(codec, AD1836_ADC_CTRL2, | 233 | return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2, |
228 | AD1836_ADC_SERFMT_MASK, 0); | 234 | AD1836_ADC_SERFMT_MASK, 0); |
229 | } | 235 | } |
230 | 236 | ||
231 | static int ad1836_resume(struct snd_soc_codec *codec) | 237 | static int ad1836_resume(struct snd_soc_codec *codec) |
232 | { | 238 | { |
239 | struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec); | ||
233 | /* restore clock control mode */ | 240 | /* restore clock control mode */ |
234 | return snd_soc_update_bits(codec, AD1836_ADC_CTRL2, | 241 | return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2, |
235 | AD1836_ADC_SERFMT_MASK, AD1836_ADC_AUX); | 242 | AD1836_ADC_SERFMT_MASK, AD1836_ADC_AUX); |
236 | } | 243 | } |
237 | #else | 244 | #else |
@@ -250,37 +257,30 @@ static int ad1836_probe(struct snd_soc_codec *codec) | |||
250 | num_dacs = ad183x_dais[ad1836->type].playback.channels_max / 2; | 257 | num_dacs = ad183x_dais[ad1836->type].playback.channels_max / 2; |
251 | num_adcs = ad183x_dais[ad1836->type].capture.channels_max / 2; | 258 | num_adcs = ad183x_dais[ad1836->type].capture.channels_max / 2; |
252 | 259 | ||
253 | ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI); | ||
254 | if (ret < 0) { | ||
255 | dev_err(codec->dev, "failed to set cache I/O: %d\n", | ||
256 | ret); | ||
257 | return ret; | ||
258 | } | ||
259 | |||
260 | /* default setting for ad1836 */ | 260 | /* default setting for ad1836 */ |
261 | /* de-emphasis: 48kHz, power-on dac */ | 261 | /* de-emphasis: 48kHz, power-on dac */ |
262 | snd_soc_write(codec, AD1836_DAC_CTRL1, 0x300); | 262 | regmap_write(ad1836->regmap, AD1836_DAC_CTRL1, 0x300); |
263 | /* unmute dac channels */ | 263 | /* unmute dac channels */ |
264 | snd_soc_write(codec, AD1836_DAC_CTRL2, 0x0); | 264 | regmap_write(ad1836->regmap, AD1836_DAC_CTRL2, 0x0); |
265 | /* high-pass filter enable, power-on adc */ | 265 | /* high-pass filter enable, power-on adc */ |
266 | snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100); | 266 | regmap_write(ad1836->regmap, AD1836_ADC_CTRL1, 0x100); |
267 | /* unmute adc channles, adc aux mode */ | 267 | /* unmute adc channles, adc aux mode */ |
268 | snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180); | 268 | regmap_write(ad1836->regmap, AD1836_ADC_CTRL2, 0x180); |
269 | /* volume */ | 269 | /* volume */ |
270 | for (i = 1; i <= num_dacs; ++i) { | 270 | for (i = 1; i <= num_dacs; ++i) { |
271 | snd_soc_write(codec, AD1836_DAC_L_VOL(i), 0x3FF); | 271 | regmap_write(ad1836->regmap, AD1836_DAC_L_VOL(i), 0x3FF); |
272 | snd_soc_write(codec, AD1836_DAC_R_VOL(i), 0x3FF); | 272 | regmap_write(ad1836->regmap, AD1836_DAC_R_VOL(i), 0x3FF); |
273 | } | 273 | } |
274 | 274 | ||
275 | if (ad1836->type == AD1836) { | 275 | if (ad1836->type == AD1836) { |
276 | /* left/right diff:PGA/MUX */ | 276 | /* left/right diff:PGA/MUX */ |
277 | snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A); | 277 | regmap_write(ad1836->regmap, AD1836_ADC_CTRL3, 0x3A); |
278 | ret = snd_soc_add_codec_controls(codec, ad1836_controls, | 278 | ret = snd_soc_add_codec_controls(codec, ad1836_controls, |
279 | ARRAY_SIZE(ad1836_controls)); | 279 | ARRAY_SIZE(ad1836_controls)); |
280 | if (ret) | 280 | if (ret) |
281 | return ret; | 281 | return ret; |
282 | } else { | 282 | } else { |
283 | snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00); | 283 | regmap_write(ad1836->regmap, AD1836_ADC_CTRL3, 0x00); |
284 | } | 284 | } |
285 | 285 | ||
286 | ret = snd_soc_add_codec_controls(codec, ad183x_dac_controls, num_dacs * 2); | 286 | ret = snd_soc_add_codec_controls(codec, ad183x_dac_controls, num_dacs * 2); |
@@ -313,8 +313,9 @@ static int ad1836_probe(struct snd_soc_codec *codec) | |||
313 | /* power down chip */ | 313 | /* power down chip */ |
314 | static int ad1836_remove(struct snd_soc_codec *codec) | 314 | static int ad1836_remove(struct snd_soc_codec *codec) |
315 | { | 315 | { |
316 | struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec); | ||
316 | /* reset clock control mode */ | 317 | /* reset clock control mode */ |
317 | return snd_soc_update_bits(codec, AD1836_ADC_CTRL2, | 318 | return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2, |
318 | AD1836_ADC_SERFMT_MASK, 0); | 319 | AD1836_ADC_SERFMT_MASK, 0); |
319 | } | 320 | } |
320 | 321 | ||
@@ -323,8 +324,6 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1836 = { | |||
323 | .remove = ad1836_remove, | 324 | .remove = ad1836_remove, |
324 | .suspend = ad1836_suspend, | 325 | .suspend = ad1836_suspend, |
325 | .resume = ad1836_resume, | 326 | .resume = ad1836_resume, |
326 | .reg_cache_size = AD1836_NUM_REGS, | ||
327 | .reg_word_size = sizeof(u16), | ||
328 | 327 | ||
329 | .controls = ad183x_controls, | 328 | .controls = ad183x_controls, |
330 | .num_controls = ARRAY_SIZE(ad183x_controls), | 329 | .num_controls = ARRAY_SIZE(ad183x_controls), |
@@ -334,6 +333,33 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1836 = { | |||
334 | .num_dapm_routes = ARRAY_SIZE(ad183x_dapm_routes), | 333 | .num_dapm_routes = ARRAY_SIZE(ad183x_dapm_routes), |
335 | }; | 334 | }; |
336 | 335 | ||
336 | static const struct reg_default ad1836_reg_defaults[] = { | ||
337 | { AD1836_DAC_CTRL1, 0x0000 }, | ||
338 | { AD1836_DAC_CTRL2, 0x0000 }, | ||
339 | { AD1836_DAC_L_VOL(0), 0x0000 }, | ||
340 | { AD1836_DAC_R_VOL(0), 0x0000 }, | ||
341 | { AD1836_DAC_L_VOL(1), 0x0000 }, | ||
342 | { AD1836_DAC_R_VOL(1), 0x0000 }, | ||
343 | { AD1836_DAC_L_VOL(2), 0x0000 }, | ||
344 | { AD1836_DAC_R_VOL(2), 0x0000 }, | ||
345 | { AD1836_DAC_L_VOL(3), 0x0000 }, | ||
346 | { AD1836_DAC_R_VOL(3), 0x0000 }, | ||
347 | { AD1836_ADC_CTRL1, 0x0000 }, | ||
348 | { AD1836_ADC_CTRL2, 0x0000 }, | ||
349 | { AD1836_ADC_CTRL3, 0x0000 }, | ||
350 | }; | ||
351 | |||
352 | static const struct regmap_config ad1836_regmap_config = { | ||
353 | .val_bits = 12, | ||
354 | .reg_bits = 4, | ||
355 | .read_flag_mask = 0x08, | ||
356 | |||
357 | .max_register = AD1836_ADC_CTRL3, | ||
358 | .reg_defaults = ad1836_reg_defaults, | ||
359 | .num_reg_defaults = ARRAY_SIZE(ad1836_reg_defaults), | ||
360 | .cache_type = REGCACHE_RBTREE, | ||
361 | }; | ||
362 | |||
337 | static int __devinit ad1836_spi_probe(struct spi_device *spi) | 363 | static int __devinit ad1836_spi_probe(struct spi_device *spi) |
338 | { | 364 | { |
339 | struct ad1836_priv *ad1836; | 365 | struct ad1836_priv *ad1836; |
@@ -344,6 +370,10 @@ static int __devinit ad1836_spi_probe(struct spi_device *spi) | |||
344 | if (ad1836 == NULL) | 370 | if (ad1836 == NULL) |
345 | return -ENOMEM; | 371 | return -ENOMEM; |
346 | 372 | ||
373 | ad1836->regmap = devm_regmap_init_spi(spi, &ad1836_regmap_config); | ||
374 | if (IS_ERR(ad1836->regmap)) | ||
375 | return PTR_ERR(ad1836->regmap); | ||
376 | |||
347 | ad1836->type = spi_get_device_id(spi)->driver_data; | 377 | ad1836->type = spi_get_device_id(spi)->driver_data; |
348 | 378 | ||
349 | spi_set_drvdata(spi, ad1836); | 379 | spi_set_drvdata(spi, ad1836); |
@@ -379,17 +409,7 @@ static struct spi_driver ad1836_spi_driver = { | |||
379 | .id_table = ad1836_ids, | 409 | .id_table = ad1836_ids, |
380 | }; | 410 | }; |
381 | 411 | ||
382 | static int __init ad1836_init(void) | 412 | module_spi_driver(ad1836_spi_driver); |
383 | { | ||
384 | return spi_register_driver(&ad1836_spi_driver); | ||
385 | } | ||
386 | module_init(ad1836_init); | ||
387 | |||
388 | static void __exit ad1836_exit(void) | ||
389 | { | ||
390 | spi_unregister_driver(&ad1836_spi_driver); | ||
391 | } | ||
392 | module_exit(ad1836_exit); | ||
393 | 413 | ||
394 | MODULE_DESCRIPTION("ASoC ad1836 driver"); | 414 | MODULE_DESCRIPTION("ASoC ad1836 driver"); |
395 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | 415 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); |
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 13e62be4f990..2f752660f678 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c | |||
@@ -381,40 +381,25 @@ static const struct regmap_config ad193x_spi_regmap_config = { | |||
381 | static int __devinit ad193x_spi_probe(struct spi_device *spi) | 381 | static int __devinit ad193x_spi_probe(struct spi_device *spi) |
382 | { | 382 | { |
383 | struct ad193x_priv *ad193x; | 383 | struct ad193x_priv *ad193x; |
384 | int ret; | ||
385 | 384 | ||
386 | ad193x = devm_kzalloc(&spi->dev, sizeof(struct ad193x_priv), | 385 | ad193x = devm_kzalloc(&spi->dev, sizeof(struct ad193x_priv), |
387 | GFP_KERNEL); | 386 | GFP_KERNEL); |
388 | if (ad193x == NULL) | 387 | if (ad193x == NULL) |
389 | return -ENOMEM; | 388 | return -ENOMEM; |
390 | 389 | ||
391 | ad193x->regmap = regmap_init_spi(spi, &ad193x_spi_regmap_config); | 390 | ad193x->regmap = devm_regmap_init_spi(spi, &ad193x_spi_regmap_config); |
392 | if (IS_ERR(ad193x->regmap)) { | 391 | if (IS_ERR(ad193x->regmap)) |
393 | ret = PTR_ERR(ad193x->regmap); | 392 | return PTR_ERR(ad193x->regmap); |
394 | goto err_out; | ||
395 | } | ||
396 | 393 | ||
397 | spi_set_drvdata(spi, ad193x); | 394 | spi_set_drvdata(spi, ad193x); |
398 | 395 | ||
399 | ret = snd_soc_register_codec(&spi->dev, | 396 | return snd_soc_register_codec(&spi->dev, &soc_codec_dev_ad193x, |
400 | &soc_codec_dev_ad193x, &ad193x_dai, 1); | 397 | &ad193x_dai, 1); |
401 | if (ret < 0) | ||
402 | goto err_regmap_exit; | ||
403 | |||
404 | return 0; | ||
405 | |||
406 | err_regmap_exit: | ||
407 | regmap_exit(ad193x->regmap); | ||
408 | err_out: | ||
409 | return ret; | ||
410 | } | 398 | } |
411 | 399 | ||
412 | static int __devexit ad193x_spi_remove(struct spi_device *spi) | 400 | static int __devexit ad193x_spi_remove(struct spi_device *spi) |
413 | { | 401 | { |
414 | struct ad193x_priv *ad193x = spi_get_drvdata(spi); | ||
415 | |||
416 | snd_soc_unregister_codec(&spi->dev); | 402 | snd_soc_unregister_codec(&spi->dev); |
417 | regmap_exit(ad193x->regmap); | ||
418 | return 0; | 403 | return 0; |
419 | } | 404 | } |
420 | 405 | ||
@@ -449,40 +434,25 @@ static int __devinit ad193x_i2c_probe(struct i2c_client *client, | |||
449 | const struct i2c_device_id *id) | 434 | const struct i2c_device_id *id) |
450 | { | 435 | { |
451 | struct ad193x_priv *ad193x; | 436 | struct ad193x_priv *ad193x; |
452 | int ret; | ||
453 | 437 | ||
454 | ad193x = devm_kzalloc(&client->dev, sizeof(struct ad193x_priv), | 438 | ad193x = devm_kzalloc(&client->dev, sizeof(struct ad193x_priv), |
455 | GFP_KERNEL); | 439 | GFP_KERNEL); |
456 | if (ad193x == NULL) | 440 | if (ad193x == NULL) |
457 | return -ENOMEM; | 441 | return -ENOMEM; |
458 | 442 | ||
459 | ad193x->regmap = regmap_init_i2c(client, &ad193x_i2c_regmap_config); | 443 | ad193x->regmap = devm_regmap_init_i2c(client, &ad193x_i2c_regmap_config); |
460 | if (IS_ERR(ad193x->regmap)) { | 444 | if (IS_ERR(ad193x->regmap)) |
461 | ret = PTR_ERR(ad193x->regmap); | 445 | return PTR_ERR(ad193x->regmap); |
462 | goto err_out; | ||
463 | } | ||
464 | 446 | ||
465 | i2c_set_clientdata(client, ad193x); | 447 | i2c_set_clientdata(client, ad193x); |
466 | 448 | ||
467 | ret = snd_soc_register_codec(&client->dev, | 449 | return snd_soc_register_codec(&client->dev, &soc_codec_dev_ad193x, |
468 | &soc_codec_dev_ad193x, &ad193x_dai, 1); | 450 | &ad193x_dai, 1); |
469 | if (ret < 0) | ||
470 | goto err_regmap_exit; | ||
471 | |||
472 | return 0; | ||
473 | |||
474 | err_regmap_exit: | ||
475 | regmap_exit(ad193x->regmap); | ||
476 | err_out: | ||
477 | return ret; | ||
478 | } | 451 | } |
479 | 452 | ||
480 | static int __devexit ad193x_i2c_remove(struct i2c_client *client) | 453 | static int __devexit ad193x_i2c_remove(struct i2c_client *client) |
481 | { | 454 | { |
482 | struct ad193x_priv *ad193x = i2c_get_clientdata(client); | ||
483 | |||
484 | snd_soc_unregister_codec(&client->dev); | 455 | snd_soc_unregister_codec(&client->dev); |
485 | regmap_exit(ad193x->regmap); | ||
486 | return 0; | 456 | return 0; |
487 | } | 457 | } |
488 | 458 | ||
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 11b1b714b8b5..8c39dddd7d00 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c | |||
@@ -186,7 +186,6 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) | |||
186 | 186 | ||
187 | printk(KERN_INFO "AD1980 SoC Audio Codec\n"); | 187 | printk(KERN_INFO "AD1980 SoC Audio Codec\n"); |
188 | 188 | ||
189 | codec->control_data = codec; /* we don't use regmap! */ | ||
190 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | 189 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); |
191 | if (ret < 0) { | 190 | if (ret < 0) { |
192 | printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); | 191 | printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); |
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 44f59064d8de..704544bfc90d 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c | |||
@@ -1392,17 +1392,7 @@ static struct i2c_driver adau1373_i2c_driver = { | |||
1392 | .id_table = adau1373_i2c_id, | 1392 | .id_table = adau1373_i2c_id, |
1393 | }; | 1393 | }; |
1394 | 1394 | ||
1395 | static int __init adau1373_init(void) | 1395 | module_i2c_driver(adau1373_i2c_driver); |
1396 | { | ||
1397 | return i2c_add_driver(&adau1373_i2c_driver); | ||
1398 | } | ||
1399 | module_init(adau1373_init); | ||
1400 | |||
1401 | static void __exit adau1373_exit(void) | ||
1402 | { | ||
1403 | i2c_del_driver(&adau1373_i2c_driver); | ||
1404 | } | ||
1405 | module_exit(adau1373_exit); | ||
1406 | 1396 | ||
1407 | MODULE_DESCRIPTION("ASoC ADAU1373 driver"); | 1397 | MODULE_DESCRIPTION("ASoC ADAU1373 driver"); |
1408 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | 1398 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); |
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 3d50fc8646b6..51f2f3cd8136 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c | |||
@@ -527,17 +527,7 @@ static struct i2c_driver adau1701_i2c_driver = { | |||
527 | .id_table = adau1701_i2c_id, | 527 | .id_table = adau1701_i2c_id, |
528 | }; | 528 | }; |
529 | 529 | ||
530 | static int __init adau1701_init(void) | 530 | module_i2c_driver(adau1701_i2c_driver); |
531 | { | ||
532 | return i2c_add_driver(&adau1701_i2c_driver); | ||
533 | } | ||
534 | module_init(adau1701_init); | ||
535 | |||
536 | static void __exit adau1701_exit(void) | ||
537 | { | ||
538 | i2c_del_driver(&adau1701_i2c_driver); | ||
539 | } | ||
540 | module_exit(adau1701_exit); | ||
541 | 531 | ||
542 | MODULE_DESCRIPTION("ASoC ADAU1701 SigmaDSP driver"); | 532 | MODULE_DESCRIPTION("ASoC ADAU1701 SigmaDSP driver"); |
543 | MODULE_AUTHOR("Cliff Cai <cliff.cai@analog.com>"); | 533 | MODULE_AUTHOR("Cliff Cai <cliff.cai@analog.com>"); |
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 5fb7c2a80e6d..2b457976a7bf 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c | |||
@@ -696,17 +696,7 @@ static struct i2c_driver ak4671_i2c_driver = { | |||
696 | .id_table = ak4671_i2c_id, | 696 | .id_table = ak4671_i2c_id, |
697 | }; | 697 | }; |
698 | 698 | ||
699 | static int __init ak4671_modinit(void) | 699 | module_i2c_driver(ak4671_i2c_driver); |
700 | { | ||
701 | return i2c_add_driver(&ak4671_i2c_driver); | ||
702 | } | ||
703 | module_init(ak4671_modinit); | ||
704 | |||
705 | static void __exit ak4671_exit(void) | ||
706 | { | ||
707 | i2c_del_driver(&ak4671_i2c_driver); | ||
708 | } | ||
709 | module_exit(ak4671_exit); | ||
710 | 700 | ||
711 | MODULE_DESCRIPTION("ASoC AK4671 codec driver"); | 701 | MODULE_DESCRIPTION("ASoC AK4671 codec driver"); |
712 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | 702 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); |
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 5c9cacaf2d52..c167c896eaee 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
@@ -229,6 +229,69 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
229 | } | 229 | } |
230 | EXPORT_SYMBOL_GPL(arizona_out_ev); | 230 | EXPORT_SYMBOL_GPL(arizona_out_ev); |
231 | 231 | ||
232 | static unsigned int arizona_sysclk_48k_rates[] = { | ||
233 | 6144000, | ||
234 | 12288000, | ||
235 | 22579200, | ||
236 | 49152000, | ||
237 | }; | ||
238 | |||
239 | static unsigned int arizona_sysclk_44k1_rates[] = { | ||
240 | 5644800, | ||
241 | 11289600, | ||
242 | 24576000, | ||
243 | 45158400, | ||
244 | }; | ||
245 | |||
246 | static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk, | ||
247 | unsigned int freq) | ||
248 | { | ||
249 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
250 | unsigned int reg; | ||
251 | unsigned int *rates; | ||
252 | int ref, div, refclk; | ||
253 | |||
254 | switch (clk) { | ||
255 | case ARIZONA_CLK_OPCLK: | ||
256 | reg = ARIZONA_OUTPUT_SYSTEM_CLOCK; | ||
257 | refclk = priv->sysclk; | ||
258 | break; | ||
259 | case ARIZONA_CLK_ASYNC_OPCLK: | ||
260 | reg = ARIZONA_OUTPUT_ASYNC_CLOCK; | ||
261 | refclk = priv->asyncclk; | ||
262 | break; | ||
263 | default: | ||
264 | return -EINVAL; | ||
265 | } | ||
266 | |||
267 | if (refclk % 8000) | ||
268 | rates = arizona_sysclk_44k1_rates; | ||
269 | else | ||
270 | rates = arizona_sysclk_48k_rates; | ||
271 | |||
272 | for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) && | ||
273 | rates[ref] <= refclk; ref++) { | ||
274 | div = 1; | ||
275 | while (rates[ref] / div >= freq && div < 32) { | ||
276 | if (rates[ref] / div == freq) { | ||
277 | dev_dbg(codec->dev, "Configured %dHz OPCLK\n", | ||
278 | freq); | ||
279 | snd_soc_update_bits(codec, reg, | ||
280 | ARIZONA_OPCLK_DIV_MASK | | ||
281 | ARIZONA_OPCLK_SEL_MASK, | ||
282 | (div << | ||
283 | ARIZONA_OPCLK_DIV_SHIFT) | | ||
284 | ref); | ||
285 | return 0; | ||
286 | } | ||
287 | div++; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq); | ||
292 | return -EINVAL; | ||
293 | } | ||
294 | |||
232 | int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, | 295 | int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, |
233 | int source, unsigned int freq, int dir) | 296 | int source, unsigned int freq, int dir) |
234 | { | 297 | { |
@@ -252,6 +315,9 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, | |||
252 | reg = ARIZONA_ASYNC_CLOCK_1; | 315 | reg = ARIZONA_ASYNC_CLOCK_1; |
253 | clk = &priv->asyncclk; | 316 | clk = &priv->asyncclk; |
254 | break; | 317 | break; |
318 | case ARIZONA_CLK_OPCLK: | ||
319 | case ARIZONA_CLK_ASYNC_OPCLK: | ||
320 | return arizona_set_opclk(codec, clk_id, freq); | ||
255 | default: | 321 | default: |
256 | return -EINVAL; | 322 | return -EINVAL; |
257 | } | 323 | } |
@@ -426,7 +492,7 @@ static const int arizona_44k1_bclk_rates[] = { | |||
426 | 940800, | 492 | 940800, |
427 | 1411200, | 493 | 1411200, |
428 | 1881600, | 494 | 1881600, |
429 | 2882400, | 495 | 2822400, |
430 | 3763200, | 496 | 3763200, |
431 | 5644800, | 497 | 5644800, |
432 | 7526400, | 498 | 7526400, |
@@ -666,7 +732,7 @@ static irqreturn_t arizona_fll_lock(int irq, void *data) | |||
666 | { | 732 | { |
667 | struct arizona_fll *fll = data; | 733 | struct arizona_fll *fll = data; |
668 | 734 | ||
669 | arizona_fll_dbg(fll, "Locked\n"); | 735 | arizona_fll_dbg(fll, "Lock status changed\n"); |
670 | 736 | ||
671 | complete(&fll->lock); | 737 | complete(&fll->lock); |
672 | 738 | ||
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 59caca8865e8..eb66b52777c9 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h | |||
@@ -17,8 +17,10 @@ | |||
17 | 17 | ||
18 | #include <sound/soc.h> | 18 | #include <sound/soc.h> |
19 | 19 | ||
20 | #define ARIZONA_CLK_SYSCLK 1 | 20 | #define ARIZONA_CLK_SYSCLK 1 |
21 | #define ARIZONA_CLK_ASYNCCLK 2 | 21 | #define ARIZONA_CLK_ASYNCCLK 2 |
22 | #define ARIZONA_CLK_OPCLK 3 | ||
23 | #define ARIZONA_CLK_ASYNC_OPCLK 4 | ||
22 | 24 | ||
23 | #define ARIZONA_CLK_SRC_MCLK1 0x0 | 25 | #define ARIZONA_CLK_SRC_MCLK1 0x0 |
24 | #define ARIZONA_CLK_SRC_MCLK2 0x1 | 26 | #define ARIZONA_CLK_SRC_MCLK2 0x1 |
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 047917f0b8ae..815b53bc2d27 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/regulator/consumer.h> | 31 | #include <linux/regulator/consumer.h> |
32 | #include <linux/of_device.h> | ||
33 | #include <linux/of_gpio.h> | ||
32 | 34 | ||
33 | /* | 35 | /* |
34 | * The codec isn't really big-endian or little-endian, since the I2S | 36 | * The codec isn't really big-endian or little-endian, since the I2S |
@@ -110,14 +112,15 @@ | |||
110 | * This array contains the power-on default values of the registers, with the | 112 | * This array contains the power-on default values of the registers, with the |
111 | * exception of the "CHIPID" register (01h). The lower four bits of that | 113 | * exception of the "CHIPID" register (01h). The lower four bits of that |
112 | * register contain the hardware revision, so it is treated as volatile. | 114 | * register contain the hardware revision, so it is treated as volatile. |
113 | * | ||
114 | * Also note that on the CS4270, the first readable register is 1, but ASoC | ||
115 | * assumes the first register is 0. Therfore, the array must have an entry for | ||
116 | * register 0, but we use cs4270_reg_is_readable() to tell ASoC that it can't | ||
117 | * be read. | ||
118 | */ | 115 | */ |
119 | static const u8 cs4270_default_reg_cache[CS4270_LASTREG + 1] = { | 116 | static const struct reg_default cs4270_reg_defaults[] = { |
120 | 0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x20, 0x00, 0x00 | 117 | { 2, 0x00 }, |
118 | { 3, 0x30 }, | ||
119 | { 4, 0x00 }, | ||
120 | { 5, 0x60 }, | ||
121 | { 6, 0x20 }, | ||
122 | { 7, 0x00 }, | ||
123 | { 8, 0x00 }, | ||
121 | }; | 124 | }; |
122 | 125 | ||
123 | static const char *supply_names[] = { | 126 | static const char *supply_names[] = { |
@@ -126,7 +129,7 @@ static const char *supply_names[] = { | |||
126 | 129 | ||
127 | /* Private data for the CS4270 */ | 130 | /* Private data for the CS4270 */ |
128 | struct cs4270_private { | 131 | struct cs4270_private { |
129 | enum snd_soc_control_type control_type; | 132 | struct regmap *regmap; |
130 | unsigned int mclk; /* Input frequency of the MCLK pin */ | 133 | unsigned int mclk; /* Input frequency of the MCLK pin */ |
131 | unsigned int mode; /* The mode (I2S or left-justified) */ | 134 | unsigned int mode; /* The mode (I2S or left-justified) */ |
132 | unsigned int slave_mode; | 135 | unsigned int slave_mode; |
@@ -191,12 +194,12 @@ static struct cs4270_mode_ratios cs4270_mode_ratios[] = { | |||
191 | /* The number of MCLK/LRCK ratios supported by the CS4270 */ | 194 | /* The number of MCLK/LRCK ratios supported by the CS4270 */ |
192 | #define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios) | 195 | #define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios) |
193 | 196 | ||
194 | static int cs4270_reg_is_readable(struct snd_soc_codec *codec, unsigned int reg) | 197 | static bool cs4270_reg_is_readable(struct device *dev, unsigned int reg) |
195 | { | 198 | { |
196 | return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG); | 199 | return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG); |
197 | } | 200 | } |
198 | 201 | ||
199 | static int cs4270_reg_is_volatile(struct snd_soc_codec *codec, unsigned int reg) | 202 | static bool cs4270_reg_is_volatile(struct device *dev, unsigned int reg) |
200 | { | 203 | { |
201 | /* Unreadable registers are considered volatile */ | 204 | /* Unreadable registers are considered volatile */ |
202 | if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG)) | 205 | if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG)) |
@@ -485,12 +488,12 @@ static struct snd_soc_dai_driver cs4270_dai = { | |||
485 | static int cs4270_probe(struct snd_soc_codec *codec) | 488 | static int cs4270_probe(struct snd_soc_codec *codec) |
486 | { | 489 | { |
487 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | 490 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); |
488 | int i, ret; | 491 | int ret; |
489 | 492 | ||
490 | /* Tell ASoC what kind of I/O to use to read the registers. ASoC will | 493 | /* Tell ASoC what kind of I/O to use to read the registers. ASoC will |
491 | * then do the I2C transactions itself. | 494 | * then do the I2C transactions itself. |
492 | */ | 495 | */ |
493 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs4270->control_type); | 496 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); |
494 | if (ret < 0) { | 497 | if (ret < 0) { |
495 | dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret); | 498 | dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret); |
496 | return ret; | 499 | return ret; |
@@ -519,33 +522,8 @@ static int cs4270_probe(struct snd_soc_codec *codec) | |||
519 | return ret; | 522 | return ret; |
520 | } | 523 | } |
521 | 524 | ||
522 | /* Add the non-DAPM controls */ | ||
523 | ret = snd_soc_add_codec_controls(codec, cs4270_snd_controls, | ||
524 | ARRAY_SIZE(cs4270_snd_controls)); | ||
525 | if (ret < 0) { | ||
526 | dev_err(codec->dev, "failed to add controls\n"); | ||
527 | return ret; | ||
528 | } | ||
529 | |||
530 | /* get the power supply regulators */ | ||
531 | for (i = 0; i < ARRAY_SIZE(supply_names); i++) | ||
532 | cs4270->supplies[i].supply = supply_names[i]; | ||
533 | |||
534 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies), | ||
535 | cs4270->supplies); | ||
536 | if (ret < 0) | ||
537 | return ret; | ||
538 | |||
539 | ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), | 525 | ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), |
540 | cs4270->supplies); | 526 | cs4270->supplies); |
541 | if (ret < 0) | ||
542 | goto error_free_regulators; | ||
543 | |||
544 | return 0; | ||
545 | |||
546 | error_free_regulators: | ||
547 | regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), | ||
548 | cs4270->supplies); | ||
549 | 527 | ||
550 | return ret; | 528 | return ret; |
551 | } | 529 | } |
@@ -561,7 +539,6 @@ static int cs4270_remove(struct snd_soc_codec *codec) | |||
561 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | 539 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); |
562 | 540 | ||
563 | regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies); | 541 | regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies); |
564 | regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies); | ||
565 | 542 | ||
566 | return 0; | 543 | return 0; |
567 | }; | 544 | }; |
@@ -611,7 +588,7 @@ static int cs4270_soc_resume(struct snd_soc_codec *codec) | |||
611 | ndelay(500); | 588 | ndelay(500); |
612 | 589 | ||
613 | /* first restore the entire register cache ... */ | 590 | /* first restore the entire register cache ... */ |
614 | snd_soc_cache_sync(codec); | 591 | regcache_sync(cs4270->regmap); |
615 | 592 | ||
616 | /* ... then disable the power-down bits */ | 593 | /* ... then disable the power-down bits */ |
617 | reg = snd_soc_read(codec, CS4270_PWRCTL); | 594 | reg = snd_soc_read(codec, CS4270_PWRCTL); |
@@ -632,11 +609,30 @@ static const struct snd_soc_codec_driver soc_codec_device_cs4270 = { | |||
632 | .remove = cs4270_remove, | 609 | .remove = cs4270_remove, |
633 | .suspend = cs4270_soc_suspend, | 610 | .suspend = cs4270_soc_suspend, |
634 | .resume = cs4270_soc_resume, | 611 | .resume = cs4270_soc_resume, |
635 | .volatile_register = cs4270_reg_is_volatile, | 612 | |
636 | .readable_register = cs4270_reg_is_readable, | 613 | .controls = cs4270_snd_controls, |
637 | .reg_cache_size = CS4270_LASTREG + 1, | 614 | .num_controls = ARRAY_SIZE(cs4270_snd_controls), |
638 | .reg_word_size = sizeof(u8), | 615 | }; |
639 | .reg_cache_default = cs4270_default_reg_cache, | 616 | |
617 | /* | ||
618 | * cs4270_of_match - the device tree bindings | ||
619 | */ | ||
620 | static const struct of_device_id cs4270_of_match[] = { | ||
621 | { .compatible = "cirrus,cs4270", }, | ||
622 | { } | ||
623 | }; | ||
624 | MODULE_DEVICE_TABLE(of, cs4270_of_match); | ||
625 | |||
626 | static const struct regmap_config cs4270_regmap = { | ||
627 | .reg_bits = 8, | ||
628 | .val_bits = 8, | ||
629 | .max_register = CS4270_LASTREG, | ||
630 | .reg_defaults = cs4270_reg_defaults, | ||
631 | .num_reg_defaults = ARRAY_SIZE(cs4270_reg_defaults), | ||
632 | .cache_type = REGCACHE_RBTREE, | ||
633 | |||
634 | .readable_reg = cs4270_reg_is_readable, | ||
635 | .volatile_reg = cs4270_reg_is_volatile, | ||
640 | }; | 636 | }; |
641 | 637 | ||
642 | /** | 638 | /** |
@@ -650,19 +646,56 @@ static const struct snd_soc_codec_driver soc_codec_device_cs4270 = { | |||
650 | static int cs4270_i2c_probe(struct i2c_client *i2c_client, | 646 | static int cs4270_i2c_probe(struct i2c_client *i2c_client, |
651 | const struct i2c_device_id *id) | 647 | const struct i2c_device_id *id) |
652 | { | 648 | { |
649 | struct device_node *np = i2c_client->dev.of_node; | ||
653 | struct cs4270_private *cs4270; | 650 | struct cs4270_private *cs4270; |
654 | int ret; | 651 | unsigned int val; |
652 | int ret, i; | ||
655 | 653 | ||
656 | /* Verify that we have a CS4270 */ | 654 | cs4270 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs4270_private), |
655 | GFP_KERNEL); | ||
656 | if (!cs4270) { | ||
657 | dev_err(&i2c_client->dev, "could not allocate codec\n"); | ||
658 | return -ENOMEM; | ||
659 | } | ||
660 | |||
661 | /* get the power supply regulators */ | ||
662 | for (i = 0; i < ARRAY_SIZE(supply_names); i++) | ||
663 | cs4270->supplies[i].supply = supply_names[i]; | ||
664 | |||
665 | ret = devm_regulator_bulk_get(&i2c_client->dev, | ||
666 | ARRAY_SIZE(cs4270->supplies), | ||
667 | cs4270->supplies); | ||
668 | if (ret < 0) | ||
669 | return ret; | ||
670 | |||
671 | /* See if we have a way to bring the codec out of reset */ | ||
672 | if (np) { | ||
673 | enum of_gpio_flags flags; | ||
674 | int gpio = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags); | ||
675 | |||
676 | if (gpio_is_valid(gpio)) { | ||
677 | ret = devm_gpio_request_one(&i2c_client->dev, gpio, | ||
678 | flags & OF_GPIO_ACTIVE_LOW ? | ||
679 | GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH, | ||
680 | "cs4270 reset"); | ||
681 | if (ret < 0) | ||
682 | return ret; | ||
683 | } | ||
684 | } | ||
685 | |||
686 | cs4270->regmap = devm_regmap_init_i2c(i2c_client, &cs4270_regmap); | ||
687 | if (IS_ERR(cs4270->regmap)) | ||
688 | return PTR_ERR(cs4270->regmap); | ||
657 | 689 | ||
658 | ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); | 690 | /* Verify that we have a CS4270 */ |
691 | ret = regmap_read(cs4270->regmap, CS4270_CHIPID, &val); | ||
659 | if (ret < 0) { | 692 | if (ret < 0) { |
660 | dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n", | 693 | dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n", |
661 | i2c_client->addr); | 694 | i2c_client->addr); |
662 | return ret; | 695 | return ret; |
663 | } | 696 | } |
664 | /* The top four bits of the chip ID should be 1100. */ | 697 | /* The top four bits of the chip ID should be 1100. */ |
665 | if ((ret & 0xF0) != 0xC0) { | 698 | if ((val & 0xF0) != 0xC0) { |
666 | dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n", | 699 | dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n", |
667 | i2c_client->addr); | 700 | i2c_client->addr); |
668 | return -ENODEV; | 701 | return -ENODEV; |
@@ -670,17 +703,9 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client, | |||
670 | 703 | ||
671 | dev_info(&i2c_client->dev, "found device at i2c address %X\n", | 704 | dev_info(&i2c_client->dev, "found device at i2c address %X\n", |
672 | i2c_client->addr); | 705 | i2c_client->addr); |
673 | dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF); | 706 | dev_info(&i2c_client->dev, "hardware revision %X\n", val & 0xF); |
674 | |||
675 | cs4270 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs4270_private), | ||
676 | GFP_KERNEL); | ||
677 | if (!cs4270) { | ||
678 | dev_err(&i2c_client->dev, "could not allocate codec\n"); | ||
679 | return -ENOMEM; | ||
680 | } | ||
681 | 707 | ||
682 | i2c_set_clientdata(i2c_client, cs4270); | 708 | i2c_set_clientdata(i2c_client, cs4270); |
683 | cs4270->control_type = SND_SOC_I2C; | ||
684 | 709 | ||
685 | ret = snd_soc_register_codec(&i2c_client->dev, | 710 | ret = snd_soc_register_codec(&i2c_client->dev, |
686 | &soc_codec_device_cs4270, &cs4270_dai, 1); | 711 | &soc_codec_device_cs4270, &cs4270_dai, 1); |
@@ -718,23 +743,14 @@ static struct i2c_driver cs4270_i2c_driver = { | |||
718 | .driver = { | 743 | .driver = { |
719 | .name = "cs4270", | 744 | .name = "cs4270", |
720 | .owner = THIS_MODULE, | 745 | .owner = THIS_MODULE, |
746 | .of_match_table = cs4270_of_match, | ||
721 | }, | 747 | }, |
722 | .id_table = cs4270_id, | 748 | .id_table = cs4270_id, |
723 | .probe = cs4270_i2c_probe, | 749 | .probe = cs4270_i2c_probe, |
724 | .remove = cs4270_i2c_remove, | 750 | .remove = cs4270_i2c_remove, |
725 | }; | 751 | }; |
726 | 752 | ||
727 | static int __init cs4270_init(void) | 753 | module_i2c_driver(cs4270_i2c_driver); |
728 | { | ||
729 | return i2c_add_driver(&cs4270_i2c_driver); | ||
730 | } | ||
731 | module_init(cs4270_init); | ||
732 | |||
733 | static void __exit cs4270_exit(void) | ||
734 | { | ||
735 | i2c_del_driver(&cs4270_i2c_driver); | ||
736 | } | ||
737 | module_exit(cs4270_exit); | ||
738 | 754 | ||
739 | MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); | 755 | MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); |
740 | MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver"); | 756 | MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver"); |
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 091d0193f507..1e0fa3b5f79a 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c | |||
@@ -614,24 +614,7 @@ static struct i2c_driver cs42l51_i2c_driver = { | |||
614 | .remove = cs42l51_i2c_remove, | 614 | .remove = cs42l51_i2c_remove, |
615 | }; | 615 | }; |
616 | 616 | ||
617 | static int __init cs42l51_init(void) | 617 | module_i2c_driver(cs42l51_i2c_driver); |
618 | { | ||
619 | int ret; | ||
620 | |||
621 | ret = i2c_add_driver(&cs42l51_i2c_driver); | ||
622 | if (ret != 0) { | ||
623 | printk(KERN_ERR "%s: can't add i2c driver\n", __func__); | ||
624 | return ret; | ||
625 | } | ||
626 | return 0; | ||
627 | } | ||
628 | module_init(cs42l51_init); | ||
629 | |||
630 | static void __exit cs42l51_exit(void) | ||
631 | { | ||
632 | i2c_del_driver(&cs42l51_i2c_driver); | ||
633 | } | ||
634 | module_exit(cs42l51_exit); | ||
635 | 618 | ||
636 | MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); | 619 | MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); |
637 | MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver"); | 620 | MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver"); |
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 628daf6a1d97..61599298fb26 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/slab.h> | ||
28 | #include <sound/core.h> | 27 | #include <sound/core.h> |
29 | #include <sound/pcm.h> | 28 | #include <sound/pcm.h> |
30 | #include <sound/pcm_params.h> | 29 | #include <sound/pcm_params.h> |
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index 5d8f39e32978..1bf55602c9eb 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c | |||
@@ -13,7 +13,6 @@ | |||
13 | */ | 13 | */ |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/moduleparam.h> | 15 | #include <linux/moduleparam.h> |
16 | #include <linux/version.h> | ||
17 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
19 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c index ba4fafb93e56..81a328c78838 100644 --- a/sound/soc/codecs/lm4857.c +++ b/sound/soc/codecs/lm4857.c | |||
@@ -250,17 +250,7 @@ static struct i2c_driver lm4857_i2c_driver = { | |||
250 | .id_table = lm4857_i2c_id, | 250 | .id_table = lm4857_i2c_id, |
251 | }; | 251 | }; |
252 | 252 | ||
253 | static int __init lm4857_init(void) | 253 | module_i2c_driver(lm4857_i2c_driver); |
254 | { | ||
255 | return i2c_add_driver(&lm4857_i2c_driver); | ||
256 | } | ||
257 | module_init(lm4857_init); | ||
258 | |||
259 | static void __exit lm4857_exit(void) | ||
260 | { | ||
261 | i2c_del_driver(&lm4857_i2c_driver); | ||
262 | } | ||
263 | module_exit(lm4857_exit); | ||
264 | 254 | ||
265 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | 255 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); |
266 | MODULE_DESCRIPTION("LM4857 amplifier driver"); | 256 | MODULE_DESCRIPTION("LM4857 amplifier driver"); |
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index af7324b79dd0..3264a5169306 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c | |||
@@ -2107,23 +2107,7 @@ static struct i2c_driver max98088_i2c_driver = { | |||
2107 | .id_table = max98088_i2c_id, | 2107 | .id_table = max98088_i2c_id, |
2108 | }; | 2108 | }; |
2109 | 2109 | ||
2110 | static int __init max98088_init(void) | 2110 | module_i2c_driver(max98088_i2c_driver); |
2111 | { | ||
2112 | int ret; | ||
2113 | |||
2114 | ret = i2c_add_driver(&max98088_i2c_driver); | ||
2115 | if (ret) | ||
2116 | pr_err("Failed to register max98088 I2C driver: %d\n", ret); | ||
2117 | |||
2118 | return ret; | ||
2119 | } | ||
2120 | module_init(max98088_init); | ||
2121 | |||
2122 | static void __exit max98088_exit(void) | ||
2123 | { | ||
2124 | i2c_del_driver(&max98088_i2c_driver); | ||
2125 | } | ||
2126 | module_exit(max98088_exit); | ||
2127 | 2111 | ||
2128 | MODULE_DESCRIPTION("ALSA SoC MAX98088 driver"); | 2112 | MODULE_DESCRIPTION("ALSA SoC MAX98088 driver"); |
2129 | MODULE_AUTHOR("Peter Hsiang, Jesse Marroquin"); | 2113 | MODULE_AUTHOR("Peter Hsiang, Jesse Marroquin"); |
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 7cd508e16a5c..38d43c59d3f4 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c | |||
@@ -2533,23 +2533,7 @@ static struct i2c_driver max98095_i2c_driver = { | |||
2533 | .id_table = max98095_i2c_id, | 2533 | .id_table = max98095_i2c_id, |
2534 | }; | 2534 | }; |
2535 | 2535 | ||
2536 | static int __init max98095_init(void) | 2536 | module_i2c_driver(max98095_i2c_driver); |
2537 | { | ||
2538 | int ret; | ||
2539 | |||
2540 | ret = i2c_add_driver(&max98095_i2c_driver); | ||
2541 | if (ret) | ||
2542 | pr_err("Failed to register max98095 I2C driver: %d\n", ret); | ||
2543 | |||
2544 | return ret; | ||
2545 | } | ||
2546 | module_init(max98095_init); | ||
2547 | |||
2548 | static void __exit max98095_exit(void) | ||
2549 | { | ||
2550 | i2c_del_driver(&max98095_i2c_driver); | ||
2551 | } | ||
2552 | module_exit(max98095_exit); | ||
2553 | 2537 | ||
2554 | MODULE_DESCRIPTION("ALSA SoC MAX98095 driver"); | 2538 | MODULE_DESCRIPTION("ALSA SoC MAX98095 driver"); |
2555 | MODULE_AUTHOR("Peter Hsiang"); | 2539 | MODULE_AUTHOR("Peter Hsiang"); |
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c index a1913091f56c..efe535c37b39 100644 --- a/sound/soc/codecs/max9850.c +++ b/sound/soc/codecs/max9850.c | |||
@@ -369,17 +369,7 @@ static struct i2c_driver max9850_i2c_driver = { | |||
369 | .id_table = max9850_i2c_id, | 369 | .id_table = max9850_i2c_id, |
370 | }; | 370 | }; |
371 | 371 | ||
372 | static int __init max9850_init(void) | 372 | module_i2c_driver(max9850_i2c_driver); |
373 | { | ||
374 | return i2c_add_driver(&max9850_i2c_driver); | ||
375 | } | ||
376 | module_init(max9850_init); | ||
377 | |||
378 | static void __exit max9850_exit(void) | ||
379 | { | ||
380 | i2c_del_driver(&max9850_i2c_driver); | ||
381 | } | ||
382 | module_exit(max9850_exit); | ||
383 | 373 | ||
384 | MODULE_AUTHOR("Christian Glindkamp <christian.glindkamp@taskit.de>"); | 374 | MODULE_AUTHOR("Christian Glindkamp <christian.glindkamp@taskit.de>"); |
385 | MODULE_DESCRIPTION("ASoC MAX9850 codec driver"); | 375 | MODULE_DESCRIPTION("ASoC MAX9850 codec driver"); |
diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c index 3a2ba3d8fd6d..d15e5943c85e 100644 --- a/sound/soc/codecs/max9877.c +++ b/sound/soc/codecs/max9877.c | |||
@@ -291,17 +291,7 @@ static struct i2c_driver max9877_i2c_driver = { | |||
291 | .id_table = max9877_i2c_id, | 291 | .id_table = max9877_i2c_id, |
292 | }; | 292 | }; |
293 | 293 | ||
294 | static int __init max9877_init(void) | 294 | module_i2c_driver(max9877_i2c_driver); |
295 | { | ||
296 | return i2c_add_driver(&max9877_i2c_driver); | ||
297 | } | ||
298 | module_init(max9877_init); | ||
299 | |||
300 | static void __exit max9877_exit(void) | ||
301 | { | ||
302 | i2c_del_driver(&max9877_i2c_driver); | ||
303 | } | ||
304 | module_exit(max9877_exit); | ||
305 | 295 | ||
306 | MODULE_DESCRIPTION("ASoC MAX9877 amp driver"); | 296 | MODULE_DESCRIPTION("ASoC MAX9877 amp driver"); |
307 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | 297 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); |
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 8f726c063f42..bc955999c8aa 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c | |||
@@ -426,16 +426,16 @@ static int mc13783_set_tdm_slot_sync(struct snd_soc_dai *dai, | |||
426 | } | 426 | } |
427 | 427 | ||
428 | static const struct snd_kcontrol_new mc1l_amp_ctl = | 428 | static const struct snd_kcontrol_new mc1l_amp_ctl = |
429 | SOC_DAPM_SINGLE("Switch", 38, 7, 1, 0); | 429 | SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_TX, 7, 1, 0); |
430 | 430 | ||
431 | static const struct snd_kcontrol_new mc1r_amp_ctl = | 431 | static const struct snd_kcontrol_new mc1r_amp_ctl = |
432 | SOC_DAPM_SINGLE("Switch", 38, 5, 1, 0); | 432 | SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_TX, 5, 1, 0); |
433 | 433 | ||
434 | static const struct snd_kcontrol_new mc2_amp_ctl = | 434 | static const struct snd_kcontrol_new mc2_amp_ctl = |
435 | SOC_DAPM_SINGLE("Switch", 38, 9, 1, 0); | 435 | SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_TX, 9, 1, 0); |
436 | 436 | ||
437 | static const struct snd_kcontrol_new atx_amp_ctl = | 437 | static const struct snd_kcontrol_new atx_amp_ctl = |
438 | SOC_DAPM_SINGLE("Switch", 38, 11, 1, 0); | 438 | SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_TX, 11, 1, 0); |
439 | 439 | ||
440 | 440 | ||
441 | /* Virtual mux. The chip does the input selection automatically | 441 | /* Virtual mux. The chip does the input selection automatically |
@@ -461,22 +461,22 @@ static const struct snd_kcontrol_new right_input_mux = | |||
461 | SOC_DAPM_ENUM_VIRT("Route", adcr_enum); | 461 | SOC_DAPM_ENUM_VIRT("Route", adcr_enum); |
462 | 462 | ||
463 | static const struct snd_kcontrol_new samp_ctl = | 463 | static const struct snd_kcontrol_new samp_ctl = |
464 | SOC_DAPM_SINGLE("Switch", 36, 3, 1, 0); | 464 | SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 3, 1, 0); |
465 | 465 | ||
466 | static const struct snd_kcontrol_new lamp_ctl = | 466 | static const struct snd_kcontrol_new lamp_ctl = |
467 | SOC_DAPM_SINGLE("Switch", 36, 5, 1, 0); | 467 | SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 5, 1, 0); |
468 | 468 | ||
469 | static const struct snd_kcontrol_new hlamp_ctl = | 469 | static const struct snd_kcontrol_new hlamp_ctl = |
470 | SOC_DAPM_SINGLE("Switch", 36, 10, 1, 0); | 470 | SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 10, 1, 0); |
471 | 471 | ||
472 | static const struct snd_kcontrol_new hramp_ctl = | 472 | static const struct snd_kcontrol_new hramp_ctl = |
473 | SOC_DAPM_SINGLE("Switch", 36, 9, 1, 0); | 473 | SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 9, 1, 0); |
474 | 474 | ||
475 | static const struct snd_kcontrol_new llamp_ctl = | 475 | static const struct snd_kcontrol_new llamp_ctl = |
476 | SOC_DAPM_SINGLE("Switch", 36, 16, 1, 0); | 476 | SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 16, 1, 0); |
477 | 477 | ||
478 | static const struct snd_kcontrol_new lramp_ctl = | 478 | static const struct snd_kcontrol_new lramp_ctl = |
479 | SOC_DAPM_SINGLE("Switch", 36, 15, 1, 0); | 479 | SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 15, 1, 0); |
480 | 480 | ||
481 | static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = { | 481 | static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = { |
482 | /* Input */ | 482 | /* Input */ |
@@ -487,13 +487,13 @@ static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = { | |||
487 | SND_SOC_DAPM_INPUT("RXINL"), | 487 | SND_SOC_DAPM_INPUT("RXINL"), |
488 | SND_SOC_DAPM_INPUT("TXIN"), | 488 | SND_SOC_DAPM_INPUT("TXIN"), |
489 | 489 | ||
490 | SND_SOC_DAPM_SUPPLY("MC1 Bias", 38, 0, 0, NULL, 0), | 490 | SND_SOC_DAPM_SUPPLY("MC1 Bias", MC13783_AUDIO_TX, 0, 0, NULL, 0), |
491 | SND_SOC_DAPM_SUPPLY("MC2 Bias", 38, 1, 0, NULL, 0), | 491 | SND_SOC_DAPM_SUPPLY("MC2 Bias", MC13783_AUDIO_TX, 1, 0, NULL, 0), |
492 | 492 | ||
493 | SND_SOC_DAPM_SWITCH("MC1L Amp", 38, 7, 0, &mc1l_amp_ctl), | 493 | SND_SOC_DAPM_SWITCH("MC1L Amp", MC13783_AUDIO_TX, 7, 0, &mc1l_amp_ctl), |
494 | SND_SOC_DAPM_SWITCH("MC1R Amp", 38, 5, 0, &mc1r_amp_ctl), | 494 | SND_SOC_DAPM_SWITCH("MC1R Amp", MC13783_AUDIO_TX, 5, 0, &mc1r_amp_ctl), |
495 | SND_SOC_DAPM_SWITCH("MC2 Amp", 38, 9, 0, &mc2_amp_ctl), | 495 | SND_SOC_DAPM_SWITCH("MC2 Amp", MC13783_AUDIO_TX, 9, 0, &mc2_amp_ctl), |
496 | SND_SOC_DAPM_SWITCH("TXIN Amp", 38, 11, 0, &atx_amp_ctl), | 496 | SND_SOC_DAPM_SWITCH("TXIN Amp", MC13783_AUDIO_TX, 11, 0, &atx_amp_ctl), |
497 | 497 | ||
498 | SND_SOC_DAPM_VIRT_MUX("PGA Left Input Mux", SND_SOC_NOPM, 0, 0, | 498 | SND_SOC_DAPM_VIRT_MUX("PGA Left Input Mux", SND_SOC_NOPM, 0, 0, |
499 | &left_input_mux), | 499 | &left_input_mux), |
@@ -503,12 +503,12 @@ static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = { | |||
503 | SND_SOC_DAPM_PGA("PGA Left Input", SND_SOC_NOPM, 0, 0, NULL, 0), | 503 | SND_SOC_DAPM_PGA("PGA Left Input", SND_SOC_NOPM, 0, 0, NULL, 0), |
504 | SND_SOC_DAPM_PGA("PGA Right Input", SND_SOC_NOPM, 0, 0, NULL, 0), | 504 | SND_SOC_DAPM_PGA("PGA Right Input", SND_SOC_NOPM, 0, 0, NULL, 0), |
505 | 505 | ||
506 | SND_SOC_DAPM_ADC("ADC", "Capture", 40, 11, 0), | 506 | SND_SOC_DAPM_ADC("ADC", "Capture", MC13783_AUDIO_CODEC, 11, 0), |
507 | SND_SOC_DAPM_SUPPLY("ADC_Reset", 40, 15, 0, NULL, 0), | 507 | SND_SOC_DAPM_SUPPLY("ADC_Reset", MC13783_AUDIO_CODEC, 15, 0, NULL, 0), |
508 | 508 | ||
509 | /* Output */ | 509 | /* Output */ |
510 | SND_SOC_DAPM_SUPPLY("DAC_E", 41, 11, 0, NULL, 0), | 510 | SND_SOC_DAPM_SUPPLY("DAC_E", MC13783_AUDIO_DAC, 11, 0, NULL, 0), |
511 | SND_SOC_DAPM_SUPPLY("DAC_Reset", 41, 15, 0, NULL, 0), | 511 | SND_SOC_DAPM_SUPPLY("DAC_Reset", MC13783_AUDIO_DAC, 15, 0, NULL, 0), |
512 | SND_SOC_DAPM_OUTPUT("RXOUTL"), | 512 | SND_SOC_DAPM_OUTPUT("RXOUTL"), |
513 | SND_SOC_DAPM_OUTPUT("RXOUTR"), | 513 | SND_SOC_DAPM_OUTPUT("RXOUTR"), |
514 | SND_SOC_DAPM_OUTPUT("HSL"), | 514 | SND_SOC_DAPM_OUTPUT("HSL"), |
@@ -516,14 +516,18 @@ static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = { | |||
516 | SND_SOC_DAPM_OUTPUT("LSP"), | 516 | SND_SOC_DAPM_OUTPUT("LSP"), |
517 | SND_SOC_DAPM_OUTPUT("SP"), | 517 | SND_SOC_DAPM_OUTPUT("SP"), |
518 | 518 | ||
519 | SND_SOC_DAPM_SWITCH("Speaker Amp", 36, 3, 0, &samp_ctl), | 519 | SND_SOC_DAPM_SWITCH("Speaker Amp", MC13783_AUDIO_RX0, 3, 0, &samp_ctl), |
520 | SND_SOC_DAPM_SWITCH("Loudspeaker Amp", SND_SOC_NOPM, 0, 0, &lamp_ctl), | 520 | SND_SOC_DAPM_SWITCH("Loudspeaker Amp", SND_SOC_NOPM, 0, 0, &lamp_ctl), |
521 | SND_SOC_DAPM_SWITCH("Headset Amp Left", 36, 10, 0, &hlamp_ctl), | 521 | SND_SOC_DAPM_SWITCH("Headset Amp Left", MC13783_AUDIO_RX0, 10, 0, |
522 | SND_SOC_DAPM_SWITCH("Headset Amp Right", 36, 9, 0, &hramp_ctl), | 522 | &hlamp_ctl), |
523 | SND_SOC_DAPM_SWITCH("Line out Amp Left", 36, 16, 0, &llamp_ctl), | 523 | SND_SOC_DAPM_SWITCH("Headset Amp Right", MC13783_AUDIO_RX0, 9, 0, |
524 | SND_SOC_DAPM_SWITCH("Line out Amp Right", 36, 15, 0, &lramp_ctl), | 524 | &hramp_ctl), |
525 | SND_SOC_DAPM_DAC("DAC", "Playback", 36, 22, 0), | 525 | SND_SOC_DAPM_SWITCH("Line out Amp Left", MC13783_AUDIO_RX0, 16, 0, |
526 | SND_SOC_DAPM_PGA("DAC PGA", 37, 5, 0, NULL, 0), | 526 | &llamp_ctl), |
527 | SND_SOC_DAPM_SWITCH("Line out Amp Right", MC13783_AUDIO_RX0, 15, 0, | ||
528 | &lramp_ctl), | ||
529 | SND_SOC_DAPM_DAC("DAC", "Playback", MC13783_AUDIO_RX0, 22, 0), | ||
530 | SND_SOC_DAPM_PGA("DAC PGA", MC13783_AUDIO_RX1, 5, 0, NULL, 0), | ||
527 | }; | 531 | }; |
528 | 532 | ||
529 | static struct snd_soc_dapm_route mc13783_routes[] = { | 533 | static struct snd_soc_dapm_route mc13783_routes[] = { |
@@ -581,8 +585,6 @@ static int mc13783_probe(struct snd_soc_codec *codec) | |||
581 | { | 585 | { |
582 | struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); | 586 | struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); |
583 | 587 | ||
584 | codec->control_data = priv->mc13xxx; | ||
585 | |||
586 | mc13xxx_lock(priv->mc13xxx); | 588 | mc13xxx_lock(priv->mc13xxx); |
587 | 589 | ||
588 | /* these are the reset values */ | 590 | /* these are the reset values */ |
@@ -659,7 +661,7 @@ static struct snd_soc_dai_driver mc13783_dai_async[] = { | |||
659 | .id = MC13783_ID_STEREO_DAC, | 661 | .id = MC13783_ID_STEREO_DAC, |
660 | .playback = { | 662 | .playback = { |
661 | .stream_name = "Playback", | 663 | .stream_name = "Playback", |
662 | .channels_min = 1, | 664 | .channels_min = 2, |
663 | .channels_max = 2, | 665 | .channels_max = 2, |
664 | .rates = SNDRV_PCM_RATE_8000_96000, | 666 | .rates = SNDRV_PCM_RATE_8000_96000, |
665 | .formats = MC13783_FORMATS, | 667 | .formats = MC13783_FORMATS, |
@@ -670,7 +672,7 @@ static struct snd_soc_dai_driver mc13783_dai_async[] = { | |||
670 | .id = MC13783_ID_STEREO_CODEC, | 672 | .id = MC13783_ID_STEREO_CODEC, |
671 | .capture = { | 673 | .capture = { |
672 | .stream_name = "Capture", | 674 | .stream_name = "Capture", |
673 | .channels_min = 1, | 675 | .channels_min = 2, |
674 | .channels_max = 2, | 676 | .channels_max = 2, |
675 | .rates = MC13783_RATES_RECORD, | 677 | .rates = MC13783_RATES_RECORD, |
676 | .formats = MC13783_FORMATS, | 678 | .formats = MC13783_FORMATS, |
@@ -692,14 +694,14 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = { | |||
692 | .id = MC13783_ID_SYNC, | 694 | .id = MC13783_ID_SYNC, |
693 | .playback = { | 695 | .playback = { |
694 | .stream_name = "Playback", | 696 | .stream_name = "Playback", |
695 | .channels_min = 1, | 697 | .channels_min = 2, |
696 | .channels_max = 2, | 698 | .channels_max = 2, |
697 | .rates = SNDRV_PCM_RATE_8000_96000, | 699 | .rates = SNDRV_PCM_RATE_8000_96000, |
698 | .formats = MC13783_FORMATS, | 700 | .formats = MC13783_FORMATS, |
699 | }, | 701 | }, |
700 | .capture = { | 702 | .capture = { |
701 | .stream_name = "Capture", | 703 | .stream_name = "Capture", |
702 | .channels_min = 1, | 704 | .channels_min = 2, |
703 | .channels_max = 2, | 705 | .channels_max = 2, |
704 | .rates = MC13783_RATES_RECORD, | 706 | .rates = MC13783_RATES_RECORD, |
705 | .formats = MC13783_FORMATS, | 707 | .formats = MC13783_FORMATS, |
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 8d717f4b5a87..0935bfe62471 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/pm.h> | 25 | #include <linux/pm.h> |
26 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
27 | #include <linux/regmap.h> | ||
27 | #include <linux/regulator/consumer.h> | 28 | #include <linux/regulator/consumer.h> |
28 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
29 | #include <linux/workqueue.h> | 30 | #include <linux/workqueue.h> |
@@ -55,12 +56,50 @@ | |||
55 | SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) | 56 | SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) |
56 | 57 | ||
57 | /* Power-up register defaults */ | 58 | /* Power-up register defaults */ |
58 | static const u8 sta32x_regs[STA32X_REGISTER_COUNT] = { | 59 | static const struct reg_default sta32x_regs[] = { |
59 | 0x63, 0x80, 0xc2, 0x40, 0xc2, 0x5c, 0x10, 0xff, 0x60, 0x60, | 60 | { 0x0, 0x63 }, |
60 | 0x60, 0x80, 0x00, 0x00, 0x00, 0x40, 0x80, 0x77, 0x6a, 0x69, | 61 | { 0x1, 0x80 }, |
61 | 0x6a, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 62 | { 0x2, 0xc2 }, |
62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, | 63 | { 0x3, 0x40 }, |
63 | 0xc0, 0xf3, 0x33, 0x00, 0x0c, | 64 | { 0x4, 0xc2 }, |
65 | { 0x5, 0x5c }, | ||
66 | { 0x6, 0x10 }, | ||
67 | { 0x7, 0xff }, | ||
68 | { 0x8, 0x60 }, | ||
69 | { 0x9, 0x60 }, | ||
70 | { 0xa, 0x60 }, | ||
71 | { 0xb, 0x80 }, | ||
72 | { 0xc, 0x00 }, | ||
73 | { 0xd, 0x00 }, | ||
74 | { 0xe, 0x00 }, | ||
75 | { 0xf, 0x40 }, | ||
76 | { 0x10, 0x80 }, | ||
77 | { 0x11, 0x77 }, | ||
78 | { 0x12, 0x6a }, | ||
79 | { 0x13, 0x69 }, | ||
80 | { 0x14, 0x6a }, | ||
81 | { 0x15, 0x69 }, | ||
82 | { 0x16, 0x00 }, | ||
83 | { 0x17, 0x00 }, | ||
84 | { 0x18, 0x00 }, | ||
85 | { 0x19, 0x00 }, | ||
86 | { 0x1a, 0x00 }, | ||
87 | { 0x1b, 0x00 }, | ||
88 | { 0x1c, 0x00 }, | ||
89 | { 0x1d, 0x00 }, | ||
90 | { 0x1e, 0x00 }, | ||
91 | { 0x1f, 0x00 }, | ||
92 | { 0x20, 0x00 }, | ||
93 | { 0x21, 0x00 }, | ||
94 | { 0x22, 0x00 }, | ||
95 | { 0x23, 0x00 }, | ||
96 | { 0x24, 0x00 }, | ||
97 | { 0x25, 0x00 }, | ||
98 | { 0x26, 0x00 }, | ||
99 | { 0x27, 0x2d }, | ||
100 | { 0x28, 0xc0 }, | ||
101 | { 0x2b, 0x00 }, | ||
102 | { 0x2c, 0x0c }, | ||
64 | }; | 103 | }; |
65 | 104 | ||
66 | /* regulator power supply names */ | 105 | /* regulator power supply names */ |
@@ -72,6 +111,7 @@ static const char *sta32x_supply_names[] = { | |||
72 | 111 | ||
73 | /* codec private data */ | 112 | /* codec private data */ |
74 | struct sta32x_priv { | 113 | struct sta32x_priv { |
114 | struct regmap *regmap; | ||
75 | struct regulator_bulk_data supplies[ARRAY_SIZE(sta32x_supply_names)]; | 115 | struct regulator_bulk_data supplies[ARRAY_SIZE(sta32x_supply_names)]; |
76 | struct snd_soc_codec *codec; | 116 | struct snd_soc_codec *codec; |
77 | struct sta32x_platform_data *pdata; | 117 | struct sta32x_platform_data *pdata; |
@@ -291,17 +331,15 @@ static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec) | |||
291 | 331 | ||
292 | static int sta32x_cache_sync(struct snd_soc_codec *codec) | 332 | static int sta32x_cache_sync(struct snd_soc_codec *codec) |
293 | { | 333 | { |
334 | struct sta32x_priv *sta32x = codec->control_data; | ||
294 | unsigned int mute; | 335 | unsigned int mute; |
295 | int rc; | 336 | int rc; |
296 | 337 | ||
297 | if (!codec->cache_sync) | ||
298 | return 0; | ||
299 | |||
300 | /* mute during register sync */ | 338 | /* mute during register sync */ |
301 | mute = snd_soc_read(codec, STA32X_MMUTE); | 339 | mute = snd_soc_read(codec, STA32X_MMUTE); |
302 | snd_soc_write(codec, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE); | 340 | snd_soc_write(codec, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE); |
303 | sta32x_sync_coef_shadow(codec); | 341 | sta32x_sync_coef_shadow(codec); |
304 | rc = snd_soc_cache_sync(codec); | 342 | rc = regcache_sync(sta32x->regmap); |
305 | snd_soc_write(codec, STA32X_MMUTE, mute); | 343 | snd_soc_write(codec, STA32X_MMUTE, mute); |
306 | return rc; | 344 | return rc; |
307 | } | 345 | } |
@@ -316,11 +354,11 @@ static void sta32x_watchdog(struct work_struct *work) | |||
316 | 354 | ||
317 | /* check if sta32x has reset itself */ | 355 | /* check if sta32x has reset itself */ |
318 | confa_cached = snd_soc_read(codec, STA32X_CONFA); | 356 | confa_cached = snd_soc_read(codec, STA32X_CONFA); |
319 | codec->cache_bypass = 1; | 357 | regcache_cache_bypass(sta32x->regmap, true); |
320 | confa = snd_soc_read(codec, STA32X_CONFA); | 358 | confa = snd_soc_read(codec, STA32X_CONFA); |
321 | codec->cache_bypass = 0; | 359 | regcache_cache_bypass(sta32x->regmap, false); |
322 | if (confa != confa_cached) { | 360 | if (confa != confa_cached) { |
323 | codec->cache_sync = 1; | 361 | regcache_mark_dirty(sta32x->regmap); |
324 | sta32x_cache_sync(codec); | 362 | sta32x_cache_sync(codec); |
325 | } | 363 | } |
326 | 364 | ||
@@ -825,31 +863,21 @@ static int sta32x_probe(struct snd_soc_codec *codec) | |||
825 | sta32x->codec = codec; | 863 | sta32x->codec = codec; |
826 | sta32x->pdata = dev_get_platdata(codec->dev); | 864 | sta32x->pdata = dev_get_platdata(codec->dev); |
827 | 865 | ||
828 | /* regulators */ | ||
829 | for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++) | ||
830 | sta32x->supplies[i].supply = sta32x_supply_names[i]; | ||
831 | |||
832 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sta32x->supplies), | ||
833 | sta32x->supplies); | ||
834 | if (ret != 0) { | ||
835 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | ||
836 | goto err; | ||
837 | } | ||
838 | |||
839 | ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies), | 866 | ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies), |
840 | sta32x->supplies); | 867 | sta32x->supplies); |
841 | if (ret != 0) { | 868 | if (ret != 0) { |
842 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | 869 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); |
843 | goto err_get; | 870 | return ret; |
844 | } | 871 | } |
845 | 872 | ||
846 | /* Tell ASoC what kind of I/O to use to read the registers. ASoC will | 873 | /* Tell ASoC what kind of I/O to use to read the registers. ASoC will |
847 | * then do the I2C transactions itself. | 874 | * then do the I2C transactions itself. |
848 | */ | 875 | */ |
849 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); | 876 | codec->control_data = sta32x->regmap; |
877 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
850 | if (ret < 0) { | 878 | if (ret < 0) { |
851 | dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret); | 879 | dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret); |
852 | return ret; | 880 | goto err; |
853 | } | 881 | } |
854 | 882 | ||
855 | /* Chip documentation explicitly requires that the reset values | 883 | /* Chip documentation explicitly requires that the reset values |
@@ -858,13 +886,15 @@ static int sta32x_probe(struct snd_soc_codec *codec) | |||
858 | * so the write to the these registers are suppressed by the cache | 886 | * so the write to the these registers are suppressed by the cache |
859 | * restore code when it skips writes of default registers. | 887 | * restore code when it skips writes of default registers. |
860 | */ | 888 | */ |
861 | snd_soc_cache_write(codec, STA32X_CONFC, 0xc2); | 889 | regcache_cache_only(sta32x->regmap, true); |
862 | snd_soc_cache_write(codec, STA32X_CONFE, 0xc2); | 890 | snd_soc_write(codec, STA32X_CONFC, 0xc2); |
863 | snd_soc_cache_write(codec, STA32X_CONFF, 0x5c); | 891 | snd_soc_write(codec, STA32X_CONFE, 0xc2); |
864 | snd_soc_cache_write(codec, STA32X_MMUTE, 0x10); | 892 | snd_soc_write(codec, STA32X_CONFF, 0x5c); |
865 | snd_soc_cache_write(codec, STA32X_AUTO1, 0x60); | 893 | snd_soc_write(codec, STA32X_MMUTE, 0x10); |
866 | snd_soc_cache_write(codec, STA32X_AUTO3, 0x00); | 894 | snd_soc_write(codec, STA32X_AUTO1, 0x60); |
867 | snd_soc_cache_write(codec, STA32X_C3CFG, 0x40); | 895 | snd_soc_write(codec, STA32X_AUTO3, 0x00); |
896 | snd_soc_write(codec, STA32X_C3CFG, 0x40); | ||
897 | regcache_cache_only(sta32x->regmap, false); | ||
868 | 898 | ||
869 | /* set thermal warning adjustment and recovery */ | 899 | /* set thermal warning adjustment and recovery */ |
870 | if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_ADJUSTMENT_ENABLE)) | 900 | if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_ADJUSTMENT_ENABLE)) |
@@ -915,9 +945,8 @@ static int sta32x_probe(struct snd_soc_codec *codec) | |||
915 | 945 | ||
916 | return 0; | 946 | return 0; |
917 | 947 | ||
918 | err_get: | ||
919 | regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); | ||
920 | err: | 948 | err: |
949 | regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); | ||
921 | return ret; | 950 | return ret; |
922 | } | 951 | } |
923 | 952 | ||
@@ -928,13 +957,11 @@ static int sta32x_remove(struct snd_soc_codec *codec) | |||
928 | sta32x_watchdog_stop(sta32x); | 957 | sta32x_watchdog_stop(sta32x); |
929 | sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF); | 958 | sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF); |
930 | regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); | 959 | regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); |
931 | regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); | ||
932 | 960 | ||
933 | return 0; | 961 | return 0; |
934 | } | 962 | } |
935 | 963 | ||
936 | static int sta32x_reg_is_volatile(struct snd_soc_codec *codec, | 964 | static bool sta32x_reg_is_volatile(struct device *dev, unsigned int reg) |
937 | unsigned int reg) | ||
938 | { | 965 | { |
939 | switch (reg) { | 966 | switch (reg) { |
940 | case STA32X_CONFA ... STA32X_L2ATRT: | 967 | case STA32X_CONFA ... STA32X_L2ATRT: |
@@ -949,10 +976,6 @@ static const struct snd_soc_codec_driver sta32x_codec = { | |||
949 | .remove = sta32x_remove, | 976 | .remove = sta32x_remove, |
950 | .suspend = sta32x_suspend, | 977 | .suspend = sta32x_suspend, |
951 | .resume = sta32x_resume, | 978 | .resume = sta32x_resume, |
952 | .reg_cache_size = STA32X_REGISTER_COUNT, | ||
953 | .reg_word_size = sizeof(u8), | ||
954 | .reg_cache_default = sta32x_regs, | ||
955 | .volatile_register = sta32x_reg_is_volatile, | ||
956 | .set_bias_level = sta32x_set_bias_level, | 979 | .set_bias_level = sta32x_set_bias_level, |
957 | .controls = sta32x_snd_controls, | 980 | .controls = sta32x_snd_controls, |
958 | .num_controls = ARRAY_SIZE(sta32x_snd_controls), | 981 | .num_controls = ARRAY_SIZE(sta32x_snd_controls), |
@@ -962,17 +985,45 @@ static const struct snd_soc_codec_driver sta32x_codec = { | |||
962 | .num_dapm_routes = ARRAY_SIZE(sta32x_dapm_routes), | 985 | .num_dapm_routes = ARRAY_SIZE(sta32x_dapm_routes), |
963 | }; | 986 | }; |
964 | 987 | ||
988 | static const struct regmap_config sta32x_regmap = { | ||
989 | .reg_bits = 8, | ||
990 | .val_bits = 8, | ||
991 | .max_register = STA32X_FDRC2, | ||
992 | .reg_defaults = sta32x_regs, | ||
993 | .num_reg_defaults = ARRAY_SIZE(sta32x_regs), | ||
994 | .cache_type = REGCACHE_RBTREE, | ||
995 | .volatile_reg = sta32x_reg_is_volatile, | ||
996 | }; | ||
997 | |||
965 | static __devinit int sta32x_i2c_probe(struct i2c_client *i2c, | 998 | static __devinit int sta32x_i2c_probe(struct i2c_client *i2c, |
966 | const struct i2c_device_id *id) | 999 | const struct i2c_device_id *id) |
967 | { | 1000 | { |
968 | struct sta32x_priv *sta32x; | 1001 | struct sta32x_priv *sta32x; |
969 | int ret; | 1002 | int ret, i; |
970 | 1003 | ||
971 | sta32x = devm_kzalloc(&i2c->dev, sizeof(struct sta32x_priv), | 1004 | sta32x = devm_kzalloc(&i2c->dev, sizeof(struct sta32x_priv), |
972 | GFP_KERNEL); | 1005 | GFP_KERNEL); |
973 | if (!sta32x) | 1006 | if (!sta32x) |
974 | return -ENOMEM; | 1007 | return -ENOMEM; |
975 | 1008 | ||
1009 | /* regulators */ | ||
1010 | for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++) | ||
1011 | sta32x->supplies[i].supply = sta32x_supply_names[i]; | ||
1012 | |||
1013 | ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(sta32x->supplies), | ||
1014 | sta32x->supplies); | ||
1015 | if (ret != 0) { | ||
1016 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); | ||
1017 | return ret; | ||
1018 | } | ||
1019 | |||
1020 | sta32x->regmap = devm_regmap_init_i2c(i2c, &sta32x_regmap); | ||
1021 | if (IS_ERR(sta32x->regmap)) { | ||
1022 | ret = PTR_ERR(sta32x->regmap); | ||
1023 | dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); | ||
1024 | return ret; | ||
1025 | } | ||
1026 | |||
976 | i2c_set_clientdata(i2c, sta32x); | 1027 | i2c_set_clientdata(i2c, sta32x); |
977 | 1028 | ||
978 | ret = snd_soc_register_codec(&i2c->dev, &sta32x_codec, &sta32x_dai, 1); | 1029 | ret = snd_soc_register_codec(&i2c->dev, &sta32x_codec, &sta32x_dai, 1); |
@@ -1006,17 +1057,7 @@ static struct i2c_driver sta32x_i2c_driver = { | |||
1006 | .id_table = sta32x_i2c_id, | 1057 | .id_table = sta32x_i2c_id, |
1007 | }; | 1058 | }; |
1008 | 1059 | ||
1009 | static int __init sta32x_init(void) | 1060 | module_i2c_driver(sta32x_i2c_driver); |
1010 | { | ||
1011 | return i2c_add_driver(&sta32x_i2c_driver); | ||
1012 | } | ||
1013 | module_init(sta32x_init); | ||
1014 | |||
1015 | static void __exit sta32x_exit(void) | ||
1016 | { | ||
1017 | i2c_del_driver(&sta32x_i2c_driver); | ||
1018 | } | ||
1019 | module_exit(sta32x_exit); | ||
1020 | 1061 | ||
1021 | MODULE_DESCRIPTION("ASoC STA32X driver"); | 1062 | MODULE_DESCRIPTION("ASoC STA32X driver"); |
1022 | MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>"); | 1063 | MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>"); |
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c index 0c225cd569d2..9e3144862386 100644 --- a/sound/soc/codecs/sta529.c +++ b/sound/soc/codecs/sta529.c | |||
@@ -358,7 +358,7 @@ static int sta529_resume(struct snd_soc_codec *codec) | |||
358 | return 0; | 358 | return 0; |
359 | } | 359 | } |
360 | 360 | ||
361 | struct snd_soc_codec_driver sta529_codec_driver = { | 361 | static const struct snd_soc_codec_driver sta529_codec_driver = { |
362 | .probe = sta529_probe, | 362 | .probe = sta529_probe, |
363 | .remove = sta529_remove, | 363 | .remove = sta529_remove, |
364 | .set_bias_level = sta529_set_bias_level, | 364 | .set_bias_level = sta529_set_bias_level, |
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 33c0f3d39c87..982e437799a8 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c | |||
@@ -340,7 +340,6 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec) | |||
340 | 340 | ||
341 | printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION); | 341 | printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION); |
342 | 342 | ||
343 | codec->control_data = codec; /* we don't use regmap! */ | ||
344 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | 343 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); |
345 | if (ret < 0) | 344 | if (ret < 0) |
346 | goto codec_err; | 345 | goto codec_err; |
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 85944e953578..b1f6982c7c9c 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c | |||
@@ -444,14 +444,4 @@ static struct spi_driver aic26_spi = { | |||
444 | .remove = aic26_spi_remove, | 444 | .remove = aic26_spi_remove, |
445 | }; | 445 | }; |
446 | 446 | ||
447 | static int __init aic26_init(void) | 447 | module_spi_driver(aic26_spi); |
448 | { | ||
449 | return spi_register_driver(&aic26_spi); | ||
450 | } | ||
451 | module_init(aic26_init); | ||
452 | |||
453 | static void __exit aic26_exit(void) | ||
454 | { | ||
455 | spi_unregister_driver(&aic26_spi); | ||
456 | } | ||
457 | module_exit(aic26_exit); | ||
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index b0a73d37ed52..f230292ba96b 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c | |||
@@ -746,24 +746,7 @@ static struct i2c_driver aic32x4_i2c_driver = { | |||
746 | .id_table = aic32x4_i2c_id, | 746 | .id_table = aic32x4_i2c_id, |
747 | }; | 747 | }; |
748 | 748 | ||
749 | static int __init aic32x4_modinit(void) | 749 | module_i2c_driver(aic32x4_i2c_driver); |
750 | { | ||
751 | int ret = 0; | ||
752 | |||
753 | ret = i2c_add_driver(&aic32x4_i2c_driver); | ||
754 | if (ret != 0) { | ||
755 | printk(KERN_ERR "Failed to register aic32x4 I2C driver: %d\n", | ||
756 | ret); | ||
757 | } | ||
758 | return ret; | ||
759 | } | ||
760 | module_init(aic32x4_modinit); | ||
761 | |||
762 | static void __exit aic32x4_exit(void) | ||
763 | { | ||
764 | i2c_del_driver(&aic32x4_i2c_driver); | ||
765 | } | ||
766 | module_exit(aic32x4_exit); | ||
767 | 750 | ||
768 | MODULE_DESCRIPTION("ASoC tlv320aic32x4 codec driver"); | 751 | MODULE_DESCRIPTION("ASoC tlv320aic32x4 codec driver"); |
769 | MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>"); | 752 | MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>"); |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index dc78f5a4bcbf..5708a973a776 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/i2c.h> | 40 | #include <linux/i2c.h> |
41 | #include <linux/gpio.h> | 41 | #include <linux/gpio.h> |
42 | #include <linux/regulator/consumer.h> | 42 | #include <linux/regulator/consumer.h> |
43 | #include <linux/of_gpio.h> | ||
43 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
44 | #include <sound/core.h> | 45 | #include <sound/core.h> |
45 | #include <sound/pcm.h> | 46 | #include <sound/pcm.h> |
@@ -1457,6 +1458,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, | |||
1457 | { | 1458 | { |
1458 | struct aic3x_pdata *pdata = i2c->dev.platform_data; | 1459 | struct aic3x_pdata *pdata = i2c->dev.platform_data; |
1459 | struct aic3x_priv *aic3x; | 1460 | struct aic3x_priv *aic3x; |
1461 | struct aic3x_setup_data *ai3x_setup; | ||
1462 | struct device_node *np = i2c->dev.of_node; | ||
1460 | int ret; | 1463 | int ret; |
1461 | 1464 | ||
1462 | aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL); | 1465 | aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL); |
@@ -1471,6 +1474,25 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, | |||
1471 | if (pdata) { | 1474 | if (pdata) { |
1472 | aic3x->gpio_reset = pdata->gpio_reset; | 1475 | aic3x->gpio_reset = pdata->gpio_reset; |
1473 | aic3x->setup = pdata->setup; | 1476 | aic3x->setup = pdata->setup; |
1477 | } else if (np) { | ||
1478 | ai3x_setup = devm_kzalloc(&i2c->dev, sizeof(*ai3x_setup), | ||
1479 | GFP_KERNEL); | ||
1480 | if (ai3x_setup == NULL) { | ||
1481 | dev_err(&i2c->dev, "failed to create private data\n"); | ||
1482 | return -ENOMEM; | ||
1483 | } | ||
1484 | |||
1485 | ret = of_get_named_gpio(np, "gpio-reset", 0); | ||
1486 | if (ret >= 0) | ||
1487 | aic3x->gpio_reset = ret; | ||
1488 | else | ||
1489 | aic3x->gpio_reset = -1; | ||
1490 | |||
1491 | if (of_property_read_u32_array(np, "ai3x-gpio-func", | ||
1492 | ai3x_setup->gpio_func, 2) >= 0) { | ||
1493 | aic3x->setup = ai3x_setup; | ||
1494 | } | ||
1495 | |||
1474 | } else { | 1496 | } else { |
1475 | aic3x->gpio_reset = -1; | 1497 | aic3x->gpio_reset = -1; |
1476 | } | 1498 | } |
@@ -1488,34 +1510,27 @@ static int aic3x_i2c_remove(struct i2c_client *client) | |||
1488 | return 0; | 1510 | return 0; |
1489 | } | 1511 | } |
1490 | 1512 | ||
1513 | #if defined(CONFIG_OF) | ||
1514 | static const struct of_device_id tlv320aic3x_of_match[] = { | ||
1515 | { .compatible = "ti,tlv320aic3x", }, | ||
1516 | {}, | ||
1517 | }; | ||
1518 | MODULE_DEVICE_TABLE(of, tlv320aic3x_of_match); | ||
1519 | #endif | ||
1520 | |||
1491 | /* machine i2c codec control layer */ | 1521 | /* machine i2c codec control layer */ |
1492 | static struct i2c_driver aic3x_i2c_driver = { | 1522 | static struct i2c_driver aic3x_i2c_driver = { |
1493 | .driver = { | 1523 | .driver = { |
1494 | .name = "tlv320aic3x-codec", | 1524 | .name = "tlv320aic3x-codec", |
1495 | .owner = THIS_MODULE, | 1525 | .owner = THIS_MODULE, |
1526 | .of_match_table = of_match_ptr(tlv320aic3x_of_match), | ||
1496 | }, | 1527 | }, |
1497 | .probe = aic3x_i2c_probe, | 1528 | .probe = aic3x_i2c_probe, |
1498 | .remove = aic3x_i2c_remove, | 1529 | .remove = aic3x_i2c_remove, |
1499 | .id_table = aic3x_i2c_id, | 1530 | .id_table = aic3x_i2c_id, |
1500 | }; | 1531 | }; |
1501 | 1532 | ||
1502 | static int __init aic3x_modinit(void) | 1533 | module_i2c_driver(aic3x_i2c_driver); |
1503 | { | ||
1504 | int ret = 0; | ||
1505 | ret = i2c_add_driver(&aic3x_i2c_driver); | ||
1506 | if (ret != 0) { | ||
1507 | printk(KERN_ERR "Failed to register TLV320AIC3x I2C driver: %d\n", | ||
1508 | ret); | ||
1509 | } | ||
1510 | return ret; | ||
1511 | } | ||
1512 | module_init(aic3x_modinit); | ||
1513 | |||
1514 | static void __exit aic3x_exit(void) | ||
1515 | { | ||
1516 | i2c_del_driver(&aic3x_i2c_driver); | ||
1517 | } | ||
1518 | module_exit(aic3x_exit); | ||
1519 | 1534 | ||
1520 | MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver"); | 1535 | MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver"); |
1521 | MODULE_AUTHOR("Vladimir Barinov"); | 1536 | MODULE_AUTHOR("Vladimir Barinov"); |
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 0dd41077ab79..d2e16c5d7d1f 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c | |||
@@ -1621,24 +1621,7 @@ static struct i2c_driver tlv320dac33_i2c_driver = { | |||
1621 | .id_table = tlv320dac33_i2c_id, | 1621 | .id_table = tlv320dac33_i2c_id, |
1622 | }; | 1622 | }; |
1623 | 1623 | ||
1624 | static int __init dac33_module_init(void) | 1624 | module_i2c_driver(tlv320dac33_i2c_driver); |
1625 | { | ||
1626 | int r; | ||
1627 | r = i2c_add_driver(&tlv320dac33_i2c_driver); | ||
1628 | if (r < 0) { | ||
1629 | printk(KERN_ERR "DAC33: driver registration failed\n"); | ||
1630 | return r; | ||
1631 | } | ||
1632 | return 0; | ||
1633 | } | ||
1634 | module_init(dac33_module_init); | ||
1635 | |||
1636 | static void __exit dac33_module_exit(void) | ||
1637 | { | ||
1638 | i2c_del_driver(&tlv320dac33_i2c_driver); | ||
1639 | } | ||
1640 | module_exit(dac33_module_exit); | ||
1641 | |||
1642 | 1625 | ||
1643 | MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver"); | 1626 | MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver"); |
1644 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); | 1627 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); |
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 6fe4aa3ac544..565ff39ad3a3 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c | |||
@@ -487,19 +487,8 @@ static struct i2c_driver tpa6130a2_i2c_driver = { | |||
487 | .id_table = tpa6130a2_id, | 487 | .id_table = tpa6130a2_id, |
488 | }; | 488 | }; |
489 | 489 | ||
490 | static int __init tpa6130a2_init(void) | 490 | module_i2c_driver(tpa6130a2_i2c_driver); |
491 | { | ||
492 | return i2c_add_driver(&tpa6130a2_i2c_driver); | ||
493 | } | ||
494 | |||
495 | static void __exit tpa6130a2_exit(void) | ||
496 | { | ||
497 | i2c_del_driver(&tpa6130a2_i2c_driver); | ||
498 | } | ||
499 | 491 | ||
500 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); | 492 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); |
501 | MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver"); | 493 | MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver"); |
502 | MODULE_LICENSE("GPL"); | 494 | MODULE_LICENSE("GPL"); |
503 | |||
504 | module_init(tpa6130a2_init); | ||
505 | module_exit(tpa6130a2_exit); | ||
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 391fcfc7b63b..e7f608996c41 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -26,8 +26,11 @@ | |||
26 | #include <linux/pm.h> | 26 | #include <linux/pm.h> |
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/of.h> | ||
30 | #include <linux/of_gpio.h> | ||
29 | #include <linux/i2c/twl.h> | 31 | #include <linux/i2c/twl.h> |
30 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/gpio.h> | ||
31 | #include <sound/core.h> | 34 | #include <sound/core.h> |
32 | #include <sound/pcm.h> | 35 | #include <sound/pcm.h> |
33 | #include <sound/pcm_params.h> | 36 | #include <sound/pcm_params.h> |
@@ -152,8 +155,7 @@ struct twl4030_priv { | |||
152 | u8 predrivel_enabled, predriver_enabled; | 155 | u8 predrivel_enabled, predriver_enabled; |
153 | u8 carkitl_enabled, carkitr_enabled; | 156 | u8 carkitl_enabled, carkitr_enabled; |
154 | 157 | ||
155 | /* Delay needed after enabling the digimic interface */ | 158 | struct twl4030_codec_data *pdata; |
156 | unsigned int digimic_delay; | ||
157 | }; | 159 | }; |
158 | 160 | ||
159 | /* | 161 | /* |
@@ -295,13 +297,73 @@ static inline void twl4030_reset_registers(struct snd_soc_codec *codec) | |||
295 | 297 | ||
296 | } | 298 | } |
297 | 299 | ||
298 | static void twl4030_init_chip(struct snd_soc_codec *codec) | 300 | static void twl4030_setup_pdata_of(struct twl4030_codec_data *pdata, |
301 | struct device_node *node) | ||
302 | { | ||
303 | int value; | ||
304 | |||
305 | of_property_read_u32(node, "ti,digimic_delay", | ||
306 | &pdata->digimic_delay); | ||
307 | of_property_read_u32(node, "ti,ramp_delay_value", | ||
308 | &pdata->ramp_delay_value); | ||
309 | of_property_read_u32(node, "ti,offset_cncl_path", | ||
310 | &pdata->offset_cncl_path); | ||
311 | if (!of_property_read_u32(node, "ti,hs_extmute", &value)) | ||
312 | pdata->hs_extmute = value; | ||
313 | |||
314 | pdata->hs_extmute_gpio = of_get_named_gpio(node, | ||
315 | "ti,hs_extmute_gpio", 0); | ||
316 | if (gpio_is_valid(pdata->hs_extmute_gpio)) | ||
317 | pdata->hs_extmute = 1; | ||
318 | } | ||
319 | |||
320 | static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_codec *codec) | ||
299 | { | 321 | { |
300 | struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev); | 322 | struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev); |
323 | struct device_node *twl4030_codec_node = NULL; | ||
324 | |||
325 | twl4030_codec_node = of_find_node_by_name(codec->dev->parent->of_node, | ||
326 | "codec"); | ||
327 | |||
328 | if (!pdata && twl4030_codec_node) { | ||
329 | pdata = devm_kzalloc(codec->dev, | ||
330 | sizeof(struct twl4030_codec_data), | ||
331 | GFP_KERNEL); | ||
332 | if (!pdata) { | ||
333 | dev_err(codec->dev, "Can not allocate memory\n"); | ||
334 | return NULL; | ||
335 | } | ||
336 | twl4030_setup_pdata_of(pdata, twl4030_codec_node); | ||
337 | } | ||
338 | |||
339 | return pdata; | ||
340 | } | ||
341 | |||
342 | static void twl4030_init_chip(struct snd_soc_codec *codec) | ||
343 | { | ||
344 | struct twl4030_codec_data *pdata; | ||
301 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 345 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
302 | u8 reg, byte; | 346 | u8 reg, byte; |
303 | int i = 0; | 347 | int i = 0; |
304 | 348 | ||
349 | pdata = twl4030_get_pdata(codec); | ||
350 | |||
351 | if (pdata && pdata->hs_extmute && | ||
352 | gpio_is_valid(pdata->hs_extmute_gpio)) { | ||
353 | int ret; | ||
354 | |||
355 | if (!pdata->hs_extmute_gpio) | ||
356 | dev_warn(codec->dev, | ||
357 | "Extmute GPIO is 0 is this correct?\n"); | ||
358 | |||
359 | ret = gpio_request_one(pdata->hs_extmute_gpio, | ||
360 | GPIOF_OUT_INIT_LOW, "hs_extmute"); | ||
361 | if (ret) { | ||
362 | dev_err(codec->dev, "Failed to get hs_extmute GPIO\n"); | ||
363 | pdata->hs_extmute_gpio = -1; | ||
364 | } | ||
365 | } | ||
366 | |||
305 | /* Check defaults, if instructed before anything else */ | 367 | /* Check defaults, if instructed before anything else */ |
306 | if (pdata && pdata->check_defaults) | 368 | if (pdata && pdata->check_defaults) |
307 | twl4030_check_defaults(codec); | 369 | twl4030_check_defaults(codec); |
@@ -331,7 +393,7 @@ static void twl4030_init_chip(struct snd_soc_codec *codec) | |||
331 | if (!pdata) | 393 | if (!pdata) |
332 | return; | 394 | return; |
333 | 395 | ||
334 | twl4030->digimic_delay = pdata->digimic_delay; | 396 | twl4030->pdata = pdata; |
335 | 397 | ||
336 | reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); | 398 | reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); |
337 | reg &= ~TWL4030_RAMP_DELAY; | 399 | reg &= ~TWL4030_RAMP_DELAY; |
@@ -732,9 +794,9 @@ static int aif_event(struct snd_soc_dapm_widget *w, | |||
732 | 794 | ||
733 | static void headset_ramp(struct snd_soc_codec *codec, int ramp) | 795 | static void headset_ramp(struct snd_soc_codec *codec, int ramp) |
734 | { | 796 | { |
735 | struct twl4030_codec_data *pdata = codec->dev->platform_data; | ||
736 | unsigned char hs_gain, hs_pop; | 797 | unsigned char hs_gain, hs_pop; |
737 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 798 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
799 | struct twl4030_codec_data *pdata = twl4030->pdata; | ||
738 | /* Base values for ramp delay calculation: 2^19 - 2^26 */ | 800 | /* Base values for ramp delay calculation: 2^19 - 2^26 */ |
739 | unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304, | 801 | unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304, |
740 | 8388608, 16777216, 33554432, 67108864}; | 802 | 8388608, 16777216, 33554432, 67108864}; |
@@ -748,8 +810,8 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) | |||
748 | /* Enable external mute control, this dramatically reduces | 810 | /* Enable external mute control, this dramatically reduces |
749 | * the pop-noise */ | 811 | * the pop-noise */ |
750 | if (pdata && pdata->hs_extmute) { | 812 | if (pdata && pdata->hs_extmute) { |
751 | if (pdata->set_hs_extmute) { | 813 | if (gpio_is_valid(pdata->hs_extmute_gpio)) { |
752 | pdata->set_hs_extmute(1); | 814 | gpio_set_value(pdata->hs_extmute_gpio, 1); |
753 | } else { | 815 | } else { |
754 | hs_pop |= TWL4030_EXTMUTE; | 816 | hs_pop |= TWL4030_EXTMUTE; |
755 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); | 817 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); |
@@ -786,8 +848,8 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) | |||
786 | 848 | ||
787 | /* Disable external mute */ | 849 | /* Disable external mute */ |
788 | if (pdata && pdata->hs_extmute) { | 850 | if (pdata && pdata->hs_extmute) { |
789 | if (pdata->set_hs_extmute) { | 851 | if (gpio_is_valid(pdata->hs_extmute_gpio)) { |
790 | pdata->set_hs_extmute(0); | 852 | gpio_set_value(pdata->hs_extmute_gpio, 0); |
791 | } else { | 853 | } else { |
792 | hs_pop &= ~TWL4030_EXTMUTE; | 854 | hs_pop &= ~TWL4030_EXTMUTE; |
793 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); | 855 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); |
@@ -847,9 +909,10 @@ static int digimic_event(struct snd_soc_dapm_widget *w, | |||
847 | struct snd_kcontrol *kcontrol, int event) | 909 | struct snd_kcontrol *kcontrol, int event) |
848 | { | 910 | { |
849 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); | 911 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); |
912 | struct twl4030_codec_data *pdata = twl4030->pdata; | ||
850 | 913 | ||
851 | if (twl4030->digimic_delay) | 914 | if (pdata && pdata->digimic_delay) |
852 | twl4030_wait_ms(twl4030->digimic_delay); | 915 | twl4030_wait_ms(pdata->digimic_delay); |
853 | return 0; | 916 | return 0; |
854 | } | 917 | } |
855 | 918 | ||
@@ -999,7 +1062,7 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, | |||
999 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 1062 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
1000 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | 1063 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
1001 | unsigned short val; | 1064 | unsigned short val; |
1002 | unsigned short mask, bitmask; | 1065 | unsigned short mask; |
1003 | 1066 | ||
1004 | if (twl4030->configured) { | 1067 | if (twl4030->configured) { |
1005 | dev_err(codec->dev, | 1068 | dev_err(codec->dev, |
@@ -1007,18 +1070,16 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, | |||
1007 | return -EBUSY; | 1070 | return -EBUSY; |
1008 | } | 1071 | } |
1009 | 1072 | ||
1010 | for (bitmask = 1; bitmask < e->max; bitmask <<= 1) | ||
1011 | ; | ||
1012 | if (ucontrol->value.enumerated.item[0] > e->max - 1) | 1073 | if (ucontrol->value.enumerated.item[0] > e->max - 1) |
1013 | return -EINVAL; | 1074 | return -EINVAL; |
1014 | 1075 | ||
1015 | val = ucontrol->value.enumerated.item[0] << e->shift_l; | 1076 | val = ucontrol->value.enumerated.item[0] << e->shift_l; |
1016 | mask = (bitmask - 1) << e->shift_l; | 1077 | mask = e->mask << e->shift_l; |
1017 | if (e->shift_l != e->shift_r) { | 1078 | if (e->shift_l != e->shift_r) { |
1018 | if (ucontrol->value.enumerated.item[1] > e->max - 1) | 1079 | if (ucontrol->value.enumerated.item[1] > e->max - 1) |
1019 | return -EINVAL; | 1080 | return -EINVAL; |
1020 | val |= ucontrol->value.enumerated.item[1] << e->shift_r; | 1081 | val |= ucontrol->value.enumerated.item[1] << e->shift_r; |
1021 | mask |= (bitmask - 1) << e->shift_r; | 1082 | mask |= e->mask << e->shift_r; |
1022 | } | 1083 | } |
1023 | 1084 | ||
1024 | return snd_soc_update_bits(codec, e->reg, mask, val); | 1085 | return snd_soc_update_bits(codec, e->reg, mask, val); |
@@ -1239,16 +1300,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { | |||
1239 | SND_SOC_DAPM_OUTPUT("Virtual Voice OUT"), | 1300 | SND_SOC_DAPM_OUTPUT("Virtual Voice OUT"), |
1240 | 1301 | ||
1241 | /* DACs */ | 1302 | /* DACs */ |
1242 | SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback", | 1303 | SND_SOC_DAPM_DAC("DAC Right1", NULL, SND_SOC_NOPM, 0, 0), |
1243 | SND_SOC_NOPM, 0, 0), | 1304 | SND_SOC_DAPM_DAC("DAC Left1", NULL, SND_SOC_NOPM, 0, 0), |
1244 | SND_SOC_DAPM_DAC("DAC Left1", "Left Front HiFi Playback", | 1305 | SND_SOC_DAPM_DAC("DAC Right2", NULL, SND_SOC_NOPM, 0, 0), |
1245 | SND_SOC_NOPM, 0, 0), | 1306 | SND_SOC_DAPM_DAC("DAC Left2", NULL, SND_SOC_NOPM, 0, 0), |
1246 | SND_SOC_DAPM_DAC("DAC Right2", "Right Rear HiFi Playback", | 1307 | SND_SOC_DAPM_DAC("DAC Voice", NULL, SND_SOC_NOPM, 0, 0), |
1247 | SND_SOC_NOPM, 0, 0), | ||
1248 | SND_SOC_DAPM_DAC("DAC Left2", "Left Rear HiFi Playback", | ||
1249 | SND_SOC_NOPM, 0, 0), | ||
1250 | SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback", | ||
1251 | SND_SOC_NOPM, 0, 0), | ||
1252 | 1308 | ||
1253 | /* Analog bypasses */ | 1309 | /* Analog bypasses */ |
1254 | SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0, | 1310 | SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0, |
@@ -1377,14 +1433,10 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { | |||
1377 | 1433 | ||
1378 | /* Introducing four virtual ADC, since TWL4030 have four channel for | 1434 | /* Introducing four virtual ADC, since TWL4030 have four channel for |
1379 | capture */ | 1435 | capture */ |
1380 | SND_SOC_DAPM_ADC("ADC Virtual Left1", "Left Front Capture", | 1436 | SND_SOC_DAPM_ADC("ADC Virtual Left1", NULL, SND_SOC_NOPM, 0, 0), |
1381 | SND_SOC_NOPM, 0, 0), | 1437 | SND_SOC_DAPM_ADC("ADC Virtual Right1", NULL, SND_SOC_NOPM, 0, 0), |
1382 | SND_SOC_DAPM_ADC("ADC Virtual Right1", "Right Front Capture", | 1438 | SND_SOC_DAPM_ADC("ADC Virtual Left2", NULL, SND_SOC_NOPM, 0, 0), |
1383 | SND_SOC_NOPM, 0, 0), | 1439 | SND_SOC_DAPM_ADC("ADC Virtual Right2", NULL, SND_SOC_NOPM, 0, 0), |
1384 | SND_SOC_DAPM_ADC("ADC Virtual Left2", "Left Rear Capture", | ||
1385 | SND_SOC_NOPM, 0, 0), | ||
1386 | SND_SOC_DAPM_ADC("ADC Virtual Right2", "Right Rear Capture", | ||
1387 | SND_SOC_NOPM, 0, 0), | ||
1388 | 1440 | ||
1389 | /* Analog/Digital mic path selection. | 1441 | /* Analog/Digital mic path selection. |
1390 | TX1 Left/Right: either analog Left/Right or Digimic0 | 1442 | TX1 Left/Right: either analog Left/Right or Digimic0 |
@@ -1428,6 +1480,23 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { | |||
1428 | }; | 1480 | }; |
1429 | 1481 | ||
1430 | static const struct snd_soc_dapm_route intercon[] = { | 1482 | static const struct snd_soc_dapm_route intercon[] = { |
1483 | /* Stream -> DAC mapping */ | ||
1484 | {"DAC Right1", NULL, "HiFi Playback"}, | ||
1485 | {"DAC Left1", NULL, "HiFi Playback"}, | ||
1486 | {"DAC Right2", NULL, "HiFi Playback"}, | ||
1487 | {"DAC Left2", NULL, "HiFi Playback"}, | ||
1488 | {"DAC Voice", NULL, "Voice Playback"}, | ||
1489 | |||
1490 | /* ADC -> Stream mapping */ | ||
1491 | {"HiFi Capture", NULL, "ADC Virtual Left1"}, | ||
1492 | {"HiFi Capture", NULL, "ADC Virtual Right1"}, | ||
1493 | {"HiFi Capture", NULL, "ADC Virtual Left2"}, | ||
1494 | {"HiFi Capture", NULL, "ADC Virtual Right2"}, | ||
1495 | {"Voice Capture", NULL, "ADC Virtual Left1"}, | ||
1496 | {"Voice Capture", NULL, "ADC Virtual Right1"}, | ||
1497 | {"Voice Capture", NULL, "ADC Virtual Left2"}, | ||
1498 | {"Voice Capture", NULL, "ADC Virtual Right2"}, | ||
1499 | |||
1431 | {"Digital L1 Playback Mixer", NULL, "DAC Left1"}, | 1500 | {"Digital L1 Playback Mixer", NULL, "DAC Left1"}, |
1432 | {"Digital R1 Playback Mixer", NULL, "DAC Right1"}, | 1501 | {"Digital R1 Playback Mixer", NULL, "DAC Right1"}, |
1433 | {"Digital L2 Playback Mixer", NULL, "DAC Left2"}, | 1502 | {"Digital L2 Playback Mixer", NULL, "DAC Left2"}, |
@@ -2172,7 +2241,7 @@ static struct snd_soc_dai_driver twl4030_dai[] = { | |||
2172 | .formats = TWL4030_FORMATS, | 2241 | .formats = TWL4030_FORMATS, |
2173 | .sig_bits = 24,}, | 2242 | .sig_bits = 24,}, |
2174 | .capture = { | 2243 | .capture = { |
2175 | .stream_name = "Capture", | 2244 | .stream_name = "HiFi Capture", |
2176 | .channels_min = 2, | 2245 | .channels_min = 2, |
2177 | .channels_max = 4, | 2246 | .channels_max = 4, |
2178 | .rates = TWL4030_RATES, | 2247 | .rates = TWL4030_RATES, |
@@ -2189,7 +2258,7 @@ static struct snd_soc_dai_driver twl4030_dai[] = { | |||
2189 | .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, | 2258 | .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, |
2190 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 2259 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, |
2191 | .capture = { | 2260 | .capture = { |
2192 | .stream_name = "Capture", | 2261 | .stream_name = "Voice Capture", |
2193 | .channels_min = 1, | 2262 | .channels_min = 1, |
2194 | .channels_max = 2, | 2263 | .channels_max = 2, |
2195 | .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, | 2264 | .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, |
@@ -2214,7 +2283,8 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec) | |||
2214 | { | 2283 | { |
2215 | struct twl4030_priv *twl4030; | 2284 | struct twl4030_priv *twl4030; |
2216 | 2285 | ||
2217 | twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); | 2286 | twl4030 = devm_kzalloc(codec->dev, sizeof(struct twl4030_priv), |
2287 | GFP_KERNEL); | ||
2218 | if (twl4030 == NULL) { | 2288 | if (twl4030 == NULL) { |
2219 | dev_err(codec->dev, "Can not allocate memory\n"); | 2289 | dev_err(codec->dev, "Can not allocate memory\n"); |
2220 | return -ENOMEM; | 2290 | return -ENOMEM; |
@@ -2231,11 +2301,15 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec) | |||
2231 | static int twl4030_soc_remove(struct snd_soc_codec *codec) | 2301 | static int twl4030_soc_remove(struct snd_soc_codec *codec) |
2232 | { | 2302 | { |
2233 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 2303 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
2304 | struct twl4030_codec_data *pdata = twl4030->pdata; | ||
2234 | 2305 | ||
2235 | /* Reset registers to their chip default before leaving */ | 2306 | /* Reset registers to their chip default before leaving */ |
2236 | twl4030_reset_registers(codec); | 2307 | twl4030_reset_registers(codec); |
2237 | twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); | 2308 | twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); |
2238 | kfree(twl4030); | 2309 | |
2310 | if (pdata && pdata->hs_extmute && gpio_is_valid(pdata->hs_extmute_gpio)) | ||
2311 | gpio_free(pdata->hs_extmute_gpio); | ||
2312 | |||
2239 | return 0; | 2313 | return 0; |
2240 | } | 2314 | } |
2241 | 2315 | ||
@@ -2262,13 +2336,6 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { | |||
2262 | 2336 | ||
2263 | static int __devinit twl4030_codec_probe(struct platform_device *pdev) | 2337 | static int __devinit twl4030_codec_probe(struct platform_device *pdev) |
2264 | { | 2338 | { |
2265 | struct twl4030_codec_data *pdata = pdev->dev.platform_data; | ||
2266 | |||
2267 | if (!pdata) { | ||
2268 | dev_err(&pdev->dev, "platform_data is missing\n"); | ||
2269 | return -EINVAL; | ||
2270 | } | ||
2271 | |||
2272 | return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030, | 2339 | return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030, |
2273 | twl4030_dai, ARRAY_SIZE(twl4030_dai)); | 2340 | twl4030_dai, ARRAY_SIZE(twl4030_dai)); |
2274 | } | 2341 | } |
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index c084c549942e..e8f97af75928 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c | |||
@@ -727,10 +727,8 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { | |||
727 | TWL6040_REG_MICRCTL, 1, 0, NULL, 0), | 727 | TWL6040_REG_MICRCTL, 1, 0, NULL, 0), |
728 | 728 | ||
729 | /* ADCs */ | 729 | /* ADCs */ |
730 | SND_SOC_DAPM_ADC("ADC Left", "Left Front Capture", | 730 | SND_SOC_DAPM_ADC("ADC Left", NULL, TWL6040_REG_MICLCTL, 2, 0), |
731 | TWL6040_REG_MICLCTL, 2, 0), | 731 | SND_SOC_DAPM_ADC("ADC Right", NULL, TWL6040_REG_MICRCTL, 2, 0), |
732 | SND_SOC_DAPM_ADC("ADC Right", "Right Front Capture", | ||
733 | TWL6040_REG_MICRCTL, 2, 0), | ||
734 | 732 | ||
735 | /* Microphone bias */ | 733 | /* Microphone bias */ |
736 | SND_SOC_DAPM_SUPPLY("Headset Mic Bias", | 734 | SND_SOC_DAPM_SUPPLY("Headset Mic Bias", |
@@ -743,15 +741,12 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { | |||
743 | TWL6040_REG_DMICBCTL, 4, 0, NULL, 0), | 741 | TWL6040_REG_DMICBCTL, 4, 0, NULL, 0), |
744 | 742 | ||
745 | /* DACs */ | 743 | /* DACs */ |
746 | SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", SND_SOC_NOPM, 0, 0), | 744 | SND_SOC_DAPM_DAC("HSDAC Left", NULL, SND_SOC_NOPM, 0, 0), |
747 | SND_SOC_DAPM_DAC("HSDAC Right", "Headset Playback", SND_SOC_NOPM, 0, 0), | 745 | SND_SOC_DAPM_DAC("HSDAC Right", NULL, SND_SOC_NOPM, 0, 0), |
748 | SND_SOC_DAPM_DAC("HFDAC Left", "Handsfree Playback", | 746 | SND_SOC_DAPM_DAC("HFDAC Left", NULL, TWL6040_REG_HFLCTL, 0, 0), |
749 | TWL6040_REG_HFLCTL, 0, 0), | 747 | SND_SOC_DAPM_DAC("HFDAC Right", NULL, TWL6040_REG_HFRCTL, 0, 0), |
750 | SND_SOC_DAPM_DAC("HFDAC Right", "Handsfree Playback", | ||
751 | TWL6040_REG_HFRCTL, 0, 0), | ||
752 | /* Virtual DAC for vibra path (DL4 channel) */ | 748 | /* Virtual DAC for vibra path (DL4 channel) */ |
753 | SND_SOC_DAPM_DAC("VIBRA DAC", "Vibra Playback", | 749 | SND_SOC_DAPM_DAC("VIBRA DAC", NULL, SND_SOC_NOPM, 0, 0), |
754 | SND_SOC_NOPM, 0, 0), | ||
755 | 750 | ||
756 | SND_SOC_DAPM_MUX("Handsfree Left Playback", | 751 | SND_SOC_DAPM_MUX("Handsfree Left Playback", |
757 | SND_SOC_NOPM, 0, 0, &hfl_mux_controls), | 752 | SND_SOC_NOPM, 0, 0, &hfl_mux_controls), |
@@ -810,6 +805,26 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { | |||
810 | }; | 805 | }; |
811 | 806 | ||
812 | static const struct snd_soc_dapm_route intercon[] = { | 807 | static const struct snd_soc_dapm_route intercon[] = { |
808 | /* Stream -> DAC mapping */ | ||
809 | {"HSDAC Left", NULL, "Legacy Playback"}, | ||
810 | {"HSDAC Left", NULL, "Headset Playback"}, | ||
811 | {"HSDAC Right", NULL, "Legacy Playback"}, | ||
812 | {"HSDAC Right", NULL, "Headset Playback"}, | ||
813 | |||
814 | {"HFDAC Left", NULL, "Legacy Playback"}, | ||
815 | {"HFDAC Left", NULL, "Handsfree Playback"}, | ||
816 | {"HFDAC Right", NULL, "Legacy Playback"}, | ||
817 | {"HFDAC Right", NULL, "Handsfree Playback"}, | ||
818 | |||
819 | {"VIBRA DAC", NULL, "Legacy Playback"}, | ||
820 | {"VIBRA DAC", NULL, "Vibra Playback"}, | ||
821 | |||
822 | /* ADC -> Stream mapping */ | ||
823 | {"ADC Left", NULL, "Legacy Capture"}, | ||
824 | {"ADC Left", NULL, "Capture"}, | ||
825 | {"ADC Right", NULL, "Legacy Capture"}, | ||
826 | {"ADC Right", NULL, "Capture"}, | ||
827 | |||
813 | /* Capture path */ | 828 | /* Capture path */ |
814 | {"Analog Left Capture Route", "Headset Mic", "HSMIC"}, | 829 | {"Analog Left Capture Route", "Headset Mic", "HSMIC"}, |
815 | {"Analog Left Capture Route", "Main Mic", "MAINMIC"}, | 830 | {"Analog Left Capture Route", "Main Mic", "MAINMIC"}, |
@@ -1028,14 +1043,14 @@ static struct snd_soc_dai_driver twl6040_dai[] = { | |||
1028 | { | 1043 | { |
1029 | .name = "twl6040-legacy", | 1044 | .name = "twl6040-legacy", |
1030 | .playback = { | 1045 | .playback = { |
1031 | .stream_name = "Playback", | 1046 | .stream_name = "Legacy Playback", |
1032 | .channels_min = 1, | 1047 | .channels_min = 1, |
1033 | .channels_max = 5, | 1048 | .channels_max = 5, |
1034 | .rates = TWL6040_RATES, | 1049 | .rates = TWL6040_RATES, |
1035 | .formats = TWL6040_FORMATS, | 1050 | .formats = TWL6040_FORMATS, |
1036 | }, | 1051 | }, |
1037 | .capture = { | 1052 | .capture = { |
1038 | .stream_name = "Capture", | 1053 | .stream_name = "Legacy Capture", |
1039 | .channels_min = 1, | 1054 | .channels_min = 1, |
1040 | .channels_max = 2, | 1055 | .channels_max = 2, |
1041 | .rates = TWL6040_RATES, | 1056 | .rates = TWL6040_RATES, |
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c new file mode 100644 index 000000000000..f8d6c31db870 --- /dev/null +++ b/sound/soc/codecs/wm0010.c | |||
@@ -0,0 +1,944 @@ | |||
1 | /* | ||
2 | * wm0010.c -- WM0010 DSP Driver | ||
3 | * | ||
4 | * Copyright 2012 Wolfson Microelectronics PLC. | ||
5 | * | ||
6 | * Authors: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
7 | * Dimitris Papastamos <dp@opensource.wolfsonmicro.com> | ||
8 | * Scott Ling <sl@opensource.wolfsonmicro.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/moduleparam.h> | ||
17 | #include <linux/irqreturn.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/spi/spi.h> | ||
20 | #include <linux/firmware.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/fs.h> | ||
23 | #include <linux/miscdevice.h> | ||
24 | #include <linux/gpio.h> | ||
25 | #include <linux/regulator/consumer.h> | ||
26 | #include <linux/mutex.h> | ||
27 | #include <linux/workqueue.h> | ||
28 | |||
29 | #include <sound/soc.h> | ||
30 | #include <sound/wm0010.h> | ||
31 | |||
32 | #define DEVICE_ID_WM0010 10 | ||
33 | |||
34 | enum dfw_cmd { | ||
35 | DFW_CMD_FUSE = 0x01, | ||
36 | DFW_CMD_CODE_HDR, | ||
37 | DFW_CMD_CODE_DATA, | ||
38 | DFW_CMD_PLL, | ||
39 | DFW_CMD_INFO = 0xff | ||
40 | }; | ||
41 | |||
42 | struct dfw_binrec { | ||
43 | u8 command; | ||
44 | u32 length:24; | ||
45 | u32 address; | ||
46 | uint8_t data[0]; | ||
47 | } __packed; | ||
48 | |||
49 | struct dfw_pllrec { | ||
50 | u8 command; | ||
51 | u32 length:24; | ||
52 | u32 address; | ||
53 | u32 clkctrl1; | ||
54 | u32 clkctrl2; | ||
55 | u32 clkctrl3; | ||
56 | u32 ldetctrl; | ||
57 | u32 uart_div; | ||
58 | u32 spi_div; | ||
59 | } __packed; | ||
60 | |||
61 | static struct pll_clock_map { | ||
62 | int max_sysclk; | ||
63 | int max_pll_spi_speed; | ||
64 | u32 pll_clkctrl1; | ||
65 | } pll_clock_map[] = { /* Dividers */ | ||
66 | { 22000000, 26000000, 0x00201f11 }, /* 2,32,2 */ | ||
67 | { 18000000, 26000000, 0x00203f21 }, /* 2,64,4 */ | ||
68 | { 14000000, 26000000, 0x00202620 }, /* 1,39,4 */ | ||
69 | { 10000000, 22000000, 0x00203120 }, /* 1,50,4 */ | ||
70 | { 6500000, 22000000, 0x00204520 }, /* 1,70,4 */ | ||
71 | { 5500000, 22000000, 0x00103f10 }, /* 1,64,2 */ | ||
72 | }; | ||
73 | |||
74 | enum wm0010_state { | ||
75 | WM0010_POWER_OFF, | ||
76 | WM0010_OUT_OF_RESET, | ||
77 | WM0010_BOOTROM, | ||
78 | WM0010_STAGE2, | ||
79 | WM0010_FIRMWARE, | ||
80 | }; | ||
81 | |||
82 | struct wm0010_priv { | ||
83 | struct snd_soc_codec *codec; | ||
84 | |||
85 | struct mutex lock; | ||
86 | struct device *dev; | ||
87 | |||
88 | struct wm0010_pdata pdata; | ||
89 | |||
90 | int gpio_reset; | ||
91 | int gpio_reset_value; | ||
92 | |||
93 | struct regulator_bulk_data core_supplies[2]; | ||
94 | struct regulator *dbvdd; | ||
95 | |||
96 | int sysclk; | ||
97 | |||
98 | enum wm0010_state state; | ||
99 | bool boot_failed; | ||
100 | int boot_done; | ||
101 | bool ready; | ||
102 | bool pll_running; | ||
103 | int max_spi_freq; | ||
104 | int board_max_spi_speed; | ||
105 | u32 pll_clkctrl1; | ||
106 | |||
107 | spinlock_t irq_lock; | ||
108 | int irq; | ||
109 | |||
110 | struct completion boot_completion; | ||
111 | }; | ||
112 | |||
113 | struct wm0010_spi_msg { | ||
114 | struct spi_message m; | ||
115 | struct spi_transfer t; | ||
116 | u8 *tx_buf; | ||
117 | u8 *rx_buf; | ||
118 | size_t len; | ||
119 | }; | ||
120 | |||
121 | static const struct snd_soc_dapm_widget wm0010_dapm_widgets[] = { | ||
122 | SND_SOC_DAPM_SUPPLY("CLKIN", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
123 | }; | ||
124 | |||
125 | static const struct snd_soc_dapm_route wm0010_dapm_routes[] = { | ||
126 | { "SDI2 Capture", NULL, "SDI1 Playback" }, | ||
127 | { "SDI1 Capture", NULL, "SDI2 Playback" }, | ||
128 | |||
129 | { "SDI1 Capture", NULL, "CLKIN" }, | ||
130 | { "SDI2 Capture", NULL, "CLKIN" }, | ||
131 | { "SDI1 Playback", NULL, "CLKIN" }, | ||
132 | { "SDI2 Playback", NULL, "CLKIN" }, | ||
133 | }; | ||
134 | |||
135 | static const char *wm0010_state_to_str(enum wm0010_state state) | ||
136 | { | ||
137 | const char *state_to_str[] = { | ||
138 | "Power off", | ||
139 | "Out of reset", | ||
140 | "Boot ROM", | ||
141 | "Stage2", | ||
142 | "Firmware" | ||
143 | }; | ||
144 | |||
145 | if (state < 0 || state >= ARRAY_SIZE(state_to_str)) | ||
146 | return "null"; | ||
147 | return state_to_str[state]; | ||
148 | } | ||
149 | |||
150 | /* Called with wm0010->lock held */ | ||
151 | static void wm0010_halt(struct snd_soc_codec *codec) | ||
152 | { | ||
153 | struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); | ||
154 | unsigned long flags; | ||
155 | enum wm0010_state state; | ||
156 | |||
157 | /* Fetch the wm0010 state */ | ||
158 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
159 | state = wm0010->state; | ||
160 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
161 | |||
162 | switch (state) { | ||
163 | case WM0010_POWER_OFF: | ||
164 | /* If there's nothing to do, bail out */ | ||
165 | return; | ||
166 | case WM0010_OUT_OF_RESET: | ||
167 | case WM0010_BOOTROM: | ||
168 | case WM0010_STAGE2: | ||
169 | case WM0010_FIRMWARE: | ||
170 | /* Remember to put chip back into reset */ | ||
171 | gpio_set_value(wm0010->gpio_reset, wm0010->gpio_reset_value); | ||
172 | /* Disable the regulators */ | ||
173 | regulator_disable(wm0010->dbvdd); | ||
174 | regulator_bulk_disable(ARRAY_SIZE(wm0010->core_supplies), | ||
175 | wm0010->core_supplies); | ||
176 | break; | ||
177 | } | ||
178 | |||
179 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
180 | wm0010->state = WM0010_POWER_OFF; | ||
181 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
182 | } | ||
183 | |||
184 | struct wm0010_boot_xfer { | ||
185 | struct list_head list; | ||
186 | struct snd_soc_codec *codec; | ||
187 | struct completion *done; | ||
188 | struct spi_message m; | ||
189 | struct spi_transfer t; | ||
190 | }; | ||
191 | |||
192 | /* Called with wm0010->lock held */ | ||
193 | static void wm0010_mark_boot_failure(struct wm0010_priv *wm0010) | ||
194 | { | ||
195 | enum wm0010_state state; | ||
196 | unsigned long flags; | ||
197 | |||
198 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
199 | state = wm0010->state; | ||
200 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
201 | |||
202 | dev_err(wm0010->dev, "Failed to transition from `%s' state to `%s' state\n", | ||
203 | wm0010_state_to_str(state), wm0010_state_to_str(state + 1)); | ||
204 | |||
205 | wm0010->boot_failed = true; | ||
206 | } | ||
207 | |||
208 | static void wm0010_boot_xfer_complete(void *data) | ||
209 | { | ||
210 | struct wm0010_boot_xfer *xfer = data; | ||
211 | struct snd_soc_codec *codec = xfer->codec; | ||
212 | struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); | ||
213 | u32 *out32 = xfer->t.rx_buf; | ||
214 | int i; | ||
215 | |||
216 | if (xfer->m.status != 0) { | ||
217 | dev_err(codec->dev, "SPI transfer failed: %d\n", | ||
218 | xfer->m.status); | ||
219 | wm0010_mark_boot_failure(wm0010); | ||
220 | if (xfer->done) | ||
221 | complete(xfer->done); | ||
222 | return; | ||
223 | } | ||
224 | |||
225 | for (i = 0; i < xfer->t.len / 4; i++) { | ||
226 | dev_dbg(codec->dev, "%d: %04x\n", i, out32[i]); | ||
227 | |||
228 | switch (be32_to_cpu(out32[i])) { | ||
229 | case 0xe0e0e0e0: | ||
230 | dev_err(codec->dev, | ||
231 | "%d: ROM error reported in stage 2\n", i); | ||
232 | wm0010_mark_boot_failure(wm0010); | ||
233 | break; | ||
234 | |||
235 | case 0x55555555: | ||
236 | if (wm0010->boot_done == 0) | ||
237 | break; | ||
238 | dev_err(codec->dev, | ||
239 | "%d: ROM bootloader running in stage 2\n", i); | ||
240 | wm0010_mark_boot_failure(wm0010); | ||
241 | break; | ||
242 | |||
243 | case 0x0fed0000: | ||
244 | dev_dbg(codec->dev, "Stage2 loader running\n"); | ||
245 | break; | ||
246 | |||
247 | case 0x0fed0007: | ||
248 | dev_dbg(codec->dev, "CODE_HDR packet received\n"); | ||
249 | break; | ||
250 | |||
251 | case 0x0fed0008: | ||
252 | dev_dbg(codec->dev, "CODE_DATA packet received\n"); | ||
253 | break; | ||
254 | |||
255 | case 0x0fed0009: | ||
256 | dev_dbg(codec->dev, "Download complete\n"); | ||
257 | break; | ||
258 | |||
259 | case 0x0fed000c: | ||
260 | dev_dbg(codec->dev, "Application start\n"); | ||
261 | break; | ||
262 | |||
263 | case 0x0fed000e: | ||
264 | dev_dbg(codec->dev, "PLL packet received\n"); | ||
265 | wm0010->pll_running = true; | ||
266 | break; | ||
267 | |||
268 | case 0x0fed0025: | ||
269 | dev_err(codec->dev, "Device reports image too long\n"); | ||
270 | wm0010_mark_boot_failure(wm0010); | ||
271 | break; | ||
272 | |||
273 | case 0x0fed002c: | ||
274 | dev_err(codec->dev, "Device reports bad SPI packet\n"); | ||
275 | wm0010_mark_boot_failure(wm0010); | ||
276 | break; | ||
277 | |||
278 | case 0x0fed0031: | ||
279 | dev_err(codec->dev, "Device reports SPI read overflow\n"); | ||
280 | wm0010_mark_boot_failure(wm0010); | ||
281 | break; | ||
282 | |||
283 | case 0x0fed0032: | ||
284 | dev_err(codec->dev, "Device reports SPI underclock\n"); | ||
285 | wm0010_mark_boot_failure(wm0010); | ||
286 | break; | ||
287 | |||
288 | case 0x0fed0033: | ||
289 | dev_err(codec->dev, "Device reports bad header packet\n"); | ||
290 | wm0010_mark_boot_failure(wm0010); | ||
291 | break; | ||
292 | |||
293 | case 0x0fed0034: | ||
294 | dev_err(codec->dev, "Device reports invalid packet type\n"); | ||
295 | wm0010_mark_boot_failure(wm0010); | ||
296 | break; | ||
297 | |||
298 | case 0x0fed0035: | ||
299 | dev_err(codec->dev, "Device reports data before header error\n"); | ||
300 | wm0010_mark_boot_failure(wm0010); | ||
301 | break; | ||
302 | |||
303 | case 0x0fed0038: | ||
304 | dev_err(codec->dev, "Device reports invalid PLL packet\n"); | ||
305 | break; | ||
306 | |||
307 | case 0x0fed003a: | ||
308 | dev_err(codec->dev, "Device reports packet alignment error\n"); | ||
309 | wm0010_mark_boot_failure(wm0010); | ||
310 | break; | ||
311 | |||
312 | default: | ||
313 | dev_err(codec->dev, "Unrecognised return 0x%x\n", | ||
314 | be32_to_cpu(out32[i])); | ||
315 | wm0010_mark_boot_failure(wm0010); | ||
316 | break; | ||
317 | } | ||
318 | |||
319 | if (wm0010->boot_failed) | ||
320 | break; | ||
321 | } | ||
322 | |||
323 | wm0010->boot_done++; | ||
324 | if (xfer->done) | ||
325 | complete(xfer->done); | ||
326 | } | ||
327 | |||
328 | static void byte_swap_64(u64 *data_in, u64 *data_out, u32 len) | ||
329 | { | ||
330 | int i; | ||
331 | |||
332 | for (i = 0; i < len / 8; i++) | ||
333 | data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i])); | ||
334 | } | ||
335 | |||
336 | static int wm0010_boot(struct snd_soc_codec *codec) | ||
337 | { | ||
338 | struct spi_device *spi = to_spi_device(codec->dev); | ||
339 | struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); | ||
340 | unsigned long flags; | ||
341 | struct list_head xfer_list; | ||
342 | struct wm0010_boot_xfer *xfer; | ||
343 | int ret; | ||
344 | struct completion done; | ||
345 | const struct firmware *fw; | ||
346 | const struct dfw_binrec *rec; | ||
347 | struct spi_message m; | ||
348 | struct spi_transfer t; | ||
349 | struct dfw_pllrec pll_rec; | ||
350 | u32 *img, *p; | ||
351 | u64 *img_swap; | ||
352 | u8 *out; | ||
353 | u32 len, offset; | ||
354 | int i; | ||
355 | |||
356 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
357 | if (wm0010->state != WM0010_POWER_OFF) | ||
358 | dev_warn(wm0010->dev, "DSP already powered up!\n"); | ||
359 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
360 | |||
361 | if (wm0010->sysclk > 26000000) { | ||
362 | dev_err(codec->dev, "Max DSP clock frequency is 26MHz\n"); | ||
363 | ret = -ECANCELED; | ||
364 | goto err; | ||
365 | } | ||
366 | |||
367 | INIT_LIST_HEAD(&xfer_list); | ||
368 | |||
369 | mutex_lock(&wm0010->lock); | ||
370 | wm0010->pll_running = false; | ||
371 | |||
372 | dev_dbg(codec->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq); | ||
373 | |||
374 | ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies), | ||
375 | wm0010->core_supplies); | ||
376 | if (ret != 0) { | ||
377 | dev_err(&spi->dev, "Failed to enable core supplies: %d\n", | ||
378 | ret); | ||
379 | mutex_unlock(&wm0010->lock); | ||
380 | goto err; | ||
381 | } | ||
382 | |||
383 | ret = regulator_enable(wm0010->dbvdd); | ||
384 | if (ret != 0) { | ||
385 | dev_err(&spi->dev, "Failed to enable DBVDD: %d\n", ret); | ||
386 | goto err_core; | ||
387 | } | ||
388 | |||
389 | /* Release reset */ | ||
390 | gpio_set_value(wm0010->gpio_reset, !wm0010->gpio_reset_value); | ||
391 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
392 | wm0010->state = WM0010_OUT_OF_RESET; | ||
393 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
394 | |||
395 | /* First the bootloader */ | ||
396 | ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev); | ||
397 | if (ret != 0) { | ||
398 | dev_err(codec->dev, "Failed to request stage2 loader: %d\n", | ||
399 | ret); | ||
400 | goto abort; | ||
401 | } | ||
402 | |||
403 | if (!wait_for_completion_timeout(&wm0010->boot_completion, | ||
404 | msecs_to_jiffies(10))) | ||
405 | dev_err(codec->dev, "Failed to get interrupt from DSP\n"); | ||
406 | |||
407 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
408 | wm0010->state = WM0010_BOOTROM; | ||
409 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
410 | |||
411 | dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size); | ||
412 | |||
413 | /* Copy to local buffer first as vmalloc causes problems for dma */ | ||
414 | img = kzalloc(fw->size, GFP_KERNEL); | ||
415 | if (!img) { | ||
416 | dev_err(codec->dev, "Failed to allocate image buffer\n"); | ||
417 | goto abort; | ||
418 | } | ||
419 | |||
420 | out = kzalloc(fw->size, GFP_KERNEL); | ||
421 | if (!out) { | ||
422 | dev_err(codec->dev, "Failed to allocate output buffer\n"); | ||
423 | goto abort; | ||
424 | } | ||
425 | |||
426 | memcpy(img, &fw->data[0], fw->size); | ||
427 | |||
428 | spi_message_init(&m); | ||
429 | memset(&t, 0, sizeof(t)); | ||
430 | t.rx_buf = out; | ||
431 | t.tx_buf = img; | ||
432 | t.len = fw->size; | ||
433 | t.bits_per_word = 8; | ||
434 | t.speed_hz = wm0010->sysclk / 10; | ||
435 | spi_message_add_tail(&t, &m); | ||
436 | |||
437 | dev_dbg(codec->dev, "Starting initial download at %dHz\n", | ||
438 | t.speed_hz); | ||
439 | |||
440 | ret = spi_sync(spi, &m); | ||
441 | if (ret != 0) { | ||
442 | dev_err(codec->dev, "Initial download failed: %d\n", ret); | ||
443 | goto abort; | ||
444 | } | ||
445 | |||
446 | /* Look for errors from the boot ROM */ | ||
447 | for (i = 0; i < fw->size; i++) { | ||
448 | if (out[i] != 0x55) { | ||
449 | ret = -EBUSY; | ||
450 | dev_err(codec->dev, "Boot ROM error: %x in %d\n", | ||
451 | out[i], i); | ||
452 | wm0010_mark_boot_failure(wm0010); | ||
453 | goto abort; | ||
454 | } | ||
455 | } | ||
456 | |||
457 | release_firmware(fw); | ||
458 | kfree(img); | ||
459 | kfree(out); | ||
460 | |||
461 | if (!wait_for_completion_timeout(&wm0010->boot_completion, | ||
462 | msecs_to_jiffies(10))) | ||
463 | dev_err(codec->dev, "Failed to get interrupt from DSP loader.\n"); | ||
464 | |||
465 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
466 | wm0010->state = WM0010_STAGE2; | ||
467 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
468 | |||
469 | /* Only initialise PLL if max_spi_freq initialised */ | ||
470 | if (wm0010->max_spi_freq) { | ||
471 | |||
472 | /* Initialise a PLL record */ | ||
473 | memset(&pll_rec, 0, sizeof(pll_rec)); | ||
474 | pll_rec.command = DFW_CMD_PLL; | ||
475 | pll_rec.length = (sizeof(pll_rec) - 8); | ||
476 | |||
477 | /* On wm0010 only the CLKCTRL1 value is used */ | ||
478 | pll_rec.clkctrl1 = wm0010->pll_clkctrl1; | ||
479 | |||
480 | len = pll_rec.length + 8; | ||
481 | out = kzalloc(len, GFP_KERNEL); | ||
482 | if (!out) { | ||
483 | dev_err(codec->dev, | ||
484 | "Failed to allocate RX buffer\n"); | ||
485 | goto abort; | ||
486 | } | ||
487 | |||
488 | img_swap = kzalloc(len, GFP_KERNEL); | ||
489 | if (!img_swap) { | ||
490 | dev_err(codec->dev, | ||
491 | "Failed to allocate image buffer\n"); | ||
492 | goto abort; | ||
493 | } | ||
494 | |||
495 | /* We need to re-order for 0010 */ | ||
496 | byte_swap_64((u64 *)&pll_rec, img_swap, len); | ||
497 | |||
498 | spi_message_init(&m); | ||
499 | memset(&t, 0, sizeof(t)); | ||
500 | t.rx_buf = out; | ||
501 | t.tx_buf = img_swap; | ||
502 | t.len = len; | ||
503 | t.bits_per_word = 8; | ||
504 | t.speed_hz = wm0010->sysclk / 6; | ||
505 | spi_message_add_tail(&t, &m); | ||
506 | |||
507 | ret = spi_sync(spi, &m); | ||
508 | if (ret != 0) { | ||
509 | dev_err(codec->dev, "First PLL write failed: %d\n", ret); | ||
510 | goto abort; | ||
511 | } | ||
512 | |||
513 | /* Use a second send of the message to get the return status */ | ||
514 | ret = spi_sync(spi, &m); | ||
515 | if (ret != 0) { | ||
516 | dev_err(codec->dev, "Second PLL write failed: %d\n", ret); | ||
517 | goto abort; | ||
518 | } | ||
519 | |||
520 | p = (u32 *)out; | ||
521 | |||
522 | /* Look for PLL active code from the DSP */ | ||
523 | for (i = 0; i < len / 4; i++) { | ||
524 | if (*p == 0x0e00ed0f) { | ||
525 | dev_dbg(codec->dev, "PLL packet received\n"); | ||
526 | wm0010->pll_running = true; | ||
527 | break; | ||
528 | } | ||
529 | p++; | ||
530 | } | ||
531 | |||
532 | kfree(img_swap); | ||
533 | kfree(out); | ||
534 | } else | ||
535 | dev_dbg(codec->dev, "Not enabling DSP PLL."); | ||
536 | |||
537 | ret = request_firmware(&fw, "wm0010.dfw", codec->dev); | ||
538 | if (ret != 0) { | ||
539 | dev_err(codec->dev, "Failed to request application: %d\n", | ||
540 | ret); | ||
541 | goto abort; | ||
542 | } | ||
543 | |||
544 | rec = (const struct dfw_binrec *)fw->data; | ||
545 | offset = 0; | ||
546 | wm0010->boot_done = 0; | ||
547 | wm0010->boot_failed = false; | ||
548 | BUG_ON(!list_empty(&xfer_list)); | ||
549 | init_completion(&done); | ||
550 | |||
551 | /* First record should be INFO */ | ||
552 | if (rec->command != DFW_CMD_INFO) { | ||
553 | dev_err(codec->dev, "First record not INFO\r\n"); | ||
554 | goto abort; | ||
555 | } | ||
556 | |||
557 | /* Check it's a 0010 file */ | ||
558 | if (rec->data[0] != DEVICE_ID_WM0010) { | ||
559 | dev_err(codec->dev, "Not a WM0010 firmware file.\r\n"); | ||
560 | goto abort; | ||
561 | } | ||
562 | |||
563 | /* Skip the info record as we don't need to send it */ | ||
564 | offset += ((rec->length) + 8); | ||
565 | rec = (void *)&rec->data[rec->length]; | ||
566 | |||
567 | while (offset < fw->size) { | ||
568 | dev_dbg(codec->dev, | ||
569 | "Packet: command %d, data length = 0x%x\r\n", | ||
570 | rec->command, rec->length); | ||
571 | len = rec->length + 8; | ||
572 | |||
573 | out = kzalloc(len, GFP_KERNEL); | ||
574 | if (!out) { | ||
575 | dev_err(codec->dev, | ||
576 | "Failed to allocate RX buffer\n"); | ||
577 | goto abort; | ||
578 | } | ||
579 | |||
580 | img_swap = kzalloc(len, GFP_KERNEL); | ||
581 | if (!img_swap) { | ||
582 | dev_err(codec->dev, | ||
583 | "Failed to allocate image buffer\n"); | ||
584 | goto abort; | ||
585 | } | ||
586 | |||
587 | /* We need to re-order for 0010 */ | ||
588 | byte_swap_64((u64 *)&rec->command, img_swap, len); | ||
589 | |||
590 | xfer = kzalloc(sizeof(*xfer), GFP_KERNEL); | ||
591 | if (!xfer) { | ||
592 | dev_err(codec->dev, "Failed to allocate xfer\n"); | ||
593 | goto abort; | ||
594 | } | ||
595 | |||
596 | xfer->codec = codec; | ||
597 | list_add_tail(&xfer->list, &xfer_list); | ||
598 | |||
599 | spi_message_init(&xfer->m); | ||
600 | xfer->m.complete = wm0010_boot_xfer_complete; | ||
601 | xfer->m.context = xfer; | ||
602 | xfer->t.tx_buf = img_swap; | ||
603 | xfer->t.rx_buf = out; | ||
604 | xfer->t.len = len; | ||
605 | xfer->t.bits_per_word = 8; | ||
606 | |||
607 | if (!wm0010->pll_running) { | ||
608 | xfer->t.speed_hz = wm0010->sysclk / 6; | ||
609 | } else { | ||
610 | xfer->t.speed_hz = wm0010->max_spi_freq; | ||
611 | |||
612 | if (wm0010->board_max_spi_speed && | ||
613 | (wm0010->board_max_spi_speed < wm0010->max_spi_freq)) | ||
614 | xfer->t.speed_hz = wm0010->board_max_spi_speed; | ||
615 | } | ||
616 | |||
617 | /* Store max usable spi frequency for later use */ | ||
618 | wm0010->max_spi_freq = xfer->t.speed_hz; | ||
619 | |||
620 | spi_message_add_tail(&xfer->t, &xfer->m); | ||
621 | |||
622 | offset += ((rec->length) + 8); | ||
623 | rec = (void *)&rec->data[rec->length]; | ||
624 | |||
625 | if (offset >= fw->size) { | ||
626 | dev_dbg(codec->dev, "All transfers scheduled\n"); | ||
627 | xfer->done = &done; | ||
628 | } | ||
629 | |||
630 | ret = spi_async(spi, &xfer->m); | ||
631 | if (ret != 0) { | ||
632 | dev_err(codec->dev, "Write failed: %d\n", ret); | ||
633 | goto abort; | ||
634 | } | ||
635 | |||
636 | if (wm0010->boot_failed) | ||
637 | goto abort; | ||
638 | } | ||
639 | |||
640 | wait_for_completion(&done); | ||
641 | |||
642 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
643 | wm0010->state = WM0010_FIRMWARE; | ||
644 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
645 | |||
646 | mutex_unlock(&wm0010->lock); | ||
647 | |||
648 | release_firmware(fw); | ||
649 | |||
650 | while (!list_empty(&xfer_list)) { | ||
651 | xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer, | ||
652 | list); | ||
653 | kfree(xfer->t.rx_buf); | ||
654 | kfree(xfer->t.tx_buf); | ||
655 | list_del(&xfer->list); | ||
656 | kfree(xfer); | ||
657 | } | ||
658 | |||
659 | return 0; | ||
660 | |||
661 | abort: | ||
662 | /* Put the chip back into reset */ | ||
663 | wm0010_halt(codec); | ||
664 | mutex_unlock(&wm0010->lock); | ||
665 | return ret; | ||
666 | |||
667 | err_core: | ||
668 | mutex_unlock(&wm0010->lock); | ||
669 | regulator_bulk_disable(ARRAY_SIZE(wm0010->core_supplies), | ||
670 | wm0010->core_supplies); | ||
671 | err: | ||
672 | return ret; | ||
673 | } | ||
674 | |||
675 | static int wm0010_set_bias_level(struct snd_soc_codec *codec, | ||
676 | enum snd_soc_bias_level level) | ||
677 | { | ||
678 | struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); | ||
679 | |||
680 | switch (level) { | ||
681 | case SND_SOC_BIAS_ON: | ||
682 | if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) | ||
683 | wm0010_boot(codec); | ||
684 | break; | ||
685 | case SND_SOC_BIAS_PREPARE: | ||
686 | break; | ||
687 | case SND_SOC_BIAS_STANDBY: | ||
688 | if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) { | ||
689 | mutex_lock(&wm0010->lock); | ||
690 | wm0010_halt(codec); | ||
691 | mutex_unlock(&wm0010->lock); | ||
692 | } | ||
693 | break; | ||
694 | case SND_SOC_BIAS_OFF: | ||
695 | break; | ||
696 | } | ||
697 | |||
698 | codec->dapm.bias_level = level; | ||
699 | |||
700 | return 0; | ||
701 | } | ||
702 | |||
703 | static int wm0010_set_sysclk(struct snd_soc_codec *codec, int source, | ||
704 | int clk_id, unsigned int freq, int dir) | ||
705 | { | ||
706 | struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); | ||
707 | unsigned int i; | ||
708 | |||
709 | wm0010->sysclk = freq; | ||
710 | |||
711 | if (freq < pll_clock_map[ARRAY_SIZE(pll_clock_map)-1].max_sysclk) { | ||
712 | wm0010->max_spi_freq = 0; | ||
713 | } else { | ||
714 | for (i = 0; i < ARRAY_SIZE(pll_clock_map); i++) | ||
715 | if (freq >= pll_clock_map[i].max_sysclk) | ||
716 | break; | ||
717 | |||
718 | wm0010->max_spi_freq = pll_clock_map[i].max_pll_spi_speed; | ||
719 | wm0010->pll_clkctrl1 = pll_clock_map[i].pll_clkctrl1; | ||
720 | } | ||
721 | |||
722 | return 0; | ||
723 | } | ||
724 | |||
725 | static int wm0010_probe(struct snd_soc_codec *codec); | ||
726 | |||
727 | static struct snd_soc_codec_driver soc_codec_dev_wm0010 = { | ||
728 | .probe = wm0010_probe, | ||
729 | .set_bias_level = wm0010_set_bias_level, | ||
730 | .set_sysclk = wm0010_set_sysclk, | ||
731 | .idle_bias_off = true, | ||
732 | |||
733 | .dapm_widgets = wm0010_dapm_widgets, | ||
734 | .num_dapm_widgets = ARRAY_SIZE(wm0010_dapm_widgets), | ||
735 | .dapm_routes = wm0010_dapm_routes, | ||
736 | .num_dapm_routes = ARRAY_SIZE(wm0010_dapm_routes), | ||
737 | }; | ||
738 | |||
739 | #define WM0010_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) | ||
740 | #define WM0010_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ | ||
741 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\ | ||
742 | SNDRV_PCM_FMTBIT_S32_LE) | ||
743 | |||
744 | static struct snd_soc_dai_driver wm0010_dai[] = { | ||
745 | { | ||
746 | .name = "wm0010-sdi1", | ||
747 | .playback = { | ||
748 | .stream_name = "SDI1 Playback", | ||
749 | .channels_min = 1, | ||
750 | .channels_max = 2, | ||
751 | .rates = WM0010_RATES, | ||
752 | .formats = WM0010_FORMATS, | ||
753 | }, | ||
754 | .capture = { | ||
755 | .stream_name = "SDI1 Capture", | ||
756 | .channels_min = 1, | ||
757 | .channels_max = 2, | ||
758 | .rates = WM0010_RATES, | ||
759 | .formats = WM0010_FORMATS, | ||
760 | }, | ||
761 | }, | ||
762 | { | ||
763 | .name = "wm0010-sdi2", | ||
764 | .playback = { | ||
765 | .stream_name = "SDI2 Playback", | ||
766 | .channels_min = 1, | ||
767 | .channels_max = 2, | ||
768 | .rates = WM0010_RATES, | ||
769 | .formats = WM0010_FORMATS, | ||
770 | }, | ||
771 | .capture = { | ||
772 | .stream_name = "SDI2 Capture", | ||
773 | .channels_min = 1, | ||
774 | .channels_max = 2, | ||
775 | .rates = WM0010_RATES, | ||
776 | .formats = WM0010_FORMATS, | ||
777 | }, | ||
778 | }, | ||
779 | }; | ||
780 | |||
781 | static irqreturn_t wm0010_irq(int irq, void *data) | ||
782 | { | ||
783 | struct wm0010_priv *wm0010 = data; | ||
784 | |||
785 | switch (wm0010->state) { | ||
786 | case WM0010_POWER_OFF: | ||
787 | case WM0010_OUT_OF_RESET: | ||
788 | case WM0010_BOOTROM: | ||
789 | case WM0010_STAGE2: | ||
790 | spin_lock(&wm0010->irq_lock); | ||
791 | complete(&wm0010->boot_completion); | ||
792 | spin_unlock(&wm0010->irq_lock); | ||
793 | return IRQ_HANDLED; | ||
794 | default: | ||
795 | return IRQ_NONE; | ||
796 | } | ||
797 | |||
798 | return IRQ_NONE; | ||
799 | } | ||
800 | |||
801 | static int wm0010_probe(struct snd_soc_codec *codec) | ||
802 | { | ||
803 | struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); | ||
804 | |||
805 | wm0010->codec = codec; | ||
806 | |||
807 | return 0; | ||
808 | } | ||
809 | |||
810 | static int __devinit wm0010_spi_probe(struct spi_device *spi) | ||
811 | { | ||
812 | unsigned long flags; | ||
813 | unsigned long gpio_flags; | ||
814 | int ret; | ||
815 | int trigger; | ||
816 | int irq; | ||
817 | struct wm0010_priv *wm0010; | ||
818 | |||
819 | wm0010 = devm_kzalloc(&spi->dev, sizeof(*wm0010), | ||
820 | GFP_KERNEL); | ||
821 | if (!wm0010) | ||
822 | return -ENOMEM; | ||
823 | |||
824 | mutex_init(&wm0010->lock); | ||
825 | spin_lock_init(&wm0010->irq_lock); | ||
826 | |||
827 | spi_set_drvdata(spi, wm0010); | ||
828 | wm0010->dev = &spi->dev; | ||
829 | |||
830 | if (dev_get_platdata(&spi->dev)) | ||
831 | memcpy(&wm0010->pdata, dev_get_platdata(&spi->dev), | ||
832 | sizeof(wm0010->pdata)); | ||
833 | |||
834 | init_completion(&wm0010->boot_completion); | ||
835 | |||
836 | wm0010->core_supplies[0].supply = "AVDD"; | ||
837 | wm0010->core_supplies[1].supply = "DCVDD"; | ||
838 | ret = devm_regulator_bulk_get(wm0010->dev, ARRAY_SIZE(wm0010->core_supplies), | ||
839 | wm0010->core_supplies); | ||
840 | if (ret != 0) { | ||
841 | dev_err(wm0010->dev, "Failed to obtain core supplies: %d\n", | ||
842 | ret); | ||
843 | return ret; | ||
844 | } | ||
845 | |||
846 | wm0010->dbvdd = devm_regulator_get(wm0010->dev, "DBVDD"); | ||
847 | if (IS_ERR(wm0010->dbvdd)) { | ||
848 | ret = PTR_ERR(wm0010->dbvdd); | ||
849 | dev_err(wm0010->dev, "Failed to obtain DBVDD: %d\n", ret); | ||
850 | return ret; | ||
851 | } | ||
852 | |||
853 | if (wm0010->pdata.gpio_reset) { | ||
854 | wm0010->gpio_reset = wm0010->pdata.gpio_reset; | ||
855 | |||
856 | if (wm0010->pdata.reset_active_high) | ||
857 | wm0010->gpio_reset_value = 1; | ||
858 | else | ||
859 | wm0010->gpio_reset_value = 0; | ||
860 | |||
861 | if (wm0010->gpio_reset_value) | ||
862 | gpio_flags = GPIOF_OUT_INIT_HIGH; | ||
863 | else | ||
864 | gpio_flags = GPIOF_OUT_INIT_LOW; | ||
865 | |||
866 | ret = devm_gpio_request_one(wm0010->dev, wm0010->gpio_reset, | ||
867 | gpio_flags, "wm0010 reset"); | ||
868 | if (ret < 0) { | ||
869 | dev_err(wm0010->dev, | ||
870 | "Failed to request GPIO for DSP reset: %d\n", | ||
871 | ret); | ||
872 | return ret; | ||
873 | } | ||
874 | } else { | ||
875 | dev_err(wm0010->dev, "No reset GPIO configured\n"); | ||
876 | return -EINVAL; | ||
877 | } | ||
878 | |||
879 | irq = spi->irq; | ||
880 | if (wm0010->pdata.irq_flags) | ||
881 | trigger = wm0010->pdata.irq_flags; | ||
882 | else | ||
883 | trigger = IRQF_TRIGGER_FALLING; | ||
884 | trigger |= IRQF_ONESHOT; | ||
885 | |||
886 | ret = request_threaded_irq(irq, NULL, wm0010_irq, trigger | IRQF_ONESHOT, | ||
887 | "wm0010", wm0010); | ||
888 | if (ret) { | ||
889 | dev_err(wm0010->dev, "Failed to request IRQ %d: %d\n", | ||
890 | irq, ret); | ||
891 | return ret; | ||
892 | } | ||
893 | wm0010->irq = irq; | ||
894 | |||
895 | if (spi->max_speed_hz) | ||
896 | wm0010->board_max_spi_speed = spi->max_speed_hz; | ||
897 | else | ||
898 | wm0010->board_max_spi_speed = 0; | ||
899 | |||
900 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
901 | wm0010->state = WM0010_POWER_OFF; | ||
902 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
903 | |||
904 | ret = snd_soc_register_codec(&spi->dev, | ||
905 | &soc_codec_dev_wm0010, wm0010_dai, | ||
906 | ARRAY_SIZE(wm0010_dai)); | ||
907 | if (ret < 0) | ||
908 | return ret; | ||
909 | |||
910 | return 0; | ||
911 | } | ||
912 | |||
913 | static int __devexit wm0010_spi_remove(struct spi_device *spi) | ||
914 | { | ||
915 | struct wm0010_priv *wm0010 = spi_get_drvdata(spi); | ||
916 | |||
917 | snd_soc_unregister_codec(&spi->dev); | ||
918 | |||
919 | if (wm0010->gpio_reset) { | ||
920 | /* Remember to put chip back into reset */ | ||
921 | gpio_set_value(wm0010->gpio_reset, wm0010->gpio_reset_value); | ||
922 | } | ||
923 | |||
924 | if (wm0010->irq) | ||
925 | free_irq(wm0010->irq, wm0010); | ||
926 | |||
927 | return 0; | ||
928 | } | ||
929 | |||
930 | static struct spi_driver wm0010_spi_driver = { | ||
931 | .driver = { | ||
932 | .name = "wm0010", | ||
933 | .bus = &spi_bus_type, | ||
934 | .owner = THIS_MODULE, | ||
935 | }, | ||
936 | .probe = wm0010_spi_probe, | ||
937 | .remove = __devexit_p(wm0010_spi_remove), | ||
938 | }; | ||
939 | |||
940 | module_spi_driver(wm0010_spi_driver); | ||
941 | |||
942 | MODULE_DESCRIPTION("ASoC WM0010 driver"); | ||
943 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
944 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 3fd5b29dc933..89cd6fcad015 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -858,17 +858,7 @@ static struct i2c_driver wm2000_i2c_driver = { | |||
858 | .id_table = wm2000_i2c_id, | 858 | .id_table = wm2000_i2c_id, |
859 | }; | 859 | }; |
860 | 860 | ||
861 | static int __init wm2000_init(void) | 861 | module_i2c_driver(wm2000_i2c_driver); |
862 | { | ||
863 | return i2c_add_driver(&wm2000_i2c_driver); | ||
864 | } | ||
865 | module_init(wm2000_init); | ||
866 | |||
867 | static void __exit wm2000_exit(void) | ||
868 | { | ||
869 | i2c_del_driver(&wm2000_i2c_driver); | ||
870 | } | ||
871 | module_exit(wm2000_exit); | ||
872 | 862 | ||
873 | MODULE_DESCRIPTION("ASoC WM2000 driver"); | 863 | MODULE_DESCRIPTION("ASoC WM2000 driver"); |
874 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>"); | 864 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>"); |
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index 32682c1b7cde..efa93dbb0191 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c | |||
@@ -1117,8 +1117,8 @@ SND_SOC_DAPM_SUPPLY("MICBIAS1", WM2200_MIC_BIAS_CTRL_1, WM2200_MICB1_ENA_SHIFT, | |||
1117 | 0, NULL, 0), | 1117 | 0, NULL, 0), |
1118 | SND_SOC_DAPM_SUPPLY("MICBIAS2", WM2200_MIC_BIAS_CTRL_2, WM2200_MICB2_ENA_SHIFT, | 1118 | SND_SOC_DAPM_SUPPLY("MICBIAS2", WM2200_MIC_BIAS_CTRL_2, WM2200_MICB2_ENA_SHIFT, |
1119 | 0, NULL, 0), | 1119 | 0, NULL, 0), |
1120 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20), | 1120 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0), |
1121 | SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 20), | 1121 | SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 20, 0), |
1122 | 1122 | ||
1123 | SND_SOC_DAPM_INPUT("IN1L"), | 1123 | SND_SOC_DAPM_INPUT("IN1L"), |
1124 | SND_SOC_DAPM_INPUT("IN1R"), | 1124 | SND_SOC_DAPM_INPUT("IN1R"), |
@@ -2270,17 +2270,7 @@ static struct i2c_driver wm2200_i2c_driver = { | |||
2270 | .id_table = wm2200_i2c_id, | 2270 | .id_table = wm2200_i2c_id, |
2271 | }; | 2271 | }; |
2272 | 2272 | ||
2273 | static int __init wm2200_modinit(void) | 2273 | module_i2c_driver(wm2200_i2c_driver); |
2274 | { | ||
2275 | return i2c_add_driver(&wm2200_i2c_driver); | ||
2276 | } | ||
2277 | module_init(wm2200_modinit); | ||
2278 | |||
2279 | static void __exit wm2200_exit(void) | ||
2280 | { | ||
2281 | i2c_del_driver(&wm2200_i2c_driver); | ||
2282 | } | ||
2283 | module_exit(wm2200_exit); | ||
2284 | 2274 | ||
2285 | MODULE_DESCRIPTION("ASoC WM2200 driver"); | 2275 | MODULE_DESCRIPTION("ASoC WM2200 driver"); |
2286 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 2276 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index f4817292ef45..4da1b92b22c2 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c | |||
@@ -848,9 +848,9 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", WM5100_CLOCKING_3, WM5100_SYSCLK_ENA_SHIFT, 0, | |||
848 | SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT, | 848 | SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT, |
849 | 0, NULL, 0), | 849 | 0, NULL, 0), |
850 | 850 | ||
851 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20), | 851 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0), |
852 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0), | 852 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0), |
853 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0), | 853 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0), |
854 | 854 | ||
855 | SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0, | 855 | SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0, |
856 | NULL, 0), | 856 | NULL, 0), |
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index e33d327396ad..4a2db4e10885 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
@@ -274,18 +274,43 @@ ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); | |||
274 | ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); | 274 | ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); |
275 | ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); | 275 | ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); |
276 | 276 | ||
277 | |||
278 | static const char *wm5102_aec_loopback_texts[] = { | ||
279 | "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT", | ||
280 | "SPKOUTL", "SPKOUTR", "SPKDAT1L", "SPKDAT1R", | ||
281 | }; | ||
282 | |||
283 | static const unsigned int wm5102_aec_loopback_values[] = { | ||
284 | 0, 1, 2, 3, 4, 6, 7, 8, 9, | ||
285 | }; | ||
286 | |||
287 | static const struct soc_enum wm5102_aec_loopback = | ||
288 | SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1, | ||
289 | ARIZONA_AEC_LOOPBACK_SRC_SHIFT, | ||
290 | ARIZONA_AEC_LOOPBACK_SRC_MASK, | ||
291 | ARRAY_SIZE(wm5102_aec_loopback_texts), | ||
292 | wm5102_aec_loopback_texts, | ||
293 | wm5102_aec_loopback_values); | ||
294 | |||
295 | static const struct snd_kcontrol_new wm5102_aec_loopback_mux = | ||
296 | SOC_DAPM_VALUE_ENUM("AEC Loopback", wm5102_aec_loopback); | ||
297 | |||
277 | static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { | 298 | static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { |
278 | SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, | 299 | SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, |
279 | 0, NULL, 0), | 300 | 0, NULL, 0), |
280 | SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, | 301 | SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, |
281 | ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), | 302 | ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), |
282 | 303 | SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK, | |
283 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0), | 304 | ARIZONA_OPCLK_ENA_SHIFT, 0, NULL, 0), |
284 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0), | 305 | SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK, |
285 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20), | 306 | ARIZONA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0), |
286 | SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0), | 307 | |
287 | SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0), | 308 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0), |
288 | SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0), | 309 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0), |
310 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0), | ||
311 | SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, 0), | ||
312 | SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0, 0), | ||
313 | SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0), | ||
289 | 314 | ||
290 | SND_SOC_DAPM_SIGGEN("TONE"), | 315 | SND_SOC_DAPM_SIGGEN("TONE"), |
291 | SND_SOC_DAPM_SIGGEN("NOISE"), | 316 | SND_SOC_DAPM_SIGGEN("NOISE"), |
@@ -421,6 +446,9 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0, | |||
421 | SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, | 446 | SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, |
422 | ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), | 447 | ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), |
423 | 448 | ||
449 | SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, | ||
450 | ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), | ||
451 | |||
424 | SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1, | 452 | SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1, |
425 | ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 453 | ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
426 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 454 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
@@ -516,6 +544,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"), | |||
516 | { name, "Noise Generator", "Noise Generator" }, \ | 544 | { name, "Noise Generator", "Noise Generator" }, \ |
517 | { name, "Tone Generator 1", "Tone Generator 1" }, \ | 545 | { name, "Tone Generator 1", "Tone Generator 1" }, \ |
518 | { name, "Tone Generator 2", "Tone Generator 2" }, \ | 546 | { name, "Tone Generator 2", "Tone Generator 2" }, \ |
547 | { name, "AEC", "AEC Loopback" }, \ | ||
519 | { name, "IN1L", "IN1L PGA" }, \ | 548 | { name, "IN1L", "IN1L PGA" }, \ |
520 | { name, "IN1R", "IN1R PGA" }, \ | 549 | { name, "IN1R", "IN1R PGA" }, \ |
521 | { name, "IN2L", "IN2L PGA" }, \ | 550 | { name, "IN2L", "IN2L PGA" }, \ |
@@ -681,21 +710,30 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { | |||
681 | ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"), | 710 | ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"), |
682 | ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"), | 711 | ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"), |
683 | 712 | ||
713 | { "AEC Loopback", "HPOUT1L", "OUT1L" }, | ||
714 | { "AEC Loopback", "HPOUT1R", "OUT1R" }, | ||
684 | { "HPOUT1L", NULL, "OUT1L" }, | 715 | { "HPOUT1L", NULL, "OUT1L" }, |
685 | { "HPOUT1R", NULL, "OUT1R" }, | 716 | { "HPOUT1R", NULL, "OUT1R" }, |
686 | 717 | ||
718 | { "AEC Loopback", "HPOUT2L", "OUT2L" }, | ||
719 | { "AEC Loopback", "HPOUT2R", "OUT2R" }, | ||
687 | { "HPOUT2L", NULL, "OUT2L" }, | 720 | { "HPOUT2L", NULL, "OUT2L" }, |
688 | { "HPOUT2R", NULL, "OUT2R" }, | 721 | { "HPOUT2R", NULL, "OUT2R" }, |
689 | 722 | ||
723 | { "AEC Loopback", "EPOUT", "OUT3L" }, | ||
690 | { "EPOUTN", NULL, "OUT3L" }, | 724 | { "EPOUTN", NULL, "OUT3L" }, |
691 | { "EPOUTP", NULL, "OUT3L" }, | 725 | { "EPOUTP", NULL, "OUT3L" }, |
692 | 726 | ||
727 | { "AEC Loopback", "SPKOUTL", "OUT4L" }, | ||
693 | { "SPKOUTLN", NULL, "OUT4L" }, | 728 | { "SPKOUTLN", NULL, "OUT4L" }, |
694 | { "SPKOUTLP", NULL, "OUT4L" }, | 729 | { "SPKOUTLP", NULL, "OUT4L" }, |
695 | 730 | ||
731 | { "AEC Loopback", "SPKOUTR", "OUT4R" }, | ||
696 | { "SPKOUTRN", NULL, "OUT4R" }, | 732 | { "SPKOUTRN", NULL, "OUT4R" }, |
697 | { "SPKOUTRP", NULL, "OUT4R" }, | 733 | { "SPKOUTRP", NULL, "OUT4R" }, |
698 | 734 | ||
735 | { "AEC Loopback", "SPKDAT1L", "OUT5L" }, | ||
736 | { "AEC Loopback", "SPKDAT1R", "OUT5R" }, | ||
699 | { "SPKDAT1L", NULL, "OUT5L" }, | 737 | { "SPKDAT1L", NULL, "OUT5L" }, |
700 | { "SPKDAT1R", NULL, "OUT5R" }, | 738 | { "SPKDAT1R", NULL, "OUT5R" }, |
701 | }; | 739 | }; |
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 01ebbcc5c6a4..bf47914234b3 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
@@ -305,13 +305,17 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, | |||
305 | 0, NULL, 0), | 305 | 0, NULL, 0), |
306 | SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, | 306 | SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, |
307 | ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), | 307 | ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), |
308 | 308 | SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK, | |
309 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0), | 309 | ARIZONA_OPCLK_ENA_SHIFT, 0, NULL, 0), |
310 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0), | 310 | SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK, |
311 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20), | 311 | ARIZONA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0), |
312 | SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0), | 312 | |
313 | SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0), | 313 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0), |
314 | SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0), | 314 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0), |
315 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0), | ||
316 | SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, 0), | ||
317 | SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0, 0), | ||
318 | SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0), | ||
315 | 319 | ||
316 | SND_SOC_DAPM_SIGGEN("TONE"), | 320 | SND_SOC_DAPM_SIGGEN("TONE"), |
317 | SND_SOC_DAPM_SIGGEN("NOISE"), | 321 | SND_SOC_DAPM_SIGGEN("NOISE"), |
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 56a049555e2c..c12a54e72e89 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/of_device.h> | 22 | #include <linux/of_device.h> |
23 | #include <linux/regmap.h> | ||
23 | #include <sound/core.h> | 24 | #include <sound/core.h> |
24 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
25 | #include <sound/pcm_params.h> | 26 | #include <sound/pcm_params.h> |
@@ -33,24 +34,75 @@ | |||
33 | * We can't read the WM8510 register space when we are | 34 | * We can't read the WM8510 register space when we are |
34 | * using 2 wire for device control, so we cache them instead. | 35 | * using 2 wire for device control, so we cache them instead. |
35 | */ | 36 | */ |
36 | static const u16 wm8510_reg[WM8510_CACHEREGNUM] = { | 37 | static const struct reg_default wm8510_reg_defaults[] = { |
37 | 0x0000, 0x0000, 0x0000, 0x0000, | 38 | { 1, 0x0000 }, |
38 | 0x0050, 0x0000, 0x0140, 0x0000, | 39 | { 2, 0x0000 }, |
39 | 0x0000, 0x0000, 0x0000, 0x00ff, | 40 | { 3, 0x0000 }, |
40 | 0x0000, 0x0000, 0x0100, 0x00ff, | 41 | { 4, 0x0050 }, |
41 | 0x0000, 0x0000, 0x012c, 0x002c, | 42 | { 5, 0x0000 }, |
42 | 0x002c, 0x002c, 0x002c, 0x0000, | 43 | { 6, 0x0140 }, |
43 | 0x0032, 0x0000, 0x0000, 0x0000, | 44 | { 7, 0x0000 }, |
44 | 0x0000, 0x0000, 0x0000, 0x0000, | 45 | { 8, 0x0000 }, |
45 | 0x0038, 0x000b, 0x0032, 0x0000, | 46 | { 9, 0x0000 }, |
46 | 0x0008, 0x000c, 0x0093, 0x00e9, | 47 | { 10, 0x0000 }, |
47 | 0x0000, 0x0000, 0x0000, 0x0000, | 48 | { 11, 0x00ff }, |
48 | 0x0003, 0x0010, 0x0000, 0x0000, | 49 | { 12, 0x0000 }, |
49 | 0x0000, 0x0002, 0x0001, 0x0000, | 50 | { 13, 0x0000 }, |
50 | 0x0000, 0x0000, 0x0039, 0x0000, | 51 | { 14, 0x0100 }, |
51 | 0x0001, | 52 | { 15, 0x00ff }, |
53 | { 16, 0x0000 }, | ||
54 | { 17, 0x0000 }, | ||
55 | { 18, 0x012c }, | ||
56 | { 19, 0x002c }, | ||
57 | { 20, 0x002c }, | ||
58 | { 21, 0x002c }, | ||
59 | { 22, 0x002c }, | ||
60 | { 23, 0x0000 }, | ||
61 | { 24, 0x0032 }, | ||
62 | { 25, 0x0000 }, | ||
63 | { 26, 0x0000 }, | ||
64 | { 27, 0x0000 }, | ||
65 | { 28, 0x0000 }, | ||
66 | { 29, 0x0000 }, | ||
67 | { 30, 0x0000 }, | ||
68 | { 31, 0x0000 }, | ||
69 | { 32, 0x0038 }, | ||
70 | { 33, 0x000b }, | ||
71 | { 34, 0x0032 }, | ||
72 | { 35, 0x0000 }, | ||
73 | { 36, 0x0008 }, | ||
74 | { 37, 0x000c }, | ||
75 | { 38, 0x0093 }, | ||
76 | { 39, 0x00e9 }, | ||
77 | { 40, 0x0000 }, | ||
78 | { 41, 0x0000 }, | ||
79 | { 42, 0x0000 }, | ||
80 | { 43, 0x0000 }, | ||
81 | { 44, 0x0003 }, | ||
82 | { 45, 0x0010 }, | ||
83 | { 46, 0x0000 }, | ||
84 | { 47, 0x0000 }, | ||
85 | { 48, 0x0000 }, | ||
86 | { 49, 0x0002 }, | ||
87 | { 50, 0x0001 }, | ||
88 | { 51, 0x0000 }, | ||
89 | { 52, 0x0000 }, | ||
90 | { 53, 0x0000 }, | ||
91 | { 54, 0x0039 }, | ||
92 | { 55, 0x0000 }, | ||
93 | { 56, 0x0001 }, | ||
52 | }; | 94 | }; |
53 | 95 | ||
96 | static bool wm8510_volatile(struct device *dev, unsigned int reg) | ||
97 | { | ||
98 | switch (reg) { | ||
99 | case WM8510_RESET: | ||
100 | return true; | ||
101 | default: | ||
102 | return false; | ||
103 | } | ||
104 | } | ||
105 | |||
54 | #define WM8510_POWER1_BIASEN 0x08 | 106 | #define WM8510_POWER1_BIASEN 0x08 |
55 | #define WM8510_POWER1_BUFIOEN 0x10 | 107 | #define WM8510_POWER1_BUFIOEN 0x10 |
56 | 108 | ||
@@ -58,7 +110,7 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = { | |||
58 | 110 | ||
59 | /* codec private data */ | 111 | /* codec private data */ |
60 | struct wm8510_priv { | 112 | struct wm8510_priv { |
61 | enum snd_soc_control_type control_type; | 113 | struct regmap *regmap; |
62 | }; | 114 | }; |
63 | 115 | ||
64 | static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" }; | 116 | static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" }; |
@@ -454,6 +506,7 @@ static int wm8510_mute(struct snd_soc_dai *dai, int mute) | |||
454 | static int wm8510_set_bias_level(struct snd_soc_codec *codec, | 506 | static int wm8510_set_bias_level(struct snd_soc_codec *codec, |
455 | enum snd_soc_bias_level level) | 507 | enum snd_soc_bias_level level) |
456 | { | 508 | { |
509 | struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec); | ||
457 | u16 power1 = snd_soc_read(codec, WM8510_POWER1) & ~0x3; | 510 | u16 power1 = snd_soc_read(codec, WM8510_POWER1) & ~0x3; |
458 | 511 | ||
459 | switch (level) { | 512 | switch (level) { |
@@ -467,7 +520,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec, | |||
467 | power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN; | 520 | power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN; |
468 | 521 | ||
469 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 522 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
470 | snd_soc_cache_sync(codec); | 523 | regcache_sync(wm8510->regmap); |
471 | 524 | ||
472 | /* Initial cap charge at VMID 5k */ | 525 | /* Initial cap charge at VMID 5k */ |
473 | snd_soc_write(codec, WM8510_POWER1, power1 | 0x3); | 526 | snd_soc_write(codec, WM8510_POWER1, power1 | 0x3); |
@@ -536,10 +589,9 @@ static int wm8510_resume(struct snd_soc_codec *codec) | |||
536 | 589 | ||
537 | static int wm8510_probe(struct snd_soc_codec *codec) | 590 | static int wm8510_probe(struct snd_soc_codec *codec) |
538 | { | 591 | { |
539 | struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec); | ||
540 | int ret; | 592 | int ret; |
541 | 593 | ||
542 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8510->control_type); | 594 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
543 | if (ret < 0) { | 595 | if (ret < 0) { |
544 | printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n", ret); | 596 | printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n", ret); |
545 | return ret; | 597 | return ret; |
@@ -569,9 +621,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8510 = { | |||
569 | .suspend = wm8510_suspend, | 621 | .suspend = wm8510_suspend, |
570 | .resume = wm8510_resume, | 622 | .resume = wm8510_resume, |
571 | .set_bias_level = wm8510_set_bias_level, | 623 | .set_bias_level = wm8510_set_bias_level, |
572 | .reg_cache_size = ARRAY_SIZE(wm8510_reg), | ||
573 | .reg_word_size = sizeof(u16), | ||
574 | .reg_cache_default =wm8510_reg, | ||
575 | 624 | ||
576 | .controls = wm8510_snd_controls, | 625 | .controls = wm8510_snd_controls, |
577 | .num_controls = ARRAY_SIZE(wm8510_snd_controls), | 626 | .num_controls = ARRAY_SIZE(wm8510_snd_controls), |
@@ -586,23 +635,38 @@ static const struct of_device_id wm8510_of_match[] = { | |||
586 | { }, | 635 | { }, |
587 | }; | 636 | }; |
588 | 637 | ||
638 | static const struct regmap_config wm8510_regmap = { | ||
639 | .reg_bits = 7, | ||
640 | .val_bits = 9, | ||
641 | .max_register = WM8510_MONOMIX, | ||
642 | |||
643 | .reg_defaults = wm8510_reg_defaults, | ||
644 | .num_reg_defaults = ARRAY_SIZE(wm8510_reg_defaults), | ||
645 | .cache_type = REGCACHE_RBTREE, | ||
646 | |||
647 | .volatile_reg = wm8510_volatile, | ||
648 | }; | ||
649 | |||
589 | #if defined(CONFIG_SPI_MASTER) | 650 | #if defined(CONFIG_SPI_MASTER) |
590 | static int __devinit wm8510_spi_probe(struct spi_device *spi) | 651 | static int __devinit wm8510_spi_probe(struct spi_device *spi) |
591 | { | 652 | { |
592 | struct wm8510_priv *wm8510; | 653 | struct wm8510_priv *wm8510; |
593 | int ret; | 654 | int ret; |
594 | 655 | ||
595 | wm8510 = kzalloc(sizeof(struct wm8510_priv), GFP_KERNEL); | 656 | wm8510 = devm_kzalloc(&spi->dev, sizeof(struct wm8510_priv), |
657 | GFP_KERNEL); | ||
596 | if (wm8510 == NULL) | 658 | if (wm8510 == NULL) |
597 | return -ENOMEM; | 659 | return -ENOMEM; |
598 | 660 | ||
599 | wm8510->control_type = SND_SOC_SPI; | 661 | wm8510->regmap = devm_regmap_init_spi(spi, &wm8510_regmap); |
662 | if (IS_ERR(wm8510->regmap)) | ||
663 | return PTR_ERR(wm8510->regmap); | ||
664 | |||
600 | spi_set_drvdata(spi, wm8510); | 665 | spi_set_drvdata(spi, wm8510); |
601 | 666 | ||
602 | ret = snd_soc_register_codec(&spi->dev, | 667 | ret = snd_soc_register_codec(&spi->dev, |
603 | &soc_codec_dev_wm8510, &wm8510_dai, 1); | 668 | &soc_codec_dev_wm8510, &wm8510_dai, 1); |
604 | if (ret < 0) | 669 | |
605 | kfree(wm8510); | ||
606 | return ret; | 670 | return ret; |
607 | } | 671 | } |
608 | 672 | ||
@@ -630,17 +694,20 @@ static __devinit int wm8510_i2c_probe(struct i2c_client *i2c, | |||
630 | struct wm8510_priv *wm8510; | 694 | struct wm8510_priv *wm8510; |
631 | int ret; | 695 | int ret; |
632 | 696 | ||
633 | wm8510 = kzalloc(sizeof(struct wm8510_priv), GFP_KERNEL); | 697 | wm8510 = devm_kzalloc(&i2c->dev, sizeof(struct wm8510_priv), |
698 | GFP_KERNEL); | ||
634 | if (wm8510 == NULL) | 699 | if (wm8510 == NULL) |
635 | return -ENOMEM; | 700 | return -ENOMEM; |
636 | 701 | ||
702 | wm8510->regmap = devm_regmap_init_i2c(i2c, &wm8510_regmap); | ||
703 | if (IS_ERR(wm8510->regmap)) | ||
704 | return PTR_ERR(wm8510->regmap); | ||
705 | |||
637 | i2c_set_clientdata(i2c, wm8510); | 706 | i2c_set_clientdata(i2c, wm8510); |
638 | wm8510->control_type = SND_SOC_I2C; | ||
639 | 707 | ||
640 | ret = snd_soc_register_codec(&i2c->dev, | 708 | ret = snd_soc_register_codec(&i2c->dev, |
641 | &soc_codec_dev_wm8510, &wm8510_dai, 1); | 709 | &soc_codec_dev_wm8510, &wm8510_dai, 1); |
642 | if (ret < 0) | 710 | |
643 | kfree(wm8510); | ||
644 | return ret; | 711 | return ret; |
645 | } | 712 | } |
646 | 713 | ||
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index 1c3ffb290cdc..8d5c27673501 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
19 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
20 | #include <linux/regmap.h> | ||
20 | #include <linux/regulator/consumer.h> | 21 | #include <linux/regulator/consumer.h> |
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
22 | #include <linux/of_device.h> | 23 | #include <linux/of_device.h> |
@@ -39,41 +40,34 @@ static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = { | |||
39 | 40 | ||
40 | /* codec private data */ | 41 | /* codec private data */ |
41 | struct wm8523_priv { | 42 | struct wm8523_priv { |
42 | enum snd_soc_control_type control_type; | 43 | struct regmap *regmap; |
43 | struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES]; | 44 | struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES]; |
44 | unsigned int sysclk; | 45 | unsigned int sysclk; |
45 | unsigned int rate_constraint_list[WM8523_NUM_RATES]; | 46 | unsigned int rate_constraint_list[WM8523_NUM_RATES]; |
46 | struct snd_pcm_hw_constraint_list rate_constraint; | 47 | struct snd_pcm_hw_constraint_list rate_constraint; |
47 | }; | 48 | }; |
48 | 49 | ||
49 | static const u16 wm8523_reg[WM8523_REGISTER_COUNT] = { | 50 | static const struct reg_default wm8523_reg_defaults[] = { |
50 | 0x8523, /* R0 - DEVICE_ID */ | 51 | { 2, 0x0000 }, /* R2 - PSCTRL1 */ |
51 | 0x0001, /* R1 - REVISION */ | 52 | { 3, 0x1812 }, /* R3 - AIF_CTRL1 */ |
52 | 0x0000, /* R2 - PSCTRL1 */ | 53 | { 4, 0x0000 }, /* R4 - AIF_CTRL2 */ |
53 | 0x1812, /* R3 - AIF_CTRL1 */ | 54 | { 5, 0x0001 }, /* R5 - DAC_CTRL3 */ |
54 | 0x0000, /* R4 - AIF_CTRL2 */ | 55 | { 6, 0x0190 }, /* R6 - DAC_GAINL */ |
55 | 0x0001, /* R5 - DAC_CTRL3 */ | 56 | { 7, 0x0190 }, /* R7 - DAC_GAINR */ |
56 | 0x0190, /* R6 - DAC_GAINL */ | 57 | { 8, 0x0000 }, /* R8 - ZERO_DETECT */ |
57 | 0x0190, /* R7 - DAC_GAINR */ | ||
58 | 0x0000, /* R8 - ZERO_DETECT */ | ||
59 | }; | 58 | }; |
60 | 59 | ||
61 | static int wm8523_volatile_register(struct snd_soc_codec *codec, unsigned int reg) | 60 | static bool wm8523_volatile_register(struct device *dev, unsigned int reg) |
62 | { | 61 | { |
63 | switch (reg) { | 62 | switch (reg) { |
64 | case WM8523_DEVICE_ID: | 63 | case WM8523_DEVICE_ID: |
65 | case WM8523_REVISION: | 64 | case WM8523_REVISION: |
66 | return 1; | 65 | return true; |
67 | default: | 66 | default: |
68 | return 0; | 67 | return false; |
69 | } | 68 | } |
70 | } | 69 | } |
71 | 70 | ||
72 | static int wm8523_reset(struct snd_soc_codec *codec) | ||
73 | { | ||
74 | return snd_soc_write(codec, WM8523_DEVICE_ID, 0); | ||
75 | } | ||
76 | |||
77 | static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0); | 71 | static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0); |
78 | 72 | ||
79 | static const char *wm8523_zd_count_text[] = { | 73 | static const char *wm8523_zd_count_text[] = { |
@@ -301,8 +295,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec, | |||
301 | enum snd_soc_bias_level level) | 295 | enum snd_soc_bias_level level) |
302 | { | 296 | { |
303 | struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); | 297 | struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); |
304 | u16 *reg_cache = codec->reg_cache; | 298 | int ret; |
305 | int ret, i; | ||
306 | 299 | ||
307 | switch (level) { | 300 | switch (level) { |
308 | case SND_SOC_BIAS_ON: | 301 | case SND_SOC_BIAS_ON: |
@@ -325,16 +318,13 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec, | |||
325 | return ret; | 318 | return ret; |
326 | } | 319 | } |
327 | 320 | ||
321 | /* Sync back default/cached values */ | ||
322 | regcache_sync(wm8523->regmap); | ||
323 | |||
328 | /* Initial power up */ | 324 | /* Initial power up */ |
329 | snd_soc_update_bits(codec, WM8523_PSCTRL1, | 325 | snd_soc_update_bits(codec, WM8523_PSCTRL1, |
330 | WM8523_SYS_ENA_MASK, 1); | 326 | WM8523_SYS_ENA_MASK, 1); |
331 | 327 | ||
332 | /* Sync back default/cached values */ | ||
333 | for (i = WM8523_AIF_CTRL1; | ||
334 | i < WM8523_MAX_REGISTER; i++) | ||
335 | snd_soc_write(codec, i, reg_cache[i]); | ||
336 | |||
337 | |||
338 | msleep(100); | 328 | msleep(100); |
339 | } | 329 | } |
340 | 330 | ||
@@ -402,60 +392,18 @@ static int wm8523_resume(struct snd_soc_codec *codec) | |||
402 | static int wm8523_probe(struct snd_soc_codec *codec) | 392 | static int wm8523_probe(struct snd_soc_codec *codec) |
403 | { | 393 | { |
404 | struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); | 394 | struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); |
405 | int ret, i; | 395 | int ret; |
406 | 396 | ||
407 | wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0]; | 397 | wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0]; |
408 | wm8523->rate_constraint.count = | 398 | wm8523->rate_constraint.count = |
409 | ARRAY_SIZE(wm8523->rate_constraint_list); | 399 | ARRAY_SIZE(wm8523->rate_constraint_list); |
410 | 400 | ||
411 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8523->control_type); | 401 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); |
412 | if (ret != 0) { | 402 | if (ret != 0) { |
413 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 403 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
414 | return ret; | 404 | return ret; |
415 | } | 405 | } |
416 | 406 | ||
417 | for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++) | ||
418 | wm8523->supplies[i].supply = wm8523_supply_names[i]; | ||
419 | |||
420 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8523->supplies), | ||
421 | wm8523->supplies); | ||
422 | if (ret != 0) { | ||
423 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | ||
424 | return ret; | ||
425 | } | ||
426 | |||
427 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies), | ||
428 | wm8523->supplies); | ||
429 | if (ret != 0) { | ||
430 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | ||
431 | goto err_get; | ||
432 | } | ||
433 | |||
434 | ret = snd_soc_read(codec, WM8523_DEVICE_ID); | ||
435 | if (ret < 0) { | ||
436 | dev_err(codec->dev, "Failed to read ID register\n"); | ||
437 | goto err_enable; | ||
438 | } | ||
439 | if (ret != wm8523_reg[WM8523_DEVICE_ID]) { | ||
440 | dev_err(codec->dev, "Device is not a WM8523, ID is %x\n", ret); | ||
441 | ret = -EINVAL; | ||
442 | goto err_enable; | ||
443 | } | ||
444 | |||
445 | ret = snd_soc_read(codec, WM8523_REVISION); | ||
446 | if (ret < 0) { | ||
447 | dev_err(codec->dev, "Failed to read revision register\n"); | ||
448 | goto err_enable; | ||
449 | } | ||
450 | dev_info(codec->dev, "revision %c\n", | ||
451 | (ret & WM8523_CHIP_REV_MASK) + 'A'); | ||
452 | |||
453 | ret = wm8523_reset(codec); | ||
454 | if (ret < 0) { | ||
455 | dev_err(codec->dev, "Failed to issue reset\n"); | ||
456 | goto err_enable; | ||
457 | } | ||
458 | |||
459 | /* Change some default settings - latch VU and enable ZC */ | 407 | /* Change some default settings - latch VU and enable ZC */ |
460 | snd_soc_update_bits(codec, WM8523_DAC_GAINR, | 408 | snd_soc_update_bits(codec, WM8523_DAC_GAINR, |
461 | WM8523_DACR_VU, WM8523_DACR_VU); | 409 | WM8523_DACR_VU, WM8523_DACR_VU); |
@@ -463,25 +411,12 @@ static int wm8523_probe(struct snd_soc_codec *codec) | |||
463 | 411 | ||
464 | wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 412 | wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
465 | 413 | ||
466 | /* Bias level configuration will have done an extra enable */ | ||
467 | regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); | ||
468 | |||
469 | return 0; | 414 | return 0; |
470 | |||
471 | err_enable: | ||
472 | regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); | ||
473 | err_get: | ||
474 | regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); | ||
475 | |||
476 | return ret; | ||
477 | } | 415 | } |
478 | 416 | ||
479 | static int wm8523_remove(struct snd_soc_codec *codec) | 417 | static int wm8523_remove(struct snd_soc_codec *codec) |
480 | { | 418 | { |
481 | struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); | ||
482 | |||
483 | wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF); | 419 | wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF); |
484 | regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); | ||
485 | return 0; | 420 | return 0; |
486 | } | 421 | } |
487 | 422 | ||
@@ -491,10 +426,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8523 = { | |||
491 | .suspend = wm8523_suspend, | 426 | .suspend = wm8523_suspend, |
492 | .resume = wm8523_resume, | 427 | .resume = wm8523_resume, |
493 | .set_bias_level = wm8523_set_bias_level, | 428 | .set_bias_level = wm8523_set_bias_level, |
494 | .reg_cache_size = WM8523_REGISTER_COUNT, | ||
495 | .reg_word_size = sizeof(u16), | ||
496 | .reg_cache_default = wm8523_reg, | ||
497 | .volatile_register = wm8523_volatile_register, | ||
498 | 429 | ||
499 | .controls = wm8523_controls, | 430 | .controls = wm8523_controls, |
500 | .num_controls = ARRAY_SIZE(wm8523_controls), | 431 | .num_controls = ARRAY_SIZE(wm8523_controls), |
@@ -509,32 +440,97 @@ static const struct of_device_id wm8523_of_match[] = { | |||
509 | { }, | 440 | { }, |
510 | }; | 441 | }; |
511 | 442 | ||
443 | static const struct regmap_config wm8523_regmap = { | ||
444 | .reg_bits = 8, | ||
445 | .val_bits = 16, | ||
446 | .max_register = WM8523_ZERO_DETECT, | ||
447 | |||
448 | .reg_defaults = wm8523_reg_defaults, | ||
449 | .num_reg_defaults = ARRAY_SIZE(wm8523_reg_defaults), | ||
450 | .cache_type = REGCACHE_RBTREE, | ||
451 | |||
452 | .volatile_reg = wm8523_volatile_register, | ||
453 | }; | ||
454 | |||
512 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 455 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
513 | static __devinit int wm8523_i2c_probe(struct i2c_client *i2c, | 456 | static __devinit int wm8523_i2c_probe(struct i2c_client *i2c, |
514 | const struct i2c_device_id *id) | 457 | const struct i2c_device_id *id) |
515 | { | 458 | { |
516 | struct wm8523_priv *wm8523; | 459 | struct wm8523_priv *wm8523; |
517 | int ret; | 460 | unsigned int val; |
461 | int ret, i; | ||
518 | 462 | ||
519 | wm8523 = kzalloc(sizeof(struct wm8523_priv), GFP_KERNEL); | 463 | wm8523 = devm_kzalloc(&i2c->dev, sizeof(struct wm8523_priv), |
464 | GFP_KERNEL); | ||
520 | if (wm8523 == NULL) | 465 | if (wm8523 == NULL) |
521 | return -ENOMEM; | 466 | return -ENOMEM; |
522 | 467 | ||
468 | wm8523->regmap = devm_regmap_init_i2c(i2c, &wm8523_regmap); | ||
469 | if (IS_ERR(wm8523->regmap)) { | ||
470 | ret = PTR_ERR(wm8523->regmap); | ||
471 | dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret); | ||
472 | return ret; | ||
473 | } | ||
474 | |||
475 | for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++) | ||
476 | wm8523->supplies[i].supply = wm8523_supply_names[i]; | ||
477 | |||
478 | ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8523->supplies), | ||
479 | wm8523->supplies); | ||
480 | if (ret != 0) { | ||
481 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); | ||
482 | return ret; | ||
483 | } | ||
484 | |||
485 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies), | ||
486 | wm8523->supplies); | ||
487 | if (ret != 0) { | ||
488 | dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); | ||
489 | return ret; | ||
490 | } | ||
491 | |||
492 | ret = regmap_read(wm8523->regmap, WM8523_DEVICE_ID, &val); | ||
493 | if (ret < 0) { | ||
494 | dev_err(&i2c->dev, "Failed to read ID register\n"); | ||
495 | goto err_enable; | ||
496 | } | ||
497 | if (val != 0x8523) { | ||
498 | dev_err(&i2c->dev, "Device is not a WM8523, ID is %x\n", ret); | ||
499 | ret = -EINVAL; | ||
500 | goto err_enable; | ||
501 | } | ||
502 | |||
503 | ret = regmap_read(wm8523->regmap, WM8523_REVISION, &val); | ||
504 | if (ret < 0) { | ||
505 | dev_err(&i2c->dev, "Failed to read revision register\n"); | ||
506 | goto err_enable; | ||
507 | } | ||
508 | dev_info(&i2c->dev, "revision %c\n", | ||
509 | (val & WM8523_CHIP_REV_MASK) + 'A'); | ||
510 | |||
511 | ret = regmap_write(wm8523->regmap, WM8523_DEVICE_ID, 0x8523); | ||
512 | if (ret != 0) { | ||
513 | dev_err(&i2c->dev, "Failed to reset device: %d\n", ret); | ||
514 | goto err_enable; | ||
515 | } | ||
516 | |||
517 | regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); | ||
518 | |||
523 | i2c_set_clientdata(i2c, wm8523); | 519 | i2c_set_clientdata(i2c, wm8523); |
524 | wm8523->control_type = SND_SOC_I2C; | ||
525 | 520 | ||
526 | ret = snd_soc_register_codec(&i2c->dev, | 521 | ret = snd_soc_register_codec(&i2c->dev, |
527 | &soc_codec_dev_wm8523, &wm8523_dai, 1); | 522 | &soc_codec_dev_wm8523, &wm8523_dai, 1); |
528 | if (ret < 0) | 523 | |
529 | kfree(wm8523); | ||
530 | return ret; | 524 | return ret; |
531 | 525 | ||
526 | err_enable: | ||
527 | regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); | ||
528 | return ret; | ||
532 | } | 529 | } |
533 | 530 | ||
534 | static __devexit int wm8523_i2c_remove(struct i2c_client *client) | 531 | static __devexit int wm8523_i2c_remove(struct i2c_client *client) |
535 | { | 532 | { |
536 | snd_soc_unregister_codec(&client->dev); | 533 | snd_soc_unregister_codec(&client->dev); |
537 | kfree(i2c_get_clientdata(client)); | ||
538 | return 0; | 534 | return 0; |
539 | } | 535 | } |
540 | 536 | ||
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 7c68226376e4..5e9c40fa7eb2 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm8580.c -- WM8580 ALSA Soc Audio driver | 2 | * wm8580.c -- WM8580 ALSA Soc Audio driver |
3 | * | 3 | * |
4 | * Copyright 2008-11 Wolfson Microelectronics PLC. | 4 | * Copyright 2008-12 Wolfson Microelectronics PLC. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License as published by the | 7 | * under the terms of the GNU General Public License as published by the |
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/pm.h> | 24 | #include <linux/pm.h> |
25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
26 | #include <linux/regmap.h> | ||
26 | #include <linux/regulator/consumer.h> | 27 | #include <linux/regulator/consumer.h> |
27 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
28 | #include <linux/of_device.h> | 29 | #include <linux/of_device.h> |
@@ -157,23 +158,72 @@ | |||
157 | * We can't read the WM8580 register space when we | 158 | * We can't read the WM8580 register space when we |
158 | * are using 2 wire for device control, so we cache them instead. | 159 | * are using 2 wire for device control, so we cache them instead. |
159 | */ | 160 | */ |
160 | static const u16 wm8580_reg[] = { | 161 | static const struct reg_default wm8580_reg_defaults[] = { |
161 | 0x0121, 0x017e, 0x007d, 0x0014, /*R3*/ | 162 | { 0, 0x0121 }, |
162 | 0x0121, 0x017e, 0x007d, 0x0194, /*R7*/ | 163 | { 1, 0x017e }, |
163 | 0x0010, 0x0002, 0x0002, 0x00c2, /*R11*/ | 164 | { 2, 0x007d }, |
164 | 0x0182, 0x0082, 0x000a, 0x0024, /*R15*/ | 165 | { 3, 0x0014 }, |
165 | 0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/ | 166 | { 4, 0x0121 }, |
166 | 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/ | 167 | { 5, 0x017e }, |
167 | 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R27*/ | 168 | { 6, 0x007d }, |
168 | 0x01f0, 0x0040, 0x0000, 0x0000, /*R31(0x1F)*/ | 169 | { 7, 0x0194 }, |
169 | 0x0000, 0x0000, 0x0031, 0x000b, /*R35*/ | 170 | { 8, 0x0010 }, |
170 | 0x0039, 0x0000, 0x0010, 0x0032, /*R39*/ | 171 | { 9, 0x0002 }, |
171 | 0x0054, 0x0076, 0x0098, 0x0000, /*R43(0x2B)*/ | 172 | { 10, 0x0002 }, |
172 | 0x0000, 0x0000, 0x0000, 0x0000, /*R47*/ | 173 | { 11, 0x00c2 }, |
173 | 0x0000, 0x0000, 0x005e, 0x003e, /*R51(0x33)*/ | 174 | { 12, 0x0182 }, |
174 | 0x0000, 0x0000 /*R53*/ | 175 | { 13, 0x0082 }, |
176 | { 14, 0x000a }, | ||
177 | { 15, 0x0024 }, | ||
178 | { 16, 0x0009 }, | ||
179 | { 17, 0x0000 }, | ||
180 | { 18, 0x00ff }, | ||
181 | { 19, 0x0000 }, | ||
182 | { 20, 0x00ff }, | ||
183 | { 21, 0x00ff }, | ||
184 | { 22, 0x00ff }, | ||
185 | { 23, 0x00ff }, | ||
186 | { 24, 0x00ff }, | ||
187 | { 25, 0x00ff }, | ||
188 | { 26, 0x00ff }, | ||
189 | { 27, 0x00ff }, | ||
190 | { 28, 0x01f0 }, | ||
191 | { 29, 0x0040 }, | ||
192 | { 30, 0x0000 }, | ||
193 | { 31, 0x0000 }, | ||
194 | { 32, 0x0000 }, | ||
195 | { 33, 0x0000 }, | ||
196 | { 34, 0x0031 }, | ||
197 | { 35, 0x000b }, | ||
198 | { 36, 0x0039 }, | ||
199 | { 37, 0x0000 }, | ||
200 | { 38, 0x0010 }, | ||
201 | { 39, 0x0032 }, | ||
202 | { 40, 0x0054 }, | ||
203 | { 41, 0x0076 }, | ||
204 | { 42, 0x0098 }, | ||
205 | { 43, 0x0000 }, | ||
206 | { 44, 0x0000 }, | ||
207 | { 45, 0x0000 }, | ||
208 | { 46, 0x0000 }, | ||
209 | { 47, 0x0000 }, | ||
210 | { 48, 0x0000 }, | ||
211 | { 49, 0x0000 }, | ||
212 | { 50, 0x005e }, | ||
213 | { 51, 0x003e }, | ||
214 | { 52, 0x0000 }, | ||
175 | }; | 215 | }; |
176 | 216 | ||
217 | static bool wm8580_volatile(struct device *dev, unsigned int reg) | ||
218 | { | ||
219 | switch (reg) { | ||
220 | case WM8580_RESET: | ||
221 | return true; | ||
222 | default: | ||
223 | return false; | ||
224 | } | ||
225 | } | ||
226 | |||
177 | struct pll_state { | 227 | struct pll_state { |
178 | unsigned int in; | 228 | unsigned int in; |
179 | unsigned int out; | 229 | unsigned int out; |
@@ -188,7 +238,7 @@ static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = { | |||
188 | 238 | ||
189 | /* codec private data */ | 239 | /* codec private data */ |
190 | struct wm8580_priv { | 240 | struct wm8580_priv { |
191 | enum snd_soc_control_type control_type; | 241 | struct regmap *regmap; |
192 | struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES]; | 242 | struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES]; |
193 | struct pll_state a; | 243 | struct pll_state a; |
194 | struct pll_state b; | 244 | struct pll_state b; |
@@ -203,14 +253,16 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol, | |||
203 | struct soc_mixer_control *mc = | 253 | struct soc_mixer_control *mc = |
204 | (struct soc_mixer_control *)kcontrol->private_value; | 254 | (struct soc_mixer_control *)kcontrol->private_value; |
205 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 255 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
206 | u16 *reg_cache = codec->reg_cache; | 256 | struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); |
207 | unsigned int reg = mc->reg; | 257 | unsigned int reg = mc->reg; |
208 | unsigned int reg2 = mc->rreg; | 258 | unsigned int reg2 = mc->rreg; |
209 | int ret; | 259 | int ret; |
210 | 260 | ||
211 | /* Clear the register cache so we write without VU set */ | 261 | /* Clear the register cache VU so we write without VU set */ |
212 | reg_cache[reg] = 0; | 262 | regcache_cache_only(wm8580->regmap, true); |
213 | reg_cache[reg2] = 0; | 263 | regmap_update_bits(wm8580->regmap, reg, 0x100, 0x000); |
264 | regmap_update_bits(wm8580->regmap, reg2, 0x100, 0x000); | ||
265 | regcache_cache_only(wm8580->regmap, false); | ||
214 | 266 | ||
215 | ret = snd_soc_put_volsw(kcontrol, ucontrol); | 267 | ret = snd_soc_put_volsw(kcontrol, ucontrol); |
216 | if (ret < 0) | 268 | if (ret < 0) |
@@ -815,24 +867,14 @@ static struct snd_soc_dai_driver wm8580_dai[] = { | |||
815 | static int wm8580_probe(struct snd_soc_codec *codec) | 867 | static int wm8580_probe(struct snd_soc_codec *codec) |
816 | { | 868 | { |
817 | struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); | 869 | struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); |
818 | int ret = 0,i; | 870 | int ret = 0; |
819 | 871 | ||
820 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8580->control_type); | 872 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
821 | if (ret < 0) { | 873 | if (ret < 0) { |
822 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 874 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
823 | return ret; | 875 | return ret; |
824 | } | 876 | } |
825 | 877 | ||
826 | for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++) | ||
827 | wm8580->supplies[i].supply = wm8580_supply_names[i]; | ||
828 | |||
829 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8580->supplies), | ||
830 | wm8580->supplies); | ||
831 | if (ret != 0) { | ||
832 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | ||
833 | return ret; | ||
834 | } | ||
835 | |||
836 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies), | 878 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies), |
837 | wm8580->supplies); | 879 | wm8580->supplies); |
838 | if (ret != 0) { | 880 | if (ret != 0) { |
@@ -854,7 +896,6 @@ static int wm8580_probe(struct snd_soc_codec *codec) | |||
854 | err_regulator_enable: | 896 | err_regulator_enable: |
855 | regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); | 897 | regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); |
856 | err_regulator_get: | 898 | err_regulator_get: |
857 | regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); | ||
858 | return ret; | 899 | return ret; |
859 | } | 900 | } |
860 | 901 | ||
@@ -866,7 +907,6 @@ static int wm8580_remove(struct snd_soc_codec *codec) | |||
866 | wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF); | 907 | wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF); |
867 | 908 | ||
868 | regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); | 909 | regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); |
869 | regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); | ||
870 | 910 | ||
871 | return 0; | 911 | return 0; |
872 | } | 912 | } |
@@ -875,9 +915,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8580 = { | |||
875 | .probe = wm8580_probe, | 915 | .probe = wm8580_probe, |
876 | .remove = wm8580_remove, | 916 | .remove = wm8580_remove, |
877 | .set_bias_level = wm8580_set_bias_level, | 917 | .set_bias_level = wm8580_set_bias_level, |
878 | .reg_cache_size = ARRAY_SIZE(wm8580_reg), | ||
879 | .reg_word_size = sizeof(u16), | ||
880 | .reg_cache_default = wm8580_reg, | ||
881 | 918 | ||
882 | .controls = wm8580_snd_controls, | 919 | .controls = wm8580_snd_controls, |
883 | .num_controls = ARRAY_SIZE(wm8580_snd_controls), | 920 | .num_controls = ARRAY_SIZE(wm8580_snd_controls), |
@@ -892,31 +929,55 @@ static const struct of_device_id wm8580_of_match[] = { | |||
892 | { }, | 929 | { }, |
893 | }; | 930 | }; |
894 | 931 | ||
932 | static const struct regmap_config wm8580_regmap = { | ||
933 | .reg_bits = 7, | ||
934 | .val_bits = 9, | ||
935 | .max_register = WM8580_MAX_REGISTER, | ||
936 | |||
937 | .reg_defaults = wm8580_reg_defaults, | ||
938 | .num_reg_defaults = ARRAY_SIZE(wm8580_reg_defaults), | ||
939 | .cache_type = REGCACHE_RBTREE, | ||
940 | |||
941 | .volatile_reg = wm8580_volatile, | ||
942 | }; | ||
943 | |||
895 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 944 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
896 | static int wm8580_i2c_probe(struct i2c_client *i2c, | 945 | static int wm8580_i2c_probe(struct i2c_client *i2c, |
897 | const struct i2c_device_id *id) | 946 | const struct i2c_device_id *id) |
898 | { | 947 | { |
899 | struct wm8580_priv *wm8580; | 948 | struct wm8580_priv *wm8580; |
900 | int ret; | 949 | int ret, i; |
901 | 950 | ||
902 | wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL); | 951 | wm8580 = devm_kzalloc(&i2c->dev, sizeof(struct wm8580_priv), |
952 | GFP_KERNEL); | ||
903 | if (wm8580 == NULL) | 953 | if (wm8580 == NULL) |
904 | return -ENOMEM; | 954 | return -ENOMEM; |
905 | 955 | ||
956 | wm8580->regmap = devm_regmap_init_i2c(i2c, &wm8580_regmap); | ||
957 | if (IS_ERR(wm8580->regmap)) | ||
958 | return PTR_ERR(wm8580->regmap); | ||
959 | |||
960 | for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++) | ||
961 | wm8580->supplies[i].supply = wm8580_supply_names[i]; | ||
962 | |||
963 | ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8580->supplies), | ||
964 | wm8580->supplies); | ||
965 | if (ret != 0) { | ||
966 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); | ||
967 | return ret; | ||
968 | } | ||
969 | |||
906 | i2c_set_clientdata(i2c, wm8580); | 970 | i2c_set_clientdata(i2c, wm8580); |
907 | wm8580->control_type = SND_SOC_I2C; | ||
908 | 971 | ||
909 | ret = snd_soc_register_codec(&i2c->dev, | 972 | ret = snd_soc_register_codec(&i2c->dev, |
910 | &soc_codec_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai)); | 973 | &soc_codec_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai)); |
911 | if (ret < 0) | 974 | |
912 | kfree(wm8580); | ||
913 | return ret; | 975 | return ret; |
914 | } | 976 | } |
915 | 977 | ||
916 | static int wm8580_i2c_remove(struct i2c_client *client) | 978 | static int wm8580_i2c_remove(struct i2c_client *client) |
917 | { | 979 | { |
918 | snd_soc_unregister_codec(&client->dev); | 980 | snd_soc_unregister_codec(&client->dev); |
919 | kfree(i2c_get_clientdata(client)); | ||
920 | return 0; | 981 | return 0; |
921 | } | 982 | } |
922 | 983 | ||
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index 0b76d1dca5ea..8b8bb70f1eb9 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/pm.h> | 19 | #include <linux/pm.h> |
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/regmap.h> | ||
21 | #include <linux/spi/spi.h> | 22 | #include <linux/spi/spi.h> |
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
23 | #include <linux/of_device.h> | 24 | #include <linux/of_device.h> |
@@ -32,7 +33,7 @@ | |||
32 | 33 | ||
33 | /* codec private data */ | 34 | /* codec private data */ |
34 | struct wm8711_priv { | 35 | struct wm8711_priv { |
35 | enum snd_soc_control_type bus_type; | 36 | struct regmap *regmap; |
36 | unsigned int sysclk; | 37 | unsigned int sysclk; |
37 | }; | 38 | }; |
38 | 39 | ||
@@ -42,11 +43,21 @@ struct wm8711_priv { | |||
42 | * using 2 wire for device control, so we cache them instead. | 43 | * using 2 wire for device control, so we cache them instead. |
43 | * There is no point in caching the reset register | 44 | * There is no point in caching the reset register |
44 | */ | 45 | */ |
45 | static const u16 wm8711_reg[WM8711_CACHEREGNUM] = { | 46 | static const struct reg_default wm8711_reg_defaults[] = { |
46 | 0x0079, 0x0079, 0x000a, 0x0008, | 47 | { 0, 0x0079 }, { 1, 0x0079 }, { 2, 0x000a }, { 3, 0x0008 }, |
47 | 0x009f, 0x000a, 0x0000, 0x0000 | 48 | { 4, 0x009f }, { 5, 0x000a }, { 6, 0x0000 }, { 7, 0x0000 }, |
48 | }; | 49 | }; |
49 | 50 | ||
51 | static bool wm8711_volatile(struct device *dev, unsigned int reg) | ||
52 | { | ||
53 | switch (reg) { | ||
54 | case WM8711_RESET: | ||
55 | return true; | ||
56 | default: | ||
57 | return false; | ||
58 | } | ||
59 | } | ||
60 | |||
50 | #define wm8711_reset(c) snd_soc_write(c, WM8711_RESET, 0) | 61 | #define wm8711_reset(c) snd_soc_write(c, WM8711_RESET, 0) |
51 | 62 | ||
52 | static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); | 63 | static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); |
@@ -289,6 +300,7 @@ static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
289 | static int wm8711_set_bias_level(struct snd_soc_codec *codec, | 300 | static int wm8711_set_bias_level(struct snd_soc_codec *codec, |
290 | enum snd_soc_bias_level level) | 301 | enum snd_soc_bias_level level) |
291 | { | 302 | { |
303 | struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec); | ||
292 | u16 reg = snd_soc_read(codec, WM8711_PWR) & 0xff7f; | 304 | u16 reg = snd_soc_read(codec, WM8711_PWR) & 0xff7f; |
293 | 305 | ||
294 | switch (level) { | 306 | switch (level) { |
@@ -299,7 +311,7 @@ static int wm8711_set_bias_level(struct snd_soc_codec *codec, | |||
299 | break; | 311 | break; |
300 | case SND_SOC_BIAS_STANDBY: | 312 | case SND_SOC_BIAS_STANDBY: |
301 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) | 313 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) |
302 | snd_soc_cache_sync(codec); | 314 | regcache_sync(wm8711->regmap); |
303 | 315 | ||
304 | snd_soc_write(codec, WM8711_PWR, reg | 0x0040); | 316 | snd_soc_write(codec, WM8711_PWR, reg | 0x0040); |
305 | break; | 317 | break; |
@@ -353,10 +365,9 @@ static int wm8711_resume(struct snd_soc_codec *codec) | |||
353 | 365 | ||
354 | static int wm8711_probe(struct snd_soc_codec *codec) | 366 | static int wm8711_probe(struct snd_soc_codec *codec) |
355 | { | 367 | { |
356 | struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec); | ||
357 | int ret; | 368 | int ret; |
358 | 369 | ||
359 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8711->bus_type); | 370 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
360 | if (ret < 0) { | 371 | if (ret < 0) { |
361 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 372 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
362 | return ret; | 373 | return ret; |
@@ -391,9 +402,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8711 = { | |||
391 | .suspend = wm8711_suspend, | 402 | .suspend = wm8711_suspend, |
392 | .resume = wm8711_resume, | 403 | .resume = wm8711_resume, |
393 | .set_bias_level = wm8711_set_bias_level, | 404 | .set_bias_level = wm8711_set_bias_level, |
394 | .reg_cache_size = ARRAY_SIZE(wm8711_reg), | ||
395 | .reg_word_size = sizeof(u16), | ||
396 | .reg_cache_default = wm8711_reg, | ||
397 | .controls = wm8711_snd_controls, | 405 | .controls = wm8711_snd_controls, |
398 | .num_controls = ARRAY_SIZE(wm8711_snd_controls), | 406 | .num_controls = ARRAY_SIZE(wm8711_snd_controls), |
399 | .dapm_widgets = wm8711_dapm_widgets, | 407 | .dapm_widgets = wm8711_dapm_widgets, |
@@ -408,30 +416,45 @@ static const struct of_device_id wm8711_of_match[] = { | |||
408 | }; | 416 | }; |
409 | MODULE_DEVICE_TABLE(of, wm8711_of_match); | 417 | MODULE_DEVICE_TABLE(of, wm8711_of_match); |
410 | 418 | ||
419 | static const struct regmap_config wm8711_regmap = { | ||
420 | .reg_bits = 7, | ||
421 | .val_bits = 9, | ||
422 | .max_register = WM8711_RESET, | ||
423 | |||
424 | .reg_defaults = wm8711_reg_defaults, | ||
425 | .num_reg_defaults = ARRAY_SIZE(wm8711_reg_defaults), | ||
426 | .cache_type = REGCACHE_RBTREE, | ||
427 | |||
428 | .volatile_reg = wm8711_volatile, | ||
429 | }; | ||
430 | |||
411 | #if defined(CONFIG_SPI_MASTER) | 431 | #if defined(CONFIG_SPI_MASTER) |
412 | static int __devinit wm8711_spi_probe(struct spi_device *spi) | 432 | static int __devinit wm8711_spi_probe(struct spi_device *spi) |
413 | { | 433 | { |
414 | struct wm8711_priv *wm8711; | 434 | struct wm8711_priv *wm8711; |
415 | int ret; | 435 | int ret; |
416 | 436 | ||
417 | wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL); | 437 | wm8711 = devm_kzalloc(&spi->dev, sizeof(struct wm8711_priv), |
438 | GFP_KERNEL); | ||
418 | if (wm8711 == NULL) | 439 | if (wm8711 == NULL) |
419 | return -ENOMEM; | 440 | return -ENOMEM; |
420 | 441 | ||
442 | wm8711->regmap = devm_regmap_init_spi(spi, &wm8711_regmap); | ||
443 | if (IS_ERR(wm8711->regmap)) | ||
444 | return PTR_ERR(wm8711->regmap); | ||
445 | |||
421 | spi_set_drvdata(spi, wm8711); | 446 | spi_set_drvdata(spi, wm8711); |
422 | wm8711->bus_type = SND_SOC_SPI; | ||
423 | 447 | ||
424 | ret = snd_soc_register_codec(&spi->dev, | 448 | ret = snd_soc_register_codec(&spi->dev, |
425 | &soc_codec_dev_wm8711, &wm8711_dai, 1); | 449 | &soc_codec_dev_wm8711, &wm8711_dai, 1); |
426 | if (ret < 0) | 450 | |
427 | kfree(wm8711); | ||
428 | return ret; | 451 | return ret; |
429 | } | 452 | } |
430 | 453 | ||
431 | static int __devexit wm8711_spi_remove(struct spi_device *spi) | 454 | static int __devexit wm8711_spi_remove(struct spi_device *spi) |
432 | { | 455 | { |
433 | snd_soc_unregister_codec(&spi->dev); | 456 | snd_soc_unregister_codec(&spi->dev); |
434 | kfree(spi_get_drvdata(spi)); | 457 | |
435 | return 0; | 458 | return 0; |
436 | } | 459 | } |
437 | 460 | ||
@@ -453,24 +476,26 @@ static __devinit int wm8711_i2c_probe(struct i2c_client *client, | |||
453 | struct wm8711_priv *wm8711; | 476 | struct wm8711_priv *wm8711; |
454 | int ret; | 477 | int ret; |
455 | 478 | ||
456 | wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL); | 479 | wm8711 = devm_kzalloc(&client->dev, sizeof(struct wm8711_priv), |
480 | GFP_KERNEL); | ||
457 | if (wm8711 == NULL) | 481 | if (wm8711 == NULL) |
458 | return -ENOMEM; | 482 | return -ENOMEM; |
459 | 483 | ||
484 | wm8711->regmap = devm_regmap_init_i2c(client, &wm8711_regmap); | ||
485 | if (IS_ERR(wm8711->regmap)) | ||
486 | return PTR_ERR(wm8711->regmap); | ||
487 | |||
460 | i2c_set_clientdata(client, wm8711); | 488 | i2c_set_clientdata(client, wm8711); |
461 | wm8711->bus_type = SND_SOC_I2C; | ||
462 | 489 | ||
463 | ret = snd_soc_register_codec(&client->dev, | 490 | ret = snd_soc_register_codec(&client->dev, |
464 | &soc_codec_dev_wm8711, &wm8711_dai, 1); | 491 | &soc_codec_dev_wm8711, &wm8711_dai, 1); |
465 | if (ret < 0) | 492 | |
466 | kfree(wm8711); | ||
467 | return ret; | 493 | return ret; |
468 | } | 494 | } |
469 | 495 | ||
470 | static __devexit int wm8711_i2c_remove(struct i2c_client *client) | 496 | static __devexit int wm8711_i2c_remove(struct i2c_client *client) |
471 | { | 497 | { |
472 | snd_soc_unregister_codec(&client->dev); | 498 | snd_soc_unregister_codec(&client->dev); |
473 | kfree(i2c_get_clientdata(client)); | ||
474 | return 0; | 499 | return 0; |
475 | } | 500 | } |
476 | 501 | ||
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 1467f97dce21..00a12a0c3919 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/regmap.h> | ||
20 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
22 | #include <linux/of_device.h> | 23 | #include <linux/of_device.h> |
@@ -35,16 +36,16 @@ | |||
35 | * the volume update bits, mute the output and enable infinite zero | 36 | * the volume update bits, mute the output and enable infinite zero |
36 | * detect. | 37 | * detect. |
37 | */ | 38 | */ |
38 | static const u16 wm8728_reg_defaults[] = { | 39 | static const struct reg_default wm8728_reg_defaults[] = { |
39 | 0x1ff, | 40 | { 0, 0x1ff }, |
40 | 0x1ff, | 41 | { 1, 0x1ff }, |
41 | 0x001, | 42 | { 2, 0x001 }, |
42 | 0x100, | 43 | { 3, 0x100 }, |
43 | }; | 44 | }; |
44 | 45 | ||
45 | /* codec private data */ | 46 | /* codec private data */ |
46 | struct wm8728_priv { | 47 | struct wm8728_priv { |
47 | enum snd_soc_control_type control_type; | 48 | struct regmap *regmap; |
48 | }; | 49 | }; |
49 | 50 | ||
50 | static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1); | 51 | static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1); |
@@ -162,8 +163,8 @@ static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
162 | static int wm8728_set_bias_level(struct snd_soc_codec *codec, | 163 | static int wm8728_set_bias_level(struct snd_soc_codec *codec, |
163 | enum snd_soc_bias_level level) | 164 | enum snd_soc_bias_level level) |
164 | { | 165 | { |
166 | struct wm8728_priv *wm8728 = snd_soc_codec_get_drvdata(codec); | ||
165 | u16 reg; | 167 | u16 reg; |
166 | int i; | ||
167 | 168 | ||
168 | switch (level) { | 169 | switch (level) { |
169 | case SND_SOC_BIAS_ON: | 170 | case SND_SOC_BIAS_ON: |
@@ -175,9 +176,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec, | |||
175 | snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4); | 176 | snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4); |
176 | 177 | ||
177 | /* ..then sync in the register cache. */ | 178 | /* ..then sync in the register cache. */ |
178 | for (i = 0; i < ARRAY_SIZE(wm8728_reg_defaults); i++) | 179 | regcache_sync(wm8728->regmap); |
179 | snd_soc_write(codec, i, | ||
180 | snd_soc_read(codec, i)); | ||
181 | } | 180 | } |
182 | break; | 181 | break; |
183 | 182 | ||
@@ -229,10 +228,9 @@ static int wm8728_resume(struct snd_soc_codec *codec) | |||
229 | 228 | ||
230 | static int wm8728_probe(struct snd_soc_codec *codec) | 229 | static int wm8728_probe(struct snd_soc_codec *codec) |
231 | { | 230 | { |
232 | struct wm8728_priv *wm8728 = snd_soc_codec_get_drvdata(codec); | ||
233 | int ret; | 231 | int ret; |
234 | 232 | ||
235 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8728->control_type); | 233 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
236 | if (ret < 0) { | 234 | if (ret < 0) { |
237 | printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n", | 235 | printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n", |
238 | ret); | 236 | ret); |
@@ -257,9 +255,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8728 = { | |||
257 | .suspend = wm8728_suspend, | 255 | .suspend = wm8728_suspend, |
258 | .resume = wm8728_resume, | 256 | .resume = wm8728_resume, |
259 | .set_bias_level = wm8728_set_bias_level, | 257 | .set_bias_level = wm8728_set_bias_level, |
260 | .reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults), | ||
261 | .reg_word_size = sizeof(u16), | ||
262 | .reg_cache_default = wm8728_reg_defaults, | ||
263 | .controls = wm8728_snd_controls, | 258 | .controls = wm8728_snd_controls, |
264 | .num_controls = ARRAY_SIZE(wm8728_snd_controls), | 259 | .num_controls = ARRAY_SIZE(wm8728_snd_controls), |
265 | .dapm_widgets = wm8728_dapm_widgets, | 260 | .dapm_widgets = wm8728_dapm_widgets, |
@@ -274,30 +269,43 @@ static const struct of_device_id wm8728_of_match[] = { | |||
274 | }; | 269 | }; |
275 | MODULE_DEVICE_TABLE(of, wm8728_of_match); | 270 | MODULE_DEVICE_TABLE(of, wm8728_of_match); |
276 | 271 | ||
272 | static const struct regmap_config wm8728_regmap = { | ||
273 | .reg_bits = 7, | ||
274 | .val_bits = 9, | ||
275 | .max_register = WM8728_IFCTL, | ||
276 | |||
277 | .reg_defaults = wm8728_reg_defaults, | ||
278 | .num_reg_defaults = ARRAY_SIZE(wm8728_reg_defaults), | ||
279 | .cache_type = REGCACHE_RBTREE, | ||
280 | }; | ||
281 | |||
277 | #if defined(CONFIG_SPI_MASTER) | 282 | #if defined(CONFIG_SPI_MASTER) |
278 | static int __devinit wm8728_spi_probe(struct spi_device *spi) | 283 | static int __devinit wm8728_spi_probe(struct spi_device *spi) |
279 | { | 284 | { |
280 | struct wm8728_priv *wm8728; | 285 | struct wm8728_priv *wm8728; |
281 | int ret; | 286 | int ret; |
282 | 287 | ||
283 | wm8728 = kzalloc(sizeof(struct wm8728_priv), GFP_KERNEL); | 288 | wm8728 = devm_kzalloc(&spi->dev, sizeof(struct wm8728_priv), |
289 | GFP_KERNEL); | ||
284 | if (wm8728 == NULL) | 290 | if (wm8728 == NULL) |
285 | return -ENOMEM; | 291 | return -ENOMEM; |
286 | 292 | ||
287 | wm8728->control_type = SND_SOC_SPI; | 293 | wm8728->regmap = devm_regmap_init_spi(spi, &wm8728_regmap); |
294 | if (IS_ERR(wm8728->regmap)) | ||
295 | return PTR_ERR(wm8728->regmap); | ||
296 | |||
288 | spi_set_drvdata(spi, wm8728); | 297 | spi_set_drvdata(spi, wm8728); |
289 | 298 | ||
290 | ret = snd_soc_register_codec(&spi->dev, | 299 | ret = snd_soc_register_codec(&spi->dev, |
291 | &soc_codec_dev_wm8728, &wm8728_dai, 1); | 300 | &soc_codec_dev_wm8728, &wm8728_dai, 1); |
292 | if (ret < 0) | 301 | |
293 | kfree(wm8728); | ||
294 | return ret; | 302 | return ret; |
295 | } | 303 | } |
296 | 304 | ||
297 | static int __devexit wm8728_spi_remove(struct spi_device *spi) | 305 | static int __devexit wm8728_spi_remove(struct spi_device *spi) |
298 | { | 306 | { |
299 | snd_soc_unregister_codec(&spi->dev); | 307 | snd_soc_unregister_codec(&spi->dev); |
300 | kfree(spi_get_drvdata(spi)); | 308 | |
301 | return 0; | 309 | return 0; |
302 | } | 310 | } |
303 | 311 | ||
@@ -319,24 +327,26 @@ static __devinit int wm8728_i2c_probe(struct i2c_client *i2c, | |||
319 | struct wm8728_priv *wm8728; | 327 | struct wm8728_priv *wm8728; |
320 | int ret; | 328 | int ret; |
321 | 329 | ||
322 | wm8728 = kzalloc(sizeof(struct wm8728_priv), GFP_KERNEL); | 330 | wm8728 = devm_kzalloc(&i2c->dev, sizeof(struct wm8728_priv), |
331 | GFP_KERNEL); | ||
323 | if (wm8728 == NULL) | 332 | if (wm8728 == NULL) |
324 | return -ENOMEM; | 333 | return -ENOMEM; |
325 | 334 | ||
335 | wm8728->regmap = devm_regmap_init_i2c(i2c, &wm8728_regmap); | ||
336 | if (IS_ERR(wm8728->regmap)) | ||
337 | return PTR_ERR(wm8728->regmap); | ||
338 | |||
326 | i2c_set_clientdata(i2c, wm8728); | 339 | i2c_set_clientdata(i2c, wm8728); |
327 | wm8728->control_type = SND_SOC_I2C; | ||
328 | 340 | ||
329 | ret = snd_soc_register_codec(&i2c->dev, | 341 | ret = snd_soc_register_codec(&i2c->dev, |
330 | &soc_codec_dev_wm8728, &wm8728_dai, 1); | 342 | &soc_codec_dev_wm8728, &wm8728_dai, 1); |
331 | if (ret < 0) | 343 | |
332 | kfree(wm8728); | ||
333 | return ret; | 344 | return ret; |
334 | } | 345 | } |
335 | 346 | ||
336 | static __devexit int wm8728_i2c_remove(struct i2c_client *client) | 347 | static __devexit int wm8728_i2c_remove(struct i2c_client *client) |
337 | { | 348 | { |
338 | snd_soc_unregister_codec(&client->dev); | 349 | snd_soc_unregister_codec(&client->dev); |
339 | kfree(i2c_get_clientdata(client)); | ||
340 | return 0; | 350 | return 0; |
341 | } | 351 | } |
342 | 352 | ||
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index d0520124616d..5c9634f4c1f0 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <linux/regmap.h> | ||
19 | #include <linux/regulator/consumer.h> | 20 | #include <linux/regulator/consumer.h> |
20 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
@@ -40,29 +41,39 @@ static const char *wm8737_supply_names[WM8737_NUM_SUPPLIES] = { | |||
40 | 41 | ||
41 | /* codec private data */ | 42 | /* codec private data */ |
42 | struct wm8737_priv { | 43 | struct wm8737_priv { |
43 | enum snd_soc_control_type control_type; | 44 | struct regmap *regmap; |
44 | struct regulator_bulk_data supplies[WM8737_NUM_SUPPLIES]; | 45 | struct regulator_bulk_data supplies[WM8737_NUM_SUPPLIES]; |
45 | unsigned int mclk; | 46 | unsigned int mclk; |
46 | }; | 47 | }; |
47 | 48 | ||
48 | static const u16 wm8737_reg[WM8737_REGISTER_COUNT] = { | 49 | static const struct reg_default wm8737_reg_defaults[] = { |
49 | 0x00C3, /* R0 - Left PGA volume */ | 50 | { 0, 0x00C3 }, /* R0 - Left PGA volume */ |
50 | 0x00C3, /* R1 - Right PGA volume */ | 51 | { 1, 0x00C3 }, /* R1 - Right PGA volume */ |
51 | 0x0007, /* R2 - AUDIO path L */ | 52 | { 2, 0x0007 }, /* R2 - AUDIO path L */ |
52 | 0x0007, /* R3 - AUDIO path R */ | 53 | { 3, 0x0007 }, /* R3 - AUDIO path R */ |
53 | 0x0000, /* R4 - 3D Enhance */ | 54 | { 4, 0x0000 }, /* R4 - 3D Enhance */ |
54 | 0x0000, /* R5 - ADC Control */ | 55 | { 5, 0x0000 }, /* R5 - ADC Control */ |
55 | 0x0000, /* R6 - Power Management */ | 56 | { 6, 0x0000 }, /* R6 - Power Management */ |
56 | 0x000A, /* R7 - Audio Format */ | 57 | { 7, 0x000A }, /* R7 - Audio Format */ |
57 | 0x0000, /* R8 - Clocking */ | 58 | { 8, 0x0000 }, /* R8 - Clocking */ |
58 | 0x000F, /* R9 - MIC Preamp Control */ | 59 | { 9, 0x000F }, /* R9 - MIC Preamp Control */ |
59 | 0x0003, /* R10 - Misc Bias Control */ | 60 | { 10, 0x0003 }, /* R10 - Misc Bias Control */ |
60 | 0x0000, /* R11 - Noise Gate */ | 61 | { 11, 0x0000 }, /* R11 - Noise Gate */ |
61 | 0x007C, /* R12 - ALC1 */ | 62 | { 12, 0x007C }, /* R12 - ALC1 */ |
62 | 0x0000, /* R13 - ALC2 */ | 63 | { 13, 0x0000 }, /* R13 - ALC2 */ |
63 | 0x0032, /* R14 - ALC3 */ | 64 | { 14, 0x0032 }, /* R14 - ALC3 */ |
64 | }; | 65 | }; |
65 | 66 | ||
67 | static bool wm8737_volatile(struct device *dev, unsigned int reg) | ||
68 | { | ||
69 | switch (reg) { | ||
70 | case WM8737_RESET: | ||
71 | return true; | ||
72 | default: | ||
73 | return false; | ||
74 | } | ||
75 | } | ||
76 | |||
66 | static int wm8737_reset(struct snd_soc_codec *codec) | 77 | static int wm8737_reset(struct snd_soc_codec *codec) |
67 | { | 78 | { |
68 | return snd_soc_write(codec, WM8737_RESET, 0); | 79 | return snd_soc_write(codec, WM8737_RESET, 0); |
@@ -479,7 +490,7 @@ static int wm8737_set_bias_level(struct snd_soc_codec *codec, | |||
479 | return ret; | 490 | return ret; |
480 | } | 491 | } |
481 | 492 | ||
482 | snd_soc_cache_sync(codec); | 493 | regcache_sync(wm8737->regmap); |
483 | 494 | ||
484 | /* Fast VMID ramp at 2*2.5k */ | 495 | /* Fast VMID ramp at 2*2.5k */ |
485 | snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL, | 496 | snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL, |
@@ -557,24 +568,14 @@ static int wm8737_resume(struct snd_soc_codec *codec) | |||
557 | static int wm8737_probe(struct snd_soc_codec *codec) | 568 | static int wm8737_probe(struct snd_soc_codec *codec) |
558 | { | 569 | { |
559 | struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); | 570 | struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); |
560 | int ret, i; | 571 | int ret; |
561 | 572 | ||
562 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8737->control_type); | 573 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
563 | if (ret != 0) { | 574 | if (ret != 0) { |
564 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 575 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
565 | return ret; | 576 | return ret; |
566 | } | 577 | } |
567 | 578 | ||
568 | for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++) | ||
569 | wm8737->supplies[i].supply = wm8737_supply_names[i]; | ||
570 | |||
571 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8737->supplies), | ||
572 | wm8737->supplies); | ||
573 | if (ret != 0) { | ||
574 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | ||
575 | return ret; | ||
576 | } | ||
577 | |||
578 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies), | 579 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies), |
579 | wm8737->supplies); | 580 | wm8737->supplies); |
580 | if (ret != 0) { | 581 | if (ret != 0) { |
@@ -607,17 +608,12 @@ static int wm8737_probe(struct snd_soc_codec *codec) | |||
607 | err_enable: | 608 | err_enable: |
608 | regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); | 609 | regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); |
609 | err_get: | 610 | err_get: |
610 | regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); | ||
611 | |||
612 | return ret; | 611 | return ret; |
613 | } | 612 | } |
614 | 613 | ||
615 | static int wm8737_remove(struct snd_soc_codec *codec) | 614 | static int wm8737_remove(struct snd_soc_codec *codec) |
616 | { | 615 | { |
617 | struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); | ||
618 | |||
619 | wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF); | 616 | wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF); |
620 | regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); | ||
621 | return 0; | 617 | return 0; |
622 | } | 618 | } |
623 | 619 | ||
@@ -627,10 +623,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8737 = { | |||
627 | .suspend = wm8737_suspend, | 623 | .suspend = wm8737_suspend, |
628 | .resume = wm8737_resume, | 624 | .resume = wm8737_resume, |
629 | .set_bias_level = wm8737_set_bias_level, | 625 | .set_bias_level = wm8737_set_bias_level, |
630 | |||
631 | .reg_cache_size = WM8737_REGISTER_COUNT - 1, /* Skip reset */ | ||
632 | .reg_word_size = sizeof(u16), | ||
633 | .reg_cache_default = wm8737_reg, | ||
634 | }; | 626 | }; |
635 | 627 | ||
636 | static const struct of_device_id wm8737_of_match[] = { | 628 | static const struct of_device_id wm8737_of_match[] = { |
@@ -640,24 +632,49 @@ static const struct of_device_id wm8737_of_match[] = { | |||
640 | 632 | ||
641 | MODULE_DEVICE_TABLE(of, wm8737_of_match); | 633 | MODULE_DEVICE_TABLE(of, wm8737_of_match); |
642 | 634 | ||
635 | static const struct regmap_config wm8737_regmap = { | ||
636 | .reg_bits = 7, | ||
637 | .val_bits = 9, | ||
638 | .max_register = WM8737_MAX_REGISTER, | ||
639 | |||
640 | .reg_defaults = wm8737_reg_defaults, | ||
641 | .num_reg_defaults = ARRAY_SIZE(wm8737_reg_defaults), | ||
642 | .cache_type = REGCACHE_RBTREE, | ||
643 | |||
644 | .volatile_reg = wm8737_volatile, | ||
645 | }; | ||
646 | |||
643 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 647 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
644 | static __devinit int wm8737_i2c_probe(struct i2c_client *i2c, | 648 | static __devinit int wm8737_i2c_probe(struct i2c_client *i2c, |
645 | const struct i2c_device_id *id) | 649 | const struct i2c_device_id *id) |
646 | { | 650 | { |
647 | struct wm8737_priv *wm8737; | 651 | struct wm8737_priv *wm8737; |
648 | int ret; | 652 | int ret, i; |
649 | 653 | ||
650 | wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL); | 654 | wm8737 = devm_kzalloc(&i2c->dev, sizeof(struct wm8737_priv), |
655 | GFP_KERNEL); | ||
651 | if (wm8737 == NULL) | 656 | if (wm8737 == NULL) |
652 | return -ENOMEM; | 657 | return -ENOMEM; |
653 | 658 | ||
659 | for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++) | ||
660 | wm8737->supplies[i].supply = wm8737_supply_names[i]; | ||
661 | |||
662 | ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8737->supplies), | ||
663 | wm8737->supplies); | ||
664 | if (ret != 0) { | ||
665 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); | ||
666 | return ret; | ||
667 | } | ||
668 | |||
669 | wm8737->regmap = devm_regmap_init_i2c(i2c, &wm8737_regmap); | ||
670 | if (IS_ERR(wm8737->regmap)) | ||
671 | return PTR_ERR(wm8737->regmap); | ||
672 | |||
654 | i2c_set_clientdata(i2c, wm8737); | 673 | i2c_set_clientdata(i2c, wm8737); |
655 | wm8737->control_type = SND_SOC_I2C; | ||
656 | 674 | ||
657 | ret = snd_soc_register_codec(&i2c->dev, | 675 | ret = snd_soc_register_codec(&i2c->dev, |
658 | &soc_codec_dev_wm8737, &wm8737_dai, 1); | 676 | &soc_codec_dev_wm8737, &wm8737_dai, 1); |
659 | if (ret < 0) | 677 | |
660 | kfree(wm8737); | ||
661 | return ret; | 678 | return ret; |
662 | 679 | ||
663 | } | 680 | } |
@@ -665,7 +682,7 @@ static __devinit int wm8737_i2c_probe(struct i2c_client *i2c, | |||
665 | static __devexit int wm8737_i2c_remove(struct i2c_client *client) | 682 | static __devexit int wm8737_i2c_remove(struct i2c_client *client) |
666 | { | 683 | { |
667 | snd_soc_unregister_codec(&client->dev); | 684 | snd_soc_unregister_codec(&client->dev); |
668 | kfree(i2c_get_clientdata(client)); | 685 | |
669 | return 0; | 686 | return 0; |
670 | } | 687 | } |
671 | 688 | ||
@@ -691,26 +708,39 @@ static struct i2c_driver wm8737_i2c_driver = { | |||
691 | static int __devinit wm8737_spi_probe(struct spi_device *spi) | 708 | static int __devinit wm8737_spi_probe(struct spi_device *spi) |
692 | { | 709 | { |
693 | struct wm8737_priv *wm8737; | 710 | struct wm8737_priv *wm8737; |
694 | int ret; | 711 | int ret, i; |
695 | 712 | ||
696 | wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL); | 713 | wm8737 = devm_kzalloc(&spi->dev, sizeof(struct wm8737_priv), |
714 | GFP_KERNEL); | ||
697 | if (wm8737 == NULL) | 715 | if (wm8737 == NULL) |
698 | return -ENOMEM; | 716 | return -ENOMEM; |
699 | 717 | ||
700 | wm8737->control_type = SND_SOC_SPI; | 718 | for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++) |
719 | wm8737->supplies[i].supply = wm8737_supply_names[i]; | ||
720 | |||
721 | ret = devm_regulator_bulk_get(&spi->dev, ARRAY_SIZE(wm8737->supplies), | ||
722 | wm8737->supplies); | ||
723 | if (ret != 0) { | ||
724 | dev_err(&spi->dev, "Failed to request supplies: %d\n", ret); | ||
725 | return ret; | ||
726 | } | ||
727 | |||
728 | wm8737->regmap = devm_regmap_init_spi(spi, &wm8737_regmap); | ||
729 | if (IS_ERR(wm8737->regmap)) | ||
730 | return PTR_ERR(wm8737->regmap); | ||
731 | |||
701 | spi_set_drvdata(spi, wm8737); | 732 | spi_set_drvdata(spi, wm8737); |
702 | 733 | ||
703 | ret = snd_soc_register_codec(&spi->dev, | 734 | ret = snd_soc_register_codec(&spi->dev, |
704 | &soc_codec_dev_wm8737, &wm8737_dai, 1); | 735 | &soc_codec_dev_wm8737, &wm8737_dai, 1); |
705 | if (ret < 0) | 736 | |
706 | kfree(wm8737); | ||
707 | return ret; | 737 | return ret; |
708 | } | 738 | } |
709 | 739 | ||
710 | static int __devexit wm8737_spi_remove(struct spi_device *spi) | 740 | static int __devexit wm8737_spi_remove(struct spi_device *spi) |
711 | { | 741 | { |
712 | snd_soc_unregister_codec(&spi->dev); | 742 | snd_soc_unregister_codec(&spi->dev); |
713 | kfree(spi_get_drvdata(spi)); | 743 | |
714 | return 0; | 744 | return 0; |
715 | } | 745 | } |
716 | 746 | ||
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 35f3d23200e0..4281a0802138 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
19 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
20 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
21 | #include <linux/regmap.h> | ||
21 | #include <linux/regulator/consumer.h> | 22 | #include <linux/regulator/consumer.h> |
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
23 | #include <linux/of_device.h> | 24 | #include <linux/of_device.h> |
@@ -40,26 +41,43 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = { | |||
40 | 41 | ||
41 | /* codec private data */ | 42 | /* codec private data */ |
42 | struct wm8741_priv { | 43 | struct wm8741_priv { |
43 | enum snd_soc_control_type control_type; | 44 | struct regmap *regmap; |
44 | struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES]; | 45 | struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES]; |
45 | unsigned int sysclk; | 46 | unsigned int sysclk; |
46 | struct snd_pcm_hw_constraint_list *sysclk_constraints; | 47 | struct snd_pcm_hw_constraint_list *sysclk_constraints; |
47 | }; | 48 | }; |
48 | 49 | ||
49 | static const u16 wm8741_reg_defaults[WM8741_REGISTER_COUNT] = { | 50 | static const struct reg_default wm8741_reg_defaults[] = { |
50 | 0x0000, /* R0 - DACLLSB Attenuation */ | 51 | { 0, 0x0000 }, /* R0 - DACLLSB Attenuation */ |
51 | 0x0000, /* R1 - DACLMSB Attenuation */ | 52 | { 1, 0x0000 }, /* R1 - DACLMSB Attenuation */ |
52 | 0x0000, /* R2 - DACRLSB Attenuation */ | 53 | { 2, 0x0000 }, /* R2 - DACRLSB Attenuation */ |
53 | 0x0000, /* R3 - DACRMSB Attenuation */ | 54 | { 3, 0x0000 }, /* R3 - DACRMSB Attenuation */ |
54 | 0x0000, /* R4 - Volume Control */ | 55 | { 4, 0x0000 }, /* R4 - Volume Control */ |
55 | 0x000A, /* R5 - Format Control */ | 56 | { 5, 0x000A }, /* R5 - Format Control */ |
56 | 0x0000, /* R6 - Filter Control */ | 57 | { 6, 0x0000 }, /* R6 - Filter Control */ |
57 | 0x0000, /* R7 - Mode Control 1 */ | 58 | { 7, 0x0000 }, /* R7 - Mode Control 1 */ |
58 | 0x0002, /* R8 - Mode Control 2 */ | 59 | { 8, 0x0002 }, /* R8 - Mode Control 2 */ |
59 | 0x0000, /* R9 - Reset */ | 60 | { 32, 0x0002 }, /* R32 - ADDITONAL_CONTROL_1 */ |
60 | 0x0002, /* R32 - ADDITONAL_CONTROL_1 */ | ||
61 | }; | 61 | }; |
62 | 62 | ||
63 | static bool wm8741_readable(struct device *dev, unsigned int reg) | ||
64 | { | ||
65 | switch (reg) { | ||
66 | case WM8741_DACLLSB_ATTENUATION: | ||
67 | case WM8741_DACLMSB_ATTENUATION: | ||
68 | case WM8741_DACRLSB_ATTENUATION: | ||
69 | case WM8741_DACRMSB_ATTENUATION: | ||
70 | case WM8741_VOLUME_CONTROL: | ||
71 | case WM8741_FORMAT_CONTROL: | ||
72 | case WM8741_FILTER_CONTROL: | ||
73 | case WM8741_MODE_CONTROL_1: | ||
74 | case WM8741_MODE_CONTROL_2: | ||
75 | case WM8741_ADDITIONAL_CONTROL_1: | ||
76 | return true; | ||
77 | default: | ||
78 | return false; | ||
79 | } | ||
80 | } | ||
63 | 81 | ||
64 | static int wm8741_reset(struct snd_soc_codec *codec) | 82 | static int wm8741_reset(struct snd_soc_codec *codec) |
65 | { | 83 | { |
@@ -403,17 +421,6 @@ static int wm8741_probe(struct snd_soc_codec *codec) | |||
403 | { | 421 | { |
404 | struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); | 422 | struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); |
405 | int ret = 0; | 423 | int ret = 0; |
406 | int i; | ||
407 | |||
408 | for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++) | ||
409 | wm8741->supplies[i].supply = wm8741_supply_names[i]; | ||
410 | |||
411 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8741->supplies), | ||
412 | wm8741->supplies); | ||
413 | if (ret != 0) { | ||
414 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | ||
415 | goto err; | ||
416 | } | ||
417 | 424 | ||
418 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies), | 425 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies), |
419 | wm8741->supplies); | 426 | wm8741->supplies); |
@@ -422,7 +429,7 @@ static int wm8741_probe(struct snd_soc_codec *codec) | |||
422 | goto err_get; | 429 | goto err_get; |
423 | } | 430 | } |
424 | 431 | ||
425 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type); | 432 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
426 | if (ret != 0) { | 433 | if (ret != 0) { |
427 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 434 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
428 | goto err_enable; | 435 | goto err_enable; |
@@ -450,8 +457,6 @@ static int wm8741_probe(struct snd_soc_codec *codec) | |||
450 | err_enable: | 457 | err_enable: |
451 | regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); | 458 | regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); |
452 | err_get: | 459 | err_get: |
453 | regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); | ||
454 | err: | ||
455 | return ret; | 460 | return ret; |
456 | } | 461 | } |
457 | 462 | ||
@@ -460,7 +465,6 @@ static int wm8741_remove(struct snd_soc_codec *codec) | |||
460 | struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); | 465 | struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); |
461 | 466 | ||
462 | regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); | 467 | regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); |
463 | regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); | ||
464 | 468 | ||
465 | return 0; | 469 | return 0; |
466 | } | 470 | } |
@@ -469,9 +473,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8741 = { | |||
469 | .probe = wm8741_probe, | 473 | .probe = wm8741_probe, |
470 | .remove = wm8741_remove, | 474 | .remove = wm8741_remove, |
471 | .resume = wm8741_resume, | 475 | .resume = wm8741_resume, |
472 | .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults), | ||
473 | .reg_word_size = sizeof(u16), | ||
474 | .reg_cache_default = wm8741_reg_defaults, | ||
475 | 476 | ||
476 | .controls = wm8741_snd_controls, | 477 | .controls = wm8741_snd_controls, |
477 | .num_controls = ARRAY_SIZE(wm8741_snd_controls), | 478 | .num_controls = ARRAY_SIZE(wm8741_snd_controls), |
@@ -487,20 +488,48 @@ static const struct of_device_id wm8741_of_match[] = { | |||
487 | }; | 488 | }; |
488 | MODULE_DEVICE_TABLE(of, wm8741_of_match); | 489 | MODULE_DEVICE_TABLE(of, wm8741_of_match); |
489 | 490 | ||
491 | static const struct regmap_config wm8741_regmap = { | ||
492 | .reg_bits = 7, | ||
493 | .val_bits = 9, | ||
494 | .max_register = WM8741_MAX_REGISTER, | ||
495 | |||
496 | .reg_defaults = wm8741_reg_defaults, | ||
497 | .num_reg_defaults = ARRAY_SIZE(wm8741_reg_defaults), | ||
498 | .cache_type = REGCACHE_RBTREE, | ||
499 | |||
500 | .readable_reg = wm8741_readable, | ||
501 | }; | ||
502 | |||
490 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 503 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
491 | static int wm8741_i2c_probe(struct i2c_client *i2c, | 504 | static int wm8741_i2c_probe(struct i2c_client *i2c, |
492 | const struct i2c_device_id *id) | 505 | const struct i2c_device_id *id) |
493 | { | 506 | { |
494 | struct wm8741_priv *wm8741; | 507 | struct wm8741_priv *wm8741; |
495 | int ret; | 508 | int ret, i; |
496 | 509 | ||
497 | wm8741 = devm_kzalloc(&i2c->dev, sizeof(struct wm8741_priv), | 510 | wm8741 = devm_kzalloc(&i2c->dev, sizeof(struct wm8741_priv), |
498 | GFP_KERNEL); | 511 | GFP_KERNEL); |
499 | if (wm8741 == NULL) | 512 | if (wm8741 == NULL) |
500 | return -ENOMEM; | 513 | return -ENOMEM; |
501 | 514 | ||
515 | for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++) | ||
516 | wm8741->supplies[i].supply = wm8741_supply_names[i]; | ||
517 | |||
518 | ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8741->supplies), | ||
519 | wm8741->supplies); | ||
520 | if (ret != 0) { | ||
521 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); | ||
522 | return ret; | ||
523 | } | ||
524 | |||
525 | wm8741->regmap = regmap_init_i2c(i2c, &wm8741_regmap); | ||
526 | if (IS_ERR(wm8741->regmap)) { | ||
527 | ret = PTR_ERR(wm8741->regmap); | ||
528 | dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); | ||
529 | return ret; | ||
530 | } | ||
531 | |||
502 | i2c_set_clientdata(i2c, wm8741); | 532 | i2c_set_clientdata(i2c, wm8741); |
503 | wm8741->control_type = SND_SOC_I2C; | ||
504 | 533 | ||
505 | ret = snd_soc_register_codec(&i2c->dev, | 534 | ret = snd_soc_register_codec(&i2c->dev, |
506 | &soc_codec_dev_wm8741, &wm8741_dai, 1); | 535 | &soc_codec_dev_wm8741, &wm8741_dai, 1); |
@@ -536,14 +565,30 @@ static struct i2c_driver wm8741_i2c_driver = { | |||
536 | static int __devinit wm8741_spi_probe(struct spi_device *spi) | 565 | static int __devinit wm8741_spi_probe(struct spi_device *spi) |
537 | { | 566 | { |
538 | struct wm8741_priv *wm8741; | 567 | struct wm8741_priv *wm8741; |
539 | int ret; | 568 | int ret, i; |
540 | 569 | ||
541 | wm8741 = devm_kzalloc(&spi->dev, sizeof(struct wm8741_priv), | 570 | wm8741 = devm_kzalloc(&spi->dev, sizeof(struct wm8741_priv), |
542 | GFP_KERNEL); | 571 | GFP_KERNEL); |
543 | if (wm8741 == NULL) | 572 | if (wm8741 == NULL) |
544 | return -ENOMEM; | 573 | return -ENOMEM; |
545 | 574 | ||
546 | wm8741->control_type = SND_SOC_SPI; | 575 | for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++) |
576 | wm8741->supplies[i].supply = wm8741_supply_names[i]; | ||
577 | |||
578 | ret = devm_regulator_bulk_get(&spi->dev, ARRAY_SIZE(wm8741->supplies), | ||
579 | wm8741->supplies); | ||
580 | if (ret != 0) { | ||
581 | dev_err(&spi->dev, "Failed to request supplies: %d\n", ret); | ||
582 | return ret; | ||
583 | } | ||
584 | |||
585 | wm8741->regmap = regmap_init_spi(spi, &wm8741_regmap); | ||
586 | if (IS_ERR(wm8741->regmap)) { | ||
587 | ret = PTR_ERR(wm8741->regmap); | ||
588 | dev_err(&spi->dev, "Failed to init regmap: %d\n", ret); | ||
589 | return ret; | ||
590 | } | ||
591 | |||
547 | spi_set_drvdata(spi, wm8741); | 592 | spi_set_drvdata(spi, wm8741); |
548 | 593 | ||
549 | ret = snd_soc_register_codec(&spi->dev, | 594 | ret = snd_soc_register_codec(&spi->dev, |
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index a5127b4ff9e1..c7c0034d3966 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c | |||
@@ -724,24 +724,7 @@ static struct spi_driver wm8770_spi_driver = { | |||
724 | .remove = __devexit_p(wm8770_spi_remove) | 724 | .remove = __devexit_p(wm8770_spi_remove) |
725 | }; | 725 | }; |
726 | 726 | ||
727 | static int __init wm8770_modinit(void) | 727 | module_spi_driver(wm8770_spi_driver); |
728 | { | ||
729 | int ret = 0; | ||
730 | |||
731 | ret = spi_register_driver(&wm8770_spi_driver); | ||
732 | if (ret) { | ||
733 | printk(KERN_ERR "Failed to register wm8770 SPI driver: %d\n", | ||
734 | ret); | ||
735 | } | ||
736 | return ret; | ||
737 | } | ||
738 | module_init(wm8770_modinit); | ||
739 | |||
740 | static void __exit wm8770_exit(void) | ||
741 | { | ||
742 | spi_unregister_driver(&wm8770_spi_driver); | ||
743 | } | ||
744 | module_exit(wm8770_exit); | ||
745 | 728 | ||
746 | MODULE_DESCRIPTION("ASoC WM8770 driver"); | 729 | MODULE_DESCRIPTION("ASoC WM8770 driver"); |
747 | MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>"); | 730 | MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>"); |
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 879c356a9045..c32249ddb2e0 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/pm.h> | 19 | #include <linux/pm.h> |
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/of_device.h> | 21 | #include <linux/of_device.h> |
22 | #include <linux/regmap.h> | ||
22 | #include <linux/spi/spi.h> | 23 | #include <linux/spi/spi.h> |
23 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
24 | #include <sound/core.h> | 25 | #include <sound/core.h> |
@@ -37,18 +38,46 @@ enum wm8776_chip_type { | |||
37 | 38 | ||
38 | /* codec private data */ | 39 | /* codec private data */ |
39 | struct wm8776_priv { | 40 | struct wm8776_priv { |
40 | enum snd_soc_control_type control_type; | 41 | struct regmap *regmap; |
41 | int sysclk[2]; | 42 | int sysclk[2]; |
42 | }; | 43 | }; |
43 | 44 | ||
44 | static const u16 wm8776_reg[WM8776_CACHEREGNUM] = { | 45 | static const struct reg_default wm8776_reg_defaults[] = { |
45 | 0x79, 0x79, 0x79, 0xff, 0xff, /* 4 */ | 46 | { 0, 0x79 }, |
46 | 0xff, 0x00, 0x90, 0x00, 0x00, /* 9 */ | 47 | { 1, 0x79 }, |
47 | 0x22, 0x22, 0x22, 0x08, 0xcf, /* 14 */ | 48 | { 2, 0x79 }, |
48 | 0xcf, 0x7b, 0x00, 0x32, 0x00, /* 19 */ | 49 | { 3, 0xff }, |
49 | 0xa6, 0x01, 0x01 | 50 | { 4, 0xff }, |
51 | { 5, 0xff }, | ||
52 | { 6, 0x00 }, | ||
53 | { 7, 0x90 }, | ||
54 | { 8, 0x00 }, | ||
55 | { 9, 0x00 }, | ||
56 | { 10, 0x22 }, | ||
57 | { 11, 0x22 }, | ||
58 | { 12, 0x22 }, | ||
59 | { 13, 0x08 }, | ||
60 | { 14, 0xcf }, | ||
61 | { 15, 0xcf }, | ||
62 | { 16, 0x7b }, | ||
63 | { 17, 0x00 }, | ||
64 | { 18, 0x32 }, | ||
65 | { 19, 0x00 }, | ||
66 | { 20, 0xa6 }, | ||
67 | { 21, 0x01 }, | ||
68 | { 22, 0x01 }, | ||
50 | }; | 69 | }; |
51 | 70 | ||
71 | static bool wm8776_volatile(struct device *dev, unsigned int reg) | ||
72 | { | ||
73 | switch (reg) { | ||
74 | case WM8776_RESET: | ||
75 | return true; | ||
76 | default: | ||
77 | return false; | ||
78 | } | ||
79 | } | ||
80 | |||
52 | static int wm8776_reset(struct snd_soc_codec *codec) | 81 | static int wm8776_reset(struct snd_soc_codec *codec) |
53 | { | 82 | { |
54 | return snd_soc_write(codec, WM8776_RESET, 0); | 83 | return snd_soc_write(codec, WM8776_RESET, 0); |
@@ -306,6 +335,8 @@ static int wm8776_set_sysclk(struct snd_soc_dai *dai, | |||
306 | static int wm8776_set_bias_level(struct snd_soc_codec *codec, | 335 | static int wm8776_set_bias_level(struct snd_soc_codec *codec, |
307 | enum snd_soc_bias_level level) | 336 | enum snd_soc_bias_level level) |
308 | { | 337 | { |
338 | struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec); | ||
339 | |||
309 | switch (level) { | 340 | switch (level) { |
310 | case SND_SOC_BIAS_ON: | 341 | case SND_SOC_BIAS_ON: |
311 | break; | 342 | break; |
@@ -313,7 +344,7 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec, | |||
313 | break; | 344 | break; |
314 | case SND_SOC_BIAS_STANDBY: | 345 | case SND_SOC_BIAS_STANDBY: |
315 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 346 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
316 | snd_soc_cache_sync(codec); | 347 | regcache_sync(wm8776->regmap); |
317 | 348 | ||
318 | /* Disable the global powerdown; DAPM does the rest */ | 349 | /* Disable the global powerdown; DAPM does the rest */ |
319 | snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0); | 350 | snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0); |
@@ -396,10 +427,9 @@ static int wm8776_resume(struct snd_soc_codec *codec) | |||
396 | 427 | ||
397 | static int wm8776_probe(struct snd_soc_codec *codec) | 428 | static int wm8776_probe(struct snd_soc_codec *codec) |
398 | { | 429 | { |
399 | struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec); | ||
400 | int ret = 0; | 430 | int ret = 0; |
401 | 431 | ||
402 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type); | 432 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
403 | if (ret < 0) { | 433 | if (ret < 0) { |
404 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 434 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
405 | return ret; | 435 | return ret; |
@@ -434,9 +464,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8776 = { | |||
434 | .suspend = wm8776_suspend, | 464 | .suspend = wm8776_suspend, |
435 | .resume = wm8776_resume, | 465 | .resume = wm8776_resume, |
436 | .set_bias_level = wm8776_set_bias_level, | 466 | .set_bias_level = wm8776_set_bias_level, |
437 | .reg_cache_size = ARRAY_SIZE(wm8776_reg), | ||
438 | .reg_word_size = sizeof(u16), | ||
439 | .reg_cache_default = wm8776_reg, | ||
440 | 467 | ||
441 | .controls = wm8776_snd_controls, | 468 | .controls = wm8776_snd_controls, |
442 | .num_controls = ARRAY_SIZE(wm8776_snd_controls), | 469 | .num_controls = ARRAY_SIZE(wm8776_snd_controls), |
@@ -452,6 +479,18 @@ static const struct of_device_id wm8776_of_match[] = { | |||
452 | }; | 479 | }; |
453 | MODULE_DEVICE_TABLE(of, wm8776_of_match); | 480 | MODULE_DEVICE_TABLE(of, wm8776_of_match); |
454 | 481 | ||
482 | static const struct regmap_config wm8776_regmap = { | ||
483 | .reg_bits = 7, | ||
484 | .val_bits = 9, | ||
485 | .max_register = WM8776_RESET, | ||
486 | |||
487 | .reg_defaults = wm8776_reg_defaults, | ||
488 | .num_reg_defaults = ARRAY_SIZE(wm8776_reg_defaults), | ||
489 | .cache_type = REGCACHE_RBTREE, | ||
490 | |||
491 | .volatile_reg = wm8776_volatile, | ||
492 | }; | ||
493 | |||
455 | #if defined(CONFIG_SPI_MASTER) | 494 | #if defined(CONFIG_SPI_MASTER) |
456 | static int __devinit wm8776_spi_probe(struct spi_device *spi) | 495 | static int __devinit wm8776_spi_probe(struct spi_device *spi) |
457 | { | 496 | { |
@@ -463,7 +502,10 @@ static int __devinit wm8776_spi_probe(struct spi_device *spi) | |||
463 | if (wm8776 == NULL) | 502 | if (wm8776 == NULL) |
464 | return -ENOMEM; | 503 | return -ENOMEM; |
465 | 504 | ||
466 | wm8776->control_type = SND_SOC_SPI; | 505 | wm8776->regmap = devm_regmap_init_spi(spi, &wm8776_regmap); |
506 | if (IS_ERR(wm8776->regmap)) | ||
507 | return PTR_ERR(wm8776->regmap); | ||
508 | |||
467 | spi_set_drvdata(spi, wm8776); | 509 | spi_set_drvdata(spi, wm8776); |
468 | 510 | ||
469 | ret = snd_soc_register_codec(&spi->dev, | 511 | ret = snd_soc_register_codec(&spi->dev, |
@@ -501,8 +543,11 @@ static __devinit int wm8776_i2c_probe(struct i2c_client *i2c, | |||
501 | if (wm8776 == NULL) | 543 | if (wm8776 == NULL) |
502 | return -ENOMEM; | 544 | return -ENOMEM; |
503 | 545 | ||
546 | wm8776->regmap = devm_regmap_init_i2c(i2c, &wm8776_regmap); | ||
547 | if (IS_ERR(wm8776->regmap)) | ||
548 | return PTR_ERR(wm8776->regmap); | ||
549 | |||
504 | i2c_set_clientdata(i2c, wm8776); | 550 | i2c_set_clientdata(i2c, wm8776); |
505 | wm8776->control_type = SND_SOC_I2C; | ||
506 | 551 | ||
507 | ret = snd_soc_register_codec(&i2c->dev, | 552 | ret = snd_soc_register_codec(&i2c->dev, |
508 | &soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai)); | 553 | &soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai)); |
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 077c9628c70d..e781f865e5d7 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/pm.h> | 24 | #include <linux/pm.h> |
25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
26 | #include <linux/regmap.h> | ||
26 | #include <linux/spi/spi.h> | 27 | #include <linux/spi/spi.h> |
27 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
28 | #include <sound/core.h> | 29 | #include <sound/core.h> |
@@ -137,7 +138,7 @@ | |||
137 | #define WM8900_LRC_MASK 0x03ff | 138 | #define WM8900_LRC_MASK 0x03ff |
138 | 139 | ||
139 | struct wm8900_priv { | 140 | struct wm8900_priv { |
140 | enum snd_soc_control_type control_type; | 141 | struct regmap *regmap; |
141 | 142 | ||
142 | u32 fll_in; /* FLL input frequency */ | 143 | u32 fll_in; /* FLL input frequency */ |
143 | u32 fll_out; /* FLL output frequency */ | 144 | u32 fll_out; /* FLL output frequency */ |
@@ -147,54 +148,77 @@ struct wm8900_priv { | |||
147 | * wm8900 register cache. We can't read the entire register space and we | 148 | * wm8900 register cache. We can't read the entire register space and we |
148 | * have slow control buses so we cache the registers. | 149 | * have slow control buses so we cache the registers. |
149 | */ | 150 | */ |
150 | static const u16 wm8900_reg_defaults[WM8900_MAXREG] = { | 151 | static const struct reg_default wm8900_reg_defaults[] = { |
151 | 0x8900, 0x0000, | 152 | { 1, 0x0000 }, |
152 | 0xc000, 0x0000, | 153 | { 2, 0xc000 }, |
153 | 0x4050, 0x4000, | 154 | { 3, 0x0000 }, |
154 | 0x0008, 0x0000, | 155 | { 4, 0x4050 }, |
155 | 0x0040, 0x0040, | 156 | { 5, 0x4000 }, |
156 | 0x1004, 0x00c0, | 157 | { 6, 0x0008 }, |
157 | 0x00c0, 0x0000, | 158 | { 7, 0x0000 }, |
158 | 0x0100, 0x00c0, | 159 | { 8, 0x0040 }, |
159 | 0x00c0, 0x0000, | 160 | { 9, 0x0040 }, |
160 | 0xb001, 0x0000, | 161 | { 10, 0x1004 }, |
161 | 0x0000, 0x0044, | 162 | { 11, 0x00c0 }, |
162 | 0x004c, 0x004c, | 163 | { 12, 0x00c0 }, |
163 | 0x0044, 0x0044, | 164 | { 13, 0x0000 }, |
164 | 0x0000, 0x0044, | 165 | { 14, 0x0100 }, |
165 | 0x0000, 0x0000, | 166 | { 15, 0x00c0 }, |
166 | 0x0002, 0x0000, | 167 | { 16, 0x00c0 }, |
167 | 0x0000, 0x0000, | 168 | { 17, 0x0000 }, |
168 | 0x0000, 0x0000, | 169 | { 18, 0xb001 }, |
169 | 0x0008, 0x0000, | 170 | { 19, 0x0000 }, |
170 | 0x0000, 0x0008, | 171 | { 20, 0x0000 }, |
171 | 0x0097, 0x0100, | 172 | { 21, 0x0044 }, |
172 | 0x0000, 0x0000, | 173 | { 22, 0x004c }, |
173 | 0x0050, 0x0050, | 174 | { 23, 0x004c }, |
174 | 0x0055, 0x0055, | 175 | { 24, 0x0044 }, |
175 | 0x0055, 0x0000, | 176 | { 25, 0x0044 }, |
176 | 0x0000, 0x0079, | 177 | { 26, 0x0000 }, |
177 | 0x0079, 0x0079, | 178 | { 27, 0x0044 }, |
178 | 0x0079, 0x0000, | 179 | { 28, 0x0000 }, |
179 | /* Remaining registers all zero */ | 180 | { 29, 0x0000 }, |
181 | { 30, 0x0002 }, | ||
182 | { 31, 0x0000 }, | ||
183 | { 32, 0x0000 }, | ||
184 | { 33, 0x0000 }, | ||
185 | { 34, 0x0000 }, | ||
186 | { 35, 0x0000 }, | ||
187 | { 36, 0x0008 }, | ||
188 | { 37, 0x0000 }, | ||
189 | { 38, 0x0000 }, | ||
190 | { 39, 0x0008 }, | ||
191 | { 40, 0x0097 }, | ||
192 | { 41, 0x0100 }, | ||
193 | { 42, 0x0000 }, | ||
194 | { 43, 0x0000 }, | ||
195 | { 44, 0x0050 }, | ||
196 | { 45, 0x0050 }, | ||
197 | { 46, 0x0055 }, | ||
198 | { 47, 0x0055 }, | ||
199 | { 48, 0x0055 }, | ||
200 | { 49, 0x0000 }, | ||
201 | { 50, 0x0000 }, | ||
202 | { 51, 0x0079 }, | ||
203 | { 52, 0x0079 }, | ||
204 | { 53, 0x0079 }, | ||
205 | { 54, 0x0079 }, | ||
206 | { 55, 0x0000 }, | ||
180 | }; | 207 | }; |
181 | 208 | ||
182 | static int wm8900_volatile_register(struct snd_soc_codec *codec, unsigned int reg) | 209 | static bool wm8900_volatile_register(struct device *dev, unsigned int reg) |
183 | { | 210 | { |
184 | switch (reg) { | 211 | switch (reg) { |
185 | case WM8900_REG_ID: | 212 | case WM8900_REG_ID: |
186 | return 1; | 213 | return true; |
187 | default: | 214 | default: |
188 | return 0; | 215 | return false; |
189 | } | 216 | } |
190 | } | 217 | } |
191 | 218 | ||
192 | static void wm8900_reset(struct snd_soc_codec *codec) | 219 | static void wm8900_reset(struct snd_soc_codec *codec) |
193 | { | 220 | { |
194 | snd_soc_write(codec, WM8900_REG_RESET, 0); | 221 | snd_soc_write(codec, WM8900_REG_RESET, 0); |
195 | |||
196 | memcpy(codec->reg_cache, wm8900_reg_defaults, | ||
197 | sizeof(wm8900_reg_defaults)); | ||
198 | } | 222 | } |
199 | 223 | ||
200 | static int wm8900_hp_event(struct snd_soc_dapm_widget *w, | 224 | static int wm8900_hp_event(struct snd_soc_dapm_widget *w, |
@@ -469,10 +493,10 @@ SOC_DAPM_SINGLE("RINPUT2 Switch", WM8900_REG_INCTL, 1, 1, 0), | |||
469 | SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INCTL, 0, 1, 0), | 493 | SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INCTL, 0, 1, 0), |
470 | }; | 494 | }; |
471 | 495 | ||
472 | static const char *wm9700_lp_mux[] = { "Disabled", "Enabled" }; | 496 | static const char *wm8900_lp_mux[] = { "Disabled", "Enabled" }; |
473 | 497 | ||
474 | static const struct soc_enum wm8900_lineout2_lp_mux = | 498 | static const struct soc_enum wm8900_lineout2_lp_mux = |
475 | SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm9700_lp_mux); | 499 | SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm8900_lp_mux); |
476 | 500 | ||
477 | static const struct snd_kcontrol_new wm8900_lineout2_lp = | 501 | static const struct snd_kcontrol_new wm8900_lineout2_lp = |
478 | SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux); | 502 | SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux); |
@@ -1119,13 +1143,16 @@ static int wm8900_suspend(struct snd_soc_codec *codec) | |||
1119 | static int wm8900_resume(struct snd_soc_codec *codec) | 1143 | static int wm8900_resume(struct snd_soc_codec *codec) |
1120 | { | 1144 | { |
1121 | struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); | 1145 | struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); |
1122 | u16 *cache; | 1146 | int ret; |
1123 | int i, ret; | ||
1124 | |||
1125 | cache = kmemdup(codec->reg_cache, sizeof(wm8900_reg_defaults), | ||
1126 | GFP_KERNEL); | ||
1127 | 1147 | ||
1128 | wm8900_reset(codec); | 1148 | wm8900_reset(codec); |
1149 | |||
1150 | ret = regcache_sync(wm8900->regmap); | ||
1151 | if (ret != 0) { | ||
1152 | dev_err(codec->dev, "Failed to restore cache: %d\n", ret); | ||
1153 | return ret; | ||
1154 | } | ||
1155 | |||
1129 | wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1156 | wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1130 | 1157 | ||
1131 | /* Restart the FLL? */ | 1158 | /* Restart the FLL? */ |
@@ -1139,27 +1166,18 @@ static int wm8900_resume(struct snd_soc_codec *codec) | |||
1139 | ret = wm8900_set_fll(codec, 0, fll_in, fll_out); | 1166 | ret = wm8900_set_fll(codec, 0, fll_in, fll_out); |
1140 | if (ret != 0) { | 1167 | if (ret != 0) { |
1141 | dev_err(codec->dev, "Failed to restart FLL\n"); | 1168 | dev_err(codec->dev, "Failed to restart FLL\n"); |
1142 | kfree(cache); | ||
1143 | return ret; | 1169 | return ret; |
1144 | } | 1170 | } |
1145 | } | 1171 | } |
1146 | 1172 | ||
1147 | if (cache) { | ||
1148 | for (i = 0; i < WM8900_MAXREG; i++) | ||
1149 | snd_soc_write(codec, i, cache[i]); | ||
1150 | kfree(cache); | ||
1151 | } else | ||
1152 | dev_err(codec->dev, "Unable to allocate register cache\n"); | ||
1153 | |||
1154 | return 0; | 1173 | return 0; |
1155 | } | 1174 | } |
1156 | 1175 | ||
1157 | static int wm8900_probe(struct snd_soc_codec *codec) | 1176 | static int wm8900_probe(struct snd_soc_codec *codec) |
1158 | { | 1177 | { |
1159 | struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); | ||
1160 | int ret = 0, reg; | 1178 | int ret = 0, reg; |
1161 | 1179 | ||
1162 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8900->control_type); | 1180 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); |
1163 | if (ret != 0) { | 1181 | if (ret != 0) { |
1164 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 1182 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
1165 | return ret; | 1183 | return ret; |
@@ -1207,10 +1225,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8900 = { | |||
1207 | .suspend = wm8900_suspend, | 1225 | .suspend = wm8900_suspend, |
1208 | .resume = wm8900_resume, | 1226 | .resume = wm8900_resume, |
1209 | .set_bias_level = wm8900_set_bias_level, | 1227 | .set_bias_level = wm8900_set_bias_level, |
1210 | .volatile_register = wm8900_volatile_register, | ||
1211 | .reg_cache_size = ARRAY_SIZE(wm8900_reg_defaults), | ||
1212 | .reg_word_size = sizeof(u16), | ||
1213 | .reg_cache_default = wm8900_reg_defaults, | ||
1214 | 1228 | ||
1215 | .controls = wm8900_snd_controls, | 1229 | .controls = wm8900_snd_controls, |
1216 | .num_controls = ARRAY_SIZE(wm8900_snd_controls), | 1230 | .num_controls = ARRAY_SIZE(wm8900_snd_controls), |
@@ -1220,30 +1234,44 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8900 = { | |||
1220 | .num_dapm_routes = ARRAY_SIZE(wm8900_dapm_routes), | 1234 | .num_dapm_routes = ARRAY_SIZE(wm8900_dapm_routes), |
1221 | }; | 1235 | }; |
1222 | 1236 | ||
1237 | static const struct regmap_config wm8900_regmap = { | ||
1238 | .reg_bits = 8, | ||
1239 | .val_bits = 16, | ||
1240 | .max_register = WM8900_MAXREG, | ||
1241 | |||
1242 | .reg_defaults = wm8900_reg_defaults, | ||
1243 | .num_reg_defaults = ARRAY_SIZE(wm8900_reg_defaults), | ||
1244 | .cache_type = REGCACHE_RBTREE, | ||
1245 | |||
1246 | .volatile_reg = wm8900_volatile_register, | ||
1247 | }; | ||
1248 | |||
1223 | #if defined(CONFIG_SPI_MASTER) | 1249 | #if defined(CONFIG_SPI_MASTER) |
1224 | static int __devinit wm8900_spi_probe(struct spi_device *spi) | 1250 | static int __devinit wm8900_spi_probe(struct spi_device *spi) |
1225 | { | 1251 | { |
1226 | struct wm8900_priv *wm8900; | 1252 | struct wm8900_priv *wm8900; |
1227 | int ret; | 1253 | int ret; |
1228 | 1254 | ||
1229 | wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL); | 1255 | wm8900 = devm_kzalloc(&spi->dev, sizeof(struct wm8900_priv), |
1256 | GFP_KERNEL); | ||
1230 | if (wm8900 == NULL) | 1257 | if (wm8900 == NULL) |
1231 | return -ENOMEM; | 1258 | return -ENOMEM; |
1232 | 1259 | ||
1233 | wm8900->control_type = SND_SOC_SPI; | 1260 | wm8900->regmap = devm_regmap_init_spi(spi, &wm8900_regmap); |
1261 | if (IS_ERR(wm8900->regmap)) | ||
1262 | return PTR_ERR(wm8900->regmap); | ||
1263 | |||
1234 | spi_set_drvdata(spi, wm8900); | 1264 | spi_set_drvdata(spi, wm8900); |
1235 | 1265 | ||
1236 | ret = snd_soc_register_codec(&spi->dev, | 1266 | ret = snd_soc_register_codec(&spi->dev, |
1237 | &soc_codec_dev_wm8900, &wm8900_dai, 1); | 1267 | &soc_codec_dev_wm8900, &wm8900_dai, 1); |
1238 | if (ret < 0) | 1268 | |
1239 | kfree(wm8900); | ||
1240 | return ret; | 1269 | return ret; |
1241 | } | 1270 | } |
1242 | 1271 | ||
1243 | static int __devexit wm8900_spi_remove(struct spi_device *spi) | 1272 | static int __devexit wm8900_spi_remove(struct spi_device *spi) |
1244 | { | 1273 | { |
1245 | snd_soc_unregister_codec(&spi->dev); | 1274 | snd_soc_unregister_codec(&spi->dev); |
1246 | kfree(spi_get_drvdata(spi)); | ||
1247 | return 0; | 1275 | return 0; |
1248 | } | 1276 | } |
1249 | 1277 | ||
@@ -1264,24 +1292,26 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c, | |||
1264 | struct wm8900_priv *wm8900; | 1292 | struct wm8900_priv *wm8900; |
1265 | int ret; | 1293 | int ret; |
1266 | 1294 | ||
1267 | wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL); | 1295 | wm8900 = devm_kzalloc(&i2c->dev, sizeof(struct wm8900_priv), |
1296 | GFP_KERNEL); | ||
1268 | if (wm8900 == NULL) | 1297 | if (wm8900 == NULL) |
1269 | return -ENOMEM; | 1298 | return -ENOMEM; |
1270 | 1299 | ||
1300 | wm8900->regmap = devm_regmap_init_i2c(i2c, &wm8900_regmap); | ||
1301 | if (IS_ERR(wm8900->regmap)) | ||
1302 | return PTR_ERR(wm8900->regmap); | ||
1303 | |||
1271 | i2c_set_clientdata(i2c, wm8900); | 1304 | i2c_set_clientdata(i2c, wm8900); |
1272 | wm8900->control_type = SND_SOC_I2C; | ||
1273 | 1305 | ||
1274 | ret = snd_soc_register_codec(&i2c->dev, | 1306 | ret = snd_soc_register_codec(&i2c->dev, |
1275 | &soc_codec_dev_wm8900, &wm8900_dai, 1); | 1307 | &soc_codec_dev_wm8900, &wm8900_dai, 1); |
1276 | if (ret < 0) | 1308 | |
1277 | kfree(wm8900); | ||
1278 | return ret; | 1309 | return ret; |
1279 | } | 1310 | } |
1280 | 1311 | ||
1281 | static __devexit int wm8900_i2c_remove(struct i2c_client *client) | 1312 | static __devexit int wm8900_i2c_remove(struct i2c_client *client) |
1282 | { | 1313 | { |
1283 | snd_soc_unregister_codec(&client->dev); | 1314 | snd_soc_unregister_codec(&client->dev); |
1284 | kfree(i2c_get_clientdata(client)); | ||
1285 | return 0; | 1315 | return 0; |
1286 | } | 1316 | } |
1287 | 1317 | ||
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 73f1c8d7bafb..839414f9e2ed 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c | |||
@@ -2241,23 +2241,7 @@ static struct i2c_driver wm8903_i2c_driver = { | |||
2241 | .id_table = wm8903_i2c_id, | 2241 | .id_table = wm8903_i2c_id, |
2242 | }; | 2242 | }; |
2243 | 2243 | ||
2244 | static int __init wm8903_modinit(void) | 2244 | module_i2c_driver(wm8903_i2c_driver); |
2245 | { | ||
2246 | int ret = 0; | ||
2247 | ret = i2c_add_driver(&wm8903_i2c_driver); | ||
2248 | if (ret != 0) { | ||
2249 | printk(KERN_ERR "Failed to register wm8903 I2C driver: %d\n", | ||
2250 | ret); | ||
2251 | } | ||
2252 | return ret; | ||
2253 | } | ||
2254 | module_init(wm8903_modinit); | ||
2255 | |||
2256 | static void __exit wm8903_exit(void) | ||
2257 | { | ||
2258 | i2c_del_driver(&wm8903_i2c_driver); | ||
2259 | } | ||
2260 | module_exit(wm8903_exit); | ||
2261 | 2245 | ||
2262 | MODULE_DESCRIPTION("ASoC WM8903 driver"); | 2246 | MODULE_DESCRIPTION("ASoC WM8903 driver"); |
2263 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>"); | 2247 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>"); |
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 0013afe48e66..7c8df52a8d9d 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c | |||
@@ -100,7 +100,7 @@ static const struct reg_default wm8904_reg_defaults[] = { | |||
100 | { 14, 0x0000 }, /* R14 - Power Management 2 */ | 100 | { 14, 0x0000 }, /* R14 - Power Management 2 */ |
101 | { 15, 0x0000 }, /* R15 - Power Management 3 */ | 101 | { 15, 0x0000 }, /* R15 - Power Management 3 */ |
102 | { 18, 0x0000 }, /* R18 - Power Management 6 */ | 102 | { 18, 0x0000 }, /* R18 - Power Management 6 */ |
103 | { 19, 0x945E }, /* R20 - Clock Rates 0 */ | 103 | { 20, 0x945E }, /* R20 - Clock Rates 0 */ |
104 | { 21, 0x0C05 }, /* R21 - Clock Rates 1 */ | 104 | { 21, 0x0C05 }, /* R21 - Clock Rates 1 */ |
105 | { 22, 0x0006 }, /* R22 - Clock Rates 2 */ | 105 | { 22, 0x0006 }, /* R22 - Clock Rates 2 */ |
106 | { 24, 0x0050 }, /* R24 - Audio Interface 0 */ | 106 | { 24, 0x0050 }, /* R24 - Audio Interface 0 */ |
@@ -1185,8 +1185,6 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec) | |||
1185 | snd_soc_dapm_new_controls(dapm, wm8904_dapm_widgets, | 1185 | snd_soc_dapm_new_controls(dapm, wm8904_dapm_widgets, |
1186 | ARRAY_SIZE(wm8904_dapm_widgets)); | 1186 | ARRAY_SIZE(wm8904_dapm_widgets)); |
1187 | 1187 | ||
1188 | snd_soc_dapm_add_routes(dapm, core_intercon, | ||
1189 | ARRAY_SIZE(core_intercon)); | ||
1190 | snd_soc_dapm_add_routes(dapm, adc_intercon, | 1188 | snd_soc_dapm_add_routes(dapm, adc_intercon, |
1191 | ARRAY_SIZE(adc_intercon)); | 1189 | ARRAY_SIZE(adc_intercon)); |
1192 | snd_soc_dapm_add_routes(dapm, dac_intercon, | 1190 | snd_soc_dapm_add_routes(dapm, dac_intercon, |
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 481a3d9cfe48..b20aa4e7c3f9 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c | |||
@@ -785,23 +785,7 @@ static struct i2c_driver wm8940_i2c_driver = { | |||
785 | .id_table = wm8940_i2c_id, | 785 | .id_table = wm8940_i2c_id, |
786 | }; | 786 | }; |
787 | 787 | ||
788 | static int __init wm8940_modinit(void) | 788 | module_i2c_driver(wm8940_i2c_driver); |
789 | { | ||
790 | int ret = 0; | ||
791 | ret = i2c_add_driver(&wm8940_i2c_driver); | ||
792 | if (ret != 0) { | ||
793 | printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n", | ||
794 | ret); | ||
795 | } | ||
796 | return ret; | ||
797 | } | ||
798 | module_init(wm8940_modinit); | ||
799 | |||
800 | static void __exit wm8940_exit(void) | ||
801 | { | ||
802 | i2c_del_driver(&wm8940_i2c_driver); | ||
803 | } | ||
804 | module_exit(wm8940_exit); | ||
805 | 789 | ||
806 | MODULE_DESCRIPTION("ASoC WM8940 driver"); | 790 | MODULE_DESCRIPTION("ASoC WM8940 driver"); |
807 | MODULE_AUTHOR("Jonathan Cameron"); | 791 | MODULE_AUTHOR("Jonathan Cameron"); |
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 61fe97433e73..2f1c075755b1 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c | |||
@@ -1071,23 +1071,7 @@ static struct i2c_driver wm8955_i2c_driver = { | |||
1071 | .id_table = wm8955_i2c_id, | 1071 | .id_table = wm8955_i2c_id, |
1072 | }; | 1072 | }; |
1073 | 1073 | ||
1074 | static int __init wm8955_modinit(void) | 1074 | module_i2c_driver(wm8955_i2c_driver); |
1075 | { | ||
1076 | int ret = 0; | ||
1077 | ret = i2c_add_driver(&wm8955_i2c_driver); | ||
1078 | if (ret != 0) { | ||
1079 | printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n", | ||
1080 | ret); | ||
1081 | } | ||
1082 | return ret; | ||
1083 | } | ||
1084 | module_init(wm8955_modinit); | ||
1085 | |||
1086 | static void __exit wm8955_exit(void) | ||
1087 | { | ||
1088 | i2c_del_driver(&wm8955_i2c_driver); | ||
1089 | } | ||
1090 | module_exit(wm8955_exit); | ||
1091 | 1075 | ||
1092 | MODULE_DESCRIPTION("ASoC WM8955 driver"); | 1076 | MODULE_DESCRIPTION("ASoC WM8955 driver"); |
1093 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 1077 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 1332692ef81b..00121ba36597 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c | |||
@@ -946,7 +946,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
946 | wm8994->mbc_texts = kmalloc(sizeof(char *) | 946 | wm8994->mbc_texts = kmalloc(sizeof(char *) |
947 | * pdata->num_mbc_cfgs, GFP_KERNEL); | 947 | * pdata->num_mbc_cfgs, GFP_KERNEL); |
948 | if (!wm8994->mbc_texts) { | 948 | if (!wm8994->mbc_texts) { |
949 | dev_err(wm8994->codec->dev, | 949 | dev_err(wm8994->hubs.codec->dev, |
950 | "Failed to allocate %d MBC config texts\n", | 950 | "Failed to allocate %d MBC config texts\n", |
951 | pdata->num_mbc_cfgs); | 951 | pdata->num_mbc_cfgs); |
952 | return; | 952 | return; |
@@ -958,9 +958,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
958 | wm8994->mbc_enum.max = pdata->num_mbc_cfgs; | 958 | wm8994->mbc_enum.max = pdata->num_mbc_cfgs; |
959 | wm8994->mbc_enum.texts = wm8994->mbc_texts; | 959 | wm8994->mbc_enum.texts = wm8994->mbc_texts; |
960 | 960 | ||
961 | ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); | 961 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, |
962 | control, 1); | ||
962 | if (ret != 0) | 963 | if (ret != 0) |
963 | dev_err(wm8994->codec->dev, | 964 | dev_err(wm8994->hubs.codec->dev, |
964 | "Failed to add MBC mode controls: %d\n", ret); | 965 | "Failed to add MBC mode controls: %d\n", ret); |
965 | } | 966 | } |
966 | 967 | ||
@@ -974,7 +975,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
974 | wm8994->vss_texts = kmalloc(sizeof(char *) | 975 | wm8994->vss_texts = kmalloc(sizeof(char *) |
975 | * pdata->num_vss_cfgs, GFP_KERNEL); | 976 | * pdata->num_vss_cfgs, GFP_KERNEL); |
976 | if (!wm8994->vss_texts) { | 977 | if (!wm8994->vss_texts) { |
977 | dev_err(wm8994->codec->dev, | 978 | dev_err(wm8994->hubs.codec->dev, |
978 | "Failed to allocate %d VSS config texts\n", | 979 | "Failed to allocate %d VSS config texts\n", |
979 | pdata->num_vss_cfgs); | 980 | pdata->num_vss_cfgs); |
980 | return; | 981 | return; |
@@ -986,9 +987,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
986 | wm8994->vss_enum.max = pdata->num_vss_cfgs; | 987 | wm8994->vss_enum.max = pdata->num_vss_cfgs; |
987 | wm8994->vss_enum.texts = wm8994->vss_texts; | 988 | wm8994->vss_enum.texts = wm8994->vss_texts; |
988 | 989 | ||
989 | ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); | 990 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, |
991 | control, 1); | ||
990 | if (ret != 0) | 992 | if (ret != 0) |
991 | dev_err(wm8994->codec->dev, | 993 | dev_err(wm8994->hubs.codec->dev, |
992 | "Failed to add VSS mode controls: %d\n", ret); | 994 | "Failed to add VSS mode controls: %d\n", ret); |
993 | } | 995 | } |
994 | 996 | ||
@@ -1003,7 +1005,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
1003 | wm8994->vss_hpf_texts = kmalloc(sizeof(char *) | 1005 | wm8994->vss_hpf_texts = kmalloc(sizeof(char *) |
1004 | * pdata->num_vss_hpf_cfgs, GFP_KERNEL); | 1006 | * pdata->num_vss_hpf_cfgs, GFP_KERNEL); |
1005 | if (!wm8994->vss_hpf_texts) { | 1007 | if (!wm8994->vss_hpf_texts) { |
1006 | dev_err(wm8994->codec->dev, | 1008 | dev_err(wm8994->hubs.codec->dev, |
1007 | "Failed to allocate %d VSS HPF config texts\n", | 1009 | "Failed to allocate %d VSS HPF config texts\n", |
1008 | pdata->num_vss_hpf_cfgs); | 1010 | pdata->num_vss_hpf_cfgs); |
1009 | return; | 1011 | return; |
@@ -1015,9 +1017,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
1015 | wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs; | 1017 | wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs; |
1016 | wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; | 1018 | wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; |
1017 | 1019 | ||
1018 | ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); | 1020 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, |
1021 | control, 1); | ||
1019 | if (ret != 0) | 1022 | if (ret != 0) |
1020 | dev_err(wm8994->codec->dev, | 1023 | dev_err(wm8994->hubs.codec->dev, |
1021 | "Failed to add VSS HPFmode controls: %d\n", | 1024 | "Failed to add VSS HPFmode controls: %d\n", |
1022 | ret); | 1025 | ret); |
1023 | } | 1026 | } |
@@ -1033,7 +1036,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
1033 | wm8994->enh_eq_texts = kmalloc(sizeof(char *) | 1036 | wm8994->enh_eq_texts = kmalloc(sizeof(char *) |
1034 | * pdata->num_enh_eq_cfgs, GFP_KERNEL); | 1037 | * pdata->num_enh_eq_cfgs, GFP_KERNEL); |
1035 | if (!wm8994->enh_eq_texts) { | 1038 | if (!wm8994->enh_eq_texts) { |
1036 | dev_err(wm8994->codec->dev, | 1039 | dev_err(wm8994->hubs.codec->dev, |
1037 | "Failed to allocate %d enhanced EQ config texts\n", | 1040 | "Failed to allocate %d enhanced EQ config texts\n", |
1038 | pdata->num_enh_eq_cfgs); | 1041 | pdata->num_enh_eq_cfgs); |
1039 | return; | 1042 | return; |
@@ -1045,9 +1048,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
1045 | wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs; | 1048 | wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs; |
1046 | wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; | 1049 | wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; |
1047 | 1050 | ||
1048 | ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); | 1051 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, |
1052 | control, 1); | ||
1049 | if (ret != 0) | 1053 | if (ret != 0) |
1050 | dev_err(wm8994->codec->dev, | 1054 | dev_err(wm8994->hubs.codec->dev, |
1051 | "Failed to add enhanced EQ controls: %d\n", | 1055 | "Failed to add enhanced EQ controls: %d\n", |
1052 | ret); | 1056 | ret); |
1053 | } | 1057 | } |
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 96518ac8e24c..f0f6f6601785 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
@@ -52,25 +52,72 @@ | |||
52 | * We can't read the WM8960 register space when we are | 52 | * We can't read the WM8960 register space when we are |
53 | * using 2 wire for device control, so we cache them instead. | 53 | * using 2 wire for device control, so we cache them instead. |
54 | */ | 54 | */ |
55 | static const u16 wm8960_reg[WM8960_CACHEREGNUM] = { | 55 | static const struct reg_default wm8960_reg_defaults[] = { |
56 | 0x0097, 0x0097, 0x0000, 0x0000, | 56 | { 0x0, 0x0097 }, |
57 | 0x0000, 0x0008, 0x0000, 0x000a, | 57 | { 0x1, 0x0097 }, |
58 | 0x01c0, 0x0000, 0x00ff, 0x00ff, | 58 | { 0x2, 0x0000 }, |
59 | 0x0000, 0x0000, 0x0000, 0x0000, | 59 | { 0x3, 0x0000 }, |
60 | 0x0000, 0x007b, 0x0100, 0x0032, | 60 | { 0x4, 0x0000 }, |
61 | 0x0000, 0x00c3, 0x00c3, 0x01c0, | 61 | { 0x5, 0x0008 }, |
62 | 0x0000, 0x0000, 0x0000, 0x0000, | 62 | { 0x6, 0x0000 }, |
63 | 0x0000, 0x0000, 0x0000, 0x0000, | 63 | { 0x7, 0x000a }, |
64 | 0x0100, 0x0100, 0x0050, 0x0050, | 64 | { 0x8, 0x01c0 }, |
65 | 0x0050, 0x0050, 0x0000, 0x0000, | 65 | { 0x9, 0x0000 }, |
66 | 0x0000, 0x0000, 0x0040, 0x0000, | 66 | { 0xa, 0x00ff }, |
67 | 0x0000, 0x0050, 0x0050, 0x0000, | 67 | { 0xb, 0x00ff }, |
68 | 0x0002, 0x0037, 0x004d, 0x0080, | 68 | |
69 | 0x0008, 0x0031, 0x0026, 0x00e9, | 69 | { 0x10, 0x0000 }, |
70 | { 0x11, 0x007b }, | ||
71 | { 0x12, 0x0100 }, | ||
72 | { 0x13, 0x0032 }, | ||
73 | { 0x14, 0x0000 }, | ||
74 | { 0x15, 0x00c3 }, | ||
75 | { 0x16, 0x00c3 }, | ||
76 | { 0x17, 0x01c0 }, | ||
77 | { 0x18, 0x0000 }, | ||
78 | { 0x19, 0x0000 }, | ||
79 | { 0x1a, 0x0000 }, | ||
80 | { 0x1b, 0x0000 }, | ||
81 | { 0x1c, 0x0000 }, | ||
82 | { 0x1d, 0x0000 }, | ||
83 | |||
84 | { 0x20, 0x0100 }, | ||
85 | { 0x21, 0x0100 }, | ||
86 | { 0x22, 0x0050 }, | ||
87 | |||
88 | { 0x25, 0x0050 }, | ||
89 | { 0x26, 0x0000 }, | ||
90 | { 0x27, 0x0000 }, | ||
91 | { 0x28, 0x0000 }, | ||
92 | { 0x29, 0x0000 }, | ||
93 | { 0x2a, 0x0040 }, | ||
94 | { 0x2b, 0x0000 }, | ||
95 | { 0x2c, 0x0000 }, | ||
96 | { 0x2d, 0x0050 }, | ||
97 | { 0x2e, 0x0050 }, | ||
98 | { 0x2f, 0x0000 }, | ||
99 | { 0x30, 0x0002 }, | ||
100 | { 0x31, 0x0037 }, | ||
101 | |||
102 | { 0x33, 0x0080 }, | ||
103 | { 0x34, 0x0008 }, | ||
104 | { 0x35, 0x0031 }, | ||
105 | { 0x36, 0x0026 }, | ||
106 | { 0x37, 0x00e9 }, | ||
70 | }; | 107 | }; |
71 | 108 | ||
109 | static bool wm8960_volatile(struct device *dev, unsigned int reg) | ||
110 | { | ||
111 | switch (reg) { | ||
112 | case WM8960_RESET: | ||
113 | return true; | ||
114 | default: | ||
115 | return false; | ||
116 | } | ||
117 | } | ||
118 | |||
72 | struct wm8960_priv { | 119 | struct wm8960_priv { |
73 | enum snd_soc_control_type control_type; | 120 | struct regmap *regmap; |
74 | int (*set_bias_level)(struct snd_soc_codec *, | 121 | int (*set_bias_level)(struct snd_soc_codec *, |
75 | enum snd_soc_bias_level level); | 122 | enum snd_soc_bias_level level); |
76 | struct snd_soc_dapm_widget *lout1; | 123 | struct snd_soc_dapm_widget *lout1; |
@@ -510,18 +557,25 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream, | |||
510 | struct snd_soc_codec *codec = dai->codec; | 557 | struct snd_soc_codec *codec = dai->codec; |
511 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); | 558 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); |
512 | u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3; | 559 | u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3; |
560 | snd_pcm_format_t format = params_format(params); | ||
513 | int i; | 561 | int i; |
514 | 562 | ||
515 | /* bit size */ | 563 | /* bit size */ |
516 | switch (params_format(params)) { | 564 | switch (format) { |
517 | case SNDRV_PCM_FORMAT_S16_LE: | 565 | case SNDRV_PCM_FORMAT_S16_LE: |
566 | case SNDRV_PCM_FORMAT_S16_BE: | ||
518 | break; | 567 | break; |
519 | case SNDRV_PCM_FORMAT_S20_3LE: | 568 | case SNDRV_PCM_FORMAT_S20_3LE: |
569 | case SNDRV_PCM_FORMAT_S20_3BE: | ||
520 | iface |= 0x0004; | 570 | iface |= 0x0004; |
521 | break; | 571 | break; |
522 | case SNDRV_PCM_FORMAT_S24_LE: | 572 | case SNDRV_PCM_FORMAT_S24_LE: |
573 | case SNDRV_PCM_FORMAT_S24_BE: | ||
523 | iface |= 0x0008; | 574 | iface |= 0x0008; |
524 | break; | 575 | break; |
576 | default: | ||
577 | dev_err(codec->dev, "unsupported format %i\n", format); | ||
578 | return -EINVAL; | ||
525 | } | 579 | } |
526 | 580 | ||
527 | /* Update filters for the new rate */ | 581 | /* Update filters for the new rate */ |
@@ -555,6 +609,8 @@ static int wm8960_mute(struct snd_soc_dai *dai, int mute) | |||
555 | static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec, | 609 | static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec, |
556 | enum snd_soc_bias_level level) | 610 | enum snd_soc_bias_level level) |
557 | { | 611 | { |
612 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); | ||
613 | |||
558 | switch (level) { | 614 | switch (level) { |
559 | case SND_SOC_BIAS_ON: | 615 | case SND_SOC_BIAS_ON: |
560 | break; | 616 | break; |
@@ -566,7 +622,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec, | |||
566 | 622 | ||
567 | case SND_SOC_BIAS_STANDBY: | 623 | case SND_SOC_BIAS_STANDBY: |
568 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 624 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
569 | snd_soc_cache_sync(codec); | 625 | regcache_sync(wm8960->regmap); |
570 | 626 | ||
571 | /* Enable anti-pop features */ | 627 | /* Enable anti-pop features */ |
572 | snd_soc_write(codec, WM8960_APOP1, | 628 | snd_soc_write(codec, WM8960_APOP1, |
@@ -667,7 +723,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec, | |||
667 | break; | 723 | break; |
668 | 724 | ||
669 | case SND_SOC_BIAS_OFF: | 725 | case SND_SOC_BIAS_OFF: |
670 | snd_soc_cache_sync(codec); | 726 | regcache_sync(wm8960->regmap); |
671 | break; | 727 | break; |
672 | default: | 728 | default: |
673 | break; | 729 | break; |
@@ -906,16 +962,11 @@ static int wm8960_probe(struct snd_soc_codec *codec) | |||
906 | if (!pdata) { | 962 | if (!pdata) { |
907 | dev_warn(codec->dev, "No platform data supplied\n"); | 963 | dev_warn(codec->dev, "No platform data supplied\n"); |
908 | } else { | 964 | } else { |
909 | if (pdata->dres > WM8960_DRES_MAX) { | ||
910 | dev_err(codec->dev, "Invalid DRES: %d\n", pdata->dres); | ||
911 | pdata->dres = 0; | ||
912 | } | ||
913 | |||
914 | if (pdata->capless) | 965 | if (pdata->capless) |
915 | wm8960->set_bias_level = wm8960_set_bias_level_capless; | 966 | wm8960->set_bias_level = wm8960_set_bias_level_capless; |
916 | } | 967 | } |
917 | 968 | ||
918 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8960->control_type); | 969 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
919 | if (ret < 0) { | 970 | if (ret < 0) { |
920 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 971 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
921 | return ret; | 972 | return ret; |
@@ -963,14 +1014,24 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8960 = { | |||
963 | .suspend = wm8960_suspend, | 1014 | .suspend = wm8960_suspend, |
964 | .resume = wm8960_resume, | 1015 | .resume = wm8960_resume, |
965 | .set_bias_level = wm8960_set_bias_level, | 1016 | .set_bias_level = wm8960_set_bias_level, |
966 | .reg_cache_size = ARRAY_SIZE(wm8960_reg), | 1017 | }; |
967 | .reg_word_size = sizeof(u16), | 1018 | |
968 | .reg_cache_default = wm8960_reg, | 1019 | static const struct regmap_config wm8960_regmap = { |
1020 | .reg_bits = 7, | ||
1021 | .val_bits = 9, | ||
1022 | .max_register = WM8960_PLL4, | ||
1023 | |||
1024 | .reg_defaults = wm8960_reg_defaults, | ||
1025 | .num_reg_defaults = ARRAY_SIZE(wm8960_reg_defaults), | ||
1026 | .cache_type = REGCACHE_RBTREE, | ||
1027 | |||
1028 | .volatile_reg = wm8960_volatile, | ||
969 | }; | 1029 | }; |
970 | 1030 | ||
971 | static __devinit int wm8960_i2c_probe(struct i2c_client *i2c, | 1031 | static __devinit int wm8960_i2c_probe(struct i2c_client *i2c, |
972 | const struct i2c_device_id *id) | 1032 | const struct i2c_device_id *id) |
973 | { | 1033 | { |
1034 | struct wm8960_data *pdata = dev_get_platdata(&i2c->dev); | ||
974 | struct wm8960_priv *wm8960; | 1035 | struct wm8960_priv *wm8960; |
975 | int ret; | 1036 | int ret; |
976 | 1037 | ||
@@ -979,8 +1040,21 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c, | |||
979 | if (wm8960 == NULL) | 1040 | if (wm8960 == NULL) |
980 | return -ENOMEM; | 1041 | return -ENOMEM; |
981 | 1042 | ||
1043 | wm8960->regmap = regmap_init_i2c(i2c, &wm8960_regmap); | ||
1044 | if (IS_ERR(wm8960->regmap)) | ||
1045 | return PTR_ERR(wm8960->regmap); | ||
1046 | |||
1047 | if (pdata && pdata->shared_lrclk) { | ||
1048 | ret = regmap_update_bits(wm8960->regmap, WM8960_ADDCTL2, | ||
1049 | 0x4, 0x4); | ||
1050 | if (ret != 0) { | ||
1051 | dev_err(&i2c->dev, "Failed to enable LRCM: %d\n", | ||
1052 | ret); | ||
1053 | return ret; | ||
1054 | } | ||
1055 | } | ||
1056 | |||
982 | i2c_set_clientdata(i2c, wm8960); | 1057 | i2c_set_clientdata(i2c, wm8960); |
983 | wm8960->control_type = SND_SOC_I2C; | ||
984 | 1058 | ||
985 | ret = snd_soc_register_codec(&i2c->dev, | 1059 | ret = snd_soc_register_codec(&i2c->dev, |
986 | &soc_codec_dev_wm8960, &wm8960_dai, 1); | 1060 | &soc_codec_dev_wm8960, &wm8960_dai, 1); |
@@ -1010,23 +1084,7 @@ static struct i2c_driver wm8960_i2c_driver = { | |||
1010 | .id_table = wm8960_i2c_id, | 1084 | .id_table = wm8960_i2c_id, |
1011 | }; | 1085 | }; |
1012 | 1086 | ||
1013 | static int __init wm8960_modinit(void) | 1087 | module_i2c_driver(wm8960_i2c_driver); |
1014 | { | ||
1015 | int ret = 0; | ||
1016 | ret = i2c_add_driver(&wm8960_i2c_driver); | ||
1017 | if (ret != 0) { | ||
1018 | printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n", | ||
1019 | ret); | ||
1020 | } | ||
1021 | return ret; | ||
1022 | } | ||
1023 | module_init(wm8960_modinit); | ||
1024 | |||
1025 | static void __exit wm8960_exit(void) | ||
1026 | { | ||
1027 | i2c_del_driver(&wm8960_i2c_driver); | ||
1028 | } | ||
1029 | module_exit(wm8960_exit); | ||
1030 | 1088 | ||
1031 | MODULE_DESCRIPTION("ASoC WM8960 driver"); | 1089 | MODULE_DESCRIPTION("ASoC WM8960 driver"); |
1032 | MODULE_AUTHOR("Liam Girdwood"); | 1090 | MODULE_AUTHOR("Liam Girdwood"); |
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index 01edbcc754d2..f387670d0d75 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/pm.h> | 20 | #include <linux/pm.h> |
21 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
22 | #include <linux/regmap.h> | ||
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
23 | #include <sound/core.h> | 24 | #include <sound/core.h> |
24 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
@@ -31,283 +32,159 @@ | |||
31 | 32 | ||
32 | #define WM8961_MAX_REGISTER 0xFC | 33 | #define WM8961_MAX_REGISTER 0xFC |
33 | 34 | ||
34 | static u16 wm8961_reg_defaults[] = { | 35 | static const struct reg_default wm8961_reg_defaults[] = { |
35 | 0x009F, /* R0 - Left Input volume */ | 36 | { 0, 0x009F }, /* R0 - Left Input volume */ |
36 | 0x009F, /* R1 - Right Input volume */ | 37 | { 1, 0x009F }, /* R1 - Right Input volume */ |
37 | 0x0000, /* R2 - LOUT1 volume */ | 38 | { 2, 0x0000 }, /* R2 - LOUT1 volume */ |
38 | 0x0000, /* R3 - ROUT1 volume */ | 39 | { 3, 0x0000 }, /* R3 - ROUT1 volume */ |
39 | 0x0020, /* R4 - Clocking1 */ | 40 | { 4, 0x0020 }, /* R4 - Clocking1 */ |
40 | 0x0008, /* R5 - ADC & DAC Control 1 */ | 41 | { 5, 0x0008 }, /* R5 - ADC & DAC Control 1 */ |
41 | 0x0000, /* R6 - ADC & DAC Control 2 */ | 42 | { 6, 0x0000 }, /* R6 - ADC & DAC Control 2 */ |
42 | 0x000A, /* R7 - Audio Interface 0 */ | 43 | { 7, 0x000A }, /* R7 - Audio Interface 0 */ |
43 | 0x01F4, /* R8 - Clocking2 */ | 44 | { 8, 0x01F4 }, /* R8 - Clocking2 */ |
44 | 0x0000, /* R9 - Audio Interface 1 */ | 45 | { 9, 0x0000 }, /* R9 - Audio Interface 1 */ |
45 | 0x00FF, /* R10 - Left DAC volume */ | 46 | { 10, 0x00FF }, /* R10 - Left DAC volume */ |
46 | 0x00FF, /* R11 - Right DAC volume */ | 47 | { 11, 0x00FF }, /* R11 - Right DAC volume */ |
47 | 0x0000, /* R12 */ | 48 | |
48 | 0x0000, /* R13 */ | 49 | { 14, 0x0040 }, /* R14 - Audio Interface 2 */ |
49 | 0x0040, /* R14 - Audio Interface 2 */ | 50 | |
50 | 0x0000, /* R15 - Software Reset */ | 51 | { 17, 0x007B }, /* R17 - ALC1 */ |
51 | 0x0000, /* R16 */ | 52 | { 18, 0x0000 }, /* R18 - ALC2 */ |
52 | 0x007B, /* R17 - ALC1 */ | 53 | { 19, 0x0032 }, /* R19 - ALC3 */ |
53 | 0x0000, /* R18 - ALC2 */ | 54 | { 20, 0x0000 }, /* R20 - Noise Gate */ |
54 | 0x0032, /* R19 - ALC3 */ | 55 | { 21, 0x00C0 }, /* R21 - Left ADC volume */ |
55 | 0x0000, /* R20 - Noise Gate */ | 56 | { 22, 0x00C0 }, /* R22 - Right ADC volume */ |
56 | 0x00C0, /* R21 - Left ADC volume */ | 57 | { 23, 0x0120 }, /* R23 - Additional control(1) */ |
57 | 0x00C0, /* R22 - Right ADC volume */ | 58 | { 24, 0x0000 }, /* R24 - Additional control(2) */ |
58 | 0x0120, /* R23 - Additional control(1) */ | 59 | { 25, 0x0000 }, /* R25 - Pwr Mgmt (1) */ |
59 | 0x0000, /* R24 - Additional control(2) */ | 60 | { 26, 0x0000 }, /* R26 - Pwr Mgmt (2) */ |
60 | 0x0000, /* R25 - Pwr Mgmt (1) */ | 61 | { 27, 0x0000 }, /* R27 - Additional Control (3) */ |
61 | 0x0000, /* R26 - Pwr Mgmt (2) */ | 62 | { 28, 0x0000 }, /* R28 - Anti-pop */ |
62 | 0x0000, /* R27 - Additional Control (3) */ | 63 | |
63 | 0x0000, /* R28 - Anti-pop */ | 64 | { 30, 0x005F }, /* R30 - Clocking 3 */ |
64 | 0x0000, /* R29 */ | 65 | |
65 | 0x005F, /* R30 - Clocking 3 */ | 66 | { 32, 0x0000 }, /* R32 - ADCL signal path */ |
66 | 0x0000, /* R31 */ | 67 | { 33, 0x0000 }, /* R33 - ADCR signal path */ |
67 | 0x0000, /* R32 - ADCL signal path */ | 68 | |
68 | 0x0000, /* R33 - ADCR signal path */ | 69 | { 40, 0x0000 }, /* R40 - LOUT2 volume */ |
69 | 0x0000, /* R34 */ | 70 | { 41, 0x0000 }, /* R41 - ROUT2 volume */ |
70 | 0x0000, /* R35 */ | 71 | |
71 | 0x0000, /* R36 */ | 72 | { 47, 0x0000 }, /* R47 - Pwr Mgmt (3) */ |
72 | 0x0000, /* R37 */ | 73 | { 48, 0x0023 }, /* R48 - Additional Control (4) */ |
73 | 0x0000, /* R38 */ | 74 | { 49, 0x0000 }, /* R49 - Class D Control 1 */ |
74 | 0x0000, /* R39 */ | 75 | |
75 | 0x0000, /* R40 - LOUT2 volume */ | 76 | { 51, 0x0003 }, /* R51 - Class D Control 2 */ |
76 | 0x0000, /* R41 - ROUT2 volume */ | 77 | |
77 | 0x0000, /* R42 */ | 78 | { 56, 0x0106 }, /* R56 - Clocking 4 */ |
78 | 0x0000, /* R43 */ | 79 | { 57, 0x0000 }, /* R57 - DSP Sidetone 0 */ |
79 | 0x0000, /* R44 */ | 80 | { 58, 0x0000 }, /* R58 - DSP Sidetone 1 */ |
80 | 0x0000, /* R45 */ | 81 | |
81 | 0x0000, /* R46 */ | 82 | { 60, 0x0000 }, /* R60 - DC Servo 0 */ |
82 | 0x0000, /* R47 - Pwr Mgmt (3) */ | 83 | { 61, 0x0000 }, /* R61 - DC Servo 1 */ |
83 | 0x0023, /* R48 - Additional Control (4) */ | 84 | |
84 | 0x0000, /* R49 - Class D Control 1 */ | 85 | { 63, 0x015E }, /* R63 - DC Servo 3 */ |
85 | 0x0000, /* R50 */ | 86 | |
86 | 0x0003, /* R51 - Class D Control 2 */ | 87 | { 65, 0x0010 }, /* R65 - DC Servo 5 */ |
87 | 0x0000, /* R52 */ | 88 | |
88 | 0x0000, /* R53 */ | 89 | { 68, 0x0003 }, /* R68 - Analogue PGA Bias */ |
89 | 0x0000, /* R54 */ | 90 | { 69, 0x0000 }, /* R69 - Analogue HP 0 */ |
90 | 0x0000, /* R55 */ | 91 | |
91 | 0x0106, /* R56 - Clocking 4 */ | 92 | { 71, 0x01FB }, /* R71 - Analogue HP 2 */ |
92 | 0x0000, /* R57 - DSP Sidetone 0 */ | 93 | { 72, 0x0000 }, /* R72 - Charge Pump 1 */ |
93 | 0x0000, /* R58 - DSP Sidetone 1 */ | 94 | |
94 | 0x0000, /* R59 */ | 95 | { 82, 0x0000 }, /* R82 - Charge Pump B */ |
95 | 0x0000, /* R60 - DC Servo 0 */ | 96 | |
96 | 0x0000, /* R61 - DC Servo 1 */ | 97 | { 87, 0x0000 }, /* R87 - Write Sequencer 1 */ |
97 | 0x0000, /* R62 */ | 98 | { 88, 0x0000 }, /* R88 - Write Sequencer 2 */ |
98 | 0x015E, /* R63 - DC Servo 3 */ | 99 | { 89, 0x0000 }, /* R89 - Write Sequencer 3 */ |
99 | 0x0010, /* R64 */ | 100 | { 90, 0x0000 }, /* R90 - Write Sequencer 4 */ |
100 | 0x0010, /* R65 - DC Servo 5 */ | 101 | { 91, 0x0000 }, /* R91 - Write Sequencer 5 */ |
101 | 0x0000, /* R66 */ | 102 | { 92, 0x0000 }, /* R92 - Write Sequencer 6 */ |
102 | 0x0001, /* R67 */ | 103 | { 93, 0x0000 }, /* R93 - Write Sequencer 7 */ |
103 | 0x0003, /* R68 - Analogue PGA Bias */ | 104 | |
104 | 0x0000, /* R69 - Analogue HP 0 */ | 105 | { 252, 0x0001 }, /* R252 - General test 1 */ |
105 | 0x0060, /* R70 */ | ||
106 | 0x01FB, /* R71 - Analogue HP 2 */ | ||
107 | 0x0000, /* R72 - Charge Pump 1 */ | ||
108 | 0x0065, /* R73 */ | ||
109 | 0x005F, /* R74 */ | ||
110 | 0x0059, /* R75 */ | ||
111 | 0x006B, /* R76 */ | ||
112 | 0x0038, /* R77 */ | ||
113 | 0x000C, /* R78 */ | ||
114 | 0x000A, /* R79 */ | ||
115 | 0x006B, /* R80 */ | ||
116 | 0x0000, /* R81 */ | ||
117 | 0x0000, /* R82 - Charge Pump B */ | ||
118 | 0x0087, /* R83 */ | ||
119 | 0x0000, /* R84 */ | ||
120 | 0x005C, /* R85 */ | ||
121 | 0x0000, /* R86 */ | ||
122 | 0x0000, /* R87 - Write Sequencer 1 */ | ||
123 | 0x0000, /* R88 - Write Sequencer 2 */ | ||
124 | 0x0000, /* R89 - Write Sequencer 3 */ | ||
125 | 0x0000, /* R90 - Write Sequencer 4 */ | ||
126 | 0x0000, /* R91 - Write Sequencer 5 */ | ||
127 | 0x0000, /* R92 - Write Sequencer 6 */ | ||
128 | 0x0000, /* R93 - Write Sequencer 7 */ | ||
129 | 0x0000, /* R94 */ | ||
130 | 0x0000, /* R95 */ | ||
131 | 0x0000, /* R96 */ | ||
132 | 0x0000, /* R97 */ | ||
133 | 0x0000, /* R98 */ | ||
134 | 0x0000, /* R99 */ | ||
135 | 0x0000, /* R100 */ | ||
136 | 0x0000, /* R101 */ | ||
137 | 0x0000, /* R102 */ | ||
138 | 0x0000, /* R103 */ | ||
139 | 0x0000, /* R104 */ | ||
140 | 0x0000, /* R105 */ | ||
141 | 0x0000, /* R106 */ | ||
142 | 0x0000, /* R107 */ | ||
143 | 0x0000, /* R108 */ | ||
144 | 0x0000, /* R109 */ | ||
145 | 0x0000, /* R110 */ | ||
146 | 0x0000, /* R111 */ | ||
147 | 0x0000, /* R112 */ | ||
148 | 0x0000, /* R113 */ | ||
149 | 0x0000, /* R114 */ | ||
150 | 0x0000, /* R115 */ | ||
151 | 0x0000, /* R116 */ | ||
152 | 0x0000, /* R117 */ | ||
153 | 0x0000, /* R118 */ | ||
154 | 0x0000, /* R119 */ | ||
155 | 0x0000, /* R120 */ | ||
156 | 0x0000, /* R121 */ | ||
157 | 0x0000, /* R122 */ | ||
158 | 0x0000, /* R123 */ | ||
159 | 0x0000, /* R124 */ | ||
160 | 0x0000, /* R125 */ | ||
161 | 0x0000, /* R126 */ | ||
162 | 0x0000, /* R127 */ | ||
163 | 0x0000, /* R128 */ | ||
164 | 0x0000, /* R129 */ | ||
165 | 0x0000, /* R130 */ | ||
166 | 0x0000, /* R131 */ | ||
167 | 0x0000, /* R132 */ | ||
168 | 0x0000, /* R133 */ | ||
169 | 0x0000, /* R134 */ | ||
170 | 0x0000, /* R135 */ | ||
171 | 0x0000, /* R136 */ | ||
172 | 0x0000, /* R137 */ | ||
173 | 0x0000, /* R138 */ | ||
174 | 0x0000, /* R139 */ | ||
175 | 0x0000, /* R140 */ | ||
176 | 0x0000, /* R141 */ | ||
177 | 0x0000, /* R142 */ | ||
178 | 0x0000, /* R143 */ | ||
179 | 0x0000, /* R144 */ | ||
180 | 0x0000, /* R145 */ | ||
181 | 0x0000, /* R146 */ | ||
182 | 0x0000, /* R147 */ | ||
183 | 0x0000, /* R148 */ | ||
184 | 0x0000, /* R149 */ | ||
185 | 0x0000, /* R150 */ | ||
186 | 0x0000, /* R151 */ | ||
187 | 0x0000, /* R152 */ | ||
188 | 0x0000, /* R153 */ | ||
189 | 0x0000, /* R154 */ | ||
190 | 0x0000, /* R155 */ | ||
191 | 0x0000, /* R156 */ | ||
192 | 0x0000, /* R157 */ | ||
193 | 0x0000, /* R158 */ | ||
194 | 0x0000, /* R159 */ | ||
195 | 0x0000, /* R160 */ | ||
196 | 0x0000, /* R161 */ | ||
197 | 0x0000, /* R162 */ | ||
198 | 0x0000, /* R163 */ | ||
199 | 0x0000, /* R164 */ | ||
200 | 0x0000, /* R165 */ | ||
201 | 0x0000, /* R166 */ | ||
202 | 0x0000, /* R167 */ | ||
203 | 0x0000, /* R168 */ | ||
204 | 0x0000, /* R169 */ | ||
205 | 0x0000, /* R170 */ | ||
206 | 0x0000, /* R171 */ | ||
207 | 0x0000, /* R172 */ | ||
208 | 0x0000, /* R173 */ | ||
209 | 0x0000, /* R174 */ | ||
210 | 0x0000, /* R175 */ | ||
211 | 0x0000, /* R176 */ | ||
212 | 0x0000, /* R177 */ | ||
213 | 0x0000, /* R178 */ | ||
214 | 0x0000, /* R179 */ | ||
215 | 0x0000, /* R180 */ | ||
216 | 0x0000, /* R181 */ | ||
217 | 0x0000, /* R182 */ | ||
218 | 0x0000, /* R183 */ | ||
219 | 0x0000, /* R184 */ | ||
220 | 0x0000, /* R185 */ | ||
221 | 0x0000, /* R186 */ | ||
222 | 0x0000, /* R187 */ | ||
223 | 0x0000, /* R188 */ | ||
224 | 0x0000, /* R189 */ | ||
225 | 0x0000, /* R190 */ | ||
226 | 0x0000, /* R191 */ | ||
227 | 0x0000, /* R192 */ | ||
228 | 0x0000, /* R193 */ | ||
229 | 0x0000, /* R194 */ | ||
230 | 0x0000, /* R195 */ | ||
231 | 0x0030, /* R196 */ | ||
232 | 0x0006, /* R197 */ | ||
233 | 0x0000, /* R198 */ | ||
234 | 0x0060, /* R199 */ | ||
235 | 0x0000, /* R200 */ | ||
236 | 0x003F, /* R201 */ | ||
237 | 0x0000, /* R202 */ | ||
238 | 0x0000, /* R203 */ | ||
239 | 0x0000, /* R204 */ | ||
240 | 0x0001, /* R205 */ | ||
241 | 0x0000, /* R206 */ | ||
242 | 0x0181, /* R207 */ | ||
243 | 0x0005, /* R208 */ | ||
244 | 0x0008, /* R209 */ | ||
245 | 0x0008, /* R210 */ | ||
246 | 0x0000, /* R211 */ | ||
247 | 0x013B, /* R212 */ | ||
248 | 0x0000, /* R213 */ | ||
249 | 0x0000, /* R214 */ | ||
250 | 0x0000, /* R215 */ | ||
251 | 0x0000, /* R216 */ | ||
252 | 0x0070, /* R217 */ | ||
253 | 0x0000, /* R218 */ | ||
254 | 0x0000, /* R219 */ | ||
255 | 0x0000, /* R220 */ | ||
256 | 0x0000, /* R221 */ | ||
257 | 0x0000, /* R222 */ | ||
258 | 0x0003, /* R223 */ | ||
259 | 0x0000, /* R224 */ | ||
260 | 0x0000, /* R225 */ | ||
261 | 0x0001, /* R226 */ | ||
262 | 0x0008, /* R227 */ | ||
263 | 0x0000, /* R228 */ | ||
264 | 0x0000, /* R229 */ | ||
265 | 0x0000, /* R230 */ | ||
266 | 0x0000, /* R231 */ | ||
267 | 0x0004, /* R232 */ | ||
268 | 0x0000, /* R233 */ | ||
269 | 0x0000, /* R234 */ | ||
270 | 0x0000, /* R235 */ | ||
271 | 0x0000, /* R236 */ | ||
272 | 0x0000, /* R237 */ | ||
273 | 0x0080, /* R238 */ | ||
274 | 0x0000, /* R239 */ | ||
275 | 0x0000, /* R240 */ | ||
276 | 0x0000, /* R241 */ | ||
277 | 0x0000, /* R242 */ | ||
278 | 0x0000, /* R243 */ | ||
279 | 0x0000, /* R244 */ | ||
280 | 0x0052, /* R245 */ | ||
281 | 0x0110, /* R246 */ | ||
282 | 0x0040, /* R247 */ | ||
283 | 0x0000, /* R248 */ | ||
284 | 0x0030, /* R249 */ | ||
285 | 0x0000, /* R250 */ | ||
286 | 0x0000, /* R251 */ | ||
287 | 0x0001, /* R252 - General test 1 */ | ||
288 | }; | 106 | }; |
289 | 107 | ||
290 | struct wm8961_priv { | 108 | struct wm8961_priv { |
291 | enum snd_soc_control_type control_type; | 109 | struct regmap *regmap; |
292 | int sysclk; | 110 | int sysclk; |
293 | }; | 111 | }; |
294 | 112 | ||
295 | static int wm8961_volatile_register(struct snd_soc_codec *codec, unsigned int reg) | 113 | static bool wm8961_volatile(struct device *dev, unsigned int reg) |
296 | { | 114 | { |
297 | switch (reg) { | 115 | switch (reg) { |
298 | case WM8961_SOFTWARE_RESET: | 116 | case WM8961_SOFTWARE_RESET: |
299 | case WM8961_WRITE_SEQUENCER_7: | 117 | case WM8961_WRITE_SEQUENCER_7: |
300 | case WM8961_DC_SERVO_1: | 118 | case WM8961_DC_SERVO_1: |
301 | return 1; | 119 | return true; |
302 | 120 | ||
303 | default: | 121 | default: |
304 | return 0; | 122 | return false; |
305 | } | 123 | } |
306 | } | 124 | } |
307 | 125 | ||
308 | static int wm8961_reset(struct snd_soc_codec *codec) | 126 | static bool wm8961_readable(struct device *dev, unsigned int reg) |
309 | { | 127 | { |
310 | return snd_soc_write(codec, WM8961_SOFTWARE_RESET, 0); | 128 | switch (reg) { |
129 | case WM8961_LEFT_INPUT_VOLUME: | ||
130 | case WM8961_RIGHT_INPUT_VOLUME: | ||
131 | case WM8961_LOUT1_VOLUME: | ||
132 | case WM8961_ROUT1_VOLUME: | ||
133 | case WM8961_CLOCKING1: | ||
134 | case WM8961_ADC_DAC_CONTROL_1: | ||
135 | case WM8961_ADC_DAC_CONTROL_2: | ||
136 | case WM8961_AUDIO_INTERFACE_0: | ||
137 | case WM8961_CLOCKING2: | ||
138 | case WM8961_AUDIO_INTERFACE_1: | ||
139 | case WM8961_LEFT_DAC_VOLUME: | ||
140 | case WM8961_RIGHT_DAC_VOLUME: | ||
141 | case WM8961_AUDIO_INTERFACE_2: | ||
142 | case WM8961_SOFTWARE_RESET: | ||
143 | case WM8961_ALC1: | ||
144 | case WM8961_ALC2: | ||
145 | case WM8961_ALC3: | ||
146 | case WM8961_NOISE_GATE: | ||
147 | case WM8961_LEFT_ADC_VOLUME: | ||
148 | case WM8961_RIGHT_ADC_VOLUME: | ||
149 | case WM8961_ADDITIONAL_CONTROL_1: | ||
150 | case WM8961_ADDITIONAL_CONTROL_2: | ||
151 | case WM8961_PWR_MGMT_1: | ||
152 | case WM8961_PWR_MGMT_2: | ||
153 | case WM8961_ADDITIONAL_CONTROL_3: | ||
154 | case WM8961_ANTI_POP: | ||
155 | case WM8961_CLOCKING_3: | ||
156 | case WM8961_ADCL_SIGNAL_PATH: | ||
157 | case WM8961_ADCR_SIGNAL_PATH: | ||
158 | case WM8961_LOUT2_VOLUME: | ||
159 | case WM8961_ROUT2_VOLUME: | ||
160 | case WM8961_PWR_MGMT_3: | ||
161 | case WM8961_ADDITIONAL_CONTROL_4: | ||
162 | case WM8961_CLASS_D_CONTROL_1: | ||
163 | case WM8961_CLASS_D_CONTROL_2: | ||
164 | case WM8961_CLOCKING_4: | ||
165 | case WM8961_DSP_SIDETONE_0: | ||
166 | case WM8961_DSP_SIDETONE_1: | ||
167 | case WM8961_DC_SERVO_0: | ||
168 | case WM8961_DC_SERVO_1: | ||
169 | case WM8961_DC_SERVO_3: | ||
170 | case WM8961_DC_SERVO_5: | ||
171 | case WM8961_ANALOGUE_PGA_BIAS: | ||
172 | case WM8961_ANALOGUE_HP_0: | ||
173 | case WM8961_ANALOGUE_HP_2: | ||
174 | case WM8961_CHARGE_PUMP_1: | ||
175 | case WM8961_CHARGE_PUMP_B: | ||
176 | case WM8961_WRITE_SEQUENCER_1: | ||
177 | case WM8961_WRITE_SEQUENCER_2: | ||
178 | case WM8961_WRITE_SEQUENCER_3: | ||
179 | case WM8961_WRITE_SEQUENCER_4: | ||
180 | case WM8961_WRITE_SEQUENCER_5: | ||
181 | case WM8961_WRITE_SEQUENCER_6: | ||
182 | case WM8961_WRITE_SEQUENCER_7: | ||
183 | case WM8961_GENERAL_TEST_1: | ||
184 | return true; | ||
185 | default: | ||
186 | return false; | ||
187 | } | ||
311 | } | 188 | } |
312 | 189 | ||
313 | /* | 190 | /* |
@@ -962,33 +839,12 @@ static int wm8961_probe(struct snd_soc_codec *codec) | |||
962 | int ret = 0; | 839 | int ret = 0; |
963 | u16 reg; | 840 | u16 reg; |
964 | 841 | ||
965 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); | 842 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); |
966 | if (ret != 0) { | 843 | if (ret != 0) { |
967 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 844 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
968 | return ret; | 845 | return ret; |
969 | } | 846 | } |
970 | 847 | ||
971 | reg = snd_soc_read(codec, WM8961_SOFTWARE_RESET); | ||
972 | if (reg != 0x1801) { | ||
973 | dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg); | ||
974 | return -EINVAL; | ||
975 | } | ||
976 | |||
977 | /* This isn't volatile - readback doesn't correspond to write */ | ||
978 | codec->cache_bypass = 1; | ||
979 | reg = snd_soc_read(codec, WM8961_RIGHT_INPUT_VOLUME); | ||
980 | codec->cache_bypass = 0; | ||
981 | dev_info(codec->dev, "WM8961 family %d revision %c\n", | ||
982 | (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT, | ||
983 | ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT) | ||
984 | + 'A'); | ||
985 | |||
986 | ret = wm8961_reset(codec); | ||
987 | if (ret < 0) { | ||
988 | dev_err(codec->dev, "Failed to issue reset\n"); | ||
989 | return ret; | ||
990 | } | ||
991 | |||
992 | /* Enable class W */ | 848 | /* Enable class W */ |
993 | reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B); | 849 | reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B); |
994 | reg |= WM8961_CP_DYN_PWR_MASK; | 850 | reg |= WM8961_CP_DYN_PWR_MASK; |
@@ -1066,16 +922,26 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8961 = { | |||
1066 | .suspend = wm8961_suspend, | 922 | .suspend = wm8961_suspend, |
1067 | .resume = wm8961_resume, | 923 | .resume = wm8961_resume, |
1068 | .set_bias_level = wm8961_set_bias_level, | 924 | .set_bias_level = wm8961_set_bias_level, |
1069 | .reg_cache_size = ARRAY_SIZE(wm8961_reg_defaults), | 925 | }; |
1070 | .reg_word_size = sizeof(u16), | 926 | |
1071 | .reg_cache_default = wm8961_reg_defaults, | 927 | static const struct regmap_config wm8961_regmap = { |
1072 | .volatile_register = wm8961_volatile_register, | 928 | .reg_bits = 8, |
929 | .val_bits = 16, | ||
930 | .max_register = WM8961_MAX_REGISTER, | ||
931 | |||
932 | .reg_defaults = wm8961_reg_defaults, | ||
933 | .num_reg_defaults = ARRAY_SIZE(wm8961_reg_defaults), | ||
934 | .cache_type = REGCACHE_RBTREE, | ||
935 | |||
936 | .volatile_reg = wm8961_volatile, | ||
937 | .readable_reg = wm8961_readable, | ||
1073 | }; | 938 | }; |
1074 | 939 | ||
1075 | static __devinit int wm8961_i2c_probe(struct i2c_client *i2c, | 940 | static __devinit int wm8961_i2c_probe(struct i2c_client *i2c, |
1076 | const struct i2c_device_id *id) | 941 | const struct i2c_device_id *id) |
1077 | { | 942 | { |
1078 | struct wm8961_priv *wm8961; | 943 | struct wm8961_priv *wm8961; |
944 | unsigned int val; | ||
1079 | int ret; | 945 | int ret; |
1080 | 946 | ||
1081 | wm8961 = devm_kzalloc(&i2c->dev, sizeof(struct wm8961_priv), | 947 | wm8961 = devm_kzalloc(&i2c->dev, sizeof(struct wm8961_priv), |
@@ -1083,6 +949,42 @@ static __devinit int wm8961_i2c_probe(struct i2c_client *i2c, | |||
1083 | if (wm8961 == NULL) | 949 | if (wm8961 == NULL) |
1084 | return -ENOMEM; | 950 | return -ENOMEM; |
1085 | 951 | ||
952 | wm8961->regmap = devm_regmap_init_i2c(i2c, &wm8961_regmap); | ||
953 | if (IS_ERR(wm8961->regmap)) | ||
954 | return PTR_ERR(wm8961->regmap); | ||
955 | |||
956 | ret = regmap_read(wm8961->regmap, WM8961_SOFTWARE_RESET, &val); | ||
957 | if (ret != 0) { | ||
958 | dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); | ||
959 | return ret; | ||
960 | } | ||
961 | |||
962 | if (val != 0x1801) { | ||
963 | dev_err(&i2c->dev, "Device is not a WM8961: ID=0x%x\n", val); | ||
964 | return -EINVAL; | ||
965 | } | ||
966 | |||
967 | /* This isn't volatile - readback doesn't correspond to write */ | ||
968 | regcache_cache_bypass(wm8961->regmap, true); | ||
969 | ret = regmap_read(wm8961->regmap, WM8961_RIGHT_INPUT_VOLUME, &val); | ||
970 | regcache_cache_bypass(wm8961->regmap, false); | ||
971 | |||
972 | if (ret != 0) { | ||
973 | dev_err(&i2c->dev, "Failed to read chip revision: %d\n", ret); | ||
974 | return ret; | ||
975 | } | ||
976 | |||
977 | dev_info(&i2c->dev, "WM8961 family %d revision %c\n", | ||
978 | (val & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT, | ||
979 | ((val & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT) | ||
980 | + 'A'); | ||
981 | |||
982 | ret = regmap_write(wm8961->regmap, WM8961_SOFTWARE_RESET, 0x1801); | ||
983 | if (ret != 0) { | ||
984 | dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret); | ||
985 | return ret; | ||
986 | } | ||
987 | |||
1086 | i2c_set_clientdata(i2c, wm8961); | 988 | i2c_set_clientdata(i2c, wm8961); |
1087 | 989 | ||
1088 | ret = snd_soc_register_codec(&i2c->dev, | 990 | ret = snd_soc_register_codec(&i2c->dev, |
@@ -1114,23 +1016,7 @@ static struct i2c_driver wm8961_i2c_driver = { | |||
1114 | .id_table = wm8961_i2c_id, | 1016 | .id_table = wm8961_i2c_id, |
1115 | }; | 1017 | }; |
1116 | 1018 | ||
1117 | static int __init wm8961_modinit(void) | 1019 | module_i2c_driver(wm8961_i2c_driver); |
1118 | { | ||
1119 | int ret = 0; | ||
1120 | ret = i2c_add_driver(&wm8961_i2c_driver); | ||
1121 | if (ret != 0) { | ||
1122 | printk(KERN_ERR "Failed to register wm8961 I2C driver: %d\n", | ||
1123 | ret); | ||
1124 | } | ||
1125 | return ret; | ||
1126 | } | ||
1127 | module_init(wm8961_modinit); | ||
1128 | |||
1129 | static void __exit wm8961_exit(void) | ||
1130 | { | ||
1131 | i2c_del_driver(&wm8961_i2c_driver); | ||
1132 | } | ||
1133 | module_exit(wm8961_exit); | ||
1134 | 1020 | ||
1135 | MODULE_DESCRIPTION("ASoC WM8961 driver"); | 1021 | MODULE_DESCRIPTION("ASoC WM8961 driver"); |
1136 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 1022 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index eef783f6b6d6..5ce647758443 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c | |||
@@ -721,23 +721,7 @@ static struct i2c_driver wm8971_i2c_driver = { | |||
721 | .id_table = wm8971_i2c_id, | 721 | .id_table = wm8971_i2c_id, |
722 | }; | 722 | }; |
723 | 723 | ||
724 | static int __init wm8971_modinit(void) | 724 | module_i2c_driver(wm8971_i2c_driver); |
725 | { | ||
726 | int ret = 0; | ||
727 | ret = i2c_add_driver(&wm8971_i2c_driver); | ||
728 | if (ret != 0) { | ||
729 | printk(KERN_ERR "Failed to register WM8971 I2C driver: %d\n", | ||
730 | ret); | ||
731 | } | ||
732 | return ret; | ||
733 | } | ||
734 | module_init(wm8971_modinit); | ||
735 | |||
736 | static void __exit wm8971_exit(void) | ||
737 | { | ||
738 | i2c_del_driver(&wm8971_i2c_driver); | ||
739 | } | ||
740 | module_exit(wm8971_exit); | ||
741 | 725 | ||
742 | MODULE_DESCRIPTION("ASoC WM8971 driver"); | 726 | MODULE_DESCRIPTION("ASoC WM8971 driver"); |
743 | MODULE_AUTHOR("Lab126"); | 727 | MODULE_AUTHOR("Lab126"); |
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index d93c03f820c9..9a39511af52a 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c | |||
@@ -659,23 +659,7 @@ static struct i2c_driver wm8974_i2c_driver = { | |||
659 | .id_table = wm8974_i2c_id, | 659 | .id_table = wm8974_i2c_id, |
660 | }; | 660 | }; |
661 | 661 | ||
662 | static int __init wm8974_modinit(void) | 662 | module_i2c_driver(wm8974_i2c_driver); |
663 | { | ||
664 | int ret = 0; | ||
665 | ret = i2c_add_driver(&wm8974_i2c_driver); | ||
666 | if (ret != 0) { | ||
667 | printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n", | ||
668 | ret); | ||
669 | } | ||
670 | return ret; | ||
671 | } | ||
672 | module_init(wm8974_modinit); | ||
673 | |||
674 | static void __exit wm8974_exit(void) | ||
675 | { | ||
676 | i2c_del_driver(&wm8974_i2c_driver); | ||
677 | } | ||
678 | module_exit(wm8974_exit); | ||
679 | 663 | ||
680 | MODULE_DESCRIPTION("ASoC WM8974 driver"); | 664 | MODULE_DESCRIPTION("ASoC WM8974 driver"); |
681 | MODULE_AUTHOR("Liam Girdwood"); | 665 | MODULE_AUTHOR("Liam Girdwood"); |
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index a5be3adecf75..5421fd9fbcb5 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c | |||
@@ -1105,23 +1105,7 @@ static struct i2c_driver wm8978_i2c_driver = { | |||
1105 | .id_table = wm8978_i2c_id, | 1105 | .id_table = wm8978_i2c_id, |
1106 | }; | 1106 | }; |
1107 | 1107 | ||
1108 | static int __init wm8978_modinit(void) | 1108 | module_i2c_driver(wm8978_i2c_driver); |
1109 | { | ||
1110 | int ret = 0; | ||
1111 | ret = i2c_add_driver(&wm8978_i2c_driver); | ||
1112 | if (ret != 0) { | ||
1113 | printk(KERN_ERR "Failed to register WM8978 I2C driver: %d\n", | ||
1114 | ret); | ||
1115 | } | ||
1116 | return ret; | ||
1117 | } | ||
1118 | module_init(wm8978_modinit); | ||
1119 | |||
1120 | static void __exit wm8978_exit(void) | ||
1121 | { | ||
1122 | i2c_del_driver(&wm8978_i2c_driver); | ||
1123 | } | ||
1124 | module_exit(wm8978_exit); | ||
1125 | 1109 | ||
1126 | MODULE_DESCRIPTION("ASoC WM8978 codec driver"); | 1110 | MODULE_DESCRIPTION("ASoC WM8978 codec driver"); |
1127 | MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); | 1111 | MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); |
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index 367388fdc486..d8879f262d27 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <linux/regmap.h> | ||
19 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
21 | #include <sound/core.h> | 22 | #include <sound/core.h> |
@@ -27,61 +28,60 @@ | |||
27 | 28 | ||
28 | #include "wm8983.h" | 29 | #include "wm8983.h" |
29 | 30 | ||
30 | static const u16 wm8983_reg_defs[WM8983_MAX_REGISTER + 1] = { | 31 | static const struct reg_default wm8983_defaults[] = { |
31 | [0x00] = 0x0000, /* R0 - Software Reset */ | 32 | { 0x01, 0x0000 }, /* R1 - Power management 1 */ |
32 | [0x01] = 0x0000, /* R1 - Power management 1 */ | 33 | { 0x02, 0x0000 }, /* R2 - Power management 2 */ |
33 | [0x02] = 0x0000, /* R2 - Power management 2 */ | 34 | { 0x03, 0x0000 }, /* R3 - Power management 3 */ |
34 | [0x03] = 0x0000, /* R3 - Power management 3 */ | 35 | { 0x04, 0x0050 }, /* R4 - Audio Interface */ |
35 | [0x04] = 0x0050, /* R4 - Audio Interface */ | 36 | { 0x05, 0x0000 }, /* R5 - Companding control */ |
36 | [0x05] = 0x0000, /* R5 - Companding control */ | 37 | { 0x06, 0x0140 }, /* R6 - Clock Gen control */ |
37 | [0x06] = 0x0140, /* R6 - Clock Gen control */ | 38 | { 0x07, 0x0000 }, /* R7 - Additional control */ |
38 | [0x07] = 0x0000, /* R7 - Additional control */ | 39 | { 0x08, 0x0000 }, /* R8 - GPIO Control */ |
39 | [0x08] = 0x0000, /* R8 - GPIO Control */ | 40 | { 0x09, 0x0000 }, /* R9 - Jack Detect Control 1 */ |
40 | [0x09] = 0x0000, /* R9 - Jack Detect Control 1 */ | 41 | { 0x0A, 0x0000 }, /* R10 - DAC Control */ |
41 | [0x0A] = 0x0000, /* R10 - DAC Control */ | 42 | { 0x0B, 0x00FF }, /* R11 - Left DAC digital Vol */ |
42 | [0x0B] = 0x00FF, /* R11 - Left DAC digital Vol */ | 43 | { 0x0C, 0x00FF }, /* R12 - Right DAC digital vol */ |
43 | [0x0C] = 0x00FF, /* R12 - Right DAC digital vol */ | 44 | { 0x0D, 0x0000 }, /* R13 - Jack Detect Control 2 */ |
44 | [0x0D] = 0x0000, /* R13 - Jack Detect Control 2 */ | 45 | { 0x0E, 0x0100 }, /* R14 - ADC Control */ |
45 | [0x0E] = 0x0100, /* R14 - ADC Control */ | 46 | { 0x0F, 0x00FF }, /* R15 - Left ADC Digital Vol */ |
46 | [0x0F] = 0x00FF, /* R15 - Left ADC Digital Vol */ | 47 | { 0x10, 0x00FF }, /* R16 - Right ADC Digital Vol */ |
47 | [0x10] = 0x00FF, /* R16 - Right ADC Digital Vol */ | 48 | { 0x12, 0x012C }, /* R18 - EQ1 - low shelf */ |
48 | [0x12] = 0x012C, /* R18 - EQ1 - low shelf */ | 49 | { 0x13, 0x002C }, /* R19 - EQ2 - peak 1 */ |
49 | [0x13] = 0x002C, /* R19 - EQ2 - peak 1 */ | 50 | { 0x14, 0x002C }, /* R20 - EQ3 - peak 2 */ |
50 | [0x14] = 0x002C, /* R20 - EQ3 - peak 2 */ | 51 | { 0x15, 0x002C }, /* R21 - EQ4 - peak 3 */ |
51 | [0x15] = 0x002C, /* R21 - EQ4 - peak 3 */ | 52 | { 0x16, 0x002C }, /* R22 - EQ5 - high shelf */ |
52 | [0x16] = 0x002C, /* R22 - EQ5 - high shelf */ | 53 | { 0x18, 0x0032 }, /* R24 - DAC Limiter 1 */ |
53 | [0x18] = 0x0032, /* R24 - DAC Limiter 1 */ | 54 | { 0x19, 0x0000 }, /* R25 - DAC Limiter 2 */ |
54 | [0x19] = 0x0000, /* R25 - DAC Limiter 2 */ | 55 | { 0x1B, 0x0000 }, /* R27 - Notch Filter 1 */ |
55 | [0x1B] = 0x0000, /* R27 - Notch Filter 1 */ | 56 | { 0x1C, 0x0000 }, /* R28 - Notch Filter 2 */ |
56 | [0x1C] = 0x0000, /* R28 - Notch Filter 2 */ | 57 | { 0x1D, 0x0000 }, /* R29 - Notch Filter 3 */ |
57 | [0x1D] = 0x0000, /* R29 - Notch Filter 3 */ | 58 | { 0x1E, 0x0000 }, /* R30 - Notch Filter 4 */ |
58 | [0x1E] = 0x0000, /* R30 - Notch Filter 4 */ | 59 | { 0x20, 0x0038 }, /* R32 - ALC control 1 */ |
59 | [0x20] = 0x0038, /* R32 - ALC control 1 */ | 60 | { 0x21, 0x000B }, /* R33 - ALC control 2 */ |
60 | [0x21] = 0x000B, /* R33 - ALC control 2 */ | 61 | { 0x22, 0x0032 }, /* R34 - ALC control 3 */ |
61 | [0x22] = 0x0032, /* R34 - ALC control 3 */ | 62 | { 0x23, 0x0000 }, /* R35 - Noise Gate */ |
62 | [0x23] = 0x0000, /* R35 - Noise Gate */ | 63 | { 0x24, 0x0008 }, /* R36 - PLL N */ |
63 | [0x24] = 0x0008, /* R36 - PLL N */ | 64 | { 0x25, 0x000C }, /* R37 - PLL K 1 */ |
64 | [0x25] = 0x000C, /* R37 - PLL K 1 */ | 65 | { 0x26, 0x0093 }, /* R38 - PLL K 2 */ |
65 | [0x26] = 0x0093, /* R38 - PLL K 2 */ | 66 | { 0x27, 0x00E9 }, /* R39 - PLL K 3 */ |
66 | [0x27] = 0x00E9, /* R39 - PLL K 3 */ | 67 | { 0x29, 0x0000 }, /* R41 - 3D control */ |
67 | [0x29] = 0x0000, /* R41 - 3D control */ | 68 | { 0x2A, 0x0000 }, /* R42 - OUT4 to ADC */ |
68 | [0x2A] = 0x0000, /* R42 - OUT4 to ADC */ | 69 | { 0x2B, 0x0000 }, /* R43 - Beep control */ |
69 | [0x2B] = 0x0000, /* R43 - Beep control */ | 70 | { 0x2C, 0x0033 }, /* R44 - Input ctrl */ |
70 | [0x2C] = 0x0033, /* R44 - Input ctrl */ | 71 | { 0x2D, 0x0010 }, /* R45 - Left INP PGA gain ctrl */ |
71 | [0x2D] = 0x0010, /* R45 - Left INP PGA gain ctrl */ | 72 | { 0x2E, 0x0010 }, /* R46 - Right INP PGA gain ctrl */ |
72 | [0x2E] = 0x0010, /* R46 - Right INP PGA gain ctrl */ | 73 | { 0x2F, 0x0100 }, /* R47 - Left ADC BOOST ctrl */ |
73 | [0x2F] = 0x0100, /* R47 - Left ADC BOOST ctrl */ | 74 | { 0x30, 0x0100 }, /* R48 - Right ADC BOOST ctrl */ |
74 | [0x30] = 0x0100, /* R48 - Right ADC BOOST ctrl */ | 75 | { 0x31, 0x0002 }, /* R49 - Output ctrl */ |
75 | [0x31] = 0x0002, /* R49 - Output ctrl */ | 76 | { 0x32, 0x0001 }, /* R50 - Left mixer ctrl */ |
76 | [0x32] = 0x0001, /* R50 - Left mixer ctrl */ | 77 | { 0x33, 0x0001 }, /* R51 - Right mixer ctrl */ |
77 | [0x33] = 0x0001, /* R51 - Right mixer ctrl */ | 78 | { 0x34, 0x0039 }, /* R52 - LOUT1 (HP) volume ctrl */ |
78 | [0x34] = 0x0039, /* R52 - LOUT1 (HP) volume ctrl */ | 79 | { 0x35, 0x0039 }, /* R53 - ROUT1 (HP) volume ctrl */ |
79 | [0x35] = 0x0039, /* R53 - ROUT1 (HP) volume ctrl */ | 80 | { 0x36, 0x0039 }, /* R54 - LOUT2 (SPK) volume ctrl */ |
80 | [0x36] = 0x0039, /* R54 - LOUT2 (SPK) volume ctrl */ | 81 | { 0x37, 0x0039 }, /* R55 - ROUT2 (SPK) volume ctrl */ |
81 | [0x37] = 0x0039, /* R55 - ROUT2 (SPK) volume ctrl */ | 82 | { 0x38, 0x0001 }, /* R56 - OUT3 mixer ctrl */ |
82 | [0x38] = 0x0001, /* R56 - OUT3 mixer ctrl */ | 83 | { 0x39, 0x0001 }, /* R57 - OUT4 (MONO) mix ctrl */ |
83 | [0x39] = 0x0001, /* R57 - OUT4 (MONO) mix ctrl */ | 84 | { 0x3D, 0x0000 }, /* R61 - BIAS CTRL */ |
84 | [0x3D] = 0x0000 /* R61 - BIAS CTRL */ | ||
85 | }; | 85 | }; |
86 | 86 | ||
87 | static const struct wm8983_reg_access { | 87 | static const struct wm8983_reg_access { |
@@ -159,7 +159,7 @@ static const int vol_update_regs[] = { | |||
159 | }; | 159 | }; |
160 | 160 | ||
161 | struct wm8983_priv { | 161 | struct wm8983_priv { |
162 | enum snd_soc_control_type control_type; | 162 | struct regmap *regmap; |
163 | u32 sysclk; | 163 | u32 sysclk; |
164 | u32 bclk; | 164 | u32 bclk; |
165 | }; | 165 | }; |
@@ -610,7 +610,7 @@ static int eqmode_put(struct snd_kcontrol *kcontrol, | |||
610 | return 0; | 610 | return 0; |
611 | } | 611 | } |
612 | 612 | ||
613 | static int wm8983_readable(struct snd_soc_codec *codec, unsigned int reg) | 613 | static bool wm8983_readable(struct device *dev, unsigned int reg) |
614 | { | 614 | { |
615 | if (reg > WM8983_MAX_REGISTER) | 615 | if (reg > WM8983_MAX_REGISTER) |
616 | return 0; | 616 | return 0; |
@@ -905,6 +905,7 @@ static int wm8983_set_sysclk(struct snd_soc_dai *dai, | |||
905 | static int wm8983_set_bias_level(struct snd_soc_codec *codec, | 905 | static int wm8983_set_bias_level(struct snd_soc_codec *codec, |
906 | enum snd_soc_bias_level level) | 906 | enum snd_soc_bias_level level) |
907 | { | 907 | { |
908 | struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec); | ||
908 | int ret; | 909 | int ret; |
909 | 910 | ||
910 | switch (level) { | 911 | switch (level) { |
@@ -917,7 +918,7 @@ static int wm8983_set_bias_level(struct snd_soc_codec *codec, | |||
917 | break; | 918 | break; |
918 | case SND_SOC_BIAS_STANDBY: | 919 | case SND_SOC_BIAS_STANDBY: |
919 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 920 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
920 | ret = snd_soc_cache_sync(codec); | 921 | ret = regcache_sync(wm8983->regmap); |
921 | if (ret < 0) { | 922 | if (ret < 0) { |
922 | dev_err(codec->dev, "Failed to sync cache: %d\n", ret); | 923 | dev_err(codec->dev, "Failed to sync cache: %d\n", ret); |
923 | return ret; | 924 | return ret; |
@@ -994,10 +995,9 @@ static int wm8983_remove(struct snd_soc_codec *codec) | |||
994 | static int wm8983_probe(struct snd_soc_codec *codec) | 995 | static int wm8983_probe(struct snd_soc_codec *codec) |
995 | { | 996 | { |
996 | int ret; | 997 | int ret; |
997 | struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec); | ||
998 | int i; | 998 | int i; |
999 | 999 | ||
1000 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8983->control_type); | 1000 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
1001 | if (ret < 0) { | 1001 | if (ret < 0) { |
1002 | dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); | 1002 | dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); |
1003 | return ret; | 1003 | return ret; |
@@ -1067,16 +1067,23 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8983 = { | |||
1067 | .suspend = wm8983_suspend, | 1067 | .suspend = wm8983_suspend, |
1068 | .resume = wm8983_resume, | 1068 | .resume = wm8983_resume, |
1069 | .set_bias_level = wm8983_set_bias_level, | 1069 | .set_bias_level = wm8983_set_bias_level, |
1070 | .reg_cache_size = ARRAY_SIZE(wm8983_reg_defs), | ||
1071 | .reg_word_size = sizeof(u16), | ||
1072 | .reg_cache_default = wm8983_reg_defs, | ||
1073 | .controls = wm8983_snd_controls, | 1070 | .controls = wm8983_snd_controls, |
1074 | .num_controls = ARRAY_SIZE(wm8983_snd_controls), | 1071 | .num_controls = ARRAY_SIZE(wm8983_snd_controls), |
1075 | .dapm_widgets = wm8983_dapm_widgets, | 1072 | .dapm_widgets = wm8983_dapm_widgets, |
1076 | .num_dapm_widgets = ARRAY_SIZE(wm8983_dapm_widgets), | 1073 | .num_dapm_widgets = ARRAY_SIZE(wm8983_dapm_widgets), |
1077 | .dapm_routes = wm8983_audio_map, | 1074 | .dapm_routes = wm8983_audio_map, |
1078 | .num_dapm_routes = ARRAY_SIZE(wm8983_audio_map), | 1075 | .num_dapm_routes = ARRAY_SIZE(wm8983_audio_map), |
1079 | .readable_register = wm8983_readable | 1076 | }; |
1077 | |||
1078 | static const struct regmap_config wm8983_regmap = { | ||
1079 | .reg_bits = 7, | ||
1080 | .val_bits = 9, | ||
1081 | |||
1082 | .reg_defaults = wm8983_defaults, | ||
1083 | .num_reg_defaults = ARRAY_SIZE(wm8983_defaults), | ||
1084 | .cache_type = REGCACHE_RBTREE, | ||
1085 | |||
1086 | .readable_reg = wm8983_readable, | ||
1080 | }; | 1087 | }; |
1081 | 1088 | ||
1082 | #if defined(CONFIG_SPI_MASTER) | 1089 | #if defined(CONFIG_SPI_MASTER) |
@@ -1085,24 +1092,27 @@ static int __devinit wm8983_spi_probe(struct spi_device *spi) | |||
1085 | struct wm8983_priv *wm8983; | 1092 | struct wm8983_priv *wm8983; |
1086 | int ret; | 1093 | int ret; |
1087 | 1094 | ||
1088 | wm8983 = kzalloc(sizeof *wm8983, GFP_KERNEL); | 1095 | wm8983 = devm_kzalloc(&spi->dev, sizeof *wm8983, GFP_KERNEL); |
1089 | if (!wm8983) | 1096 | if (!wm8983) |
1090 | return -ENOMEM; | 1097 | return -ENOMEM; |
1091 | 1098 | ||
1092 | wm8983->control_type = SND_SOC_SPI; | 1099 | wm8983->regmap = devm_regmap_init_spi(spi, &wm8983_regmap); |
1100 | if (IS_ERR(wm8983->regmap)) { | ||
1101 | ret = PTR_ERR(wm8983->regmap); | ||
1102 | dev_err(&spi->dev, "Failed to init regmap: %d\n", ret); | ||
1103 | return ret; | ||
1104 | } | ||
1105 | |||
1093 | spi_set_drvdata(spi, wm8983); | 1106 | spi_set_drvdata(spi, wm8983); |
1094 | 1107 | ||
1095 | ret = snd_soc_register_codec(&spi->dev, | 1108 | ret = snd_soc_register_codec(&spi->dev, |
1096 | &soc_codec_dev_wm8983, &wm8983_dai, 1); | 1109 | &soc_codec_dev_wm8983, &wm8983_dai, 1); |
1097 | if (ret < 0) | ||
1098 | kfree(wm8983); | ||
1099 | return ret; | 1110 | return ret; |
1100 | } | 1111 | } |
1101 | 1112 | ||
1102 | static int __devexit wm8983_spi_remove(struct spi_device *spi) | 1113 | static int __devexit wm8983_spi_remove(struct spi_device *spi) |
1103 | { | 1114 | { |
1104 | snd_soc_unregister_codec(&spi->dev); | 1115 | snd_soc_unregister_codec(&spi->dev); |
1105 | kfree(spi_get_drvdata(spi)); | ||
1106 | return 0; | 1116 | return 0; |
1107 | } | 1117 | } |
1108 | 1118 | ||
@@ -1123,24 +1133,28 @@ static __devinit int wm8983_i2c_probe(struct i2c_client *i2c, | |||
1123 | struct wm8983_priv *wm8983; | 1133 | struct wm8983_priv *wm8983; |
1124 | int ret; | 1134 | int ret; |
1125 | 1135 | ||
1126 | wm8983 = kzalloc(sizeof *wm8983, GFP_KERNEL); | 1136 | wm8983 = devm_kzalloc(&i2c->dev, sizeof *wm8983, GFP_KERNEL); |
1127 | if (!wm8983) | 1137 | if (!wm8983) |
1128 | return -ENOMEM; | 1138 | return -ENOMEM; |
1129 | 1139 | ||
1130 | wm8983->control_type = SND_SOC_I2C; | 1140 | wm8983->regmap = devm_regmap_init_i2c(i2c, &wm8983_regmap); |
1141 | if (IS_ERR(wm8983->regmap)) { | ||
1142 | ret = PTR_ERR(wm8983->regmap); | ||
1143 | dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); | ||
1144 | return ret; | ||
1145 | } | ||
1146 | |||
1131 | i2c_set_clientdata(i2c, wm8983); | 1147 | i2c_set_clientdata(i2c, wm8983); |
1132 | 1148 | ||
1133 | ret = snd_soc_register_codec(&i2c->dev, | 1149 | ret = snd_soc_register_codec(&i2c->dev, |
1134 | &soc_codec_dev_wm8983, &wm8983_dai, 1); | 1150 | &soc_codec_dev_wm8983, &wm8983_dai, 1); |
1135 | if (ret < 0) | 1151 | |
1136 | kfree(wm8983); | ||
1137 | return ret; | 1152 | return ret; |
1138 | } | 1153 | } |
1139 | 1154 | ||
1140 | static __devexit int wm8983_i2c_remove(struct i2c_client *client) | 1155 | static __devexit int wm8983_i2c_remove(struct i2c_client *client) |
1141 | { | 1156 | { |
1142 | snd_soc_unregister_codec(&client->dev); | 1157 | snd_soc_unregister_codec(&client->dev); |
1143 | kfree(i2c_get_clientdata(client)); | ||
1144 | return 0; | 1158 | return 0; |
1145 | } | 1159 | } |
1146 | 1160 | ||
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index db63c97ddf51..c28c83e5395d 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c | |||
@@ -1388,7 +1388,8 @@ static __devinit int wm8990_i2c_probe(struct i2c_client *i2c, | |||
1388 | struct wm8990_priv *wm8990; | 1388 | struct wm8990_priv *wm8990; |
1389 | int ret; | 1389 | int ret; |
1390 | 1390 | ||
1391 | wm8990 = kzalloc(sizeof(struct wm8990_priv), GFP_KERNEL); | 1391 | wm8990 = devm_kzalloc(&i2c->dev, sizeof(struct wm8990_priv), |
1392 | GFP_KERNEL); | ||
1392 | if (wm8990 == NULL) | 1393 | if (wm8990 == NULL) |
1393 | return -ENOMEM; | 1394 | return -ENOMEM; |
1394 | 1395 | ||
@@ -1396,15 +1397,14 @@ static __devinit int wm8990_i2c_probe(struct i2c_client *i2c, | |||
1396 | 1397 | ||
1397 | ret = snd_soc_register_codec(&i2c->dev, | 1398 | ret = snd_soc_register_codec(&i2c->dev, |
1398 | &soc_codec_dev_wm8990, &wm8990_dai, 1); | 1399 | &soc_codec_dev_wm8990, &wm8990_dai, 1); |
1399 | if (ret < 0) | 1400 | |
1400 | kfree(wm8990); | ||
1401 | return ret; | 1401 | return ret; |
1402 | } | 1402 | } |
1403 | 1403 | ||
1404 | static __devexit int wm8990_i2c_remove(struct i2c_client *client) | 1404 | static __devexit int wm8990_i2c_remove(struct i2c_client *client) |
1405 | { | 1405 | { |
1406 | snd_soc_unregister_codec(&client->dev); | 1406 | snd_soc_unregister_codec(&client->dev); |
1407 | kfree(i2c_get_clientdata(client)); | 1407 | |
1408 | return 0; | 1408 | return 0; |
1409 | } | 1409 | } |
1410 | 1410 | ||
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index 9ac31ba9b82e..fe439f027e10 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c | |||
@@ -1363,7 +1363,7 @@ static __devinit int wm8991_i2c_probe(struct i2c_client *i2c, | |||
1363 | struct wm8991_priv *wm8991; | 1363 | struct wm8991_priv *wm8991; |
1364 | int ret; | 1364 | int ret; |
1365 | 1365 | ||
1366 | wm8991 = kzalloc(sizeof *wm8991, GFP_KERNEL); | 1366 | wm8991 = devm_kzalloc(&i2c->dev, sizeof(*wm8991), GFP_KERNEL); |
1367 | if (!wm8991) | 1367 | if (!wm8991) |
1368 | return -ENOMEM; | 1368 | return -ENOMEM; |
1369 | 1369 | ||
@@ -1372,15 +1372,14 @@ static __devinit int wm8991_i2c_probe(struct i2c_client *i2c, | |||
1372 | 1372 | ||
1373 | ret = snd_soc_register_codec(&i2c->dev, | 1373 | ret = snd_soc_register_codec(&i2c->dev, |
1374 | &soc_codec_dev_wm8991, &wm8991_dai, 1); | 1374 | &soc_codec_dev_wm8991, &wm8991_dai, 1); |
1375 | if (ret < 0) | 1375 | |
1376 | kfree(wm8991); | ||
1377 | return ret; | 1376 | return ret; |
1378 | } | 1377 | } |
1379 | 1378 | ||
1380 | static __devexit int wm8991_i2c_remove(struct i2c_client *client) | 1379 | static __devexit int wm8991_i2c_remove(struct i2c_client *client) |
1381 | { | 1380 | { |
1382 | snd_soc_unregister_codec(&client->dev); | 1381 | snd_soc_unregister_codec(&client->dev); |
1383 | kfree(i2c_get_clientdata(client)); | 1382 | |
1384 | return 0; | 1383 | return 0; |
1385 | } | 1384 | } |
1386 | 1385 | ||
@@ -1400,23 +1399,7 @@ static struct i2c_driver wm8991_i2c_driver = { | |||
1400 | .id_table = wm8991_i2c_id, | 1399 | .id_table = wm8991_i2c_id, |
1401 | }; | 1400 | }; |
1402 | 1401 | ||
1403 | static int __init wm8991_modinit(void) | 1402 | module_i2c_driver(wm8991_i2c_driver); |
1404 | { | ||
1405 | int ret; | ||
1406 | ret = i2c_add_driver(&wm8991_i2c_driver); | ||
1407 | if (ret != 0) { | ||
1408 | printk(KERN_ERR "Failed to register WM8991 I2C driver: %d\n", | ||
1409 | ret); | ||
1410 | } | ||
1411 | return 0; | ||
1412 | } | ||
1413 | module_init(wm8991_modinit); | ||
1414 | |||
1415 | static void __exit wm8991_exit(void) | ||
1416 | { | ||
1417 | i2c_del_driver(&wm8991_i2c_driver); | ||
1418 | } | ||
1419 | module_exit(wm8991_exit); | ||
1420 | 1403 | ||
1421 | MODULE_DESCRIPTION("ASoC WM8991 driver"); | 1404 | MODULE_DESCRIPTION("ASoC WM8991 driver"); |
1422 | MODULE_AUTHOR("Graeme Gregory"); | 1405 | MODULE_AUTHOR("Graeme Gregory"); |
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 9fd80d688979..94737a30716b 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
@@ -1520,6 +1520,8 @@ static int wm8993_probe(struct snd_soc_codec *codec) | |||
1520 | wm8993->pdata.lineout2fb, | 1520 | wm8993->pdata.lineout2fb, |
1521 | wm8993->pdata.jd_scthr, | 1521 | wm8993->pdata.jd_scthr, |
1522 | wm8993->pdata.jd_thr, | 1522 | wm8993->pdata.jd_thr, |
1523 | wm8993->pdata.micbias1_delay, | ||
1524 | wm8993->pdata.micbias2_delay, | ||
1523 | wm8993->pdata.micbias1_lvl, | 1525 | wm8993->pdata.micbias1_lvl, |
1524 | wm8993->pdata.micbias2_lvl); | 1526 | wm8993->pdata.micbias2_lvl); |
1525 | 1527 | ||
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6c9eeca85b95..2b2dadc54dac 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -671,6 +671,18 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0, | |||
671 | eq_tlv), | 671 | eq_tlv), |
672 | }; | 672 | }; |
673 | 673 | ||
674 | static const struct snd_kcontrol_new wm8994_drc_controls[] = { | ||
675 | SND_SOC_BYTES_MASK("AIF1.1 DRC", WM8994_AIF1_DRC1_1, 5, | ||
676 | WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA | | ||
677 | WM8994_AIF1ADC1R_DRC_ENA), | ||
678 | SND_SOC_BYTES_MASK("AIF1.2 DRC", WM8994_AIF1_DRC2_1, 5, | ||
679 | WM8994_AIF1DAC2_DRC_ENA | WM8994_AIF1ADC2L_DRC_ENA | | ||
680 | WM8994_AIF1ADC2R_DRC_ENA), | ||
681 | SND_SOC_BYTES_MASK("AIF2 DRC", WM8994_AIF2_DRC_1, 5, | ||
682 | WM8994_AIF2DAC_DRC_ENA | WM8994_AIF2ADCL_DRC_ENA | | ||
683 | WM8994_AIF2ADCR_DRC_ENA), | ||
684 | }; | ||
685 | |||
674 | static const char *wm8958_ng_text[] = { | 686 | static const char *wm8958_ng_text[] = { |
675 | "30ms", "125ms", "250ms", "500ms", | 687 | "30ms", "125ms", "250ms", "500ms", |
676 | }; | 688 | }; |
@@ -789,11 +801,27 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w, | |||
789 | struct snd_kcontrol *kcontrol, int event) | 801 | struct snd_kcontrol *kcontrol, int event) |
790 | { | 802 | { |
791 | struct snd_soc_codec *codec = w->codec; | 803 | struct snd_soc_codec *codec = w->codec; |
804 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | ||
792 | 805 | ||
793 | switch (event) { | 806 | switch (event) { |
794 | case SND_SOC_DAPM_PRE_PMU: | 807 | case SND_SOC_DAPM_PRE_PMU: |
795 | return configure_clock(codec); | 808 | return configure_clock(codec); |
796 | 809 | ||
810 | case SND_SOC_DAPM_POST_PMU: | ||
811 | /* | ||
812 | * JACKDET won't run until we start the clock and it | ||
813 | * only reports deltas, make sure we notify the state | ||
814 | * up the stack on startup. Use a *very* generous | ||
815 | * timeout for paranoia, there's no urgency and we | ||
816 | * don't want false reports. | ||
817 | */ | ||
818 | if (wm8994->jackdet && !wm8994->clk_has_run) { | ||
819 | schedule_delayed_work(&wm8994->jackdet_bootstrap, | ||
820 | msecs_to_jiffies(1000)); | ||
821 | wm8994->clk_has_run = true; | ||
822 | } | ||
823 | break; | ||
824 | |||
797 | case SND_SOC_DAPM_POST_PMD: | 825 | case SND_SOC_DAPM_POST_PMD: |
798 | configure_clock(codec); | 826 | configure_clock(codec); |
799 | break; | 827 | break; |
@@ -1632,7 +1660,8 @@ SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, vmid_event, | |||
1632 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | 1660 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
1633 | 1661 | ||
1634 | SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, | 1662 | SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, |
1635 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 1663 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | |
1664 | SND_SOC_DAPM_PRE_PMD), | ||
1636 | 1665 | ||
1637 | SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, 3, 0, NULL, 0), | 1666 | SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, 3, 0, NULL, 0), |
1638 | SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM, 2, 0, NULL, 0), | 1667 | SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM, 2, 0, NULL, 0), |
@@ -2102,6 +2131,10 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
2102 | case WM8994_FLL_SRC_LRCLK: | 2131 | case WM8994_FLL_SRC_LRCLK: |
2103 | case WM8994_FLL_SRC_BCLK: | 2132 | case WM8994_FLL_SRC_BCLK: |
2104 | break; | 2133 | break; |
2134 | case WM8994_FLL_SRC_INTERNAL: | ||
2135 | freq_in = 12000000; | ||
2136 | freq_out = 12000000; | ||
2137 | break; | ||
2105 | default: | 2138 | default: |
2106 | return -EINVAL; | 2139 | return -EINVAL; |
2107 | } | 2140 | } |
@@ -2161,12 +2194,14 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
2161 | 2194 | ||
2162 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset, | 2195 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset, |
2163 | WM8994_FLL1_N_MASK, | 2196 | WM8994_FLL1_N_MASK, |
2164 | fll.n << WM8994_FLL1_N_SHIFT); | 2197 | fll.n << WM8994_FLL1_N_SHIFT); |
2165 | 2198 | ||
2166 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset, | 2199 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset, |
2167 | WM8958_FLL1_BYP | | 2200 | WM8994_FLL1_FRC_NCO | WM8958_FLL1_BYP | |
2168 | WM8994_FLL1_REFCLK_DIV_MASK | | 2201 | WM8994_FLL1_REFCLK_DIV_MASK | |
2169 | WM8994_FLL1_REFCLK_SRC_MASK, | 2202 | WM8994_FLL1_REFCLK_SRC_MASK, |
2203 | ((src == WM8994_FLL_SRC_INTERNAL) | ||
2204 | << WM8994_FLL1_FRC_NCO_SHIFT) | | ||
2170 | (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) | | 2205 | (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) | |
2171 | (src - 1)); | 2206 | (src - 1)); |
2172 | 2207 | ||
@@ -2192,13 +2227,16 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
2192 | } | 2227 | } |
2193 | } | 2228 | } |
2194 | 2229 | ||
2230 | reg = WM8994_FLL1_ENA; | ||
2231 | |||
2195 | if (fll.k) | 2232 | if (fll.k) |
2196 | reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC; | 2233 | reg |= WM8994_FLL1_FRAC; |
2197 | else | 2234 | if (src == WM8994_FLL_SRC_INTERNAL) |
2198 | reg = WM8994_FLL1_ENA; | 2235 | reg |= WM8994_FLL1_OSC_ENA; |
2236 | |||
2199 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, | 2237 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, |
2200 | WM8994_FLL1_ENA | WM8994_FLL1_FRAC, | 2238 | WM8994_FLL1_ENA | WM8994_FLL1_OSC_ENA | |
2201 | reg); | 2239 | WM8994_FLL1_FRAC, reg); |
2202 | 2240 | ||
2203 | if (wm8994->fll_locked_irq) { | 2241 | if (wm8994->fll_locked_irq) { |
2204 | timeout = wait_for_completion_timeout(&wm8994->fll_locked[id], | 2242 | timeout = wait_for_completion_timeout(&wm8994->fll_locked[id], |
@@ -3027,7 +3065,7 @@ static int wm8994_codec_resume(struct snd_soc_codec *codec) | |||
3027 | 3065 | ||
3028 | static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) | 3066 | static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) |
3029 | { | 3067 | { |
3030 | struct snd_soc_codec *codec = wm8994->codec; | 3068 | struct snd_soc_codec *codec = wm8994->hubs.codec; |
3031 | struct wm8994_pdata *pdata = wm8994->pdata; | 3069 | struct wm8994_pdata *pdata = wm8994->pdata; |
3032 | struct snd_kcontrol_new controls[] = { | 3070 | struct snd_kcontrol_new controls[] = { |
3033 | SOC_ENUM_EXT("AIF1.1 EQ Mode", | 3071 | SOC_ENUM_EXT("AIF1.1 EQ Mode", |
@@ -3085,16 +3123,16 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) | |||
3085 | wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; | 3123 | wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; |
3086 | wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; | 3124 | wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; |
3087 | 3125 | ||
3088 | ret = snd_soc_add_codec_controls(wm8994->codec, controls, | 3126 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls, |
3089 | ARRAY_SIZE(controls)); | 3127 | ARRAY_SIZE(controls)); |
3090 | if (ret != 0) | 3128 | if (ret != 0) |
3091 | dev_err(wm8994->codec->dev, | 3129 | dev_err(wm8994->hubs.codec->dev, |
3092 | "Failed to add ReTune Mobile controls: %d\n", ret); | 3130 | "Failed to add ReTune Mobile controls: %d\n", ret); |
3093 | } | 3131 | } |
3094 | 3132 | ||
3095 | static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | 3133 | static void wm8994_handle_pdata(struct wm8994_priv *wm8994) |
3096 | { | 3134 | { |
3097 | struct snd_soc_codec *codec = wm8994->codec; | 3135 | struct snd_soc_codec *codec = wm8994->hubs.codec; |
3098 | struct wm8994_pdata *pdata = wm8994->pdata; | 3136 | struct wm8994_pdata *pdata = wm8994->pdata; |
3099 | int ret, i; | 3137 | int ret, i; |
3100 | 3138 | ||
@@ -3107,6 +3145,8 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | |||
3107 | pdata->lineout2fb, | 3145 | pdata->lineout2fb, |
3108 | pdata->jd_scthr, | 3146 | pdata->jd_scthr, |
3109 | pdata->jd_thr, | 3147 | pdata->jd_thr, |
3148 | pdata->micb1_delay, | ||
3149 | pdata->micb2_delay, | ||
3110 | pdata->micbias1_lvl, | 3150 | pdata->micbias1_lvl, |
3111 | pdata->micbias2_lvl); | 3151 | pdata->micbias2_lvl); |
3112 | 3152 | ||
@@ -3123,10 +3163,10 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | |||
3123 | }; | 3163 | }; |
3124 | 3164 | ||
3125 | /* We need an array of texts for the enum API */ | 3165 | /* We need an array of texts for the enum API */ |
3126 | wm8994->drc_texts = devm_kzalloc(wm8994->codec->dev, | 3166 | wm8994->drc_texts = devm_kzalloc(wm8994->hubs.codec->dev, |
3127 | sizeof(char *) * pdata->num_drc_cfgs, GFP_KERNEL); | 3167 | sizeof(char *) * pdata->num_drc_cfgs, GFP_KERNEL); |
3128 | if (!wm8994->drc_texts) { | 3168 | if (!wm8994->drc_texts) { |
3129 | dev_err(wm8994->codec->dev, | 3169 | dev_err(wm8994->hubs.codec->dev, |
3130 | "Failed to allocate %d DRC config texts\n", | 3170 | "Failed to allocate %d DRC config texts\n", |
3131 | pdata->num_drc_cfgs); | 3171 | pdata->num_drc_cfgs); |
3132 | return; | 3172 | return; |
@@ -3138,23 +3178,28 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | |||
3138 | wm8994->drc_enum.max = pdata->num_drc_cfgs; | 3178 | wm8994->drc_enum.max = pdata->num_drc_cfgs; |
3139 | wm8994->drc_enum.texts = wm8994->drc_texts; | 3179 | wm8994->drc_enum.texts = wm8994->drc_texts; |
3140 | 3180 | ||
3141 | ret = snd_soc_add_codec_controls(wm8994->codec, controls, | 3181 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls, |
3142 | ARRAY_SIZE(controls)); | 3182 | ARRAY_SIZE(controls)); |
3143 | if (ret != 0) | ||
3144 | dev_err(wm8994->codec->dev, | ||
3145 | "Failed to add DRC mode controls: %d\n", ret); | ||
3146 | |||
3147 | for (i = 0; i < WM8994_NUM_DRC; i++) | 3183 | for (i = 0; i < WM8994_NUM_DRC; i++) |
3148 | wm8994_set_drc(codec, i); | 3184 | wm8994_set_drc(codec, i); |
3185 | } else { | ||
3186 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, | ||
3187 | wm8994_drc_controls, | ||
3188 | ARRAY_SIZE(wm8994_drc_controls)); | ||
3149 | } | 3189 | } |
3150 | 3190 | ||
3191 | if (ret != 0) | ||
3192 | dev_err(wm8994->hubs.codec->dev, | ||
3193 | "Failed to add DRC mode controls: %d\n", ret); | ||
3194 | |||
3195 | |||
3151 | dev_dbg(codec->dev, "%d ReTune Mobile configurations\n", | 3196 | dev_dbg(codec->dev, "%d ReTune Mobile configurations\n", |
3152 | pdata->num_retune_mobile_cfgs); | 3197 | pdata->num_retune_mobile_cfgs); |
3153 | 3198 | ||
3154 | if (pdata->num_retune_mobile_cfgs) | 3199 | if (pdata->num_retune_mobile_cfgs) |
3155 | wm8994_handle_retune_mobile_pdata(wm8994); | 3200 | wm8994_handle_retune_mobile_pdata(wm8994); |
3156 | else | 3201 | else |
3157 | snd_soc_add_codec_controls(wm8994->codec, wm8994_eq_controls, | 3202 | snd_soc_add_codec_controls(wm8994->hubs.codec, wm8994_eq_controls, |
3158 | ARRAY_SIZE(wm8994_eq_controls)); | 3203 | ARRAY_SIZE(wm8994_eq_controls)); |
3159 | 3204 | ||
3160 | for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) { | 3205 | for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) { |
@@ -3236,6 +3281,12 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
3236 | 3281 | ||
3237 | snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg); | 3282 | snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg); |
3238 | 3283 | ||
3284 | /* enable MICDET and MICSHRT deboune */ | ||
3285 | snd_soc_update_bits(codec, WM8994_IRQ_DEBOUNCE, | ||
3286 | WM8994_MIC1_DET_DB_MASK | WM8994_MIC1_SHRT_DB_MASK | | ||
3287 | WM8994_MIC2_DET_DB_MASK | WM8994_MIC2_SHRT_DB_MASK, | ||
3288 | WM8994_MIC1_DET_DB | WM8994_MIC1_SHRT_DB); | ||
3289 | |||
3239 | snd_soc_dapm_sync(&codec->dapm); | 3290 | snd_soc_dapm_sync(&codec->dapm); |
3240 | 3291 | ||
3241 | return 0; | 3292 | return 0; |
@@ -3309,7 +3360,7 @@ static void wm8994_mic_work(struct work_struct *work) | |||
3309 | static irqreturn_t wm8994_mic_irq(int irq, void *data) | 3360 | static irqreturn_t wm8994_mic_irq(int irq, void *data) |
3310 | { | 3361 | { |
3311 | struct wm8994_priv *priv = data; | 3362 | struct wm8994_priv *priv = data; |
3312 | struct snd_soc_codec *codec = priv->codec; | 3363 | struct snd_soc_codec *codec = priv->hubs.codec; |
3313 | 3364 | ||
3314 | #ifndef CONFIG_SND_SOC_WM8994_MODULE | 3365 | #ifndef CONFIG_SND_SOC_WM8994_MODULE |
3315 | trace_snd_soc_jack_irq(dev_name(codec->dev)); | 3366 | trace_snd_soc_jack_irq(dev_name(codec->dev)); |
@@ -3345,7 +3396,7 @@ static void wm8958_default_micdet(u16 status, void *data) | |||
3345 | 3396 | ||
3346 | snd_soc_jack_report(wm8994->micdet[0].jack, 0, | 3397 | snd_soc_jack_report(wm8994->micdet[0].jack, 0, |
3347 | wm8994->btn_mask | | 3398 | wm8994->btn_mask | |
3348 | SND_JACK_HEADSET); | 3399 | SND_JACK_HEADSET); |
3349 | } | 3400 | } |
3350 | return; | 3401 | return; |
3351 | } | 3402 | } |
@@ -3422,7 +3473,7 @@ static void wm8958_default_micdet(u16 status, void *data) | |||
3422 | static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | 3473 | static irqreturn_t wm1811_jackdet_irq(int irq, void *data) |
3423 | { | 3474 | { |
3424 | struct wm8994_priv *wm8994 = data; | 3475 | struct wm8994_priv *wm8994 = data; |
3425 | struct snd_soc_codec *codec = wm8994->codec; | 3476 | struct snd_soc_codec *codec = wm8994->hubs.codec; |
3426 | int reg; | 3477 | int reg; |
3427 | bool present; | 3478 | bool present; |
3428 | 3479 | ||
@@ -3499,10 +3550,22 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3499 | SND_JACK_MECHANICAL | SND_JACK_HEADSET | | 3550 | SND_JACK_MECHANICAL | SND_JACK_HEADSET | |
3500 | wm8994->btn_mask); | 3551 | wm8994->btn_mask); |
3501 | 3552 | ||
3553 | /* Since we only report deltas force an update, ensures we | ||
3554 | * avoid bootstrapping issues with the core. */ | ||
3555 | snd_soc_jack_report(wm8994->micdet[0].jack, 0, 0); | ||
3556 | |||
3502 | pm_runtime_put(codec->dev); | 3557 | pm_runtime_put(codec->dev); |
3503 | return IRQ_HANDLED; | 3558 | return IRQ_HANDLED; |
3504 | } | 3559 | } |
3505 | 3560 | ||
3561 | static void wm1811_jackdet_bootstrap(struct work_struct *work) | ||
3562 | { | ||
3563 | struct wm8994_priv *wm8994 = container_of(work, | ||
3564 | struct wm8994_priv, | ||
3565 | jackdet_bootstrap.work); | ||
3566 | wm1811_jackdet_irq(0, wm8994); | ||
3567 | } | ||
3568 | |||
3506 | /** | 3569 | /** |
3507 | * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ | 3570 | * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ |
3508 | * | 3571 | * |
@@ -3573,6 +3636,10 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
3573 | * otherwise jump straight to microphone detection. | 3636 | * otherwise jump straight to microphone detection. |
3574 | */ | 3637 | */ |
3575 | if (wm8994->jackdet) { | 3638 | if (wm8994->jackdet) { |
3639 | /* Disable debounce for the initial detect */ | ||
3640 | snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, | ||
3641 | WM1811_JACKDET_DB, 0); | ||
3642 | |||
3576 | snd_soc_update_bits(codec, WM8958_MICBIAS2, | 3643 | snd_soc_update_bits(codec, WM8958_MICBIAS2, |
3577 | WM8958_MICB2_DISCH, | 3644 | WM8958_MICB2_DISCH, |
3578 | WM8958_MICB2_DISCH); | 3645 | WM8958_MICB2_DISCH); |
@@ -3600,7 +3667,7 @@ EXPORT_SYMBOL_GPL(wm8958_mic_detect); | |||
3600 | static irqreturn_t wm8958_mic_irq(int irq, void *data) | 3667 | static irqreturn_t wm8958_mic_irq(int irq, void *data) |
3601 | { | 3668 | { |
3602 | struct wm8994_priv *wm8994 = data; | 3669 | struct wm8994_priv *wm8994 = data; |
3603 | struct snd_soc_codec *codec = wm8994->codec; | 3670 | struct snd_soc_codec *codec = wm8994->hubs.codec; |
3604 | int reg, count; | 3671 | int reg, count; |
3605 | 3672 | ||
3606 | /* | 3673 | /* |
@@ -3690,15 +3757,15 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3690 | unsigned int reg; | 3757 | unsigned int reg; |
3691 | int ret, i; | 3758 | int ret, i; |
3692 | 3759 | ||
3693 | wm8994->codec = codec; | 3760 | wm8994->hubs.codec = codec; |
3694 | codec->control_data = control->regmap; | 3761 | codec->control_data = control->regmap; |
3695 | 3762 | ||
3696 | snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | 3763 | snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); |
3697 | 3764 | ||
3698 | wm8994->codec = codec; | ||
3699 | |||
3700 | mutex_init(&wm8994->accdet_lock); | 3765 | mutex_init(&wm8994->accdet_lock); |
3701 | INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); | 3766 | INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); |
3767 | INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, | ||
3768 | wm1811_jackdet_bootstrap); | ||
3702 | 3769 | ||
3703 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) | 3770 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) |
3704 | init_completion(&wm8994->fll_locked[i]); | 3771 | init_completion(&wm8994->fll_locked[i]); |
@@ -3756,14 +3823,17 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3756 | wm8994->hubs.no_cache_dac_hp_direct = true; | 3823 | wm8994->hubs.no_cache_dac_hp_direct = true; |
3757 | wm8994->fll_byp = true; | 3824 | wm8994->fll_byp = true; |
3758 | 3825 | ||
3759 | switch (wm8994->revision) { | 3826 | switch (control->cust_id) { |
3760 | case 0: | 3827 | case 0: |
3761 | case 1: | ||
3762 | case 2: | 3828 | case 2: |
3763 | case 3: | ||
3764 | wm8994->hubs.dcs_codes_l = -9; | 3829 | wm8994->hubs.dcs_codes_l = -9; |
3765 | wm8994->hubs.dcs_codes_r = -7; | 3830 | wm8994->hubs.dcs_codes_r = -7; |
3766 | break; | 3831 | break; |
3832 | case 1: | ||
3833 | case 3: | ||
3834 | wm8994->hubs.dcs_codes_l = -8; | ||
3835 | wm8994->hubs.dcs_codes_r = -7; | ||
3836 | break; | ||
3767 | default: | 3837 | default: |
3768 | break; | 3838 | break; |
3769 | } | 3839 | } |
@@ -3852,7 +3922,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3852 | 3922 | ||
3853 | switch (control->type) { | 3923 | switch (control->type) { |
3854 | case WM1811: | 3924 | case WM1811: |
3855 | if (wm8994->revision > 1) { | 3925 | if (control->cust_id > 1 || wm8994->revision > 1) { |
3856 | ret = wm8994_request_irq(wm8994->wm8994, | 3926 | ret = wm8994_request_irq(wm8994->wm8994, |
3857 | WM8994_IRQ_GPIO(6), | 3927 | WM8994_IRQ_GPIO(6), |
3858 | wm1811_jackdet_irq, "JACKDET", | 3928 | wm1811_jackdet_irq, "JACKDET", |
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index d77e06f0a675..f142ec198db3 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h | |||
@@ -28,10 +28,11 @@ | |||
28 | #define WM8994_FLL1 1 | 28 | #define WM8994_FLL1 1 |
29 | #define WM8994_FLL2 2 | 29 | #define WM8994_FLL2 2 |
30 | 30 | ||
31 | #define WM8994_FLL_SRC_MCLK1 1 | 31 | #define WM8994_FLL_SRC_MCLK1 1 |
32 | #define WM8994_FLL_SRC_MCLK2 2 | 32 | #define WM8994_FLL_SRC_MCLK2 2 |
33 | #define WM8994_FLL_SRC_LRCLK 3 | 33 | #define WM8994_FLL_SRC_LRCLK 3 |
34 | #define WM8994_FLL_SRC_BCLK 4 | 34 | #define WM8994_FLL_SRC_BCLK 4 |
35 | #define WM8994_FLL_SRC_INTERNAL 5 | ||
35 | 36 | ||
36 | enum wm8994_vmid_mode { | 37 | enum wm8994_vmid_mode { |
37 | WM8994_VMID_NORMAL, | 38 | WM8994_VMID_NORMAL, |
@@ -72,7 +73,6 @@ struct wm8994; | |||
72 | struct wm8994_priv { | 73 | struct wm8994_priv { |
73 | struct wm_hubs_data hubs; | 74 | struct wm_hubs_data hubs; |
74 | struct wm8994 *wm8994; | 75 | struct wm8994 *wm8994; |
75 | struct snd_soc_codec *codec; | ||
76 | int sysclk[2]; | 76 | int sysclk[2]; |
77 | int sysclk_rate[2]; | 77 | int sysclk_rate[2]; |
78 | int mclk[2]; | 78 | int mclk[2]; |
@@ -81,6 +81,7 @@ struct wm8994_priv { | |||
81 | struct completion fll_locked[2]; | 81 | struct completion fll_locked[2]; |
82 | bool fll_locked_irq; | 82 | bool fll_locked_irq; |
83 | bool fll_byp; | 83 | bool fll_byp; |
84 | bool clk_has_run; | ||
84 | 85 | ||
85 | int vmid_refcount; | 86 | int vmid_refcount; |
86 | int active_refcount; | 87 | int active_refcount; |
@@ -134,6 +135,7 @@ struct wm8994_priv { | |||
134 | int btn_mask; | 135 | int btn_mask; |
135 | bool jackdet; | 136 | bool jackdet; |
136 | int jackdet_mode; | 137 | int jackdet_mode; |
138 | struct delayed_work jackdet_bootstrap; | ||
137 | 139 | ||
138 | wm8958_micdet_cb jack_cb; | 140 | wm8958_micdet_cb jack_cb; |
139 | void *jack_cb_data; | 141 | void *jack_cb_data; |
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 00f183dfa454..6dcb02c3666f 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c | |||
@@ -931,7 +931,7 @@ SND_SOC_DAPM_INPUT("IN2RP"), | |||
931 | SND_SOC_DAPM_INPUT("DMIC1DAT"), | 931 | SND_SOC_DAPM_INPUT("DMIC1DAT"), |
932 | SND_SOC_DAPM_INPUT("DMIC2DAT"), | 932 | SND_SOC_DAPM_INPUT("DMIC2DAT"), |
933 | 933 | ||
934 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20), | 934 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0), |
935 | SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0), | 935 | SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0), |
936 | SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), | 936 | SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), |
937 | SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), | 937 | SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), |
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 2c2346fdd637..c7ddc56175d1 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c | |||
@@ -695,17 +695,7 @@ static struct i2c_driver wm9090_i2c_driver = { | |||
695 | .id_table = wm9090_id, | 695 | .id_table = wm9090_id, |
696 | }; | 696 | }; |
697 | 697 | ||
698 | static int __init wm9090_init(void) | 698 | module_i2c_driver(wm9090_i2c_driver); |
699 | { | ||
700 | return i2c_add_driver(&wm9090_i2c_driver); | ||
701 | } | ||
702 | module_init(wm9090_init); | ||
703 | |||
704 | static void __exit wm9090_exit(void) | ||
705 | { | ||
706 | i2c_del_driver(&wm9090_i2c_driver); | ||
707 | } | ||
708 | module_exit(wm9090_exit); | ||
709 | 699 | ||
710 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 700 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
711 | MODULE_DESCRIPTION("WM9090 ASoC driver"); | 701 | MODULE_DESCRIPTION("WM9090 ASoC driver"); |
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index c6d2076a796b..4dd73ea08d0b 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c | |||
@@ -132,8 +132,9 @@ SOC_SINGLE("Aux Playback Phone Volume", AC97_CD, 4, 7, 1), | |||
132 | SOC_SINGLE("Phone Volume", AC97_PHONE, 0, 15, 1), | 132 | SOC_SINGLE("Phone Volume", AC97_PHONE, 0, 15, 1), |
133 | SOC_DOUBLE("Line Capture Volume", AC97_LINE, 8, 0, 31, 1), | 133 | SOC_DOUBLE("Line Capture Volume", AC97_LINE, 8, 0, 31, 1), |
134 | 134 | ||
135 | SOC_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0), | 135 | SOC_SINGLE_TLV("Capture Boost Switch", AC97_REC_SEL, 14, 1, 0, boost_tlv), |
136 | SOC_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1), | 136 | SOC_SINGLE_TLV("Capture to Phone Boost Switch", AC97_REC_SEL, 11, 1, 1, |
137 | boost_tlv), | ||
137 | 138 | ||
138 | SOC_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1), | 139 | SOC_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1), |
139 | SOC_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1), | 140 | SOC_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1), |
@@ -146,7 +147,7 @@ SOC_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0), | |||
146 | SOC_SINGLE("Bass Volume", AC97_MASTER_TONE, 8, 15, 1), | 147 | SOC_SINGLE("Bass Volume", AC97_MASTER_TONE, 8, 15, 1), |
147 | SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 1), | 148 | SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 1), |
148 | 149 | ||
149 | SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN, 15, 1, 1), | 150 | SOC_SINGLE("Capture Switch", AC97_REC_GAIN, 15, 1, 1), |
150 | SOC_ENUM("Capture Volume Steps", wm9712_enum[6]), | 151 | SOC_ENUM("Capture Volume Steps", wm9712_enum[6]), |
151 | SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 0), | 152 | SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 0), |
152 | SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), | 153 | SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), |
@@ -634,7 +635,6 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) | |||
634 | { | 635 | { |
635 | int ret = 0; | 636 | int ret = 0; |
636 | 637 | ||
637 | codec->control_data = codec; /* we don't use regmap! */ | ||
638 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | 638 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); |
639 | if (ret < 0) { | 639 | if (ret < 0) { |
640 | printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); | 640 | printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); |
@@ -699,8 +699,8 @@ static int __devexit wm9712_remove(struct platform_device *pdev) | |||
699 | 699 | ||
700 | static struct platform_driver wm9712_codec_driver = { | 700 | static struct platform_driver wm9712_codec_driver = { |
701 | .driver = { | 701 | .driver = { |
702 | .name = "wm9712-codec", | 702 | .name = "wm9712-codec", |
703 | .owner = THIS_MODULE, | 703 | .owner = THIS_MODULE, |
704 | }, | 704 | }, |
705 | 705 | ||
706 | .probe = wm9712_probe, | 706 | .probe = wm9712_probe, |
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index d0b8a3287a85..3eb19fb71d17 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c | |||
@@ -1196,7 +1196,6 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) | |||
1196 | if (wm9713 == NULL) | 1196 | if (wm9713 == NULL) |
1197 | return -ENOMEM; | 1197 | return -ENOMEM; |
1198 | snd_soc_codec_set_drvdata(codec, wm9713); | 1198 | snd_soc_codec_set_drvdata(codec, wm9713); |
1199 | codec->control_data = wm9713; /* we don't use regmap! */ | ||
1200 | 1199 | ||
1201 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | 1200 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); |
1202 | if (ret < 0) | 1201 | if (ret < 0) |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 61baa48823cb..7a773a835b8e 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
@@ -199,15 +199,56 @@ static void wm_hubs_dcs_cache_set(struct snd_soc_codec *codec, u16 dcs_cfg) | |||
199 | list_add_tail(&cache->list, &hubs->dcs_cache); | 199 | list_add_tail(&cache->list, &hubs->dcs_cache); |
200 | } | 200 | } |
201 | 201 | ||
202 | static void wm_hubs_read_dc_servo(struct snd_soc_codec *codec, | ||
203 | u16 *reg_l, u16 *reg_r) | ||
204 | { | ||
205 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | ||
206 | u16 dcs_reg, reg; | ||
207 | |||
208 | switch (hubs->dcs_readback_mode) { | ||
209 | case 2: | ||
210 | dcs_reg = WM8994_DC_SERVO_4E; | ||
211 | break; | ||
212 | case 1: | ||
213 | dcs_reg = WM8994_DC_SERVO_READBACK; | ||
214 | break; | ||
215 | default: | ||
216 | dcs_reg = WM8993_DC_SERVO_3; | ||
217 | break; | ||
218 | } | ||
219 | |||
220 | /* Different chips in the family support different readback | ||
221 | * methods. | ||
222 | */ | ||
223 | switch (hubs->dcs_readback_mode) { | ||
224 | case 0: | ||
225 | *reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) | ||
226 | & WM8993_DCS_INTEG_CHAN_0_MASK; | ||
227 | *reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) | ||
228 | & WM8993_DCS_INTEG_CHAN_1_MASK; | ||
229 | break; | ||
230 | case 2: | ||
231 | case 1: | ||
232 | reg = snd_soc_read(codec, dcs_reg); | ||
233 | *reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK) | ||
234 | >> WM8993_DCS_DAC_WR_VAL_1_SHIFT; | ||
235 | *reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; | ||
236 | break; | ||
237 | default: | ||
238 | WARN(1, "Unknown DCS readback method\n"); | ||
239 | return; | ||
240 | } | ||
241 | } | ||
242 | |||
202 | /* | 243 | /* |
203 | * Startup calibration of the DC servo | 244 | * Startup calibration of the DC servo |
204 | */ | 245 | */ |
205 | static void calibrate_dc_servo(struct snd_soc_codec *codec) | 246 | static void enable_dc_servo(struct snd_soc_codec *codec) |
206 | { | 247 | { |
207 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | 248 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); |
208 | struct wm_hubs_dcs_cache *cache; | 249 | struct wm_hubs_dcs_cache *cache; |
209 | s8 offset; | 250 | s8 offset; |
210 | u16 reg, reg_l, reg_r, dcs_cfg, dcs_reg; | 251 | u16 reg_l, reg_r, dcs_cfg, dcs_reg; |
211 | 252 | ||
212 | switch (hubs->dcs_readback_mode) { | 253 | switch (hubs->dcs_readback_mode) { |
213 | case 2: | 254 | case 2: |
@@ -245,27 +286,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) | |||
245 | WM8993_DCS_TRIG_STARTUP_1); | 286 | WM8993_DCS_TRIG_STARTUP_1); |
246 | } | 287 | } |
247 | 288 | ||
248 | /* Different chips in the family support different readback | 289 | wm_hubs_read_dc_servo(codec, ®_l, ®_r); |
249 | * methods. | ||
250 | */ | ||
251 | switch (hubs->dcs_readback_mode) { | ||
252 | case 0: | ||
253 | reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) | ||
254 | & WM8993_DCS_INTEG_CHAN_0_MASK; | ||
255 | reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) | ||
256 | & WM8993_DCS_INTEG_CHAN_1_MASK; | ||
257 | break; | ||
258 | case 2: | ||
259 | case 1: | ||
260 | reg = snd_soc_read(codec, dcs_reg); | ||
261 | reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK) | ||
262 | >> WM8993_DCS_DAC_WR_VAL_1_SHIFT; | ||
263 | reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; | ||
264 | break; | ||
265 | default: | ||
266 | WARN(1, "Unknown DCS readback method\n"); | ||
267 | return; | ||
268 | } | ||
269 | 290 | ||
270 | dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); | 291 | dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); |
271 | 292 | ||
@@ -276,12 +297,16 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) | |||
276 | hubs->dcs_codes_l, hubs->dcs_codes_r); | 297 | hubs->dcs_codes_l, hubs->dcs_codes_r); |
277 | 298 | ||
278 | /* HPOUT1R */ | 299 | /* HPOUT1R */ |
279 | offset = reg_r; | 300 | offset = (s8)reg_r; |
301 | dev_dbg(codec->dev, "DCS right %d->%d\n", offset, | ||
302 | offset + hubs->dcs_codes_r); | ||
280 | offset += hubs->dcs_codes_r; | 303 | offset += hubs->dcs_codes_r; |
281 | dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT; | 304 | dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT; |
282 | 305 | ||
283 | /* HPOUT1L */ | 306 | /* HPOUT1L */ |
284 | offset = reg_l; | 307 | offset = (s8)reg_l; |
308 | dev_dbg(codec->dev, "DCS left %d->%d\n", offset, | ||
309 | offset + hubs->dcs_codes_l); | ||
285 | offset += hubs->dcs_codes_l; | 310 | offset += hubs->dcs_codes_l; |
286 | dcs_cfg |= (u8)offset; | 311 | dcs_cfg |= (u8)offset; |
287 | 312 | ||
@@ -535,7 +560,7 @@ static int hp_event(struct snd_soc_dapm_widget *w, | |||
535 | snd_soc_update_bits(codec, WM8993_DC_SERVO_1, | 560 | snd_soc_update_bits(codec, WM8993_DC_SERVO_1, |
536 | WM8993_DCS_TIMER_PERIOD_01_MASK, 0); | 561 | WM8993_DCS_TIMER_PERIOD_01_MASK, 0); |
537 | 562 | ||
538 | calibrate_dc_servo(codec); | 563 | enable_dc_servo(codec); |
539 | 564 | ||
540 | reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT | | 565 | reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT | |
541 | WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT; | 566 | WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT; |
@@ -619,6 +644,28 @@ static int lineout_event(struct snd_soc_dapm_widget *w, | |||
619 | return 0; | 644 | return 0; |
620 | } | 645 | } |
621 | 646 | ||
647 | static int micbias_event(struct snd_soc_dapm_widget *w, | ||
648 | struct snd_kcontrol *kcontrol, int event) | ||
649 | { | ||
650 | struct snd_soc_codec *codec = w->codec; | ||
651 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | ||
652 | |||
653 | switch (w->shift) { | ||
654 | case WM8993_MICB1_ENA_SHIFT: | ||
655 | if (hubs->micb1_delay) | ||
656 | msleep(hubs->micb1_delay); | ||
657 | break; | ||
658 | case WM8993_MICB2_ENA_SHIFT: | ||
659 | if (hubs->micb2_delay) | ||
660 | msleep(hubs->micb2_delay); | ||
661 | break; | ||
662 | default: | ||
663 | return -EINVAL; | ||
664 | } | ||
665 | |||
666 | return 0; | ||
667 | } | ||
668 | |||
622 | void wm_hubs_update_class_w(struct snd_soc_codec *codec) | 669 | void wm_hubs_update_class_w(struct snd_soc_codec *codec) |
623 | { | 670 | { |
624 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | 671 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); |
@@ -809,8 +856,10 @@ SND_SOC_DAPM_INPUT("IN1RP"), | |||
809 | SND_SOC_DAPM_INPUT("IN2RN"), | 856 | SND_SOC_DAPM_INPUT("IN2RN"), |
810 | SND_SOC_DAPM_INPUT("IN2RP:VXRP"), | 857 | SND_SOC_DAPM_INPUT("IN2RP:VXRP"), |
811 | 858 | ||
812 | SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0), | 859 | SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, |
813 | SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0), | 860 | micbias_event, SND_SOC_DAPM_POST_PMU), |
861 | SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, | ||
862 | micbias_event, SND_SOC_DAPM_POST_PMU), | ||
814 | 863 | ||
815 | SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0, | 864 | SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0, |
816 | in1l_pga, ARRAY_SIZE(in1l_pga)), | 865 | in1l_pga, ARRAY_SIZE(in1l_pga)), |
@@ -1112,6 +1161,8 @@ int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec, | |||
1112 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | 1161 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); |
1113 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 1162 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
1114 | 1163 | ||
1164 | hubs->codec = codec; | ||
1165 | |||
1115 | INIT_LIST_HEAD(&hubs->dcs_cache); | 1166 | INIT_LIST_HEAD(&hubs->dcs_cache); |
1116 | init_completion(&hubs->dcs_done); | 1167 | init_completion(&hubs->dcs_done); |
1117 | 1168 | ||
@@ -1143,13 +1194,16 @@ EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes); | |||
1143 | int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec, | 1194 | int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec, |
1144 | int lineout1_diff, int lineout2_diff, | 1195 | int lineout1_diff, int lineout2_diff, |
1145 | int lineout1fb, int lineout2fb, | 1196 | int lineout1fb, int lineout2fb, |
1146 | int jd_scthr, int jd_thr, int micbias1_lvl, | 1197 | int jd_scthr, int jd_thr, |
1147 | int micbias2_lvl) | 1198 | int micbias1_delay, int micbias2_delay, |
1199 | int micbias1_lvl, int micbias2_lvl) | ||
1148 | { | 1200 | { |
1149 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | 1201 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); |
1150 | 1202 | ||
1151 | hubs->lineout1_se = !lineout1_diff; | 1203 | hubs->lineout1_se = !lineout1_diff; |
1152 | hubs->lineout2_se = !lineout2_diff; | 1204 | hubs->lineout2_se = !lineout2_diff; |
1205 | hubs->micb1_delay = micbias1_delay; | ||
1206 | hubs->micb2_delay = micbias2_delay; | ||
1153 | 1207 | ||
1154 | if (!lineout1_diff) | 1208 | if (!lineout1_diff) |
1155 | snd_soc_update_bits(codec, WM8993_LINE_MIXER1, | 1209 | snd_soc_update_bits(codec, WM8993_LINE_MIXER1, |
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h index da2dc899ce6d..24c763df21f9 100644 --- a/sound/soc/codecs/wm_hubs.h +++ b/sound/soc/codecs/wm_hubs.h | |||
@@ -36,6 +36,9 @@ struct wm_hubs_data { | |||
36 | struct list_head dcs_cache; | 36 | struct list_head dcs_cache; |
37 | bool (*check_class_w_digital)(struct snd_soc_codec *); | 37 | bool (*check_class_w_digital)(struct snd_soc_codec *); |
38 | 38 | ||
39 | int micb1_delay; | ||
40 | int micb2_delay; | ||
41 | |||
39 | bool lineout1_se; | 42 | bool lineout1_se; |
40 | bool lineout1n_ena; | 43 | bool lineout1n_ena; |
41 | bool lineout1p_ena; | 44 | bool lineout1p_ena; |
@@ -46,6 +49,8 @@ struct wm_hubs_data { | |||
46 | 49 | ||
47 | bool dcs_done_irq; | 50 | bool dcs_done_irq; |
48 | struct completion dcs_done; | 51 | struct completion dcs_done; |
52 | |||
53 | struct snd_soc_codec *codec; | ||
49 | }; | 54 | }; |
50 | 55 | ||
51 | extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); | 56 | extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); |
@@ -54,6 +59,7 @@ extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *, | |||
54 | int lineout1_diff, int lineout2_diff, | 59 | int lineout1_diff, int lineout2_diff, |
55 | int lineout1fb, int lineout2fb, | 60 | int lineout1fb, int lineout2fb, |
56 | int jd_scthr, int jd_thr, | 61 | int jd_scthr, int jd_thr, |
62 | int micbias1_dly, int micbias2_dly, | ||
57 | int micbias1_lvl, int micbias2_lvl); | 63 | int micbias1_lvl, int micbias2_lvl); |
58 | 64 | ||
59 | extern irqreturn_t wm_hubs_dcs_done(int irq, void *data); | 65 | extern irqreturn_t wm_hubs_dcs_done(int irq, void *data); |
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 10a2d8c788b7..6fac5af13298 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c | |||
@@ -22,10 +22,6 @@ | |||
22 | #include <asm/dma.h> | 22 | #include <asm/dma.h> |
23 | #include <asm/mach-types.h> | 23 | #include <asm/mach-types.h> |
24 | 24 | ||
25 | #include <mach/asp.h> | ||
26 | #include <mach/edma.h> | ||
27 | #include <mach/mux.h> | ||
28 | |||
29 | #include "davinci-pcm.h" | 25 | #include "davinci-pcm.h" |
30 | #include "davinci-i2s.h" | 26 | #include "davinci-i2s.h" |
31 | #include "davinci-mcasp.h" | 27 | #include "davinci-mcasp.h" |
@@ -160,7 +156,7 @@ static struct snd_soc_dai_link dm6446_evm_dai = { | |||
160 | .cpu_dai_name = "davinci-mcbsp", | 156 | .cpu_dai_name = "davinci-mcbsp", |
161 | .codec_dai_name = "tlv320aic3x-hifi", | 157 | .codec_dai_name = "tlv320aic3x-hifi", |
162 | .codec_name = "tlv320aic3x-codec.1-001b", | 158 | .codec_name = "tlv320aic3x-codec.1-001b", |
163 | .platform_name = "davinci-pcm-audio", | 159 | .platform_name = "davinci-mcbsp", |
164 | .init = evm_aic3x_init, | 160 | .init = evm_aic3x_init, |
165 | .ops = &evm_ops, | 161 | .ops = &evm_ops, |
166 | }; | 162 | }; |
@@ -171,7 +167,7 @@ static struct snd_soc_dai_link dm355_evm_dai = { | |||
171 | .cpu_dai_name = "davinci-mcbsp.1", | 167 | .cpu_dai_name = "davinci-mcbsp.1", |
172 | .codec_dai_name = "tlv320aic3x-hifi", | 168 | .codec_dai_name = "tlv320aic3x-hifi", |
173 | .codec_name = "tlv320aic3x-codec.1-001b", | 169 | .codec_name = "tlv320aic3x-codec.1-001b", |
174 | .platform_name = "davinci-pcm-audio", | 170 | .platform_name = "davinci-mcbsp.1", |
175 | .init = evm_aic3x_init, | 171 | .init = evm_aic3x_init, |
176 | .ops = &evm_ops, | 172 | .ops = &evm_ops, |
177 | }; | 173 | }; |
@@ -185,14 +181,15 @@ static struct snd_soc_dai_link dm365_evm_dai = { | |||
185 | .init = evm_aic3x_init, | 181 | .init = evm_aic3x_init, |
186 | .codec_name = "tlv320aic3x-codec.1-0018", | 182 | .codec_name = "tlv320aic3x-codec.1-0018", |
187 | .ops = &evm_ops, | 183 | .ops = &evm_ops, |
184 | .platform_name = "davinci-mcbsp", | ||
188 | #elif defined(CONFIG_SND_DM365_VOICE_CODEC) | 185 | #elif defined(CONFIG_SND_DM365_VOICE_CODEC) |
189 | .name = "Voice Codec - CQ93VC", | 186 | .name = "Voice Codec - CQ93VC", |
190 | .stream_name = "CQ93", | 187 | .stream_name = "CQ93", |
191 | .cpu_dai_name = "davinci-vcif", | 188 | .cpu_dai_name = "davinci-vcif", |
192 | .codec_dai_name = "cq93vc-hifi", | 189 | .codec_dai_name = "cq93vc-hifi", |
193 | .codec_name = "cq93vc-codec", | 190 | .codec_name = "cq93vc-codec", |
191 | .platform_name = "davinci-vcif", | ||
194 | #endif | 192 | #endif |
195 | .platform_name = "davinci-pcm-audio", | ||
196 | }; | 193 | }; |
197 | 194 | ||
198 | static struct snd_soc_dai_link dm6467_evm_dai[] = { | 195 | static struct snd_soc_dai_link dm6467_evm_dai[] = { |
@@ -201,7 +198,7 @@ static struct snd_soc_dai_link dm6467_evm_dai[] = { | |||
201 | .stream_name = "AIC3X", | 198 | .stream_name = "AIC3X", |
202 | .cpu_dai_name= "davinci-mcasp.0", | 199 | .cpu_dai_name= "davinci-mcasp.0", |
203 | .codec_dai_name = "tlv320aic3x-hifi", | 200 | .codec_dai_name = "tlv320aic3x-hifi", |
204 | .platform_name ="davinci-pcm-audio", | 201 | .platform_name = "davinci-mcasp.0", |
205 | .codec_name = "tlv320aic3x-codec.0-001a", | 202 | .codec_name = "tlv320aic3x-codec.0-001a", |
206 | .init = evm_aic3x_init, | 203 | .init = evm_aic3x_init, |
207 | .ops = &evm_ops, | 204 | .ops = &evm_ops, |
@@ -212,7 +209,7 @@ static struct snd_soc_dai_link dm6467_evm_dai[] = { | |||
212 | .cpu_dai_name= "davinci-mcasp.1", | 209 | .cpu_dai_name= "davinci-mcasp.1", |
213 | .codec_dai_name = "dit-hifi", | 210 | .codec_dai_name = "dit-hifi", |
214 | .codec_name = "spdif_dit", | 211 | .codec_name = "spdif_dit", |
215 | .platform_name = "davinci-pcm-audio", | 212 | .platform_name = "davinci-mcasp.1", |
216 | .ops = &evm_spdif_ops, | 213 | .ops = &evm_spdif_ops, |
217 | }, | 214 | }, |
218 | }; | 215 | }; |
@@ -223,7 +220,7 @@ static struct snd_soc_dai_link da830_evm_dai = { | |||
223 | .cpu_dai_name = "davinci-mcasp.1", | 220 | .cpu_dai_name = "davinci-mcasp.1", |
224 | .codec_dai_name = "tlv320aic3x-hifi", | 221 | .codec_dai_name = "tlv320aic3x-hifi", |
225 | .codec_name = "tlv320aic3x-codec.1-0018", | 222 | .codec_name = "tlv320aic3x-codec.1-0018", |
226 | .platform_name = "davinci-pcm-audio", | 223 | .platform_name = "davinci-mcasp.1", |
227 | .init = evm_aic3x_init, | 224 | .init = evm_aic3x_init, |
228 | .ops = &evm_ops, | 225 | .ops = &evm_ops, |
229 | }; | 226 | }; |
@@ -234,7 +231,7 @@ static struct snd_soc_dai_link da850_evm_dai = { | |||
234 | .cpu_dai_name= "davinci-mcasp.0", | 231 | .cpu_dai_name= "davinci-mcasp.0", |
235 | .codec_dai_name = "tlv320aic3x-hifi", | 232 | .codec_dai_name = "tlv320aic3x-hifi", |
236 | .codec_name = "tlv320aic3x-codec.1-0018", | 233 | .codec_name = "tlv320aic3x-codec.1-0018", |
237 | .platform_name = "davinci-pcm-audio", | 234 | .platform_name = "davinci-mcasp.0", |
238 | .init = evm_aic3x_init, | 235 | .init = evm_aic3x_init, |
239 | .ops = &evm_ops, | 236 | .ops = &evm_ops, |
240 | }; | 237 | }; |
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index 0a74b9587a2c..821831207180 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
19 | #include <linux/platform_data/davinci_asp.h> | ||
19 | 20 | ||
20 | #include <sound/core.h> | 21 | #include <sound/core.h> |
21 | #include <sound/pcm.h> | 22 | #include <sound/pcm.h> |
@@ -23,8 +24,6 @@ | |||
23 | #include <sound/initval.h> | 24 | #include <sound/initval.h> |
24 | #include <sound/soc.h> | 25 | #include <sound/soc.h> |
25 | 26 | ||
26 | #include <mach/asp.h> | ||
27 | |||
28 | #include "davinci-pcm.h" | 27 | #include "davinci-pcm.h" |
29 | #include "davinci-i2s.h" | 28 | #include "davinci-i2s.h" |
30 | 29 | ||
@@ -732,8 +731,16 @@ static int davinci_i2s_probe(struct platform_device *pdev) | |||
732 | if (ret != 0) | 731 | if (ret != 0) |
733 | goto err_release_clk; | 732 | goto err_release_clk; |
734 | 733 | ||
734 | ret = davinci_soc_platform_register(&pdev->dev); | ||
735 | if (ret) { | ||
736 | dev_err(&pdev->dev, "register PCM failed: %d\n", ret); | ||
737 | goto err_unregister_dai; | ||
738 | } | ||
739 | |||
735 | return 0; | 740 | return 0; |
736 | 741 | ||
742 | err_unregister_dai: | ||
743 | snd_soc_unregister_dai(&pdev->dev); | ||
737 | err_release_clk: | 744 | err_release_clk: |
738 | clk_disable(dev->clk); | 745 | clk_disable(dev->clk); |
739 | clk_put(dev->clk); | 746 | clk_put(dev->clk); |
@@ -745,6 +752,8 @@ static int davinci_i2s_remove(struct platform_device *pdev) | |||
745 | struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev); | 752 | struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev); |
746 | 753 | ||
747 | snd_soc_unregister_dai(&pdev->dev); | 754 | snd_soc_unregister_dai(&pdev->dev); |
755 | davinci_soc_platform_unregister(&pdev->dev); | ||
756 | |||
748 | clk_disable(dev->clk); | 757 | clk_disable(dev->clk); |
749 | clk_put(dev->clk); | 758 | clk_put(dev->clk); |
750 | dev->clk = NULL; | 759 | dev->clk = NULL; |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index ce5e5cd254dd..714e51e5be5b 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -21,7 +21,10 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/clk.h> | 24 | #include <linux/pm_runtime.h> |
25 | #include <linux/of.h> | ||
26 | #include <linux/of_platform.h> | ||
27 | #include <linux/of_device.h> | ||
25 | 28 | ||
26 | #include <sound/core.h> | 29 | #include <sound/core.h> |
27 | #include <sound/pcm.h> | 30 | #include <sound/pcm.h> |
@@ -108,6 +111,10 @@ | |||
108 | #define DAVINCI_MCASP_WFIFOSTS (0x1014) | 111 | #define DAVINCI_MCASP_WFIFOSTS (0x1014) |
109 | #define DAVINCI_MCASP_RFIFOCTL (0x1018) | 112 | #define DAVINCI_MCASP_RFIFOCTL (0x1018) |
110 | #define DAVINCI_MCASP_RFIFOSTS (0x101C) | 113 | #define DAVINCI_MCASP_RFIFOSTS (0x101C) |
114 | #define MCASP_VER3_WFIFOCTL (0x1000) | ||
115 | #define MCASP_VER3_WFIFOSTS (0x1004) | ||
116 | #define MCASP_VER3_RFIFOCTL (0x1008) | ||
117 | #define MCASP_VER3_RFIFOSTS (0x100C) | ||
111 | 118 | ||
112 | /* | 119 | /* |
113 | * DAVINCI_MCASP_PWREMUMGT_REG - Power Down and Emulation Management | 120 | * DAVINCI_MCASP_PWREMUMGT_REG - Power Down and Emulation Management |
@@ -381,18 +388,36 @@ static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) | |||
381 | { | 388 | { |
382 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 389 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
383 | if (dev->txnumevt) { /* enable FIFO */ | 390 | if (dev->txnumevt) { /* enable FIFO */ |
384 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, | 391 | switch (dev->version) { |
392 | case MCASP_VERSION_3: | ||
393 | mcasp_clr_bits(dev->base + MCASP_VER3_WFIFOCTL, | ||
385 | FIFO_ENABLE); | 394 | FIFO_ENABLE); |
386 | mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, | 395 | mcasp_set_bits(dev->base + MCASP_VER3_WFIFOCTL, |
387 | FIFO_ENABLE); | 396 | FIFO_ENABLE); |
397 | break; | ||
398 | default: | ||
399 | mcasp_clr_bits(dev->base + | ||
400 | DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE); | ||
401 | mcasp_set_bits(dev->base + | ||
402 | DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE); | ||
403 | } | ||
388 | } | 404 | } |
389 | mcasp_start_tx(dev); | 405 | mcasp_start_tx(dev); |
390 | } else { | 406 | } else { |
391 | if (dev->rxnumevt) { /* enable FIFO */ | 407 | if (dev->rxnumevt) { /* enable FIFO */ |
392 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, | 408 | switch (dev->version) { |
409 | case MCASP_VERSION_3: | ||
410 | mcasp_clr_bits(dev->base + MCASP_VER3_RFIFOCTL, | ||
393 | FIFO_ENABLE); | 411 | FIFO_ENABLE); |
394 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, | 412 | mcasp_set_bits(dev->base + MCASP_VER3_RFIFOCTL, |
395 | FIFO_ENABLE); | 413 | FIFO_ENABLE); |
414 | break; | ||
415 | default: | ||
416 | mcasp_clr_bits(dev->base + | ||
417 | DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE); | ||
418 | mcasp_set_bits(dev->base + | ||
419 | DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE); | ||
420 | } | ||
396 | } | 421 | } |
397 | mcasp_start_rx(dev); | 422 | mcasp_start_rx(dev); |
398 | } | 423 | } |
@@ -413,14 +438,31 @@ static void mcasp_stop_tx(struct davinci_audio_dev *dev) | |||
413 | static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream) | 438 | static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream) |
414 | { | 439 | { |
415 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 440 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
416 | if (dev->txnumevt) /* disable FIFO */ | 441 | if (dev->txnumevt) { /* disable FIFO */ |
417 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, | 442 | switch (dev->version) { |
443 | case MCASP_VERSION_3: | ||
444 | mcasp_clr_bits(dev->base + MCASP_VER3_WFIFOCTL, | ||
418 | FIFO_ENABLE); | 445 | FIFO_ENABLE); |
446 | break; | ||
447 | default: | ||
448 | mcasp_clr_bits(dev->base + | ||
449 | DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE); | ||
450 | } | ||
451 | } | ||
419 | mcasp_stop_tx(dev); | 452 | mcasp_stop_tx(dev); |
420 | } else { | 453 | } else { |
421 | if (dev->rxnumevt) /* disable FIFO */ | 454 | if (dev->rxnumevt) { /* disable FIFO */ |
422 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, | 455 | switch (dev->version) { |
456 | case MCASP_VERSION_3: | ||
457 | mcasp_clr_bits(dev->base + MCASP_VER3_RFIFOCTL, | ||
423 | FIFO_ENABLE); | 458 | FIFO_ENABLE); |
459 | break; | ||
460 | |||
461 | default: | ||
462 | mcasp_clr_bits(dev->base + | ||
463 | DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE); | ||
464 | } | ||
465 | } | ||
424 | mcasp_stop_rx(dev); | 466 | mcasp_stop_rx(dev); |
425 | } | 467 | } |
426 | } | 468 | } |
@@ -619,20 +661,37 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) | |||
619 | if (dev->txnumevt * tx_ser > 64) | 661 | if (dev->txnumevt * tx_ser > 64) |
620 | dev->txnumevt = 1; | 662 | dev->txnumevt = 1; |
621 | 663 | ||
622 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, tx_ser, | 664 | switch (dev->version) { |
665 | case MCASP_VERSION_3: | ||
666 | mcasp_mod_bits(dev->base + MCASP_VER3_WFIFOCTL, tx_ser, | ||
623 | NUMDMA_MASK); | 667 | NUMDMA_MASK); |
624 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, | 668 | mcasp_mod_bits(dev->base + MCASP_VER3_WFIFOCTL, |
625 | ((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK); | 669 | ((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK); |
670 | break; | ||
671 | default: | ||
672 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, | ||
673 | tx_ser, NUMDMA_MASK); | ||
674 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, | ||
675 | ((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK); | ||
676 | } | ||
626 | } | 677 | } |
627 | 678 | ||
628 | if (dev->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) { | 679 | if (dev->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) { |
629 | if (dev->rxnumevt * rx_ser > 64) | 680 | if (dev->rxnumevt * rx_ser > 64) |
630 | dev->rxnumevt = 1; | 681 | dev->rxnumevt = 1; |
631 | 682 | switch (dev->version) { | |
632 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, rx_ser, | 683 | case MCASP_VERSION_3: |
684 | mcasp_mod_bits(dev->base + MCASP_VER3_RFIFOCTL, rx_ser, | ||
633 | NUMDMA_MASK); | 685 | NUMDMA_MASK); |
634 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, | 686 | mcasp_mod_bits(dev->base + MCASP_VER3_RFIFOCTL, |
635 | ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); | 687 | ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); |
688 | break; | ||
689 | default: | ||
690 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, | ||
691 | rx_ser, NUMDMA_MASK); | ||
692 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, | ||
693 | ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); | ||
694 | } | ||
636 | } | 695 | } |
637 | } | 696 | } |
638 | 697 | ||
@@ -782,20 +841,17 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, | |||
782 | case SNDRV_PCM_TRIGGER_RESUME: | 841 | case SNDRV_PCM_TRIGGER_RESUME: |
783 | case SNDRV_PCM_TRIGGER_START: | 842 | case SNDRV_PCM_TRIGGER_START: |
784 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 843 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
785 | if (!dev->clk_active) { | 844 | ret = pm_runtime_get_sync(dev->dev); |
786 | clk_enable(dev->clk); | 845 | if (IS_ERR_VALUE(ret)) |
787 | dev->clk_active = 1; | 846 | dev_err(dev->dev, "pm_runtime_get_sync() failed\n"); |
788 | } | ||
789 | davinci_mcasp_start(dev, substream->stream); | 847 | davinci_mcasp_start(dev, substream->stream); |
790 | break; | 848 | break; |
791 | 849 | ||
792 | case SNDRV_PCM_TRIGGER_SUSPEND: | 850 | case SNDRV_PCM_TRIGGER_SUSPEND: |
793 | davinci_mcasp_stop(dev, substream->stream); | 851 | davinci_mcasp_stop(dev, substream->stream); |
794 | if (dev->clk_active) { | 852 | ret = pm_runtime_put_sync(dev->dev); |
795 | clk_disable(dev->clk); | 853 | if (IS_ERR_VALUE(ret)) |
796 | dev->clk_active = 0; | 854 | dev_err(dev->dev, "pm_runtime_put_sync() failed\n"); |
797 | } | ||
798 | |||
799 | break; | 855 | break; |
800 | 856 | ||
801 | case SNDRV_PCM_TRIGGER_STOP: | 857 | case SNDRV_PCM_TRIGGER_STOP: |
@@ -865,6 +921,118 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { | |||
865 | 921 | ||
866 | }; | 922 | }; |
867 | 923 | ||
924 | static const struct of_device_id mcasp_dt_ids[] = { | ||
925 | { | ||
926 | .compatible = "ti,dm646x-mcasp-audio", | ||
927 | .data = (void *)MCASP_VERSION_1, | ||
928 | }, | ||
929 | { | ||
930 | .compatible = "ti,da830-mcasp-audio", | ||
931 | .data = (void *)MCASP_VERSION_2, | ||
932 | }, | ||
933 | { | ||
934 | .compatible = "ti,omap2-mcasp-audio", | ||
935 | .data = (void *)MCASP_VERSION_3, | ||
936 | }, | ||
937 | { /* sentinel */ } | ||
938 | }; | ||
939 | MODULE_DEVICE_TABLE(of, mcasp_dt_ids); | ||
940 | |||
941 | static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( | ||
942 | struct platform_device *pdev) | ||
943 | { | ||
944 | struct device_node *np = pdev->dev.of_node; | ||
945 | struct snd_platform_data *pdata = NULL; | ||
946 | const struct of_device_id *match = | ||
947 | of_match_device(of_match_ptr(mcasp_dt_ids), &pdev->dev); | ||
948 | |||
949 | const u32 *of_serial_dir32; | ||
950 | u8 *of_serial_dir; | ||
951 | u32 val; | ||
952 | int i, ret = 0; | ||
953 | |||
954 | if (pdev->dev.platform_data) { | ||
955 | pdata = pdev->dev.platform_data; | ||
956 | return pdata; | ||
957 | } else if (match) { | ||
958 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
959 | if (!pdata) { | ||
960 | ret = -ENOMEM; | ||
961 | goto nodata; | ||
962 | } | ||
963 | } else { | ||
964 | /* control shouldn't reach here. something is wrong */ | ||
965 | ret = -EINVAL; | ||
966 | goto nodata; | ||
967 | } | ||
968 | |||
969 | if (match->data) | ||
970 | pdata->version = (u8)((int)match->data); | ||
971 | |||
972 | ret = of_property_read_u32(np, "op-mode", &val); | ||
973 | if (ret >= 0) | ||
974 | pdata->op_mode = val; | ||
975 | |||
976 | ret = of_property_read_u32(np, "tdm-slots", &val); | ||
977 | if (ret >= 0) | ||
978 | pdata->tdm_slots = val; | ||
979 | |||
980 | ret = of_property_read_u32(np, "num-serializer", &val); | ||
981 | if (ret >= 0) | ||
982 | pdata->num_serializer = val; | ||
983 | |||
984 | of_serial_dir32 = of_get_property(np, "serial-dir", &val); | ||
985 | val /= sizeof(u32); | ||
986 | if (val != pdata->num_serializer) { | ||
987 | dev_err(&pdev->dev, | ||
988 | "num-serializer(%d) != serial-dir size(%d)\n", | ||
989 | pdata->num_serializer, val); | ||
990 | ret = -EINVAL; | ||
991 | goto nodata; | ||
992 | } | ||
993 | |||
994 | if (of_serial_dir32) { | ||
995 | of_serial_dir = devm_kzalloc(&pdev->dev, | ||
996 | (sizeof(*of_serial_dir) * val), | ||
997 | GFP_KERNEL); | ||
998 | if (!of_serial_dir) { | ||
999 | ret = -ENOMEM; | ||
1000 | goto nodata; | ||
1001 | } | ||
1002 | |||
1003 | for (i = 0; i < pdata->num_serializer; i++) | ||
1004 | of_serial_dir[i] = be32_to_cpup(&of_serial_dir32[i]); | ||
1005 | |||
1006 | pdata->serial_dir = of_serial_dir; | ||
1007 | } | ||
1008 | |||
1009 | ret = of_property_read_u32(np, "tx-num-evt", &val); | ||
1010 | if (ret >= 0) | ||
1011 | pdata->txnumevt = val; | ||
1012 | |||
1013 | ret = of_property_read_u32(np, "rx-num-evt", &val); | ||
1014 | if (ret >= 0) | ||
1015 | pdata->rxnumevt = val; | ||
1016 | |||
1017 | ret = of_property_read_u32(np, "sram-size-playback", &val); | ||
1018 | if (ret >= 0) | ||
1019 | pdata->sram_size_playback = val; | ||
1020 | |||
1021 | ret = of_property_read_u32(np, "sram-size-capture", &val); | ||
1022 | if (ret >= 0) | ||
1023 | pdata->sram_size_capture = val; | ||
1024 | |||
1025 | return pdata; | ||
1026 | |||
1027 | nodata: | ||
1028 | if (ret < 0) { | ||
1029 | dev_err(&pdev->dev, "Error populating platform data, err %d\n", | ||
1030 | ret); | ||
1031 | pdata = NULL; | ||
1032 | } | ||
1033 | return pdata; | ||
1034 | } | ||
1035 | |||
868 | static int davinci_mcasp_probe(struct platform_device *pdev) | 1036 | static int davinci_mcasp_probe(struct platform_device *pdev) |
869 | { | 1037 | { |
870 | struct davinci_pcm_dma_params *dma_data; | 1038 | struct davinci_pcm_dma_params *dma_data; |
@@ -873,11 +1041,22 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
873 | struct davinci_audio_dev *dev; | 1041 | struct davinci_audio_dev *dev; |
874 | int ret; | 1042 | int ret; |
875 | 1043 | ||
1044 | if (!pdev->dev.platform_data && !pdev->dev.of_node) { | ||
1045 | dev_err(&pdev->dev, "No platform data supplied\n"); | ||
1046 | return -EINVAL; | ||
1047 | } | ||
1048 | |||
876 | dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_audio_dev), | 1049 | dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_audio_dev), |
877 | GFP_KERNEL); | 1050 | GFP_KERNEL); |
878 | if (!dev) | 1051 | if (!dev) |
879 | return -ENOMEM; | 1052 | return -ENOMEM; |
880 | 1053 | ||
1054 | pdata = davinci_mcasp_set_pdata_from_of(pdev); | ||
1055 | if (!pdata) { | ||
1056 | dev_err(&pdev->dev, "no platform data\n"); | ||
1057 | return -EINVAL; | ||
1058 | } | ||
1059 | |||
881 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1060 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
882 | if (!mem) { | 1061 | if (!mem) { |
883 | dev_err(&pdev->dev, "no mem resource?\n"); | 1062 | dev_err(&pdev->dev, "no mem resource?\n"); |
@@ -891,13 +1070,13 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
891 | return -EBUSY; | 1070 | return -EBUSY; |
892 | } | 1071 | } |
893 | 1072 | ||
894 | pdata = pdev->dev.platform_data; | 1073 | pm_runtime_enable(&pdev->dev); |
895 | dev->clk = clk_get(&pdev->dev, NULL); | ||
896 | if (IS_ERR(dev->clk)) | ||
897 | return -ENODEV; | ||
898 | 1074 | ||
899 | clk_enable(dev->clk); | 1075 | ret = pm_runtime_get_sync(&pdev->dev); |
900 | dev->clk_active = 1; | 1076 | if (IS_ERR_VALUE(ret)) { |
1077 | dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); | ||
1078 | return ret; | ||
1079 | } | ||
901 | 1080 | ||
902 | dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); | 1081 | dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); |
903 | if (!dev->base) { | 1082 | if (!dev->base) { |
@@ -914,6 +1093,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
914 | dev->version = pdata->version; | 1093 | dev->version = pdata->version; |
915 | dev->txnumevt = pdata->txnumevt; | 1094 | dev->txnumevt = pdata->txnumevt; |
916 | dev->rxnumevt = pdata->rxnumevt; | 1095 | dev->rxnumevt = pdata->rxnumevt; |
1096 | dev->dev = &pdev->dev; | ||
917 | 1097 | ||
918 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; | 1098 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; |
919 | dma_data->asp_chan_q = pdata->asp_chan_q; | 1099 | dma_data->asp_chan_q = pdata->asp_chan_q; |
@@ -952,22 +1132,31 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
952 | 1132 | ||
953 | if (ret != 0) | 1133 | if (ret != 0) |
954 | goto err_release_clk; | 1134 | goto err_release_clk; |
1135 | |||
1136 | ret = davinci_soc_platform_register(&pdev->dev); | ||
1137 | if (ret) { | ||
1138 | dev_err(&pdev->dev, "register PCM failed: %d\n", ret); | ||
1139 | goto err_unregister_dai; | ||
1140 | } | ||
1141 | |||
955 | return 0; | 1142 | return 0; |
956 | 1143 | ||
1144 | err_unregister_dai: | ||
1145 | snd_soc_unregister_dai(&pdev->dev); | ||
957 | err_release_clk: | 1146 | err_release_clk: |
958 | clk_disable(dev->clk); | 1147 | pm_runtime_put_sync(&pdev->dev); |
959 | clk_put(dev->clk); | 1148 | pm_runtime_disable(&pdev->dev); |
960 | return ret; | 1149 | return ret; |
961 | } | 1150 | } |
962 | 1151 | ||
963 | static int davinci_mcasp_remove(struct platform_device *pdev) | 1152 | static int davinci_mcasp_remove(struct platform_device *pdev) |
964 | { | 1153 | { |
965 | struct davinci_audio_dev *dev = dev_get_drvdata(&pdev->dev); | ||
966 | 1154 | ||
967 | snd_soc_unregister_dai(&pdev->dev); | 1155 | snd_soc_unregister_dai(&pdev->dev); |
968 | clk_disable(dev->clk); | 1156 | davinci_soc_platform_unregister(&pdev->dev); |
969 | clk_put(dev->clk); | 1157 | |
970 | dev->clk = NULL; | 1158 | pm_runtime_put_sync(&pdev->dev); |
1159 | pm_runtime_disable(&pdev->dev); | ||
971 | 1160 | ||
972 | return 0; | 1161 | return 0; |
973 | } | 1162 | } |
@@ -978,6 +1167,7 @@ static struct platform_driver davinci_mcasp_driver = { | |||
978 | .driver = { | 1167 | .driver = { |
979 | .name = "davinci-mcasp", | 1168 | .name = "davinci-mcasp", |
980 | .owner = THIS_MODULE, | 1169 | .owner = THIS_MODULE, |
1170 | .of_match_table = of_match_ptr(mcasp_dt_ids), | ||
981 | }, | 1171 | }, |
982 | }; | 1172 | }; |
983 | 1173 | ||
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h index 4681acc63606..0de9ed6ce038 100644 --- a/sound/soc/davinci/davinci-mcasp.h +++ b/sound/soc/davinci/davinci-mcasp.h | |||
@@ -19,7 +19,8 @@ | |||
19 | #define DAVINCI_MCASP_H | 19 | #define DAVINCI_MCASP_H |
20 | 20 | ||
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <mach/asp.h> | 22 | #include <linux/platform_data/davinci_asp.h> |
23 | |||
23 | #include "davinci-pcm.h" | 24 | #include "davinci-pcm.h" |
24 | 25 | ||
25 | #define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_96000 | 26 | #define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_96000 |
@@ -40,9 +41,8 @@ struct davinci_audio_dev { | |||
40 | struct davinci_pcm_dma_params dma_params[2]; | 41 | struct davinci_pcm_dma_params dma_params[2]; |
41 | void __iomem *base; | 42 | void __iomem *base; |
42 | int sample_rate; | 43 | int sample_rate; |
43 | struct clk *clk; | 44 | struct device *dev; |
44 | unsigned int codec_fmt; | 45 | unsigned int codec_fmt; |
45 | u8 clk_active; | ||
46 | 46 | ||
47 | /* McASP specific data */ | 47 | /* McASP specific data */ |
48 | int tdm_slots; | 48 | int tdm_slots; |
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index 97d77b298968..93ea3bf567e1 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <sound/soc.h> | 23 | #include <sound/soc.h> |
24 | 24 | ||
25 | #include <asm/dma.h> | 25 | #include <asm/dma.h> |
26 | #include <mach/edma.h> | ||
27 | #include <mach/sram.h> | 26 | #include <mach/sram.h> |
28 | 27 | ||
29 | #include "davinci-pcm.h" | 28 | #include "davinci-pcm.h" |
@@ -864,28 +863,17 @@ static struct snd_soc_platform_driver davinci_soc_platform = { | |||
864 | .pcm_free = davinci_pcm_free, | 863 | .pcm_free = davinci_pcm_free, |
865 | }; | 864 | }; |
866 | 865 | ||
867 | static int __devinit davinci_soc_platform_probe(struct platform_device *pdev) | 866 | int davinci_soc_platform_register(struct device *dev) |
868 | { | 867 | { |
869 | return snd_soc_register_platform(&pdev->dev, &davinci_soc_platform); | 868 | return snd_soc_register_platform(dev, &davinci_soc_platform); |
870 | } | 869 | } |
870 | EXPORT_SYMBOL_GPL(davinci_soc_platform_register); | ||
871 | 871 | ||
872 | static int __devexit davinci_soc_platform_remove(struct platform_device *pdev) | 872 | void davinci_soc_platform_unregister(struct device *dev) |
873 | { | 873 | { |
874 | snd_soc_unregister_platform(&pdev->dev); | 874 | snd_soc_unregister_platform(dev); |
875 | return 0; | ||
876 | } | 875 | } |
877 | 876 | EXPORT_SYMBOL_GPL(davinci_soc_platform_unregister); | |
878 | static struct platform_driver davinci_pcm_driver = { | ||
879 | .driver = { | ||
880 | .name = "davinci-pcm-audio", | ||
881 | .owner = THIS_MODULE, | ||
882 | }, | ||
883 | |||
884 | .probe = davinci_soc_platform_probe, | ||
885 | .remove = __devexit_p(davinci_soc_platform_remove), | ||
886 | }; | ||
887 | |||
888 | module_platform_driver(davinci_pcm_driver); | ||
889 | 877 | ||
890 | MODULE_AUTHOR("Vladimir Barinov"); | 878 | MODULE_AUTHOR("Vladimir Barinov"); |
891 | MODULE_DESCRIPTION("TI DAVINCI PCM DMA module"); | 879 | MODULE_DESCRIPTION("TI DAVINCI PCM DMA module"); |
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h index c0d6c9be4b4d..fc4d01cdd8c9 100644 --- a/sound/soc/davinci/davinci-pcm.h +++ b/sound/soc/davinci/davinci-pcm.h | |||
@@ -12,9 +12,8 @@ | |||
12 | #ifndef _DAVINCI_PCM_H | 12 | #ifndef _DAVINCI_PCM_H |
13 | #define _DAVINCI_PCM_H | 13 | #define _DAVINCI_PCM_H |
14 | 14 | ||
15 | #include <linux/platform_data/davinci_asp.h> | ||
15 | #include <mach/edma.h> | 16 | #include <mach/edma.h> |
16 | #include <mach/asp.h> | ||
17 | |||
18 | 17 | ||
19 | struct davinci_pcm_dma_params { | 18 | struct davinci_pcm_dma_params { |
20 | int channel; /* sync dma channel ID */ | 19 | int channel; /* sync dma channel ID */ |
@@ -28,4 +27,7 @@ struct davinci_pcm_dma_params { | |||
28 | unsigned int fifo_level; | 27 | unsigned int fifo_level; |
29 | }; | 28 | }; |
30 | 29 | ||
30 | int davinci_soc_platform_register(struct device *dev); | ||
31 | void davinci_soc_platform_unregister(struct device *dev); | ||
32 | |||
31 | #endif | 33 | #endif |
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c index f71175b29e38..5be65aae7e0e 100644 --- a/sound/soc/davinci/davinci-sffsdr.c +++ b/sound/soc/davinci/davinci-sffsdr.c | |||
@@ -86,7 +86,7 @@ static struct snd_soc_dai_link sffsdr_dai = { | |||
86 | .cpu_dai_name = "davinci-mcbsp", | 86 | .cpu_dai_name = "davinci-mcbsp", |
87 | .codec_dai_name = "pcm3008-hifi", | 87 | .codec_dai_name = "pcm3008-hifi", |
88 | .codec_name = "pcm3008-codec", | 88 | .codec_name = "pcm3008-codec", |
89 | .platform_name = "davinci-pcm-audio", | 89 | .platform_name = "davinci-mcbsp", |
90 | .ops = &sffsdr_ops, | 90 | .ops = &sffsdr_ops, |
91 | }; | 91 | }; |
92 | 92 | ||
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c index da030ff883d5..07bde2e6f84e 100644 --- a/sound/soc/davinci/davinci-vcif.c +++ b/sound/soc/davinci/davinci-vcif.c | |||
@@ -240,12 +240,20 @@ static int davinci_vcif_probe(struct platform_device *pdev) | |||
240 | return ret; | 240 | return ret; |
241 | } | 241 | } |
242 | 242 | ||
243 | ret = davinci_soc_platform_register(&pdev->dev); | ||
244 | if (ret) { | ||
245 | dev_err(&pdev->dev, "register PCM failed: %d\n", ret); | ||
246 | snd_soc_unregister_dai(&pdev->dev); | ||
247 | return ret; | ||
248 | } | ||
249 | |||
243 | return 0; | 250 | return 0; |
244 | } | 251 | } |
245 | 252 | ||
246 | static int davinci_vcif_remove(struct platform_device *pdev) | 253 | static int davinci_vcif_remove(struct platform_device *pdev) |
247 | { | 254 | { |
248 | snd_soc_unregister_dai(&pdev->dev); | 255 | snd_soc_unregister_dai(&pdev->dev); |
256 | davinci_soc_platform_unregister(&pdev->dev); | ||
249 | 257 | ||
250 | return 0; | 258 | return 0; |
251 | } | 259 | } |
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index d70133086ac3..4563b28bd625 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig | |||
@@ -6,7 +6,7 @@ config SND_SOC_FSL_UTILS | |||
6 | 6 | ||
7 | menuconfig SND_POWERPC_SOC | 7 | menuconfig SND_POWERPC_SOC |
8 | tristate "SoC Audio for Freescale PowerPC CPUs" | 8 | tristate "SoC Audio for Freescale PowerPC CPUs" |
9 | depends on FSL_SOC | 9 | depends on FSL_SOC || PPC_MPC52xx |
10 | help | 10 | help |
11 | Say Y or M if you want to add support for codecs attached to | 11 | Say Y or M if you want to add support for codecs attached to |
12 | the PowerPC CPUs. | 12 | the PowerPC CPUs. |
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index 96bb92dd174c..6feb26500580 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c | |||
@@ -823,12 +823,6 @@ static int fsl_dma_close(struct snd_pcm_substream *substream) | |||
823 | if (dma_private->irq) | 823 | if (dma_private->irq) |
824 | free_irq(dma_private->irq, dma_private); | 824 | free_irq(dma_private->irq, dma_private); |
825 | 825 | ||
826 | if (dma_private->ld_buf_phys) { | ||
827 | dma_unmap_single(dev, dma_private->ld_buf_phys, | ||
828 | sizeof(dma_private->link), | ||
829 | DMA_TO_DEVICE); | ||
830 | } | ||
831 | |||
832 | /* Deallocate the fsl_dma_private structure */ | 826 | /* Deallocate the fsl_dma_private structure */ |
833 | dma_free_coherent(dev, sizeof(struct fsl_dma_private), | 827 | dma_free_coherent(dev, sizeof(struct fsl_dma_private), |
834 | dma_private, dma_private->ld_buf_phys); | 828 | dma_private, dma_private->ld_buf_phys); |
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c index e7c800ebbd75..524ce6210cee 100644 --- a/sound/soc/fsl/imx-audmux.c +++ b/sound/soc/fsl/imx-audmux.c | |||
@@ -74,9 +74,6 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf, | |||
74 | if (!buf) | 74 | if (!buf) |
75 | return -ENOMEM; | 75 | return -ENOMEM; |
76 | 76 | ||
77 | if (!audmux_base) | ||
78 | return -ENOSYS; | ||
79 | |||
80 | if (audmux_clk) | 77 | if (audmux_clk) |
81 | clk_prepare_enable(audmux_clk); | 78 | clk_prepare_enable(audmux_clk); |
82 | 79 | ||
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c index 48f9d886f020..9a15bc4bd570 100644 --- a/sound/soc/fsl/imx-pcm-dma.c +++ b/sound/soc/fsl/imx-pcm-dma.c | |||
@@ -109,6 +109,9 @@ static int snd_imx_open(struct snd_pcm_substream *substream) | |||
109 | dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | 109 | dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
110 | 110 | ||
111 | dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL); | 111 | dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL); |
112 | if (!dma_data) | ||
113 | return -ENOMEM; | ||
114 | |||
112 | dma_data->peripheral_type = dma_params->shared_peripheral ? | 115 | dma_data->peripheral_type = dma_params->shared_peripheral ? |
113 | IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI; | 116 | IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI; |
114 | dma_data->priority = DMA_PRIO_HIGH; | 117 | dma_data->priority = DMA_PRIO_HIGH; |
@@ -117,7 +120,7 @@ static int snd_imx_open(struct snd_pcm_substream *substream) | |||
117 | ret = snd_dmaengine_pcm_open(substream, filter, dma_data); | 120 | ret = snd_dmaengine_pcm_open(substream, filter, dma_data); |
118 | if (ret) { | 121 | if (ret) { |
119 | kfree(dma_data); | 122 | kfree(dma_data); |
120 | return 0; | 123 | return ret; |
121 | } | 124 | } |
122 | 125 | ||
123 | snd_dmaengine_pcm_set_data(substream, dma_data); | 126 | snd_dmaengine_pcm_set_data(substream, dma_data); |
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index fb21b17f17f5..199408ec4261 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c | |||
@@ -94,7 +94,7 @@ static int __devinit imx_sgtl5000_probe(struct platform_device *pdev) | |||
94 | dev_err(&pdev->dev, "audmux internal port setup failed\n"); | 94 | dev_err(&pdev->dev, "audmux internal port setup failed\n"); |
95 | return ret; | 95 | return ret; |
96 | } | 96 | } |
97 | imx_audmux_v2_configure_port(ext_port, | 97 | ret = imx_audmux_v2_configure_port(ext_port, |
98 | IMX_AUDMUX_V2_PTCR_SYN, | 98 | IMX_AUDMUX_V2_PTCR_SYN, |
99 | IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)); | 99 | IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)); |
100 | if (ret) { | 100 | if (ret) { |
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index 81d7728cf67f..3c520c46fa4a 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c | |||
@@ -380,14 +380,13 @@ static int imx_ssi_dai_probe(struct snd_soc_dai *dai) | |||
380 | static struct snd_soc_dai_driver imx_ssi_dai = { | 380 | static struct snd_soc_dai_driver imx_ssi_dai = { |
381 | .probe = imx_ssi_dai_probe, | 381 | .probe = imx_ssi_dai_probe, |
382 | .playback = { | 382 | .playback = { |
383 | /* The SSI does not support monaural audio. */ | 383 | .channels_min = 1, |
384 | .channels_min = 2, | ||
385 | .channels_max = 2, | 384 | .channels_max = 2, |
386 | .rates = SNDRV_PCM_RATE_8000_96000, | 385 | .rates = SNDRV_PCM_RATE_8000_96000, |
387 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 386 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
388 | }, | 387 | }, |
389 | .capture = { | 388 | .capture = { |
390 | .channels_min = 2, | 389 | .channels_min = 1, |
391 | .channels_max = 2, | 390 | .channels_max = 2, |
392 | .rates = SNDRV_PCM_RATE_8000_96000, | 391 | .rates = SNDRV_PCM_RATE_8000_96000, |
393 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 392 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
@@ -524,7 +523,7 @@ static int imx_ssi_probe(struct platform_device *pdev) | |||
524 | int ret = 0; | 523 | int ret = 0; |
525 | struct snd_soc_dai_driver *dai; | 524 | struct snd_soc_dai_driver *dai; |
526 | 525 | ||
527 | ssi = kzalloc(sizeof(*ssi), GFP_KERNEL); | 526 | ssi = devm_kzalloc(&pdev->dev, sizeof(*ssi), GFP_KERNEL); |
528 | if (!ssi) | 527 | if (!ssi) |
529 | return -ENOMEM; | 528 | return -ENOMEM; |
530 | dev_set_drvdata(&pdev->dev, ssi); | 529 | dev_set_drvdata(&pdev->dev, ssi); |
@@ -537,7 +536,7 @@ static int imx_ssi_probe(struct platform_device *pdev) | |||
537 | 536 | ||
538 | ssi->irq = platform_get_irq(pdev, 0); | 537 | ssi->irq = platform_get_irq(pdev, 0); |
539 | 538 | ||
540 | ssi->clk = clk_get(&pdev->dev, NULL); | 539 | ssi->clk = devm_clk_get(&pdev->dev, NULL); |
541 | if (IS_ERR(ssi->clk)) { | 540 | if (IS_ERR(ssi->clk)) { |
542 | ret = PTR_ERR(ssi->clk); | 541 | ret = PTR_ERR(ssi->clk); |
543 | dev_err(&pdev->dev, "Cannot get the clock: %d\n", | 542 | dev_err(&pdev->dev, "Cannot get the clock: %d\n", |
@@ -552,23 +551,18 @@ static int imx_ssi_probe(struct platform_device *pdev) | |||
552 | goto failed_get_resource; | 551 | goto failed_get_resource; |
553 | } | 552 | } |
554 | 553 | ||
555 | if (!request_mem_region(res->start, resource_size(res), DRV_NAME)) { | 554 | ssi->base = devm_request_and_ioremap(&pdev->dev, res); |
556 | dev_err(&pdev->dev, "request_mem_region failed\n"); | ||
557 | ret = -EBUSY; | ||
558 | goto failed_get_resource; | ||
559 | } | ||
560 | |||
561 | ssi->base = ioremap(res->start, resource_size(res)); | ||
562 | if (!ssi->base) { | 555 | if (!ssi->base) { |
563 | dev_err(&pdev->dev, "ioremap failed\n"); | 556 | dev_err(&pdev->dev, "ioremap failed\n"); |
564 | ret = -ENODEV; | 557 | ret = -ENODEV; |
565 | goto failed_ioremap; | 558 | goto failed_register; |
566 | } | 559 | } |
567 | 560 | ||
568 | if (ssi->flags & IMX_SSI_USE_AC97) { | 561 | if (ssi->flags & IMX_SSI_USE_AC97) { |
569 | if (ac97_ssi) { | 562 | if (ac97_ssi) { |
563 | dev_err(&pdev->dev, "AC'97 SSI already registered\n"); | ||
570 | ret = -EBUSY; | 564 | ret = -EBUSY; |
571 | goto failed_ac97; | 565 | goto failed_register; |
572 | } | 566 | } |
573 | ac97_ssi = ssi; | 567 | ac97_ssi = ssi; |
574 | setup_channel_to_ac97(ssi); | 568 | setup_channel_to_ac97(ssi); |
@@ -637,15 +631,10 @@ failed_pdev_fiq_add: | |||
637 | failed_pdev_fiq_alloc: | 631 | failed_pdev_fiq_alloc: |
638 | snd_soc_unregister_dai(&pdev->dev); | 632 | snd_soc_unregister_dai(&pdev->dev); |
639 | failed_register: | 633 | failed_register: |
640 | failed_ac97: | ||
641 | iounmap(ssi->base); | ||
642 | failed_ioremap: | ||
643 | release_mem_region(res->start, resource_size(res)); | 634 | release_mem_region(res->start, resource_size(res)); |
644 | failed_get_resource: | 635 | failed_get_resource: |
645 | clk_disable_unprepare(ssi->clk); | 636 | clk_disable_unprepare(ssi->clk); |
646 | clk_put(ssi->clk); | ||
647 | failed_clk: | 637 | failed_clk: |
648 | kfree(ssi); | ||
649 | 638 | ||
650 | return ret; | 639 | return ret; |
651 | } | 640 | } |
@@ -663,11 +652,8 @@ static int __devexit imx_ssi_remove(struct platform_device *pdev) | |||
663 | if (ssi->flags & IMX_SSI_USE_AC97) | 652 | if (ssi->flags & IMX_SSI_USE_AC97) |
664 | ac97_ssi = NULL; | 653 | ac97_ssi = NULL; |
665 | 654 | ||
666 | iounmap(ssi->base); | ||
667 | release_mem_region(res->start, resource_size(res)); | 655 | release_mem_region(res->start, resource_size(res)); |
668 | clk_disable_unprepare(ssi->clk); | 656 | clk_disable_unprepare(ssi->clk); |
669 | clk_put(ssi->clk); | ||
670 | kfree(ssi); | ||
671 | 657 | ||
672 | return 0; | 658 | return 0; |
673 | } | 659 | } |
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index 9a3f7c5ab687..9997c039bb24 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c | |||
@@ -370,7 +370,7 @@ static struct snd_soc_platform_driver mpc5200_audio_dma_platform = { | |||
370 | .pcm_free = &psc_dma_free, | 370 | .pcm_free = &psc_dma_free, |
371 | }; | 371 | }; |
372 | 372 | ||
373 | static int mpc5200_hpcd_probe(struct platform_device *op) | 373 | int mpc5200_audio_dma_create(struct platform_device *op) |
374 | { | 374 | { |
375 | phys_addr_t fifo; | 375 | phys_addr_t fifo; |
376 | struct psc_dma *psc_dma; | 376 | struct psc_dma *psc_dma; |
@@ -487,8 +487,9 @@ out_unmap: | |||
487 | iounmap(regs); | 487 | iounmap(regs); |
488 | return ret; | 488 | return ret; |
489 | } | 489 | } |
490 | EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create); | ||
490 | 491 | ||
491 | static int mpc5200_hpcd_remove(struct platform_device *op) | 492 | int mpc5200_audio_dma_destroy(struct platform_device *op) |
492 | { | 493 | { |
493 | struct psc_dma *psc_dma = dev_get_drvdata(&op->dev); | 494 | struct psc_dma *psc_dma = dev_get_drvdata(&op->dev); |
494 | 495 | ||
@@ -510,24 +511,7 @@ static int mpc5200_hpcd_remove(struct platform_device *op) | |||
510 | 511 | ||
511 | return 0; | 512 | return 0; |
512 | } | 513 | } |
513 | 514 | EXPORT_SYMBOL_GPL(mpc5200_audio_dma_destroy); | |
514 | static struct of_device_id mpc5200_hpcd_match[] = { | ||
515 | { .compatible = "fsl,mpc5200-pcm", }, | ||
516 | {} | ||
517 | }; | ||
518 | MODULE_DEVICE_TABLE(of, mpc5200_hpcd_match); | ||
519 | |||
520 | static struct platform_driver mpc5200_hpcd_of_driver = { | ||
521 | .probe = mpc5200_hpcd_probe, | ||
522 | .remove = mpc5200_hpcd_remove, | ||
523 | .driver = { | ||
524 | .owner = THIS_MODULE, | ||
525 | .name = "mpc5200-pcm-audio", | ||
526 | .of_match_table = mpc5200_hpcd_match, | ||
527 | } | ||
528 | }; | ||
529 | |||
530 | module_platform_driver(mpc5200_hpcd_of_driver); | ||
531 | 515 | ||
532 | MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>"); | 516 | MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>"); |
533 | MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver"); | 517 | MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver"); |
diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h index a3c0cd5382fb..dff253fde29a 100644 --- a/sound/soc/fsl/mpc5200_dma.h +++ b/sound/soc/fsl/mpc5200_dma.h | |||
@@ -81,4 +81,7 @@ to_psc_dma_stream(struct snd_pcm_substream *substream, struct psc_dma *psc_dma) | |||
81 | return &psc_dma->playback; | 81 | return &psc_dma->playback; |
82 | } | 82 | } |
83 | 83 | ||
84 | int mpc5200_audio_dma_create(struct platform_device *op); | ||
85 | int mpc5200_audio_dma_destroy(struct platform_device *op); | ||
86 | |||
84 | #endif /* __SOUND_SOC_FSL_MPC5200_DMA_H__ */ | 87 | #endif /* __SOUND_SOC_FSL_MPC5200_DMA_H__ */ |
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index ffa00a2eb770..a313c0ae36db 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c | |||
@@ -237,15 +237,18 @@ static const struct snd_soc_dai_ops psc_ac97_digital_ops = { | |||
237 | 237 | ||
238 | static struct snd_soc_dai_driver psc_ac97_dai[] = { | 238 | static struct snd_soc_dai_driver psc_ac97_dai[] = { |
239 | { | 239 | { |
240 | .name = "mpc5200-psc-ac97.0", | ||
240 | .ac97_control = 1, | 241 | .ac97_control = 1, |
241 | .probe = psc_ac97_probe, | 242 | .probe = psc_ac97_probe, |
242 | .playback = { | 243 | .playback = { |
244 | .stream_name = "AC97 Playback", | ||
243 | .channels_min = 1, | 245 | .channels_min = 1, |
244 | .channels_max = 6, | 246 | .channels_max = 6, |
245 | .rates = SNDRV_PCM_RATE_8000_48000, | 247 | .rates = SNDRV_PCM_RATE_8000_48000, |
246 | .formats = SNDRV_PCM_FMTBIT_S32_BE, | 248 | .formats = SNDRV_PCM_FMTBIT_S32_BE, |
247 | }, | 249 | }, |
248 | .capture = { | 250 | .capture = { |
251 | .stream_name = "AC97 Capture", | ||
249 | .channels_min = 1, | 252 | .channels_min = 1, |
250 | .channels_max = 2, | 253 | .channels_max = 2, |
251 | .rates = SNDRV_PCM_RATE_8000_48000, | 254 | .rates = SNDRV_PCM_RATE_8000_48000, |
@@ -254,8 +257,10 @@ static struct snd_soc_dai_driver psc_ac97_dai[] = { | |||
254 | .ops = &psc_ac97_analog_ops, | 257 | .ops = &psc_ac97_analog_ops, |
255 | }, | 258 | }, |
256 | { | 259 | { |
260 | .name = "mpc5200-psc-ac97.1", | ||
257 | .ac97_control = 1, | 261 | .ac97_control = 1, |
258 | .playback = { | 262 | .playback = { |
263 | .stream_name = "AC97 SPDIF", | ||
259 | .channels_min = 1, | 264 | .channels_min = 1, |
260 | .channels_max = 2, | 265 | .channels_max = 2, |
261 | .rates = SNDRV_PCM_RATE_32000 | \ | 266 | .rates = SNDRV_PCM_RATE_32000 | \ |
@@ -278,6 +283,10 @@ static int __devinit psc_ac97_of_probe(struct platform_device *op) | |||
278 | struct snd_ac97 ac97; | 283 | struct snd_ac97 ac97; |
279 | struct mpc52xx_psc __iomem *regs; | 284 | struct mpc52xx_psc __iomem *regs; |
280 | 285 | ||
286 | rc = mpc5200_audio_dma_create(op); | ||
287 | if (rc != 0) | ||
288 | return rc; | ||
289 | |||
281 | rc = snd_soc_register_dais(&op->dev, psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai)); | 290 | rc = snd_soc_register_dais(&op->dev, psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai)); |
282 | if (rc != 0) { | 291 | if (rc != 0) { |
283 | dev_err(&op->dev, "Failed to register DAI\n"); | 292 | dev_err(&op->dev, "Failed to register DAI\n"); |
@@ -303,6 +312,7 @@ static int __devinit psc_ac97_of_probe(struct platform_device *op) | |||
303 | 312 | ||
304 | static int __devexit psc_ac97_of_remove(struct platform_device *op) | 313 | static int __devexit psc_ac97_of_remove(struct platform_device *op) |
305 | { | 314 | { |
315 | mpc5200_audio_dma_destroy(op); | ||
306 | snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_ac97_dai)); | 316 | snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_ac97_dai)); |
307 | return 0; | 317 | return 0; |
308 | } | 318 | } |
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index 7b530327553a..ba1f0a66358f 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c | |||
@@ -130,13 +130,16 @@ static const struct snd_soc_dai_ops psc_i2s_dai_ops = { | |||
130 | }; | 130 | }; |
131 | 131 | ||
132 | static struct snd_soc_dai_driver psc_i2s_dai[] = {{ | 132 | static struct snd_soc_dai_driver psc_i2s_dai[] = {{ |
133 | .name = "mpc5200-psc-i2s.0", | ||
133 | .playback = { | 134 | .playback = { |
135 | .stream_name = "I2S Playback", | ||
134 | .channels_min = 2, | 136 | .channels_min = 2, |
135 | .channels_max = 2, | 137 | .channels_max = 2, |
136 | .rates = PSC_I2S_RATES, | 138 | .rates = PSC_I2S_RATES, |
137 | .formats = PSC_I2S_FORMATS, | 139 | .formats = PSC_I2S_FORMATS, |
138 | }, | 140 | }, |
139 | .capture = { | 141 | .capture = { |
142 | .stream_name = "I2S Capture", | ||
140 | .channels_min = 2, | 143 | .channels_min = 2, |
141 | .channels_max = 2, | 144 | .channels_max = 2, |
142 | .rates = PSC_I2S_RATES, | 145 | .rates = PSC_I2S_RATES, |
@@ -156,6 +159,10 @@ static int __devinit psc_i2s_of_probe(struct platform_device *op) | |||
156 | struct psc_dma *psc_dma; | 159 | struct psc_dma *psc_dma; |
157 | struct mpc52xx_psc __iomem *regs; | 160 | struct mpc52xx_psc __iomem *regs; |
158 | 161 | ||
162 | rc = mpc5200_audio_dma_create(op); | ||
163 | if (rc != 0) | ||
164 | return rc; | ||
165 | |||
159 | rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai)); | 166 | rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai)); |
160 | if (rc != 0) { | 167 | if (rc != 0) { |
161 | pr_err("Failed to register DAI\n"); | 168 | pr_err("Failed to register DAI\n"); |
@@ -200,6 +207,7 @@ static int __devinit psc_i2s_of_probe(struct platform_device *op) | |||
200 | 207 | ||
201 | static int __devexit psc_i2s_of_remove(struct platform_device *op) | 208 | static int __devexit psc_i2s_of_remove(struct platform_device *op) |
202 | { | 209 | { |
210 | mpc5200_audio_dma_destroy(op); | ||
203 | snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_i2s_dai)); | 211 | snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_i2s_dai)); |
204 | return 0; | 212 | return 0; |
205 | } | 213 | } |
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index 60bcba1bc30e..9ff9318c52b9 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c | |||
@@ -192,7 +192,6 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev) | |||
192 | container_of(dev, struct platform_device, dev); | 192 | container_of(dev, struct platform_device, dev); |
193 | struct device_node *np = ssi_pdev->dev.of_node; | 193 | struct device_node *np = ssi_pdev->dev.of_node; |
194 | struct device_node *codec_np = NULL; | 194 | struct device_node *codec_np = NULL; |
195 | struct platform_device *sound_device = NULL; | ||
196 | struct mpc8610_hpcd_data *machine_data; | 195 | struct mpc8610_hpcd_data *machine_data; |
197 | int ret = -ENODEV; | 196 | int ret = -ENODEV; |
198 | const char *sprop; | 197 | const char *sprop; |
@@ -341,34 +340,22 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev) | |||
341 | machine_data->card.probe = mpc8610_hpcd_machine_probe; | 340 | machine_data->card.probe = mpc8610_hpcd_machine_probe; |
342 | machine_data->card.remove = mpc8610_hpcd_machine_remove; | 341 | machine_data->card.remove = mpc8610_hpcd_machine_remove; |
343 | machine_data->card.name = pdev->name; /* The platform driver name */ | 342 | machine_data->card.name = pdev->name; /* The platform driver name */ |
343 | machine_data->card.owner = THIS_MODULE; | ||
344 | machine_data->card.dev = &pdev->dev; | ||
344 | machine_data->card.num_links = 2; | 345 | machine_data->card.num_links = 2; |
345 | machine_data->card.dai_link = machine_data->dai; | 346 | machine_data->card.dai_link = machine_data->dai; |
346 | 347 | ||
347 | /* Allocate a new audio platform device structure */ | ||
348 | sound_device = platform_device_alloc("soc-audio", -1); | ||
349 | if (!sound_device) { | ||
350 | dev_err(&pdev->dev, "platform device alloc failed\n"); | ||
351 | ret = -ENOMEM; | ||
352 | goto error; | ||
353 | } | ||
354 | |||
355 | /* Associate the card data with the sound device */ | ||
356 | platform_set_drvdata(sound_device, &machine_data->card); | ||
357 | |||
358 | /* Register with ASoC */ | 348 | /* Register with ASoC */ |
359 | ret = platform_device_add(sound_device); | 349 | ret = snd_soc_register_card(&machine_data->card); |
360 | if (ret) { | 350 | if (ret) { |
361 | dev_err(&pdev->dev, "platform device add failed\n"); | 351 | dev_err(&pdev->dev, "could not register card\n"); |
362 | goto error_sound; | 352 | goto error; |
363 | } | 353 | } |
364 | dev_set_drvdata(&pdev->dev, sound_device); | ||
365 | 354 | ||
366 | of_node_put(codec_np); | 355 | of_node_put(codec_np); |
367 | 356 | ||
368 | return 0; | 357 | return 0; |
369 | 358 | ||
370 | error_sound: | ||
371 | platform_device_put(sound_device); | ||
372 | error: | 359 | error: |
373 | kfree(machine_data); | 360 | kfree(machine_data); |
374 | error_alloc: | 361 | error_alloc: |
@@ -383,17 +370,12 @@ error_alloc: | |||
383 | */ | 370 | */ |
384 | static int __devexit mpc8610_hpcd_remove(struct platform_device *pdev) | 371 | static int __devexit mpc8610_hpcd_remove(struct platform_device *pdev) |
385 | { | 372 | { |
386 | struct platform_device *sound_device = dev_get_drvdata(&pdev->dev); | 373 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
387 | struct snd_soc_card *card = platform_get_drvdata(sound_device); | ||
388 | struct mpc8610_hpcd_data *machine_data = | 374 | struct mpc8610_hpcd_data *machine_data = |
389 | container_of(card, struct mpc8610_hpcd_data, card); | 375 | container_of(card, struct mpc8610_hpcd_data, card); |
390 | 376 | ||
391 | platform_device_unregister(sound_device); | 377 | snd_soc_unregister_card(card); |
392 | |||
393 | kfree(machine_data); | 378 | kfree(machine_data); |
394 | sound_device->dev.platform_data = NULL; | ||
395 | |||
396 | dev_set_drvdata(&pdev->dev, NULL); | ||
397 | 379 | ||
398 | return 0; | 380 | return 0; |
399 | } | 381 | } |
diff --git a/sound/soc/fsl/mx27vis-aic32x4.c b/sound/soc/fsl/mx27vis-aic32x4.c index f6d04ad4bb39..2b76877b1789 100644 --- a/sound/soc/fsl/mx27vis-aic32x4.c +++ b/sound/soc/fsl/mx27vis-aic32x4.c | |||
@@ -26,13 +26,13 @@ | |||
26 | #include <linux/device.h> | 26 | #include <linux/device.h> |
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
29 | #include <linux/platform_data/asoc-mx27vis.h> | ||
29 | #include <sound/core.h> | 30 | #include <sound/core.h> |
30 | #include <sound/pcm.h> | 31 | #include <sound/pcm.h> |
31 | #include <sound/soc.h> | 32 | #include <sound/soc.h> |
32 | #include <sound/soc-dapm.h> | 33 | #include <sound/soc-dapm.h> |
33 | #include <sound/tlv.h> | 34 | #include <sound/tlv.h> |
34 | #include <asm/mach-types.h> | 35 | #include <asm/mach-types.h> |
35 | #include <mach/iomux-mx27.h> | ||
36 | 36 | ||
37 | #include "../codecs/tlv320aic32x4.h" | 37 | #include "../codecs/tlv320aic32x4.h" |
38 | #include "imx-ssi.h" | 38 | #include "imx-ssi.h" |
@@ -41,20 +41,12 @@ | |||
41 | #define MX27VIS_AMP_GAIN 0 | 41 | #define MX27VIS_AMP_GAIN 0 |
42 | #define MX27VIS_AMP_MUTE 1 | 42 | #define MX27VIS_AMP_MUTE 1 |
43 | 43 | ||
44 | #define MX27VIS_PIN_G0 (GPIO_PORTF + 9) | ||
45 | #define MX27VIS_PIN_G1 (GPIO_PORTF + 8) | ||
46 | #define MX27VIS_PIN_SDL (GPIO_PORTE + 5) | ||
47 | #define MX27VIS_PIN_SDR (GPIO_PORTF + 7) | ||
48 | |||
49 | static int mx27vis_amp_gain; | 44 | static int mx27vis_amp_gain; |
50 | static int mx27vis_amp_mute; | 45 | static int mx27vis_amp_mute; |
51 | 46 | static int mx27vis_amp_gain0_gpio; | |
52 | static const int mx27vis_amp_pins[] = { | 47 | static int mx27vis_amp_gain1_gpio; |
53 | MX27VIS_PIN_G0 | GPIO_GPIO | GPIO_OUT, | 48 | static int mx27vis_amp_mutel_gpio; |
54 | MX27VIS_PIN_G1 | GPIO_GPIO | GPIO_OUT, | 49 | static int mx27vis_amp_muter_gpio; |
55 | MX27VIS_PIN_SDL | GPIO_GPIO | GPIO_OUT, | ||
56 | MX27VIS_PIN_SDR | GPIO_GPIO | GPIO_OUT, | ||
57 | }; | ||
58 | 50 | ||
59 | static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream, | 51 | static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream, |
60 | struct snd_pcm_hw_params *params) | 52 | struct snd_pcm_hw_params *params) |
@@ -109,13 +101,13 @@ static int mx27vis_amp_set(struct snd_kcontrol *kcontrol, | |||
109 | 101 | ||
110 | switch (reg) { | 102 | switch (reg) { |
111 | case MX27VIS_AMP_GAIN: | 103 | case MX27VIS_AMP_GAIN: |
112 | gpio_set_value(MX27VIS_PIN_G0, value & 1); | 104 | gpio_set_value(mx27vis_amp_gain0_gpio, value & 1); |
113 | gpio_set_value(MX27VIS_PIN_G1, value >> 1); | 105 | gpio_set_value(mx27vis_amp_gain1_gpio, value >> 1); |
114 | mx27vis_amp_gain = value; | 106 | mx27vis_amp_gain = value; |
115 | break; | 107 | break; |
116 | case MX27VIS_AMP_MUTE: | 108 | case MX27VIS_AMP_MUTE: |
117 | gpio_set_value(MX27VIS_PIN_SDL, value & 1); | 109 | gpio_set_value(mx27vis_amp_mutel_gpio, value & 1); |
118 | gpio_set_value(MX27VIS_PIN_SDR, value >> 1); | 110 | gpio_set_value(mx27vis_amp_muter_gpio, value >> 1); |
119 | mx27vis_amp_mute = value; | 111 | mx27vis_amp_mute = value; |
120 | break; | 112 | break; |
121 | } | 113 | } |
@@ -190,8 +182,19 @@ static struct snd_soc_card mx27vis_aic32x4 = { | |||
190 | 182 | ||
191 | static int __devinit mx27vis_aic32x4_probe(struct platform_device *pdev) | 183 | static int __devinit mx27vis_aic32x4_probe(struct platform_device *pdev) |
192 | { | 184 | { |
185 | struct snd_mx27vis_platform_data *pdata = pdev->dev.platform_data; | ||
193 | int ret; | 186 | int ret; |
194 | 187 | ||
188 | if (!pdata) { | ||
189 | dev_err(&pdev->dev, "No platform data supplied\n"); | ||
190 | return -EINVAL; | ||
191 | } | ||
192 | |||
193 | mx27vis_amp_gain0_gpio = pdata->amp_gain0_gpio; | ||
194 | mx27vis_amp_gain1_gpio = pdata->amp_gain1_gpio; | ||
195 | mx27vis_amp_mutel_gpio = pdata->amp_mutel_gpio; | ||
196 | mx27vis_amp_muter_gpio = pdata->amp_muter_gpio; | ||
197 | |||
195 | mx27vis_aic32x4.dev = &pdev->dev; | 198 | mx27vis_aic32x4.dev = &pdev->dev; |
196 | ret = snd_soc_register_card(&mx27vis_aic32x4); | 199 | ret = snd_soc_register_card(&mx27vis_aic32x4); |
197 | if (ret) { | 200 | if (ret) { |
@@ -213,11 +216,6 @@ static int __devinit mx27vis_aic32x4_probe(struct platform_device *pdev) | |||
213 | IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0) | 216 | IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0) |
214 | ); | 217 | ); |
215 | 218 | ||
216 | ret = mxc_gpio_setup_multiple_pins(mx27vis_amp_pins, | ||
217 | ARRAY_SIZE(mx27vis_amp_pins), "MX27VIS_AMP"); | ||
218 | if (ret) | ||
219 | printk(KERN_ERR "ASoC: unable to setup gpios\n"); | ||
220 | |||
221 | return ret; | 219 | return ret; |
222 | } | 220 | } |
223 | 221 | ||
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c index 50adf4032bcc..144d49603637 100644 --- a/sound/soc/fsl/p1022_ds.c +++ b/sound/soc/fsl/p1022_ds.c | |||
@@ -202,7 +202,6 @@ static int p1022_ds_probe(struct platform_device *pdev) | |||
202 | container_of(dev, struct platform_device, dev); | 202 | container_of(dev, struct platform_device, dev); |
203 | struct device_node *np = ssi_pdev->dev.of_node; | 203 | struct device_node *np = ssi_pdev->dev.of_node; |
204 | struct device_node *codec_np = NULL; | 204 | struct device_node *codec_np = NULL; |
205 | struct platform_device *sound_device = NULL; | ||
206 | struct machine_data *mdata; | 205 | struct machine_data *mdata; |
207 | int ret = -ENODEV; | 206 | int ret = -ENODEV; |
208 | const char *sprop; | 207 | const char *sprop; |
@@ -349,36 +348,23 @@ static int p1022_ds_probe(struct platform_device *pdev) | |||
349 | mdata->card.probe = p1022_ds_machine_probe; | 348 | mdata->card.probe = p1022_ds_machine_probe; |
350 | mdata->card.remove = p1022_ds_machine_remove; | 349 | mdata->card.remove = p1022_ds_machine_remove; |
351 | mdata->card.name = pdev->name; /* The platform driver name */ | 350 | mdata->card.name = pdev->name; /* The platform driver name */ |
351 | mdata->card.owner = THIS_MODULE; | ||
352 | mdata->card.dev = &pdev->dev; | ||
352 | mdata->card.num_links = 2; | 353 | mdata->card.num_links = 2; |
353 | mdata->card.dai_link = mdata->dai; | 354 | mdata->card.dai_link = mdata->dai; |
354 | 355 | ||
355 | /* Allocate a new audio platform device structure */ | ||
356 | sound_device = platform_device_alloc("soc-audio", -1); | ||
357 | if (!sound_device) { | ||
358 | dev_err(&pdev->dev, "platform device alloc failed\n"); | ||
359 | ret = -ENOMEM; | ||
360 | goto error; | ||
361 | } | ||
362 | |||
363 | /* Associate the card data with the sound device */ | ||
364 | platform_set_drvdata(sound_device, &mdata->card); | ||
365 | |||
366 | /* Register with ASoC */ | 356 | /* Register with ASoC */ |
367 | ret = platform_device_add(sound_device); | 357 | ret = snd_soc_register_card(&mdata->card); |
368 | if (ret) { | 358 | if (ret) { |
369 | dev_err(&pdev->dev, "platform device add failed\n"); | 359 | dev_err(&pdev->dev, "could not register card\n"); |
370 | goto error; | 360 | goto error; |
371 | } | 361 | } |
372 | dev_set_drvdata(&pdev->dev, sound_device); | ||
373 | 362 | ||
374 | of_node_put(codec_np); | 363 | of_node_put(codec_np); |
375 | 364 | ||
376 | return 0; | 365 | return 0; |
377 | 366 | ||
378 | error: | 367 | error: |
379 | if (sound_device) | ||
380 | platform_device_put(sound_device); | ||
381 | |||
382 | kfree(mdata); | 368 | kfree(mdata); |
383 | error_put: | 369 | error_put: |
384 | of_node_put(codec_np); | 370 | of_node_put(codec_np); |
@@ -392,17 +378,12 @@ error_put: | |||
392 | */ | 378 | */ |
393 | static int __devexit p1022_ds_remove(struct platform_device *pdev) | 379 | static int __devexit p1022_ds_remove(struct platform_device *pdev) |
394 | { | 380 | { |
395 | struct platform_device *sound_device = dev_get_drvdata(&pdev->dev); | 381 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
396 | struct snd_soc_card *card = platform_get_drvdata(sound_device); | ||
397 | struct machine_data *mdata = | 382 | struct machine_data *mdata = |
398 | container_of(card, struct machine_data, card); | 383 | container_of(card, struct machine_data, card); |
399 | 384 | ||
400 | platform_device_unregister(sound_device); | 385 | snd_soc_unregister_card(card); |
401 | |||
402 | kfree(mdata); | 386 | kfree(mdata); |
403 | sound_device->dev.platform_data = NULL; | ||
404 | |||
405 | dev_set_drvdata(&pdev->dev, NULL); | ||
406 | 387 | ||
407 | return 0; | 388 | return 0; |
408 | } | 389 | } |
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c index b3af55dcde9d..4b63ec8eb372 100644 --- a/sound/soc/fsl/pcm030-audio-fabric.c +++ b/sound/soc/fsl/pcm030-audio-fabric.c | |||
@@ -12,32 +12,27 @@ | |||
12 | 12 | ||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/device.h> | 15 | #include <linux/device.h> |
17 | #include <linux/delay.h> | ||
18 | #include <linux/of_device.h> | 16 | #include <linux/of_device.h> |
19 | #include <linux/of_platform.h> | 17 | #include <linux/of_platform.h> |
20 | #include <linux/dma-mapping.h> | ||
21 | 18 | ||
22 | #include <sound/core.h> | ||
23 | #include <sound/pcm.h> | ||
24 | #include <sound/pcm_params.h> | ||
25 | #include <sound/initval.h> | ||
26 | #include <sound/soc.h> | 19 | #include <sound/soc.h> |
27 | 20 | ||
28 | #include "mpc5200_dma.h" | 21 | #include "mpc5200_dma.h" |
29 | #include "mpc5200_psc_ac97.h" | ||
30 | #include "../codecs/wm9712.h" | ||
31 | 22 | ||
32 | #define DRV_NAME "pcm030-audio-fabric" | 23 | #define DRV_NAME "pcm030-audio-fabric" |
33 | 24 | ||
25 | struct pcm030_audio_data { | ||
26 | struct snd_soc_card *card; | ||
27 | struct platform_device *codec_device; | ||
28 | }; | ||
29 | |||
34 | static struct snd_soc_dai_link pcm030_fabric_dai[] = { | 30 | static struct snd_soc_dai_link pcm030_fabric_dai[] = { |
35 | { | 31 | { |
36 | .name = "AC97", | 32 | .name = "AC97", |
37 | .stream_name = "AC97 Analog", | 33 | .stream_name = "AC97 Analog", |
38 | .codec_dai_name = "wm9712-hifi", | 34 | .codec_dai_name = "wm9712-hifi", |
39 | .cpu_dai_name = "mpc5200-psc-ac97.0", | 35 | .cpu_dai_name = "mpc5200-psc-ac97.0", |
40 | .platform_name = "mpc5200-pcm-audio", | ||
41 | .codec_name = "wm9712-codec", | 36 | .codec_name = "wm9712-codec", |
42 | }, | 37 | }, |
43 | { | 38 | { |
@@ -45,44 +40,95 @@ static struct snd_soc_dai_link pcm030_fabric_dai[] = { | |||
45 | .stream_name = "AC97 IEC958", | 40 | .stream_name = "AC97 IEC958", |
46 | .codec_dai_name = "wm9712-aux", | 41 | .codec_dai_name = "wm9712-aux", |
47 | .cpu_dai_name = "mpc5200-psc-ac97.1", | 42 | .cpu_dai_name = "mpc5200-psc-ac97.1", |
48 | .platform_name = "mpc5200-pcm-audio", | ||
49 | .codec_name = "wm9712-codec", | 43 | .codec_name = "wm9712-codec", |
50 | }, | 44 | }, |
51 | }; | 45 | }; |
52 | 46 | ||
53 | static struct snd_soc_card card = { | 47 | static struct snd_soc_card pcm030_card = { |
54 | .name = "pcm030", | 48 | .name = "pcm030", |
55 | .owner = THIS_MODULE, | 49 | .owner = THIS_MODULE, |
56 | .dai_link = pcm030_fabric_dai, | 50 | .dai_link = pcm030_fabric_dai, |
57 | .num_links = ARRAY_SIZE(pcm030_fabric_dai), | 51 | .num_links = ARRAY_SIZE(pcm030_fabric_dai), |
58 | }; | 52 | }; |
59 | 53 | ||
60 | static __init int pcm030_fabric_init(void) | 54 | static int __init pcm030_fabric_probe(struct platform_device *op) |
61 | { | 55 | { |
62 | struct platform_device *pdev; | 56 | struct device_node *np = op->dev.of_node; |
63 | int rc; | 57 | struct device_node *platform_np; |
58 | struct snd_soc_card *card = &pcm030_card; | ||
59 | struct pcm030_audio_data *pdata; | ||
60 | int ret; | ||
61 | int i; | ||
64 | 62 | ||
65 | if (!of_machine_is_compatible("phytec,pcm030")) | 63 | if (!of_machine_is_compatible("phytec,pcm030")) |
66 | return -ENODEV; | 64 | return -ENODEV; |
67 | 65 | ||
68 | pdev = platform_device_alloc("soc-audio", 1); | 66 | pdata = devm_kzalloc(&op->dev, sizeof(struct pcm030_audio_data), |
69 | if (!pdev) { | 67 | GFP_KERNEL); |
70 | pr_err("pcm030_fabric_init: platform_device_alloc() failed\n"); | 68 | if (!pdata) |
71 | return -ENODEV; | 69 | return -ENOMEM; |
72 | } | 70 | |
71 | card->dev = &op->dev; | ||
72 | platform_set_drvdata(op, pdata); | ||
73 | 73 | ||
74 | platform_set_drvdata(pdev, &card); | 74 | pdata->card = card; |
75 | 75 | ||
76 | rc = platform_device_add(pdev); | 76 | platform_np = of_parse_phandle(np, "asoc-platform", 0); |
77 | if (rc) { | 77 | if (!platform_np) { |
78 | pr_err("pcm030_fabric_init: platform_device_add() failed\n"); | 78 | dev_err(&op->dev, "ac97 not registered\n"); |
79 | platform_device_put(pdev); | ||
80 | return -ENODEV; | 79 | return -ENODEV; |
81 | } | 80 | } |
82 | return 0; | 81 | |
82 | for (i = 0; i < card->num_links; i++) | ||
83 | card->dai_link[i].platform_of_node = platform_np; | ||
84 | |||
85 | ret = request_module("snd-soc-wm9712"); | ||
86 | if (ret) | ||
87 | dev_err(&op->dev, "request_module returned: %d\n", ret); | ||
88 | |||
89 | pdata->codec_device = platform_device_alloc("wm9712-codec", -1); | ||
90 | if (!pdata->codec_device) | ||
91 | dev_err(&op->dev, "platform_device_alloc() failed\n"); | ||
92 | |||
93 | ret = platform_device_add(pdata->codec_device); | ||
94 | if (ret) | ||
95 | dev_err(&op->dev, "platform_device_add() failed: %d\n", ret); | ||
96 | |||
97 | ret = snd_soc_register_card(card); | ||
98 | if (ret) | ||
99 | dev_err(&op->dev, "snd_soc_register_card() failed: %d\n", ret); | ||
100 | |||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | static int __devexit pcm030_fabric_remove(struct platform_device *op) | ||
105 | { | ||
106 | struct pcm030_audio_data *pdata = platform_get_drvdata(op); | ||
107 | int ret; | ||
108 | |||
109 | ret = snd_soc_unregister_card(pdata->card); | ||
110 | platform_device_unregister(pdata->codec_device); | ||
111 | |||
112 | return ret; | ||
83 | } | 113 | } |
84 | 114 | ||
85 | module_init(pcm030_fabric_init); | 115 | static struct of_device_id pcm030_audio_match[] = { |
116 | { .compatible = "phytec,pcm030-audio-fabric", }, | ||
117 | {} | ||
118 | }; | ||
119 | MODULE_DEVICE_TABLE(of, pcm030_audio_match); | ||
120 | |||
121 | static struct platform_driver pcm030_fabric_driver = { | ||
122 | .probe = pcm030_fabric_probe, | ||
123 | .remove = __devexit_p(pcm030_fabric_remove), | ||
124 | .driver = { | ||
125 | .name = DRV_NAME, | ||
126 | .owner = THIS_MODULE, | ||
127 | .of_match_table = pcm030_audio_match, | ||
128 | }, | ||
129 | }; | ||
130 | |||
131 | module_platform_driver(pcm030_fabric_driver); | ||
86 | 132 | ||
87 | 133 | ||
88 | MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>"); | 134 | MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>"); |
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c index 2937e54da49e..2cc7782714b5 100644 --- a/sound/soc/mid-x86/mfld_machine.c +++ b/sound/soc/mid-x86/mfld_machine.c | |||
@@ -318,6 +318,15 @@ static struct snd_soc_dai_link mfld_msic_dailink[] = { | |||
318 | .platform_name = "sst-platform", | 318 | .platform_name = "sst-platform", |
319 | .init = NULL, | 319 | .init = NULL, |
320 | }, | 320 | }, |
321 | { | ||
322 | .name = "Medfield Compress", | ||
323 | .stream_name = "Speaker", | ||
324 | .cpu_dai_name = "Compress-cpu-dai", | ||
325 | .codec_dai_name = "SN95031 Speaker", | ||
326 | .codec_name = "sn95031", | ||
327 | .platform_name = "sst-platform", | ||
328 | .init = NULL, | ||
329 | }, | ||
321 | }; | 330 | }; |
322 | 331 | ||
323 | /* SoC card */ | 332 | /* SoC card */ |
diff --git a/sound/soc/mid-x86/sst_dsp.h b/sound/soc/mid-x86/sst_dsp.h new file mode 100644 index 000000000000..0fce1de284ff --- /dev/null +++ b/sound/soc/mid-x86/sst_dsp.h | |||
@@ -0,0 +1,134 @@ | |||
1 | #ifndef __SST_DSP_H__ | ||
2 | #define __SST_DSP_H__ | ||
3 | /* | ||
4 | * sst_dsp.h - Intel SST Driver for audio engine | ||
5 | * | ||
6 | * Copyright (C) 2008-12 Intel Corporation | ||
7 | * Authors: Vinod Koul <vinod.koul@linux.intel.com> | ||
8 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; version 2 of the License. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
22 | * | ||
23 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
24 | */ | ||
25 | |||
26 | enum sst_codec_types { | ||
27 | /* AUDIO/MUSIC CODEC Type Definitions */ | ||
28 | SST_CODEC_TYPE_UNKNOWN = 0, | ||
29 | SST_CODEC_TYPE_PCM, /* Pass through Audio codec */ | ||
30 | SST_CODEC_TYPE_MP3, | ||
31 | SST_CODEC_TYPE_MP24, | ||
32 | SST_CODEC_TYPE_AAC, | ||
33 | SST_CODEC_TYPE_AACP, | ||
34 | SST_CODEC_TYPE_eAACP, | ||
35 | }; | ||
36 | |||
37 | enum stream_type { | ||
38 | SST_STREAM_TYPE_NONE = 0, | ||
39 | SST_STREAM_TYPE_MUSIC = 1, | ||
40 | }; | ||
41 | |||
42 | struct snd_pcm_params { | ||
43 | u16 codec; /* codec type */ | ||
44 | u8 num_chan; /* 1=Mono, 2=Stereo */ | ||
45 | u8 pcm_wd_sz; /* 16/24 - bit*/ | ||
46 | u32 reserved; /* Bitrate in bits per second */ | ||
47 | u32 sfreq; /* Sampling rate in Hz */ | ||
48 | u8 use_offload_path; | ||
49 | u8 reserved2; | ||
50 | u16 reserved3; | ||
51 | u8 channel_map[8]; | ||
52 | } __packed; | ||
53 | |||
54 | /* MP3 Music Parameters Message */ | ||
55 | struct snd_mp3_params { | ||
56 | u16 codec; | ||
57 | u8 num_chan; /* 1=Mono, 2=Stereo */ | ||
58 | u8 pcm_wd_sz; /* 16/24 - bit*/ | ||
59 | u8 crc_check; /* crc_check - disable (0) or enable (1) */ | ||
60 | u8 reserved1; /* unused*/ | ||
61 | u16 reserved2; /* Unused */ | ||
62 | } __packed; | ||
63 | |||
64 | #define AAC_BIT_STREAM_ADTS 0 | ||
65 | #define AAC_BIT_STREAM_ADIF 1 | ||
66 | #define AAC_BIT_STREAM_RAW 2 | ||
67 | |||
68 | /* AAC Music Parameters Message */ | ||
69 | struct snd_aac_params { | ||
70 | u16 codec; | ||
71 | u8 num_chan; /* 1=Mono, 2=Stereo*/ | ||
72 | u8 pcm_wd_sz; /* 16/24 - bit*/ | ||
73 | u8 bdownsample; /*SBR downsampling 0 - disable 1 -enabled AAC+ only */ | ||
74 | u8 bs_format; /* input bit stream format adts=0, adif=1, raw=2 */ | ||
75 | u16 reser2; | ||
76 | u32 externalsr; /*sampling rate of basic AAC raw bit stream*/ | ||
77 | u8 sbr_signalling;/*disable/enable/set automode the SBR tool.AAC+*/ | ||
78 | u8 reser1; | ||
79 | u16 reser3; | ||
80 | } __packed; | ||
81 | |||
82 | /* WMA Music Parameters Message */ | ||
83 | struct snd_wma_params { | ||
84 | u16 codec; | ||
85 | u8 num_chan; /* 1=Mono, 2=Stereo */ | ||
86 | u8 pcm_wd_sz; /* 16/24 - bit*/ | ||
87 | u32 brate; /* Use the hard coded value. */ | ||
88 | u32 sfreq; /* Sampling freq eg. 8000, 441000, 48000 */ | ||
89 | u32 channel_mask; /* Channel Mask */ | ||
90 | u16 format_tag; /* Format Tag */ | ||
91 | u16 block_align; /* packet size */ | ||
92 | u16 wma_encode_opt;/* Encoder option */ | ||
93 | u8 op_align; /* op align 0- 16 bit, 1- MSB, 2 LSB */ | ||
94 | u8 reserved; /* reserved */ | ||
95 | } __packed; | ||
96 | |||
97 | /* Codec params struture */ | ||
98 | union snd_sst_codec_params { | ||
99 | struct snd_pcm_params pcm_params; | ||
100 | struct snd_mp3_params mp3_params; | ||
101 | struct snd_aac_params aac_params; | ||
102 | struct snd_wma_params wma_params; | ||
103 | } __packed; | ||
104 | |||
105 | /* Address and size info of a frame buffer */ | ||
106 | struct sst_address_info { | ||
107 | u32 addr; /* Address at IA */ | ||
108 | u32 size; /* Size of the buffer */ | ||
109 | }; | ||
110 | |||
111 | struct snd_sst_alloc_params_ext { | ||
112 | struct sst_address_info ring_buf_info[8]; | ||
113 | u8 sg_count; | ||
114 | u8 reserved; | ||
115 | u16 reserved2; | ||
116 | u32 frag_size; /*Number of samples after which period elapsed | ||
117 | message is sent valid only if path = 0*/ | ||
118 | } __packed; | ||
119 | |||
120 | struct snd_sst_stream_params { | ||
121 | union snd_sst_codec_params uc; | ||
122 | } __packed; | ||
123 | |||
124 | struct snd_sst_params { | ||
125 | u32 stream_id; | ||
126 | u8 codec; | ||
127 | u8 ops; | ||
128 | u8 stream_type; | ||
129 | u8 device_type; | ||
130 | struct snd_sst_stream_params sparams; | ||
131 | struct snd_sst_alloc_params_ext aparams; | ||
132 | }; | ||
133 | |||
134 | #endif /* __SST_DSP_H__ */ | ||
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index d34563b12c3b..a263cbed8624 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * sst_platform.c - Intel MID Platform driver | 2 | * sst_platform.c - Intel MID Platform driver |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Intel Corp | 4 | * Copyright (C) 2010-2012 Intel Corp |
5 | * Author: Vinod Koul <vinod.koul@intel.com> | 5 | * Author: Vinod Koul <vinod.koul@intel.com> |
6 | * Author: Harsha Priya <priya.harsha@intel.com> | 6 | * Author: Harsha Priya <priya.harsha@intel.com> |
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
@@ -32,6 +32,7 @@ | |||
32 | #include <sound/pcm.h> | 32 | #include <sound/pcm.h> |
33 | #include <sound/pcm_params.h> | 33 | #include <sound/pcm_params.h> |
34 | #include <sound/soc.h> | 34 | #include <sound/soc.h> |
35 | #include <sound/compress_driver.h> | ||
35 | #include "sst_platform.h" | 36 | #include "sst_platform.h" |
36 | 37 | ||
37 | static struct sst_device *sst; | 38 | static struct sst_device *sst; |
@@ -152,6 +153,16 @@ static struct snd_soc_dai_driver sst_platform_dai[] = { | |||
152 | .formats = SNDRV_PCM_FMTBIT_S24_LE, | 153 | .formats = SNDRV_PCM_FMTBIT_S24_LE, |
153 | }, | 154 | }, |
154 | }, | 155 | }, |
156 | { | ||
157 | .name = "Compress-cpu-dai", | ||
158 | .compress_dai = 1, | ||
159 | .playback = { | ||
160 | .channels_min = SST_STEREO, | ||
161 | .channels_max = SST_STEREO, | ||
162 | .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000, | ||
163 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
164 | }, | ||
165 | }, | ||
155 | }; | 166 | }; |
156 | 167 | ||
157 | /* helper functions */ | 168 | /* helper functions */ |
@@ -463,8 +474,199 @@ static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
463 | } | 474 | } |
464 | return retval; | 475 | return retval; |
465 | } | 476 | } |
477 | |||
478 | /* compress stream operations */ | ||
479 | static void sst_compr_fragment_elapsed(void *arg) | ||
480 | { | ||
481 | struct snd_compr_stream *cstream = (struct snd_compr_stream *)arg; | ||
482 | |||
483 | pr_debug("fragment elapsed by driver\n"); | ||
484 | if (cstream) | ||
485 | snd_compr_fragment_elapsed(cstream); | ||
486 | } | ||
487 | |||
488 | static int sst_platform_compr_open(struct snd_compr_stream *cstream) | ||
489 | { | ||
490 | |||
491 | int ret_val = 0; | ||
492 | struct snd_compr_runtime *runtime = cstream->runtime; | ||
493 | struct sst_runtime_stream *stream; | ||
494 | |||
495 | stream = kzalloc(sizeof(*stream), GFP_KERNEL); | ||
496 | if (!stream) | ||
497 | return -ENOMEM; | ||
498 | |||
499 | spin_lock_init(&stream->status_lock); | ||
500 | |||
501 | /* get the sst ops */ | ||
502 | if (!sst || !try_module_get(sst->dev->driver->owner)) { | ||
503 | pr_err("no device available to run\n"); | ||
504 | ret_val = -ENODEV; | ||
505 | goto out_ops; | ||
506 | } | ||
507 | stream->compr_ops = sst->compr_ops; | ||
508 | |||
509 | stream->id = 0; | ||
510 | sst_set_stream_status(stream, SST_PLATFORM_INIT); | ||
511 | runtime->private_data = stream; | ||
512 | return 0; | ||
513 | out_ops: | ||
514 | kfree(stream); | ||
515 | return ret_val; | ||
516 | } | ||
517 | |||
518 | static int sst_platform_compr_free(struct snd_compr_stream *cstream) | ||
519 | { | ||
520 | struct sst_runtime_stream *stream; | ||
521 | int ret_val = 0, str_id; | ||
522 | |||
523 | stream = cstream->runtime->private_data; | ||
524 | /*need to check*/ | ||
525 | str_id = stream->id; | ||
526 | if (str_id) | ||
527 | ret_val = stream->compr_ops->close(str_id); | ||
528 | module_put(sst->dev->driver->owner); | ||
529 | kfree(stream); | ||
530 | pr_debug("%s: %d\n", __func__, ret_val); | ||
531 | return 0; | ||
532 | } | ||
533 | |||
534 | static int sst_platform_compr_set_params(struct snd_compr_stream *cstream, | ||
535 | struct snd_compr_params *params) | ||
536 | { | ||
537 | struct sst_runtime_stream *stream; | ||
538 | int retval; | ||
539 | struct snd_sst_params str_params; | ||
540 | struct sst_compress_cb cb; | ||
541 | |||
542 | stream = cstream->runtime->private_data; | ||
543 | /* construct fw structure for this*/ | ||
544 | memset(&str_params, 0, sizeof(str_params)); | ||
545 | |||
546 | str_params.ops = STREAM_OPS_PLAYBACK; | ||
547 | str_params.stream_type = SST_STREAM_TYPE_MUSIC; | ||
548 | str_params.device_type = SND_SST_DEVICE_COMPRESS; | ||
549 | |||
550 | switch (params->codec.id) { | ||
551 | case SND_AUDIOCODEC_MP3: { | ||
552 | str_params.codec = SST_CODEC_TYPE_MP3; | ||
553 | str_params.sparams.uc.mp3_params.codec = SST_CODEC_TYPE_MP3; | ||
554 | str_params.sparams.uc.mp3_params.num_chan = params->codec.ch_in; | ||
555 | str_params.sparams.uc.mp3_params.pcm_wd_sz = 16; | ||
556 | break; | ||
557 | } | ||
558 | |||
559 | case SND_AUDIOCODEC_AAC: { | ||
560 | str_params.codec = SST_CODEC_TYPE_AAC; | ||
561 | str_params.sparams.uc.aac_params.codec = SST_CODEC_TYPE_AAC; | ||
562 | str_params.sparams.uc.aac_params.num_chan = params->codec.ch_in; | ||
563 | str_params.sparams.uc.aac_params.pcm_wd_sz = 16; | ||
564 | if (params->codec.format == SND_AUDIOSTREAMFORMAT_MP4ADTS) | ||
565 | str_params.sparams.uc.aac_params.bs_format = | ||
566 | AAC_BIT_STREAM_ADTS; | ||
567 | else if (params->codec.format == SND_AUDIOSTREAMFORMAT_RAW) | ||
568 | str_params.sparams.uc.aac_params.bs_format = | ||
569 | AAC_BIT_STREAM_RAW; | ||
570 | else { | ||
571 | pr_err("Undefined format%d\n", params->codec.format); | ||
572 | return -EINVAL; | ||
573 | } | ||
574 | str_params.sparams.uc.aac_params.externalsr = | ||
575 | params->codec.sample_rate; | ||
576 | break; | ||
577 | } | ||
578 | |||
579 | default: | ||
580 | pr_err("codec not supported, id =%d\n", params->codec.id); | ||
581 | return -EINVAL; | ||
582 | } | ||
583 | |||
584 | str_params.aparams.ring_buf_info[0].addr = | ||
585 | virt_to_phys(cstream->runtime->buffer); | ||
586 | str_params.aparams.ring_buf_info[0].size = | ||
587 | cstream->runtime->buffer_size; | ||
588 | str_params.aparams.sg_count = 1; | ||
589 | str_params.aparams.frag_size = cstream->runtime->fragment_size; | ||
590 | |||
591 | cb.param = cstream; | ||
592 | cb.compr_cb = sst_compr_fragment_elapsed; | ||
593 | |||
594 | retval = stream->compr_ops->open(&str_params, &cb); | ||
595 | if (retval < 0) { | ||
596 | pr_err("stream allocation failed %d\n", retval); | ||
597 | return retval; | ||
598 | } | ||
599 | |||
600 | stream->id = retval; | ||
601 | return 0; | ||
602 | } | ||
603 | |||
604 | static int sst_platform_compr_trigger(struct snd_compr_stream *cstream, int cmd) | ||
605 | { | ||
606 | struct sst_runtime_stream *stream = | ||
607 | cstream->runtime->private_data; | ||
608 | |||
609 | return stream->compr_ops->control(cmd, stream->id); | ||
610 | } | ||
611 | |||
612 | static int sst_platform_compr_pointer(struct snd_compr_stream *cstream, | ||
613 | struct snd_compr_tstamp *tstamp) | ||
614 | { | ||
615 | struct sst_runtime_stream *stream; | ||
616 | |||
617 | stream = cstream->runtime->private_data; | ||
618 | stream->compr_ops->tstamp(stream->id, tstamp); | ||
619 | tstamp->byte_offset = tstamp->copied_total % | ||
620 | (u32)cstream->runtime->buffer_size; | ||
621 | pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset); | ||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | static int sst_platform_compr_ack(struct snd_compr_stream *cstream, | ||
626 | size_t bytes) | ||
627 | { | ||
628 | struct sst_runtime_stream *stream; | ||
629 | |||
630 | stream = cstream->runtime->private_data; | ||
631 | stream->compr_ops->ack(stream->id, (unsigned long)bytes); | ||
632 | stream->bytes_written += bytes; | ||
633 | |||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | static int sst_platform_compr_get_caps(struct snd_compr_stream *cstream, | ||
638 | struct snd_compr_caps *caps) | ||
639 | { | ||
640 | struct sst_runtime_stream *stream = | ||
641 | cstream->runtime->private_data; | ||
642 | |||
643 | return stream->compr_ops->get_caps(caps); | ||
644 | } | ||
645 | |||
646 | static int sst_platform_compr_get_codec_caps(struct snd_compr_stream *cstream, | ||
647 | struct snd_compr_codec_caps *codec) | ||
648 | { | ||
649 | struct sst_runtime_stream *stream = | ||
650 | cstream->runtime->private_data; | ||
651 | |||
652 | return stream->compr_ops->get_codec_caps(codec); | ||
653 | } | ||
654 | |||
655 | static struct snd_compr_ops sst_platform_compr_ops = { | ||
656 | |||
657 | .open = sst_platform_compr_open, | ||
658 | .free = sst_platform_compr_free, | ||
659 | .set_params = sst_platform_compr_set_params, | ||
660 | .trigger = sst_platform_compr_trigger, | ||
661 | .pointer = sst_platform_compr_pointer, | ||
662 | .ack = sst_platform_compr_ack, | ||
663 | .get_caps = sst_platform_compr_get_caps, | ||
664 | .get_codec_caps = sst_platform_compr_get_codec_caps, | ||
665 | }; | ||
666 | |||
466 | static struct snd_soc_platform_driver sst_soc_platform_drv = { | 667 | static struct snd_soc_platform_driver sst_soc_platform_drv = { |
467 | .ops = &sst_platform_ops, | 668 | .ops = &sst_platform_ops, |
669 | .compr_ops = &sst_platform_compr_ops, | ||
468 | .pcm_new = sst_pcm_new, | 670 | .pcm_new = sst_pcm_new, |
469 | .pcm_free = sst_pcm_free, | 671 | .pcm_free = sst_pcm_free, |
470 | }; | 672 | }; |
diff --git a/sound/soc/mid-x86/sst_platform.h b/sound/soc/mid-x86/sst_platform.h index f04f4f72daa0..d61c5d514ffa 100644 --- a/sound/soc/mid-x86/sst_platform.h +++ b/sound/soc/mid-x86/sst_platform.h | |||
@@ -27,6 +27,8 @@ | |||
27 | #ifndef __SST_PLATFORMDRV_H__ | 27 | #ifndef __SST_PLATFORMDRV_H__ |
28 | #define __SST_PLATFORMDRV_H__ | 28 | #define __SST_PLATFORMDRV_H__ |
29 | 29 | ||
30 | #include "sst_dsp.h" | ||
31 | |||
30 | #define SST_MONO 1 | 32 | #define SST_MONO 1 |
31 | #define SST_STEREO 2 | 33 | #define SST_STEREO 2 |
32 | #define SST_MAX_CAP 5 | 34 | #define SST_MAX_CAP 5 |
@@ -42,7 +44,6 @@ | |||
42 | #define SST_MIN_PERIODS 2 | 44 | #define SST_MIN_PERIODS 2 |
43 | #define SST_MAX_PERIODS (1024*2) | 45 | #define SST_MAX_PERIODS (1024*2) |
44 | #define SST_FIFO_SIZE 0 | 46 | #define SST_FIFO_SIZE 0 |
45 | #define SST_CODEC_TYPE_PCM 1 | ||
46 | 47 | ||
47 | struct pcm_stream_info { | 48 | struct pcm_stream_info { |
48 | int str_id; | 49 | int str_id; |
@@ -83,6 +84,7 @@ enum sst_audio_device_type { | |||
83 | SND_SST_DEVICE_VIBRA, | 84 | SND_SST_DEVICE_VIBRA, |
84 | SND_SST_DEVICE_HAPTIC, | 85 | SND_SST_DEVICE_HAPTIC, |
85 | SND_SST_DEVICE_CAPTURE, | 86 | SND_SST_DEVICE_CAPTURE, |
87 | SND_SST_DEVICE_COMPRESS, | ||
86 | }; | 88 | }; |
87 | 89 | ||
88 | /* PCM Parameters */ | 90 | /* PCM Parameters */ |
@@ -107,6 +109,24 @@ struct sst_stream_params { | |||
107 | struct sst_pcm_params sparams; | 109 | struct sst_pcm_params sparams; |
108 | }; | 110 | }; |
109 | 111 | ||
112 | struct sst_compress_cb { | ||
113 | void *param; | ||
114 | void (*compr_cb)(void *param); | ||
115 | }; | ||
116 | |||
117 | struct compress_sst_ops { | ||
118 | const char *name; | ||
119 | int (*open) (struct snd_sst_params *str_params, | ||
120 | struct sst_compress_cb *cb); | ||
121 | int (*control) (unsigned int cmd, unsigned int str_id); | ||
122 | int (*tstamp) (unsigned int str_id, struct snd_compr_tstamp *tstamp); | ||
123 | int (*ack) (unsigned int str_id, unsigned long bytes); | ||
124 | int (*close) (unsigned int str_id); | ||
125 | int (*get_caps) (struct snd_compr_caps *caps); | ||
126 | int (*get_codec_caps) (struct snd_compr_codec_caps *codec); | ||
127 | |||
128 | }; | ||
129 | |||
110 | struct sst_ops { | 130 | struct sst_ops { |
111 | int (*open) (struct sst_stream_params *str_param); | 131 | int (*open) (struct sst_stream_params *str_param); |
112 | int (*device_control) (int cmd, void *arg); | 132 | int (*device_control) (int cmd, void *arg); |
@@ -115,8 +135,11 @@ struct sst_ops { | |||
115 | 135 | ||
116 | struct sst_runtime_stream { | 136 | struct sst_runtime_stream { |
117 | int stream_status; | 137 | int stream_status; |
138 | unsigned int id; | ||
139 | size_t bytes_written; | ||
118 | struct pcm_stream_info stream_info; | 140 | struct pcm_stream_info stream_info; |
119 | struct sst_ops *ops; | 141 | struct sst_ops *ops; |
142 | struct compress_sst_ops *compr_ops; | ||
120 | spinlock_t status_lock; | 143 | spinlock_t status_lock; |
121 | }; | 144 | }; |
122 | 145 | ||
@@ -124,6 +147,7 @@ struct sst_device { | |||
124 | char *name; | 147 | char *name; |
125 | struct device *dev; | 148 | struct device *dev; |
126 | struct sst_ops *ops; | 149 | struct sst_ops *ops; |
150 | struct compress_sst_ops *compr_ops; | ||
127 | }; | 151 | }; |
128 | 152 | ||
129 | int sst_register_dsp(struct sst_device *sst); | 153 | int sst_register_dsp(struct sst_device *sst); |
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index b3030718c228..aa037b292f3d 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c | |||
@@ -704,7 +704,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev) | |||
704 | return ret; | 704 | return ret; |
705 | } | 705 | } |
706 | 706 | ||
707 | saif->clk = clk_get(&pdev->dev, NULL); | 707 | saif->clk = devm_clk_get(&pdev->dev, NULL); |
708 | if (IS_ERR(saif->clk)) { | 708 | if (IS_ERR(saif->clk)) { |
709 | ret = PTR_ERR(saif->clk); | 709 | ret = PTR_ERR(saif->clk); |
710 | dev_err(&pdev->dev, "Cannot get the clock: %d\n", | 710 | dev_err(&pdev->dev, "Cannot get the clock: %d\n", |
@@ -717,8 +717,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev) | |||
717 | saif->base = devm_request_and_ioremap(&pdev->dev, iores); | 717 | saif->base = devm_request_and_ioremap(&pdev->dev, iores); |
718 | if (!saif->base) { | 718 | if (!saif->base) { |
719 | dev_err(&pdev->dev, "ioremap failed\n"); | 719 | dev_err(&pdev->dev, "ioremap failed\n"); |
720 | ret = -ENODEV; | 720 | return -ENODEV; |
721 | goto failed_get_resource; | ||
722 | } | 721 | } |
723 | 722 | ||
724 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 723 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
@@ -731,7 +730,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev) | |||
731 | &saif->dma_param.chan_num); | 730 | &saif->dma_param.chan_num); |
732 | if (ret) { | 731 | if (ret) { |
733 | dev_err(&pdev->dev, "failed to get dma channel\n"); | 732 | dev_err(&pdev->dev, "failed to get dma channel\n"); |
734 | goto failed_get_resource; | 733 | return ret; |
735 | } | 734 | } |
736 | } else { | 735 | } else { |
737 | saif->dma_param.chan_num = dmares->start; | 736 | saif->dma_param.chan_num = dmares->start; |
@@ -742,7 +741,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev) | |||
742 | ret = saif->irq; | 741 | ret = saif->irq; |
743 | dev_err(&pdev->dev, "failed to get irq resource: %d\n", | 742 | dev_err(&pdev->dev, "failed to get irq resource: %d\n", |
744 | ret); | 743 | ret); |
745 | goto failed_get_resource; | 744 | return ret; |
746 | } | 745 | } |
747 | 746 | ||
748 | saif->dev = &pdev->dev; | 747 | saif->dev = &pdev->dev; |
@@ -750,7 +749,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev) | |||
750 | "mxs-saif", saif); | 749 | "mxs-saif", saif); |
751 | if (ret) { | 750 | if (ret) { |
752 | dev_err(&pdev->dev, "failed to request irq\n"); | 751 | dev_err(&pdev->dev, "failed to request irq\n"); |
753 | goto failed_get_resource; | 752 | return ret; |
754 | } | 753 | } |
755 | 754 | ||
756 | saif->dma_param.chan_irq = platform_get_irq(pdev, 1); | 755 | saif->dma_param.chan_irq = platform_get_irq(pdev, 1); |
@@ -758,7 +757,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev) | |||
758 | ret = saif->dma_param.chan_irq; | 757 | ret = saif->dma_param.chan_irq; |
759 | dev_err(&pdev->dev, "failed to get dma irq resource: %d\n", | 758 | dev_err(&pdev->dev, "failed to get dma irq resource: %d\n", |
760 | ret); | 759 | ret); |
761 | goto failed_get_resource; | 760 | return ret; |
762 | } | 761 | } |
763 | 762 | ||
764 | platform_set_drvdata(pdev, saif); | 763 | platform_set_drvdata(pdev, saif); |
@@ -766,7 +765,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev) | |||
766 | ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai); | 765 | ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai); |
767 | if (ret) { | 766 | if (ret) { |
768 | dev_err(&pdev->dev, "register DAI failed\n"); | 767 | dev_err(&pdev->dev, "register DAI failed\n"); |
769 | goto failed_get_resource; | 768 | return ret; |
770 | } | 769 | } |
771 | 770 | ||
772 | ret = mxs_pcm_platform_register(&pdev->dev); | 771 | ret = mxs_pcm_platform_register(&pdev->dev); |
@@ -779,19 +778,14 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev) | |||
779 | 778 | ||
780 | failed_pdev_alloc: | 779 | failed_pdev_alloc: |
781 | snd_soc_unregister_dai(&pdev->dev); | 780 | snd_soc_unregister_dai(&pdev->dev); |
782 | failed_get_resource: | ||
783 | clk_put(saif->clk); | ||
784 | 781 | ||
785 | return ret; | 782 | return ret; |
786 | } | 783 | } |
787 | 784 | ||
788 | static int __devexit mxs_saif_remove(struct platform_device *pdev) | 785 | static int __devexit mxs_saif_remove(struct platform_device *pdev) |
789 | { | 786 | { |
790 | struct mxs_saif *saif = platform_get_drvdata(pdev); | ||
791 | |||
792 | mxs_pcm_platform_unregister(&pdev->dev); | 787 | mxs_pcm_platform_unregister(&pdev->dev); |
793 | snd_soc_unregister_dai(&pdev->dev); | 788 | snd_soc_unregister_dai(&pdev->dev); |
794 | clk_put(saif->clk); | ||
795 | 789 | ||
796 | return 0; | 790 | return 0; |
797 | } | 791 | } |
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index 57a2fa751085..7048137f9a33 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config SND_OMAP_SOC | 1 | config SND_OMAP_SOC |
2 | tristate "SoC Audio for the Texas Instruments OMAP chips" | 2 | tristate "SoC Audio for the Texas Instruments OMAP chips" |
3 | depends on ARCH_OMAP | 3 | depends on ARCH_OMAP && DMA_OMAP |
4 | select SND_SOC_DMAENGINE_PCM | ||
4 | 5 | ||
5 | config SND_OMAP_SOC_DMIC | 6 | config SND_OMAP_SOC_DMIC |
6 | tristate | 7 | tristate |
@@ -60,23 +61,6 @@ config SND_OMAP_SOC_OSK5912 | |||
60 | help | 61 | help |
61 | Say Y if you want to add support for SoC audio on osk5912. | 62 | Say Y if you want to add support for SoC audio on osk5912. |
62 | 63 | ||
63 | config SND_OMAP_SOC_OVERO | ||
64 | tristate "SoC Audio support for Gumstix Overo and CompuLab CM-T35" | ||
65 | depends on TWL4030_CORE && SND_OMAP_SOC && (MACH_OVERO || MACH_CM_T35) | ||
66 | select SND_OMAP_SOC_MCBSP | ||
67 | select SND_SOC_TWL4030 | ||
68 | help | ||
69 | Say Y if you want to add support for SoC audio on the | ||
70 | Gumstix Overo or CompuLab CM-T35 | ||
71 | |||
72 | config SND_OMAP_SOC_OMAP3EVM | ||
73 | tristate "SoC Audio support for OMAP3EVM board" | ||
74 | depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3EVM | ||
75 | select SND_OMAP_SOC_MCBSP | ||
76 | select SND_SOC_TWL4030 | ||
77 | help | ||
78 | Say Y if you want to add support for SoC audio on the omap3evm board. | ||
79 | |||
80 | config SND_OMAP_SOC_AM3517EVM | 64 | config SND_OMAP_SOC_AM3517EVM |
81 | tristate "SoC Audio support for OMAP3517 / AM3517 EVM" | 65 | tristate "SoC Audio support for OMAP3517 / AM3517 EVM" |
82 | depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C | 66 | depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C |
@@ -95,6 +79,19 @@ config SND_OMAP_SOC_SDP3430 | |||
95 | Say Y if you want to add support for SoC audio on Texas Instruments | 79 | Say Y if you want to add support for SoC audio on Texas Instruments |
96 | SDP3430. | 80 | SDP3430. |
97 | 81 | ||
82 | config SND_OMAP_SOC_OMAP_TWL4030 | ||
83 | tristate "SoC Audio support for TI SoC based boards with twl4030 codec" | ||
84 | depends on TWL4030_CORE && SND_OMAP_SOC | ||
85 | select SND_OMAP_SOC_MCBSP | ||
86 | select SND_SOC_TWL4030 | ||
87 | help | ||
88 | Say Y if you want to add support for SoC audio on TI SoC based boards | ||
89 | using twl4030 as c codec. This driver currently supports: | ||
90 | - Beagleboard or Devkit8000 | ||
91 | - Gumstix Overo or CompuLab CM-T35/CM-T3730 | ||
92 | - IGEP v2 | ||
93 | - OMAP3EVM | ||
94 | |||
98 | config SND_OMAP_SOC_OMAP_ABE_TWL6040 | 95 | config SND_OMAP_SOC_OMAP_ABE_TWL6040 |
99 | tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" | 96 | tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" |
100 | depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4 | 97 | depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4 |
@@ -127,16 +124,6 @@ config SND_OMAP_SOC_OMAP3_PANDORA | |||
127 | help | 124 | help |
128 | Say Y if you want to add support for SoC audio on the OMAP3 Pandora. | 125 | Say Y if you want to add support for SoC audio on the OMAP3 Pandora. |
129 | 126 | ||
130 | config SND_OMAP_SOC_OMAP3_BEAGLE | ||
131 | tristate "SoC Audio support for OMAP3 Beagle and Devkit8000" | ||
132 | depends on TWL4030_CORE && SND_OMAP_SOC | ||
133 | depends on (MACH_OMAP3_BEAGLE || MACH_DEVKIT8000) | ||
134 | select SND_OMAP_SOC_MCBSP | ||
135 | select SND_SOC_TWL4030 | ||
136 | help | ||
137 | Say Y if you want to add support for SoC audio on the Beagleboard or | ||
138 | the clone Devkit8000. | ||
139 | |||
140 | config SND_OMAP_SOC_ZOOM2 | 127 | config SND_OMAP_SOC_ZOOM2 |
141 | tristate "SoC Audio support for Zoom2" | 128 | tristate "SoC Audio support for Zoom2" |
142 | depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_ZOOM2 | 129 | depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_ZOOM2 |
@@ -144,11 +131,3 @@ config SND_OMAP_SOC_ZOOM2 | |||
144 | select SND_SOC_TWL4030 | 131 | select SND_SOC_TWL4030 |
145 | help | 132 | help |
146 | Say Y if you want to add support for Soc audio on Zoom2 board. | 133 | Say Y if you want to add support for Soc audio on Zoom2 board. |
147 | |||
148 | config SND_OMAP_SOC_IGEP0020 | ||
149 | tristate "SoC Audio support for IGEP v2" | ||
150 | depends on TWL4030_CORE && SND_OMAP_SOC && MACH_IGEP0020 | ||
151 | select SND_OMAP_SOC_MCBSP | ||
152 | select SND_SOC_TWL4030 | ||
153 | help | ||
154 | Say Y if you want to add support for Soc audio on IGEP v2 board. | ||
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile index 0e14dd322565..19637e55ea48 100644 --- a/sound/soc/omap/Makefile +++ b/sound/soc/omap/Makefile | |||
@@ -16,29 +16,23 @@ snd-soc-n810-objs := n810.o | |||
16 | snd-soc-rx51-objs := rx51.o | 16 | snd-soc-rx51-objs := rx51.o |
17 | snd-soc-ams-delta-objs := ams-delta.o | 17 | snd-soc-ams-delta-objs := ams-delta.o |
18 | snd-soc-osk5912-objs := osk5912.o | 18 | snd-soc-osk5912-objs := osk5912.o |
19 | snd-soc-overo-objs := overo.o | ||
20 | snd-soc-omap3evm-objs := omap3evm.o | ||
21 | snd-soc-am3517evm-objs := am3517evm.o | 19 | snd-soc-am3517evm-objs := am3517evm.o |
22 | snd-soc-sdp3430-objs := sdp3430.o | 20 | snd-soc-sdp3430-objs := sdp3430.o |
23 | snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o | 21 | snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o |
22 | snd-soc-omap-twl4030-objs := omap-twl4030.o | ||
24 | snd-soc-omap3pandora-objs := omap3pandora.o | 23 | snd-soc-omap3pandora-objs := omap3pandora.o |
25 | snd-soc-omap3beagle-objs := omap3beagle.o | ||
26 | snd-soc-zoom2-objs := zoom2.o | 24 | snd-soc-zoom2-objs := zoom2.o |
27 | snd-soc-igep0020-objs := igep0020.o | ||
28 | snd-soc-omap-hdmi-card-objs := omap-hdmi-card.o | 25 | snd-soc-omap-hdmi-card-objs := omap-hdmi-card.o |
29 | 26 | ||
30 | obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o | 27 | obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o |
31 | obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o | 28 | obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o |
32 | obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o | 29 | obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o |
33 | obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o | 30 | obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o |
34 | obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o | ||
35 | obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o | 31 | obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o |
36 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o | ||
37 | obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o | 32 | obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o |
38 | obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o | 33 | obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o |
39 | obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o | 34 | obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o |
35 | obj-$(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) += snd-soc-omap-twl4030.o | ||
40 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o | 36 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o |
41 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o | ||
42 | obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o | 37 | obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o |
43 | obj-$(CONFIG_SND_OMAP_SOC_IGEP0020) += snd-soc-igep0020.o | ||
44 | obj-$(CONFIG_SND_OMAP_SOC_OMAP_HDMI) += snd-soc-omap-hdmi-card.o | 38 | obj-$(CONFIG_SND_OMAP_SOC_OMAP_HDMI) += snd-soc-omap-hdmi-card.o |
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c index 009533ab8d18..77a87012977c 100644 --- a/sound/soc/omap/am3517evm.c +++ b/sound/soc/omap/am3517evm.c | |||
@@ -41,32 +41,15 @@ static int am3517evm_hw_params(struct snd_pcm_substream *substream, | |||
41 | { | 41 | { |
42 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 42 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
43 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 43 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
44 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
45 | int ret; | 44 | int ret; |
46 | 45 | ||
47 | /* Set the codec system clock for DAC and ADC */ | 46 | /* Set the codec system clock for DAC and ADC */ |
48 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, | 47 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, |
49 | CODEC_CLOCK, SND_SOC_CLOCK_IN); | 48 | CODEC_CLOCK, SND_SOC_CLOCK_IN); |
50 | if (ret < 0) { | 49 | if (ret < 0) |
51 | printk(KERN_ERR "can't set codec system clock\n"); | 50 | printk(KERN_ERR "can't set codec system clock\n"); |
52 | return ret; | ||
53 | } | ||
54 | |||
55 | ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_CLKR_SRC_CLKX, 0, | ||
56 | SND_SOC_CLOCK_IN); | ||
57 | if (ret < 0) { | ||
58 | printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_CLKR_SRC_CLKX\n"); | ||
59 | return ret; | ||
60 | } | ||
61 | 51 | ||
62 | snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0, | 52 | return ret; |
63 | SND_SOC_CLOCK_IN); | ||
64 | if (ret < 0) { | ||
65 | printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n"); | ||
66 | return ret; | ||
67 | } | ||
68 | |||
69 | return 0; | ||
70 | } | 53 | } |
71 | 54 | ||
72 | static struct snd_soc_ops am3517evm_ops = { | 55 | static struct snd_soc_ops am3517evm_ops = { |
diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c deleted file mode 100644 index e8357819175b..000000000000 --- a/sound/soc/omap/igep0020.c +++ /dev/null | |||
@@ -1,120 +0,0 @@ | |||
1 | /* | ||
2 | * igep0020.c -- SoC audio for IGEP v2 | ||
3 | * | ||
4 | * Based on sound/soc/omap/overo.c by Steve Sakoman | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/clk.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <sound/core.h> | ||
26 | #include <sound/pcm.h> | ||
27 | #include <sound/soc.h> | ||
28 | |||
29 | #include <asm/mach-types.h> | ||
30 | #include <mach/hardware.h> | ||
31 | #include <mach/gpio.h> | ||
32 | #include <plat/mcbsp.h> | ||
33 | |||
34 | #include "omap-mcbsp.h" | ||
35 | #include "omap-pcm.h" | ||
36 | |||
37 | static int igep2_hw_params(struct snd_pcm_substream *substream, | ||
38 | struct snd_pcm_hw_params *params) | ||
39 | { | ||
40 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
41 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
42 | int ret; | ||
43 | |||
44 | /* Set the codec system clock for DAC and ADC */ | ||
45 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, | ||
46 | SND_SOC_CLOCK_IN); | ||
47 | if (ret < 0) { | ||
48 | printk(KERN_ERR "can't set codec system clock\n"); | ||
49 | return ret; | ||
50 | } | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static struct snd_soc_ops igep2_ops = { | ||
56 | .hw_params = igep2_hw_params, | ||
57 | }; | ||
58 | |||
59 | /* Digital audio interface glue - connects codec <--> CPU */ | ||
60 | static struct snd_soc_dai_link igep2_dai = { | ||
61 | .name = "TWL4030", | ||
62 | .stream_name = "TWL4030", | ||
63 | .cpu_dai_name = "omap-mcbsp.2", | ||
64 | .codec_dai_name = "twl4030-hifi", | ||
65 | .platform_name = "omap-pcm-audio", | ||
66 | .codec_name = "twl4030-codec", | ||
67 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
68 | SND_SOC_DAIFMT_CBM_CFM, | ||
69 | .ops = &igep2_ops, | ||
70 | }; | ||
71 | |||
72 | /* Audio machine driver */ | ||
73 | static struct snd_soc_card snd_soc_card_igep2 = { | ||
74 | .name = "igep2", | ||
75 | .owner = THIS_MODULE, | ||
76 | .dai_link = &igep2_dai, | ||
77 | .num_links = 1, | ||
78 | }; | ||
79 | |||
80 | static struct platform_device *igep2_snd_device; | ||
81 | |||
82 | static int __init igep2_soc_init(void) | ||
83 | { | ||
84 | int ret; | ||
85 | |||
86 | if (!machine_is_igep0020()) | ||
87 | return -ENODEV; | ||
88 | printk(KERN_INFO "IGEP v2 SoC init\n"); | ||
89 | |||
90 | igep2_snd_device = platform_device_alloc("soc-audio", -1); | ||
91 | if (!igep2_snd_device) { | ||
92 | printk(KERN_ERR "Platform device allocation failed\n"); | ||
93 | return -ENOMEM; | ||
94 | } | ||
95 | |||
96 | platform_set_drvdata(igep2_snd_device, &snd_soc_card_igep2); | ||
97 | |||
98 | ret = platform_device_add(igep2_snd_device); | ||
99 | if (ret) | ||
100 | goto err1; | ||
101 | |||
102 | return 0; | ||
103 | |||
104 | err1: | ||
105 | printk(KERN_ERR "Unable to add platform device\n"); | ||
106 | platform_device_put(igep2_snd_device); | ||
107 | |||
108 | return ret; | ||
109 | } | ||
110 | module_init(igep2_soc_init); | ||
111 | |||
112 | static void __exit igep2_soc_exit(void) | ||
113 | { | ||
114 | platform_device_unregister(igep2_snd_device); | ||
115 | } | ||
116 | module_exit(igep2_soc_exit); | ||
117 | |||
118 | MODULE_AUTHOR("Enric Balletbo i Serra <eballetbo@iseebcn.com>"); | ||
119 | MODULE_DESCRIPTION("ALSA SoC IGEP v2"); | ||
120 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c index d33c48baaf71..bc06175e6367 100644 --- a/sound/soc/omap/mcbsp.c +++ b/sound/soc/omap/mcbsp.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/pm_runtime.h> | ||
27 | 28 | ||
28 | #include <plat/mcbsp.h> | 29 | #include <plat/mcbsp.h> |
29 | 30 | ||
@@ -726,50 +727,39 @@ void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx) | |||
726 | 727 | ||
727 | int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id) | 728 | int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id) |
728 | { | 729 | { |
730 | struct clk *fck_src; | ||
729 | const char *src; | 731 | const char *src; |
732 | int r; | ||
730 | 733 | ||
731 | if (fck_src_id == MCBSP_CLKS_PAD_SRC) | 734 | if (fck_src_id == MCBSP_CLKS_PAD_SRC) |
732 | src = "clks_ext"; | 735 | src = "pad_fck"; |
733 | else if (fck_src_id == MCBSP_CLKS_PRCM_SRC) | 736 | else if (fck_src_id == MCBSP_CLKS_PRCM_SRC) |
734 | src = "clks_fclk"; | 737 | src = "prcm_fck"; |
735 | else | 738 | else |
736 | return -EINVAL; | 739 | return -EINVAL; |
737 | 740 | ||
738 | if (mcbsp->pdata->set_clk_src) | 741 | fck_src = clk_get(mcbsp->dev, src); |
739 | return mcbsp->pdata->set_clk_src(mcbsp->dev, mcbsp->fclk, src); | 742 | if (IS_ERR(fck_src)) { |
740 | else | 743 | dev_err(mcbsp->dev, "CLKS: could not clk_get() %s\n", src); |
741 | return -EINVAL; | 744 | return -EINVAL; |
742 | } | 745 | } |
743 | |||
744 | int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux) | ||
745 | { | ||
746 | const char *signal, *src; | ||
747 | 746 | ||
748 | if (!mcbsp->pdata->mux_signal) | 747 | pm_runtime_put_sync(mcbsp->dev); |
749 | return -EINVAL; | ||
750 | 748 | ||
751 | switch (mux) { | 749 | r = clk_set_parent(mcbsp->fclk, fck_src); |
752 | case CLKR_SRC_CLKR: | 750 | if (r) { |
753 | signal = "clkr"; | 751 | dev_err(mcbsp->dev, "CLKS: could not clk_set_parent() to %s\n", |
754 | src = "clkr"; | 752 | src); |
755 | break; | 753 | clk_put(fck_src); |
756 | case CLKR_SRC_CLKX: | 754 | return r; |
757 | signal = "clkr"; | ||
758 | src = "clkx"; | ||
759 | break; | ||
760 | case FSR_SRC_FSR: | ||
761 | signal = "fsr"; | ||
762 | src = "fsr"; | ||
763 | break; | ||
764 | case FSR_SRC_FSX: | ||
765 | signal = "fsr"; | ||
766 | src = "fsx"; | ||
767 | break; | ||
768 | default: | ||
769 | return -EINVAL; | ||
770 | } | 755 | } |
771 | 756 | ||
772 | return mcbsp->pdata->mux_signal(mcbsp->dev, signal, src); | 757 | pm_runtime_get_sync(mcbsp->dev); |
758 | |||
759 | clk_put(fck_src); | ||
760 | |||
761 | return 0; | ||
762 | |||
773 | } | 763 | } |
774 | 764 | ||
775 | #define max_thres(m) (mcbsp->pdata->buffer_size) | 765 | #define max_thres(m) (mcbsp->pdata->buffer_size) |
diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h index 262a6152111f..49a67259ce5a 100644 --- a/sound/soc/omap/mcbsp.h +++ b/sound/soc/omap/mcbsp.h | |||
@@ -334,9 +334,6 @@ void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx); | |||
334 | /* McBSP functional clock source changing function */ | 334 | /* McBSP functional clock source changing function */ |
335 | int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id); | 335 | int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id); |
336 | 336 | ||
337 | /* McBSP signal muxing API */ | ||
338 | int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux); | ||
339 | |||
340 | /* Sidetone specific API */ | 337 | /* Sidetone specific API */ |
341 | int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain); | 338 | int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain); |
342 | int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain); | 339 | int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain); |
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index 9d93793d3077..be525dfe9faa 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/mfd/twl6040.h> | 25 | #include <linux/mfd/twl6040.h> |
26 | #include <linux/platform_data/omap-abe-twl6040.h> | 26 | #include <linux/platform_data/omap-abe-twl6040.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/of.h> | ||
28 | 29 | ||
29 | #include <sound/core.h> | 30 | #include <sound/core.h> |
30 | #include <sound/pcm.h> | 31 | #include <sound/pcm.h> |
@@ -43,6 +44,8 @@ | |||
43 | struct abe_twl6040 { | 44 | struct abe_twl6040 { |
44 | int jack_detection; /* board can detect jack events */ | 45 | int jack_detection; /* board can detect jack events */ |
45 | int mclk_freq; /* MCLK frequency speed for twl6040 */ | 46 | int mclk_freq; /* MCLK frequency speed for twl6040 */ |
47 | |||
48 | struct platform_device *dmic_codec_dev; | ||
46 | }; | 49 | }; |
47 | 50 | ||
48 | static int omap_abe_hw_params(struct snd_pcm_substream *substream, | 51 | static int omap_abe_hw_params(struct snd_pcm_substream *substream, |
@@ -185,17 +188,6 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd) | |||
185 | int hs_trim; | 188 | int hs_trim; |
186 | int ret = 0; | 189 | int ret = 0; |
187 | 190 | ||
188 | /* Disable not connected paths if not used */ | ||
189 | twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone"); | ||
190 | twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk"); | ||
191 | twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk"); | ||
192 | twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out"); | ||
193 | twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vinrator"); | ||
194 | twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic"); | ||
195 | twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic"); | ||
196 | twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic"); | ||
197 | twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In"); | ||
198 | |||
199 | /* | 191 | /* |
200 | * Configure McPDM offset cancellation based on the HSOTRIM value from | 192 | * Configure McPDM offset cancellation based on the HSOTRIM value from |
201 | * twl6040. | 193 | * twl6040. |
@@ -216,6 +208,24 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd) | |||
216 | twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); | 208 | twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); |
217 | } | 209 | } |
218 | 210 | ||
211 | /* | ||
212 | * NULL pdata means we booted with DT. In this case the routing is | ||
213 | * provided and the card is fully routed, no need to mark pins. | ||
214 | */ | ||
215 | if (!pdata) | ||
216 | return ret; | ||
217 | |||
218 | /* Disable not connected paths if not used */ | ||
219 | twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone"); | ||
220 | twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk"); | ||
221 | twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk"); | ||
222 | twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out"); | ||
223 | twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vinrator"); | ||
224 | twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic"); | ||
225 | twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic"); | ||
226 | twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic"); | ||
227 | twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In"); | ||
228 | |||
219 | return ret; | 229 | return ret; |
220 | } | 230 | } |
221 | 231 | ||
@@ -270,52 +280,116 @@ static struct snd_soc_card omap_abe_card = { | |||
270 | static __devinit int omap_abe_probe(struct platform_device *pdev) | 280 | static __devinit int omap_abe_probe(struct platform_device *pdev) |
271 | { | 281 | { |
272 | struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev); | 282 | struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev); |
283 | struct device_node *node = pdev->dev.of_node; | ||
273 | struct snd_soc_card *card = &omap_abe_card; | 284 | struct snd_soc_card *card = &omap_abe_card; |
274 | struct abe_twl6040 *priv; | 285 | struct abe_twl6040 *priv; |
275 | int num_links = 0; | 286 | int num_links = 0; |
276 | int ret; | 287 | int ret = 0; |
277 | 288 | ||
278 | card->dev = &pdev->dev; | 289 | card->dev = &pdev->dev; |
279 | 290 | ||
280 | if (!pdata) { | ||
281 | dev_err(&pdev->dev, "Missing pdata\n"); | ||
282 | return -ENODEV; | ||
283 | } | ||
284 | |||
285 | priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL); | 291 | priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL); |
286 | if (priv == NULL) | 292 | if (priv == NULL) |
287 | return -ENOMEM; | 293 | return -ENOMEM; |
288 | 294 | ||
289 | if (pdata->card_name) { | 295 | priv->dmic_codec_dev = ERR_PTR(-EINVAL); |
290 | card->name = pdata->card_name; | 296 | |
297 | if (node) { | ||
298 | struct device_node *dai_node; | ||
299 | |||
300 | if (snd_soc_of_parse_card_name(card, "ti,model")) { | ||
301 | dev_err(&pdev->dev, "Card name is not provided\n"); | ||
302 | return -ENODEV; | ||
303 | } | ||
304 | |||
305 | ret = snd_soc_of_parse_audio_routing(card, | ||
306 | "ti,audio-routing"); | ||
307 | if (ret) { | ||
308 | dev_err(&pdev->dev, | ||
309 | "Error while parsing DAPM routing\n"); | ||
310 | return ret; | ||
311 | } | ||
312 | |||
313 | dai_node = of_parse_phandle(node, "ti,mcpdm", 0); | ||
314 | if (!dai_node) { | ||
315 | dev_err(&pdev->dev, "McPDM node is not provided\n"); | ||
316 | return -EINVAL; | ||
317 | } | ||
318 | abe_twl6040_dai_links[0].cpu_dai_name = NULL; | ||
319 | abe_twl6040_dai_links[0].cpu_of_node = dai_node; | ||
320 | |||
321 | dai_node = of_parse_phandle(node, "ti,dmic", 0); | ||
322 | if (dai_node) { | ||
323 | num_links = 2; | ||
324 | abe_twl6040_dai_links[1].cpu_dai_name = NULL; | ||
325 | abe_twl6040_dai_links[1].cpu_of_node = dai_node; | ||
326 | |||
327 | priv->dmic_codec_dev = platform_device_register_simple( | ||
328 | "dmic-codec", -1, NULL, 0); | ||
329 | if (IS_ERR(priv->dmic_codec_dev)) { | ||
330 | dev_err(&pdev->dev, | ||
331 | "Can't instantiate dmic-codec\n"); | ||
332 | return PTR_ERR(priv->dmic_codec_dev); | ||
333 | } | ||
334 | } else { | ||
335 | num_links = 1; | ||
336 | } | ||
337 | |||
338 | of_property_read_u32(node, "ti,jack-detection", | ||
339 | &priv->jack_detection); | ||
340 | of_property_read_u32(node, "ti,mclk-freq", | ||
341 | &priv->mclk_freq); | ||
342 | if (!priv->mclk_freq) { | ||
343 | dev_err(&pdev->dev, "MCLK frequency not provided\n"); | ||
344 | ret = -EINVAL; | ||
345 | goto err_unregister; | ||
346 | } | ||
347 | |||
348 | omap_abe_card.fully_routed = 1; | ||
349 | } else if (pdata) { | ||
350 | if (pdata->card_name) { | ||
351 | card->name = pdata->card_name; | ||
352 | } else { | ||
353 | dev_err(&pdev->dev, "Card name is not provided\n"); | ||
354 | return -ENODEV; | ||
355 | } | ||
356 | |||
357 | if (pdata->has_dmic) | ||
358 | num_links = 2; | ||
359 | else | ||
360 | num_links = 1; | ||
361 | |||
362 | priv->jack_detection = pdata->jack_detection; | ||
363 | priv->mclk_freq = pdata->mclk_freq; | ||
291 | } else { | 364 | } else { |
292 | dev_err(&pdev->dev, "Card name is not provided\n"); | 365 | dev_err(&pdev->dev, "Missing pdata\n"); |
293 | return -ENODEV; | 366 | return -ENODEV; |
294 | } | 367 | } |
295 | 368 | ||
296 | priv->jack_detection = pdata->jack_detection; | ||
297 | priv->mclk_freq = pdata->mclk_freq; | ||
298 | |||
299 | 369 | ||
300 | if (!priv->mclk_freq) { | 370 | if (!priv->mclk_freq) { |
301 | dev_err(&pdev->dev, "MCLK frequency missing\n"); | 371 | dev_err(&pdev->dev, "MCLK frequency missing\n"); |
302 | return -ENODEV; | 372 | ret = -ENODEV; |
373 | goto err_unregister; | ||
303 | } | 374 | } |
304 | 375 | ||
305 | if (pdata->has_dmic) | ||
306 | num_links = 2; | ||
307 | else | ||
308 | num_links = 1; | ||
309 | |||
310 | card->dai_link = abe_twl6040_dai_links; | 376 | card->dai_link = abe_twl6040_dai_links; |
311 | card->num_links = num_links; | 377 | card->num_links = num_links; |
312 | 378 | ||
313 | snd_soc_card_set_drvdata(card, priv); | 379 | snd_soc_card_set_drvdata(card, priv); |
314 | 380 | ||
315 | ret = snd_soc_register_card(card); | 381 | ret = snd_soc_register_card(card); |
316 | if (ret) | 382 | if (ret) { |
317 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", | 383 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", |
318 | ret); | 384 | ret); |
385 | goto err_unregister; | ||
386 | } | ||
387 | |||
388 | return 0; | ||
389 | |||
390 | err_unregister: | ||
391 | if (!IS_ERR(priv->dmic_codec_dev)) | ||
392 | platform_device_unregister(priv->dmic_codec_dev); | ||
319 | 393 | ||
320 | return ret; | 394 | return ret; |
321 | } | 395 | } |
@@ -323,17 +397,28 @@ static __devinit int omap_abe_probe(struct platform_device *pdev) | |||
323 | static int __devexit omap_abe_remove(struct platform_device *pdev) | 397 | static int __devexit omap_abe_remove(struct platform_device *pdev) |
324 | { | 398 | { |
325 | struct snd_soc_card *card = platform_get_drvdata(pdev); | 399 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
400 | struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card); | ||
326 | 401 | ||
327 | snd_soc_unregister_card(card); | 402 | snd_soc_unregister_card(card); |
328 | 403 | ||
404 | if (!IS_ERR(priv->dmic_codec_dev)) | ||
405 | platform_device_unregister(priv->dmic_codec_dev); | ||
406 | |||
329 | return 0; | 407 | return 0; |
330 | } | 408 | } |
331 | 409 | ||
410 | static const struct of_device_id omap_abe_of_match[] = { | ||
411 | {.compatible = "ti,abe-twl6040", }, | ||
412 | { }, | ||
413 | }; | ||
414 | MODULE_DEVICE_TABLE(of, omap_abe_of_match); | ||
415 | |||
332 | static struct platform_driver omap_abe_driver = { | 416 | static struct platform_driver omap_abe_driver = { |
333 | .driver = { | 417 | .driver = { |
334 | .name = "omap-abe-twl6040", | 418 | .name = "omap-abe-twl6040", |
335 | .owner = THIS_MODULE, | 419 | .owner = THIS_MODULE, |
336 | .pm = &snd_soc_pm_ops, | 420 | .pm = &snd_soc_pm_ops, |
421 | .of_match_table = omap_abe_of_match, | ||
337 | }, | 422 | }, |
338 | .probe = omap_abe_probe, | 423 | .probe = omap_abe_probe, |
339 | .remove = __devexit_p(omap_abe_remove), | 424 | .remove = __devexit_p(omap_abe_remove), |
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 75f5dca0e8d2..68f2cd1a9206 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/pm_runtime.h> | 34 | #include <linux/pm_runtime.h> |
35 | #include <linux/of_device.h> | 35 | #include <linux/of_device.h> |
36 | #include <plat/dma.h> | ||
37 | 36 | ||
38 | #include <sound/core.h> | 37 | #include <sound/core.h> |
39 | #include <sound/pcm.h> | 38 | #include <sound/pcm.h> |
@@ -63,8 +62,6 @@ struct omap_dmic { | |||
63 | */ | 62 | */ |
64 | static struct omap_pcm_dma_data omap_dmic_dai_dma_params = { | 63 | static struct omap_pcm_dma_data omap_dmic_dai_dma_params = { |
65 | .name = "DMIC capture", | 64 | .name = "DMIC capture", |
66 | .data_type = OMAP_DMA_DATA_TYPE_S32, | ||
67 | .sync_mode = OMAP_DMA_SYNC_PACKET, | ||
68 | }; | 65 | }; |
69 | 66 | ||
70 | static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val) | 67 | static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val) |
@@ -121,6 +118,7 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream, | |||
121 | 118 | ||
122 | mutex_unlock(&dmic->mutex); | 119 | mutex_unlock(&dmic->mutex); |
123 | 120 | ||
121 | snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params); | ||
124 | return ret; | 122 | return ret; |
125 | } | 123 | } |
126 | 124 | ||
@@ -205,6 +203,7 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream, | |||
205 | struct snd_soc_dai *dai) | 203 | struct snd_soc_dai *dai) |
206 | { | 204 | { |
207 | struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); | 205 | struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); |
206 | struct omap_pcm_dma_data *dma_data; | ||
208 | int channels; | 207 | int channels; |
209 | 208 | ||
210 | dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params)); | 209 | dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params)); |
@@ -230,8 +229,8 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream, | |||
230 | } | 229 | } |
231 | 230 | ||
232 | /* packet size is threshold * channels */ | 231 | /* packet size is threshold * channels */ |
233 | omap_dmic_dai_dma_params.packet_size = dmic->threshold * channels; | 232 | dma_data = snd_soc_dai_get_dma_data(dai, substream); |
234 | snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params); | 233 | dma_data->packet_size = dmic->threshold * channels; |
235 | 234 | ||
236 | return 0; | 235 | return 0; |
237 | } | 236 | } |
diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c index a08245d9203c..f59c69fb400e 100644 --- a/sound/soc/omap/omap-hdmi.c +++ b/sound/soc/omap/omap-hdmi.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <sound/asoundef.h> | 34 | #include <sound/asoundef.h> |
35 | #include <video/omapdss.h> | 35 | #include <video/omapdss.h> |
36 | 36 | ||
37 | #include <plat/dma.h> | ||
38 | #include "omap-pcm.h" | 37 | #include "omap-pcm.h" |
39 | #include "omap-hdmi.h" | 38 | #include "omap-hdmi.h" |
40 | 39 | ||
@@ -68,6 +67,9 @@ static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream, | |||
68 | dev_err(dai->dev, "audio not supported\n"); | 67 | dev_err(dai->dev, "audio not supported\n"); |
69 | return -ENODEV; | 68 | return -ENODEV; |
70 | } | 69 | } |
70 | |||
71 | snd_soc_dai_set_dma_data(dai, substream, &priv->dma_params); | ||
72 | |||
71 | return 0; | 73 | return 0; |
72 | } | 74 | } |
73 | 75 | ||
@@ -86,24 +88,24 @@ static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream, | |||
86 | struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai); | 88 | struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai); |
87 | struct snd_aes_iec958 *iec = &priv->iec; | 89 | struct snd_aes_iec958 *iec = &priv->iec; |
88 | struct snd_cea_861_aud_if *cea = &priv->cea; | 90 | struct snd_cea_861_aud_if *cea = &priv->cea; |
91 | struct omap_pcm_dma_data *dma_data; | ||
89 | int err = 0; | 92 | int err = 0; |
90 | 93 | ||
94 | dma_data = snd_soc_dai_get_dma_data(dai, substream); | ||
95 | |||
91 | switch (params_format(params)) { | 96 | switch (params_format(params)) { |
92 | case SNDRV_PCM_FORMAT_S16_LE: | 97 | case SNDRV_PCM_FORMAT_S16_LE: |
93 | priv->dma_params.packet_size = 16; | 98 | dma_data->packet_size = 16; |
94 | break; | 99 | break; |
95 | case SNDRV_PCM_FORMAT_S24_LE: | 100 | case SNDRV_PCM_FORMAT_S24_LE: |
96 | priv->dma_params.packet_size = 32; | 101 | dma_data->packet_size = 32; |
97 | break; | 102 | break; |
98 | default: | 103 | default: |
99 | dev_err(dai->dev, "format not supported!\n"); | 104 | dev_err(dai->dev, "format not supported!\n"); |
100 | return -EINVAL; | 105 | return -EINVAL; |
101 | } | 106 | } |
102 | 107 | ||
103 | priv->dma_params.data_type = OMAP_DMA_DATA_TYPE_S32; | 108 | dma_data->data_type = 32; |
104 | |||
105 | snd_soc_dai_set_dma_data(dai, substream, | ||
106 | &priv->dma_params); | ||
107 | 109 | ||
108 | /* | 110 | /* |
109 | * fill the IEC-60958 channel status word | 111 | * fill the IEC-60958 channel status word |
@@ -290,7 +292,6 @@ static __devinit int omap_hdmi_probe(struct platform_device *pdev) | |||
290 | 292 | ||
291 | hdmi_data->dma_params.dma_req = hdmi_rsrc->start; | 293 | hdmi_data->dma_params.dma_req = hdmi_rsrc->start; |
292 | hdmi_data->dma_params.name = "HDMI playback"; | 294 | hdmi_data->dma_params.name = "HDMI playback"; |
293 | hdmi_data->dma_params.sync_mode = OMAP_DMA_SYNC_PACKET; | ||
294 | 295 | ||
295 | /* | 296 | /* |
296 | * TODO: We assume that there is only one DSS HDMI device. Future | 297 | * TODO: We assume that there is only one DSS HDMI device. Future |
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index acdd3ef14e08..fef2f5933bb2 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c | |||
@@ -26,13 +26,14 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/device.h> | 27 | #include <linux/device.h> |
28 | #include <linux/pm_runtime.h> | 28 | #include <linux/pm_runtime.h> |
29 | #include <linux/of.h> | ||
30 | #include <linux/of_device.h> | ||
29 | #include <sound/core.h> | 31 | #include <sound/core.h> |
30 | #include <sound/pcm.h> | 32 | #include <sound/pcm.h> |
31 | #include <sound/pcm_params.h> | 33 | #include <sound/pcm_params.h> |
32 | #include <sound/initval.h> | 34 | #include <sound/initval.h> |
33 | #include <sound/soc.h> | 35 | #include <sound/soc.h> |
34 | 36 | ||
35 | #include <plat/dma.h> | ||
36 | #include <plat/mcbsp.h> | 37 | #include <plat/mcbsp.h> |
37 | #include "mcbsp.h" | 38 | #include "mcbsp.h" |
38 | #include "omap-mcbsp.h" | 39 | #include "omap-mcbsp.h" |
@@ -79,9 +80,6 @@ static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) | |||
79 | */ | 80 | */ |
80 | if (dma_data->packet_size) | 81 | if (dma_data->packet_size) |
81 | words = dma_data->packet_size; | 82 | words = dma_data->packet_size; |
82 | else if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) | ||
83 | words = snd_pcm_lib_period_bytes(substream) / | ||
84 | (mcbsp->wlen / 8); | ||
85 | else | 83 | else |
86 | words = 1; | 84 | words = 1; |
87 | 85 | ||
@@ -153,6 +151,9 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, | |||
153 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2); | 151 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2); |
154 | } | 152 | } |
155 | 153 | ||
154 | snd_soc_dai_set_dma_data(cpu_dai, substream, | ||
155 | &mcbsp->dma_data[substream->stream]); | ||
156 | |||
156 | return err; | 157 | return err; |
157 | } | 158 | } |
158 | 159 | ||
@@ -226,20 +227,18 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
226 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); | 227 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); |
227 | struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs; | 228 | struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs; |
228 | struct omap_pcm_dma_data *dma_data; | 229 | struct omap_pcm_dma_data *dma_data; |
229 | int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT; | 230 | int wlen, channels, wpf; |
230 | int pkt_size = 0; | 231 | int pkt_size = 0; |
231 | unsigned int format, div, framesize, master; | 232 | unsigned int format, div, framesize, master; |
232 | 233 | ||
233 | dma_data = &mcbsp->dma_data[substream->stream]; | 234 | dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream); |
234 | channels = params_channels(params); | 235 | channels = params_channels(params); |
235 | 236 | ||
236 | switch (params_format(params)) { | 237 | switch (params_format(params)) { |
237 | case SNDRV_PCM_FORMAT_S16_LE: | 238 | case SNDRV_PCM_FORMAT_S16_LE: |
238 | dma_data->data_type = OMAP_DMA_DATA_TYPE_S16; | ||
239 | wlen = 16; | 239 | wlen = 16; |
240 | break; | 240 | break; |
241 | case SNDRV_PCM_FORMAT_S32_LE: | 241 | case SNDRV_PCM_FORMAT_S32_LE: |
242 | dma_data->data_type = OMAP_DMA_DATA_TYPE_S32; | ||
243 | wlen = 32; | 242 | wlen = 32; |
244 | break; | 243 | break; |
245 | default: | 244 | default: |
@@ -249,6 +248,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
249 | dma_data->set_threshold = omap_mcbsp_set_threshold; | 248 | dma_data->set_threshold = omap_mcbsp_set_threshold; |
250 | if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) { | 249 | if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) { |
251 | int period_words, max_thrsh; | 250 | int period_words, max_thrsh; |
251 | int divider = 0; | ||
252 | 252 | ||
253 | period_words = params_period_bytes(params) / (wlen / 8); | 253 | period_words = params_period_bytes(params) / (wlen / 8); |
254 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 254 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
@@ -256,46 +256,30 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
256 | else | 256 | else |
257 | max_thrsh = mcbsp->max_rx_thres; | 257 | max_thrsh = mcbsp->max_rx_thres; |
258 | /* | 258 | /* |
259 | * If the period contains less or equal number of words, | 259 | * Use sDMA packet mode if McBSP is in threshold mode: |
260 | * we are using the original threshold mode setup: | 260 | * If period words less than the FIFO size the packet |
261 | * McBSP threshold = sDMA frame size = period_size | 261 | * size is set to the number of period words, otherwise |
262 | * Otherwise we switch to sDMA packet mode: | 262 | * Look for the biggest threshold value which divides |
263 | * McBSP threshold = sDMA packet size | 263 | * the period size evenly. |
264 | * sDMA frame size = period size | ||
265 | */ | 264 | */ |
266 | if (period_words > max_thrsh) { | 265 | divider = period_words / max_thrsh; |
267 | int divider = 0; | 266 | if (period_words % max_thrsh) |
268 | 267 | divider++; | |
269 | /* | 268 | while (period_words % divider && |
270 | * Look for the biggest threshold value, which | 269 | divider < period_words) |
271 | * divides the period size evenly. | 270 | divider++; |
272 | */ | 271 | if (divider == period_words) |
273 | divider = period_words / max_thrsh; | 272 | return -EINVAL; |
274 | if (period_words % max_thrsh) | 273 | |
275 | divider++; | 274 | pkt_size = period_words / divider; |
276 | while (period_words % divider && | ||
277 | divider < period_words) | ||
278 | divider++; | ||
279 | if (divider == period_words) | ||
280 | return -EINVAL; | ||
281 | |||
282 | pkt_size = period_words / divider; | ||
283 | sync_mode = OMAP_DMA_SYNC_PACKET; | ||
284 | } else { | ||
285 | sync_mode = OMAP_DMA_SYNC_FRAME; | ||
286 | } | ||
287 | } else if (channels > 1) { | 275 | } else if (channels > 1) { |
288 | /* Use packet mode for non mono streams */ | 276 | /* Use packet mode for non mono streams */ |
289 | pkt_size = channels; | 277 | pkt_size = channels; |
290 | sync_mode = OMAP_DMA_SYNC_PACKET; | ||
291 | } | 278 | } |
292 | } | 279 | } |
293 | 280 | ||
294 | dma_data->sync_mode = sync_mode; | ||
295 | dma_data->packet_size = pkt_size; | 281 | dma_data->packet_size = pkt_size; |
296 | 282 | ||
297 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); | ||
298 | |||
299 | if (mcbsp->configured) { | 283 | if (mcbsp->configured) { |
300 | /* McBSP already configured by another stream */ | 284 | /* McBSP already configured by another stream */ |
301 | return 0; | 285 | return 0; |
@@ -398,12 +382,14 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
398 | /* Generic McBSP register settings */ | 382 | /* Generic McBSP register settings */ |
399 | regs->spcr2 |= XINTM(3) | FREE; | 383 | regs->spcr2 |= XINTM(3) | FREE; |
400 | regs->spcr1 |= RINTM(3); | 384 | regs->spcr1 |= RINTM(3); |
401 | /* RFIG and XFIG are not defined in 34xx */ | 385 | /* RFIG and XFIG are not defined in 2430 and on OMAP3+ */ |
402 | if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) { | 386 | if (!mcbsp->pdata->has_ccr) { |
403 | regs->rcr2 |= RFIG; | 387 | regs->rcr2 |= RFIG; |
404 | regs->xcr2 |= XFIG; | 388 | regs->xcr2 |= XFIG; |
405 | } | 389 | } |
406 | if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { | 390 | |
391 | /* Configure XCCR/RCCR only for revisions which have ccr registers */ | ||
392 | if (mcbsp->pdata->has_ccr) { | ||
407 | regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE; | 393 | regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE; |
408 | regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE; | 394 | regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE; |
409 | } | 395 | } |
@@ -516,21 +502,9 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
516 | return -EBUSY; | 502 | return -EBUSY; |
517 | } | 503 | } |
518 | 504 | ||
519 | if (clk_id == OMAP_MCBSP_SYSCLK_CLK || | 505 | mcbsp->in_freq = freq; |
520 | clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK || | 506 | regs->srgr2 &= ~CLKSM; |
521 | clk_id == OMAP_MCBSP_SYSCLK_CLKS_EXT || | 507 | regs->pcr0 &= ~SCLKME; |
522 | clk_id == OMAP_MCBSP_SYSCLK_CLKX_EXT || | ||
523 | clk_id == OMAP_MCBSP_SYSCLK_CLKR_EXT) { | ||
524 | mcbsp->in_freq = freq; | ||
525 | regs->srgr2 &= ~CLKSM; | ||
526 | regs->pcr0 &= ~SCLKME; | ||
527 | } else if (cpu_class_is_omap1()) { | ||
528 | /* | ||
529 | * McBSP CLKR/FSR signal muxing functions are only available on | ||
530 | * OMAP2 or newer versions | ||
531 | */ | ||
532 | return -EINVAL; | ||
533 | } | ||
534 | 508 | ||
535 | switch (clk_id) { | 509 | switch (clk_id) { |
536 | case OMAP_MCBSP_SYSCLK_CLK: | 510 | case OMAP_MCBSP_SYSCLK_CLK: |
@@ -558,20 +532,6 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
558 | case OMAP_MCBSP_SYSCLK_CLKR_EXT: | 532 | case OMAP_MCBSP_SYSCLK_CLKR_EXT: |
559 | regs->pcr0 |= SCLKME; | 533 | regs->pcr0 |= SCLKME; |
560 | break; | 534 | break; |
561 | |||
562 | |||
563 | case OMAP_MCBSP_CLKR_SRC_CLKR: | ||
564 | err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKR); | ||
565 | break; | ||
566 | case OMAP_MCBSP_CLKR_SRC_CLKX: | ||
567 | err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKX); | ||
568 | break; | ||
569 | case OMAP_MCBSP_FSR_SRC_FSR: | ||
570 | err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSR); | ||
571 | break; | ||
572 | case OMAP_MCBSP_FSR_SRC_FSX: | ||
573 | err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSX); | ||
574 | break; | ||
575 | default: | 535 | default: |
576 | err = -ENODEV; | 536 | err = -ENODEV; |
577 | } | 537 | } |
@@ -641,9 +601,9 @@ static int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol, | |||
641 | return 0; | 601 | return 0; |
642 | } | 602 | } |
643 | 603 | ||
644 | #define OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(channel) \ | 604 | #define OMAP_MCBSP_ST_CHANNEL_VOLUME(channel) \ |
645 | static int \ | 605 | static int \ |
646 | omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \ | 606 | omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \ |
647 | struct snd_ctl_elem_value *uc) \ | 607 | struct snd_ctl_elem_value *uc) \ |
648 | { \ | 608 | { \ |
649 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \ | 609 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \ |
@@ -659,11 +619,10 @@ omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \ | |||
659 | \ | 619 | \ |
660 | /* OMAP McBSP implementation uses index values 0..4 */ \ | 620 | /* OMAP McBSP implementation uses index values 0..4 */ \ |
661 | return omap_st_set_chgain(mcbsp, channel, val); \ | 621 | return omap_st_set_chgain(mcbsp, channel, val); \ |
662 | } | 622 | } \ |
663 | 623 | \ | |
664 | #define OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(channel) \ | ||
665 | static int \ | 624 | static int \ |
666 | omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \ | 625 | omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \ |
667 | struct snd_ctl_elem_value *uc) \ | 626 | struct snd_ctl_elem_value *uc) \ |
668 | { \ | 627 | { \ |
669 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \ | 628 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \ |
@@ -677,10 +636,8 @@ omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \ | |||
677 | return 0; \ | 636 | return 0; \ |
678 | } | 637 | } |
679 | 638 | ||
680 | OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(0) | 639 | OMAP_MCBSP_ST_CHANNEL_VOLUME(0) |
681 | OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(1) | 640 | OMAP_MCBSP_ST_CHANNEL_VOLUME(1) |
682 | OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(0) | ||
683 | OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(1) | ||
684 | 641 | ||
685 | static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol, | 642 | static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol, |
686 | struct snd_ctl_elem_value *ucontrol) | 643 | struct snd_ctl_elem_value *ucontrol) |
@@ -710,41 +667,34 @@ static int omap_mcbsp_st_get_mode(struct snd_kcontrol *kcontrol, | |||
710 | return 0; | 667 | return 0; |
711 | } | 668 | } |
712 | 669 | ||
713 | static const struct snd_kcontrol_new omap_mcbsp2_st_controls[] = { | 670 | #define OMAP_MCBSP_ST_CONTROLS(port) \ |
714 | SOC_SINGLE_EXT("McBSP2 Sidetone Switch", 1, 0, 1, 0, | 671 | static const struct snd_kcontrol_new omap_mcbsp##port##_st_controls[] = { \ |
715 | omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode), | 672 | SOC_SINGLE_EXT("McBSP" #port " Sidetone Switch", 1, 0, 1, 0, \ |
716 | OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 0 Volume", | 673 | omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode), \ |
717 | -32768, 32767, | 674 | OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 0 Volume", \ |
718 | omap_mcbsp_get_st_ch0_volume, | 675 | -32768, 32767, \ |
719 | omap_mcbsp_set_st_ch0_volume), | 676 | omap_mcbsp_get_st_ch0_volume, \ |
720 | OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 1 Volume", | 677 | omap_mcbsp_set_st_ch0_volume), \ |
721 | -32768, 32767, | 678 | OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 1 Volume", \ |
722 | omap_mcbsp_get_st_ch1_volume, | 679 | -32768, 32767, \ |
723 | omap_mcbsp_set_st_ch1_volume), | 680 | omap_mcbsp_get_st_ch1_volume, \ |
724 | }; | 681 | omap_mcbsp_set_st_ch1_volume), \ |
682 | } | ||
725 | 683 | ||
726 | static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = { | 684 | OMAP_MCBSP_ST_CONTROLS(2); |
727 | SOC_SINGLE_EXT("McBSP3 Sidetone Switch", 2, 0, 1, 0, | 685 | OMAP_MCBSP_ST_CONTROLS(3); |
728 | omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode), | ||
729 | OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 0 Volume", | ||
730 | -32768, 32767, | ||
731 | omap_mcbsp_get_st_ch0_volume, | ||
732 | omap_mcbsp_set_st_ch0_volume), | ||
733 | OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 1 Volume", | ||
734 | -32768, 32767, | ||
735 | omap_mcbsp_get_st_ch1_volume, | ||
736 | omap_mcbsp_set_st_ch1_volume), | ||
737 | }; | ||
738 | 686 | ||
739 | int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd) | 687 | int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd) |
740 | { | 688 | { |
741 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 689 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
742 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); | 690 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); |
743 | 691 | ||
744 | if (!mcbsp->st_data) | 692 | if (!mcbsp->st_data) { |
745 | return -ENODEV; | 693 | dev_warn(mcbsp->dev, "No sidetone data for port\n"); |
694 | return 0; | ||
695 | } | ||
746 | 696 | ||
747 | switch (cpu_dai->id) { | 697 | switch (mcbsp->id) { |
748 | case 2: /* McBSP 2 */ | 698 | case 2: /* McBSP 2 */ |
749 | return snd_soc_add_dai_controls(cpu_dai, | 699 | return snd_soc_add_dai_controls(cpu_dai, |
750 | omap_mcbsp2_st_controls, | 700 | omap_mcbsp2_st_controls, |
@@ -761,13 +711,74 @@ int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd) | |||
761 | } | 711 | } |
762 | EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls); | 712 | EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls); |
763 | 713 | ||
714 | static struct omap_mcbsp_platform_data omap2420_pdata = { | ||
715 | .reg_step = 4, | ||
716 | .reg_size = 2, | ||
717 | }; | ||
718 | |||
719 | static struct omap_mcbsp_platform_data omap2430_pdata = { | ||
720 | .reg_step = 4, | ||
721 | .reg_size = 4, | ||
722 | .has_ccr = true, | ||
723 | }; | ||
724 | |||
725 | static struct omap_mcbsp_platform_data omap3_pdata = { | ||
726 | .reg_step = 4, | ||
727 | .reg_size = 4, | ||
728 | .has_ccr = true, | ||
729 | .has_wakeup = true, | ||
730 | }; | ||
731 | |||
732 | static struct omap_mcbsp_platform_data omap4_pdata = { | ||
733 | .reg_step = 4, | ||
734 | .reg_size = 4, | ||
735 | .has_ccr = true, | ||
736 | .has_wakeup = true, | ||
737 | }; | ||
738 | |||
739 | static const struct of_device_id omap_mcbsp_of_match[] = { | ||
740 | { | ||
741 | .compatible = "ti,omap2420-mcbsp", | ||
742 | .data = &omap2420_pdata, | ||
743 | }, | ||
744 | { | ||
745 | .compatible = "ti,omap2430-mcbsp", | ||
746 | .data = &omap2430_pdata, | ||
747 | }, | ||
748 | { | ||
749 | .compatible = "ti,omap3-mcbsp", | ||
750 | .data = &omap3_pdata, | ||
751 | }, | ||
752 | { | ||
753 | .compatible = "ti,omap4-mcbsp", | ||
754 | .data = &omap4_pdata, | ||
755 | }, | ||
756 | { }, | ||
757 | }; | ||
758 | MODULE_DEVICE_TABLE(of, omap_mcbsp_of_match); | ||
759 | |||
764 | static __devinit int asoc_mcbsp_probe(struct platform_device *pdev) | 760 | static __devinit int asoc_mcbsp_probe(struct platform_device *pdev) |
765 | { | 761 | { |
766 | struct omap_mcbsp_platform_data *pdata = dev_get_platdata(&pdev->dev); | 762 | struct omap_mcbsp_platform_data *pdata = dev_get_platdata(&pdev->dev); |
767 | struct omap_mcbsp *mcbsp; | 763 | struct omap_mcbsp *mcbsp; |
764 | const struct of_device_id *match; | ||
768 | int ret; | 765 | int ret; |
769 | 766 | ||
770 | if (!pdata) { | 767 | match = of_match_device(omap_mcbsp_of_match, &pdev->dev); |
768 | if (match) { | ||
769 | struct device_node *node = pdev->dev.of_node; | ||
770 | int buffer_size; | ||
771 | |||
772 | pdata = devm_kzalloc(&pdev->dev, | ||
773 | sizeof(struct omap_mcbsp_platform_data), | ||
774 | GFP_KERNEL); | ||
775 | if (!pdata) | ||
776 | return -ENOMEM; | ||
777 | |||
778 | memcpy(pdata, match->data, sizeof(*pdata)); | ||
779 | if (!of_property_read_u32(node, "ti,buffer-size", &buffer_size)) | ||
780 | pdata->buffer_size = buffer_size; | ||
781 | } else if (!pdata) { | ||
771 | dev_err(&pdev->dev, "missing platform data.\n"); | 782 | dev_err(&pdev->dev, "missing platform data.\n"); |
772 | return -EINVAL; | 783 | return -EINVAL; |
773 | } | 784 | } |
@@ -809,6 +820,7 @@ static struct platform_driver asoc_mcbsp_driver = { | |||
809 | .driver = { | 820 | .driver = { |
810 | .name = "omap-mcbsp", | 821 | .name = "omap-mcbsp", |
811 | .owner = THIS_MODULE, | 822 | .owner = THIS_MODULE, |
823 | .of_match_table = omap_mcbsp_of_match, | ||
812 | }, | 824 | }, |
813 | 825 | ||
814 | .probe = asoc_mcbsp_probe, | 826 | .probe = asoc_mcbsp_probe, |
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h index f877b16f19c9..ba8386a0d8dc 100644 --- a/sound/soc/omap/omap-mcbsp.h +++ b/sound/soc/omap/omap-mcbsp.h | |||
@@ -32,10 +32,6 @@ enum omap_mcbsp_clksrg_clk { | |||
32 | OMAP_MCBSP_SYSCLK_CLK, /* Internal ICLK */ | 32 | OMAP_MCBSP_SYSCLK_CLK, /* Internal ICLK */ |
33 | OMAP_MCBSP_SYSCLK_CLKX_EXT, /* External CLKX pin */ | 33 | OMAP_MCBSP_SYSCLK_CLKX_EXT, /* External CLKX pin */ |
34 | OMAP_MCBSP_SYSCLK_CLKR_EXT, /* External CLKR pin */ | 34 | OMAP_MCBSP_SYSCLK_CLKR_EXT, /* External CLKR pin */ |
35 | OMAP_MCBSP_CLKR_SRC_CLKR, /* CLKR from CLKR pin */ | ||
36 | OMAP_MCBSP_CLKR_SRC_CLKX, /* CLKR from CLKX pin */ | ||
37 | OMAP_MCBSP_FSR_SRC_FSR, /* FSR from FSR pin */ | ||
38 | OMAP_MCBSP_FSR_SRC_FSX, /* FSR from FSX pin */ | ||
39 | }; | 35 | }; |
40 | 36 | ||
41 | /* McBSP dividers */ | 37 | /* McBSP dividers */ |
@@ -43,22 +39,6 @@ enum omap_mcbsp_div { | |||
43 | OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */ | 39 | OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */ |
44 | }; | 40 | }; |
45 | 41 | ||
46 | #if defined(CONFIG_SOC_OMAP2420) | ||
47 | #define NUM_LINKS 2 | ||
48 | #endif | ||
49 | #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) | ||
50 | #undef NUM_LINKS | ||
51 | #define NUM_LINKS 3 | ||
52 | #endif | ||
53 | #if defined(CONFIG_ARCH_OMAP4) | ||
54 | #undef NUM_LINKS | ||
55 | #define NUM_LINKS 4 | ||
56 | #endif | ||
57 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_OMAP2430) | ||
58 | #undef NUM_LINKS | ||
59 | #define NUM_LINKS 5 | ||
60 | #endif | ||
61 | |||
62 | int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd); | 42 | int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd); |
63 | 43 | ||
64 | #endif | 44 | #endif |
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 2c66e2498a45..775565032ce3 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <sound/pcm_params.h> | 40 | #include <sound/pcm_params.h> |
41 | #include <sound/soc.h> | 41 | #include <sound/soc.h> |
42 | 42 | ||
43 | #include <plat/dma.h> | ||
44 | #include <plat/omap_hwmod.h> | 43 | #include <plat/omap_hwmod.h> |
45 | #include "omap-mcpdm.h" | 44 | #include "omap-mcpdm.h" |
46 | #include "omap-pcm.h" | 45 | #include "omap-pcm.h" |
@@ -71,17 +70,9 @@ struct omap_mcpdm { | |||
71 | static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = { | 70 | static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = { |
72 | { | 71 | { |
73 | .name = "Audio playback", | 72 | .name = "Audio playback", |
74 | .dma_req = OMAP44XX_DMA_MCPDM_DL, | ||
75 | .data_type = OMAP_DMA_DATA_TYPE_S32, | ||
76 | .sync_mode = OMAP_DMA_SYNC_PACKET, | ||
77 | .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_REG_DN_DATA, | ||
78 | }, | 73 | }, |
79 | { | 74 | { |
80 | .name = "Audio capture", | 75 | .name = "Audio capture", |
81 | .dma_req = OMAP44XX_DMA_MCPDM_UP, | ||
82 | .data_type = OMAP_DMA_DATA_TYPE_S32, | ||
83 | .sync_mode = OMAP_DMA_SYNC_PACKET, | ||
84 | .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_REG_UP_DATA, | ||
85 | }, | 76 | }, |
86 | }; | 77 | }; |
87 | 78 | ||
@@ -276,9 +267,11 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream, | |||
276 | } | 267 | } |
277 | omap_mcpdm_open_streams(mcpdm); | 268 | omap_mcpdm_open_streams(mcpdm); |
278 | } | 269 | } |
279 | |||
280 | mutex_unlock(&mcpdm->mutex); | 270 | mutex_unlock(&mcpdm->mutex); |
281 | 271 | ||
272 | snd_soc_dai_set_dma_data(dai, substream, | ||
273 | &omap_mcpdm_dai_dma_params[substream->stream]); | ||
274 | |||
282 | return 0; | 275 | return 0; |
283 | } | 276 | } |
284 | 277 | ||
@@ -333,7 +326,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, | |||
333 | return -EINVAL; | 326 | return -EINVAL; |
334 | } | 327 | } |
335 | 328 | ||
336 | dma_data = &omap_mcpdm_dai_dma_params[stream]; | 329 | dma_data = snd_soc_dai_get_dma_data(dai, substream); |
337 | 330 | ||
338 | /* Configure McPDM channels, and DMA packet size */ | 331 | /* Configure McPDM channels, and DMA packet size */ |
339 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 332 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
@@ -345,8 +338,6 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, | |||
345 | dma_data->packet_size = mcpdm->up_threshold * channels; | 338 | dma_data->packet_size = mcpdm->up_threshold * channels; |
346 | } | 339 | } |
347 | 340 | ||
348 | snd_soc_dai_set_dma_data(dai, substream, dma_data); | ||
349 | |||
350 | return 0; | 341 | return 0; |
351 | } | 342 | } |
352 | 343 | ||
@@ -445,9 +436,8 @@ static __devinit int asoc_mcpdm_probe(struct platform_device *pdev) | |||
445 | { | 436 | { |
446 | struct omap_mcpdm *mcpdm; | 437 | struct omap_mcpdm *mcpdm; |
447 | struct resource *res; | 438 | struct resource *res; |
448 | int ret = 0; | ||
449 | 439 | ||
450 | mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL); | 440 | mcpdm = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcpdm), GFP_KERNEL); |
451 | if (!mcpdm) | 441 | if (!mcpdm) |
452 | return -ENOMEM; | 442 | return -ENOMEM; |
453 | 443 | ||
@@ -455,56 +445,54 @@ static __devinit int asoc_mcpdm_probe(struct platform_device *pdev) | |||
455 | 445 | ||
456 | mutex_init(&mcpdm->mutex); | 446 | mutex_init(&mcpdm->mutex); |
457 | 447 | ||
448 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma"); | ||
449 | if (res == NULL) | ||
450 | return -ENOMEM; | ||
451 | |||
452 | omap_mcpdm_dai_dma_params[0].port_addr = res->start + MCPDM_REG_DN_DATA; | ||
453 | omap_mcpdm_dai_dma_params[1].port_addr = res->start + MCPDM_REG_UP_DATA; | ||
454 | |||
458 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 455 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
459 | if (res == NULL) { | 456 | if (res == NULL) |
460 | dev_err(&pdev->dev, "no resource\n"); | 457 | return -ENOMEM; |
461 | goto err_res; | ||
462 | } | ||
463 | 458 | ||
464 | if (!request_mem_region(res->start, resource_size(res), "McPDM")) { | 459 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "dn_link"); |
465 | ret = -EBUSY; | 460 | if (!res) |
466 | goto err_res; | 461 | return -ENODEV; |
467 | } | ||
468 | 462 | ||
469 | mcpdm->io_base = ioremap(res->start, resource_size(res)); | 463 | omap_mcpdm_dai_dma_params[0].dma_req = res->start; |
470 | if (!mcpdm->io_base) { | 464 | |
471 | ret = -ENOMEM; | 465 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "up_link"); |
472 | goto err_iomap; | 466 | if (!res) |
473 | } | 467 | return -ENODEV; |
468 | |||
469 | omap_mcpdm_dai_dma_params[1].dma_req = res->start; | ||
470 | |||
471 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); | ||
472 | if (res == NULL) | ||
473 | return -ENOMEM; | ||
474 | |||
475 | if (!devm_request_mem_region(&pdev->dev, res->start, | ||
476 | resource_size(res), "McPDM")) | ||
477 | return -EBUSY; | ||
478 | |||
479 | mcpdm->io_base = devm_ioremap(&pdev->dev, res->start, | ||
480 | resource_size(res)); | ||
481 | if (!mcpdm->io_base) | ||
482 | return -ENOMEM; | ||
474 | 483 | ||
475 | mcpdm->irq = platform_get_irq(pdev, 0); | 484 | mcpdm->irq = platform_get_irq(pdev, 0); |
476 | if (mcpdm->irq < 0) { | 485 | if (mcpdm->irq < 0) |
477 | ret = mcpdm->irq; | 486 | return mcpdm->irq; |
478 | goto err_irq; | ||
479 | } | ||
480 | 487 | ||
481 | mcpdm->dev = &pdev->dev; | 488 | mcpdm->dev = &pdev->dev; |
482 | 489 | ||
483 | ret = snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai); | 490 | return snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai); |
484 | if (!ret) | ||
485 | return 0; | ||
486 | |||
487 | err_irq: | ||
488 | iounmap(mcpdm->io_base); | ||
489 | err_iomap: | ||
490 | release_mem_region(res->start, resource_size(res)); | ||
491 | err_res: | ||
492 | kfree(mcpdm); | ||
493 | return ret; | ||
494 | } | 491 | } |
495 | 492 | ||
496 | static int __devexit asoc_mcpdm_remove(struct platform_device *pdev) | 493 | static int __devexit asoc_mcpdm_remove(struct platform_device *pdev) |
497 | { | 494 | { |
498 | struct omap_mcpdm *mcpdm = platform_get_drvdata(pdev); | ||
499 | struct resource *res; | ||
500 | |||
501 | snd_soc_unregister_dai(&pdev->dev); | 495 | snd_soc_unregister_dai(&pdev->dev); |
502 | |||
503 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
504 | iounmap(mcpdm->io_base); | ||
505 | release_mem_region(res->start, resource_size(res)); | ||
506 | |||
507 | kfree(mcpdm); | ||
508 | return 0; | 496 | return 0; |
509 | } | 497 | } |
510 | 498 | ||
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index f0feb06615f8..a2636f6b8362 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c | |||
@@ -25,12 +25,13 @@ | |||
25 | #include <linux/dma-mapping.h> | 25 | #include <linux/dma-mapping.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/omap-dma.h> | ||
28 | #include <sound/core.h> | 29 | #include <sound/core.h> |
29 | #include <sound/pcm.h> | 30 | #include <sound/pcm.h> |
30 | #include <sound/pcm_params.h> | 31 | #include <sound/pcm_params.h> |
32 | #include <sound/dmaengine_pcm.h> | ||
31 | #include <sound/soc.h> | 33 | #include <sound/soc.h> |
32 | 34 | ||
33 | #include <plat/dma.h> | ||
34 | #include "omap-pcm.h" | 35 | #include "omap-pcm.h" |
35 | 36 | ||
36 | static const struct snd_pcm_hardware omap_pcm_hardware = { | 37 | static const struct snd_pcm_hardware omap_pcm_hardware = { |
@@ -49,61 +50,34 @@ static const struct snd_pcm_hardware omap_pcm_hardware = { | |||
49 | .buffer_bytes_max = 128 * 1024, | 50 | .buffer_bytes_max = 128 * 1024, |
50 | }; | 51 | }; |
51 | 52 | ||
52 | struct omap_runtime_data { | 53 | static int omap_pcm_get_dma_buswidth(int num_bits) |
53 | spinlock_t lock; | ||
54 | struct omap_pcm_dma_data *dma_data; | ||
55 | int dma_ch; | ||
56 | int period_index; | ||
57 | }; | ||
58 | |||
59 | static void omap_pcm_dma_irq(int ch, u16 stat, void *data) | ||
60 | { | 54 | { |
61 | struct snd_pcm_substream *substream = data; | 55 | int buswidth; |
62 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
63 | struct omap_runtime_data *prtd = runtime->private_data; | ||
64 | unsigned long flags; | ||
65 | |||
66 | if ((cpu_is_omap1510())) { | ||
67 | /* | ||
68 | * OMAP1510 doesn't fully support DMA progress counter | ||
69 | * and there is no software emulation implemented yet, | ||
70 | * so have to maintain our own progress counters | ||
71 | * that can be used by omap_pcm_pointer() instead. | ||
72 | */ | ||
73 | spin_lock_irqsave(&prtd->lock, flags); | ||
74 | if ((stat == OMAP_DMA_LAST_IRQ) && | ||
75 | (prtd->period_index == runtime->periods - 1)) { | ||
76 | /* we are in sync, do nothing */ | ||
77 | spin_unlock_irqrestore(&prtd->lock, flags); | ||
78 | return; | ||
79 | } | ||
80 | if (prtd->period_index >= 0) { | ||
81 | if (stat & OMAP_DMA_BLOCK_IRQ) { | ||
82 | /* end of buffer reached, loop back */ | ||
83 | prtd->period_index = 0; | ||
84 | } else if (stat & OMAP_DMA_LAST_IRQ) { | ||
85 | /* update the counter for the last period */ | ||
86 | prtd->period_index = runtime->periods - 1; | ||
87 | } else if (++prtd->period_index >= runtime->periods) { | ||
88 | /* end of buffer missed? loop back */ | ||
89 | prtd->period_index = 0; | ||
90 | } | ||
91 | } | ||
92 | spin_unlock_irqrestore(&prtd->lock, flags); | ||
93 | } | ||
94 | 56 | ||
95 | snd_pcm_period_elapsed(substream); | 57 | switch (num_bits) { |
58 | case 16: | ||
59 | buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
60 | break; | ||
61 | case 32: | ||
62 | buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
63 | break; | ||
64 | default: | ||
65 | buswidth = -EINVAL; | ||
66 | break; | ||
67 | } | ||
68 | return buswidth; | ||
96 | } | 69 | } |
97 | 70 | ||
71 | |||
98 | /* this may get called several times by oss emulation */ | 72 | /* this may get called several times by oss emulation */ |
99 | static int omap_pcm_hw_params(struct snd_pcm_substream *substream, | 73 | static int omap_pcm_hw_params(struct snd_pcm_substream *substream, |
100 | struct snd_pcm_hw_params *params) | 74 | struct snd_pcm_hw_params *params) |
101 | { | 75 | { |
102 | struct snd_pcm_runtime *runtime = substream->runtime; | 76 | struct snd_pcm_runtime *runtime = substream->runtime; |
103 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 77 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
104 | struct omap_runtime_data *prtd = runtime->private_data; | ||
105 | struct omap_pcm_dma_data *dma_data; | 78 | struct omap_pcm_dma_data *dma_data; |
106 | 79 | struct dma_slave_config config; | |
80 | struct dma_chan *chan; | ||
107 | int err = 0; | 81 | int err = 0; |
108 | 82 | ||
109 | dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | 83 | dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
@@ -116,162 +90,78 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream, | |||
116 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | 90 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); |
117 | runtime->dma_bytes = params_buffer_bytes(params); | 91 | runtime->dma_bytes = params_buffer_bytes(params); |
118 | 92 | ||
119 | if (prtd->dma_data) | 93 | chan = snd_dmaengine_pcm_get_chan(substream); |
120 | return 0; | 94 | if (!chan) |
121 | prtd->dma_data = dma_data; | 95 | return -EINVAL; |
122 | err = omap_request_dma(dma_data->dma_req, dma_data->name, | ||
123 | omap_pcm_dma_irq, substream, &prtd->dma_ch); | ||
124 | if (!err) { | ||
125 | /* | ||
126 | * Link channel with itself so DMA doesn't need any | ||
127 | * reprogramming while looping the buffer | ||
128 | */ | ||
129 | omap_dma_link_lch(prtd->dma_ch, prtd->dma_ch); | ||
130 | } | ||
131 | 96 | ||
132 | return err; | 97 | /* fills in addr_width and direction */ |
133 | } | 98 | err = snd_hwparams_to_dma_slave_config(substream, params, &config); |
99 | if (err) | ||
100 | return err; | ||
134 | 101 | ||
135 | static int omap_pcm_hw_free(struct snd_pcm_substream *substream) | 102 | /* Override the *_dma addr_width if requested by the DAI driver */ |
136 | { | 103 | if (dma_data->data_type) { |
137 | struct snd_pcm_runtime *runtime = substream->runtime; | 104 | int buswidth = omap_pcm_get_dma_buswidth(dma_data->data_type); |
138 | struct omap_runtime_data *prtd = runtime->private_data; | ||
139 | 105 | ||
140 | if (prtd->dma_data == NULL) | 106 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
141 | return 0; | 107 | config.dst_addr_width = buswidth; |
142 | 108 | else | |
143 | omap_dma_unlink_lch(prtd->dma_ch, prtd->dma_ch); | 109 | config.src_addr_width = buswidth; |
144 | omap_free_dma(prtd->dma_ch); | 110 | } |
145 | prtd->dma_data = NULL; | ||
146 | 111 | ||
147 | snd_pcm_set_runtime_buffer(substream, NULL); | 112 | config.src_addr = dma_data->port_addr; |
113 | config.dst_addr = dma_data->port_addr; | ||
114 | config.src_maxburst = dma_data->packet_size; | ||
115 | config.dst_maxburst = dma_data->packet_size; | ||
148 | 116 | ||
149 | return 0; | 117 | return dmaengine_slave_config(chan, &config); |
150 | } | 118 | } |
151 | 119 | ||
152 | static int omap_pcm_prepare(struct snd_pcm_substream *substream) | 120 | static int omap_pcm_hw_free(struct snd_pcm_substream *substream) |
153 | { | 121 | { |
154 | struct snd_pcm_runtime *runtime = substream->runtime; | 122 | snd_pcm_set_runtime_buffer(substream, NULL); |
155 | struct omap_runtime_data *prtd = runtime->private_data; | ||
156 | struct omap_pcm_dma_data *dma_data = prtd->dma_data; | ||
157 | struct omap_dma_channel_params dma_params; | ||
158 | int bytes; | ||
159 | |||
160 | /* return if this is a bufferless transfer e.g. | ||
161 | * codec <--> BT codec or GSM modem -- lg FIXME */ | ||
162 | if (!prtd->dma_data) | ||
163 | return 0; | ||
164 | |||
165 | memset(&dma_params, 0, sizeof(dma_params)); | ||
166 | dma_params.data_type = dma_data->data_type; | ||
167 | dma_params.trigger = dma_data->dma_req; | ||
168 | dma_params.sync_mode = dma_data->sync_mode; | ||
169 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
170 | dma_params.src_amode = OMAP_DMA_AMODE_POST_INC; | ||
171 | dma_params.dst_amode = OMAP_DMA_AMODE_CONSTANT; | ||
172 | dma_params.src_or_dst_synch = OMAP_DMA_DST_SYNC; | ||
173 | dma_params.src_start = runtime->dma_addr; | ||
174 | dma_params.dst_start = dma_data->port_addr; | ||
175 | dma_params.dst_port = OMAP_DMA_PORT_MPUI; | ||
176 | dma_params.dst_fi = dma_data->packet_size; | ||
177 | } else { | ||
178 | dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT; | ||
179 | dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC; | ||
180 | dma_params.src_or_dst_synch = OMAP_DMA_SRC_SYNC; | ||
181 | dma_params.src_start = dma_data->port_addr; | ||
182 | dma_params.dst_start = runtime->dma_addr; | ||
183 | dma_params.src_port = OMAP_DMA_PORT_MPUI; | ||
184 | dma_params.src_fi = dma_data->packet_size; | ||
185 | } | ||
186 | /* | ||
187 | * Set DMA transfer frame size equal to ALSA period size and frame | ||
188 | * count as no. of ALSA periods. Then with DMA frame interrupt enabled, | ||
189 | * we can transfer the whole ALSA buffer with single DMA transfer but | ||
190 | * still can get an interrupt at each period bounary | ||
191 | */ | ||
192 | bytes = snd_pcm_lib_period_bytes(substream); | ||
193 | dma_params.elem_count = bytes >> dma_data->data_type; | ||
194 | dma_params.frame_count = runtime->periods; | ||
195 | omap_set_dma_params(prtd->dma_ch, &dma_params); | ||
196 | |||
197 | if ((cpu_is_omap1510())) | ||
198 | omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ | | ||
199 | OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); | ||
200 | else if (!substream->runtime->no_period_wakeup) | ||
201 | omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ); | ||
202 | else { | ||
203 | /* | ||
204 | * No period wakeup: | ||
205 | * we need to disable BLOCK_IRQ, which is enabled by the omap | ||
206 | * dma core at request dma time. | ||
207 | */ | ||
208 | omap_disable_dma_irq(prtd->dma_ch, OMAP_DMA_BLOCK_IRQ); | ||
209 | } | ||
210 | |||
211 | if (!(cpu_class_is_omap1())) { | ||
212 | omap_set_dma_src_burst_mode(prtd->dma_ch, | ||
213 | OMAP_DMA_DATA_BURST_16); | ||
214 | omap_set_dma_dest_burst_mode(prtd->dma_ch, | ||
215 | OMAP_DMA_DATA_BURST_16); | ||
216 | } | ||
217 | |||
218 | return 0; | 123 | return 0; |
219 | } | 124 | } |
220 | 125 | ||
221 | static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | 126 | static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) |
222 | { | 127 | { |
223 | struct snd_pcm_runtime *runtime = substream->runtime; | 128 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
224 | struct omap_runtime_data *prtd = runtime->private_data; | 129 | struct omap_pcm_dma_data *dma_data; |
225 | struct omap_pcm_dma_data *dma_data = prtd->dma_data; | ||
226 | unsigned long flags; | ||
227 | int ret = 0; | 130 | int ret = 0; |
228 | 131 | ||
229 | spin_lock_irqsave(&prtd->lock, flags); | 132 | dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
133 | |||
230 | switch (cmd) { | 134 | switch (cmd) { |
231 | case SNDRV_PCM_TRIGGER_START: | 135 | case SNDRV_PCM_TRIGGER_START: |
232 | case SNDRV_PCM_TRIGGER_RESUME: | 136 | case SNDRV_PCM_TRIGGER_RESUME: |
233 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 137 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
234 | prtd->period_index = 0; | ||
235 | /* Configure McBSP internal buffer usage */ | 138 | /* Configure McBSP internal buffer usage */ |
236 | if (dma_data->set_threshold) | 139 | if (dma_data->set_threshold) |
237 | dma_data->set_threshold(substream); | 140 | dma_data->set_threshold(substream); |
238 | |||
239 | omap_start_dma(prtd->dma_ch); | ||
240 | break; | 141 | break; |
241 | 142 | ||
242 | case SNDRV_PCM_TRIGGER_STOP: | 143 | case SNDRV_PCM_TRIGGER_STOP: |
243 | case SNDRV_PCM_TRIGGER_SUSPEND: | 144 | case SNDRV_PCM_TRIGGER_SUSPEND: |
244 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 145 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
245 | prtd->period_index = -1; | ||
246 | omap_stop_dma(prtd->dma_ch); | ||
247 | break; | 146 | break; |
248 | default: | 147 | default: |
249 | ret = -EINVAL; | 148 | ret = -EINVAL; |
250 | } | 149 | } |
251 | spin_unlock_irqrestore(&prtd->lock, flags); | 150 | |
151 | if (ret == 0) | ||
152 | ret = snd_dmaengine_pcm_trigger(substream, cmd); | ||
252 | 153 | ||
253 | return ret; | 154 | return ret; |
254 | } | 155 | } |
255 | 156 | ||
256 | static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) | 157 | static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) |
257 | { | 158 | { |
258 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
259 | struct omap_runtime_data *prtd = runtime->private_data; | ||
260 | dma_addr_t ptr; | ||
261 | snd_pcm_uframes_t offset; | 159 | snd_pcm_uframes_t offset; |
262 | 160 | ||
263 | if (cpu_is_omap1510()) { | 161 | if (cpu_is_omap1510()) |
264 | offset = prtd->period_index * runtime->period_size; | 162 | offset = snd_dmaengine_pcm_pointer_no_residue(substream); |
265 | } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | 163 | else |
266 | ptr = omap_get_dma_dst_pos(prtd->dma_ch); | 164 | offset = snd_dmaengine_pcm_pointer(substream); |
267 | offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); | ||
268 | } else { | ||
269 | ptr = omap_get_dma_src_pos(prtd->dma_ch); | ||
270 | offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); | ||
271 | } | ||
272 | |||
273 | if (offset >= runtime->buffer_size) | ||
274 | offset = 0; | ||
275 | 165 | ||
276 | return offset; | 166 | return offset; |
277 | } | 167 | } |
@@ -279,7 +169,8 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) | |||
279 | static int omap_pcm_open(struct snd_pcm_substream *substream) | 169 | static int omap_pcm_open(struct snd_pcm_substream *substream) |
280 | { | 170 | { |
281 | struct snd_pcm_runtime *runtime = substream->runtime; | 171 | struct snd_pcm_runtime *runtime = substream->runtime; |
282 | struct omap_runtime_data *prtd; | 172 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
173 | struct omap_pcm_dma_data *dma_data; | ||
283 | int ret; | 174 | int ret; |
284 | 175 | ||
285 | snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware); | 176 | snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware); |
@@ -288,25 +179,17 @@ static int omap_pcm_open(struct snd_pcm_substream *substream) | |||
288 | ret = snd_pcm_hw_constraint_integer(runtime, | 179 | ret = snd_pcm_hw_constraint_integer(runtime, |
289 | SNDRV_PCM_HW_PARAM_PERIODS); | 180 | SNDRV_PCM_HW_PARAM_PERIODS); |
290 | if (ret < 0) | 181 | if (ret < 0) |
291 | goto out; | 182 | return ret; |
292 | 183 | ||
293 | prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); | 184 | dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
294 | if (prtd == NULL) { | 185 | ret = snd_dmaengine_pcm_open(substream, omap_dma_filter_fn, |
295 | ret = -ENOMEM; | 186 | &dma_data->dma_req); |
296 | goto out; | ||
297 | } | ||
298 | spin_lock_init(&prtd->lock); | ||
299 | runtime->private_data = prtd; | ||
300 | |||
301 | out: | ||
302 | return ret; | 187 | return ret; |
303 | } | 188 | } |
304 | 189 | ||
305 | static int omap_pcm_close(struct snd_pcm_substream *substream) | 190 | static int omap_pcm_close(struct snd_pcm_substream *substream) |
306 | { | 191 | { |
307 | struct snd_pcm_runtime *runtime = substream->runtime; | 192 | snd_dmaengine_pcm_close(substream); |
308 | |||
309 | kfree(runtime->private_data); | ||
310 | return 0; | 193 | return 0; |
311 | } | 194 | } |
312 | 195 | ||
@@ -327,7 +210,6 @@ static struct snd_pcm_ops omap_pcm_ops = { | |||
327 | .ioctl = snd_pcm_lib_ioctl, | 210 | .ioctl = snd_pcm_lib_ioctl, |
328 | .hw_params = omap_pcm_hw_params, | 211 | .hw_params = omap_pcm_hw_params, |
329 | .hw_free = omap_pcm_hw_free, | 212 | .hw_free = omap_pcm_hw_free, |
330 | .prepare = omap_pcm_prepare, | ||
331 | .trigger = omap_pcm_trigger, | 213 | .trigger = omap_pcm_trigger, |
332 | .pointer = omap_pcm_pointer, | 214 | .pointer = omap_pcm_pointer, |
333 | .mmap = omap_pcm_mmap, | 215 | .mmap = omap_pcm_mmap, |
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h index b92248cbd47a..cabe74c4068b 100644 --- a/sound/soc/omap/omap-pcm.h +++ b/sound/soc/omap/omap-pcm.h | |||
@@ -32,8 +32,8 @@ struct omap_pcm_dma_data { | |||
32 | int dma_req; /* DMA request line */ | 32 | int dma_req; /* DMA request line */ |
33 | unsigned long port_addr; /* transmit/receive register */ | 33 | unsigned long port_addr; /* transmit/receive register */ |
34 | void (*set_threshold)(struct snd_pcm_substream *substream); | 34 | void (*set_threshold)(struct snd_pcm_substream *substream); |
35 | int data_type; /* data type 8,16,32 */ | 35 | int data_type; /* 8, 16, 32 (bits) or 0 to let omap-pcm |
36 | int sync_mode; /* DMA sync mode */ | 36 | * to decide the sDMA data type */ |
37 | int packet_size; /* packet size only in PACKET mode */ | 37 | int packet_size; /* packet size only in PACKET mode */ |
38 | }; | 38 | }; |
39 | 39 | ||
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c new file mode 100644 index 000000000000..3b97b87971f5 --- /dev/null +++ b/sound/soc/omap/omap-twl4030.c | |||
@@ -0,0 +1,188 @@ | |||
1 | /* | ||
2 | * omap-twl4030.c -- SoC audio for TI SoC based boards with twl4030 codec | ||
3 | * | ||
4 | * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Author: Peter Ujfalusi <peter.ujfalusi@ti.com> | ||
8 | * | ||
9 | * This driver replaces the following machine drivers: | ||
10 | * omap3beagle (Author: Steve Sakoman <steve@sakoman.com>) | ||
11 | * omap3evm (Author: Anuj Aggarwal <anuj.aggarwal@ti.com>) | ||
12 | * overo (Author: Steve Sakoman <steve@sakoman.com>) | ||
13 | * igep0020 (Author: Enric Balletbo i Serra <eballetbo@iseebcn.com>) | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License | ||
17 | * version 2 as published by the Free Software Foundation. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, but | ||
20 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
22 | * General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
27 | * 02110-1301 USA | ||
28 | * | ||
29 | */ | ||
30 | |||
31 | #include <linux/platform_device.h> | ||
32 | #include <linux/platform_data/omap-twl4030.h> | ||
33 | #include <linux/module.h> | ||
34 | #include <linux/of.h> | ||
35 | |||
36 | #include <sound/core.h> | ||
37 | #include <sound/pcm.h> | ||
38 | #include <sound/soc.h> | ||
39 | |||
40 | #include "omap-mcbsp.h" | ||
41 | #include "omap-pcm.h" | ||
42 | |||
43 | static int omap_twl4030_hw_params(struct snd_pcm_substream *substream, | ||
44 | struct snd_pcm_hw_params *params) | ||
45 | { | ||
46 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
47 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
48 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
49 | struct snd_soc_codec *codec = rtd->codec; | ||
50 | struct snd_soc_card *card = codec->card; | ||
51 | unsigned int fmt; | ||
52 | int ret; | ||
53 | |||
54 | switch (params_channels(params)) { | ||
55 | case 2: /* Stereo I2S mode */ | ||
56 | fmt = SND_SOC_DAIFMT_I2S | | ||
57 | SND_SOC_DAIFMT_NB_NF | | ||
58 | SND_SOC_DAIFMT_CBM_CFM; | ||
59 | break; | ||
60 | case 4: /* Four channel TDM mode */ | ||
61 | fmt = SND_SOC_DAIFMT_DSP_A | | ||
62 | SND_SOC_DAIFMT_IB_NF | | ||
63 | SND_SOC_DAIFMT_CBM_CFM; | ||
64 | break; | ||
65 | default: | ||
66 | return -EINVAL; | ||
67 | } | ||
68 | |||
69 | /* Set codec DAI configuration */ | ||
70 | ret = snd_soc_dai_set_fmt(codec_dai, fmt); | ||
71 | if (ret < 0) { | ||
72 | dev_err(card->dev, "can't set codec DAI configuration\n"); | ||
73 | return ret; | ||
74 | } | ||
75 | |||
76 | /* Set cpu DAI configuration */ | ||
77 | ret = snd_soc_dai_set_fmt(cpu_dai, fmt); | ||
78 | if (ret < 0) { | ||
79 | dev_err(card->dev, "can't set cpu DAI configuration\n"); | ||
80 | return ret; | ||
81 | } | ||
82 | |||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static struct snd_soc_ops omap_twl4030_ops = { | ||
87 | .hw_params = omap_twl4030_hw_params, | ||
88 | }; | ||
89 | |||
90 | /* Digital audio interface glue - connects codec <--> CPU */ | ||
91 | static struct snd_soc_dai_link omap_twl4030_dai_links[] = { | ||
92 | { | ||
93 | .name = "TWL4030", | ||
94 | .stream_name = "TWL4030", | ||
95 | .cpu_dai_name = "omap-mcbsp.2", | ||
96 | .codec_dai_name = "twl4030-hifi", | ||
97 | .platform_name = "omap-pcm-audio", | ||
98 | .codec_name = "twl4030-codec", | ||
99 | .ops = &omap_twl4030_ops, | ||
100 | }, | ||
101 | }; | ||
102 | |||
103 | /* Audio machine driver */ | ||
104 | static struct snd_soc_card omap_twl4030_card = { | ||
105 | .owner = THIS_MODULE, | ||
106 | .dai_link = omap_twl4030_dai_links, | ||
107 | .num_links = ARRAY_SIZE(omap_twl4030_dai_links), | ||
108 | }; | ||
109 | |||
110 | static __devinit int omap_twl4030_probe(struct platform_device *pdev) | ||
111 | { | ||
112 | struct omap_tw4030_pdata *pdata = dev_get_platdata(&pdev->dev); | ||
113 | struct device_node *node = pdev->dev.of_node; | ||
114 | struct snd_soc_card *card = &omap_twl4030_card; | ||
115 | int ret = 0; | ||
116 | |||
117 | card->dev = &pdev->dev; | ||
118 | |||
119 | if (node) { | ||
120 | struct device_node *dai_node; | ||
121 | |||
122 | if (snd_soc_of_parse_card_name(card, "ti,model")) { | ||
123 | dev_err(&pdev->dev, "Card name is not provided\n"); | ||
124 | return -ENODEV; | ||
125 | } | ||
126 | |||
127 | dai_node = of_parse_phandle(node, "ti,mcbsp", 0); | ||
128 | if (!dai_node) { | ||
129 | dev_err(&pdev->dev, "McBSP node is not provided\n"); | ||
130 | return -EINVAL; | ||
131 | } | ||
132 | omap_twl4030_dai_links[0].cpu_dai_name = NULL; | ||
133 | omap_twl4030_dai_links[0].cpu_of_node = dai_node; | ||
134 | |||
135 | } else if (pdata) { | ||
136 | if (pdata->card_name) { | ||
137 | card->name = pdata->card_name; | ||
138 | } else { | ||
139 | dev_err(&pdev->dev, "Card name is not provided\n"); | ||
140 | return -ENODEV; | ||
141 | } | ||
142 | } else { | ||
143 | dev_err(&pdev->dev, "Missing pdata\n"); | ||
144 | return -ENODEV; | ||
145 | } | ||
146 | |||
147 | ret = snd_soc_register_card(card); | ||
148 | if (ret) { | ||
149 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", | ||
150 | ret); | ||
151 | return ret; | ||
152 | } | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static int __devexit omap_twl4030_remove(struct platform_device *pdev) | ||
158 | { | ||
159 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
160 | |||
161 | snd_soc_unregister_card(card); | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static const struct of_device_id omap_twl4030_of_match[] = { | ||
167 | {.compatible = "ti,omap-twl4030", }, | ||
168 | { }, | ||
169 | }; | ||
170 | MODULE_DEVICE_TABLE(of, omap_twl4030_of_match); | ||
171 | |||
172 | static struct platform_driver omap_twl4030_driver = { | ||
173 | .driver = { | ||
174 | .name = "omap-twl4030", | ||
175 | .owner = THIS_MODULE, | ||
176 | .pm = &snd_soc_pm_ops, | ||
177 | .of_match_table = omap_twl4030_of_match, | ||
178 | }, | ||
179 | .probe = omap_twl4030_probe, | ||
180 | .remove = __devexit_p(omap_twl4030_remove), | ||
181 | }; | ||
182 | |||
183 | module_platform_driver(omap_twl4030_driver); | ||
184 | |||
185 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); | ||
186 | MODULE_DESCRIPTION("ALSA SoC for TI SoC based boards with twl4030 codec"); | ||
187 | MODULE_LICENSE("GPL"); | ||
188 | MODULE_ALIAS("platform:omap-twl4030"); | ||
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c deleted file mode 100644 index 2830dfd05661..000000000000 --- a/sound/soc/omap/omap3beagle.c +++ /dev/null | |||
@@ -1,150 +0,0 @@ | |||
1 | /* | ||
2 | * omap3beagle.c -- SoC audio for OMAP3 Beagle | ||
3 | * | ||
4 | * Author: Steve Sakoman <steve@sakoman.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/clk.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <sound/core.h> | ||
26 | #include <sound/pcm.h> | ||
27 | #include <sound/soc.h> | ||
28 | |||
29 | #include <asm/mach-types.h> | ||
30 | #include <mach/hardware.h> | ||
31 | #include <mach/gpio.h> | ||
32 | #include <plat/mcbsp.h> | ||
33 | |||
34 | #include "omap-mcbsp.h" | ||
35 | #include "omap-pcm.h" | ||
36 | |||
37 | static int omap3beagle_hw_params(struct snd_pcm_substream *substream, | ||
38 | struct snd_pcm_hw_params *params) | ||
39 | { | ||
40 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
41 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
42 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
43 | unsigned int fmt; | ||
44 | int ret; | ||
45 | |||
46 | switch (params_channels(params)) { | ||
47 | case 2: /* Stereo I2S mode */ | ||
48 | fmt = SND_SOC_DAIFMT_I2S | | ||
49 | SND_SOC_DAIFMT_NB_NF | | ||
50 | SND_SOC_DAIFMT_CBM_CFM; | ||
51 | break; | ||
52 | case 4: /* Four channel TDM mode */ | ||
53 | fmt = SND_SOC_DAIFMT_DSP_A | | ||
54 | SND_SOC_DAIFMT_IB_NF | | ||
55 | SND_SOC_DAIFMT_CBM_CFM; | ||
56 | break; | ||
57 | default: | ||
58 | return -EINVAL; | ||
59 | } | ||
60 | |||
61 | /* Set codec DAI configuration */ | ||
62 | ret = snd_soc_dai_set_fmt(codec_dai, fmt); | ||
63 | if (ret < 0) { | ||
64 | printk(KERN_ERR "can't set codec DAI configuration\n"); | ||
65 | return ret; | ||
66 | } | ||
67 | |||
68 | /* Set cpu DAI configuration */ | ||
69 | ret = snd_soc_dai_set_fmt(cpu_dai, fmt); | ||
70 | if (ret < 0) { | ||
71 | printk(KERN_ERR "can't set cpu DAI configuration\n"); | ||
72 | return ret; | ||
73 | } | ||
74 | |||
75 | /* Set the codec system clock for DAC and ADC */ | ||
76 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, | ||
77 | SND_SOC_CLOCK_IN); | ||
78 | if (ret < 0) { | ||
79 | printk(KERN_ERR "can't set codec system clock\n"); | ||
80 | return ret; | ||
81 | } | ||
82 | |||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static struct snd_soc_ops omap3beagle_ops = { | ||
87 | .hw_params = omap3beagle_hw_params, | ||
88 | }; | ||
89 | |||
90 | /* Digital audio interface glue - connects codec <--> CPU */ | ||
91 | static struct snd_soc_dai_link omap3beagle_dai = { | ||
92 | .name = "TWL4030", | ||
93 | .stream_name = "TWL4030", | ||
94 | .cpu_dai_name = "omap-mcbsp.2", | ||
95 | .platform_name = "omap-pcm-audio", | ||
96 | .codec_dai_name = "twl4030-hifi", | ||
97 | .codec_name = "twl4030-codec", | ||
98 | .ops = &omap3beagle_ops, | ||
99 | }; | ||
100 | |||
101 | /* Audio machine driver */ | ||
102 | static struct snd_soc_card snd_soc_omap3beagle = { | ||
103 | .name = "omap3beagle", | ||
104 | .owner = THIS_MODULE, | ||
105 | .dai_link = &omap3beagle_dai, | ||
106 | .num_links = 1, | ||
107 | }; | ||
108 | |||
109 | static struct platform_device *omap3beagle_snd_device; | ||
110 | |||
111 | static int __init omap3beagle_soc_init(void) | ||
112 | { | ||
113 | int ret; | ||
114 | |||
115 | if (!(machine_is_omap3_beagle() || machine_is_devkit8000())) | ||
116 | return -ENODEV; | ||
117 | pr_info("OMAP3 Beagle/Devkit8000 SoC init\n"); | ||
118 | |||
119 | omap3beagle_snd_device = platform_device_alloc("soc-audio", -1); | ||
120 | if (!omap3beagle_snd_device) { | ||
121 | printk(KERN_ERR "Platform device allocation failed\n"); | ||
122 | return -ENOMEM; | ||
123 | } | ||
124 | |||
125 | platform_set_drvdata(omap3beagle_snd_device, &snd_soc_omap3beagle); | ||
126 | |||
127 | ret = platform_device_add(omap3beagle_snd_device); | ||
128 | if (ret) | ||
129 | goto err1; | ||
130 | |||
131 | return 0; | ||
132 | |||
133 | err1: | ||
134 | printk(KERN_ERR "Unable to add platform device\n"); | ||
135 | platform_device_put(omap3beagle_snd_device); | ||
136 | |||
137 | return ret; | ||
138 | } | ||
139 | |||
140 | static void __exit omap3beagle_soc_exit(void) | ||
141 | { | ||
142 | platform_device_unregister(omap3beagle_snd_device); | ||
143 | } | ||
144 | |||
145 | module_init(omap3beagle_soc_init); | ||
146 | module_exit(omap3beagle_soc_exit); | ||
147 | |||
148 | MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>"); | ||
149 | MODULE_DESCRIPTION("ALSA SoC OMAP3 Beagle"); | ||
150 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c deleted file mode 100644 index 3d468c9179d7..000000000000 --- a/sound/soc/omap/omap3evm.c +++ /dev/null | |||
@@ -1,118 +0,0 @@ | |||
1 | /* | ||
2 | * omap3evm.c -- ALSA SoC support for OMAP3 EVM | ||
3 | * | ||
4 | * Author: Anuj Aggarwal <anuj.aggarwal@ti.com> | ||
5 | * | ||
6 | * Based on sound/soc/omap/beagle.c by Steve Sakoman | ||
7 | * | ||
8 | * Copyright (C) 2008 Texas Instruments, Incorporated | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation version 2. | ||
13 | * | ||
14 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, | ||
15 | * whether express or implied; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | #include <linux/clk.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <sound/core.h> | ||
24 | #include <sound/pcm.h> | ||
25 | #include <sound/soc.h> | ||
26 | |||
27 | #include <asm/mach-types.h> | ||
28 | #include <mach/hardware.h> | ||
29 | #include <mach/gpio.h> | ||
30 | #include <plat/mcbsp.h> | ||
31 | |||
32 | #include "omap-mcbsp.h" | ||
33 | #include "omap-pcm.h" | ||
34 | |||
35 | static int omap3evm_hw_params(struct snd_pcm_substream *substream, | ||
36 | struct snd_pcm_hw_params *params) | ||
37 | { | ||
38 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
39 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
40 | int ret; | ||
41 | |||
42 | /* Set the codec system clock for DAC and ADC */ | ||
43 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, | ||
44 | SND_SOC_CLOCK_IN); | ||
45 | if (ret < 0) { | ||
46 | printk(KERN_ERR "Can't set codec system clock\n"); | ||
47 | return ret; | ||
48 | } | ||
49 | |||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | static struct snd_soc_ops omap3evm_ops = { | ||
54 | .hw_params = omap3evm_hw_params, | ||
55 | }; | ||
56 | |||
57 | /* Digital audio interface glue - connects codec <--> CPU */ | ||
58 | static struct snd_soc_dai_link omap3evm_dai = { | ||
59 | .name = "TWL4030", | ||
60 | .stream_name = "TWL4030", | ||
61 | .cpu_dai_name = "omap-mcbsp.2", | ||
62 | .codec_dai_name = "twl4030-hifi", | ||
63 | .platform_name = "omap-pcm-audio", | ||
64 | .codec_name = "twl4030-codec", | ||
65 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
66 | SND_SOC_DAIFMT_CBM_CFM, | ||
67 | .ops = &omap3evm_ops, | ||
68 | }; | ||
69 | |||
70 | /* Audio machine driver */ | ||
71 | static struct snd_soc_card snd_soc_omap3evm = { | ||
72 | .name = "omap3evm", | ||
73 | .owner = THIS_MODULE, | ||
74 | .dai_link = &omap3evm_dai, | ||
75 | .num_links = 1, | ||
76 | }; | ||
77 | |||
78 | static struct platform_device *omap3evm_snd_device; | ||
79 | |||
80 | static int __init omap3evm_soc_init(void) | ||
81 | { | ||
82 | int ret; | ||
83 | |||
84 | if (!machine_is_omap3evm()) | ||
85 | return -ENODEV; | ||
86 | pr_info("OMAP3 EVM SoC init\n"); | ||
87 | |||
88 | omap3evm_snd_device = platform_device_alloc("soc-audio", -1); | ||
89 | if (!omap3evm_snd_device) { | ||
90 | printk(KERN_ERR "Platform device allocation failed\n"); | ||
91 | return -ENOMEM; | ||
92 | } | ||
93 | |||
94 | platform_set_drvdata(omap3evm_snd_device, &snd_soc_omap3evm); | ||
95 | ret = platform_device_add(omap3evm_snd_device); | ||
96 | if (ret) | ||
97 | goto err1; | ||
98 | |||
99 | return 0; | ||
100 | |||
101 | err1: | ||
102 | printk(KERN_ERR "Unable to add platform device\n"); | ||
103 | platform_device_put(omap3evm_snd_device); | ||
104 | |||
105 | return ret; | ||
106 | } | ||
107 | |||
108 | static void __exit omap3evm_soc_exit(void) | ||
109 | { | ||
110 | platform_device_unregister(omap3evm_snd_device); | ||
111 | } | ||
112 | |||
113 | module_init(omap3evm_soc_init); | ||
114 | module_exit(omap3evm_soc_exit); | ||
115 | |||
116 | MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>"); | ||
117 | MODULE_DESCRIPTION("ALSA SoC OMAP3 EVM"); | ||
118 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c deleted file mode 100644 index 6ac3e0c3c282..000000000000 --- a/sound/soc/omap/overo.c +++ /dev/null | |||
@@ -1,122 +0,0 @@ | |||
1 | /* | ||
2 | * overo.c -- SoC audio for Gumstix Overo | ||
3 | * | ||
4 | * Author: Steve Sakoman <steve@sakoman.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/clk.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <sound/core.h> | ||
26 | #include <sound/pcm.h> | ||
27 | #include <sound/soc.h> | ||
28 | |||
29 | #include <asm/mach-types.h> | ||
30 | #include <mach/hardware.h> | ||
31 | #include <mach/gpio.h> | ||
32 | #include <plat/mcbsp.h> | ||
33 | |||
34 | #include "omap-mcbsp.h" | ||
35 | #include "omap-pcm.h" | ||
36 | |||
37 | static int overo_hw_params(struct snd_pcm_substream *substream, | ||
38 | struct snd_pcm_hw_params *params) | ||
39 | { | ||
40 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
41 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
42 | int ret; | ||
43 | |||
44 | /* Set the codec system clock for DAC and ADC */ | ||
45 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, | ||
46 | SND_SOC_CLOCK_IN); | ||
47 | if (ret < 0) { | ||
48 | printk(KERN_ERR "can't set codec system clock\n"); | ||
49 | return ret; | ||
50 | } | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static struct snd_soc_ops overo_ops = { | ||
56 | .hw_params = overo_hw_params, | ||
57 | }; | ||
58 | |||
59 | /* Digital audio interface glue - connects codec <--> CPU */ | ||
60 | static struct snd_soc_dai_link overo_dai = { | ||
61 | .name = "TWL4030", | ||
62 | .stream_name = "TWL4030", | ||
63 | .cpu_dai_name = "omap-mcbsp.2", | ||
64 | .codec_dai_name = "twl4030-hifi", | ||
65 | .platform_name = "omap-pcm-audio", | ||
66 | .codec_name = "twl4030-codec", | ||
67 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
68 | SND_SOC_DAIFMT_CBM_CFM, | ||
69 | .ops = &overo_ops, | ||
70 | }; | ||
71 | |||
72 | /* Audio machine driver */ | ||
73 | static struct snd_soc_card snd_soc_card_overo = { | ||
74 | .name = "overo", | ||
75 | .owner = THIS_MODULE, | ||
76 | .dai_link = &overo_dai, | ||
77 | .num_links = 1, | ||
78 | }; | ||
79 | |||
80 | static struct platform_device *overo_snd_device; | ||
81 | |||
82 | static int __init overo_soc_init(void) | ||
83 | { | ||
84 | int ret; | ||
85 | |||
86 | if (!(machine_is_overo() || machine_is_cm_t35())) { | ||
87 | pr_debug("Incomatible machine!\n"); | ||
88 | return -ENODEV; | ||
89 | } | ||
90 | printk(KERN_INFO "overo SoC init\n"); | ||
91 | |||
92 | overo_snd_device = platform_device_alloc("soc-audio", -1); | ||
93 | if (!overo_snd_device) { | ||
94 | printk(KERN_ERR "Platform device allocation failed\n"); | ||
95 | return -ENOMEM; | ||
96 | } | ||
97 | |||
98 | platform_set_drvdata(overo_snd_device, &snd_soc_card_overo); | ||
99 | |||
100 | ret = platform_device_add(overo_snd_device); | ||
101 | if (ret) | ||
102 | goto err1; | ||
103 | |||
104 | return 0; | ||
105 | |||
106 | err1: | ||
107 | printk(KERN_ERR "Unable to add platform device\n"); | ||
108 | platform_device_put(overo_snd_device); | ||
109 | |||
110 | return ret; | ||
111 | } | ||
112 | module_init(overo_soc_init); | ||
113 | |||
114 | static void __exit overo_soc_exit(void) | ||
115 | { | ||
116 | platform_device_unregister(overo_snd_device); | ||
117 | } | ||
118 | module_exit(overo_soc_exit); | ||
119 | |||
120 | MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>"); | ||
121 | MODULE_DESCRIPTION("ALSA SoC overo"); | ||
122 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c index 920e0d9e03db..df97a4196cd3 100644 --- a/sound/soc/omap/zoom2.c +++ b/sound/soc/omap/zoom2.c | |||
@@ -191,9 +191,6 @@ static int __init zoom2_soc_init(void) | |||
191 | BUG_ON(gpio_request(ZOOM2_HEADSET_MUX_GPIO, "hs_mux") < 0); | 191 | BUG_ON(gpio_request(ZOOM2_HEADSET_MUX_GPIO, "hs_mux") < 0); |
192 | gpio_direction_output(ZOOM2_HEADSET_MUX_GPIO, 0); | 192 | gpio_direction_output(ZOOM2_HEADSET_MUX_GPIO, 0); |
193 | 193 | ||
194 | BUG_ON(gpio_request(ZOOM2_HEADSET_EXTMUTE_GPIO, "ext_mute") < 0); | ||
195 | gpio_direction_output(ZOOM2_HEADSET_EXTMUTE_GPIO, 0); | ||
196 | |||
197 | return 0; | 194 | return 0; |
198 | 195 | ||
199 | err1: | 196 | err1: |
@@ -207,7 +204,6 @@ module_init(zoom2_soc_init); | |||
207 | static void __exit zoom2_soc_exit(void) | 204 | static void __exit zoom2_soc_exit(void) |
208 | { | 205 | { |
209 | gpio_free(ZOOM2_HEADSET_MUX_GPIO); | 206 | gpio_free(ZOOM2_HEADSET_MUX_GPIO); |
210 | gpio_free(ZOOM2_HEADSET_EXTMUTE_GPIO); | ||
211 | 207 | ||
212 | platform_device_unregister(zoom2_snd_device); | 208 | platform_device_unregister(zoom2_snd_device); |
213 | } | 209 | } |
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index fe3995ce9b38..e7b83179aca2 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config SND_SOC_SAMSUNG | 1 | config SND_SOC_SAMSUNG |
2 | tristate "ASoC support for Samsung" | 2 | tristate "ASoC support for Samsung" |
3 | depends on ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_EXYNOS4 | 3 | depends on PLAT_SAMSUNG |
4 | select S3C64XX_DMA if ARCH_S3C64XX | 4 | select S3C64XX_DMA if ARCH_S3C64XX |
5 | select S3C2410_DMA if ARCH_S3C24XX | 5 | select S3C2410_DMA if ARCH_S3C24XX |
6 | help | 6 | help |
@@ -191,6 +191,7 @@ config SND_SOC_SPEYSIDE | |||
191 | select SND_SAMSUNG_I2S | 191 | select SND_SAMSUNG_I2S |
192 | select SND_SOC_WM8996 | 192 | select SND_SOC_WM8996 |
193 | select SND_SOC_WM9081 | 193 | select SND_SOC_WM9081 |
194 | select SND_SOC_WM0010 | ||
194 | select SND_SOC_WM1250_EV1 | 195 | select SND_SOC_WM1250_EV1 |
195 | 196 | ||
196 | config SND_SOC_TOBERMORY | 197 | config SND_SOC_TOBERMORY |
@@ -199,6 +200,14 @@ config SND_SOC_TOBERMORY | |||
199 | select SND_SAMSUNG_I2S | 200 | select SND_SAMSUNG_I2S |
200 | select SND_SOC_WM8962 | 201 | select SND_SOC_WM8962 |
201 | 202 | ||
203 | config SND_SOC_BELLS | ||
204 | tristate "Audio support for Wolfson Bells" | ||
205 | depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 | ||
206 | select SND_SAMSUNG_I2S | ||
207 | select SND_SOC_WM5102 | ||
208 | select SND_SOC_WM5110 | ||
209 | select SND_SOC_WM9081 | ||
210 | |||
202 | config SND_SOC_LOWLAND | 211 | config SND_SOC_LOWLAND |
203 | tristate "Audio support for Wolfson Lowland" | 212 | tristate "Audio support for Wolfson Lowland" |
204 | depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 | 213 | depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 |
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 9d03beb40c86..709f6059ad67 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile | |||
@@ -42,6 +42,7 @@ snd-soc-speyside-objs := speyside.o | |||
42 | snd-soc-tobermory-objs := tobermory.o | 42 | snd-soc-tobermory-objs := tobermory.o |
43 | snd-soc-lowland-objs := lowland.o | 43 | snd-soc-lowland-objs := lowland.o |
44 | snd-soc-littlemill-objs := littlemill.o | 44 | snd-soc-littlemill-objs := littlemill.o |
45 | snd-soc-bells-objs := bells.o | ||
45 | 46 | ||
46 | obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o | 47 | obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o |
47 | obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o | 48 | obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o |
@@ -65,3 +66,4 @@ obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o | |||
65 | obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o | 66 | obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o |
66 | obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o | 67 | obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o |
67 | obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o | 68 | obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o |
69 | obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o | ||
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c new file mode 100644 index 000000000000..5dc10dfc0d42 --- /dev/null +++ b/sound/soc/samsung/bells.c | |||
@@ -0,0 +1,346 @@ | |||
1 | /* | ||
2 | * Bells audio support | ||
3 | * | ||
4 | * Copyright 2012 Wolfson Microelectronics | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <sound/soc.h> | ||
13 | #include <sound/soc-dapm.h> | ||
14 | #include <sound/jack.h> | ||
15 | #include <linux/gpio.h> | ||
16 | #include <linux/module.h> | ||
17 | |||
18 | #include "../codecs/wm5102.h" | ||
19 | #include "../codecs/wm9081.h" | ||
20 | |||
21 | /* | ||
22 | * 44.1kHz based clocks for the SYSCLK domain, use a very high clock | ||
23 | * to allow all the DSP functionality to be enabled if desired. | ||
24 | */ | ||
25 | #define SYSCLK_RATE (44100 * 1024) | ||
26 | |||
27 | /* 48kHz based clocks for the ASYNC domain */ | ||
28 | #define ASYNCCLK_RATE (48000 * 512) | ||
29 | |||
30 | /* BCLK2 is fixed at this currently */ | ||
31 | #define BCLK2_RATE (64 * 8000) | ||
32 | |||
33 | /* | ||
34 | * Expect a 24.576MHz crystal if one is fitted (the driver will function | ||
35 | * if this is not fitted). | ||
36 | */ | ||
37 | #define MCLK_RATE 24576000 | ||
38 | |||
39 | #define WM9081_AUDIO_RATE 44100 | ||
40 | #define WM9081_MCLK_RATE (WM9081_AUDIO_RATE * 256) | ||
41 | |||
42 | static int bells_set_bias_level(struct snd_soc_card *card, | ||
43 | struct snd_soc_dapm_context *dapm, | ||
44 | enum snd_soc_bias_level level) | ||
45 | { | ||
46 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | ||
47 | struct snd_soc_codec *codec = codec_dai->codec; | ||
48 | int ret; | ||
49 | |||
50 | if (dapm->dev != codec_dai->dev) | ||
51 | return 0; | ||
52 | |||
53 | switch (level) { | ||
54 | case SND_SOC_BIAS_PREPARE: | ||
55 | if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { | ||
56 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, | ||
57 | ARIZONA_FLL_SRC_MCLK1, | ||
58 | MCLK_RATE, | ||
59 | SYSCLK_RATE); | ||
60 | if (ret < 0) | ||
61 | pr_err("Failed to start FLL: %d\n", ret); | ||
62 | |||
63 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, | ||
64 | ARIZONA_FLL_SRC_AIF2BCLK, | ||
65 | BCLK2_RATE, | ||
66 | ASYNCCLK_RATE); | ||
67 | if (ret < 0) | ||
68 | pr_err("Failed to start FLL: %d\n", ret); | ||
69 | } | ||
70 | break; | ||
71 | |||
72 | default: | ||
73 | break; | ||
74 | } | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static int bells_set_bias_level_post(struct snd_soc_card *card, | ||
80 | struct snd_soc_dapm_context *dapm, | ||
81 | enum snd_soc_bias_level level) | ||
82 | { | ||
83 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | ||
84 | struct snd_soc_codec *codec = codec_dai->codec; | ||
85 | int ret; | ||
86 | |||
87 | if (dapm->dev != codec_dai->dev) | ||
88 | return 0; | ||
89 | |||
90 | switch (level) { | ||
91 | case SND_SOC_BIAS_STANDBY: | ||
92 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, 0, 0, 0); | ||
93 | if (ret < 0) { | ||
94 | pr_err("Failed to stop FLL: %d\n", ret); | ||
95 | return ret; | ||
96 | } | ||
97 | |||
98 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, 0, 0, 0); | ||
99 | if (ret < 0) { | ||
100 | pr_err("Failed to stop FLL: %d\n", ret); | ||
101 | return ret; | ||
102 | } | ||
103 | break; | ||
104 | |||
105 | default: | ||
106 | break; | ||
107 | } | ||
108 | |||
109 | dapm->bias_level = level; | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int bells_late_probe(struct snd_soc_card *card) | ||
115 | { | ||
116 | struct snd_soc_codec *codec = card->rtd[0].codec; | ||
117 | struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai; | ||
118 | struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai; | ||
119 | struct snd_soc_dai *aif3_dai = card->rtd[2].cpu_dai; | ||
120 | struct snd_soc_dai *wm9081_dai = card->rtd[2].codec_dai; | ||
121 | int ret; | ||
122 | |||
123 | ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0); | ||
124 | if (ret != 0) { | ||
125 | dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); | ||
126 | return ret; | ||
127 | } | ||
128 | |||
129 | ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0); | ||
130 | if (ret != 0) { | ||
131 | dev_err(aif2_dai->dev, "Failed to set AIF2 clock: %d\n", ret); | ||
132 | return ret; | ||
133 | } | ||
134 | |||
135 | ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0); | ||
136 | if (ret != 0) { | ||
137 | dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); | ||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK, | ||
142 | ARIZONA_CLK_SRC_FLL1, SYSCLK_RATE, | ||
143 | SND_SOC_CLOCK_IN); | ||
144 | if (ret != 0) { | ||
145 | dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret); | ||
146 | return ret; | ||
147 | } | ||
148 | |||
149 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_OPCLK, 0, | ||
150 | WM9081_MCLK_RATE, SND_SOC_CLOCK_OUT); | ||
151 | if (ret != 0) { | ||
152 | dev_err(codec->dev, "Failed to set OPCLK: %d\n", ret); | ||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK, | ||
157 | ARIZONA_CLK_SRC_FLL2, ASYNCCLK_RATE, | ||
158 | SND_SOC_CLOCK_IN); | ||
159 | if (ret != 0) { | ||
160 | dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret); | ||
161 | return ret; | ||
162 | } | ||
163 | |||
164 | ret = snd_soc_codec_set_sysclk(wm9081_dai->codec, WM9081_SYSCLK_MCLK, | ||
165 | 0, WM9081_MCLK_RATE, 0); | ||
166 | if (ret != 0) { | ||
167 | dev_err(wm9081_dai->dev, "Failed to set MCLK: %d\n", ret); | ||
168 | return ret; | ||
169 | } | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | static const struct snd_soc_pcm_stream baseband_params = { | ||
175 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | ||
176 | .rate_min = 8000, | ||
177 | .rate_max = 8000, | ||
178 | .channels_min = 2, | ||
179 | .channels_max = 2, | ||
180 | }; | ||
181 | |||
182 | static const struct snd_soc_pcm_stream sub_params = { | ||
183 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | ||
184 | .rate_min = WM9081_AUDIO_RATE, | ||
185 | .rate_max = WM9081_AUDIO_RATE, | ||
186 | .channels_min = 2, | ||
187 | .channels_max = 2, | ||
188 | }; | ||
189 | |||
190 | static struct snd_soc_dai_link bells_dai_wm5102[] = { | ||
191 | { | ||
192 | .name = "CPU", | ||
193 | .stream_name = "CPU", | ||
194 | .cpu_dai_name = "samsung-i2s.0", | ||
195 | .codec_dai_name = "wm5102-aif1", | ||
196 | .platform_name = "samsung-audio", | ||
197 | .codec_name = "wm5102-codec", | ||
198 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
199 | | SND_SOC_DAIFMT_CBM_CFM, | ||
200 | }, | ||
201 | { | ||
202 | .name = "Baseband", | ||
203 | .stream_name = "Baseband", | ||
204 | .cpu_dai_name = "wm5102-aif2", | ||
205 | .codec_dai_name = "wm1250-ev1", | ||
206 | .codec_name = "wm1250-ev1.1-0027", | ||
207 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
208 | | SND_SOC_DAIFMT_CBM_CFM, | ||
209 | .ignore_suspend = 1, | ||
210 | .params = &baseband_params, | ||
211 | }, | ||
212 | { | ||
213 | .name = "Sub", | ||
214 | .stream_name = "Sub", | ||
215 | .cpu_dai_name = "wm5102-aif3", | ||
216 | .codec_dai_name = "wm9081-hifi", | ||
217 | .codec_name = "wm9081.1-006c", | ||
218 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
219 | | SND_SOC_DAIFMT_CBS_CFS, | ||
220 | .ignore_suspend = 1, | ||
221 | .params = &sub_params, | ||
222 | }, | ||
223 | }; | ||
224 | |||
225 | static struct snd_soc_dai_link bells_dai_wm5110[] = { | ||
226 | { | ||
227 | .name = "CPU", | ||
228 | .stream_name = "CPU", | ||
229 | .cpu_dai_name = "samsung-i2s.0", | ||
230 | .codec_dai_name = "wm5110-aif1", | ||
231 | .platform_name = "samsung-audio", | ||
232 | .codec_name = "wm5110-codec", | ||
233 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
234 | | SND_SOC_DAIFMT_CBM_CFM, | ||
235 | }, | ||
236 | { | ||
237 | .name = "Baseband", | ||
238 | .stream_name = "Baseband", | ||
239 | .cpu_dai_name = "wm5110-aif2", | ||
240 | .codec_dai_name = "wm1250-ev1", | ||
241 | .codec_name = "wm1250-ev1.1-0027", | ||
242 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
243 | | SND_SOC_DAIFMT_CBM_CFM, | ||
244 | .ignore_suspend = 1, | ||
245 | .params = &baseband_params, | ||
246 | }, | ||
247 | { | ||
248 | .name = "Sub", | ||
249 | .stream_name = "Sub", | ||
250 | .cpu_dai_name = "wm5102-aif3", | ||
251 | .codec_dai_name = "wm9081-hifi", | ||
252 | .codec_name = "wm9081.1-006c", | ||
253 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
254 | | SND_SOC_DAIFMT_CBS_CFS, | ||
255 | .ignore_suspend = 1, | ||
256 | .params = &sub_params, | ||
257 | }, | ||
258 | }; | ||
259 | |||
260 | static struct snd_soc_codec_conf bells_codec_conf[] = { | ||
261 | { | ||
262 | .dev_name = "wm9081.1-006c", | ||
263 | .name_prefix = "Sub", | ||
264 | }, | ||
265 | }; | ||
266 | |||
267 | static struct snd_soc_dapm_route bells_routes[] = { | ||
268 | { "Sub CLK_SYS", NULL, "OPCLK" }, | ||
269 | }; | ||
270 | |||
271 | static struct snd_soc_card bells_cards[] = { | ||
272 | { | ||
273 | .name = "Bells WM5102", | ||
274 | .owner = THIS_MODULE, | ||
275 | .dai_link = bells_dai_wm5102, | ||
276 | .num_links = ARRAY_SIZE(bells_dai_wm5102), | ||
277 | .codec_conf = bells_codec_conf, | ||
278 | .num_configs = ARRAY_SIZE(bells_codec_conf), | ||
279 | |||
280 | .late_probe = bells_late_probe, | ||
281 | |||
282 | .dapm_routes = bells_routes, | ||
283 | .num_dapm_routes = ARRAY_SIZE(bells_routes), | ||
284 | |||
285 | .set_bias_level = bells_set_bias_level, | ||
286 | .set_bias_level_post = bells_set_bias_level_post, | ||
287 | }, | ||
288 | { | ||
289 | .name = "Bells WM5110", | ||
290 | .owner = THIS_MODULE, | ||
291 | .dai_link = bells_dai_wm5110, | ||
292 | .num_links = ARRAY_SIZE(bells_dai_wm5110), | ||
293 | .codec_conf = bells_codec_conf, | ||
294 | .num_configs = ARRAY_SIZE(bells_codec_conf), | ||
295 | |||
296 | .late_probe = bells_late_probe, | ||
297 | |||
298 | .dapm_routes = bells_routes, | ||
299 | .num_dapm_routes = ARRAY_SIZE(bells_routes), | ||
300 | |||
301 | .set_bias_level = bells_set_bias_level, | ||
302 | .set_bias_level_post = bells_set_bias_level_post, | ||
303 | }, | ||
304 | }; | ||
305 | |||
306 | |||
307 | static __devinit int bells_probe(struct platform_device *pdev) | ||
308 | { | ||
309 | int ret; | ||
310 | |||
311 | bells_cards[pdev->id].dev = &pdev->dev; | ||
312 | |||
313 | ret = snd_soc_register_card(&bells_cards[pdev->id]); | ||
314 | if (ret) { | ||
315 | dev_err(&pdev->dev, | ||
316 | "snd_soc_register_card(%s) failed: %d\n", | ||
317 | bells_cards[pdev->id].name, ret); | ||
318 | return ret; | ||
319 | } | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static int __devexit bells_remove(struct platform_device *pdev) | ||
325 | { | ||
326 | snd_soc_unregister_card(&bells_cards[pdev->id]); | ||
327 | |||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | static struct platform_driver bells_driver = { | ||
332 | .driver = { | ||
333 | .name = "bells", | ||
334 | .owner = THIS_MODULE, | ||
335 | .pm = &snd_soc_pm_ops, | ||
336 | }, | ||
337 | .probe = bells_probe, | ||
338 | .remove = __devexit_p(bells_remove), | ||
339 | }; | ||
340 | |||
341 | module_platform_driver(bells_driver); | ||
342 | |||
343 | MODULE_DESCRIPTION("Bells audio support"); | ||
344 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
345 | MODULE_LICENSE("GPL"); | ||
346 | MODULE_ALIAS("platform:bells"); | ||
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index f3ebc38c10fe..b70964ea448c 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c | |||
@@ -34,9 +34,7 @@ static const struct snd_pcm_hardware dma_hardware = { | |||
34 | .info = SNDRV_PCM_INFO_INTERLEAVED | | 34 | .info = SNDRV_PCM_INFO_INTERLEAVED | |
35 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 35 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
36 | SNDRV_PCM_INFO_MMAP | | 36 | SNDRV_PCM_INFO_MMAP | |
37 | SNDRV_PCM_INFO_MMAP_VALID | | 37 | SNDRV_PCM_INFO_MMAP_VALID, |
38 | SNDRV_PCM_INFO_PAUSE | | ||
39 | SNDRV_PCM_INFO_RESUME, | ||
40 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | 38 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
41 | SNDRV_PCM_FMTBIT_U16_LE | | 39 | SNDRV_PCM_FMTBIT_U16_LE | |
42 | SNDRV_PCM_FMTBIT_U8 | | 40 | SNDRV_PCM_FMTBIT_U8 | |
@@ -248,15 +246,11 @@ static int dma_trigger(struct snd_pcm_substream *substream, int cmd) | |||
248 | 246 | ||
249 | switch (cmd) { | 247 | switch (cmd) { |
250 | case SNDRV_PCM_TRIGGER_START: | 248 | case SNDRV_PCM_TRIGGER_START: |
251 | case SNDRV_PCM_TRIGGER_RESUME: | ||
252 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
253 | prtd->state |= ST_RUNNING; | 249 | prtd->state |= ST_RUNNING; |
254 | prtd->params->ops->trigger(prtd->params->ch); | 250 | prtd->params->ops->trigger(prtd->params->ch); |
255 | break; | 251 | break; |
256 | 252 | ||
257 | case SNDRV_PCM_TRIGGER_STOP: | 253 | case SNDRV_PCM_TRIGGER_STOP: |
258 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
259 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
260 | prtd->state &= ~ST_RUNNING; | 254 | prtd->state &= ~ST_RUNNING; |
261 | prtd->params->ops->stop(prtd->params->ch); | 255 | prtd->params->ops->stop(prtd->params->ch); |
262 | break; | 256 | break; |
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index a4a9fc7e8c76..c7e1c28528a4 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c | |||
@@ -25,7 +25,7 @@ static int speyside_set_bias_level(struct snd_soc_card *card, | |||
25 | struct snd_soc_dapm_context *dapm, | 25 | struct snd_soc_dapm_context *dapm, |
26 | enum snd_soc_bias_level level) | 26 | enum snd_soc_bias_level level) |
27 | { | 27 | { |
28 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | 28 | struct snd_soc_dai *codec_dai = card->rtd[1].codec_dai; |
29 | int ret; | 29 | int ret; |
30 | 30 | ||
31 | if (dapm->dev != codec_dai->dev) | 31 | if (dapm->dev != codec_dai->dev) |
@@ -57,7 +57,7 @@ static int speyside_set_bias_level_post(struct snd_soc_card *card, | |||
57 | struct snd_soc_dapm_context *dapm, | 57 | struct snd_soc_dapm_context *dapm, |
58 | enum snd_soc_bias_level level) | 58 | enum snd_soc_bias_level level) |
59 | { | 59 | { |
60 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | 60 | struct snd_soc_dai *codec_dai = card->rtd[1].codec_dai; |
61 | int ret; | 61 | int ret; |
62 | 62 | ||
63 | if (dapm->dev != codec_dai->dev) | 63 | if (dapm->dev != codec_dai->dev) |
@@ -126,6 +126,18 @@ static void speyside_set_polarity(struct snd_soc_codec *codec, | |||
126 | snd_soc_dapm_sync(&codec->dapm); | 126 | snd_soc_dapm_sync(&codec->dapm); |
127 | } | 127 | } |
128 | 128 | ||
129 | static int speyside_wm0010_init(struct snd_soc_pcm_runtime *rtd) | ||
130 | { | ||
131 | struct snd_soc_dai *dai = rtd->codec_dai; | ||
132 | int ret; | ||
133 | |||
134 | ret = snd_soc_dai_set_sysclk(dai, 0, MCLK_AUDIO_RATE, 0); | ||
135 | if (ret < 0) | ||
136 | return ret; | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
129 | static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd) | 141 | static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd) |
130 | { | 142 | { |
131 | struct snd_soc_dai *dai = rtd->codec_dai; | 143 | struct snd_soc_dai *dai = rtd->codec_dai; |
@@ -172,17 +184,37 @@ static int speyside_late_probe(struct snd_soc_card *card) | |||
172 | return 0; | 184 | return 0; |
173 | } | 185 | } |
174 | 186 | ||
187 | static const struct snd_soc_pcm_stream dsp_codec_params = { | ||
188 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | ||
189 | .rate_min = 48000, | ||
190 | .rate_max = 48000, | ||
191 | .channels_min = 2, | ||
192 | .channels_max = 2, | ||
193 | }; | ||
194 | |||
175 | static struct snd_soc_dai_link speyside_dai[] = { | 195 | static struct snd_soc_dai_link speyside_dai[] = { |
176 | { | 196 | { |
177 | .name = "CPU", | 197 | .name = "CPU-DSP", |
178 | .stream_name = "CPU", | 198 | .stream_name = "CPU-DSP", |
179 | .cpu_dai_name = "samsung-i2s.0", | 199 | .cpu_dai_name = "samsung-i2s.0", |
180 | .codec_dai_name = "wm8996-aif1", | 200 | .codec_dai_name = "wm0010-sdi1", |
181 | .platform_name = "samsung-audio", | 201 | .platform_name = "samsung-audio", |
202 | .codec_name = "spi0.0", | ||
203 | .init = speyside_wm0010_init, | ||
204 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
205 | | SND_SOC_DAIFMT_CBM_CFM, | ||
206 | }, | ||
207 | { | ||
208 | .name = "DSP-CODEC", | ||
209 | .stream_name = "DSP-CODEC", | ||
210 | .cpu_dai_name = "wm0010-sdi2", | ||
211 | .codec_dai_name = "wm8996-aif1", | ||
182 | .codec_name = "wm8996.1-001a", | 212 | .codec_name = "wm8996.1-001a", |
183 | .init = speyside_wm8996_init, | 213 | .init = speyside_wm8996_init, |
184 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 214 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
185 | | SND_SOC_DAIFMT_CBM_CFM, | 215 | | SND_SOC_DAIFMT_CBM_CFM, |
216 | .params = &dsp_codec_params, | ||
217 | .ignore_suspend = 1, | ||
186 | }, | 218 | }, |
187 | { | 219 | { |
188 | .name = "Baseband", | 220 | .name = "Baseband", |
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 0540408a9fa9..5328ae5539f1 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -1655,22 +1655,20 @@ static int fsi_probe(struct platform_device *pdev) | |||
1655 | irq = platform_get_irq(pdev, 0); | 1655 | irq = platform_get_irq(pdev, 0); |
1656 | if (!res || (int)irq <= 0) { | 1656 | if (!res || (int)irq <= 0) { |
1657 | dev_err(&pdev->dev, "Not enough FSI platform resources.\n"); | 1657 | dev_err(&pdev->dev, "Not enough FSI platform resources.\n"); |
1658 | ret = -ENODEV; | 1658 | return -ENODEV; |
1659 | goto exit; | ||
1660 | } | 1659 | } |
1661 | 1660 | ||
1662 | master = kzalloc(sizeof(*master), GFP_KERNEL); | 1661 | master = devm_kzalloc(&pdev->dev, sizeof(*master), GFP_KERNEL); |
1663 | if (!master) { | 1662 | if (!master) { |
1664 | dev_err(&pdev->dev, "Could not allocate master\n"); | 1663 | dev_err(&pdev->dev, "Could not allocate master\n"); |
1665 | ret = -ENOMEM; | 1664 | return -ENOMEM; |
1666 | goto exit; | ||
1667 | } | 1665 | } |
1668 | 1666 | ||
1669 | master->base = ioremap_nocache(res->start, resource_size(res)); | 1667 | master->base = devm_ioremap_nocache(&pdev->dev, |
1668 | res->start, resource_size(res)); | ||
1670 | if (!master->base) { | 1669 | if (!master->base) { |
1671 | ret = -ENXIO; | ||
1672 | dev_err(&pdev->dev, "Unable to ioremap FSI registers.\n"); | 1670 | dev_err(&pdev->dev, "Unable to ioremap FSI registers.\n"); |
1673 | goto exit_kfree; | 1671 | return -ENXIO; |
1674 | } | 1672 | } |
1675 | 1673 | ||
1676 | /* master setting */ | 1674 | /* master setting */ |
@@ -1686,7 +1684,7 @@ static int fsi_probe(struct platform_device *pdev) | |||
1686 | ret = fsi_stream_probe(&master->fsia, &pdev->dev); | 1684 | ret = fsi_stream_probe(&master->fsia, &pdev->dev); |
1687 | if (ret < 0) { | 1685 | if (ret < 0) { |
1688 | dev_err(&pdev->dev, "FSIA stream probe failed\n"); | 1686 | dev_err(&pdev->dev, "FSIA stream probe failed\n"); |
1689 | goto exit_iounmap; | 1687 | return ret; |
1690 | } | 1688 | } |
1691 | 1689 | ||
1692 | /* FSI B setting */ | 1690 | /* FSI B setting */ |
@@ -1730,16 +1728,11 @@ exit_snd_soc: | |||
1730 | exit_free_irq: | 1728 | exit_free_irq: |
1731 | free_irq(irq, master); | 1729 | free_irq(irq, master); |
1732 | exit_fsib: | 1730 | exit_fsib: |
1731 | pm_runtime_disable(&pdev->dev); | ||
1733 | fsi_stream_remove(&master->fsib); | 1732 | fsi_stream_remove(&master->fsib); |
1734 | exit_fsia: | 1733 | exit_fsia: |
1735 | fsi_stream_remove(&master->fsia); | 1734 | fsi_stream_remove(&master->fsia); |
1736 | exit_iounmap: | 1735 | |
1737 | iounmap(master->base); | ||
1738 | pm_runtime_disable(&pdev->dev); | ||
1739 | exit_kfree: | ||
1740 | kfree(master); | ||
1741 | master = NULL; | ||
1742 | exit: | ||
1743 | return ret; | 1736 | return ret; |
1744 | } | 1737 | } |
1745 | 1738 | ||
@@ -1758,9 +1751,6 @@ static int fsi_remove(struct platform_device *pdev) | |||
1758 | fsi_stream_remove(&master->fsia); | 1751 | fsi_stream_remove(&master->fsia); |
1759 | fsi_stream_remove(&master->fsib); | 1752 | fsi_stream_remove(&master->fsib); |
1760 | 1753 | ||
1761 | iounmap(master->base); | ||
1762 | kfree(master); | ||
1763 | |||
1764 | return 0; | 1754 | return 0; |
1765 | } | 1755 | } |
1766 | 1756 | ||
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c new file mode 100644 index 000000000000..967d0e173e1b --- /dev/null +++ b/sound/soc/soc-compress.c | |||
@@ -0,0 +1,294 @@ | |||
1 | /* | ||
2 | * soc-compress.c -- ALSA SoC Compress | ||
3 | * | ||
4 | * Copyright (C) 2012 Intel Corp. | ||
5 | * | ||
6 | * Authors: Namarta Kohli <namartax.kohli@intel.com> | ||
7 | * Ramesh Babu K V <ramesh.babu@linux.intel.com> | ||
8 | * Vinod Koul <vinod.koul@linux.intel.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/workqueue.h> | ||
22 | #include <sound/core.h> | ||
23 | #include <sound/compress_params.h> | ||
24 | #include <sound/compress_driver.h> | ||
25 | #include <sound/soc.h> | ||
26 | #include <sound/initval.h> | ||
27 | |||
28 | static int soc_compr_open(struct snd_compr_stream *cstream) | ||
29 | { | ||
30 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
31 | struct snd_soc_platform *platform = rtd->platform; | ||
32 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
33 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
34 | int ret = 0; | ||
35 | |||
36 | if (platform->driver->compr_ops && platform->driver->compr_ops->open) { | ||
37 | ret = platform->driver->compr_ops->open(cstream); | ||
38 | if (ret < 0) { | ||
39 | pr_err("compress asoc: can't open platform %s\n", platform->name); | ||
40 | goto out; | ||
41 | } | ||
42 | } | ||
43 | |||
44 | if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->startup) { | ||
45 | ret = rtd->dai_link->compr_ops->startup(cstream); | ||
46 | if (ret < 0) { | ||
47 | pr_err("compress asoc: %s startup failed\n", rtd->dai_link->name); | ||
48 | goto machine_err; | ||
49 | } | ||
50 | } | ||
51 | |||
52 | if (cstream->direction == SND_COMPRESS_PLAYBACK) { | ||
53 | cpu_dai->playback_active++; | ||
54 | codec_dai->playback_active++; | ||
55 | } else { | ||
56 | cpu_dai->capture_active++; | ||
57 | codec_dai->capture_active++; | ||
58 | } | ||
59 | |||
60 | cpu_dai->active++; | ||
61 | codec_dai->active++; | ||
62 | rtd->codec->active++; | ||
63 | |||
64 | return 0; | ||
65 | |||
66 | machine_err: | ||
67 | if (platform->driver->compr_ops && platform->driver->compr_ops->free) | ||
68 | platform->driver->compr_ops->free(cstream); | ||
69 | out: | ||
70 | return ret; | ||
71 | } | ||
72 | |||
73 | static int soc_compr_free(struct snd_compr_stream *cstream) | ||
74 | { | ||
75 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
76 | struct snd_soc_platform *platform = rtd->platform; | ||
77 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
78 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
79 | struct snd_soc_codec *codec = rtd->codec; | ||
80 | |||
81 | if (cstream->direction == SND_COMPRESS_PLAYBACK) { | ||
82 | cpu_dai->playback_active--; | ||
83 | codec_dai->playback_active--; | ||
84 | } else { | ||
85 | cpu_dai->capture_active--; | ||
86 | codec_dai->capture_active--; | ||
87 | } | ||
88 | |||
89 | snd_soc_dai_digital_mute(codec_dai, 1); | ||
90 | |||
91 | cpu_dai->active--; | ||
92 | codec_dai->active--; | ||
93 | codec->active--; | ||
94 | |||
95 | if (!cpu_dai->active) | ||
96 | cpu_dai->rate = 0; | ||
97 | |||
98 | if (!codec_dai->active) | ||
99 | codec_dai->rate = 0; | ||
100 | |||
101 | |||
102 | if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown) | ||
103 | rtd->dai_link->compr_ops->shutdown(cstream); | ||
104 | |||
105 | if (platform->driver->compr_ops && platform->driver->compr_ops->free) | ||
106 | platform->driver->compr_ops->free(cstream); | ||
107 | cpu_dai->runtime = NULL; | ||
108 | |||
109 | if (cstream->direction == SND_COMPRESS_PLAYBACK) { | ||
110 | if (!rtd->pmdown_time || codec->ignore_pmdown_time || | ||
111 | rtd->dai_link->ignore_pmdown_time) { | ||
112 | snd_soc_dapm_stream_event(rtd, | ||
113 | SNDRV_PCM_STREAM_PLAYBACK, | ||
114 | SND_SOC_DAPM_STREAM_STOP); | ||
115 | } else | ||
116 | codec_dai->pop_wait = 1; | ||
117 | schedule_delayed_work(&rtd->delayed_work, | ||
118 | msecs_to_jiffies(rtd->pmdown_time)); | ||
119 | } else { | ||
120 | /* capture streams can be powered down now */ | ||
121 | snd_soc_dapm_stream_event(rtd, | ||
122 | SNDRV_PCM_STREAM_CAPTURE, | ||
123 | SND_SOC_DAPM_STREAM_STOP); | ||
124 | } | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd) | ||
130 | { | ||
131 | |||
132 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
133 | struct snd_soc_platform *platform = rtd->platform; | ||
134 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
135 | int ret = 0; | ||
136 | |||
137 | if (platform->driver->compr_ops && platform->driver->compr_ops->trigger) { | ||
138 | ret = platform->driver->compr_ops->trigger(cstream, cmd); | ||
139 | if (ret < 0) | ||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | if (cmd == SNDRV_PCM_TRIGGER_START) | ||
144 | snd_soc_dai_digital_mute(codec_dai, 0); | ||
145 | else if (cmd == SNDRV_PCM_TRIGGER_STOP) | ||
146 | snd_soc_dai_digital_mute(codec_dai, 1); | ||
147 | |||
148 | return ret; | ||
149 | } | ||
150 | |||
151 | static int soc_compr_set_params(struct snd_compr_stream *cstream, | ||
152 | struct snd_compr_params *params) | ||
153 | { | ||
154 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
155 | struct snd_soc_platform *platform = rtd->platform; | ||
156 | int ret = 0; | ||
157 | |||
158 | /* first we call set_params for the platform driver | ||
159 | * this should configure the soc side | ||
160 | * if the machine has compressed ops then we call that as well | ||
161 | * expectation is that platform and machine will configure everything | ||
162 | * for this compress path, like configuring pcm port for codec | ||
163 | */ | ||
164 | if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) { | ||
165 | ret = platform->driver->compr_ops->set_params(cstream, params); | ||
166 | if (ret < 0) | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) { | ||
171 | ret = rtd->dai_link->compr_ops->set_params(cstream); | ||
172 | if (ret < 0) | ||
173 | return ret; | ||
174 | } | ||
175 | |||
176 | snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, | ||
177 | SND_SOC_DAPM_STREAM_START); | ||
178 | |||
179 | return ret; | ||
180 | } | ||
181 | |||
182 | static int soc_compr_get_params(struct snd_compr_stream *cstream, | ||
183 | struct snd_codec *params) | ||
184 | { | ||
185 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
186 | struct snd_soc_platform *platform = rtd->platform; | ||
187 | int ret = 0; | ||
188 | |||
189 | if (platform->driver->compr_ops && platform->driver->compr_ops->get_params) | ||
190 | ret = platform->driver->compr_ops->get_params(cstream, params); | ||
191 | |||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | static int soc_compr_get_caps(struct snd_compr_stream *cstream, | ||
196 | struct snd_compr_caps *caps) | ||
197 | { | ||
198 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
199 | struct snd_soc_platform *platform = rtd->platform; | ||
200 | int ret = 0; | ||
201 | |||
202 | if (platform->driver->compr_ops && platform->driver->compr_ops->get_caps) | ||
203 | ret = platform->driver->compr_ops->get_caps(cstream, caps); | ||
204 | |||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream, | ||
209 | struct snd_compr_codec_caps *codec) | ||
210 | { | ||
211 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
212 | struct snd_soc_platform *platform = rtd->platform; | ||
213 | int ret = 0; | ||
214 | |||
215 | if (platform->driver->compr_ops && platform->driver->compr_ops->get_codec_caps) | ||
216 | ret = platform->driver->compr_ops->get_codec_caps(cstream, codec); | ||
217 | |||
218 | return ret; | ||
219 | } | ||
220 | |||
221 | static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes) | ||
222 | { | ||
223 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
224 | struct snd_soc_platform *platform = rtd->platform; | ||
225 | int ret = 0; | ||
226 | |||
227 | if (platform->driver->compr_ops && platform->driver->compr_ops->ack) | ||
228 | ret = platform->driver->compr_ops->ack(cstream, bytes); | ||
229 | |||
230 | return ret; | ||
231 | } | ||
232 | |||
233 | static int soc_compr_pointer(struct snd_compr_stream *cstream, | ||
234 | struct snd_compr_tstamp *tstamp) | ||
235 | { | ||
236 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
237 | struct snd_soc_platform *platform = rtd->platform; | ||
238 | |||
239 | if (platform->driver->compr_ops && platform->driver->compr_ops->pointer) | ||
240 | platform->driver->compr_ops->pointer(cstream, tstamp); | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | /* ASoC Compress operations */ | ||
246 | static struct snd_compr_ops soc_compr_ops = { | ||
247 | .open = soc_compr_open, | ||
248 | .free = soc_compr_free, | ||
249 | .set_params = soc_compr_set_params, | ||
250 | .get_params = soc_compr_get_params, | ||
251 | .trigger = soc_compr_trigger, | ||
252 | .pointer = soc_compr_pointer, | ||
253 | .ack = soc_compr_ack, | ||
254 | .get_caps = soc_compr_get_caps, | ||
255 | .get_codec_caps = soc_compr_get_codec_caps | ||
256 | }; | ||
257 | |||
258 | /* create a new compress */ | ||
259 | int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) | ||
260 | { | ||
261 | struct snd_soc_codec *codec = rtd->codec; | ||
262 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
263 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
264 | struct snd_compr *compr; | ||
265 | char new_name[64]; | ||
266 | int ret = 0, direction = 0; | ||
267 | |||
268 | /* check client and interface hw capabilities */ | ||
269 | snprintf(new_name, sizeof(new_name), "%s %s-%d", | ||
270 | rtd->dai_link->stream_name, codec_dai->name, num); | ||
271 | direction = SND_COMPRESS_PLAYBACK; | ||
272 | compr = kzalloc(sizeof(*compr), GFP_KERNEL); | ||
273 | if (compr == NULL) { | ||
274 | snd_printk(KERN_ERR "Cannot allocate compr\n"); | ||
275 | return -ENOMEM; | ||
276 | } | ||
277 | |||
278 | compr->ops = &soc_compr_ops; | ||
279 | mutex_init(&compr->lock); | ||
280 | ret = snd_compress_new(rtd->card->snd_card, num, direction, compr); | ||
281 | if (ret < 0) { | ||
282 | pr_err("compress asoc: can't create compress for codec %s\n", | ||
283 | codec->name); | ||
284 | kfree(compr); | ||
285 | return ret; | ||
286 | } | ||
287 | |||
288 | rtd->compr = compr; | ||
289 | compr->private_data = rtd; | ||
290 | |||
291 | printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", codec_dai->name, | ||
292 | cpu_dai->name); | ||
293 | return ret; | ||
294 | } | ||
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index c501af6d8dbe..9a6daf997319 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -609,6 +609,10 @@ int snd_soc_suspend(struct device *dev) | |||
609 | SND_SOC_DAPM_STREAM_SUSPEND); | 609 | SND_SOC_DAPM_STREAM_SUSPEND); |
610 | } | 610 | } |
611 | 611 | ||
612 | /* Recheck all analogue paths too */ | ||
613 | dapm_mark_io_dirty(&card->dapm); | ||
614 | snd_soc_dapm_sync(&card->dapm); | ||
615 | |||
612 | /* suspend all CODECs */ | 616 | /* suspend all CODECs */ |
613 | list_for_each_entry(codec, &card->codec_dev_list, card_list) { | 617 | list_for_each_entry(codec, &card->codec_dev_list, card_list) { |
614 | /* If there are paths active then the CODEC will be held with | 618 | /* If there are paths active then the CODEC will be held with |
@@ -631,6 +635,8 @@ int snd_soc_suspend(struct device *dev) | |||
631 | codec->driver->suspend(codec); | 635 | codec->driver->suspend(codec); |
632 | codec->suspended = 1; | 636 | codec->suspended = 1; |
633 | codec->cache_sync = 1; | 637 | codec->cache_sync = 1; |
638 | if (codec->using_regmap) | ||
639 | regcache_mark_dirty(codec->control_data); | ||
634 | break; | 640 | break; |
635 | default: | 641 | default: |
636 | dev_dbg(codec->dev, "CODEC is on over suspend\n"); | 642 | dev_dbg(codec->dev, "CODEC is on over suspend\n"); |
@@ -756,6 +762,10 @@ static void soc_resume_deferred(struct work_struct *work) | |||
756 | 762 | ||
757 | /* userspace can access us now we are back as we were before */ | 763 | /* userspace can access us now we are back as we were before */ |
758 | snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0); | 764 | snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0); |
765 | |||
766 | /* Recheck all analogue paths too */ | ||
767 | dapm_mark_io_dirty(&card->dapm); | ||
768 | snd_soc_dapm_sync(&card->dapm); | ||
759 | } | 769 | } |
760 | 770 | ||
761 | /* powers up audio subsystem after a suspend */ | 771 | /* powers up audio subsystem after a suspend */ |
@@ -1388,37 +1398,48 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1388 | if (ret < 0) | 1398 | if (ret < 0) |
1389 | pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret); | 1399 | pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret); |
1390 | 1400 | ||
1391 | if (!dai_link->params) { | 1401 | if (cpu_dai->driver->compress_dai) { |
1392 | /* create the pcm */ | 1402 | /*create compress_device"*/ |
1393 | ret = soc_new_pcm(rtd, num); | 1403 | ret = soc_new_compress(rtd, num); |
1394 | if (ret < 0) { | 1404 | if (ret < 0) { |
1395 | pr_err("asoc: can't create pcm %s :%d\n", | 1405 | pr_err("asoc: can't create compress %s\n", |
1396 | dai_link->stream_name, ret); | 1406 | dai_link->stream_name); |
1397 | return ret; | 1407 | return ret; |
1398 | } | 1408 | } |
1399 | } else { | 1409 | } else { |
1400 | /* link the DAI widgets */ | 1410 | |
1401 | play_w = codec_dai->playback_widget; | 1411 | if (!dai_link->params) { |
1402 | capture_w = cpu_dai->capture_widget; | 1412 | /* create the pcm */ |
1403 | if (play_w && capture_w) { | 1413 | ret = soc_new_pcm(rtd, num); |
1404 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, | 1414 | if (ret < 0) { |
1405 | capture_w, play_w); | 1415 | pr_err("asoc: can't create pcm %s :%d\n", |
1406 | if (ret != 0) { | 1416 | dai_link->stream_name, ret); |
1407 | dev_err(card->dev, "Can't link %s to %s: %d\n", | ||
1408 | play_w->name, capture_w->name, ret); | ||
1409 | return ret; | 1417 | return ret; |
1410 | } | 1418 | } |
1411 | } | 1419 | } else { |
1420 | /* link the DAI widgets */ | ||
1421 | play_w = codec_dai->playback_widget; | ||
1422 | capture_w = cpu_dai->capture_widget; | ||
1423 | if (play_w && capture_w) { | ||
1424 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, | ||
1425 | capture_w, play_w); | ||
1426 | if (ret != 0) { | ||
1427 | dev_err(card->dev, "Can't link %s to %s: %d\n", | ||
1428 | play_w->name, capture_w->name, ret); | ||
1429 | return ret; | ||
1430 | } | ||
1431 | } | ||
1412 | 1432 | ||
1413 | play_w = cpu_dai->playback_widget; | 1433 | play_w = cpu_dai->playback_widget; |
1414 | capture_w = codec_dai->capture_widget; | 1434 | capture_w = codec_dai->capture_widget; |
1415 | if (play_w && capture_w) { | 1435 | if (play_w && capture_w) { |
1416 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, | 1436 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, |
1417 | capture_w, play_w); | 1437 | capture_w, play_w); |
1418 | if (ret != 0) { | 1438 | if (ret != 0) { |
1419 | dev_err(card->dev, "Can't link %s to %s: %d\n", | 1439 | dev_err(card->dev, "Can't link %s to %s: %d\n", |
1420 | play_w->name, capture_w->name, ret); | 1440 | play_w->name, capture_w->name, ret); |
1421 | return ret; | 1441 | return ret; |
1442 | } | ||
1422 | } | 1443 | } |
1423 | } | 1444 | } |
1424 | } | 1445 | } |
@@ -1816,7 +1837,6 @@ base_error: | |||
1816 | static int soc_probe(struct platform_device *pdev) | 1837 | static int soc_probe(struct platform_device *pdev) |
1817 | { | 1838 | { |
1818 | struct snd_soc_card *card = platform_get_drvdata(pdev); | 1839 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
1819 | int ret = 0; | ||
1820 | 1840 | ||
1821 | /* | 1841 | /* |
1822 | * no card, so machine driver should be registering card | 1842 | * no card, so machine driver should be registering card |
@@ -1832,13 +1852,7 @@ static int soc_probe(struct platform_device *pdev) | |||
1832 | /* Bodge while we unpick instantiation */ | 1852 | /* Bodge while we unpick instantiation */ |
1833 | card->dev = &pdev->dev; | 1853 | card->dev = &pdev->dev; |
1834 | 1854 | ||
1835 | ret = snd_soc_register_card(card); | 1855 | return snd_soc_register_card(card); |
1836 | if (ret != 0) { | ||
1837 | dev_err(&pdev->dev, "Failed to register card\n"); | ||
1838 | return ret; | ||
1839 | } | ||
1840 | |||
1841 | return 0; | ||
1842 | } | 1856 | } |
1843 | 1857 | ||
1844 | static int soc_cleanup_card_resources(struct snd_soc_card *card) | 1858 | static int soc_cleanup_card_resources(struct snd_soc_card *card) |
@@ -2399,16 +2413,14 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol, | |||
2399 | { | 2413 | { |
2400 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2414 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
2401 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | 2415 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
2402 | unsigned int val, bitmask; | 2416 | unsigned int val; |
2403 | 2417 | ||
2404 | for (bitmask = 1; bitmask < e->max; bitmask <<= 1) | ||
2405 | ; | ||
2406 | val = snd_soc_read(codec, e->reg); | 2418 | val = snd_soc_read(codec, e->reg); |
2407 | ucontrol->value.enumerated.item[0] | 2419 | ucontrol->value.enumerated.item[0] |
2408 | = (val >> e->shift_l) & (bitmask - 1); | 2420 | = (val >> e->shift_l) & e->mask; |
2409 | if (e->shift_l != e->shift_r) | 2421 | if (e->shift_l != e->shift_r) |
2410 | ucontrol->value.enumerated.item[1] = | 2422 | ucontrol->value.enumerated.item[1] = |
2411 | (val >> e->shift_r) & (bitmask - 1); | 2423 | (val >> e->shift_r) & e->mask; |
2412 | 2424 | ||
2413 | return 0; | 2425 | return 0; |
2414 | } | 2426 | } |
@@ -2429,19 +2441,17 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, | |||
2429 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2441 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
2430 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | 2442 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
2431 | unsigned int val; | 2443 | unsigned int val; |
2432 | unsigned int mask, bitmask; | 2444 | unsigned int mask; |
2433 | 2445 | ||
2434 | for (bitmask = 1; bitmask < e->max; bitmask <<= 1) | ||
2435 | ; | ||
2436 | if (ucontrol->value.enumerated.item[0] > e->max - 1) | 2446 | if (ucontrol->value.enumerated.item[0] > e->max - 1) |
2437 | return -EINVAL; | 2447 | return -EINVAL; |
2438 | val = ucontrol->value.enumerated.item[0] << e->shift_l; | 2448 | val = ucontrol->value.enumerated.item[0] << e->shift_l; |
2439 | mask = (bitmask - 1) << e->shift_l; | 2449 | mask = e->mask << e->shift_l; |
2440 | if (e->shift_l != e->shift_r) { | 2450 | if (e->shift_l != e->shift_r) { |
2441 | if (ucontrol->value.enumerated.item[1] > e->max - 1) | 2451 | if (ucontrol->value.enumerated.item[1] > e->max - 1) |
2442 | return -EINVAL; | 2452 | return -EINVAL; |
2443 | val |= ucontrol->value.enumerated.item[1] << e->shift_r; | 2453 | val |= ucontrol->value.enumerated.item[1] << e->shift_r; |
2444 | mask |= (bitmask - 1) << e->shift_r; | 2454 | mask |= e->mask << e->shift_r; |
2445 | } | 2455 | } |
2446 | 2456 | ||
2447 | return snd_soc_update_bits_locked(codec, e->reg, mask, val); | 2457 | return snd_soc_update_bits_locked(codec, e->reg, mask, val); |
@@ -3717,6 +3727,9 @@ int snd_soc_register_dai(struct device *dev, | |||
3717 | } | 3727 | } |
3718 | } | 3728 | } |
3719 | 3729 | ||
3730 | if (!dai->codec) | ||
3731 | dai->dapm.idle_bias_off = 1; | ||
3732 | |||
3720 | list_add(&dai->list, &dai_list); | 3733 | list_add(&dai->list, &dai_list); |
3721 | 3734 | ||
3722 | mutex_unlock(&client_mutex); | 3735 | mutex_unlock(&client_mutex); |
@@ -3805,6 +3818,9 @@ int snd_soc_register_dais(struct device *dev, | |||
3805 | } | 3818 | } |
3806 | } | 3819 | } |
3807 | 3820 | ||
3821 | if (!dai->codec) | ||
3822 | dai->dapm.idle_bias_off = 1; | ||
3823 | |||
3808 | list_add(&dai->list, &dai_list); | 3824 | list_add(&dai->list, &dai_list); |
3809 | 3825 | ||
3810 | mutex_unlock(&client_mutex); | 3826 | mutex_unlock(&client_mutex); |
@@ -4034,8 +4050,6 @@ int snd_soc_register_codec(struct device *dev, | |||
4034 | return 0; | 4050 | return 0; |
4035 | 4051 | ||
4036 | fail: | 4052 | fail: |
4037 | kfree(codec->reg_def_copy); | ||
4038 | codec->reg_def_copy = NULL; | ||
4039 | kfree(codec->name); | 4053 | kfree(codec->name); |
4040 | kfree(codec); | 4054 | kfree(codec); |
4041 | return ret; | 4055 | return ret; |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index dd7c49fafd75..873e6e76ee87 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -141,6 +141,28 @@ void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason) | |||
141 | } | 141 | } |
142 | EXPORT_SYMBOL_GPL(dapm_mark_dirty); | 142 | EXPORT_SYMBOL_GPL(dapm_mark_dirty); |
143 | 143 | ||
144 | void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm) | ||
145 | { | ||
146 | struct snd_soc_card *card = dapm->card; | ||
147 | struct snd_soc_dapm_widget *w; | ||
148 | |||
149 | mutex_lock(&card->dapm_mutex); | ||
150 | |||
151 | list_for_each_entry(w, &card->widgets, list) { | ||
152 | switch (w->id) { | ||
153 | case snd_soc_dapm_input: | ||
154 | case snd_soc_dapm_output: | ||
155 | dapm_mark_dirty(w, "Rechecking inputs and outputs"); | ||
156 | break; | ||
157 | default: | ||
158 | break; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | mutex_unlock(&card->dapm_mutex); | ||
163 | } | ||
164 | EXPORT_SYMBOL_GPL(dapm_mark_io_dirty); | ||
165 | |||
144 | /* create a new dapm widget */ | 166 | /* create a new dapm widget */ |
145 | static inline struct snd_soc_dapm_widget *dapm_cnew_widget( | 167 | static inline struct snd_soc_dapm_widget *dapm_cnew_widget( |
146 | const struct snd_soc_dapm_widget *_widget) | 168 | const struct snd_soc_dapm_widget *_widget) |
@@ -291,8 +313,11 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm, | |||
291 | if (dapm->codec->driver->set_bias_level) | 313 | if (dapm->codec->driver->set_bias_level) |
292 | ret = dapm->codec->driver->set_bias_level(dapm->codec, | 314 | ret = dapm->codec->driver->set_bias_level(dapm->codec, |
293 | level); | 315 | level); |
294 | } else | 316 | else |
317 | dapm->bias_level = level; | ||
318 | } else if (!card || dapm != &card->dapm) { | ||
295 | dapm->bias_level = level; | 319 | dapm->bias_level = level; |
320 | } | ||
296 | 321 | ||
297 | if (ret != 0) | 322 | if (ret != 0) |
298 | goto out; | 323 | goto out; |
@@ -333,12 +358,10 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, | |||
333 | case snd_soc_dapm_mux: { | 358 | case snd_soc_dapm_mux: { |
334 | struct soc_enum *e = (struct soc_enum *) | 359 | struct soc_enum *e = (struct soc_enum *) |
335 | w->kcontrol_news[i].private_value; | 360 | w->kcontrol_news[i].private_value; |
336 | int val, item, bitmask; | 361 | int val, item; |
337 | 362 | ||
338 | for (bitmask = 1; bitmask < e->max; bitmask <<= 1) | ||
339 | ; | ||
340 | val = soc_widget_read(w, e->reg); | 363 | val = soc_widget_read(w, e->reg); |
341 | item = (val >> e->shift_l) & (bitmask - 1); | 364 | item = (val >> e->shift_l) & e->mask; |
342 | 365 | ||
343 | p->connect = 0; | 366 | p->connect = 0; |
344 | for (i = 0; i < e->max; i++) { | 367 | for (i = 0; i < e->max; i++) { |
@@ -2655,15 +2678,13 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, | |||
2655 | struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); | 2678 | struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); |
2656 | struct snd_soc_dapm_widget *widget = wlist->widgets[0]; | 2679 | struct snd_soc_dapm_widget *widget = wlist->widgets[0]; |
2657 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | 2680 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
2658 | unsigned int val, bitmask; | 2681 | unsigned int val; |
2659 | 2682 | ||
2660 | for (bitmask = 1; bitmask < e->max; bitmask <<= 1) | ||
2661 | ; | ||
2662 | val = snd_soc_read(widget->codec, e->reg); | 2683 | val = snd_soc_read(widget->codec, e->reg); |
2663 | ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1); | 2684 | ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & e->mask; |
2664 | if (e->shift_l != e->shift_r) | 2685 | if (e->shift_l != e->shift_r) |
2665 | ucontrol->value.enumerated.item[1] = | 2686 | ucontrol->value.enumerated.item[1] = |
2666 | (val >> e->shift_r) & (bitmask - 1); | 2687 | (val >> e->shift_r) & e->mask; |
2667 | 2688 | ||
2668 | return 0; | 2689 | return 0; |
2669 | } | 2690 | } |
@@ -2687,22 +2708,20 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, | |||
2687 | struct snd_soc_card *card = codec->card; | 2708 | struct snd_soc_card *card = codec->card; |
2688 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | 2709 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
2689 | unsigned int val, mux, change; | 2710 | unsigned int val, mux, change; |
2690 | unsigned int mask, bitmask; | 2711 | unsigned int mask; |
2691 | struct snd_soc_dapm_update update; | 2712 | struct snd_soc_dapm_update update; |
2692 | int wi; | 2713 | int wi; |
2693 | 2714 | ||
2694 | for (bitmask = 1; bitmask < e->max; bitmask <<= 1) | ||
2695 | ; | ||
2696 | if (ucontrol->value.enumerated.item[0] > e->max - 1) | 2715 | if (ucontrol->value.enumerated.item[0] > e->max - 1) |
2697 | return -EINVAL; | 2716 | return -EINVAL; |
2698 | mux = ucontrol->value.enumerated.item[0]; | 2717 | mux = ucontrol->value.enumerated.item[0]; |
2699 | val = mux << e->shift_l; | 2718 | val = mux << e->shift_l; |
2700 | mask = (bitmask - 1) << e->shift_l; | 2719 | mask = e->mask << e->shift_l; |
2701 | if (e->shift_l != e->shift_r) { | 2720 | if (e->shift_l != e->shift_r) { |
2702 | if (ucontrol->value.enumerated.item[1] > e->max - 1) | 2721 | if (ucontrol->value.enumerated.item[1] > e->max - 1) |
2703 | return -EINVAL; | 2722 | return -EINVAL; |
2704 | val |= ucontrol->value.enumerated.item[1] << e->shift_r; | 2723 | val |= ucontrol->value.enumerated.item[1] << e->shift_r; |
2705 | mask |= (bitmask - 1) << e->shift_r; | 2724 | mask |= e->mask << e->shift_r; |
2706 | } | 2725 | } |
2707 | 2726 | ||
2708 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | 2727 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); |
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 0c172938b82a..fa0fd8ddae90 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c | |||
@@ -83,11 +83,6 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) | |||
83 | jack->status &= ~mask; | 83 | jack->status &= ~mask; |
84 | jack->status |= status & mask; | 84 | jack->status |= status & mask; |
85 | 85 | ||
86 | /* The DAPM sync is expensive enough to be worth skipping. | ||
87 | * However, empty mask means pin synchronization is desired. */ | ||
88 | if (mask && (jack->status == oldstatus)) | ||
89 | goto out; | ||
90 | |||
91 | trace_snd_soc_jack_notify(jack, status); | 86 | trace_snd_soc_jack_notify(jack, status); |
92 | 87 | ||
93 | list_for_each_entry(pin, &jack->pins, list) { | 88 | list_for_each_entry(pin, &jack->pins, list) { |
@@ -109,7 +104,6 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) | |||
109 | 104 | ||
110 | snd_jack_report(jack->jack, jack->status); | 105 | snd_jack_report(jack->jack, jack->status); |
111 | 106 | ||
112 | out: | ||
113 | mutex_unlock(&jack->mutex); | 107 | mutex_unlock(&jack->mutex); |
114 | } | 108 | } |
115 | EXPORT_SYMBOL_GPL(snd_soc_jack_report); | 109 | EXPORT_SYMBOL_GPL(snd_soc_jack_report); |
diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c index 97c2cac8e92c..8c7f23729446 100644 --- a/sound/soc/spear/spear_pcm.c +++ b/sound/soc/spear/spear_pcm.c | |||
@@ -138,7 +138,7 @@ static void spear_pcm_free(struct snd_pcm *pcm) | |||
138 | continue; | 138 | continue; |
139 | 139 | ||
140 | buf = &substream->dma_buffer; | 140 | buf = &substream->dma_buffer; |
141 | if (!buf && !buf->area) | 141 | if (!buf || !buf->area) |
142 | continue; | 142 | continue; |
143 | 143 | ||
144 | dma_free_writecombine(pcm->card->dev, buf->bytes, | 144 | dma_free_writecombine(pcm->card->dev, buf->bytes, |
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index e463529b38bb..76cb1b363b71 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c | |||
@@ -89,7 +89,6 @@ static struct snd_soc_jack_gpio tegra_alc5632_hp_jack_gpio = { | |||
89 | .name = "Headset detection", | 89 | .name = "Headset detection", |
90 | .report = SND_JACK_HEADSET, | 90 | .report = SND_JACK_HEADSET, |
91 | .debounce_time = 150, | 91 | .debounce_time = 150, |
92 | .invert = 1, | ||
93 | }; | 92 | }; |
94 | 93 | ||
95 | static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = { | 94 | static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = { |
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index 5658bcec1931..8d6900c1ee47 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c | |||
@@ -334,11 +334,11 @@ static int tegra_pcm_hw_params(struct snd_pcm_substream *substream, | |||
334 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 334 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
335 | slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | 335 | slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
336 | slave_config.dst_addr = dmap->addr; | 336 | slave_config.dst_addr = dmap->addr; |
337 | slave_config.src_maxburst = 0; | 337 | slave_config.dst_maxburst = 4; |
338 | } else { | 338 | } else { |
339 | slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | 339 | slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
340 | slave_config.src_addr = dmap->addr; | 340 | slave_config.src_addr = dmap->addr; |
341 | slave_config.dst_maxburst = 0; | 341 | slave_config.src_maxburst = 4; |
342 | } | 342 | } |
343 | slave_config.slave_id = dmap->req_sel; | 343 | slave_config.slave_id = dmap->req_sel; |
344 | 344 | ||
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index d4f14e492341..cee13b7bfb94 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c | |||
@@ -34,13 +34,12 @@ | |||
34 | #include <linux/gpio.h> | 34 | #include <linux/gpio.h> |
35 | #include <linux/of_gpio.h> | 35 | #include <linux/of_gpio.h> |
36 | 36 | ||
37 | #include <mach/tegra_wm8903_pdata.h> | ||
38 | |||
39 | #include <sound/core.h> | 37 | #include <sound/core.h> |
40 | #include <sound/jack.h> | 38 | #include <sound/jack.h> |
41 | #include <sound/pcm.h> | 39 | #include <sound/pcm.h> |
42 | #include <sound/pcm_params.h> | 40 | #include <sound/pcm_params.h> |
43 | #include <sound/soc.h> | 41 | #include <sound/soc.h> |
42 | #include <sound/tegra_wm8903.h> | ||
44 | 43 | ||
45 | #include "../codecs/wm8903.h" | 44 | #include "../codecs/wm8903.h" |
46 | 45 | ||
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index 057e28ef770e..772cb19d2fb3 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c | |||
@@ -760,6 +760,9 @@ static int __devinit ux500_msp_drv_probe(struct platform_device *pdev) | |||
760 | drvdata = devm_kzalloc(&pdev->dev, | 760 | drvdata = devm_kzalloc(&pdev->dev, |
761 | sizeof(struct ux500_msp_i2s_drvdata), | 761 | sizeof(struct ux500_msp_i2s_drvdata), |
762 | GFP_KERNEL); | 762 | GFP_KERNEL); |
763 | if (!drvdata) | ||
764 | return -ENOMEM; | ||
765 | |||
763 | drvdata->fmt = 0; | 766 | drvdata->fmt = 0; |
764 | drvdata->slots = 1; | 767 | drvdata->slots = 1; |
765 | drvdata->tx_mask = 0x01; | 768 | drvdata->tx_mask = 0x01; |
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c index 5c472f335a64..1b7c2f58ce13 100644 --- a/sound/soc/ux500/ux500_msp_i2s.c +++ b/sound/soc/ux500/ux500_msp_i2s.c | |||
@@ -663,7 +663,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, | |||
663 | struct ux500_msp **msp_p, | 663 | struct ux500_msp **msp_p, |
664 | struct msp_i2s_platform_data *platform_data) | 664 | struct msp_i2s_platform_data *platform_data) |
665 | { | 665 | { |
666 | int ret = 0; | ||
667 | struct resource *res = NULL; | 666 | struct resource *res = NULL; |
668 | struct i2s_controller *i2s_cont; | 667 | struct i2s_controller *i2s_cont; |
669 | struct ux500_msp *msp; | 668 | struct ux500_msp *msp; |
@@ -673,6 +672,8 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, | |||
673 | 672 | ||
674 | *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL); | 673 | *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL); |
675 | msp = *msp_p; | 674 | msp = *msp_p; |
675 | if (!msp) | ||
676 | return -ENOMEM; | ||
676 | 677 | ||
677 | msp->id = platform_data->id; | 678 | msp->id = platform_data->id; |
678 | msp->dev = &pdev->dev; | 679 | msp->dev = &pdev->dev; |
@@ -685,15 +686,14 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, | |||
685 | if (res == NULL) { | 686 | if (res == NULL) { |
686 | dev_err(&pdev->dev, "%s: ERROR: Unable to get resource!\n", | 687 | dev_err(&pdev->dev, "%s: ERROR: Unable to get resource!\n", |
687 | __func__); | 688 | __func__); |
688 | ret = -ENOMEM; | 689 | return -ENOMEM; |
689 | goto err_res; | ||
690 | } | 690 | } |
691 | 691 | ||
692 | msp->registers = ioremap(res->start, (res->end - res->start + 1)); | 692 | msp->registers = devm_ioremap(&pdev->dev, res->start, |
693 | resource_size(res)); | ||
693 | if (msp->registers == NULL) { | 694 | if (msp->registers == NULL) { |
694 | dev_err(&pdev->dev, "%s: ERROR: ioremap failed!\n", __func__); | 695 | dev_err(&pdev->dev, "%s: ERROR: ioremap failed!\n", __func__); |
695 | ret = -ENOMEM; | 696 | return -ENOMEM; |
696 | goto err_res; | ||
697 | } | 697 | } |
698 | 698 | ||
699 | msp->msp_state = MSP_STATE_IDLE; | 699 | msp->msp_state = MSP_STATE_IDLE; |
@@ -705,7 +705,7 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, | |||
705 | dev_err(&pdev->dev, | 705 | dev_err(&pdev->dev, |
706 | "%s: ERROR: Failed to allocate I2S-controller!\n", | 706 | "%s: ERROR: Failed to allocate I2S-controller!\n", |
707 | __func__); | 707 | __func__); |
708 | goto err_i2s_cont; | 708 | return -ENOMEM; |
709 | } | 709 | } |
710 | i2s_cont->dev.parent = &pdev->dev; | 710 | i2s_cont->dev.parent = &pdev->dev; |
711 | i2s_cont->data = (void *)msp; | 711 | i2s_cont->data = (void *)msp; |
@@ -716,14 +716,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, | |||
716 | msp->i2s_cont = i2s_cont; | 716 | msp->i2s_cont = i2s_cont; |
717 | 717 | ||
718 | return 0; | 718 | return 0; |
719 | |||
720 | err_i2s_cont: | ||
721 | iounmap(msp->registers); | ||
722 | |||
723 | err_res: | ||
724 | devm_kfree(&pdev->dev, msp); | ||
725 | |||
726 | return ret; | ||
727 | } | 719 | } |
728 | 720 | ||
729 | void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev, | 721 | void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev, |
@@ -732,11 +724,6 @@ void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev, | |||
732 | dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id); | 724 | dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id); |
733 | 725 | ||
734 | device_unregister(&msp->i2s_cont->dev); | 726 | device_unregister(&msp->i2s_cont->dev); |
735 | devm_kfree(&pdev->dev, msp->i2s_cont); | ||
736 | |||
737 | iounmap(msp->registers); | ||
738 | |||
739 | devm_kfree(&pdev->dev, msp); | ||
740 | } | 727 | } |
741 | 728 | ||
742 | MODULE_LICENSE("GPL v2"); | 729 | MODULE_LICENSE("GPL v2"); |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 246852397e30..d617f69131d7 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -1976,9 +1976,10 @@ static long kvm_vcpu_compat_ioctl(struct file *filp, | |||
1976 | if (copy_from_user(&csigset, sigmask_arg->sigset, | 1976 | if (copy_from_user(&csigset, sigmask_arg->sigset, |
1977 | sizeof csigset)) | 1977 | sizeof csigset)) |
1978 | goto out; | 1978 | goto out; |
1979 | } | 1979 | sigset_from_compat(&sigset, &csigset); |
1980 | sigset_from_compat(&sigset, &csigset); | 1980 | r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset); |
1981 | r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset); | 1981 | } else |
1982 | r = kvm_vcpu_ioctl_set_sigmask(vcpu, NULL); | ||
1982 | break; | 1983 | break; |
1983 | } | 1984 | } |
1984 | default: | 1985 | default: |