diff options
285 files changed, 5662 insertions, 2003 deletions
diff --git a/Documentation/devicetree/bindings/input/touchscreen/tsc2005.txt b/Documentation/devicetree/bindings/input/touchscreen/tsc2005.txt index 4b641c7bf1c2..09089a6d69ed 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/tsc2005.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/tsc2005.txt | |||
@@ -32,8 +32,8 @@ Example: | |||
32 | touchscreen-fuzz-x = <4>; | 32 | touchscreen-fuzz-x = <4>; |
33 | touchscreen-fuzz-y = <7>; | 33 | touchscreen-fuzz-y = <7>; |
34 | touchscreen-fuzz-pressure = <2>; | 34 | touchscreen-fuzz-pressure = <2>; |
35 | touchscreen-max-x = <4096>; | 35 | touchscreen-size-x = <4096>; |
36 | touchscreen-max-y = <4096>; | 36 | touchscreen-size-y = <4096>; |
37 | touchscreen-max-pressure = <2048>; | 37 | touchscreen-max-pressure = <2048>; |
38 | 38 | ||
39 | ti,x-plate-ohms = <280>; | 39 | ti,x-plate-ohms = <280>; |
diff --git a/Documentation/devicetree/bindings/sound/mt8173-max98090.txt b/Documentation/devicetree/bindings/sound/mt8173-max98090.txt new file mode 100644 index 000000000000..829bd26d17f8 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8173-max98090.txt | |||
@@ -0,0 +1,13 @@ | |||
1 | MT8173 with MAX98090 CODEC | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "mediatek,mt8173-max98090" | ||
5 | - mediatek,audio-codec: the phandle of the MAX98090 audio codec | ||
6 | |||
7 | Example: | ||
8 | |||
9 | sound { | ||
10 | compatible = "mediatek,mt8173-max98090"; | ||
11 | mediatek,audio-codec = <&max98090>; | ||
12 | }; | ||
13 | |||
diff --git a/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt new file mode 100644 index 000000000000..61e98c976bd4 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5676.txt | |||
@@ -0,0 +1,13 @@ | |||
1 | MT8173 with RT5650 RT5676 CODECS | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "mediatek,mt8173-rt5650-rt5676" | ||
5 | - mediatek,audio-codec: the phandles of rt5650 and rt5676 codecs | ||
6 | |||
7 | Example: | ||
8 | |||
9 | sound { | ||
10 | compatible = "mediatek,mt8173-rt5650-rt5676"; | ||
11 | mediatek,audio-codec = <&rt5650 &rt5676>; | ||
12 | }; | ||
13 | |||
diff --git a/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt b/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt new file mode 100644 index 000000000000..e302c7f43b95 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt | |||
@@ -0,0 +1,45 @@ | |||
1 | Mediatek AFE PCM controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible = "mediatek,mt8173-afe-pcm"; | ||
5 | - reg: register location and size | ||
6 | - interrupts: Should contain AFE interrupt | ||
7 | - clock-names: should have these clock names: | ||
8 | "infra_sys_audio_clk", | ||
9 | "top_pdn_audio", | ||
10 | "top_pdn_aud_intbus", | ||
11 | "bck0", | ||
12 | "bck1", | ||
13 | "i2s0_m", | ||
14 | "i2s1_m", | ||
15 | "i2s2_m", | ||
16 | "i2s3_m", | ||
17 | "i2s3_b"; | ||
18 | |||
19 | Example: | ||
20 | |||
21 | afe: mt8173-afe-pcm@11220000 { | ||
22 | compatible = "mediatek,mt8173-afe-pcm"; | ||
23 | reg = <0 0x11220000 0 0x1000>; | ||
24 | interrupts = <GIC_SPI 134 IRQ_TYPE_EDGE_FALLING>; | ||
25 | clocks = <&infracfg INFRA_AUDIO>, | ||
26 | <&topckgen TOP_AUDIO_SEL>, | ||
27 | <&topckgen TOP_AUD_INTBUS_SEL>, | ||
28 | <&topckgen TOP_APLL1_DIV0>, | ||
29 | <&topckgen TOP_APLL2_DIV0>, | ||
30 | <&topckgen TOP_I2S0_M_CK_SEL>, | ||
31 | <&topckgen TOP_I2S1_M_CK_SEL>, | ||
32 | <&topckgen TOP_I2S2_M_CK_SEL>, | ||
33 | <&topckgen TOP_I2S3_M_CK_SEL>, | ||
34 | <&topckgen TOP_I2S3_B_CK_SEL>; | ||
35 | clock-names = "infra_sys_audio_clk", | ||
36 | "top_pdn_audio", | ||
37 | "top_pdn_aud_intbus", | ||
38 | "bck0", | ||
39 | "bck1", | ||
40 | "i2s0_m", | ||
41 | "i2s1_m", | ||
42 | "i2s2_m", | ||
43 | "i2s3_m", | ||
44 | "i2s3_b"; | ||
45 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt b/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt new file mode 100644 index 000000000000..48129368d4d9 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt | |||
@@ -0,0 +1,60 @@ | |||
1 | * Qualcomm Technologies APQ8016 SBC ASoC machine driver | ||
2 | |||
3 | This node models the Qualcomm Technologies APQ8016 SBC ASoC machine driver | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : "qcom,apq8016-sbc-sndcard" | ||
8 | |||
9 | - pinctrl-N : One property must exist for each entry in | ||
10 | pinctrl-names. See ../pinctrl/pinctrl-bindings.txt | ||
11 | for details of the property values. | ||
12 | - pinctrl-names : Must contain a "default" entry. | ||
13 | - reg : Must contain an address for each entry in reg-names. | ||
14 | - reg-names : A list which must include the following entries: | ||
15 | * "mic-iomux" | ||
16 | * "spkr-iomux" | ||
17 | - qcom,model : Name of the sound card. | ||
18 | |||
19 | Dai-link subnode properties and subnodes: | ||
20 | |||
21 | Required dai-link subnodes: | ||
22 | |||
23 | - cpu : CPU sub-node | ||
24 | - codec : CODEC sub-node | ||
25 | |||
26 | Required CPU/CODEC subnodes properties: | ||
27 | |||
28 | -link-name : Name of the dai link. | ||
29 | -sound-dai : phandle and port of CPU/CODEC | ||
30 | -capture-dai : phandle and port of CPU/CODEC | ||
31 | |||
32 | Example: | ||
33 | |||
34 | sound: sound { | ||
35 | compatible = "qcom,apq8016-sbc-sndcard"; | ||
36 | reg = <0x07702000 0x4>, <0x07702004 0x4>; | ||
37 | reg-names = "mic-iomux", "spkr-iomux"; | ||
38 | qcom,model = "DB410c"; | ||
39 | |||
40 | /* I2S - Internal codec */ | ||
41 | internal-dai-link@0 { | ||
42 | cpu { /* PRIMARY */ | ||
43 | sound-dai = <&lpass MI2S_PRIMARY>; | ||
44 | }; | ||
45 | codec { | ||
46 | sound-dai = <&wcd_codec 0>; | ||
47 | }; | ||
48 | }; | ||
49 | |||
50 | /* External Primary or External Secondary -ADV7533 HDMI */ | ||
51 | external-dai-link@0 { | ||
52 | link-name = "ADV7533"; | ||
53 | cpu { /* QUAT */ | ||
54 | sound-dai = <&lpass MI2S_QUATERNARY>; | ||
55 | }; | ||
56 | codec { | ||
57 | sound-dai = <&adv_bridge 0>; | ||
58 | }; | ||
59 | }; | ||
60 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/rt5645.txt b/Documentation/devicetree/bindings/sound/rt5645.txt new file mode 100644 index 000000000000..7cee1f518f59 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/rt5645.txt | |||
@@ -0,0 +1,72 @@ | |||
1 | RT5650/RT5645 audio CODEC | ||
2 | |||
3 | This device supports I2C only. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : One of "realtek,rt5645" or "realtek,rt5650". | ||
8 | |||
9 | - reg : The I2C address of the device. | ||
10 | |||
11 | - interrupts : The CODEC's interrupt output. | ||
12 | |||
13 | Optional properties: | ||
14 | |||
15 | - hp-detect-gpios: | ||
16 | a GPIO spec for the external headphone detect pin. If jd-mode = 0, | ||
17 | we will get the JD status by getting the value of hp-detect-gpios. | ||
18 | |||
19 | - realtek,in2-differential | ||
20 | Boolean. Indicate MIC2 input are differential, rather than single-ended. | ||
21 | |||
22 | - realtek,dmic1-data-pin | ||
23 | 0: dmic1 is not used | ||
24 | 1: using IN2P pin as dmic1 data pin | ||
25 | 2: using GPIO6 pin as dmic1 data pin | ||
26 | 3: using GPIO10 pin as dmic1 data pin | ||
27 | 4: using GPIO12 pin as dmic1 data pin | ||
28 | |||
29 | - realtek,dmic2-data-pin | ||
30 | 0: dmic2 is not used | ||
31 | 1: using IN2N pin as dmic2 data pin | ||
32 | 2: using GPIO5 pin as dmic2 data pin | ||
33 | 3: using GPIO11 pin as dmic2 data pin | ||
34 | |||
35 | -- realtek,jd-mode : The JD mode of rt5645/rt5650 | ||
36 | 0 : rt5645/rt5650 JD function is not used | ||
37 | 1 : Mode-0 (VDD=3.3V), two port jack detection | ||
38 | 2 : Mode-1 (VDD=3.3V), one port jack detection | ||
39 | 3 : Mode-2 (VDD=1.8V), one port jack detection | ||
40 | |||
41 | Pins on the device (for linking into audio routes) for RT5645/RT5650: | ||
42 | |||
43 | * DMIC L1 | ||
44 | * DMIC R1 | ||
45 | * DMIC L2 | ||
46 | * DMIC R2 | ||
47 | * IN1P | ||
48 | * IN1N | ||
49 | * IN2P | ||
50 | * IN2N | ||
51 | * Haptic Generator | ||
52 | * HPOL | ||
53 | * HPOR | ||
54 | * LOUTL | ||
55 | * LOUTR | ||
56 | * PDM1L | ||
57 | * PDM1R | ||
58 | * SPOL | ||
59 | * SPOR | ||
60 | |||
61 | Example: | ||
62 | |||
63 | codec: rt5650@1a { | ||
64 | compatible = "realtek,rt5650"; | ||
65 | reg = <0x1a>; | ||
66 | hp-detect-gpios = <&gpio 19 0>; | ||
67 | interrupt-parent = <&gpio>; | ||
68 | interrupts = <7 IRQ_TYPE_EDGE_FALLING>; | ||
69 | realtek,dmic-en = "true"; | ||
70 | realtek,en-jd-func = "true"; | ||
71 | realtek,jd-mode = <3>; | ||
72 | }; \ No newline at end of file | ||
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt index 73bf314f7240..cf3979eb3578 100644 --- a/Documentation/devicetree/bindings/sound/simple-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-card.txt | |||
@@ -16,7 +16,8 @@ Optional properties: | |||
16 | connection's sink, the second being the connection's | 16 | connection's sink, the second being the connection's |
17 | source. | 17 | source. |
18 | - simple-audio-card,mclk-fs : Multiplication factor between stream rate and codec | 18 | - simple-audio-card,mclk-fs : Multiplication factor between stream rate and codec |
19 | mclk. | 19 | mclk. When defined, mclk-fs property defined in |
20 | dai-link sub nodes are ignored. | ||
20 | - simple-audio-card,hp-det-gpio : Reference to GPIO that signals when | 21 | - simple-audio-card,hp-det-gpio : Reference to GPIO that signals when |
21 | headphones are attached. | 22 | headphones are attached. |
22 | - simple-audio-card,mic-det-gpio : Reference to GPIO that signals when | 23 | - simple-audio-card,mic-det-gpio : Reference to GPIO that signals when |
@@ -55,6 +56,9 @@ Optional dai-link subnode properties: | |||
55 | dai-link uses bit clock inversion. | 56 | dai-link uses bit clock inversion. |
56 | - frame-inversion : bool property. Add this if the | 57 | - frame-inversion : bool property. Add this if the |
57 | dai-link uses frame clock inversion. | 58 | dai-link uses frame clock inversion. |
59 | - mclk-fs : Multiplication factor between stream | ||
60 | rate and codec mclk, applied only for | ||
61 | the dai-link. | ||
58 | 62 | ||
59 | For backward compatibility the frame-master and bitclock-master | 63 | For backward compatibility the frame-master and bitclock-master |
60 | properties can be used as booleans in codec subnode to indicate if the | 64 | properties can be used as booleans in codec subnode to indicate if the |
diff --git a/Documentation/devicetree/bindings/sound/tas2552.txt b/Documentation/devicetree/bindings/sound/tas2552.txt index 55e2a0af5645..c49992c0b62a 100644 --- a/Documentation/devicetree/bindings/sound/tas2552.txt +++ b/Documentation/devicetree/bindings/sound/tas2552.txt | |||
@@ -14,6 +14,12 @@ Required properties: | |||
14 | Optional properties: | 14 | Optional properties: |
15 | - enable-gpio - gpio pin to enable/disable the device | 15 | - enable-gpio - gpio pin to enable/disable the device |
16 | 16 | ||
17 | tas2552 can receive it's reference clock via MCLK, BCLK, IVCLKIN pin or use the | ||
18 | internal 1.8MHz. This CLKIN is used by the PLL. In addition to PLL, the PDM | ||
19 | reference clock is also selectable: PLL, IVCLKIN, BCLK or MCLK. | ||
20 | For system integration the dt-bindings/sound/tas2552.h header file provides | ||
21 | defined values to selct and configure the PLL and PDM reference clocks. | ||
22 | |||
17 | Example: | 23 | Example: |
18 | 24 | ||
19 | tas2552: tas2552@41 { | 25 | tas2552: tas2552@41 { |
diff --git a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt index dc2a18f0b3a1..ddbe304beb21 100644 --- a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt +++ b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt | |||
@@ -15,10 +15,8 @@ Optional properties: | |||
15 | - phys: phandle + phy specifier pair | 15 | - phys: phandle + phy specifier pair |
16 | - phy-names: must be "usb" | 16 | - phy-names: must be "usb" |
17 | - dmas: Must contain a list of references to DMA specifiers. | 17 | - dmas: Must contain a list of references to DMA specifiers. |
18 | - dma-names : Must contain a list of DMA names: | 18 | - dma-names : named "ch%d", where %d is the channel number ranging from zero |
19 | - tx0 ... tx<n> | 19 | to the number of channels (DnFIFOs) minus one. |
20 | - rx0 ... rx<n> | ||
21 | - This <n> means DnFIFO in USBHS module. | ||
22 | 20 | ||
23 | Example: | 21 | Example: |
24 | usbhs: usb@e6590000 { | 22 | usbhs: usb@e6590000 { |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 61ab1628a057..6726139bd289 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1481,6 +1481,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1481 | By default, super page will be supported if Intel IOMMU | 1481 | By default, super page will be supported if Intel IOMMU |
1482 | has the capability. With this option, super page will | 1482 | has the capability. With this option, super page will |
1483 | not be supported. | 1483 | not be supported. |
1484 | ecs_off [Default Off] | ||
1485 | By default, extended context tables will be supported if | ||
1486 | the hardware advertises that it has support both for the | ||
1487 | extended tables themselves, and also PASID support. With | ||
1488 | this option set, extended tables will not be used even | ||
1489 | on hardware which claims to support them. | ||
1484 | 1490 | ||
1485 | intel_idle.max_cstate= [KNL,HW,ACPI,X86] | 1491 | intel_idle.max_cstate= [KNL,HW,ACPI,X86] |
1486 | 0 disables intel_idle and fall back on acpi_idle. | 1492 | 0 disables intel_idle and fall back on acpi_idle. |
diff --git a/Documentation/networking/udplite.txt b/Documentation/networking/udplite.txt index d727a3829100..53a726855e49 100644 --- a/Documentation/networking/udplite.txt +++ b/Documentation/networking/udplite.txt | |||
@@ -20,7 +20,7 @@ | |||
20 | files/UDP-Lite-HOWTO.txt | 20 | files/UDP-Lite-HOWTO.txt |
21 | 21 | ||
22 | o The Wireshark UDP-Lite WiKi (with capture files): | 22 | o The Wireshark UDP-Lite WiKi (with capture files): |
23 | http://wiki.wireshark.org/Lightweight_User_Datagram_Protocol | 23 | https://wiki.wireshark.org/Lightweight_User_Datagram_Protocol |
24 | 24 | ||
25 | o The Protocol Spec, RFC 3828, http://www.ietf.org/rfc/rfc3828.txt | 25 | o The Protocol Spec, RFC 3828, http://www.ietf.org/rfc/rfc3828.txt |
26 | 26 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 34d9b3bf4e2e..8939e1b29f6d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -51,9 +51,9 @@ trivial patch so apply some common sense. | |||
51 | or does something very odd once a month document it. | 51 | or does something very odd once a month document it. |
52 | 52 | ||
53 | PLEASE remember that submissions must be made under the terms | 53 | PLEASE remember that submissions must be made under the terms |
54 | of the OSDL certificate of contribution and should include a | 54 | of the Linux Foundation certificate of contribution and should |
55 | Signed-off-by: line. The current version of this "Developer's | 55 | include a Signed-off-by: line. The current version of this |
56 | Certificate of Origin" (DCO) is listed in the file | 56 | "Developer's Certificate of Origin" (DCO) is listed in the file |
57 | Documentation/SubmittingPatches. | 57 | Documentation/SubmittingPatches. |
58 | 58 | ||
59 | 6. Make sure you have the right to send any changes you make. If you | 59 | 6. Make sure you have the right to send any changes you make. If you |
@@ -7575,6 +7575,7 @@ F: drivers/pci/host/pci-exynos.c | |||
7575 | 7575 | ||
7576 | PCI DRIVER FOR SYNOPSIS DESIGNWARE | 7576 | PCI DRIVER FOR SYNOPSIS DESIGNWARE |
7577 | M: Jingoo Han <jingoohan1@gmail.com> | 7577 | M: Jingoo Han <jingoohan1@gmail.com> |
7578 | M: Pratyush Anand <pratyush.anand@gmail.com> | ||
7578 | L: linux-pci@vger.kernel.org | 7579 | L: linux-pci@vger.kernel.org |
7579 | S: Maintained | 7580 | S: Maintained |
7580 | F: drivers/pci/host/*designware* | 7581 | F: drivers/pci/host/*designware* |
@@ -7588,8 +7589,9 @@ F: Documentation/devicetree/bindings/pci/host-generic-pci.txt | |||
7588 | F: drivers/pci/host/pci-host-generic.c | 7589 | F: drivers/pci/host/pci-host-generic.c |
7589 | 7590 | ||
7590 | PCIE DRIVER FOR ST SPEAR13XX | 7591 | PCIE DRIVER FOR ST SPEAR13XX |
7592 | M: Pratyush Anand <pratyush.anand@gmail.com> | ||
7591 | L: linux-pci@vger.kernel.org | 7593 | L: linux-pci@vger.kernel.org |
7592 | S: Orphan | 7594 | S: Maintained |
7593 | F: drivers/pci/host/*spear* | 7595 | F: drivers/pci/host/*spear* |
7594 | 7596 | ||
7595 | PCMCIA SUBSYSTEM | 7597 | PCMCIA SUBSYSTEM |
@@ -10593,8 +10595,7 @@ F: drivers/virtio/virtio_input.c | |||
10593 | F: include/uapi/linux/virtio_input.h | 10595 | F: include/uapi/linux/virtio_input.h |
10594 | 10596 | ||
10595 | VIA RHINE NETWORK DRIVER | 10597 | VIA RHINE NETWORK DRIVER |
10596 | M: Roger Luethi <rl@hellgate.ch> | 10598 | S: Orphan |
10597 | S: Maintained | ||
10598 | F: drivers/net/ethernet/via/via-rhine.c | 10599 | F: drivers/net/ethernet/via/via-rhine.c |
10599 | 10600 | ||
10600 | VIA SD/MMC CARD CONTROLLER DRIVER | 10601 | VIA SD/MMC CARD CONTROLLER DRIVER |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 4 | 1 | VERSION = 4 |
2 | PATCHLEVEL = 1 | 2 | PATCHLEVEL = 1 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = -rc6 | 4 | EXTRAVERSION = -rc8 |
5 | NAME = Hurr durr I'ma sheep | 5 | NAME = Hurr durr I'ma sheep |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi index c3255e0c90aa..dbb3f4d2bf84 100644 --- a/arch/arm/boot/dts/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi | |||
@@ -223,6 +223,25 @@ | |||
223 | /include/ "tps65217.dtsi" | 223 | /include/ "tps65217.dtsi" |
224 | 224 | ||
225 | &tps { | 225 | &tps { |
226 | /* | ||
227 | * Configure pmic to enter OFF-state instead of SLEEP-state ("RTC-only | ||
228 | * mode") at poweroff. Most BeagleBone versions do not support RTC-only | ||
229 | * mode and risk hardware damage if this mode is entered. | ||
230 | * | ||
231 | * For details, see linux-omap mailing list May 2015 thread | ||
232 | * [PATCH] ARM: dts: am335x-bone* enable pmic-shutdown-controller | ||
233 | * In particular, messages: | ||
234 | * http://www.spinics.net/lists/linux-omap/msg118585.html | ||
235 | * http://www.spinics.net/lists/linux-omap/msg118615.html | ||
236 | * | ||
237 | * You can override this later with | ||
238 | * &tps { /delete-property/ ti,pmic-shutdown-controller; } | ||
239 | * if you want to use RTC-only mode and made sure you are not affected | ||
240 | * by the hardware problems. (Tip: double-check by performing a current | ||
241 | * measurement after shutdown: it should be less than 1 mA.) | ||
242 | */ | ||
243 | ti,pmic-shutdown-controller; | ||
244 | |||
226 | regulators { | 245 | regulators { |
227 | dcdc1_reg: regulator@0 { | 246 | dcdc1_reg: regulator@0 { |
228 | regulator-name = "vdds_dpr"; | 247 | regulator-name = "vdds_dpr"; |
diff --git a/arch/arm/boot/dts/am35xx-clocks.dtsi b/arch/arm/boot/dts/am35xx-clocks.dtsi index 518b8fde88b0..18cc826e9db5 100644 --- a/arch/arm/boot/dts/am35xx-clocks.dtsi +++ b/arch/arm/boot/dts/am35xx-clocks.dtsi | |||
@@ -12,7 +12,7 @@ | |||
12 | #clock-cells = <0>; | 12 | #clock-cells = <0>; |
13 | compatible = "ti,am35xx-gate-clock"; | 13 | compatible = "ti,am35xx-gate-clock"; |
14 | clocks = <&ipss_ick>; | 14 | clocks = <&ipss_ick>; |
15 | reg = <0x059c>; | 15 | reg = <0x032c>; |
16 | ti,bit-shift = <1>; | 16 | ti,bit-shift = <1>; |
17 | }; | 17 | }; |
18 | 18 | ||
@@ -20,7 +20,7 @@ | |||
20 | #clock-cells = <0>; | 20 | #clock-cells = <0>; |
21 | compatible = "ti,gate-clock"; | 21 | compatible = "ti,gate-clock"; |
22 | clocks = <&rmii_ck>; | 22 | clocks = <&rmii_ck>; |
23 | reg = <0x059c>; | 23 | reg = <0x032c>; |
24 | ti,bit-shift = <9>; | 24 | ti,bit-shift = <9>; |
25 | }; | 25 | }; |
26 | 26 | ||
@@ -28,7 +28,7 @@ | |||
28 | #clock-cells = <0>; | 28 | #clock-cells = <0>; |
29 | compatible = "ti,am35xx-gate-clock"; | 29 | compatible = "ti,am35xx-gate-clock"; |
30 | clocks = <&ipss_ick>; | 30 | clocks = <&ipss_ick>; |
31 | reg = <0x059c>; | 31 | reg = <0x032c>; |
32 | ti,bit-shift = <2>; | 32 | ti,bit-shift = <2>; |
33 | }; | 33 | }; |
34 | 34 | ||
@@ -36,7 +36,7 @@ | |||
36 | #clock-cells = <0>; | 36 | #clock-cells = <0>; |
37 | compatible = "ti,gate-clock"; | 37 | compatible = "ti,gate-clock"; |
38 | clocks = <&pclk_ck>; | 38 | clocks = <&pclk_ck>; |
39 | reg = <0x059c>; | 39 | reg = <0x032c>; |
40 | ti,bit-shift = <10>; | 40 | ti,bit-shift = <10>; |
41 | }; | 41 | }; |
42 | 42 | ||
@@ -44,7 +44,7 @@ | |||
44 | #clock-cells = <0>; | 44 | #clock-cells = <0>; |
45 | compatible = "ti,am35xx-gate-clock"; | 45 | compatible = "ti,am35xx-gate-clock"; |
46 | clocks = <&ipss_ick>; | 46 | clocks = <&ipss_ick>; |
47 | reg = <0x059c>; | 47 | reg = <0x032c>; |
48 | ti,bit-shift = <0>; | 48 | ti,bit-shift = <0>; |
49 | }; | 49 | }; |
50 | 50 | ||
@@ -52,7 +52,7 @@ | |||
52 | #clock-cells = <0>; | 52 | #clock-cells = <0>; |
53 | compatible = "ti,gate-clock"; | 53 | compatible = "ti,gate-clock"; |
54 | clocks = <&sys_ck>; | 54 | clocks = <&sys_ck>; |
55 | reg = <0x059c>; | 55 | reg = <0x032c>; |
56 | ti,bit-shift = <8>; | 56 | ti,bit-shift = <8>; |
57 | }; | 57 | }; |
58 | 58 | ||
@@ -60,7 +60,7 @@ | |||
60 | #clock-cells = <0>; | 60 | #clock-cells = <0>; |
61 | compatible = "ti,am35xx-gate-clock"; | 61 | compatible = "ti,am35xx-gate-clock"; |
62 | clocks = <&sys_ck>; | 62 | clocks = <&sys_ck>; |
63 | reg = <0x059c>; | 63 | reg = <0x032c>; |
64 | ti,bit-shift = <3>; | 64 | ti,bit-shift = <3>; |
65 | }; | 65 | }; |
66 | }; | 66 | }; |
diff --git a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts index a2cf2154dcdb..fdd187c55aa5 100644 --- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts +++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts | |||
@@ -95,6 +95,11 @@ | |||
95 | 95 | ||
96 | internal-regs { | 96 | internal-regs { |
97 | 97 | ||
98 | rtc@10300 { | ||
99 | /* No crystal connected to the internal RTC */ | ||
100 | status = "disabled"; | ||
101 | }; | ||
102 | |||
98 | /* J10: VCC, NC, RX, NC, TX, GND */ | 103 | /* J10: VCC, NC, RX, NC, TX, GND */ |
99 | serial@12000 { | 104 | serial@12000 { |
100 | status = "okay"; | 105 | status = "okay"; |
diff --git a/arch/arm/boot/dts/dm816x.dtsi b/arch/arm/boot/dts/dm816x.dtsi index de8427be830a..289806adb343 100644 --- a/arch/arm/boot/dts/dm816x.dtsi +++ b/arch/arm/boot/dts/dm816x.dtsi | |||
@@ -382,7 +382,7 @@ | |||
382 | ti,hwmods = "usb_otg_hs"; | 382 | ti,hwmods = "usb_otg_hs"; |
383 | 383 | ||
384 | usb0: usb@47401000 { | 384 | usb0: usb@47401000 { |
385 | compatible = "ti,musb-am33xx"; | 385 | compatible = "ti,musb-dm816"; |
386 | reg = <0x47401400 0x400 | 386 | reg = <0x47401400 0x400 |
387 | 0x47401000 0x200>; | 387 | 0x47401000 0x200>; |
388 | reg-names = "mc", "control"; | 388 | reg-names = "mc", "control"; |
@@ -422,7 +422,7 @@ | |||
422 | }; | 422 | }; |
423 | 423 | ||
424 | usb1: usb@47401800 { | 424 | usb1: usb@47401800 { |
425 | compatible = "ti,musb-am33xx"; | 425 | compatible = "ti,musb-dm816"; |
426 | reg = <0x47401c00 0x400 | 426 | reg = <0x47401c00 0x400 |
427 | 0x47401800 0x200>; | 427 | 0x47401800 0x200>; |
428 | reg-names = "mc", "control"; | 428 | reg-names = "mc", "control"; |
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index 5c16145920ea..5f5e0f3d5b64 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts | |||
@@ -832,8 +832,8 @@ | |||
832 | touchscreen-fuzz-x = <4>; | 832 | touchscreen-fuzz-x = <4>; |
833 | touchscreen-fuzz-y = <7>; | 833 | touchscreen-fuzz-y = <7>; |
834 | touchscreen-fuzz-pressure = <2>; | 834 | touchscreen-fuzz-pressure = <2>; |
835 | touchscreen-max-x = <4096>; | 835 | touchscreen-size-x = <4096>; |
836 | touchscreen-max-y = <4096>; | 836 | touchscreen-size-y = <4096>; |
837 | touchscreen-max-pressure = <2048>; | 837 | touchscreen-max-pressure = <2048>; |
838 | 838 | ||
839 | ti,x-plate-ohms = <280>; | 839 | ti,x-plate-ohms = <280>; |
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index c0b6dccbf7bd..7d23ce04cad5 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c | |||
@@ -87,8 +87,8 @@ static unsigned int exynos_pmu_spare3; | |||
87 | static u32 exynos_irqwake_intmask = 0xffffffff; | 87 | static u32 exynos_irqwake_intmask = 0xffffffff; |
88 | 88 | ||
89 | static const struct exynos_wkup_irq exynos3250_wkup_irq[] = { | 89 | static const struct exynos_wkup_irq exynos3250_wkup_irq[] = { |
90 | { 105, BIT(1) }, /* RTC alarm */ | 90 | { 73, BIT(1) }, /* RTC alarm */ |
91 | { 106, BIT(2) }, /* RTC tick */ | 91 | { 74, BIT(2) }, /* RTC tick */ |
92 | { /* sentinel */ }, | 92 | { /* sentinel */ }, |
93 | }; | 93 | }; |
94 | 94 | ||
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index d1dedc8195ed..eafd120b53f1 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S | |||
@@ -203,23 +203,8 @@ save_context_wfi: | |||
203 | */ | 203 | */ |
204 | ldr r1, kernel_flush | 204 | ldr r1, kernel_flush |
205 | blx r1 | 205 | blx r1 |
206 | /* | ||
207 | * The kernel doesn't interwork: v7_flush_dcache_all in particluar will | ||
208 | * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled. | ||
209 | * This sequence switches back to ARM. Note that .align may insert a | ||
210 | * nop: bx pc needs to be word-aligned in order to work. | ||
211 | */ | ||
212 | THUMB( .thumb ) | ||
213 | THUMB( .align ) | ||
214 | THUMB( bx pc ) | ||
215 | THUMB( nop ) | ||
216 | .arm | ||
217 | |||
218 | b omap3_do_wfi | 206 | b omap3_do_wfi |
219 | 207 | ENDPROC(omap34xx_cpu_suspend) | |
220 | /* | ||
221 | * Local variables | ||
222 | */ | ||
223 | omap3_do_wfi_sram_addr: | 208 | omap3_do_wfi_sram_addr: |
224 | .word omap3_do_wfi_sram | 209 | .word omap3_do_wfi_sram |
225 | kernel_flush: | 210 | kernel_flush: |
@@ -364,10 +349,7 @@ exit_nonoff_modes: | |||
364 | * =================================== | 349 | * =================================== |
365 | */ | 350 | */ |
366 | ldmfd sp!, {r4 - r11, pc} @ restore regs and return | 351 | ldmfd sp!, {r4 - r11, pc} @ restore regs and return |
367 | 352 | ENDPROC(omap3_do_wfi) | |
368 | /* | ||
369 | * Local variables | ||
370 | */ | ||
371 | sdrc_power: | 353 | sdrc_power: |
372 | .word SDRC_POWER_V | 354 | .word SDRC_POWER_V |
373 | cm_idlest1_core: | 355 | cm_idlest1_core: |
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts index 43d54017b779..d0ab012fa379 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts +++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts | |||
@@ -16,7 +16,8 @@ | |||
16 | #include "mt8173.dtsi" | 16 | #include "mt8173.dtsi" |
17 | 17 | ||
18 | / { | 18 | / { |
19 | model = "mediatek,mt8173-evb"; | 19 | model = "MediaTek MT8173 evaluation board"; |
20 | compatible = "mediatek,mt8173-evb", "mediatek,mt8173"; | ||
20 | 21 | ||
21 | aliases { | 22 | aliases { |
22 | serial0 = &uart0; | 23 | serial0 = &uart0; |
diff --git a/arch/blackfin/include/asm/io.h b/arch/blackfin/include/asm/io.h index 4e8ad0523118..6abebe82d4e9 100644 --- a/arch/blackfin/include/asm/io.h +++ b/arch/blackfin/include/asm/io.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/compiler.h> | 10 | #include <linux/compiler.h> |
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | #include <asm/byteorder.h> | 12 | #include <asm/byteorder.h> |
13 | #include <asm/def_LPBlackfin.h> | ||
13 | 14 | ||
14 | #define __raw_readb bfin_read8 | 15 | #define __raw_readb bfin_read8 |
15 | #define __raw_readw bfin_read16 | 16 | #define __raw_readw bfin_read16 |
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 15051e9c2c6f..b054c5c6e713 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c | |||
@@ -127,7 +127,7 @@ int smp_num_siblings = 1; | |||
127 | volatile int ia64_cpu_to_sapicid[NR_CPUS]; | 127 | volatile int ia64_cpu_to_sapicid[NR_CPUS]; |
128 | EXPORT_SYMBOL(ia64_cpu_to_sapicid); | 128 | EXPORT_SYMBOL(ia64_cpu_to_sapicid); |
129 | 129 | ||
130 | static volatile cpumask_t cpu_callin_map; | 130 | static cpumask_t cpu_callin_map; |
131 | 131 | ||
132 | struct smp_boot_data smp_boot_data __initdata; | 132 | struct smp_boot_data smp_boot_data __initdata; |
133 | 133 | ||
@@ -477,6 +477,7 @@ do_boot_cpu (int sapicid, int cpu, struct task_struct *idle) | |||
477 | for (timeout = 0; timeout < 100000; timeout++) { | 477 | for (timeout = 0; timeout < 100000; timeout++) { |
478 | if (cpumask_test_cpu(cpu, &cpu_callin_map)) | 478 | if (cpumask_test_cpu(cpu, &cpu_callin_map)) |
479 | break; /* It has booted */ | 479 | break; /* It has booted */ |
480 | barrier(); /* Make sure we re-read cpu_callin_map */ | ||
480 | udelay(100); | 481 | udelay(100); |
481 | } | 482 | } |
482 | Dprintk("\n"); | 483 | Dprintk("\n"); |
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index a73c93c3d44a..7fc8397d16f2 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c | |||
@@ -225,7 +225,7 @@ void __init plat_time_init(void) | |||
225 | ddr_clk_rate = ath79_get_sys_clk_rate("ddr"); | 225 | ddr_clk_rate = ath79_get_sys_clk_rate("ddr"); |
226 | ref_clk_rate = ath79_get_sys_clk_rate("ref"); | 226 | ref_clk_rate = ath79_get_sys_clk_rate("ref"); |
227 | 227 | ||
228 | pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, Ref:%lu.%03luMHz", | 228 | pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, Ref:%lu.%03luMHz\n", |
229 | cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000, | 229 | cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000, |
230 | ddr_clk_rate / 1000000, (ddr_clk_rate / 1000) % 1000, | 230 | ddr_clk_rate / 1000000, (ddr_clk_rate / 1000) % 1000, |
231 | ahb_clk_rate / 1000000, (ahb_clk_rate / 1000) % 1000, | 231 | ahb_clk_rate / 1000000, (ahb_clk_rate / 1000) % 1000, |
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile index 558e94977942..68f0c5871adc 100644 --- a/arch/mips/cobalt/Makefile +++ b/arch/mips/cobalt/Makefile | |||
@@ -2,7 +2,6 @@ | |||
2 | # Makefile for the Cobalt micro systems family specific parts of the kernel | 2 | # Makefile for the Cobalt micro systems family specific parts of the kernel |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := buttons.o irq.o lcd.o led.o reset.o rtc.o serial.o setup.o time.o | 5 | obj-y := buttons.o irq.o lcd.o led.o mtd.o reset.o rtc.o serial.o setup.o time.o |
6 | 6 | ||
7 | obj-$(CONFIG_PCI) += pci.o | 7 | obj-$(CONFIG_PCI) += pci.o |
8 | obj-$(CONFIG_MTD_PHYSMAP) += mtd.o | ||
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h index 18ae5ddef118..c28a8499aec7 100644 --- a/arch/mips/include/asm/pgtable-bits.h +++ b/arch/mips/include/asm/pgtable-bits.h | |||
@@ -113,7 +113,7 @@ | |||
113 | #define _PAGE_PRESENT_SHIFT 0 | 113 | #define _PAGE_PRESENT_SHIFT 0 |
114 | #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) | 114 | #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) |
115 | /* R2 or later cores check for RI/XI support to determine _PAGE_READ */ | 115 | /* R2 or later cores check for RI/XI support to determine _PAGE_READ */ |
116 | #ifdef CONFIG_CPU_MIPSR2 | 116 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) |
117 | #define _PAGE_WRITE_SHIFT (_PAGE_PRESENT_SHIFT + 1) | 117 | #define _PAGE_WRITE_SHIFT (_PAGE_PRESENT_SHIFT + 1) |
118 | #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) | 118 | #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) |
119 | #else | 119 | #else |
@@ -135,16 +135,16 @@ | |||
135 | #define _PAGE_SPLITTING (1 << _PAGE_SPLITTING_SHIFT) | 135 | #define _PAGE_SPLITTING (1 << _PAGE_SPLITTING_SHIFT) |
136 | 136 | ||
137 | /* Only R2 or newer cores have the XI bit */ | 137 | /* Only R2 or newer cores have the XI bit */ |
138 | #ifdef CONFIG_CPU_MIPSR2 | 138 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) |
139 | #define _PAGE_NO_EXEC_SHIFT (_PAGE_SPLITTING_SHIFT + 1) | 139 | #define _PAGE_NO_EXEC_SHIFT (_PAGE_SPLITTING_SHIFT + 1) |
140 | #else | 140 | #else |
141 | #define _PAGE_GLOBAL_SHIFT (_PAGE_SPLITTING_SHIFT + 1) | 141 | #define _PAGE_GLOBAL_SHIFT (_PAGE_SPLITTING_SHIFT + 1) |
142 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) | 142 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) |
143 | #endif /* CONFIG_CPU_MIPSR2 */ | 143 | #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ |
144 | 144 | ||
145 | #endif /* CONFIG_64BIT && CONFIG_MIPS_HUGE_TLB_SUPPORT */ | 145 | #endif /* CONFIG_64BIT && CONFIG_MIPS_HUGE_TLB_SUPPORT */ |
146 | 146 | ||
147 | #ifdef CONFIG_CPU_MIPSR2 | 147 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) |
148 | /* XI - page cannot be executed */ | 148 | /* XI - page cannot be executed */ |
149 | #ifndef _PAGE_NO_EXEC_SHIFT | 149 | #ifndef _PAGE_NO_EXEC_SHIFT |
150 | #define _PAGE_NO_EXEC_SHIFT (_PAGE_MODIFIED_SHIFT + 1) | 150 | #define _PAGE_NO_EXEC_SHIFT (_PAGE_MODIFIED_SHIFT + 1) |
@@ -160,10 +160,10 @@ | |||
160 | #define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1) | 160 | #define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1) |
161 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) | 161 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) |
162 | 162 | ||
163 | #else /* !CONFIG_CPU_MIPSR2 */ | 163 | #else /* !CONFIG_CPU_MIPSR2 && !CONFIG_CPU_MIPSR6 */ |
164 | #define _PAGE_GLOBAL_SHIFT (_PAGE_MODIFIED_SHIFT + 1) | 164 | #define _PAGE_GLOBAL_SHIFT (_PAGE_MODIFIED_SHIFT + 1) |
165 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) | 165 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) |
166 | #endif /* CONFIG_CPU_MIPSR2 */ | 166 | #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ |
167 | 167 | ||
168 | #define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1) | 168 | #define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1) |
169 | #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) | 169 | #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) |
@@ -205,7 +205,7 @@ | |||
205 | */ | 205 | */ |
206 | static inline uint64_t pte_to_entrylo(unsigned long pte_val) | 206 | static inline uint64_t pte_to_entrylo(unsigned long pte_val) |
207 | { | 207 | { |
208 | #ifdef CONFIG_CPU_MIPSR2 | 208 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) |
209 | if (cpu_has_rixi) { | 209 | if (cpu_has_rixi) { |
210 | int sa; | 210 | int sa; |
211 | #ifdef CONFIG_32BIT | 211 | #ifdef CONFIG_32BIT |
diff --git a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h index e92d6c4b5ed1..7163cd7fdd69 100644 --- a/arch/mips/include/asm/switch_to.h +++ b/arch/mips/include/asm/switch_to.h | |||
@@ -104,7 +104,6 @@ do { \ | |||
104 | if (test_and_clear_tsk_thread_flag(prev, TIF_USEDMSA)) \ | 104 | if (test_and_clear_tsk_thread_flag(prev, TIF_USEDMSA)) \ |
105 | __fpsave = FP_SAVE_VECTOR; \ | 105 | __fpsave = FP_SAVE_VECTOR; \ |
106 | (last) = resume(prev, next, task_thread_info(next), __fpsave); \ | 106 | (last) = resume(prev, next, task_thread_info(next), __fpsave); \ |
107 | disable_msa(); \ | ||
108 | } while (0) | 107 | } while (0) |
109 | 108 | ||
110 | #define finish_arch_switch(prev) \ | 109 | #define finish_arch_switch(prev) \ |
@@ -122,6 +121,7 @@ do { \ | |||
122 | if (cpu_has_userlocal) \ | 121 | if (cpu_has_userlocal) \ |
123 | write_c0_userlocal(current_thread_info()->tp_value); \ | 122 | write_c0_userlocal(current_thread_info()->tp_value); \ |
124 | __restore_watch(); \ | 123 | __restore_watch(); \ |
124 | disable_msa(); \ | ||
125 | } while (0) | 125 | } while (0) |
126 | 126 | ||
127 | #endif /* _ASM_SWITCH_TO_H */ | 127 | #endif /* _ASM_SWITCH_TO_H */ |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index e36515dcd3b2..209e5b76c1bc 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -74,13 +74,12 @@ static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c) | |||
74 | { | 74 | { |
75 | unsigned long sr, mask, fcsr, fcsr0, fcsr1; | 75 | unsigned long sr, mask, fcsr, fcsr0, fcsr1; |
76 | 76 | ||
77 | fcsr = c->fpu_csr31; | ||
77 | mask = FPU_CSR_ALL_X | FPU_CSR_ALL_E | FPU_CSR_ALL_S | FPU_CSR_RM; | 78 | mask = FPU_CSR_ALL_X | FPU_CSR_ALL_E | FPU_CSR_ALL_S | FPU_CSR_RM; |
78 | 79 | ||
79 | sr = read_c0_status(); | 80 | sr = read_c0_status(); |
80 | __enable_fpu(FPU_AS_IS); | 81 | __enable_fpu(FPU_AS_IS); |
81 | 82 | ||
82 | fcsr = read_32bit_cp1_register(CP1_STATUS); | ||
83 | |||
84 | fcsr0 = fcsr & mask; | 83 | fcsr0 = fcsr & mask; |
85 | write_32bit_cp1_register(CP1_STATUS, fcsr0); | 84 | write_32bit_cp1_register(CP1_STATUS, fcsr0); |
86 | fcsr0 = read_32bit_cp1_register(CP1_STATUS); | 85 | fcsr0 = read_32bit_cp1_register(CP1_STATUS); |
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 51f57d841662..3c8a18a00a65 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c | |||
@@ -109,7 +109,7 @@ void __init init_IRQ(void) | |||
109 | #endif | 109 | #endif |
110 | } | 110 | } |
111 | 111 | ||
112 | #ifdef DEBUG_STACKOVERFLOW | 112 | #ifdef CONFIG_DEBUG_STACKOVERFLOW |
113 | static inline void check_stack_overflow(void) | 113 | static inline void check_stack_overflow(void) |
114 | { | 114 | { |
115 | unsigned long sp; | 115 | unsigned long sp; |
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c index 4b50c5787e25..d5fa3eaf39a1 100644 --- a/arch/mips/kvm/emulate.c +++ b/arch/mips/kvm/emulate.c | |||
@@ -2409,7 +2409,7 @@ enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu, | |||
2409 | if (vcpu->mmio_needed == 2) | 2409 | if (vcpu->mmio_needed == 2) |
2410 | *gpr = *(int16_t *) run->mmio.data; | 2410 | *gpr = *(int16_t *) run->mmio.data; |
2411 | else | 2411 | else |
2412 | *gpr = *(int16_t *) run->mmio.data; | 2412 | *gpr = *(uint16_t *)run->mmio.data; |
2413 | 2413 | ||
2414 | break; | 2414 | break; |
2415 | case 1: | 2415 | case 1: |
diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile index e70c33fdb881..f2e8153e44f5 100644 --- a/arch/mips/loongson/common/Makefile +++ b/arch/mips/loongson/common/Makefile | |||
@@ -3,15 +3,13 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \ | 5 | obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \ |
6 | bonito-irq.o mem.o machtype.o platform.o | 6 | bonito-irq.o mem.o machtype.o platform.o serial.o |
7 | obj-$(CONFIG_PCI) += pci.o | 7 | obj-$(CONFIG_PCI) += pci.o |
8 | 8 | ||
9 | # | 9 | # |
10 | # Serial port support | 10 | # Serial port support |
11 | # | 11 | # |
12 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 12 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
13 | loongson-serial-$(CONFIG_SERIAL_8250) := serial.o | ||
14 | obj-y += $(loongson-serial-m) $(loongson-serial-y) | ||
15 | obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o | 13 | obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o |
16 | obj-$(CONFIG_LOONGSON_MC146818) += rtc.o | 14 | obj-$(CONFIG_LOONGSON_MC146818) += rtc.o |
17 | 15 | ||
diff --git a/arch/mips/loongson/loongson-3/smp.c b/arch/mips/loongson/loongson-3/smp.c index e3c68b5da18d..509877c6e9d9 100644 --- a/arch/mips/loongson/loongson-3/smp.c +++ b/arch/mips/loongson/loongson-3/smp.c | |||
@@ -272,7 +272,7 @@ void loongson3_ipi_interrupt(struct pt_regs *regs) | |||
272 | if (action & SMP_ASK_C0COUNT) { | 272 | if (action & SMP_ASK_C0COUNT) { |
273 | BUG_ON(cpu != 0); | 273 | BUG_ON(cpu != 0); |
274 | c0count = read_c0_count(); | 274 | c0count = read_c0_count(); |
275 | for (i = 1; i < loongson_sysconf.nr_cpus; i++) | 275 | for (i = 1; i < num_possible_cpus(); i++) |
276 | per_cpu(core0_c0count, i) = c0count; | 276 | per_cpu(core0_c0count, i) = c0count; |
277 | } | 277 | } |
278 | } | 278 | } |
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 0dbb65a51ce5..2e03ab173591 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -1372,7 +1372,7 @@ static int probe_scache(void) | |||
1372 | scache_size = addr; | 1372 | scache_size = addr; |
1373 | c->scache.linesz = 16 << ((config & R4K_CONF_SB) >> 22); | 1373 | c->scache.linesz = 16 << ((config & R4K_CONF_SB) >> 22); |
1374 | c->scache.ways = 1; | 1374 | c->scache.ways = 1; |
1375 | c->dcache.waybit = 0; /* does not matter */ | 1375 | c->scache.waybit = 0; /* does not matter */ |
1376 | 1376 | ||
1377 | return 1; | 1377 | return 1; |
1378 | } | 1378 | } |
diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c index 5d6139390bf8..e23fdf2a9c80 100644 --- a/arch/mips/net/bpf_jit.c +++ b/arch/mips/net/bpf_jit.c | |||
@@ -681,11 +681,7 @@ static unsigned int get_stack_depth(struct jit_ctx *ctx) | |||
681 | sp_off += config_enabled(CONFIG_64BIT) ? | 681 | sp_off += config_enabled(CONFIG_64BIT) ? |
682 | (ARGS_USED_BY_JIT + 1) * RSIZE : RSIZE; | 682 | (ARGS_USED_BY_JIT + 1) * RSIZE : RSIZE; |
683 | 683 | ||
684 | /* | 684 | return sp_off; |
685 | * Subtract the bytes for the last registers since we only care about | ||
686 | * the location on the stack pointer. | ||
687 | */ | ||
688 | return sp_off - RSIZE; | ||
689 | } | 685 | } |
690 | 686 | ||
691 | static void build_prologue(struct jit_ctx *ctx) | 687 | static void build_prologue(struct jit_ctx *ctx) |
diff --git a/arch/mips/ralink/ill_acc.c b/arch/mips/ralink/ill_acc.c index e20b02e3ae28..e10d10b9e82a 100644 --- a/arch/mips/ralink/ill_acc.c +++ b/arch/mips/ralink/ill_acc.c | |||
@@ -41,7 +41,7 @@ static irqreturn_t ill_acc_irq_handler(int irq, void *_priv) | |||
41 | addr, (type >> ILL_ACC_OFF_S) & ILL_ACC_OFF_M, | 41 | addr, (type >> ILL_ACC_OFF_S) & ILL_ACC_OFF_M, |
42 | type & ILL_ACC_LEN_M); | 42 | type & ILL_ACC_LEN_M); |
43 | 43 | ||
44 | rt_memc_w32(REG_ILL_ACC_TYPE, REG_ILL_ACC_TYPE); | 44 | rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE); |
45 | 45 | ||
46 | return IRQ_HANDLED; | 46 | return IRQ_HANDLED; |
47 | } | 47 | } |
diff --git a/arch/s390/net/bpf_jit.h b/arch/s390/net/bpf_jit.h index ba8593a515ba..de156ba3bd71 100644 --- a/arch/s390/net/bpf_jit.h +++ b/arch/s390/net/bpf_jit.h | |||
@@ -48,7 +48,9 @@ extern u8 sk_load_word[], sk_load_half[], sk_load_byte[]; | |||
48 | * We get 160 bytes stack space from calling function, but only use | 48 | * We get 160 bytes stack space from calling function, but only use |
49 | * 11 * 8 byte (old backchain + r15 - r6) for storing registers. | 49 | * 11 * 8 byte (old backchain + r15 - r6) for storing registers. |
50 | */ | 50 | */ |
51 | #define STK_OFF (MAX_BPF_STACK + 8 + 4 + 4 + (160 - 11 * 8)) | 51 | #define STK_SPACE (MAX_BPF_STACK + 8 + 4 + 4 + 160) |
52 | #define STK_160_UNUSED (160 - 11 * 8) | ||
53 | #define STK_OFF (STK_SPACE - STK_160_UNUSED) | ||
52 | #define STK_OFF_TMP 160 /* Offset of tmp buffer on stack */ | 54 | #define STK_OFF_TMP 160 /* Offset of tmp buffer on stack */ |
53 | #define STK_OFF_HLEN 168 /* Offset of SKB header length on stack */ | 55 | #define STK_OFF_HLEN 168 /* Offset of SKB header length on stack */ |
54 | 56 | ||
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 20c146d1251a..55423d8be580 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c | |||
@@ -384,13 +384,16 @@ static void bpf_jit_prologue(struct bpf_jit *jit) | |||
384 | } | 384 | } |
385 | /* Setup stack and backchain */ | 385 | /* Setup stack and backchain */ |
386 | if (jit->seen & SEEN_STACK) { | 386 | if (jit->seen & SEEN_STACK) { |
387 | /* lgr %bfp,%r15 (BPF frame pointer) */ | 387 | if (jit->seen & SEEN_FUNC) |
388 | EMIT4(0xb9040000, BPF_REG_FP, REG_15); | 388 | /* lgr %w1,%r15 (backchain) */ |
389 | EMIT4(0xb9040000, REG_W1, REG_15); | ||
390 | /* la %bfp,STK_160_UNUSED(%r15) (BPF frame pointer) */ | ||
391 | EMIT4_DISP(0x41000000, BPF_REG_FP, REG_15, STK_160_UNUSED); | ||
389 | /* aghi %r15,-STK_OFF */ | 392 | /* aghi %r15,-STK_OFF */ |
390 | EMIT4_IMM(0xa70b0000, REG_15, -STK_OFF); | 393 | EMIT4_IMM(0xa70b0000, REG_15, -STK_OFF); |
391 | if (jit->seen & SEEN_FUNC) | 394 | if (jit->seen & SEEN_FUNC) |
392 | /* stg %bfp,152(%r15) (backchain) */ | 395 | /* stg %w1,152(%r15) (backchain) */ |
393 | EMIT6_DISP_LH(0xe3000000, 0x0024, BPF_REG_FP, REG_0, | 396 | EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0, |
394 | REG_15, 152); | 397 | REG_15, 152); |
395 | } | 398 | } |
396 | /* | 399 | /* |
diff --git a/arch/score/lib/string.S b/arch/score/lib/string.S index 00b7d3a2fc60..16efa3ad037f 100644 --- a/arch/score/lib/string.S +++ b/arch/score/lib/string.S | |||
@@ -175,10 +175,10 @@ ENTRY(__clear_user) | |||
175 | br r3 | 175 | br r3 |
176 | 176 | ||
177 | .section .fixup, "ax" | 177 | .section .fixup, "ax" |
178 | 99: | ||
178 | br r3 | 179 | br r3 |
179 | .previous | 180 | .previous |
180 | .section __ex_table, "a" | 181 | .section __ex_table, "a" |
181 | .align 2 | 182 | .align 2 |
182 | 99: | ||
183 | .word 0b, 99b | 183 | .word 0b, 99b |
184 | .previous | 184 | .previous |
diff --git a/arch/sparc/include/asm/cpudata_64.h b/arch/sparc/include/asm/cpudata_64.h index a6e424d185d0..a6cfdabb6054 100644 --- a/arch/sparc/include/asm/cpudata_64.h +++ b/arch/sparc/include/asm/cpudata_64.h | |||
@@ -24,7 +24,8 @@ typedef struct { | |||
24 | unsigned int icache_line_size; | 24 | unsigned int icache_line_size; |
25 | unsigned int ecache_size; | 25 | unsigned int ecache_size; |
26 | unsigned int ecache_line_size; | 26 | unsigned int ecache_line_size; |
27 | int core_id; | 27 | unsigned short sock_id; |
28 | unsigned short core_id; | ||
28 | int proc_id; | 29 | int proc_id; |
29 | } cpuinfo_sparc; | 30 | } cpuinfo_sparc; |
30 | 31 | ||
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index dc165ebdf05a..2a52c91d2c8a 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h | |||
@@ -308,12 +308,26 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot) | |||
308 | " sllx %1, 32, %1\n" | 308 | " sllx %1, 32, %1\n" |
309 | " or %0, %1, %0\n" | 309 | " or %0, %1, %0\n" |
310 | " .previous\n" | 310 | " .previous\n" |
311 | " .section .sun_m7_2insn_patch, \"ax\"\n" | ||
312 | " .word 661b\n" | ||
313 | " sethi %%uhi(%4), %1\n" | ||
314 | " sethi %%hi(%4), %0\n" | ||
315 | " .word 662b\n" | ||
316 | " or %1, %%ulo(%4), %1\n" | ||
317 | " or %0, %%lo(%4), %0\n" | ||
318 | " .word 663b\n" | ||
319 | " sllx %1, 32, %1\n" | ||
320 | " or %0, %1, %0\n" | ||
321 | " .previous\n" | ||
311 | : "=r" (mask), "=r" (tmp) | 322 | : "=r" (mask), "=r" (tmp) |
312 | : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U | | 323 | : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U | |
313 | _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | | 324 | _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | |
314 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U), | 325 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U), |
315 | "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V | | 326 | "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V | |
316 | _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | | 327 | _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | |
328 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V), | ||
329 | "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V | | ||
330 | _PAGE_CP_4V | _PAGE_E_4V | | ||
317 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V)); | 331 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V)); |
318 | 332 | ||
319 | return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask)); | 333 | return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask)); |
@@ -342,9 +356,15 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot) | |||
342 | " andn %0, %4, %0\n" | 356 | " andn %0, %4, %0\n" |
343 | " or %0, %5, %0\n" | 357 | " or %0, %5, %0\n" |
344 | " .previous\n" | 358 | " .previous\n" |
359 | " .section .sun_m7_2insn_patch, \"ax\"\n" | ||
360 | " .word 661b\n" | ||
361 | " andn %0, %6, %0\n" | ||
362 | " or %0, %5, %0\n" | ||
363 | " .previous\n" | ||
345 | : "=r" (val) | 364 | : "=r" (val) |
346 | : "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U), | 365 | : "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U), |
347 | "i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V)); | 366 | "i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V), |
367 | "i" (_PAGE_CP_4V)); | ||
348 | 368 | ||
349 | return __pgprot(val); | 369 | return __pgprot(val); |
350 | } | 370 | } |
diff --git a/arch/sparc/include/asm/topology_64.h b/arch/sparc/include/asm/topology_64.h index ed8f071132e4..d1761df5cca6 100644 --- a/arch/sparc/include/asm/topology_64.h +++ b/arch/sparc/include/asm/topology_64.h | |||
@@ -40,11 +40,12 @@ static inline int pcibus_to_node(struct pci_bus *pbus) | |||
40 | #ifdef CONFIG_SMP | 40 | #ifdef CONFIG_SMP |
41 | #define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id) | 41 | #define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id) |
42 | #define topology_core_id(cpu) (cpu_data(cpu).core_id) | 42 | #define topology_core_id(cpu) (cpu_data(cpu).core_id) |
43 | #define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) | 43 | #define topology_core_cpumask(cpu) (&cpu_core_sib_map[cpu]) |
44 | #define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu)) | 44 | #define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu)) |
45 | #endif /* CONFIG_SMP */ | 45 | #endif /* CONFIG_SMP */ |
46 | 46 | ||
47 | extern cpumask_t cpu_core_map[NR_CPUS]; | 47 | extern cpumask_t cpu_core_map[NR_CPUS]; |
48 | extern cpumask_t cpu_core_sib_map[NR_CPUS]; | ||
48 | static inline const struct cpumask *cpu_coregroup_mask(int cpu) | 49 | static inline const struct cpumask *cpu_coregroup_mask(int cpu) |
49 | { | 50 | { |
50 | return &cpu_core_map[cpu]; | 51 | return &cpu_core_map[cpu]; |
diff --git a/arch/sparc/include/asm/trap_block.h b/arch/sparc/include/asm/trap_block.h index 6fd4436d32f0..ec9c04de3664 100644 --- a/arch/sparc/include/asm/trap_block.h +++ b/arch/sparc/include/asm/trap_block.h | |||
@@ -79,6 +79,8 @@ struct sun4v_2insn_patch_entry { | |||
79 | }; | 79 | }; |
80 | extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, | 80 | extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, |
81 | __sun4v_2insn_patch_end; | 81 | __sun4v_2insn_patch_end; |
82 | extern struct sun4v_2insn_patch_entry __sun_m7_2insn_patch, | ||
83 | __sun_m7_2insn_patch_end; | ||
82 | 84 | ||
83 | 85 | ||
84 | #endif /* !(__ASSEMBLY__) */ | 86 | #endif /* !(__ASSEMBLY__) */ |
diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index 07cc49e541f4..0f679421b468 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h | |||
@@ -69,6 +69,8 @@ void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, | |||
69 | struct sun4v_1insn_patch_entry *); | 69 | struct sun4v_1insn_patch_entry *); |
70 | void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *, | 70 | void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *, |
71 | struct sun4v_2insn_patch_entry *); | 71 | struct sun4v_2insn_patch_entry *); |
72 | void sun_m7_patch_2insn_range(struct sun4v_2insn_patch_entry *, | ||
73 | struct sun4v_2insn_patch_entry *); | ||
72 | extern unsigned int dcache_parity_tl1_occurred; | 74 | extern unsigned int dcache_parity_tl1_occurred; |
73 | extern unsigned int icache_parity_tl1_occurred; | 75 | extern unsigned int icache_parity_tl1_occurred; |
74 | 76 | ||
diff --git a/arch/sparc/kernel/leon_pci_grpci2.c b/arch/sparc/kernel/leon_pci_grpci2.c index 94e392bdee7d..814fb1729b12 100644 --- a/arch/sparc/kernel/leon_pci_grpci2.c +++ b/arch/sparc/kernel/leon_pci_grpci2.c | |||
@@ -723,7 +723,6 @@ static int grpci2_of_probe(struct platform_device *ofdev) | |||
723 | err = -ENOMEM; | 723 | err = -ENOMEM; |
724 | goto err1; | 724 | goto err1; |
725 | } | 725 | } |
726 | memset(grpci2priv, 0, sizeof(*grpci2priv)); | ||
727 | priv->regs = regs; | 726 | priv->regs = regs; |
728 | priv->irq = ofdev->archdata.irqs[0]; /* BASE IRQ */ | 727 | priv->irq = ofdev->archdata.irqs[0]; /* BASE IRQ */ |
729 | priv->irq_mode = (capability & STS_IRQMODE) >> STS_IRQMODE_BIT; | 728 | priv->irq_mode = (capability & STS_IRQMODE) >> STS_IRQMODE_BIT; |
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index 26c80e18d7b1..6f80936e0eea 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c | |||
@@ -614,45 +614,68 @@ static void fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_handle *hp, u64 mp) | |||
614 | } | 614 | } |
615 | } | 615 | } |
616 | 616 | ||
617 | static void mark_core_ids(struct mdesc_handle *hp, u64 mp, int core_id) | 617 | static void find_back_node_value(struct mdesc_handle *hp, u64 node, |
618 | char *srch_val, | ||
619 | void (*func)(struct mdesc_handle *, u64, int), | ||
620 | u64 val, int depth) | ||
618 | { | 621 | { |
619 | u64 a; | 622 | u64 arc; |
620 | |||
621 | mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) { | ||
622 | u64 t = mdesc_arc_target(hp, a); | ||
623 | const char *name; | ||
624 | const u64 *id; | ||
625 | 623 | ||
626 | name = mdesc_node_name(hp, t); | 624 | /* Since we have an estimate of recursion depth, do a sanity check. */ |
627 | if (!strcmp(name, "cpu")) { | 625 | if (depth == 0) |
628 | id = mdesc_get_property(hp, t, "id", NULL); | 626 | return; |
629 | if (*id < NR_CPUS) | ||
630 | cpu_data(*id).core_id = core_id; | ||
631 | } else { | ||
632 | u64 j; | ||
633 | 627 | ||
634 | mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_BACK) { | 628 | mdesc_for_each_arc(arc, hp, node, MDESC_ARC_TYPE_BACK) { |
635 | u64 n = mdesc_arc_target(hp, j); | 629 | u64 n = mdesc_arc_target(hp, arc); |
636 | const char *n_name; | 630 | const char *name = mdesc_node_name(hp, n); |
637 | 631 | ||
638 | n_name = mdesc_node_name(hp, n); | 632 | if (!strcmp(srch_val, name)) |
639 | if (strcmp(n_name, "cpu")) | 633 | (*func)(hp, n, val); |
640 | continue; | ||
641 | 634 | ||
642 | id = mdesc_get_property(hp, n, "id", NULL); | 635 | find_back_node_value(hp, n, srch_val, func, val, depth-1); |
643 | if (*id < NR_CPUS) | ||
644 | cpu_data(*id).core_id = core_id; | ||
645 | } | ||
646 | } | ||
647 | } | 636 | } |
648 | } | 637 | } |
649 | 638 | ||
639 | static void __mark_core_id(struct mdesc_handle *hp, u64 node, | ||
640 | int core_id) | ||
641 | { | ||
642 | const u64 *id = mdesc_get_property(hp, node, "id", NULL); | ||
643 | |||
644 | if (*id < num_possible_cpus()) | ||
645 | cpu_data(*id).core_id = core_id; | ||
646 | } | ||
647 | |||
648 | static void __mark_sock_id(struct mdesc_handle *hp, u64 node, | ||
649 | int sock_id) | ||
650 | { | ||
651 | const u64 *id = mdesc_get_property(hp, node, "id", NULL); | ||
652 | |||
653 | if (*id < num_possible_cpus()) | ||
654 | cpu_data(*id).sock_id = sock_id; | ||
655 | } | ||
656 | |||
657 | static void mark_core_ids(struct mdesc_handle *hp, u64 mp, | ||
658 | int core_id) | ||
659 | { | ||
660 | find_back_node_value(hp, mp, "cpu", __mark_core_id, core_id, 10); | ||
661 | } | ||
662 | |||
663 | static void mark_sock_ids(struct mdesc_handle *hp, u64 mp, | ||
664 | int sock_id) | ||
665 | { | ||
666 | find_back_node_value(hp, mp, "cpu", __mark_sock_id, sock_id, 10); | ||
667 | } | ||
668 | |||
650 | static void set_core_ids(struct mdesc_handle *hp) | 669 | static void set_core_ids(struct mdesc_handle *hp) |
651 | { | 670 | { |
652 | int idx; | 671 | int idx; |
653 | u64 mp; | 672 | u64 mp; |
654 | 673 | ||
655 | idx = 1; | 674 | idx = 1; |
675 | |||
676 | /* Identify unique cores by looking for cpus backpointed to by | ||
677 | * level 1 instruction caches. | ||
678 | */ | ||
656 | mdesc_for_each_node_by_name(hp, mp, "cache") { | 679 | mdesc_for_each_node_by_name(hp, mp, "cache") { |
657 | const u64 *level; | 680 | const u64 *level; |
658 | const char *type; | 681 | const char *type; |
@@ -667,11 +690,72 @@ static void set_core_ids(struct mdesc_handle *hp) | |||
667 | continue; | 690 | continue; |
668 | 691 | ||
669 | mark_core_ids(hp, mp, idx); | 692 | mark_core_ids(hp, mp, idx); |
693 | idx++; | ||
694 | } | ||
695 | } | ||
696 | |||
697 | static int set_sock_ids_by_cache(struct mdesc_handle *hp, int level) | ||
698 | { | ||
699 | u64 mp; | ||
700 | int idx = 1; | ||
701 | int fnd = 0; | ||
702 | |||
703 | /* Identify unique sockets by looking for cpus backpointed to by | ||
704 | * shared level n caches. | ||
705 | */ | ||
706 | mdesc_for_each_node_by_name(hp, mp, "cache") { | ||
707 | const u64 *cur_lvl; | ||
708 | |||
709 | cur_lvl = mdesc_get_property(hp, mp, "level", NULL); | ||
710 | if (*cur_lvl != level) | ||
711 | continue; | ||
712 | |||
713 | mark_sock_ids(hp, mp, idx); | ||
714 | idx++; | ||
715 | fnd = 1; | ||
716 | } | ||
717 | return fnd; | ||
718 | } | ||
719 | |||
720 | static void set_sock_ids_by_socket(struct mdesc_handle *hp, u64 mp) | ||
721 | { | ||
722 | int idx = 1; | ||
670 | 723 | ||
724 | mdesc_for_each_node_by_name(hp, mp, "socket") { | ||
725 | u64 a; | ||
726 | |||
727 | mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) { | ||
728 | u64 t = mdesc_arc_target(hp, a); | ||
729 | const char *name; | ||
730 | const u64 *id; | ||
731 | |||
732 | name = mdesc_node_name(hp, t); | ||
733 | if (strcmp(name, "cpu")) | ||
734 | continue; | ||
735 | |||
736 | id = mdesc_get_property(hp, t, "id", NULL); | ||
737 | if (*id < num_possible_cpus()) | ||
738 | cpu_data(*id).sock_id = idx; | ||
739 | } | ||
671 | idx++; | 740 | idx++; |
672 | } | 741 | } |
673 | } | 742 | } |
674 | 743 | ||
744 | static void set_sock_ids(struct mdesc_handle *hp) | ||
745 | { | ||
746 | u64 mp; | ||
747 | |||
748 | /* If machine description exposes sockets data use it. | ||
749 | * Otherwise fallback to use shared L3 or L2 caches. | ||
750 | */ | ||
751 | mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "sockets"); | ||
752 | if (mp != MDESC_NODE_NULL) | ||
753 | return set_sock_ids_by_socket(hp, mp); | ||
754 | |||
755 | if (!set_sock_ids_by_cache(hp, 3)) | ||
756 | set_sock_ids_by_cache(hp, 2); | ||
757 | } | ||
758 | |||
675 | static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id) | 759 | static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id) |
676 | { | 760 | { |
677 | u64 a; | 761 | u64 a; |
@@ -707,7 +791,6 @@ static void __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name) | |||
707 | continue; | 791 | continue; |
708 | 792 | ||
709 | mark_proc_ids(hp, mp, idx); | 793 | mark_proc_ids(hp, mp, idx); |
710 | |||
711 | idx++; | 794 | idx++; |
712 | } | 795 | } |
713 | } | 796 | } |
@@ -900,6 +983,7 @@ void mdesc_fill_in_cpu_data(cpumask_t *mask) | |||
900 | 983 | ||
901 | set_core_ids(hp); | 984 | set_core_ids(hp); |
902 | set_proc_ids(hp); | 985 | set_proc_ids(hp); |
986 | set_sock_ids(hp); | ||
903 | 987 | ||
904 | mdesc_release(hp); | 988 | mdesc_release(hp); |
905 | 989 | ||
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 6f7251fd2eab..c928bc64b4ba 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c | |||
@@ -1002,6 +1002,38 @@ static int __init pcibios_init(void) | |||
1002 | subsys_initcall(pcibios_init); | 1002 | subsys_initcall(pcibios_init); |
1003 | 1003 | ||
1004 | #ifdef CONFIG_SYSFS | 1004 | #ifdef CONFIG_SYSFS |
1005 | |||
1006 | #define SLOT_NAME_SIZE 11 /* Max decimal digits + null in u32 */ | ||
1007 | |||
1008 | static void pcie_bus_slot_names(struct pci_bus *pbus) | ||
1009 | { | ||
1010 | struct pci_dev *pdev; | ||
1011 | struct pci_bus *bus; | ||
1012 | |||
1013 | list_for_each_entry(pdev, &pbus->devices, bus_list) { | ||
1014 | char name[SLOT_NAME_SIZE]; | ||
1015 | struct pci_slot *pci_slot; | ||
1016 | const u32 *slot_num; | ||
1017 | int len; | ||
1018 | |||
1019 | slot_num = of_get_property(pdev->dev.of_node, | ||
1020 | "physical-slot#", &len); | ||
1021 | |||
1022 | if (slot_num == NULL || len != 4) | ||
1023 | continue; | ||
1024 | |||
1025 | snprintf(name, sizeof(name), "%u", slot_num[0]); | ||
1026 | pci_slot = pci_create_slot(pbus, slot_num[0], name, NULL); | ||
1027 | |||
1028 | if (IS_ERR(pci_slot)) | ||
1029 | pr_err("PCI: pci_create_slot returned %ld.\n", | ||
1030 | PTR_ERR(pci_slot)); | ||
1031 | } | ||
1032 | |||
1033 | list_for_each_entry(bus, &pbus->children, node) | ||
1034 | pcie_bus_slot_names(bus); | ||
1035 | } | ||
1036 | |||
1005 | static void pci_bus_slot_names(struct device_node *node, struct pci_bus *bus) | 1037 | static void pci_bus_slot_names(struct device_node *node, struct pci_bus *bus) |
1006 | { | 1038 | { |
1007 | const struct pci_slot_names { | 1039 | const struct pci_slot_names { |
@@ -1053,18 +1085,29 @@ static int __init of_pci_slot_init(void) | |||
1053 | 1085 | ||
1054 | while ((pbus = pci_find_next_bus(pbus)) != NULL) { | 1086 | while ((pbus = pci_find_next_bus(pbus)) != NULL) { |
1055 | struct device_node *node; | 1087 | struct device_node *node; |
1088 | struct pci_dev *pdev; | ||
1089 | |||
1090 | pdev = list_first_entry(&pbus->devices, struct pci_dev, | ||
1091 | bus_list); | ||
1056 | 1092 | ||
1057 | if (pbus->self) { | 1093 | if (pdev && pci_is_pcie(pdev)) { |
1058 | /* PCI->PCI bridge */ | 1094 | pcie_bus_slot_names(pbus); |
1059 | node = pbus->self->dev.of_node; | ||
1060 | } else { | 1095 | } else { |
1061 | struct pci_pbm_info *pbm = pbus->sysdata; | ||
1062 | 1096 | ||
1063 | /* Host PCI controller */ | 1097 | if (pbus->self) { |
1064 | node = pbm->op->dev.of_node; | 1098 | |
1065 | } | 1099 | /* PCI->PCI bridge */ |
1100 | node = pbus->self->dev.of_node; | ||
1101 | |||
1102 | } else { | ||
1103 | struct pci_pbm_info *pbm = pbus->sysdata; | ||
1066 | 1104 | ||
1067 | pci_bus_slot_names(node, pbus); | 1105 | /* Host PCI controller */ |
1106 | node = pbm->op->dev.of_node; | ||
1107 | } | ||
1108 | |||
1109 | pci_bus_slot_names(node, pbus); | ||
1110 | } | ||
1068 | } | 1111 | } |
1069 | 1112 | ||
1070 | return 0; | 1113 | return 0; |
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index c38d19fc27ba..f7b261749383 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c | |||
@@ -255,6 +255,24 @@ void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *start, | |||
255 | } | 255 | } |
256 | } | 256 | } |
257 | 257 | ||
258 | void sun_m7_patch_2insn_range(struct sun4v_2insn_patch_entry *start, | ||
259 | struct sun4v_2insn_patch_entry *end) | ||
260 | { | ||
261 | while (start < end) { | ||
262 | unsigned long addr = start->addr; | ||
263 | |||
264 | *(unsigned int *) (addr + 0) = start->insns[0]; | ||
265 | wmb(); | ||
266 | __asm__ __volatile__("flush %0" : : "r" (addr + 0)); | ||
267 | |||
268 | *(unsigned int *) (addr + 4) = start->insns[1]; | ||
269 | wmb(); | ||
270 | __asm__ __volatile__("flush %0" : : "r" (addr + 4)); | ||
271 | |||
272 | start++; | ||
273 | } | ||
274 | } | ||
275 | |||
258 | static void __init sun4v_patch(void) | 276 | static void __init sun4v_patch(void) |
259 | { | 277 | { |
260 | extern void sun4v_hvapi_init(void); | 278 | extern void sun4v_hvapi_init(void); |
@@ -267,6 +285,9 @@ static void __init sun4v_patch(void) | |||
267 | 285 | ||
268 | sun4v_patch_2insn_range(&__sun4v_2insn_patch, | 286 | sun4v_patch_2insn_range(&__sun4v_2insn_patch, |
269 | &__sun4v_2insn_patch_end); | 287 | &__sun4v_2insn_patch_end); |
288 | if (sun4v_chip_type == SUN4V_CHIP_SPARC_M7) | ||
289 | sun_m7_patch_2insn_range(&__sun_m7_2insn_patch, | ||
290 | &__sun_m7_2insn_patch_end); | ||
270 | 291 | ||
271 | sun4v_hvapi_init(); | 292 | sun4v_hvapi_init(); |
272 | } | 293 | } |
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index 61139d9924ca..19cd08d18672 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c | |||
@@ -60,8 +60,12 @@ DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE; | |||
60 | cpumask_t cpu_core_map[NR_CPUS] __read_mostly = | 60 | cpumask_t cpu_core_map[NR_CPUS] __read_mostly = |
61 | { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; | 61 | { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; |
62 | 62 | ||
63 | cpumask_t cpu_core_sib_map[NR_CPUS] __read_mostly = { | ||
64 | [0 ... NR_CPUS-1] = CPU_MASK_NONE }; | ||
65 | |||
63 | EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); | 66 | EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); |
64 | EXPORT_SYMBOL(cpu_core_map); | 67 | EXPORT_SYMBOL(cpu_core_map); |
68 | EXPORT_SYMBOL(cpu_core_sib_map); | ||
65 | 69 | ||
66 | static cpumask_t smp_commenced_mask; | 70 | static cpumask_t smp_commenced_mask; |
67 | 71 | ||
@@ -1243,6 +1247,15 @@ void smp_fill_in_sib_core_maps(void) | |||
1243 | } | 1247 | } |
1244 | } | 1248 | } |
1245 | 1249 | ||
1250 | for_each_present_cpu(i) { | ||
1251 | unsigned int j; | ||
1252 | |||
1253 | for_each_present_cpu(j) { | ||
1254 | if (cpu_data(i).sock_id == cpu_data(j).sock_id) | ||
1255 | cpumask_set_cpu(j, &cpu_core_sib_map[i]); | ||
1256 | } | ||
1257 | } | ||
1258 | |||
1246 | for_each_present_cpu(i) { | 1259 | for_each_present_cpu(i) { |
1247 | unsigned int j; | 1260 | unsigned int j; |
1248 | 1261 | ||
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 09243057cb0b..f1a2f688b28a 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S | |||
@@ -138,6 +138,11 @@ SECTIONS | |||
138 | *(.pause_3insn_patch) | 138 | *(.pause_3insn_patch) |
139 | __pause_3insn_patch_end = .; | 139 | __pause_3insn_patch_end = .; |
140 | } | 140 | } |
141 | .sun_m7_2insn_patch : { | ||
142 | __sun_m7_2insn_patch = .; | ||
143 | *(.sun_m7_2insn_patch) | ||
144 | __sun_m7_2insn_patch_end = .; | ||
145 | } | ||
141 | PERCPU_SECTION(SMP_CACHE_BYTES) | 146 | PERCPU_SECTION(SMP_CACHE_BYTES) |
142 | 147 | ||
143 | . = ALIGN(PAGE_SIZE); | 148 | . = ALIGN(PAGE_SIZE); |
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 4ca0d6ba5ec8..559cb744112c 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include "init_64.h" | 54 | #include "init_64.h" |
55 | 55 | ||
56 | unsigned long kern_linear_pte_xor[4] __read_mostly; | 56 | unsigned long kern_linear_pte_xor[4] __read_mostly; |
57 | static unsigned long page_cache4v_flag; | ||
57 | 58 | ||
58 | /* A bitmap, two bits for every 256MB of physical memory. These two | 59 | /* A bitmap, two bits for every 256MB of physical memory. These two |
59 | * bits determine what page size we use for kernel linear | 60 | * bits determine what page size we use for kernel linear |
@@ -1909,11 +1910,24 @@ static void __init sun4u_linear_pte_xor_finalize(void) | |||
1909 | 1910 | ||
1910 | static void __init sun4v_linear_pte_xor_finalize(void) | 1911 | static void __init sun4v_linear_pte_xor_finalize(void) |
1911 | { | 1912 | { |
1913 | unsigned long pagecv_flag; | ||
1914 | |||
1915 | /* Bit 9 of TTE is no longer CV bit on M7 processor and it instead | ||
1916 | * enables MCD error. Do not set bit 9 on M7 processor. | ||
1917 | */ | ||
1918 | switch (sun4v_chip_type) { | ||
1919 | case SUN4V_CHIP_SPARC_M7: | ||
1920 | pagecv_flag = 0x00; | ||
1921 | break; | ||
1922 | default: | ||
1923 | pagecv_flag = _PAGE_CV_4V; | ||
1924 | break; | ||
1925 | } | ||
1912 | #ifndef CONFIG_DEBUG_PAGEALLOC | 1926 | #ifndef CONFIG_DEBUG_PAGEALLOC |
1913 | if (cpu_pgsz_mask & HV_PGSZ_MASK_256MB) { | 1927 | if (cpu_pgsz_mask & HV_PGSZ_MASK_256MB) { |
1914 | kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^ | 1928 | kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^ |
1915 | PAGE_OFFSET; | 1929 | PAGE_OFFSET; |
1916 | kern_linear_pte_xor[1] |= (_PAGE_CP_4V | _PAGE_CV_4V | | 1930 | kern_linear_pte_xor[1] |= (_PAGE_CP_4V | pagecv_flag | |
1917 | _PAGE_P_4V | _PAGE_W_4V); | 1931 | _PAGE_P_4V | _PAGE_W_4V); |
1918 | } else { | 1932 | } else { |
1919 | kern_linear_pte_xor[1] = kern_linear_pte_xor[0]; | 1933 | kern_linear_pte_xor[1] = kern_linear_pte_xor[0]; |
@@ -1922,7 +1936,7 @@ static void __init sun4v_linear_pte_xor_finalize(void) | |||
1922 | if (cpu_pgsz_mask & HV_PGSZ_MASK_2GB) { | 1936 | if (cpu_pgsz_mask & HV_PGSZ_MASK_2GB) { |
1923 | kern_linear_pte_xor[2] = (_PAGE_VALID | _PAGE_SZ2GB_4V) ^ | 1937 | kern_linear_pte_xor[2] = (_PAGE_VALID | _PAGE_SZ2GB_4V) ^ |
1924 | PAGE_OFFSET; | 1938 | PAGE_OFFSET; |
1925 | kern_linear_pte_xor[2] |= (_PAGE_CP_4V | _PAGE_CV_4V | | 1939 | kern_linear_pte_xor[2] |= (_PAGE_CP_4V | pagecv_flag | |
1926 | _PAGE_P_4V | _PAGE_W_4V); | 1940 | _PAGE_P_4V | _PAGE_W_4V); |
1927 | } else { | 1941 | } else { |
1928 | kern_linear_pte_xor[2] = kern_linear_pte_xor[1]; | 1942 | kern_linear_pte_xor[2] = kern_linear_pte_xor[1]; |
@@ -1931,7 +1945,7 @@ static void __init sun4v_linear_pte_xor_finalize(void) | |||
1931 | if (cpu_pgsz_mask & HV_PGSZ_MASK_16GB) { | 1945 | if (cpu_pgsz_mask & HV_PGSZ_MASK_16GB) { |
1932 | kern_linear_pte_xor[3] = (_PAGE_VALID | _PAGE_SZ16GB_4V) ^ | 1946 | kern_linear_pte_xor[3] = (_PAGE_VALID | _PAGE_SZ16GB_4V) ^ |
1933 | PAGE_OFFSET; | 1947 | PAGE_OFFSET; |
1934 | kern_linear_pte_xor[3] |= (_PAGE_CP_4V | _PAGE_CV_4V | | 1948 | kern_linear_pte_xor[3] |= (_PAGE_CP_4V | pagecv_flag | |
1935 | _PAGE_P_4V | _PAGE_W_4V); | 1949 | _PAGE_P_4V | _PAGE_W_4V); |
1936 | } else { | 1950 | } else { |
1937 | kern_linear_pte_xor[3] = kern_linear_pte_xor[2]; | 1951 | kern_linear_pte_xor[3] = kern_linear_pte_xor[2]; |
@@ -1958,6 +1972,13 @@ static phys_addr_t __init available_memory(void) | |||
1958 | return available; | 1972 | return available; |
1959 | } | 1973 | } |
1960 | 1974 | ||
1975 | #define _PAGE_CACHE_4U (_PAGE_CP_4U | _PAGE_CV_4U) | ||
1976 | #define _PAGE_CACHE_4V (_PAGE_CP_4V | _PAGE_CV_4V) | ||
1977 | #define __DIRTY_BITS_4U (_PAGE_MODIFIED_4U | _PAGE_WRITE_4U | _PAGE_W_4U) | ||
1978 | #define __DIRTY_BITS_4V (_PAGE_MODIFIED_4V | _PAGE_WRITE_4V | _PAGE_W_4V) | ||
1979 | #define __ACCESS_BITS_4U (_PAGE_ACCESSED_4U | _PAGE_READ_4U | _PAGE_R) | ||
1980 | #define __ACCESS_BITS_4V (_PAGE_ACCESSED_4V | _PAGE_READ_4V | _PAGE_R) | ||
1981 | |||
1961 | /* We need to exclude reserved regions. This exclusion will include | 1982 | /* We need to exclude reserved regions. This exclusion will include |
1962 | * vmlinux and initrd. To be more precise the initrd size could be used to | 1983 | * vmlinux and initrd. To be more precise the initrd size could be used to |
1963 | * compute a new lower limit because it is freed later during initialization. | 1984 | * compute a new lower limit because it is freed later during initialization. |
@@ -2034,6 +2055,25 @@ void __init paging_init(void) | |||
2034 | memset(swapper_4m_tsb, 0x40, sizeof(swapper_4m_tsb)); | 2055 | memset(swapper_4m_tsb, 0x40, sizeof(swapper_4m_tsb)); |
2035 | #endif | 2056 | #endif |
2036 | 2057 | ||
2058 | /* TTE.cv bit on sparc v9 occupies the same position as TTE.mcde | ||
2059 | * bit on M7 processor. This is a conflicting usage of the same | ||
2060 | * bit. Enabling TTE.cv on M7 would turn on Memory Corruption | ||
2061 | * Detection error on all pages and this will lead to problems | ||
2062 | * later. Kernel does not run with MCD enabled and hence rest | ||
2063 | * of the required steps to fully configure memory corruption | ||
2064 | * detection are not taken. We need to ensure TTE.mcde is not | ||
2065 | * set on M7 processor. Compute the value of cacheability | ||
2066 | * flag for use later taking this into consideration. | ||
2067 | */ | ||
2068 | switch (sun4v_chip_type) { | ||
2069 | case SUN4V_CHIP_SPARC_M7: | ||
2070 | page_cache4v_flag = _PAGE_CP_4V; | ||
2071 | break; | ||
2072 | default: | ||
2073 | page_cache4v_flag = _PAGE_CACHE_4V; | ||
2074 | break; | ||
2075 | } | ||
2076 | |||
2037 | if (tlb_type == hypervisor) | 2077 | if (tlb_type == hypervisor) |
2038 | sun4v_pgprot_init(); | 2078 | sun4v_pgprot_init(); |
2039 | else | 2079 | else |
@@ -2274,13 +2314,6 @@ void free_initrd_mem(unsigned long start, unsigned long end) | |||
2274 | } | 2314 | } |
2275 | #endif | 2315 | #endif |
2276 | 2316 | ||
2277 | #define _PAGE_CACHE_4U (_PAGE_CP_4U | _PAGE_CV_4U) | ||
2278 | #define _PAGE_CACHE_4V (_PAGE_CP_4V | _PAGE_CV_4V) | ||
2279 | #define __DIRTY_BITS_4U (_PAGE_MODIFIED_4U | _PAGE_WRITE_4U | _PAGE_W_4U) | ||
2280 | #define __DIRTY_BITS_4V (_PAGE_MODIFIED_4V | _PAGE_WRITE_4V | _PAGE_W_4V) | ||
2281 | #define __ACCESS_BITS_4U (_PAGE_ACCESSED_4U | _PAGE_READ_4U | _PAGE_R) | ||
2282 | #define __ACCESS_BITS_4V (_PAGE_ACCESSED_4V | _PAGE_READ_4V | _PAGE_R) | ||
2283 | |||
2284 | pgprot_t PAGE_KERNEL __read_mostly; | 2317 | pgprot_t PAGE_KERNEL __read_mostly; |
2285 | EXPORT_SYMBOL(PAGE_KERNEL); | 2318 | EXPORT_SYMBOL(PAGE_KERNEL); |
2286 | 2319 | ||
@@ -2312,8 +2345,7 @@ int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend, | |||
2312 | _PAGE_P_4U | _PAGE_W_4U); | 2345 | _PAGE_P_4U | _PAGE_W_4U); |
2313 | if (tlb_type == hypervisor) | 2346 | if (tlb_type == hypervisor) |
2314 | pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4V | | 2347 | pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4V | |
2315 | _PAGE_CP_4V | _PAGE_CV_4V | | 2348 | page_cache4v_flag | _PAGE_P_4V | _PAGE_W_4V); |
2316 | _PAGE_P_4V | _PAGE_W_4V); | ||
2317 | 2349 | ||
2318 | pte_base |= _PAGE_PMD_HUGE; | 2350 | pte_base |= _PAGE_PMD_HUGE; |
2319 | 2351 | ||
@@ -2450,14 +2482,14 @@ static void __init sun4v_pgprot_init(void) | |||
2450 | int i; | 2482 | int i; |
2451 | 2483 | ||
2452 | PAGE_KERNEL = __pgprot (_PAGE_PRESENT_4V | _PAGE_VALID | | 2484 | PAGE_KERNEL = __pgprot (_PAGE_PRESENT_4V | _PAGE_VALID | |
2453 | _PAGE_CACHE_4V | _PAGE_P_4V | | 2485 | page_cache4v_flag | _PAGE_P_4V | |
2454 | __ACCESS_BITS_4V | __DIRTY_BITS_4V | | 2486 | __ACCESS_BITS_4V | __DIRTY_BITS_4V | |
2455 | _PAGE_EXEC_4V); | 2487 | _PAGE_EXEC_4V); |
2456 | PAGE_KERNEL_LOCKED = PAGE_KERNEL; | 2488 | PAGE_KERNEL_LOCKED = PAGE_KERNEL; |
2457 | 2489 | ||
2458 | _PAGE_IE = _PAGE_IE_4V; | 2490 | _PAGE_IE = _PAGE_IE_4V; |
2459 | _PAGE_E = _PAGE_E_4V; | 2491 | _PAGE_E = _PAGE_E_4V; |
2460 | _PAGE_CACHE = _PAGE_CACHE_4V; | 2492 | _PAGE_CACHE = page_cache4v_flag; |
2461 | 2493 | ||
2462 | #ifdef CONFIG_DEBUG_PAGEALLOC | 2494 | #ifdef CONFIG_DEBUG_PAGEALLOC |
2463 | kern_linear_pte_xor[0] = _PAGE_VALID ^ PAGE_OFFSET; | 2495 | kern_linear_pte_xor[0] = _PAGE_VALID ^ PAGE_OFFSET; |
@@ -2465,8 +2497,8 @@ static void __init sun4v_pgprot_init(void) | |||
2465 | kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4V) ^ | 2497 | kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4V) ^ |
2466 | PAGE_OFFSET; | 2498 | PAGE_OFFSET; |
2467 | #endif | 2499 | #endif |
2468 | kern_linear_pte_xor[0] |= (_PAGE_CP_4V | _PAGE_CV_4V | | 2500 | kern_linear_pte_xor[0] |= (page_cache4v_flag | _PAGE_P_4V | |
2469 | _PAGE_P_4V | _PAGE_W_4V); | 2501 | _PAGE_W_4V); |
2470 | 2502 | ||
2471 | for (i = 1; i < 4; i++) | 2503 | for (i = 1; i < 4; i++) |
2472 | kern_linear_pte_xor[i] = kern_linear_pte_xor[0]; | 2504 | kern_linear_pte_xor[i] = kern_linear_pte_xor[0]; |
@@ -2479,12 +2511,12 @@ static void __init sun4v_pgprot_init(void) | |||
2479 | _PAGE_SZ4MB_4V | _PAGE_SZ512K_4V | | 2511 | _PAGE_SZ4MB_4V | _PAGE_SZ512K_4V | |
2480 | _PAGE_SZ64K_4V | _PAGE_SZ8K_4V); | 2512 | _PAGE_SZ64K_4V | _PAGE_SZ8K_4V); |
2481 | 2513 | ||
2482 | page_none = _PAGE_PRESENT_4V | _PAGE_ACCESSED_4V | _PAGE_CACHE_4V; | 2514 | page_none = _PAGE_PRESENT_4V | _PAGE_ACCESSED_4V | page_cache4v_flag; |
2483 | page_shared = (_PAGE_VALID | _PAGE_PRESENT_4V | _PAGE_CACHE_4V | | 2515 | page_shared = (_PAGE_VALID | _PAGE_PRESENT_4V | page_cache4v_flag | |
2484 | __ACCESS_BITS_4V | _PAGE_WRITE_4V | _PAGE_EXEC_4V); | 2516 | __ACCESS_BITS_4V | _PAGE_WRITE_4V | _PAGE_EXEC_4V); |
2485 | page_copy = (_PAGE_VALID | _PAGE_PRESENT_4V | _PAGE_CACHE_4V | | 2517 | page_copy = (_PAGE_VALID | _PAGE_PRESENT_4V | page_cache4v_flag | |
2486 | __ACCESS_BITS_4V | _PAGE_EXEC_4V); | 2518 | __ACCESS_BITS_4V | _PAGE_EXEC_4V); |
2487 | page_readonly = (_PAGE_VALID | _PAGE_PRESENT_4V | _PAGE_CACHE_4V | | 2519 | page_readonly = (_PAGE_VALID | _PAGE_PRESENT_4V | page_cache4v_flag | |
2488 | __ACCESS_BITS_4V | _PAGE_EXEC_4V); | 2520 | __ACCESS_BITS_4V | _PAGE_EXEC_4V); |
2489 | 2521 | ||
2490 | page_exec_bit = _PAGE_EXEC_4V; | 2522 | page_exec_bit = _PAGE_EXEC_4V; |
@@ -2542,7 +2574,7 @@ static unsigned long kern_large_tte(unsigned long paddr) | |||
2542 | _PAGE_EXEC_4U | _PAGE_L_4U | _PAGE_W_4U); | 2574 | _PAGE_EXEC_4U | _PAGE_L_4U | _PAGE_W_4U); |
2543 | if (tlb_type == hypervisor) | 2575 | if (tlb_type == hypervisor) |
2544 | val = (_PAGE_VALID | _PAGE_SZ4MB_4V | | 2576 | val = (_PAGE_VALID | _PAGE_SZ4MB_4V | |
2545 | _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_P_4V | | 2577 | page_cache4v_flag | _PAGE_P_4V | |
2546 | _PAGE_EXEC_4V | _PAGE_W_4V); | 2578 | _PAGE_EXEC_4V | _PAGE_W_4V); |
2547 | 2579 | ||
2548 | return val | paddr; | 2580 | return val | paddr; |
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index 89dd0d78013a..805d25ca5f1d 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h | |||
@@ -2,15 +2,14 @@ | |||
2 | #define BOOT_COMPRESSED_MISC_H | 2 | #define BOOT_COMPRESSED_MISC_H |
3 | 3 | ||
4 | /* | 4 | /* |
5 | * we have to be careful, because no indirections are allowed here, and | 5 | * Special hack: we have to be careful, because no indirections are allowed here, |
6 | * paravirt_ops is a kind of one. As it will only run in baremetal anyway, | 6 | * and paravirt_ops is a kind of one. As it will only run in baremetal anyway, |
7 | * we just keep it from happening | 7 | * we just keep it from happening. (This list needs to be extended when new |
8 | * paravirt and debugging variants are added.) | ||
8 | */ | 9 | */ |
9 | #undef CONFIG_PARAVIRT | 10 | #undef CONFIG_PARAVIRT |
11 | #undef CONFIG_PARAVIRT_SPINLOCKS | ||
10 | #undef CONFIG_KASAN | 12 | #undef CONFIG_KASAN |
11 | #ifdef CONFIG_X86_32 | ||
12 | #define _ASM_X86_DESC_H 1 | ||
13 | #endif | ||
14 | 13 | ||
15 | #include <linux/linkage.h> | 14 | #include <linux/linkage.h> |
16 | #include <linux/screen_info.h> | 15 | #include <linux/screen_info.h> |
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 19507ffa5d28..5fabf1362942 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h | |||
@@ -107,7 +107,7 @@ static inline unsigned long regs_return_value(struct pt_regs *regs) | |||
107 | static inline int user_mode(struct pt_regs *regs) | 107 | static inline int user_mode(struct pt_regs *regs) |
108 | { | 108 | { |
109 | #ifdef CONFIG_X86_32 | 109 | #ifdef CONFIG_X86_32 |
110 | return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL; | 110 | return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >= USER_RPL; |
111 | #else | 111 | #else |
112 | return !!(regs->cs & 3); | 112 | return !!(regs->cs & 3); |
113 | #endif | 113 | #endif |
diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index 5a9856eb12ba..7d5a1929d76b 100644 --- a/arch/x86/include/asm/segment.h +++ b/arch/x86/include/asm/segment.h | |||
@@ -231,11 +231,21 @@ | |||
231 | #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES* 8) | 231 | #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES* 8) |
232 | 232 | ||
233 | #ifdef __KERNEL__ | 233 | #ifdef __KERNEL__ |
234 | |||
235 | /* | ||
236 | * early_idt_handler_array is an array of entry points referenced in the | ||
237 | * early IDT. For simplicity, it's a real array with one entry point | ||
238 | * every nine bytes. That leaves room for an optional 'push $0' if the | ||
239 | * vector has no error code (two bytes), a 'push $vector_number' (two | ||
240 | * bytes), and a jump to the common entry code (up to five bytes). | ||
241 | */ | ||
242 | #define EARLY_IDT_HANDLER_SIZE 9 | ||
243 | |||
234 | #ifndef __ASSEMBLY__ | 244 | #ifndef __ASSEMBLY__ |
235 | 245 | ||
236 | extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5]; | 246 | extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE]; |
237 | #ifdef CONFIG_TRACING | 247 | #ifdef CONFIG_TRACING |
238 | # define trace_early_idt_handlers early_idt_handlers | 248 | # define trace_early_idt_handler_array early_idt_handler_array |
239 | #endif | 249 | #endif |
240 | 250 | ||
241 | /* | 251 | /* |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 87848ebe2bb7..4f7001f28936 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -190,6 +190,7 @@ static bool check_hw_exists(void) | |||
190 | u64 val, val_fail, val_new= ~0; | 190 | u64 val, val_fail, val_new= ~0; |
191 | int i, reg, reg_fail, ret = 0; | 191 | int i, reg, reg_fail, ret = 0; |
192 | int bios_fail = 0; | 192 | int bios_fail = 0; |
193 | int reg_safe = -1; | ||
193 | 194 | ||
194 | /* | 195 | /* |
195 | * Check to see if the BIOS enabled any of the counters, if so | 196 | * Check to see if the BIOS enabled any of the counters, if so |
@@ -204,6 +205,8 @@ static bool check_hw_exists(void) | |||
204 | bios_fail = 1; | 205 | bios_fail = 1; |
205 | val_fail = val; | 206 | val_fail = val; |
206 | reg_fail = reg; | 207 | reg_fail = reg; |
208 | } else { | ||
209 | reg_safe = i; | ||
207 | } | 210 | } |
208 | } | 211 | } |
209 | 212 | ||
@@ -222,11 +225,22 @@ static bool check_hw_exists(void) | |||
222 | } | 225 | } |
223 | 226 | ||
224 | /* | 227 | /* |
228 | * If all the counters are enabled, the below test will always | ||
229 | * fail. The tools will also become useless in this scenario. | ||
230 | * Just fail and disable the hardware counters. | ||
231 | */ | ||
232 | |||
233 | if (reg_safe == -1) { | ||
234 | reg = reg_safe; | ||
235 | goto msr_fail; | ||
236 | } | ||
237 | |||
238 | /* | ||
225 | * Read the current value, change it and read it back to see if it | 239 | * Read the current value, change it and read it back to see if it |
226 | * matches, this is needed to detect certain hardware emulators | 240 | * matches, this is needed to detect certain hardware emulators |
227 | * (qemu/kvm) that don't trap on the MSR access and always return 0s. | 241 | * (qemu/kvm) that don't trap on the MSR access and always return 0s. |
228 | */ | 242 | */ |
229 | reg = x86_pmu_event_addr(0); | 243 | reg = x86_pmu_event_addr(reg_safe); |
230 | if (rdmsrl_safe(reg, &val)) | 244 | if (rdmsrl_safe(reg, &val)) |
231 | goto msr_fail; | 245 | goto msr_fail; |
232 | val ^= 0xffffUL; | 246 | val ^= 0xffffUL; |
@@ -611,6 +625,7 @@ struct sched_state { | |||
611 | int event; /* event index */ | 625 | int event; /* event index */ |
612 | int counter; /* counter index */ | 626 | int counter; /* counter index */ |
613 | int unassigned; /* number of events to be assigned left */ | 627 | int unassigned; /* number of events to be assigned left */ |
628 | int nr_gp; /* number of GP counters used */ | ||
614 | unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; | 629 | unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; |
615 | }; | 630 | }; |
616 | 631 | ||
@@ -620,27 +635,29 @@ struct sched_state { | |||
620 | struct perf_sched { | 635 | struct perf_sched { |
621 | int max_weight; | 636 | int max_weight; |
622 | int max_events; | 637 | int max_events; |
623 | struct perf_event **events; | 638 | int max_gp; |
624 | struct sched_state state; | ||
625 | int saved_states; | 639 | int saved_states; |
640 | struct event_constraint **constraints; | ||
641 | struct sched_state state; | ||
626 | struct sched_state saved[SCHED_STATES_MAX]; | 642 | struct sched_state saved[SCHED_STATES_MAX]; |
627 | }; | 643 | }; |
628 | 644 | ||
629 | /* | 645 | /* |
630 | * Initialize interator that runs through all events and counters. | 646 | * Initialize interator that runs through all events and counters. |
631 | */ | 647 | */ |
632 | static void perf_sched_init(struct perf_sched *sched, struct perf_event **events, | 648 | static void perf_sched_init(struct perf_sched *sched, struct event_constraint **constraints, |
633 | int num, int wmin, int wmax) | 649 | int num, int wmin, int wmax, int gpmax) |
634 | { | 650 | { |
635 | int idx; | 651 | int idx; |
636 | 652 | ||
637 | memset(sched, 0, sizeof(*sched)); | 653 | memset(sched, 0, sizeof(*sched)); |
638 | sched->max_events = num; | 654 | sched->max_events = num; |
639 | sched->max_weight = wmax; | 655 | sched->max_weight = wmax; |
640 | sched->events = events; | 656 | sched->max_gp = gpmax; |
657 | sched->constraints = constraints; | ||
641 | 658 | ||
642 | for (idx = 0; idx < num; idx++) { | 659 | for (idx = 0; idx < num; idx++) { |
643 | if (events[idx]->hw.constraint->weight == wmin) | 660 | if (constraints[idx]->weight == wmin) |
644 | break; | 661 | break; |
645 | } | 662 | } |
646 | 663 | ||
@@ -687,7 +704,7 @@ static bool __perf_sched_find_counter(struct perf_sched *sched) | |||
687 | if (sched->state.event >= sched->max_events) | 704 | if (sched->state.event >= sched->max_events) |
688 | return false; | 705 | return false; |
689 | 706 | ||
690 | c = sched->events[sched->state.event]->hw.constraint; | 707 | c = sched->constraints[sched->state.event]; |
691 | /* Prefer fixed purpose counters */ | 708 | /* Prefer fixed purpose counters */ |
692 | if (c->idxmsk64 & (~0ULL << INTEL_PMC_IDX_FIXED)) { | 709 | if (c->idxmsk64 & (~0ULL << INTEL_PMC_IDX_FIXED)) { |
693 | idx = INTEL_PMC_IDX_FIXED; | 710 | idx = INTEL_PMC_IDX_FIXED; |
@@ -696,11 +713,16 @@ static bool __perf_sched_find_counter(struct perf_sched *sched) | |||
696 | goto done; | 713 | goto done; |
697 | } | 714 | } |
698 | } | 715 | } |
716 | |||
699 | /* Grab the first unused counter starting with idx */ | 717 | /* Grab the first unused counter starting with idx */ |
700 | idx = sched->state.counter; | 718 | idx = sched->state.counter; |
701 | for_each_set_bit_from(idx, c->idxmsk, INTEL_PMC_IDX_FIXED) { | 719 | for_each_set_bit_from(idx, c->idxmsk, INTEL_PMC_IDX_FIXED) { |
702 | if (!__test_and_set_bit(idx, sched->state.used)) | 720 | if (!__test_and_set_bit(idx, sched->state.used)) { |
721 | if (sched->state.nr_gp++ >= sched->max_gp) | ||
722 | return false; | ||
723 | |||
703 | goto done; | 724 | goto done; |
725 | } | ||
704 | } | 726 | } |
705 | 727 | ||
706 | return false; | 728 | return false; |
@@ -745,7 +767,7 @@ static bool perf_sched_next_event(struct perf_sched *sched) | |||
745 | if (sched->state.weight > sched->max_weight) | 767 | if (sched->state.weight > sched->max_weight) |
746 | return false; | 768 | return false; |
747 | } | 769 | } |
748 | c = sched->events[sched->state.event]->hw.constraint; | 770 | c = sched->constraints[sched->state.event]; |
749 | } while (c->weight != sched->state.weight); | 771 | } while (c->weight != sched->state.weight); |
750 | 772 | ||
751 | sched->state.counter = 0; /* start with first counter */ | 773 | sched->state.counter = 0; /* start with first counter */ |
@@ -756,12 +778,12 @@ static bool perf_sched_next_event(struct perf_sched *sched) | |||
756 | /* | 778 | /* |
757 | * Assign a counter for each event. | 779 | * Assign a counter for each event. |
758 | */ | 780 | */ |
759 | int perf_assign_events(struct perf_event **events, int n, | 781 | int perf_assign_events(struct event_constraint **constraints, int n, |
760 | int wmin, int wmax, int *assign) | 782 | int wmin, int wmax, int gpmax, int *assign) |
761 | { | 783 | { |
762 | struct perf_sched sched; | 784 | struct perf_sched sched; |
763 | 785 | ||
764 | perf_sched_init(&sched, events, n, wmin, wmax); | 786 | perf_sched_init(&sched, constraints, n, wmin, wmax, gpmax); |
765 | 787 | ||
766 | do { | 788 | do { |
767 | if (!perf_sched_find_counter(&sched)) | 789 | if (!perf_sched_find_counter(&sched)) |
@@ -788,9 +810,9 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) | |||
788 | x86_pmu.start_scheduling(cpuc); | 810 | x86_pmu.start_scheduling(cpuc); |
789 | 811 | ||
790 | for (i = 0, wmin = X86_PMC_IDX_MAX, wmax = 0; i < n; i++) { | 812 | for (i = 0, wmin = X86_PMC_IDX_MAX, wmax = 0; i < n; i++) { |
791 | hwc = &cpuc->event_list[i]->hw; | 813 | cpuc->event_constraint[i] = NULL; |
792 | c = x86_pmu.get_event_constraints(cpuc, i, cpuc->event_list[i]); | 814 | c = x86_pmu.get_event_constraints(cpuc, i, cpuc->event_list[i]); |
793 | hwc->constraint = c; | 815 | cpuc->event_constraint[i] = c; |
794 | 816 | ||
795 | wmin = min(wmin, c->weight); | 817 | wmin = min(wmin, c->weight); |
796 | wmax = max(wmax, c->weight); | 818 | wmax = max(wmax, c->weight); |
@@ -801,7 +823,7 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) | |||
801 | */ | 823 | */ |
802 | for (i = 0; i < n; i++) { | 824 | for (i = 0; i < n; i++) { |
803 | hwc = &cpuc->event_list[i]->hw; | 825 | hwc = &cpuc->event_list[i]->hw; |
804 | c = hwc->constraint; | 826 | c = cpuc->event_constraint[i]; |
805 | 827 | ||
806 | /* never assigned */ | 828 | /* never assigned */ |
807 | if (hwc->idx == -1) | 829 | if (hwc->idx == -1) |
@@ -821,9 +843,26 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) | |||
821 | } | 843 | } |
822 | 844 | ||
823 | /* slow path */ | 845 | /* slow path */ |
824 | if (i != n) | 846 | if (i != n) { |
825 | unsched = perf_assign_events(cpuc->event_list, n, wmin, | 847 | int gpmax = x86_pmu.num_counters; |
826 | wmax, assign); | 848 | |
849 | /* | ||
850 | * Do not allow scheduling of more than half the available | ||
851 | * generic counters. | ||
852 | * | ||
853 | * This helps avoid counter starvation of sibling thread by | ||
854 | * ensuring at most half the counters cannot be in exclusive | ||
855 | * mode. There is no designated counters for the limits. Any | ||
856 | * N/2 counters can be used. This helps with events with | ||
857 | * specific counter constraints. | ||
858 | */ | ||
859 | if (is_ht_workaround_enabled() && !cpuc->is_fake && | ||
860 | READ_ONCE(cpuc->excl_cntrs->exclusive_present)) | ||
861 | gpmax /= 2; | ||
862 | |||
863 | unsched = perf_assign_events(cpuc->event_constraint, n, wmin, | ||
864 | wmax, gpmax, assign); | ||
865 | } | ||
827 | 866 | ||
828 | /* | 867 | /* |
829 | * In case of success (unsched = 0), mark events as committed, | 868 | * In case of success (unsched = 0), mark events as committed, |
@@ -840,7 +879,7 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) | |||
840 | e = cpuc->event_list[i]; | 879 | e = cpuc->event_list[i]; |
841 | e->hw.flags |= PERF_X86_EVENT_COMMITTED; | 880 | e->hw.flags |= PERF_X86_EVENT_COMMITTED; |
842 | if (x86_pmu.commit_scheduling) | 881 | if (x86_pmu.commit_scheduling) |
843 | x86_pmu.commit_scheduling(cpuc, e, assign[i]); | 882 | x86_pmu.commit_scheduling(cpuc, i, assign[i]); |
844 | } | 883 | } |
845 | } | 884 | } |
846 | 885 | ||
@@ -1292,8 +1331,10 @@ static void x86_pmu_del(struct perf_event *event, int flags) | |||
1292 | x86_pmu.put_event_constraints(cpuc, event); | 1331 | x86_pmu.put_event_constraints(cpuc, event); |
1293 | 1332 | ||
1294 | /* Delete the array entry. */ | 1333 | /* Delete the array entry. */ |
1295 | while (++i < cpuc->n_events) | 1334 | while (++i < cpuc->n_events) { |
1296 | cpuc->event_list[i-1] = cpuc->event_list[i]; | 1335 | cpuc->event_list[i-1] = cpuc->event_list[i]; |
1336 | cpuc->event_constraint[i-1] = cpuc->event_constraint[i]; | ||
1337 | } | ||
1297 | --cpuc->n_events; | 1338 | --cpuc->n_events; |
1298 | 1339 | ||
1299 | perf_event_update_userpage(event); | 1340 | perf_event_update_userpage(event); |
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 6ac5cb7a9e14..ef78516850fb 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h | |||
@@ -74,6 +74,7 @@ struct event_constraint { | |||
74 | #define PERF_X86_EVENT_EXCL 0x0040 /* HT exclusivity on counter */ | 74 | #define PERF_X86_EVENT_EXCL 0x0040 /* HT exclusivity on counter */ |
75 | #define PERF_X86_EVENT_DYNAMIC 0x0080 /* dynamic alloc'd constraint */ | 75 | #define PERF_X86_EVENT_DYNAMIC 0x0080 /* dynamic alloc'd constraint */ |
76 | #define PERF_X86_EVENT_RDPMC_ALLOWED 0x0100 /* grant rdpmc permission */ | 76 | #define PERF_X86_EVENT_RDPMC_ALLOWED 0x0100 /* grant rdpmc permission */ |
77 | #define PERF_X86_EVENT_EXCL_ACCT 0x0200 /* accounted EXCL event */ | ||
77 | 78 | ||
78 | 79 | ||
79 | struct amd_nb { | 80 | struct amd_nb { |
@@ -134,8 +135,6 @@ enum intel_excl_state_type { | |||
134 | struct intel_excl_states { | 135 | struct intel_excl_states { |
135 | enum intel_excl_state_type init_state[X86_PMC_IDX_MAX]; | 136 | enum intel_excl_state_type init_state[X86_PMC_IDX_MAX]; |
136 | enum intel_excl_state_type state[X86_PMC_IDX_MAX]; | 137 | enum intel_excl_state_type state[X86_PMC_IDX_MAX]; |
137 | int num_alloc_cntrs;/* #counters allocated */ | ||
138 | int max_alloc_cntrs;/* max #counters allowed */ | ||
139 | bool sched_started; /* true if scheduling has started */ | 138 | bool sched_started; /* true if scheduling has started */ |
140 | }; | 139 | }; |
141 | 140 | ||
@@ -144,6 +143,11 @@ struct intel_excl_cntrs { | |||
144 | 143 | ||
145 | struct intel_excl_states states[2]; | 144 | struct intel_excl_states states[2]; |
146 | 145 | ||
146 | union { | ||
147 | u16 has_exclusive[2]; | ||
148 | u32 exclusive_present; | ||
149 | }; | ||
150 | |||
147 | int refcnt; /* per-core: #HT threads */ | 151 | int refcnt; /* per-core: #HT threads */ |
148 | unsigned core_id; /* per-core: core id */ | 152 | unsigned core_id; /* per-core: core id */ |
149 | }; | 153 | }; |
@@ -172,7 +176,11 @@ struct cpu_hw_events { | |||
172 | added in the current transaction */ | 176 | added in the current transaction */ |
173 | int assign[X86_PMC_IDX_MAX]; /* event to counter assignment */ | 177 | int assign[X86_PMC_IDX_MAX]; /* event to counter assignment */ |
174 | u64 tags[X86_PMC_IDX_MAX]; | 178 | u64 tags[X86_PMC_IDX_MAX]; |
179 | |||
175 | struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */ | 180 | struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */ |
181 | struct event_constraint *event_constraint[X86_PMC_IDX_MAX]; | ||
182 | |||
183 | int n_excl; /* the number of exclusive events */ | ||
176 | 184 | ||
177 | unsigned int group_flag; | 185 | unsigned int group_flag; |
178 | int is_fake; | 186 | int is_fake; |
@@ -519,9 +527,7 @@ struct x86_pmu { | |||
519 | void (*put_event_constraints)(struct cpu_hw_events *cpuc, | 527 | void (*put_event_constraints)(struct cpu_hw_events *cpuc, |
520 | struct perf_event *event); | 528 | struct perf_event *event); |
521 | 529 | ||
522 | void (*commit_scheduling)(struct cpu_hw_events *cpuc, | 530 | void (*commit_scheduling)(struct cpu_hw_events *cpuc, int idx, int cntr); |
523 | struct perf_event *event, | ||
524 | int cntr); | ||
525 | 531 | ||
526 | void (*start_scheduling)(struct cpu_hw_events *cpuc); | 532 | void (*start_scheduling)(struct cpu_hw_events *cpuc); |
527 | 533 | ||
@@ -717,8 +723,8 @@ static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, | |||
717 | 723 | ||
718 | void x86_pmu_enable_all(int added); | 724 | void x86_pmu_enable_all(int added); |
719 | 725 | ||
720 | int perf_assign_events(struct perf_event **events, int n, | 726 | int perf_assign_events(struct event_constraint **constraints, int n, |
721 | int wmin, int wmax, int *assign); | 727 | int wmin, int wmax, int gpmax, int *assign); |
722 | int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign); | 728 | int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign); |
723 | 729 | ||
724 | void x86_pmu_stop(struct perf_event *event, int flags); | 730 | void x86_pmu_stop(struct perf_event *event, int flags); |
@@ -929,4 +935,8 @@ static inline struct intel_shared_regs *allocate_shared_regs(int cpu) | |||
929 | return NULL; | 935 | return NULL; |
930 | } | 936 | } |
931 | 937 | ||
938 | static inline int is_ht_workaround_enabled(void) | ||
939 | { | ||
940 | return 0; | ||
941 | } | ||
932 | #endif /* CONFIG_CPU_SUP_INTEL */ | 942 | #endif /* CONFIG_CPU_SUP_INTEL */ |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 3998131d1a68..a1e35c9f06b9 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -1923,7 +1923,6 @@ intel_start_scheduling(struct cpu_hw_events *cpuc) | |||
1923 | xl = &excl_cntrs->states[tid]; | 1923 | xl = &excl_cntrs->states[tid]; |
1924 | 1924 | ||
1925 | xl->sched_started = true; | 1925 | xl->sched_started = true; |
1926 | xl->num_alloc_cntrs = 0; | ||
1927 | /* | 1926 | /* |
1928 | * lock shared state until we are done scheduling | 1927 | * lock shared state until we are done scheduling |
1929 | * in stop_event_scheduling() | 1928 | * in stop_event_scheduling() |
@@ -2000,6 +1999,11 @@ intel_get_excl_constraints(struct cpu_hw_events *cpuc, struct perf_event *event, | |||
2000 | * across HT threads | 1999 | * across HT threads |
2001 | */ | 2000 | */ |
2002 | is_excl = c->flags & PERF_X86_EVENT_EXCL; | 2001 | is_excl = c->flags & PERF_X86_EVENT_EXCL; |
2002 | if (is_excl && !(event->hw.flags & PERF_X86_EVENT_EXCL_ACCT)) { | ||
2003 | event->hw.flags |= PERF_X86_EVENT_EXCL_ACCT; | ||
2004 | if (!cpuc->n_excl++) | ||
2005 | WRITE_ONCE(excl_cntrs->has_exclusive[tid], 1); | ||
2006 | } | ||
2003 | 2007 | ||
2004 | /* | 2008 | /* |
2005 | * xl = state of current HT | 2009 | * xl = state of current HT |
@@ -2008,18 +2012,6 @@ intel_get_excl_constraints(struct cpu_hw_events *cpuc, struct perf_event *event, | |||
2008 | xl = &excl_cntrs->states[tid]; | 2012 | xl = &excl_cntrs->states[tid]; |
2009 | xlo = &excl_cntrs->states[o_tid]; | 2013 | xlo = &excl_cntrs->states[o_tid]; |
2010 | 2014 | ||
2011 | /* | ||
2012 | * do not allow scheduling of more than max_alloc_cntrs | ||
2013 | * which is set to half the available generic counters. | ||
2014 | * this helps avoid counter starvation of sibling thread | ||
2015 | * by ensuring at most half the counters cannot be in | ||
2016 | * exclusive mode. There is not designated counters for the | ||
2017 | * limits. Any N/2 counters can be used. This helps with | ||
2018 | * events with specifix counter constraints | ||
2019 | */ | ||
2020 | if (xl->num_alloc_cntrs++ == xl->max_alloc_cntrs) | ||
2021 | return &emptyconstraint; | ||
2022 | |||
2023 | cx = c; | 2015 | cx = c; |
2024 | 2016 | ||
2025 | /* | 2017 | /* |
@@ -2106,7 +2098,7 @@ static struct event_constraint * | |||
2106 | intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx, | 2098 | intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx, |
2107 | struct perf_event *event) | 2099 | struct perf_event *event) |
2108 | { | 2100 | { |
2109 | struct event_constraint *c1 = event->hw.constraint; | 2101 | struct event_constraint *c1 = cpuc->event_constraint[idx]; |
2110 | struct event_constraint *c2; | 2102 | struct event_constraint *c2; |
2111 | 2103 | ||
2112 | /* | 2104 | /* |
@@ -2150,6 +2142,11 @@ static void intel_put_excl_constraints(struct cpu_hw_events *cpuc, | |||
2150 | 2142 | ||
2151 | xl = &excl_cntrs->states[tid]; | 2143 | xl = &excl_cntrs->states[tid]; |
2152 | xlo = &excl_cntrs->states[o_tid]; | 2144 | xlo = &excl_cntrs->states[o_tid]; |
2145 | if (hwc->flags & PERF_X86_EVENT_EXCL_ACCT) { | ||
2146 | hwc->flags &= ~PERF_X86_EVENT_EXCL_ACCT; | ||
2147 | if (!--cpuc->n_excl) | ||
2148 | WRITE_ONCE(excl_cntrs->has_exclusive[tid], 0); | ||
2149 | } | ||
2153 | 2150 | ||
2154 | /* | 2151 | /* |
2155 | * put_constraint may be called from x86_schedule_events() | 2152 | * put_constraint may be called from x86_schedule_events() |
@@ -2188,8 +2185,6 @@ intel_put_shared_regs_event_constraints(struct cpu_hw_events *cpuc, | |||
2188 | static void intel_put_event_constraints(struct cpu_hw_events *cpuc, | 2185 | static void intel_put_event_constraints(struct cpu_hw_events *cpuc, |
2189 | struct perf_event *event) | 2186 | struct perf_event *event) |
2190 | { | 2187 | { |
2191 | struct event_constraint *c = event->hw.constraint; | ||
2192 | |||
2193 | intel_put_shared_regs_event_constraints(cpuc, event); | 2188 | intel_put_shared_regs_event_constraints(cpuc, event); |
2194 | 2189 | ||
2195 | /* | 2190 | /* |
@@ -2197,19 +2192,14 @@ static void intel_put_event_constraints(struct cpu_hw_events *cpuc, | |||
2197 | * all events are subject to and must call the | 2192 | * all events are subject to and must call the |
2198 | * put_excl_constraints() routine | 2193 | * put_excl_constraints() routine |
2199 | */ | 2194 | */ |
2200 | if (c && cpuc->excl_cntrs) | 2195 | if (cpuc->excl_cntrs) |
2201 | intel_put_excl_constraints(cpuc, event); | 2196 | intel_put_excl_constraints(cpuc, event); |
2202 | |||
2203 | /* cleanup dynamic constraint */ | ||
2204 | if (c && (c->flags & PERF_X86_EVENT_DYNAMIC)) | ||
2205 | event->hw.constraint = NULL; | ||
2206 | } | 2197 | } |
2207 | 2198 | ||
2208 | static void intel_commit_scheduling(struct cpu_hw_events *cpuc, | 2199 | static void intel_commit_scheduling(struct cpu_hw_events *cpuc, int idx, int cntr) |
2209 | struct perf_event *event, int cntr) | ||
2210 | { | 2200 | { |
2211 | struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs; | 2201 | struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs; |
2212 | struct event_constraint *c = event->hw.constraint; | 2202 | struct event_constraint *c = cpuc->event_constraint[idx]; |
2213 | struct intel_excl_states *xlo, *xl; | 2203 | struct intel_excl_states *xlo, *xl; |
2214 | int tid = cpuc->excl_thread_id; | 2204 | int tid = cpuc->excl_thread_id; |
2215 | int o_tid = 1 - tid; | 2205 | int o_tid = 1 - tid; |
@@ -2639,8 +2629,6 @@ static void intel_pmu_cpu_starting(int cpu) | |||
2639 | cpuc->lbr_sel = &cpuc->shared_regs->regs[EXTRA_REG_LBR]; | 2629 | cpuc->lbr_sel = &cpuc->shared_regs->regs[EXTRA_REG_LBR]; |
2640 | 2630 | ||
2641 | if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) { | 2631 | if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) { |
2642 | int h = x86_pmu.num_counters >> 1; | ||
2643 | |||
2644 | for_each_cpu(i, topology_thread_cpumask(cpu)) { | 2632 | for_each_cpu(i, topology_thread_cpumask(cpu)) { |
2645 | struct intel_excl_cntrs *c; | 2633 | struct intel_excl_cntrs *c; |
2646 | 2634 | ||
@@ -2654,11 +2642,6 @@ static void intel_pmu_cpu_starting(int cpu) | |||
2654 | } | 2642 | } |
2655 | cpuc->excl_cntrs->core_id = core_id; | 2643 | cpuc->excl_cntrs->core_id = core_id; |
2656 | cpuc->excl_cntrs->refcnt++; | 2644 | cpuc->excl_cntrs->refcnt++; |
2657 | /* | ||
2658 | * set hard limit to half the number of generic counters | ||
2659 | */ | ||
2660 | cpuc->excl_cntrs->states[0].max_alloc_cntrs = h; | ||
2661 | cpuc->excl_cntrs->states[1].max_alloc_cntrs = h; | ||
2662 | } | 2645 | } |
2663 | } | 2646 | } |
2664 | 2647 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 813f75d71175..7f73b3553e2e 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c | |||
@@ -706,9 +706,9 @@ void intel_pmu_pebs_disable(struct perf_event *event) | |||
706 | 706 | ||
707 | cpuc->pebs_enabled &= ~(1ULL << hwc->idx); | 707 | cpuc->pebs_enabled &= ~(1ULL << hwc->idx); |
708 | 708 | ||
709 | if (event->hw.constraint->flags & PERF_X86_EVENT_PEBS_LDLAT) | 709 | if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT) |
710 | cpuc->pebs_enabled &= ~(1ULL << (hwc->idx + 32)); | 710 | cpuc->pebs_enabled &= ~(1ULL << (hwc->idx + 32)); |
711 | else if (event->hw.constraint->flags & PERF_X86_EVENT_PEBS_ST) | 711 | else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST) |
712 | cpuc->pebs_enabled &= ~(1ULL << 63); | 712 | cpuc->pebs_enabled &= ~(1ULL << 63); |
713 | 713 | ||
714 | if (cpuc->enabled) | 714 | if (cpuc->enabled) |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_pt.c b/arch/x86/kernel/cpu/perf_event_intel_pt.c index ffe666c2c6b5..123ff1bb2f60 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_pt.c +++ b/arch/x86/kernel/cpu/perf_event_intel_pt.c | |||
@@ -151,7 +151,7 @@ static int __init pt_pmu_hw_init(void) | |||
151 | 151 | ||
152 | de_attr->attr.attr.name = pt_caps[i].name; | 152 | de_attr->attr.attr.name = pt_caps[i].name; |
153 | 153 | ||
154 | sysfs_attr_init(&de_attrs->attr.attr); | 154 | sysfs_attr_init(&de_attr->attr.attr); |
155 | 155 | ||
156 | de_attr->attr.attr.mode = S_IRUGO; | 156 | de_attr->attr.attr.mode = S_IRUGO; |
157 | de_attr->attr.show = pt_cap_show; | 157 | de_attr->attr.show = pt_cap_show; |
@@ -615,7 +615,8 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf, | |||
615 | struct perf_output_handle *handle) | 615 | struct perf_output_handle *handle) |
616 | 616 | ||
617 | { | 617 | { |
618 | unsigned long idx, npages, end; | 618 | unsigned long head = local64_read(&buf->head); |
619 | unsigned long idx, npages, wakeup; | ||
619 | 620 | ||
620 | if (buf->snapshot) | 621 | if (buf->snapshot) |
621 | return 0; | 622 | return 0; |
@@ -634,17 +635,26 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf, | |||
634 | buf->topa_index[buf->stop_pos]->stop = 0; | 635 | buf->topa_index[buf->stop_pos]->stop = 0; |
635 | buf->topa_index[buf->intr_pos]->intr = 0; | 636 | buf->topa_index[buf->intr_pos]->intr = 0; |
636 | 637 | ||
637 | if (pt_cap_get(PT_CAP_topa_multiple_entries)) { | 638 | /* how many pages till the STOP marker */ |
638 | npages = (handle->size + 1) >> PAGE_SHIFT; | 639 | npages = handle->size >> PAGE_SHIFT; |
639 | end = (local64_read(&buf->head) >> PAGE_SHIFT) + npages; | 640 | |
640 | /*if (end > handle->wakeup >> PAGE_SHIFT) | 641 | /* if it's on a page boundary, fill up one more page */ |
641 | end = handle->wakeup >> PAGE_SHIFT;*/ | 642 | if (!offset_in_page(head + handle->size + 1)) |
642 | idx = end & (buf->nr_pages - 1); | 643 | npages++; |
643 | buf->stop_pos = idx; | 644 | |
644 | idx = (local64_read(&buf->head) >> PAGE_SHIFT) + npages - 1; | 645 | idx = (head >> PAGE_SHIFT) + npages; |
645 | idx &= buf->nr_pages - 1; | 646 | idx &= buf->nr_pages - 1; |
646 | buf->intr_pos = idx; | 647 | buf->stop_pos = idx; |
647 | } | 648 | |
649 | wakeup = handle->wakeup >> PAGE_SHIFT; | ||
650 | |||
651 | /* in the worst case, wake up the consumer one page before hard stop */ | ||
652 | idx = (head >> PAGE_SHIFT) + npages - 1; | ||
653 | if (idx > wakeup) | ||
654 | idx = wakeup; | ||
655 | |||
656 | idx &= buf->nr_pages - 1; | ||
657 | buf->intr_pos = idx; | ||
648 | 658 | ||
649 | buf->topa_index[buf->stop_pos]->stop = 1; | 659 | buf->topa_index[buf->stop_pos]->stop = 1; |
650 | buf->topa_index[buf->intr_pos]->intr = 1; | 660 | buf->topa_index[buf->intr_pos]->intr = 1; |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index c635b8b49e93..90b7c501c95b 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c | |||
@@ -365,9 +365,8 @@ static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int | |||
365 | bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX); | 365 | bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX); |
366 | 366 | ||
367 | for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) { | 367 | for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) { |
368 | hwc = &box->event_list[i]->hw; | ||
369 | c = uncore_get_event_constraint(box, box->event_list[i]); | 368 | c = uncore_get_event_constraint(box, box->event_list[i]); |
370 | hwc->constraint = c; | 369 | box->event_constraint[i] = c; |
371 | wmin = min(wmin, c->weight); | 370 | wmin = min(wmin, c->weight); |
372 | wmax = max(wmax, c->weight); | 371 | wmax = max(wmax, c->weight); |
373 | } | 372 | } |
@@ -375,7 +374,7 @@ static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int | |||
375 | /* fastpath, try to reuse previous register */ | 374 | /* fastpath, try to reuse previous register */ |
376 | for (i = 0; i < n; i++) { | 375 | for (i = 0; i < n; i++) { |
377 | hwc = &box->event_list[i]->hw; | 376 | hwc = &box->event_list[i]->hw; |
378 | c = hwc->constraint; | 377 | c = box->event_constraint[i]; |
379 | 378 | ||
380 | /* never assigned */ | 379 | /* never assigned */ |
381 | if (hwc->idx == -1) | 380 | if (hwc->idx == -1) |
@@ -395,8 +394,8 @@ static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int | |||
395 | } | 394 | } |
396 | /* slow path */ | 395 | /* slow path */ |
397 | if (i != n) | 396 | if (i != n) |
398 | ret = perf_assign_events(box->event_list, n, | 397 | ret = perf_assign_events(box->event_constraint, n, |
399 | wmin, wmax, assign); | 398 | wmin, wmax, n, assign); |
400 | 399 | ||
401 | if (!assign || ret) { | 400 | if (!assign || ret) { |
402 | for (i = 0; i < n; i++) | 401 | for (i = 0; i < n; i++) |
@@ -840,6 +839,7 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id | |||
840 | box->phys_id = phys_id; | 839 | box->phys_id = phys_id; |
841 | box->pci_dev = pdev; | 840 | box->pci_dev = pdev; |
842 | box->pmu = pmu; | 841 | box->pmu = pmu; |
842 | uncore_box_init(box); | ||
843 | pci_set_drvdata(pdev, box); | 843 | pci_set_drvdata(pdev, box); |
844 | 844 | ||
845 | raw_spin_lock(&uncore_box_lock); | 845 | raw_spin_lock(&uncore_box_lock); |
@@ -1003,8 +1003,10 @@ static int uncore_cpu_starting(int cpu) | |||
1003 | pmu = &type->pmus[j]; | 1003 | pmu = &type->pmus[j]; |
1004 | box = *per_cpu_ptr(pmu->box, cpu); | 1004 | box = *per_cpu_ptr(pmu->box, cpu); |
1005 | /* called by uncore_cpu_init? */ | 1005 | /* called by uncore_cpu_init? */ |
1006 | if (box && box->phys_id >= 0) | 1006 | if (box && box->phys_id >= 0) { |
1007 | uncore_box_init(box); | ||
1007 | continue; | 1008 | continue; |
1009 | } | ||
1008 | 1010 | ||
1009 | for_each_online_cpu(k) { | 1011 | for_each_online_cpu(k) { |
1010 | exist = *per_cpu_ptr(pmu->box, k); | 1012 | exist = *per_cpu_ptr(pmu->box, k); |
@@ -1020,8 +1022,10 @@ static int uncore_cpu_starting(int cpu) | |||
1020 | } | 1022 | } |
1021 | } | 1023 | } |
1022 | 1024 | ||
1023 | if (box) | 1025 | if (box) { |
1024 | box->phys_id = phys_id; | 1026 | box->phys_id = phys_id; |
1027 | uncore_box_init(box); | ||
1028 | } | ||
1025 | } | 1029 | } |
1026 | } | 1030 | } |
1027 | return 0; | 1031 | return 0; |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index 6c8c1e7e69d8..ceac8f5dc018 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h | |||
@@ -97,6 +97,7 @@ struct intel_uncore_box { | |||
97 | atomic_t refcnt; | 97 | atomic_t refcnt; |
98 | struct perf_event *events[UNCORE_PMC_IDX_MAX]; | 98 | struct perf_event *events[UNCORE_PMC_IDX_MAX]; |
99 | struct perf_event *event_list[UNCORE_PMC_IDX_MAX]; | 99 | struct perf_event *event_list[UNCORE_PMC_IDX_MAX]; |
100 | struct event_constraint *event_constraint[UNCORE_PMC_IDX_MAX]; | ||
100 | unsigned long active_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; | 101 | unsigned long active_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; |
101 | u64 tags[UNCORE_PMC_IDX_MAX]; | 102 | u64 tags[UNCORE_PMC_IDX_MAX]; |
102 | struct pci_dev *pci_dev; | 103 | struct pci_dev *pci_dev; |
@@ -257,14 +258,6 @@ static inline int uncore_num_counters(struct intel_uncore_box *box) | |||
257 | return box->pmu->type->num_counters; | 258 | return box->pmu->type->num_counters; |
258 | } | 259 | } |
259 | 260 | ||
260 | static inline void uncore_box_init(struct intel_uncore_box *box) | ||
261 | { | ||
262 | if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) { | ||
263 | if (box->pmu->type->ops->init_box) | ||
264 | box->pmu->type->ops->init_box(box); | ||
265 | } | ||
266 | } | ||
267 | |||
268 | static inline void uncore_disable_box(struct intel_uncore_box *box) | 261 | static inline void uncore_disable_box(struct intel_uncore_box *box) |
269 | { | 262 | { |
270 | if (box->pmu->type->ops->disable_box) | 263 | if (box->pmu->type->ops->disable_box) |
@@ -273,8 +266,6 @@ static inline void uncore_disable_box(struct intel_uncore_box *box) | |||
273 | 266 | ||
274 | static inline void uncore_enable_box(struct intel_uncore_box *box) | 267 | static inline void uncore_enable_box(struct intel_uncore_box *box) |
275 | { | 268 | { |
276 | uncore_box_init(box); | ||
277 | |||
278 | if (box->pmu->type->ops->enable_box) | 269 | if (box->pmu->type->ops->enable_box) |
279 | box->pmu->type->ops->enable_box(box); | 270 | box->pmu->type->ops->enable_box(box); |
280 | } | 271 | } |
@@ -297,6 +288,14 @@ static inline u64 uncore_read_counter(struct intel_uncore_box *box, | |||
297 | return box->pmu->type->ops->read_counter(box, event); | 288 | return box->pmu->type->ops->read_counter(box, event); |
298 | } | 289 | } |
299 | 290 | ||
291 | static inline void uncore_box_init(struct intel_uncore_box *box) | ||
292 | { | ||
293 | if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) { | ||
294 | if (box->pmu->type->ops->init_box) | ||
295 | box->pmu->type->ops->init_box(box); | ||
296 | } | ||
297 | } | ||
298 | |||
300 | static inline bool uncore_box_is_fake(struct intel_uncore_box *box) | 299 | static inline bool uncore_box_is_fake(struct intel_uncore_box *box) |
301 | { | 300 | { |
302 | return (box->phys_id < 0); | 301 | return (box->phys_id < 0); |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c index 12d9548457e7..6d6e85dd5849 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c | |||
@@ -164,8 +164,8 @@ | |||
164 | ((1ULL << (n)) - 1))) | 164 | ((1ULL << (n)) - 1))) |
165 | 165 | ||
166 | /* Haswell-EP Ubox */ | 166 | /* Haswell-EP Ubox */ |
167 | #define HSWEP_U_MSR_PMON_CTR0 0x705 | 167 | #define HSWEP_U_MSR_PMON_CTR0 0x709 |
168 | #define HSWEP_U_MSR_PMON_CTL0 0x709 | 168 | #define HSWEP_U_MSR_PMON_CTL0 0x705 |
169 | #define HSWEP_U_MSR_PMON_FILTER 0x707 | 169 | #define HSWEP_U_MSR_PMON_FILTER 0x707 |
170 | 170 | ||
171 | #define HSWEP_U_MSR_PMON_UCLK_FIXED_CTL 0x703 | 171 | #define HSWEP_U_MSR_PMON_UCLK_FIXED_CTL 0x703 |
@@ -1914,7 +1914,7 @@ static struct intel_uncore_type hswep_uncore_cbox = { | |||
1914 | .name = "cbox", | 1914 | .name = "cbox", |
1915 | .num_counters = 4, | 1915 | .num_counters = 4, |
1916 | .num_boxes = 18, | 1916 | .num_boxes = 18, |
1917 | .perf_ctr_bits = 44, | 1917 | .perf_ctr_bits = 48, |
1918 | .event_ctl = HSWEP_C0_MSR_PMON_CTL0, | 1918 | .event_ctl = HSWEP_C0_MSR_PMON_CTL0, |
1919 | .perf_ctr = HSWEP_C0_MSR_PMON_CTR0, | 1919 | .perf_ctr = HSWEP_C0_MSR_PMON_CTR0, |
1920 | .event_mask = SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK, | 1920 | .event_mask = SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK, |
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 2b55ee6db053..5a4668136e98 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
@@ -167,7 +167,7 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) | |||
167 | clear_bss(); | 167 | clear_bss(); |
168 | 168 | ||
169 | for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) | 169 | for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) |
170 | set_intr_gate(i, early_idt_handlers[i]); | 170 | set_intr_gate(i, early_idt_handler_array[i]); |
171 | load_idt((const struct desc_ptr *)&idt_descr); | 171 | load_idt((const struct desc_ptr *)&idt_descr); |
172 | 172 | ||
173 | copy_bootdata(__va(real_mode_data)); | 173 | copy_bootdata(__va(real_mode_data)); |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index d031bad9e07e..53eeb226657c 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -478,21 +478,22 @@ is486: | |||
478 | __INIT | 478 | __INIT |
479 | setup_once: | 479 | setup_once: |
480 | /* | 480 | /* |
481 | * Set up a idt with 256 entries pointing to ignore_int, | 481 | * Set up a idt with 256 interrupt gates that push zero if there |
482 | * interrupt gates. It doesn't actually load idt - that needs | 482 | * is no error code and then jump to early_idt_handler_common. |
483 | * to be done on each CPU. Interrupts are enabled elsewhere, | 483 | * It doesn't actually load the idt - that needs to be done on |
484 | * when we can be relatively sure everything is ok. | 484 | * each CPU. Interrupts are enabled elsewhere, when we can be |
485 | * relatively sure everything is ok. | ||
485 | */ | 486 | */ |
486 | 487 | ||
487 | movl $idt_table,%edi | 488 | movl $idt_table,%edi |
488 | movl $early_idt_handlers,%eax | 489 | movl $early_idt_handler_array,%eax |
489 | movl $NUM_EXCEPTION_VECTORS,%ecx | 490 | movl $NUM_EXCEPTION_VECTORS,%ecx |
490 | 1: | 491 | 1: |
491 | movl %eax,(%edi) | 492 | movl %eax,(%edi) |
492 | movl %eax,4(%edi) | 493 | movl %eax,4(%edi) |
493 | /* interrupt gate, dpl=0, present */ | 494 | /* interrupt gate, dpl=0, present */ |
494 | movl $(0x8E000000 + __KERNEL_CS),2(%edi) | 495 | movl $(0x8E000000 + __KERNEL_CS),2(%edi) |
495 | addl $9,%eax | 496 | addl $EARLY_IDT_HANDLER_SIZE,%eax |
496 | addl $8,%edi | 497 | addl $8,%edi |
497 | loop 1b | 498 | loop 1b |
498 | 499 | ||
@@ -524,26 +525,28 @@ setup_once: | |||
524 | andl $0,setup_once_ref /* Once is enough, thanks */ | 525 | andl $0,setup_once_ref /* Once is enough, thanks */ |
525 | ret | 526 | ret |
526 | 527 | ||
527 | ENTRY(early_idt_handlers) | 528 | ENTRY(early_idt_handler_array) |
528 | # 36(%esp) %eflags | 529 | # 36(%esp) %eflags |
529 | # 32(%esp) %cs | 530 | # 32(%esp) %cs |
530 | # 28(%esp) %eip | 531 | # 28(%esp) %eip |
531 | # 24(%rsp) error code | 532 | # 24(%rsp) error code |
532 | i = 0 | 533 | i = 0 |
533 | .rept NUM_EXCEPTION_VECTORS | 534 | .rept NUM_EXCEPTION_VECTORS |
534 | .if (EXCEPTION_ERRCODE_MASK >> i) & 1 | 535 | .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1 |
535 | ASM_NOP2 | ||
536 | .else | ||
537 | pushl $0 # Dummy error code, to make stack frame uniform | 536 | pushl $0 # Dummy error code, to make stack frame uniform |
538 | .endif | 537 | .endif |
539 | pushl $i # 20(%esp) Vector number | 538 | pushl $i # 20(%esp) Vector number |
540 | jmp early_idt_handler | 539 | jmp early_idt_handler_common |
541 | i = i + 1 | 540 | i = i + 1 |
541 | .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc | ||
542 | .endr | 542 | .endr |
543 | ENDPROC(early_idt_handlers) | 543 | ENDPROC(early_idt_handler_array) |
544 | 544 | ||
545 | /* This is global to keep gas from relaxing the jumps */ | 545 | early_idt_handler_common: |
546 | ENTRY(early_idt_handler) | 546 | /* |
547 | * The stack is the hardware frame, an error code or zero, and the | ||
548 | * vector number. | ||
549 | */ | ||
547 | cld | 550 | cld |
548 | 551 | ||
549 | cmpl $2,(%esp) # X86_TRAP_NMI | 552 | cmpl $2,(%esp) # X86_TRAP_NMI |
@@ -603,7 +606,7 @@ ex_entry: | |||
603 | is_nmi: | 606 | is_nmi: |
604 | addl $8,%esp /* drop vector number and error code */ | 607 | addl $8,%esp /* drop vector number and error code */ |
605 | iret | 608 | iret |
606 | ENDPROC(early_idt_handler) | 609 | ENDPROC(early_idt_handler_common) |
607 | 610 | ||
608 | /* This is the default interrupt "handler" :-) */ | 611 | /* This is the default interrupt "handler" :-) */ |
609 | ALIGN | 612 | ALIGN |
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index ae6588b301c2..df7e78057ae0 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S | |||
@@ -321,26 +321,28 @@ bad_address: | |||
321 | jmp bad_address | 321 | jmp bad_address |
322 | 322 | ||
323 | __INIT | 323 | __INIT |
324 | .globl early_idt_handlers | 324 | ENTRY(early_idt_handler_array) |
325 | early_idt_handlers: | ||
326 | # 104(%rsp) %rflags | 325 | # 104(%rsp) %rflags |
327 | # 96(%rsp) %cs | 326 | # 96(%rsp) %cs |
328 | # 88(%rsp) %rip | 327 | # 88(%rsp) %rip |
329 | # 80(%rsp) error code | 328 | # 80(%rsp) error code |
330 | i = 0 | 329 | i = 0 |
331 | .rept NUM_EXCEPTION_VECTORS | 330 | .rept NUM_EXCEPTION_VECTORS |
332 | .if (EXCEPTION_ERRCODE_MASK >> i) & 1 | 331 | .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1 |
333 | ASM_NOP2 | ||
334 | .else | ||
335 | pushq $0 # Dummy error code, to make stack frame uniform | 332 | pushq $0 # Dummy error code, to make stack frame uniform |
336 | .endif | 333 | .endif |
337 | pushq $i # 72(%rsp) Vector number | 334 | pushq $i # 72(%rsp) Vector number |
338 | jmp early_idt_handler | 335 | jmp early_idt_handler_common |
339 | i = i + 1 | 336 | i = i + 1 |
337 | .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc | ||
340 | .endr | 338 | .endr |
339 | ENDPROC(early_idt_handler_array) | ||
341 | 340 | ||
342 | /* This is global to keep gas from relaxing the jumps */ | 341 | early_idt_handler_common: |
343 | ENTRY(early_idt_handler) | 342 | /* |
343 | * The stack is the hardware frame, an error code or zero, and the | ||
344 | * vector number. | ||
345 | */ | ||
344 | cld | 346 | cld |
345 | 347 | ||
346 | cmpl $2,(%rsp) # X86_TRAP_NMI | 348 | cmpl $2,(%rsp) # X86_TRAP_NMI |
@@ -412,7 +414,7 @@ ENTRY(early_idt_handler) | |||
412 | is_nmi: | 414 | is_nmi: |
413 | addq $16,%rsp # drop vector number and error code | 415 | addq $16,%rsp # drop vector number and error code |
414 | INTERRUPT_RETURN | 416 | INTERRUPT_RETURN |
415 | ENDPROC(early_idt_handler) | 417 | ENDPROC(early_idt_handler_common) |
416 | 418 | ||
417 | __INITDATA | 419 | __INITDATA |
418 | 420 | ||
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 44a7d2515497..b73337634214 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -4215,13 +4215,13 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, | |||
4215 | u64 entry, gentry, *spte; | 4215 | u64 entry, gentry, *spte; |
4216 | int npte; | 4216 | int npte; |
4217 | bool remote_flush, local_flush, zap_page; | 4217 | bool remote_flush, local_flush, zap_page; |
4218 | union kvm_mmu_page_role mask = (union kvm_mmu_page_role) { | 4218 | union kvm_mmu_page_role mask = { }; |
4219 | .cr0_wp = 1, | 4219 | |
4220 | .cr4_pae = 1, | 4220 | mask.cr0_wp = 1; |
4221 | .nxe = 1, | 4221 | mask.cr4_pae = 1; |
4222 | .smep_andnot_wp = 1, | 4222 | mask.nxe = 1; |
4223 | .smap_andnot_wp = 1, | 4223 | mask.smep_andnot_wp = 1; |
4224 | }; | 4224 | mask.smap_andnot_wp = 1; |
4225 | 4225 | ||
4226 | /* | 4226 | /* |
4227 | * If we don't have indirect shadow pages, it means no page is | 4227 | * If we don't have indirect shadow pages, it means no page is |
diff --git a/block/blk-mq.c b/block/blk-mq.c index e68b71b85a7e..594eea04266e 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
@@ -1600,6 +1600,7 @@ static int blk_mq_hctx_notify(void *data, unsigned long action, | |||
1600 | return NOTIFY_OK; | 1600 | return NOTIFY_OK; |
1601 | } | 1601 | } |
1602 | 1602 | ||
1603 | /* hctx->ctxs will be freed in queue's release handler */ | ||
1603 | static void blk_mq_exit_hctx(struct request_queue *q, | 1604 | static void blk_mq_exit_hctx(struct request_queue *q, |
1604 | struct blk_mq_tag_set *set, | 1605 | struct blk_mq_tag_set *set, |
1605 | struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx) | 1606 | struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx) |
@@ -1618,7 +1619,6 @@ static void blk_mq_exit_hctx(struct request_queue *q, | |||
1618 | 1619 | ||
1619 | blk_mq_unregister_cpu_notifier(&hctx->cpu_notifier); | 1620 | blk_mq_unregister_cpu_notifier(&hctx->cpu_notifier); |
1620 | blk_free_flush_queue(hctx->fq); | 1621 | blk_free_flush_queue(hctx->fq); |
1621 | kfree(hctx->ctxs); | ||
1622 | blk_mq_free_bitmap(&hctx->ctx_map); | 1622 | blk_mq_free_bitmap(&hctx->ctx_map); |
1623 | } | 1623 | } |
1624 | 1624 | ||
@@ -1891,8 +1891,12 @@ void blk_mq_release(struct request_queue *q) | |||
1891 | unsigned int i; | 1891 | unsigned int i; |
1892 | 1892 | ||
1893 | /* hctx kobj stays in hctx */ | 1893 | /* hctx kobj stays in hctx */ |
1894 | queue_for_each_hw_ctx(q, hctx, i) | 1894 | queue_for_each_hw_ctx(q, hctx, i) { |
1895 | if (!hctx) | ||
1896 | continue; | ||
1897 | kfree(hctx->ctxs); | ||
1895 | kfree(hctx); | 1898 | kfree(hctx); |
1899 | } | ||
1896 | 1900 | ||
1897 | kfree(q->queue_hw_ctx); | 1901 | kfree(q->queue_hw_ctx); |
1898 | 1902 | ||
diff --git a/block/genhd.c b/block/genhd.c index 0a536dc05f3b..ea982eadaf63 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -422,9 +422,9 @@ int blk_alloc_devt(struct hd_struct *part, dev_t *devt) | |||
422 | /* allocate ext devt */ | 422 | /* allocate ext devt */ |
423 | idr_preload(GFP_KERNEL); | 423 | idr_preload(GFP_KERNEL); |
424 | 424 | ||
425 | spin_lock(&ext_devt_lock); | 425 | spin_lock_bh(&ext_devt_lock); |
426 | idx = idr_alloc(&ext_devt_idr, part, 0, NR_EXT_DEVT, GFP_NOWAIT); | 426 | idx = idr_alloc(&ext_devt_idr, part, 0, NR_EXT_DEVT, GFP_NOWAIT); |
427 | spin_unlock(&ext_devt_lock); | 427 | spin_unlock_bh(&ext_devt_lock); |
428 | 428 | ||
429 | idr_preload_end(); | 429 | idr_preload_end(); |
430 | if (idx < 0) | 430 | if (idx < 0) |
@@ -449,9 +449,9 @@ void blk_free_devt(dev_t devt) | |||
449 | return; | 449 | return; |
450 | 450 | ||
451 | if (MAJOR(devt) == BLOCK_EXT_MAJOR) { | 451 | if (MAJOR(devt) == BLOCK_EXT_MAJOR) { |
452 | spin_lock(&ext_devt_lock); | 452 | spin_lock_bh(&ext_devt_lock); |
453 | idr_remove(&ext_devt_idr, blk_mangle_minor(MINOR(devt))); | 453 | idr_remove(&ext_devt_idr, blk_mangle_minor(MINOR(devt))); |
454 | spin_unlock(&ext_devt_lock); | 454 | spin_unlock_bh(&ext_devt_lock); |
455 | } | 455 | } |
456 | } | 456 | } |
457 | 457 | ||
@@ -653,7 +653,6 @@ void del_gendisk(struct gendisk *disk) | |||
653 | disk->flags &= ~GENHD_FL_UP; | 653 | disk->flags &= ~GENHD_FL_UP; |
654 | 654 | ||
655 | sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi"); | 655 | sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi"); |
656 | bdi_unregister(&disk->queue->backing_dev_info); | ||
657 | blk_unregister_queue(disk); | 656 | blk_unregister_queue(disk); |
658 | blk_unregister_region(disk_devt(disk), disk->minors); | 657 | blk_unregister_region(disk_devt(disk), disk->minors); |
659 | 658 | ||
@@ -691,13 +690,13 @@ struct gendisk *get_gendisk(dev_t devt, int *partno) | |||
691 | } else { | 690 | } else { |
692 | struct hd_struct *part; | 691 | struct hd_struct *part; |
693 | 692 | ||
694 | spin_lock(&ext_devt_lock); | 693 | spin_lock_bh(&ext_devt_lock); |
695 | part = idr_find(&ext_devt_idr, blk_mangle_minor(MINOR(devt))); | 694 | part = idr_find(&ext_devt_idr, blk_mangle_minor(MINOR(devt))); |
696 | if (part && get_disk(part_to_disk(part))) { | 695 | if (part && get_disk(part_to_disk(part))) { |
697 | *partno = part->partno; | 696 | *partno = part->partno; |
698 | disk = part_to_disk(part); | 697 | disk = part_to_disk(part); |
699 | } | 698 | } |
700 | spin_unlock(&ext_devt_lock); | 699 | spin_unlock_bh(&ext_devt_lock); |
701 | } | 700 | } |
702 | 701 | ||
703 | return disk; | 702 | return disk; |
diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c index 23716dd8a7ec..5928d0746a27 100644 --- a/drivers/ata/ahci_mvebu.c +++ b/drivers/ata/ahci_mvebu.c | |||
@@ -45,7 +45,7 @@ static void ahci_mvebu_mbus_config(struct ahci_host_priv *hpriv, | |||
45 | writel((cs->mbus_attr << 8) | | 45 | writel((cs->mbus_attr << 8) | |
46 | (dram->mbus_dram_target_id << 4) | 1, | 46 | (dram->mbus_dram_target_id << 4) | 1, |
47 | hpriv->mmio + AHCI_WINDOW_CTRL(i)); | 47 | hpriv->mmio + AHCI_WINDOW_CTRL(i)); |
48 | writel(cs->base, hpriv->mmio + AHCI_WINDOW_BASE(i)); | 48 | writel(cs->base >> 16, hpriv->mmio + AHCI_WINDOW_BASE(i)); |
49 | writel(((cs->size - 1) & 0xffff0000), | 49 | writel(((cs->size - 1) & 0xffff0000), |
50 | hpriv->mmio + AHCI_WINDOW_SIZE(i)); | 50 | hpriv->mmio + AHCI_WINDOW_SIZE(i)); |
51 | } | 51 | } |
diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index 80a80548ad0a..27245957eee3 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c | |||
@@ -1053,7 +1053,7 @@ static struct of_device_id octeon_cf_match[] = { | |||
1053 | }, | 1053 | }, |
1054 | {}, | 1054 | {}, |
1055 | }; | 1055 | }; |
1056 | MODULE_DEVICE_TABLE(of, octeon_i2c_match); | 1056 | MODULE_DEVICE_TABLE(of, octeon_cf_match); |
1057 | 1057 | ||
1058 | static struct platform_driver octeon_cf_driver = { | 1058 | static struct platform_driver octeon_cf_driver = { |
1059 | .probe = octeon_cf_probe, | 1059 | .probe = octeon_cf_probe, |
diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index 9c2ba1c97c42..df0c66cb7ad3 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c | |||
@@ -179,7 +179,7 @@ static int detect_cache_attributes(unsigned int cpu) | |||
179 | { | 179 | { |
180 | int ret; | 180 | int ret; |
181 | 181 | ||
182 | if (init_cache_level(cpu)) | 182 | if (init_cache_level(cpu) || !cache_leaves(cpu)) |
183 | return -ENOENT; | 183 | return -ENOENT; |
184 | 184 | ||
185 | per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu), | 185 | per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu), |
diff --git a/drivers/base/init.c b/drivers/base/init.c index da033d3bab3c..48c0e220acc0 100644 --- a/drivers/base/init.c +++ b/drivers/base/init.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/device.h> | 8 | #include <linux/device.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/memory.h> | 10 | #include <linux/memory.h> |
11 | #include <linux/of.h> | ||
11 | 12 | ||
12 | #include "base.h" | 13 | #include "base.h" |
13 | 14 | ||
@@ -34,4 +35,5 @@ void __init driver_init(void) | |||
34 | cpu_dev_init(); | 35 | cpu_dev_init(); |
35 | memory_dev_init(); | 36 | memory_dev_init(); |
36 | container_dev_init(); | 37 | container_dev_init(); |
38 | of_core_init(); | ||
37 | } | 39 | } |
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index eb1fed5bd516..3ccef9eba6f9 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
@@ -406,6 +406,7 @@ config BLK_DEV_RAM_DAX | |||
406 | 406 | ||
407 | config BLK_DEV_PMEM | 407 | config BLK_DEV_PMEM |
408 | tristate "Persistent memory block device support" | 408 | tristate "Persistent memory block device support" |
409 | depends on HAS_IOMEM | ||
409 | help | 410 | help |
410 | Saying Y here will allow you to use a contiguous range of reserved | 411 | Saying Y here will allow you to use a contiguous range of reserved |
411 | memory as one or more persistent block devices. | 412 | memory as one or more persistent block devices. |
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 85b8036deaa3..683dff272562 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c | |||
@@ -1750,6 +1750,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) | |||
1750 | struct nvme_iod *iod; | 1750 | struct nvme_iod *iod; |
1751 | dma_addr_t meta_dma = 0; | 1751 | dma_addr_t meta_dma = 0; |
1752 | void *meta = NULL; | 1752 | void *meta = NULL; |
1753 | void __user *metadata; | ||
1753 | 1754 | ||
1754 | if (copy_from_user(&io, uio, sizeof(io))) | 1755 | if (copy_from_user(&io, uio, sizeof(io))) |
1755 | return -EFAULT; | 1756 | return -EFAULT; |
@@ -1763,6 +1764,8 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) | |||
1763 | meta_len = 0; | 1764 | meta_len = 0; |
1764 | } | 1765 | } |
1765 | 1766 | ||
1767 | metadata = (void __user *)(unsigned long)io.metadata; | ||
1768 | |||
1766 | write = io.opcode & 1; | 1769 | write = io.opcode & 1; |
1767 | 1770 | ||
1768 | switch (io.opcode) { | 1771 | switch (io.opcode) { |
@@ -1786,13 +1789,13 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) | |||
1786 | if (meta_len) { | 1789 | if (meta_len) { |
1787 | meta = dma_alloc_coherent(&dev->pci_dev->dev, meta_len, | 1790 | meta = dma_alloc_coherent(&dev->pci_dev->dev, meta_len, |
1788 | &meta_dma, GFP_KERNEL); | 1791 | &meta_dma, GFP_KERNEL); |
1792 | |||
1789 | if (!meta) { | 1793 | if (!meta) { |
1790 | status = -ENOMEM; | 1794 | status = -ENOMEM; |
1791 | goto unmap; | 1795 | goto unmap; |
1792 | } | 1796 | } |
1793 | if (write) { | 1797 | if (write) { |
1794 | if (copy_from_user(meta, (void __user *)io.metadata, | 1798 | if (copy_from_user(meta, metadata, meta_len)) { |
1795 | meta_len)) { | ||
1796 | status = -EFAULT; | 1799 | status = -EFAULT; |
1797 | goto unmap; | 1800 | goto unmap; |
1798 | } | 1801 | } |
@@ -1819,8 +1822,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) | |||
1819 | nvme_free_iod(dev, iod); | 1822 | nvme_free_iod(dev, iod); |
1820 | if (meta) { | 1823 | if (meta) { |
1821 | if (status == NVME_SC_SUCCESS && !write) { | 1824 | if (status == NVME_SC_SUCCESS && !write) { |
1822 | if (copy_to_user((void __user *)io.metadata, meta, | 1825 | if (copy_to_user(metadata, meta, meta_len)) |
1823 | meta_len)) | ||
1824 | status = -EFAULT; | 1826 | status = -EFAULT; |
1825 | } | 1827 | } |
1826 | dma_free_coherent(&dev->pci_dev->dev, meta_len, meta, meta_dma); | 1828 | dma_free_coherent(&dev->pci_dev->dev, meta_len, meta, meta_dma); |
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 8dcbced0eafd..6e134f4759c0 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c | |||
@@ -805,7 +805,9 @@ static void zram_reset_device(struct zram *zram) | |||
805 | memset(&zram->stats, 0, sizeof(zram->stats)); | 805 | memset(&zram->stats, 0, sizeof(zram->stats)); |
806 | zram->disksize = 0; | 806 | zram->disksize = 0; |
807 | zram->max_comp_streams = 1; | 807 | zram->max_comp_streams = 1; |
808 | |||
808 | set_capacity(zram->disk, 0); | 809 | set_capacity(zram->disk, 0); |
810 | part_stat_set_all(&zram->disk->part0, 0); | ||
809 | 811 | ||
810 | up_write(&zram->init_lock); | 812 | up_write(&zram->init_lock); |
811 | /* I/O operation under all of CPU are done so let's free */ | 813 | /* I/O operation under all of CPU are done so let's free */ |
diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index fb9ec6221730..6f047dcb94c2 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c | |||
@@ -58,7 +58,6 @@ | |||
58 | #include <linux/debugfs.h> | 58 | #include <linux/debugfs.h> |
59 | #include <linux/log2.h> | 59 | #include <linux/log2.h> |
60 | #include <linux/syscore_ops.h> | 60 | #include <linux/syscore_ops.h> |
61 | #include <linux/memblock.h> | ||
62 | 61 | ||
63 | /* | 62 | /* |
64 | * DDR target is the same on all platforms. | 63 | * DDR target is the same on all platforms. |
@@ -70,6 +69,7 @@ | |||
70 | */ | 69 | */ |
71 | #define WIN_CTRL_OFF 0x0000 | 70 | #define WIN_CTRL_OFF 0x0000 |
72 | #define WIN_CTRL_ENABLE BIT(0) | 71 | #define WIN_CTRL_ENABLE BIT(0) |
72 | /* Only on HW I/O coherency capable platforms */ | ||
73 | #define WIN_CTRL_SYNCBARRIER BIT(1) | 73 | #define WIN_CTRL_SYNCBARRIER BIT(1) |
74 | #define WIN_CTRL_TGT_MASK 0xf0 | 74 | #define WIN_CTRL_TGT_MASK 0xf0 |
75 | #define WIN_CTRL_TGT_SHIFT 4 | 75 | #define WIN_CTRL_TGT_SHIFT 4 |
@@ -102,9 +102,7 @@ | |||
102 | 102 | ||
103 | /* Relative to mbusbridge_base */ | 103 | /* Relative to mbusbridge_base */ |
104 | #define MBUS_BRIDGE_CTRL_OFF 0x0 | 104 | #define MBUS_BRIDGE_CTRL_OFF 0x0 |
105 | #define MBUS_BRIDGE_SIZE_MASK 0xffff0000 | ||
106 | #define MBUS_BRIDGE_BASE_OFF 0x4 | 105 | #define MBUS_BRIDGE_BASE_OFF 0x4 |
107 | #define MBUS_BRIDGE_BASE_MASK 0xffff0000 | ||
108 | 106 | ||
109 | /* Maximum number of windows, for all known platforms */ | 107 | /* Maximum number of windows, for all known platforms */ |
110 | #define MBUS_WINS_MAX 20 | 108 | #define MBUS_WINS_MAX 20 |
@@ -323,8 +321,9 @@ static int mvebu_mbus_setup_window(struct mvebu_mbus_state *mbus, | |||
323 | ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) | | 321 | ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) | |
324 | (attr << WIN_CTRL_ATTR_SHIFT) | | 322 | (attr << WIN_CTRL_ATTR_SHIFT) | |
325 | (target << WIN_CTRL_TGT_SHIFT) | | 323 | (target << WIN_CTRL_TGT_SHIFT) | |
326 | WIN_CTRL_SYNCBARRIER | | ||
327 | WIN_CTRL_ENABLE; | 324 | WIN_CTRL_ENABLE; |
325 | if (mbus->hw_io_coherency) | ||
326 | ctrl |= WIN_CTRL_SYNCBARRIER; | ||
328 | 327 | ||
329 | writel(base & WIN_BASE_LOW, addr + WIN_BASE_OFF); | 328 | writel(base & WIN_BASE_LOW, addr + WIN_BASE_OFF); |
330 | writel(ctrl, addr + WIN_CTRL_OFF); | 329 | writel(ctrl, addr + WIN_CTRL_OFF); |
@@ -577,106 +576,36 @@ static unsigned int armada_xp_mbus_win_remap_offset(int win) | |||
577 | return MVEBU_MBUS_NO_REMAP; | 576 | return MVEBU_MBUS_NO_REMAP; |
578 | } | 577 | } |
579 | 578 | ||
580 | /* | ||
581 | * Use the memblock information to find the MBus bridge hole in the | ||
582 | * physical address space. | ||
583 | */ | ||
584 | static void __init | ||
585 | mvebu_mbus_find_bridge_hole(uint64_t *start, uint64_t *end) | ||
586 | { | ||
587 | struct memblock_region *r; | ||
588 | uint64_t s = 0; | ||
589 | |||
590 | for_each_memblock(memory, r) { | ||
591 | /* | ||
592 | * This part of the memory is above 4 GB, so we don't | ||
593 | * care for the MBus bridge hole. | ||
594 | */ | ||
595 | if (r->base >= 0x100000000) | ||
596 | continue; | ||
597 | |||
598 | /* | ||
599 | * The MBus bridge hole is at the end of the RAM under | ||
600 | * the 4 GB limit. | ||
601 | */ | ||
602 | if (r->base + r->size > s) | ||
603 | s = r->base + r->size; | ||
604 | } | ||
605 | |||
606 | *start = s; | ||
607 | *end = 0x100000000; | ||
608 | } | ||
609 | |||
610 | static void __init | 579 | static void __init |
611 | mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus) | 580 | mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus) |
612 | { | 581 | { |
613 | int i; | 582 | int i; |
614 | int cs; | 583 | int cs; |
615 | uint64_t mbus_bridge_base, mbus_bridge_end; | ||
616 | 584 | ||
617 | mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; | 585 | mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; |
618 | 586 | ||
619 | mvebu_mbus_find_bridge_hole(&mbus_bridge_base, &mbus_bridge_end); | ||
620 | |||
621 | for (i = 0, cs = 0; i < 4; i++) { | 587 | for (i = 0, cs = 0; i < 4; i++) { |
622 | u64 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i)); | 588 | u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i)); |
623 | u64 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i)); | 589 | u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i)); |
624 | u64 end; | ||
625 | struct mbus_dram_window *w; | ||
626 | |||
627 | /* Ignore entries that are not enabled */ | ||
628 | if (!(size & DDR_SIZE_ENABLED)) | ||
629 | continue; | ||
630 | |||
631 | /* | ||
632 | * Ignore entries whose base address is above 2^32, | ||
633 | * since devices cannot DMA to such high addresses | ||
634 | */ | ||
635 | if (base & DDR_BASE_CS_HIGH_MASK) | ||
636 | continue; | ||
637 | |||
638 | base = base & DDR_BASE_CS_LOW_MASK; | ||
639 | size = (size | ~DDR_SIZE_MASK) + 1; | ||
640 | end = base + size; | ||
641 | |||
642 | /* | ||
643 | * Adjust base/size of the current CS to make sure it | ||
644 | * doesn't overlap with the MBus bridge hole. This is | ||
645 | * particularly important for devices that do DMA from | ||
646 | * DRAM to a SRAM mapped in a MBus window, such as the | ||
647 | * CESA cryptographic engine. | ||
648 | */ | ||
649 | 590 | ||
650 | /* | 591 | /* |
651 | * The CS is fully enclosed inside the MBus bridge | 592 | * We only take care of entries for which the chip |
652 | * area, so ignore it. | 593 | * select is enabled, and that don't have high base |
594 | * address bits set (devices can only access the first | ||
595 | * 32 bits of the memory). | ||
653 | */ | 596 | */ |
654 | if (base >= mbus_bridge_base && end <= mbus_bridge_end) | 597 | if ((size & DDR_SIZE_ENABLED) && |
655 | continue; | 598 | !(base & DDR_BASE_CS_HIGH_MASK)) { |
599 | struct mbus_dram_window *w; | ||
656 | 600 | ||
657 | /* | 601 | w = &mvebu_mbus_dram_info.cs[cs++]; |
658 | * Beginning of CS overlaps with end of MBus, raise CS | 602 | w->cs_index = i; |
659 | * base address, and shrink its size. | 603 | w->mbus_attr = 0xf & ~(1 << i); |
660 | */ | 604 | if (mbus->hw_io_coherency) |
661 | if (base >= mbus_bridge_base && end > mbus_bridge_end) { | 605 | w->mbus_attr |= ATTR_HW_COHERENCY; |
662 | size -= mbus_bridge_end - base; | 606 | w->base = base & DDR_BASE_CS_LOW_MASK; |
663 | base = mbus_bridge_end; | 607 | w->size = (size | ~DDR_SIZE_MASK) + 1; |
664 | } | 608 | } |
665 | |||
666 | /* | ||
667 | * End of CS overlaps with beginning of MBus, shrink | ||
668 | * CS size. | ||
669 | */ | ||
670 | if (base < mbus_bridge_base && end > mbus_bridge_base) | ||
671 | size -= end - mbus_bridge_base; | ||
672 | |||
673 | w = &mvebu_mbus_dram_info.cs[cs++]; | ||
674 | w->cs_index = i; | ||
675 | w->mbus_attr = 0xf & ~(1 << i); | ||
676 | if (mbus->hw_io_coherency) | ||
677 | w->mbus_attr |= ATTR_HW_COHERENCY; | ||
678 | w->base = base; | ||
679 | w->size = size; | ||
680 | } | 609 | } |
681 | mvebu_mbus_dram_info.num_cs = cs; | 610 | mvebu_mbus_dram_info.num_cs = cs; |
682 | } | 611 | } |
diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index 933e4b338459..7992164ea9ec 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c | |||
@@ -174,6 +174,8 @@ | |||
174 | #define AT_XDMAC_MBR_UBC_NDV3 (0x3 << 27) /* Next Descriptor View 3 */ | 174 | #define AT_XDMAC_MBR_UBC_NDV3 (0x3 << 27) /* Next Descriptor View 3 */ |
175 | 175 | ||
176 | #define AT_XDMAC_MAX_CHAN 0x20 | 176 | #define AT_XDMAC_MAX_CHAN 0x20 |
177 | #define AT_XDMAC_MAX_CSIZE 16 /* 16 data */ | ||
178 | #define AT_XDMAC_MAX_DWIDTH 8 /* 64 bits */ | ||
177 | 179 | ||
178 | #define AT_XDMAC_DMA_BUSWIDTHS\ | 180 | #define AT_XDMAC_DMA_BUSWIDTHS\ |
179 | (BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) |\ | 181 | (BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) |\ |
@@ -192,20 +194,17 @@ struct at_xdmac_chan { | |||
192 | struct dma_chan chan; | 194 | struct dma_chan chan; |
193 | void __iomem *ch_regs; | 195 | void __iomem *ch_regs; |
194 | u32 mask; /* Channel Mask */ | 196 | u32 mask; /* Channel Mask */ |
195 | u32 cfg[2]; /* Channel Configuration Register */ | 197 | u32 cfg; /* Channel Configuration Register */ |
196 | #define AT_XDMAC_DEV_TO_MEM_CFG 0 /* Predifined dev to mem channel conf */ | ||
197 | #define AT_XDMAC_MEM_TO_DEV_CFG 1 /* Predifined mem to dev channel conf */ | ||
198 | u8 perid; /* Peripheral ID */ | 198 | u8 perid; /* Peripheral ID */ |
199 | u8 perif; /* Peripheral Interface */ | 199 | u8 perif; /* Peripheral Interface */ |
200 | u8 memif; /* Memory Interface */ | 200 | u8 memif; /* Memory Interface */ |
201 | u32 per_src_addr; | ||
202 | u32 per_dst_addr; | ||
203 | u32 save_cc; | 201 | u32 save_cc; |
204 | u32 save_cim; | 202 | u32 save_cim; |
205 | u32 save_cnda; | 203 | u32 save_cnda; |
206 | u32 save_cndc; | 204 | u32 save_cndc; |
207 | unsigned long status; | 205 | unsigned long status; |
208 | struct tasklet_struct tasklet; | 206 | struct tasklet_struct tasklet; |
207 | struct dma_slave_config sconfig; | ||
209 | 208 | ||
210 | spinlock_t lock; | 209 | spinlock_t lock; |
211 | 210 | ||
@@ -415,8 +414,9 @@ static dma_cookie_t at_xdmac_tx_submit(struct dma_async_tx_descriptor *tx) | |||
415 | struct at_xdmac_desc *desc = txd_to_at_desc(tx); | 414 | struct at_xdmac_desc *desc = txd_to_at_desc(tx); |
416 | struct at_xdmac_chan *atchan = to_at_xdmac_chan(tx->chan); | 415 | struct at_xdmac_chan *atchan = to_at_xdmac_chan(tx->chan); |
417 | dma_cookie_t cookie; | 416 | dma_cookie_t cookie; |
417 | unsigned long irqflags; | ||
418 | 418 | ||
419 | spin_lock_bh(&atchan->lock); | 419 | spin_lock_irqsave(&atchan->lock, irqflags); |
420 | cookie = dma_cookie_assign(tx); | 420 | cookie = dma_cookie_assign(tx); |
421 | 421 | ||
422 | dev_vdbg(chan2dev(tx->chan), "%s: atchan 0x%p, add desc 0x%p to xfers_list\n", | 422 | dev_vdbg(chan2dev(tx->chan), "%s: atchan 0x%p, add desc 0x%p to xfers_list\n", |
@@ -425,7 +425,7 @@ static dma_cookie_t at_xdmac_tx_submit(struct dma_async_tx_descriptor *tx) | |||
425 | if (list_is_singular(&atchan->xfers_list)) | 425 | if (list_is_singular(&atchan->xfers_list)) |
426 | at_xdmac_start_xfer(atchan, desc); | 426 | at_xdmac_start_xfer(atchan, desc); |
427 | 427 | ||
428 | spin_unlock_bh(&atchan->lock); | 428 | spin_unlock_irqrestore(&atchan->lock, irqflags); |
429 | return cookie; | 429 | return cookie; |
430 | } | 430 | } |
431 | 431 | ||
@@ -494,61 +494,94 @@ static struct dma_chan *at_xdmac_xlate(struct of_phandle_args *dma_spec, | |||
494 | return chan; | 494 | return chan; |
495 | } | 495 | } |
496 | 496 | ||
497 | static int at_xdmac_compute_chan_conf(struct dma_chan *chan, | ||
498 | enum dma_transfer_direction direction) | ||
499 | { | ||
500 | struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); | ||
501 | int csize, dwidth; | ||
502 | |||
503 | if (direction == DMA_DEV_TO_MEM) { | ||
504 | atchan->cfg = | ||
505 | AT91_XDMAC_DT_PERID(atchan->perid) | ||
506 | | AT_XDMAC_CC_DAM_INCREMENTED_AM | ||
507 | | AT_XDMAC_CC_SAM_FIXED_AM | ||
508 | | AT_XDMAC_CC_DIF(atchan->memif) | ||
509 | | AT_XDMAC_CC_SIF(atchan->perif) | ||
510 | | AT_XDMAC_CC_SWREQ_HWR_CONNECTED | ||
511 | | AT_XDMAC_CC_DSYNC_PER2MEM | ||
512 | | AT_XDMAC_CC_MBSIZE_SIXTEEN | ||
513 | | AT_XDMAC_CC_TYPE_PER_TRAN; | ||
514 | csize = ffs(atchan->sconfig.src_maxburst) - 1; | ||
515 | if (csize < 0) { | ||
516 | dev_err(chan2dev(chan), "invalid src maxburst value\n"); | ||
517 | return -EINVAL; | ||
518 | } | ||
519 | atchan->cfg |= AT_XDMAC_CC_CSIZE(csize); | ||
520 | dwidth = ffs(atchan->sconfig.src_addr_width) - 1; | ||
521 | if (dwidth < 0) { | ||
522 | dev_err(chan2dev(chan), "invalid src addr width value\n"); | ||
523 | return -EINVAL; | ||
524 | } | ||
525 | atchan->cfg |= AT_XDMAC_CC_DWIDTH(dwidth); | ||
526 | } else if (direction == DMA_MEM_TO_DEV) { | ||
527 | atchan->cfg = | ||
528 | AT91_XDMAC_DT_PERID(atchan->perid) | ||
529 | | AT_XDMAC_CC_DAM_FIXED_AM | ||
530 | | AT_XDMAC_CC_SAM_INCREMENTED_AM | ||
531 | | AT_XDMAC_CC_DIF(atchan->perif) | ||
532 | | AT_XDMAC_CC_SIF(atchan->memif) | ||
533 | | AT_XDMAC_CC_SWREQ_HWR_CONNECTED | ||
534 | | AT_XDMAC_CC_DSYNC_MEM2PER | ||
535 | | AT_XDMAC_CC_MBSIZE_SIXTEEN | ||
536 | | AT_XDMAC_CC_TYPE_PER_TRAN; | ||
537 | csize = ffs(atchan->sconfig.dst_maxburst) - 1; | ||
538 | if (csize < 0) { | ||
539 | dev_err(chan2dev(chan), "invalid src maxburst value\n"); | ||
540 | return -EINVAL; | ||
541 | } | ||
542 | atchan->cfg |= AT_XDMAC_CC_CSIZE(csize); | ||
543 | dwidth = ffs(atchan->sconfig.dst_addr_width) - 1; | ||
544 | if (dwidth < 0) { | ||
545 | dev_err(chan2dev(chan), "invalid dst addr width value\n"); | ||
546 | return -EINVAL; | ||
547 | } | ||
548 | atchan->cfg |= AT_XDMAC_CC_DWIDTH(dwidth); | ||
549 | } | ||
550 | |||
551 | dev_dbg(chan2dev(chan), "%s: cfg=0x%08x\n", __func__, atchan->cfg); | ||
552 | |||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | /* | ||
557 | * Only check that maxburst and addr width values are supported by the | ||
558 | * the controller but not that the configuration is good to perform the | ||
559 | * transfer since we don't know the direction at this stage. | ||
560 | */ | ||
561 | static int at_xdmac_check_slave_config(struct dma_slave_config *sconfig) | ||
562 | { | ||
563 | if ((sconfig->src_maxburst > AT_XDMAC_MAX_CSIZE) | ||
564 | || (sconfig->dst_maxburst > AT_XDMAC_MAX_CSIZE)) | ||
565 | return -EINVAL; | ||
566 | |||
567 | if ((sconfig->src_addr_width > AT_XDMAC_MAX_DWIDTH) | ||
568 | || (sconfig->dst_addr_width > AT_XDMAC_MAX_DWIDTH)) | ||
569 | return -EINVAL; | ||
570 | |||
571 | return 0; | ||
572 | } | ||
573 | |||
497 | static int at_xdmac_set_slave_config(struct dma_chan *chan, | 574 | static int at_xdmac_set_slave_config(struct dma_chan *chan, |
498 | struct dma_slave_config *sconfig) | 575 | struct dma_slave_config *sconfig) |
499 | { | 576 | { |
500 | struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); | 577 | struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); |
501 | u8 dwidth; | ||
502 | int csize; | ||
503 | 578 | ||
504 | atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG] = | 579 | if (at_xdmac_check_slave_config(sconfig)) { |
505 | AT91_XDMAC_DT_PERID(atchan->perid) | 580 | dev_err(chan2dev(chan), "invalid slave configuration\n"); |
506 | | AT_XDMAC_CC_DAM_INCREMENTED_AM | ||
507 | | AT_XDMAC_CC_SAM_FIXED_AM | ||
508 | | AT_XDMAC_CC_DIF(atchan->memif) | ||
509 | | AT_XDMAC_CC_SIF(atchan->perif) | ||
510 | | AT_XDMAC_CC_SWREQ_HWR_CONNECTED | ||
511 | | AT_XDMAC_CC_DSYNC_PER2MEM | ||
512 | | AT_XDMAC_CC_MBSIZE_SIXTEEN | ||
513 | | AT_XDMAC_CC_TYPE_PER_TRAN; | ||
514 | csize = at_xdmac_csize(sconfig->src_maxburst); | ||
515 | if (csize < 0) { | ||
516 | dev_err(chan2dev(chan), "invalid src maxburst value\n"); | ||
517 | return -EINVAL; | 581 | return -EINVAL; |
518 | } | 582 | } |
519 | atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG] |= AT_XDMAC_CC_CSIZE(csize); | ||
520 | dwidth = ffs(sconfig->src_addr_width) - 1; | ||
521 | atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG] |= AT_XDMAC_CC_DWIDTH(dwidth); | ||
522 | |||
523 | |||
524 | atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG] = | ||
525 | AT91_XDMAC_DT_PERID(atchan->perid) | ||
526 | | AT_XDMAC_CC_DAM_FIXED_AM | ||
527 | | AT_XDMAC_CC_SAM_INCREMENTED_AM | ||
528 | | AT_XDMAC_CC_DIF(atchan->perif) | ||
529 | | AT_XDMAC_CC_SIF(atchan->memif) | ||
530 | | AT_XDMAC_CC_SWREQ_HWR_CONNECTED | ||
531 | | AT_XDMAC_CC_DSYNC_MEM2PER | ||
532 | | AT_XDMAC_CC_MBSIZE_SIXTEEN | ||
533 | | AT_XDMAC_CC_TYPE_PER_TRAN; | ||
534 | csize = at_xdmac_csize(sconfig->dst_maxburst); | ||
535 | if (csize < 0) { | ||
536 | dev_err(chan2dev(chan), "invalid src maxburst value\n"); | ||
537 | return -EINVAL; | ||
538 | } | ||
539 | atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG] |= AT_XDMAC_CC_CSIZE(csize); | ||
540 | dwidth = ffs(sconfig->dst_addr_width) - 1; | ||
541 | atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG] |= AT_XDMAC_CC_DWIDTH(dwidth); | ||
542 | |||
543 | /* Src and dst addr are needed to configure the link list descriptor. */ | ||
544 | atchan->per_src_addr = sconfig->src_addr; | ||
545 | atchan->per_dst_addr = sconfig->dst_addr; | ||
546 | 583 | ||
547 | dev_dbg(chan2dev(chan), | 584 | memcpy(&atchan->sconfig, sconfig, sizeof(atchan->sconfig)); |
548 | "%s: cfg[dev2mem]=0x%08x, cfg[mem2dev]=0x%08x, per_src_addr=0x%08x, per_dst_addr=0x%08x\n", | ||
549 | __func__, atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG], | ||
550 | atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG], | ||
551 | atchan->per_src_addr, atchan->per_dst_addr); | ||
552 | 585 | ||
553 | return 0; | 586 | return 0; |
554 | } | 587 | } |
@@ -563,6 +596,8 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
563 | struct scatterlist *sg; | 596 | struct scatterlist *sg; |
564 | int i; | 597 | int i; |
565 | unsigned int xfer_size = 0; | 598 | unsigned int xfer_size = 0; |
599 | unsigned long irqflags; | ||
600 | struct dma_async_tx_descriptor *ret = NULL; | ||
566 | 601 | ||
567 | if (!sgl) | 602 | if (!sgl) |
568 | return NULL; | 603 | return NULL; |
@@ -578,7 +613,10 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
578 | flags); | 613 | flags); |
579 | 614 | ||
580 | /* Protect dma_sconfig field that can be modified by set_slave_conf. */ | 615 | /* Protect dma_sconfig field that can be modified by set_slave_conf. */ |
581 | spin_lock_bh(&atchan->lock); | 616 | spin_lock_irqsave(&atchan->lock, irqflags); |
617 | |||
618 | if (at_xdmac_compute_chan_conf(chan, direction)) | ||
619 | goto spin_unlock; | ||
582 | 620 | ||
583 | /* Prepare descriptors. */ | 621 | /* Prepare descriptors. */ |
584 | for_each_sg(sgl, sg, sg_len, i) { | 622 | for_each_sg(sgl, sg, sg_len, i) { |
@@ -589,8 +627,7 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
589 | mem = sg_dma_address(sg); | 627 | mem = sg_dma_address(sg); |
590 | if (unlikely(!len)) { | 628 | if (unlikely(!len)) { |
591 | dev_err(chan2dev(chan), "sg data length is zero\n"); | 629 | dev_err(chan2dev(chan), "sg data length is zero\n"); |
592 | spin_unlock_bh(&atchan->lock); | 630 | goto spin_unlock; |
593 | return NULL; | ||
594 | } | 631 | } |
595 | dev_dbg(chan2dev(chan), "%s: * sg%d len=%u, mem=0x%08x\n", | 632 | dev_dbg(chan2dev(chan), "%s: * sg%d len=%u, mem=0x%08x\n", |
596 | __func__, i, len, mem); | 633 | __func__, i, len, mem); |
@@ -600,20 +637,18 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
600 | dev_err(chan2dev(chan), "can't get descriptor\n"); | 637 | dev_err(chan2dev(chan), "can't get descriptor\n"); |
601 | if (first) | 638 | if (first) |
602 | list_splice_init(&first->descs_list, &atchan->free_descs_list); | 639 | list_splice_init(&first->descs_list, &atchan->free_descs_list); |
603 | spin_unlock_bh(&atchan->lock); | 640 | goto spin_unlock; |
604 | return NULL; | ||
605 | } | 641 | } |
606 | 642 | ||
607 | /* Linked list descriptor setup. */ | 643 | /* Linked list descriptor setup. */ |
608 | if (direction == DMA_DEV_TO_MEM) { | 644 | if (direction == DMA_DEV_TO_MEM) { |
609 | desc->lld.mbr_sa = atchan->per_src_addr; | 645 | desc->lld.mbr_sa = atchan->sconfig.src_addr; |
610 | desc->lld.mbr_da = mem; | 646 | desc->lld.mbr_da = mem; |
611 | desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG]; | ||
612 | } else { | 647 | } else { |
613 | desc->lld.mbr_sa = mem; | 648 | desc->lld.mbr_sa = mem; |
614 | desc->lld.mbr_da = atchan->per_dst_addr; | 649 | desc->lld.mbr_da = atchan->sconfig.dst_addr; |
615 | desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG]; | ||
616 | } | 650 | } |
651 | desc->lld.mbr_cfg = atchan->cfg; | ||
617 | dwidth = at_xdmac_get_dwidth(desc->lld.mbr_cfg); | 652 | dwidth = at_xdmac_get_dwidth(desc->lld.mbr_cfg); |
618 | fixed_dwidth = IS_ALIGNED(len, 1 << dwidth) | 653 | fixed_dwidth = IS_ALIGNED(len, 1 << dwidth) |
619 | ? at_xdmac_get_dwidth(desc->lld.mbr_cfg) | 654 | ? at_xdmac_get_dwidth(desc->lld.mbr_cfg) |
@@ -645,13 +680,15 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
645 | xfer_size += len; | 680 | xfer_size += len; |
646 | } | 681 | } |
647 | 682 | ||
648 | spin_unlock_bh(&atchan->lock); | ||
649 | 683 | ||
650 | first->tx_dma_desc.flags = flags; | 684 | first->tx_dma_desc.flags = flags; |
651 | first->xfer_size = xfer_size; | 685 | first->xfer_size = xfer_size; |
652 | first->direction = direction; | 686 | first->direction = direction; |
687 | ret = &first->tx_dma_desc; | ||
653 | 688 | ||
654 | return &first->tx_dma_desc; | 689 | spin_unlock: |
690 | spin_unlock_irqrestore(&atchan->lock, irqflags); | ||
691 | return ret; | ||
655 | } | 692 | } |
656 | 693 | ||
657 | static struct dma_async_tx_descriptor * | 694 | static struct dma_async_tx_descriptor * |
@@ -664,6 +701,7 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, | |||
664 | struct at_xdmac_desc *first = NULL, *prev = NULL; | 701 | struct at_xdmac_desc *first = NULL, *prev = NULL; |
665 | unsigned int periods = buf_len / period_len; | 702 | unsigned int periods = buf_len / period_len; |
666 | int i; | 703 | int i; |
704 | unsigned long irqflags; | ||
667 | 705 | ||
668 | dev_dbg(chan2dev(chan), "%s: buf_addr=%pad, buf_len=%zd, period_len=%zd, dir=%s, flags=0x%lx\n", | 706 | dev_dbg(chan2dev(chan), "%s: buf_addr=%pad, buf_len=%zd, period_len=%zd, dir=%s, flags=0x%lx\n", |
669 | __func__, &buf_addr, buf_len, period_len, | 707 | __func__, &buf_addr, buf_len, period_len, |
@@ -679,32 +717,34 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, | |||
679 | return NULL; | 717 | return NULL; |
680 | } | 718 | } |
681 | 719 | ||
720 | if (at_xdmac_compute_chan_conf(chan, direction)) | ||
721 | return NULL; | ||
722 | |||
682 | for (i = 0; i < periods; i++) { | 723 | for (i = 0; i < periods; i++) { |
683 | struct at_xdmac_desc *desc = NULL; | 724 | struct at_xdmac_desc *desc = NULL; |
684 | 725 | ||
685 | spin_lock_bh(&atchan->lock); | 726 | spin_lock_irqsave(&atchan->lock, irqflags); |
686 | desc = at_xdmac_get_desc(atchan); | 727 | desc = at_xdmac_get_desc(atchan); |
687 | if (!desc) { | 728 | if (!desc) { |
688 | dev_err(chan2dev(chan), "can't get descriptor\n"); | 729 | dev_err(chan2dev(chan), "can't get descriptor\n"); |
689 | if (first) | 730 | if (first) |
690 | list_splice_init(&first->descs_list, &atchan->free_descs_list); | 731 | list_splice_init(&first->descs_list, &atchan->free_descs_list); |
691 | spin_unlock_bh(&atchan->lock); | 732 | spin_unlock_irqrestore(&atchan->lock, irqflags); |
692 | return NULL; | 733 | return NULL; |
693 | } | 734 | } |
694 | spin_unlock_bh(&atchan->lock); | 735 | spin_unlock_irqrestore(&atchan->lock, irqflags); |
695 | dev_dbg(chan2dev(chan), | 736 | dev_dbg(chan2dev(chan), |
696 | "%s: desc=0x%p, tx_dma_desc.phys=%pad\n", | 737 | "%s: desc=0x%p, tx_dma_desc.phys=%pad\n", |
697 | __func__, desc, &desc->tx_dma_desc.phys); | 738 | __func__, desc, &desc->tx_dma_desc.phys); |
698 | 739 | ||
699 | if (direction == DMA_DEV_TO_MEM) { | 740 | if (direction == DMA_DEV_TO_MEM) { |
700 | desc->lld.mbr_sa = atchan->per_src_addr; | 741 | desc->lld.mbr_sa = atchan->sconfig.src_addr; |
701 | desc->lld.mbr_da = buf_addr + i * period_len; | 742 | desc->lld.mbr_da = buf_addr + i * period_len; |
702 | desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG]; | ||
703 | } else { | 743 | } else { |
704 | desc->lld.mbr_sa = buf_addr + i * period_len; | 744 | desc->lld.mbr_sa = buf_addr + i * period_len; |
705 | desc->lld.mbr_da = atchan->per_dst_addr; | 745 | desc->lld.mbr_da = atchan->sconfig.dst_addr; |
706 | desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG]; | ||
707 | } | 746 | } |
747 | desc->lld.mbr_cfg = atchan->cfg; | ||
708 | desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV1 | 748 | desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV1 |
709 | | AT_XDMAC_MBR_UBC_NDEN | 749 | | AT_XDMAC_MBR_UBC_NDEN |
710 | | AT_XDMAC_MBR_UBC_NSEN | 750 | | AT_XDMAC_MBR_UBC_NSEN |
@@ -766,6 +806,7 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | |||
766 | | AT_XDMAC_CC_SIF(0) | 806 | | AT_XDMAC_CC_SIF(0) |
767 | | AT_XDMAC_CC_MBSIZE_SIXTEEN | 807 | | AT_XDMAC_CC_MBSIZE_SIXTEEN |
768 | | AT_XDMAC_CC_TYPE_MEM_TRAN; | 808 | | AT_XDMAC_CC_TYPE_MEM_TRAN; |
809 | unsigned long irqflags; | ||
769 | 810 | ||
770 | dev_dbg(chan2dev(chan), "%s: src=%pad, dest=%pad, len=%zd, flags=0x%lx\n", | 811 | dev_dbg(chan2dev(chan), "%s: src=%pad, dest=%pad, len=%zd, flags=0x%lx\n", |
771 | __func__, &src, &dest, len, flags); | 812 | __func__, &src, &dest, len, flags); |
@@ -798,9 +839,9 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | |||
798 | 839 | ||
799 | dev_dbg(chan2dev(chan), "%s: remaining_size=%zu\n", __func__, remaining_size); | 840 | dev_dbg(chan2dev(chan), "%s: remaining_size=%zu\n", __func__, remaining_size); |
800 | 841 | ||
801 | spin_lock_bh(&atchan->lock); | 842 | spin_lock_irqsave(&atchan->lock, irqflags); |
802 | desc = at_xdmac_get_desc(atchan); | 843 | desc = at_xdmac_get_desc(atchan); |
803 | spin_unlock_bh(&atchan->lock); | 844 | spin_unlock_irqrestore(&atchan->lock, irqflags); |
804 | if (!desc) { | 845 | if (!desc) { |
805 | dev_err(chan2dev(chan), "can't get descriptor\n"); | 846 | dev_err(chan2dev(chan), "can't get descriptor\n"); |
806 | if (first) | 847 | if (first) |
@@ -886,6 +927,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, | |||
886 | int residue; | 927 | int residue; |
887 | u32 cur_nda, mask, value; | 928 | u32 cur_nda, mask, value; |
888 | u8 dwidth = 0; | 929 | u8 dwidth = 0; |
930 | unsigned long flags; | ||
889 | 931 | ||
890 | ret = dma_cookie_status(chan, cookie, txstate); | 932 | ret = dma_cookie_status(chan, cookie, txstate); |
891 | if (ret == DMA_COMPLETE) | 933 | if (ret == DMA_COMPLETE) |
@@ -894,7 +936,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, | |||
894 | if (!txstate) | 936 | if (!txstate) |
895 | return ret; | 937 | return ret; |
896 | 938 | ||
897 | spin_lock_bh(&atchan->lock); | 939 | spin_lock_irqsave(&atchan->lock, flags); |
898 | 940 | ||
899 | desc = list_first_entry(&atchan->xfers_list, struct at_xdmac_desc, xfer_node); | 941 | desc = list_first_entry(&atchan->xfers_list, struct at_xdmac_desc, xfer_node); |
900 | 942 | ||
@@ -904,8 +946,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, | |||
904 | */ | 946 | */ |
905 | if (!desc->active_xfer) { | 947 | if (!desc->active_xfer) { |
906 | dma_set_residue(txstate, desc->xfer_size); | 948 | dma_set_residue(txstate, desc->xfer_size); |
907 | spin_unlock_bh(&atchan->lock); | 949 | goto spin_unlock; |
908 | return ret; | ||
909 | } | 950 | } |
910 | 951 | ||
911 | residue = desc->xfer_size; | 952 | residue = desc->xfer_size; |
@@ -936,14 +977,14 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, | |||
936 | } | 977 | } |
937 | residue += at_xdmac_chan_read(atchan, AT_XDMAC_CUBC) << dwidth; | 978 | residue += at_xdmac_chan_read(atchan, AT_XDMAC_CUBC) << dwidth; |
938 | 979 | ||
939 | spin_unlock_bh(&atchan->lock); | ||
940 | |||
941 | dma_set_residue(txstate, residue); | 980 | dma_set_residue(txstate, residue); |
942 | 981 | ||
943 | dev_dbg(chan2dev(chan), | 982 | dev_dbg(chan2dev(chan), |
944 | "%s: desc=0x%p, tx_dma_desc.phys=%pad, tx_status=%d, cookie=%d, residue=%d\n", | 983 | "%s: desc=0x%p, tx_dma_desc.phys=%pad, tx_status=%d, cookie=%d, residue=%d\n", |
945 | __func__, desc, &desc->tx_dma_desc.phys, ret, cookie, residue); | 984 | __func__, desc, &desc->tx_dma_desc.phys, ret, cookie, residue); |
946 | 985 | ||
986 | spin_unlock: | ||
987 | spin_unlock_irqrestore(&atchan->lock, flags); | ||
947 | return ret; | 988 | return ret; |
948 | } | 989 | } |
949 | 990 | ||
@@ -964,8 +1005,9 @@ static void at_xdmac_remove_xfer(struct at_xdmac_chan *atchan, | |||
964 | static void at_xdmac_advance_work(struct at_xdmac_chan *atchan) | 1005 | static void at_xdmac_advance_work(struct at_xdmac_chan *atchan) |
965 | { | 1006 | { |
966 | struct at_xdmac_desc *desc; | 1007 | struct at_xdmac_desc *desc; |
1008 | unsigned long flags; | ||
967 | 1009 | ||
968 | spin_lock_bh(&atchan->lock); | 1010 | spin_lock_irqsave(&atchan->lock, flags); |
969 | 1011 | ||
970 | /* | 1012 | /* |
971 | * If channel is enabled, do nothing, advance_work will be triggered | 1013 | * If channel is enabled, do nothing, advance_work will be triggered |
@@ -980,7 +1022,7 @@ static void at_xdmac_advance_work(struct at_xdmac_chan *atchan) | |||
980 | at_xdmac_start_xfer(atchan, desc); | 1022 | at_xdmac_start_xfer(atchan, desc); |
981 | } | 1023 | } |
982 | 1024 | ||
983 | spin_unlock_bh(&atchan->lock); | 1025 | spin_unlock_irqrestore(&atchan->lock, flags); |
984 | } | 1026 | } |
985 | 1027 | ||
986 | static void at_xdmac_handle_cyclic(struct at_xdmac_chan *atchan) | 1028 | static void at_xdmac_handle_cyclic(struct at_xdmac_chan *atchan) |
@@ -1116,12 +1158,13 @@ static int at_xdmac_device_config(struct dma_chan *chan, | |||
1116 | { | 1158 | { |
1117 | struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); | 1159 | struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); |
1118 | int ret; | 1160 | int ret; |
1161 | unsigned long flags; | ||
1119 | 1162 | ||
1120 | dev_dbg(chan2dev(chan), "%s\n", __func__); | 1163 | dev_dbg(chan2dev(chan), "%s\n", __func__); |
1121 | 1164 | ||
1122 | spin_lock_bh(&atchan->lock); | 1165 | spin_lock_irqsave(&atchan->lock, flags); |
1123 | ret = at_xdmac_set_slave_config(chan, config); | 1166 | ret = at_xdmac_set_slave_config(chan, config); |
1124 | spin_unlock_bh(&atchan->lock); | 1167 | spin_unlock_irqrestore(&atchan->lock, flags); |
1125 | 1168 | ||
1126 | return ret; | 1169 | return ret; |
1127 | } | 1170 | } |
@@ -1130,18 +1173,19 @@ static int at_xdmac_device_pause(struct dma_chan *chan) | |||
1130 | { | 1173 | { |
1131 | struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); | 1174 | struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); |
1132 | struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); | 1175 | struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); |
1176 | unsigned long flags; | ||
1133 | 1177 | ||
1134 | dev_dbg(chan2dev(chan), "%s\n", __func__); | 1178 | dev_dbg(chan2dev(chan), "%s\n", __func__); |
1135 | 1179 | ||
1136 | if (test_and_set_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status)) | 1180 | if (test_and_set_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status)) |
1137 | return 0; | 1181 | return 0; |
1138 | 1182 | ||
1139 | spin_lock_bh(&atchan->lock); | 1183 | spin_lock_irqsave(&atchan->lock, flags); |
1140 | at_xdmac_write(atxdmac, AT_XDMAC_GRWS, atchan->mask); | 1184 | at_xdmac_write(atxdmac, AT_XDMAC_GRWS, atchan->mask); |
1141 | while (at_xdmac_chan_read(atchan, AT_XDMAC_CC) | 1185 | while (at_xdmac_chan_read(atchan, AT_XDMAC_CC) |
1142 | & (AT_XDMAC_CC_WRIP | AT_XDMAC_CC_RDIP)) | 1186 | & (AT_XDMAC_CC_WRIP | AT_XDMAC_CC_RDIP)) |
1143 | cpu_relax(); | 1187 | cpu_relax(); |
1144 | spin_unlock_bh(&atchan->lock); | 1188 | spin_unlock_irqrestore(&atchan->lock, flags); |
1145 | 1189 | ||
1146 | return 0; | 1190 | return 0; |
1147 | } | 1191 | } |
@@ -1150,18 +1194,19 @@ static int at_xdmac_device_resume(struct dma_chan *chan) | |||
1150 | { | 1194 | { |
1151 | struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); | 1195 | struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); |
1152 | struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); | 1196 | struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); |
1197 | unsigned long flags; | ||
1153 | 1198 | ||
1154 | dev_dbg(chan2dev(chan), "%s\n", __func__); | 1199 | dev_dbg(chan2dev(chan), "%s\n", __func__); |
1155 | 1200 | ||
1156 | spin_lock_bh(&atchan->lock); | 1201 | spin_lock_irqsave(&atchan->lock, flags); |
1157 | if (!at_xdmac_chan_is_paused(atchan)) { | 1202 | if (!at_xdmac_chan_is_paused(atchan)) { |
1158 | spin_unlock_bh(&atchan->lock); | 1203 | spin_unlock_irqrestore(&atchan->lock, flags); |
1159 | return 0; | 1204 | return 0; |
1160 | } | 1205 | } |
1161 | 1206 | ||
1162 | at_xdmac_write(atxdmac, AT_XDMAC_GRWR, atchan->mask); | 1207 | at_xdmac_write(atxdmac, AT_XDMAC_GRWR, atchan->mask); |
1163 | clear_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status); | 1208 | clear_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status); |
1164 | spin_unlock_bh(&atchan->lock); | 1209 | spin_unlock_irqrestore(&atchan->lock, flags); |
1165 | 1210 | ||
1166 | return 0; | 1211 | return 0; |
1167 | } | 1212 | } |
@@ -1171,10 +1216,11 @@ static int at_xdmac_device_terminate_all(struct dma_chan *chan) | |||
1171 | struct at_xdmac_desc *desc, *_desc; | 1216 | struct at_xdmac_desc *desc, *_desc; |
1172 | struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); | 1217 | struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); |
1173 | struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); | 1218 | struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); |
1219 | unsigned long flags; | ||
1174 | 1220 | ||
1175 | dev_dbg(chan2dev(chan), "%s\n", __func__); | 1221 | dev_dbg(chan2dev(chan), "%s\n", __func__); |
1176 | 1222 | ||
1177 | spin_lock_bh(&atchan->lock); | 1223 | spin_lock_irqsave(&atchan->lock, flags); |
1178 | at_xdmac_write(atxdmac, AT_XDMAC_GD, atchan->mask); | 1224 | at_xdmac_write(atxdmac, AT_XDMAC_GD, atchan->mask); |
1179 | while (at_xdmac_read(atxdmac, AT_XDMAC_GS) & atchan->mask) | 1225 | while (at_xdmac_read(atxdmac, AT_XDMAC_GS) & atchan->mask) |
1180 | cpu_relax(); | 1226 | cpu_relax(); |
@@ -1184,7 +1230,7 @@ static int at_xdmac_device_terminate_all(struct dma_chan *chan) | |||
1184 | at_xdmac_remove_xfer(atchan, desc); | 1230 | at_xdmac_remove_xfer(atchan, desc); |
1185 | 1231 | ||
1186 | clear_bit(AT_XDMAC_CHAN_IS_CYCLIC, &atchan->status); | 1232 | clear_bit(AT_XDMAC_CHAN_IS_CYCLIC, &atchan->status); |
1187 | spin_unlock_bh(&atchan->lock); | 1233 | spin_unlock_irqrestore(&atchan->lock, flags); |
1188 | 1234 | ||
1189 | return 0; | 1235 | return 0; |
1190 | } | 1236 | } |
@@ -1194,8 +1240,9 @@ static int at_xdmac_alloc_chan_resources(struct dma_chan *chan) | |||
1194 | struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); | 1240 | struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); |
1195 | struct at_xdmac_desc *desc; | 1241 | struct at_xdmac_desc *desc; |
1196 | int i; | 1242 | int i; |
1243 | unsigned long flags; | ||
1197 | 1244 | ||
1198 | spin_lock_bh(&atchan->lock); | 1245 | spin_lock_irqsave(&atchan->lock, flags); |
1199 | 1246 | ||
1200 | if (at_xdmac_chan_is_enabled(atchan)) { | 1247 | if (at_xdmac_chan_is_enabled(atchan)) { |
1201 | dev_err(chan2dev(chan), | 1248 | dev_err(chan2dev(chan), |
@@ -1226,7 +1273,7 @@ static int at_xdmac_alloc_chan_resources(struct dma_chan *chan) | |||
1226 | dev_dbg(chan2dev(chan), "%s: allocated %d descriptors\n", __func__, i); | 1273 | dev_dbg(chan2dev(chan), "%s: allocated %d descriptors\n", __func__, i); |
1227 | 1274 | ||
1228 | spin_unlock: | 1275 | spin_unlock: |
1229 | spin_unlock_bh(&atchan->lock); | 1276 | spin_unlock_irqrestore(&atchan->lock, flags); |
1230 | return i; | 1277 | return i; |
1231 | } | 1278 | } |
1232 | 1279 | ||
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 2890d744bb1b..3ddfd1f6c23c 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -487,7 +487,11 @@ int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps) | |||
487 | caps->directions = device->directions; | 487 | caps->directions = device->directions; |
488 | caps->residue_granularity = device->residue_granularity; | 488 | caps->residue_granularity = device->residue_granularity; |
489 | 489 | ||
490 | caps->cmd_pause = !!device->device_pause; | 490 | /* |
491 | * Some devices implement only pause (e.g. to get residuum) but no | ||
492 | * resume. However cmd_pause is advertised as pause AND resume. | ||
493 | */ | ||
494 | caps->cmd_pause = !!(device->device_pause && device->device_resume); | ||
491 | caps->cmd_terminate = !!device->device_terminate_all; | 495 | caps->cmd_terminate = !!device->device_terminate_all; |
492 | 496 | ||
493 | return 0; | 497 | return 0; |
diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c index 9b84def7a353..f42f71e37e73 100644 --- a/drivers/dma/hsu/hsu.c +++ b/drivers/dma/hsu/hsu.c | |||
@@ -384,7 +384,10 @@ static int hsu_dma_terminate_all(struct dma_chan *chan) | |||
384 | spin_lock_irqsave(&hsuc->vchan.lock, flags); | 384 | spin_lock_irqsave(&hsuc->vchan.lock, flags); |
385 | 385 | ||
386 | hsu_dma_stop_channel(hsuc); | 386 | hsu_dma_stop_channel(hsuc); |
387 | hsuc->desc = NULL; | 387 | if (hsuc->desc) { |
388 | hsu_dma_desc_free(&hsuc->desc->vdesc); | ||
389 | hsuc->desc = NULL; | ||
390 | } | ||
388 | 391 | ||
389 | vchan_get_all_descriptors(&hsuc->vchan, &head); | 392 | vchan_get_all_descriptors(&hsuc->vchan, &head); |
390 | spin_unlock_irqrestore(&hsuc->vchan.lock, flags); | 393 | spin_unlock_irqrestore(&hsuc->vchan.lock, flags); |
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index a7d9d3029b14..340f9e607cd8 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c | |||
@@ -2127,6 +2127,7 @@ static int pl330_terminate_all(struct dma_chan *chan) | |||
2127 | struct pl330_dmac *pl330 = pch->dmac; | 2127 | struct pl330_dmac *pl330 = pch->dmac; |
2128 | LIST_HEAD(list); | 2128 | LIST_HEAD(list); |
2129 | 2129 | ||
2130 | pm_runtime_get_sync(pl330->ddma.dev); | ||
2130 | spin_lock_irqsave(&pch->lock, flags); | 2131 | spin_lock_irqsave(&pch->lock, flags); |
2131 | spin_lock(&pl330->lock); | 2132 | spin_lock(&pl330->lock); |
2132 | _stop(pch->thread); | 2133 | _stop(pch->thread); |
@@ -2151,6 +2152,8 @@ static int pl330_terminate_all(struct dma_chan *chan) | |||
2151 | list_splice_tail_init(&pch->work_list, &pl330->desc_pool); | 2152 | list_splice_tail_init(&pch->work_list, &pl330->desc_pool); |
2152 | list_splice_tail_init(&pch->completed_list, &pl330->desc_pool); | 2153 | list_splice_tail_init(&pch->completed_list, &pl330->desc_pool); |
2153 | spin_unlock_irqrestore(&pch->lock, flags); | 2154 | spin_unlock_irqrestore(&pch->lock, flags); |
2155 | pm_runtime_mark_last_busy(pl330->ddma.dev); | ||
2156 | pm_runtime_put_autosuspend(pl330->ddma.dev); | ||
2154 | 2157 | ||
2155 | return 0; | 2158 | return 0; |
2156 | } | 2159 | } |
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c index 071c2c969eec..72791232e46b 100644 --- a/drivers/firmware/iscsi_ibft.c +++ b/drivers/firmware/iscsi_ibft.c | |||
@@ -186,8 +186,20 @@ struct ibft_kobject { | |||
186 | 186 | ||
187 | static struct iscsi_boot_kset *boot_kset; | 187 | static struct iscsi_boot_kset *boot_kset; |
188 | 188 | ||
189 | /* fully null address */ | ||
189 | static const char nulls[16]; | 190 | static const char nulls[16]; |
190 | 191 | ||
192 | /* IPv4-mapped IPv6 ::ffff:0.0.0.0 */ | ||
193 | static const char mapped_nulls[16] = { 0x00, 0x00, 0x00, 0x00, | ||
194 | 0x00, 0x00, 0x00, 0x00, | ||
195 | 0x00, 0x00, 0xff, 0xff, | ||
196 | 0x00, 0x00, 0x00, 0x00 }; | ||
197 | |||
198 | static int address_not_null(u8 *ip) | ||
199 | { | ||
200 | return (memcmp(ip, nulls, 16) && memcmp(ip, mapped_nulls, 16)); | ||
201 | } | ||
202 | |||
191 | /* | 203 | /* |
192 | * Helper functions to parse data properly. | 204 | * Helper functions to parse data properly. |
193 | */ | 205 | */ |
@@ -445,7 +457,7 @@ static umode_t ibft_check_nic_for(void *data, int type) | |||
445 | rc = S_IRUGO; | 457 | rc = S_IRUGO; |
446 | break; | 458 | break; |
447 | case ISCSI_BOOT_ETH_IP_ADDR: | 459 | case ISCSI_BOOT_ETH_IP_ADDR: |
448 | if (memcmp(nic->ip_addr, nulls, sizeof(nic->ip_addr))) | 460 | if (address_not_null(nic->ip_addr)) |
449 | rc = S_IRUGO; | 461 | rc = S_IRUGO; |
450 | break; | 462 | break; |
451 | case ISCSI_BOOT_ETH_SUBNET_MASK: | 463 | case ISCSI_BOOT_ETH_SUBNET_MASK: |
@@ -456,21 +468,19 @@ static umode_t ibft_check_nic_for(void *data, int type) | |||
456 | rc = S_IRUGO; | 468 | rc = S_IRUGO; |
457 | break; | 469 | break; |
458 | case ISCSI_BOOT_ETH_GATEWAY: | 470 | case ISCSI_BOOT_ETH_GATEWAY: |
459 | if (memcmp(nic->gateway, nulls, sizeof(nic->gateway))) | 471 | if (address_not_null(nic->gateway)) |
460 | rc = S_IRUGO; | 472 | rc = S_IRUGO; |
461 | break; | 473 | break; |
462 | case ISCSI_BOOT_ETH_PRIMARY_DNS: | 474 | case ISCSI_BOOT_ETH_PRIMARY_DNS: |
463 | if (memcmp(nic->primary_dns, nulls, | 475 | if (address_not_null(nic->primary_dns)) |
464 | sizeof(nic->primary_dns))) | ||
465 | rc = S_IRUGO; | 476 | rc = S_IRUGO; |
466 | break; | 477 | break; |
467 | case ISCSI_BOOT_ETH_SECONDARY_DNS: | 478 | case ISCSI_BOOT_ETH_SECONDARY_DNS: |
468 | if (memcmp(nic->secondary_dns, nulls, | 479 | if (address_not_null(nic->secondary_dns)) |
469 | sizeof(nic->secondary_dns))) | ||
470 | rc = S_IRUGO; | 480 | rc = S_IRUGO; |
471 | break; | 481 | break; |
472 | case ISCSI_BOOT_ETH_DHCP: | 482 | case ISCSI_BOOT_ETH_DHCP: |
473 | if (memcmp(nic->dhcp, nulls, sizeof(nic->dhcp))) | 483 | if (address_not_null(nic->dhcp)) |
474 | rc = S_IRUGO; | 484 | rc = S_IRUGO; |
475 | break; | 485 | break; |
476 | case ISCSI_BOOT_ETH_VLAN: | 486 | case ISCSI_BOOT_ETH_VLAN: |
@@ -536,23 +546,19 @@ static umode_t __init ibft_check_initiator_for(void *data, int type) | |||
536 | rc = S_IRUGO; | 546 | rc = S_IRUGO; |
537 | break; | 547 | break; |
538 | case ISCSI_BOOT_INI_ISNS_SERVER: | 548 | case ISCSI_BOOT_INI_ISNS_SERVER: |
539 | if (memcmp(init->isns_server, nulls, | 549 | if (address_not_null(init->isns_server)) |
540 | sizeof(init->isns_server))) | ||
541 | rc = S_IRUGO; | 550 | rc = S_IRUGO; |
542 | break; | 551 | break; |
543 | case ISCSI_BOOT_INI_SLP_SERVER: | 552 | case ISCSI_BOOT_INI_SLP_SERVER: |
544 | if (memcmp(init->slp_server, nulls, | 553 | if (address_not_null(init->slp_server)) |
545 | sizeof(init->slp_server))) | ||
546 | rc = S_IRUGO; | 554 | rc = S_IRUGO; |
547 | break; | 555 | break; |
548 | case ISCSI_BOOT_INI_PRI_RADIUS_SERVER: | 556 | case ISCSI_BOOT_INI_PRI_RADIUS_SERVER: |
549 | if (memcmp(init->pri_radius_server, nulls, | 557 | if (address_not_null(init->pri_radius_server)) |
550 | sizeof(init->pri_radius_server))) | ||
551 | rc = S_IRUGO; | 558 | rc = S_IRUGO; |
552 | break; | 559 | break; |
553 | case ISCSI_BOOT_INI_SEC_RADIUS_SERVER: | 560 | case ISCSI_BOOT_INI_SEC_RADIUS_SERVER: |
554 | if (memcmp(init->sec_radius_server, nulls, | 561 | if (address_not_null(init->sec_radius_server)) |
555 | sizeof(init->sec_radius_server))) | ||
556 | rc = S_IRUGO; | 562 | rc = S_IRUGO; |
557 | break; | 563 | break; |
558 | case ISCSI_BOOT_INI_INITIATOR_NAME: | 564 | case ISCSI_BOOT_INI_INITIATOR_NAME: |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index e469c4b2e8cc..c25728bc388a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c | |||
@@ -684,8 +684,6 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, | |||
684 | dev->node_props.cpu_core_id_base); | 684 | dev->node_props.cpu_core_id_base); |
685 | sysfs_show_32bit_prop(buffer, "simd_id_base", | 685 | sysfs_show_32bit_prop(buffer, "simd_id_base", |
686 | dev->node_props.simd_id_base); | 686 | dev->node_props.simd_id_base); |
687 | sysfs_show_32bit_prop(buffer, "capability", | ||
688 | dev->node_props.capability); | ||
689 | sysfs_show_32bit_prop(buffer, "max_waves_per_simd", | 687 | sysfs_show_32bit_prop(buffer, "max_waves_per_simd", |
690 | dev->node_props.max_waves_per_simd); | 688 | dev->node_props.max_waves_per_simd); |
691 | sysfs_show_32bit_prop(buffer, "lds_size_in_kb", | 689 | sysfs_show_32bit_prop(buffer, "lds_size_in_kb", |
@@ -736,6 +734,8 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, | |||
736 | dev->gpu->kfd2kgd->get_fw_version( | 734 | dev->gpu->kfd2kgd->get_fw_version( |
737 | dev->gpu->kgd, | 735 | dev->gpu->kgd, |
738 | KGD_ENGINE_MEC1)); | 736 | KGD_ENGINE_MEC1)); |
737 | sysfs_show_32bit_prop(buffer, "capability", | ||
738 | dev->node_props.capability); | ||
739 | } | 739 | } |
740 | 740 | ||
741 | return sysfs_show_32bit_prop(buffer, "max_engine_clk_ccompute", | 741 | return sysfs_show_32bit_prop(buffer, "max_engine_clk_ccompute", |
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index ffc305fc2076..eb7e61078a5b 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -217,7 +217,7 @@ static ssize_t status_store(struct device *device, | |||
217 | 217 | ||
218 | mutex_unlock(&dev->mode_config.mutex); | 218 | mutex_unlock(&dev->mode_config.mutex); |
219 | 219 | ||
220 | return ret; | 220 | return ret ? ret : count; |
221 | } | 221 | } |
222 | 222 | ||
223 | static ssize_t status_show(struct device *device, | 223 | static ssize_t status_show(struct device *device, |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 007c7d7d8295..dc55c51964ab 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -1667,12 +1667,15 @@ static int i915_sr_status(struct seq_file *m, void *unused) | |||
1667 | 1667 | ||
1668 | if (HAS_PCH_SPLIT(dev)) | 1668 | if (HAS_PCH_SPLIT(dev)) |
1669 | sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; | 1669 | sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; |
1670 | else if (IS_CRESTLINE(dev) || IS_I945G(dev) || IS_I945GM(dev)) | 1670 | else if (IS_CRESTLINE(dev) || IS_G4X(dev) || |
1671 | IS_I945G(dev) || IS_I945GM(dev)) | ||
1671 | sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; | 1672 | sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; |
1672 | else if (IS_I915GM(dev)) | 1673 | else if (IS_I915GM(dev)) |
1673 | sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN; | 1674 | sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN; |
1674 | else if (IS_PINEVIEW(dev)) | 1675 | else if (IS_PINEVIEW(dev)) |
1675 | sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN; | 1676 | sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN; |
1677 | else if (IS_VALLEYVIEW(dev)) | ||
1678 | sr_enabled = I915_READ(FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; | ||
1676 | 1679 | ||
1677 | intel_runtime_pm_put(dev_priv); | 1680 | intel_runtime_pm_put(dev_priv); |
1678 | 1681 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 53394f998a1f..851b585987f9 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2656,9 +2656,6 @@ void i915_gem_reset(struct drm_device *dev) | |||
2656 | void | 2656 | void |
2657 | i915_gem_retire_requests_ring(struct intel_engine_cs *ring) | 2657 | i915_gem_retire_requests_ring(struct intel_engine_cs *ring) |
2658 | { | 2658 | { |
2659 | if (list_empty(&ring->request_list)) | ||
2660 | return; | ||
2661 | |||
2662 | WARN_ON(i915_verify_lists(ring->dev)); | 2659 | WARN_ON(i915_verify_lists(ring->dev)); |
2663 | 2660 | ||
2664 | /* Retire requests first as we use it above for the early return. | 2661 | /* Retire requests first as we use it above for the early return. |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f27346e907b1..d714a4b5711e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -880,10 +880,8 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
880 | DP_AUX_CH_CTL_RECEIVE_ERROR)) | 880 | DP_AUX_CH_CTL_RECEIVE_ERROR)) |
881 | continue; | 881 | continue; |
882 | if (status & DP_AUX_CH_CTL_DONE) | 882 | if (status & DP_AUX_CH_CTL_DONE) |
883 | break; | 883 | goto done; |
884 | } | 884 | } |
885 | if (status & DP_AUX_CH_CTL_DONE) | ||
886 | break; | ||
887 | } | 885 | } |
888 | 886 | ||
889 | if ((status & DP_AUX_CH_CTL_DONE) == 0) { | 887 | if ((status & DP_AUX_CH_CTL_DONE) == 0) { |
@@ -892,6 +890,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
892 | goto out; | 890 | goto out; |
893 | } | 891 | } |
894 | 892 | ||
893 | done: | ||
895 | /* Check for timeout or receive error. | 894 | /* Check for timeout or receive error. |
896 | * Timeouts occur when the sink is not connected | 895 | * Timeouts occur when the sink is not connected |
897 | */ | 896 | */ |
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 56e437e31580..ae628001fd97 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -435,7 +435,7 @@ gmbus_xfer(struct i2c_adapter *adapter, | |||
435 | struct intel_gmbus, | 435 | struct intel_gmbus, |
436 | adapter); | 436 | adapter); |
437 | struct drm_i915_private *dev_priv = bus->dev_priv; | 437 | struct drm_i915_private *dev_priv = bus->dev_priv; |
438 | int i, reg_offset; | 438 | int i = 0, inc, try = 0, reg_offset; |
439 | int ret = 0; | 439 | int ret = 0; |
440 | 440 | ||
441 | intel_aux_display_runtime_get(dev_priv); | 441 | intel_aux_display_runtime_get(dev_priv); |
@@ -448,12 +448,14 @@ gmbus_xfer(struct i2c_adapter *adapter, | |||
448 | 448 | ||
449 | reg_offset = dev_priv->gpio_mmio_base; | 449 | reg_offset = dev_priv->gpio_mmio_base; |
450 | 450 | ||
451 | retry: | ||
451 | I915_WRITE(GMBUS0 + reg_offset, bus->reg0); | 452 | I915_WRITE(GMBUS0 + reg_offset, bus->reg0); |
452 | 453 | ||
453 | for (i = 0; i < num; i++) { | 454 | for (; i < num; i += inc) { |
455 | inc = 1; | ||
454 | if (gmbus_is_index_read(msgs, i, num)) { | 456 | if (gmbus_is_index_read(msgs, i, num)) { |
455 | ret = gmbus_xfer_index_read(dev_priv, &msgs[i]); | 457 | ret = gmbus_xfer_index_read(dev_priv, &msgs[i]); |
456 | i += 1; /* set i to the index of the read xfer */ | 458 | inc = 2; /* an index read is two msgs */ |
457 | } else if (msgs[i].flags & I2C_M_RD) { | 459 | } else if (msgs[i].flags & I2C_M_RD) { |
458 | ret = gmbus_xfer_read(dev_priv, &msgs[i], 0); | 460 | ret = gmbus_xfer_read(dev_priv, &msgs[i], 0); |
459 | } else { | 461 | } else { |
@@ -525,6 +527,18 @@ clear_err: | |||
525 | adapter->name, msgs[i].addr, | 527 | adapter->name, msgs[i].addr, |
526 | (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len); | 528 | (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len); |
527 | 529 | ||
530 | /* | ||
531 | * Passive adapters sometimes NAK the first probe. Retry the first | ||
532 | * message once on -ENXIO for GMBUS transfers; the bit banging algorithm | ||
533 | * has retries internally. See also the retry loop in | ||
534 | * drm_do_probe_ddc_edid, which bails out on the first -ENXIO. | ||
535 | */ | ||
536 | if (ret == -ENXIO && i == 0 && try++ == 0) { | ||
537 | DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n", | ||
538 | adapter->name); | ||
539 | goto retry; | ||
540 | } | ||
541 | |||
528 | goto out; | 542 | goto out; |
529 | 543 | ||
530 | timeout: | 544 | timeout: |
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 09df74b8e917..424e62197787 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c | |||
@@ -1134,6 +1134,12 @@ static int gen8_init_common_ring(struct intel_engine_cs *ring) | |||
1134 | I915_WRITE_IMR(ring, ~(ring->irq_enable_mask | ring->irq_keep_mask)); | 1134 | I915_WRITE_IMR(ring, ~(ring->irq_enable_mask | ring->irq_keep_mask)); |
1135 | I915_WRITE(RING_HWSTAM(ring->mmio_base), 0xffffffff); | 1135 | I915_WRITE(RING_HWSTAM(ring->mmio_base), 0xffffffff); |
1136 | 1136 | ||
1137 | if (ring->status_page.obj) { | ||
1138 | I915_WRITE(RING_HWS_PGA(ring->mmio_base), | ||
1139 | (u32)ring->status_page.gfx_addr); | ||
1140 | POSTING_READ(RING_HWS_PGA(ring->mmio_base)); | ||
1141 | } | ||
1142 | |||
1137 | I915_WRITE(RING_MODE_GEN7(ring), | 1143 | I915_WRITE(RING_MODE_GEN7(ring), |
1138 | _MASKED_BIT_DISABLE(GFX_REPLAY_MODE) | | 1144 | _MASKED_BIT_DISABLE(GFX_REPLAY_MODE) | |
1139 | _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE)); | 1145 | _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE)); |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 441e2502b889..005b5e04de4d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -901,13 +901,6 @@ static int chv_init_workarounds(struct intel_engine_cs *ring) | |||
901 | GEN6_WIZ_HASHING_MASK, | 901 | GEN6_WIZ_HASHING_MASK, |
902 | GEN6_WIZ_HASHING_16x4); | 902 | GEN6_WIZ_HASHING_16x4); |
903 | 903 | ||
904 | if (INTEL_REVID(dev) == SKL_REVID_C0 || | ||
905 | INTEL_REVID(dev) == SKL_REVID_D0) | ||
906 | /* WaBarrierPerformanceFixDisable:skl */ | ||
907 | WA_SET_BIT_MASKED(HDC_CHICKEN0, | ||
908 | HDC_FENCE_DEST_SLM_DISABLE | | ||
909 | HDC_BARRIER_PERFORMANCE_DISABLE); | ||
910 | |||
911 | return 0; | 904 | return 0; |
912 | } | 905 | } |
913 | 906 | ||
@@ -1024,6 +1017,13 @@ static int skl_init_workarounds(struct intel_engine_cs *ring) | |||
1024 | WA_SET_BIT_MASKED(HIZ_CHICKEN, | 1017 | WA_SET_BIT_MASKED(HIZ_CHICKEN, |
1025 | BDW_HIZ_POWER_COMPILER_CLOCK_GATING_DISABLE); | 1018 | BDW_HIZ_POWER_COMPILER_CLOCK_GATING_DISABLE); |
1026 | 1019 | ||
1020 | if (INTEL_REVID(dev) == SKL_REVID_C0 || | ||
1021 | INTEL_REVID(dev) == SKL_REVID_D0) | ||
1022 | /* WaBarrierPerformanceFixDisable:skl */ | ||
1023 | WA_SET_BIT_MASKED(HDC_CHICKEN0, | ||
1024 | HDC_FENCE_DEST_SLM_DISABLE | | ||
1025 | HDC_BARRIER_PERFORMANCE_DISABLE); | ||
1026 | |||
1027 | return skl_tune_iz_hashing(ring); | 1027 | return skl_tune_iz_hashing(ring); |
1028 | } | 1028 | } |
1029 | 1029 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index e87d2f418de4..987b81f31b0e 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -2550,7 +2550,7 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) | |||
2550 | 2550 | ||
2551 | DRM_DEBUG_KMS("initialising analog device %d\n", device); | 2551 | DRM_DEBUG_KMS("initialising analog device %d\n", device); |
2552 | 2552 | ||
2553 | intel_sdvo_connector = kzalloc(sizeof(*intel_sdvo_connector), GFP_KERNEL); | 2553 | intel_sdvo_connector = intel_sdvo_connector_alloc(); |
2554 | if (!intel_sdvo_connector) | 2554 | if (!intel_sdvo_connector) |
2555 | return false; | 2555 | return false; |
2556 | 2556 | ||
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index e597ffc26563..dac78ad24b31 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -580,9 +580,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
580 | else | 580 | else |
581 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; | 581 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
582 | 582 | ||
583 | /* if there is no audio, set MINM_OVER_MAXP */ | ||
584 | if (!drm_detect_monitor_audio(radeon_connector_edid(connector))) | ||
585 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; | ||
586 | if (rdev->family < CHIP_RV770) | 583 | if (rdev->family < CHIP_RV770) |
587 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; | 584 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; |
588 | /* use frac fb div on APUs */ | 585 | /* use frac fb div on APUs */ |
@@ -1798,9 +1795,7 @@ static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc) | |||
1798 | if ((crtc->mode.clock == test_crtc->mode.clock) && | 1795 | if ((crtc->mode.clock == test_crtc->mode.clock) && |
1799 | (adjusted_clock == test_adjusted_clock) && | 1796 | (adjusted_clock == test_adjusted_clock) && |
1800 | (radeon_crtc->ss_enabled == test_radeon_crtc->ss_enabled) && | 1797 | (radeon_crtc->ss_enabled == test_radeon_crtc->ss_enabled) && |
1801 | (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID) && | 1798 | (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)) |
1802 | (drm_detect_monitor_audio(radeon_connector_edid(test_radeon_crtc->connector)) == | ||
1803 | drm_detect_monitor_audio(radeon_connector_edid(radeon_crtc->connector)))) | ||
1804 | return test_radeon_crtc->pll_id; | 1799 | return test_radeon_crtc->pll_id; |
1805 | } | 1800 | } |
1806 | } | 1801 | } |
diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index f04205170b8a..cfa3a84a2af0 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c | |||
@@ -173,7 +173,7 @@ void dce3_2_hdmi_update_acr(struct drm_encoder *encoder, long offset, | |||
173 | struct drm_device *dev = encoder->dev; | 173 | struct drm_device *dev = encoder->dev; |
174 | struct radeon_device *rdev = dev->dev_private; | 174 | struct radeon_device *rdev = dev->dev_private; |
175 | 175 | ||
176 | WREG32(HDMI0_ACR_PACKET_CONTROL + offset, | 176 | WREG32(DCE3_HDMI0_ACR_PACKET_CONTROL + offset, |
177 | HDMI0_ACR_SOURCE | /* select SW CTS value */ | 177 | HDMI0_ACR_SOURCE | /* select SW CTS value */ |
178 | HDMI0_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ | 178 | HDMI0_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ |
179 | 179 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index b7ca4c514621..a7fdfa4f0857 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -1463,6 +1463,21 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1463 | if (r) | 1463 | if (r) |
1464 | DRM_ERROR("ib ring test failed (%d).\n", r); | 1464 | DRM_ERROR("ib ring test failed (%d).\n", r); |
1465 | 1465 | ||
1466 | /* | ||
1467 | * Turks/Thames GPU will freeze whole laptop if DPM is not restarted | ||
1468 | * after the CP ring have chew one packet at least. Hence here we stop | ||
1469 | * and restart DPM after the radeon_ib_ring_tests(). | ||
1470 | */ | ||
1471 | if (rdev->pm.dpm_enabled && | ||
1472 | (rdev->pm.pm_method == PM_METHOD_DPM) && | ||
1473 | (rdev->family == CHIP_TURKS) && | ||
1474 | (rdev->flags & RADEON_IS_MOBILITY)) { | ||
1475 | mutex_lock(&rdev->pm.mutex); | ||
1476 | radeon_dpm_disable(rdev); | ||
1477 | radeon_dpm_enable(rdev); | ||
1478 | mutex_unlock(&rdev->pm.mutex); | ||
1479 | } | ||
1480 | |||
1466 | if ((radeon_testing & 1)) { | 1481 | if ((radeon_testing & 1)) { |
1467 | if (rdev->accel_working) | 1482 | if (rdev->accel_working) |
1468 | radeon_test_moves(rdev); | 1483 | radeon_test_moves(rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index de42fc4a22b8..9c3377ca17b7 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c | |||
@@ -458,14 +458,16 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, | |||
458 | /* make sure object fit at this offset */ | 458 | /* make sure object fit at this offset */ |
459 | eoffset = soffset + size; | 459 | eoffset = soffset + size; |
460 | if (soffset >= eoffset) { | 460 | if (soffset >= eoffset) { |
461 | return -EINVAL; | 461 | r = -EINVAL; |
462 | goto error_unreserve; | ||
462 | } | 463 | } |
463 | 464 | ||
464 | last_pfn = eoffset / RADEON_GPU_PAGE_SIZE; | 465 | last_pfn = eoffset / RADEON_GPU_PAGE_SIZE; |
465 | if (last_pfn > rdev->vm_manager.max_pfn) { | 466 | if (last_pfn > rdev->vm_manager.max_pfn) { |
466 | dev_err(rdev->dev, "va above limit (0x%08X > 0x%08X)\n", | 467 | dev_err(rdev->dev, "va above limit (0x%08X > 0x%08X)\n", |
467 | last_pfn, rdev->vm_manager.max_pfn); | 468 | last_pfn, rdev->vm_manager.max_pfn); |
468 | return -EINVAL; | 469 | r = -EINVAL; |
470 | goto error_unreserve; | ||
469 | } | 471 | } |
470 | 472 | ||
471 | } else { | 473 | } else { |
@@ -486,7 +488,8 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, | |||
486 | "(bo %p 0x%010lx 0x%010lx)\n", bo_va->bo, | 488 | "(bo %p 0x%010lx 0x%010lx)\n", bo_va->bo, |
487 | soffset, tmp->bo, tmp->it.start, tmp->it.last); | 489 | soffset, tmp->bo, tmp->it.start, tmp->it.last); |
488 | mutex_unlock(&vm->mutex); | 490 | mutex_unlock(&vm->mutex); |
489 | return -EINVAL; | 491 | r = -EINVAL; |
492 | goto error_unreserve; | ||
490 | } | 493 | } |
491 | } | 494 | } |
492 | 495 | ||
@@ -497,7 +500,8 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, | |||
497 | tmp = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL); | 500 | tmp = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL); |
498 | if (!tmp) { | 501 | if (!tmp) { |
499 | mutex_unlock(&vm->mutex); | 502 | mutex_unlock(&vm->mutex); |
500 | return -ENOMEM; | 503 | r = -ENOMEM; |
504 | goto error_unreserve; | ||
501 | } | 505 | } |
502 | tmp->it.start = bo_va->it.start; | 506 | tmp->it.start = bo_va->it.start; |
503 | tmp->it.last = bo_va->it.last; | 507 | tmp->it.last = bo_va->it.last; |
@@ -555,7 +559,6 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, | |||
555 | r = radeon_vm_clear_bo(rdev, pt); | 559 | r = radeon_vm_clear_bo(rdev, pt); |
556 | if (r) { | 560 | if (r) { |
557 | radeon_bo_unref(&pt); | 561 | radeon_bo_unref(&pt); |
558 | radeon_bo_reserve(bo_va->bo, false); | ||
559 | return r; | 562 | return r; |
560 | } | 563 | } |
561 | 564 | ||
@@ -575,6 +578,10 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, | |||
575 | 578 | ||
576 | mutex_unlock(&vm->mutex); | 579 | mutex_unlock(&vm->mutex); |
577 | return 0; | 580 | return 0; |
581 | |||
582 | error_unreserve: | ||
583 | radeon_bo_unreserve(bo_va->bo); | ||
584 | return r; | ||
578 | } | 585 | } |
579 | 586 | ||
580 | /** | 587 | /** |
diff --git a/drivers/i2c/busses/i2c-hix5hd2.c b/drivers/i2c/busses/i2c-hix5hd2.c index 8fe78d08e01c..7c6966434ee7 100644 --- a/drivers/i2c/busses/i2c-hix5hd2.c +++ b/drivers/i2c/busses/i2c-hix5hd2.c | |||
@@ -554,4 +554,4 @@ module_platform_driver(hix5hd2_i2c_driver); | |||
554 | MODULE_DESCRIPTION("Hix5hd2 I2C Bus driver"); | 554 | MODULE_DESCRIPTION("Hix5hd2 I2C Bus driver"); |
555 | MODULE_AUTHOR("Wei Yan <sledge.yanwei@huawei.com>"); | 555 | MODULE_AUTHOR("Wei Yan <sledge.yanwei@huawei.com>"); |
556 | MODULE_LICENSE("GPL"); | 556 | MODULE_LICENSE("GPL"); |
557 | MODULE_ALIAS("platform:i2c-hix5hd2"); | 557 | MODULE_ALIAS("platform:hix5hd2-i2c"); |
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 958c8db4ec30..297e9c9ac943 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c | |||
@@ -1143,6 +1143,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) | |||
1143 | return -ENOMEM; | 1143 | return -ENOMEM; |
1144 | 1144 | ||
1145 | i2c->quirks = s3c24xx_get_device_quirks(pdev); | 1145 | i2c->quirks = s3c24xx_get_device_quirks(pdev); |
1146 | i2c->sysreg = ERR_PTR(-ENOENT); | ||
1146 | if (pdata) | 1147 | if (pdata) |
1147 | memcpy(i2c->pdata, pdata, sizeof(*pdata)); | 1148 | memcpy(i2c->pdata, pdata, sizeof(*pdata)); |
1148 | else | 1149 | else |
diff --git a/drivers/iio/adc/twl6030-gpadc.c b/drivers/iio/adc/twl6030-gpadc.c index 89d8aa1d2818..df12c57e6ce0 100644 --- a/drivers/iio/adc/twl6030-gpadc.c +++ b/drivers/iio/adc/twl6030-gpadc.c | |||
@@ -1001,7 +1001,7 @@ static struct platform_driver twl6030_gpadc_driver = { | |||
1001 | 1001 | ||
1002 | module_platform_driver(twl6030_gpadc_driver); | 1002 | module_platform_driver(twl6030_gpadc_driver); |
1003 | 1003 | ||
1004 | MODULE_ALIAS("platform: " DRIVER_NAME); | 1004 | MODULE_ALIAS("platform:" DRIVER_NAME); |
1005 | MODULE_AUTHOR("Balaji T K <balajitk@ti.com>"); | 1005 | MODULE_AUTHOR("Balaji T K <balajitk@ti.com>"); |
1006 | MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); | 1006 | MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); |
1007 | MODULE_AUTHOR("Oleksandr Kozaruk <oleksandr.kozaruk@ti.com"); | 1007 | MODULE_AUTHOR("Oleksandr Kozaruk <oleksandr.kozaruk@ti.com"); |
diff --git a/drivers/iio/imu/adis16400.h b/drivers/iio/imu/adis16400.h index 0916bf6b6c31..73b189c1c0fb 100644 --- a/drivers/iio/imu/adis16400.h +++ b/drivers/iio/imu/adis16400.h | |||
@@ -139,6 +139,7 @@ | |||
139 | #define ADIS16400_NO_BURST BIT(1) | 139 | #define ADIS16400_NO_BURST BIT(1) |
140 | #define ADIS16400_HAS_SLOW_MODE BIT(2) | 140 | #define ADIS16400_HAS_SLOW_MODE BIT(2) |
141 | #define ADIS16400_HAS_SERIAL_NUMBER BIT(3) | 141 | #define ADIS16400_HAS_SERIAL_NUMBER BIT(3) |
142 | #define ADIS16400_BURST_DIAG_STAT BIT(4) | ||
142 | 143 | ||
143 | struct adis16400_state; | 144 | struct adis16400_state; |
144 | 145 | ||
@@ -165,6 +166,7 @@ struct adis16400_state { | |||
165 | int filt_int; | 166 | int filt_int; |
166 | 167 | ||
167 | struct adis adis; | 168 | struct adis adis; |
169 | unsigned long avail_scan_mask[2]; | ||
168 | }; | 170 | }; |
169 | 171 | ||
170 | /* At the moment triggers are only used for ring buffer | 172 | /* At the moment triggers are only used for ring buffer |
diff --git a/drivers/iio/imu/adis16400_buffer.c b/drivers/iio/imu/adis16400_buffer.c index 6e727ffe5262..90c24a23c679 100644 --- a/drivers/iio/imu/adis16400_buffer.c +++ b/drivers/iio/imu/adis16400_buffer.c | |||
@@ -18,7 +18,8 @@ int adis16400_update_scan_mode(struct iio_dev *indio_dev, | |||
18 | { | 18 | { |
19 | struct adis16400_state *st = iio_priv(indio_dev); | 19 | struct adis16400_state *st = iio_priv(indio_dev); |
20 | struct adis *adis = &st->adis; | 20 | struct adis *adis = &st->adis; |
21 | uint16_t *tx; | 21 | unsigned int burst_length; |
22 | u8 *tx; | ||
22 | 23 | ||
23 | if (st->variant->flags & ADIS16400_NO_BURST) | 24 | if (st->variant->flags & ADIS16400_NO_BURST) |
24 | return adis_update_scan_mode(indio_dev, scan_mask); | 25 | return adis_update_scan_mode(indio_dev, scan_mask); |
@@ -26,26 +27,29 @@ int adis16400_update_scan_mode(struct iio_dev *indio_dev, | |||
26 | kfree(adis->xfer); | 27 | kfree(adis->xfer); |
27 | kfree(adis->buffer); | 28 | kfree(adis->buffer); |
28 | 29 | ||
30 | /* All but the timestamp channel */ | ||
31 | burst_length = (indio_dev->num_channels - 1) * sizeof(u16); | ||
32 | if (st->variant->flags & ADIS16400_BURST_DIAG_STAT) | ||
33 | burst_length += sizeof(u16); | ||
34 | |||
29 | adis->xfer = kcalloc(2, sizeof(*adis->xfer), GFP_KERNEL); | 35 | adis->xfer = kcalloc(2, sizeof(*adis->xfer), GFP_KERNEL); |
30 | if (!adis->xfer) | 36 | if (!adis->xfer) |
31 | return -ENOMEM; | 37 | return -ENOMEM; |
32 | 38 | ||
33 | adis->buffer = kzalloc(indio_dev->scan_bytes + sizeof(u16), | 39 | adis->buffer = kzalloc(burst_length + sizeof(u16), GFP_KERNEL); |
34 | GFP_KERNEL); | ||
35 | if (!adis->buffer) | 40 | if (!adis->buffer) |
36 | return -ENOMEM; | 41 | return -ENOMEM; |
37 | 42 | ||
38 | tx = adis->buffer + indio_dev->scan_bytes; | 43 | tx = adis->buffer + burst_length; |
39 | |||
40 | tx[0] = ADIS_READ_REG(ADIS16400_GLOB_CMD); | 44 | tx[0] = ADIS_READ_REG(ADIS16400_GLOB_CMD); |
41 | tx[1] = 0; | 45 | tx[1] = 0; |
42 | 46 | ||
43 | adis->xfer[0].tx_buf = tx; | 47 | adis->xfer[0].tx_buf = tx; |
44 | adis->xfer[0].bits_per_word = 8; | 48 | adis->xfer[0].bits_per_word = 8; |
45 | adis->xfer[0].len = 2; | 49 | adis->xfer[0].len = 2; |
46 | adis->xfer[1].tx_buf = tx; | 50 | adis->xfer[1].rx_buf = adis->buffer; |
47 | adis->xfer[1].bits_per_word = 8; | 51 | adis->xfer[1].bits_per_word = 8; |
48 | adis->xfer[1].len = indio_dev->scan_bytes; | 52 | adis->xfer[1].len = burst_length; |
49 | 53 | ||
50 | spi_message_init(&adis->msg); | 54 | spi_message_init(&adis->msg); |
51 | spi_message_add_tail(&adis->xfer[0], &adis->msg); | 55 | spi_message_add_tail(&adis->xfer[0], &adis->msg); |
@@ -61,6 +65,7 @@ irqreturn_t adis16400_trigger_handler(int irq, void *p) | |||
61 | struct adis16400_state *st = iio_priv(indio_dev); | 65 | struct adis16400_state *st = iio_priv(indio_dev); |
62 | struct adis *adis = &st->adis; | 66 | struct adis *adis = &st->adis; |
63 | u32 old_speed_hz = st->adis.spi->max_speed_hz; | 67 | u32 old_speed_hz = st->adis.spi->max_speed_hz; |
68 | void *buffer; | ||
64 | int ret; | 69 | int ret; |
65 | 70 | ||
66 | if (!adis->buffer) | 71 | if (!adis->buffer) |
@@ -81,7 +86,12 @@ irqreturn_t adis16400_trigger_handler(int irq, void *p) | |||
81 | spi_setup(st->adis.spi); | 86 | spi_setup(st->adis.spi); |
82 | } | 87 | } |
83 | 88 | ||
84 | iio_push_to_buffers_with_timestamp(indio_dev, adis->buffer, | 89 | if (st->variant->flags & ADIS16400_BURST_DIAG_STAT) |
90 | buffer = adis->buffer + sizeof(u16); | ||
91 | else | ||
92 | buffer = adis->buffer; | ||
93 | |||
94 | iio_push_to_buffers_with_timestamp(indio_dev, buffer, | ||
85 | pf->timestamp); | 95 | pf->timestamp); |
86 | 96 | ||
87 | iio_trigger_notify_done(indio_dev->trig); | 97 | iio_trigger_notify_done(indio_dev->trig); |
diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c index fa795dcd5f75..2fd68f2219a7 100644 --- a/drivers/iio/imu/adis16400_core.c +++ b/drivers/iio/imu/adis16400_core.c | |||
@@ -405,6 +405,11 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, | |||
405 | *val = st->variant->temp_scale_nano / 1000000; | 405 | *val = st->variant->temp_scale_nano / 1000000; |
406 | *val2 = (st->variant->temp_scale_nano % 1000000); | 406 | *val2 = (st->variant->temp_scale_nano % 1000000); |
407 | return IIO_VAL_INT_PLUS_MICRO; | 407 | return IIO_VAL_INT_PLUS_MICRO; |
408 | case IIO_PRESSURE: | ||
409 | /* 20 uBar = 0.002kPascal */ | ||
410 | *val = 0; | ||
411 | *val2 = 2000; | ||
412 | return IIO_VAL_INT_PLUS_MICRO; | ||
408 | default: | 413 | default: |
409 | return -EINVAL; | 414 | return -EINVAL; |
410 | } | 415 | } |
@@ -454,10 +459,10 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, | |||
454 | } | 459 | } |
455 | } | 460 | } |
456 | 461 | ||
457 | #define ADIS16400_VOLTAGE_CHAN(addr, bits, name, si) { \ | 462 | #define ADIS16400_VOLTAGE_CHAN(addr, bits, name, si, chn) { \ |
458 | .type = IIO_VOLTAGE, \ | 463 | .type = IIO_VOLTAGE, \ |
459 | .indexed = 1, \ | 464 | .indexed = 1, \ |
460 | .channel = 0, \ | 465 | .channel = chn, \ |
461 | .extend_name = name, \ | 466 | .extend_name = name, \ |
462 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ | 467 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
463 | BIT(IIO_CHAN_INFO_SCALE), \ | 468 | BIT(IIO_CHAN_INFO_SCALE), \ |
@@ -474,10 +479,10 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, | |||
474 | } | 479 | } |
475 | 480 | ||
476 | #define ADIS16400_SUPPLY_CHAN(addr, bits) \ | 481 | #define ADIS16400_SUPPLY_CHAN(addr, bits) \ |
477 | ADIS16400_VOLTAGE_CHAN(addr, bits, "supply", ADIS16400_SCAN_SUPPLY) | 482 | ADIS16400_VOLTAGE_CHAN(addr, bits, "supply", ADIS16400_SCAN_SUPPLY, 0) |
478 | 483 | ||
479 | #define ADIS16400_AUX_ADC_CHAN(addr, bits) \ | 484 | #define ADIS16400_AUX_ADC_CHAN(addr, bits) \ |
480 | ADIS16400_VOLTAGE_CHAN(addr, bits, NULL, ADIS16400_SCAN_ADC) | 485 | ADIS16400_VOLTAGE_CHAN(addr, bits, NULL, ADIS16400_SCAN_ADC, 1) |
481 | 486 | ||
482 | #define ADIS16400_GYRO_CHAN(mod, addr, bits) { \ | 487 | #define ADIS16400_GYRO_CHAN(mod, addr, bits) { \ |
483 | .type = IIO_ANGL_VEL, \ | 488 | .type = IIO_ANGL_VEL, \ |
@@ -773,7 +778,8 @@ static struct adis16400_chip_info adis16400_chips[] = { | |||
773 | .channels = adis16448_channels, | 778 | .channels = adis16448_channels, |
774 | .num_channels = ARRAY_SIZE(adis16448_channels), | 779 | .num_channels = ARRAY_SIZE(adis16448_channels), |
775 | .flags = ADIS16400_HAS_PROD_ID | | 780 | .flags = ADIS16400_HAS_PROD_ID | |
776 | ADIS16400_HAS_SERIAL_NUMBER, | 781 | ADIS16400_HAS_SERIAL_NUMBER | |
782 | ADIS16400_BURST_DIAG_STAT, | ||
777 | .gyro_scale_micro = IIO_DEGREE_TO_RAD(10000), /* 0.01 deg/s */ | 783 | .gyro_scale_micro = IIO_DEGREE_TO_RAD(10000), /* 0.01 deg/s */ |
778 | .accel_scale_micro = IIO_G_TO_M_S_2(833), /* 1/1200 g */ | 784 | .accel_scale_micro = IIO_G_TO_M_S_2(833), /* 1/1200 g */ |
779 | .temp_scale_nano = 73860000, /* 0.07386 C */ | 785 | .temp_scale_nano = 73860000, /* 0.07386 C */ |
@@ -791,11 +797,6 @@ static const struct iio_info adis16400_info = { | |||
791 | .debugfs_reg_access = adis_debugfs_reg_access, | 797 | .debugfs_reg_access = adis_debugfs_reg_access, |
792 | }; | 798 | }; |
793 | 799 | ||
794 | static const unsigned long adis16400_burst_scan_mask[] = { | ||
795 | ~0UL, | ||
796 | 0, | ||
797 | }; | ||
798 | |||
799 | static const char * const adis16400_status_error_msgs[] = { | 800 | static const char * const adis16400_status_error_msgs[] = { |
800 | [ADIS16400_DIAG_STAT_ZACCL_FAIL] = "Z-axis accelerometer self-test failure", | 801 | [ADIS16400_DIAG_STAT_ZACCL_FAIL] = "Z-axis accelerometer self-test failure", |
801 | [ADIS16400_DIAG_STAT_YACCL_FAIL] = "Y-axis accelerometer self-test failure", | 802 | [ADIS16400_DIAG_STAT_YACCL_FAIL] = "Y-axis accelerometer self-test failure", |
@@ -843,6 +844,20 @@ static const struct adis_data adis16400_data = { | |||
843 | BIT(ADIS16400_DIAG_STAT_POWER_LOW), | 844 | BIT(ADIS16400_DIAG_STAT_POWER_LOW), |
844 | }; | 845 | }; |
845 | 846 | ||
847 | static void adis16400_setup_chan_mask(struct adis16400_state *st) | ||
848 | { | ||
849 | const struct adis16400_chip_info *chip_info = st->variant; | ||
850 | unsigned i; | ||
851 | |||
852 | for (i = 0; i < chip_info->num_channels; i++) { | ||
853 | const struct iio_chan_spec *ch = &chip_info->channels[i]; | ||
854 | |||
855 | if (ch->scan_index >= 0 && | ||
856 | ch->scan_index != ADIS16400_SCAN_TIMESTAMP) | ||
857 | st->avail_scan_mask[0] |= BIT(ch->scan_index); | ||
858 | } | ||
859 | } | ||
860 | |||
846 | static int adis16400_probe(struct spi_device *spi) | 861 | static int adis16400_probe(struct spi_device *spi) |
847 | { | 862 | { |
848 | struct adis16400_state *st; | 863 | struct adis16400_state *st; |
@@ -866,8 +881,10 @@ static int adis16400_probe(struct spi_device *spi) | |||
866 | indio_dev->info = &adis16400_info; | 881 | indio_dev->info = &adis16400_info; |
867 | indio_dev->modes = INDIO_DIRECT_MODE; | 882 | indio_dev->modes = INDIO_DIRECT_MODE; |
868 | 883 | ||
869 | if (!(st->variant->flags & ADIS16400_NO_BURST)) | 884 | if (!(st->variant->flags & ADIS16400_NO_BURST)) { |
870 | indio_dev->available_scan_masks = adis16400_burst_scan_mask; | 885 | adis16400_setup_chan_mask(st); |
886 | indio_dev->available_scan_masks = st->avail_scan_mask; | ||
887 | } | ||
871 | 888 | ||
872 | ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data); | 889 | ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data); |
873 | if (ret) | 890 | if (ret) |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 7752bd59d4b7..a353b7de6d22 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -1063,9 +1063,8 @@ static void alps_process_trackstick_packet_v7(struct psmouse *psmouse) | |||
1063 | right = (packet[1] & 0x02) >> 1; | 1063 | right = (packet[1] & 0x02) >> 1; |
1064 | middle = (packet[1] & 0x04) >> 2; | 1064 | middle = (packet[1] & 0x04) >> 2; |
1065 | 1065 | ||
1066 | /* Divide 2 since trackpoint's speed is too fast */ | 1066 | input_report_rel(dev2, REL_X, (char)x); |
1067 | input_report_rel(dev2, REL_X, (char)x / 2); | 1067 | input_report_rel(dev2, REL_Y, -((char)y)); |
1068 | input_report_rel(dev2, REL_Y, -((char)y / 2)); | ||
1069 | 1068 | ||
1070 | input_report_key(dev2, BTN_LEFT, left); | 1069 | input_report_key(dev2, BTN_LEFT, left); |
1071 | input_report_key(dev2, BTN_RIGHT, right); | 1070 | input_report_key(dev2, BTN_RIGHT, right); |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 79363b687195..ce3d40004458 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -1376,10 +1376,11 @@ static bool elantech_is_signature_valid(const unsigned char *param) | |||
1376 | return true; | 1376 | return true; |
1377 | 1377 | ||
1378 | /* | 1378 | /* |
1379 | * Some models have a revision higher then 20. Meaning param[2] may | 1379 | * Some hw_version >= 4 models have a revision higher then 20. Meaning |
1380 | * be 10 or 20, skip the rates check for these. | 1380 | * that param[2] may be 10 or 20, skip the rates check for these. |
1381 | */ | 1381 | */ |
1382 | if (param[0] == 0x46 && (param[1] & 0xef) == 0x0f && param[2] < 40) | 1382 | if ((param[0] & 0x0f) >= 0x06 && (param[1] & 0xaf) == 0x0f && |
1383 | param[2] < 40) | ||
1383 | return true; | 1384 | return true; |
1384 | 1385 | ||
1385 | for (i = 0; i < ARRAY_SIZE(rates); i++) | 1386 | for (i = 0; i < ARRAY_SIZE(rates); i++) |
@@ -1555,6 +1556,7 @@ static int elantech_set_properties(struct elantech_data *etd) | |||
1555 | case 9: | 1556 | case 9: |
1556 | case 10: | 1557 | case 10: |
1557 | case 13: | 1558 | case 13: |
1559 | case 14: | ||
1558 | etd->hw_version = 4; | 1560 | etd->hw_version = 4; |
1559 | break; | 1561 | break; |
1560 | default: | 1562 | default: |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 630af73e98c4..35c8d0ceabee 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -151,6 +151,11 @@ static const struct min_max_quirk min_max_pnpid_table[] = { | |||
151 | 1024, 5112, 2024, 4832 | 151 | 1024, 5112, 2024, 4832 |
152 | }, | 152 | }, |
153 | { | 153 | { |
154 | (const char * const []){"LEN2000", NULL}, | ||
155 | {ANY_BOARD_ID, ANY_BOARD_ID}, | ||
156 | 1024, 5113, 2021, 4832 | ||
157 | }, | ||
158 | { | ||
154 | (const char * const []){"LEN2001", NULL}, | 159 | (const char * const []){"LEN2001", NULL}, |
155 | {ANY_BOARD_ID, ANY_BOARD_ID}, | 160 | {ANY_BOARD_ID, ANY_BOARD_ID}, |
156 | 1024, 5022, 2508, 4832 | 161 | 1024, 5022, 2508, 4832 |
@@ -191,7 +196,7 @@ static const char * const topbuttonpad_pnp_ids[] = { | |||
191 | "LEN0045", | 196 | "LEN0045", |
192 | "LEN0047", | 197 | "LEN0047", |
193 | "LEN0049", | 198 | "LEN0049", |
194 | "LEN2000", | 199 | "LEN2000", /* S540 */ |
195 | "LEN2001", /* Edge E431 */ | 200 | "LEN2001", /* Edge E431 */ |
196 | "LEN2002", /* Edge E531 */ | 201 | "LEN2002", /* Edge E531 */ |
197 | "LEN2003", | 202 | "LEN2003", |
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index e43d48956dea..e1c7e9e51045 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -2930,6 +2930,7 @@ static void *alloc_coherent(struct device *dev, size_t size, | |||
2930 | size = PAGE_ALIGN(size); | 2930 | size = PAGE_ALIGN(size); |
2931 | dma_mask = dev->coherent_dma_mask; | 2931 | dma_mask = dev->coherent_dma_mask; |
2932 | flag &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32); | 2932 | flag &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32); |
2933 | flag |= __GFP_ZERO; | ||
2933 | 2934 | ||
2934 | page = alloc_pages(flag | __GFP_NOWARN, get_order(size)); | 2935 | page = alloc_pages(flag | __GFP_NOWARN, get_order(size)); |
2935 | if (!page) { | 2936 | if (!page) { |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 68d43beccb7e..5ecfaf29933a 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -422,6 +422,14 @@ static int dmar_map_gfx = 1; | |||
422 | static int dmar_forcedac; | 422 | static int dmar_forcedac; |
423 | static int intel_iommu_strict; | 423 | static int intel_iommu_strict; |
424 | static int intel_iommu_superpage = 1; | 424 | static int intel_iommu_superpage = 1; |
425 | static int intel_iommu_ecs = 1; | ||
426 | |||
427 | /* We only actually use ECS when PASID support (on the new bit 40) | ||
428 | * is also advertised. Some early implementations — the ones with | ||
429 | * PASID support on bit 28 — have issues even when we *only* use | ||
430 | * extended root/context tables. */ | ||
431 | #define ecs_enabled(iommu) (intel_iommu_ecs && ecap_ecs(iommu->ecap) && \ | ||
432 | ecap_pasid(iommu->ecap)) | ||
425 | 433 | ||
426 | int intel_iommu_gfx_mapped; | 434 | int intel_iommu_gfx_mapped; |
427 | EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped); | 435 | EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped); |
@@ -465,6 +473,10 @@ static int __init intel_iommu_setup(char *str) | |||
465 | printk(KERN_INFO | 473 | printk(KERN_INFO |
466 | "Intel-IOMMU: disable supported super page\n"); | 474 | "Intel-IOMMU: disable supported super page\n"); |
467 | intel_iommu_superpage = 0; | 475 | intel_iommu_superpage = 0; |
476 | } else if (!strncmp(str, "ecs_off", 7)) { | ||
477 | printk(KERN_INFO | ||
478 | "Intel-IOMMU: disable extended context table support\n"); | ||
479 | intel_iommu_ecs = 0; | ||
468 | } | 480 | } |
469 | 481 | ||
470 | str += strcspn(str, ","); | 482 | str += strcspn(str, ","); |
@@ -669,7 +681,7 @@ static inline struct context_entry *iommu_context_addr(struct intel_iommu *iommu | |||
669 | struct context_entry *context; | 681 | struct context_entry *context; |
670 | u64 *entry; | 682 | u64 *entry; |
671 | 683 | ||
672 | if (ecap_ecs(iommu->ecap)) { | 684 | if (ecs_enabled(iommu)) { |
673 | if (devfn >= 0x80) { | 685 | if (devfn >= 0x80) { |
674 | devfn -= 0x80; | 686 | devfn -= 0x80; |
675 | entry = &root->hi; | 687 | entry = &root->hi; |
@@ -696,6 +708,11 @@ static inline struct context_entry *iommu_context_addr(struct intel_iommu *iommu | |||
696 | return &context[devfn]; | 708 | return &context[devfn]; |
697 | } | 709 | } |
698 | 710 | ||
711 | static int iommu_dummy(struct device *dev) | ||
712 | { | ||
713 | return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO; | ||
714 | } | ||
715 | |||
699 | static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn) | 716 | static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn) |
700 | { | 717 | { |
701 | struct dmar_drhd_unit *drhd = NULL; | 718 | struct dmar_drhd_unit *drhd = NULL; |
@@ -705,6 +722,9 @@ static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devf | |||
705 | u16 segment = 0; | 722 | u16 segment = 0; |
706 | int i; | 723 | int i; |
707 | 724 | ||
725 | if (iommu_dummy(dev)) | ||
726 | return NULL; | ||
727 | |||
708 | if (dev_is_pci(dev)) { | 728 | if (dev_is_pci(dev)) { |
709 | pdev = to_pci_dev(dev); | 729 | pdev = to_pci_dev(dev); |
710 | segment = pci_domain_nr(pdev->bus); | 730 | segment = pci_domain_nr(pdev->bus); |
@@ -798,7 +818,7 @@ static void free_context_table(struct intel_iommu *iommu) | |||
798 | if (context) | 818 | if (context) |
799 | free_pgtable_page(context); | 819 | free_pgtable_page(context); |
800 | 820 | ||
801 | if (!ecap_ecs(iommu->ecap)) | 821 | if (!ecs_enabled(iommu)) |
802 | continue; | 822 | continue; |
803 | 823 | ||
804 | context = iommu_context_addr(iommu, i, 0x80, 0); | 824 | context = iommu_context_addr(iommu, i, 0x80, 0); |
@@ -1133,7 +1153,7 @@ static void iommu_set_root_entry(struct intel_iommu *iommu) | |||
1133 | unsigned long flag; | 1153 | unsigned long flag; |
1134 | 1154 | ||
1135 | addr = virt_to_phys(iommu->root_entry); | 1155 | addr = virt_to_phys(iommu->root_entry); |
1136 | if (ecap_ecs(iommu->ecap)) | 1156 | if (ecs_enabled(iommu)) |
1137 | addr |= DMA_RTADDR_RTT; | 1157 | addr |= DMA_RTADDR_RTT; |
1138 | 1158 | ||
1139 | raw_spin_lock_irqsave(&iommu->register_lock, flag); | 1159 | raw_spin_lock_irqsave(&iommu->register_lock, flag); |
@@ -2969,11 +2989,6 @@ static inline struct dmar_domain *get_valid_domain_for_dev(struct device *dev) | |||
2969 | return __get_valid_domain_for_dev(dev); | 2989 | return __get_valid_domain_for_dev(dev); |
2970 | } | 2990 | } |
2971 | 2991 | ||
2972 | static int iommu_dummy(struct device *dev) | ||
2973 | { | ||
2974 | return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO; | ||
2975 | } | ||
2976 | |||
2977 | /* Check if the dev needs to go through non-identity map and unmap process.*/ | 2992 | /* Check if the dev needs to go through non-identity map and unmap process.*/ |
2978 | static int iommu_no_mapping(struct device *dev) | 2993 | static int iommu_no_mapping(struct device *dev) |
2979 | { | 2994 | { |
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 57f09cb54464..269c2354c431 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c | |||
@@ -271,7 +271,7 @@ int gic_get_c0_fdc_int(void) | |||
271 | GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_FDC)); | 271 | GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_FDC)); |
272 | } | 272 | } |
273 | 273 | ||
274 | static void gic_handle_shared_int(void) | 274 | static void gic_handle_shared_int(bool chained) |
275 | { | 275 | { |
276 | unsigned int i, intr, virq; | 276 | unsigned int i, intr, virq; |
277 | unsigned long *pcpu_mask; | 277 | unsigned long *pcpu_mask; |
@@ -299,7 +299,10 @@ static void gic_handle_shared_int(void) | |||
299 | while (intr != gic_shared_intrs) { | 299 | while (intr != gic_shared_intrs) { |
300 | virq = irq_linear_revmap(gic_irq_domain, | 300 | virq = irq_linear_revmap(gic_irq_domain, |
301 | GIC_SHARED_TO_HWIRQ(intr)); | 301 | GIC_SHARED_TO_HWIRQ(intr)); |
302 | do_IRQ(virq); | 302 | if (chained) |
303 | generic_handle_irq(virq); | ||
304 | else | ||
305 | do_IRQ(virq); | ||
303 | 306 | ||
304 | /* go to next pending bit */ | 307 | /* go to next pending bit */ |
305 | bitmap_clear(pending, intr, 1); | 308 | bitmap_clear(pending, intr, 1); |
@@ -431,7 +434,7 @@ static struct irq_chip gic_edge_irq_controller = { | |||
431 | #endif | 434 | #endif |
432 | }; | 435 | }; |
433 | 436 | ||
434 | static void gic_handle_local_int(void) | 437 | static void gic_handle_local_int(bool chained) |
435 | { | 438 | { |
436 | unsigned long pending, masked; | 439 | unsigned long pending, masked; |
437 | unsigned int intr, virq; | 440 | unsigned int intr, virq; |
@@ -445,7 +448,10 @@ static void gic_handle_local_int(void) | |||
445 | while (intr != GIC_NUM_LOCAL_INTRS) { | 448 | while (intr != GIC_NUM_LOCAL_INTRS) { |
446 | virq = irq_linear_revmap(gic_irq_domain, | 449 | virq = irq_linear_revmap(gic_irq_domain, |
447 | GIC_LOCAL_TO_HWIRQ(intr)); | 450 | GIC_LOCAL_TO_HWIRQ(intr)); |
448 | do_IRQ(virq); | 451 | if (chained) |
452 | generic_handle_irq(virq); | ||
453 | else | ||
454 | do_IRQ(virq); | ||
449 | 455 | ||
450 | /* go to next pending bit */ | 456 | /* go to next pending bit */ |
451 | bitmap_clear(&pending, intr, 1); | 457 | bitmap_clear(&pending, intr, 1); |
@@ -509,13 +515,14 @@ static struct irq_chip gic_all_vpes_local_irq_controller = { | |||
509 | 515 | ||
510 | static void __gic_irq_dispatch(void) | 516 | static void __gic_irq_dispatch(void) |
511 | { | 517 | { |
512 | gic_handle_local_int(); | 518 | gic_handle_local_int(false); |
513 | gic_handle_shared_int(); | 519 | gic_handle_shared_int(false); |
514 | } | 520 | } |
515 | 521 | ||
516 | static void gic_irq_dispatch(unsigned int irq, struct irq_desc *desc) | 522 | static void gic_irq_dispatch(unsigned int irq, struct irq_desc *desc) |
517 | { | 523 | { |
518 | __gic_irq_dispatch(); | 524 | gic_handle_local_int(true); |
525 | gic_handle_shared_int(true); | ||
519 | } | 526 | } |
520 | 527 | ||
521 | #ifdef CONFIG_MIPS_GIC_IPI | 528 | #ifdef CONFIG_MIPS_GIC_IPI |
diff --git a/drivers/irqchip/irq-sunxi-nmi.c b/drivers/irqchip/irq-sunxi-nmi.c index 4a9ce5b50c5b..6b2b582433bd 100644 --- a/drivers/irqchip/irq-sunxi-nmi.c +++ b/drivers/irqchip/irq-sunxi-nmi.c | |||
@@ -104,7 +104,7 @@ static int sunxi_sc_nmi_set_type(struct irq_data *data, unsigned int flow_type) | |||
104 | irqd_set_trigger_type(data, flow_type); | 104 | irqd_set_trigger_type(data, flow_type); |
105 | irq_setup_alt_chip(data, flow_type); | 105 | irq_setup_alt_chip(data, flow_type); |
106 | 106 | ||
107 | for (i = 0; i <= gc->num_ct; i++, ct++) | 107 | for (i = 0; i < gc->num_ct; i++, ct++) |
108 | if (ct->type & flow_type) | 108 | if (ct->type & flow_type) |
109 | ctrl_off = ct->regs.type; | 109 | ctrl_off = ct->regs.type; |
110 | 110 | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index 27506302eb7a..4dbed4a67aaf 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -3834,7 +3834,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) | |||
3834 | err = -EBUSY; | 3834 | err = -EBUSY; |
3835 | } | 3835 | } |
3836 | spin_unlock(&mddev->lock); | 3836 | spin_unlock(&mddev->lock); |
3837 | return err; | 3837 | return err ?: len; |
3838 | } | 3838 | } |
3839 | err = mddev_lock(mddev); | 3839 | err = mddev_lock(mddev); |
3840 | if (err) | 3840 | if (err) |
@@ -4217,13 +4217,14 @@ action_store(struct mddev *mddev, const char *page, size_t len) | |||
4217 | set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); | 4217 | set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
4218 | else | 4218 | else |
4219 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); | 4219 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
4220 | flush_workqueue(md_misc_wq); | 4220 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && |
4221 | if (mddev->sync_thread) { | 4221 | mddev_lock(mddev) == 0) { |
4222 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | 4222 | flush_workqueue(md_misc_wq); |
4223 | if (mddev_lock(mddev) == 0) { | 4223 | if (mddev->sync_thread) { |
4224 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | ||
4224 | md_reap_sync_thread(mddev); | 4225 | md_reap_sync_thread(mddev); |
4225 | mddev_unlock(mddev); | ||
4226 | } | 4226 | } |
4227 | mddev_unlock(mddev); | ||
4227 | } | 4228 | } |
4228 | } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) || | 4229 | } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) || |
4229 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) | 4230 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) |
@@ -8261,6 +8262,7 @@ void md_reap_sync_thread(struct mddev *mddev) | |||
8261 | if (mddev_is_clustered(mddev)) | 8262 | if (mddev_is_clustered(mddev)) |
8262 | md_cluster_ops->metadata_update_finish(mddev); | 8263 | md_cluster_ops->metadata_update_finish(mddev); |
8263 | clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery); | 8264 | clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery); |
8265 | clear_bit(MD_RECOVERY_DONE, &mddev->recovery); | ||
8264 | clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); | 8266 | clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); |
8265 | clear_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); | 8267 | clear_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); |
8266 | clear_bit(MD_RECOVERY_REQUESTED, &mddev->recovery); | 8268 | clear_bit(MD_RECOVERY_REQUESTED, &mddev->recovery); |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index e793ab6b3570..f55c3f35b746 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -4156,6 +4156,7 @@ static int raid10_start_reshape(struct mddev *mddev) | |||
4156 | 4156 | ||
4157 | clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); | 4157 | clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); |
4158 | clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); | 4158 | clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); |
4159 | clear_bit(MD_RECOVERY_DONE, &mddev->recovery); | ||
4159 | set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); | 4160 | set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); |
4160 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); | 4161 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); |
4161 | 4162 | ||
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 553d54b87052..b6793d2e051f 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -7354,6 +7354,7 @@ static int raid5_start_reshape(struct mddev *mddev) | |||
7354 | 7354 | ||
7355 | clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); | 7355 | clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); |
7356 | clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); | 7356 | clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); |
7357 | clear_bit(MD_RECOVERY_DONE, &mddev->recovery); | ||
7357 | set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); | 7358 | set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); |
7358 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); | 7359 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); |
7359 | mddev->sync_thread = md_register_thread(md_do_sync, mddev, | 7360 | mddev->sync_thread = md_register_thread(md_do_sync, mddev, |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index db84ddcfec84..9fd6c69a8bac 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c | |||
@@ -423,7 +423,7 @@ static void xgbe_tx_timer(unsigned long data) | |||
423 | if (napi_schedule_prep(napi)) { | 423 | if (napi_schedule_prep(napi)) { |
424 | /* Disable Tx and Rx interrupts */ | 424 | /* Disable Tx and Rx interrupts */ |
425 | if (pdata->per_channel_irq) | 425 | if (pdata->per_channel_irq) |
426 | disable_irq(channel->dma_irq); | 426 | disable_irq_nosync(channel->dma_irq); |
427 | else | 427 | else |
428 | xgbe_disable_rx_tx_ints(pdata); | 428 | xgbe_disable_rx_tx_ints(pdata); |
429 | 429 | ||
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c index 77363d680532..a3b1c07ae0af 100644 --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c | |||
@@ -2464,6 +2464,7 @@ err_out_powerdown: | |||
2464 | ssb_bus_may_powerdown(sdev->bus); | 2464 | ssb_bus_may_powerdown(sdev->bus); |
2465 | 2465 | ||
2466 | err_out_free_dev: | 2466 | err_out_free_dev: |
2467 | netif_napi_del(&bp->napi); | ||
2467 | free_netdev(dev); | 2468 | free_netdev(dev); |
2468 | 2469 | ||
2469 | out: | 2470 | out: |
@@ -2480,6 +2481,7 @@ static void b44_remove_one(struct ssb_device *sdev) | |||
2480 | b44_unregister_phy_one(bp); | 2481 | b44_unregister_phy_one(bp); |
2481 | ssb_device_disable(sdev, 0); | 2482 | ssb_device_disable(sdev, 0); |
2482 | ssb_bus_may_powerdown(sdev->bus); | 2483 | ssb_bus_may_powerdown(sdev->bus); |
2484 | netif_napi_del(&bp->napi); | ||
2483 | free_netdev(dev); | 2485 | free_netdev(dev); |
2484 | ssb_pcihost_set_power_state(sdev, PCI_D3hot); | 2486 | ssb_pcihost_set_power_state(sdev, PCI_D3hot); |
2485 | ssb_set_drvdata(sdev, NULL); | 2487 | ssb_set_drvdata(sdev, NULL); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index a3b0f7a0c61e..1f82a04ce01a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | |||
@@ -1774,7 +1774,7 @@ struct bnx2x { | |||
1774 | int stats_state; | 1774 | int stats_state; |
1775 | 1775 | ||
1776 | /* used for synchronization of concurrent threads statistics handling */ | 1776 | /* used for synchronization of concurrent threads statistics handling */ |
1777 | struct mutex stats_lock; | 1777 | struct semaphore stats_lock; |
1778 | 1778 | ||
1779 | /* used by dmae command loader */ | 1779 | /* used by dmae command loader */ |
1780 | struct dmae_command stats_dmae; | 1780 | struct dmae_command stats_dmae; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index fd52ce95127e..33501bcddc48 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -12054,7 +12054,7 @@ static int bnx2x_init_bp(struct bnx2x *bp) | |||
12054 | mutex_init(&bp->port.phy_mutex); | 12054 | mutex_init(&bp->port.phy_mutex); |
12055 | mutex_init(&bp->fw_mb_mutex); | 12055 | mutex_init(&bp->fw_mb_mutex); |
12056 | mutex_init(&bp->drv_info_mutex); | 12056 | mutex_init(&bp->drv_info_mutex); |
12057 | mutex_init(&bp->stats_lock); | 12057 | sema_init(&bp->stats_lock, 1); |
12058 | bp->drv_info_mng_owner = false; | 12058 | bp->drv_info_mng_owner = false; |
12059 | 12059 | ||
12060 | INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); | 12060 | INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); |
@@ -13690,9 +13690,10 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) | |||
13690 | cancel_delayed_work_sync(&bp->sp_task); | 13690 | cancel_delayed_work_sync(&bp->sp_task); |
13691 | cancel_delayed_work_sync(&bp->period_task); | 13691 | cancel_delayed_work_sync(&bp->period_task); |
13692 | 13692 | ||
13693 | mutex_lock(&bp->stats_lock); | 13693 | if (!down_timeout(&bp->stats_lock, HZ / 10)) { |
13694 | bp->stats_state = STATS_STATE_DISABLED; | 13694 | bp->stats_state = STATS_STATE_DISABLED; |
13695 | mutex_unlock(&bp->stats_lock); | 13695 | up(&bp->stats_lock); |
13696 | } | ||
13696 | 13697 | ||
13697 | bnx2x_save_statistics(bp); | 13698 | bnx2x_save_statistics(bp); |
13698 | 13699 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 266b055c2360..69d699f0730a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c | |||
@@ -1372,19 +1372,23 @@ void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) | |||
1372 | * that context in case someone is in the middle of a transition. | 1372 | * that context in case someone is in the middle of a transition. |
1373 | * For other events, wait a bit until lock is taken. | 1373 | * For other events, wait a bit until lock is taken. |
1374 | */ | 1374 | */ |
1375 | if (!mutex_trylock(&bp->stats_lock)) { | 1375 | if (down_trylock(&bp->stats_lock)) { |
1376 | if (event == STATS_EVENT_UPDATE) | 1376 | if (event == STATS_EVENT_UPDATE) |
1377 | return; | 1377 | return; |
1378 | 1378 | ||
1379 | DP(BNX2X_MSG_STATS, | 1379 | DP(BNX2X_MSG_STATS, |
1380 | "Unlikely stats' lock contention [event %d]\n", event); | 1380 | "Unlikely stats' lock contention [event %d]\n", event); |
1381 | mutex_lock(&bp->stats_lock); | 1381 | if (unlikely(down_timeout(&bp->stats_lock, HZ / 10))) { |
1382 | BNX2X_ERR("Failed to take stats lock [event %d]\n", | ||
1383 | event); | ||
1384 | return; | ||
1385 | } | ||
1382 | } | 1386 | } |
1383 | 1387 | ||
1384 | bnx2x_stats_stm[state][event].action(bp); | 1388 | bnx2x_stats_stm[state][event].action(bp); |
1385 | bp->stats_state = bnx2x_stats_stm[state][event].next_state; | 1389 | bp->stats_state = bnx2x_stats_stm[state][event].next_state; |
1386 | 1390 | ||
1387 | mutex_unlock(&bp->stats_lock); | 1391 | up(&bp->stats_lock); |
1388 | 1392 | ||
1389 | if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) | 1393 | if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) |
1390 | DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", | 1394 | DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", |
@@ -1970,7 +1974,11 @@ int bnx2x_stats_safe_exec(struct bnx2x *bp, | |||
1970 | /* Wait for statistics to end [while blocking further requests], | 1974 | /* Wait for statistics to end [while blocking further requests], |
1971 | * then run supplied function 'safely'. | 1975 | * then run supplied function 'safely'. |
1972 | */ | 1976 | */ |
1973 | mutex_lock(&bp->stats_lock); | 1977 | rc = down_timeout(&bp->stats_lock, HZ / 10); |
1978 | if (unlikely(rc)) { | ||
1979 | BNX2X_ERR("Failed to take statistics lock for safe execution\n"); | ||
1980 | goto out_no_lock; | ||
1981 | } | ||
1974 | 1982 | ||
1975 | bnx2x_stats_comp(bp); | 1983 | bnx2x_stats_comp(bp); |
1976 | while (bp->stats_pending && cnt--) | 1984 | while (bp->stats_pending && cnt--) |
@@ -1988,7 +1996,7 @@ out: | |||
1988 | /* No need to restart statistics - if they're enabled, the timer | 1996 | /* No need to restart statistics - if they're enabled, the timer |
1989 | * will restart the statistics. | 1997 | * will restart the statistics. |
1990 | */ | 1998 | */ |
1991 | mutex_unlock(&bp->stats_lock); | 1999 | up(&bp->stats_lock); |
1992 | 2000 | out_no_lock: | |
1993 | return rc; | 2001 | return rc; |
1994 | } | 2002 | } |
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index e7651b3c6c57..420949cc55aa 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c | |||
@@ -299,9 +299,6 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) | |||
299 | phy_name = "external RGMII (no delay)"; | 299 | phy_name = "external RGMII (no delay)"; |
300 | else | 300 | else |
301 | phy_name = "external RGMII (TX delay)"; | 301 | phy_name = "external RGMII (TX delay)"; |
302 | reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL); | ||
303 | reg |= RGMII_MODE_EN | id_mode_dis; | ||
304 | bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL); | ||
305 | bcmgenet_sys_writel(priv, | 302 | bcmgenet_sys_writel(priv, |
306 | PORT_MODE_EXT_GPHY, SYS_PORT_CTRL); | 303 | PORT_MODE_EXT_GPHY, SYS_PORT_CTRL); |
307 | break; | 304 | break; |
@@ -310,6 +307,15 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) | |||
310 | return -EINVAL; | 307 | return -EINVAL; |
311 | } | 308 | } |
312 | 309 | ||
310 | /* This is an external PHY (xMII), so we need to enable the RGMII | ||
311 | * block for the interface to work | ||
312 | */ | ||
313 | if (priv->ext_phy) { | ||
314 | reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL); | ||
315 | reg |= RGMII_MODE_EN | id_mode_dis; | ||
316 | bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL); | ||
317 | } | ||
318 | |||
313 | if (init) | 319 | if (init) |
314 | dev_info(kdev, "configuring instance for %s\n", phy_name); | 320 | dev_info(kdev, "configuring instance for %s\n", phy_name); |
315 | 321 | ||
diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c index 594a2ab36d31..68f3c13c9ef6 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c +++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c | |||
@@ -2414,7 +2414,7 @@ bfa_ioc_boot(struct bfa_ioc *ioc, enum bfi_fwboot_type boot_type, | |||
2414 | if (status == BFA_STATUS_OK) | 2414 | if (status == BFA_STATUS_OK) |
2415 | bfa_ioc_lpu_start(ioc); | 2415 | bfa_ioc_lpu_start(ioc); |
2416 | else | 2416 | else |
2417 | bfa_nw_iocpf_timeout(ioc); | 2417 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT); |
2418 | 2418 | ||
2419 | return status; | 2419 | return status; |
2420 | } | 2420 | } |
@@ -3029,7 +3029,7 @@ bfa_ioc_poll_fwinit(struct bfa_ioc *ioc) | |||
3029 | } | 3029 | } |
3030 | 3030 | ||
3031 | if (ioc->iocpf.poll_time >= BFA_IOC_TOV) { | 3031 | if (ioc->iocpf.poll_time >= BFA_IOC_TOV) { |
3032 | bfa_nw_iocpf_timeout(ioc); | 3032 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT); |
3033 | } else { | 3033 | } else { |
3034 | ioc->iocpf.poll_time += BFA_IOC_POLL_TOV; | 3034 | ioc->iocpf.poll_time += BFA_IOC_POLL_TOV; |
3035 | mod_timer(&ioc->iocpf_timer, jiffies + | 3035 | mod_timer(&ioc->iocpf_timer, jiffies + |
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index 37072a83f9d6..caae6cb2bc1a 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c | |||
@@ -3701,10 +3701,6 @@ bnad_pci_probe(struct pci_dev *pdev, | |||
3701 | setup_timer(&bnad->bna.ioceth.ioc.sem_timer, bnad_iocpf_sem_timeout, | 3701 | setup_timer(&bnad->bna.ioceth.ioc.sem_timer, bnad_iocpf_sem_timeout, |
3702 | ((unsigned long)bnad)); | 3702 | ((unsigned long)bnad)); |
3703 | 3703 | ||
3704 | /* Now start the timer before calling IOC */ | ||
3705 | mod_timer(&bnad->bna.ioceth.ioc.iocpf_timer, | ||
3706 | jiffies + msecs_to_jiffies(BNA_IOC_TIMER_FREQ)); | ||
3707 | |||
3708 | /* | 3704 | /* |
3709 | * Start the chip | 3705 | * Start the chip |
3710 | * If the call back comes with error, we bail out. | 3706 | * If the call back comes with error, we bail out. |
diff --git a/drivers/net/ethernet/brocade/bna/cna_fwimg.c b/drivers/net/ethernet/brocade/bna/cna_fwimg.c index ebf462d8082f..badea368bdc8 100644 --- a/drivers/net/ethernet/brocade/bna/cna_fwimg.c +++ b/drivers/net/ethernet/brocade/bna/cna_fwimg.c | |||
@@ -30,6 +30,7 @@ cna_read_firmware(struct pci_dev *pdev, u32 **bfi_image, | |||
30 | u32 *bfi_image_size, char *fw_name) | 30 | u32 *bfi_image_size, char *fw_name) |
31 | { | 31 | { |
32 | const struct firmware *fw; | 32 | const struct firmware *fw; |
33 | u32 n; | ||
33 | 34 | ||
34 | if (request_firmware(&fw, fw_name, &pdev->dev)) { | 35 | if (request_firmware(&fw, fw_name, &pdev->dev)) { |
35 | pr_alert("Can't locate firmware %s\n", fw_name); | 36 | pr_alert("Can't locate firmware %s\n", fw_name); |
@@ -40,6 +41,12 @@ cna_read_firmware(struct pci_dev *pdev, u32 **bfi_image, | |||
40 | *bfi_image_size = fw->size/sizeof(u32); | 41 | *bfi_image_size = fw->size/sizeof(u32); |
41 | bfi_fw = fw; | 42 | bfi_fw = fw; |
42 | 43 | ||
44 | /* Convert loaded firmware to host order as it is stored in file | ||
45 | * as sequence of LE32 integers. | ||
46 | */ | ||
47 | for (n = 0; n < *bfi_image_size; n++) | ||
48 | le32_to_cpus(*bfi_image + n); | ||
49 | |||
43 | return *bfi_image; | 50 | return *bfi_image; |
44 | error: | 51 | error: |
45 | return NULL; | 52 | return NULL; |
diff --git a/drivers/net/ethernet/cisco/enic/enic_ethtool.c b/drivers/net/ethernet/cisco/enic/enic_ethtool.c index 28d9ca675a27..68d47b196dae 100644 --- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c +++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c | |||
@@ -131,8 +131,15 @@ static void enic_get_drvinfo(struct net_device *netdev, | |||
131 | { | 131 | { |
132 | struct enic *enic = netdev_priv(netdev); | 132 | struct enic *enic = netdev_priv(netdev); |
133 | struct vnic_devcmd_fw_info *fw_info; | 133 | struct vnic_devcmd_fw_info *fw_info; |
134 | int err; | ||
134 | 135 | ||
135 | enic_dev_fw_info(enic, &fw_info); | 136 | err = enic_dev_fw_info(enic, &fw_info); |
137 | /* return only when pci_zalloc_consistent fails in vnic_dev_fw_info | ||
138 | * For other failures, like devcmd failure, we return previously | ||
139 | * recorded info. | ||
140 | */ | ||
141 | if (err == -ENOMEM) | ||
142 | return; | ||
136 | 143 | ||
137 | strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); | 144 | strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); |
138 | strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); | 145 | strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); |
@@ -181,8 +188,15 @@ static void enic_get_ethtool_stats(struct net_device *netdev, | |||
181 | struct enic *enic = netdev_priv(netdev); | 188 | struct enic *enic = netdev_priv(netdev); |
182 | struct vnic_stats *vstats; | 189 | struct vnic_stats *vstats; |
183 | unsigned int i; | 190 | unsigned int i; |
184 | 191 | int err; | |
185 | enic_dev_stats_dump(enic, &vstats); | 192 | |
193 | err = enic_dev_stats_dump(enic, &vstats); | ||
194 | /* return only when pci_zalloc_consistent fails in vnic_dev_stats_dump | ||
195 | * For other failures, like devcmd failure, we return previously | ||
196 | * recorded stats. | ||
197 | */ | ||
198 | if (err == -ENOMEM) | ||
199 | return; | ||
186 | 200 | ||
187 | for (i = 0; i < enic_n_tx_stats; i++) | 201 | for (i = 0; i < enic_n_tx_stats; i++) |
188 | *(data++) = ((u64 *)&vstats->tx)[enic_tx_stats[i].index]; | 202 | *(data++) = ((u64 *)&vstats->tx)[enic_tx_stats[i].index]; |
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 204bd182473b..eadae1b412c6 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c | |||
@@ -615,8 +615,15 @@ static struct rtnl_link_stats64 *enic_get_stats(struct net_device *netdev, | |||
615 | { | 615 | { |
616 | struct enic *enic = netdev_priv(netdev); | 616 | struct enic *enic = netdev_priv(netdev); |
617 | struct vnic_stats *stats; | 617 | struct vnic_stats *stats; |
618 | int err; | ||
618 | 619 | ||
619 | enic_dev_stats_dump(enic, &stats); | 620 | err = enic_dev_stats_dump(enic, &stats); |
621 | /* return only when pci_zalloc_consistent fails in vnic_dev_stats_dump | ||
622 | * For other failures, like devcmd failure, we return previously | ||
623 | * recorded stats. | ||
624 | */ | ||
625 | if (err == -ENOMEM) | ||
626 | return net_stats; | ||
620 | 627 | ||
621 | net_stats->tx_packets = stats->tx.tx_frames_ok; | 628 | net_stats->tx_packets = stats->tx.tx_frames_ok; |
622 | net_stats->tx_bytes = stats->tx.tx_bytes_ok; | 629 | net_stats->tx_bytes = stats->tx.tx_bytes_ok; |
@@ -1407,6 +1414,7 @@ static int enic_poll_msix_rq(struct napi_struct *napi, int budget) | |||
1407 | */ | 1414 | */ |
1408 | enic_calc_int_moderation(enic, &enic->rq[rq]); | 1415 | enic_calc_int_moderation(enic, &enic->rq[rq]); |
1409 | 1416 | ||
1417 | enic_poll_unlock_napi(&enic->rq[rq]); | ||
1410 | if (work_done < work_to_do) { | 1418 | if (work_done < work_to_do) { |
1411 | 1419 | ||
1412 | /* Some work done, but not enough to stay in polling, | 1420 | /* Some work done, but not enough to stay in polling, |
@@ -1418,7 +1426,6 @@ static int enic_poll_msix_rq(struct napi_struct *napi, int budget) | |||
1418 | enic_set_int_moderation(enic, &enic->rq[rq]); | 1426 | enic_set_int_moderation(enic, &enic->rq[rq]); |
1419 | vnic_intr_unmask(&enic->intr[intr]); | 1427 | vnic_intr_unmask(&enic->intr[intr]); |
1420 | } | 1428 | } |
1421 | enic_poll_unlock_napi(&enic->rq[rq]); | ||
1422 | 1429 | ||
1423 | return work_done; | 1430 | return work_done; |
1424 | } | 1431 | } |
diff --git a/drivers/net/ethernet/cisco/enic/vnic_rq.c b/drivers/net/ethernet/cisco/enic/vnic_rq.c index 36a2ed606c91..c4b2183bf352 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_rq.c +++ b/drivers/net/ethernet/cisco/enic/vnic_rq.c | |||
@@ -188,16 +188,15 @@ void vnic_rq_clean(struct vnic_rq *rq, | |||
188 | struct vnic_rq_buf *buf; | 188 | struct vnic_rq_buf *buf; |
189 | u32 fetch_index; | 189 | u32 fetch_index; |
190 | unsigned int count = rq->ring.desc_count; | 190 | unsigned int count = rq->ring.desc_count; |
191 | int i; | ||
191 | 192 | ||
192 | buf = rq->to_clean; | 193 | buf = rq->to_clean; |
193 | 194 | ||
194 | while (vnic_rq_desc_used(rq) > 0) { | 195 | for (i = 0; i < rq->ring.desc_count; i++) { |
195 | |||
196 | (*buf_clean)(rq, buf); | 196 | (*buf_clean)(rq, buf); |
197 | 197 | buf = buf->next; | |
198 | buf = rq->to_clean = buf->next; | ||
199 | rq->ring.desc_avail++; | ||
200 | } | 198 | } |
199 | rq->ring.desc_avail = rq->ring.desc_count - 1; | ||
201 | 200 | ||
202 | /* Use current fetch_index as the ring starting point */ | 201 | /* Use current fetch_index as the ring starting point */ |
203 | fetch_index = ioread32(&rq->ctrl->fetch_index); | 202 | fetch_index = ioread32(&rq->ctrl->fetch_index); |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index fb140faeafb1..c5e1d0ac75f9 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -1720,9 +1720,9 @@ int be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf) | |||
1720 | total_size = buf_len; | 1720 | total_size = buf_len; |
1721 | 1721 | ||
1722 | get_fat_cmd.size = sizeof(struct be_cmd_req_get_fat) + 60*1024; | 1722 | get_fat_cmd.size = sizeof(struct be_cmd_req_get_fat) + 60*1024; |
1723 | get_fat_cmd.va = pci_alloc_consistent(adapter->pdev, | 1723 | get_fat_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, |
1724 | get_fat_cmd.size, | 1724 | get_fat_cmd.size, |
1725 | &get_fat_cmd.dma); | 1725 | &get_fat_cmd.dma, GFP_ATOMIC); |
1726 | if (!get_fat_cmd.va) { | 1726 | if (!get_fat_cmd.va) { |
1727 | dev_err(&adapter->pdev->dev, | 1727 | dev_err(&adapter->pdev->dev, |
1728 | "Memory allocation failure while reading FAT data\n"); | 1728 | "Memory allocation failure while reading FAT data\n"); |
@@ -1767,8 +1767,8 @@ int be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf) | |||
1767 | log_offset += buf_size; | 1767 | log_offset += buf_size; |
1768 | } | 1768 | } |
1769 | err: | 1769 | err: |
1770 | pci_free_consistent(adapter->pdev, get_fat_cmd.size, | 1770 | dma_free_coherent(&adapter->pdev->dev, get_fat_cmd.size, |
1771 | get_fat_cmd.va, get_fat_cmd.dma); | 1771 | get_fat_cmd.va, get_fat_cmd.dma); |
1772 | spin_unlock_bh(&adapter->mcc_lock); | 1772 | spin_unlock_bh(&adapter->mcc_lock); |
1773 | return status; | 1773 | return status; |
1774 | } | 1774 | } |
@@ -2215,12 +2215,12 @@ int be_cmd_read_port_transceiver_data(struct be_adapter *adapter, | |||
2215 | return -EINVAL; | 2215 | return -EINVAL; |
2216 | 2216 | ||
2217 | cmd.size = sizeof(struct be_cmd_resp_port_type); | 2217 | cmd.size = sizeof(struct be_cmd_resp_port_type); |
2218 | cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma); | 2218 | cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma, |
2219 | GFP_ATOMIC); | ||
2219 | if (!cmd.va) { | 2220 | if (!cmd.va) { |
2220 | dev_err(&adapter->pdev->dev, "Memory allocation failed\n"); | 2221 | dev_err(&adapter->pdev->dev, "Memory allocation failed\n"); |
2221 | return -ENOMEM; | 2222 | return -ENOMEM; |
2222 | } | 2223 | } |
2223 | memset(cmd.va, 0, cmd.size); | ||
2224 | 2224 | ||
2225 | spin_lock_bh(&adapter->mcc_lock); | 2225 | spin_lock_bh(&adapter->mcc_lock); |
2226 | 2226 | ||
@@ -2245,7 +2245,7 @@ int be_cmd_read_port_transceiver_data(struct be_adapter *adapter, | |||
2245 | } | 2245 | } |
2246 | err: | 2246 | err: |
2247 | spin_unlock_bh(&adapter->mcc_lock); | 2247 | spin_unlock_bh(&adapter->mcc_lock); |
2248 | pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma); | 2248 | dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma); |
2249 | return status; | 2249 | return status; |
2250 | } | 2250 | } |
2251 | 2251 | ||
@@ -2720,7 +2720,8 @@ int be_cmd_get_phy_info(struct be_adapter *adapter) | |||
2720 | goto err; | 2720 | goto err; |
2721 | } | 2721 | } |
2722 | cmd.size = sizeof(struct be_cmd_req_get_phy_info); | 2722 | cmd.size = sizeof(struct be_cmd_req_get_phy_info); |
2723 | cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma); | 2723 | cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma, |
2724 | GFP_ATOMIC); | ||
2724 | if (!cmd.va) { | 2725 | if (!cmd.va) { |
2725 | dev_err(&adapter->pdev->dev, "Memory alloc failure\n"); | 2726 | dev_err(&adapter->pdev->dev, "Memory alloc failure\n"); |
2726 | status = -ENOMEM; | 2727 | status = -ENOMEM; |
@@ -2754,7 +2755,7 @@ int be_cmd_get_phy_info(struct be_adapter *adapter) | |||
2754 | BE_SUPPORTED_SPEED_1GBPS; | 2755 | BE_SUPPORTED_SPEED_1GBPS; |
2755 | } | 2756 | } |
2756 | } | 2757 | } |
2757 | pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma); | 2758 | dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma); |
2758 | err: | 2759 | err: |
2759 | spin_unlock_bh(&adapter->mcc_lock); | 2760 | spin_unlock_bh(&adapter->mcc_lock); |
2760 | return status; | 2761 | return status; |
@@ -2805,8 +2806,9 @@ int be_cmd_get_cntl_attributes(struct be_adapter *adapter) | |||
2805 | 2806 | ||
2806 | memset(&attribs_cmd, 0, sizeof(struct be_dma_mem)); | 2807 | memset(&attribs_cmd, 0, sizeof(struct be_dma_mem)); |
2807 | attribs_cmd.size = sizeof(struct be_cmd_resp_cntl_attribs); | 2808 | attribs_cmd.size = sizeof(struct be_cmd_resp_cntl_attribs); |
2808 | attribs_cmd.va = pci_alloc_consistent(adapter->pdev, attribs_cmd.size, | 2809 | attribs_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, |
2809 | &attribs_cmd.dma); | 2810 | attribs_cmd.size, |
2811 | &attribs_cmd.dma, GFP_ATOMIC); | ||
2810 | if (!attribs_cmd.va) { | 2812 | if (!attribs_cmd.va) { |
2811 | dev_err(&adapter->pdev->dev, "Memory allocation failure\n"); | 2813 | dev_err(&adapter->pdev->dev, "Memory allocation failure\n"); |
2812 | status = -ENOMEM; | 2814 | status = -ENOMEM; |
@@ -2833,8 +2835,8 @@ int be_cmd_get_cntl_attributes(struct be_adapter *adapter) | |||
2833 | err: | 2835 | err: |
2834 | mutex_unlock(&adapter->mbox_lock); | 2836 | mutex_unlock(&adapter->mbox_lock); |
2835 | if (attribs_cmd.va) | 2837 | if (attribs_cmd.va) |
2836 | pci_free_consistent(adapter->pdev, attribs_cmd.size, | 2838 | dma_free_coherent(&adapter->pdev->dev, attribs_cmd.size, |
2837 | attribs_cmd.va, attribs_cmd.dma); | 2839 | attribs_cmd.va, attribs_cmd.dma); |
2838 | return status; | 2840 | return status; |
2839 | } | 2841 | } |
2840 | 2842 | ||
@@ -2972,9 +2974,10 @@ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, | |||
2972 | 2974 | ||
2973 | memset(&get_mac_list_cmd, 0, sizeof(struct be_dma_mem)); | 2975 | memset(&get_mac_list_cmd, 0, sizeof(struct be_dma_mem)); |
2974 | get_mac_list_cmd.size = sizeof(struct be_cmd_resp_get_mac_list); | 2976 | get_mac_list_cmd.size = sizeof(struct be_cmd_resp_get_mac_list); |
2975 | get_mac_list_cmd.va = pci_alloc_consistent(adapter->pdev, | 2977 | get_mac_list_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, |
2976 | get_mac_list_cmd.size, | 2978 | get_mac_list_cmd.size, |
2977 | &get_mac_list_cmd.dma); | 2979 | &get_mac_list_cmd.dma, |
2980 | GFP_ATOMIC); | ||
2978 | 2981 | ||
2979 | if (!get_mac_list_cmd.va) { | 2982 | if (!get_mac_list_cmd.va) { |
2980 | dev_err(&adapter->pdev->dev, | 2983 | dev_err(&adapter->pdev->dev, |
@@ -3047,8 +3050,8 @@ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, | |||
3047 | 3050 | ||
3048 | out: | 3051 | out: |
3049 | spin_unlock_bh(&adapter->mcc_lock); | 3052 | spin_unlock_bh(&adapter->mcc_lock); |
3050 | pci_free_consistent(adapter->pdev, get_mac_list_cmd.size, | 3053 | dma_free_coherent(&adapter->pdev->dev, get_mac_list_cmd.size, |
3051 | get_mac_list_cmd.va, get_mac_list_cmd.dma); | 3054 | get_mac_list_cmd.va, get_mac_list_cmd.dma); |
3052 | return status; | 3055 | return status; |
3053 | } | 3056 | } |
3054 | 3057 | ||
@@ -3101,8 +3104,8 @@ int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, | |||
3101 | 3104 | ||
3102 | memset(&cmd, 0, sizeof(struct be_dma_mem)); | 3105 | memset(&cmd, 0, sizeof(struct be_dma_mem)); |
3103 | cmd.size = sizeof(struct be_cmd_req_set_mac_list); | 3106 | cmd.size = sizeof(struct be_cmd_req_set_mac_list); |
3104 | cmd.va = dma_alloc_coherent(&adapter->pdev->dev, cmd.size, | 3107 | cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma, |
3105 | &cmd.dma, GFP_KERNEL); | 3108 | GFP_KERNEL); |
3106 | if (!cmd.va) | 3109 | if (!cmd.va) |
3107 | return -ENOMEM; | 3110 | return -ENOMEM; |
3108 | 3111 | ||
@@ -3291,7 +3294,8 @@ int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter) | |||
3291 | 3294 | ||
3292 | memset(&cmd, 0, sizeof(struct be_dma_mem)); | 3295 | memset(&cmd, 0, sizeof(struct be_dma_mem)); |
3293 | cmd.size = sizeof(struct be_cmd_resp_acpi_wol_magic_config_v1); | 3296 | cmd.size = sizeof(struct be_cmd_resp_acpi_wol_magic_config_v1); |
3294 | cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma); | 3297 | cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma, |
3298 | GFP_ATOMIC); | ||
3295 | if (!cmd.va) { | 3299 | if (!cmd.va) { |
3296 | dev_err(&adapter->pdev->dev, "Memory allocation failure\n"); | 3300 | dev_err(&adapter->pdev->dev, "Memory allocation failure\n"); |
3297 | status = -ENOMEM; | 3301 | status = -ENOMEM; |
@@ -3326,7 +3330,8 @@ int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter) | |||
3326 | err: | 3330 | err: |
3327 | mutex_unlock(&adapter->mbox_lock); | 3331 | mutex_unlock(&adapter->mbox_lock); |
3328 | if (cmd.va) | 3332 | if (cmd.va) |
3329 | pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma); | 3333 | dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, |
3334 | cmd.dma); | ||
3330 | return status; | 3335 | return status; |
3331 | 3336 | ||
3332 | } | 3337 | } |
@@ -3340,8 +3345,9 @@ int be_cmd_set_fw_log_level(struct be_adapter *adapter, u32 level) | |||
3340 | 3345 | ||
3341 | memset(&extfat_cmd, 0, sizeof(struct be_dma_mem)); | 3346 | memset(&extfat_cmd, 0, sizeof(struct be_dma_mem)); |
3342 | extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps); | 3347 | extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps); |
3343 | extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size, | 3348 | extfat_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, |
3344 | &extfat_cmd.dma); | 3349 | extfat_cmd.size, &extfat_cmd.dma, |
3350 | GFP_ATOMIC); | ||
3345 | if (!extfat_cmd.va) | 3351 | if (!extfat_cmd.va) |
3346 | return -ENOMEM; | 3352 | return -ENOMEM; |
3347 | 3353 | ||
@@ -3363,8 +3369,8 @@ int be_cmd_set_fw_log_level(struct be_adapter *adapter, u32 level) | |||
3363 | 3369 | ||
3364 | status = be_cmd_set_ext_fat_capabilites(adapter, &extfat_cmd, cfgs); | 3370 | status = be_cmd_set_ext_fat_capabilites(adapter, &extfat_cmd, cfgs); |
3365 | err: | 3371 | err: |
3366 | pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va, | 3372 | dma_free_coherent(&adapter->pdev->dev, extfat_cmd.size, extfat_cmd.va, |
3367 | extfat_cmd.dma); | 3373 | extfat_cmd.dma); |
3368 | return status; | 3374 | return status; |
3369 | } | 3375 | } |
3370 | 3376 | ||
@@ -3377,8 +3383,9 @@ int be_cmd_get_fw_log_level(struct be_adapter *adapter) | |||
3377 | 3383 | ||
3378 | memset(&extfat_cmd, 0, sizeof(struct be_dma_mem)); | 3384 | memset(&extfat_cmd, 0, sizeof(struct be_dma_mem)); |
3379 | extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps); | 3385 | extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps); |
3380 | extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size, | 3386 | extfat_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, |
3381 | &extfat_cmd.dma); | 3387 | extfat_cmd.size, &extfat_cmd.dma, |
3388 | GFP_ATOMIC); | ||
3382 | 3389 | ||
3383 | if (!extfat_cmd.va) { | 3390 | if (!extfat_cmd.va) { |
3384 | dev_err(&adapter->pdev->dev, "%s: Memory allocation failure\n", | 3391 | dev_err(&adapter->pdev->dev, "%s: Memory allocation failure\n", |
@@ -3396,8 +3403,8 @@ int be_cmd_get_fw_log_level(struct be_adapter *adapter) | |||
3396 | level = cfgs->module[0].trace_lvl[j].dbg_lvl; | 3403 | level = cfgs->module[0].trace_lvl[j].dbg_lvl; |
3397 | } | 3404 | } |
3398 | } | 3405 | } |
3399 | pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va, | 3406 | dma_free_coherent(&adapter->pdev->dev, extfat_cmd.size, extfat_cmd.va, |
3400 | extfat_cmd.dma); | 3407 | extfat_cmd.dma); |
3401 | err: | 3408 | err: |
3402 | return level; | 3409 | return level; |
3403 | } | 3410 | } |
@@ -3595,7 +3602,8 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res) | |||
3595 | 3602 | ||
3596 | memset(&cmd, 0, sizeof(struct be_dma_mem)); | 3603 | memset(&cmd, 0, sizeof(struct be_dma_mem)); |
3597 | cmd.size = sizeof(struct be_cmd_resp_get_func_config); | 3604 | cmd.size = sizeof(struct be_cmd_resp_get_func_config); |
3598 | cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma); | 3605 | cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma, |
3606 | GFP_ATOMIC); | ||
3599 | if (!cmd.va) { | 3607 | if (!cmd.va) { |
3600 | dev_err(&adapter->pdev->dev, "Memory alloc failure\n"); | 3608 | dev_err(&adapter->pdev->dev, "Memory alloc failure\n"); |
3601 | status = -ENOMEM; | 3609 | status = -ENOMEM; |
@@ -3635,7 +3643,8 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res) | |||
3635 | err: | 3643 | err: |
3636 | mutex_unlock(&adapter->mbox_lock); | 3644 | mutex_unlock(&adapter->mbox_lock); |
3637 | if (cmd.va) | 3645 | if (cmd.va) |
3638 | pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma); | 3646 | dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, |
3647 | cmd.dma); | ||
3639 | return status; | 3648 | return status; |
3640 | } | 3649 | } |
3641 | 3650 | ||
@@ -3656,7 +3665,8 @@ int be_cmd_get_profile_config(struct be_adapter *adapter, | |||
3656 | 3665 | ||
3657 | memset(&cmd, 0, sizeof(struct be_dma_mem)); | 3666 | memset(&cmd, 0, sizeof(struct be_dma_mem)); |
3658 | cmd.size = sizeof(struct be_cmd_resp_get_profile_config); | 3667 | cmd.size = sizeof(struct be_cmd_resp_get_profile_config); |
3659 | cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma); | 3668 | cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma, |
3669 | GFP_ATOMIC); | ||
3660 | if (!cmd.va) | 3670 | if (!cmd.va) |
3661 | return -ENOMEM; | 3671 | return -ENOMEM; |
3662 | 3672 | ||
@@ -3702,7 +3712,8 @@ int be_cmd_get_profile_config(struct be_adapter *adapter, | |||
3702 | res->vf_if_cap_flags = vf_res->cap_flags; | 3712 | res->vf_if_cap_flags = vf_res->cap_flags; |
3703 | err: | 3713 | err: |
3704 | if (cmd.va) | 3714 | if (cmd.va) |
3705 | pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma); | 3715 | dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, |
3716 | cmd.dma); | ||
3706 | return status; | 3717 | return status; |
3707 | } | 3718 | } |
3708 | 3719 | ||
@@ -3717,7 +3728,8 @@ static int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc, | |||
3717 | 3728 | ||
3718 | memset(&cmd, 0, sizeof(struct be_dma_mem)); | 3729 | memset(&cmd, 0, sizeof(struct be_dma_mem)); |
3719 | cmd.size = sizeof(struct be_cmd_req_set_profile_config); | 3730 | cmd.size = sizeof(struct be_cmd_req_set_profile_config); |
3720 | cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma); | 3731 | cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma, |
3732 | GFP_ATOMIC); | ||
3721 | if (!cmd.va) | 3733 | if (!cmd.va) |
3722 | return -ENOMEM; | 3734 | return -ENOMEM; |
3723 | 3735 | ||
@@ -3733,7 +3745,8 @@ static int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc, | |||
3733 | status = be_cmd_notify_wait(adapter, &wrb); | 3745 | status = be_cmd_notify_wait(adapter, &wrb); |
3734 | 3746 | ||
3735 | if (cmd.va) | 3747 | if (cmd.va) |
3736 | pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma); | 3748 | dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, |
3749 | cmd.dma); | ||
3737 | return status; | 3750 | return status; |
3738 | } | 3751 | } |
3739 | 3752 | ||
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index b765c24625bf..2835dee5dc39 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c | |||
@@ -264,8 +264,8 @@ static int lancer_cmd_read_file(struct be_adapter *adapter, u8 *file_name, | |||
264 | int status = 0; | 264 | int status = 0; |
265 | 265 | ||
266 | read_cmd.size = LANCER_READ_FILE_CHUNK; | 266 | read_cmd.size = LANCER_READ_FILE_CHUNK; |
267 | read_cmd.va = pci_alloc_consistent(adapter->pdev, read_cmd.size, | 267 | read_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, read_cmd.size, |
268 | &read_cmd.dma); | 268 | &read_cmd.dma, GFP_ATOMIC); |
269 | 269 | ||
270 | if (!read_cmd.va) { | 270 | if (!read_cmd.va) { |
271 | dev_err(&adapter->pdev->dev, | 271 | dev_err(&adapter->pdev->dev, |
@@ -289,8 +289,8 @@ static int lancer_cmd_read_file(struct be_adapter *adapter, u8 *file_name, | |||
289 | break; | 289 | break; |
290 | } | 290 | } |
291 | } | 291 | } |
292 | pci_free_consistent(adapter->pdev, read_cmd.size, read_cmd.va, | 292 | dma_free_coherent(&adapter->pdev->dev, read_cmd.size, read_cmd.va, |
293 | read_cmd.dma); | 293 | read_cmd.dma); |
294 | 294 | ||
295 | return status; | 295 | return status; |
296 | } | 296 | } |
@@ -818,8 +818,9 @@ static int be_test_ddr_dma(struct be_adapter *adapter) | |||
818 | }; | 818 | }; |
819 | 819 | ||
820 | ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test); | 820 | ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test); |
821 | ddrdma_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, ddrdma_cmd.size, | 821 | ddrdma_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, |
822 | &ddrdma_cmd.dma, GFP_KERNEL); | 822 | ddrdma_cmd.size, &ddrdma_cmd.dma, |
823 | GFP_KERNEL); | ||
823 | if (!ddrdma_cmd.va) | 824 | if (!ddrdma_cmd.va) |
824 | return -ENOMEM; | 825 | return -ENOMEM; |
825 | 826 | ||
@@ -941,8 +942,9 @@ static int be_read_eeprom(struct net_device *netdev, | |||
941 | 942 | ||
942 | memset(&eeprom_cmd, 0, sizeof(struct be_dma_mem)); | 943 | memset(&eeprom_cmd, 0, sizeof(struct be_dma_mem)); |
943 | eeprom_cmd.size = sizeof(struct be_cmd_req_seeprom_read); | 944 | eeprom_cmd.size = sizeof(struct be_cmd_req_seeprom_read); |
944 | eeprom_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, eeprom_cmd.size, | 945 | eeprom_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, |
945 | &eeprom_cmd.dma, GFP_KERNEL); | 946 | eeprom_cmd.size, &eeprom_cmd.dma, |
947 | GFP_KERNEL); | ||
946 | 948 | ||
947 | if (!eeprom_cmd.va) | 949 | if (!eeprom_cmd.va) |
948 | return -ENOMEM; | 950 | return -ENOMEM; |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 6f9ffb9026cd..e43cc8a73ea7 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -4605,8 +4605,8 @@ static int lancer_fw_download(struct be_adapter *adapter, | |||
4605 | 4605 | ||
4606 | flash_cmd.size = sizeof(struct lancer_cmd_req_write_object) | 4606 | flash_cmd.size = sizeof(struct lancer_cmd_req_write_object) |
4607 | + LANCER_FW_DOWNLOAD_CHUNK; | 4607 | + LANCER_FW_DOWNLOAD_CHUNK; |
4608 | flash_cmd.va = dma_alloc_coherent(dev, flash_cmd.size, | 4608 | flash_cmd.va = dma_zalloc_coherent(dev, flash_cmd.size, |
4609 | &flash_cmd.dma, GFP_KERNEL); | 4609 | &flash_cmd.dma, GFP_KERNEL); |
4610 | if (!flash_cmd.va) | 4610 | if (!flash_cmd.va) |
4611 | return -ENOMEM; | 4611 | return -ENOMEM; |
4612 | 4612 | ||
@@ -4739,8 +4739,8 @@ static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw) | |||
4739 | } | 4739 | } |
4740 | 4740 | ||
4741 | flash_cmd.size = sizeof(struct be_cmd_write_flashrom); | 4741 | flash_cmd.size = sizeof(struct be_cmd_write_flashrom); |
4742 | flash_cmd.va = dma_alloc_coherent(dev, flash_cmd.size, &flash_cmd.dma, | 4742 | flash_cmd.va = dma_zalloc_coherent(dev, flash_cmd.size, &flash_cmd.dma, |
4743 | GFP_KERNEL); | 4743 | GFP_KERNEL); |
4744 | if (!flash_cmd.va) | 4744 | if (!flash_cmd.va) |
4745 | return -ENOMEM; | 4745 | return -ENOMEM; |
4746 | 4746 | ||
@@ -5291,16 +5291,15 @@ static int be_drv_init(struct be_adapter *adapter) | |||
5291 | int status = 0; | 5291 | int status = 0; |
5292 | 5292 | ||
5293 | mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16; | 5293 | mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16; |
5294 | mbox_mem_alloc->va = dma_alloc_coherent(dev, mbox_mem_alloc->size, | 5294 | mbox_mem_alloc->va = dma_zalloc_coherent(dev, mbox_mem_alloc->size, |
5295 | &mbox_mem_alloc->dma, | 5295 | &mbox_mem_alloc->dma, |
5296 | GFP_KERNEL); | 5296 | GFP_KERNEL); |
5297 | if (!mbox_mem_alloc->va) | 5297 | if (!mbox_mem_alloc->va) |
5298 | return -ENOMEM; | 5298 | return -ENOMEM; |
5299 | 5299 | ||
5300 | mbox_mem_align->size = sizeof(struct be_mcc_mailbox); | 5300 | mbox_mem_align->size = sizeof(struct be_mcc_mailbox); |
5301 | mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16); | 5301 | mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16); |
5302 | mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16); | 5302 | mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16); |
5303 | memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox)); | ||
5304 | 5303 | ||
5305 | rx_filter->size = sizeof(struct be_cmd_req_rx_filter); | 5304 | rx_filter->size = sizeof(struct be_cmd_req_rx_filter); |
5306 | rx_filter->va = dma_zalloc_coherent(dev, rx_filter->size, | 5305 | rx_filter->va = dma_zalloc_coherent(dev, rx_filter->size, |
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 33c35d3b7420..5d47307121ab 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h | |||
@@ -317,6 +317,7 @@ struct i40e_pf { | |||
317 | #endif | 317 | #endif |
318 | #define I40E_FLAG_PORT_ID_VALID (u64)(1 << 28) | 318 | #define I40E_FLAG_PORT_ID_VALID (u64)(1 << 28) |
319 | #define I40E_FLAG_DCB_CAPABLE (u64)(1 << 29) | 319 | #define I40E_FLAG_DCB_CAPABLE (u64)(1 << 29) |
320 | #define I40E_FLAG_VEB_MODE_ENABLED BIT_ULL(40) | ||
320 | 321 | ||
321 | /* tracks features that get auto disabled by errors */ | 322 | /* tracks features that get auto disabled by errors */ |
322 | u64 auto_disable_flags; | 323 | u64 auto_disable_flags; |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c index 34170eabca7d..da0faf478af0 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c | |||
@@ -1021,6 +1021,15 @@ static ssize_t i40e_dbg_command_write(struct file *filp, | |||
1021 | goto command_write_done; | 1021 | goto command_write_done; |
1022 | } | 1022 | } |
1023 | 1023 | ||
1024 | /* By default we are in VEPA mode, if this is the first VF/VMDq | ||
1025 | * VSI to be added switch to VEB mode. | ||
1026 | */ | ||
1027 | if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) { | ||
1028 | pf->flags |= I40E_FLAG_VEB_MODE_ENABLED; | ||
1029 | i40e_do_reset_safe(pf, | ||
1030 | BIT_ULL(__I40E_PF_RESET_REQUESTED)); | ||
1031 | } | ||
1032 | |||
1024 | vsi = i40e_vsi_setup(pf, I40E_VSI_VMDQ2, vsi_seid, 0); | 1033 | vsi = i40e_vsi_setup(pf, I40E_VSI_VMDQ2, vsi_seid, 0); |
1025 | if (vsi) | 1034 | if (vsi) |
1026 | dev_info(&pf->pdev->dev, "added VSI %d to relay %d\n", | 1035 | dev_info(&pf->pdev->dev, "added VSI %d to relay %d\n", |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index a54c14491e3b..5b5bea159bd5 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c | |||
@@ -6097,6 +6097,10 @@ static int i40e_reconstitute_veb(struct i40e_veb *veb) | |||
6097 | if (ret) | 6097 | if (ret) |
6098 | goto end_reconstitute; | 6098 | goto end_reconstitute; |
6099 | 6099 | ||
6100 | if (pf->flags & I40E_FLAG_VEB_MODE_ENABLED) | ||
6101 | veb->bridge_mode = BRIDGE_MODE_VEB; | ||
6102 | else | ||
6103 | veb->bridge_mode = BRIDGE_MODE_VEPA; | ||
6100 | i40e_config_bridge_mode(veb); | 6104 | i40e_config_bridge_mode(veb); |
6101 | 6105 | ||
6102 | /* create the remaining VSIs attached to this VEB */ | 6106 | /* create the remaining VSIs attached to this VEB */ |
@@ -8031,7 +8035,12 @@ static int i40e_ndo_bridge_setlink(struct net_device *dev, | |||
8031 | } else if (mode != veb->bridge_mode) { | 8035 | } else if (mode != veb->bridge_mode) { |
8032 | /* Existing HW bridge but different mode needs reset */ | 8036 | /* Existing HW bridge but different mode needs reset */ |
8033 | veb->bridge_mode = mode; | 8037 | veb->bridge_mode = mode; |
8034 | i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED)); | 8038 | /* TODO: If no VFs or VMDq VSIs, disallow VEB mode */ |
8039 | if (mode == BRIDGE_MODE_VEB) | ||
8040 | pf->flags |= I40E_FLAG_VEB_MODE_ENABLED; | ||
8041 | else | ||
8042 | pf->flags &= ~I40E_FLAG_VEB_MODE_ENABLED; | ||
8043 | i40e_do_reset(pf, BIT_ULL(__I40E_PF_RESET_REQUESTED)); | ||
8035 | break; | 8044 | break; |
8036 | } | 8045 | } |
8037 | } | 8046 | } |
@@ -8343,11 +8352,12 @@ static int i40e_add_vsi(struct i40e_vsi *vsi) | |||
8343 | ctxt.uplink_seid = vsi->uplink_seid; | 8352 | ctxt.uplink_seid = vsi->uplink_seid; |
8344 | ctxt.connection_type = I40E_AQ_VSI_CONN_TYPE_NORMAL; | 8353 | ctxt.connection_type = I40E_AQ_VSI_CONN_TYPE_NORMAL; |
8345 | ctxt.flags = I40E_AQ_VSI_TYPE_PF; | 8354 | ctxt.flags = I40E_AQ_VSI_TYPE_PF; |
8346 | if (i40e_is_vsi_uplink_mode_veb(vsi)) { | 8355 | if ((pf->flags & I40E_FLAG_VEB_MODE_ENABLED) && |
8356 | (i40e_is_vsi_uplink_mode_veb(vsi))) { | ||
8347 | ctxt.info.valid_sections |= | 8357 | ctxt.info.valid_sections |= |
8348 | cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID); | 8358 | cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID); |
8349 | ctxt.info.switch_id = | 8359 | ctxt.info.switch_id = |
8350 | cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB); | 8360 | cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB); |
8351 | } | 8361 | } |
8352 | i40e_vsi_setup_queue_map(vsi, &ctxt, enabled_tc, true); | 8362 | i40e_vsi_setup_queue_map(vsi, &ctxt, enabled_tc, true); |
8353 | break; | 8363 | break; |
@@ -8746,6 +8756,14 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type, | |||
8746 | __func__); | 8756 | __func__); |
8747 | return NULL; | 8757 | return NULL; |
8748 | } | 8758 | } |
8759 | /* We come up by default in VEPA mode if SRIOV is not | ||
8760 | * already enabled, in which case we can't force VEPA | ||
8761 | * mode. | ||
8762 | */ | ||
8763 | if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) { | ||
8764 | veb->bridge_mode = BRIDGE_MODE_VEPA; | ||
8765 | pf->flags &= ~I40E_FLAG_VEB_MODE_ENABLED; | ||
8766 | } | ||
8749 | i40e_config_bridge_mode(veb); | 8767 | i40e_config_bridge_mode(veb); |
8750 | } | 8768 | } |
8751 | for (i = 0; i < I40E_MAX_VEB && !veb; i++) { | 8769 | for (i = 0; i < I40E_MAX_VEB && !veb; i++) { |
@@ -9856,6 +9874,15 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
9856 | goto err_switch_setup; | 9874 | goto err_switch_setup; |
9857 | } | 9875 | } |
9858 | 9876 | ||
9877 | #ifdef CONFIG_PCI_IOV | ||
9878 | /* prep for VF support */ | ||
9879 | if ((pf->flags & I40E_FLAG_SRIOV_ENABLED) && | ||
9880 | (pf->flags & I40E_FLAG_MSIX_ENABLED) && | ||
9881 | !test_bit(__I40E_BAD_EEPROM, &pf->state)) { | ||
9882 | if (pci_num_vf(pdev)) | ||
9883 | pf->flags |= I40E_FLAG_VEB_MODE_ENABLED; | ||
9884 | } | ||
9885 | #endif | ||
9859 | err = i40e_setup_pf_switch(pf, false); | 9886 | err = i40e_setup_pf_switch(pf, false); |
9860 | if (err) { | 9887 | if (err) { |
9861 | dev_info(&pdev->dev, "setup_pf_switch failed: %d\n", err); | 9888 | dev_info(&pdev->dev, "setup_pf_switch failed: %d\n", err); |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 4bd3a80aba82..9d95042d5a0f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c | |||
@@ -2410,14 +2410,12 @@ static int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size) | |||
2410 | * i40e_chk_linearize - Check if there are more than 8 fragments per packet | 2410 | * i40e_chk_linearize - Check if there are more than 8 fragments per packet |
2411 | * @skb: send buffer | 2411 | * @skb: send buffer |
2412 | * @tx_flags: collected send information | 2412 | * @tx_flags: collected send information |
2413 | * @hdr_len: size of the packet header | ||
2414 | * | 2413 | * |
2415 | * Note: Our HW can't scatter-gather more than 8 fragments to build | 2414 | * Note: Our HW can't scatter-gather more than 8 fragments to build |
2416 | * a packet on the wire and so we need to figure out the cases where we | 2415 | * a packet on the wire and so we need to figure out the cases where we |
2417 | * need to linearize the skb. | 2416 | * need to linearize the skb. |
2418 | **/ | 2417 | **/ |
2419 | static bool i40e_chk_linearize(struct sk_buff *skb, u32 tx_flags, | 2418 | static bool i40e_chk_linearize(struct sk_buff *skb, u32 tx_flags) |
2420 | const u8 hdr_len) | ||
2421 | { | 2419 | { |
2422 | struct skb_frag_struct *frag; | 2420 | struct skb_frag_struct *frag; |
2423 | bool linearize = false; | 2421 | bool linearize = false; |
@@ -2429,7 +2427,7 @@ static bool i40e_chk_linearize(struct sk_buff *skb, u32 tx_flags, | |||
2429 | gso_segs = skb_shinfo(skb)->gso_segs; | 2427 | gso_segs = skb_shinfo(skb)->gso_segs; |
2430 | 2428 | ||
2431 | if (tx_flags & (I40E_TX_FLAGS_TSO | I40E_TX_FLAGS_FSO)) { | 2429 | if (tx_flags & (I40E_TX_FLAGS_TSO | I40E_TX_FLAGS_FSO)) { |
2432 | u16 j = 1; | 2430 | u16 j = 0; |
2433 | 2431 | ||
2434 | if (num_frags < (I40E_MAX_BUFFER_TXD)) | 2432 | if (num_frags < (I40E_MAX_BUFFER_TXD)) |
2435 | goto linearize_chk_done; | 2433 | goto linearize_chk_done; |
@@ -2440,21 +2438,18 @@ static bool i40e_chk_linearize(struct sk_buff *skb, u32 tx_flags, | |||
2440 | goto linearize_chk_done; | 2438 | goto linearize_chk_done; |
2441 | } | 2439 | } |
2442 | frag = &skb_shinfo(skb)->frags[0]; | 2440 | frag = &skb_shinfo(skb)->frags[0]; |
2443 | size = hdr_len; | ||
2444 | /* we might still have more fragments per segment */ | 2441 | /* we might still have more fragments per segment */ |
2445 | do { | 2442 | do { |
2446 | size += skb_frag_size(frag); | 2443 | size += skb_frag_size(frag); |
2447 | frag++; j++; | 2444 | frag++; j++; |
2445 | if ((size >= skb_shinfo(skb)->gso_size) && | ||
2446 | (j < I40E_MAX_BUFFER_TXD)) { | ||
2447 | size = (size % skb_shinfo(skb)->gso_size); | ||
2448 | j = (size) ? 1 : 0; | ||
2449 | } | ||
2448 | if (j == I40E_MAX_BUFFER_TXD) { | 2450 | if (j == I40E_MAX_BUFFER_TXD) { |
2449 | if (size < skb_shinfo(skb)->gso_size) { | 2451 | linearize = true; |
2450 | linearize = true; | 2452 | break; |
2451 | break; | ||
2452 | } | ||
2453 | j = 1; | ||
2454 | size -= skb_shinfo(skb)->gso_size; | ||
2455 | if (size) | ||
2456 | j++; | ||
2457 | size += hdr_len; | ||
2458 | } | 2453 | } |
2459 | num_frags--; | 2454 | num_frags--; |
2460 | } while (num_frags); | 2455 | } while (num_frags); |
@@ -2724,7 +2719,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb, | |||
2724 | if (tsyn) | 2719 | if (tsyn) |
2725 | tx_flags |= I40E_TX_FLAGS_TSYN; | 2720 | tx_flags |= I40E_TX_FLAGS_TSYN; |
2726 | 2721 | ||
2727 | if (i40e_chk_linearize(skb, tx_flags, hdr_len)) | 2722 | if (i40e_chk_linearize(skb, tx_flags)) |
2728 | if (skb_linearize(skb)) | 2723 | if (skb_linearize(skb)) |
2729 | goto out_drop; | 2724 | goto out_drop; |
2730 | 2725 | ||
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 78d1c4ff565e..4e9376da0518 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | |||
@@ -1018,11 +1018,19 @@ int i40e_pci_sriov_configure(struct pci_dev *pdev, int num_vfs) | |||
1018 | { | 1018 | { |
1019 | struct i40e_pf *pf = pci_get_drvdata(pdev); | 1019 | struct i40e_pf *pf = pci_get_drvdata(pdev); |
1020 | 1020 | ||
1021 | if (num_vfs) | 1021 | if (num_vfs) { |
1022 | if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) { | ||
1023 | pf->flags |= I40E_FLAG_VEB_MODE_ENABLED; | ||
1024 | i40e_do_reset_safe(pf, | ||
1025 | BIT_ULL(__I40E_PF_RESET_REQUESTED)); | ||
1026 | } | ||
1022 | return i40e_pci_sriov_enable(pdev, num_vfs); | 1027 | return i40e_pci_sriov_enable(pdev, num_vfs); |
1028 | } | ||
1023 | 1029 | ||
1024 | if (!pci_vfs_assigned(pf->pdev)) { | 1030 | if (!pci_vfs_assigned(pf->pdev)) { |
1025 | i40e_free_vfs(pf); | 1031 | i40e_free_vfs(pf); |
1032 | pf->flags &= ~I40E_FLAG_VEB_MODE_ENABLED; | ||
1033 | i40e_do_reset_safe(pf, BIT_ULL(__I40E_PF_RESET_REQUESTED)); | ||
1026 | } else { | 1034 | } else { |
1027 | dev_warn(&pdev->dev, "Unable to free VFs because some are assigned to VMs.\n"); | 1035 | dev_warn(&pdev->dev, "Unable to free VFs because some are assigned to VMs.\n"); |
1028 | return -EINVAL; | 1036 | return -EINVAL; |
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c index b077e02a0cc7..458fbb421090 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c | |||
@@ -1619,14 +1619,12 @@ static void i40e_create_tx_ctx(struct i40e_ring *tx_ring, | |||
1619 | * i40e_chk_linearize - Check if there are more than 8 fragments per packet | 1619 | * i40e_chk_linearize - Check if there are more than 8 fragments per packet |
1620 | * @skb: send buffer | 1620 | * @skb: send buffer |
1621 | * @tx_flags: collected send information | 1621 | * @tx_flags: collected send information |
1622 | * @hdr_len: size of the packet header | ||
1623 | * | 1622 | * |
1624 | * Note: Our HW can't scatter-gather more than 8 fragments to build | 1623 | * Note: Our HW can't scatter-gather more than 8 fragments to build |
1625 | * a packet on the wire and so we need to figure out the cases where we | 1624 | * a packet on the wire and so we need to figure out the cases where we |
1626 | * need to linearize the skb. | 1625 | * need to linearize the skb. |
1627 | **/ | 1626 | **/ |
1628 | static bool i40e_chk_linearize(struct sk_buff *skb, u32 tx_flags, | 1627 | static bool i40e_chk_linearize(struct sk_buff *skb, u32 tx_flags) |
1629 | const u8 hdr_len) | ||
1630 | { | 1628 | { |
1631 | struct skb_frag_struct *frag; | 1629 | struct skb_frag_struct *frag; |
1632 | bool linearize = false; | 1630 | bool linearize = false; |
@@ -1638,7 +1636,7 @@ static bool i40e_chk_linearize(struct sk_buff *skb, u32 tx_flags, | |||
1638 | gso_segs = skb_shinfo(skb)->gso_segs; | 1636 | gso_segs = skb_shinfo(skb)->gso_segs; |
1639 | 1637 | ||
1640 | if (tx_flags & (I40E_TX_FLAGS_TSO | I40E_TX_FLAGS_FSO)) { | 1638 | if (tx_flags & (I40E_TX_FLAGS_TSO | I40E_TX_FLAGS_FSO)) { |
1641 | u16 j = 1; | 1639 | u16 j = 0; |
1642 | 1640 | ||
1643 | if (num_frags < (I40E_MAX_BUFFER_TXD)) | 1641 | if (num_frags < (I40E_MAX_BUFFER_TXD)) |
1644 | goto linearize_chk_done; | 1642 | goto linearize_chk_done; |
@@ -1649,21 +1647,18 @@ static bool i40e_chk_linearize(struct sk_buff *skb, u32 tx_flags, | |||
1649 | goto linearize_chk_done; | 1647 | goto linearize_chk_done; |
1650 | } | 1648 | } |
1651 | frag = &skb_shinfo(skb)->frags[0]; | 1649 | frag = &skb_shinfo(skb)->frags[0]; |
1652 | size = hdr_len; | ||
1653 | /* we might still have more fragments per segment */ | 1650 | /* we might still have more fragments per segment */ |
1654 | do { | 1651 | do { |
1655 | size += skb_frag_size(frag); | 1652 | size += skb_frag_size(frag); |
1656 | frag++; j++; | 1653 | frag++; j++; |
1654 | if ((size >= skb_shinfo(skb)->gso_size) && | ||
1655 | (j < I40E_MAX_BUFFER_TXD)) { | ||
1656 | size = (size % skb_shinfo(skb)->gso_size); | ||
1657 | j = (size) ? 1 : 0; | ||
1658 | } | ||
1657 | if (j == I40E_MAX_BUFFER_TXD) { | 1659 | if (j == I40E_MAX_BUFFER_TXD) { |
1658 | if (size < skb_shinfo(skb)->gso_size) { | 1660 | linearize = true; |
1659 | linearize = true; | 1661 | break; |
1660 | break; | ||
1661 | } | ||
1662 | j = 1; | ||
1663 | size -= skb_shinfo(skb)->gso_size; | ||
1664 | if (size) | ||
1665 | j++; | ||
1666 | size += hdr_len; | ||
1667 | } | 1662 | } |
1668 | num_frags--; | 1663 | num_frags--; |
1669 | } while (num_frags); | 1664 | } while (num_frags); |
@@ -1950,7 +1945,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb, | |||
1950 | else if (tso) | 1945 | else if (tso) |
1951 | tx_flags |= I40E_TX_FLAGS_TSO; | 1946 | tx_flags |= I40E_TX_FLAGS_TSO; |
1952 | 1947 | ||
1953 | if (i40e_chk_linearize(skb, tx_flags, hdr_len)) | 1948 | if (i40e_chk_linearize(skb, tx_flags)) |
1954 | if (skb_linearize(skb)) | 1949 | if (skb_linearize(skb)) |
1955 | goto out_drop; | 1950 | goto out_drop; |
1956 | 1951 | ||
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index e3b9b63ad010..c3a9392cbc19 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c | |||
@@ -538,8 +538,8 @@ static int igb_ptp_feature_enable_i210(struct ptp_clock_info *ptp, | |||
538 | igb->perout[i].start.tv_nsec = rq->perout.start.nsec; | 538 | igb->perout[i].start.tv_nsec = rq->perout.start.nsec; |
539 | igb->perout[i].period.tv_sec = ts.tv_sec; | 539 | igb->perout[i].period.tv_sec = ts.tv_sec; |
540 | igb->perout[i].period.tv_nsec = ts.tv_nsec; | 540 | igb->perout[i].period.tv_nsec = ts.tv_nsec; |
541 | wr32(trgttiml, rq->perout.start.sec); | 541 | wr32(trgttimh, rq->perout.start.sec); |
542 | wr32(trgttimh, rq->perout.start.nsec); | 542 | wr32(trgttiml, rq->perout.start.nsec); |
543 | tsauxc |= tsauxc_mask; | 543 | tsauxc |= tsauxc_mask; |
544 | tsim |= tsim_mask; | 544 | tsim |= tsim_mask; |
545 | } else { | 545 | } else { |
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index c0ad95d2f63d..809ea4610a77 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c | |||
@@ -224,12 +224,17 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx, | |||
224 | } | 224 | } |
225 | } | 225 | } |
226 | 226 | ||
227 | static void efx_free_rx_buffer(struct efx_rx_buffer *rx_buf) | 227 | static void efx_free_rx_buffers(struct efx_rx_queue *rx_queue, |
228 | struct efx_rx_buffer *rx_buf, | ||
229 | unsigned int num_bufs) | ||
228 | { | 230 | { |
229 | if (rx_buf->page) { | 231 | do { |
230 | put_page(rx_buf->page); | 232 | if (rx_buf->page) { |
231 | rx_buf->page = NULL; | 233 | put_page(rx_buf->page); |
232 | } | 234 | rx_buf->page = NULL; |
235 | } | ||
236 | rx_buf = efx_rx_buf_next(rx_queue, rx_buf); | ||
237 | } while (--num_bufs); | ||
233 | } | 238 | } |
234 | 239 | ||
235 | /* Attempt to recycle the page if there is an RX recycle ring; the page can | 240 | /* Attempt to recycle the page if there is an RX recycle ring; the page can |
@@ -278,7 +283,7 @@ static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue, | |||
278 | /* If this is the last buffer in a page, unmap and free it. */ | 283 | /* If this is the last buffer in a page, unmap and free it. */ |
279 | if (rx_buf->flags & EFX_RX_BUF_LAST_IN_PAGE) { | 284 | if (rx_buf->flags & EFX_RX_BUF_LAST_IN_PAGE) { |
280 | efx_unmap_rx_buffer(rx_queue->efx, rx_buf); | 285 | efx_unmap_rx_buffer(rx_queue->efx, rx_buf); |
281 | efx_free_rx_buffer(rx_buf); | 286 | efx_free_rx_buffers(rx_queue, rx_buf, 1); |
282 | } | 287 | } |
283 | rx_buf->page = NULL; | 288 | rx_buf->page = NULL; |
284 | } | 289 | } |
@@ -304,10 +309,7 @@ static void efx_discard_rx_packet(struct efx_channel *channel, | |||
304 | 309 | ||
305 | efx_recycle_rx_pages(channel, rx_buf, n_frags); | 310 | efx_recycle_rx_pages(channel, rx_buf, n_frags); |
306 | 311 | ||
307 | do { | 312 | efx_free_rx_buffers(rx_queue, rx_buf, n_frags); |
308 | efx_free_rx_buffer(rx_buf); | ||
309 | rx_buf = efx_rx_buf_next(rx_queue, rx_buf); | ||
310 | } while (--n_frags); | ||
311 | } | 313 | } |
312 | 314 | ||
313 | /** | 315 | /** |
@@ -431,11 +433,10 @@ efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf, | |||
431 | 433 | ||
432 | skb = napi_get_frags(napi); | 434 | skb = napi_get_frags(napi); |
433 | if (unlikely(!skb)) { | 435 | if (unlikely(!skb)) { |
434 | while (n_frags--) { | 436 | struct efx_rx_queue *rx_queue; |
435 | put_page(rx_buf->page); | 437 | |
436 | rx_buf->page = NULL; | 438 | rx_queue = efx_channel_get_rx_queue(channel); |
437 | rx_buf = efx_rx_buf_next(&channel->rx_queue, rx_buf); | 439 | efx_free_rx_buffers(rx_queue, rx_buf, n_frags); |
438 | } | ||
439 | return; | 440 | return; |
440 | } | 441 | } |
441 | 442 | ||
@@ -622,7 +623,10 @@ static void efx_rx_deliver(struct efx_channel *channel, u8 *eh, | |||
622 | 623 | ||
623 | skb = efx_rx_mk_skb(channel, rx_buf, n_frags, eh, hdr_len); | 624 | skb = efx_rx_mk_skb(channel, rx_buf, n_frags, eh, hdr_len); |
624 | if (unlikely(skb == NULL)) { | 625 | if (unlikely(skb == NULL)) { |
625 | efx_free_rx_buffer(rx_buf); | 626 | struct efx_rx_queue *rx_queue; |
627 | |||
628 | rx_queue = efx_channel_get_rx_queue(channel); | ||
629 | efx_free_rx_buffers(rx_queue, rx_buf, n_frags); | ||
626 | return; | 630 | return; |
627 | } | 631 | } |
628 | skb_record_rx_queue(skb, channel->rx_queue.core_index); | 632 | skb_record_rx_queue(skb, channel->rx_queue.core_index); |
@@ -661,8 +665,12 @@ void __efx_rx_packet(struct efx_channel *channel) | |||
661 | * loopback layer, and free the rx_buf here | 665 | * loopback layer, and free the rx_buf here |
662 | */ | 666 | */ |
663 | if (unlikely(efx->loopback_selftest)) { | 667 | if (unlikely(efx->loopback_selftest)) { |
668 | struct efx_rx_queue *rx_queue; | ||
669 | |||
664 | efx_loopback_rx_packet(efx, eh, rx_buf->len); | 670 | efx_loopback_rx_packet(efx, eh, rx_buf->len); |
665 | efx_free_rx_buffer(rx_buf); | 671 | rx_queue = efx_channel_get_rx_queue(channel); |
672 | efx_free_rx_buffers(rx_queue, rx_buf, | ||
673 | channel->rx_pkt_n_frags); | ||
666 | goto out; | 674 | goto out; |
667 | } | 675 | } |
668 | 676 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c index 4ec9811f49c8..65efb1468988 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c | |||
@@ -511,11 +511,9 @@ static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx, | |||
511 | msgbuf->rx_pktids, | 511 | msgbuf->rx_pktids, |
512 | msgbuf->ioctl_resp_pktid); | 512 | msgbuf->ioctl_resp_pktid); |
513 | if (msgbuf->ioctl_resp_ret_len != 0) { | 513 | if (msgbuf->ioctl_resp_ret_len != 0) { |
514 | if (!skb) { | 514 | if (!skb) |
515 | brcmf_err("Invalid packet id idx recv'd %d\n", | ||
516 | msgbuf->ioctl_resp_pktid); | ||
517 | return -EBADF; | 515 | return -EBADF; |
518 | } | 516 | |
519 | memcpy(buf, skb->data, (len < msgbuf->ioctl_resp_ret_len) ? | 517 | memcpy(buf, skb->data, (len < msgbuf->ioctl_resp_ret_len) ? |
520 | len : msgbuf->ioctl_resp_ret_len); | 518 | len : msgbuf->ioctl_resp_ret_len); |
521 | } | 519 | } |
@@ -874,10 +872,8 @@ brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf *msgbuf, void *buf) | |||
874 | flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS; | 872 | flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS; |
875 | skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, | 873 | skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, |
876 | msgbuf->tx_pktids, idx); | 874 | msgbuf->tx_pktids, idx); |
877 | if (!skb) { | 875 | if (!skb) |
878 | brcmf_err("Invalid packet id idx recv'd %d\n", idx); | ||
879 | return; | 876 | return; |
880 | } | ||
881 | 877 | ||
882 | set_bit(flowid, msgbuf->txstatus_done_map); | 878 | set_bit(flowid, msgbuf->txstatus_done_map); |
883 | commonring = msgbuf->flowrings[flowid]; | 879 | commonring = msgbuf->flowrings[flowid]; |
@@ -1156,6 +1152,8 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf) | |||
1156 | 1152 | ||
1157 | skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, | 1153 | skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, |
1158 | msgbuf->rx_pktids, idx); | 1154 | msgbuf->rx_pktids, idx); |
1155 | if (!skb) | ||
1156 | return; | ||
1159 | 1157 | ||
1160 | if (data_offset) | 1158 | if (data_offset) |
1161 | skb_pull(skb, data_offset); | 1159 | skb_pull(skb, data_offset); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 75e96db6626b..8e604a3931ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
@@ -471,7 +471,7 @@ static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw, | |||
471 | if (cfg->device_family != IWL_DEVICE_FAMILY_8000) | 471 | if (cfg->device_family != IWL_DEVICE_FAMILY_8000) |
472 | return le16_to_cpup(nvm_sw + RADIO_CFG); | 472 | return le16_to_cpup(nvm_sw + RADIO_CFG); |
473 | 473 | ||
474 | return le32_to_cpup((__le32 *)(nvm_sw + RADIO_CFG_FAMILY_8000)); | 474 | return le32_to_cpup((__le32 *)(phy_sku + RADIO_CFG_FAMILY_8000)); |
475 | 475 | ||
476 | } | 476 | } |
477 | 477 | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index 01996c9d98a7..376b84e54ad7 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2015 Intel Corporation. All rights reserved. |
4 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | 4 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
5 | * | 5 | * |
6 | * Portions of this file are derived from the ipw3945 project, as well | 6 | * Portions of this file are derived from the ipw3945 project, as well |
7 | * as portions of the ieee80211 subsystem header files. | 7 | * as portions of the ieee80211 subsystem header files. |
@@ -320,7 +320,7 @@ struct iwl_trans_pcie { | |||
320 | 320 | ||
321 | /*protect hw register */ | 321 | /*protect hw register */ |
322 | spinlock_t reg_lock; | 322 | spinlock_t reg_lock; |
323 | bool cmd_in_flight; | 323 | bool cmd_hold_nic_awake; |
324 | bool ref_cmd_in_flight; | 324 | bool ref_cmd_in_flight; |
325 | 325 | ||
326 | /* protect ref counter */ | 326 | /* protect ref counter */ |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index d6f6515fe663..dc179094e6a0 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -1372,7 +1372,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent, | |||
1372 | 1372 | ||
1373 | spin_lock_irqsave(&trans_pcie->reg_lock, *flags); | 1373 | spin_lock_irqsave(&trans_pcie->reg_lock, *flags); |
1374 | 1374 | ||
1375 | if (trans_pcie->cmd_in_flight) | 1375 | if (trans_pcie->cmd_hold_nic_awake) |
1376 | goto out; | 1376 | goto out; |
1377 | 1377 | ||
1378 | /* this bit wakes up the NIC */ | 1378 | /* this bit wakes up the NIC */ |
@@ -1438,7 +1438,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans, | |||
1438 | */ | 1438 | */ |
1439 | __acquire(&trans_pcie->reg_lock); | 1439 | __acquire(&trans_pcie->reg_lock); |
1440 | 1440 | ||
1441 | if (trans_pcie->cmd_in_flight) | 1441 | if (trans_pcie->cmd_hold_nic_awake) |
1442 | goto out; | 1442 | goto out; |
1443 | 1443 | ||
1444 | __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, | 1444 | __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, |
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 06952aadfd7b..5ef8044c2ea3 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -1039,18 +1039,14 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, | |||
1039 | iwl_trans_pcie_ref(trans); | 1039 | iwl_trans_pcie_ref(trans); |
1040 | } | 1040 | } |
1041 | 1041 | ||
1042 | if (trans_pcie->cmd_in_flight) | ||
1043 | return 0; | ||
1044 | |||
1045 | trans_pcie->cmd_in_flight = true; | ||
1046 | |||
1047 | /* | 1042 | /* |
1048 | * wake up the NIC to make sure that the firmware will see the host | 1043 | * wake up the NIC to make sure that the firmware will see the host |
1049 | * command - we will let the NIC sleep once all the host commands | 1044 | * command - we will let the NIC sleep once all the host commands |
1050 | * returned. This needs to be done only on NICs that have | 1045 | * returned. This needs to be done only on NICs that have |
1051 | * apmg_wake_up_wa set. | 1046 | * apmg_wake_up_wa set. |
1052 | */ | 1047 | */ |
1053 | if (trans->cfg->base_params->apmg_wake_up_wa) { | 1048 | if (trans->cfg->base_params->apmg_wake_up_wa && |
1049 | !trans_pcie->cmd_hold_nic_awake) { | ||
1054 | __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, | 1050 | __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, |
1055 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 1051 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
1056 | if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) | 1052 | if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) |
@@ -1064,10 +1060,10 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, | |||
1064 | if (ret < 0) { | 1060 | if (ret < 0) { |
1065 | __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, | 1061 | __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, |
1066 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 1062 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
1067 | trans_pcie->cmd_in_flight = false; | ||
1068 | IWL_ERR(trans, "Failed to wake NIC for hcmd\n"); | 1063 | IWL_ERR(trans, "Failed to wake NIC for hcmd\n"); |
1069 | return -EIO; | 1064 | return -EIO; |
1070 | } | 1065 | } |
1066 | trans_pcie->cmd_hold_nic_awake = true; | ||
1071 | } | 1067 | } |
1072 | 1068 | ||
1073 | return 0; | 1069 | return 0; |
@@ -1085,15 +1081,14 @@ static int iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans) | |||
1085 | iwl_trans_pcie_unref(trans); | 1081 | iwl_trans_pcie_unref(trans); |
1086 | } | 1082 | } |
1087 | 1083 | ||
1088 | if (WARN_ON(!trans_pcie->cmd_in_flight)) | 1084 | if (trans->cfg->base_params->apmg_wake_up_wa) { |
1089 | return 0; | 1085 | if (WARN_ON(!trans_pcie->cmd_hold_nic_awake)) |
1090 | 1086 | return 0; | |
1091 | trans_pcie->cmd_in_flight = false; | ||
1092 | 1087 | ||
1093 | if (trans->cfg->base_params->apmg_wake_up_wa) | 1088 | trans_pcie->cmd_hold_nic_awake = false; |
1094 | __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, | 1089 | __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, |
1095 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 1090 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
1096 | 1091 | } | |
1097 | return 0; | 1092 | return 0; |
1098 | } | 1093 | } |
1099 | 1094 | ||
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 4de46aa61d95..0d2594395ffb 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
@@ -1250,7 +1250,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, | |||
1250 | netdev_err(queue->vif->dev, | 1250 | netdev_err(queue->vif->dev, |
1251 | "txreq.offset: %x, size: %u, end: %lu\n", | 1251 | "txreq.offset: %x, size: %u, end: %lu\n", |
1252 | txreq.offset, txreq.size, | 1252 | txreq.offset, txreq.size, |
1253 | (txreq.offset&~PAGE_MASK) + txreq.size); | 1253 | (unsigned long)(txreq.offset&~PAGE_MASK) + txreq.size); |
1254 | xenvif_fatal_tx_err(queue->vif); | 1254 | xenvif_fatal_tx_err(queue->vif); |
1255 | break; | 1255 | break; |
1256 | } | 1256 | } |
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index fee02414529e..968787abf78d 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c | |||
@@ -34,6 +34,8 @@ struct backend_info { | |||
34 | enum xenbus_state frontend_state; | 34 | enum xenbus_state frontend_state; |
35 | struct xenbus_watch hotplug_status_watch; | 35 | struct xenbus_watch hotplug_status_watch; |
36 | u8 have_hotplug_status_watch:1; | 36 | u8 have_hotplug_status_watch:1; |
37 | |||
38 | const char *hotplug_script; | ||
37 | }; | 39 | }; |
38 | 40 | ||
39 | static int connect_rings(struct backend_info *be, struct xenvif_queue *queue); | 41 | static int connect_rings(struct backend_info *be, struct xenvif_queue *queue); |
@@ -238,6 +240,7 @@ static int netback_remove(struct xenbus_device *dev) | |||
238 | xenvif_free(be->vif); | 240 | xenvif_free(be->vif); |
239 | be->vif = NULL; | 241 | be->vif = NULL; |
240 | } | 242 | } |
243 | kfree(be->hotplug_script); | ||
241 | kfree(be); | 244 | kfree(be); |
242 | dev_set_drvdata(&dev->dev, NULL); | 245 | dev_set_drvdata(&dev->dev, NULL); |
243 | return 0; | 246 | return 0; |
@@ -255,6 +258,7 @@ static int netback_probe(struct xenbus_device *dev, | |||
255 | struct xenbus_transaction xbt; | 258 | struct xenbus_transaction xbt; |
256 | int err; | 259 | int err; |
257 | int sg; | 260 | int sg; |
261 | const char *script; | ||
258 | struct backend_info *be = kzalloc(sizeof(struct backend_info), | 262 | struct backend_info *be = kzalloc(sizeof(struct backend_info), |
259 | GFP_KERNEL); | 263 | GFP_KERNEL); |
260 | if (!be) { | 264 | if (!be) { |
@@ -347,6 +351,15 @@ static int netback_probe(struct xenbus_device *dev, | |||
347 | if (err) | 351 | if (err) |
348 | pr_debug("Error writing multi-queue-max-queues\n"); | 352 | pr_debug("Error writing multi-queue-max-queues\n"); |
349 | 353 | ||
354 | script = xenbus_read(XBT_NIL, dev->nodename, "script", NULL); | ||
355 | if (IS_ERR(script)) { | ||
356 | err = PTR_ERR(script); | ||
357 | xenbus_dev_fatal(dev, err, "reading script"); | ||
358 | goto fail; | ||
359 | } | ||
360 | |||
361 | be->hotplug_script = script; | ||
362 | |||
350 | err = xenbus_switch_state(dev, XenbusStateInitWait); | 363 | err = xenbus_switch_state(dev, XenbusStateInitWait); |
351 | if (err) | 364 | if (err) |
352 | goto fail; | 365 | goto fail; |
@@ -379,22 +392,14 @@ static int netback_uevent(struct xenbus_device *xdev, | |||
379 | struct kobj_uevent_env *env) | 392 | struct kobj_uevent_env *env) |
380 | { | 393 | { |
381 | struct backend_info *be = dev_get_drvdata(&xdev->dev); | 394 | struct backend_info *be = dev_get_drvdata(&xdev->dev); |
382 | char *val; | ||
383 | 395 | ||
384 | val = xenbus_read(XBT_NIL, xdev->nodename, "script", NULL); | 396 | if (!be) |
385 | if (IS_ERR(val)) { | 397 | return 0; |
386 | int err = PTR_ERR(val); | 398 | |
387 | xenbus_dev_fatal(xdev, err, "reading script"); | 399 | if (add_uevent_var(env, "script=%s", be->hotplug_script)) |
388 | return err; | 400 | return -ENOMEM; |
389 | } else { | ||
390 | if (add_uevent_var(env, "script=%s", val)) { | ||
391 | kfree(val); | ||
392 | return -ENOMEM; | ||
393 | } | ||
394 | kfree(val); | ||
395 | } | ||
396 | 401 | ||
397 | if (!be || !be->vif) | 402 | if (!be->vif) |
398 | return 0; | 403 | return 0; |
399 | 404 | ||
400 | return add_uevent_var(env, "vif=%s", be->vif->dev->name); | 405 | return add_uevent_var(env, "vif=%s", be->vif->dev->name); |
diff --git a/drivers/ntb/ntb_hw.c b/drivers/ntb/ntb_hw.c index cd29b1038c5e..15f9b7c9e4d3 100644 --- a/drivers/ntb/ntb_hw.c +++ b/drivers/ntb/ntb_hw.c | |||
@@ -1660,6 +1660,7 @@ static int ntb_atom_detect(struct ntb_device *ndev) | |||
1660 | u32 ppd; | 1660 | u32 ppd; |
1661 | 1661 | ||
1662 | ndev->hw_type = BWD_HW; | 1662 | ndev->hw_type = BWD_HW; |
1663 | ndev->limits.max_mw = BWD_MAX_MW; | ||
1663 | 1664 | ||
1664 | rc = pci_read_config_dword(ndev->pdev, NTB_PPD_OFFSET, &ppd); | 1665 | rc = pci_read_config_dword(ndev->pdev, NTB_PPD_OFFSET, &ppd); |
1665 | if (rc) | 1666 | if (rc) |
@@ -1778,7 +1779,7 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1778 | dev_warn(&pdev->dev, "Cannot remap BAR %d\n", | 1779 | dev_warn(&pdev->dev, "Cannot remap BAR %d\n", |
1779 | MW_TO_BAR(i)); | 1780 | MW_TO_BAR(i)); |
1780 | rc = -EIO; | 1781 | rc = -EIO; |
1781 | goto err3; | 1782 | goto err4; |
1782 | } | 1783 | } |
1783 | } | 1784 | } |
1784 | 1785 | ||
diff --git a/drivers/of/base.c b/drivers/of/base.c index 99764db0875a..f0650265febf 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -189,7 +189,7 @@ int __of_attach_node_sysfs(struct device_node *np) | |||
189 | return 0; | 189 | return 0; |
190 | } | 190 | } |
191 | 191 | ||
192 | static int __init of_init(void) | 192 | void __init of_core_init(void) |
193 | { | 193 | { |
194 | struct device_node *np; | 194 | struct device_node *np; |
195 | 195 | ||
@@ -198,7 +198,8 @@ static int __init of_init(void) | |||
198 | of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj); | 198 | of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj); |
199 | if (!of_kset) { | 199 | if (!of_kset) { |
200 | mutex_unlock(&of_mutex); | 200 | mutex_unlock(&of_mutex); |
201 | return -ENOMEM; | 201 | pr_err("devicetree: failed to register existing nodes\n"); |
202 | return; | ||
202 | } | 203 | } |
203 | for_each_of_allnodes(np) | 204 | for_each_of_allnodes(np) |
204 | __of_attach_node_sysfs(np); | 205 | __of_attach_node_sysfs(np); |
@@ -207,10 +208,7 @@ static int __init of_init(void) | |||
207 | /* Symlink in /proc as required by userspace ABI */ | 208 | /* Symlink in /proc as required by userspace ABI */ |
208 | if (of_root) | 209 | if (of_root) |
209 | proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base"); | 210 | proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base"); |
210 | |||
211 | return 0; | ||
212 | } | 211 | } |
213 | core_initcall(of_init); | ||
214 | 212 | ||
215 | static struct property *__of_find_property(const struct device_node *np, | 213 | static struct property *__of_find_property(const struct device_node *np, |
216 | const char *name, int *lenp) | 214 | const char *name, int *lenp) |
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 3351ef408125..53826b84e0ec 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c | |||
@@ -225,7 +225,7 @@ void __of_attach_node(struct device_node *np) | |||
225 | phandle = __of_get_property(np, "phandle", &sz); | 225 | phandle = __of_get_property(np, "phandle", &sz); |
226 | if (!phandle) | 226 | if (!phandle) |
227 | phandle = __of_get_property(np, "linux,phandle", &sz); | 227 | phandle = __of_get_property(np, "linux,phandle", &sz); |
228 | if (IS_ENABLED(PPC_PSERIES) && !phandle) | 228 | if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle) |
229 | phandle = __of_get_property(np, "ibm,phandle", &sz); | 229 | phandle = __of_get_property(np, "ibm,phandle", &sz); |
230 | np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0; | 230 | np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0; |
231 | 231 | ||
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 4fd0cacf7ca0..508cc56130e3 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -428,16 +428,19 @@ static void __assign_resources_sorted(struct list_head *head, | |||
428 | * consistent. | 428 | * consistent. |
429 | */ | 429 | */ |
430 | if (add_align > dev_res->res->start) { | 430 | if (add_align > dev_res->res->start) { |
431 | resource_size_t r_size = resource_size(dev_res->res); | ||
432 | |||
431 | dev_res->res->start = add_align; | 433 | dev_res->res->start = add_align; |
432 | dev_res->res->end = add_align + | 434 | dev_res->res->end = add_align + r_size - 1; |
433 | resource_size(dev_res->res); | ||
434 | 435 | ||
435 | list_for_each_entry(dev_res2, head, list) { | 436 | list_for_each_entry(dev_res2, head, list) { |
436 | align = pci_resource_alignment(dev_res2->dev, | 437 | align = pci_resource_alignment(dev_res2->dev, |
437 | dev_res2->res); | 438 | dev_res2->res); |
438 | if (add_align > align) | 439 | if (add_align > align) { |
439 | list_move_tail(&dev_res->list, | 440 | list_move_tail(&dev_res->list, |
440 | &dev_res2->list); | 441 | &dev_res2->list); |
442 | break; | ||
443 | } | ||
441 | } | 444 | } |
442 | } | 445 | } |
443 | 446 | ||
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index a53bd5b52df9..fc9b9f0ea91e 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig | |||
@@ -38,7 +38,9 @@ config ARMADA375_USBCLUSTER_PHY | |||
38 | config PHY_DM816X_USB | 38 | config PHY_DM816X_USB |
39 | tristate "TI dm816x USB PHY driver" | 39 | tristate "TI dm816x USB PHY driver" |
40 | depends on ARCH_OMAP2PLUS | 40 | depends on ARCH_OMAP2PLUS |
41 | depends on USB_SUPPORT | ||
41 | select GENERIC_PHY | 42 | select GENERIC_PHY |
43 | select USB_PHY | ||
42 | help | 44 | help |
43 | Enable this for dm816x USB to work. | 45 | Enable this for dm816x USB to work. |
44 | 46 | ||
@@ -97,8 +99,9 @@ config OMAP_CONTROL_PHY | |||
97 | config OMAP_USB2 | 99 | config OMAP_USB2 |
98 | tristate "OMAP USB2 PHY Driver" | 100 | tristate "OMAP USB2 PHY Driver" |
99 | depends on ARCH_OMAP2PLUS | 101 | depends on ARCH_OMAP2PLUS |
100 | depends on USB_PHY | 102 | depends on USB_SUPPORT |
101 | select GENERIC_PHY | 103 | select GENERIC_PHY |
104 | select USB_PHY | ||
102 | select OMAP_CONTROL_PHY | 105 | select OMAP_CONTROL_PHY |
103 | depends on OMAP_OCP2SCP | 106 | depends on OMAP_OCP2SCP |
104 | help | 107 | help |
@@ -122,8 +125,9 @@ config TI_PIPE3 | |||
122 | config TWL4030_USB | 125 | config TWL4030_USB |
123 | tristate "TWL4030 USB Transceiver Driver" | 126 | tristate "TWL4030 USB Transceiver Driver" |
124 | depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS | 127 | depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS |
125 | depends on USB_PHY | 128 | depends on USB_SUPPORT |
126 | select GENERIC_PHY | 129 | select GENERIC_PHY |
130 | select USB_PHY | ||
127 | help | 131 | help |
128 | Enable this to support the USB OTG transceiver on TWL4030 | 132 | Enable this to support the USB OTG transceiver on TWL4030 |
129 | family chips (including the TWL5030 and TPS659x0 devices). | 133 | family chips (including the TWL5030 and TPS659x0 devices). |
@@ -304,7 +308,7 @@ config PHY_STIH41X_USB | |||
304 | 308 | ||
305 | config PHY_QCOM_UFS | 309 | config PHY_QCOM_UFS |
306 | tristate "Qualcomm UFS PHY driver" | 310 | tristate "Qualcomm UFS PHY driver" |
307 | depends on OF && ARCH_MSM | 311 | depends on OF && ARCH_QCOM |
308 | select GENERIC_PHY | 312 | select GENERIC_PHY |
309 | help | 313 | help |
310 | Support for UFS PHY on QCOM chipsets. | 314 | Support for UFS PHY on QCOM chipsets. |
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 3791838f4bd4..63bc12d7a73e 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c | |||
@@ -530,7 +530,7 @@ struct phy *phy_optional_get(struct device *dev, const char *string) | |||
530 | { | 530 | { |
531 | struct phy *phy = phy_get(dev, string); | 531 | struct phy *phy = phy_get(dev, string); |
532 | 532 | ||
533 | if (PTR_ERR(phy) == -ENODEV) | 533 | if (IS_ERR(phy) && (PTR_ERR(phy) == -ENODEV)) |
534 | phy = NULL; | 534 | phy = NULL; |
535 | 535 | ||
536 | return phy; | 536 | return phy; |
@@ -584,7 +584,7 @@ struct phy *devm_phy_optional_get(struct device *dev, const char *string) | |||
584 | { | 584 | { |
585 | struct phy *phy = devm_phy_get(dev, string); | 585 | struct phy *phy = devm_phy_get(dev, string); |
586 | 586 | ||
587 | if (PTR_ERR(phy) == -ENODEV) | 587 | if (IS_ERR(phy) && (PTR_ERR(phy) == -ENODEV)) |
588 | phy = NULL; | 588 | phy = NULL; |
589 | 589 | ||
590 | return phy; | 590 | return phy; |
diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c index 183ef4368101..c1a468686bdc 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/phy-omap-usb2.c | |||
@@ -275,6 +275,7 @@ static int omap_usb2_probe(struct platform_device *pdev) | |||
275 | phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); | 275 | phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); |
276 | if (IS_ERR(phy->wkupclk)) { | 276 | if (IS_ERR(phy->wkupclk)) { |
277 | dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); | 277 | dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); |
278 | pm_runtime_disable(phy->dev); | ||
278 | return PTR_ERR(phy->wkupclk); | 279 | return PTR_ERR(phy->wkupclk); |
279 | } else { | 280 | } else { |
280 | dev_warn(&pdev->dev, | 281 | dev_warn(&pdev->dev, |
diff --git a/drivers/phy/phy-rcar-gen2.c b/drivers/phy/phy-rcar-gen2.c index 778276aba3aa..97d45f47d1ad 100644 --- a/drivers/phy/phy-rcar-gen2.c +++ b/drivers/phy/phy-rcar-gen2.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #define USBHS_LPSTS 0x02 | 23 | #define USBHS_LPSTS 0x02 |
24 | #define USBHS_UGCTRL 0x80 | 24 | #define USBHS_UGCTRL 0x80 |
25 | #define USBHS_UGCTRL2 0x84 | 25 | #define USBHS_UGCTRL2 0x84 |
26 | #define USBHS_UGSTS 0x88 /* The manuals have 0x90 */ | 26 | #define USBHS_UGSTS 0x88 /* From technical update */ |
27 | 27 | ||
28 | /* Low Power Status register (LPSTS) */ | 28 | /* Low Power Status register (LPSTS) */ |
29 | #define USBHS_LPSTS_SUSPM 0x4000 | 29 | #define USBHS_LPSTS_SUSPM 0x4000 |
@@ -41,7 +41,7 @@ | |||
41 | #define USBHS_UGCTRL2_USB0SEL_HS_USB 0x00000030 | 41 | #define USBHS_UGCTRL2_USB0SEL_HS_USB 0x00000030 |
42 | 42 | ||
43 | /* USB General status register (UGSTS) */ | 43 | /* USB General status register (UGSTS) */ |
44 | #define USBHS_UGSTS_LOCK 0x00000300 /* The manuals have 0x3 */ | 44 | #define USBHS_UGSTS_LOCK 0x00000100 /* From technical update */ |
45 | 45 | ||
46 | #define PHYS_PER_CHANNEL 2 | 46 | #define PHYS_PER_CHANNEL 2 |
47 | 47 | ||
diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig index bcdb22d5e215..3c1850332a90 100644 --- a/drivers/soc/mediatek/Kconfig +++ b/drivers/soc/mediatek/Kconfig | |||
@@ -4,6 +4,7 @@ | |||
4 | config MTK_PMIC_WRAP | 4 | config MTK_PMIC_WRAP |
5 | tristate "MediaTek PMIC Wrapper Support" | 5 | tristate "MediaTek PMIC Wrapper Support" |
6 | depends on ARCH_MEDIATEK | 6 | depends on ARCH_MEDIATEK |
7 | depends on RESET_CONTROLLER | ||
7 | select REGMAP | 8 | select REGMAP |
8 | help | 9 | help |
9 | Say yes here to add support for MediaTek PMIC Wrapper found | 10 | Say yes here to add support for MediaTek PMIC Wrapper found |
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c index db5be1eec54c..f432291feee9 100644 --- a/drivers/soc/mediatek/mtk-pmic-wrap.c +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c | |||
@@ -443,11 +443,6 @@ static int pwrap_wait_for_state(struct pmic_wrapper *wrp, | |||
443 | static int pwrap_write(struct pmic_wrapper *wrp, u32 adr, u32 wdata) | 443 | static int pwrap_write(struct pmic_wrapper *wrp, u32 adr, u32 wdata) |
444 | { | 444 | { |
445 | int ret; | 445 | int ret; |
446 | u32 val; | ||
447 | |||
448 | val = pwrap_readl(wrp, PWRAP_WACS2_RDATA); | ||
449 | if (PWRAP_GET_WACS_FSM(val) == PWRAP_WACS_FSM_WFVLDCLR) | ||
450 | pwrap_writel(wrp, 1, PWRAP_WACS2_VLDCLR); | ||
451 | 446 | ||
452 | ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle); | 447 | ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle); |
453 | if (ret) | 448 | if (ret) |
@@ -462,11 +457,6 @@ static int pwrap_write(struct pmic_wrapper *wrp, u32 adr, u32 wdata) | |||
462 | static int pwrap_read(struct pmic_wrapper *wrp, u32 adr, u32 *rdata) | 457 | static int pwrap_read(struct pmic_wrapper *wrp, u32 adr, u32 *rdata) |
463 | { | 458 | { |
464 | int ret; | 459 | int ret; |
465 | u32 val; | ||
466 | |||
467 | val = pwrap_readl(wrp, PWRAP_WACS2_RDATA); | ||
468 | if (PWRAP_GET_WACS_FSM(val) == PWRAP_WACS_FSM_WFVLDCLR) | ||
469 | pwrap_writel(wrp, 1, PWRAP_WACS2_VLDCLR); | ||
470 | 460 | ||
471 | ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle); | 461 | ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle); |
472 | if (ret) | 462 | if (ret) |
@@ -480,6 +470,8 @@ static int pwrap_read(struct pmic_wrapper *wrp, u32 adr, u32 *rdata) | |||
480 | 470 | ||
481 | *rdata = PWRAP_GET_WACS_RDATA(pwrap_readl(wrp, PWRAP_WACS2_RDATA)); | 471 | *rdata = PWRAP_GET_WACS_RDATA(pwrap_readl(wrp, PWRAP_WACS2_RDATA)); |
482 | 472 | ||
473 | pwrap_writel(wrp, 1, PWRAP_WACS2_VLDCLR); | ||
474 | |||
483 | return 0; | 475 | return 0; |
484 | } | 476 | } |
485 | 477 | ||
@@ -563,45 +555,17 @@ static int pwrap_init_sidly(struct pmic_wrapper *wrp) | |||
563 | 555 | ||
564 | static int pwrap_init_reg_clock(struct pmic_wrapper *wrp) | 556 | static int pwrap_init_reg_clock(struct pmic_wrapper *wrp) |
565 | { | 557 | { |
566 | unsigned long rate_spi; | 558 | if (pwrap_is_mt8135(wrp)) { |
567 | int ck_mhz; | 559 | pwrap_writel(wrp, 0x4, PWRAP_CSHEXT); |
568 | |||
569 | rate_spi = clk_get_rate(wrp->clk_spi); | ||
570 | |||
571 | if (rate_spi > 26000000) | ||
572 | ck_mhz = 26; | ||
573 | else if (rate_spi > 18000000) | ||
574 | ck_mhz = 18; | ||
575 | else | ||
576 | ck_mhz = 0; | ||
577 | |||
578 | switch (ck_mhz) { | ||
579 | case 18: | ||
580 | if (pwrap_is_mt8135(wrp)) | ||
581 | pwrap_writel(wrp, 0xc, PWRAP_CSHEXT); | ||
582 | pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_WRITE); | ||
583 | pwrap_writel(wrp, 0xc, PWRAP_CSHEXT_READ); | ||
584 | pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_START); | ||
585 | pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_END); | ||
586 | break; | ||
587 | case 26: | ||
588 | if (pwrap_is_mt8135(wrp)) | ||
589 | pwrap_writel(wrp, 0x4, PWRAP_CSHEXT); | ||
590 | pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE); | 560 | pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE); |
591 | pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ); | 561 | pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ); |
592 | pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_START); | 562 | pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_START); |
593 | pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_END); | 563 | pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_END); |
594 | break; | 564 | } else { |
595 | case 0: | 565 | pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE); |
596 | if (pwrap_is_mt8135(wrp)) | 566 | pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ); |
597 | pwrap_writel(wrp, 0xf, PWRAP_CSHEXT); | 567 | pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START); |
598 | pwrap_writel(wrp, 0xf, PWRAP_CSHEXT_WRITE); | 568 | pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END); |
599 | pwrap_writel(wrp, 0xf, PWRAP_CSHEXT_READ); | ||
600 | pwrap_writel(wrp, 0xf, PWRAP_CSLEXT_START); | ||
601 | pwrap_writel(wrp, 0xf, PWRAP_CSLEXT_END); | ||
602 | break; | ||
603 | default: | ||
604 | return -EINVAL; | ||
605 | } | 569 | } |
606 | 570 | ||
607 | return 0; | 571 | return 0; |
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c index 09428412139e..c5352ea4821e 100644 --- a/drivers/ssb/driver_chipcommon_pmu.c +++ b/drivers/ssb/driver_chipcommon_pmu.c | |||
@@ -621,8 +621,8 @@ static u32 ssb_pmu_get_alp_clock_clk0(struct ssb_chipcommon *cc) | |||
621 | u32 crystalfreq; | 621 | u32 crystalfreq; |
622 | const struct pmu0_plltab_entry *e = NULL; | 622 | const struct pmu0_plltab_entry *e = NULL; |
623 | 623 | ||
624 | crystalfreq = chipco_read32(cc, SSB_CHIPCO_PMU_CTL) & | 624 | crystalfreq = (chipco_read32(cc, SSB_CHIPCO_PMU_CTL) & |
625 | SSB_CHIPCO_PMU_CTL_XTALFREQ >> SSB_CHIPCO_PMU_CTL_XTALFREQ_SHIFT; | 625 | SSB_CHIPCO_PMU_CTL_XTALFREQ) >> SSB_CHIPCO_PMU_CTL_XTALFREQ_SHIFT; |
626 | e = pmu0_plltab_find_entry(crystalfreq); | 626 | e = pmu0_plltab_find_entry(crystalfreq); |
627 | BUG_ON(!e); | 627 | BUG_ON(!e); |
628 | return e->freq * 1000; | 628 | return e->freq * 1000; |
@@ -634,7 +634,7 @@ u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc) | |||
634 | 634 | ||
635 | switch (bus->chip_id) { | 635 | switch (bus->chip_id) { |
636 | case 0x5354: | 636 | case 0x5354: |
637 | ssb_pmu_get_alp_clock_clk0(cc); | 637 | return ssb_pmu_get_alp_clock_clk0(cc); |
638 | default: | 638 | default: |
639 | ssb_err("ERROR: PMU alp clock unknown for device %04X\n", | 639 | ssb_err("ERROR: PMU alp clock unknown for device %04X\n", |
640 | bus->chip_id); | 640 | bus->chip_id); |
diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 5ff4716b72c3..784b5ecfa849 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c | |||
@@ -746,8 +746,8 @@ void oz_hcd_pd_reset(void *hpd, void *hport) | |||
746 | /* | 746 | /* |
747 | * Context: softirq | 747 | * Context: softirq |
748 | */ | 748 | */ |
749 | void oz_hcd_get_desc_cnf(void *hport, u8 req_id, int status, const u8 *desc, | 749 | void oz_hcd_get_desc_cnf(void *hport, u8 req_id, u8 status, const u8 *desc, |
750 | int length, int offset, int total_size) | 750 | u8 length, u16 offset, u16 total_size) |
751 | { | 751 | { |
752 | struct oz_port *port = hport; | 752 | struct oz_port *port = hport; |
753 | struct urb *urb; | 753 | struct urb *urb; |
@@ -759,8 +759,8 @@ void oz_hcd_get_desc_cnf(void *hport, u8 req_id, int status, const u8 *desc, | |||
759 | if (!urb) | 759 | if (!urb) |
760 | return; | 760 | return; |
761 | if (status == 0) { | 761 | if (status == 0) { |
762 | int copy_len; | 762 | unsigned int copy_len; |
763 | int required_size = urb->transfer_buffer_length; | 763 | unsigned int required_size = urb->transfer_buffer_length; |
764 | 764 | ||
765 | if (required_size > total_size) | 765 | if (required_size > total_size) |
766 | required_size = total_size; | 766 | required_size = total_size; |
diff --git a/drivers/staging/ozwpan/ozusbif.h b/drivers/staging/ozwpan/ozusbif.h index 4249fa374012..d2a6085345be 100644 --- a/drivers/staging/ozwpan/ozusbif.h +++ b/drivers/staging/ozwpan/ozusbif.h | |||
@@ -29,8 +29,8 @@ void oz_usb_request_heartbeat(void *hpd); | |||
29 | 29 | ||
30 | /* Confirmation functions. | 30 | /* Confirmation functions. |
31 | */ | 31 | */ |
32 | void oz_hcd_get_desc_cnf(void *hport, u8 req_id, int status, | 32 | void oz_hcd_get_desc_cnf(void *hport, u8 req_id, u8 status, |
33 | const u8 *desc, int length, int offset, int total_size); | 33 | const u8 *desc, u8 length, u16 offset, u16 total_size); |
34 | void oz_hcd_control_cnf(void *hport, u8 req_id, u8 rcode, | 34 | void oz_hcd_control_cnf(void *hport, u8 req_id, u8 rcode, |
35 | const u8 *data, int data_len); | 35 | const u8 *data, int data_len); |
36 | 36 | ||
diff --git a/drivers/staging/ozwpan/ozusbsvc1.c b/drivers/staging/ozwpan/ozusbsvc1.c index d434d8c6fff6..f660bb198c65 100644 --- a/drivers/staging/ozwpan/ozusbsvc1.c +++ b/drivers/staging/ozwpan/ozusbsvc1.c | |||
@@ -326,7 +326,11 @@ static void oz_usb_handle_ep_data(struct oz_usb_ctx *usb_ctx, | |||
326 | struct oz_multiple_fixed *body = | 326 | struct oz_multiple_fixed *body = |
327 | (struct oz_multiple_fixed *)data_hdr; | 327 | (struct oz_multiple_fixed *)data_hdr; |
328 | u8 *data = body->data; | 328 | u8 *data = body->data; |
329 | int n = (len - sizeof(struct oz_multiple_fixed)+1) | 329 | unsigned int n; |
330 | if (!body->unit_size || | ||
331 | len < sizeof(struct oz_multiple_fixed) - 1) | ||
332 | break; | ||
333 | n = (len - (sizeof(struct oz_multiple_fixed) - 1)) | ||
330 | / body->unit_size; | 334 | / body->unit_size; |
331 | while (n--) { | 335 | while (n--) { |
332 | oz_hcd_data_ind(usb_ctx->hport, body->endpoint, | 336 | oz_hcd_data_ind(usb_ctx->hport, body->endpoint, |
@@ -390,10 +394,15 @@ void oz_usb_rx(struct oz_pd *pd, struct oz_elt *elt) | |||
390 | case OZ_GET_DESC_RSP: { | 394 | case OZ_GET_DESC_RSP: { |
391 | struct oz_get_desc_rsp *body = | 395 | struct oz_get_desc_rsp *body = |
392 | (struct oz_get_desc_rsp *)usb_hdr; | 396 | (struct oz_get_desc_rsp *)usb_hdr; |
393 | int data_len = elt->length - | 397 | u16 offs, total_size; |
394 | sizeof(struct oz_get_desc_rsp) + 1; | 398 | u8 data_len; |
395 | u16 offs = le16_to_cpu(get_unaligned(&body->offset)); | 399 | |
396 | u16 total_size = | 400 | if (elt->length < sizeof(struct oz_get_desc_rsp) - 1) |
401 | break; | ||
402 | data_len = elt->length - | ||
403 | (sizeof(struct oz_get_desc_rsp) - 1); | ||
404 | offs = le16_to_cpu(get_unaligned(&body->offset)); | ||
405 | total_size = | ||
397 | le16_to_cpu(get_unaligned(&body->total_size)); | 406 | le16_to_cpu(get_unaligned(&body->total_size)); |
398 | oz_dbg(ON, "USB_REQ_GET_DESCRIPTOR - cnf\n"); | 407 | oz_dbg(ON, "USB_REQ_GET_DESCRIPTOR - cnf\n"); |
399 | oz_hcd_get_desc_cnf(usb_ctx->hport, body->req_id, | 408 | oz_hcd_get_desc_cnf(usb_ctx->hport, body->req_id, |
diff --git a/drivers/staging/rtl8712/rtl8712_led.c b/drivers/staging/rtl8712/rtl8712_led.c index f1d47a0676c3..ada8d5dafd49 100644 --- a/drivers/staging/rtl8712/rtl8712_led.c +++ b/drivers/staging/rtl8712/rtl8712_led.c | |||
@@ -898,11 +898,11 @@ static void SwLedControlMode1(struct _adapter *padapter, | |||
898 | IS_LED_WPS_BLINKING(pLed)) | 898 | IS_LED_WPS_BLINKING(pLed)) |
899 | return; | 899 | return; |
900 | if (pLed->bLedLinkBlinkInProgress == true) { | 900 | if (pLed->bLedLinkBlinkInProgress == true) { |
901 | del_timer_sync(&pLed->BlinkTimer); | 901 | del_timer(&pLed->BlinkTimer); |
902 | pLed->bLedLinkBlinkInProgress = false; | 902 | pLed->bLedLinkBlinkInProgress = false; |
903 | } | 903 | } |
904 | if (pLed->bLedBlinkInProgress == true) { | 904 | if (pLed->bLedBlinkInProgress == true) { |
905 | del_timer_sync(&pLed->BlinkTimer); | 905 | del_timer(&pLed->BlinkTimer); |
906 | pLed->bLedBlinkInProgress = false; | 906 | pLed->bLedBlinkInProgress = false; |
907 | } | 907 | } |
908 | pLed->bLedNoLinkBlinkInProgress = true; | 908 | pLed->bLedNoLinkBlinkInProgress = true; |
@@ -921,11 +921,11 @@ static void SwLedControlMode1(struct _adapter *padapter, | |||
921 | IS_LED_WPS_BLINKING(pLed)) | 921 | IS_LED_WPS_BLINKING(pLed)) |
922 | return; | 922 | return; |
923 | if (pLed->bLedNoLinkBlinkInProgress == true) { | 923 | if (pLed->bLedNoLinkBlinkInProgress == true) { |
924 | del_timer_sync(&pLed->BlinkTimer); | 924 | del_timer(&pLed->BlinkTimer); |
925 | pLed->bLedNoLinkBlinkInProgress = false; | 925 | pLed->bLedNoLinkBlinkInProgress = false; |
926 | } | 926 | } |
927 | if (pLed->bLedBlinkInProgress == true) { | 927 | if (pLed->bLedBlinkInProgress == true) { |
928 | del_timer_sync(&pLed->BlinkTimer); | 928 | del_timer(&pLed->BlinkTimer); |
929 | pLed->bLedBlinkInProgress = false; | 929 | pLed->bLedBlinkInProgress = false; |
930 | } | 930 | } |
931 | pLed->bLedLinkBlinkInProgress = true; | 931 | pLed->bLedLinkBlinkInProgress = true; |
@@ -946,15 +946,15 @@ static void SwLedControlMode1(struct _adapter *padapter, | |||
946 | if (IS_LED_WPS_BLINKING(pLed)) | 946 | if (IS_LED_WPS_BLINKING(pLed)) |
947 | return; | 947 | return; |
948 | if (pLed->bLedNoLinkBlinkInProgress == true) { | 948 | if (pLed->bLedNoLinkBlinkInProgress == true) { |
949 | del_timer_sync(&pLed->BlinkTimer); | 949 | del_timer(&pLed->BlinkTimer); |
950 | pLed->bLedNoLinkBlinkInProgress = false; | 950 | pLed->bLedNoLinkBlinkInProgress = false; |
951 | } | 951 | } |
952 | if (pLed->bLedLinkBlinkInProgress == true) { | 952 | if (pLed->bLedLinkBlinkInProgress == true) { |
953 | del_timer_sync(&pLed->BlinkTimer); | 953 | del_timer(&pLed->BlinkTimer); |
954 | pLed->bLedLinkBlinkInProgress = false; | 954 | pLed->bLedLinkBlinkInProgress = false; |
955 | } | 955 | } |
956 | if (pLed->bLedBlinkInProgress == true) { | 956 | if (pLed->bLedBlinkInProgress == true) { |
957 | del_timer_sync(&pLed->BlinkTimer); | 957 | del_timer(&pLed->BlinkTimer); |
958 | pLed->bLedBlinkInProgress = false; | 958 | pLed->bLedBlinkInProgress = false; |
959 | } | 959 | } |
960 | pLed->bLedScanBlinkInProgress = true; | 960 | pLed->bLedScanBlinkInProgress = true; |
@@ -975,11 +975,11 @@ static void SwLedControlMode1(struct _adapter *padapter, | |||
975 | IS_LED_WPS_BLINKING(pLed)) | 975 | IS_LED_WPS_BLINKING(pLed)) |
976 | return; | 976 | return; |
977 | if (pLed->bLedNoLinkBlinkInProgress == true) { | 977 | if (pLed->bLedNoLinkBlinkInProgress == true) { |
978 | del_timer_sync(&pLed->BlinkTimer); | 978 | del_timer(&pLed->BlinkTimer); |
979 | pLed->bLedNoLinkBlinkInProgress = false; | 979 | pLed->bLedNoLinkBlinkInProgress = false; |
980 | } | 980 | } |
981 | if (pLed->bLedLinkBlinkInProgress == true) { | 981 | if (pLed->bLedLinkBlinkInProgress == true) { |
982 | del_timer_sync(&pLed->BlinkTimer); | 982 | del_timer(&pLed->BlinkTimer); |
983 | pLed->bLedLinkBlinkInProgress = false; | 983 | pLed->bLedLinkBlinkInProgress = false; |
984 | } | 984 | } |
985 | pLed->bLedBlinkInProgress = true; | 985 | pLed->bLedBlinkInProgress = true; |
@@ -998,19 +998,19 @@ static void SwLedControlMode1(struct _adapter *padapter, | |||
998 | case LED_CTL_START_WPS_BOTTON: | 998 | case LED_CTL_START_WPS_BOTTON: |
999 | if (pLed->bLedWPSBlinkInProgress == false) { | 999 | if (pLed->bLedWPSBlinkInProgress == false) { |
1000 | if (pLed->bLedNoLinkBlinkInProgress == true) { | 1000 | if (pLed->bLedNoLinkBlinkInProgress == true) { |
1001 | del_timer_sync(&pLed->BlinkTimer); | 1001 | del_timer(&pLed->BlinkTimer); |
1002 | pLed->bLedNoLinkBlinkInProgress = false; | 1002 | pLed->bLedNoLinkBlinkInProgress = false; |
1003 | } | 1003 | } |
1004 | if (pLed->bLedLinkBlinkInProgress == true) { | 1004 | if (pLed->bLedLinkBlinkInProgress == true) { |
1005 | del_timer_sync(&pLed->BlinkTimer); | 1005 | del_timer(&pLed->BlinkTimer); |
1006 | pLed->bLedLinkBlinkInProgress = false; | 1006 | pLed->bLedLinkBlinkInProgress = false; |
1007 | } | 1007 | } |
1008 | if (pLed->bLedBlinkInProgress == true) { | 1008 | if (pLed->bLedBlinkInProgress == true) { |
1009 | del_timer_sync(&pLed->BlinkTimer); | 1009 | del_timer(&pLed->BlinkTimer); |
1010 | pLed->bLedBlinkInProgress = false; | 1010 | pLed->bLedBlinkInProgress = false; |
1011 | } | 1011 | } |
1012 | if (pLed->bLedScanBlinkInProgress == true) { | 1012 | if (pLed->bLedScanBlinkInProgress == true) { |
1013 | del_timer_sync(&pLed->BlinkTimer); | 1013 | del_timer(&pLed->BlinkTimer); |
1014 | pLed->bLedScanBlinkInProgress = false; | 1014 | pLed->bLedScanBlinkInProgress = false; |
1015 | } | 1015 | } |
1016 | pLed->bLedWPSBlinkInProgress = true; | 1016 | pLed->bLedWPSBlinkInProgress = true; |
@@ -1025,23 +1025,23 @@ static void SwLedControlMode1(struct _adapter *padapter, | |||
1025 | break; | 1025 | break; |
1026 | case LED_CTL_STOP_WPS: | 1026 | case LED_CTL_STOP_WPS: |
1027 | if (pLed->bLedNoLinkBlinkInProgress == true) { | 1027 | if (pLed->bLedNoLinkBlinkInProgress == true) { |
1028 | del_timer_sync(&pLed->BlinkTimer); | 1028 | del_timer(&pLed->BlinkTimer); |
1029 | pLed->bLedNoLinkBlinkInProgress = false; | 1029 | pLed->bLedNoLinkBlinkInProgress = false; |
1030 | } | 1030 | } |
1031 | if (pLed->bLedLinkBlinkInProgress == true) { | 1031 | if (pLed->bLedLinkBlinkInProgress == true) { |
1032 | del_timer_sync(&pLed->BlinkTimer); | 1032 | del_timer(&pLed->BlinkTimer); |
1033 | pLed->bLedLinkBlinkInProgress = false; | 1033 | pLed->bLedLinkBlinkInProgress = false; |
1034 | } | 1034 | } |
1035 | if (pLed->bLedBlinkInProgress == true) { | 1035 | if (pLed->bLedBlinkInProgress == true) { |
1036 | del_timer_sync(&pLed->BlinkTimer); | 1036 | del_timer(&pLed->BlinkTimer); |
1037 | pLed->bLedBlinkInProgress = false; | 1037 | pLed->bLedBlinkInProgress = false; |
1038 | } | 1038 | } |
1039 | if (pLed->bLedScanBlinkInProgress == true) { | 1039 | if (pLed->bLedScanBlinkInProgress == true) { |
1040 | del_timer_sync(&pLed->BlinkTimer); | 1040 | del_timer(&pLed->BlinkTimer); |
1041 | pLed->bLedScanBlinkInProgress = false; | 1041 | pLed->bLedScanBlinkInProgress = false; |
1042 | } | 1042 | } |
1043 | if (pLed->bLedWPSBlinkInProgress) | 1043 | if (pLed->bLedWPSBlinkInProgress) |
1044 | del_timer_sync(&pLed->BlinkTimer); | 1044 | del_timer(&pLed->BlinkTimer); |
1045 | else | 1045 | else |
1046 | pLed->bLedWPSBlinkInProgress = true; | 1046 | pLed->bLedWPSBlinkInProgress = true; |
1047 | pLed->CurrLedState = LED_BLINK_WPS_STOP; | 1047 | pLed->CurrLedState = LED_BLINK_WPS_STOP; |
@@ -1057,7 +1057,7 @@ static void SwLedControlMode1(struct _adapter *padapter, | |||
1057 | break; | 1057 | break; |
1058 | case LED_CTL_STOP_WPS_FAIL: | 1058 | case LED_CTL_STOP_WPS_FAIL: |
1059 | if (pLed->bLedWPSBlinkInProgress) { | 1059 | if (pLed->bLedWPSBlinkInProgress) { |
1060 | del_timer_sync(&pLed->BlinkTimer); | 1060 | del_timer(&pLed->BlinkTimer); |
1061 | pLed->bLedWPSBlinkInProgress = false; | 1061 | pLed->bLedWPSBlinkInProgress = false; |
1062 | } | 1062 | } |
1063 | pLed->bLedNoLinkBlinkInProgress = true; | 1063 | pLed->bLedNoLinkBlinkInProgress = true; |
@@ -1073,23 +1073,23 @@ static void SwLedControlMode1(struct _adapter *padapter, | |||
1073 | pLed->CurrLedState = LED_OFF; | 1073 | pLed->CurrLedState = LED_OFF; |
1074 | pLed->BlinkingLedState = LED_OFF; | 1074 | pLed->BlinkingLedState = LED_OFF; |
1075 | if (pLed->bLedNoLinkBlinkInProgress) { | 1075 | if (pLed->bLedNoLinkBlinkInProgress) { |
1076 | del_timer_sync(&pLed->BlinkTimer); | 1076 | del_timer(&pLed->BlinkTimer); |
1077 | pLed->bLedNoLinkBlinkInProgress = false; | 1077 | pLed->bLedNoLinkBlinkInProgress = false; |
1078 | } | 1078 | } |
1079 | if (pLed->bLedLinkBlinkInProgress) { | 1079 | if (pLed->bLedLinkBlinkInProgress) { |
1080 | del_timer_sync(&pLed->BlinkTimer); | 1080 | del_timer(&pLed->BlinkTimer); |
1081 | pLed->bLedLinkBlinkInProgress = false; | 1081 | pLed->bLedLinkBlinkInProgress = false; |
1082 | } | 1082 | } |
1083 | if (pLed->bLedBlinkInProgress) { | 1083 | if (pLed->bLedBlinkInProgress) { |
1084 | del_timer_sync(&pLed->BlinkTimer); | 1084 | del_timer(&pLed->BlinkTimer); |
1085 | pLed->bLedBlinkInProgress = false; | 1085 | pLed->bLedBlinkInProgress = false; |
1086 | } | 1086 | } |
1087 | if (pLed->bLedWPSBlinkInProgress) { | 1087 | if (pLed->bLedWPSBlinkInProgress) { |
1088 | del_timer_sync(&pLed->BlinkTimer); | 1088 | del_timer(&pLed->BlinkTimer); |
1089 | pLed->bLedWPSBlinkInProgress = false; | 1089 | pLed->bLedWPSBlinkInProgress = false; |
1090 | } | 1090 | } |
1091 | if (pLed->bLedScanBlinkInProgress) { | 1091 | if (pLed->bLedScanBlinkInProgress) { |
1092 | del_timer_sync(&pLed->BlinkTimer); | 1092 | del_timer(&pLed->BlinkTimer); |
1093 | pLed->bLedScanBlinkInProgress = false; | 1093 | pLed->bLedScanBlinkInProgress = false; |
1094 | } | 1094 | } |
1095 | mod_timer(&pLed->BlinkTimer, | 1095 | mod_timer(&pLed->BlinkTimer, |
@@ -1116,7 +1116,7 @@ static void SwLedControlMode2(struct _adapter *padapter, | |||
1116 | return; | 1116 | return; |
1117 | 1117 | ||
1118 | if (pLed->bLedBlinkInProgress == true) { | 1118 | if (pLed->bLedBlinkInProgress == true) { |
1119 | del_timer_sync(&pLed->BlinkTimer); | 1119 | del_timer(&pLed->BlinkTimer); |
1120 | pLed->bLedBlinkInProgress = false; | 1120 | pLed->bLedBlinkInProgress = false; |
1121 | } | 1121 | } |
1122 | pLed->bLedScanBlinkInProgress = true; | 1122 | pLed->bLedScanBlinkInProgress = true; |
@@ -1154,11 +1154,11 @@ static void SwLedControlMode2(struct _adapter *padapter, | |||
1154 | pLed->CurrLedState = LED_ON; | 1154 | pLed->CurrLedState = LED_ON; |
1155 | pLed->BlinkingLedState = LED_ON; | 1155 | pLed->BlinkingLedState = LED_ON; |
1156 | if (pLed->bLedBlinkInProgress) { | 1156 | if (pLed->bLedBlinkInProgress) { |
1157 | del_timer_sync(&pLed->BlinkTimer); | 1157 | del_timer(&pLed->BlinkTimer); |
1158 | pLed->bLedBlinkInProgress = false; | 1158 | pLed->bLedBlinkInProgress = false; |
1159 | } | 1159 | } |
1160 | if (pLed->bLedScanBlinkInProgress) { | 1160 | if (pLed->bLedScanBlinkInProgress) { |
1161 | del_timer_sync(&pLed->BlinkTimer); | 1161 | del_timer(&pLed->BlinkTimer); |
1162 | pLed->bLedScanBlinkInProgress = false; | 1162 | pLed->bLedScanBlinkInProgress = false; |
1163 | } | 1163 | } |
1164 | 1164 | ||
@@ -1170,11 +1170,11 @@ static void SwLedControlMode2(struct _adapter *padapter, | |||
1170 | case LED_CTL_START_WPS_BOTTON: | 1170 | case LED_CTL_START_WPS_BOTTON: |
1171 | if (pLed->bLedWPSBlinkInProgress == false) { | 1171 | if (pLed->bLedWPSBlinkInProgress == false) { |
1172 | if (pLed->bLedBlinkInProgress == true) { | 1172 | if (pLed->bLedBlinkInProgress == true) { |
1173 | del_timer_sync(&pLed->BlinkTimer); | 1173 | del_timer(&pLed->BlinkTimer); |
1174 | pLed->bLedBlinkInProgress = false; | 1174 | pLed->bLedBlinkInProgress = false; |
1175 | } | 1175 | } |
1176 | if (pLed->bLedScanBlinkInProgress == true) { | 1176 | if (pLed->bLedScanBlinkInProgress == true) { |
1177 | del_timer_sync(&pLed->BlinkTimer); | 1177 | del_timer(&pLed->BlinkTimer); |
1178 | pLed->bLedScanBlinkInProgress = false; | 1178 | pLed->bLedScanBlinkInProgress = false; |
1179 | } | 1179 | } |
1180 | pLed->bLedWPSBlinkInProgress = true; | 1180 | pLed->bLedWPSBlinkInProgress = true; |
@@ -1214,15 +1214,15 @@ static void SwLedControlMode2(struct _adapter *padapter, | |||
1214 | pLed->CurrLedState = LED_OFF; | 1214 | pLed->CurrLedState = LED_OFF; |
1215 | pLed->BlinkingLedState = LED_OFF; | 1215 | pLed->BlinkingLedState = LED_OFF; |
1216 | if (pLed->bLedBlinkInProgress) { | 1216 | if (pLed->bLedBlinkInProgress) { |
1217 | del_timer_sync(&pLed->BlinkTimer); | 1217 | del_timer(&pLed->BlinkTimer); |
1218 | pLed->bLedBlinkInProgress = false; | 1218 | pLed->bLedBlinkInProgress = false; |
1219 | } | 1219 | } |
1220 | if (pLed->bLedScanBlinkInProgress) { | 1220 | if (pLed->bLedScanBlinkInProgress) { |
1221 | del_timer_sync(&pLed->BlinkTimer); | 1221 | del_timer(&pLed->BlinkTimer); |
1222 | pLed->bLedScanBlinkInProgress = false; | 1222 | pLed->bLedScanBlinkInProgress = false; |
1223 | } | 1223 | } |
1224 | if (pLed->bLedWPSBlinkInProgress) { | 1224 | if (pLed->bLedWPSBlinkInProgress) { |
1225 | del_timer_sync(&pLed->BlinkTimer); | 1225 | del_timer(&pLed->BlinkTimer); |
1226 | pLed->bLedWPSBlinkInProgress = false; | 1226 | pLed->bLedWPSBlinkInProgress = false; |
1227 | } | 1227 | } |
1228 | mod_timer(&pLed->BlinkTimer, | 1228 | mod_timer(&pLed->BlinkTimer, |
@@ -1248,7 +1248,7 @@ static void SwLedControlMode3(struct _adapter *padapter, | |||
1248 | if (IS_LED_WPS_BLINKING(pLed)) | 1248 | if (IS_LED_WPS_BLINKING(pLed)) |
1249 | return; | 1249 | return; |
1250 | if (pLed->bLedBlinkInProgress == true) { | 1250 | if (pLed->bLedBlinkInProgress == true) { |
1251 | del_timer_sync(&pLed->BlinkTimer); | 1251 | del_timer(&pLed->BlinkTimer); |
1252 | pLed->bLedBlinkInProgress = false; | 1252 | pLed->bLedBlinkInProgress = false; |
1253 | } | 1253 | } |
1254 | pLed->bLedScanBlinkInProgress = true; | 1254 | pLed->bLedScanBlinkInProgress = true; |
@@ -1286,11 +1286,11 @@ static void SwLedControlMode3(struct _adapter *padapter, | |||
1286 | pLed->CurrLedState = LED_ON; | 1286 | pLed->CurrLedState = LED_ON; |
1287 | pLed->BlinkingLedState = LED_ON; | 1287 | pLed->BlinkingLedState = LED_ON; |
1288 | if (pLed->bLedBlinkInProgress) { | 1288 | if (pLed->bLedBlinkInProgress) { |
1289 | del_timer_sync(&pLed->BlinkTimer); | 1289 | del_timer(&pLed->BlinkTimer); |
1290 | pLed->bLedBlinkInProgress = false; | 1290 | pLed->bLedBlinkInProgress = false; |
1291 | } | 1291 | } |
1292 | if (pLed->bLedScanBlinkInProgress) { | 1292 | if (pLed->bLedScanBlinkInProgress) { |
1293 | del_timer_sync(&pLed->BlinkTimer); | 1293 | del_timer(&pLed->BlinkTimer); |
1294 | pLed->bLedScanBlinkInProgress = false; | 1294 | pLed->bLedScanBlinkInProgress = false; |
1295 | } | 1295 | } |
1296 | mod_timer(&pLed->BlinkTimer, | 1296 | mod_timer(&pLed->BlinkTimer, |
@@ -1300,11 +1300,11 @@ static void SwLedControlMode3(struct _adapter *padapter, | |||
1300 | case LED_CTL_START_WPS_BOTTON: | 1300 | case LED_CTL_START_WPS_BOTTON: |
1301 | if (pLed->bLedWPSBlinkInProgress == false) { | 1301 | if (pLed->bLedWPSBlinkInProgress == false) { |
1302 | if (pLed->bLedBlinkInProgress == true) { | 1302 | if (pLed->bLedBlinkInProgress == true) { |
1303 | del_timer_sync(&pLed->BlinkTimer); | 1303 | del_timer(&pLed->BlinkTimer); |
1304 | pLed->bLedBlinkInProgress = false; | 1304 | pLed->bLedBlinkInProgress = false; |
1305 | } | 1305 | } |
1306 | if (pLed->bLedScanBlinkInProgress == true) { | 1306 | if (pLed->bLedScanBlinkInProgress == true) { |
1307 | del_timer_sync(&pLed->BlinkTimer); | 1307 | del_timer(&pLed->BlinkTimer); |
1308 | pLed->bLedScanBlinkInProgress = false; | 1308 | pLed->bLedScanBlinkInProgress = false; |
1309 | } | 1309 | } |
1310 | pLed->bLedWPSBlinkInProgress = true; | 1310 | pLed->bLedWPSBlinkInProgress = true; |
@@ -1319,7 +1319,7 @@ static void SwLedControlMode3(struct _adapter *padapter, | |||
1319 | break; | 1319 | break; |
1320 | case LED_CTL_STOP_WPS: | 1320 | case LED_CTL_STOP_WPS: |
1321 | if (pLed->bLedWPSBlinkInProgress) { | 1321 | if (pLed->bLedWPSBlinkInProgress) { |
1322 | del_timer_sync(&(pLed->BlinkTimer)); | 1322 | del_timer(&pLed->BlinkTimer); |
1323 | pLed->bLedWPSBlinkInProgress = false; | 1323 | pLed->bLedWPSBlinkInProgress = false; |
1324 | } else | 1324 | } else |
1325 | pLed->bLedWPSBlinkInProgress = true; | 1325 | pLed->bLedWPSBlinkInProgress = true; |
@@ -1336,7 +1336,7 @@ static void SwLedControlMode3(struct _adapter *padapter, | |||
1336 | break; | 1336 | break; |
1337 | case LED_CTL_STOP_WPS_FAIL: | 1337 | case LED_CTL_STOP_WPS_FAIL: |
1338 | if (pLed->bLedWPSBlinkInProgress) { | 1338 | if (pLed->bLedWPSBlinkInProgress) { |
1339 | del_timer_sync(&pLed->BlinkTimer); | 1339 | del_timer(&pLed->BlinkTimer); |
1340 | pLed->bLedWPSBlinkInProgress = false; | 1340 | pLed->bLedWPSBlinkInProgress = false; |
1341 | } | 1341 | } |
1342 | pLed->CurrLedState = LED_OFF; | 1342 | pLed->CurrLedState = LED_OFF; |
@@ -1357,15 +1357,15 @@ static void SwLedControlMode3(struct _adapter *padapter, | |||
1357 | pLed->CurrLedState = LED_OFF; | 1357 | pLed->CurrLedState = LED_OFF; |
1358 | pLed->BlinkingLedState = LED_OFF; | 1358 | pLed->BlinkingLedState = LED_OFF; |
1359 | if (pLed->bLedBlinkInProgress) { | 1359 | if (pLed->bLedBlinkInProgress) { |
1360 | del_timer_sync(&pLed->BlinkTimer); | 1360 | del_timer(&pLed->BlinkTimer); |
1361 | pLed->bLedBlinkInProgress = false; | 1361 | pLed->bLedBlinkInProgress = false; |
1362 | } | 1362 | } |
1363 | if (pLed->bLedScanBlinkInProgress) { | 1363 | if (pLed->bLedScanBlinkInProgress) { |
1364 | del_timer_sync(&pLed->BlinkTimer); | 1364 | del_timer(&pLed->BlinkTimer); |
1365 | pLed->bLedScanBlinkInProgress = false; | 1365 | pLed->bLedScanBlinkInProgress = false; |
1366 | } | 1366 | } |
1367 | if (pLed->bLedWPSBlinkInProgress) { | 1367 | if (pLed->bLedWPSBlinkInProgress) { |
1368 | del_timer_sync(&pLed->BlinkTimer); | 1368 | del_timer(&pLed->BlinkTimer); |
1369 | pLed->bLedWPSBlinkInProgress = false; | 1369 | pLed->bLedWPSBlinkInProgress = false; |
1370 | } | 1370 | } |
1371 | mod_timer(&pLed->BlinkTimer, | 1371 | mod_timer(&pLed->BlinkTimer, |
@@ -1388,7 +1388,7 @@ static void SwLedControlMode4(struct _adapter *padapter, | |||
1388 | case LED_CTL_START_TO_LINK: | 1388 | case LED_CTL_START_TO_LINK: |
1389 | if (pLed1->bLedWPSBlinkInProgress) { | 1389 | if (pLed1->bLedWPSBlinkInProgress) { |
1390 | pLed1->bLedWPSBlinkInProgress = false; | 1390 | pLed1->bLedWPSBlinkInProgress = false; |
1391 | del_timer_sync(&pLed1->BlinkTimer); | 1391 | del_timer(&pLed1->BlinkTimer); |
1392 | pLed1->BlinkingLedState = LED_OFF; | 1392 | pLed1->BlinkingLedState = LED_OFF; |
1393 | pLed1->CurrLedState = LED_OFF; | 1393 | pLed1->CurrLedState = LED_OFF; |
1394 | if (pLed1->bLedOn) | 1394 | if (pLed1->bLedOn) |
@@ -1400,11 +1400,11 @@ static void SwLedControlMode4(struct _adapter *padapter, | |||
1400 | IS_LED_WPS_BLINKING(pLed)) | 1400 | IS_LED_WPS_BLINKING(pLed)) |
1401 | return; | 1401 | return; |
1402 | if (pLed->bLedBlinkInProgress == true) { | 1402 | if (pLed->bLedBlinkInProgress == true) { |
1403 | del_timer_sync(&pLed->BlinkTimer); | 1403 | del_timer(&pLed->BlinkTimer); |
1404 | pLed->bLedBlinkInProgress = false; | 1404 | pLed->bLedBlinkInProgress = false; |
1405 | } | 1405 | } |
1406 | if (pLed->bLedNoLinkBlinkInProgress == true) { | 1406 | if (pLed->bLedNoLinkBlinkInProgress == true) { |
1407 | del_timer_sync(&pLed->BlinkTimer); | 1407 | del_timer(&pLed->BlinkTimer); |
1408 | pLed->bLedNoLinkBlinkInProgress = false; | 1408 | pLed->bLedNoLinkBlinkInProgress = false; |
1409 | } | 1409 | } |
1410 | pLed->bLedStartToLinkBlinkInProgress = true; | 1410 | pLed->bLedStartToLinkBlinkInProgress = true; |
@@ -1426,7 +1426,7 @@ static void SwLedControlMode4(struct _adapter *padapter, | |||
1426 | if (LedAction == LED_CTL_LINK) { | 1426 | if (LedAction == LED_CTL_LINK) { |
1427 | if (pLed1->bLedWPSBlinkInProgress) { | 1427 | if (pLed1->bLedWPSBlinkInProgress) { |
1428 | pLed1->bLedWPSBlinkInProgress = false; | 1428 | pLed1->bLedWPSBlinkInProgress = false; |
1429 | del_timer_sync(&pLed1->BlinkTimer); | 1429 | del_timer(&pLed1->BlinkTimer); |
1430 | pLed1->BlinkingLedState = LED_OFF; | 1430 | pLed1->BlinkingLedState = LED_OFF; |
1431 | pLed1->CurrLedState = LED_OFF; | 1431 | pLed1->CurrLedState = LED_OFF; |
1432 | if (pLed1->bLedOn) | 1432 | if (pLed1->bLedOn) |
@@ -1439,7 +1439,7 @@ static void SwLedControlMode4(struct _adapter *padapter, | |||
1439 | IS_LED_WPS_BLINKING(pLed)) | 1439 | IS_LED_WPS_BLINKING(pLed)) |
1440 | return; | 1440 | return; |
1441 | if (pLed->bLedBlinkInProgress == true) { | 1441 | if (pLed->bLedBlinkInProgress == true) { |
1442 | del_timer_sync(&pLed->BlinkTimer); | 1442 | del_timer(&pLed->BlinkTimer); |
1443 | pLed->bLedBlinkInProgress = false; | 1443 | pLed->bLedBlinkInProgress = false; |
1444 | } | 1444 | } |
1445 | pLed->bLedNoLinkBlinkInProgress = true; | 1445 | pLed->bLedNoLinkBlinkInProgress = true; |
@@ -1460,11 +1460,11 @@ static void SwLedControlMode4(struct _adapter *padapter, | |||
1460 | if (IS_LED_WPS_BLINKING(pLed)) | 1460 | if (IS_LED_WPS_BLINKING(pLed)) |
1461 | return; | 1461 | return; |
1462 | if (pLed->bLedNoLinkBlinkInProgress == true) { | 1462 | if (pLed->bLedNoLinkBlinkInProgress == true) { |
1463 | del_timer_sync(&pLed->BlinkTimer); | 1463 | del_timer(&pLed->BlinkTimer); |
1464 | pLed->bLedNoLinkBlinkInProgress = false; | 1464 | pLed->bLedNoLinkBlinkInProgress = false; |
1465 | } | 1465 | } |
1466 | if (pLed->bLedBlinkInProgress == true) { | 1466 | if (pLed->bLedBlinkInProgress == true) { |
1467 | del_timer_sync(&pLed->BlinkTimer); | 1467 | del_timer(&pLed->BlinkTimer); |
1468 | pLed->bLedBlinkInProgress = false; | 1468 | pLed->bLedBlinkInProgress = false; |
1469 | } | 1469 | } |
1470 | pLed->bLedScanBlinkInProgress = true; | 1470 | pLed->bLedScanBlinkInProgress = true; |
@@ -1485,7 +1485,7 @@ static void SwLedControlMode4(struct _adapter *padapter, | |||
1485 | IS_LED_WPS_BLINKING(pLed)) | 1485 | IS_LED_WPS_BLINKING(pLed)) |
1486 | return; | 1486 | return; |
1487 | if (pLed->bLedNoLinkBlinkInProgress == true) { | 1487 | if (pLed->bLedNoLinkBlinkInProgress == true) { |
1488 | del_timer_sync(&pLed->BlinkTimer); | 1488 | del_timer(&pLed->BlinkTimer); |
1489 | pLed->bLedNoLinkBlinkInProgress = false; | 1489 | pLed->bLedNoLinkBlinkInProgress = false; |
1490 | } | 1490 | } |
1491 | pLed->bLedBlinkInProgress = true; | 1491 | pLed->bLedBlinkInProgress = true; |
@@ -1503,7 +1503,7 @@ static void SwLedControlMode4(struct _adapter *padapter, | |||
1503 | case LED_CTL_START_WPS_BOTTON: | 1503 | case LED_CTL_START_WPS_BOTTON: |
1504 | if (pLed1->bLedWPSBlinkInProgress) { | 1504 | if (pLed1->bLedWPSBlinkInProgress) { |
1505 | pLed1->bLedWPSBlinkInProgress = false; | 1505 | pLed1->bLedWPSBlinkInProgress = false; |
1506 | del_timer_sync(&(pLed1->BlinkTimer)); | 1506 | del_timer(&pLed1->BlinkTimer); |
1507 | pLed1->BlinkingLedState = LED_OFF; | 1507 | pLed1->BlinkingLedState = LED_OFF; |
1508 | pLed1->CurrLedState = LED_OFF; | 1508 | pLed1->CurrLedState = LED_OFF; |
1509 | if (pLed1->bLedOn) | 1509 | if (pLed1->bLedOn) |
@@ -1512,15 +1512,15 @@ static void SwLedControlMode4(struct _adapter *padapter, | |||
1512 | } | 1512 | } |
1513 | if (pLed->bLedWPSBlinkInProgress == false) { | 1513 | if (pLed->bLedWPSBlinkInProgress == false) { |
1514 | if (pLed->bLedNoLinkBlinkInProgress == true) { | 1514 | if (pLed->bLedNoLinkBlinkInProgress == true) { |
1515 | del_timer_sync(&pLed->BlinkTimer); | 1515 | del_timer(&pLed->BlinkTimer); |
1516 | pLed->bLedNoLinkBlinkInProgress = false; | 1516 | pLed->bLedNoLinkBlinkInProgress = false; |
1517 | } | 1517 | } |
1518 | if (pLed->bLedBlinkInProgress == true) { | 1518 | if (pLed->bLedBlinkInProgress == true) { |
1519 | del_timer_sync(&pLed->BlinkTimer); | 1519 | del_timer(&pLed->BlinkTimer); |
1520 | pLed->bLedBlinkInProgress = false; | 1520 | pLed->bLedBlinkInProgress = false; |
1521 | } | 1521 | } |
1522 | if (pLed->bLedScanBlinkInProgress == true) { | 1522 | if (pLed->bLedScanBlinkInProgress == true) { |
1523 | del_timer_sync(&pLed->BlinkTimer); | 1523 | del_timer(&pLed->BlinkTimer); |
1524 | pLed->bLedScanBlinkInProgress = false; | 1524 | pLed->bLedScanBlinkInProgress = false; |
1525 | } | 1525 | } |
1526 | pLed->bLedWPSBlinkInProgress = true; | 1526 | pLed->bLedWPSBlinkInProgress = true; |
@@ -1538,7 +1538,7 @@ static void SwLedControlMode4(struct _adapter *padapter, | |||
1538 | break; | 1538 | break; |
1539 | case LED_CTL_STOP_WPS: /*WPS connect success*/ | 1539 | case LED_CTL_STOP_WPS: /*WPS connect success*/ |
1540 | if (pLed->bLedWPSBlinkInProgress) { | 1540 | if (pLed->bLedWPSBlinkInProgress) { |
1541 | del_timer_sync(&pLed->BlinkTimer); | 1541 | del_timer(&pLed->BlinkTimer); |
1542 | pLed->bLedWPSBlinkInProgress = false; | 1542 | pLed->bLedWPSBlinkInProgress = false; |
1543 | } | 1543 | } |
1544 | pLed->bLedNoLinkBlinkInProgress = true; | 1544 | pLed->bLedNoLinkBlinkInProgress = true; |
@@ -1552,7 +1552,7 @@ static void SwLedControlMode4(struct _adapter *padapter, | |||
1552 | break; | 1552 | break; |
1553 | case LED_CTL_STOP_WPS_FAIL: /*WPS authentication fail*/ | 1553 | case LED_CTL_STOP_WPS_FAIL: /*WPS authentication fail*/ |
1554 | if (pLed->bLedWPSBlinkInProgress) { | 1554 | if (pLed->bLedWPSBlinkInProgress) { |
1555 | del_timer_sync(&pLed->BlinkTimer); | 1555 | del_timer(&pLed->BlinkTimer); |
1556 | pLed->bLedWPSBlinkInProgress = false; | 1556 | pLed->bLedWPSBlinkInProgress = false; |
1557 | } | 1557 | } |
1558 | pLed->bLedNoLinkBlinkInProgress = true; | 1558 | pLed->bLedNoLinkBlinkInProgress = true; |
@@ -1565,7 +1565,7 @@ static void SwLedControlMode4(struct _adapter *padapter, | |||
1565 | msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); | 1565 | msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); |
1566 | /*LED1 settings*/ | 1566 | /*LED1 settings*/ |
1567 | if (pLed1->bLedWPSBlinkInProgress) | 1567 | if (pLed1->bLedWPSBlinkInProgress) |
1568 | del_timer_sync(&pLed1->BlinkTimer); | 1568 | del_timer(&pLed1->BlinkTimer); |
1569 | else | 1569 | else |
1570 | pLed1->bLedWPSBlinkInProgress = true; | 1570 | pLed1->bLedWPSBlinkInProgress = true; |
1571 | pLed1->CurrLedState = LED_BLINK_WPS_STOP; | 1571 | pLed1->CurrLedState = LED_BLINK_WPS_STOP; |
@@ -1578,7 +1578,7 @@ static void SwLedControlMode4(struct _adapter *padapter, | |||
1578 | break; | 1578 | break; |
1579 | case LED_CTL_STOP_WPS_FAIL_OVERLAP: /*WPS session overlap*/ | 1579 | case LED_CTL_STOP_WPS_FAIL_OVERLAP: /*WPS session overlap*/ |
1580 | if (pLed->bLedWPSBlinkInProgress) { | 1580 | if (pLed->bLedWPSBlinkInProgress) { |
1581 | del_timer_sync(&pLed->BlinkTimer); | 1581 | del_timer(&pLed->BlinkTimer); |
1582 | pLed->bLedWPSBlinkInProgress = false; | 1582 | pLed->bLedWPSBlinkInProgress = false; |
1583 | } | 1583 | } |
1584 | pLed->bLedNoLinkBlinkInProgress = true; | 1584 | pLed->bLedNoLinkBlinkInProgress = true; |
@@ -1591,7 +1591,7 @@ static void SwLedControlMode4(struct _adapter *padapter, | |||
1591 | msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); | 1591 | msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); |
1592 | /*LED1 settings*/ | 1592 | /*LED1 settings*/ |
1593 | if (pLed1->bLedWPSBlinkInProgress) | 1593 | if (pLed1->bLedWPSBlinkInProgress) |
1594 | del_timer_sync(&pLed1->BlinkTimer); | 1594 | del_timer(&pLed1->BlinkTimer); |
1595 | else | 1595 | else |
1596 | pLed1->bLedWPSBlinkInProgress = true; | 1596 | pLed1->bLedWPSBlinkInProgress = true; |
1597 | pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP; | 1597 | pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP; |
@@ -1607,31 +1607,31 @@ static void SwLedControlMode4(struct _adapter *padapter, | |||
1607 | pLed->CurrLedState = LED_OFF; | 1607 | pLed->CurrLedState = LED_OFF; |
1608 | pLed->BlinkingLedState = LED_OFF; | 1608 | pLed->BlinkingLedState = LED_OFF; |
1609 | if (pLed->bLedNoLinkBlinkInProgress) { | 1609 | if (pLed->bLedNoLinkBlinkInProgress) { |
1610 | del_timer_sync(&pLed->BlinkTimer); | 1610 | del_timer(&pLed->BlinkTimer); |
1611 | pLed->bLedNoLinkBlinkInProgress = false; | 1611 | pLed->bLedNoLinkBlinkInProgress = false; |
1612 | } | 1612 | } |
1613 | if (pLed->bLedLinkBlinkInProgress) { | 1613 | if (pLed->bLedLinkBlinkInProgress) { |
1614 | del_timer_sync(&pLed->BlinkTimer); | 1614 | del_timer(&pLed->BlinkTimer); |
1615 | pLed->bLedLinkBlinkInProgress = false; | 1615 | pLed->bLedLinkBlinkInProgress = false; |
1616 | } | 1616 | } |
1617 | if (pLed->bLedBlinkInProgress) { | 1617 | if (pLed->bLedBlinkInProgress) { |
1618 | del_timer_sync(&pLed->BlinkTimer); | 1618 | del_timer(&pLed->BlinkTimer); |
1619 | pLed->bLedBlinkInProgress = false; | 1619 | pLed->bLedBlinkInProgress = false; |
1620 | } | 1620 | } |
1621 | if (pLed->bLedWPSBlinkInProgress) { | 1621 | if (pLed->bLedWPSBlinkInProgress) { |
1622 | del_timer_sync(&pLed->BlinkTimer); | 1622 | del_timer(&pLed->BlinkTimer); |
1623 | pLed->bLedWPSBlinkInProgress = false; | 1623 | pLed->bLedWPSBlinkInProgress = false; |
1624 | } | 1624 | } |
1625 | if (pLed->bLedScanBlinkInProgress) { | 1625 | if (pLed->bLedScanBlinkInProgress) { |
1626 | del_timer_sync(&pLed->BlinkTimer); | 1626 | del_timer(&pLed->BlinkTimer); |
1627 | pLed->bLedScanBlinkInProgress = false; | 1627 | pLed->bLedScanBlinkInProgress = false; |
1628 | } | 1628 | } |
1629 | if (pLed->bLedStartToLinkBlinkInProgress) { | 1629 | if (pLed->bLedStartToLinkBlinkInProgress) { |
1630 | del_timer_sync(&pLed->BlinkTimer); | 1630 | del_timer(&pLed->BlinkTimer); |
1631 | pLed->bLedStartToLinkBlinkInProgress = false; | 1631 | pLed->bLedStartToLinkBlinkInProgress = false; |
1632 | } | 1632 | } |
1633 | if (pLed1->bLedWPSBlinkInProgress) { | 1633 | if (pLed1->bLedWPSBlinkInProgress) { |
1634 | del_timer_sync(&pLed1->BlinkTimer); | 1634 | del_timer(&pLed1->BlinkTimer); |
1635 | pLed1->bLedWPSBlinkInProgress = false; | 1635 | pLed1->bLedWPSBlinkInProgress = false; |
1636 | } | 1636 | } |
1637 | pLed1->BlinkingLedState = LED_UNKNOWN; | 1637 | pLed1->BlinkingLedState = LED_UNKNOWN; |
@@ -1671,7 +1671,7 @@ static void SwLedControlMode5(struct _adapter *padapter, | |||
1671 | ; /* dummy branch */ | 1671 | ; /* dummy branch */ |
1672 | else if (pLed->bLedScanBlinkInProgress == false) { | 1672 | else if (pLed->bLedScanBlinkInProgress == false) { |
1673 | if (pLed->bLedBlinkInProgress == true) { | 1673 | if (pLed->bLedBlinkInProgress == true) { |
1674 | del_timer_sync(&pLed->BlinkTimer); | 1674 | del_timer(&pLed->BlinkTimer); |
1675 | pLed->bLedBlinkInProgress = false; | 1675 | pLed->bLedBlinkInProgress = false; |
1676 | } | 1676 | } |
1677 | pLed->bLedScanBlinkInProgress = true; | 1677 | pLed->bLedScanBlinkInProgress = true; |
@@ -1705,7 +1705,7 @@ static void SwLedControlMode5(struct _adapter *padapter, | |||
1705 | pLed->CurrLedState = LED_OFF; | 1705 | pLed->CurrLedState = LED_OFF; |
1706 | pLed->BlinkingLedState = LED_OFF; | 1706 | pLed->BlinkingLedState = LED_OFF; |
1707 | if (pLed->bLedBlinkInProgress) { | 1707 | if (pLed->bLedBlinkInProgress) { |
1708 | del_timer_sync(&pLed->BlinkTimer); | 1708 | del_timer(&pLed->BlinkTimer); |
1709 | pLed->bLedBlinkInProgress = false; | 1709 | pLed->bLedBlinkInProgress = false; |
1710 | } | 1710 | } |
1711 | SwLedOff(padapter, pLed); | 1711 | SwLedOff(padapter, pLed); |
@@ -1756,7 +1756,7 @@ static void SwLedControlMode6(struct _adapter *padapter, | |||
1756 | case LED_CTL_START_WPS_BOTTON: | 1756 | case LED_CTL_START_WPS_BOTTON: |
1757 | if (pLed->bLedWPSBlinkInProgress == false) { | 1757 | if (pLed->bLedWPSBlinkInProgress == false) { |
1758 | if (pLed->bLedBlinkInProgress == true) { | 1758 | if (pLed->bLedBlinkInProgress == true) { |
1759 | del_timer_sync(&pLed->BlinkTimer); | 1759 | del_timer(&pLed->BlinkTimer); |
1760 | pLed->bLedBlinkInProgress = false; | 1760 | pLed->bLedBlinkInProgress = false; |
1761 | } | 1761 | } |
1762 | pLed->bLedWPSBlinkInProgress = true; | 1762 | pLed->bLedWPSBlinkInProgress = true; |
@@ -1772,7 +1772,7 @@ static void SwLedControlMode6(struct _adapter *padapter, | |||
1772 | case LED_CTL_STOP_WPS_FAIL: | 1772 | case LED_CTL_STOP_WPS_FAIL: |
1773 | case LED_CTL_STOP_WPS: | 1773 | case LED_CTL_STOP_WPS: |
1774 | if (pLed->bLedWPSBlinkInProgress) { | 1774 | if (pLed->bLedWPSBlinkInProgress) { |
1775 | del_timer_sync(&pLed->BlinkTimer); | 1775 | del_timer(&pLed->BlinkTimer); |
1776 | pLed->bLedWPSBlinkInProgress = false; | 1776 | pLed->bLedWPSBlinkInProgress = false; |
1777 | } | 1777 | } |
1778 | pLed->CurrLedState = LED_ON; | 1778 | pLed->CurrLedState = LED_ON; |
@@ -1784,11 +1784,11 @@ static void SwLedControlMode6(struct _adapter *padapter, | |||
1784 | pLed->CurrLedState = LED_OFF; | 1784 | pLed->CurrLedState = LED_OFF; |
1785 | pLed->BlinkingLedState = LED_OFF; | 1785 | pLed->BlinkingLedState = LED_OFF; |
1786 | if (pLed->bLedBlinkInProgress) { | 1786 | if (pLed->bLedBlinkInProgress) { |
1787 | del_timer_sync(&pLed->BlinkTimer); | 1787 | del_timer(&pLed->BlinkTimer); |
1788 | pLed->bLedBlinkInProgress = false; | 1788 | pLed->bLedBlinkInProgress = false; |
1789 | } | 1789 | } |
1790 | if (pLed->bLedWPSBlinkInProgress) { | 1790 | if (pLed->bLedWPSBlinkInProgress) { |
1791 | del_timer_sync(&pLed->BlinkTimer); | 1791 | del_timer(&pLed->BlinkTimer); |
1792 | pLed->bLedWPSBlinkInProgress = false; | 1792 | pLed->bLedWPSBlinkInProgress = false; |
1793 | } | 1793 | } |
1794 | SwLedOff(padapter, pLed); | 1794 | SwLedOff(padapter, pLed); |
diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c index 1a1c38f885d6..e35854d28f90 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.c +++ b/drivers/staging/rtl8712/rtl871x_cmd.c | |||
@@ -910,7 +910,7 @@ void r8712_createbss_cmd_callback(struct _adapter *padapter, | |||
910 | if (pcmd->res != H2C_SUCCESS) | 910 | if (pcmd->res != H2C_SUCCESS) |
911 | mod_timer(&pmlmepriv->assoc_timer, | 911 | mod_timer(&pmlmepriv->assoc_timer, |
912 | jiffies + msecs_to_jiffies(1)); | 912 | jiffies + msecs_to_jiffies(1)); |
913 | del_timer_sync(&pmlmepriv->assoc_timer); | 913 | del_timer(&pmlmepriv->assoc_timer); |
914 | #ifdef __BIG_ENDIAN | 914 | #ifdef __BIG_ENDIAN |
915 | /* endian_convert */ | 915 | /* endian_convert */ |
916 | pnetwork->Length = le32_to_cpu(pnetwork->Length); | 916 | pnetwork->Length = le32_to_cpu(pnetwork->Length); |
diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index fb2b195b90af..c044b0e55ba9 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c | |||
@@ -582,7 +582,7 @@ void r8712_surveydone_event_callback(struct _adapter *adapter, u8 *pbuf) | |||
582 | spin_lock_irqsave(&pmlmepriv->lock, irqL); | 582 | spin_lock_irqsave(&pmlmepriv->lock, irqL); |
583 | 583 | ||
584 | if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) { | 584 | if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) { |
585 | del_timer_sync(&pmlmepriv->scan_to_timer); | 585 | del_timer(&pmlmepriv->scan_to_timer); |
586 | 586 | ||
587 | _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); | 587 | _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); |
588 | } | 588 | } |
@@ -696,7 +696,7 @@ void r8712_ind_disconnect(struct _adapter *padapter) | |||
696 | } | 696 | } |
697 | if (padapter->pwrctrlpriv.pwr_mode != | 697 | if (padapter->pwrctrlpriv.pwr_mode != |
698 | padapter->registrypriv.power_mgnt) { | 698 | padapter->registrypriv.power_mgnt) { |
699 | del_timer_sync(&pmlmepriv->dhcp_timer); | 699 | del_timer(&pmlmepriv->dhcp_timer); |
700 | r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt, | 700 | r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt, |
701 | padapter->registrypriv.smart_ps); | 701 | padapter->registrypriv.smart_ps); |
702 | } | 702 | } |
@@ -910,7 +910,7 @@ void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf) | |||
910 | if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) | 910 | if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) |
911 | == true) | 911 | == true) |
912 | r8712_indicate_connect(adapter); | 912 | r8712_indicate_connect(adapter); |
913 | del_timer_sync(&pmlmepriv->assoc_timer); | 913 | del_timer(&pmlmepriv->assoc_timer); |
914 | } else | 914 | } else |
915 | goto ignore_joinbss_callback; | 915 | goto ignore_joinbss_callback; |
916 | } else { | 916 | } else { |
diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.c b/drivers/staging/rtl8712/rtl871x_pwrctrl.c index aaa584435c87..9bc04f474d18 100644 --- a/drivers/staging/rtl8712/rtl871x_pwrctrl.c +++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.c | |||
@@ -103,7 +103,7 @@ void r8712_cpwm_int_hdl(struct _adapter *padapter, | |||
103 | 103 | ||
104 | if (pwrpriv->cpwm_tog == ((preportpwrstate->state) & 0x80)) | 104 | if (pwrpriv->cpwm_tog == ((preportpwrstate->state) & 0x80)) |
105 | return; | 105 | return; |
106 | del_timer_sync(&padapter->pwrctrlpriv.rpwm_check_timer); | 106 | del_timer(&padapter->pwrctrlpriv.rpwm_check_timer); |
107 | _enter_pwrlock(&pwrpriv->lock); | 107 | _enter_pwrlock(&pwrpriv->lock); |
108 | pwrpriv->cpwm = (preportpwrstate->state) & 0xf; | 108 | pwrpriv->cpwm = (preportpwrstate->state) & 0xf; |
109 | if (pwrpriv->cpwm >= PS_STATE_S2) { | 109 | if (pwrpriv->cpwm >= PS_STATE_S2) { |
diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c index 7bb96c47f188..a9b93d0f6f56 100644 --- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c +++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c | |||
@@ -198,7 +198,7 @@ void r8712_free_stainfo(struct _adapter *padapter, struct sta_info *psta) | |||
198 | * cancel reordering_ctrl_timer */ | 198 | * cancel reordering_ctrl_timer */ |
199 | for (i = 0; i < 16; i++) { | 199 | for (i = 0; i < 16; i++) { |
200 | preorder_ctrl = &psta->recvreorder_ctrl[i]; | 200 | preorder_ctrl = &psta->recvreorder_ctrl[i]; |
201 | del_timer_sync(&preorder_ctrl->reordering_ctrl_timer); | 201 | del_timer(&preorder_ctrl->reordering_ctrl_timer); |
202 | } | 202 | } |
203 | spin_lock(&(pfree_sta_queue->lock)); | 203 | spin_lock(&(pfree_sta_queue->lock)); |
204 | /* insert into free_sta_queue; 20061114 */ | 204 | /* insert into free_sta_queue; 20061114 */ |
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index cc57a3a6b02b..396344cb011f 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -162,6 +162,17 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, | |||
162 | return put_user(x, ptr); | 162 | return put_user(x, ptr); |
163 | } | 163 | } |
164 | 164 | ||
165 | static inline int tty_copy_to_user(struct tty_struct *tty, | ||
166 | void __user *to, | ||
167 | const void *from, | ||
168 | unsigned long n) | ||
169 | { | ||
170 | struct n_tty_data *ldata = tty->disc_data; | ||
171 | |||
172 | tty_audit_add_data(tty, to, n, ldata->icanon); | ||
173 | return copy_to_user(to, from, n); | ||
174 | } | ||
175 | |||
165 | /** | 176 | /** |
166 | * n_tty_kick_worker - start input worker (if required) | 177 | * n_tty_kick_worker - start input worker (if required) |
167 | * @tty: terminal | 178 | * @tty: terminal |
@@ -2070,8 +2081,8 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, | |||
2070 | 2081 | ||
2071 | size = N_TTY_BUF_SIZE - tail; | 2082 | size = N_TTY_BUF_SIZE - tail; |
2072 | n = eol - tail; | 2083 | n = eol - tail; |
2073 | if (n > 4096) | 2084 | if (n > N_TTY_BUF_SIZE) |
2074 | n += 4096; | 2085 | n += N_TTY_BUF_SIZE; |
2075 | n += found; | 2086 | n += found; |
2076 | c = n; | 2087 | c = n; |
2077 | 2088 | ||
@@ -2084,12 +2095,12 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, | |||
2084 | __func__, eol, found, n, c, size, more); | 2095 | __func__, eol, found, n, c, size, more); |
2085 | 2096 | ||
2086 | if (n > size) { | 2097 | if (n > size) { |
2087 | ret = copy_to_user(*b, read_buf_addr(ldata, tail), size); | 2098 | ret = tty_copy_to_user(tty, *b, read_buf_addr(ldata, tail), size); |
2088 | if (ret) | 2099 | if (ret) |
2089 | return -EFAULT; | 2100 | return -EFAULT; |
2090 | ret = copy_to_user(*b + size, ldata->read_buf, n - size); | 2101 | ret = tty_copy_to_user(tty, *b + size, ldata->read_buf, n - size); |
2091 | } else | 2102 | } else |
2092 | ret = copy_to_user(*b, read_buf_addr(ldata, tail), n); | 2103 | ret = tty_copy_to_user(tty, *b, read_buf_addr(ldata, tail), n); |
2093 | 2104 | ||
2094 | if (ret) | 2105 | if (ret) |
2095 | return -EFAULT; | 2106 | return -EFAULT; |
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 9289999cb7c6..dce1a23706e8 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c | |||
@@ -562,12 +562,36 @@ static irqreturn_t omap_wake_irq(int irq, void *dev_id) | |||
562 | return IRQ_NONE; | 562 | return IRQ_NONE; |
563 | } | 563 | } |
564 | 564 | ||
565 | #ifdef CONFIG_SERIAL_8250_DMA | ||
566 | static int omap_8250_dma_handle_irq(struct uart_port *port); | ||
567 | #endif | ||
568 | |||
569 | static irqreturn_t omap8250_irq(int irq, void *dev_id) | ||
570 | { | ||
571 | struct uart_port *port = dev_id; | ||
572 | struct uart_8250_port *up = up_to_u8250p(port); | ||
573 | unsigned int iir; | ||
574 | int ret; | ||
575 | |||
576 | #ifdef CONFIG_SERIAL_8250_DMA | ||
577 | if (up->dma) { | ||
578 | ret = omap_8250_dma_handle_irq(port); | ||
579 | return IRQ_RETVAL(ret); | ||
580 | } | ||
581 | #endif | ||
582 | |||
583 | serial8250_rpm_get(up); | ||
584 | iir = serial_port_in(port, UART_IIR); | ||
585 | ret = serial8250_handle_irq(port, iir); | ||
586 | serial8250_rpm_put(up); | ||
587 | |||
588 | return IRQ_RETVAL(ret); | ||
589 | } | ||
590 | |||
565 | static int omap_8250_startup(struct uart_port *port) | 591 | static int omap_8250_startup(struct uart_port *port) |
566 | { | 592 | { |
567 | struct uart_8250_port *up = | 593 | struct uart_8250_port *up = up_to_u8250p(port); |
568 | container_of(port, struct uart_8250_port, port); | ||
569 | struct omap8250_priv *priv = port->private_data; | 594 | struct omap8250_priv *priv = port->private_data; |
570 | |||
571 | int ret; | 595 | int ret; |
572 | 596 | ||
573 | if (priv->wakeirq) { | 597 | if (priv->wakeirq) { |
@@ -580,10 +604,31 @@ static int omap_8250_startup(struct uart_port *port) | |||
580 | 604 | ||
581 | pm_runtime_get_sync(port->dev); | 605 | pm_runtime_get_sync(port->dev); |
582 | 606 | ||
583 | ret = serial8250_do_startup(port); | 607 | up->mcr = 0; |
584 | if (ret) | 608 | serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); |
609 | |||
610 | serial_out(up, UART_LCR, UART_LCR_WLEN8); | ||
611 | |||
612 | up->lsr_saved_flags = 0; | ||
613 | up->msr_saved_flags = 0; | ||
614 | |||
615 | if (up->dma) { | ||
616 | ret = serial8250_request_dma(up); | ||
617 | if (ret) { | ||
618 | dev_warn_ratelimited(port->dev, | ||
619 | "failed to request DMA\n"); | ||
620 | up->dma = NULL; | ||
621 | } | ||
622 | } | ||
623 | |||
624 | ret = request_irq(port->irq, omap8250_irq, IRQF_SHARED, | ||
625 | dev_name(port->dev), port); | ||
626 | if (ret < 0) | ||
585 | goto err; | 627 | goto err; |
586 | 628 | ||
629 | up->ier = UART_IER_RLSI | UART_IER_RDI; | ||
630 | serial_out(up, UART_IER, up->ier); | ||
631 | |||
587 | #ifdef CONFIG_PM | 632 | #ifdef CONFIG_PM |
588 | up->capabilities |= UART_CAP_RPM; | 633 | up->capabilities |= UART_CAP_RPM; |
589 | #endif | 634 | #endif |
@@ -610,8 +655,7 @@ err: | |||
610 | 655 | ||
611 | static void omap_8250_shutdown(struct uart_port *port) | 656 | static void omap_8250_shutdown(struct uart_port *port) |
612 | { | 657 | { |
613 | struct uart_8250_port *up = | 658 | struct uart_8250_port *up = up_to_u8250p(port); |
614 | container_of(port, struct uart_8250_port, port); | ||
615 | struct omap8250_priv *priv = port->private_data; | 659 | struct omap8250_priv *priv = port->private_data; |
616 | 660 | ||
617 | flush_work(&priv->qos_work); | 661 | flush_work(&priv->qos_work); |
@@ -621,11 +665,24 @@ static void omap_8250_shutdown(struct uart_port *port) | |||
621 | pm_runtime_get_sync(port->dev); | 665 | pm_runtime_get_sync(port->dev); |
622 | 666 | ||
623 | serial_out(up, UART_OMAP_WER, 0); | 667 | serial_out(up, UART_OMAP_WER, 0); |
624 | serial8250_do_shutdown(port); | 668 | |
669 | up->ier = 0; | ||
670 | serial_out(up, UART_IER, 0); | ||
671 | |||
672 | if (up->dma) | ||
673 | serial8250_release_dma(up); | ||
674 | |||
675 | /* | ||
676 | * Disable break condition and FIFOs | ||
677 | */ | ||
678 | if (up->lcr & UART_LCR_SBC) | ||
679 | serial_out(up, UART_LCR, up->lcr & ~UART_LCR_SBC); | ||
680 | serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | ||
625 | 681 | ||
626 | pm_runtime_mark_last_busy(port->dev); | 682 | pm_runtime_mark_last_busy(port->dev); |
627 | pm_runtime_put_autosuspend(port->dev); | 683 | pm_runtime_put_autosuspend(port->dev); |
628 | 684 | ||
685 | free_irq(port->irq, port); | ||
629 | if (priv->wakeirq) | 686 | if (priv->wakeirq) |
630 | free_irq(priv->wakeirq, port); | 687 | free_irq(priv->wakeirq, port); |
631 | } | 688 | } |
@@ -974,6 +1031,13 @@ static inline int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | |||
974 | } | 1031 | } |
975 | #endif | 1032 | #endif |
976 | 1033 | ||
1034 | static int omap8250_no_handle_irq(struct uart_port *port) | ||
1035 | { | ||
1036 | /* IRQ has not been requested but handling irq? */ | ||
1037 | WARN_ONCE(1, "Unexpected irq handling before port startup\n"); | ||
1038 | return 0; | ||
1039 | } | ||
1040 | |||
977 | static int omap8250_probe(struct platform_device *pdev) | 1041 | static int omap8250_probe(struct platform_device *pdev) |
978 | { | 1042 | { |
979 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1043 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -1075,6 +1139,7 @@ static int omap8250_probe(struct platform_device *pdev) | |||
1075 | pm_runtime_get_sync(&pdev->dev); | 1139 | pm_runtime_get_sync(&pdev->dev); |
1076 | 1140 | ||
1077 | omap_serial_fill_features_erratas(&up, priv); | 1141 | omap_serial_fill_features_erratas(&up, priv); |
1142 | up.port.handle_irq = omap8250_no_handle_irq; | ||
1078 | #ifdef CONFIG_SERIAL_8250_DMA | 1143 | #ifdef CONFIG_SERIAL_8250_DMA |
1079 | if (pdev->dev.of_node) { | 1144 | if (pdev->dev.of_node) { |
1080 | /* | 1145 | /* |
@@ -1088,7 +1153,6 @@ static int omap8250_probe(struct platform_device *pdev) | |||
1088 | ret = of_property_count_strings(pdev->dev.of_node, "dma-names"); | 1153 | ret = of_property_count_strings(pdev->dev.of_node, "dma-names"); |
1089 | if (ret == 2) { | 1154 | if (ret == 2) { |
1090 | up.dma = &priv->omap8250_dma; | 1155 | up.dma = &priv->omap8250_dma; |
1091 | up.port.handle_irq = omap_8250_dma_handle_irq; | ||
1092 | priv->omap8250_dma.fn = the_no_dma_filter_fn; | 1156 | priv->omap8250_dma.fn = the_no_dma_filter_fn; |
1093 | priv->omap8250_dma.tx_dma = omap_8250_tx_dma; | 1157 | priv->omap8250_dma.tx_dma = omap_8250_tx_dma; |
1094 | priv->omap8250_dma.rx_dma = omap_8250_rx_dma; | 1158 | priv->omap8250_dma.rx_dma = omap_8250_rx_dma; |
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 6f5a0720a8c8..763eb20fe321 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -1249,20 +1249,19 @@ __acquires(&uap->port.lock) | |||
1249 | 1249 | ||
1250 | /* | 1250 | /* |
1251 | * Transmit a character | 1251 | * Transmit a character |
1252 | * There must be at least one free entry in the TX FIFO to accept the char. | ||
1253 | * | 1252 | * |
1254 | * Returns true if the FIFO might have space in it afterwards; | 1253 | * Returns true if the character was successfully queued to the FIFO. |
1255 | * returns false if the FIFO definitely became full. | 1254 | * Returns false otherwise. |
1256 | */ | 1255 | */ |
1257 | static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c) | 1256 | static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c) |
1258 | { | 1257 | { |
1258 | if (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) | ||
1259 | return false; /* unable to transmit character */ | ||
1260 | |||
1259 | writew(c, uap->port.membase + UART01x_DR); | 1261 | writew(c, uap->port.membase + UART01x_DR); |
1260 | uap->port.icount.tx++; | 1262 | uap->port.icount.tx++; |
1261 | 1263 | ||
1262 | if (likely(uap->tx_irq_seen > 1)) | 1264 | return true; |
1263 | return true; | ||
1264 | |||
1265 | return !(readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF); | ||
1266 | } | 1265 | } |
1267 | 1266 | ||
1268 | static bool pl011_tx_chars(struct uart_amba_port *uap) | 1267 | static bool pl011_tx_chars(struct uart_amba_port *uap) |
@@ -1296,7 +1295,8 @@ static bool pl011_tx_chars(struct uart_amba_port *uap) | |||
1296 | return false; | 1295 | return false; |
1297 | 1296 | ||
1298 | if (uap->port.x_char) { | 1297 | if (uap->port.x_char) { |
1299 | pl011_tx_char(uap, uap->port.x_char); | 1298 | if (!pl011_tx_char(uap, uap->port.x_char)) |
1299 | goto done; | ||
1300 | uap->port.x_char = 0; | 1300 | uap->port.x_char = 0; |
1301 | --count; | 1301 | --count; |
1302 | } | 1302 | } |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index c8cfa0637128..88250395b0ce 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -911,6 +911,14 @@ static void dma_rx_callback(void *data) | |||
911 | 911 | ||
912 | status = dmaengine_tx_status(chan, (dma_cookie_t)0, &state); | 912 | status = dmaengine_tx_status(chan, (dma_cookie_t)0, &state); |
913 | count = RX_BUF_SIZE - state.residue; | 913 | count = RX_BUF_SIZE - state.residue; |
914 | |||
915 | if (readl(sport->port.membase + USR2) & USR2_IDLE) { | ||
916 | /* In condition [3] the SDMA counted up too early */ | ||
917 | count--; | ||
918 | |||
919 | writel(USR2_IDLE, sport->port.membase + USR2); | ||
920 | } | ||
921 | |||
914 | dev_dbg(sport->port.dev, "We get %d bytes.\n", count); | 922 | dev_dbg(sport->port.dev, "We get %d bytes.\n", count); |
915 | 923 | ||
916 | if (count) { | 924 | if (count) { |
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index fdab715a0631..c0eafa6fd403 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h | |||
@@ -339,7 +339,7 @@ | |||
339 | #define DWC3_DGCMD_SET_ENDPOINT_NRDY 0x0c | 339 | #define DWC3_DGCMD_SET_ENDPOINT_NRDY 0x0c |
340 | #define DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK 0x10 | 340 | #define DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK 0x10 |
341 | 341 | ||
342 | #define DWC3_DGCMD_STATUS(n) (((n) >> 15) & 1) | 342 | #define DWC3_DGCMD_STATUS(n) (((n) >> 12) & 0x0F) |
343 | #define DWC3_DGCMD_CMDACT (1 << 10) | 343 | #define DWC3_DGCMD_CMDACT (1 << 10) |
344 | #define DWC3_DGCMD_CMDIOC (1 << 8) | 344 | #define DWC3_DGCMD_CMDIOC (1 << 8) |
345 | 345 | ||
@@ -355,7 +355,7 @@ | |||
355 | #define DWC3_DEPCMD_PARAM_SHIFT 16 | 355 | #define DWC3_DEPCMD_PARAM_SHIFT 16 |
356 | #define DWC3_DEPCMD_PARAM(x) ((x) << DWC3_DEPCMD_PARAM_SHIFT) | 356 | #define DWC3_DEPCMD_PARAM(x) ((x) << DWC3_DEPCMD_PARAM_SHIFT) |
357 | #define DWC3_DEPCMD_GET_RSC_IDX(x) (((x) >> DWC3_DEPCMD_PARAM_SHIFT) & 0x7f) | 357 | #define DWC3_DEPCMD_GET_RSC_IDX(x) (((x) >> DWC3_DEPCMD_PARAM_SHIFT) & 0x7f) |
358 | #define DWC3_DEPCMD_STATUS(x) (((x) >> 15) & 1) | 358 | #define DWC3_DEPCMD_STATUS(x) (((x) >> 12) & 0x0F) |
359 | #define DWC3_DEPCMD_HIPRI_FORCERM (1 << 11) | 359 | #define DWC3_DEPCMD_HIPRI_FORCERM (1 << 11) |
360 | #define DWC3_DEPCMD_CMDACT (1 << 10) | 360 | #define DWC3_DEPCMD_CMDACT (1 << 10) |
361 | #define DWC3_DEPCMD_CMDIOC (1 << 8) | 361 | #define DWC3_DEPCMD_CMDIOC (1 << 8) |
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 6bdb57069044..3507f880eb74 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c | |||
@@ -315,7 +315,6 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf, | |||
315 | return ret; | 315 | return ret; |
316 | } | 316 | } |
317 | 317 | ||
318 | set_bit(FFS_FL_CALL_CLOSED_CALLBACK, &ffs->flags); | ||
319 | return len; | 318 | return len; |
320 | } | 319 | } |
321 | break; | 320 | break; |
@@ -847,7 +846,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) | |||
847 | ret = ep->status; | 846 | ret = ep->status; |
848 | if (io_data->read && ret > 0) { | 847 | if (io_data->read && ret > 0) { |
849 | ret = copy_to_iter(data, ret, &io_data->data); | 848 | ret = copy_to_iter(data, ret, &io_data->data); |
850 | if (unlikely(iov_iter_count(&io_data->data))) | 849 | if (!ret) |
851 | ret = -EFAULT; | 850 | ret = -EFAULT; |
852 | } | 851 | } |
853 | } | 852 | } |
@@ -1463,8 +1462,7 @@ static void ffs_data_clear(struct ffs_data *ffs) | |||
1463 | { | 1462 | { |
1464 | ENTER(); | 1463 | ENTER(); |
1465 | 1464 | ||
1466 | if (test_and_clear_bit(FFS_FL_CALL_CLOSED_CALLBACK, &ffs->flags)) | 1465 | ffs_closed(ffs); |
1467 | ffs_closed(ffs); | ||
1468 | 1466 | ||
1469 | BUG_ON(ffs->gadget); | 1467 | BUG_ON(ffs->gadget); |
1470 | 1468 | ||
@@ -3422,9 +3420,13 @@ static int ffs_ready(struct ffs_data *ffs) | |||
3422 | ffs_obj->desc_ready = true; | 3420 | ffs_obj->desc_ready = true; |
3423 | ffs_obj->ffs_data = ffs; | 3421 | ffs_obj->ffs_data = ffs; |
3424 | 3422 | ||
3425 | if (ffs_obj->ffs_ready_callback) | 3423 | if (ffs_obj->ffs_ready_callback) { |
3426 | ret = ffs_obj->ffs_ready_callback(ffs); | 3424 | ret = ffs_obj->ffs_ready_callback(ffs); |
3425 | if (ret) | ||
3426 | goto done; | ||
3427 | } | ||
3427 | 3428 | ||
3429 | set_bit(FFS_FL_CALL_CLOSED_CALLBACK, &ffs->flags); | ||
3428 | done: | 3430 | done: |
3429 | ffs_dev_unlock(); | 3431 | ffs_dev_unlock(); |
3430 | return ret; | 3432 | return ret; |
@@ -3443,7 +3445,8 @@ static void ffs_closed(struct ffs_data *ffs) | |||
3443 | 3445 | ||
3444 | ffs_obj->desc_ready = false; | 3446 | ffs_obj->desc_ready = false; |
3445 | 3447 | ||
3446 | if (ffs_obj->ffs_closed_callback) | 3448 | if (test_and_clear_bit(FFS_FL_CALL_CLOSED_CALLBACK, &ffs->flags) && |
3449 | ffs_obj->ffs_closed_callback) | ||
3447 | ffs_obj->ffs_closed_callback(ffs); | 3450 | ffs_obj->ffs_closed_callback(ffs); |
3448 | 3451 | ||
3449 | if (!ffs_obj->opts || ffs_obj->opts->no_configfs | 3452 | if (!ffs_obj->opts || ffs_obj->opts->no_configfs |
diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index 259b656c0b3e..6316aa5b1c49 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c | |||
@@ -973,7 +973,13 @@ static ssize_t f_midi_opts_id_show(struct f_midi_opts *opts, char *page) | |||
973 | int result; | 973 | int result; |
974 | 974 | ||
975 | mutex_lock(&opts->lock); | 975 | mutex_lock(&opts->lock); |
976 | result = strlcpy(page, opts->id, PAGE_SIZE); | 976 | if (opts->id) { |
977 | result = strlcpy(page, opts->id, PAGE_SIZE); | ||
978 | } else { | ||
979 | page[0] = 0; | ||
980 | result = 0; | ||
981 | } | ||
982 | |||
977 | mutex_unlock(&opts->lock); | 983 | mutex_unlock(&opts->lock); |
978 | 984 | ||
979 | return result; | 985 | return result; |
diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 9719abfb6145..7856b3394494 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c | |||
@@ -588,7 +588,10 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | |||
588 | 588 | ||
589 | if (intf == 1) { | 589 | if (intf == 1) { |
590 | if (alt == 1) { | 590 | if (alt == 1) { |
591 | config_ep_by_speed(cdev->gadget, f, out_ep); | 591 | err = config_ep_by_speed(cdev->gadget, f, out_ep); |
592 | if (err) | ||
593 | return err; | ||
594 | |||
592 | usb_ep_enable(out_ep); | 595 | usb_ep_enable(out_ep); |
593 | out_ep->driver_data = audio; | 596 | out_ep->driver_data = audio; |
594 | audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); | 597 | audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); |
diff --git a/drivers/usb/gadget/legacy/g_ffs.c b/drivers/usb/gadget/legacy/g_ffs.c index 7b9ef7e257d2..e821931c965c 100644 --- a/drivers/usb/gadget/legacy/g_ffs.c +++ b/drivers/usb/gadget/legacy/g_ffs.c | |||
@@ -304,8 +304,10 @@ static int functionfs_ready_callback(struct ffs_data *ffs) | |||
304 | gfs_registered = true; | 304 | gfs_registered = true; |
305 | 305 | ||
306 | ret = usb_composite_probe(&gfs_driver); | 306 | ret = usb_composite_probe(&gfs_driver); |
307 | if (unlikely(ret < 0)) | 307 | if (unlikely(ret < 0)) { |
308 | ++missing_funcs; | ||
308 | gfs_registered = false; | 309 | gfs_registered = false; |
310 | } | ||
309 | 311 | ||
310 | return ret; | 312 | return ret; |
311 | } | 313 | } |
diff --git a/drivers/usb/gadget/udc/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c index b808951491cc..99fd9a5667df 100644 --- a/drivers/usb/gadget/udc/s3c2410_udc.c +++ b/drivers/usb/gadget/udc/s3c2410_udc.c | |||
@@ -1487,7 +1487,7 @@ static int s3c2410_udc_pullup(struct usb_gadget *gadget, int is_on) | |||
1487 | 1487 | ||
1488 | dprintk(DEBUG_NORMAL, "%s()\n", __func__); | 1488 | dprintk(DEBUG_NORMAL, "%s()\n", __func__); |
1489 | 1489 | ||
1490 | s3c2410_udc_set_pullup(udc, is_on ? 0 : 1); | 1490 | s3c2410_udc_set_pullup(udc, is_on); |
1491 | return 0; | 1491 | return 0; |
1492 | } | 1492 | } |
1493 | 1493 | ||
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ec8ac1674854..36bf089b708f 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -3682,18 +3682,21 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
3682 | { | 3682 | { |
3683 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 3683 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
3684 | unsigned long flags; | 3684 | unsigned long flags; |
3685 | int ret; | 3685 | int ret, slot_id; |
3686 | struct xhci_command *command; | 3686 | struct xhci_command *command; |
3687 | 3687 | ||
3688 | command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); | 3688 | command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); |
3689 | if (!command) | 3689 | if (!command) |
3690 | return 0; | 3690 | return 0; |
3691 | 3691 | ||
3692 | /* xhci->slot_id and xhci->addr_dev are not thread-safe */ | ||
3693 | mutex_lock(&xhci->mutex); | ||
3692 | spin_lock_irqsave(&xhci->lock, flags); | 3694 | spin_lock_irqsave(&xhci->lock, flags); |
3693 | command->completion = &xhci->addr_dev; | 3695 | command->completion = &xhci->addr_dev; |
3694 | ret = xhci_queue_slot_control(xhci, command, TRB_ENABLE_SLOT, 0); | 3696 | ret = xhci_queue_slot_control(xhci, command, TRB_ENABLE_SLOT, 0); |
3695 | if (ret) { | 3697 | if (ret) { |
3696 | spin_unlock_irqrestore(&xhci->lock, flags); | 3698 | spin_unlock_irqrestore(&xhci->lock, flags); |
3699 | mutex_unlock(&xhci->mutex); | ||
3697 | xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); | 3700 | xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); |
3698 | kfree(command); | 3701 | kfree(command); |
3699 | return 0; | 3702 | return 0; |
@@ -3702,8 +3705,10 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
3702 | spin_unlock_irqrestore(&xhci->lock, flags); | 3705 | spin_unlock_irqrestore(&xhci->lock, flags); |
3703 | 3706 | ||
3704 | wait_for_completion(command->completion); | 3707 | wait_for_completion(command->completion); |
3708 | slot_id = xhci->slot_id; | ||
3709 | mutex_unlock(&xhci->mutex); | ||
3705 | 3710 | ||
3706 | if (!xhci->slot_id || command->status != COMP_SUCCESS) { | 3711 | if (!slot_id || command->status != COMP_SUCCESS) { |
3707 | xhci_err(xhci, "Error while assigning device slot ID\n"); | 3712 | xhci_err(xhci, "Error while assigning device slot ID\n"); |
3708 | xhci_err(xhci, "Max number of devices this xHCI host supports is %u.\n", | 3713 | xhci_err(xhci, "Max number of devices this xHCI host supports is %u.\n", |
3709 | HCS_MAX_SLOTS( | 3714 | HCS_MAX_SLOTS( |
@@ -3728,11 +3733,11 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
3728 | * xhci_discover_or_reset_device(), which may be called as part of | 3733 | * xhci_discover_or_reset_device(), which may be called as part of |
3729 | * mass storage driver error handling. | 3734 | * mass storage driver error handling. |
3730 | */ | 3735 | */ |
3731 | if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_NOIO)) { | 3736 | if (!xhci_alloc_virt_device(xhci, slot_id, udev, GFP_NOIO)) { |
3732 | xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); | 3737 | xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); |
3733 | goto disable_slot; | 3738 | goto disable_slot; |
3734 | } | 3739 | } |
3735 | udev->slot_id = xhci->slot_id; | 3740 | udev->slot_id = slot_id; |
3736 | 3741 | ||
3737 | #ifndef CONFIG_USB_DEFAULT_PERSIST | 3742 | #ifndef CONFIG_USB_DEFAULT_PERSIST |
3738 | /* | 3743 | /* |
@@ -3778,12 +3783,15 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, | |||
3778 | struct xhci_slot_ctx *slot_ctx; | 3783 | struct xhci_slot_ctx *slot_ctx; |
3779 | struct xhci_input_control_ctx *ctrl_ctx; | 3784 | struct xhci_input_control_ctx *ctrl_ctx; |
3780 | u64 temp_64; | 3785 | u64 temp_64; |
3781 | struct xhci_command *command; | 3786 | struct xhci_command *command = NULL; |
3787 | |||
3788 | mutex_lock(&xhci->mutex); | ||
3782 | 3789 | ||
3783 | if (!udev->slot_id) { | 3790 | if (!udev->slot_id) { |
3784 | xhci_dbg_trace(xhci, trace_xhci_dbg_address, | 3791 | xhci_dbg_trace(xhci, trace_xhci_dbg_address, |
3785 | "Bad Slot ID %d", udev->slot_id); | 3792 | "Bad Slot ID %d", udev->slot_id); |
3786 | return -EINVAL; | 3793 | ret = -EINVAL; |
3794 | goto out; | ||
3787 | } | 3795 | } |
3788 | 3796 | ||
3789 | virt_dev = xhci->devs[udev->slot_id]; | 3797 | virt_dev = xhci->devs[udev->slot_id]; |
@@ -3796,7 +3804,8 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, | |||
3796 | */ | 3804 | */ |
3797 | xhci_warn(xhci, "Virt dev invalid for slot_id 0x%x!\n", | 3805 | xhci_warn(xhci, "Virt dev invalid for slot_id 0x%x!\n", |
3798 | udev->slot_id); | 3806 | udev->slot_id); |
3799 | return -EINVAL; | 3807 | ret = -EINVAL; |
3808 | goto out; | ||
3800 | } | 3809 | } |
3801 | 3810 | ||
3802 | if (setup == SETUP_CONTEXT_ONLY) { | 3811 | if (setup == SETUP_CONTEXT_ONLY) { |
@@ -3804,13 +3813,15 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, | |||
3804 | if (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state)) == | 3813 | if (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state)) == |
3805 | SLOT_STATE_DEFAULT) { | 3814 | SLOT_STATE_DEFAULT) { |
3806 | xhci_dbg(xhci, "Slot already in default state\n"); | 3815 | xhci_dbg(xhci, "Slot already in default state\n"); |
3807 | return 0; | 3816 | goto out; |
3808 | } | 3817 | } |
3809 | } | 3818 | } |
3810 | 3819 | ||
3811 | command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); | 3820 | command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); |
3812 | if (!command) | 3821 | if (!command) { |
3813 | return -ENOMEM; | 3822 | ret = -ENOMEM; |
3823 | goto out; | ||
3824 | } | ||
3814 | 3825 | ||
3815 | command->in_ctx = virt_dev->in_ctx; | 3826 | command->in_ctx = virt_dev->in_ctx; |
3816 | command->completion = &xhci->addr_dev; | 3827 | command->completion = &xhci->addr_dev; |
@@ -3820,8 +3831,8 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, | |||
3820 | if (!ctrl_ctx) { | 3831 | if (!ctrl_ctx) { |
3821 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", | 3832 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", |
3822 | __func__); | 3833 | __func__); |
3823 | kfree(command); | 3834 | ret = -EINVAL; |
3824 | return -EINVAL; | 3835 | goto out; |
3825 | } | 3836 | } |
3826 | /* | 3837 | /* |
3827 | * If this is the first Set Address since device plug-in or | 3838 | * If this is the first Set Address since device plug-in or |
@@ -3848,8 +3859,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, | |||
3848 | spin_unlock_irqrestore(&xhci->lock, flags); | 3859 | spin_unlock_irqrestore(&xhci->lock, flags); |
3849 | xhci_dbg_trace(xhci, trace_xhci_dbg_address, | 3860 | xhci_dbg_trace(xhci, trace_xhci_dbg_address, |
3850 | "FIXME: allocate a command ring segment"); | 3861 | "FIXME: allocate a command ring segment"); |
3851 | kfree(command); | 3862 | goto out; |
3852 | return ret; | ||
3853 | } | 3863 | } |
3854 | xhci_ring_cmd_db(xhci); | 3864 | xhci_ring_cmd_db(xhci); |
3855 | spin_unlock_irqrestore(&xhci->lock, flags); | 3865 | spin_unlock_irqrestore(&xhci->lock, flags); |
@@ -3896,10 +3906,8 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, | |||
3896 | ret = -EINVAL; | 3906 | ret = -EINVAL; |
3897 | break; | 3907 | break; |
3898 | } | 3908 | } |
3899 | if (ret) { | 3909 | if (ret) |
3900 | kfree(command); | 3910 | goto out; |
3901 | return ret; | ||
3902 | } | ||
3903 | temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); | 3911 | temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); |
3904 | xhci_dbg_trace(xhci, trace_xhci_dbg_address, | 3912 | xhci_dbg_trace(xhci, trace_xhci_dbg_address, |
3905 | "Op regs DCBAA ptr = %#016llx", temp_64); | 3913 | "Op regs DCBAA ptr = %#016llx", temp_64); |
@@ -3932,8 +3940,10 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, | |||
3932 | xhci_dbg_trace(xhci, trace_xhci_dbg_address, | 3940 | xhci_dbg_trace(xhci, trace_xhci_dbg_address, |
3933 | "Internal device address = %d", | 3941 | "Internal device address = %d", |
3934 | le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK); | 3942 | le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK); |
3943 | out: | ||
3944 | mutex_unlock(&xhci->mutex); | ||
3935 | kfree(command); | 3945 | kfree(command); |
3936 | return 0; | 3946 | return ret; |
3937 | } | 3947 | } |
3938 | 3948 | ||
3939 | int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | 3949 | int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) |
@@ -4855,6 +4865,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) | |||
4855 | return 0; | 4865 | return 0; |
4856 | } | 4866 | } |
4857 | 4867 | ||
4868 | mutex_init(&xhci->mutex); | ||
4858 | xhci->cap_regs = hcd->regs; | 4869 | xhci->cap_regs = hcd->regs; |
4859 | xhci->op_regs = hcd->regs + | 4870 | xhci->op_regs = hcd->regs + |
4860 | HC_LENGTH(readl(&xhci->cap_regs->hc_capbase)); | 4871 | HC_LENGTH(readl(&xhci->cap_regs->hc_capbase)); |
@@ -5011,4 +5022,12 @@ static int __init xhci_hcd_init(void) | |||
5011 | BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8); | 5022 | BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8); |
5012 | return 0; | 5023 | return 0; |
5013 | } | 5024 | } |
5025 | |||
5026 | /* | ||
5027 | * If an init function is provided, an exit function must also be provided | ||
5028 | * to allow module unload. | ||
5029 | */ | ||
5030 | static void __exit xhci_hcd_fini(void) { } | ||
5031 | |||
5014 | module_init(xhci_hcd_init); | 5032 | module_init(xhci_hcd_init); |
5033 | module_exit(xhci_hcd_fini); | ||
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index ea75e8ccd3c1..6977f8491fa7 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1497,6 +1497,8 @@ struct xhci_hcd { | |||
1497 | struct list_head lpm_failed_devs; | 1497 | struct list_head lpm_failed_devs; |
1498 | 1498 | ||
1499 | /* slot enabling and address device helpers */ | 1499 | /* slot enabling and address device helpers */ |
1500 | /* these are not thread safe so use mutex */ | ||
1501 | struct mutex mutex; | ||
1500 | struct completion addr_dev; | 1502 | struct completion addr_dev; |
1501 | int slot_id; | 1503 | int slot_id; |
1502 | /* For USB 3.0 LPM enable/disable. */ | 1504 | /* For USB 3.0 LPM enable/disable. */ |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 3789b08ef67b..6dca3d794ced 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -2021,13 +2021,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) | |||
2021 | if (musb->ops->quirks) | 2021 | if (musb->ops->quirks) |
2022 | musb->io.quirks = musb->ops->quirks; | 2022 | musb->io.quirks = musb->ops->quirks; |
2023 | 2023 | ||
2024 | /* At least tusb6010 has it's own offsets.. */ | 2024 | /* Most devices use indexed offset or flat offset */ |
2025 | if (musb->ops->ep_offset) | ||
2026 | musb->io.ep_offset = musb->ops->ep_offset; | ||
2027 | if (musb->ops->ep_select) | ||
2028 | musb->io.ep_select = musb->ops->ep_select; | ||
2029 | |||
2030 | /* ..and some devices use indexed offset or flat offset */ | ||
2031 | if (musb->io.quirks & MUSB_INDEXED_EP) { | 2025 | if (musb->io.quirks & MUSB_INDEXED_EP) { |
2032 | musb->io.ep_offset = musb_indexed_ep_offset; | 2026 | musb->io.ep_offset = musb_indexed_ep_offset; |
2033 | musb->io.ep_select = musb_indexed_ep_select; | 2027 | musb->io.ep_select = musb_indexed_ep_select; |
@@ -2036,6 +2030,12 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) | |||
2036 | musb->io.ep_select = musb_flat_ep_select; | 2030 | musb->io.ep_select = musb_flat_ep_select; |
2037 | } | 2031 | } |
2038 | 2032 | ||
2033 | /* At least tusb6010 has its own offsets */ | ||
2034 | if (musb->ops->ep_offset) | ||
2035 | musb->io.ep_offset = musb->ops->ep_offset; | ||
2036 | if (musb->ops->ep_select) | ||
2037 | musb->io.ep_select = musb->ops->ep_select; | ||
2038 | |||
2039 | if (musb->ops->fifo_mode) | 2039 | if (musb->ops->fifo_mode) |
2040 | fifo_mode = musb->ops->fifo_mode; | 2040 | fifo_mode = musb->ops->fifo_mode; |
2041 | else | 2041 | else |
diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c index 7225d526df04..03ab0c699f74 100644 --- a/drivers/usb/phy/phy-ab8500-usb.c +++ b/drivers/usb/phy/phy-ab8500-usb.c | |||
@@ -1179,7 +1179,7 @@ static int ab8500_usb_irq_setup(struct platform_device *pdev, | |||
1179 | } | 1179 | } |
1180 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 1180 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
1181 | ab8500_usb_link_status_irq, | 1181 | ab8500_usb_link_status_irq, |
1182 | IRQF_NO_SUSPEND | IRQF_SHARED, | 1182 | IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT, |
1183 | "usb-link-status", ab); | 1183 | "usb-link-status", ab); |
1184 | if (err < 0) { | 1184 | if (err < 0) { |
1185 | dev_err(ab->dev, "request_irq failed for link status irq\n"); | 1185 | dev_err(ab->dev, "request_irq failed for link status irq\n"); |
@@ -1195,7 +1195,7 @@ static int ab8500_usb_irq_setup(struct platform_device *pdev, | |||
1195 | } | 1195 | } |
1196 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 1196 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
1197 | ab8500_usb_disconnect_irq, | 1197 | ab8500_usb_disconnect_irq, |
1198 | IRQF_NO_SUSPEND | IRQF_SHARED, | 1198 | IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT, |
1199 | "usb-id-fall", ab); | 1199 | "usb-id-fall", ab); |
1200 | if (err < 0) { | 1200 | if (err < 0) { |
1201 | dev_err(ab->dev, "request_irq failed for ID fall irq\n"); | 1201 | dev_err(ab->dev, "request_irq failed for ID fall irq\n"); |
@@ -1211,7 +1211,7 @@ static int ab8500_usb_irq_setup(struct platform_device *pdev, | |||
1211 | } | 1211 | } |
1212 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 1212 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
1213 | ab8500_usb_disconnect_irq, | 1213 | ab8500_usb_disconnect_irq, |
1214 | IRQF_NO_SUSPEND | IRQF_SHARED, | 1214 | IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT, |
1215 | "usb-vbus-fall", ab); | 1215 | "usb-vbus-fall", ab); |
1216 | if (err < 0) { | 1216 | if (err < 0) { |
1217 | dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); | 1217 | dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); |
diff --git a/drivers/usb/phy/phy-tahvo.c b/drivers/usb/phy/phy-tahvo.c index 845f658276b1..2b28443d07b9 100644 --- a/drivers/usb/phy/phy-tahvo.c +++ b/drivers/usb/phy/phy-tahvo.c | |||
@@ -401,7 +401,8 @@ static int tahvo_usb_probe(struct platform_device *pdev) | |||
401 | dev_set_drvdata(&pdev->dev, tu); | 401 | dev_set_drvdata(&pdev->dev, tu); |
402 | 402 | ||
403 | tu->irq = platform_get_irq(pdev, 0); | 403 | tu->irq = platform_get_irq(pdev, 0); |
404 | ret = request_threaded_irq(tu->irq, NULL, tahvo_usb_vbus_interrupt, 0, | 404 | ret = request_threaded_irq(tu->irq, NULL, tahvo_usb_vbus_interrupt, |
405 | IRQF_ONESHOT, | ||
405 | "tahvo-vbus", tu); | 406 | "tahvo-vbus", tu); |
406 | if (ret) { | 407 | if (ret) { |
407 | dev_err(&pdev->dev, "could not register tahvo-vbus irq: %d\n", | 408 | dev_err(&pdev->dev, "could not register tahvo-vbus irq: %d\n", |
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 8597cf9cfceb..c0f5c652d272 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c | |||
@@ -611,6 +611,8 @@ struct usbhs_pkt_handle usbhs_fifo_pio_push_handler = { | |||
611 | static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) | 611 | static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) |
612 | { | 612 | { |
613 | struct usbhs_pipe *pipe = pkt->pipe; | 613 | struct usbhs_pipe *pipe = pkt->pipe; |
614 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | ||
615 | struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); | ||
614 | 616 | ||
615 | if (usbhs_pipe_is_busy(pipe)) | 617 | if (usbhs_pipe_is_busy(pipe)) |
616 | return 0; | 618 | return 0; |
@@ -624,6 +626,9 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) | |||
624 | usbhs_pipe_data_sequence(pipe, pkt->sequence); | 626 | usbhs_pipe_data_sequence(pipe, pkt->sequence); |
625 | pkt->sequence = -1; /* -1 sequence will be ignored */ | 627 | pkt->sequence = -1; /* -1 sequence will be ignored */ |
626 | 628 | ||
629 | if (usbhs_pipe_is_dcp(pipe)) | ||
630 | usbhsf_fifo_clear(pipe, fifo); | ||
631 | |||
627 | usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length); | 632 | usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length); |
628 | usbhs_pipe_enable(pipe); | 633 | usbhs_pipe_enable(pipe); |
629 | usbhs_pipe_running(pipe, 1); | 634 | usbhs_pipe_running(pipe, 1); |
@@ -673,7 +678,14 @@ static int usbhsf_pio_try_pop(struct usbhs_pkt *pkt, int *is_done) | |||
673 | *is_done = 1; | 678 | *is_done = 1; |
674 | usbhsf_rx_irq_ctrl(pipe, 0); | 679 | usbhsf_rx_irq_ctrl(pipe, 0); |
675 | usbhs_pipe_running(pipe, 0); | 680 | usbhs_pipe_running(pipe, 0); |
676 | usbhs_pipe_disable(pipe); /* disable pipe first */ | 681 | /* |
682 | * If function mode, since this controller is possible to enter | ||
683 | * Control Write status stage at this timing, this driver | ||
684 | * should not disable the pipe. If such a case happens, this | ||
685 | * controller is not able to complete the status stage. | ||
686 | */ | ||
687 | if (!usbhs_mod_is_host(priv) && !usbhs_pipe_is_dcp(pipe)) | ||
688 | usbhs_pipe_disable(pipe); /* disable pipe first */ | ||
677 | } | 689 | } |
678 | 690 | ||
679 | /* | 691 | /* |
@@ -1227,15 +1239,21 @@ static void usbhsf_dma_init_dt(struct device *dev, struct usbhs_fifo *fifo, | |||
1227 | { | 1239 | { |
1228 | char name[16]; | 1240 | char name[16]; |
1229 | 1241 | ||
1230 | snprintf(name, sizeof(name), "tx%d", channel); | 1242 | /* |
1231 | fifo->tx_chan = dma_request_slave_channel_reason(dev, name); | 1243 | * To avoid complex handing for DnFIFOs, the driver uses each |
1232 | if (IS_ERR(fifo->tx_chan)) | 1244 | * DnFIFO as TX or RX direction (not bi-direction). |
1233 | fifo->tx_chan = NULL; | 1245 | * So, the driver uses odd channels for TX, even channels for RX. |
1234 | 1246 | */ | |
1235 | snprintf(name, sizeof(name), "rx%d", channel); | 1247 | snprintf(name, sizeof(name), "ch%d", channel); |
1236 | fifo->rx_chan = dma_request_slave_channel_reason(dev, name); | 1248 | if (channel & 1) { |
1237 | if (IS_ERR(fifo->rx_chan)) | 1249 | fifo->tx_chan = dma_request_slave_channel_reason(dev, name); |
1238 | fifo->rx_chan = NULL; | 1250 | if (IS_ERR(fifo->tx_chan)) |
1251 | fifo->tx_chan = NULL; | ||
1252 | } else { | ||
1253 | fifo->rx_chan = dma_request_slave_channel_reason(dev, name); | ||
1254 | if (IS_ERR(fifo->rx_chan)) | ||
1255 | fifo->rx_chan = NULL; | ||
1256 | } | ||
1239 | } | 1257 | } |
1240 | 1258 | ||
1241 | static void usbhsf_dma_init(struct usbhs_priv *priv, struct usbhs_fifo *fifo, | 1259 | static void usbhsf_dma_init(struct usbhs_priv *priv, struct usbhs_fifo *fifo, |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 9031750e7404..ffd739e31bfc 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -128,6 +128,7 @@ static const struct usb_device_id id_table[] = { | |||
128 | { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ | 128 | { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ |
129 | { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */ | 129 | { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */ |
130 | { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */ | 130 | { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */ |
131 | { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */ | ||
131 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ | 132 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
132 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ | 133 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ |
133 | { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ | 134 | { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8eb68a31cab6..4c8b3b82103d 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -699,6 +699,7 @@ static const struct usb_device_id id_table_combined[] = { | |||
699 | { USB_DEVICE(XSENS_VID, XSENS_AWINDA_DONGLE_PID) }, | 699 | { USB_DEVICE(XSENS_VID, XSENS_AWINDA_DONGLE_PID) }, |
700 | { USB_DEVICE(XSENS_VID, XSENS_AWINDA_STATION_PID) }, | 700 | { USB_DEVICE(XSENS_VID, XSENS_AWINDA_STATION_PID) }, |
701 | { USB_DEVICE(XSENS_VID, XSENS_CONVERTER_PID) }, | 701 | { USB_DEVICE(XSENS_VID, XSENS_CONVERTER_PID) }, |
702 | { USB_DEVICE(XSENS_VID, XSENS_MTDEVBOARD_PID) }, | ||
702 | { USB_DEVICE(XSENS_VID, XSENS_MTW_PID) }, | 703 | { USB_DEVICE(XSENS_VID, XSENS_MTW_PID) }, |
703 | { USB_DEVICE(FTDI_VID, FTDI_OMNI1509) }, | 704 | { USB_DEVICE(FTDI_VID, FTDI_OMNI1509) }, |
704 | { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, | 705 | { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 4e4f46f3c89c..792e054126de 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -155,6 +155,7 @@ | |||
155 | #define XSENS_AWINDA_STATION_PID 0x0101 | 155 | #define XSENS_AWINDA_STATION_PID 0x0101 |
156 | #define XSENS_AWINDA_DONGLE_PID 0x0102 | 156 | #define XSENS_AWINDA_DONGLE_PID 0x0102 |
157 | #define XSENS_MTW_PID 0x0200 /* Xsens MTw */ | 157 | #define XSENS_MTW_PID 0x0200 /* Xsens MTw */ |
158 | #define XSENS_MTDEVBOARD_PID 0x0300 /* Motion Tracker Development Board */ | ||
158 | #define XSENS_CONVERTER_PID 0xD00D /* Xsens USB-serial converter */ | 159 | #define XSENS_CONVERTER_PID 0xD00D /* Xsens USB-serial converter */ |
159 | 160 | ||
160 | /* Xsens devices using FTDI VID */ | 161 | /* Xsens devices using FTDI VID */ |
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index e894eb278d83..eba1b7ac7294 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c | |||
@@ -423,6 +423,7 @@ int vp_set_vq_affinity(struct virtqueue *vq, int cpu) | |||
423 | if (cpu == -1) | 423 | if (cpu == -1) |
424 | irq_set_affinity_hint(irq, NULL); | 424 | irq_set_affinity_hint(irq, NULL); |
425 | else { | 425 | else { |
426 | cpumask_clear(mask); | ||
426 | cpumask_set_cpu(cpu, mask); | 427 | cpumask_set_cpu(cpu, mask); |
427 | irq_set_affinity_hint(irq, mask); | 428 | irq_set_affinity_hint(irq, mask); |
428 | } | 429 | } |
diff --git a/fs/fhandle.c b/fs/fhandle.c index 999ff5c3cab0..d59712dfa3e7 100644 --- a/fs/fhandle.c +++ b/fs/fhandle.c | |||
@@ -195,8 +195,9 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh, | |||
195 | goto out_err; | 195 | goto out_err; |
196 | } | 196 | } |
197 | /* copy the full handle */ | 197 | /* copy the full handle */ |
198 | if (copy_from_user(handle, ufh, | 198 | *handle = f_handle; |
199 | sizeof(struct file_handle) + | 199 | if (copy_from_user(&handle->f_handle, |
200 | &ufh->f_handle, | ||
200 | f_handle.handle_bytes)) { | 201 | f_handle.handle_bytes)) { |
201 | retval = -EFAULT; | 202 | retval = -EFAULT; |
202 | goto out_handle; | 203 | goto out_handle; |
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index aff923ae8c4b..d87d8eced064 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h | |||
@@ -116,7 +116,6 @@ __printf(3, 4) | |||
116 | int bdi_register(struct backing_dev_info *bdi, struct device *parent, | 116 | int bdi_register(struct backing_dev_info *bdi, struct device *parent, |
117 | const char *fmt, ...); | 117 | const char *fmt, ...); |
118 | int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev); | 118 | int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev); |
119 | void bdi_unregister(struct backing_dev_info *bdi); | ||
120 | int __must_check bdi_setup_and_register(struct backing_dev_info *, char *); | 119 | int __must_check bdi_setup_and_register(struct backing_dev_info *, char *); |
121 | void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages, | 120 | void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages, |
122 | enum wb_reason reason); | 121 | enum wb_reason reason); |
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 796ef9645827..a240e61a7700 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h | |||
@@ -115,13 +115,14 @@ static inline void dmar_writeq(void __iomem *addr, u64 val) | |||
115 | * Extended Capability Register | 115 | * Extended Capability Register |
116 | */ | 116 | */ |
117 | 117 | ||
118 | #define ecap_pasid(e) ((e >> 40) & 0x1) | ||
118 | #define ecap_pss(e) ((e >> 35) & 0x1f) | 119 | #define ecap_pss(e) ((e >> 35) & 0x1f) |
119 | #define ecap_eafs(e) ((e >> 34) & 0x1) | 120 | #define ecap_eafs(e) ((e >> 34) & 0x1) |
120 | #define ecap_nwfs(e) ((e >> 33) & 0x1) | 121 | #define ecap_nwfs(e) ((e >> 33) & 0x1) |
121 | #define ecap_srs(e) ((e >> 31) & 0x1) | 122 | #define ecap_srs(e) ((e >> 31) & 0x1) |
122 | #define ecap_ers(e) ((e >> 30) & 0x1) | 123 | #define ecap_ers(e) ((e >> 30) & 0x1) |
123 | #define ecap_prs(e) ((e >> 29) & 0x1) | 124 | #define ecap_prs(e) ((e >> 29) & 0x1) |
124 | #define ecap_pasid(e) ((e >> 28) & 0x1) | 125 | /* PASID support used to be on bit 28 */ |
125 | #define ecap_dis(e) ((e >> 27) & 0x1) | 126 | #define ecap_dis(e) ((e >> 27) & 0x1) |
126 | #define ecap_nest(e) ((e >> 26) & 0x1) | 127 | #define ecap_nest(e) ((e >> 26) & 0x1) |
127 | #define ecap_mts(e) ((e >> 25) & 0x1) | 128 | #define ecap_mts(e) ((e >> 25) & 0x1) |
diff --git a/include/linux/of.h b/include/linux/of.h index ddeaae6d2083..b871ff9d81d7 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
@@ -121,6 +121,8 @@ extern struct device_node *of_stdout; | |||
121 | extern raw_spinlock_t devtree_lock; | 121 | extern raw_spinlock_t devtree_lock; |
122 | 122 | ||
123 | #ifdef CONFIG_OF | 123 | #ifdef CONFIG_OF |
124 | void of_core_init(void); | ||
125 | |||
124 | static inline bool is_of_node(struct fwnode_handle *fwnode) | 126 | static inline bool is_of_node(struct fwnode_handle *fwnode) |
125 | { | 127 | { |
126 | return fwnode && fwnode->type == FWNODE_OF; | 128 | return fwnode && fwnode->type == FWNODE_OF; |
@@ -376,6 +378,10 @@ bool of_console_check(struct device_node *dn, char *name, int index); | |||
376 | 378 | ||
377 | #else /* CONFIG_OF */ | 379 | #else /* CONFIG_OF */ |
378 | 380 | ||
381 | static inline void of_core_init(void) | ||
382 | { | ||
383 | } | ||
384 | |||
379 | static inline bool is_of_node(struct fwnode_handle *fwnode) | 385 | static inline bool is_of_node(struct fwnode_handle *fwnode) |
380 | { | 386 | { |
381 | return false; | 387 | return false; |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 61992cf2e977..d8a82a89f35a 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
@@ -92,8 +92,6 @@ struct hw_perf_event_extra { | |||
92 | int idx; /* index in shared_regs->regs[] */ | 92 | int idx; /* index in shared_regs->regs[] */ |
93 | }; | 93 | }; |
94 | 94 | ||
95 | struct event_constraint; | ||
96 | |||
97 | /** | 95 | /** |
98 | * struct hw_perf_event - performance event hardware details: | 96 | * struct hw_perf_event - performance event hardware details: |
99 | */ | 97 | */ |
@@ -112,8 +110,6 @@ struct hw_perf_event { | |||
112 | 110 | ||
113 | struct hw_perf_event_extra extra_reg; | 111 | struct hw_perf_event_extra extra_reg; |
114 | struct hw_perf_event_extra branch_reg; | 112 | struct hw_perf_event_extra branch_reg; |
115 | |||
116 | struct event_constraint *constraint; | ||
117 | }; | 113 | }; |
118 | struct { /* software */ | 114 | struct { /* software */ |
119 | struct hrtimer hrtimer; | 115 | struct hrtimer hrtimer; |
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 497bc14cdb85..0320bbb7d7b5 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h | |||
@@ -98,7 +98,8 @@ struct inet_connection_sock { | |||
98 | const struct tcp_congestion_ops *icsk_ca_ops; | 98 | const struct tcp_congestion_ops *icsk_ca_ops; |
99 | const struct inet_connection_sock_af_ops *icsk_af_ops; | 99 | const struct inet_connection_sock_af_ops *icsk_af_ops; |
100 | unsigned int (*icsk_sync_mss)(struct sock *sk, u32 pmtu); | 100 | unsigned int (*icsk_sync_mss)(struct sock *sk, u32 pmtu); |
101 | __u8 icsk_ca_state:7, | 101 | __u8 icsk_ca_state:6, |
102 | icsk_ca_setsockopt:1, | ||
102 | icsk_ca_dst_locked:1; | 103 | icsk_ca_dst_locked:1; |
103 | __u8 icsk_retransmits; | 104 | __u8 icsk_retransmits; |
104 | __u8 icsk_pending; | 105 | __u8 icsk_pending; |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 8e3668b44c29..fc57f6b82fc5 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -354,7 +354,7 @@ enum ieee80211_rssi_event_data { | |||
354 | }; | 354 | }; |
355 | 355 | ||
356 | /** | 356 | /** |
357 | * enum ieee80211_rssi_event - data attached to an %RSSI_EVENT | 357 | * struct ieee80211_rssi_event - data attached to an %RSSI_EVENT |
358 | * @data: See &enum ieee80211_rssi_event_data | 358 | * @data: See &enum ieee80211_rssi_event_data |
359 | */ | 359 | */ |
360 | struct ieee80211_rssi_event { | 360 | struct ieee80211_rssi_event { |
@@ -388,7 +388,7 @@ enum ieee80211_mlme_event_status { | |||
388 | }; | 388 | }; |
389 | 389 | ||
390 | /** | 390 | /** |
391 | * enum ieee80211_mlme_event - data attached to an %MLME_EVENT | 391 | * struct ieee80211_mlme_event - data attached to an %MLME_EVENT |
392 | * @data: See &enum ieee80211_mlme_event_data | 392 | * @data: See &enum ieee80211_mlme_event_data |
393 | * @status: See &enum ieee80211_mlme_event_status | 393 | * @status: See &enum ieee80211_mlme_event_status |
394 | * @reason: the reason code if applicable | 394 | * @reason: the reason code if applicable |
@@ -401,9 +401,10 @@ struct ieee80211_mlme_event { | |||
401 | 401 | ||
402 | /** | 402 | /** |
403 | * struct ieee80211_event - event to be sent to the driver | 403 | * struct ieee80211_event - event to be sent to the driver |
404 | * @type The event itself. See &enum ieee80211_event_type. | 404 | * @type: The event itself. See &enum ieee80211_event_type. |
405 | * @rssi: relevant if &type is %RSSI_EVENT | 405 | * @rssi: relevant if &type is %RSSI_EVENT |
406 | * @mlme: relevant if &type is %AUTH_EVENT | 406 | * @mlme: relevant if &type is %AUTH_EVENT |
407 | * @u: union holding the above two fields | ||
407 | */ | 408 | */ |
408 | struct ieee80211_event { | 409 | struct ieee80211_event { |
409 | enum ieee80211_event_type type; | 410 | enum ieee80211_event_type type; |
diff --git a/include/sound/rt5645.h b/include/sound/rt5645.h index 652cb9e4afe5..22734bc3ffd4 100644 --- a/include/sound/rt5645.h +++ b/include/sound/rt5645.h | |||
@@ -20,9 +20,6 @@ struct rt5645_platform_data { | |||
20 | unsigned int dmic2_data_pin; | 20 | unsigned int dmic2_data_pin; |
21 | /* 0 = IN2P; 1 = GPIO6; 2 = GPIO10; 3 = GPIO12 */ | 21 | /* 0 = IN2P; 1 = GPIO6; 2 = GPIO10; 3 = GPIO12 */ |
22 | 22 | ||
23 | unsigned int hp_det_gpio; | ||
24 | bool gpio_hp_det_active_high; | ||
25 | |||
26 | unsigned int jd_mode; | 23 | unsigned int jd_mode; |
27 | }; | 24 | }; |
28 | 25 | ||
diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h index 880dd7437172..c178d13d6f4c 100644 --- a/include/trace/events/writeback.h +++ b/include/trace/events/writeback.h | |||
@@ -250,7 +250,6 @@ DEFINE_EVENT(writeback_class, name, \ | |||
250 | DEFINE_WRITEBACK_EVENT(writeback_nowork); | 250 | DEFINE_WRITEBACK_EVENT(writeback_nowork); |
251 | DEFINE_WRITEBACK_EVENT(writeback_wake_background); | 251 | DEFINE_WRITEBACK_EVENT(writeback_wake_background); |
252 | DEFINE_WRITEBACK_EVENT(writeback_bdi_register); | 252 | DEFINE_WRITEBACK_EVENT(writeback_bdi_register); |
253 | DEFINE_WRITEBACK_EVENT(writeback_bdi_unregister); | ||
254 | 253 | ||
255 | DECLARE_EVENT_CLASS(wbc_class, | 254 | DECLARE_EVENT_CLASS(wbc_class, |
256 | TP_PROTO(struct writeback_control *wbc, struct backing_dev_info *bdi), | 255 | TP_PROTO(struct writeback_control *wbc, struct backing_dev_info *bdi), |
diff --git a/include/uapi/linux/virtio_balloon.h b/include/uapi/linux/virtio_balloon.h index 984169a819ee..d7f1cbc3766c 100644 --- a/include/uapi/linux/virtio_balloon.h +++ b/include/uapi/linux/virtio_balloon.h | |||
@@ -26,6 +26,7 @@ | |||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
27 | * SUCH DAMAGE. */ | 27 | * SUCH DAMAGE. */ |
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | #include <linux/virtio_types.h> | ||
29 | #include <linux/virtio_ids.h> | 30 | #include <linux/virtio_ids.h> |
30 | #include <linux/virtio_config.h> | 31 | #include <linux/virtio_config.h> |
31 | 32 | ||
diff --git a/kernel/compat.c b/kernel/compat.c index 24f00610c575..333d364be29d 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
@@ -912,7 +912,8 @@ long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask, | |||
912 | * bitmap. We must however ensure the end of the | 912 | * bitmap. We must however ensure the end of the |
913 | * kernel bitmap is zeroed. | 913 | * kernel bitmap is zeroed. |
914 | */ | 914 | */ |
915 | if (nr_compat_longs-- > 0) { | 915 | if (nr_compat_longs) { |
916 | nr_compat_longs--; | ||
916 | if (__get_user(um, umask)) | 917 | if (__get_user(um, umask)) |
917 | return -EFAULT; | 918 | return -EFAULT; |
918 | } else { | 919 | } else { |
@@ -954,7 +955,8 @@ long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask, | |||
954 | * We dont want to write past the end of the userspace | 955 | * We dont want to write past the end of the userspace |
955 | * bitmap. | 956 | * bitmap. |
956 | */ | 957 | */ |
957 | if (nr_compat_longs-- > 0) { | 958 | if (nr_compat_longs) { |
959 | nr_compat_longs--; | ||
958 | if (__put_user(um, umask)) | 960 | if (__put_user(um, umask)) |
959 | return -EFAULT; | 961 | return -EFAULT; |
960 | } | 962 | } |
diff --git a/kernel/events/core.c b/kernel/events/core.c index 1a3bf48743ce..eddf1ed4155e 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -3442,7 +3442,6 @@ static void free_event_rcu(struct rcu_head *head) | |||
3442 | if (event->ns) | 3442 | if (event->ns) |
3443 | put_pid_ns(event->ns); | 3443 | put_pid_ns(event->ns); |
3444 | perf_event_free_filter(event); | 3444 | perf_event_free_filter(event); |
3445 | perf_event_free_bpf_prog(event); | ||
3446 | kfree(event); | 3445 | kfree(event); |
3447 | } | 3446 | } |
3448 | 3447 | ||
@@ -3573,6 +3572,8 @@ static void __free_event(struct perf_event *event) | |||
3573 | put_callchain_buffers(); | 3572 | put_callchain_buffers(); |
3574 | } | 3573 | } |
3575 | 3574 | ||
3575 | perf_event_free_bpf_prog(event); | ||
3576 | |||
3576 | if (event->destroy) | 3577 | if (event->destroy) |
3577 | event->destroy(event); | 3578 | event->destroy(event); |
3578 | 3579 | ||
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c index 232f00f273cb..725c416085e3 100644 --- a/kernel/events/ring_buffer.c +++ b/kernel/events/ring_buffer.c | |||
@@ -493,6 +493,20 @@ int rb_alloc_aux(struct ring_buffer *rb, struct perf_event *event, | |||
493 | rb->aux_pages[rb->aux_nr_pages] = page_address(page++); | 493 | rb->aux_pages[rb->aux_nr_pages] = page_address(page++); |
494 | } | 494 | } |
495 | 495 | ||
496 | /* | ||
497 | * In overwrite mode, PMUs that don't support SG may not handle more | ||
498 | * than one contiguous allocation, since they rely on PMI to do double | ||
499 | * buffering. In this case, the entire buffer has to be one contiguous | ||
500 | * chunk. | ||
501 | */ | ||
502 | if ((event->pmu->capabilities & PERF_PMU_CAP_AUX_NO_SG) && | ||
503 | overwrite) { | ||
504 | struct page *page = virt_to_page(rb->aux_pages[0]); | ||
505 | |||
506 | if (page_private(page) != max_order) | ||
507 | goto out; | ||
508 | } | ||
509 | |||
496 | rb->aux_priv = event->pmu->setup_aux(event->cpu, rb->aux_pages, nr_pages, | 510 | rb->aux_priv = event->pmu->setup_aux(event->cpu, rb->aux_pages, nr_pages, |
497 | overwrite); | 511 | overwrite); |
498 | if (!rb->aux_priv) | 512 | if (!rb->aux_priv) |
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index a0831e1b99f4..aaeae885d9af 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c | |||
@@ -3900,7 +3900,8 @@ static void zap_class(struct lock_class *class) | |||
3900 | list_del_rcu(&class->hash_entry); | 3900 | list_del_rcu(&class->hash_entry); |
3901 | list_del_rcu(&class->lock_entry); | 3901 | list_del_rcu(&class->lock_entry); |
3902 | 3902 | ||
3903 | class->key = NULL; | 3903 | RCU_INIT_POINTER(class->key, NULL); |
3904 | RCU_INIT_POINTER(class->name, NULL); | ||
3904 | } | 3905 | } |
3905 | 3906 | ||
3906 | static inline int within(const void *addr, void *start, unsigned long size) | 3907 | static inline int within(const void *addr, void *start, unsigned long size) |
diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c index ef43ac4bafb5..d83d798bef95 100644 --- a/kernel/locking/lockdep_proc.c +++ b/kernel/locking/lockdep_proc.c | |||
@@ -426,10 +426,12 @@ static void seq_lock_time(struct seq_file *m, struct lock_time *lt) | |||
426 | 426 | ||
427 | static void seq_stats(struct seq_file *m, struct lock_stat_data *data) | 427 | static void seq_stats(struct seq_file *m, struct lock_stat_data *data) |
428 | { | 428 | { |
429 | char name[39]; | 429 | struct lockdep_subclass_key *ckey; |
430 | struct lock_class *class; | ||
431 | struct lock_class_stats *stats; | 430 | struct lock_class_stats *stats; |
431 | struct lock_class *class; | ||
432 | const char *cname; | ||
432 | int i, namelen; | 433 | int i, namelen; |
434 | char name[39]; | ||
433 | 435 | ||
434 | class = data->class; | 436 | class = data->class; |
435 | stats = &data->stats; | 437 | stats = &data->stats; |
@@ -440,15 +442,25 @@ static void seq_stats(struct seq_file *m, struct lock_stat_data *data) | |||
440 | if (class->subclass) | 442 | if (class->subclass) |
441 | namelen -= 2; | 443 | namelen -= 2; |
442 | 444 | ||
443 | if (!class->name) { | 445 | rcu_read_lock_sched(); |
446 | cname = rcu_dereference_sched(class->name); | ||
447 | ckey = rcu_dereference_sched(class->key); | ||
448 | |||
449 | if (!cname && !ckey) { | ||
450 | rcu_read_unlock_sched(); | ||
451 | return; | ||
452 | |||
453 | } else if (!cname) { | ||
444 | char str[KSYM_NAME_LEN]; | 454 | char str[KSYM_NAME_LEN]; |
445 | const char *key_name; | 455 | const char *key_name; |
446 | 456 | ||
447 | key_name = __get_key_name(class->key, str); | 457 | key_name = __get_key_name(ckey, str); |
448 | snprintf(name, namelen, "%s", key_name); | 458 | snprintf(name, namelen, "%s", key_name); |
449 | } else { | 459 | } else { |
450 | snprintf(name, namelen, "%s", class->name); | 460 | snprintf(name, namelen, "%s", cname); |
451 | } | 461 | } |
462 | rcu_read_unlock_sched(); | ||
463 | |||
452 | namelen = strlen(name); | 464 | namelen = strlen(name); |
453 | if (class->name_version > 1) { | 465 | if (class->name_version > 1) { |
454 | snprintf(name+namelen, 3, "#%d", class->name_version); | 466 | snprintf(name+namelen, 3, "#%d", class->name_version); |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index ffeaa4105e48..c2980e8733bc 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -2181,7 +2181,7 @@ void task_numa_work(struct callback_head *work) | |||
2181 | } | 2181 | } |
2182 | for (; vma; vma = vma->vm_next) { | 2182 | for (; vma; vma = vma->vm_next) { |
2183 | if (!vma_migratable(vma) || !vma_policy_mof(vma) || | 2183 | if (!vma_migratable(vma) || !vma_policy_mof(vma) || |
2184 | is_vm_hugetlb_page(vma)) { | 2184 | is_vm_hugetlb_page(vma) || (vma->vm_flags & VM_MIXEDMAP)) { |
2185 | continue; | 2185 | continue; |
2186 | } | 2186 | } |
2187 | 2187 | ||
diff --git a/kernel/trace/ring_buffer_benchmark.c b/kernel/trace/ring_buffer_benchmark.c index 13d945c0d03f..1b28df2d9104 100644 --- a/kernel/trace/ring_buffer_benchmark.c +++ b/kernel/trace/ring_buffer_benchmark.c | |||
@@ -450,7 +450,7 @@ static int __init ring_buffer_benchmark_init(void) | |||
450 | 450 | ||
451 | if (producer_fifo >= 0) { | 451 | if (producer_fifo >= 0) { |
452 | struct sched_param param = { | 452 | struct sched_param param = { |
453 | .sched_priority = consumer_fifo | 453 | .sched_priority = producer_fifo |
454 | }; | 454 | }; |
455 | sched_setscheduler(producer, SCHED_FIFO, ¶m); | 455 | sched_setscheduler(producer, SCHED_FIFO, ¶m); |
456 | } else | 456 | } else |
diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h index aac511417ad1..a89d041592c8 100644 --- a/lib/mpi/longlong.h +++ b/lib/mpi/longlong.h | |||
@@ -639,7 +639,7 @@ do { \ | |||
639 | ************** MIPS ***************** | 639 | ************** MIPS ***************** |
640 | ***************************************/ | 640 | ***************************************/ |
641 | #if defined(__mips__) && W_TYPE_SIZE == 32 | 641 | #if defined(__mips__) && W_TYPE_SIZE == 32 |
642 | #if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 | 642 | #if (__GNUC__ >= 5) || (__GNUC__ >= 4 && __GNUC_MINOR__ >= 4) |
643 | #define umul_ppmm(w1, w0, u, v) \ | 643 | #define umul_ppmm(w1, w0, u, v) \ |
644 | do { \ | 644 | do { \ |
645 | UDItype __ll = (UDItype)(u) * (v); \ | 645 | UDItype __ll = (UDItype)(u) * (v); \ |
@@ -671,7 +671,7 @@ do { \ | |||
671 | ************** MIPS/64 ************** | 671 | ************** MIPS/64 ************** |
672 | ***************************************/ | 672 | ***************************************/ |
673 | #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64 | 673 | #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64 |
674 | #if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 | 674 | #if (__GNUC__ >= 5) || (__GNUC__ >= 4 && __GNUC_MINOR__ >= 4) |
675 | #define umul_ppmm(w1, w0, u, v) \ | 675 | #define umul_ppmm(w1, w0, u, v) \ |
676 | do { \ | 676 | do { \ |
677 | typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \ | 677 | typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \ |
diff --git a/lib/rhashtable.c b/lib/rhashtable.c index 4396434e4715..8609378e6505 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/random.h> | 26 | #include <linux/random.h> |
27 | #include <linux/rhashtable.h> | 27 | #include <linux/rhashtable.h> |
28 | #include <linux/err.h> | 28 | #include <linux/err.h> |
29 | #include <linux/export.h> | ||
29 | 30 | ||
30 | #define HASH_DEFAULT_SIZE 64UL | 31 | #define HASH_DEFAULT_SIZE 64UL |
31 | #define HASH_MIN_SIZE 4U | 32 | #define HASH_MIN_SIZE 4U |
diff --git a/lib/strnlen_user.c b/lib/strnlen_user.c index a28df5206d95..fe9a32591c24 100644 --- a/lib/strnlen_user.c +++ b/lib/strnlen_user.c | |||
@@ -57,7 +57,8 @@ static inline long do_strnlen_user(const char __user *src, unsigned long count, | |||
57 | return res + find_zero(data) + 1 - align; | 57 | return res + find_zero(data) + 1 - align; |
58 | } | 58 | } |
59 | res += sizeof(unsigned long); | 59 | res += sizeof(unsigned long); |
60 | if (unlikely(max < sizeof(unsigned long))) | 60 | /* We already handled 'unsigned long' bytes. Did we do it all ? */ |
61 | if (unlikely(max <= sizeof(unsigned long))) | ||
61 | break; | 62 | break; |
62 | max -= sizeof(unsigned long); | 63 | max -= sizeof(unsigned long); |
63 | if (unlikely(__get_user(c,(unsigned long __user *)(src+res)))) | 64 | if (unlikely(__get_user(c,(unsigned long __user *)(src+res)))) |
@@ -89,8 +90,15 @@ static inline long do_strnlen_user(const char __user *src, unsigned long count, | |||
89 | * Get the size of a NUL-terminated string in user space. | 90 | * Get the size of a NUL-terminated string in user space. |
90 | * | 91 | * |
91 | * Returns the size of the string INCLUDING the terminating NUL. | 92 | * Returns the size of the string INCLUDING the terminating NUL. |
92 | * If the string is too long, returns 'count+1'. | 93 | * If the string is too long, returns a number larger than @count. User |
94 | * has to check the return value against "> count". | ||
93 | * On exception (or invalid count), returns 0. | 95 | * On exception (or invalid count), returns 0. |
96 | * | ||
97 | * NOTE! You should basically never use this function. There is | ||
98 | * almost never any valid case for using the length of a user space | ||
99 | * string, since the string can be changed at any time by other | ||
100 | * threads. Use "strncpy_from_user()" instead to get a stable copy | ||
101 | * of the string. | ||
94 | */ | 102 | */ |
95 | long strnlen_user(const char __user *str, long count) | 103 | long strnlen_user(const char __user *str, long count) |
96 | { | 104 | { |
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 4abda074ea45..3c365ab6cf5f 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
@@ -537,8 +537,9 @@ EXPORT_SYMBOL_GPL(swiotlb_tbl_map_single); | |||
537 | * Allocates bounce buffer and returns its kernel virtual address. | 537 | * Allocates bounce buffer and returns its kernel virtual address. |
538 | */ | 538 | */ |
539 | 539 | ||
540 | phys_addr_t map_single(struct device *hwdev, phys_addr_t phys, size_t size, | 540 | static phys_addr_t |
541 | enum dma_data_direction dir) | 541 | map_single(struct device *hwdev, phys_addr_t phys, size_t size, |
542 | enum dma_data_direction dir) | ||
542 | { | 543 | { |
543 | dma_addr_t start_dma_addr = phys_to_dma(hwdev, io_tlb_start); | 544 | dma_addr_t start_dma_addr = phys_to_dma(hwdev, io_tlb_start); |
544 | 545 | ||
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 6dc4580df2af..000e7b3b9896 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -359,23 +359,6 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi) | |||
359 | flush_delayed_work(&bdi->wb.dwork); | 359 | flush_delayed_work(&bdi->wb.dwork); |
360 | } | 360 | } |
361 | 361 | ||
362 | /* | ||
363 | * Called when the device behind @bdi has been removed or ejected. | ||
364 | * | ||
365 | * We can't really do much here except for reducing the dirty ratio at | ||
366 | * the moment. In the future we should be able to set a flag so that | ||
367 | * the filesystem can handle errors at mark_inode_dirty time instead | ||
368 | * of only at writeback time. | ||
369 | */ | ||
370 | void bdi_unregister(struct backing_dev_info *bdi) | ||
371 | { | ||
372 | if (WARN_ON_ONCE(!bdi->dev)) | ||
373 | return; | ||
374 | |||
375 | bdi_set_min_ratio(bdi, 0); | ||
376 | } | ||
377 | EXPORT_SYMBOL(bdi_unregister); | ||
378 | |||
379 | static void bdi_wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi) | 362 | static void bdi_wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi) |
380 | { | 363 | { |
381 | memset(wb, 0, sizeof(*wb)); | 364 | memset(wb, 0, sizeof(*wb)); |
@@ -443,6 +426,7 @@ void bdi_destroy(struct backing_dev_info *bdi) | |||
443 | int i; | 426 | int i; |
444 | 427 | ||
445 | bdi_wb_shutdown(bdi); | 428 | bdi_wb_shutdown(bdi); |
429 | bdi_set_min_ratio(bdi, 0); | ||
446 | 430 | ||
447 | WARN_ON(!list_empty(&bdi->work_list)); | 431 | WARN_ON(!list_empty(&bdi->work_list)); |
448 | WARN_ON(delayed_work_pending(&bdi->wb.dwork)); | 432 | WARN_ON(delayed_work_pending(&bdi->wb.dwork)); |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 14c2f2017e37..a04225d372ba 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -2323,6 +2323,8 @@ done_restock: | |||
2323 | css_get_many(&memcg->css, batch); | 2323 | css_get_many(&memcg->css, batch); |
2324 | if (batch > nr_pages) | 2324 | if (batch > nr_pages) |
2325 | refill_stock(memcg, batch - nr_pages); | 2325 | refill_stock(memcg, batch - nr_pages); |
2326 | if (!(gfp_mask & __GFP_WAIT)) | ||
2327 | goto done; | ||
2326 | /* | 2328 | /* |
2327 | * If the hierarchy is above the normal consumption range, | 2329 | * If the hierarchy is above the normal consumption range, |
2328 | * make the charging task trim their excess contribution. | 2330 | * make the charging task trim their excess contribution. |
@@ -5833,9 +5835,7 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry) | |||
5833 | if (!mem_cgroup_is_root(memcg)) | 5835 | if (!mem_cgroup_is_root(memcg)) |
5834 | page_counter_uncharge(&memcg->memory, 1); | 5836 | page_counter_uncharge(&memcg->memory, 1); |
5835 | 5837 | ||
5836 | /* XXX: caller holds IRQ-safe mapping->tree_lock */ | 5838 | /* Caller disabled preemption with mapping->tree_lock */ |
5837 | VM_BUG_ON(!irqs_disabled()); | ||
5838 | |||
5839 | mem_cgroup_charge_statistics(memcg, page, -1); | 5839 | mem_cgroup_charge_statistics(memcg, page, -1); |
5840 | memcg_check_events(memcg, page); | 5840 | memcg_check_events(memcg, page); |
5841 | } | 5841 | } |
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 457bde530cbe..9e88f749aa51 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -1969,8 +1969,10 @@ void try_offline_node(int nid) | |||
1969 | * wait_table may be allocated from boot memory, | 1969 | * wait_table may be allocated from boot memory, |
1970 | * here only free if it's allocated by vmalloc. | 1970 | * here only free if it's allocated by vmalloc. |
1971 | */ | 1971 | */ |
1972 | if (is_vmalloc_addr(zone->wait_table)) | 1972 | if (is_vmalloc_addr(zone->wait_table)) { |
1973 | vfree(zone->wait_table); | 1973 | vfree(zone->wait_table); |
1974 | zone->wait_table = NULL; | ||
1975 | } | ||
1974 | } | 1976 | } |
1975 | } | 1977 | } |
1976 | EXPORT_SYMBOL(try_offline_node); | 1978 | EXPORT_SYMBOL(try_offline_node); |
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index 08bd7a3d464a..a8b5e749e84e 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c | |||
@@ -289,7 +289,8 @@ static int create_handle_cache(struct zs_pool *pool) | |||
289 | 289 | ||
290 | static void destroy_handle_cache(struct zs_pool *pool) | 290 | static void destroy_handle_cache(struct zs_pool *pool) |
291 | { | 291 | { |
292 | kmem_cache_destroy(pool->handle_cachep); | 292 | if (pool->handle_cachep) |
293 | kmem_cache_destroy(pool->handle_cachep); | ||
293 | } | 294 | } |
294 | 295 | ||
295 | static unsigned long alloc_handle(struct zs_pool *pool) | 296 | static unsigned long alloc_handle(struct zs_pool *pool) |
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index e0670d7054f9..659fb96672e4 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c | |||
@@ -796,9 +796,11 @@ static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge_port *p, | |||
796 | int err = 0; | 796 | int err = 0; |
797 | 797 | ||
798 | if (ndm->ndm_flags & NTF_USE) { | 798 | if (ndm->ndm_flags & NTF_USE) { |
799 | local_bh_disable(); | ||
799 | rcu_read_lock(); | 800 | rcu_read_lock(); |
800 | br_fdb_update(p->br, p, addr, vid, true); | 801 | br_fdb_update(p->br, p, addr, vid, true); |
801 | rcu_read_unlock(); | 802 | rcu_read_unlock(); |
803 | local_bh_enable(); | ||
802 | } else { | 804 | } else { |
803 | spin_lock_bh(&p->br->hash_lock); | 805 | spin_lock_bh(&p->br->hash_lock); |
804 | err = fdb_add_entry(p, addr, ndm->ndm_state, | 806 | err = fdb_add_entry(p, addr, ndm->ndm_state, |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index a3abe6ed111e..ff667e18b2d6 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -1167,6 +1167,9 @@ static void br_multicast_add_router(struct net_bridge *br, | |||
1167 | struct net_bridge_port *p; | 1167 | struct net_bridge_port *p; |
1168 | struct hlist_node *slot = NULL; | 1168 | struct hlist_node *slot = NULL; |
1169 | 1169 | ||
1170 | if (!hlist_unhashed(&port->rlist)) | ||
1171 | return; | ||
1172 | |||
1170 | hlist_for_each_entry(p, &br->router_list, rlist) { | 1173 | hlist_for_each_entry(p, &br->router_list, rlist) { |
1171 | if ((unsigned long) port >= (unsigned long) p) | 1174 | if ((unsigned long) port >= (unsigned long) p) |
1172 | break; | 1175 | break; |
@@ -1194,12 +1197,8 @@ static void br_multicast_mark_router(struct net_bridge *br, | |||
1194 | if (port->multicast_router != 1) | 1197 | if (port->multicast_router != 1) |
1195 | return; | 1198 | return; |
1196 | 1199 | ||
1197 | if (!hlist_unhashed(&port->rlist)) | ||
1198 | goto timer; | ||
1199 | |||
1200 | br_multicast_add_router(br, port); | 1200 | br_multicast_add_router(br, port); |
1201 | 1201 | ||
1202 | timer: | ||
1203 | mod_timer(&port->multicast_router_timer, | 1202 | mod_timer(&port->multicast_router_timer, |
1204 | now + br->multicast_querier_interval); | 1203 | now + br->multicast_querier_interval); |
1205 | } | 1204 | } |
@@ -1822,7 +1821,7 @@ static void br_multicast_query_expired(struct net_bridge *br, | |||
1822 | if (query->startup_sent < br->multicast_startup_query_count) | 1821 | if (query->startup_sent < br->multicast_startup_query_count) |
1823 | query->startup_sent++; | 1822 | query->startup_sent++; |
1824 | 1823 | ||
1825 | RCU_INIT_POINTER(querier, NULL); | 1824 | RCU_INIT_POINTER(querier->port, NULL); |
1826 | br_multicast_send_query(br, NULL, query); | 1825 | br_multicast_send_query(br, NULL, query); |
1827 | spin_unlock(&br->multicast_lock); | 1826 | spin_unlock(&br->multicast_lock); |
1828 | } | 1827 | } |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 24c7c96bf5f8..91180a7fc943 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -1117,8 +1117,6 @@ static int do_replace(struct net *net, const void __user *user, | |||
1117 | return -ENOMEM; | 1117 | return -ENOMEM; |
1118 | if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter)) | 1118 | if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter)) |
1119 | return -ENOMEM; | 1119 | return -ENOMEM; |
1120 | if (tmp.num_counters == 0) | ||
1121 | return -EINVAL; | ||
1122 | 1120 | ||
1123 | tmp.name[sizeof(tmp.name) - 1] = 0; | 1121 | tmp.name[sizeof(tmp.name) - 1] = 0; |
1124 | 1122 | ||
@@ -2161,8 +2159,6 @@ static int compat_copy_ebt_replace_from_user(struct ebt_replace *repl, | |||
2161 | return -ENOMEM; | 2159 | return -ENOMEM; |
2162 | if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter)) | 2160 | if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter)) |
2163 | return -ENOMEM; | 2161 | return -ENOMEM; |
2164 | if (tmp.num_counters == 0) | ||
2165 | return -EINVAL; | ||
2166 | 2162 | ||
2167 | memcpy(repl, &tmp, offsetof(struct ebt_replace, hook_entry)); | 2163 | memcpy(repl, &tmp, offsetof(struct ebt_replace, hook_entry)); |
2168 | 2164 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 2c1c67fad64d..aa82f9ab6a36 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1718,15 +1718,8 @@ EXPORT_SYMBOL_GPL(is_skb_forwardable); | |||
1718 | 1718 | ||
1719 | int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb) | 1719 | int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb) |
1720 | { | 1720 | { |
1721 | if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) { | 1721 | if (skb_orphan_frags(skb, GFP_ATOMIC) || |
1722 | if (skb_copy_ubufs(skb, GFP_ATOMIC)) { | 1722 | unlikely(!is_skb_forwardable(dev, skb))) { |
1723 | atomic_long_inc(&dev->rx_dropped); | ||
1724 | kfree_skb(skb); | ||
1725 | return NET_RX_DROP; | ||
1726 | } | ||
1727 | } | ||
1728 | |||
1729 | if (unlikely(!is_skb_forwardable(dev, skb))) { | ||
1730 | atomic_long_inc(&dev->rx_dropped); | 1723 | atomic_long_inc(&dev->rx_dropped); |
1731 | kfree_skb(skb); | 1724 | kfree_skb(skb); |
1732 | return NET_RX_DROP; | 1725 | return NET_RX_DROP; |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 1347e11f5cc9..1d00b8922902 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -359,15 +359,7 @@ static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) | |||
359 | int err; | 359 | int err; |
360 | struct ethtool_cmd cmd; | 360 | struct ethtool_cmd cmd; |
361 | 361 | ||
362 | if (!dev->ethtool_ops->get_settings) | 362 | err = __ethtool_get_settings(dev, &cmd); |
363 | return -EOPNOTSUPP; | ||
364 | |||
365 | if (copy_from_user(&cmd, useraddr, sizeof(cmd))) | ||
366 | return -EFAULT; | ||
367 | |||
368 | cmd.cmd = ETHTOOL_GSET; | ||
369 | |||
370 | err = dev->ethtool_ops->get_settings(dev, &cmd); | ||
371 | if (err < 0) | 363 | if (err < 0) |
372 | return err; | 364 | return err; |
373 | 365 | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 3cfff2a3d651..41ec02242ea7 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -4398,7 +4398,7 @@ struct sk_buff *alloc_skb_with_frags(unsigned long header_len, | |||
4398 | 4398 | ||
4399 | while (order) { | 4399 | while (order) { |
4400 | if (npages >= 1 << order) { | 4400 | if (npages >= 1 << order) { |
4401 | page = alloc_pages(gfp_mask | | 4401 | page = alloc_pages((gfp_mask & ~__GFP_WAIT) | |
4402 | __GFP_COMP | | 4402 | __GFP_COMP | |
4403 | __GFP_NOWARN | | 4403 | __GFP_NOWARN | |
4404 | __GFP_NORETRY, | 4404 | __GFP_NORETRY, |
diff --git a/net/core/sock.c b/net/core/sock.c index 292f42228bfb..dc30dc5bb1b8 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -354,15 +354,12 @@ void sk_clear_memalloc(struct sock *sk) | |||
354 | 354 | ||
355 | /* | 355 | /* |
356 | * SOCK_MEMALLOC is allowed to ignore rmem limits to ensure forward | 356 | * SOCK_MEMALLOC is allowed to ignore rmem limits to ensure forward |
357 | * progress of swapping. However, if SOCK_MEMALLOC is cleared while | 357 | * progress of swapping. SOCK_MEMALLOC may be cleared while |
358 | * it has rmem allocations there is a risk that the user of the | 358 | * it has rmem allocations due to the last swapfile being deactivated |
359 | * socket cannot make forward progress due to exceeding the rmem | 359 | * but there is a risk that the socket is unusable due to exceeding |
360 | * limits. By rights, sk_clear_memalloc() should only be called | 360 | * the rmem limits. Reclaim the reserves and obey rmem limits again. |
361 | * on sockets being torn down but warn and reset the accounting if | ||
362 | * that assumption breaks. | ||
363 | */ | 361 | */ |
364 | if (WARN_ON(sk->sk_forward_alloc)) | 362 | sk_mem_reclaim(sk); |
365 | sk_mem_reclaim(sk); | ||
366 | } | 363 | } |
367 | EXPORT_SYMBOL_GPL(sk_clear_memalloc); | 364 | EXPORT_SYMBOL_GPL(sk_clear_memalloc); |
368 | 365 | ||
@@ -1883,7 +1880,7 @@ bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t gfp) | |||
1883 | 1880 | ||
1884 | pfrag->offset = 0; | 1881 | pfrag->offset = 0; |
1885 | if (SKB_FRAG_PAGE_ORDER) { | 1882 | if (SKB_FRAG_PAGE_ORDER) { |
1886 | pfrag->page = alloc_pages(gfp | __GFP_COMP | | 1883 | pfrag->page = alloc_pages((gfp & ~__GFP_WAIT) | __GFP_COMP | |
1887 | __GFP_NOWARN | __GFP_NORETRY, | 1884 | __GFP_NOWARN | __GFP_NORETRY, |
1888 | SKB_FRAG_PAGE_ORDER); | 1885 | SKB_FRAG_PAGE_ORDER); |
1889 | if (likely(pfrag->page)) { | 1886 | if (likely(pfrag->page)) { |
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index e6f6cc3a1bcf..392e29a0227d 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c | |||
@@ -359,7 +359,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, | |||
359 | */ | 359 | */ |
360 | ds = kzalloc(sizeof(*ds) + drv->priv_size, GFP_KERNEL); | 360 | ds = kzalloc(sizeof(*ds) + drv->priv_size, GFP_KERNEL); |
361 | if (ds == NULL) | 361 | if (ds == NULL) |
362 | return NULL; | 362 | return ERR_PTR(-ENOMEM); |
363 | 363 | ||
364 | ds->dst = dst; | 364 | ds->dst = dst; |
365 | ds->index = index; | 365 | ds->index = index; |
@@ -370,7 +370,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, | |||
370 | 370 | ||
371 | ret = dsa_switch_setup_one(ds, parent); | 371 | ret = dsa_switch_setup_one(ds, parent); |
372 | if (ret) | 372 | if (ret) |
373 | return NULL; | 373 | return ERR_PTR(ret); |
374 | 374 | ||
375 | return ds; | 375 | return ds; |
376 | } | 376 | } |
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 421a80b09b62..30b544f025ac 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -256,7 +256,8 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
256 | aead_givcrypt_set_crypt(req, sg, sg, clen, iv); | 256 | aead_givcrypt_set_crypt(req, sg, sg, clen, iv); |
257 | aead_givcrypt_set_assoc(req, asg, assoclen); | 257 | aead_givcrypt_set_assoc(req, asg, assoclen); |
258 | aead_givcrypt_set_giv(req, esph->enc_data, | 258 | aead_givcrypt_set_giv(req, esph->enc_data, |
259 | XFRM_SKB_CB(skb)->seq.output.low); | 259 | XFRM_SKB_CB(skb)->seq.output.low + |
260 | ((u64)XFRM_SKB_CB(skb)->seq.output.hi << 32)); | ||
260 | 261 | ||
261 | ESP_SKB_CB(skb)->tmp = tmp; | 262 | ESP_SKB_CB(skb)->tmp = tmp; |
262 | err = crypto_aead_givencrypt(req); | 263 | err = crypto_aead_givencrypt(req); |
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 9f7269f3c54a..0c152087ca15 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
@@ -65,7 +65,6 @@ static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi, | |||
65 | goto drop; | 65 | goto drop; |
66 | 66 | ||
67 | XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = tunnel; | 67 | XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = tunnel; |
68 | skb->mark = be32_to_cpu(tunnel->parms.i_key); | ||
69 | 68 | ||
70 | return xfrm_input(skb, nexthdr, spi, encap_type); | 69 | return xfrm_input(skb, nexthdr, spi, encap_type); |
71 | } | 70 | } |
@@ -91,6 +90,8 @@ static int vti_rcv_cb(struct sk_buff *skb, int err) | |||
91 | struct pcpu_sw_netstats *tstats; | 90 | struct pcpu_sw_netstats *tstats; |
92 | struct xfrm_state *x; | 91 | struct xfrm_state *x; |
93 | struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4; | 92 | struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4; |
93 | u32 orig_mark = skb->mark; | ||
94 | int ret; | ||
94 | 95 | ||
95 | if (!tunnel) | 96 | if (!tunnel) |
96 | return 1; | 97 | return 1; |
@@ -107,7 +108,11 @@ static int vti_rcv_cb(struct sk_buff *skb, int err) | |||
107 | x = xfrm_input_state(skb); | 108 | x = xfrm_input_state(skb); |
108 | family = x->inner_mode->afinfo->family; | 109 | family = x->inner_mode->afinfo->family; |
109 | 110 | ||
110 | if (!xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family)) | 111 | skb->mark = be32_to_cpu(tunnel->parms.i_key); |
112 | ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family); | ||
113 | skb->mark = orig_mark; | ||
114 | |||
115 | if (!ret) | ||
111 | return -EPERM; | 116 | return -EPERM; |
112 | 117 | ||
113 | skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(skb->dev))); | 118 | skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(skb->dev))); |
@@ -216,8 +221,6 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
216 | 221 | ||
217 | memset(&fl, 0, sizeof(fl)); | 222 | memset(&fl, 0, sizeof(fl)); |
218 | 223 | ||
219 | skb->mark = be32_to_cpu(tunnel->parms.o_key); | ||
220 | |||
221 | switch (skb->protocol) { | 224 | switch (skb->protocol) { |
222 | case htons(ETH_P_IP): | 225 | case htons(ETH_P_IP): |
223 | xfrm_decode_session(skb, &fl, AF_INET); | 226 | xfrm_decode_session(skb, &fl, AF_INET); |
@@ -233,6 +236,9 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
233 | return NETDEV_TX_OK; | 236 | return NETDEV_TX_OK; |
234 | } | 237 | } |
235 | 238 | ||
239 | /* override mark with tunnel output key */ | ||
240 | fl.flowi_mark = be32_to_cpu(tunnel->parms.o_key); | ||
241 | |||
236 | return vti_xmit(skb, dev, &fl); | 242 | return vti_xmit(skb, dev, &fl); |
237 | } | 243 | } |
238 | 244 | ||
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 7a5ae50c80c8..84be008c945c 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
@@ -187,6 +187,7 @@ static void tcp_reinit_congestion_control(struct sock *sk, | |||
187 | 187 | ||
188 | tcp_cleanup_congestion_control(sk); | 188 | tcp_cleanup_congestion_control(sk); |
189 | icsk->icsk_ca_ops = ca; | 189 | icsk->icsk_ca_ops = ca; |
190 | icsk->icsk_ca_setsockopt = 1; | ||
190 | 191 | ||
191 | if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init) | 192 | if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init) |
192 | icsk->icsk_ca_ops->init(sk); | 193 | icsk->icsk_ca_ops->init(sk); |
@@ -335,8 +336,10 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) | |||
335 | rcu_read_lock(); | 336 | rcu_read_lock(); |
336 | ca = __tcp_ca_find_autoload(name); | 337 | ca = __tcp_ca_find_autoload(name); |
337 | /* No change asking for existing value */ | 338 | /* No change asking for existing value */ |
338 | if (ca == icsk->icsk_ca_ops) | 339 | if (ca == icsk->icsk_ca_ops) { |
340 | icsk->icsk_ca_setsockopt = 1; | ||
339 | goto out; | 341 | goto out; |
342 | } | ||
340 | if (!ca) | 343 | if (!ca) |
341 | err = -ENOENT; | 344 | err = -ENOENT; |
342 | else if (!((ca->flags & TCP_CONG_NON_RESTRICTED) || | 345 | else if (!((ca->flags & TCP_CONG_NON_RESTRICTED) || |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index b5732a54f2ad..17e7339ee5ca 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -420,7 +420,10 @@ void tcp_ca_openreq_child(struct sock *sk, const struct dst_entry *dst) | |||
420 | rcu_read_unlock(); | 420 | rcu_read_unlock(); |
421 | } | 421 | } |
422 | 422 | ||
423 | if (!ca_got_dst && !try_module_get(icsk->icsk_ca_ops->owner)) | 423 | /* If no valid choice made yet, assign current system default ca. */ |
424 | if (!ca_got_dst && | ||
425 | (!icsk->icsk_ca_setsockopt || | ||
426 | !try_module_get(icsk->icsk_ca_ops->owner))) | ||
424 | tcp_assign_congestion_control(sk); | 427 | tcp_assign_congestion_control(sk); |
425 | 428 | ||
426 | tcp_set_ca_state(sk, TCP_CA_Open); | 429 | tcp_set_ca_state(sk, TCP_CA_Open); |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index d10b7e0112eb..83aa604f9273 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -90,6 +90,7 @@ | |||
90 | #include <linux/socket.h> | 90 | #include <linux/socket.h> |
91 | #include <linux/sockios.h> | 91 | #include <linux/sockios.h> |
92 | #include <linux/igmp.h> | 92 | #include <linux/igmp.h> |
93 | #include <linux/inetdevice.h> | ||
93 | #include <linux/in.h> | 94 | #include <linux/in.h> |
94 | #include <linux/errno.h> | 95 | #include <linux/errno.h> |
95 | #include <linux/timer.h> | 96 | #include <linux/timer.h> |
@@ -1345,10 +1346,8 @@ csum_copy_err: | |||
1345 | } | 1346 | } |
1346 | unlock_sock_fast(sk, slow); | 1347 | unlock_sock_fast(sk, slow); |
1347 | 1348 | ||
1348 | if (noblock) | 1349 | /* starting over for a new packet, but check if we need to yield */ |
1349 | return -EAGAIN; | 1350 | cond_resched(); |
1350 | |||
1351 | /* starting over for a new packet */ | ||
1352 | msg->msg_flags &= ~MSG_TRUNC; | 1351 | msg->msg_flags &= ~MSG_TRUNC; |
1353 | goto try_again; | 1352 | goto try_again; |
1354 | } | 1353 | } |
@@ -1962,6 +1961,7 @@ void udp_v4_early_demux(struct sk_buff *skb) | |||
1962 | struct sock *sk; | 1961 | struct sock *sk; |
1963 | struct dst_entry *dst; | 1962 | struct dst_entry *dst; |
1964 | int dif = skb->dev->ifindex; | 1963 | int dif = skb->dev->ifindex; |
1964 | int ours; | ||
1965 | 1965 | ||
1966 | /* validate the packet */ | 1966 | /* validate the packet */ |
1967 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr))) | 1967 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr))) |
@@ -1971,14 +1971,24 @@ void udp_v4_early_demux(struct sk_buff *skb) | |||
1971 | uh = udp_hdr(skb); | 1971 | uh = udp_hdr(skb); |
1972 | 1972 | ||
1973 | if (skb->pkt_type == PACKET_BROADCAST || | 1973 | if (skb->pkt_type == PACKET_BROADCAST || |
1974 | skb->pkt_type == PACKET_MULTICAST) | 1974 | skb->pkt_type == PACKET_MULTICAST) { |
1975 | struct in_device *in_dev = __in_dev_get_rcu(skb->dev); | ||
1976 | |||
1977 | if (!in_dev) | ||
1978 | return; | ||
1979 | |||
1980 | ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr, | ||
1981 | iph->protocol); | ||
1982 | if (!ours) | ||
1983 | return; | ||
1975 | sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr, | 1984 | sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr, |
1976 | uh->source, iph->saddr, dif); | 1985 | uh->source, iph->saddr, dif); |
1977 | else if (skb->pkt_type == PACKET_HOST) | 1986 | } else if (skb->pkt_type == PACKET_HOST) { |
1978 | sk = __udp4_lib_demux_lookup(net, uh->dest, iph->daddr, | 1987 | sk = __udp4_lib_demux_lookup(net, uh->dest, iph->daddr, |
1979 | uh->source, iph->saddr, dif); | 1988 | uh->source, iph->saddr, dif); |
1980 | else | 1989 | } else { |
1981 | return; | 1990 | return; |
1991 | } | ||
1982 | 1992 | ||
1983 | if (!sk) | 1993 | if (!sk) |
1984 | return; | 1994 | return; |
diff --git a/net/ipv6/addrconf_core.c b/net/ipv6/addrconf_core.c index d873ceea86e6..ca09bf49ac68 100644 --- a/net/ipv6/addrconf_core.c +++ b/net/ipv6/addrconf_core.c | |||
@@ -133,6 +133,14 @@ static void snmp6_free_dev(struct inet6_dev *idev) | |||
133 | free_percpu(idev->stats.ipv6); | 133 | free_percpu(idev->stats.ipv6); |
134 | } | 134 | } |
135 | 135 | ||
136 | static void in6_dev_finish_destroy_rcu(struct rcu_head *head) | ||
137 | { | ||
138 | struct inet6_dev *idev = container_of(head, struct inet6_dev, rcu); | ||
139 | |||
140 | snmp6_free_dev(idev); | ||
141 | kfree(idev); | ||
142 | } | ||
143 | |||
136 | /* Nobody refers to this device, we may destroy it. */ | 144 | /* Nobody refers to this device, we may destroy it. */ |
137 | 145 | ||
138 | void in6_dev_finish_destroy(struct inet6_dev *idev) | 146 | void in6_dev_finish_destroy(struct inet6_dev *idev) |
@@ -151,7 +159,6 @@ void in6_dev_finish_destroy(struct inet6_dev *idev) | |||
151 | pr_warn("Freeing alive inet6 device %p\n", idev); | 159 | pr_warn("Freeing alive inet6 device %p\n", idev); |
152 | return; | 160 | return; |
153 | } | 161 | } |
154 | snmp6_free_dev(idev); | 162 | call_rcu(&idev->rcu, in6_dev_finish_destroy_rcu); |
155 | kfree_rcu(idev, rcu); | ||
156 | } | 163 | } |
157 | EXPORT_SYMBOL(in6_dev_finish_destroy); | 164 | EXPORT_SYMBOL(in6_dev_finish_destroy); |
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 31f1b5d5e2ef..7c07ce36aae2 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -248,7 +248,8 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
248 | aead_givcrypt_set_crypt(req, sg, sg, clen, iv); | 248 | aead_givcrypt_set_crypt(req, sg, sg, clen, iv); |
249 | aead_givcrypt_set_assoc(req, asg, assoclen); | 249 | aead_givcrypt_set_assoc(req, asg, assoclen); |
250 | aead_givcrypt_set_giv(req, esph->enc_data, | 250 | aead_givcrypt_set_giv(req, esph->enc_data, |
251 | XFRM_SKB_CB(skb)->seq.output.low); | 251 | XFRM_SKB_CB(skb)->seq.output.low + |
252 | ((u64)XFRM_SKB_CB(skb)->seq.output.hi << 32)); | ||
252 | 253 | ||
253 | ESP_SKB_CB(skb)->tmp = tmp; | 254 | ESP_SKB_CB(skb)->tmp = tmp; |
254 | err = crypto_aead_givencrypt(req); | 255 | err = crypto_aead_givencrypt(req); |
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index ed9d681207fa..0224c032dca5 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
@@ -322,7 +322,6 @@ static int vti6_rcv(struct sk_buff *skb) | |||
322 | } | 322 | } |
323 | 323 | ||
324 | XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t; | 324 | XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t; |
325 | skb->mark = be32_to_cpu(t->parms.i_key); | ||
326 | 325 | ||
327 | rcu_read_unlock(); | 326 | rcu_read_unlock(); |
328 | 327 | ||
@@ -342,6 +341,8 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err) | |||
342 | struct pcpu_sw_netstats *tstats; | 341 | struct pcpu_sw_netstats *tstats; |
343 | struct xfrm_state *x; | 342 | struct xfrm_state *x; |
344 | struct ip6_tnl *t = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6; | 343 | struct ip6_tnl *t = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6; |
344 | u32 orig_mark = skb->mark; | ||
345 | int ret; | ||
345 | 346 | ||
346 | if (!t) | 347 | if (!t) |
347 | return 1; | 348 | return 1; |
@@ -358,7 +359,11 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err) | |||
358 | x = xfrm_input_state(skb); | 359 | x = xfrm_input_state(skb); |
359 | family = x->inner_mode->afinfo->family; | 360 | family = x->inner_mode->afinfo->family; |
360 | 361 | ||
361 | if (!xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family)) | 362 | skb->mark = be32_to_cpu(t->parms.i_key); |
363 | ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family); | ||
364 | skb->mark = orig_mark; | ||
365 | |||
366 | if (!ret) | ||
362 | return -EPERM; | 367 | return -EPERM; |
363 | 368 | ||
364 | skb_scrub_packet(skb, !net_eq(t->net, dev_net(skb->dev))); | 369 | skb_scrub_packet(skb, !net_eq(t->net, dev_net(skb->dev))); |
@@ -430,6 +435,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) | |||
430 | struct net_device *tdev; | 435 | struct net_device *tdev; |
431 | struct xfrm_state *x; | 436 | struct xfrm_state *x; |
432 | int err = -1; | 437 | int err = -1; |
438 | int mtu; | ||
433 | 439 | ||
434 | if (!dst) | 440 | if (!dst) |
435 | goto tx_err_link_failure; | 441 | goto tx_err_link_failure; |
@@ -463,6 +469,19 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) | |||
463 | skb_dst_set(skb, dst); | 469 | skb_dst_set(skb, dst); |
464 | skb->dev = skb_dst(skb)->dev; | 470 | skb->dev = skb_dst(skb)->dev; |
465 | 471 | ||
472 | mtu = dst_mtu(dst); | ||
473 | if (!skb->ignore_df && skb->len > mtu) { | ||
474 | skb_dst(skb)->ops->update_pmtu(dst, NULL, skb, mtu); | ||
475 | |||
476 | if (skb->protocol == htons(ETH_P_IPV6)) | ||
477 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | ||
478 | else | ||
479 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, | ||
480 | htonl(mtu)); | ||
481 | |||
482 | return -EMSGSIZE; | ||
483 | } | ||
484 | |||
466 | err = dst_output(skb); | 485 | err = dst_output(skb); |
467 | if (net_xmit_eval(err) == 0) { | 486 | if (net_xmit_eval(err) == 0) { |
468 | struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); | 487 | struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); |
@@ -495,7 +514,6 @@ vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
495 | int ret; | 514 | int ret; |
496 | 515 | ||
497 | memset(&fl, 0, sizeof(fl)); | 516 | memset(&fl, 0, sizeof(fl)); |
498 | skb->mark = be32_to_cpu(t->parms.o_key); | ||
499 | 517 | ||
500 | switch (skb->protocol) { | 518 | switch (skb->protocol) { |
501 | case htons(ETH_P_IPV6): | 519 | case htons(ETH_P_IPV6): |
@@ -516,6 +534,9 @@ vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
516 | goto tx_err; | 534 | goto tx_err; |
517 | } | 535 | } |
518 | 536 | ||
537 | /* override mark with tunnel output key */ | ||
538 | fl.flowi_mark = be32_to_cpu(t->parms.o_key); | ||
539 | |||
519 | ret = vti6_xmit(skb, dev, &fl); | 540 | ret = vti6_xmit(skb, dev, &fl); |
520 | if (ret < 0) | 541 | if (ret < 0) |
521 | goto tx_err; | 542 | goto tx_err; |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index c2ec41617a35..e51fc3eee6db 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -525,10 +525,8 @@ csum_copy_err: | |||
525 | } | 525 | } |
526 | unlock_sock_fast(sk, slow); | 526 | unlock_sock_fast(sk, slow); |
527 | 527 | ||
528 | if (noblock) | 528 | /* starting over for a new packet, but check if we need to yield */ |
529 | return -EAGAIN; | 529 | cond_resched(); |
530 | |||
531 | /* starting over for a new packet */ | ||
532 | msg->msg_flags &= ~MSG_TRUNC; | 530 | msg->msg_flags &= ~MSG_TRUNC; |
533 | goto try_again; | 531 | goto try_again; |
534 | } | 532 | } |
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 7b3f732269e4..1f93a5978f2a 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c | |||
@@ -541,7 +541,7 @@ static void mpls_ifdown(struct net_device *dev) | |||
541 | 541 | ||
542 | RCU_INIT_POINTER(dev->mpls_ptr, NULL); | 542 | RCU_INIT_POINTER(dev->mpls_ptr, NULL); |
543 | 543 | ||
544 | kfree(mdev); | 544 | kfree_rcu(mdev, rcu); |
545 | } | 545 | } |
546 | 546 | ||
547 | static int mpls_dev_notify(struct notifier_block *this, unsigned long event, | 547 | static int mpls_dev_notify(struct notifier_block *this, unsigned long event, |
@@ -564,6 +564,17 @@ static int mpls_dev_notify(struct notifier_block *this, unsigned long event, | |||
564 | case NETDEV_UNREGISTER: | 564 | case NETDEV_UNREGISTER: |
565 | mpls_ifdown(dev); | 565 | mpls_ifdown(dev); |
566 | break; | 566 | break; |
567 | case NETDEV_CHANGENAME: | ||
568 | mdev = mpls_dev_get(dev); | ||
569 | if (mdev) { | ||
570 | int err; | ||
571 | |||
572 | mpls_dev_sysctl_unregister(mdev); | ||
573 | err = mpls_dev_sysctl_register(dev, mdev); | ||
574 | if (err) | ||
575 | return notifier_from_errno(err); | ||
576 | } | ||
577 | break; | ||
567 | } | 578 | } |
568 | return NOTIFY_OK; | 579 | return NOTIFY_OK; |
569 | } | 580 | } |
diff --git a/net/mpls/internal.h b/net/mpls/internal.h index b064c345042c..8cabeb5a1cb9 100644 --- a/net/mpls/internal.h +++ b/net/mpls/internal.h | |||
@@ -16,6 +16,7 @@ struct mpls_dev { | |||
16 | int input_enabled; | 16 | int input_enabled; |
17 | 17 | ||
18 | struct ctl_table_header *sysctl; | 18 | struct ctl_table_header *sysctl; |
19 | struct rcu_head rcu; | ||
19 | }; | 20 | }; |
20 | 21 | ||
21 | struct sk_buff; | 22 | struct sk_buff; |
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c index 4776282c6417..33e6d6e2908f 100644 --- a/net/openvswitch/vport-netdev.c +++ b/net/openvswitch/vport-netdev.c | |||
@@ -125,6 +125,7 @@ static struct vport *netdev_create(const struct vport_parms *parms) | |||
125 | if (err) | 125 | if (err) |
126 | goto error_master_upper_dev_unlink; | 126 | goto error_master_upper_dev_unlink; |
127 | 127 | ||
128 | dev_disable_lro(netdev_vport->dev); | ||
128 | dev_set_promiscuity(netdev_vport->dev, 1); | 129 | dev_set_promiscuity(netdev_vport->dev, 1); |
129 | netdev_vport->dev->priv_flags |= IFF_OVS_DATAPATH; | 130 | netdev_vport->dev->priv_flags |= IFF_OVS_DATAPATH; |
130 | rtnl_unlock(); | 131 | rtnl_unlock(); |
diff --git a/net/sctp/auth.c b/net/sctp/auth.c index fb7976aee61c..4f15b7d730e1 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c | |||
@@ -381,13 +381,14 @@ nomem: | |||
381 | } | 381 | } |
382 | 382 | ||
383 | 383 | ||
384 | /* Public interface to creat the association shared key. | 384 | /* Public interface to create the association shared key. |
385 | * See code above for the algorithm. | 385 | * See code above for the algorithm. |
386 | */ | 386 | */ |
387 | int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp) | 387 | int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp) |
388 | { | 388 | { |
389 | struct sctp_auth_bytes *secret; | 389 | struct sctp_auth_bytes *secret; |
390 | struct sctp_shared_key *ep_key; | 390 | struct sctp_shared_key *ep_key; |
391 | struct sctp_chunk *chunk; | ||
391 | 392 | ||
392 | /* If we don't support AUTH, or peer is not capable | 393 | /* If we don't support AUTH, or peer is not capable |
393 | * we don't need to do anything. | 394 | * we don't need to do anything. |
@@ -410,6 +411,14 @@ int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp) | |||
410 | sctp_auth_key_put(asoc->asoc_shared_key); | 411 | sctp_auth_key_put(asoc->asoc_shared_key); |
411 | asoc->asoc_shared_key = secret; | 412 | asoc->asoc_shared_key = secret; |
412 | 413 | ||
414 | /* Update send queue in case any chunk already in there now | ||
415 | * needs authenticating | ||
416 | */ | ||
417 | list_for_each_entry(chunk, &asoc->outqueue.out_chunk_list, list) { | ||
418 | if (sctp_auth_send_cid(chunk->chunk_hdr->type, asoc)) | ||
419 | chunk->auth = 1; | ||
420 | } | ||
421 | |||
413 | return 0; | 422 | return 0; |
414 | } | 423 | } |
415 | 424 | ||
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 9074b5cede38..f485600c4507 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -2142,11 +2142,17 @@ static void tipc_sk_timeout(unsigned long data) | |||
2142 | peer_node = tsk_peer_node(tsk); | 2142 | peer_node = tsk_peer_node(tsk); |
2143 | 2143 | ||
2144 | if (tsk->probing_state == TIPC_CONN_PROBING) { | 2144 | if (tsk->probing_state == TIPC_CONN_PROBING) { |
2145 | /* Previous probe not answered -> self abort */ | 2145 | if (!sock_owned_by_user(sk)) { |
2146 | skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, | 2146 | sk->sk_socket->state = SS_DISCONNECTING; |
2147 | TIPC_CONN_MSG, SHORT_H_SIZE, 0, | 2147 | tsk->connected = 0; |
2148 | own_node, peer_node, tsk->portid, | 2148 | tipc_node_remove_conn(sock_net(sk), tsk_peer_node(tsk), |
2149 | peer_port, TIPC_ERR_NO_PORT); | 2149 | tsk_peer_port(tsk)); |
2150 | sk->sk_state_change(sk); | ||
2151 | } else { | ||
2152 | /* Try again later */ | ||
2153 | sk_reset_timer(sk, &sk->sk_timer, (HZ / 20)); | ||
2154 | } | ||
2155 | |||
2150 | } else { | 2156 | } else { |
2151 | skb = tipc_msg_create(CONN_MANAGER, CONN_PROBE, | 2157 | skb = tipc_msg_create(CONN_MANAGER, CONN_PROBE, |
2152 | INT_H_SIZE, 0, peer_node, own_node, | 2158 | INT_H_SIZE, 0, peer_node, own_node, |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index fff1bef6ed6d..fd682832a0e3 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -1333,6 +1333,8 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) | |||
1333 | memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); | 1333 | memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); |
1334 | wdev_unlock(wdev); | 1334 | wdev_unlock(wdev); |
1335 | 1335 | ||
1336 | memset(&sinfo, 0, sizeof(sinfo)); | ||
1337 | |||
1336 | if (rdev_get_station(rdev, dev, bssid, &sinfo)) | 1338 | if (rdev_get_station(rdev, dev, bssid, &sinfo)) |
1337 | return NULL; | 1339 | return NULL; |
1338 | 1340 | ||
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 526c4feb3b50..b58286ecd156 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
@@ -13,6 +13,8 @@ | |||
13 | #include <net/dst.h> | 13 | #include <net/dst.h> |
14 | #include <net/ip.h> | 14 | #include <net/ip.h> |
15 | #include <net/xfrm.h> | 15 | #include <net/xfrm.h> |
16 | #include <net/ip_tunnels.h> | ||
17 | #include <net/ip6_tunnel.h> | ||
16 | 18 | ||
17 | static struct kmem_cache *secpath_cachep __read_mostly; | 19 | static struct kmem_cache *secpath_cachep __read_mostly; |
18 | 20 | ||
@@ -186,6 +188,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
186 | struct xfrm_state *x = NULL; | 188 | struct xfrm_state *x = NULL; |
187 | xfrm_address_t *daddr; | 189 | xfrm_address_t *daddr; |
188 | struct xfrm_mode *inner_mode; | 190 | struct xfrm_mode *inner_mode; |
191 | u32 mark = skb->mark; | ||
189 | unsigned int family; | 192 | unsigned int family; |
190 | int decaps = 0; | 193 | int decaps = 0; |
191 | int async = 0; | 194 | int async = 0; |
@@ -203,6 +206,18 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
203 | XFRM_SPI_SKB_CB(skb)->daddroff); | 206 | XFRM_SPI_SKB_CB(skb)->daddroff); |
204 | family = XFRM_SPI_SKB_CB(skb)->family; | 207 | family = XFRM_SPI_SKB_CB(skb)->family; |
205 | 208 | ||
209 | /* if tunnel is present override skb->mark value with tunnel i_key */ | ||
210 | if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) { | ||
211 | switch (family) { | ||
212 | case AF_INET: | ||
213 | mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key); | ||
214 | break; | ||
215 | case AF_INET6: | ||
216 | mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key); | ||
217 | break; | ||
218 | } | ||
219 | } | ||
220 | |||
206 | /* Allocate new secpath or COW existing one. */ | 221 | /* Allocate new secpath or COW existing one. */ |
207 | if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) { | 222 | if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) { |
208 | struct sec_path *sp; | 223 | struct sec_path *sp; |
@@ -229,7 +244,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
229 | goto drop; | 244 | goto drop; |
230 | } | 245 | } |
231 | 246 | ||
232 | x = xfrm_state_lookup(net, skb->mark, daddr, spi, nexthdr, family); | 247 | x = xfrm_state_lookup(net, mark, daddr, spi, nexthdr, family); |
233 | if (x == NULL) { | 248 | if (x == NULL) { |
234 | XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES); | 249 | XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES); |
235 | xfrm_audit_state_notfound(skb, family, spi, seq); | 250 | xfrm_audit_state_notfound(skb, family, spi, seq); |
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c index dab57daae408..4fd725a0c500 100644 --- a/net/xfrm/xfrm_replay.c +++ b/net/xfrm/xfrm_replay.c | |||
@@ -99,6 +99,7 @@ static int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb) | |||
99 | 99 | ||
100 | if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { | 100 | if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { |
101 | XFRM_SKB_CB(skb)->seq.output.low = ++x->replay.oseq; | 101 | XFRM_SKB_CB(skb)->seq.output.low = ++x->replay.oseq; |
102 | XFRM_SKB_CB(skb)->seq.output.hi = 0; | ||
102 | if (unlikely(x->replay.oseq == 0)) { | 103 | if (unlikely(x->replay.oseq == 0)) { |
103 | x->replay.oseq--; | 104 | x->replay.oseq--; |
104 | xfrm_audit_state_replay_overflow(x, skb); | 105 | xfrm_audit_state_replay_overflow(x, skb); |
@@ -177,6 +178,7 @@ static int xfrm_replay_overflow_bmp(struct xfrm_state *x, struct sk_buff *skb) | |||
177 | 178 | ||
178 | if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { | 179 | if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { |
179 | XFRM_SKB_CB(skb)->seq.output.low = ++replay_esn->oseq; | 180 | XFRM_SKB_CB(skb)->seq.output.low = ++replay_esn->oseq; |
181 | XFRM_SKB_CB(skb)->seq.output.hi = 0; | ||
180 | if (unlikely(replay_esn->oseq == 0)) { | 182 | if (unlikely(replay_esn->oseq == 0)) { |
181 | replay_esn->oseq--; | 183 | replay_esn->oseq--; |
182 | xfrm_audit_state_replay_overflow(x, skb); | 184 | xfrm_audit_state_replay_overflow(x, skb); |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index f5e39e35d73a..96688cd0f6f1 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -927,8 +927,8 @@ struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi, | |||
927 | x->id.spi != spi) | 927 | x->id.spi != spi) |
928 | continue; | 928 | continue; |
929 | 929 | ||
930 | spin_unlock_bh(&net->xfrm.xfrm_state_lock); | ||
931 | xfrm_state_hold(x); | 930 | xfrm_state_hold(x); |
931 | spin_unlock_bh(&net->xfrm.xfrm_state_lock); | ||
932 | return x; | 932 | return x; |
933 | } | 933 | } |
934 | spin_unlock_bh(&net->xfrm.xfrm_state_lock); | 934 | spin_unlock_bh(&net->xfrm.xfrm_state_lock); |
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 89b1df4e72ab..c5ec977b9c37 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
@@ -3169,12 +3169,12 @@ sub process { | |||
3169 | } | 3169 | } |
3170 | 3170 | ||
3171 | # check for global initialisers. | 3171 | # check for global initialisers. |
3172 | if ($line =~ /^\+(\s*$Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/) { | 3172 | if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*(?:0|NULL|false)\s*;/) { |
3173 | if (ERROR("GLOBAL_INITIALISERS", | 3173 | if (ERROR("GLOBAL_INITIALISERS", |
3174 | "do not initialise globals to 0 or NULL\n" . | 3174 | "do not initialise globals to 0 or NULL\n" . |
3175 | $herecurr) && | 3175 | $herecurr) && |
3176 | $fix) { | 3176 | $fix) { |
3177 | $fixed[$fixlinenr] =~ s/($Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/$1;/; | 3177 | $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*(0|NULL|false)\s*;/$1;/; |
3178 | } | 3178 | } |
3179 | } | 3179 | } |
3180 | # check for static initialisers. | 3180 | # check for static initialisers. |
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index e2828e101433..2ae9619443d1 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig | |||
@@ -45,6 +45,7 @@ source "sound/soc/nuc900/Kconfig" | |||
45 | source "sound/soc/omap/Kconfig" | 45 | source "sound/soc/omap/Kconfig" |
46 | source "sound/soc/kirkwood/Kconfig" | 46 | source "sound/soc/kirkwood/Kconfig" |
47 | source "sound/soc/intel/Kconfig" | 47 | source "sound/soc/intel/Kconfig" |
48 | source "sound/soc/mediatek/Kconfig" | ||
48 | source "sound/soc/mxs/Kconfig" | 49 | source "sound/soc/mxs/Kconfig" |
49 | source "sound/soc/pxa/Kconfig" | 50 | source "sound/soc/pxa/Kconfig" |
50 | source "sound/soc/qcom/Kconfig" | 51 | source "sound/soc/qcom/Kconfig" |
diff --git a/sound/soc/Makefile b/sound/soc/Makefile index a0e1ee6b507d..e189903fabf4 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile | |||
@@ -24,6 +24,7 @@ obj-$(CONFIG_SND_SOC) += dwc/ | |||
24 | obj-$(CONFIG_SND_SOC) += fsl/ | 24 | obj-$(CONFIG_SND_SOC) += fsl/ |
25 | obj-$(CONFIG_SND_SOC) += jz4740/ | 25 | obj-$(CONFIG_SND_SOC) += jz4740/ |
26 | obj-$(CONFIG_SND_SOC) += intel/ | 26 | obj-$(CONFIG_SND_SOC) += intel/ |
27 | obj-$(CONFIG_SND_SOC) += mediatek/ | ||
27 | obj-$(CONFIG_SND_SOC) += mxs/ | 28 | obj-$(CONFIG_SND_SOC) += mxs/ |
28 | obj-$(CONFIG_SND_SOC) += nuc900/ | 29 | obj-$(CONFIG_SND_SOC) += nuc900/ |
29 | obj-$(CONFIG_SND_SOC) += omap/ | 30 | obj-$(CONFIG_SND_SOC) += omap/ |
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig index c3152072d682..1489cd461aec 100644 --- a/sound/soc/atmel/Kconfig +++ b/sound/soc/atmel/Kconfig | |||
@@ -9,21 +9,32 @@ config SND_ATMEL_SOC | |||
9 | if SND_ATMEL_SOC | 9 | if SND_ATMEL_SOC |
10 | 10 | ||
11 | config SND_ATMEL_SOC_PDC | 11 | config SND_ATMEL_SOC_PDC |
12 | bool | 12 | tristate |
13 | default m if SND_ATMEL_SOC_SSC_PDC=m && SND_ATMEL_SOC_SSC=m | ||
14 | default y if SND_ATMEL_SOC_SSC_PDC=y || (SND_ATMEL_SOC_SSC_PDC=m && SND_ATMEL_SOC_SSC=y) | ||
15 | |||
16 | config SND_ATMEL_SOC_SSC_PDC | ||
17 | tristate | ||
13 | 18 | ||
14 | config SND_ATMEL_SOC_DMA | 19 | config SND_ATMEL_SOC_DMA |
15 | bool | 20 | tristate |
16 | select SND_SOC_GENERIC_DMAENGINE_PCM | 21 | select SND_SOC_GENERIC_DMAENGINE_PCM |
22 | default m if SND_ATMEL_SOC_SSC_DMA=m && SND_ATMEL_SOC_SSC=m | ||
23 | default y if SND_ATMEL_SOC_SSC_DMA=y || (SND_ATMEL_SOC_SSC_DMA=m && SND_ATMEL_SOC_SSC=y) | ||
24 | |||
25 | config SND_ATMEL_SOC_SSC_DMA | ||
26 | tristate | ||
17 | 27 | ||
18 | config SND_ATMEL_SOC_SSC | 28 | config SND_ATMEL_SOC_SSC |
19 | tristate | 29 | tristate |
30 | default y if SND_ATMEL_SOC_SSC_DMA=y || SND_ATMEL_SOC_SSC_PDC=y | ||
31 | default m if SND_ATMEL_SOC_SSC_DMA=m || SND_ATMEL_SOC_SSC_PDC=m | ||
20 | 32 | ||
21 | config SND_AT91_SOC_SAM9G20_WM8731 | 33 | config SND_AT91_SOC_SAM9G20_WM8731 |
22 | tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" | 34 | tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" |
23 | depends on ARCH_AT91 || COMPILE_TEST | 35 | depends on ARCH_AT91 || COMPILE_TEST |
24 | depends on ATMEL_SSC && SND_SOC_I2C_AND_SPI | 36 | depends on ATMEL_SSC && SND_SOC_I2C_AND_SPI |
25 | select SND_ATMEL_SOC_PDC | 37 | select SND_ATMEL_SOC_SSC_PDC |
26 | select SND_ATMEL_SOC_SSC | ||
27 | select SND_SOC_WM8731 | 38 | select SND_SOC_WM8731 |
28 | help | 39 | help |
29 | Say Y if you want to add support for SoC audio on WM8731-based | 40 | Say Y if you want to add support for SoC audio on WM8731-based |
@@ -33,8 +44,7 @@ config SND_ATMEL_SOC_WM8904 | |||
33 | tristate "Atmel ASoC driver for boards using WM8904 codec" | 44 | tristate "Atmel ASoC driver for boards using WM8904 codec" |
34 | depends on ARCH_AT91 || COMPILE_TEST | 45 | depends on ARCH_AT91 || COMPILE_TEST |
35 | depends on ATMEL_SSC && I2C | 46 | depends on ATMEL_SSC && I2C |
36 | select SND_ATMEL_SOC_SSC | 47 | select SND_ATMEL_SOC_SSC_DMA |
37 | select SND_ATMEL_SOC_DMA | ||
38 | select SND_SOC_WM8904 | 48 | select SND_SOC_WM8904 |
39 | help | 49 | help |
40 | Say Y if you want to add support for Atmel ASoC driver for boards using | 50 | Say Y if you want to add support for Atmel ASoC driver for boards using |
@@ -44,8 +54,7 @@ config SND_AT91_SOC_SAM9X5_WM8731 | |||
44 | tristate "SoC Audio support for WM8731-based at91sam9x5 board" | 54 | tristate "SoC Audio support for WM8731-based at91sam9x5 board" |
45 | depends on ARCH_AT91 || COMPILE_TEST | 55 | depends on ARCH_AT91 || COMPILE_TEST |
46 | depends on ATMEL_SSC && SND_SOC_I2C_AND_SPI | 56 | depends on ATMEL_SSC && SND_SOC_I2C_AND_SPI |
47 | select SND_ATMEL_SOC_SSC | 57 | select SND_ATMEL_SOC_SSC_DMA |
48 | select SND_ATMEL_SOC_DMA | ||
49 | select SND_SOC_WM8731 | 58 | select SND_SOC_WM8731 |
50 | help | 59 | help |
51 | Say Y if you want to add support for audio SoC on an | 60 | Say Y if you want to add support for audio SoC on an |
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile index 4fa7ac91f972..b327e5cc8de3 100644 --- a/sound/soc/atmel/Makefile +++ b/sound/soc/atmel/Makefile | |||
@@ -1,8 +1,10 @@ | |||
1 | # AT91 Platform Support | 1 | # AT91 Platform Support |
2 | snd-soc-atmel-pcm-$(CONFIG_SND_ATMEL_SOC_PDC) := atmel-pcm-pdc.o | 2 | snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o |
3 | snd-soc-atmel-pcm-$(CONFIG_SND_ATMEL_SOC_DMA) += atmel-pcm-dma.o | 3 | snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o |
4 | snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o $(snd-soc-atmel-pcm-y) | 4 | snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o |
5 | 5 | ||
6 | obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o | ||
7 | obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o | ||
6 | obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o | 8 | obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o |
7 | 9 | ||
8 | # AT91 Machine Support | 10 | # AT91 Machine Support |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 9b36011a814e..efaafce8ba38 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -509,6 +509,11 @@ config SND_SOC_RL6231 | |||
509 | default m if SND_SOC_RT5670=m | 509 | default m if SND_SOC_RT5670=m |
510 | default m if SND_SOC_RT5677=m | 510 | default m if SND_SOC_RT5677=m |
511 | 511 | ||
512 | config SND_SOC_RL6347A | ||
513 | tristate | ||
514 | default y if SND_SOC_RT286=y | ||
515 | default m if SND_SOC_RT286=m | ||
516 | |||
512 | config SND_SOC_RT286 | 517 | config SND_SOC_RT286 |
513 | tristate | 518 | tristate |
514 | depends on I2C | 519 | depends on I2C |
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 3dcf5ac85e89..cf160d972cb3 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -77,6 +77,7 @@ snd-soc-pcm512x-objs := pcm512x.o | |||
77 | snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o | 77 | snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o |
78 | snd-soc-pcm512x-spi-objs := pcm512x-spi.o | 78 | snd-soc-pcm512x-spi-objs := pcm512x-spi.o |
79 | snd-soc-rl6231-objs := rl6231.o | 79 | snd-soc-rl6231-objs := rl6231.o |
80 | snd-soc-rl6347a-objs := rl6347a.o | ||
80 | snd-soc-rt286-objs := rt286.o | 81 | snd-soc-rt286-objs := rt286.o |
81 | snd-soc-rt5631-objs := rt5631.o | 82 | snd-soc-rt5631-objs := rt5631.o |
82 | snd-soc-rt5640-objs := rt5640.o | 83 | snd-soc-rt5640-objs := rt5640.o |
@@ -263,6 +264,7 @@ obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o | |||
263 | obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o | 264 | obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o |
264 | obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o | 265 | obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o |
265 | obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o | 266 | obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o |
267 | obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o | ||
266 | obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o | 268 | obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o |
267 | obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o | 269 | obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o |
268 | obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o | 270 | obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o |
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 679f0a0f7039..78268f0514e9 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "max98090.h" | 27 | #include "max98090.h" |
28 | 28 | ||
29 | /* Allows for sparsely populated register maps */ | 29 | /* Allows for sparsely populated register maps */ |
30 | static struct reg_default max98090_reg[] = { | 30 | static const struct reg_default max98090_reg[] = { |
31 | { 0x00, 0x00 }, /* 00 Software Reset */ | 31 | { 0x00, 0x00 }, /* 00 Software Reset */ |
32 | { 0x03, 0x04 }, /* 03 Interrupt Masks */ | 32 | { 0x03, 0x04 }, /* 03 Interrupt Masks */ |
33 | { 0x04, 0x00 }, /* 04 System Clock Quick */ | 33 | { 0x04, 0x00 }, /* 04 System Clock Quick */ |
@@ -2704,7 +2704,7 @@ static const struct of_device_id max98090_of_match[] = { | |||
2704 | MODULE_DEVICE_TABLE(of, max98090_of_match); | 2704 | MODULE_DEVICE_TABLE(of, max98090_of_match); |
2705 | 2705 | ||
2706 | #ifdef CONFIG_ACPI | 2706 | #ifdef CONFIG_ACPI |
2707 | static struct acpi_device_id max98090_acpi_match[] = { | 2707 | static const struct acpi_device_id max98090_acpi_match[] = { |
2708 | { "193C9890", MAX98090 }, | 2708 | { "193C9890", MAX98090 }, |
2709 | { } | 2709 | { } |
2710 | }; | 2710 | }; |
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c index 62dda2488f14..b74118e019fb 100644 --- a/sound/soc/codecs/ml26124.c +++ b/sound/soc/codecs/ml26124.c | |||
@@ -341,6 +341,7 @@ static int ml26124_hw_params(struct snd_pcm_substream *substream, | |||
341 | struct snd_soc_codec *codec = dai->codec; | 341 | struct snd_soc_codec *codec = dai->codec; |
342 | struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec); | 342 | struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec); |
343 | int i = get_coeff(priv->mclk, params_rate(hw_params)); | 343 | int i = get_coeff(priv->mclk, params_rate(hw_params)); |
344 | int srate; | ||
344 | 345 | ||
345 | if (i < 0) | 346 | if (i < 0) |
346 | return i; | 347 | return i; |
@@ -370,53 +371,16 @@ static int ml26124_hw_params(struct snd_pcm_substream *substream, | |||
370 | BIT(0) | BIT(1), 0); | 371 | BIT(0) | BIT(1), 0); |
371 | } | 372 | } |
372 | 373 | ||
373 | switch (params_rate(hw_params)) { | 374 | srate = get_srate(params_rate(hw_params)); |
374 | case 16000: | 375 | if (srate < 0) |
375 | snd_soc_update_bits(codec, ML26124_SMPLING_RATE, 0xf, | 376 | return srate; |
376 | get_srate(params_rate(hw_params))); | 377 | |
377 | snd_soc_update_bits(codec, ML26124_PLLNL, 0xff, | 378 | snd_soc_update_bits(codec, ML26124_SMPLING_RATE, 0xf, srate); |
378 | coeff_div[i].pllnl); | 379 | snd_soc_update_bits(codec, ML26124_PLLNL, 0xff, coeff_div[i].pllnl); |
379 | snd_soc_update_bits(codec, ML26124_PLLNH, 0x1, | 380 | snd_soc_update_bits(codec, ML26124_PLLNH, 0x1, coeff_div[i].pllnh); |
380 | coeff_div[i].pllnh); | 381 | snd_soc_update_bits(codec, ML26124_PLLML, 0xff, coeff_div[i].pllml); |
381 | snd_soc_update_bits(codec, ML26124_PLLML, 0xff, | 382 | snd_soc_update_bits(codec, ML26124_PLLMH, 0x3f, coeff_div[i].pllmh); |
382 | coeff_div[i].pllml); | 383 | snd_soc_update_bits(codec, ML26124_PLLDIV, 0x1f, coeff_div[i].plldiv); |
383 | snd_soc_update_bits(codec, ML26124_PLLMH, 0x3f, | ||
384 | coeff_div[i].pllmh); | ||
385 | snd_soc_update_bits(codec, ML26124_PLLDIV, 0x1f, | ||
386 | coeff_div[i].plldiv); | ||
387 | break; | ||
388 | case 32000: | ||
389 | snd_soc_update_bits(codec, ML26124_SMPLING_RATE, 0xf, | ||
390 | get_srate(params_rate(hw_params))); | ||
391 | snd_soc_update_bits(codec, ML26124_PLLNL, 0xff, | ||
392 | coeff_div[i].pllnl); | ||
393 | snd_soc_update_bits(codec, ML26124_PLLNH, 0x1, | ||
394 | coeff_div[i].pllnh); | ||
395 | snd_soc_update_bits(codec, ML26124_PLLML, 0xff, | ||
396 | coeff_div[i].pllml); | ||
397 | snd_soc_update_bits(codec, ML26124_PLLMH, 0x3f, | ||
398 | coeff_div[i].pllmh); | ||
399 | snd_soc_update_bits(codec, ML26124_PLLDIV, 0x1f, | ||
400 | coeff_div[i].plldiv); | ||
401 | break; | ||
402 | case 48000: | ||
403 | snd_soc_update_bits(codec, ML26124_SMPLING_RATE, 0xf, | ||
404 | get_srate(params_rate(hw_params))); | ||
405 | snd_soc_update_bits(codec, ML26124_PLLNL, 0xff, | ||
406 | coeff_div[i].pllnl); | ||
407 | snd_soc_update_bits(codec, ML26124_PLLNH, 0x1, | ||
408 | coeff_div[i].pllnh); | ||
409 | snd_soc_update_bits(codec, ML26124_PLLML, 0xff, | ||
410 | coeff_div[i].pllml); | ||
411 | snd_soc_update_bits(codec, ML26124_PLLMH, 0x3f, | ||
412 | coeff_div[i].pllmh); | ||
413 | snd_soc_update_bits(codec, ML26124_PLLDIV, 0x1f, | ||
414 | coeff_div[i].plldiv); | ||
415 | break; | ||
416 | default: | ||
417 | pr_err("%s:this rate is no support for ml26124\n", __func__); | ||
418 | return -EINVAL; | ||
419 | } | ||
420 | 384 | ||
421 | return 0; | 385 | return 0; |
422 | } | 386 | } |
diff --git a/sound/soc/codecs/rl6347a.c b/sound/soc/codecs/rl6347a.c new file mode 100644 index 000000000000..91d5166bd3a1 --- /dev/null +++ b/sound/soc/codecs/rl6347a.c | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * rl6347a.c - RL6347A class device shared support | ||
3 | * | ||
4 | * Copyright 2015 Realtek Semiconductor Corp. | ||
5 | * | ||
6 | * Author: Oder Chiou <oder_chiou@realtek.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/moduleparam.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/pm.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/spi/spi.h> | ||
21 | #include <linux/dmi.h> | ||
22 | #include <linux/acpi.h> | ||
23 | #include <sound/core.h> | ||
24 | #include <sound/pcm.h> | ||
25 | #include <sound/pcm_params.h> | ||
26 | #include <sound/soc.h> | ||
27 | #include <sound/soc-dapm.h> | ||
28 | #include <sound/initval.h> | ||
29 | #include <sound/tlv.h> | ||
30 | #include <sound/jack.h> | ||
31 | #include <linux/workqueue.h> | ||
32 | #include <sound/hda_verbs.h> | ||
33 | |||
34 | #include "rl6347a.h" | ||
35 | |||
36 | int rl6347a_hw_write(void *context, unsigned int reg, unsigned int value) | ||
37 | { | ||
38 | struct i2c_client *client = context; | ||
39 | struct rl6347a_priv *rl6347a = i2c_get_clientdata(client); | ||
40 | u8 data[4]; | ||
41 | int ret, i; | ||
42 | |||
43 | /* handle index registers */ | ||
44 | if (reg <= 0xff) { | ||
45 | rl6347a_hw_write(client, RL6347A_COEF_INDEX, reg); | ||
46 | for (i = 0; i < rl6347a->index_cache_size; i++) { | ||
47 | if (reg == rl6347a->index_cache[i].reg) { | ||
48 | rl6347a->index_cache[i].def = value; | ||
49 | break; | ||
50 | } | ||
51 | |||
52 | } | ||
53 | reg = RL6347A_PROC_COEF; | ||
54 | } | ||
55 | |||
56 | data[0] = (reg >> 24) & 0xff; | ||
57 | data[1] = (reg >> 16) & 0xff; | ||
58 | /* | ||
59 | * 4 bit VID: reg should be 0 | ||
60 | * 12 bit VID: value should be 0 | ||
61 | * So we use an OR operator to handle it rather than use if condition. | ||
62 | */ | ||
63 | data[2] = ((reg >> 8) & 0xff) | ((value >> 8) & 0xff); | ||
64 | data[3] = value & 0xff; | ||
65 | |||
66 | ret = i2c_master_send(client, data, 4); | ||
67 | |||
68 | if (ret == 4) | ||
69 | return 0; | ||
70 | else | ||
71 | pr_err("ret=%d\n", ret); | ||
72 | if (ret < 0) | ||
73 | return ret; | ||
74 | else | ||
75 | return -EIO; | ||
76 | } | ||
77 | EXPORT_SYMBOL_GPL(rl6347a_hw_write); | ||
78 | |||
79 | int rl6347a_hw_read(void *context, unsigned int reg, unsigned int *value) | ||
80 | { | ||
81 | struct i2c_client *client = context; | ||
82 | struct i2c_msg xfer[2]; | ||
83 | int ret; | ||
84 | __be32 be_reg; | ||
85 | unsigned int index, vid, buf = 0x0; | ||
86 | |||
87 | /* handle index registers */ | ||
88 | if (reg <= 0xff) { | ||
89 | rl6347a_hw_write(client, RL6347A_COEF_INDEX, reg); | ||
90 | reg = RL6347A_PROC_COEF; | ||
91 | } | ||
92 | |||
93 | reg = reg | 0x80000; | ||
94 | vid = (reg >> 8) & 0xfff; | ||
95 | |||
96 | if (AC_VERB_GET_AMP_GAIN_MUTE == (vid & 0xf00)) { | ||
97 | index = (reg >> 8) & 0xf; | ||
98 | reg = (reg & ~0xf0f) | index; | ||
99 | } | ||
100 | be_reg = cpu_to_be32(reg); | ||
101 | |||
102 | /* Write register */ | ||
103 | xfer[0].addr = client->addr; | ||
104 | xfer[0].flags = 0; | ||
105 | xfer[0].len = 4; | ||
106 | xfer[0].buf = (u8 *)&be_reg; | ||
107 | |||
108 | /* Read data */ | ||
109 | xfer[1].addr = client->addr; | ||
110 | xfer[1].flags = I2C_M_RD; | ||
111 | xfer[1].len = 4; | ||
112 | xfer[1].buf = (u8 *)&buf; | ||
113 | |||
114 | ret = i2c_transfer(client->adapter, xfer, 2); | ||
115 | if (ret < 0) | ||
116 | return ret; | ||
117 | else if (ret != 2) | ||
118 | return -EIO; | ||
119 | |||
120 | *value = be32_to_cpu(buf); | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | EXPORT_SYMBOL_GPL(rl6347a_hw_read); | ||
125 | |||
126 | MODULE_DESCRIPTION("RL6347A class device shared support"); | ||
127 | MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>"); | ||
128 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/rl6347a.h b/sound/soc/codecs/rl6347a.h new file mode 100644 index 000000000000..1cb56e50b7f3 --- /dev/null +++ b/sound/soc/codecs/rl6347a.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * rl6347a.h - RL6347A class device shared support | ||
3 | * | ||
4 | * Copyright 2015 Realtek Semiconductor Corp. | ||
5 | * | ||
6 | * Author: Oder Chiou <oder_chiou@realtek.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | #ifndef __RL6347A_H__ | ||
13 | #define __RL6347A_H__ | ||
14 | |||
15 | #define VERB_CMD(V, N, D) ((N << 20) | (V << 8) | D) | ||
16 | |||
17 | #define RL6347A_VENDOR_REGISTERS 0x20 | ||
18 | |||
19 | #define RL6347A_COEF_INDEX\ | ||
20 | VERB_CMD(AC_VERB_SET_COEF_INDEX, RL6347A_VENDOR_REGISTERS, 0) | ||
21 | #define RL6347A_PROC_COEF\ | ||
22 | VERB_CMD(AC_VERB_SET_PROC_COEF, RL6347A_VENDOR_REGISTERS, 0) | ||
23 | |||
24 | struct rl6347a_priv { | ||
25 | struct reg_default *index_cache; | ||
26 | int index_cache_size; | ||
27 | }; | ||
28 | |||
29 | int rl6347a_hw_write(void *context, unsigned int reg, unsigned int value); | ||
30 | int rl6347a_hw_read(void *context, unsigned int reg, unsigned int *value); | ||
31 | |||
32 | #endif /* __RL6347A_H__ */ | ||
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index c6cca0639e0d..5c43e263b2c1 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c | |||
@@ -31,12 +31,15 @@ | |||
31 | #include <sound/rt286.h> | 31 | #include <sound/rt286.h> |
32 | #include <sound/hda_verbs.h> | 32 | #include <sound/hda_verbs.h> |
33 | 33 | ||
34 | #include "rl6347a.h" | ||
34 | #include "rt286.h" | 35 | #include "rt286.h" |
35 | 36 | ||
36 | #define RT286_VENDOR_ID 0x10ec0286 | 37 | #define RT286_VENDOR_ID 0x10ec0286 |
37 | #define RT288_VENDOR_ID 0x10ec0288 | 38 | #define RT288_VENDOR_ID 0x10ec0288 |
38 | 39 | ||
39 | struct rt286_priv { | 40 | struct rt286_priv { |
41 | struct reg_default *index_cache; | ||
42 | int index_cache_size; | ||
40 | struct regmap *regmap; | 43 | struct regmap *regmap; |
41 | struct snd_soc_codec *codec; | 44 | struct snd_soc_codec *codec; |
42 | struct rt286_platform_data pdata; | 45 | struct rt286_platform_data pdata; |
@@ -45,7 +48,6 @@ struct rt286_priv { | |||
45 | struct delayed_work jack_detect_work; | 48 | struct delayed_work jack_detect_work; |
46 | int sys_clk; | 49 | int sys_clk; |
47 | int clk_id; | 50 | int clk_id; |
48 | struct reg_default *index_cache; | ||
49 | }; | 51 | }; |
50 | 52 | ||
51 | static struct reg_default rt286_index_def[] = { | 53 | static struct reg_default rt286_index_def[] = { |
@@ -185,94 +187,6 @@ static bool rt286_readable_register(struct device *dev, unsigned int reg) | |||
185 | } | 187 | } |
186 | } | 188 | } |
187 | 189 | ||
188 | static int rt286_hw_write(void *context, unsigned int reg, unsigned int value) | ||
189 | { | ||
190 | struct i2c_client *client = context; | ||
191 | struct rt286_priv *rt286 = i2c_get_clientdata(client); | ||
192 | u8 data[4]; | ||
193 | int ret, i; | ||
194 | |||
195 | /* handle index registers */ | ||
196 | if (reg <= 0xff) { | ||
197 | rt286_hw_write(client, RT286_COEF_INDEX, reg); | ||
198 | for (i = 0; i < INDEX_CACHE_SIZE; i++) { | ||
199 | if (reg == rt286->index_cache[i].reg) { | ||
200 | rt286->index_cache[i].def = value; | ||
201 | break; | ||
202 | } | ||
203 | |||
204 | } | ||
205 | reg = RT286_PROC_COEF; | ||
206 | } | ||
207 | |||
208 | data[0] = (reg >> 24) & 0xff; | ||
209 | data[1] = (reg >> 16) & 0xff; | ||
210 | /* | ||
211 | * 4 bit VID: reg should be 0 | ||
212 | * 12 bit VID: value should be 0 | ||
213 | * So we use an OR operator to handle it rather than use if condition. | ||
214 | */ | ||
215 | data[2] = ((reg >> 8) & 0xff) | ((value >> 8) & 0xff); | ||
216 | data[3] = value & 0xff; | ||
217 | |||
218 | ret = i2c_master_send(client, data, 4); | ||
219 | |||
220 | if (ret == 4) | ||
221 | return 0; | ||
222 | else | ||
223 | pr_err("ret=%d\n", ret); | ||
224 | if (ret < 0) | ||
225 | return ret; | ||
226 | else | ||
227 | return -EIO; | ||
228 | } | ||
229 | |||
230 | static int rt286_hw_read(void *context, unsigned int reg, unsigned int *value) | ||
231 | { | ||
232 | struct i2c_client *client = context; | ||
233 | struct i2c_msg xfer[2]; | ||
234 | int ret; | ||
235 | __be32 be_reg; | ||
236 | unsigned int index, vid, buf = 0x0; | ||
237 | |||
238 | /* handle index registers */ | ||
239 | if (reg <= 0xff) { | ||
240 | rt286_hw_write(client, RT286_COEF_INDEX, reg); | ||
241 | reg = RT286_PROC_COEF; | ||
242 | } | ||
243 | |||
244 | reg = reg | 0x80000; | ||
245 | vid = (reg >> 8) & 0xfff; | ||
246 | |||
247 | if (AC_VERB_GET_AMP_GAIN_MUTE == (vid & 0xf00)) { | ||
248 | index = (reg >> 8) & 0xf; | ||
249 | reg = (reg & ~0xf0f) | index; | ||
250 | } | ||
251 | be_reg = cpu_to_be32(reg); | ||
252 | |||
253 | /* Write register */ | ||
254 | xfer[0].addr = client->addr; | ||
255 | xfer[0].flags = 0; | ||
256 | xfer[0].len = 4; | ||
257 | xfer[0].buf = (u8 *)&be_reg; | ||
258 | |||
259 | /* Read data */ | ||
260 | xfer[1].addr = client->addr; | ||
261 | xfer[1].flags = I2C_M_RD; | ||
262 | xfer[1].len = 4; | ||
263 | xfer[1].buf = (u8 *)&buf; | ||
264 | |||
265 | ret = i2c_transfer(client->adapter, xfer, 2); | ||
266 | if (ret < 0) | ||
267 | return ret; | ||
268 | else if (ret != 2) | ||
269 | return -EIO; | ||
270 | |||
271 | *value = be32_to_cpu(buf); | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | #ifdef CONFIG_PM | 190 | #ifdef CONFIG_PM |
277 | static void rt286_index_sync(struct snd_soc_codec *codec) | 191 | static void rt286_index_sync(struct snd_soc_codec *codec) |
278 | { | 192 | { |
@@ -1174,8 +1088,8 @@ static const struct regmap_config rt286_regmap = { | |||
1174 | .max_register = 0x02370100, | 1088 | .max_register = 0x02370100, |
1175 | .volatile_reg = rt286_volatile_register, | 1089 | .volatile_reg = rt286_volatile_register, |
1176 | .readable_reg = rt286_readable_register, | 1090 | .readable_reg = rt286_readable_register, |
1177 | .reg_write = rt286_hw_write, | 1091 | .reg_write = rl6347a_hw_write, |
1178 | .reg_read = rt286_hw_read, | 1092 | .reg_read = rl6347a_hw_read, |
1179 | .cache_type = REGCACHE_RBTREE, | 1093 | .cache_type = REGCACHE_RBTREE, |
1180 | .reg_defaults = rt286_reg, | 1094 | .reg_defaults = rt286_reg, |
1181 | .num_reg_defaults = ARRAY_SIZE(rt286_reg), | 1095 | .num_reg_defaults = ARRAY_SIZE(rt286_reg), |
@@ -1248,6 +1162,7 @@ static int rt286_i2c_probe(struct i2c_client *i2c, | |||
1248 | } | 1162 | } |
1249 | 1163 | ||
1250 | rt286->index_cache = rt286_index_def; | 1164 | rt286->index_cache = rt286_index_def; |
1165 | rt286->index_cache_size = INDEX_CACHE_SIZE; | ||
1251 | rt286->i2c = i2c; | 1166 | rt286->i2c = i2c; |
1252 | i2c_set_clientdata(i2c, rt286); | 1167 | i2c_set_clientdata(i2c, rt286); |
1253 | 1168 | ||
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index f40752a6c242..9bc78e57513d 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c | |||
@@ -51,7 +51,7 @@ static const struct regmap_range_cfg rt5640_ranges[] = { | |||
51 | .window_len = 0x1, }, | 51 | .window_len = 0x1, }, |
52 | }; | 52 | }; |
53 | 53 | ||
54 | static struct reg_default init_list[] = { | 54 | static const struct reg_default init_list[] = { |
55 | {RT5640_PR_BASE + 0x3d, 0x3600}, | 55 | {RT5640_PR_BASE + 0x3d, 0x3600}, |
56 | {RT5640_PR_BASE + 0x12, 0x0aa8}, | 56 | {RT5640_PR_BASE + 0x12, 0x0aa8}, |
57 | {RT5640_PR_BASE + 0x14, 0x0aaa}, | 57 | {RT5640_PR_BASE + 0x14, 0x0aaa}, |
@@ -59,7 +59,6 @@ static struct reg_default init_list[] = { | |||
59 | {RT5640_PR_BASE + 0x21, 0xe0e0}, | 59 | {RT5640_PR_BASE + 0x21, 0xe0e0}, |
60 | {RT5640_PR_BASE + 0x23, 0x1804}, | 60 | {RT5640_PR_BASE + 0x23, 0x1804}, |
61 | }; | 61 | }; |
62 | #define RT5640_INIT_REG_LEN ARRAY_SIZE(init_list) | ||
63 | 62 | ||
64 | static const struct reg_default rt5640_reg[] = { | 63 | static const struct reg_default rt5640_reg[] = { |
65 | { 0x00, 0x000e }, | 64 | { 0x00, 0x000e }, |
@@ -2122,7 +2121,7 @@ MODULE_DEVICE_TABLE(of, rt5640_of_match); | |||
2122 | #endif | 2121 | #endif |
2123 | 2122 | ||
2124 | #ifdef CONFIG_ACPI | 2123 | #ifdef CONFIG_ACPI |
2125 | static struct acpi_device_id rt5640_acpi_match[] = { | 2124 | static const struct acpi_device_id rt5640_acpi_match[] = { |
2126 | { "INT33CA", 0 }, | 2125 | { "INT33CA", 0 }, |
2127 | { "10EC5640", 0 }, | 2126 | { "10EC5640", 0 }, |
2128 | { "10EC5642", 0 }, | 2127 | { "10EC5642", 0 }, |
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index d5f0f5680d3b..9ce311e088fc 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c | |||
@@ -349,6 +349,7 @@ static bool rt5645_readable_register(struct device *dev, unsigned int reg) | |||
349 | case RT5645_TDM_CTRL_1: | 349 | case RT5645_TDM_CTRL_1: |
350 | case RT5645_TDM_CTRL_2: | 350 | case RT5645_TDM_CTRL_2: |
351 | case RT5645_TDM_CTRL_3: | 351 | case RT5645_TDM_CTRL_3: |
352 | case RT5650_TDM_CTRL_4: | ||
352 | case RT5645_GLB_CLK: | 353 | case RT5645_GLB_CLK: |
353 | case RT5645_PLL_CTRL1: | 354 | case RT5645_PLL_CTRL1: |
354 | case RT5645_PLL_CTRL2: | 355 | case RT5645_PLL_CTRL2: |
@@ -1705,15 +1706,6 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { | |||
1705 | SND_SOC_DAPM_MUX("RT5645 IF1 ADC Mux", SND_SOC_NOPM, | 1706 | SND_SOC_DAPM_MUX("RT5645 IF1 ADC Mux", SND_SOC_NOPM, |
1706 | 0, 0, &rt5645_if1_adc_in_mux), | 1707 | 0, 0, &rt5645_if1_adc_in_mux), |
1707 | 1708 | ||
1708 | SND_SOC_DAPM_MUX("RT5650 IF1 ADC1 Swap Mux", SND_SOC_NOPM, | ||
1709 | 0, 0, &rt5650_if1_adc1_in_mux), | ||
1710 | SND_SOC_DAPM_MUX("RT5650 IF1 ADC2 Swap Mux", SND_SOC_NOPM, | ||
1711 | 0, 0, &rt5650_if1_adc2_in_mux), | ||
1712 | SND_SOC_DAPM_MUX("RT5650 IF1 ADC3 Swap Mux", SND_SOC_NOPM, | ||
1713 | 0, 0, &rt5650_if1_adc3_in_mux), | ||
1714 | SND_SOC_DAPM_MUX("RT5650 IF1 ADC Mux", SND_SOC_NOPM, | ||
1715 | 0, 0, &rt5650_if1_adc_in_mux), | ||
1716 | |||
1717 | SND_SOC_DAPM_MUX("IF2 ADC Mux", SND_SOC_NOPM, | 1709 | SND_SOC_DAPM_MUX("IF2 ADC Mux", SND_SOC_NOPM, |
1718 | 0, 0, &rt5645_if2_adc_in_mux), | 1710 | 0, 0, &rt5645_if2_adc_in_mux), |
1719 | 1711 | ||
@@ -1732,14 +1724,6 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { | |||
1732 | &rt5645_if1_dac2_tdm_sel_mux), | 1724 | &rt5645_if1_dac2_tdm_sel_mux), |
1733 | SND_SOC_DAPM_MUX("RT5645 IF1 DAC2 R Mux", SND_SOC_NOPM, 0, 0, | 1725 | SND_SOC_DAPM_MUX("RT5645 IF1 DAC2 R Mux", SND_SOC_NOPM, 0, 0, |
1734 | &rt5645_if1_dac3_tdm_sel_mux), | 1726 | &rt5645_if1_dac3_tdm_sel_mux), |
1735 | SND_SOC_DAPM_MUX("RT5650 IF1 DAC1 L Mux", SND_SOC_NOPM, 0, 0, | ||
1736 | &rt5650_if1_dac0_tdm_sel_mux), | ||
1737 | SND_SOC_DAPM_MUX("RT5650 IF1 DAC1 R Mux", SND_SOC_NOPM, 0, 0, | ||
1738 | &rt5650_if1_dac1_tdm_sel_mux), | ||
1739 | SND_SOC_DAPM_MUX("RT5650 IF1 DAC2 L Mux", SND_SOC_NOPM, 0, 0, | ||
1740 | &rt5650_if1_dac2_tdm_sel_mux), | ||
1741 | SND_SOC_DAPM_MUX("RT5650 IF1 DAC2 R Mux", SND_SOC_NOPM, 0, 0, | ||
1742 | &rt5650_if1_dac3_tdm_sel_mux), | ||
1743 | SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0), | 1727 | SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0), |
1744 | SND_SOC_DAPM_PGA("IF1 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0), | 1728 | SND_SOC_DAPM_PGA("IF1 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0), |
1745 | SND_SOC_DAPM_PGA("IF1 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0), | 1729 | SND_SOC_DAPM_PGA("IF1 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0), |
@@ -1881,6 +1865,24 @@ static const struct snd_soc_dapm_widget rt5650_specific_dapm_widgets[] = { | |||
1881 | 0, 0, &rt5650_a_dac2_l_mux), | 1865 | 0, 0, &rt5650_a_dac2_l_mux), |
1882 | SND_SOC_DAPM_MUX("A DAC2 R Mux", SND_SOC_NOPM, | 1866 | SND_SOC_DAPM_MUX("A DAC2 R Mux", SND_SOC_NOPM, |
1883 | 0, 0, &rt5650_a_dac2_r_mux), | 1867 | 0, 0, &rt5650_a_dac2_r_mux), |
1868 | |||
1869 | SND_SOC_DAPM_MUX("RT5650 IF1 ADC1 Swap Mux", SND_SOC_NOPM, | ||
1870 | 0, 0, &rt5650_if1_adc1_in_mux), | ||
1871 | SND_SOC_DAPM_MUX("RT5650 IF1 ADC2 Swap Mux", SND_SOC_NOPM, | ||
1872 | 0, 0, &rt5650_if1_adc2_in_mux), | ||
1873 | SND_SOC_DAPM_MUX("RT5650 IF1 ADC3 Swap Mux", SND_SOC_NOPM, | ||
1874 | 0, 0, &rt5650_if1_adc3_in_mux), | ||
1875 | SND_SOC_DAPM_MUX("RT5650 IF1 ADC Mux", SND_SOC_NOPM, | ||
1876 | 0, 0, &rt5650_if1_adc_in_mux), | ||
1877 | |||
1878 | SND_SOC_DAPM_MUX("RT5650 IF1 DAC1 L Mux", SND_SOC_NOPM, 0, 0, | ||
1879 | &rt5650_if1_dac0_tdm_sel_mux), | ||
1880 | SND_SOC_DAPM_MUX("RT5650 IF1 DAC1 R Mux", SND_SOC_NOPM, 0, 0, | ||
1881 | &rt5650_if1_dac1_tdm_sel_mux), | ||
1882 | SND_SOC_DAPM_MUX("RT5650 IF1 DAC2 L Mux", SND_SOC_NOPM, 0, 0, | ||
1883 | &rt5650_if1_dac2_tdm_sel_mux), | ||
1884 | SND_SOC_DAPM_MUX("RT5650 IF1 DAC2 R Mux", SND_SOC_NOPM, 0, 0, | ||
1885 | &rt5650_if1_dac3_tdm_sel_mux), | ||
1884 | }; | 1886 | }; |
1885 | 1887 | ||
1886 | static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { | 1888 | static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { |
@@ -2761,6 +2763,7 @@ static void rt5645_enable_push_button_irq(struct snd_soc_codec *codec, | |||
2761 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | 2763 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); |
2762 | 2764 | ||
2763 | if (enable) { | 2765 | if (enable) { |
2766 | snd_soc_dapm_mutex_lock(&codec->dapm); | ||
2764 | snd_soc_dapm_force_enable_pin_unlocked(&codec->dapm, | 2767 | snd_soc_dapm_force_enable_pin_unlocked(&codec->dapm, |
2765 | "ADC L power"); | 2768 | "ADC L power"); |
2766 | snd_soc_dapm_force_enable_pin_unlocked(&codec->dapm, | 2769 | snd_soc_dapm_force_enable_pin_unlocked(&codec->dapm, |
@@ -2770,6 +2773,8 @@ static void rt5645_enable_push_button_irq(struct snd_soc_codec *codec, | |||
2770 | snd_soc_dapm_force_enable_pin_unlocked(&codec->dapm, | 2773 | snd_soc_dapm_force_enable_pin_unlocked(&codec->dapm, |
2771 | "Mic Det Power"); | 2774 | "Mic Det Power"); |
2772 | snd_soc_dapm_sync_unlocked(&codec->dapm); | 2775 | snd_soc_dapm_sync_unlocked(&codec->dapm); |
2776 | snd_soc_dapm_mutex_unlock(&codec->dapm); | ||
2777 | |||
2773 | snd_soc_update_bits(codec, | 2778 | snd_soc_update_bits(codec, |
2774 | RT5645_INT_IRQ_ST, 0x8, 0x8); | 2779 | RT5645_INT_IRQ_ST, 0x8, 0x8); |
2775 | snd_soc_update_bits(codec, | 2780 | snd_soc_update_bits(codec, |
@@ -2780,6 +2785,8 @@ static void rt5645_enable_push_button_irq(struct snd_soc_codec *codec, | |||
2780 | } else { | 2785 | } else { |
2781 | snd_soc_update_bits(codec, RT5650_4BTN_IL_CMD2, 0x8000, 0x0); | 2786 | snd_soc_update_bits(codec, RT5650_4BTN_IL_CMD2, 0x8000, 0x0); |
2782 | snd_soc_update_bits(codec, RT5645_INT_IRQ_ST, 0x8, 0x0); | 2787 | snd_soc_update_bits(codec, RT5645_INT_IRQ_ST, 0x8, 0x0); |
2788 | |||
2789 | snd_soc_dapm_mutex_lock(&codec->dapm); | ||
2783 | snd_soc_dapm_disable_pin_unlocked(&codec->dapm, | 2790 | snd_soc_dapm_disable_pin_unlocked(&codec->dapm, |
2784 | "ADC L power"); | 2791 | "ADC L power"); |
2785 | snd_soc_dapm_disable_pin_unlocked(&codec->dapm, | 2792 | snd_soc_dapm_disable_pin_unlocked(&codec->dapm, |
@@ -2790,6 +2797,7 @@ static void rt5645_enable_push_button_irq(struct snd_soc_codec *codec, | |||
2790 | snd_soc_dapm_disable_pin_unlocked(&codec->dapm, | 2797 | snd_soc_dapm_disable_pin_unlocked(&codec->dapm, |
2791 | "Mic Det Power"); | 2798 | "Mic Det Power"); |
2792 | snd_soc_dapm_sync_unlocked(&codec->dapm); | 2799 | snd_soc_dapm_sync_unlocked(&codec->dapm); |
2800 | snd_soc_dapm_mutex_unlock(&codec->dapm); | ||
2793 | } | 2801 | } |
2794 | } | 2802 | } |
2795 | 2803 | ||
@@ -2937,17 +2945,11 @@ static int rt5645_irq_detection(struct rt5645_priv *rt5645) | |||
2937 | 2945 | ||
2938 | switch (rt5645->pdata.jd_mode) { | 2946 | switch (rt5645->pdata.jd_mode) { |
2939 | case 0: /* Not using rt5645 JD */ | 2947 | case 0: /* Not using rt5645 JD */ |
2940 | if (gpio_is_valid(rt5645->pdata.hp_det_gpio)) { | 2948 | if (rt5645->gpiod_hp_det) { |
2941 | gpio_state = gpio_get_value(rt5645->pdata.hp_det_gpio); | 2949 | gpio_state = gpiod_get_value(rt5645->gpiod_hp_det); |
2942 | dev_dbg(rt5645->codec->dev, "gpio = %d(%d)\n", | 2950 | dev_dbg(rt5645->codec->dev, "gpio_state = %d\n", |
2943 | rt5645->pdata.hp_det_gpio, gpio_state); | 2951 | gpio_state); |
2944 | } | 2952 | report = rt5645_jack_detect(rt5645->codec, gpio_state); |
2945 | if ((rt5645->pdata.gpio_hp_det_active_high && gpio_state) || | ||
2946 | (!rt5645->pdata.gpio_hp_det_active_high && | ||
2947 | !gpio_state)) { | ||
2948 | report = rt5645_jack_detect(rt5645->codec, 1); | ||
2949 | } else { | ||
2950 | report = rt5645_jack_detect(rt5645->codec, 0); | ||
2951 | } | 2953 | } |
2952 | snd_soc_jack_report(rt5645->hp_jack, | 2954 | snd_soc_jack_report(rt5645->hp_jack, |
2953 | report, SND_JACK_HEADPHONE); | 2955 | report, SND_JACK_HEADPHONE); |
@@ -3230,6 +3232,20 @@ static struct dmi_system_id dmi_platform_intel_braswell[] = { | |||
3230 | { } | 3232 | { } |
3231 | }; | 3233 | }; |
3232 | 3234 | ||
3235 | static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev) | ||
3236 | { | ||
3237 | rt5645->pdata.in2_diff = device_property_read_bool(dev, | ||
3238 | "realtek,in2-differential"); | ||
3239 | device_property_read_u32(dev, | ||
3240 | "realtek,dmic1-data-pin", &rt5645->pdata.dmic1_data_pin); | ||
3241 | device_property_read_u32(dev, | ||
3242 | "realtek,dmic2-data-pin", &rt5645->pdata.dmic2_data_pin); | ||
3243 | device_property_read_u32(dev, | ||
3244 | "realtek,jd-mode", &rt5645->pdata.jd_mode); | ||
3245 | |||
3246 | return 0; | ||
3247 | } | ||
3248 | |||
3233 | static int rt5645_i2c_probe(struct i2c_client *i2c, | 3249 | static int rt5645_i2c_probe(struct i2c_client *i2c, |
3234 | const struct i2c_device_id *id) | 3250 | const struct i2c_device_id *id) |
3235 | { | 3251 | { |
@@ -3237,7 +3253,6 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | |||
3237 | struct rt5645_priv *rt5645; | 3253 | struct rt5645_priv *rt5645; |
3238 | int ret; | 3254 | int ret; |
3239 | unsigned int val; | 3255 | unsigned int val; |
3240 | struct gpio_desc *gpiod; | ||
3241 | 3256 | ||
3242 | rt5645 = devm_kzalloc(&i2c->dev, sizeof(struct rt5645_priv), | 3257 | rt5645 = devm_kzalloc(&i2c->dev, sizeof(struct rt5645_priv), |
3243 | GFP_KERNEL); | 3258 | GFP_KERNEL); |
@@ -3247,22 +3262,19 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | |||
3247 | rt5645->i2c = i2c; | 3262 | rt5645->i2c = i2c; |
3248 | i2c_set_clientdata(i2c, rt5645); | 3263 | i2c_set_clientdata(i2c, rt5645); |
3249 | 3264 | ||
3250 | if (pdata) { | 3265 | if (pdata) |
3251 | rt5645->pdata = *pdata; | 3266 | rt5645->pdata = *pdata; |
3252 | } else { | 3267 | else if (dmi_check_system(dmi_platform_intel_braswell)) |
3253 | if (dmi_check_system(dmi_platform_intel_braswell)) { | 3268 | rt5645->pdata = *rt5645_pdata; |
3254 | rt5645->pdata = *rt5645_pdata; | 3269 | else |
3255 | gpiod = devm_gpiod_get_index(&i2c->dev, "rt5645", 0); | 3270 | rt5645_parse_dt(rt5645, &i2c->dev); |
3256 | 3271 | ||
3257 | if (IS_ERR(gpiod) || gpiod_direction_input(gpiod)) { | 3272 | rt5645->gpiod_hp_det = devm_gpiod_get_optional(&i2c->dev, "hp-detect", |
3258 | rt5645->pdata.hp_det_gpio = -1; | 3273 | GPIOD_IN); |
3259 | dev_err(&i2c->dev, "failed to initialize gpiod\n"); | 3274 | |
3260 | } else { | 3275 | if (IS_ERR(rt5645->gpiod_hp_det)) { |
3261 | rt5645->pdata.hp_det_gpio = desc_to_gpio(gpiod); | 3276 | dev_err(&i2c->dev, "failed to initialize gpiod\n"); |
3262 | rt5645->pdata.gpio_hp_det_active_high | 3277 | return PTR_ERR(rt5645->gpiod_hp_det); |
3263 | = !gpiod_is_active_low(gpiod); | ||
3264 | } | ||
3265 | } | ||
3266 | } | 3278 | } |
3267 | 3279 | ||
3268 | rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5645_regmap); | 3280 | rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5645_regmap); |
@@ -3426,16 +3438,6 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | |||
3426 | dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret); | 3438 | dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret); |
3427 | } | 3439 | } |
3428 | 3440 | ||
3429 | if (gpio_is_valid(rt5645->pdata.hp_det_gpio)) { | ||
3430 | ret = gpio_request(rt5645->pdata.hp_det_gpio, "rt5645"); | ||
3431 | if (ret) | ||
3432 | dev_err(&i2c->dev, "Fail gpio_request hp_det_gpio\n"); | ||
3433 | |||
3434 | ret = gpio_direction_input(rt5645->pdata.hp_det_gpio); | ||
3435 | if (ret) | ||
3436 | dev_err(&i2c->dev, "Fail gpio_direction hp_det_gpio\n"); | ||
3437 | } | ||
3438 | |||
3439 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5645, | 3441 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5645, |
3440 | rt5645_dai, ARRAY_SIZE(rt5645_dai)); | 3442 | rt5645_dai, ARRAY_SIZE(rt5645_dai)); |
3441 | } | 3443 | } |
@@ -3449,9 +3451,6 @@ static int rt5645_i2c_remove(struct i2c_client *i2c) | |||
3449 | 3451 | ||
3450 | cancel_delayed_work_sync(&rt5645->jack_detect_work); | 3452 | cancel_delayed_work_sync(&rt5645->jack_detect_work); |
3451 | 3453 | ||
3452 | if (gpio_is_valid(rt5645->pdata.hp_det_gpio)) | ||
3453 | gpio_free(rt5645->pdata.hp_det_gpio); | ||
3454 | |||
3455 | snd_soc_unregister_codec(&i2c->dev); | 3454 | snd_soc_unregister_codec(&i2c->dev); |
3456 | 3455 | ||
3457 | return 0; | 3456 | return 0; |
diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h index 9ec4e899795d..0353a6a273ab 100644 --- a/sound/soc/codecs/rt5645.h +++ b/sound/soc/codecs/rt5645.h | |||
@@ -2182,6 +2182,7 @@ struct rt5645_priv { | |||
2182 | struct rt5645_platform_data pdata; | 2182 | struct rt5645_platform_data pdata; |
2183 | struct regmap *regmap; | 2183 | struct regmap *regmap; |
2184 | struct i2c_client *i2c; | 2184 | struct i2c_client *i2c; |
2185 | struct gpio_desc *gpiod_hp_det; | ||
2185 | struct snd_soc_jack *hp_jack; | 2186 | struct snd_soc_jack *hp_jack; |
2186 | struct snd_soc_jack *mic_jack; | 2187 | struct snd_soc_jack *mic_jack; |
2187 | struct snd_soc_jack *btn_jack; | 2188 | struct snd_soc_jack *btn_jack; |
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 840dd6d0003a..a9123d414178 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c | |||
@@ -51,12 +51,11 @@ static const struct regmap_range_cfg rt5670_ranges[] = { | |||
51 | .window_len = 0x1, }, | 51 | .window_len = 0x1, }, |
52 | }; | 52 | }; |
53 | 53 | ||
54 | static struct reg_default init_list[] = { | 54 | static const struct reg_default init_list[] = { |
55 | { RT5670_PR_BASE + 0x14, 0x9a8a }, | 55 | { RT5670_PR_BASE + 0x14, 0x9a8a }, |
56 | { RT5670_PR_BASE + 0x38, 0x3ba1 }, | 56 | { RT5670_PR_BASE + 0x38, 0x3ba1 }, |
57 | { RT5670_PR_BASE + 0x3d, 0x3640 }, | 57 | { RT5670_PR_BASE + 0x3d, 0x3640 }, |
58 | }; | 58 | }; |
59 | #define RT5670_INIT_REG_LEN ARRAY_SIZE(init_list) | ||
60 | 59 | ||
61 | static const struct reg_default rt5670_reg[] = { | 60 | static const struct reg_default rt5670_reg[] = { |
62 | { 0x00, 0x0000 }, | 61 | { 0x00, 0x0000 }, |
@@ -2809,7 +2808,7 @@ static const struct i2c_device_id rt5670_i2c_id[] = { | |||
2809 | MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id); | 2808 | MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id); |
2810 | 2809 | ||
2811 | #ifdef CONFIG_ACPI | 2810 | #ifdef CONFIG_ACPI |
2812 | static struct acpi_device_id rt5670_acpi_match[] = { | 2811 | static const struct acpi_device_id rt5670_acpi_match[] = { |
2813 | { "10EC5670", 0}, | 2812 | { "10EC5670", 0}, |
2814 | { }, | 2813 | { }, |
2815 | }; | 2814 | }; |
diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c index 891e2c529df3..4f25a7d0efa2 100644 --- a/sound/soc/codecs/tas2552.c +++ b/sound/soc/codecs/tas2552.c | |||
@@ -45,7 +45,7 @@ static struct reg_default tas2552_reg_defs[] = { | |||
45 | {TAS2552_OUTPUT_DATA, 0xc0}, | 45 | {TAS2552_OUTPUT_DATA, 0xc0}, |
46 | {TAS2552_PDM_CFG, 0x01}, | 46 | {TAS2552_PDM_CFG, 0x01}, |
47 | {TAS2552_PGA_GAIN, 0x00}, | 47 | {TAS2552_PGA_GAIN, 0x00}, |
48 | {TAS2552_BOOST_PT_CTRL, 0x0f}, | 48 | {TAS2552_BOOST_APT_CTRL, 0x0f}, |
49 | {TAS2552_RESERVED_0D, 0xbe}, | 49 | {TAS2552_RESERVED_0D, 0xbe}, |
50 | {TAS2552_LIMIT_RATE_HYS, 0x08}, | 50 | {TAS2552_LIMIT_RATE_HYS, 0x08}, |
51 | {TAS2552_CFG_2, 0xef}, | 51 | {TAS2552_CFG_2, 0xef}, |
@@ -77,7 +77,9 @@ struct tas2552_data { | |||
77 | struct gpio_desc *enable_gpio; | 77 | struct gpio_desc *enable_gpio; |
78 | unsigned char regs[TAS2552_VBAT_DATA]; | 78 | unsigned char regs[TAS2552_VBAT_DATA]; |
79 | unsigned int pll_clkin; | 79 | unsigned int pll_clkin; |
80 | int pll_clk_id; | ||
80 | unsigned int pdm_clk; | 81 | unsigned int pdm_clk; |
82 | int pdm_clk_id; | ||
81 | 83 | ||
82 | unsigned int dai_fmt; | 84 | unsigned int dai_fmt; |
83 | unsigned int tdm_delay; | 85 | unsigned int tdm_delay; |
@@ -143,31 +145,105 @@ static const struct snd_soc_dapm_route tas2552_audio_map[] = { | |||
143 | }; | 145 | }; |
144 | 146 | ||
145 | #ifdef CONFIG_PM | 147 | #ifdef CONFIG_PM |
146 | static void tas2552_sw_shutdown(struct tas2552_data *tas_data, int sw_shutdown) | 148 | static void tas2552_sw_shutdown(struct tas2552_data *tas2552, int sw_shutdown) |
147 | { | 149 | { |
148 | u8 cfg1_reg = 0; | 150 | u8 cfg1_reg = 0; |
149 | 151 | ||
150 | if (!tas_data->codec) | 152 | if (!tas2552->codec) |
151 | return; | 153 | return; |
152 | 154 | ||
153 | if (sw_shutdown) | 155 | if (sw_shutdown) |
154 | cfg1_reg = TAS2552_SWS; | 156 | cfg1_reg = TAS2552_SWS; |
155 | 157 | ||
156 | snd_soc_update_bits(tas_data->codec, TAS2552_CFG_1, TAS2552_SWS, | 158 | snd_soc_update_bits(tas2552->codec, TAS2552_CFG_1, TAS2552_SWS, |
157 | cfg1_reg); | 159 | cfg1_reg); |
158 | } | 160 | } |
159 | #endif | 161 | #endif |
160 | 162 | ||
163 | static int tas2552_setup_pll(struct snd_soc_codec *codec, | ||
164 | struct snd_pcm_hw_params *params) | ||
165 | { | ||
166 | struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev); | ||
167 | bool bypass_pll = false; | ||
168 | unsigned int pll_clk = params_rate(params) * 512; | ||
169 | unsigned int pll_clkin = tas2552->pll_clkin; | ||
170 | u8 pll_enable; | ||
171 | |||
172 | if (!pll_clkin) { | ||
173 | if (tas2552->pll_clk_id != TAS2552_PLL_CLKIN_BCLK) | ||
174 | return -EINVAL; | ||
175 | |||
176 | pll_clkin = snd_soc_params_to_bclk(params); | ||
177 | pll_clkin += tas2552->tdm_delay; | ||
178 | } | ||
179 | |||
180 | pll_enable = snd_soc_read(codec, TAS2552_CFG_2) & TAS2552_PLL_ENABLE; | ||
181 | snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0); | ||
182 | |||
183 | if (pll_clkin == pll_clk) | ||
184 | bypass_pll = true; | ||
185 | |||
186 | if (bypass_pll) { | ||
187 | /* By pass the PLL configuration */ | ||
188 | snd_soc_update_bits(codec, TAS2552_PLL_CTRL_2, | ||
189 | TAS2552_PLL_BYPASS, TAS2552_PLL_BYPASS); | ||
190 | } else { | ||
191 | /* Fill in the PLL control registers for J & D | ||
192 | * pll_clk = (.5 * pll_clkin * J.D) / 2^p | ||
193 | * Need to fill in J and D here based on incoming freq | ||
194 | */ | ||
195 | unsigned int d; | ||
196 | u8 j; | ||
197 | u8 pll_sel = (tas2552->pll_clk_id << 3) & TAS2552_PLL_SRC_MASK; | ||
198 | u8 p = snd_soc_read(codec, TAS2552_PLL_CTRL_1); | ||
199 | |||
200 | p = (p >> 7); | ||
201 | |||
202 | recalc: | ||
203 | j = (pll_clk * 2 * (1 << p)) / pll_clkin; | ||
204 | d = (pll_clk * 2 * (1 << p)) % pll_clkin; | ||
205 | d /= (pll_clkin / 10000); | ||
206 | |||
207 | if (d && (pll_clkin < 512000 || pll_clkin > 9200000)) { | ||
208 | if (tas2552->pll_clk_id == TAS2552_PLL_CLKIN_BCLK) { | ||
209 | pll_clkin = 1800000; | ||
210 | pll_sel = (TAS2552_PLL_CLKIN_1_8_FIXED << 3) & | ||
211 | TAS2552_PLL_SRC_MASK; | ||
212 | } else { | ||
213 | pll_clkin = snd_soc_params_to_bclk(params); | ||
214 | pll_clkin += tas2552->tdm_delay; | ||
215 | pll_sel = (TAS2552_PLL_CLKIN_BCLK << 3) & | ||
216 | TAS2552_PLL_SRC_MASK; | ||
217 | } | ||
218 | goto recalc; | ||
219 | } | ||
220 | |||
221 | snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_PLL_SRC_MASK, | ||
222 | pll_sel); | ||
223 | |||
224 | snd_soc_update_bits(codec, TAS2552_PLL_CTRL_1, | ||
225 | TAS2552_PLL_J_MASK, j); | ||
226 | /* Will clear the PLL_BYPASS bit */ | ||
227 | snd_soc_write(codec, TAS2552_PLL_CTRL_2, | ||
228 | TAS2552_PLL_D_UPPER(d)); | ||
229 | snd_soc_write(codec, TAS2552_PLL_CTRL_3, | ||
230 | TAS2552_PLL_D_LOWER(d)); | ||
231 | } | ||
232 | |||
233 | /* Restore PLL status */ | ||
234 | snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, | ||
235 | pll_enable); | ||
236 | |||
237 | return 0; | ||
238 | } | ||
239 | |||
161 | static int tas2552_hw_params(struct snd_pcm_substream *substream, | 240 | static int tas2552_hw_params(struct snd_pcm_substream *substream, |
162 | struct snd_pcm_hw_params *params, | 241 | struct snd_pcm_hw_params *params, |
163 | struct snd_soc_dai *dai) | 242 | struct snd_soc_dai *dai) |
164 | { | 243 | { |
165 | struct snd_soc_codec *codec = dai->codec; | 244 | struct snd_soc_codec *codec = dai->codec; |
166 | struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev); | 245 | struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev); |
167 | int sample_rate, pll_clk; | ||
168 | int d; | ||
169 | int cpf; | 246 | int cpf; |
170 | u8 p, j; | ||
171 | u8 ser_ctrl1_reg, wclk_rate; | 247 | u8 ser_ctrl1_reg, wclk_rate; |
172 | 248 | ||
173 | switch (params_width(params)) { | 249 | switch (params_width(params)) { |
@@ -245,49 +321,7 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream, | |||
245 | snd_soc_update_bits(codec, TAS2552_CFG_3, TAS2552_WCLK_FREQ_MASK, | 321 | snd_soc_update_bits(codec, TAS2552_CFG_3, TAS2552_WCLK_FREQ_MASK, |
246 | wclk_rate); | 322 | wclk_rate); |
247 | 323 | ||
248 | if (!tas2552->pll_clkin) | 324 | return tas2552_setup_pll(codec, params); |
249 | return -EINVAL; | ||
250 | |||
251 | snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0); | ||
252 | |||
253 | if (tas2552->pll_clkin == TAS2552_245MHZ_CLK || | ||
254 | tas2552->pll_clkin == TAS2552_225MHZ_CLK) { | ||
255 | /* By pass the PLL configuration */ | ||
256 | snd_soc_update_bits(codec, TAS2552_PLL_CTRL_2, | ||
257 | TAS2552_PLL_BYPASS_MASK, | ||
258 | TAS2552_PLL_BYPASS); | ||
259 | } else { | ||
260 | /* Fill in the PLL control registers for J & D | ||
261 | * PLL_CLK = (.5 * freq * J.D) / 2^p | ||
262 | * Need to fill in J and D here based on incoming freq | ||
263 | */ | ||
264 | p = snd_soc_read(codec, TAS2552_PLL_CTRL_1); | ||
265 | p = (p >> 7); | ||
266 | sample_rate = params_rate(params); | ||
267 | |||
268 | if (sample_rate == 48000) | ||
269 | pll_clk = TAS2552_245MHZ_CLK; | ||
270 | else if (sample_rate == 44100) | ||
271 | pll_clk = TAS2552_225MHZ_CLK; | ||
272 | else { | ||
273 | dev_vdbg(codec->dev, "Substream sample rate is not found %i\n", | ||
274 | params_rate(params)); | ||
275 | return -EINVAL; | ||
276 | } | ||
277 | |||
278 | j = (pll_clk * 2 * (1 << p)) / tas2552->pll_clkin; | ||
279 | d = (pll_clk * 2 * (1 << p)) % tas2552->pll_clkin; | ||
280 | |||
281 | snd_soc_update_bits(codec, TAS2552_PLL_CTRL_1, | ||
282 | TAS2552_PLL_J_MASK, j); | ||
283 | snd_soc_write(codec, TAS2552_PLL_CTRL_2, | ||
284 | (d >> 7) & TAS2552_PLL_D_UPPER_MASK); | ||
285 | snd_soc_write(codec, TAS2552_PLL_CTRL_3, | ||
286 | d & TAS2552_PLL_D_LOWER_MASK); | ||
287 | |||
288 | } | ||
289 | |||
290 | return 0; | ||
291 | } | 325 | } |
292 | 326 | ||
293 | #define TAS2552_DAI_FMT_MASK (TAS2552_BCLKDIR | \ | 327 | #define TAS2552_DAI_FMT_MASK (TAS2552_BCLKDIR | \ |
@@ -370,12 +404,21 @@ static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, | |||
370 | 404 | ||
371 | switch (clk_id) { | 405 | switch (clk_id) { |
372 | case TAS2552_PLL_CLKIN_MCLK: | 406 | case TAS2552_PLL_CLKIN_MCLK: |
373 | case TAS2552_PLL_CLKIN_BCLK: | ||
374 | case TAS2552_PLL_CLKIN_IVCLKIN: | 407 | case TAS2552_PLL_CLKIN_IVCLKIN: |
408 | if (freq < 512000 || freq > 24576000) { | ||
409 | /* out of range PLL_CLKIN, fall back to use BCLK */ | ||
410 | dev_warn(codec->dev, "Out of range PLL_CLKIN: %u\n", | ||
411 | freq); | ||
412 | clk_id = TAS2552_PLL_CLKIN_BCLK; | ||
413 | freq = 0; | ||
414 | } | ||
415 | /* fall through */ | ||
416 | case TAS2552_PLL_CLKIN_BCLK: | ||
375 | case TAS2552_PLL_CLKIN_1_8_FIXED: | 417 | case TAS2552_PLL_CLKIN_1_8_FIXED: |
376 | mask = TAS2552_PLL_SRC_MASK; | 418 | mask = TAS2552_PLL_SRC_MASK; |
377 | val = (clk_id << 3) & mask; /* bit 4:5 in the register */ | 419 | val = (clk_id << 3) & mask; /* bit 4:5 in the register */ |
378 | reg = TAS2552_CFG_1; | 420 | reg = TAS2552_CFG_1; |
421 | tas2552->pll_clk_id = clk_id; | ||
379 | tas2552->pll_clkin = freq; | 422 | tas2552->pll_clkin = freq; |
380 | break; | 423 | break; |
381 | case TAS2552_PDM_CLK_PLL: | 424 | case TAS2552_PDM_CLK_PLL: |
@@ -385,6 +428,7 @@ static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, | |||
385 | mask = TAS2552_PDM_CLK_SEL_MASK; | 428 | mask = TAS2552_PDM_CLK_SEL_MASK; |
386 | val = (clk_id >> 1) & mask; /* bit 0:1 in the register */ | 429 | val = (clk_id >> 1) & mask; /* bit 0:1 in the register */ |
387 | reg = TAS2552_PDM_CFG; | 430 | reg = TAS2552_PDM_CFG; |
431 | tas2552->pdm_clk_id = clk_id; | ||
388 | tas2552->pdm_clk = freq; | 432 | tas2552->pdm_clk = freq; |
389 | break; | 433 | break; |
390 | default: | 434 | default: |
@@ -509,9 +553,20 @@ static struct snd_soc_dai_driver tas2552_dai[] = { | |||
509 | */ | 553 | */ |
510 | static DECLARE_TLV_DB_SCALE(dac_tlv, -7, 100, 0); | 554 | static DECLARE_TLV_DB_SCALE(dac_tlv, -7, 100, 0); |
511 | 555 | ||
556 | static const char * const tas2552_din_source_select[] = { | ||
557 | "Muted", | ||
558 | "Left", | ||
559 | "Right", | ||
560 | "Left + Right average", | ||
561 | }; | ||
562 | static SOC_ENUM_SINGLE_DECL(tas2552_din_source_enum, | ||
563 | TAS2552_CFG_3, 3, | ||
564 | tas2552_din_source_select); | ||
565 | |||
512 | static const struct snd_kcontrol_new tas2552_snd_controls[] = { | 566 | static const struct snd_kcontrol_new tas2552_snd_controls[] = { |
513 | SOC_SINGLE_TLV("Speaker Driver Playback Volume", | 567 | SOC_SINGLE_TLV("Speaker Driver Playback Volume", |
514 | TAS2552_PGA_GAIN, 0, 0x1f, 0, dac_tlv), | 568 | TAS2552_PGA_GAIN, 0, 0x1f, 0, dac_tlv), |
569 | SOC_ENUM("DIN source", tas2552_din_source_enum), | ||
515 | }; | 570 | }; |
516 | 571 | ||
517 | static int tas2552_codec_probe(struct snd_soc_codec *codec) | 572 | static int tas2552_codec_probe(struct snd_soc_codec *codec) |
@@ -543,13 +598,14 @@ static int tas2552_codec_probe(struct snd_soc_codec *codec) | |||
543 | snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_MUTE, TAS2552_MUTE); | 598 | snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_MUTE, TAS2552_MUTE); |
544 | snd_soc_write(codec, TAS2552_CFG_3, TAS2552_I2S_OUT_SEL | | 599 | snd_soc_write(codec, TAS2552_CFG_3, TAS2552_I2S_OUT_SEL | |
545 | TAS2552_DIN_SRC_SEL_AVG_L_R); | 600 | TAS2552_DIN_SRC_SEL_AVG_L_R); |
546 | snd_soc_write(codec, TAS2552_DOUT, TAS2552_PDM_DATA_I); | 601 | snd_soc_write(codec, TAS2552_OUTPUT_DATA, |
547 | snd_soc_write(codec, TAS2552_OUTPUT_DATA, TAS2552_PDM_DATA_V_I | 0x8); | 602 | TAS2552_PDM_DATA_SEL_V_I | |
548 | snd_soc_write(codec, TAS2552_BOOST_PT_CTRL, TAS2552_APT_DELAY_200 | | 603 | TAS2552_R_DATA_OUT(TAS2552_DATA_OUT_V_DATA)); |
549 | TAS2552_APT_THRESH_2_1_7); | 604 | snd_soc_write(codec, TAS2552_BOOST_APT_CTRL, TAS2552_APT_DELAY_200 | |
605 | TAS2552_APT_THRESH_20_17); | ||
550 | 606 | ||
551 | snd_soc_write(codec, TAS2552_CFG_2, TAS2552_BOOST_EN | | 607 | snd_soc_write(codec, TAS2552_CFG_2, TAS2552_BOOST_EN | TAS2552_APT_EN | |
552 | TAS2552_APT_EN | TAS2552_LIM_EN); | 608 | TAS2552_LIM_EN); |
553 | 609 | ||
554 | return 0; | 610 | return 0; |
555 | 611 | ||
@@ -647,13 +703,10 @@ static int tas2552_probe(struct i2c_client *client, | |||
647 | if (data == NULL) | 703 | if (data == NULL) |
648 | return -ENOMEM; | 704 | return -ENOMEM; |
649 | 705 | ||
650 | data->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); | 706 | data->enable_gpio = devm_gpiod_get_optional(dev, "enable", |
651 | if (IS_ERR(data->enable_gpio)) { | 707 | GPIOD_OUT_LOW); |
652 | if (PTR_ERR(data->enable_gpio) == -EPROBE_DEFER) | 708 | if (IS_ERR(data->enable_gpio)) |
653 | return -EPROBE_DEFER; | 709 | return PTR_ERR(data->enable_gpio); |
654 | |||
655 | data->enable_gpio = NULL;; | ||
656 | } | ||
657 | 710 | ||
658 | data->tas2552_client = client; | 711 | data->tas2552_client = client; |
659 | data->regmap = devm_regmap_init_i2c(client, &tas2552_regmap_config); | 712 | data->regmap = devm_regmap_init_i2c(client, &tas2552_regmap_config); |
@@ -695,6 +748,7 @@ static int tas2552_probe(struct i2c_client *client, | |||
695 | static int tas2552_i2c_remove(struct i2c_client *client) | 748 | static int tas2552_i2c_remove(struct i2c_client *client) |
696 | { | 749 | { |
697 | snd_soc_unregister_codec(&client->dev); | 750 | snd_soc_unregister_codec(&client->dev); |
751 | pm_runtime_disable(&client->dev); | ||
698 | return 0; | 752 | return 0; |
699 | } | 753 | } |
700 | 754 | ||
diff --git a/sound/soc/codecs/tas2552.h b/sound/soc/codecs/tas2552.h index bbb820495516..5746f8fd0afd 100644 --- a/sound/soc/codecs/tas2552.h +++ b/sound/soc/codecs/tas2552.h | |||
@@ -19,7 +19,7 @@ | |||
19 | #define __TAS2552_H__ | 19 | #define __TAS2552_H__ |
20 | 20 | ||
21 | /* Register Address Map */ | 21 | /* Register Address Map */ |
22 | #define TAS2552_DEVICE_STATUS 0x00 | 22 | #define TAS2552_DEVICE_STATUS 0x00 |
23 | #define TAS2552_CFG_1 0x01 | 23 | #define TAS2552_CFG_1 0x01 |
24 | #define TAS2552_CFG_2 0x02 | 24 | #define TAS2552_CFG_2 0x02 |
25 | #define TAS2552_CFG_3 0x03 | 25 | #define TAS2552_CFG_3 0x03 |
@@ -33,13 +33,13 @@ | |||
33 | #define TAS2552_BTIP 0x0b | 33 | #define TAS2552_BTIP 0x0b |
34 | #define TAS2552_BTS_CTRL 0x0c | 34 | #define TAS2552_BTS_CTRL 0x0c |
35 | #define TAS2552_RESERVED_0D 0x0d | 35 | #define TAS2552_RESERVED_0D 0x0d |
36 | #define TAS2552_LIMIT_RATE_HYS 0x0e | 36 | #define TAS2552_LIMIT_RATE_HYS 0x0e |
37 | #define TAS2552_LIMIT_RELEASE 0x0f | 37 | #define TAS2552_LIMIT_RELEASE 0x0f |
38 | #define TAS2552_LIMIT_INT_COUNT 0x10 | 38 | #define TAS2552_LIMIT_INT_COUNT 0x10 |
39 | #define TAS2552_PDM_CFG 0x11 | 39 | #define TAS2552_PDM_CFG 0x11 |
40 | #define TAS2552_PGA_GAIN 0x12 | 40 | #define TAS2552_PGA_GAIN 0x12 |
41 | #define TAS2552_EDGE_RATE_CTRL 0x13 | 41 | #define TAS2552_EDGE_RATE_CTRL 0x13 |
42 | #define TAS2552_BOOST_PT_CTRL 0x14 | 42 | #define TAS2552_BOOST_APT_CTRL 0x14 |
43 | #define TAS2552_VER_NUM 0x16 | 43 | #define TAS2552_VER_NUM 0x16 |
44 | #define TAS2552_VBAT_DATA 0x19 | 44 | #define TAS2552_VBAT_DATA 0x19 |
45 | #define TAS2552_MAX_REG 0x20 | 45 | #define TAS2552_MAX_REG 0x20 |
@@ -103,10 +103,21 @@ | |||
103 | #define TAS2552_WCLKDIR (1 << 7) | 103 | #define TAS2552_WCLKDIR (1 << 7) |
104 | 104 | ||
105 | /* OUTPUT_DATA register */ | 105 | /* OUTPUT_DATA register */ |
106 | #define TAS2552_PDM_DATA_I 0x00 | 106 | #define TAS2552_DATA_OUT_I_DATA (0x0) |
107 | #define TAS2552_PDM_DATA_V (1 << 6) | 107 | #define TAS2552_DATA_OUT_V_DATA (0x1) |
108 | #define TAS2552_PDM_DATA_I_V (1 << 7) | 108 | #define TAS2552_DATA_OUT_VBAT_DATA (0x2) |
109 | #define TAS2552_PDM_DATA_V_I (0x11 << 6) | 109 | #define TAS2552_DATA_OUT_VBOOST_DATA (0x3) |
110 | #define TAS2552_DATA_OUT_PGA_GAIN (0x4) | ||
111 | #define TAS2552_DATA_OUT_IV_DATA (0x5) | ||
112 | #define TAS2552_DATA_OUT_VBAT_VBOOST_GAIN (0x6) | ||
113 | #define TAS2552_DATA_OUT_DISABLED (0x7) | ||
114 | #define TAS2552_L_DATA_OUT(x) ((x) << 0) | ||
115 | #define TAS2552_R_DATA_OUT(x) ((x) << 3) | ||
116 | #define TAS2552_PDM_DATA_SEL_I (0x0 << 6) | ||
117 | #define TAS2552_PDM_DATA_SEL_V (0x1 << 6) | ||
118 | #define TAS2552_PDM_DATA_SEL_I_V (0x2 << 6) | ||
119 | #define TAS2552_PDM_DATA_SEL_V_I (0x3 << 6) | ||
120 | #define TAS2552_PDM_DATA_SEL_MASK TAS2552_PDM_DATA_SEL_V_I | ||
110 | 121 | ||
111 | /* PDM CFG Register */ | 122 | /* PDM CFG Register */ |
112 | #define TAS2552_PDM_CLK_SEL_PLL (0x0 << 0) | 123 | #define TAS2552_PDM_CLK_SEL_PLL (0x0 << 0) |
@@ -116,24 +127,20 @@ | |||
116 | #define TAS2552_PDM_CLK_SEL_MASK TAS2552_PDM_CLK_SEL_MCLK | 127 | #define TAS2552_PDM_CLK_SEL_MASK TAS2552_PDM_CLK_SEL_MCLK |
117 | #define TAS2552_PDM_DATA_ES (1 << 2) | 128 | #define TAS2552_PDM_DATA_ES (1 << 2) |
118 | 129 | ||
119 | /* Boost pass-through register */ | 130 | /* Boost Auto-pass through register */ |
120 | #define TAS2552_APT_DELAY_50 0x00 | 131 | #define TAS2552_APT_DELAY_50 (0x0 << 0) |
121 | #define TAS2552_APT_DELAY_75 (1 << 1) | 132 | #define TAS2552_APT_DELAY_75 (0x1 << 0) |
122 | #define TAS2552_APT_DELAY_125 (1 << 2) | 133 | #define TAS2552_APT_DELAY_125 (0x2 << 0) |
123 | #define TAS2552_APT_DELAY_200 (1 << 3) | 134 | #define TAS2552_APT_DELAY_200 (0x3 << 0) |
124 | 135 | #define TAS2552_APT_THRESH_05_02 (0x0 << 2) | |
125 | #define TAS2552_APT_THRESH_2_5 0x00 | 136 | #define TAS2552_APT_THRESH_10_07 (0x1 << 2) |
126 | #define TAS2552_APT_THRESH_1_7 (1 << 3) | 137 | #define TAS2552_APT_THRESH_14_11 (0x2 << 2) |
127 | #define TAS2552_APT_THRESH_1_4_1_1 (1 << 4) | 138 | #define TAS2552_APT_THRESH_20_17 (0x3 << 2) |
128 | #define TAS2552_APT_THRESH_2_1_7 (0x11 << 2) | ||
129 | 139 | ||
130 | /* PLL Control Register */ | 140 | /* PLL Control Register */ |
131 | #define TAS2552_245MHZ_CLK 24576000 | 141 | #define TAS2552_PLL_J_MASK 0x7f |
132 | #define TAS2552_225MHZ_CLK 22579200 | 142 | #define TAS2552_PLL_D_UPPER(x) (((x) >> 8) & 0x3f) |
133 | #define TAS2552_PLL_J_MASK 0x7f | 143 | #define TAS2552_PLL_D_LOWER(x) ((x) & 0xff) |
134 | #define TAS2552_PLL_D_UPPER_MASK 0x3f | 144 | #define TAS2552_PLL_BYPASS (1 << 7) |
135 | #define TAS2552_PLL_D_LOWER_MASK 0xff | ||
136 | #define TAS2552_PLL_BYPASS_MASK 0x80 | ||
137 | #define TAS2552_PLL_BYPASS 0x80 | ||
138 | 145 | ||
139 | #endif | 146 | #endif |
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index d8959e31853d..c5ec519d34be 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
@@ -1876,8 +1876,8 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec) | |||
1876 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); | 1876 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); |
1877 | int ret; | 1877 | int ret; |
1878 | 1878 | ||
1879 | ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 2); | 1879 | ret = wm_adsp2_codec_probe(&priv->core.adsp[0], codec); |
1880 | if (ret != 0) | 1880 | if (ret) |
1881 | return ret; | 1881 | return ret; |
1882 | 1882 | ||
1883 | arizona_init_spk(codec); | 1883 | arizona_init_spk(codec); |
@@ -1894,6 +1894,8 @@ static int wm5102_codec_remove(struct snd_soc_codec *codec) | |||
1894 | { | 1894 | { |
1895 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); | 1895 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); |
1896 | 1896 | ||
1897 | wm_adsp2_codec_remove(&priv->core.adsp[0], codec); | ||
1898 | |||
1897 | priv->core.arizona->dapm = NULL; | 1899 | priv->core.arizona->dapm = NULL; |
1898 | 1900 | ||
1899 | return 0; | 1901 | return 0; |
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 14a7739d6c09..5f032a37b61f 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
@@ -1600,7 +1600,7 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec) | |||
1600 | { | 1600 | { |
1601 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | 1601 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); |
1602 | struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); | 1602 | struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); |
1603 | int ret; | 1603 | int i, ret; |
1604 | 1604 | ||
1605 | priv->core.arizona->dapm = dapm; | 1605 | priv->core.arizona->dapm = dapm; |
1606 | 1606 | ||
@@ -1608,9 +1608,11 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec) | |||
1608 | arizona_init_gpio(codec); | 1608 | arizona_init_gpio(codec); |
1609 | arizona_init_mono(codec); | 1609 | arizona_init_mono(codec); |
1610 | 1610 | ||
1611 | ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 8); | 1611 | for (i = 0; i < WM5110_NUM_ADSP; ++i) { |
1612 | if (ret != 0) | 1612 | ret = wm_adsp2_codec_probe(&priv->core.adsp[i], codec); |
1613 | return ret; | 1613 | if (ret) |
1614 | return ret; | ||
1615 | } | ||
1614 | 1616 | ||
1615 | snd_soc_dapm_disable_pin(dapm, "HAPTICS"); | 1617 | snd_soc_dapm_disable_pin(dapm, "HAPTICS"); |
1616 | 1618 | ||
@@ -1620,6 +1622,10 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec) | |||
1620 | static int wm5110_codec_remove(struct snd_soc_codec *codec) | 1622 | static int wm5110_codec_remove(struct snd_soc_codec *codec) |
1621 | { | 1623 | { |
1622 | struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); | 1624 | struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); |
1625 | int i; | ||
1626 | |||
1627 | for (i = 0; i < WM5110_NUM_ADSP; ++i) | ||
1628 | wm_adsp2_codec_remove(&priv->core.adsp[i], codec); | ||
1623 | 1629 | ||
1624 | priv->core.arizona->dapm = NULL; | 1630 | priv->core.arizona->dapm = NULL; |
1625 | 1631 | ||
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index 8c5b9df3e542..43ea8ae5f871 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c | |||
@@ -113,6 +113,15 @@ static struct { | |||
113 | { 7, 1152 }, | 113 | { 7, 1152 }, |
114 | }; | 114 | }; |
115 | 115 | ||
116 | static struct { | ||
117 | int value; | ||
118 | int ratio; | ||
119 | } bclk_ratios[WM8523_NUM_RATES] = { | ||
120 | { 2, 32 }, | ||
121 | { 3, 64 }, | ||
122 | { 4, 128 }, | ||
123 | }; | ||
124 | |||
116 | static int wm8523_startup(struct snd_pcm_substream *substream, | 125 | static int wm8523_startup(struct snd_pcm_substream *substream, |
117 | struct snd_soc_dai *dai) | 126 | struct snd_soc_dai *dai) |
118 | { | 127 | { |
@@ -162,6 +171,23 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream, | |||
162 | aifctrl2 &= ~WM8523_SR_MASK; | 171 | aifctrl2 &= ~WM8523_SR_MASK; |
163 | aifctrl2 |= lrclk_ratios[i].value; | 172 | aifctrl2 |= lrclk_ratios[i].value; |
164 | 173 | ||
174 | if (aifctrl1 & WM8523_AIF_MSTR) { | ||
175 | /* Find a fs->bclk ratio */ | ||
176 | for (i = 0; i < ARRAY_SIZE(bclk_ratios); i++) | ||
177 | if (params_width(params) * 2 <= bclk_ratios[i].ratio) | ||
178 | break; | ||
179 | |||
180 | if (i == ARRAY_SIZE(bclk_ratios)) { | ||
181 | dev_err(codec->dev, | ||
182 | "No matching BCLK/fs ratio for word length %d\n", | ||
183 | params_width(params)); | ||
184 | return -EINVAL; | ||
185 | } | ||
186 | |||
187 | aifctrl2 &= ~WM8523_BCLKDIV_MASK; | ||
188 | aifctrl2 |= bclk_ratios[i].value << WM8523_BCLKDIV_SHIFT; | ||
189 | } | ||
190 | |||
165 | aifctrl1 &= ~WM8523_WL_MASK; | 191 | aifctrl1 &= ~WM8523_WL_MASK; |
166 | switch (params_width(params)) { | 192 | switch (params_width(params)) { |
167 | case 16: | 193 | case 16: |
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 09ff01f2fc1e..b34623786e35 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c | |||
@@ -125,18 +125,6 @@ static const struct snd_soc_dapm_route wm8741_dapm_routes[] = { | |||
125 | { "VOUTRN", NULL, "DACR" }, | 125 | { "VOUTRN", NULL, "DACR" }, |
126 | }; | 126 | }; |
127 | 127 | ||
128 | static struct { | ||
129 | int value; | ||
130 | int ratio; | ||
131 | } lrclk_ratios[WM8741_NUM_RATES] = { | ||
132 | { 1, 128 }, | ||
133 | { 2, 192 }, | ||
134 | { 3, 256 }, | ||
135 | { 4, 384 }, | ||
136 | { 5, 512 }, | ||
137 | { 6, 768 }, | ||
138 | }; | ||
139 | |||
140 | static const unsigned int rates_11289[] = { | 128 | static const unsigned int rates_11289[] = { |
141 | 44100, 88200, | 129 | 44100, 88200, |
142 | }; | 130 | }; |
@@ -209,25 +197,16 @@ static const struct snd_pcm_hw_constraint_list constraints_36864 = { | |||
209 | .list = rates_36864, | 197 | .list = rates_36864, |
210 | }; | 198 | }; |
211 | 199 | ||
212 | |||
213 | static int wm8741_startup(struct snd_pcm_substream *substream, | 200 | static int wm8741_startup(struct snd_pcm_substream *substream, |
214 | struct snd_soc_dai *dai) | 201 | struct snd_soc_dai *dai) |
215 | { | 202 | { |
216 | struct snd_soc_codec *codec = dai->codec; | 203 | struct snd_soc_codec *codec = dai->codec; |
217 | struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); | 204 | struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); |
218 | 205 | ||
219 | /* The set of sample rates that can be supported depends on the | 206 | if (wm8741->sysclk) |
220 | * MCLK supplied to the CODEC - enforce this. | 207 | snd_pcm_hw_constraint_list(substream->runtime, 0, |
221 | */ | 208 | SNDRV_PCM_HW_PARAM_RATE, |
222 | if (!wm8741->sysclk) { | 209 | wm8741->sysclk_constraints); |
223 | dev_err(codec->dev, | ||
224 | "No MCLK configured, call set_sysclk() on init\n"); | ||
225 | return -EINVAL; | ||
226 | } | ||
227 | |||
228 | snd_pcm_hw_constraint_list(substream->runtime, 0, | ||
229 | SNDRV_PCM_HW_PARAM_RATE, | ||
230 | wm8741->sysclk_constraints); | ||
231 | 210 | ||
232 | return 0; | 211 | return 0; |
233 | } | 212 | } |
@@ -241,17 +220,24 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream, | |||
241 | u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC; | 220 | u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC; |
242 | int i; | 221 | int i; |
243 | 222 | ||
244 | /* Find a supported LRCLK ratio */ | 223 | /* The set of sample rates that can be supported depends on the |
245 | for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) { | 224 | * MCLK supplied to the CODEC - enforce this. |
246 | if (wm8741->sysclk / params_rate(params) == | 225 | */ |
247 | lrclk_ratios[i].ratio) | 226 | if (!wm8741->sysclk) { |
227 | dev_err(codec->dev, | ||
228 | "No MCLK configured, call set_sysclk() on init or in hw_params\n"); | ||
229 | return -EINVAL; | ||
230 | } | ||
231 | |||
232 | /* Find a supported LRCLK rate */ | ||
233 | for (i = 0; i < wm8741->sysclk_constraints->count; i++) { | ||
234 | if (wm8741->sysclk_constraints->list[i] == params_rate(params)) | ||
248 | break; | 235 | break; |
249 | } | 236 | } |
250 | 237 | ||
251 | /* Should never happen, should be handled by constraints */ | 238 | if (i == wm8741->sysclk_constraints->count) { |
252 | if (i == ARRAY_SIZE(lrclk_ratios)) { | 239 | dev_err(codec->dev, "LRCLK %d unsupported with MCLK %d\n", |
253 | dev_err(codec->dev, "MCLK/fs ratio %d unsupported\n", | 240 | params_rate(params), wm8741->sysclk); |
254 | wm8741->sysclk / params_rate(params)); | ||
255 | return -EINVAL; | 241 | return -EINVAL; |
256 | } | 242 | } |
257 | 243 | ||
@@ -274,8 +260,8 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream, | |||
274 | return -EINVAL; | 260 | return -EINVAL; |
275 | } | 261 | } |
276 | 262 | ||
277 | dev_dbg(codec->dev, "wm8741_hw_params: bit size param = %d", | 263 | dev_dbg(codec->dev, "wm8741_hw_params: bit size param = %d, rate param = %d", |
278 | params_width(params)); | 264 | params_width(params), params_rate(params)); |
279 | 265 | ||
280 | snd_soc_write(codec, WM8741_FORMAT_CONTROL, iface); | 266 | snd_soc_write(codec, WM8741_FORMAT_CONTROL, iface); |
281 | return 0; | 267 | return 0; |
@@ -290,6 +276,11 @@ static int wm8741_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
290 | dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq); | 276 | dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq); |
291 | 277 | ||
292 | switch (freq) { | 278 | switch (freq) { |
279 | case 0: | ||
280 | wm8741->sysclk_constraints = NULL; | ||
281 | wm8741->sysclk = freq; | ||
282 | return 0; | ||
283 | |||
293 | case 11289600: | 284 | case 11289600: |
294 | wm8741->sysclk_constraints = &constraints_11289; | 285 | wm8741->sysclk_constraints = &constraints_11289; |
295 | wm8741->sysclk = freq; | 286 | wm8741->sysclk = freq; |
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 761418f05d59..94c5c4681ce5 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
@@ -247,7 +247,7 @@ SOC_SINGLE("PCM Playback -6dB Switch", WM8960_DACCTL1, 7, 1, 0), | |||
247 | SOC_ENUM("ADC Polarity", wm8960_enum[0]), | 247 | SOC_ENUM("ADC Polarity", wm8960_enum[0]), |
248 | SOC_SINGLE("ADC High Pass Filter Switch", WM8960_DACCTL1, 0, 1, 0), | 248 | SOC_SINGLE("ADC High Pass Filter Switch", WM8960_DACCTL1, 0, 1, 0), |
249 | 249 | ||
250 | SOC_ENUM("DAC Polarity", wm8960_enum[2]), | 250 | SOC_ENUM("DAC Polarity", wm8960_enum[1]), |
251 | SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0, | 251 | SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0, |
252 | wm8960_get_deemph, wm8960_put_deemph), | 252 | wm8960_get_deemph, wm8960_put_deemph), |
253 | 253 | ||
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index 687c4dd7ec99..505b65f5734f 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c | |||
@@ -1930,7 +1930,7 @@ static int wm8995_set_dai_sysclk(struct snd_soc_dai *dai, | |||
1930 | dai->id + 1, freq); | 1930 | dai->id + 1, freq); |
1931 | break; | 1931 | break; |
1932 | case WM8995_SYSCLK_MCLK2: | 1932 | case WM8995_SYSCLK_MCLK2: |
1933 | wm8995->sysclk[dai->id] = WM8995_SYSCLK_MCLK1; | 1933 | wm8995->sysclk[dai->id] = WM8995_SYSCLK_MCLK2; |
1934 | wm8995->mclk[1] = freq; | 1934 | wm8995->mclk[1] = freq; |
1935 | dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n", | 1935 | dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n", |
1936 | dai->id + 1, freq); | 1936 | dai->id + 1, freq); |
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index b62ffd0c133e..f9f90b0f5db4 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/vmalloc.h> | 24 | #include <linux/vmalloc.h> |
25 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
26 | #include <linux/debugfs.h> | ||
26 | #include <sound/core.h> | 27 | #include <sound/core.h> |
27 | #include <sound/pcm.h> | 28 | #include <sound/pcm.h> |
28 | #include <sound/pcm_params.h> | 29 | #include <sound/pcm_params.h> |
@@ -248,6 +249,175 @@ struct wm_coeff_ctl { | |||
248 | unsigned int flags; | 249 | unsigned int flags; |
249 | }; | 250 | }; |
250 | 251 | ||
252 | #ifdef CONFIG_DEBUG_FS | ||
253 | static void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s) | ||
254 | { | ||
255 | char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); | ||
256 | |||
257 | mutex_lock(&dsp->debugfs_lock); | ||
258 | kfree(dsp->wmfw_file_name); | ||
259 | dsp->wmfw_file_name = tmp; | ||
260 | mutex_unlock(&dsp->debugfs_lock); | ||
261 | } | ||
262 | |||
263 | static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) | ||
264 | { | ||
265 | char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); | ||
266 | |||
267 | mutex_lock(&dsp->debugfs_lock); | ||
268 | kfree(dsp->bin_file_name); | ||
269 | dsp->bin_file_name = tmp; | ||
270 | mutex_unlock(&dsp->debugfs_lock); | ||
271 | } | ||
272 | |||
273 | static void wm_adsp_debugfs_clear(struct wm_adsp *dsp) | ||
274 | { | ||
275 | mutex_lock(&dsp->debugfs_lock); | ||
276 | kfree(dsp->wmfw_file_name); | ||
277 | kfree(dsp->bin_file_name); | ||
278 | dsp->wmfw_file_name = NULL; | ||
279 | dsp->bin_file_name = NULL; | ||
280 | mutex_unlock(&dsp->debugfs_lock); | ||
281 | } | ||
282 | |||
283 | static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file, | ||
284 | char __user *user_buf, | ||
285 | size_t count, loff_t *ppos) | ||
286 | { | ||
287 | struct wm_adsp *dsp = file->private_data; | ||
288 | ssize_t ret; | ||
289 | |||
290 | mutex_lock(&dsp->debugfs_lock); | ||
291 | |||
292 | if (!dsp->wmfw_file_name || !dsp->running) | ||
293 | ret = 0; | ||
294 | else | ||
295 | ret = simple_read_from_buffer(user_buf, count, ppos, | ||
296 | dsp->wmfw_file_name, | ||
297 | strlen(dsp->wmfw_file_name)); | ||
298 | |||
299 | mutex_unlock(&dsp->debugfs_lock); | ||
300 | return ret; | ||
301 | } | ||
302 | |||
303 | static ssize_t wm_adsp_debugfs_bin_read(struct file *file, | ||
304 | char __user *user_buf, | ||
305 | size_t count, loff_t *ppos) | ||
306 | { | ||
307 | struct wm_adsp *dsp = file->private_data; | ||
308 | ssize_t ret; | ||
309 | |||
310 | mutex_lock(&dsp->debugfs_lock); | ||
311 | |||
312 | if (!dsp->bin_file_name || !dsp->running) | ||
313 | ret = 0; | ||
314 | else | ||
315 | ret = simple_read_from_buffer(user_buf, count, ppos, | ||
316 | dsp->bin_file_name, | ||
317 | strlen(dsp->bin_file_name)); | ||
318 | |||
319 | mutex_unlock(&dsp->debugfs_lock); | ||
320 | return ret; | ||
321 | } | ||
322 | |||
323 | static const struct { | ||
324 | const char *name; | ||
325 | const struct file_operations fops; | ||
326 | } wm_adsp_debugfs_fops[] = { | ||
327 | { | ||
328 | .name = "wmfw_file_name", | ||
329 | .fops = { | ||
330 | .open = simple_open, | ||
331 | .read = wm_adsp_debugfs_wmfw_read, | ||
332 | }, | ||
333 | }, | ||
334 | { | ||
335 | .name = "bin_file_name", | ||
336 | .fops = { | ||
337 | .open = simple_open, | ||
338 | .read = wm_adsp_debugfs_bin_read, | ||
339 | }, | ||
340 | }, | ||
341 | }; | ||
342 | |||
343 | static void wm_adsp2_init_debugfs(struct wm_adsp *dsp, | ||
344 | struct snd_soc_codec *codec) | ||
345 | { | ||
346 | struct dentry *root = NULL; | ||
347 | char *root_name; | ||
348 | int i; | ||
349 | |||
350 | if (!codec->component.debugfs_root) { | ||
351 | adsp_err(dsp, "No codec debugfs root\n"); | ||
352 | goto err; | ||
353 | } | ||
354 | |||
355 | root_name = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
356 | if (!root_name) | ||
357 | goto err; | ||
358 | |||
359 | snprintf(root_name, PAGE_SIZE, "dsp%d", dsp->num); | ||
360 | root = debugfs_create_dir(root_name, codec->component.debugfs_root); | ||
361 | kfree(root_name); | ||
362 | |||
363 | if (!root) | ||
364 | goto err; | ||
365 | |||
366 | if (!debugfs_create_bool("running", S_IRUGO, root, &dsp->running)) | ||
367 | goto err; | ||
368 | |||
369 | if (!debugfs_create_x32("fw_id", S_IRUGO, root, &dsp->fw_id)) | ||
370 | goto err; | ||
371 | |||
372 | if (!debugfs_create_x32("fw_version", S_IRUGO, root, | ||
373 | &dsp->fw_id_version)) | ||
374 | goto err; | ||
375 | |||
376 | for (i = 0; i < ARRAY_SIZE(wm_adsp_debugfs_fops); ++i) { | ||
377 | if (!debugfs_create_file(wm_adsp_debugfs_fops[i].name, | ||
378 | S_IRUGO, root, dsp, | ||
379 | &wm_adsp_debugfs_fops[i].fops)) | ||
380 | goto err; | ||
381 | } | ||
382 | |||
383 | dsp->debugfs_root = root; | ||
384 | return; | ||
385 | |||
386 | err: | ||
387 | debugfs_remove_recursive(root); | ||
388 | adsp_err(dsp, "Failed to create debugfs\n"); | ||
389 | } | ||
390 | |||
391 | static void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp) | ||
392 | { | ||
393 | wm_adsp_debugfs_clear(dsp); | ||
394 | debugfs_remove_recursive(dsp->debugfs_root); | ||
395 | } | ||
396 | #else | ||
397 | static inline void wm_adsp2_init_debugfs(struct wm_adsp *dsp, | ||
398 | struct snd_soc_codec *codec) | ||
399 | { | ||
400 | } | ||
401 | |||
402 | static inline void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp) | ||
403 | { | ||
404 | } | ||
405 | |||
406 | static inline void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, | ||
407 | const char *s) | ||
408 | { | ||
409 | } | ||
410 | |||
411 | static inline void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, | ||
412 | const char *s) | ||
413 | { | ||
414 | } | ||
415 | |||
416 | static inline void wm_adsp_debugfs_clear(struct wm_adsp *dsp) | ||
417 | { | ||
418 | } | ||
419 | #endif | ||
420 | |||
251 | static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, | 421 | static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, |
252 | struct snd_ctl_elem_value *ucontrol) | 422 | struct snd_ctl_elem_value *ucontrol) |
253 | { | 423 | { |
@@ -298,7 +468,6 @@ const struct snd_kcontrol_new wm_adsp1_fw_controls[] = { | |||
298 | }; | 468 | }; |
299 | EXPORT_SYMBOL_GPL(wm_adsp1_fw_controls); | 469 | EXPORT_SYMBOL_GPL(wm_adsp1_fw_controls); |
300 | 470 | ||
301 | #if IS_ENABLED(CONFIG_SND_SOC_ARIZONA) | ||
302 | static const struct soc_enum wm_adsp2_rate_enum[] = { | 471 | static const struct soc_enum wm_adsp2_rate_enum[] = { |
303 | SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1, | 472 | SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1, |
304 | ARIZONA_DSP1_RATE_SHIFT, 0xf, | 473 | ARIZONA_DSP1_RATE_SHIFT, 0xf, |
@@ -318,22 +487,28 @@ static const struct soc_enum wm_adsp2_rate_enum[] = { | |||
318 | arizona_rate_text, arizona_rate_val), | 487 | arizona_rate_text, arizona_rate_val), |
319 | }; | 488 | }; |
320 | 489 | ||
321 | const struct snd_kcontrol_new wm_adsp2_fw_controls[] = { | 490 | static const struct snd_kcontrol_new wm_adsp2_fw_controls[4][2] = { |
322 | SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], | 491 | { |
323 | wm_adsp_fw_get, wm_adsp_fw_put), | 492 | SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], |
324 | SOC_ENUM("DSP1 Rate", wm_adsp2_rate_enum[0]), | 493 | wm_adsp_fw_get, wm_adsp_fw_put), |
325 | SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], | 494 | SOC_ENUM("DSP1 Rate", wm_adsp2_rate_enum[0]), |
326 | wm_adsp_fw_get, wm_adsp_fw_put), | 495 | }, |
327 | SOC_ENUM("DSP2 Rate", wm_adsp2_rate_enum[1]), | 496 | { |
328 | SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], | 497 | SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], |
329 | wm_adsp_fw_get, wm_adsp_fw_put), | 498 | wm_adsp_fw_get, wm_adsp_fw_put), |
330 | SOC_ENUM("DSP3 Rate", wm_adsp2_rate_enum[2]), | 499 | SOC_ENUM("DSP2 Rate", wm_adsp2_rate_enum[1]), |
331 | SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], | 500 | }, |
332 | wm_adsp_fw_get, wm_adsp_fw_put), | 501 | { |
333 | SOC_ENUM("DSP4 Rate", wm_adsp2_rate_enum[3]), | 502 | SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], |
503 | wm_adsp_fw_get, wm_adsp_fw_put), | ||
504 | SOC_ENUM("DSP3 Rate", wm_adsp2_rate_enum[2]), | ||
505 | }, | ||
506 | { | ||
507 | SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], | ||
508 | wm_adsp_fw_get, wm_adsp_fw_put), | ||
509 | SOC_ENUM("DSP4 Rate", wm_adsp2_rate_enum[3]), | ||
510 | }, | ||
334 | }; | 511 | }; |
335 | EXPORT_SYMBOL_GPL(wm_adsp2_fw_controls); | ||
336 | #endif | ||
337 | 512 | ||
338 | static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, | 513 | static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, |
339 | int type) | 514 | int type) |
@@ -1128,6 +1303,8 @@ static int wm_adsp_load(struct wm_adsp *dsp) | |||
1128 | adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", | 1303 | adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", |
1129 | file, regions, pos - firmware->size); | 1304 | file, regions, pos - firmware->size); |
1130 | 1305 | ||
1306 | wm_adsp_debugfs_save_wmfwname(dsp, file); | ||
1307 | |||
1131 | out_fw: | 1308 | out_fw: |
1132 | regmap_async_complete(regmap); | 1309 | regmap_async_complete(regmap); |
1133 | wm_adsp_buf_free(&buf_list); | 1310 | wm_adsp_buf_free(&buf_list); |
@@ -1345,11 +1522,12 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) | |||
1345 | 1522 | ||
1346 | n_algs = be32_to_cpu(adsp2_id.n_algs); | 1523 | n_algs = be32_to_cpu(adsp2_id.n_algs); |
1347 | dsp->fw_id = be32_to_cpu(adsp2_id.fw.id); | 1524 | dsp->fw_id = be32_to_cpu(adsp2_id.fw.id); |
1525 | dsp->fw_id_version = be32_to_cpu(adsp2_id.fw.ver); | ||
1348 | adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", | 1526 | adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", |
1349 | dsp->fw_id, | 1527 | dsp->fw_id, |
1350 | (be32_to_cpu(adsp2_id.fw.ver) & 0xff0000) >> 16, | 1528 | (dsp->fw_id_version & 0xff0000) >> 16, |
1351 | (be32_to_cpu(adsp2_id.fw.ver) & 0xff00) >> 8, | 1529 | (dsp->fw_id_version & 0xff00) >> 8, |
1352 | be32_to_cpu(adsp2_id.fw.ver) & 0xff, | 1530 | dsp->fw_id_version & 0xff, |
1353 | n_algs); | 1531 | n_algs); |
1354 | 1532 | ||
1355 | alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, | 1533 | alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, |
@@ -1625,6 +1803,8 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) | |||
1625 | adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", | 1803 | adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", |
1626 | file, blocks, pos - firmware->size); | 1804 | file, blocks, pos - firmware->size); |
1627 | 1805 | ||
1806 | wm_adsp_debugfs_save_binname(dsp, file); | ||
1807 | |||
1628 | out_fw: | 1808 | out_fw: |
1629 | regmap_async_complete(regmap); | 1809 | regmap_async_complete(regmap); |
1630 | release_firmware(firmware); | 1810 | release_firmware(firmware); |
@@ -1638,6 +1818,9 @@ int wm_adsp1_init(struct wm_adsp *dsp) | |||
1638 | { | 1818 | { |
1639 | INIT_LIST_HEAD(&dsp->alg_regions); | 1819 | INIT_LIST_HEAD(&dsp->alg_regions); |
1640 | 1820 | ||
1821 | #ifdef CONFIG_DEBUG_FS | ||
1822 | mutex_init(&dsp->debugfs_lock); | ||
1823 | #endif | ||
1641 | return 0; | 1824 | return 0; |
1642 | } | 1825 | } |
1643 | EXPORT_SYMBOL_GPL(wm_adsp1_init); | 1826 | EXPORT_SYMBOL_GPL(wm_adsp1_init); |
@@ -1896,6 +2079,10 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, | |||
1896 | /* Log firmware state, it can be useful for analysis */ | 2079 | /* Log firmware state, it can be useful for analysis */ |
1897 | wm_adsp2_show_fw_status(dsp); | 2080 | wm_adsp2_show_fw_status(dsp); |
1898 | 2081 | ||
2082 | wm_adsp_debugfs_clear(dsp); | ||
2083 | |||
2084 | dsp->fw_id = 0; | ||
2085 | dsp->fw_id_version = 0; | ||
1899 | dsp->running = false; | 2086 | dsp->running = false; |
1900 | 2087 | ||
1901 | regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | 2088 | regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, |
@@ -1933,6 +2120,24 @@ err: | |||
1933 | } | 2120 | } |
1934 | EXPORT_SYMBOL_GPL(wm_adsp2_event); | 2121 | EXPORT_SYMBOL_GPL(wm_adsp2_event); |
1935 | 2122 | ||
2123 | int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec) | ||
2124 | { | ||
2125 | wm_adsp2_init_debugfs(dsp, codec); | ||
2126 | |||
2127 | return snd_soc_add_codec_controls(codec, | ||
2128 | wm_adsp2_fw_controls[dsp->num - 1], | ||
2129 | ARRAY_SIZE(wm_adsp2_fw_controls[0])); | ||
2130 | } | ||
2131 | EXPORT_SYMBOL_GPL(wm_adsp2_codec_probe); | ||
2132 | |||
2133 | int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec) | ||
2134 | { | ||
2135 | wm_adsp2_cleanup_debugfs(dsp); | ||
2136 | |||
2137 | return 0; | ||
2138 | } | ||
2139 | EXPORT_SYMBOL_GPL(wm_adsp2_codec_remove); | ||
2140 | |||
1936 | int wm_adsp2_init(struct wm_adsp *dsp) | 2141 | int wm_adsp2_init(struct wm_adsp *dsp) |
1937 | { | 2142 | { |
1938 | int ret; | 2143 | int ret; |
@@ -1952,6 +2157,9 @@ int wm_adsp2_init(struct wm_adsp *dsp) | |||
1952 | INIT_LIST_HEAD(&dsp->ctl_list); | 2157 | INIT_LIST_HEAD(&dsp->ctl_list); |
1953 | INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work); | 2158 | INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work); |
1954 | 2159 | ||
2160 | #ifdef CONFIG_DEBUG_FS | ||
2161 | mutex_init(&dsp->debugfs_lock); | ||
2162 | #endif | ||
1955 | return 0; | 2163 | return 0; |
1956 | } | 2164 | } |
1957 | EXPORT_SYMBOL_GPL(wm_adsp2_init); | 2165 | EXPORT_SYMBOL_GPL(wm_adsp2_init); |
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index 0e5f07c35d50..5042cbd39e54 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h | |||
@@ -46,17 +46,26 @@ struct wm_adsp { | |||
46 | struct list_head alg_regions; | 46 | struct list_head alg_regions; |
47 | 47 | ||
48 | int fw_id; | 48 | int fw_id; |
49 | int fw_id_version; | ||
49 | 50 | ||
50 | const struct wm_adsp_region *mem; | 51 | const struct wm_adsp_region *mem; |
51 | int num_mems; | 52 | int num_mems; |
52 | 53 | ||
53 | int fw; | 54 | int fw; |
54 | int fw_ver; | 55 | int fw_ver; |
55 | bool running; | 56 | u32 running; |
56 | 57 | ||
57 | struct list_head ctl_list; | 58 | struct list_head ctl_list; |
58 | 59 | ||
59 | struct work_struct boot_work; | 60 | struct work_struct boot_work; |
61 | |||
62 | #ifdef CONFIG_DEBUG_FS | ||
63 | struct dentry *debugfs_root; | ||
64 | struct mutex debugfs_lock; | ||
65 | char *wmfw_file_name; | ||
66 | char *bin_file_name; | ||
67 | #endif | ||
68 | |||
60 | }; | 69 | }; |
61 | 70 | ||
62 | #define WM_ADSP1(wname, num) \ | 71 | #define WM_ADSP1(wname, num) \ |
@@ -75,10 +84,11 @@ struct wm_adsp { | |||
75 | WM_ADSP2_E(wname, num, wm_adsp2_early_event) | 84 | WM_ADSP2_E(wname, num, wm_adsp2_early_event) |
76 | 85 | ||
77 | extern const struct snd_kcontrol_new wm_adsp1_fw_controls[]; | 86 | extern const struct snd_kcontrol_new wm_adsp1_fw_controls[]; |
78 | extern const struct snd_kcontrol_new wm_adsp2_fw_controls[]; | ||
79 | 87 | ||
80 | int wm_adsp1_init(struct wm_adsp *dsp); | 88 | int wm_adsp1_init(struct wm_adsp *dsp); |
81 | int wm_adsp2_init(struct wm_adsp *dsp); | 89 | int wm_adsp2_init(struct wm_adsp *dsp); |
90 | int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec); | ||
91 | int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec); | ||
82 | int wm_adsp1_event(struct snd_soc_dapm_widget *w, | 92 | int wm_adsp1_event(struct snd_soc_dapm_widget *w, |
83 | struct snd_kcontrol *kcontrol, int event); | 93 | struct snd_kcontrol *kcontrol, int event); |
84 | int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, | 94 | int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index d79349434a9a..b960e626dad9 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -686,6 +686,8 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, | |||
686 | if (mcasp->serial_dir[i] == TX_MODE && | 686 | if (mcasp->serial_dir[i] == TX_MODE && |
687 | tx_ser < max_active_serializers) { | 687 | tx_ser < max_active_serializers) { |
688 | mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AXR(i)); | 688 | mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AXR(i)); |
689 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i), | ||
690 | DISMOD_LOW, DISMOD_MASK); | ||
689 | tx_ser++; | 691 | tx_ser++; |
690 | } else if (mcasp->serial_dir[i] == RX_MODE && | 692 | } else if (mcasp->serial_dir[i] == RX_MODE && |
691 | rx_ser < max_active_serializers) { | 693 | rx_ser < max_active_serializers) { |
@@ -1565,6 +1567,49 @@ static int davinci_mcasp_init_ch_constraints(struct davinci_mcasp *mcasp) | |||
1565 | return ret; | 1567 | return ret; |
1566 | } | 1568 | } |
1567 | 1569 | ||
1570 | enum { | ||
1571 | PCM_EDMA, | ||
1572 | PCM_SDMA, | ||
1573 | }; | ||
1574 | static const char *sdma_prefix = "ti,omap"; | ||
1575 | |||
1576 | static int davinci_mcasp_get_dma_type(struct davinci_mcasp *mcasp) | ||
1577 | { | ||
1578 | struct dma_chan *chan; | ||
1579 | const char *tmp; | ||
1580 | int ret = PCM_EDMA; | ||
1581 | |||
1582 | if (!mcasp->dev->of_node) | ||
1583 | return PCM_EDMA; | ||
1584 | |||
1585 | tmp = mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data; | ||
1586 | chan = dma_request_slave_channel_reason(mcasp->dev, tmp); | ||
1587 | if (IS_ERR(chan)) { | ||
1588 | if (PTR_ERR(chan) != -EPROBE_DEFER) | ||
1589 | dev_err(mcasp->dev, | ||
1590 | "Can't verify DMA configuration (%ld)\n", | ||
1591 | PTR_ERR(chan)); | ||
1592 | return PTR_ERR(chan); | ||
1593 | } | ||
1594 | BUG_ON(!chan->device || !chan->device->dev); | ||
1595 | |||
1596 | if (chan->device->dev->of_node) | ||
1597 | ret = of_property_read_string(chan->device->dev->of_node, | ||
1598 | "compatible", &tmp); | ||
1599 | else | ||
1600 | dev_dbg(mcasp->dev, "DMA controller has no of-node\n"); | ||
1601 | |||
1602 | dma_release_channel(chan); | ||
1603 | if (ret) | ||
1604 | return ret; | ||
1605 | |||
1606 | dev_dbg(mcasp->dev, "DMA controller compatible = \"%s\"\n", tmp); | ||
1607 | if (!strncmp(tmp, sdma_prefix, strlen(sdma_prefix))) | ||
1608 | return PCM_SDMA; | ||
1609 | |||
1610 | return PCM_EDMA; | ||
1611 | } | ||
1612 | |||
1568 | static int davinci_mcasp_probe(struct platform_device *pdev) | 1613 | static int davinci_mcasp_probe(struct platform_device *pdev) |
1569 | { | 1614 | { |
1570 | struct snd_dmaengine_dai_dma_data *dma_data; | 1615 | struct snd_dmaengine_dai_dma_data *dma_data; |
@@ -1763,27 +1808,34 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1763 | if (ret != 0) | 1808 | if (ret != 0) |
1764 | goto err; | 1809 | goto err; |
1765 | 1810 | ||
1766 | switch (mcasp->version) { | 1811 | ret = davinci_mcasp_get_dma_type(mcasp); |
1812 | switch (ret) { | ||
1813 | case PCM_EDMA: | ||
1767 | #if IS_BUILTIN(CONFIG_SND_EDMA_SOC) || \ | 1814 | #if IS_BUILTIN(CONFIG_SND_EDMA_SOC) || \ |
1768 | (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \ | 1815 | (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \ |
1769 | IS_MODULE(CONFIG_SND_EDMA_SOC)) | 1816 | IS_MODULE(CONFIG_SND_EDMA_SOC)) |
1770 | case MCASP_VERSION_1: | ||
1771 | case MCASP_VERSION_2: | ||
1772 | case MCASP_VERSION_3: | ||
1773 | ret = edma_pcm_platform_register(&pdev->dev); | 1817 | ret = edma_pcm_platform_register(&pdev->dev); |
1774 | break; | 1818 | #else |
1819 | dev_err(&pdev->dev, "Missing SND_EDMA_SOC\n"); | ||
1820 | ret = -EINVAL; | ||
1821 | goto err; | ||
1775 | #endif | 1822 | #endif |
1823 | break; | ||
1824 | case PCM_SDMA: | ||
1776 | #if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \ | 1825 | #if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \ |
1777 | (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \ | 1826 | (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \ |
1778 | IS_MODULE(CONFIG_SND_OMAP_SOC)) | 1827 | IS_MODULE(CONFIG_SND_OMAP_SOC)) |
1779 | case MCASP_VERSION_4: | ||
1780 | ret = omap_pcm_platform_register(&pdev->dev); | 1828 | ret = omap_pcm_platform_register(&pdev->dev); |
1781 | break; | 1829 | #else |
1830 | dev_err(&pdev->dev, "Missing SND_SDMA_SOC\n"); | ||
1831 | ret = -EINVAL; | ||
1832 | goto err; | ||
1782 | #endif | 1833 | #endif |
1834 | break; | ||
1783 | default: | 1835 | default: |
1784 | dev_err(&pdev->dev, "Invalid McASP version: %d\n", | 1836 | dev_err(&pdev->dev, "No DMA controller found (%d)\n", ret); |
1785 | mcasp->version); | 1837 | case -EPROBE_DEFER: |
1786 | ret = -EINVAL; | 1838 | goto err; |
1787 | break; | 1839 | break; |
1788 | } | 1840 | } |
1789 | 1841 | ||
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h index 79dc511180bf..a3be108a8c17 100644 --- a/sound/soc/davinci/davinci-mcasp.h +++ b/sound/soc/davinci/davinci-mcasp.h | |||
@@ -215,7 +215,10 @@ | |||
215 | * DAVINCI_MCASP_XRSRCTL_BASE_REG - Serializer Control Register Bits | 215 | * DAVINCI_MCASP_XRSRCTL_BASE_REG - Serializer Control Register Bits |
216 | */ | 216 | */ |
217 | #define MODE(val) (val) | 217 | #define MODE(val) (val) |
218 | #define DISMOD (val)(val<<2) | 218 | #define DISMOD_3STATE (0x0) |
219 | #define DISMOD_LOW (0x2 << 2) | ||
220 | #define DISMOD_HIGH (0x3 << 2) | ||
221 | #define DISMOD_MASK DISMOD_HIGH | ||
219 | #define TXSTATE BIT(4) | 222 | #define TXSTATE BIT(4) |
220 | #define RXSTATE BIT(5) | 223 | #define RXSTATE BIT(5) |
221 | #define SRMOD_MASK 3 | 224 | #define SRMOD_MASK 3 |
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c index cd146d4fa805..b38b98cae855 100644 --- a/sound/soc/fsl/imx-wm8962.c +++ b/sound/soc/fsl/imx-wm8962.c | |||
@@ -190,7 +190,7 @@ static int imx_wm8962_probe(struct platform_device *pdev) | |||
190 | dev_err(&pdev->dev, "audmux internal port setup failed\n"); | 190 | dev_err(&pdev->dev, "audmux internal port setup failed\n"); |
191 | return ret; | 191 | return ret; |
192 | } | 192 | } |
193 | imx_audmux_v2_configure_port(ext_port, | 193 | ret = imx_audmux_v2_configure_port(ext_port, |
194 | IMX_AUDMUX_V2_PTCR_SYN, | 194 | IMX_AUDMUX_V2_PTCR_SYN, |
195 | IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)); | 195 | IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)); |
196 | if (ret) { | 196 | if (ret) { |
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index c87e58504a62..d5554939146e 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c | |||
@@ -26,6 +26,7 @@ struct simple_card_data { | |||
26 | struct simple_dai_props { | 26 | struct simple_dai_props { |
27 | struct asoc_simple_dai cpu_dai; | 27 | struct asoc_simple_dai cpu_dai; |
28 | struct asoc_simple_dai codec_dai; | 28 | struct asoc_simple_dai codec_dai; |
29 | unsigned int mclk_fs; | ||
29 | } *dai_props; | 30 | } *dai_props; |
30 | unsigned int mclk_fs; | 31 | unsigned int mclk_fs; |
31 | int gpio_hp_det; | 32 | int gpio_hp_det; |
@@ -76,11 +77,18 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream, | |||
76 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 77 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
77 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 78 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
78 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); | 79 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); |
79 | unsigned int mclk; | 80 | struct simple_dai_props *dai_props = |
81 | &priv->dai_props[rtd - rtd->card->rtd]; | ||
82 | unsigned int mclk, mclk_fs = 0; | ||
80 | int ret = 0; | 83 | int ret = 0; |
81 | 84 | ||
82 | if (priv->mclk_fs) { | 85 | if (priv->mclk_fs) |
83 | mclk = params_rate(params) * priv->mclk_fs; | 86 | mclk_fs = priv->mclk_fs; |
87 | else if (dai_props->mclk_fs) | ||
88 | mclk_fs = dai_props->mclk_fs; | ||
89 | |||
90 | if (mclk_fs) { | ||
91 | mclk = params_rate(params) * mclk_fs; | ||
84 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, | 92 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, |
85 | SND_SOC_CLOCK_IN); | 93 | SND_SOC_CLOCK_IN); |
86 | } | 94 | } |
@@ -313,6 +321,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, | |||
313 | char prop[128]; | 321 | char prop[128]; |
314 | char *prefix = ""; | 322 | char *prefix = ""; |
315 | int ret, cpu_args; | 323 | int ret, cpu_args; |
324 | u32 val; | ||
316 | 325 | ||
317 | /* For single DAI link & old style of DT node */ | 326 | /* For single DAI link & old style of DT node */ |
318 | if (is_top_level_node) | 327 | if (is_top_level_node) |
@@ -338,6 +347,9 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, | |||
338 | if (ret < 0) | 347 | if (ret < 0) |
339 | goto dai_link_of_err; | 348 | goto dai_link_of_err; |
340 | 349 | ||
350 | if (!of_property_read_u32(node, "mclk-fs", &val)) | ||
351 | dai_props->mclk_fs = val; | ||
352 | |||
341 | ret = asoc_simple_card_sub_parse_of(cpu, &dai_props->cpu_dai, | 353 | ret = asoc_simple_card_sub_parse_of(cpu, &dai_props->cpu_dai, |
342 | &dai_link->cpu_of_node, | 354 | &dai_link->cpu_of_node, |
343 | &dai_link->cpu_dai_name, | 355 | &dai_link->cpu_dai_name, |
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index 791953ffbc41..f3060a4ca040 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig | |||
@@ -112,7 +112,7 @@ config SND_SOC_INTEL_CHT_BSW_RT5672_MACH | |||
112 | 112 | ||
113 | config SND_SOC_INTEL_CHT_BSW_RT5645_MACH | 113 | config SND_SOC_INTEL_CHT_BSW_RT5645_MACH |
114 | tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645/5650 codec" | 114 | tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645/5650 codec" |
115 | depends on X86_INTEL_LPSS | 115 | depends on X86_INTEL_LPSS && I2C |
116 | select SND_SOC_RT5645 | 116 | select SND_SOC_RT5645 |
117 | select SND_SST_MFLD_PLATFORM | 117 | select SND_SST_MFLD_PLATFORM |
118 | select SND_SST_IPC_ACPI | 118 | select SND_SST_IPC_ACPI |
@@ -123,7 +123,7 @@ config SND_SOC_INTEL_CHT_BSW_RT5645_MACH | |||
123 | 123 | ||
124 | config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH | 124 | config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH |
125 | tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with MAX98090 & TI codec" | 125 | tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with MAX98090 & TI codec" |
126 | depends on X86_INTEL_LPSS | 126 | depends on X86_INTEL_LPSS && I2C |
127 | select SND_SOC_MAX98090 | 127 | select SND_SOC_MAX98090 |
128 | select SND_SOC_TS3A227E | 128 | select SND_SOC_TS3A227E |
129 | select SND_SST_MFLD_PLATFORM | 129 | select SND_SST_MFLD_PLATFORM |
diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c index 61e240935451..31e9b9ecbb8a 100644 --- a/sound/soc/intel/atom/sst-atom-controls.c +++ b/sound/soc/intel/atom/sst-atom-controls.c | |||
@@ -1401,36 +1401,32 @@ static int sst_fill_widget_module_info(struct snd_soc_dapm_widget *w, | |||
1401 | down_read(&card->controls_rwsem); | 1401 | down_read(&card->controls_rwsem); |
1402 | 1402 | ||
1403 | list_for_each_entry(kctl, &card->controls, list) { | 1403 | list_for_each_entry(kctl, &card->controls, list) { |
1404 | idx = strstr(kctl->id.name, " "); | 1404 | idx = strchr(kctl->id.name, ' '); |
1405 | if (idx == NULL) | 1405 | if (idx == NULL) |
1406 | continue; | 1406 | continue; |
1407 | index = strlen(kctl->id.name) - strlen(idx); | 1407 | index = idx - (char*)kctl->id.name; |
1408 | if (strncmp(kctl->id.name, w->name, index)) | ||
1409 | continue; | ||
1408 | 1410 | ||
1409 | if (strstr(kctl->id.name, "Volume") && | 1411 | if (strstr(kctl->id.name, "Volume")) |
1410 | !strncmp(kctl->id.name, w->name, index)) | ||
1411 | ret = sst_fill_module_list(kctl, w, SST_MODULE_GAIN); | 1412 | ret = sst_fill_module_list(kctl, w, SST_MODULE_GAIN); |
1412 | 1413 | ||
1413 | else if (strstr(kctl->id.name, "params") && | 1414 | else if (strstr(kctl->id.name, "params")) |
1414 | !strncmp(kctl->id.name, w->name, index)) | ||
1415 | ret = sst_fill_module_list(kctl, w, SST_MODULE_ALGO); | 1415 | ret = sst_fill_module_list(kctl, w, SST_MODULE_ALGO); |
1416 | 1416 | ||
1417 | else if (strstr(kctl->id.name, "Switch") && | 1417 | else if (strstr(kctl->id.name, "Switch") && |
1418 | !strncmp(kctl->id.name, w->name, index) && | ||
1419 | strstr(kctl->id.name, "Gain")) { | 1418 | strstr(kctl->id.name, "Gain")) { |
1420 | struct sst_gain_mixer_control *mc = | 1419 | struct sst_gain_mixer_control *mc = |
1421 | (void *)kctl->private_value; | 1420 | (void *)kctl->private_value; |
1422 | 1421 | ||
1423 | mc->w = w; | 1422 | mc->w = w; |
1424 | 1423 | ||
1425 | } else if (strstr(kctl->id.name, "interleaver") && | 1424 | } else if (strstr(kctl->id.name, "interleaver")) { |
1426 | !strncmp(kctl->id.name, w->name, index)) { | ||
1427 | struct sst_enum *e = (void *)kctl->private_value; | 1425 | struct sst_enum *e = (void *)kctl->private_value; |
1428 | 1426 | ||
1429 | e->w = w; | 1427 | e->w = w; |
1430 | 1428 | ||
1431 | } else if (strstr(kctl->id.name, "deinterleaver") && | 1429 | } else if (strstr(kctl->id.name, "deinterleaver")) { |
1432 | !strncmp(kctl->id.name, w->name, index)) { | ||
1433 | |||
1434 | struct sst_enum *e = (void *)kctl->private_value; | 1430 | struct sst_enum *e = (void *)kctl->private_value; |
1435 | 1431 | ||
1436 | e->w = w; | 1432 | e->w = w; |
diff --git a/sound/soc/intel/atom/sst/sst.c b/sound/soc/intel/atom/sst/sst.c index 96c2e420cce6..a4b458e77089 100644 --- a/sound/soc/intel/atom/sst/sst.c +++ b/sound/soc/intel/atom/sst/sst.c | |||
@@ -368,8 +368,8 @@ static inline void sst_restore_shim64(struct intel_sst_drv *ctx, | |||
368 | * initialize by FW or driver when firmware is loaded | 368 | * initialize by FW or driver when firmware is loaded |
369 | */ | 369 | */ |
370 | spin_lock_irqsave(&ctx->ipc_spin_lock, irq_flags); | 370 | spin_lock_irqsave(&ctx->ipc_spin_lock, irq_flags); |
371 | sst_shim_write64(shim, SST_IMRX, shim_regs->imrx), | 371 | sst_shim_write64(shim, SST_IMRX, shim_regs->imrx); |
372 | sst_shim_write64(shim, SST_CSR, shim_regs->csr), | 372 | sst_shim_write64(shim, SST_CSR, shim_regs->csr); |
373 | spin_unlock_irqrestore(&ctx->ipc_spin_lock, irq_flags); | 373 | spin_unlock_irqrestore(&ctx->ipc_spin_lock, irq_flags); |
374 | } | 374 | } |
375 | 375 | ||
diff --git a/sound/soc/intel/atom/sst/sst_drv_interface.c b/sound/soc/intel/atom/sst/sst_drv_interface.c index 7b50a9d17ec1..620da1d1b9e3 100644 --- a/sound/soc/intel/atom/sst/sst_drv_interface.c +++ b/sound/soc/intel/atom/sst/sst_drv_interface.c | |||
@@ -533,7 +533,7 @@ static inline int sst_calc_tstamp(struct intel_sst_drv *ctx, | |||
533 | 533 | ||
534 | info->buffer_ptr = pointer_samples / substream->runtime->channels; | 534 | info->buffer_ptr = pointer_samples / substream->runtime->channels; |
535 | 535 | ||
536 | info->pcm_delay = delay_frames / substream->runtime->channels; | 536 | info->pcm_delay = delay_frames; |
537 | dev_dbg(ctx->dev, "buffer ptr %llu pcm_delay rep: %llu\n", | 537 | dev_dbg(ctx->dev, "buffer ptr %llu pcm_delay rep: %llu\n", |
538 | info->buffer_ptr, info->pcm_delay); | 538 | info->buffer_ptr, info->pcm_delay); |
539 | return 0; | 539 | return 0; |
diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c index 1be079423d1e..d604ee80eda4 100644 --- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c +++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c | |||
@@ -101,6 +101,33 @@ static int cht_aif1_hw_params(struct snd_pcm_substream *substream, | |||
101 | return 0; | 101 | return 0; |
102 | } | 102 | } |
103 | 103 | ||
104 | static int cht_ti_jack_event(struct notifier_block *nb, | ||
105 | unsigned long event, void *data) | ||
106 | { | ||
107 | |||
108 | struct snd_soc_jack *jack = (struct snd_soc_jack *)data; | ||
109 | struct snd_soc_dai *codec_dai = jack->card->rtd->codec_dai; | ||
110 | struct snd_soc_codec *codec = codec_dai->codec; | ||
111 | |||
112 | if (event & SND_JACK_MICROPHONE) { | ||
113 | |||
114 | snd_soc_dapm_force_enable_pin(&codec->dapm, "SHDN"); | ||
115 | snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS"); | ||
116 | snd_soc_dapm_sync(&codec->dapm); | ||
117 | } else { | ||
118 | |||
119 | snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS"); | ||
120 | snd_soc_dapm_disable_pin(&codec->dapm, "SHDN"); | ||
121 | snd_soc_dapm_sync(&codec->dapm); | ||
122 | } | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static struct notifier_block cht_jack_nb = { | ||
128 | .notifier_call = cht_ti_jack_event, | ||
129 | }; | ||
130 | |||
104 | static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) | 131 | static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) |
105 | { | 132 | { |
106 | int ret; | 133 | int ret; |
@@ -130,6 +157,9 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) | |||
130 | return ret; | 157 | return ret; |
131 | } | 158 | } |
132 | 159 | ||
160 | if (ctx->ts3a227e_present) | ||
161 | snd_soc_jack_notifier_register(jack, &cht_jack_nb); | ||
162 | |||
133 | return ret; | 163 | return ret; |
134 | } | 164 | } |
135 | 165 | ||
diff --git a/sound/soc/intel/common/sst-acpi.c b/sound/soc/intel/common/sst-acpi.c index 42f293f9c6e2..67b6d3d52f57 100644 --- a/sound/soc/intel/common/sst-acpi.c +++ b/sound/soc/intel/common/sst-acpi.c | |||
@@ -263,7 +263,7 @@ static struct sst_acpi_desc sst_acpi_baytrail_desc = { | |||
263 | .resindex_dma_base = -1, | 263 | .resindex_dma_base = -1, |
264 | }; | 264 | }; |
265 | 265 | ||
266 | static struct acpi_device_id sst_acpi_match[] = { | 266 | static const struct acpi_device_id sst_acpi_match[] = { |
267 | { "INT33C8", (unsigned long)&sst_acpi_haswell_desc }, | 267 | { "INT33C8", (unsigned long)&sst_acpi_haswell_desc }, |
268 | { "INT3438", (unsigned long)&sst_acpi_broadwell_desc }, | 268 | { "INT3438", (unsigned long)&sst_acpi_broadwell_desc }, |
269 | { "80860F28", (unsigned long)&sst_acpi_baytrail_desc }, | 269 | { "80860F28", (unsigned long)&sst_acpi_baytrail_desc }, |
diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig new file mode 100644 index 000000000000..15c04e2eae34 --- /dev/null +++ b/sound/soc/mediatek/Kconfig | |||
@@ -0,0 +1,30 @@ | |||
1 | config SND_SOC_MEDIATEK | ||
2 | tristate "ASoC support for Mediatek chip" | ||
3 | depends on ARCH_MEDIATEK | ||
4 | help | ||
5 | This adds ASoC platform driver support for Mediatek chip | ||
6 | that can be used with other codecs. | ||
7 | Select Y if you have such device. | ||
8 | Ex: MT8173 | ||
9 | |||
10 | config SND_SOC_MT8173_MAX98090 | ||
11 | tristate "ASoC Audio driver for MT8173 with MAX98090 codec" | ||
12 | depends on SND_SOC_MEDIATEK | ||
13 | select SND_SOC_MAX98090 | ||
14 | help | ||
15 | This adds ASoC driver for Mediatek MT8173 boards | ||
16 | with the MAX98090 audio codec. | ||
17 | Select Y if you have such device. | ||
18 | If unsure select "N". | ||
19 | |||
20 | config SND_SOC_MT8173_RT5650_RT5676 | ||
21 | tristate "ASoC Audio driver for MT8173 with RT5650 RT5676 codecs" | ||
22 | depends on SND_SOC_MEDIATEK | ||
23 | select SND_SOC_RT5645 | ||
24 | select SND_SOC_RT5677 | ||
25 | help | ||
26 | This adds ASoC driver for Mediatek MT8173 boards | ||
27 | with the RT5650 and RT5676 codecs. | ||
28 | Select Y if you have such device. | ||
29 | If unsure select "N". | ||
30 | |||
diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile new file mode 100644 index 000000000000..75effbec438d --- /dev/null +++ b/sound/soc/mediatek/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | # MTK Platform Support | ||
2 | obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o | ||
3 | # Machine support | ||
4 | obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o | ||
5 | obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5676) += mt8173-rt5650-rt5676.o | ||
diff --git a/sound/soc/mediatek/mt8173-max98090.c b/sound/soc/mediatek/mt8173-max98090.c new file mode 100644 index 000000000000..4d44b5803e55 --- /dev/null +++ b/sound/soc/mediatek/mt8173-max98090.c | |||
@@ -0,0 +1,213 @@ | |||
1 | /* | ||
2 | * mt8173-max98090.c -- MT8173 MAX98090 ALSA SoC machine driver | ||
3 | * | ||
4 | * Copyright (c) 2015 MediaTek Inc. | ||
5 | * Author: Koro Chen <koro.chen@mediatek.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 and | ||
9 | * only version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <sound/soc.h> | ||
19 | #include <sound/jack.h> | ||
20 | #include <linux/gpio.h> | ||
21 | #include "../codecs/max98090.h" | ||
22 | |||
23 | static struct snd_soc_jack mt8173_max98090_jack; | ||
24 | |||
25 | static struct snd_soc_jack_pin mt8173_max98090_jack_pins[] = { | ||
26 | { | ||
27 | .pin = "Headphone", | ||
28 | .mask = SND_JACK_HEADPHONE, | ||
29 | }, | ||
30 | { | ||
31 | .pin = "Headset Mic", | ||
32 | .mask = SND_JACK_MICROPHONE, | ||
33 | }, | ||
34 | }; | ||
35 | |||
36 | static const struct snd_soc_dapm_widget mt8173_max98090_widgets[] = { | ||
37 | SND_SOC_DAPM_SPK("Speaker", NULL), | ||
38 | SND_SOC_DAPM_MIC("Int Mic", NULL), | ||
39 | SND_SOC_DAPM_HP("Headphone", NULL), | ||
40 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
41 | }; | ||
42 | |||
43 | static const struct snd_soc_dapm_route mt8173_max98090_routes[] = { | ||
44 | {"Speaker", NULL, "SPKL"}, | ||
45 | {"Speaker", NULL, "SPKR"}, | ||
46 | {"DMICL", NULL, "Int Mic"}, | ||
47 | {"Headphone", NULL, "HPL"}, | ||
48 | {"Headphone", NULL, "HPR"}, | ||
49 | {"Headset Mic", NULL, "MICBIAS"}, | ||
50 | {"IN34", NULL, "Headset Mic"}, | ||
51 | }; | ||
52 | |||
53 | static const struct snd_kcontrol_new mt8173_max98090_controls[] = { | ||
54 | SOC_DAPM_PIN_SWITCH("Speaker"), | ||
55 | SOC_DAPM_PIN_SWITCH("Int Mic"), | ||
56 | SOC_DAPM_PIN_SWITCH("Headphone"), | ||
57 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | ||
58 | }; | ||
59 | |||
60 | static int mt8173_max98090_hw_params(struct snd_pcm_substream *substream, | ||
61 | struct snd_pcm_hw_params *params) | ||
62 | { | ||
63 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
64 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
65 | |||
66 | return snd_soc_dai_set_sysclk(codec_dai, 0, params_rate(params) * 256, | ||
67 | SND_SOC_CLOCK_IN); | ||
68 | } | ||
69 | |||
70 | static struct snd_soc_ops mt8173_max98090_ops = { | ||
71 | .hw_params = mt8173_max98090_hw_params, | ||
72 | }; | ||
73 | |||
74 | static int mt8173_max98090_init(struct snd_soc_pcm_runtime *runtime) | ||
75 | { | ||
76 | int ret; | ||
77 | struct snd_soc_card *card = runtime->card; | ||
78 | struct snd_soc_codec *codec = runtime->codec; | ||
79 | |||
80 | /* enable jack detection */ | ||
81 | ret = snd_soc_card_jack_new(card, "Headphone", SND_JACK_HEADPHONE, | ||
82 | &mt8173_max98090_jack, NULL, 0); | ||
83 | if (ret) { | ||
84 | dev_err(card->dev, "Can't snd_soc_jack_new %d\n", ret); | ||
85 | return ret; | ||
86 | } | ||
87 | |||
88 | ret = snd_soc_jack_add_pins(&mt8173_max98090_jack, | ||
89 | ARRAY_SIZE(mt8173_max98090_jack_pins), | ||
90 | mt8173_max98090_jack_pins); | ||
91 | if (ret) { | ||
92 | dev_err(card->dev, "Can't snd_soc_jack_add_pins %d\n", ret); | ||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | return max98090_mic_detect(codec, &mt8173_max98090_jack); | ||
97 | } | ||
98 | |||
99 | /* Digital audio interface glue - connects codec <---> CPU */ | ||
100 | static struct snd_soc_dai_link mt8173_max98090_dais[] = { | ||
101 | /* Front End DAI links */ | ||
102 | { | ||
103 | .name = "MAX98090 Playback", | ||
104 | .stream_name = "MAX98090 Playback", | ||
105 | .cpu_dai_name = "DL1", | ||
106 | .platform_name = "11220000.mt8173-afe-pcm", | ||
107 | .codec_name = "snd-soc-dummy", | ||
108 | .codec_dai_name = "snd-soc-dummy-dai", | ||
109 | .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | ||
110 | .dynamic = 1, | ||
111 | .dpcm_playback = 1, | ||
112 | }, | ||
113 | { | ||
114 | .name = "MAX98090 Capture", | ||
115 | .stream_name = "MAX98090 Capture", | ||
116 | .cpu_dai_name = "VUL", | ||
117 | .platform_name = "11220000.mt8173-afe-pcm", | ||
118 | .codec_name = "snd-soc-dummy", | ||
119 | .codec_dai_name = "snd-soc-dummy-dai", | ||
120 | .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | ||
121 | .dynamic = 1, | ||
122 | .dpcm_capture = 1, | ||
123 | }, | ||
124 | /* Back End DAI links */ | ||
125 | { | ||
126 | .name = "Codec", | ||
127 | .cpu_dai_name = "I2S", | ||
128 | .platform_name = "11220000.mt8173-afe-pcm", | ||
129 | .no_pcm = 1, | ||
130 | .codec_dai_name = "HiFi", | ||
131 | .init = mt8173_max98090_init, | ||
132 | .ops = &mt8173_max98090_ops, | ||
133 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
134 | SND_SOC_DAIFMT_CBS_CFS, | ||
135 | .dpcm_playback = 1, | ||
136 | .dpcm_capture = 1, | ||
137 | }, | ||
138 | }; | ||
139 | |||
140 | static struct snd_soc_card mt8173_max98090_card = { | ||
141 | .name = "mt8173-max98090", | ||
142 | .dai_link = mt8173_max98090_dais, | ||
143 | .num_links = ARRAY_SIZE(mt8173_max98090_dais), | ||
144 | .controls = mt8173_max98090_controls, | ||
145 | .num_controls = ARRAY_SIZE(mt8173_max98090_controls), | ||
146 | .dapm_widgets = mt8173_max98090_widgets, | ||
147 | .num_dapm_widgets = ARRAY_SIZE(mt8173_max98090_widgets), | ||
148 | .dapm_routes = mt8173_max98090_routes, | ||
149 | .num_dapm_routes = ARRAY_SIZE(mt8173_max98090_routes), | ||
150 | }; | ||
151 | |||
152 | static int mt8173_max98090_dev_probe(struct platform_device *pdev) | ||
153 | { | ||
154 | struct snd_soc_card *card = &mt8173_max98090_card; | ||
155 | struct device_node *codec_node; | ||
156 | int ret, i; | ||
157 | |||
158 | codec_node = of_parse_phandle(pdev->dev.of_node, | ||
159 | "mediatek,audio-codec", 0); | ||
160 | if (!codec_node) { | ||
161 | dev_err(&pdev->dev, | ||
162 | "Property 'audio-codec' missing or invalid\n"); | ||
163 | return -EINVAL; | ||
164 | } | ||
165 | for (i = 0; i < card->num_links; i++) { | ||
166 | if (mt8173_max98090_dais[i].codec_name) | ||
167 | continue; | ||
168 | mt8173_max98090_dais[i].codec_of_node = codec_node; | ||
169 | } | ||
170 | card->dev = &pdev->dev; | ||
171 | |||
172 | ret = snd_soc_register_card(card); | ||
173 | if (ret) | ||
174 | dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", | ||
175 | __func__, ret); | ||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | static int mt8173_max98090_dev_remove(struct platform_device *pdev) | ||
180 | { | ||
181 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
182 | |||
183 | snd_soc_unregister_card(card); | ||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static const struct of_device_id mt8173_max98090_dt_match[] = { | ||
188 | { .compatible = "mediatek,mt8173-max98090", }, | ||
189 | { } | ||
190 | }; | ||
191 | MODULE_DEVICE_TABLE(of, mt8173_max98090_dt_match); | ||
192 | |||
193 | static struct platform_driver mt8173_max98090_driver = { | ||
194 | .driver = { | ||
195 | .name = "mt8173-max98090", | ||
196 | .owner = THIS_MODULE, | ||
197 | .of_match_table = mt8173_max98090_dt_match, | ||
198 | #ifdef CONFIG_PM | ||
199 | .pm = &snd_soc_pm_ops, | ||
200 | #endif | ||
201 | }, | ||
202 | .probe = mt8173_max98090_dev_probe, | ||
203 | .remove = mt8173_max98090_dev_remove, | ||
204 | }; | ||
205 | |||
206 | module_platform_driver(mt8173_max98090_driver); | ||
207 | |||
208 | /* Module information */ | ||
209 | MODULE_DESCRIPTION("MT8173 MAX98090 ALSA SoC machine driver"); | ||
210 | MODULE_AUTHOR("Koro Chen <koro.chen@mediatek.com>"); | ||
211 | MODULE_LICENSE("GPL v2"); | ||
212 | MODULE_ALIAS("platform:mt8173-max98090"); | ||
213 | |||
diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173-rt5650-rt5676.c new file mode 100644 index 000000000000..094055323059 --- /dev/null +++ b/sound/soc/mediatek/mt8173-rt5650-rt5676.c | |||
@@ -0,0 +1,278 @@ | |||
1 | /* | ||
2 | * mt8173-rt5650-rt5676.c -- MT8173 machine driver with RT5650/5676 codecs | ||
3 | * | ||
4 | * Copyright (c) 2015 MediaTek Inc. | ||
5 | * Author: Koro Chen <koro.chen@mediatek.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 and | ||
9 | * only version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/of_gpio.h> | ||
20 | #include <sound/soc.h> | ||
21 | #include <sound/jack.h> | ||
22 | #include "../codecs/rt5645.h" | ||
23 | #include "../codecs/rt5677.h" | ||
24 | |||
25 | #define MCLK_FOR_CODECS 12288000 | ||
26 | |||
27 | static const struct snd_soc_dapm_widget mt8173_rt5650_rt5676_widgets[] = { | ||
28 | SND_SOC_DAPM_SPK("Speaker", NULL), | ||
29 | SND_SOC_DAPM_MIC("Int Mic", NULL), | ||
30 | SND_SOC_DAPM_HP("Headphone", NULL), | ||
31 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
32 | }; | ||
33 | |||
34 | static const struct snd_soc_dapm_route mt8173_rt5650_rt5676_routes[] = { | ||
35 | {"Speaker", NULL, "SPOL"}, | ||
36 | {"Speaker", NULL, "SPOR"}, | ||
37 | {"Speaker", NULL, "Sub AIF2TX"}, /* IF2 ADC to 5650 */ | ||
38 | {"Sub DMIC L1", NULL, "Int Mic"}, /* DMIC from 5676 */ | ||
39 | {"Sub DMIC R1", NULL, "Int Mic"}, | ||
40 | {"Headphone", NULL, "HPOL"}, | ||
41 | {"Headphone", NULL, "HPOR"}, | ||
42 | {"Headphone", NULL, "Sub AIF2TX"}, /* IF2 ADC to 5650 */ | ||
43 | {"Headset Mic", NULL, "micbias1"}, | ||
44 | {"Headset Mic", NULL, "micbias2"}, | ||
45 | {"IN1P", NULL, "Headset Mic"}, | ||
46 | {"IN1N", NULL, "Headset Mic"}, | ||
47 | {"Sub AIF2RX", NULL, "Headset Mic"}, /* IF2 DAC from 5650 */ | ||
48 | }; | ||
49 | |||
50 | static const struct snd_kcontrol_new mt8173_rt5650_rt5676_controls[] = { | ||
51 | SOC_DAPM_PIN_SWITCH("Speaker"), | ||
52 | SOC_DAPM_PIN_SWITCH("Int Mic"), | ||
53 | SOC_DAPM_PIN_SWITCH("Headphone"), | ||
54 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | ||
55 | }; | ||
56 | |||
57 | static int mt8173_rt5650_rt5676_hw_params(struct snd_pcm_substream *substream, | ||
58 | struct snd_pcm_hw_params *params) | ||
59 | { | ||
60 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
61 | int i, ret; | ||
62 | |||
63 | for (i = 0; i < rtd->num_codecs; i++) { | ||
64 | struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; | ||
65 | |||
66 | /* pll from mclk 12.288M */ | ||
67 | ret = snd_soc_dai_set_pll(codec_dai, 0, 0, MCLK_FOR_CODECS, | ||
68 | params_rate(params) * 512); | ||
69 | if (ret) | ||
70 | return ret; | ||
71 | |||
72 | /* sysclk from pll */ | ||
73 | ret = snd_soc_dai_set_sysclk(codec_dai, 1, | ||
74 | params_rate(params) * 512, | ||
75 | SND_SOC_CLOCK_IN); | ||
76 | if (ret) | ||
77 | return ret; | ||
78 | } | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static struct snd_soc_ops mt8173_rt5650_rt5676_ops = { | ||
83 | .hw_params = mt8173_rt5650_rt5676_hw_params, | ||
84 | }; | ||
85 | |||
86 | static struct snd_soc_jack mt8173_rt5650_rt5676_jack; | ||
87 | |||
88 | static int mt8173_rt5650_rt5676_init(struct snd_soc_pcm_runtime *runtime) | ||
89 | { | ||
90 | struct snd_soc_card *card = runtime->card; | ||
91 | struct snd_soc_codec *codec = runtime->codec_dais[0]->codec; | ||
92 | struct snd_soc_codec *codec_sub = runtime->codec_dais[1]->codec; | ||
93 | int ret; | ||
94 | |||
95 | rt5645_sel_asrc_clk_src(codec, | ||
96 | RT5645_DA_STEREO_FILTER | | ||
97 | RT5645_AD_STEREO_FILTER, | ||
98 | RT5645_CLK_SEL_I2S1_ASRC); | ||
99 | rt5677_sel_asrc_clk_src(codec_sub, | ||
100 | RT5677_DA_STEREO_FILTER | | ||
101 | RT5677_AD_STEREO1_FILTER, | ||
102 | RT5677_CLK_SEL_I2S1_ASRC); | ||
103 | rt5677_sel_asrc_clk_src(codec_sub, | ||
104 | RT5677_AD_STEREO2_FILTER | | ||
105 | RT5677_I2S2_SOURCE, | ||
106 | RT5677_CLK_SEL_I2S2_ASRC); | ||
107 | |||
108 | /* enable jack detection */ | ||
109 | ret = snd_soc_card_jack_new(card, "Headset Jack", | ||
110 | SND_JACK_HEADPHONE | SND_JACK_MICROPHONE | | ||
111 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | | ||
112 | SND_JACK_BTN_2 | SND_JACK_BTN_3, | ||
113 | &mt8173_rt5650_rt5676_jack, NULL, 0); | ||
114 | if (ret) { | ||
115 | dev_err(card->dev, "Can't new Headset Jack %d\n", ret); | ||
116 | return ret; | ||
117 | } | ||
118 | |||
119 | return rt5645_set_jack_detect(codec, | ||
120 | &mt8173_rt5650_rt5676_jack, | ||
121 | &mt8173_rt5650_rt5676_jack, | ||
122 | &mt8173_rt5650_rt5676_jack); | ||
123 | } | ||
124 | |||
125 | static struct snd_soc_dai_link_component mt8173_rt5650_rt5676_codecs[] = { | ||
126 | { | ||
127 | .dai_name = "rt5645-aif1", | ||
128 | }, | ||
129 | { | ||
130 | .dai_name = "rt5677-aif1", | ||
131 | }, | ||
132 | }; | ||
133 | |||
134 | /* Digital audio interface glue - connects codec <---> CPU */ | ||
135 | static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = { | ||
136 | /* Front End DAI links */ | ||
137 | { | ||
138 | .name = "rt5650_rt5676 Playback", | ||
139 | .stream_name = "rt5650_rt5676 Playback", | ||
140 | .cpu_dai_name = "DL1", | ||
141 | .platform_name = "11220000.mt8173-afe-pcm", | ||
142 | .codec_name = "snd-soc-dummy", | ||
143 | .codec_dai_name = "snd-soc-dummy-dai", | ||
144 | .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | ||
145 | .dynamic = 1, | ||
146 | .dpcm_playback = 1, | ||
147 | }, | ||
148 | { | ||
149 | .name = "rt5650_rt5676 Capture", | ||
150 | .stream_name = "rt5650_rt5676 Capture", | ||
151 | .cpu_dai_name = "VUL", | ||
152 | .platform_name = "11220000.mt8173-afe-pcm", | ||
153 | .codec_name = "snd-soc-dummy", | ||
154 | .codec_dai_name = "snd-soc-dummy-dai", | ||
155 | .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | ||
156 | .dynamic = 1, | ||
157 | .dpcm_capture = 1, | ||
158 | }, | ||
159 | |||
160 | /* Back End DAI links */ | ||
161 | { | ||
162 | .name = "Codec", | ||
163 | .cpu_dai_name = "I2S", | ||
164 | .platform_name = "11220000.mt8173-afe-pcm", | ||
165 | .no_pcm = 1, | ||
166 | .codecs = mt8173_rt5650_rt5676_codecs, | ||
167 | .num_codecs = 2, | ||
168 | .init = mt8173_rt5650_rt5676_init, | ||
169 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
170 | SND_SOC_DAIFMT_CBS_CFS, | ||
171 | .ops = &mt8173_rt5650_rt5676_ops, | ||
172 | .ignore_pmdown_time = 1, | ||
173 | .dpcm_playback = 1, | ||
174 | .dpcm_capture = 1, | ||
175 | }, | ||
176 | { /* rt5676 <-> rt5650 intercodec link: Sets rt5676 I2S2 as master */ | ||
177 | .name = "rt5650_rt5676 intercodec", | ||
178 | .stream_name = "rt5650_rt5676 intercodec", | ||
179 | .cpu_dai_name = "snd-soc-dummy-dai", | ||
180 | .platform_name = "snd-soc-dummy", | ||
181 | .no_pcm = 1, | ||
182 | .codec_dai_name = "rt5677-aif2", | ||
183 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
184 | SND_SOC_DAIFMT_CBM_CFM, | ||
185 | }, | ||
186 | |||
187 | }; | ||
188 | |||
189 | static struct snd_soc_codec_conf mt8173_rt5650_rt5676_codec_conf[] = { | ||
190 | { | ||
191 | .name_prefix = "Sub", | ||
192 | }, | ||
193 | }; | ||
194 | |||
195 | static struct snd_soc_card mt8173_rt5650_rt5676_card = { | ||
196 | .name = "mtk-rt5650-rt5676", | ||
197 | .dai_link = mt8173_rt5650_rt5676_dais, | ||
198 | .num_links = ARRAY_SIZE(mt8173_rt5650_rt5676_dais), | ||
199 | .codec_conf = mt8173_rt5650_rt5676_codec_conf, | ||
200 | .num_configs = ARRAY_SIZE(mt8173_rt5650_rt5676_codec_conf), | ||
201 | .controls = mt8173_rt5650_rt5676_controls, | ||
202 | .num_controls = ARRAY_SIZE(mt8173_rt5650_rt5676_controls), | ||
203 | .dapm_widgets = mt8173_rt5650_rt5676_widgets, | ||
204 | .num_dapm_widgets = ARRAY_SIZE(mt8173_rt5650_rt5676_widgets), | ||
205 | .dapm_routes = mt8173_rt5650_rt5676_routes, | ||
206 | .num_dapm_routes = ARRAY_SIZE(mt8173_rt5650_rt5676_routes), | ||
207 | }; | ||
208 | |||
209 | static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev) | ||
210 | { | ||
211 | struct snd_soc_card *card = &mt8173_rt5650_rt5676_card; | ||
212 | int ret; | ||
213 | |||
214 | mt8173_rt5650_rt5676_codecs[0].of_node = | ||
215 | of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 0); | ||
216 | if (!mt8173_rt5650_rt5676_codecs[0].of_node) { | ||
217 | dev_err(&pdev->dev, | ||
218 | "Property 'audio-codec' missing or invalid\n"); | ||
219 | return -EINVAL; | ||
220 | } | ||
221 | mt8173_rt5650_rt5676_codecs[1].of_node = | ||
222 | of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 1); | ||
223 | if (!mt8173_rt5650_rt5676_codecs[1].of_node) { | ||
224 | dev_err(&pdev->dev, | ||
225 | "Property 'audio-codec' missing or invalid\n"); | ||
226 | return -EINVAL; | ||
227 | } | ||
228 | mt8173_rt5650_rt5676_codec_conf[0].of_node = | ||
229 | mt8173_rt5650_rt5676_codecs[1].of_node; | ||
230 | |||
231 | mt8173_rt5650_rt5676_dais[3].codec_of_node = | ||
232 | mt8173_rt5650_rt5676_codecs[1].of_node; | ||
233 | |||
234 | card->dev = &pdev->dev; | ||
235 | platform_set_drvdata(pdev, card); | ||
236 | |||
237 | ret = snd_soc_register_card(card); | ||
238 | if (ret) | ||
239 | dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", | ||
240 | __func__, ret); | ||
241 | return ret; | ||
242 | } | ||
243 | |||
244 | static int mt8173_rt5650_rt5676_dev_remove(struct platform_device *pdev) | ||
245 | { | ||
246 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
247 | |||
248 | snd_soc_unregister_card(card); | ||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | static const struct of_device_id mt8173_rt5650_rt5676_dt_match[] = { | ||
253 | { .compatible = "mediatek,mt8173-rt5650-rt5676", }, | ||
254 | { } | ||
255 | }; | ||
256 | MODULE_DEVICE_TABLE(of, mt8173_rt5650_rt5676_dt_match); | ||
257 | |||
258 | static struct platform_driver mt8173_rt5650_rt5676_driver = { | ||
259 | .driver = { | ||
260 | .name = "mtk-rt5650-rt5676", | ||
261 | .owner = THIS_MODULE, | ||
262 | .of_match_table = mt8173_rt5650_rt5676_dt_match, | ||
263 | #ifdef CONFIG_PM | ||
264 | .pm = &snd_soc_pm_ops, | ||
265 | #endif | ||
266 | }, | ||
267 | .probe = mt8173_rt5650_rt5676_dev_probe, | ||
268 | .remove = mt8173_rt5650_rt5676_dev_remove, | ||
269 | }; | ||
270 | |||
271 | module_platform_driver(mt8173_rt5650_rt5676_driver); | ||
272 | |||
273 | /* Module information */ | ||
274 | MODULE_DESCRIPTION("MT8173 RT5650 and RT5676 SoC machine driver"); | ||
275 | MODULE_AUTHOR("Koro Chen <koro.chen@mediatek.com>"); | ||
276 | MODULE_LICENSE("GPL v2"); | ||
277 | MODULE_ALIAS("platform:mtk-rt5650-rt5676"); | ||
278 | |||
diff --git a/sound/soc/mediatek/mtk-afe-common.h b/sound/soc/mediatek/mtk-afe-common.h new file mode 100644 index 000000000000..a88b17511fdf --- /dev/null +++ b/sound/soc/mediatek/mtk-afe-common.h | |||
@@ -0,0 +1,109 @@ | |||
1 | /* | ||
2 | * mtk_afe_common.h -- Mediatek audio driver common definitions | ||
3 | * | ||
4 | * Copyright (c) 2015 MediaTek Inc. | ||
5 | * Author: Koro Chen <koro.chen@mediatek.com> | ||
6 | * Sascha Hauer <s.hauer@pengutronix.de> | ||
7 | * Hidalgo Huang <hidalgo.huang@mediatek.com> | ||
8 | * Ir Lian <ir.lian@mediatek.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 and | ||
12 | * only version 2 as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | #ifndef _MTK_AFE_COMMON_H_ | ||
21 | #define _MTK_AFE_COMMON_H_ | ||
22 | |||
23 | #include <linux/clk.h> | ||
24 | #include <linux/regmap.h> | ||
25 | |||
26 | enum { | ||
27 | MTK_AFE_MEMIF_DL1, | ||
28 | MTK_AFE_MEMIF_DL2, | ||
29 | MTK_AFE_MEMIF_VUL, | ||
30 | MTK_AFE_MEMIF_DAI, | ||
31 | MTK_AFE_MEMIF_AWB, | ||
32 | MTK_AFE_MEMIF_MOD_DAI, | ||
33 | MTK_AFE_MEMIF_HDMI, | ||
34 | MTK_AFE_MEMIF_NUM, | ||
35 | MTK_AFE_IO_MOD_PCM1 = MTK_AFE_MEMIF_NUM, | ||
36 | MTK_AFE_IO_MOD_PCM2, | ||
37 | MTK_AFE_IO_PMIC, | ||
38 | MTK_AFE_IO_I2S, | ||
39 | MTK_AFE_IO_2ND_I2S, | ||
40 | MTK_AFE_IO_HW_GAIN1, | ||
41 | MTK_AFE_IO_HW_GAIN2, | ||
42 | MTK_AFE_IO_MRG_O, | ||
43 | MTK_AFE_IO_MRG_I, | ||
44 | MTK_AFE_IO_DAIBT, | ||
45 | MTK_AFE_IO_HDMI, | ||
46 | }; | ||
47 | |||
48 | enum { | ||
49 | MTK_AFE_IRQ_1, | ||
50 | MTK_AFE_IRQ_2, | ||
51 | MTK_AFE_IRQ_3, | ||
52 | MTK_AFE_IRQ_4, | ||
53 | MTK_AFE_IRQ_5, | ||
54 | MTK_AFE_IRQ_6, | ||
55 | MTK_AFE_IRQ_7, | ||
56 | MTK_AFE_IRQ_8, | ||
57 | MTK_AFE_IRQ_NUM, | ||
58 | }; | ||
59 | |||
60 | enum { | ||
61 | MTK_CLK_INFRASYS_AUD, | ||
62 | MTK_CLK_TOP_PDN_AUD, | ||
63 | MTK_CLK_TOP_PDN_AUD_BUS, | ||
64 | MTK_CLK_I2S0_M, | ||
65 | MTK_CLK_I2S1_M, | ||
66 | MTK_CLK_I2S2_M, | ||
67 | MTK_CLK_I2S3_M, | ||
68 | MTK_CLK_I2S3_B, | ||
69 | MTK_CLK_BCK0, | ||
70 | MTK_CLK_BCK1, | ||
71 | MTK_CLK_NUM | ||
72 | }; | ||
73 | |||
74 | struct mtk_afe; | ||
75 | struct snd_pcm_substream; | ||
76 | |||
77 | struct mtk_afe_memif_data { | ||
78 | int id; | ||
79 | const char *name; | ||
80 | int reg_ofs_base; | ||
81 | int reg_ofs_cur; | ||
82 | int fs_shift; | ||
83 | int mono_shift; | ||
84 | int enable_shift; | ||
85 | int irq_reg_cnt; | ||
86 | int irq_cnt_shift; | ||
87 | int irq_en_shift; | ||
88 | int irq_fs_shift; | ||
89 | int irq_clr_shift; | ||
90 | }; | ||
91 | |||
92 | struct mtk_afe_memif { | ||
93 | unsigned int phys_buf_addr; | ||
94 | int buffer_size; | ||
95 | unsigned int hw_ptr; /* Previous IRQ's HW ptr */ | ||
96 | struct snd_pcm_substream *substream; | ||
97 | const struct mtk_afe_memif_data *data; | ||
98 | const struct mtk_afe_irq_data *irqdata; | ||
99 | }; | ||
100 | |||
101 | struct mtk_afe { | ||
102 | /* address for ioremap audio hardware register */ | ||
103 | void __iomem *base_addr; | ||
104 | struct device *dev; | ||
105 | struct regmap *regmap; | ||
106 | struct mtk_afe_memif memif[MTK_AFE_MEMIF_NUM]; | ||
107 | struct clk *clocks[MTK_CLK_NUM]; | ||
108 | }; | ||
109 | #endif | ||
diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c new file mode 100644 index 000000000000..cc228db5fb76 --- /dev/null +++ b/sound/soc/mediatek/mtk-afe-pcm.c | |||
@@ -0,0 +1,1233 @@ | |||
1 | /* | ||
2 | * Mediatek ALSA SoC AFE platform driver | ||
3 | * | ||
4 | * Copyright (c) 2015 MediaTek Inc. | ||
5 | * Author: Koro Chen <koro.chen@mediatek.com> | ||
6 | * Sascha Hauer <s.hauer@pengutronix.de> | ||
7 | * Hidalgo Huang <hidalgo.huang@mediatek.com> | ||
8 | * Ir Lian <ir.lian@mediatek.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 and | ||
12 | * only version 2 as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | #include <linux/delay.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/of_address.h> | ||
24 | #include <linux/pm_runtime.h> | ||
25 | #include <sound/soc.h> | ||
26 | #include "mtk-afe-common.h" | ||
27 | |||
28 | /***************************************************************************** | ||
29 | * R E G I S T E R D E F I N I T I O N | ||
30 | *****************************************************************************/ | ||
31 | #define AUDIO_TOP_CON0 0x0000 | ||
32 | #define AUDIO_TOP_CON1 0x0004 | ||
33 | #define AFE_DAC_CON0 0x0010 | ||
34 | #define AFE_DAC_CON1 0x0014 | ||
35 | #define AFE_I2S_CON1 0x0034 | ||
36 | #define AFE_I2S_CON2 0x0038 | ||
37 | #define AFE_CONN_24BIT 0x006c | ||
38 | |||
39 | #define AFE_CONN1 0x0024 | ||
40 | #define AFE_CONN2 0x0028 | ||
41 | #define AFE_CONN7 0x0460 | ||
42 | #define AFE_CONN8 0x0464 | ||
43 | #define AFE_HDMI_CONN0 0x0390 | ||
44 | |||
45 | /* Memory interface */ | ||
46 | #define AFE_DL1_BASE 0x0040 | ||
47 | #define AFE_DL1_CUR 0x0044 | ||
48 | #define AFE_DL2_BASE 0x0050 | ||
49 | #define AFE_DL2_CUR 0x0054 | ||
50 | #define AFE_AWB_BASE 0x0070 | ||
51 | #define AFE_AWB_CUR 0x007c | ||
52 | #define AFE_VUL_BASE 0x0080 | ||
53 | #define AFE_VUL_CUR 0x008c | ||
54 | #define AFE_DAI_BASE 0x0090 | ||
55 | #define AFE_DAI_CUR 0x009c | ||
56 | #define AFE_MOD_PCM_BASE 0x0330 | ||
57 | #define AFE_MOD_PCM_CUR 0x033c | ||
58 | #define AFE_HDMI_OUT_BASE 0x0374 | ||
59 | #define AFE_HDMI_OUT_CUR 0x0378 | ||
60 | |||
61 | #define AFE_ADDA2_TOP_CON0 0x0600 | ||
62 | |||
63 | #define AFE_HDMI_OUT_CON0 0x0370 | ||
64 | |||
65 | #define AFE_IRQ_MCU_CON 0x03a0 | ||
66 | #define AFE_IRQ_STATUS 0x03a4 | ||
67 | #define AFE_IRQ_CLR 0x03a8 | ||
68 | #define AFE_IRQ_CNT1 0x03ac | ||
69 | #define AFE_IRQ_CNT2 0x03b0 | ||
70 | #define AFE_IRQ_MCU_EN 0x03b4 | ||
71 | #define AFE_IRQ_CNT5 0x03bc | ||
72 | #define AFE_IRQ_CNT7 0x03dc | ||
73 | |||
74 | #define AFE_TDM_CON1 0x0548 | ||
75 | #define AFE_TDM_CON2 0x054c | ||
76 | |||
77 | #define AFE_BASE_END_OFFSET 8 | ||
78 | #define AFE_IRQ_STATUS_BITS 0xff | ||
79 | |||
80 | /* AUDIO_TOP_CON0 (0x0000) */ | ||
81 | #define AUD_TCON0_PDN_SPDF (0x1 << 21) | ||
82 | #define AUD_TCON0_PDN_HDMI (0x1 << 20) | ||
83 | #define AUD_TCON0_PDN_24M (0x1 << 9) | ||
84 | #define AUD_TCON0_PDN_22M (0x1 << 8) | ||
85 | #define AUD_TCON0_PDN_AFE (0x1 << 2) | ||
86 | |||
87 | /* AFE_I2S_CON1 (0x0034) */ | ||
88 | #define AFE_I2S_CON1_LOW_JITTER_CLK (0x1 << 12) | ||
89 | #define AFE_I2S_CON1_RATE(x) (((x) & 0xf) << 8) | ||
90 | #define AFE_I2S_CON1_FORMAT_I2S (0x1 << 3) | ||
91 | #define AFE_I2S_CON1_EN (0x1 << 0) | ||
92 | |||
93 | /* AFE_I2S_CON2 (0x0038) */ | ||
94 | #define AFE_I2S_CON2_LOW_JITTER_CLK (0x1 << 12) | ||
95 | #define AFE_I2S_CON2_RATE(x) (((x) & 0xf) << 8) | ||
96 | #define AFE_I2S_CON2_FORMAT_I2S (0x1 << 3) | ||
97 | #define AFE_I2S_CON2_EN (0x1 << 0) | ||
98 | |||
99 | /* AFE_CONN_24BIT (0x006c) */ | ||
100 | #define AFE_CONN_24BIT_O04 (0x1 << 4) | ||
101 | #define AFE_CONN_24BIT_O03 (0x1 << 3) | ||
102 | |||
103 | /* AFE_HDMI_CONN0 (0x0390) */ | ||
104 | #define AFE_HDMI_CONN0_O37_I37 (0x7 << 21) | ||
105 | #define AFE_HDMI_CONN0_O36_I36 (0x6 << 18) | ||
106 | #define AFE_HDMI_CONN0_O35_I33 (0x3 << 15) | ||
107 | #define AFE_HDMI_CONN0_O34_I32 (0x2 << 12) | ||
108 | #define AFE_HDMI_CONN0_O33_I35 (0x5 << 9) | ||
109 | #define AFE_HDMI_CONN0_O32_I34 (0x4 << 6) | ||
110 | #define AFE_HDMI_CONN0_O31_I31 (0x1 << 3) | ||
111 | #define AFE_HDMI_CONN0_O30_I30 (0x0 << 0) | ||
112 | |||
113 | /* AFE_TDM_CON1 (0x0548) */ | ||
114 | #define AFE_TDM_CON1_LRCK_WIDTH(x) (((x) - 1) << 24) | ||
115 | #define AFE_TDM_CON1_32_BCK_CYCLES (0x2 << 12) | ||
116 | #define AFE_TDM_CON1_WLEN_32BIT (0x2 << 8) | ||
117 | #define AFE_TDM_CON1_MSB_ALIGNED (0x1 << 4) | ||
118 | #define AFE_TDM_CON1_1_BCK_DELAY (0x1 << 3) | ||
119 | #define AFE_TDM_CON1_BCK_INV (0x1 << 1) | ||
120 | #define AFE_TDM_CON1_EN (0x1 << 0) | ||
121 | |||
122 | enum afe_tdm_ch_start { | ||
123 | AFE_TDM_CH_START_O30_O31 = 0, | ||
124 | AFE_TDM_CH_START_O32_O33, | ||
125 | AFE_TDM_CH_START_O34_O35, | ||
126 | AFE_TDM_CH_START_O36_O37, | ||
127 | AFE_TDM_CH_ZERO, | ||
128 | }; | ||
129 | |||
130 | static const struct snd_pcm_hardware mtk_afe_hardware = { | ||
131 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | ||
132 | SNDRV_PCM_INFO_MMAP_VALID), | ||
133 | .buffer_bytes_max = 256 * 1024, | ||
134 | .period_bytes_min = 512, | ||
135 | .period_bytes_max = 128 * 1024, | ||
136 | .periods_min = 2, | ||
137 | .periods_max = 256, | ||
138 | .fifo_size = 0, | ||
139 | }; | ||
140 | |||
141 | static snd_pcm_uframes_t mtk_afe_pcm_pointer | ||
142 | (struct snd_pcm_substream *substream) | ||
143 | { | ||
144 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
145 | struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | ||
146 | struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; | ||
147 | |||
148 | return bytes_to_frames(substream->runtime, memif->hw_ptr); | ||
149 | } | ||
150 | |||
151 | static const struct snd_pcm_ops mtk_afe_pcm_ops = { | ||
152 | .ioctl = snd_pcm_lib_ioctl, | ||
153 | .pointer = mtk_afe_pcm_pointer, | ||
154 | }; | ||
155 | |||
156 | static int mtk_afe_pcm_new(struct snd_soc_pcm_runtime *rtd) | ||
157 | { | ||
158 | size_t size; | ||
159 | struct snd_card *card = rtd->card->snd_card; | ||
160 | struct snd_pcm *pcm = rtd->pcm; | ||
161 | |||
162 | size = mtk_afe_hardware.buffer_bytes_max; | ||
163 | |||
164 | return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | ||
165 | card->dev, size, size); | ||
166 | } | ||
167 | |||
168 | static void mtk_afe_pcm_free(struct snd_pcm *pcm) | ||
169 | { | ||
170 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
171 | } | ||
172 | |||
173 | static const struct snd_soc_platform_driver mtk_afe_pcm_platform = { | ||
174 | .ops = &mtk_afe_pcm_ops, | ||
175 | .pcm_new = mtk_afe_pcm_new, | ||
176 | .pcm_free = mtk_afe_pcm_free, | ||
177 | }; | ||
178 | |||
179 | struct mtk_afe_rate { | ||
180 | unsigned int rate; | ||
181 | unsigned int regvalue; | ||
182 | }; | ||
183 | |||
184 | static const struct mtk_afe_rate mtk_afe_i2s_rates[] = { | ||
185 | { .rate = 8000, .regvalue = 0 }, | ||
186 | { .rate = 11025, .regvalue = 1 }, | ||
187 | { .rate = 12000, .regvalue = 2 }, | ||
188 | { .rate = 16000, .regvalue = 4 }, | ||
189 | { .rate = 22050, .regvalue = 5 }, | ||
190 | { .rate = 24000, .regvalue = 6 }, | ||
191 | { .rate = 32000, .regvalue = 8 }, | ||
192 | { .rate = 44100, .regvalue = 9 }, | ||
193 | { .rate = 48000, .regvalue = 10 }, | ||
194 | { .rate = 88000, .regvalue = 11 }, | ||
195 | { .rate = 96000, .regvalue = 12 }, | ||
196 | { .rate = 174000, .regvalue = 13 }, | ||
197 | { .rate = 192000, .regvalue = 14 }, | ||
198 | }; | ||
199 | |||
200 | static int mtk_afe_i2s_fs(unsigned int sample_rate) | ||
201 | { | ||
202 | int i; | ||
203 | |||
204 | for (i = 0; i < ARRAY_SIZE(mtk_afe_i2s_rates); i++) | ||
205 | if (mtk_afe_i2s_rates[i].rate == sample_rate) | ||
206 | return mtk_afe_i2s_rates[i].regvalue; | ||
207 | |||
208 | return -EINVAL; | ||
209 | } | ||
210 | |||
211 | static int mtk_afe_set_i2s(struct mtk_afe *afe, unsigned int rate) | ||
212 | { | ||
213 | unsigned int val; | ||
214 | int fs = mtk_afe_i2s_fs(rate); | ||
215 | |||
216 | if (fs < 0) | ||
217 | return -EINVAL; | ||
218 | |||
219 | /* from external ADC */ | ||
220 | regmap_update_bits(afe->regmap, AFE_ADDA2_TOP_CON0, 0x1, 0x1); | ||
221 | |||
222 | /* set input */ | ||
223 | val = AFE_I2S_CON2_LOW_JITTER_CLK | | ||
224 | AFE_I2S_CON2_RATE(fs) | | ||
225 | AFE_I2S_CON2_FORMAT_I2S; | ||
226 | |||
227 | regmap_update_bits(afe->regmap, AFE_I2S_CON2, ~AFE_I2S_CON2_EN, val); | ||
228 | |||
229 | /* set output */ | ||
230 | val = AFE_I2S_CON1_LOW_JITTER_CLK | | ||
231 | AFE_I2S_CON1_RATE(fs) | | ||
232 | AFE_I2S_CON1_FORMAT_I2S; | ||
233 | |||
234 | regmap_update_bits(afe->regmap, AFE_I2S_CON1, ~AFE_I2S_CON1_EN, val); | ||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | static void mtk_afe_set_i2s_enable(struct mtk_afe *afe, bool enable) | ||
239 | { | ||
240 | unsigned int val; | ||
241 | |||
242 | regmap_read(afe->regmap, AFE_I2S_CON2, &val); | ||
243 | if (!!(val & AFE_I2S_CON2_EN) == enable) | ||
244 | return; /* must skip soft reset */ | ||
245 | |||
246 | /* I2S soft reset begin */ | ||
247 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON1, 0x4, 0x4); | ||
248 | |||
249 | /* input */ | ||
250 | regmap_update_bits(afe->regmap, AFE_I2S_CON2, 0x1, enable); | ||
251 | |||
252 | /* output */ | ||
253 | regmap_update_bits(afe->regmap, AFE_I2S_CON1, 0x1, enable); | ||
254 | |||
255 | /* I2S soft reset end */ | ||
256 | udelay(1); | ||
257 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON1, 0x4, 0); | ||
258 | } | ||
259 | |||
260 | static int mtk_afe_dais_enable_clks(struct mtk_afe *afe, | ||
261 | struct clk *m_ck, struct clk *b_ck) | ||
262 | { | ||
263 | int ret; | ||
264 | |||
265 | if (m_ck) { | ||
266 | ret = clk_prepare_enable(m_ck); | ||
267 | if (ret) { | ||
268 | dev_err(afe->dev, "Failed to enable m_ck\n"); | ||
269 | return ret; | ||
270 | } | ||
271 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, | ||
272 | AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0); | ||
273 | } | ||
274 | |||
275 | if (b_ck) { | ||
276 | ret = clk_prepare_enable(b_ck); | ||
277 | if (ret) { | ||
278 | dev_err(afe->dev, "Failed to enable b_ck\n"); | ||
279 | return ret; | ||
280 | } | ||
281 | } | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static int mtk_afe_dais_set_clks(struct mtk_afe *afe, | ||
286 | struct clk *m_ck, unsigned int mck_rate, | ||
287 | struct clk *b_ck, unsigned int bck_rate) | ||
288 | { | ||
289 | int ret; | ||
290 | |||
291 | if (m_ck) { | ||
292 | ret = clk_set_rate(m_ck, mck_rate); | ||
293 | if (ret) { | ||
294 | dev_err(afe->dev, "Failed to set m_ck rate\n"); | ||
295 | return ret; | ||
296 | } | ||
297 | } | ||
298 | |||
299 | if (b_ck) { | ||
300 | ret = clk_set_rate(b_ck, bck_rate); | ||
301 | if (ret) { | ||
302 | dev_err(afe->dev, "Failed to set b_ck rate\n"); | ||
303 | return ret; | ||
304 | } | ||
305 | } | ||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | static void mtk_afe_dais_disable_clks(struct mtk_afe *afe, | ||
310 | struct clk *m_ck, struct clk *b_ck) | ||
311 | { | ||
312 | if (m_ck) { | ||
313 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, | ||
314 | AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, | ||
315 | AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M); | ||
316 | clk_disable_unprepare(m_ck); | ||
317 | } | ||
318 | if (b_ck) | ||
319 | clk_disable_unprepare(b_ck); | ||
320 | } | ||
321 | |||
322 | static int mtk_afe_i2s_startup(struct snd_pcm_substream *substream, | ||
323 | struct snd_soc_dai *dai) | ||
324 | { | ||
325 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
326 | struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | ||
327 | |||
328 | if (dai->active) | ||
329 | return 0; | ||
330 | |||
331 | mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL); | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static void mtk_afe_i2s_shutdown(struct snd_pcm_substream *substream, | ||
336 | struct snd_soc_dai *dai) | ||
337 | { | ||
338 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
339 | struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | ||
340 | |||
341 | if (dai->active) | ||
342 | return; | ||
343 | |||
344 | mtk_afe_set_i2s_enable(afe, false); | ||
345 | mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL); | ||
346 | |||
347 | /* disable AFE */ | ||
348 | regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0); | ||
349 | } | ||
350 | |||
351 | static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream, | ||
352 | struct snd_soc_dai *dai) | ||
353 | { | ||
354 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
355 | struct snd_pcm_runtime * const runtime = substream->runtime; | ||
356 | struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | ||
357 | int ret; | ||
358 | |||
359 | mtk_afe_dais_set_clks(afe, | ||
360 | afe->clocks[MTK_CLK_I2S1_M], runtime->rate * 256, | ||
361 | NULL, 0); | ||
362 | /* config I2S */ | ||
363 | ret = mtk_afe_set_i2s(afe, substream->runtime->rate); | ||
364 | if (ret) | ||
365 | return ret; | ||
366 | |||
367 | mtk_afe_set_i2s_enable(afe, true); | ||
368 | |||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | static int mtk_afe_hdmi_startup(struct snd_pcm_substream *substream, | ||
373 | struct snd_soc_dai *dai) | ||
374 | { | ||
375 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
376 | struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | ||
377 | |||
378 | if (dai->active) | ||
379 | return 0; | ||
380 | |||
381 | mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S3_M], | ||
382 | afe->clocks[MTK_CLK_I2S3_B]); | ||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | static void mtk_afe_hdmi_shutdown(struct snd_pcm_substream *substream, | ||
387 | struct snd_soc_dai *dai) | ||
388 | { | ||
389 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
390 | struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | ||
391 | |||
392 | if (dai->active) | ||
393 | return; | ||
394 | |||
395 | mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S3_M], | ||
396 | afe->clocks[MTK_CLK_I2S3_B]); | ||
397 | |||
398 | /* disable AFE */ | ||
399 | regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0); | ||
400 | } | ||
401 | |||
402 | static int mtk_afe_hdmi_prepare(struct snd_pcm_substream *substream, | ||
403 | struct snd_soc_dai *dai) | ||
404 | { | ||
405 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
406 | struct snd_pcm_runtime * const runtime = substream->runtime; | ||
407 | struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | ||
408 | unsigned int val; | ||
409 | |||
410 | mtk_afe_dais_set_clks(afe, | ||
411 | afe->clocks[MTK_CLK_I2S3_M], runtime->rate * 128, | ||
412 | afe->clocks[MTK_CLK_I2S3_B], | ||
413 | runtime->rate * runtime->channels * 32); | ||
414 | |||
415 | val = AFE_TDM_CON1_BCK_INV | | ||
416 | AFE_TDM_CON1_1_BCK_DELAY | | ||
417 | AFE_TDM_CON1_MSB_ALIGNED | /* I2S mode */ | ||
418 | AFE_TDM_CON1_WLEN_32BIT | | ||
419 | AFE_TDM_CON1_32_BCK_CYCLES | | ||
420 | AFE_TDM_CON1_LRCK_WIDTH(32); | ||
421 | regmap_update_bits(afe->regmap, AFE_TDM_CON1, ~AFE_TDM_CON1_EN, val); | ||
422 | |||
423 | /* set tdm2 config */ | ||
424 | switch (runtime->channels) { | ||
425 | case 1: | ||
426 | case 2: | ||
427 | val = AFE_TDM_CH_START_O30_O31; | ||
428 | val |= (AFE_TDM_CH_ZERO << 4); | ||
429 | val |= (AFE_TDM_CH_ZERO << 8); | ||
430 | val |= (AFE_TDM_CH_ZERO << 12); | ||
431 | break; | ||
432 | case 3: | ||
433 | case 4: | ||
434 | val = AFE_TDM_CH_START_O30_O31; | ||
435 | val |= (AFE_TDM_CH_START_O32_O33 << 4); | ||
436 | val |= (AFE_TDM_CH_ZERO << 8); | ||
437 | val |= (AFE_TDM_CH_ZERO << 12); | ||
438 | break; | ||
439 | case 5: | ||
440 | case 6: | ||
441 | val = AFE_TDM_CH_START_O30_O31; | ||
442 | val |= (AFE_TDM_CH_START_O32_O33 << 4); | ||
443 | val |= (AFE_TDM_CH_START_O34_O35 << 8); | ||
444 | val |= (AFE_TDM_CH_ZERO << 12); | ||
445 | break; | ||
446 | case 7: | ||
447 | case 8: | ||
448 | val = AFE_TDM_CH_START_O30_O31; | ||
449 | val |= (AFE_TDM_CH_START_O32_O33 << 4); | ||
450 | val |= (AFE_TDM_CH_START_O34_O35 << 8); | ||
451 | val |= (AFE_TDM_CH_START_O36_O37 << 12); | ||
452 | break; | ||
453 | default: | ||
454 | val = 0; | ||
455 | } | ||
456 | regmap_update_bits(afe->regmap, AFE_TDM_CON2, 0x0000ffff, val); | ||
457 | |||
458 | regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, | ||
459 | 0x000000f0, runtime->channels << 4); | ||
460 | return 0; | ||
461 | } | ||
462 | |||
463 | static int mtk_afe_hdmi_trigger(struct snd_pcm_substream *substream, int cmd, | ||
464 | struct snd_soc_dai *dai) | ||
465 | { | ||
466 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
467 | struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | ||
468 | |||
469 | dev_info(afe->dev, "%s cmd=%d %s\n", __func__, cmd, dai->name); | ||
470 | |||
471 | switch (cmd) { | ||
472 | case SNDRV_PCM_TRIGGER_START: | ||
473 | case SNDRV_PCM_TRIGGER_RESUME: | ||
474 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, | ||
475 | AUD_TCON0_PDN_HDMI | AUD_TCON0_PDN_SPDF, 0); | ||
476 | |||
477 | /* set connections: O30~O37: L/R/LS/RS/C/LFE/CH7/CH8 */ | ||
478 | regmap_write(afe->regmap, AFE_HDMI_CONN0, | ||
479 | AFE_HDMI_CONN0_O30_I30 | AFE_HDMI_CONN0_O31_I31 | | ||
480 | AFE_HDMI_CONN0_O32_I34 | AFE_HDMI_CONN0_O33_I35 | | ||
481 | AFE_HDMI_CONN0_O34_I32 | AFE_HDMI_CONN0_O35_I33 | | ||
482 | AFE_HDMI_CONN0_O36_I36 | AFE_HDMI_CONN0_O37_I37); | ||
483 | |||
484 | /* enable Out control */ | ||
485 | regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, 0x1, 0x1); | ||
486 | |||
487 | /* enable tdm */ | ||
488 | regmap_update_bits(afe->regmap, AFE_TDM_CON1, 0x1, 0x1); | ||
489 | |||
490 | return 0; | ||
491 | case SNDRV_PCM_TRIGGER_STOP: | ||
492 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
493 | /* disable tdm */ | ||
494 | regmap_update_bits(afe->regmap, AFE_TDM_CON1, 0x1, 0); | ||
495 | |||
496 | /* disable Out control */ | ||
497 | regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, 0x1, 0); | ||
498 | |||
499 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, | ||
500 | AUD_TCON0_PDN_HDMI | AUD_TCON0_PDN_SPDF, | ||
501 | AUD_TCON0_PDN_HDMI | AUD_TCON0_PDN_SPDF); | ||
502 | |||
503 | return 0; | ||
504 | default: | ||
505 | return -EINVAL; | ||
506 | } | ||
507 | } | ||
508 | |||
509 | static int mtk_afe_dais_startup(struct snd_pcm_substream *substream, | ||
510 | struct snd_soc_dai *dai) | ||
511 | { | ||
512 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
513 | struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | ||
514 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
515 | struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; | ||
516 | int ret; | ||
517 | |||
518 | memif->substream = substream; | ||
519 | |||
520 | snd_soc_set_runtime_hwparams(substream, &mtk_afe_hardware); | ||
521 | ret = snd_pcm_hw_constraint_integer(runtime, | ||
522 | SNDRV_PCM_HW_PARAM_PERIODS); | ||
523 | if (ret < 0) | ||
524 | dev_err(afe->dev, "snd_pcm_hw_constraint_integer failed\n"); | ||
525 | return ret; | ||
526 | } | ||
527 | |||
528 | static void mtk_afe_dais_shutdown(struct snd_pcm_substream *substream, | ||
529 | struct snd_soc_dai *dai) | ||
530 | { | ||
531 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
532 | struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | ||
533 | struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; | ||
534 | |||
535 | memif->substream = NULL; | ||
536 | } | ||
537 | |||
538 | static int mtk_afe_dais_hw_params(struct snd_pcm_substream *substream, | ||
539 | struct snd_pcm_hw_params *params, | ||
540 | struct snd_soc_dai *dai) | ||
541 | { | ||
542 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
543 | struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | ||
544 | struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; | ||
545 | int ret; | ||
546 | |||
547 | dev_dbg(afe->dev, | ||
548 | "%s period = %u, rate= %u, channels=%u\n", | ||
549 | __func__, params_period_size(params), params_rate(params), | ||
550 | params_channels(params)); | ||
551 | |||
552 | ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); | ||
553 | if (ret < 0) | ||
554 | return ret; | ||
555 | |||
556 | memif->phys_buf_addr = substream->runtime->dma_addr; | ||
557 | memif->buffer_size = substream->runtime->dma_bytes; | ||
558 | memif->hw_ptr = 0; | ||
559 | |||
560 | /* start */ | ||
561 | regmap_write(afe->regmap, | ||
562 | memif->data->reg_ofs_base, memif->phys_buf_addr); | ||
563 | /* end */ | ||
564 | regmap_write(afe->regmap, | ||
565 | memif->data->reg_ofs_base + AFE_BASE_END_OFFSET, | ||
566 | memif->phys_buf_addr + memif->buffer_size - 1); | ||
567 | |||
568 | /* set channel */ | ||
569 | if (memif->data->mono_shift >= 0) { | ||
570 | unsigned int mono = (params_channels(params) == 1) ? 1 : 0; | ||
571 | |||
572 | regmap_update_bits(afe->regmap, AFE_DAC_CON1, | ||
573 | 1 << memif->data->mono_shift, | ||
574 | mono << memif->data->mono_shift); | ||
575 | } | ||
576 | |||
577 | /* set rate */ | ||
578 | if (memif->data->fs_shift < 0) | ||
579 | return 0; | ||
580 | if (memif->data->id == MTK_AFE_MEMIF_DAI || | ||
581 | memif->data->id == MTK_AFE_MEMIF_MOD_DAI) { | ||
582 | unsigned int val; | ||
583 | |||
584 | switch (params_rate(params)) { | ||
585 | case 8000: | ||
586 | val = 0; | ||
587 | break; | ||
588 | case 16000: | ||
589 | val = 1; | ||
590 | break; | ||
591 | case 32000: | ||
592 | val = 2; | ||
593 | break; | ||
594 | default: | ||
595 | return -EINVAL; | ||
596 | } | ||
597 | |||
598 | if (memif->data->id == MTK_AFE_MEMIF_DAI) | ||
599 | regmap_update_bits(afe->regmap, AFE_DAC_CON0, | ||
600 | 0x3 << memif->data->fs_shift, | ||
601 | val << memif->data->fs_shift); | ||
602 | else | ||
603 | regmap_update_bits(afe->regmap, AFE_DAC_CON1, | ||
604 | 0x3 << memif->data->fs_shift, | ||
605 | val << memif->data->fs_shift); | ||
606 | |||
607 | } else { | ||
608 | int fs = mtk_afe_i2s_fs(params_rate(params)); | ||
609 | |||
610 | if (fs < 0) | ||
611 | return -EINVAL; | ||
612 | |||
613 | regmap_update_bits(afe->regmap, AFE_DAC_CON1, | ||
614 | 0xf << memif->data->fs_shift, | ||
615 | fs << memif->data->fs_shift); | ||
616 | } | ||
617 | |||
618 | return 0; | ||
619 | } | ||
620 | |||
621 | static int mtk_afe_dais_hw_free(struct snd_pcm_substream *substream, | ||
622 | struct snd_soc_dai *dai) | ||
623 | { | ||
624 | return snd_pcm_lib_free_pages(substream); | ||
625 | } | ||
626 | |||
627 | static int mtk_afe_dais_prepare(struct snd_pcm_substream *substream, | ||
628 | struct snd_soc_dai *dai) | ||
629 | { | ||
630 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
631 | struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | ||
632 | |||
633 | /* enable AFE */ | ||
634 | regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1); | ||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | static int mtk_afe_dais_trigger(struct snd_pcm_substream *substream, int cmd, | ||
639 | struct snd_soc_dai *dai) | ||
640 | { | ||
641 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
642 | struct snd_pcm_runtime * const runtime = substream->runtime; | ||
643 | struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | ||
644 | struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; | ||
645 | unsigned int counter = runtime->period_size; | ||
646 | |||
647 | dev_info(afe->dev, "%s %s cmd=%d\n", __func__, memif->data->name, cmd); | ||
648 | |||
649 | switch (cmd) { | ||
650 | case SNDRV_PCM_TRIGGER_START: | ||
651 | case SNDRV_PCM_TRIGGER_RESUME: | ||
652 | if (memif->data->enable_shift >= 0) | ||
653 | regmap_update_bits(afe->regmap, AFE_DAC_CON0, | ||
654 | 1 << memif->data->enable_shift, | ||
655 | 1 << memif->data->enable_shift); | ||
656 | |||
657 | /* set irq counter */ | ||
658 | regmap_update_bits(afe->regmap, | ||
659 | memif->data->irq_reg_cnt, | ||
660 | 0x3ffff << memif->data->irq_cnt_shift, | ||
661 | counter << memif->data->irq_cnt_shift); | ||
662 | |||
663 | /* set irq fs */ | ||
664 | if (memif->data->irq_fs_shift >= 0) { | ||
665 | int fs = mtk_afe_i2s_fs(runtime->rate); | ||
666 | |||
667 | if (fs < 0) | ||
668 | return -EINVAL; | ||
669 | |||
670 | regmap_update_bits(afe->regmap, | ||
671 | AFE_IRQ_MCU_CON, | ||
672 | 0xf << memif->data->irq_fs_shift, | ||
673 | fs << memif->data->irq_fs_shift); | ||
674 | } | ||
675 | /* enable interrupt */ | ||
676 | regmap_update_bits(afe->regmap, AFE_IRQ_MCU_CON, | ||
677 | 1 << memif->data->irq_en_shift, | ||
678 | 1 << memif->data->irq_en_shift); | ||
679 | |||
680 | return 0; | ||
681 | case SNDRV_PCM_TRIGGER_STOP: | ||
682 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
683 | if (memif->data->enable_shift >= 0) | ||
684 | regmap_update_bits(afe->regmap, AFE_DAC_CON0, | ||
685 | 1 << memif->data->enable_shift, 0); | ||
686 | /* disable interrupt */ | ||
687 | regmap_update_bits(afe->regmap, AFE_IRQ_MCU_CON, | ||
688 | 1 << memif->data->irq_en_shift, | ||
689 | 0 << memif->data->irq_en_shift); | ||
690 | /* and clear pending IRQ */ | ||
691 | regmap_write(afe->regmap, AFE_IRQ_CLR, | ||
692 | 1 << memif->data->irq_clr_shift); | ||
693 | memif->hw_ptr = 0; | ||
694 | return 0; | ||
695 | default: | ||
696 | return -EINVAL; | ||
697 | } | ||
698 | } | ||
699 | |||
700 | /* FE DAIs */ | ||
701 | static const struct snd_soc_dai_ops mtk_afe_dai_ops = { | ||
702 | .startup = mtk_afe_dais_startup, | ||
703 | .shutdown = mtk_afe_dais_shutdown, | ||
704 | .hw_params = mtk_afe_dais_hw_params, | ||
705 | .hw_free = mtk_afe_dais_hw_free, | ||
706 | .prepare = mtk_afe_dais_prepare, | ||
707 | .trigger = mtk_afe_dais_trigger, | ||
708 | }; | ||
709 | |||
710 | /* BE DAIs */ | ||
711 | static const struct snd_soc_dai_ops mtk_afe_i2s_ops = { | ||
712 | .startup = mtk_afe_i2s_startup, | ||
713 | .shutdown = mtk_afe_i2s_shutdown, | ||
714 | .prepare = mtk_afe_i2s_prepare, | ||
715 | }; | ||
716 | |||
717 | static const struct snd_soc_dai_ops mtk_afe_hdmi_ops = { | ||
718 | .startup = mtk_afe_hdmi_startup, | ||
719 | .shutdown = mtk_afe_hdmi_shutdown, | ||
720 | .prepare = mtk_afe_hdmi_prepare, | ||
721 | .trigger = mtk_afe_hdmi_trigger, | ||
722 | |||
723 | }; | ||
724 | |||
725 | static struct snd_soc_dai_driver mtk_afe_pcm_dais[] = { | ||
726 | /* FE DAIs: memory intefaces to CPU */ | ||
727 | { | ||
728 | .name = "DL1", /* downlink 1 */ | ||
729 | .id = MTK_AFE_MEMIF_DL1, | ||
730 | .playback = { | ||
731 | .stream_name = "DL1", | ||
732 | .channels_min = 1, | ||
733 | .channels_max = 2, | ||
734 | .rates = SNDRV_PCM_RATE_8000_48000, | ||
735 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
736 | }, | ||
737 | .ops = &mtk_afe_dai_ops, | ||
738 | }, { | ||
739 | .name = "VUL", /* voice uplink */ | ||
740 | .id = MTK_AFE_MEMIF_VUL, | ||
741 | .capture = { | ||
742 | .stream_name = "VUL", | ||
743 | .channels_min = 1, | ||
744 | .channels_max = 2, | ||
745 | .rates = SNDRV_PCM_RATE_8000_48000, | ||
746 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
747 | }, | ||
748 | .ops = &mtk_afe_dai_ops, | ||
749 | }, { | ||
750 | /* BE DAIs */ | ||
751 | .name = "I2S", | ||
752 | .id = MTK_AFE_IO_I2S, | ||
753 | .playback = { | ||
754 | .stream_name = "I2S Playback", | ||
755 | .channels_min = 1, | ||
756 | .channels_max = 2, | ||
757 | .rates = SNDRV_PCM_RATE_8000_48000, | ||
758 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
759 | }, | ||
760 | .capture = { | ||
761 | .stream_name = "I2S Capture", | ||
762 | .channels_min = 1, | ||
763 | .channels_max = 2, | ||
764 | .rates = SNDRV_PCM_RATE_8000_48000, | ||
765 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
766 | }, | ||
767 | .ops = &mtk_afe_i2s_ops, | ||
768 | .symmetric_rates = 1, | ||
769 | }, | ||
770 | }; | ||
771 | |||
772 | static struct snd_soc_dai_driver mtk_afe_hdmi_dais[] = { | ||
773 | /* FE DAIs */ | ||
774 | { | ||
775 | .name = "HDMI", | ||
776 | .id = MTK_AFE_MEMIF_HDMI, | ||
777 | .playback = { | ||
778 | .stream_name = "HDMI", | ||
779 | .channels_min = 2, | ||
780 | .channels_max = 8, | ||
781 | .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | | ||
782 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | | ||
783 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | | ||
784 | SNDRV_PCM_RATE_192000, | ||
785 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
786 | }, | ||
787 | .ops = &mtk_afe_dai_ops, | ||
788 | }, { | ||
789 | /* BE DAIs */ | ||
790 | .name = "HDMIO", | ||
791 | .id = MTK_AFE_IO_HDMI, | ||
792 | .playback = { | ||
793 | .stream_name = "HDMIO Playback", | ||
794 | .channels_min = 2, | ||
795 | .channels_max = 8, | ||
796 | .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | | ||
797 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | | ||
798 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | | ||
799 | SNDRV_PCM_RATE_192000, | ||
800 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
801 | }, | ||
802 | .ops = &mtk_afe_hdmi_ops, | ||
803 | }, | ||
804 | }; | ||
805 | |||
806 | static const struct snd_kcontrol_new mtk_afe_o03_mix[] = { | ||
807 | SOC_DAPM_SINGLE_AUTODISABLE("I05 Switch", AFE_CONN1, 21, 1, 0), | ||
808 | }; | ||
809 | |||
810 | static const struct snd_kcontrol_new mtk_afe_o04_mix[] = { | ||
811 | SOC_DAPM_SINGLE_AUTODISABLE("I06 Switch", AFE_CONN2, 6, 1, 0), | ||
812 | }; | ||
813 | |||
814 | static const struct snd_kcontrol_new mtk_afe_o09_mix[] = { | ||
815 | SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN7, 30, 1, 0), | ||
816 | }; | ||
817 | |||
818 | static const struct snd_kcontrol_new mtk_afe_o10_mix[] = { | ||
819 | SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN8, 0, 1, 0), | ||
820 | }; | ||
821 | |||
822 | static const struct snd_soc_dapm_widget mtk_afe_pcm_widgets[] = { | ||
823 | /* Backend DAIs */ | ||
824 | SND_SOC_DAPM_AIF_IN("I2S Capture", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
825 | SND_SOC_DAPM_AIF_OUT("I2S Playback", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
826 | |||
827 | /* inter-connections */ | ||
828 | SND_SOC_DAPM_MIXER("I05", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
829 | SND_SOC_DAPM_MIXER("I06", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
830 | SND_SOC_DAPM_MIXER("I17", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
831 | SND_SOC_DAPM_MIXER("I18", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
832 | |||
833 | SND_SOC_DAPM_MIXER("O03", SND_SOC_NOPM, 0, 0, | ||
834 | mtk_afe_o03_mix, ARRAY_SIZE(mtk_afe_o03_mix)), | ||
835 | SND_SOC_DAPM_MIXER("O04", SND_SOC_NOPM, 0, 0, | ||
836 | mtk_afe_o04_mix, ARRAY_SIZE(mtk_afe_o04_mix)), | ||
837 | SND_SOC_DAPM_MIXER("O09", SND_SOC_NOPM, 0, 0, | ||
838 | mtk_afe_o09_mix, ARRAY_SIZE(mtk_afe_o09_mix)), | ||
839 | SND_SOC_DAPM_MIXER("O10", SND_SOC_NOPM, 0, 0, | ||
840 | mtk_afe_o10_mix, ARRAY_SIZE(mtk_afe_o10_mix)), | ||
841 | }; | ||
842 | |||
843 | static const struct snd_soc_dapm_route mtk_afe_pcm_routes[] = { | ||
844 | {"I05", NULL, "DL1"}, | ||
845 | {"I06", NULL, "DL1"}, | ||
846 | {"I2S Playback", NULL, "O03"}, | ||
847 | {"I2S Playback", NULL, "O04"}, | ||
848 | {"VUL", NULL, "O09"}, | ||
849 | {"VUL", NULL, "O10"}, | ||
850 | {"I17", NULL, "I2S Capture"}, | ||
851 | {"I18", NULL, "I2S Capture"}, | ||
852 | { "O03", "I05 Switch", "I05" }, | ||
853 | { "O04", "I06 Switch", "I06" }, | ||
854 | { "O09", "I17 Switch", "I17" }, | ||
855 | { "O10", "I18 Switch", "I18" }, | ||
856 | }; | ||
857 | |||
858 | static const struct snd_soc_dapm_widget mtk_afe_hdmi_widgets[] = { | ||
859 | /* Backend DAIs */ | ||
860 | SND_SOC_DAPM_AIF_OUT("HDMIO Playback", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
861 | }; | ||
862 | |||
863 | static const struct snd_soc_dapm_route mtk_afe_hdmi_routes[] = { | ||
864 | {"HDMIO Playback", NULL, "HDMI"}, | ||
865 | }; | ||
866 | |||
867 | static const struct snd_soc_component_driver mtk_afe_pcm_dai_component = { | ||
868 | .name = "mtk-afe-pcm-dai", | ||
869 | .dapm_widgets = mtk_afe_pcm_widgets, | ||
870 | .num_dapm_widgets = ARRAY_SIZE(mtk_afe_pcm_widgets), | ||
871 | .dapm_routes = mtk_afe_pcm_routes, | ||
872 | .num_dapm_routes = ARRAY_SIZE(mtk_afe_pcm_routes), | ||
873 | }; | ||
874 | |||
875 | static const struct snd_soc_component_driver mtk_afe_hdmi_dai_component = { | ||
876 | .name = "mtk-afe-hdmi-dai", | ||
877 | .dapm_widgets = mtk_afe_hdmi_widgets, | ||
878 | .num_dapm_widgets = ARRAY_SIZE(mtk_afe_hdmi_widgets), | ||
879 | .dapm_routes = mtk_afe_hdmi_routes, | ||
880 | .num_dapm_routes = ARRAY_SIZE(mtk_afe_hdmi_routes), | ||
881 | }; | ||
882 | |||
883 | static const char *aud_clks[MTK_CLK_NUM] = { | ||
884 | [MTK_CLK_INFRASYS_AUD] = "infra_sys_audio_clk", | ||
885 | [MTK_CLK_TOP_PDN_AUD] = "top_pdn_audio", | ||
886 | [MTK_CLK_TOP_PDN_AUD_BUS] = "top_pdn_aud_intbus", | ||
887 | [MTK_CLK_I2S0_M] = "i2s0_m", | ||
888 | [MTK_CLK_I2S1_M] = "i2s1_m", | ||
889 | [MTK_CLK_I2S2_M] = "i2s2_m", | ||
890 | [MTK_CLK_I2S3_M] = "i2s3_m", | ||
891 | [MTK_CLK_I2S3_B] = "i2s3_b", | ||
892 | [MTK_CLK_BCK0] = "bck0", | ||
893 | [MTK_CLK_BCK1] = "bck1", | ||
894 | }; | ||
895 | |||
896 | static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = { | ||
897 | { | ||
898 | .name = "DL1", | ||
899 | .id = MTK_AFE_MEMIF_DL1, | ||
900 | .reg_ofs_base = AFE_DL1_BASE, | ||
901 | .reg_ofs_cur = AFE_DL1_CUR, | ||
902 | .fs_shift = 0, | ||
903 | .mono_shift = 21, | ||
904 | .enable_shift = 1, | ||
905 | .irq_reg_cnt = AFE_IRQ_CNT1, | ||
906 | .irq_cnt_shift = 0, | ||
907 | .irq_en_shift = 0, | ||
908 | .irq_fs_shift = 4, | ||
909 | .irq_clr_shift = 0, | ||
910 | }, { | ||
911 | .name = "DL2", | ||
912 | .id = MTK_AFE_MEMIF_DL2, | ||
913 | .reg_ofs_base = AFE_DL2_BASE, | ||
914 | .reg_ofs_cur = AFE_DL2_CUR, | ||
915 | .fs_shift = 4, | ||
916 | .mono_shift = 22, | ||
917 | .enable_shift = 2, | ||
918 | .irq_reg_cnt = AFE_IRQ_CNT1, | ||
919 | .irq_cnt_shift = 20, | ||
920 | .irq_en_shift = 2, | ||
921 | .irq_fs_shift = 16, | ||
922 | .irq_clr_shift = 2, | ||
923 | }, { | ||
924 | .name = "VUL", | ||
925 | .id = MTK_AFE_MEMIF_VUL, | ||
926 | .reg_ofs_base = AFE_VUL_BASE, | ||
927 | .reg_ofs_cur = AFE_VUL_CUR, | ||
928 | .fs_shift = 16, | ||
929 | .mono_shift = 27, | ||
930 | .enable_shift = 3, | ||
931 | .irq_reg_cnt = AFE_IRQ_CNT2, | ||
932 | .irq_cnt_shift = 0, | ||
933 | .irq_en_shift = 1, | ||
934 | .irq_fs_shift = 8, | ||
935 | .irq_clr_shift = 1, | ||
936 | }, { | ||
937 | .name = "DAI", | ||
938 | .id = MTK_AFE_MEMIF_DAI, | ||
939 | .reg_ofs_base = AFE_DAI_BASE, | ||
940 | .reg_ofs_cur = AFE_DAI_CUR, | ||
941 | .fs_shift = 24, | ||
942 | .mono_shift = -1, | ||
943 | .enable_shift = 4, | ||
944 | .irq_reg_cnt = AFE_IRQ_CNT2, | ||
945 | .irq_cnt_shift = 20, | ||
946 | .irq_en_shift = 3, | ||
947 | .irq_fs_shift = 20, | ||
948 | .irq_clr_shift = 3, | ||
949 | }, { | ||
950 | .name = "AWB", | ||
951 | .id = MTK_AFE_MEMIF_AWB, | ||
952 | .reg_ofs_base = AFE_AWB_BASE, | ||
953 | .reg_ofs_cur = AFE_AWB_CUR, | ||
954 | .fs_shift = 12, | ||
955 | .mono_shift = 24, | ||
956 | .enable_shift = 6, | ||
957 | .irq_reg_cnt = AFE_IRQ_CNT7, | ||
958 | .irq_cnt_shift = 0, | ||
959 | .irq_en_shift = 14, | ||
960 | .irq_fs_shift = 24, | ||
961 | .irq_clr_shift = 6, | ||
962 | }, { | ||
963 | .name = "MOD_DAI", | ||
964 | .id = MTK_AFE_MEMIF_MOD_DAI, | ||
965 | .reg_ofs_base = AFE_MOD_PCM_BASE, | ||
966 | .reg_ofs_cur = AFE_MOD_PCM_CUR, | ||
967 | .fs_shift = 30, | ||
968 | .mono_shift = 30, | ||
969 | .enable_shift = 7, | ||
970 | .irq_reg_cnt = AFE_IRQ_CNT2, | ||
971 | .irq_cnt_shift = 20, | ||
972 | .irq_en_shift = 3, | ||
973 | .irq_fs_shift = 20, | ||
974 | .irq_clr_shift = 3, | ||
975 | }, { | ||
976 | .name = "HDMI", | ||
977 | .id = MTK_AFE_MEMIF_HDMI, | ||
978 | .reg_ofs_base = AFE_HDMI_OUT_BASE, | ||
979 | .reg_ofs_cur = AFE_HDMI_OUT_CUR, | ||
980 | .fs_shift = -1, | ||
981 | .mono_shift = -1, | ||
982 | .enable_shift = -1, | ||
983 | .irq_reg_cnt = AFE_IRQ_CNT5, | ||
984 | .irq_cnt_shift = 0, | ||
985 | .irq_en_shift = 12, | ||
986 | .irq_fs_shift = -1, | ||
987 | .irq_clr_shift = 4, | ||
988 | }, | ||
989 | }; | ||
990 | |||
991 | static const struct regmap_config mtk_afe_regmap_config = { | ||
992 | .reg_bits = 32, | ||
993 | .reg_stride = 4, | ||
994 | .val_bits = 32, | ||
995 | .max_register = AFE_ADDA2_TOP_CON0, | ||
996 | .cache_type = REGCACHE_NONE, | ||
997 | }; | ||
998 | |||
999 | static irqreturn_t mtk_afe_irq_handler(int irq, void *dev_id) | ||
1000 | { | ||
1001 | struct mtk_afe *afe = dev_id; | ||
1002 | unsigned int reg_value, hw_ptr; | ||
1003 | int i, ret; | ||
1004 | |||
1005 | ret = regmap_read(afe->regmap, AFE_IRQ_STATUS, ®_value); | ||
1006 | if (ret) { | ||
1007 | dev_err(afe->dev, "%s irq status err\n", __func__); | ||
1008 | reg_value = AFE_IRQ_STATUS_BITS; | ||
1009 | goto err_irq; | ||
1010 | } | ||
1011 | |||
1012 | for (i = 0; i < MTK_AFE_MEMIF_NUM; i++) { | ||
1013 | struct mtk_afe_memif *memif = &afe->memif[i]; | ||
1014 | |||
1015 | if (!(reg_value & (1 << memif->data->irq_clr_shift))) | ||
1016 | continue; | ||
1017 | |||
1018 | ret = regmap_read(afe->regmap, memif->data->reg_ofs_cur, | ||
1019 | &hw_ptr); | ||
1020 | if (ret || hw_ptr == 0) { | ||
1021 | dev_err(afe->dev, "%s hw_ptr err\n", __func__); | ||
1022 | hw_ptr = memif->phys_buf_addr; | ||
1023 | } | ||
1024 | memif->hw_ptr = hw_ptr - memif->phys_buf_addr; | ||
1025 | snd_pcm_period_elapsed(memif->substream); | ||
1026 | } | ||
1027 | |||
1028 | err_irq: | ||
1029 | /* clear irq */ | ||
1030 | regmap_write(afe->regmap, AFE_IRQ_CLR, reg_value & AFE_IRQ_STATUS_BITS); | ||
1031 | |||
1032 | return IRQ_HANDLED; | ||
1033 | } | ||
1034 | |||
1035 | static int mtk_afe_runtime_suspend(struct device *dev) | ||
1036 | { | ||
1037 | struct mtk_afe *afe = dev_get_drvdata(dev); | ||
1038 | |||
1039 | /* disable AFE clk */ | ||
1040 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, | ||
1041 | AUD_TCON0_PDN_AFE, AUD_TCON0_PDN_AFE); | ||
1042 | |||
1043 | clk_disable_unprepare(afe->clocks[MTK_CLK_BCK0]); | ||
1044 | clk_disable_unprepare(afe->clocks[MTK_CLK_BCK1]); | ||
1045 | clk_disable_unprepare(afe->clocks[MTK_CLK_TOP_PDN_AUD]); | ||
1046 | clk_disable_unprepare(afe->clocks[MTK_CLK_TOP_PDN_AUD_BUS]); | ||
1047 | clk_disable_unprepare(afe->clocks[MTK_CLK_INFRASYS_AUD]); | ||
1048 | return 0; | ||
1049 | } | ||
1050 | |||
1051 | static int mtk_afe_runtime_resume(struct device *dev) | ||
1052 | { | ||
1053 | struct mtk_afe *afe = dev_get_drvdata(dev); | ||
1054 | int ret; | ||
1055 | |||
1056 | ret = clk_prepare_enable(afe->clocks[MTK_CLK_INFRASYS_AUD]); | ||
1057 | if (ret) | ||
1058 | return ret; | ||
1059 | |||
1060 | ret = clk_prepare_enable(afe->clocks[MTK_CLK_TOP_PDN_AUD_BUS]); | ||
1061 | if (ret) | ||
1062 | goto err_infra; | ||
1063 | |||
1064 | ret = clk_prepare_enable(afe->clocks[MTK_CLK_TOP_PDN_AUD]); | ||
1065 | if (ret) | ||
1066 | goto err_top_aud_bus; | ||
1067 | |||
1068 | ret = clk_prepare_enable(afe->clocks[MTK_CLK_BCK0]); | ||
1069 | if (ret) | ||
1070 | goto err_top_aud; | ||
1071 | |||
1072 | ret = clk_prepare_enable(afe->clocks[MTK_CLK_BCK1]); | ||
1073 | if (ret) | ||
1074 | goto err_bck0; | ||
1075 | |||
1076 | /* enable AFE clk */ | ||
1077 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, AUD_TCON0_PDN_AFE, 0); | ||
1078 | |||
1079 | /* set O3/O4 16bits */ | ||
1080 | regmap_update_bits(afe->regmap, AFE_CONN_24BIT, | ||
1081 | AFE_CONN_24BIT_O03 | AFE_CONN_24BIT_O04, 0); | ||
1082 | |||
1083 | /* unmask all IRQs */ | ||
1084 | regmap_update_bits(afe->regmap, AFE_IRQ_MCU_EN, 0xff, 0xff); | ||
1085 | return 0; | ||
1086 | |||
1087 | err_bck0: | ||
1088 | clk_disable_unprepare(afe->clocks[MTK_CLK_BCK0]); | ||
1089 | err_top_aud: | ||
1090 | clk_disable_unprepare(afe->clocks[MTK_CLK_TOP_PDN_AUD]); | ||
1091 | err_top_aud_bus: | ||
1092 | clk_disable_unprepare(afe->clocks[MTK_CLK_TOP_PDN_AUD_BUS]); | ||
1093 | err_infra: | ||
1094 | clk_disable_unprepare(afe->clocks[MTK_CLK_INFRASYS_AUD]); | ||
1095 | return ret; | ||
1096 | } | ||
1097 | |||
1098 | static int mtk_afe_init_audio_clk(struct mtk_afe *afe) | ||
1099 | { | ||
1100 | size_t i; | ||
1101 | |||
1102 | for (i = 0; i < ARRAY_SIZE(aud_clks); i++) { | ||
1103 | afe->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]); | ||
1104 | if (IS_ERR(afe->clocks[i])) { | ||
1105 | dev_err(afe->dev, "%s devm_clk_get %s fail\n", | ||
1106 | __func__, aud_clks[i]); | ||
1107 | return PTR_ERR(afe->clocks[i]); | ||
1108 | } | ||
1109 | } | ||
1110 | clk_set_rate(afe->clocks[MTK_CLK_BCK0], 22579200); /* 22M */ | ||
1111 | clk_set_rate(afe->clocks[MTK_CLK_BCK1], 24576000); /* 24M */ | ||
1112 | return 0; | ||
1113 | } | ||
1114 | |||
1115 | static int mtk_afe_pcm_dev_probe(struct platform_device *pdev) | ||
1116 | { | ||
1117 | int ret, i; | ||
1118 | unsigned int irq_id; | ||
1119 | struct mtk_afe *afe; | ||
1120 | struct resource *res; | ||
1121 | |||
1122 | afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL); | ||
1123 | if (!afe) | ||
1124 | return -ENOMEM; | ||
1125 | |||
1126 | afe->dev = &pdev->dev; | ||
1127 | |||
1128 | irq_id = platform_get_irq(pdev, 0); | ||
1129 | if (!irq_id) { | ||
1130 | dev_err(afe->dev, "np %s no irq\n", afe->dev->of_node->name); | ||
1131 | return -ENXIO; | ||
1132 | } | ||
1133 | ret = devm_request_irq(afe->dev, irq_id, mtk_afe_irq_handler, | ||
1134 | 0, "Afe_ISR_Handle", (void *)afe); | ||
1135 | if (ret) { | ||
1136 | dev_err(afe->dev, "could not request_irq\n"); | ||
1137 | return ret; | ||
1138 | } | ||
1139 | |||
1140 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1141 | afe->base_addr = devm_ioremap_resource(&pdev->dev, res); | ||
1142 | if (IS_ERR(afe->base_addr)) | ||
1143 | return PTR_ERR(afe->base_addr); | ||
1144 | |||
1145 | afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr, | ||
1146 | &mtk_afe_regmap_config); | ||
1147 | if (IS_ERR(afe->regmap)) | ||
1148 | return PTR_ERR(afe->regmap); | ||
1149 | |||
1150 | /* initial audio related clock */ | ||
1151 | ret = mtk_afe_init_audio_clk(afe); | ||
1152 | if (ret) { | ||
1153 | dev_err(afe->dev, "mtk_afe_init_audio_clk fail\n"); | ||
1154 | return ret; | ||
1155 | } | ||
1156 | |||
1157 | for (i = 0; i < MTK_AFE_MEMIF_NUM; i++) | ||
1158 | afe->memif[i].data = &memif_data[i]; | ||
1159 | |||
1160 | platform_set_drvdata(pdev, afe); | ||
1161 | |||
1162 | pm_runtime_enable(&pdev->dev); | ||
1163 | if (!pm_runtime_enabled(&pdev->dev)) { | ||
1164 | ret = mtk_afe_runtime_resume(&pdev->dev); | ||
1165 | if (ret) | ||
1166 | goto err_pm_disable; | ||
1167 | } | ||
1168 | |||
1169 | ret = snd_soc_register_platform(&pdev->dev, &mtk_afe_pcm_platform); | ||
1170 | if (ret) | ||
1171 | goto err_pm_disable; | ||
1172 | |||
1173 | ret = snd_soc_register_component(&pdev->dev, | ||
1174 | &mtk_afe_pcm_dai_component, | ||
1175 | mtk_afe_pcm_dais, | ||
1176 | ARRAY_SIZE(mtk_afe_pcm_dais)); | ||
1177 | if (ret) | ||
1178 | goto err_platform; | ||
1179 | |||
1180 | ret = snd_soc_register_component(&pdev->dev, | ||
1181 | &mtk_afe_hdmi_dai_component, | ||
1182 | mtk_afe_hdmi_dais, | ||
1183 | ARRAY_SIZE(mtk_afe_hdmi_dais)); | ||
1184 | if (ret) | ||
1185 | goto err_comp; | ||
1186 | |||
1187 | dev_info(&pdev->dev, "MTK AFE driver initialized.\n"); | ||
1188 | return 0; | ||
1189 | |||
1190 | err_comp: | ||
1191 | snd_soc_unregister_component(&pdev->dev); | ||
1192 | err_platform: | ||
1193 | snd_soc_unregister_platform(&pdev->dev); | ||
1194 | err_pm_disable: | ||
1195 | pm_runtime_disable(&pdev->dev); | ||
1196 | return ret; | ||
1197 | } | ||
1198 | |||
1199 | static int mtk_afe_pcm_dev_remove(struct platform_device *pdev) | ||
1200 | { | ||
1201 | pm_runtime_disable(&pdev->dev); | ||
1202 | snd_soc_unregister_component(&pdev->dev); | ||
1203 | snd_soc_unregister_platform(&pdev->dev); | ||
1204 | return 0; | ||
1205 | } | ||
1206 | |||
1207 | static const struct of_device_id mtk_afe_pcm_dt_match[] = { | ||
1208 | { .compatible = "mediatek,mt8173-afe-pcm", }, | ||
1209 | { } | ||
1210 | }; | ||
1211 | MODULE_DEVICE_TABLE(of, mtk_afe_pcm_dt_match); | ||
1212 | |||
1213 | static const struct dev_pm_ops mtk_afe_pm_ops = { | ||
1214 | SET_RUNTIME_PM_OPS(mtk_afe_runtime_suspend, mtk_afe_runtime_resume, | ||
1215 | NULL) | ||
1216 | }; | ||
1217 | |||
1218 | static struct platform_driver mtk_afe_pcm_driver = { | ||
1219 | .driver = { | ||
1220 | .name = "mtk-afe-pcm", | ||
1221 | .owner = THIS_MODULE, | ||
1222 | .of_match_table = mtk_afe_pcm_dt_match, | ||
1223 | .pm = &mtk_afe_pm_ops, | ||
1224 | }, | ||
1225 | .probe = mtk_afe_pcm_dev_probe, | ||
1226 | .remove = mtk_afe_pcm_dev_remove, | ||
1227 | }; | ||
1228 | |||
1229 | module_platform_driver(mtk_afe_pcm_driver); | ||
1230 | |||
1231 | MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver"); | ||
1232 | MODULE_AUTHOR("Koro Chen <koro.chen@mediatek.com>"); | ||
1233 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index fded99362d39..3bebfb1d3a6f 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c | |||
@@ -245,6 +245,8 @@ static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = { | |||
245 | static const struct snd_soc_dapm_route audio_map[] = { | 245 | static const struct snd_soc_dapm_route audio_map[] = { |
246 | {"Ext Spk", NULL, "HPLOUT"}, | 246 | {"Ext Spk", NULL, "HPLOUT"}, |
247 | {"Ext Spk", NULL, "HPROUT"}, | 247 | {"Ext Spk", NULL, "HPROUT"}, |
248 | {"Ext Spk", NULL, "HPLCOM"}, | ||
249 | {"Ext Spk", NULL, "HPRCOM"}, | ||
248 | {"Headphone Jack", NULL, "LLOUT"}, | 250 | {"Headphone Jack", NULL, "LLOUT"}, |
249 | {"Headphone Jack", NULL, "RLOUT"}, | 251 | {"Headphone Jack", NULL, "RLOUT"}, |
250 | {"FM Transmitter", NULL, "LLOUT"}, | 252 | {"FM Transmitter", NULL, "LLOUT"}, |
@@ -288,15 +290,8 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) | |||
288 | struct snd_soc_codec *codec = rtd->codec; | 290 | struct snd_soc_codec *codec = rtd->codec; |
289 | struct snd_soc_card *card = rtd->card; | 291 | struct snd_soc_card *card = rtd->card; |
290 | struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card); | 292 | struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card); |
291 | |||
292 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
293 | int err; | 293 | int err; |
294 | 294 | ||
295 | /* Set up NC codec pins */ | ||
296 | snd_soc_dapm_nc_pin(dapm, "MIC3L"); | ||
297 | snd_soc_dapm_nc_pin(dapm, "MIC3R"); | ||
298 | snd_soc_dapm_nc_pin(dapm, "LINE1R"); | ||
299 | |||
300 | err = tpa6130a2_add_controls(codec); | 295 | err = tpa6130a2_add_controls(codec); |
301 | if (err < 0) { | 296 | if (err < 0) { |
302 | dev_err(card->dev, "Failed to add TPA6130A2 controls\n"); | 297 | dev_err(card->dev, "Failed to add TPA6130A2 controls\n"); |
@@ -383,6 +378,7 @@ static struct snd_soc_card rx51_sound_card = { | |||
383 | .num_aux_devs = ARRAY_SIZE(rx51_aux_dev), | 378 | .num_aux_devs = ARRAY_SIZE(rx51_aux_dev), |
384 | .codec_conf = rx51_codec_conf, | 379 | .codec_conf = rx51_codec_conf, |
385 | .num_configs = ARRAY_SIZE(rx51_codec_conf), | 380 | .num_configs = ARRAY_SIZE(rx51_codec_conf), |
381 | .fully_routed = true, | ||
386 | 382 | ||
387 | .controls = aic34_rx51_controls, | 383 | .controls = aic34_rx51_controls, |
388 | .num_controls = ARRAY_SIZE(aic34_rx51_controls), | 384 | .num_controls = ARRAY_SIZE(aic34_rx51_controls), |
diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 938144c59e2b..807fedfa1c76 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig | |||
@@ -32,3 +32,12 @@ config SND_SOC_STORM | |||
32 | help | 32 | help |
33 | Say Y or M if you want add support for SoC audio on the | 33 | Say Y or M if you want add support for SoC audio on the |
34 | Qualcomm Technologies IPQ806X-based Storm board. | 34 | Qualcomm Technologies IPQ806X-based Storm board. |
35 | |||
36 | config SND_SOC_APQ8016_SBC | ||
37 | tristate "SoC Audio support for APQ8016 SBC platforms" | ||
38 | depends on SND_SOC_QCOM && (ARCH_QCOM || COMPILE_TEST) | ||
39 | select SND_SOC_LPASS_APQ8016 | ||
40 | help | ||
41 | Support for Qualcomm Technologies LPASS audio block in | ||
42 | APQ8016 SOC-based systems. | ||
43 | Say Y if you want to use audio devices on MI2S. | ||
diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile index ac7630833fe5..79e5c50a8f71 100644 --- a/sound/soc/qcom/Makefile +++ b/sound/soc/qcom/Makefile | |||
@@ -11,5 +11,7 @@ obj-$(CONFIG_SND_SOC_LPASS_APQ8016) += snd-soc-lpass-apq8016.o | |||
11 | 11 | ||
12 | # Machine | 12 | # Machine |
13 | snd-soc-storm-objs := storm.o | 13 | snd-soc-storm-objs := storm.o |
14 | snd-soc-apq8016-sbc-objs := apq8016_sbc.o | ||
14 | 15 | ||
15 | obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o | 16 | obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o |
17 | obj-$(CONFIG_SND_SOC_APQ8016_SBC) += snd-soc-apq8016-sbc.o | ||
diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c new file mode 100644 index 000000000000..1efdf0088ecd --- /dev/null +++ b/sound/soc/qcom/apq8016_sbc.c | |||
@@ -0,0 +1,198 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015 The Linux Foundation. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 and | ||
6 | * only version 2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/device.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/of.h> | ||
20 | #include <linux/clk.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <sound/pcm.h> | ||
23 | #include <sound/pcm_params.h> | ||
24 | #include <sound/soc.h> | ||
25 | #include <dt-bindings/sound/apq8016-lpass.h> | ||
26 | |||
27 | struct apq8016_sbc_data { | ||
28 | void __iomem *mic_iomux; | ||
29 | void __iomem *spkr_iomux; | ||
30 | struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ | ||
31 | }; | ||
32 | |||
33 | #define MIC_CTRL_QUA_WS_SLAVE_SEL_10 BIT(17) | ||
34 | #define MIC_CTRL_TLMM_SCLK_EN BIT(1) | ||
35 | #define SPKR_CTL_PRI_WS_SLAVE_SEL_11 (BIT(17) | BIT(16)) | ||
36 | |||
37 | static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd) | ||
38 | { | ||
39 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
40 | struct snd_soc_card *card = rtd->card; | ||
41 | struct apq8016_sbc_data *pdata = snd_soc_card_get_drvdata(card); | ||
42 | int rval = 0; | ||
43 | |||
44 | switch (cpu_dai->id) { | ||
45 | case MI2S_PRIMARY: | ||
46 | writel(readl(pdata->spkr_iomux) | SPKR_CTL_PRI_WS_SLAVE_SEL_11, | ||
47 | pdata->spkr_iomux); | ||
48 | break; | ||
49 | |||
50 | case MI2S_QUATERNARY: | ||
51 | /* Configure the Quat MI2S to TLMM */ | ||
52 | writel(readl(pdata->mic_iomux) | MIC_CTRL_QUA_WS_SLAVE_SEL_10 | | ||
53 | MIC_CTRL_TLMM_SCLK_EN, | ||
54 | pdata->mic_iomux); | ||
55 | break; | ||
56 | |||
57 | default: | ||
58 | dev_err(card->dev, "unsupported cpu dai configuration\n"); | ||
59 | rval = -EINVAL; | ||
60 | break; | ||
61 | |||
62 | } | ||
63 | |||
64 | return rval; | ||
65 | } | ||
66 | |||
67 | static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card) | ||
68 | { | ||
69 | struct device *dev = card->dev; | ||
70 | struct snd_soc_dai_link *link; | ||
71 | struct device_node *np, *codec, *cpu, *node = dev->of_node; | ||
72 | struct apq8016_sbc_data *data; | ||
73 | int ret, num_links; | ||
74 | |||
75 | ret = snd_soc_of_parse_card_name(card, "qcom,model"); | ||
76 | if (ret) { | ||
77 | dev_err(dev, "Error parsing card name: %d\n", ret); | ||
78 | return ERR_PTR(ret); | ||
79 | } | ||
80 | |||
81 | /* Populate links */ | ||
82 | num_links = of_get_child_count(node); | ||
83 | |||
84 | /* Allocate the private data and the DAI link array */ | ||
85 | data = devm_kzalloc(dev, sizeof(*data) + sizeof(*link) * num_links, | ||
86 | GFP_KERNEL); | ||
87 | if (!data) | ||
88 | return ERR_PTR(-ENOMEM); | ||
89 | |||
90 | card->dai_link = &data->dai_link[0]; | ||
91 | card->num_links = num_links; | ||
92 | |||
93 | link = data->dai_link; | ||
94 | |||
95 | for_each_child_of_node(node, np) { | ||
96 | cpu = of_get_child_by_name(np, "cpu"); | ||
97 | codec = of_get_child_by_name(np, "codec"); | ||
98 | |||
99 | if (!cpu || !codec) { | ||
100 | dev_err(dev, "Can't find cpu/codec DT node\n"); | ||
101 | return ERR_PTR(-EINVAL); | ||
102 | } | ||
103 | |||
104 | link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0); | ||
105 | if (!link->cpu_of_node) { | ||
106 | dev_err(card->dev, "error getting cpu phandle\n"); | ||
107 | return ERR_PTR(-EINVAL); | ||
108 | } | ||
109 | |||
110 | link->codec_of_node = of_parse_phandle(codec, "sound-dai", 0); | ||
111 | if (!link->codec_of_node) { | ||
112 | dev_err(card->dev, "error getting codec phandle\n"); | ||
113 | return ERR_PTR(-EINVAL); | ||
114 | } | ||
115 | |||
116 | ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name); | ||
117 | if (ret) { | ||
118 | dev_err(card->dev, "error getting cpu dai name\n"); | ||
119 | return ERR_PTR(ret); | ||
120 | } | ||
121 | |||
122 | ret = snd_soc_of_get_dai_name(codec, &link->codec_dai_name); | ||
123 | if (ret) { | ||
124 | dev_err(card->dev, "error getting codec dai name\n"); | ||
125 | return ERR_PTR(ret); | ||
126 | } | ||
127 | |||
128 | link->platform_of_node = link->cpu_of_node; | ||
129 | /* For now we only support playback */ | ||
130 | link->playback_only = true; | ||
131 | |||
132 | ret = of_property_read_string(np, "link-name", &link->name); | ||
133 | if (ret) { | ||
134 | dev_err(card->dev, "error getting codec dai_link name\n"); | ||
135 | return ERR_PTR(ret); | ||
136 | } | ||
137 | |||
138 | link->stream_name = link->name; | ||
139 | link->init = apq8016_sbc_dai_init; | ||
140 | link++; | ||
141 | } | ||
142 | |||
143 | return data; | ||
144 | } | ||
145 | |||
146 | static int apq8016_sbc_platform_probe(struct platform_device *pdev) | ||
147 | { | ||
148 | struct device *dev = &pdev->dev; | ||
149 | struct snd_soc_card *card; | ||
150 | struct apq8016_sbc_data *data; | ||
151 | struct resource *res; | ||
152 | |||
153 | card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); | ||
154 | if (!card) | ||
155 | return -ENOMEM; | ||
156 | |||
157 | card->dev = dev; | ||
158 | data = apq8016_sbc_parse_of(card); | ||
159 | if (IS_ERR(data)) { | ||
160 | dev_err(&pdev->dev, "Error resolving dai links: %ld\n", | ||
161 | PTR_ERR(data)); | ||
162 | return PTR_ERR(data); | ||
163 | } | ||
164 | |||
165 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mic-iomux"); | ||
166 | data->mic_iomux = devm_ioremap_resource(dev, res); | ||
167 | if (IS_ERR(data->mic_iomux)) | ||
168 | return PTR_ERR(data->mic_iomux); | ||
169 | |||
170 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "spkr-iomux"); | ||
171 | data->spkr_iomux = devm_ioremap_resource(dev, res); | ||
172 | if (IS_ERR(data->spkr_iomux)) | ||
173 | return PTR_ERR(data->spkr_iomux); | ||
174 | |||
175 | platform_set_drvdata(pdev, data); | ||
176 | snd_soc_card_set_drvdata(card, data); | ||
177 | |||
178 | return devm_snd_soc_register_card(&pdev->dev, card); | ||
179 | } | ||
180 | |||
181 | static const struct of_device_id apq8016_sbc_device_id[] = { | ||
182 | { .compatible = "qcom,apq8016-sbc-sndcard" }, | ||
183 | {}, | ||
184 | }; | ||
185 | MODULE_DEVICE_TABLE(of, apq8016_sbc_device_id); | ||
186 | |||
187 | static struct platform_driver apq8016_sbc_platform_driver = { | ||
188 | .driver = { | ||
189 | .name = "qcom-apq8016-sbc", | ||
190 | .of_match_table = of_match_ptr(apq8016_sbc_device_id), | ||
191 | }, | ||
192 | .probe = apq8016_sbc_platform_probe, | ||
193 | }; | ||
194 | module_platform_driver(apq8016_sbc_platform_driver); | ||
195 | |||
196 | MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org"); | ||
197 | MODULE_DESCRIPTION("APQ8016 ASoC Machine Driver"); | ||
198 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/qcom/storm.c b/sound/soc/qcom/storm.c index b8bd296190ad..2d833bffdba0 100644 --- a/sound/soc/qcom/storm.c +++ b/sound/soc/qcom/storm.c | |||
@@ -69,11 +69,6 @@ static struct snd_soc_dai_link storm_dai_link = { | |||
69 | .ops = &storm_soc_ops, | 69 | .ops = &storm_soc_ops, |
70 | }; | 70 | }; |
71 | 71 | ||
72 | static struct snd_soc_card storm_soc_card = { | ||
73 | .name = "ipq806x-storm", | ||
74 | .dev = NULL, | ||
75 | }; | ||
76 | |||
77 | static int storm_parse_of(struct snd_soc_card *card) | 72 | static int storm_parse_of(struct snd_soc_card *card) |
78 | { | 73 | { |
79 | struct snd_soc_dai_link *dai_link = card->dai_link; | 74 | struct snd_soc_dai_link *dai_link = card->dai_link; |
@@ -99,14 +94,13 @@ static int storm_parse_of(struct snd_soc_card *card) | |||
99 | 94 | ||
100 | static int storm_platform_probe(struct platform_device *pdev) | 95 | static int storm_platform_probe(struct platform_device *pdev) |
101 | { | 96 | { |
102 | struct snd_soc_card *card = &storm_soc_card; | 97 | struct snd_soc_card *card; |
103 | int ret; | 98 | int ret; |
104 | 99 | ||
105 | if (card->dev) { | 100 | card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL); |
106 | dev_err(&pdev->dev, "%s() error, existing soundcard\n", | 101 | if (!card) |
107 | __func__); | 102 | return -ENOMEM; |
108 | return -ENODEV; | 103 | |
109 | } | ||
110 | card->dev = &pdev->dev; | 104 | card->dev = &pdev->dev; |
111 | platform_set_drvdata(pdev, card); | 105 | platform_set_drvdata(pdev, card); |
112 | 106 | ||
@@ -128,16 +122,12 @@ static int storm_platform_probe(struct platform_device *pdev) | |||
128 | } | 122 | } |
129 | 123 | ||
130 | ret = devm_snd_soc_register_card(&pdev->dev, card); | 124 | ret = devm_snd_soc_register_card(&pdev->dev, card); |
131 | if (ret == -EPROBE_DEFER) { | 125 | if (ret) |
132 | card->dev = NULL; | ||
133 | return ret; | ||
134 | } else if (ret) { | ||
135 | dev_err(&pdev->dev, "%s() error registering soundcard: %d\n", | 126 | dev_err(&pdev->dev, "%s() error registering soundcard: %d\n", |
136 | __func__, ret); | 127 | __func__, ret); |
137 | return ret; | ||
138 | } | ||
139 | 128 | ||
140 | return 0; | 129 | return ret; |
130 | |||
141 | } | 131 | } |
142 | 132 | ||
143 | #ifdef CONFIG_OF | 133 | #ifdef CONFIG_OF |
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index d460d2aa82ee..f1e5920654f6 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
@@ -137,15 +137,17 @@ char *rsnd_mod_name(struct rsnd_mod *mod) | |||
137 | return mod->ops->name; | 137 | return mod->ops->name; |
138 | } | 138 | } |
139 | 139 | ||
140 | struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod) | 140 | struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io, |
141 | struct rsnd_mod *mod) | ||
141 | { | 142 | { |
142 | if (!mod || !mod->ops || !mod->ops->dma_req) | 143 | if (!mod || !mod->ops || !mod->ops->dma_req) |
143 | return NULL; | 144 | return NULL; |
144 | 145 | ||
145 | return mod->ops->dma_req(mod); | 146 | return mod->ops->dma_req(io, mod); |
146 | } | 147 | } |
147 | 148 | ||
148 | int rsnd_mod_init(struct rsnd_mod *mod, | 149 | int rsnd_mod_init(struct rsnd_priv *priv, |
150 | struct rsnd_mod *mod, | ||
149 | struct rsnd_mod_ops *ops, | 151 | struct rsnd_mod_ops *ops, |
150 | struct clk *clk, | 152 | struct clk *clk, |
151 | enum rsnd_mod_type type, | 153 | enum rsnd_mod_type type, |
@@ -160,6 +162,7 @@ int rsnd_mod_init(struct rsnd_mod *mod, | |||
160 | mod->ops = ops; | 162 | mod->ops = ops; |
161 | mod->type = type; | 163 | mod->type = type; |
162 | mod->clk = clk; | 164 | mod->clk = clk; |
165 | mod->priv = priv; | ||
163 | 166 | ||
164 | return ret; | 167 | return ret; |
165 | } | 168 | } |
@@ -170,10 +173,31 @@ void rsnd_mod_quit(struct rsnd_mod *mod) | |||
170 | clk_unprepare(mod->clk); | 173 | clk_unprepare(mod->clk); |
171 | } | 174 | } |
172 | 175 | ||
173 | int rsnd_mod_is_working(struct rsnd_mod *mod) | 176 | void rsnd_mod_interrupt(struct rsnd_mod *mod, |
177 | void (*callback)(struct rsnd_mod *mod, | ||
178 | struct rsnd_dai_stream *io)) | ||
174 | { | 179 | { |
175 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 180 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
181 | struct rsnd_dai_stream *io; | ||
182 | struct rsnd_dai *rdai; | ||
183 | int i, j; | ||
184 | |||
185 | for_each_rsnd_dai(rdai, priv, j) { | ||
186 | |||
187 | for (i = 0; i < RSND_MOD_MAX; i++) { | ||
188 | io = &rdai->playback; | ||
189 | if (mod == io->mod[i]) | ||
190 | callback(mod, io); | ||
191 | |||
192 | io = &rdai->capture; | ||
193 | if (mod == io->mod[i]) | ||
194 | callback(mod, io); | ||
195 | } | ||
196 | } | ||
197 | } | ||
176 | 198 | ||
199 | int rsnd_io_is_working(struct rsnd_dai_stream *io) | ||
200 | { | ||
177 | /* see rsnd_dai_stream_init/quit() */ | 201 | /* see rsnd_dai_stream_init/quit() */ |
178 | return !!io->substream; | 202 | return !!io->substream; |
179 | } | 203 | } |
@@ -181,10 +205,9 @@ int rsnd_mod_is_working(struct rsnd_mod *mod) | |||
181 | /* | 205 | /* |
182 | * settting function | 206 | * settting function |
183 | */ | 207 | */ |
184 | u32 rsnd_get_adinr(struct rsnd_mod *mod) | 208 | u32 rsnd_get_adinr(struct rsnd_mod *mod, struct rsnd_dai_stream *io) |
185 | { | 209 | { |
186 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 210 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
187 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
188 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 211 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
189 | struct device *dev = rsnd_priv_to_dev(priv); | 212 | struct device *dev = rsnd_priv_to_dev(priv); |
190 | u32 adinr = runtime->channels; | 213 | u32 adinr = runtime->channels; |
@@ -207,26 +230,31 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod) | |||
207 | /* | 230 | /* |
208 | * rsnd_dai functions | 231 | * rsnd_dai functions |
209 | */ | 232 | */ |
210 | #define __rsnd_mod_call(mod, func, param...) \ | 233 | #define __rsnd_mod_call(mod, io, func, param...) \ |
211 | ({ \ | 234 | ({ \ |
212 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ | 235 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ |
213 | struct device *dev = rsnd_priv_to_dev(priv); \ | 236 | struct device *dev = rsnd_priv_to_dev(priv); \ |
214 | u32 mask = (1 << __rsnd_mod_shift_##func) & ~(1 << 31); \ | 237 | u32 mask = 0xF << __rsnd_mod_shift_##func; \ |
215 | u32 call = __rsnd_mod_call_##func << __rsnd_mod_shift_##func; \ | 238 | u8 val = (mod->status >> __rsnd_mod_shift_##func) & 0xF; \ |
239 | u8 add = ((val + __rsnd_mod_add_##func) & 0xF); \ | ||
216 | int ret = 0; \ | 240 | int ret = 0; \ |
217 | if ((mod->status & mask) == call) { \ | 241 | int called = 0; \ |
218 | dev_dbg(dev, "%s[%d] %s\n", \ | 242 | if (val == __rsnd_mod_call_##func) { \ |
219 | rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \ | 243 | called = 1; \ |
220 | ret = (mod)->ops->func(mod, param); \ | 244 | ret = (mod)->ops->func(mod, io, param); \ |
221 | mod->status = (mod->status & ~mask) | (~call & mask); \ | 245 | mod->status = (mod->status & ~mask) + \ |
246 | (add << __rsnd_mod_shift_##func); \ | ||
222 | } \ | 247 | } \ |
248 | dev_dbg(dev, "%s[%d] 0x%08x %s\n", \ | ||
249 | rsnd_mod_name(mod), rsnd_mod_id(mod), mod->status, \ | ||
250 | called ? #func : ""); \ | ||
223 | ret; \ | 251 | ret; \ |
224 | }) | 252 | }) |
225 | 253 | ||
226 | #define rsnd_mod_call(mod, func, param...) \ | 254 | #define rsnd_mod_call(mod, io, func, param...) \ |
227 | (!(mod) ? -ENODEV : \ | 255 | (!(mod) ? -ENODEV : \ |
228 | !((mod)->ops->func) ? 0 : \ | 256 | !((mod)->ops->func) ? 0 : \ |
229 | __rsnd_mod_call(mod, func, param)) | 257 | __rsnd_mod_call(mod, io, func, param)) |
230 | 258 | ||
231 | #define rsnd_dai_call(fn, io, param...) \ | 259 | #define rsnd_dai_call(fn, io, param...) \ |
232 | ({ \ | 260 | ({ \ |
@@ -236,7 +264,7 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod) | |||
236 | mod = (io)->mod[i]; \ | 264 | mod = (io)->mod[i]; \ |
237 | if (!mod) \ | 265 | if (!mod) \ |
238 | continue; \ | 266 | continue; \ |
239 | ret = rsnd_mod_call(mod, fn, param); \ | 267 | ret = rsnd_mod_call(mod, io, fn, param); \ |
240 | if (ret < 0) \ | 268 | if (ret < 0) \ |
241 | break; \ | 269 | break; \ |
242 | } \ | 270 | } \ |
@@ -260,7 +288,6 @@ static int rsnd_dai_connect(struct rsnd_mod *mod, | |||
260 | } | 288 | } |
261 | 289 | ||
262 | io->mod[mod->type] = mod; | 290 | io->mod[mod->type] = mod; |
263 | mod->io = io; | ||
264 | 291 | ||
265 | return 0; | 292 | return 0; |
266 | } | 293 | } |
@@ -268,7 +295,6 @@ static int rsnd_dai_connect(struct rsnd_mod *mod, | |||
268 | static void rsnd_dai_disconnect(struct rsnd_mod *mod, | 295 | static void rsnd_dai_disconnect(struct rsnd_mod *mod, |
269 | struct rsnd_dai_stream *io) | 296 | struct rsnd_dai_stream *io) |
270 | { | 297 | { |
271 | mod->io = NULL; | ||
272 | io->mod[mod->type] = NULL; | 298 | io->mod[mod->type] = NULL; |
273 | } | 299 | } |
274 | 300 | ||
@@ -302,7 +328,7 @@ int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional) | |||
302 | return pos; | 328 | return pos; |
303 | } | 329 | } |
304 | 330 | ||
305 | void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int byte) | 331 | bool rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int byte) |
306 | { | 332 | { |
307 | io->byte_pos += byte; | 333 | io->byte_pos += byte; |
308 | 334 | ||
@@ -319,8 +345,24 @@ void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int byte) | |||
319 | io->next_period_byte = io->byte_per_period; | 345 | io->next_period_byte = io->byte_per_period; |
320 | } | 346 | } |
321 | 347 | ||
322 | snd_pcm_period_elapsed(substream); | 348 | return true; |
323 | } | 349 | } |
350 | |||
351 | return false; | ||
352 | } | ||
353 | |||
354 | void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io) | ||
355 | { | ||
356 | struct snd_pcm_substream *substream = io->substream; | ||
357 | |||
358 | /* | ||
359 | * this function should be called... | ||
360 | * | ||
361 | * - if rsnd_dai_pointer_update() returns true | ||
362 | * - without spin lock | ||
363 | */ | ||
364 | |||
365 | snd_pcm_period_elapsed(substream); | ||
324 | } | 366 | } |
325 | 367 | ||
326 | static void rsnd_dai_stream_init(struct rsnd_dai_stream *io, | 368 | static void rsnd_dai_stream_init(struct rsnd_dai_stream *io, |
@@ -834,16 +876,18 @@ static int rsnd_kctrl_put(struct snd_kcontrol *kctrl, | |||
834 | } | 876 | } |
835 | 877 | ||
836 | if (change) | 878 | if (change) |
837 | cfg->update(mod); | 879 | cfg->update(cfg->io, mod); |
838 | 880 | ||
839 | return change; | 881 | return change; |
840 | } | 882 | } |
841 | 883 | ||
842 | static int __rsnd_kctrl_new(struct rsnd_mod *mod, | 884 | static int __rsnd_kctrl_new(struct rsnd_mod *mod, |
885 | struct rsnd_dai_stream *io, | ||
843 | struct snd_soc_pcm_runtime *rtd, | 886 | struct snd_soc_pcm_runtime *rtd, |
844 | const unsigned char *name, | 887 | const unsigned char *name, |
845 | struct rsnd_kctrl_cfg *cfg, | 888 | struct rsnd_kctrl_cfg *cfg, |
846 | void (*update)(struct rsnd_mod *mod)) | 889 | void (*update)(struct rsnd_dai_stream *io, |
890 | struct rsnd_mod *mod)) | ||
847 | { | 891 | { |
848 | struct snd_soc_card *soc_card = rtd->card; | 892 | struct snd_soc_card *soc_card = rtd->card; |
849 | struct snd_card *card = rtd->card->snd_card; | 893 | struct snd_card *card = rtd->card->snd_card; |
@@ -872,6 +916,7 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod, | |||
872 | cfg->update = update; | 916 | cfg->update = update; |
873 | cfg->card = card; | 917 | cfg->card = card; |
874 | cfg->kctrl = kctrl; | 918 | cfg->kctrl = kctrl; |
919 | cfg->io = io; | ||
875 | 920 | ||
876 | return 0; | 921 | return 0; |
877 | } | 922 | } |
@@ -882,36 +927,42 @@ void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg) | |||
882 | } | 927 | } |
883 | 928 | ||
884 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, | 929 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, |
930 | struct rsnd_dai_stream *io, | ||
885 | struct snd_soc_pcm_runtime *rtd, | 931 | struct snd_soc_pcm_runtime *rtd, |
886 | const unsigned char *name, | 932 | const unsigned char *name, |
887 | void (*update)(struct rsnd_mod *mod), | 933 | void (*update)(struct rsnd_dai_stream *io, |
934 | struct rsnd_mod *mod), | ||
888 | struct rsnd_kctrl_cfg_m *_cfg, | 935 | struct rsnd_kctrl_cfg_m *_cfg, |
889 | u32 max) | 936 | u32 max) |
890 | { | 937 | { |
891 | _cfg->cfg.max = max; | 938 | _cfg->cfg.max = max; |
892 | _cfg->cfg.size = RSND_DVC_CHANNELS; | 939 | _cfg->cfg.size = RSND_DVC_CHANNELS; |
893 | _cfg->cfg.val = _cfg->val; | 940 | _cfg->cfg.val = _cfg->val; |
894 | return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update); | 941 | return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update); |
895 | } | 942 | } |
896 | 943 | ||
897 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, | 944 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, |
945 | struct rsnd_dai_stream *io, | ||
898 | struct snd_soc_pcm_runtime *rtd, | 946 | struct snd_soc_pcm_runtime *rtd, |
899 | const unsigned char *name, | 947 | const unsigned char *name, |
900 | void (*update)(struct rsnd_mod *mod), | 948 | void (*update)(struct rsnd_dai_stream *io, |
949 | struct rsnd_mod *mod), | ||
901 | struct rsnd_kctrl_cfg_s *_cfg, | 950 | struct rsnd_kctrl_cfg_s *_cfg, |
902 | u32 max) | 951 | u32 max) |
903 | { | 952 | { |
904 | _cfg->cfg.max = max; | 953 | _cfg->cfg.max = max; |
905 | _cfg->cfg.size = 1; | 954 | _cfg->cfg.size = 1; |
906 | _cfg->cfg.val = &_cfg->val; | 955 | _cfg->cfg.val = &_cfg->val; |
907 | return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update); | 956 | return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update); |
908 | } | 957 | } |
909 | 958 | ||
910 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, | 959 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, |
960 | struct rsnd_dai_stream *io, | ||
911 | struct snd_soc_pcm_runtime *rtd, | 961 | struct snd_soc_pcm_runtime *rtd, |
912 | const unsigned char *name, | 962 | const unsigned char *name, |
913 | struct rsnd_kctrl_cfg_s *_cfg, | 963 | struct rsnd_kctrl_cfg_s *_cfg, |
914 | void (*update)(struct rsnd_mod *mod), | 964 | void (*update)(struct rsnd_dai_stream *io, |
965 | struct rsnd_mod *mod), | ||
915 | const char * const *texts, | 966 | const char * const *texts, |
916 | u32 max) | 967 | u32 max) |
917 | { | 968 | { |
@@ -919,7 +970,7 @@ int rsnd_kctrl_new_e(struct rsnd_mod *mod, | |||
919 | _cfg->cfg.size = 1; | 970 | _cfg->cfg.size = 1; |
920 | _cfg->cfg.val = &_cfg->val; | 971 | _cfg->cfg.val = &_cfg->val; |
921 | _cfg->cfg.texts = texts; | 972 | _cfg->cfg.texts = texts; |
922 | return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update); | 973 | return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update); |
923 | } | 974 | } |
924 | 975 | ||
925 | /* | 976 | /* |
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 144308f15fb3..d306e298c63d 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c | |||
@@ -32,11 +32,12 @@ struct rsnd_dma_ctrl { | |||
32 | /* | 32 | /* |
33 | * Audio DMAC | 33 | * Audio DMAC |
34 | */ | 34 | */ |
35 | static void rsnd_dmaen_complete(void *data) | 35 | static void __rsnd_dmaen_complete(struct rsnd_mod *mod, |
36 | struct rsnd_dai_stream *io) | ||
36 | { | 37 | { |
37 | struct rsnd_dma *dma = (struct rsnd_dma *)data; | 38 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
38 | struct rsnd_mod *mod = rsnd_dma_to_mod(dma); | 39 | bool elapsed = false; |
39 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 40 | unsigned long flags; |
40 | 41 | ||
41 | /* | 42 | /* |
42 | * Renesas sound Gen1 needs 1 DMAC, | 43 | * Renesas sound Gen1 needs 1 DMAC, |
@@ -49,23 +50,36 @@ static void rsnd_dmaen_complete(void *data) | |||
49 | * rsnd_dai_pointer_update() will be called twice, | 50 | * rsnd_dai_pointer_update() will be called twice, |
50 | * ant it will breaks io->byte_pos | 51 | * ant it will breaks io->byte_pos |
51 | */ | 52 | */ |
53 | spin_lock_irqsave(&priv->lock, flags); | ||
54 | |||
55 | if (rsnd_io_is_working(io)) | ||
56 | elapsed = rsnd_dai_pointer_update(io, io->byte_per_period); | ||
52 | 57 | ||
53 | rsnd_dai_pointer_update(io, io->byte_per_period); | 58 | spin_unlock_irqrestore(&priv->lock, flags); |
59 | |||
60 | if (elapsed) | ||
61 | rsnd_dai_period_elapsed(io); | ||
54 | } | 62 | } |
55 | 63 | ||
56 | static void rsnd_dmaen_stop(struct rsnd_dma *dma) | 64 | static void rsnd_dmaen_complete(void *data) |
65 | { | ||
66 | struct rsnd_mod *mod = data; | ||
67 | |||
68 | rsnd_mod_interrupt(mod, __rsnd_dmaen_complete); | ||
69 | } | ||
70 | |||
71 | static void rsnd_dmaen_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) | ||
57 | { | 72 | { |
58 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); | 73 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); |
59 | 74 | ||
60 | dmaengine_terminate_all(dmaen->chan); | 75 | dmaengine_terminate_all(dmaen->chan); |
61 | } | 76 | } |
62 | 77 | ||
63 | static void rsnd_dmaen_start(struct rsnd_dma *dma) | 78 | static void rsnd_dmaen_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma) |
64 | { | 79 | { |
65 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); | 80 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); |
66 | struct rsnd_mod *mod = rsnd_dma_to_mod(dma); | 81 | struct rsnd_mod *mod = rsnd_dma_to_mod(dma); |
67 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 82 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
68 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
69 | struct snd_pcm_substream *substream = io->substream; | 83 | struct snd_pcm_substream *substream = io->substream; |
70 | struct device *dev = rsnd_priv_to_dev(priv); | 84 | struct device *dev = rsnd_priv_to_dev(priv); |
71 | struct dma_async_tx_descriptor *desc; | 85 | struct dma_async_tx_descriptor *desc; |
@@ -84,7 +98,7 @@ static void rsnd_dmaen_start(struct rsnd_dma *dma) | |||
84 | } | 98 | } |
85 | 99 | ||
86 | desc->callback = rsnd_dmaen_complete; | 100 | desc->callback = rsnd_dmaen_complete; |
87 | desc->callback_param = dma; | 101 | desc->callback_param = mod; |
88 | 102 | ||
89 | if (dmaengine_submit(desc) < 0) { | 103 | if (dmaengine_submit(desc) < 0) { |
90 | dev_err(dev, "dmaengine_submit() fail\n"); | 104 | dev_err(dev, "dmaengine_submit() fail\n"); |
@@ -115,7 +129,8 @@ struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, | |||
115 | return chan; | 129 | return chan; |
116 | } | 130 | } |
117 | 131 | ||
118 | static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_mod *mod_from, | 132 | static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_dai_stream *io, |
133 | struct rsnd_mod *mod_from, | ||
119 | struct rsnd_mod *mod_to) | 134 | struct rsnd_mod *mod_to) |
120 | { | 135 | { |
121 | if ((!mod_from && !mod_to) || | 136 | if ((!mod_from && !mod_to) || |
@@ -123,19 +138,19 @@ static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_mod *mod_from, | |||
123 | return NULL; | 138 | return NULL; |
124 | 139 | ||
125 | if (mod_from) | 140 | if (mod_from) |
126 | return rsnd_mod_dma_req(mod_from); | 141 | return rsnd_mod_dma_req(io, mod_from); |
127 | else | 142 | else |
128 | return rsnd_mod_dma_req(mod_to); | 143 | return rsnd_mod_dma_req(io, mod_to); |
129 | } | 144 | } |
130 | 145 | ||
131 | static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, | 146 | static int rsnd_dmaen_init(struct rsnd_dai_stream *io, |
147 | struct rsnd_dma *dma, int id, | ||
132 | struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) | 148 | struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) |
133 | { | 149 | { |
134 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); | 150 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); |
151 | struct rsnd_priv *priv = rsnd_io_to_priv(io); | ||
135 | struct device *dev = rsnd_priv_to_dev(priv); | 152 | struct device *dev = rsnd_priv_to_dev(priv); |
136 | struct dma_slave_config cfg = {}; | 153 | struct dma_slave_config cfg = {}; |
137 | struct rsnd_mod *mod = rsnd_dma_to_mod(dma); | ||
138 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
139 | int is_play = rsnd_io_is_play(io); | 154 | int is_play = rsnd_io_is_play(io); |
140 | int ret; | 155 | int ret; |
141 | 156 | ||
@@ -145,7 +160,7 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, | |||
145 | } | 160 | } |
146 | 161 | ||
147 | if (dev->of_node) { | 162 | if (dev->of_node) { |
148 | dmaen->chan = rsnd_dmaen_request_channel(mod_from, mod_to); | 163 | dmaen->chan = rsnd_dmaen_request_channel(io, mod_from, mod_to); |
149 | } else { | 164 | } else { |
150 | dma_cap_mask_t mask; | 165 | dma_cap_mask_t mask; |
151 | 166 | ||
@@ -177,7 +192,7 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, | |||
177 | return 0; | 192 | return 0; |
178 | 193 | ||
179 | rsnd_dma_init_err: | 194 | rsnd_dma_init_err: |
180 | rsnd_dma_quit(dma); | 195 | rsnd_dma_quit(io, dma); |
181 | rsnd_dma_channel_err: | 196 | rsnd_dma_channel_err: |
182 | 197 | ||
183 | /* | 198 | /* |
@@ -189,7 +204,7 @@ rsnd_dma_channel_err: | |||
189 | return -EAGAIN; | 204 | return -EAGAIN; |
190 | } | 205 | } |
191 | 206 | ||
192 | static void rsnd_dmaen_quit(struct rsnd_dma *dma) | 207 | static void rsnd_dmaen_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma) |
193 | { | 208 | { |
194 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); | 209 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); |
195 | 210 | ||
@@ -238,9 +253,9 @@ static const u8 gen2_id_table_cmd[] = { | |||
238 | 0x38, /* SCU_CMD1 */ | 253 | 0x38, /* SCU_CMD1 */ |
239 | }; | 254 | }; |
240 | 255 | ||
241 | static u32 rsnd_dmapp_get_id(struct rsnd_mod *mod) | 256 | static u32 rsnd_dmapp_get_id(struct rsnd_dai_stream *io, |
257 | struct rsnd_mod *mod) | ||
242 | { | 258 | { |
243 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
244 | struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); | 259 | struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); |
245 | struct rsnd_mod *src = rsnd_io_to_mod_src(io); | 260 | struct rsnd_mod *src = rsnd_io_to_mod_src(io); |
246 | struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); | 261 | struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); |
@@ -268,11 +283,12 @@ static u32 rsnd_dmapp_get_id(struct rsnd_mod *mod) | |||
268 | return entry[id]; | 283 | return entry[id]; |
269 | } | 284 | } |
270 | 285 | ||
271 | static u32 rsnd_dmapp_get_chcr(struct rsnd_mod *mod_from, | 286 | static u32 rsnd_dmapp_get_chcr(struct rsnd_dai_stream *io, |
287 | struct rsnd_mod *mod_from, | ||
272 | struct rsnd_mod *mod_to) | 288 | struct rsnd_mod *mod_to) |
273 | { | 289 | { |
274 | return (rsnd_dmapp_get_id(mod_from) << 24) + | 290 | return (rsnd_dmapp_get_id(io, mod_from) << 24) + |
275 | (rsnd_dmapp_get_id(mod_to) << 16); | 291 | (rsnd_dmapp_get_id(io, mod_to) << 16); |
276 | } | 292 | } |
277 | 293 | ||
278 | #define rsnd_dmapp_addr(dmac, dma, reg) \ | 294 | #define rsnd_dmapp_addr(dmac, dma, reg) \ |
@@ -299,7 +315,7 @@ static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg) | |||
299 | return ioread32(rsnd_dmapp_addr(dmac, dma, reg)); | 315 | return ioread32(rsnd_dmapp_addr(dmac, dma, reg)); |
300 | } | 316 | } |
301 | 317 | ||
302 | static void rsnd_dmapp_stop(struct rsnd_dma *dma) | 318 | static void rsnd_dmapp_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) |
303 | { | 319 | { |
304 | int i; | 320 | int i; |
305 | 321 | ||
@@ -312,7 +328,7 @@ static void rsnd_dmapp_stop(struct rsnd_dma *dma) | |||
312 | } | 328 | } |
313 | } | 329 | } |
314 | 330 | ||
315 | static void rsnd_dmapp_start(struct rsnd_dma *dma) | 331 | static void rsnd_dmapp_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma) |
316 | { | 332 | { |
317 | struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); | 333 | struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); |
318 | 334 | ||
@@ -321,19 +337,21 @@ static void rsnd_dmapp_start(struct rsnd_dma *dma) | |||
321 | rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR); | 337 | rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR); |
322 | } | 338 | } |
323 | 339 | ||
324 | static int rsnd_dmapp_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, | 340 | static int rsnd_dmapp_init(struct rsnd_dai_stream *io, |
341 | struct rsnd_dma *dma, int id, | ||
325 | struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) | 342 | struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) |
326 | { | 343 | { |
327 | struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); | 344 | struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); |
345 | struct rsnd_priv *priv = rsnd_io_to_priv(io); | ||
328 | struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); | 346 | struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); |
329 | struct device *dev = rsnd_priv_to_dev(priv); | 347 | struct device *dev = rsnd_priv_to_dev(priv); |
330 | 348 | ||
331 | dmapp->dmapp_id = dmac->dmapp_num; | 349 | dmapp->dmapp_id = dmac->dmapp_num; |
332 | dmapp->chcr = rsnd_dmapp_get_chcr(mod_from, mod_to) | PDMACHCR_DE; | 350 | dmapp->chcr = rsnd_dmapp_get_chcr(io, mod_from, mod_to) | PDMACHCR_DE; |
333 | 351 | ||
334 | dmac->dmapp_num++; | 352 | dmac->dmapp_num++; |
335 | 353 | ||
336 | rsnd_dmapp_stop(dma); | 354 | rsnd_dmapp_stop(io, dma); |
337 | 355 | ||
338 | dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n", | 356 | dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n", |
339 | dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr); | 357 | dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr); |
@@ -386,12 +404,12 @@ static struct rsnd_dma_ops rsnd_dmapp_ops = { | |||
386 | #define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i)) | 404 | #define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i)) |
387 | 405 | ||
388 | static dma_addr_t | 406 | static dma_addr_t |
389 | rsnd_gen2_dma_addr(struct rsnd_priv *priv, | 407 | rsnd_gen2_dma_addr(struct rsnd_dai_stream *io, |
390 | struct rsnd_mod *mod, | 408 | struct rsnd_mod *mod, |
391 | int is_play, int is_from) | 409 | int is_play, int is_from) |
392 | { | 410 | { |
411 | struct rsnd_priv *priv = rsnd_io_to_priv(io); | ||
393 | struct device *dev = rsnd_priv_to_dev(priv); | 412 | struct device *dev = rsnd_priv_to_dev(priv); |
394 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
395 | phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI); | 413 | phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI); |
396 | phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU); | 414 | phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU); |
397 | int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod); | 415 | int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod); |
@@ -438,7 +456,7 @@ rsnd_gen2_dma_addr(struct rsnd_priv *priv, | |||
438 | dev_err(dev, "DVC is selected without SRC\n"); | 456 | dev_err(dev, "DVC is selected without SRC\n"); |
439 | 457 | ||
440 | /* use SSIU or SSI ? */ | 458 | /* use SSIU or SSI ? */ |
441 | if (is_ssi && rsnd_ssi_use_busif(mod)) | 459 | if (is_ssi && rsnd_ssi_use_busif(io, mod)) |
442 | is_ssi++; | 460 | is_ssi++; |
443 | 461 | ||
444 | return (is_from) ? | 462 | return (is_from) ? |
@@ -446,10 +464,12 @@ rsnd_gen2_dma_addr(struct rsnd_priv *priv, | |||
446 | dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr; | 464 | dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr; |
447 | } | 465 | } |
448 | 466 | ||
449 | static dma_addr_t rsnd_dma_addr(struct rsnd_priv *priv, | 467 | static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io, |
450 | struct rsnd_mod *mod, | 468 | struct rsnd_mod *mod, |
451 | int is_play, int is_from) | 469 | int is_play, int is_from) |
452 | { | 470 | { |
471 | struct rsnd_priv *priv = rsnd_io_to_priv(io); | ||
472 | |||
453 | /* | 473 | /* |
454 | * gen1 uses default DMA addr | 474 | * gen1 uses default DMA addr |
455 | */ | 475 | */ |
@@ -459,17 +479,17 @@ static dma_addr_t rsnd_dma_addr(struct rsnd_priv *priv, | |||
459 | if (!mod) | 479 | if (!mod) |
460 | return 0; | 480 | return 0; |
461 | 481 | ||
462 | return rsnd_gen2_dma_addr(priv, mod, is_play, is_from); | 482 | return rsnd_gen2_dma_addr(io, mod, is_play, is_from); |
463 | } | 483 | } |
464 | 484 | ||
465 | #define MOD_MAX 4 /* MEM/SSI/SRC/DVC */ | 485 | #define MOD_MAX 4 /* MEM/SSI/SRC/DVC */ |
466 | static void rsnd_dma_of_path(struct rsnd_dma *dma, | 486 | static void rsnd_dma_of_path(struct rsnd_dma *dma, |
487 | struct rsnd_dai_stream *io, | ||
467 | int is_play, | 488 | int is_play, |
468 | struct rsnd_mod **mod_from, | 489 | struct rsnd_mod **mod_from, |
469 | struct rsnd_mod **mod_to) | 490 | struct rsnd_mod **mod_to) |
470 | { | 491 | { |
471 | struct rsnd_mod *this = rsnd_dma_to_mod(dma); | 492 | struct rsnd_mod *this = rsnd_dma_to_mod(dma); |
472 | struct rsnd_dai_stream *io = rsnd_mod_to_io(this); | ||
473 | struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); | 493 | struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); |
474 | struct rsnd_mod *src = rsnd_io_to_mod_src(io); | 494 | struct rsnd_mod *src = rsnd_io_to_mod_src(io); |
475 | struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); | 495 | struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); |
@@ -524,17 +544,17 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma, | |||
524 | } | 544 | } |
525 | } | 545 | } |
526 | 546 | ||
527 | void rsnd_dma_stop(struct rsnd_dma *dma) | 547 | void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) |
528 | { | 548 | { |
529 | dma->ops->stop(dma); | 549 | dma->ops->stop(io, dma); |
530 | } | 550 | } |
531 | 551 | ||
532 | void rsnd_dma_start(struct rsnd_dma *dma) | 552 | void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma) |
533 | { | 553 | { |
534 | dma->ops->start(dma); | 554 | dma->ops->start(io, dma); |
535 | } | 555 | } |
536 | 556 | ||
537 | void rsnd_dma_quit(struct rsnd_dma *dma) | 557 | void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma) |
538 | { | 558 | { |
539 | struct rsnd_mod *mod = rsnd_dma_to_mod(dma); | 559 | struct rsnd_mod *mod = rsnd_dma_to_mod(dma); |
540 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 560 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
@@ -543,15 +563,14 @@ void rsnd_dma_quit(struct rsnd_dma *dma) | |||
543 | if (!dmac) | 563 | if (!dmac) |
544 | return; | 564 | return; |
545 | 565 | ||
546 | dma->ops->quit(dma); | 566 | dma->ops->quit(io, dma); |
547 | } | 567 | } |
548 | 568 | ||
549 | int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) | 569 | int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id) |
550 | { | 570 | { |
551 | struct rsnd_mod *mod = rsnd_dma_to_mod(dma); | ||
552 | struct rsnd_mod *mod_from; | 571 | struct rsnd_mod *mod_from; |
553 | struct rsnd_mod *mod_to; | 572 | struct rsnd_mod *mod_to; |
554 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 573 | struct rsnd_priv *priv = rsnd_io_to_priv(io); |
555 | struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); | 574 | struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); |
556 | int is_play = rsnd_io_is_play(io); | 575 | int is_play = rsnd_io_is_play(io); |
557 | 576 | ||
@@ -564,10 +583,10 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) | |||
564 | if (!dmac) | 583 | if (!dmac) |
565 | return -EAGAIN; | 584 | return -EAGAIN; |
566 | 585 | ||
567 | rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to); | 586 | rsnd_dma_of_path(dma, io, is_play, &mod_from, &mod_to); |
568 | 587 | ||
569 | dma->src_addr = rsnd_dma_addr(priv, mod_from, is_play, 1); | 588 | dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1); |
570 | dma->dst_addr = rsnd_dma_addr(priv, mod_to, is_play, 0); | 589 | dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0); |
571 | 590 | ||
572 | /* for Gen2 */ | 591 | /* for Gen2 */ |
573 | if (mod_from && mod_to) | 592 | if (mod_from && mod_to) |
@@ -579,7 +598,7 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) | |||
579 | if (rsnd_is_gen1(priv)) | 598 | if (rsnd_is_gen1(priv)) |
580 | dma->ops = &rsnd_dmaen_ops; | 599 | dma->ops = &rsnd_dmaen_ops; |
581 | 600 | ||
582 | return dma->ops->init(priv, dma, id, mod_from, mod_to); | 601 | return dma->ops->init(io, dma, id, mod_from, mod_to); |
583 | } | 602 | } |
584 | 603 | ||
585 | int rsnd_dma_probe(struct platform_device *pdev, | 604 | int rsnd_dma_probe(struct platform_device *pdev, |
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index e5fcb062ad77..36fc020cbc18 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c | |||
@@ -63,7 +63,8 @@ static const char * const dvc_ramp_rate[] = { | |||
63 | "0.125 dB/8192 steps", /* 10111 */ | 63 | "0.125 dB/8192 steps", /* 10111 */ |
64 | }; | 64 | }; |
65 | 65 | ||
66 | static void rsnd_dvc_volume_update(struct rsnd_mod *mod) | 66 | static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io, |
67 | struct rsnd_mod *mod) | ||
67 | { | 68 | { |
68 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | 69 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); |
69 | u32 val[RSND_DVC_CHANNELS]; | 70 | u32 val[RSND_DVC_CHANNELS]; |
@@ -120,6 +121,7 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod) | |||
120 | } | 121 | } |
121 | 122 | ||
122 | static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, | 123 | static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, |
124 | struct rsnd_dai_stream *io, | ||
123 | struct rsnd_priv *priv) | 125 | struct rsnd_priv *priv) |
124 | { | 126 | { |
125 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | 127 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); |
@@ -134,9 +136,9 @@ static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, | |||
134 | } | 136 | } |
135 | 137 | ||
136 | static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, | 138 | static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, |
139 | struct rsnd_dai_stream *io, | ||
137 | struct rsnd_priv *priv) | 140 | struct rsnd_priv *priv) |
138 | { | 141 | { |
139 | struct rsnd_dai_stream *io = rsnd_mod_to_io(dvc_mod); | ||
140 | struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); | 142 | struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); |
141 | struct device *dev = rsnd_priv_to_dev(priv); | 143 | struct device *dev = rsnd_priv_to_dev(priv); |
142 | int dvc_id = rsnd_mod_id(dvc_mod); | 144 | int dvc_id = rsnd_mod_id(dvc_mod); |
@@ -168,10 +170,10 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, | |||
168 | 170 | ||
169 | rsnd_mod_write(dvc_mod, DVC_DVUIR, 1); | 171 | rsnd_mod_write(dvc_mod, DVC_DVUIR, 1); |
170 | 172 | ||
171 | rsnd_mod_write(dvc_mod, DVC_ADINR, rsnd_get_adinr(dvc_mod)); | 173 | rsnd_mod_write(dvc_mod, DVC_ADINR, rsnd_get_adinr(dvc_mod, io)); |
172 | 174 | ||
173 | /* ch0/ch1 Volume */ | 175 | /* ch0/ch1 Volume */ |
174 | rsnd_dvc_volume_update(dvc_mod); | 176 | rsnd_dvc_volume_update(io, dvc_mod); |
175 | 177 | ||
176 | rsnd_mod_write(dvc_mod, DVC_DVUIR, 0); | 178 | rsnd_mod_write(dvc_mod, DVC_DVUIR, 0); |
177 | 179 | ||
@@ -181,6 +183,7 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, | |||
181 | } | 183 | } |
182 | 184 | ||
183 | static int rsnd_dvc_quit(struct rsnd_mod *mod, | 185 | static int rsnd_dvc_quit(struct rsnd_mod *mod, |
186 | struct rsnd_dai_stream *io, | ||
184 | struct rsnd_priv *priv) | 187 | struct rsnd_priv *priv) |
185 | { | 188 | { |
186 | rsnd_mod_hw_stop(mod); | 189 | rsnd_mod_hw_stop(mod); |
@@ -189,6 +192,7 @@ static int rsnd_dvc_quit(struct rsnd_mod *mod, | |||
189 | } | 192 | } |
190 | 193 | ||
191 | static int rsnd_dvc_start(struct rsnd_mod *mod, | 194 | static int rsnd_dvc_start(struct rsnd_mod *mod, |
195 | struct rsnd_dai_stream *io, | ||
192 | struct rsnd_priv *priv) | 196 | struct rsnd_priv *priv) |
193 | { | 197 | { |
194 | rsnd_mod_write(mod, CMD_CTRL, 0x10); | 198 | rsnd_mod_write(mod, CMD_CTRL, 0x10); |
@@ -197,6 +201,7 @@ static int rsnd_dvc_start(struct rsnd_mod *mod, | |||
197 | } | 201 | } |
198 | 202 | ||
199 | static int rsnd_dvc_stop(struct rsnd_mod *mod, | 203 | static int rsnd_dvc_stop(struct rsnd_mod *mod, |
204 | struct rsnd_dai_stream *io, | ||
200 | struct rsnd_priv *priv) | 205 | struct rsnd_priv *priv) |
201 | { | 206 | { |
202 | rsnd_mod_write(mod, CMD_CTRL, 0); | 207 | rsnd_mod_write(mod, CMD_CTRL, 0); |
@@ -205,15 +210,15 @@ static int rsnd_dvc_stop(struct rsnd_mod *mod, | |||
205 | } | 210 | } |
206 | 211 | ||
207 | static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | 212 | static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, |
213 | struct rsnd_dai_stream *io, | ||
208 | struct snd_soc_pcm_runtime *rtd) | 214 | struct snd_soc_pcm_runtime *rtd) |
209 | { | 215 | { |
210 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
211 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | 216 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); |
212 | int is_play = rsnd_io_is_play(io); | 217 | int is_play = rsnd_io_is_play(io); |
213 | int ret; | 218 | int ret; |
214 | 219 | ||
215 | /* Volume */ | 220 | /* Volume */ |
216 | ret = rsnd_kctrl_new_m(mod, rtd, | 221 | ret = rsnd_kctrl_new_m(mod, io, rtd, |
217 | is_play ? | 222 | is_play ? |
218 | "DVC Out Playback Volume" : "DVC In Capture Volume", | 223 | "DVC Out Playback Volume" : "DVC In Capture Volume", |
219 | rsnd_dvc_volume_update, | 224 | rsnd_dvc_volume_update, |
@@ -222,7 +227,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
222 | return ret; | 227 | return ret; |
223 | 228 | ||
224 | /* Mute */ | 229 | /* Mute */ |
225 | ret = rsnd_kctrl_new_m(mod, rtd, | 230 | ret = rsnd_kctrl_new_m(mod, io, rtd, |
226 | is_play ? | 231 | is_play ? |
227 | "DVC Out Mute Switch" : "DVC In Mute Switch", | 232 | "DVC Out Mute Switch" : "DVC In Mute Switch", |
228 | rsnd_dvc_volume_update, | 233 | rsnd_dvc_volume_update, |
@@ -231,7 +236,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
231 | return ret; | 236 | return ret; |
232 | 237 | ||
233 | /* Ramp */ | 238 | /* Ramp */ |
234 | ret = rsnd_kctrl_new_s(mod, rtd, | 239 | ret = rsnd_kctrl_new_s(mod, io, rtd, |
235 | is_play ? | 240 | is_play ? |
236 | "DVC Out Ramp Switch" : "DVC In Ramp Switch", | 241 | "DVC Out Ramp Switch" : "DVC In Ramp Switch", |
237 | rsnd_dvc_volume_update, | 242 | rsnd_dvc_volume_update, |
@@ -239,7 +244,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
239 | if (ret < 0) | 244 | if (ret < 0) |
240 | return ret; | 245 | return ret; |
241 | 246 | ||
242 | ret = rsnd_kctrl_new_e(mod, rtd, | 247 | ret = rsnd_kctrl_new_e(mod, io, rtd, |
243 | is_play ? | 248 | is_play ? |
244 | "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate", | 249 | "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate", |
245 | &dvc->rup, | 250 | &dvc->rup, |
@@ -248,7 +253,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
248 | if (ret < 0) | 253 | if (ret < 0) |
249 | return ret; | 254 | return ret; |
250 | 255 | ||
251 | ret = rsnd_kctrl_new_e(mod, rtd, | 256 | ret = rsnd_kctrl_new_e(mod, io, rtd, |
252 | is_play ? | 257 | is_play ? |
253 | "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate", | 258 | "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate", |
254 | &dvc->rdown, | 259 | &dvc->rdown, |
@@ -261,7 +266,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
261 | return 0; | 266 | return 0; |
262 | } | 267 | } |
263 | 268 | ||
264 | static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_mod *mod) | 269 | static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_dai_stream *io, |
270 | struct rsnd_mod *mod) | ||
265 | { | 271 | { |
266 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 272 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
267 | 273 | ||
@@ -366,7 +372,7 @@ int rsnd_dvc_probe(struct platform_device *pdev, | |||
366 | 372 | ||
367 | dvc->info = &info->dvc_info[i]; | 373 | dvc->info = &info->dvc_info[i]; |
368 | 374 | ||
369 | ret = rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops, | 375 | ret = rsnd_mod_init(priv, &dvc->mod, &rsnd_dvc_ops, |
370 | clk, RSND_MOD_DVC, i); | 376 | clk, RSND_MOD_DVC, i); |
371 | if (ret) | 377 | if (ret) |
372 | return ret; | 378 | return ret; |
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 03ff071d012f..09fcc54a8ee0 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h | |||
@@ -165,18 +165,18 @@ void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod, | |||
165 | enum rsnd_reg reg, u32 data); | 165 | enum rsnd_reg reg, u32 data); |
166 | void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, | 166 | void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, |
167 | u32 mask, u32 data); | 167 | u32 mask, u32 data); |
168 | u32 rsnd_get_adinr(struct rsnd_mod *mod); | 168 | u32 rsnd_get_adinr(struct rsnd_mod *mod, struct rsnd_dai_stream *io); |
169 | 169 | ||
170 | /* | 170 | /* |
171 | * R-Car DMA | 171 | * R-Car DMA |
172 | */ | 172 | */ |
173 | struct rsnd_dma; | 173 | struct rsnd_dma; |
174 | struct rsnd_dma_ops { | 174 | struct rsnd_dma_ops { |
175 | void (*start)(struct rsnd_dma *dma); | 175 | void (*start)(struct rsnd_dai_stream *io, struct rsnd_dma *dma); |
176 | void (*stop)(struct rsnd_dma *dma); | 176 | void (*stop)(struct rsnd_dai_stream *io, struct rsnd_dma *dma); |
177 | int (*init)(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, | 177 | int (*init)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id, |
178 | struct rsnd_mod *mod_from, struct rsnd_mod *mod_to); | 178 | struct rsnd_mod *mod_from, struct rsnd_mod *mod_to); |
179 | void (*quit)(struct rsnd_dma *dma); | 179 | void (*quit)(struct rsnd_dai_stream *io, struct rsnd_dma *dma); |
180 | }; | 180 | }; |
181 | 181 | ||
182 | struct rsnd_dmaen { | 182 | struct rsnd_dmaen { |
@@ -200,10 +200,10 @@ struct rsnd_dma { | |||
200 | #define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en) | 200 | #define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en) |
201 | #define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp) | 201 | #define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp) |
202 | 202 | ||
203 | void rsnd_dma_start(struct rsnd_dma *dma); | 203 | void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma); |
204 | void rsnd_dma_stop(struct rsnd_dma *dma); | 204 | void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma); |
205 | int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id); | 205 | int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id); |
206 | void rsnd_dma_quit(struct rsnd_dma *dma); | 206 | void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma); |
207 | int rsnd_dma_probe(struct platform_device *pdev, | 207 | int rsnd_dma_probe(struct platform_device *pdev, |
208 | const struct rsnd_of_data *of_data, | 208 | const struct rsnd_of_data *of_data, |
209 | struct rsnd_priv *priv); | 209 | struct rsnd_priv *priv); |
@@ -224,25 +224,35 @@ enum rsnd_mod_type { | |||
224 | 224 | ||
225 | struct rsnd_mod_ops { | 225 | struct rsnd_mod_ops { |
226 | char *name; | 226 | char *name; |
227 | struct dma_chan* (*dma_req)(struct rsnd_mod *mod); | 227 | struct dma_chan* (*dma_req)(struct rsnd_dai_stream *io, |
228 | struct rsnd_mod *mod); | ||
228 | int (*probe)(struct rsnd_mod *mod, | 229 | int (*probe)(struct rsnd_mod *mod, |
230 | struct rsnd_dai_stream *io, | ||
229 | struct rsnd_priv *priv); | 231 | struct rsnd_priv *priv); |
230 | int (*remove)(struct rsnd_mod *mod, | 232 | int (*remove)(struct rsnd_mod *mod, |
233 | struct rsnd_dai_stream *io, | ||
231 | struct rsnd_priv *priv); | 234 | struct rsnd_priv *priv); |
232 | int (*init)(struct rsnd_mod *mod, | 235 | int (*init)(struct rsnd_mod *mod, |
236 | struct rsnd_dai_stream *io, | ||
233 | struct rsnd_priv *priv); | 237 | struct rsnd_priv *priv); |
234 | int (*quit)(struct rsnd_mod *mod, | 238 | int (*quit)(struct rsnd_mod *mod, |
239 | struct rsnd_dai_stream *io, | ||
235 | struct rsnd_priv *priv); | 240 | struct rsnd_priv *priv); |
236 | int (*start)(struct rsnd_mod *mod, | 241 | int (*start)(struct rsnd_mod *mod, |
242 | struct rsnd_dai_stream *io, | ||
237 | struct rsnd_priv *priv); | 243 | struct rsnd_priv *priv); |
238 | int (*stop)(struct rsnd_mod *mod, | 244 | int (*stop)(struct rsnd_mod *mod, |
245 | struct rsnd_dai_stream *io, | ||
239 | struct rsnd_priv *priv); | 246 | struct rsnd_priv *priv); |
240 | int (*pcm_new)(struct rsnd_mod *mod, | 247 | int (*pcm_new)(struct rsnd_mod *mod, |
248 | struct rsnd_dai_stream *io, | ||
241 | struct snd_soc_pcm_runtime *rtd); | 249 | struct snd_soc_pcm_runtime *rtd); |
242 | int (*hw_params)(struct rsnd_mod *mod, | 250 | int (*hw_params)(struct rsnd_mod *mod, |
251 | struct rsnd_dai_stream *io, | ||
243 | struct snd_pcm_substream *substream, | 252 | struct snd_pcm_substream *substream, |
244 | struct snd_pcm_hw_params *hw_params); | 253 | struct snd_pcm_hw_params *hw_params); |
245 | int (*fallback)(struct rsnd_mod *mod, | 254 | int (*fallback)(struct rsnd_mod *mod, |
255 | struct rsnd_dai_stream *io, | ||
246 | struct rsnd_priv *priv); | 256 | struct rsnd_priv *priv); |
247 | }; | 257 | }; |
248 | 258 | ||
@@ -252,32 +262,43 @@ struct rsnd_mod { | |||
252 | enum rsnd_mod_type type; | 262 | enum rsnd_mod_type type; |
253 | struct rsnd_mod_ops *ops; | 263 | struct rsnd_mod_ops *ops; |
254 | struct rsnd_dma dma; | 264 | struct rsnd_dma dma; |
255 | struct rsnd_dai_stream *io; | 265 | struct rsnd_priv *priv; |
256 | struct clk *clk; | 266 | struct clk *clk; |
257 | u32 status; | 267 | u32 status; |
258 | }; | 268 | }; |
259 | /* | 269 | /* |
260 | * status | 270 | * status |
261 | * | 271 | * |
262 | * bit | 272 | * 0xH0000CBA |
263 | * 0 0: probe 1: remove | 273 | * |
264 | * 1 0: init 1: quit | 274 | * A 0: probe 1: remove |
265 | * 2 0: start 1: stop | 275 | * B 0: init 1: quit |
266 | * 3 0: pcm_new | 276 | * C 0: start 1: stop |
267 | * 4 0: fallback | ||
268 | * | 277 | * |
269 | * 31 bit is always called (see __rsnd_mod_call) | 278 | * H is always called (see __rsnd_mod_call) |
270 | * 31 0: hw_params | 279 | * H 0: pcm_new |
280 | * H 0: fallback | ||
281 | * H 0: hw_params | ||
271 | */ | 282 | */ |
272 | #define __rsnd_mod_shift_probe 0 | 283 | #define __rsnd_mod_shift_probe 0 |
273 | #define __rsnd_mod_shift_remove 0 | 284 | #define __rsnd_mod_shift_remove 0 |
274 | #define __rsnd_mod_shift_init 1 | 285 | #define __rsnd_mod_shift_init 4 |
275 | #define __rsnd_mod_shift_quit 1 | 286 | #define __rsnd_mod_shift_quit 4 |
276 | #define __rsnd_mod_shift_start 2 | 287 | #define __rsnd_mod_shift_start 8 |
277 | #define __rsnd_mod_shift_stop 2 | 288 | #define __rsnd_mod_shift_stop 8 |
278 | #define __rsnd_mod_shift_pcm_new 3 | 289 | #define __rsnd_mod_shift_pcm_new 28 /* always called */ |
279 | #define __rsnd_mod_shift_fallback 4 | 290 | #define __rsnd_mod_shift_fallback 28 /* always called */ |
280 | #define __rsnd_mod_shift_hw_params 31 /* always called */ | 291 | #define __rsnd_mod_shift_hw_params 28 /* always called */ |
292 | |||
293 | #define __rsnd_mod_add_probe 1 | ||
294 | #define __rsnd_mod_add_remove -1 | ||
295 | #define __rsnd_mod_add_init 1 | ||
296 | #define __rsnd_mod_add_quit -1 | ||
297 | #define __rsnd_mod_add_start 1 | ||
298 | #define __rsnd_mod_add_stop -1 | ||
299 | #define __rsnd_mod_add_pcm_new 0 | ||
300 | #define __rsnd_mod_add_fallback 0 | ||
301 | #define __rsnd_mod_add_hw_params 0 | ||
281 | 302 | ||
282 | #define __rsnd_mod_call_probe 0 | 303 | #define __rsnd_mod_call_probe 0 |
283 | #define __rsnd_mod_call_remove 1 | 304 | #define __rsnd_mod_call_remove 1 |
@@ -289,22 +310,25 @@ struct rsnd_mod { | |||
289 | #define __rsnd_mod_call_fallback 0 | 310 | #define __rsnd_mod_call_fallback 0 |
290 | #define __rsnd_mod_call_hw_params 0 | 311 | #define __rsnd_mod_call_hw_params 0 |
291 | 312 | ||
292 | #define rsnd_mod_to_priv(mod) (rsnd_io_to_priv(rsnd_mod_to_io(mod))) | 313 | #define rsnd_mod_to_priv(mod) ((mod)->priv) |
293 | #define rsnd_mod_to_dma(mod) (&(mod)->dma) | 314 | #define rsnd_mod_to_dma(mod) (&(mod)->dma) |
294 | #define rsnd_mod_to_io(mod) ((mod)->io) | ||
295 | #define rsnd_mod_id(mod) ((mod)->id) | 315 | #define rsnd_mod_id(mod) ((mod)->id) |
296 | #define rsnd_mod_hw_start(mod) clk_enable((mod)->clk) | 316 | #define rsnd_mod_hw_start(mod) clk_enable((mod)->clk) |
297 | #define rsnd_mod_hw_stop(mod) clk_disable((mod)->clk) | 317 | #define rsnd_mod_hw_stop(mod) clk_disable((mod)->clk) |
298 | 318 | ||
299 | int rsnd_mod_init(struct rsnd_mod *mod, | 319 | int rsnd_mod_init(struct rsnd_priv *priv, |
320 | struct rsnd_mod *mod, | ||
300 | struct rsnd_mod_ops *ops, | 321 | struct rsnd_mod_ops *ops, |
301 | struct clk *clk, | 322 | struct clk *clk, |
302 | enum rsnd_mod_type type, | 323 | enum rsnd_mod_type type, |
303 | int id); | 324 | int id); |
304 | void rsnd_mod_quit(struct rsnd_mod *mod); | 325 | void rsnd_mod_quit(struct rsnd_mod *mod); |
305 | char *rsnd_mod_name(struct rsnd_mod *mod); | 326 | char *rsnd_mod_name(struct rsnd_mod *mod); |
306 | int rsnd_mod_is_working(struct rsnd_mod *mod); | 327 | struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io, |
307 | struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod); | 328 | struct rsnd_mod *mod); |
329 | void rsnd_mod_interrupt(struct rsnd_mod *mod, | ||
330 | void (*callback)(struct rsnd_mod *mod, | ||
331 | struct rsnd_dai_stream *io)); | ||
308 | 332 | ||
309 | /* | 333 | /* |
310 | * R-Car sound DAI | 334 | * R-Car sound DAI |
@@ -329,7 +353,7 @@ struct rsnd_dai_stream { | |||
329 | #define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io) | 353 | #define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io) |
330 | #define rsnd_io_to_runtime(io) ((io)->substream ? \ | 354 | #define rsnd_io_to_runtime(io) ((io)->substream ? \ |
331 | (io)->substream->runtime : NULL) | 355 | (io)->substream->runtime : NULL) |
332 | 356 | int rsnd_io_is_working(struct rsnd_dai_stream *io); | |
333 | 357 | ||
334 | struct rsnd_dai { | 358 | struct rsnd_dai { |
335 | char name[RSND_DAI_NAME_SIZE]; | 359 | char name[RSND_DAI_NAME_SIZE]; |
@@ -355,7 +379,8 @@ struct rsnd_dai { | |||
355 | 379 | ||
356 | struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id); | 380 | struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id); |
357 | 381 | ||
358 | void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); | 382 | bool rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); |
383 | void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io); | ||
359 | int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); | 384 | int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); |
360 | 385 | ||
361 | /* | 386 | /* |
@@ -459,7 +484,8 @@ struct rsnd_kctrl_cfg { | |||
459 | unsigned int size; | 484 | unsigned int size; |
460 | u32 *val; | 485 | u32 *val; |
461 | const char * const *texts; | 486 | const char * const *texts; |
462 | void (*update)(struct rsnd_mod *mod); | 487 | void (*update)(struct rsnd_dai_stream *io, struct rsnd_mod *mod); |
488 | struct rsnd_dai_stream *io; | ||
463 | struct snd_card *card; | 489 | struct snd_card *card; |
464 | struct snd_kcontrol *kctrl; | 490 | struct snd_kcontrol *kctrl; |
465 | }; | 491 | }; |
@@ -479,22 +505,28 @@ void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg); | |||
479 | #define rsnd_kctrl_remove(_cfg) _rsnd_kctrl_remove(&((_cfg).cfg)) | 505 | #define rsnd_kctrl_remove(_cfg) _rsnd_kctrl_remove(&((_cfg).cfg)) |
480 | 506 | ||
481 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, | 507 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, |
508 | struct rsnd_dai_stream *io, | ||
482 | struct snd_soc_pcm_runtime *rtd, | 509 | struct snd_soc_pcm_runtime *rtd, |
483 | const unsigned char *name, | 510 | const unsigned char *name, |
484 | void (*update)(struct rsnd_mod *mod), | 511 | void (*update)(struct rsnd_dai_stream *io, |
512 | struct rsnd_mod *mod), | ||
485 | struct rsnd_kctrl_cfg_m *_cfg, | 513 | struct rsnd_kctrl_cfg_m *_cfg, |
486 | u32 max); | 514 | u32 max); |
487 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, | 515 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, |
516 | struct rsnd_dai_stream *io, | ||
488 | struct snd_soc_pcm_runtime *rtd, | 517 | struct snd_soc_pcm_runtime *rtd, |
489 | const unsigned char *name, | 518 | const unsigned char *name, |
490 | void (*update)(struct rsnd_mod *mod), | 519 | void (*update)(struct rsnd_dai_stream *io, |
520 | struct rsnd_mod *mod), | ||
491 | struct rsnd_kctrl_cfg_s *_cfg, | 521 | struct rsnd_kctrl_cfg_s *_cfg, |
492 | u32 max); | 522 | u32 max); |
493 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, | 523 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, |
524 | struct rsnd_dai_stream *io, | ||
494 | struct snd_soc_pcm_runtime *rtd, | 525 | struct snd_soc_pcm_runtime *rtd, |
495 | const unsigned char *name, | 526 | const unsigned char *name, |
496 | struct rsnd_kctrl_cfg_s *_cfg, | 527 | struct rsnd_kctrl_cfg_s *_cfg, |
497 | void (*update)(struct rsnd_mod *mod), | 528 | void (*update)(struct rsnd_dai_stream *io, |
529 | struct rsnd_mod *mod), | ||
498 | const char * const *texts, | 530 | const char * const *texts, |
499 | u32 max); | 531 | u32 max); |
500 | 532 | ||
@@ -511,8 +543,10 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, | |||
511 | struct rsnd_dai_stream *io, | 543 | struct rsnd_dai_stream *io, |
512 | struct snd_pcm_runtime *runtime); | 544 | struct snd_pcm_runtime *runtime); |
513 | int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, | 545 | int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, |
546 | struct rsnd_dai_stream *io, | ||
514 | int use_busif); | 547 | int use_busif); |
515 | int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod); | 548 | int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, |
549 | struct rsnd_dai_stream *io); | ||
516 | int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod); | 550 | int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod); |
517 | int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod); | 551 | int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod); |
518 | 552 | ||
@@ -529,7 +563,7 @@ void rsnd_ssi_remove(struct platform_device *pdev, | |||
529 | struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); | 563 | struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); |
530 | int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); | 564 | int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); |
531 | int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); | 565 | int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); |
532 | int rsnd_ssi_use_busif(struct rsnd_mod *mod); | 566 | int rsnd_ssi_use_busif(struct rsnd_dai_stream *io, struct rsnd_mod *mod); |
533 | 567 | ||
534 | /* | 568 | /* |
535 | * R-Car DVC | 569 | * R-Car DVC |
diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c index 050b0dbcee65..8caca2e180c3 100644 --- a/sound/soc/sh/rcar/rsrc-card.c +++ b/sound/soc/sh/rcar/rsrc-card.c | |||
@@ -45,61 +45,50 @@ static const struct of_device_id rsrc_card_of_match[] = { | |||
45 | }; | 45 | }; |
46 | MODULE_DEVICE_TABLE(of, rsrc_card_of_match); | 46 | MODULE_DEVICE_TABLE(of, rsrc_card_of_match); |
47 | 47 | ||
48 | #define DAI_NAME_NUM 32 | ||
48 | struct rsrc_card_dai { | 49 | struct rsrc_card_dai { |
49 | const char *name; | ||
50 | unsigned int fmt; | 50 | unsigned int fmt; |
51 | unsigned int sysclk; | 51 | unsigned int sysclk; |
52 | struct clk *clk; | 52 | struct clk *clk; |
53 | char dai_name[DAI_NAME_NUM]; | ||
53 | }; | 54 | }; |
54 | 55 | ||
55 | #define RSRC_FB_NUM 2 /* FE/BE */ | ||
56 | #define IDX_CPU 0 | 56 | #define IDX_CPU 0 |
57 | #define IDX_CODEC 1 | 57 | #define IDX_CODEC 1 |
58 | struct rsrc_card_priv { | 58 | struct rsrc_card_priv { |
59 | struct snd_soc_card snd_card; | 59 | struct snd_soc_card snd_card; |
60 | struct rsrc_card_dai_props { | ||
61 | struct rsrc_card_dai cpu_dai; | ||
62 | struct rsrc_card_dai codec_dai; | ||
63 | } dai_props[RSRC_FB_NUM]; | ||
64 | struct snd_soc_codec_conf codec_conf; | 60 | struct snd_soc_codec_conf codec_conf; |
65 | struct snd_soc_dai_link dai_link[RSRC_FB_NUM]; | 61 | struct rsrc_card_dai *dai_props; |
62 | struct snd_soc_dai_link *dai_link; | ||
63 | int dai_num; | ||
66 | u32 convert_rate; | 64 | u32 convert_rate; |
67 | }; | 65 | }; |
68 | 66 | ||
69 | #define rsrc_priv_to_dev(priv) ((priv)->snd_card.dev) | 67 | #define rsrc_priv_to_dev(priv) ((priv)->snd_card.dev) |
70 | #define rsrc_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i) | 68 | #define rsrc_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i)) |
71 | #define rsrc_priv_to_props(priv, i) ((priv)->dai_props + i) | 69 | #define rsrc_priv_to_props(priv, i) ((priv)->dai_props + (i)) |
72 | #define rsrc_dev_to_of_data(dev) (of_match_device(rsrc_card_of_match, (dev))->data) | 70 | #define rsrc_dev_to_of_data(dev) (of_match_device(rsrc_card_of_match, (dev))->data) |
73 | 71 | ||
74 | static int rsrc_card_startup(struct snd_pcm_substream *substream) | 72 | static int rsrc_card_startup(struct snd_pcm_substream *substream) |
75 | { | 73 | { |
76 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 74 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
77 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | 75 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); |
78 | struct rsrc_card_dai_props *dai_props = | 76 | struct rsrc_card_dai *dai_props = |
79 | &priv->dai_props[rtd - rtd->card->rtd]; | 77 | rsrc_priv_to_props(priv, rtd - rtd->card->rtd); |
80 | int ret; | 78 | int ret; |
81 | 79 | ||
82 | ret = clk_prepare_enable(dai_props->cpu_dai.clk); | ||
83 | if (ret) | ||
84 | return ret; | ||
85 | |||
86 | ret = clk_prepare_enable(dai_props->codec_dai.clk); | ||
87 | if (ret) | ||
88 | clk_disable_unprepare(dai_props->cpu_dai.clk); | ||
89 | 80 | ||
90 | return ret; | 81 | return clk_prepare_enable(dai_props->clk); |
91 | } | 82 | } |
92 | 83 | ||
93 | static void rsrc_card_shutdown(struct snd_pcm_substream *substream) | 84 | static void rsrc_card_shutdown(struct snd_pcm_substream *substream) |
94 | { | 85 | { |
95 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 86 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
96 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | 87 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); |
97 | struct rsrc_card_dai_props *dai_props = | 88 | struct rsrc_card_dai *dai_props = |
98 | &priv->dai_props[rtd - rtd->card->rtd]; | 89 | rsrc_priv_to_props(priv, rtd - rtd->card->rtd); |
99 | |||
100 | clk_disable_unprepare(dai_props->cpu_dai.clk); | ||
101 | 90 | ||
102 | clk_disable_unprepare(dai_props->codec_dai.clk); | 91 | clk_disable_unprepare(dai_props->clk); |
103 | } | 92 | } |
104 | 93 | ||
105 | static struct snd_soc_ops rsrc_card_ops = { | 94 | static struct snd_soc_ops rsrc_card_ops = { |
@@ -107,21 +96,31 @@ static struct snd_soc_ops rsrc_card_ops = { | |||
107 | .shutdown = rsrc_card_shutdown, | 96 | .shutdown = rsrc_card_shutdown, |
108 | }; | 97 | }; |
109 | 98 | ||
110 | static int __rsrc_card_dai_init(struct snd_soc_dai *dai, | 99 | static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd) |
111 | struct rsrc_card_dai *set) | ||
112 | { | 100 | { |
101 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
102 | struct snd_soc_dai *dai; | ||
103 | struct snd_soc_dai_link *dai_link; | ||
104 | struct rsrc_card_dai *dai_props; | ||
105 | int num = rtd - rtd->card->rtd; | ||
113 | int ret; | 106 | int ret; |
114 | 107 | ||
115 | if (set->fmt) { | 108 | dai_link = rsrc_priv_to_link(priv, num); |
116 | ret = snd_soc_dai_set_fmt(dai, set->fmt); | 109 | dai_props = rsrc_priv_to_props(priv, num); |
110 | dai = dai_link->dynamic ? | ||
111 | rtd->cpu_dai : | ||
112 | rtd->codec_dai; | ||
113 | |||
114 | if (dai_props->fmt) { | ||
115 | ret = snd_soc_dai_set_fmt(dai, dai_props->fmt); | ||
117 | if (ret && ret != -ENOTSUPP) { | 116 | if (ret && ret != -ENOTSUPP) { |
118 | dev_err(dai->dev, "set_fmt error\n"); | 117 | dev_err(dai->dev, "set_fmt error\n"); |
119 | goto err; | 118 | goto err; |
120 | } | 119 | } |
121 | } | 120 | } |
122 | 121 | ||
123 | if (set->sysclk) { | 122 | if (dai_props->sysclk) { |
124 | ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0); | 123 | ret = snd_soc_dai_set_sysclk(dai, 0, dai_props->sysclk, 0); |
125 | if (ret && ret != -ENOTSUPP) { | 124 | if (ret && ret != -ENOTSUPP) { |
126 | dev_err(dai->dev, "set_sysclk error\n"); | 125 | dev_err(dai->dev, "set_sysclk error\n"); |
127 | goto err; | 126 | goto err; |
@@ -134,27 +133,6 @@ err: | |||
134 | return ret; | 133 | return ret; |
135 | } | 134 | } |
136 | 135 | ||
137 | static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd) | ||
138 | { | ||
139 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
140 | struct snd_soc_dai *codec = rtd->codec_dai; | ||
141 | struct snd_soc_dai *cpu = rtd->cpu_dai; | ||
142 | struct rsrc_card_dai_props *dai_props; | ||
143 | int num, ret; | ||
144 | |||
145 | num = rtd - rtd->card->rtd; | ||
146 | dai_props = &priv->dai_props[num]; | ||
147 | ret = __rsrc_card_dai_init(codec, &dai_props->codec_dai); | ||
148 | if (ret < 0) | ||
149 | return ret; | ||
150 | |||
151 | ret = __rsrc_card_dai_init(cpu, &dai_props->cpu_dai); | ||
152 | if (ret < 0) | ||
153 | return ret; | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, | 136 | static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, |
159 | struct snd_pcm_hw_params *params) | 137 | struct snd_pcm_hw_params *params) |
160 | { | 138 | { |
@@ -170,40 +148,47 @@ static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, | |||
170 | return 0; | 148 | return 0; |
171 | } | 149 | } |
172 | 150 | ||
173 | static int | 151 | static int rsrc_card_parse_daifmt(struct device_node *node, |
174 | rsrc_card_sub_parse_of(struct rsrc_card_priv *priv, | 152 | struct device_node *np, |
175 | struct device_node *np, | 153 | struct rsrc_card_priv *priv, |
176 | struct rsrc_card_dai *dai, | 154 | int idx, bool is_fe) |
177 | struct snd_soc_dai_link *dai_link, | ||
178 | int *args_count) | ||
179 | { | 155 | { |
180 | struct device *dev = rsrc_priv_to_dev(priv); | 156 | struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); |
181 | const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev); | 157 | struct device_node *bitclkmaster = NULL; |
182 | struct of_phandle_args args; | 158 | struct device_node *framemaster = NULL; |
183 | struct device_node **p_node; | 159 | struct device_node *codec = is_fe ? NULL : np; |
184 | struct clk *clk; | 160 | unsigned int daifmt; |
185 | const char **dai_name; | ||
186 | const char **name; | ||
187 | u32 val; | ||
188 | int ret; | ||
189 | 161 | ||
190 | if (args_count) { | 162 | daifmt = snd_soc_of_parse_daifmt(node, NULL, |
191 | p_node = &dai_link->cpu_of_node; | 163 | &bitclkmaster, &framemaster); |
192 | dai_name = &dai_link->cpu_dai_name; | 164 | daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK; |
193 | name = &dai_link->cpu_name; | ||
194 | } else { | ||
195 | p_node = &dai_link->codec_of_node; | ||
196 | dai_name = &dai_link->codec_dai_name; | ||
197 | name = &dai_link->codec_name; | ||
198 | } | ||
199 | 165 | ||
200 | if (!np) { | 166 | if (!bitclkmaster && !framemaster) |
201 | /* use snd-soc-dummy */ | 167 | return -EINVAL; |
202 | *p_node = NULL; | 168 | |
203 | *dai_name = "snd-soc-dummy-dai"; | 169 | if (codec == bitclkmaster) |
204 | *name = "snd-soc-dummy"; | 170 | daifmt |= (codec == framemaster) ? |
205 | return 0; | 171 | SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS; |
206 | } | 172 | else |
173 | daifmt |= (codec == framemaster) ? | ||
174 | SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; | ||
175 | |||
176 | dai_props->fmt = daifmt; | ||
177 | |||
178 | of_node_put(bitclkmaster); | ||
179 | of_node_put(framemaster); | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int rsrc_card_parse_links(struct device_node *np, | ||
185 | struct rsrc_card_priv *priv, | ||
186 | int idx, bool is_fe) | ||
187 | { | ||
188 | struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); | ||
189 | struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); | ||
190 | struct of_phandle_args args; | ||
191 | int ret; | ||
207 | 192 | ||
208 | /* | 193 | /* |
209 | * Get node via "sound-dai = <&phandle port>" | 194 | * Get node via "sound-dai = <&phandle port>" |
@@ -214,31 +199,82 @@ rsrc_card_sub_parse_of(struct rsrc_card_priv *priv, | |||
214 | if (ret) | 199 | if (ret) |
215 | return ret; | 200 | return ret; |
216 | 201 | ||
217 | *p_node = args.np; | 202 | if (is_fe) { |
203 | /* BE is dummy */ | ||
204 | dai_link->codec_of_node = NULL; | ||
205 | dai_link->codec_dai_name = "snd-soc-dummy-dai"; | ||
206 | dai_link->codec_name = "snd-soc-dummy"; | ||
207 | |||
208 | /* FE settings */ | ||
209 | dai_link->dynamic = 1; | ||
210 | dai_link->dpcm_merged_format = 1; | ||
211 | dai_link->cpu_of_node = args.np; | ||
212 | snd_soc_of_get_dai_name(np, &dai_link->cpu_dai_name); | ||
213 | |||
214 | /* set dai_name */ | ||
215 | snprintf(dai_props->dai_name, DAI_NAME_NUM, "fe.%s", | ||
216 | dai_link->cpu_dai_name); | ||
217 | |||
218 | /* | ||
219 | * In soc_bind_dai_link() will check cpu name after | ||
220 | * of_node matching if dai_link has cpu_dai_name. | ||
221 | * but, it will never match if name was created by | ||
222 | * fmt_single_name() remove cpu_dai_name if cpu_args | ||
223 | * was 0. See: | ||
224 | * fmt_single_name() | ||
225 | * fmt_multiple_name() | ||
226 | */ | ||
227 | if (!args.args_count) | ||
228 | dai_link->cpu_dai_name = NULL; | ||
229 | } else { | ||
230 | struct device *dev = rsrc_priv_to_dev(priv); | ||
231 | const struct rsrc_card_of_data *of_data; | ||
218 | 232 | ||
219 | /* Get dai->name */ | 233 | of_data = rsrc_dev_to_of_data(dev); |
220 | ret = snd_soc_of_get_dai_name(np, dai_name); | ||
221 | if (ret < 0) | ||
222 | return ret; | ||
223 | 234 | ||
224 | /* | 235 | /* FE is dummy */ |
225 | * FIXME | 236 | dai_link->cpu_of_node = NULL; |
226 | * | 237 | dai_link->cpu_dai_name = "snd-soc-dummy-dai"; |
227 | * rsrc assumes DPCM playback/capture | 238 | dai_link->cpu_name = "snd-soc-dummy"; |
228 | */ | ||
229 | dai_link->dpcm_playback = 1; | ||
230 | dai_link->dpcm_capture = 1; | ||
231 | 239 | ||
232 | if (args_count) { | 240 | /* BE settings */ |
233 | *args_count = args.args_count; | 241 | dai_link->no_pcm = 1; |
234 | dai_link->dynamic = 1; | 242 | dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup; |
235 | dai_link->dpcm_merged_format = 1; | 243 | dai_link->codec_of_node = args.np; |
236 | } else { | 244 | snd_soc_of_get_dai_name(np, &dai_link->codec_dai_name); |
237 | dai_link->no_pcm = 1; | 245 | |
238 | priv->codec_conf.of_node = (*p_node); | 246 | /* additional name prefix */ |
239 | priv->codec_conf.name_prefix = of_data->prefix; | 247 | priv->codec_conf.of_node = dai_link->codec_of_node; |
248 | priv->codec_conf.name_prefix = of_data->prefix; | ||
249 | |||
250 | /* set dai_name */ | ||
251 | snprintf(dai_props->dai_name, DAI_NAME_NUM, "be.%s", | ||
252 | dai_link->codec_dai_name); | ||
240 | } | 253 | } |
241 | 254 | ||
255 | /* Simple Card assumes platform == cpu */ | ||
256 | dai_link->platform_of_node = dai_link->cpu_of_node; | ||
257 | dai_link->dpcm_playback = 1; | ||
258 | dai_link->dpcm_capture = 1; | ||
259 | dai_link->name = dai_props->dai_name; | ||
260 | dai_link->stream_name = dai_props->dai_name; | ||
261 | dai_link->ops = &rsrc_card_ops; | ||
262 | dai_link->init = rsrc_card_dai_init; | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | static int rsrc_card_parse_clk(struct device_node *np, | ||
268 | struct rsrc_card_priv *priv, | ||
269 | int idx, bool is_fe) | ||
270 | { | ||
271 | struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); | ||
272 | struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); | ||
273 | struct clk *clk; | ||
274 | struct device_node *of_np = is_fe ? dai_link->cpu_of_node : | ||
275 | dai_link->codec_of_node; | ||
276 | u32 val; | ||
277 | |||
242 | /* | 278 | /* |
243 | * Parse dai->sysclk come from "clocks = <&xxx>" | 279 | * Parse dai->sysclk come from "clocks = <&xxx>" |
244 | * (if system has common clock) | 280 | * (if system has common clock) |
@@ -247,173 +283,92 @@ rsrc_card_sub_parse_of(struct rsrc_card_priv *priv, | |||
247 | */ | 283 | */ |
248 | if (of_property_read_bool(np, "clocks")) { | 284 | if (of_property_read_bool(np, "clocks")) { |
249 | clk = of_clk_get(np, 0); | 285 | clk = of_clk_get(np, 0); |
250 | if (IS_ERR(clk)) { | 286 | if (IS_ERR(clk)) |
251 | ret = PTR_ERR(clk); | 287 | return PTR_ERR(clk); |
252 | return ret; | ||
253 | } | ||
254 | 288 | ||
255 | dai->sysclk = clk_get_rate(clk); | 289 | dai_props->sysclk = clk_get_rate(clk); |
256 | dai->clk = clk; | 290 | dai_props->clk = clk; |
257 | } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) { | 291 | } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) { |
258 | dai->sysclk = val; | 292 | dai_props->sysclk = val; |
259 | } else { | 293 | } else { |
260 | clk = of_clk_get(args.np, 0); | 294 | clk = of_clk_get(of_np, 0); |
261 | if (!IS_ERR(clk)) | 295 | if (!IS_ERR(clk)) |
262 | dai->sysclk = clk_get_rate(clk); | 296 | dai_props->sysclk = clk_get_rate(clk); |
263 | } | 297 | } |
264 | 298 | ||
265 | return 0; | 299 | return 0; |
266 | } | 300 | } |
267 | 301 | ||
268 | static int rsrc_card_parse_daifmt(struct device_node *node, | ||
269 | struct rsrc_card_priv *priv, | ||
270 | struct device_node *codec, | ||
271 | int idx) | ||
272 | { | ||
273 | struct device_node *bitclkmaster = NULL; | ||
274 | struct device_node *framemaster = NULL; | ||
275 | struct rsrc_card_dai_props *dai_props = rsrc_priv_to_props(priv, idx); | ||
276 | struct rsrc_card_dai *cpu_dai = &dai_props->cpu_dai; | ||
277 | struct rsrc_card_dai *codec_dai = &dai_props->codec_dai; | ||
278 | unsigned int daifmt; | ||
279 | |||
280 | daifmt = snd_soc_of_parse_daifmt(node, NULL, | ||
281 | &bitclkmaster, &framemaster); | ||
282 | daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK; | ||
283 | |||
284 | if (!bitclkmaster && !framemaster) | ||
285 | return -EINVAL; | ||
286 | |||
287 | if (codec == bitclkmaster) | ||
288 | daifmt |= (codec == framemaster) ? | ||
289 | SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS; | ||
290 | else | ||
291 | daifmt |= (codec == framemaster) ? | ||
292 | SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; | ||
293 | |||
294 | cpu_dai->fmt = daifmt; | ||
295 | codec_dai->fmt = daifmt; | ||
296 | |||
297 | of_node_put(bitclkmaster); | ||
298 | of_node_put(framemaster); | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | static int rsrc_card_dai_link_of(struct device_node *node, | 302 | static int rsrc_card_dai_link_of(struct device_node *node, |
303 | struct device_node *np, | ||
304 | struct rsrc_card_priv *priv, | 304 | struct rsrc_card_priv *priv, |
305 | int idx) | 305 | int idx) |
306 | { | 306 | { |
307 | struct device *dev = rsrc_priv_to_dev(priv); | 307 | struct device *dev = rsrc_priv_to_dev(priv); |
308 | struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); | 308 | struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); |
309 | struct rsrc_card_dai_props *dai_props = rsrc_priv_to_props(priv, idx); | 309 | bool is_fe = false; |
310 | struct device_node *cpu = NULL; | 310 | int ret; |
311 | struct device_node *codec = NULL; | ||
312 | char *name; | ||
313 | char prop[128]; | ||
314 | int ret, cpu_args; | ||
315 | |||
316 | cpu = of_get_child_by_name(node, "cpu"); | ||
317 | codec = of_get_child_by_name(node, "codec"); | ||
318 | |||
319 | if (!cpu || !codec) { | ||
320 | ret = -EINVAL; | ||
321 | dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop); | ||
322 | goto dai_link_of_err; | ||
323 | } | ||
324 | 311 | ||
325 | ret = rsrc_card_parse_daifmt(node, priv, codec, idx); | 312 | if (0 == strcmp(np->name, "cpu")) |
326 | if (ret < 0) | 313 | is_fe = true; |
327 | goto dai_link_of_err; | ||
328 | 314 | ||
329 | ret = rsrc_card_sub_parse_of(priv, (idx == IDX_CPU) ? cpu : NULL, | 315 | ret = rsrc_card_parse_daifmt(node, np, priv, idx, is_fe); |
330 | &dai_props->cpu_dai, | ||
331 | dai_link, | ||
332 | &cpu_args); | ||
333 | if (ret < 0) | 316 | if (ret < 0) |
334 | goto dai_link_of_err; | 317 | return ret; |
335 | 318 | ||
336 | ret = rsrc_card_sub_parse_of(priv, (idx == IDX_CODEC) ? codec : NULL, | 319 | ret = rsrc_card_parse_links(np, priv, idx, is_fe); |
337 | &dai_props->codec_dai, | ||
338 | dai_link, | ||
339 | NULL); | ||
340 | if (ret < 0) | 320 | if (ret < 0) |
341 | goto dai_link_of_err; | 321 | return ret; |
342 | |||
343 | if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) { | ||
344 | ret = -EINVAL; | ||
345 | goto dai_link_of_err; | ||
346 | } | ||
347 | |||
348 | /* Simple Card assumes platform == cpu */ | ||
349 | dai_link->platform_of_node = dai_link->cpu_of_node; | ||
350 | |||
351 | /* DAI link name is created from CPU/CODEC dai name */ | ||
352 | name = devm_kzalloc(dev, | ||
353 | strlen(dai_link->cpu_dai_name) + | ||
354 | strlen(dai_link->codec_dai_name) + 2, | ||
355 | GFP_KERNEL); | ||
356 | if (!name) { | ||
357 | ret = -ENOMEM; | ||
358 | goto dai_link_of_err; | ||
359 | } | ||
360 | |||
361 | sprintf(name, "%s-%s", dai_link->cpu_dai_name, | ||
362 | dai_link->codec_dai_name); | ||
363 | dai_link->name = dai_link->stream_name = name; | ||
364 | dai_link->ops = &rsrc_card_ops; | ||
365 | dai_link->init = rsrc_card_dai_init; | ||
366 | |||
367 | if (idx == IDX_CODEC) | ||
368 | dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup; | ||
369 | |||
370 | dev_dbg(dev, "\tname : %s\n", dai_link->stream_name); | ||
371 | dev_dbg(dev, "\tcpu : %s / %04x / %d\n", | ||
372 | dai_link->cpu_dai_name, | ||
373 | dai_props->cpu_dai.fmt, | ||
374 | dai_props->cpu_dai.sysclk); | ||
375 | dev_dbg(dev, "\tcodec : %s / %04x / %d\n", | ||
376 | dai_link->codec_dai_name, | ||
377 | dai_props->codec_dai.fmt, | ||
378 | dai_props->codec_dai.sysclk); | ||
379 | 322 | ||
380 | /* | 323 | ret = rsrc_card_parse_clk(np, priv, idx, is_fe); |
381 | * In soc_bind_dai_link() will check cpu name after | 324 | if (ret < 0) |
382 | * of_node matching if dai_link has cpu_dai_name. | 325 | return ret; |
383 | * but, it will never match if name was created by | ||
384 | * fmt_single_name() remove cpu_dai_name if cpu_args | ||
385 | * was 0. See: | ||
386 | * fmt_single_name() | ||
387 | * fmt_multiple_name() | ||
388 | */ | ||
389 | if (!cpu_args) | ||
390 | dai_link->cpu_dai_name = NULL; | ||
391 | 326 | ||
392 | dai_link_of_err: | 327 | dev_dbg(dev, "\t%s / %04x / %d\n", |
393 | of_node_put(cpu); | 328 | dai_props->dai_name, |
394 | of_node_put(codec); | 329 | dai_props->fmt, |
330 | dai_props->sysclk); | ||
395 | 331 | ||
396 | return ret; | 332 | return ret; |
397 | } | 333 | } |
398 | 334 | ||
399 | static int rsrc_card_parse_of(struct device_node *node, | 335 | static int rsrc_card_parse_of(struct device_node *node, |
400 | struct rsrc_card_priv *priv) | 336 | struct rsrc_card_priv *priv, |
337 | struct device *dev) | ||
401 | { | 338 | { |
402 | struct device *dev = rsrc_priv_to_dev(priv); | ||
403 | const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev); | 339 | const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev); |
340 | struct rsrc_card_dai *props; | ||
341 | struct snd_soc_dai_link *links; | ||
342 | struct device_node *np; | ||
404 | int ret; | 343 | int ret; |
405 | int i; | 344 | int i, num; |
406 | 345 | ||
407 | if (!node) | 346 | if (!node) |
408 | return -EINVAL; | 347 | return -EINVAL; |
409 | 348 | ||
410 | /* Parse the card name from DT */ | 349 | num = of_get_child_count(node); |
411 | snd_soc_of_parse_card_name(&priv->snd_card, "card-name"); | 350 | props = devm_kzalloc(dev, sizeof(*props) * num, GFP_KERNEL); |
351 | links = devm_kzalloc(dev, sizeof(*links) * num, GFP_KERNEL); | ||
352 | if (!props || !links) | ||
353 | return -ENOMEM; | ||
354 | |||
355 | priv->dai_props = props; | ||
356 | priv->dai_link = links; | ||
357 | priv->dai_num = num; | ||
412 | 358 | ||
413 | /* DAPM routes */ | 359 | /* Init snd_soc_card */ |
360 | priv->snd_card.owner = THIS_MODULE; | ||
361 | priv->snd_card.dev = dev; | ||
362 | priv->snd_card.dai_link = priv->dai_link; | ||
363 | priv->snd_card.num_links = num; | ||
364 | priv->snd_card.codec_conf = &priv->codec_conf; | ||
365 | priv->snd_card.num_configs = 1; | ||
414 | priv->snd_card.of_dapm_routes = of_data->routes; | 366 | priv->snd_card.of_dapm_routes = of_data->routes; |
415 | priv->snd_card.num_of_dapm_routes = of_data->num_routes; | 367 | priv->snd_card.num_of_dapm_routes = of_data->num_routes; |
416 | 368 | ||
369 | /* Parse the card name from DT */ | ||
370 | snd_soc_of_parse_card_name(&priv->snd_card, "card-name"); | ||
371 | |||
417 | /* sampling rate convert */ | 372 | /* sampling rate convert */ |
418 | of_property_read_u32(node, "convert-rate", &priv->convert_rate); | 373 | of_property_read_u32(node, "convert-rate", &priv->convert_rate); |
419 | 374 | ||
@@ -421,11 +376,12 @@ static int rsrc_card_parse_of(struct device_node *node, | |||
421 | priv->snd_card.name ? priv->snd_card.name : "", | 376 | priv->snd_card.name ? priv->snd_card.name : "", |
422 | priv->convert_rate); | 377 | priv->convert_rate); |
423 | 378 | ||
424 | /* FE/BE */ | 379 | i = 0; |
425 | for (i = 0; i < RSRC_FB_NUM; i++) { | 380 | for_each_child_of_node(node, np) { |
426 | ret = rsrc_card_dai_link_of(node, priv, i); | 381 | ret = rsrc_card_dai_link_of(node, np, priv, i); |
427 | if (ret < 0) | 382 | if (ret < 0) |
428 | return ret; | 383 | return ret; |
384 | i++; | ||
429 | } | 385 | } |
430 | 386 | ||
431 | if (!priv->snd_card.name) | 387 | if (!priv->snd_card.name) |
@@ -452,7 +408,6 @@ static int rsrc_card_unref(struct snd_soc_card *card) | |||
452 | static int rsrc_card_probe(struct platform_device *pdev) | 408 | static int rsrc_card_probe(struct platform_device *pdev) |
453 | { | 409 | { |
454 | struct rsrc_card_priv *priv; | 410 | struct rsrc_card_priv *priv; |
455 | struct snd_soc_dai_link *dai_link; | ||
456 | struct device_node *np = pdev->dev.of_node; | 411 | struct device_node *np = pdev->dev.of_node; |
457 | struct device *dev = &pdev->dev; | 412 | struct device *dev = &pdev->dev; |
458 | int ret; | 413 | int ret; |
@@ -462,16 +417,7 @@ static int rsrc_card_probe(struct platform_device *pdev) | |||
462 | if (!priv) | 417 | if (!priv) |
463 | return -ENOMEM; | 418 | return -ENOMEM; |
464 | 419 | ||
465 | /* Init snd_soc_card */ | 420 | ret = rsrc_card_parse_of(np, priv, dev); |
466 | priv->snd_card.owner = THIS_MODULE; | ||
467 | priv->snd_card.dev = dev; | ||
468 | dai_link = priv->dai_link; | ||
469 | priv->snd_card.dai_link = dai_link; | ||
470 | priv->snd_card.num_links = RSRC_FB_NUM; | ||
471 | priv->snd_card.codec_conf = &priv->codec_conf; | ||
472 | priv->snd_card.num_configs = 1; | ||
473 | |||
474 | ret = rsrc_card_parse_of(np, priv); | ||
475 | if (ret < 0) { | 421 | if (ret < 0) { |
476 | if (ret != -EPROBE_DEFER) | 422 | if (ret != -EPROBE_DEFER) |
477 | dev_err(dev, "parse error %d\n", ret); | 423 | dev_err(dev, "parse error %d\n", ret); |
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index fbe9166e26d1..c61c17180142 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c | |||
@@ -117,10 +117,10 @@ struct rsnd_src { | |||
117 | /* | 117 | /* |
118 | * Gen1/Gen2 common functions | 118 | * Gen1/Gen2 common functions |
119 | */ | 119 | */ |
120 | static struct dma_chan *rsnd_src_dma_req(struct rsnd_mod *mod) | 120 | static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io, |
121 | struct rsnd_mod *mod) | ||
121 | { | 122 | { |
122 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 123 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
123 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
124 | int is_play = rsnd_io_is_play(io); | 124 | int is_play = rsnd_io_is_play(io); |
125 | 125 | ||
126 | return rsnd_dma_request_channel(rsnd_src_of_node(priv), | 126 | return rsnd_dma_request_channel(rsnd_src_of_node(priv), |
@@ -129,9 +129,9 @@ static struct dma_chan *rsnd_src_dma_req(struct rsnd_mod *mod) | |||
129 | } | 129 | } |
130 | 130 | ||
131 | int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, | 131 | int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, |
132 | struct rsnd_dai_stream *io, | ||
132 | int use_busif) | 133 | int use_busif) |
133 | { | 134 | { |
134 | struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod); | ||
135 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | 135 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); |
136 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 136 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
137 | int ssi_id = rsnd_mod_id(ssi_mod); | 137 | int ssi_id = rsnd_mod_id(ssi_mod); |
@@ -174,7 +174,7 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, | |||
174 | u32 mask = ~0; | 174 | u32 mask = ~0; |
175 | 175 | ||
176 | rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR, | 176 | rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR, |
177 | rsnd_get_adinr(ssi_mod)); | 177 | rsnd_get_adinr(ssi_mod, io)); |
178 | rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1); | 178 | rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1); |
179 | rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1); | 179 | rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1); |
180 | 180 | ||
@@ -196,7 +196,8 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, | |||
196 | return 0; | 196 | return 0; |
197 | } | 197 | } |
198 | 198 | ||
199 | int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod) | 199 | int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, |
200 | struct rsnd_dai_stream *io) | ||
200 | { | 201 | { |
201 | /* | 202 | /* |
202 | * DMA settings for SSIU | 203 | * DMA settings for SSIU |
@@ -235,10 +236,9 @@ int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod) | |||
235 | return 0; | 236 | return 0; |
236 | } | 237 | } |
237 | 238 | ||
238 | static u32 rsnd_src_convert_rate(struct rsnd_src *src) | 239 | static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io, |
240 | struct rsnd_src *src) | ||
239 | { | 241 | { |
240 | struct rsnd_mod *mod = &src->mod; | ||
241 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
242 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 242 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
243 | u32 convert_rate; | 243 | u32 convert_rate; |
244 | 244 | ||
@@ -274,7 +274,7 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, | |||
274 | * return convert rate if SRC is used, | 274 | * return convert rate if SRC is used, |
275 | * otherwise, return runtime->rate as usual | 275 | * otherwise, return runtime->rate as usual |
276 | */ | 276 | */ |
277 | rate = rsnd_src_convert_rate(src); | 277 | rate = rsnd_src_convert_rate(io, src); |
278 | } | 278 | } |
279 | 279 | ||
280 | if (!rate) | 280 | if (!rate) |
@@ -283,12 +283,12 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, | |||
283 | return rate; | 283 | return rate; |
284 | } | 284 | } |
285 | 285 | ||
286 | static int rsnd_src_set_convert_rate(struct rsnd_mod *mod) | 286 | static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, |
287 | struct rsnd_dai_stream *io) | ||
287 | { | 288 | { |
288 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
289 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 289 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
290 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 290 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
291 | u32 convert_rate = rsnd_src_convert_rate(src); | 291 | u32 convert_rate = rsnd_src_convert_rate(io, src); |
292 | u32 fsrate = 0; | 292 | u32 fsrate = 0; |
293 | 293 | ||
294 | if (convert_rate) | 294 | if (convert_rate) |
@@ -299,7 +299,7 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod) | |||
299 | rsnd_mod_write(mod, SRC_SWRSR, 1); | 299 | rsnd_mod_write(mod, SRC_SWRSR, 1); |
300 | 300 | ||
301 | /* Set channel number and output bit length */ | 301 | /* Set channel number and output bit length */ |
302 | rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod)); | 302 | rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod, io)); |
303 | 303 | ||
304 | /* Enable the initial value of IFS */ | 304 | /* Enable the initial value of IFS */ |
305 | if (fsrate) { | 305 | if (fsrate) { |
@@ -316,6 +316,7 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod) | |||
316 | } | 316 | } |
317 | 317 | ||
318 | static int rsnd_src_hw_params(struct rsnd_mod *mod, | 318 | static int rsnd_src_hw_params(struct rsnd_mod *mod, |
319 | struct rsnd_dai_stream *io, | ||
319 | struct snd_pcm_substream *substream, | 320 | struct snd_pcm_substream *substream, |
320 | struct snd_pcm_hw_params *fe_params) | 321 | struct snd_pcm_hw_params *fe_params) |
321 | { | 322 | { |
@@ -372,6 +373,7 @@ static int rsnd_src_init(struct rsnd_mod *mod, | |||
372 | } | 373 | } |
373 | 374 | ||
374 | static int rsnd_src_quit(struct rsnd_mod *mod, | 375 | static int rsnd_src_quit(struct rsnd_mod *mod, |
376 | struct rsnd_dai_stream *io, | ||
375 | struct rsnd_priv *priv) | 377 | struct rsnd_priv *priv) |
376 | { | 378 | { |
377 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 379 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
@@ -411,9 +413,9 @@ static int rsnd_src_stop(struct rsnd_mod *mod) | |||
411 | /* | 413 | /* |
412 | * Gen1 functions | 414 | * Gen1 functions |
413 | */ | 415 | */ |
414 | static int rsnd_src_set_route_gen1(struct rsnd_mod *mod) | 416 | static int rsnd_src_set_route_gen1(struct rsnd_dai_stream *io, |
417 | struct rsnd_mod *mod) | ||
415 | { | 418 | { |
416 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
417 | struct src_route_config { | 419 | struct src_route_config { |
418 | u32 mask; | 420 | u32 mask; |
419 | int shift; | 421 | int shift; |
@@ -448,13 +450,13 @@ static int rsnd_src_set_route_gen1(struct rsnd_mod *mod) | |||
448 | return 0; | 450 | return 0; |
449 | } | 451 | } |
450 | 452 | ||
451 | static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod) | 453 | static int rsnd_src_set_convert_timing_gen1(struct rsnd_dai_stream *io, |
454 | struct rsnd_mod *mod) | ||
452 | { | 455 | { |
453 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
454 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 456 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
455 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 457 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
456 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 458 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
457 | u32 convert_rate = rsnd_src_convert_rate(src); | 459 | u32 convert_rate = rsnd_src_convert_rate(io, src); |
458 | u32 mask; | 460 | u32 mask; |
459 | u32 val; | 461 | u32 val; |
460 | int shift; | 462 | int shift; |
@@ -506,12 +508,13 @@ static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod) | |||
506 | return 0; | 508 | return 0; |
507 | } | 509 | } |
508 | 510 | ||
509 | static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod) | 511 | static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, |
512 | struct rsnd_dai_stream *io) | ||
510 | { | 513 | { |
511 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 514 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
512 | int ret; | 515 | int ret; |
513 | 516 | ||
514 | ret = rsnd_src_set_convert_rate(mod); | 517 | ret = rsnd_src_set_convert_rate(mod, io); |
515 | if (ret < 0) | 518 | if (ret < 0) |
516 | return ret; | 519 | return ret; |
517 | 520 | ||
@@ -523,7 +526,7 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod) | |||
523 | rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98); | 526 | rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98); |
524 | 527 | ||
525 | /* Gen1/Gen2 are not compatible */ | 528 | /* Gen1/Gen2 are not compatible */ |
526 | if (rsnd_src_convert_rate(src)) | 529 | if (rsnd_src_convert_rate(io, src)) |
527 | rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); | 530 | rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); |
528 | 531 | ||
529 | /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */ | 532 | /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */ |
@@ -532,6 +535,7 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod) | |||
532 | } | 535 | } |
533 | 536 | ||
534 | static int rsnd_src_init_gen1(struct rsnd_mod *mod, | 537 | static int rsnd_src_init_gen1(struct rsnd_mod *mod, |
538 | struct rsnd_dai_stream *io, | ||
535 | struct rsnd_priv *priv) | 539 | struct rsnd_priv *priv) |
536 | { | 540 | { |
537 | int ret; | 541 | int ret; |
@@ -540,15 +544,15 @@ static int rsnd_src_init_gen1(struct rsnd_mod *mod, | |||
540 | if (ret < 0) | 544 | if (ret < 0) |
541 | return ret; | 545 | return ret; |
542 | 546 | ||
543 | ret = rsnd_src_set_route_gen1(mod); | 547 | ret = rsnd_src_set_route_gen1(io, mod); |
544 | if (ret < 0) | 548 | if (ret < 0) |
545 | return ret; | 549 | return ret; |
546 | 550 | ||
547 | ret = rsnd_src_set_convert_rate_gen1(mod); | 551 | ret = rsnd_src_set_convert_rate_gen1(mod, io); |
548 | if (ret < 0) | 552 | if (ret < 0) |
549 | return ret; | 553 | return ret; |
550 | 554 | ||
551 | ret = rsnd_src_set_convert_timing_gen1(mod); | 555 | ret = rsnd_src_set_convert_timing_gen1(io, mod); |
552 | if (ret < 0) | 556 | if (ret < 0) |
553 | return ret; | 557 | return ret; |
554 | 558 | ||
@@ -556,6 +560,7 @@ static int rsnd_src_init_gen1(struct rsnd_mod *mod, | |||
556 | } | 560 | } |
557 | 561 | ||
558 | static int rsnd_src_start_gen1(struct rsnd_mod *mod, | 562 | static int rsnd_src_start_gen1(struct rsnd_mod *mod, |
563 | struct rsnd_dai_stream *io, | ||
559 | struct rsnd_priv *priv) | 564 | struct rsnd_priv *priv) |
560 | { | 565 | { |
561 | int id = rsnd_mod_id(mod); | 566 | int id = rsnd_mod_id(mod); |
@@ -566,6 +571,7 @@ static int rsnd_src_start_gen1(struct rsnd_mod *mod, | |||
566 | } | 571 | } |
567 | 572 | ||
568 | static int rsnd_src_stop_gen1(struct rsnd_mod *mod, | 573 | static int rsnd_src_stop_gen1(struct rsnd_mod *mod, |
574 | struct rsnd_dai_stream *io, | ||
569 | struct rsnd_priv *priv) | 575 | struct rsnd_priv *priv) |
570 | { | 576 | { |
571 | int id = rsnd_mod_id(mod); | 577 | int id = rsnd_mod_id(mod); |
@@ -643,9 +649,9 @@ static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod) | |||
643 | return ret; | 649 | return ret; |
644 | } | 650 | } |
645 | 651 | ||
646 | static int _rsnd_src_start_gen2(struct rsnd_mod *mod) | 652 | static int _rsnd_src_start_gen2(struct rsnd_mod *mod, |
653 | struct rsnd_dai_stream *io) | ||
647 | { | 654 | { |
648 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
649 | u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11; | 655 | u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11; |
650 | 656 | ||
651 | rsnd_mod_write(mod, SRC_CTRL, val); | 657 | rsnd_mod_write(mod, SRC_CTRL, val); |
@@ -670,15 +676,15 @@ static int _rsnd_src_stop_gen2(struct rsnd_mod *mod) | |||
670 | return rsnd_src_stop(mod); | 676 | return rsnd_src_stop(mod); |
671 | } | 677 | } |
672 | 678 | ||
673 | static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) | 679 | static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod, |
680 | struct rsnd_dai_stream *io) | ||
674 | { | 681 | { |
675 | struct rsnd_mod *mod = data; | ||
676 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 682 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
677 | 683 | ||
678 | spin_lock(&priv->lock); | 684 | spin_lock(&priv->lock); |
679 | 685 | ||
680 | /* ignore all cases if not working */ | 686 | /* ignore all cases if not working */ |
681 | if (!rsnd_mod_is_working(mod)) | 687 | if (!rsnd_io_is_working(io)) |
682 | goto rsnd_src_interrupt_gen2_out; | 688 | goto rsnd_src_interrupt_gen2_out; |
683 | 689 | ||
684 | if (rsnd_src_error_record_gen2(mod)) { | 690 | if (rsnd_src_error_record_gen2(mod)) { |
@@ -691,24 +697,32 @@ static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) | |||
691 | 697 | ||
692 | _rsnd_src_stop_gen2(mod); | 698 | _rsnd_src_stop_gen2(mod); |
693 | if (src->err < 1024) | 699 | if (src->err < 1024) |
694 | _rsnd_src_start_gen2(mod); | 700 | _rsnd_src_start_gen2(mod, io); |
695 | else | 701 | else |
696 | dev_warn(dev, "no more SRC restart\n"); | 702 | dev_warn(dev, "no more SRC restart\n"); |
697 | } | 703 | } |
704 | |||
698 | rsnd_src_interrupt_gen2_out: | 705 | rsnd_src_interrupt_gen2_out: |
699 | spin_unlock(&priv->lock); | 706 | spin_unlock(&priv->lock); |
707 | } | ||
708 | |||
709 | static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) | ||
710 | { | ||
711 | struct rsnd_mod *mod = data; | ||
712 | |||
713 | rsnd_mod_interrupt(mod, __rsnd_src_interrupt_gen2); | ||
700 | 714 | ||
701 | return IRQ_HANDLED; | 715 | return IRQ_HANDLED; |
702 | } | 716 | } |
703 | 717 | ||
704 | static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod) | 718 | static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, |
719 | struct rsnd_dai_stream *io) | ||
705 | { | 720 | { |
706 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 721 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
707 | struct device *dev = rsnd_priv_to_dev(priv); | 722 | struct device *dev = rsnd_priv_to_dev(priv); |
708 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
709 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 723 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
710 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 724 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
711 | u32 convert_rate = rsnd_src_convert_rate(src); | 725 | u32 convert_rate = rsnd_src_convert_rate(io, src); |
712 | u32 cr, route; | 726 | u32 cr, route; |
713 | uint ratio; | 727 | uint ratio; |
714 | int ret; | 728 | int ret; |
@@ -726,7 +740,7 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod) | |||
726 | return -EINVAL; | 740 | return -EINVAL; |
727 | } | 741 | } |
728 | 742 | ||
729 | ret = rsnd_src_set_convert_rate(mod); | 743 | ret = rsnd_src_set_convert_rate(mod, io); |
730 | if (ret < 0) | 744 | if (ret < 0) |
731 | return ret; | 745 | return ret; |
732 | 746 | ||
@@ -762,12 +776,12 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod) | |||
762 | return 0; | 776 | return 0; |
763 | } | 777 | } |
764 | 778 | ||
765 | static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod) | 779 | static int rsnd_src_set_convert_timing_gen2(struct rsnd_dai_stream *io, |
780 | struct rsnd_mod *mod) | ||
766 | { | 781 | { |
767 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
768 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 782 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
769 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 783 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
770 | u32 convert_rate = rsnd_src_convert_rate(src); | 784 | u32 convert_rate = rsnd_src_convert_rate(io, src); |
771 | int ret; | 785 | int ret; |
772 | 786 | ||
773 | if (convert_rate) | 787 | if (convert_rate) |
@@ -781,6 +795,7 @@ static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod) | |||
781 | } | 795 | } |
782 | 796 | ||
783 | static int rsnd_src_probe_gen2(struct rsnd_mod *mod, | 797 | static int rsnd_src_probe_gen2(struct rsnd_mod *mod, |
798 | struct rsnd_dai_stream *io, | ||
784 | struct rsnd_priv *priv) | 799 | struct rsnd_priv *priv) |
785 | { | 800 | { |
786 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 801 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
@@ -802,7 +817,7 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod, | |||
802 | return ret; | 817 | return ret; |
803 | } | 818 | } |
804 | 819 | ||
805 | ret = rsnd_dma_init(priv, | 820 | ret = rsnd_dma_init(io, |
806 | rsnd_mod_to_dma(mod), | 821 | rsnd_mod_to_dma(mod), |
807 | src->info->dma_id); | 822 | src->info->dma_id); |
808 | 823 | ||
@@ -810,14 +825,16 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod, | |||
810 | } | 825 | } |
811 | 826 | ||
812 | static int rsnd_src_remove_gen2(struct rsnd_mod *mod, | 827 | static int rsnd_src_remove_gen2(struct rsnd_mod *mod, |
828 | struct rsnd_dai_stream *io, | ||
813 | struct rsnd_priv *priv) | 829 | struct rsnd_priv *priv) |
814 | { | 830 | { |
815 | rsnd_dma_quit(rsnd_mod_to_dma(mod)); | 831 | rsnd_dma_quit(io, rsnd_mod_to_dma(mod)); |
816 | 832 | ||
817 | return 0; | 833 | return 0; |
818 | } | 834 | } |
819 | 835 | ||
820 | static int rsnd_src_init_gen2(struct rsnd_mod *mod, | 836 | static int rsnd_src_init_gen2(struct rsnd_mod *mod, |
837 | struct rsnd_dai_stream *io, | ||
821 | struct rsnd_priv *priv) | 838 | struct rsnd_priv *priv) |
822 | { | 839 | { |
823 | int ret; | 840 | int ret; |
@@ -826,11 +843,11 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod, | |||
826 | if (ret < 0) | 843 | if (ret < 0) |
827 | return ret; | 844 | return ret; |
828 | 845 | ||
829 | ret = rsnd_src_set_convert_rate_gen2(mod); | 846 | ret = rsnd_src_set_convert_rate_gen2(mod, io); |
830 | if (ret < 0) | 847 | if (ret < 0) |
831 | return ret; | 848 | return ret; |
832 | 849 | ||
833 | ret = rsnd_src_set_convert_timing_gen2(mod); | 850 | ret = rsnd_src_set_convert_timing_gen2(io, mod); |
834 | if (ret < 0) | 851 | if (ret < 0) |
835 | return ret; | 852 | return ret; |
836 | 853 | ||
@@ -838,31 +855,33 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod, | |||
838 | } | 855 | } |
839 | 856 | ||
840 | static int rsnd_src_start_gen2(struct rsnd_mod *mod, | 857 | static int rsnd_src_start_gen2(struct rsnd_mod *mod, |
858 | struct rsnd_dai_stream *io, | ||
841 | struct rsnd_priv *priv) | 859 | struct rsnd_priv *priv) |
842 | { | 860 | { |
843 | rsnd_dma_start(rsnd_mod_to_dma(mod)); | 861 | rsnd_dma_start(io, rsnd_mod_to_dma(mod)); |
844 | 862 | ||
845 | return _rsnd_src_start_gen2(mod); | 863 | return _rsnd_src_start_gen2(mod, io); |
846 | } | 864 | } |
847 | 865 | ||
848 | static int rsnd_src_stop_gen2(struct rsnd_mod *mod, | 866 | static int rsnd_src_stop_gen2(struct rsnd_mod *mod, |
867 | struct rsnd_dai_stream *io, | ||
849 | struct rsnd_priv *priv) | 868 | struct rsnd_priv *priv) |
850 | { | 869 | { |
851 | int ret; | 870 | int ret; |
852 | 871 | ||
853 | ret = _rsnd_src_stop_gen2(mod); | 872 | ret = _rsnd_src_stop_gen2(mod); |
854 | 873 | ||
855 | rsnd_dma_stop(rsnd_mod_to_dma(mod)); | 874 | rsnd_dma_stop(io, rsnd_mod_to_dma(mod)); |
856 | 875 | ||
857 | return ret; | 876 | return ret; |
858 | } | 877 | } |
859 | 878 | ||
860 | static void rsnd_src_reconvert_update(struct rsnd_mod *mod) | 879 | static void rsnd_src_reconvert_update(struct rsnd_dai_stream *io, |
880 | struct rsnd_mod *mod) | ||
861 | { | 881 | { |
862 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
863 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 882 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
864 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 883 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
865 | u32 convert_rate = rsnd_src_convert_rate(src); | 884 | u32 convert_rate = rsnd_src_convert_rate(io, src); |
866 | u32 fsrate; | 885 | u32 fsrate; |
867 | 886 | ||
868 | if (!runtime) | 887 | if (!runtime) |
@@ -878,10 +897,10 @@ static void rsnd_src_reconvert_update(struct rsnd_mod *mod) | |||
878 | } | 897 | } |
879 | 898 | ||
880 | static int rsnd_src_pcm_new(struct rsnd_mod *mod, | 899 | static int rsnd_src_pcm_new(struct rsnd_mod *mod, |
900 | struct rsnd_dai_stream *io, | ||
881 | struct snd_soc_pcm_runtime *rtd) | 901 | struct snd_soc_pcm_runtime *rtd) |
882 | { | 902 | { |
883 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 903 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
884 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
885 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | 904 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); |
886 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 905 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
887 | int ret; | 906 | int ret; |
@@ -912,7 +931,7 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod, | |||
912 | /* | 931 | /* |
913 | * enable sync convert | 932 | * enable sync convert |
914 | */ | 933 | */ |
915 | ret = rsnd_kctrl_new_s(mod, rtd, | 934 | ret = rsnd_kctrl_new_s(mod, io, rtd, |
916 | rsnd_io_is_play(io) ? | 935 | rsnd_io_is_play(io) ? |
917 | "SRC Out Rate Switch" : | 936 | "SRC Out Rate Switch" : |
918 | "SRC In Rate Switch", | 937 | "SRC In Rate Switch", |
@@ -921,7 +940,7 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod, | |||
921 | if (ret < 0) | 940 | if (ret < 0) |
922 | return ret; | 941 | return ret; |
923 | 942 | ||
924 | ret = rsnd_kctrl_new_s(mod, rtd, | 943 | ret = rsnd_kctrl_new_s(mod, io, rtd, |
925 | rsnd_io_is_play(io) ? | 944 | rsnd_io_is_play(io) ? |
926 | "SRC Out Rate" : | 945 | "SRC Out Rate" : |
927 | "SRC In Rate", | 946 | "SRC In Rate", |
@@ -1046,7 +1065,7 @@ int rsnd_src_probe(struct platform_device *pdev, | |||
1046 | 1065 | ||
1047 | src->info = &info->src_info[i]; | 1066 | src->info = &info->src_info[i]; |
1048 | 1067 | ||
1049 | ret = rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i); | 1068 | ret = rsnd_mod_init(priv, &src->mod, ops, clk, RSND_MOD_SRC, i); |
1050 | if (ret) | 1069 | if (ret) |
1051 | return ret; | 1070 | return ret; |
1052 | } | 1071 | } |
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 50fa3928a003..2fbe59f7f9b5 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c | |||
@@ -87,10 +87,9 @@ struct rsnd_ssi { | |||
87 | #define rsnd_ssi_of_node(priv) \ | 87 | #define rsnd_ssi_of_node(priv) \ |
88 | of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi") | 88 | of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi") |
89 | 89 | ||
90 | int rsnd_ssi_use_busif(struct rsnd_mod *mod) | 90 | int rsnd_ssi_use_busif(struct rsnd_dai_stream *io, struct rsnd_mod *mod) |
91 | { | 91 | { |
92 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 92 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
93 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
94 | int use_busif = 0; | 93 | int use_busif = 0; |
95 | 94 | ||
96 | if (!rsnd_ssi_is_dma_mode(mod)) | 95 | if (!rsnd_ssi_is_dma_mode(mod)) |
@@ -199,15 +198,17 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, | |||
199 | } | 198 | } |
200 | } | 199 | } |
201 | 200 | ||
202 | cr_mode = rsnd_ssi_is_dma_mode(&ssi->mod) ? | 201 | if (rsnd_ssi_is_dma_mode(&ssi->mod)) { |
203 | DMEN : /* DMA : enable DMA */ | 202 | cr_mode = UIEN | OIEN | /* over/under run */ |
204 | DIEN; /* PIO : enable Data interrupt */ | 203 | DMEN; /* DMA : enable DMA */ |
205 | 204 | } else { | |
205 | cr_mode = DIEN; /* PIO : enable Data interrupt */ | ||
206 | } | ||
206 | 207 | ||
207 | cr = ssi->cr_own | | 208 | cr = ssi->cr_own | |
208 | ssi->cr_clk | | 209 | ssi->cr_clk | |
209 | cr_mode | | 210 | cr_mode | |
210 | UIEN | OIEN | EN; | 211 | EN; |
211 | 212 | ||
212 | rsnd_mod_write(&ssi->mod, SSICR, cr); | 213 | rsnd_mod_write(&ssi->mod, SSICR, cr); |
213 | 214 | ||
@@ -224,10 +225,9 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, | |||
224 | rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); | 225 | rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); |
225 | } | 226 | } |
226 | 227 | ||
227 | static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi) | 228 | static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi) |
228 | { | 229 | { |
229 | struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); | 230 | struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); |
230 | struct rsnd_dai_stream *io = rsnd_mod_to_io(&ssi->mod); | ||
231 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | 231 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); |
232 | struct device *dev = rsnd_priv_to_dev(priv); | 232 | struct device *dev = rsnd_priv_to_dev(priv); |
233 | u32 cr; | 233 | u32 cr; |
@@ -261,7 +261,7 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi) | |||
261 | struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi); | 261 | struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi); |
262 | 262 | ||
263 | if (ssi_parent) | 263 | if (ssi_parent) |
264 | rsnd_ssi_hw_stop(ssi_parent); | 264 | rsnd_ssi_hw_stop(io, ssi_parent); |
265 | else | 265 | else |
266 | rsnd_ssi_master_clk_stop(ssi); | 266 | rsnd_ssi_master_clk_stop(ssi); |
267 | } | 267 | } |
@@ -279,10 +279,10 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi) | |||
279 | * SSI mod common functions | 279 | * SSI mod common functions |
280 | */ | 280 | */ |
281 | static int rsnd_ssi_init(struct rsnd_mod *mod, | 281 | static int rsnd_ssi_init(struct rsnd_mod *mod, |
282 | struct rsnd_dai_stream *io, | ||
282 | struct rsnd_priv *priv) | 283 | struct rsnd_priv *priv) |
283 | { | 284 | { |
284 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 285 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
285 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
286 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | 286 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); |
287 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 287 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
288 | u32 cr; | 288 | u32 cr; |
@@ -330,6 +330,7 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, | |||
330 | } | 330 | } |
331 | 331 | ||
332 | static int rsnd_ssi_quit(struct rsnd_mod *mod, | 332 | static int rsnd_ssi_quit(struct rsnd_mod *mod, |
333 | struct rsnd_dai_stream *io, | ||
333 | struct rsnd_priv *priv) | 334 | struct rsnd_priv *priv) |
334 | { | 335 | { |
335 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 336 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
@@ -346,6 +347,7 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod, | |||
346 | } | 347 | } |
347 | 348 | ||
348 | static int rsnd_ssi_hw_params(struct rsnd_mod *mod, | 349 | static int rsnd_ssi_hw_params(struct rsnd_mod *mod, |
350 | struct rsnd_dai_stream *io, | ||
349 | struct snd_pcm_substream *substream, | 351 | struct snd_pcm_substream *substream, |
350 | struct snd_pcm_hw_params *params) | 352 | struct snd_pcm_hw_params *params) |
351 | { | 353 | { |
@@ -369,7 +371,8 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod, | |||
369 | /* It will be removed on rsnd_ssi_hw_stop */ | 371 | /* It will be removed on rsnd_ssi_hw_stop */ |
370 | ssi->chan = chan; | 372 | ssi->chan = chan; |
371 | if (ssi_parent) | 373 | if (ssi_parent) |
372 | return rsnd_ssi_hw_params(&ssi_parent->mod, substream, params); | 374 | return rsnd_ssi_hw_params(&ssi_parent->mod, io, |
375 | substream, params); | ||
373 | 376 | ||
374 | return 0; | 377 | return 0; |
375 | } | 378 | } |
@@ -386,12 +389,12 @@ static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status) | |||
386 | } | 389 | } |
387 | 390 | ||
388 | static int rsnd_ssi_start(struct rsnd_mod *mod, | 391 | static int rsnd_ssi_start(struct rsnd_mod *mod, |
392 | struct rsnd_dai_stream *io, | ||
389 | struct rsnd_priv *priv) | 393 | struct rsnd_priv *priv) |
390 | { | 394 | { |
391 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 395 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
392 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
393 | 396 | ||
394 | rsnd_src_ssiu_start(mod, rsnd_ssi_use_busif(mod)); | 397 | rsnd_src_ssiu_start(mod, io, rsnd_ssi_use_busif(io, mod)); |
395 | 398 | ||
396 | rsnd_ssi_hw_start(ssi, io); | 399 | rsnd_ssi_hw_start(ssi, io); |
397 | 400 | ||
@@ -401,6 +404,7 @@ static int rsnd_ssi_start(struct rsnd_mod *mod, | |||
401 | } | 404 | } |
402 | 405 | ||
403 | static int rsnd_ssi_stop(struct rsnd_mod *mod, | 406 | static int rsnd_ssi_stop(struct rsnd_mod *mod, |
407 | struct rsnd_dai_stream *io, | ||
404 | struct rsnd_priv *priv) | 408 | struct rsnd_priv *priv) |
405 | { | 409 | { |
406 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 410 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
@@ -409,26 +413,26 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod, | |||
409 | 413 | ||
410 | rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); | 414 | rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); |
411 | 415 | ||
412 | rsnd_ssi_hw_stop(ssi); | 416 | rsnd_ssi_hw_stop(io, ssi); |
413 | 417 | ||
414 | rsnd_src_ssiu_stop(mod); | 418 | rsnd_src_ssiu_stop(mod, io); |
415 | 419 | ||
416 | return 0; | 420 | return 0; |
417 | } | 421 | } |
418 | 422 | ||
419 | static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | 423 | static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, |
424 | struct rsnd_dai_stream *io) | ||
420 | { | 425 | { |
421 | struct rsnd_ssi *ssi = data; | 426 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
422 | struct rsnd_mod *mod = &ssi->mod; | ||
423 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 427 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
424 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
425 | int is_dma = rsnd_ssi_is_dma_mode(mod); | 428 | int is_dma = rsnd_ssi_is_dma_mode(mod); |
426 | u32 status; | 429 | u32 status; |
430 | bool elapsed = false; | ||
427 | 431 | ||
428 | spin_lock(&priv->lock); | 432 | spin_lock(&priv->lock); |
429 | 433 | ||
430 | /* ignore all cases if not working */ | 434 | /* ignore all cases if not working */ |
431 | if (!rsnd_mod_is_working(mod)) | 435 | if (!rsnd_io_is_working(io)) |
432 | goto rsnd_ssi_interrupt_out; | 436 | goto rsnd_ssi_interrupt_out; |
433 | 437 | ||
434 | status = rsnd_mod_read(mod, SSISR); | 438 | status = rsnd_mod_read(mod, SSISR); |
@@ -449,11 +453,11 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | |||
449 | else | 453 | else |
450 | *buf = rsnd_mod_read(mod, SSIRDR); | 454 | *buf = rsnd_mod_read(mod, SSIRDR); |
451 | 455 | ||
452 | rsnd_dai_pointer_update(io, sizeof(*buf)); | 456 | elapsed = rsnd_dai_pointer_update(io, sizeof(*buf)); |
453 | } | 457 | } |
454 | 458 | ||
455 | /* PIO / DMA */ | 459 | /* DMA only */ |
456 | if (status & (UIRQ | OIRQ)) { | 460 | if (is_dma && (status & (UIRQ | OIRQ))) { |
457 | struct device *dev = rsnd_priv_to_dev(priv); | 461 | struct device *dev = rsnd_priv_to_dev(priv); |
458 | 462 | ||
459 | /* | 463 | /* |
@@ -462,9 +466,9 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | |||
462 | dev_dbg(dev, "%s[%d] restart\n", | 466 | dev_dbg(dev, "%s[%d] restart\n", |
463 | rsnd_mod_name(mod), rsnd_mod_id(mod)); | 467 | rsnd_mod_name(mod), rsnd_mod_id(mod)); |
464 | 468 | ||
465 | rsnd_ssi_stop(mod, priv); | 469 | rsnd_ssi_stop(mod, io, priv); |
466 | if (ssi->err < 1024) | 470 | if (ssi->err < 1024) |
467 | rsnd_ssi_start(mod, priv); | 471 | rsnd_ssi_start(mod, io, priv); |
468 | else | 472 | else |
469 | dev_warn(dev, "no more SSI restart\n"); | 473 | dev_warn(dev, "no more SSI restart\n"); |
470 | } | 474 | } |
@@ -474,6 +478,16 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | |||
474 | rsnd_ssi_interrupt_out: | 478 | rsnd_ssi_interrupt_out: |
475 | spin_unlock(&priv->lock); | 479 | spin_unlock(&priv->lock); |
476 | 480 | ||
481 | if (elapsed) | ||
482 | rsnd_dai_period_elapsed(io); | ||
483 | } | ||
484 | |||
485 | static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | ||
486 | { | ||
487 | struct rsnd_mod *mod = data; | ||
488 | |||
489 | rsnd_mod_interrupt(mod, __rsnd_ssi_interrupt); | ||
490 | |||
477 | return IRQ_HANDLED; | 491 | return IRQ_HANDLED; |
478 | } | 492 | } |
479 | 493 | ||
@@ -481,6 +495,7 @@ rsnd_ssi_interrupt_out: | |||
481 | * SSI PIO | 495 | * SSI PIO |
482 | */ | 496 | */ |
483 | static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, | 497 | static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, |
498 | struct rsnd_dai_stream *io, | ||
484 | struct rsnd_priv *priv) | 499 | struct rsnd_priv *priv) |
485 | { | 500 | { |
486 | struct device *dev = rsnd_priv_to_dev(priv); | 501 | struct device *dev = rsnd_priv_to_dev(priv); |
@@ -490,7 +505,7 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, | |||
490 | ret = devm_request_irq(dev, ssi->info->irq, | 505 | ret = devm_request_irq(dev, ssi->info->irq, |
491 | rsnd_ssi_interrupt, | 506 | rsnd_ssi_interrupt, |
492 | IRQF_SHARED, | 507 | IRQF_SHARED, |
493 | dev_name(dev), ssi); | 508 | dev_name(dev), mod); |
494 | 509 | ||
495 | return ret; | 510 | return ret; |
496 | } | 511 | } |
@@ -506,6 +521,7 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = { | |||
506 | }; | 521 | }; |
507 | 522 | ||
508 | static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, | 523 | static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, |
524 | struct rsnd_dai_stream *io, | ||
509 | struct rsnd_priv *priv) | 525 | struct rsnd_priv *priv) |
510 | { | 526 | { |
511 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 527 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
@@ -516,25 +532,26 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, | |||
516 | ret = devm_request_irq(dev, ssi->info->irq, | 532 | ret = devm_request_irq(dev, ssi->info->irq, |
517 | rsnd_ssi_interrupt, | 533 | rsnd_ssi_interrupt, |
518 | IRQF_SHARED, | 534 | IRQF_SHARED, |
519 | dev_name(dev), ssi); | 535 | dev_name(dev), mod); |
520 | if (ret) | 536 | if (ret) |
521 | return ret; | 537 | return ret; |
522 | 538 | ||
523 | ret = rsnd_dma_init( | 539 | ret = rsnd_dma_init( |
524 | priv, rsnd_mod_to_dma(mod), | 540 | io, rsnd_mod_to_dma(mod), |
525 | dma_id); | 541 | dma_id); |
526 | 542 | ||
527 | return ret; | 543 | return ret; |
528 | } | 544 | } |
529 | 545 | ||
530 | static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, | 546 | static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, |
547 | struct rsnd_dai_stream *io, | ||
531 | struct rsnd_priv *priv) | 548 | struct rsnd_priv *priv) |
532 | { | 549 | { |
533 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 550 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
534 | struct device *dev = rsnd_priv_to_dev(priv); | 551 | struct device *dev = rsnd_priv_to_dev(priv); |
535 | int irq = ssi->info->irq; | 552 | int irq = ssi->info->irq; |
536 | 553 | ||
537 | rsnd_dma_quit(rsnd_mod_to_dma(mod)); | 554 | rsnd_dma_quit(io, rsnd_mod_to_dma(mod)); |
538 | 555 | ||
539 | /* PIO will request IRQ again */ | 556 | /* PIO will request IRQ again */ |
540 | devm_free_irq(dev, irq, ssi); | 557 | devm_free_irq(dev, irq, ssi); |
@@ -543,6 +560,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, | |||
543 | } | 560 | } |
544 | 561 | ||
545 | static int rsnd_ssi_fallback(struct rsnd_mod *mod, | 562 | static int rsnd_ssi_fallback(struct rsnd_mod *mod, |
563 | struct rsnd_dai_stream *io, | ||
546 | struct rsnd_priv *priv) | 564 | struct rsnd_priv *priv) |
547 | { | 565 | { |
548 | struct device *dev = rsnd_priv_to_dev(priv); | 566 | struct device *dev = rsnd_priv_to_dev(priv); |
@@ -563,37 +581,39 @@ static int rsnd_ssi_fallback(struct rsnd_mod *mod, | |||
563 | } | 581 | } |
564 | 582 | ||
565 | static int rsnd_ssi_dma_start(struct rsnd_mod *mod, | 583 | static int rsnd_ssi_dma_start(struct rsnd_mod *mod, |
584 | struct rsnd_dai_stream *io, | ||
566 | struct rsnd_priv *priv) | 585 | struct rsnd_priv *priv) |
567 | { | 586 | { |
568 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); | 587 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); |
569 | 588 | ||
570 | rsnd_dma_start(dma); | 589 | rsnd_dma_start(io, dma); |
571 | 590 | ||
572 | rsnd_ssi_start(mod, priv); | 591 | rsnd_ssi_start(mod, io, priv); |
573 | 592 | ||
574 | return 0; | 593 | return 0; |
575 | } | 594 | } |
576 | 595 | ||
577 | static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, | 596 | static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, |
597 | struct rsnd_dai_stream *io, | ||
578 | struct rsnd_priv *priv) | 598 | struct rsnd_priv *priv) |
579 | { | 599 | { |
580 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); | 600 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); |
581 | 601 | ||
582 | rsnd_ssi_stop(mod, priv); | 602 | rsnd_ssi_stop(mod, io, priv); |
583 | 603 | ||
584 | rsnd_dma_stop(dma); | 604 | rsnd_dma_stop(io, dma); |
585 | 605 | ||
586 | return 0; | 606 | return 0; |
587 | } | 607 | } |
588 | 608 | ||
589 | static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_mod *mod) | 609 | static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_dai_stream *io, |
610 | struct rsnd_mod *mod) | ||
590 | { | 611 | { |
591 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 612 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
592 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
593 | int is_play = rsnd_io_is_play(io); | 613 | int is_play = rsnd_io_is_play(io); |
594 | char *name; | 614 | char *name; |
595 | 615 | ||
596 | if (rsnd_ssi_use_busif(mod)) | 616 | if (rsnd_ssi_use_busif(io, mod)) |
597 | name = is_play ? "rxu" : "txu"; | 617 | name = is_play ? "rxu" : "txu"; |
598 | else | 618 | else |
599 | name = is_play ? "rx" : "tx"; | 619 | name = is_play ? "rx" : "tx"; |
@@ -776,7 +796,7 @@ int rsnd_ssi_probe(struct platform_device *pdev, | |||
776 | else if (rsnd_ssi_pio_available(ssi)) | 796 | else if (rsnd_ssi_pio_available(ssi)) |
777 | ops = &rsnd_ssi_pio_ops; | 797 | ops = &rsnd_ssi_pio_ops; |
778 | 798 | ||
779 | ret = rsnd_mod_init(&ssi->mod, ops, clk, RSND_MOD_SSI, i); | 799 | ret = rsnd_mod_init(priv, &ssi->mod, ops, clk, RSND_MOD_SSI, i); |
780 | if (ret) | 800 | if (ret) |
781 | return ret; | 801 | return ret; |
782 | 802 | ||
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index 5bdb781163d1..9b0d8baf2934 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile | |||
@@ -5,8 +5,10 @@ include ../lib.mk | |||
5 | .PHONY: all all_32 all_64 warn_32bit_failure clean | 5 | .PHONY: all all_32 all_64 warn_32bit_failure clean |
6 | 6 | ||
7 | TARGETS_C_BOTHBITS := sigreturn single_step_syscall | 7 | TARGETS_C_BOTHBITS := sigreturn single_step_syscall |
8 | TARGETS_C_32BIT_ONLY := entry_from_vm86 | ||
8 | 9 | ||
9 | BINARIES_32 := $(TARGETS_C_BOTHBITS:%=%_32) | 10 | TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) |
11 | BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32) | ||
10 | BINARIES_64 := $(TARGETS_C_BOTHBITS:%=%_64) | 12 | BINARIES_64 := $(TARGETS_C_BOTHBITS:%=%_64) |
11 | 13 | ||
12 | CFLAGS := -O2 -g -std=gnu99 -pthread -Wall | 14 | CFLAGS := -O2 -g -std=gnu99 -pthread -Wall |
@@ -32,7 +34,7 @@ all_64: $(BINARIES_64) | |||
32 | clean: | 34 | clean: |
33 | $(RM) $(BINARIES_32) $(BINARIES_64) | 35 | $(RM) $(BINARIES_32) $(BINARIES_64) |
34 | 36 | ||
35 | $(TARGETS_C_BOTHBITS:%=%_32): %_32: %.c | 37 | $(TARGETS_C_32BIT_ALL:%=%_32): %_32: %.c |
36 | $(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl | 38 | $(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl |
37 | 39 | ||
38 | $(TARGETS_C_BOTHBITS:%=%_64): %_64: %.c | 40 | $(TARGETS_C_BOTHBITS:%=%_64): %_64: %.c |
diff --git a/tools/testing/selftests/x86/entry_from_vm86.c b/tools/testing/selftests/x86/entry_from_vm86.c new file mode 100644 index 000000000000..5c38a187677b --- /dev/null +++ b/tools/testing/selftests/x86/entry_from_vm86.c | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * entry_from_vm86.c - tests kernel entries from vm86 mode | ||
3 | * Copyright (c) 2014-2015 Andrew Lutomirski | ||
4 | * | ||
5 | * This exercises a few paths that need to special-case vm86 mode. | ||
6 | * | ||
7 | * GPL v2. | ||
8 | */ | ||
9 | |||
10 | #define _GNU_SOURCE | ||
11 | |||
12 | #include <assert.h> | ||
13 | #include <stdlib.h> | ||
14 | #include <sys/syscall.h> | ||
15 | #include <sys/signal.h> | ||
16 | #include <sys/ucontext.h> | ||
17 | #include <unistd.h> | ||
18 | #include <stdio.h> | ||
19 | #include <string.h> | ||
20 | #include <inttypes.h> | ||
21 | #include <sys/mman.h> | ||
22 | #include <err.h> | ||
23 | #include <stddef.h> | ||
24 | #include <stdbool.h> | ||
25 | #include <errno.h> | ||
26 | #include <sys/vm86.h> | ||
27 | |||
28 | static unsigned long load_addr = 0x10000; | ||
29 | static int nerrs = 0; | ||
30 | |||
31 | asm ( | ||
32 | ".pushsection .rodata\n\t" | ||
33 | ".type vmcode_bound, @object\n\t" | ||
34 | "vmcode:\n\t" | ||
35 | "vmcode_bound:\n\t" | ||
36 | ".code16\n\t" | ||
37 | "bound %ax, (2048)\n\t" | ||
38 | "int3\n\t" | ||
39 | "vmcode_sysenter:\n\t" | ||
40 | "sysenter\n\t" | ||
41 | ".size vmcode, . - vmcode\n\t" | ||
42 | "end_vmcode:\n\t" | ||
43 | ".code32\n\t" | ||
44 | ".popsection" | ||
45 | ); | ||
46 | |||
47 | extern unsigned char vmcode[], end_vmcode[]; | ||
48 | extern unsigned char vmcode_bound[], vmcode_sysenter[]; | ||
49 | |||
50 | static void do_test(struct vm86plus_struct *v86, unsigned long eip, | ||
51 | const char *text) | ||
52 | { | ||
53 | long ret; | ||
54 | |||
55 | printf("[RUN]\t%s from vm86 mode\n", text); | ||
56 | v86->regs.eip = eip; | ||
57 | ret = vm86(VM86_ENTER, v86); | ||
58 | |||
59 | if (ret == -1 && errno == ENOSYS) { | ||
60 | printf("[SKIP]\tvm86 not supported\n"); | ||
61 | return; | ||
62 | } | ||
63 | |||
64 | if (VM86_TYPE(ret) == VM86_INTx) { | ||
65 | char trapname[32]; | ||
66 | int trapno = VM86_ARG(ret); | ||
67 | if (trapno == 13) | ||
68 | strcpy(trapname, "GP"); | ||
69 | else if (trapno == 5) | ||
70 | strcpy(trapname, "BR"); | ||
71 | else if (trapno == 14) | ||
72 | strcpy(trapname, "PF"); | ||
73 | else | ||
74 | sprintf(trapname, "%d", trapno); | ||
75 | |||
76 | printf("[OK]\tExited vm86 mode due to #%s\n", trapname); | ||
77 | } else if (VM86_TYPE(ret) == VM86_UNKNOWN) { | ||
78 | printf("[OK]\tExited vm86 mode due to unhandled GP fault\n"); | ||
79 | } else { | ||
80 | printf("[OK]\tExited vm86 mode due to type %ld, arg %ld\n", | ||
81 | VM86_TYPE(ret), VM86_ARG(ret)); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | int main(void) | ||
86 | { | ||
87 | struct vm86plus_struct v86; | ||
88 | unsigned char *addr = mmap((void *)load_addr, 4096, | ||
89 | PROT_READ | PROT_WRITE | PROT_EXEC, | ||
90 | MAP_ANONYMOUS | MAP_PRIVATE, -1,0); | ||
91 | if (addr != (unsigned char *)load_addr) | ||
92 | err(1, "mmap"); | ||
93 | |||
94 | memcpy(addr, vmcode, end_vmcode - vmcode); | ||
95 | addr[2048] = 2; | ||
96 | addr[2050] = 3; | ||
97 | |||
98 | memset(&v86, 0, sizeof(v86)); | ||
99 | |||
100 | v86.regs.cs = load_addr / 16; | ||
101 | v86.regs.ss = load_addr / 16; | ||
102 | v86.regs.ds = load_addr / 16; | ||
103 | v86.regs.es = load_addr / 16; | ||
104 | |||
105 | assert((v86.regs.cs & 3) == 0); /* Looks like RPL = 0 */ | ||
106 | |||
107 | /* #BR -- should deliver SIG??? */ | ||
108 | do_test(&v86, vmcode_bound - vmcode, "#BR"); | ||
109 | |||
110 | /* SYSENTER -- should cause #GP or #UD depending on CPU */ | ||
111 | do_test(&v86, vmcode_sysenter - vmcode, "SYSENTER"); | ||
112 | |||
113 | return (nerrs == 0 ? 0 : 1); | ||
114 | } | ||