diff options
author | Takashi Iwai <tiwai@suse.de> | 2016-09-30 12:40:40 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2016-09-30 12:40:40 -0400 |
commit | eeea8b40cd2866ca24f25e5ef09225edb076ae45 (patch) | |
tree | ece5b5287ee2ce53a841b66d0f526947f74d036f | |
parent | 3383c5c395386ac8e258b1a324c72ce850b84a9e (diff) | |
parent | 513e43efafe329dad7b5794583b67ac898dcbdca (diff) |
Merge tag 'asoc-v4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v4.9
Apart from the cleanups done by Morimoto-san this has very much been a
driver focused release with very little generic change:
- A big factoring out of the simple-card code to allow it to be shared
more with the rcar generic card from Kuninori Morimoto.
- Removal of some operations duplicated on the CODEC level, again by
Kuninori Morimoto.
- Lots more machine support for x86 systems.
- New drivers for Nuvoton NAU88C10, Realtek RT5660 and RT5663.
1364 files changed, 24708 insertions, 8897 deletions
@@ -88,6 +88,7 @@ Kay Sievers <kay.sievers@vrfy.org> | |||
88 | Kenneth W Chen <kenneth.w.chen@intel.com> | 88 | Kenneth W Chen <kenneth.w.chen@intel.com> |
89 | Konstantin Khlebnikov <koct9i@gmail.com> <k.khlebnikov@samsung.com> | 89 | Konstantin Khlebnikov <koct9i@gmail.com> <k.khlebnikov@samsung.com> |
90 | Koushik <raghavendra.koushik@neterion.com> | 90 | Koushik <raghavendra.koushik@neterion.com> |
91 | Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski@samsung.com> | ||
91 | Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski.k@gmail.com> | 92 | Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski.k@gmail.com> |
92 | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 93 | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
93 | Leonid I Ananiev <leonid.i.ananiev@intel.com> | 94 | Leonid I Ananiev <leonid.i.ananiev@intel.com> |
@@ -158,6 +159,8 @@ Valdis Kletnieks <Valdis.Kletnieks@vt.edu> | |||
158 | Viresh Kumar <vireshk@kernel.org> <viresh.kumar@st.com> | 159 | Viresh Kumar <vireshk@kernel.org> <viresh.kumar@st.com> |
159 | Viresh Kumar <vireshk@kernel.org> <viresh.linux@gmail.com> | 160 | Viresh Kumar <vireshk@kernel.org> <viresh.linux@gmail.com> |
160 | Viresh Kumar <vireshk@kernel.org> <viresh.kumar2@arm.com> | 161 | Viresh Kumar <vireshk@kernel.org> <viresh.kumar2@arm.com> |
162 | Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@virtuozzo.com> | ||
163 | Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@parallels.com> | ||
161 | Takashi YOSHII <takashi.yoshii.zj@renesas.com> | 164 | Takashi YOSHII <takashi.yoshii.zj@renesas.com> |
162 | Yusuke Goda <goda.yusuke@renesas.com> | 165 | Yusuke Goda <goda.yusuke@renesas.com> |
163 | Gustavo Padovan <gustavo@las.ic.unicamp.br> | 166 | Gustavo Padovan <gustavo@las.ic.unicamp.br> |
diff --git a/Documentation/ABI/stable/sysfs-devices b/Documentation/ABI/stable/sysfs-devices index 43f78b88da28..df449d79b563 100644 --- a/Documentation/ABI/stable/sysfs-devices +++ b/Documentation/ABI/stable/sysfs-devices | |||
@@ -1,7 +1,7 @@ | |||
1 | # Note: This documents additional properties of any device beyond what | 1 | # Note: This documents additional properties of any device beyond what |
2 | # is documented in Documentation/sysfs-rules.txt | 2 | # is documented in Documentation/sysfs-rules.txt |
3 | 3 | ||
4 | What: /sys/devices/*/of_path | 4 | What: /sys/devices/*/of_node |
5 | Date: February 2015 | 5 | Date: February 2015 |
6 | Contact: Device Tree mailing list <devicetree@vger.kernel.org> | 6 | Contact: Device Tree mailing list <devicetree@vger.kernel.org> |
7 | Description: | 7 | Description: |
diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt index c55df2911136..cd9c9f6a7cd9 100644 --- a/Documentation/PCI/MSI-HOWTO.txt +++ b/Documentation/PCI/MSI-HOWTO.txt | |||
@@ -94,14 +94,11 @@ has a requirements for a minimum number of vectors the driver can pass a | |||
94 | min_vecs argument set to this limit, and the PCI core will return -ENOSPC | 94 | min_vecs argument set to this limit, and the PCI core will return -ENOSPC |
95 | if it can't meet the minimum number of vectors. | 95 | if it can't meet the minimum number of vectors. |
96 | 96 | ||
97 | The flags argument should normally be set to 0, but can be used to pass the | 97 | The flags argument is used to specify which type of interrupt can be used |
98 | PCI_IRQ_NOMSI and PCI_IRQ_NOMSIX flag in case a device claims to support | 98 | by the device and the driver (PCI_IRQ_LEGACY, PCI_IRQ_MSI, PCI_IRQ_MSIX). |
99 | MSI or MSI-X, but the support is broken, or to pass PCI_IRQ_NOLEGACY in | 99 | A convenient short-hand (PCI_IRQ_ALL_TYPES) is also available to ask for |
100 | case the device does not support legacy interrupt lines. | 100 | any possible kind of interrupt. If the PCI_IRQ_AFFINITY flag is set, |
101 | 101 | pci_alloc_irq_vectors() will spread the interrupts around the available CPUs. | |
102 | By default this function will spread the interrupts around the available | ||
103 | CPUs, but this feature can be disabled by passing the PCI_IRQ_NOAFFINITY | ||
104 | flag. | ||
105 | 102 | ||
106 | To get the Linux IRQ numbers passed to request_irq() and free_irq() and the | 103 | To get the Linux IRQ numbers passed to request_irq() and free_irq() and the |
107 | vectors, use the following function: | 104 | vectors, use the following function: |
@@ -131,7 +128,7 @@ larger than the number supported by the device it will automatically be | |||
131 | capped to the supported limit, so there is no need to query the number of | 128 | capped to the supported limit, so there is no need to query the number of |
132 | vectors supported beforehand: | 129 | vectors supported beforehand: |
133 | 130 | ||
134 | nvec = pci_alloc_irq_vectors(pdev, 1, nvec, 0); | 131 | nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_ALL_TYPES) |
135 | if (nvec < 0) | 132 | if (nvec < 0) |
136 | goto out_err; | 133 | goto out_err; |
137 | 134 | ||
@@ -140,7 +137,7 @@ interrupts it can request a particular number of interrupts by passing that | |||
140 | number to pci_alloc_irq_vectors() function as both 'min_vecs' and | 137 | number to pci_alloc_irq_vectors() function as both 'min_vecs' and |
141 | 'max_vecs' parameters: | 138 | 'max_vecs' parameters: |
142 | 139 | ||
143 | ret = pci_alloc_irq_vectors(pdev, nvec, nvec, 0); | 140 | ret = pci_alloc_irq_vectors(pdev, nvec, nvec, PCI_IRQ_ALL_TYPES); |
144 | if (ret < 0) | 141 | if (ret < 0) |
145 | goto out_err; | 142 | goto out_err; |
146 | 143 | ||
@@ -148,15 +145,14 @@ The most notorious example of the request type described above is enabling | |||
148 | the single MSI mode for a device. It could be done by passing two 1s as | 145 | the single MSI mode for a device. It could be done by passing two 1s as |
149 | 'min_vecs' and 'max_vecs': | 146 | 'min_vecs' and 'max_vecs': |
150 | 147 | ||
151 | ret = pci_alloc_irq_vectors(pdev, 1, 1, 0); | 148 | ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); |
152 | if (ret < 0) | 149 | if (ret < 0) |
153 | goto out_err; | 150 | goto out_err; |
154 | 151 | ||
155 | Some devices might not support using legacy line interrupts, in which case | 152 | Some devices might not support using legacy line interrupts, in which case |
156 | the PCI_IRQ_NOLEGACY flag can be used to fail the request if the platform | 153 | the driver can specify that only MSI or MSI-X is acceptable: |
157 | can't provide MSI or MSI-X interrupts: | ||
158 | 154 | ||
159 | nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_NOLEGACY); | 155 | nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_MSI | PCI_IRQ_MSIX); |
160 | if (nvec < 0) | 156 | if (nvec < 0) |
161 | goto out_err; | 157 | goto out_err; |
162 | 158 | ||
diff --git a/Documentation/PCI/pci.txt b/Documentation/PCI/pci.txt index 123881f62219..77f49dc5be23 100644 --- a/Documentation/PCI/pci.txt +++ b/Documentation/PCI/pci.txt | |||
@@ -124,7 +124,6 @@ initialization with a pointer to a structure describing the driver | |||
124 | 124 | ||
125 | The ID table is an array of struct pci_device_id entries ending with an | 125 | The ID table is an array of struct pci_device_id entries ending with an |
126 | all-zero entry. Definitions with static const are generally preferred. | 126 | all-zero entry. Definitions with static const are generally preferred. |
127 | Use of the deprecated macro DEFINE_PCI_DEVICE_TABLE should be avoided. | ||
128 | 127 | ||
129 | Each entry consists of: | 128 | Each entry consists of: |
130 | 129 | ||
diff --git a/Documentation/arm/CCN.txt b/Documentation/arm/CCN.txt index ffca443a19b4..15cdb7bc57c3 100644 --- a/Documentation/arm/CCN.txt +++ b/Documentation/arm/CCN.txt | |||
@@ -18,13 +18,17 @@ and config2 fields of the perf_event_attr structure. The "events" | |||
18 | directory provides configuration templates for all documented | 18 | directory provides configuration templates for all documented |
19 | events, that can be used with perf tool. For example "xp_valid_flit" | 19 | events, that can be used with perf tool. For example "xp_valid_flit" |
20 | is an equivalent of "type=0x8,event=0x4". Other parameters must be | 20 | is an equivalent of "type=0x8,event=0x4". Other parameters must be |
21 | explicitly specified. For events originating from device, "node" | 21 | explicitly specified. |
22 | defines its index. All crosspoint events require "xp" (index), | ||
23 | "port" (device port number) and "vc" (virtual channel ID) and | ||
24 | "dir" (direction). Watchpoints (special "event" value 0xfe) also | ||
25 | require comparator values ("cmp_l" and "cmp_h") and "mask", being | ||
26 | index of the comparator mask. | ||
27 | 22 | ||
23 | For events originating from device, "node" defines its index. | ||
24 | |||
25 | Crosspoint PMU events require "xp" (index), "bus" (bus number) | ||
26 | and "vc" (virtual channel ID). | ||
27 | |||
28 | Crosspoint watchpoint-based events (special "event" value 0xfe) | ||
29 | require "xp" and "vc" as as above plus "port" (device port index), | ||
30 | "dir" (transmit/receive direction), comparator values ("cmp_l" | ||
31 | and "cmp_h") and "mask", being index of the comparator mask. | ||
28 | Masks are defined separately from the event description | 32 | Masks are defined separately from the event description |
29 | (due to limited number of the config values) in the "cmp_mask" | 33 | (due to limited number of the config values) in the "cmp_mask" |
30 | directory, with first 8 configurable by user and additional | 34 | directory, with first 8 configurable by user and additional |
diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 4da60b463995..ccc60324e738 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt | |||
@@ -53,6 +53,7 @@ stable kernels. | |||
53 | | ARM | Cortex-A57 | #832075 | ARM64_ERRATUM_832075 | | 53 | | ARM | Cortex-A57 | #832075 | ARM64_ERRATUM_832075 | |
54 | | ARM | Cortex-A57 | #852523 | N/A | | 54 | | ARM | Cortex-A57 | #852523 | N/A | |
55 | | ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 | | 55 | | ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 | |
56 | | ARM | Cortex-A72 | #853709 | N/A | | ||
56 | | ARM | MMU-500 | #841119,#826419 | N/A | | 57 | | ARM | MMU-500 | #841119,#826419 | N/A | |
57 | | | | | | | 58 | | | | | | |
58 | | Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 | | 59 | | Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 | |
diff --git a/Documentation/cpu-freq/cpufreq-stats.txt b/Documentation/cpu-freq/cpufreq-stats.txt index fc647492e940..8d9773f23550 100644 --- a/Documentation/cpu-freq/cpufreq-stats.txt +++ b/Documentation/cpu-freq/cpufreq-stats.txt | |||
@@ -103,7 +103,7 @@ Config Main Menu | |||
103 | Power management options (ACPI, APM) ---> | 103 | Power management options (ACPI, APM) ---> |
104 | CPU Frequency scaling ---> | 104 | CPU Frequency scaling ---> |
105 | [*] CPU Frequency scaling | 105 | [*] CPU Frequency scaling |
106 | <*> CPU frequency translation statistics | 106 | [*] CPU frequency translation statistics |
107 | [*] CPU frequency translation statistics details | 107 | [*] CPU frequency translation statistics details |
108 | 108 | ||
109 | 109 | ||
diff --git a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt index bf99e2f24788..205593f56fe7 100644 --- a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt +++ b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt | |||
@@ -16,6 +16,11 @@ Required properties: | |||
16 | - vref-supply: The regulator supply ADC reference voltage. | 16 | - vref-supply: The regulator supply ADC reference voltage. |
17 | - #io-channel-cells: Should be 1, see ../iio-bindings.txt | 17 | - #io-channel-cells: Should be 1, see ../iio-bindings.txt |
18 | 18 | ||
19 | Optional properties: | ||
20 | - resets: Must contain an entry for each entry in reset-names if need support | ||
21 | this option. See ../reset/reset.txt for details. | ||
22 | - reset-names: Must include the name "saradc-apb". | ||
23 | |||
19 | Example: | 24 | Example: |
20 | saradc: saradc@2006c000 { | 25 | saradc: saradc@2006c000 { |
21 | compatible = "rockchip,saradc"; | 26 | compatible = "rockchip,saradc"; |
@@ -23,6 +28,8 @@ Example: | |||
23 | interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; | 28 | interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; |
24 | clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; | 29 | clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; |
25 | clock-names = "saradc", "apb_pclk"; | 30 | clock-names = "saradc", "apb_pclk"; |
31 | resets = <&cru SRST_SARADC>; | ||
32 | reset-names = "saradc-apb"; | ||
26 | #io-channel-cells = <1>; | 33 | #io-channel-cells = <1>; |
27 | vref-supply = <&vcc18>; | 34 | vref-supply = <&vcc18>; |
28 | }; | 35 | }; |
diff --git a/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt b/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt index 1112e0d794e1..820fee4b77b6 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt | |||
@@ -13,6 +13,7 @@ Required properties: | |||
13 | - touchscreen-size-y : See touchscreen.txt | 13 | - touchscreen-size-y : See touchscreen.txt |
14 | 14 | ||
15 | Optional properties: | 15 | Optional properties: |
16 | - firmware-name : File basename (string) for board specific firmware | ||
16 | - touchscreen-inverted-x : See touchscreen.txt | 17 | - touchscreen-inverted-x : See touchscreen.txt |
17 | - touchscreen-inverted-y : See touchscreen.txt | 18 | - touchscreen-inverted-y : See touchscreen.txt |
18 | - touchscreen-swapped-x-y : See touchscreen.txt | 19 | - touchscreen-swapped-x-y : See touchscreen.txt |
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-st.txt b/Documentation/devicetree/bindings/mmc/sdhci-st.txt index 88faa91125bf..3cd4c43a3260 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-st.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci-st.txt | |||
@@ -10,7 +10,7 @@ Required properties: | |||
10 | subsystem (mmcss) inside the FlashSS (available in STiH407 SoC | 10 | subsystem (mmcss) inside the FlashSS (available in STiH407 SoC |
11 | family). | 11 | family). |
12 | 12 | ||
13 | - clock-names: Should be "mmc". | 13 | - clock-names: Should be "mmc" and "icn". (NB: The latter is not compulsory) |
14 | See: Documentation/devicetree/bindings/resource-names.txt | 14 | See: Documentation/devicetree/bindings/resource-names.txt |
15 | - clocks: Phandle to the clock. | 15 | - clocks: Phandle to the clock. |
16 | See: Documentation/devicetree/bindings/clock/clock-bindings.txt | 16 | See: Documentation/devicetree/bindings/clock/clock-bindings.txt |
diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt index f5561ac7e17e..936ab5b87324 100644 --- a/Documentation/devicetree/bindings/serial/8250.txt +++ b/Documentation/devicetree/bindings/serial/8250.txt | |||
@@ -42,9 +42,6 @@ Optional properties: | |||
42 | - auto-flow-control: one way to enable automatic flow control support. The | 42 | - auto-flow-control: one way to enable automatic flow control support. The |
43 | driver is allowed to detect support for the capability even without this | 43 | driver is allowed to detect support for the capability even without this |
44 | property. | 44 | property. |
45 | - {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD | ||
46 | line respectively. It will use specified GPIO instead of the peripheral | ||
47 | function pin for the UART feature. If unsure, don't specify this property. | ||
48 | 45 | ||
49 | Note: | 46 | Note: |
50 | * fsl,ns16550: | 47 | * fsl,ns16550: |
@@ -66,19 +63,3 @@ Example: | |||
66 | interrupts = <10>; | 63 | interrupts = <10>; |
67 | reg-shift = <2>; | 64 | reg-shift = <2>; |
68 | }; | 65 | }; |
69 | |||
70 | Example for OMAP UART using GPIO-based modem control signals: | ||
71 | |||
72 | uart4: serial@49042000 { | ||
73 | compatible = "ti,omap3-uart"; | ||
74 | reg = <0x49042000 0x400>; | ||
75 | interrupts = <80>; | ||
76 | ti,hwmods = "uart4"; | ||
77 | clock-frequency = <48000000>; | ||
78 | cts-gpios = <&gpio3 5 GPIO_ACTIVE_LOW>; | ||
79 | rts-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>; | ||
80 | dtr-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; | ||
81 | dsr-gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; | ||
82 | dcd-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; | ||
83 | rng-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; | ||
84 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/nau8810.txt b/Documentation/devicetree/bindings/sound/nau8810.txt new file mode 100644 index 000000000000..05830e477acd --- /dev/null +++ b/Documentation/devicetree/bindings/sound/nau8810.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | NAU8810 audio CODEC | ||
2 | |||
3 | This device supports I2C only. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : "nuvoton,nau8810" | ||
8 | |||
9 | - reg : the I2C address of the device. | ||
10 | |||
11 | Example: | ||
12 | |||
13 | codec: nau8810@1a { | ||
14 | compatible = "nuvoton,nau8810"; | ||
15 | reg = <0x1a>; | ||
16 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-sgtl5000.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-sgtl5000.txt new file mode 100644 index 000000000000..5da7da4ea07a --- /dev/null +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-sgtl5000.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | NVIDIA Tegra audio complex, with SGTL5000 CODEC | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "nvidia,tegra-audio-sgtl5000" | ||
5 | - clocks : Must contain an entry for each entry in clock-names. | ||
6 | See ../clocks/clock-bindings.txt for details. | ||
7 | - clock-names : Must include the following entries: | ||
8 | - pll_a | ||
9 | - pll_a_out0 | ||
10 | - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) | ||
11 | - nvidia,model : The user-visible name of this sound complex. | ||
12 | - nvidia,audio-routing : A list of the connections between audio components. | ||
13 | Each entry is a pair of strings, the first being the connection's sink, | ||
14 | the second being the connection's source. Valid names for sources and | ||
15 | sinks are the SGTL5000's pins (as documented in its binding), and the jacks | ||
16 | on the board: | ||
17 | |||
18 | * Headphone Jack | ||
19 | * Line In Jack | ||
20 | * Mic Jack | ||
21 | |||
22 | - nvidia,i2s-controller : The phandle of the Tegra I2S controller that's | ||
23 | connected to the CODEC. | ||
24 | - nvidia,audio-codec : The phandle of the SGTL5000 audio codec. | ||
25 | |||
26 | Example: | ||
27 | |||
28 | sound { | ||
29 | compatible = "toradex,tegra-audio-sgtl5000-apalis_t30", | ||
30 | "nvidia,tegra-audio-sgtl5000"; | ||
31 | nvidia,model = "Toradex Apalis T30"; | ||
32 | nvidia,audio-routing = | ||
33 | "Headphone Jack", "HP_OUT", | ||
34 | "LINE_IN", "Line In Jack", | ||
35 | "MIC_IN", "Mic Jack"; | ||
36 | nvidia,i2s-controller = <&tegra_i2s2>; | ||
37 | nvidia,audio-codec = <&sgtl5000>; | ||
38 | clocks = <&tegra_car TEGRA30_CLK_PLL_A>, | ||
39 | <&tegra_car TEGRA30_CLK_PLL_A_OUT0>, | ||
40 | <&tegra_car TEGRA30_CLK_EXTERN1>; | ||
41 | clock-names = "pll_a", "pll_a_out0", "mclk"; | ||
42 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt b/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt index 48129368d4d9..d9d8635ff94c 100644 --- a/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt +++ b/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt | |||
@@ -16,6 +16,24 @@ Required properties: | |||
16 | * "spkr-iomux" | 16 | * "spkr-iomux" |
17 | - qcom,model : Name of the sound card. | 17 | - qcom,model : Name of the sound card. |
18 | 18 | ||
19 | - qcom,audio-routing : A list of the connections between audio components. | ||
20 | Each entry is a pair of strings, the first being the | ||
21 | connection's sink, the second being the connection's | ||
22 | source. Valid names could be power supplies, MicBias | ||
23 | of msm8x16_wcd codec and the jacks on the board: | ||
24 | |||
25 | Power supplies: | ||
26 | * MIC BIAS External1 | ||
27 | * MIC BIAS External2 | ||
28 | * MIC BIAS Internal1 | ||
29 | * MIC BIAS Internal2 | ||
30 | |||
31 | Board connectors: | ||
32 | * Headset Mic | ||
33 | * Secondary Mic", | ||
34 | * DMIC | ||
35 | * Ext Spk | ||
36 | |||
19 | Dai-link subnode properties and subnodes: | 37 | Dai-link subnode properties and subnodes: |
20 | 38 | ||
21 | Required dai-link subnodes: | 39 | Required dai-link subnodes: |
@@ -37,6 +55,18 @@ sound: sound { | |||
37 | reg-names = "mic-iomux", "spkr-iomux"; | 55 | reg-names = "mic-iomux", "spkr-iomux"; |
38 | qcom,model = "DB410c"; | 56 | qcom,model = "DB410c"; |
39 | 57 | ||
58 | qcom,audio-routing = | ||
59 | "MIC BIAS External1", "Handset Mic", | ||
60 | "MIC BIAS Internal2", "Headset Mic", | ||
61 | "MIC BIAS External1", "Secondary Mic", | ||
62 | "AMIC1", "MIC BIAS External1", | ||
63 | "AMIC2", "MIC BIAS Internal2", | ||
64 | "AMIC3", "MIC BIAS External1", | ||
65 | "DMIC1", "MIC BIAS Internal1", | ||
66 | "MIC BIAS Internal1", "Digital Mic1", | ||
67 | "DMIC2", "MIC BIAS Internal1", | ||
68 | "MIC BIAS Internal1", "Digital Mic2"; | ||
69 | |||
40 | /* I2S - Internal codec */ | 70 | /* I2S - Internal codec */ |
41 | internal-dai-link@0 { | 71 | internal-dai-link@0 { |
42 | cpu { /* PRIMARY */ | 72 | cpu { /* PRIMARY */ |
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt deleted file mode 100644 index 255ece3043ad..000000000000 --- a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt +++ /dev/null | |||
@@ -1,75 +0,0 @@ | |||
1 | Renesas Sampling Rate Convert Sound Card: | ||
2 | |||
3 | Renesas Sampling Rate Convert Sound Card specifies audio DAI connections of SoC <-> codec. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : "renesas,rsrc-card{,<board>}" | ||
8 | Examples with boards are: | ||
9 | - "renesas,rsrc-card" | ||
10 | - "renesas,rsrc-card,lager" | ||
11 | - "renesas,rsrc-card,koelsch" | ||
12 | Optional properties: | ||
13 | |||
14 | - card_name : User specified audio sound card name, one string | ||
15 | property. | ||
16 | - cpu : CPU sub-node | ||
17 | - codec : CODEC sub-node | ||
18 | |||
19 | Optional subnode properties: | ||
20 | |||
21 | - format : CPU/CODEC common audio format. | ||
22 | "i2s", "right_j", "left_j" , "dsp_a" | ||
23 | "dsp_b", "ac97", "pdm", "msb", "lsb" | ||
24 | - frame-master : Indicates dai-link frame master. | ||
25 | phandle to a cpu or codec subnode. | ||
26 | - bitclock-master : Indicates dai-link bit clock master. | ||
27 | phandle to a cpu or codec subnode. | ||
28 | - bitclock-inversion : bool property. Add this if the | ||
29 | dai-link uses bit clock inversion. | ||
30 | - frame-inversion : bool property. Add this if the | ||
31 | dai-link uses frame clock inversion. | ||
32 | - convert-rate : platform specified sampling rate convert | ||
33 | - convert-channels : platform specified converted channel size (2 - 8 ch) | ||
34 | - audio-prefix : see audio-routing | ||
35 | - audio-routing : A list of the connections between audio components. | ||
36 | Each entry is a pair of strings, the first being the connection's sink, | ||
37 | the second being the connection's source. Valid names for sources. | ||
38 | use audio-prefix if some components is using same sink/sources naming. | ||
39 | it can be used if compatible was "renesas,rsrc-card"; | ||
40 | |||
41 | Required CPU/CODEC subnodes properties: | ||
42 | |||
43 | - sound-dai : phandle and port of CPU/CODEC | ||
44 | |||
45 | Optional CPU/CODEC subnodes properties: | ||
46 | |||
47 | - clocks / system-clock-frequency : specify subnode's clock if needed. | ||
48 | it can be specified via "clocks" if system has | ||
49 | clock node (= common clock), or "system-clock-frequency" | ||
50 | (if system doens't support common clock) | ||
51 | If a clock is specified, it is | ||
52 | enabled with clk_prepare_enable() | ||
53 | in dai startup() and disabled with | ||
54 | clk_disable_unprepare() in dai | ||
55 | shutdown(). | ||
56 | |||
57 | Example | ||
58 | |||
59 | sound { | ||
60 | compatible = "renesas,rsrc-card,lager"; | ||
61 | |||
62 | card-name = "rsnd-ak4643"; | ||
63 | format = "left_j"; | ||
64 | bitclock-master = <&sndcodec>; | ||
65 | frame-master = <&sndcodec>; | ||
66 | |||
67 | sndcpu: cpu { | ||
68 | sound-dai = <&rcar_sound>; | ||
69 | }; | ||
70 | |||
71 | sndcodec: codec { | ||
72 | sound-dai = <&ak4643>; | ||
73 | system-clock-frequency = <11289600>; | ||
74 | }; | ||
75 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt new file mode 100644 index 000000000000..eac91db07178 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | ROCKCHIP with MAX98357A/RT5514/DA7219 codecs on GRU boards | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "rockchip,rk3399-gru-sound" | ||
5 | - rockchip,cpu: The phandle of the Rockchip I2S controller that's | ||
6 | connected to the codecs | ||
7 | - rockchip,codec: The phandle of the MAX98357A/RT5514/DA7219 codecs | ||
8 | |||
9 | Optional properties: | ||
10 | - dmic-wakeup-delay-ms : specify delay time (ms) for DMIC ready. | ||
11 | If this option is specified, which means it's required dmic need | ||
12 | delay for DMIC to ready so that rt5514 can avoid recording before | ||
13 | DMIC send valid data | ||
14 | |||
15 | Example: | ||
16 | |||
17 | sound { | ||
18 | compatible = "rockchip,rk3399-gru-sound"; | ||
19 | rockchip,cpu = <&i2s0>; | ||
20 | rockchip,codec = <&max98357a &rt5514 &da7219>; | ||
21 | dmic-wakeup-delay-ms = <20>; | ||
22 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/rt5659.txt b/Documentation/devicetree/bindings/sound/rt5659.txt index 5f79e7fde032..1766e0543fc5 100644 --- a/Documentation/devicetree/bindings/sound/rt5659.txt +++ b/Documentation/devicetree/bindings/sound/rt5659.txt | |||
@@ -12,6 +12,9 @@ Required properties: | |||
12 | 12 | ||
13 | Optional properties: | 13 | Optional properties: |
14 | 14 | ||
15 | - clocks: The phandle of the master clock to the CODEC | ||
16 | - clock-names: Should be "mclk" | ||
17 | |||
15 | - realtek,in1-differential | 18 | - realtek,in1-differential |
16 | - realtek,in3-differential | 19 | - realtek,in3-differential |
17 | - realtek,in4-differential | 20 | - realtek,in4-differential |
diff --git a/Documentation/devicetree/bindings/sound/rt5660.txt b/Documentation/devicetree/bindings/sound/rt5660.txt new file mode 100644 index 000000000000..30be5f921930 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/rt5660.txt | |||
@@ -0,0 +1,47 @@ | |||
1 | RT5660 audio CODEC | ||
2 | |||
3 | This device supports I2C only. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : "realtek,rt5660". | ||
8 | |||
9 | - reg : The I2C address of the device. | ||
10 | |||
11 | Optional properties: | ||
12 | |||
13 | - clocks: The phandle of the master clock to the CODEC | ||
14 | - clock-names: Should be "mclk" | ||
15 | |||
16 | - realtek,in1-differential | ||
17 | - realtek,in3-differential | ||
18 | Boolean. Indicate MIC1/3 input are differential, rather than single-ended. | ||
19 | |||
20 | - realtek,poweroff-in-suspend | ||
21 | Boolean. If the codec will be powered off in suspend, the resume should be | ||
22 | added delay time for waiting codec power ready. | ||
23 | |||
24 | - realtek,dmic1-data-pin | ||
25 | 0: dmic1 is not used | ||
26 | 1: using GPIO2 pin as dmic1 data pin | ||
27 | 2: using IN1P pin as dmic1 data pin | ||
28 | |||
29 | Pins on the device (for linking into audio routes) for RT5660: | ||
30 | |||
31 | * DMIC L1 | ||
32 | * DMIC R1 | ||
33 | * IN1P | ||
34 | * IN1N | ||
35 | * IN2P | ||
36 | * IN3P | ||
37 | * IN3N | ||
38 | * SPO | ||
39 | * LOUTL | ||
40 | * LOUTR | ||
41 | |||
42 | Example: | ||
43 | |||
44 | rt5660 { | ||
45 | compatible = "realtek,rt5660"; | ||
46 | reg = <0x1c>; | ||
47 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/rt5663.txt b/Documentation/devicetree/bindings/sound/rt5663.txt new file mode 100644 index 000000000000..7d3c974c6e2e --- /dev/null +++ b/Documentation/devicetree/bindings/sound/rt5663.txt | |||
@@ -0,0 +1,30 @@ | |||
1 | RT5663/RT5668 audio CODEC | ||
2 | |||
3 | This device supports I2C only. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : One of "realtek,rt5663" or "realtek,rt5668". | ||
8 | |||
9 | - reg : The I2C address of the device. | ||
10 | |||
11 | - interrupts : The CODEC's interrupt output. | ||
12 | |||
13 | Optional properties: | ||
14 | |||
15 | Pins on the device (for linking into audio routes) for RT5663/RT5668: | ||
16 | |||
17 | * IN1P | ||
18 | * IN1N | ||
19 | * IN2P | ||
20 | * IN2N | ||
21 | * HPOL | ||
22 | * HPOR | ||
23 | |||
24 | Example: | ||
25 | |||
26 | codec: rt5663@12 { | ||
27 | compatible = "realtek,rt5663"; | ||
28 | reg = <0x12>; | ||
29 | interrupts = <7 IRQ_TYPE_EDGE_FALLING>; | ||
30 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt index 59d862801e59..c7a93931fad2 100644 --- a/Documentation/devicetree/bindings/sound/simple-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-card.txt | |||
@@ -22,6 +22,8 @@ Optional properties: | |||
22 | headphones are attached. | 22 | headphones are attached. |
23 | - 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 |
24 | a microphone is attached. | 24 | a microphone is attached. |
25 | - simple-audio-card,aux-devs : List of phandles pointing to auxiliary devices, such | ||
26 | as amplifiers, to be added to the sound card. | ||
25 | 27 | ||
26 | Optional subnodes: | 28 | Optional subnodes: |
27 | 29 | ||
@@ -162,3 +164,38 @@ sound { | |||
162 | }; | 164 | }; |
163 | }; | 165 | }; |
164 | }; | 166 | }; |
167 | |||
168 | Example 3 - route audio from IMX6 SSI2 through TLV320DAC3100 codec | ||
169 | through TPA6130A2 amplifier to headphones: | ||
170 | |||
171 | &i2c0 { | ||
172 | codec: tlv320dac3100@18 { | ||
173 | compatible = "ti,tlv320dac3100"; | ||
174 | ... | ||
175 | } | ||
176 | |||
177 | amp: tpa6130a2@60 { | ||
178 | compatible = "ti,tpa6130a2"; | ||
179 | ... | ||
180 | } | ||
181 | } | ||
182 | |||
183 | sound { | ||
184 | compatible = "simple-audio-card"; | ||
185 | ... | ||
186 | simple-audio-card,widgets = | ||
187 | "Headphone", "Headphone Jack"; | ||
188 | simple-audio-card,routing = | ||
189 | "Headphone Jack", "HPLEFT", | ||
190 | "Headphone Jack", "HPRIGHT", | ||
191 | "LEFTIN", "HPL", | ||
192 | "RIGHTIN", "HPR"; | ||
193 | simple-audio-card,aux-devs = <&>; | ||
194 | simple-audio-card,cpu { | ||
195 | sound-dai = <&ssi2>; | ||
196 | }; | ||
197 | simple-audio-card,codec { | ||
198 | sound-dai = <&codec>; | ||
199 | clocks = ... | ||
200 | }; | ||
201 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/simple-scu-card.txt b/Documentation/devicetree/bindings/sound/simple-scu-card.txt new file mode 100644 index 000000000000..d6fe47ed09af --- /dev/null +++ b/Documentation/devicetree/bindings/sound/simple-scu-card.txt | |||
@@ -0,0 +1,110 @@ | |||
1 | ASoC simple SCU Sound Card | ||
2 | |||
3 | Simple-Card specifies audio DAI connections of SoC <-> codec. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : "simple-scu-audio-card" | ||
8 | "renesas,rsrc-card" | ||
9 | |||
10 | Optional properties: | ||
11 | |||
12 | - simple-audio-card,name : User specified audio sound card name, one string | ||
13 | property. | ||
14 | - simple-audio-card,cpu : CPU sub-node | ||
15 | - simple-audio-card,codec : CODEC sub-node | ||
16 | |||
17 | Optional subnode properties: | ||
18 | |||
19 | - simple-audio-card,format : CPU/CODEC common audio format. | ||
20 | "i2s", "right_j", "left_j" , "dsp_a" | ||
21 | "dsp_b", "ac97", "pdm", "msb", "lsb" | ||
22 | - simple-audio-card,frame-master : Indicates dai-link frame master. | ||
23 | phandle to a cpu or codec subnode. | ||
24 | - simple-audio-card,bitclock-master : Indicates dai-link bit clock master. | ||
25 | phandle to a cpu or codec subnode. | ||
26 | - simple-audio-card,bitclock-inversion : bool property. Add this if the | ||
27 | dai-link uses bit clock inversion. | ||
28 | - simple-audio-card,frame-inversion : bool property. Add this if the | ||
29 | dai-link uses frame clock inversion. | ||
30 | - simple-audio-card,convert-rate : platform specified sampling rate convert | ||
31 | - simple-audio-card,convert-channels : platform specified converted channel size (2 - 8 ch) | ||
32 | - simple-audio-card,prefix : see audio-routing | ||
33 | - simple-audio-card,routing : A list of the connections between audio components. | ||
34 | Each entry is a pair of strings, the first being the connection's sink, | ||
35 | the second being the connection's source. Valid names for sources. | ||
36 | use audio-prefix if some components is using same sink/sources naming. | ||
37 | it can be used if compatible was "renesas,rsrc-card"; | ||
38 | |||
39 | Required CPU/CODEC subnodes properties: | ||
40 | |||
41 | - sound-dai : phandle and port of CPU/CODEC | ||
42 | |||
43 | Optional CPU/CODEC subnodes properties: | ||
44 | |||
45 | - clocks / system-clock-frequency : specify subnode's clock if needed. | ||
46 | it can be specified via "clocks" if system has | ||
47 | clock node (= common clock), or "system-clock-frequency" | ||
48 | (if system doens't support common clock) | ||
49 | If a clock is specified, it is | ||
50 | enabled with clk_prepare_enable() | ||
51 | in dai startup() and disabled with | ||
52 | clk_disable_unprepare() in dai | ||
53 | shutdown(). | ||
54 | |||
55 | Example 1. Sampling Rate Covert | ||
56 | |||
57 | sound { | ||
58 | compatible = "simple-scu-audio-card"; | ||
59 | |||
60 | simple-audio-card,name = "rsnd-ak4643"; | ||
61 | simple-audio-card,format = "left_j"; | ||
62 | simple-audio-card,format = "left_j"; | ||
63 | simple-audio-card,bitclock-master = <&sndcodec>; | ||
64 | simple-audio-card,frame-master = <&sndcodec>; | ||
65 | |||
66 | simple-audio-card,convert-rate = <48000>; /* see audio_clk_a */ | ||
67 | |||
68 | simple-audio-card,prefix = "ak4642"; | ||
69 | simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback", | ||
70 | "DAI0 Capture", "ak4642 Capture"; | ||
71 | |||
72 | sndcpu: simple-audio-card,cpu { | ||
73 | sound-dai = <&rcar_sound>; | ||
74 | }; | ||
75 | |||
76 | sndcodec: simple-audio-card,codec { | ||
77 | sound-dai = <&ak4643>; | ||
78 | system-clock-frequency = <11289600>; | ||
79 | }; | ||
80 | }; | ||
81 | |||
82 | Example 2. 2 CPU 1 Codec | ||
83 | |||
84 | sound { | ||
85 | compatible = "renesas,rsrc-card"; | ||
86 | |||
87 | card-name = "rsnd-ak4643"; | ||
88 | format = "left_j"; | ||
89 | bitclock-master = <&dpcmcpu>; | ||
90 | frame-master = <&dpcmcpu>; | ||
91 | |||
92 | convert-rate = <48000>; /* see audio_clk_a */ | ||
93 | |||
94 | audio-prefix = "ak4642"; | ||
95 | audio-routing = "ak4642 Playback", "DAI0 Playback", | ||
96 | "ak4642 Playback", "DAI1 Playback"; | ||
97 | |||
98 | dpcmcpu: cpu@0 { | ||
99 | sound-dai = <&rcar_sound 0>; | ||
100 | }; | ||
101 | |||
102 | cpu@1 { | ||
103 | sound-dai = <&rcar_sound 1>; | ||
104 | }; | ||
105 | |||
106 | codec { | ||
107 | sound-dai = <&ak4643>; | ||
108 | clocks = <&audio_clock>; | ||
109 | }; | ||
110 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt index 16bcdfb6760e..745dc62f76ea 100644 --- a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt +++ b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt | |||
@@ -11,7 +11,9 @@ Documentation/devicetree/bindings/sound/simple-card.txt. | |||
11 | --------------------------------------- | 11 | --------------------------------------- |
12 | 12 | ||
13 | Required properties: | 13 | Required properties: |
14 | - compatible: "st,sti-uni-player" or "st,sti-uni-reader" | 14 | - compatible: "st,stih407-uni-player-hdmi", "st,stih407-uni-player-pcm-out", |
15 | "st,stih407-uni-player-dac", "st,stih407-uni-player-spdif", | ||
16 | "st,stih407-uni-reader-pcm_in", "st,stih407-uni-reader-hdmi", | ||
15 | 17 | ||
16 | - st,syscfg: phandle to boot-device system configuration registers | 18 | - st,syscfg: phandle to boot-device system configuration registers |
17 | 19 | ||
@@ -33,32 +35,24 @@ Required properties: | |||
33 | "tx" for "st,sti-uni-player" compatibility | 35 | "tx" for "st,sti-uni-player" compatibility |
34 | "rx" for "st,sti-uni-reader" compatibility | 36 | "rx" for "st,sti-uni-reader" compatibility |
35 | 37 | ||
36 | - st,version: IP version integrated in SOC. | ||
37 | |||
38 | - dai-name: DAI name that describes the IP. | ||
39 | |||
40 | - st,mode: IP working mode depending on associated codec. | ||
41 | "HDMI" connected to HDMI codec and support IEC HDMI formats (player only). | ||
42 | "SPDIF" connected to SPDIF codec and support SPDIF formats (player only). | ||
43 | "PCM" PCM standard mode for I2S or TDM bus. | ||
44 | "TDM" TDM mode for TDM bus. | ||
45 | |||
46 | Required properties ("st,sti-uni-player" compatibility only): | 38 | Required properties ("st,sti-uni-player" compatibility only): |
47 | - clocks: CPU_DAI IP clock source, listed in the same order than the | 39 | - clocks: CPU_DAI IP clock source, listed in the same order than the |
48 | CPU_DAI properties. | 40 | CPU_DAI properties. |
49 | 41 | ||
50 | - st,uniperiph-id: internal SOC IP instance ID. | ||
51 | |||
52 | Optional properties: | 42 | Optional properties: |
53 | - pinctrl-0: defined for CPU_DAI@1 and CPU_DAI@4 to describe I2S PIOs for | 43 | - pinctrl-0: defined for CPU_DAI@1 and CPU_DAI@4 to describe I2S PIOs for |
54 | external codecs connection. | 44 | external codecs connection. |
55 | 45 | ||
56 | - pinctrl-names: should contain only one value - "default". | 46 | - pinctrl-names: should contain only one value - "default". |
57 | 47 | ||
48 | - st,tdm-mode: to declare to set TDM mode for unireader and uniplayer IPs. | ||
49 | Only compartible with IPs in charge of the external I2S/TDM bus. | ||
50 | Should be declared depending on associated codec. | ||
51 | |||
58 | Example: | 52 | Example: |
59 | 53 | ||
60 | sti_uni_player1: sti-uni-player@1 { | 54 | sti_uni_player1: sti-uni-player@0x8D81000 { |
61 | compatible = "st,sti-uni-player"; | 55 | compatible = "st,stih407-uni-player-hdmi"; |
62 | status = "okay"; | 56 | status = "okay"; |
63 | #sound-dai-cells = <0>; | 57 | #sound-dai-cells = <0>; |
64 | st,syscfg = <&syscfg_core>; | 58 | st,syscfg = <&syscfg_core>; |
@@ -66,15 +60,12 @@ Example: | |||
66 | reg = <0x8D81000 0x158>; | 60 | reg = <0x8D81000 0x158>; |
67 | interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>; | 61 | interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>; |
68 | dmas = <&fdma0 3 0 1>; | 62 | dmas = <&fdma0 3 0 1>; |
69 | st,dai-name = "Uni Player #1 (I2S)"; | ||
70 | dma-names = "tx"; | 63 | dma-names = "tx"; |
71 | st,uniperiph-id = <1>; | 64 | st,tdm-mode = <1>; |
72 | st,version = <5>; | ||
73 | st,mode = "TDM"; | ||
74 | }; | 65 | }; |
75 | 66 | ||
76 | sti_uni_player2: sti-uni-player@2 { | 67 | sti_uni_player2: sti-uni-player@0x8D82000 { |
77 | compatible = "st,sti-uni-player"; | 68 | compatible = "st,stih407-uni-player-pcm-out"; |
78 | status = "okay"; | 69 | status = "okay"; |
79 | #sound-dai-cells = <0>; | 70 | #sound-dai-cells = <0>; |
80 | st,syscfg = <&syscfg_core>; | 71 | st,syscfg = <&syscfg_core>; |
@@ -82,15 +73,11 @@ Example: | |||
82 | reg = <0x8D82000 0x158>; | 73 | reg = <0x8D82000 0x158>; |
83 | interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>; | 74 | interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>; |
84 | dmas = <&fdma0 4 0 1>; | 75 | dmas = <&fdma0 4 0 1>; |
85 | dai-name = "Uni Player #2 (DAC)"; | ||
86 | dma-names = "tx"; | 76 | dma-names = "tx"; |
87 | st,uniperiph-id = <2>; | ||
88 | st,version = <5>; | ||
89 | st,mode = "PCM"; | ||
90 | }; | 77 | }; |
91 | 78 | ||
92 | sti_uni_player3: sti-uni-player@3 { | 79 | sti_uni_player3: sti-uni-player@0x8D85000 { |
93 | compatible = "st,sti-uni-player"; | 80 | compatible = "st,stih407-uni-player-spdif"; |
94 | status = "okay"; | 81 | status = "okay"; |
95 | #sound-dai-cells = <0>; | 82 | #sound-dai-cells = <0>; |
96 | st,syscfg = <&syscfg_core>; | 83 | st,syscfg = <&syscfg_core>; |
@@ -99,14 +86,10 @@ Example: | |||
99 | interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>; | 86 | interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>; |
100 | dmas = <&fdma0 7 0 1>; | 87 | dmas = <&fdma0 7 0 1>; |
101 | dma-names = "tx"; | 88 | dma-names = "tx"; |
102 | dai-name = "Uni Player #3 (SPDIF)"; | ||
103 | st,uniperiph-id = <3>; | ||
104 | st,version = <5>; | ||
105 | st,mode = "SPDIF"; | ||
106 | }; | 89 | }; |
107 | 90 | ||
108 | sti_uni_reader1: sti-uni-reader@1 { | 91 | sti_uni_reader1: sti-uni-reader@0x8D84000 { |
109 | compatible = "st,sti-uni-reader"; | 92 | compatible = "st,stih407-uni-reader-hdmi"; |
110 | status = "disabled"; | 93 | status = "disabled"; |
111 | #sound-dai-cells = <0>; | 94 | #sound-dai-cells = <0>; |
112 | st,syscfg = <&syscfg_core>; | 95 | st,syscfg = <&syscfg_core>; |
@@ -114,9 +97,6 @@ Example: | |||
114 | interrupts = <GIC_SPI 88 IRQ_TYPE_NONE>; | 97 | interrupts = <GIC_SPI 88 IRQ_TYPE_NONE>; |
115 | dmas = <&fdma0 6 0 1>; | 98 | dmas = <&fdma0 6 0 1>; |
116 | dma-names = "rx"; | 99 | dma-names = "rx"; |
117 | dai-name = "Uni Reader #1 (HDMI RX)"; | ||
118 | st,version = <3>; | ||
119 | st,mode = "PCM"; | ||
120 | }; | 100 | }; |
121 | 101 | ||
122 | 2) sti-sas-codec: internal audio codec IPs driver | 102 | 2) sti-sas-codec: internal audio codec IPs driver |
diff --git a/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt b/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt index 13503aa505a9..0230c4d20506 100644 --- a/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt +++ b/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt | |||
@@ -9,6 +9,7 @@ Required properties: | |||
9 | 9 | ||
10 | - compatible : should be one of the following: | 10 | - compatible : should be one of the following: |
11 | - "allwinner,sun4i-a10-spdif": for the Allwinner A10 SoC | 11 | - "allwinner,sun4i-a10-spdif": for the Allwinner A10 SoC |
12 | - "allwinner,sun6i-a31-spdif": for the Allwinner A31 SoC | ||
12 | 13 | ||
13 | - reg : Offset and length of the register set for the device. | 14 | - reg : Offset and length of the register set for the device. |
14 | 15 | ||
@@ -25,6 +26,8 @@ Required properties: | |||
25 | "apb" clock for the spdif bus. | 26 | "apb" clock for the spdif bus. |
26 | "spdif" clock for spdif controller. | 27 | "spdif" clock for spdif controller. |
27 | 28 | ||
29 | - resets : reset specifier for the ahb reset (A31 and newer only) | ||
30 | |||
28 | Example: | 31 | Example: |
29 | 32 | ||
30 | spdif: spdif@01c21000 { | 33 | spdif: spdif@01c21000 { |
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt b/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt index eff12be5e789..9340d2ddcc54 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt | |||
@@ -11,6 +11,7 @@ Required properties: | |||
11 | "ti,tlv320aic3110" - TLV320AIC3110 (stereo speaker amp, no MiniDSP) | 11 | "ti,tlv320aic3110" - TLV320AIC3110 (stereo speaker amp, no MiniDSP) |
12 | "ti,tlv320aic3120" - TLV320AIC3120 (mono speaker amp, MiniDSP) | 12 | "ti,tlv320aic3120" - TLV320AIC3120 (mono speaker amp, MiniDSP) |
13 | "ti,tlv320aic3111" - TLV320AIC3111 (stereo speaker amp, MiniDSP) | 13 | "ti,tlv320aic3111" - TLV320AIC3111 (stereo speaker amp, MiniDSP) |
14 | "ti,tlv320dac3100" - TLV320DAC3100 (no ADC, mono speaker amp, no MiniDSP) | ||
14 | 15 | ||
15 | - reg - <int> - I2C slave address | 16 | - reg - <int> - I2C slave address |
16 | - HPVDD-supply, SPRVDD-supply, SPLVDD-supply, AVDD-supply, IOVDD-supply, | 17 | - HPVDD-supply, SPRVDD-supply, SPLVDD-supply, AVDD-supply, IOVDD-supply, |
@@ -37,9 +38,11 @@ CODEC output pins: | |||
37 | * MICBIAS | 38 | * MICBIAS |
38 | 39 | ||
39 | CODEC input pins: | 40 | CODEC input pins: |
40 | * MIC1LP | 41 | * MIC1LP, devices with ADC |
41 | * MIC1RP | 42 | * MIC1RP, devices with ADC |
42 | * MIC1LM | 43 | * MIC1LM, devices with ADC |
44 | * AIN1, devices without ADC | ||
45 | * AIN2, devices without ADC | ||
43 | 46 | ||
44 | The pins can be used in referring sound node's audio-routing property. | 47 | The pins can be used in referring sound node's audio-routing property. |
45 | 48 | ||
diff --git a/Documentation/devicetree/bindings/thermal/thermal.txt b/Documentation/devicetree/bindings/thermal/thermal.txt index 41b817f7b670..88b6ea1ad290 100644 --- a/Documentation/devicetree/bindings/thermal/thermal.txt +++ b/Documentation/devicetree/bindings/thermal/thermal.txt | |||
@@ -62,7 +62,7 @@ For more examples of cooling devices, refer to the example sections below. | |||
62 | Required properties: | 62 | Required properties: |
63 | - #cooling-cells: Used to provide cooling device specific information | 63 | - #cooling-cells: Used to provide cooling device specific information |
64 | Type: unsigned while referring to it. Must be at least 2, in order | 64 | Type: unsigned while referring to it. Must be at least 2, in order |
65 | Size: one cell to specify minimum and maximum cooling state used | 65 | Size: one cell to specify minimum and maximum cooling state used |
66 | in the reference. The first cell is the minimum | 66 | in the reference. The first cell is the minimum |
67 | cooling state requested and the second cell is | 67 | cooling state requested and the second cell is |
68 | the maximum cooling state requested in the reference. | 68 | the maximum cooling state requested in the reference. |
@@ -119,7 +119,7 @@ Required properties: | |||
119 | Optional property: | 119 | Optional property: |
120 | - contribution: The cooling contribution to the thermal zone of the | 120 | - contribution: The cooling contribution to the thermal zone of the |
121 | Type: unsigned referred cooling device at the referred trip point. | 121 | Type: unsigned referred cooling device at the referred trip point. |
122 | Size: one cell The contribution is a ratio of the sum | 122 | Size: one cell The contribution is a ratio of the sum |
123 | of all cooling contributions within a thermal zone. | 123 | of all cooling contributions within a thermal zone. |
124 | 124 | ||
125 | Note: Using the THERMAL_NO_LIMIT (-1UL) constant in the cooling-device phandle | 125 | Note: Using the THERMAL_NO_LIMIT (-1UL) constant in the cooling-device phandle |
@@ -145,7 +145,7 @@ Required properties: | |||
145 | Size: one cell | 145 | Size: one cell |
146 | 146 | ||
147 | - thermal-sensors: A list of thermal sensor phandles and sensor specifier | 147 | - thermal-sensors: A list of thermal sensor phandles and sensor specifier |
148 | Type: list of used while monitoring the thermal zone. | 148 | Type: list of used while monitoring the thermal zone. |
149 | phandles + sensor | 149 | phandles + sensor |
150 | specifier | 150 | specifier |
151 | 151 | ||
@@ -473,7 +473,7 @@ thermal-zones { | |||
473 | <&adc>; /* pcb north */ | 473 | <&adc>; /* pcb north */ |
474 | 474 | ||
475 | /* hotspot = 100 * bandgap - 120 * adc + 484 */ | 475 | /* hotspot = 100 * bandgap - 120 * adc + 484 */ |
476 | coefficients = <100 -120 484>; | 476 | coefficients = <100 -120 484>; |
477 | 477 | ||
478 | trips { | 478 | trips { |
479 | ... | 479 | ... |
@@ -502,7 +502,7 @@ from the ADC sensor. The binding would be then: | |||
502 | thermal-sensors = <&adc>; | 502 | thermal-sensors = <&adc>; |
503 | 503 | ||
504 | /* hotspot = 1 * adc + 6000 */ | 504 | /* hotspot = 1 * adc + 6000 */ |
505 | coefficients = <1 6000>; | 505 | coefficients = <1 6000>; |
506 | 506 | ||
507 | (d) - Board thermal | 507 | (d) - Board thermal |
508 | 508 | ||
diff --git a/Documentation/filesystems/overlayfs.txt b/Documentation/filesystems/overlayfs.txt index d6259c786316..bcbf9710e4af 100644 --- a/Documentation/filesystems/overlayfs.txt +++ b/Documentation/filesystems/overlayfs.txt | |||
@@ -183,12 +183,10 @@ The copy_up operation essentially creates a new, identical file and | |||
183 | moves it over to the old name. The new file may be on a different | 183 | moves it over to the old name. The new file may be on a different |
184 | filesystem, so both st_dev and st_ino of the file may change. | 184 | filesystem, so both st_dev and st_ino of the file may change. |
185 | 185 | ||
186 | Any open files referring to this inode will access the old data and | 186 | Any open files referring to this inode will access the old data. |
187 | metadata. Similarly any file locks obtained before copy_up will not | ||
188 | apply to the copied up file. | ||
189 | 187 | ||
190 | On a file opened with O_RDONLY fchmod(2), fchown(2), futimesat(2) and | 188 | Any file locks (and leases) obtained before copy_up will not apply |
191 | fsetxattr(2) will fail with EROFS. | 189 | to the copied up file. |
192 | 190 | ||
193 | If a file with multiple hard links is copied up, then this will | 191 | If a file with multiple hard links is copied up, then this will |
194 | "break" the link. Changes will not be propagated to other names | 192 | "break" the link. Changes will not be propagated to other names |
diff --git a/Documentation/i2c/slave-interface b/Documentation/i2c/slave-interface index 80807adb8ded..7e2a228f21bc 100644 --- a/Documentation/i2c/slave-interface +++ b/Documentation/i2c/slave-interface | |||
@@ -145,6 +145,11 @@ If you want to add slave support to the bus driver: | |||
145 | 145 | ||
146 | * Catch the slave interrupts and send appropriate i2c_slave_events to the backend. | 146 | * Catch the slave interrupts and send appropriate i2c_slave_events to the backend. |
147 | 147 | ||
148 | Note that most hardware supports being master _and_ slave on the same bus. So, | ||
149 | if you extend a bus driver, please make sure that the driver supports that as | ||
150 | well. In almost all cases, slave support does not need to disable the master | ||
151 | functionality. | ||
152 | |||
148 | Check the i2c-rcar driver as an example. | 153 | Check the i2c-rcar driver as an example. |
149 | 154 | ||
150 | 155 | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 46c030a49186..a4f4d693e2c1 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -3032,6 +3032,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
3032 | PAGE_SIZE is used as alignment. | 3032 | PAGE_SIZE is used as alignment. |
3033 | PCI-PCI bridge can be specified, if resource | 3033 | PCI-PCI bridge can be specified, if resource |
3034 | windows need to be expanded. | 3034 | windows need to be expanded. |
3035 | To specify the alignment for several | ||
3036 | instances of a device, the PCI vendor, | ||
3037 | device, subvendor, and subdevice may be | ||
3038 | specified, e.g., 4096@pci:8086:9c22:103c:198f | ||
3035 | ecrc= Enable/disable PCIe ECRC (transaction layer | 3039 | ecrc= Enable/disable PCIe ECRC (transaction layer |
3036 | end-to-end CRC checking). | 3040 | end-to-end CRC checking). |
3037 | bios: Use BIOS/firmware settings. This is the | 3041 | bios: Use BIOS/firmware settings. This is the |
diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst index 04ee90099676..201d4839931c 100644 --- a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst +++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst | |||
@@ -144,7 +144,7 @@ logical address types are already defined will return with error ``EBUSY``. | |||
144 | 144 | ||
145 | - ``flags`` | 145 | - ``flags`` |
146 | 146 | ||
147 | - Flags. No flags are defined yet, so set this to 0. | 147 | - Flags. See :ref:`cec-log-addrs-flags` for a list of available flags. |
148 | 148 | ||
149 | - .. row 7 | 149 | - .. row 7 |
150 | 150 | ||
@@ -201,6 +201,25 @@ logical address types are already defined will return with error ``EBUSY``. | |||
201 | give the CEC framework more information about the device type, even | 201 | give the CEC framework more information about the device type, even |
202 | though the framework won't use it directly in the CEC message. | 202 | though the framework won't use it directly in the CEC message. |
203 | 203 | ||
204 | .. _cec-log-addrs-flags: | ||
205 | |||
206 | .. flat-table:: Flags for struct cec_log_addrs | ||
207 | :header-rows: 0 | ||
208 | :stub-columns: 0 | ||
209 | :widths: 3 1 4 | ||
210 | |||
211 | |||
212 | - .. _`CEC-LOG-ADDRS-FL-ALLOW-UNREG-FALLBACK`: | ||
213 | |||
214 | - ``CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK`` | ||
215 | |||
216 | - 1 | ||
217 | |||
218 | - By default if no logical address of the requested type can be claimed, then | ||
219 | it will go back to the unconfigured state. If this flag is set, then it will | ||
220 | fallback to the Unregistered logical address. Note that if the Unregistered | ||
221 | logical address was explicitly requested, then this flag has no effect. | ||
222 | |||
204 | .. _cec-versions: | 223 | .. _cec-versions: |
205 | 224 | ||
206 | .. flat-table:: CEC Versions | 225 | .. flat-table:: CEC Versions |
diff --git a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst index 7a6d6d00ce19..2e1e73928396 100644 --- a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst +++ b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst | |||
@@ -64,7 +64,8 @@ it is guaranteed that the state did change in between the two events. | |||
64 | 64 | ||
65 | - ``phys_addr`` | 65 | - ``phys_addr`` |
66 | 66 | ||
67 | - The current physical address. | 67 | - The current physical address. This is ``CEC_PHYS_ADDR_INVALID`` if no |
68 | valid physical address is set. | ||
68 | 69 | ||
69 | - .. row 2 | 70 | - .. row 2 |
70 | 71 | ||
@@ -72,7 +73,10 @@ it is guaranteed that the state did change in between the two events. | |||
72 | 73 | ||
73 | - ``log_addr_mask`` | 74 | - ``log_addr_mask`` |
74 | 75 | ||
75 | - The current set of claimed logical addresses. | 76 | - The current set of claimed logical addresses. This is 0 if no logical |
77 | addresses are claimed or if ``phys_addr`` is ``CEC_PHYS_ADDR_INVALID``. | ||
78 | If bit 15 is set (``1 << CEC_LOG_ADDR_UNREGISTERED``) then this device | ||
79 | has the unregistered logical address. In that case all other bits are 0. | ||
76 | 80 | ||
77 | 81 | ||
78 | 82 | ||
diff --git a/Documentation/networking/dsa/dsa.txt b/Documentation/networking/dsa/dsa.txt index 9d05ed7f7da5..f20c884c048a 100644 --- a/Documentation/networking/dsa/dsa.txt +++ b/Documentation/networking/dsa/dsa.txt | |||
@@ -587,26 +587,6 @@ of DSA, would be the its port-based VLAN, used by the associated bridge device. | |||
587 | TODO | 587 | TODO |
588 | ==== | 588 | ==== |
589 | 589 | ||
590 | The platform device problem | ||
591 | --------------------------- | ||
592 | DSA is currently implemented as a platform device driver which is far from ideal | ||
593 | as was discussed in this thread: | ||
594 | |||
595 | http://permalink.gmane.org/gmane.linux.network/329848 | ||
596 | |||
597 | This basically prevents the device driver model to be properly used and applied, | ||
598 | and support non-MDIO, non-MMIO Ethernet connected switches. | ||
599 | |||
600 | Another problem with the platform device driver approach is that it prevents the | ||
601 | use of a modular switch drivers build due to a circular dependency, illustrated | ||
602 | here: | ||
603 | |||
604 | http://comments.gmane.org/gmane.linux.network/345803 | ||
605 | |||
606 | Attempts of reworking this has been done here: | ||
607 | |||
608 | https://lwn.net/Articles/643149/ | ||
609 | |||
610 | Making SWITCHDEV and DSA converge towards an unified codebase | 590 | Making SWITCHDEV and DSA converge towards an unified codebase |
611 | ------------------------------------------------------------- | 591 | ------------------------------------------------------------- |
612 | 592 | ||
diff --git a/Documentation/powerpc/transactional_memory.txt b/Documentation/powerpc/transactional_memory.txt index ba0a2a4a54ba..e32fdbb4c9a7 100644 --- a/Documentation/powerpc/transactional_memory.txt +++ b/Documentation/powerpc/transactional_memory.txt | |||
@@ -167,6 +167,8 @@ signal will be rolled back anyway. | |||
167 | For signals taken in non-TM or suspended mode, we use the | 167 | For signals taken in non-TM or suspended mode, we use the |
168 | normal/non-checkpointed stack pointer. | 168 | normal/non-checkpointed stack pointer. |
169 | 169 | ||
170 | Any transaction initiated inside a sighandler and suspended on return | ||
171 | from the sighandler to the kernel will get reclaimed and discarded. | ||
170 | 172 | ||
171 | Failure cause codes used by kernel | 173 | Failure cause codes used by kernel |
172 | ================================== | 174 | ================================== |
diff --git a/Documentation/rapidio/mport_cdev.txt b/Documentation/rapidio/mport_cdev.txt index 6e491a662461..a53f786ee2e9 100644 --- a/Documentation/rapidio/mport_cdev.txt +++ b/Documentation/rapidio/mport_cdev.txt | |||
@@ -80,6 +80,10 @@ functionality of their platform when planning to use this driver: | |||
80 | 80 | ||
81 | III. Module parameters | 81 | III. Module parameters |
82 | 82 | ||
83 | - 'dma_timeout' - DMA transfer completion timeout (in msec, default value 3000). | ||
84 | This parameter set a maximum completion wait time for SYNC mode DMA | ||
85 | transfer requests and for RIO_WAIT_FOR_ASYNC ioctl requests. | ||
86 | |||
83 | - 'dbg_level' - This parameter allows to control amount of debug information | 87 | - 'dbg_level' - This parameter allows to control amount of debug information |
84 | generated by this device driver. This parameter is formed by set of | 88 | generated by this device driver. This parameter is formed by set of |
85 | bit masks that correspond to the specific functional blocks. | 89 | bit masks that correspond to the specific functional blocks. |
diff --git a/MAINTAINERS b/MAINTAINERS index 0bbe4b105c34..01bff8ea28d8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -798,6 +798,7 @@ M: Laura Abbott <labbott@redhat.com> | |||
798 | M: Sumit Semwal <sumit.semwal@linaro.org> | 798 | M: Sumit Semwal <sumit.semwal@linaro.org> |
799 | L: devel@driverdev.osuosl.org | 799 | L: devel@driverdev.osuosl.org |
800 | S: Supported | 800 | S: Supported |
801 | F: Documentation/devicetree/bindings/staging/ion/ | ||
801 | F: drivers/staging/android/ion | 802 | F: drivers/staging/android/ion |
802 | F: drivers/staging/android/uapi/ion.h | 803 | F: drivers/staging/android/uapi/ion.h |
803 | F: drivers/staging/android/uapi/ion_test.h | 804 | F: drivers/staging/android/uapi/ion_test.h |
@@ -881,6 +882,15 @@ S: Supported | |||
881 | F: drivers/gpu/drm/arc/ | 882 | F: drivers/gpu/drm/arc/ |
882 | F: Documentation/devicetree/bindings/display/snps,arcpgu.txt | 883 | F: Documentation/devicetree/bindings/display/snps,arcpgu.txt |
883 | 884 | ||
885 | ARM ARCHITECTED TIMER DRIVER | ||
886 | M: Mark Rutland <mark.rutland@arm.com> | ||
887 | M: Marc Zyngier <marc.zyngier@arm.com> | ||
888 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
889 | S: Maintained | ||
890 | F: arch/arm/include/asm/arch_timer.h | ||
891 | F: arch/arm64/include/asm/arch_timer.h | ||
892 | F: drivers/clocksource/arm_arch_timer.c | ||
893 | |||
884 | ARM HDLCD DRM DRIVER | 894 | ARM HDLCD DRM DRIVER |
885 | M: Liviu Dudau <liviu.dudau@arm.com> | 895 | M: Liviu Dudau <liviu.dudau@arm.com> |
886 | S: Supported | 896 | S: Supported |
@@ -1614,7 +1624,8 @@ N: rockchip | |||
1614 | 1624 | ||
1615 | ARM/SAMSUNG EXYNOS ARM ARCHITECTURES | 1625 | ARM/SAMSUNG EXYNOS ARM ARCHITECTURES |
1616 | M: Kukjin Kim <kgene@kernel.org> | 1626 | M: Kukjin Kim <kgene@kernel.org> |
1617 | M: Krzysztof Kozlowski <k.kozlowski@samsung.com> | 1627 | M: Krzysztof Kozlowski <krzk@kernel.org> |
1628 | R: Javier Martinez Canillas <javier@osg.samsung.com> | ||
1618 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 1629 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
1619 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) | 1630 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) |
1620 | S: Maintained | 1631 | S: Maintained |
@@ -1634,7 +1645,6 @@ F: drivers/*/*s3c64xx* | |||
1634 | F: drivers/*/*s5pv210* | 1645 | F: drivers/*/*s5pv210* |
1635 | F: drivers/memory/samsung/* | 1646 | F: drivers/memory/samsung/* |
1636 | F: drivers/soc/samsung/* | 1647 | F: drivers/soc/samsung/* |
1637 | F: drivers/spi/spi-s3c* | ||
1638 | F: Documentation/arm/Samsung/ | 1648 | F: Documentation/arm/Samsung/ |
1639 | F: Documentation/devicetree/bindings/arm/samsung/ | 1649 | F: Documentation/devicetree/bindings/arm/samsung/ |
1640 | F: Documentation/devicetree/bindings/sram/samsung-sram.txt | 1650 | F: Documentation/devicetree/bindings/sram/samsung-sram.txt |
@@ -1822,6 +1832,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git | |||
1822 | ARM/UNIPHIER ARCHITECTURE | 1832 | ARM/UNIPHIER ARCHITECTURE |
1823 | M: Masahiro Yamada <yamada.masahiro@socionext.com> | 1833 | M: Masahiro Yamada <yamada.masahiro@socionext.com> |
1824 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 1834 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
1835 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-uniphier.git | ||
1825 | S: Maintained | 1836 | S: Maintained |
1826 | F: arch/arm/boot/dts/uniphier* | 1837 | F: arch/arm/boot/dts/uniphier* |
1827 | F: arch/arm/include/asm/hardware/cache-uniphier.h | 1838 | F: arch/arm/include/asm/hardware/cache-uniphier.h |
@@ -2475,7 +2486,7 @@ F: include/net/bluetooth/ | |||
2475 | BONDING DRIVER | 2486 | BONDING DRIVER |
2476 | M: Jay Vosburgh <j.vosburgh@gmail.com> | 2487 | M: Jay Vosburgh <j.vosburgh@gmail.com> |
2477 | M: Veaceslav Falico <vfalico@gmail.com> | 2488 | M: Veaceslav Falico <vfalico@gmail.com> |
2478 | M: Andy Gospodarek <gospo@cumulusnetworks.com> | 2489 | M: Andy Gospodarek <andy@greyhouse.net> |
2479 | L: netdev@vger.kernel.org | 2490 | L: netdev@vger.kernel.org |
2480 | W: http://sourceforge.net/projects/bonding/ | 2491 | W: http://sourceforge.net/projects/bonding/ |
2481 | S: Supported | 2492 | S: Supported |
@@ -2490,7 +2501,7 @@ S: Supported | |||
2490 | F: kernel/bpf/ | 2501 | F: kernel/bpf/ |
2491 | 2502 | ||
2492 | BROADCOM B44 10/100 ETHERNET DRIVER | 2503 | BROADCOM B44 10/100 ETHERNET DRIVER |
2493 | M: Gary Zambrano <zambrano@broadcom.com> | 2504 | M: Michael Chan <michael.chan@broadcom.com> |
2494 | L: netdev@vger.kernel.org | 2505 | L: netdev@vger.kernel.org |
2495 | S: Supported | 2506 | S: Supported |
2496 | F: drivers/net/ethernet/broadcom/b44.* | 2507 | F: drivers/net/ethernet/broadcom/b44.* |
@@ -3238,7 +3249,7 @@ F: kernel/cpuset.c | |||
3238 | CONTROL GROUP - MEMORY RESOURCE CONTROLLER (MEMCG) | 3249 | CONTROL GROUP - MEMORY RESOURCE CONTROLLER (MEMCG) |
3239 | M: Johannes Weiner <hannes@cmpxchg.org> | 3250 | M: Johannes Weiner <hannes@cmpxchg.org> |
3240 | M: Michal Hocko <mhocko@kernel.org> | 3251 | M: Michal Hocko <mhocko@kernel.org> |
3241 | M: Vladimir Davydov <vdavydov@virtuozzo.com> | 3252 | M: Vladimir Davydov <vdavydov.dev@gmail.com> |
3242 | L: cgroups@vger.kernel.org | 3253 | L: cgroups@vger.kernel.org |
3243 | L: linux-mm@kvack.org | 3254 | L: linux-mm@kvack.org |
3244 | S: Maintained | 3255 | S: Maintained |
@@ -3259,7 +3270,7 @@ S: Maintained | |||
3259 | F: drivers/net/wan/cosa* | 3270 | F: drivers/net/wan/cosa* |
3260 | 3271 | ||
3261 | CPMAC ETHERNET DRIVER | 3272 | CPMAC ETHERNET DRIVER |
3262 | M: Florian Fainelli <florian@openwrt.org> | 3273 | M: Florian Fainelli <f.fainelli@gmail.com> |
3263 | L: netdev@vger.kernel.org | 3274 | L: netdev@vger.kernel.org |
3264 | S: Maintained | 3275 | S: Maintained |
3265 | F: drivers/net/ethernet/ti/cpmac.c | 3276 | F: drivers/net/ethernet/ti/cpmac.c |
@@ -6092,7 +6103,7 @@ S: Supported | |||
6092 | F: drivers/cpufreq/intel_pstate.c | 6103 | F: drivers/cpufreq/intel_pstate.c |
6093 | 6104 | ||
6094 | INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) | 6105 | INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) |
6095 | M: Maik Broemme <mbroemme@plusserver.de> | 6106 | M: Maik Broemme <mbroemme@libmpq.org> |
6096 | L: linux-fbdev@vger.kernel.org | 6107 | L: linux-fbdev@vger.kernel.org |
6097 | S: Maintained | 6108 | S: Maintained |
6098 | F: Documentation/fb/intelfb.txt | 6109 | F: Documentation/fb/intelfb.txt |
@@ -7455,7 +7466,8 @@ F: Documentation/devicetree/bindings/sound/max9860.txt | |||
7455 | F: sound/soc/codecs/max9860.* | 7466 | F: sound/soc/codecs/max9860.* |
7456 | 7467 | ||
7457 | MAXIM MUIC CHARGER DRIVERS FOR EXYNOS BASED BOARDS | 7468 | MAXIM MUIC CHARGER DRIVERS FOR EXYNOS BASED BOARDS |
7458 | M: Krzysztof Kozlowski <k.kozlowski@samsung.com> | 7469 | M: Krzysztof Kozlowski <krzk@kernel.org> |
7470 | M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> | ||
7459 | L: linux-pm@vger.kernel.org | 7471 | L: linux-pm@vger.kernel.org |
7460 | S: Supported | 7472 | S: Supported |
7461 | F: drivers/power/max14577_charger.c | 7473 | F: drivers/power/max14577_charger.c |
@@ -7471,7 +7483,8 @@ F: include/dt-bindings/*/*max77802.h | |||
7471 | 7483 | ||
7472 | MAXIM PMIC AND MUIC DRIVERS FOR EXYNOS BASED BOARDS | 7484 | MAXIM PMIC AND MUIC DRIVERS FOR EXYNOS BASED BOARDS |
7473 | M: Chanwoo Choi <cw00.choi@samsung.com> | 7485 | M: Chanwoo Choi <cw00.choi@samsung.com> |
7474 | M: Krzysztof Kozlowski <k.kozlowski@samsung.com> | 7486 | M: Krzysztof Kozlowski <krzk@kernel.org> |
7487 | M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> | ||
7475 | L: linux-kernel@vger.kernel.org | 7488 | L: linux-kernel@vger.kernel.org |
7476 | S: Supported | 7489 | S: Supported |
7477 | F: drivers/*/max14577*.c | 7490 | F: drivers/*/max14577*.c |
@@ -7661,7 +7674,7 @@ L: linux-rdma@vger.kernel.org | |||
7661 | S: Supported | 7674 | S: Supported |
7662 | W: https://github.com/SoftRoCE/rxe-dev/wiki/rxe-dev:-Home | 7675 | W: https://github.com/SoftRoCE/rxe-dev/wiki/rxe-dev:-Home |
7663 | Q: http://patchwork.kernel.org/project/linux-rdma/list/ | 7676 | Q: http://patchwork.kernel.org/project/linux-rdma/list/ |
7664 | F: drivers/infiniband/hw/rxe/ | 7677 | F: drivers/infiniband/sw/rxe/ |
7665 | F: include/uapi/rdma/rdma_user_rxe.h | 7678 | F: include/uapi/rdma/rdma_user_rxe.h |
7666 | 7679 | ||
7667 | MEMBARRIER SUPPORT | 7680 | MEMBARRIER SUPPORT |
@@ -8148,6 +8161,15 @@ S: Maintained | |||
8148 | W: https://fedorahosted.org/dropwatch/ | 8161 | W: https://fedorahosted.org/dropwatch/ |
8149 | F: net/core/drop_monitor.c | 8162 | F: net/core/drop_monitor.c |
8150 | 8163 | ||
8164 | NETWORKING [DSA] | ||
8165 | M: Andrew Lunn <andrew@lunn.ch> | ||
8166 | M: Vivien Didelot <vivien.didelot@savoirfairelinux.com> | ||
8167 | M: Florian Fainelli <f.fainelli@gmail.com> | ||
8168 | S: Maintained | ||
8169 | F: net/dsa/ | ||
8170 | F: include/net/dsa.h | ||
8171 | F: drivers/net/dsa/ | ||
8172 | |||
8151 | NETWORKING [GENERAL] | 8173 | NETWORKING [GENERAL] |
8152 | M: "David S. Miller" <davem@davemloft.net> | 8174 | M: "David S. Miller" <davem@davemloft.net> |
8153 | L: netdev@vger.kernel.org | 8175 | L: netdev@vger.kernel.org |
@@ -9237,7 +9259,7 @@ F: drivers/pinctrl/sh-pfc/ | |||
9237 | 9259 | ||
9238 | PIN CONTROLLER - SAMSUNG | 9260 | PIN CONTROLLER - SAMSUNG |
9239 | M: Tomasz Figa <tomasz.figa@gmail.com> | 9261 | M: Tomasz Figa <tomasz.figa@gmail.com> |
9240 | M: Krzysztof Kozlowski <k.kozlowski@samsung.com> | 9262 | M: Krzysztof Kozlowski <krzk@kernel.org> |
9241 | M: Sylwester Nawrocki <s.nawrocki@samsung.com> | 9263 | M: Sylwester Nawrocki <s.nawrocki@samsung.com> |
9242 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 9264 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
9243 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) | 9265 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) |
@@ -10170,7 +10192,7 @@ S: Maintained | |||
10170 | F: drivers/platform/x86/samsung-laptop.c | 10192 | F: drivers/platform/x86/samsung-laptop.c |
10171 | 10193 | ||
10172 | SAMSUNG AUDIO (ASoC) DRIVERS | 10194 | SAMSUNG AUDIO (ASoC) DRIVERS |
10173 | M: Krzysztof Kozlowski <k.kozlowski@samsung.com> | 10195 | M: Krzysztof Kozlowski <krzk@kernel.org> |
10174 | M: Sangbeom Kim <sbkim73@samsung.com> | 10196 | M: Sangbeom Kim <sbkim73@samsung.com> |
10175 | M: Sylwester Nawrocki <s.nawrocki@samsung.com> | 10197 | M: Sylwester Nawrocki <s.nawrocki@samsung.com> |
10176 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 10198 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
@@ -10185,7 +10207,8 @@ F: drivers/video/fbdev/s3c-fb.c | |||
10185 | 10207 | ||
10186 | SAMSUNG MULTIFUNCTION PMIC DEVICE DRIVERS | 10208 | SAMSUNG MULTIFUNCTION PMIC DEVICE DRIVERS |
10187 | M: Sangbeom Kim <sbkim73@samsung.com> | 10209 | M: Sangbeom Kim <sbkim73@samsung.com> |
10188 | M: Krzysztof Kozlowski <k.kozlowski@samsung.com> | 10210 | M: Krzysztof Kozlowski <krzk@kernel.org> |
10211 | M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> | ||
10189 | L: linux-kernel@vger.kernel.org | 10212 | L: linux-kernel@vger.kernel.org |
10190 | L: linux-samsung-soc@vger.kernel.org | 10213 | L: linux-samsung-soc@vger.kernel.org |
10191 | S: Supported | 10214 | S: Supported |
@@ -10244,6 +10267,17 @@ S: Supported | |||
10244 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) | 10267 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) |
10245 | F: drivers/clk/samsung/ | 10268 | F: drivers/clk/samsung/ |
10246 | 10269 | ||
10270 | SAMSUNG SPI DRIVERS | ||
10271 | M: Kukjin Kim <kgene@kernel.org> | ||
10272 | M: Krzysztof Kozlowski <krzk@kernel.org> | ||
10273 | M: Andi Shyti <andi.shyti@samsung.com> | ||
10274 | L: linux-spi@vger.kernel.org | ||
10275 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) | ||
10276 | S: Maintained | ||
10277 | F: Documentation/devicetree/bindings/spi/spi-samsung.txt | ||
10278 | F: drivers/spi/spi-s3c* | ||
10279 | F: include/linux/platform_data/spi-s3c64xx.h | ||
10280 | |||
10247 | SAMSUNG SXGBE DRIVERS | 10281 | SAMSUNG SXGBE DRIVERS |
10248 | M: Byungho An <bh74.an@samsung.com> | 10282 | M: Byungho An <bh74.an@samsung.com> |
10249 | M: Girish K S <ks.giri@samsung.com> | 10283 | M: Girish K S <ks.giri@samsung.com> |
@@ -11223,12 +11257,8 @@ S: Odd Fixes | |||
11223 | F: drivers/staging/vt665?/ | 11257 | F: drivers/staging/vt665?/ |
11224 | 11258 | ||
11225 | STAGING - WILC1000 WIFI DRIVER | 11259 | STAGING - WILC1000 WIFI DRIVER |
11226 | M: Johnny Kim <johnny.kim@atmel.com> | 11260 | M: Aditya Shankar <aditya.shankar@microchip.com> |
11227 | M: Austin Shin <austin.shin@atmel.com> | 11261 | M: Ganesh Krishna <ganesh.krishna@microchip.com> |
11228 | M: Chris Park <chris.park@atmel.com> | ||
11229 | M: Tony Cho <tony.cho@atmel.com> | ||
11230 | M: Glen Lee <glen.lee@atmel.com> | ||
11231 | M: Leo Kim <leo.kim@atmel.com> | ||
11232 | L: linux-wireless@vger.kernel.org | 11262 | L: linux-wireless@vger.kernel.org |
11233 | S: Supported | 11263 | S: Supported |
11234 | F: drivers/staging/wilc1000/ | 11264 | F: drivers/staging/wilc1000/ |
@@ -12548,7 +12578,7 @@ F: include/linux/if_*vlan.h | |||
12548 | F: net/8021q/ | 12578 | F: net/8021q/ |
12549 | 12579 | ||
12550 | VLYNQ BUS | 12580 | VLYNQ BUS |
12551 | M: Florian Fainelli <florian@openwrt.org> | 12581 | M: Florian Fainelli <f.fainelli@gmail.com> |
12552 | L: openwrt-devel@lists.openwrt.org (subscribers-only) | 12582 | L: openwrt-devel@lists.openwrt.org (subscribers-only) |
12553 | S: Maintained | 12583 | S: Maintained |
12554 | F: drivers/vlynq/vlynq.c | 12584 | F: drivers/vlynq/vlynq.c |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 4 | 1 | VERSION = 4 |
2 | PATCHLEVEL = 8 | 2 | PATCHLEVEL = 8 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = -rc3 | 4 | EXTRAVERSION = -rc8 |
5 | NAME = Psychotic Stoned Sheep | 5 | NAME = Psychotic Stoned Sheep |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/Kconfig b/arch/Kconfig index e9c9334507dd..fd6e9712af81 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
@@ -336,17 +336,6 @@ config HAVE_ARCH_SECCOMP_FILTER | |||
336 | results in the system call being skipped immediately. | 336 | results in the system call being skipped immediately. |
337 | - seccomp syscall wired up | 337 | - seccomp syscall wired up |
338 | 338 | ||
339 | For best performance, an arch should use seccomp_phase1 and | ||
340 | seccomp_phase2 directly. It should call seccomp_phase1 for all | ||
341 | syscalls if TIF_SECCOMP is set, but seccomp_phase1 does not | ||
342 | need to be called from a ptrace-safe context. It must then | ||
343 | call seccomp_phase2 if seccomp_phase1 returns anything other | ||
344 | than SECCOMP_PHASE1_OK or SECCOMP_PHASE1_SKIP. | ||
345 | |||
346 | As an additional optimization, an arch may provide seccomp_data | ||
347 | directly to seccomp_phase1; this avoids multiple calls | ||
348 | to the syscall_xyz helpers for every syscall. | ||
349 | |||
350 | config SECCOMP_FILTER | 339 | config SECCOMP_FILTER |
351 | def_bool y | 340 | def_bool y |
352 | depends on HAVE_ARCH_SECCOMP_FILTER && SECCOMP && NET | 341 | depends on HAVE_ARCH_SECCOMP_FILTER && SECCOMP && NET |
diff --git a/arch/alpha/include/asm/uaccess.h b/arch/alpha/include/asm/uaccess.h index c419b43c461d..466e42e96bfa 100644 --- a/arch/alpha/include/asm/uaccess.h +++ b/arch/alpha/include/asm/uaccess.h | |||
@@ -371,14 +371,6 @@ __copy_tofrom_user_nocheck(void *to, const void *from, long len) | |||
371 | return __cu_len; | 371 | return __cu_len; |
372 | } | 372 | } |
373 | 373 | ||
374 | extern inline long | ||
375 | __copy_tofrom_user(void *to, const void *from, long len, const void __user *validate) | ||
376 | { | ||
377 | if (__access_ok((unsigned long)validate, len, get_fs())) | ||
378 | len = __copy_tofrom_user_nocheck(to, from, len); | ||
379 | return len; | ||
380 | } | ||
381 | |||
382 | #define __copy_to_user(to, from, n) \ | 374 | #define __copy_to_user(to, from, n) \ |
383 | ({ \ | 375 | ({ \ |
384 | __chk_user_ptr(to); \ | 376 | __chk_user_ptr(to); \ |
@@ -393,17 +385,22 @@ __copy_tofrom_user(void *to, const void *from, long len, const void __user *vali | |||
393 | #define __copy_to_user_inatomic __copy_to_user | 385 | #define __copy_to_user_inatomic __copy_to_user |
394 | #define __copy_from_user_inatomic __copy_from_user | 386 | #define __copy_from_user_inatomic __copy_from_user |
395 | 387 | ||
396 | |||
397 | extern inline long | 388 | extern inline long |
398 | copy_to_user(void __user *to, const void *from, long n) | 389 | copy_to_user(void __user *to, const void *from, long n) |
399 | { | 390 | { |
400 | return __copy_tofrom_user((__force void *)to, from, n, to); | 391 | if (likely(__access_ok((unsigned long)to, n, get_fs()))) |
392 | n = __copy_tofrom_user_nocheck((__force void *)to, from, n); | ||
393 | return n; | ||
401 | } | 394 | } |
402 | 395 | ||
403 | extern inline long | 396 | extern inline long |
404 | copy_from_user(void *to, const void __user *from, long n) | 397 | copy_from_user(void *to, const void __user *from, long n) |
405 | { | 398 | { |
406 | return __copy_tofrom_user(to, (__force void *)from, n, from); | 399 | if (likely(__access_ok((unsigned long)from, n, get_fs()))) |
400 | n = __copy_tofrom_user_nocheck(to, (__force void *)from, n); | ||
401 | else | ||
402 | memset(to, 0, n); | ||
403 | return n; | ||
407 | } | 404 | } |
408 | 405 | ||
409 | extern void __do_clear_user(void); | 406 | extern void __do_clear_user(void); |
diff --git a/arch/arc/include/asm/entry.h b/arch/arc/include/asm/entry.h index ad7860c5ce15..51597f344a62 100644 --- a/arch/arc/include/asm/entry.h +++ b/arch/arc/include/asm/entry.h | |||
@@ -142,7 +142,7 @@ | |||
142 | 142 | ||
143 | #ifdef CONFIG_ARC_CURR_IN_REG | 143 | #ifdef CONFIG_ARC_CURR_IN_REG |
144 | ; Retrieve orig r25 and save it with rest of callee_regs | 144 | ; Retrieve orig r25 and save it with rest of callee_regs |
145 | ld.as r12, [r12, PT_user_r25] | 145 | ld r12, [r12, PT_user_r25] |
146 | PUSH r12 | 146 | PUSH r12 |
147 | #else | 147 | #else |
148 | PUSH r25 | 148 | PUSH r25 |
@@ -198,7 +198,7 @@ | |||
198 | 198 | ||
199 | ; SP is back to start of pt_regs | 199 | ; SP is back to start of pt_regs |
200 | #ifdef CONFIG_ARC_CURR_IN_REG | 200 | #ifdef CONFIG_ARC_CURR_IN_REG |
201 | st.as r12, [sp, PT_user_r25] | 201 | st r12, [sp, PT_user_r25] |
202 | #endif | 202 | #endif |
203 | .endm | 203 | .endm |
204 | 204 | ||
diff --git a/arch/arc/include/asm/irqflags-compact.h b/arch/arc/include/asm/irqflags-compact.h index c1d36458bfb7..4c6eed80cd8b 100644 --- a/arch/arc/include/asm/irqflags-compact.h +++ b/arch/arc/include/asm/irqflags-compact.h | |||
@@ -188,10 +188,10 @@ static inline int arch_irqs_disabled(void) | |||
188 | .endm | 188 | .endm |
189 | 189 | ||
190 | .macro IRQ_ENABLE scratch | 190 | .macro IRQ_ENABLE scratch |
191 | TRACE_ASM_IRQ_ENABLE | ||
191 | lr \scratch, [status32] | 192 | lr \scratch, [status32] |
192 | or \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK) | 193 | or \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK) |
193 | flag \scratch | 194 | flag \scratch |
194 | TRACE_ASM_IRQ_ENABLE | ||
195 | .endm | 195 | .endm |
196 | 196 | ||
197 | #endif /* __ASSEMBLY__ */ | 197 | #endif /* __ASSEMBLY__ */ |
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h index 0f92d97432a2..89eeb3720051 100644 --- a/arch/arc/include/asm/pgtable.h +++ b/arch/arc/include/asm/pgtable.h | |||
@@ -280,7 +280,7 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep) | |||
280 | 280 | ||
281 | #define pte_page(pte) pfn_to_page(pte_pfn(pte)) | 281 | #define pte_page(pte) pfn_to_page(pte_pfn(pte)) |
282 | #define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot) | 282 | #define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot) |
283 | #define pfn_pte(pfn, prot) (__pte(((pte_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))) | 283 | #define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) |
284 | 284 | ||
285 | /* Don't use virt_to_pfn for macros below: could cause truncations for PAE40*/ | 285 | /* Don't use virt_to_pfn for macros below: could cause truncations for PAE40*/ |
286 | #define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) | 286 | #define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) |
diff --git a/arch/arc/include/asm/uaccess.h b/arch/arc/include/asm/uaccess.h index a78d5670884f..41faf17cd28d 100644 --- a/arch/arc/include/asm/uaccess.h +++ b/arch/arc/include/asm/uaccess.h | |||
@@ -83,7 +83,10 @@ | |||
83 | "2: ;nop\n" \ | 83 | "2: ;nop\n" \ |
84 | " .section .fixup, \"ax\"\n" \ | 84 | " .section .fixup, \"ax\"\n" \ |
85 | " .align 4\n" \ | 85 | " .align 4\n" \ |
86 | "3: mov %0, %3\n" \ | 86 | "3: # return -EFAULT\n" \ |
87 | " mov %0, %3\n" \ | ||
88 | " # zero out dst ptr\n" \ | ||
89 | " mov %1, 0\n" \ | ||
87 | " j 2b\n" \ | 90 | " j 2b\n" \ |
88 | " .previous\n" \ | 91 | " .previous\n" \ |
89 | " .section __ex_table, \"a\"\n" \ | 92 | " .section __ex_table, \"a\"\n" \ |
@@ -101,7 +104,11 @@ | |||
101 | "2: ;nop\n" \ | 104 | "2: ;nop\n" \ |
102 | " .section .fixup, \"ax\"\n" \ | 105 | " .section .fixup, \"ax\"\n" \ |
103 | " .align 4\n" \ | 106 | " .align 4\n" \ |
104 | "3: mov %0, %3\n" \ | 107 | "3: # return -EFAULT\n" \ |
108 | " mov %0, %3\n" \ | ||
109 | " # zero out dst ptr\n" \ | ||
110 | " mov %1, 0\n" \ | ||
111 | " mov %R1, 0\n" \ | ||
105 | " j 2b\n" \ | 112 | " j 2b\n" \ |
106 | " .previous\n" \ | 113 | " .previous\n" \ |
107 | " .section __ex_table, \"a\"\n" \ | 114 | " .section __ex_table, \"a\"\n" \ |
diff --git a/arch/arc/include/uapi/asm/elf.h b/arch/arc/include/uapi/asm/elf.h index 0f99ac8fcbb2..0037a587320d 100644 --- a/arch/arc/include/uapi/asm/elf.h +++ b/arch/arc/include/uapi/asm/elf.h | |||
@@ -13,8 +13,15 @@ | |||
13 | 13 | ||
14 | /* Machine specific ELF Hdr flags */ | 14 | /* Machine specific ELF Hdr flags */ |
15 | #define EF_ARC_OSABI_MSK 0x00000f00 | 15 | #define EF_ARC_OSABI_MSK 0x00000f00 |
16 | #define EF_ARC_OSABI_ORIG 0x00000000 /* MUST be zero for back-compat */ | 16 | |
17 | #define EF_ARC_OSABI_CURRENT 0x00000300 /* v3 (no legacy syscalls) */ | 17 | #define EF_ARC_OSABI_V3 0x00000300 /* v3 (no legacy syscalls) */ |
18 | #define EF_ARC_OSABI_V4 0x00000400 /* v4 (64bit data any reg align) */ | ||
19 | |||
20 | #if __GNUC__ < 6 | ||
21 | #define EF_ARC_OSABI_CURRENT EF_ARC_OSABI_V3 | ||
22 | #else | ||
23 | #define EF_ARC_OSABI_CURRENT EF_ARC_OSABI_V4 | ||
24 | #endif | ||
18 | 25 | ||
19 | typedef unsigned long elf_greg_t; | 26 | typedef unsigned long elf_greg_t; |
20 | typedef unsigned long elf_fpregset_t; | 27 | typedef unsigned long elf_fpregset_t; |
diff --git a/arch/arc/kernel/arcksyms.c b/arch/arc/kernel/arcksyms.c index 4d9e77724bed..000dd041ab42 100644 --- a/arch/arc/kernel/arcksyms.c +++ b/arch/arc/kernel/arcksyms.c | |||
@@ -28,6 +28,7 @@ extern void __muldf3(void); | |||
28 | extern void __divdf3(void); | 28 | extern void __divdf3(void); |
29 | extern void __floatunsidf(void); | 29 | extern void __floatunsidf(void); |
30 | extern void __floatunsisf(void); | 30 | extern void __floatunsisf(void); |
31 | extern void __udivdi3(void); | ||
31 | 32 | ||
32 | EXPORT_SYMBOL(__ashldi3); | 33 | EXPORT_SYMBOL(__ashldi3); |
33 | EXPORT_SYMBOL(__ashrdi3); | 34 | EXPORT_SYMBOL(__ashrdi3); |
@@ -45,6 +46,7 @@ EXPORT_SYMBOL(__muldf3); | |||
45 | EXPORT_SYMBOL(__divdf3); | 46 | EXPORT_SYMBOL(__divdf3); |
46 | EXPORT_SYMBOL(__floatunsidf); | 47 | EXPORT_SYMBOL(__floatunsidf); |
47 | EXPORT_SYMBOL(__floatunsisf); | 48 | EXPORT_SYMBOL(__floatunsisf); |
49 | EXPORT_SYMBOL(__udivdi3); | ||
48 | 50 | ||
49 | /* ARC optimised assembler routines */ | 51 | /* ARC optimised assembler routines */ |
50 | EXPORT_SYMBOL(memset); | 52 | EXPORT_SYMBOL(memset); |
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c index b5db9e7fd649..be1972bd2729 100644 --- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c | |||
@@ -199,7 +199,7 @@ int elf_check_arch(const struct elf32_hdr *x) | |||
199 | } | 199 | } |
200 | 200 | ||
201 | eflags = x->e_flags; | 201 | eflags = x->e_flags; |
202 | if ((eflags & EF_ARC_OSABI_MSK) < EF_ARC_OSABI_CURRENT) { | 202 | if ((eflags & EF_ARC_OSABI_MSK) != EF_ARC_OSABI_CURRENT) { |
203 | pr_err("ABI mismatch - you need newer toolchain\n"); | 203 | pr_err("ABI mismatch - you need newer toolchain\n"); |
204 | force_sigsegv(SIGSEGV, current); | 204 | force_sigsegv(SIGSEGV, current); |
205 | return 0; | 205 | return 0; |
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index a946400a86d0..f52a0d0dc462 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c | |||
@@ -291,8 +291,10 @@ static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) | |||
291 | cpu->dccm.base_addr, TO_KB(cpu->dccm.sz), | 291 | cpu->dccm.base_addr, TO_KB(cpu->dccm.sz), |
292 | cpu->iccm.base_addr, TO_KB(cpu->iccm.sz)); | 292 | cpu->iccm.base_addr, TO_KB(cpu->iccm.sz)); |
293 | 293 | ||
294 | n += scnprintf(buf + n, len - n, | 294 | n += scnprintf(buf + n, len - n, "OS ABI [v%d]\t: %s\n", |
295 | "OS ABI [v3]\t: no-legacy-syscalls\n"); | 295 | EF_ARC_OSABI_CURRENT >> 8, |
296 | EF_ARC_OSABI_CURRENT == EF_ARC_OSABI_V3 ? | ||
297 | "no-legacy-syscalls" : "64-bit data any register aligned"); | ||
296 | 298 | ||
297 | return buf; | 299 | return buf; |
298 | } | 300 | } |
diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index 5a294b2c3cb3..0b10efe3a6a7 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c | |||
@@ -921,6 +921,15 @@ void arc_cache_init(void) | |||
921 | 921 | ||
922 | printk(arc_cache_mumbojumbo(0, str, sizeof(str))); | 922 | printk(arc_cache_mumbojumbo(0, str, sizeof(str))); |
923 | 923 | ||
924 | /* | ||
925 | * Only master CPU needs to execute rest of function: | ||
926 | * - Assume SMP so all cores will have same cache config so | ||
927 | * any geomtry checks will be same for all | ||
928 | * - IOC setup / dma callbacks only need to be setup once | ||
929 | */ | ||
930 | if (cpu) | ||
931 | return; | ||
932 | |||
924 | if (IS_ENABLED(CONFIG_ARC_HAS_ICACHE)) { | 933 | if (IS_ENABLED(CONFIG_ARC_HAS_ICACHE)) { |
925 | struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache; | 934 | struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache; |
926 | 935 | ||
diff --git a/arch/arc/mm/highmem.c b/arch/arc/mm/highmem.c index 04f83322c9fd..77ff64a874a1 100644 --- a/arch/arc/mm/highmem.c +++ b/arch/arc/mm/highmem.c | |||
@@ -61,6 +61,7 @@ void *kmap(struct page *page) | |||
61 | 61 | ||
62 | return kmap_high(page); | 62 | return kmap_high(page); |
63 | } | 63 | } |
64 | EXPORT_SYMBOL(kmap); | ||
64 | 65 | ||
65 | void *kmap_atomic(struct page *page) | 66 | void *kmap_atomic(struct page *page) |
66 | { | 67 | { |
diff --git a/arch/arm/boot/dts/am335x-baltos.dtsi b/arch/arm/boot/dts/am335x-baltos.dtsi index c8609d8d2c55..b689172632ef 100644 --- a/arch/arm/boot/dts/am335x-baltos.dtsi +++ b/arch/arm/boot/dts/am335x-baltos.dtsi | |||
@@ -226,7 +226,7 @@ | |||
226 | 226 | ||
227 | #address-cells = <1>; | 227 | #address-cells = <1>; |
228 | #size-cells = <1>; | 228 | #size-cells = <1>; |
229 | elm_id = <&elm>; | 229 | ti,elm-id = <&elm>; |
230 | }; | 230 | }; |
231 | }; | 231 | }; |
232 | 232 | ||
diff --git a/arch/arm/boot/dts/am335x-igep0033.dtsi b/arch/arm/boot/dts/am335x-igep0033.dtsi index df63484ef9b3..e7d9ca1305fa 100644 --- a/arch/arm/boot/dts/am335x-igep0033.dtsi +++ b/arch/arm/boot/dts/am335x-igep0033.dtsi | |||
@@ -161,7 +161,7 @@ | |||
161 | 161 | ||
162 | #address-cells = <1>; | 162 | #address-cells = <1>; |
163 | #size-cells = <1>; | 163 | #size-cells = <1>; |
164 | elm_id = <&elm>; | 164 | ti,elm-id = <&elm>; |
165 | 165 | ||
166 | /* MTD partition table */ | 166 | /* MTD partition table */ |
167 | partition@0 { | 167 | partition@0 { |
diff --git a/arch/arm/boot/dts/am335x-phycore-som.dtsi b/arch/arm/boot/dts/am335x-phycore-som.dtsi index 86f773165d5c..1263c9d4cba3 100644 --- a/arch/arm/boot/dts/am335x-phycore-som.dtsi +++ b/arch/arm/boot/dts/am335x-phycore-som.dtsi | |||
@@ -197,7 +197,7 @@ | |||
197 | gpmc,wr-access-ns = <30>; | 197 | gpmc,wr-access-ns = <30>; |
198 | gpmc,wr-data-mux-bus-ns = <0>; | 198 | gpmc,wr-data-mux-bus-ns = <0>; |
199 | 199 | ||
200 | elm_id = <&elm>; | 200 | ti,elm-id = <&elm>; |
201 | 201 | ||
202 | #address-cells = <1>; | 202 | #address-cells = <1>; |
203 | #size-cells = <1>; | 203 | #size-cells = <1>; |
diff --git a/arch/arm/boot/dts/armada-388-clearfog.dts b/arch/arm/boot/dts/armada-388-clearfog.dts index 2e0556af6e5e..d3e6bd805006 100644 --- a/arch/arm/boot/dts/armada-388-clearfog.dts +++ b/arch/arm/boot/dts/armada-388-clearfog.dts | |||
@@ -390,12 +390,12 @@ | |||
390 | 390 | ||
391 | port@0 { | 391 | port@0 { |
392 | reg = <0>; | 392 | reg = <0>; |
393 | label = "lan1"; | 393 | label = "lan5"; |
394 | }; | 394 | }; |
395 | 395 | ||
396 | port@1 { | 396 | port@1 { |
397 | reg = <1>; | 397 | reg = <1>; |
398 | label = "lan2"; | 398 | label = "lan4"; |
399 | }; | 399 | }; |
400 | 400 | ||
401 | port@2 { | 401 | port@2 { |
@@ -405,12 +405,12 @@ | |||
405 | 405 | ||
406 | port@3 { | 406 | port@3 { |
407 | reg = <3>; | 407 | reg = <3>; |
408 | label = "lan4"; | 408 | label = "lan2"; |
409 | }; | 409 | }; |
410 | 410 | ||
411 | port@4 { | 411 | port@4 { |
412 | reg = <4>; | 412 | reg = <4>; |
413 | label = "lan5"; | 413 | label = "lan1"; |
414 | }; | 414 | }; |
415 | 415 | ||
416 | port@5 { | 416 | port@5 { |
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi index caf2707680c1..e9b47b2bbc33 100644 --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | / { | 3 | / { |
4 | memory { | 4 | memory { |
5 | device_type = "memory"; | ||
5 | reg = <0 0x10000000>; | 6 | reg = <0 0x10000000>; |
6 | }; | 7 | }; |
7 | 8 | ||
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi index b98252232d20..445624a1a1de 100644 --- a/arch/arm/boot/dts/bcm283x.dtsi +++ b/arch/arm/boot/dts/bcm283x.dtsi | |||
@@ -2,7 +2,6 @@ | |||
2 | #include <dt-bindings/clock/bcm2835.h> | 2 | #include <dt-bindings/clock/bcm2835.h> |
3 | #include <dt-bindings/clock/bcm2835-aux.h> | 3 | #include <dt-bindings/clock/bcm2835-aux.h> |
4 | #include <dt-bindings/gpio/gpio.h> | 4 | #include <dt-bindings/gpio/gpio.h> |
5 | #include "skeleton.dtsi" | ||
6 | 5 | ||
7 | /* This include file covers the common peripherals and configuration between | 6 | /* This include file covers the common peripherals and configuration between |
8 | * bcm2835 and bcm2836 implementations, leaving the CPU configuration to | 7 | * bcm2835 and bcm2836 implementations, leaving the CPU configuration to |
@@ -13,6 +12,8 @@ | |||
13 | compatible = "brcm,bcm2835"; | 12 | compatible = "brcm,bcm2835"; |
14 | model = "BCM2835"; | 13 | model = "BCM2835"; |
15 | interrupt-parent = <&intc>; | 14 | interrupt-parent = <&intc>; |
15 | #address-cells = <1>; | ||
16 | #size-cells = <1>; | ||
16 | 17 | ||
17 | chosen { | 18 | chosen { |
18 | bootargs = "earlyprintk console=ttyAMA0"; | 19 | bootargs = "earlyprintk console=ttyAMA0"; |
diff --git a/arch/arm/boot/dts/exynos5410-odroidxu.dts b/arch/arm/boot/dts/exynos5410-odroidxu.dts index d9499310a301..f6d135245a4b 100644 --- a/arch/arm/boot/dts/exynos5410-odroidxu.dts +++ b/arch/arm/boot/dts/exynos5410-odroidxu.dts | |||
@@ -447,14 +447,11 @@ | |||
447 | samsung,dw-mshc-ciu-div = <3>; | 447 | samsung,dw-mshc-ciu-div = <3>; |
448 | samsung,dw-mshc-sdr-timing = <0 4>; | 448 | samsung,dw-mshc-sdr-timing = <0 4>; |
449 | samsung,dw-mshc-ddr-timing = <0 2>; | 449 | samsung,dw-mshc-ddr-timing = <0 2>; |
450 | samsung,dw-mshc-hs400-timing = <0 2>; | ||
451 | samsung,read-strobe-delay = <90>; | ||
452 | pinctrl-names = "default"; | 450 | pinctrl-names = "default"; |
453 | pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8 &sd0_cd>; | 451 | pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8 &sd0_cd>; |
454 | bus-width = <8>; | 452 | bus-width = <8>; |
455 | cap-mmc-highspeed; | 453 | cap-mmc-highspeed; |
456 | mmc-hs200-1_8v; | 454 | mmc-hs200-1_8v; |
457 | mmc-hs400-1_8v; | ||
458 | vmmc-supply = <&ldo20_reg>; | 455 | vmmc-supply = <&ldo20_reg>; |
459 | vqmmc-supply = <&ldo11_reg>; | 456 | vqmmc-supply = <&ldo11_reg>; |
460 | }; | 457 | }; |
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index b620ac884cfd..b13b0b2db881 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi | |||
@@ -243,7 +243,7 @@ | |||
243 | clocks = <&clks IMX6QDL_CLK_SPDIF_GCLK>, <&clks IMX6QDL_CLK_OSC>, | 243 | clocks = <&clks IMX6QDL_CLK_SPDIF_GCLK>, <&clks IMX6QDL_CLK_OSC>, |
244 | <&clks IMX6QDL_CLK_SPDIF>, <&clks IMX6QDL_CLK_ASRC>, | 244 | <&clks IMX6QDL_CLK_SPDIF>, <&clks IMX6QDL_CLK_ASRC>, |
245 | <&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_ESAI_EXTAL>, | 245 | <&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_ESAI_EXTAL>, |
246 | <&clks IMX6QDL_CLK_IPG>, <&clks IMX6QDL_CLK_MLB>, | 246 | <&clks IMX6QDL_CLK_IPG>, <&clks IMX6QDL_CLK_DUMMY>, |
247 | <&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_SPBA>; | 247 | <&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_SPBA>; |
248 | clock-names = "core", "rxtx0", | 248 | clock-names = "core", "rxtx0", |
249 | "rxtx1", "rxtx2", | 249 | "rxtx1", "rxtx2", |
diff --git a/arch/arm/boot/dts/imx6sx-sabreauto.dts b/arch/arm/boot/dts/imx6sx-sabreauto.dts index 96ea936eeeb0..240a2864d044 100644 --- a/arch/arm/boot/dts/imx6sx-sabreauto.dts +++ b/arch/arm/boot/dts/imx6sx-sabreauto.dts | |||
@@ -64,7 +64,7 @@ | |||
64 | cd-gpios = <&gpio7 11 GPIO_ACTIVE_LOW>; | 64 | cd-gpios = <&gpio7 11 GPIO_ACTIVE_LOW>; |
65 | no-1-8-v; | 65 | no-1-8-v; |
66 | keep-power-in-suspend; | 66 | keep-power-in-suspend; |
67 | enable-sdio-wakup; | 67 | wakeup-source; |
68 | status = "okay"; | 68 | status = "okay"; |
69 | }; | 69 | }; |
70 | 70 | ||
diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts index 95ee268ed510..2f33c463cbce 100644 --- a/arch/arm/boot/dts/imx7d-sdb.dts +++ b/arch/arm/boot/dts/imx7d-sdb.dts | |||
@@ -131,7 +131,7 @@ | |||
131 | ti,y-min = /bits/ 16 <0>; | 131 | ti,y-min = /bits/ 16 <0>; |
132 | ti,y-max = /bits/ 16 <0>; | 132 | ti,y-max = /bits/ 16 <0>; |
133 | ti,pressure-max = /bits/ 16 <0>; | 133 | ti,pressure-max = /bits/ 16 <0>; |
134 | ti,x-plat-ohms = /bits/ 16 <400>; | 134 | ti,x-plate-ohms = /bits/ 16 <400>; |
135 | wakeup-source; | 135 | wakeup-source; |
136 | }; | 136 | }; |
137 | }; | 137 | }; |
diff --git a/arch/arm/boot/dts/kirkwood-ib62x0.dts b/arch/arm/boot/dts/kirkwood-ib62x0.dts index ef84d8699a76..5bf62897014c 100644 --- a/arch/arm/boot/dts/kirkwood-ib62x0.dts +++ b/arch/arm/boot/dts/kirkwood-ib62x0.dts | |||
@@ -113,7 +113,7 @@ | |||
113 | 113 | ||
114 | partition@e0000 { | 114 | partition@e0000 { |
115 | label = "u-boot environment"; | 115 | label = "u-boot environment"; |
116 | reg = <0xe0000 0x100000>; | 116 | reg = <0xe0000 0x20000>; |
117 | }; | 117 | }; |
118 | 118 | ||
119 | partition@100000 { | 119 | partition@100000 { |
diff --git a/arch/arm/boot/dts/kirkwood-openrd.dtsi b/arch/arm/boot/dts/kirkwood-openrd.dtsi index e4ecab112601..7175511a92da 100644 --- a/arch/arm/boot/dts/kirkwood-openrd.dtsi +++ b/arch/arm/boot/dts/kirkwood-openrd.dtsi | |||
@@ -116,6 +116,10 @@ | |||
116 | }; | 116 | }; |
117 | }; | 117 | }; |
118 | 118 | ||
119 | &pciec { | ||
120 | status = "okay"; | ||
121 | }; | ||
122 | |||
119 | &pcie0 { | 123 | &pcie0 { |
120 | status = "okay"; | 124 | status = "okay"; |
121 | }; | 125 | }; |
diff --git a/arch/arm/boot/dts/logicpd-som-lv.dtsi b/arch/arm/boot/dts/logicpd-som-lv.dtsi index 365f39ff58bb..0ff1c2de95bf 100644 --- a/arch/arm/boot/dts/logicpd-som-lv.dtsi +++ b/arch/arm/boot/dts/logicpd-som-lv.dtsi | |||
@@ -35,10 +35,15 @@ | |||
35 | ranges = <0 0 0x00000000 0x1000000>; /* CS0: 16MB for NAND */ | 35 | ranges = <0 0 0x00000000 0x1000000>; /* CS0: 16MB for NAND */ |
36 | 36 | ||
37 | nand@0,0 { | 37 | nand@0,0 { |
38 | linux,mtd-name = "micron,mt29f4g16abbda3w"; | 38 | compatible = "ti,omap2-nand"; |
39 | reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ | 39 | reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ |
40 | interrupt-parent = <&gpmc>; | ||
41 | interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ | ||
42 | <1 IRQ_TYPE_NONE>; /* termcount */ | ||
43 | linux,mtd-name = "micron,mt29f4g16abbda3w"; | ||
40 | nand-bus-width = <16>; | 44 | nand-bus-width = <16>; |
41 | ti,nand-ecc-opt = "bch8"; | 45 | ti,nand-ecc-opt = "bch8"; |
46 | rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */ | ||
42 | gpmc,sync-clk-ps = <0>; | 47 | gpmc,sync-clk-ps = <0>; |
43 | gpmc,cs-on-ns = <0>; | 48 | gpmc,cs-on-ns = <0>; |
44 | gpmc,cs-rd-off-ns = <44>; | 49 | gpmc,cs-rd-off-ns = <44>; |
@@ -54,10 +59,6 @@ | |||
54 | gpmc,wr-access-ns = <40>; | 59 | gpmc,wr-access-ns = <40>; |
55 | gpmc,wr-data-mux-bus-ns = <0>; | 60 | gpmc,wr-data-mux-bus-ns = <0>; |
56 | gpmc,device-width = <2>; | 61 | gpmc,device-width = <2>; |
57 | |||
58 | gpmc,page-burst-access-ns = <5>; | ||
59 | gpmc,cycle2cycle-delay-ns = <50>; | ||
60 | |||
61 | #address-cells = <1>; | 62 | #address-cells = <1>; |
62 | #size-cells = <1>; | 63 | #size-cells = <1>; |
63 | 64 | ||
diff --git a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi index 5e9a13c0eaf7..1c2c74655416 100644 --- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi +++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi | |||
@@ -46,6 +46,7 @@ | |||
46 | linux,mtd-name = "micron,mt29f4g16abbda3w"; | 46 | linux,mtd-name = "micron,mt29f4g16abbda3w"; |
47 | nand-bus-width = <16>; | 47 | nand-bus-width = <16>; |
48 | ti,nand-ecc-opt = "bch8"; | 48 | ti,nand-ecc-opt = "bch8"; |
49 | rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */ | ||
49 | gpmc,sync-clk-ps = <0>; | 50 | gpmc,sync-clk-ps = <0>; |
50 | gpmc,cs-on-ns = <0>; | 51 | gpmc,cs-on-ns = <0>; |
51 | gpmc,cs-rd-off-ns = <44>; | 52 | gpmc,cs-rd-off-ns = <44>; |
diff --git a/arch/arm/boot/dts/omap3-overo-base.dtsi b/arch/arm/boot/dts/omap3-overo-base.dtsi index de256fa8da48..3e946cac55f3 100644 --- a/arch/arm/boot/dts/omap3-overo-base.dtsi +++ b/arch/arm/boot/dts/omap3-overo-base.dtsi | |||
@@ -223,7 +223,9 @@ | |||
223 | }; | 223 | }; |
224 | 224 | ||
225 | &gpmc { | 225 | &gpmc { |
226 | ranges = <0 0 0x00000000 0x20000000>; | 226 | ranges = <0 0 0x30000000 0x1000000>, /* CS0 */ |
227 | <4 0 0x2b000000 0x1000000>, /* CS4 */ | ||
228 | <5 0 0x2c000000 0x1000000>; /* CS5 */ | ||
227 | 229 | ||
228 | nand@0,0 { | 230 | nand@0,0 { |
229 | compatible = "ti,omap2-nand"; | 231 | compatible = "ti,omap2-nand"; |
diff --git a/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi b/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi index 7df27926ead2..4f4c6efbd518 100644 --- a/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi +++ b/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi | |||
@@ -55,8 +55,6 @@ | |||
55 | #include "omap-gpmc-smsc9221.dtsi" | 55 | #include "omap-gpmc-smsc9221.dtsi" |
56 | 56 | ||
57 | &gpmc { | 57 | &gpmc { |
58 | ranges = <5 0 0x2c000000 0x1000000>; /* CS5 */ | ||
59 | |||
60 | ethernet@gpmc { | 58 | ethernet@gpmc { |
61 | reg = <5 0 0xff>; | 59 | reg = <5 0 0xff>; |
62 | interrupt-parent = <&gpio6>; | 60 | interrupt-parent = <&gpio6>; |
diff --git a/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi b/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi index 9e24b6a1d07b..1b304e2f1bd2 100644 --- a/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi +++ b/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi | |||
@@ -27,8 +27,6 @@ | |||
27 | #include "omap-gpmc-smsc9221.dtsi" | 27 | #include "omap-gpmc-smsc9221.dtsi" |
28 | 28 | ||
29 | &gpmc { | 29 | &gpmc { |
30 | ranges = <5 0 0x2c000000 0x1000000>; /* CS5 */ | ||
31 | |||
32 | ethernet@gpmc { | 30 | ethernet@gpmc { |
33 | reg = <5 0 0xff>; | 31 | reg = <5 0 0xff>; |
34 | interrupt-parent = <&gpio6>; | 32 | interrupt-parent = <&gpio6>; |
diff --git a/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi b/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi index 334109e14613..82e98ee3023a 100644 --- a/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi +++ b/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi | |||
@@ -15,9 +15,6 @@ | |||
15 | #include "omap-gpmc-smsc9221.dtsi" | 15 | #include "omap-gpmc-smsc9221.dtsi" |
16 | 16 | ||
17 | &gpmc { | 17 | &gpmc { |
18 | ranges = <4 0 0x2b000000 0x1000000>, /* CS4 */ | ||
19 | <5 0 0x2c000000 0x1000000>; /* CS5 */ | ||
20 | |||
21 | smsc1: ethernet@gpmc { | 18 | smsc1: ethernet@gpmc { |
22 | reg = <5 0 0xff>; | 19 | reg = <5 0 0xff>; |
23 | interrupt-parent = <&gpio6>; | 20 | interrupt-parent = <&gpio6>; |
diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi index c0ba86c3a2ab..0d0dae3a1694 100644 --- a/arch/arm/boot/dts/rk3066a.dtsi +++ b/arch/arm/boot/dts/rk3066a.dtsi | |||
@@ -197,6 +197,8 @@ | |||
197 | clock-names = "saradc", "apb_pclk"; | 197 | clock-names = "saradc", "apb_pclk"; |
198 | interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>; | 198 | interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>; |
199 | #io-channel-cells = <1>; | 199 | #io-channel-cells = <1>; |
200 | resets = <&cru SRST_SARADC>; | ||
201 | reset-names = "saradc-apb"; | ||
200 | status = "disabled"; | 202 | status = "disabled"; |
201 | }; | 203 | }; |
202 | 204 | ||
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index cd33f0170890..91c4b3c7a8d5 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi | |||
@@ -279,6 +279,8 @@ | |||
279 | #io-channel-cells = <1>; | 279 | #io-channel-cells = <1>; |
280 | clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; | 280 | clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; |
281 | clock-names = "saradc", "apb_pclk"; | 281 | clock-names = "saradc", "apb_pclk"; |
282 | resets = <&cru SRST_SARADC>; | ||
283 | reset-names = "saradc-apb"; | ||
282 | status = "disabled"; | 284 | status = "disabled"; |
283 | }; | 285 | }; |
284 | 286 | ||
diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi index 99bbcc2c9b89..e2cd683b4e4b 100644 --- a/arch/arm/boot/dts/rk3xxx.dtsi +++ b/arch/arm/boot/dts/rk3xxx.dtsi | |||
@@ -399,6 +399,8 @@ | |||
399 | #io-channel-cells = <1>; | 399 | #io-channel-cells = <1>; |
400 | clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; | 400 | clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; |
401 | clock-names = "saradc", "apb_pclk"; | 401 | clock-names = "saradc", "apb_pclk"; |
402 | resets = <&cru SRST_SARADC>; | ||
403 | reset-names = "saradc-apb"; | ||
402 | status = "disabled"; | 404 | status = "disabled"; |
403 | }; | 405 | }; |
404 | 406 | ||
diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi index d294e82447a2..8b063ab10c19 100644 --- a/arch/arm/boot/dts/stih407-family.dtsi +++ b/arch/arm/boot/dts/stih407-family.dtsi | |||
@@ -550,8 +550,9 @@ | |||
550 | interrupt-names = "mmcirq"; | 550 | interrupt-names = "mmcirq"; |
551 | pinctrl-names = "default"; | 551 | pinctrl-names = "default"; |
552 | pinctrl-0 = <&pinctrl_mmc0>; | 552 | pinctrl-0 = <&pinctrl_mmc0>; |
553 | clock-names = "mmc"; | 553 | clock-names = "mmc", "icn"; |
554 | clocks = <&clk_s_c0_flexgen CLK_MMC_0>; | 554 | clocks = <&clk_s_c0_flexgen CLK_MMC_0>, |
555 | <&clk_s_c0_flexgen CLK_RX_ICN_HVA>; | ||
555 | bus-width = <8>; | 556 | bus-width = <8>; |
556 | non-removable; | 557 | non-removable; |
557 | }; | 558 | }; |
@@ -565,8 +566,9 @@ | |||
565 | interrupt-names = "mmcirq"; | 566 | interrupt-names = "mmcirq"; |
566 | pinctrl-names = "default"; | 567 | pinctrl-names = "default"; |
567 | pinctrl-0 = <&pinctrl_sd1>; | 568 | pinctrl-0 = <&pinctrl_sd1>; |
568 | clock-names = "mmc"; | 569 | clock-names = "mmc", "icn"; |
569 | clocks = <&clk_s_c0_flexgen CLK_MMC_1>; | 570 | clocks = <&clk_s_c0_flexgen CLK_MMC_1>, |
571 | <&clk_s_c0_flexgen CLK_RX_ICN_HVA>; | ||
570 | resets = <&softreset STIH407_MMC1_SOFTRESET>; | 572 | resets = <&softreset STIH407_MMC1_SOFTRESET>; |
571 | bus-width = <4>; | 573 | bus-width = <4>; |
572 | }; | 574 | }; |
diff --git a/arch/arm/boot/dts/stih410.dtsi b/arch/arm/boot/dts/stih410.dtsi index 18ed1ad10d32..40318869c733 100644 --- a/arch/arm/boot/dts/stih410.dtsi +++ b/arch/arm/boot/dts/stih410.dtsi | |||
@@ -41,7 +41,8 @@ | |||
41 | compatible = "st,st-ohci-300x"; | 41 | compatible = "st,st-ohci-300x"; |
42 | reg = <0x9a03c00 0x100>; | 42 | reg = <0x9a03c00 0x100>; |
43 | interrupts = <GIC_SPI 180 IRQ_TYPE_NONE>; | 43 | interrupts = <GIC_SPI 180 IRQ_TYPE_NONE>; |
44 | clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>; | 44 | clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>, |
45 | <&clk_s_c0_flexgen CLK_RX_ICN_DISP_0>; | ||
45 | resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>, | 46 | resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>, |
46 | <&softreset STIH407_USB2_PORT0_SOFTRESET>; | 47 | <&softreset STIH407_USB2_PORT0_SOFTRESET>; |
47 | reset-names = "power", "softreset"; | 48 | reset-names = "power", "softreset"; |
@@ -57,7 +58,8 @@ | |||
57 | interrupts = <GIC_SPI 151 IRQ_TYPE_NONE>; | 58 | interrupts = <GIC_SPI 151 IRQ_TYPE_NONE>; |
58 | pinctrl-names = "default"; | 59 | pinctrl-names = "default"; |
59 | pinctrl-0 = <&pinctrl_usb0>; | 60 | pinctrl-0 = <&pinctrl_usb0>; |
60 | clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>; | 61 | clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>, |
62 | <&clk_s_c0_flexgen CLK_RX_ICN_DISP_0>; | ||
61 | resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>, | 63 | resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>, |
62 | <&softreset STIH407_USB2_PORT0_SOFTRESET>; | 64 | <&softreset STIH407_USB2_PORT0_SOFTRESET>; |
63 | reset-names = "power", "softreset"; | 65 | reset-names = "power", "softreset"; |
@@ -71,7 +73,8 @@ | |||
71 | compatible = "st,st-ohci-300x"; | 73 | compatible = "st,st-ohci-300x"; |
72 | reg = <0x9a83c00 0x100>; | 74 | reg = <0x9a83c00 0x100>; |
73 | interrupts = <GIC_SPI 181 IRQ_TYPE_NONE>; | 75 | interrupts = <GIC_SPI 181 IRQ_TYPE_NONE>; |
74 | clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>; | 76 | clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>, |
77 | <&clk_s_c0_flexgen CLK_RX_ICN_DISP_0>; | ||
75 | resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>, | 78 | resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>, |
76 | <&softreset STIH407_USB2_PORT1_SOFTRESET>; | 79 | <&softreset STIH407_USB2_PORT1_SOFTRESET>; |
77 | reset-names = "power", "softreset"; | 80 | reset-names = "power", "softreset"; |
@@ -87,7 +90,8 @@ | |||
87 | interrupts = <GIC_SPI 153 IRQ_TYPE_NONE>; | 90 | interrupts = <GIC_SPI 153 IRQ_TYPE_NONE>; |
88 | pinctrl-names = "default"; | 91 | pinctrl-names = "default"; |
89 | pinctrl-0 = <&pinctrl_usb1>; | 92 | pinctrl-0 = <&pinctrl_usb1>; |
90 | clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>; | 93 | clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>, |
94 | <&clk_s_c0_flexgen CLK_RX_ICN_DISP_0>; | ||
91 | resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>, | 95 | resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>, |
92 | <&softreset STIH407_USB2_PORT1_SOFTRESET>; | 96 | <&softreset STIH407_USB2_PORT1_SOFTRESET>; |
93 | reset-names = "power", "softreset"; | 97 | reset-names = "power", "softreset"; |
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi index e012890e0cf2..a17ba0243db3 100644 --- a/arch/arm/boot/dts/sun5i-a13.dtsi +++ b/arch/arm/boot/dts/sun5i-a13.dtsi | |||
@@ -84,7 +84,7 @@ | |||
84 | trips { | 84 | trips { |
85 | cpu_alert0: cpu_alert0 { | 85 | cpu_alert0: cpu_alert0 { |
86 | /* milliCelsius */ | 86 | /* milliCelsius */ |
87 | temperature = <850000>; | 87 | temperature = <85000>; |
88 | hysteresis = <2000>; | 88 | hysteresis = <2000>; |
89 | type = "passive"; | 89 | type = "passive"; |
90 | }; | 90 | }; |
diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts b/arch/arm/boot/dts/tegra114-dalmore.dts index 1dfc492cc004..1444fbd543e7 100644 --- a/arch/arm/boot/dts/tegra114-dalmore.dts +++ b/arch/arm/boot/dts/tegra114-dalmore.dts | |||
@@ -897,7 +897,7 @@ | |||
897 | palmas: tps65913@58 { | 897 | palmas: tps65913@58 { |
898 | compatible = "ti,palmas"; | 898 | compatible = "ti,palmas"; |
899 | reg = <0x58>; | 899 | reg = <0x58>; |
900 | interrupts = <0 86 IRQ_TYPE_LEVEL_LOW>; | 900 | interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>; |
901 | 901 | ||
902 | #interrupt-cells = <2>; | 902 | #interrupt-cells = <2>; |
903 | interrupt-controller; | 903 | interrupt-controller; |
diff --git a/arch/arm/boot/dts/tegra114-roth.dts b/arch/arm/boot/dts/tegra114-roth.dts index 70cf40996c3f..966a7fc044af 100644 --- a/arch/arm/boot/dts/tegra114-roth.dts +++ b/arch/arm/boot/dts/tegra114-roth.dts | |||
@@ -802,7 +802,7 @@ | |||
802 | palmas: pmic@58 { | 802 | palmas: pmic@58 { |
803 | compatible = "ti,palmas"; | 803 | compatible = "ti,palmas"; |
804 | reg = <0x58>; | 804 | reg = <0x58>; |
805 | interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_LOW>; | 805 | interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; |
806 | 806 | ||
807 | #interrupt-cells = <2>; | 807 | #interrupt-cells = <2>; |
808 | interrupt-controller; | 808 | interrupt-controller; |
diff --git a/arch/arm/boot/dts/tegra114-tn7.dts b/arch/arm/boot/dts/tegra114-tn7.dts index 17dd14545862..a161fa1dfb61 100644 --- a/arch/arm/boot/dts/tegra114-tn7.dts +++ b/arch/arm/boot/dts/tegra114-tn7.dts | |||
@@ -63,7 +63,7 @@ | |||
63 | palmas: pmic@58 { | 63 | palmas: pmic@58 { |
64 | compatible = "ti,palmas"; | 64 | compatible = "ti,palmas"; |
65 | reg = <0x58>; | 65 | reg = <0x58>; |
66 | interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_LOW>; | 66 | interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; |
67 | 67 | ||
68 | #interrupt-cells = <2>; | 68 | #interrupt-cells = <2>; |
69 | interrupt-controller; | 69 | interrupt-controller; |
diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1.dts b/arch/arm/boot/dts/tegra124-jetson-tk1.dts index 6403e0de540e..e52b82449a79 100644 --- a/arch/arm/boot/dts/tegra124-jetson-tk1.dts +++ b/arch/arm/boot/dts/tegra124-jetson-tk1.dts | |||
@@ -1382,7 +1382,7 @@ | |||
1382 | * Pin 41: BR_UART1_TXD | 1382 | * Pin 41: BR_UART1_TXD |
1383 | * Pin 44: BR_UART1_RXD | 1383 | * Pin 44: BR_UART1_RXD |
1384 | */ | 1384 | */ |
1385 | serial@0,70006000 { | 1385 | serial@70006000 { |
1386 | compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart"; | 1386 | compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart"; |
1387 | status = "okay"; | 1387 | status = "okay"; |
1388 | }; | 1388 | }; |
@@ -1394,7 +1394,7 @@ | |||
1394 | * Pin 71: UART2_CTS_L | 1394 | * Pin 71: UART2_CTS_L |
1395 | * Pin 74: UART2_RTS_L | 1395 | * Pin 74: UART2_RTS_L |
1396 | */ | 1396 | */ |
1397 | serial@0,70006040 { | 1397 | serial@70006040 { |
1398 | compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart"; | 1398 | compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart"; |
1399 | status = "okay"; | 1399 | status = "okay"; |
1400 | }; | 1400 | }; |
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 0e97b4b871f9..6c7b06854fce 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c | |||
@@ -140,7 +140,7 @@ static struct locomo_dev_info locomo_devices[] = { | |||
140 | 140 | ||
141 | static void locomo_handler(struct irq_desc *desc) | 141 | static void locomo_handler(struct irq_desc *desc) |
142 | { | 142 | { |
143 | struct locomo *lchip = irq_desc_get_chip_data(desc); | 143 | struct locomo *lchip = irq_desc_get_handler_data(desc); |
144 | int req, i; | 144 | int req, i; |
145 | 145 | ||
146 | /* Acknowledge the parent IRQ */ | 146 | /* Acknowledge the parent IRQ */ |
@@ -200,8 +200,7 @@ static void locomo_setup_irq(struct locomo *lchip) | |||
200 | * Install handler for IRQ_LOCOMO_HW. | 200 | * Install handler for IRQ_LOCOMO_HW. |
201 | */ | 201 | */ |
202 | irq_set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING); | 202 | irq_set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING); |
203 | irq_set_chip_data(lchip->irq, lchip); | 203 | irq_set_chained_handler_and_data(lchip->irq, locomo_handler, lchip); |
204 | irq_set_chained_handler(lchip->irq, locomo_handler); | ||
205 | 204 | ||
206 | /* Install handlers for IRQ_LOCOMO_* */ | 205 | /* Install handlers for IRQ_LOCOMO_* */ |
207 | for ( ; irq <= lchip->irq_base + 3; irq++) { | 206 | for ( ; irq <= lchip->irq_base + 3; irq++) { |
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index fb0a0a4dfea4..2e076c492005 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c | |||
@@ -472,8 +472,8 @@ static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base) | |||
472 | * specifies that S0ReadyInt and S1ReadyInt should be '1'. | 472 | * specifies that S0ReadyInt and S1ReadyInt should be '1'. |
473 | */ | 473 | */ |
474 | sa1111_writel(0, irqbase + SA1111_INTPOL0); | 474 | sa1111_writel(0, irqbase + SA1111_INTPOL0); |
475 | sa1111_writel(SA1111_IRQMASK_HI(IRQ_S0_READY_NINT) | | 475 | sa1111_writel(BIT(IRQ_S0_READY_NINT & 31) | |
476 | SA1111_IRQMASK_HI(IRQ_S1_READY_NINT), | 476 | BIT(IRQ_S1_READY_NINT & 31), |
477 | irqbase + SA1111_INTPOL1); | 477 | irqbase + SA1111_INTPOL1); |
478 | 478 | ||
479 | /* clear all IRQs */ | 479 | /* clear all IRQs */ |
@@ -754,7 +754,7 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq) | |||
754 | if (sachip->irq != NO_IRQ) { | 754 | if (sachip->irq != NO_IRQ) { |
755 | ret = sa1111_setup_irq(sachip, pd->irq_base); | 755 | ret = sa1111_setup_irq(sachip, pd->irq_base); |
756 | if (ret) | 756 | if (ret) |
757 | goto err_unmap; | 757 | goto err_clk; |
758 | } | 758 | } |
759 | 759 | ||
760 | #ifdef CONFIG_ARCH_SA1100 | 760 | #ifdef CONFIG_ARCH_SA1100 |
@@ -799,6 +799,8 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq) | |||
799 | 799 | ||
800 | return 0; | 800 | return 0; |
801 | 801 | ||
802 | err_clk: | ||
803 | clk_disable(sachip->clk); | ||
802 | err_unmap: | 804 | err_unmap: |
803 | iounmap(sachip->base); | 805 | iounmap(sachip->base); |
804 | err_clk_unprep: | 806 | err_clk_unprep: |
@@ -869,9 +871,9 @@ struct sa1111_save_data { | |||
869 | 871 | ||
870 | #ifdef CONFIG_PM | 872 | #ifdef CONFIG_PM |
871 | 873 | ||
872 | static int sa1111_suspend(struct platform_device *dev, pm_message_t state) | 874 | static int sa1111_suspend_noirq(struct device *dev) |
873 | { | 875 | { |
874 | struct sa1111 *sachip = platform_get_drvdata(dev); | 876 | struct sa1111 *sachip = dev_get_drvdata(dev); |
875 | struct sa1111_save_data *save; | 877 | struct sa1111_save_data *save; |
876 | unsigned long flags; | 878 | unsigned long flags; |
877 | unsigned int val; | 879 | unsigned int val; |
@@ -934,9 +936,9 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state) | |||
934 | * restored by their respective drivers, and must be called | 936 | * restored by their respective drivers, and must be called |
935 | * via LDM after this function. | 937 | * via LDM after this function. |
936 | */ | 938 | */ |
937 | static int sa1111_resume(struct platform_device *dev) | 939 | static int sa1111_resume_noirq(struct device *dev) |
938 | { | 940 | { |
939 | struct sa1111 *sachip = platform_get_drvdata(dev); | 941 | struct sa1111 *sachip = dev_get_drvdata(dev); |
940 | struct sa1111_save_data *save; | 942 | struct sa1111_save_data *save; |
941 | unsigned long flags, id; | 943 | unsigned long flags, id; |
942 | void __iomem *base; | 944 | void __iomem *base; |
@@ -952,7 +954,7 @@ static int sa1111_resume(struct platform_device *dev) | |||
952 | id = sa1111_readl(sachip->base + SA1111_SKID); | 954 | id = sa1111_readl(sachip->base + SA1111_SKID); |
953 | if ((id & SKID_ID_MASK) != SKID_SA1111_ID) { | 955 | if ((id & SKID_ID_MASK) != SKID_SA1111_ID) { |
954 | __sa1111_remove(sachip); | 956 | __sa1111_remove(sachip); |
955 | platform_set_drvdata(dev, NULL); | 957 | dev_set_drvdata(dev, NULL); |
956 | kfree(save); | 958 | kfree(save); |
957 | return 0; | 959 | return 0; |
958 | } | 960 | } |
@@ -1003,8 +1005,8 @@ static int sa1111_resume(struct platform_device *dev) | |||
1003 | } | 1005 | } |
1004 | 1006 | ||
1005 | #else | 1007 | #else |
1006 | #define sa1111_suspend NULL | 1008 | #define sa1111_suspend_noirq NULL |
1007 | #define sa1111_resume NULL | 1009 | #define sa1111_resume_noirq NULL |
1008 | #endif | 1010 | #endif |
1009 | 1011 | ||
1010 | static int sa1111_probe(struct platform_device *pdev) | 1012 | static int sa1111_probe(struct platform_device *pdev) |
@@ -1017,7 +1019,7 @@ static int sa1111_probe(struct platform_device *pdev) | |||
1017 | return -EINVAL; | 1019 | return -EINVAL; |
1018 | irq = platform_get_irq(pdev, 0); | 1020 | irq = platform_get_irq(pdev, 0); |
1019 | if (irq < 0) | 1021 | if (irq < 0) |
1020 | return -ENXIO; | 1022 | return irq; |
1021 | 1023 | ||
1022 | return __sa1111_probe(&pdev->dev, mem, irq); | 1024 | return __sa1111_probe(&pdev->dev, mem, irq); |
1023 | } | 1025 | } |
@@ -1038,6 +1040,11 @@ static int sa1111_remove(struct platform_device *pdev) | |||
1038 | return 0; | 1040 | return 0; |
1039 | } | 1041 | } |
1040 | 1042 | ||
1043 | static struct dev_pm_ops sa1111_pm_ops = { | ||
1044 | .suspend_noirq = sa1111_suspend_noirq, | ||
1045 | .resume_noirq = sa1111_resume_noirq, | ||
1046 | }; | ||
1047 | |||
1041 | /* | 1048 | /* |
1042 | * Not sure if this should be on the system bus or not yet. | 1049 | * Not sure if this should be on the system bus or not yet. |
1043 | * We really want some way to register a system device at | 1050 | * We really want some way to register a system device at |
@@ -1050,10 +1057,9 @@ static int sa1111_remove(struct platform_device *pdev) | |||
1050 | static struct platform_driver sa1111_device_driver = { | 1057 | static struct platform_driver sa1111_device_driver = { |
1051 | .probe = sa1111_probe, | 1058 | .probe = sa1111_probe, |
1052 | .remove = sa1111_remove, | 1059 | .remove = sa1111_remove, |
1053 | .suspend = sa1111_suspend, | ||
1054 | .resume = sa1111_resume, | ||
1055 | .driver = { | 1060 | .driver = { |
1056 | .name = "sa1111", | 1061 | .name = "sa1111", |
1062 | .pm = &sa1111_pm_ops, | ||
1057 | }, | 1063 | }, |
1058 | }; | 1064 | }; |
1059 | 1065 | ||
diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig index 71b42e66488a..78cd2f197e01 100644 --- a/arch/arm/configs/keystone_defconfig +++ b/arch/arm/configs/keystone_defconfig | |||
@@ -161,6 +161,7 @@ CONFIG_USB_MON=y | |||
161 | CONFIG_USB_XHCI_HCD=y | 161 | CONFIG_USB_XHCI_HCD=y |
162 | CONFIG_USB_STORAGE=y | 162 | CONFIG_USB_STORAGE=y |
163 | CONFIG_USB_DWC3=y | 163 | CONFIG_USB_DWC3=y |
164 | CONFIG_NOP_USB_XCEIV=y | ||
164 | CONFIG_KEYSTONE_USB_PHY=y | 165 | CONFIG_KEYSTONE_USB_PHY=y |
165 | CONFIG_NEW_LEDS=y | 166 | CONFIG_NEW_LEDS=y |
166 | CONFIG_LEDS_CLASS=y | 167 | CONFIG_LEDS_CLASS=y |
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 2c8665cd9dc5..ea3566fb92e2 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig | |||
@@ -781,7 +781,7 @@ CONFIG_MXS_DMA=y | |||
781 | CONFIG_DMA_BCM2835=y | 781 | CONFIG_DMA_BCM2835=y |
782 | CONFIG_DMA_OMAP=y | 782 | CONFIG_DMA_OMAP=y |
783 | CONFIG_QCOM_BAM_DMA=y | 783 | CONFIG_QCOM_BAM_DMA=y |
784 | CONFIG_XILINX_VDMA=y | 784 | CONFIG_XILINX_DMA=y |
785 | CONFIG_DMA_SUN6I=y | 785 | CONFIG_DMA_SUN6I=y |
786 | CONFIG_STAGING=y | 786 | CONFIG_STAGING=y |
787 | CONFIG_SENSORS_ISL29018=y | 787 | CONFIG_SENSORS_ISL29018=y |
diff --git a/arch/arm/crypto/aes-ce-glue.c b/arch/arm/crypto/aes-ce-glue.c index da3c0428507b..aef022a87c53 100644 --- a/arch/arm/crypto/aes-ce-glue.c +++ b/arch/arm/crypto/aes-ce-glue.c | |||
@@ -284,7 +284,7 @@ static int ctr_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | |||
284 | err = blkcipher_walk_done(desc, &walk, | 284 | err = blkcipher_walk_done(desc, &walk, |
285 | walk.nbytes % AES_BLOCK_SIZE); | 285 | walk.nbytes % AES_BLOCK_SIZE); |
286 | } | 286 | } |
287 | if (nbytes) { | 287 | if (walk.nbytes % AES_BLOCK_SIZE) { |
288 | u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE; | 288 | u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE; |
289 | u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE; | 289 | u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE; |
290 | u8 __aligned(8) tail[AES_BLOCK_SIZE]; | 290 | u8 __aligned(8) tail[AES_BLOCK_SIZE]; |
diff --git a/arch/arm/include/asm/pgtable-2level-hwdef.h b/arch/arm/include/asm/pgtable-2level-hwdef.h index d0131ee6f6af..3f82e9da7cec 100644 --- a/arch/arm/include/asm/pgtable-2level-hwdef.h +++ b/arch/arm/include/asm/pgtable-2level-hwdef.h | |||
@@ -47,6 +47,7 @@ | |||
47 | #define PMD_SECT_WB (PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE) | 47 | #define PMD_SECT_WB (PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE) |
48 | #define PMD_SECT_MINICACHE (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE) | 48 | #define PMD_SECT_MINICACHE (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE) |
49 | #define PMD_SECT_WBWA (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE) | 49 | #define PMD_SECT_WBWA (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE) |
50 | #define PMD_SECT_CACHE_MASK (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE) | ||
50 | #define PMD_SECT_NONSHARED_DEV (PMD_SECT_TEX(2)) | 51 | #define PMD_SECT_NONSHARED_DEV (PMD_SECT_TEX(2)) |
51 | 52 | ||
52 | /* | 53 | /* |
diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h index f8f1cff62065..4cd664abfcd3 100644 --- a/arch/arm/include/asm/pgtable-3level-hwdef.h +++ b/arch/arm/include/asm/pgtable-3level-hwdef.h | |||
@@ -62,6 +62,7 @@ | |||
62 | #define PMD_SECT_WT (_AT(pmdval_t, 2) << 2) /* normal inner write-through */ | 62 | #define PMD_SECT_WT (_AT(pmdval_t, 2) << 2) /* normal inner write-through */ |
63 | #define PMD_SECT_WB (_AT(pmdval_t, 3) << 2) /* normal inner write-back */ | 63 | #define PMD_SECT_WB (_AT(pmdval_t, 3) << 2) /* normal inner write-back */ |
64 | #define PMD_SECT_WBWA (_AT(pmdval_t, 7) << 2) /* normal inner write-alloc */ | 64 | #define PMD_SECT_WBWA (_AT(pmdval_t, 7) << 2) /* normal inner write-alloc */ |
65 | #define PMD_SECT_CACHE_MASK (_AT(pmdval_t, 7) << 2) | ||
65 | 66 | ||
66 | /* | 67 | /* |
67 | * + Level 3 descriptor (PTE) | 68 | * + Level 3 descriptor (PTE) |
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S index 0b1e4a93d67e..15d073ae5da2 100644 --- a/arch/arm/kernel/hyp-stub.S +++ b/arch/arm/kernel/hyp-stub.S | |||
@@ -142,6 +142,19 @@ ARM_BE8(orr r7, r7, #(1 << 25)) @ HSCTLR.EE | |||
142 | and r7, #0x1f @ Preserve HPMN | 142 | and r7, #0x1f @ Preserve HPMN |
143 | mcr p15, 4, r7, c1, c1, 1 @ HDCR | 143 | mcr p15, 4, r7, c1, c1, 1 @ HDCR |
144 | 144 | ||
145 | @ Make sure NS-SVC is initialised appropriately | ||
146 | mrc p15, 0, r7, c1, c0, 0 @ SCTLR | ||
147 | orr r7, #(1 << 5) @ CP15 barriers enabled | ||
148 | bic r7, #(3 << 7) @ Clear SED/ITD for v8 (RES0 for v7) | ||
149 | bic r7, #(3 << 19) @ WXN and UWXN disabled | ||
150 | mcr p15, 0, r7, c1, c0, 0 @ SCTLR | ||
151 | |||
152 | mrc p15, 0, r7, c0, c0, 0 @ MIDR | ||
153 | mcr p15, 4, r7, c0, c0, 0 @ VPIDR | ||
154 | |||
155 | mrc p15, 0, r7, c0, c0, 5 @ MPIDR | ||
156 | mcr p15, 4, r7, c0, c0, 5 @ VMPIDR | ||
157 | |||
145 | #if !defined(ZIMAGE) && defined(CONFIG_ARM_ARCH_TIMER) | 158 | #if !defined(ZIMAGE) && defined(CONFIG_ARM_ARCH_TIMER) |
146 | @ make CNTP_* and CNTPCT accessible from PL1 | 159 | @ make CNTP_* and CNTPCT accessible from PL1 |
147 | mrc p15, 0, r7, c0, c1, 1 @ ID_PFR1 | 160 | mrc p15, 0, r7, c0, c1, 1 @ ID_PFR1 |
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 75f130ef6504..c94b90d43772 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c | |||
@@ -158,8 +158,6 @@ void kvm_arch_destroy_vm(struct kvm *kvm) | |||
158 | { | 158 | { |
159 | int i; | 159 | int i; |
160 | 160 | ||
161 | kvm_free_stage2_pgd(kvm); | ||
162 | |||
163 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { | 161 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { |
164 | if (kvm->vcpus[i]) { | 162 | if (kvm->vcpus[i]) { |
165 | kvm_arch_vcpu_free(kvm->vcpus[i]); | 163 | kvm_arch_vcpu_free(kvm->vcpus[i]); |
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index bda27b6b1aa2..e9a5c0e0c115 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c | |||
@@ -1309,7 +1309,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
1309 | smp_rmb(); | 1309 | smp_rmb(); |
1310 | 1310 | ||
1311 | pfn = gfn_to_pfn_prot(kvm, gfn, write_fault, &writable); | 1311 | pfn = gfn_to_pfn_prot(kvm, gfn, write_fault, &writable); |
1312 | if (is_error_pfn(pfn)) | 1312 | if (is_error_noslot_pfn(pfn)) |
1313 | return -EFAULT; | 1313 | return -EFAULT; |
1314 | 1314 | ||
1315 | if (kvm_is_device_pfn(pfn)) { | 1315 | if (kvm_is_device_pfn(pfn)) { |
@@ -1714,7 +1714,8 @@ int kvm_mmu_init(void) | |||
1714 | kern_hyp_va(PAGE_OFFSET), kern_hyp_va(~0UL)); | 1714 | kern_hyp_va(PAGE_OFFSET), kern_hyp_va(~0UL)); |
1715 | 1715 | ||
1716 | if (hyp_idmap_start >= kern_hyp_va(PAGE_OFFSET) && | 1716 | if (hyp_idmap_start >= kern_hyp_va(PAGE_OFFSET) && |
1717 | hyp_idmap_start < kern_hyp_va(~0UL)) { | 1717 | hyp_idmap_start < kern_hyp_va(~0UL) && |
1718 | hyp_idmap_start != (unsigned long)__hyp_idmap_text_start) { | ||
1718 | /* | 1719 | /* |
1719 | * The idmap page is intersecting with the VA space, | 1720 | * The idmap page is intersecting with the VA space, |
1720 | * it is not safe to continue further. | 1721 | * it is not safe to continue further. |
@@ -1893,6 +1894,7 @@ void kvm_arch_memslots_updated(struct kvm *kvm, struct kvm_memslots *slots) | |||
1893 | 1894 | ||
1894 | void kvm_arch_flush_shadow_all(struct kvm *kvm) | 1895 | void kvm_arch_flush_shadow_all(struct kvm *kvm) |
1895 | { | 1896 | { |
1897 | kvm_free_stage2_pgd(kvm); | ||
1896 | } | 1898 | } |
1897 | 1899 | ||
1898 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, | 1900 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, |
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index 3750575c73c5..06332f626565 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c | |||
@@ -255,6 +255,12 @@ static int __init exynos_pmu_irq_init(struct device_node *node, | |||
255 | return -ENOMEM; | 255 | return -ENOMEM; |
256 | } | 256 | } |
257 | 257 | ||
258 | /* | ||
259 | * Clear the OF_POPULATED flag set in of_irq_init so that | ||
260 | * later the Exynos PMU platform device won't be skipped. | ||
261 | */ | ||
262 | of_node_clear_flag(node, OF_POPULATED); | ||
263 | |||
258 | return 0; | 264 | return 0; |
259 | } | 265 | } |
260 | 266 | ||
diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c index 5d9bfab279dd..6bb7d9cf1e38 100644 --- a/arch/arm/mach-imx/mach-imx6ul.c +++ b/arch/arm/mach-imx/mach-imx6ul.c | |||
@@ -64,6 +64,7 @@ static void __init imx6ul_init_machine(void) | |||
64 | if (parent == NULL) | 64 | if (parent == NULL) |
65 | pr_warn("failed to initialize soc device\n"); | 65 | pr_warn("failed to initialize soc device\n"); |
66 | 66 | ||
67 | of_platform_default_populate(NULL, NULL, parent); | ||
67 | imx6ul_enet_init(); | 68 | imx6ul_enet_init(); |
68 | imx_anatop_init(); | 69 | imx_anatop_init(); |
69 | imx6ul_pm_init(); | 70 | imx6ul_pm_init(); |
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index 58924b3844df..fe708e26d021 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c | |||
@@ -295,7 +295,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode) | |||
295 | val &= ~BM_CLPCR_SBYOS; | 295 | val &= ~BM_CLPCR_SBYOS; |
296 | if (cpu_is_imx6sl()) | 296 | if (cpu_is_imx6sl()) |
297 | val |= BM_CLPCR_BYPASS_PMIC_READY; | 297 | val |= BM_CLPCR_BYPASS_PMIC_READY; |
298 | if (cpu_is_imx6sl() || cpu_is_imx6sx()) | 298 | if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul()) |
299 | val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS; | 299 | val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS; |
300 | else | 300 | else |
301 | val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; | 301 | val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; |
@@ -310,7 +310,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode) | |||
310 | val |= 0x3 << BP_CLPCR_STBY_COUNT; | 310 | val |= 0x3 << BP_CLPCR_STBY_COUNT; |
311 | val |= BM_CLPCR_VSTBY; | 311 | val |= BM_CLPCR_VSTBY; |
312 | val |= BM_CLPCR_SBYOS; | 312 | val |= BM_CLPCR_SBYOS; |
313 | if (cpu_is_imx6sl()) | 313 | if (cpu_is_imx6sl() || cpu_is_imx6sx()) |
314 | val |= BM_CLPCR_BYPASS_PMIC_READY; | 314 | val |= BM_CLPCR_BYPASS_PMIC_READY; |
315 | if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul()) | 315 | if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul()) |
316 | val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS; | 316 | val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS; |
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c index c073fb57dd13..6f2d0aec0513 100644 --- a/arch/arm/mach-omap2/cm33xx.c +++ b/arch/arm/mach-omap2/cm33xx.c | |||
@@ -220,9 +220,6 @@ static int am33xx_cm_wait_module_ready(u8 part, s16 inst, u16 clkctrl_offs, | |||
220 | { | 220 | { |
221 | int i = 0; | 221 | int i = 0; |
222 | 222 | ||
223 | if (!clkctrl_offs) | ||
224 | return 0; | ||
225 | |||
226 | omap_test_timeout(_is_module_ready(inst, clkctrl_offs), | 223 | omap_test_timeout(_is_module_ready(inst, clkctrl_offs), |
227 | MAX_MODULE_READY_TIME, i); | 224 | MAX_MODULE_READY_TIME, i); |
228 | 225 | ||
@@ -246,9 +243,6 @@ static int am33xx_cm_wait_module_idle(u8 part, s16 inst, u16 clkctrl_offs, | |||
246 | { | 243 | { |
247 | int i = 0; | 244 | int i = 0; |
248 | 245 | ||
249 | if (!clkctrl_offs) | ||
250 | return 0; | ||
251 | |||
252 | omap_test_timeout((_clkctrl_idlest(inst, clkctrl_offs) == | 246 | omap_test_timeout((_clkctrl_idlest(inst, clkctrl_offs) == |
253 | CLKCTRL_IDLEST_DISABLED), | 247 | CLKCTRL_IDLEST_DISABLED), |
254 | MAX_MODULE_READY_TIME, i); | 248 | MAX_MODULE_READY_TIME, i); |
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index 2c0e07ed6b99..2ab27ade136a 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c | |||
@@ -278,9 +278,6 @@ static int omap4_cminst_wait_module_ready(u8 part, s16 inst, u16 clkctrl_offs, | |||
278 | { | 278 | { |
279 | int i = 0; | 279 | int i = 0; |
280 | 280 | ||
281 | if (!clkctrl_offs) | ||
282 | return 0; | ||
283 | |||
284 | omap_test_timeout(_is_module_ready(part, inst, clkctrl_offs), | 281 | omap_test_timeout(_is_module_ready(part, inst, clkctrl_offs), |
285 | MAX_MODULE_READY_TIME, i); | 282 | MAX_MODULE_READY_TIME, i); |
286 | 283 | ||
@@ -304,9 +301,6 @@ static int omap4_cminst_wait_module_idle(u8 part, s16 inst, u16 clkctrl_offs, | |||
304 | { | 301 | { |
305 | int i = 0; | 302 | int i = 0; |
306 | 303 | ||
307 | if (!clkctrl_offs) | ||
308 | return 0; | ||
309 | |||
310 | omap_test_timeout((_clkctrl_idlest(part, inst, clkctrl_offs) == | 304 | omap_test_timeout((_clkctrl_idlest(part, inst, clkctrl_offs) == |
311 | CLKCTRL_IDLEST_DISABLED), | 305 | CLKCTRL_IDLEST_DISABLED), |
312 | MAX_MODULE_DISABLE_TIME, i); | 306 | MAX_MODULE_DISABLE_TIME, i); |
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 5b709383381c..1052b29697b8 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -1053,6 +1053,10 @@ static int _omap4_wait_target_disable(struct omap_hwmod *oh) | |||
1053 | if (oh->flags & HWMOD_NO_IDLEST) | 1053 | if (oh->flags & HWMOD_NO_IDLEST) |
1054 | return 0; | 1054 | return 0; |
1055 | 1055 | ||
1056 | if (!oh->prcm.omap4.clkctrl_offs && | ||
1057 | !(oh->prcm.omap4.flags & HWMOD_OMAP4_ZERO_CLKCTRL_OFFSET)) | ||
1058 | return 0; | ||
1059 | |||
1056 | return omap_cm_wait_module_idle(oh->clkdm->prcm_partition, | 1060 | return omap_cm_wait_module_idle(oh->clkdm->prcm_partition, |
1057 | oh->clkdm->cm_inst, | 1061 | oh->clkdm->cm_inst, |
1058 | oh->prcm.omap4.clkctrl_offs, 0); | 1062 | oh->prcm.omap4.clkctrl_offs, 0); |
@@ -2971,6 +2975,10 @@ static int _omap4_wait_target_ready(struct omap_hwmod *oh) | |||
2971 | if (!_find_mpu_rt_port(oh)) | 2975 | if (!_find_mpu_rt_port(oh)) |
2972 | return 0; | 2976 | return 0; |
2973 | 2977 | ||
2978 | if (!oh->prcm.omap4.clkctrl_offs && | ||
2979 | !(oh->prcm.omap4.flags & HWMOD_OMAP4_ZERO_CLKCTRL_OFFSET)) | ||
2980 | return 0; | ||
2981 | |||
2974 | /* XXX check module SIDLEMODE, hardreset status */ | 2982 | /* XXX check module SIDLEMODE, hardreset status */ |
2975 | 2983 | ||
2976 | return omap_cm_wait_module_ready(oh->clkdm->prcm_partition, | 2984 | return omap_cm_wait_module_ready(oh->clkdm->prcm_partition, |
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index 4041bad79a9a..78904017f18c 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h | |||
@@ -443,8 +443,12 @@ struct omap_hwmod_omap2_prcm { | |||
443 | * HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT: Some IP blocks don't have a PRCM | 443 | * HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT: Some IP blocks don't have a PRCM |
444 | * module-level context loss register associated with them; this | 444 | * module-level context loss register associated with them; this |
445 | * flag bit should be set in those cases | 445 | * flag bit should be set in those cases |
446 | * HWMOD_OMAP4_ZERO_CLKCTRL_OFFSET: Some IP blocks have a valid CLKCTRL | ||
447 | * offset of zero; this flag bit should be set in those cases to | ||
448 | * distinguish from hwmods that have no clkctrl offset. | ||
446 | */ | 449 | */ |
447 | #define HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT (1 << 0) | 450 | #define HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT (1 << 0) |
451 | #define HWMOD_OMAP4_ZERO_CLKCTRL_OFFSET (1 << 1) | ||
448 | 452 | ||
449 | /** | 453 | /** |
450 | * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data | 454 | * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data |
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c index 55c5878577f4..e2d84aa7f595 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #define CLKCTRL(oh, clkctrl) ((oh).prcm.omap4.clkctrl_offs = (clkctrl)) | 29 | #define CLKCTRL(oh, clkctrl) ((oh).prcm.omap4.clkctrl_offs = (clkctrl)) |
30 | #define RSTCTRL(oh, rstctrl) ((oh).prcm.omap4.rstctrl_offs = (rstctrl)) | 30 | #define RSTCTRL(oh, rstctrl) ((oh).prcm.omap4.rstctrl_offs = (rstctrl)) |
31 | #define RSTST(oh, rstst) ((oh).prcm.omap4.rstst_offs = (rstst)) | 31 | #define RSTST(oh, rstst) ((oh).prcm.omap4.rstst_offs = (rstst)) |
32 | #define PRCM_FLAGS(oh, flag) ((oh).prcm.omap4.flags = (flag)) | ||
32 | 33 | ||
33 | /* | 34 | /* |
34 | * 'l3' class | 35 | * 'l3' class |
@@ -1296,6 +1297,7 @@ static void omap_hwmod_am33xx_clkctrl(void) | |||
1296 | CLKCTRL(am33xx_i2c1_hwmod, AM33XX_CM_WKUP_I2C0_CLKCTRL_OFFSET); | 1297 | CLKCTRL(am33xx_i2c1_hwmod, AM33XX_CM_WKUP_I2C0_CLKCTRL_OFFSET); |
1297 | CLKCTRL(am33xx_wd_timer1_hwmod, AM33XX_CM_WKUP_WDT1_CLKCTRL_OFFSET); | 1298 | CLKCTRL(am33xx_wd_timer1_hwmod, AM33XX_CM_WKUP_WDT1_CLKCTRL_OFFSET); |
1298 | CLKCTRL(am33xx_rtc_hwmod, AM33XX_CM_RTC_RTC_CLKCTRL_OFFSET); | 1299 | CLKCTRL(am33xx_rtc_hwmod, AM33XX_CM_RTC_RTC_CLKCTRL_OFFSET); |
1300 | PRCM_FLAGS(am33xx_rtc_hwmod, HWMOD_OMAP4_ZERO_CLKCTRL_OFFSET); | ||
1299 | CLKCTRL(am33xx_mmc2_hwmod, AM33XX_CM_PER_MMC2_CLKCTRL_OFFSET); | 1301 | CLKCTRL(am33xx_mmc2_hwmod, AM33XX_CM_PER_MMC2_CLKCTRL_OFFSET); |
1300 | CLKCTRL(am33xx_gpmc_hwmod, AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET); | 1302 | CLKCTRL(am33xx_gpmc_hwmod, AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET); |
1301 | CLKCTRL(am33xx_l4_ls_hwmod, AM33XX_CM_PER_L4LS_CLKCTRL_OFFSET); | 1303 | CLKCTRL(am33xx_l4_ls_hwmod, AM33XX_CM_PER_L4LS_CLKCTRL_OFFSET); |
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index d72ee6185d5e..1cc4a6f3954e 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | |||
@@ -722,8 +722,20 @@ static struct omap_hwmod omap3xxx_dss_dispc_hwmod = { | |||
722 | * display serial interface controller | 722 | * display serial interface controller |
723 | */ | 723 | */ |
724 | 724 | ||
725 | static struct omap_hwmod_class_sysconfig omap3xxx_dsi_sysc = { | ||
726 | .rev_offs = 0x0000, | ||
727 | .sysc_offs = 0x0010, | ||
728 | .syss_offs = 0x0014, | ||
729 | .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | | ||
730 | SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | | ||
731 | SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), | ||
732 | .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), | ||
733 | .sysc_fields = &omap_hwmod_sysc_type1, | ||
734 | }; | ||
735 | |||
725 | static struct omap_hwmod_class omap3xxx_dsi_hwmod_class = { | 736 | static struct omap_hwmod_class omap3xxx_dsi_hwmod_class = { |
726 | .name = "dsi", | 737 | .name = "dsi", |
738 | .sysc = &omap3xxx_dsi_sysc, | ||
727 | }; | 739 | }; |
728 | 740 | ||
729 | static struct omap_hwmod_irq_info omap3xxx_dsi1_irqs[] = { | 741 | static struct omap_hwmod_irq_info omap3xxx_dsi1_irqs[] = { |
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index c410d84b243d..66070acaa888 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c | |||
@@ -83,7 +83,8 @@ static struct resource smc91x_resources[] = { | |||
83 | }; | 83 | }; |
84 | 84 | ||
85 | static struct smc91x_platdata smc91x_platdata = { | 85 | static struct smc91x_platdata smc91x_platdata = { |
86 | .flags = SMC91X_USE_32BIT | SMC91X_USE_DMA | SMC91X_NOWAIT, | 86 | .flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT | |
87 | SMC91X_USE_DMA | SMC91X_NOWAIT, | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | static struct platform_device smc91x_device = { | 90 | static struct platform_device smc91x_device = { |
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 7245f3359564..d6159f8ef0c2 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c | |||
@@ -137,6 +137,18 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = { | |||
137 | // no D+ pullup; lubbock can't connect/disconnect in software | 137 | // no D+ pullup; lubbock can't connect/disconnect in software |
138 | }; | 138 | }; |
139 | 139 | ||
140 | static void lubbock_init_pcmcia(void) | ||
141 | { | ||
142 | struct clk *clk; | ||
143 | |||
144 | /* Add an alias for the SA1111 PCMCIA clock */ | ||
145 | clk = clk_get_sys("pxa2xx-pcmcia", NULL); | ||
146 | if (!IS_ERR(clk)) { | ||
147 | clkdev_create(clk, NULL, "1800"); | ||
148 | clk_put(clk); | ||
149 | } | ||
150 | } | ||
151 | |||
140 | static struct resource sa1111_resources[] = { | 152 | static struct resource sa1111_resources[] = { |
141 | [0] = { | 153 | [0] = { |
142 | .start = 0x10000000, | 154 | .start = 0x10000000, |
@@ -467,6 +479,8 @@ static void __init lubbock_init(void) | |||
467 | pxa_set_btuart_info(NULL); | 479 | pxa_set_btuart_info(NULL); |
468 | pxa_set_stuart_info(NULL); | 480 | pxa_set_stuart_info(NULL); |
469 | 481 | ||
482 | lubbock_init_pcmcia(); | ||
483 | |||
470 | clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL); | 484 | clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL); |
471 | pxa_set_udc_info(&udc_info); | 485 | pxa_set_udc_info(&udc_info); |
472 | pxa_set_fb_info(NULL, &sharp_lm8v31); | 486 | pxa_set_fb_info(NULL, &sharp_lm8v31); |
diff --git a/arch/arm/mach-pxa/xcep.c b/arch/arm/mach-pxa/xcep.c index 3f06cd90567a..056369ef250e 100644 --- a/arch/arm/mach-pxa/xcep.c +++ b/arch/arm/mach-pxa/xcep.c | |||
@@ -120,7 +120,8 @@ static struct resource smc91x_resources[] = { | |||
120 | }; | 120 | }; |
121 | 121 | ||
122 | static struct smc91x_platdata xcep_smc91x_info = { | 122 | static struct smc91x_platdata xcep_smc91x_info = { |
123 | .flags = SMC91X_USE_32BIT | SMC91X_NOWAIT | SMC91X_USE_DMA, | 123 | .flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT | |
124 | SMC91X_NOWAIT | SMC91X_USE_DMA, | ||
124 | }; | 125 | }; |
125 | 126 | ||
126 | static struct platform_device smc91x_device = { | 127 | static struct platform_device smc91x_device = { |
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index baf174542e36..a0ead0ae23d6 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c | |||
@@ -93,7 +93,8 @@ static struct smsc911x_platform_config smsc911x_config = { | |||
93 | }; | 93 | }; |
94 | 94 | ||
95 | static struct smc91x_platdata smc91x_platdata = { | 95 | static struct smc91x_platdata smc91x_platdata = { |
96 | .flags = SMC91X_USE_32BIT | SMC91X_NOWAIT, | 96 | .flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT | |
97 | SMC91X_NOWAIT, | ||
97 | }; | 98 | }; |
98 | 99 | ||
99 | static struct platform_device realview_eth_device = { | 100 | static struct platform_device realview_eth_device = { |
diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c index a8521684a7f5..13999c1c46cf 100644 --- a/arch/arm/mach-s3c24xx/mach-mini2440.c +++ b/arch/arm/mach-s3c24xx/mach-mini2440.c | |||
@@ -497,9 +497,28 @@ static struct i2c_board_info mini2440_i2c_devs[] __initdata = { | |||
497 | }, | 497 | }, |
498 | }; | 498 | }; |
499 | 499 | ||
500 | static struct uda134x_platform_data s3c24xx_uda134x = { | ||
501 | .l3 = { | ||
502 | .gpio_clk = S3C2410_GPB(4), | ||
503 | .gpio_data = S3C2410_GPB(3), | ||
504 | .gpio_mode = S3C2410_GPB(2), | ||
505 | .use_gpios = 1, | ||
506 | .data_hold = 1, | ||
507 | .data_setup = 1, | ||
508 | .clock_high = 1, | ||
509 | .mode_hold = 1, | ||
510 | .mode = 1, | ||
511 | .mode_setup = 1, | ||
512 | }, | ||
513 | .model = UDA134X_UDA1341, | ||
514 | }; | ||
515 | |||
500 | static struct platform_device uda1340_codec = { | 516 | static struct platform_device uda1340_codec = { |
501 | .name = "uda134x-codec", | 517 | .name = "uda134x-codec", |
502 | .id = -1, | 518 | .id = -1, |
519 | .dev = { | ||
520 | .platform_data = &s3c24xx_uda134x, | ||
521 | }, | ||
503 | }; | 522 | }; |
504 | 523 | ||
505 | static struct platform_device *mini2440_devices[] __initdata = { | 524 | static struct platform_device *mini2440_devices[] __initdata = { |
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c index cbf53bb9c814..0db46895c82a 100644 --- a/arch/arm/mach-sa1100/clock.c +++ b/arch/arm/mach-sa1100/clock.c | |||
@@ -125,6 +125,8 @@ static unsigned long clk_36864_get_rate(struct clk *clk) | |||
125 | } | 125 | } |
126 | 126 | ||
127 | static struct clkops clk_36864_ops = { | 127 | static struct clkops clk_36864_ops = { |
128 | .enable = clk_cpu_enable, | ||
129 | .disable = clk_cpu_disable, | ||
128 | .get_rate = clk_36864_get_rate, | 130 | .get_rate = clk_36864_get_rate, |
129 | }; | 131 | }; |
130 | 132 | ||
@@ -140,9 +142,8 @@ static struct clk_lookup sa11xx_clkregs[] = { | |||
140 | CLKDEV_INIT(NULL, "OSTIMER0", &clk_36864), | 142 | CLKDEV_INIT(NULL, "OSTIMER0", &clk_36864), |
141 | }; | 143 | }; |
142 | 144 | ||
143 | static int __init sa11xx_clk_init(void) | 145 | int __init sa11xx_clk_init(void) |
144 | { | 146 | { |
145 | clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs)); | 147 | clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs)); |
146 | return 0; | 148 | return 0; |
147 | } | 149 | } |
148 | core_initcall(sa11xx_clk_init); | ||
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 345e63f4eb71..3e09beddb6e8 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | #include <mach/hardware.h> | 35 | #include <mach/hardware.h> |
36 | #include <mach/irqs.h> | 36 | #include <mach/irqs.h> |
37 | #include <mach/reset.h> | ||
37 | 38 | ||
38 | #include "generic.h" | 39 | #include "generic.h" |
39 | #include <clocksource/pxa.h> | 40 | #include <clocksource/pxa.h> |
@@ -95,6 +96,8 @@ static void sa1100_power_off(void) | |||
95 | 96 | ||
96 | void sa11x0_restart(enum reboot_mode mode, const char *cmd) | 97 | void sa11x0_restart(enum reboot_mode mode, const char *cmd) |
97 | { | 98 | { |
99 | clear_reset_status(RESET_STATUS_ALL); | ||
100 | |||
98 | if (mode == REBOOT_SOFT) { | 101 | if (mode == REBOOT_SOFT) { |
99 | /* Jump into ROM at address 0 */ | 102 | /* Jump into ROM at address 0 */ |
100 | soft_restart(0); | 103 | soft_restart(0); |
@@ -388,6 +391,7 @@ void __init sa1100_init_irq(void) | |||
388 | sa11x0_init_irq_nodt(IRQ_GPIO0_SC, irq_resource.start); | 391 | sa11x0_init_irq_nodt(IRQ_GPIO0_SC, irq_resource.start); |
389 | 392 | ||
390 | sa1100_init_gpio(); | 393 | sa1100_init_gpio(); |
394 | sa11xx_clk_init(); | ||
391 | } | 395 | } |
392 | 396 | ||
393 | /* | 397 | /* |
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h index 0d92e119b36b..68199b603ff7 100644 --- a/arch/arm/mach-sa1100/generic.h +++ b/arch/arm/mach-sa1100/generic.h | |||
@@ -44,3 +44,5 @@ int sa11x0_pm_init(void); | |||
44 | #else | 44 | #else |
45 | static inline int sa11x0_pm_init(void) { return 0; } | 45 | static inline int sa11x0_pm_init(void) { return 0; } |
46 | #endif | 46 | #endif |
47 | |||
48 | int sa11xx_clk_init(void); | ||
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c index 1525d7b5f1b7..88149f85bc49 100644 --- a/arch/arm/mach-sa1100/pleb.c +++ b/arch/arm/mach-sa1100/pleb.c | |||
@@ -45,7 +45,7 @@ static struct resource smc91x_resources[] = { | |||
45 | }; | 45 | }; |
46 | 46 | ||
47 | static struct smc91x_platdata smc91x_platdata = { | 47 | static struct smc91x_platdata smc91x_platdata = { |
48 | .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, | 48 | .flags = SMC91X_USE_16BIT | SMC91X_USE_8BIT | SMC91X_NOWAIT, |
49 | }; | 49 | }; |
50 | 50 | ||
51 | static struct platform_device smc91x_device = { | 51 | static struct platform_device smc91x_device = { |
diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c index 62437b57813e..73e3adbc1330 100644 --- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c +++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c | |||
@@ -41,39 +41,26 @@ | |||
41 | 41 | ||
42 | #define REGULATOR_IRQ_MASK BIT(2) /* IRQ2, active low */ | 42 | #define REGULATOR_IRQ_MASK BIT(2) /* IRQ2, active low */ |
43 | 43 | ||
44 | static void __iomem *irqc; | 44 | /* start of DA9210 System Control and Event Registers */ |
45 | |||
46 | static const u8 da9063_mask_regs[] = { | ||
47 | DA9063_REG_IRQ_MASK_A, | ||
48 | DA9063_REG_IRQ_MASK_B, | ||
49 | DA9063_REG_IRQ_MASK_C, | ||
50 | DA9063_REG_IRQ_MASK_D, | ||
51 | }; | ||
52 | |||
53 | /* DA9210 System Control and Event Registers */ | ||
54 | #define DA9210_REG_MASK_A 0x54 | 45 | #define DA9210_REG_MASK_A 0x54 |
55 | #define DA9210_REG_MASK_B 0x55 | ||
56 | |||
57 | static const u8 da9210_mask_regs[] = { | ||
58 | DA9210_REG_MASK_A, | ||
59 | DA9210_REG_MASK_B, | ||
60 | }; | ||
61 | |||
62 | static void da9xxx_mask_irqs(struct i2c_client *client, const u8 regs[], | ||
63 | unsigned int nregs) | ||
64 | { | ||
65 | unsigned int i; | ||
66 | 46 | ||
67 | dev_info(&client->dev, "Masking %s interrupt sources\n", client->name); | 47 | static void __iomem *irqc; |
68 | 48 | ||
69 | for (i = 0; i < nregs; i++) { | 49 | /* first byte sets the memory pointer, following are consecutive reg values */ |
70 | int error = i2c_smbus_write_byte_data(client, regs[i], ~0); | 50 | static u8 da9063_irq_clr[] = { DA9063_REG_IRQ_MASK_A, 0xff, 0xff, 0xff, 0xff }; |
71 | if (error) { | 51 | static u8 da9210_irq_clr[] = { DA9210_REG_MASK_A, 0xff, 0xff }; |
72 | dev_err(&client->dev, "i2c error %d\n", error); | 52 | |
73 | return; | 53 | static struct i2c_msg da9xxx_msgs[2] = { |
74 | } | 54 | { |
75 | } | 55 | .addr = 0x58, |
76 | } | 56 | .len = ARRAY_SIZE(da9063_irq_clr), |
57 | .buf = da9063_irq_clr, | ||
58 | }, { | ||
59 | .addr = 0x68, | ||
60 | .len = ARRAY_SIZE(da9210_irq_clr), | ||
61 | .buf = da9210_irq_clr, | ||
62 | }, | ||
63 | }; | ||
77 | 64 | ||
78 | static int regulator_quirk_notify(struct notifier_block *nb, | 65 | static int regulator_quirk_notify(struct notifier_block *nb, |
79 | unsigned long action, void *data) | 66 | unsigned long action, void *data) |
@@ -93,12 +80,15 @@ static int regulator_quirk_notify(struct notifier_block *nb, | |||
93 | client = to_i2c_client(dev); | 80 | client = to_i2c_client(dev); |
94 | dev_dbg(dev, "Detected %s\n", client->name); | 81 | dev_dbg(dev, "Detected %s\n", client->name); |
95 | 82 | ||
96 | if ((client->addr == 0x58 && !strcmp(client->name, "da9063"))) | 83 | if ((client->addr == 0x58 && !strcmp(client->name, "da9063")) || |
97 | da9xxx_mask_irqs(client, da9063_mask_regs, | 84 | (client->addr == 0x68 && !strcmp(client->name, "da9210"))) { |
98 | ARRAY_SIZE(da9063_mask_regs)); | 85 | int ret; |
99 | else if (client->addr == 0x68 && !strcmp(client->name, "da9210")) | 86 | |
100 | da9xxx_mask_irqs(client, da9210_mask_regs, | 87 | dev_info(&client->dev, "clearing da9063/da9210 interrupts\n"); |
101 | ARRAY_SIZE(da9210_mask_regs)); | 88 | ret = i2c_transfer(client->adapter, da9xxx_msgs, ARRAY_SIZE(da9xxx_msgs)); |
89 | if (ret != ARRAY_SIZE(da9xxx_msgs)) | ||
90 | dev_err(&client->dev, "i2c error %d\n", ret); | ||
91 | } | ||
102 | 92 | ||
103 | mon = ioread32(irqc + IRQC_MONITOR); | 93 | mon = ioread32(irqc + IRQC_MONITOR); |
104 | if (mon & REGULATOR_IRQ_MASK) | 94 | if (mon & REGULATOR_IRQ_MASK) |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 6344913f0804..30fe03f95c85 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -137,7 +137,7 @@ void __init init_default_cache_policy(unsigned long pmd) | |||
137 | 137 | ||
138 | initial_pmd_value = pmd; | 138 | initial_pmd_value = pmd; |
139 | 139 | ||
140 | pmd &= PMD_SECT_TEX(1) | PMD_SECT_BUFFERABLE | PMD_SECT_CACHEABLE; | 140 | pmd &= PMD_SECT_CACHE_MASK; |
141 | 141 | ||
142 | for (i = 0; i < ARRAY_SIZE(cache_policies); i++) | 142 | for (i = 0; i < ARRAY_SIZE(cache_policies); i++) |
143 | if (cache_policies[i].pmd == pmd) { | 143 | if (cache_policies[i].pmd == pmd) { |
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index a7123b4e129d..d00d52c9de3e 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <asm/hwcap.h> | 16 | #include <asm/hwcap.h> |
17 | #include <asm/pgtable-hwdef.h> | 17 | #include <asm/pgtable-hwdef.h> |
18 | #include <asm/pgtable.h> | 18 | #include <asm/pgtable.h> |
19 | #include <asm/memory.h> | ||
19 | 20 | ||
20 | #include "proc-macros.S" | 21 | #include "proc-macros.S" |
21 | 22 | ||
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index b0b82f5ea338..f193414d0f6f 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c | |||
@@ -50,7 +50,7 @@ DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); | |||
50 | static struct vcpu_info __percpu *xen_vcpu_info; | 50 | static struct vcpu_info __percpu *xen_vcpu_info; |
51 | 51 | ||
52 | /* Linux <-> Xen vCPU id mapping */ | 52 | /* Linux <-> Xen vCPU id mapping */ |
53 | DEFINE_PER_CPU(int, xen_vcpu_id) = -1; | 53 | DEFINE_PER_CPU(uint32_t, xen_vcpu_id); |
54 | EXPORT_PER_CPU_SYMBOL(xen_vcpu_id); | 54 | EXPORT_PER_CPU_SYMBOL(xen_vcpu_id); |
55 | 55 | ||
56 | /* These are unused until we support booting "pre-ballooned" */ | 56 | /* These are unused until we support booting "pre-ballooned" */ |
@@ -170,9 +170,6 @@ static int xen_starting_cpu(unsigned int cpu) | |||
170 | pr_info("Xen: initializing cpu%d\n", cpu); | 170 | pr_info("Xen: initializing cpu%d\n", cpu); |
171 | vcpup = per_cpu_ptr(xen_vcpu_info, cpu); | 171 | vcpup = per_cpu_ptr(xen_vcpu_info, cpu); |
172 | 172 | ||
173 | /* Direct vCPU id mapping for ARM guests. */ | ||
174 | per_cpu(xen_vcpu_id, cpu) = cpu; | ||
175 | |||
176 | info.mfn = virt_to_gfn(vcpup); | 173 | info.mfn = virt_to_gfn(vcpup); |
177 | info.offset = xen_offset_in_page(vcpup); | 174 | info.offset = xen_offset_in_page(vcpup); |
178 | 175 | ||
@@ -330,6 +327,7 @@ static int __init xen_guest_init(void) | |||
330 | { | 327 | { |
331 | struct xen_add_to_physmap xatp; | 328 | struct xen_add_to_physmap xatp; |
332 | struct shared_info *shared_info_page = NULL; | 329 | struct shared_info *shared_info_page = NULL; |
330 | int cpu; | ||
333 | 331 | ||
334 | if (!xen_domain()) | 332 | if (!xen_domain()) |
335 | return 0; | 333 | return 0; |
@@ -380,7 +378,8 @@ static int __init xen_guest_init(void) | |||
380 | return -ENOMEM; | 378 | return -ENOMEM; |
381 | 379 | ||
382 | /* Direct vCPU id mapping for ARM guests. */ | 380 | /* Direct vCPU id mapping for ARM guests. */ |
383 | per_cpu(xen_vcpu_id, 0) = 0; | 381 | for_each_possible_cpu(cpu) |
382 | per_cpu(xen_vcpu_id, cpu) = cpu; | ||
384 | 383 | ||
385 | xen_auto_xlat_grant_frames.count = gnttab_max_grant_frames(); | 384 | xen_auto_xlat_grant_frames.count = gnttab_max_grant_frames(); |
386 | if (xen_xlate_map_ballooned_pages(&xen_auto_xlat_grant_frames.pfn, | 385 | if (xen_xlate_map_ballooned_pages(&xen_auto_xlat_grant_frames.pfn, |
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi index 445aa678f914..c2b9bcb0ef61 100644 --- a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi +++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi | |||
@@ -255,10 +255,10 @@ | |||
255 | /* Local timer */ | 255 | /* Local timer */ |
256 | timer { | 256 | timer { |
257 | compatible = "arm,armv8-timer"; | 257 | compatible = "arm,armv8-timer"; |
258 | interrupts = <1 13 0xf01>, | 258 | interrupts = <1 13 0xf08>, |
259 | <1 14 0xf01>, | 259 | <1 14 0xf08>, |
260 | <1 11 0xf01>, | 260 | <1 11 0xf08>, |
261 | <1 10 0xf01>; | 261 | <1 10 0xf08>; |
262 | }; | 262 | }; |
263 | 263 | ||
264 | timer0: timer0@ffc03000 { | 264 | timer0: timer0@ffc03000 { |
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi index e502c24b0ac7..bf6c8d051002 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | |||
@@ -102,13 +102,13 @@ | |||
102 | timer { | 102 | timer { |
103 | compatible = "arm,armv8-timer"; | 103 | compatible = "arm,armv8-timer"; |
104 | interrupts = <GIC_PPI 13 | 104 | interrupts = <GIC_PPI 13 |
105 | (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_EDGE_RISING)>, | 105 | (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>, |
106 | <GIC_PPI 14 | 106 | <GIC_PPI 14 |
107 | (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_EDGE_RISING)>, | 107 | (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>, |
108 | <GIC_PPI 11 | 108 | <GIC_PPI 11 |
109 | (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_EDGE_RISING)>, | 109 | (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>, |
110 | <GIC_PPI 10 | 110 | <GIC_PPI 10 |
111 | (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_EDGE_RISING)>; | 111 | (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>; |
112 | }; | 112 | }; |
113 | 113 | ||
114 | xtal: xtal-clk { | 114 | xtal: xtal-clk { |
diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi index f1c2c713f9b0..c29dab9d1834 100644 --- a/arch/arm64/boot/dts/apm/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi | |||
@@ -110,10 +110,10 @@ | |||
110 | 110 | ||
111 | timer { | 111 | timer { |
112 | compatible = "arm,armv8-timer"; | 112 | compatible = "arm,armv8-timer"; |
113 | interrupts = <1 0 0xff01>, /* Secure Phys IRQ */ | 113 | interrupts = <1 0 0xff08>, /* Secure Phys IRQ */ |
114 | <1 13 0xff01>, /* Non-secure Phys IRQ */ | 114 | <1 13 0xff08>, /* Non-secure Phys IRQ */ |
115 | <1 14 0xff01>, /* Virt IRQ */ | 115 | <1 14 0xff08>, /* Virt IRQ */ |
116 | <1 15 0xff01>; /* Hyp IRQ */ | 116 | <1 15 0xff08>; /* Hyp IRQ */ |
117 | clock-frequency = <50000000>; | 117 | clock-frequency = <50000000>; |
118 | }; | 118 | }; |
119 | 119 | ||
diff --git a/arch/arm64/boot/dts/broadcom/bcm2835-rpi.dtsi b/arch/arm64/boot/dts/broadcom/bcm2835-rpi.dtsi new file mode 120000 index 000000000000..3937b77cb310 --- /dev/null +++ b/arch/arm64/boot/dts/broadcom/bcm2835-rpi.dtsi | |||
@@ -0,0 +1 @@ | |||
../../../../arm/boot/dts/bcm2835-rpi.dtsi \ No newline at end of file | |||
diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts index 6f47dd2bb1db..7841b724e340 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts +++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts | |||
@@ -1,7 +1,7 @@ | |||
1 | /dts-v1/; | 1 | /dts-v1/; |
2 | #include "bcm2837.dtsi" | 2 | #include "bcm2837.dtsi" |
3 | #include "../../../../arm/boot/dts/bcm2835-rpi.dtsi" | 3 | #include "bcm2835-rpi.dtsi" |
4 | #include "../../../../arm/boot/dts/bcm283x-rpi-smsc9514.dtsi" | 4 | #include "bcm283x-rpi-smsc9514.dtsi" |
5 | 5 | ||
6 | / { | 6 | / { |
7 | compatible = "raspberrypi,3-model-b", "brcm,bcm2837"; | 7 | compatible = "raspberrypi,3-model-b", "brcm,bcm2837"; |
diff --git a/arch/arm64/boot/dts/broadcom/bcm2837.dtsi b/arch/arm64/boot/dts/broadcom/bcm2837.dtsi index f2a31d06845d..8216bbb29fe0 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2837.dtsi +++ b/arch/arm64/boot/dts/broadcom/bcm2837.dtsi | |||
@@ -1,4 +1,4 @@ | |||
1 | #include "../../../../arm/boot/dts/bcm283x.dtsi" | 1 | #include "bcm283x.dtsi" |
2 | 2 | ||
3 | / { | 3 | / { |
4 | compatible = "brcm,bcm2836"; | 4 | compatible = "brcm,bcm2836"; |
diff --git a/arch/arm64/boot/dts/broadcom/bcm283x-rpi-smsc9514.dtsi b/arch/arm64/boot/dts/broadcom/bcm283x-rpi-smsc9514.dtsi new file mode 120000 index 000000000000..dca7c057d5a5 --- /dev/null +++ b/arch/arm64/boot/dts/broadcom/bcm283x-rpi-smsc9514.dtsi | |||
@@ -0,0 +1 @@ | |||
../../../../arm/boot/dts/bcm283x-rpi-smsc9514.dtsi \ No newline at end of file | |||
diff --git a/arch/arm64/boot/dts/broadcom/bcm283x.dtsi b/arch/arm64/boot/dts/broadcom/bcm283x.dtsi new file mode 120000 index 000000000000..5f54e4cab99b --- /dev/null +++ b/arch/arm64/boot/dts/broadcom/bcm283x.dtsi | |||
@@ -0,0 +1 @@ | |||
../../../../arm/boot/dts/bcm283x.dtsi \ No newline at end of file | |||
diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi index f53b0955bfd3..d4a12fad8afd 100644 --- a/arch/arm64/boot/dts/broadcom/ns2.dtsi +++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi | |||
@@ -88,13 +88,13 @@ | |||
88 | timer { | 88 | timer { |
89 | compatible = "arm,armv8-timer"; | 89 | compatible = "arm,armv8-timer"; |
90 | interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(0xff) | | 90 | interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(0xff) | |
91 | IRQ_TYPE_EDGE_RISING)>, | 91 | IRQ_TYPE_LEVEL_LOW)>, |
92 | <GIC_PPI 14 (GIC_CPU_MASK_RAW(0xff) | | 92 | <GIC_PPI 14 (GIC_CPU_MASK_RAW(0xff) | |
93 | IRQ_TYPE_EDGE_RISING)>, | 93 | IRQ_TYPE_LEVEL_LOW)>, |
94 | <GIC_PPI 11 (GIC_CPU_MASK_RAW(0xff) | | 94 | <GIC_PPI 11 (GIC_CPU_MASK_RAW(0xff) | |
95 | IRQ_TYPE_EDGE_RISING)>, | 95 | IRQ_TYPE_LEVEL_LOW)>, |
96 | <GIC_PPI 10 (GIC_CPU_MASK_RAW(0xff) | | 96 | <GIC_PPI 10 (GIC_CPU_MASK_RAW(0xff) | |
97 | IRQ_TYPE_EDGE_RISING)>; | 97 | IRQ_TYPE_LEVEL_LOW)>; |
98 | }; | 98 | }; |
99 | 99 | ||
100 | pmu { | 100 | pmu { |
diff --git a/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi b/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi index 2eb9b225f0bc..04dc8a8d1539 100644 --- a/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi +++ b/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi | |||
@@ -354,10 +354,10 @@ | |||
354 | 354 | ||
355 | timer { | 355 | timer { |
356 | compatible = "arm,armv8-timer"; | 356 | compatible = "arm,armv8-timer"; |
357 | interrupts = <1 13 0xff01>, | 357 | interrupts = <1 13 4>, |
358 | <1 14 0xff01>, | 358 | <1 14 4>, |
359 | <1 11 0xff01>, | 359 | <1 11 4>, |
360 | <1 10 0xff01>; | 360 | <1 10 4>; |
361 | }; | 361 | }; |
362 | 362 | ||
363 | pmu { | 363 | pmu { |
diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi index ca663dfe5189..162831546e18 100644 --- a/arch/arm64/boot/dts/exynos/exynos7.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi | |||
@@ -473,10 +473,10 @@ | |||
473 | 473 | ||
474 | timer { | 474 | timer { |
475 | compatible = "arm,armv8-timer"; | 475 | compatible = "arm,armv8-timer"; |
476 | interrupts = <1 13 0xff01>, | 476 | interrupts = <1 13 0xff08>, |
477 | <1 14 0xff01>, | 477 | <1 14 0xff08>, |
478 | <1 11 0xff01>, | 478 | <1 11 0xff08>, |
479 | <1 10 0xff01>; | 479 | <1 10 0xff08>; |
480 | }; | 480 | }; |
481 | 481 | ||
482 | pmu_system_controller: system-controller@105c0000 { | 482 | pmu_system_controller: system-controller@105c0000 { |
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi index e669fbd7f9c3..a67e210e2019 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | |||
@@ -119,10 +119,10 @@ | |||
119 | 119 | ||
120 | timer { | 120 | timer { |
121 | compatible = "arm,armv8-timer"; | 121 | compatible = "arm,armv8-timer"; |
122 | interrupts = <1 13 0x1>, /* Physical Secure PPI */ | 122 | interrupts = <1 13 0xf08>, /* Physical Secure PPI */ |
123 | <1 14 0x1>, /* Physical Non-Secure PPI */ | 123 | <1 14 0xf08>, /* Physical Non-Secure PPI */ |
124 | <1 11 0x1>, /* Virtual PPI */ | 124 | <1 11 0xf08>, /* Virtual PPI */ |
125 | <1 10 0x1>; /* Hypervisor PPI */ | 125 | <1 10 0xf08>; /* Hypervisor PPI */ |
126 | }; | 126 | }; |
127 | 127 | ||
128 | pmu { | 128 | pmu { |
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi index 21023a388c29..e3b6034ea5d9 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi | |||
@@ -191,10 +191,10 @@ | |||
191 | 191 | ||
192 | timer { | 192 | timer { |
193 | compatible = "arm,armv8-timer"; | 193 | compatible = "arm,armv8-timer"; |
194 | interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */ | 194 | interrupts = <1 13 4>, /* Physical Secure PPI, active-low */ |
195 | <1 14 0x8>, /* Physical Non-Secure PPI, active-low */ | 195 | <1 14 4>, /* Physical Non-Secure PPI, active-low */ |
196 | <1 11 0x8>, /* Virtual PPI, active-low */ | 196 | <1 11 4>, /* Virtual PPI, active-low */ |
197 | <1 10 0x8>; /* Hypervisor PPI, active-low */ | 197 | <1 10 4>; /* Hypervisor PPI, active-low */ |
198 | }; | 198 | }; |
199 | 199 | ||
200 | pmu { | 200 | pmu { |
diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi index eab1a42fb934..c2a6745f168c 100644 --- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi | |||
@@ -122,10 +122,10 @@ | |||
122 | 122 | ||
123 | timer { | 123 | timer { |
124 | compatible = "arm,armv8-timer"; | 124 | compatible = "arm,armv8-timer"; |
125 | interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>, | 125 | interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, |
126 | <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>, | 126 | <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, |
127 | <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>, | 127 | <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, |
128 | <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>; | 128 | <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; |
129 | }; | 129 | }; |
130 | 130 | ||
131 | odmi: odmi@300000 { | 131 | odmi: odmi@300000 { |
diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi index d02a900378e1..4f44d1191bfd 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi | |||
@@ -270,6 +270,8 @@ | |||
270 | #io-channel-cells = <1>; | 270 | #io-channel-cells = <1>; |
271 | clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; | 271 | clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; |
272 | clock-names = "saradc", "apb_pclk"; | 272 | clock-names = "saradc", "apb_pclk"; |
273 | resets = <&cru SRST_SARADC>; | ||
274 | reset-names = "saradc-apb"; | ||
273 | status = "disabled"; | 275 | status = "disabled"; |
274 | }; | 276 | }; |
275 | 277 | ||
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi index c223915f0907..d73bdc8c9115 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi +++ b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi | |||
@@ -129,10 +129,10 @@ | |||
129 | 129 | ||
130 | timer { | 130 | timer { |
131 | compatible = "arm,armv8-timer"; | 131 | compatible = "arm,armv8-timer"; |
132 | interrupts = <1 13 0xf01>, | 132 | interrupts = <1 13 4>, |
133 | <1 14 0xf01>, | 133 | <1 14 4>, |
134 | <1 11 0xf01>, | 134 | <1 11 4>, |
135 | <1 10 0xf01>; | 135 | <1 10 4>; |
136 | }; | 136 | }; |
137 | 137 | ||
138 | soc { | 138 | soc { |
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi index e595f22e7e4b..3e2e51fbd2bc 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi | |||
@@ -65,10 +65,10 @@ | |||
65 | timer { | 65 | timer { |
66 | compatible = "arm,armv8-timer"; | 66 | compatible = "arm,armv8-timer"; |
67 | interrupt-parent = <&gic>; | 67 | interrupt-parent = <&gic>; |
68 | interrupts = <1 13 0xf01>, | 68 | interrupts = <1 13 0xf08>, |
69 | <1 14 0xf01>, | 69 | <1 14 0xf08>, |
70 | <1 11 0xf01>, | 70 | <1 11 0xf08>, |
71 | <1 10 0xf01>; | 71 | <1 10 0xf08>; |
72 | }; | 72 | }; |
73 | 73 | ||
74 | amba_apu { | 74 | amba_apu { |
diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c index 5c888049d061..6b2aa0fd6cd0 100644 --- a/arch/arm64/crypto/aes-glue.c +++ b/arch/arm64/crypto/aes-glue.c | |||
@@ -216,7 +216,7 @@ static int ctr_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | |||
216 | err = blkcipher_walk_done(desc, &walk, | 216 | err = blkcipher_walk_done(desc, &walk, |
217 | walk.nbytes % AES_BLOCK_SIZE); | 217 | walk.nbytes % AES_BLOCK_SIZE); |
218 | } | 218 | } |
219 | if (nbytes) { | 219 | if (walk.nbytes % AES_BLOCK_SIZE) { |
220 | u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE; | 220 | u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE; |
221 | u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE; | 221 | u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE; |
222 | u8 __aligned(8) tail[AES_BLOCK_SIZE]; | 222 | u8 __aligned(8) tail[AES_BLOCK_SIZE]; |
diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h index 4b6b3f72a215..b71420a12f26 100644 --- a/arch/arm64/include/asm/debug-monitors.h +++ b/arch/arm64/include/asm/debug-monitors.h | |||
@@ -61,8 +61,6 @@ | |||
61 | 61 | ||
62 | #define AARCH64_BREAK_KGDB_DYN_DBG \ | 62 | #define AARCH64_BREAK_KGDB_DYN_DBG \ |
63 | (AARCH64_BREAK_MON | (KGDB_DYN_DBG_BRK_IMM << 5)) | 63 | (AARCH64_BREAK_MON | (KGDB_DYN_DBG_BRK_IMM << 5)) |
64 | #define KGDB_DYN_BRK_INS_BYTE(x) \ | ||
65 | ((AARCH64_BREAK_KGDB_DYN_DBG >> (8 * (x))) & 0xff) | ||
66 | 64 | ||
67 | #define CACHE_FLUSH_IS_SAFE 1 | 65 | #define CACHE_FLUSH_IS_SAFE 1 |
68 | 66 | ||
diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h index 0a456bef8c79..2fee2f59288c 100644 --- a/arch/arm64/include/asm/percpu.h +++ b/arch/arm64/include/asm/percpu.h | |||
@@ -199,19 +199,19 @@ static inline unsigned long __percpu_xchg(void *ptr, unsigned long val, | |||
199 | #define _percpu_read(pcp) \ | 199 | #define _percpu_read(pcp) \ |
200 | ({ \ | 200 | ({ \ |
201 | typeof(pcp) __retval; \ | 201 | typeof(pcp) __retval; \ |
202 | preempt_disable(); \ | 202 | preempt_disable_notrace(); \ |
203 | __retval = (typeof(pcp))__percpu_read(raw_cpu_ptr(&(pcp)), \ | 203 | __retval = (typeof(pcp))__percpu_read(raw_cpu_ptr(&(pcp)), \ |
204 | sizeof(pcp)); \ | 204 | sizeof(pcp)); \ |
205 | preempt_enable(); \ | 205 | preempt_enable_notrace(); \ |
206 | __retval; \ | 206 | __retval; \ |
207 | }) | 207 | }) |
208 | 208 | ||
209 | #define _percpu_write(pcp, val) \ | 209 | #define _percpu_write(pcp, val) \ |
210 | do { \ | 210 | do { \ |
211 | preempt_disable(); \ | 211 | preempt_disable_notrace(); \ |
212 | __percpu_write(raw_cpu_ptr(&(pcp)), (unsigned long)(val), \ | 212 | __percpu_write(raw_cpu_ptr(&(pcp)), (unsigned long)(val), \ |
213 | sizeof(pcp)); \ | 213 | sizeof(pcp)); \ |
214 | preempt_enable(); \ | 214 | preempt_enable_notrace(); \ |
215 | } while(0) \ | 215 | } while(0) \ |
216 | 216 | ||
217 | #define _pcp_protect(operation, pcp, val) \ | 217 | #define _pcp_protect(operation, pcp, val) \ |
diff --git a/arch/arm64/include/asm/spinlock.h b/arch/arm64/include/asm/spinlock.h index e875a5a551d7..89206b568cd4 100644 --- a/arch/arm64/include/asm/spinlock.h +++ b/arch/arm64/include/asm/spinlock.h | |||
@@ -363,4 +363,14 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) | |||
363 | #define arch_read_relax(lock) cpu_relax() | 363 | #define arch_read_relax(lock) cpu_relax() |
364 | #define arch_write_relax(lock) cpu_relax() | 364 | #define arch_write_relax(lock) cpu_relax() |
365 | 365 | ||
366 | /* | ||
367 | * Accesses appearing in program order before a spin_lock() operation | ||
368 | * can be reordered with accesses inside the critical section, by virtue | ||
369 | * of arch_spin_lock being constructed using acquire semantics. | ||
370 | * | ||
371 | * In cases where this is problematic (e.g. try_to_wake_up), an | ||
372 | * smp_mb__before_spinlock() can restore the required ordering. | ||
373 | */ | ||
374 | #define smp_mb__before_spinlock() smp_mb() | ||
375 | |||
366 | #endif /* __ASM_SPINLOCK_H */ | 376 | #endif /* __ASM_SPINLOCK_H */ |
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index b77f58355da1..3e7b050e99dc 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S | |||
@@ -757,6 +757,9 @@ ENTRY(__enable_mmu) | |||
757 | isb | 757 | isb |
758 | bl __create_page_tables // recreate kernel mapping | 758 | bl __create_page_tables // recreate kernel mapping |
759 | 759 | ||
760 | tlbi vmalle1 // Remove any stale TLB entries | ||
761 | dsb nsh | ||
762 | |||
760 | msr sctlr_el1, x19 // re-enable the MMU | 763 | msr sctlr_el1, x19 // re-enable the MMU |
761 | isb | 764 | isb |
762 | ic iallu // flush instructions fetched | 765 | ic iallu // flush instructions fetched |
diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c index 8c57f6496e56..e017a9493b92 100644 --- a/arch/arm64/kernel/kgdb.c +++ b/arch/arm64/kernel/kgdb.c | |||
@@ -19,10 +19,13 @@ | |||
19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/bug.h> | ||
22 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
23 | #include <linux/kdebug.h> | 24 | #include <linux/kdebug.h> |
24 | #include <linux/kgdb.h> | 25 | #include <linux/kgdb.h> |
25 | #include <linux/kprobes.h> | 26 | #include <linux/kprobes.h> |
27 | #include <asm/debug-monitors.h> | ||
28 | #include <asm/insn.h> | ||
26 | #include <asm/traps.h> | 29 | #include <asm/traps.h> |
27 | 30 | ||
28 | struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { | 31 | struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { |
@@ -338,15 +341,24 @@ void kgdb_arch_exit(void) | |||
338 | unregister_die_notifier(&kgdb_notifier); | 341 | unregister_die_notifier(&kgdb_notifier); |
339 | } | 342 | } |
340 | 343 | ||
341 | /* | 344 | struct kgdb_arch arch_kgdb_ops; |
342 | * ARM instructions are always in LE. | 345 | |
343 | * Break instruction is encoded in LE format | 346 | int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) |
344 | */ | 347 | { |
345 | struct kgdb_arch arch_kgdb_ops = { | 348 | int err; |
346 | .gdb_bpt_instr = { | 349 | |
347 | KGDB_DYN_BRK_INS_BYTE(0), | 350 | BUILD_BUG_ON(AARCH64_INSN_SIZE != BREAK_INSTR_SIZE); |
348 | KGDB_DYN_BRK_INS_BYTE(1), | 351 | |
349 | KGDB_DYN_BRK_INS_BYTE(2), | 352 | err = aarch64_insn_read((void *)bpt->bpt_addr, (u32 *)bpt->saved_instr); |
350 | KGDB_DYN_BRK_INS_BYTE(3), | 353 | if (err) |
351 | } | 354 | return err; |
352 | }; | 355 | |
356 | return aarch64_insn_write((void *)bpt->bpt_addr, | ||
357 | (u32)AARCH64_BREAK_KGDB_DYN_DBG); | ||
358 | } | ||
359 | |||
360 | int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) | ||
361 | { | ||
362 | return aarch64_insn_write((void *)bpt->bpt_addr, | ||
363 | *(u32 *)bpt->saved_instr); | ||
364 | } | ||
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index d93d43352504..3ff173e92582 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c | |||
@@ -201,12 +201,6 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) | |||
201 | return ret; | 201 | return ret; |
202 | } | 202 | } |
203 | 203 | ||
204 | static void smp_store_cpu_info(unsigned int cpuid) | ||
205 | { | ||
206 | store_cpu_topology(cpuid); | ||
207 | numa_store_cpu_info(cpuid); | ||
208 | } | ||
209 | |||
210 | /* | 204 | /* |
211 | * This is the secondary CPU boot entry. We're using this CPUs | 205 | * This is the secondary CPU boot entry. We're using this CPUs |
212 | * idle thread stack, but a set of temporary page tables. | 206 | * idle thread stack, but a set of temporary page tables. |
@@ -254,7 +248,7 @@ asmlinkage void secondary_start_kernel(void) | |||
254 | */ | 248 | */ |
255 | notify_cpu_starting(cpu); | 249 | notify_cpu_starting(cpu); |
256 | 250 | ||
257 | smp_store_cpu_info(cpu); | 251 | store_cpu_topology(cpu); |
258 | 252 | ||
259 | /* | 253 | /* |
260 | * OK, now it's safe to let the boot CPU continue. Wait for | 254 | * OK, now it's safe to let the boot CPU continue. Wait for |
@@ -689,10 +683,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
689 | { | 683 | { |
690 | int err; | 684 | int err; |
691 | unsigned int cpu; | 685 | unsigned int cpu; |
686 | unsigned int this_cpu; | ||
692 | 687 | ||
693 | init_cpu_topology(); | 688 | init_cpu_topology(); |
694 | 689 | ||
695 | smp_store_cpu_info(smp_processor_id()); | 690 | this_cpu = smp_processor_id(); |
691 | store_cpu_topology(this_cpu); | ||
692 | numa_store_cpu_info(this_cpu); | ||
696 | 693 | ||
697 | /* | 694 | /* |
698 | * If UP is mandated by "nosmp" (which implies "maxcpus=0"), don't set | 695 | * If UP is mandated by "nosmp" (which implies "maxcpus=0"), don't set |
@@ -719,6 +716,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
719 | continue; | 716 | continue; |
720 | 717 | ||
721 | set_cpu_present(cpu, true); | 718 | set_cpu_present(cpu, true); |
719 | numa_store_cpu_info(cpu); | ||
722 | } | 720 | } |
723 | } | 721 | } |
724 | 722 | ||
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c index ae7855f16ec2..5a84b4562603 100644 --- a/arch/arm64/kvm/hyp/switch.c +++ b/arch/arm64/kvm/hyp/switch.c | |||
@@ -256,7 +256,7 @@ static int __hyp_text __guest_run(struct kvm_vcpu *vcpu) | |||
256 | 256 | ||
257 | /* | 257 | /* |
258 | * We must restore the 32-bit state before the sysregs, thanks | 258 | * We must restore the 32-bit state before the sysregs, thanks |
259 | * to Cortex-A57 erratum #852523. | 259 | * to erratum #852523 (Cortex-A57) or #853709 (Cortex-A72). |
260 | */ | 260 | */ |
261 | __sysreg32_restore_state(vcpu); | 261 | __sysreg32_restore_state(vcpu); |
262 | __sysreg_restore_guest_state(guest_ctxt); | 262 | __sysreg_restore_guest_state(guest_ctxt); |
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index b0b225ceca18..e51367d159d0 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c | |||
@@ -823,14 +823,6 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, | |||
823 | * Architected system registers. | 823 | * Architected system registers. |
824 | * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2 | 824 | * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2 |
825 | * | 825 | * |
826 | * We could trap ID_DFR0 and tell the guest we don't support performance | ||
827 | * monitoring. Unfortunately the patch to make the kernel check ID_DFR0 was | ||
828 | * NAKed, so it will read the PMCR anyway. | ||
829 | * | ||
830 | * Therefore we tell the guest we have 0 counters. Unfortunately, we | ||
831 | * must always support PMCCNTR (the cycle counter): we just RAZ/WI for | ||
832 | * all PM registers, which doesn't crash the guest kernel at least. | ||
833 | * | ||
834 | * Debug handling: We do trap most, if not all debug related system | 826 | * Debug handling: We do trap most, if not all debug related system |
835 | * registers. The implementation is good enough to ensure that a guest | 827 | * registers. The implementation is good enough to ensure that a guest |
836 | * can use these with minimal performance degradation. The drawback is | 828 | * can use these with minimal performance degradation. The drawback is |
@@ -1360,7 +1352,7 @@ static const struct sys_reg_desc cp15_regs[] = { | |||
1360 | { Op1( 0), CRn(10), CRm( 3), Op2( 1), access_vm_reg, NULL, c10_AMAIR1 }, | 1352 | { Op1( 0), CRn(10), CRm( 3), Op2( 1), access_vm_reg, NULL, c10_AMAIR1 }, |
1361 | 1353 | ||
1362 | /* ICC_SRE */ | 1354 | /* ICC_SRE */ |
1363 | { Op1( 0), CRn(12), CRm(12), Op2( 5), trap_raz_wi }, | 1355 | { Op1( 0), CRn(12), CRm(12), Op2( 5), access_gic_sre }, |
1364 | 1356 | ||
1365 | { Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, c13_CID }, | 1357 | { Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, c13_CID }, |
1366 | 1358 | ||
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index 5bb61de23201..9d37e967fa19 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S | |||
@@ -100,7 +100,16 @@ ENTRY(cpu_do_resume) | |||
100 | 100 | ||
101 | msr tcr_el1, x8 | 101 | msr tcr_el1, x8 |
102 | msr vbar_el1, x9 | 102 | msr vbar_el1, x9 |
103 | |||
104 | /* | ||
105 | * __cpu_setup() cleared MDSCR_EL1.MDE and friends, before unmasking | ||
106 | * debug exceptions. By restoring MDSCR_EL1 here, we may take a debug | ||
107 | * exception. Mask them until local_dbg_restore() in cpu_suspend() | ||
108 | * resets them. | ||
109 | */ | ||
110 | disable_dbg | ||
103 | msr mdscr_el1, x10 | 111 | msr mdscr_el1, x10 |
112 | |||
104 | msr sctlr_el1, x12 | 113 | msr sctlr_el1, x12 |
105 | /* | 114 | /* |
106 | * Restore oslsr_el1 by writing oslar_el1 | 115 | * Restore oslsr_el1 by writing oslar_el1 |
diff --git a/arch/avr32/include/asm/uaccess.h b/arch/avr32/include/asm/uaccess.h index 68cf638faf48..b1ec1fa06463 100644 --- a/arch/avr32/include/asm/uaccess.h +++ b/arch/avr32/include/asm/uaccess.h | |||
@@ -74,7 +74,7 @@ extern __kernel_size_t __copy_user(void *to, const void *from, | |||
74 | 74 | ||
75 | extern __kernel_size_t copy_to_user(void __user *to, const void *from, | 75 | extern __kernel_size_t copy_to_user(void __user *to, const void *from, |
76 | __kernel_size_t n); | 76 | __kernel_size_t n); |
77 | extern __kernel_size_t copy_from_user(void *to, const void __user *from, | 77 | extern __kernel_size_t ___copy_from_user(void *to, const void __user *from, |
78 | __kernel_size_t n); | 78 | __kernel_size_t n); |
79 | 79 | ||
80 | static inline __kernel_size_t __copy_to_user(void __user *to, const void *from, | 80 | static inline __kernel_size_t __copy_to_user(void __user *to, const void *from, |
@@ -88,6 +88,15 @@ static inline __kernel_size_t __copy_from_user(void *to, | |||
88 | { | 88 | { |
89 | return __copy_user(to, (const void __force *)from, n); | 89 | return __copy_user(to, (const void __force *)from, n); |
90 | } | 90 | } |
91 | static inline __kernel_size_t copy_from_user(void *to, | ||
92 | const void __user *from, | ||
93 | __kernel_size_t n) | ||
94 | { | ||
95 | size_t res = ___copy_from_user(to, from, n); | ||
96 | if (unlikely(res)) | ||
97 | memset(to + (n - res), 0, res); | ||
98 | return res; | ||
99 | } | ||
91 | 100 | ||
92 | #define __copy_to_user_inatomic __copy_to_user | 101 | #define __copy_to_user_inatomic __copy_to_user |
93 | #define __copy_from_user_inatomic __copy_from_user | 102 | #define __copy_from_user_inatomic __copy_from_user |
diff --git a/arch/avr32/kernel/avr32_ksyms.c b/arch/avr32/kernel/avr32_ksyms.c index d93ead02daed..7c6cf14f0985 100644 --- a/arch/avr32/kernel/avr32_ksyms.c +++ b/arch/avr32/kernel/avr32_ksyms.c | |||
@@ -36,7 +36,7 @@ EXPORT_SYMBOL(copy_page); | |||
36 | /* | 36 | /* |
37 | * Userspace access stuff. | 37 | * Userspace access stuff. |
38 | */ | 38 | */ |
39 | EXPORT_SYMBOL(copy_from_user); | 39 | EXPORT_SYMBOL(___copy_from_user); |
40 | EXPORT_SYMBOL(copy_to_user); | 40 | EXPORT_SYMBOL(copy_to_user); |
41 | EXPORT_SYMBOL(__copy_user); | 41 | EXPORT_SYMBOL(__copy_user); |
42 | EXPORT_SYMBOL(strncpy_from_user); | 42 | EXPORT_SYMBOL(strncpy_from_user); |
diff --git a/arch/avr32/lib/copy_user.S b/arch/avr32/lib/copy_user.S index ea59c04b07de..075373471da1 100644 --- a/arch/avr32/lib/copy_user.S +++ b/arch/avr32/lib/copy_user.S | |||
@@ -23,13 +23,13 @@ | |||
23 | */ | 23 | */ |
24 | .text | 24 | .text |
25 | .align 1 | 25 | .align 1 |
26 | .global copy_from_user | 26 | .global ___copy_from_user |
27 | .type copy_from_user, @function | 27 | .type ___copy_from_user, @function |
28 | copy_from_user: | 28 | ___copy_from_user: |
29 | branch_if_kernel r8, __copy_user | 29 | branch_if_kernel r8, __copy_user |
30 | ret_if_privileged r8, r11, r10, r10 | 30 | ret_if_privileged r8, r11, r10, r10 |
31 | rjmp __copy_user | 31 | rjmp __copy_user |
32 | .size copy_from_user, . - copy_from_user | 32 | .size ___copy_from_user, . - ___copy_from_user |
33 | 33 | ||
34 | .global copy_to_user | 34 | .global copy_to_user |
35 | .type copy_to_user, @function | 35 | .type copy_to_user, @function |
diff --git a/arch/blackfin/include/asm/uaccess.h b/arch/blackfin/include/asm/uaccess.h index 12f5d6851bbc..0a2a70096d8b 100644 --- a/arch/blackfin/include/asm/uaccess.h +++ b/arch/blackfin/include/asm/uaccess.h | |||
@@ -171,11 +171,12 @@ static inline int bad_user_access_length(void) | |||
171 | static inline unsigned long __must_check | 171 | static inline unsigned long __must_check |
172 | copy_from_user(void *to, const void __user *from, unsigned long n) | 172 | copy_from_user(void *to, const void __user *from, unsigned long n) |
173 | { | 173 | { |
174 | if (access_ok(VERIFY_READ, from, n)) | 174 | if (likely(access_ok(VERIFY_READ, from, n))) { |
175 | memcpy(to, (const void __force *)from, n); | 175 | memcpy(to, (const void __force *)from, n); |
176 | else | 176 | return 0; |
177 | return n; | 177 | } |
178 | return 0; | 178 | memset(to, 0, n); |
179 | return n; | ||
179 | } | 180 | } |
180 | 181 | ||
181 | static inline unsigned long __must_check | 182 | static inline unsigned long __must_check |
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c index c6db52ba3a06..10c57771822d 100644 --- a/arch/blackfin/mach-bf561/boards/cm_bf561.c +++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c | |||
@@ -146,7 +146,8 @@ static struct platform_device hitachi_fb_device = { | |||
146 | #include <linux/smc91x.h> | 146 | #include <linux/smc91x.h> |
147 | 147 | ||
148 | static struct smc91x_platdata smc91x_info = { | 148 | static struct smc91x_platdata smc91x_info = { |
149 | .flags = SMC91X_USE_32BIT | SMC91X_NOWAIT, | 149 | .flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT | |
150 | SMC91X_NOWAIT, | ||
150 | .leda = RPC_LED_100_10, | 151 | .leda = RPC_LED_100_10, |
151 | .ledb = RPC_LED_TX_RX, | 152 | .ledb = RPC_LED_TX_RX, |
152 | }; | 153 | }; |
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c index f35525b55819..57d1c43726d9 100644 --- a/arch/blackfin/mach-bf561/boards/ezkit.c +++ b/arch/blackfin/mach-bf561/boards/ezkit.c | |||
@@ -134,7 +134,8 @@ static struct platform_device net2272_bfin_device = { | |||
134 | #include <linux/smc91x.h> | 134 | #include <linux/smc91x.h> |
135 | 135 | ||
136 | static struct smc91x_platdata smc91x_info = { | 136 | static struct smc91x_platdata smc91x_info = { |
137 | .flags = SMC91X_USE_32BIT | SMC91X_NOWAIT, | 137 | .flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT | |
138 | SMC91X_NOWAIT, | ||
138 | .leda = RPC_LED_100_10, | 139 | .leda = RPC_LED_100_10, |
139 | .ledb = RPC_LED_TX_RX, | 140 | .ledb = RPC_LED_TX_RX, |
140 | }; | 141 | }; |
diff --git a/arch/cris/include/asm/uaccess.h b/arch/cris/include/asm/uaccess.h index e3530d0f13ee..56c7d5750abd 100644 --- a/arch/cris/include/asm/uaccess.h +++ b/arch/cris/include/asm/uaccess.h | |||
@@ -194,30 +194,6 @@ extern unsigned long __copy_user(void __user *to, const void *from, unsigned lon | |||
194 | extern unsigned long __copy_user_zeroing(void *to, const void __user *from, unsigned long n); | 194 | extern unsigned long __copy_user_zeroing(void *to, const void __user *from, unsigned long n); |
195 | extern unsigned long __do_clear_user(void __user *to, unsigned long n); | 195 | extern unsigned long __do_clear_user(void __user *to, unsigned long n); |
196 | 196 | ||
197 | static inline unsigned long | ||
198 | __generic_copy_to_user(void __user *to, const void *from, unsigned long n) | ||
199 | { | ||
200 | if (access_ok(VERIFY_WRITE, to, n)) | ||
201 | return __copy_user(to, from, n); | ||
202 | return n; | ||
203 | } | ||
204 | |||
205 | static inline unsigned long | ||
206 | __generic_copy_from_user(void *to, const void __user *from, unsigned long n) | ||
207 | { | ||
208 | if (access_ok(VERIFY_READ, from, n)) | ||
209 | return __copy_user_zeroing(to, from, n); | ||
210 | return n; | ||
211 | } | ||
212 | |||
213 | static inline unsigned long | ||
214 | __generic_clear_user(void __user *to, unsigned long n) | ||
215 | { | ||
216 | if (access_ok(VERIFY_WRITE, to, n)) | ||
217 | return __do_clear_user(to, n); | ||
218 | return n; | ||
219 | } | ||
220 | |||
221 | static inline long | 197 | static inline long |
222 | __strncpy_from_user(char *dst, const char __user *src, long count) | 198 | __strncpy_from_user(char *dst, const char __user *src, long count) |
223 | { | 199 | { |
@@ -282,7 +258,7 @@ __constant_copy_from_user(void *to, const void __user *from, unsigned long n) | |||
282 | else if (n == 24) | 258 | else if (n == 24) |
283 | __asm_copy_from_user_24(to, from, ret); | 259 | __asm_copy_from_user_24(to, from, ret); |
284 | else | 260 | else |
285 | ret = __generic_copy_from_user(to, from, n); | 261 | ret = __copy_user_zeroing(to, from, n); |
286 | 262 | ||
287 | return ret; | 263 | return ret; |
288 | } | 264 | } |
@@ -333,7 +309,7 @@ __constant_copy_to_user(void __user *to, const void *from, unsigned long n) | |||
333 | else if (n == 24) | 309 | else if (n == 24) |
334 | __asm_copy_to_user_24(to, from, ret); | 310 | __asm_copy_to_user_24(to, from, ret); |
335 | else | 311 | else |
336 | ret = __generic_copy_to_user(to, from, n); | 312 | ret = __copy_user(to, from, n); |
337 | 313 | ||
338 | return ret; | 314 | return ret; |
339 | } | 315 | } |
@@ -366,26 +342,43 @@ __constant_clear_user(void __user *to, unsigned long n) | |||
366 | else if (n == 24) | 342 | else if (n == 24) |
367 | __asm_clear_24(to, ret); | 343 | __asm_clear_24(to, ret); |
368 | else | 344 | else |
369 | ret = __generic_clear_user(to, n); | 345 | ret = __do_clear_user(to, n); |
370 | 346 | ||
371 | return ret; | 347 | return ret; |
372 | } | 348 | } |
373 | 349 | ||
374 | 350 | ||
375 | #define clear_user(to, n) \ | 351 | static inline size_t clear_user(void __user *to, size_t n) |
376 | (__builtin_constant_p(n) ? \ | 352 | { |
377 | __constant_clear_user(to, n) : \ | 353 | if (unlikely(!access_ok(VERIFY_WRITE, to, n))) |
378 | __generic_clear_user(to, n)) | 354 | return n; |
355 | if (__builtin_constant_p(n)) | ||
356 | return __constant_clear_user(to, n); | ||
357 | else | ||
358 | return __do_clear_user(to, n); | ||
359 | } | ||
379 | 360 | ||
380 | #define copy_from_user(to, from, n) \ | 361 | static inline size_t copy_from_user(void *to, const void __user *from, size_t n) |
381 | (__builtin_constant_p(n) ? \ | 362 | { |
382 | __constant_copy_from_user(to, from, n) : \ | 363 | if (unlikely(!access_ok(VERIFY_READ, from, n))) { |
383 | __generic_copy_from_user(to, from, n)) | 364 | memset(to, 0, n); |
365 | return n; | ||
366 | } | ||
367 | if (__builtin_constant_p(n)) | ||
368 | return __constant_copy_from_user(to, from, n); | ||
369 | else | ||
370 | return __copy_user_zeroing(to, from, n); | ||
371 | } | ||
384 | 372 | ||
385 | #define copy_to_user(to, from, n) \ | 373 | static inline size_t copy_to_user(void __user *to, const void *from, size_t n) |
386 | (__builtin_constant_p(n) ? \ | 374 | { |
387 | __constant_copy_to_user(to, from, n) : \ | 375 | if (unlikely(!access_ok(VERIFY_WRITE, to, n))) |
388 | __generic_copy_to_user(to, from, n)) | 376 | return n; |
377 | if (__builtin_constant_p(n)) | ||
378 | return __constant_copy_to_user(to, from, n); | ||
379 | else | ||
380 | return __copy_user(to, from, n); | ||
381 | } | ||
389 | 382 | ||
390 | /* We let the __ versions of copy_from/to_user inline, because they're often | 383 | /* We let the __ versions of copy_from/to_user inline, because they're often |
391 | * used in fast paths and have only a small space overhead. | 384 | * used in fast paths and have only a small space overhead. |
diff --git a/arch/frv/include/asm/uaccess.h b/arch/frv/include/asm/uaccess.h index 3ac9a59d65d4..87d9e34c5df8 100644 --- a/arch/frv/include/asm/uaccess.h +++ b/arch/frv/include/asm/uaccess.h | |||
@@ -263,19 +263,25 @@ do { \ | |||
263 | extern long __memset_user(void *dst, unsigned long count); | 263 | extern long __memset_user(void *dst, unsigned long count); |
264 | extern long __memcpy_user(void *dst, const void *src, unsigned long count); | 264 | extern long __memcpy_user(void *dst, const void *src, unsigned long count); |
265 | 265 | ||
266 | #define clear_user(dst,count) __memset_user(____force(dst), (count)) | 266 | #define __clear_user(dst,count) __memset_user(____force(dst), (count)) |
267 | #define __copy_from_user_inatomic(to, from, n) __memcpy_user((to), ____force(from), (n)) | 267 | #define __copy_from_user_inatomic(to, from, n) __memcpy_user((to), ____force(from), (n)) |
268 | #define __copy_to_user_inatomic(to, from, n) __memcpy_user(____force(to), (from), (n)) | 268 | #define __copy_to_user_inatomic(to, from, n) __memcpy_user(____force(to), (from), (n)) |
269 | 269 | ||
270 | #else | 270 | #else |
271 | 271 | ||
272 | #define clear_user(dst,count) (memset(____force(dst), 0, (count)), 0) | 272 | #define __clear_user(dst,count) (memset(____force(dst), 0, (count)), 0) |
273 | #define __copy_from_user_inatomic(to, from, n) (memcpy((to), ____force(from), (n)), 0) | 273 | #define __copy_from_user_inatomic(to, from, n) (memcpy((to), ____force(from), (n)), 0) |
274 | #define __copy_to_user_inatomic(to, from, n) (memcpy(____force(to), (from), (n)), 0) | 274 | #define __copy_to_user_inatomic(to, from, n) (memcpy(____force(to), (from), (n)), 0) |
275 | 275 | ||
276 | #endif | 276 | #endif |
277 | 277 | ||
278 | #define __clear_user clear_user | 278 | static inline unsigned long __must_check |
279 | clear_user(void __user *to, unsigned long n) | ||
280 | { | ||
281 | if (likely(__access_ok(to, n))) | ||
282 | n = __clear_user(to, n); | ||
283 | return n; | ||
284 | } | ||
279 | 285 | ||
280 | static inline unsigned long __must_check | 286 | static inline unsigned long __must_check |
281 | __copy_to_user(void __user *to, const void *from, unsigned long n) | 287 | __copy_to_user(void __user *to, const void *from, unsigned long n) |
diff --git a/arch/hexagon/include/asm/uaccess.h b/arch/hexagon/include/asm/uaccess.h index f000a382bc7f..f61cfb28e9f2 100644 --- a/arch/hexagon/include/asm/uaccess.h +++ b/arch/hexagon/include/asm/uaccess.h | |||
@@ -103,7 +103,8 @@ static inline long hexagon_strncpy_from_user(char *dst, const char __user *src, | |||
103 | { | 103 | { |
104 | long res = __strnlen_user(src, n); | 104 | long res = __strnlen_user(src, n); |
105 | 105 | ||
106 | /* return from strnlen can't be zero -- that would be rubbish. */ | 106 | if (unlikely(!res)) |
107 | return -EFAULT; | ||
107 | 108 | ||
108 | if (res > n) { | 109 | if (res > n) { |
109 | copy_from_user(dst, src, n); | 110 | copy_from_user(dst, src, n); |
diff --git a/arch/ia64/include/asm/uaccess.h b/arch/ia64/include/asm/uaccess.h index 465c70982f40..bfe13196f770 100644 --- a/arch/ia64/include/asm/uaccess.h +++ b/arch/ia64/include/asm/uaccess.h | |||
@@ -241,8 +241,7 @@ extern unsigned long __must_check __copy_user (void __user *to, const void __use | |||
241 | static inline unsigned long | 241 | static inline unsigned long |
242 | __copy_to_user (void __user *to, const void *from, unsigned long count) | 242 | __copy_to_user (void __user *to, const void *from, unsigned long count) |
243 | { | 243 | { |
244 | if (!__builtin_constant_p(count)) | 244 | check_object_size(from, count, true); |
245 | check_object_size(from, count, true); | ||
246 | 245 | ||
247 | return __copy_user(to, (__force void __user *) from, count); | 246 | return __copy_user(to, (__force void __user *) from, count); |
248 | } | 247 | } |
@@ -250,8 +249,7 @@ __copy_to_user (void __user *to, const void *from, unsigned long count) | |||
250 | static inline unsigned long | 249 | static inline unsigned long |
251 | __copy_from_user (void *to, const void __user *from, unsigned long count) | 250 | __copy_from_user (void *to, const void __user *from, unsigned long count) |
252 | { | 251 | { |
253 | if (!__builtin_constant_p(count)) | 252 | check_object_size(to, count, false); |
254 | check_object_size(to, count, false); | ||
255 | 253 | ||
256 | return __copy_user((__force void __user *) to, from, count); | 254 | return __copy_user((__force void __user *) to, from, count); |
257 | } | 255 | } |
@@ -265,27 +263,22 @@ __copy_from_user (void *to, const void __user *from, unsigned long count) | |||
265 | long __cu_len = (n); \ | 263 | long __cu_len = (n); \ |
266 | \ | 264 | \ |
267 | if (__access_ok(__cu_to, __cu_len, get_fs())) { \ | 265 | if (__access_ok(__cu_to, __cu_len, get_fs())) { \ |
268 | if (!__builtin_constant_p(n)) \ | 266 | check_object_size(__cu_from, __cu_len, true); \ |
269 | check_object_size(__cu_from, __cu_len, true); \ | ||
270 | __cu_len = __copy_user(__cu_to, (__force void __user *) __cu_from, __cu_len); \ | 267 | __cu_len = __copy_user(__cu_to, (__force void __user *) __cu_from, __cu_len); \ |
271 | } \ | 268 | } \ |
272 | __cu_len; \ | 269 | __cu_len; \ |
273 | }) | 270 | }) |
274 | 271 | ||
275 | #define copy_from_user(to, from, n) \ | 272 | static inline unsigned long |
276 | ({ \ | 273 | copy_from_user(void *to, const void __user *from, unsigned long n) |
277 | void *__cu_to = (to); \ | 274 | { |
278 | const void __user *__cu_from = (from); \ | 275 | check_object_size(to, n, false); |
279 | long __cu_len = (n); \ | 276 | if (likely(__access_ok(from, n, get_fs()))) |
280 | \ | 277 | n = __copy_user((__force void __user *) to, from, n); |
281 | __chk_user_ptr(__cu_from); \ | 278 | else |
282 | if (__access_ok(__cu_from, __cu_len, get_fs())) { \ | 279 | memset(to, 0, n); |
283 | if (!__builtin_constant_p(n)) \ | 280 | return n; |
284 | check_object_size(__cu_to, __cu_len, false); \ | 281 | } |
285 | __cu_len = __copy_user((__force void __user *) __cu_to, __cu_from, __cu_len); \ | ||
286 | } \ | ||
287 | __cu_len; \ | ||
288 | }) | ||
289 | 282 | ||
290 | #define __copy_in_user(to, from, size) __copy_user((to), (from), (size)) | 283 | #define __copy_in_user(to, from, size) __copy_user((to), (from), (size)) |
291 | 284 | ||
diff --git a/arch/m32r/include/asm/uaccess.h b/arch/m32r/include/asm/uaccess.h index cac7014daef3..6f8982157a75 100644 --- a/arch/m32r/include/asm/uaccess.h +++ b/arch/m32r/include/asm/uaccess.h | |||
@@ -219,7 +219,7 @@ extern int fixup_exception(struct pt_regs *regs); | |||
219 | #define __get_user_nocheck(x, ptr, size) \ | 219 | #define __get_user_nocheck(x, ptr, size) \ |
220 | ({ \ | 220 | ({ \ |
221 | long __gu_err = 0; \ | 221 | long __gu_err = 0; \ |
222 | unsigned long __gu_val; \ | 222 | unsigned long __gu_val = 0; \ |
223 | might_fault(); \ | 223 | might_fault(); \ |
224 | __get_user_size(__gu_val, (ptr), (size), __gu_err); \ | 224 | __get_user_size(__gu_val, (ptr), (size), __gu_err); \ |
225 | (x) = (__force __typeof__(*(ptr)))__gu_val; \ | 225 | (x) = (__force __typeof__(*(ptr)))__gu_val; \ |
diff --git a/arch/metag/include/asm/uaccess.h b/arch/metag/include/asm/uaccess.h index 8282cbce7e39..273e61225c27 100644 --- a/arch/metag/include/asm/uaccess.h +++ b/arch/metag/include/asm/uaccess.h | |||
@@ -204,8 +204,9 @@ extern unsigned long __must_check __copy_user_zeroing(void *to, | |||
204 | static inline unsigned long | 204 | static inline unsigned long |
205 | copy_from_user(void *to, const void __user *from, unsigned long n) | 205 | copy_from_user(void *to, const void __user *from, unsigned long n) |
206 | { | 206 | { |
207 | if (access_ok(VERIFY_READ, from, n)) | 207 | if (likely(access_ok(VERIFY_READ, from, n))) |
208 | return __copy_user_zeroing(to, from, n); | 208 | return __copy_user_zeroing(to, from, n); |
209 | memset(to, 0, n); | ||
209 | return n; | 210 | return n; |
210 | } | 211 | } |
211 | 212 | ||
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h index 331b0d35f89c..826676778094 100644 --- a/arch/microblaze/include/asm/uaccess.h +++ b/arch/microblaze/include/asm/uaccess.h | |||
@@ -227,7 +227,7 @@ extern long __user_bad(void); | |||
227 | 227 | ||
228 | #define __get_user(x, ptr) \ | 228 | #define __get_user(x, ptr) \ |
229 | ({ \ | 229 | ({ \ |
230 | unsigned long __gu_val; \ | 230 | unsigned long __gu_val = 0; \ |
231 | /*unsigned long __gu_ptr = (unsigned long)(ptr);*/ \ | 231 | /*unsigned long __gu_ptr = (unsigned long)(ptr);*/ \ |
232 | long __gu_err; \ | 232 | long __gu_err; \ |
233 | switch (sizeof(*(ptr))) { \ | 233 | switch (sizeof(*(ptr))) { \ |
@@ -373,10 +373,13 @@ extern long __user_bad(void); | |||
373 | static inline long copy_from_user(void *to, | 373 | static inline long copy_from_user(void *to, |
374 | const void __user *from, unsigned long n) | 374 | const void __user *from, unsigned long n) |
375 | { | 375 | { |
376 | unsigned long res = n; | ||
376 | might_fault(); | 377 | might_fault(); |
377 | if (access_ok(VERIFY_READ, from, n)) | 378 | if (likely(access_ok(VERIFY_READ, from, n))) |
378 | return __copy_from_user(to, from, n); | 379 | res = __copy_from_user(to, from, n); |
379 | return n; | 380 | if (unlikely(res)) |
381 | memset(to + (n - res), 0, res); | ||
382 | return res; | ||
380 | } | 383 | } |
381 | 384 | ||
382 | #define __copy_to_user(to, from, n) \ | 385 | #define __copy_to_user(to, from, n) \ |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 26388562e300..212ff92920d2 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -65,6 +65,7 @@ config MIPS | |||
65 | select ARCH_CLOCKSOURCE_DATA | 65 | select ARCH_CLOCKSOURCE_DATA |
66 | select HANDLE_DOMAIN_IRQ | 66 | select HANDLE_DOMAIN_IRQ |
67 | select HAVE_EXIT_THREAD | 67 | select HAVE_EXIT_THREAD |
68 | select HAVE_REGS_AND_STACK_ACCESS_API | ||
68 | 69 | ||
69 | menu "Machine selection" | 70 | menu "Machine selection" |
70 | 71 | ||
diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug index f0e314ceb8ba..7f975b20b20c 100644 --- a/arch/mips/Kconfig.debug +++ b/arch/mips/Kconfig.debug | |||
@@ -113,42 +113,6 @@ config SPINLOCK_TEST | |||
113 | help | 113 | help |
114 | Add several files to the debugfs to test spinlock speed. | 114 | Add several files to the debugfs to test spinlock speed. |
115 | 115 | ||
116 | if CPU_MIPSR6 | ||
117 | |||
118 | choice | ||
119 | prompt "Compact branch policy" | ||
120 | default MIPS_COMPACT_BRANCHES_OPTIMAL | ||
121 | |||
122 | config MIPS_COMPACT_BRANCHES_NEVER | ||
123 | bool "Never (force delay slot branches)" | ||
124 | help | ||
125 | Pass the -mcompact-branches=never flag to the compiler in order to | ||
126 | force it to always emit branches with delay slots, and make no use | ||
127 | of the compact branch instructions introduced by MIPSr6. This is | ||
128 | useful if you suspect there may be an issue with compact branches in | ||
129 | either the compiler or the CPU. | ||
130 | |||
131 | config MIPS_COMPACT_BRANCHES_OPTIMAL | ||
132 | bool "Optimal (use where beneficial)" | ||
133 | help | ||
134 | Pass the -mcompact-branches=optimal flag to the compiler in order for | ||
135 | it to make use of compact branch instructions where it deems them | ||
136 | beneficial, and use branches with delay slots elsewhere. This is the | ||
137 | default compiler behaviour, and should be used unless you have a | ||
138 | reason to choose otherwise. | ||
139 | |||
140 | config MIPS_COMPACT_BRANCHES_ALWAYS | ||
141 | bool "Always (force compact branches)" | ||
142 | help | ||
143 | Pass the -mcompact-branches=always flag to the compiler in order to | ||
144 | force it to always emit compact branches, making no use of branch | ||
145 | instructions with delay slots. This can result in more compact code | ||
146 | which may be beneficial in some scenarios. | ||
147 | |||
148 | endchoice | ||
149 | |||
150 | endif # CPU_MIPSR6 | ||
151 | |||
152 | config SCACHE_DEBUGFS | 116 | config SCACHE_DEBUGFS |
153 | bool "L2 cache debugfs entries" | 117 | bool "L2 cache debugfs entries" |
154 | depends on DEBUG_FS | 118 | depends on DEBUG_FS |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index efd7a9dc93c4..598ab2930fce 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -203,10 +203,6 @@ endif | |||
203 | toolchain-virt := $(call cc-option-yn,$(mips-cflags) -mvirt) | 203 | toolchain-virt := $(call cc-option-yn,$(mips-cflags) -mvirt) |
204 | cflags-$(toolchain-virt) += -DTOOLCHAIN_SUPPORTS_VIRT | 204 | cflags-$(toolchain-virt) += -DTOOLCHAIN_SUPPORTS_VIRT |
205 | 205 | ||
206 | cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_NEVER) += -mcompact-branches=never | ||
207 | cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_OPTIMAL) += -mcompact-branches=optimal | ||
208 | cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_ALWAYS) += -mcompact-branches=always | ||
209 | |||
210 | # | 206 | # |
211 | # Firmware support | 207 | # Firmware support |
212 | # | 208 | # |
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c index 2e7378467c5c..cc3a1e33a600 100644 --- a/arch/mips/ath79/clock.c +++ b/arch/mips/ath79/clock.c | |||
@@ -96,7 +96,7 @@ static struct clk * __init ath79_reg_ffclk(const char *name, | |||
96 | struct clk *clk; | 96 | struct clk *clk; |
97 | 97 | ||
98 | clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mult, div); | 98 | clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mult, div); |
99 | if (!clk) | 99 | if (IS_ERR(clk)) |
100 | panic("failed to allocate %s clock structure", name); | 100 | panic("failed to allocate %s clock structure", name); |
101 | 101 | ||
102 | return clk; | 102 | return clk; |
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c index b31fbc9d6eae..37a932d9148c 100644 --- a/arch/mips/cavium-octeon/octeon-platform.c +++ b/arch/mips/cavium-octeon/octeon-platform.c | |||
@@ -1059,7 +1059,7 @@ static int __init octeon_publish_devices(void) | |||
1059 | { | 1059 | { |
1060 | return of_platform_bus_probe(NULL, octeon_ids, NULL); | 1060 | return of_platform_bus_probe(NULL, octeon_ids, NULL); |
1061 | } | 1061 | } |
1062 | device_initcall(octeon_publish_devices); | 1062 | arch_initcall(octeon_publish_devices); |
1063 | 1063 | ||
1064 | MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>"); | 1064 | MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>"); |
1065 | MODULE_LICENSE("GPL"); | 1065 | MODULE_LICENSE("GPL"); |
diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h index 56584a659183..83054f79f72a 100644 --- a/arch/mips/include/asm/asmmacro.h +++ b/arch/mips/include/asm/asmmacro.h | |||
@@ -157,6 +157,7 @@ | |||
157 | ldc1 $f28, THREAD_FPR28(\thread) | 157 | ldc1 $f28, THREAD_FPR28(\thread) |
158 | ldc1 $f30, THREAD_FPR30(\thread) | 158 | ldc1 $f30, THREAD_FPR30(\thread) |
159 | ctc1 \tmp, fcr31 | 159 | ctc1 \tmp, fcr31 |
160 | .set pop | ||
160 | .endm | 161 | .endm |
161 | 162 | ||
162 | .macro fpu_restore_16odd thread | 163 | .macro fpu_restore_16odd thread |
diff --git a/arch/mips/include/asm/mach-cavium-octeon/mangle-port.h b/arch/mips/include/asm/mach-cavium-octeon/mangle-port.h index 0cf5ac1f7245..8ff2cbdf2c3e 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/mangle-port.h +++ b/arch/mips/include/asm/mach-cavium-octeon/mangle-port.h | |||
@@ -15,8 +15,8 @@ | |||
15 | static inline bool __should_swizzle_bits(volatile void *a) | 15 | static inline bool __should_swizzle_bits(volatile void *a) |
16 | { | 16 | { |
17 | extern const bool octeon_should_swizzle_table[]; | 17 | extern const bool octeon_should_swizzle_table[]; |
18 | u64 did = ((u64)(uintptr_t)a >> 40) & 0xff; | ||
18 | 19 | ||
19 | unsigned long did = ((unsigned long)a >> 40) & 0xff; | ||
20 | return octeon_should_swizzle_table[did]; | 20 | return octeon_should_swizzle_table[did]; |
21 | } | 21 | } |
22 | 22 | ||
@@ -29,7 +29,7 @@ static inline bool __should_swizzle_bits(volatile void *a) | |||
29 | 29 | ||
30 | #define __should_swizzle_bits(a) false | 30 | #define __should_swizzle_bits(a) false |
31 | 31 | ||
32 | static inline bool __should_swizzle_addr(unsigned long p) | 32 | static inline bool __should_swizzle_addr(u64 p) |
33 | { | 33 | { |
34 | /* boot bus? */ | 34 | /* boot bus? */ |
35 | return ((p >> 40) & 0xff) == 0; | 35 | return ((p >> 40) & 0xff) == 0; |
diff --git a/arch/mips/include/asm/mach-paravirt/kernel-entry-init.h b/arch/mips/include/asm/mach-paravirt/kernel-entry-init.h index 2f82bfa3a773..c9f5769dfc8f 100644 --- a/arch/mips/include/asm/mach-paravirt/kernel-entry-init.h +++ b/arch/mips/include/asm/mach-paravirt/kernel-entry-init.h | |||
@@ -11,11 +11,13 @@ | |||
11 | #define CP0_EBASE $15, 1 | 11 | #define CP0_EBASE $15, 1 |
12 | 12 | ||
13 | .macro kernel_entry_setup | 13 | .macro kernel_entry_setup |
14 | #ifdef CONFIG_SMP | ||
14 | mfc0 t0, CP0_EBASE | 15 | mfc0 t0, CP0_EBASE |
15 | andi t0, t0, 0x3ff # CPUNum | 16 | andi t0, t0, 0x3ff # CPUNum |
16 | beqz t0, 1f | 17 | beqz t0, 1f |
17 | # CPUs other than zero goto smp_bootstrap | 18 | # CPUs other than zero goto smp_bootstrap |
18 | j smp_bootstrap | 19 | j smp_bootstrap |
20 | #endif /* CONFIG_SMP */ | ||
19 | 21 | ||
20 | 1: | 22 | 1: |
21 | .endm | 23 | .endm |
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index ea0cd9773914..5f987598054f 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h | |||
@@ -164,7 +164,7 @@ typedef struct { unsigned long pgprot; } pgprot_t; | |||
164 | */ | 164 | */ |
165 | static inline unsigned long ___pa(unsigned long x) | 165 | static inline unsigned long ___pa(unsigned long x) |
166 | { | 166 | { |
167 | if (config_enabled(CONFIG_64BIT)) { | 167 | if (IS_ENABLED(CONFIG_64BIT)) { |
168 | /* | 168 | /* |
169 | * For MIPS64 the virtual address may either be in one of | 169 | * For MIPS64 the virtual address may either be in one of |
170 | * the compatibility segements ckseg0 or ckseg1, or it may | 170 | * the compatibility segements ckseg0 or ckseg1, or it may |
@@ -173,7 +173,7 @@ static inline unsigned long ___pa(unsigned long x) | |||
173 | return x < CKSEG0 ? XPHYSADDR(x) : CPHYSADDR(x); | 173 | return x < CKSEG0 ? XPHYSADDR(x) : CPHYSADDR(x); |
174 | } | 174 | } |
175 | 175 | ||
176 | if (!config_enabled(CONFIG_EVA)) { | 176 | if (!IS_ENABLED(CONFIG_EVA)) { |
177 | /* | 177 | /* |
178 | * We're using the standard MIPS32 legacy memory map, ie. | 178 | * We're using the standard MIPS32 legacy memory map, ie. |
179 | * the address x is going to be in kseg0 or kseg1. We can | 179 | * the address x is going to be in kseg0 or kseg1. We can |
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index 11b965f98d95..21a2aaba20d5 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
16 | #include <linux/thread_info.h> | 16 | #include <linux/thread_info.h> |
17 | #include <linux/string.h> | ||
17 | #include <asm/asm-eva.h> | 18 | #include <asm/asm-eva.h> |
18 | 19 | ||
19 | /* | 20 | /* |
@@ -1170,6 +1171,8 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n); | |||
1170 | __cu_len = __invoke_copy_from_user(__cu_to, \ | 1171 | __cu_len = __invoke_copy_from_user(__cu_to, \ |
1171 | __cu_from, \ | 1172 | __cu_from, \ |
1172 | __cu_len); \ | 1173 | __cu_len); \ |
1174 | } else { \ | ||
1175 | memset(__cu_to, 0, __cu_len); \ | ||
1173 | } \ | 1176 | } \ |
1174 | } \ | 1177 | } \ |
1175 | __cu_len; \ | 1178 | __cu_len; \ |
diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c index c3372cac6db2..0a7e10b5f9e3 100644 --- a/arch/mips/kernel/mips-r2-to-r6-emul.c +++ b/arch/mips/kernel/mips-r2-to-r6-emul.c | |||
@@ -1164,7 +1164,9 @@ fpu_emul: | |||
1164 | regs->regs[31] = r31; | 1164 | regs->regs[31] = r31; |
1165 | regs->cp0_epc = epc; | 1165 | regs->cp0_epc = epc; |
1166 | if (!used_math()) { /* First time FPU user. */ | 1166 | if (!used_math()) { /* First time FPU user. */ |
1167 | preempt_disable(); | ||
1167 | err = init_fpu(); | 1168 | err = init_fpu(); |
1169 | preempt_enable(); | ||
1168 | set_used_math(); | 1170 | set_used_math(); |
1169 | } | 1171 | } |
1170 | lose_fpu(1); /* Save FPU state for the emulator. */ | 1172 | lose_fpu(1); /* Save FPU state for the emulator. */ |
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 7429ad09fbe3..d2d061520a23 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -605,14 +605,14 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value) | |||
605 | return -EOPNOTSUPP; | 605 | return -EOPNOTSUPP; |
606 | 606 | ||
607 | /* Avoid inadvertently triggering emulation */ | 607 | /* Avoid inadvertently triggering emulation */ |
608 | if ((value & PR_FP_MODE_FR) && cpu_has_fpu && | 608 | if ((value & PR_FP_MODE_FR) && raw_cpu_has_fpu && |
609 | !(current_cpu_data.fpu_id & MIPS_FPIR_F64)) | 609 | !(raw_current_cpu_data.fpu_id & MIPS_FPIR_F64)) |
610 | return -EOPNOTSUPP; | 610 | return -EOPNOTSUPP; |
611 | if ((value & PR_FP_MODE_FRE) && cpu_has_fpu && !cpu_has_fre) | 611 | if ((value & PR_FP_MODE_FRE) && raw_cpu_has_fpu && !cpu_has_fre) |
612 | return -EOPNOTSUPP; | 612 | return -EOPNOTSUPP; |
613 | 613 | ||
614 | /* FR = 0 not supported in MIPS R6 */ | 614 | /* FR = 0 not supported in MIPS R6 */ |
615 | if (!(value & PR_FP_MODE_FR) && cpu_has_fpu && cpu_has_mips_r6) | 615 | if (!(value & PR_FP_MODE_FR) && raw_cpu_has_fpu && cpu_has_mips_r6) |
616 | return -EOPNOTSUPP; | 616 | return -EOPNOTSUPP; |
617 | 617 | ||
618 | /* Proceed with the mode switch */ | 618 | /* Proceed with the mode switch */ |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 36cf8d65c47d..3be0e6ba2797 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -87,6 +87,13 @@ void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type) | |||
87 | int x = boot_mem_map.nr_map; | 87 | int x = boot_mem_map.nr_map; |
88 | int i; | 88 | int i; |
89 | 89 | ||
90 | /* | ||
91 | * If the region reaches the top of the physical address space, adjust | ||
92 | * the size slightly so that (start + size) doesn't overflow | ||
93 | */ | ||
94 | if (start + size - 1 == (phys_addr_t)ULLONG_MAX) | ||
95 | --size; | ||
96 | |||
90 | /* Sanity check */ | 97 | /* Sanity check */ |
91 | if (start + size < start) { | 98 | if (start + size < start) { |
92 | pr_warn("Trying to add an invalid memory region, skipped\n"); | 99 | pr_warn("Trying to add an invalid memory region, skipped\n"); |
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index f95f094f36e4..b0baf48951fa 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -322,6 +322,9 @@ asmlinkage void start_secondary(void) | |||
322 | cpumask_set_cpu(cpu, &cpu_coherent_mask); | 322 | cpumask_set_cpu(cpu, &cpu_coherent_mask); |
323 | notify_cpu_starting(cpu); | 323 | notify_cpu_starting(cpu); |
324 | 324 | ||
325 | cpumask_set_cpu(cpu, &cpu_callin_map); | ||
326 | synchronise_count_slave(cpu); | ||
327 | |||
325 | set_cpu_online(cpu, true); | 328 | set_cpu_online(cpu, true); |
326 | 329 | ||
327 | set_cpu_sibling_map(cpu); | 330 | set_cpu_sibling_map(cpu); |
@@ -329,10 +332,6 @@ asmlinkage void start_secondary(void) | |||
329 | 332 | ||
330 | calculate_cpu_foreign_map(); | 333 | calculate_cpu_foreign_map(); |
331 | 334 | ||
332 | cpumask_set_cpu(cpu, &cpu_callin_map); | ||
333 | |||
334 | synchronise_count_slave(cpu); | ||
335 | |||
336 | /* | 335 | /* |
337 | * irq will be enabled in ->smp_finish(), enabling it too early | 336 | * irq will be enabled in ->smp_finish(), enabling it too early |
338 | * is dangerous. | 337 | * is dangerous. |
diff --git a/arch/mips/kernel/uprobes.c b/arch/mips/kernel/uprobes.c index 8452d933a645..1149b30c9aeb 100644 --- a/arch/mips/kernel/uprobes.c +++ b/arch/mips/kernel/uprobes.c | |||
@@ -222,7 +222,7 @@ int arch_uprobe_exception_notify(struct notifier_block *self, | |||
222 | return NOTIFY_DONE; | 222 | return NOTIFY_DONE; |
223 | 223 | ||
224 | switch (val) { | 224 | switch (val) { |
225 | case DIE_BREAK: | 225 | case DIE_UPROBE: |
226 | if (uprobe_pre_sstep_notifier(regs)) | 226 | if (uprobe_pre_sstep_notifier(regs)) |
227 | return NOTIFY_STOP; | 227 | return NOTIFY_STOP; |
228 | break; | 228 | break; |
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c index 9abe447a4b48..f9dbfb14af33 100644 --- a/arch/mips/kernel/vdso.c +++ b/arch/mips/kernel/vdso.c | |||
@@ -39,16 +39,16 @@ static struct vm_special_mapping vdso_vvar_mapping = { | |||
39 | static void __init init_vdso_image(struct mips_vdso_image *image) | 39 | static void __init init_vdso_image(struct mips_vdso_image *image) |
40 | { | 40 | { |
41 | unsigned long num_pages, i; | 41 | unsigned long num_pages, i; |
42 | unsigned long data_pfn; | ||
42 | 43 | ||
43 | BUG_ON(!PAGE_ALIGNED(image->data)); | 44 | BUG_ON(!PAGE_ALIGNED(image->data)); |
44 | BUG_ON(!PAGE_ALIGNED(image->size)); | 45 | BUG_ON(!PAGE_ALIGNED(image->size)); |
45 | 46 | ||
46 | num_pages = image->size / PAGE_SIZE; | 47 | num_pages = image->size / PAGE_SIZE; |
47 | 48 | ||
48 | for (i = 0; i < num_pages; i++) { | 49 | data_pfn = __phys_to_pfn(__pa_symbol(image->data)); |
49 | image->mapping.pages[i] = | 50 | for (i = 0; i < num_pages; i++) |
50 | virt_to_page(image->data + (i * PAGE_SIZE)); | 51 | image->mapping.pages[i] = pfn_to_page(data_pfn + i); |
51 | } | ||
52 | } | 52 | } |
53 | 53 | ||
54 | static int __init init_vdso(void) | 54 | static int __init init_vdso(void) |
diff --git a/arch/mips/kvm/mmu.c b/arch/mips/kvm/mmu.c index 6cfdcf55572d..121008c0fcc9 100644 --- a/arch/mips/kvm/mmu.c +++ b/arch/mips/kvm/mmu.c | |||
@@ -40,7 +40,7 @@ static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) | |||
40 | srcu_idx = srcu_read_lock(&kvm->srcu); | 40 | srcu_idx = srcu_read_lock(&kvm->srcu); |
41 | pfn = gfn_to_pfn(kvm, gfn); | 41 | pfn = gfn_to_pfn(kvm, gfn); |
42 | 42 | ||
43 | if (is_error_pfn(pfn)) { | 43 | if (is_error_noslot_pfn(pfn)) { |
44 | kvm_err("Couldn't get pfn for gfn %#llx!\n", gfn); | 44 | kvm_err("Couldn't get pfn for gfn %#llx!\n", gfn); |
45 | err = -EFAULT; | 45 | err = -EFAULT; |
46 | goto out; | 46 | goto out; |
diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c index 72a4642eee2c..4a094f7acb3d 100644 --- a/arch/mips/math-emu/dsemul.c +++ b/arch/mips/math-emu/dsemul.c | |||
@@ -298,5 +298,6 @@ bool do_dsemulret(struct pt_regs *xcp) | |||
298 | /* Set EPC to return to post-branch instruction */ | 298 | /* Set EPC to return to post-branch instruction */ |
299 | xcp->cp0_epc = current->thread.bd_emu_cont_pc; | 299 | xcp->cp0_epc = current->thread.bd_emu_cont_pc; |
300 | pr_debug("dsemulret to 0x%08lx\n", xcp->cp0_epc); | 300 | pr_debug("dsemulret to 0x%08lx\n", xcp->cp0_epc); |
301 | MIPS_FPU_EMU_INC_STATS(ds_emul); | ||
301 | return true; | 302 | return true; |
302 | } | 303 | } |
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index cd72805b64a7..fa7d8d3790bf 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -800,7 +800,7 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) | |||
800 | * If address-based cache ops don't require an SMP call, then | 800 | * If address-based cache ops don't require an SMP call, then |
801 | * use them exclusively for small flushes. | 801 | * use them exclusively for small flushes. |
802 | */ | 802 | */ |
803 | size = start - end; | 803 | size = end - start; |
804 | cache_size = icache_size; | 804 | cache_size = icache_size; |
805 | if (!cpu_has_ic_fills_f_dc) { | 805 | if (!cpu_has_ic_fills_f_dc) { |
806 | size *= 2; | 806 | size *= 2; |
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index a5509e7dcad2..2c3749d98f04 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -261,7 +261,6 @@ unsigned __weak platform_maar_init(unsigned num_pairs) | |||
261 | { | 261 | { |
262 | struct maar_config cfg[BOOT_MEM_MAP_MAX]; | 262 | struct maar_config cfg[BOOT_MEM_MAP_MAX]; |
263 | unsigned i, num_configured, num_cfg = 0; | 263 | unsigned i, num_configured, num_cfg = 0; |
264 | phys_addr_t skip; | ||
265 | 264 | ||
266 | for (i = 0; i < boot_mem_map.nr_map; i++) { | 265 | for (i = 0; i < boot_mem_map.nr_map; i++) { |
267 | switch (boot_mem_map.map[i].type) { | 266 | switch (boot_mem_map.map[i].type) { |
@@ -272,14 +271,14 @@ unsigned __weak platform_maar_init(unsigned num_pairs) | |||
272 | continue; | 271 | continue; |
273 | } | 272 | } |
274 | 273 | ||
275 | skip = 0x10000 - (boot_mem_map.map[i].addr & 0xffff); | 274 | /* Round lower up */ |
276 | |||
277 | cfg[num_cfg].lower = boot_mem_map.map[i].addr; | 275 | cfg[num_cfg].lower = boot_mem_map.map[i].addr; |
278 | cfg[num_cfg].lower += skip; | 276 | cfg[num_cfg].lower = (cfg[num_cfg].lower + 0xffff) & ~0xffff; |
279 | 277 | ||
280 | cfg[num_cfg].upper = cfg[num_cfg].lower; | 278 | /* Round upper down */ |
281 | cfg[num_cfg].upper += boot_mem_map.map[i].size - 1; | 279 | cfg[num_cfg].upper = boot_mem_map.map[i].addr + |
282 | cfg[num_cfg].upper -= skip; | 280 | boot_mem_map.map[i].size; |
281 | cfg[num_cfg].upper = (cfg[num_cfg].upper & ~0xffff) - 1; | ||
283 | 282 | ||
284 | cfg[num_cfg].attrs = MIPS_MAAR_S; | 283 | cfg[num_cfg].attrs = MIPS_MAAR_S; |
285 | num_cfg++; | 284 | num_cfg++; |
diff --git a/arch/mn10300/include/asm/uaccess.h b/arch/mn10300/include/asm/uaccess.h index 20f7bf6de384..d012e877a95a 100644 --- a/arch/mn10300/include/asm/uaccess.h +++ b/arch/mn10300/include/asm/uaccess.h | |||
@@ -166,6 +166,7 @@ struct __large_struct { unsigned long buf[100]; }; | |||
166 | "2:\n" \ | 166 | "2:\n" \ |
167 | " .section .fixup,\"ax\"\n" \ | 167 | " .section .fixup,\"ax\"\n" \ |
168 | "3:\n\t" \ | 168 | "3:\n\t" \ |
169 | " mov 0,%1\n" \ | ||
169 | " mov %3,%0\n" \ | 170 | " mov %3,%0\n" \ |
170 | " jmp 2b\n" \ | 171 | " jmp 2b\n" \ |
171 | " .previous\n" \ | 172 | " .previous\n" \ |
diff --git a/arch/mn10300/lib/usercopy.c b/arch/mn10300/lib/usercopy.c index 7826e6c364e7..ce8899e5e171 100644 --- a/arch/mn10300/lib/usercopy.c +++ b/arch/mn10300/lib/usercopy.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * as published by the Free Software Foundation; either version | 9 | * as published by the Free Software Foundation; either version |
10 | * 2 of the Licence, or (at your option) any later version. | 10 | * 2 of the Licence, or (at your option) any later version. |
11 | */ | 11 | */ |
12 | #include <asm/uaccess.h> | 12 | #include <linux/uaccess.h> |
13 | 13 | ||
14 | unsigned long | 14 | unsigned long |
15 | __generic_copy_to_user(void *to, const void *from, unsigned long n) | 15 | __generic_copy_to_user(void *to, const void *from, unsigned long n) |
@@ -24,6 +24,8 @@ __generic_copy_from_user(void *to, const void *from, unsigned long n) | |||
24 | { | 24 | { |
25 | if (access_ok(VERIFY_READ, from, n)) | 25 | if (access_ok(VERIFY_READ, from, n)) |
26 | __copy_user_zeroing(to, from, n); | 26 | __copy_user_zeroing(to, from, n); |
27 | else | ||
28 | memset(to, 0, n); | ||
27 | return n; | 29 | return n; |
28 | } | 30 | } |
29 | 31 | ||
diff --git a/arch/nios2/include/asm/uaccess.h b/arch/nios2/include/asm/uaccess.h index caa51ff85a3c..0ab82324c817 100644 --- a/arch/nios2/include/asm/uaccess.h +++ b/arch/nios2/include/asm/uaccess.h | |||
@@ -102,9 +102,12 @@ extern long __copy_to_user(void __user *to, const void *from, unsigned long n); | |||
102 | static inline long copy_from_user(void *to, const void __user *from, | 102 | static inline long copy_from_user(void *to, const void __user *from, |
103 | unsigned long n) | 103 | unsigned long n) |
104 | { | 104 | { |
105 | if (!access_ok(VERIFY_READ, from, n)) | 105 | unsigned long res = n; |
106 | return n; | 106 | if (access_ok(VERIFY_READ, from, n)) |
107 | return __copy_from_user(to, from, n); | 107 | res = __copy_from_user(to, from, n); |
108 | if (unlikely(res)) | ||
109 | memset(to + (n - res), 0, res); | ||
110 | return res; | ||
108 | } | 111 | } |
109 | 112 | ||
110 | static inline long copy_to_user(void __user *to, const void *from, | 113 | static inline long copy_to_user(void __user *to, const void *from, |
@@ -139,7 +142,7 @@ extern long strnlen_user(const char __user *s, long n); | |||
139 | 142 | ||
140 | #define __get_user_unknown(val, size, ptr, err) do { \ | 143 | #define __get_user_unknown(val, size, ptr, err) do { \ |
141 | err = 0; \ | 144 | err = 0; \ |
142 | if (copy_from_user(&(val), ptr, size)) { \ | 145 | if (__copy_from_user(&(val), ptr, size)) { \ |
143 | err = -EFAULT; \ | 146 | err = -EFAULT; \ |
144 | } \ | 147 | } \ |
145 | } while (0) | 148 | } while (0) |
@@ -166,7 +169,7 @@ do { \ | |||
166 | ({ \ | 169 | ({ \ |
167 | long __gu_err = -EFAULT; \ | 170 | long __gu_err = -EFAULT; \ |
168 | const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ | 171 | const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ |
169 | unsigned long __gu_val; \ | 172 | unsigned long __gu_val = 0; \ |
170 | __get_user_common(__gu_val, sizeof(*(ptr)), __gu_ptr, __gu_err);\ | 173 | __get_user_common(__gu_val, sizeof(*(ptr)), __gu_ptr, __gu_err);\ |
171 | (x) = (__force __typeof__(x))__gu_val; \ | 174 | (x) = (__force __typeof__(x))__gu_val; \ |
172 | __gu_err; \ | 175 | __gu_err; \ |
diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h index a6bd07ca3d6c..5cc6b4f1b795 100644 --- a/arch/openrisc/include/asm/uaccess.h +++ b/arch/openrisc/include/asm/uaccess.h | |||
@@ -273,28 +273,20 @@ __copy_tofrom_user(void *to, const void *from, unsigned long size); | |||
273 | static inline unsigned long | 273 | static inline unsigned long |
274 | copy_from_user(void *to, const void *from, unsigned long n) | 274 | copy_from_user(void *to, const void *from, unsigned long n) |
275 | { | 275 | { |
276 | unsigned long over; | 276 | unsigned long res = n; |
277 | 277 | ||
278 | if (access_ok(VERIFY_READ, from, n)) | 278 | if (likely(access_ok(VERIFY_READ, from, n))) |
279 | return __copy_tofrom_user(to, from, n); | 279 | res = __copy_tofrom_user(to, from, n); |
280 | if ((unsigned long)from < TASK_SIZE) { | 280 | if (unlikely(res)) |
281 | over = (unsigned long)from + n - TASK_SIZE; | 281 | memset(to + (n - res), 0, res); |
282 | return __copy_tofrom_user(to, from, n - over) + over; | 282 | return res; |
283 | } | ||
284 | return n; | ||
285 | } | 283 | } |
286 | 284 | ||
287 | static inline unsigned long | 285 | static inline unsigned long |
288 | copy_to_user(void *to, const void *from, unsigned long n) | 286 | copy_to_user(void *to, const void *from, unsigned long n) |
289 | { | 287 | { |
290 | unsigned long over; | 288 | if (likely(access_ok(VERIFY_WRITE, to, n))) |
291 | 289 | n = __copy_tofrom_user(to, from, n); | |
292 | if (access_ok(VERIFY_WRITE, to, n)) | ||
293 | return __copy_tofrom_user(to, from, n); | ||
294 | if ((unsigned long)to < TASK_SIZE) { | ||
295 | over = (unsigned long)to + n - TASK_SIZE; | ||
296 | return __copy_tofrom_user(to, from, n - over) + over; | ||
297 | } | ||
298 | return n; | 290 | return n; |
299 | } | 291 | } |
300 | 292 | ||
@@ -303,13 +295,8 @@ extern unsigned long __clear_user(void *addr, unsigned long size); | |||
303 | static inline __must_check unsigned long | 295 | static inline __must_check unsigned long |
304 | clear_user(void *addr, unsigned long size) | 296 | clear_user(void *addr, unsigned long size) |
305 | { | 297 | { |
306 | 298 | if (likely(access_ok(VERIFY_WRITE, addr, size))) | |
307 | if (access_ok(VERIFY_WRITE, addr, size)) | 299 | size = __clear_user(addr, size); |
308 | return __clear_user(addr, size); | ||
309 | if ((unsigned long)addr < TASK_SIZE) { | ||
310 | unsigned long over = (unsigned long)addr + size - TASK_SIZE; | ||
311 | return __clear_user(addr, size - over) + over; | ||
312 | } | ||
313 | return size; | 300 | return size; |
314 | } | 301 | } |
315 | 302 | ||
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index cd8778103165..af12c2db9bb8 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig | |||
@@ -1,6 +1,5 @@ | |||
1 | config PARISC | 1 | config PARISC |
2 | def_bool y | 2 | def_bool y |
3 | select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS | ||
4 | select ARCH_MIGHT_HAVE_PC_PARPORT | 3 | select ARCH_MIGHT_HAVE_PC_PARPORT |
5 | select HAVE_IDE | 4 | select HAVE_IDE |
6 | select HAVE_OPROFILE | 5 | select HAVE_OPROFILE |
diff --git a/arch/parisc/configs/c8000_defconfig b/arch/parisc/configs/c8000_defconfig index 1a8f6f95689e..f6a4c016304b 100644 --- a/arch/parisc/configs/c8000_defconfig +++ b/arch/parisc/configs/c8000_defconfig | |||
@@ -245,7 +245,6 @@ CONFIG_DEBUG_RT_MUTEXES=y | |||
245 | CONFIG_PROVE_RCU_DELAY=y | 245 | CONFIG_PROVE_RCU_DELAY=y |
246 | CONFIG_DEBUG_BLOCK_EXT_DEVT=y | 246 | CONFIG_DEBUG_BLOCK_EXT_DEVT=y |
247 | CONFIG_LATENCYTOP=y | 247 | CONFIG_LATENCYTOP=y |
248 | CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y | ||
249 | CONFIG_KEYS=y | 248 | CONFIG_KEYS=y |
250 | # CONFIG_CRYPTO_HW is not set | 249 | # CONFIG_CRYPTO_HW is not set |
251 | CONFIG_FONTS=y | 250 | CONFIG_FONTS=y |
diff --git a/arch/parisc/configs/generic-64bit_defconfig b/arch/parisc/configs/generic-64bit_defconfig index 7e0792658952..c564e6e1fa23 100644 --- a/arch/parisc/configs/generic-64bit_defconfig +++ b/arch/parisc/configs/generic-64bit_defconfig | |||
@@ -291,7 +291,6 @@ CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y | |||
291 | CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y | 291 | CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y |
292 | # CONFIG_SCHED_DEBUG is not set | 292 | # CONFIG_SCHED_DEBUG is not set |
293 | CONFIG_TIMER_STATS=y | 293 | CONFIG_TIMER_STATS=y |
294 | CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y | ||
295 | CONFIG_CRYPTO_MANAGER=y | 294 | CONFIG_CRYPTO_MANAGER=y |
296 | CONFIG_CRYPTO_ECB=m | 295 | CONFIG_CRYPTO_ECB=m |
297 | CONFIG_CRYPTO_PCBC=m | 296 | CONFIG_CRYPTO_PCBC=m |
diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h index 0f59fd9ca205..482847865dac 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <asm-generic/uaccess-unaligned.h> | 10 | #include <asm-generic/uaccess-unaligned.h> |
11 | 11 | ||
12 | #include <linux/bug.h> | 12 | #include <linux/bug.h> |
13 | #include <linux/string.h> | ||
13 | 14 | ||
14 | #define VERIFY_READ 0 | 15 | #define VERIFY_READ 0 |
15 | #define VERIFY_WRITE 1 | 16 | #define VERIFY_WRITE 1 |
@@ -208,26 +209,30 @@ unsigned long copy_in_user(void __user *dst, const void __user *src, unsigned lo | |||
208 | #define __copy_to_user_inatomic __copy_to_user | 209 | #define __copy_to_user_inatomic __copy_to_user |
209 | #define __copy_from_user_inatomic __copy_from_user | 210 | #define __copy_from_user_inatomic __copy_from_user |
210 | 211 | ||
211 | extern void copy_from_user_overflow(void) | 212 | extern void __compiletime_error("usercopy buffer size is too small") |
212 | #ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS | 213 | __bad_copy_user(void); |
213 | __compiletime_error("copy_from_user() buffer size is not provably correct") | 214 | |
214 | #else | 215 | static inline void copy_user_overflow(int size, unsigned long count) |
215 | __compiletime_warning("copy_from_user() buffer size is not provably correct") | 216 | { |
216 | #endif | 217 | WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count); |
217 | ; | 218 | } |
218 | 219 | ||
219 | static inline unsigned long __must_check copy_from_user(void *to, | 220 | static inline unsigned long __must_check copy_from_user(void *to, |
220 | const void __user *from, | 221 | const void __user *from, |
221 | unsigned long n) | 222 | unsigned long n) |
222 | { | 223 | { |
223 | int sz = __compiletime_object_size(to); | 224 | int sz = __compiletime_object_size(to); |
224 | int ret = -EFAULT; | 225 | unsigned long ret = n; |
225 | 226 | ||
226 | if (likely(sz == -1 || !__builtin_constant_p(n) || sz >= n)) | 227 | if (likely(sz == -1 || sz >= n)) |
227 | ret = __copy_from_user(to, from, n); | 228 | ret = __copy_from_user(to, from, n); |
228 | else | 229 | else if (!__builtin_constant_p(n)) |
229 | copy_from_user_overflow(); | 230 | copy_user_overflow(sz, n); |
231 | else | ||
232 | __bad_copy_user(); | ||
230 | 233 | ||
234 | if (unlikely(ret)) | ||
235 | memset(to + (n - ret), 0, ret); | ||
231 | return ret; | 236 | return ret; |
232 | } | 237 | } |
233 | 238 | ||
diff --git a/arch/powerpc/include/asm/cpu_has_feature.h b/arch/powerpc/include/asm/cpu_has_feature.h index 2ef55f8968a2..b312b152461b 100644 --- a/arch/powerpc/include/asm/cpu_has_feature.h +++ b/arch/powerpc/include/asm/cpu_has_feature.h | |||
@@ -15,7 +15,7 @@ static inline bool early_cpu_has_feature(unsigned long feature) | |||
15 | #ifdef CONFIG_JUMP_LABEL_FEATURE_CHECKS | 15 | #ifdef CONFIG_JUMP_LABEL_FEATURE_CHECKS |
16 | #include <linux/jump_label.h> | 16 | #include <linux/jump_label.h> |
17 | 17 | ||
18 | #define NUM_CPU_FTR_KEYS 64 | 18 | #define NUM_CPU_FTR_KEYS BITS_PER_LONG |
19 | 19 | ||
20 | extern struct static_key_true cpu_feature_keys[NUM_CPU_FTR_KEYS]; | 20 | extern struct static_key_true cpu_feature_keys[NUM_CPU_FTR_KEYS]; |
21 | 21 | ||
diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h index 666bef4ebfae..9377bdf42eb8 100644 --- a/arch/powerpc/include/asm/cputhreads.h +++ b/arch/powerpc/include/asm/cputhreads.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #ifndef __ASSEMBLY__ | 4 | #ifndef __ASSEMBLY__ |
5 | #include <linux/cpumask.h> | 5 | #include <linux/cpumask.h> |
6 | #include <asm/cpu_has_feature.h> | ||
6 | 7 | ||
7 | /* | 8 | /* |
8 | * Mapping of threads to cores | 9 | * Mapping of threads to cores |
diff --git a/arch/powerpc/include/asm/hmi.h b/arch/powerpc/include/asm/hmi.h index 88b4901ac4ee..85b7a1a21e22 100644 --- a/arch/powerpc/include/asm/hmi.h +++ b/arch/powerpc/include/asm/hmi.h | |||
@@ -21,7 +21,7 @@ | |||
21 | #ifndef __ASM_PPC64_HMI_H__ | 21 | #ifndef __ASM_PPC64_HMI_H__ |
22 | #define __ASM_PPC64_HMI_H__ | 22 | #define __ASM_PPC64_HMI_H__ |
23 | 23 | ||
24 | #ifdef CONFIG_PPC_BOOK3S_64 | 24 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE |
25 | 25 | ||
26 | #define CORE_TB_RESYNC_REQ_BIT 63 | 26 | #define CORE_TB_RESYNC_REQ_BIT 63 |
27 | #define MAX_SUBCORE_PER_CORE 4 | 27 | #define MAX_SUBCORE_PER_CORE 4 |
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 148303e7771f..6a6792bb39fb 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h | |||
@@ -183,11 +183,6 @@ struct paca_struct { | |||
183 | */ | 183 | */ |
184 | u16 in_mce; | 184 | u16 in_mce; |
185 | u8 hmi_event_available; /* HMI event is available */ | 185 | u8 hmi_event_available; /* HMI event is available */ |
186 | /* | ||
187 | * Bitmap for sibling subcore status. See kvm/book3s_hv_ras.c for | ||
188 | * more details | ||
189 | */ | ||
190 | struct sibling_subcore_state *sibling_subcore_state; | ||
191 | #endif | 186 | #endif |
192 | 187 | ||
193 | /* Stuff for accurate time accounting */ | 188 | /* Stuff for accurate time accounting */ |
@@ -202,6 +197,13 @@ struct paca_struct { | |||
202 | struct kvmppc_book3s_shadow_vcpu shadow_vcpu; | 197 | struct kvmppc_book3s_shadow_vcpu shadow_vcpu; |
203 | #endif | 198 | #endif |
204 | struct kvmppc_host_state kvm_hstate; | 199 | struct kvmppc_host_state kvm_hstate; |
200 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE | ||
201 | /* | ||
202 | * Bitmap for sibling subcore status. See kvm/book3s_hv_ras.c for | ||
203 | * more details | ||
204 | */ | ||
205 | struct sibling_subcore_state *sibling_subcore_state; | ||
206 | #endif | ||
205 | #endif | 207 | #endif |
206 | }; | 208 | }; |
207 | 209 | ||
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index b5e88e4a171a..c0309c59bed8 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h | |||
@@ -301,6 +301,7 @@ extern void pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
301 | /* Allocate & free a PCI host bridge structure */ | 301 | /* Allocate & free a PCI host bridge structure */ |
302 | extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev); | 302 | extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev); |
303 | extern void pcibios_free_controller(struct pci_controller *phb); | 303 | extern void pcibios_free_controller(struct pci_controller *phb); |
304 | extern void pcibios_free_controller_deferred(struct pci_host_bridge *bridge); | ||
304 | 305 | ||
305 | #ifdef CONFIG_PCI | 306 | #ifdef CONFIG_PCI |
306 | extern int pcibios_vaddr_is_ioport(void __iomem *address); | 307 | extern int pcibios_vaddr_is_ioport(void __iomem *address); |
diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h index c1dc6c14deb8..c266227fdd5b 100644 --- a/arch/powerpc/include/asm/uaccess.h +++ b/arch/powerpc/include/asm/uaccess.h | |||
@@ -308,40 +308,21 @@ extern unsigned long __copy_tofrom_user(void __user *to, | |||
308 | static inline unsigned long copy_from_user(void *to, | 308 | static inline unsigned long copy_from_user(void *to, |
309 | const void __user *from, unsigned long n) | 309 | const void __user *from, unsigned long n) |
310 | { | 310 | { |
311 | unsigned long over; | 311 | if (likely(access_ok(VERIFY_READ, from, n))) { |
312 | 312 | check_object_size(to, n, false); | |
313 | if (access_ok(VERIFY_READ, from, n)) { | ||
314 | if (!__builtin_constant_p(n)) | ||
315 | check_object_size(to, n, false); | ||
316 | return __copy_tofrom_user((__force void __user *)to, from, n); | 313 | return __copy_tofrom_user((__force void __user *)to, from, n); |
317 | } | 314 | } |
318 | if ((unsigned long)from < TASK_SIZE) { | 315 | memset(to, 0, n); |
319 | over = (unsigned long)from + n - TASK_SIZE; | ||
320 | if (!__builtin_constant_p(n - over)) | ||
321 | check_object_size(to, n - over, false); | ||
322 | return __copy_tofrom_user((__force void __user *)to, from, | ||
323 | n - over) + over; | ||
324 | } | ||
325 | return n; | 316 | return n; |
326 | } | 317 | } |
327 | 318 | ||
328 | static inline unsigned long copy_to_user(void __user *to, | 319 | static inline unsigned long copy_to_user(void __user *to, |
329 | const void *from, unsigned long n) | 320 | const void *from, unsigned long n) |
330 | { | 321 | { |
331 | unsigned long over; | ||
332 | |||
333 | if (access_ok(VERIFY_WRITE, to, n)) { | 322 | if (access_ok(VERIFY_WRITE, to, n)) { |
334 | if (!__builtin_constant_p(n)) | 323 | check_object_size(from, n, true); |
335 | check_object_size(from, n, true); | ||
336 | return __copy_tofrom_user(to, (__force void __user *)from, n); | 324 | return __copy_tofrom_user(to, (__force void __user *)from, n); |
337 | } | 325 | } |
338 | if ((unsigned long)to < TASK_SIZE) { | ||
339 | over = (unsigned long)to + n - TASK_SIZE; | ||
340 | if (!__builtin_constant_p(n)) | ||
341 | check_object_size(from, n - over, true); | ||
342 | return __copy_tofrom_user(to, (__force void __user *)from, | ||
343 | n - over) + over; | ||
344 | } | ||
345 | return n; | 326 | return n; |
346 | } | 327 | } |
347 | 328 | ||
@@ -383,8 +364,7 @@ static inline unsigned long __copy_from_user_inatomic(void *to, | |||
383 | return 0; | 364 | return 0; |
384 | } | 365 | } |
385 | 366 | ||
386 | if (!__builtin_constant_p(n)) | 367 | check_object_size(to, n, false); |
387 | check_object_size(to, n, false); | ||
388 | 368 | ||
389 | return __copy_tofrom_user((__force void __user *)to, from, n); | 369 | return __copy_tofrom_user((__force void __user *)to, from, n); |
390 | } | 370 | } |
@@ -412,8 +392,8 @@ static inline unsigned long __copy_to_user_inatomic(void __user *to, | |||
412 | if (ret == 0) | 392 | if (ret == 0) |
413 | return 0; | 393 | return 0; |
414 | } | 394 | } |
415 | if (!__builtin_constant_p(n)) | 395 | |
416 | check_object_size(from, n, true); | 396 | check_object_size(from, n, true); |
417 | 397 | ||
418 | return __copy_tofrom_user(to, (__force const void __user *)from, n); | 398 | return __copy_tofrom_user(to, (__force const void __user *)from, n); |
419 | } | 399 | } |
@@ -439,10 +419,6 @@ static inline unsigned long clear_user(void __user *addr, unsigned long size) | |||
439 | might_fault(); | 419 | might_fault(); |
440 | if (likely(access_ok(VERIFY_WRITE, addr, size))) | 420 | if (likely(access_ok(VERIFY_WRITE, addr, size))) |
441 | return __clear_user(addr, size); | 421 | return __clear_user(addr, size); |
442 | if ((unsigned long)addr < TASK_SIZE) { | ||
443 | unsigned long over = (unsigned long)addr + size - TASK_SIZE; | ||
444 | return __clear_user(addr, size - over) + over; | ||
445 | } | ||
446 | return size; | 422 | return size; |
447 | } | 423 | } |
448 | 424 | ||
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index b2027a5cf508..fe4c075bcf50 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -41,7 +41,7 @@ obj-$(CONFIG_VDSO32) += vdso32/ | |||
41 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o | 41 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o |
42 | obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o | 42 | obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o |
43 | obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o | 43 | obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o |
44 | obj-$(CONFIG_PPC_BOOK3S_64) += mce.o mce_power.o hmi.o | 44 | obj-$(CONFIG_PPC_BOOK3S_64) += mce.o mce_power.o |
45 | obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_book3e.o | 45 | obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_book3e.o |
46 | obj-$(CONFIG_PPC64) += vdso64/ | 46 | obj-$(CONFIG_PPC64) += vdso64/ |
47 | obj-$(CONFIG_ALTIVEC) += vecemu.o | 47 | obj-$(CONFIG_ALTIVEC) += vecemu.o |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 6b8bc0dd09d4..5afd03e5e8b8 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -368,13 +368,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) | |||
368 | tabort_syscall: | 368 | tabort_syscall: |
369 | /* Firstly we need to enable TM in the kernel */ | 369 | /* Firstly we need to enable TM in the kernel */ |
370 | mfmsr r10 | 370 | mfmsr r10 |
371 | li r13, 1 | 371 | li r9, 1 |
372 | rldimi r10, r13, MSR_TM_LG, 63-MSR_TM_LG | 372 | rldimi r10, r9, MSR_TM_LG, 63-MSR_TM_LG |
373 | mtmsrd r10, 0 | 373 | mtmsrd r10, 0 |
374 | 374 | ||
375 | /* tabort, this dooms the transaction, nothing else */ | 375 | /* tabort, this dooms the transaction, nothing else */ |
376 | li r13, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT) | 376 | li r9, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT) |
377 | TABORT(R13) | 377 | TABORT(R9) |
378 | 378 | ||
379 | /* | 379 | /* |
380 | * Return directly to userspace. We have corrupted user register state, | 380 | * Return directly to userspace. We have corrupted user register state, |
@@ -382,8 +382,8 @@ tabort_syscall: | |||
382 | * resume after the tbegin of the aborted transaction with the | 382 | * resume after the tbegin of the aborted transaction with the |
383 | * checkpointed register state. | 383 | * checkpointed register state. |
384 | */ | 384 | */ |
385 | li r13, MSR_RI | 385 | li r9, MSR_RI |
386 | andc r10, r10, r13 | 386 | andc r10, r10, r9 |
387 | mtmsrd r10, 1 | 387 | mtmsrd r10, 1 |
388 | mtspr SPRN_SRR0, r11 | 388 | mtspr SPRN_SRR0, r11 |
389 | mtspr SPRN_SRR1, r12 | 389 | mtspr SPRN_SRR1, r12 |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index df6d45eb4115..bffec73dbffc 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -485,7 +485,23 @@ machine_check_fwnmi: | |||
485 | EXCEPTION_PROLOG_0(PACA_EXMC) | 485 | EXCEPTION_PROLOG_0(PACA_EXMC) |
486 | machine_check_pSeries_0: | 486 | machine_check_pSeries_0: |
487 | EXCEPTION_PROLOG_1(PACA_EXMC, KVMTEST, 0x200) | 487 | EXCEPTION_PROLOG_1(PACA_EXMC, KVMTEST, 0x200) |
488 | EXCEPTION_PROLOG_PSERIES_1(machine_check_common, EXC_STD) | 488 | /* |
489 | * The following is essentially EXCEPTION_PROLOG_PSERIES_1 with the | ||
490 | * difference that MSR_RI is not enabled, because PACA_EXMC is being | ||
491 | * used, so nested machine check corrupts it. machine_check_common | ||
492 | * enables MSR_RI. | ||
493 | */ | ||
494 | ld r12,PACAKBASE(r13) | ||
495 | ld r10,PACAKMSR(r13) | ||
496 | xori r10,r10,MSR_RI | ||
497 | mfspr r11,SPRN_SRR0 | ||
498 | LOAD_HANDLER(r12, machine_check_common) | ||
499 | mtspr SPRN_SRR0,r12 | ||
500 | mfspr r12,SPRN_SRR1 | ||
501 | mtspr SPRN_SRR1,r10 | ||
502 | rfid | ||
503 | b . /* prevent speculative execution */ | ||
504 | |||
489 | KVM_HANDLER_SKIP(PACA_EXMC, EXC_STD, 0x200) | 505 | KVM_HANDLER_SKIP(PACA_EXMC, EXC_STD, 0x200) |
490 | KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300) | 506 | KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300) |
491 | KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380) | 507 | KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380) |
@@ -969,14 +985,17 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) | |||
969 | machine_check_common: | 985 | machine_check_common: |
970 | 986 | ||
971 | mfspr r10,SPRN_DAR | 987 | mfspr r10,SPRN_DAR |
972 | std r10,PACA_EXGEN+EX_DAR(r13) | 988 | std r10,PACA_EXMC+EX_DAR(r13) |
973 | mfspr r10,SPRN_DSISR | 989 | mfspr r10,SPRN_DSISR |
974 | stw r10,PACA_EXGEN+EX_DSISR(r13) | 990 | stw r10,PACA_EXMC+EX_DSISR(r13) |
975 | EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) | 991 | EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) |
976 | FINISH_NAP | 992 | FINISH_NAP |
977 | RECONCILE_IRQ_STATE(r10, r11) | 993 | RECONCILE_IRQ_STATE(r10, r11) |
978 | ld r3,PACA_EXGEN+EX_DAR(r13) | 994 | ld r3,PACA_EXMC+EX_DAR(r13) |
979 | lwz r4,PACA_EXGEN+EX_DSISR(r13) | 995 | lwz r4,PACA_EXMC+EX_DSISR(r13) |
996 | /* Enable MSR_RI when finished with PACA_EXMC */ | ||
997 | li r10,MSR_RI | ||
998 | mtmsrd r10,1 | ||
980 | std r3,_DAR(r1) | 999 | std r3,_DAR(r1) |
981 | std r4,_DSISR(r1) | 1000 | std r4,_DSISR(r1) |
982 | bl save_nvgprs | 1001 | bl save_nvgprs |
diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S index 2265c6398a17..bd739fed26e3 100644 --- a/arch/powerpc/kernel/idle_book3s.S +++ b/arch/powerpc/kernel/idle_book3s.S | |||
@@ -411,7 +411,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) | |||
411 | * | 411 | * |
412 | * r13 - PACA | 412 | * r13 - PACA |
413 | * cr3 - gt if waking up with partial/complete hypervisor state loss | 413 | * cr3 - gt if waking up with partial/complete hypervisor state loss |
414 | * cr4 - eq if waking up from complete hypervisor state loss. | 414 | * cr4 - gt or eq if waking up from complete hypervisor state loss. |
415 | */ | 415 | */ |
416 | _GLOBAL(pnv_wakeup_tb_loss) | 416 | _GLOBAL(pnv_wakeup_tb_loss) |
417 | ld r1,PACAR1(r13) | 417 | ld r1,PACAR1(r13) |
@@ -453,7 +453,7 @@ lwarx_loop2: | |||
453 | * At this stage | 453 | * At this stage |
454 | * cr2 - eq if first thread to wakeup in core | 454 | * cr2 - eq if first thread to wakeup in core |
455 | * cr3- gt if waking up with partial/complete hypervisor state loss | 455 | * cr3- gt if waking up with partial/complete hypervisor state loss |
456 | * cr4 - eq if waking up from complete hypervisor state loss. | 456 | * cr4 - gt or eq if waking up from complete hypervisor state loss. |
457 | */ | 457 | */ |
458 | 458 | ||
459 | ori r15,r15,PNV_CORE_IDLE_LOCK_BIT | 459 | ori r15,r15,PNV_CORE_IDLE_LOCK_BIT |
@@ -481,7 +481,7 @@ first_thread_in_subcore: | |||
481 | * If waking up from sleep, subcore state is not lost. Hence | 481 | * If waking up from sleep, subcore state is not lost. Hence |
482 | * skip subcore state restore | 482 | * skip subcore state restore |
483 | */ | 483 | */ |
484 | bne cr4,subcore_state_restored | 484 | blt cr4,subcore_state_restored |
485 | 485 | ||
486 | /* Restore per-subcore state */ | 486 | /* Restore per-subcore state */ |
487 | ld r4,_SDR1(r1) | 487 | ld r4,_SDR1(r1) |
@@ -526,7 +526,7 @@ timebase_resync: | |||
526 | * If waking up from sleep, per core state is not lost, skip to | 526 | * If waking up from sleep, per core state is not lost, skip to |
527 | * clear_lock. | 527 | * clear_lock. |
528 | */ | 528 | */ |
529 | bne cr4,clear_lock | 529 | blt cr4,clear_lock |
530 | 530 | ||
531 | /* | 531 | /* |
532 | * First thread in the core to wake up and its waking up with | 532 | * First thread in the core to wake up and its waking up with |
@@ -557,7 +557,7 @@ common_exit: | |||
557 | * If waking up from sleep, hypervisor state is not lost. Hence | 557 | * If waking up from sleep, hypervisor state is not lost. Hence |
558 | * skip hypervisor state restore. | 558 | * skip hypervisor state restore. |
559 | */ | 559 | */ |
560 | bne cr4,hypervisor_state_restored | 560 | blt cr4,hypervisor_state_restored |
561 | 561 | ||
562 | /* Waking up from winkle */ | 562 | /* Waking up from winkle */ |
563 | 563 | ||
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 3ed8ec09b5c9..e785cc9e1ecd 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <linux/kprobes.h> | 29 | #include <linux/kprobes.h> |
30 | #include <linux/ptrace.h> | 30 | #include <linux/ptrace.h> |
31 | #include <linux/preempt.h> | 31 | #include <linux/preempt.h> |
32 | #include <linux/module.h> | 32 | #include <linux/extable.h> |
33 | #include <linux/kdebug.h> | 33 | #include <linux/kdebug.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <asm/code-patching.h> | 35 | #include <asm/code-patching.h> |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 7fdf324d5b51..e58908066b0e 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -154,6 +154,42 @@ void pcibios_free_controller(struct pci_controller *phb) | |||
154 | EXPORT_SYMBOL_GPL(pcibios_free_controller); | 154 | EXPORT_SYMBOL_GPL(pcibios_free_controller); |
155 | 155 | ||
156 | /* | 156 | /* |
157 | * This function is used to call pcibios_free_controller() | ||
158 | * in a deferred manner: a callback from the PCI subsystem. | ||
159 | * | ||
160 | * _*DO NOT*_ call pcibios_free_controller() explicitly if | ||
161 | * this is used (or it may access an invalid *phb pointer). | ||
162 | * | ||
163 | * The callback occurs when all references to the root bus | ||
164 | * are dropped (e.g., child buses/devices and their users). | ||
165 | * | ||
166 | * It's called as .release_fn() of 'struct pci_host_bridge' | ||
167 | * which is associated with the 'struct pci_controller.bus' | ||
168 | * (root bus) - it expects .release_data to hold a pointer | ||
169 | * to 'struct pci_controller'. | ||
170 | * | ||
171 | * In order to use it, register .release_fn()/release_data | ||
172 | * like this: | ||
173 | * | ||
174 | * pci_set_host_bridge_release(bridge, | ||
175 | * pcibios_free_controller_deferred | ||
176 | * (void *) phb); | ||
177 | * | ||
178 | * e.g. in the pcibios_root_bridge_prepare() callback from | ||
179 | * pci_create_root_bus(). | ||
180 | */ | ||
181 | void pcibios_free_controller_deferred(struct pci_host_bridge *bridge) | ||
182 | { | ||
183 | struct pci_controller *phb = (struct pci_controller *) | ||
184 | bridge->release_data; | ||
185 | |||
186 | pr_debug("domain %d, dynamic %d\n", phb->global_number, phb->is_dynamic); | ||
187 | |||
188 | pcibios_free_controller(phb); | ||
189 | } | ||
190 | EXPORT_SYMBOL_GPL(pcibios_free_controller_deferred); | ||
191 | |||
192 | /* | ||
157 | * The function is used to return the minimal alignment | 193 | * The function is used to return the minimal alignment |
158 | * for memory or I/O windows of the associated P2P bridge. | 194 | * for memory or I/O windows of the associated P2P bridge. |
159 | * By default, 4KiB alignment for I/O windows and 1MiB for | 195 | * By default, 4KiB alignment for I/O windows and 1MiB for |
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 4e74fc588a3f..d3eff99e938c 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -695,7 +695,7 @@ unsigned char ibm_architecture_vec[] = { | |||
695 | OV4_MIN_ENT_CAP, /* minimum VP entitled capacity */ | 695 | OV4_MIN_ENT_CAP, /* minimum VP entitled capacity */ |
696 | 696 | ||
697 | /* option vector 5: PAPR/OF options */ | 697 | /* option vector 5: PAPR/OF options */ |
698 | VECTOR_LENGTH(18), /* length */ | 698 | VECTOR_LENGTH(21), /* length */ |
699 | 0, /* don't ignore, don't halt */ | 699 | 0, /* don't ignore, don't halt */ |
700 | OV5_FEAT(OV5_LPAR) | OV5_FEAT(OV5_SPLPAR) | OV5_FEAT(OV5_LARGE_PAGES) | | 700 | OV5_FEAT(OV5_LPAR) | OV5_FEAT(OV5_SPLPAR) | OV5_FEAT(OV5_LARGE_PAGES) | |
701 | OV5_FEAT(OV5_DRCONF_MEMORY) | OV5_FEAT(OV5_DONATE_DEDICATE_CPU) | | 701 | OV5_FEAT(OV5_DRCONF_MEMORY) | OV5_FEAT(OV5_DONATE_DEDICATE_CPU) | |
@@ -726,8 +726,11 @@ unsigned char ibm_architecture_vec[] = { | |||
726 | 0, | 726 | 0, |
727 | 0, | 727 | 0, |
728 | OV5_FEAT(OV5_PFO_HW_RNG) | OV5_FEAT(OV5_PFO_HW_ENCR) | | 728 | OV5_FEAT(OV5_PFO_HW_RNG) | OV5_FEAT(OV5_PFO_HW_ENCR) | |
729 | OV5_FEAT(OV5_PFO_HW_842), | 729 | OV5_FEAT(OV5_PFO_HW_842), /* Byte 17 */ |
730 | OV5_FEAT(OV5_SUB_PROCESSORS), | 730 | 0, /* Byte 18 */ |
731 | 0, /* Byte 19 */ | ||
732 | 0, /* Byte 20 */ | ||
733 | OV5_FEAT(OV5_SUB_PROCESSORS), /* Byte 21 */ | ||
731 | 734 | ||
732 | /* option vector 6: IBM PAPR hints */ | 735 | /* option vector 6: IBM PAPR hints */ |
733 | VECTOR_LENGTH(3), /* length */ | 736 | VECTOR_LENGTH(3), /* length */ |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index b6aa378aff63..a7daf749b97f 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -1226,7 +1226,21 @@ long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, | |||
1226 | (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16); | 1226 | (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16); |
1227 | if (!access_ok(VERIFY_READ, rt_sf, sizeof(*rt_sf))) | 1227 | if (!access_ok(VERIFY_READ, rt_sf, sizeof(*rt_sf))) |
1228 | goto bad; | 1228 | goto bad; |
1229 | |||
1229 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 1230 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
1231 | /* | ||
1232 | * If there is a transactional state then throw it away. | ||
1233 | * The purpose of a sigreturn is to destroy all traces of the | ||
1234 | * signal frame, this includes any transactional state created | ||
1235 | * within in. We only check for suspended as we can never be | ||
1236 | * active in the kernel, we are active, there is nothing better to | ||
1237 | * do than go ahead and Bad Thing later. | ||
1238 | * The cause is not important as there will never be a | ||
1239 | * recheckpoint so it's not user visible. | ||
1240 | */ | ||
1241 | if (MSR_TM_SUSPENDED(mfmsr())) | ||
1242 | tm_reclaim_current(0); | ||
1243 | |||
1230 | if (__get_user(tmp, &rt_sf->uc.uc_link)) | 1244 | if (__get_user(tmp, &rt_sf->uc.uc_link)) |
1231 | goto bad; | 1245 | goto bad; |
1232 | uc_transact = (struct ucontext __user *)(uintptr_t)tmp; | 1246 | uc_transact = (struct ucontext __user *)(uintptr_t)tmp; |
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 7e49984d4331..70409bb90a95 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
@@ -676,7 +676,21 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, | |||
676 | if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set))) | 676 | if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set))) |
677 | goto badframe; | 677 | goto badframe; |
678 | set_current_blocked(&set); | 678 | set_current_blocked(&set); |
679 | |||
679 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 680 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
681 | /* | ||
682 | * If there is a transactional state then throw it away. | ||
683 | * The purpose of a sigreturn is to destroy all traces of the | ||
684 | * signal frame, this includes any transactional state created | ||
685 | * within in. We only check for suspended as we can never be | ||
686 | * active in the kernel, we are active, there is nothing better to | ||
687 | * do than go ahead and Bad Thing later. | ||
688 | * The cause is not important as there will never be a | ||
689 | * recheckpoint so it's not user visible. | ||
690 | */ | ||
691 | if (MSR_TM_SUSPENDED(mfmsr())) | ||
692 | tm_reclaim_current(0); | ||
693 | |||
680 | if (__get_user(msr, &uc->uc_mcontext.gp_regs[PT_MSR])) | 694 | if (__get_user(msr, &uc->uc_mcontext.gp_regs[PT_MSR])) |
681 | goto badframe; | 695 | goto badframe; |
682 | if (MSR_TM_ACTIVE(msr)) { | 696 | if (MSR_TM_ACTIVE(msr)) { |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 25a39052bf6b..9c6f3fd58059 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -830,7 +830,7 @@ int __cpu_disable(void) | |||
830 | 830 | ||
831 | /* Update sibling maps */ | 831 | /* Update sibling maps */ |
832 | base = cpu_first_thread_sibling(cpu); | 832 | base = cpu_first_thread_sibling(cpu); |
833 | for (i = 0; i < threads_per_core; i++) { | 833 | for (i = 0; i < threads_per_core && base + i < nr_cpu_ids; i++) { |
834 | cpumask_clear_cpu(cpu, cpu_sibling_mask(base + i)); | 834 | cpumask_clear_cpu(cpu, cpu_sibling_mask(base + i)); |
835 | cpumask_clear_cpu(base + i, cpu_sibling_mask(cpu)); | 835 | cpumask_clear_cpu(base + i, cpu_sibling_mask(cpu)); |
836 | cpumask_clear_cpu(cpu, cpu_core_mask(base + i)); | 836 | cpumask_clear_cpu(cpu, cpu_core_mask(base + i)); |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 2cb589264cb7..62859ebe0062 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -25,7 +25,8 @@ | |||
25 | #include <linux/user.h> | 25 | #include <linux/user.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/module.h> | 28 | #include <linux/extable.h> |
29 | #include <linux/module.h> /* print_modules */ | ||
29 | #include <linux/prctl.h> | 30 | #include <linux/prctl.h> |
30 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
31 | #include <linux/kprobes.h> | 32 | #include <linux/kprobes.h> |
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 1f9e5529e692..855d4b95d752 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile | |||
@@ -78,6 +78,7 @@ kvm-book3s_64-builtin-xics-objs-$(CONFIG_KVM_XICS) := \ | |||
78 | 78 | ||
79 | ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE | 79 | ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE |
80 | kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HANDLER) += \ | 80 | kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HANDLER) += \ |
81 | book3s_hv_hmi.o \ | ||
81 | book3s_hv_rmhandlers.o \ | 82 | book3s_hv_rmhandlers.o \ |
82 | book3s_hv_rm_mmu.o \ | 83 | book3s_hv_rm_mmu.o \ |
83 | book3s_hv_ras.o \ | 84 | book3s_hv_ras.o \ |
diff --git a/arch/powerpc/kernel/hmi.c b/arch/powerpc/kvm/book3s_hv_hmi.c index e3f738eb1cac..e3f738eb1cac 100644 --- a/arch/powerpc/kernel/hmi.c +++ b/arch/powerpc/kvm/book3s_hv_hmi.c | |||
diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S index 0a57fe6d49cc..aa8214f30c92 100644 --- a/arch/powerpc/lib/checksum_32.S +++ b/arch/powerpc/lib/checksum_32.S | |||
@@ -127,18 +127,19 @@ _GLOBAL(csum_partial_copy_generic) | |||
127 | stw r7,12(r1) | 127 | stw r7,12(r1) |
128 | stw r8,8(r1) | 128 | stw r8,8(r1) |
129 | 129 | ||
130 | rlwinm r0,r4,3,0x8 | ||
131 | rlwnm r6,r6,r0,0,31 /* odd destination address: rotate one byte */ | ||
132 | cmplwi cr7,r0,0 /* is destination address even ? */ | ||
133 | addic r12,r6,0 | 130 | addic r12,r6,0 |
134 | addi r6,r4,-4 | 131 | addi r6,r4,-4 |
135 | neg r0,r4 | 132 | neg r0,r4 |
136 | addi r4,r3,-4 | 133 | addi r4,r3,-4 |
137 | andi. r0,r0,CACHELINE_MASK /* # bytes to start of cache line */ | 134 | andi. r0,r0,CACHELINE_MASK /* # bytes to start of cache line */ |
135 | crset 4*cr7+eq | ||
138 | beq 58f | 136 | beq 58f |
139 | 137 | ||
140 | cmplw 0,r5,r0 /* is this more than total to do? */ | 138 | cmplw 0,r5,r0 /* is this more than total to do? */ |
141 | blt 63f /* if not much to do */ | 139 | blt 63f /* if not much to do */ |
140 | rlwinm r7,r6,3,0x8 | ||
141 | rlwnm r12,r12,r7,0,31 /* odd destination address: rotate one byte */ | ||
142 | cmplwi cr7,r7,0 /* is destination address even ? */ | ||
142 | andi. r8,r0,3 /* get it word-aligned first */ | 143 | andi. r8,r0,3 /* get it word-aligned first */ |
143 | mtctr r8 | 144 | mtctr r8 |
144 | beq+ 61f | 145 | beq+ 61f |
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index a4db22f65021..bb1ffc559f38 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
29 | #include <linux/module.h> | 29 | #include <linux/extable.h> |
30 | #include <linux/kprobes.h> | 30 | #include <linux/kprobes.h> |
31 | #include <linux/kdebug.h> | 31 | #include <linux/kdebug.h> |
32 | #include <linux/perf_event.h> | 32 | #include <linux/perf_event.h> |
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S index dfdb90cb4403..9f1983404e1a 100644 --- a/arch/powerpc/mm/slb_low.S +++ b/arch/powerpc/mm/slb_low.S | |||
@@ -113,7 +113,12 @@ BEGIN_FTR_SECTION | |||
113 | END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT) | 113 | END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT) |
114 | b slb_finish_load_1T | 114 | b slb_finish_load_1T |
115 | 115 | ||
116 | 0: | 116 | 0: /* |
117 | * For userspace addresses, make sure this is region 0. | ||
118 | */ | ||
119 | cmpdi r9, 0 | ||
120 | bne 8f | ||
121 | |||
117 | /* when using slices, we extract the psize off the slice bitmaps | 122 | /* when using slices, we extract the psize off the slice bitmaps |
118 | * and then we need to get the sllp encoding off the mmu_psize_defs | 123 | * and then we need to get the sllp encoding off the mmu_psize_defs |
119 | * array. | 124 | * array. |
diff --git a/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c b/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c index 8eb82b043dd8..d93dd4acf40b 100644 --- a/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c +++ b/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c | |||
@@ -528,7 +528,6 @@ static struct platform_driver mpc512x_lpbfifo_driver = { | |||
528 | .remove = mpc512x_lpbfifo_remove, | 528 | .remove = mpc512x_lpbfifo_remove, |
529 | .driver = { | 529 | .driver = { |
530 | .name = DRV_NAME, | 530 | .name = DRV_NAME, |
531 | .owner = THIS_MODULE, | ||
532 | .of_match_table = mpc512x_lpbfifo_match, | 531 | .of_match_table = mpc512x_lpbfifo_match, |
533 | }, | 532 | }, |
534 | }; | 533 | }; |
diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index dbcd0303afed..63c5ab6489c9 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c | |||
@@ -222,7 +222,6 @@ static const struct of_device_id mcu_of_match_table[] = { | |||
222 | static struct i2c_driver mcu_driver = { | 222 | static struct i2c_driver mcu_driver = { |
223 | .driver = { | 223 | .driver = { |
224 | .name = "mcu-mpc8349emitx", | 224 | .name = "mcu-mpc8349emitx", |
225 | .owner = THIS_MODULE, | ||
226 | .of_match_table = mcu_of_match_table, | 225 | .of_match_table = mcu_of_match_table, |
227 | }, | 226 | }, |
228 | .probe = mcu_probe, | 227 | .probe = mcu_probe, |
diff --git a/arch/powerpc/platforms/embedded6xx/holly.c b/arch/powerpc/platforms/embedded6xx/holly.c index dafba1057a47..dfd310031549 100644 --- a/arch/powerpc/platforms/embedded6xx/holly.c +++ b/arch/powerpc/platforms/embedded6xx/holly.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/tty.h> | 26 | #include <linux/tty.h> |
27 | #include <linux/serial_core.h> | 27 | #include <linux/serial_core.h> |
28 | #include <linux/of_platform.h> | 28 | #include <linux/of_platform.h> |
29 | #include <linux/module.h> | 29 | #include <linux/extable.h> |
30 | 30 | ||
31 | #include <asm/time.h> | 31 | #include <asm/time.h> |
32 | #include <asm/machdep.h> | 32 | #include <asm/machdep.h> |
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index 80804f9916ee..f97bab8e37a2 100644 --- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
24 | #include <linux/kdev_t.h> | 24 | #include <linux/kdev_t.h> |
25 | #include <linux/console.h> | 25 | #include <linux/console.h> |
26 | #include <linux/module.h> | 26 | #include <linux/extable.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/irq.h> | 28 | #include <linux/irq.h> |
29 | #include <linux/seq_file.h> | 29 | #include <linux/seq_file.h> |
diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c index 2ee96431f736..4c827826c05e 100644 --- a/arch/powerpc/platforms/powernv/opal-dump.c +++ b/arch/powerpc/platforms/powernv/opal-dump.c | |||
@@ -370,6 +370,7 @@ static irqreturn_t process_dump(int irq, void *data) | |||
370 | uint32_t dump_id, dump_size, dump_type; | 370 | uint32_t dump_id, dump_size, dump_type; |
371 | struct dump_obj *dump; | 371 | struct dump_obj *dump; |
372 | char name[22]; | 372 | char name[22]; |
373 | struct kobject *kobj; | ||
373 | 374 | ||
374 | rc = dump_read_info(&dump_id, &dump_size, &dump_type); | 375 | rc = dump_read_info(&dump_id, &dump_size, &dump_type); |
375 | if (rc != OPAL_SUCCESS) | 376 | if (rc != OPAL_SUCCESS) |
@@ -381,8 +382,12 @@ static irqreturn_t process_dump(int irq, void *data) | |||
381 | * that gracefully and not create two conflicting | 382 | * that gracefully and not create two conflicting |
382 | * entries. | 383 | * entries. |
383 | */ | 384 | */ |
384 | if (kset_find_obj(dump_kset, name)) | 385 | kobj = kset_find_obj(dump_kset, name); |
386 | if (kobj) { | ||
387 | /* Drop reference added by kset_find_obj() */ | ||
388 | kobject_put(kobj); | ||
385 | return 0; | 389 | return 0; |
390 | } | ||
386 | 391 | ||
387 | dump = create_dump_obj(dump_id, dump_size, dump_type); | 392 | dump = create_dump_obj(dump_id, dump_size, dump_type); |
388 | if (!dump) | 393 | if (!dump) |
diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c index 37f959bf392e..f2344cbd2f46 100644 --- a/arch/powerpc/platforms/powernv/opal-elog.c +++ b/arch/powerpc/platforms/powernv/opal-elog.c | |||
@@ -247,6 +247,7 @@ static irqreturn_t elog_event(int irq, void *data) | |||
247 | uint64_t elog_type; | 247 | uint64_t elog_type; |
248 | int rc; | 248 | int rc; |
249 | char name[2+16+1]; | 249 | char name[2+16+1]; |
250 | struct kobject *kobj; | ||
250 | 251 | ||
251 | rc = opal_get_elog_size(&id, &size, &type); | 252 | rc = opal_get_elog_size(&id, &size, &type); |
252 | if (rc != OPAL_SUCCESS) { | 253 | if (rc != OPAL_SUCCESS) { |
@@ -269,8 +270,12 @@ static irqreturn_t elog_event(int irq, void *data) | |||
269 | * that gracefully and not create two conflicting | 270 | * that gracefully and not create two conflicting |
270 | * entries. | 271 | * entries. |
271 | */ | 272 | */ |
272 | if (kset_find_obj(elog_kset, name)) | 273 | kobj = kset_find_obj(elog_kset, name); |
274 | if (kobj) { | ||
275 | /* Drop reference added by kset_find_obj() */ | ||
276 | kobject_put(kobj); | ||
273 | return IRQ_HANDLED; | 277 | return IRQ_HANDLED; |
278 | } | ||
274 | 279 | ||
275 | create_elog_obj(log_id, elog_size, elog_type); | 280 | create_elog_obj(log_id, elog_size, elog_type); |
276 | 281 | ||
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index fd9444f9fb0c..38a5c657ffd3 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
@@ -124,6 +124,13 @@ static inline bool pnv_pci_is_m64(struct pnv_phb *phb, struct resource *r) | |||
124 | r->start < (phb->ioda.m64_base + phb->ioda.m64_size)); | 124 | r->start < (phb->ioda.m64_base + phb->ioda.m64_size)); |
125 | } | 125 | } |
126 | 126 | ||
127 | static inline bool pnv_pci_is_m64_flags(unsigned long resource_flags) | ||
128 | { | ||
129 | unsigned long flags = (IORESOURCE_MEM_64 | IORESOURCE_PREFETCH); | ||
130 | |||
131 | return (resource_flags & flags) == flags; | ||
132 | } | ||
133 | |||
127 | static struct pnv_ioda_pe *pnv_ioda_init_pe(struct pnv_phb *phb, int pe_no) | 134 | static struct pnv_ioda_pe *pnv_ioda_init_pe(struct pnv_phb *phb, int pe_no) |
128 | { | 135 | { |
129 | phb->ioda.pe_array[pe_no].phb = phb; | 136 | phb->ioda.pe_array[pe_no].phb = phb; |
@@ -149,7 +156,7 @@ static void pnv_ioda_reserve_pe(struct pnv_phb *phb, int pe_no) | |||
149 | 156 | ||
150 | static struct pnv_ioda_pe *pnv_ioda_alloc_pe(struct pnv_phb *phb) | 157 | static struct pnv_ioda_pe *pnv_ioda_alloc_pe(struct pnv_phb *phb) |
151 | { | 158 | { |
152 | unsigned long pe = phb->ioda.total_pe_num - 1; | 159 | long pe; |
153 | 160 | ||
154 | for (pe = phb->ioda.total_pe_num - 1; pe >= 0; pe--) { | 161 | for (pe = phb->ioda.total_pe_num - 1; pe >= 0; pe--) { |
155 | if (!test_and_set_bit(pe, phb->ioda.pe_alloc)) | 162 | if (!test_and_set_bit(pe, phb->ioda.pe_alloc)) |
@@ -162,11 +169,12 @@ static struct pnv_ioda_pe *pnv_ioda_alloc_pe(struct pnv_phb *phb) | |||
162 | static void pnv_ioda_free_pe(struct pnv_ioda_pe *pe) | 169 | static void pnv_ioda_free_pe(struct pnv_ioda_pe *pe) |
163 | { | 170 | { |
164 | struct pnv_phb *phb = pe->phb; | 171 | struct pnv_phb *phb = pe->phb; |
172 | unsigned int pe_num = pe->pe_number; | ||
165 | 173 | ||
166 | WARN_ON(pe->pdev); | 174 | WARN_ON(pe->pdev); |
167 | 175 | ||
168 | memset(pe, 0, sizeof(struct pnv_ioda_pe)); | 176 | memset(pe, 0, sizeof(struct pnv_ioda_pe)); |
169 | clear_bit(pe->pe_number, phb->ioda.pe_alloc); | 177 | clear_bit(pe_num, phb->ioda.pe_alloc); |
170 | } | 178 | } |
171 | 179 | ||
172 | /* The default M64 BAR is shared by all PEs */ | 180 | /* The default M64 BAR is shared by all PEs */ |
@@ -2216,7 +2224,7 @@ static long pnv_pci_ioda2_set_window(struct iommu_table_group *table_group, | |||
2216 | 2224 | ||
2217 | pnv_pci_link_table_and_group(phb->hose->node, num, | 2225 | pnv_pci_link_table_and_group(phb->hose->node, num, |
2218 | tbl, &pe->table_group); | 2226 | tbl, &pe->table_group); |
2219 | pnv_pci_phb3_tce_invalidate_pe(pe); | 2227 | pnv_pci_ioda2_tce_invalidate_pe(pe); |
2220 | 2228 | ||
2221 | return 0; | 2229 | return 0; |
2222 | } | 2230 | } |
@@ -2354,7 +2362,7 @@ static long pnv_pci_ioda2_unset_window(struct iommu_table_group *table_group, | |||
2354 | if (ret) | 2362 | if (ret) |
2355 | pe_warn(pe, "Unmapping failed, ret = %ld\n", ret); | 2363 | pe_warn(pe, "Unmapping failed, ret = %ld\n", ret); |
2356 | else | 2364 | else |
2357 | pnv_pci_phb3_tce_invalidate_pe(pe); | 2365 | pnv_pci_ioda2_tce_invalidate_pe(pe); |
2358 | 2366 | ||
2359 | pnv_pci_unlink_table_and_group(table_group->tables[num], table_group); | 2367 | pnv_pci_unlink_table_and_group(table_group->tables[num], table_group); |
2360 | 2368 | ||
@@ -2870,7 +2878,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) | |||
2870 | res = &pdev->resource[i + PCI_IOV_RESOURCES]; | 2878 | res = &pdev->resource[i + PCI_IOV_RESOURCES]; |
2871 | if (!res->flags || res->parent) | 2879 | if (!res->flags || res->parent) |
2872 | continue; | 2880 | continue; |
2873 | if (!pnv_pci_is_m64(phb, res)) { | 2881 | if (!pnv_pci_is_m64_flags(res->flags)) { |
2874 | dev_warn(&pdev->dev, "Don't support SR-IOV with" | 2882 | dev_warn(&pdev->dev, "Don't support SR-IOV with" |
2875 | " non M64 VF BAR%d: %pR. \n", | 2883 | " non M64 VF BAR%d: %pR. \n", |
2876 | i, res); | 2884 | i, res); |
@@ -3095,7 +3103,7 @@ static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus, | |||
3095 | * alignment for any 64-bit resource, PCIe doesn't care and | 3103 | * alignment for any 64-bit resource, PCIe doesn't care and |
3096 | * bridges only do 64-bit prefetchable anyway. | 3104 | * bridges only do 64-bit prefetchable anyway. |
3097 | */ | 3105 | */ |
3098 | if (phb->ioda.m64_segsize && (type & IORESOURCE_MEM_64)) | 3106 | if (phb->ioda.m64_segsize && pnv_pci_is_m64_flags(type)) |
3099 | return phb->ioda.m64_segsize; | 3107 | return phb->ioda.m64_segsize; |
3100 | if (type & IORESOURCE_MEM) | 3108 | if (type & IORESOURCE_MEM) |
3101 | return phb->ioda.m32_segsize; | 3109 | return phb->ioda.m32_segsize; |
@@ -3402,12 +3410,6 @@ static void pnv_ioda_release_pe(struct pnv_ioda_pe *pe) | |||
3402 | struct pnv_phb *phb = pe->phb; | 3410 | struct pnv_phb *phb = pe->phb; |
3403 | struct pnv_ioda_pe *slave, *tmp; | 3411 | struct pnv_ioda_pe *slave, *tmp; |
3404 | 3412 | ||
3405 | /* Release slave PEs in compound PE */ | ||
3406 | if (pe->flags & PNV_IODA_PE_MASTER) { | ||
3407 | list_for_each_entry_safe(slave, tmp, &pe->slaves, list) | ||
3408 | pnv_ioda_release_pe(slave); | ||
3409 | } | ||
3410 | |||
3411 | list_del(&pe->list); | 3413 | list_del(&pe->list); |
3412 | switch (phb->type) { | 3414 | switch (phb->type) { |
3413 | case PNV_PHB_IODA1: | 3415 | case PNV_PHB_IODA1: |
@@ -3422,7 +3424,26 @@ static void pnv_ioda_release_pe(struct pnv_ioda_pe *pe) | |||
3422 | 3424 | ||
3423 | pnv_ioda_release_pe_seg(pe); | 3425 | pnv_ioda_release_pe_seg(pe); |
3424 | pnv_ioda_deconfigure_pe(pe->phb, pe); | 3426 | pnv_ioda_deconfigure_pe(pe->phb, pe); |
3425 | pnv_ioda_free_pe(pe); | 3427 | |
3428 | /* Release slave PEs in the compound PE */ | ||
3429 | if (pe->flags & PNV_IODA_PE_MASTER) { | ||
3430 | list_for_each_entry_safe(slave, tmp, &pe->slaves, list) { | ||
3431 | list_del(&slave->list); | ||
3432 | pnv_ioda_free_pe(slave); | ||
3433 | } | ||
3434 | } | ||
3435 | |||
3436 | /* | ||
3437 | * The PE for root bus can be removed because of hotplug in EEH | ||
3438 | * recovery for fenced PHB error. We need to mark the PE dead so | ||
3439 | * that it can be populated again in PCI hot add path. The PE | ||
3440 | * shouldn't be destroyed as it's the global reserved resource. | ||
3441 | */ | ||
3442 | if (phb->ioda.root_pe_populated && | ||
3443 | phb->ioda.root_pe_idx == pe->pe_number) | ||
3444 | phb->ioda.root_pe_populated = false; | ||
3445 | else | ||
3446 | pnv_ioda_free_pe(pe); | ||
3426 | } | 3447 | } |
3427 | 3448 | ||
3428 | static void pnv_pci_release_device(struct pci_dev *pdev) | 3449 | static void pnv_pci_release_device(struct pci_dev *pdev) |
@@ -3438,7 +3459,17 @@ static void pnv_pci_release_device(struct pci_dev *pdev) | |||
3438 | if (!pdn || pdn->pe_number == IODA_INVALID_PE) | 3459 | if (!pdn || pdn->pe_number == IODA_INVALID_PE) |
3439 | return; | 3460 | return; |
3440 | 3461 | ||
3462 | /* | ||
3463 | * PCI hotplug can happen as part of EEH error recovery. The @pdn | ||
3464 | * isn't removed and added afterwards in this scenario. We should | ||
3465 | * set the PE number in @pdn to an invalid one. Otherwise, the PE's | ||
3466 | * device count is decreased on removing devices while failing to | ||
3467 | * be increased on adding devices. It leads to unbalanced PE's device | ||
3468 | * count and eventually make normal PCI hotplug path broken. | ||
3469 | */ | ||
3441 | pe = &phb->ioda.pe_array[pdn->pe_number]; | 3470 | pe = &phb->ioda.pe_array[pdn->pe_number]; |
3471 | pdn->pe_number = IODA_INVALID_PE; | ||
3472 | |||
3442 | WARN_ON(--pe->device_count < 0); | 3473 | WARN_ON(--pe->device_count < 0); |
3443 | if (pe->device_count == 0) | 3474 | if (pe->device_count == 0) |
3444 | pnv_ioda_release_pe(pe); | 3475 | pnv_ioda_release_pe(pe); |
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c index fe16a50700de..09eba5a9929a 100644 --- a/arch/powerpc/platforms/pseries/pci.c +++ b/arch/powerpc/platforms/pseries/pci.c | |||
@@ -119,6 +119,10 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge) | |||
119 | 119 | ||
120 | bus = bridge->bus; | 120 | bus = bridge->bus; |
121 | 121 | ||
122 | /* Rely on the pcibios_free_controller_deferred() callback. */ | ||
123 | pci_set_host_bridge_release(bridge, pcibios_free_controller_deferred, | ||
124 | (void *) pci_bus_to_host(bus)); | ||
125 | |||
122 | dn = pcibios_get_phb_of_node(bus); | 126 | dn = pcibios_get_phb_of_node(bus); |
123 | if (!dn) | 127 | if (!dn) |
124 | return 0; | 128 | return 0; |
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index 906dbaa97fe2..547fd13e4f8e 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c | |||
@@ -106,8 +106,11 @@ int remove_phb_dynamic(struct pci_controller *phb) | |||
106 | release_resource(res); | 106 | release_resource(res); |
107 | } | 107 | } |
108 | 108 | ||
109 | /* Free pci_controller data structure */ | 109 | /* |
110 | pcibios_free_controller(phb); | 110 | * The pci_controller data structure is freed by |
111 | * the pcibios_free_controller_deferred() callback; | ||
112 | * see pseries_root_bridge_prepare(). | ||
113 | */ | ||
111 | 114 | ||
112 | return 0; | 115 | return 0; |
113 | } | 116 | } |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 4ffcaa6f8670..a39d20e8623d 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <linux/root_dev.h> | 41 | #include <linux/root_dev.h> |
42 | #include <linux/of.h> | 42 | #include <linux/of.h> |
43 | #include <linux/of_pci.h> | 43 | #include <linux/of_pci.h> |
44 | #include <linux/kexec.h> | ||
45 | 44 | ||
46 | #include <asm/mmu.h> | 45 | #include <asm/mmu.h> |
47 | #include <asm/processor.h> | 46 | #include <asm/processor.h> |
@@ -66,6 +65,7 @@ | |||
66 | #include <asm/eeh.h> | 65 | #include <asm/eeh.h> |
67 | #include <asm/reg.h> | 66 | #include <asm/reg.h> |
68 | #include <asm/plpar_wrappers.h> | 67 | #include <asm/plpar_wrappers.h> |
68 | #include <asm/kexec.h> | ||
69 | 69 | ||
70 | #include "pseries.h" | 70 | #include "pseries.h" |
71 | 71 | ||
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index 6c110994d902..81d49476c47e 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c | |||
@@ -534,7 +534,8 @@ struct cpm1_gpio16_chip { | |||
534 | 534 | ||
535 | static void cpm1_gpio16_save_regs(struct of_mm_gpio_chip *mm_gc) | 535 | static void cpm1_gpio16_save_regs(struct of_mm_gpio_chip *mm_gc) |
536 | { | 536 | { |
537 | struct cpm1_gpio16_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); | 537 | struct cpm1_gpio16_chip *cpm1_gc = |
538 | container_of(mm_gc, struct cpm1_gpio16_chip, mm_gc); | ||
538 | struct cpm_ioport16 __iomem *iop = mm_gc->regs; | 539 | struct cpm_ioport16 __iomem *iop = mm_gc->regs; |
539 | 540 | ||
540 | cpm1_gc->cpdata = in_be16(&iop->dat); | 541 | cpm1_gc->cpdata = in_be16(&iop->dat); |
@@ -649,7 +650,8 @@ struct cpm1_gpio32_chip { | |||
649 | 650 | ||
650 | static void cpm1_gpio32_save_regs(struct of_mm_gpio_chip *mm_gc) | 651 | static void cpm1_gpio32_save_regs(struct of_mm_gpio_chip *mm_gc) |
651 | { | 652 | { |
652 | struct cpm1_gpio32_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); | 653 | struct cpm1_gpio32_chip *cpm1_gc = |
654 | container_of(mm_gc, struct cpm1_gpio32_chip, mm_gc); | ||
653 | struct cpm_ioport32b __iomem *iop = mm_gc->regs; | 655 | struct cpm_ioport32b __iomem *iop = mm_gc->regs; |
654 | 656 | ||
655 | cpm1_gc->cpdata = in_be32(&iop->dat); | 657 | cpm1_gc->cpdata = in_be32(&iop->dat); |
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 911456d17713..947f42007734 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c | |||
@@ -94,7 +94,8 @@ struct cpm2_gpio32_chip { | |||
94 | 94 | ||
95 | static void cpm2_gpio32_save_regs(struct of_mm_gpio_chip *mm_gc) | 95 | static void cpm2_gpio32_save_regs(struct of_mm_gpio_chip *mm_gc) |
96 | { | 96 | { |
97 | struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(&mm_gc->gc); | 97 | struct cpm2_gpio32_chip *cpm2_gc = |
98 | container_of(mm_gc, struct cpm2_gpio32_chip, mm_gc); | ||
98 | struct cpm2_ioports __iomem *iop = mm_gc->regs; | 99 | struct cpm2_ioports __iomem *iop = mm_gc->regs; |
99 | 100 | ||
100 | cpm2_gc->cpdata = in_be32(&iop->dat); | 101 | cpm2_gc->cpdata = in_be32(&iop->dat); |
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 68e7c0dd2e45..3cc7cace194a 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c | |||
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/module.h> | 26 | #include <linux/extable.h> |
27 | #include <linux/types.h> | 27 | #include <linux/types.h> |
28 | #include <linux/dma-mapping.h> | 28 | #include <linux/dma-mapping.h> |
29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
diff --git a/arch/powerpc/sysdev/xics/icp-opal.c b/arch/powerpc/sysdev/xics/icp-opal.c index 57d72f10a97f..9114243fa1b5 100644 --- a/arch/powerpc/sysdev/xics/icp-opal.c +++ b/arch/powerpc/sysdev/xics/icp-opal.c | |||
@@ -23,10 +23,10 @@ | |||
23 | 23 | ||
24 | static void icp_opal_teardown_cpu(void) | 24 | static void icp_opal_teardown_cpu(void) |
25 | { | 25 | { |
26 | int cpu = smp_processor_id(); | 26 | int hw_cpu = hard_smp_processor_id(); |
27 | 27 | ||
28 | /* Clear any pending IPI */ | 28 | /* Clear any pending IPI */ |
29 | opal_int_set_mfrr(cpu, 0xff); | 29 | opal_int_set_mfrr(hw_cpu, 0xff); |
30 | } | 30 | } |
31 | 31 | ||
32 | static void icp_opal_flush_ipi(void) | 32 | static void icp_opal_flush_ipi(void) |
@@ -101,14 +101,16 @@ static void icp_opal_eoi(struct irq_data *d) | |||
101 | 101 | ||
102 | static void icp_opal_cause_ipi(int cpu, unsigned long data) | 102 | static void icp_opal_cause_ipi(int cpu, unsigned long data) |
103 | { | 103 | { |
104 | opal_int_set_mfrr(cpu, IPI_PRIORITY); | 104 | int hw_cpu = get_hard_smp_processor_id(cpu); |
105 | |||
106 | opal_int_set_mfrr(hw_cpu, IPI_PRIORITY); | ||
105 | } | 107 | } |
106 | 108 | ||
107 | static irqreturn_t icp_opal_ipi_action(int irq, void *dev_id) | 109 | static irqreturn_t icp_opal_ipi_action(int irq, void *dev_id) |
108 | { | 110 | { |
109 | int cpu = smp_processor_id(); | 111 | int hw_cpu = hard_smp_processor_id(); |
110 | 112 | ||
111 | opal_int_set_mfrr(cpu, 0xff); | 113 | opal_int_set_mfrr(hw_cpu, 0xff); |
112 | 114 | ||
113 | return smp_ipi_demux(); | 115 | return smp_ipi_demux(); |
114 | } | 116 | } |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index e751fe25d6ab..c109f073d454 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -68,7 +68,6 @@ config DEBUG_RODATA | |||
68 | config S390 | 68 | config S390 |
69 | def_bool y | 69 | def_bool y |
70 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | 70 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE |
71 | select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS | ||
72 | select ARCH_HAS_DEVMEM_IS_ALLOWED | 71 | select ARCH_HAS_DEVMEM_IS_ALLOWED |
73 | select ARCH_HAS_ELF_RANDOMIZE | 72 | select ARCH_HAS_ELF_RANDOMIZE |
74 | select ARCH_HAS_GCOV_PROFILE_ALL | 73 | select ARCH_HAS_GCOV_PROFILE_ALL |
diff --git a/arch/s390/configs/default_defconfig b/arch/s390/configs/default_defconfig index 26e0c7f08814..412b1bd21029 100644 --- a/arch/s390/configs/default_defconfig +++ b/arch/s390/configs/default_defconfig | |||
@@ -602,7 +602,6 @@ CONFIG_FAIL_FUTEX=y | |||
602 | CONFIG_FAULT_INJECTION_DEBUG_FS=y | 602 | CONFIG_FAULT_INJECTION_DEBUG_FS=y |
603 | CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y | 603 | CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y |
604 | CONFIG_LATENCYTOP=y | 604 | CONFIG_LATENCYTOP=y |
605 | CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y | ||
606 | CONFIG_IRQSOFF_TRACER=y | 605 | CONFIG_IRQSOFF_TRACER=y |
607 | CONFIG_PREEMPT_TRACER=y | 606 | CONFIG_PREEMPT_TRACER=y |
608 | CONFIG_SCHED_TRACER=y | 607 | CONFIG_SCHED_TRACER=y |
diff --git a/arch/s390/configs/gcov_defconfig b/arch/s390/configs/gcov_defconfig index 24879dab47bc..bec279eb4b93 100644 --- a/arch/s390/configs/gcov_defconfig +++ b/arch/s390/configs/gcov_defconfig | |||
@@ -552,7 +552,6 @@ CONFIG_NOTIFIER_ERROR_INJECTION=m | |||
552 | CONFIG_CPU_NOTIFIER_ERROR_INJECT=m | 552 | CONFIG_CPU_NOTIFIER_ERROR_INJECT=m |
553 | CONFIG_PM_NOTIFIER_ERROR_INJECT=m | 553 | CONFIG_PM_NOTIFIER_ERROR_INJECT=m |
554 | CONFIG_LATENCYTOP=y | 554 | CONFIG_LATENCYTOP=y |
555 | CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y | ||
556 | CONFIG_BLK_DEV_IO_TRACE=y | 555 | CONFIG_BLK_DEV_IO_TRACE=y |
557 | # CONFIG_KPROBE_EVENT is not set | 556 | # CONFIG_KPROBE_EVENT is not set |
558 | CONFIG_TRACE_ENUM_MAP_FILE=y | 557 | CONFIG_TRACE_ENUM_MAP_FILE=y |
diff --git a/arch/s390/configs/performance_defconfig b/arch/s390/configs/performance_defconfig index a5c1e5f2a0ca..1751446a5bbb 100644 --- a/arch/s390/configs/performance_defconfig +++ b/arch/s390/configs/performance_defconfig | |||
@@ -549,7 +549,6 @@ CONFIG_TIMER_STATS=y | |||
549 | CONFIG_RCU_TORTURE_TEST=m | 549 | CONFIG_RCU_TORTURE_TEST=m |
550 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 | 550 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 |
551 | CONFIG_LATENCYTOP=y | 551 | CONFIG_LATENCYTOP=y |
552 | CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y | ||
553 | CONFIG_SCHED_TRACER=y | 552 | CONFIG_SCHED_TRACER=y |
554 | CONFIG_FTRACE_SYSCALLS=y | 553 | CONFIG_FTRACE_SYSCALLS=y |
555 | CONFIG_STACK_TRACER=y | 554 | CONFIG_STACK_TRACER=y |
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 73610f2e3b4f..2d40ef0a6295 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
@@ -172,7 +172,6 @@ CONFIG_DEBUG_NOTIFIERS=y | |||
172 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 | 172 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 |
173 | CONFIG_RCU_TRACE=y | 173 | CONFIG_RCU_TRACE=y |
174 | CONFIG_LATENCYTOP=y | 174 | CONFIG_LATENCYTOP=y |
175 | CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y | ||
176 | CONFIG_SCHED_TRACER=y | 175 | CONFIG_SCHED_TRACER=y |
177 | CONFIG_FTRACE_SYSCALLS=y | 176 | CONFIG_FTRACE_SYSCALLS=y |
178 | CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y | 177 | CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y |
diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index 9b49cf1daa8f..52d7c8709279 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h | |||
@@ -266,28 +266,28 @@ int __put_user_bad(void) __attribute__((noreturn)); | |||
266 | __chk_user_ptr(ptr); \ | 266 | __chk_user_ptr(ptr); \ |
267 | switch (sizeof(*(ptr))) { \ | 267 | switch (sizeof(*(ptr))) { \ |
268 | case 1: { \ | 268 | case 1: { \ |
269 | unsigned char __x; \ | 269 | unsigned char __x = 0; \ |
270 | __gu_err = __get_user_fn(&__x, ptr, \ | 270 | __gu_err = __get_user_fn(&__x, ptr, \ |
271 | sizeof(*(ptr))); \ | 271 | sizeof(*(ptr))); \ |
272 | (x) = *(__force __typeof__(*(ptr)) *) &__x; \ | 272 | (x) = *(__force __typeof__(*(ptr)) *) &__x; \ |
273 | break; \ | 273 | break; \ |
274 | }; \ | 274 | }; \ |
275 | case 2: { \ | 275 | case 2: { \ |
276 | unsigned short __x; \ | 276 | unsigned short __x = 0; \ |
277 | __gu_err = __get_user_fn(&__x, ptr, \ | 277 | __gu_err = __get_user_fn(&__x, ptr, \ |
278 | sizeof(*(ptr))); \ | 278 | sizeof(*(ptr))); \ |
279 | (x) = *(__force __typeof__(*(ptr)) *) &__x; \ | 279 | (x) = *(__force __typeof__(*(ptr)) *) &__x; \ |
280 | break; \ | 280 | break; \ |
281 | }; \ | 281 | }; \ |
282 | case 4: { \ | 282 | case 4: { \ |
283 | unsigned int __x; \ | 283 | unsigned int __x = 0; \ |
284 | __gu_err = __get_user_fn(&__x, ptr, \ | 284 | __gu_err = __get_user_fn(&__x, ptr, \ |
285 | sizeof(*(ptr))); \ | 285 | sizeof(*(ptr))); \ |
286 | (x) = *(__force __typeof__(*(ptr)) *) &__x; \ | 286 | (x) = *(__force __typeof__(*(ptr)) *) &__x; \ |
287 | break; \ | 287 | break; \ |
288 | }; \ | 288 | }; \ |
289 | case 8: { \ | 289 | case 8: { \ |
290 | unsigned long long __x; \ | 290 | unsigned long long __x = 0; \ |
291 | __gu_err = __get_user_fn(&__x, ptr, \ | 291 | __gu_err = __get_user_fn(&__x, ptr, \ |
292 | sizeof(*(ptr))); \ | 292 | sizeof(*(ptr))); \ |
293 | (x) = *(__force __typeof__(*(ptr)) *) &__x; \ | 293 | (x) = *(__force __typeof__(*(ptr)) *) &__x; \ |
@@ -311,6 +311,14 @@ int __get_user_bad(void) __attribute__((noreturn)); | |||
311 | #define __put_user_unaligned __put_user | 311 | #define __put_user_unaligned __put_user |
312 | #define __get_user_unaligned __get_user | 312 | #define __get_user_unaligned __get_user |
313 | 313 | ||
314 | extern void __compiletime_error("usercopy buffer size is too small") | ||
315 | __bad_copy_user(void); | ||
316 | |||
317 | static inline void copy_user_overflow(int size, unsigned long count) | ||
318 | { | ||
319 | WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count); | ||
320 | } | ||
321 | |||
314 | /** | 322 | /** |
315 | * copy_to_user: - Copy a block of data into user space. | 323 | * copy_to_user: - Copy a block of data into user space. |
316 | * @to: Destination address, in user space. | 324 | * @to: Destination address, in user space. |
@@ -332,12 +340,6 @@ copy_to_user(void __user *to, const void *from, unsigned long n) | |||
332 | return __copy_to_user(to, from, n); | 340 | return __copy_to_user(to, from, n); |
333 | } | 341 | } |
334 | 342 | ||
335 | void copy_from_user_overflow(void) | ||
336 | #ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS | ||
337 | __compiletime_warning("copy_from_user() buffer size is not provably correct") | ||
338 | #endif | ||
339 | ; | ||
340 | |||
341 | /** | 343 | /** |
342 | * copy_from_user: - Copy a block of data from user space. | 344 | * copy_from_user: - Copy a block of data from user space. |
343 | * @to: Destination address, in kernel space. | 345 | * @to: Destination address, in kernel space. |
@@ -362,7 +364,10 @@ copy_from_user(void *to, const void __user *from, unsigned long n) | |||
362 | 364 | ||
363 | might_fault(); | 365 | might_fault(); |
364 | if (unlikely(sz != -1 && sz < n)) { | 366 | if (unlikely(sz != -1 && sz < n)) { |
365 | copy_from_user_overflow(); | 367 | if (!__builtin_constant_p(n)) |
368 | copy_user_overflow(sz, n); | ||
369 | else | ||
370 | __bad_copy_user(); | ||
366 | return n; | 371 | return n; |
367 | } | 372 | } |
368 | return __copy_from_user(to, from, n); | 373 | return __copy_from_user(to, from, n); |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index ba5f456edaa9..7f7ba5f23f13 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -204,11 +204,9 @@ static void __init conmode_default(void) | |||
204 | #endif | 204 | #endif |
205 | } | 205 | } |
206 | } else if (MACHINE_IS_KVM) { | 206 | } else if (MACHINE_IS_KVM) { |
207 | if (sclp.has_vt220 && | 207 | if (sclp.has_vt220 && IS_ENABLED(CONFIG_SCLP_VT220_CONSOLE)) |
208 | config_enabled(CONFIG_SCLP_VT220_CONSOLE)) | ||
209 | SET_CONSOLE_VT220; | 208 | SET_CONSOLE_VT220; |
210 | else if (sclp.has_linemode && | 209 | else if (sclp.has_linemode && IS_ENABLED(CONFIG_SCLP_CONSOLE)) |
211 | config_enabled(CONFIG_SCLP_CONSOLE)) | ||
212 | SET_CONSOLE_SCLP; | 210 | SET_CONSOLE_SCLP; |
213 | else | 211 | else |
214 | SET_CONSOLE_HVC; | 212 | SET_CONSOLE_HVC; |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index f142215ed30d..607ec91966c7 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -2231,9 +2231,10 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) | |||
2231 | return -EINVAL; | 2231 | return -EINVAL; |
2232 | current->thread.fpu.fpc = fpu->fpc; | 2232 | current->thread.fpu.fpc = fpu->fpc; |
2233 | if (MACHINE_HAS_VX) | 2233 | if (MACHINE_HAS_VX) |
2234 | convert_fp_to_vx(current->thread.fpu.vxrs, (freg_t *)fpu->fprs); | 2234 | convert_fp_to_vx((__vector128 *) vcpu->run->s.regs.vrs, |
2235 | (freg_t *) fpu->fprs); | ||
2235 | else | 2236 | else |
2236 | memcpy(current->thread.fpu.fprs, &fpu->fprs, sizeof(fpu->fprs)); | 2237 | memcpy(vcpu->run->s.regs.fprs, &fpu->fprs, sizeof(fpu->fprs)); |
2237 | return 0; | 2238 | return 0; |
2238 | } | 2239 | } |
2239 | 2240 | ||
@@ -2242,9 +2243,10 @@ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) | |||
2242 | /* make sure we have the latest values */ | 2243 | /* make sure we have the latest values */ |
2243 | save_fpu_regs(); | 2244 | save_fpu_regs(); |
2244 | if (MACHINE_HAS_VX) | 2245 | if (MACHINE_HAS_VX) |
2245 | convert_vx_to_fp((freg_t *)fpu->fprs, current->thread.fpu.vxrs); | 2246 | convert_vx_to_fp((freg_t *) fpu->fprs, |
2247 | (__vector128 *) vcpu->run->s.regs.vrs); | ||
2246 | else | 2248 | else |
2247 | memcpy(fpu->fprs, current->thread.fpu.fprs, sizeof(fpu->fprs)); | 2249 | memcpy(fpu->fprs, vcpu->run->s.regs.fprs, sizeof(fpu->fprs)); |
2248 | fpu->fpc = current->thread.fpu.fpc; | 2250 | fpu->fpc = current->thread.fpu.fpc; |
2249 | return 0; | 2251 | return 0; |
2250 | } | 2252 | } |
diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c index c106488b4137..d8673e243f13 100644 --- a/arch/s390/kvm/vsie.c +++ b/arch/s390/kvm/vsie.c | |||
@@ -584,7 +584,7 @@ static int pin_blocks(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) | |||
584 | /* Validity 0x0044 will be checked by SIE */ | 584 | /* Validity 0x0044 will be checked by SIE */ |
585 | if (rc) | 585 | if (rc) |
586 | goto unpin; | 586 | goto unpin; |
587 | scb_s->gvrd = hpa; | 587 | scb_s->riccbd = hpa; |
588 | } | 588 | } |
589 | return 0; | 589 | return 0; |
590 | unpin: | 590 | unpin: |
diff --git a/arch/score/include/asm/uaccess.h b/arch/score/include/asm/uaccess.h index 20a3591225cc..01aec8ccde83 100644 --- a/arch/score/include/asm/uaccess.h +++ b/arch/score/include/asm/uaccess.h | |||
@@ -163,7 +163,7 @@ do { \ | |||
163 | __get_user_asm(val, "lw", ptr); \ | 163 | __get_user_asm(val, "lw", ptr); \ |
164 | break; \ | 164 | break; \ |
165 | case 8: \ | 165 | case 8: \ |
166 | if ((copy_from_user((void *)&val, ptr, 8)) == 0) \ | 166 | if (__copy_from_user((void *)&val, ptr, 8) == 0) \ |
167 | __gu_err = 0; \ | 167 | __gu_err = 0; \ |
168 | else \ | 168 | else \ |
169 | __gu_err = -EFAULT; \ | 169 | __gu_err = -EFAULT; \ |
@@ -188,6 +188,8 @@ do { \ | |||
188 | \ | 188 | \ |
189 | if (likely(access_ok(VERIFY_READ, __gu_ptr, size))) \ | 189 | if (likely(access_ok(VERIFY_READ, __gu_ptr, size))) \ |
190 | __get_user_common((x), size, __gu_ptr); \ | 190 | __get_user_common((x), size, __gu_ptr); \ |
191 | else \ | ||
192 | (x) = 0; \ | ||
191 | \ | 193 | \ |
192 | __gu_err; \ | 194 | __gu_err; \ |
193 | }) | 195 | }) |
@@ -201,6 +203,7 @@ do { \ | |||
201 | "2:\n" \ | 203 | "2:\n" \ |
202 | ".section .fixup,\"ax\"\n" \ | 204 | ".section .fixup,\"ax\"\n" \ |
203 | "3:li %0, %4\n" \ | 205 | "3:li %0, %4\n" \ |
206 | "li %1, 0\n" \ | ||
204 | "j 2b\n" \ | 207 | "j 2b\n" \ |
205 | ".previous\n" \ | 208 | ".previous\n" \ |
206 | ".section __ex_table,\"a\"\n" \ | 209 | ".section __ex_table,\"a\"\n" \ |
@@ -298,35 +301,34 @@ extern int __copy_tofrom_user(void *to, const void *from, unsigned long len); | |||
298 | static inline unsigned long | 301 | static inline unsigned long |
299 | copy_from_user(void *to, const void *from, unsigned long len) | 302 | copy_from_user(void *to, const void *from, unsigned long len) |
300 | { | 303 | { |
301 | unsigned long over; | 304 | unsigned long res = len; |
302 | 305 | ||
303 | if (access_ok(VERIFY_READ, from, len)) | 306 | if (likely(access_ok(VERIFY_READ, from, len))) |
304 | return __copy_tofrom_user(to, from, len); | 307 | res = __copy_tofrom_user(to, from, len); |
305 | 308 | ||
306 | if ((unsigned long)from < TASK_SIZE) { | 309 | if (unlikely(res)) |
307 | over = (unsigned long)from + len - TASK_SIZE; | 310 | memset(to + (len - res), 0, res); |
308 | return __copy_tofrom_user(to, from, len - over) + over; | 311 | |
309 | } | 312 | return res; |
310 | return len; | ||
311 | } | 313 | } |
312 | 314 | ||
313 | static inline unsigned long | 315 | static inline unsigned long |
314 | copy_to_user(void *to, const void *from, unsigned long len) | 316 | copy_to_user(void *to, const void *from, unsigned long len) |
315 | { | 317 | { |
316 | unsigned long over; | 318 | if (likely(access_ok(VERIFY_WRITE, to, len))) |
317 | 319 | len = __copy_tofrom_user(to, from, len); | |
318 | if (access_ok(VERIFY_WRITE, to, len)) | ||
319 | return __copy_tofrom_user(to, from, len); | ||
320 | 320 | ||
321 | if ((unsigned long)to < TASK_SIZE) { | ||
322 | over = (unsigned long)to + len - TASK_SIZE; | ||
323 | return __copy_tofrom_user(to, from, len - over) + over; | ||
324 | } | ||
325 | return len; | 321 | return len; |
326 | } | 322 | } |
327 | 323 | ||
328 | #define __copy_from_user(to, from, len) \ | 324 | static inline unsigned long |
329 | __copy_tofrom_user((to), (from), (len)) | 325 | __copy_from_user(void *to, const void *from, unsigned long len) |
326 | { | ||
327 | unsigned long left = __copy_tofrom_user(to, from, len); | ||
328 | if (unlikely(left)) | ||
329 | memset(to + (len - left), 0, left); | ||
330 | return left; | ||
331 | } | ||
330 | 332 | ||
331 | #define __copy_to_user(to, from, len) \ | 333 | #define __copy_to_user(to, from, len) \ |
332 | __copy_tofrom_user((to), (from), (len)) | 334 | __copy_tofrom_user((to), (from), (len)) |
@@ -340,17 +342,17 @@ __copy_to_user_inatomic(void *to, const void *from, unsigned long len) | |||
340 | static inline unsigned long | 342 | static inline unsigned long |
341 | __copy_from_user_inatomic(void *to, const void *from, unsigned long len) | 343 | __copy_from_user_inatomic(void *to, const void *from, unsigned long len) |
342 | { | 344 | { |
343 | return __copy_from_user(to, from, len); | 345 | return __copy_tofrom_user(to, from, len); |
344 | } | 346 | } |
345 | 347 | ||
346 | #define __copy_in_user(to, from, len) __copy_from_user(to, from, len) | 348 | #define __copy_in_user(to, from, len) __copy_tofrom_user(to, from, len) |
347 | 349 | ||
348 | static inline unsigned long | 350 | static inline unsigned long |
349 | copy_in_user(void *to, const void *from, unsigned long len) | 351 | copy_in_user(void *to, const void *from, unsigned long len) |
350 | { | 352 | { |
351 | if (access_ok(VERIFY_READ, from, len) && | 353 | if (access_ok(VERIFY_READ, from, len) && |
352 | access_ok(VERFITY_WRITE, to, len)) | 354 | access_ok(VERFITY_WRITE, to, len)) |
353 | return copy_from_user(to, from, len); | 355 | return __copy_tofrom_user(to, from, len); |
354 | } | 356 | } |
355 | 357 | ||
356 | /* | 358 | /* |
diff --git a/arch/sh/include/asm/atomic-llsc.h b/arch/sh/include/asm/atomic-llsc.h index caea2c45f6c2..1d159ce50f5a 100644 --- a/arch/sh/include/asm/atomic-llsc.h +++ b/arch/sh/include/asm/atomic-llsc.h | |||
@@ -60,7 +60,7 @@ static inline int atomic_fetch_##op(int i, atomic_t *v) \ | |||
60 | " movco.l %0, @%3 \n" \ | 60 | " movco.l %0, @%3 \n" \ |
61 | " bf 1b \n" \ | 61 | " bf 1b \n" \ |
62 | " synco \n" \ | 62 | " synco \n" \ |
63 | : "=&z" (temp), "=&z" (res) \ | 63 | : "=&z" (temp), "=&r" (res) \ |
64 | : "r" (i), "r" (&v->counter) \ | 64 | : "r" (i), "r" (&v->counter) \ |
65 | : "t"); \ | 65 | : "t"); \ |
66 | \ | 66 | \ |
diff --git a/arch/sh/include/asm/uaccess.h b/arch/sh/include/asm/uaccess.h index a49635c51266..92ade79ac427 100644 --- a/arch/sh/include/asm/uaccess.h +++ b/arch/sh/include/asm/uaccess.h | |||
@@ -151,7 +151,10 @@ copy_from_user(void *to, const void __user *from, unsigned long n) | |||
151 | __kernel_size_t __copy_size = (__kernel_size_t) n; | 151 | __kernel_size_t __copy_size = (__kernel_size_t) n; |
152 | 152 | ||
153 | if (__copy_size && __access_ok(__copy_from, __copy_size)) | 153 | if (__copy_size && __access_ok(__copy_from, __copy_size)) |
154 | return __copy_user(to, from, __copy_size); | 154 | __copy_size = __copy_user(to, from, __copy_size); |
155 | |||
156 | if (unlikely(__copy_size)) | ||
157 | memset(to + (n - __copy_size), 0, __copy_size); | ||
155 | 158 | ||
156 | return __copy_size; | 159 | return __copy_size; |
157 | } | 160 | } |
diff --git a/arch/sh/include/asm/uaccess_64.h b/arch/sh/include/asm/uaccess_64.h index c01376c76b86..ca5073dd4596 100644 --- a/arch/sh/include/asm/uaccess_64.h +++ b/arch/sh/include/asm/uaccess_64.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define __get_user_size(x,ptr,size,retval) \ | 24 | #define __get_user_size(x,ptr,size,retval) \ |
25 | do { \ | 25 | do { \ |
26 | retval = 0; \ | 26 | retval = 0; \ |
27 | x = 0; \ | ||
27 | switch (size) { \ | 28 | switch (size) { \ |
28 | case 1: \ | 29 | case 1: \ |
29 | retval = __get_user_asm_b((void *)&x, \ | 30 | retval = __get_user_asm_b((void *)&x, \ |
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h index 341a5a133f48..ea55f86d7ccd 100644 --- a/arch/sparc/include/asm/uaccess_32.h +++ b/arch/sparc/include/asm/uaccess_32.h | |||
@@ -249,8 +249,7 @@ unsigned long __copy_user(void __user *to, const void __user *from, unsigned lon | |||
249 | static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) | 249 | static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) |
250 | { | 250 | { |
251 | if (n && __access_ok((unsigned long) to, n)) { | 251 | if (n && __access_ok((unsigned long) to, n)) { |
252 | if (!__builtin_constant_p(n)) | 252 | check_object_size(from, n, true); |
253 | check_object_size(from, n, true); | ||
254 | return __copy_user(to, (__force void __user *) from, n); | 253 | return __copy_user(to, (__force void __user *) from, n); |
255 | } else | 254 | } else |
256 | return n; | 255 | return n; |
@@ -258,19 +257,19 @@ static inline unsigned long copy_to_user(void __user *to, const void *from, unsi | |||
258 | 257 | ||
259 | static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n) | 258 | static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n) |
260 | { | 259 | { |
261 | if (!__builtin_constant_p(n)) | 260 | check_object_size(from, n, true); |
262 | check_object_size(from, n, true); | ||
263 | return __copy_user(to, (__force void __user *) from, n); | 261 | return __copy_user(to, (__force void __user *) from, n); |
264 | } | 262 | } |
265 | 263 | ||
266 | static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) | 264 | static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) |
267 | { | 265 | { |
268 | if (n && __access_ok((unsigned long) from, n)) { | 266 | if (n && __access_ok((unsigned long) from, n)) { |
269 | if (!__builtin_constant_p(n)) | 267 | check_object_size(to, n, false); |
270 | check_object_size(to, n, false); | ||
271 | return __copy_user((__force void __user *) to, from, n); | 268 | return __copy_user((__force void __user *) to, from, n); |
272 | } else | 269 | } else { |
270 | memset(to, 0, n); | ||
273 | return n; | 271 | return n; |
272 | } | ||
274 | } | 273 | } |
275 | 274 | ||
276 | static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n) | 275 | static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n) |
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h index 8bda94fab8e8..37a315d0ddd4 100644 --- a/arch/sparc/include/asm/uaccess_64.h +++ b/arch/sparc/include/asm/uaccess_64.h | |||
@@ -212,8 +212,7 @@ copy_from_user(void *to, const void __user *from, unsigned long size) | |||
212 | { | 212 | { |
213 | unsigned long ret; | 213 | unsigned long ret; |
214 | 214 | ||
215 | if (!__builtin_constant_p(size)) | 215 | check_object_size(to, size, false); |
216 | check_object_size(to, size, false); | ||
217 | 216 | ||
218 | ret = ___copy_from_user(to, from, size); | 217 | ret = ___copy_from_user(to, from, size); |
219 | if (unlikely(ret)) | 218 | if (unlikely(ret)) |
@@ -233,8 +232,8 @@ copy_to_user(void __user *to, const void *from, unsigned long size) | |||
233 | { | 232 | { |
234 | unsigned long ret; | 233 | unsigned long ret; |
235 | 234 | ||
236 | if (!__builtin_constant_p(size)) | 235 | check_object_size(from, size, true); |
237 | check_object_size(from, size, true); | 236 | |
238 | ret = ___copy_to_user(to, from, size); | 237 | ret = ___copy_to_user(to, from, size); |
239 | if (unlikely(ret)) | 238 | if (unlikely(ret)) |
240 | ret = copy_to_user_fixup(to, from, size); | 239 | ret = copy_to_user_fixup(to, from, size); |
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 4820a02838ac..78da75b670bc 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig | |||
@@ -4,7 +4,6 @@ | |||
4 | config TILE | 4 | config TILE |
5 | def_bool y | 5 | def_bool y |
6 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | 6 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE |
7 | select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS | ||
8 | select ARCH_HAS_DEVMEM_IS_ALLOWED | 7 | select ARCH_HAS_DEVMEM_IS_ALLOWED |
9 | select ARCH_HAVE_NMI_SAFE_CMPXCHG | 8 | select ARCH_HAVE_NMI_SAFE_CMPXCHG |
10 | select ARCH_WANT_FRAME_POINTERS | 9 | select ARCH_WANT_FRAME_POINTERS |
diff --git a/arch/tile/include/asm/uaccess.h b/arch/tile/include/asm/uaccess.h index 0a9c4265763b..a77369e91e54 100644 --- a/arch/tile/include/asm/uaccess.h +++ b/arch/tile/include/asm/uaccess.h | |||
@@ -416,14 +416,13 @@ _copy_from_user(void *to, const void __user *from, unsigned long n) | |||
416 | return n; | 416 | return n; |
417 | } | 417 | } |
418 | 418 | ||
419 | #ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS | 419 | extern void __compiletime_error("usercopy buffer size is too small") |
420 | /* | 420 | __bad_copy_user(void); |
421 | * There are still unprovable places in the generic code as of 2.6.34, so this | 421 | |
422 | * option is not really compatible with -Werror, which is more useful in | 422 | static inline void copy_user_overflow(int size, unsigned long count) |
423 | * general. | 423 | { |
424 | */ | 424 | WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count); |
425 | extern void copy_from_user_overflow(void) | 425 | } |
426 | __compiletime_warning("copy_from_user() size is not provably correct"); | ||
427 | 426 | ||
428 | static inline unsigned long __must_check copy_from_user(void *to, | 427 | static inline unsigned long __must_check copy_from_user(void *to, |
429 | const void __user *from, | 428 | const void __user *from, |
@@ -433,14 +432,13 @@ static inline unsigned long __must_check copy_from_user(void *to, | |||
433 | 432 | ||
434 | if (likely(sz == -1 || sz >= n)) | 433 | if (likely(sz == -1 || sz >= n)) |
435 | n = _copy_from_user(to, from, n); | 434 | n = _copy_from_user(to, from, n); |
435 | else if (!__builtin_constant_p(n)) | ||
436 | copy_user_overflow(sz, n); | ||
436 | else | 437 | else |
437 | copy_from_user_overflow(); | 438 | __bad_copy_user(); |
438 | 439 | ||
439 | return n; | 440 | return n; |
440 | } | 441 | } |
441 | #else | ||
442 | #define copy_from_user _copy_from_user | ||
443 | #endif | ||
444 | 442 | ||
445 | #ifdef __tilegx__ | 443 | #ifdef __tilegx__ |
446 | /** | 444 | /** |
diff --git a/arch/um/include/asm/common.lds.S b/arch/um/include/asm/common.lds.S index 1dd5bd8a8c59..133055311dce 100644 --- a/arch/um/include/asm/common.lds.S +++ b/arch/um/include/asm/common.lds.S | |||
@@ -81,7 +81,7 @@ | |||
81 | .altinstr_replacement : { *(.altinstr_replacement) } | 81 | .altinstr_replacement : { *(.altinstr_replacement) } |
82 | /* .exit.text is discard at runtime, not link time, to deal with references | 82 | /* .exit.text is discard at runtime, not link time, to deal with references |
83 | from .altinstructions and .eh_frame */ | 83 | from .altinstructions and .eh_frame */ |
84 | .exit.text : { *(.exit.text) } | 84 | .exit.text : { EXIT_TEXT } |
85 | .exit.data : { *(.exit.data) } | 85 | .exit.data : { *(.exit.data) } |
86 | 86 | ||
87 | .preinit_array : { | 87 | .preinit_array : { |
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index ef4b8f949b51..b783ac87d98a 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c | |||
@@ -21,21 +21,17 @@ void handle_syscall(struct uml_pt_regs *r) | |||
21 | PT_REGS_SET_SYSCALL_RETURN(regs, -ENOSYS); | 21 | PT_REGS_SET_SYSCALL_RETURN(regs, -ENOSYS); |
22 | 22 | ||
23 | if (syscall_trace_enter(regs)) | 23 | if (syscall_trace_enter(regs)) |
24 | return; | 24 | goto out; |
25 | 25 | ||
26 | /* Do the seccomp check after ptrace; failures should be fast. */ | 26 | /* Do the seccomp check after ptrace; failures should be fast. */ |
27 | if (secure_computing(NULL) == -1) | 27 | if (secure_computing(NULL) == -1) |
28 | return; | 28 | goto out; |
29 | 29 | ||
30 | /* Update the syscall number after orig_ax has potentially been updated | ||
31 | * with ptrace. | ||
32 | */ | ||
33 | UPT_SYSCALL_NR(r) = PT_SYSCALL_NR(r->gp); | ||
34 | syscall = UPT_SYSCALL_NR(r); | 30 | syscall = UPT_SYSCALL_NR(r); |
35 | |||
36 | if (syscall >= 0 && syscall <= __NR_syscall_max) | 31 | if (syscall >= 0 && syscall <= __NR_syscall_max) |
37 | PT_REGS_SET_SYSCALL_RETURN(regs, | 32 | PT_REGS_SET_SYSCALL_RETURN(regs, |
38 | EXECUTE_SYSCALL(syscall, regs)); | 33 | EXECUTE_SYSCALL(syscall, regs)); |
39 | 34 | ||
35 | out: | ||
40 | syscall_trace_leave(regs); | 36 | syscall_trace_leave(regs); |
41 | } | 37 | } |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c580d8c33562..2a1f0ce7c59a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -24,7 +24,6 @@ config X86 | |||
24 | select ARCH_DISCARD_MEMBLOCK | 24 | select ARCH_DISCARD_MEMBLOCK |
25 | select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI | 25 | select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI |
26 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | 26 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE |
27 | select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS | ||
28 | select ARCH_HAS_DEVMEM_IS_ALLOWED | 27 | select ARCH_HAS_DEVMEM_IS_ALLOWED |
29 | select ARCH_HAS_ELF_RANDOMIZE | 28 | select ARCH_HAS_ELF_RANDOMIZE |
30 | select ARCH_HAS_FAST_MULTIPLIER | 29 | select ARCH_HAS_FAST_MULTIPLIER |
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index ff574dad95cc..94dd4a31f5b3 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
@@ -1004,79 +1004,87 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext, | |||
1004 | return status; | 1004 | return status; |
1005 | } | 1005 | } |
1006 | 1006 | ||
1007 | static efi_status_t exit_boot(struct boot_params *boot_params, | 1007 | struct exit_boot_struct { |
1008 | void *handle, bool is64) | 1008 | struct boot_params *boot_params; |
1009 | { | 1009 | struct efi_info *efi; |
1010 | struct efi_info *efi = &boot_params->efi_info; | ||
1011 | unsigned long map_sz, key, desc_size; | ||
1012 | efi_memory_desc_t *mem_map; | ||
1013 | struct setup_data *e820ext; | 1010 | struct setup_data *e820ext; |
1014 | const char *signature; | ||
1015 | __u32 e820ext_size; | 1011 | __u32 e820ext_size; |
1016 | __u32 nr_desc, prev_nr_desc; | 1012 | bool is64; |
1017 | efi_status_t status; | 1013 | }; |
1018 | __u32 desc_version; | ||
1019 | bool called_exit = false; | ||
1020 | u8 nr_entries; | ||
1021 | int i; | ||
1022 | |||
1023 | nr_desc = 0; | ||
1024 | e820ext = NULL; | ||
1025 | e820ext_size = 0; | ||
1026 | |||
1027 | get_map: | ||
1028 | status = efi_get_memory_map(sys_table, &mem_map, &map_sz, &desc_size, | ||
1029 | &desc_version, &key); | ||
1030 | |||
1031 | if (status != EFI_SUCCESS) | ||
1032 | return status; | ||
1033 | |||
1034 | prev_nr_desc = nr_desc; | ||
1035 | nr_desc = map_sz / desc_size; | ||
1036 | if (nr_desc > prev_nr_desc && | ||
1037 | nr_desc > ARRAY_SIZE(boot_params->e820_map)) { | ||
1038 | u32 nr_e820ext = nr_desc - ARRAY_SIZE(boot_params->e820_map); | ||
1039 | |||
1040 | status = alloc_e820ext(nr_e820ext, &e820ext, &e820ext_size); | ||
1041 | if (status != EFI_SUCCESS) | ||
1042 | goto free_mem_map; | ||
1043 | 1014 | ||
1044 | efi_call_early(free_pool, mem_map); | 1015 | static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg, |
1045 | goto get_map; /* Allocated memory, get map again */ | 1016 | struct efi_boot_memmap *map, |
1017 | void *priv) | ||
1018 | { | ||
1019 | static bool first = true; | ||
1020 | const char *signature; | ||
1021 | __u32 nr_desc; | ||
1022 | efi_status_t status; | ||
1023 | struct exit_boot_struct *p = priv; | ||
1024 | |||
1025 | if (first) { | ||
1026 | nr_desc = *map->buff_size / *map->desc_size; | ||
1027 | if (nr_desc > ARRAY_SIZE(p->boot_params->e820_map)) { | ||
1028 | u32 nr_e820ext = nr_desc - | ||
1029 | ARRAY_SIZE(p->boot_params->e820_map); | ||
1030 | |||
1031 | status = alloc_e820ext(nr_e820ext, &p->e820ext, | ||
1032 | &p->e820ext_size); | ||
1033 | if (status != EFI_SUCCESS) | ||
1034 | return status; | ||
1035 | } | ||
1036 | first = false; | ||
1046 | } | 1037 | } |
1047 | 1038 | ||
1048 | signature = is64 ? EFI64_LOADER_SIGNATURE : EFI32_LOADER_SIGNATURE; | 1039 | signature = p->is64 ? EFI64_LOADER_SIGNATURE : EFI32_LOADER_SIGNATURE; |
1049 | memcpy(&efi->efi_loader_signature, signature, sizeof(__u32)); | 1040 | memcpy(&p->efi->efi_loader_signature, signature, sizeof(__u32)); |
1050 | 1041 | ||
1051 | efi->efi_systab = (unsigned long)sys_table; | 1042 | p->efi->efi_systab = (unsigned long)sys_table_arg; |
1052 | efi->efi_memdesc_size = desc_size; | 1043 | p->efi->efi_memdesc_size = *map->desc_size; |
1053 | efi->efi_memdesc_version = desc_version; | 1044 | p->efi->efi_memdesc_version = *map->desc_ver; |
1054 | efi->efi_memmap = (unsigned long)mem_map; | 1045 | p->efi->efi_memmap = (unsigned long)*map->map; |
1055 | efi->efi_memmap_size = map_sz; | 1046 | p->efi->efi_memmap_size = *map->map_size; |
1056 | 1047 | ||
1057 | #ifdef CONFIG_X86_64 | 1048 | #ifdef CONFIG_X86_64 |
1058 | efi->efi_systab_hi = (unsigned long)sys_table >> 32; | 1049 | p->efi->efi_systab_hi = (unsigned long)sys_table_arg >> 32; |
1059 | efi->efi_memmap_hi = (unsigned long)mem_map >> 32; | 1050 | p->efi->efi_memmap_hi = (unsigned long)*map->map >> 32; |
1060 | #endif | 1051 | #endif |
1061 | 1052 | ||
1053 | return EFI_SUCCESS; | ||
1054 | } | ||
1055 | |||
1056 | static efi_status_t exit_boot(struct boot_params *boot_params, | ||
1057 | void *handle, bool is64) | ||
1058 | { | ||
1059 | unsigned long map_sz, key, desc_size, buff_size; | ||
1060 | efi_memory_desc_t *mem_map; | ||
1061 | struct setup_data *e820ext; | ||
1062 | __u32 e820ext_size; | ||
1063 | efi_status_t status; | ||
1064 | __u32 desc_version; | ||
1065 | struct efi_boot_memmap map; | ||
1066 | struct exit_boot_struct priv; | ||
1067 | |||
1068 | map.map = &mem_map; | ||
1069 | map.map_size = &map_sz; | ||
1070 | map.desc_size = &desc_size; | ||
1071 | map.desc_ver = &desc_version; | ||
1072 | map.key_ptr = &key; | ||
1073 | map.buff_size = &buff_size; | ||
1074 | priv.boot_params = boot_params; | ||
1075 | priv.efi = &boot_params->efi_info; | ||
1076 | priv.e820ext = NULL; | ||
1077 | priv.e820ext_size = 0; | ||
1078 | priv.is64 = is64; | ||
1079 | |||
1062 | /* Might as well exit boot services now */ | 1080 | /* Might as well exit boot services now */ |
1063 | status = efi_call_early(exit_boot_services, handle, key); | 1081 | status = efi_exit_boot_services(sys_table, handle, &map, &priv, |
1064 | if (status != EFI_SUCCESS) { | 1082 | exit_boot_func); |
1065 | /* | 1083 | if (status != EFI_SUCCESS) |
1066 | * ExitBootServices() will fail if any of the event | 1084 | return status; |
1067 | * handlers change the memory map. In which case, we | ||
1068 | * must be prepared to retry, but only once so that | ||
1069 | * we're guaranteed to exit on repeated failures instead | ||
1070 | * of spinning forever. | ||
1071 | */ | ||
1072 | if (called_exit) | ||
1073 | goto free_mem_map; | ||
1074 | |||
1075 | called_exit = true; | ||
1076 | efi_call_early(free_pool, mem_map); | ||
1077 | goto get_map; | ||
1078 | } | ||
1079 | 1085 | ||
1086 | e820ext = priv.e820ext; | ||
1087 | e820ext_size = priv.e820ext_size; | ||
1080 | /* Historic? */ | 1088 | /* Historic? */ |
1081 | boot_params->alt_mem_k = 32 * 1024; | 1089 | boot_params->alt_mem_k = 32 * 1024; |
1082 | 1090 | ||
@@ -1085,10 +1093,6 @@ get_map: | |||
1085 | return status; | 1093 | return status; |
1086 | 1094 | ||
1087 | return EFI_SUCCESS; | 1095 | return EFI_SUCCESS; |
1088 | |||
1089 | free_mem_map: | ||
1090 | efi_call_early(free_pool, mem_map); | ||
1091 | return status; | ||
1092 | } | 1096 | } |
1093 | 1097 | ||
1094 | /* | 1098 | /* |
diff --git a/arch/x86/configs/tiny.config b/arch/x86/configs/tiny.config index 4e2ecfa23c15..4b429df40d7a 100644 --- a/arch/x86/configs/tiny.config +++ b/arch/x86/configs/tiny.config | |||
@@ -1 +1,3 @@ | |||
1 | CONFIG_NOHIGHMEM=y | 1 | CONFIG_NOHIGHMEM=y |
2 | # CONFIG_HIGHMEM4G is not set | ||
3 | # CONFIG_HIGHMEM64G is not set | ||
diff --git a/arch/x86/crypto/sha256-mb/sha256_mb.c b/arch/x86/crypto/sha256-mb/sha256_mb.c index 89fa85e8b10c..6f97fb33ae21 100644 --- a/arch/x86/crypto/sha256-mb/sha256_mb.c +++ b/arch/x86/crypto/sha256-mb/sha256_mb.c | |||
@@ -485,10 +485,10 @@ static int sha_complete_job(struct mcryptd_hash_request_ctx *rctx, | |||
485 | 485 | ||
486 | req = cast_mcryptd_ctx_to_req(req_ctx); | 486 | req = cast_mcryptd_ctx_to_req(req_ctx); |
487 | if (irqs_disabled()) | 487 | if (irqs_disabled()) |
488 | rctx->complete(&req->base, ret); | 488 | req_ctx->complete(&req->base, ret); |
489 | else { | 489 | else { |
490 | local_bh_disable(); | 490 | local_bh_disable(); |
491 | rctx->complete(&req->base, ret); | 491 | req_ctx->complete(&req->base, ret); |
492 | local_bh_enable(); | 492 | local_bh_enable(); |
493 | } | 493 | } |
494 | } | 494 | } |
diff --git a/arch/x86/crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S b/arch/x86/crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S index b691da981cd9..a78a0694ddef 100644 --- a/arch/x86/crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S +++ b/arch/x86/crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S | |||
@@ -265,13 +265,14 @@ ENTRY(sha256_mb_mgr_get_comp_job_avx2) | |||
265 | vpinsrd $1, _args_digest+1*32(state, idx, 4), %xmm0, %xmm0 | 265 | vpinsrd $1, _args_digest+1*32(state, idx, 4), %xmm0, %xmm0 |
266 | vpinsrd $2, _args_digest+2*32(state, idx, 4), %xmm0, %xmm0 | 266 | vpinsrd $2, _args_digest+2*32(state, idx, 4), %xmm0, %xmm0 |
267 | vpinsrd $3, _args_digest+3*32(state, idx, 4), %xmm0, %xmm0 | 267 | vpinsrd $3, _args_digest+3*32(state, idx, 4), %xmm0, %xmm0 |
268 | movl _args_digest+4*32(state, idx, 4), tmp2_w | 268 | vmovd _args_digest(state , idx, 4) , %xmm0 |
269 | vpinsrd $1, _args_digest+5*32(state, idx, 4), %xmm1, %xmm1 | 269 | vpinsrd $1, _args_digest+5*32(state, idx, 4), %xmm1, %xmm1 |
270 | vpinsrd $2, _args_digest+6*32(state, idx, 4), %xmm1, %xmm1 | 270 | vpinsrd $2, _args_digest+6*32(state, idx, 4), %xmm1, %xmm1 |
271 | vpinsrd $3, _args_digest+7*32(state, idx, 4), %xmm1, %xmm1 | 271 | vpinsrd $3, _args_digest+7*32(state, idx, 4), %xmm1, %xmm1 |
272 | 272 | ||
273 | vmovdqu %xmm0, _result_digest(job_rax) | 273 | vmovdqu %xmm0, _result_digest(job_rax) |
274 | movl tmp2_w, _result_digest+1*16(job_rax) | 274 | offset = (_result_digest + 1*16) |
275 | vmovdqu %xmm1, offset(job_rax) | ||
275 | 276 | ||
276 | pop %rbx | 277 | pop %rbx |
277 | 278 | ||
diff --git a/arch/x86/crypto/sha512-mb/sha512_mb.c b/arch/x86/crypto/sha512-mb/sha512_mb.c index f4cf5b78fd36..d210174a52b0 100644 --- a/arch/x86/crypto/sha512-mb/sha512_mb.c +++ b/arch/x86/crypto/sha512-mb/sha512_mb.c | |||
@@ -497,10 +497,10 @@ static int sha_complete_job(struct mcryptd_hash_request_ctx *rctx, | |||
497 | 497 | ||
498 | req = cast_mcryptd_ctx_to_req(req_ctx); | 498 | req = cast_mcryptd_ctx_to_req(req_ctx); |
499 | if (irqs_disabled()) | 499 | if (irqs_disabled()) |
500 | rctx->complete(&req->base, ret); | 500 | req_ctx->complete(&req->base, ret); |
501 | else { | 501 | else { |
502 | local_bh_disable(); | 502 | local_bh_disable(); |
503 | rctx->complete(&req->base, ret); | 503 | req_ctx->complete(&req->base, ret); |
504 | local_bh_enable(); | 504 | local_bh_enable(); |
505 | } | 505 | } |
506 | } | 506 | } |
diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index e07a22bb9308..f5f4b3fbbbc2 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c | |||
@@ -119,8 +119,8 @@ static const u64 amd_perfmon_event_map[PERF_COUNT_HW_MAX] = | |||
119 | { | 119 | { |
120 | [PERF_COUNT_HW_CPU_CYCLES] = 0x0076, | 120 | [PERF_COUNT_HW_CPU_CYCLES] = 0x0076, |
121 | [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, | 121 | [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, |
122 | [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0080, | 122 | [PERF_COUNT_HW_CACHE_REFERENCES] = 0x077d, |
123 | [PERF_COUNT_HW_CACHE_MISSES] = 0x0081, | 123 | [PERF_COUNT_HW_CACHE_MISSES] = 0x077e, |
124 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2, | 124 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2, |
125 | [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3, | 125 | [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3, |
126 | [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00d0, /* "Decoder empty" event */ | 126 | [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00d0, /* "Decoder empty" event */ |
diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c index e6131d4454e6..65577f081d07 100644 --- a/arch/x86/events/amd/uncore.c +++ b/arch/x86/events/amd/uncore.c | |||
@@ -29,6 +29,8 @@ | |||
29 | 29 | ||
30 | #define COUNTER_SHIFT 16 | 30 | #define COUNTER_SHIFT 16 |
31 | 31 | ||
32 | static HLIST_HEAD(uncore_unused_list); | ||
33 | |||
32 | struct amd_uncore { | 34 | struct amd_uncore { |
33 | int id; | 35 | int id; |
34 | int refcnt; | 36 | int refcnt; |
@@ -39,7 +41,7 @@ struct amd_uncore { | |||
39 | cpumask_t *active_mask; | 41 | cpumask_t *active_mask; |
40 | struct pmu *pmu; | 42 | struct pmu *pmu; |
41 | struct perf_event *events[MAX_COUNTERS]; | 43 | struct perf_event *events[MAX_COUNTERS]; |
42 | struct amd_uncore *free_when_cpu_online; | 44 | struct hlist_node node; |
43 | }; | 45 | }; |
44 | 46 | ||
45 | static struct amd_uncore * __percpu *amd_uncore_nb; | 47 | static struct amd_uncore * __percpu *amd_uncore_nb; |
@@ -306,6 +308,7 @@ static int amd_uncore_cpu_up_prepare(unsigned int cpu) | |||
306 | uncore_nb->msr_base = MSR_F15H_NB_PERF_CTL; | 308 | uncore_nb->msr_base = MSR_F15H_NB_PERF_CTL; |
307 | uncore_nb->active_mask = &amd_nb_active_mask; | 309 | uncore_nb->active_mask = &amd_nb_active_mask; |
308 | uncore_nb->pmu = &amd_nb_pmu; | 310 | uncore_nb->pmu = &amd_nb_pmu; |
311 | uncore_nb->id = -1; | ||
309 | *per_cpu_ptr(amd_uncore_nb, cpu) = uncore_nb; | 312 | *per_cpu_ptr(amd_uncore_nb, cpu) = uncore_nb; |
310 | } | 313 | } |
311 | 314 | ||
@@ -319,6 +322,7 @@ static int amd_uncore_cpu_up_prepare(unsigned int cpu) | |||
319 | uncore_l2->msr_base = MSR_F16H_L2I_PERF_CTL; | 322 | uncore_l2->msr_base = MSR_F16H_L2I_PERF_CTL; |
320 | uncore_l2->active_mask = &amd_l2_active_mask; | 323 | uncore_l2->active_mask = &amd_l2_active_mask; |
321 | uncore_l2->pmu = &amd_l2_pmu; | 324 | uncore_l2->pmu = &amd_l2_pmu; |
325 | uncore_l2->id = -1; | ||
322 | *per_cpu_ptr(amd_uncore_l2, cpu) = uncore_l2; | 326 | *per_cpu_ptr(amd_uncore_l2, cpu) = uncore_l2; |
323 | } | 327 | } |
324 | 328 | ||
@@ -348,7 +352,7 @@ amd_uncore_find_online_sibling(struct amd_uncore *this, | |||
348 | continue; | 352 | continue; |
349 | 353 | ||
350 | if (this->id == that->id) { | 354 | if (this->id == that->id) { |
351 | that->free_when_cpu_online = this; | 355 | hlist_add_head(&this->node, &uncore_unused_list); |
352 | this = that; | 356 | this = that; |
353 | break; | 357 | break; |
354 | } | 358 | } |
@@ -388,13 +392,23 @@ static int amd_uncore_cpu_starting(unsigned int cpu) | |||
388 | return 0; | 392 | return 0; |
389 | } | 393 | } |
390 | 394 | ||
395 | static void uncore_clean_online(void) | ||
396 | { | ||
397 | struct amd_uncore *uncore; | ||
398 | struct hlist_node *n; | ||
399 | |||
400 | hlist_for_each_entry_safe(uncore, n, &uncore_unused_list, node) { | ||
401 | hlist_del(&uncore->node); | ||
402 | kfree(uncore); | ||
403 | } | ||
404 | } | ||
405 | |||
391 | static void uncore_online(unsigned int cpu, | 406 | static void uncore_online(unsigned int cpu, |
392 | struct amd_uncore * __percpu *uncores) | 407 | struct amd_uncore * __percpu *uncores) |
393 | { | 408 | { |
394 | struct amd_uncore *uncore = *per_cpu_ptr(uncores, cpu); | 409 | struct amd_uncore *uncore = *per_cpu_ptr(uncores, cpu); |
395 | 410 | ||
396 | kfree(uncore->free_when_cpu_online); | 411 | uncore_clean_online(); |
397 | uncore->free_when_cpu_online = NULL; | ||
398 | 412 | ||
399 | if (cpu == uncore->cpu) | 413 | if (cpu == uncore->cpu) |
400 | cpumask_set_cpu(cpu, uncore->active_mask); | 414 | cpumask_set_cpu(cpu, uncore->active_mask); |
diff --git a/arch/x86/events/intel/bts.c b/arch/x86/events/intel/bts.c index 0a6e393a2e62..982c9e31daca 100644 --- a/arch/x86/events/intel/bts.c +++ b/arch/x86/events/intel/bts.c | |||
@@ -31,7 +31,17 @@ | |||
31 | struct bts_ctx { | 31 | struct bts_ctx { |
32 | struct perf_output_handle handle; | 32 | struct perf_output_handle handle; |
33 | struct debug_store ds_back; | 33 | struct debug_store ds_back; |
34 | int started; | 34 | int state; |
35 | }; | ||
36 | |||
37 | /* BTS context states: */ | ||
38 | enum { | ||
39 | /* no ongoing AUX transactions */ | ||
40 | BTS_STATE_STOPPED = 0, | ||
41 | /* AUX transaction is on, BTS tracing is disabled */ | ||
42 | BTS_STATE_INACTIVE, | ||
43 | /* AUX transaction is on, BTS tracing is running */ | ||
44 | BTS_STATE_ACTIVE, | ||
35 | }; | 45 | }; |
36 | 46 | ||
37 | static DEFINE_PER_CPU(struct bts_ctx, bts_ctx); | 47 | static DEFINE_PER_CPU(struct bts_ctx, bts_ctx); |
@@ -204,6 +214,15 @@ static void bts_update(struct bts_ctx *bts) | |||
204 | static int | 214 | static int |
205 | bts_buffer_reset(struct bts_buffer *buf, struct perf_output_handle *handle); | 215 | bts_buffer_reset(struct bts_buffer *buf, struct perf_output_handle *handle); |
206 | 216 | ||
217 | /* | ||
218 | * Ordering PMU callbacks wrt themselves and the PMI is done by means | ||
219 | * of bts::state, which: | ||
220 | * - is set when bts::handle::event is valid, that is, between | ||
221 | * perf_aux_output_begin() and perf_aux_output_end(); | ||
222 | * - is zero otherwise; | ||
223 | * - is ordered against bts::handle::event with a compiler barrier. | ||
224 | */ | ||
225 | |||
207 | static void __bts_event_start(struct perf_event *event) | 226 | static void __bts_event_start(struct perf_event *event) |
208 | { | 227 | { |
209 | struct bts_ctx *bts = this_cpu_ptr(&bts_ctx); | 228 | struct bts_ctx *bts = this_cpu_ptr(&bts_ctx); |
@@ -221,10 +240,13 @@ static void __bts_event_start(struct perf_event *event) | |||
221 | 240 | ||
222 | /* | 241 | /* |
223 | * local barrier to make sure that ds configuration made it | 242 | * local barrier to make sure that ds configuration made it |
224 | * before we enable BTS | 243 | * before we enable BTS and bts::state goes ACTIVE |
225 | */ | 244 | */ |
226 | wmb(); | 245 | wmb(); |
227 | 246 | ||
247 | /* INACTIVE/STOPPED -> ACTIVE */ | ||
248 | WRITE_ONCE(bts->state, BTS_STATE_ACTIVE); | ||
249 | |||
228 | intel_pmu_enable_bts(config); | 250 | intel_pmu_enable_bts(config); |
229 | 251 | ||
230 | } | 252 | } |
@@ -251,9 +273,6 @@ static void bts_event_start(struct perf_event *event, int flags) | |||
251 | 273 | ||
252 | __bts_event_start(event); | 274 | __bts_event_start(event); |
253 | 275 | ||
254 | /* PMI handler: this counter is running and likely generating PMIs */ | ||
255 | ACCESS_ONCE(bts->started) = 1; | ||
256 | |||
257 | return; | 276 | return; |
258 | 277 | ||
259 | fail_end_stop: | 278 | fail_end_stop: |
@@ -263,30 +282,34 @@ fail_stop: | |||
263 | event->hw.state = PERF_HES_STOPPED; | 282 | event->hw.state = PERF_HES_STOPPED; |
264 | } | 283 | } |
265 | 284 | ||
266 | static void __bts_event_stop(struct perf_event *event) | 285 | static void __bts_event_stop(struct perf_event *event, int state) |
267 | { | 286 | { |
287 | struct bts_ctx *bts = this_cpu_ptr(&bts_ctx); | ||
288 | |||
289 | /* ACTIVE -> INACTIVE(PMI)/STOPPED(->stop()) */ | ||
290 | WRITE_ONCE(bts->state, state); | ||
291 | |||
268 | /* | 292 | /* |
269 | * No extra synchronization is mandated by the documentation to have | 293 | * No extra synchronization is mandated by the documentation to have |
270 | * BTS data stores globally visible. | 294 | * BTS data stores globally visible. |
271 | */ | 295 | */ |
272 | intel_pmu_disable_bts(); | 296 | intel_pmu_disable_bts(); |
273 | |||
274 | if (event->hw.state & PERF_HES_STOPPED) | ||
275 | return; | ||
276 | |||
277 | ACCESS_ONCE(event->hw.state) |= PERF_HES_STOPPED; | ||
278 | } | 297 | } |
279 | 298 | ||
280 | static void bts_event_stop(struct perf_event *event, int flags) | 299 | static void bts_event_stop(struct perf_event *event, int flags) |
281 | { | 300 | { |
282 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); | 301 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
283 | struct bts_ctx *bts = this_cpu_ptr(&bts_ctx); | 302 | struct bts_ctx *bts = this_cpu_ptr(&bts_ctx); |
284 | struct bts_buffer *buf = perf_get_aux(&bts->handle); | 303 | struct bts_buffer *buf = NULL; |
304 | int state = READ_ONCE(bts->state); | ||
285 | 305 | ||
286 | /* PMI handler: don't restart this counter */ | 306 | if (state == BTS_STATE_ACTIVE) |
287 | ACCESS_ONCE(bts->started) = 0; | 307 | __bts_event_stop(event, BTS_STATE_STOPPED); |
288 | 308 | ||
289 | __bts_event_stop(event); | 309 | if (state != BTS_STATE_STOPPED) |
310 | buf = perf_get_aux(&bts->handle); | ||
311 | |||
312 | event->hw.state |= PERF_HES_STOPPED; | ||
290 | 313 | ||
291 | if (flags & PERF_EF_UPDATE) { | 314 | if (flags & PERF_EF_UPDATE) { |
292 | bts_update(bts); | 315 | bts_update(bts); |
@@ -296,6 +319,7 @@ static void bts_event_stop(struct perf_event *event, int flags) | |||
296 | bts->handle.head = | 319 | bts->handle.head = |
297 | local_xchg(&buf->data_size, | 320 | local_xchg(&buf->data_size, |
298 | buf->nr_pages << PAGE_SHIFT); | 321 | buf->nr_pages << PAGE_SHIFT); |
322 | |||
299 | perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0), | 323 | perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0), |
300 | !!local_xchg(&buf->lost, 0)); | 324 | !!local_xchg(&buf->lost, 0)); |
301 | } | 325 | } |
@@ -310,8 +334,20 @@ static void bts_event_stop(struct perf_event *event, int flags) | |||
310 | void intel_bts_enable_local(void) | 334 | void intel_bts_enable_local(void) |
311 | { | 335 | { |
312 | struct bts_ctx *bts = this_cpu_ptr(&bts_ctx); | 336 | struct bts_ctx *bts = this_cpu_ptr(&bts_ctx); |
337 | int state = READ_ONCE(bts->state); | ||
338 | |||
339 | /* | ||
340 | * Here we transition from INACTIVE to ACTIVE; | ||
341 | * if we instead are STOPPED from the interrupt handler, | ||
342 | * stay that way. Can't be ACTIVE here though. | ||
343 | */ | ||
344 | if (WARN_ON_ONCE(state == BTS_STATE_ACTIVE)) | ||
345 | return; | ||
346 | |||
347 | if (state == BTS_STATE_STOPPED) | ||
348 | return; | ||
313 | 349 | ||
314 | if (bts->handle.event && bts->started) | 350 | if (bts->handle.event) |
315 | __bts_event_start(bts->handle.event); | 351 | __bts_event_start(bts->handle.event); |
316 | } | 352 | } |
317 | 353 | ||
@@ -319,8 +355,15 @@ void intel_bts_disable_local(void) | |||
319 | { | 355 | { |
320 | struct bts_ctx *bts = this_cpu_ptr(&bts_ctx); | 356 | struct bts_ctx *bts = this_cpu_ptr(&bts_ctx); |
321 | 357 | ||
358 | /* | ||
359 | * Here we transition from ACTIVE to INACTIVE; | ||
360 | * do nothing for STOPPED or INACTIVE. | ||
361 | */ | ||
362 | if (READ_ONCE(bts->state) != BTS_STATE_ACTIVE) | ||
363 | return; | ||
364 | |||
322 | if (bts->handle.event) | 365 | if (bts->handle.event) |
323 | __bts_event_stop(bts->handle.event); | 366 | __bts_event_stop(bts->handle.event, BTS_STATE_INACTIVE); |
324 | } | 367 | } |
325 | 368 | ||
326 | static int | 369 | static int |
@@ -335,8 +378,6 @@ bts_buffer_reset(struct bts_buffer *buf, struct perf_output_handle *handle) | |||
335 | return 0; | 378 | return 0; |
336 | 379 | ||
337 | head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1); | 380 | head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1); |
338 | if (WARN_ON_ONCE(head != local_read(&buf->head))) | ||
339 | return -EINVAL; | ||
340 | 381 | ||
341 | phys = &buf->buf[buf->cur_buf]; | 382 | phys = &buf->buf[buf->cur_buf]; |
342 | space = phys->offset + phys->displacement + phys->size - head; | 383 | space = phys->offset + phys->displacement + phys->size - head; |
@@ -403,22 +444,37 @@ bts_buffer_reset(struct bts_buffer *buf, struct perf_output_handle *handle) | |||
403 | 444 | ||
404 | int intel_bts_interrupt(void) | 445 | int intel_bts_interrupt(void) |
405 | { | 446 | { |
447 | struct debug_store *ds = this_cpu_ptr(&cpu_hw_events)->ds; | ||
406 | struct bts_ctx *bts = this_cpu_ptr(&bts_ctx); | 448 | struct bts_ctx *bts = this_cpu_ptr(&bts_ctx); |
407 | struct perf_event *event = bts->handle.event; | 449 | struct perf_event *event = bts->handle.event; |
408 | struct bts_buffer *buf; | 450 | struct bts_buffer *buf; |
409 | s64 old_head; | 451 | s64 old_head; |
410 | int err; | 452 | int err = -ENOSPC, handled = 0; |
411 | 453 | ||
412 | if (!event || !bts->started) | 454 | /* |
413 | return 0; | 455 | * The only surefire way of knowing if this NMI is ours is by checking |
456 | * the write ptr against the PMI threshold. | ||
457 | */ | ||
458 | if (ds && (ds->bts_index >= ds->bts_interrupt_threshold)) | ||
459 | handled = 1; | ||
460 | |||
461 | /* | ||
462 | * this is wrapped in intel_bts_enable_local/intel_bts_disable_local, | ||
463 | * so we can only be INACTIVE or STOPPED | ||
464 | */ | ||
465 | if (READ_ONCE(bts->state) == BTS_STATE_STOPPED) | ||
466 | return handled; | ||
414 | 467 | ||
415 | buf = perf_get_aux(&bts->handle); | 468 | buf = perf_get_aux(&bts->handle); |
469 | if (!buf) | ||
470 | return handled; | ||
471 | |||
416 | /* | 472 | /* |
417 | * Skip snapshot counters: they don't use the interrupt, but | 473 | * Skip snapshot counters: they don't use the interrupt, but |
418 | * there's no other way of telling, because the pointer will | 474 | * there's no other way of telling, because the pointer will |
419 | * keep moving | 475 | * keep moving |
420 | */ | 476 | */ |
421 | if (!buf || buf->snapshot) | 477 | if (buf->snapshot) |
422 | return 0; | 478 | return 0; |
423 | 479 | ||
424 | old_head = local_read(&buf->head); | 480 | old_head = local_read(&buf->head); |
@@ -426,18 +482,27 @@ int intel_bts_interrupt(void) | |||
426 | 482 | ||
427 | /* no new data */ | 483 | /* no new data */ |
428 | if (old_head == local_read(&buf->head)) | 484 | if (old_head == local_read(&buf->head)) |
429 | return 0; | 485 | return handled; |
430 | 486 | ||
431 | perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0), | 487 | perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0), |
432 | !!local_xchg(&buf->lost, 0)); | 488 | !!local_xchg(&buf->lost, 0)); |
433 | 489 | ||
434 | buf = perf_aux_output_begin(&bts->handle, event); | 490 | buf = perf_aux_output_begin(&bts->handle, event); |
435 | if (!buf) | 491 | if (buf) |
436 | return 1; | 492 | err = bts_buffer_reset(buf, &bts->handle); |
493 | |||
494 | if (err) { | ||
495 | WRITE_ONCE(bts->state, BTS_STATE_STOPPED); | ||
437 | 496 | ||
438 | err = bts_buffer_reset(buf, &bts->handle); | 497 | if (buf) { |
439 | if (err) | 498 | /* |
440 | perf_aux_output_end(&bts->handle, 0, false); | 499 | * BTS_STATE_STOPPED should be visible before |
500 | * cleared handle::event | ||
501 | */ | ||
502 | barrier(); | ||
503 | perf_aux_output_end(&bts->handle, 0, false); | ||
504 | } | ||
505 | } | ||
441 | 506 | ||
442 | return 1; | 507 | return 1; |
443 | } | 508 | } |
@@ -519,7 +584,8 @@ static __init int bts_init(void) | |||
519 | if (!boot_cpu_has(X86_FEATURE_DTES64) || !x86_pmu.bts) | 584 | if (!boot_cpu_has(X86_FEATURE_DTES64) || !x86_pmu.bts) |
520 | return -ENODEV; | 585 | return -ENODEV; |
521 | 586 | ||
522 | bts_pmu.capabilities = PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_ITRACE; | 587 | bts_pmu.capabilities = PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_ITRACE | |
588 | PERF_PMU_CAP_EXCLUSIVE; | ||
523 | bts_pmu.task_ctx_nr = perf_sw_context; | 589 | bts_pmu.task_ctx_nr = perf_sw_context; |
524 | bts_pmu.event_init = bts_event_init; | 590 | bts_pmu.event_init = bts_event_init; |
525 | bts_pmu.add = bts_event_add; | 591 | bts_pmu.add = bts_event_add; |
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 2cbde2f449aa..4c9a79b9cd69 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c | |||
@@ -1730,9 +1730,11 @@ static __initconst const u64 knl_hw_cache_extra_regs | |||
1730 | * disabled state if called consecutively. | 1730 | * disabled state if called consecutively. |
1731 | * | 1731 | * |
1732 | * During consecutive calls, the same disable value will be written to related | 1732 | * During consecutive calls, the same disable value will be written to related |
1733 | * registers, so the PMU state remains unchanged. hw.state in | 1733 | * registers, so the PMU state remains unchanged. |
1734 | * intel_bts_disable_local will remain PERF_HES_STOPPED too in consecutive | 1734 | * |
1735 | * calls. | 1735 | * intel_bts events don't coexist with intel PMU's BTS events because of |
1736 | * x86_add_exclusive(x86_lbr_exclusive_lbr); there's no need to keep them | ||
1737 | * disabled around intel PMU's event batching etc, only inside the PMI handler. | ||
1736 | */ | 1738 | */ |
1737 | static void __intel_pmu_disable_all(void) | 1739 | static void __intel_pmu_disable_all(void) |
1738 | { | 1740 | { |
@@ -1742,8 +1744,6 @@ static void __intel_pmu_disable_all(void) | |||
1742 | 1744 | ||
1743 | if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) | 1745 | if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) |
1744 | intel_pmu_disable_bts(); | 1746 | intel_pmu_disable_bts(); |
1745 | else | ||
1746 | intel_bts_disable_local(); | ||
1747 | 1747 | ||
1748 | intel_pmu_pebs_disable_all(); | 1748 | intel_pmu_pebs_disable_all(); |
1749 | } | 1749 | } |
@@ -1771,8 +1771,7 @@ static void __intel_pmu_enable_all(int added, bool pmi) | |||
1771 | return; | 1771 | return; |
1772 | 1772 | ||
1773 | intel_pmu_enable_bts(event->hw.config); | 1773 | intel_pmu_enable_bts(event->hw.config); |
1774 | } else | 1774 | } |
1775 | intel_bts_enable_local(); | ||
1776 | } | 1775 | } |
1777 | 1776 | ||
1778 | static void intel_pmu_enable_all(int added) | 1777 | static void intel_pmu_enable_all(int added) |
@@ -2073,6 +2072,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) | |||
2073 | */ | 2072 | */ |
2074 | if (!x86_pmu.late_ack) | 2073 | if (!x86_pmu.late_ack) |
2075 | apic_write(APIC_LVTPC, APIC_DM_NMI); | 2074 | apic_write(APIC_LVTPC, APIC_DM_NMI); |
2075 | intel_bts_disable_local(); | ||
2076 | __intel_pmu_disable_all(); | 2076 | __intel_pmu_disable_all(); |
2077 | handled = intel_pmu_drain_bts_buffer(); | 2077 | handled = intel_pmu_drain_bts_buffer(); |
2078 | handled += intel_bts_interrupt(); | 2078 | handled += intel_bts_interrupt(); |
@@ -2172,6 +2172,7 @@ done: | |||
2172 | /* Only restore PMU state when it's active. See x86_pmu_disable(). */ | 2172 | /* Only restore PMU state when it's active. See x86_pmu_disable(). */ |
2173 | if (cpuc->enabled) | 2173 | if (cpuc->enabled) |
2174 | __intel_pmu_enable_all(0, true); | 2174 | __intel_pmu_enable_all(0, true); |
2175 | intel_bts_enable_local(); | ||
2175 | 2176 | ||
2176 | /* | 2177 | /* |
2177 | * Only unmask the NMI after the overflow counters | 2178 | * Only unmask the NMI after the overflow counters |
diff --git a/arch/x86/events/intel/cqm.c b/arch/x86/events/intel/cqm.c index 783c49ddef29..8f82b02934fa 100644 --- a/arch/x86/events/intel/cqm.c +++ b/arch/x86/events/intel/cqm.c | |||
@@ -458,6 +458,11 @@ static void __intel_cqm_event_count(void *info); | |||
458 | static void init_mbm_sample(u32 rmid, u32 evt_type); | 458 | static void init_mbm_sample(u32 rmid, u32 evt_type); |
459 | static void __intel_mbm_event_count(void *info); | 459 | static void __intel_mbm_event_count(void *info); |
460 | 460 | ||
461 | static bool is_cqm_event(int e) | ||
462 | { | ||
463 | return (e == QOS_L3_OCCUP_EVENT_ID); | ||
464 | } | ||
465 | |||
461 | static bool is_mbm_event(int e) | 466 | static bool is_mbm_event(int e) |
462 | { | 467 | { |
463 | return (e >= QOS_MBM_TOTAL_EVENT_ID && e <= QOS_MBM_LOCAL_EVENT_ID); | 468 | return (e >= QOS_MBM_TOTAL_EVENT_ID && e <= QOS_MBM_LOCAL_EVENT_ID); |
@@ -1366,6 +1371,10 @@ static int intel_cqm_event_init(struct perf_event *event) | |||
1366 | (event->attr.config > QOS_MBM_LOCAL_EVENT_ID)) | 1371 | (event->attr.config > QOS_MBM_LOCAL_EVENT_ID)) |
1367 | return -EINVAL; | 1372 | return -EINVAL; |
1368 | 1373 | ||
1374 | if ((is_cqm_event(event->attr.config) && !cqm_enabled) || | ||
1375 | (is_mbm_event(event->attr.config) && !mbm_enabled)) | ||
1376 | return -EINVAL; | ||
1377 | |||
1369 | /* unsupported modes and filters */ | 1378 | /* unsupported modes and filters */ |
1370 | if (event->attr.exclude_user || | 1379 | if (event->attr.exclude_user || |
1371 | event->attr.exclude_kernel || | 1380 | event->attr.exclude_kernel || |
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c index 7ce9f3f669e6..9b983a474253 100644 --- a/arch/x86/events/intel/ds.c +++ b/arch/x86/events/intel/ds.c | |||
@@ -1274,18 +1274,18 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) | |||
1274 | struct pebs_record_nhm *p = at; | 1274 | struct pebs_record_nhm *p = at; |
1275 | u64 pebs_status; | 1275 | u64 pebs_status; |
1276 | 1276 | ||
1277 | /* PEBS v3 has accurate status bits */ | 1277 | pebs_status = p->status & cpuc->pebs_enabled; |
1278 | pebs_status &= (1ULL << x86_pmu.max_pebs_events) - 1; | ||
1279 | |||
1280 | /* PEBS v3 has more accurate status bits */ | ||
1278 | if (x86_pmu.intel_cap.pebs_format >= 3) { | 1281 | if (x86_pmu.intel_cap.pebs_format >= 3) { |
1279 | for_each_set_bit(bit, (unsigned long *)&p->status, | 1282 | for_each_set_bit(bit, (unsigned long *)&pebs_status, |
1280 | MAX_PEBS_EVENTS) | 1283 | x86_pmu.max_pebs_events) |
1281 | counts[bit]++; | 1284 | counts[bit]++; |
1282 | 1285 | ||
1283 | continue; | 1286 | continue; |
1284 | } | 1287 | } |
1285 | 1288 | ||
1286 | pebs_status = p->status & cpuc->pebs_enabled; | ||
1287 | pebs_status &= (1ULL << x86_pmu.max_pebs_events) - 1; | ||
1288 | |||
1289 | /* | 1289 | /* |
1290 | * On some CPUs the PEBS status can be zero when PEBS is | 1290 | * On some CPUs the PEBS status can be zero when PEBS is |
1291 | * racing with clearing of GLOBAL_STATUS. | 1291 | * racing with clearing of GLOBAL_STATUS. |
@@ -1333,8 +1333,11 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) | |||
1333 | continue; | 1333 | continue; |
1334 | 1334 | ||
1335 | event = cpuc->events[bit]; | 1335 | event = cpuc->events[bit]; |
1336 | WARN_ON_ONCE(!event); | 1336 | if (WARN_ON_ONCE(!event)) |
1337 | WARN_ON_ONCE(!event->attr.precise_ip); | 1337 | continue; |
1338 | |||
1339 | if (WARN_ON_ONCE(!event->attr.precise_ip)) | ||
1340 | continue; | ||
1338 | 1341 | ||
1339 | /* log dropped samples number */ | 1342 | /* log dropped samples number */ |
1340 | if (error[bit]) | 1343 | if (error[bit]) |
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 04bb5fb5a8d7..861a7d9cb60f 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c | |||
@@ -1074,6 +1074,11 @@ static void pt_addr_filters_fini(struct perf_event *event) | |||
1074 | event->hw.addr_filters = NULL; | 1074 | event->hw.addr_filters = NULL; |
1075 | } | 1075 | } |
1076 | 1076 | ||
1077 | static inline bool valid_kernel_ip(unsigned long ip) | ||
1078 | { | ||
1079 | return virt_addr_valid(ip) && kernel_ip(ip); | ||
1080 | } | ||
1081 | |||
1077 | static int pt_event_addr_filters_validate(struct list_head *filters) | 1082 | static int pt_event_addr_filters_validate(struct list_head *filters) |
1078 | { | 1083 | { |
1079 | struct perf_addr_filter *filter; | 1084 | struct perf_addr_filter *filter; |
@@ -1081,11 +1086,16 @@ static int pt_event_addr_filters_validate(struct list_head *filters) | |||
1081 | 1086 | ||
1082 | list_for_each_entry(filter, filters, entry) { | 1087 | list_for_each_entry(filter, filters, entry) { |
1083 | /* PT doesn't support single address triggers */ | 1088 | /* PT doesn't support single address triggers */ |
1084 | if (!filter->range) | 1089 | if (!filter->range || !filter->size) |
1085 | return -EOPNOTSUPP; | 1090 | return -EOPNOTSUPP; |
1086 | 1091 | ||
1087 | if (!filter->inode && !kernel_ip(filter->offset)) | 1092 | if (!filter->inode) { |
1088 | return -EINVAL; | 1093 | if (!valid_kernel_ip(filter->offset)) |
1094 | return -EINVAL; | ||
1095 | |||
1096 | if (!valid_kernel_ip(filter->offset + filter->size)) | ||
1097 | return -EINVAL; | ||
1098 | } | ||
1089 | 1099 | ||
1090 | if (++range > pt_cap_get(PT_CAP_num_address_ranges)) | 1100 | if (++range > pt_cap_get(PT_CAP_num_address_ranges)) |
1091 | return -EOPNOTSUPP; | 1101 | return -EOPNOTSUPP; |
@@ -1111,7 +1121,7 @@ static void pt_event_addr_filters_sync(struct perf_event *event) | |||
1111 | } else { | 1121 | } else { |
1112 | /* apply the offset */ | 1122 | /* apply the offset */ |
1113 | msr_a = filter->offset + offs[range]; | 1123 | msr_a = filter->offset + offs[range]; |
1114 | msr_b = filter->size + msr_a; | 1124 | msr_b = filter->size + msr_a - 1; |
1115 | } | 1125 | } |
1116 | 1126 | ||
1117 | filters->filter[range].msr_a = msr_a; | 1127 | filters->filter[range].msr_a = msr_a; |
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index a0ae610b9280..2131c4ce7d8a 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h | |||
@@ -433,7 +433,11 @@ do { \ | |||
433 | #define __get_user_asm_ex(x, addr, itype, rtype, ltype) \ | 433 | #define __get_user_asm_ex(x, addr, itype, rtype, ltype) \ |
434 | asm volatile("1: mov"itype" %1,%"rtype"0\n" \ | 434 | asm volatile("1: mov"itype" %1,%"rtype"0\n" \ |
435 | "2:\n" \ | 435 | "2:\n" \ |
436 | _ASM_EXTABLE_EX(1b, 2b) \ | 436 | ".section .fixup,\"ax\"\n" \ |
437 | "3:xor"itype" %"rtype"0,%"rtype"0\n" \ | ||
438 | " jmp 2b\n" \ | ||
439 | ".previous\n" \ | ||
440 | _ASM_EXTABLE_EX(1b, 3b) \ | ||
437 | : ltype(x) : "m" (__m(addr))) | 441 | : ltype(x) : "m" (__m(addr))) |
438 | 442 | ||
439 | #define __put_user_nocheck(x, ptr, size) \ | 443 | #define __put_user_nocheck(x, ptr, size) \ |
@@ -697,44 +701,15 @@ unsigned long __must_check _copy_from_user(void *to, const void __user *from, | |||
697 | unsigned long __must_check _copy_to_user(void __user *to, const void *from, | 701 | unsigned long __must_check _copy_to_user(void __user *to, const void *from, |
698 | unsigned n); | 702 | unsigned n); |
699 | 703 | ||
700 | #ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS | 704 | extern void __compiletime_error("usercopy buffer size is too small") |
701 | # define copy_user_diag __compiletime_error | 705 | __bad_copy_user(void); |
702 | #else | ||
703 | # define copy_user_diag __compiletime_warning | ||
704 | #endif | ||
705 | |||
706 | extern void copy_user_diag("copy_from_user() buffer size is too small") | ||
707 | copy_from_user_overflow(void); | ||
708 | extern void copy_user_diag("copy_to_user() buffer size is too small") | ||
709 | copy_to_user_overflow(void) __asm__("copy_from_user_overflow"); | ||
710 | |||
711 | #undef copy_user_diag | ||
712 | |||
713 | #ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS | ||
714 | |||
715 | extern void | ||
716 | __compiletime_warning("copy_from_user() buffer size is not provably correct") | ||
717 | __copy_from_user_overflow(void) __asm__("copy_from_user_overflow"); | ||
718 | #define __copy_from_user_overflow(size, count) __copy_from_user_overflow() | ||
719 | |||
720 | extern void | ||
721 | __compiletime_warning("copy_to_user() buffer size is not provably correct") | ||
722 | __copy_to_user_overflow(void) __asm__("copy_from_user_overflow"); | ||
723 | #define __copy_to_user_overflow(size, count) __copy_to_user_overflow() | ||
724 | 706 | ||
725 | #else | 707 | static inline void copy_user_overflow(int size, unsigned long count) |
726 | |||
727 | static inline void | ||
728 | __copy_from_user_overflow(int size, unsigned long count) | ||
729 | { | 708 | { |
730 | WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count); | 709 | WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count); |
731 | } | 710 | } |
732 | 711 | ||
733 | #define __copy_to_user_overflow __copy_from_user_overflow | 712 | static __always_inline unsigned long __must_check |
734 | |||
735 | #endif | ||
736 | |||
737 | static inline unsigned long __must_check | ||
738 | copy_from_user(void *to, const void __user *from, unsigned long n) | 713 | copy_from_user(void *to, const void __user *from, unsigned long n) |
739 | { | 714 | { |
740 | int sz = __compiletime_object_size(to); | 715 | int sz = __compiletime_object_size(to); |
@@ -743,36 +718,18 @@ copy_from_user(void *to, const void __user *from, unsigned long n) | |||
743 | 718 | ||
744 | kasan_check_write(to, n); | 719 | kasan_check_write(to, n); |
745 | 720 | ||
746 | /* | ||
747 | * While we would like to have the compiler do the checking for us | ||
748 | * even in the non-constant size case, any false positives there are | ||
749 | * a problem (especially when DEBUG_STRICT_USER_COPY_CHECKS, but even | ||
750 | * without - the [hopefully] dangerous looking nature of the warning | ||
751 | * would make people go look at the respecitive call sites over and | ||
752 | * over again just to find that there's no problem). | ||
753 | * | ||
754 | * And there are cases where it's just not realistic for the compiler | ||
755 | * to prove the count to be in range. For example when multiple call | ||
756 | * sites of a helper function - perhaps in different source files - | ||
757 | * all doing proper range checking, yet the helper function not doing | ||
758 | * so again. | ||
759 | * | ||
760 | * Therefore limit the compile time checking to the constant size | ||
761 | * case, and do only runtime checking for non-constant sizes. | ||
762 | */ | ||
763 | |||
764 | if (likely(sz < 0 || sz >= n)) { | 721 | if (likely(sz < 0 || sz >= n)) { |
765 | check_object_size(to, n, false); | 722 | check_object_size(to, n, false); |
766 | n = _copy_from_user(to, from, n); | 723 | n = _copy_from_user(to, from, n); |
767 | } else if (__builtin_constant_p(n)) | 724 | } else if (!__builtin_constant_p(n)) |
768 | copy_from_user_overflow(); | 725 | copy_user_overflow(sz, n); |
769 | else | 726 | else |
770 | __copy_from_user_overflow(sz, n); | 727 | __bad_copy_user(); |
771 | 728 | ||
772 | return n; | 729 | return n; |
773 | } | 730 | } |
774 | 731 | ||
775 | static inline unsigned long __must_check | 732 | static __always_inline unsigned long __must_check |
776 | copy_to_user(void __user *to, const void *from, unsigned long n) | 733 | copy_to_user(void __user *to, const void *from, unsigned long n) |
777 | { | 734 | { |
778 | int sz = __compiletime_object_size(from); | 735 | int sz = __compiletime_object_size(from); |
@@ -781,21 +738,17 @@ copy_to_user(void __user *to, const void *from, unsigned long n) | |||
781 | 738 | ||
782 | might_fault(); | 739 | might_fault(); |
783 | 740 | ||
784 | /* See the comment in copy_from_user() above. */ | ||
785 | if (likely(sz < 0 || sz >= n)) { | 741 | if (likely(sz < 0 || sz >= n)) { |
786 | check_object_size(from, n, true); | 742 | check_object_size(from, n, true); |
787 | n = _copy_to_user(to, from, n); | 743 | n = _copy_to_user(to, from, n); |
788 | } else if (__builtin_constant_p(n)) | 744 | } else if (!__builtin_constant_p(n)) |
789 | copy_to_user_overflow(); | 745 | copy_user_overflow(sz, n); |
790 | else | 746 | else |
791 | __copy_to_user_overflow(sz, n); | 747 | __bad_copy_user(); |
792 | 748 | ||
793 | return n; | 749 | return n; |
794 | } | 750 | } |
795 | 751 | ||
796 | #undef __copy_from_user_overflow | ||
797 | #undef __copy_to_user_overflow | ||
798 | |||
799 | /* | 752 | /* |
800 | * We rely on the nested NMI work to allow atomic faults from the NMI path; the | 753 | * We rely on the nested NMI work to allow atomic faults from the NMI path; the |
801 | * nested NMI paths are careful to preserve CR2. | 754 | * nested NMI paths are careful to preserve CR2. |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index cea4fc19e844..f3e9b2df4b16 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -1623,6 +1623,9 @@ void __init enable_IR_x2apic(void) | |||
1623 | unsigned long flags; | 1623 | unsigned long flags; |
1624 | int ret, ir_stat; | 1624 | int ret, ir_stat; |
1625 | 1625 | ||
1626 | if (skip_ioapic_setup) | ||
1627 | return; | ||
1628 | |||
1626 | ir_stat = irq_remapping_prepare(); | 1629 | ir_stat = irq_remapping_prepare(); |
1627 | if (ir_stat < 0 && !x2apic_supported()) | 1630 | if (ir_stat < 0 && !x2apic_supported()) |
1628 | return; | 1631 | return; |
@@ -2090,7 +2093,6 @@ int generic_processor_info(int apicid, int version) | |||
2090 | return -EINVAL; | 2093 | return -EINVAL; |
2091 | } | 2094 | } |
2092 | 2095 | ||
2093 | num_processors++; | ||
2094 | if (apicid == boot_cpu_physical_apicid) { | 2096 | if (apicid == boot_cpu_physical_apicid) { |
2095 | /* | 2097 | /* |
2096 | * x86_bios_cpu_apicid is required to have processors listed | 2098 | * x86_bios_cpu_apicid is required to have processors listed |
@@ -2113,10 +2115,13 @@ int generic_processor_info(int apicid, int version) | |||
2113 | 2115 | ||
2114 | pr_warning("APIC: Package limit reached. Processor %d/0x%x ignored.\n", | 2116 | pr_warning("APIC: Package limit reached. Processor %d/0x%x ignored.\n", |
2115 | thiscpu, apicid); | 2117 | thiscpu, apicid); |
2118 | |||
2116 | disabled_cpus++; | 2119 | disabled_cpus++; |
2117 | return -ENOSPC; | 2120 | return -ENOSPC; |
2118 | } | 2121 | } |
2119 | 2122 | ||
2123 | num_processors++; | ||
2124 | |||
2120 | /* | 2125 | /* |
2121 | * Validate version | 2126 | * Validate version |
2122 | */ | 2127 | */ |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index f5c69d8974e1..b81fe2d63e15 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -669,6 +669,17 @@ static void init_amd_gh(struct cpuinfo_x86 *c) | |||
669 | set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH); | 669 | set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH); |
670 | } | 670 | } |
671 | 671 | ||
672 | #define MSR_AMD64_DE_CFG 0xC0011029 | ||
673 | |||
674 | static void init_amd_ln(struct cpuinfo_x86 *c) | ||
675 | { | ||
676 | /* | ||
677 | * Apply erratum 665 fix unconditionally so machines without a BIOS | ||
678 | * fix work. | ||
679 | */ | ||
680 | msr_set_bit(MSR_AMD64_DE_CFG, 31); | ||
681 | } | ||
682 | |||
672 | static void init_amd_bd(struct cpuinfo_x86 *c) | 683 | static void init_amd_bd(struct cpuinfo_x86 *c) |
673 | { | 684 | { |
674 | u64 value; | 685 | u64 value; |
@@ -726,6 +737,7 @@ static void init_amd(struct cpuinfo_x86 *c) | |||
726 | case 6: init_amd_k7(c); break; | 737 | case 6: init_amd_k7(c); break; |
727 | case 0xf: init_amd_k8(c); break; | 738 | case 0xf: init_amd_k8(c); break; |
728 | case 0x10: init_amd_gh(c); break; | 739 | case 0x10: init_amd_gh(c); break; |
740 | case 0x12: init_amd_ln(c); break; | ||
729 | case 0x15: init_amd_bd(c); break; | 741 | case 0x15: init_amd_bd(c); break; |
730 | } | 742 | } |
731 | 743 | ||
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index b816971f5da4..620ab06bcf45 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c | |||
@@ -54,6 +54,7 @@ static LIST_HEAD(pcache); | |||
54 | */ | 54 | */ |
55 | static u8 *container; | 55 | static u8 *container; |
56 | static size_t container_size; | 56 | static size_t container_size; |
57 | static bool ucode_builtin; | ||
57 | 58 | ||
58 | static u32 ucode_new_rev; | 59 | static u32 ucode_new_rev; |
59 | static u8 amd_ucode_patch[PATCH_MAX_SIZE]; | 60 | static u8 amd_ucode_patch[PATCH_MAX_SIZE]; |
@@ -281,18 +282,22 @@ static bool __init load_builtin_amd_microcode(struct cpio_data *cp, | |||
281 | void __init load_ucode_amd_bsp(unsigned int family) | 282 | void __init load_ucode_amd_bsp(unsigned int family) |
282 | { | 283 | { |
283 | struct cpio_data cp; | 284 | struct cpio_data cp; |
285 | bool *builtin; | ||
284 | void **data; | 286 | void **data; |
285 | size_t *size; | 287 | size_t *size; |
286 | 288 | ||
287 | #ifdef CONFIG_X86_32 | 289 | #ifdef CONFIG_X86_32 |
288 | data = (void **)__pa_nodebug(&ucode_cpio.data); | 290 | data = (void **)__pa_nodebug(&ucode_cpio.data); |
289 | size = (size_t *)__pa_nodebug(&ucode_cpio.size); | 291 | size = (size_t *)__pa_nodebug(&ucode_cpio.size); |
292 | builtin = (bool *)__pa_nodebug(&ucode_builtin); | ||
290 | #else | 293 | #else |
291 | data = &ucode_cpio.data; | 294 | data = &ucode_cpio.data; |
292 | size = &ucode_cpio.size; | 295 | size = &ucode_cpio.size; |
296 | builtin = &ucode_builtin; | ||
293 | #endif | 297 | #endif |
294 | 298 | ||
295 | if (!load_builtin_amd_microcode(&cp, family)) | 299 | *builtin = load_builtin_amd_microcode(&cp, family); |
300 | if (!*builtin) | ||
296 | cp = find_ucode_in_initrd(); | 301 | cp = find_ucode_in_initrd(); |
297 | 302 | ||
298 | if (!(cp.data && cp.size)) | 303 | if (!(cp.data && cp.size)) |
@@ -373,7 +378,8 @@ void load_ucode_amd_ap(void) | |||
373 | return; | 378 | return; |
374 | 379 | ||
375 | /* Add CONFIG_RANDOMIZE_MEMORY offset. */ | 380 | /* Add CONFIG_RANDOMIZE_MEMORY offset. */ |
376 | cont += PAGE_OFFSET - __PAGE_OFFSET_BASE; | 381 | if (!ucode_builtin) |
382 | cont += PAGE_OFFSET - __PAGE_OFFSET_BASE; | ||
377 | 383 | ||
378 | eax = cpuid_eax(0x00000001); | 384 | eax = cpuid_eax(0x00000001); |
379 | eq = (struct equiv_cpu_entry *)(cont + CONTAINER_HDR_SZ); | 385 | eq = (struct equiv_cpu_entry *)(cont + CONTAINER_HDR_SZ); |
@@ -439,7 +445,8 @@ int __init save_microcode_in_initrd_amd(void) | |||
439 | container = cont_va; | 445 | container = cont_va; |
440 | 446 | ||
441 | /* Add CONFIG_RANDOMIZE_MEMORY offset. */ | 447 | /* Add CONFIG_RANDOMIZE_MEMORY offset. */ |
442 | container += PAGE_OFFSET - __PAGE_OFFSET_BASE; | 448 | if (!ucode_builtin) |
449 | container += PAGE_OFFSET - __PAGE_OFFSET_BASE; | ||
443 | 450 | ||
444 | eax = cpuid_eax(0x00000001); | 451 | eax = cpuid_eax(0x00000001); |
445 | eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); | 452 | eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); |
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 1d39bfbd26bb..3692249a70f1 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c | |||
@@ -289,6 +289,7 @@ void __init kvmclock_init(void) | |||
289 | put_cpu(); | 289 | put_cpu(); |
290 | 290 | ||
291 | x86_platform.calibrate_tsc = kvm_get_tsc_khz; | 291 | x86_platform.calibrate_tsc = kvm_get_tsc_khz; |
292 | x86_platform.calibrate_cpu = kvm_get_tsc_khz; | ||
292 | x86_platform.get_wallclock = kvm_get_wallclock; | 293 | x86_platform.get_wallclock = kvm_get_wallclock; |
293 | x86_platform.set_wallclock = kvm_set_wallclock; | 294 | x86_platform.set_wallclock = kvm_set_wallclock; |
294 | #ifdef CONFIG_X86_LOCAL_APIC | 295 | #ifdef CONFIG_X86_LOCAL_APIC |
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index ad5bc9578a73..1acfd76e3e26 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
@@ -56,12 +56,12 @@ asm (".pushsection .entry.text, \"ax\"\n" | |||
56 | ".popsection"); | 56 | ".popsection"); |
57 | 57 | ||
58 | /* identity function, which can be inlined */ | 58 | /* identity function, which can be inlined */ |
59 | u32 _paravirt_ident_32(u32 x) | 59 | u32 notrace _paravirt_ident_32(u32 x) |
60 | { | 60 | { |
61 | return x; | 61 | return x; |
62 | } | 62 | } |
63 | 63 | ||
64 | u64 _paravirt_ident_64(u64 x) | 64 | u64 notrace _paravirt_ident_64(u64 x) |
65 | { | 65 | { |
66 | return x; | 66 | return x; |
67 | } | 67 | } |
diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c index 5f42d038fcb4..c7220ba94aa7 100644 --- a/arch/x86/kvm/ioapic.c +++ b/arch/x86/kvm/ioapic.c | |||
@@ -109,6 +109,7 @@ static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu) | |||
109 | { | 109 | { |
110 | bool new_val, old_val; | 110 | bool new_val, old_val; |
111 | struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic; | 111 | struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic; |
112 | struct dest_map *dest_map = &ioapic->rtc_status.dest_map; | ||
112 | union kvm_ioapic_redirect_entry *e; | 113 | union kvm_ioapic_redirect_entry *e; |
113 | 114 | ||
114 | e = &ioapic->redirtbl[RTC_GSI]; | 115 | e = &ioapic->redirtbl[RTC_GSI]; |
@@ -117,16 +118,17 @@ static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu) | |||
117 | return; | 118 | return; |
118 | 119 | ||
119 | new_val = kvm_apic_pending_eoi(vcpu, e->fields.vector); | 120 | new_val = kvm_apic_pending_eoi(vcpu, e->fields.vector); |
120 | old_val = test_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map.map); | 121 | old_val = test_bit(vcpu->vcpu_id, dest_map->map); |
121 | 122 | ||
122 | if (new_val == old_val) | 123 | if (new_val == old_val) |
123 | return; | 124 | return; |
124 | 125 | ||
125 | if (new_val) { | 126 | if (new_val) { |
126 | __set_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map.map); | 127 | __set_bit(vcpu->vcpu_id, dest_map->map); |
128 | dest_map->vectors[vcpu->vcpu_id] = e->fields.vector; | ||
127 | ioapic->rtc_status.pending_eoi++; | 129 | ioapic->rtc_status.pending_eoi++; |
128 | } else { | 130 | } else { |
129 | __clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map.map); | 131 | __clear_bit(vcpu->vcpu_id, dest_map->map); |
130 | ioapic->rtc_status.pending_eoi--; | 132 | ioapic->rtc_status.pending_eoi--; |
131 | rtc_status_pending_eoi_check_valid(ioapic); | 133 | rtc_status_pending_eoi_check_valid(ioapic); |
132 | } | 134 | } |
diff --git a/arch/x86/kvm/pmu_amd.c b/arch/x86/kvm/pmu_amd.c index 39b91127ef07..cd944435dfbd 100644 --- a/arch/x86/kvm/pmu_amd.c +++ b/arch/x86/kvm/pmu_amd.c | |||
@@ -23,8 +23,8 @@ | |||
23 | static struct kvm_event_hw_type_mapping amd_event_mapping[] = { | 23 | static struct kvm_event_hw_type_mapping amd_event_mapping[] = { |
24 | [0] = { 0x76, 0x00, PERF_COUNT_HW_CPU_CYCLES }, | 24 | [0] = { 0x76, 0x00, PERF_COUNT_HW_CPU_CYCLES }, |
25 | [1] = { 0xc0, 0x00, PERF_COUNT_HW_INSTRUCTIONS }, | 25 | [1] = { 0xc0, 0x00, PERF_COUNT_HW_INSTRUCTIONS }, |
26 | [2] = { 0x80, 0x00, PERF_COUNT_HW_CACHE_REFERENCES }, | 26 | [2] = { 0x7d, 0x07, PERF_COUNT_HW_CACHE_REFERENCES }, |
27 | [3] = { 0x81, 0x00, PERF_COUNT_HW_CACHE_MISSES }, | 27 | [3] = { 0x7e, 0x07, PERF_COUNT_HW_CACHE_MISSES }, |
28 | [4] = { 0xc2, 0x00, PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, | 28 | [4] = { 0xc2, 0x00, PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, |
29 | [5] = { 0xc3, 0x00, PERF_COUNT_HW_BRANCH_MISSES }, | 29 | [5] = { 0xc3, 0x00, PERF_COUNT_HW_BRANCH_MISSES }, |
30 | [6] = { 0xd0, 0x00, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, | 30 | [6] = { 0xd0, 0x00, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index a45d8580f91e..5cede40e2552 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -422,6 +422,7 @@ struct nested_vmx { | |||
422 | struct list_head vmcs02_pool; | 422 | struct list_head vmcs02_pool; |
423 | int vmcs02_num; | 423 | int vmcs02_num; |
424 | u64 vmcs01_tsc_offset; | 424 | u64 vmcs01_tsc_offset; |
425 | bool change_vmcs01_virtual_x2apic_mode; | ||
425 | /* L2 must run next, and mustn't decide to exit to L1. */ | 426 | /* L2 must run next, and mustn't decide to exit to L1. */ |
426 | bool nested_run_pending; | 427 | bool nested_run_pending; |
427 | /* | 428 | /* |
@@ -435,6 +436,8 @@ struct nested_vmx { | |||
435 | bool pi_pending; | 436 | bool pi_pending; |
436 | u16 posted_intr_nv; | 437 | u16 posted_intr_nv; |
437 | 438 | ||
439 | unsigned long *msr_bitmap; | ||
440 | |||
438 | struct hrtimer preemption_timer; | 441 | struct hrtimer preemption_timer; |
439 | bool preemption_timer_expired; | 442 | bool preemption_timer_expired; |
440 | 443 | ||
@@ -924,7 +927,6 @@ static unsigned long *vmx_msr_bitmap_legacy; | |||
924 | static unsigned long *vmx_msr_bitmap_longmode; | 927 | static unsigned long *vmx_msr_bitmap_longmode; |
925 | static unsigned long *vmx_msr_bitmap_legacy_x2apic; | 928 | static unsigned long *vmx_msr_bitmap_legacy_x2apic; |
926 | static unsigned long *vmx_msr_bitmap_longmode_x2apic; | 929 | static unsigned long *vmx_msr_bitmap_longmode_x2apic; |
927 | static unsigned long *vmx_msr_bitmap_nested; | ||
928 | static unsigned long *vmx_vmread_bitmap; | 930 | static unsigned long *vmx_vmread_bitmap; |
929 | static unsigned long *vmx_vmwrite_bitmap; | 931 | static unsigned long *vmx_vmwrite_bitmap; |
930 | 932 | ||
@@ -2198,6 +2200,12 @@ static void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu) | |||
2198 | new.control) != old.control); | 2200 | new.control) != old.control); |
2199 | } | 2201 | } |
2200 | 2202 | ||
2203 | static void decache_tsc_multiplier(struct vcpu_vmx *vmx) | ||
2204 | { | ||
2205 | vmx->current_tsc_ratio = vmx->vcpu.arch.tsc_scaling_ratio; | ||
2206 | vmcs_write64(TSC_MULTIPLIER, vmx->current_tsc_ratio); | ||
2207 | } | ||
2208 | |||
2201 | /* | 2209 | /* |
2202 | * Switches to specified vcpu, until a matching vcpu_put(), but assumes | 2210 | * Switches to specified vcpu, until a matching vcpu_put(), but assumes |
2203 | * vcpu mutex is already taken. | 2211 | * vcpu mutex is already taken. |
@@ -2256,10 +2264,8 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
2256 | 2264 | ||
2257 | /* Setup TSC multiplier */ | 2265 | /* Setup TSC multiplier */ |
2258 | if (kvm_has_tsc_control && | 2266 | if (kvm_has_tsc_control && |
2259 | vmx->current_tsc_ratio != vcpu->arch.tsc_scaling_ratio) { | 2267 | vmx->current_tsc_ratio != vcpu->arch.tsc_scaling_ratio) |
2260 | vmx->current_tsc_ratio = vcpu->arch.tsc_scaling_ratio; | 2268 | decache_tsc_multiplier(vmx); |
2261 | vmcs_write64(TSC_MULTIPLIER, vmx->current_tsc_ratio); | ||
2262 | } | ||
2263 | 2269 | ||
2264 | vmx_vcpu_pi_load(vcpu, cpu); | 2270 | vmx_vcpu_pi_load(vcpu, cpu); |
2265 | vmx->host_pkru = read_pkru(); | 2271 | vmx->host_pkru = read_pkru(); |
@@ -2508,7 +2514,7 @@ static void vmx_set_msr_bitmap(struct kvm_vcpu *vcpu) | |||
2508 | unsigned long *msr_bitmap; | 2514 | unsigned long *msr_bitmap; |
2509 | 2515 | ||
2510 | if (is_guest_mode(vcpu)) | 2516 | if (is_guest_mode(vcpu)) |
2511 | msr_bitmap = vmx_msr_bitmap_nested; | 2517 | msr_bitmap = to_vmx(vcpu)->nested.msr_bitmap; |
2512 | else if (cpu_has_secondary_exec_ctrls() && | 2518 | else if (cpu_has_secondary_exec_ctrls() && |
2513 | (vmcs_read32(SECONDARY_VM_EXEC_CONTROL) & | 2519 | (vmcs_read32(SECONDARY_VM_EXEC_CONTROL) & |
2514 | SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE)) { | 2520 | SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE)) { |
@@ -6363,13 +6369,6 @@ static __init int hardware_setup(void) | |||
6363 | if (!vmx_msr_bitmap_longmode_x2apic) | 6369 | if (!vmx_msr_bitmap_longmode_x2apic) |
6364 | goto out4; | 6370 | goto out4; |
6365 | 6371 | ||
6366 | if (nested) { | ||
6367 | vmx_msr_bitmap_nested = | ||
6368 | (unsigned long *)__get_free_page(GFP_KERNEL); | ||
6369 | if (!vmx_msr_bitmap_nested) | ||
6370 | goto out5; | ||
6371 | } | ||
6372 | |||
6373 | vmx_vmread_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL); | 6372 | vmx_vmread_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL); |
6374 | if (!vmx_vmread_bitmap) | 6373 | if (!vmx_vmread_bitmap) |
6375 | goto out6; | 6374 | goto out6; |
@@ -6392,8 +6391,6 @@ static __init int hardware_setup(void) | |||
6392 | 6391 | ||
6393 | memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE); | 6392 | memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE); |
6394 | memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE); | 6393 | memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE); |
6395 | if (nested) | ||
6396 | memset(vmx_msr_bitmap_nested, 0xff, PAGE_SIZE); | ||
6397 | 6394 | ||
6398 | if (setup_vmcs_config(&vmcs_config) < 0) { | 6395 | if (setup_vmcs_config(&vmcs_config) < 0) { |
6399 | r = -EIO; | 6396 | r = -EIO; |
@@ -6529,9 +6526,6 @@ out8: | |||
6529 | out7: | 6526 | out7: |
6530 | free_page((unsigned long)vmx_vmread_bitmap); | 6527 | free_page((unsigned long)vmx_vmread_bitmap); |
6531 | out6: | 6528 | out6: |
6532 | if (nested) | ||
6533 | free_page((unsigned long)vmx_msr_bitmap_nested); | ||
6534 | out5: | ||
6535 | free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic); | 6529 | free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic); |
6536 | out4: | 6530 | out4: |
6537 | free_page((unsigned long)vmx_msr_bitmap_longmode); | 6531 | free_page((unsigned long)vmx_msr_bitmap_longmode); |
@@ -6557,8 +6551,6 @@ static __exit void hardware_unsetup(void) | |||
6557 | free_page((unsigned long)vmx_io_bitmap_a); | 6551 | free_page((unsigned long)vmx_io_bitmap_a); |
6558 | free_page((unsigned long)vmx_vmwrite_bitmap); | 6552 | free_page((unsigned long)vmx_vmwrite_bitmap); |
6559 | free_page((unsigned long)vmx_vmread_bitmap); | 6553 | free_page((unsigned long)vmx_vmread_bitmap); |
6560 | if (nested) | ||
6561 | free_page((unsigned long)vmx_msr_bitmap_nested); | ||
6562 | 6554 | ||
6563 | free_kvm_area(); | 6555 | free_kvm_area(); |
6564 | } | 6556 | } |
@@ -6995,16 +6987,21 @@ static int handle_vmon(struct kvm_vcpu *vcpu) | |||
6995 | return 1; | 6987 | return 1; |
6996 | } | 6988 | } |
6997 | 6989 | ||
6990 | if (cpu_has_vmx_msr_bitmap()) { | ||
6991 | vmx->nested.msr_bitmap = | ||
6992 | (unsigned long *)__get_free_page(GFP_KERNEL); | ||
6993 | if (!vmx->nested.msr_bitmap) | ||
6994 | goto out_msr_bitmap; | ||
6995 | } | ||
6996 | |||
6998 | vmx->nested.cached_vmcs12 = kmalloc(VMCS12_SIZE, GFP_KERNEL); | 6997 | vmx->nested.cached_vmcs12 = kmalloc(VMCS12_SIZE, GFP_KERNEL); |
6999 | if (!vmx->nested.cached_vmcs12) | 6998 | if (!vmx->nested.cached_vmcs12) |
7000 | return -ENOMEM; | 6999 | goto out_cached_vmcs12; |
7001 | 7000 | ||
7002 | if (enable_shadow_vmcs) { | 7001 | if (enable_shadow_vmcs) { |
7003 | shadow_vmcs = alloc_vmcs(); | 7002 | shadow_vmcs = alloc_vmcs(); |
7004 | if (!shadow_vmcs) { | 7003 | if (!shadow_vmcs) |
7005 | kfree(vmx->nested.cached_vmcs12); | 7004 | goto out_shadow_vmcs; |
7006 | return -ENOMEM; | ||
7007 | } | ||
7008 | /* mark vmcs as shadow */ | 7005 | /* mark vmcs as shadow */ |
7009 | shadow_vmcs->revision_id |= (1u << 31); | 7006 | shadow_vmcs->revision_id |= (1u << 31); |
7010 | /* init shadow vmcs */ | 7007 | /* init shadow vmcs */ |
@@ -7024,6 +7021,15 @@ static int handle_vmon(struct kvm_vcpu *vcpu) | |||
7024 | skip_emulated_instruction(vcpu); | 7021 | skip_emulated_instruction(vcpu); |
7025 | nested_vmx_succeed(vcpu); | 7022 | nested_vmx_succeed(vcpu); |
7026 | return 1; | 7023 | return 1; |
7024 | |||
7025 | out_shadow_vmcs: | ||
7026 | kfree(vmx->nested.cached_vmcs12); | ||
7027 | |||
7028 | out_cached_vmcs12: | ||
7029 | free_page((unsigned long)vmx->nested.msr_bitmap); | ||
7030 | |||
7031 | out_msr_bitmap: | ||
7032 | return -ENOMEM; | ||
7027 | } | 7033 | } |
7028 | 7034 | ||
7029 | /* | 7035 | /* |
@@ -7098,6 +7104,10 @@ static void free_nested(struct vcpu_vmx *vmx) | |||
7098 | vmx->nested.vmxon = false; | 7104 | vmx->nested.vmxon = false; |
7099 | free_vpid(vmx->nested.vpid02); | 7105 | free_vpid(vmx->nested.vpid02); |
7100 | nested_release_vmcs12(vmx); | 7106 | nested_release_vmcs12(vmx); |
7107 | if (vmx->nested.msr_bitmap) { | ||
7108 | free_page((unsigned long)vmx->nested.msr_bitmap); | ||
7109 | vmx->nested.msr_bitmap = NULL; | ||
7110 | } | ||
7101 | if (enable_shadow_vmcs) | 7111 | if (enable_shadow_vmcs) |
7102 | free_vmcs(vmx->nested.current_shadow_vmcs); | 7112 | free_vmcs(vmx->nested.current_shadow_vmcs); |
7103 | kfree(vmx->nested.cached_vmcs12); | 7113 | kfree(vmx->nested.cached_vmcs12); |
@@ -8419,6 +8429,12 @@ static void vmx_set_virtual_x2apic_mode(struct kvm_vcpu *vcpu, bool set) | |||
8419 | { | 8429 | { |
8420 | u32 sec_exec_control; | 8430 | u32 sec_exec_control; |
8421 | 8431 | ||
8432 | /* Postpone execution until vmcs01 is the current VMCS. */ | ||
8433 | if (is_guest_mode(vcpu)) { | ||
8434 | to_vmx(vcpu)->nested.change_vmcs01_virtual_x2apic_mode = true; | ||
8435 | return; | ||
8436 | } | ||
8437 | |||
8422 | /* | 8438 | /* |
8423 | * There is not point to enable virtualize x2apic without enable | 8439 | * There is not point to enable virtualize x2apic without enable |
8424 | * apicv | 8440 | * apicv |
@@ -9472,8 +9488,10 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu, | |||
9472 | { | 9488 | { |
9473 | int msr; | 9489 | int msr; |
9474 | struct page *page; | 9490 | struct page *page; |
9475 | unsigned long *msr_bitmap; | 9491 | unsigned long *msr_bitmap_l1; |
9492 | unsigned long *msr_bitmap_l0 = to_vmx(vcpu)->nested.msr_bitmap; | ||
9476 | 9493 | ||
9494 | /* This shortcut is ok because we support only x2APIC MSRs so far. */ | ||
9477 | if (!nested_cpu_has_virt_x2apic_mode(vmcs12)) | 9495 | if (!nested_cpu_has_virt_x2apic_mode(vmcs12)) |
9478 | return false; | 9496 | return false; |
9479 | 9497 | ||
@@ -9482,63 +9500,37 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu, | |||
9482 | WARN_ON(1); | 9500 | WARN_ON(1); |
9483 | return false; | 9501 | return false; |
9484 | } | 9502 | } |
9485 | msr_bitmap = (unsigned long *)kmap(page); | 9503 | msr_bitmap_l1 = (unsigned long *)kmap(page); |
9486 | if (!msr_bitmap) { | 9504 | if (!msr_bitmap_l1) { |
9487 | nested_release_page_clean(page); | 9505 | nested_release_page_clean(page); |
9488 | WARN_ON(1); | 9506 | WARN_ON(1); |
9489 | return false; | 9507 | return false; |
9490 | } | 9508 | } |
9491 | 9509 | ||
9510 | memset(msr_bitmap_l0, 0xff, PAGE_SIZE); | ||
9511 | |||
9492 | if (nested_cpu_has_virt_x2apic_mode(vmcs12)) { | 9512 | if (nested_cpu_has_virt_x2apic_mode(vmcs12)) { |
9493 | if (nested_cpu_has_apic_reg_virt(vmcs12)) | 9513 | if (nested_cpu_has_apic_reg_virt(vmcs12)) |
9494 | for (msr = 0x800; msr <= 0x8ff; msr++) | 9514 | for (msr = 0x800; msr <= 0x8ff; msr++) |
9495 | nested_vmx_disable_intercept_for_msr( | 9515 | nested_vmx_disable_intercept_for_msr( |
9496 | msr_bitmap, | 9516 | msr_bitmap_l1, msr_bitmap_l0, |
9497 | vmx_msr_bitmap_nested, | ||
9498 | msr, MSR_TYPE_R); | 9517 | msr, MSR_TYPE_R); |
9499 | /* TPR is allowed */ | 9518 | |
9500 | nested_vmx_disable_intercept_for_msr(msr_bitmap, | 9519 | nested_vmx_disable_intercept_for_msr( |
9501 | vmx_msr_bitmap_nested, | 9520 | msr_bitmap_l1, msr_bitmap_l0, |
9502 | APIC_BASE_MSR + (APIC_TASKPRI >> 4), | 9521 | APIC_BASE_MSR + (APIC_TASKPRI >> 4), |
9503 | MSR_TYPE_R | MSR_TYPE_W); | 9522 | MSR_TYPE_R | MSR_TYPE_W); |
9523 | |||
9504 | if (nested_cpu_has_vid(vmcs12)) { | 9524 | if (nested_cpu_has_vid(vmcs12)) { |
9505 | /* EOI and self-IPI are allowed */ | ||
9506 | nested_vmx_disable_intercept_for_msr( | 9525 | nested_vmx_disable_intercept_for_msr( |
9507 | msr_bitmap, | 9526 | msr_bitmap_l1, msr_bitmap_l0, |
9508 | vmx_msr_bitmap_nested, | ||
9509 | APIC_BASE_MSR + (APIC_EOI >> 4), | 9527 | APIC_BASE_MSR + (APIC_EOI >> 4), |
9510 | MSR_TYPE_W); | 9528 | MSR_TYPE_W); |
9511 | nested_vmx_disable_intercept_for_msr( | 9529 | nested_vmx_disable_intercept_for_msr( |
9512 | msr_bitmap, | 9530 | msr_bitmap_l1, msr_bitmap_l0, |
9513 | vmx_msr_bitmap_nested, | ||
9514 | APIC_BASE_MSR + (APIC_SELF_IPI >> 4), | 9531 | APIC_BASE_MSR + (APIC_SELF_IPI >> 4), |
9515 | MSR_TYPE_W); | 9532 | MSR_TYPE_W); |
9516 | } | 9533 | } |
9517 | } else { | ||
9518 | /* | ||
9519 | * Enable reading intercept of all the x2apic | ||
9520 | * MSRs. We should not rely on vmcs12 to do any | ||
9521 | * optimizations here, it may have been modified | ||
9522 | * by L1. | ||
9523 | */ | ||
9524 | for (msr = 0x800; msr <= 0x8ff; msr++) | ||
9525 | __vmx_enable_intercept_for_msr( | ||
9526 | vmx_msr_bitmap_nested, | ||
9527 | msr, | ||
9528 | MSR_TYPE_R); | ||
9529 | |||
9530 | __vmx_enable_intercept_for_msr( | ||
9531 | vmx_msr_bitmap_nested, | ||
9532 | APIC_BASE_MSR + (APIC_TASKPRI >> 4), | ||
9533 | MSR_TYPE_W); | ||
9534 | __vmx_enable_intercept_for_msr( | ||
9535 | vmx_msr_bitmap_nested, | ||
9536 | APIC_BASE_MSR + (APIC_EOI >> 4), | ||
9537 | MSR_TYPE_W); | ||
9538 | __vmx_enable_intercept_for_msr( | ||
9539 | vmx_msr_bitmap_nested, | ||
9540 | APIC_BASE_MSR + (APIC_SELF_IPI >> 4), | ||
9541 | MSR_TYPE_W); | ||
9542 | } | 9534 | } |
9543 | kunmap(page); | 9535 | kunmap(page); |
9544 | nested_release_page_clean(page); | 9536 | nested_release_page_clean(page); |
@@ -9957,10 +9949,10 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
9957 | } | 9949 | } |
9958 | 9950 | ||
9959 | if (cpu_has_vmx_msr_bitmap() && | 9951 | if (cpu_has_vmx_msr_bitmap() && |
9960 | exec_control & CPU_BASED_USE_MSR_BITMAPS) { | 9952 | exec_control & CPU_BASED_USE_MSR_BITMAPS && |
9961 | nested_vmx_merge_msr_bitmap(vcpu, vmcs12); | 9953 | nested_vmx_merge_msr_bitmap(vcpu, vmcs12)) |
9962 | /* MSR_BITMAP will be set by following vmx_set_efer. */ | 9954 | ; /* MSR_BITMAP will be set by following vmx_set_efer. */ |
9963 | } else | 9955 | else |
9964 | exec_control &= ~CPU_BASED_USE_MSR_BITMAPS; | 9956 | exec_control &= ~CPU_BASED_USE_MSR_BITMAPS; |
9965 | 9957 | ||
9966 | /* | 9958 | /* |
@@ -10011,6 +10003,8 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
10011 | vmx->nested.vmcs01_tsc_offset + vmcs12->tsc_offset); | 10003 | vmx->nested.vmcs01_tsc_offset + vmcs12->tsc_offset); |
10012 | else | 10004 | else |
10013 | vmcs_write64(TSC_OFFSET, vmx->nested.vmcs01_tsc_offset); | 10005 | vmcs_write64(TSC_OFFSET, vmx->nested.vmcs01_tsc_offset); |
10006 | if (kvm_has_tsc_control) | ||
10007 | decache_tsc_multiplier(vmx); | ||
10014 | 10008 | ||
10015 | if (enable_vpid) { | 10009 | if (enable_vpid) { |
10016 | /* | 10010 | /* |
@@ -10767,6 +10761,14 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason, | |||
10767 | else | 10761 | else |
10768 | vmcs_set_bits(PIN_BASED_VM_EXEC_CONTROL, | 10762 | vmcs_set_bits(PIN_BASED_VM_EXEC_CONTROL, |
10769 | PIN_BASED_VMX_PREEMPTION_TIMER); | 10763 | PIN_BASED_VMX_PREEMPTION_TIMER); |
10764 | if (kvm_has_tsc_control) | ||
10765 | decache_tsc_multiplier(vmx); | ||
10766 | |||
10767 | if (vmx->nested.change_vmcs01_virtual_x2apic_mode) { | ||
10768 | vmx->nested.change_vmcs01_virtual_x2apic_mode = false; | ||
10769 | vmx_set_virtual_x2apic_mode(vcpu, | ||
10770 | vcpu->arch.apic_base & X2APIC_ENABLE); | ||
10771 | } | ||
10770 | 10772 | ||
10771 | /* This is needed for same reason as it was needed in prepare_vmcs02 */ | 10773 | /* This is needed for same reason as it was needed in prepare_vmcs02 */ |
10772 | vmx->host_rsp = 0; | 10774 | vmx->host_rsp = 0; |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 19f9f9e05c2a..699f8726539a 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -2743,16 +2743,16 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
2743 | if (tsc_delta < 0) | 2743 | if (tsc_delta < 0) |
2744 | mark_tsc_unstable("KVM discovered backwards TSC"); | 2744 | mark_tsc_unstable("KVM discovered backwards TSC"); |
2745 | 2745 | ||
2746 | if (kvm_lapic_hv_timer_in_use(vcpu) && | ||
2747 | kvm_x86_ops->set_hv_timer(vcpu, | ||
2748 | kvm_get_lapic_tscdeadline_msr(vcpu))) | ||
2749 | kvm_lapic_switch_to_sw_timer(vcpu); | ||
2750 | if (check_tsc_unstable()) { | 2746 | if (check_tsc_unstable()) { |
2751 | u64 offset = kvm_compute_tsc_offset(vcpu, | 2747 | u64 offset = kvm_compute_tsc_offset(vcpu, |
2752 | vcpu->arch.last_guest_tsc); | 2748 | vcpu->arch.last_guest_tsc); |
2753 | kvm_x86_ops->write_tsc_offset(vcpu, offset); | 2749 | kvm_x86_ops->write_tsc_offset(vcpu, offset); |
2754 | vcpu->arch.tsc_catchup = 1; | 2750 | vcpu->arch.tsc_catchup = 1; |
2755 | } | 2751 | } |
2752 | if (kvm_lapic_hv_timer_in_use(vcpu) && | ||
2753 | kvm_x86_ops->set_hv_timer(vcpu, | ||
2754 | kvm_get_lapic_tscdeadline_msr(vcpu))) | ||
2755 | kvm_lapic_switch_to_sw_timer(vcpu); | ||
2756 | /* | 2756 | /* |
2757 | * On a host with synchronized TSC, there is no need to update | 2757 | * On a host with synchronized TSC, there is no need to update |
2758 | * kvmclock on vcpu->cpu migration | 2758 | * kvmclock on vcpu->cpu migration |
diff --git a/arch/x86/mm/kaslr.c b/arch/x86/mm/kaslr.c index ec8654f117d8..bda8d5eef04d 100644 --- a/arch/x86/mm/kaslr.c +++ b/arch/x86/mm/kaslr.c | |||
@@ -77,7 +77,7 @@ static inline unsigned long get_padding(struct kaslr_memory_region *region) | |||
77 | */ | 77 | */ |
78 | static inline bool kaslr_memory_enabled(void) | 78 | static inline bool kaslr_memory_enabled(void) |
79 | { | 79 | { |
80 | return kaslr_enabled() && !config_enabled(CONFIG_KASAN); | 80 | return kaslr_enabled() && !IS_ENABLED(CONFIG_KASAN); |
81 | } | 81 | } |
82 | 82 | ||
83 | /* Initialize base and padding for each memory region randomized with KASLR */ | 83 | /* Initialize base and padding for each memory region randomized with KASLR */ |
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 849dc09fa4f0..e3353c97d086 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -917,11 +917,11 @@ static void populate_pte(struct cpa_data *cpa, | |||
917 | } | 917 | } |
918 | } | 918 | } |
919 | 919 | ||
920 | static int populate_pmd(struct cpa_data *cpa, | 920 | static long populate_pmd(struct cpa_data *cpa, |
921 | unsigned long start, unsigned long end, | 921 | unsigned long start, unsigned long end, |
922 | unsigned num_pages, pud_t *pud, pgprot_t pgprot) | 922 | unsigned num_pages, pud_t *pud, pgprot_t pgprot) |
923 | { | 923 | { |
924 | unsigned int cur_pages = 0; | 924 | long cur_pages = 0; |
925 | pmd_t *pmd; | 925 | pmd_t *pmd; |
926 | pgprot_t pmd_pgprot; | 926 | pgprot_t pmd_pgprot; |
927 | 927 | ||
@@ -991,12 +991,12 @@ static int populate_pmd(struct cpa_data *cpa, | |||
991 | return num_pages; | 991 | return num_pages; |
992 | } | 992 | } |
993 | 993 | ||
994 | static int populate_pud(struct cpa_data *cpa, unsigned long start, pgd_t *pgd, | 994 | static long populate_pud(struct cpa_data *cpa, unsigned long start, pgd_t *pgd, |
995 | pgprot_t pgprot) | 995 | pgprot_t pgprot) |
996 | { | 996 | { |
997 | pud_t *pud; | 997 | pud_t *pud; |
998 | unsigned long end; | 998 | unsigned long end; |
999 | int cur_pages = 0; | 999 | long cur_pages = 0; |
1000 | pgprot_t pud_pgprot; | 1000 | pgprot_t pud_pgprot; |
1001 | 1001 | ||
1002 | end = start + (cpa->numpages << PAGE_SHIFT); | 1002 | end = start + (cpa->numpages << PAGE_SHIFT); |
@@ -1052,7 +1052,7 @@ static int populate_pud(struct cpa_data *cpa, unsigned long start, pgd_t *pgd, | |||
1052 | 1052 | ||
1053 | /* Map trailing leftover */ | 1053 | /* Map trailing leftover */ |
1054 | if (start < end) { | 1054 | if (start < end) { |
1055 | int tmp; | 1055 | long tmp; |
1056 | 1056 | ||
1057 | pud = pud_offset(pgd, start); | 1057 | pud = pud_offset(pgd, start); |
1058 | if (pud_none(*pud)) | 1058 | if (pud_none(*pud)) |
@@ -1078,7 +1078,7 @@ static int populate_pgd(struct cpa_data *cpa, unsigned long addr) | |||
1078 | pgprot_t pgprot = __pgprot(_KERNPG_TABLE); | 1078 | pgprot_t pgprot = __pgprot(_KERNPG_TABLE); |
1079 | pud_t *pud = NULL; /* shut up gcc */ | 1079 | pud_t *pud = NULL; /* shut up gcc */ |
1080 | pgd_t *pgd_entry; | 1080 | pgd_t *pgd_entry; |
1081 | int ret; | 1081 | long ret; |
1082 | 1082 | ||
1083 | pgd_entry = cpa->pgd + pgd_index(addr); | 1083 | pgd_entry = cpa->pgd + pgd_index(addr); |
1084 | 1084 | ||
@@ -1327,7 +1327,8 @@ static int cpa_process_alias(struct cpa_data *cpa) | |||
1327 | 1327 | ||
1328 | static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) | 1328 | static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) |
1329 | { | 1329 | { |
1330 | int ret, numpages = cpa->numpages; | 1330 | unsigned long numpages = cpa->numpages; |
1331 | int ret; | ||
1331 | 1332 | ||
1332 | while (numpages) { | 1333 | while (numpages) { |
1333 | /* | 1334 | /* |
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index ecb1b69c1651..170cc4ff057b 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
@@ -927,9 +927,10 @@ int track_pfn_copy(struct vm_area_struct *vma) | |||
927 | } | 927 | } |
928 | 928 | ||
929 | /* | 929 | /* |
930 | * prot is passed in as a parameter for the new mapping. If the vma has a | 930 | * prot is passed in as a parameter for the new mapping. If the vma has |
931 | * linear pfn mapping for the entire range reserve the entire vma range with | 931 | * a linear pfn mapping for the entire range, or no vma is provided, |
932 | * single reserve_pfn_range call. | 932 | * reserve the entire pfn + size range with single reserve_pfn_range |
933 | * call. | ||
933 | */ | 934 | */ |
934 | int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot, | 935 | int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot, |
935 | unsigned long pfn, unsigned long addr, unsigned long size) | 936 | unsigned long pfn, unsigned long addr, unsigned long size) |
@@ -938,11 +939,12 @@ int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot, | |||
938 | enum page_cache_mode pcm; | 939 | enum page_cache_mode pcm; |
939 | 940 | ||
940 | /* reserve the whole chunk starting from paddr */ | 941 | /* reserve the whole chunk starting from paddr */ |
941 | if (addr == vma->vm_start && size == (vma->vm_end - vma->vm_start)) { | 942 | if (!vma || (addr == vma->vm_start |
943 | && size == (vma->vm_end - vma->vm_start))) { | ||
942 | int ret; | 944 | int ret; |
943 | 945 | ||
944 | ret = reserve_pfn_range(paddr, size, prot, 0); | 946 | ret = reserve_pfn_range(paddr, size, prot, 0); |
945 | if (!ret) | 947 | if (ret == 0 && vma) |
946 | vma->vm_flags |= VM_PAT; | 948 | vma->vm_flags |= VM_PAT; |
947 | return ret; | 949 | return ret; |
948 | } | 950 | } |
@@ -997,7 +999,7 @@ void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn, | |||
997 | resource_size_t paddr; | 999 | resource_size_t paddr; |
998 | unsigned long prot; | 1000 | unsigned long prot; |
999 | 1001 | ||
1000 | if (!(vma->vm_flags & VM_PAT)) | 1002 | if (vma && !(vma->vm_flags & VM_PAT)) |
1001 | return; | 1003 | return; |
1002 | 1004 | ||
1003 | /* free the chunk starting from pfn or the whole chunk */ | 1005 | /* free the chunk starting from pfn or the whole chunk */ |
@@ -1011,7 +1013,8 @@ void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn, | |||
1011 | size = vma->vm_end - vma->vm_start; | 1013 | size = vma->vm_end - vma->vm_start; |
1012 | } | 1014 | } |
1013 | free_pfn_range(paddr, size); | 1015 | free_pfn_range(paddr, size); |
1014 | vma->vm_flags &= ~VM_PAT; | 1016 | if (vma) |
1017 | vma->vm_flags &= ~VM_PAT; | ||
1015 | } | 1018 | } |
1016 | 1019 | ||
1017 | /* | 1020 | /* |
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 837ea36a837d..6d52b94f4bb9 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c | |||
@@ -553,15 +553,21 @@ static void twinhead_reserve_killing_zone(struct pci_dev *dev) | |||
553 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x27B9, twinhead_reserve_killing_zone); | 553 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x27B9, twinhead_reserve_killing_zone); |
554 | 554 | ||
555 | /* | 555 | /* |
556 | * Broadwell EP Home Agent BARs erroneously return non-zero values when read. | 556 | * Device [8086:2fc0] |
557 | * Erratum HSE43 | ||
558 | * CONFIG_TDP_NOMINAL CSR Implemented at Incorrect Offset | ||
559 | * http://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v3-spec-update.html | ||
557 | * | 560 | * |
558 | * See http://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v4-spec-update.html | 561 | * Devices [8086:6f60,6fa0,6fc0] |
559 | * entry BDF2. | 562 | * Erratum BDF2 |
563 | * PCI BARs in the Home Agent Will Return Non-Zero Values During Enumeration | ||
564 | * http://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v4-spec-update.html | ||
560 | */ | 565 | */ |
561 | static void pci_bdwep_bar(struct pci_dev *dev) | 566 | static void pci_invalid_bar(struct pci_dev *dev) |
562 | { | 567 | { |
563 | dev->non_compliant_bars = 1; | 568 | dev->non_compliant_bars = 1; |
564 | } | 569 | } |
565 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6f60, pci_bdwep_bar); | 570 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2fc0, pci_invalid_bar); |
566 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fa0, pci_bdwep_bar); | 571 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6f60, pci_invalid_bar); |
567 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, pci_bdwep_bar); | 572 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fa0, pci_invalid_bar); |
573 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, pci_invalid_bar); | ||
diff --git a/arch/x86/pci/vmd.c b/arch/x86/pci/vmd.c index b814ca675131..7948be342ee9 100644 --- a/arch/x86/pci/vmd.c +++ b/arch/x86/pci/vmd.c | |||
@@ -41,6 +41,7 @@ static DEFINE_RAW_SPINLOCK(list_lock); | |||
41 | * @node: list item for parent traversal. | 41 | * @node: list item for parent traversal. |
42 | * @rcu: RCU callback item for freeing. | 42 | * @rcu: RCU callback item for freeing. |
43 | * @irq: back pointer to parent. | 43 | * @irq: back pointer to parent. |
44 | * @enabled: true if driver enabled IRQ | ||
44 | * @virq: the virtual IRQ value provided to the requesting driver. | 45 | * @virq: the virtual IRQ value provided to the requesting driver. |
45 | * | 46 | * |
46 | * Every MSI/MSI-X IRQ requested for a device in a VMD domain will be mapped to | 47 | * Every MSI/MSI-X IRQ requested for a device in a VMD domain will be mapped to |
@@ -50,6 +51,7 @@ struct vmd_irq { | |||
50 | struct list_head node; | 51 | struct list_head node; |
51 | struct rcu_head rcu; | 52 | struct rcu_head rcu; |
52 | struct vmd_irq_list *irq; | 53 | struct vmd_irq_list *irq; |
54 | bool enabled; | ||
53 | unsigned int virq; | 55 | unsigned int virq; |
54 | }; | 56 | }; |
55 | 57 | ||
@@ -122,7 +124,9 @@ static void vmd_irq_enable(struct irq_data *data) | |||
122 | unsigned long flags; | 124 | unsigned long flags; |
123 | 125 | ||
124 | raw_spin_lock_irqsave(&list_lock, flags); | 126 | raw_spin_lock_irqsave(&list_lock, flags); |
127 | WARN_ON(vmdirq->enabled); | ||
125 | list_add_tail_rcu(&vmdirq->node, &vmdirq->irq->irq_list); | 128 | list_add_tail_rcu(&vmdirq->node, &vmdirq->irq->irq_list); |
129 | vmdirq->enabled = true; | ||
126 | raw_spin_unlock_irqrestore(&list_lock, flags); | 130 | raw_spin_unlock_irqrestore(&list_lock, flags); |
127 | 131 | ||
128 | data->chip->irq_unmask(data); | 132 | data->chip->irq_unmask(data); |
@@ -136,8 +140,10 @@ static void vmd_irq_disable(struct irq_data *data) | |||
136 | data->chip->irq_mask(data); | 140 | data->chip->irq_mask(data); |
137 | 141 | ||
138 | raw_spin_lock_irqsave(&list_lock, flags); | 142 | raw_spin_lock_irqsave(&list_lock, flags); |
139 | list_del_rcu(&vmdirq->node); | 143 | if (vmdirq->enabled) { |
140 | INIT_LIST_HEAD_RCU(&vmdirq->node); | 144 | list_del_rcu(&vmdirq->node); |
145 | vmdirq->enabled = false; | ||
146 | } | ||
141 | raw_spin_unlock_irqrestore(&list_lock, flags); | 147 | raw_spin_unlock_irqrestore(&list_lock, flags); |
142 | } | 148 | } |
143 | 149 | ||
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 677e29e29473..8dd3784eb075 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c | |||
@@ -245,7 +245,7 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) | |||
245 | * text and allocate a new stack because we can't rely on the | 245 | * text and allocate a new stack because we can't rely on the |
246 | * stack pointer being < 4GB. | 246 | * stack pointer being < 4GB. |
247 | */ | 247 | */ |
248 | if (!IS_ENABLED(CONFIG_EFI_MIXED)) | 248 | if (!IS_ENABLED(CONFIG_EFI_MIXED) || efi_is_native()) |
249 | return 0; | 249 | return 0; |
250 | 250 | ||
251 | /* | 251 | /* |
diff --git a/arch/x86/um/ptrace_32.c b/arch/x86/um/ptrace_32.c index ebd4dd6ef73b..a7ef7b131e25 100644 --- a/arch/x86/um/ptrace_32.c +++ b/arch/x86/um/ptrace_32.c | |||
@@ -84,7 +84,10 @@ int putreg(struct task_struct *child, int regno, unsigned long value) | |||
84 | case EAX: | 84 | case EAX: |
85 | case EIP: | 85 | case EIP: |
86 | case UESP: | 86 | case UESP: |
87 | break; | ||
87 | case ORIG_EAX: | 88 | case ORIG_EAX: |
89 | /* Update the syscall number. */ | ||
90 | UPT_SYSCALL_NR(&child->thread.regs.regs) = value; | ||
88 | break; | 91 | break; |
89 | case FS: | 92 | case FS: |
90 | if (value && (value & 3) != 3) | 93 | if (value && (value & 3) != 3) |
diff --git a/arch/x86/um/ptrace_64.c b/arch/x86/um/ptrace_64.c index faab418876ce..0b5c184dd5b3 100644 --- a/arch/x86/um/ptrace_64.c +++ b/arch/x86/um/ptrace_64.c | |||
@@ -78,7 +78,11 @@ int putreg(struct task_struct *child, int regno, unsigned long value) | |||
78 | case RSI: | 78 | case RSI: |
79 | case RDI: | 79 | case RDI: |
80 | case RBP: | 80 | case RBP: |
81 | break; | ||
82 | |||
81 | case ORIG_RAX: | 83 | case ORIG_RAX: |
84 | /* Update the syscall number. */ | ||
85 | UPT_SYSCALL_NR(&child->thread.regs.regs) = value; | ||
82 | break; | 86 | break; |
83 | 87 | ||
84 | case FS: | 88 | case FS: |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 8ffb089b19a5..b86ebb1a9a7f 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -118,7 +118,7 @@ DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); | |||
118 | DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info); | 118 | DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info); |
119 | 119 | ||
120 | /* Linux <-> Xen vCPU id mapping */ | 120 | /* Linux <-> Xen vCPU id mapping */ |
121 | DEFINE_PER_CPU(int, xen_vcpu_id) = -1; | 121 | DEFINE_PER_CPU(uint32_t, xen_vcpu_id); |
122 | EXPORT_PER_CPU_SYMBOL(xen_vcpu_id); | 122 | EXPORT_PER_CPU_SYMBOL(xen_vcpu_id); |
123 | 123 | ||
124 | enum xen_domain_type xen_domain_type = XEN_NATIVE; | 124 | enum xen_domain_type xen_domain_type = XEN_NATIVE; |
diff --git a/block/bio.c b/block/bio.c index f39477538fef..aa7354088008 100644 --- a/block/bio.c +++ b/block/bio.c | |||
@@ -667,18 +667,19 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask, | |||
667 | bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector; | 667 | bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector; |
668 | bio->bi_iter.bi_size = bio_src->bi_iter.bi_size; | 668 | bio->bi_iter.bi_size = bio_src->bi_iter.bi_size; |
669 | 669 | ||
670 | if (bio_op(bio) == REQ_OP_DISCARD) | 670 | switch (bio_op(bio)) { |
671 | goto integrity_clone; | 671 | case REQ_OP_DISCARD: |
672 | 672 | case REQ_OP_SECURE_ERASE: | |
673 | if (bio_op(bio) == REQ_OP_WRITE_SAME) { | 673 | break; |
674 | case REQ_OP_WRITE_SAME: | ||
674 | bio->bi_io_vec[bio->bi_vcnt++] = bio_src->bi_io_vec[0]; | 675 | bio->bi_io_vec[bio->bi_vcnt++] = bio_src->bi_io_vec[0]; |
675 | goto integrity_clone; | 676 | break; |
677 | default: | ||
678 | bio_for_each_segment(bv, bio_src, iter) | ||
679 | bio->bi_io_vec[bio->bi_vcnt++] = bv; | ||
680 | break; | ||
676 | } | 681 | } |
677 | 682 | ||
678 | bio_for_each_segment(bv, bio_src, iter) | ||
679 | bio->bi_io_vec[bio->bi_vcnt++] = bv; | ||
680 | |||
681 | integrity_clone: | ||
682 | if (bio_integrity(bio_src)) { | 683 | if (bio_integrity(bio_src)) { |
683 | int ret; | 684 | int ret; |
684 | 685 | ||
@@ -1788,7 +1789,7 @@ struct bio *bio_split(struct bio *bio, int sectors, | |||
1788 | * Discards need a mutable bio_vec to accommodate the payload | 1789 | * Discards need a mutable bio_vec to accommodate the payload |
1789 | * required by the DSM TRIM and UNMAP commands. | 1790 | * required by the DSM TRIM and UNMAP commands. |
1790 | */ | 1791 | */ |
1791 | if (bio_op(bio) == REQ_OP_DISCARD) | 1792 | if (bio_op(bio) == REQ_OP_DISCARD || bio_op(bio) == REQ_OP_SECURE_ERASE) |
1792 | split = bio_clone_bioset(bio, gfp, bs); | 1793 | split = bio_clone_bioset(bio, gfp, bs); |
1793 | else | 1794 | else |
1794 | split = bio_clone_fast(bio, gfp, bs); | 1795 | split = bio_clone_fast(bio, gfp, bs); |
diff --git a/block/blk-core.c b/block/blk-core.c index 999442ec4601..36c7ac328d8c 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -515,7 +515,9 @@ EXPORT_SYMBOL_GPL(blk_queue_bypass_end); | |||
515 | 515 | ||
516 | void blk_set_queue_dying(struct request_queue *q) | 516 | void blk_set_queue_dying(struct request_queue *q) |
517 | { | 517 | { |
518 | queue_flag_set_unlocked(QUEUE_FLAG_DYING, q); | 518 | spin_lock_irq(q->queue_lock); |
519 | queue_flag_set(QUEUE_FLAG_DYING, q); | ||
520 | spin_unlock_irq(q->queue_lock); | ||
519 | 521 | ||
520 | if (q->mq_ops) | 522 | if (q->mq_ops) |
521 | blk_mq_wake_waiters(q); | 523 | blk_mq_wake_waiters(q); |
diff --git a/block/blk-merge.c b/block/blk-merge.c index 3eec75a9e91d..2642e5fc8b69 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
@@ -94,9 +94,31 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, | |||
94 | bool do_split = true; | 94 | bool do_split = true; |
95 | struct bio *new = NULL; | 95 | struct bio *new = NULL; |
96 | const unsigned max_sectors = get_max_io_size(q, bio); | 96 | const unsigned max_sectors = get_max_io_size(q, bio); |
97 | unsigned bvecs = 0; | ||
97 | 98 | ||
98 | bio_for_each_segment(bv, bio, iter) { | 99 | bio_for_each_segment(bv, bio, iter) { |
99 | /* | 100 | /* |
101 | * With arbitrary bio size, the incoming bio may be very | ||
102 | * big. We have to split the bio into small bios so that | ||
103 | * each holds at most BIO_MAX_PAGES bvecs because | ||
104 | * bio_clone() can fail to allocate big bvecs. | ||
105 | * | ||
106 | * It should have been better to apply the limit per | ||
107 | * request queue in which bio_clone() is involved, | ||
108 | * instead of globally. The biggest blocker is the | ||
109 | * bio_clone() in bio bounce. | ||
110 | * | ||
111 | * If bio is splitted by this reason, we should have | ||
112 | * allowed to continue bios merging, but don't do | ||
113 | * that now for making the change simple. | ||
114 | * | ||
115 | * TODO: deal with bio bounce's bio_clone() gracefully | ||
116 | * and convert the global limit into per-queue limit. | ||
117 | */ | ||
118 | if (bvecs++ >= BIO_MAX_PAGES) | ||
119 | goto split; | ||
120 | |||
121 | /* | ||
100 | * If the queue doesn't support SG gaps and adding this | 122 | * If the queue doesn't support SG gaps and adding this |
101 | * offset would create a gap, disallow it. | 123 | * offset would create a gap, disallow it. |
102 | */ | 124 | */ |
@@ -172,12 +194,18 @@ void blk_queue_split(struct request_queue *q, struct bio **bio, | |||
172 | struct bio *split, *res; | 194 | struct bio *split, *res; |
173 | unsigned nsegs; | 195 | unsigned nsegs; |
174 | 196 | ||
175 | if (bio_op(*bio) == REQ_OP_DISCARD) | 197 | switch (bio_op(*bio)) { |
198 | case REQ_OP_DISCARD: | ||
199 | case REQ_OP_SECURE_ERASE: | ||
176 | split = blk_bio_discard_split(q, *bio, bs, &nsegs); | 200 | split = blk_bio_discard_split(q, *bio, bs, &nsegs); |
177 | else if (bio_op(*bio) == REQ_OP_WRITE_SAME) | 201 | break; |
202 | case REQ_OP_WRITE_SAME: | ||
178 | split = blk_bio_write_same_split(q, *bio, bs, &nsegs); | 203 | split = blk_bio_write_same_split(q, *bio, bs, &nsegs); |
179 | else | 204 | break; |
205 | default: | ||
180 | split = blk_bio_segment_split(q, *bio, q->bio_split, &nsegs); | 206 | split = blk_bio_segment_split(q, *bio, q->bio_split, &nsegs); |
207 | break; | ||
208 | } | ||
181 | 209 | ||
182 | /* physical segments can be figured out during splitting */ | 210 | /* physical segments can be figured out during splitting */ |
183 | res = split ? split : *bio; | 211 | res = split ? split : *bio; |
@@ -213,7 +241,7 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q, | |||
213 | * This should probably be returning 0, but blk_add_request_payload() | 241 | * This should probably be returning 0, but blk_add_request_payload() |
214 | * (Christoph!!!!) | 242 | * (Christoph!!!!) |
215 | */ | 243 | */ |
216 | if (bio_op(bio) == REQ_OP_DISCARD) | 244 | if (bio_op(bio) == REQ_OP_DISCARD || bio_op(bio) == REQ_OP_SECURE_ERASE) |
217 | return 1; | 245 | return 1; |
218 | 246 | ||
219 | if (bio_op(bio) == REQ_OP_WRITE_SAME) | 247 | if (bio_op(bio) == REQ_OP_WRITE_SAME) |
@@ -385,7 +413,9 @@ static int __blk_bios_map_sg(struct request_queue *q, struct bio *bio, | |||
385 | nsegs = 0; | 413 | nsegs = 0; |
386 | cluster = blk_queue_cluster(q); | 414 | cluster = blk_queue_cluster(q); |
387 | 415 | ||
388 | if (bio_op(bio) == REQ_OP_DISCARD) { | 416 | switch (bio_op(bio)) { |
417 | case REQ_OP_DISCARD: | ||
418 | case REQ_OP_SECURE_ERASE: | ||
389 | /* | 419 | /* |
390 | * This is a hack - drivers should be neither modifying the | 420 | * This is a hack - drivers should be neither modifying the |
391 | * biovec, nor relying on bi_vcnt - but because of | 421 | * biovec, nor relying on bi_vcnt - but because of |
@@ -393,19 +423,16 @@ static int __blk_bios_map_sg(struct request_queue *q, struct bio *bio, | |||
393 | * a payload we need to set up here (thank you Christoph) and | 423 | * a payload we need to set up here (thank you Christoph) and |
394 | * bi_vcnt is really the only way of telling if we need to. | 424 | * bi_vcnt is really the only way of telling if we need to. |
395 | */ | 425 | */ |
396 | 426 | if (!bio->bi_vcnt) | |
397 | if (bio->bi_vcnt) | 427 | return 0; |
398 | goto single_segment; | 428 | /* Fall through */ |
399 | 429 | case REQ_OP_WRITE_SAME: | |
400 | return 0; | ||
401 | } | ||
402 | |||
403 | if (bio_op(bio) == REQ_OP_WRITE_SAME) { | ||
404 | single_segment: | ||
405 | *sg = sglist; | 430 | *sg = sglist; |
406 | bvec = bio_iovec(bio); | 431 | bvec = bio_iovec(bio); |
407 | sg_set_page(*sg, bvec.bv_page, bvec.bv_len, bvec.bv_offset); | 432 | sg_set_page(*sg, bvec.bv_page, bvec.bv_len, bvec.bv_offset); |
408 | return 1; | 433 | return 1; |
434 | default: | ||
435 | break; | ||
409 | } | 436 | } |
410 | 437 | ||
411 | for_each_bio(bio) | 438 | for_each_bio(bio) |
diff --git a/block/blk-mq.c b/block/blk-mq.c index e931a0e8e73d..c207fa9870eb 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
@@ -296,17 +296,29 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q, int rw, | |||
296 | if (ret) | 296 | if (ret) |
297 | return ERR_PTR(ret); | 297 | return ERR_PTR(ret); |
298 | 298 | ||
299 | /* | ||
300 | * Check if the hardware context is actually mapped to anything. | ||
301 | * If not tell the caller that it should skip this queue. | ||
302 | */ | ||
299 | hctx = q->queue_hw_ctx[hctx_idx]; | 303 | hctx = q->queue_hw_ctx[hctx_idx]; |
304 | if (!blk_mq_hw_queue_mapped(hctx)) { | ||
305 | ret = -EXDEV; | ||
306 | goto out_queue_exit; | ||
307 | } | ||
300 | ctx = __blk_mq_get_ctx(q, cpumask_first(hctx->cpumask)); | 308 | ctx = __blk_mq_get_ctx(q, cpumask_first(hctx->cpumask)); |
301 | 309 | ||
302 | blk_mq_set_alloc_data(&alloc_data, q, flags, ctx, hctx); | 310 | blk_mq_set_alloc_data(&alloc_data, q, flags, ctx, hctx); |
303 | rq = __blk_mq_alloc_request(&alloc_data, rw, 0); | 311 | rq = __blk_mq_alloc_request(&alloc_data, rw, 0); |
304 | if (!rq) { | 312 | if (!rq) { |
305 | blk_queue_exit(q); | 313 | ret = -EWOULDBLOCK; |
306 | return ERR_PTR(-EWOULDBLOCK); | 314 | goto out_queue_exit; |
307 | } | 315 | } |
308 | 316 | ||
309 | return rq; | 317 | return rq; |
318 | |||
319 | out_queue_exit: | ||
320 | blk_queue_exit(q); | ||
321 | return ERR_PTR(ret); | ||
310 | } | 322 | } |
311 | EXPORT_SYMBOL_GPL(blk_mq_alloc_request_hctx); | 323 | EXPORT_SYMBOL_GPL(blk_mq_alloc_request_hctx); |
312 | 324 | ||
@@ -793,11 +805,12 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx) | |||
793 | struct list_head *dptr; | 805 | struct list_head *dptr; |
794 | int queued; | 806 | int queued; |
795 | 807 | ||
796 | WARN_ON(!cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask)); | ||
797 | |||
798 | if (unlikely(test_bit(BLK_MQ_S_STOPPED, &hctx->state))) | 808 | if (unlikely(test_bit(BLK_MQ_S_STOPPED, &hctx->state))) |
799 | return; | 809 | return; |
800 | 810 | ||
811 | WARN_ON(!cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask) && | ||
812 | cpu_online(hctx->next_cpu)); | ||
813 | |||
801 | hctx->run++; | 814 | hctx->run++; |
802 | 815 | ||
803 | /* | 816 | /* |
@@ -1036,10 +1049,11 @@ void blk_mq_delay_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs) | |||
1036 | EXPORT_SYMBOL(blk_mq_delay_queue); | 1049 | EXPORT_SYMBOL(blk_mq_delay_queue); |
1037 | 1050 | ||
1038 | static inline void __blk_mq_insert_req_list(struct blk_mq_hw_ctx *hctx, | 1051 | static inline void __blk_mq_insert_req_list(struct blk_mq_hw_ctx *hctx, |
1039 | struct blk_mq_ctx *ctx, | ||
1040 | struct request *rq, | 1052 | struct request *rq, |
1041 | bool at_head) | 1053 | bool at_head) |
1042 | { | 1054 | { |
1055 | struct blk_mq_ctx *ctx = rq->mq_ctx; | ||
1056 | |||
1043 | trace_block_rq_insert(hctx->queue, rq); | 1057 | trace_block_rq_insert(hctx->queue, rq); |
1044 | 1058 | ||
1045 | if (at_head) | 1059 | if (at_head) |
@@ -1053,20 +1067,16 @@ static void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx, | |||
1053 | { | 1067 | { |
1054 | struct blk_mq_ctx *ctx = rq->mq_ctx; | 1068 | struct blk_mq_ctx *ctx = rq->mq_ctx; |
1055 | 1069 | ||
1056 | __blk_mq_insert_req_list(hctx, ctx, rq, at_head); | 1070 | __blk_mq_insert_req_list(hctx, rq, at_head); |
1057 | blk_mq_hctx_mark_pending(hctx, ctx); | 1071 | blk_mq_hctx_mark_pending(hctx, ctx); |
1058 | } | 1072 | } |
1059 | 1073 | ||
1060 | void blk_mq_insert_request(struct request *rq, bool at_head, bool run_queue, | 1074 | void blk_mq_insert_request(struct request *rq, bool at_head, bool run_queue, |
1061 | bool async) | 1075 | bool async) |
1062 | { | 1076 | { |
1077 | struct blk_mq_ctx *ctx = rq->mq_ctx; | ||
1063 | struct request_queue *q = rq->q; | 1078 | struct request_queue *q = rq->q; |
1064 | struct blk_mq_hw_ctx *hctx; | 1079 | struct blk_mq_hw_ctx *hctx; |
1065 | struct blk_mq_ctx *ctx = rq->mq_ctx, *current_ctx; | ||
1066 | |||
1067 | current_ctx = blk_mq_get_ctx(q); | ||
1068 | if (!cpu_online(ctx->cpu)) | ||
1069 | rq->mq_ctx = ctx = current_ctx; | ||
1070 | 1080 | ||
1071 | hctx = q->mq_ops->map_queue(q, ctx->cpu); | 1081 | hctx = q->mq_ops->map_queue(q, ctx->cpu); |
1072 | 1082 | ||
@@ -1076,8 +1086,6 @@ void blk_mq_insert_request(struct request *rq, bool at_head, bool run_queue, | |||
1076 | 1086 | ||
1077 | if (run_queue) | 1087 | if (run_queue) |
1078 | blk_mq_run_hw_queue(hctx, async); | 1088 | blk_mq_run_hw_queue(hctx, async); |
1079 | |||
1080 | blk_mq_put_ctx(current_ctx); | ||
1081 | } | 1089 | } |
1082 | 1090 | ||
1083 | static void blk_mq_insert_requests(struct request_queue *q, | 1091 | static void blk_mq_insert_requests(struct request_queue *q, |
@@ -1088,14 +1096,9 @@ static void blk_mq_insert_requests(struct request_queue *q, | |||
1088 | 1096 | ||
1089 | { | 1097 | { |
1090 | struct blk_mq_hw_ctx *hctx; | 1098 | struct blk_mq_hw_ctx *hctx; |
1091 | struct blk_mq_ctx *current_ctx; | ||
1092 | 1099 | ||
1093 | trace_block_unplug(q, depth, !from_schedule); | 1100 | trace_block_unplug(q, depth, !from_schedule); |
1094 | 1101 | ||
1095 | current_ctx = blk_mq_get_ctx(q); | ||
1096 | |||
1097 | if (!cpu_online(ctx->cpu)) | ||
1098 | ctx = current_ctx; | ||
1099 | hctx = q->mq_ops->map_queue(q, ctx->cpu); | 1102 | hctx = q->mq_ops->map_queue(q, ctx->cpu); |
1100 | 1103 | ||
1101 | /* | 1104 | /* |
@@ -1107,15 +1110,14 @@ static void blk_mq_insert_requests(struct request_queue *q, | |||
1107 | struct request *rq; | 1110 | struct request *rq; |
1108 | 1111 | ||
1109 | rq = list_first_entry(list, struct request, queuelist); | 1112 | rq = list_first_entry(list, struct request, queuelist); |
1113 | BUG_ON(rq->mq_ctx != ctx); | ||
1110 | list_del_init(&rq->queuelist); | 1114 | list_del_init(&rq->queuelist); |
1111 | rq->mq_ctx = ctx; | 1115 | __blk_mq_insert_req_list(hctx, rq, false); |
1112 | __blk_mq_insert_req_list(hctx, ctx, rq, false); | ||
1113 | } | 1116 | } |
1114 | blk_mq_hctx_mark_pending(hctx, ctx); | 1117 | blk_mq_hctx_mark_pending(hctx, ctx); |
1115 | spin_unlock(&ctx->lock); | 1118 | spin_unlock(&ctx->lock); |
1116 | 1119 | ||
1117 | blk_mq_run_hw_queue(hctx, from_schedule); | 1120 | blk_mq_run_hw_queue(hctx, from_schedule); |
1118 | blk_mq_put_ctx(current_ctx); | ||
1119 | } | 1121 | } |
1120 | 1122 | ||
1121 | static int plug_ctx_cmp(void *priv, struct list_head *a, struct list_head *b) | 1123 | static int plug_ctx_cmp(void *priv, struct list_head *a, struct list_head *b) |
@@ -1630,16 +1632,17 @@ static int blk_mq_alloc_bitmap(struct blk_mq_ctxmap *bitmap, int node) | |||
1630 | return 0; | 1632 | return 0; |
1631 | } | 1633 | } |
1632 | 1634 | ||
1635 | /* | ||
1636 | * 'cpu' is going away. splice any existing rq_list entries from this | ||
1637 | * software queue to the hw queue dispatch list, and ensure that it | ||
1638 | * gets run. | ||
1639 | */ | ||
1633 | static int blk_mq_hctx_cpu_offline(struct blk_mq_hw_ctx *hctx, int cpu) | 1640 | static int blk_mq_hctx_cpu_offline(struct blk_mq_hw_ctx *hctx, int cpu) |
1634 | { | 1641 | { |
1635 | struct request_queue *q = hctx->queue; | ||
1636 | struct blk_mq_ctx *ctx; | 1642 | struct blk_mq_ctx *ctx; |
1637 | LIST_HEAD(tmp); | 1643 | LIST_HEAD(tmp); |
1638 | 1644 | ||
1639 | /* | 1645 | ctx = __blk_mq_get_ctx(hctx->queue, cpu); |
1640 | * Move ctx entries to new CPU, if this one is going away. | ||
1641 | */ | ||
1642 | ctx = __blk_mq_get_ctx(q, cpu); | ||
1643 | 1646 | ||
1644 | spin_lock(&ctx->lock); | 1647 | spin_lock(&ctx->lock); |
1645 | if (!list_empty(&ctx->rq_list)) { | 1648 | if (!list_empty(&ctx->rq_list)) { |
@@ -1651,24 +1654,11 @@ static int blk_mq_hctx_cpu_offline(struct blk_mq_hw_ctx *hctx, int cpu) | |||
1651 | if (list_empty(&tmp)) | 1654 | if (list_empty(&tmp)) |
1652 | return NOTIFY_OK; | 1655 | return NOTIFY_OK; |
1653 | 1656 | ||
1654 | ctx = blk_mq_get_ctx(q); | 1657 | spin_lock(&hctx->lock); |
1655 | spin_lock(&ctx->lock); | 1658 | list_splice_tail_init(&tmp, &hctx->dispatch); |
1656 | 1659 | spin_unlock(&hctx->lock); | |
1657 | while (!list_empty(&tmp)) { | ||
1658 | struct request *rq; | ||
1659 | |||
1660 | rq = list_first_entry(&tmp, struct request, queuelist); | ||
1661 | rq->mq_ctx = ctx; | ||
1662 | list_move_tail(&rq->queuelist, &ctx->rq_list); | ||
1663 | } | ||
1664 | |||
1665 | hctx = q->mq_ops->map_queue(q, ctx->cpu); | ||
1666 | blk_mq_hctx_mark_pending(hctx, ctx); | ||
1667 | |||
1668 | spin_unlock(&ctx->lock); | ||
1669 | 1660 | ||
1670 | blk_mq_run_hw_queue(hctx, true); | 1661 | blk_mq_run_hw_queue(hctx, true); |
1671 | blk_mq_put_ctx(ctx); | ||
1672 | return NOTIFY_OK; | 1662 | return NOTIFY_OK; |
1673 | } | 1663 | } |
1674 | 1664 | ||
diff --git a/block/blk-throttle.c b/block/blk-throttle.c index f1aba26f4719..a3ea8260c94c 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c | |||
@@ -780,9 +780,11 @@ static bool tg_may_dispatch(struct throtl_grp *tg, struct bio *bio, | |||
780 | /* | 780 | /* |
781 | * If previous slice expired, start a new one otherwise renew/extend | 781 | * If previous slice expired, start a new one otherwise renew/extend |
782 | * existing slice to make sure it is at least throtl_slice interval | 782 | * existing slice to make sure it is at least throtl_slice interval |
783 | * long since now. | 783 | * long since now. New slice is started only for empty throttle group. |
784 | * If there is queued bio, that means there should be an active | ||
785 | * slice and it should be extended instead. | ||
784 | */ | 786 | */ |
785 | if (throtl_slice_used(tg, rw)) | 787 | if (throtl_slice_used(tg, rw) && !(tg->service_queue.nr_queued[rw])) |
786 | throtl_start_new_slice(tg, rw); | 788 | throtl_start_new_slice(tg, rw); |
787 | else { | 789 | else { |
788 | if (time_before(tg->slice_end[rw], jiffies + throtl_slice)) | 790 | if (time_before(tg->slice_end[rw], jiffies + throtl_slice)) |
diff --git a/block/elevator.c b/block/elevator.c index 7096c22041e7..f7d973a56fd7 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
@@ -366,7 +366,7 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq) | |||
366 | list_for_each_prev(entry, &q->queue_head) { | 366 | list_for_each_prev(entry, &q->queue_head) { |
367 | struct request *pos = list_entry_rq(entry); | 367 | struct request *pos = list_entry_rq(entry); |
368 | 368 | ||
369 | if ((req_op(rq) == REQ_OP_DISCARD) != (req_op(pos) == REQ_OP_DISCARD)) | 369 | if (req_op(rq) != req_op(pos)) |
370 | break; | 370 | break; |
371 | if (rq_data_dir(rq) != rq_data_dir(pos)) | 371 | if (rq_data_dir(rq) != rq_data_dir(pos)) |
372 | break; | 372 | break; |
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c index 369999530108..a832426820e8 100644 --- a/crypto/blkcipher.c +++ b/crypto/blkcipher.c | |||
@@ -233,6 +233,8 @@ static int blkcipher_walk_next(struct blkcipher_desc *desc, | |||
233 | return blkcipher_walk_done(desc, walk, -EINVAL); | 233 | return blkcipher_walk_done(desc, walk, -EINVAL); |
234 | } | 234 | } |
235 | 235 | ||
236 | bsize = min(walk->walk_blocksize, n); | ||
237 | |||
236 | walk->flags &= ~(BLKCIPHER_WALK_SLOW | BLKCIPHER_WALK_COPY | | 238 | walk->flags &= ~(BLKCIPHER_WALK_SLOW | BLKCIPHER_WALK_COPY | |
237 | BLKCIPHER_WALK_DIFF); | 239 | BLKCIPHER_WALK_DIFF); |
238 | if (!scatterwalk_aligned(&walk->in, walk->alignmask) || | 240 | if (!scatterwalk_aligned(&walk->in, walk->alignmask) || |
@@ -245,7 +247,6 @@ static int blkcipher_walk_next(struct blkcipher_desc *desc, | |||
245 | } | 247 | } |
246 | } | 248 | } |
247 | 249 | ||
248 | bsize = min(walk->walk_blocksize, n); | ||
249 | n = scatterwalk_clamp(&walk->in, n); | 250 | n = scatterwalk_clamp(&walk->in, n); |
250 | n = scatterwalk_clamp(&walk->out, n); | 251 | n = scatterwalk_clamp(&walk->out, n); |
251 | 252 | ||
diff --git a/crypto/cryptd.c b/crypto/cryptd.c index cf8037a87b2d..0c654e59f215 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c | |||
@@ -631,9 +631,14 @@ static int cryptd_hash_export(struct ahash_request *req, void *out) | |||
631 | 631 | ||
632 | static int cryptd_hash_import(struct ahash_request *req, const void *in) | 632 | static int cryptd_hash_import(struct ahash_request *req, const void *in) |
633 | { | 633 | { |
634 | struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req); | 634 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
635 | struct cryptd_hash_ctx *ctx = crypto_ahash_ctx(tfm); | ||
636 | struct shash_desc *desc = cryptd_shash_desc(req); | ||
637 | |||
638 | desc->tfm = ctx->child; | ||
639 | desc->flags = req->base.flags; | ||
635 | 640 | ||
636 | return crypto_shash_import(&rctx->desc, in); | 641 | return crypto_shash_import(desc, in); |
637 | } | 642 | } |
638 | 643 | ||
639 | static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb, | 644 | static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb, |
@@ -733,13 +738,14 @@ static void cryptd_aead_crypt(struct aead_request *req, | |||
733 | rctx = aead_request_ctx(req); | 738 | rctx = aead_request_ctx(req); |
734 | compl = rctx->complete; | 739 | compl = rctx->complete; |
735 | 740 | ||
741 | tfm = crypto_aead_reqtfm(req); | ||
742 | |||
736 | if (unlikely(err == -EINPROGRESS)) | 743 | if (unlikely(err == -EINPROGRESS)) |
737 | goto out; | 744 | goto out; |
738 | aead_request_set_tfm(req, child); | 745 | aead_request_set_tfm(req, child); |
739 | err = crypt( req ); | 746 | err = crypt( req ); |
740 | 747 | ||
741 | out: | 748 | out: |
742 | tfm = crypto_aead_reqtfm(req); | ||
743 | ctx = crypto_aead_ctx(tfm); | 749 | ctx = crypto_aead_ctx(tfm); |
744 | refcnt = atomic_read(&ctx->refcnt); | 750 | refcnt = atomic_read(&ctx->refcnt); |
745 | 751 | ||
diff --git a/crypto/echainiv.c b/crypto/echainiv.c index 1b01fe98e91f..e3d889b122e0 100644 --- a/crypto/echainiv.c +++ b/crypto/echainiv.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * echainiv: Encrypted Chain IV Generator | 2 | * echainiv: Encrypted Chain IV Generator |
3 | * | 3 | * |
4 | * This generator generates an IV based on a sequence number by xoring it | 4 | * This generator generates an IV based on a sequence number by multiplying |
5 | * with a salt and then encrypting it with the same key as used to encrypt | 5 | * it with a salt and then encrypting it with the same key as used to encrypt |
6 | * the plain text. This algorithm requires that the block size be equal | 6 | * the plain text. This algorithm requires that the block size be equal |
7 | * to the IV size. It is mainly useful for CBC. | 7 | * to the IV size. It is mainly useful for CBC. |
8 | * | 8 | * |
@@ -24,81 +24,17 @@ | |||
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/mm.h> | ||
28 | #include <linux/module.h> | 27 | #include <linux/module.h> |
29 | #include <linux/percpu.h> | 28 | #include <linux/slab.h> |
30 | #include <linux/spinlock.h> | ||
31 | #include <linux/string.h> | 29 | #include <linux/string.h> |
32 | 30 | ||
33 | #define MAX_IV_SIZE 16 | ||
34 | |||
35 | static DEFINE_PER_CPU(u32 [MAX_IV_SIZE / sizeof(u32)], echainiv_iv); | ||
36 | |||
37 | /* We don't care if we get preempted and read/write IVs from the next CPU. */ | ||
38 | static void echainiv_read_iv(u8 *dst, unsigned size) | ||
39 | { | ||
40 | u32 *a = (u32 *)dst; | ||
41 | u32 __percpu *b = echainiv_iv; | ||
42 | |||
43 | for (; size >= 4; size -= 4) { | ||
44 | *a++ = this_cpu_read(*b); | ||
45 | b++; | ||
46 | } | ||
47 | } | ||
48 | |||
49 | static void echainiv_write_iv(const u8 *src, unsigned size) | ||
50 | { | ||
51 | const u32 *a = (const u32 *)src; | ||
52 | u32 __percpu *b = echainiv_iv; | ||
53 | |||
54 | for (; size >= 4; size -= 4) { | ||
55 | this_cpu_write(*b, *a); | ||
56 | a++; | ||
57 | b++; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | static void echainiv_encrypt_complete2(struct aead_request *req, int err) | ||
62 | { | ||
63 | struct aead_request *subreq = aead_request_ctx(req); | ||
64 | struct crypto_aead *geniv; | ||
65 | unsigned int ivsize; | ||
66 | |||
67 | if (err == -EINPROGRESS) | ||
68 | return; | ||
69 | |||
70 | if (err) | ||
71 | goto out; | ||
72 | |||
73 | geniv = crypto_aead_reqtfm(req); | ||
74 | ivsize = crypto_aead_ivsize(geniv); | ||
75 | |||
76 | echainiv_write_iv(subreq->iv, ivsize); | ||
77 | |||
78 | if (req->iv != subreq->iv) | ||
79 | memcpy(req->iv, subreq->iv, ivsize); | ||
80 | |||
81 | out: | ||
82 | if (req->iv != subreq->iv) | ||
83 | kzfree(subreq->iv); | ||
84 | } | ||
85 | |||
86 | static void echainiv_encrypt_complete(struct crypto_async_request *base, | ||
87 | int err) | ||
88 | { | ||
89 | struct aead_request *req = base->data; | ||
90 | |||
91 | echainiv_encrypt_complete2(req, err); | ||
92 | aead_request_complete(req, err); | ||
93 | } | ||
94 | |||
95 | static int echainiv_encrypt(struct aead_request *req) | 31 | static int echainiv_encrypt(struct aead_request *req) |
96 | { | 32 | { |
97 | struct crypto_aead *geniv = crypto_aead_reqtfm(req); | 33 | struct crypto_aead *geniv = crypto_aead_reqtfm(req); |
98 | struct aead_geniv_ctx *ctx = crypto_aead_ctx(geniv); | 34 | struct aead_geniv_ctx *ctx = crypto_aead_ctx(geniv); |
99 | struct aead_request *subreq = aead_request_ctx(req); | 35 | struct aead_request *subreq = aead_request_ctx(req); |
100 | crypto_completion_t compl; | 36 | __be64 nseqno; |
101 | void *data; | 37 | u64 seqno; |
102 | u8 *info; | 38 | u8 *info; |
103 | unsigned int ivsize = crypto_aead_ivsize(geniv); | 39 | unsigned int ivsize = crypto_aead_ivsize(geniv); |
104 | int err; | 40 | int err; |
@@ -108,8 +44,6 @@ static int echainiv_encrypt(struct aead_request *req) | |||
108 | 44 | ||
109 | aead_request_set_tfm(subreq, ctx->child); | 45 | aead_request_set_tfm(subreq, ctx->child); |
110 | 46 | ||
111 | compl = echainiv_encrypt_complete; | ||
112 | data = req; | ||
113 | info = req->iv; | 47 | info = req->iv; |
114 | 48 | ||
115 | if (req->src != req->dst) { | 49 | if (req->src != req->dst) { |
@@ -127,29 +61,30 @@ static int echainiv_encrypt(struct aead_request *req) | |||
127 | return err; | 61 | return err; |
128 | } | 62 | } |
129 | 63 | ||
130 | if (unlikely(!IS_ALIGNED((unsigned long)info, | 64 | aead_request_set_callback(subreq, req->base.flags, |
131 | crypto_aead_alignmask(geniv) + 1))) { | 65 | req->base.complete, req->base.data); |
132 | info = kmalloc(ivsize, req->base.flags & | ||
133 | CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL: | ||
134 | GFP_ATOMIC); | ||
135 | if (!info) | ||
136 | return -ENOMEM; | ||
137 | |||
138 | memcpy(info, req->iv, ivsize); | ||
139 | } | ||
140 | |||
141 | aead_request_set_callback(subreq, req->base.flags, compl, data); | ||
142 | aead_request_set_crypt(subreq, req->dst, req->dst, | 66 | aead_request_set_crypt(subreq, req->dst, req->dst, |
143 | req->cryptlen, info); | 67 | req->cryptlen, info); |
144 | aead_request_set_ad(subreq, req->assoclen); | 68 | aead_request_set_ad(subreq, req->assoclen); |
145 | 69 | ||
146 | crypto_xor(info, ctx->salt, ivsize); | 70 | memcpy(&nseqno, info + ivsize - 8, 8); |
71 | seqno = be64_to_cpu(nseqno); | ||
72 | memset(info, 0, ivsize); | ||
73 | |||
147 | scatterwalk_map_and_copy(info, req->dst, req->assoclen, ivsize, 1); | 74 | scatterwalk_map_and_copy(info, req->dst, req->assoclen, ivsize, 1); |
148 | echainiv_read_iv(info, ivsize); | ||
149 | 75 | ||
150 | err = crypto_aead_encrypt(subreq); | 76 | do { |
151 | echainiv_encrypt_complete2(req, err); | 77 | u64 a; |
152 | return err; | 78 | |
79 | memcpy(&a, ctx->salt + ivsize - 8, 8); | ||
80 | |||
81 | a |= 1; | ||
82 | a *= seqno; | ||
83 | |||
84 | memcpy(info + ivsize - 8, &a, 8); | ||
85 | } while ((ivsize -= 8)); | ||
86 | |||
87 | return crypto_aead_encrypt(subreq); | ||
153 | } | 88 | } |
154 | 89 | ||
155 | static int echainiv_decrypt(struct aead_request *req) | 90 | static int echainiv_decrypt(struct aead_request *req) |
@@ -196,8 +131,7 @@ static int echainiv_aead_create(struct crypto_template *tmpl, | |||
196 | alg = crypto_spawn_aead_alg(spawn); | 131 | alg = crypto_spawn_aead_alg(spawn); |
197 | 132 | ||
198 | err = -EINVAL; | 133 | err = -EINVAL; |
199 | if (inst->alg.ivsize & (sizeof(u32) - 1) || | 134 | if (inst->alg.ivsize & (sizeof(u64) - 1) || !inst->alg.ivsize) |
200 | inst->alg.ivsize > MAX_IV_SIZE) | ||
201 | goto free_inst; | 135 | goto free_inst; |
202 | 136 | ||
203 | inst->alg.encrypt = echainiv_encrypt; | 137 | inst->alg.encrypt = echainiv_encrypt; |
@@ -206,7 +140,6 @@ static int echainiv_aead_create(struct crypto_template *tmpl, | |||
206 | inst->alg.init = aead_init_geniv; | 140 | inst->alg.init = aead_init_geniv; |
207 | inst->alg.exit = aead_exit_geniv; | 141 | inst->alg.exit = aead_exit_geniv; |
208 | 142 | ||
209 | inst->alg.base.cra_alignmask |= __alignof__(u32) - 1; | ||
210 | inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx); | 143 | inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx); |
211 | inst->alg.base.cra_ctxsize += inst->alg.ivsize; | 144 | inst->alg.base.cra_ctxsize += inst->alg.ivsize; |
212 | 145 | ||
diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c index 877019a6d3ea..8baab4307f7b 100644 --- a/crypto/rsa-pkcs1pad.c +++ b/crypto/rsa-pkcs1pad.c | |||
@@ -298,41 +298,48 @@ static int pkcs1pad_decrypt_complete(struct akcipher_request *req, int err) | |||
298 | struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); | 298 | struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); |
299 | struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); | 299 | struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); |
300 | struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); | 300 | struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); |
301 | unsigned int dst_len; | ||
301 | unsigned int pos; | 302 | unsigned int pos; |
302 | 303 | u8 *out_buf; | |
303 | if (err == -EOVERFLOW) | ||
304 | /* Decrypted value had no leading 0 byte */ | ||
305 | err = -EINVAL; | ||
306 | 304 | ||
307 | if (err) | 305 | if (err) |
308 | goto done; | 306 | goto done; |
309 | 307 | ||
310 | if (req_ctx->child_req.dst_len != ctx->key_size - 1) { | 308 | err = -EINVAL; |
311 | err = -EINVAL; | 309 | dst_len = req_ctx->child_req.dst_len; |
310 | if (dst_len < ctx->key_size - 1) | ||
312 | goto done; | 311 | goto done; |
312 | |||
313 | out_buf = req_ctx->out_buf; | ||
314 | if (dst_len == ctx->key_size) { | ||
315 | if (out_buf[0] != 0x00) | ||
316 | /* Decrypted value had no leading 0 byte */ | ||
317 | goto done; | ||
318 | |||
319 | dst_len--; | ||
320 | out_buf++; | ||
313 | } | 321 | } |
314 | 322 | ||
315 | if (req_ctx->out_buf[0] != 0x02) { | 323 | if (out_buf[0] != 0x02) |
316 | err = -EINVAL; | ||
317 | goto done; | 324 | goto done; |
318 | } | 325 | |
319 | for (pos = 1; pos < req_ctx->child_req.dst_len; pos++) | 326 | for (pos = 1; pos < dst_len; pos++) |
320 | if (req_ctx->out_buf[pos] == 0x00) | 327 | if (out_buf[pos] == 0x00) |
321 | break; | 328 | break; |
322 | if (pos < 9 || pos == req_ctx->child_req.dst_len) { | 329 | if (pos < 9 || pos == dst_len) |
323 | err = -EINVAL; | ||
324 | goto done; | 330 | goto done; |
325 | } | ||
326 | pos++; | 331 | pos++; |
327 | 332 | ||
328 | if (req->dst_len < req_ctx->child_req.dst_len - pos) | 333 | err = 0; |
334 | |||
335 | if (req->dst_len < dst_len - pos) | ||
329 | err = -EOVERFLOW; | 336 | err = -EOVERFLOW; |
330 | req->dst_len = req_ctx->child_req.dst_len - pos; | 337 | req->dst_len = dst_len - pos; |
331 | 338 | ||
332 | if (!err) | 339 | if (!err) |
333 | sg_copy_from_buffer(req->dst, | 340 | sg_copy_from_buffer(req->dst, |
334 | sg_nents_for_len(req->dst, req->dst_len), | 341 | sg_nents_for_len(req->dst, req->dst_len), |
335 | req_ctx->out_buf + pos, req->dst_len); | 342 | out_buf + pos, req->dst_len); |
336 | 343 | ||
337 | done: | 344 | done: |
338 | kzfree(req_ctx->out_buf); | 345 | kzfree(req_ctx->out_buf); |
diff --git a/drivers/acpi/nfit/mce.c b/drivers/acpi/nfit/mce.c index 4c745bf389fe..161f91539ae6 100644 --- a/drivers/acpi/nfit/mce.c +++ b/drivers/acpi/nfit/mce.c | |||
@@ -42,7 +42,7 @@ static int nfit_handle_mce(struct notifier_block *nb, unsigned long val, | |||
42 | list_for_each_entry(nfit_spa, &acpi_desc->spas, list) { | 42 | list_for_each_entry(nfit_spa, &acpi_desc->spas, list) { |
43 | struct acpi_nfit_system_address *spa = nfit_spa->spa; | 43 | struct acpi_nfit_system_address *spa = nfit_spa->spa; |
44 | 44 | ||
45 | if (nfit_spa_type(spa) == NFIT_SPA_PM) | 45 | if (nfit_spa_type(spa) != NFIT_SPA_PM) |
46 | continue; | 46 | continue; |
47 | /* find the spa that covers the mce addr */ | 47 | /* find the spa that covers the mce addr */ |
48 | if (spa->address > mce->addr) | 48 | if (spa->address > mce->addr) |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index ad9fc84a8601..e878fc799af7 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -2054,7 +2054,7 @@ int __init acpi_scan_init(void) | |||
2054 | 2054 | ||
2055 | static struct acpi_probe_entry *ape; | 2055 | static struct acpi_probe_entry *ape; |
2056 | static int acpi_probe_count; | 2056 | static int acpi_probe_count; |
2057 | static DEFINE_SPINLOCK(acpi_probe_lock); | 2057 | static DEFINE_MUTEX(acpi_probe_mutex); |
2058 | 2058 | ||
2059 | static int __init acpi_match_madt(struct acpi_subtable_header *header, | 2059 | static int __init acpi_match_madt(struct acpi_subtable_header *header, |
2060 | const unsigned long end) | 2060 | const unsigned long end) |
@@ -2073,7 +2073,7 @@ int __init __acpi_probe_device_table(struct acpi_probe_entry *ap_head, int nr) | |||
2073 | if (acpi_disabled) | 2073 | if (acpi_disabled) |
2074 | return 0; | 2074 | return 0; |
2075 | 2075 | ||
2076 | spin_lock(&acpi_probe_lock); | 2076 | mutex_lock(&acpi_probe_mutex); |
2077 | for (ape = ap_head; nr; ape++, nr--) { | 2077 | for (ape = ap_head; nr; ape++, nr--) { |
2078 | if (ACPI_COMPARE_NAME(ACPI_SIG_MADT, ape->id)) { | 2078 | if (ACPI_COMPARE_NAME(ACPI_SIG_MADT, ape->id)) { |
2079 | acpi_probe_count = 0; | 2079 | acpi_probe_count = 0; |
@@ -2086,7 +2086,7 @@ int __init __acpi_probe_device_table(struct acpi_probe_entry *ap_head, int nr) | |||
2086 | count++; | 2086 | count++; |
2087 | } | 2087 | } |
2088 | } | 2088 | } |
2089 | spin_unlock(&acpi_probe_lock); | 2089 | mutex_unlock(&acpi_probe_mutex); |
2090 | 2090 | ||
2091 | return count; | 2091 | return count; |
2092 | } | 2092 | } |
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 7461a587b39b..dcf2c724fd06 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -2524,7 +2524,7 @@ static int ahci_host_activate_multi_irqs(struct ata_host *host, | |||
2524 | 2524 | ||
2525 | /* Do not receive interrupts sent by dummy ports */ | 2525 | /* Do not receive interrupts sent by dummy ports */ |
2526 | if (!pp) { | 2526 | if (!pp) { |
2527 | disable_irq(irq + i); | 2527 | disable_irq(irq); |
2528 | continue; | 2528 | continue; |
2529 | } | 2529 | } |
2530 | 2530 | ||
diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c index 633aa2934a18..44f97ad3c88d 100644 --- a/drivers/ata/pata_ninja32.c +++ b/drivers/ata/pata_ninja32.c | |||
@@ -144,7 +144,7 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
144 | ap->ioaddr.altstatus_addr = base + 0x1E; | 144 | ap->ioaddr.altstatus_addr = base + 0x1E; |
145 | ap->ioaddr.bmdma_addr = base; | 145 | ap->ioaddr.bmdma_addr = base; |
146 | ata_sff_std_ports(&ap->ioaddr); | 146 | ata_sff_std_ports(&ap->ioaddr); |
147 | ap->pflags = ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE; | 147 | ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE; |
148 | 148 | ||
149 | ninja32_program(base); | 149 | ninja32_program(base); |
150 | /* FIXME: Should we disable them at remove ? */ | 150 | /* FIXME: Should we disable them at remove ? */ |
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index e097d355cc04..82a081ea4317 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -301,7 +301,7 @@ static int rpm_idle(struct device *dev, int rpmflags) | |||
301 | int (*callback)(struct device *); | 301 | int (*callback)(struct device *); |
302 | int retval; | 302 | int retval; |
303 | 303 | ||
304 | trace_rpm_idle(dev, rpmflags); | 304 | trace_rpm_idle_rcuidle(dev, rpmflags); |
305 | retval = rpm_check_suspend_allowed(dev); | 305 | retval = rpm_check_suspend_allowed(dev); |
306 | if (retval < 0) | 306 | if (retval < 0) |
307 | ; /* Conditions are wrong. */ | 307 | ; /* Conditions are wrong. */ |
@@ -337,7 +337,7 @@ static int rpm_idle(struct device *dev, int rpmflags) | |||
337 | dev->power.request_pending = true; | 337 | dev->power.request_pending = true; |
338 | queue_work(pm_wq, &dev->power.work); | 338 | queue_work(pm_wq, &dev->power.work); |
339 | } | 339 | } |
340 | trace_rpm_return_int(dev, _THIS_IP_, 0); | 340 | trace_rpm_return_int_rcuidle(dev, _THIS_IP_, 0); |
341 | return 0; | 341 | return 0; |
342 | } | 342 | } |
343 | 343 | ||
@@ -352,7 +352,7 @@ static int rpm_idle(struct device *dev, int rpmflags) | |||
352 | wake_up_all(&dev->power.wait_queue); | 352 | wake_up_all(&dev->power.wait_queue); |
353 | 353 | ||
354 | out: | 354 | out: |
355 | trace_rpm_return_int(dev, _THIS_IP_, retval); | 355 | trace_rpm_return_int_rcuidle(dev, _THIS_IP_, retval); |
356 | return retval ? retval : rpm_suspend(dev, rpmflags | RPM_AUTO); | 356 | return retval ? retval : rpm_suspend(dev, rpmflags | RPM_AUTO); |
357 | } | 357 | } |
358 | 358 | ||
@@ -419,7 +419,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
419 | struct device *parent = NULL; | 419 | struct device *parent = NULL; |
420 | int retval; | 420 | int retval; |
421 | 421 | ||
422 | trace_rpm_suspend(dev, rpmflags); | 422 | trace_rpm_suspend_rcuidle(dev, rpmflags); |
423 | 423 | ||
424 | repeat: | 424 | repeat: |
425 | retval = rpm_check_suspend_allowed(dev); | 425 | retval = rpm_check_suspend_allowed(dev); |
@@ -549,7 +549,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
549 | } | 549 | } |
550 | 550 | ||
551 | out: | 551 | out: |
552 | trace_rpm_return_int(dev, _THIS_IP_, retval); | 552 | trace_rpm_return_int_rcuidle(dev, _THIS_IP_, retval); |
553 | 553 | ||
554 | return retval; | 554 | return retval; |
555 | 555 | ||
@@ -601,7 +601,7 @@ static int rpm_resume(struct device *dev, int rpmflags) | |||
601 | struct device *parent = NULL; | 601 | struct device *parent = NULL; |
602 | int retval = 0; | 602 | int retval = 0; |
603 | 603 | ||
604 | trace_rpm_resume(dev, rpmflags); | 604 | trace_rpm_resume_rcuidle(dev, rpmflags); |
605 | 605 | ||
606 | repeat: | 606 | repeat: |
607 | if (dev->power.runtime_error) | 607 | if (dev->power.runtime_error) |
@@ -764,7 +764,7 @@ static int rpm_resume(struct device *dev, int rpmflags) | |||
764 | spin_lock_irq(&dev->power.lock); | 764 | spin_lock_irq(&dev->power.lock); |
765 | } | 765 | } |
766 | 766 | ||
767 | trace_rpm_return_int(dev, _THIS_IP_, retval); | 767 | trace_rpm_return_int_rcuidle(dev, _THIS_IP_, retval); |
768 | 768 | ||
769 | return retval; | 769 | return retval; |
770 | } | 770 | } |
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index aa56af87d941..b11af3f2c1db 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c | |||
@@ -404,6 +404,7 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, | |||
404 | unsigned int new_base_reg, new_top_reg; | 404 | unsigned int new_base_reg, new_top_reg; |
405 | unsigned int min, max; | 405 | unsigned int min, max; |
406 | unsigned int max_dist; | 406 | unsigned int max_dist; |
407 | unsigned int dist, best_dist = UINT_MAX; | ||
407 | 408 | ||
408 | max_dist = map->reg_stride * sizeof(*rbnode_tmp) / | 409 | max_dist = map->reg_stride * sizeof(*rbnode_tmp) / |
409 | map->cache_word_size; | 410 | map->cache_word_size; |
@@ -423,24 +424,41 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, | |||
423 | &base_reg, &top_reg); | 424 | &base_reg, &top_reg); |
424 | 425 | ||
425 | if (base_reg <= max && top_reg >= min) { | 426 | if (base_reg <= max && top_reg >= min) { |
426 | new_base_reg = min(reg, base_reg); | 427 | if (reg < base_reg) |
427 | new_top_reg = max(reg, top_reg); | 428 | dist = base_reg - reg; |
428 | } else { | 429 | else if (reg > top_reg) |
429 | if (max < base_reg) | 430 | dist = reg - top_reg; |
430 | node = node->rb_left; | ||
431 | else | 431 | else |
432 | node = node->rb_right; | 432 | dist = 0; |
433 | 433 | if (dist < best_dist) { | |
434 | continue; | 434 | rbnode = rbnode_tmp; |
435 | best_dist = dist; | ||
436 | new_base_reg = min(reg, base_reg); | ||
437 | new_top_reg = max(reg, top_reg); | ||
438 | } | ||
435 | } | 439 | } |
436 | 440 | ||
437 | ret = regcache_rbtree_insert_to_block(map, rbnode_tmp, | 441 | /* |
442 | * Keep looking, we want to choose the closest block, | ||
443 | * otherwise we might end up creating overlapping | ||
444 | * blocks, which breaks the rbtree. | ||
445 | */ | ||
446 | if (reg < base_reg) | ||
447 | node = node->rb_left; | ||
448 | else if (reg > top_reg) | ||
449 | node = node->rb_right; | ||
450 | else | ||
451 | break; | ||
452 | } | ||
453 | |||
454 | if (rbnode) { | ||
455 | ret = regcache_rbtree_insert_to_block(map, rbnode, | ||
438 | new_base_reg, | 456 | new_base_reg, |
439 | new_top_reg, reg, | 457 | new_top_reg, reg, |
440 | value); | 458 | value); |
441 | if (ret) | 459 | if (ret) |
442 | return ret; | 460 | return ret; |
443 | rbtree_ctx->cached_rbnode = rbnode_tmp; | 461 | rbtree_ctx->cached_rbnode = rbnode; |
444 | return 0; | 462 | return 0; |
445 | } | 463 | } |
446 | 464 | ||
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index df7ff7290821..4e582561e1e7 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c | |||
@@ -38,10 +38,11 @@ static int regcache_hw_init(struct regmap *map) | |||
38 | 38 | ||
39 | /* calculate the size of reg_defaults */ | 39 | /* calculate the size of reg_defaults */ |
40 | for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) | 40 | for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) |
41 | if (!regmap_volatile(map, i * map->reg_stride)) | 41 | if (regmap_readable(map, i * map->reg_stride) && |
42 | !regmap_volatile(map, i * map->reg_stride)) | ||
42 | count++; | 43 | count++; |
43 | 44 | ||
44 | /* all registers are volatile, so just bypass */ | 45 | /* all registers are unreadable or volatile, so just bypass */ |
45 | if (!count) { | 46 | if (!count) { |
46 | map->cache_bypass = true; | 47 | map->cache_bypass = true; |
47 | return 0; | 48 | return 0; |
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 51fa7d66a393..e964d068874d 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
@@ -1474,6 +1474,12 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg, | |||
1474 | ret = map->bus->write(map->bus_context, buf, len); | 1474 | ret = map->bus->write(map->bus_context, buf, len); |
1475 | 1475 | ||
1476 | kfree(buf); | 1476 | kfree(buf); |
1477 | } else if (ret != 0 && !map->cache_bypass && map->format.parse_val) { | ||
1478 | /* regcache_drop_region() takes lock that we already have, | ||
1479 | * thus call map->cache_ops->drop() directly | ||
1480 | */ | ||
1481 | if (map->cache_ops && map->cache_ops->drop) | ||
1482 | map->cache_ops->drop(map, reg, reg + 1); | ||
1477 | } | 1483 | } |
1478 | 1484 | ||
1479 | trace_regmap_hw_write_done(map, reg, val_len / map->format.val_bytes); | 1485 | trace_regmap_hw_write_done(map, reg, val_len / map->format.val_bytes); |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index b71a9c767009..e3d8e4ced4a2 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -3706,22 +3706,21 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) | |||
3706 | if (UFDCS->rawcmd == 1) | 3706 | if (UFDCS->rawcmd == 1) |
3707 | UFDCS->rawcmd = 2; | 3707 | UFDCS->rawcmd = 2; |
3708 | 3708 | ||
3709 | if (mode & (FMODE_READ|FMODE_WRITE)) { | 3709 | if (!(mode & FMODE_NDELAY)) { |
3710 | UDRS->last_checked = 0; | 3710 | if (mode & (FMODE_READ|FMODE_WRITE)) { |
3711 | clear_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags); | 3711 | UDRS->last_checked = 0; |
3712 | check_disk_change(bdev); | 3712 | clear_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags); |
3713 | if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags)) | 3713 | check_disk_change(bdev); |
3714 | goto out; | 3714 | if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags)) |
3715 | if (test_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags)) | 3715 | goto out; |
3716 | if (test_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags)) | ||
3717 | goto out; | ||
3718 | } | ||
3719 | res = -EROFS; | ||
3720 | if ((mode & FMODE_WRITE) && | ||
3721 | !test_bit(FD_DISK_WRITABLE_BIT, &UDRS->flags)) | ||
3716 | goto out; | 3722 | goto out; |
3717 | } | 3723 | } |
3718 | |||
3719 | res = -EROFS; | ||
3720 | |||
3721 | if ((mode & FMODE_WRITE) && | ||
3722 | !test_bit(FD_DISK_WRITABLE_BIT, &UDRS->flags)) | ||
3723 | goto out; | ||
3724 | |||
3725 | mutex_unlock(&open_lock); | 3724 | mutex_unlock(&open_lock); |
3726 | mutex_unlock(&floppy_mutex); | 3725 | mutex_unlock(&floppy_mutex); |
3727 | return 0; | 3726 | return 0; |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index be4fea6a5dd3..88ef6d4729b4 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -189,6 +189,8 @@ struct blkfront_info | |||
189 | struct mutex mutex; | 189 | struct mutex mutex; |
190 | struct xenbus_device *xbdev; | 190 | struct xenbus_device *xbdev; |
191 | struct gendisk *gd; | 191 | struct gendisk *gd; |
192 | u16 sector_size; | ||
193 | unsigned int physical_sector_size; | ||
192 | int vdevice; | 194 | int vdevice; |
193 | blkif_vdev_t handle; | 195 | blkif_vdev_t handle; |
194 | enum blkif_state connected; | 196 | enum blkif_state connected; |
@@ -910,9 +912,45 @@ static struct blk_mq_ops blkfront_mq_ops = { | |||
910 | .map_queue = blk_mq_map_queue, | 912 | .map_queue = blk_mq_map_queue, |
911 | }; | 913 | }; |
912 | 914 | ||
915 | static void blkif_set_queue_limits(struct blkfront_info *info) | ||
916 | { | ||
917 | struct request_queue *rq = info->rq; | ||
918 | struct gendisk *gd = info->gd; | ||
919 | unsigned int segments = info->max_indirect_segments ? : | ||
920 | BLKIF_MAX_SEGMENTS_PER_REQUEST; | ||
921 | |||
922 | queue_flag_set_unlocked(QUEUE_FLAG_VIRT, rq); | ||
923 | |||
924 | if (info->feature_discard) { | ||
925 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, rq); | ||
926 | blk_queue_max_discard_sectors(rq, get_capacity(gd)); | ||
927 | rq->limits.discard_granularity = info->discard_granularity; | ||
928 | rq->limits.discard_alignment = info->discard_alignment; | ||
929 | if (info->feature_secdiscard) | ||
930 | queue_flag_set_unlocked(QUEUE_FLAG_SECERASE, rq); | ||
931 | } | ||
932 | |||
933 | /* Hard sector size and max sectors impersonate the equiv. hardware. */ | ||
934 | blk_queue_logical_block_size(rq, info->sector_size); | ||
935 | blk_queue_physical_block_size(rq, info->physical_sector_size); | ||
936 | blk_queue_max_hw_sectors(rq, (segments * XEN_PAGE_SIZE) / 512); | ||
937 | |||
938 | /* Each segment in a request is up to an aligned page in size. */ | ||
939 | blk_queue_segment_boundary(rq, PAGE_SIZE - 1); | ||
940 | blk_queue_max_segment_size(rq, PAGE_SIZE); | ||
941 | |||
942 | /* Ensure a merged request will fit in a single I/O ring slot. */ | ||
943 | blk_queue_max_segments(rq, segments / GRANTS_PER_PSEG); | ||
944 | |||
945 | /* Make sure buffer addresses are sector-aligned. */ | ||
946 | blk_queue_dma_alignment(rq, 511); | ||
947 | |||
948 | /* Make sure we don't use bounce buffers. */ | ||
949 | blk_queue_bounce_limit(rq, BLK_BOUNCE_ANY); | ||
950 | } | ||
951 | |||
913 | static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size, | 952 | static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size, |
914 | unsigned int physical_sector_size, | 953 | unsigned int physical_sector_size) |
915 | unsigned int segments) | ||
916 | { | 954 | { |
917 | struct request_queue *rq; | 955 | struct request_queue *rq; |
918 | struct blkfront_info *info = gd->private_data; | 956 | struct blkfront_info *info = gd->private_data; |
@@ -944,36 +982,11 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size, | |||
944 | } | 982 | } |
945 | 983 | ||
946 | rq->queuedata = info; | 984 | rq->queuedata = info; |
947 | queue_flag_set_unlocked(QUEUE_FLAG_VIRT, rq); | 985 | info->rq = gd->queue = rq; |
948 | 986 | info->gd = gd; | |
949 | if (info->feature_discard) { | 987 | info->sector_size = sector_size; |
950 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, rq); | 988 | info->physical_sector_size = physical_sector_size; |
951 | blk_queue_max_discard_sectors(rq, get_capacity(gd)); | 989 | blkif_set_queue_limits(info); |
952 | rq->limits.discard_granularity = info->discard_granularity; | ||
953 | rq->limits.discard_alignment = info->discard_alignment; | ||
954 | if (info->feature_secdiscard) | ||
955 | queue_flag_set_unlocked(QUEUE_FLAG_SECERASE, rq); | ||
956 | } | ||
957 | |||
958 | /* Hard sector size and max sectors impersonate the equiv. hardware. */ | ||
959 | blk_queue_logical_block_size(rq, sector_size); | ||
960 | blk_queue_physical_block_size(rq, physical_sector_size); | ||
961 | blk_queue_max_hw_sectors(rq, (segments * XEN_PAGE_SIZE) / 512); | ||
962 | |||
963 | /* Each segment in a request is up to an aligned page in size. */ | ||
964 | blk_queue_segment_boundary(rq, PAGE_SIZE - 1); | ||
965 | blk_queue_max_segment_size(rq, PAGE_SIZE); | ||
966 | |||
967 | /* Ensure a merged request will fit in a single I/O ring slot. */ | ||
968 | blk_queue_max_segments(rq, segments / GRANTS_PER_PSEG); | ||
969 | |||
970 | /* Make sure buffer addresses are sector-aligned. */ | ||
971 | blk_queue_dma_alignment(rq, 511); | ||
972 | |||
973 | /* Make sure we don't use bounce buffers. */ | ||
974 | blk_queue_bounce_limit(rq, BLK_BOUNCE_ANY); | ||
975 | |||
976 | gd->queue = rq; | ||
977 | 990 | ||
978 | return 0; | 991 | return 0; |
979 | } | 992 | } |
@@ -1136,16 +1149,11 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, | |||
1136 | gd->private_data = info; | 1149 | gd->private_data = info; |
1137 | set_capacity(gd, capacity); | 1150 | set_capacity(gd, capacity); |
1138 | 1151 | ||
1139 | if (xlvbd_init_blk_queue(gd, sector_size, physical_sector_size, | 1152 | if (xlvbd_init_blk_queue(gd, sector_size, physical_sector_size)) { |
1140 | info->max_indirect_segments ? : | ||
1141 | BLKIF_MAX_SEGMENTS_PER_REQUEST)) { | ||
1142 | del_gendisk(gd); | 1153 | del_gendisk(gd); |
1143 | goto release; | 1154 | goto release; |
1144 | } | 1155 | } |
1145 | 1156 | ||
1146 | info->rq = gd->queue; | ||
1147 | info->gd = gd; | ||
1148 | |||
1149 | xlvbd_flush(info); | 1157 | xlvbd_flush(info); |
1150 | 1158 | ||
1151 | if (vdisk_info & VDISK_READONLY) | 1159 | if (vdisk_info & VDISK_READONLY) |
@@ -1315,7 +1323,7 @@ free_shadow: | |||
1315 | rinfo->ring_ref[i] = GRANT_INVALID_REF; | 1323 | rinfo->ring_ref[i] = GRANT_INVALID_REF; |
1316 | } | 1324 | } |
1317 | } | 1325 | } |
1318 | free_pages((unsigned long)rinfo->ring.sring, get_order(info->nr_ring_pages * PAGE_SIZE)); | 1326 | free_pages((unsigned long)rinfo->ring.sring, get_order(info->nr_ring_pages * XEN_PAGE_SIZE)); |
1319 | rinfo->ring.sring = NULL; | 1327 | rinfo->ring.sring = NULL; |
1320 | 1328 | ||
1321 | if (rinfo->irq) | 1329 | if (rinfo->irq) |
@@ -2007,8 +2015,10 @@ static int blkif_recover(struct blkfront_info *info) | |||
2007 | struct split_bio *split_bio; | 2015 | struct split_bio *split_bio; |
2008 | 2016 | ||
2009 | blkfront_gather_backend_features(info); | 2017 | blkfront_gather_backend_features(info); |
2018 | /* Reset limits changed by blk_mq_update_nr_hw_queues(). */ | ||
2019 | blkif_set_queue_limits(info); | ||
2010 | segs = info->max_indirect_segments ? : BLKIF_MAX_SEGMENTS_PER_REQUEST; | 2020 | segs = info->max_indirect_segments ? : BLKIF_MAX_SEGMENTS_PER_REQUEST; |
2011 | blk_queue_max_segments(info->rq, segs); | 2021 | blk_queue_max_segments(info->rq, segs / GRANTS_PER_PSEG); |
2012 | 2022 | ||
2013 | for (r_index = 0; r_index < info->nr_rings; r_index++) { | 2023 | for (r_index = 0; r_index < info->nr_rings; r_index++) { |
2014 | struct blkfront_ring_info *rinfo = &info->rinfo[r_index]; | 2024 | struct blkfront_ring_info *rinfo = &info->rinfo[r_index]; |
@@ -2432,7 +2442,7 @@ static void blkfront_connect(struct blkfront_info *info) | |||
2432 | if (err) { | 2442 | if (err) { |
2433 | xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s", | 2443 | xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s", |
2434 | info->xbdev->otherend); | 2444 | info->xbdev->otherend); |
2435 | return; | 2445 | goto fail; |
2436 | } | 2446 | } |
2437 | 2447 | ||
2438 | xenbus_switch_state(info->xbdev, XenbusStateConnected); | 2448 | xenbus_switch_state(info->xbdev, XenbusStateConnected); |
@@ -2445,6 +2455,11 @@ static void blkfront_connect(struct blkfront_info *info) | |||
2445 | device_add_disk(&info->xbdev->dev, info->gd); | 2455 | device_add_disk(&info->xbdev->dev, info->gd); |
2446 | 2456 | ||
2447 | info->is_ready = 1; | 2457 | info->is_ready = 1; |
2458 | return; | ||
2459 | |||
2460 | fail: | ||
2461 | blkif_free(info, 0); | ||
2462 | return; | ||
2448 | } | 2463 | } |
2449 | 2464 | ||
2450 | /** | 2465 | /** |
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index 5755907f836f..ffa7c9dcbd7a 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c | |||
@@ -551,7 +551,7 @@ static struct attribute *cci5xx_pmu_event_attrs[] = { | |||
551 | CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_wrq, 0xB), | 551 | CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_wrq, 0xB), |
552 | CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_cd_hs, 0xC), | 552 | CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_cd_hs, 0xC), |
553 | CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_rq_stall_addr_hazard, 0xD), | 553 | CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_rq_stall_addr_hazard, 0xD), |
554 | CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snopp_rq_stall_tt_full, 0xE), | 554 | CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_rq_stall_tt_full, 0xE), |
555 | CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_rq_tzmp1_prot, 0xF), | 555 | CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_rq_tzmp1_prot, 0xF), |
556 | NULL | 556 | NULL |
557 | }; | 557 | }; |
diff --git a/drivers/bus/arm-ccn.c b/drivers/bus/arm-ccn.c index 97a9185af433..884c0305e290 100644 --- a/drivers/bus/arm-ccn.c +++ b/drivers/bus/arm-ccn.c | |||
@@ -187,6 +187,7 @@ struct arm_ccn { | |||
187 | struct arm_ccn_component *xp; | 187 | struct arm_ccn_component *xp; |
188 | 188 | ||
189 | struct arm_ccn_dt dt; | 189 | struct arm_ccn_dt dt; |
190 | int mn_id; | ||
190 | }; | 191 | }; |
191 | 192 | ||
192 | static DEFINE_MUTEX(arm_ccn_mutex); | 193 | static DEFINE_MUTEX(arm_ccn_mutex); |
@@ -212,6 +213,7 @@ static int arm_ccn_node_to_xp_port(int node) | |||
212 | #define CCN_CONFIG_TYPE(_config) (((_config) >> 8) & 0xff) | 213 | #define CCN_CONFIG_TYPE(_config) (((_config) >> 8) & 0xff) |
213 | #define CCN_CONFIG_EVENT(_config) (((_config) >> 16) & 0xff) | 214 | #define CCN_CONFIG_EVENT(_config) (((_config) >> 16) & 0xff) |
214 | #define CCN_CONFIG_PORT(_config) (((_config) >> 24) & 0x3) | 215 | #define CCN_CONFIG_PORT(_config) (((_config) >> 24) & 0x3) |
216 | #define CCN_CONFIG_BUS(_config) (((_config) >> 24) & 0x3) | ||
215 | #define CCN_CONFIG_VC(_config) (((_config) >> 26) & 0x7) | 217 | #define CCN_CONFIG_VC(_config) (((_config) >> 26) & 0x7) |
216 | #define CCN_CONFIG_DIR(_config) (((_config) >> 29) & 0x1) | 218 | #define CCN_CONFIG_DIR(_config) (((_config) >> 29) & 0x1) |
217 | #define CCN_CONFIG_MASK(_config) (((_config) >> 30) & 0xf) | 219 | #define CCN_CONFIG_MASK(_config) (((_config) >> 30) & 0xf) |
@@ -241,6 +243,7 @@ static CCN_FORMAT_ATTR(xp, "config:0-7"); | |||
241 | static CCN_FORMAT_ATTR(type, "config:8-15"); | 243 | static CCN_FORMAT_ATTR(type, "config:8-15"); |
242 | static CCN_FORMAT_ATTR(event, "config:16-23"); | 244 | static CCN_FORMAT_ATTR(event, "config:16-23"); |
243 | static CCN_FORMAT_ATTR(port, "config:24-25"); | 245 | static CCN_FORMAT_ATTR(port, "config:24-25"); |
246 | static CCN_FORMAT_ATTR(bus, "config:24-25"); | ||
244 | static CCN_FORMAT_ATTR(vc, "config:26-28"); | 247 | static CCN_FORMAT_ATTR(vc, "config:26-28"); |
245 | static CCN_FORMAT_ATTR(dir, "config:29-29"); | 248 | static CCN_FORMAT_ATTR(dir, "config:29-29"); |
246 | static CCN_FORMAT_ATTR(mask, "config:30-33"); | 249 | static CCN_FORMAT_ATTR(mask, "config:30-33"); |
@@ -253,6 +256,7 @@ static struct attribute *arm_ccn_pmu_format_attrs[] = { | |||
253 | &arm_ccn_pmu_format_attr_type.attr.attr, | 256 | &arm_ccn_pmu_format_attr_type.attr.attr, |
254 | &arm_ccn_pmu_format_attr_event.attr.attr, | 257 | &arm_ccn_pmu_format_attr_event.attr.attr, |
255 | &arm_ccn_pmu_format_attr_port.attr.attr, | 258 | &arm_ccn_pmu_format_attr_port.attr.attr, |
259 | &arm_ccn_pmu_format_attr_bus.attr.attr, | ||
256 | &arm_ccn_pmu_format_attr_vc.attr.attr, | 260 | &arm_ccn_pmu_format_attr_vc.attr.attr, |
257 | &arm_ccn_pmu_format_attr_dir.attr.attr, | 261 | &arm_ccn_pmu_format_attr_dir.attr.attr, |
258 | &arm_ccn_pmu_format_attr_mask.attr.attr, | 262 | &arm_ccn_pmu_format_attr_mask.attr.attr, |
@@ -328,6 +332,7 @@ struct arm_ccn_pmu_event { | |||
328 | static ssize_t arm_ccn_pmu_event_show(struct device *dev, | 332 | static ssize_t arm_ccn_pmu_event_show(struct device *dev, |
329 | struct device_attribute *attr, char *buf) | 333 | struct device_attribute *attr, char *buf) |
330 | { | 334 | { |
335 | struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev)); | ||
331 | struct arm_ccn_pmu_event *event = container_of(attr, | 336 | struct arm_ccn_pmu_event *event = container_of(attr, |
332 | struct arm_ccn_pmu_event, attr); | 337 | struct arm_ccn_pmu_event, attr); |
333 | ssize_t res; | 338 | ssize_t res; |
@@ -349,10 +354,17 @@ static ssize_t arm_ccn_pmu_event_show(struct device *dev, | |||
349 | break; | 354 | break; |
350 | case CCN_TYPE_XP: | 355 | case CCN_TYPE_XP: |
351 | res += snprintf(buf + res, PAGE_SIZE - res, | 356 | res += snprintf(buf + res, PAGE_SIZE - res, |
352 | ",xp=?,port=?,vc=?,dir=?"); | 357 | ",xp=?,vc=?"); |
353 | if (event->event == CCN_EVENT_WATCHPOINT) | 358 | if (event->event == CCN_EVENT_WATCHPOINT) |
354 | res += snprintf(buf + res, PAGE_SIZE - res, | 359 | res += snprintf(buf + res, PAGE_SIZE - res, |
355 | ",cmp_l=?,cmp_h=?,mask=?"); | 360 | ",port=?,dir=?,cmp_l=?,cmp_h=?,mask=?"); |
361 | else | ||
362 | res += snprintf(buf + res, PAGE_SIZE - res, | ||
363 | ",bus=?"); | ||
364 | |||
365 | break; | ||
366 | case CCN_TYPE_MN: | ||
367 | res += snprintf(buf + res, PAGE_SIZE - res, ",node=%d", ccn->mn_id); | ||
356 | break; | 368 | break; |
357 | default: | 369 | default: |
358 | res += snprintf(buf + res, PAGE_SIZE - res, ",node=?"); | 370 | res += snprintf(buf + res, PAGE_SIZE - res, ",node=?"); |
@@ -383,9 +395,9 @@ static umode_t arm_ccn_pmu_events_is_visible(struct kobject *kobj, | |||
383 | } | 395 | } |
384 | 396 | ||
385 | static struct arm_ccn_pmu_event arm_ccn_pmu_events[] = { | 397 | static struct arm_ccn_pmu_event arm_ccn_pmu_events[] = { |
386 | CCN_EVENT_MN(eobarrier, "dir=0,vc=0,cmp_h=0x1c00", CCN_IDX_MASK_OPCODE), | 398 | CCN_EVENT_MN(eobarrier, "dir=1,vc=0,cmp_h=0x1c00", CCN_IDX_MASK_OPCODE), |
387 | CCN_EVENT_MN(ecbarrier, "dir=0,vc=0,cmp_h=0x1e00", CCN_IDX_MASK_OPCODE), | 399 | CCN_EVENT_MN(ecbarrier, "dir=1,vc=0,cmp_h=0x1e00", CCN_IDX_MASK_OPCODE), |
388 | CCN_EVENT_MN(dvmop, "dir=0,vc=0,cmp_h=0x2800", CCN_IDX_MASK_OPCODE), | 400 | CCN_EVENT_MN(dvmop, "dir=1,vc=0,cmp_h=0x2800", CCN_IDX_MASK_OPCODE), |
389 | CCN_EVENT_HNI(txdatflits, "dir=1,vc=3", CCN_IDX_MASK_ANY), | 401 | CCN_EVENT_HNI(txdatflits, "dir=1,vc=3", CCN_IDX_MASK_ANY), |
390 | CCN_EVENT_HNI(rxdatflits, "dir=0,vc=3", CCN_IDX_MASK_ANY), | 402 | CCN_EVENT_HNI(rxdatflits, "dir=0,vc=3", CCN_IDX_MASK_ANY), |
391 | CCN_EVENT_HNI(txreqflits, "dir=1,vc=0", CCN_IDX_MASK_ANY), | 403 | CCN_EVENT_HNI(txreqflits, "dir=1,vc=0", CCN_IDX_MASK_ANY), |
@@ -733,9 +745,10 @@ static int arm_ccn_pmu_event_init(struct perf_event *event) | |||
733 | 745 | ||
734 | if (has_branch_stack(event) || event->attr.exclude_user || | 746 | if (has_branch_stack(event) || event->attr.exclude_user || |
735 | event->attr.exclude_kernel || event->attr.exclude_hv || | 747 | event->attr.exclude_kernel || event->attr.exclude_hv || |
736 | event->attr.exclude_idle) { | 748 | event->attr.exclude_idle || event->attr.exclude_host || |
749 | event->attr.exclude_guest) { | ||
737 | dev_warn(ccn->dev, "Can't exclude execution levels!\n"); | 750 | dev_warn(ccn->dev, "Can't exclude execution levels!\n"); |
738 | return -EOPNOTSUPP; | 751 | return -EINVAL; |
739 | } | 752 | } |
740 | 753 | ||
741 | if (event->cpu < 0) { | 754 | if (event->cpu < 0) { |
@@ -759,6 +772,12 @@ static int arm_ccn_pmu_event_init(struct perf_event *event) | |||
759 | 772 | ||
760 | /* Validate node/xp vs topology */ | 773 | /* Validate node/xp vs topology */ |
761 | switch (type) { | 774 | switch (type) { |
775 | case CCN_TYPE_MN: | ||
776 | if (node_xp != ccn->mn_id) { | ||
777 | dev_warn(ccn->dev, "Invalid MN ID %d!\n", node_xp); | ||
778 | return -EINVAL; | ||
779 | } | ||
780 | break; | ||
762 | case CCN_TYPE_XP: | 781 | case CCN_TYPE_XP: |
763 | if (node_xp >= ccn->num_xps) { | 782 | if (node_xp >= ccn->num_xps) { |
764 | dev_warn(ccn->dev, "Invalid XP ID %d!\n", node_xp); | 783 | dev_warn(ccn->dev, "Invalid XP ID %d!\n", node_xp); |
@@ -886,6 +905,10 @@ static void arm_ccn_pmu_xp_dt_config(struct perf_event *event, int enable) | |||
886 | struct arm_ccn_component *xp; | 905 | struct arm_ccn_component *xp; |
887 | u32 val, dt_cfg; | 906 | u32 val, dt_cfg; |
888 | 907 | ||
908 | /* Nothing to do for cycle counter */ | ||
909 | if (hw->idx == CCN_IDX_PMU_CYCLE_COUNTER) | ||
910 | return; | ||
911 | |||
889 | if (CCN_CONFIG_TYPE(event->attr.config) == CCN_TYPE_XP) | 912 | if (CCN_CONFIG_TYPE(event->attr.config) == CCN_TYPE_XP) |
890 | xp = &ccn->xp[CCN_CONFIG_XP(event->attr.config)]; | 913 | xp = &ccn->xp[CCN_CONFIG_XP(event->attr.config)]; |
891 | else | 914 | else |
@@ -917,38 +940,17 @@ static void arm_ccn_pmu_event_start(struct perf_event *event, int flags) | |||
917 | arm_ccn_pmu_read_counter(ccn, hw->idx)); | 940 | arm_ccn_pmu_read_counter(ccn, hw->idx)); |
918 | hw->state = 0; | 941 | hw->state = 0; |
919 | 942 | ||
920 | /* | ||
921 | * Pin the timer, so that the overflows are handled by the chosen | ||
922 | * event->cpu (this is the same one as presented in "cpumask" | ||
923 | * attribute). | ||
924 | */ | ||
925 | if (!ccn->irq) | ||
926 | hrtimer_start(&ccn->dt.hrtimer, arm_ccn_pmu_timer_period(), | ||
927 | HRTIMER_MODE_REL_PINNED); | ||
928 | |||
929 | /* Set the DT bus input, engaging the counter */ | 943 | /* Set the DT bus input, engaging the counter */ |
930 | arm_ccn_pmu_xp_dt_config(event, 1); | 944 | arm_ccn_pmu_xp_dt_config(event, 1); |
931 | } | 945 | } |
932 | 946 | ||
933 | static void arm_ccn_pmu_event_stop(struct perf_event *event, int flags) | 947 | static void arm_ccn_pmu_event_stop(struct perf_event *event, int flags) |
934 | { | 948 | { |
935 | struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); | ||
936 | struct hw_perf_event *hw = &event->hw; | 949 | struct hw_perf_event *hw = &event->hw; |
937 | u64 timeout; | ||
938 | 950 | ||
939 | /* Disable counting, setting the DT bus to pass-through mode */ | 951 | /* Disable counting, setting the DT bus to pass-through mode */ |
940 | arm_ccn_pmu_xp_dt_config(event, 0); | 952 | arm_ccn_pmu_xp_dt_config(event, 0); |
941 | 953 | ||
942 | if (!ccn->irq) | ||
943 | hrtimer_cancel(&ccn->dt.hrtimer); | ||
944 | |||
945 | /* Let the DT bus drain */ | ||
946 | timeout = arm_ccn_pmu_read_counter(ccn, CCN_IDX_PMU_CYCLE_COUNTER) + | ||
947 | ccn->num_xps; | ||
948 | while (arm_ccn_pmu_read_counter(ccn, CCN_IDX_PMU_CYCLE_COUNTER) < | ||
949 | timeout) | ||
950 | cpu_relax(); | ||
951 | |||
952 | if (flags & PERF_EF_UPDATE) | 954 | if (flags & PERF_EF_UPDATE) |
953 | arm_ccn_pmu_event_update(event); | 955 | arm_ccn_pmu_event_update(event); |
954 | 956 | ||
@@ -988,7 +990,7 @@ static void arm_ccn_pmu_xp_watchpoint_config(struct perf_event *event) | |||
988 | 990 | ||
989 | /* Comparison values */ | 991 | /* Comparison values */ |
990 | writel(cmp_l & 0xffffffff, source->base + CCN_XP_DT_CMP_VAL_L(wp)); | 992 | writel(cmp_l & 0xffffffff, source->base + CCN_XP_DT_CMP_VAL_L(wp)); |
991 | writel((cmp_l >> 32) & 0xefffffff, | 993 | writel((cmp_l >> 32) & 0x7fffffff, |
992 | source->base + CCN_XP_DT_CMP_VAL_L(wp) + 4); | 994 | source->base + CCN_XP_DT_CMP_VAL_L(wp) + 4); |
993 | writel(cmp_h & 0xffffffff, source->base + CCN_XP_DT_CMP_VAL_H(wp)); | 995 | writel(cmp_h & 0xffffffff, source->base + CCN_XP_DT_CMP_VAL_H(wp)); |
994 | writel((cmp_h >> 32) & 0x0fffffff, | 996 | writel((cmp_h >> 32) & 0x0fffffff, |
@@ -996,7 +998,7 @@ static void arm_ccn_pmu_xp_watchpoint_config(struct perf_event *event) | |||
996 | 998 | ||
997 | /* Mask */ | 999 | /* Mask */ |
998 | writel(mask_l & 0xffffffff, source->base + CCN_XP_DT_CMP_MASK_L(wp)); | 1000 | writel(mask_l & 0xffffffff, source->base + CCN_XP_DT_CMP_MASK_L(wp)); |
999 | writel((mask_l >> 32) & 0xefffffff, | 1001 | writel((mask_l >> 32) & 0x7fffffff, |
1000 | source->base + CCN_XP_DT_CMP_MASK_L(wp) + 4); | 1002 | source->base + CCN_XP_DT_CMP_MASK_L(wp) + 4); |
1001 | writel(mask_h & 0xffffffff, source->base + CCN_XP_DT_CMP_MASK_H(wp)); | 1003 | writel(mask_h & 0xffffffff, source->base + CCN_XP_DT_CMP_MASK_H(wp)); |
1002 | writel((mask_h >> 32) & 0x0fffffff, | 1004 | writel((mask_h >> 32) & 0x0fffffff, |
@@ -1014,7 +1016,7 @@ static void arm_ccn_pmu_xp_event_config(struct perf_event *event) | |||
1014 | hw->event_base = CCN_XP_DT_CONFIG__DT_CFG__XP_PMU_EVENT(hw->config_base); | 1016 | hw->event_base = CCN_XP_DT_CONFIG__DT_CFG__XP_PMU_EVENT(hw->config_base); |
1015 | 1017 | ||
1016 | id = (CCN_CONFIG_VC(event->attr.config) << 4) | | 1018 | id = (CCN_CONFIG_VC(event->attr.config) << 4) | |
1017 | (CCN_CONFIG_PORT(event->attr.config) << 3) | | 1019 | (CCN_CONFIG_BUS(event->attr.config) << 3) | |
1018 | (CCN_CONFIG_EVENT(event->attr.config) << 0); | 1020 | (CCN_CONFIG_EVENT(event->attr.config) << 0); |
1019 | 1021 | ||
1020 | val = readl(source->base + CCN_XP_PMU_EVENT_SEL); | 1022 | val = readl(source->base + CCN_XP_PMU_EVENT_SEL); |
@@ -1099,15 +1101,31 @@ static void arm_ccn_pmu_event_config(struct perf_event *event) | |||
1099 | spin_unlock(&ccn->dt.config_lock); | 1101 | spin_unlock(&ccn->dt.config_lock); |
1100 | } | 1102 | } |
1101 | 1103 | ||
1104 | static int arm_ccn_pmu_active_counters(struct arm_ccn *ccn) | ||
1105 | { | ||
1106 | return bitmap_weight(ccn->dt.pmu_counters_mask, | ||
1107 | CCN_NUM_PMU_EVENT_COUNTERS + 1); | ||
1108 | } | ||
1109 | |||
1102 | static int arm_ccn_pmu_event_add(struct perf_event *event, int flags) | 1110 | static int arm_ccn_pmu_event_add(struct perf_event *event, int flags) |
1103 | { | 1111 | { |
1104 | int err; | 1112 | int err; |
1105 | struct hw_perf_event *hw = &event->hw; | 1113 | struct hw_perf_event *hw = &event->hw; |
1114 | struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); | ||
1106 | 1115 | ||
1107 | err = arm_ccn_pmu_event_alloc(event); | 1116 | err = arm_ccn_pmu_event_alloc(event); |
1108 | if (err) | 1117 | if (err) |
1109 | return err; | 1118 | return err; |
1110 | 1119 | ||
1120 | /* | ||
1121 | * Pin the timer, so that the overflows are handled by the chosen | ||
1122 | * event->cpu (this is the same one as presented in "cpumask" | ||
1123 | * attribute). | ||
1124 | */ | ||
1125 | if (!ccn->irq && arm_ccn_pmu_active_counters(ccn) == 1) | ||
1126 | hrtimer_start(&ccn->dt.hrtimer, arm_ccn_pmu_timer_period(), | ||
1127 | HRTIMER_MODE_REL_PINNED); | ||
1128 | |||
1111 | arm_ccn_pmu_event_config(event); | 1129 | arm_ccn_pmu_event_config(event); |
1112 | 1130 | ||
1113 | hw->state = PERF_HES_STOPPED; | 1131 | hw->state = PERF_HES_STOPPED; |
@@ -1120,9 +1138,14 @@ static int arm_ccn_pmu_event_add(struct perf_event *event, int flags) | |||
1120 | 1138 | ||
1121 | static void arm_ccn_pmu_event_del(struct perf_event *event, int flags) | 1139 | static void arm_ccn_pmu_event_del(struct perf_event *event, int flags) |
1122 | { | 1140 | { |
1141 | struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); | ||
1142 | |||
1123 | arm_ccn_pmu_event_stop(event, PERF_EF_UPDATE); | 1143 | arm_ccn_pmu_event_stop(event, PERF_EF_UPDATE); |
1124 | 1144 | ||
1125 | arm_ccn_pmu_event_release(event); | 1145 | arm_ccn_pmu_event_release(event); |
1146 | |||
1147 | if (!ccn->irq && arm_ccn_pmu_active_counters(ccn) == 0) | ||
1148 | hrtimer_cancel(&ccn->dt.hrtimer); | ||
1126 | } | 1149 | } |
1127 | 1150 | ||
1128 | static void arm_ccn_pmu_event_read(struct perf_event *event) | 1151 | static void arm_ccn_pmu_event_read(struct perf_event *event) |
@@ -1130,6 +1153,24 @@ static void arm_ccn_pmu_event_read(struct perf_event *event) | |||
1130 | arm_ccn_pmu_event_update(event); | 1153 | arm_ccn_pmu_event_update(event); |
1131 | } | 1154 | } |
1132 | 1155 | ||
1156 | static void arm_ccn_pmu_enable(struct pmu *pmu) | ||
1157 | { | ||
1158 | struct arm_ccn *ccn = pmu_to_arm_ccn(pmu); | ||
1159 | |||
1160 | u32 val = readl(ccn->dt.base + CCN_DT_PMCR); | ||
1161 | val |= CCN_DT_PMCR__PMU_EN; | ||
1162 | writel(val, ccn->dt.base + CCN_DT_PMCR); | ||
1163 | } | ||
1164 | |||
1165 | static void arm_ccn_pmu_disable(struct pmu *pmu) | ||
1166 | { | ||
1167 | struct arm_ccn *ccn = pmu_to_arm_ccn(pmu); | ||
1168 | |||
1169 | u32 val = readl(ccn->dt.base + CCN_DT_PMCR); | ||
1170 | val &= ~CCN_DT_PMCR__PMU_EN; | ||
1171 | writel(val, ccn->dt.base + CCN_DT_PMCR); | ||
1172 | } | ||
1173 | |||
1133 | static irqreturn_t arm_ccn_pmu_overflow_handler(struct arm_ccn_dt *dt) | 1174 | static irqreturn_t arm_ccn_pmu_overflow_handler(struct arm_ccn_dt *dt) |
1134 | { | 1175 | { |
1135 | u32 pmovsr = readl(dt->base + CCN_DT_PMOVSR); | 1176 | u32 pmovsr = readl(dt->base + CCN_DT_PMOVSR); |
@@ -1252,6 +1293,8 @@ static int arm_ccn_pmu_init(struct arm_ccn *ccn) | |||
1252 | .start = arm_ccn_pmu_event_start, | 1293 | .start = arm_ccn_pmu_event_start, |
1253 | .stop = arm_ccn_pmu_event_stop, | 1294 | .stop = arm_ccn_pmu_event_stop, |
1254 | .read = arm_ccn_pmu_event_read, | 1295 | .read = arm_ccn_pmu_event_read, |
1296 | .pmu_enable = arm_ccn_pmu_enable, | ||
1297 | .pmu_disable = arm_ccn_pmu_disable, | ||
1255 | }; | 1298 | }; |
1256 | 1299 | ||
1257 | /* No overflow interrupt? Have to use a timer instead. */ | 1300 | /* No overflow interrupt? Have to use a timer instead. */ |
@@ -1361,6 +1404,8 @@ static int arm_ccn_init_nodes(struct arm_ccn *ccn, int region, | |||
1361 | 1404 | ||
1362 | switch (type) { | 1405 | switch (type) { |
1363 | case CCN_TYPE_MN: | 1406 | case CCN_TYPE_MN: |
1407 | ccn->mn_id = id; | ||
1408 | return 0; | ||
1364 | case CCN_TYPE_DT: | 1409 | case CCN_TYPE_DT: |
1365 | return 0; | 1410 | return 0; |
1366 | case CCN_TYPE_XP: | 1411 | case CCN_TYPE_XP: |
@@ -1471,8 +1516,9 @@ static int arm_ccn_probe(struct platform_device *pdev) | |||
1471 | /* Can set 'disable' bits, so can acknowledge interrupts */ | 1516 | /* Can set 'disable' bits, so can acknowledge interrupts */ |
1472 | writel(CCN_MN_ERRINT_STATUS__PMU_EVENTS__ENABLE, | 1517 | writel(CCN_MN_ERRINT_STATUS__PMU_EVENTS__ENABLE, |
1473 | ccn->base + CCN_MN_ERRINT_STATUS); | 1518 | ccn->base + CCN_MN_ERRINT_STATUS); |
1474 | err = devm_request_irq(ccn->dev, irq, arm_ccn_irq_handler, 0, | 1519 | err = devm_request_irq(ccn->dev, irq, arm_ccn_irq_handler, |
1475 | dev_name(ccn->dev), ccn); | 1520 | IRQF_NOBALANCING | IRQF_NO_THREAD, |
1521 | dev_name(ccn->dev), ccn); | ||
1476 | if (err) | 1522 | if (err) |
1477 | return err; | 1523 | return err; |
1478 | 1524 | ||
diff --git a/drivers/bus/vexpress-config.c b/drivers/bus/vexpress-config.c index c3cb76b363c6..9efdf1de4035 100644 --- a/drivers/bus/vexpress-config.c +++ b/drivers/bus/vexpress-config.c | |||
@@ -178,6 +178,7 @@ static int vexpress_config_populate(struct device_node *node) | |||
178 | 178 | ||
179 | parent = class_find_device(vexpress_config_class, NULL, bridge, | 179 | parent = class_find_device(vexpress_config_class, NULL, bridge, |
180 | vexpress_config_node_match); | 180 | vexpress_config_node_match); |
181 | of_node_put(bridge); | ||
181 | if (WARN_ON(!parent)) | 182 | if (WARN_ON(!parent)) |
182 | return -ENODEV; | 183 | return -ENODEV; |
183 | 184 | ||
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index 56ad5a5936a9..8c0770bf8881 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig | |||
@@ -244,7 +244,7 @@ config HW_RANDOM_TX4939 | |||
244 | 244 | ||
245 | config HW_RANDOM_MXC_RNGA | 245 | config HW_RANDOM_MXC_RNGA |
246 | tristate "Freescale i.MX RNGA Random Number Generator" | 246 | tristate "Freescale i.MX RNGA Random Number Generator" |
247 | depends on ARCH_HAS_RNGA | 247 | depends on SOC_IMX31 |
248 | default HW_RANDOM | 248 | default HW_RANDOM |
249 | ---help--- | 249 | ---help--- |
250 | This driver provides kernel-side support for the Random Number | 250 | This driver provides kernel-side support for the Random Number |
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 08c7e23ed535..0c75c3f1689f 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c | |||
@@ -957,7 +957,7 @@ int tpm2_auto_startup(struct tpm_chip *chip) | |||
957 | goto out; | 957 | goto out; |
958 | 958 | ||
959 | rc = tpm2_do_selftest(chip); | 959 | rc = tpm2_do_selftest(chip); |
960 | if (rc != TPM2_RC_INITIALIZE) { | 960 | if (rc != 0 && rc != TPM2_RC_INITIALIZE) { |
961 | dev_err(&chip->dev, "TPM self test failed\n"); | 961 | dev_err(&chip->dev, "TPM self test failed\n"); |
962 | goto out; | 962 | goto out; |
963 | } | 963 | } |
@@ -974,7 +974,6 @@ int tpm2_auto_startup(struct tpm_chip *chip) | |||
974 | } | 974 | } |
975 | } | 975 | } |
976 | 976 | ||
977 | return rc; | ||
978 | out: | 977 | out: |
979 | if (rc > 0) | 978 | if (rc > 0) |
980 | rc = -ENODEV; | 979 | rc = -ENODEV; |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index d2406fe25533..5da47e26a012 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -165,6 +165,12 @@ struct ports_device { | |||
165 | */ | 165 | */ |
166 | struct virtqueue *c_ivq, *c_ovq; | 166 | struct virtqueue *c_ivq, *c_ovq; |
167 | 167 | ||
168 | /* | ||
169 | * A control packet buffer for guest->host requests, protected | ||
170 | * by c_ovq_lock. | ||
171 | */ | ||
172 | struct virtio_console_control cpkt; | ||
173 | |||
168 | /* Array of per-port IO virtqueues */ | 174 | /* Array of per-port IO virtqueues */ |
169 | struct virtqueue **in_vqs, **out_vqs; | 175 | struct virtqueue **in_vqs, **out_vqs; |
170 | 176 | ||
@@ -560,28 +566,29 @@ static ssize_t __send_control_msg(struct ports_device *portdev, u32 port_id, | |||
560 | unsigned int event, unsigned int value) | 566 | unsigned int event, unsigned int value) |
561 | { | 567 | { |
562 | struct scatterlist sg[1]; | 568 | struct scatterlist sg[1]; |
563 | struct virtio_console_control cpkt; | ||
564 | struct virtqueue *vq; | 569 | struct virtqueue *vq; |
565 | unsigned int len; | 570 | unsigned int len; |
566 | 571 | ||
567 | if (!use_multiport(portdev)) | 572 | if (!use_multiport(portdev)) |
568 | return 0; | 573 | return 0; |
569 | 574 | ||
570 | cpkt.id = cpu_to_virtio32(portdev->vdev, port_id); | ||
571 | cpkt.event = cpu_to_virtio16(portdev->vdev, event); | ||
572 | cpkt.value = cpu_to_virtio16(portdev->vdev, value); | ||
573 | |||
574 | vq = portdev->c_ovq; | 575 | vq = portdev->c_ovq; |
575 | 576 | ||
576 | sg_init_one(sg, &cpkt, sizeof(cpkt)); | ||
577 | |||
578 | spin_lock(&portdev->c_ovq_lock); | 577 | spin_lock(&portdev->c_ovq_lock); |
579 | if (virtqueue_add_outbuf(vq, sg, 1, &cpkt, GFP_ATOMIC) == 0) { | 578 | |
579 | portdev->cpkt.id = cpu_to_virtio32(portdev->vdev, port_id); | ||
580 | portdev->cpkt.event = cpu_to_virtio16(portdev->vdev, event); | ||
581 | portdev->cpkt.value = cpu_to_virtio16(portdev->vdev, value); | ||
582 | |||
583 | sg_init_one(sg, &portdev->cpkt, sizeof(struct virtio_console_control)); | ||
584 | |||
585 | if (virtqueue_add_outbuf(vq, sg, 1, &portdev->cpkt, GFP_ATOMIC) == 0) { | ||
580 | virtqueue_kick(vq); | 586 | virtqueue_kick(vq); |
581 | while (!virtqueue_get_buf(vq, &len) | 587 | while (!virtqueue_get_buf(vq, &len) |
582 | && !virtqueue_is_broken(vq)) | 588 | && !virtqueue_is_broken(vq)) |
583 | cpu_relax(); | 589 | cpu_relax(); |
584 | } | 590 | } |
591 | |||
585 | spin_unlock(&portdev->c_ovq_lock); | 592 | spin_unlock(&portdev->c_ovq_lock); |
586 | return 0; | 593 | return 0; |
587 | } | 594 | } |
diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index d359c92e13a6..e38bf60c0ff4 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c | |||
@@ -69,6 +69,7 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { | |||
69 | DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), | 69 | DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), |
70 | DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), | 70 | DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), |
71 | DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), | 71 | DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), |
72 | DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), | ||
72 | 73 | ||
73 | /* Core Clock Outputs */ | 74 | /* Core Clock Outputs */ |
74 | DEF_FIXED("ztr", R8A7795_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), | 75 | DEF_FIXED("ztr", R8A7795_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), |
@@ -87,10 +88,10 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { | |||
87 | DEF_FIXED("s3d2", R8A7795_CLK_S3D2, CLK_S3, 2, 1), | 88 | DEF_FIXED("s3d2", R8A7795_CLK_S3D2, CLK_S3, 2, 1), |
88 | DEF_FIXED("s3d4", R8A7795_CLK_S3D4, CLK_S3, 4, 1), | 89 | DEF_FIXED("s3d4", R8A7795_CLK_S3D4, CLK_S3, 4, 1), |
89 | 90 | ||
90 | DEF_GEN3_SD("sd0", R8A7795_CLK_SD0, CLK_PLL1_DIV2, 0x0074), | 91 | DEF_GEN3_SD("sd0", R8A7795_CLK_SD0, CLK_SDSRC, 0x0074), |
91 | DEF_GEN3_SD("sd1", R8A7795_CLK_SD1, CLK_PLL1_DIV2, 0x0078), | 92 | DEF_GEN3_SD("sd1", R8A7795_CLK_SD1, CLK_SDSRC, 0x0078), |
92 | DEF_GEN3_SD("sd2", R8A7795_CLK_SD2, CLK_PLL1_DIV2, 0x0268), | 93 | DEF_GEN3_SD("sd2", R8A7795_CLK_SD2, CLK_SDSRC, 0x0268), |
93 | DEF_GEN3_SD("sd3", R8A7795_CLK_SD3, CLK_PLL1_DIV2, 0x026c), | 94 | DEF_GEN3_SD("sd3", R8A7795_CLK_SD3, CLK_SDSRC, 0x026c), |
94 | 95 | ||
95 | DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1), | 96 | DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1), |
96 | DEF_FIXED("cp", R8A7795_CLK_CP, CLK_EXTAL, 2, 1), | 97 | DEF_FIXED("cp", R8A7795_CLK_CP, CLK_EXTAL, 2, 1), |
diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c index c109d80e7a8a..cdfabeb9a034 100644 --- a/drivers/clk/rockchip/clk-rk3399.c +++ b/drivers/clk/rockchip/clk-rk3399.c | |||
@@ -833,9 +833,9 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { | |||
833 | 833 | ||
834 | /* perihp */ | 834 | /* perihp */ |
835 | GATE(0, "cpll_aclk_perihp_src", "cpll", CLK_IGNORE_UNUSED, | 835 | GATE(0, "cpll_aclk_perihp_src", "cpll", CLK_IGNORE_UNUSED, |
836 | RK3399_CLKGATE_CON(5), 0, GFLAGS), | ||
837 | GATE(0, "gpll_aclk_perihp_src", "gpll", CLK_IGNORE_UNUSED, | ||
838 | RK3399_CLKGATE_CON(5), 1, GFLAGS), | 836 | RK3399_CLKGATE_CON(5), 1, GFLAGS), |
837 | GATE(0, "gpll_aclk_perihp_src", "gpll", CLK_IGNORE_UNUSED, | ||
838 | RK3399_CLKGATE_CON(5), 0, GFLAGS), | ||
839 | COMPOSITE(ACLK_PERIHP, "aclk_perihp", mux_aclk_perihp_p, CLK_IGNORE_UNUSED, | 839 | COMPOSITE(ACLK_PERIHP, "aclk_perihp", mux_aclk_perihp_p, CLK_IGNORE_UNUSED, |
840 | RK3399_CLKSEL_CON(14), 7, 1, MFLAGS, 0, 5, DFLAGS, | 840 | RK3399_CLKSEL_CON(14), 7, 1, MFLAGS, 0, 5, DFLAGS, |
841 | RK3399_CLKGATE_CON(5), 2, GFLAGS), | 841 | RK3399_CLKGATE_CON(5), 2, GFLAGS), |
@@ -923,9 +923,9 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { | |||
923 | RK3399_CLKGATE_CON(6), 14, GFLAGS), | 923 | RK3399_CLKGATE_CON(6), 14, GFLAGS), |
924 | 924 | ||
925 | GATE(0, "cpll_aclk_emmc_src", "cpll", CLK_IGNORE_UNUSED, | 925 | GATE(0, "cpll_aclk_emmc_src", "cpll", CLK_IGNORE_UNUSED, |
926 | RK3399_CLKGATE_CON(6), 12, GFLAGS), | ||
927 | GATE(0, "gpll_aclk_emmc_src", "gpll", CLK_IGNORE_UNUSED, | ||
928 | RK3399_CLKGATE_CON(6), 13, GFLAGS), | 926 | RK3399_CLKGATE_CON(6), 13, GFLAGS), |
927 | GATE(0, "gpll_aclk_emmc_src", "gpll", CLK_IGNORE_UNUSED, | ||
928 | RK3399_CLKGATE_CON(6), 12, GFLAGS), | ||
929 | COMPOSITE_NOGATE(ACLK_EMMC, "aclk_emmc", mux_aclk_emmc_p, CLK_IGNORE_UNUSED, | 929 | COMPOSITE_NOGATE(ACLK_EMMC, "aclk_emmc", mux_aclk_emmc_p, CLK_IGNORE_UNUSED, |
930 | RK3399_CLKSEL_CON(21), 7, 1, MFLAGS, 0, 5, DFLAGS), | 930 | RK3399_CLKSEL_CON(21), 7, 1, MFLAGS, 0, 5, DFLAGS), |
931 | GATE(ACLK_EMMC_CORE, "aclk_emmccore", "aclk_emmc", CLK_IGNORE_UNUSED, | 931 | GATE(ACLK_EMMC_CORE, "aclk_emmccore", "aclk_emmc", CLK_IGNORE_UNUSED, |
@@ -1071,7 +1071,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { | |||
1071 | /* vio */ | 1071 | /* vio */ |
1072 | COMPOSITE(ACLK_VIO, "aclk_vio", mux_pll_src_cpll_gpll_ppll_p, CLK_IGNORE_UNUSED, | 1072 | COMPOSITE(ACLK_VIO, "aclk_vio", mux_pll_src_cpll_gpll_ppll_p, CLK_IGNORE_UNUSED, |
1073 | RK3399_CLKSEL_CON(42), 6, 2, MFLAGS, 0, 5, DFLAGS, | 1073 | RK3399_CLKSEL_CON(42), 6, 2, MFLAGS, 0, 5, DFLAGS, |
1074 | RK3399_CLKGATE_CON(11), 10, GFLAGS), | 1074 | RK3399_CLKGATE_CON(11), 0, GFLAGS), |
1075 | COMPOSITE_NOMUX(PCLK_VIO, "pclk_vio", "aclk_vio", 0, | 1075 | COMPOSITE_NOMUX(PCLK_VIO, "pclk_vio", "aclk_vio", 0, |
1076 | RK3399_CLKSEL_CON(43), 0, 5, DFLAGS, | 1076 | RK3399_CLKSEL_CON(43), 0, 5, DFLAGS, |
1077 | RK3399_CLKGATE_CON(11), 1, GFLAGS), | 1077 | RK3399_CLKGATE_CON(11), 1, GFLAGS), |
@@ -1484,6 +1484,7 @@ static const char *const rk3399_cru_critical_clocks[] __initconst = { | |||
1484 | "hclk_perilp1", | 1484 | "hclk_perilp1", |
1485 | "hclk_perilp1_noc", | 1485 | "hclk_perilp1_noc", |
1486 | "aclk_dmac0_perilp", | 1486 | "aclk_dmac0_perilp", |
1487 | "aclk_emmc_noc", | ||
1487 | "gpll_hclk_perilp1_src", | 1488 | "gpll_hclk_perilp1_src", |
1488 | "gpll_aclk_perilp0_src", | 1489 | "gpll_aclk_perilp0_src", |
1489 | "gpll_aclk_perihp_src", | 1490 | "gpll_aclk_perihp_src", |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index 9af359544110..267f99523fbe 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c | |||
@@ -783,14 +783,14 @@ static struct ccu_reset_map sun8i_h3_ccu_resets[] = { | |||
783 | [RST_BUS_I2S1] = { 0x2d0, BIT(13) }, | 783 | [RST_BUS_I2S1] = { 0x2d0, BIT(13) }, |
784 | [RST_BUS_I2S2] = { 0x2d0, BIT(14) }, | 784 | [RST_BUS_I2S2] = { 0x2d0, BIT(14) }, |
785 | 785 | ||
786 | [RST_BUS_I2C0] = { 0x2d4, BIT(0) }, | 786 | [RST_BUS_I2C0] = { 0x2d8, BIT(0) }, |
787 | [RST_BUS_I2C1] = { 0x2d4, BIT(1) }, | 787 | [RST_BUS_I2C1] = { 0x2d8, BIT(1) }, |
788 | [RST_BUS_I2C2] = { 0x2d4, BIT(2) }, | 788 | [RST_BUS_I2C2] = { 0x2d8, BIT(2) }, |
789 | [RST_BUS_UART0] = { 0x2d4, BIT(16) }, | 789 | [RST_BUS_UART0] = { 0x2d8, BIT(16) }, |
790 | [RST_BUS_UART1] = { 0x2d4, BIT(17) }, | 790 | [RST_BUS_UART1] = { 0x2d8, BIT(17) }, |
791 | [RST_BUS_UART2] = { 0x2d4, BIT(18) }, | 791 | [RST_BUS_UART2] = { 0x2d8, BIT(18) }, |
792 | [RST_BUS_UART3] = { 0x2d4, BIT(19) }, | 792 | [RST_BUS_UART3] = { 0x2d8, BIT(19) }, |
793 | [RST_BUS_SCR] = { 0x2d4, BIT(20) }, | 793 | [RST_BUS_SCR] = { 0x2d8, BIT(20) }, |
794 | }; | 794 | }; |
795 | 795 | ||
796 | static const struct sunxi_ccu_desc sun8i_h3_ccu_desc = { | 796 | static const struct sunxi_ccu_desc sun8i_h3_ccu_desc = { |
diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c index fc17b5295e16..51d4bac97ab3 100644 --- a/drivers/clk/sunxi-ng/ccu_common.c +++ b/drivers/clk/sunxi-ng/ccu_common.c | |||
@@ -31,7 +31,7 @@ void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock) | |||
31 | return; | 31 | return; |
32 | 32 | ||
33 | WARN_ON(readl_relaxed_poll_timeout(common->base + common->reg, reg, | 33 | WARN_ON(readl_relaxed_poll_timeout(common->base + common->reg, reg, |
34 | !(reg & lock), 100, 70000)); | 34 | reg & lock, 100, 70000)); |
35 | } | 35 | } |
36 | 36 | ||
37 | int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, | 37 | int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, |
diff --git a/drivers/clk/sunxi-ng/ccu_nk.c b/drivers/clk/sunxi-ng/ccu_nk.c index 4470ffc8cf0d..d6fafb397489 100644 --- a/drivers/clk/sunxi-ng/ccu_nk.c +++ b/drivers/clk/sunxi-ng/ccu_nk.c | |||
@@ -14,9 +14,9 @@ | |||
14 | #include "ccu_gate.h" | 14 | #include "ccu_gate.h" |
15 | #include "ccu_nk.h" | 15 | #include "ccu_nk.h" |
16 | 16 | ||
17 | void ccu_nk_find_best(unsigned long parent, unsigned long rate, | 17 | static void ccu_nk_find_best(unsigned long parent, unsigned long rate, |
18 | unsigned int max_n, unsigned int max_k, | 18 | unsigned int max_n, unsigned int max_k, |
19 | unsigned int *n, unsigned int *k) | 19 | unsigned int *n, unsigned int *k) |
20 | { | 20 | { |
21 | unsigned long best_rate = 0; | 21 | unsigned long best_rate = 0; |
22 | unsigned int best_k = 0, best_n = 0; | 22 | unsigned int best_k = 0, best_n = 0; |
diff --git a/drivers/clk/sunxi/clk-a10-pll2.c b/drivers/clk/sunxi/clk-a10-pll2.c index 0ee1f363e4be..d8eab90ae661 100644 --- a/drivers/clk/sunxi/clk-a10-pll2.c +++ b/drivers/clk/sunxi/clk-a10-pll2.c | |||
@@ -73,7 +73,7 @@ static void __init sun4i_pll2_setup(struct device_node *node, | |||
73 | SUN4I_PLL2_PRE_DIV_WIDTH, | 73 | SUN4I_PLL2_PRE_DIV_WIDTH, |
74 | CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, | 74 | CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, |
75 | &sun4i_a10_pll2_lock); | 75 | &sun4i_a10_pll2_lock); |
76 | if (!prediv_clk) { | 76 | if (IS_ERR(prediv_clk)) { |
77 | pr_err("Couldn't register the prediv clock\n"); | 77 | pr_err("Couldn't register the prediv clock\n"); |
78 | goto err_free_array; | 78 | goto err_free_array; |
79 | } | 79 | } |
@@ -106,7 +106,7 @@ static void __init sun4i_pll2_setup(struct device_node *node, | |||
106 | &mult->hw, &clk_multiplier_ops, | 106 | &mult->hw, &clk_multiplier_ops, |
107 | &gate->hw, &clk_gate_ops, | 107 | &gate->hw, &clk_gate_ops, |
108 | CLK_SET_RATE_PARENT); | 108 | CLK_SET_RATE_PARENT); |
109 | if (!base_clk) { | 109 | if (IS_ERR(base_clk)) { |
110 | pr_err("Couldn't register the base multiplier clock\n"); | 110 | pr_err("Couldn't register the base multiplier clock\n"); |
111 | goto err_free_multiplier; | 111 | goto err_free_multiplier; |
112 | } | 112 | } |
diff --git a/drivers/clk/sunxi/clk-sun8i-mbus.c b/drivers/clk/sunxi/clk-sun8i-mbus.c index 411d3033a96e..b200ebf159ee 100644 --- a/drivers/clk/sunxi/clk-sun8i-mbus.c +++ b/drivers/clk/sunxi/clk-sun8i-mbus.c | |||
@@ -48,7 +48,7 @@ static void __init sun8i_a23_mbus_setup(struct device_node *node) | |||
48 | return; | 48 | return; |
49 | 49 | ||
50 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | 50 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); |
51 | if (!reg) { | 51 | if (IS_ERR(reg)) { |
52 | pr_err("Could not get registers for sun8i-mbus-clk\n"); | 52 | pr_err("Could not get registers for sun8i-mbus-clk\n"); |
53 | goto err_free_parents; | 53 | goto err_free_parents; |
54 | } | 54 | } |
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 64da7b79a6e4..933b5dd698b8 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c | |||
@@ -428,7 +428,7 @@ static struct tegra_clk_pll_params pll_d_params = { | |||
428 | .div_nmp = &pllp_nmp, | 428 | .div_nmp = &pllp_nmp, |
429 | .freq_table = pll_d_freq_table, | 429 | .freq_table = pll_d_freq_table, |
430 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | | 430 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | |
431 | TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, | 431 | TEGRA_PLL_HAS_LOCK_ENABLE, |
432 | }; | 432 | }; |
433 | 433 | ||
434 | static struct tegra_clk_pll_params pll_d2_params = { | 434 | static struct tegra_clk_pll_params pll_d2_params = { |
@@ -446,7 +446,7 @@ static struct tegra_clk_pll_params pll_d2_params = { | |||
446 | .div_nmp = &pllp_nmp, | 446 | .div_nmp = &pllp_nmp, |
447 | .freq_table = pll_d_freq_table, | 447 | .freq_table = pll_d_freq_table, |
448 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | | 448 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | |
449 | TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, | 449 | TEGRA_PLL_HAS_LOCK_ENABLE, |
450 | }; | 450 | }; |
451 | 451 | ||
452 | static const struct pdiv_map pllu_p[] = { | 452 | static const struct pdiv_map pllu_p[] = { |
diff --git a/drivers/clocksource/pxa_timer.c b/drivers/clocksource/pxa_timer.c index 937e10b84d58..3e1cb512f3ce 100644 --- a/drivers/clocksource/pxa_timer.c +++ b/drivers/clocksource/pxa_timer.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/of_irq.h> | 21 | #include <linux/of_irq.h> |
22 | #include <linux/sched_clock.h> | 22 | #include <linux/sched_clock.h> |
23 | 23 | ||
24 | #include <clocksource/pxa.h> | ||
25 | |||
24 | #include <asm/div64.h> | 26 | #include <asm/div64.h> |
25 | 27 | ||
26 | #define OSMR0 0x00 /* OS Timer 0 Match Register */ | 28 | #define OSMR0 0x00 /* OS Timer 0 Match Register */ |
diff --git a/drivers/clocksource/sun4i_timer.c b/drivers/clocksource/sun4i_timer.c index 97669ee4df2a..c83452cacb41 100644 --- a/drivers/clocksource/sun4i_timer.c +++ b/drivers/clocksource/sun4i_timer.c | |||
@@ -123,12 +123,16 @@ static struct clock_event_device sun4i_clockevent = { | |||
123 | .set_next_event = sun4i_clkevt_next_event, | 123 | .set_next_event = sun4i_clkevt_next_event, |
124 | }; | 124 | }; |
125 | 125 | ||
126 | static void sun4i_timer_clear_interrupt(void) | ||
127 | { | ||
128 | writel(TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_ST_REG); | ||
129 | } | ||
126 | 130 | ||
127 | static irqreturn_t sun4i_timer_interrupt(int irq, void *dev_id) | 131 | static irqreturn_t sun4i_timer_interrupt(int irq, void *dev_id) |
128 | { | 132 | { |
129 | struct clock_event_device *evt = (struct clock_event_device *)dev_id; | 133 | struct clock_event_device *evt = (struct clock_event_device *)dev_id; |
130 | 134 | ||
131 | writel(0x1, timer_base + TIMER_IRQ_ST_REG); | 135 | sun4i_timer_clear_interrupt(); |
132 | evt->event_handler(evt); | 136 | evt->event_handler(evt); |
133 | 137 | ||
134 | return IRQ_HANDLED; | 138 | return IRQ_HANDLED; |
@@ -208,6 +212,9 @@ static int __init sun4i_timer_init(struct device_node *node) | |||
208 | /* Make sure timer is stopped before playing with interrupts */ | 212 | /* Make sure timer is stopped before playing with interrupts */ |
209 | sun4i_clkevt_time_stop(0); | 213 | sun4i_clkevt_time_stop(0); |
210 | 214 | ||
215 | /* clear timer0 interrupt */ | ||
216 | sun4i_timer_clear_interrupt(); | ||
217 | |||
211 | sun4i_clockevent.cpumask = cpu_possible_mask; | 218 | sun4i_clockevent.cpumask = cpu_possible_mask; |
212 | sun4i_clockevent.irq = irq; | 219 | sun4i_clockevent.irq = irq; |
213 | 220 | ||
diff --git a/drivers/clocksource/time-pistachio.c b/drivers/clocksource/time-pistachio.c index a7d9a08e4b0e..a8e6c7df853d 100644 --- a/drivers/clocksource/time-pistachio.c +++ b/drivers/clocksource/time-pistachio.c | |||
@@ -202,10 +202,10 @@ static int __init pistachio_clksrc_of_init(struct device_node *node) | |||
202 | rate = clk_get_rate(fast_clk); | 202 | rate = clk_get_rate(fast_clk); |
203 | 203 | ||
204 | /* Disable irq's for clocksource usage */ | 204 | /* Disable irq's for clocksource usage */ |
205 | gpt_writel(&pcs_gpt.base, 0, TIMER_IRQ_MASK, 0); | 205 | gpt_writel(pcs_gpt.base, 0, TIMER_IRQ_MASK, 0); |
206 | gpt_writel(&pcs_gpt.base, 0, TIMER_IRQ_MASK, 1); | 206 | gpt_writel(pcs_gpt.base, 0, TIMER_IRQ_MASK, 1); |
207 | gpt_writel(&pcs_gpt.base, 0, TIMER_IRQ_MASK, 2); | 207 | gpt_writel(pcs_gpt.base, 0, TIMER_IRQ_MASK, 2); |
208 | gpt_writel(&pcs_gpt.base, 0, TIMER_IRQ_MASK, 3); | 208 | gpt_writel(pcs_gpt.base, 0, TIMER_IRQ_MASK, 3); |
209 | 209 | ||
210 | /* Enable timer block */ | 210 | /* Enable timer block */ |
211 | writel(TIMER_ME_GLOBAL, pcs_gpt.base); | 211 | writel(TIMER_ME_GLOBAL, pcs_gpt.base); |
diff --git a/drivers/clocksource/timer-atmel-pit.c b/drivers/clocksource/timer-atmel-pit.c index 1ffac0cb0cb7..7f0f5b26d8c5 100644 --- a/drivers/clocksource/timer-atmel-pit.c +++ b/drivers/clocksource/timer-atmel-pit.c | |||
@@ -240,6 +240,7 @@ static int __init at91sam926x_pit_common_init(struct pit_data *data) | |||
240 | static int __init at91sam926x_pit_dt_init(struct device_node *node) | 240 | static int __init at91sam926x_pit_dt_init(struct device_node *node) |
241 | { | 241 | { |
242 | struct pit_data *data; | 242 | struct pit_data *data; |
243 | int ret; | ||
243 | 244 | ||
244 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 245 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
245 | if (!data) | 246 | if (!data) |
@@ -261,6 +262,12 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node) | |||
261 | return PTR_ERR(data->mck); | 262 | return PTR_ERR(data->mck); |
262 | } | 263 | } |
263 | 264 | ||
265 | ret = clk_prepare_enable(data->mck); | ||
266 | if (ret) { | ||
267 | pr_err("Unable to enable mck\n"); | ||
268 | return ret; | ||
269 | } | ||
270 | |||
264 | /* Get the interrupts property */ | 271 | /* Get the interrupts property */ |
265 | data->irq = irq_of_parse_and_map(node, 0); | 272 | data->irq = irq_of_parse_and_map(node, 0); |
266 | if (!data->irq) { | 273 | if (!data->irq) { |
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index 0bb44d5b5df4..2ee40fd360ca 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c | |||
@@ -74,6 +74,8 @@ static const struct of_device_id machines[] __initconst = { | |||
74 | { .compatible = "ti,omap5", }, | 74 | { .compatible = "ti,omap5", }, |
75 | 75 | ||
76 | { .compatible = "xlnx,zynq-7000", }, | 76 | { .compatible = "xlnx,zynq-7000", }, |
77 | |||
78 | { } | ||
77 | }; | 79 | }; |
78 | 80 | ||
79 | static int __init cpufreq_dt_platdev_init(void) | 81 | static int __init cpufreq_dt_platdev_init(void) |
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 6dc597126b79..b3044219772c 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c | |||
@@ -556,7 +556,10 @@ skip_enc: | |||
556 | 556 | ||
557 | /* Read and write assoclen bytes */ | 557 | /* Read and write assoclen bytes */ |
558 | append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ); | 558 | append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ); |
559 | append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ); | 559 | if (alg->caam.geniv) |
560 | append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM, ivsize); | ||
561 | else | ||
562 | append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ); | ||
560 | 563 | ||
561 | /* Skip assoc data */ | 564 | /* Skip assoc data */ |
562 | append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF); | 565 | append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF); |
@@ -565,6 +568,14 @@ skip_enc: | |||
565 | append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG | | 568 | append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG | |
566 | KEY_VLF); | 569 | KEY_VLF); |
567 | 570 | ||
571 | if (alg->caam.geniv) { | ||
572 | append_seq_load(desc, ivsize, LDST_CLASS_1_CCB | | ||
573 | LDST_SRCDST_BYTE_CONTEXT | | ||
574 | (ctx1_iv_off << LDST_OFFSET_SHIFT)); | ||
575 | append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO | | ||
576 | (ctx1_iv_off << MOVE_OFFSET_SHIFT) | ivsize); | ||
577 | } | ||
578 | |||
568 | /* Load Counter into CONTEXT1 reg */ | 579 | /* Load Counter into CONTEXT1 reg */ |
569 | if (is_rfc3686) | 580 | if (is_rfc3686) |
570 | append_load_imm_u32(desc, be32_to_cpu(1), LDST_IMM | | 581 | append_load_imm_u32(desc, be32_to_cpu(1), LDST_IMM | |
@@ -2150,7 +2161,7 @@ static void init_authenc_job(struct aead_request *req, | |||
2150 | 2161 | ||
2151 | init_aead_job(req, edesc, all_contig, encrypt); | 2162 | init_aead_job(req, edesc, all_contig, encrypt); |
2152 | 2163 | ||
2153 | if (ivsize && (is_rfc3686 || !(alg->caam.geniv && encrypt))) | 2164 | if (ivsize && ((is_rfc3686 && encrypt) || !alg->caam.geniv)) |
2154 | append_load_as_imm(desc, req->iv, ivsize, | 2165 | append_load_as_imm(desc, req->iv, ivsize, |
2155 | LDST_CLASS_1_CCB | | 2166 | LDST_CLASS_1_CCB | |
2156 | LDST_SRCDST_BYTE_CONTEXT | | 2167 | LDST_SRCDST_BYTE_CONTEXT | |
@@ -2537,20 +2548,6 @@ static int aead_decrypt(struct aead_request *req) | |||
2537 | return ret; | 2548 | return ret; |
2538 | } | 2549 | } |
2539 | 2550 | ||
2540 | static int aead_givdecrypt(struct aead_request *req) | ||
2541 | { | ||
2542 | struct crypto_aead *aead = crypto_aead_reqtfm(req); | ||
2543 | unsigned int ivsize = crypto_aead_ivsize(aead); | ||
2544 | |||
2545 | if (req->cryptlen < ivsize) | ||
2546 | return -EINVAL; | ||
2547 | |||
2548 | req->cryptlen -= ivsize; | ||
2549 | req->assoclen += ivsize; | ||
2550 | |||
2551 | return aead_decrypt(req); | ||
2552 | } | ||
2553 | |||
2554 | /* | 2551 | /* |
2555 | * allocate and map the ablkcipher extended descriptor for ablkcipher | 2552 | * allocate and map the ablkcipher extended descriptor for ablkcipher |
2556 | */ | 2553 | */ |
@@ -3210,7 +3207,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3210 | .setkey = aead_setkey, | 3207 | .setkey = aead_setkey, |
3211 | .setauthsize = aead_setauthsize, | 3208 | .setauthsize = aead_setauthsize, |
3212 | .encrypt = aead_encrypt, | 3209 | .encrypt = aead_encrypt, |
3213 | .decrypt = aead_givdecrypt, | 3210 | .decrypt = aead_decrypt, |
3214 | .ivsize = AES_BLOCK_SIZE, | 3211 | .ivsize = AES_BLOCK_SIZE, |
3215 | .maxauthsize = MD5_DIGEST_SIZE, | 3212 | .maxauthsize = MD5_DIGEST_SIZE, |
3216 | }, | 3213 | }, |
@@ -3256,7 +3253,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3256 | .setkey = aead_setkey, | 3253 | .setkey = aead_setkey, |
3257 | .setauthsize = aead_setauthsize, | 3254 | .setauthsize = aead_setauthsize, |
3258 | .encrypt = aead_encrypt, | 3255 | .encrypt = aead_encrypt, |
3259 | .decrypt = aead_givdecrypt, | 3256 | .decrypt = aead_decrypt, |
3260 | .ivsize = AES_BLOCK_SIZE, | 3257 | .ivsize = AES_BLOCK_SIZE, |
3261 | .maxauthsize = SHA1_DIGEST_SIZE, | 3258 | .maxauthsize = SHA1_DIGEST_SIZE, |
3262 | }, | 3259 | }, |
@@ -3302,7 +3299,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3302 | .setkey = aead_setkey, | 3299 | .setkey = aead_setkey, |
3303 | .setauthsize = aead_setauthsize, | 3300 | .setauthsize = aead_setauthsize, |
3304 | .encrypt = aead_encrypt, | 3301 | .encrypt = aead_encrypt, |
3305 | .decrypt = aead_givdecrypt, | 3302 | .decrypt = aead_decrypt, |
3306 | .ivsize = AES_BLOCK_SIZE, | 3303 | .ivsize = AES_BLOCK_SIZE, |
3307 | .maxauthsize = SHA224_DIGEST_SIZE, | 3304 | .maxauthsize = SHA224_DIGEST_SIZE, |
3308 | }, | 3305 | }, |
@@ -3348,7 +3345,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3348 | .setkey = aead_setkey, | 3345 | .setkey = aead_setkey, |
3349 | .setauthsize = aead_setauthsize, | 3346 | .setauthsize = aead_setauthsize, |
3350 | .encrypt = aead_encrypt, | 3347 | .encrypt = aead_encrypt, |
3351 | .decrypt = aead_givdecrypt, | 3348 | .decrypt = aead_decrypt, |
3352 | .ivsize = AES_BLOCK_SIZE, | 3349 | .ivsize = AES_BLOCK_SIZE, |
3353 | .maxauthsize = SHA256_DIGEST_SIZE, | 3350 | .maxauthsize = SHA256_DIGEST_SIZE, |
3354 | }, | 3351 | }, |
@@ -3394,7 +3391,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3394 | .setkey = aead_setkey, | 3391 | .setkey = aead_setkey, |
3395 | .setauthsize = aead_setauthsize, | 3392 | .setauthsize = aead_setauthsize, |
3396 | .encrypt = aead_encrypt, | 3393 | .encrypt = aead_encrypt, |
3397 | .decrypt = aead_givdecrypt, | 3394 | .decrypt = aead_decrypt, |
3398 | .ivsize = AES_BLOCK_SIZE, | 3395 | .ivsize = AES_BLOCK_SIZE, |
3399 | .maxauthsize = SHA384_DIGEST_SIZE, | 3396 | .maxauthsize = SHA384_DIGEST_SIZE, |
3400 | }, | 3397 | }, |
@@ -3440,7 +3437,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3440 | .setkey = aead_setkey, | 3437 | .setkey = aead_setkey, |
3441 | .setauthsize = aead_setauthsize, | 3438 | .setauthsize = aead_setauthsize, |
3442 | .encrypt = aead_encrypt, | 3439 | .encrypt = aead_encrypt, |
3443 | .decrypt = aead_givdecrypt, | 3440 | .decrypt = aead_decrypt, |
3444 | .ivsize = AES_BLOCK_SIZE, | 3441 | .ivsize = AES_BLOCK_SIZE, |
3445 | .maxauthsize = SHA512_DIGEST_SIZE, | 3442 | .maxauthsize = SHA512_DIGEST_SIZE, |
3446 | }, | 3443 | }, |
@@ -3486,7 +3483,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3486 | .setkey = aead_setkey, | 3483 | .setkey = aead_setkey, |
3487 | .setauthsize = aead_setauthsize, | 3484 | .setauthsize = aead_setauthsize, |
3488 | .encrypt = aead_encrypt, | 3485 | .encrypt = aead_encrypt, |
3489 | .decrypt = aead_givdecrypt, | 3486 | .decrypt = aead_decrypt, |
3490 | .ivsize = DES3_EDE_BLOCK_SIZE, | 3487 | .ivsize = DES3_EDE_BLOCK_SIZE, |
3491 | .maxauthsize = MD5_DIGEST_SIZE, | 3488 | .maxauthsize = MD5_DIGEST_SIZE, |
3492 | }, | 3489 | }, |
@@ -3534,7 +3531,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3534 | .setkey = aead_setkey, | 3531 | .setkey = aead_setkey, |
3535 | .setauthsize = aead_setauthsize, | 3532 | .setauthsize = aead_setauthsize, |
3536 | .encrypt = aead_encrypt, | 3533 | .encrypt = aead_encrypt, |
3537 | .decrypt = aead_givdecrypt, | 3534 | .decrypt = aead_decrypt, |
3538 | .ivsize = DES3_EDE_BLOCK_SIZE, | 3535 | .ivsize = DES3_EDE_BLOCK_SIZE, |
3539 | .maxauthsize = SHA1_DIGEST_SIZE, | 3536 | .maxauthsize = SHA1_DIGEST_SIZE, |
3540 | }, | 3537 | }, |
@@ -3582,7 +3579,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3582 | .setkey = aead_setkey, | 3579 | .setkey = aead_setkey, |
3583 | .setauthsize = aead_setauthsize, | 3580 | .setauthsize = aead_setauthsize, |
3584 | .encrypt = aead_encrypt, | 3581 | .encrypt = aead_encrypt, |
3585 | .decrypt = aead_givdecrypt, | 3582 | .decrypt = aead_decrypt, |
3586 | .ivsize = DES3_EDE_BLOCK_SIZE, | 3583 | .ivsize = DES3_EDE_BLOCK_SIZE, |
3587 | .maxauthsize = SHA224_DIGEST_SIZE, | 3584 | .maxauthsize = SHA224_DIGEST_SIZE, |
3588 | }, | 3585 | }, |
@@ -3630,7 +3627,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3630 | .setkey = aead_setkey, | 3627 | .setkey = aead_setkey, |
3631 | .setauthsize = aead_setauthsize, | 3628 | .setauthsize = aead_setauthsize, |
3632 | .encrypt = aead_encrypt, | 3629 | .encrypt = aead_encrypt, |
3633 | .decrypt = aead_givdecrypt, | 3630 | .decrypt = aead_decrypt, |
3634 | .ivsize = DES3_EDE_BLOCK_SIZE, | 3631 | .ivsize = DES3_EDE_BLOCK_SIZE, |
3635 | .maxauthsize = SHA256_DIGEST_SIZE, | 3632 | .maxauthsize = SHA256_DIGEST_SIZE, |
3636 | }, | 3633 | }, |
@@ -3678,7 +3675,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3678 | .setkey = aead_setkey, | 3675 | .setkey = aead_setkey, |
3679 | .setauthsize = aead_setauthsize, | 3676 | .setauthsize = aead_setauthsize, |
3680 | .encrypt = aead_encrypt, | 3677 | .encrypt = aead_encrypt, |
3681 | .decrypt = aead_givdecrypt, | 3678 | .decrypt = aead_decrypt, |
3682 | .ivsize = DES3_EDE_BLOCK_SIZE, | 3679 | .ivsize = DES3_EDE_BLOCK_SIZE, |
3683 | .maxauthsize = SHA384_DIGEST_SIZE, | 3680 | .maxauthsize = SHA384_DIGEST_SIZE, |
3684 | }, | 3681 | }, |
@@ -3726,7 +3723,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3726 | .setkey = aead_setkey, | 3723 | .setkey = aead_setkey, |
3727 | .setauthsize = aead_setauthsize, | 3724 | .setauthsize = aead_setauthsize, |
3728 | .encrypt = aead_encrypt, | 3725 | .encrypt = aead_encrypt, |
3729 | .decrypt = aead_givdecrypt, | 3726 | .decrypt = aead_decrypt, |
3730 | .ivsize = DES3_EDE_BLOCK_SIZE, | 3727 | .ivsize = DES3_EDE_BLOCK_SIZE, |
3731 | .maxauthsize = SHA512_DIGEST_SIZE, | 3728 | .maxauthsize = SHA512_DIGEST_SIZE, |
3732 | }, | 3729 | }, |
@@ -3772,7 +3769,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3772 | .setkey = aead_setkey, | 3769 | .setkey = aead_setkey, |
3773 | .setauthsize = aead_setauthsize, | 3770 | .setauthsize = aead_setauthsize, |
3774 | .encrypt = aead_encrypt, | 3771 | .encrypt = aead_encrypt, |
3775 | .decrypt = aead_givdecrypt, | 3772 | .decrypt = aead_decrypt, |
3776 | .ivsize = DES_BLOCK_SIZE, | 3773 | .ivsize = DES_BLOCK_SIZE, |
3777 | .maxauthsize = MD5_DIGEST_SIZE, | 3774 | .maxauthsize = MD5_DIGEST_SIZE, |
3778 | }, | 3775 | }, |
@@ -3818,7 +3815,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3818 | .setkey = aead_setkey, | 3815 | .setkey = aead_setkey, |
3819 | .setauthsize = aead_setauthsize, | 3816 | .setauthsize = aead_setauthsize, |
3820 | .encrypt = aead_encrypt, | 3817 | .encrypt = aead_encrypt, |
3821 | .decrypt = aead_givdecrypt, | 3818 | .decrypt = aead_decrypt, |
3822 | .ivsize = DES_BLOCK_SIZE, | 3819 | .ivsize = DES_BLOCK_SIZE, |
3823 | .maxauthsize = SHA1_DIGEST_SIZE, | 3820 | .maxauthsize = SHA1_DIGEST_SIZE, |
3824 | }, | 3821 | }, |
@@ -3864,7 +3861,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3864 | .setkey = aead_setkey, | 3861 | .setkey = aead_setkey, |
3865 | .setauthsize = aead_setauthsize, | 3862 | .setauthsize = aead_setauthsize, |
3866 | .encrypt = aead_encrypt, | 3863 | .encrypt = aead_encrypt, |
3867 | .decrypt = aead_givdecrypt, | 3864 | .decrypt = aead_decrypt, |
3868 | .ivsize = DES_BLOCK_SIZE, | 3865 | .ivsize = DES_BLOCK_SIZE, |
3869 | .maxauthsize = SHA224_DIGEST_SIZE, | 3866 | .maxauthsize = SHA224_DIGEST_SIZE, |
3870 | }, | 3867 | }, |
@@ -3910,7 +3907,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3910 | .setkey = aead_setkey, | 3907 | .setkey = aead_setkey, |
3911 | .setauthsize = aead_setauthsize, | 3908 | .setauthsize = aead_setauthsize, |
3912 | .encrypt = aead_encrypt, | 3909 | .encrypt = aead_encrypt, |
3913 | .decrypt = aead_givdecrypt, | 3910 | .decrypt = aead_decrypt, |
3914 | .ivsize = DES_BLOCK_SIZE, | 3911 | .ivsize = DES_BLOCK_SIZE, |
3915 | .maxauthsize = SHA256_DIGEST_SIZE, | 3912 | .maxauthsize = SHA256_DIGEST_SIZE, |
3916 | }, | 3913 | }, |
@@ -3956,7 +3953,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
3956 | .setkey = aead_setkey, | 3953 | .setkey = aead_setkey, |
3957 | .setauthsize = aead_setauthsize, | 3954 | .setauthsize = aead_setauthsize, |
3958 | .encrypt = aead_encrypt, | 3955 | .encrypt = aead_encrypt, |
3959 | .decrypt = aead_givdecrypt, | 3956 | .decrypt = aead_decrypt, |
3960 | .ivsize = DES_BLOCK_SIZE, | 3957 | .ivsize = DES_BLOCK_SIZE, |
3961 | .maxauthsize = SHA384_DIGEST_SIZE, | 3958 | .maxauthsize = SHA384_DIGEST_SIZE, |
3962 | }, | 3959 | }, |
@@ -4002,7 +3999,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
4002 | .setkey = aead_setkey, | 3999 | .setkey = aead_setkey, |
4003 | .setauthsize = aead_setauthsize, | 4000 | .setauthsize = aead_setauthsize, |
4004 | .encrypt = aead_encrypt, | 4001 | .encrypt = aead_encrypt, |
4005 | .decrypt = aead_givdecrypt, | 4002 | .decrypt = aead_decrypt, |
4006 | .ivsize = DES_BLOCK_SIZE, | 4003 | .ivsize = DES_BLOCK_SIZE, |
4007 | .maxauthsize = SHA512_DIGEST_SIZE, | 4004 | .maxauthsize = SHA512_DIGEST_SIZE, |
4008 | }, | 4005 | }, |
@@ -4051,7 +4048,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
4051 | .setkey = aead_setkey, | 4048 | .setkey = aead_setkey, |
4052 | .setauthsize = aead_setauthsize, | 4049 | .setauthsize = aead_setauthsize, |
4053 | .encrypt = aead_encrypt, | 4050 | .encrypt = aead_encrypt, |
4054 | .decrypt = aead_givdecrypt, | 4051 | .decrypt = aead_decrypt, |
4055 | .ivsize = CTR_RFC3686_IV_SIZE, | 4052 | .ivsize = CTR_RFC3686_IV_SIZE, |
4056 | .maxauthsize = MD5_DIGEST_SIZE, | 4053 | .maxauthsize = MD5_DIGEST_SIZE, |
4057 | }, | 4054 | }, |
@@ -4102,7 +4099,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
4102 | .setkey = aead_setkey, | 4099 | .setkey = aead_setkey, |
4103 | .setauthsize = aead_setauthsize, | 4100 | .setauthsize = aead_setauthsize, |
4104 | .encrypt = aead_encrypt, | 4101 | .encrypt = aead_encrypt, |
4105 | .decrypt = aead_givdecrypt, | 4102 | .decrypt = aead_decrypt, |
4106 | .ivsize = CTR_RFC3686_IV_SIZE, | 4103 | .ivsize = CTR_RFC3686_IV_SIZE, |
4107 | .maxauthsize = SHA1_DIGEST_SIZE, | 4104 | .maxauthsize = SHA1_DIGEST_SIZE, |
4108 | }, | 4105 | }, |
@@ -4153,7 +4150,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
4153 | .setkey = aead_setkey, | 4150 | .setkey = aead_setkey, |
4154 | .setauthsize = aead_setauthsize, | 4151 | .setauthsize = aead_setauthsize, |
4155 | .encrypt = aead_encrypt, | 4152 | .encrypt = aead_encrypt, |
4156 | .decrypt = aead_givdecrypt, | 4153 | .decrypt = aead_decrypt, |
4157 | .ivsize = CTR_RFC3686_IV_SIZE, | 4154 | .ivsize = CTR_RFC3686_IV_SIZE, |
4158 | .maxauthsize = SHA224_DIGEST_SIZE, | 4155 | .maxauthsize = SHA224_DIGEST_SIZE, |
4159 | }, | 4156 | }, |
@@ -4204,7 +4201,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
4204 | .setkey = aead_setkey, | 4201 | .setkey = aead_setkey, |
4205 | .setauthsize = aead_setauthsize, | 4202 | .setauthsize = aead_setauthsize, |
4206 | .encrypt = aead_encrypt, | 4203 | .encrypt = aead_encrypt, |
4207 | .decrypt = aead_givdecrypt, | 4204 | .decrypt = aead_decrypt, |
4208 | .ivsize = CTR_RFC3686_IV_SIZE, | 4205 | .ivsize = CTR_RFC3686_IV_SIZE, |
4209 | .maxauthsize = SHA256_DIGEST_SIZE, | 4206 | .maxauthsize = SHA256_DIGEST_SIZE, |
4210 | }, | 4207 | }, |
@@ -4255,7 +4252,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
4255 | .setkey = aead_setkey, | 4252 | .setkey = aead_setkey, |
4256 | .setauthsize = aead_setauthsize, | 4253 | .setauthsize = aead_setauthsize, |
4257 | .encrypt = aead_encrypt, | 4254 | .encrypt = aead_encrypt, |
4258 | .decrypt = aead_givdecrypt, | 4255 | .decrypt = aead_decrypt, |
4259 | .ivsize = CTR_RFC3686_IV_SIZE, | 4256 | .ivsize = CTR_RFC3686_IV_SIZE, |
4260 | .maxauthsize = SHA384_DIGEST_SIZE, | 4257 | .maxauthsize = SHA384_DIGEST_SIZE, |
4261 | }, | 4258 | }, |
@@ -4306,7 +4303,7 @@ static struct caam_aead_alg driver_aeads[] = { | |||
4306 | .setkey = aead_setkey, | 4303 | .setkey = aead_setkey, |
4307 | .setauthsize = aead_setauthsize, | 4304 | .setauthsize = aead_setauthsize, |
4308 | .encrypt = aead_encrypt, | 4305 | .encrypt = aead_encrypt, |
4309 | .decrypt = aead_givdecrypt, | 4306 | .decrypt = aead_decrypt, |
4310 | .ivsize = CTR_RFC3686_IV_SIZE, | 4307 | .ivsize = CTR_RFC3686_IV_SIZE, |
4311 | .maxauthsize = SHA512_DIGEST_SIZE, | 4308 | .maxauthsize = SHA512_DIGEST_SIZE, |
4312 | }, | 4309 | }, |
diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c index 769148dbaeb3..20f35df8a01f 100644 --- a/drivers/crypto/qat/qat_common/qat_algs.c +++ b/drivers/crypto/qat/qat_common/qat_algs.c | |||
@@ -1260,8 +1260,8 @@ static struct crypto_alg qat_algs[] = { { | |||
1260 | .setkey = qat_alg_ablkcipher_xts_setkey, | 1260 | .setkey = qat_alg_ablkcipher_xts_setkey, |
1261 | .decrypt = qat_alg_ablkcipher_decrypt, | 1261 | .decrypt = qat_alg_ablkcipher_decrypt, |
1262 | .encrypt = qat_alg_ablkcipher_encrypt, | 1262 | .encrypt = qat_alg_ablkcipher_encrypt, |
1263 | .min_keysize = AES_MIN_KEY_SIZE, | 1263 | .min_keysize = 2 * AES_MIN_KEY_SIZE, |
1264 | .max_keysize = AES_MAX_KEY_SIZE, | 1264 | .max_keysize = 2 * AES_MAX_KEY_SIZE, |
1265 | .ivsize = AES_BLOCK_SIZE, | 1265 | .ivsize = AES_BLOCK_SIZE, |
1266 | }, | 1266 | }, |
1267 | }, | 1267 | }, |
diff --git a/drivers/crypto/vmx/aes_xts.c b/drivers/crypto/vmx/aes_xts.c index cfb25413917c..24353ec336c5 100644 --- a/drivers/crypto/vmx/aes_xts.c +++ b/drivers/crypto/vmx/aes_xts.c | |||
@@ -129,8 +129,8 @@ static int p8_aes_xts_crypt(struct blkcipher_desc *desc, | |||
129 | 129 | ||
130 | blkcipher_walk_init(&walk, dst, src, nbytes); | 130 | blkcipher_walk_init(&walk, dst, src, nbytes); |
131 | 131 | ||
132 | iv = (u8 *)walk.iv; | ||
133 | ret = blkcipher_walk_virt(desc, &walk); | 132 | ret = blkcipher_walk_virt(desc, &walk); |
133 | iv = walk.iv; | ||
134 | memset(tweak, 0, AES_BLOCK_SIZE); | 134 | memset(tweak, 0, AES_BLOCK_SIZE); |
135 | aes_p8_encrypt(iv, tweak, &ctx->tweak_key); | 135 | aes_p8_encrypt(iv, tweak, &ctx->tweak_key); |
136 | 136 | ||
diff --git a/drivers/dax/dax.c b/drivers/dax/dax.c index 803f3953b341..29f600f2c447 100644 --- a/drivers/dax/dax.c +++ b/drivers/dax/dax.c | |||
@@ -459,7 +459,7 @@ static int __dax_dev_pmd_fault(struct dax_dev *dax_dev, | |||
459 | } | 459 | } |
460 | 460 | ||
461 | pgoff = linear_page_index(vma, pmd_addr); | 461 | pgoff = linear_page_index(vma, pmd_addr); |
462 | phys = pgoff_to_phys(dax_dev, pgoff, PAGE_SIZE); | 462 | phys = pgoff_to_phys(dax_dev, pgoff, PMD_SIZE); |
463 | if (phys == -1) { | 463 | if (phys == -1) { |
464 | dev_dbg(dev, "%s: phys_to_pgoff(%#lx) failed\n", __func__, | 464 | dev_dbg(dev, "%s: phys_to_pgoff(%#lx) failed\n", __func__, |
465 | pgoff); | 465 | pgoff); |
diff --git a/drivers/dax/pmem.c b/drivers/dax/pmem.c index dfb168568af1..1f01e98c83c7 100644 --- a/drivers/dax/pmem.c +++ b/drivers/dax/pmem.c | |||
@@ -116,6 +116,9 @@ static int dax_pmem_probe(struct device *dev) | |||
116 | if (rc) | 116 | if (rc) |
117 | return rc; | 117 | return rc; |
118 | 118 | ||
119 | /* adjust the dax_region resource to the start of data */ | ||
120 | res.start += le64_to_cpu(pfn_sb->dataoff); | ||
121 | |||
119 | nd_region = to_nd_region(dev->parent); | 122 | nd_region = to_nd_region(dev->parent); |
120 | dax_region = alloc_dax_region(dev, nd_region->id, &res, | 123 | dax_region = alloc_dax_region(dev, nd_region->id, &res, |
121 | le32_to_cpu(pfn_sb->align), addr, PFN_DEV|PFN_MAP); | 124 | le32_to_cpu(pfn_sb->align), addr, PFN_DEV|PFN_MAP); |
diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index e434ffe7bc5c..832cbd647145 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c | |||
@@ -2067,7 +2067,7 @@ err_dma_unregister: | |||
2067 | err_clk_disable: | 2067 | err_clk_disable: |
2068 | clk_disable_unprepare(atxdmac->clk); | 2068 | clk_disable_unprepare(atxdmac->clk); |
2069 | err_free_irq: | 2069 | err_free_irq: |
2070 | free_irq(atxdmac->irq, atxdmac->dma.dev); | 2070 | free_irq(atxdmac->irq, atxdmac); |
2071 | return ret; | 2071 | return ret; |
2072 | } | 2072 | } |
2073 | 2073 | ||
@@ -2081,7 +2081,7 @@ static int at_xdmac_remove(struct platform_device *pdev) | |||
2081 | dma_async_device_unregister(&atxdmac->dma); | 2081 | dma_async_device_unregister(&atxdmac->dma); |
2082 | clk_disable_unprepare(atxdmac->clk); | 2082 | clk_disable_unprepare(atxdmac->clk); |
2083 | 2083 | ||
2084 | free_irq(atxdmac->irq, atxdmac->dma.dev); | 2084 | free_irq(atxdmac->irq, atxdmac); |
2085 | 2085 | ||
2086 | for (i = 0; i < atxdmac->dma.chancnt; i++) { | 2086 | for (i = 0; i < atxdmac->dma.chancnt; i++) { |
2087 | struct at_xdmac_chan *atchan = &atxdmac->chan[i]; | 2087 | struct at_xdmac_chan *atchan = &atxdmac->chan[i]; |
diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c index aad167eaaee8..de2a2a2b1d75 100644 --- a/drivers/dma/fsl_raid.c +++ b/drivers/dma/fsl_raid.c | |||
@@ -836,6 +836,7 @@ static int fsl_re_probe(struct platform_device *ofdev) | |||
836 | rc = of_property_read_u32(np, "reg", &off); | 836 | rc = of_property_read_u32(np, "reg", &off); |
837 | if (rc) { | 837 | if (rc) { |
838 | dev_err(dev, "Reg property not found in JQ node\n"); | 838 | dev_err(dev, "Reg property not found in JQ node\n"); |
839 | of_node_put(np); | ||
839 | return -ENODEV; | 840 | return -ENODEV; |
840 | } | 841 | } |
841 | /* Find out the Job Rings present under each JQ */ | 842 | /* Find out the Job Rings present under each JQ */ |
diff --git a/drivers/dma/img-mdc-dma.c b/drivers/dma/img-mdc-dma.c index a4c53be482cf..624f1e1e9c55 100644 --- a/drivers/dma/img-mdc-dma.c +++ b/drivers/dma/img-mdc-dma.c | |||
@@ -861,7 +861,6 @@ static int mdc_dma_probe(struct platform_device *pdev) | |||
861 | { | 861 | { |
862 | struct mdc_dma *mdma; | 862 | struct mdc_dma *mdma; |
863 | struct resource *res; | 863 | struct resource *res; |
864 | const struct of_device_id *match; | ||
865 | unsigned int i; | 864 | unsigned int i; |
866 | u32 val; | 865 | u32 val; |
867 | int ret; | 866 | int ret; |
@@ -871,8 +870,7 @@ static int mdc_dma_probe(struct platform_device *pdev) | |||
871 | return -ENOMEM; | 870 | return -ENOMEM; |
872 | platform_set_drvdata(pdev, mdma); | 871 | platform_set_drvdata(pdev, mdma); |
873 | 872 | ||
874 | match = of_match_device(mdc_dma_of_match, &pdev->dev); | 873 | mdma->soc = of_device_get_match_data(&pdev->dev); |
875 | mdma->soc = match->data; | ||
876 | 874 | ||
877 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 875 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
878 | mdma->regs = devm_ioremap_resource(&pdev->dev, res); | 876 | mdma->regs = devm_ioremap_resource(&pdev->dev, res); |
diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c index dc7850a422b8..3f56f9ca4482 100644 --- a/drivers/dma/pxa_dma.c +++ b/drivers/dma/pxa_dma.c | |||
@@ -638,7 +638,7 @@ static bool pxad_try_hotchain(struct virt_dma_chan *vc, | |||
638 | vd_last_issued = list_entry(vc->desc_issued.prev, | 638 | vd_last_issued = list_entry(vc->desc_issued.prev, |
639 | struct virt_dma_desc, node); | 639 | struct virt_dma_desc, node); |
640 | pxad_desc_chain(vd_last_issued, vd); | 640 | pxad_desc_chain(vd_last_issued, vd); |
641 | if (is_chan_running(chan) || is_desc_completed(vd_last_issued)) | 641 | if (is_chan_running(chan) || is_desc_completed(vd)) |
642 | return true; | 642 | return true; |
643 | } | 643 | } |
644 | 644 | ||
@@ -671,6 +671,7 @@ static irqreturn_t pxad_chan_handler(int irq, void *dev_id) | |||
671 | struct virt_dma_desc *vd, *tmp; | 671 | struct virt_dma_desc *vd, *tmp; |
672 | unsigned int dcsr; | 672 | unsigned int dcsr; |
673 | unsigned long flags; | 673 | unsigned long flags; |
674 | bool vd_completed; | ||
674 | dma_cookie_t last_started = 0; | 675 | dma_cookie_t last_started = 0; |
675 | 676 | ||
676 | BUG_ON(!chan); | 677 | BUG_ON(!chan); |
@@ -681,15 +682,17 @@ static irqreturn_t pxad_chan_handler(int irq, void *dev_id) | |||
681 | 682 | ||
682 | spin_lock_irqsave(&chan->vc.lock, flags); | 683 | spin_lock_irqsave(&chan->vc.lock, flags); |
683 | list_for_each_entry_safe(vd, tmp, &chan->vc.desc_issued, node) { | 684 | list_for_each_entry_safe(vd, tmp, &chan->vc.desc_issued, node) { |
685 | vd_completed = is_desc_completed(vd); | ||
684 | dev_dbg(&chan->vc.chan.dev->device, | 686 | dev_dbg(&chan->vc.chan.dev->device, |
685 | "%s(): checking txd %p[%x]: completed=%d\n", | 687 | "%s(): checking txd %p[%x]: completed=%d dcsr=0x%x\n", |
686 | __func__, vd, vd->tx.cookie, is_desc_completed(vd)); | 688 | __func__, vd, vd->tx.cookie, vd_completed, |
689 | dcsr); | ||
687 | last_started = vd->tx.cookie; | 690 | last_started = vd->tx.cookie; |
688 | if (to_pxad_sw_desc(vd)->cyclic) { | 691 | if (to_pxad_sw_desc(vd)->cyclic) { |
689 | vchan_cyclic_callback(vd); | 692 | vchan_cyclic_callback(vd); |
690 | break; | 693 | break; |
691 | } | 694 | } |
692 | if (is_desc_completed(vd)) { | 695 | if (vd_completed) { |
693 | list_del(&vd->node); | 696 | list_del(&vd->node); |
694 | vchan_cookie_complete(vd); | 697 | vchan_cookie_complete(vd); |
695 | } else { | 698 | } else { |
diff --git a/drivers/dma/sh/usb-dmac.c b/drivers/dma/sh/usb-dmac.c index 749f1bd5d65d..06ecdc38cee0 100644 --- a/drivers/dma/sh/usb-dmac.c +++ b/drivers/dma/sh/usb-dmac.c | |||
@@ -600,27 +600,30 @@ static irqreturn_t usb_dmac_isr_channel(int irq, void *dev) | |||
600 | { | 600 | { |
601 | struct usb_dmac_chan *chan = dev; | 601 | struct usb_dmac_chan *chan = dev; |
602 | irqreturn_t ret = IRQ_NONE; | 602 | irqreturn_t ret = IRQ_NONE; |
603 | u32 mask = USB_DMACHCR_TE; | 603 | u32 mask = 0; |
604 | u32 check_bits = USB_DMACHCR_TE | USB_DMACHCR_SP; | ||
605 | u32 chcr; | 604 | u32 chcr; |
605 | bool xfer_end = false; | ||
606 | 606 | ||
607 | spin_lock(&chan->vc.lock); | 607 | spin_lock(&chan->vc.lock); |
608 | 608 | ||
609 | chcr = usb_dmac_chan_read(chan, USB_DMACHCR); | 609 | chcr = usb_dmac_chan_read(chan, USB_DMACHCR); |
610 | if (chcr & check_bits) | 610 | if (chcr & (USB_DMACHCR_TE | USB_DMACHCR_SP)) { |
611 | mask |= USB_DMACHCR_DE | check_bits; | 611 | mask |= USB_DMACHCR_DE | USB_DMACHCR_TE | USB_DMACHCR_SP; |
612 | if (chcr & USB_DMACHCR_DE) | ||
613 | xfer_end = true; | ||
614 | ret |= IRQ_HANDLED; | ||
615 | } | ||
612 | if (chcr & USB_DMACHCR_NULL) { | 616 | if (chcr & USB_DMACHCR_NULL) { |
613 | /* An interruption of TE will happen after we set FTE */ | 617 | /* An interruption of TE will happen after we set FTE */ |
614 | mask |= USB_DMACHCR_NULL; | 618 | mask |= USB_DMACHCR_NULL; |
615 | chcr |= USB_DMACHCR_FTE; | 619 | chcr |= USB_DMACHCR_FTE; |
616 | ret |= IRQ_HANDLED; | 620 | ret |= IRQ_HANDLED; |
617 | } | 621 | } |
618 | usb_dmac_chan_write(chan, USB_DMACHCR, chcr & ~mask); | 622 | if (mask) |
623 | usb_dmac_chan_write(chan, USB_DMACHCR, chcr & ~mask); | ||
619 | 624 | ||
620 | if (chcr & check_bits) { | 625 | if (xfer_end) |
621 | usb_dmac_isr_transfer_end(chan); | 626 | usb_dmac_isr_transfer_end(chan); |
622 | ret |= IRQ_HANDLED; | ||
623 | } | ||
624 | 627 | ||
625 | spin_unlock(&chan->vc.lock); | 628 | spin_unlock(&chan->vc.lock); |
626 | 629 | ||
diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 438893762076..ce2bc2a38101 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c | |||
@@ -709,9 +709,10 @@ static int scpi_probe(struct platform_device *pdev) | |||
709 | struct mbox_client *cl = &pchan->cl; | 709 | struct mbox_client *cl = &pchan->cl; |
710 | struct device_node *shmem = of_parse_phandle(np, "shmem", idx); | 710 | struct device_node *shmem = of_parse_phandle(np, "shmem", idx); |
711 | 711 | ||
712 | if (of_address_to_resource(shmem, 0, &res)) { | 712 | ret = of_address_to_resource(shmem, 0, &res); |
713 | of_node_put(shmem); | ||
714 | if (ret) { | ||
713 | dev_err(dev, "failed to get SCPI payload mem resource\n"); | 715 | dev_err(dev, "failed to get SCPI payload mem resource\n"); |
714 | ret = -EINVAL; | ||
715 | goto err; | 716 | goto err; |
716 | } | 717 | } |
717 | 718 | ||
diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c index 94a58a082b99..44c01390d035 100644 --- a/drivers/firmware/dmi-id.c +++ b/drivers/firmware/dmi-id.c | |||
@@ -229,14 +229,14 @@ static int __init dmi_id_init(void) | |||
229 | 229 | ||
230 | ret = device_register(dmi_dev); | 230 | ret = device_register(dmi_dev); |
231 | if (ret) | 231 | if (ret) |
232 | goto fail_free_dmi_dev; | 232 | goto fail_put_dmi_dev; |
233 | 233 | ||
234 | return 0; | 234 | return 0; |
235 | 235 | ||
236 | fail_free_dmi_dev: | 236 | fail_put_dmi_dev: |
237 | kfree(dmi_dev); | 237 | put_device(dmi_dev); |
238 | fail_class_unregister: | ||
239 | 238 | ||
239 | fail_class_unregister: | ||
240 | class_unregister(&dmi_class); | 240 | class_unregister(&dmi_class); |
241 | 241 | ||
242 | return ret; | 242 | return ret; |
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 5a2631af7410..7dd2e2d37231 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c | |||
@@ -657,9 +657,12 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname, | |||
657 | } | 657 | } |
658 | 658 | ||
659 | if (subnode) { | 659 | if (subnode) { |
660 | node = of_get_flat_dt_subnode_by_name(node, subnode); | 660 | int err = of_get_flat_dt_subnode_by_name(node, subnode); |
661 | if (node < 0) | 661 | |
662 | if (err < 0) | ||
662 | return 0; | 663 | return 0; |
664 | |||
665 | node = err; | ||
663 | } | 666 | } |
664 | 667 | ||
665 | return __find_uefi_params(node, info, dt_params[i].params); | 668 | return __find_uefi_params(node, info, dt_params[i].params); |
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 3bd127f95315..aded10662020 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c | |||
@@ -41,6 +41,8 @@ static unsigned long __chunk_size = EFI_READ_CHUNK_SIZE; | |||
41 | #define EFI_ALLOC_ALIGN EFI_PAGE_SIZE | 41 | #define EFI_ALLOC_ALIGN EFI_PAGE_SIZE |
42 | #endif | 42 | #endif |
43 | 43 | ||
44 | #define EFI_MMAP_NR_SLACK_SLOTS 8 | ||
45 | |||
44 | struct file_info { | 46 | struct file_info { |
45 | efi_file_handle_t *handle; | 47 | efi_file_handle_t *handle; |
46 | u64 size; | 48 | u64 size; |
@@ -63,49 +65,62 @@ void efi_printk(efi_system_table_t *sys_table_arg, char *str) | |||
63 | } | 65 | } |
64 | } | 66 | } |
65 | 67 | ||
68 | static inline bool mmap_has_headroom(unsigned long buff_size, | ||
69 | unsigned long map_size, | ||
70 | unsigned long desc_size) | ||
71 | { | ||
72 | unsigned long slack = buff_size - map_size; | ||
73 | |||
74 | return slack / desc_size >= EFI_MMAP_NR_SLACK_SLOTS; | ||
75 | } | ||
76 | |||
66 | efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg, | 77 | efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg, |
67 | efi_memory_desc_t **map, | 78 | struct efi_boot_memmap *map) |
68 | unsigned long *map_size, | ||
69 | unsigned long *desc_size, | ||
70 | u32 *desc_ver, | ||
71 | unsigned long *key_ptr) | ||
72 | { | 79 | { |
73 | efi_memory_desc_t *m = NULL; | 80 | efi_memory_desc_t *m = NULL; |
74 | efi_status_t status; | 81 | efi_status_t status; |
75 | unsigned long key; | 82 | unsigned long key; |
76 | u32 desc_version; | 83 | u32 desc_version; |
77 | 84 | ||
78 | *map_size = sizeof(*m) * 32; | 85 | *map->desc_size = sizeof(*m); |
86 | *map->map_size = *map->desc_size * 32; | ||
87 | *map->buff_size = *map->map_size; | ||
79 | again: | 88 | again: |
80 | /* | ||
81 | * Add an additional efi_memory_desc_t because we're doing an | ||
82 | * allocation which may be in a new descriptor region. | ||
83 | */ | ||
84 | *map_size += sizeof(*m); | ||
85 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, | 89 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, |
86 | *map_size, (void **)&m); | 90 | *map->map_size, (void **)&m); |
87 | if (status != EFI_SUCCESS) | 91 | if (status != EFI_SUCCESS) |
88 | goto fail; | 92 | goto fail; |
89 | 93 | ||
90 | *desc_size = 0; | 94 | *map->desc_size = 0; |
91 | key = 0; | 95 | key = 0; |
92 | status = efi_call_early(get_memory_map, map_size, m, | 96 | status = efi_call_early(get_memory_map, map->map_size, m, |
93 | &key, desc_size, &desc_version); | 97 | &key, map->desc_size, &desc_version); |
94 | if (status == EFI_BUFFER_TOO_SMALL) { | 98 | if (status == EFI_BUFFER_TOO_SMALL || |
99 | !mmap_has_headroom(*map->buff_size, *map->map_size, | ||
100 | *map->desc_size)) { | ||
95 | efi_call_early(free_pool, m); | 101 | efi_call_early(free_pool, m); |
102 | /* | ||
103 | * Make sure there is some entries of headroom so that the | ||
104 | * buffer can be reused for a new map after allocations are | ||
105 | * no longer permitted. Its unlikely that the map will grow to | ||
106 | * exceed this headroom once we are ready to trigger | ||
107 | * ExitBootServices() | ||
108 | */ | ||
109 | *map->map_size += *map->desc_size * EFI_MMAP_NR_SLACK_SLOTS; | ||
110 | *map->buff_size = *map->map_size; | ||
96 | goto again; | 111 | goto again; |
97 | } | 112 | } |
98 | 113 | ||
99 | if (status != EFI_SUCCESS) | 114 | if (status != EFI_SUCCESS) |
100 | efi_call_early(free_pool, m); | 115 | efi_call_early(free_pool, m); |
101 | 116 | ||
102 | if (key_ptr && status == EFI_SUCCESS) | 117 | if (map->key_ptr && status == EFI_SUCCESS) |
103 | *key_ptr = key; | 118 | *map->key_ptr = key; |
104 | if (desc_ver && status == EFI_SUCCESS) | 119 | if (map->desc_ver && status == EFI_SUCCESS) |
105 | *desc_ver = desc_version; | 120 | *map->desc_ver = desc_version; |
106 | 121 | ||
107 | fail: | 122 | fail: |
108 | *map = m; | 123 | *map->map = m; |
109 | return status; | 124 | return status; |
110 | } | 125 | } |
111 | 126 | ||
@@ -113,13 +128,20 @@ fail: | |||
113 | unsigned long get_dram_base(efi_system_table_t *sys_table_arg) | 128 | unsigned long get_dram_base(efi_system_table_t *sys_table_arg) |
114 | { | 129 | { |
115 | efi_status_t status; | 130 | efi_status_t status; |
116 | unsigned long map_size; | 131 | unsigned long map_size, buff_size; |
117 | unsigned long membase = EFI_ERROR; | 132 | unsigned long membase = EFI_ERROR; |
118 | struct efi_memory_map map; | 133 | struct efi_memory_map map; |
119 | efi_memory_desc_t *md; | 134 | efi_memory_desc_t *md; |
135 | struct efi_boot_memmap boot_map; | ||
120 | 136 | ||
121 | status = efi_get_memory_map(sys_table_arg, (efi_memory_desc_t **)&map.map, | 137 | boot_map.map = (efi_memory_desc_t **)&map.map; |
122 | &map_size, &map.desc_size, NULL, NULL); | 138 | boot_map.map_size = &map_size; |
139 | boot_map.desc_size = &map.desc_size; | ||
140 | boot_map.desc_ver = NULL; | ||
141 | boot_map.key_ptr = NULL; | ||
142 | boot_map.buff_size = &buff_size; | ||
143 | |||
144 | status = efi_get_memory_map(sys_table_arg, &boot_map); | ||
123 | if (status != EFI_SUCCESS) | 145 | if (status != EFI_SUCCESS) |
124 | return membase; | 146 | return membase; |
125 | 147 | ||
@@ -144,15 +166,22 @@ efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg, | |||
144 | unsigned long size, unsigned long align, | 166 | unsigned long size, unsigned long align, |
145 | unsigned long *addr, unsigned long max) | 167 | unsigned long *addr, unsigned long max) |
146 | { | 168 | { |
147 | unsigned long map_size, desc_size; | 169 | unsigned long map_size, desc_size, buff_size; |
148 | efi_memory_desc_t *map; | 170 | efi_memory_desc_t *map; |
149 | efi_status_t status; | 171 | efi_status_t status; |
150 | unsigned long nr_pages; | 172 | unsigned long nr_pages; |
151 | u64 max_addr = 0; | 173 | u64 max_addr = 0; |
152 | int i; | 174 | int i; |
175 | struct efi_boot_memmap boot_map; | ||
176 | |||
177 | boot_map.map = ↦ | ||
178 | boot_map.map_size = &map_size; | ||
179 | boot_map.desc_size = &desc_size; | ||
180 | boot_map.desc_ver = NULL; | ||
181 | boot_map.key_ptr = NULL; | ||
182 | boot_map.buff_size = &buff_size; | ||
153 | 183 | ||
154 | status = efi_get_memory_map(sys_table_arg, &map, &map_size, &desc_size, | 184 | status = efi_get_memory_map(sys_table_arg, &boot_map); |
155 | NULL, NULL); | ||
156 | if (status != EFI_SUCCESS) | 185 | if (status != EFI_SUCCESS) |
157 | goto fail; | 186 | goto fail; |
158 | 187 | ||
@@ -230,14 +259,21 @@ efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg, | |||
230 | unsigned long size, unsigned long align, | 259 | unsigned long size, unsigned long align, |
231 | unsigned long *addr) | 260 | unsigned long *addr) |
232 | { | 261 | { |
233 | unsigned long map_size, desc_size; | 262 | unsigned long map_size, desc_size, buff_size; |
234 | efi_memory_desc_t *map; | 263 | efi_memory_desc_t *map; |
235 | efi_status_t status; | 264 | efi_status_t status; |
236 | unsigned long nr_pages; | 265 | unsigned long nr_pages; |
237 | int i; | 266 | int i; |
267 | struct efi_boot_memmap boot_map; | ||
238 | 268 | ||
239 | status = efi_get_memory_map(sys_table_arg, &map, &map_size, &desc_size, | 269 | boot_map.map = ↦ |
240 | NULL, NULL); | 270 | boot_map.map_size = &map_size; |
271 | boot_map.desc_size = &desc_size; | ||
272 | boot_map.desc_ver = NULL; | ||
273 | boot_map.key_ptr = NULL; | ||
274 | boot_map.buff_size = &buff_size; | ||
275 | |||
276 | status = efi_get_memory_map(sys_table_arg, &boot_map); | ||
241 | if (status != EFI_SUCCESS) | 277 | if (status != EFI_SUCCESS) |
242 | goto fail; | 278 | goto fail; |
243 | 279 | ||
@@ -704,3 +740,76 @@ char *efi_convert_cmdline(efi_system_table_t *sys_table_arg, | |||
704 | *cmd_line_len = options_bytes; | 740 | *cmd_line_len = options_bytes; |
705 | return (char *)cmdline_addr; | 741 | return (char *)cmdline_addr; |
706 | } | 742 | } |
743 | |||
744 | /* | ||
745 | * Handle calling ExitBootServices according to the requirements set out by the | ||
746 | * spec. Obtains the current memory map, and returns that info after calling | ||
747 | * ExitBootServices. The client must specify a function to perform any | ||
748 | * processing of the memory map data prior to ExitBootServices. A client | ||
749 | * specific structure may be passed to the function via priv. The client | ||
750 | * function may be called multiple times. | ||
751 | */ | ||
752 | efi_status_t efi_exit_boot_services(efi_system_table_t *sys_table_arg, | ||
753 | void *handle, | ||
754 | struct efi_boot_memmap *map, | ||
755 | void *priv, | ||
756 | efi_exit_boot_map_processing priv_func) | ||
757 | { | ||
758 | efi_status_t status; | ||
759 | |||
760 | status = efi_get_memory_map(sys_table_arg, map); | ||
761 | |||
762 | if (status != EFI_SUCCESS) | ||
763 | goto fail; | ||
764 | |||
765 | status = priv_func(sys_table_arg, map, priv); | ||
766 | if (status != EFI_SUCCESS) | ||
767 | goto free_map; | ||
768 | |||
769 | status = efi_call_early(exit_boot_services, handle, *map->key_ptr); | ||
770 | |||
771 | if (status == EFI_INVALID_PARAMETER) { | ||
772 | /* | ||
773 | * The memory map changed between efi_get_memory_map() and | ||
774 | * exit_boot_services(). Per the UEFI Spec v2.6, Section 6.4: | ||
775 | * EFI_BOOT_SERVICES.ExitBootServices we need to get the | ||
776 | * updated map, and try again. The spec implies one retry | ||
777 | * should be sufficent, which is confirmed against the EDK2 | ||
778 | * implementation. Per the spec, we can only invoke | ||
779 | * get_memory_map() and exit_boot_services() - we cannot alloc | ||
780 | * so efi_get_memory_map() cannot be used, and we must reuse | ||
781 | * the buffer. For all practical purposes, the headroom in the | ||
782 | * buffer should account for any changes in the map so the call | ||
783 | * to get_memory_map() is expected to succeed here. | ||
784 | */ | ||
785 | *map->map_size = *map->buff_size; | ||
786 | status = efi_call_early(get_memory_map, | ||
787 | map->map_size, | ||
788 | *map->map, | ||
789 | map->key_ptr, | ||
790 | map->desc_size, | ||
791 | map->desc_ver); | ||
792 | |||
793 | /* exit_boot_services() was called, thus cannot free */ | ||
794 | if (status != EFI_SUCCESS) | ||
795 | goto fail; | ||
796 | |||
797 | status = priv_func(sys_table_arg, map, priv); | ||
798 | /* exit_boot_services() was called, thus cannot free */ | ||
799 | if (status != EFI_SUCCESS) | ||
800 | goto fail; | ||
801 | |||
802 | status = efi_call_early(exit_boot_services, handle, *map->key_ptr); | ||
803 | } | ||
804 | |||
805 | /* exit_boot_services() was called, thus cannot free */ | ||
806 | if (status != EFI_SUCCESS) | ||
807 | goto fail; | ||
808 | |||
809 | return EFI_SUCCESS; | ||
810 | |||
811 | free_map: | ||
812 | efi_call_early(free_pool, *map->map); | ||
813 | fail: | ||
814 | return status; | ||
815 | } | ||
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index e58abfa953cc..a6a93116a8f0 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c | |||
@@ -152,6 +152,27 @@ fdt_set_fail: | |||
152 | #define EFI_FDT_ALIGN EFI_PAGE_SIZE | 152 | #define EFI_FDT_ALIGN EFI_PAGE_SIZE |
153 | #endif | 153 | #endif |
154 | 154 | ||
155 | struct exit_boot_struct { | ||
156 | efi_memory_desc_t *runtime_map; | ||
157 | int *runtime_entry_count; | ||
158 | }; | ||
159 | |||
160 | static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg, | ||
161 | struct efi_boot_memmap *map, | ||
162 | void *priv) | ||
163 | { | ||
164 | struct exit_boot_struct *p = priv; | ||
165 | /* | ||
166 | * Update the memory map with virtual addresses. The function will also | ||
167 | * populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME | ||
168 | * entries so that we can pass it straight to SetVirtualAddressMap() | ||
169 | */ | ||
170 | efi_get_virtmap(*map->map, *map->map_size, *map->desc_size, | ||
171 | p->runtime_map, p->runtime_entry_count); | ||
172 | |||
173 | return EFI_SUCCESS; | ||
174 | } | ||
175 | |||
155 | /* | 176 | /* |
156 | * Allocate memory for a new FDT, then add EFI, commandline, and | 177 | * Allocate memory for a new FDT, then add EFI, commandline, and |
157 | * initrd related fields to the FDT. This routine increases the | 178 | * initrd related fields to the FDT. This routine increases the |
@@ -175,13 +196,22 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table, | |||
175 | unsigned long fdt_addr, | 196 | unsigned long fdt_addr, |
176 | unsigned long fdt_size) | 197 | unsigned long fdt_size) |
177 | { | 198 | { |
178 | unsigned long map_size, desc_size; | 199 | unsigned long map_size, desc_size, buff_size; |
179 | u32 desc_ver; | 200 | u32 desc_ver; |
180 | unsigned long mmap_key; | 201 | unsigned long mmap_key; |
181 | efi_memory_desc_t *memory_map, *runtime_map; | 202 | efi_memory_desc_t *memory_map, *runtime_map; |
182 | unsigned long new_fdt_size; | 203 | unsigned long new_fdt_size; |
183 | efi_status_t status; | 204 | efi_status_t status; |
184 | int runtime_entry_count = 0; | 205 | int runtime_entry_count = 0; |
206 | struct efi_boot_memmap map; | ||
207 | struct exit_boot_struct priv; | ||
208 | |||
209 | map.map = &runtime_map; | ||
210 | map.map_size = &map_size; | ||
211 | map.desc_size = &desc_size; | ||
212 | map.desc_ver = &desc_ver; | ||
213 | map.key_ptr = &mmap_key; | ||
214 | map.buff_size = &buff_size; | ||
185 | 215 | ||
186 | /* | 216 | /* |
187 | * Get a copy of the current memory map that we will use to prepare | 217 | * Get a copy of the current memory map that we will use to prepare |
@@ -189,8 +219,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table, | |||
189 | * subsequent allocations adding entries, since they could not affect | 219 | * subsequent allocations adding entries, since they could not affect |
190 | * the number of EFI_MEMORY_RUNTIME regions. | 220 | * the number of EFI_MEMORY_RUNTIME regions. |
191 | */ | 221 | */ |
192 | status = efi_get_memory_map(sys_table, &runtime_map, &map_size, | 222 | status = efi_get_memory_map(sys_table, &map); |
193 | &desc_size, &desc_ver, &mmap_key); | ||
194 | if (status != EFI_SUCCESS) { | 223 | if (status != EFI_SUCCESS) { |
195 | pr_efi_err(sys_table, "Unable to retrieve UEFI memory map.\n"); | 224 | pr_efi_err(sys_table, "Unable to retrieve UEFI memory map.\n"); |
196 | return status; | 225 | return status; |
@@ -199,6 +228,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table, | |||
199 | pr_efi(sys_table, | 228 | pr_efi(sys_table, |
200 | "Exiting boot services and installing virtual address map...\n"); | 229 | "Exiting boot services and installing virtual address map...\n"); |
201 | 230 | ||
231 | map.map = &memory_map; | ||
202 | /* | 232 | /* |
203 | * Estimate size of new FDT, and allocate memory for it. We | 233 | * Estimate size of new FDT, and allocate memory for it. We |
204 | * will allocate a bigger buffer if this ends up being too | 234 | * will allocate a bigger buffer if this ends up being too |
@@ -218,8 +248,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table, | |||
218 | * we can get the memory map key needed for | 248 | * we can get the memory map key needed for |
219 | * exit_boot_services(). | 249 | * exit_boot_services(). |
220 | */ | 250 | */ |
221 | status = efi_get_memory_map(sys_table, &memory_map, &map_size, | 251 | status = efi_get_memory_map(sys_table, &map); |
222 | &desc_size, &desc_ver, &mmap_key); | ||
223 | if (status != EFI_SUCCESS) | 252 | if (status != EFI_SUCCESS) |
224 | goto fail_free_new_fdt; | 253 | goto fail_free_new_fdt; |
225 | 254 | ||
@@ -250,16 +279,11 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table, | |||
250 | } | 279 | } |
251 | } | 280 | } |
252 | 281 | ||
253 | /* | 282 | sys_table->boottime->free_pool(memory_map); |
254 | * Update the memory map with virtual addresses. The function will also | 283 | priv.runtime_map = runtime_map; |
255 | * populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME | 284 | priv.runtime_entry_count = &runtime_entry_count; |
256 | * entries so that we can pass it straight into SetVirtualAddressMap() | 285 | status = efi_exit_boot_services(sys_table, handle, &map, &priv, |
257 | */ | 286 | exit_boot_func); |
258 | efi_get_virtmap(memory_map, map_size, desc_size, runtime_map, | ||
259 | &runtime_entry_count); | ||
260 | |||
261 | /* Now we are ready to exit_boot_services.*/ | ||
262 | status = sys_table->boottime->exit_boot_services(handle, mmap_key); | ||
263 | 287 | ||
264 | if (status == EFI_SUCCESS) { | 288 | if (status == EFI_SUCCESS) { |
265 | efi_set_virtual_address_map_t *svam; | 289 | efi_set_virtual_address_map_t *svam; |
diff --git a/drivers/firmware/efi/libstub/random.c b/drivers/firmware/efi/libstub/random.c index 53f6d3fe6d86..0c9f58c5ba50 100644 --- a/drivers/firmware/efi/libstub/random.c +++ b/drivers/firmware/efi/libstub/random.c | |||
@@ -73,12 +73,20 @@ efi_status_t efi_random_alloc(efi_system_table_t *sys_table_arg, | |||
73 | unsigned long random_seed) | 73 | unsigned long random_seed) |
74 | { | 74 | { |
75 | unsigned long map_size, desc_size, total_slots = 0, target_slot; | 75 | unsigned long map_size, desc_size, total_slots = 0, target_slot; |
76 | unsigned long buff_size; | ||
76 | efi_status_t status; | 77 | efi_status_t status; |
77 | efi_memory_desc_t *memory_map; | 78 | efi_memory_desc_t *memory_map; |
78 | int map_offset; | 79 | int map_offset; |
80 | struct efi_boot_memmap map; | ||
79 | 81 | ||
80 | status = efi_get_memory_map(sys_table_arg, &memory_map, &map_size, | 82 | map.map = &memory_map; |
81 | &desc_size, NULL, NULL); | 83 | map.map_size = &map_size; |
84 | map.desc_size = &desc_size; | ||
85 | map.desc_ver = NULL; | ||
86 | map.key_ptr = NULL; | ||
87 | map.buff_size = &buff_size; | ||
88 | |||
89 | status = efi_get_memory_map(sys_table_arg, &map); | ||
82 | if (status != EFI_SUCCESS) | 90 | if (status != EFI_SUCCESS) |
83 | return status; | 91 | return status; |
84 | 92 | ||
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 98dd47a30fc7..24caedb00a7a 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -50,6 +50,7 @@ config GPIO_DEVRES | |||
50 | config OF_GPIO | 50 | config OF_GPIO |
51 | def_bool y | 51 | def_bool y |
52 | depends on OF | 52 | depends on OF |
53 | depends on HAS_IOMEM | ||
53 | 54 | ||
54 | config GPIO_ACPI | 55 | config GPIO_ACPI |
55 | def_bool y | 56 | def_bool y |
@@ -188,7 +189,7 @@ config GPIO_EP93XX | |||
188 | config GPIO_ETRAXFS | 189 | config GPIO_ETRAXFS |
189 | bool "Axis ETRAX FS General I/O" | 190 | bool "Axis ETRAX FS General I/O" |
190 | depends on CRIS || COMPILE_TEST | 191 | depends on CRIS || COMPILE_TEST |
191 | depends on OF | 192 | depends on OF_GPIO |
192 | select GPIO_GENERIC | 193 | select GPIO_GENERIC |
193 | select GPIOLIB_IRQCHIP | 194 | select GPIOLIB_IRQCHIP |
194 | help | 195 | help |
@@ -214,7 +215,7 @@ config GPIO_GENERIC_PLATFORM | |||
214 | 215 | ||
215 | config GPIO_GRGPIO | 216 | config GPIO_GRGPIO |
216 | tristate "Aeroflex Gaisler GRGPIO support" | 217 | tristate "Aeroflex Gaisler GRGPIO support" |
217 | depends on OF | 218 | depends on OF_GPIO |
218 | select GPIO_GENERIC | 219 | select GPIO_GENERIC |
219 | select IRQ_DOMAIN | 220 | select IRQ_DOMAIN |
220 | help | 221 | help |
@@ -312,7 +313,7 @@ config GPIO_MPC8XXX | |||
312 | config GPIO_MVEBU | 313 | config GPIO_MVEBU |
313 | def_bool y | 314 | def_bool y |
314 | depends on PLAT_ORION | 315 | depends on PLAT_ORION |
315 | depends on OF | 316 | depends on OF_GPIO |
316 | select GENERIC_IRQ_CHIP | 317 | select GENERIC_IRQ_CHIP |
317 | 318 | ||
318 | config GPIO_MXC | 319 | config GPIO_MXC |
@@ -405,7 +406,7 @@ config GPIO_TEGRA | |||
405 | bool "NVIDIA Tegra GPIO support" | 406 | bool "NVIDIA Tegra GPIO support" |
406 | default ARCH_TEGRA | 407 | default ARCH_TEGRA |
407 | depends on ARCH_TEGRA || COMPILE_TEST | 408 | depends on ARCH_TEGRA || COMPILE_TEST |
408 | depends on OF | 409 | depends on OF_GPIO |
409 | help | 410 | help |
410 | Say yes here to support GPIO pins on NVIDIA Tegra SoCs. | 411 | Say yes here to support GPIO pins on NVIDIA Tegra SoCs. |
411 | 412 | ||
@@ -1099,7 +1100,7 @@ menu "SPI GPIO expanders" | |||
1099 | 1100 | ||
1100 | config GPIO_74X164 | 1101 | config GPIO_74X164 |
1101 | tristate "74x164 serial-in/parallel-out 8-bits shift register" | 1102 | tristate "74x164 serial-in/parallel-out 8-bits shift register" |
1102 | depends on OF | 1103 | depends on OF_GPIO |
1103 | help | 1104 | help |
1104 | Driver for 74x164 compatible serial-in/parallel-out 8-outputs | 1105 | Driver for 74x164 compatible serial-in/parallel-out 8-outputs |
1105 | shift registers. This driver can be used to provide access | 1106 | shift registers. This driver can be used to provide access |
@@ -1130,6 +1131,7 @@ menu "SPI or I2C GPIO expanders" | |||
1130 | 1131 | ||
1131 | config GPIO_MCP23S08 | 1132 | config GPIO_MCP23S08 |
1132 | tristate "Microchip MCP23xxx I/O expander" | 1133 | tristate "Microchip MCP23xxx I/O expander" |
1134 | depends on OF_GPIO | ||
1133 | select GPIOLIB_IRQCHIP | 1135 | select GPIOLIB_IRQCHIP |
1134 | help | 1136 | help |
1135 | SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017 | 1137 | SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017 |
diff --git a/drivers/gpio/gpio-max730x.c b/drivers/gpio/gpio-max730x.c index 08807368f007..946d09195598 100644 --- a/drivers/gpio/gpio-max730x.c +++ b/drivers/gpio/gpio-max730x.c | |||
@@ -192,6 +192,10 @@ int __max730x_probe(struct max7301 *ts) | |||
192 | ts->chip.parent = dev; | 192 | ts->chip.parent = dev; |
193 | ts->chip.owner = THIS_MODULE; | 193 | ts->chip.owner = THIS_MODULE; |
194 | 194 | ||
195 | ret = gpiochip_add_data(&ts->chip, ts); | ||
196 | if (ret) | ||
197 | goto exit_destroy; | ||
198 | |||
195 | /* | 199 | /* |
196 | * initialize pullups according to platform data and cache the | 200 | * initialize pullups according to platform data and cache the |
197 | * register values for later use. | 201 | * register values for later use. |
@@ -213,10 +217,6 @@ int __max730x_probe(struct max7301 *ts) | |||
213 | } | 217 | } |
214 | } | 218 | } |
215 | 219 | ||
216 | ret = gpiochip_add_data(&ts->chip, ts); | ||
217 | if (ret) | ||
218 | goto exit_destroy; | ||
219 | |||
220 | return ret; | 220 | return ret; |
221 | 221 | ||
222 | exit_destroy: | 222 | exit_destroy: |
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index ac22efc1840e..99d37b56c258 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c | |||
@@ -564,7 +564,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, | |||
564 | mcp->chip.direction_output = mcp23s08_direction_output; | 564 | mcp->chip.direction_output = mcp23s08_direction_output; |
565 | mcp->chip.set = mcp23s08_set; | 565 | mcp->chip.set = mcp23s08_set; |
566 | mcp->chip.dbg_show = mcp23s08_dbg_show; | 566 | mcp->chip.dbg_show = mcp23s08_dbg_show; |
567 | #ifdef CONFIG_OF | 567 | #ifdef CONFIG_OF_GPIO |
568 | mcp->chip.of_gpio_n_cells = 2; | 568 | mcp->chip.of_gpio_n_cells = 2; |
569 | mcp->chip.of_node = dev->of_node; | 569 | mcp->chip.of_node = dev->of_node; |
570 | #endif | 570 | #endif |
diff --git a/drivers/gpio/gpio-sa1100.c b/drivers/gpio/gpio-sa1100.c index 0c99e8fb9af3..8d8ee0ebf14c 100644 --- a/drivers/gpio/gpio-sa1100.c +++ b/drivers/gpio/gpio-sa1100.c | |||
@@ -155,7 +155,7 @@ static int sa1100_gpio_irqdomain_map(struct irq_domain *d, | |||
155 | { | 155 | { |
156 | irq_set_chip_and_handler(irq, &sa1100_gpio_irq_chip, | 156 | irq_set_chip_and_handler(irq, &sa1100_gpio_irq_chip, |
157 | handle_edge_irq); | 157 | handle_edge_irq); |
158 | irq_set_noprobe(irq); | 158 | irq_set_probe(irq); |
159 | 159 | ||
160 | return 0; | 160 | return 0; |
161 | } | 161 | } |
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 75e7b3919ea7..a28feb3edf33 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/io-mapping.h> | ||
20 | #include <linux/gpio/consumer.h> | 19 | #include <linux/gpio/consumer.h> |
21 | #include <linux/of.h> | 20 | #include <linux/of.h> |
22 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 8c704c86597b..700c56baf2de 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -426,6 +426,8 @@ struct amdgpu_mman { | |||
426 | 426 | ||
427 | /* custom LRU management */ | 427 | /* custom LRU management */ |
428 | struct amdgpu_mman_lru log2_size[AMDGPU_TTM_LRU_SIZE]; | 428 | struct amdgpu_mman_lru log2_size[AMDGPU_TTM_LRU_SIZE]; |
429 | /* guard for log2_size array, don't add anything in between */ | ||
430 | struct amdgpu_mman_lru guard; | ||
429 | }; | 431 | }; |
430 | 432 | ||
431 | int amdgpu_copy_buffer(struct amdgpu_ring *ring, | 433 | int amdgpu_copy_buffer(struct amdgpu_ring *ring, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c index 983175363b06..fe872b82e619 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | |||
@@ -321,6 +321,19 @@ bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device * | |||
321 | (le16_to_cpu(path->usConnObjectId) & | 321 | (le16_to_cpu(path->usConnObjectId) & |
322 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; | 322 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; |
323 | 323 | ||
324 | /* Skip TV/CV support */ | ||
325 | if ((le16_to_cpu(path->usDeviceTag) == | ||
326 | ATOM_DEVICE_TV1_SUPPORT) || | ||
327 | (le16_to_cpu(path->usDeviceTag) == | ||
328 | ATOM_DEVICE_CV_SUPPORT)) | ||
329 | continue; | ||
330 | |||
331 | if (con_obj_id >= ARRAY_SIZE(object_connector_convert)) { | ||
332 | DRM_ERROR("invalid con_obj_id %d for device tag 0x%04x\n", | ||
333 | con_obj_id, le16_to_cpu(path->usDeviceTag)); | ||
334 | continue; | ||
335 | } | ||
336 | |||
324 | connector_type = | 337 | connector_type = |
325 | object_connector_convert[con_obj_id]; | 338 | object_connector_convert[con_obj_id]; |
326 | connector_object_id = con_obj_id; | 339 | connector_object_id = con_obj_id; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index a31d7ef3032c..ec1282af2479 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | |||
@@ -280,7 +280,7 @@ void amdgpu_ib_pool_fini(struct amdgpu_device *adev) | |||
280 | int amdgpu_ib_ring_tests(struct amdgpu_device *adev) | 280 | int amdgpu_ib_ring_tests(struct amdgpu_device *adev) |
281 | { | 281 | { |
282 | unsigned i; | 282 | unsigned i; |
283 | int r; | 283 | int r, ret = 0; |
284 | 284 | ||
285 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 285 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
286 | struct amdgpu_ring *ring = adev->rings[i]; | 286 | struct amdgpu_ring *ring = adev->rings[i]; |
@@ -301,10 +301,11 @@ int amdgpu_ib_ring_tests(struct amdgpu_device *adev) | |||
301 | } else { | 301 | } else { |
302 | /* still not good, but we can live with it */ | 302 | /* still not good, but we can live with it */ |
303 | DRM_ERROR("amdgpu: failed testing IB on ring %d (%d).\n", i, r); | 303 | DRM_ERROR("amdgpu: failed testing IB on ring %d (%d).\n", i, r); |
304 | ret = r; | ||
304 | } | 305 | } |
305 | } | 306 | } |
306 | } | 307 | } |
307 | return 0; | 308 | return ret; |
308 | } | 309 | } |
309 | 310 | ||
310 | /* | 311 | /* |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 9b61c8ba7aaf..716f2afeb6a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | |||
@@ -251,8 +251,8 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo, | |||
251 | 251 | ||
252 | adev = amdgpu_get_adev(bo->bdev); | 252 | adev = amdgpu_get_adev(bo->bdev); |
253 | ring = adev->mman.buffer_funcs_ring; | 253 | ring = adev->mman.buffer_funcs_ring; |
254 | old_start = old_mem->start << PAGE_SHIFT; | 254 | old_start = (u64)old_mem->start << PAGE_SHIFT; |
255 | new_start = new_mem->start << PAGE_SHIFT; | 255 | new_start = (u64)new_mem->start << PAGE_SHIFT; |
256 | 256 | ||
257 | switch (old_mem->mem_type) { | 257 | switch (old_mem->mem_type) { |
258 | case TTM_PL_VRAM: | 258 | case TTM_PL_VRAM: |
@@ -950,6 +950,8 @@ static struct list_head *amdgpu_ttm_lru_tail(struct ttm_buffer_object *tbo) | |||
950 | struct list_head *res = lru->lru[tbo->mem.mem_type]; | 950 | struct list_head *res = lru->lru[tbo->mem.mem_type]; |
951 | 951 | ||
952 | lru->lru[tbo->mem.mem_type] = &tbo->lru; | 952 | lru->lru[tbo->mem.mem_type] = &tbo->lru; |
953 | while ((++lru)->lru[tbo->mem.mem_type] == res) | ||
954 | lru->lru[tbo->mem.mem_type] = &tbo->lru; | ||
953 | 955 | ||
954 | return res; | 956 | return res; |
955 | } | 957 | } |
@@ -960,6 +962,8 @@ static struct list_head *amdgpu_ttm_swap_lru_tail(struct ttm_buffer_object *tbo) | |||
960 | struct list_head *res = lru->swap_lru; | 962 | struct list_head *res = lru->swap_lru; |
961 | 963 | ||
962 | lru->swap_lru = &tbo->swap; | 964 | lru->swap_lru = &tbo->swap; |
965 | while ((++lru)->swap_lru == res) | ||
966 | lru->swap_lru = &tbo->swap; | ||
963 | 967 | ||
964 | return res; | 968 | return res; |
965 | } | 969 | } |
@@ -1011,6 +1015,10 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) | |||
1011 | lru->swap_lru = &adev->mman.bdev.glob->swap_lru; | 1015 | lru->swap_lru = &adev->mman.bdev.glob->swap_lru; |
1012 | } | 1016 | } |
1013 | 1017 | ||
1018 | for (j = 0; j < TTM_NUM_MEM_TYPES; ++j) | ||
1019 | adev->mman.guard.lru[j] = NULL; | ||
1020 | adev->mman.guard.swap_lru = NULL; | ||
1021 | |||
1014 | adev->mman.initialized = true; | 1022 | adev->mman.initialized = true; |
1015 | r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_VRAM, | 1023 | r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_VRAM, |
1016 | adev->mc.real_vram_size >> PAGE_SHIFT); | 1024 | adev->mc.real_vram_size >> PAGE_SHIFT); |
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index ee6466912497..77fdd9911c3c 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c | |||
@@ -52,6 +52,7 @@ static void cik_sdma_set_ring_funcs(struct amdgpu_device *adev); | |||
52 | static void cik_sdma_set_irq_funcs(struct amdgpu_device *adev); | 52 | static void cik_sdma_set_irq_funcs(struct amdgpu_device *adev); |
53 | static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev); | 53 | static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev); |
54 | static void cik_sdma_set_vm_pte_funcs(struct amdgpu_device *adev); | 54 | static void cik_sdma_set_vm_pte_funcs(struct amdgpu_device *adev); |
55 | static int cik_sdma_soft_reset(void *handle); | ||
55 | 56 | ||
56 | MODULE_FIRMWARE("radeon/bonaire_sdma.bin"); | 57 | MODULE_FIRMWARE("radeon/bonaire_sdma.bin"); |
57 | MODULE_FIRMWARE("radeon/bonaire_sdma1.bin"); | 58 | MODULE_FIRMWARE("radeon/bonaire_sdma1.bin"); |
@@ -1037,6 +1038,8 @@ static int cik_sdma_resume(void *handle) | |||
1037 | { | 1038 | { |
1038 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1039 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1039 | 1040 | ||
1041 | cik_sdma_soft_reset(handle); | ||
1042 | |||
1040 | return cik_sdma_hw_init(adev); | 1043 | return cik_sdma_hw_init(adev); |
1041 | } | 1044 | } |
1042 | 1045 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index d869d058ef24..425413fcaf02 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | |||
@@ -2755,8 +2755,7 @@ static int gfx_v7_0_cp_compute_resume(struct amdgpu_device *adev) | |||
2755 | u64 wb_gpu_addr; | 2755 | u64 wb_gpu_addr; |
2756 | u32 *buf; | 2756 | u32 *buf; |
2757 | struct bonaire_mqd *mqd; | 2757 | struct bonaire_mqd *mqd; |
2758 | 2758 | struct amdgpu_ring *ring; | |
2759 | gfx_v7_0_cp_compute_enable(adev, true); | ||
2760 | 2759 | ||
2761 | /* fix up chicken bits */ | 2760 | /* fix up chicken bits */ |
2762 | tmp = RREG32(mmCP_CPF_DEBUG); | 2761 | tmp = RREG32(mmCP_CPF_DEBUG); |
@@ -2791,7 +2790,7 @@ static int gfx_v7_0_cp_compute_resume(struct amdgpu_device *adev) | |||
2791 | 2790 | ||
2792 | /* init the queues. Just two for now. */ | 2791 | /* init the queues. Just two for now. */ |
2793 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { | 2792 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { |
2794 | struct amdgpu_ring *ring = &adev->gfx.compute_ring[i]; | 2793 | ring = &adev->gfx.compute_ring[i]; |
2795 | 2794 | ||
2796 | if (ring->mqd_obj == NULL) { | 2795 | if (ring->mqd_obj == NULL) { |
2797 | r = amdgpu_bo_create(adev, | 2796 | r = amdgpu_bo_create(adev, |
@@ -2970,6 +2969,13 @@ static int gfx_v7_0_cp_compute_resume(struct amdgpu_device *adev) | |||
2970 | amdgpu_bo_unreserve(ring->mqd_obj); | 2969 | amdgpu_bo_unreserve(ring->mqd_obj); |
2971 | 2970 | ||
2972 | ring->ready = true; | 2971 | ring->ready = true; |
2972 | } | ||
2973 | |||
2974 | gfx_v7_0_cp_compute_enable(adev, true); | ||
2975 | |||
2976 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { | ||
2977 | ring = &adev->gfx.compute_ring[i]; | ||
2978 | |||
2973 | r = amdgpu_ring_test_ring(ring); | 2979 | r = amdgpu_ring_test_ring(ring); |
2974 | if (r) | 2980 | if (r) |
2975 | ring->ready = false; | 2981 | ring->ready = false; |
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index 1351c7e834a2..a64715d90503 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | |||
@@ -714,7 +714,7 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
714 | DRM_ERROR("amdgpu: IB test timed out\n"); | 714 | DRM_ERROR("amdgpu: IB test timed out\n"); |
715 | r = -ETIMEDOUT; | 715 | r = -ETIMEDOUT; |
716 | goto err1; | 716 | goto err1; |
717 | } else if (r) { | 717 | } else if (r < 0) { |
718 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | 718 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); |
719 | goto err1; | 719 | goto err1; |
720 | } | 720 | } |
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index ef312bb75fda..963a24d46a93 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | |||
@@ -405,7 +405,7 @@ void amd_sched_job_recovery(struct amd_gpu_scheduler *sched) | |||
405 | spin_lock(&sched->job_list_lock); | 405 | spin_lock(&sched->job_list_lock); |
406 | s_job = list_first_entry_or_null(&sched->ring_mirror_list, | 406 | s_job = list_first_entry_or_null(&sched->ring_mirror_list, |
407 | struct amd_sched_job, node); | 407 | struct amd_sched_job, node); |
408 | if (s_job) | 408 | if (s_job && sched->timeout != MAX_SCHEDULE_TIMEOUT) |
409 | schedule_delayed_work(&s_job->work_tdr, sched->timeout); | 409 | schedule_delayed_work(&s_job->work_tdr, sched->timeout); |
410 | 410 | ||
411 | list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) { | 411 | list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) { |
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c index a978381ef95b..9b17a66cf0e1 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | |||
@@ -387,7 +387,7 @@ void atmel_hlcdc_crtc_irq(struct drm_crtc *c) | |||
387 | atmel_hlcdc_crtc_finish_page_flip(drm_crtc_to_atmel_hlcdc_crtc(c)); | 387 | atmel_hlcdc_crtc_finish_page_flip(drm_crtc_to_atmel_hlcdc_crtc(c)); |
388 | } | 388 | } |
389 | 389 | ||
390 | void atmel_hlcdc_crtc_reset(struct drm_crtc *crtc) | 390 | static void atmel_hlcdc_crtc_reset(struct drm_crtc *crtc) |
391 | { | 391 | { |
392 | struct atmel_hlcdc_crtc_state *state; | 392 | struct atmel_hlcdc_crtc_state *state; |
393 | 393 | ||
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c index 016c191221f3..52c527f6642a 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | |||
@@ -320,19 +320,19 @@ atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane, | |||
320 | u32 *coeff_tab = heo_upscaling_ycoef; | 320 | u32 *coeff_tab = heo_upscaling_ycoef; |
321 | u32 max_memsize; | 321 | u32 max_memsize; |
322 | 322 | ||
323 | if (state->crtc_w < state->src_w) | 323 | if (state->crtc_h < state->src_h) |
324 | coeff_tab = heo_downscaling_ycoef; | 324 | coeff_tab = heo_downscaling_ycoef; |
325 | for (i = 0; i < ARRAY_SIZE(heo_upscaling_ycoef); i++) | 325 | for (i = 0; i < ARRAY_SIZE(heo_upscaling_ycoef); i++) |
326 | atmel_hlcdc_layer_update_cfg(&plane->layer, | 326 | atmel_hlcdc_layer_update_cfg(&plane->layer, |
327 | 33 + i, | 327 | 33 + i, |
328 | 0xffffffff, | 328 | 0xffffffff, |
329 | coeff_tab[i]); | 329 | coeff_tab[i]); |
330 | factor = ((8 * 256 * state->src_w) - (256 * 4)) / | 330 | factor = ((8 * 256 * state->src_h) - (256 * 4)) / |
331 | state->crtc_w; | 331 | state->crtc_h; |
332 | factor++; | 332 | factor++; |
333 | max_memsize = ((factor * state->crtc_w) + (256 * 4)) / | 333 | max_memsize = ((factor * state->crtc_h) + (256 * 4)) / |
334 | 2048; | 334 | 2048; |
335 | if (max_memsize > state->src_w) | 335 | if (max_memsize > state->src_h) |
336 | factor--; | 336 | factor--; |
337 | factor_reg |= (factor << 16) | 0x80000000; | 337 | factor_reg |= (factor << 16) | 0x80000000; |
338 | } | 338 | } |
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index fa3930757972..2a3ded44cf2a 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c | |||
@@ -475,7 +475,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, | |||
475 | val, | 475 | val, |
476 | -1, | 476 | -1, |
477 | &replaced); | 477 | &replaced); |
478 | state->color_mgmt_changed = replaced; | 478 | state->color_mgmt_changed |= replaced; |
479 | return ret; | 479 | return ret; |
480 | } else if (property == config->ctm_property) { | 480 | } else if (property == config->ctm_property) { |
481 | ret = drm_atomic_replace_property_blob_from_id(crtc, | 481 | ret = drm_atomic_replace_property_blob_from_id(crtc, |
@@ -483,7 +483,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, | |||
483 | val, | 483 | val, |
484 | sizeof(struct drm_color_ctm), | 484 | sizeof(struct drm_color_ctm), |
485 | &replaced); | 485 | &replaced); |
486 | state->color_mgmt_changed = replaced; | 486 | state->color_mgmt_changed |= replaced; |
487 | return ret; | 487 | return ret; |
488 | } else if (property == config->gamma_lut_property) { | 488 | } else if (property == config->gamma_lut_property) { |
489 | ret = drm_atomic_replace_property_blob_from_id(crtc, | 489 | ret = drm_atomic_replace_property_blob_from_id(crtc, |
@@ -491,7 +491,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, | |||
491 | val, | 491 | val, |
492 | -1, | 492 | -1, |
493 | &replaced); | 493 | &replaced); |
494 | state->color_mgmt_changed = replaced; | 494 | state->color_mgmt_changed |= replaced; |
495 | return ret; | 495 | return ret; |
496 | } else if (crtc->funcs->atomic_set_property) | 496 | } else if (crtc->funcs->atomic_set_property) |
497 | return crtc->funcs->atomic_set_property(crtc, state, property, val); | 497 | return crtc->funcs->atomic_set_property(crtc, state, property, val); |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index b1dbb60af99f..ddebe54cd5ca 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -5404,6 +5404,9 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, | |||
5404 | struct drm_pending_vblank_event *e = NULL; | 5404 | struct drm_pending_vblank_event *e = NULL; |
5405 | int ret = -EINVAL; | 5405 | int ret = -EINVAL; |
5406 | 5406 | ||
5407 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | ||
5408 | return -EINVAL; | ||
5409 | |||
5407 | if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS || | 5410 | if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS || |
5408 | page_flip->reserved != 0) | 5411 | page_flip->reserved != 0) |
5409 | return -EINVAL; | 5412 | return -EINVAL; |
diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c index 57676f8d7ecf..a6289752be16 100644 --- a/drivers/gpu/drm/drm_ioc32.c +++ b/drivers/gpu/drm/drm_ioc32.c | |||
@@ -1015,6 +1015,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, | |||
1015 | return 0; | 1015 | return 0; |
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | #if defined(CONFIG_X86) || defined(CONFIG_IA64) | ||
1018 | typedef struct drm_mode_fb_cmd232 { | 1019 | typedef struct drm_mode_fb_cmd232 { |
1019 | u32 fb_id; | 1020 | u32 fb_id; |
1020 | u32 width; | 1021 | u32 width; |
@@ -1071,6 +1072,7 @@ static int compat_drm_mode_addfb2(struct file *file, unsigned int cmd, | |||
1071 | 1072 | ||
1072 | return 0; | 1073 | return 0; |
1073 | } | 1074 | } |
1075 | #endif | ||
1074 | 1076 | ||
1075 | static drm_ioctl_compat_t *drm_compat_ioctls[] = { | 1077 | static drm_ioctl_compat_t *drm_compat_ioctls[] = { |
1076 | [DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version, | 1078 | [DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version, |
@@ -1104,7 +1106,9 @@ static drm_ioctl_compat_t *drm_compat_ioctls[] = { | |||
1104 | [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW32)] = compat_drm_update_draw, | 1106 | [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW32)] = compat_drm_update_draw, |
1105 | #endif | 1107 | #endif |
1106 | [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank, | 1108 | [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank, |
1109 | #if defined(CONFIG_X86) || defined(CONFIG_IA64) | ||
1107 | [DRM_IOCTL_NR(DRM_IOCTL_MODE_ADDFB232)] = compat_drm_mode_addfb2, | 1110 | [DRM_IOCTL_NR(DRM_IOCTL_MODE_ADDFB232)] = compat_drm_mode_addfb2, |
1111 | #endif | ||
1108 | }; | 1112 | }; |
1109 | 1113 | ||
1110 | /** | 1114 | /** |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index e0166403b4bd..40ce841eb952 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c | |||
@@ -55,11 +55,11 @@ static int check_fb_gem_memory_type(struct drm_device *drm_dev, | |||
55 | flags = exynos_gem->flags; | 55 | flags = exynos_gem->flags; |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * without iommu support, not support physically non-continuous memory | 58 | * Physically non-contiguous memory type for framebuffer is not |
59 | * for framebuffer. | 59 | * supported without IOMMU. |
60 | */ | 60 | */ |
61 | if (IS_NONCONTIG_BUFFER(flags)) { | 61 | if (IS_NONCONTIG_BUFFER(flags)) { |
62 | DRM_ERROR("cannot use this gem memory type for fb.\n"); | 62 | DRM_ERROR("Non-contiguous GEM memory is not supported.\n"); |
63 | return -EINVAL; | 63 | return -EINVAL; |
64 | } | 64 | } |
65 | 65 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c index 0525c56145db..147ef0d298cb 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c | |||
@@ -1753,32 +1753,6 @@ static int fimc_clk_ctrl(struct fimc_context *ctx, bool enable) | |||
1753 | return 0; | 1753 | return 0; |
1754 | } | 1754 | } |
1755 | 1755 | ||
1756 | #ifdef CONFIG_PM_SLEEP | ||
1757 | static int fimc_suspend(struct device *dev) | ||
1758 | { | ||
1759 | struct fimc_context *ctx = get_fimc_context(dev); | ||
1760 | |||
1761 | DRM_DEBUG_KMS("id[%d]\n", ctx->id); | ||
1762 | |||
1763 | if (pm_runtime_suspended(dev)) | ||
1764 | return 0; | ||
1765 | |||
1766 | return fimc_clk_ctrl(ctx, false); | ||
1767 | } | ||
1768 | |||
1769 | static int fimc_resume(struct device *dev) | ||
1770 | { | ||
1771 | struct fimc_context *ctx = get_fimc_context(dev); | ||
1772 | |||
1773 | DRM_DEBUG_KMS("id[%d]\n", ctx->id); | ||
1774 | |||
1775 | if (!pm_runtime_suspended(dev)) | ||
1776 | return fimc_clk_ctrl(ctx, true); | ||
1777 | |||
1778 | return 0; | ||
1779 | } | ||
1780 | #endif | ||
1781 | |||
1782 | static int fimc_runtime_suspend(struct device *dev) | 1756 | static int fimc_runtime_suspend(struct device *dev) |
1783 | { | 1757 | { |
1784 | struct fimc_context *ctx = get_fimc_context(dev); | 1758 | struct fimc_context *ctx = get_fimc_context(dev); |
@@ -1799,7 +1773,8 @@ static int fimc_runtime_resume(struct device *dev) | |||
1799 | #endif | 1773 | #endif |
1800 | 1774 | ||
1801 | static const struct dev_pm_ops fimc_pm_ops = { | 1775 | static const struct dev_pm_ops fimc_pm_ops = { |
1802 | SET_SYSTEM_SLEEP_PM_OPS(fimc_suspend, fimc_resume) | 1776 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, |
1777 | pm_runtime_force_resume) | ||
1803 | SET_RUNTIME_PM_OPS(fimc_runtime_suspend, fimc_runtime_resume, NULL) | 1778 | SET_RUNTIME_PM_OPS(fimc_runtime_suspend, fimc_runtime_resume, NULL) |
1804 | }; | 1779 | }; |
1805 | 1780 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 4bf00f57ffe8..6eca8bb88648 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c | |||
@@ -1475,8 +1475,8 @@ static int g2d_remove(struct platform_device *pdev) | |||
1475 | return 0; | 1475 | return 0; |
1476 | } | 1476 | } |
1477 | 1477 | ||
1478 | #ifdef CONFIG_PM_SLEEP | 1478 | #ifdef CONFIG_PM |
1479 | static int g2d_suspend(struct device *dev) | 1479 | static int g2d_runtime_suspend(struct device *dev) |
1480 | { | 1480 | { |
1481 | struct g2d_data *g2d = dev_get_drvdata(dev); | 1481 | struct g2d_data *g2d = dev_get_drvdata(dev); |
1482 | 1482 | ||
@@ -1490,25 +1490,6 @@ static int g2d_suspend(struct device *dev) | |||
1490 | 1490 | ||
1491 | flush_work(&g2d->runqueue_work); | 1491 | flush_work(&g2d->runqueue_work); |
1492 | 1492 | ||
1493 | return 0; | ||
1494 | } | ||
1495 | |||
1496 | static int g2d_resume(struct device *dev) | ||
1497 | { | ||
1498 | struct g2d_data *g2d = dev_get_drvdata(dev); | ||
1499 | |||
1500 | g2d->suspended = false; | ||
1501 | g2d_exec_runqueue(g2d); | ||
1502 | |||
1503 | return 0; | ||
1504 | } | ||
1505 | #endif | ||
1506 | |||
1507 | #ifdef CONFIG_PM | ||
1508 | static int g2d_runtime_suspend(struct device *dev) | ||
1509 | { | ||
1510 | struct g2d_data *g2d = dev_get_drvdata(dev); | ||
1511 | |||
1512 | clk_disable_unprepare(g2d->gate_clk); | 1493 | clk_disable_unprepare(g2d->gate_clk); |
1513 | 1494 | ||
1514 | return 0; | 1495 | return 0; |
@@ -1523,12 +1504,16 @@ static int g2d_runtime_resume(struct device *dev) | |||
1523 | if (ret < 0) | 1504 | if (ret < 0) |
1524 | dev_warn(dev, "failed to enable clock.\n"); | 1505 | dev_warn(dev, "failed to enable clock.\n"); |
1525 | 1506 | ||
1507 | g2d->suspended = false; | ||
1508 | g2d_exec_runqueue(g2d); | ||
1509 | |||
1526 | return ret; | 1510 | return ret; |
1527 | } | 1511 | } |
1528 | #endif | 1512 | #endif |
1529 | 1513 | ||
1530 | static const struct dev_pm_ops g2d_pm_ops = { | 1514 | static const struct dev_pm_ops g2d_pm_ops = { |
1531 | SET_SYSTEM_SLEEP_PM_OPS(g2d_suspend, g2d_resume) | 1515 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, |
1516 | pm_runtime_force_resume) | ||
1532 | SET_RUNTIME_PM_OPS(g2d_runtime_suspend, g2d_runtime_resume, NULL) | 1517 | SET_RUNTIME_PM_OPS(g2d_runtime_suspend, g2d_runtime_resume, NULL) |
1533 | }; | 1518 | }; |
1534 | 1519 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index 5d20da8f957e..52a9d269484e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c | |||
@@ -1760,34 +1760,7 @@ static int gsc_remove(struct platform_device *pdev) | |||
1760 | return 0; | 1760 | return 0; |
1761 | } | 1761 | } |
1762 | 1762 | ||
1763 | #ifdef CONFIG_PM_SLEEP | 1763 | static int __maybe_unused gsc_runtime_suspend(struct device *dev) |
1764 | static int gsc_suspend(struct device *dev) | ||
1765 | { | ||
1766 | struct gsc_context *ctx = get_gsc_context(dev); | ||
1767 | |||
1768 | DRM_DEBUG_KMS("id[%d]\n", ctx->id); | ||
1769 | |||
1770 | if (pm_runtime_suspended(dev)) | ||
1771 | return 0; | ||
1772 | |||
1773 | return gsc_clk_ctrl(ctx, false); | ||
1774 | } | ||
1775 | |||
1776 | static int gsc_resume(struct device *dev) | ||
1777 | { | ||
1778 | struct gsc_context *ctx = get_gsc_context(dev); | ||
1779 | |||
1780 | DRM_DEBUG_KMS("id[%d]\n", ctx->id); | ||
1781 | |||
1782 | if (!pm_runtime_suspended(dev)) | ||
1783 | return gsc_clk_ctrl(ctx, true); | ||
1784 | |||
1785 | return 0; | ||
1786 | } | ||
1787 | #endif | ||
1788 | |||
1789 | #ifdef CONFIG_PM | ||
1790 | static int gsc_runtime_suspend(struct device *dev) | ||
1791 | { | 1764 | { |
1792 | struct gsc_context *ctx = get_gsc_context(dev); | 1765 | struct gsc_context *ctx = get_gsc_context(dev); |
1793 | 1766 | ||
@@ -1796,7 +1769,7 @@ static int gsc_runtime_suspend(struct device *dev) | |||
1796 | return gsc_clk_ctrl(ctx, false); | 1769 | return gsc_clk_ctrl(ctx, false); |
1797 | } | 1770 | } |
1798 | 1771 | ||
1799 | static int gsc_runtime_resume(struct device *dev) | 1772 | static int __maybe_unused gsc_runtime_resume(struct device *dev) |
1800 | { | 1773 | { |
1801 | struct gsc_context *ctx = get_gsc_context(dev); | 1774 | struct gsc_context *ctx = get_gsc_context(dev); |
1802 | 1775 | ||
@@ -1804,10 +1777,10 @@ static int gsc_runtime_resume(struct device *dev) | |||
1804 | 1777 | ||
1805 | return gsc_clk_ctrl(ctx, true); | 1778 | return gsc_clk_ctrl(ctx, true); |
1806 | } | 1779 | } |
1807 | #endif | ||
1808 | 1780 | ||
1809 | static const struct dev_pm_ops gsc_pm_ops = { | 1781 | static const struct dev_pm_ops gsc_pm_ops = { |
1810 | SET_SYSTEM_SLEEP_PM_OPS(gsc_suspend, gsc_resume) | 1782 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, |
1783 | pm_runtime_force_resume) | ||
1811 | SET_RUNTIME_PM_OPS(gsc_runtime_suspend, gsc_runtime_resume, NULL) | 1784 | SET_RUNTIME_PM_OPS(gsc_runtime_suspend, gsc_runtime_resume, NULL) |
1812 | }; | 1785 | }; |
1813 | 1786 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c index 404367a430b5..6591e406084c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c +++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c | |||
@@ -794,29 +794,6 @@ static int rotator_clk_crtl(struct rot_context *rot, bool enable) | |||
794 | return 0; | 794 | return 0; |
795 | } | 795 | } |
796 | 796 | ||
797 | |||
798 | #ifdef CONFIG_PM_SLEEP | ||
799 | static int rotator_suspend(struct device *dev) | ||
800 | { | ||
801 | struct rot_context *rot = dev_get_drvdata(dev); | ||
802 | |||
803 | if (pm_runtime_suspended(dev)) | ||
804 | return 0; | ||
805 | |||
806 | return rotator_clk_crtl(rot, false); | ||
807 | } | ||
808 | |||
809 | static int rotator_resume(struct device *dev) | ||
810 | { | ||
811 | struct rot_context *rot = dev_get_drvdata(dev); | ||
812 | |||
813 | if (!pm_runtime_suspended(dev)) | ||
814 | return rotator_clk_crtl(rot, true); | ||
815 | |||
816 | return 0; | ||
817 | } | ||
818 | #endif | ||
819 | |||
820 | static int rotator_runtime_suspend(struct device *dev) | 797 | static int rotator_runtime_suspend(struct device *dev) |
821 | { | 798 | { |
822 | struct rot_context *rot = dev_get_drvdata(dev); | 799 | struct rot_context *rot = dev_get_drvdata(dev); |
@@ -833,7 +810,8 @@ static int rotator_runtime_resume(struct device *dev) | |||
833 | #endif | 810 | #endif |
834 | 811 | ||
835 | static const struct dev_pm_ops rotator_pm_ops = { | 812 | static const struct dev_pm_ops rotator_pm_ops = { |
836 | SET_SYSTEM_SLEEP_PM_OPS(rotator_suspend, rotator_resume) | 813 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, |
814 | pm_runtime_force_resume) | ||
837 | SET_RUNTIME_PM_OPS(rotator_runtime_suspend, rotator_runtime_resume, | 815 | SET_RUNTIME_PM_OPS(rotator_runtime_suspend, rotator_runtime_resume, |
838 | NULL) | 816 | NULL) |
839 | }; | 817 | }; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 95ddd56b89f0..5de36d8dcc68 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -1281,6 +1281,11 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1281 | 1281 | ||
1282 | intel_runtime_pm_enable(dev_priv); | 1282 | intel_runtime_pm_enable(dev_priv); |
1283 | 1283 | ||
1284 | /* Everything is in place, we can now relax! */ | ||
1285 | DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", | ||
1286 | driver.name, driver.major, driver.minor, driver.patchlevel, | ||
1287 | driver.date, pci_name(pdev), dev_priv->drm.primary->index); | ||
1288 | |||
1284 | intel_runtime_pm_put(dev_priv); | 1289 | intel_runtime_pm_put(dev_priv); |
1285 | 1290 | ||
1286 | return 0; | 1291 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 20fe9d52e256..f68c78918d63 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -882,11 +882,12 @@ struct i915_gem_context { | |||
882 | 882 | ||
883 | struct i915_ctx_hang_stats hang_stats; | 883 | struct i915_ctx_hang_stats hang_stats; |
884 | 884 | ||
885 | /* Unique identifier for this context, used by the hw for tracking */ | ||
886 | unsigned long flags; | 885 | unsigned long flags; |
887 | #define CONTEXT_NO_ZEROMAP BIT(0) | 886 | #define CONTEXT_NO_ZEROMAP BIT(0) |
888 | #define CONTEXT_NO_ERROR_CAPTURE BIT(1) | 887 | #define CONTEXT_NO_ERROR_CAPTURE BIT(1) |
889 | unsigned hw_id; | 888 | |
889 | /* Unique identifier for this context, used by the hw for tracking */ | ||
890 | unsigned int hw_id; | ||
890 | u32 user_handle; | 891 | u32 user_handle; |
891 | 892 | ||
892 | u32 ggtt_alignment; | 893 | u32 ggtt_alignment; |
@@ -1963,6 +1964,13 @@ struct drm_i915_private { | |||
1963 | struct i915_suspend_saved_registers regfile; | 1964 | struct i915_suspend_saved_registers regfile; |
1964 | struct vlv_s0ix_state vlv_s0ix_state; | 1965 | struct vlv_s0ix_state vlv_s0ix_state; |
1965 | 1966 | ||
1967 | enum { | ||
1968 | I915_SKL_SAGV_UNKNOWN = 0, | ||
1969 | I915_SKL_SAGV_DISABLED, | ||
1970 | I915_SKL_SAGV_ENABLED, | ||
1971 | I915_SKL_SAGV_NOT_CONTROLLED | ||
1972 | } skl_sagv_status; | ||
1973 | |||
1966 | struct { | 1974 | struct { |
1967 | /* | 1975 | /* |
1968 | * Raw watermark latency values: | 1976 | * Raw watermark latency values: |
@@ -3591,6 +3599,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle); | |||
3591 | /* belongs in i915_gem_gtt.h */ | 3599 | /* belongs in i915_gem_gtt.h */ |
3592 | static inline void i915_gem_chipset_flush(struct drm_i915_private *dev_priv) | 3600 | static inline void i915_gem_chipset_flush(struct drm_i915_private *dev_priv) |
3593 | { | 3601 | { |
3602 | wmb(); | ||
3594 | if (INTEL_GEN(dev_priv) < 6) | 3603 | if (INTEL_GEN(dev_priv) < 6) |
3595 | intel_gtt_chipset_flush(); | 3604 | intel_gtt_chipset_flush(); |
3596 | } | 3605 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 1978633e7549..b35e5b6475b2 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -943,8 +943,6 @@ i915_gem_execbuffer_move_to_gpu(struct drm_i915_gem_request *req, | |||
943 | { | 943 | { |
944 | const unsigned other_rings = ~intel_engine_flag(req->engine); | 944 | const unsigned other_rings = ~intel_engine_flag(req->engine); |
945 | struct i915_vma *vma; | 945 | struct i915_vma *vma; |
946 | uint32_t flush_domains = 0; | ||
947 | bool flush_chipset = false; | ||
948 | int ret; | 946 | int ret; |
949 | 947 | ||
950 | list_for_each_entry(vma, vmas, exec_list) { | 948 | list_for_each_entry(vma, vmas, exec_list) { |
@@ -957,16 +955,11 @@ i915_gem_execbuffer_move_to_gpu(struct drm_i915_gem_request *req, | |||
957 | } | 955 | } |
958 | 956 | ||
959 | if (obj->base.write_domain & I915_GEM_DOMAIN_CPU) | 957 | if (obj->base.write_domain & I915_GEM_DOMAIN_CPU) |
960 | flush_chipset |= i915_gem_clflush_object(obj, false); | 958 | i915_gem_clflush_object(obj, false); |
961 | |||
962 | flush_domains |= obj->base.write_domain; | ||
963 | } | 959 | } |
964 | 960 | ||
965 | if (flush_chipset) | 961 | /* Unconditionally flush any chipset caches (for streaming writes). */ |
966 | i915_gem_chipset_flush(req->engine->i915); | 962 | i915_gem_chipset_flush(req->engine->i915); |
967 | |||
968 | if (flush_domains & I915_GEM_DOMAIN_GTT) | ||
969 | wmb(); | ||
970 | 963 | ||
971 | /* Unconditionally invalidate gpu caches and ensure that we do flush | 964 | /* Unconditionally invalidate gpu caches and ensure that we do flush |
972 | * any residual writes from the previous batch. | 965 | * any residual writes from the previous batch. |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 7a30af79d799..f38ceffd82c3 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -122,8 +122,11 @@ int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv, | |||
122 | has_full_48bit_ppgtt = | 122 | has_full_48bit_ppgtt = |
123 | IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9; | 123 | IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9; |
124 | 124 | ||
125 | if (intel_vgpu_active(dev_priv)) | 125 | if (intel_vgpu_active(dev_priv)) { |
126 | has_full_ppgtt = false; /* emulation is too hard */ | 126 | /* emulation is too hard */ |
127 | has_full_ppgtt = false; | ||
128 | has_full_48bit_ppgtt = false; | ||
129 | } | ||
127 | 130 | ||
128 | if (!has_aliasing_ppgtt) | 131 | if (!has_aliasing_ppgtt) |
129 | return 0; | 132 | return 0; |
@@ -158,7 +161,7 @@ int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv, | |||
158 | return 0; | 161 | return 0; |
159 | } | 162 | } |
160 | 163 | ||
161 | if (INTEL_GEN(dev_priv) >= 8 && i915.enable_execlists) | 164 | if (INTEL_GEN(dev_priv) >= 8 && i915.enable_execlists && has_full_ppgtt) |
162 | return has_full_48bit_ppgtt ? 3 : 2; | 165 | return has_full_48bit_ppgtt ? 3 : 2; |
163 | else | 166 | else |
164 | return has_aliasing_ppgtt ? 1 : 0; | 167 | return has_aliasing_ppgtt ? 1 : 0; |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5c06413ae0e6..bf2cad3f9e1f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -7145,6 +7145,15 @@ enum { | |||
7145 | 7145 | ||
7146 | #define GEN6_PCODE_MAILBOX _MMIO(0x138124) | 7146 | #define GEN6_PCODE_MAILBOX _MMIO(0x138124) |
7147 | #define GEN6_PCODE_READY (1<<31) | 7147 | #define GEN6_PCODE_READY (1<<31) |
7148 | #define GEN6_PCODE_ERROR_MASK 0xFF | ||
7149 | #define GEN6_PCODE_SUCCESS 0x0 | ||
7150 | #define GEN6_PCODE_ILLEGAL_CMD 0x1 | ||
7151 | #define GEN6_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE 0x2 | ||
7152 | #define GEN6_PCODE_TIMEOUT 0x3 | ||
7153 | #define GEN6_PCODE_UNIMPLEMENTED_CMD 0xFF | ||
7154 | #define GEN7_PCODE_TIMEOUT 0x2 | ||
7155 | #define GEN7_PCODE_ILLEGAL_DATA 0x3 | ||
7156 | #define GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE 0x10 | ||
7148 | #define GEN6_PCODE_WRITE_RC6VIDS 0x4 | 7157 | #define GEN6_PCODE_WRITE_RC6VIDS 0x4 |
7149 | #define GEN6_PCODE_READ_RC6VIDS 0x5 | 7158 | #define GEN6_PCODE_READ_RC6VIDS 0x5 |
7150 | #define GEN6_ENCODE_RC6_VID(mv) (((mv) - 245) / 5) | 7159 | #define GEN6_ENCODE_RC6_VID(mv) (((mv) - 245) / 5) |
@@ -7166,6 +7175,10 @@ enum { | |||
7166 | #define HSW_PCODE_DE_WRITE_FREQ_REQ 0x17 | 7175 | #define HSW_PCODE_DE_WRITE_FREQ_REQ 0x17 |
7167 | #define DISPLAY_IPS_CONTROL 0x19 | 7176 | #define DISPLAY_IPS_CONTROL 0x19 |
7168 | #define HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL 0x1A | 7177 | #define HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL 0x1A |
7178 | #define GEN9_PCODE_SAGV_CONTROL 0x21 | ||
7179 | #define GEN9_SAGV_DISABLE 0x0 | ||
7180 | #define GEN9_SAGV_IS_DISABLED 0x1 | ||
7181 | #define GEN9_SAGV_ENABLE 0x3 | ||
7169 | #define GEN6_PCODE_DATA _MMIO(0x138128) | 7182 | #define GEN6_PCODE_DATA _MMIO(0x138128) |
7170 | #define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 | 7183 | #define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 |
7171 | #define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16 | 7184 | #define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16 |
diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c index f6acb5a0e701..b81cfb3b22ec 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.c +++ b/drivers/gpu/drm/i915/i915_vgpu.c | |||
@@ -65,9 +65,6 @@ void i915_check_vgpu(struct drm_i915_private *dev_priv) | |||
65 | 65 | ||
66 | BUILD_BUG_ON(sizeof(struct vgt_if) != VGT_PVINFO_SIZE); | 66 | BUILD_BUG_ON(sizeof(struct vgt_if) != VGT_PVINFO_SIZE); |
67 | 67 | ||
68 | if (!IS_HASWELL(dev_priv)) | ||
69 | return; | ||
70 | |||
71 | magic = __raw_i915_read64(dev_priv, vgtif_reg(magic)); | 68 | magic = __raw_i915_read64(dev_priv, vgtif_reg(magic)); |
72 | if (magic != VGT_MAGIC) | 69 | if (magic != VGT_MAGIC) |
73 | return; | 70 | return; |
diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 3edb9580928e..c3b33a10c15c 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c | |||
@@ -41,15 +41,15 @@ | |||
41 | * be moved to FW_FAILED. | 41 | * be moved to FW_FAILED. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #define I915_CSR_KBL "i915/kbl_dmc_ver1.bin" | 44 | #define I915_CSR_KBL "i915/kbl_dmc_ver1_01.bin" |
45 | MODULE_FIRMWARE(I915_CSR_KBL); | 45 | MODULE_FIRMWARE(I915_CSR_KBL); |
46 | #define KBL_CSR_VERSION_REQUIRED CSR_VERSION(1, 1) | 46 | #define KBL_CSR_VERSION_REQUIRED CSR_VERSION(1, 1) |
47 | 47 | ||
48 | #define I915_CSR_SKL "i915/skl_dmc_ver1.bin" | 48 | #define I915_CSR_SKL "i915/skl_dmc_ver1_26.bin" |
49 | MODULE_FIRMWARE(I915_CSR_SKL); | 49 | MODULE_FIRMWARE(I915_CSR_SKL); |
50 | #define SKL_CSR_VERSION_REQUIRED CSR_VERSION(1, 23) | 50 | #define SKL_CSR_VERSION_REQUIRED CSR_VERSION(1, 26) |
51 | 51 | ||
52 | #define I915_CSR_BXT "i915/bxt_dmc_ver1.bin" | 52 | #define I915_CSR_BXT "i915/bxt_dmc_ver1_07.bin" |
53 | MODULE_FIRMWARE(I915_CSR_BXT); | 53 | MODULE_FIRMWARE(I915_CSR_BXT); |
54 | #define BXT_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) | 54 | #define BXT_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) |
55 | 55 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2a751b6e0253..175595fc3e45 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -13759,6 +13759,13 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) | |||
13759 | intel_state->cdclk_pll_vco != dev_priv->cdclk_pll.vco)) | 13759 | intel_state->cdclk_pll_vco != dev_priv->cdclk_pll.vco)) |
13760 | dev_priv->display.modeset_commit_cdclk(state); | 13760 | dev_priv->display.modeset_commit_cdclk(state); |
13761 | 13761 | ||
13762 | /* | ||
13763 | * SKL workaround: bspec recommends we disable the SAGV when we | ||
13764 | * have more then one pipe enabled | ||
13765 | */ | ||
13766 | if (IS_SKYLAKE(dev_priv) && !skl_can_enable_sagv(state)) | ||
13767 | skl_disable_sagv(dev_priv); | ||
13768 | |||
13762 | intel_modeset_verify_disabled(dev); | 13769 | intel_modeset_verify_disabled(dev); |
13763 | } | 13770 | } |
13764 | 13771 | ||
@@ -13832,6 +13839,10 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) | |||
13832 | intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state); | 13839 | intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state); |
13833 | } | 13840 | } |
13834 | 13841 | ||
13842 | if (IS_SKYLAKE(dev_priv) && intel_state->modeset && | ||
13843 | skl_can_enable_sagv(state)) | ||
13844 | skl_enable_sagv(dev_priv); | ||
13845 | |||
13835 | drm_atomic_helper_commit_hw_done(state); | 13846 | drm_atomic_helper_commit_hw_done(state); |
13836 | 13847 | ||
13837 | if (intel_state->modeset) | 13848 | if (intel_state->modeset) |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index cc937a19b1ba..ff399b9a5c1f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -1716,6 +1716,9 @@ void ilk_wm_get_hw_state(struct drm_device *dev); | |||
1716 | void skl_wm_get_hw_state(struct drm_device *dev); | 1716 | void skl_wm_get_hw_state(struct drm_device *dev); |
1717 | void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, | 1717 | void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, |
1718 | struct skl_ddb_allocation *ddb /* out */); | 1718 | struct skl_ddb_allocation *ddb /* out */); |
1719 | bool skl_can_enable_sagv(struct drm_atomic_state *state); | ||
1720 | int skl_enable_sagv(struct drm_i915_private *dev_priv); | ||
1721 | int skl_disable_sagv(struct drm_i915_private *dev_priv); | ||
1719 | uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config); | 1722 | uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config); |
1720 | bool ilk_disable_lp_wm(struct drm_device *dev); | 1723 | bool ilk_disable_lp_wm(struct drm_device *dev); |
1721 | int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6); | 1724 | int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6); |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 47bdf9dad0d3..b9e5a63a7c9e 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -554,7 +554,6 @@ void intel_dvo_init(struct drm_device *dev) | |||
554 | return; | 554 | return; |
555 | } | 555 | } |
556 | 556 | ||
557 | drm_encoder_cleanup(&intel_encoder->base); | ||
558 | kfree(intel_dvo); | 557 | kfree(intel_dvo); |
559 | kfree(intel_connector); | 558 | kfree(intel_connector); |
560 | } | 559 | } |
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index adca262d591a..7acbbbf97833 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c | |||
@@ -1047,6 +1047,23 @@ err_out: | |||
1047 | return err; | 1047 | return err; |
1048 | } | 1048 | } |
1049 | 1049 | ||
1050 | static int intel_use_opregion_panel_type_callback(const struct dmi_system_id *id) | ||
1051 | { | ||
1052 | DRM_INFO("Using panel type from OpRegion on %s\n", id->ident); | ||
1053 | return 1; | ||
1054 | } | ||
1055 | |||
1056 | static const struct dmi_system_id intel_use_opregion_panel_type[] = { | ||
1057 | { | ||
1058 | .callback = intel_use_opregion_panel_type_callback, | ||
1059 | .ident = "Conrac GmbH IX45GM2", | ||
1060 | .matches = {DMI_MATCH(DMI_SYS_VENDOR, "Conrac GmbH"), | ||
1061 | DMI_MATCH(DMI_PRODUCT_NAME, "IX45GM2"), | ||
1062 | }, | ||
1063 | }, | ||
1064 | { } | ||
1065 | }; | ||
1066 | |||
1050 | int | 1067 | int |
1051 | intel_opregion_get_panel_type(struct drm_i915_private *dev_priv) | 1068 | intel_opregion_get_panel_type(struct drm_i915_private *dev_priv) |
1052 | { | 1069 | { |
@@ -1073,6 +1090,16 @@ intel_opregion_get_panel_type(struct drm_i915_private *dev_priv) | |||
1073 | } | 1090 | } |
1074 | 1091 | ||
1075 | /* | 1092 | /* |
1093 | * So far we know that some machined must use it, others must not use it. | ||
1094 | * There doesn't seem to be any way to determine which way to go, except | ||
1095 | * via a quirk list :( | ||
1096 | */ | ||
1097 | if (!dmi_check_system(intel_use_opregion_panel_type)) { | ||
1098 | DRM_DEBUG_KMS("Ignoring OpRegion panel type (%d)\n", ret - 1); | ||
1099 | return -ENODEV; | ||
1100 | } | ||
1101 | |||
1102 | /* | ||
1076 | * FIXME On Dell XPS 13 9350 the OpRegion panel type (0) gives us | 1103 | * FIXME On Dell XPS 13 9350 the OpRegion panel type (0) gives us |
1077 | * low vswing for eDP, whereas the VBT panel type (2) gives us normal | 1104 | * low vswing for eDP, whereas the VBT panel type (2) gives us normal |
1078 | * vswing instead. Low vswing results in some display flickers, so | 1105 | * vswing instead. Low vswing results in some display flickers, so |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d5deb58a2128..2d2481392824 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -2852,6 +2852,7 @@ bool ilk_disable_lp_wm(struct drm_device *dev) | |||
2852 | 2852 | ||
2853 | #define SKL_DDB_SIZE 896 /* in blocks */ | 2853 | #define SKL_DDB_SIZE 896 /* in blocks */ |
2854 | #define BXT_DDB_SIZE 512 | 2854 | #define BXT_DDB_SIZE 512 |
2855 | #define SKL_SAGV_BLOCK_TIME 30 /* µs */ | ||
2855 | 2856 | ||
2856 | /* | 2857 | /* |
2857 | * Return the index of a plane in the SKL DDB and wm result arrays. Primary | 2858 | * Return the index of a plane in the SKL DDB and wm result arrays. Primary |
@@ -2875,6 +2876,153 @@ skl_wm_plane_id(const struct intel_plane *plane) | |||
2875 | } | 2876 | } |
2876 | } | 2877 | } |
2877 | 2878 | ||
2879 | /* | ||
2880 | * SAGV dynamically adjusts the system agent voltage and clock frequencies | ||
2881 | * depending on power and performance requirements. The display engine access | ||
2882 | * to system memory is blocked during the adjustment time. Because of the | ||
2883 | * blocking time, having this enabled can cause full system hangs and/or pipe | ||
2884 | * underruns if we don't meet all of the following requirements: | ||
2885 | * | ||
2886 | * - <= 1 pipe enabled | ||
2887 | * - All planes can enable watermarks for latencies >= SAGV engine block time | ||
2888 | * - We're not using an interlaced display configuration | ||
2889 | */ | ||
2890 | int | ||
2891 | skl_enable_sagv(struct drm_i915_private *dev_priv) | ||
2892 | { | ||
2893 | int ret; | ||
2894 | |||
2895 | if (dev_priv->skl_sagv_status == I915_SKL_SAGV_NOT_CONTROLLED || | ||
2896 | dev_priv->skl_sagv_status == I915_SKL_SAGV_ENABLED) | ||
2897 | return 0; | ||
2898 | |||
2899 | DRM_DEBUG_KMS("Enabling the SAGV\n"); | ||
2900 | mutex_lock(&dev_priv->rps.hw_lock); | ||
2901 | |||
2902 | ret = sandybridge_pcode_write(dev_priv, GEN9_PCODE_SAGV_CONTROL, | ||
2903 | GEN9_SAGV_ENABLE); | ||
2904 | |||
2905 | /* We don't need to wait for the SAGV when enabling */ | ||
2906 | mutex_unlock(&dev_priv->rps.hw_lock); | ||
2907 | |||
2908 | /* | ||
2909 | * Some skl systems, pre-release machines in particular, | ||
2910 | * don't actually have an SAGV. | ||
2911 | */ | ||
2912 | if (ret == -ENXIO) { | ||
2913 | DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); | ||
2914 | dev_priv->skl_sagv_status = I915_SKL_SAGV_NOT_CONTROLLED; | ||
2915 | return 0; | ||
2916 | } else if (ret < 0) { | ||
2917 | DRM_ERROR("Failed to enable the SAGV\n"); | ||
2918 | return ret; | ||
2919 | } | ||
2920 | |||
2921 | dev_priv->skl_sagv_status = I915_SKL_SAGV_ENABLED; | ||
2922 | return 0; | ||
2923 | } | ||
2924 | |||
2925 | static int | ||
2926 | skl_do_sagv_disable(struct drm_i915_private *dev_priv) | ||
2927 | { | ||
2928 | int ret; | ||
2929 | uint32_t temp = GEN9_SAGV_DISABLE; | ||
2930 | |||
2931 | ret = sandybridge_pcode_read(dev_priv, GEN9_PCODE_SAGV_CONTROL, | ||
2932 | &temp); | ||
2933 | if (ret) | ||
2934 | return ret; | ||
2935 | else | ||
2936 | return temp & GEN9_SAGV_IS_DISABLED; | ||
2937 | } | ||
2938 | |||
2939 | int | ||
2940 | skl_disable_sagv(struct drm_i915_private *dev_priv) | ||
2941 | { | ||
2942 | int ret, result; | ||
2943 | |||
2944 | if (dev_priv->skl_sagv_status == I915_SKL_SAGV_NOT_CONTROLLED || | ||
2945 | dev_priv->skl_sagv_status == I915_SKL_SAGV_DISABLED) | ||
2946 | return 0; | ||
2947 | |||
2948 | DRM_DEBUG_KMS("Disabling the SAGV\n"); | ||
2949 | mutex_lock(&dev_priv->rps.hw_lock); | ||
2950 | |||
2951 | /* bspec says to keep retrying for at least 1 ms */ | ||
2952 | ret = wait_for(result = skl_do_sagv_disable(dev_priv), 1); | ||
2953 | mutex_unlock(&dev_priv->rps.hw_lock); | ||
2954 | |||
2955 | if (ret == -ETIMEDOUT) { | ||
2956 | DRM_ERROR("Request to disable SAGV timed out\n"); | ||
2957 | return -ETIMEDOUT; | ||
2958 | } | ||
2959 | |||
2960 | /* | ||
2961 | * Some skl systems, pre-release machines in particular, | ||
2962 | * don't actually have an SAGV. | ||
2963 | */ | ||
2964 | if (result == -ENXIO) { | ||
2965 | DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); | ||
2966 | dev_priv->skl_sagv_status = I915_SKL_SAGV_NOT_CONTROLLED; | ||
2967 | return 0; | ||
2968 | } else if (result < 0) { | ||
2969 | DRM_ERROR("Failed to disable the SAGV\n"); | ||
2970 | return result; | ||
2971 | } | ||
2972 | |||
2973 | dev_priv->skl_sagv_status = I915_SKL_SAGV_DISABLED; | ||
2974 | return 0; | ||
2975 | } | ||
2976 | |||
2977 | bool skl_can_enable_sagv(struct drm_atomic_state *state) | ||
2978 | { | ||
2979 | struct drm_device *dev = state->dev; | ||
2980 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2981 | struct intel_atomic_state *intel_state = to_intel_atomic_state(state); | ||
2982 | struct drm_crtc *crtc; | ||
2983 | enum pipe pipe; | ||
2984 | int level, plane; | ||
2985 | |||
2986 | /* | ||
2987 | * SKL workaround: bspec recommends we disable the SAGV when we have | ||
2988 | * more then one pipe enabled | ||
2989 | * | ||
2990 | * If there are no active CRTCs, no additional checks need be performed | ||
2991 | */ | ||
2992 | if (hweight32(intel_state->active_crtcs) == 0) | ||
2993 | return true; | ||
2994 | else if (hweight32(intel_state->active_crtcs) > 1) | ||
2995 | return false; | ||
2996 | |||
2997 | /* Since we're now guaranteed to only have one active CRTC... */ | ||
2998 | pipe = ffs(intel_state->active_crtcs) - 1; | ||
2999 | crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | ||
3000 | |||
3001 | if (crtc->state->mode.flags & DRM_MODE_FLAG_INTERLACE) | ||
3002 | return false; | ||
3003 | |||
3004 | for_each_plane(dev_priv, pipe, plane) { | ||
3005 | /* Skip this plane if it's not enabled */ | ||
3006 | if (intel_state->wm_results.plane[pipe][plane][0] == 0) | ||
3007 | continue; | ||
3008 | |||
3009 | /* Find the highest enabled wm level for this plane */ | ||
3010 | for (level = ilk_wm_max_level(dev); | ||
3011 | intel_state->wm_results.plane[pipe][plane][level] == 0; --level) | ||
3012 | { } | ||
3013 | |||
3014 | /* | ||
3015 | * If any of the planes on this pipe don't enable wm levels | ||
3016 | * that incur memory latencies higher then 30µs we can't enable | ||
3017 | * the SAGV | ||
3018 | */ | ||
3019 | if (dev_priv->wm.skl_latency[level] < SKL_SAGV_BLOCK_TIME) | ||
3020 | return false; | ||
3021 | } | ||
3022 | |||
3023 | return true; | ||
3024 | } | ||
3025 | |||
2878 | static void | 3026 | static void |
2879 | skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, | 3027 | skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, |
2880 | const struct intel_crtc_state *cstate, | 3028 | const struct intel_crtc_state *cstate, |
@@ -3107,8 +3255,6 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate) | |||
3107 | total_data_rate += intel_cstate->wm.skl.plane_y_data_rate[id]; | 3255 | total_data_rate += intel_cstate->wm.skl.plane_y_data_rate[id]; |
3108 | } | 3256 | } |
3109 | 3257 | ||
3110 | WARN_ON(cstate->plane_mask && total_data_rate == 0); | ||
3111 | |||
3112 | return total_data_rate; | 3258 | return total_data_rate; |
3113 | } | 3259 | } |
3114 | 3260 | ||
@@ -3912,9 +4058,24 @@ skl_compute_ddb(struct drm_atomic_state *state) | |||
3912 | * pretend that all pipes switched active status so that we'll | 4058 | * pretend that all pipes switched active status so that we'll |
3913 | * ensure a full DDB recompute. | 4059 | * ensure a full DDB recompute. |
3914 | */ | 4060 | */ |
3915 | if (dev_priv->wm.distrust_bios_wm) | 4061 | if (dev_priv->wm.distrust_bios_wm) { |
4062 | ret = drm_modeset_lock(&dev->mode_config.connection_mutex, | ||
4063 | state->acquire_ctx); | ||
4064 | if (ret) | ||
4065 | return ret; | ||
4066 | |||
3916 | intel_state->active_pipe_changes = ~0; | 4067 | intel_state->active_pipe_changes = ~0; |
3917 | 4068 | ||
4069 | /* | ||
4070 | * We usually only initialize intel_state->active_crtcs if we | ||
4071 | * we're doing a modeset; make sure this field is always | ||
4072 | * initialized during the sanitization process that happens | ||
4073 | * on the first commit too. | ||
4074 | */ | ||
4075 | if (!intel_state->modeset) | ||
4076 | intel_state->active_crtcs = dev_priv->active_crtcs; | ||
4077 | } | ||
4078 | |||
3918 | /* | 4079 | /* |
3919 | * If the modeset changes which CRTC's are active, we need to | 4080 | * If the modeset changes which CRTC's are active, we need to |
3920 | * recompute the DDB allocation for *all* active pipes, even | 4081 | * recompute the DDB allocation for *all* active pipes, even |
@@ -3943,11 +4104,33 @@ skl_compute_ddb(struct drm_atomic_state *state) | |||
3943 | ret = skl_allocate_pipe_ddb(cstate, ddb); | 4104 | ret = skl_allocate_pipe_ddb(cstate, ddb); |
3944 | if (ret) | 4105 | if (ret) |
3945 | return ret; | 4106 | return ret; |
4107 | |||
4108 | ret = drm_atomic_add_affected_planes(state, &intel_crtc->base); | ||
4109 | if (ret) | ||
4110 | return ret; | ||
3946 | } | 4111 | } |
3947 | 4112 | ||
3948 | return 0; | 4113 | return 0; |
3949 | } | 4114 | } |
3950 | 4115 | ||
4116 | static void | ||
4117 | skl_copy_wm_for_pipe(struct skl_wm_values *dst, | ||
4118 | struct skl_wm_values *src, | ||
4119 | enum pipe pipe) | ||
4120 | { | ||
4121 | dst->wm_linetime[pipe] = src->wm_linetime[pipe]; | ||
4122 | memcpy(dst->plane[pipe], src->plane[pipe], | ||
4123 | sizeof(dst->plane[pipe])); | ||
4124 | memcpy(dst->plane_trans[pipe], src->plane_trans[pipe], | ||
4125 | sizeof(dst->plane_trans[pipe])); | ||
4126 | |||
4127 | dst->ddb.pipe[pipe] = src->ddb.pipe[pipe]; | ||
4128 | memcpy(dst->ddb.y_plane[pipe], src->ddb.y_plane[pipe], | ||
4129 | sizeof(dst->ddb.y_plane[pipe])); | ||
4130 | memcpy(dst->ddb.plane[pipe], src->ddb.plane[pipe], | ||
4131 | sizeof(dst->ddb.plane[pipe])); | ||
4132 | } | ||
4133 | |||
3951 | static int | 4134 | static int |
3952 | skl_compute_wm(struct drm_atomic_state *state) | 4135 | skl_compute_wm(struct drm_atomic_state *state) |
3953 | { | 4136 | { |
@@ -4020,8 +4203,10 @@ static void skl_update_wm(struct drm_crtc *crtc) | |||
4020 | struct drm_device *dev = crtc->dev; | 4203 | struct drm_device *dev = crtc->dev; |
4021 | struct drm_i915_private *dev_priv = to_i915(dev); | 4204 | struct drm_i915_private *dev_priv = to_i915(dev); |
4022 | struct skl_wm_values *results = &dev_priv->wm.skl_results; | 4205 | struct skl_wm_values *results = &dev_priv->wm.skl_results; |
4206 | struct skl_wm_values *hw_vals = &dev_priv->wm.skl_hw; | ||
4023 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); | 4207 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); |
4024 | struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal; | 4208 | struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal; |
4209 | int pipe; | ||
4025 | 4210 | ||
4026 | if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0) | 4211 | if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0) |
4027 | return; | 4212 | return; |
@@ -4033,8 +4218,12 @@ static void skl_update_wm(struct drm_crtc *crtc) | |||
4033 | skl_write_wm_values(dev_priv, results); | 4218 | skl_write_wm_values(dev_priv, results); |
4034 | skl_flush_wm_values(dev_priv, results); | 4219 | skl_flush_wm_values(dev_priv, results); |
4035 | 4220 | ||
4036 | /* store the new configuration */ | 4221 | /* |
4037 | dev_priv->wm.skl_hw = *results; | 4222 | * Store the new configuration (but only for the pipes that have |
4223 | * changed; the other values weren't recomputed). | ||
4224 | */ | ||
4225 | for_each_pipe_masked(dev_priv, pipe, results->dirty_pipes) | ||
4226 | skl_copy_wm_for_pipe(hw_vals, results, pipe); | ||
4038 | 4227 | ||
4039 | mutex_unlock(&dev_priv->wm.wm_mutex); | 4228 | mutex_unlock(&dev_priv->wm.wm_mutex); |
4040 | } | 4229 | } |
@@ -7658,8 +7847,54 @@ void intel_init_pm(struct drm_device *dev) | |||
7658 | } | 7847 | } |
7659 | } | 7848 | } |
7660 | 7849 | ||
7850 | static inline int gen6_check_mailbox_status(struct drm_i915_private *dev_priv) | ||
7851 | { | ||
7852 | uint32_t flags = | ||
7853 | I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_ERROR_MASK; | ||
7854 | |||
7855 | switch (flags) { | ||
7856 | case GEN6_PCODE_SUCCESS: | ||
7857 | return 0; | ||
7858 | case GEN6_PCODE_UNIMPLEMENTED_CMD: | ||
7859 | case GEN6_PCODE_ILLEGAL_CMD: | ||
7860 | return -ENXIO; | ||
7861 | case GEN6_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE: | ||
7862 | case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE: | ||
7863 | return -EOVERFLOW; | ||
7864 | case GEN6_PCODE_TIMEOUT: | ||
7865 | return -ETIMEDOUT; | ||
7866 | default: | ||
7867 | MISSING_CASE(flags) | ||
7868 | return 0; | ||
7869 | } | ||
7870 | } | ||
7871 | |||
7872 | static inline int gen7_check_mailbox_status(struct drm_i915_private *dev_priv) | ||
7873 | { | ||
7874 | uint32_t flags = | ||
7875 | I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_ERROR_MASK; | ||
7876 | |||
7877 | switch (flags) { | ||
7878 | case GEN6_PCODE_SUCCESS: | ||
7879 | return 0; | ||
7880 | case GEN6_PCODE_ILLEGAL_CMD: | ||
7881 | return -ENXIO; | ||
7882 | case GEN7_PCODE_TIMEOUT: | ||
7883 | return -ETIMEDOUT; | ||
7884 | case GEN7_PCODE_ILLEGAL_DATA: | ||
7885 | return -EINVAL; | ||
7886 | case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE: | ||
7887 | return -EOVERFLOW; | ||
7888 | default: | ||
7889 | MISSING_CASE(flags); | ||
7890 | return 0; | ||
7891 | } | ||
7892 | } | ||
7893 | |||
7661 | int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val) | 7894 | int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val) |
7662 | { | 7895 | { |
7896 | int status; | ||
7897 | |||
7663 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); | 7898 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); |
7664 | 7899 | ||
7665 | /* GEN6_PCODE_* are outside of the forcewake domain, we can | 7900 | /* GEN6_PCODE_* are outside of the forcewake domain, we can |
@@ -7686,12 +7921,25 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val | |||
7686 | *val = I915_READ_FW(GEN6_PCODE_DATA); | 7921 | *val = I915_READ_FW(GEN6_PCODE_DATA); |
7687 | I915_WRITE_FW(GEN6_PCODE_DATA, 0); | 7922 | I915_WRITE_FW(GEN6_PCODE_DATA, 0); |
7688 | 7923 | ||
7924 | if (INTEL_GEN(dev_priv) > 6) | ||
7925 | status = gen7_check_mailbox_status(dev_priv); | ||
7926 | else | ||
7927 | status = gen6_check_mailbox_status(dev_priv); | ||
7928 | |||
7929 | if (status) { | ||
7930 | DRM_DEBUG_DRIVER("warning: pcode (read) mailbox access failed: %d\n", | ||
7931 | status); | ||
7932 | return status; | ||
7933 | } | ||
7934 | |||
7689 | return 0; | 7935 | return 0; |
7690 | } | 7936 | } |
7691 | 7937 | ||
7692 | int sandybridge_pcode_write(struct drm_i915_private *dev_priv, | 7938 | int sandybridge_pcode_write(struct drm_i915_private *dev_priv, |
7693 | u32 mbox, u32 val) | 7939 | u32 mbox, u32 val) |
7694 | { | 7940 | { |
7941 | int status; | ||
7942 | |||
7695 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); | 7943 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); |
7696 | 7944 | ||
7697 | /* GEN6_PCODE_* are outside of the forcewake domain, we can | 7945 | /* GEN6_PCODE_* are outside of the forcewake domain, we can |
@@ -7716,6 +7964,17 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, | |||
7716 | 7964 | ||
7717 | I915_WRITE_FW(GEN6_PCODE_DATA, 0); | 7965 | I915_WRITE_FW(GEN6_PCODE_DATA, 0); |
7718 | 7966 | ||
7967 | if (INTEL_GEN(dev_priv) > 6) | ||
7968 | status = gen7_check_mailbox_status(dev_priv); | ||
7969 | else | ||
7970 | status = gen6_check_mailbox_status(dev_priv); | ||
7971 | |||
7972 | if (status) { | ||
7973 | DRM_DEBUG_DRIVER("warning: pcode (write) mailbox access failed: %d\n", | ||
7974 | status); | ||
7975 | return status; | ||
7976 | } | ||
7977 | |||
7719 | return 0; | 7978 | return 0; |
7720 | } | 7979 | } |
7721 | 7980 | ||
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 2b0d1baf15b3..cf171b4b8c67 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c | |||
@@ -255,14 +255,14 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp) | |||
255 | struct drm_i915_private *dev_priv = to_i915(dev); | 255 | struct drm_i915_private *dev_priv = to_i915(dev); |
256 | 256 | ||
257 | uint32_t max_sleep_time = 0x1f; | 257 | uint32_t max_sleep_time = 0x1f; |
258 | /* Lately it was identified that depending on panel idle frame count | 258 | /* |
259 | * calculated at HW can be off by 1. So let's use what came | 259 | * Let's respect VBT in case VBT asks a higher idle_frame value. |
260 | * from VBT + 1. | 260 | * Let's use 6 as the minimum to cover all known cases including |
261 | * There are also other cases where panel demands at least 4 | 261 | * the off-by-one issue that HW has in some cases. Also there are |
262 | * but VBT is not being set. To cover these 2 cases lets use | 262 | * cases where sink should be able to train |
263 | * at least 5 when VBT isn't set to be on the safest side. | 263 | * with the 5 or 6 idle patterns. |
264 | */ | 264 | */ |
265 | uint32_t idle_frames = dev_priv->vbt.psr.idle_frames + 1; | 265 | uint32_t idle_frames = max(6, dev_priv->vbt.psr.idle_frames); |
266 | uint32_t val = EDP_PSR_ENABLE; | 266 | uint32_t val = EDP_PSR_ENABLE; |
267 | 267 | ||
268 | val |= max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT; | 268 | val |= max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT; |
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 9f7dafce3a4c..7bf90e9e6139 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c | |||
@@ -171,10 +171,34 @@ static void imx_drm_output_poll_changed(struct drm_device *drm) | |||
171 | drm_fbdev_cma_hotplug_event(imxdrm->fbhelper); | 171 | drm_fbdev_cma_hotplug_event(imxdrm->fbhelper); |
172 | } | 172 | } |
173 | 173 | ||
174 | static int imx_drm_atomic_check(struct drm_device *dev, | ||
175 | struct drm_atomic_state *state) | ||
176 | { | ||
177 | int ret; | ||
178 | |||
179 | ret = drm_atomic_helper_check_modeset(dev, state); | ||
180 | if (ret) | ||
181 | return ret; | ||
182 | |||
183 | ret = drm_atomic_helper_check_planes(dev, state); | ||
184 | if (ret) | ||
185 | return ret; | ||
186 | |||
187 | /* | ||
188 | * Check modeset again in case crtc_state->mode_changed is | ||
189 | * updated in plane's ->atomic_check callback. | ||
190 | */ | ||
191 | ret = drm_atomic_helper_check_modeset(dev, state); | ||
192 | if (ret) | ||
193 | return ret; | ||
194 | |||
195 | return ret; | ||
196 | } | ||
197 | |||
174 | static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = { | 198 | static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = { |
175 | .fb_create = drm_fb_cma_create, | 199 | .fb_create = drm_fb_cma_create, |
176 | .output_poll_changed = imx_drm_output_poll_changed, | 200 | .output_poll_changed = imx_drm_output_poll_changed, |
177 | .atomic_check = drm_atomic_helper_check, | 201 | .atomic_check = imx_drm_atomic_check, |
178 | .atomic_commit = drm_atomic_helper_commit, | 202 | .atomic_commit = drm_atomic_helper_commit, |
179 | }; | 203 | }; |
180 | 204 | ||
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index 08e188bc10fc..462056e4b9e4 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c | |||
@@ -76,6 +76,8 @@ static void ipu_crtc_disable(struct drm_crtc *crtc) | |||
76 | crtc->state->event = NULL; | 76 | crtc->state->event = NULL; |
77 | } | 77 | } |
78 | spin_unlock_irq(&crtc->dev->event_lock); | 78 | spin_unlock_irq(&crtc->dev->event_lock); |
79 | |||
80 | drm_crtc_vblank_off(crtc); | ||
79 | } | 81 | } |
80 | 82 | ||
81 | static void imx_drm_crtc_reset(struct drm_crtc *crtc) | 83 | static void imx_drm_crtc_reset(struct drm_crtc *crtc) |
@@ -175,6 +177,8 @@ static int ipu_crtc_atomic_check(struct drm_crtc *crtc, | |||
175 | static void ipu_crtc_atomic_begin(struct drm_crtc *crtc, | 177 | static void ipu_crtc_atomic_begin(struct drm_crtc *crtc, |
176 | struct drm_crtc_state *old_crtc_state) | 178 | struct drm_crtc_state *old_crtc_state) |
177 | { | 179 | { |
180 | drm_crtc_vblank_on(crtc); | ||
181 | |||
178 | spin_lock_irq(&crtc->dev->event_lock); | 182 | spin_lock_irq(&crtc->dev->event_lock); |
179 | if (crtc->state->event) { | 183 | if (crtc->state->event) { |
180 | WARN_ON(drm_crtc_vblank_get(crtc)); | 184 | WARN_ON(drm_crtc_vblank_get(crtc)); |
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index 4ad67d015ec7..29423e757d36 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c | |||
@@ -319,13 +319,14 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, | |||
319 | return -EINVAL; | 319 | return -EINVAL; |
320 | 320 | ||
321 | /* | 321 | /* |
322 | * since we cannot touch active IDMAC channels, we do not support | 322 | * We support resizing active plane or changing its format by |
323 | * resizing the enabled plane or changing its format | 323 | * forcing CRTC mode change and disabling-enabling plane in plane's |
324 | * ->atomic_update callback. | ||
324 | */ | 325 | */ |
325 | if (old_fb && (state->src_w != old_state->src_w || | 326 | if (old_fb && (state->src_w != old_state->src_w || |
326 | state->src_h != old_state->src_h || | 327 | state->src_h != old_state->src_h || |
327 | fb->pixel_format != old_fb->pixel_format)) | 328 | fb->pixel_format != old_fb->pixel_format)) |
328 | return -EINVAL; | 329 | crtc_state->mode_changed = true; |
329 | 330 | ||
330 | eba = drm_plane_state_to_eba(state); | 331 | eba = drm_plane_state_to_eba(state); |
331 | 332 | ||
@@ -336,7 +337,7 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, | |||
336 | return -EINVAL; | 337 | return -EINVAL; |
337 | 338 | ||
338 | if (old_fb && fb->pitches[0] != old_fb->pitches[0]) | 339 | if (old_fb && fb->pitches[0] != old_fb->pitches[0]) |
339 | return -EINVAL; | 340 | crtc_state->mode_changed = true; |
340 | 341 | ||
341 | switch (fb->pixel_format) { | 342 | switch (fb->pixel_format) { |
342 | case DRM_FORMAT_YUV420: | 343 | case DRM_FORMAT_YUV420: |
@@ -372,7 +373,7 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, | |||
372 | return -EINVAL; | 373 | return -EINVAL; |
373 | 374 | ||
374 | if (old_fb && old_fb->pitches[1] != fb->pitches[1]) | 375 | if (old_fb && old_fb->pitches[1] != fb->pitches[1]) |
375 | return -EINVAL; | 376 | crtc_state->mode_changed = true; |
376 | } | 377 | } |
377 | 378 | ||
378 | return 0; | 379 | return 0; |
@@ -392,8 +393,14 @@ static void ipu_plane_atomic_update(struct drm_plane *plane, | |||
392 | enum ipu_color_space ics; | 393 | enum ipu_color_space ics; |
393 | 394 | ||
394 | if (old_state->fb) { | 395 | if (old_state->fb) { |
395 | ipu_plane_atomic_set_base(ipu_plane, old_state); | 396 | struct drm_crtc_state *crtc_state = state->crtc->state; |
396 | return; | 397 | |
398 | if (!crtc_state->mode_changed) { | ||
399 | ipu_plane_atomic_set_base(ipu_plane, old_state); | ||
400 | return; | ||
401 | } | ||
402 | |||
403 | ipu_disable_plane(plane); | ||
397 | } | 404 | } |
398 | 405 | ||
399 | switch (ipu_plane->dp_flow) { | 406 | switch (ipu_plane->dp_flow) { |
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index b4bc7f1ef717..d0da52f2a806 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h | |||
@@ -157,6 +157,12 @@ struct msm_drm_private { | |||
157 | struct shrinker shrinker; | 157 | struct shrinker shrinker; |
158 | 158 | ||
159 | struct msm_vblank_ctrl vblank_ctrl; | 159 | struct msm_vblank_ctrl vblank_ctrl; |
160 | |||
161 | /* task holding struct_mutex.. currently only used in submit path | ||
162 | * to detect and reject faults from copy_from_user() for submit | ||
163 | * ioctl. | ||
164 | */ | ||
165 | struct task_struct *struct_mutex_task; | ||
160 | }; | 166 | }; |
161 | 167 | ||
162 | struct msm_format { | 168 | struct msm_format { |
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 6cd4af443139..85f3047e05ae 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c | |||
@@ -196,11 +196,20 @@ int msm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
196 | { | 196 | { |
197 | struct drm_gem_object *obj = vma->vm_private_data; | 197 | struct drm_gem_object *obj = vma->vm_private_data; |
198 | struct drm_device *dev = obj->dev; | 198 | struct drm_device *dev = obj->dev; |
199 | struct msm_drm_private *priv = dev->dev_private; | ||
199 | struct page **pages; | 200 | struct page **pages; |
200 | unsigned long pfn; | 201 | unsigned long pfn; |
201 | pgoff_t pgoff; | 202 | pgoff_t pgoff; |
202 | int ret; | 203 | int ret; |
203 | 204 | ||
205 | /* This should only happen if userspace tries to pass a mmap'd | ||
206 | * but unfaulted gem bo vaddr into submit ioctl, triggering | ||
207 | * a page fault while struct_mutex is already held. This is | ||
208 | * not a valid use-case so just bail. | ||
209 | */ | ||
210 | if (priv->struct_mutex_task == current) | ||
211 | return VM_FAULT_SIGBUS; | ||
212 | |||
204 | /* Make sure we don't parallel update on a fault, nor move or remove | 213 | /* Make sure we don't parallel update on a fault, nor move or remove |
205 | * something from beneath our feet | 214 | * something from beneath our feet |
206 | */ | 215 | */ |
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 9766f9ae4b7d..880d6a9af7c8 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c | |||
@@ -64,6 +64,14 @@ void msm_gem_submit_free(struct msm_gem_submit *submit) | |||
64 | kfree(submit); | 64 | kfree(submit); |
65 | } | 65 | } |
66 | 66 | ||
67 | static inline unsigned long __must_check | ||
68 | copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) | ||
69 | { | ||
70 | if (access_ok(VERIFY_READ, from, n)) | ||
71 | return __copy_from_user_inatomic(to, from, n); | ||
72 | return -EFAULT; | ||
73 | } | ||
74 | |||
67 | static int submit_lookup_objects(struct msm_gem_submit *submit, | 75 | static int submit_lookup_objects(struct msm_gem_submit *submit, |
68 | struct drm_msm_gem_submit *args, struct drm_file *file) | 76 | struct drm_msm_gem_submit *args, struct drm_file *file) |
69 | { | 77 | { |
@@ -71,6 +79,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, | |||
71 | int ret = 0; | 79 | int ret = 0; |
72 | 80 | ||
73 | spin_lock(&file->table_lock); | 81 | spin_lock(&file->table_lock); |
82 | pagefault_disable(); | ||
74 | 83 | ||
75 | for (i = 0; i < args->nr_bos; i++) { | 84 | for (i = 0; i < args->nr_bos; i++) { |
76 | struct drm_msm_gem_submit_bo submit_bo; | 85 | struct drm_msm_gem_submit_bo submit_bo; |
@@ -84,10 +93,15 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, | |||
84 | */ | 93 | */ |
85 | submit->bos[i].flags = 0; | 94 | submit->bos[i].flags = 0; |
86 | 95 | ||
87 | ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo)); | 96 | ret = copy_from_user_inatomic(&submit_bo, userptr, sizeof(submit_bo)); |
88 | if (ret) { | 97 | if (unlikely(ret)) { |
89 | ret = -EFAULT; | 98 | pagefault_enable(); |
90 | goto out_unlock; | 99 | spin_unlock(&file->table_lock); |
100 | ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo)); | ||
101 | if (ret) | ||
102 | goto out; | ||
103 | spin_lock(&file->table_lock); | ||
104 | pagefault_disable(); | ||
91 | } | 105 | } |
92 | 106 | ||
93 | if (submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) { | 107 | if (submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) { |
@@ -127,9 +141,12 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, | |||
127 | } | 141 | } |
128 | 142 | ||
129 | out_unlock: | 143 | out_unlock: |
130 | submit->nr_bos = i; | 144 | pagefault_enable(); |
131 | spin_unlock(&file->table_lock); | 145 | spin_unlock(&file->table_lock); |
132 | 146 | ||
147 | out: | ||
148 | submit->nr_bos = i; | ||
149 | |||
133 | return ret; | 150 | return ret; |
134 | } | 151 | } |
135 | 152 | ||
@@ -377,6 +394,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, | |||
377 | if (ret) | 394 | if (ret) |
378 | return ret; | 395 | return ret; |
379 | 396 | ||
397 | priv->struct_mutex_task = current; | ||
398 | |||
380 | submit = submit_create(dev, gpu, args->nr_bos, args->nr_cmds); | 399 | submit = submit_create(dev, gpu, args->nr_bos, args->nr_cmds); |
381 | if (!submit) { | 400 | if (!submit) { |
382 | ret = -ENOMEM; | 401 | ret = -ENOMEM; |
@@ -468,6 +487,7 @@ out: | |||
468 | if (ret) | 487 | if (ret) |
469 | msm_gem_submit_free(submit); | 488 | msm_gem_submit_free(submit); |
470 | out_unlock: | 489 | out_unlock: |
490 | priv->struct_mutex_task = NULL; | ||
471 | mutex_unlock(&dev->struct_mutex); | 491 | mutex_unlock(&dev->struct_mutex); |
472 | return ret; | 492 | return ret; |
473 | } | 493 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index f2ad17aa33f0..dc57b628e074 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c | |||
@@ -225,6 +225,17 @@ static bool nouveau_pr3_present(struct pci_dev *pdev) | |||
225 | if (!parent_pdev) | 225 | if (!parent_pdev) |
226 | return false; | 226 | return false; |
227 | 227 | ||
228 | if (!parent_pdev->bridge_d3) { | ||
229 | /* | ||
230 | * Parent PCI bridge is currently not power managed. | ||
231 | * Since userspace can change these afterwards to be on | ||
232 | * the safe side we stick with _DSM and prevent usage of | ||
233 | * _PR3 from the bridge. | ||
234 | */ | ||
235 | pci_d3cold_disable(pdev); | ||
236 | return false; | ||
237 | } | ||
238 | |||
228 | parent_adev = ACPI_COMPANION(&parent_pdev->dev); | 239 | parent_adev = ACPI_COMPANION(&parent_pdev->dev); |
229 | if (!parent_adev) | 240 | if (!parent_adev) |
230 | return false; | 241 | return false; |
diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c index df2657051afd..28c1423049c5 100644 --- a/drivers/gpu/drm/qxl/qxl_fb.c +++ b/drivers/gpu/drm/qxl/qxl_fb.c | |||
@@ -73,10 +73,12 @@ static void qxl_fb_image_init(struct qxl_fb_image *qxl_fb_image, | |||
73 | } | 73 | } |
74 | } | 74 | } |
75 | 75 | ||
76 | #ifdef CONFIG_DRM_FBDEV_EMULATION | ||
76 | static struct fb_deferred_io qxl_defio = { | 77 | static struct fb_deferred_io qxl_defio = { |
77 | .delay = QXL_DIRTY_DELAY, | 78 | .delay = QXL_DIRTY_DELAY, |
78 | .deferred_io = drm_fb_helper_deferred_io, | 79 | .deferred_io = drm_fb_helper_deferred_io, |
79 | }; | 80 | }; |
81 | #endif | ||
80 | 82 | ||
81 | static struct fb_ops qxlfb_ops = { | 83 | static struct fb_ops qxlfb_ops = { |
82 | .owner = THIS_MODULE, | 84 | .owner = THIS_MODULE, |
@@ -313,8 +315,10 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, | |||
313 | goto out_destroy_fbi; | 315 | goto out_destroy_fbi; |
314 | } | 316 | } |
315 | 317 | ||
318 | #ifdef CONFIG_DRM_FBDEV_EMULATION | ||
316 | info->fbdefio = &qxl_defio; | 319 | info->fbdefio = &qxl_defio; |
317 | fb_deferred_io_init(info); | 320 | fb_deferred_io_init(info); |
321 | #endif | ||
318 | 322 | ||
319 | qdev->fbdev_info = info; | 323 | qdev->fbdev_info = info; |
320 | qdev->fbdev_qfb = &qfbdev->qfb; | 324 | qdev->fbdev_qfb = &qfbdev->qfb; |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index a97abc8af657..1dcf39084555 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -627,7 +627,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
627 | if (radeon_crtc->ss.refdiv) { | 627 | if (radeon_crtc->ss.refdiv) { |
628 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; | 628 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; |
629 | radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv; | 629 | radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv; |
630 | if (rdev->family >= CHIP_RV770) | 630 | if (ASIC_IS_AVIVO(rdev) && |
631 | rdev->family != CHIP_RS780 && | ||
632 | rdev->family != CHIP_RS880) | ||
631 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 633 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
632 | } | 634 | } |
633 | } | 635 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 0c00e192c845..c2e0a1ccdfbc 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -263,8 +263,8 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, | |||
263 | 263 | ||
264 | rdev = radeon_get_rdev(bo->bdev); | 264 | rdev = radeon_get_rdev(bo->bdev); |
265 | ridx = radeon_copy_ring_index(rdev); | 265 | ridx = radeon_copy_ring_index(rdev); |
266 | old_start = old_mem->start << PAGE_SHIFT; | 266 | old_start = (u64)old_mem->start << PAGE_SHIFT; |
267 | new_start = new_mem->start << PAGE_SHIFT; | 267 | new_start = (u64)new_mem->start << PAGE_SHIFT; |
268 | 268 | ||
269 | switch (old_mem->mem_type) { | 269 | switch (old_mem->mem_type) { |
270 | case TTM_PL_VRAM: | 270 | case TTM_PL_VRAM: |
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 3d228ad90e0f..3dea1216bafd 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c | |||
@@ -840,6 +840,21 @@ static const struct drm_encoder_funcs tegra_dsi_encoder_funcs = { | |||
840 | .destroy = tegra_output_encoder_destroy, | 840 | .destroy = tegra_output_encoder_destroy, |
841 | }; | 841 | }; |
842 | 842 | ||
843 | static void tegra_dsi_unprepare(struct tegra_dsi *dsi) | ||
844 | { | ||
845 | int err; | ||
846 | |||
847 | if (dsi->slave) | ||
848 | tegra_dsi_unprepare(dsi->slave); | ||
849 | |||
850 | err = tegra_mipi_disable(dsi->mipi); | ||
851 | if (err < 0) | ||
852 | dev_err(dsi->dev, "failed to disable MIPI calibration: %d\n", | ||
853 | err); | ||
854 | |||
855 | pm_runtime_put(dsi->dev); | ||
856 | } | ||
857 | |||
843 | static void tegra_dsi_encoder_disable(struct drm_encoder *encoder) | 858 | static void tegra_dsi_encoder_disable(struct drm_encoder *encoder) |
844 | { | 859 | { |
845 | struct tegra_output *output = encoder_to_output(encoder); | 860 | struct tegra_output *output = encoder_to_output(encoder); |
@@ -876,7 +891,26 @@ static void tegra_dsi_encoder_disable(struct drm_encoder *encoder) | |||
876 | 891 | ||
877 | tegra_dsi_disable(dsi); | 892 | tegra_dsi_disable(dsi); |
878 | 893 | ||
879 | pm_runtime_put(dsi->dev); | 894 | tegra_dsi_unprepare(dsi); |
895 | } | ||
896 | |||
897 | static void tegra_dsi_prepare(struct tegra_dsi *dsi) | ||
898 | { | ||
899 | int err; | ||
900 | |||
901 | pm_runtime_get_sync(dsi->dev); | ||
902 | |||
903 | err = tegra_mipi_enable(dsi->mipi); | ||
904 | if (err < 0) | ||
905 | dev_err(dsi->dev, "failed to enable MIPI calibration: %d\n", | ||
906 | err); | ||
907 | |||
908 | err = tegra_dsi_pad_calibrate(dsi); | ||
909 | if (err < 0) | ||
910 | dev_err(dsi->dev, "MIPI calibration failed: %d\n", err); | ||
911 | |||
912 | if (dsi->slave) | ||
913 | tegra_dsi_prepare(dsi->slave); | ||
880 | } | 914 | } |
881 | 915 | ||
882 | static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) | 916 | static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) |
@@ -887,13 +921,8 @@ static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) | |||
887 | struct tegra_dsi *dsi = to_dsi(output); | 921 | struct tegra_dsi *dsi = to_dsi(output); |
888 | struct tegra_dsi_state *state; | 922 | struct tegra_dsi_state *state; |
889 | u32 value; | 923 | u32 value; |
890 | int err; | ||
891 | |||
892 | pm_runtime_get_sync(dsi->dev); | ||
893 | 924 | ||
894 | err = tegra_dsi_pad_calibrate(dsi); | 925 | tegra_dsi_prepare(dsi); |
895 | if (err < 0) | ||
896 | dev_err(dsi->dev, "MIPI calibration failed: %d\n", err); | ||
897 | 926 | ||
898 | state = tegra_dsi_get_state(dsi); | 927 | state = tegra_dsi_get_state(dsi); |
899 | 928 | ||
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index d5df555aeba0..9688bfa92ccd 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c | |||
@@ -203,6 +203,7 @@ static int udl_fb_open(struct fb_info *info, int user) | |||
203 | 203 | ||
204 | ufbdev->fb_count++; | 204 | ufbdev->fb_count++; |
205 | 205 | ||
206 | #ifdef CONFIG_DRM_FBDEV_EMULATION | ||
206 | if (fb_defio && (info->fbdefio == NULL)) { | 207 | if (fb_defio && (info->fbdefio == NULL)) { |
207 | /* enable defio at last moment if not disabled by client */ | 208 | /* enable defio at last moment if not disabled by client */ |
208 | 209 | ||
@@ -218,6 +219,7 @@ static int udl_fb_open(struct fb_info *info, int user) | |||
218 | info->fbdefio = fbdefio; | 219 | info->fbdefio = fbdefio; |
219 | fb_deferred_io_init(info); | 220 | fb_deferred_io_init(info); |
220 | } | 221 | } |
222 | #endif | ||
221 | 223 | ||
222 | pr_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n", | 224 | pr_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n", |
223 | info->node, user, info, ufbdev->fb_count); | 225 | info->node, user, info, ufbdev->fb_count); |
@@ -235,12 +237,14 @@ static int udl_fb_release(struct fb_info *info, int user) | |||
235 | 237 | ||
236 | ufbdev->fb_count--; | 238 | ufbdev->fb_count--; |
237 | 239 | ||
240 | #ifdef CONFIG_DRM_FBDEV_EMULATION | ||
238 | if ((ufbdev->fb_count == 0) && (info->fbdefio)) { | 241 | if ((ufbdev->fb_count == 0) && (info->fbdefio)) { |
239 | fb_deferred_io_cleanup(info); | 242 | fb_deferred_io_cleanup(info); |
240 | kfree(info->fbdefio); | 243 | kfree(info->fbdefio); |
241 | info->fbdefio = NULL; | 244 | info->fbdefio = NULL; |
242 | info->fbops->fb_mmap = udl_fb_mmap; | 245 | info->fbops->fb_mmap = udl_fb_mmap; |
243 | } | 246 | } |
247 | #endif | ||
244 | 248 | ||
245 | pr_warn("released /dev/fb%d user=%d count=%d\n", | 249 | pr_warn("released /dev/fb%d user=%d count=%d\n", |
246 | info->node, user, ufbdev->fb_count); | 250 | info->node, user, ufbdev->fb_count); |
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 59adcf8532dd..3f6704cf6608 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c | |||
@@ -144,7 +144,7 @@ static struct list_head *vc4_get_cache_list_for_size(struct drm_device *dev, | |||
144 | return &vc4->bo_cache.size_list[page_index]; | 144 | return &vc4->bo_cache.size_list[page_index]; |
145 | } | 145 | } |
146 | 146 | ||
147 | void vc4_bo_cache_purge(struct drm_device *dev) | 147 | static void vc4_bo_cache_purge(struct drm_device *dev) |
148 | { | 148 | { |
149 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 149 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
150 | 150 | ||
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 8b42d31a7f0e..9ecef9385491 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c | |||
@@ -57,21 +57,21 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data, | |||
57 | switch (args->param) { | 57 | switch (args->param) { |
58 | case DRM_VC4_PARAM_V3D_IDENT0: | 58 | case DRM_VC4_PARAM_V3D_IDENT0: |
59 | ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev); | 59 | ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev); |
60 | if (ret) | 60 | if (ret < 0) |
61 | return ret; | 61 | return ret; |
62 | args->value = V3D_READ(V3D_IDENT0); | 62 | args->value = V3D_READ(V3D_IDENT0); |
63 | pm_runtime_put(&vc4->v3d->pdev->dev); | 63 | pm_runtime_put(&vc4->v3d->pdev->dev); |
64 | break; | 64 | break; |
65 | case DRM_VC4_PARAM_V3D_IDENT1: | 65 | case DRM_VC4_PARAM_V3D_IDENT1: |
66 | ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev); | 66 | ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev); |
67 | if (ret) | 67 | if (ret < 0) |
68 | return ret; | 68 | return ret; |
69 | args->value = V3D_READ(V3D_IDENT1); | 69 | args->value = V3D_READ(V3D_IDENT1); |
70 | pm_runtime_put(&vc4->v3d->pdev->dev); | 70 | pm_runtime_put(&vc4->v3d->pdev->dev); |
71 | break; | 71 | break; |
72 | case DRM_VC4_PARAM_V3D_IDENT2: | 72 | case DRM_VC4_PARAM_V3D_IDENT2: |
73 | ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev); | 73 | ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev); |
74 | if (ret) | 74 | if (ret < 0) |
75 | return ret; | 75 | return ret; |
76 | args->value = V3D_READ(V3D_IDENT2); | 76 | args->value = V3D_READ(V3D_IDENT2); |
77 | pm_runtime_put(&vc4->v3d->pdev->dev); | 77 | pm_runtime_put(&vc4->v3d->pdev->dev); |
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 489e3de0c050..428e24919ef1 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h | |||
@@ -321,6 +321,15 @@ vc4_first_render_job(struct vc4_dev *vc4) | |||
321 | struct vc4_exec_info, head); | 321 | struct vc4_exec_info, head); |
322 | } | 322 | } |
323 | 323 | ||
324 | static inline struct vc4_exec_info * | ||
325 | vc4_last_render_job(struct vc4_dev *vc4) | ||
326 | { | ||
327 | if (list_empty(&vc4->render_job_list)) | ||
328 | return NULL; | ||
329 | return list_last_entry(&vc4->render_job_list, | ||
330 | struct vc4_exec_info, head); | ||
331 | } | ||
332 | |||
324 | /** | 333 | /** |
325 | * struct vc4_texture_sample_info - saves the offsets into the UBO for texture | 334 | * struct vc4_texture_sample_info - saves the offsets into the UBO for texture |
326 | * setup parameters. | 335 | * setup parameters. |
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index 6155e8aca1c6..b262c5c26f10 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c | |||
@@ -534,8 +534,8 @@ vc4_cl_lookup_bos(struct drm_device *dev, | |||
534 | return -EINVAL; | 534 | return -EINVAL; |
535 | } | 535 | } |
536 | 536 | ||
537 | exec->bo = kcalloc(exec->bo_count, sizeof(struct drm_gem_cma_object *), | 537 | exec->bo = drm_calloc_large(exec->bo_count, |
538 | GFP_KERNEL); | 538 | sizeof(struct drm_gem_cma_object *)); |
539 | if (!exec->bo) { | 539 | if (!exec->bo) { |
540 | DRM_ERROR("Failed to allocate validated BO pointers\n"); | 540 | DRM_ERROR("Failed to allocate validated BO pointers\n"); |
541 | return -ENOMEM; | 541 | return -ENOMEM; |
@@ -572,8 +572,8 @@ vc4_cl_lookup_bos(struct drm_device *dev, | |||
572 | spin_unlock(&file_priv->table_lock); | 572 | spin_unlock(&file_priv->table_lock); |
573 | 573 | ||
574 | fail: | 574 | fail: |
575 | kfree(handles); | 575 | drm_free_large(handles); |
576 | return 0; | 576 | return ret; |
577 | } | 577 | } |
578 | 578 | ||
579 | static int | 579 | static int |
@@ -608,7 +608,7 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec) | |||
608 | * read the contents back for validation, and I think the | 608 | * read the contents back for validation, and I think the |
609 | * bo->vaddr is uncached access. | 609 | * bo->vaddr is uncached access. |
610 | */ | 610 | */ |
611 | temp = kmalloc(temp_size, GFP_KERNEL); | 611 | temp = drm_malloc_ab(temp_size, 1); |
612 | if (!temp) { | 612 | if (!temp) { |
613 | DRM_ERROR("Failed to allocate storage for copying " | 613 | DRM_ERROR("Failed to allocate storage for copying " |
614 | "in bin/render CLs.\n"); | 614 | "in bin/render CLs.\n"); |
@@ -675,7 +675,7 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec) | |||
675 | ret = vc4_validate_shader_recs(dev, exec); | 675 | ret = vc4_validate_shader_recs(dev, exec); |
676 | 676 | ||
677 | fail: | 677 | fail: |
678 | kfree(temp); | 678 | drm_free_large(temp); |
679 | return ret; | 679 | return ret; |
680 | } | 680 | } |
681 | 681 | ||
@@ -688,7 +688,7 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec) | |||
688 | if (exec->bo) { | 688 | if (exec->bo) { |
689 | for (i = 0; i < exec->bo_count; i++) | 689 | for (i = 0; i < exec->bo_count; i++) |
690 | drm_gem_object_unreference_unlocked(&exec->bo[i]->base); | 690 | drm_gem_object_unreference_unlocked(&exec->bo[i]->base); |
691 | kfree(exec->bo); | 691 | drm_free_large(exec->bo); |
692 | } | 692 | } |
693 | 693 | ||
694 | while (!list_empty(&exec->unref_list)) { | 694 | while (!list_empty(&exec->unref_list)) { |
@@ -942,8 +942,8 @@ vc4_gem_destroy(struct drm_device *dev) | |||
942 | vc4->overflow_mem = NULL; | 942 | vc4->overflow_mem = NULL; |
943 | } | 943 | } |
944 | 944 | ||
945 | vc4_bo_cache_destroy(dev); | ||
946 | |||
947 | if (vc4->hang_state) | 945 | if (vc4->hang_state) |
948 | vc4_free_hang_state(dev, vc4->hang_state); | 946 | vc4_free_hang_state(dev, vc4->hang_state); |
947 | |||
948 | vc4_bo_cache_destroy(dev); | ||
949 | } | 949 | } |
diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c index b0104a346a74..094bc6a475c1 100644 --- a/drivers/gpu/drm/vc4/vc4_irq.c +++ b/drivers/gpu/drm/vc4/vc4_irq.c | |||
@@ -83,8 +83,10 @@ vc4_overflow_mem_work(struct work_struct *work) | |||
83 | 83 | ||
84 | spin_lock_irqsave(&vc4->job_lock, irqflags); | 84 | spin_lock_irqsave(&vc4->job_lock, irqflags); |
85 | current_exec = vc4_first_bin_job(vc4); | 85 | current_exec = vc4_first_bin_job(vc4); |
86 | if (!current_exec) | ||
87 | current_exec = vc4_last_render_job(vc4); | ||
86 | if (current_exec) { | 88 | if (current_exec) { |
87 | vc4->overflow_mem->seqno = vc4->finished_seqno + 1; | 89 | vc4->overflow_mem->seqno = current_exec->seqno; |
88 | list_add_tail(&vc4->overflow_mem->unref_head, | 90 | list_add_tail(&vc4->overflow_mem->unref_head, |
89 | ¤t_exec->unref_list); | 91 | ¤t_exec->unref_list); |
90 | vc4->overflow_mem = NULL; | 92 | vc4->overflow_mem = NULL; |
diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c index 46527e989ce3..2543cf5b8b51 100644 --- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c +++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c | |||
@@ -309,8 +309,14 @@ validate_uniform_address_write(struct vc4_validated_shader_info *validated_shade | |||
309 | * of uniforms on each side. However, this scheme is easy to | 309 | * of uniforms on each side. However, this scheme is easy to |
310 | * validate so it's all we allow for now. | 310 | * validate so it's all we allow for now. |
311 | */ | 311 | */ |
312 | 312 | switch (QPU_GET_FIELD(inst, QPU_SIG)) { | |
313 | if (QPU_GET_FIELD(inst, QPU_SIG) != QPU_SIG_NONE) { | 313 | case QPU_SIG_NONE: |
314 | case QPU_SIG_SCOREBOARD_UNLOCK: | ||
315 | case QPU_SIG_COLOR_LOAD: | ||
316 | case QPU_SIG_LOAD_TMU0: | ||
317 | case QPU_SIG_LOAD_TMU1: | ||
318 | break; | ||
319 | default: | ||
314 | DRM_ERROR("uniforms address change must be " | 320 | DRM_ERROR("uniforms address change must be " |
315 | "normal math\n"); | 321 | "normal math\n"); |
316 | return false; | 322 | return false; |
diff --git a/drivers/gpu/host1x/mipi.c b/drivers/gpu/host1x/mipi.c index 52a6fd224127..e00809d996a2 100644 --- a/drivers/gpu/host1x/mipi.c +++ b/drivers/gpu/host1x/mipi.c | |||
@@ -242,20 +242,6 @@ struct tegra_mipi_device *tegra_mipi_request(struct device *device) | |||
242 | dev->pads = args.args[0]; | 242 | dev->pads = args.args[0]; |
243 | dev->device = device; | 243 | dev->device = device; |
244 | 244 | ||
245 | mutex_lock(&dev->mipi->lock); | ||
246 | |||
247 | if (dev->mipi->usage_count++ == 0) { | ||
248 | err = tegra_mipi_power_up(dev->mipi); | ||
249 | if (err < 0) { | ||
250 | dev_err(dev->mipi->dev, | ||
251 | "failed to power up MIPI bricks: %d\n", | ||
252 | err); | ||
253 | return ERR_PTR(err); | ||
254 | } | ||
255 | } | ||
256 | |||
257 | mutex_unlock(&dev->mipi->lock); | ||
258 | |||
259 | return dev; | 245 | return dev; |
260 | 246 | ||
261 | put: | 247 | put: |
@@ -270,29 +256,42 @@ EXPORT_SYMBOL(tegra_mipi_request); | |||
270 | 256 | ||
271 | void tegra_mipi_free(struct tegra_mipi_device *device) | 257 | void tegra_mipi_free(struct tegra_mipi_device *device) |
272 | { | 258 | { |
273 | int err; | 259 | platform_device_put(device->pdev); |
260 | kfree(device); | ||
261 | } | ||
262 | EXPORT_SYMBOL(tegra_mipi_free); | ||
274 | 263 | ||
275 | mutex_lock(&device->mipi->lock); | 264 | int tegra_mipi_enable(struct tegra_mipi_device *dev) |
265 | { | ||
266 | int err = 0; | ||
276 | 267 | ||
277 | if (--device->mipi->usage_count == 0) { | 268 | mutex_lock(&dev->mipi->lock); |
278 | err = tegra_mipi_power_down(device->mipi); | ||
279 | if (err < 0) { | ||
280 | /* | ||
281 | * Not much that can be done here, so an error message | ||
282 | * will have to do. | ||
283 | */ | ||
284 | dev_err(device->mipi->dev, | ||
285 | "failed to power down MIPI bricks: %d\n", | ||
286 | err); | ||
287 | } | ||
288 | } | ||
289 | 269 | ||
290 | mutex_unlock(&device->mipi->lock); | 270 | if (dev->mipi->usage_count++ == 0) |
271 | err = tegra_mipi_power_up(dev->mipi); | ||
272 | |||
273 | mutex_unlock(&dev->mipi->lock); | ||
274 | |||
275 | return err; | ||
291 | 276 | ||
292 | platform_device_put(device->pdev); | ||
293 | kfree(device); | ||
294 | } | 277 | } |
295 | EXPORT_SYMBOL(tegra_mipi_free); | 278 | EXPORT_SYMBOL(tegra_mipi_enable); |
279 | |||
280 | int tegra_mipi_disable(struct tegra_mipi_device *dev) | ||
281 | { | ||
282 | int err = 0; | ||
283 | |||
284 | mutex_lock(&dev->mipi->lock); | ||
285 | |||
286 | if (--dev->mipi->usage_count == 0) | ||
287 | err = tegra_mipi_power_down(dev->mipi); | ||
288 | |||
289 | mutex_unlock(&dev->mipi->lock); | ||
290 | |||
291 | return err; | ||
292 | |||
293 | } | ||
294 | EXPORT_SYMBOL(tegra_mipi_disable); | ||
296 | 295 | ||
297 | static int tegra_mipi_wait(struct tegra_mipi *mipi) | 296 | static int tegra_mipi_wait(struct tegra_mipi *mipi) |
298 | { | 297 | { |
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index d0203a115eff..4667012b46b7 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -2015,6 +2015,7 @@ static struct attribute *it87_attributes_in[] = { | |||
2015 | &sensor_dev_attr_in10_input.dev_attr.attr, /* 41 */ | 2015 | &sensor_dev_attr_in10_input.dev_attr.attr, /* 41 */ |
2016 | &sensor_dev_attr_in11_input.dev_attr.attr, /* 41 */ | 2016 | &sensor_dev_attr_in11_input.dev_attr.attr, /* 41 */ |
2017 | &sensor_dev_attr_in12_input.dev_attr.attr, /* 41 */ | 2017 | &sensor_dev_attr_in12_input.dev_attr.attr, /* 41 */ |
2018 | NULL | ||
2018 | }; | 2019 | }; |
2019 | 2020 | ||
2020 | static const struct attribute_group it87_group_in = { | 2021 | static const struct attribute_group it87_group_in = { |
diff --git a/drivers/i2c/busses/i2c-bcm-kona.c b/drivers/i2c/busses/i2c-bcm-kona.c index f98743277e3c..258cb9a40ab3 100644 --- a/drivers/i2c/busses/i2c-bcm-kona.c +++ b/drivers/i2c/busses/i2c-bcm-kona.c | |||
@@ -643,7 +643,7 @@ static int bcm_kona_i2c_xfer(struct i2c_adapter *adapter, | |||
643 | if (rc < 0) { | 643 | if (rc < 0) { |
644 | dev_err(dev->device, | 644 | dev_err(dev->device, |
645 | "restart cmd failed rc = %d\n", rc); | 645 | "restart cmd failed rc = %d\n", rc); |
646 | goto xfer_send_stop; | 646 | goto xfer_send_stop; |
647 | } | 647 | } |
648 | } | 648 | } |
649 | 649 | ||
diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index 90bbd9f9dd8f..3c16a2f7c673 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c | |||
@@ -767,7 +767,7 @@ static int cdns_i2c_setclk(unsigned long clk_in, struct cdns_i2c *id) | |||
767 | * depending on the scaling direction. | 767 | * depending on the scaling direction. |
768 | * | 768 | * |
769 | * Return: NOTIFY_STOP if the rate change should be aborted, NOTIFY_OK | 769 | * Return: NOTIFY_STOP if the rate change should be aborted, NOTIFY_OK |
770 | * to acknowedge the change, NOTIFY_DONE if the notification is | 770 | * to acknowledge the change, NOTIFY_DONE if the notification is |
771 | * considered irrelevant. | 771 | * considered irrelevant. |
772 | */ | 772 | */ |
773 | static int cdns_i2c_clk_notifier_cb(struct notifier_block *nb, unsigned long | 773 | static int cdns_i2c_clk_notifier_cb(struct notifier_block *nb, unsigned long |
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index c6922b806fb7..fcd973d5131e 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c | |||
@@ -367,13 +367,17 @@ int i2c_dw_init(struct dw_i2c_dev *dev) | |||
367 | dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt); | 367 | dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt); |
368 | 368 | ||
369 | /* Configure SDA Hold Time if required */ | 369 | /* Configure SDA Hold Time if required */ |
370 | if (dev->sda_hold_time) { | 370 | reg = dw_readl(dev, DW_IC_COMP_VERSION); |
371 | reg = dw_readl(dev, DW_IC_COMP_VERSION); | 371 | if (reg >= DW_IC_SDA_HOLD_MIN_VERS) { |
372 | if (reg >= DW_IC_SDA_HOLD_MIN_VERS) | 372 | if (dev->sda_hold_time) { |
373 | dw_writel(dev, dev->sda_hold_time, DW_IC_SDA_HOLD); | 373 | dw_writel(dev, dev->sda_hold_time, DW_IC_SDA_HOLD); |
374 | else | 374 | } else { |
375 | dev_warn(dev->dev, | 375 | /* Keep previous hold time setting if no one set it */ |
376 | "Hardware too old to adjust SDA hold time."); | 376 | dev->sda_hold_time = dw_readl(dev, DW_IC_SDA_HOLD); |
377 | } | ||
378 | } else { | ||
379 | dev_warn(dev->dev, | ||
380 | "Hardware too old to adjust SDA hold time.\n"); | ||
377 | } | 381 | } |
378 | 382 | ||
379 | /* Configure Tx/Rx FIFO threshold levels */ | 383 | /* Configure Tx/Rx FIFO threshold levels */ |
diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index 137125b5eae7..5ce71ce7b6c4 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c | |||
@@ -773,13 +773,6 @@ static int pch_i2c_probe(struct pci_dev *pdev, | |||
773 | /* Set the number of I2C channel instance */ | 773 | /* Set the number of I2C channel instance */ |
774 | adap_info->ch_num = id->driver_data; | 774 | adap_info->ch_num = id->driver_data; |
775 | 775 | ||
776 | ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED, | ||
777 | KBUILD_MODNAME, adap_info); | ||
778 | if (ret) { | ||
779 | pch_pci_err(pdev, "request_irq FAILED\n"); | ||
780 | goto err_request_irq; | ||
781 | } | ||
782 | |||
783 | for (i = 0; i < adap_info->ch_num; i++) { | 776 | for (i = 0; i < adap_info->ch_num; i++) { |
784 | pch_adap = &adap_info->pch_data[i].pch_adapter; | 777 | pch_adap = &adap_info->pch_data[i].pch_adapter; |
785 | adap_info->pch_i2c_suspended = false; | 778 | adap_info->pch_i2c_suspended = false; |
@@ -797,6 +790,17 @@ static int pch_i2c_probe(struct pci_dev *pdev, | |||
797 | 790 | ||
798 | pch_adap->dev.of_node = pdev->dev.of_node; | 791 | pch_adap->dev.of_node = pdev->dev.of_node; |
799 | pch_adap->dev.parent = &pdev->dev; | 792 | pch_adap->dev.parent = &pdev->dev; |
793 | } | ||
794 | |||
795 | ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED, | ||
796 | KBUILD_MODNAME, adap_info); | ||
797 | if (ret) { | ||
798 | pch_pci_err(pdev, "request_irq FAILED\n"); | ||
799 | goto err_request_irq; | ||
800 | } | ||
801 | |||
802 | for (i = 0; i < adap_info->ch_num; i++) { | ||
803 | pch_adap = &adap_info->pch_data[i].pch_adapter; | ||
800 | 804 | ||
801 | pch_i2c_init(&adap_info->pch_data[i]); | 805 | pch_i2c_init(&adap_info->pch_data[i]); |
802 | 806 | ||
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c index 501bd15cb78e..a8497cfdae6f 100644 --- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c | |||
@@ -1599,7 +1599,8 @@ static int qup_i2c_pm_resume_runtime(struct device *device) | |||
1599 | #ifdef CONFIG_PM_SLEEP | 1599 | #ifdef CONFIG_PM_SLEEP |
1600 | static int qup_i2c_suspend(struct device *device) | 1600 | static int qup_i2c_suspend(struct device *device) |
1601 | { | 1601 | { |
1602 | qup_i2c_pm_suspend_runtime(device); | 1602 | if (!pm_runtime_suspended(device)) |
1603 | return qup_i2c_pm_suspend_runtime(device); | ||
1603 | return 0; | 1604 | return 0; |
1604 | } | 1605 | } |
1605 | 1606 | ||
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 52407f3c9e1c..9bd849dacee8 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c | |||
@@ -378,7 +378,7 @@ static void rcar_i2c_dma(struct rcar_i2c_priv *priv) | |||
378 | } | 378 | } |
379 | 379 | ||
380 | dma_addr = dma_map_single(chan->device->dev, buf, len, dir); | 380 | dma_addr = dma_map_single(chan->device->dev, buf, len, dir); |
381 | if (dma_mapping_error(dev, dma_addr)) { | 381 | if (dma_mapping_error(chan->device->dev, dma_addr)) { |
382 | dev_dbg(dev, "dma map failed, using PIO\n"); | 382 | dev_dbg(dev, "dma map failed, using PIO\n"); |
383 | return; | 383 | return; |
384 | } | 384 | } |
diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c index 2bc8b01153d6..5c5b7cada8be 100644 --- a/drivers/i2c/busses/i2c-rk3x.c +++ b/drivers/i2c/busses/i2c-rk3x.c | |||
@@ -918,7 +918,7 @@ static void rk3x_i2c_adapt_div(struct rk3x_i2c *i2c, unsigned long clk_rate) | |||
918 | * Code adapted from i2c-cadence.c. | 918 | * Code adapted from i2c-cadence.c. |
919 | * | 919 | * |
920 | * Return: NOTIFY_STOP if the rate change should be aborted, NOTIFY_OK | 920 | * Return: NOTIFY_STOP if the rate change should be aborted, NOTIFY_OK |
921 | * to acknowedge the change, NOTIFY_DONE if the notification is | 921 | * to acknowledge the change, NOTIFY_DONE if the notification is |
922 | * considered irrelevant. | 922 | * considered irrelevant. |
923 | */ | 923 | */ |
924 | static int rk3x_i2c_clk_notifier_cb(struct notifier_block *nb, unsigned long | 924 | static int rk3x_i2c_clk_notifier_cb(struct notifier_block *nb, unsigned long |
@@ -1111,6 +1111,15 @@ static int rk3x_i2c_xfer(struct i2c_adapter *adap, | |||
1111 | return ret < 0 ? ret : num; | 1111 | return ret < 0 ? ret : num; |
1112 | } | 1112 | } |
1113 | 1113 | ||
1114 | static __maybe_unused int rk3x_i2c_resume(struct device *dev) | ||
1115 | { | ||
1116 | struct rk3x_i2c *i2c = dev_get_drvdata(dev); | ||
1117 | |||
1118 | rk3x_i2c_adapt_div(i2c, clk_get_rate(i2c->clk)); | ||
1119 | |||
1120 | return 0; | ||
1121 | } | ||
1122 | |||
1114 | static u32 rk3x_i2c_func(struct i2c_adapter *adap) | 1123 | static u32 rk3x_i2c_func(struct i2c_adapter *adap) |
1115 | { | 1124 | { |
1116 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING; | 1125 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING; |
@@ -1334,12 +1343,15 @@ static int rk3x_i2c_remove(struct platform_device *pdev) | |||
1334 | return 0; | 1343 | return 0; |
1335 | } | 1344 | } |
1336 | 1345 | ||
1346 | static SIMPLE_DEV_PM_OPS(rk3x_i2c_pm_ops, NULL, rk3x_i2c_resume); | ||
1347 | |||
1337 | static struct platform_driver rk3x_i2c_driver = { | 1348 | static struct platform_driver rk3x_i2c_driver = { |
1338 | .probe = rk3x_i2c_probe, | 1349 | .probe = rk3x_i2c_probe, |
1339 | .remove = rk3x_i2c_remove, | 1350 | .remove = rk3x_i2c_remove, |
1340 | .driver = { | 1351 | .driver = { |
1341 | .name = "rk3x-i2c", | 1352 | .name = "rk3x-i2c", |
1342 | .of_match_table = rk3x_i2c_match, | 1353 | .of_match_table = rk3x_i2c_match, |
1354 | .pm = &rk3x_i2c_pm_ops, | ||
1343 | }, | 1355 | }, |
1344 | }; | 1356 | }; |
1345 | 1357 | ||
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 6fb3e2645992..05b1eeab9cf5 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c | |||
@@ -610,7 +610,7 @@ static void sh_mobile_i2c_xfer_dma(struct sh_mobile_i2c_data *pd) | |||
610 | return; | 610 | return; |
611 | 611 | ||
612 | dma_addr = dma_map_single(chan->device->dev, pd->msg->buf, pd->msg->len, dir); | 612 | dma_addr = dma_map_single(chan->device->dev, pd->msg->buf, pd->msg->len, dir); |
613 | if (dma_mapping_error(pd->dev, dma_addr)) { | 613 | if (dma_mapping_error(chan->device->dev, dma_addr)) { |
614 | dev_dbg(pd->dev, "dma map failed, using PIO\n"); | 614 | dev_dbg(pd->dev, "dma map failed, using PIO\n"); |
615 | return; | 615 | return; |
616 | } | 616 | } |
diff --git a/drivers/i2c/muxes/i2c-demux-pinctrl.c b/drivers/i2c/muxes/i2c-demux-pinctrl.c index 215ac87f606d..b3893f6282ba 100644 --- a/drivers/i2c/muxes/i2c-demux-pinctrl.c +++ b/drivers/i2c/muxes/i2c-demux-pinctrl.c | |||
@@ -37,8 +37,6 @@ struct i2c_demux_pinctrl_priv { | |||
37 | struct i2c_demux_pinctrl_chan chan[]; | 37 | struct i2c_demux_pinctrl_chan chan[]; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static struct property status_okay = { .name = "status", .length = 3, .value = "ok" }; | ||
41 | |||
42 | static int i2c_demux_master_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | 40 | static int i2c_demux_master_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) |
43 | { | 41 | { |
44 | struct i2c_demux_pinctrl_priv *priv = adap->algo_data; | 42 | struct i2c_demux_pinctrl_priv *priv = adap->algo_data; |
@@ -107,6 +105,7 @@ static int i2c_demux_activate_master(struct i2c_demux_pinctrl_priv *priv, u32 ne | |||
107 | of_changeset_revert(&priv->chan[new_chan].chgset); | 105 | of_changeset_revert(&priv->chan[new_chan].chgset); |
108 | err: | 106 | err: |
109 | dev_err(priv->dev, "failed to setup demux-adapter %d (%d)\n", new_chan, ret); | 107 | dev_err(priv->dev, "failed to setup demux-adapter %d (%d)\n", new_chan, ret); |
108 | priv->cur_chan = -EINVAL; | ||
110 | return ret; | 109 | return ret; |
111 | } | 110 | } |
112 | 111 | ||
@@ -192,6 +191,7 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev) | |||
192 | { | 191 | { |
193 | struct device_node *np = pdev->dev.of_node; | 192 | struct device_node *np = pdev->dev.of_node; |
194 | struct i2c_demux_pinctrl_priv *priv; | 193 | struct i2c_demux_pinctrl_priv *priv; |
194 | struct property *props; | ||
195 | int num_chan, i, j, err; | 195 | int num_chan, i, j, err; |
196 | 196 | ||
197 | num_chan = of_count_phandle_with_args(np, "i2c-parent", NULL); | 197 | num_chan = of_count_phandle_with_args(np, "i2c-parent", NULL); |
@@ -202,7 +202,10 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev) | |||
202 | 202 | ||
203 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv) | 203 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv) |
204 | + num_chan * sizeof(struct i2c_demux_pinctrl_chan), GFP_KERNEL); | 204 | + num_chan * sizeof(struct i2c_demux_pinctrl_chan), GFP_KERNEL); |
205 | if (!priv) | 205 | |
206 | props = devm_kcalloc(&pdev->dev, num_chan, sizeof(*props), GFP_KERNEL); | ||
207 | |||
208 | if (!priv || !props) | ||
206 | return -ENOMEM; | 209 | return -ENOMEM; |
207 | 210 | ||
208 | err = of_property_read_string(np, "i2c-bus-name", &priv->bus_name); | 211 | err = of_property_read_string(np, "i2c-bus-name", &priv->bus_name); |
@@ -220,8 +223,12 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev) | |||
220 | } | 223 | } |
221 | priv->chan[i].parent_np = adap_np; | 224 | priv->chan[i].parent_np = adap_np; |
222 | 225 | ||
226 | props[i].name = devm_kstrdup(&pdev->dev, "status", GFP_KERNEL); | ||
227 | props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL); | ||
228 | props[i].length = 3; | ||
229 | |||
223 | of_changeset_init(&priv->chan[i].chgset); | 230 | of_changeset_init(&priv->chan[i].chgset); |
224 | of_changeset_update_property(&priv->chan[i].chgset, adap_np, &status_okay); | 231 | of_changeset_update_property(&priv->chan[i].chgset, adap_np, &props[i]); |
225 | } | 232 | } |
226 | 233 | ||
227 | priv->num_chan = num_chan; | 234 | priv->num_chan = num_chan; |
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c index 528e755c468f..3278ebf1cc5c 100644 --- a/drivers/i2c/muxes/i2c-mux-pca954x.c +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c | |||
@@ -164,7 +164,7 @@ static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan) | |||
164 | /* Only select the channel if its different from the last channel */ | 164 | /* Only select the channel if its different from the last channel */ |
165 | if (data->last_chan != regval) { | 165 | if (data->last_chan != regval) { |
166 | ret = pca954x_reg_write(muxc->parent, client, regval); | 166 | ret = pca954x_reg_write(muxc->parent, client, regval); |
167 | data->last_chan = regval; | 167 | data->last_chan = ret ? 0 : regval; |
168 | } | 168 | } |
169 | 169 | ||
170 | return ret; | 170 | return ret; |
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index 89d78208de3f..78f148ea9d9f 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig | |||
@@ -20,6 +20,8 @@ config BMA180 | |||
20 | config BMA220 | 20 | config BMA220 |
21 | tristate "Bosch BMA220 3-Axis Accelerometer Driver" | 21 | tristate "Bosch BMA220 3-Axis Accelerometer Driver" |
22 | depends on SPI | 22 | depends on SPI |
23 | select IIO_BUFFER | ||
24 | select IIO_TRIGGERED_BUFFER | ||
23 | help | 25 | help |
24 | Say yes here to add support for the Bosch BMA220 triaxial | 26 | Say yes here to add support for the Bosch BMA220 triaxial |
25 | acceleration sensor. | 27 | acceleration sensor. |
@@ -234,7 +236,8 @@ config STK8312 | |||
234 | config STK8BA50 | 236 | config STK8BA50 |
235 | tristate "Sensortek STK8BA50 3-Axis Accelerometer Driver" | 237 | tristate "Sensortek STK8BA50 3-Axis Accelerometer Driver" |
236 | depends on I2C | 238 | depends on I2C |
237 | depends on IIO_TRIGGER | 239 | select IIO_BUFFER |
240 | select IIO_TRIGGERED_BUFFER | ||
238 | help | 241 | help |
239 | Say yes here to get support for the Sensortek STK8BA50 3-axis | 242 | Say yes here to get support for the Sensortek STK8BA50 3-axis |
240 | accelerometer. | 243 | accelerometer. |
diff --git a/drivers/iio/accel/bma220_spi.c b/drivers/iio/accel/bma220_spi.c index 1098d10df8e8..5099f295dd37 100644 --- a/drivers/iio/accel/bma220_spi.c +++ b/drivers/iio/accel/bma220_spi.c | |||
@@ -253,7 +253,7 @@ static int bma220_probe(struct spi_device *spi) | |||
253 | if (ret < 0) | 253 | if (ret < 0) |
254 | return ret; | 254 | return ret; |
255 | 255 | ||
256 | ret = iio_triggered_buffer_setup(indio_dev, NULL, | 256 | ret = iio_triggered_buffer_setup(indio_dev, iio_pollfunc_store_time, |
257 | bma220_trigger_handler, NULL); | 257 | bma220_trigger_handler, NULL); |
258 | if (ret < 0) { | 258 | if (ret < 0) { |
259 | dev_err(&spi->dev, "iio triggered buffer setup failed\n"); | 259 | dev_err(&spi->dev, "iio triggered buffer setup failed\n"); |
diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index bf17aae66145..59b380dbf27f 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c | |||
@@ -67,6 +67,9 @@ | |||
67 | #define BMC150_ACCEL_REG_PMU_BW 0x10 | 67 | #define BMC150_ACCEL_REG_PMU_BW 0x10 |
68 | #define BMC150_ACCEL_DEF_BW 125 | 68 | #define BMC150_ACCEL_DEF_BW 125 |
69 | 69 | ||
70 | #define BMC150_ACCEL_REG_RESET 0x14 | ||
71 | #define BMC150_ACCEL_RESET_VAL 0xB6 | ||
72 | |||
70 | #define BMC150_ACCEL_REG_INT_MAP_0 0x19 | 73 | #define BMC150_ACCEL_REG_INT_MAP_0 0x19 |
71 | #define BMC150_ACCEL_INT_MAP_0_BIT_SLOPE BIT(2) | 74 | #define BMC150_ACCEL_INT_MAP_0_BIT_SLOPE BIT(2) |
72 | 75 | ||
@@ -1497,6 +1500,14 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data) | |||
1497 | int ret, i; | 1500 | int ret, i; |
1498 | unsigned int val; | 1501 | unsigned int val; |
1499 | 1502 | ||
1503 | /* | ||
1504 | * Reset chip to get it in a known good state. A delay of 1.8ms after | ||
1505 | * reset is required according to the data sheets of supported chips. | ||
1506 | */ | ||
1507 | regmap_write(data->regmap, BMC150_ACCEL_REG_RESET, | ||
1508 | BMC150_ACCEL_RESET_VAL); | ||
1509 | usleep_range(1800, 2500); | ||
1510 | |||
1500 | ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val); | 1511 | ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val); |
1501 | if (ret < 0) { | 1512 | if (ret < 0) { |
1502 | dev_err(dev, "Error: Reading chip id\n"); | 1513 | dev_err(dev, "Error: Reading chip id\n"); |
diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c index 3a9f106787d2..9d72d4bcf5e9 100644 --- a/drivers/iio/accel/kxsd9.c +++ b/drivers/iio/accel/kxsd9.c | |||
@@ -160,11 +160,13 @@ static int kxsd9_read_raw(struct iio_dev *indio_dev, | |||
160 | if (ret < 0) | 160 | if (ret < 0) |
161 | goto error_ret; | 161 | goto error_ret; |
162 | *val = ret; | 162 | *val = ret; |
163 | ret = IIO_VAL_INT; | ||
163 | break; | 164 | break; |
164 | case IIO_CHAN_INFO_SCALE: | 165 | case IIO_CHAN_INFO_SCALE: |
165 | ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C)); | 166 | ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C)); |
166 | if (ret < 0) | 167 | if (ret < 0) |
167 | goto error_ret; | 168 | goto error_ret; |
169 | *val = 0; | ||
168 | *val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK]; | 170 | *val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK]; |
169 | ret = IIO_VAL_INT_PLUS_MICRO; | 171 | ret = IIO_VAL_INT_PLUS_MICRO; |
170 | break; | 172 | break; |
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 1de31bdd4ce4..767577298ee3 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig | |||
@@ -389,6 +389,7 @@ config QCOM_SPMI_VADC | |||
389 | config ROCKCHIP_SARADC | 389 | config ROCKCHIP_SARADC |
390 | tristate "Rockchip SARADC driver" | 390 | tristate "Rockchip SARADC driver" |
391 | depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST) | 391 | depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST) |
392 | depends on RESET_CONTROLLER | ||
392 | help | 393 | help |
393 | Say yes here to build support for the SARADC found in SoCs from | 394 | Say yes here to build support for the SARADC found in SoCs from |
394 | Rockchip. | 395 | Rockchip. |
diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c index b6163764489c..9704090b7908 100644 --- a/drivers/iio/adc/ad799x.c +++ b/drivers/iio/adc/ad799x.c | |||
@@ -527,6 +527,7 @@ static struct attribute_group ad799x_event_attrs_group = { | |||
527 | static const struct iio_info ad7991_info = { | 527 | static const struct iio_info ad7991_info = { |
528 | .read_raw = &ad799x_read_raw, | 528 | .read_raw = &ad799x_read_raw, |
529 | .driver_module = THIS_MODULE, | 529 | .driver_module = THIS_MODULE, |
530 | .update_scan_mode = ad799x_update_scan_mode, | ||
530 | }; | 531 | }; |
531 | 532 | ||
532 | static const struct iio_info ad7993_4_7_8_noirq_info = { | 533 | static const struct iio_info ad7993_4_7_8_noirq_info = { |
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 52430ba171f3..0438c68015e8 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c | |||
@@ -381,8 +381,8 @@ static irqreturn_t at91_adc_rl_interrupt(int irq, void *private) | |||
381 | st->ts_bufferedmeasure = false; | 381 | st->ts_bufferedmeasure = false; |
382 | input_report_key(st->ts_input, BTN_TOUCH, 0); | 382 | input_report_key(st->ts_input, BTN_TOUCH, 0); |
383 | input_sync(st->ts_input); | 383 | input_sync(st->ts_input); |
384 | } else if (status & AT91_ADC_EOC(3)) { | 384 | } else if (status & AT91_ADC_EOC(3) && st->ts_input) { |
385 | /* Conversion finished */ | 385 | /* Conversion finished and we've a touchscreen */ |
386 | if (st->ts_bufferedmeasure) { | 386 | if (st->ts_bufferedmeasure) { |
387 | /* | 387 | /* |
388 | * Last measurement is always discarded, since it can | 388 | * Last measurement is always discarded, since it can |
diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c index f9ad6c2d6821..85d701291654 100644 --- a/drivers/iio/adc/rockchip_saradc.c +++ b/drivers/iio/adc/rockchip_saradc.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/of_device.h> | 21 | #include <linux/of_device.h> |
22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
23 | #include <linux/completion.h> | 23 | #include <linux/completion.h> |
24 | #include <linux/delay.h> | ||
25 | #include <linux/reset.h> | ||
24 | #include <linux/regulator/consumer.h> | 26 | #include <linux/regulator/consumer.h> |
25 | #include <linux/iio/iio.h> | 27 | #include <linux/iio/iio.h> |
26 | 28 | ||
@@ -53,6 +55,7 @@ struct rockchip_saradc { | |||
53 | struct clk *clk; | 55 | struct clk *clk; |
54 | struct completion completion; | 56 | struct completion completion; |
55 | struct regulator *vref; | 57 | struct regulator *vref; |
58 | struct reset_control *reset; | ||
56 | const struct rockchip_saradc_data *data; | 59 | const struct rockchip_saradc_data *data; |
57 | u16 last_val; | 60 | u16 last_val; |
58 | }; | 61 | }; |
@@ -190,6 +193,16 @@ static const struct of_device_id rockchip_saradc_match[] = { | |||
190 | }; | 193 | }; |
191 | MODULE_DEVICE_TABLE(of, rockchip_saradc_match); | 194 | MODULE_DEVICE_TABLE(of, rockchip_saradc_match); |
192 | 195 | ||
196 | /** | ||
197 | * Reset SARADC Controller. | ||
198 | */ | ||
199 | static void rockchip_saradc_reset_controller(struct reset_control *reset) | ||
200 | { | ||
201 | reset_control_assert(reset); | ||
202 | usleep_range(10, 20); | ||
203 | reset_control_deassert(reset); | ||
204 | } | ||
205 | |||
193 | static int rockchip_saradc_probe(struct platform_device *pdev) | 206 | static int rockchip_saradc_probe(struct platform_device *pdev) |
194 | { | 207 | { |
195 | struct rockchip_saradc *info = NULL; | 208 | struct rockchip_saradc *info = NULL; |
@@ -218,6 +231,20 @@ static int rockchip_saradc_probe(struct platform_device *pdev) | |||
218 | if (IS_ERR(info->regs)) | 231 | if (IS_ERR(info->regs)) |
219 | return PTR_ERR(info->regs); | 232 | return PTR_ERR(info->regs); |
220 | 233 | ||
234 | /* | ||
235 | * The reset should be an optional property, as it should work | ||
236 | * with old devicetrees as well | ||
237 | */ | ||
238 | info->reset = devm_reset_control_get(&pdev->dev, "saradc-apb"); | ||
239 | if (IS_ERR(info->reset)) { | ||
240 | ret = PTR_ERR(info->reset); | ||
241 | if (ret != -ENOENT) | ||
242 | return ret; | ||
243 | |||
244 | dev_dbg(&pdev->dev, "no reset control found\n"); | ||
245 | info->reset = NULL; | ||
246 | } | ||
247 | |||
221 | init_completion(&info->completion); | 248 | init_completion(&info->completion); |
222 | 249 | ||
223 | irq = platform_get_irq(pdev, 0); | 250 | irq = platform_get_irq(pdev, 0); |
@@ -252,6 +279,9 @@ static int rockchip_saradc_probe(struct platform_device *pdev) | |||
252 | return PTR_ERR(info->vref); | 279 | return PTR_ERR(info->vref); |
253 | } | 280 | } |
254 | 281 | ||
282 | if (info->reset) | ||
283 | rockchip_saradc_reset_controller(info->reset); | ||
284 | |||
255 | /* | 285 | /* |
256 | * Use a default value for the converter clock. | 286 | * Use a default value for the converter clock. |
257 | * This may become user-configurable in the future. | 287 | * This may become user-configurable in the future. |
diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index 1ef398770a1f..066abaf80201 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c | |||
@@ -489,7 +489,8 @@ static struct iio_info ads1115_info = { | |||
489 | #ifdef CONFIG_OF | 489 | #ifdef CONFIG_OF |
490 | static int ads1015_get_channels_config_of(struct i2c_client *client) | 490 | static int ads1015_get_channels_config_of(struct i2c_client *client) |
491 | { | 491 | { |
492 | struct ads1015_data *data = i2c_get_clientdata(client); | 492 | struct iio_dev *indio_dev = i2c_get_clientdata(client); |
493 | struct ads1015_data *data = iio_priv(indio_dev); | ||
493 | struct device_node *node; | 494 | struct device_node *node; |
494 | 495 | ||
495 | if (!client->dev.of_node || | 496 | if (!client->dev.of_node || |
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index 8a368756881b..c3cfacca2541 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | struct tiadc_device { | 33 | struct tiadc_device { |
34 | struct ti_tscadc_dev *mfd_tscadc; | 34 | struct ti_tscadc_dev *mfd_tscadc; |
35 | struct mutex fifo1_lock; /* to protect fifo access */ | ||
35 | int channels; | 36 | int channels; |
36 | u8 channel_line[8]; | 37 | u8 channel_line[8]; |
37 | u8 channel_step[8]; | 38 | u8 channel_step[8]; |
@@ -359,6 +360,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, | |||
359 | int *val, int *val2, long mask) | 360 | int *val, int *val2, long mask) |
360 | { | 361 | { |
361 | struct tiadc_device *adc_dev = iio_priv(indio_dev); | 362 | struct tiadc_device *adc_dev = iio_priv(indio_dev); |
363 | int ret = IIO_VAL_INT; | ||
362 | int i, map_val; | 364 | int i, map_val; |
363 | unsigned int fifo1count, read, stepid; | 365 | unsigned int fifo1count, read, stepid; |
364 | bool found = false; | 366 | bool found = false; |
@@ -372,13 +374,14 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, | |||
372 | if (!step_en) | 374 | if (!step_en) |
373 | return -EINVAL; | 375 | return -EINVAL; |
374 | 376 | ||
377 | mutex_lock(&adc_dev->fifo1_lock); | ||
375 | fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); | 378 | fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); |
376 | while (fifo1count--) | 379 | while (fifo1count--) |
377 | tiadc_readl(adc_dev, REG_FIFO1); | 380 | tiadc_readl(adc_dev, REG_FIFO1); |
378 | 381 | ||
379 | am335x_tsc_se_set_once(adc_dev->mfd_tscadc, step_en); | 382 | am335x_tsc_se_set_once(adc_dev->mfd_tscadc, step_en); |
380 | 383 | ||
381 | timeout = jiffies + usecs_to_jiffies | 384 | timeout = jiffies + msecs_to_jiffies |
382 | (IDLE_TIMEOUT * adc_dev->channels); | 385 | (IDLE_TIMEOUT * adc_dev->channels); |
383 | /* Wait for Fifo threshold interrupt */ | 386 | /* Wait for Fifo threshold interrupt */ |
384 | while (1) { | 387 | while (1) { |
@@ -388,7 +391,8 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, | |||
388 | 391 | ||
389 | if (time_after(jiffies, timeout)) { | 392 | if (time_after(jiffies, timeout)) { |
390 | am335x_tsc_se_adc_done(adc_dev->mfd_tscadc); | 393 | am335x_tsc_se_adc_done(adc_dev->mfd_tscadc); |
391 | return -EAGAIN; | 394 | ret = -EAGAIN; |
395 | goto err_unlock; | ||
392 | } | 396 | } |
393 | } | 397 | } |
394 | map_val = adc_dev->channel_step[chan->scan_index]; | 398 | map_val = adc_dev->channel_step[chan->scan_index]; |
@@ -414,8 +418,11 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, | |||
414 | am335x_tsc_se_adc_done(adc_dev->mfd_tscadc); | 418 | am335x_tsc_se_adc_done(adc_dev->mfd_tscadc); |
415 | 419 | ||
416 | if (found == false) | 420 | if (found == false) |
417 | return -EBUSY; | 421 | ret = -EBUSY; |
418 | return IIO_VAL_INT; | 422 | |
423 | err_unlock: | ||
424 | mutex_unlock(&adc_dev->fifo1_lock); | ||
425 | return ret; | ||
419 | } | 426 | } |
420 | 427 | ||
421 | static const struct iio_info tiadc_info = { | 428 | static const struct iio_info tiadc_info = { |
@@ -483,6 +490,7 @@ static int tiadc_probe(struct platform_device *pdev) | |||
483 | 490 | ||
484 | tiadc_step_config(indio_dev); | 491 | tiadc_step_config(indio_dev); |
485 | tiadc_writel(adc_dev, REG_FIFO1THR, FIFO1_THRESHOLD); | 492 | tiadc_writel(adc_dev, REG_FIFO1THR, FIFO1_THRESHOLD); |
493 | mutex_init(&adc_dev->fifo1_lock); | ||
486 | 494 | ||
487 | err = tiadc_channel_init(indio_dev, adc_dev->channels); | 495 | err = tiadc_channel_init(indio_dev, adc_dev->channels); |
488 | if (err < 0) | 496 | if (err < 0) |
diff --git a/drivers/iio/chemical/atlas-ph-sensor.c b/drivers/iio/chemical/atlas-ph-sensor.c index ae038a59d256..407f141a1eee 100644 --- a/drivers/iio/chemical/atlas-ph-sensor.c +++ b/drivers/iio/chemical/atlas-ph-sensor.c | |||
@@ -434,7 +434,7 @@ static int atlas_read_raw(struct iio_dev *indio_dev, | |||
434 | break; | 434 | break; |
435 | case IIO_ELECTRICALCONDUCTIVITY: | 435 | case IIO_ELECTRICALCONDUCTIVITY: |
436 | *val = 1; /* 0.00001 */ | 436 | *val = 1; /* 0.00001 */ |
437 | *val = 100000; | 437 | *val2 = 100000; |
438 | break; | 438 | break; |
439 | case IIO_CONCENTRATION: | 439 | case IIO_CONCENTRATION: |
440 | *val = 0; /* 0.000000001 */ | 440 | *val = 0; /* 0.000000001 */ |
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c index e81f434760f4..dc33c1dd5191 100644 --- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c +++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c | |||
@@ -56,8 +56,8 @@ static struct { | |||
56 | {HID_USAGE_SENSOR_ALS, 0, 1, 0}, | 56 | {HID_USAGE_SENSOR_ALS, 0, 1, 0}, |
57 | {HID_USAGE_SENSOR_ALS, HID_USAGE_SENSOR_UNITS_LUX, 1, 0}, | 57 | {HID_USAGE_SENSOR_ALS, HID_USAGE_SENSOR_UNITS_LUX, 1, 0}, |
58 | 58 | ||
59 | {HID_USAGE_SENSOR_PRESSURE, 0, 100000, 0}, | 59 | {HID_USAGE_SENSOR_PRESSURE, 0, 100, 0}, |
60 | {HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, 1, 0}, | 60 | {HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, 0, 1000}, |
61 | }; | 61 | }; |
62 | 62 | ||
63 | static int pow_10(unsigned power) | 63 | static int pow_10(unsigned power) |
diff --git a/drivers/iio/dac/stx104.c b/drivers/iio/dac/stx104.c index 792a97164cb2..bebbd00304ce 100644 --- a/drivers/iio/dac/stx104.c +++ b/drivers/iio/dac/stx104.c | |||
@@ -65,6 +65,16 @@ struct stx104_gpio { | |||
65 | unsigned int out_state; | 65 | unsigned int out_state; |
66 | }; | 66 | }; |
67 | 67 | ||
68 | /** | ||
69 | * struct stx104_dev - STX104 device private data structure | ||
70 | * @indio_dev: IIO device | ||
71 | * @chip: instance of the gpio_chip | ||
72 | */ | ||
73 | struct stx104_dev { | ||
74 | struct iio_dev *indio_dev; | ||
75 | struct gpio_chip *chip; | ||
76 | }; | ||
77 | |||
68 | static int stx104_read_raw(struct iio_dev *indio_dev, | 78 | static int stx104_read_raw(struct iio_dev *indio_dev, |
69 | struct iio_chan_spec const *chan, int *val, int *val2, long mask) | 79 | struct iio_chan_spec const *chan, int *val, int *val2, long mask) |
70 | { | 80 | { |
@@ -107,6 +117,7 @@ static const struct iio_chan_spec stx104_channels[STX104_NUM_CHAN] = { | |||
107 | static int stx104_gpio_get_direction(struct gpio_chip *chip, | 117 | static int stx104_gpio_get_direction(struct gpio_chip *chip, |
108 | unsigned int offset) | 118 | unsigned int offset) |
109 | { | 119 | { |
120 | /* GPIO 0-3 are input only, while the rest are output only */ | ||
110 | if (offset < 4) | 121 | if (offset < 4) |
111 | return 1; | 122 | return 1; |
112 | 123 | ||
@@ -169,6 +180,7 @@ static int stx104_probe(struct device *dev, unsigned int id) | |||
169 | struct iio_dev *indio_dev; | 180 | struct iio_dev *indio_dev; |
170 | struct stx104_iio *priv; | 181 | struct stx104_iio *priv; |
171 | struct stx104_gpio *stx104gpio; | 182 | struct stx104_gpio *stx104gpio; |
183 | struct stx104_dev *stx104dev; | ||
172 | int err; | 184 | int err; |
173 | 185 | ||
174 | indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); | 186 | indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); |
@@ -179,6 +191,10 @@ static int stx104_probe(struct device *dev, unsigned int id) | |||
179 | if (!stx104gpio) | 191 | if (!stx104gpio) |
180 | return -ENOMEM; | 192 | return -ENOMEM; |
181 | 193 | ||
194 | stx104dev = devm_kzalloc(dev, sizeof(*stx104dev), GFP_KERNEL); | ||
195 | if (!stx104dev) | ||
196 | return -ENOMEM; | ||
197 | |||
182 | if (!devm_request_region(dev, base[id], STX104_EXTENT, | 198 | if (!devm_request_region(dev, base[id], STX104_EXTENT, |
183 | dev_name(dev))) { | 199 | dev_name(dev))) { |
184 | dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", | 200 | dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", |
@@ -199,12 +215,6 @@ static int stx104_probe(struct device *dev, unsigned int id) | |||
199 | outw(0, base[id] + 4); | 215 | outw(0, base[id] + 4); |
200 | outw(0, base[id] + 6); | 216 | outw(0, base[id] + 6); |
201 | 217 | ||
202 | err = devm_iio_device_register(dev, indio_dev); | ||
203 | if (err) { | ||
204 | dev_err(dev, "IIO device registering failed (%d)\n", err); | ||
205 | return err; | ||
206 | } | ||
207 | |||
208 | stx104gpio->chip.label = dev_name(dev); | 218 | stx104gpio->chip.label = dev_name(dev); |
209 | stx104gpio->chip.parent = dev; | 219 | stx104gpio->chip.parent = dev; |
210 | stx104gpio->chip.owner = THIS_MODULE; | 220 | stx104gpio->chip.owner = THIS_MODULE; |
@@ -220,7 +230,9 @@ static int stx104_probe(struct device *dev, unsigned int id) | |||
220 | 230 | ||
221 | spin_lock_init(&stx104gpio->lock); | 231 | spin_lock_init(&stx104gpio->lock); |
222 | 232 | ||
223 | dev_set_drvdata(dev, stx104gpio); | 233 | stx104dev->indio_dev = indio_dev; |
234 | stx104dev->chip = &stx104gpio->chip; | ||
235 | dev_set_drvdata(dev, stx104dev); | ||
224 | 236 | ||
225 | err = gpiochip_add_data(&stx104gpio->chip, stx104gpio); | 237 | err = gpiochip_add_data(&stx104gpio->chip, stx104gpio); |
226 | if (err) { | 238 | if (err) { |
@@ -228,14 +240,22 @@ static int stx104_probe(struct device *dev, unsigned int id) | |||
228 | return err; | 240 | return err; |
229 | } | 241 | } |
230 | 242 | ||
243 | err = iio_device_register(indio_dev); | ||
244 | if (err) { | ||
245 | dev_err(dev, "IIO device registering failed (%d)\n", err); | ||
246 | gpiochip_remove(&stx104gpio->chip); | ||
247 | return err; | ||
248 | } | ||
249 | |||
231 | return 0; | 250 | return 0; |
232 | } | 251 | } |
233 | 252 | ||
234 | static int stx104_remove(struct device *dev, unsigned int id) | 253 | static int stx104_remove(struct device *dev, unsigned int id) |
235 | { | 254 | { |
236 | struct stx104_gpio *const stx104gpio = dev_get_drvdata(dev); | 255 | struct stx104_dev *const stx104dev = dev_get_drvdata(dev); |
237 | 256 | ||
238 | gpiochip_remove(&stx104gpio->chip); | 257 | iio_device_unregister(stx104dev->indio_dev); |
258 | gpiochip_remove(stx104dev->chip); | ||
239 | 259 | ||
240 | return 0; | 260 | return 0; |
241 | } | 261 | } |
diff --git a/drivers/iio/humidity/Kconfig b/drivers/iio/humidity/Kconfig index 738a86d9e4a9..d04124345992 100644 --- a/drivers/iio/humidity/Kconfig +++ b/drivers/iio/humidity/Kconfig | |||
@@ -6,6 +6,8 @@ menu "Humidity sensors" | |||
6 | config AM2315 | 6 | config AM2315 |
7 | tristate "Aosong AM2315 relative humidity and temperature sensor" | 7 | tristate "Aosong AM2315 relative humidity and temperature sensor" |
8 | depends on I2C | 8 | depends on I2C |
9 | select IIO_BUFFER | ||
10 | select IIO_TRIGGERED_BUFFER | ||
9 | help | 11 | help |
10 | If you say yes here you get support for the Aosong AM2315 | 12 | If you say yes here you get support for the Aosong AM2315 |
11 | relative humidity and ambient temperature sensor. | 13 | relative humidity and ambient temperature sensor. |
diff --git a/drivers/iio/humidity/am2315.c b/drivers/iio/humidity/am2315.c index 3e200f69e886..ff96b6d0fdae 100644 --- a/drivers/iio/humidity/am2315.c +++ b/drivers/iio/humidity/am2315.c | |||
@@ -244,7 +244,7 @@ static int am2315_probe(struct i2c_client *client, | |||
244 | indio_dev->channels = am2315_channels; | 244 | indio_dev->channels = am2315_channels; |
245 | indio_dev->num_channels = ARRAY_SIZE(am2315_channels); | 245 | indio_dev->num_channels = ARRAY_SIZE(am2315_channels); |
246 | 246 | ||
247 | ret = iio_triggered_buffer_setup(indio_dev, NULL, | 247 | ret = iio_triggered_buffer_setup(indio_dev, iio_pollfunc_store_time, |
248 | am2315_trigger_handler, NULL); | 248 | am2315_trigger_handler, NULL); |
249 | if (ret < 0) { | 249 | if (ret < 0) { |
250 | dev_err(&client->dev, "iio triggered buffer setup failed\n"); | 250 | dev_err(&client->dev, "iio triggered buffer setup failed\n"); |
diff --git a/drivers/iio/humidity/hdc100x.c b/drivers/iio/humidity/hdc100x.c index a03832a5fc95..e0c9c70c2a4a 100644 --- a/drivers/iio/humidity/hdc100x.c +++ b/drivers/iio/humidity/hdc100x.c | |||
@@ -142,7 +142,7 @@ static int hdc100x_get_measurement(struct hdc100x_data *data, | |||
142 | struct i2c_client *client = data->client; | 142 | struct i2c_client *client = data->client; |
143 | int delay = data->adc_int_us[chan->address]; | 143 | int delay = data->adc_int_us[chan->address]; |
144 | int ret; | 144 | int ret; |
145 | int val; | 145 | __be16 val; |
146 | 146 | ||
147 | /* start measurement */ | 147 | /* start measurement */ |
148 | ret = i2c_smbus_write_byte(client, chan->address); | 148 | ret = i2c_smbus_write_byte(client, chan->address); |
@@ -154,26 +154,13 @@ static int hdc100x_get_measurement(struct hdc100x_data *data, | |||
154 | /* wait for integration time to pass */ | 154 | /* wait for integration time to pass */ |
155 | usleep_range(delay, delay + 1000); | 155 | usleep_range(delay, delay + 1000); |
156 | 156 | ||
157 | /* | 157 | /* read measurement */ |
158 | * i2c_smbus_read_word_data cannot() be used here due to the command | 158 | ret = i2c_master_recv(data->client, (char *)&val, sizeof(val)); |
159 | * value not being understood and causes NAKs preventing any reading | ||
160 | * from being accessed. | ||
161 | */ | ||
162 | ret = i2c_smbus_read_byte(client); | ||
163 | if (ret < 0) { | 159 | if (ret < 0) { |
164 | dev_err(&client->dev, "cannot read high byte measurement"); | 160 | dev_err(&client->dev, "cannot read sensor data\n"); |
165 | return ret; | 161 | return ret; |
166 | } | 162 | } |
167 | val = ret << 8; | 163 | return be16_to_cpu(val); |
168 | |||
169 | ret = i2c_smbus_read_byte(client); | ||
170 | if (ret < 0) { | ||
171 | dev_err(&client->dev, "cannot read low byte measurement"); | ||
172 | return ret; | ||
173 | } | ||
174 | val |= ret; | ||
175 | |||
176 | return val; | ||
177 | } | 164 | } |
178 | 165 | ||
179 | static int hdc100x_get_heater_status(struct hdc100x_data *data) | 166 | static int hdc100x_get_heater_status(struct hdc100x_data *data) |
@@ -272,8 +259,8 @@ static int hdc100x_probe(struct i2c_client *client, | |||
272 | struct iio_dev *indio_dev; | 259 | struct iio_dev *indio_dev; |
273 | struct hdc100x_data *data; | 260 | struct hdc100x_data *data; |
274 | 261 | ||
275 | if (!i2c_check_functionality(client->adapter, | 262 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA | |
276 | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BYTE)) | 263 | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C)) |
277 | return -EOPNOTSUPP; | 264 | return -EOPNOTSUPP; |
278 | 265 | ||
279 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); | 266 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); |
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 90462fcf5436..158aaf44dd95 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c | |||
@@ -107,9 +107,10 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, | |||
107 | { | 107 | { |
108 | struct iio_dev *indio_dev = filp->private_data; | 108 | struct iio_dev *indio_dev = filp->private_data; |
109 | struct iio_buffer *rb = indio_dev->buffer; | 109 | struct iio_buffer *rb = indio_dev->buffer; |
110 | DEFINE_WAIT_FUNC(wait, woken_wake_function); | ||
110 | size_t datum_size; | 111 | size_t datum_size; |
111 | size_t to_wait; | 112 | size_t to_wait; |
112 | int ret; | 113 | int ret = 0; |
113 | 114 | ||
114 | if (!indio_dev->info) | 115 | if (!indio_dev->info) |
115 | return -ENODEV; | 116 | return -ENODEV; |
@@ -131,19 +132,29 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, | |||
131 | else | 132 | else |
132 | to_wait = min_t(size_t, n / datum_size, rb->watermark); | 133 | to_wait = min_t(size_t, n / datum_size, rb->watermark); |
133 | 134 | ||
135 | add_wait_queue(&rb->pollq, &wait); | ||
134 | do { | 136 | do { |
135 | ret = wait_event_interruptible(rb->pollq, | 137 | if (!indio_dev->info) { |
136 | iio_buffer_ready(indio_dev, rb, to_wait, n / datum_size)); | 138 | ret = -ENODEV; |
137 | if (ret) | 139 | break; |
138 | return ret; | 140 | } |
139 | 141 | ||
140 | if (!indio_dev->info) | 142 | if (!iio_buffer_ready(indio_dev, rb, to_wait, n / datum_size)) { |
141 | return -ENODEV; | 143 | if (signal_pending(current)) { |
144 | ret = -ERESTARTSYS; | ||
145 | break; | ||
146 | } | ||
147 | |||
148 | wait_woken(&wait, TASK_INTERRUPTIBLE, | ||
149 | MAX_SCHEDULE_TIMEOUT); | ||
150 | continue; | ||
151 | } | ||
142 | 152 | ||
143 | ret = rb->access->read_first_n(rb, n, buf); | 153 | ret = rb->access->read_first_n(rb, n, buf); |
144 | if (ret == 0 && (filp->f_flags & O_NONBLOCK)) | 154 | if (ret == 0 && (filp->f_flags & O_NONBLOCK)) |
145 | ret = -EAGAIN; | 155 | ret = -EAGAIN; |
146 | } while (ret == 0); | 156 | } while (ret == 0); |
157 | remove_wait_queue(&rb->pollq, &wait); | ||
147 | 158 | ||
148 | return ret; | 159 | return ret; |
149 | } | 160 | } |
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index f914d5d140e4..d2b889918c3e 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c | |||
@@ -613,9 +613,8 @@ ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals) | |||
613 | return sprintf(buf, "%d.%09u\n", vals[0], vals[1]); | 613 | return sprintf(buf, "%d.%09u\n", vals[0], vals[1]); |
614 | case IIO_VAL_FRACTIONAL: | 614 | case IIO_VAL_FRACTIONAL: |
615 | tmp = div_s64((s64)vals[0] * 1000000000LL, vals[1]); | 615 | tmp = div_s64((s64)vals[0] * 1000000000LL, vals[1]); |
616 | vals[1] = do_div(tmp, 1000000000LL); | 616 | vals[0] = (int)div_s64_rem(tmp, 1000000000, &vals[1]); |
617 | vals[0] = tmp; | 617 | return sprintf(buf, "%d.%09u\n", vals[0], abs(vals[1])); |
618 | return sprintf(buf, "%d.%09u\n", vals[0], vals[1]); | ||
619 | case IIO_VAL_FRACTIONAL_LOG2: | 618 | case IIO_VAL_FRACTIONAL_LOG2: |
620 | tmp = (s64)vals[0] * 1000000000LL >> vals[1]; | 619 | tmp = (s64)vals[0] * 1000000000LL >> vals[1]; |
621 | vals[1] = do_div(tmp, 1000000000LL); | 620 | vals[1] = do_div(tmp, 1000000000LL); |
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index 7c566f516572..3574945183fe 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig | |||
@@ -76,7 +76,6 @@ config BH1750 | |||
76 | config BH1780 | 76 | config BH1780 |
77 | tristate "ROHM BH1780 ambient light sensor" | 77 | tristate "ROHM BH1780 ambient light sensor" |
78 | depends on I2C | 78 | depends on I2C |
79 | depends on !SENSORS_BH1780 | ||
80 | help | 79 | help |
81 | Say Y here to build support for the ROHM BH1780GLI ambient | 80 | Say Y here to build support for the ROHM BH1780GLI ambient |
82 | light sensor. | 81 | light sensor. |
@@ -238,6 +237,8 @@ config MAX44000 | |||
238 | tristate "MAX44000 Ambient and Infrared Proximity Sensor" | 237 | tristate "MAX44000 Ambient and Infrared Proximity Sensor" |
239 | depends on I2C | 238 | depends on I2C |
240 | select REGMAP_I2C | 239 | select REGMAP_I2C |
240 | select IIO_BUFFER | ||
241 | select IIO_TRIGGERED_BUFFER | ||
241 | help | 242 | help |
242 | Say Y here if you want to build support for Maxim Integrated's | 243 | Say Y here if you want to build support for Maxim Integrated's |
243 | MAX44000 ambient and infrared proximity sensor device. | 244 | MAX44000 ambient and infrared proximity sensor device. |
diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c index 6943688e66df..e5a533cbd53f 100644 --- a/drivers/iio/pressure/bmp280-core.c +++ b/drivers/iio/pressure/bmp280-core.c | |||
@@ -970,7 +970,7 @@ int bmp280_common_probe(struct device *dev, | |||
970 | data->vdda = devm_regulator_get(dev, "vdda"); | 970 | data->vdda = devm_regulator_get(dev, "vdda"); |
971 | if (IS_ERR(data->vdda)) { | 971 | if (IS_ERR(data->vdda)) { |
972 | dev_err(dev, "failed to get VDDA regulator\n"); | 972 | dev_err(dev, "failed to get VDDA regulator\n"); |
973 | ret = PTR_ERR(data->vddd); | 973 | ret = PTR_ERR(data->vdda); |
974 | goto out_disable_vddd; | 974 | goto out_disable_vddd; |
975 | } | 975 | } |
976 | ret = regulator_enable(data->vdda); | 976 | ret = regulator_enable(data->vdda); |
@@ -1079,7 +1079,8 @@ EXPORT_SYMBOL(bmp280_common_remove); | |||
1079 | #ifdef CONFIG_PM | 1079 | #ifdef CONFIG_PM |
1080 | static int bmp280_runtime_suspend(struct device *dev) | 1080 | static int bmp280_runtime_suspend(struct device *dev) |
1081 | { | 1081 | { |
1082 | struct bmp280_data *data = dev_get_drvdata(dev); | 1082 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1083 | struct bmp280_data *data = iio_priv(indio_dev); | ||
1083 | int ret; | 1084 | int ret; |
1084 | 1085 | ||
1085 | ret = regulator_disable(data->vdda); | 1086 | ret = regulator_disable(data->vdda); |
@@ -1090,7 +1091,8 @@ static int bmp280_runtime_suspend(struct device *dev) | |||
1090 | 1091 | ||
1091 | static int bmp280_runtime_resume(struct device *dev) | 1092 | static int bmp280_runtime_resume(struct device *dev) |
1092 | { | 1093 | { |
1093 | struct bmp280_data *data = dev_get_drvdata(dev); | 1094 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1095 | struct bmp280_data *data = iio_priv(indio_dev); | ||
1094 | int ret; | 1096 | int ret; |
1095 | 1097 | ||
1096 | ret = regulator_enable(data->vddd); | 1098 | ret = regulator_enable(data->vddd); |
diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c index 2e3a70e1b245..5656deb17261 100644 --- a/drivers/iio/proximity/as3935.c +++ b/drivers/iio/proximity/as3935.c | |||
@@ -397,7 +397,7 @@ static int as3935_probe(struct spi_device *spi) | |||
397 | return ret; | 397 | return ret; |
398 | } | 398 | } |
399 | 399 | ||
400 | ret = iio_triggered_buffer_setup(indio_dev, NULL, | 400 | ret = iio_triggered_buffer_setup(indio_dev, iio_pollfunc_store_time, |
401 | &as3935_trigger_handler, NULL); | 401 | &as3935_trigger_handler, NULL); |
402 | 402 | ||
403 | if (ret) { | 403 | if (ret) { |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index e6dfa1bd3def..5f65a78b27c9 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -2462,18 +2462,24 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) | |||
2462 | 2462 | ||
2463 | if (addr->dev_addr.bound_dev_if) { | 2463 | if (addr->dev_addr.bound_dev_if) { |
2464 | ndev = dev_get_by_index(&init_net, addr->dev_addr.bound_dev_if); | 2464 | ndev = dev_get_by_index(&init_net, addr->dev_addr.bound_dev_if); |
2465 | if (!ndev) | 2465 | if (!ndev) { |
2466 | return -ENODEV; | 2466 | ret = -ENODEV; |
2467 | goto err2; | ||
2468 | } | ||
2467 | 2469 | ||
2468 | if (ndev->flags & IFF_LOOPBACK) { | 2470 | if (ndev->flags & IFF_LOOPBACK) { |
2469 | dev_put(ndev); | 2471 | dev_put(ndev); |
2470 | if (!id_priv->id.device->get_netdev) | 2472 | if (!id_priv->id.device->get_netdev) { |
2471 | return -EOPNOTSUPP; | 2473 | ret = -EOPNOTSUPP; |
2474 | goto err2; | ||
2475 | } | ||
2472 | 2476 | ||
2473 | ndev = id_priv->id.device->get_netdev(id_priv->id.device, | 2477 | ndev = id_priv->id.device->get_netdev(id_priv->id.device, |
2474 | id_priv->id.port_num); | 2478 | id_priv->id.port_num); |
2475 | if (!ndev) | 2479 | if (!ndev) { |
2476 | return -ENODEV; | 2480 | ret = -ENODEV; |
2481 | goto err2; | ||
2482 | } | ||
2477 | } | 2483 | } |
2478 | 2484 | ||
2479 | route->path_rec->net = &init_net; | 2485 | route->path_rec->net = &init_net; |
diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c index 3a3c5d73bbfc..51c79b2fb0b8 100644 --- a/drivers/infiniband/core/multicast.c +++ b/drivers/infiniband/core/multicast.c | |||
@@ -106,7 +106,6 @@ struct mcast_group { | |||
106 | atomic_t refcount; | 106 | atomic_t refcount; |
107 | enum mcast_group_state state; | 107 | enum mcast_group_state state; |
108 | struct ib_sa_query *query; | 108 | struct ib_sa_query *query; |
109 | int query_id; | ||
110 | u16 pkey_index; | 109 | u16 pkey_index; |
111 | u8 leave_state; | 110 | u8 leave_state; |
112 | int retries; | 111 | int retries; |
@@ -340,11 +339,7 @@ static int send_join(struct mcast_group *group, struct mcast_member *member) | |||
340 | member->multicast.comp_mask, | 339 | member->multicast.comp_mask, |
341 | 3000, GFP_KERNEL, join_handler, group, | 340 | 3000, GFP_KERNEL, join_handler, group, |
342 | &group->query); | 341 | &group->query); |
343 | if (ret >= 0) { | 342 | return (ret > 0) ? 0 : ret; |
344 | group->query_id = ret; | ||
345 | ret = 0; | ||
346 | } | ||
347 | return ret; | ||
348 | } | 343 | } |
349 | 344 | ||
350 | static int send_leave(struct mcast_group *group, u8 leave_state) | 345 | static int send_leave(struct mcast_group *group, u8 leave_state) |
@@ -364,11 +359,7 @@ static int send_leave(struct mcast_group *group, u8 leave_state) | |||
364 | IB_SA_MCMEMBER_REC_JOIN_STATE, | 359 | IB_SA_MCMEMBER_REC_JOIN_STATE, |
365 | 3000, GFP_KERNEL, leave_handler, | 360 | 3000, GFP_KERNEL, leave_handler, |
366 | group, &group->query); | 361 | group, &group->query); |
367 | if (ret >= 0) { | 362 | return (ret > 0) ? 0 : ret; |
368 | group->query_id = ret; | ||
369 | ret = 0; | ||
370 | } | ||
371 | return ret; | ||
372 | } | 363 | } |
373 | 364 | ||
374 | static void join_group(struct mcast_group *group, struct mcast_member *member, | 365 | static void join_group(struct mcast_group *group, struct mcast_member *member, |
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 3aca7f6171b4..80f988984f44 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c | |||
@@ -333,6 +333,8 @@ static void remove_ep_tid(struct c4iw_ep *ep) | |||
333 | 333 | ||
334 | spin_lock_irqsave(&ep->com.dev->lock, flags); | 334 | spin_lock_irqsave(&ep->com.dev->lock, flags); |
335 | _remove_handle(ep->com.dev, &ep->com.dev->hwtid_idr, ep->hwtid, 0); | 335 | _remove_handle(ep->com.dev, &ep->com.dev->hwtid_idr, ep->hwtid, 0); |
336 | if (idr_is_empty(&ep->com.dev->hwtid_idr)) | ||
337 | wake_up(&ep->com.dev->wait); | ||
336 | spin_unlock_irqrestore(&ep->com.dev->lock, flags); | 338 | spin_unlock_irqrestore(&ep->com.dev->lock, flags); |
337 | } | 339 | } |
338 | 340 | ||
@@ -1827,8 +1829,12 @@ static int process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb) | |||
1827 | (ep->mpa_pkt + sizeof(*mpa)); | 1829 | (ep->mpa_pkt + sizeof(*mpa)); |
1828 | ep->ird = ntohs(mpa_v2_params->ird) & | 1830 | ep->ird = ntohs(mpa_v2_params->ird) & |
1829 | MPA_V2_IRD_ORD_MASK; | 1831 | MPA_V2_IRD_ORD_MASK; |
1832 | ep->ird = min_t(u32, ep->ird, | ||
1833 | cur_max_read_depth(ep->com.dev)); | ||
1830 | ep->ord = ntohs(mpa_v2_params->ord) & | 1834 | ep->ord = ntohs(mpa_v2_params->ord) & |
1831 | MPA_V2_IRD_ORD_MASK; | 1835 | MPA_V2_IRD_ORD_MASK; |
1836 | ep->ord = min_t(u32, ep->ord, | ||
1837 | cur_max_read_depth(ep->com.dev)); | ||
1832 | PDBG("%s initiator ird %u ord %u\n", __func__, ep->ird, | 1838 | PDBG("%s initiator ird %u ord %u\n", __func__, ep->ird, |
1833 | ep->ord); | 1839 | ep->ord); |
1834 | if (ntohs(mpa_v2_params->ird) & MPA_V2_PEER2PEER_MODEL) | 1840 | if (ntohs(mpa_v2_params->ird) & MPA_V2_PEER2PEER_MODEL) |
@@ -2113,8 +2119,10 @@ static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip, | |||
2113 | } | 2119 | } |
2114 | ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, | 2120 | ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, |
2115 | n, pdev, rt_tos2priority(tos)); | 2121 | n, pdev, rt_tos2priority(tos)); |
2116 | if (!ep->l2t) | 2122 | if (!ep->l2t) { |
2123 | dev_put(pdev); | ||
2117 | goto out; | 2124 | goto out; |
2125 | } | ||
2118 | ep->mtu = pdev->mtu; | 2126 | ep->mtu = pdev->mtu; |
2119 | ep->tx_chan = cxgb4_port_chan(pdev); | 2127 | ep->tx_chan = cxgb4_port_chan(pdev); |
2120 | ep->smac_idx = cxgb4_tp_smt_idx(adapter_type, | 2128 | ep->smac_idx = cxgb4_tp_smt_idx(adapter_type, |
@@ -3136,7 +3144,7 @@ int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
3136 | if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn) { | 3144 | if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn) { |
3137 | if (conn_param->ord > ep->ird) { | 3145 | if (conn_param->ord > ep->ird) { |
3138 | if (RELAXED_IRD_NEGOTIATION) { | 3146 | if (RELAXED_IRD_NEGOTIATION) { |
3139 | ep->ord = ep->ird; | 3147 | conn_param->ord = ep->ird; |
3140 | } else { | 3148 | } else { |
3141 | ep->ird = conn_param->ird; | 3149 | ep->ird = conn_param->ird; |
3142 | ep->ord = conn_param->ord; | 3150 | ep->ord = conn_param->ord; |
diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index 812ab7278b8e..ac926c942fee 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c | |||
@@ -1016,15 +1016,15 @@ int c4iw_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata) | |||
1016 | int c4iw_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags) | 1016 | int c4iw_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags) |
1017 | { | 1017 | { |
1018 | struct c4iw_cq *chp; | 1018 | struct c4iw_cq *chp; |
1019 | int ret; | 1019 | int ret = 0; |
1020 | unsigned long flag; | 1020 | unsigned long flag; |
1021 | 1021 | ||
1022 | chp = to_c4iw_cq(ibcq); | 1022 | chp = to_c4iw_cq(ibcq); |
1023 | spin_lock_irqsave(&chp->lock, flag); | 1023 | spin_lock_irqsave(&chp->lock, flag); |
1024 | ret = t4_arm_cq(&chp->cq, | 1024 | t4_arm_cq(&chp->cq, |
1025 | (flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED); | 1025 | (flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED); |
1026 | if (flags & IB_CQ_REPORT_MISSED_EVENTS) | ||
1027 | ret = t4_cq_notempty(&chp->cq); | ||
1026 | spin_unlock_irqrestore(&chp->lock, flag); | 1028 | spin_unlock_irqrestore(&chp->lock, flag); |
1027 | if (ret && !(flags & IB_CQ_REPORT_MISSED_EVENTS)) | ||
1028 | ret = 0; | ||
1029 | return ret; | 1029 | return ret; |
1030 | } | 1030 | } |
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index 071d7332ec06..3c4b2126e0d1 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c | |||
@@ -872,9 +872,13 @@ static void c4iw_rdev_close(struct c4iw_rdev *rdev) | |||
872 | static void c4iw_dealloc(struct uld_ctx *ctx) | 872 | static void c4iw_dealloc(struct uld_ctx *ctx) |
873 | { | 873 | { |
874 | c4iw_rdev_close(&ctx->dev->rdev); | 874 | c4iw_rdev_close(&ctx->dev->rdev); |
875 | WARN_ON_ONCE(!idr_is_empty(&ctx->dev->cqidr)); | ||
875 | idr_destroy(&ctx->dev->cqidr); | 876 | idr_destroy(&ctx->dev->cqidr); |
877 | WARN_ON_ONCE(!idr_is_empty(&ctx->dev->qpidr)); | ||
876 | idr_destroy(&ctx->dev->qpidr); | 878 | idr_destroy(&ctx->dev->qpidr); |
879 | WARN_ON_ONCE(!idr_is_empty(&ctx->dev->mmidr)); | ||
877 | idr_destroy(&ctx->dev->mmidr); | 880 | idr_destroy(&ctx->dev->mmidr); |
881 | wait_event(ctx->dev->wait, idr_is_empty(&ctx->dev->hwtid_idr)); | ||
878 | idr_destroy(&ctx->dev->hwtid_idr); | 882 | idr_destroy(&ctx->dev->hwtid_idr); |
879 | idr_destroy(&ctx->dev->stid_idr); | 883 | idr_destroy(&ctx->dev->stid_idr); |
880 | idr_destroy(&ctx->dev->atid_idr); | 884 | idr_destroy(&ctx->dev->atid_idr); |
@@ -992,6 +996,7 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) | |||
992 | mutex_init(&devp->rdev.stats.lock); | 996 | mutex_init(&devp->rdev.stats.lock); |
993 | mutex_init(&devp->db_mutex); | 997 | mutex_init(&devp->db_mutex); |
994 | INIT_LIST_HEAD(&devp->db_fc_list); | 998 | INIT_LIST_HEAD(&devp->db_fc_list); |
999 | init_waitqueue_head(&devp->wait); | ||
995 | devp->avail_ird = devp->rdev.lldi.max_ird_adapter; | 1000 | devp->avail_ird = devp->rdev.lldi.max_ird_adapter; |
996 | 1001 | ||
997 | if (c4iw_debugfs_root) { | 1002 | if (c4iw_debugfs_root) { |
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index aa47e0ae80bc..4b83b84f7ddf 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h | |||
@@ -263,6 +263,7 @@ struct c4iw_dev { | |||
263 | struct idr stid_idr; | 263 | struct idr stid_idr; |
264 | struct list_head db_fc_list; | 264 | struct list_head db_fc_list; |
265 | u32 avail_ird; | 265 | u32 avail_ird; |
266 | wait_queue_head_t wait; | ||
266 | }; | 267 | }; |
267 | 268 | ||
268 | static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev) | 269 | static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev) |
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index edb1172b6f54..690435229be7 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c | |||
@@ -683,7 +683,7 @@ static int build_inv_stag(union t4_wr *wqe, struct ib_send_wr *wr, | |||
683 | return 0; | 683 | return 0; |
684 | } | 684 | } |
685 | 685 | ||
686 | void _free_qp(struct kref *kref) | 686 | static void _free_qp(struct kref *kref) |
687 | { | 687 | { |
688 | struct c4iw_qp *qhp; | 688 | struct c4iw_qp *qhp; |
689 | 689 | ||
diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index 6126bbe36095..02173f4315fa 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h | |||
@@ -634,6 +634,11 @@ static inline int t4_valid_cqe(struct t4_cq *cq, struct t4_cqe *cqe) | |||
634 | return (CQE_GENBIT(cqe) == cq->gen); | 634 | return (CQE_GENBIT(cqe) == cq->gen); |
635 | } | 635 | } |
636 | 636 | ||
637 | static inline int t4_cq_notempty(struct t4_cq *cq) | ||
638 | { | ||
639 | return cq->sw_in_use || t4_valid_cqe(cq, &cq->queue[cq->cidx]); | ||
640 | } | ||
641 | |||
637 | static inline int t4_next_hw_cqe(struct t4_cq *cq, struct t4_cqe **cqe) | 642 | static inline int t4_next_hw_cqe(struct t4_cq *cq, struct t4_cqe **cqe) |
638 | { | 643 | { |
639 | int ret; | 644 | int ret; |
diff --git a/drivers/infiniband/hw/hfi1/affinity.c b/drivers/infiniband/hw/hfi1/affinity.c index 79575ee873f2..0566393e5aba 100644 --- a/drivers/infiniband/hw/hfi1/affinity.c +++ b/drivers/infiniband/hw/hfi1/affinity.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <linux/topology.h> | 47 | #include <linux/topology.h> |
48 | #include <linux/cpumask.h> | 48 | #include <linux/cpumask.h> |
49 | #include <linux/module.h> | 49 | #include <linux/module.h> |
50 | #include <linux/cpumask.h> | ||
51 | 50 | ||
52 | #include "hfi.h" | 51 | #include "hfi.h" |
53 | #include "affinity.h" | 52 | #include "affinity.h" |
@@ -682,7 +681,7 @@ int hfi1_set_sdma_affinity(struct hfi1_devdata *dd, const char *buf, | |||
682 | size_t count) | 681 | size_t count) |
683 | { | 682 | { |
684 | struct hfi1_affinity_node *entry; | 683 | struct hfi1_affinity_node *entry; |
685 | struct cpumask mask; | 684 | cpumask_var_t mask; |
686 | int ret, i; | 685 | int ret, i; |
687 | 686 | ||
688 | spin_lock(&node_affinity.lock); | 687 | spin_lock(&node_affinity.lock); |
@@ -692,19 +691,24 @@ int hfi1_set_sdma_affinity(struct hfi1_devdata *dd, const char *buf, | |||
692 | if (!entry) | 691 | if (!entry) |
693 | return -EINVAL; | 692 | return -EINVAL; |
694 | 693 | ||
695 | ret = cpulist_parse(buf, &mask); | 694 | ret = zalloc_cpumask_var(&mask, GFP_KERNEL); |
695 | if (!ret) | ||
696 | return -ENOMEM; | ||
697 | |||
698 | ret = cpulist_parse(buf, mask); | ||
696 | if (ret) | 699 | if (ret) |
697 | return ret; | 700 | goto out; |
698 | 701 | ||
699 | if (!cpumask_subset(&mask, cpu_online_mask) || cpumask_empty(&mask)) { | 702 | if (!cpumask_subset(mask, cpu_online_mask) || cpumask_empty(mask)) { |
700 | dd_dev_warn(dd, "Invalid CPU mask\n"); | 703 | dd_dev_warn(dd, "Invalid CPU mask\n"); |
701 | return -EINVAL; | 704 | ret = -EINVAL; |
705 | goto out; | ||
702 | } | 706 | } |
703 | 707 | ||
704 | mutex_lock(&sdma_affinity_mutex); | 708 | mutex_lock(&sdma_affinity_mutex); |
705 | /* reset the SDMA interrupt affinity details */ | 709 | /* reset the SDMA interrupt affinity details */ |
706 | init_cpu_mask_set(&entry->def_intr); | 710 | init_cpu_mask_set(&entry->def_intr); |
707 | cpumask_copy(&entry->def_intr.mask, &mask); | 711 | cpumask_copy(&entry->def_intr.mask, mask); |
708 | /* | 712 | /* |
709 | * Reassign the affinity for each SDMA interrupt. | 713 | * Reassign the affinity for each SDMA interrupt. |
710 | */ | 714 | */ |
@@ -720,8 +724,9 @@ int hfi1_set_sdma_affinity(struct hfi1_devdata *dd, const char *buf, | |||
720 | if (ret) | 724 | if (ret) |
721 | break; | 725 | break; |
722 | } | 726 | } |
723 | |||
724 | mutex_unlock(&sdma_affinity_mutex); | 727 | mutex_unlock(&sdma_affinity_mutex); |
728 | out: | ||
729 | free_cpumask_var(mask); | ||
725 | return ret ? ret : strnlen(buf, PAGE_SIZE); | 730 | return ret ? ret : strnlen(buf, PAGE_SIZE); |
726 | } | 731 | } |
727 | 732 | ||
diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c index b32638d58ae8..cc38004cea42 100644 --- a/drivers/infiniband/hw/hfi1/chip.c +++ b/drivers/infiniband/hw/hfi1/chip.c | |||
@@ -9490,6 +9490,78 @@ static void init_lcb(struct hfi1_devdata *dd) | |||
9490 | write_csr(dd, DC_LCB_CFG_TX_FIFOS_RESET, 0x00); | 9490 | write_csr(dd, DC_LCB_CFG_TX_FIFOS_RESET, 0x00); |
9491 | } | 9491 | } |
9492 | 9492 | ||
9493 | /* | ||
9494 | * Perform a test read on the QSFP. Return 0 on success, -ERRNO | ||
9495 | * on error. | ||
9496 | */ | ||
9497 | static int test_qsfp_read(struct hfi1_pportdata *ppd) | ||
9498 | { | ||
9499 | int ret; | ||
9500 | u8 status; | ||
9501 | |||
9502 | /* report success if not a QSFP */ | ||
9503 | if (ppd->port_type != PORT_TYPE_QSFP) | ||
9504 | return 0; | ||
9505 | |||
9506 | /* read byte 2, the status byte */ | ||
9507 | ret = one_qsfp_read(ppd, ppd->dd->hfi1_id, 2, &status, 1); | ||
9508 | if (ret < 0) | ||
9509 | return ret; | ||
9510 | if (ret != 1) | ||
9511 | return -EIO; | ||
9512 | |||
9513 | return 0; /* success */ | ||
9514 | } | ||
9515 | |||
9516 | /* | ||
9517 | * Values for QSFP retry. | ||
9518 | * | ||
9519 | * Give up after 10s (20 x 500ms). The overall timeout was empirically | ||
9520 | * arrived at from experience on a large cluster. | ||
9521 | */ | ||
9522 | #define MAX_QSFP_RETRIES 20 | ||
9523 | #define QSFP_RETRY_WAIT 500 /* msec */ | ||
9524 | |||
9525 | /* | ||
9526 | * Try a QSFP read. If it fails, schedule a retry for later. | ||
9527 | * Called on first link activation after driver load. | ||
9528 | */ | ||
9529 | static void try_start_link(struct hfi1_pportdata *ppd) | ||
9530 | { | ||
9531 | if (test_qsfp_read(ppd)) { | ||
9532 | /* read failed */ | ||
9533 | if (ppd->qsfp_retry_count >= MAX_QSFP_RETRIES) { | ||
9534 | dd_dev_err(ppd->dd, "QSFP not responding, giving up\n"); | ||
9535 | return; | ||
9536 | } | ||
9537 | dd_dev_info(ppd->dd, | ||
9538 | "QSFP not responding, waiting and retrying %d\n", | ||
9539 | (int)ppd->qsfp_retry_count); | ||
9540 | ppd->qsfp_retry_count++; | ||
9541 | queue_delayed_work(ppd->hfi1_wq, &ppd->start_link_work, | ||
9542 | msecs_to_jiffies(QSFP_RETRY_WAIT)); | ||
9543 | return; | ||
9544 | } | ||
9545 | ppd->qsfp_retry_count = 0; | ||
9546 | |||
9547 | /* | ||
9548 | * Tune the SerDes to a ballpark setting for optimal signal and bit | ||
9549 | * error rate. Needs to be done before starting the link. | ||
9550 | */ | ||
9551 | tune_serdes(ppd); | ||
9552 | start_link(ppd); | ||
9553 | } | ||
9554 | |||
9555 | /* | ||
9556 | * Workqueue function to start the link after a delay. | ||
9557 | */ | ||
9558 | void handle_start_link(struct work_struct *work) | ||
9559 | { | ||
9560 | struct hfi1_pportdata *ppd = container_of(work, struct hfi1_pportdata, | ||
9561 | start_link_work.work); | ||
9562 | try_start_link(ppd); | ||
9563 | } | ||
9564 | |||
9493 | int bringup_serdes(struct hfi1_pportdata *ppd) | 9565 | int bringup_serdes(struct hfi1_pportdata *ppd) |
9494 | { | 9566 | { |
9495 | struct hfi1_devdata *dd = ppd->dd; | 9567 | struct hfi1_devdata *dd = ppd->dd; |
@@ -9525,14 +9597,8 @@ int bringup_serdes(struct hfi1_pportdata *ppd) | |||
9525 | set_qsfp_int_n(ppd, 1); | 9597 | set_qsfp_int_n(ppd, 1); |
9526 | } | 9598 | } |
9527 | 9599 | ||
9528 | /* | 9600 | try_start_link(ppd); |
9529 | * Tune the SerDes to a ballpark setting for | 9601 | return 0; |
9530 | * optimal signal and bit error rate | ||
9531 | * Needs to be done before starting the link | ||
9532 | */ | ||
9533 | tune_serdes(ppd); | ||
9534 | |||
9535 | return start_link(ppd); | ||
9536 | } | 9602 | } |
9537 | 9603 | ||
9538 | void hfi1_quiet_serdes(struct hfi1_pportdata *ppd) | 9604 | void hfi1_quiet_serdes(struct hfi1_pportdata *ppd) |
@@ -9549,6 +9615,10 @@ void hfi1_quiet_serdes(struct hfi1_pportdata *ppd) | |||
9549 | ppd->driver_link_ready = 0; | 9615 | ppd->driver_link_ready = 0; |
9550 | ppd->link_enabled = 0; | 9616 | ppd->link_enabled = 0; |
9551 | 9617 | ||
9618 | ppd->qsfp_retry_count = MAX_QSFP_RETRIES; /* prevent more retries */ | ||
9619 | flush_delayed_work(&ppd->start_link_work); | ||
9620 | cancel_delayed_work_sync(&ppd->start_link_work); | ||
9621 | |||
9552 | ppd->offline_disabled_reason = | 9622 | ppd->offline_disabled_reason = |
9553 | HFI1_ODR_MASK(OPA_LINKDOWN_REASON_SMA_DISABLED); | 9623 | HFI1_ODR_MASK(OPA_LINKDOWN_REASON_SMA_DISABLED); |
9554 | set_link_down_reason(ppd, OPA_LINKDOWN_REASON_SMA_DISABLED, 0, | 9624 | set_link_down_reason(ppd, OPA_LINKDOWN_REASON_SMA_DISABLED, 0, |
@@ -12865,7 +12935,7 @@ fail: | |||
12865 | */ | 12935 | */ |
12866 | static int set_up_context_variables(struct hfi1_devdata *dd) | 12936 | static int set_up_context_variables(struct hfi1_devdata *dd) |
12867 | { | 12937 | { |
12868 | int num_kernel_contexts; | 12938 | unsigned long num_kernel_contexts; |
12869 | int total_contexts; | 12939 | int total_contexts; |
12870 | int ret; | 12940 | int ret; |
12871 | unsigned ngroups; | 12941 | unsigned ngroups; |
@@ -12894,9 +12964,9 @@ static int set_up_context_variables(struct hfi1_devdata *dd) | |||
12894 | */ | 12964 | */ |
12895 | if (num_kernel_contexts > (dd->chip_send_contexts - num_vls - 1)) { | 12965 | if (num_kernel_contexts > (dd->chip_send_contexts - num_vls - 1)) { |
12896 | dd_dev_err(dd, | 12966 | dd_dev_err(dd, |
12897 | "Reducing # kernel rcv contexts to: %d, from %d\n", | 12967 | "Reducing # kernel rcv contexts to: %d, from %lu\n", |
12898 | (int)(dd->chip_send_contexts - num_vls - 1), | 12968 | (int)(dd->chip_send_contexts - num_vls - 1), |
12899 | (int)num_kernel_contexts); | 12969 | num_kernel_contexts); |
12900 | num_kernel_contexts = dd->chip_send_contexts - num_vls - 1; | 12970 | num_kernel_contexts = dd->chip_send_contexts - num_vls - 1; |
12901 | } | 12971 | } |
12902 | /* | 12972 | /* |
diff --git a/drivers/infiniband/hw/hfi1/chip.h b/drivers/infiniband/hw/hfi1/chip.h index ed11107c50fe..e29573769efc 100644 --- a/drivers/infiniband/hw/hfi1/chip.h +++ b/drivers/infiniband/hw/hfi1/chip.h | |||
@@ -706,6 +706,7 @@ void handle_link_up(struct work_struct *work); | |||
706 | void handle_link_down(struct work_struct *work); | 706 | void handle_link_down(struct work_struct *work); |
707 | void handle_link_downgrade(struct work_struct *work); | 707 | void handle_link_downgrade(struct work_struct *work); |
708 | void handle_link_bounce(struct work_struct *work); | 708 | void handle_link_bounce(struct work_struct *work); |
709 | void handle_start_link(struct work_struct *work); | ||
709 | void handle_sma_message(struct work_struct *work); | 710 | void handle_sma_message(struct work_struct *work); |
710 | void reset_qsfp(struct hfi1_pportdata *ppd); | 711 | void reset_qsfp(struct hfi1_pportdata *ppd); |
711 | void qsfp_event(struct work_struct *work); | 712 | void qsfp_event(struct work_struct *work); |
diff --git a/drivers/infiniband/hw/hfi1/debugfs.c b/drivers/infiniband/hw/hfi1/debugfs.c index dbab9d9cc288..5e9be16f6cd3 100644 --- a/drivers/infiniband/hw/hfi1/debugfs.c +++ b/drivers/infiniband/hw/hfi1/debugfs.c | |||
@@ -59,6 +59,40 @@ | |||
59 | 59 | ||
60 | static struct dentry *hfi1_dbg_root; | 60 | static struct dentry *hfi1_dbg_root; |
61 | 61 | ||
62 | /* wrappers to enforce srcu in seq file */ | ||
63 | static ssize_t hfi1_seq_read( | ||
64 | struct file *file, | ||
65 | char __user *buf, | ||
66 | size_t size, | ||
67 | loff_t *ppos) | ||
68 | { | ||
69 | struct dentry *d = file->f_path.dentry; | ||
70 | int srcu_idx; | ||
71 | ssize_t r; | ||
72 | |||
73 | r = debugfs_use_file_start(d, &srcu_idx); | ||
74 | if (likely(!r)) | ||
75 | r = seq_read(file, buf, size, ppos); | ||
76 | debugfs_use_file_finish(srcu_idx); | ||
77 | return r; | ||
78 | } | ||
79 | |||
80 | static loff_t hfi1_seq_lseek( | ||
81 | struct file *file, | ||
82 | loff_t offset, | ||
83 | int whence) | ||
84 | { | ||
85 | struct dentry *d = file->f_path.dentry; | ||
86 | int srcu_idx; | ||
87 | loff_t r; | ||
88 | |||
89 | r = debugfs_use_file_start(d, &srcu_idx); | ||
90 | if (likely(!r)) | ||
91 | r = seq_lseek(file, offset, whence); | ||
92 | debugfs_use_file_finish(srcu_idx); | ||
93 | return r; | ||
94 | } | ||
95 | |||
62 | #define private2dd(file) (file_inode(file)->i_private) | 96 | #define private2dd(file) (file_inode(file)->i_private) |
63 | #define private2ppd(file) (file_inode(file)->i_private) | 97 | #define private2ppd(file) (file_inode(file)->i_private) |
64 | 98 | ||
@@ -87,8 +121,8 @@ static int _##name##_open(struct inode *inode, struct file *s) \ | |||
87 | static const struct file_operations _##name##_file_ops = { \ | 121 | static const struct file_operations _##name##_file_ops = { \ |
88 | .owner = THIS_MODULE, \ | 122 | .owner = THIS_MODULE, \ |
89 | .open = _##name##_open, \ | 123 | .open = _##name##_open, \ |
90 | .read = seq_read, \ | 124 | .read = hfi1_seq_read, \ |
91 | .llseek = seq_lseek, \ | 125 | .llseek = hfi1_seq_lseek, \ |
92 | .release = seq_release \ | 126 | .release = seq_release \ |
93 | } | 127 | } |
94 | 128 | ||
@@ -105,11 +139,9 @@ do { \ | |||
105 | DEBUGFS_FILE_CREATE(#name, parent, data, &_##name##_file_ops, S_IRUGO) | 139 | DEBUGFS_FILE_CREATE(#name, parent, data, &_##name##_file_ops, S_IRUGO) |
106 | 140 | ||
107 | static void *_opcode_stats_seq_start(struct seq_file *s, loff_t *pos) | 141 | static void *_opcode_stats_seq_start(struct seq_file *s, loff_t *pos) |
108 | __acquires(RCU) | ||
109 | { | 142 | { |
110 | struct hfi1_opcode_stats_perctx *opstats; | 143 | struct hfi1_opcode_stats_perctx *opstats; |
111 | 144 | ||
112 | rcu_read_lock(); | ||
113 | if (*pos >= ARRAY_SIZE(opstats->stats)) | 145 | if (*pos >= ARRAY_SIZE(opstats->stats)) |
114 | return NULL; | 146 | return NULL; |
115 | return pos; | 147 | return pos; |
@@ -126,9 +158,7 @@ static void *_opcode_stats_seq_next(struct seq_file *s, void *v, loff_t *pos) | |||
126 | } | 158 | } |
127 | 159 | ||
128 | static void _opcode_stats_seq_stop(struct seq_file *s, void *v) | 160 | static void _opcode_stats_seq_stop(struct seq_file *s, void *v) |
129 | __releases(RCU) | ||
130 | { | 161 | { |
131 | rcu_read_unlock(); | ||
132 | } | 162 | } |
133 | 163 | ||
134 | static int _opcode_stats_seq_show(struct seq_file *s, void *v) | 164 | static int _opcode_stats_seq_show(struct seq_file *s, void *v) |
@@ -223,28 +253,32 @@ DEBUGFS_SEQ_FILE_OPEN(ctx_stats) | |||
223 | DEBUGFS_FILE_OPS(ctx_stats); | 253 | DEBUGFS_FILE_OPS(ctx_stats); |
224 | 254 | ||
225 | static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos) | 255 | static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos) |
226 | __acquires(RCU) | 256 | __acquires(RCU) |
227 | { | 257 | { |
228 | struct qp_iter *iter; | 258 | struct qp_iter *iter; |
229 | loff_t n = *pos; | 259 | loff_t n = *pos; |
230 | 260 | ||
231 | rcu_read_lock(); | ||
232 | iter = qp_iter_init(s->private); | 261 | iter = qp_iter_init(s->private); |
262 | |||
263 | /* stop calls rcu_read_unlock */ | ||
264 | rcu_read_lock(); | ||
265 | |||
233 | if (!iter) | 266 | if (!iter) |
234 | return NULL; | 267 | return NULL; |
235 | 268 | ||
236 | while (n--) { | 269 | do { |
237 | if (qp_iter_next(iter)) { | 270 | if (qp_iter_next(iter)) { |
238 | kfree(iter); | 271 | kfree(iter); |
239 | return NULL; | 272 | return NULL; |
240 | } | 273 | } |
241 | } | 274 | } while (n--); |
242 | 275 | ||
243 | return iter; | 276 | return iter; |
244 | } | 277 | } |
245 | 278 | ||
246 | static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr, | 279 | static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr, |
247 | loff_t *pos) | 280 | loff_t *pos) |
281 | __must_hold(RCU) | ||
248 | { | 282 | { |
249 | struct qp_iter *iter = iter_ptr; | 283 | struct qp_iter *iter = iter_ptr; |
250 | 284 | ||
@@ -259,7 +293,7 @@ static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr, | |||
259 | } | 293 | } |
260 | 294 | ||
261 | static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr) | 295 | static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr) |
262 | __releases(RCU) | 296 | __releases(RCU) |
263 | { | 297 | { |
264 | rcu_read_unlock(); | 298 | rcu_read_unlock(); |
265 | } | 299 | } |
@@ -281,12 +315,10 @@ DEBUGFS_SEQ_FILE_OPEN(qp_stats) | |||
281 | DEBUGFS_FILE_OPS(qp_stats); | 315 | DEBUGFS_FILE_OPS(qp_stats); |
282 | 316 | ||
283 | static void *_sdes_seq_start(struct seq_file *s, loff_t *pos) | 317 | static void *_sdes_seq_start(struct seq_file *s, loff_t *pos) |
284 | __acquires(RCU) | ||
285 | { | 318 | { |
286 | struct hfi1_ibdev *ibd; | 319 | struct hfi1_ibdev *ibd; |
287 | struct hfi1_devdata *dd; | 320 | struct hfi1_devdata *dd; |
288 | 321 | ||
289 | rcu_read_lock(); | ||
290 | ibd = (struct hfi1_ibdev *)s->private; | 322 | ibd = (struct hfi1_ibdev *)s->private; |
291 | dd = dd_from_dev(ibd); | 323 | dd = dd_from_dev(ibd); |
292 | if (!dd->per_sdma || *pos >= dd->num_sdma) | 324 | if (!dd->per_sdma || *pos >= dd->num_sdma) |
@@ -306,9 +338,7 @@ static void *_sdes_seq_next(struct seq_file *s, void *v, loff_t *pos) | |||
306 | } | 338 | } |
307 | 339 | ||
308 | static void _sdes_seq_stop(struct seq_file *s, void *v) | 340 | static void _sdes_seq_stop(struct seq_file *s, void *v) |
309 | __releases(RCU) | ||
310 | { | 341 | { |
311 | rcu_read_unlock(); | ||
312 | } | 342 | } |
313 | 343 | ||
314 | static int _sdes_seq_show(struct seq_file *s, void *v) | 344 | static int _sdes_seq_show(struct seq_file *s, void *v) |
@@ -335,11 +365,9 @@ static ssize_t dev_counters_read(struct file *file, char __user *buf, | |||
335 | struct hfi1_devdata *dd; | 365 | struct hfi1_devdata *dd; |
336 | ssize_t rval; | 366 | ssize_t rval; |
337 | 367 | ||
338 | rcu_read_lock(); | ||
339 | dd = private2dd(file); | 368 | dd = private2dd(file); |
340 | avail = hfi1_read_cntrs(dd, NULL, &counters); | 369 | avail = hfi1_read_cntrs(dd, NULL, &counters); |
341 | rval = simple_read_from_buffer(buf, count, ppos, counters, avail); | 370 | rval = simple_read_from_buffer(buf, count, ppos, counters, avail); |
342 | rcu_read_unlock(); | ||
343 | return rval; | 371 | return rval; |
344 | } | 372 | } |
345 | 373 | ||
@@ -352,11 +380,9 @@ static ssize_t dev_names_read(struct file *file, char __user *buf, | |||
352 | struct hfi1_devdata *dd; | 380 | struct hfi1_devdata *dd; |
353 | ssize_t rval; | 381 | ssize_t rval; |
354 | 382 | ||
355 | rcu_read_lock(); | ||
356 | dd = private2dd(file); | 383 | dd = private2dd(file); |
357 | avail = hfi1_read_cntrs(dd, &names, NULL); | 384 | avail = hfi1_read_cntrs(dd, &names, NULL); |
358 | rval = simple_read_from_buffer(buf, count, ppos, names, avail); | 385 | rval = simple_read_from_buffer(buf, count, ppos, names, avail); |
359 | rcu_read_unlock(); | ||
360 | return rval; | 386 | return rval; |
361 | } | 387 | } |
362 | 388 | ||
@@ -379,11 +405,9 @@ static ssize_t portnames_read(struct file *file, char __user *buf, | |||
379 | struct hfi1_devdata *dd; | 405 | struct hfi1_devdata *dd; |
380 | ssize_t rval; | 406 | ssize_t rval; |
381 | 407 | ||
382 | rcu_read_lock(); | ||
383 | dd = private2dd(file); | 408 | dd = private2dd(file); |
384 | avail = hfi1_read_portcntrs(dd->pport, &names, NULL); | 409 | avail = hfi1_read_portcntrs(dd->pport, &names, NULL); |
385 | rval = simple_read_from_buffer(buf, count, ppos, names, avail); | 410 | rval = simple_read_from_buffer(buf, count, ppos, names, avail); |
386 | rcu_read_unlock(); | ||
387 | return rval; | 411 | return rval; |
388 | } | 412 | } |
389 | 413 | ||
@@ -396,11 +420,9 @@ static ssize_t portcntrs_debugfs_read(struct file *file, char __user *buf, | |||
396 | struct hfi1_pportdata *ppd; | 420 | struct hfi1_pportdata *ppd; |
397 | ssize_t rval; | 421 | ssize_t rval; |
398 | 422 | ||
399 | rcu_read_lock(); | ||
400 | ppd = private2ppd(file); | 423 | ppd = private2ppd(file); |
401 | avail = hfi1_read_portcntrs(ppd, NULL, &counters); | 424 | avail = hfi1_read_portcntrs(ppd, NULL, &counters); |
402 | rval = simple_read_from_buffer(buf, count, ppos, counters, avail); | 425 | rval = simple_read_from_buffer(buf, count, ppos, counters, avail); |
403 | rcu_read_unlock(); | ||
404 | return rval; | 426 | return rval; |
405 | } | 427 | } |
406 | 428 | ||
@@ -430,16 +452,13 @@ static ssize_t asic_flags_read(struct file *file, char __user *buf, | |||
430 | int used; | 452 | int used; |
431 | int i; | 453 | int i; |
432 | 454 | ||
433 | rcu_read_lock(); | ||
434 | ppd = private2ppd(file); | 455 | ppd = private2ppd(file); |
435 | dd = ppd->dd; | 456 | dd = ppd->dd; |
436 | size = PAGE_SIZE; | 457 | size = PAGE_SIZE; |
437 | used = 0; | 458 | used = 0; |
438 | tmp = kmalloc(size, GFP_KERNEL); | 459 | tmp = kmalloc(size, GFP_KERNEL); |
439 | if (!tmp) { | 460 | if (!tmp) |
440 | rcu_read_unlock(); | ||
441 | return -ENOMEM; | 461 | return -ENOMEM; |
442 | } | ||
443 | 462 | ||
444 | scratch0 = read_csr(dd, ASIC_CFG_SCRATCH); | 463 | scratch0 = read_csr(dd, ASIC_CFG_SCRATCH); |
445 | used += scnprintf(tmp + used, size - used, | 464 | used += scnprintf(tmp + used, size - used, |
@@ -466,7 +485,6 @@ static ssize_t asic_flags_read(struct file *file, char __user *buf, | |||
466 | used += scnprintf(tmp + used, size - used, "Write bits to clear\n"); | 485 | used += scnprintf(tmp + used, size - used, "Write bits to clear\n"); |
467 | 486 | ||
468 | ret = simple_read_from_buffer(buf, count, ppos, tmp, used); | 487 | ret = simple_read_from_buffer(buf, count, ppos, tmp, used); |
469 | rcu_read_unlock(); | ||
470 | kfree(tmp); | 488 | kfree(tmp); |
471 | return ret; | 489 | return ret; |
472 | } | 490 | } |
@@ -482,15 +500,12 @@ static ssize_t asic_flags_write(struct file *file, const char __user *buf, | |||
482 | u64 scratch0; | 500 | u64 scratch0; |
483 | u64 clear; | 501 | u64 clear; |
484 | 502 | ||
485 | rcu_read_lock(); | ||
486 | ppd = private2ppd(file); | 503 | ppd = private2ppd(file); |
487 | dd = ppd->dd; | 504 | dd = ppd->dd; |
488 | 505 | ||
489 | buff = kmalloc(count + 1, GFP_KERNEL); | 506 | buff = kmalloc(count + 1, GFP_KERNEL); |
490 | if (!buff) { | 507 | if (!buff) |
491 | ret = -ENOMEM; | 508 | return -ENOMEM; |
492 | goto do_return; | ||
493 | } | ||
494 | 509 | ||
495 | ret = copy_from_user(buff, buf, count); | 510 | ret = copy_from_user(buff, buf, count); |
496 | if (ret > 0) { | 511 | if (ret > 0) { |
@@ -523,8 +538,6 @@ static ssize_t asic_flags_write(struct file *file, const char __user *buf, | |||
523 | 538 | ||
524 | do_free: | 539 | do_free: |
525 | kfree(buff); | 540 | kfree(buff); |
526 | do_return: | ||
527 | rcu_read_unlock(); | ||
528 | return ret; | 541 | return ret; |
529 | } | 542 | } |
530 | 543 | ||
@@ -538,18 +551,14 @@ static ssize_t qsfp_debugfs_dump(struct file *file, char __user *buf, | |||
538 | char *tmp; | 551 | char *tmp; |
539 | int ret; | 552 | int ret; |
540 | 553 | ||
541 | rcu_read_lock(); | ||
542 | ppd = private2ppd(file); | 554 | ppd = private2ppd(file); |
543 | tmp = kmalloc(PAGE_SIZE, GFP_KERNEL); | 555 | tmp = kmalloc(PAGE_SIZE, GFP_KERNEL); |
544 | if (!tmp) { | 556 | if (!tmp) |
545 | rcu_read_unlock(); | ||
546 | return -ENOMEM; | 557 | return -ENOMEM; |
547 | } | ||
548 | 558 | ||
549 | ret = qsfp_dump(ppd, tmp, PAGE_SIZE); | 559 | ret = qsfp_dump(ppd, tmp, PAGE_SIZE); |
550 | if (ret > 0) | 560 | if (ret > 0) |
551 | ret = simple_read_from_buffer(buf, count, ppos, tmp, ret); | 561 | ret = simple_read_from_buffer(buf, count, ppos, tmp, ret); |
552 | rcu_read_unlock(); | ||
553 | kfree(tmp); | 562 | kfree(tmp); |
554 | return ret; | 563 | return ret; |
555 | } | 564 | } |
@@ -565,7 +574,6 @@ static ssize_t __i2c_debugfs_write(struct file *file, const char __user *buf, | |||
565 | int offset; | 574 | int offset; |
566 | int total_written; | 575 | int total_written; |
567 | 576 | ||
568 | rcu_read_lock(); | ||
569 | ppd = private2ppd(file); | 577 | ppd = private2ppd(file); |
570 | 578 | ||
571 | /* byte offset format: [offsetSize][i2cAddr][offsetHigh][offsetLow] */ | 579 | /* byte offset format: [offsetSize][i2cAddr][offsetHigh][offsetLow] */ |
@@ -573,16 +581,12 @@ static ssize_t __i2c_debugfs_write(struct file *file, const char __user *buf, | |||
573 | offset = *ppos & 0xffff; | 581 | offset = *ppos & 0xffff; |
574 | 582 | ||
575 | /* explicitly reject invalid address 0 to catch cp and cat */ | 583 | /* explicitly reject invalid address 0 to catch cp and cat */ |
576 | if (i2c_addr == 0) { | 584 | if (i2c_addr == 0) |
577 | ret = -EINVAL; | 585 | return -EINVAL; |
578 | goto _return; | ||
579 | } | ||
580 | 586 | ||
581 | buff = kmalloc(count, GFP_KERNEL); | 587 | buff = kmalloc(count, GFP_KERNEL); |
582 | if (!buff) { | 588 | if (!buff) |
583 | ret = -ENOMEM; | 589 | return -ENOMEM; |
584 | goto _return; | ||
585 | } | ||
586 | 590 | ||
587 | ret = copy_from_user(buff, buf, count); | 591 | ret = copy_from_user(buff, buf, count); |
588 | if (ret > 0) { | 592 | if (ret > 0) { |
@@ -602,8 +606,6 @@ static ssize_t __i2c_debugfs_write(struct file *file, const char __user *buf, | |||
602 | 606 | ||
603 | _free: | 607 | _free: |
604 | kfree(buff); | 608 | kfree(buff); |
605 | _return: | ||
606 | rcu_read_unlock(); | ||
607 | return ret; | 609 | return ret; |
608 | } | 610 | } |
609 | 611 | ||
@@ -632,7 +634,6 @@ static ssize_t __i2c_debugfs_read(struct file *file, char __user *buf, | |||
632 | int offset; | 634 | int offset; |
633 | int total_read; | 635 | int total_read; |
634 | 636 | ||
635 | rcu_read_lock(); | ||
636 | ppd = private2ppd(file); | 637 | ppd = private2ppd(file); |
637 | 638 | ||
638 | /* byte offset format: [offsetSize][i2cAddr][offsetHigh][offsetLow] */ | 639 | /* byte offset format: [offsetSize][i2cAddr][offsetHigh][offsetLow] */ |
@@ -640,16 +641,12 @@ static ssize_t __i2c_debugfs_read(struct file *file, char __user *buf, | |||
640 | offset = *ppos & 0xffff; | 641 | offset = *ppos & 0xffff; |
641 | 642 | ||
642 | /* explicitly reject invalid address 0 to catch cp and cat */ | 643 | /* explicitly reject invalid address 0 to catch cp and cat */ |
643 | if (i2c_addr == 0) { | 644 | if (i2c_addr == 0) |
644 | ret = -EINVAL; | 645 | return -EINVAL; |
645 | goto _return; | ||
646 | } | ||
647 | 646 | ||
648 | buff = kmalloc(count, GFP_KERNEL); | 647 | buff = kmalloc(count, GFP_KERNEL); |
649 | if (!buff) { | 648 | if (!buff) |
650 | ret = -ENOMEM; | 649 | return -ENOMEM; |
651 | goto _return; | ||
652 | } | ||
653 | 650 | ||
654 | total_read = i2c_read(ppd, target, i2c_addr, offset, buff, count); | 651 | total_read = i2c_read(ppd, target, i2c_addr, offset, buff, count); |
655 | if (total_read < 0) { | 652 | if (total_read < 0) { |
@@ -669,8 +666,6 @@ static ssize_t __i2c_debugfs_read(struct file *file, char __user *buf, | |||
669 | 666 | ||
670 | _free: | 667 | _free: |
671 | kfree(buff); | 668 | kfree(buff); |
672 | _return: | ||
673 | rcu_read_unlock(); | ||
674 | return ret; | 669 | return ret; |
675 | } | 670 | } |
676 | 671 | ||
@@ -697,26 +692,20 @@ static ssize_t __qsfp_debugfs_write(struct file *file, const char __user *buf, | |||
697 | int ret; | 692 | int ret; |
698 | int total_written; | 693 | int total_written; |
699 | 694 | ||
700 | rcu_read_lock(); | 695 | if (*ppos + count > QSFP_PAGESIZE * 4) /* base page + page00-page03 */ |
701 | if (*ppos + count > QSFP_PAGESIZE * 4) { /* base page + page00-page03 */ | 696 | return -EINVAL; |
702 | ret = -EINVAL; | ||
703 | goto _return; | ||
704 | } | ||
705 | 697 | ||
706 | ppd = private2ppd(file); | 698 | ppd = private2ppd(file); |
707 | 699 | ||
708 | buff = kmalloc(count, GFP_KERNEL); | 700 | buff = kmalloc(count, GFP_KERNEL); |
709 | if (!buff) { | 701 | if (!buff) |
710 | ret = -ENOMEM; | 702 | return -ENOMEM; |
711 | goto _return; | ||
712 | } | ||
713 | 703 | ||
714 | ret = copy_from_user(buff, buf, count); | 704 | ret = copy_from_user(buff, buf, count); |
715 | if (ret > 0) { | 705 | if (ret > 0) { |
716 | ret = -EFAULT; | 706 | ret = -EFAULT; |
717 | goto _free; | 707 | goto _free; |
718 | } | 708 | } |
719 | |||
720 | total_written = qsfp_write(ppd, target, *ppos, buff, count); | 709 | total_written = qsfp_write(ppd, target, *ppos, buff, count); |
721 | if (total_written < 0) { | 710 | if (total_written < 0) { |
722 | ret = total_written; | 711 | ret = total_written; |
@@ -729,8 +718,6 @@ static ssize_t __qsfp_debugfs_write(struct file *file, const char __user *buf, | |||
729 | 718 | ||
730 | _free: | 719 | _free: |
731 | kfree(buff); | 720 | kfree(buff); |
732 | _return: | ||
733 | rcu_read_unlock(); | ||
734 | return ret; | 721 | return ret; |
735 | } | 722 | } |
736 | 723 | ||
@@ -757,7 +744,6 @@ static ssize_t __qsfp_debugfs_read(struct file *file, char __user *buf, | |||
757 | int ret; | 744 | int ret; |
758 | int total_read; | 745 | int total_read; |
759 | 746 | ||
760 | rcu_read_lock(); | ||
761 | if (*ppos + count > QSFP_PAGESIZE * 4) { /* base page + page00-page03 */ | 747 | if (*ppos + count > QSFP_PAGESIZE * 4) { /* base page + page00-page03 */ |
762 | ret = -EINVAL; | 748 | ret = -EINVAL; |
763 | goto _return; | 749 | goto _return; |
@@ -790,7 +776,6 @@ static ssize_t __qsfp_debugfs_read(struct file *file, char __user *buf, | |||
790 | _free: | 776 | _free: |
791 | kfree(buff); | 777 | kfree(buff); |
792 | _return: | 778 | _return: |
793 | rcu_read_unlock(); | ||
794 | return ret; | 779 | return ret; |
795 | } | 780 | } |
796 | 781 | ||
@@ -1006,7 +991,6 @@ void hfi1_dbg_ibdev_exit(struct hfi1_ibdev *ibd) | |||
1006 | debugfs_remove_recursive(ibd->hfi1_ibdev_dbg); | 991 | debugfs_remove_recursive(ibd->hfi1_ibdev_dbg); |
1007 | out: | 992 | out: |
1008 | ibd->hfi1_ibdev_dbg = NULL; | 993 | ibd->hfi1_ibdev_dbg = NULL; |
1009 | synchronize_rcu(); | ||
1010 | } | 994 | } |
1011 | 995 | ||
1012 | /* | 996 | /* |
@@ -1031,9 +1015,7 @@ static const char * const hfi1_statnames[] = { | |||
1031 | }; | 1015 | }; |
1032 | 1016 | ||
1033 | static void *_driver_stats_names_seq_start(struct seq_file *s, loff_t *pos) | 1017 | static void *_driver_stats_names_seq_start(struct seq_file *s, loff_t *pos) |
1034 | __acquires(RCU) | ||
1035 | { | 1018 | { |
1036 | rcu_read_lock(); | ||
1037 | if (*pos >= ARRAY_SIZE(hfi1_statnames)) | 1019 | if (*pos >= ARRAY_SIZE(hfi1_statnames)) |
1038 | return NULL; | 1020 | return NULL; |
1039 | return pos; | 1021 | return pos; |
@@ -1051,9 +1033,7 @@ static void *_driver_stats_names_seq_next( | |||
1051 | } | 1033 | } |
1052 | 1034 | ||
1053 | static void _driver_stats_names_seq_stop(struct seq_file *s, void *v) | 1035 | static void _driver_stats_names_seq_stop(struct seq_file *s, void *v) |
1054 | __releases(RCU) | ||
1055 | { | 1036 | { |
1056 | rcu_read_unlock(); | ||
1057 | } | 1037 | } |
1058 | 1038 | ||
1059 | static int _driver_stats_names_seq_show(struct seq_file *s, void *v) | 1039 | static int _driver_stats_names_seq_show(struct seq_file *s, void *v) |
@@ -1069,9 +1049,7 @@ DEBUGFS_SEQ_FILE_OPEN(driver_stats_names) | |||
1069 | DEBUGFS_FILE_OPS(driver_stats_names); | 1049 | DEBUGFS_FILE_OPS(driver_stats_names); |
1070 | 1050 | ||
1071 | static void *_driver_stats_seq_start(struct seq_file *s, loff_t *pos) | 1051 | static void *_driver_stats_seq_start(struct seq_file *s, loff_t *pos) |
1072 | __acquires(RCU) | ||
1073 | { | 1052 | { |
1074 | rcu_read_lock(); | ||
1075 | if (*pos >= ARRAY_SIZE(hfi1_statnames)) | 1053 | if (*pos >= ARRAY_SIZE(hfi1_statnames)) |
1076 | return NULL; | 1054 | return NULL; |
1077 | return pos; | 1055 | return pos; |
@@ -1086,9 +1064,7 @@ static void *_driver_stats_seq_next(struct seq_file *s, void *v, loff_t *pos) | |||
1086 | } | 1064 | } |
1087 | 1065 | ||
1088 | static void _driver_stats_seq_stop(struct seq_file *s, void *v) | 1066 | static void _driver_stats_seq_stop(struct seq_file *s, void *v) |
1089 | __releases(RCU) | ||
1090 | { | 1067 | { |
1091 | rcu_read_unlock(); | ||
1092 | } | 1068 | } |
1093 | 1069 | ||
1094 | static u64 hfi1_sps_ints(void) | 1070 | static u64 hfi1_sps_ints(void) |
diff --git a/drivers/infiniband/hw/hfi1/driver.c b/drivers/infiniband/hw/hfi1/driver.c index 8246dc7d0573..303f10555729 100644 --- a/drivers/infiniband/hw/hfi1/driver.c +++ b/drivers/infiniband/hw/hfi1/driver.c | |||
@@ -888,14 +888,15 @@ void set_all_slowpath(struct hfi1_devdata *dd) | |||
888 | } | 888 | } |
889 | 889 | ||
890 | static inline int set_armed_to_active(struct hfi1_ctxtdata *rcd, | 890 | static inline int set_armed_to_active(struct hfi1_ctxtdata *rcd, |
891 | struct hfi1_packet packet, | 891 | struct hfi1_packet *packet, |
892 | struct hfi1_devdata *dd) | 892 | struct hfi1_devdata *dd) |
893 | { | 893 | { |
894 | struct work_struct *lsaw = &rcd->ppd->linkstate_active_work; | 894 | struct work_struct *lsaw = &rcd->ppd->linkstate_active_work; |
895 | struct hfi1_message_header *hdr = hfi1_get_msgheader(packet.rcd->dd, | 895 | struct hfi1_message_header *hdr = hfi1_get_msgheader(packet->rcd->dd, |
896 | packet.rhf_addr); | 896 | packet->rhf_addr); |
897 | u8 etype = rhf_rcv_type(packet->rhf); | ||
897 | 898 | ||
898 | if (hdr2sc(hdr, packet.rhf) != 0xf) { | 899 | if (etype == RHF_RCV_TYPE_IB && hdr2sc(hdr, packet->rhf) != 0xf) { |
899 | int hwstate = read_logical_state(dd); | 900 | int hwstate = read_logical_state(dd); |
900 | 901 | ||
901 | if (hwstate != LSTATE_ACTIVE) { | 902 | if (hwstate != LSTATE_ACTIVE) { |
@@ -979,7 +980,7 @@ int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread) | |||
979 | /* Auto activate link on non-SC15 packet receive */ | 980 | /* Auto activate link on non-SC15 packet receive */ |
980 | if (unlikely(rcd->ppd->host_link_state == | 981 | if (unlikely(rcd->ppd->host_link_state == |
981 | HLS_UP_ARMED) && | 982 | HLS_UP_ARMED) && |
982 | set_armed_to_active(rcd, packet, dd)) | 983 | set_armed_to_active(rcd, &packet, dd)) |
983 | goto bail; | 984 | goto bail; |
984 | last = process_rcv_packet(&packet, thread); | 985 | last = process_rcv_packet(&packet, thread); |
985 | } | 986 | } |
diff --git a/drivers/infiniband/hw/hfi1/file_ops.c b/drivers/infiniband/hw/hfi1/file_ops.c index 1ecbec192358..7e03ccd2554d 100644 --- a/drivers/infiniband/hw/hfi1/file_ops.c +++ b/drivers/infiniband/hw/hfi1/file_ops.c | |||
@@ -183,6 +183,7 @@ static int hfi1_file_open(struct inode *inode, struct file *fp) | |||
183 | if (fd) { | 183 | if (fd) { |
184 | fd->rec_cpu_num = -1; /* no cpu affinity by default */ | 184 | fd->rec_cpu_num = -1; /* no cpu affinity by default */ |
185 | fd->mm = current->mm; | 185 | fd->mm = current->mm; |
186 | atomic_inc(&fd->mm->mm_count); | ||
186 | } | 187 | } |
187 | 188 | ||
188 | fp->private_data = fd; | 189 | fp->private_data = fd; |
@@ -222,7 +223,7 @@ static long hfi1_file_ioctl(struct file *fp, unsigned int cmd, | |||
222 | ret = assign_ctxt(fp, &uinfo); | 223 | ret = assign_ctxt(fp, &uinfo); |
223 | if (ret < 0) | 224 | if (ret < 0) |
224 | return ret; | 225 | return ret; |
225 | setup_ctxt(fp); | 226 | ret = setup_ctxt(fp); |
226 | if (ret) | 227 | if (ret) |
227 | return ret; | 228 | return ret; |
228 | ret = user_init(fp); | 229 | ret = user_init(fp); |
@@ -779,6 +780,7 @@ static int hfi1_file_close(struct inode *inode, struct file *fp) | |||
779 | mutex_unlock(&hfi1_mutex); | 780 | mutex_unlock(&hfi1_mutex); |
780 | hfi1_free_ctxtdata(dd, uctxt); | 781 | hfi1_free_ctxtdata(dd, uctxt); |
781 | done: | 782 | done: |
783 | mmdrop(fdata->mm); | ||
782 | kobject_put(&dd->kobj); | 784 | kobject_put(&dd->kobj); |
783 | kfree(fdata); | 785 | kfree(fdata); |
784 | return 0; | 786 | return 0; |
diff --git a/drivers/infiniband/hw/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h index 1000e0fd96d9..325ec211370f 100644 --- a/drivers/infiniband/hw/hfi1/hfi.h +++ b/drivers/infiniband/hw/hfi1/hfi.h | |||
@@ -605,6 +605,7 @@ struct hfi1_pportdata { | |||
605 | struct work_struct freeze_work; | 605 | struct work_struct freeze_work; |
606 | struct work_struct link_downgrade_work; | 606 | struct work_struct link_downgrade_work; |
607 | struct work_struct link_bounce_work; | 607 | struct work_struct link_bounce_work; |
608 | struct delayed_work start_link_work; | ||
608 | /* host link state variables */ | 609 | /* host link state variables */ |
609 | struct mutex hls_lock; | 610 | struct mutex hls_lock; |
610 | u32 host_link_state; | 611 | u32 host_link_state; |
@@ -659,6 +660,7 @@ struct hfi1_pportdata { | |||
659 | u8 linkinit_reason; | 660 | u8 linkinit_reason; |
660 | u8 local_tx_rate; /* rate given to 8051 firmware */ | 661 | u8 local_tx_rate; /* rate given to 8051 firmware */ |
661 | u8 last_pstate; /* info only */ | 662 | u8 last_pstate; /* info only */ |
663 | u8 qsfp_retry_count; | ||
662 | 664 | ||
663 | /* placeholders for IB MAD packet settings */ | 665 | /* placeholders for IB MAD packet settings */ |
664 | u8 overrun_threshold; | 666 | u8 overrun_threshold; |
@@ -1272,9 +1274,26 @@ static inline int hdr2sc(struct hfi1_message_header *hdr, u64 rhf) | |||
1272 | ((!!(rhf_dc_info(rhf))) << 4); | 1274 | ((!!(rhf_dc_info(rhf))) << 4); |
1273 | } | 1275 | } |
1274 | 1276 | ||
1277 | #define HFI1_JKEY_WIDTH 16 | ||
1278 | #define HFI1_JKEY_MASK (BIT(16) - 1) | ||
1279 | #define HFI1_ADMIN_JKEY_RANGE 32 | ||
1280 | |||
1281 | /* | ||
1282 | * J_KEYs are split and allocated in the following groups: | ||
1283 | * 0 - 31 - users with administrator privileges | ||
1284 | * 32 - 63 - kernel protocols using KDETH packets | ||
1285 | * 64 - 65535 - all other users using KDETH packets | ||
1286 | */ | ||
1275 | static inline u16 generate_jkey(kuid_t uid) | 1287 | static inline u16 generate_jkey(kuid_t uid) |
1276 | { | 1288 | { |
1277 | return from_kuid(current_user_ns(), uid) & 0xffff; | 1289 | u16 jkey = from_kuid(current_user_ns(), uid) & HFI1_JKEY_MASK; |
1290 | |||
1291 | if (capable(CAP_SYS_ADMIN)) | ||
1292 | jkey &= HFI1_ADMIN_JKEY_RANGE - 1; | ||
1293 | else if (jkey < 64) | ||
1294 | jkey |= BIT(HFI1_JKEY_WIDTH - 1); | ||
1295 | |||
1296 | return jkey; | ||
1278 | } | 1297 | } |
1279 | 1298 | ||
1280 | /* | 1299 | /* |
@@ -1656,7 +1675,6 @@ struct cc_state *get_cc_state_protected(struct hfi1_pportdata *ppd) | |||
1656 | struct hfi1_devdata *hfi1_init_dd(struct pci_dev *, | 1675 | struct hfi1_devdata *hfi1_init_dd(struct pci_dev *, |
1657 | const struct pci_device_id *); | 1676 | const struct pci_device_id *); |
1658 | void hfi1_free_devdata(struct hfi1_devdata *); | 1677 | void hfi1_free_devdata(struct hfi1_devdata *); |
1659 | void cc_state_reclaim(struct rcu_head *rcu); | ||
1660 | struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra); | 1678 | struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra); |
1661 | 1679 | ||
1662 | /* LED beaconing functions */ | 1680 | /* LED beaconing functions */ |
@@ -1788,7 +1806,7 @@ extern unsigned int hfi1_max_mtu; | |||
1788 | extern unsigned int hfi1_cu; | 1806 | extern unsigned int hfi1_cu; |
1789 | extern unsigned int user_credit_return_threshold; | 1807 | extern unsigned int user_credit_return_threshold; |
1790 | extern int num_user_contexts; | 1808 | extern int num_user_contexts; |
1791 | extern unsigned n_krcvqs; | 1809 | extern unsigned long n_krcvqs; |
1792 | extern uint krcvqs[]; | 1810 | extern uint krcvqs[]; |
1793 | extern int krcvqsset; | 1811 | extern int krcvqsset; |
1794 | extern uint kdeth_qp; | 1812 | extern uint kdeth_qp; |
diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c index a358d23ecd54..384b43d2fd49 100644 --- a/drivers/infiniband/hw/hfi1/init.c +++ b/drivers/infiniband/hw/hfi1/init.c | |||
@@ -94,7 +94,7 @@ module_param_array(krcvqs, uint, &krcvqsset, S_IRUGO); | |||
94 | MODULE_PARM_DESC(krcvqs, "Array of the number of non-control kernel receive queues by VL"); | 94 | MODULE_PARM_DESC(krcvqs, "Array of the number of non-control kernel receive queues by VL"); |
95 | 95 | ||
96 | /* computed based on above array */ | 96 | /* computed based on above array */ |
97 | unsigned n_krcvqs; | 97 | unsigned long n_krcvqs; |
98 | 98 | ||
99 | static unsigned hfi1_rcvarr_split = 25; | 99 | static unsigned hfi1_rcvarr_split = 25; |
100 | module_param_named(rcvarr_split, hfi1_rcvarr_split, uint, S_IRUGO); | 100 | module_param_named(rcvarr_split, hfi1_rcvarr_split, uint, S_IRUGO); |
@@ -500,6 +500,7 @@ void hfi1_init_pportdata(struct pci_dev *pdev, struct hfi1_pportdata *ppd, | |||
500 | INIT_WORK(&ppd->link_downgrade_work, handle_link_downgrade); | 500 | INIT_WORK(&ppd->link_downgrade_work, handle_link_downgrade); |
501 | INIT_WORK(&ppd->sma_message_work, handle_sma_message); | 501 | INIT_WORK(&ppd->sma_message_work, handle_sma_message); |
502 | INIT_WORK(&ppd->link_bounce_work, handle_link_bounce); | 502 | INIT_WORK(&ppd->link_bounce_work, handle_link_bounce); |
503 | INIT_DELAYED_WORK(&ppd->start_link_work, handle_start_link); | ||
503 | INIT_WORK(&ppd->linkstate_active_work, receive_interrupt_work); | 504 | INIT_WORK(&ppd->linkstate_active_work, receive_interrupt_work); |
504 | INIT_WORK(&ppd->qsfp_info.qsfp_work, qsfp_event); | 505 | INIT_WORK(&ppd->qsfp_info.qsfp_work, qsfp_event); |
505 | 506 | ||
@@ -1333,7 +1334,7 @@ static void cleanup_device_data(struct hfi1_devdata *dd) | |||
1333 | spin_unlock(&ppd->cc_state_lock); | 1334 | spin_unlock(&ppd->cc_state_lock); |
1334 | 1335 | ||
1335 | if (cc_state) | 1336 | if (cc_state) |
1336 | call_rcu(&cc_state->rcu, cc_state_reclaim); | 1337 | kfree_rcu(cc_state, rcu); |
1337 | } | 1338 | } |
1338 | 1339 | ||
1339 | free_credit_return(dd); | 1340 | free_credit_return(dd); |
diff --git a/drivers/infiniband/hw/hfi1/mad.c b/drivers/infiniband/hw/hfi1/mad.c index 1263abe01999..7ffc14f21523 100644 --- a/drivers/infiniband/hw/hfi1/mad.c +++ b/drivers/infiniband/hw/hfi1/mad.c | |||
@@ -1819,6 +1819,11 @@ static int __subn_get_opa_cable_info(struct opa_smp *smp, u32 am, u8 *data, | |||
1819 | u32 len = OPA_AM_CI_LEN(am) + 1; | 1819 | u32 len = OPA_AM_CI_LEN(am) + 1; |
1820 | int ret; | 1820 | int ret; |
1821 | 1821 | ||
1822 | if (dd->pport->port_type != PORT_TYPE_QSFP) { | ||
1823 | smp->status |= IB_SMP_INVALID_FIELD; | ||
1824 | return reply((struct ib_mad_hdr *)smp); | ||
1825 | } | ||
1826 | |||
1822 | #define __CI_PAGE_SIZE BIT(7) /* 128 bytes */ | 1827 | #define __CI_PAGE_SIZE BIT(7) /* 128 bytes */ |
1823 | #define __CI_PAGE_MASK ~(__CI_PAGE_SIZE - 1) | 1828 | #define __CI_PAGE_MASK ~(__CI_PAGE_SIZE - 1) |
1824 | #define __CI_PAGE_NUM(a) ((a) & __CI_PAGE_MASK) | 1829 | #define __CI_PAGE_NUM(a) ((a) & __CI_PAGE_MASK) |
@@ -2599,7 +2604,7 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp, | |||
2599 | u8 lq, num_vls; | 2604 | u8 lq, num_vls; |
2600 | u8 res_lli, res_ler; | 2605 | u8 res_lli, res_ler; |
2601 | u64 port_mask; | 2606 | u64 port_mask; |
2602 | unsigned long port_num; | 2607 | u8 port_num; |
2603 | unsigned long vl; | 2608 | unsigned long vl; |
2604 | u32 vl_select_mask; | 2609 | u32 vl_select_mask; |
2605 | int vfi; | 2610 | int vfi; |
@@ -2633,9 +2638,9 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp, | |||
2633 | */ | 2638 | */ |
2634 | port_mask = be64_to_cpu(req->port_select_mask[3]); | 2639 | port_mask = be64_to_cpu(req->port_select_mask[3]); |
2635 | port_num = find_first_bit((unsigned long *)&port_mask, | 2640 | port_num = find_first_bit((unsigned long *)&port_mask, |
2636 | sizeof(port_mask)); | 2641 | sizeof(port_mask) * 8); |
2637 | 2642 | ||
2638 | if ((u8)port_num != port) { | 2643 | if (port_num != port) { |
2639 | pmp->mad_hdr.status |= IB_SMP_INVALID_FIELD; | 2644 | pmp->mad_hdr.status |= IB_SMP_INVALID_FIELD; |
2640 | return reply((struct ib_mad_hdr *)pmp); | 2645 | return reply((struct ib_mad_hdr *)pmp); |
2641 | } | 2646 | } |
@@ -2837,7 +2842,7 @@ static int pma_get_opa_porterrors(struct opa_pma_mad *pmp, | |||
2837 | */ | 2842 | */ |
2838 | port_mask = be64_to_cpu(req->port_select_mask[3]); | 2843 | port_mask = be64_to_cpu(req->port_select_mask[3]); |
2839 | port_num = find_first_bit((unsigned long *)&port_mask, | 2844 | port_num = find_first_bit((unsigned long *)&port_mask, |
2840 | sizeof(port_mask)); | 2845 | sizeof(port_mask) * 8); |
2841 | 2846 | ||
2842 | if (port_num != port) { | 2847 | if (port_num != port) { |
2843 | pmp->mad_hdr.status |= IB_SMP_INVALID_FIELD; | 2848 | pmp->mad_hdr.status |= IB_SMP_INVALID_FIELD; |
@@ -3010,7 +3015,7 @@ static int pma_get_opa_errorinfo(struct opa_pma_mad *pmp, | |||
3010 | */ | 3015 | */ |
3011 | port_mask = be64_to_cpu(req->port_select_mask[3]); | 3016 | port_mask = be64_to_cpu(req->port_select_mask[3]); |
3012 | port_num = find_first_bit((unsigned long *)&port_mask, | 3017 | port_num = find_first_bit((unsigned long *)&port_mask, |
3013 | sizeof(port_mask)); | 3018 | sizeof(port_mask) * 8); |
3014 | 3019 | ||
3015 | if (port_num != port) { | 3020 | if (port_num != port) { |
3016 | pmp->mad_hdr.status |= IB_SMP_INVALID_FIELD; | 3021 | pmp->mad_hdr.status |= IB_SMP_INVALID_FIELD; |
@@ -3247,7 +3252,7 @@ static int pma_set_opa_errorinfo(struct opa_pma_mad *pmp, | |||
3247 | */ | 3252 | */ |
3248 | port_mask = be64_to_cpu(req->port_select_mask[3]); | 3253 | port_mask = be64_to_cpu(req->port_select_mask[3]); |
3249 | port_num = find_first_bit((unsigned long *)&port_mask, | 3254 | port_num = find_first_bit((unsigned long *)&port_mask, |
3250 | sizeof(port_mask)); | 3255 | sizeof(port_mask) * 8); |
3251 | 3256 | ||
3252 | if (port_num != port) { | 3257 | if (port_num != port) { |
3253 | pmp->mad_hdr.status |= IB_SMP_INVALID_FIELD; | 3258 | pmp->mad_hdr.status |= IB_SMP_INVALID_FIELD; |
@@ -3398,7 +3403,7 @@ static void apply_cc_state(struct hfi1_pportdata *ppd) | |||
3398 | 3403 | ||
3399 | spin_unlock(&ppd->cc_state_lock); | 3404 | spin_unlock(&ppd->cc_state_lock); |
3400 | 3405 | ||
3401 | call_rcu(&old_cc_state->rcu, cc_state_reclaim); | 3406 | kfree_rcu(old_cc_state, rcu); |
3402 | } | 3407 | } |
3403 | 3408 | ||
3404 | static int __subn_set_opa_cong_setting(struct opa_smp *smp, u32 am, u8 *data, | 3409 | static int __subn_set_opa_cong_setting(struct opa_smp *smp, u32 am, u8 *data, |
@@ -3553,13 +3558,6 @@ static int __subn_get_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data, | |||
3553 | return reply((struct ib_mad_hdr *)smp); | 3558 | return reply((struct ib_mad_hdr *)smp); |
3554 | } | 3559 | } |
3555 | 3560 | ||
3556 | void cc_state_reclaim(struct rcu_head *rcu) | ||
3557 | { | ||
3558 | struct cc_state *cc_state = container_of(rcu, struct cc_state, rcu); | ||
3559 | |||
3560 | kfree(cc_state); | ||
3561 | } | ||
3562 | |||
3563 | static int __subn_set_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data, | 3561 | static int __subn_set_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data, |
3564 | struct ib_device *ibdev, u8 port, | 3562 | struct ib_device *ibdev, u8 port, |
3565 | u32 *resp_len) | 3563 | u32 *resp_len) |
diff --git a/drivers/infiniband/hw/hfi1/pio_copy.c b/drivers/infiniband/hw/hfi1/pio_copy.c index 8c25e1b58849..3a1ef3056282 100644 --- a/drivers/infiniband/hw/hfi1/pio_copy.c +++ b/drivers/infiniband/hw/hfi1/pio_copy.c | |||
@@ -771,6 +771,9 @@ void seg_pio_copy_mid(struct pio_buf *pbuf, const void *from, size_t nbytes) | |||
771 | read_extra_bytes(pbuf, from, to_fill); | 771 | read_extra_bytes(pbuf, from, to_fill); |
772 | from += to_fill; | 772 | from += to_fill; |
773 | nbytes -= to_fill; | 773 | nbytes -= to_fill; |
774 | /* may not be enough valid bytes left to align */ | ||
775 | if (extra > nbytes) | ||
776 | extra = nbytes; | ||
774 | 777 | ||
775 | /* ...now write carry */ | 778 | /* ...now write carry */ |
776 | dest = pbuf->start + (pbuf->qw_written * sizeof(u64)); | 779 | dest = pbuf->start + (pbuf->qw_written * sizeof(u64)); |
@@ -798,6 +801,15 @@ void seg_pio_copy_mid(struct pio_buf *pbuf, const void *from, size_t nbytes) | |||
798 | read_low_bytes(pbuf, from, extra); | 801 | read_low_bytes(pbuf, from, extra); |
799 | from += extra; | 802 | from += extra; |
800 | nbytes -= extra; | 803 | nbytes -= extra; |
804 | /* | ||
805 | * If no bytes are left, return early - we are done. | ||
806 | * NOTE: This short-circuit is *required* because | ||
807 | * "extra" may have been reduced in size and "from" | ||
808 | * is not aligned, as required when leaving this | ||
809 | * if block. | ||
810 | */ | ||
811 | if (nbytes == 0) | ||
812 | return; | ||
801 | } | 813 | } |
802 | 814 | ||
803 | /* at this point, from is QW aligned */ | 815 | /* at this point, from is QW aligned */ |
diff --git a/drivers/infiniband/hw/hfi1/qp.c b/drivers/infiniband/hw/hfi1/qp.c index a5aa3517e7d5..4e4d8317c281 100644 --- a/drivers/infiniband/hw/hfi1/qp.c +++ b/drivers/infiniband/hw/hfi1/qp.c | |||
@@ -656,10 +656,6 @@ struct qp_iter *qp_iter_init(struct hfi1_ibdev *dev) | |||
656 | 656 | ||
657 | iter->dev = dev; | 657 | iter->dev = dev; |
658 | iter->specials = dev->rdi.ibdev.phys_port_cnt * 2; | 658 | iter->specials = dev->rdi.ibdev.phys_port_cnt * 2; |
659 | if (qp_iter_next(iter)) { | ||
660 | kfree(iter); | ||
661 | return NULL; | ||
662 | } | ||
663 | 659 | ||
664 | return iter; | 660 | return iter; |
665 | } | 661 | } |
diff --git a/drivers/infiniband/hw/hfi1/qsfp.c b/drivers/infiniband/hw/hfi1/qsfp.c index a207717ade2a..4e95ad810847 100644 --- a/drivers/infiniband/hw/hfi1/qsfp.c +++ b/drivers/infiniband/hw/hfi1/qsfp.c | |||
@@ -706,8 +706,8 @@ int get_cable_info(struct hfi1_devdata *dd, u32 port_num, u32 addr, u32 len, | |||
706 | u8 *data) | 706 | u8 *data) |
707 | { | 707 | { |
708 | struct hfi1_pportdata *ppd; | 708 | struct hfi1_pportdata *ppd; |
709 | u32 excess_len = 0; | 709 | u32 excess_len = len; |
710 | int ret = 0; | 710 | int ret = 0, offset = 0; |
711 | 711 | ||
712 | if (port_num > dd->num_pports || port_num < 1) { | 712 | if (port_num > dd->num_pports || port_num < 1) { |
713 | dd_dev_info(dd, "%s: Invalid port number %d\n", | 713 | dd_dev_info(dd, "%s: Invalid port number %d\n", |
@@ -740,6 +740,34 @@ int get_cable_info(struct hfi1_devdata *dd, u32 port_num, u32 addr, u32 len, | |||
740 | } | 740 | } |
741 | 741 | ||
742 | memcpy(data, &ppd->qsfp_info.cache[addr], len); | 742 | memcpy(data, &ppd->qsfp_info.cache[addr], len); |
743 | |||
744 | if (addr <= QSFP_MONITOR_VAL_END && | ||
745 | (addr + len) >= QSFP_MONITOR_VAL_START) { | ||
746 | /* Overlap with the dynamic channel monitor range */ | ||
747 | if (addr < QSFP_MONITOR_VAL_START) { | ||
748 | if (addr + len <= QSFP_MONITOR_VAL_END) | ||
749 | len = addr + len - QSFP_MONITOR_VAL_START; | ||
750 | else | ||
751 | len = QSFP_MONITOR_RANGE; | ||
752 | offset = QSFP_MONITOR_VAL_START - addr; | ||
753 | addr = QSFP_MONITOR_VAL_START; | ||
754 | } else if (addr == QSFP_MONITOR_VAL_START) { | ||
755 | offset = 0; | ||
756 | if (addr + len > QSFP_MONITOR_VAL_END) | ||
757 | len = QSFP_MONITOR_RANGE; | ||
758 | } else { | ||
759 | offset = 0; | ||
760 | if (addr + len > QSFP_MONITOR_VAL_END) | ||
761 | len = QSFP_MONITOR_VAL_END - addr + 1; | ||
762 | } | ||
763 | /* Refresh the values of the dynamic monitors from the cable */ | ||
764 | ret = one_qsfp_read(ppd, dd->hfi1_id, addr, data + offset, len); | ||
765 | if (ret != len) { | ||
766 | ret = -EAGAIN; | ||
767 | goto set_zeroes; | ||
768 | } | ||
769 | } | ||
770 | |||
743 | return 0; | 771 | return 0; |
744 | 772 | ||
745 | set_zeroes: | 773 | set_zeroes: |
diff --git a/drivers/infiniband/hw/hfi1/qsfp.h b/drivers/infiniband/hw/hfi1/qsfp.h index 69275ebd9597..36cf52359848 100644 --- a/drivers/infiniband/hw/hfi1/qsfp.h +++ b/drivers/infiniband/hw/hfi1/qsfp.h | |||
@@ -74,6 +74,9 @@ | |||
74 | /* Defined fields that Intel requires of qualified cables */ | 74 | /* Defined fields that Intel requires of qualified cables */ |
75 | /* Byte 0 is Identifier, not checked */ | 75 | /* Byte 0 is Identifier, not checked */ |
76 | /* Byte 1 is reserved "status MSB" */ | 76 | /* Byte 1 is reserved "status MSB" */ |
77 | #define QSFP_MONITOR_VAL_START 22 | ||
78 | #define QSFP_MONITOR_VAL_END 81 | ||
79 | #define QSFP_MONITOR_RANGE (QSFP_MONITOR_VAL_END - QSFP_MONITOR_VAL_START + 1) | ||
77 | #define QSFP_TX_CTRL_BYTE_OFFS 86 | 80 | #define QSFP_TX_CTRL_BYTE_OFFS 86 |
78 | #define QSFP_PWR_CTRL_BYTE_OFFS 93 | 81 | #define QSFP_PWR_CTRL_BYTE_OFFS 93 |
79 | #define QSFP_CDR_CTRL_BYTE_OFFS 98 | 82 | #define QSFP_CDR_CTRL_BYTE_OFFS 98 |
diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c index 0ecf27903dc2..1694037d1eee 100644 --- a/drivers/infiniband/hw/hfi1/user_sdma.c +++ b/drivers/infiniband/hw/hfi1/user_sdma.c | |||
@@ -114,6 +114,8 @@ MODULE_PARM_DESC(sdma_comp_size, "Size of User SDMA completion ring. Default: 12 | |||
114 | #define KDETH_HCRC_LOWER_SHIFT 24 | 114 | #define KDETH_HCRC_LOWER_SHIFT 24 |
115 | #define KDETH_HCRC_LOWER_MASK 0xff | 115 | #define KDETH_HCRC_LOWER_MASK 0xff |
116 | 116 | ||
117 | #define AHG_KDETH_INTR_SHIFT 12 | ||
118 | |||
117 | #define PBC2LRH(x) ((((x) & 0xfff) << 2) - 4) | 119 | #define PBC2LRH(x) ((((x) & 0xfff) << 2) - 4) |
118 | #define LRH2PBC(x) ((((x) >> 2) + 1) & 0xfff) | 120 | #define LRH2PBC(x) ((((x) >> 2) + 1) & 0xfff) |
119 | 121 | ||
@@ -1480,7 +1482,8 @@ static int set_txreq_header_ahg(struct user_sdma_request *req, | |||
1480 | /* Clear KDETH.SH on last packet */ | 1482 | /* Clear KDETH.SH on last packet */ |
1481 | if (unlikely(tx->flags & TXREQ_FLAGS_REQ_LAST_PKT)) { | 1483 | if (unlikely(tx->flags & TXREQ_FLAGS_REQ_LAST_PKT)) { |
1482 | val |= cpu_to_le16(KDETH_GET(hdr->kdeth.ver_tid_offset, | 1484 | val |= cpu_to_le16(KDETH_GET(hdr->kdeth.ver_tid_offset, |
1483 | INTR) >> 16); | 1485 | INTR) << |
1486 | AHG_KDETH_INTR_SHIFT); | ||
1484 | val &= cpu_to_le16(~(1U << 13)); | 1487 | val &= cpu_to_le16(~(1U << 13)); |
1485 | AHG_HEADER_SET(req->ahg, diff, 7, 16, 14, val); | 1488 | AHG_HEADER_SET(req->ahg, diff, 7, 16, 14, val); |
1486 | } else { | 1489 | } else { |
diff --git a/drivers/infiniband/hw/i40iw/i40iw.h b/drivers/infiniband/hw/i40iw/i40iw.h index b738acdb9b02..8ec09e470f84 100644 --- a/drivers/infiniband/hw/i40iw/i40iw.h +++ b/drivers/infiniband/hw/i40iw/i40iw.h | |||
@@ -232,7 +232,7 @@ struct i40iw_device { | |||
232 | struct i40e_client *client; | 232 | struct i40e_client *client; |
233 | struct i40iw_hw hw; | 233 | struct i40iw_hw hw; |
234 | struct i40iw_cm_core cm_core; | 234 | struct i40iw_cm_core cm_core; |
235 | unsigned long *mem_resources; | 235 | u8 *mem_resources; |
236 | unsigned long *allocated_qps; | 236 | unsigned long *allocated_qps; |
237 | unsigned long *allocated_cqs; | 237 | unsigned long *allocated_cqs; |
238 | unsigned long *allocated_mrs; | 238 | unsigned long *allocated_mrs; |
@@ -435,8 +435,8 @@ static inline int i40iw_alloc_resource(struct i40iw_device *iwdev, | |||
435 | *next = resource_num + 1; | 435 | *next = resource_num + 1; |
436 | if (*next == max_resources) | 436 | if (*next == max_resources) |
437 | *next = 0; | 437 | *next = 0; |
438 | spin_unlock_irqrestore(&iwdev->resource_lock, flags); | ||
439 | *req_resource_num = resource_num; | 438 | *req_resource_num = resource_num; |
439 | spin_unlock_irqrestore(&iwdev->resource_lock, flags); | ||
440 | 440 | ||
441 | return 0; | 441 | return 0; |
442 | } | 442 | } |
diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.c b/drivers/infiniband/hw/i40iw/i40iw_cm.c index 5026dc79978a..7ca0638579c0 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_cm.c +++ b/drivers/infiniband/hw/i40iw/i40iw_cm.c | |||
@@ -535,8 +535,8 @@ static struct i40iw_puda_buf *i40iw_form_cm_frame(struct i40iw_cm_node *cm_node, | |||
535 | buf += hdr_len; | 535 | buf += hdr_len; |
536 | } | 536 | } |
537 | 537 | ||
538 | if (pd_len) | 538 | if (pdata && pdata->addr) |
539 | memcpy(buf, pdata->addr, pd_len); | 539 | memcpy(buf, pdata->addr, pdata->size); |
540 | 540 | ||
541 | atomic_set(&sqbuf->refcount, 1); | 541 | atomic_set(&sqbuf->refcount, 1); |
542 | 542 | ||
@@ -3347,26 +3347,6 @@ int i40iw_cm_disconn(struct i40iw_qp *iwqp) | |||
3347 | } | 3347 | } |
3348 | 3348 | ||
3349 | /** | 3349 | /** |
3350 | * i40iw_loopback_nop - Send a nop | ||
3351 | * @qp: associated hw qp | ||
3352 | */ | ||
3353 | static void i40iw_loopback_nop(struct i40iw_sc_qp *qp) | ||
3354 | { | ||
3355 | u64 *wqe; | ||
3356 | u64 header; | ||
3357 | |||
3358 | wqe = qp->qp_uk.sq_base->elem; | ||
3359 | set_64bit_val(wqe, 0, 0); | ||
3360 | set_64bit_val(wqe, 8, 0); | ||
3361 | set_64bit_val(wqe, 16, 0); | ||
3362 | |||
3363 | header = LS_64(I40IWQP_OP_NOP, I40IWQPSQ_OPCODE) | | ||
3364 | LS_64(0, I40IWQPSQ_SIGCOMPL) | | ||
3365 | LS_64(qp->qp_uk.swqe_polarity, I40IWQPSQ_VALID); | ||
3366 | set_64bit_val(wqe, 24, header); | ||
3367 | } | ||
3368 | |||
3369 | /** | ||
3370 | * i40iw_qp_disconnect - free qp and close cm | 3350 | * i40iw_qp_disconnect - free qp and close cm |
3371 | * @iwqp: associate qp for the connection | 3351 | * @iwqp: associate qp for the connection |
3372 | */ | 3352 | */ |
@@ -3638,7 +3618,7 @@ int i40iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
3638 | } else { | 3618 | } else { |
3639 | if (iwqp->page) | 3619 | if (iwqp->page) |
3640 | iwqp->sc_qp.qp_uk.sq_base = kmap(iwqp->page); | 3620 | iwqp->sc_qp.qp_uk.sq_base = kmap(iwqp->page); |
3641 | i40iw_loopback_nop(&iwqp->sc_qp); | 3621 | dev->iw_priv_qp_ops->qp_send_lsmm(&iwqp->sc_qp, NULL, 0, 0); |
3642 | } | 3622 | } |
3643 | 3623 | ||
3644 | if (iwqp->page) | 3624 | if (iwqp->page) |
diff --git a/drivers/infiniband/hw/i40iw/i40iw_hw.c b/drivers/infiniband/hw/i40iw/i40iw_hw.c index 3ee0cad96bc6..0c92a40b3e86 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_hw.c +++ b/drivers/infiniband/hw/i40iw/i40iw_hw.c | |||
@@ -265,6 +265,7 @@ void i40iw_next_iw_state(struct i40iw_qp *iwqp, | |||
265 | info.dont_send_fin = false; | 265 | info.dont_send_fin = false; |
266 | if (iwqp->sc_qp.term_flags && (state == I40IW_QP_STATE_ERROR)) | 266 | if (iwqp->sc_qp.term_flags && (state == I40IW_QP_STATE_ERROR)) |
267 | info.reset_tcp_conn = true; | 267 | info.reset_tcp_conn = true; |
268 | iwqp->hw_iwarp_state = state; | ||
268 | i40iw_hw_modify_qp(iwqp->iwdev, iwqp, &info, 0); | 269 | i40iw_hw_modify_qp(iwqp->iwdev, iwqp, &info, 0); |
269 | } | 270 | } |
270 | 271 | ||
diff --git a/drivers/infiniband/hw/i40iw/i40iw_main.c b/drivers/infiniband/hw/i40iw/i40iw_main.c index 6e9081380a27..445e230d5ff8 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_main.c +++ b/drivers/infiniband/hw/i40iw/i40iw_main.c | |||
@@ -100,7 +100,7 @@ static struct notifier_block i40iw_net_notifier = { | |||
100 | .notifier_call = i40iw_net_event | 100 | .notifier_call = i40iw_net_event |
101 | }; | 101 | }; |
102 | 102 | ||
103 | static int i40iw_notifiers_registered; | 103 | static atomic_t i40iw_notifiers_registered; |
104 | 104 | ||
105 | /** | 105 | /** |
106 | * i40iw_find_i40e_handler - find a handler given a client info | 106 | * i40iw_find_i40e_handler - find a handler given a client info |
@@ -1342,12 +1342,11 @@ exit: | |||
1342 | */ | 1342 | */ |
1343 | static void i40iw_register_notifiers(void) | 1343 | static void i40iw_register_notifiers(void) |
1344 | { | 1344 | { |
1345 | if (!i40iw_notifiers_registered) { | 1345 | if (atomic_inc_return(&i40iw_notifiers_registered) == 1) { |
1346 | register_inetaddr_notifier(&i40iw_inetaddr_notifier); | 1346 | register_inetaddr_notifier(&i40iw_inetaddr_notifier); |
1347 | register_inet6addr_notifier(&i40iw_inetaddr6_notifier); | 1347 | register_inet6addr_notifier(&i40iw_inetaddr6_notifier); |
1348 | register_netevent_notifier(&i40iw_net_notifier); | 1348 | register_netevent_notifier(&i40iw_net_notifier); |
1349 | } | 1349 | } |
1350 | i40iw_notifiers_registered++; | ||
1351 | } | 1350 | } |
1352 | 1351 | ||
1353 | /** | 1352 | /** |
@@ -1429,8 +1428,7 @@ static void i40iw_deinit_device(struct i40iw_device *iwdev, bool reset, bool del | |||
1429 | i40iw_del_macip_entry(iwdev, (u8)iwdev->mac_ip_table_idx); | 1428 | i40iw_del_macip_entry(iwdev, (u8)iwdev->mac_ip_table_idx); |
1430 | /* fallthrough */ | 1429 | /* fallthrough */ |
1431 | case INET_NOTIFIER: | 1430 | case INET_NOTIFIER: |
1432 | if (i40iw_notifiers_registered > 0) { | 1431 | if (!atomic_dec_return(&i40iw_notifiers_registered)) { |
1433 | i40iw_notifiers_registered--; | ||
1434 | unregister_netevent_notifier(&i40iw_net_notifier); | 1432 | unregister_netevent_notifier(&i40iw_net_notifier); |
1435 | unregister_inetaddr_notifier(&i40iw_inetaddr_notifier); | 1433 | unregister_inetaddr_notifier(&i40iw_inetaddr_notifier); |
1436 | unregister_inet6addr_notifier(&i40iw_inetaddr6_notifier); | 1434 | unregister_inet6addr_notifier(&i40iw_inetaddr6_notifier); |
@@ -1558,6 +1556,10 @@ static int i40iw_open(struct i40e_info *ldev, struct i40e_client *client) | |||
1558 | enum i40iw_status_code status; | 1556 | enum i40iw_status_code status; |
1559 | struct i40iw_handler *hdl; | 1557 | struct i40iw_handler *hdl; |
1560 | 1558 | ||
1559 | hdl = i40iw_find_netdev(ldev->netdev); | ||
1560 | if (hdl) | ||
1561 | return 0; | ||
1562 | |||
1561 | hdl = kzalloc(sizeof(*hdl), GFP_KERNEL); | 1563 | hdl = kzalloc(sizeof(*hdl), GFP_KERNEL); |
1562 | if (!hdl) | 1564 | if (!hdl) |
1563 | return -ENOMEM; | 1565 | return -ENOMEM; |
diff --git a/drivers/infiniband/hw/i40iw/i40iw_utils.c b/drivers/infiniband/hw/i40iw/i40iw_utils.c index 0e8db0a35141..6fd043b1d714 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_utils.c +++ b/drivers/infiniband/hw/i40iw/i40iw_utils.c | |||
@@ -673,8 +673,11 @@ enum i40iw_status_code i40iw_free_virt_mem(struct i40iw_hw *hw, | |||
673 | { | 673 | { |
674 | if (!mem) | 674 | if (!mem) |
675 | return I40IW_ERR_PARAM; | 675 | return I40IW_ERR_PARAM; |
676 | /* | ||
677 | * mem->va points to the parent of mem, so both mem and mem->va | ||
678 | * can not be touched once mem->va is freed | ||
679 | */ | ||
676 | kfree(mem->va); | 680 | kfree(mem->va); |
677 | mem->va = NULL; | ||
678 | return 0; | 681 | return 0; |
679 | } | 682 | } |
680 | 683 | ||
diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.c b/drivers/infiniband/hw/i40iw/i40iw_verbs.c index 2360338877bf..6329c971c22f 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_verbs.c +++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.c | |||
@@ -794,7 +794,6 @@ static struct ib_qp *i40iw_create_qp(struct ib_pd *ibpd, | |||
794 | return &iwqp->ibqp; | 794 | return &iwqp->ibqp; |
795 | error: | 795 | error: |
796 | i40iw_free_qp_resources(iwdev, iwqp, qp_num); | 796 | i40iw_free_qp_resources(iwdev, iwqp, qp_num); |
797 | kfree(mem); | ||
798 | return ERR_PTR(err_code); | 797 | return ERR_PTR(err_code); |
799 | } | 798 | } |
800 | 799 | ||
@@ -1926,8 +1925,7 @@ static int i40iw_dereg_mr(struct ib_mr *ib_mr) | |||
1926 | } | 1925 | } |
1927 | if (iwpbl->pbl_allocated) | 1926 | if (iwpbl->pbl_allocated) |
1928 | i40iw_free_pble(iwdev->pble_rsrc, palloc); | 1927 | i40iw_free_pble(iwdev->pble_rsrc, palloc); |
1929 | kfree(iwpbl->iwmr); | 1928 | kfree(iwmr); |
1930 | iwpbl->iwmr = NULL; | ||
1931 | return 0; | 1929 | return 0; |
1932 | } | 1930 | } |
1933 | 1931 | ||
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index d6fc8a6e8c33..5df63dacaaa3 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c | |||
@@ -576,8 +576,8 @@ static int mlx4_ib_ipoib_csum_ok(__be16 status, __be16 checksum) | |||
576 | checksum == cpu_to_be16(0xffff); | 576 | checksum == cpu_to_be16(0xffff); |
577 | } | 577 | } |
578 | 578 | ||
579 | static int use_tunnel_data(struct mlx4_ib_qp *qp, struct mlx4_ib_cq *cq, struct ib_wc *wc, | 579 | static void use_tunnel_data(struct mlx4_ib_qp *qp, struct mlx4_ib_cq *cq, struct ib_wc *wc, |
580 | unsigned tail, struct mlx4_cqe *cqe, int is_eth) | 580 | unsigned tail, struct mlx4_cqe *cqe, int is_eth) |
581 | { | 581 | { |
582 | struct mlx4_ib_proxy_sqp_hdr *hdr; | 582 | struct mlx4_ib_proxy_sqp_hdr *hdr; |
583 | 583 | ||
@@ -600,8 +600,6 @@ static int use_tunnel_data(struct mlx4_ib_qp *qp, struct mlx4_ib_cq *cq, struct | |||
600 | wc->slid = be16_to_cpu(hdr->tun.slid_mac_47_32); | 600 | wc->slid = be16_to_cpu(hdr->tun.slid_mac_47_32); |
601 | wc->sl = (u8) (be16_to_cpu(hdr->tun.sl_vid) >> 12); | 601 | wc->sl = (u8) (be16_to_cpu(hdr->tun.sl_vid) >> 12); |
602 | } | 602 | } |
603 | |||
604 | return 0; | ||
605 | } | 603 | } |
606 | 604 | ||
607 | static void mlx4_ib_qp_sw_comp(struct mlx4_ib_qp *qp, int num_entries, | 605 | static void mlx4_ib_qp_sw_comp(struct mlx4_ib_qp *qp, int num_entries, |
@@ -689,12 +687,6 @@ repoll: | |||
689 | is_error = (cqe->owner_sr_opcode & MLX4_CQE_OPCODE_MASK) == | 687 | is_error = (cqe->owner_sr_opcode & MLX4_CQE_OPCODE_MASK) == |
690 | MLX4_CQE_OPCODE_ERROR; | 688 | MLX4_CQE_OPCODE_ERROR; |
691 | 689 | ||
692 | if (unlikely((cqe->owner_sr_opcode & MLX4_CQE_OPCODE_MASK) == MLX4_OPCODE_NOP && | ||
693 | is_send)) { | ||
694 | pr_warn("Completion for NOP opcode detected!\n"); | ||
695 | return -EINVAL; | ||
696 | } | ||
697 | |||
698 | /* Resize CQ in progress */ | 690 | /* Resize CQ in progress */ |
699 | if (unlikely((cqe->owner_sr_opcode & MLX4_CQE_OPCODE_MASK) == MLX4_CQE_OPCODE_RESIZE)) { | 691 | if (unlikely((cqe->owner_sr_opcode & MLX4_CQE_OPCODE_MASK) == MLX4_CQE_OPCODE_RESIZE)) { |
700 | if (cq->resize_buf) { | 692 | if (cq->resize_buf) { |
@@ -720,12 +712,6 @@ repoll: | |||
720 | */ | 712 | */ |
721 | mqp = __mlx4_qp_lookup(to_mdev(cq->ibcq.device)->dev, | 713 | mqp = __mlx4_qp_lookup(to_mdev(cq->ibcq.device)->dev, |
722 | be32_to_cpu(cqe->vlan_my_qpn)); | 714 | be32_to_cpu(cqe->vlan_my_qpn)); |
723 | if (unlikely(!mqp)) { | ||
724 | pr_warn("CQ %06x with entry for unknown QPN %06x\n", | ||
725 | cq->mcq.cqn, be32_to_cpu(cqe->vlan_my_qpn) & MLX4_CQE_QPN_MASK); | ||
726 | return -EINVAL; | ||
727 | } | ||
728 | |||
729 | *cur_qp = to_mibqp(mqp); | 715 | *cur_qp = to_mibqp(mqp); |
730 | } | 716 | } |
731 | 717 | ||
@@ -738,11 +724,6 @@ repoll: | |||
738 | /* SRQ is also in the radix tree */ | 724 | /* SRQ is also in the radix tree */ |
739 | msrq = mlx4_srq_lookup(to_mdev(cq->ibcq.device)->dev, | 725 | msrq = mlx4_srq_lookup(to_mdev(cq->ibcq.device)->dev, |
740 | srq_num); | 726 | srq_num); |
741 | if (unlikely(!msrq)) { | ||
742 | pr_warn("CQ %06x with entry for unknown SRQN %06x\n", | ||
743 | cq->mcq.cqn, srq_num); | ||
744 | return -EINVAL; | ||
745 | } | ||
746 | } | 727 | } |
747 | 728 | ||
748 | if (is_send) { | 729 | if (is_send) { |
@@ -852,9 +833,11 @@ repoll: | |||
852 | if (mlx4_is_mfunc(to_mdev(cq->ibcq.device)->dev)) { | 833 | if (mlx4_is_mfunc(to_mdev(cq->ibcq.device)->dev)) { |
853 | if ((*cur_qp)->mlx4_ib_qp_type & | 834 | if ((*cur_qp)->mlx4_ib_qp_type & |
854 | (MLX4_IB_QPT_PROXY_SMI_OWNER | | 835 | (MLX4_IB_QPT_PROXY_SMI_OWNER | |
855 | MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI)) | 836 | MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI)) { |
856 | return use_tunnel_data(*cur_qp, cq, wc, tail, | 837 | use_tunnel_data(*cur_qp, cq, wc, tail, cqe, |
857 | cqe, is_eth); | 838 | is_eth); |
839 | return 0; | ||
840 | } | ||
858 | } | 841 | } |
859 | 842 | ||
860 | wc->slid = be16_to_cpu(cqe->rlid); | 843 | wc->slid = be16_to_cpu(cqe->rlid); |
@@ -891,7 +874,6 @@ int mlx4_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) | |||
891 | struct mlx4_ib_qp *cur_qp = NULL; | 874 | struct mlx4_ib_qp *cur_qp = NULL; |
892 | unsigned long flags; | 875 | unsigned long flags; |
893 | int npolled; | 876 | int npolled; |
894 | int err = 0; | ||
895 | struct mlx4_ib_dev *mdev = to_mdev(cq->ibcq.device); | 877 | struct mlx4_ib_dev *mdev = to_mdev(cq->ibcq.device); |
896 | 878 | ||
897 | spin_lock_irqsave(&cq->lock, flags); | 879 | spin_lock_irqsave(&cq->lock, flags); |
@@ -901,8 +883,7 @@ int mlx4_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) | |||
901 | } | 883 | } |
902 | 884 | ||
903 | for (npolled = 0; npolled < num_entries; ++npolled) { | 885 | for (npolled = 0; npolled < num_entries; ++npolled) { |
904 | err = mlx4_ib_poll_one(cq, &cur_qp, wc + npolled); | 886 | if (mlx4_ib_poll_one(cq, &cur_qp, wc + npolled)) |
905 | if (err) | ||
906 | break; | 887 | break; |
907 | } | 888 | } |
908 | 889 | ||
@@ -911,10 +892,7 @@ int mlx4_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) | |||
911 | out: | 892 | out: |
912 | spin_unlock_irqrestore(&cq->lock, flags); | 893 | spin_unlock_irqrestore(&cq->lock, flags); |
913 | 894 | ||
914 | if (err == 0 || err == -EAGAIN) | 895 | return npolled; |
915 | return npolled; | ||
916 | else | ||
917 | return err; | ||
918 | } | 896 | } |
919 | 897 | ||
920 | int mlx4_ib_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags) | 898 | int mlx4_ib_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags) |
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 9c2e53d28f98..0f21c3a25552 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
@@ -1128,6 +1128,27 @@ void handle_port_mgmt_change_event(struct work_struct *work) | |||
1128 | 1128 | ||
1129 | /* Generate GUID changed event */ | 1129 | /* Generate GUID changed event */ |
1130 | if (changed_attr & MLX4_EQ_PORT_INFO_GID_PFX_CHANGE_MASK) { | 1130 | if (changed_attr & MLX4_EQ_PORT_INFO_GID_PFX_CHANGE_MASK) { |
1131 | if (mlx4_is_master(dev->dev)) { | ||
1132 | union ib_gid gid; | ||
1133 | int err = 0; | ||
1134 | |||
1135 | if (!eqe->event.port_mgmt_change.params.port_info.gid_prefix) | ||
1136 | err = __mlx4_ib_query_gid(&dev->ib_dev, port, 0, &gid, 1); | ||
1137 | else | ||
1138 | gid.global.subnet_prefix = | ||
1139 | eqe->event.port_mgmt_change.params.port_info.gid_prefix; | ||
1140 | if (err) { | ||
1141 | pr_warn("Could not change QP1 subnet prefix for port %d: query_gid error (%d)\n", | ||
1142 | port, err); | ||
1143 | } else { | ||
1144 | pr_debug("Changing QP1 subnet prefix for port %d. old=0x%llx. new=0x%llx\n", | ||
1145 | port, | ||
1146 | (u64)atomic64_read(&dev->sriov.demux[port - 1].subnet_prefix), | ||
1147 | be64_to_cpu(gid.global.subnet_prefix)); | ||
1148 | atomic64_set(&dev->sriov.demux[port - 1].subnet_prefix, | ||
1149 | be64_to_cpu(gid.global.subnet_prefix)); | ||
1150 | } | ||
1151 | } | ||
1131 | mlx4_ib_dispatch_event(dev, port, IB_EVENT_GID_CHANGE); | 1152 | mlx4_ib_dispatch_event(dev, port, IB_EVENT_GID_CHANGE); |
1132 | /*if master, notify all slaves*/ | 1153 | /*if master, notify all slaves*/ |
1133 | if (mlx4_is_master(dev->dev)) | 1154 | if (mlx4_is_master(dev->dev)) |
@@ -2202,6 +2223,8 @@ int mlx4_ib_init_sriov(struct mlx4_ib_dev *dev) | |||
2202 | if (err) | 2223 | if (err) |
2203 | goto demux_err; | 2224 | goto demux_err; |
2204 | dev->sriov.demux[i].guid_cache[0] = gid.global.interface_id; | 2225 | dev->sriov.demux[i].guid_cache[0] = gid.global.interface_id; |
2226 | atomic64_set(&dev->sriov.demux[i].subnet_prefix, | ||
2227 | be64_to_cpu(gid.global.subnet_prefix)); | ||
2205 | err = alloc_pv_object(dev, mlx4_master_func_num(dev->dev), i + 1, | 2228 | err = alloc_pv_object(dev, mlx4_master_func_num(dev->dev), i + 1, |
2206 | &dev->sriov.sqps[i]); | 2229 | &dev->sriov.sqps[i]); |
2207 | if (err) | 2230 | if (err) |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 2af44c2de262..87ba9bca4181 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -2202,6 +2202,9 @@ static int mlx4_ib_alloc_diag_counters(struct mlx4_ib_dev *ibdev) | |||
2202 | bool per_port = !!(ibdev->dev->caps.flags2 & | 2202 | bool per_port = !!(ibdev->dev->caps.flags2 & |
2203 | MLX4_DEV_CAP_FLAG2_DIAG_PER_PORT); | 2203 | MLX4_DEV_CAP_FLAG2_DIAG_PER_PORT); |
2204 | 2204 | ||
2205 | if (mlx4_is_slave(ibdev->dev)) | ||
2206 | return 0; | ||
2207 | |||
2205 | for (i = 0; i < MLX4_DIAG_COUNTERS_TYPES; i++) { | 2208 | for (i = 0; i < MLX4_DIAG_COUNTERS_TYPES; i++) { |
2206 | /* i == 1 means we are building port counters */ | 2209 | /* i == 1 means we are building port counters */ |
2207 | if (i && !per_port) | 2210 | if (i && !per_port) |
diff --git a/drivers/infiniband/hw/mlx4/mcg.c b/drivers/infiniband/hw/mlx4/mcg.c index 8f7ad07915b0..097bfcc4ee99 100644 --- a/drivers/infiniband/hw/mlx4/mcg.c +++ b/drivers/infiniband/hw/mlx4/mcg.c | |||
@@ -489,7 +489,7 @@ static u8 get_leave_state(struct mcast_group *group) | |||
489 | if (!group->members[i]) | 489 | if (!group->members[i]) |
490 | leave_state |= (1 << i); | 490 | leave_state |= (1 << i); |
491 | 491 | ||
492 | return leave_state & (group->rec.scope_join_state & 7); | 492 | return leave_state & (group->rec.scope_join_state & 0xf); |
493 | } | 493 | } |
494 | 494 | ||
495 | static int join_group(struct mcast_group *group, int slave, u8 join_mask) | 495 | static int join_group(struct mcast_group *group, int slave, u8 join_mask) |
@@ -564,8 +564,8 @@ static void mlx4_ib_mcg_timeout_handler(struct work_struct *work) | |||
564 | } else | 564 | } else |
565 | mcg_warn_group(group, "DRIVER BUG\n"); | 565 | mcg_warn_group(group, "DRIVER BUG\n"); |
566 | } else if (group->state == MCAST_LEAVE_SENT) { | 566 | } else if (group->state == MCAST_LEAVE_SENT) { |
567 | if (group->rec.scope_join_state & 7) | 567 | if (group->rec.scope_join_state & 0xf) |
568 | group->rec.scope_join_state &= 0xf8; | 568 | group->rec.scope_join_state &= 0xf0; |
569 | group->state = MCAST_IDLE; | 569 | group->state = MCAST_IDLE; |
570 | mutex_unlock(&group->lock); | 570 | mutex_unlock(&group->lock); |
571 | if (release_group(group, 1)) | 571 | if (release_group(group, 1)) |
@@ -605,7 +605,7 @@ static int handle_leave_req(struct mcast_group *group, u8 leave_mask, | |||
605 | static int handle_join_req(struct mcast_group *group, u8 join_mask, | 605 | static int handle_join_req(struct mcast_group *group, u8 join_mask, |
606 | struct mcast_req *req) | 606 | struct mcast_req *req) |
607 | { | 607 | { |
608 | u8 group_join_state = group->rec.scope_join_state & 7; | 608 | u8 group_join_state = group->rec.scope_join_state & 0xf; |
609 | int ref = 0; | 609 | int ref = 0; |
610 | u16 status; | 610 | u16 status; |
611 | struct ib_sa_mcmember_data *sa_data = (struct ib_sa_mcmember_data *)req->sa_mad.data; | 611 | struct ib_sa_mcmember_data *sa_data = (struct ib_sa_mcmember_data *)req->sa_mad.data; |
@@ -690,8 +690,8 @@ static void mlx4_ib_mcg_work_handler(struct work_struct *work) | |||
690 | u8 cur_join_state; | 690 | u8 cur_join_state; |
691 | 691 | ||
692 | resp_join_state = ((struct ib_sa_mcmember_data *) | 692 | resp_join_state = ((struct ib_sa_mcmember_data *) |
693 | group->response_sa_mad.data)->scope_join_state & 7; | 693 | group->response_sa_mad.data)->scope_join_state & 0xf; |
694 | cur_join_state = group->rec.scope_join_state & 7; | 694 | cur_join_state = group->rec.scope_join_state & 0xf; |
695 | 695 | ||
696 | if (method == IB_MGMT_METHOD_GET_RESP) { | 696 | if (method == IB_MGMT_METHOD_GET_RESP) { |
697 | /* successfull join */ | 697 | /* successfull join */ |
@@ -710,7 +710,7 @@ process_requests: | |||
710 | req = list_first_entry(&group->pending_list, struct mcast_req, | 710 | req = list_first_entry(&group->pending_list, struct mcast_req, |
711 | group_list); | 711 | group_list); |
712 | sa_data = (struct ib_sa_mcmember_data *)req->sa_mad.data; | 712 | sa_data = (struct ib_sa_mcmember_data *)req->sa_mad.data; |
713 | req_join_state = sa_data->scope_join_state & 0x7; | 713 | req_join_state = sa_data->scope_join_state & 0xf; |
714 | 714 | ||
715 | /* For a leave request, we will immediately answer the VF, and | 715 | /* For a leave request, we will immediately answer the VF, and |
716 | * update our internal counters. The actual leave will be sent | 716 | * update our internal counters. The actual leave will be sent |
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h index 7c5832ede4bd..686ab48ff644 100644 --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h | |||
@@ -448,7 +448,7 @@ struct mlx4_ib_demux_ctx { | |||
448 | struct workqueue_struct *wq; | 448 | struct workqueue_struct *wq; |
449 | struct workqueue_struct *ud_wq; | 449 | struct workqueue_struct *ud_wq; |
450 | spinlock_t ud_lock; | 450 | spinlock_t ud_lock; |
451 | __be64 subnet_prefix; | 451 | atomic64_t subnet_prefix; |
452 | __be64 guid_cache[128]; | 452 | __be64 guid_cache[128]; |
453 | struct mlx4_ib_dev *dev; | 453 | struct mlx4_ib_dev *dev; |
454 | /* the following lock protects both mcg_table and mcg_mgid0_list */ | 454 | /* the following lock protects both mcg_table and mcg_mgid0_list */ |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 768085f59566..7fb9629bd12b 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
@@ -2493,24 +2493,27 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_ud_wr *wr, | |||
2493 | sqp->ud_header.grh.flow_label = | 2493 | sqp->ud_header.grh.flow_label = |
2494 | ah->av.ib.sl_tclass_flowlabel & cpu_to_be32(0xfffff); | 2494 | ah->av.ib.sl_tclass_flowlabel & cpu_to_be32(0xfffff); |
2495 | sqp->ud_header.grh.hop_limit = ah->av.ib.hop_limit; | 2495 | sqp->ud_header.grh.hop_limit = ah->av.ib.hop_limit; |
2496 | if (is_eth) | 2496 | if (is_eth) { |
2497 | memcpy(sqp->ud_header.grh.source_gid.raw, sgid.raw, 16); | 2497 | memcpy(sqp->ud_header.grh.source_gid.raw, sgid.raw, 16); |
2498 | else { | 2498 | } else { |
2499 | if (mlx4_is_mfunc(to_mdev(ib_dev)->dev)) { | 2499 | if (mlx4_is_mfunc(to_mdev(ib_dev)->dev)) { |
2500 | /* When multi-function is enabled, the ib_core gid | 2500 | /* When multi-function is enabled, the ib_core gid |
2501 | * indexes don't necessarily match the hw ones, so | 2501 | * indexes don't necessarily match the hw ones, so |
2502 | * we must use our own cache */ | 2502 | * we must use our own cache |
2503 | sqp->ud_header.grh.source_gid.global.subnet_prefix = | 2503 | */ |
2504 | to_mdev(ib_dev)->sriov.demux[sqp->qp.port - 1]. | 2504 | sqp->ud_header.grh.source_gid.global.subnet_prefix = |
2505 | subnet_prefix; | 2505 | cpu_to_be64(atomic64_read(&(to_mdev(ib_dev)->sriov. |
2506 | sqp->ud_header.grh.source_gid.global.interface_id = | 2506 | demux[sqp->qp.port - 1]. |
2507 | to_mdev(ib_dev)->sriov.demux[sqp->qp.port - 1]. | 2507 | subnet_prefix))); |
2508 | guid_cache[ah->av.ib.gid_index]; | 2508 | sqp->ud_header.grh.source_gid.global.interface_id = |
2509 | } else | 2509 | to_mdev(ib_dev)->sriov.demux[sqp->qp.port - 1]. |
2510 | ib_get_cached_gid(ib_dev, | 2510 | guid_cache[ah->av.ib.gid_index]; |
2511 | be32_to_cpu(ah->av.ib.port_pd) >> 24, | 2511 | } else { |
2512 | ah->av.ib.gid_index, | 2512 | ib_get_cached_gid(ib_dev, |
2513 | &sqp->ud_header.grh.source_gid, NULL); | 2513 | be32_to_cpu(ah->av.ib.port_pd) >> 24, |
2514 | ah->av.ib.gid_index, | ||
2515 | &sqp->ud_header.grh.source_gid, NULL); | ||
2516 | } | ||
2514 | } | 2517 | } |
2515 | memcpy(sqp->ud_header.grh.destination_gid.raw, | 2518 | memcpy(sqp->ud_header.grh.destination_gid.raw, |
2516 | ah->av.ib.dgid, 16); | 2519 | ah->av.ib.dgid, 16); |
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c index 308a358e5b46..e4fac9292e4a 100644 --- a/drivers/infiniband/hw/mlx5/cq.c +++ b/drivers/infiniband/hw/mlx5/cq.c | |||
@@ -553,12 +553,6 @@ repoll: | |||
553 | * from the table. | 553 | * from the table. |
554 | */ | 554 | */ |
555 | mqp = __mlx5_qp_lookup(dev->mdev, qpn); | 555 | mqp = __mlx5_qp_lookup(dev->mdev, qpn); |
556 | if (unlikely(!mqp)) { | ||
557 | mlx5_ib_warn(dev, "CQE@CQ %06x for unknown QPN %6x\n", | ||
558 | cq->mcq.cqn, qpn); | ||
559 | return -EINVAL; | ||
560 | } | ||
561 | |||
562 | *cur_qp = to_mibqp(mqp); | 556 | *cur_qp = to_mibqp(mqp); |
563 | } | 557 | } |
564 | 558 | ||
@@ -619,13 +613,6 @@ repoll: | |||
619 | read_lock(&dev->mdev->priv.mkey_table.lock); | 613 | read_lock(&dev->mdev->priv.mkey_table.lock); |
620 | mmkey = __mlx5_mr_lookup(dev->mdev, | 614 | mmkey = __mlx5_mr_lookup(dev->mdev, |
621 | mlx5_base_mkey(be32_to_cpu(sig_err_cqe->mkey))); | 615 | mlx5_base_mkey(be32_to_cpu(sig_err_cqe->mkey))); |
622 | if (unlikely(!mmkey)) { | ||
623 | read_unlock(&dev->mdev->priv.mkey_table.lock); | ||
624 | mlx5_ib_warn(dev, "CQE@CQ %06x for unknown MR %6x\n", | ||
625 | cq->mcq.cqn, be32_to_cpu(sig_err_cqe->mkey)); | ||
626 | return -EINVAL; | ||
627 | } | ||
628 | |||
629 | mr = to_mibmr(mmkey); | 616 | mr = to_mibmr(mmkey); |
630 | get_sig_err_item(sig_err_cqe, &mr->sig->err_item); | 617 | get_sig_err_item(sig_err_cqe, &mr->sig->err_item); |
631 | mr->sig->sig_err_exists = true; | 618 | mr->sig->sig_err_exists = true; |
@@ -676,7 +663,6 @@ int mlx5_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) | |||
676 | unsigned long flags; | 663 | unsigned long flags; |
677 | int soft_polled = 0; | 664 | int soft_polled = 0; |
678 | int npolled; | 665 | int npolled; |
679 | int err = 0; | ||
680 | 666 | ||
681 | spin_lock_irqsave(&cq->lock, flags); | 667 | spin_lock_irqsave(&cq->lock, flags); |
682 | if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) { | 668 | if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) { |
@@ -688,8 +674,7 @@ int mlx5_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) | |||
688 | soft_polled = poll_soft_wc(cq, num_entries, wc); | 674 | soft_polled = poll_soft_wc(cq, num_entries, wc); |
689 | 675 | ||
690 | for (npolled = 0; npolled < num_entries - soft_polled; npolled++) { | 676 | for (npolled = 0; npolled < num_entries - soft_polled; npolled++) { |
691 | err = mlx5_poll_one(cq, &cur_qp, wc + soft_polled + npolled); | 677 | if (mlx5_poll_one(cq, &cur_qp, wc + soft_polled + npolled)) |
692 | if (err) | ||
693 | break; | 678 | break; |
694 | } | 679 | } |
695 | 680 | ||
@@ -698,10 +683,7 @@ int mlx5_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) | |||
698 | out: | 683 | out: |
699 | spin_unlock_irqrestore(&cq->lock, flags); | 684 | spin_unlock_irqrestore(&cq->lock, flags); |
700 | 685 | ||
701 | if (err == 0 || err == -EAGAIN) | 686 | return soft_polled + npolled; |
702 | return soft_polled + npolled; | ||
703 | else | ||
704 | return err; | ||
705 | } | 687 | } |
706 | 688 | ||
707 | int mlx5_ib_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags) | 689 | int mlx5_ib_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags) |
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index a84bb766fc62..e19537cf44ab 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <linux/dma-mapping.h> | 38 | #include <linux/dma-mapping.h> |
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/io-mapping.h> | ||
41 | #if defined(CONFIG_X86) | 40 | #if defined(CONFIG_X86) |
42 | #include <asm/pat.h> | 41 | #include <asm/pat.h> |
43 | #endif | 42 | #endif |
@@ -289,7 +288,9 @@ __be16 mlx5_get_roce_udp_sport(struct mlx5_ib_dev *dev, u8 port_num, | |||
289 | 288 | ||
290 | static int mlx5_use_mad_ifc(struct mlx5_ib_dev *dev) | 289 | static int mlx5_use_mad_ifc(struct mlx5_ib_dev *dev) |
291 | { | 290 | { |
292 | return !MLX5_CAP_GEN(dev->mdev, ib_virt); | 291 | if (MLX5_CAP_GEN(dev->mdev, port_type) == MLX5_CAP_PORT_TYPE_IB) |
292 | return !MLX5_CAP_GEN(dev->mdev, ib_virt); | ||
293 | return 0; | ||
293 | } | 294 | } |
294 | 295 | ||
295 | enum { | 296 | enum { |
@@ -1429,6 +1430,13 @@ static int parse_flow_attr(u32 *match_c, u32 *match_v, | |||
1429 | dmac_47_16), | 1430 | dmac_47_16), |
1430 | ib_spec->eth.val.dst_mac); | 1431 | ib_spec->eth.val.dst_mac); |
1431 | 1432 | ||
1433 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c, | ||
1434 | smac_47_16), | ||
1435 | ib_spec->eth.mask.src_mac); | ||
1436 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v, | ||
1437 | smac_47_16), | ||
1438 | ib_spec->eth.val.src_mac); | ||
1439 | |||
1432 | if (ib_spec->eth.mask.vlan_tag) { | 1440 | if (ib_spec->eth.mask.vlan_tag) { |
1433 | MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, | 1441 | MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, |
1434 | vlan_tag, 1); | 1442 | vlan_tag, 1); |
@@ -1850,6 +1858,7 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp, | |||
1850 | int domain) | 1858 | int domain) |
1851 | { | 1859 | { |
1852 | struct mlx5_ib_dev *dev = to_mdev(qp->device); | 1860 | struct mlx5_ib_dev *dev = to_mdev(qp->device); |
1861 | struct mlx5_ib_qp *mqp = to_mqp(qp); | ||
1853 | struct mlx5_ib_flow_handler *handler = NULL; | 1862 | struct mlx5_ib_flow_handler *handler = NULL; |
1854 | struct mlx5_flow_destination *dst = NULL; | 1863 | struct mlx5_flow_destination *dst = NULL; |
1855 | struct mlx5_ib_flow_prio *ft_prio; | 1864 | struct mlx5_ib_flow_prio *ft_prio; |
@@ -1876,7 +1885,10 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp, | |||
1876 | } | 1885 | } |
1877 | 1886 | ||
1878 | dst->type = MLX5_FLOW_DESTINATION_TYPE_TIR; | 1887 | dst->type = MLX5_FLOW_DESTINATION_TYPE_TIR; |
1879 | dst->tir_num = to_mqp(qp)->raw_packet_qp.rq.tirn; | 1888 | if (mqp->flags & MLX5_IB_QP_RSS) |
1889 | dst->tir_num = mqp->rss_qp.tirn; | ||
1890 | else | ||
1891 | dst->tir_num = mqp->raw_packet_qp.rq.tirn; | ||
1880 | 1892 | ||
1881 | if (flow_attr->type == IB_FLOW_ATTR_NORMAL) { | 1893 | if (flow_attr->type == IB_FLOW_ATTR_NORMAL) { |
1882 | if (flow_attr->flags & IB_FLOW_ATTR_FLAGS_DONT_TRAP) { | 1894 | if (flow_attr->flags & IB_FLOW_ATTR_FLAGS_DONT_TRAP) { |
diff --git a/drivers/infiniband/hw/mlx5/mem.c b/drivers/infiniband/hw/mlx5/mem.c index 40df2cca0609..996b54e366b0 100644 --- a/drivers/infiniband/hw/mlx5/mem.c +++ b/drivers/infiniband/hw/mlx5/mem.c | |||
@@ -71,7 +71,7 @@ void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift, | |||
71 | 71 | ||
72 | addr = addr >> page_shift; | 72 | addr = addr >> page_shift; |
73 | tmp = (unsigned long)addr; | 73 | tmp = (unsigned long)addr; |
74 | m = find_first_bit(&tmp, sizeof(tmp)); | 74 | m = find_first_bit(&tmp, BITS_PER_LONG); |
75 | skip = 1 << m; | 75 | skip = 1 << m; |
76 | mask = skip - 1; | 76 | mask = skip - 1; |
77 | i = 0; | 77 | i = 0; |
@@ -81,7 +81,7 @@ void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift, | |||
81 | for (k = 0; k < len; k++) { | 81 | for (k = 0; k < len; k++) { |
82 | if (!(i & mask)) { | 82 | if (!(i & mask)) { |
83 | tmp = (unsigned long)pfn; | 83 | tmp = (unsigned long)pfn; |
84 | m = min_t(unsigned long, m, find_first_bit(&tmp, sizeof(tmp))); | 84 | m = min_t(unsigned long, m, find_first_bit(&tmp, BITS_PER_LONG)); |
85 | skip = 1 << m; | 85 | skip = 1 << m; |
86 | mask = skip - 1; | 86 | mask = skip - 1; |
87 | base = pfn; | 87 | base = pfn; |
@@ -89,7 +89,7 @@ void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift, | |||
89 | } else { | 89 | } else { |
90 | if (base + p != pfn) { | 90 | if (base + p != pfn) { |
91 | tmp = (unsigned long)p; | 91 | tmp = (unsigned long)p; |
92 | m = find_first_bit(&tmp, sizeof(tmp)); | 92 | m = find_first_bit(&tmp, BITS_PER_LONG); |
93 | skip = 1 << m; | 93 | skip = 1 << m; |
94 | mask = skip - 1; | 94 | mask = skip - 1; |
95 | base = pfn; | 95 | base = pfn; |
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h index 372385d0f993..95146f4aa3e3 100644 --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h | |||
@@ -402,6 +402,7 @@ enum mlx5_ib_qp_flags { | |||
402 | /* QP uses 1 as its source QP number */ | 402 | /* QP uses 1 as its source QP number */ |
403 | MLX5_IB_QP_SQPN_QP1 = 1 << 6, | 403 | MLX5_IB_QP_SQPN_QP1 = 1 << 6, |
404 | MLX5_IB_QP_CAP_SCATTER_FCS = 1 << 7, | 404 | MLX5_IB_QP_CAP_SCATTER_FCS = 1 << 7, |
405 | MLX5_IB_QP_RSS = 1 << 8, | ||
405 | }; | 406 | }; |
406 | 407 | ||
407 | struct mlx5_umr_wr { | 408 | struct mlx5_umr_wr { |
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 0dd7d93cac95..affc3f6598ca 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c | |||
@@ -1449,6 +1449,7 @@ create_tir: | |||
1449 | kvfree(in); | 1449 | kvfree(in); |
1450 | /* qpn is reserved for that QP */ | 1450 | /* qpn is reserved for that QP */ |
1451 | qp->trans_qp.base.mqp.qpn = 0; | 1451 | qp->trans_qp.base.mqp.qpn = 0; |
1452 | qp->flags |= MLX5_IB_QP_RSS; | ||
1452 | return 0; | 1453 | return 0; |
1453 | 1454 | ||
1454 | err: | 1455 | err: |
@@ -3658,12 +3659,8 @@ static int begin_wqe(struct mlx5_ib_qp *qp, void **seg, | |||
3658 | struct ib_send_wr *wr, unsigned *idx, | 3659 | struct ib_send_wr *wr, unsigned *idx, |
3659 | int *size, int nreq) | 3660 | int *size, int nreq) |
3660 | { | 3661 | { |
3661 | int err = 0; | 3662 | if (unlikely(mlx5_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq))) |
3662 | 3663 | return -ENOMEM; | |
3663 | if (unlikely(mlx5_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq))) { | ||
3664 | err = -ENOMEM; | ||
3665 | return err; | ||
3666 | } | ||
3667 | 3664 | ||
3668 | *idx = qp->sq.cur_post & (qp->sq.wqe_cnt - 1); | 3665 | *idx = qp->sq.cur_post & (qp->sq.wqe_cnt - 1); |
3669 | *seg = mlx5_get_send_wqe(qp, *idx); | 3666 | *seg = mlx5_get_send_wqe(qp, *idx); |
@@ -3679,7 +3676,7 @@ static int begin_wqe(struct mlx5_ib_qp *qp, void **seg, | |||
3679 | *seg += sizeof(**ctrl); | 3676 | *seg += sizeof(**ctrl); |
3680 | *size = sizeof(**ctrl) / 16; | 3677 | *size = sizeof(**ctrl) / 16; |
3681 | 3678 | ||
3682 | return err; | 3679 | return 0; |
3683 | } | 3680 | } |
3684 | 3681 | ||
3685 | static void finish_wqe(struct mlx5_ib_qp *qp, | 3682 | static void finish_wqe(struct mlx5_ib_qp *qp, |
@@ -3758,7 +3755,7 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
3758 | num_sge = wr->num_sge; | 3755 | num_sge = wr->num_sge; |
3759 | if (unlikely(num_sge > qp->sq.max_gs)) { | 3756 | if (unlikely(num_sge > qp->sq.max_gs)) { |
3760 | mlx5_ib_warn(dev, "\n"); | 3757 | mlx5_ib_warn(dev, "\n"); |
3761 | err = -ENOMEM; | 3758 | err = -EINVAL; |
3762 | *bad_wr = wr; | 3759 | *bad_wr = wr; |
3763 | goto out; | 3760 | goto out; |
3764 | } | 3761 | } |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c index 16740dcb876b..67fc0b6857e1 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c | |||
@@ -1156,18 +1156,18 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, | |||
1156 | attr->max_srq = | 1156 | attr->max_srq = |
1157 | (rsp->max_srq_rpir_qps & OCRDMA_MBX_QUERY_CFG_MAX_SRQ_MASK) >> | 1157 | (rsp->max_srq_rpir_qps & OCRDMA_MBX_QUERY_CFG_MAX_SRQ_MASK) >> |
1158 | OCRDMA_MBX_QUERY_CFG_MAX_SRQ_OFFSET; | 1158 | OCRDMA_MBX_QUERY_CFG_MAX_SRQ_OFFSET; |
1159 | attr->max_send_sge = ((rsp->max_write_send_sge & | 1159 | attr->max_send_sge = ((rsp->max_recv_send_sge & |
1160 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >> | 1160 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >> |
1161 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT); | 1161 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT); |
1162 | attr->max_recv_sge = (rsp->max_write_send_sge & | 1162 | attr->max_recv_sge = (rsp->max_recv_send_sge & |
1163 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >> | 1163 | OCRDMA_MBX_QUERY_CFG_MAX_RECV_SGE_MASK) >> |
1164 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT; | 1164 | OCRDMA_MBX_QUERY_CFG_MAX_RECV_SGE_SHIFT; |
1165 | attr->max_srq_sge = (rsp->max_srq_rqe_sge & | 1165 | attr->max_srq_sge = (rsp->max_srq_rqe_sge & |
1166 | OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_MASK) >> | 1166 | OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_MASK) >> |
1167 | OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET; | 1167 | OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET; |
1168 | attr->max_rdma_sge = (rsp->max_write_send_sge & | 1168 | attr->max_rdma_sge = (rsp->max_wr_rd_sge & |
1169 | OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_MASK) >> | 1169 | OCRDMA_MBX_QUERY_CFG_MAX_RD_SGE_MASK) >> |
1170 | OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT; | 1170 | OCRDMA_MBX_QUERY_CFG_MAX_RD_SGE_SHIFT; |
1171 | attr->max_ord_per_qp = (rsp->max_ird_ord_per_qp & | 1171 | attr->max_ord_per_qp = (rsp->max_ird_ord_per_qp & |
1172 | OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK) >> | 1172 | OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK) >> |
1173 | OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT; | 1173 | OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT; |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h index 0efc9662c6d8..37df4481bb8f 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h | |||
@@ -554,9 +554,9 @@ enum { | |||
554 | OCRDMA_MBX_QUERY_CFG_L3_TYPE_MASK = 0x18, | 554 | OCRDMA_MBX_QUERY_CFG_L3_TYPE_MASK = 0x18, |
555 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT = 0, | 555 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT = 0, |
556 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK = 0xFFFF, | 556 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK = 0xFFFF, |
557 | OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT = 16, | 557 | OCRDMA_MBX_QUERY_CFG_MAX_RECV_SGE_SHIFT = 16, |
558 | OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_MASK = 0xFFFF << | 558 | OCRDMA_MBX_QUERY_CFG_MAX_RECV_SGE_MASK = 0xFFFF << |
559 | OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT, | 559 | OCRDMA_MBX_QUERY_CFG_MAX_RECV_SGE_SHIFT, |
560 | 560 | ||
561 | OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT = 0, | 561 | OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT = 0, |
562 | OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK = 0xFFFF, | 562 | OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK = 0xFFFF, |
@@ -612,6 +612,8 @@ enum { | |||
612 | OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET = 0, | 612 | OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET = 0, |
613 | OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_MASK = 0xFFFF << | 613 | OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_MASK = 0xFFFF << |
614 | OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET, | 614 | OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET, |
615 | OCRDMA_MBX_QUERY_CFG_MAX_RD_SGE_SHIFT = 0, | ||
616 | OCRDMA_MBX_QUERY_CFG_MAX_RD_SGE_MASK = 0xFFFF, | ||
615 | }; | 617 | }; |
616 | 618 | ||
617 | struct ocrdma_mbx_query_config { | 619 | struct ocrdma_mbx_query_config { |
@@ -619,7 +621,7 @@ struct ocrdma_mbx_query_config { | |||
619 | struct ocrdma_mbx_rsp rsp; | 621 | struct ocrdma_mbx_rsp rsp; |
620 | u32 qp_srq_cq_ird_ord; | 622 | u32 qp_srq_cq_ird_ord; |
621 | u32 max_pd_ca_ack_delay; | 623 | u32 max_pd_ca_ack_delay; |
622 | u32 max_write_send_sge; | 624 | u32 max_recv_send_sge; |
623 | u32 max_ird_ord_per_qp; | 625 | u32 max_ird_ord_per_qp; |
624 | u32 max_shared_ird_ord; | 626 | u32 max_shared_ird_ord; |
625 | u32 max_mr; | 627 | u32 max_mr; |
@@ -639,6 +641,8 @@ struct ocrdma_mbx_query_config { | |||
639 | u32 max_wqes_rqes_per_q; | 641 | u32 max_wqes_rqes_per_q; |
640 | u32 max_cq_cqes_per_cq; | 642 | u32 max_cq_cqes_per_cq; |
641 | u32 max_srq_rqe_sge; | 643 | u32 max_srq_rqe_sge; |
644 | u32 max_wr_rd_sge; | ||
645 | u32 ird_pgsz_num_pages; | ||
642 | }; | 646 | }; |
643 | 647 | ||
644 | struct ocrdma_fw_ver_rsp { | 648 | struct ocrdma_fw_ver_rsp { |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index b1a3d91fe8b9..0aa854737e74 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | |||
@@ -125,8 +125,8 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr, | |||
125 | IB_DEVICE_SYS_IMAGE_GUID | | 125 | IB_DEVICE_SYS_IMAGE_GUID | |
126 | IB_DEVICE_LOCAL_DMA_LKEY | | 126 | IB_DEVICE_LOCAL_DMA_LKEY | |
127 | IB_DEVICE_MEM_MGT_EXTENSIONS; | 127 | IB_DEVICE_MEM_MGT_EXTENSIONS; |
128 | attr->max_sge = dev->attr.max_send_sge; | 128 | attr->max_sge = min(dev->attr.max_send_sge, dev->attr.max_recv_sge); |
129 | attr->max_sge_rd = attr->max_sge; | 129 | attr->max_sge_rd = dev->attr.max_rdma_sge; |
130 | attr->max_cq = dev->attr.max_cq; | 130 | attr->max_cq = dev->attr.max_cq; |
131 | attr->max_cqe = dev->attr.max_cqe; | 131 | attr->max_cqe = dev->attr.max_cqe; |
132 | attr->max_mr = dev->attr.max_mr; | 132 | attr->max_mr = dev->attr.max_mr; |
diff --git a/drivers/infiniband/hw/qib/qib_debugfs.c b/drivers/infiniband/hw/qib/qib_debugfs.c index 5e75b43c596b..5bad8e3b40bb 100644 --- a/drivers/infiniband/hw/qib/qib_debugfs.c +++ b/drivers/infiniband/hw/qib/qib_debugfs.c | |||
@@ -189,27 +189,32 @@ static int _ctx_stats_seq_show(struct seq_file *s, void *v) | |||
189 | DEBUGFS_FILE(ctx_stats) | 189 | DEBUGFS_FILE(ctx_stats) |
190 | 190 | ||
191 | static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos) | 191 | static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos) |
192 | __acquires(RCU) | ||
192 | { | 193 | { |
193 | struct qib_qp_iter *iter; | 194 | struct qib_qp_iter *iter; |
194 | loff_t n = *pos; | 195 | loff_t n = *pos; |
195 | 196 | ||
196 | rcu_read_lock(); | ||
197 | iter = qib_qp_iter_init(s->private); | 197 | iter = qib_qp_iter_init(s->private); |
198 | |||
199 | /* stop calls rcu_read_unlock */ | ||
200 | rcu_read_lock(); | ||
201 | |||
198 | if (!iter) | 202 | if (!iter) |
199 | return NULL; | 203 | return NULL; |
200 | 204 | ||
201 | while (n--) { | 205 | do { |
202 | if (qib_qp_iter_next(iter)) { | 206 | if (qib_qp_iter_next(iter)) { |
203 | kfree(iter); | 207 | kfree(iter); |
204 | return NULL; | 208 | return NULL; |
205 | } | 209 | } |
206 | } | 210 | } while (n--); |
207 | 211 | ||
208 | return iter; | 212 | return iter; |
209 | } | 213 | } |
210 | 214 | ||
211 | static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr, | 215 | static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr, |
212 | loff_t *pos) | 216 | loff_t *pos) |
217 | __must_hold(RCU) | ||
213 | { | 218 | { |
214 | struct qib_qp_iter *iter = iter_ptr; | 219 | struct qib_qp_iter *iter = iter_ptr; |
215 | 220 | ||
@@ -224,6 +229,7 @@ static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr, | |||
224 | } | 229 | } |
225 | 230 | ||
226 | static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr) | 231 | static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr) |
232 | __releases(RCU) | ||
227 | { | 233 | { |
228 | rcu_read_unlock(); | 234 | rcu_read_unlock(); |
229 | } | 235 | } |
diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c index fcdf37913a26..c3edc033f7c4 100644 --- a/drivers/infiniband/hw/qib/qib_fs.c +++ b/drivers/infiniband/hw/qib/qib_fs.c | |||
@@ -328,26 +328,12 @@ static ssize_t flash_write(struct file *file, const char __user *buf, | |||
328 | 328 | ||
329 | pos = *ppos; | 329 | pos = *ppos; |
330 | 330 | ||
331 | if (pos != 0) { | 331 | if (pos != 0 || count != sizeof(struct qib_flash)) |
332 | ret = -EINVAL; | 332 | return -EINVAL; |
333 | goto bail; | ||
334 | } | ||
335 | |||
336 | if (count != sizeof(struct qib_flash)) { | ||
337 | ret = -EINVAL; | ||
338 | goto bail; | ||
339 | } | ||
340 | |||
341 | tmp = kmalloc(count, GFP_KERNEL); | ||
342 | if (!tmp) { | ||
343 | ret = -ENOMEM; | ||
344 | goto bail; | ||
345 | } | ||
346 | 333 | ||
347 | if (copy_from_user(tmp, buf, count)) { | 334 | tmp = memdup_user(buf, count); |
348 | ret = -EFAULT; | 335 | if (IS_ERR(tmp)) |
349 | goto bail_tmp; | 336 | return PTR_ERR(tmp); |
350 | } | ||
351 | 337 | ||
352 | dd = private2dd(file); | 338 | dd = private2dd(file); |
353 | if (qib_eeprom_write(dd, pos, tmp, count)) { | 339 | if (qib_eeprom_write(dd, pos, tmp, count)) { |
@@ -361,8 +347,6 @@ static ssize_t flash_write(struct file *file, const char __user *buf, | |||
361 | 347 | ||
362 | bail_tmp: | 348 | bail_tmp: |
363 | kfree(tmp); | 349 | kfree(tmp); |
364 | |||
365 | bail: | ||
366 | return ret; | 350 | return ret; |
367 | } | 351 | } |
368 | 352 | ||
diff --git a/drivers/infiniband/hw/qib/qib_qp.c b/drivers/infiniband/hw/qib/qib_qp.c index 9cc0aae1d781..f9b8cd2354d1 100644 --- a/drivers/infiniband/hw/qib/qib_qp.c +++ b/drivers/infiniband/hw/qib/qib_qp.c | |||
@@ -573,10 +573,6 @@ struct qib_qp_iter *qib_qp_iter_init(struct qib_ibdev *dev) | |||
573 | return NULL; | 573 | return NULL; |
574 | 574 | ||
575 | iter->dev = dev; | 575 | iter->dev = dev; |
576 | if (qib_qp_iter_next(iter)) { | ||
577 | kfree(iter); | ||
578 | return NULL; | ||
579 | } | ||
580 | 576 | ||
581 | return iter; | 577 | return iter; |
582 | } | 578 | } |
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_main.c b/drivers/infiniband/hw/usnic/usnic_ib_main.c index c229b9f4a52d..0a89a955550b 100644 --- a/drivers/infiniband/hw/usnic/usnic_ib_main.c +++ b/drivers/infiniband/hw/usnic/usnic_ib_main.c | |||
@@ -664,7 +664,8 @@ static int __init usnic_ib_init(void) | |||
664 | return err; | 664 | return err; |
665 | } | 665 | } |
666 | 666 | ||
667 | if (pci_register_driver(&usnic_ib_pci_driver)) { | 667 | err = pci_register_driver(&usnic_ib_pci_driver); |
668 | if (err) { | ||
668 | usnic_err("Unable to register with PCI\n"); | 669 | usnic_err("Unable to register with PCI\n"); |
669 | goto out_umem_fini; | 670 | goto out_umem_fini; |
670 | } | 671 | } |
diff --git a/drivers/infiniband/sw/rdmavt/mr.c b/drivers/infiniband/sw/rdmavt/mr.c index 80c4b6b401b8..46b64970058e 100644 --- a/drivers/infiniband/sw/rdmavt/mr.c +++ b/drivers/infiniband/sw/rdmavt/mr.c | |||
@@ -294,7 +294,7 @@ static void __rvt_free_mr(struct rvt_mr *mr) | |||
294 | { | 294 | { |
295 | rvt_deinit_mregion(&mr->mr); | 295 | rvt_deinit_mregion(&mr->mr); |
296 | rvt_free_lkey(&mr->mr); | 296 | rvt_free_lkey(&mr->mr); |
297 | vfree(mr); | 297 | kfree(mr); |
298 | } | 298 | } |
299 | 299 | ||
300 | /** | 300 | /** |
diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c index bdb540f25a88..870b4f212fbc 100644 --- a/drivers/infiniband/sw/rdmavt/qp.c +++ b/drivers/infiniband/sw/rdmavt/qp.c | |||
@@ -873,7 +873,8 @@ bail_qpn: | |||
873 | free_qpn(&rdi->qp_dev->qpn_table, qp->ibqp.qp_num); | 873 | free_qpn(&rdi->qp_dev->qpn_table, qp->ibqp.qp_num); |
874 | 874 | ||
875 | bail_rq_wq: | 875 | bail_rq_wq: |
876 | vfree(qp->r_rq.wq); | 876 | if (!qp->ip) |
877 | vfree(qp->r_rq.wq); | ||
877 | 878 | ||
878 | bail_driver_priv: | 879 | bail_driver_priv: |
879 | rdi->driver_f.qp_priv_free(rdi, qp); | 880 | rdi->driver_f.qp_priv_free(rdi, qp); |
diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c index 55f0e8f0ca79..ddd59270ff6d 100644 --- a/drivers/infiniband/sw/rxe/rxe.c +++ b/drivers/infiniband/sw/rxe/rxe.c | |||
@@ -362,15 +362,34 @@ static int __init rxe_module_init(void) | |||
362 | return err; | 362 | return err; |
363 | } | 363 | } |
364 | 364 | ||
365 | err = rxe_net_init(); | 365 | err = rxe_net_ipv4_init(); |
366 | if (err) { | 366 | if (err) { |
367 | pr_err("rxe: unable to init\n"); | 367 | pr_err("rxe: unable to init ipv4 tunnel\n"); |
368 | rxe_cache_exit(); | 368 | rxe_cache_exit(); |
369 | return err; | 369 | goto exit; |
370 | } | ||
371 | |||
372 | err = rxe_net_ipv6_init(); | ||
373 | if (err) { | ||
374 | pr_err("rxe: unable to init ipv6 tunnel\n"); | ||
375 | rxe_cache_exit(); | ||
376 | goto exit; | ||
370 | } | 377 | } |
378 | |||
379 | err = register_netdevice_notifier(&rxe_net_notifier); | ||
380 | if (err) { | ||
381 | pr_err("rxe: Failed to rigister netdev notifier\n"); | ||
382 | goto exit; | ||
383 | } | ||
384 | |||
371 | pr_info("rxe: loaded\n"); | 385 | pr_info("rxe: loaded\n"); |
372 | 386 | ||
373 | return 0; | 387 | return 0; |
388 | |||
389 | exit: | ||
390 | rxe_release_udp_tunnel(recv_sockets.sk4); | ||
391 | rxe_release_udp_tunnel(recv_sockets.sk6); | ||
392 | return err; | ||
374 | } | 393 | } |
375 | 394 | ||
376 | static void __exit rxe_module_exit(void) | 395 | static void __exit rxe_module_exit(void) |
diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c index 36f67de44095..1c59ef2c67aa 100644 --- a/drivers/infiniband/sw/rxe/rxe_comp.c +++ b/drivers/infiniband/sw/rxe/rxe_comp.c | |||
@@ -689,7 +689,14 @@ int rxe_completer(void *arg) | |||
689 | qp->req.need_retry = 1; | 689 | qp->req.need_retry = 1; |
690 | rxe_run_task(&qp->req.task, 1); | 690 | rxe_run_task(&qp->req.task, 1); |
691 | } | 691 | } |
692 | |||
693 | if (pkt) { | ||
694 | rxe_drop_ref(pkt->qp); | ||
695 | kfree_skb(skb); | ||
696 | } | ||
697 | |||
692 | goto exit; | 698 | goto exit; |
699 | |||
693 | } else { | 700 | } else { |
694 | wqe->status = IB_WC_RETRY_EXC_ERR; | 701 | wqe->status = IB_WC_RETRY_EXC_ERR; |
695 | state = COMPST_ERROR; | 702 | state = COMPST_ERROR; |
@@ -716,6 +723,12 @@ int rxe_completer(void *arg) | |||
716 | case COMPST_ERROR: | 723 | case COMPST_ERROR: |
717 | do_complete(qp, wqe); | 724 | do_complete(qp, wqe); |
718 | rxe_qp_error(qp); | 725 | rxe_qp_error(qp); |
726 | |||
727 | if (pkt) { | ||
728 | rxe_drop_ref(pkt->qp); | ||
729 | kfree_skb(skb); | ||
730 | } | ||
731 | |||
719 | goto exit; | 732 | goto exit; |
720 | } | 733 | } |
721 | } | 734 | } |
diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c index 0b8d2ea8b41d..eedf2f1cafdf 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.c +++ b/drivers/infiniband/sw/rxe/rxe_net.c | |||
@@ -275,9 +275,10 @@ static struct socket *rxe_setup_udp_tunnel(struct net *net, __be16 port, | |||
275 | return sock; | 275 | return sock; |
276 | } | 276 | } |
277 | 277 | ||
278 | static void rxe_release_udp_tunnel(struct socket *sk) | 278 | void rxe_release_udp_tunnel(struct socket *sk) |
279 | { | 279 | { |
280 | udp_tunnel_sock_release(sk); | 280 | if (sk) |
281 | udp_tunnel_sock_release(sk); | ||
281 | } | 282 | } |
282 | 283 | ||
283 | static void prepare_udp_hdr(struct sk_buff *skb, __be16 src_port, | 284 | static void prepare_udp_hdr(struct sk_buff *skb, __be16 src_port, |
@@ -658,51 +659,45 @@ out: | |||
658 | return NOTIFY_OK; | 659 | return NOTIFY_OK; |
659 | } | 660 | } |
660 | 661 | ||
661 | static struct notifier_block rxe_net_notifier = { | 662 | struct notifier_block rxe_net_notifier = { |
662 | .notifier_call = rxe_notify, | 663 | .notifier_call = rxe_notify, |
663 | }; | 664 | }; |
664 | 665 | ||
665 | int rxe_net_init(void) | 666 | int rxe_net_ipv4_init(void) |
666 | { | 667 | { |
667 | int err; | ||
668 | |||
669 | spin_lock_init(&dev_list_lock); | 668 | spin_lock_init(&dev_list_lock); |
670 | 669 | ||
671 | recv_sockets.sk6 = rxe_setup_udp_tunnel(&init_net, | ||
672 | htons(ROCE_V2_UDP_DPORT), true); | ||
673 | if (IS_ERR(recv_sockets.sk6)) { | ||
674 | recv_sockets.sk6 = NULL; | ||
675 | pr_err("rxe: Failed to create IPv6 UDP tunnel\n"); | ||
676 | return -1; | ||
677 | } | ||
678 | |||
679 | recv_sockets.sk4 = rxe_setup_udp_tunnel(&init_net, | 670 | recv_sockets.sk4 = rxe_setup_udp_tunnel(&init_net, |
680 | htons(ROCE_V2_UDP_DPORT), false); | 671 | htons(ROCE_V2_UDP_DPORT), false); |
681 | if (IS_ERR(recv_sockets.sk4)) { | 672 | if (IS_ERR(recv_sockets.sk4)) { |
682 | rxe_release_udp_tunnel(recv_sockets.sk6); | ||
683 | recv_sockets.sk4 = NULL; | 673 | recv_sockets.sk4 = NULL; |
684 | recv_sockets.sk6 = NULL; | ||
685 | pr_err("rxe: Failed to create IPv4 UDP tunnel\n"); | 674 | pr_err("rxe: Failed to create IPv4 UDP tunnel\n"); |
686 | return -1; | 675 | return -1; |
687 | } | 676 | } |
688 | 677 | ||
689 | err = register_netdevice_notifier(&rxe_net_notifier); | 678 | return 0; |
690 | if (err) { | ||
691 | rxe_release_udp_tunnel(recv_sockets.sk6); | ||
692 | rxe_release_udp_tunnel(recv_sockets.sk4); | ||
693 | pr_err("rxe: Failed to rigister netdev notifier\n"); | ||
694 | } | ||
695 | |||
696 | return err; | ||
697 | } | 679 | } |
698 | 680 | ||
699 | void rxe_net_exit(void) | 681 | int rxe_net_ipv6_init(void) |
700 | { | 682 | { |
701 | if (recv_sockets.sk6) | 683 | #if IS_ENABLED(CONFIG_IPV6) |
702 | rxe_release_udp_tunnel(recv_sockets.sk6); | ||
703 | 684 | ||
704 | if (recv_sockets.sk4) | 685 | spin_lock_init(&dev_list_lock); |
705 | rxe_release_udp_tunnel(recv_sockets.sk4); | ||
706 | 686 | ||
687 | recv_sockets.sk6 = rxe_setup_udp_tunnel(&init_net, | ||
688 | htons(ROCE_V2_UDP_DPORT), true); | ||
689 | if (IS_ERR(recv_sockets.sk6)) { | ||
690 | recv_sockets.sk6 = NULL; | ||
691 | pr_err("rxe: Failed to create IPv6 UDP tunnel\n"); | ||
692 | return -1; | ||
693 | } | ||
694 | #endif | ||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | void rxe_net_exit(void) | ||
699 | { | ||
700 | rxe_release_udp_tunnel(recv_sockets.sk6); | ||
701 | rxe_release_udp_tunnel(recv_sockets.sk4); | ||
707 | unregister_netdevice_notifier(&rxe_net_notifier); | 702 | unregister_netdevice_notifier(&rxe_net_notifier); |
708 | } | 703 | } |
diff --git a/drivers/infiniband/sw/rxe/rxe_net.h b/drivers/infiniband/sw/rxe/rxe_net.h index 7b06f76d16cc..0daf7f09e5b5 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.h +++ b/drivers/infiniband/sw/rxe/rxe_net.h | |||
@@ -44,10 +44,13 @@ struct rxe_recv_sockets { | |||
44 | }; | 44 | }; |
45 | 45 | ||
46 | extern struct rxe_recv_sockets recv_sockets; | 46 | extern struct rxe_recv_sockets recv_sockets; |
47 | extern struct notifier_block rxe_net_notifier; | ||
48 | void rxe_release_udp_tunnel(struct socket *sk); | ||
47 | 49 | ||
48 | struct rxe_dev *rxe_net_add(struct net_device *ndev); | 50 | struct rxe_dev *rxe_net_add(struct net_device *ndev); |
49 | 51 | ||
50 | int rxe_net_init(void); | 52 | int rxe_net_ipv4_init(void); |
53 | int rxe_net_ipv6_init(void); | ||
51 | void rxe_net_exit(void); | 54 | void rxe_net_exit(void); |
52 | 55 | ||
53 | #endif /* RXE_NET_H */ | 56 | #endif /* RXE_NET_H */ |
diff --git a/drivers/infiniband/sw/rxe/rxe_recv.c b/drivers/infiniband/sw/rxe/rxe_recv.c index 3d464c23e08b..144d2f129fcd 100644 --- a/drivers/infiniband/sw/rxe/rxe_recv.c +++ b/drivers/infiniband/sw/rxe/rxe_recv.c | |||
@@ -312,7 +312,7 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb) | |||
312 | * make a copy of the skb to post to the next qp | 312 | * make a copy of the skb to post to the next qp |
313 | */ | 313 | */ |
314 | skb_copy = (mce->qp_list.next != &mcg->qp_list) ? | 314 | skb_copy = (mce->qp_list.next != &mcg->qp_list) ? |
315 | skb_clone(skb, GFP_KERNEL) : NULL; | 315 | skb_clone(skb, GFP_ATOMIC) : NULL; |
316 | 316 | ||
317 | pkt->qp = qp; | 317 | pkt->qp = qp; |
318 | rxe_add_ref(qp); | 318 | rxe_add_ref(qp); |
diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c index 33b2d9d77021..13a848a518e8 100644 --- a/drivers/infiniband/sw/rxe/rxe_req.c +++ b/drivers/infiniband/sw/rxe/rxe_req.c | |||
@@ -511,24 +511,21 @@ static int fill_packet(struct rxe_qp *qp, struct rxe_send_wqe *wqe, | |||
511 | } | 511 | } |
512 | 512 | ||
513 | static void update_wqe_state(struct rxe_qp *qp, | 513 | static void update_wqe_state(struct rxe_qp *qp, |
514 | struct rxe_send_wqe *wqe, | 514 | struct rxe_send_wqe *wqe, |
515 | struct rxe_pkt_info *pkt, | 515 | struct rxe_pkt_info *pkt) |
516 | enum wqe_state *prev_state) | ||
517 | { | 516 | { |
518 | enum wqe_state prev_state_ = wqe->state; | ||
519 | |||
520 | if (pkt->mask & RXE_END_MASK) { | 517 | if (pkt->mask & RXE_END_MASK) { |
521 | if (qp_type(qp) == IB_QPT_RC) | 518 | if (qp_type(qp) == IB_QPT_RC) |
522 | wqe->state = wqe_state_pending; | 519 | wqe->state = wqe_state_pending; |
523 | } else { | 520 | } else { |
524 | wqe->state = wqe_state_processing; | 521 | wqe->state = wqe_state_processing; |
525 | } | 522 | } |
526 | |||
527 | *prev_state = prev_state_; | ||
528 | } | 523 | } |
529 | 524 | ||
530 | static void update_state(struct rxe_qp *qp, struct rxe_send_wqe *wqe, | 525 | static void update_wqe_psn(struct rxe_qp *qp, |
531 | struct rxe_pkt_info *pkt, int payload) | 526 | struct rxe_send_wqe *wqe, |
527 | struct rxe_pkt_info *pkt, | ||
528 | int payload) | ||
532 | { | 529 | { |
533 | /* number of packets left to send including current one */ | 530 | /* number of packets left to send including current one */ |
534 | int num_pkt = (wqe->dma.resid + payload + qp->mtu - 1) / qp->mtu; | 531 | int num_pkt = (wqe->dma.resid + payload + qp->mtu - 1) / qp->mtu; |
@@ -546,9 +543,34 @@ static void update_state(struct rxe_qp *qp, struct rxe_send_wqe *wqe, | |||
546 | qp->req.psn = (wqe->first_psn + num_pkt) & BTH_PSN_MASK; | 543 | qp->req.psn = (wqe->first_psn + num_pkt) & BTH_PSN_MASK; |
547 | else | 544 | else |
548 | qp->req.psn = (qp->req.psn + 1) & BTH_PSN_MASK; | 545 | qp->req.psn = (qp->req.psn + 1) & BTH_PSN_MASK; |
546 | } | ||
549 | 547 | ||
550 | qp->req.opcode = pkt->opcode; | 548 | static void save_state(struct rxe_send_wqe *wqe, |
549 | struct rxe_qp *qp, | ||
550 | struct rxe_send_wqe *rollback_wqe, | ||
551 | struct rxe_qp *rollback_qp) | ||
552 | { | ||
553 | rollback_wqe->state = wqe->state; | ||
554 | rollback_wqe->first_psn = wqe->first_psn; | ||
555 | rollback_wqe->last_psn = wqe->last_psn; | ||
556 | rollback_qp->req.psn = qp->req.psn; | ||
557 | } | ||
551 | 558 | ||
559 | static void rollback_state(struct rxe_send_wqe *wqe, | ||
560 | struct rxe_qp *qp, | ||
561 | struct rxe_send_wqe *rollback_wqe, | ||
562 | struct rxe_qp *rollback_qp) | ||
563 | { | ||
564 | wqe->state = rollback_wqe->state; | ||
565 | wqe->first_psn = rollback_wqe->first_psn; | ||
566 | wqe->last_psn = rollback_wqe->last_psn; | ||
567 | qp->req.psn = rollback_qp->req.psn; | ||
568 | } | ||
569 | |||
570 | static void update_state(struct rxe_qp *qp, struct rxe_send_wqe *wqe, | ||
571 | struct rxe_pkt_info *pkt, int payload) | ||
572 | { | ||
573 | qp->req.opcode = pkt->opcode; | ||
552 | 574 | ||
553 | if (pkt->mask & RXE_END_MASK) | 575 | if (pkt->mask & RXE_END_MASK) |
554 | qp->req.wqe_index = next_index(qp->sq.queue, qp->req.wqe_index); | 576 | qp->req.wqe_index = next_index(qp->sq.queue, qp->req.wqe_index); |
@@ -571,7 +593,8 @@ int rxe_requester(void *arg) | |||
571 | int mtu; | 593 | int mtu; |
572 | int opcode; | 594 | int opcode; |
573 | int ret; | 595 | int ret; |
574 | enum wqe_state prev_state; | 596 | struct rxe_qp rollback_qp; |
597 | struct rxe_send_wqe rollback_wqe; | ||
575 | 598 | ||
576 | next_wqe: | 599 | next_wqe: |
577 | if (unlikely(!qp->valid || qp->req.state == QP_STATE_ERROR)) | 600 | if (unlikely(!qp->valid || qp->req.state == QP_STATE_ERROR)) |
@@ -688,13 +711,21 @@ next_wqe: | |||
688 | goto err; | 711 | goto err; |
689 | } | 712 | } |
690 | 713 | ||
691 | update_wqe_state(qp, wqe, &pkt, &prev_state); | 714 | /* |
715 | * To prevent a race on wqe access between requester and completer, | ||
716 | * wqe members state and psn need to be set before calling | ||
717 | * rxe_xmit_packet(). | ||
718 | * Otherwise, completer might initiate an unjustified retry flow. | ||
719 | */ | ||
720 | save_state(wqe, qp, &rollback_wqe, &rollback_qp); | ||
721 | update_wqe_state(qp, wqe, &pkt); | ||
722 | update_wqe_psn(qp, wqe, &pkt, payload); | ||
692 | ret = rxe_xmit_packet(to_rdev(qp->ibqp.device), qp, &pkt, skb); | 723 | ret = rxe_xmit_packet(to_rdev(qp->ibqp.device), qp, &pkt, skb); |
693 | if (ret) { | 724 | if (ret) { |
694 | qp->need_req_skb = 1; | 725 | qp->need_req_skb = 1; |
695 | kfree_skb(skb); | 726 | kfree_skb(skb); |
696 | 727 | ||
697 | wqe->state = prev_state; | 728 | rollback_state(wqe, qp, &rollback_wqe, &rollback_qp); |
698 | 729 | ||
699 | if (ret == -EAGAIN) { | 730 | if (ret == -EAGAIN) { |
700 | rxe_run_task(&qp->req.task, 1); | 731 | rxe_run_task(&qp->req.task, 1); |
diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c index ebb03b46e2ad..3e0f0f2baace 100644 --- a/drivers/infiniband/sw/rxe/rxe_resp.c +++ b/drivers/infiniband/sw/rxe/rxe_resp.c | |||
@@ -972,11 +972,13 @@ static int send_atomic_ack(struct rxe_qp *qp, struct rxe_pkt_info *pkt, | |||
972 | free_rd_atomic_resource(qp, res); | 972 | free_rd_atomic_resource(qp, res); |
973 | rxe_advance_resp_resource(qp); | 973 | rxe_advance_resp_resource(qp); |
974 | 974 | ||
975 | memcpy(SKB_TO_PKT(skb), &ack_pkt, sizeof(skb->cb)); | ||
976 | |||
975 | res->type = RXE_ATOMIC_MASK; | 977 | res->type = RXE_ATOMIC_MASK; |
976 | res->atomic.skb = skb; | 978 | res->atomic.skb = skb; |
977 | res->first_psn = qp->resp.psn; | 979 | res->first_psn = ack_pkt.psn; |
978 | res->last_psn = qp->resp.psn; | 980 | res->last_psn = ack_pkt.psn; |
979 | res->cur_psn = qp->resp.psn; | 981 | res->cur_psn = ack_pkt.psn; |
980 | 982 | ||
981 | rc = rxe_xmit_packet(rxe, qp, &ack_pkt, skb_copy); | 983 | rc = rxe_xmit_packet(rxe, qp, &ack_pkt, skb_copy); |
982 | if (rc) { | 984 | if (rc) { |
@@ -1116,8 +1118,7 @@ static enum resp_states duplicate_request(struct rxe_qp *qp, | |||
1116 | rc = RESPST_CLEANUP; | 1118 | rc = RESPST_CLEANUP; |
1117 | goto out; | 1119 | goto out; |
1118 | } | 1120 | } |
1119 | bth_set_psn(SKB_TO_PKT(skb_copy), | 1121 | |
1120 | qp->resp.psn - 1); | ||
1121 | /* Resend the result. */ | 1122 | /* Resend the result. */ |
1122 | rc = rxe_xmit_packet(to_rdev(qp->ibqp.device), qp, | 1123 | rc = rxe_xmit_packet(to_rdev(qp->ibqp.device), qp, |
1123 | pkt, skb_copy); | 1124 | pkt, skb_copy); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 4f7d9b48df64..9dbfcc0ab577 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -478,6 +478,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
478 | struct ipoib_ah *address, u32 qpn); | 478 | struct ipoib_ah *address, u32 qpn); |
479 | void ipoib_reap_ah(struct work_struct *work); | 479 | void ipoib_reap_ah(struct work_struct *work); |
480 | 480 | ||
481 | struct ipoib_path *__path_find(struct net_device *dev, void *gid); | ||
481 | void ipoib_mark_paths_invalid(struct net_device *dev); | 482 | void ipoib_mark_paths_invalid(struct net_device *dev); |
482 | void ipoib_flush_paths(struct net_device *dev); | 483 | void ipoib_flush_paths(struct net_device *dev); |
483 | int ipoib_check_sm_sendonly_fullmember_support(struct ipoib_dev_priv *priv); | 484 | int ipoib_check_sm_sendonly_fullmember_support(struct ipoib_dev_priv *priv); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 951d9abcca8b..4ad297d3de89 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
@@ -1318,6 +1318,8 @@ void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx) | |||
1318 | } | 1318 | } |
1319 | } | 1319 | } |
1320 | 1320 | ||
1321 | #define QPN_AND_OPTIONS_OFFSET 4 | ||
1322 | |||
1321 | static void ipoib_cm_tx_start(struct work_struct *work) | 1323 | static void ipoib_cm_tx_start(struct work_struct *work) |
1322 | { | 1324 | { |
1323 | struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv, | 1325 | struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv, |
@@ -1326,6 +1328,7 @@ static void ipoib_cm_tx_start(struct work_struct *work) | |||
1326 | struct ipoib_neigh *neigh; | 1328 | struct ipoib_neigh *neigh; |
1327 | struct ipoib_cm_tx *p; | 1329 | struct ipoib_cm_tx *p; |
1328 | unsigned long flags; | 1330 | unsigned long flags; |
1331 | struct ipoib_path *path; | ||
1329 | int ret; | 1332 | int ret; |
1330 | 1333 | ||
1331 | struct ib_sa_path_rec pathrec; | 1334 | struct ib_sa_path_rec pathrec; |
@@ -1338,7 +1341,19 @@ static void ipoib_cm_tx_start(struct work_struct *work) | |||
1338 | p = list_entry(priv->cm.start_list.next, typeof(*p), list); | 1341 | p = list_entry(priv->cm.start_list.next, typeof(*p), list); |
1339 | list_del_init(&p->list); | 1342 | list_del_init(&p->list); |
1340 | neigh = p->neigh; | 1343 | neigh = p->neigh; |
1344 | |||
1341 | qpn = IPOIB_QPN(neigh->daddr); | 1345 | qpn = IPOIB_QPN(neigh->daddr); |
1346 | /* | ||
1347 | * As long as the search is with these 2 locks, | ||
1348 | * path existence indicates its validity. | ||
1349 | */ | ||
1350 | path = __path_find(dev, neigh->daddr + QPN_AND_OPTIONS_OFFSET); | ||
1351 | if (!path) { | ||
1352 | pr_info("%s ignore not valid path %pI6\n", | ||
1353 | __func__, | ||
1354 | neigh->daddr + QPN_AND_OPTIONS_OFFSET); | ||
1355 | goto free_neigh; | ||
1356 | } | ||
1342 | memcpy(&pathrec, &p->path->pathrec, sizeof pathrec); | 1357 | memcpy(&pathrec, &p->path->pathrec, sizeof pathrec); |
1343 | 1358 | ||
1344 | spin_unlock_irqrestore(&priv->lock, flags); | 1359 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -1350,6 +1365,7 @@ static void ipoib_cm_tx_start(struct work_struct *work) | |||
1350 | spin_lock_irqsave(&priv->lock, flags); | 1365 | spin_lock_irqsave(&priv->lock, flags); |
1351 | 1366 | ||
1352 | if (ret) { | 1367 | if (ret) { |
1368 | free_neigh: | ||
1353 | neigh = p->neigh; | 1369 | neigh = p->neigh; |
1354 | if (neigh) { | 1370 | if (neigh) { |
1355 | neigh->cm = NULL; | 1371 | neigh->cm = NULL; |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index dc6d241b9406..be11d5d5b8c1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -1161,8 +1161,17 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | |||
1161 | } | 1161 | } |
1162 | 1162 | ||
1163 | if (level == IPOIB_FLUSH_LIGHT) { | 1163 | if (level == IPOIB_FLUSH_LIGHT) { |
1164 | int oper_up; | ||
1164 | ipoib_mark_paths_invalid(dev); | 1165 | ipoib_mark_paths_invalid(dev); |
1166 | /* Set IPoIB operation as down to prevent races between: | ||
1167 | * the flush flow which leaves MCG and on the fly joins | ||
1168 | * which can happen during that time. mcast restart task | ||
1169 | * should deal with join requests we missed. | ||
1170 | */ | ||
1171 | oper_up = test_and_clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags); | ||
1165 | ipoib_mcast_dev_flush(dev); | 1172 | ipoib_mcast_dev_flush(dev); |
1173 | if (oper_up) | ||
1174 | set_bit(IPOIB_FLAG_OPER_UP, &priv->flags); | ||
1166 | ipoib_flush_ah(dev); | 1175 | ipoib_flush_ah(dev); |
1167 | } | 1176 | } |
1168 | 1177 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 74bcaa064226..cc1c1b062ea5 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -485,7 +485,7 @@ int ipoib_set_mode(struct net_device *dev, const char *buf) | |||
485 | return -EINVAL; | 485 | return -EINVAL; |
486 | } | 486 | } |
487 | 487 | ||
488 | static struct ipoib_path *__path_find(struct net_device *dev, void *gid) | 488 | struct ipoib_path *__path_find(struct net_device *dev, void *gid) |
489 | { | 489 | { |
490 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 490 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
491 | struct rb_node *n = priv->path_tree.rb_node; | 491 | struct rb_node *n = priv->path_tree.rb_node; |
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index ba6be060a476..cae9bbcc27e7 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c | |||
@@ -403,6 +403,7 @@ isert_init_conn(struct isert_conn *isert_conn) | |||
403 | INIT_LIST_HEAD(&isert_conn->node); | 403 | INIT_LIST_HEAD(&isert_conn->node); |
404 | init_completion(&isert_conn->login_comp); | 404 | init_completion(&isert_conn->login_comp); |
405 | init_completion(&isert_conn->login_req_comp); | 405 | init_completion(&isert_conn->login_req_comp); |
406 | init_waitqueue_head(&isert_conn->rem_wait); | ||
406 | kref_init(&isert_conn->kref); | 407 | kref_init(&isert_conn->kref); |
407 | mutex_init(&isert_conn->mutex); | 408 | mutex_init(&isert_conn->mutex); |
408 | INIT_WORK(&isert_conn->release_work, isert_release_work); | 409 | INIT_WORK(&isert_conn->release_work, isert_release_work); |
@@ -448,7 +449,7 @@ isert_alloc_login_buf(struct isert_conn *isert_conn, | |||
448 | 449 | ||
449 | isert_conn->login_rsp_buf = kzalloc(ISER_RX_PAYLOAD_SIZE, GFP_KERNEL); | 450 | isert_conn->login_rsp_buf = kzalloc(ISER_RX_PAYLOAD_SIZE, GFP_KERNEL); |
450 | if (!isert_conn->login_rsp_buf) { | 451 | if (!isert_conn->login_rsp_buf) { |
451 | isert_err("Unable to allocate isert_conn->login_rspbuf\n"); | 452 | ret = -ENOMEM; |
452 | goto out_unmap_login_req_buf; | 453 | goto out_unmap_login_req_buf; |
453 | } | 454 | } |
454 | 455 | ||
@@ -578,7 +579,8 @@ isert_connect_release(struct isert_conn *isert_conn) | |||
578 | BUG_ON(!device); | 579 | BUG_ON(!device); |
579 | 580 | ||
580 | isert_free_rx_descriptors(isert_conn); | 581 | isert_free_rx_descriptors(isert_conn); |
581 | if (isert_conn->cm_id) | 582 | if (isert_conn->cm_id && |
583 | !isert_conn->dev_removed) | ||
582 | rdma_destroy_id(isert_conn->cm_id); | 584 | rdma_destroy_id(isert_conn->cm_id); |
583 | 585 | ||
584 | if (isert_conn->qp) { | 586 | if (isert_conn->qp) { |
@@ -593,7 +595,10 @@ isert_connect_release(struct isert_conn *isert_conn) | |||
593 | 595 | ||
594 | isert_device_put(device); | 596 | isert_device_put(device); |
595 | 597 | ||
596 | kfree(isert_conn); | 598 | if (isert_conn->dev_removed) |
599 | wake_up_interruptible(&isert_conn->rem_wait); | ||
600 | else | ||
601 | kfree(isert_conn); | ||
597 | } | 602 | } |
598 | 603 | ||
599 | static void | 604 | static void |
@@ -753,6 +758,7 @@ static int | |||
753 | isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | 758 | isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) |
754 | { | 759 | { |
755 | struct isert_np *isert_np = cma_id->context; | 760 | struct isert_np *isert_np = cma_id->context; |
761 | struct isert_conn *isert_conn; | ||
756 | int ret = 0; | 762 | int ret = 0; |
757 | 763 | ||
758 | isert_info("%s (%d): status %d id %p np %p\n", | 764 | isert_info("%s (%d): status %d id %p np %p\n", |
@@ -773,10 +779,21 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | |||
773 | break; | 779 | break; |
774 | case RDMA_CM_EVENT_ADDR_CHANGE: /* FALLTHRU */ | 780 | case RDMA_CM_EVENT_ADDR_CHANGE: /* FALLTHRU */ |
775 | case RDMA_CM_EVENT_DISCONNECTED: /* FALLTHRU */ | 781 | case RDMA_CM_EVENT_DISCONNECTED: /* FALLTHRU */ |
776 | case RDMA_CM_EVENT_DEVICE_REMOVAL: /* FALLTHRU */ | ||
777 | case RDMA_CM_EVENT_TIMEWAIT_EXIT: /* FALLTHRU */ | 782 | case RDMA_CM_EVENT_TIMEWAIT_EXIT: /* FALLTHRU */ |
778 | ret = isert_disconnected_handler(cma_id, event->event); | 783 | ret = isert_disconnected_handler(cma_id, event->event); |
779 | break; | 784 | break; |
785 | case RDMA_CM_EVENT_DEVICE_REMOVAL: | ||
786 | isert_conn = cma_id->qp->qp_context; | ||
787 | isert_conn->dev_removed = true; | ||
788 | isert_disconnected_handler(cma_id, event->event); | ||
789 | wait_event_interruptible(isert_conn->rem_wait, | ||
790 | isert_conn->state == ISER_CONN_DOWN); | ||
791 | kfree(isert_conn); | ||
792 | /* | ||
793 | * return non-zero from the callback to destroy | ||
794 | * the rdma cm id | ||
795 | */ | ||
796 | return 1; | ||
780 | case RDMA_CM_EVENT_REJECTED: /* FALLTHRU */ | 797 | case RDMA_CM_EVENT_REJECTED: /* FALLTHRU */ |
781 | case RDMA_CM_EVENT_UNREACHABLE: /* FALLTHRU */ | 798 | case RDMA_CM_EVENT_UNREACHABLE: /* FALLTHRU */ |
782 | case RDMA_CM_EVENT_CONNECT_ERROR: | 799 | case RDMA_CM_EVENT_CONNECT_ERROR: |
diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h index fc791efe3a10..c02ada57d7f5 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.h +++ b/drivers/infiniband/ulp/isert/ib_isert.h | |||
@@ -158,6 +158,8 @@ struct isert_conn { | |||
158 | struct work_struct release_work; | 158 | struct work_struct release_work; |
159 | bool logout_posted; | 159 | bool logout_posted; |
160 | bool snd_w_inv; | 160 | bool snd_w_inv; |
161 | wait_queue_head_t rem_wait; | ||
162 | bool dev_removed; | ||
161 | }; | 163 | }; |
162 | 164 | ||
163 | #define ISERT_MAX_CQ 64 | 165 | #define ISERT_MAX_CQ 64 |
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index dfa23b075a88..883bbfe08e0e 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
@@ -522,6 +522,11 @@ static int srpt_refresh_port(struct srpt_port *sport) | |||
522 | if (ret) | 522 | if (ret) |
523 | goto err_query_port; | 523 | goto err_query_port; |
524 | 524 | ||
525 | snprintf(sport->port_guid, sizeof(sport->port_guid), | ||
526 | "0x%016llx%016llx", | ||
527 | be64_to_cpu(sport->gid.global.subnet_prefix), | ||
528 | be64_to_cpu(sport->gid.global.interface_id)); | ||
529 | |||
525 | if (!sport->mad_agent) { | 530 | if (!sport->mad_agent) { |
526 | memset(®_req, 0, sizeof(reg_req)); | 531 | memset(®_req, 0, sizeof(reg_req)); |
527 | reg_req.mgmt_class = IB_MGMT_CLASS_DEVICE_MGMT; | 532 | reg_req.mgmt_class = IB_MGMT_CLASS_DEVICE_MGMT; |
@@ -2548,10 +2553,6 @@ static void srpt_add_one(struct ib_device *device) | |||
2548 | sdev->device->name, i); | 2553 | sdev->device->name, i); |
2549 | goto err_ring; | 2554 | goto err_ring; |
2550 | } | 2555 | } |
2551 | snprintf(sport->port_guid, sizeof(sport->port_guid), | ||
2552 | "0x%016llx%016llx", | ||
2553 | be64_to_cpu(sport->gid.global.subnet_prefix), | ||
2554 | be64_to_cpu(sport->gid.global.interface_id)); | ||
2555 | } | 2556 | } |
2556 | 2557 | ||
2557 | spin_lock(&srpt_dev_lock); | 2558 | spin_lock(&srpt_dev_lock); |
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 7d61439be5f2..0c07e1023a46 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c | |||
@@ -376,7 +376,7 @@ static int tegra_kbc_start(struct tegra_kbc *kbc) | |||
376 | /* Reset the KBC controller to clear all previous status.*/ | 376 | /* Reset the KBC controller to clear all previous status.*/ |
377 | reset_control_assert(kbc->rst); | 377 | reset_control_assert(kbc->rst); |
378 | udelay(100); | 378 | udelay(100); |
379 | reset_control_assert(kbc->rst); | 379 | reset_control_deassert(kbc->rst); |
380 | udelay(100); | 380 | udelay(100); |
381 | 381 | ||
382 | tegra_kbc_config_pins(kbc); | 382 | tegra_kbc_config_pins(kbc); |
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c index faa295ec4f31..c83bce89028b 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c | |||
@@ -553,7 +553,6 @@ int rmi_read_register_desc(struct rmi_device *d, u16 addr, | |||
553 | goto free_struct_buff; | 553 | goto free_struct_buff; |
554 | 554 | ||
555 | reg = find_first_bit(rdesc->presense_map, RMI_REG_DESC_PRESENSE_BITS); | 555 | reg = find_first_bit(rdesc->presense_map, RMI_REG_DESC_PRESENSE_BITS); |
556 | map_offset = 0; | ||
557 | for (i = 0; i < rdesc->num_registers; i++) { | 556 | for (i = 0; i < rdesc->num_registers; i++) { |
558 | struct rmi_register_desc_item *item = &rdesc->registers[i]; | 557 | struct rmi_register_desc_item *item = &rdesc->registers[i]; |
559 | int reg_size = struct_buf[offset]; | 558 | int reg_size = struct_buf[offset]; |
@@ -576,6 +575,8 @@ int rmi_read_register_desc(struct rmi_device *d, u16 addr, | |||
576 | item->reg = reg; | 575 | item->reg = reg; |
577 | item->reg_size = reg_size; | 576 | item->reg_size = reg_size; |
578 | 577 | ||
578 | map_offset = 0; | ||
579 | |||
579 | do { | 580 | do { |
580 | for (b = 0; b < 7; b++) { | 581 | for (b = 0; b < 7; b++) { |
581 | if (struct_buf[offset] & (0x1 << b)) | 582 | if (struct_buf[offset] & (0x1 << b)) |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index b4d34086e73f..405252a884dd 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -1305,6 +1305,7 @@ static int __init i8042_create_aux_port(int idx) | |||
1305 | serio->write = i8042_aux_write; | 1305 | serio->write = i8042_aux_write; |
1306 | serio->start = i8042_start; | 1306 | serio->start = i8042_start; |
1307 | serio->stop = i8042_stop; | 1307 | serio->stop = i8042_stop; |
1308 | serio->ps2_cmd_mutex = &i8042_mutex; | ||
1308 | serio->port_data = port; | 1309 | serio->port_data = port; |
1309 | serio->dev.parent = &i8042_platform_device->dev; | 1310 | serio->dev.parent = &i8042_platform_device->dev; |
1310 | if (idx < 0) { | 1311 | if (idx < 0) { |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index a61b2153ab8c..1ce3ecbe37f8 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -1473,7 +1473,6 @@ static int ads7846_remove(struct spi_device *spi) | |||
1473 | 1473 | ||
1474 | ads784x_hwmon_unregister(spi, ts); | 1474 | ads784x_hwmon_unregister(spi, ts); |
1475 | 1475 | ||
1476 | regulator_disable(ts->reg); | ||
1477 | regulator_put(ts->reg); | 1476 | regulator_put(ts->reg); |
1478 | 1477 | ||
1479 | if (!ts->get_pendown_state) { | 1478 | if (!ts->get_pendown_state) { |
diff --git a/drivers/input/touchscreen/silead.c b/drivers/input/touchscreen/silead.c index 7379fe153cf9..f502c8488be8 100644 --- a/drivers/input/touchscreen/silead.c +++ b/drivers/input/touchscreen/silead.c | |||
@@ -390,9 +390,10 @@ static void silead_ts_read_props(struct i2c_client *client) | |||
390 | data->max_fingers = 5; /* Most devices handle up-to 5 fingers */ | 390 | data->max_fingers = 5; /* Most devices handle up-to 5 fingers */ |
391 | } | 391 | } |
392 | 392 | ||
393 | error = device_property_read_string(dev, "touchscreen-fw-name", &str); | 393 | error = device_property_read_string(dev, "firmware-name", &str); |
394 | if (!error) | 394 | if (!error) |
395 | snprintf(data->fw_name, sizeof(data->fw_name), "%s", str); | 395 | snprintf(data->fw_name, sizeof(data->fw_name), |
396 | "silead/%s", str); | ||
396 | else | 397 | else |
397 | dev_dbg(dev, "Firmware file name read error. Using default."); | 398 | dev_dbg(dev, "Firmware file name read error. Using default."); |
398 | } | 399 | } |
@@ -410,14 +411,14 @@ static int silead_ts_set_default_fw_name(struct silead_ts_data *data, | |||
410 | if (!acpi_id) | 411 | if (!acpi_id) |
411 | return -ENODEV; | 412 | return -ENODEV; |
412 | 413 | ||
413 | snprintf(data->fw_name, sizeof(data->fw_name), "%s.fw", | 414 | snprintf(data->fw_name, sizeof(data->fw_name), |
414 | acpi_id->id); | 415 | "silead/%s.fw", acpi_id->id); |
415 | 416 | ||
416 | for (i = 0; i < strlen(data->fw_name); i++) | 417 | for (i = 0; i < strlen(data->fw_name); i++) |
417 | data->fw_name[i] = tolower(data->fw_name[i]); | 418 | data->fw_name[i] = tolower(data->fw_name[i]); |
418 | } else { | 419 | } else { |
419 | snprintf(data->fw_name, sizeof(data->fw_name), "%s.fw", | 420 | snprintf(data->fw_name, sizeof(data->fw_name), |
420 | id->name); | 421 | "silead/%s.fw", id->name); |
421 | } | 422 | } |
422 | 423 | ||
423 | return 0; | 424 | return 0; |
@@ -426,7 +427,8 @@ static int silead_ts_set_default_fw_name(struct silead_ts_data *data, | |||
426 | static int silead_ts_set_default_fw_name(struct silead_ts_data *data, | 427 | static int silead_ts_set_default_fw_name(struct silead_ts_data *data, |
427 | const struct i2c_device_id *id) | 428 | const struct i2c_device_id *id) |
428 | { | 429 | { |
429 | snprintf(data->fw_name, sizeof(data->fw_name), "%s.fw", id->name); | 430 | snprintf(data->fw_name, sizeof(data->fw_name), |
431 | "silead/%s.fw", id->name); | ||
430 | return 0; | 432 | return 0; |
431 | } | 433 | } |
432 | #endif | 434 | #endif |
@@ -464,7 +466,7 @@ static int silead_ts_probe(struct i2c_client *client, | |||
464 | return -ENODEV; | 466 | return -ENODEV; |
465 | 467 | ||
466 | /* Power GPIO pin */ | 468 | /* Power GPIO pin */ |
467 | data->gpio_power = gpiod_get_optional(dev, "power", GPIOD_OUT_LOW); | 469 | data->gpio_power = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW); |
468 | if (IS_ERR(data->gpio_power)) { | 470 | if (IS_ERR(data->gpio_power)) { |
469 | if (PTR_ERR(data->gpio_power) != -EPROBE_DEFER) | 471 | if (PTR_ERR(data->gpio_power) != -EPROBE_DEFER) |
470 | dev_err(dev, "Shutdown GPIO request failed\n"); | 472 | dev_err(dev, "Shutdown GPIO request failed\n"); |
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index ce801170d5f2..641e88761319 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c | |||
@@ -879,7 +879,7 @@ static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu) | |||
879 | * We may have concurrent producers, so we need to be careful | 879 | * We may have concurrent producers, so we need to be careful |
880 | * not to touch any of the shadow cmdq state. | 880 | * not to touch any of the shadow cmdq state. |
881 | */ | 881 | */ |
882 | queue_read(cmd, Q_ENT(q, idx), q->ent_dwords); | 882 | queue_read(cmd, Q_ENT(q, cons), q->ent_dwords); |
883 | dev_err(smmu->dev, "skipping command in error state:\n"); | 883 | dev_err(smmu->dev, "skipping command in error state:\n"); |
884 | for (i = 0; i < ARRAY_SIZE(cmd); ++i) | 884 | for (i = 0; i < ARRAY_SIZE(cmd); ++i) |
885 | dev_err(smmu->dev, "\t0x%016llx\n", (unsigned long long)cmd[i]); | 885 | dev_err(smmu->dev, "\t0x%016llx\n", (unsigned long long)cmd[i]); |
@@ -890,7 +890,7 @@ static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu) | |||
890 | return; | 890 | return; |
891 | } | 891 | } |
892 | 892 | ||
893 | queue_write(cmd, Q_ENT(q, idx), q->ent_dwords); | 893 | queue_write(Q_ENT(q, cons), cmd, q->ent_dwords); |
894 | } | 894 | } |
895 | 895 | ||
896 | static void arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu, | 896 | static void arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu, |
@@ -1034,6 +1034,9 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid, | |||
1034 | case STRTAB_STE_0_CFG_S2_TRANS: | 1034 | case STRTAB_STE_0_CFG_S2_TRANS: |
1035 | ste_live = true; | 1035 | ste_live = true; |
1036 | break; | 1036 | break; |
1037 | case STRTAB_STE_0_CFG_ABORT: | ||
1038 | if (disable_bypass) | ||
1039 | break; | ||
1037 | default: | 1040 | default: |
1038 | BUG(); /* STE corruption */ | 1041 | BUG(); /* STE corruption */ |
1039 | } | 1042 | } |
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 4f49fe29f202..2db74ebc3240 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c | |||
@@ -686,8 +686,7 @@ static struct iommu_gather_ops arm_smmu_gather_ops = { | |||
686 | 686 | ||
687 | static irqreturn_t arm_smmu_context_fault(int irq, void *dev) | 687 | static irqreturn_t arm_smmu_context_fault(int irq, void *dev) |
688 | { | 688 | { |
689 | int flags, ret; | 689 | u32 fsr, fsynr; |
690 | u32 fsr, fsynr, resume; | ||
691 | unsigned long iova; | 690 | unsigned long iova; |
692 | struct iommu_domain *domain = dev; | 691 | struct iommu_domain *domain = dev; |
693 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); | 692 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
@@ -701,34 +700,15 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev) | |||
701 | if (!(fsr & FSR_FAULT)) | 700 | if (!(fsr & FSR_FAULT)) |
702 | return IRQ_NONE; | 701 | return IRQ_NONE; |
703 | 702 | ||
704 | if (fsr & FSR_IGN) | ||
705 | dev_err_ratelimited(smmu->dev, | ||
706 | "Unexpected context fault (fsr 0x%x)\n", | ||
707 | fsr); | ||
708 | |||
709 | fsynr = readl_relaxed(cb_base + ARM_SMMU_CB_FSYNR0); | 703 | fsynr = readl_relaxed(cb_base + ARM_SMMU_CB_FSYNR0); |
710 | flags = fsynr & FSYNR0_WNR ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ; | ||
711 | |||
712 | iova = readq_relaxed(cb_base + ARM_SMMU_CB_FAR); | 704 | iova = readq_relaxed(cb_base + ARM_SMMU_CB_FAR); |
713 | if (!report_iommu_fault(domain, smmu->dev, iova, flags)) { | ||
714 | ret = IRQ_HANDLED; | ||
715 | resume = RESUME_RETRY; | ||
716 | } else { | ||
717 | dev_err_ratelimited(smmu->dev, | ||
718 | "Unhandled context fault: iova=0x%08lx, fsynr=0x%x, cb=%d\n", | ||
719 | iova, fsynr, cfg->cbndx); | ||
720 | ret = IRQ_NONE; | ||
721 | resume = RESUME_TERMINATE; | ||
722 | } | ||
723 | |||
724 | /* Clear the faulting FSR */ | ||
725 | writel(fsr, cb_base + ARM_SMMU_CB_FSR); | ||
726 | 705 | ||
727 | /* Retry or terminate any stalled transactions */ | 706 | dev_err_ratelimited(smmu->dev, |
728 | if (fsr & FSR_SS) | 707 | "Unhandled context fault: fsr=0x%x, iova=0x%08lx, fsynr=0x%x, cb=%d\n", |
729 | writel_relaxed(resume, cb_base + ARM_SMMU_CB_RESUME); | 708 | fsr, iova, fsynr, cfg->cbndx); |
730 | 709 | ||
731 | return ret; | 710 | writel(fsr, cb_base + ARM_SMMU_CB_FSR); |
711 | return IRQ_HANDLED; | ||
732 | } | 712 | } |
733 | 713 | ||
734 | static irqreturn_t arm_smmu_global_fault(int irq, void *dev) | 714 | static irqreturn_t arm_smmu_global_fault(int irq, void *dev) |
@@ -837,7 +817,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, | |||
837 | } | 817 | } |
838 | 818 | ||
839 | /* SCTLR */ | 819 | /* SCTLR */ |
840 | reg = SCTLR_CFCFG | SCTLR_CFIE | SCTLR_CFRE | SCTLR_M | SCTLR_EAE_SBOP; | 820 | reg = SCTLR_CFIE | SCTLR_CFRE | SCTLR_M | SCTLR_EAE_SBOP; |
841 | if (stage1) | 821 | if (stage1) |
842 | reg |= SCTLR_S1_ASIDPNE; | 822 | reg |= SCTLR_S1_ASIDPNE; |
843 | #ifdef __BIG_ENDIAN | 823 | #ifdef __BIG_ENDIAN |
diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c index 8c6139986d7d..def8ca1c982d 100644 --- a/drivers/iommu/io-pgtable-arm-v7s.c +++ b/drivers/iommu/io-pgtable-arm-v7s.c | |||
@@ -286,12 +286,14 @@ static int arm_v7s_pte_to_prot(arm_v7s_iopte pte, int lvl) | |||
286 | int prot = IOMMU_READ; | 286 | int prot = IOMMU_READ; |
287 | arm_v7s_iopte attr = pte >> ARM_V7S_ATTR_SHIFT(lvl); | 287 | arm_v7s_iopte attr = pte >> ARM_V7S_ATTR_SHIFT(lvl); |
288 | 288 | ||
289 | if (attr & ARM_V7S_PTE_AP_RDONLY) | 289 | if (!(attr & ARM_V7S_PTE_AP_RDONLY)) |
290 | prot |= IOMMU_WRITE; | 290 | prot |= IOMMU_WRITE; |
291 | if ((attr & (ARM_V7S_TEX_MASK << ARM_V7S_TEX_SHIFT)) == 0) | 291 | if ((attr & (ARM_V7S_TEX_MASK << ARM_V7S_TEX_SHIFT)) == 0) |
292 | prot |= IOMMU_MMIO; | 292 | prot |= IOMMU_MMIO; |
293 | else if (pte & ARM_V7S_ATTR_C) | 293 | else if (pte & ARM_V7S_ATTR_C) |
294 | prot |= IOMMU_CACHE; | 294 | prot |= IOMMU_CACHE; |
295 | if (pte & ARM_V7S_ATTR_XN(lvl)) | ||
296 | prot |= IOMMU_NOEXEC; | ||
295 | 297 | ||
296 | return prot; | 298 | return prot; |
297 | } | 299 | } |
diff --git a/drivers/irqchip/irq-atmel-aic.c b/drivers/irqchip/irq-atmel-aic.c index 112e17c2768b..37f952dd9fc9 100644 --- a/drivers/irqchip/irq-atmel-aic.c +++ b/drivers/irqchip/irq-atmel-aic.c | |||
@@ -176,6 +176,7 @@ static int aic_irq_domain_xlate(struct irq_domain *d, | |||
176 | { | 176 | { |
177 | struct irq_domain_chip_generic *dgc = d->gc; | 177 | struct irq_domain_chip_generic *dgc = d->gc; |
178 | struct irq_chip_generic *gc; | 178 | struct irq_chip_generic *gc; |
179 | unsigned long flags; | ||
179 | unsigned smr; | 180 | unsigned smr; |
180 | int idx; | 181 | int idx; |
181 | int ret; | 182 | int ret; |
@@ -194,11 +195,11 @@ static int aic_irq_domain_xlate(struct irq_domain *d, | |||
194 | 195 | ||
195 | gc = dgc->gc[idx]; | 196 | gc = dgc->gc[idx]; |
196 | 197 | ||
197 | irq_gc_lock(gc); | 198 | irq_gc_lock_irqsave(gc, flags); |
198 | smr = irq_reg_readl(gc, AT91_AIC_SMR(*out_hwirq)); | 199 | smr = irq_reg_readl(gc, AT91_AIC_SMR(*out_hwirq)); |
199 | aic_common_set_priority(intspec[2], &smr); | 200 | aic_common_set_priority(intspec[2], &smr); |
200 | irq_reg_writel(gc, smr, AT91_AIC_SMR(*out_hwirq)); | 201 | irq_reg_writel(gc, smr, AT91_AIC_SMR(*out_hwirq)); |
201 | irq_gc_unlock(gc); | 202 | irq_gc_unlock_irqrestore(gc, flags); |
202 | 203 | ||
203 | return ret; | 204 | return ret; |
204 | } | 205 | } |
diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c index 4f0d068e1abe..2a624d87a035 100644 --- a/drivers/irqchip/irq-atmel-aic5.c +++ b/drivers/irqchip/irq-atmel-aic5.c | |||
@@ -258,6 +258,7 @@ static int aic5_irq_domain_xlate(struct irq_domain *d, | |||
258 | unsigned int *out_type) | 258 | unsigned int *out_type) |
259 | { | 259 | { |
260 | struct irq_chip_generic *bgc = irq_get_domain_generic_chip(d, 0); | 260 | struct irq_chip_generic *bgc = irq_get_domain_generic_chip(d, 0); |
261 | unsigned long flags; | ||
261 | unsigned smr; | 262 | unsigned smr; |
262 | int ret; | 263 | int ret; |
263 | 264 | ||
@@ -269,12 +270,12 @@ static int aic5_irq_domain_xlate(struct irq_domain *d, | |||
269 | if (ret) | 270 | if (ret) |
270 | return ret; | 271 | return ret; |
271 | 272 | ||
272 | irq_gc_lock(bgc); | 273 | irq_gc_lock_irqsave(bgc, flags); |
273 | irq_reg_writel(bgc, *out_hwirq, AT91_AIC5_SSR); | 274 | irq_reg_writel(bgc, *out_hwirq, AT91_AIC5_SSR); |
274 | smr = irq_reg_readl(bgc, AT91_AIC5_SMR); | 275 | smr = irq_reg_readl(bgc, AT91_AIC5_SMR); |
275 | aic_common_set_priority(intspec[2], &smr); | 276 | aic_common_set_priority(intspec[2], &smr); |
276 | irq_reg_writel(bgc, smr, AT91_AIC5_SMR); | 277 | irq_reg_writel(bgc, smr, AT91_AIC5_SMR); |
277 | irq_gc_unlock(bgc); | 278 | irq_gc_unlock_irqrestore(bgc, flags); |
278 | 279 | ||
279 | return ret; | 280 | return ret; |
280 | } | 281 | } |
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 7ceaba81efb4..36b9c28a5c91 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c | |||
@@ -1545,7 +1545,12 @@ static int its_force_quiescent(void __iomem *base) | |||
1545 | u32 val; | 1545 | u32 val; |
1546 | 1546 | ||
1547 | val = readl_relaxed(base + GITS_CTLR); | 1547 | val = readl_relaxed(base + GITS_CTLR); |
1548 | if (val & GITS_CTLR_QUIESCENT) | 1548 | /* |
1549 | * GIC architecture specification requires the ITS to be both | ||
1550 | * disabled and quiescent for writes to GITS_BASER<n> or | ||
1551 | * GITS_CBASER to not have UNPREDICTABLE results. | ||
1552 | */ | ||
1553 | if ((val & GITS_CTLR_QUIESCENT) && !(val & GITS_CTLR_ENABLE)) | ||
1549 | return 0; | 1554 | return 0; |
1550 | 1555 | ||
1551 | /* Disable the generation of all interrupts to this ITS */ | 1556 | /* Disable the generation of all interrupts to this ITS */ |
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 6fc56c3466b0..da6c0ba61d4f 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c | |||
@@ -548,7 +548,7 @@ static int gic_starting_cpu(unsigned int cpu) | |||
548 | static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask, | 548 | static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask, |
549 | unsigned long cluster_id) | 549 | unsigned long cluster_id) |
550 | { | 550 | { |
551 | int cpu = *base_cpu; | 551 | int next_cpu, cpu = *base_cpu; |
552 | unsigned long mpidr = cpu_logical_map(cpu); | 552 | unsigned long mpidr = cpu_logical_map(cpu); |
553 | u16 tlist = 0; | 553 | u16 tlist = 0; |
554 | 554 | ||
@@ -562,9 +562,10 @@ static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask, | |||
562 | 562 | ||
563 | tlist |= 1 << (mpidr & 0xf); | 563 | tlist |= 1 << (mpidr & 0xf); |
564 | 564 | ||
565 | cpu = cpumask_next(cpu, mask); | 565 | next_cpu = cpumask_next(cpu, mask); |
566 | if (cpu >= nr_cpu_ids) | 566 | if (next_cpu >= nr_cpu_ids) |
567 | goto out; | 567 | goto out; |
568 | cpu = next_cpu; | ||
568 | 569 | ||
569 | mpidr = cpu_logical_map(cpu); | 570 | mpidr = cpu_logical_map(cpu); |
570 | 571 | ||
@@ -667,13 +668,20 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, | |||
667 | #endif | 668 | #endif |
668 | 669 | ||
669 | #ifdef CONFIG_CPU_PM | 670 | #ifdef CONFIG_CPU_PM |
671 | /* Check whether it's single security state view */ | ||
672 | static bool gic_dist_security_disabled(void) | ||
673 | { | ||
674 | return readl_relaxed(gic_data.dist_base + GICD_CTLR) & GICD_CTLR_DS; | ||
675 | } | ||
676 | |||
670 | static int gic_cpu_pm_notifier(struct notifier_block *self, | 677 | static int gic_cpu_pm_notifier(struct notifier_block *self, |
671 | unsigned long cmd, void *v) | 678 | unsigned long cmd, void *v) |
672 | { | 679 | { |
673 | if (cmd == CPU_PM_EXIT) { | 680 | if (cmd == CPU_PM_EXIT) { |
674 | gic_enable_redist(true); | 681 | if (gic_dist_security_disabled()) |
682 | gic_enable_redist(true); | ||
675 | gic_cpu_sys_reg_init(); | 683 | gic_cpu_sys_reg_init(); |
676 | } else if (cmd == CPU_PM_ENTER) { | 684 | } else if (cmd == CPU_PM_ENTER && gic_dist_security_disabled()) { |
677 | gic_write_grpen1(0); | 685 | gic_write_grpen1(0); |
678 | gic_enable_redist(false); | 686 | gic_enable_redist(false); |
679 | } | 687 | } |
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index c2cab572c511..390fac59c6bc 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c | |||
@@ -769,6 +769,13 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) | |||
769 | int cpu; | 769 | int cpu; |
770 | unsigned long flags, map = 0; | 770 | unsigned long flags, map = 0; |
771 | 771 | ||
772 | if (unlikely(nr_cpu_ids == 1)) { | ||
773 | /* Only one CPU? let's do a self-IPI... */ | ||
774 | writel_relaxed(2 << 24 | irq, | ||
775 | gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); | ||
776 | return; | ||
777 | } | ||
778 | |||
772 | raw_spin_lock_irqsave(&irq_controller_lock, flags); | 779 | raw_spin_lock_irqsave(&irq_controller_lock, flags); |
773 | 780 | ||
774 | /* Convert our logical CPU mask into a physical one. */ | 781 | /* Convert our logical CPU mask into a physical one. */ |
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index c5f33c3bd228..6185696405d5 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c | |||
@@ -638,27 +638,6 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq, | |||
638 | if (!gic_local_irq_is_routable(intr)) | 638 | if (!gic_local_irq_is_routable(intr)) |
639 | return -EPERM; | 639 | return -EPERM; |
640 | 640 | ||
641 | /* | ||
642 | * HACK: These are all really percpu interrupts, but the rest | ||
643 | * of the MIPS kernel code does not use the percpu IRQ API for | ||
644 | * the CP0 timer and performance counter interrupts. | ||
645 | */ | ||
646 | switch (intr) { | ||
647 | case GIC_LOCAL_INT_TIMER: | ||
648 | case GIC_LOCAL_INT_PERFCTR: | ||
649 | case GIC_LOCAL_INT_FDC: | ||
650 | irq_set_chip_and_handler(virq, | ||
651 | &gic_all_vpes_local_irq_controller, | ||
652 | handle_percpu_irq); | ||
653 | break; | ||
654 | default: | ||
655 | irq_set_chip_and_handler(virq, | ||
656 | &gic_local_irq_controller, | ||
657 | handle_percpu_devid_irq); | ||
658 | irq_set_percpu_devid(virq); | ||
659 | break; | ||
660 | } | ||
661 | |||
662 | spin_lock_irqsave(&gic_lock, flags); | 641 | spin_lock_irqsave(&gic_lock, flags); |
663 | for (i = 0; i < gic_vpes; i++) { | 642 | for (i = 0; i < gic_vpes; i++) { |
664 | u32 val = GIC_MAP_TO_PIN_MSK | gic_cpu_pin; | 643 | u32 val = GIC_MAP_TO_PIN_MSK | gic_cpu_pin; |
@@ -713,9 +692,6 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, | |||
713 | unsigned long flags; | 692 | unsigned long flags; |
714 | int i; | 693 | int i; |
715 | 694 | ||
716 | irq_set_chip_and_handler(virq, &gic_level_irq_controller, | ||
717 | handle_level_irq); | ||
718 | |||
719 | spin_lock_irqsave(&gic_lock, flags); | 695 | spin_lock_irqsave(&gic_lock, flags); |
720 | gic_map_to_pin(intr, gic_cpu_pin); | 696 | gic_map_to_pin(intr, gic_cpu_pin); |
721 | gic_map_to_vpe(intr, mips_cm_vp_id(vpe)); | 697 | gic_map_to_vpe(intr, mips_cm_vp_id(vpe)); |
@@ -727,12 +703,42 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, | |||
727 | return 0; | 703 | return 0; |
728 | } | 704 | } |
729 | 705 | ||
730 | static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, | 706 | static int gic_setup_dev_chip(struct irq_domain *d, unsigned int virq, |
731 | irq_hw_number_t hw) | 707 | unsigned int hwirq) |
732 | { | 708 | { |
733 | if (GIC_HWIRQ_TO_LOCAL(hw) < GIC_NUM_LOCAL_INTRS) | 709 | struct irq_chip *chip; |
734 | return gic_local_irq_domain_map(d, virq, hw); | 710 | int err; |
735 | return gic_shared_irq_domain_map(d, virq, hw, 0); | 711 | |
712 | if (hwirq >= GIC_SHARED_HWIRQ_BASE) { | ||
713 | err = irq_domain_set_hwirq_and_chip(d, virq, hwirq, | ||
714 | &gic_level_irq_controller, | ||
715 | NULL); | ||
716 | } else { | ||
717 | switch (GIC_HWIRQ_TO_LOCAL(hwirq)) { | ||
718 | case GIC_LOCAL_INT_TIMER: | ||
719 | case GIC_LOCAL_INT_PERFCTR: | ||
720 | case GIC_LOCAL_INT_FDC: | ||
721 | /* | ||
722 | * HACK: These are all really percpu interrupts, but | ||
723 | * the rest of the MIPS kernel code does not use the | ||
724 | * percpu IRQ API for them. | ||
725 | */ | ||
726 | chip = &gic_all_vpes_local_irq_controller; | ||
727 | irq_set_handler(virq, handle_percpu_irq); | ||
728 | break; | ||
729 | |||
730 | default: | ||
731 | chip = &gic_local_irq_controller; | ||
732 | irq_set_handler(virq, handle_percpu_devid_irq); | ||
733 | irq_set_percpu_devid(virq); | ||
734 | break; | ||
735 | } | ||
736 | |||
737 | err = irq_domain_set_hwirq_and_chip(d, virq, hwirq, | ||
738 | chip, NULL); | ||
739 | } | ||
740 | |||
741 | return err; | ||
736 | } | 742 | } |
737 | 743 | ||
738 | static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq, | 744 | static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq, |
@@ -743,15 +749,12 @@ static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq, | |||
743 | int cpu, ret, i; | 749 | int cpu, ret, i; |
744 | 750 | ||
745 | if (spec->type == GIC_DEVICE) { | 751 | if (spec->type == GIC_DEVICE) { |
746 | /* verify that it doesn't conflict with an IPI irq */ | 752 | /* verify that shared irqs don't conflict with an IPI irq */ |
747 | if (test_bit(spec->hwirq, ipi_resrv)) | 753 | if ((spec->hwirq >= GIC_SHARED_HWIRQ_BASE) && |
754 | test_bit(GIC_HWIRQ_TO_SHARED(spec->hwirq), ipi_resrv)) | ||
748 | return -EBUSY; | 755 | return -EBUSY; |
749 | 756 | ||
750 | hwirq = GIC_SHARED_TO_HWIRQ(spec->hwirq); | 757 | return gic_setup_dev_chip(d, virq, spec->hwirq); |
751 | |||
752 | return irq_domain_set_hwirq_and_chip(d, virq, hwirq, | ||
753 | &gic_level_irq_controller, | ||
754 | NULL); | ||
755 | } else { | 758 | } else { |
756 | base_hwirq = find_first_bit(ipi_resrv, gic_shared_intrs); | 759 | base_hwirq = find_first_bit(ipi_resrv, gic_shared_intrs); |
757 | if (base_hwirq == gic_shared_intrs) { | 760 | if (base_hwirq == gic_shared_intrs) { |
@@ -771,11 +774,13 @@ static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq, | |||
771 | hwirq = GIC_SHARED_TO_HWIRQ(base_hwirq + i); | 774 | hwirq = GIC_SHARED_TO_HWIRQ(base_hwirq + i); |
772 | 775 | ||
773 | ret = irq_domain_set_hwirq_and_chip(d, virq + i, hwirq, | 776 | ret = irq_domain_set_hwirq_and_chip(d, virq + i, hwirq, |
774 | &gic_edge_irq_controller, | 777 | &gic_level_irq_controller, |
775 | NULL); | 778 | NULL); |
776 | if (ret) | 779 | if (ret) |
777 | goto error; | 780 | goto error; |
778 | 781 | ||
782 | irq_set_handler(virq + i, handle_level_irq); | ||
783 | |||
779 | ret = gic_shared_irq_domain_map(d, virq + i, hwirq, cpu); | 784 | ret = gic_shared_irq_domain_map(d, virq + i, hwirq, cpu); |
780 | if (ret) | 785 | if (ret) |
781 | goto error; | 786 | goto error; |
@@ -818,7 +823,6 @@ int gic_irq_domain_match(struct irq_domain *d, struct device_node *node, | |||
818 | } | 823 | } |
819 | 824 | ||
820 | static const struct irq_domain_ops gic_irq_domain_ops = { | 825 | static const struct irq_domain_ops gic_irq_domain_ops = { |
821 | .map = gic_irq_domain_map, | ||
822 | .alloc = gic_irq_domain_alloc, | 826 | .alloc = gic_irq_domain_alloc, |
823 | .free = gic_irq_domain_free, | 827 | .free = gic_irq_domain_free, |
824 | .match = gic_irq_domain_match, | 828 | .match = gic_irq_domain_match, |
@@ -849,29 +853,20 @@ static int gic_dev_domain_alloc(struct irq_domain *d, unsigned int virq, | |||
849 | struct irq_fwspec *fwspec = arg; | 853 | struct irq_fwspec *fwspec = arg; |
850 | struct gic_irq_spec spec = { | 854 | struct gic_irq_spec spec = { |
851 | .type = GIC_DEVICE, | 855 | .type = GIC_DEVICE, |
852 | .hwirq = fwspec->param[1], | ||
853 | }; | 856 | }; |
854 | int i, ret; | 857 | int i, ret; |
855 | bool is_shared = fwspec->param[0] == GIC_SHARED; | ||
856 | 858 | ||
857 | if (is_shared) { | 859 | if (fwspec->param[0] == GIC_SHARED) |
858 | ret = irq_domain_alloc_irqs_parent(d, virq, nr_irqs, &spec); | 860 | spec.hwirq = GIC_SHARED_TO_HWIRQ(fwspec->param[1]); |
859 | if (ret) | 861 | else |
860 | return ret; | 862 | spec.hwirq = GIC_LOCAL_TO_HWIRQ(fwspec->param[1]); |
861 | } | ||
862 | |||
863 | for (i = 0; i < nr_irqs; i++) { | ||
864 | irq_hw_number_t hwirq; | ||
865 | 863 | ||
866 | if (is_shared) | 864 | ret = irq_domain_alloc_irqs_parent(d, virq, nr_irqs, &spec); |
867 | hwirq = GIC_SHARED_TO_HWIRQ(spec.hwirq + i); | 865 | if (ret) |
868 | else | 866 | return ret; |
869 | hwirq = GIC_LOCAL_TO_HWIRQ(spec.hwirq + i); | ||
870 | 867 | ||
871 | ret = irq_domain_set_hwirq_and_chip(d, virq + i, | 868 | for (i = 0; i < nr_irqs; i++) { |
872 | hwirq, | 869 | ret = gic_setup_dev_chip(d, virq + i, spec.hwirq + i); |
873 | &gic_level_irq_controller, | ||
874 | NULL); | ||
875 | if (ret) | 870 | if (ret) |
876 | goto error; | 871 | goto error; |
877 | } | 872 | } |
@@ -890,10 +885,20 @@ void gic_dev_domain_free(struct irq_domain *d, unsigned int virq, | |||
890 | return; | 885 | return; |
891 | } | 886 | } |
892 | 887 | ||
888 | static void gic_dev_domain_activate(struct irq_domain *domain, | ||
889 | struct irq_data *d) | ||
890 | { | ||
891 | if (GIC_HWIRQ_TO_LOCAL(d->hwirq) < GIC_NUM_LOCAL_INTRS) | ||
892 | gic_local_irq_domain_map(domain, d->irq, d->hwirq); | ||
893 | else | ||
894 | gic_shared_irq_domain_map(domain, d->irq, d->hwirq, 0); | ||
895 | } | ||
896 | |||
893 | static struct irq_domain_ops gic_dev_domain_ops = { | 897 | static struct irq_domain_ops gic_dev_domain_ops = { |
894 | .xlate = gic_dev_domain_xlate, | 898 | .xlate = gic_dev_domain_xlate, |
895 | .alloc = gic_dev_domain_alloc, | 899 | .alloc = gic_dev_domain_alloc, |
896 | .free = gic_dev_domain_free, | 900 | .free = gic_dev_domain_free, |
901 | .activate = gic_dev_domain_activate, | ||
897 | }; | 902 | }; |
898 | 903 | ||
899 | static int gic_ipi_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, | 904 | static int gic_ipi_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, |
diff --git a/drivers/macintosh/ams/ams-i2c.c b/drivers/macintosh/ams/ams-i2c.c index 978eda8d6678..8a3ba565106f 100644 --- a/drivers/macintosh/ams/ams-i2c.c +++ b/drivers/macintosh/ams/ams-i2c.c | |||
@@ -73,7 +73,6 @@ MODULE_DEVICE_TABLE(i2c, ams_id); | |||
73 | static struct i2c_driver ams_i2c_driver = { | 73 | static struct i2c_driver ams_i2c_driver = { |
74 | .driver = { | 74 | .driver = { |
75 | .name = "ams", | 75 | .name = "ams", |
76 | .owner = THIS_MODULE, | ||
77 | }, | 76 | }, |
78 | .probe = ams_i2c_probe, | 77 | .probe = ams_i2c_probe, |
79 | .remove = ams_i2c_remove, | 78 | .remove = ams_i2c_remove, |
diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c index 3024685e4cca..96d16fca68b2 100644 --- a/drivers/macintosh/windfarm_pm112.c +++ b/drivers/macintosh/windfarm_pm112.c | |||
@@ -668,7 +668,6 @@ static struct platform_driver wf_pm112_driver = { | |||
668 | .remove = wf_pm112_remove, | 668 | .remove = wf_pm112_remove, |
669 | .driver = { | 669 | .driver = { |
670 | .name = "windfarm", | 670 | .name = "windfarm", |
671 | .owner = THIS_MODULE, | ||
672 | }, | 671 | }, |
673 | }; | 672 | }; |
674 | 673 | ||
diff --git a/drivers/macintosh/windfarm_pm72.c b/drivers/macintosh/windfarm_pm72.c index 2f506b9d5a52..e88cfb36a74d 100644 --- a/drivers/macintosh/windfarm_pm72.c +++ b/drivers/macintosh/windfarm_pm72.c | |||
@@ -789,7 +789,6 @@ static struct platform_driver wf_pm72_driver = { | |||
789 | .remove = wf_pm72_remove, | 789 | .remove = wf_pm72_remove, |
790 | .driver = { | 790 | .driver = { |
791 | .name = "windfarm", | 791 | .name = "windfarm", |
792 | .owner = THIS_MODULE, | ||
793 | }, | 792 | }, |
794 | }; | 793 | }; |
795 | 794 | ||
diff --git a/drivers/macintosh/windfarm_rm31.c b/drivers/macintosh/windfarm_rm31.c index 82fc86a90c1a..bdfcb8a8bfbb 100644 --- a/drivers/macintosh/windfarm_rm31.c +++ b/drivers/macintosh/windfarm_rm31.c | |||
@@ -682,7 +682,6 @@ static struct platform_driver wf_rm31_driver = { | |||
682 | .remove = wf_rm31_remove, | 682 | .remove = wf_rm31_remove, |
683 | .driver = { | 683 | .driver = { |
684 | .name = "windfarm", | 684 | .name = "windfarm", |
685 | .owner = THIS_MODULE, | ||
686 | }, | 685 | }, |
687 | }; | 686 | }; |
688 | 687 | ||
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index 97c372908e78..7817d40d81e7 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig | |||
@@ -127,6 +127,7 @@ config XGENE_SLIMPRO_MBOX | |||
127 | config BCM_PDC_MBOX | 127 | config BCM_PDC_MBOX |
128 | tristate "Broadcom PDC Mailbox" | 128 | tristate "Broadcom PDC Mailbox" |
129 | depends on ARM64 || COMPILE_TEST | 129 | depends on ARM64 || COMPILE_TEST |
130 | depends on HAS_DMA | ||
130 | default ARCH_BCM_IPROC | 131 | default ARCH_BCM_IPROC |
131 | help | 132 | help |
132 | Mailbox implementation for the Broadcom PDC ring manager, | 133 | Mailbox implementation for the Broadcom PDC ring manager, |
diff --git a/drivers/mailbox/bcm-pdc-mailbox.c b/drivers/mailbox/bcm-pdc-mailbox.c index cbe0c1ee4ba9..c19dd820ea9b 100644 --- a/drivers/mailbox/bcm-pdc-mailbox.c +++ b/drivers/mailbox/bcm-pdc-mailbox.c | |||
@@ -469,7 +469,7 @@ static const struct file_operations pdc_debugfs_stats = { | |||
469 | * this directory for a SPU. | 469 | * this directory for a SPU. |
470 | * @pdcs: PDC state structure | 470 | * @pdcs: PDC state structure |
471 | */ | 471 | */ |
472 | void pdc_setup_debugfs(struct pdc_state *pdcs) | 472 | static void pdc_setup_debugfs(struct pdc_state *pdcs) |
473 | { | 473 | { |
474 | char spu_stats_name[16]; | 474 | char spu_stats_name[16]; |
475 | 475 | ||
@@ -485,7 +485,7 @@ void pdc_setup_debugfs(struct pdc_state *pdcs) | |||
485 | &pdc_debugfs_stats); | 485 | &pdc_debugfs_stats); |
486 | } | 486 | } |
487 | 487 | ||
488 | void pdc_free_debugfs(void) | 488 | static void pdc_free_debugfs(void) |
489 | { | 489 | { |
490 | if (debugfs_dir && simple_empty(debugfs_dir)) { | 490 | if (debugfs_dir && simple_empty(debugfs_dir)) { |
491 | debugfs_remove_recursive(debugfs_dir); | 491 | debugfs_remove_recursive(debugfs_dir); |
@@ -1191,10 +1191,11 @@ static void pdc_shutdown(struct mbox_chan *chan) | |||
1191 | { | 1191 | { |
1192 | struct pdc_state *pdcs = chan->con_priv; | 1192 | struct pdc_state *pdcs = chan->con_priv; |
1193 | 1193 | ||
1194 | if (pdcs) | 1194 | if (!pdcs) |
1195 | dev_dbg(&pdcs->pdev->dev, | 1195 | return; |
1196 | "Shutdown mailbox channel for PDC %u", pdcs->pdc_idx); | ||
1197 | 1196 | ||
1197 | dev_dbg(&pdcs->pdev->dev, | ||
1198 | "Shutdown mailbox channel for PDC %u", pdcs->pdc_idx); | ||
1198 | pdc_ring_free(pdcs); | 1199 | pdc_ring_free(pdcs); |
1199 | } | 1200 | } |
1200 | 1201 | ||
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 95a4ca6ce6ff..849ad441cd76 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c | |||
@@ -760,7 +760,8 @@ static int bcache_device_init(struct bcache_device *d, unsigned block_size, | |||
760 | if (!d->nr_stripes || | 760 | if (!d->nr_stripes || |
761 | d->nr_stripes > INT_MAX || | 761 | d->nr_stripes > INT_MAX || |
762 | d->nr_stripes > SIZE_MAX / sizeof(atomic_t)) { | 762 | d->nr_stripes > SIZE_MAX / sizeof(atomic_t)) { |
763 | pr_err("nr_stripes too large"); | 763 | pr_err("nr_stripes too large or invalid: %u (start sector beyond end of disk?)", |
764 | (unsigned)d->nr_stripes); | ||
764 | return -ENOMEM; | 765 | return -ENOMEM; |
765 | } | 766 | } |
766 | 767 | ||
@@ -1820,7 +1821,7 @@ static int cache_alloc(struct cache *ca) | |||
1820 | free = roundup_pow_of_two(ca->sb.nbuckets) >> 10; | 1821 | free = roundup_pow_of_two(ca->sb.nbuckets) >> 10; |
1821 | 1822 | ||
1822 | if (!init_fifo(&ca->free[RESERVE_BTREE], 8, GFP_KERNEL) || | 1823 | if (!init_fifo(&ca->free[RESERVE_BTREE], 8, GFP_KERNEL) || |
1823 | !init_fifo(&ca->free[RESERVE_PRIO], prio_buckets(ca), GFP_KERNEL) || | 1824 | !init_fifo_exact(&ca->free[RESERVE_PRIO], prio_buckets(ca), GFP_KERNEL) || |
1824 | !init_fifo(&ca->free[RESERVE_MOVINGGC], free, GFP_KERNEL) || | 1825 | !init_fifo(&ca->free[RESERVE_MOVINGGC], free, GFP_KERNEL) || |
1825 | !init_fifo(&ca->free[RESERVE_NONE], free, GFP_KERNEL) || | 1826 | !init_fifo(&ca->free[RESERVE_NONE], free, GFP_KERNEL) || |
1826 | !init_fifo(&ca->free_inc, free << 2, GFP_KERNEL) || | 1827 | !init_fifo(&ca->free_inc, free << 2, GFP_KERNEL) || |
@@ -1844,7 +1845,7 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page, | |||
1844 | struct block_device *bdev, struct cache *ca) | 1845 | struct block_device *bdev, struct cache *ca) |
1845 | { | 1846 | { |
1846 | char name[BDEVNAME_SIZE]; | 1847 | char name[BDEVNAME_SIZE]; |
1847 | const char *err = NULL; | 1848 | const char *err = NULL; /* must be set for any error case */ |
1848 | int ret = 0; | 1849 | int ret = 0; |
1849 | 1850 | ||
1850 | memcpy(&ca->sb, sb, sizeof(struct cache_sb)); | 1851 | memcpy(&ca->sb, sb, sizeof(struct cache_sb)); |
@@ -1861,8 +1862,13 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page, | |||
1861 | ca->discard = CACHE_DISCARD(&ca->sb); | 1862 | ca->discard = CACHE_DISCARD(&ca->sb); |
1862 | 1863 | ||
1863 | ret = cache_alloc(ca); | 1864 | ret = cache_alloc(ca); |
1864 | if (ret != 0) | 1865 | if (ret != 0) { |
1866 | if (ret == -ENOMEM) | ||
1867 | err = "cache_alloc(): -ENOMEM"; | ||
1868 | else | ||
1869 | err = "cache_alloc(): unknown error"; | ||
1865 | goto err; | 1870 | goto err; |
1871 | } | ||
1866 | 1872 | ||
1867 | if (kobject_add(&ca->kobj, &part_to_dev(bdev->bd_part)->kobj, "bcache")) { | 1873 | if (kobject_add(&ca->kobj, &part_to_dev(bdev->bd_part)->kobj, "bcache")) { |
1868 | err = "error calling kobject_add"; | 1874 | err = "error calling kobject_add"; |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 6fff794e0c72..13041ee37ad6 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -2183,19 +2183,29 @@ location_show(struct mddev *mddev, char *page) | |||
2183 | static ssize_t | 2183 | static ssize_t |
2184 | location_store(struct mddev *mddev, const char *buf, size_t len) | 2184 | location_store(struct mddev *mddev, const char *buf, size_t len) |
2185 | { | 2185 | { |
2186 | int rv; | ||
2186 | 2187 | ||
2188 | rv = mddev_lock(mddev); | ||
2189 | if (rv) | ||
2190 | return rv; | ||
2187 | if (mddev->pers) { | 2191 | if (mddev->pers) { |
2188 | if (!mddev->pers->quiesce) | 2192 | if (!mddev->pers->quiesce) { |
2189 | return -EBUSY; | 2193 | rv = -EBUSY; |
2190 | if (mddev->recovery || mddev->sync_thread) | 2194 | goto out; |
2191 | return -EBUSY; | 2195 | } |
2196 | if (mddev->recovery || mddev->sync_thread) { | ||
2197 | rv = -EBUSY; | ||
2198 | goto out; | ||
2199 | } | ||
2192 | } | 2200 | } |
2193 | 2201 | ||
2194 | if (mddev->bitmap || mddev->bitmap_info.file || | 2202 | if (mddev->bitmap || mddev->bitmap_info.file || |
2195 | mddev->bitmap_info.offset) { | 2203 | mddev->bitmap_info.offset) { |
2196 | /* bitmap already configured. Only option is to clear it */ | 2204 | /* bitmap already configured. Only option is to clear it */ |
2197 | if (strncmp(buf, "none", 4) != 0) | 2205 | if (strncmp(buf, "none", 4) != 0) { |
2198 | return -EBUSY; | 2206 | rv = -EBUSY; |
2207 | goto out; | ||
2208 | } | ||
2199 | if (mddev->pers) { | 2209 | if (mddev->pers) { |
2200 | mddev->pers->quiesce(mddev, 1); | 2210 | mddev->pers->quiesce(mddev, 1); |
2201 | bitmap_destroy(mddev); | 2211 | bitmap_destroy(mddev); |
@@ -2214,21 +2224,25 @@ location_store(struct mddev *mddev, const char *buf, size_t len) | |||
2214 | /* nothing to be done */; | 2224 | /* nothing to be done */; |
2215 | else if (strncmp(buf, "file:", 5) == 0) { | 2225 | else if (strncmp(buf, "file:", 5) == 0) { |
2216 | /* Not supported yet */ | 2226 | /* Not supported yet */ |
2217 | return -EINVAL; | 2227 | rv = -EINVAL; |
2228 | goto out; | ||
2218 | } else { | 2229 | } else { |
2219 | int rv; | ||
2220 | if (buf[0] == '+') | 2230 | if (buf[0] == '+') |
2221 | rv = kstrtoll(buf+1, 10, &offset); | 2231 | rv = kstrtoll(buf+1, 10, &offset); |
2222 | else | 2232 | else |
2223 | rv = kstrtoll(buf, 10, &offset); | 2233 | rv = kstrtoll(buf, 10, &offset); |
2224 | if (rv) | 2234 | if (rv) |
2225 | return rv; | 2235 | goto out; |
2226 | if (offset == 0) | 2236 | if (offset == 0) { |
2227 | return -EINVAL; | 2237 | rv = -EINVAL; |
2238 | goto out; | ||
2239 | } | ||
2228 | if (mddev->bitmap_info.external == 0 && | 2240 | if (mddev->bitmap_info.external == 0 && |
2229 | mddev->major_version == 0 && | 2241 | mddev->major_version == 0 && |
2230 | offset != mddev->bitmap_info.default_offset) | 2242 | offset != mddev->bitmap_info.default_offset) { |
2231 | return -EINVAL; | 2243 | rv = -EINVAL; |
2244 | goto out; | ||
2245 | } | ||
2232 | mddev->bitmap_info.offset = offset; | 2246 | mddev->bitmap_info.offset = offset; |
2233 | if (mddev->pers) { | 2247 | if (mddev->pers) { |
2234 | struct bitmap *bitmap; | 2248 | struct bitmap *bitmap; |
@@ -2245,7 +2259,7 @@ location_store(struct mddev *mddev, const char *buf, size_t len) | |||
2245 | mddev->pers->quiesce(mddev, 0); | 2259 | mddev->pers->quiesce(mddev, 0); |
2246 | if (rv) { | 2260 | if (rv) { |
2247 | bitmap_destroy(mddev); | 2261 | bitmap_destroy(mddev); |
2248 | return rv; | 2262 | goto out; |
2249 | } | 2263 | } |
2250 | } | 2264 | } |
2251 | } | 2265 | } |
@@ -2257,6 +2271,11 @@ location_store(struct mddev *mddev, const char *buf, size_t len) | |||
2257 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 2271 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
2258 | md_wakeup_thread(mddev->thread); | 2272 | md_wakeup_thread(mddev->thread); |
2259 | } | 2273 | } |
2274 | rv = 0; | ||
2275 | out: | ||
2276 | mddev_unlock(mddev); | ||
2277 | if (rv) | ||
2278 | return rv; | ||
2260 | return len; | 2279 | return len; |
2261 | } | 2280 | } |
2262 | 2281 | ||
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c index 6571c81465e1..8625040bae92 100644 --- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c | |||
@@ -1879,7 +1879,7 @@ static int __init dm_bufio_init(void) | |||
1879 | __cache_size_refresh(); | 1879 | __cache_size_refresh(); |
1880 | mutex_unlock(&dm_bufio_clients_lock); | 1880 | mutex_unlock(&dm_bufio_clients_lock); |
1881 | 1881 | ||
1882 | dm_bufio_wq = create_singlethread_workqueue("dm_bufio_cache"); | 1882 | dm_bufio_wq = alloc_workqueue("dm_bufio_cache", WQ_MEM_RECLAIM, 0); |
1883 | if (!dm_bufio_wq) | 1883 | if (!dm_bufio_wq) |
1884 | return -ENOMEM; | 1884 | return -ENOMEM; |
1885 | 1885 | ||
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index eedba67b0e3e..874295757caa 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -1453,7 +1453,7 @@ static int crypt_alloc_tfms(struct crypt_config *cc, char *ciphermode) | |||
1453 | unsigned i; | 1453 | unsigned i; |
1454 | int err; | 1454 | int err; |
1455 | 1455 | ||
1456 | cc->tfms = kmalloc(cc->tfms_count * sizeof(struct crypto_skcipher *), | 1456 | cc->tfms = kzalloc(cc->tfms_count * sizeof(struct crypto_skcipher *), |
1457 | GFP_KERNEL); | 1457 | GFP_KERNEL); |
1458 | if (!cc->tfms) | 1458 | if (!cc->tfms) |
1459 | return -ENOMEM; | 1459 | return -ENOMEM; |
@@ -1924,6 +1924,13 @@ static int crypt_map(struct dm_target *ti, struct bio *bio) | |||
1924 | return DM_MAPIO_REMAPPED; | 1924 | return DM_MAPIO_REMAPPED; |
1925 | } | 1925 | } |
1926 | 1926 | ||
1927 | /* | ||
1928 | * Check if bio is too large, split as needed. | ||
1929 | */ | ||
1930 | if (unlikely(bio->bi_iter.bi_size > (BIO_MAX_PAGES << PAGE_SHIFT)) && | ||
1931 | bio_data_dir(bio) == WRITE) | ||
1932 | dm_accept_partial_bio(bio, ((BIO_MAX_PAGES << PAGE_SHIFT) >> SECTOR_SHIFT)); | ||
1933 | |||
1927 | io = dm_per_bio_data(bio, cc->per_bio_data_size); | 1934 | io = dm_per_bio_data(bio, cc->per_bio_data_size); |
1928 | crypt_io_init(io, cc, bio, dm_target_offset(ti, bio->bi_iter.bi_sector)); | 1935 | crypt_io_init(io, cc, bio, dm_target_offset(ti, bio->bi_iter.bi_sector)); |
1929 | io->ctx.req = (struct skcipher_request *)(io + 1); | 1936 | io->ctx.req = (struct skcipher_request *)(io + 1); |
diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index 97e446d54a15..6a2e8dd44a1b 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c | |||
@@ -289,15 +289,13 @@ static int flakey_map(struct dm_target *ti, struct bio *bio) | |||
289 | pb->bio_submitted = true; | 289 | pb->bio_submitted = true; |
290 | 290 | ||
291 | /* | 291 | /* |
292 | * Map reads as normal only if corrupt_bio_byte set. | 292 | * Error reads if neither corrupt_bio_byte or drop_writes are set. |
293 | * Otherwise, flakey_end_io() will decide if the reads should be modified. | ||
293 | */ | 294 | */ |
294 | if (bio_data_dir(bio) == READ) { | 295 | if (bio_data_dir(bio) == READ) { |
295 | /* If flags were specified, only corrupt those that match. */ | 296 | if (!fc->corrupt_bio_byte && !test_bit(DROP_WRITES, &fc->flags)) |
296 | if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == READ) && | ||
297 | all_corrupt_bio_flags_match(bio, fc)) | ||
298 | goto map_bio; | ||
299 | else | ||
300 | return -EIO; | 297 | return -EIO; |
298 | goto map_bio; | ||
301 | } | 299 | } |
302 | 300 | ||
303 | /* | 301 | /* |
@@ -334,14 +332,21 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio, int error) | |||
334 | struct flakey_c *fc = ti->private; | 332 | struct flakey_c *fc = ti->private; |
335 | struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data)); | 333 | struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data)); |
336 | 334 | ||
337 | /* | ||
338 | * Corrupt successful READs while in down state. | ||
339 | */ | ||
340 | if (!error && pb->bio_submitted && (bio_data_dir(bio) == READ)) { | 335 | if (!error && pb->bio_submitted && (bio_data_dir(bio) == READ)) { |
341 | if (fc->corrupt_bio_byte) | 336 | if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == READ) && |
337 | all_corrupt_bio_flags_match(bio, fc)) { | ||
338 | /* | ||
339 | * Corrupt successful matching READs while in down state. | ||
340 | */ | ||
342 | corrupt_bio_data(bio, fc); | 341 | corrupt_bio_data(bio, fc); |
343 | else | 342 | |
343 | } else if (!test_bit(DROP_WRITES, &fc->flags)) { | ||
344 | /* | ||
345 | * Error read during the down_interval if drop_writes | ||
346 | * wasn't configured. | ||
347 | */ | ||
344 | return -EIO; | 348 | return -EIO; |
349 | } | ||
345 | } | 350 | } |
346 | 351 | ||
347 | return error; | 352 | return error; |
diff --git a/drivers/md/dm-log-writes.c b/drivers/md/dm-log-writes.c index 4ab68033f9d1..49e4d8d4558f 100644 --- a/drivers/md/dm-log-writes.c +++ b/drivers/md/dm-log-writes.c | |||
@@ -259,12 +259,12 @@ static int log_one_block(struct log_writes_c *lc, | |||
259 | goto out; | 259 | goto out; |
260 | sector++; | 260 | sector++; |
261 | 261 | ||
262 | bio = bio_alloc(GFP_KERNEL, block->vec_cnt); | 262 | atomic_inc(&lc->io_blocks); |
263 | bio = bio_alloc(GFP_KERNEL, min(block->vec_cnt, BIO_MAX_PAGES)); | ||
263 | if (!bio) { | 264 | if (!bio) { |
264 | DMERR("Couldn't alloc log bio"); | 265 | DMERR("Couldn't alloc log bio"); |
265 | goto error; | 266 | goto error; |
266 | } | 267 | } |
267 | atomic_inc(&lc->io_blocks); | ||
268 | bio->bi_iter.bi_size = 0; | 268 | bio->bi_iter.bi_size = 0; |
269 | bio->bi_iter.bi_sector = sector; | 269 | bio->bi_iter.bi_sector = sector; |
270 | bio->bi_bdev = lc->logdev->bdev; | 270 | bio->bi_bdev = lc->logdev->bdev; |
@@ -282,7 +282,7 @@ static int log_one_block(struct log_writes_c *lc, | |||
282 | if (ret != block->vecs[i].bv_len) { | 282 | if (ret != block->vecs[i].bv_len) { |
283 | atomic_inc(&lc->io_blocks); | 283 | atomic_inc(&lc->io_blocks); |
284 | submit_bio(bio); | 284 | submit_bio(bio); |
285 | bio = bio_alloc(GFP_KERNEL, block->vec_cnt - i); | 285 | bio = bio_alloc(GFP_KERNEL, min(block->vec_cnt - i, BIO_MAX_PAGES)); |
286 | if (!bio) { | 286 | if (!bio) { |
287 | DMERR("Couldn't alloc log bio"); | 287 | DMERR("Couldn't alloc log bio"); |
288 | goto error; | 288 | goto error; |
@@ -459,9 +459,9 @@ static int log_writes_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
459 | goto bad; | 459 | goto bad; |
460 | } | 460 | } |
461 | 461 | ||
462 | ret = -EINVAL; | ||
463 | lc->log_kthread = kthread_run(log_writes_kthread, lc, "log-write"); | 462 | lc->log_kthread = kthread_run(log_writes_kthread, lc, "log-write"); |
464 | if (!lc->log_kthread) { | 463 | if (IS_ERR(lc->log_kthread)) { |
464 | ret = PTR_ERR(lc->log_kthread); | ||
465 | ti->error = "Couldn't alloc kthread"; | 465 | ti->error = "Couldn't alloc kthread"; |
466 | dm_put_device(ti, lc->dev); | 466 | dm_put_device(ti, lc->dev); |
467 | dm_put_device(ti, lc->logdev); | 467 | dm_put_device(ti, lc->logdev); |
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 4ca2d1df5b44..07fc1ad42ec5 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c | |||
@@ -291,9 +291,10 @@ static void header_from_disk(struct log_header_core *core, struct log_header_dis | |||
291 | core->nr_regions = le64_to_cpu(disk->nr_regions); | 291 | core->nr_regions = le64_to_cpu(disk->nr_regions); |
292 | } | 292 | } |
293 | 293 | ||
294 | static int rw_header(struct log_c *lc, int rw) | 294 | static int rw_header(struct log_c *lc, int op) |
295 | { | 295 | { |
296 | lc->io_req.bi_op = rw; | 296 | lc->io_req.bi_op = op; |
297 | lc->io_req.bi_op_flags = 0; | ||
297 | 298 | ||
298 | return dm_io(&lc->io_req, 1, &lc->header_location, NULL); | 299 | return dm_io(&lc->io_req, 1, &lc->header_location, NULL); |
299 | } | 300 | } |
@@ -316,7 +317,7 @@ static int read_header(struct log_c *log) | |||
316 | { | 317 | { |
317 | int r; | 318 | int r; |
318 | 319 | ||
319 | r = rw_header(log, READ); | 320 | r = rw_header(log, REQ_OP_READ); |
320 | if (r) | 321 | if (r) |
321 | return r; | 322 | return r; |
322 | 323 | ||
@@ -630,7 +631,7 @@ static int disk_resume(struct dm_dirty_log *log) | |||
630 | header_to_disk(&lc->header, lc->disk_header); | 631 | header_to_disk(&lc->header, lc->disk_header); |
631 | 632 | ||
632 | /* write the new header */ | 633 | /* write the new header */ |
633 | r = rw_header(lc, WRITE); | 634 | r = rw_header(lc, REQ_OP_WRITE); |
634 | if (!r) { | 635 | if (!r) { |
635 | r = flush_header(lc); | 636 | r = flush_header(lc); |
636 | if (r) | 637 | if (r) |
@@ -698,7 +699,7 @@ static int disk_flush(struct dm_dirty_log *log) | |||
698 | log_clear_bit(lc, lc->clean_bits, i); | 699 | log_clear_bit(lc, lc->clean_bits, i); |
699 | } | 700 | } |
700 | 701 | ||
701 | r = rw_header(lc, WRITE); | 702 | r = rw_header(lc, REQ_OP_WRITE); |
702 | if (r) | 703 | if (r) |
703 | fail_log_device(lc); | 704 | fail_log_device(lc); |
704 | else { | 705 | else { |
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 41573f1f626f..34a840d9df76 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c | |||
@@ -834,8 +834,10 @@ static int join(struct mddev *mddev, int nodes) | |||
834 | goto err; | 834 | goto err; |
835 | } | 835 | } |
836 | cinfo->ack_lockres = lockres_init(mddev, "ack", ack_bast, 0); | 836 | cinfo->ack_lockres = lockres_init(mddev, "ack", ack_bast, 0); |
837 | if (!cinfo->ack_lockres) | 837 | if (!cinfo->ack_lockres) { |
838 | ret = -ENOMEM; | ||
838 | goto err; | 839 | goto err; |
840 | } | ||
839 | /* get sync CR lock on ACK. */ | 841 | /* get sync CR lock on ACK. */ |
840 | if (dlm_lock_sync(cinfo->ack_lockres, DLM_LOCK_CR)) | 842 | if (dlm_lock_sync(cinfo->ack_lockres, DLM_LOCK_CR)) |
841 | pr_err("md-cluster: failed to get a sync CR lock on ACK!(%d)\n", | 843 | pr_err("md-cluster: failed to get a sync CR lock on ACK!(%d)\n", |
@@ -849,8 +851,10 @@ static int join(struct mddev *mddev, int nodes) | |||
849 | pr_info("md-cluster: Joined cluster %s slot %d\n", str, cinfo->slot_number); | 851 | pr_info("md-cluster: Joined cluster %s slot %d\n", str, cinfo->slot_number); |
850 | snprintf(str, 64, "bitmap%04d", cinfo->slot_number - 1); | 852 | snprintf(str, 64, "bitmap%04d", cinfo->slot_number - 1); |
851 | cinfo->bitmap_lockres = lockres_init(mddev, str, NULL, 1); | 853 | cinfo->bitmap_lockres = lockres_init(mddev, str, NULL, 1); |
852 | if (!cinfo->bitmap_lockres) | 854 | if (!cinfo->bitmap_lockres) { |
855 | ret = -ENOMEM; | ||
853 | goto err; | 856 | goto err; |
857 | } | ||
854 | if (dlm_lock_sync(cinfo->bitmap_lockres, DLM_LOCK_PW)) { | 858 | if (dlm_lock_sync(cinfo->bitmap_lockres, DLM_LOCK_PW)) { |
855 | pr_err("Failed to get bitmap lock\n"); | 859 | pr_err("Failed to get bitmap lock\n"); |
856 | ret = -EINVAL; | 860 | ret = -EINVAL; |
@@ -858,8 +862,10 @@ static int join(struct mddev *mddev, int nodes) | |||
858 | } | 862 | } |
859 | 863 | ||
860 | cinfo->resync_lockres = lockres_init(mddev, "resync", NULL, 0); | 864 | cinfo->resync_lockres = lockres_init(mddev, "resync", NULL, 0); |
861 | if (!cinfo->resync_lockres) | 865 | if (!cinfo->resync_lockres) { |
866 | ret = -ENOMEM; | ||
862 | goto err; | 867 | goto err; |
868 | } | ||
863 | 869 | ||
864 | return 0; | 870 | return 0; |
865 | err: | 871 | err: |
diff --git a/drivers/md/md.c b/drivers/md/md.c index d646f6e444f0..915e84d631a2 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1604,11 +1604,8 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) | |||
1604 | mddev->new_chunk_sectors = mddev->chunk_sectors; | 1604 | mddev->new_chunk_sectors = mddev->chunk_sectors; |
1605 | } | 1605 | } |
1606 | 1606 | ||
1607 | if (le32_to_cpu(sb->feature_map) & MD_FEATURE_JOURNAL) { | 1607 | if (le32_to_cpu(sb->feature_map) & MD_FEATURE_JOURNAL) |
1608 | set_bit(MD_HAS_JOURNAL, &mddev->flags); | 1608 | set_bit(MD_HAS_JOURNAL, &mddev->flags); |
1609 | if (mddev->recovery_cp == MaxSector) | ||
1610 | set_bit(MD_JOURNAL_CLEAN, &mddev->flags); | ||
1611 | } | ||
1612 | } else if (mddev->pers == NULL) { | 1609 | } else if (mddev->pers == NULL) { |
1613 | /* Insist of good event counter while assembling, except for | 1610 | /* Insist of good event counter while assembling, except for |
1614 | * spares (which don't need an event count) */ | 1611 | * spares (which don't need an event count) */ |
@@ -5851,6 +5848,9 @@ static int get_array_info(struct mddev *mddev, void __user *arg) | |||
5851 | working++; | 5848 | working++; |
5852 | if (test_bit(In_sync, &rdev->flags)) | 5849 | if (test_bit(In_sync, &rdev->flags)) |
5853 | insync++; | 5850 | insync++; |
5851 | else if (test_bit(Journal, &rdev->flags)) | ||
5852 | /* TODO: add journal count to md_u.h */ | ||
5853 | ; | ||
5854 | else | 5854 | else |
5855 | spare++; | 5855 | spare++; |
5856 | } | 5856 | } |
@@ -7610,16 +7610,12 @@ EXPORT_SYMBOL(unregister_md_cluster_operations); | |||
7610 | 7610 | ||
7611 | int md_setup_cluster(struct mddev *mddev, int nodes) | 7611 | int md_setup_cluster(struct mddev *mddev, int nodes) |
7612 | { | 7612 | { |
7613 | int err; | 7613 | if (!md_cluster_ops) |
7614 | 7614 | request_module("md-cluster"); | |
7615 | err = request_module("md-cluster"); | ||
7616 | if (err) { | ||
7617 | pr_err("md-cluster module not found.\n"); | ||
7618 | return -ENOENT; | ||
7619 | } | ||
7620 | |||
7621 | spin_lock(&pers_lock); | 7615 | spin_lock(&pers_lock); |
7616 | /* ensure module won't be unloaded */ | ||
7622 | if (!md_cluster_ops || !try_module_get(md_cluster_mod)) { | 7617 | if (!md_cluster_ops || !try_module_get(md_cluster_mod)) { |
7618 | pr_err("can't find md-cluster module or get it's reference.\n"); | ||
7623 | spin_unlock(&pers_lock); | 7619 | spin_unlock(&pers_lock); |
7624 | return -ENOENT; | 7620 | return -ENOENT; |
7625 | } | 7621 | } |
@@ -7862,6 +7858,7 @@ void md_do_sync(struct md_thread *thread) | |||
7862 | */ | 7858 | */ |
7863 | 7859 | ||
7864 | do { | 7860 | do { |
7861 | int mddev2_minor = -1; | ||
7865 | mddev->curr_resync = 2; | 7862 | mddev->curr_resync = 2; |
7866 | 7863 | ||
7867 | try_again: | 7864 | try_again: |
@@ -7891,10 +7888,14 @@ void md_do_sync(struct md_thread *thread) | |||
7891 | prepare_to_wait(&resync_wait, &wq, TASK_INTERRUPTIBLE); | 7888 | prepare_to_wait(&resync_wait, &wq, TASK_INTERRUPTIBLE); |
7892 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) && | 7889 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) && |
7893 | mddev2->curr_resync >= mddev->curr_resync) { | 7890 | mddev2->curr_resync >= mddev->curr_resync) { |
7894 | printk(KERN_INFO "md: delaying %s of %s" | 7891 | if (mddev2_minor != mddev2->md_minor) { |
7895 | " until %s has finished (they" | 7892 | mddev2_minor = mddev2->md_minor; |
7896 | " share one or more physical units)\n", | 7893 | printk(KERN_INFO "md: delaying %s of %s" |
7897 | desc, mdname(mddev), mdname(mddev2)); | 7894 | " until %s has finished (they" |
7895 | " share one or more physical units)\n", | ||
7896 | desc, mdname(mddev), | ||
7897 | mdname(mddev2)); | ||
7898 | } | ||
7898 | mddev_put(mddev2); | 7899 | mddev_put(mddev2); |
7899 | if (signal_pending(current)) | 7900 | if (signal_pending(current)) |
7900 | flush_signals(current); | 7901 | flush_signals(current); |
@@ -8275,16 +8276,13 @@ no_add: | |||
8275 | static void md_start_sync(struct work_struct *ws) | 8276 | static void md_start_sync(struct work_struct *ws) |
8276 | { | 8277 | { |
8277 | struct mddev *mddev = container_of(ws, struct mddev, del_work); | 8278 | struct mddev *mddev = container_of(ws, struct mddev, del_work); |
8278 | int ret = 0; | ||
8279 | 8279 | ||
8280 | mddev->sync_thread = md_register_thread(md_do_sync, | 8280 | mddev->sync_thread = md_register_thread(md_do_sync, |
8281 | mddev, | 8281 | mddev, |
8282 | "resync"); | 8282 | "resync"); |
8283 | if (!mddev->sync_thread) { | 8283 | if (!mddev->sync_thread) { |
8284 | if (!(mddev_is_clustered(mddev) && ret == -EAGAIN)) | 8284 | printk(KERN_ERR "%s: could not start resync thread...\n", |
8285 | printk(KERN_ERR "%s: could not start resync" | 8285 | mdname(mddev)); |
8286 | " thread...\n", | ||
8287 | mdname(mddev)); | ||
8288 | /* leave the spares where they are, it shouldn't hurt */ | 8286 | /* leave the spares where they are, it shouldn't hurt */ |
8289 | clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); | 8287 | clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); |
8290 | clear_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); | 8288 | clear_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 0e4efcd10795..be1a9fca3b2d 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1064,6 +1064,8 @@ static void __make_request(struct mddev *mddev, struct bio *bio) | |||
1064 | int max_sectors; | 1064 | int max_sectors; |
1065 | int sectors; | 1065 | int sectors; |
1066 | 1066 | ||
1067 | md_write_start(mddev, bio); | ||
1068 | |||
1067 | /* | 1069 | /* |
1068 | * Register the new request and wait if the reconstruction | 1070 | * Register the new request and wait if the reconstruction |
1069 | * thread has put up a bar for new requests. | 1071 | * thread has put up a bar for new requests. |
@@ -1445,8 +1447,6 @@ static void raid10_make_request(struct mddev *mddev, struct bio *bio) | |||
1445 | return; | 1447 | return; |
1446 | } | 1448 | } |
1447 | 1449 | ||
1448 | md_write_start(mddev, bio); | ||
1449 | |||
1450 | do { | 1450 | do { |
1451 | 1451 | ||
1452 | /* | 1452 | /* |
@@ -2465,20 +2465,21 @@ static int narrow_write_error(struct r10bio *r10_bio, int i) | |||
2465 | 2465 | ||
2466 | while (sect_to_write) { | 2466 | while (sect_to_write) { |
2467 | struct bio *wbio; | 2467 | struct bio *wbio; |
2468 | sector_t wsector; | ||
2468 | if (sectors > sect_to_write) | 2469 | if (sectors > sect_to_write) |
2469 | sectors = sect_to_write; | 2470 | sectors = sect_to_write; |
2470 | /* Write at 'sector' for 'sectors' */ | 2471 | /* Write at 'sector' for 'sectors' */ |
2471 | wbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | 2472 | wbio = bio_clone_mddev(bio, GFP_NOIO, mddev); |
2472 | bio_trim(wbio, sector - bio->bi_iter.bi_sector, sectors); | 2473 | bio_trim(wbio, sector - bio->bi_iter.bi_sector, sectors); |
2473 | wbio->bi_iter.bi_sector = (r10_bio->devs[i].addr+ | 2474 | wsector = r10_bio->devs[i].addr + (sector - r10_bio->sector); |
2474 | choose_data_offset(r10_bio, rdev) + | 2475 | wbio->bi_iter.bi_sector = wsector + |
2475 | (sector - r10_bio->sector)); | 2476 | choose_data_offset(r10_bio, rdev); |
2476 | wbio->bi_bdev = rdev->bdev; | 2477 | wbio->bi_bdev = rdev->bdev; |
2477 | bio_set_op_attrs(wbio, REQ_OP_WRITE, 0); | 2478 | bio_set_op_attrs(wbio, REQ_OP_WRITE, 0); |
2478 | 2479 | ||
2479 | if (submit_bio_wait(wbio) < 0) | 2480 | if (submit_bio_wait(wbio) < 0) |
2480 | /* Failure! */ | 2481 | /* Failure! */ |
2481 | ok = rdev_set_badblocks(rdev, sector, | 2482 | ok = rdev_set_badblocks(rdev, wsector, |
2482 | sectors, 0) | 2483 | sectors, 0) |
2483 | && ok; | 2484 | && ok; |
2484 | 2485 | ||
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index 51f76ddbe265..1b1ab4a1d132 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c | |||
@@ -96,7 +96,6 @@ struct r5l_log { | |||
96 | spinlock_t no_space_stripes_lock; | 96 | spinlock_t no_space_stripes_lock; |
97 | 97 | ||
98 | bool need_cache_flush; | 98 | bool need_cache_flush; |
99 | bool in_teardown; | ||
100 | }; | 99 | }; |
101 | 100 | ||
102 | /* | 101 | /* |
@@ -704,31 +703,22 @@ static void r5l_write_super_and_discard_space(struct r5l_log *log, | |||
704 | 703 | ||
705 | mddev = log->rdev->mddev; | 704 | mddev = log->rdev->mddev; |
706 | /* | 705 | /* |
707 | * This is to avoid a deadlock. r5l_quiesce holds reconfig_mutex and | 706 | * Discard could zero data, so before discard we must make sure |
708 | * wait for this thread to finish. This thread waits for | 707 | * superblock is updated to new log tail. Updating superblock (either |
709 | * MD_CHANGE_PENDING clear, which is supposed to be done in | 708 | * directly call md_update_sb() or depend on md thread) must hold |
710 | * md_check_recovery(). md_check_recovery() tries to get | 709 | * reconfig mutex. On the other hand, raid5_quiesce is called with |
711 | * reconfig_mutex. Since r5l_quiesce already holds the mutex, | 710 | * reconfig_mutex hold. The first step of raid5_quiesce() is waitting |
712 | * md_check_recovery() fails, so the PENDING never get cleared. The | 711 | * for all IO finish, hence waitting for reclaim thread, while reclaim |
713 | * in_teardown check workaround this issue. | 712 | * thread is calling this function and waitting for reconfig mutex. So |
713 | * there is a deadlock. We workaround this issue with a trylock. | ||
714 | * FIXME: we could miss discard if we can't take reconfig mutex | ||
714 | */ | 715 | */ |
715 | if (!log->in_teardown) { | 716 | set_mask_bits(&mddev->flags, 0, |
716 | set_mask_bits(&mddev->flags, 0, | 717 | BIT(MD_CHANGE_DEVS) | BIT(MD_CHANGE_PENDING)); |
717 | BIT(MD_CHANGE_DEVS) | BIT(MD_CHANGE_PENDING)); | 718 | if (!mddev_trylock(mddev)) |
718 | md_wakeup_thread(mddev->thread); | 719 | return; |
719 | wait_event(mddev->sb_wait, | 720 | md_update_sb(mddev, 1); |
720 | !test_bit(MD_CHANGE_PENDING, &mddev->flags) || | 721 | mddev_unlock(mddev); |
721 | log->in_teardown); | ||
722 | /* | ||
723 | * r5l_quiesce could run after in_teardown check and hold | ||
724 | * mutex first. Superblock might get updated twice. | ||
725 | */ | ||
726 | if (log->in_teardown) | ||
727 | md_update_sb(mddev, 1); | ||
728 | } else { | ||
729 | WARN_ON(!mddev_is_locked(mddev)); | ||
730 | md_update_sb(mddev, 1); | ||
731 | } | ||
732 | 722 | ||
733 | /* discard IO error really doesn't matter, ignore it */ | 723 | /* discard IO error really doesn't matter, ignore it */ |
734 | if (log->last_checkpoint < end) { | 724 | if (log->last_checkpoint < end) { |
@@ -827,7 +817,6 @@ void r5l_quiesce(struct r5l_log *log, int state) | |||
827 | if (!log || state == 2) | 817 | if (!log || state == 2) |
828 | return; | 818 | return; |
829 | if (state == 0) { | 819 | if (state == 0) { |
830 | log->in_teardown = 0; | ||
831 | /* | 820 | /* |
832 | * This is a special case for hotadd. In suspend, the array has | 821 | * This is a special case for hotadd. In suspend, the array has |
833 | * no journal. In resume, journal is initialized as well as the | 822 | * no journal. In resume, journal is initialized as well as the |
@@ -838,11 +827,6 @@ void r5l_quiesce(struct r5l_log *log, int state) | |||
838 | log->reclaim_thread = md_register_thread(r5l_reclaim_thread, | 827 | log->reclaim_thread = md_register_thread(r5l_reclaim_thread, |
839 | log->rdev->mddev, "reclaim"); | 828 | log->rdev->mddev, "reclaim"); |
840 | } else if (state == 1) { | 829 | } else if (state == 1) { |
841 | /* | ||
842 | * at this point all stripes are finished, so io_unit is at | ||
843 | * least in STRIPE_END state | ||
844 | */ | ||
845 | log->in_teardown = 1; | ||
846 | /* make sure r5l_write_super_and_discard_space exits */ | 830 | /* make sure r5l_write_super_and_discard_space exits */ |
847 | mddev = log->rdev->mddev; | 831 | mddev = log->rdev->mddev; |
848 | wake_up(&mddev->sb_wait); | 832 | wake_up(&mddev->sb_wait); |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 8912407a4dd0..ee7fc3701700 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -659,6 +659,7 @@ raid5_get_active_stripe(struct r5conf *conf, sector_t sector, | |||
659 | { | 659 | { |
660 | struct stripe_head *sh; | 660 | struct stripe_head *sh; |
661 | int hash = stripe_hash_locks_hash(sector); | 661 | int hash = stripe_hash_locks_hash(sector); |
662 | int inc_empty_inactive_list_flag; | ||
662 | 663 | ||
663 | pr_debug("get_stripe, sector %llu\n", (unsigned long long)sector); | 664 | pr_debug("get_stripe, sector %llu\n", (unsigned long long)sector); |
664 | 665 | ||
@@ -703,7 +704,12 @@ raid5_get_active_stripe(struct r5conf *conf, sector_t sector, | |||
703 | atomic_inc(&conf->active_stripes); | 704 | atomic_inc(&conf->active_stripes); |
704 | BUG_ON(list_empty(&sh->lru) && | 705 | BUG_ON(list_empty(&sh->lru) && |
705 | !test_bit(STRIPE_EXPANDING, &sh->state)); | 706 | !test_bit(STRIPE_EXPANDING, &sh->state)); |
707 | inc_empty_inactive_list_flag = 0; | ||
708 | if (!list_empty(conf->inactive_list + hash)) | ||
709 | inc_empty_inactive_list_flag = 1; | ||
706 | list_del_init(&sh->lru); | 710 | list_del_init(&sh->lru); |
711 | if (list_empty(conf->inactive_list + hash) && inc_empty_inactive_list_flag) | ||
712 | atomic_inc(&conf->empty_inactive_list_nr); | ||
707 | if (sh->group) { | 713 | if (sh->group) { |
708 | sh->group->stripes_cnt--; | 714 | sh->group->stripes_cnt--; |
709 | sh->group = NULL; | 715 | sh->group = NULL; |
@@ -762,6 +768,7 @@ static void stripe_add_to_batch_list(struct r5conf *conf, struct stripe_head *sh | |||
762 | sector_t head_sector, tmp_sec; | 768 | sector_t head_sector, tmp_sec; |
763 | int hash; | 769 | int hash; |
764 | int dd_idx; | 770 | int dd_idx; |
771 | int inc_empty_inactive_list_flag; | ||
765 | 772 | ||
766 | /* Don't cross chunks, so stripe pd_idx/qd_idx is the same */ | 773 | /* Don't cross chunks, so stripe pd_idx/qd_idx is the same */ |
767 | tmp_sec = sh->sector; | 774 | tmp_sec = sh->sector; |
@@ -779,7 +786,12 @@ static void stripe_add_to_batch_list(struct r5conf *conf, struct stripe_head *sh | |||
779 | atomic_inc(&conf->active_stripes); | 786 | atomic_inc(&conf->active_stripes); |
780 | BUG_ON(list_empty(&head->lru) && | 787 | BUG_ON(list_empty(&head->lru) && |
781 | !test_bit(STRIPE_EXPANDING, &head->state)); | 788 | !test_bit(STRIPE_EXPANDING, &head->state)); |
789 | inc_empty_inactive_list_flag = 0; | ||
790 | if (!list_empty(conf->inactive_list + hash)) | ||
791 | inc_empty_inactive_list_flag = 1; | ||
782 | list_del_init(&head->lru); | 792 | list_del_init(&head->lru); |
793 | if (list_empty(conf->inactive_list + hash) && inc_empty_inactive_list_flag) | ||
794 | atomic_inc(&conf->empty_inactive_list_nr); | ||
783 | if (head->group) { | 795 | if (head->group) { |
784 | head->group->stripes_cnt--; | 796 | head->group->stripes_cnt--; |
785 | head->group = NULL; | 797 | head->group = NULL; |
@@ -993,7 +1005,6 @@ again: | |||
993 | 1005 | ||
994 | set_bit(STRIPE_IO_STARTED, &sh->state); | 1006 | set_bit(STRIPE_IO_STARTED, &sh->state); |
995 | 1007 | ||
996 | bio_reset(bi); | ||
997 | bi->bi_bdev = rdev->bdev; | 1008 | bi->bi_bdev = rdev->bdev; |
998 | bio_set_op_attrs(bi, op, op_flags); | 1009 | bio_set_op_attrs(bi, op, op_flags); |
999 | bi->bi_end_io = op_is_write(op) | 1010 | bi->bi_end_io = op_is_write(op) |
@@ -1045,7 +1056,6 @@ again: | |||
1045 | 1056 | ||
1046 | set_bit(STRIPE_IO_STARTED, &sh->state); | 1057 | set_bit(STRIPE_IO_STARTED, &sh->state); |
1047 | 1058 | ||
1048 | bio_reset(rbi); | ||
1049 | rbi->bi_bdev = rrdev->bdev; | 1059 | rbi->bi_bdev = rrdev->bdev; |
1050 | bio_set_op_attrs(rbi, op, op_flags); | 1060 | bio_set_op_attrs(rbi, op, op_flags); |
1051 | BUG_ON(!op_is_write(op)); | 1061 | BUG_ON(!op_is_write(op)); |
@@ -1978,9 +1988,11 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) | |||
1978 | put_cpu(); | 1988 | put_cpu(); |
1979 | } | 1989 | } |
1980 | 1990 | ||
1981 | static struct stripe_head *alloc_stripe(struct kmem_cache *sc, gfp_t gfp) | 1991 | static struct stripe_head *alloc_stripe(struct kmem_cache *sc, gfp_t gfp, |
1992 | int disks) | ||
1982 | { | 1993 | { |
1983 | struct stripe_head *sh; | 1994 | struct stripe_head *sh; |
1995 | int i; | ||
1984 | 1996 | ||
1985 | sh = kmem_cache_zalloc(sc, gfp); | 1997 | sh = kmem_cache_zalloc(sc, gfp); |
1986 | if (sh) { | 1998 | if (sh) { |
@@ -1989,6 +2001,17 @@ static struct stripe_head *alloc_stripe(struct kmem_cache *sc, gfp_t gfp) | |||
1989 | INIT_LIST_HEAD(&sh->batch_list); | 2001 | INIT_LIST_HEAD(&sh->batch_list); |
1990 | INIT_LIST_HEAD(&sh->lru); | 2002 | INIT_LIST_HEAD(&sh->lru); |
1991 | atomic_set(&sh->count, 1); | 2003 | atomic_set(&sh->count, 1); |
2004 | for (i = 0; i < disks; i++) { | ||
2005 | struct r5dev *dev = &sh->dev[i]; | ||
2006 | |||
2007 | bio_init(&dev->req); | ||
2008 | dev->req.bi_io_vec = &dev->vec; | ||
2009 | dev->req.bi_max_vecs = 1; | ||
2010 | |||
2011 | bio_init(&dev->rreq); | ||
2012 | dev->rreq.bi_io_vec = &dev->rvec; | ||
2013 | dev->rreq.bi_max_vecs = 1; | ||
2014 | } | ||
1992 | } | 2015 | } |
1993 | return sh; | 2016 | return sh; |
1994 | } | 2017 | } |
@@ -1996,7 +2019,7 @@ static int grow_one_stripe(struct r5conf *conf, gfp_t gfp) | |||
1996 | { | 2019 | { |
1997 | struct stripe_head *sh; | 2020 | struct stripe_head *sh; |
1998 | 2021 | ||
1999 | sh = alloc_stripe(conf->slab_cache, gfp); | 2022 | sh = alloc_stripe(conf->slab_cache, gfp, conf->pool_size); |
2000 | if (!sh) | 2023 | if (!sh) |
2001 | return 0; | 2024 | return 0; |
2002 | 2025 | ||
@@ -2167,7 +2190,7 @@ static int resize_stripes(struct r5conf *conf, int newsize) | |||
2167 | mutex_lock(&conf->cache_size_mutex); | 2190 | mutex_lock(&conf->cache_size_mutex); |
2168 | 2191 | ||
2169 | for (i = conf->max_nr_stripes; i; i--) { | 2192 | for (i = conf->max_nr_stripes; i; i--) { |
2170 | nsh = alloc_stripe(sc, GFP_KERNEL); | 2193 | nsh = alloc_stripe(sc, GFP_KERNEL, newsize); |
2171 | if (!nsh) | 2194 | if (!nsh) |
2172 | break; | 2195 | break; |
2173 | 2196 | ||
@@ -2299,6 +2322,7 @@ static void raid5_end_read_request(struct bio * bi) | |||
2299 | (unsigned long long)sh->sector, i, atomic_read(&sh->count), | 2322 | (unsigned long long)sh->sector, i, atomic_read(&sh->count), |
2300 | bi->bi_error); | 2323 | bi->bi_error); |
2301 | if (i == disks) { | 2324 | if (i == disks) { |
2325 | bio_reset(bi); | ||
2302 | BUG(); | 2326 | BUG(); |
2303 | return; | 2327 | return; |
2304 | } | 2328 | } |
@@ -2399,6 +2423,7 @@ static void raid5_end_read_request(struct bio * bi) | |||
2399 | } | 2423 | } |
2400 | } | 2424 | } |
2401 | rdev_dec_pending(rdev, conf->mddev); | 2425 | rdev_dec_pending(rdev, conf->mddev); |
2426 | bio_reset(bi); | ||
2402 | clear_bit(R5_LOCKED, &sh->dev[i].flags); | 2427 | clear_bit(R5_LOCKED, &sh->dev[i].flags); |
2403 | set_bit(STRIPE_HANDLE, &sh->state); | 2428 | set_bit(STRIPE_HANDLE, &sh->state); |
2404 | raid5_release_stripe(sh); | 2429 | raid5_release_stripe(sh); |
@@ -2436,6 +2461,7 @@ static void raid5_end_write_request(struct bio *bi) | |||
2436 | (unsigned long long)sh->sector, i, atomic_read(&sh->count), | 2461 | (unsigned long long)sh->sector, i, atomic_read(&sh->count), |
2437 | bi->bi_error); | 2462 | bi->bi_error); |
2438 | if (i == disks) { | 2463 | if (i == disks) { |
2464 | bio_reset(bi); | ||
2439 | BUG(); | 2465 | BUG(); |
2440 | return; | 2466 | return; |
2441 | } | 2467 | } |
@@ -2472,6 +2498,7 @@ static void raid5_end_write_request(struct bio *bi) | |||
2472 | if (sh->batch_head && bi->bi_error && !replacement) | 2498 | if (sh->batch_head && bi->bi_error && !replacement) |
2473 | set_bit(STRIPE_BATCH_ERR, &sh->batch_head->state); | 2499 | set_bit(STRIPE_BATCH_ERR, &sh->batch_head->state); |
2474 | 2500 | ||
2501 | bio_reset(bi); | ||
2475 | if (!test_and_clear_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags)) | 2502 | if (!test_and_clear_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags)) |
2476 | clear_bit(R5_LOCKED, &sh->dev[i].flags); | 2503 | clear_bit(R5_LOCKED, &sh->dev[i].flags); |
2477 | set_bit(STRIPE_HANDLE, &sh->state); | 2504 | set_bit(STRIPE_HANDLE, &sh->state); |
@@ -2485,16 +2512,6 @@ static void raid5_build_block(struct stripe_head *sh, int i, int previous) | |||
2485 | { | 2512 | { |
2486 | struct r5dev *dev = &sh->dev[i]; | 2513 | struct r5dev *dev = &sh->dev[i]; |
2487 | 2514 | ||
2488 | bio_init(&dev->req); | ||
2489 | dev->req.bi_io_vec = &dev->vec; | ||
2490 | dev->req.bi_max_vecs = 1; | ||
2491 | dev->req.bi_private = sh; | ||
2492 | |||
2493 | bio_init(&dev->rreq); | ||
2494 | dev->rreq.bi_io_vec = &dev->rvec; | ||
2495 | dev->rreq.bi_max_vecs = 1; | ||
2496 | dev->rreq.bi_private = sh; | ||
2497 | |||
2498 | dev->flags = 0; | 2515 | dev->flags = 0; |
2499 | dev->sector = raid5_compute_blocknr(sh, i, previous); | 2516 | dev->sector = raid5_compute_blocknr(sh, i, previous); |
2500 | } | 2517 | } |
@@ -4628,7 +4645,9 @@ finish: | |||
4628 | } | 4645 | } |
4629 | 4646 | ||
4630 | if (!bio_list_empty(&s.return_bi)) { | 4647 | if (!bio_list_empty(&s.return_bi)) { |
4631 | if (test_bit(MD_CHANGE_PENDING, &conf->mddev->flags)) { | 4648 | if (test_bit(MD_CHANGE_PENDING, &conf->mddev->flags) && |
4649 | (s.failed <= conf->max_degraded || | ||
4650 | conf->mddev->external == 0)) { | ||
4632 | spin_lock_irq(&conf->device_lock); | 4651 | spin_lock_irq(&conf->device_lock); |
4633 | bio_list_merge(&conf->return_bi, &s.return_bi); | 4652 | bio_list_merge(&conf->return_bi, &s.return_bi); |
4634 | spin_unlock_irq(&conf->device_lock); | 4653 | spin_unlock_irq(&conf->device_lock); |
@@ -6620,6 +6639,16 @@ static struct r5conf *setup_conf(struct mddev *mddev) | |||
6620 | } | 6639 | } |
6621 | 6640 | ||
6622 | conf->min_nr_stripes = NR_STRIPES; | 6641 | conf->min_nr_stripes = NR_STRIPES; |
6642 | if (mddev->reshape_position != MaxSector) { | ||
6643 | int stripes = max_t(int, | ||
6644 | ((mddev->chunk_sectors << 9) / STRIPE_SIZE) * 4, | ||
6645 | ((mddev->new_chunk_sectors << 9) / STRIPE_SIZE) * 4); | ||
6646 | conf->min_nr_stripes = max(NR_STRIPES, stripes); | ||
6647 | if (conf->min_nr_stripes != NR_STRIPES) | ||
6648 | printk(KERN_INFO | ||
6649 | "md/raid:%s: force stripe size %d for reshape\n", | ||
6650 | mdname(mddev), conf->min_nr_stripes); | ||
6651 | } | ||
6623 | memory = conf->min_nr_stripes * (sizeof(struct stripe_head) + | 6652 | memory = conf->min_nr_stripes * (sizeof(struct stripe_head) + |
6624 | max_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024; | 6653 | max_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024; |
6625 | atomic_set(&conf->empty_inactive_list_nr, NR_STRIPE_HASH_LOCKS); | 6654 | atomic_set(&conf->empty_inactive_list_nr, NR_STRIPE_HASH_LOCKS); |
@@ -6826,11 +6855,14 @@ static int raid5_run(struct mddev *mddev) | |||
6826 | if (IS_ERR(conf)) | 6855 | if (IS_ERR(conf)) |
6827 | return PTR_ERR(conf); | 6856 | return PTR_ERR(conf); |
6828 | 6857 | ||
6829 | if (test_bit(MD_HAS_JOURNAL, &mddev->flags) && !journal_dev) { | 6858 | if (test_bit(MD_HAS_JOURNAL, &mddev->flags)) { |
6830 | printk(KERN_ERR "md/raid:%s: journal disk is missing, force array readonly\n", | 6859 | if (!journal_dev) { |
6831 | mdname(mddev)); | 6860 | pr_err("md/raid:%s: journal disk is missing, force array readonly\n", |
6832 | mddev->ro = 1; | 6861 | mdname(mddev)); |
6833 | set_disk_ro(mddev->gendisk, 1); | 6862 | mddev->ro = 1; |
6863 | set_disk_ro(mddev->gendisk, 1); | ||
6864 | } else if (mddev->recovery_cp == MaxSector) | ||
6865 | set_bit(MD_JOURNAL_CLEAN, &mddev->flags); | ||
6834 | } | 6866 | } |
6835 | 6867 | ||
6836 | conf->min_offset_diff = min_offset_diff; | 6868 | conf->min_offset_diff = min_offset_diff; |
diff --git a/drivers/media/cec-edid.c b/drivers/media/cec-edid.c index 70018247bdda..5719b991e340 100644 --- a/drivers/media/cec-edid.c +++ b/drivers/media/cec-edid.c | |||
@@ -70,7 +70,10 @@ static unsigned int cec_get_edid_spa_location(const u8 *edid, unsigned int size) | |||
70 | u8 tag = edid[i] >> 5; | 70 | u8 tag = edid[i] >> 5; |
71 | u8 len = edid[i] & 0x1f; | 71 | u8 len = edid[i] & 0x1f; |
72 | 72 | ||
73 | if (tag == 3 && len >= 5 && i + len <= end) | 73 | if (tag == 3 && len >= 5 && i + len <= end && |
74 | edid[i + 1] == 0x03 && | ||
75 | edid[i + 2] == 0x0c && | ||
76 | edid[i + 3] == 0x00) | ||
74 | return i + 4; | 77 | return i + 4; |
75 | i += len + 1; | 78 | i += len + 1; |
76 | } while (i < end); | 79 | } while (i < end); |
diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c index efec2d1a7afd..4d080da7afaf 100644 --- a/drivers/media/pci/cx23885/cx23885-417.c +++ b/drivers/media/pci/cx23885/cx23885-417.c | |||
@@ -1552,6 +1552,7 @@ int cx23885_417_register(struct cx23885_dev *dev) | |||
1552 | q->mem_ops = &vb2_dma_sg_memops; | 1552 | q->mem_ops = &vb2_dma_sg_memops; |
1553 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | 1553 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
1554 | q->lock = &dev->lock; | 1554 | q->lock = &dev->lock; |
1555 | q->dev = &dev->pci->dev; | ||
1555 | 1556 | ||
1556 | err = vb2_queue_init(q); | 1557 | err = vb2_queue_init(q); |
1557 | if (err < 0) | 1558 | if (err < 0) |
diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c index db987e5b93eb..59a4b5f7724e 100644 --- a/drivers/media/pci/saa7134/saa7134-dvb.c +++ b/drivers/media/pci/saa7134/saa7134-dvb.c | |||
@@ -1238,6 +1238,7 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1238 | q->buf_struct_size = sizeof(struct saa7134_buf); | 1238 | q->buf_struct_size = sizeof(struct saa7134_buf); |
1239 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | 1239 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
1240 | q->lock = &dev->lock; | 1240 | q->lock = &dev->lock; |
1241 | q->dev = &dev->pci->dev; | ||
1241 | ret = vb2_queue_init(q); | 1242 | ret = vb2_queue_init(q); |
1242 | if (ret) { | 1243 | if (ret) { |
1243 | vb2_dvb_dealloc_frontends(&dev->frontends); | 1244 | vb2_dvb_dealloc_frontends(&dev->frontends); |
diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c index ca417a454d67..791a5161809b 100644 --- a/drivers/media/pci/saa7134/saa7134-empress.c +++ b/drivers/media/pci/saa7134/saa7134-empress.c | |||
@@ -295,6 +295,7 @@ static int empress_init(struct saa7134_dev *dev) | |||
295 | q->buf_struct_size = sizeof(struct saa7134_buf); | 295 | q->buf_struct_size = sizeof(struct saa7134_buf); |
296 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | 296 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
297 | q->lock = &dev->lock; | 297 | q->lock = &dev->lock; |
298 | q->dev = &dev->pci->dev; | ||
298 | err = vb2_queue_init(q); | 299 | err = vb2_queue_init(q); |
299 | if (err) | 300 | if (err) |
300 | return err; | 301 | return err; |
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index f25344bc7912..552b635cfce7 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig | |||
@@ -169,7 +169,7 @@ config VIDEO_MEDIATEK_VPU | |||
169 | config VIDEO_MEDIATEK_VCODEC | 169 | config VIDEO_MEDIATEK_VCODEC |
170 | tristate "Mediatek Video Codec driver" | 170 | tristate "Mediatek Video Codec driver" |
171 | depends on MTK_IOMMU || COMPILE_TEST | 171 | depends on MTK_IOMMU || COMPILE_TEST |
172 | depends on VIDEO_DEV && VIDEO_V4L2 | 172 | depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA |
173 | depends on ARCH_MEDIATEK || COMPILE_TEST | 173 | depends on ARCH_MEDIATEK || COMPILE_TEST |
174 | select VIDEOBUF2_DMA_CONTIG | 174 | select VIDEOBUF2_DMA_CONTIG |
175 | select V4L2_MEM2MEM_DEV | 175 | select V4L2_MEM2MEM_DEV |
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index 94f0a425be42..3a8e6958adae 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <media/v4l2-ioctl.h> | 23 | #include <media/v4l2-ioctl.h> |
24 | #include <media/videobuf2-core.h> | 24 | #include <media/videobuf2-core.h> |
25 | 25 | ||
26 | #include "mtk_vcodec_util.h" | ||
27 | 26 | ||
28 | #define MTK_VCODEC_DRV_NAME "mtk_vcodec_drv" | 27 | #define MTK_VCODEC_DRV_NAME "mtk_vcodec_drv" |
29 | #define MTK_VCODEC_ENC_NAME "mtk-vcodec-enc" | 28 | #define MTK_VCODEC_ENC_NAME "mtk-vcodec-enc" |
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c index 3ed3f2d31df5..2c5719ac23b2 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c | |||
@@ -487,7 +487,6 @@ static int vidioc_venc_s_fmt_out(struct file *file, void *priv, | |||
487 | struct mtk_q_data *q_data; | 487 | struct mtk_q_data *q_data; |
488 | int ret, i; | 488 | int ret, i; |
489 | struct mtk_video_fmt *fmt; | 489 | struct mtk_video_fmt *fmt; |
490 | unsigned int pitch_w_div16; | ||
491 | struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; | 490 | struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; |
492 | 491 | ||
493 | vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); | 492 | vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); |
@@ -530,15 +529,6 @@ static int vidioc_venc_s_fmt_out(struct file *file, void *priv, | |||
530 | q_data->coded_width = f->fmt.pix_mp.width; | 529 | q_data->coded_width = f->fmt.pix_mp.width; |
531 | q_data->coded_height = f->fmt.pix_mp.height; | 530 | q_data->coded_height = f->fmt.pix_mp.height; |
532 | 531 | ||
533 | pitch_w_div16 = DIV_ROUND_UP(q_data->visible_width, 16); | ||
534 | if (pitch_w_div16 % 8 != 0) { | ||
535 | /* Adjust returned width/height, so application could correctly | ||
536 | * allocate hw required memory | ||
537 | */ | ||
538 | q_data->visible_height += 32; | ||
539 | vidioc_try_fmt(f, q_data->fmt); | ||
540 | } | ||
541 | |||
542 | q_data->field = f->fmt.pix_mp.field; | 532 | q_data->field = f->fmt.pix_mp.field; |
543 | ctx->colorspace = f->fmt.pix_mp.colorspace; | 533 | ctx->colorspace = f->fmt.pix_mp.colorspace; |
544 | ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; | 534 | ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; |
@@ -878,7 +868,8 @@ static int mtk_venc_encode_header(void *priv) | |||
878 | { | 868 | { |
879 | struct mtk_vcodec_ctx *ctx = priv; | 869 | struct mtk_vcodec_ctx *ctx = priv; |
880 | int ret; | 870 | int ret; |
881 | struct vb2_buffer *dst_buf; | 871 | struct vb2_buffer *src_buf, *dst_buf; |
872 | struct vb2_v4l2_buffer *dst_vb2_v4l2, *src_vb2_v4l2; | ||
882 | struct mtk_vcodec_mem bs_buf; | 873 | struct mtk_vcodec_mem bs_buf; |
883 | struct venc_done_result enc_result; | 874 | struct venc_done_result enc_result; |
884 | 875 | ||
@@ -911,6 +902,15 @@ static int mtk_venc_encode_header(void *priv) | |||
911 | mtk_v4l2_err("venc_if_encode failed=%d", ret); | 902 | mtk_v4l2_err("venc_if_encode failed=%d", ret); |
912 | return -EINVAL; | 903 | return -EINVAL; |
913 | } | 904 | } |
905 | src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); | ||
906 | if (src_buf) { | ||
907 | src_vb2_v4l2 = to_vb2_v4l2_buffer(src_buf); | ||
908 | dst_vb2_v4l2 = to_vb2_v4l2_buffer(dst_buf); | ||
909 | dst_buf->timestamp = src_buf->timestamp; | ||
910 | dst_vb2_v4l2->timecode = src_vb2_v4l2->timecode; | ||
911 | } else { | ||
912 | mtk_v4l2_err("No timestamp for the header buffer."); | ||
913 | } | ||
914 | 914 | ||
915 | ctx->state = MTK_STATE_HEADER; | 915 | ctx->state = MTK_STATE_HEADER; |
916 | dst_buf->planes[0].bytesused = enc_result.bs_size; | 916 | dst_buf->planes[0].bytesused = enc_result.bs_size; |
@@ -1003,7 +1003,7 @@ static void mtk_venc_worker(struct work_struct *work) | |||
1003 | struct mtk_vcodec_mem bs_buf; | 1003 | struct mtk_vcodec_mem bs_buf; |
1004 | struct venc_done_result enc_result; | 1004 | struct venc_done_result enc_result; |
1005 | int ret, i; | 1005 | int ret, i; |
1006 | struct vb2_v4l2_buffer *vb2_v4l2; | 1006 | struct vb2_v4l2_buffer *dst_vb2_v4l2, *src_vb2_v4l2; |
1007 | 1007 | ||
1008 | /* check dst_buf, dst_buf may be removed in device_run | 1008 | /* check dst_buf, dst_buf may be removed in device_run |
1009 | * to stored encdoe header so we need check dst_buf and | 1009 | * to stored encdoe header so we need check dst_buf and |
@@ -1043,9 +1043,14 @@ static void mtk_venc_worker(struct work_struct *work) | |||
1043 | ret = venc_if_encode(ctx, VENC_START_OPT_ENCODE_FRAME, | 1043 | ret = venc_if_encode(ctx, VENC_START_OPT_ENCODE_FRAME, |
1044 | &frm_buf, &bs_buf, &enc_result); | 1044 | &frm_buf, &bs_buf, &enc_result); |
1045 | 1045 | ||
1046 | vb2_v4l2 = container_of(dst_buf, struct vb2_v4l2_buffer, vb2_buf); | 1046 | src_vb2_v4l2 = to_vb2_v4l2_buffer(src_buf); |
1047 | dst_vb2_v4l2 = to_vb2_v4l2_buffer(dst_buf); | ||
1048 | |||
1049 | dst_buf->timestamp = src_buf->timestamp; | ||
1050 | dst_vb2_v4l2->timecode = src_vb2_v4l2->timecode; | ||
1051 | |||
1047 | if (enc_result.is_key_frm) | 1052 | if (enc_result.is_key_frm) |
1048 | vb2_v4l2->flags |= V4L2_BUF_FLAG_KEYFRAME; | 1053 | dst_vb2_v4l2->flags |= V4L2_BUF_FLAG_KEYFRAME; |
1049 | 1054 | ||
1050 | if (ret) { | 1055 | if (ret) { |
1051 | v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), | 1056 | v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), |
@@ -1217,7 +1222,7 @@ int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx) | |||
1217 | 0, V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE); | 1222 | 0, V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE); |
1218 | v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_PROFILE, | 1223 | v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_PROFILE, |
1219 | V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, | 1224 | V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, |
1220 | 0, V4L2_MPEG_VIDEO_H264_PROFILE_MAIN); | 1225 | 0, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH); |
1221 | v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_LEVEL, | 1226 | v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_LEVEL, |
1222 | V4L2_MPEG_VIDEO_H264_LEVEL_4_2, | 1227 | V4L2_MPEG_VIDEO_H264_LEVEL_4_2, |
1223 | 0, V4L2_MPEG_VIDEO_H264_LEVEL_4_0); | 1228 | 0, V4L2_MPEG_VIDEO_H264_LEVEL_4_0); |
@@ -1288,5 +1293,10 @@ int mtk_venc_lock(struct mtk_vcodec_ctx *ctx) | |||
1288 | 1293 | ||
1289 | void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx) | 1294 | void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx) |
1290 | { | 1295 | { |
1291 | venc_if_deinit(ctx); | 1296 | int ret = venc_if_deinit(ctx); |
1297 | |||
1298 | if (ret) | ||
1299 | mtk_v4l2_err("venc_if_deinit failed=%d", ret); | ||
1300 | |||
1301 | ctx->state = MTK_STATE_FREE; | ||
1292 | } | 1302 | } |
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c index c7806ecda2dd..5cd2151431bf 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c | |||
@@ -218,11 +218,15 @@ static int fops_vcodec_release(struct file *file) | |||
218 | mtk_v4l2_debug(1, "[%d] encoder", ctx->id); | 218 | mtk_v4l2_debug(1, "[%d] encoder", ctx->id); |
219 | mutex_lock(&dev->dev_mutex); | 219 | mutex_lock(&dev->dev_mutex); |
220 | 220 | ||
221 | /* | ||
222 | * Call v4l2_m2m_ctx_release to make sure the worker thread is not | ||
223 | * running after venc_if_deinit. | ||
224 | */ | ||
225 | v4l2_m2m_ctx_release(ctx->m2m_ctx); | ||
221 | mtk_vcodec_enc_release(ctx); | 226 | mtk_vcodec_enc_release(ctx); |
222 | v4l2_fh_del(&ctx->fh); | 227 | v4l2_fh_del(&ctx->fh); |
223 | v4l2_fh_exit(&ctx->fh); | 228 | v4l2_fh_exit(&ctx->fh); |
224 | v4l2_ctrl_handler_free(&ctx->ctrl_hdl); | 229 | v4l2_ctrl_handler_free(&ctx->ctrl_hdl); |
225 | v4l2_m2m_ctx_release(ctx->m2m_ctx); | ||
226 | 230 | ||
227 | list_del_init(&ctx->list); | 231 | list_del_init(&ctx->list); |
228 | dev->num_instances--; | 232 | dev->num_instances--; |
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h index 33e890f5aa9c..12131855b46a 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h | |||
@@ -16,7 +16,6 @@ | |||
16 | #define _MTK_VCODEC_INTR_H_ | 16 | #define _MTK_VCODEC_INTR_H_ |
17 | 17 | ||
18 | #define MTK_INST_IRQ_RECEIVED 0x1 | 18 | #define MTK_INST_IRQ_RECEIVED 0x1 |
19 | #define MTK_INST_WORK_THREAD_ABORT_DONE 0x2 | ||
20 | 19 | ||
21 | struct mtk_vcodec_ctx; | 20 | struct mtk_vcodec_ctx; |
22 | 21 | ||
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c index 9a600525b3c1..63d4be4ff327 100644 --- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c +++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c | |||
@@ -61,6 +61,8 @@ enum venc_h264_bs_mode { | |||
61 | 61 | ||
62 | /* | 62 | /* |
63 | * struct venc_h264_vpu_config - Structure for h264 encoder configuration | 63 | * struct venc_h264_vpu_config - Structure for h264 encoder configuration |
64 | * AP-W/R : AP is writer/reader on this item | ||
65 | * VPU-W/R: VPU is write/reader on this item | ||
64 | * @input_fourcc: input fourcc | 66 | * @input_fourcc: input fourcc |
65 | * @bitrate: target bitrate (in bps) | 67 | * @bitrate: target bitrate (in bps) |
66 | * @pic_w: picture width. Picture size is visible stream resolution, in pixels, | 68 | * @pic_w: picture width. Picture size is visible stream resolution, in pixels, |
@@ -94,13 +96,13 @@ struct venc_h264_vpu_config { | |||
94 | 96 | ||
95 | /* | 97 | /* |
96 | * struct venc_h264_vpu_buf - Structure for buffer information | 98 | * struct venc_h264_vpu_buf - Structure for buffer information |
97 | * @align: buffer alignment (in bytes) | 99 | * AP-W/R : AP is writer/reader on this item |
100 | * VPU-W/R: VPU is write/reader on this item | ||
98 | * @iova: IO virtual address | 101 | * @iova: IO virtual address |
99 | * @vpua: VPU side memory addr which is used by RC_CODE | 102 | * @vpua: VPU side memory addr which is used by RC_CODE |
100 | * @size: buffer size (in bytes) | 103 | * @size: buffer size (in bytes) |
101 | */ | 104 | */ |
102 | struct venc_h264_vpu_buf { | 105 | struct venc_h264_vpu_buf { |
103 | u32 align; | ||
104 | u32 iova; | 106 | u32 iova; |
105 | u32 vpua; | 107 | u32 vpua; |
106 | u32 size; | 108 | u32 size; |
@@ -108,6 +110,8 @@ struct venc_h264_vpu_buf { | |||
108 | 110 | ||
109 | /* | 111 | /* |
110 | * struct venc_h264_vsi - Structure for VPU driver control and info share | 112 | * struct venc_h264_vsi - Structure for VPU driver control and info share |
113 | * AP-W/R : AP is writer/reader on this item | ||
114 | * VPU-W/R: VPU is write/reader on this item | ||
111 | * This structure is allocated in VPU side and shared to AP side. | 115 | * This structure is allocated in VPU side and shared to AP side. |
112 | * @config: h264 encoder configuration | 116 | * @config: h264 encoder configuration |
113 | * @work_bufs: working buffer information in VPU side | 117 | * @work_bufs: working buffer information in VPU side |
@@ -150,12 +154,6 @@ struct venc_h264_inst { | |||
150 | struct mtk_vcodec_ctx *ctx; | 154 | struct mtk_vcodec_ctx *ctx; |
151 | }; | 155 | }; |
152 | 156 | ||
153 | static inline void h264_write_reg(struct venc_h264_inst *inst, u32 addr, | ||
154 | u32 val) | ||
155 | { | ||
156 | writel(val, inst->hw_base + addr); | ||
157 | } | ||
158 | |||
159 | static inline u32 h264_read_reg(struct venc_h264_inst *inst, u32 addr) | 157 | static inline u32 h264_read_reg(struct venc_h264_inst *inst, u32 addr) |
160 | { | 158 | { |
161 | return readl(inst->hw_base + addr); | 159 | return readl(inst->hw_base + addr); |
@@ -214,6 +212,8 @@ static unsigned int h264_get_level(struct venc_h264_inst *inst, | |||
214 | return 40; | 212 | return 40; |
215 | case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: | 213 | case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: |
216 | return 41; | 214 | return 41; |
215 | case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: | ||
216 | return 42; | ||
217 | default: | 217 | default: |
218 | mtk_vcodec_debug(inst, "unsupported level %d", level); | 218 | mtk_vcodec_debug(inst, "unsupported level %d", level); |
219 | return 31; | 219 | return 31; |
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c index 60bbcd2a0510..6d9758479f9a 100644 --- a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c +++ b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c | |||
@@ -56,6 +56,8 @@ enum venc_vp8_vpu_work_buf { | |||
56 | 56 | ||
57 | /* | 57 | /* |
58 | * struct venc_vp8_vpu_config - Structure for vp8 encoder configuration | 58 | * struct venc_vp8_vpu_config - Structure for vp8 encoder configuration |
59 | * AP-W/R : AP is writer/reader on this item | ||
60 | * VPU-W/R: VPU is write/reader on this item | ||
59 | * @input_fourcc: input fourcc | 61 | * @input_fourcc: input fourcc |
60 | * @bitrate: target bitrate (in bps) | 62 | * @bitrate: target bitrate (in bps) |
61 | * @pic_w: picture width. Picture size is visible stream resolution, in pixels, | 63 | * @pic_w: picture width. Picture size is visible stream resolution, in pixels, |
@@ -83,14 +85,14 @@ struct venc_vp8_vpu_config { | |||
83 | }; | 85 | }; |
84 | 86 | ||
85 | /* | 87 | /* |
86 | * struct venc_vp8_vpu_buf -Structure for buffer information | 88 | * struct venc_vp8_vpu_buf - Structure for buffer information |
87 | * @align: buffer alignment (in bytes) | 89 | * AP-W/R : AP is writer/reader on this item |
90 | * VPU-W/R: VPU is write/reader on this item | ||
88 | * @iova: IO virtual address | 91 | * @iova: IO virtual address |
89 | * @vpua: VPU side memory addr which is used by RC_CODE | 92 | * @vpua: VPU side memory addr which is used by RC_CODE |
90 | * @size: buffer size (in bytes) | 93 | * @size: buffer size (in bytes) |
91 | */ | 94 | */ |
92 | struct venc_vp8_vpu_buf { | 95 | struct venc_vp8_vpu_buf { |
93 | u32 align; | ||
94 | u32 iova; | 96 | u32 iova; |
95 | u32 vpua; | 97 | u32 vpua; |
96 | u32 size; | 98 | u32 size; |
@@ -98,6 +100,8 @@ struct venc_vp8_vpu_buf { | |||
98 | 100 | ||
99 | /* | 101 | /* |
100 | * struct venc_vp8_vsi - Structure for VPU driver control and info share | 102 | * struct venc_vp8_vsi - Structure for VPU driver control and info share |
103 | * AP-W/R : AP is writer/reader on this item | ||
104 | * VPU-W/R: VPU is write/reader on this item | ||
101 | * This structure is allocated in VPU side and shared to AP side. | 105 | * This structure is allocated in VPU side and shared to AP side. |
102 | * @config: vp8 encoder configuration | 106 | * @config: vp8 encoder configuration |
103 | * @work_bufs: working buffer information in VPU side | 107 | * @work_bufs: working buffer information in VPU side |
@@ -138,12 +142,6 @@ struct venc_vp8_inst { | |||
138 | struct mtk_vcodec_ctx *ctx; | 142 | struct mtk_vcodec_ctx *ctx; |
139 | }; | 143 | }; |
140 | 144 | ||
141 | static inline void vp8_enc_write_reg(struct venc_vp8_inst *inst, u32 addr, | ||
142 | u32 val) | ||
143 | { | ||
144 | writel(val, inst->hw_base + addr); | ||
145 | } | ||
146 | |||
147 | static inline u32 vp8_enc_read_reg(struct venc_vp8_inst *inst, u32 addr) | 145 | static inline u32 vp8_enc_read_reg(struct venc_vp8_inst *inst, u32 addr) |
148 | { | 146 | { |
149 | return readl(inst->hw_base + addr); | 147 | return readl(inst->hw_base + addr); |
diff --git a/drivers/media/platform/rcar-fcp.c b/drivers/media/platform/rcar-fcp.c index 6a7bcc3028b1..bc50c69ee0c5 100644 --- a/drivers/media/platform/rcar-fcp.c +++ b/drivers/media/platform/rcar-fcp.c | |||
@@ -99,10 +99,16 @@ EXPORT_SYMBOL_GPL(rcar_fcp_put); | |||
99 | */ | 99 | */ |
100 | int rcar_fcp_enable(struct rcar_fcp_device *fcp) | 100 | int rcar_fcp_enable(struct rcar_fcp_device *fcp) |
101 | { | 101 | { |
102 | int error; | ||
103 | |||
102 | if (!fcp) | 104 | if (!fcp) |
103 | return 0; | 105 | return 0; |
104 | 106 | ||
105 | return pm_runtime_get_sync(fcp->dev); | 107 | error = pm_runtime_get_sync(fcp->dev); |
108 | if (error < 0) | ||
109 | return error; | ||
110 | |||
111 | return 0; | ||
106 | } | 112 | } |
107 | EXPORT_SYMBOL_GPL(rcar_fcp_enable); | 113 | EXPORT_SYMBOL_GPL(rcar_fcp_enable); |
108 | 114 | ||
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 869c83fb3c5d..f00f3e742265 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c | |||
@@ -2185,7 +2185,7 @@ static int gpmc_probe_dt(struct platform_device *pdev) | |||
2185 | return 0; | 2185 | return 0; |
2186 | } | 2186 | } |
2187 | 2187 | ||
2188 | static int gpmc_probe_dt_children(struct platform_device *pdev) | 2188 | static void gpmc_probe_dt_children(struct platform_device *pdev) |
2189 | { | 2189 | { |
2190 | int ret; | 2190 | int ret; |
2191 | struct device_node *child; | 2191 | struct device_node *child; |
@@ -2200,11 +2200,11 @@ static int gpmc_probe_dt_children(struct platform_device *pdev) | |||
2200 | else | 2200 | else |
2201 | ret = gpmc_probe_generic_child(pdev, child); | 2201 | ret = gpmc_probe_generic_child(pdev, child); |
2202 | 2202 | ||
2203 | if (ret) | 2203 | if (ret) { |
2204 | return ret; | 2204 | dev_err(&pdev->dev, "failed to probe DT child '%s': %d\n", |
2205 | child->name, ret); | ||
2206 | } | ||
2205 | } | 2207 | } |
2206 | |||
2207 | return 0; | ||
2208 | } | 2208 | } |
2209 | #else | 2209 | #else |
2210 | static int gpmc_probe_dt(struct platform_device *pdev) | 2210 | static int gpmc_probe_dt(struct platform_device *pdev) |
@@ -2212,9 +2212,8 @@ static int gpmc_probe_dt(struct platform_device *pdev) | |||
2212 | return 0; | 2212 | return 0; |
2213 | } | 2213 | } |
2214 | 2214 | ||
2215 | static int gpmc_probe_dt_children(struct platform_device *pdev) | 2215 | static void gpmc_probe_dt_children(struct platform_device *pdev) |
2216 | { | 2216 | { |
2217 | return 0; | ||
2218 | } | 2217 | } |
2219 | #endif /* CONFIG_OF */ | 2218 | #endif /* CONFIG_OF */ |
2220 | 2219 | ||
@@ -2369,16 +2368,10 @@ static int gpmc_probe(struct platform_device *pdev) | |||
2369 | goto setup_irq_failed; | 2368 | goto setup_irq_failed; |
2370 | } | 2369 | } |
2371 | 2370 | ||
2372 | rc = gpmc_probe_dt_children(pdev); | 2371 | gpmc_probe_dt_children(pdev); |
2373 | if (rc < 0) { | ||
2374 | dev_err(gpmc->dev, "failed to probe DT children\n"); | ||
2375 | goto dt_children_failed; | ||
2376 | } | ||
2377 | 2372 | ||
2378 | return 0; | 2373 | return 0; |
2379 | 2374 | ||
2380 | dt_children_failed: | ||
2381 | gpmc_free_irq(gpmc); | ||
2382 | setup_irq_failed: | 2375 | setup_irq_failed: |
2383 | gpmc_gpio_exit(gpmc); | 2376 | gpmc_gpio_exit(gpmc); |
2384 | gpio_init_failed: | 2377 | gpio_init_failed: |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index a216b4667742..d00252828966 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -345,16 +345,6 @@ config SENSORS_TSL2550 | |||
345 | This driver can also be built as a module. If so, the module | 345 | This driver can also be built as a module. If so, the module |
346 | will be called tsl2550. | 346 | will be called tsl2550. |
347 | 347 | ||
348 | config SENSORS_BH1780 | ||
349 | tristate "ROHM BH1780GLI ambient light sensor" | ||
350 | depends on I2C && SYSFS | ||
351 | help | ||
352 | If you say yes here you get support for the ROHM BH1780GLI | ||
353 | ambient light sensor. | ||
354 | |||
355 | This driver can also be built as a module. If so, the module | ||
356 | will be called bh1780gli. | ||
357 | |||
358 | config SENSORS_BH1770 | 348 | config SENSORS_BH1770 |
359 | tristate "BH1770GLC / SFH7770 combined ALS - Proximity sensor" | 349 | tristate "BH1770GLC / SFH7770 combined ALS - Proximity sensor" |
360 | depends on I2C | 350 | depends on I2C |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 7410c6d9a34d..fb32516ddfe2 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -19,7 +19,6 @@ obj-$(CONFIG_TIFM_CORE) += tifm_core.o | |||
19 | obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o | 19 | obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o |
20 | obj-$(CONFIG_PHANTOM) += phantom.o | 20 | obj-$(CONFIG_PHANTOM) += phantom.o |
21 | obj-$(CONFIG_QCOM_COINCELL) += qcom-coincell.o | 21 | obj-$(CONFIG_QCOM_COINCELL) += qcom-coincell.o |
22 | obj-$(CONFIG_SENSORS_BH1780) += bh1780gli.o | ||
23 | obj-$(CONFIG_SENSORS_BH1770) += bh1770glc.o | 22 | obj-$(CONFIG_SENSORS_BH1770) += bh1770glc.o |
24 | obj-$(CONFIG_SENSORS_APDS990X) += apds990x.o | 23 | obj-$(CONFIG_SENSORS_APDS990X) += apds990x.o |
25 | obj-$(CONFIG_SGI_IOC4) += ioc4.o | 24 | obj-$(CONFIG_SGI_IOC4) += ioc4.o |
diff --git a/drivers/misc/bh1780gli.c b/drivers/misc/bh1780gli.c deleted file mode 100644 index 7f90ce5a569a..000000000000 --- a/drivers/misc/bh1780gli.c +++ /dev/null | |||
@@ -1,259 +0,0 @@ | |||
1 | /* | ||
2 | * bh1780gli.c | ||
3 | * ROHM Ambient Light Sensor Driver | ||
4 | * | ||
5 | * Copyright (C) 2010 Texas Instruments | ||
6 | * Author: Hemanth V <hemanthv@ti.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License version 2 as published by | ||
10 | * the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | ||
20 | #include <linux/i2c.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/mutex.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/of.h> | ||
27 | |||
28 | #define BH1780_REG_CONTROL 0x80 | ||
29 | #define BH1780_REG_PARTID 0x8A | ||
30 | #define BH1780_REG_MANFID 0x8B | ||
31 | #define BH1780_REG_DLOW 0x8C | ||
32 | #define BH1780_REG_DHIGH 0x8D | ||
33 | |||
34 | #define BH1780_REVMASK (0xf) | ||
35 | #define BH1780_POWMASK (0x3) | ||
36 | #define BH1780_POFF (0x0) | ||
37 | #define BH1780_PON (0x3) | ||
38 | |||
39 | /* power on settling time in ms */ | ||
40 | #define BH1780_PON_DELAY 2 | ||
41 | |||
42 | struct bh1780_data { | ||
43 | struct i2c_client *client; | ||
44 | int power_state; | ||
45 | /* lock for sysfs operations */ | ||
46 | struct mutex lock; | ||
47 | }; | ||
48 | |||
49 | static int bh1780_write(struct bh1780_data *ddata, u8 reg, u8 val, char *msg) | ||
50 | { | ||
51 | int ret = i2c_smbus_write_byte_data(ddata->client, reg, val); | ||
52 | if (ret < 0) | ||
53 | dev_err(&ddata->client->dev, | ||
54 | "i2c_smbus_write_byte_data failed error %d Register (%s)\n", | ||
55 | ret, msg); | ||
56 | return ret; | ||
57 | } | ||
58 | |||
59 | static int bh1780_read(struct bh1780_data *ddata, u8 reg, char *msg) | ||
60 | { | ||
61 | int ret = i2c_smbus_read_byte_data(ddata->client, reg); | ||
62 | if (ret < 0) | ||
63 | dev_err(&ddata->client->dev, | ||
64 | "i2c_smbus_read_byte_data failed error %d Register (%s)\n", | ||
65 | ret, msg); | ||
66 | return ret; | ||
67 | } | ||
68 | |||
69 | static ssize_t bh1780_show_lux(struct device *dev, | ||
70 | struct device_attribute *attr, char *buf) | ||
71 | { | ||
72 | struct platform_device *pdev = to_platform_device(dev); | ||
73 | struct bh1780_data *ddata = platform_get_drvdata(pdev); | ||
74 | int lsb, msb; | ||
75 | |||
76 | lsb = bh1780_read(ddata, BH1780_REG_DLOW, "DLOW"); | ||
77 | if (lsb < 0) | ||
78 | return lsb; | ||
79 | |||
80 | msb = bh1780_read(ddata, BH1780_REG_DHIGH, "DHIGH"); | ||
81 | if (msb < 0) | ||
82 | return msb; | ||
83 | |||
84 | return sprintf(buf, "%d\n", (msb << 8) | lsb); | ||
85 | } | ||
86 | |||
87 | static ssize_t bh1780_show_power_state(struct device *dev, | ||
88 | struct device_attribute *attr, | ||
89 | char *buf) | ||
90 | { | ||
91 | struct platform_device *pdev = to_platform_device(dev); | ||
92 | struct bh1780_data *ddata = platform_get_drvdata(pdev); | ||
93 | int state; | ||
94 | |||
95 | state = bh1780_read(ddata, BH1780_REG_CONTROL, "CONTROL"); | ||
96 | if (state < 0) | ||
97 | return state; | ||
98 | |||
99 | return sprintf(buf, "%d\n", state & BH1780_POWMASK); | ||
100 | } | ||
101 | |||
102 | static ssize_t bh1780_store_power_state(struct device *dev, | ||
103 | struct device_attribute *attr, | ||
104 | const char *buf, size_t count) | ||
105 | { | ||
106 | struct platform_device *pdev = to_platform_device(dev); | ||
107 | struct bh1780_data *ddata = platform_get_drvdata(pdev); | ||
108 | unsigned long val; | ||
109 | int error; | ||
110 | |||
111 | error = kstrtoul(buf, 0, &val); | ||
112 | if (error) | ||
113 | return error; | ||
114 | |||
115 | if (val < BH1780_POFF || val > BH1780_PON) | ||
116 | return -EINVAL; | ||
117 | |||
118 | mutex_lock(&ddata->lock); | ||
119 | |||
120 | error = bh1780_write(ddata, BH1780_REG_CONTROL, val, "CONTROL"); | ||
121 | if (error < 0) { | ||
122 | mutex_unlock(&ddata->lock); | ||
123 | return error; | ||
124 | } | ||
125 | |||
126 | msleep(BH1780_PON_DELAY); | ||
127 | ddata->power_state = val; | ||
128 | mutex_unlock(&ddata->lock); | ||
129 | |||
130 | return count; | ||
131 | } | ||
132 | |||
133 | static DEVICE_ATTR(lux, S_IRUGO, bh1780_show_lux, NULL); | ||
134 | |||
135 | static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO, | ||
136 | bh1780_show_power_state, bh1780_store_power_state); | ||
137 | |||
138 | static struct attribute *bh1780_attributes[] = { | ||
139 | &dev_attr_power_state.attr, | ||
140 | &dev_attr_lux.attr, | ||
141 | NULL | ||
142 | }; | ||
143 | |||
144 | static const struct attribute_group bh1780_attr_group = { | ||
145 | .attrs = bh1780_attributes, | ||
146 | }; | ||
147 | |||
148 | static int bh1780_probe(struct i2c_client *client, | ||
149 | const struct i2c_device_id *id) | ||
150 | { | ||
151 | int ret; | ||
152 | struct bh1780_data *ddata; | ||
153 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | ||
154 | |||
155 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) | ||
156 | return -EIO; | ||
157 | |||
158 | ddata = devm_kzalloc(&client->dev, sizeof(struct bh1780_data), | ||
159 | GFP_KERNEL); | ||
160 | if (ddata == NULL) | ||
161 | return -ENOMEM; | ||
162 | |||
163 | ddata->client = client; | ||
164 | i2c_set_clientdata(client, ddata); | ||
165 | |||
166 | ret = bh1780_read(ddata, BH1780_REG_PARTID, "PART ID"); | ||
167 | if (ret < 0) | ||
168 | return ret; | ||
169 | |||
170 | dev_info(&client->dev, "Ambient Light Sensor, Rev : %d\n", | ||
171 | (ret & BH1780_REVMASK)); | ||
172 | |||
173 | mutex_init(&ddata->lock); | ||
174 | |||
175 | return sysfs_create_group(&client->dev.kobj, &bh1780_attr_group); | ||
176 | } | ||
177 | |||
178 | static int bh1780_remove(struct i2c_client *client) | ||
179 | { | ||
180 | sysfs_remove_group(&client->dev.kobj, &bh1780_attr_group); | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | #ifdef CONFIG_PM_SLEEP | ||
186 | static int bh1780_suspend(struct device *dev) | ||
187 | { | ||
188 | struct bh1780_data *ddata; | ||
189 | int state, ret; | ||
190 | struct i2c_client *client = to_i2c_client(dev); | ||
191 | |||
192 | ddata = i2c_get_clientdata(client); | ||
193 | state = bh1780_read(ddata, BH1780_REG_CONTROL, "CONTROL"); | ||
194 | if (state < 0) | ||
195 | return state; | ||
196 | |||
197 | ddata->power_state = state & BH1780_POWMASK; | ||
198 | |||
199 | ret = bh1780_write(ddata, BH1780_REG_CONTROL, BH1780_POFF, | ||
200 | "CONTROL"); | ||
201 | |||
202 | if (ret < 0) | ||
203 | return ret; | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | static int bh1780_resume(struct device *dev) | ||
209 | { | ||
210 | struct bh1780_data *ddata; | ||
211 | int state, ret; | ||
212 | struct i2c_client *client = to_i2c_client(dev); | ||
213 | |||
214 | ddata = i2c_get_clientdata(client); | ||
215 | state = ddata->power_state; | ||
216 | ret = bh1780_write(ddata, BH1780_REG_CONTROL, state, | ||
217 | "CONTROL"); | ||
218 | |||
219 | if (ret < 0) | ||
220 | return ret; | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | #endif /* CONFIG_PM_SLEEP */ | ||
225 | |||
226 | static SIMPLE_DEV_PM_OPS(bh1780_pm, bh1780_suspend, bh1780_resume); | ||
227 | |||
228 | static const struct i2c_device_id bh1780_id[] = { | ||
229 | { "bh1780", 0 }, | ||
230 | { }, | ||
231 | }; | ||
232 | |||
233 | MODULE_DEVICE_TABLE(i2c, bh1780_id); | ||
234 | |||
235 | #ifdef CONFIG_OF | ||
236 | static const struct of_device_id of_bh1780_match[] = { | ||
237 | { .compatible = "rohm,bh1780gli", }, | ||
238 | {}, | ||
239 | }; | ||
240 | |||
241 | MODULE_DEVICE_TABLE(of, of_bh1780_match); | ||
242 | #endif | ||
243 | |||
244 | static struct i2c_driver bh1780_driver = { | ||
245 | .probe = bh1780_probe, | ||
246 | .remove = bh1780_remove, | ||
247 | .id_table = bh1780_id, | ||
248 | .driver = { | ||
249 | .name = "bh1780", | ||
250 | .pm = &bh1780_pm, | ||
251 | .of_match_table = of_match_ptr(of_bh1780_match), | ||
252 | }, | ||
253 | }; | ||
254 | |||
255 | module_i2c_driver(bh1780_driver); | ||
256 | |||
257 | MODULE_DESCRIPTION("BH1780GLI Ambient Light Sensor Driver"); | ||
258 | MODULE_LICENSE("GPL"); | ||
259 | MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>"); | ||
diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c index 7ada5f1b7bb6..3519acebfdab 100644 --- a/drivers/misc/cxl/vphb.c +++ b/drivers/misc/cxl/vphb.c | |||
@@ -230,6 +230,11 @@ int cxl_pci_vphb_add(struct cxl_afu *afu) | |||
230 | if (phb->bus == NULL) | 230 | if (phb->bus == NULL) |
231 | return -ENXIO; | 231 | return -ENXIO; |
232 | 232 | ||
233 | /* Set release hook on root bus */ | ||
234 | pci_set_host_bridge_release(to_pci_host_bridge(phb->bus->bridge), | ||
235 | pcibios_free_controller_deferred, | ||
236 | (void *) phb); | ||
237 | |||
233 | /* Claim resources. This might need some rework as well depending | 238 | /* Claim resources. This might need some rework as well depending |
234 | * whether we are doing probe-only or not, like assigning unassigned | 239 | * whether we are doing probe-only or not, like assigning unassigned |
235 | * resources etc... | 240 | * resources etc... |
@@ -256,7 +261,10 @@ void cxl_pci_vphb_remove(struct cxl_afu *afu) | |||
256 | afu->phb = NULL; | 261 | afu->phb = NULL; |
257 | 262 | ||
258 | pci_remove_root_bus(phb->bus); | 263 | pci_remove_root_bus(phb->bus); |
259 | pcibios_free_controller(phb); | 264 | /* |
265 | * We don't free phb here - that's handled by | ||
266 | * pcibios_free_controller_deferred() | ||
267 | */ | ||
260 | } | 268 | } |
261 | 269 | ||
262 | static bool _cxl_pci_is_vphb_device(struct pci_controller *phb) | 270 | static bool _cxl_pci_is_vphb_device(struct pci_controller *phb) |
diff --git a/drivers/misc/lkdtm_rodata.c b/drivers/misc/lkdtm_rodata.c index 166b1db3969f..3564477b8c2d 100644 --- a/drivers/misc/lkdtm_rodata.c +++ b/drivers/misc/lkdtm_rodata.c | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | #include "lkdtm.h" | 5 | #include "lkdtm.h" |
6 | 6 | ||
7 | void lkdtm_rodata_do_nothing(void) | 7 | void notrace lkdtm_rodata_do_nothing(void) |
8 | { | 8 | { |
9 | /* Does nothing. We just want an architecture agnostic "return". */ | 9 | /* Does nothing. We just want an architecture agnostic "return". */ |
10 | } | 10 | } |
diff --git a/drivers/misc/lkdtm_usercopy.c b/drivers/misc/lkdtm_usercopy.c index 5525a204db93..1dd611423d8b 100644 --- a/drivers/misc/lkdtm_usercopy.c +++ b/drivers/misc/lkdtm_usercopy.c | |||
@@ -9,7 +9,15 @@ | |||
9 | #include <linux/uaccess.h> | 9 | #include <linux/uaccess.h> |
10 | #include <asm/cacheflush.h> | 10 | #include <asm/cacheflush.h> |
11 | 11 | ||
12 | static size_t cache_size = 1024; | 12 | /* |
13 | * Many of the tests here end up using const sizes, but those would | ||
14 | * normally be ignored by hardened usercopy, so force the compiler | ||
15 | * into choosing the non-const path to make sure we trigger the | ||
16 | * hardened usercopy checks by added "unconst" to all the const copies, | ||
17 | * and making sure "cache_size" isn't optimized into a const. | ||
18 | */ | ||
19 | static volatile size_t unconst = 0; | ||
20 | static volatile size_t cache_size = 1024; | ||
13 | static struct kmem_cache *bad_cache; | 21 | static struct kmem_cache *bad_cache; |
14 | 22 | ||
15 | static const unsigned char test_text[] = "This is a test.\n"; | 23 | static const unsigned char test_text[] = "This is a test.\n"; |
@@ -67,14 +75,14 @@ static noinline void do_usercopy_stack(bool to_user, bool bad_frame) | |||
67 | if (to_user) { | 75 | if (to_user) { |
68 | pr_info("attempting good copy_to_user of local stack\n"); | 76 | pr_info("attempting good copy_to_user of local stack\n"); |
69 | if (copy_to_user((void __user *)user_addr, good_stack, | 77 | if (copy_to_user((void __user *)user_addr, good_stack, |
70 | sizeof(good_stack))) { | 78 | unconst + sizeof(good_stack))) { |
71 | pr_warn("copy_to_user failed unexpectedly?!\n"); | 79 | pr_warn("copy_to_user failed unexpectedly?!\n"); |
72 | goto free_user; | 80 | goto free_user; |
73 | } | 81 | } |
74 | 82 | ||
75 | pr_info("attempting bad copy_to_user of distant stack\n"); | 83 | pr_info("attempting bad copy_to_user of distant stack\n"); |
76 | if (copy_to_user((void __user *)user_addr, bad_stack, | 84 | if (copy_to_user((void __user *)user_addr, bad_stack, |
77 | sizeof(good_stack))) { | 85 | unconst + sizeof(good_stack))) { |
78 | pr_warn("copy_to_user failed, but lacked Oops\n"); | 86 | pr_warn("copy_to_user failed, but lacked Oops\n"); |
79 | goto free_user; | 87 | goto free_user; |
80 | } | 88 | } |
@@ -88,14 +96,14 @@ static noinline void do_usercopy_stack(bool to_user, bool bad_frame) | |||
88 | 96 | ||
89 | pr_info("attempting good copy_from_user of local stack\n"); | 97 | pr_info("attempting good copy_from_user of local stack\n"); |
90 | if (copy_from_user(good_stack, (void __user *)user_addr, | 98 | if (copy_from_user(good_stack, (void __user *)user_addr, |
91 | sizeof(good_stack))) { | 99 | unconst + sizeof(good_stack))) { |
92 | pr_warn("copy_from_user failed unexpectedly?!\n"); | 100 | pr_warn("copy_from_user failed unexpectedly?!\n"); |
93 | goto free_user; | 101 | goto free_user; |
94 | } | 102 | } |
95 | 103 | ||
96 | pr_info("attempting bad copy_from_user of distant stack\n"); | 104 | pr_info("attempting bad copy_from_user of distant stack\n"); |
97 | if (copy_from_user(bad_stack, (void __user *)user_addr, | 105 | if (copy_from_user(bad_stack, (void __user *)user_addr, |
98 | sizeof(good_stack))) { | 106 | unconst + sizeof(good_stack))) { |
99 | pr_warn("copy_from_user failed, but lacked Oops\n"); | 107 | pr_warn("copy_from_user failed, but lacked Oops\n"); |
100 | goto free_user; | 108 | goto free_user; |
101 | } | 109 | } |
@@ -109,7 +117,7 @@ static void do_usercopy_heap_size(bool to_user) | |||
109 | { | 117 | { |
110 | unsigned long user_addr; | 118 | unsigned long user_addr; |
111 | unsigned char *one, *two; | 119 | unsigned char *one, *two; |
112 | const size_t size = 1024; | 120 | size_t size = unconst + 1024; |
113 | 121 | ||
114 | one = kmalloc(size, GFP_KERNEL); | 122 | one = kmalloc(size, GFP_KERNEL); |
115 | two = kmalloc(size, GFP_KERNEL); | 123 | two = kmalloc(size, GFP_KERNEL); |
@@ -285,13 +293,14 @@ void lkdtm_USERCOPY_KERNEL(void) | |||
285 | 293 | ||
286 | pr_info("attempting good copy_to_user from kernel rodata\n"); | 294 | pr_info("attempting good copy_to_user from kernel rodata\n"); |
287 | if (copy_to_user((void __user *)user_addr, test_text, | 295 | if (copy_to_user((void __user *)user_addr, test_text, |
288 | sizeof(test_text))) { | 296 | unconst + sizeof(test_text))) { |
289 | pr_warn("copy_to_user failed unexpectedly?!\n"); | 297 | pr_warn("copy_to_user failed unexpectedly?!\n"); |
290 | goto free_user; | 298 | goto free_user; |
291 | } | 299 | } |
292 | 300 | ||
293 | pr_info("attempting bad copy_to_user from kernel text\n"); | 301 | pr_info("attempting bad copy_to_user from kernel text\n"); |
294 | if (copy_to_user((void __user *)user_addr, vm_mmap, PAGE_SIZE)) { | 302 | if (copy_to_user((void __user *)user_addr, vm_mmap, |
303 | unconst + PAGE_SIZE)) { | ||
295 | pr_warn("copy_to_user failed, but lacked Oops\n"); | 304 | pr_warn("copy_to_user failed, but lacked Oops\n"); |
296 | goto free_user; | 305 | goto free_user; |
297 | } | 306 | } |
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index e2fb44cc5c37..dc3a854e02d3 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c | |||
@@ -1263,8 +1263,14 @@ static bool mei_me_fw_type_nm(struct pci_dev *pdev) | |||
1263 | static bool mei_me_fw_type_sps(struct pci_dev *pdev) | 1263 | static bool mei_me_fw_type_sps(struct pci_dev *pdev) |
1264 | { | 1264 | { |
1265 | u32 reg; | 1265 | u32 reg; |
1266 | /* Read ME FW Status check for SPS Firmware */ | 1266 | unsigned int devfn; |
1267 | pci_read_config_dword(pdev, PCI_CFG_HFS_1, ®); | 1267 | |
1268 | /* | ||
1269 | * Read ME FW Status register to check for SPS Firmware | ||
1270 | * The SPS FW is only signaled in pci function 0 | ||
1271 | */ | ||
1272 | devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0); | ||
1273 | pci_bus_read_config_dword(pdev->bus, devfn, PCI_CFG_HFS_1, ®); | ||
1268 | trace_mei_pci_cfg_read(&pdev->dev, "PCI_CFG_HFS_1", PCI_CFG_HFS_1, reg); | 1274 | trace_mei_pci_cfg_read(&pdev->dev, "PCI_CFG_HFS_1", PCI_CFG_HFS_1, reg); |
1269 | /* if bits [19:16] = 15, running SPS Firmware */ | 1275 | /* if bits [19:16] = 15, running SPS Firmware */ |
1270 | return (reg & 0xf0000) == 0xf0000; | 1276 | return (reg & 0xf0000) == 0xf0000; |
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 64e64da6da44..71cea9b296b2 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c | |||
@@ -85,8 +85,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = { | |||
85 | 85 | ||
86 | {MEI_PCI_DEVICE(MEI_DEV_ID_SPT, mei_me_pch8_cfg)}, | 86 | {MEI_PCI_DEVICE(MEI_DEV_ID_SPT, mei_me_pch8_cfg)}, |
87 | {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_2, mei_me_pch8_cfg)}, | 87 | {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_2, mei_me_pch8_cfg)}, |
88 | {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, mei_me_pch8_cfg)}, | 88 | {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, mei_me_pch8_sps_cfg)}, |
89 | {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, mei_me_pch8_cfg)}, | 89 | {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, mei_me_pch8_sps_cfg)}, |
90 | 90 | ||
91 | {MEI_PCI_DEVICE(MEI_DEV_ID_BXT_M, mei_me_pch8_cfg)}, | 91 | {MEI_PCI_DEVICE(MEI_DEV_ID_BXT_M, mei_me_pch8_cfg)}, |
92 | {MEI_PCI_DEVICE(MEI_DEV_ID_APL_I, mei_me_pch8_cfg)}, | 92 | {MEI_PCI_DEVICE(MEI_DEV_ID_APL_I, mei_me_pch8_cfg)}, |
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 48a5dd740f3b..2206d4477dbb 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -1726,6 +1726,7 @@ static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req) | |||
1726 | break; | 1726 | break; |
1727 | 1727 | ||
1728 | if (req_op(next) == REQ_OP_DISCARD || | 1728 | if (req_op(next) == REQ_OP_DISCARD || |
1729 | req_op(next) == REQ_OP_SECURE_ERASE || | ||
1729 | req_op(next) == REQ_OP_FLUSH) | 1730 | req_op(next) == REQ_OP_FLUSH) |
1730 | break; | 1731 | break; |
1731 | 1732 | ||
@@ -2150,6 +2151,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
2150 | struct mmc_card *card = md->queue.card; | 2151 | struct mmc_card *card = md->queue.card; |
2151 | struct mmc_host *host = card->host; | 2152 | struct mmc_host *host = card->host; |
2152 | unsigned long flags; | 2153 | unsigned long flags; |
2154 | bool req_is_special = mmc_req_is_special(req); | ||
2153 | 2155 | ||
2154 | if (req && !mq->mqrq_prev->req) | 2156 | if (req && !mq->mqrq_prev->req) |
2155 | /* claim host only for the first request */ | 2157 | /* claim host only for the first request */ |
@@ -2190,8 +2192,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
2190 | } | 2192 | } |
2191 | 2193 | ||
2192 | out: | 2194 | out: |
2193 | if ((!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) || | 2195 | if ((!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) || req_is_special) |
2194 | mmc_req_is_special(req)) | ||
2195 | /* | 2196 | /* |
2196 | * Release host when there are no more requests | 2197 | * Release host when there are no more requests |
2197 | * and after special request(discard, flush) is done. | 2198 | * and after special request(discard, flush) is done. |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index bf14642a576a..708057261b38 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -33,7 +33,8 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) | |||
33 | /* | 33 | /* |
34 | * We only like normal block requests and discards. | 34 | * We only like normal block requests and discards. |
35 | */ | 35 | */ |
36 | if (req->cmd_type != REQ_TYPE_FS && req_op(req) != REQ_OP_DISCARD) { | 36 | if (req->cmd_type != REQ_TYPE_FS && req_op(req) != REQ_OP_DISCARD && |
37 | req_op(req) != REQ_OP_SECURE_ERASE) { | ||
37 | blk_dump_rq_flags(req, "MMC bad request"); | 38 | blk_dump_rq_flags(req, "MMC bad request"); |
38 | return BLKPREP_KILL; | 39 | return BLKPREP_KILL; |
39 | } | 40 | } |
@@ -64,6 +65,8 @@ static int mmc_queue_thread(void *d) | |||
64 | spin_unlock_irq(q->queue_lock); | 65 | spin_unlock_irq(q->queue_lock); |
65 | 66 | ||
66 | if (req || mq->mqrq_prev->req) { | 67 | if (req || mq->mqrq_prev->req) { |
68 | bool req_is_special = mmc_req_is_special(req); | ||
69 | |||
67 | set_current_state(TASK_RUNNING); | 70 | set_current_state(TASK_RUNNING); |
68 | mq->issue_fn(mq, req); | 71 | mq->issue_fn(mq, req); |
69 | cond_resched(); | 72 | cond_resched(); |
@@ -79,7 +82,7 @@ static int mmc_queue_thread(void *d) | |||
79 | * has been finished. Do not assign it to previous | 82 | * has been finished. Do not assign it to previous |
80 | * request. | 83 | * request. |
81 | */ | 84 | */ |
82 | if (mmc_req_is_special(req)) | 85 | if (req_is_special) |
83 | mq->mqrq_cur->req = NULL; | 86 | mq->mqrq_cur->req = NULL; |
84 | 87 | ||
85 | mq->mqrq_prev->brq.mrq.data = NULL; | 88 | mq->mqrq_prev->brq.mrq.data = NULL; |
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h index d62531124d54..fee5e1271465 100644 --- a/drivers/mmc/card/queue.h +++ b/drivers/mmc/card/queue.h | |||
@@ -4,7 +4,9 @@ | |||
4 | static inline bool mmc_req_is_special(struct request *req) | 4 | static inline bool mmc_req_is_special(struct request *req) |
5 | { | 5 | { |
6 | return req && | 6 | return req && |
7 | (req_op(req) == REQ_OP_FLUSH || req_op(req) == REQ_OP_DISCARD); | 7 | (req_op(req) == REQ_OP_FLUSH || |
8 | req_op(req) == REQ_OP_DISCARD || | ||
9 | req_op(req) == REQ_OP_SECURE_ERASE); | ||
8 | } | 10 | } |
9 | 11 | ||
10 | struct request; | 12 | struct request; |
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 32380d5d4f6b..767af2026f8b 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
@@ -1112,11 +1112,12 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit) | |||
1112 | 1112 | ||
1113 | div = (host->bus_hz != clock) ? DIV_ROUND_UP(div, 2) : 0; | 1113 | div = (host->bus_hz != clock) ? DIV_ROUND_UP(div, 2) : 0; |
1114 | 1114 | ||
1115 | dev_info(&slot->mmc->class_dev, | 1115 | if (clock != slot->__clk_old || force_clkinit) |
1116 | "Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ div = %d)\n", | 1116 | dev_info(&slot->mmc->class_dev, |
1117 | slot->id, host->bus_hz, clock, | 1117 | "Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ div = %d)\n", |
1118 | div ? ((host->bus_hz / div) >> 1) : | 1118 | slot->id, host->bus_hz, clock, |
1119 | host->bus_hz, div); | 1119 | div ? ((host->bus_hz / div) >> 1) : |
1120 | host->bus_hz, div); | ||
1120 | 1121 | ||
1121 | /* disable clock */ | 1122 | /* disable clock */ |
1122 | mci_writel(host, CLKENA, 0); | 1123 | mci_writel(host, CLKENA, 0); |
@@ -1139,6 +1140,9 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit) | |||
1139 | 1140 | ||
1140 | /* inform CIU */ | 1141 | /* inform CIU */ |
1141 | mci_send_cmd(slot, sdmmc_cmd_bits, 0); | 1142 | mci_send_cmd(slot, sdmmc_cmd_bits, 0); |
1143 | |||
1144 | /* keep the last clock value that was requested from core */ | ||
1145 | slot->__clk_old = clock; | ||
1142 | } | 1146 | } |
1143 | 1147 | ||
1144 | host->current_speed = clock; | 1148 | host->current_speed = clock; |
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 9e740bc232a8..e8cd2dec3263 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h | |||
@@ -249,6 +249,8 @@ extern int dw_mci_resume(struct dw_mci *host); | |||
249 | * @queue_node: List node for placing this node in the @queue list of | 249 | * @queue_node: List node for placing this node in the @queue list of |
250 | * &struct dw_mci. | 250 | * &struct dw_mci. |
251 | * @clock: Clock rate configured by set_ios(). Protected by host->lock. | 251 | * @clock: Clock rate configured by set_ios(). Protected by host->lock. |
252 | * @__clk_old: The last clock value that was requested from core. | ||
253 | * Keeping track of this helps us to avoid spamming the console. | ||
252 | * @flags: Random state bits associated with the slot. | 254 | * @flags: Random state bits associated with the slot. |
253 | * @id: Number of this slot. | 255 | * @id: Number of this slot. |
254 | * @sdio_id: Number of this slot in the SDIO interrupt registers. | 256 | * @sdio_id: Number of this slot in the SDIO interrupt registers. |
@@ -263,6 +265,7 @@ struct dw_mci_slot { | |||
263 | struct list_head queue_node; | 265 | struct list_head queue_node; |
264 | 266 | ||
265 | unsigned int clock; | 267 | unsigned int clock; |
268 | unsigned int __clk_old; | ||
266 | 269 | ||
267 | unsigned long flags; | 270 | unsigned long flags; |
268 | #define DW_MMC_CARD_PRESENT 0 | 271 | #define DW_MMC_CARD_PRESENT 0 |
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index f23d65eb070d..be3c49fa7382 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -1016,14 +1016,16 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req) | |||
1016 | 1016 | ||
1017 | /* Only reconfigure if we have a different burst size */ | 1017 | /* Only reconfigure if we have a different burst size */ |
1018 | if (*bp != burst) { | 1018 | if (*bp != burst) { |
1019 | struct dma_slave_config cfg; | 1019 | struct dma_slave_config cfg = { |
1020 | 1020 | .src_addr = host->phys_base + | |
1021 | cfg.src_addr = host->phys_base + OMAP_MMC_REG(host, DATA); | 1021 | OMAP_MMC_REG(host, DATA), |
1022 | cfg.dst_addr = host->phys_base + OMAP_MMC_REG(host, DATA); | 1022 | .dst_addr = host->phys_base + |
1023 | cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | 1023 | OMAP_MMC_REG(host, DATA), |
1024 | cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | 1024 | .src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, |
1025 | cfg.src_maxburst = burst; | 1025 | .dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, |
1026 | cfg.dst_maxburst = burst; | 1026 | .src_maxburst = burst, |
1027 | .dst_maxburst = burst, | ||
1028 | }; | ||
1027 | 1029 | ||
1028 | if (dmaengine_slave_config(c, &cfg)) | 1030 | if (dmaengine_slave_config(c, &cfg)) |
1029 | goto use_pio; | 1031 | goto use_pio; |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 24ebc9a8de89..5f2f24a7360d 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -1409,11 +1409,18 @@ static int omap_hsmmc_pre_dma_transfer(struct omap_hsmmc_host *host, | |||
1409 | static int omap_hsmmc_setup_dma_transfer(struct omap_hsmmc_host *host, | 1409 | static int omap_hsmmc_setup_dma_transfer(struct omap_hsmmc_host *host, |
1410 | struct mmc_request *req) | 1410 | struct mmc_request *req) |
1411 | { | 1411 | { |
1412 | struct dma_slave_config cfg; | ||
1413 | struct dma_async_tx_descriptor *tx; | 1412 | struct dma_async_tx_descriptor *tx; |
1414 | int ret = 0, i; | 1413 | int ret = 0, i; |
1415 | struct mmc_data *data = req->data; | 1414 | struct mmc_data *data = req->data; |
1416 | struct dma_chan *chan; | 1415 | struct dma_chan *chan; |
1416 | struct dma_slave_config cfg = { | ||
1417 | .src_addr = host->mapbase + OMAP_HSMMC_DATA, | ||
1418 | .dst_addr = host->mapbase + OMAP_HSMMC_DATA, | ||
1419 | .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, | ||
1420 | .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, | ||
1421 | .src_maxburst = data->blksz / 4, | ||
1422 | .dst_maxburst = data->blksz / 4, | ||
1423 | }; | ||
1417 | 1424 | ||
1418 | /* Sanity check: all the SG entries must be aligned by block size. */ | 1425 | /* Sanity check: all the SG entries must be aligned by block size. */ |
1419 | for (i = 0; i < data->sg_len; i++) { | 1426 | for (i = 0; i < data->sg_len; i++) { |
@@ -1433,13 +1440,6 @@ static int omap_hsmmc_setup_dma_transfer(struct omap_hsmmc_host *host, | |||
1433 | 1440 | ||
1434 | chan = omap_hsmmc_get_dma_chan(host, data); | 1441 | chan = omap_hsmmc_get_dma_chan(host, data); |
1435 | 1442 | ||
1436 | cfg.src_addr = host->mapbase + OMAP_HSMMC_DATA; | ||
1437 | cfg.dst_addr = host->mapbase + OMAP_HSMMC_DATA; | ||
1438 | cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
1439 | cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
1440 | cfg.src_maxburst = data->blksz / 4; | ||
1441 | cfg.dst_maxburst = data->blksz / 4; | ||
1442 | |||
1443 | ret = dmaengine_slave_config(chan, &cfg); | 1443 | ret = dmaengine_slave_config(chan, &cfg); |
1444 | if (ret) | 1444 | if (ret) |
1445 | return ret; | 1445 | return ret; |
diff --git a/drivers/mmc/host/sdhci-st.c b/drivers/mmc/host/sdhci-st.c index c95ba83366a0..ed92ce729dde 100644 --- a/drivers/mmc/host/sdhci-st.c +++ b/drivers/mmc/host/sdhci-st.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | struct st_mmc_platform_data { | 29 | struct st_mmc_platform_data { |
30 | struct reset_control *rstc; | 30 | struct reset_control *rstc; |
31 | struct clk *icnclk; | ||
31 | void __iomem *top_ioaddr; | 32 | void __iomem *top_ioaddr; |
32 | }; | 33 | }; |
33 | 34 | ||
@@ -353,7 +354,7 @@ static int sdhci_st_probe(struct platform_device *pdev) | |||
353 | struct sdhci_host *host; | 354 | struct sdhci_host *host; |
354 | struct st_mmc_platform_data *pdata; | 355 | struct st_mmc_platform_data *pdata; |
355 | struct sdhci_pltfm_host *pltfm_host; | 356 | struct sdhci_pltfm_host *pltfm_host; |
356 | struct clk *clk; | 357 | struct clk *clk, *icnclk; |
357 | int ret = 0; | 358 | int ret = 0; |
358 | u16 host_version; | 359 | u16 host_version; |
359 | struct resource *res; | 360 | struct resource *res; |
@@ -365,6 +366,11 @@ static int sdhci_st_probe(struct platform_device *pdev) | |||
365 | return PTR_ERR(clk); | 366 | return PTR_ERR(clk); |
366 | } | 367 | } |
367 | 368 | ||
369 | /* ICN clock isn't compulsory, but use it if it's provided. */ | ||
370 | icnclk = devm_clk_get(&pdev->dev, "icn"); | ||
371 | if (IS_ERR(icnclk)) | ||
372 | icnclk = NULL; | ||
373 | |||
368 | rstc = devm_reset_control_get(&pdev->dev, NULL); | 374 | rstc = devm_reset_control_get(&pdev->dev, NULL); |
369 | if (IS_ERR(rstc)) | 375 | if (IS_ERR(rstc)) |
370 | rstc = NULL; | 376 | rstc = NULL; |
@@ -389,6 +395,7 @@ static int sdhci_st_probe(struct platform_device *pdev) | |||
389 | } | 395 | } |
390 | 396 | ||
391 | clk_prepare_enable(clk); | 397 | clk_prepare_enable(clk); |
398 | clk_prepare_enable(icnclk); | ||
392 | 399 | ||
393 | /* Configure the FlashSS Top registers for setting eMMC TX/RX delay */ | 400 | /* Configure the FlashSS Top registers for setting eMMC TX/RX delay */ |
394 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 401 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
@@ -400,6 +407,7 @@ static int sdhci_st_probe(struct platform_device *pdev) | |||
400 | } | 407 | } |
401 | 408 | ||
402 | pltfm_host->clk = clk; | 409 | pltfm_host->clk = clk; |
410 | pdata->icnclk = icnclk; | ||
403 | 411 | ||
404 | /* Configure the Arasan HC inside the flashSS */ | 412 | /* Configure the Arasan HC inside the flashSS */ |
405 | st_mmcss_cconfig(np, host); | 413 | st_mmcss_cconfig(np, host); |
@@ -422,6 +430,7 @@ static int sdhci_st_probe(struct platform_device *pdev) | |||
422 | return 0; | 430 | return 0; |
423 | 431 | ||
424 | err_out: | 432 | err_out: |
433 | clk_disable_unprepare(icnclk); | ||
425 | clk_disable_unprepare(clk); | 434 | clk_disable_unprepare(clk); |
426 | err_of: | 435 | err_of: |
427 | sdhci_pltfm_free(pdev); | 436 | sdhci_pltfm_free(pdev); |
@@ -442,6 +451,8 @@ static int sdhci_st_remove(struct platform_device *pdev) | |||
442 | 451 | ||
443 | ret = sdhci_pltfm_unregister(pdev); | 452 | ret = sdhci_pltfm_unregister(pdev); |
444 | 453 | ||
454 | clk_disable_unprepare(pdata->icnclk); | ||
455 | |||
445 | if (rstc) | 456 | if (rstc) |
446 | reset_control_assert(rstc); | 457 | reset_control_assert(rstc); |
447 | 458 | ||
@@ -462,6 +473,7 @@ static int sdhci_st_suspend(struct device *dev) | |||
462 | if (pdata->rstc) | 473 | if (pdata->rstc) |
463 | reset_control_assert(pdata->rstc); | 474 | reset_control_assert(pdata->rstc); |
464 | 475 | ||
476 | clk_disable_unprepare(pdata->icnclk); | ||
465 | clk_disable_unprepare(pltfm_host->clk); | 477 | clk_disable_unprepare(pltfm_host->clk); |
466 | out: | 478 | out: |
467 | return ret; | 479 | return ret; |
@@ -475,6 +487,7 @@ static int sdhci_st_resume(struct device *dev) | |||
475 | struct device_node *np = dev->of_node; | 487 | struct device_node *np = dev->of_node; |
476 | 488 | ||
477 | clk_prepare_enable(pltfm_host->clk); | 489 | clk_prepare_enable(pltfm_host->clk); |
490 | clk_prepare_enable(pdata->icnclk); | ||
478 | 491 | ||
479 | if (pdata->rstc) | 492 | if (pdata->rstc) |
480 | reset_control_deassert(pdata->rstc); | 493 | reset_control_deassert(pdata->rstc); |
diff --git a/drivers/mtd/nand/mtk_ecc.c b/drivers/mtd/nand/mtk_ecc.c index 25a4fbd4d24a..d54f666417e1 100644 --- a/drivers/mtd/nand/mtk_ecc.c +++ b/drivers/mtd/nand/mtk_ecc.c | |||
@@ -366,7 +366,8 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config, | |||
366 | u8 *data, u32 bytes) | 366 | u8 *data, u32 bytes) |
367 | { | 367 | { |
368 | dma_addr_t addr; | 368 | dma_addr_t addr; |
369 | u32 *p, len, i; | 369 | u8 *p; |
370 | u32 len, i, val; | ||
370 | int ret = 0; | 371 | int ret = 0; |
371 | 372 | ||
372 | addr = dma_map_single(ecc->dev, data, bytes, DMA_TO_DEVICE); | 373 | addr = dma_map_single(ecc->dev, data, bytes, DMA_TO_DEVICE); |
@@ -392,11 +393,14 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config, | |||
392 | 393 | ||
393 | /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */ | 394 | /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */ |
394 | len = (config->strength * ECC_PARITY_BITS + 7) >> 3; | 395 | len = (config->strength * ECC_PARITY_BITS + 7) >> 3; |
395 | p = (u32 *)(data + bytes); | 396 | p = data + bytes; |
396 | 397 | ||
397 | /* write the parity bytes generated by the ECC back to the OOB region */ | 398 | /* write the parity bytes generated by the ECC back to the OOB region */ |
398 | for (i = 0; i < len; i++) | 399 | for (i = 0; i < len; i++) { |
399 | p[i] = readl(ecc->regs + ECC_ENCPAR(i)); | 400 | if ((i % 4) == 0) |
401 | val = readl(ecc->regs + ECC_ENCPAR(i / 4)); | ||
402 | p[i] = (val >> ((i % 4) * 8)) & 0xff; | ||
403 | } | ||
400 | timeout: | 404 | timeout: |
401 | 405 | ||
402 | dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE); | 406 | dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE); |
diff --git a/drivers/mtd/nand/mtk_nand.c b/drivers/mtd/nand/mtk_nand.c index ddaa2acb9dd7..5223a2182ee4 100644 --- a/drivers/mtd/nand/mtk_nand.c +++ b/drivers/mtd/nand/mtk_nand.c | |||
@@ -93,6 +93,9 @@ | |||
93 | #define NFI_FSM_MASK (0xf << 16) | 93 | #define NFI_FSM_MASK (0xf << 16) |
94 | #define NFI_ADDRCNTR (0x70) | 94 | #define NFI_ADDRCNTR (0x70) |
95 | #define CNTR_MASK GENMASK(16, 12) | 95 | #define CNTR_MASK GENMASK(16, 12) |
96 | #define ADDRCNTR_SEC_SHIFT (12) | ||
97 | #define ADDRCNTR_SEC(val) \ | ||
98 | (((val) & CNTR_MASK) >> ADDRCNTR_SEC_SHIFT) | ||
96 | #define NFI_STRADDR (0x80) | 99 | #define NFI_STRADDR (0x80) |
97 | #define NFI_BYTELEN (0x84) | 100 | #define NFI_BYTELEN (0x84) |
98 | #define NFI_CSEL (0x90) | 101 | #define NFI_CSEL (0x90) |
@@ -699,7 +702,7 @@ static int mtk_nfc_do_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
699 | } | 702 | } |
700 | 703 | ||
701 | ret = readl_poll_timeout_atomic(nfc->regs + NFI_ADDRCNTR, reg, | 704 | ret = readl_poll_timeout_atomic(nfc->regs + NFI_ADDRCNTR, reg, |
702 | (reg & CNTR_MASK) >= chip->ecc.steps, | 705 | ADDRCNTR_SEC(reg) >= chip->ecc.steps, |
703 | 10, MTK_TIMEOUT); | 706 | 10, MTK_TIMEOUT); |
704 | if (ret) | 707 | if (ret) |
705 | dev_err(dev, "hwecc write timeout\n"); | 708 | dev_err(dev, "hwecc write timeout\n"); |
@@ -902,7 +905,7 @@ static int mtk_nfc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, | |||
902 | dev_warn(nfc->dev, "read ahb/dma done timeout\n"); | 905 | dev_warn(nfc->dev, "read ahb/dma done timeout\n"); |
903 | 906 | ||
904 | rc = readl_poll_timeout_atomic(nfc->regs + NFI_BYTELEN, reg, | 907 | rc = readl_poll_timeout_atomic(nfc->regs + NFI_BYTELEN, reg, |
905 | (reg & CNTR_MASK) >= sectors, 10, | 908 | ADDRCNTR_SEC(reg) >= sectors, 10, |
906 | MTK_TIMEOUT); | 909 | MTK_TIMEOUT); |
907 | if (rc < 0) { | 910 | if (rc < 0) { |
908 | dev_err(nfc->dev, "subpage done timeout\n"); | 911 | dev_err(nfc->dev, "subpage done timeout\n"); |
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 5173fadc9a4e..57cbe2b83849 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c | |||
@@ -943,7 +943,7 @@ static int mxc_v2_ooblayout_free(struct mtd_info *mtd, int section, | |||
943 | struct nand_chip *nand_chip = mtd_to_nand(mtd); | 943 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
944 | int stepsize = nand_chip->ecc.bytes == 9 ? 16 : 26; | 944 | int stepsize = nand_chip->ecc.bytes == 9 ? 16 : 26; |
945 | 945 | ||
946 | if (section > nand_chip->ecc.steps) | 946 | if (section >= nand_chip->ecc.steps) |
947 | return -ERANGE; | 947 | return -ERANGE; |
948 | 948 | ||
949 | if (!section) { | 949 | if (!section) { |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 217e8da0628c..9599ed6f1213 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1341,9 +1341,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1341 | slave_dev->name); | 1341 | slave_dev->name); |
1342 | } | 1342 | } |
1343 | 1343 | ||
1344 | /* already enslaved */ | 1344 | /* already in-use? */ |
1345 | if (slave_dev->flags & IFF_SLAVE) { | 1345 | if (netdev_is_rx_handler_busy(slave_dev)) { |
1346 | netdev_dbg(bond_dev, "Error: Device was already enslaved\n"); | 1346 | netdev_err(bond_dev, |
1347 | "Error: Device is in use and cannot be enslaved\n"); | ||
1347 | return -EBUSY; | 1348 | return -EBUSY; |
1348 | } | 1349 | } |
1349 | 1350 | ||
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 41c0fc9f3b14..16f7cadda5c3 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
@@ -1268,11 +1268,10 @@ static int __maybe_unused flexcan_suspend(struct device *device) | |||
1268 | struct flexcan_priv *priv = netdev_priv(dev); | 1268 | struct flexcan_priv *priv = netdev_priv(dev); |
1269 | int err; | 1269 | int err; |
1270 | 1270 | ||
1271 | err = flexcan_chip_disable(priv); | ||
1272 | if (err) | ||
1273 | return err; | ||
1274 | |||
1275 | if (netif_running(dev)) { | 1271 | if (netif_running(dev)) { |
1272 | err = flexcan_chip_disable(priv); | ||
1273 | if (err) | ||
1274 | return err; | ||
1276 | netif_stop_queue(dev); | 1275 | netif_stop_queue(dev); |
1277 | netif_device_detach(dev); | 1276 | netif_device_detach(dev); |
1278 | } | 1277 | } |
@@ -1285,13 +1284,17 @@ static int __maybe_unused flexcan_resume(struct device *device) | |||
1285 | { | 1284 | { |
1286 | struct net_device *dev = dev_get_drvdata(device); | 1285 | struct net_device *dev = dev_get_drvdata(device); |
1287 | struct flexcan_priv *priv = netdev_priv(dev); | 1286 | struct flexcan_priv *priv = netdev_priv(dev); |
1287 | int err; | ||
1288 | 1288 | ||
1289 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 1289 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
1290 | if (netif_running(dev)) { | 1290 | if (netif_running(dev)) { |
1291 | netif_device_attach(dev); | 1291 | netif_device_attach(dev); |
1292 | netif_start_queue(dev); | 1292 | netif_start_queue(dev); |
1293 | err = flexcan_chip_enable(priv); | ||
1294 | if (err) | ||
1295 | return err; | ||
1293 | } | 1296 | } |
1294 | return flexcan_chip_enable(priv); | 1297 | return 0; |
1295 | } | 1298 | } |
1296 | 1299 | ||
1297 | static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume); | 1300 | static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume); |
diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c index 2d1d22eec750..368bb0710d8f 100644 --- a/drivers/net/can/ifi_canfd/ifi_canfd.c +++ b/drivers/net/can/ifi_canfd/ifi_canfd.c | |||
@@ -81,6 +81,10 @@ | |||
81 | #define IFI_CANFD_TIME_SET_TIMEA_4_12_6_6 BIT(15) | 81 | #define IFI_CANFD_TIME_SET_TIMEA_4_12_6_6 BIT(15) |
82 | 82 | ||
83 | #define IFI_CANFD_TDELAY 0x1c | 83 | #define IFI_CANFD_TDELAY 0x1c |
84 | #define IFI_CANFD_TDELAY_DEFAULT 0xb | ||
85 | #define IFI_CANFD_TDELAY_MASK 0x3fff | ||
86 | #define IFI_CANFD_TDELAY_ABS BIT(14) | ||
87 | #define IFI_CANFD_TDELAY_EN BIT(15) | ||
84 | 88 | ||
85 | #define IFI_CANFD_ERROR 0x20 | 89 | #define IFI_CANFD_ERROR 0x20 |
86 | #define IFI_CANFD_ERROR_TX_OFFSET 0 | 90 | #define IFI_CANFD_ERROR_TX_OFFSET 0 |
@@ -641,7 +645,7 @@ static void ifi_canfd_set_bittiming(struct net_device *ndev) | |||
641 | struct ifi_canfd_priv *priv = netdev_priv(ndev); | 645 | struct ifi_canfd_priv *priv = netdev_priv(ndev); |
642 | const struct can_bittiming *bt = &priv->can.bittiming; | 646 | const struct can_bittiming *bt = &priv->can.bittiming; |
643 | const struct can_bittiming *dbt = &priv->can.data_bittiming; | 647 | const struct can_bittiming *dbt = &priv->can.data_bittiming; |
644 | u16 brp, sjw, tseg1, tseg2; | 648 | u16 brp, sjw, tseg1, tseg2, tdc; |
645 | 649 | ||
646 | /* Configure bit timing */ | 650 | /* Configure bit timing */ |
647 | brp = bt->brp - 2; | 651 | brp = bt->brp - 2; |
@@ -664,6 +668,11 @@ static void ifi_canfd_set_bittiming(struct net_device *ndev) | |||
664 | (brp << IFI_CANFD_TIME_PRESCALE_OFF) | | 668 | (brp << IFI_CANFD_TIME_PRESCALE_OFF) | |
665 | (sjw << IFI_CANFD_TIME_SJW_OFF_7_9_8_8), | 669 | (sjw << IFI_CANFD_TIME_SJW_OFF_7_9_8_8), |
666 | priv->base + IFI_CANFD_FTIME); | 670 | priv->base + IFI_CANFD_FTIME); |
671 | |||
672 | /* Configure transmitter delay */ | ||
673 | tdc = (dbt->brp * (dbt->phase_seg1 + 1)) & IFI_CANFD_TDELAY_MASK; | ||
674 | writel(IFI_CANFD_TDELAY_EN | IFI_CANFD_TDELAY_ABS | tdc, | ||
675 | priv->base + IFI_CANFD_TDELAY); | ||
667 | } | 676 | } |
668 | 677 | ||
669 | static void ifi_canfd_set_filter(struct net_device *ndev, const u32 id, | 678 | static void ifi_canfd_set_filter(struct net_device *ndev, const u32 id, |
diff --git a/drivers/net/dsa/bcm_sf2.h b/drivers/net/dsa/bcm_sf2.h index 463bed8cbe4c..dd446e466699 100644 --- a/drivers/net/dsa/bcm_sf2.h +++ b/drivers/net/dsa/bcm_sf2.h | |||
@@ -205,8 +205,8 @@ static inline void name##_writeq(struct bcm_sf2_priv *priv, u64 val, \ | |||
205 | static inline void intrl2_##which##_mask_clear(struct bcm_sf2_priv *priv, \ | 205 | static inline void intrl2_##which##_mask_clear(struct bcm_sf2_priv *priv, \ |
206 | u32 mask) \ | 206 | u32 mask) \ |
207 | { \ | 207 | { \ |
208 | intrl2_##which##_writel(priv, mask, INTRL2_CPU_MASK_CLEAR); \ | ||
209 | priv->irq##which##_mask &= ~(mask); \ | 208 | priv->irq##which##_mask &= ~(mask); \ |
209 | intrl2_##which##_writel(priv, mask, INTRL2_CPU_MASK_CLEAR); \ | ||
210 | } \ | 210 | } \ |
211 | static inline void intrl2_##which##_mask_set(struct bcm_sf2_priv *priv, \ | 211 | static inline void intrl2_##which##_mask_set(struct bcm_sf2_priv *priv, \ |
212 | u32 mask) \ | 212 | u32 mask) \ |
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index d1d9d3cf9139..710679067594 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c | |||
@@ -2656,15 +2656,19 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port) | |||
2656 | return ret; | 2656 | return ret; |
2657 | } | 2657 | } |
2658 | 2658 | ||
2659 | /* Rate Control: disable ingress rate limiting. */ | ||
2659 | if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) || | 2660 | if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) || |
2660 | mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) || | 2661 | mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) || |
2661 | mv88e6xxx_6185_family(chip) || mv88e6xxx_6095_family(chip) || | ||
2662 | mv88e6xxx_6320_family(chip)) { | 2662 | mv88e6xxx_6320_family(chip)) { |
2663 | /* Rate Control: disable ingress rate limiting. */ | ||
2664 | ret = _mv88e6xxx_reg_write(chip, REG_PORT(port), | 2663 | ret = _mv88e6xxx_reg_write(chip, REG_PORT(port), |
2665 | PORT_RATE_CONTROL, 0x0001); | 2664 | PORT_RATE_CONTROL, 0x0001); |
2666 | if (ret) | 2665 | if (ret) |
2667 | return ret; | 2666 | return ret; |
2667 | } else if (mv88e6xxx_6185_family(chip) || mv88e6xxx_6095_family(chip)) { | ||
2668 | ret = _mv88e6xxx_reg_write(chip, REG_PORT(port), | ||
2669 | PORT_RATE_CONTROL, 0x0000); | ||
2670 | if (ret) | ||
2671 | return ret; | ||
2668 | } | 2672 | } |
2669 | 2673 | ||
2670 | /* Port Control 1: disable trunking, disable sending | 2674 | /* Port Control 1: disable trunking, disable sending |
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index 6453148d066a..4eb17daefc4f 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c | |||
@@ -1545,6 +1545,8 @@ static const struct pci_device_id alx_pci_tbl[] = { | |||
1545 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, | 1545 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, |
1546 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_E2400), | 1546 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_E2400), |
1547 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, | 1547 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, |
1548 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_E2500), | ||
1549 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, | ||
1548 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8162), | 1550 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8162), |
1549 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, | 1551 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, |
1550 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8171) }, | 1552 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8171) }, |
diff --git a/drivers/net/ethernet/atheros/alx/reg.h b/drivers/net/ethernet/atheros/alx/reg.h index 0959e6824cb6..1fc2d852249f 100644 --- a/drivers/net/ethernet/atheros/alx/reg.h +++ b/drivers/net/ethernet/atheros/alx/reg.h | |||
@@ -38,6 +38,7 @@ | |||
38 | #define ALX_DEV_ID_AR8161 0x1091 | 38 | #define ALX_DEV_ID_AR8161 0x1091 |
39 | #define ALX_DEV_ID_E2200 0xe091 | 39 | #define ALX_DEV_ID_E2200 0xe091 |
40 | #define ALX_DEV_ID_E2400 0xe0a1 | 40 | #define ALX_DEV_ID_E2400 0xe0a1 |
41 | #define ALX_DEV_ID_E2500 0xe0b1 | ||
41 | #define ALX_DEV_ID_AR8162 0x1090 | 42 | #define ALX_DEV_ID_AR8162 0x1090 |
42 | #define ALX_DEV_ID_AR8171 0x10A1 | 43 | #define ALX_DEV_ID_AR8171 0x10A1 |
43 | #define ALX_DEV_ID_AR8172 0x10A0 | 44 | #define ALX_DEV_ID_AR8172 0x10A0 |
diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c index 9a9745c4047c..625235db644f 100644 --- a/drivers/net/ethernet/broadcom/bgmac-bcma.c +++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c | |||
@@ -159,7 +159,7 @@ static int bgmac_probe(struct bcma_device *core) | |||
159 | 159 | ||
160 | if (!bgmac_is_bcm4707_family(core)) { | 160 | if (!bgmac_is_bcm4707_family(core)) { |
161 | mii_bus = bcma_mdio_mii_register(core, bgmac->phyaddr); | 161 | mii_bus = bcma_mdio_mii_register(core, bgmac->phyaddr); |
162 | if (!IS_ERR(mii_bus)) { | 162 | if (IS_ERR(mii_bus)) { |
163 | err = PTR_ERR(mii_bus); | 163 | err = PTR_ERR(mii_bus); |
164 | goto err; | 164 | goto err; |
165 | } | 165 | } |
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 8fc3f3c137f8..505ceaf451e2 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c | |||
@@ -6356,10 +6356,6 @@ bnx2_open(struct net_device *dev) | |||
6356 | struct bnx2 *bp = netdev_priv(dev); | 6356 | struct bnx2 *bp = netdev_priv(dev); |
6357 | int rc; | 6357 | int rc; |
6358 | 6358 | ||
6359 | rc = bnx2_request_firmware(bp); | ||
6360 | if (rc < 0) | ||
6361 | goto out; | ||
6362 | |||
6363 | netif_carrier_off(dev); | 6359 | netif_carrier_off(dev); |
6364 | 6360 | ||
6365 | bnx2_disable_int(bp); | 6361 | bnx2_disable_int(bp); |
@@ -6428,7 +6424,6 @@ open_err: | |||
6428 | bnx2_free_irq(bp); | 6424 | bnx2_free_irq(bp); |
6429 | bnx2_free_mem(bp); | 6425 | bnx2_free_mem(bp); |
6430 | bnx2_del_napi(bp); | 6426 | bnx2_del_napi(bp); |
6431 | bnx2_release_firmware(bp); | ||
6432 | goto out; | 6427 | goto out; |
6433 | } | 6428 | } |
6434 | 6429 | ||
@@ -8575,6 +8570,12 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
8575 | 8570 | ||
8576 | pci_set_drvdata(pdev, dev); | 8571 | pci_set_drvdata(pdev, dev); |
8577 | 8572 | ||
8573 | rc = bnx2_request_firmware(bp); | ||
8574 | if (rc < 0) | ||
8575 | goto error; | ||
8576 | |||
8577 | |||
8578 | bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); | ||
8578 | memcpy(dev->dev_addr, bp->mac_addr, ETH_ALEN); | 8579 | memcpy(dev->dev_addr, bp->mac_addr, ETH_ALEN); |
8579 | 8580 | ||
8580 | dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | | 8581 | dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | |
@@ -8607,6 +8608,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
8607 | return 0; | 8608 | return 0; |
8608 | 8609 | ||
8609 | error: | 8610 | error: |
8611 | bnx2_release_firmware(bp); | ||
8610 | pci_iounmap(pdev, bp->regview); | 8612 | pci_iounmap(pdev, bp->regview); |
8611 | pci_release_regions(pdev); | 8613 | pci_release_regions(pdev); |
8612 | pci_disable_device(pdev); | 8614 | pci_disable_device(pdev); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 97e892511666..fa3386bb14f7 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -772,6 +772,11 @@ void bnx2x_fw_dump_lvl(struct bnx2x *bp, const char *lvl) | |||
772 | (bp->common.bc_ver & 0xff00) >> 8, | 772 | (bp->common.bc_ver & 0xff00) >> 8, |
773 | (bp->common.bc_ver & 0xff)); | 773 | (bp->common.bc_ver & 0xff)); |
774 | 774 | ||
775 | if (pci_channel_offline(bp->pdev)) { | ||
776 | BNX2X_ERR("Cannot dump MCP info while in PCI error\n"); | ||
777 | return; | ||
778 | } | ||
779 | |||
775 | val = REG_RD(bp, MCP_REG_MCPR_CPU_PROGRAM_COUNTER); | 780 | val = REG_RD(bp, MCP_REG_MCPR_CPU_PROGRAM_COUNTER); |
776 | if (val == REG_RD(bp, MCP_REG_MCPR_CPU_PROGRAM_COUNTER)) | 781 | if (val == REG_RD(bp, MCP_REG_MCPR_CPU_PROGRAM_COUNTER)) |
777 | BNX2X_ERR("%s" "MCP PC at 0x%x\n", lvl, val); | 782 | BNX2X_ERR("%s" "MCP PC at 0x%x\n", lvl, val); |
@@ -9415,10 +9420,16 @@ unload_error: | |||
9415 | /* Release IRQs */ | 9420 | /* Release IRQs */ |
9416 | bnx2x_free_irq(bp); | 9421 | bnx2x_free_irq(bp); |
9417 | 9422 | ||
9418 | /* Reset the chip */ | 9423 | /* Reset the chip, unless PCI function is offline. If we reach this |
9419 | rc = bnx2x_reset_hw(bp, reset_code); | 9424 | * point following a PCI error handling, it means device is really |
9420 | if (rc) | 9425 | * in a bad state and we're about to remove it, so reset the chip |
9421 | BNX2X_ERR("HW_RESET failed\n"); | 9426 | * is not a good idea. |
9427 | */ | ||
9428 | if (!pci_channel_offline(bp->pdev)) { | ||
9429 | rc = bnx2x_reset_hw(bp, reset_code); | ||
9430 | if (rc) | ||
9431 | BNX2X_ERR("HW_RESET failed\n"); | ||
9432 | } | ||
9422 | 9433 | ||
9423 | /* Report UNLOAD_DONE to MCP */ | 9434 | /* Report UNLOAD_DONE to MCP */ |
9424 | bnx2x_send_unload_done(bp, keep_link); | 9435 | bnx2x_send_unload_done(bp, keep_link); |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 2cf79100c9cb..228c964e709a 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
@@ -353,8 +353,8 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
353 | push_len = (length + sizeof(*tx_push) + 7) / 8; | 353 | push_len = (length + sizeof(*tx_push) + 7) / 8; |
354 | if (push_len > 16) { | 354 | if (push_len > 16) { |
355 | __iowrite64_copy(txr->tx_doorbell, tx_push_buf, 16); | 355 | __iowrite64_copy(txr->tx_doorbell, tx_push_buf, 16); |
356 | __iowrite64_copy(txr->tx_doorbell + 4, tx_push_buf + 1, | 356 | __iowrite32_copy(txr->tx_doorbell + 4, tx_push_buf + 1, |
357 | push_len - 16); | 357 | (push_len - 16) << 1); |
358 | } else { | 358 | } else { |
359 | __iowrite64_copy(txr->tx_doorbell, tx_push_buf, | 359 | __iowrite64_copy(txr->tx_doorbell, tx_push_buf, |
360 | push_len); | 360 | push_len); |
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 659261218d9f..a2551bcd1027 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -14012,6 +14012,7 @@ static int tg3_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) | |||
14012 | if ((ec->rx_coalesce_usecs > MAX_RXCOL_TICKS) || | 14012 | if ((ec->rx_coalesce_usecs > MAX_RXCOL_TICKS) || |
14013 | (!ec->rx_coalesce_usecs) || | 14013 | (!ec->rx_coalesce_usecs) || |
14014 | (ec->tx_coalesce_usecs > MAX_TXCOL_TICKS) || | 14014 | (ec->tx_coalesce_usecs > MAX_TXCOL_TICKS) || |
14015 | (!ec->tx_coalesce_usecs) || | ||
14015 | (ec->rx_max_coalesced_frames > MAX_RXMAX_FRAMES) || | 14016 | (ec->rx_max_coalesced_frames > MAX_RXMAX_FRAMES) || |
14016 | (ec->tx_max_coalesced_frames > MAX_TXMAX_FRAMES) || | 14017 | (ec->tx_max_coalesced_frames > MAX_TXMAX_FRAMES) || |
14017 | (ec->rx_coalesce_usecs_irq > max_rxcoal_tick_int) || | 14018 | (ec->rx_coalesce_usecs_irq > max_rxcoal_tick_int) || |
@@ -14022,16 +14023,6 @@ static int tg3_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) | |||
14022 | (ec->stats_block_coalesce_usecs < min_stat_coal_ticks)) | 14023 | (ec->stats_block_coalesce_usecs < min_stat_coal_ticks)) |
14023 | return -EINVAL; | 14024 | return -EINVAL; |
14024 | 14025 | ||
14025 | /* No rx interrupts will be generated if both are zero */ | ||
14026 | if ((ec->rx_coalesce_usecs == 0) && | ||
14027 | (ec->rx_max_coalesced_frames == 0)) | ||
14028 | return -EINVAL; | ||
14029 | |||
14030 | /* No tx interrupts will be generated if both are zero */ | ||
14031 | if ((ec->tx_coalesce_usecs == 0) && | ||
14032 | (ec->tx_max_coalesced_frames == 0)) | ||
14033 | return -EINVAL; | ||
14034 | |||
14035 | /* Only copy relevant parameters, ignore all others. */ | 14026 | /* Only copy relevant parameters, ignore all others. */ |
14036 | tp->coal.rx_coalesce_usecs = ec->rx_coalesce_usecs; | 14027 | tp->coal.rx_coalesce_usecs = ec->rx_coalesce_usecs; |
14037 | tp->coal.tx_coalesce_usecs = ec->tx_coalesce_usecs; | 14028 | tp->coal.tx_coalesce_usecs = ec->tx_coalesce_usecs; |
diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c index 0e4fdc3dd729..31f61a744d66 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c +++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c | |||
@@ -31,15 +31,10 @@ | |||
31 | #define BNAD_NUM_TXF_COUNTERS 12 | 31 | #define BNAD_NUM_TXF_COUNTERS 12 |
32 | #define BNAD_NUM_RXF_COUNTERS 10 | 32 | #define BNAD_NUM_RXF_COUNTERS 10 |
33 | #define BNAD_NUM_CQ_COUNTERS (3 + 5) | 33 | #define BNAD_NUM_CQ_COUNTERS (3 + 5) |
34 | #define BNAD_NUM_RXQ_COUNTERS 6 | 34 | #define BNAD_NUM_RXQ_COUNTERS 7 |
35 | #define BNAD_NUM_TXQ_COUNTERS 5 | 35 | #define BNAD_NUM_TXQ_COUNTERS 5 |
36 | 36 | ||
37 | #define BNAD_ETHTOOL_STATS_NUM \ | 37 | static const char *bnad_net_stats_strings[] = { |
38 | (sizeof(struct rtnl_link_stats64) / sizeof(u64) + \ | ||
39 | sizeof(struct bnad_drv_stats) / sizeof(u64) + \ | ||
40 | offsetof(struct bfi_enet_stats, rxf_stats[0]) / sizeof(u64)) | ||
41 | |||
42 | static const char *bnad_net_stats_strings[BNAD_ETHTOOL_STATS_NUM] = { | ||
43 | "rx_packets", | 38 | "rx_packets", |
44 | "tx_packets", | 39 | "tx_packets", |
45 | "rx_bytes", | 40 | "rx_bytes", |
@@ -50,22 +45,10 @@ static const char *bnad_net_stats_strings[BNAD_ETHTOOL_STATS_NUM] = { | |||
50 | "tx_dropped", | 45 | "tx_dropped", |
51 | "multicast", | 46 | "multicast", |
52 | "collisions", | 47 | "collisions", |
53 | |||
54 | "rx_length_errors", | 48 | "rx_length_errors", |
55 | "rx_over_errors", | ||
56 | "rx_crc_errors", | 49 | "rx_crc_errors", |
57 | "rx_frame_errors", | 50 | "rx_frame_errors", |
58 | "rx_fifo_errors", | ||
59 | "rx_missed_errors", | ||
60 | |||
61 | "tx_aborted_errors", | ||
62 | "tx_carrier_errors", | ||
63 | "tx_fifo_errors", | 51 | "tx_fifo_errors", |
64 | "tx_heartbeat_errors", | ||
65 | "tx_window_errors", | ||
66 | |||
67 | "rx_compressed", | ||
68 | "tx_compressed", | ||
69 | 52 | ||
70 | "netif_queue_stop", | 53 | "netif_queue_stop", |
71 | "netif_queue_wakeup", | 54 | "netif_queue_wakeup", |
@@ -254,6 +237,8 @@ static const char *bnad_net_stats_strings[BNAD_ETHTOOL_STATS_NUM] = { | |||
254 | "fc_tx_fid_parity_errors", | 237 | "fc_tx_fid_parity_errors", |
255 | }; | 238 | }; |
256 | 239 | ||
240 | #define BNAD_ETHTOOL_STATS_NUM ARRAY_SIZE(bnad_net_stats_strings) | ||
241 | |||
257 | static int | 242 | static int |
258 | bnad_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) | 243 | bnad_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) |
259 | { | 244 | { |
@@ -658,6 +643,8 @@ bnad_get_strings(struct net_device *netdev, u32 stringset, u8 *string) | |||
658 | string += ETH_GSTRING_LEN; | 643 | string += ETH_GSTRING_LEN; |
659 | sprintf(string, "rxq%d_allocbuf_failed", q_num); | 644 | sprintf(string, "rxq%d_allocbuf_failed", q_num); |
660 | string += ETH_GSTRING_LEN; | 645 | string += ETH_GSTRING_LEN; |
646 | sprintf(string, "rxq%d_mapbuf_failed", q_num); | ||
647 | string += ETH_GSTRING_LEN; | ||
661 | sprintf(string, "rxq%d_producer_index", q_num); | 648 | sprintf(string, "rxq%d_producer_index", q_num); |
662 | string += ETH_GSTRING_LEN; | 649 | string += ETH_GSTRING_LEN; |
663 | sprintf(string, "rxq%d_consumer_index", q_num); | 650 | sprintf(string, "rxq%d_consumer_index", q_num); |
@@ -678,6 +665,9 @@ bnad_get_strings(struct net_device *netdev, u32 stringset, u8 *string) | |||
678 | sprintf(string, "rxq%d_allocbuf_failed", | 665 | sprintf(string, "rxq%d_allocbuf_failed", |
679 | q_num); | 666 | q_num); |
680 | string += ETH_GSTRING_LEN; | 667 | string += ETH_GSTRING_LEN; |
668 | sprintf(string, "rxq%d_mapbuf_failed", | ||
669 | q_num); | ||
670 | string += ETH_GSTRING_LEN; | ||
681 | sprintf(string, "rxq%d_producer_index", | 671 | sprintf(string, "rxq%d_producer_index", |
682 | q_num); | 672 | q_num); |
683 | string += ETH_GSTRING_LEN; | 673 | string += ETH_GSTRING_LEN; |
@@ -854,9 +844,9 @@ bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, | |||
854 | u64 *buf) | 844 | u64 *buf) |
855 | { | 845 | { |
856 | struct bnad *bnad = netdev_priv(netdev); | 846 | struct bnad *bnad = netdev_priv(netdev); |
857 | int i, j, bi; | 847 | int i, j, bi = 0; |
858 | unsigned long flags; | 848 | unsigned long flags; |
859 | struct rtnl_link_stats64 *net_stats64; | 849 | struct rtnl_link_stats64 net_stats64; |
860 | u64 *stats64; | 850 | u64 *stats64; |
861 | u32 bmap; | 851 | u32 bmap; |
862 | 852 | ||
@@ -871,14 +861,25 @@ bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, | |||
871 | * under the same lock | 861 | * under the same lock |
872 | */ | 862 | */ |
873 | spin_lock_irqsave(&bnad->bna_lock, flags); | 863 | spin_lock_irqsave(&bnad->bna_lock, flags); |
874 | bi = 0; | ||
875 | memset(buf, 0, stats->n_stats * sizeof(u64)); | ||
876 | |||
877 | net_stats64 = (struct rtnl_link_stats64 *)buf; | ||
878 | bnad_netdev_qstats_fill(bnad, net_stats64); | ||
879 | bnad_netdev_hwstats_fill(bnad, net_stats64); | ||
880 | 864 | ||
881 | bi = sizeof(*net_stats64) / sizeof(u64); | 865 | memset(&net_stats64, 0, sizeof(net_stats64)); |
866 | bnad_netdev_qstats_fill(bnad, &net_stats64); | ||
867 | bnad_netdev_hwstats_fill(bnad, &net_stats64); | ||
868 | |||
869 | buf[bi++] = net_stats64.rx_packets; | ||
870 | buf[bi++] = net_stats64.tx_packets; | ||
871 | buf[bi++] = net_stats64.rx_bytes; | ||
872 | buf[bi++] = net_stats64.tx_bytes; | ||
873 | buf[bi++] = net_stats64.rx_errors; | ||
874 | buf[bi++] = net_stats64.tx_errors; | ||
875 | buf[bi++] = net_stats64.rx_dropped; | ||
876 | buf[bi++] = net_stats64.tx_dropped; | ||
877 | buf[bi++] = net_stats64.multicast; | ||
878 | buf[bi++] = net_stats64.collisions; | ||
879 | buf[bi++] = net_stats64.rx_length_errors; | ||
880 | buf[bi++] = net_stats64.rx_crc_errors; | ||
881 | buf[bi++] = net_stats64.rx_frame_errors; | ||
882 | buf[bi++] = net_stats64.tx_fifo_errors; | ||
882 | 883 | ||
883 | /* Get netif_queue_stopped from stack */ | 884 | /* Get netif_queue_stopped from stack */ |
884 | bnad->stats.drv_stats.netif_queue_stopped = netif_queue_stopped(netdev); | 885 | bnad->stats.drv_stats.netif_queue_stopped = netif_queue_stopped(netdev); |
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 89c0cfa9719f..d954a97b0b0b 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c | |||
@@ -1323,6 +1323,24 @@ dma_error: | |||
1323 | return 0; | 1323 | return 0; |
1324 | } | 1324 | } |
1325 | 1325 | ||
1326 | static inline int macb_clear_csum(struct sk_buff *skb) | ||
1327 | { | ||
1328 | /* no change for packets without checksum offloading */ | ||
1329 | if (skb->ip_summed != CHECKSUM_PARTIAL) | ||
1330 | return 0; | ||
1331 | |||
1332 | /* make sure we can modify the header */ | ||
1333 | if (unlikely(skb_cow_head(skb, 0))) | ||
1334 | return -1; | ||
1335 | |||
1336 | /* initialize checksum field | ||
1337 | * This is required - at least for Zynq, which otherwise calculates | ||
1338 | * wrong UDP header checksums for UDP packets with UDP data len <=2 | ||
1339 | */ | ||
1340 | *(__sum16 *)(skb_checksum_start(skb) + skb->csum_offset) = 0; | ||
1341 | return 0; | ||
1342 | } | ||
1343 | |||
1326 | static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) | 1344 | static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) |
1327 | { | 1345 | { |
1328 | u16 queue_index = skb_get_queue_mapping(skb); | 1346 | u16 queue_index = skb_get_queue_mapping(skb); |
@@ -1362,6 +1380,11 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1362 | return NETDEV_TX_BUSY; | 1380 | return NETDEV_TX_BUSY; |
1363 | } | 1381 | } |
1364 | 1382 | ||
1383 | if (macb_clear_csum(skb)) { | ||
1384 | dev_kfree_skb_any(skb); | ||
1385 | return NETDEV_TX_OK; | ||
1386 | } | ||
1387 | |||
1365 | /* Map socket buffer for DMA transfer */ | 1388 | /* Map socket buffer for DMA transfer */ |
1366 | if (!macb_tx_map(bp, queue, skb)) { | 1389 | if (!macb_tx_map(bp, queue, skb)) { |
1367 | dev_kfree_skb_any(skb); | 1390 | dev_kfree_skb_any(skb); |
diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h index 83025bb4737c..e29815d9e6f4 100644 --- a/drivers/net/ethernet/cavium/thunder/nic.h +++ b/drivers/net/ethernet/cavium/thunder/nic.h | |||
@@ -279,6 +279,7 @@ struct nicvf { | |||
279 | u8 sqs_id; | 279 | u8 sqs_id; |
280 | bool sqs_mode; | 280 | bool sqs_mode; |
281 | bool hw_tso; | 281 | bool hw_tso; |
282 | bool t88; | ||
282 | 283 | ||
283 | /* Receive buffer alloc */ | 284 | /* Receive buffer alloc */ |
284 | u32 rb_page_offset; | 285 | u32 rb_page_offset; |
diff --git a/drivers/net/ethernet/cavium/thunder/nic_main.c b/drivers/net/ethernet/cavium/thunder/nic_main.c index 16ed20357c5c..85cc782b9060 100644 --- a/drivers/net/ethernet/cavium/thunder/nic_main.c +++ b/drivers/net/ethernet/cavium/thunder/nic_main.c | |||
@@ -251,9 +251,14 @@ static void nic_set_tx_pkt_pad(struct nicpf *nic, int size) | |||
251 | int lmac; | 251 | int lmac; |
252 | u64 lmac_cfg; | 252 | u64 lmac_cfg; |
253 | 253 | ||
254 | /* Max value that can be set is 60 */ | 254 | /* There is a issue in HW where-in while sending GSO sized |
255 | if (size > 60) | 255 | * pkts as part of TSO, if pkt len falls below this size |
256 | size = 60; | 256 | * NIC will zero PAD packet and also updates IP total length. |
257 | * Hence set this value to lessthan min pkt size of MAC+IP+TCP | ||
258 | * headers, BGX will do the padding to transmit 64 byte pkt. | ||
259 | */ | ||
260 | if (size > 52) | ||
261 | size = 52; | ||
257 | 262 | ||
258 | for (lmac = 0; lmac < (MAX_BGX_PER_CN88XX * MAX_LMAC_PER_BGX); lmac++) { | 263 | for (lmac = 0; lmac < (MAX_BGX_PER_CN88XX * MAX_LMAC_PER_BGX); lmac++) { |
259 | lmac_cfg = nic_reg_read(nic, NIC_PF_LMAC_0_7_CFG | (lmac << 3)); | 264 | lmac_cfg = nic_reg_read(nic, NIC_PF_LMAC_0_7_CFG | (lmac << 3)); |
diff --git a/drivers/net/ethernet/cavium/thunder/nic_reg.h b/drivers/net/ethernet/cavium/thunder/nic_reg.h index afb10e326b4f..fab35a593898 100644 --- a/drivers/net/ethernet/cavium/thunder/nic_reg.h +++ b/drivers/net/ethernet/cavium/thunder/nic_reg.h | |||
@@ -170,7 +170,6 @@ | |||
170 | #define NIC_QSET_SQ_0_7_DOOR (0x010838) | 170 | #define NIC_QSET_SQ_0_7_DOOR (0x010838) |
171 | #define NIC_QSET_SQ_0_7_STATUS (0x010840) | 171 | #define NIC_QSET_SQ_0_7_STATUS (0x010840) |
172 | #define NIC_QSET_SQ_0_7_DEBUG (0x010848) | 172 | #define NIC_QSET_SQ_0_7_DEBUG (0x010848) |
173 | #define NIC_QSET_SQ_0_7_CNM_CHG (0x010860) | ||
174 | #define NIC_QSET_SQ_0_7_STAT_0_1 (0x010900) | 173 | #define NIC_QSET_SQ_0_7_STAT_0_1 (0x010900) |
175 | 174 | ||
176 | #define NIC_QSET_RBDR_0_1_CFG (0x010C00) | 175 | #define NIC_QSET_RBDR_0_1_CFG (0x010C00) |
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c index d2d8ef270142..ad4fddb55421 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c | |||
@@ -382,7 +382,10 @@ static void nicvf_get_regs(struct net_device *dev, | |||
382 | p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_DOOR, q); | 382 | p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_DOOR, q); |
383 | p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_STATUS, q); | 383 | p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_STATUS, q); |
384 | p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_DEBUG, q); | 384 | p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_DEBUG, q); |
385 | p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_CNM_CHG, q); | 385 | /* Padding, was NIC_QSET_SQ_0_7_CNM_CHG, which |
386 | * produces bus errors when read | ||
387 | */ | ||
388 | p[i++] = 0; | ||
386 | p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_STAT_0_1, q); | 389 | p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_STAT_0_1, q); |
387 | reg_offset = NIC_QSET_SQ_0_7_STAT_0_1 | (1 << 3); | 390 | reg_offset = NIC_QSET_SQ_0_7_STAT_0_1 | (1 << 3); |
388 | p[i++] = nicvf_queue_reg_read(nic, reg_offset, q); | 391 | p[i++] = nicvf_queue_reg_read(nic, reg_offset, q); |
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c index a19e73f11d73..3240349615bd 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c | |||
@@ -513,6 +513,7 @@ static void nicvf_snd_pkt_handler(struct net_device *netdev, | |||
513 | struct nicvf *nic = netdev_priv(netdev); | 513 | struct nicvf *nic = netdev_priv(netdev); |
514 | struct snd_queue *sq; | 514 | struct snd_queue *sq; |
515 | struct sq_hdr_subdesc *hdr; | 515 | struct sq_hdr_subdesc *hdr; |
516 | struct sq_hdr_subdesc *tso_sqe; | ||
516 | 517 | ||
517 | sq = &nic->qs->sq[cqe_tx->sq_idx]; | 518 | sq = &nic->qs->sq[cqe_tx->sq_idx]; |
518 | 519 | ||
@@ -527,17 +528,21 @@ static void nicvf_snd_pkt_handler(struct net_device *netdev, | |||
527 | 528 | ||
528 | nicvf_check_cqe_tx_errs(nic, cq, cqe_tx); | 529 | nicvf_check_cqe_tx_errs(nic, cq, cqe_tx); |
529 | skb = (struct sk_buff *)sq->skbuff[cqe_tx->sqe_ptr]; | 530 | skb = (struct sk_buff *)sq->skbuff[cqe_tx->sqe_ptr]; |
530 | /* For TSO offloaded packets only one SQE will have a valid SKB */ | ||
531 | if (skb) { | 531 | if (skb) { |
532 | /* Check for dummy descriptor used for HW TSO offload on 88xx */ | ||
533 | if (hdr->dont_send) { | ||
534 | /* Get actual TSO descriptors and free them */ | ||
535 | tso_sqe = | ||
536 | (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, hdr->rsvd2); | ||
537 | nicvf_put_sq_desc(sq, tso_sqe->subdesc_cnt + 1); | ||
538 | } | ||
532 | nicvf_put_sq_desc(sq, hdr->subdesc_cnt + 1); | 539 | nicvf_put_sq_desc(sq, hdr->subdesc_cnt + 1); |
533 | prefetch(skb); | 540 | prefetch(skb); |
534 | dev_consume_skb_any(skb); | 541 | dev_consume_skb_any(skb); |
535 | sq->skbuff[cqe_tx->sqe_ptr] = (u64)NULL; | 542 | sq->skbuff[cqe_tx->sqe_ptr] = (u64)NULL; |
536 | } else { | 543 | } else { |
537 | /* In case of HW TSO, HW sends a CQE for each segment of a TSO | 544 | /* In case of SW TSO on 88xx, only last segment will have |
538 | * packet instead of a single CQE for the whole TSO packet | 545 | * a SKB attached, so just free SQEs here. |
539 | * transmitted. Each of this CQE points to the same SQE, so | ||
540 | * avoid freeing same SQE multiple times. | ||
541 | */ | 546 | */ |
542 | if (!nic->hw_tso) | 547 | if (!nic->hw_tso) |
543 | nicvf_put_sq_desc(sq, hdr->subdesc_cnt + 1); | 548 | nicvf_put_sq_desc(sq, hdr->subdesc_cnt + 1); |
@@ -1502,6 +1507,7 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1502 | struct net_device *netdev; | 1507 | struct net_device *netdev; |
1503 | struct nicvf *nic; | 1508 | struct nicvf *nic; |
1504 | int err, qcount; | 1509 | int err, qcount; |
1510 | u16 sdevid; | ||
1505 | 1511 | ||
1506 | err = pci_enable_device(pdev); | 1512 | err = pci_enable_device(pdev); |
1507 | if (err) { | 1513 | if (err) { |
@@ -1575,6 +1581,10 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1575 | if (!pass1_silicon(nic->pdev)) | 1581 | if (!pass1_silicon(nic->pdev)) |
1576 | nic->hw_tso = true; | 1582 | nic->hw_tso = true; |
1577 | 1583 | ||
1584 | pci_read_config_word(nic->pdev, PCI_SUBSYSTEM_ID, &sdevid); | ||
1585 | if (sdevid == 0xA134) | ||
1586 | nic->t88 = true; | ||
1587 | |||
1578 | /* Check if this VF is in QS only mode */ | 1588 | /* Check if this VF is in QS only mode */ |
1579 | if (nic->sqs_mode) | 1589 | if (nic->sqs_mode) |
1580 | return 0; | 1590 | return 0; |
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c index 0ff8e60deccb..dda3ea3f3bb6 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c | |||
@@ -938,6 +938,8 @@ static int nicvf_tso_count_subdescs(struct sk_buff *skb) | |||
938 | return num_edescs + sh->gso_segs; | 938 | return num_edescs + sh->gso_segs; |
939 | } | 939 | } |
940 | 940 | ||
941 | #define POST_CQE_DESC_COUNT 2 | ||
942 | |||
941 | /* Get the number of SQ descriptors needed to xmit this skb */ | 943 | /* Get the number of SQ descriptors needed to xmit this skb */ |
942 | static int nicvf_sq_subdesc_required(struct nicvf *nic, struct sk_buff *skb) | 944 | static int nicvf_sq_subdesc_required(struct nicvf *nic, struct sk_buff *skb) |
943 | { | 945 | { |
@@ -948,6 +950,10 @@ static int nicvf_sq_subdesc_required(struct nicvf *nic, struct sk_buff *skb) | |||
948 | return subdesc_cnt; | 950 | return subdesc_cnt; |
949 | } | 951 | } |
950 | 952 | ||
953 | /* Dummy descriptors to get TSO pkt completion notification */ | ||
954 | if (nic->t88 && nic->hw_tso && skb_shinfo(skb)->gso_size) | ||
955 | subdesc_cnt += POST_CQE_DESC_COUNT; | ||
956 | |||
951 | if (skb_shinfo(skb)->nr_frags) | 957 | if (skb_shinfo(skb)->nr_frags) |
952 | subdesc_cnt += skb_shinfo(skb)->nr_frags; | 958 | subdesc_cnt += skb_shinfo(skb)->nr_frags; |
953 | 959 | ||
@@ -965,14 +971,21 @@ nicvf_sq_add_hdr_subdesc(struct nicvf *nic, struct snd_queue *sq, int qentry, | |||
965 | struct sq_hdr_subdesc *hdr; | 971 | struct sq_hdr_subdesc *hdr; |
966 | 972 | ||
967 | hdr = (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, qentry); | 973 | hdr = (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, qentry); |
968 | sq->skbuff[qentry] = (u64)skb; | ||
969 | |||
970 | memset(hdr, 0, SND_QUEUE_DESC_SIZE); | 974 | memset(hdr, 0, SND_QUEUE_DESC_SIZE); |
971 | hdr->subdesc_type = SQ_DESC_TYPE_HEADER; | 975 | hdr->subdesc_type = SQ_DESC_TYPE_HEADER; |
972 | /* Enable notification via CQE after processing SQE */ | 976 | |
973 | hdr->post_cqe = 1; | 977 | if (nic->t88 && nic->hw_tso && skb_shinfo(skb)->gso_size) { |
974 | /* No of subdescriptors following this */ | 978 | /* post_cqe = 0, to avoid HW posting a CQE for every TSO |
975 | hdr->subdesc_cnt = subdesc_cnt; | 979 | * segment transmitted on 88xx. |
980 | */ | ||
981 | hdr->subdesc_cnt = subdesc_cnt - POST_CQE_DESC_COUNT; | ||
982 | } else { | ||
983 | sq->skbuff[qentry] = (u64)skb; | ||
984 | /* Enable notification via CQE after processing SQE */ | ||
985 | hdr->post_cqe = 1; | ||
986 | /* No of subdescriptors following this */ | ||
987 | hdr->subdesc_cnt = subdesc_cnt; | ||
988 | } | ||
976 | hdr->tot_len = len; | 989 | hdr->tot_len = len; |
977 | 990 | ||
978 | /* Offload checksum calculation to HW */ | 991 | /* Offload checksum calculation to HW */ |
@@ -1023,6 +1036,37 @@ static inline void nicvf_sq_add_gather_subdesc(struct snd_queue *sq, int qentry, | |||
1023 | gather->addr = data; | 1036 | gather->addr = data; |
1024 | } | 1037 | } |
1025 | 1038 | ||
1039 | /* Add HDR + IMMEDIATE subdescriptors right after descriptors of a TSO | ||
1040 | * packet so that a CQE is posted as a notifation for transmission of | ||
1041 | * TSO packet. | ||
1042 | */ | ||
1043 | static inline void nicvf_sq_add_cqe_subdesc(struct snd_queue *sq, int qentry, | ||
1044 | int tso_sqe, struct sk_buff *skb) | ||
1045 | { | ||
1046 | struct sq_imm_subdesc *imm; | ||
1047 | struct sq_hdr_subdesc *hdr; | ||
1048 | |||
1049 | sq->skbuff[qentry] = (u64)skb; | ||
1050 | |||
1051 | hdr = (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, qentry); | ||
1052 | memset(hdr, 0, SND_QUEUE_DESC_SIZE); | ||
1053 | hdr->subdesc_type = SQ_DESC_TYPE_HEADER; | ||
1054 | /* Enable notification via CQE after processing SQE */ | ||
1055 | hdr->post_cqe = 1; | ||
1056 | /* There is no packet to transmit here */ | ||
1057 | hdr->dont_send = 1; | ||
1058 | hdr->subdesc_cnt = POST_CQE_DESC_COUNT - 1; | ||
1059 | hdr->tot_len = 1; | ||
1060 | /* Actual TSO header SQE index, needed for cleanup */ | ||
1061 | hdr->rsvd2 = tso_sqe; | ||
1062 | |||
1063 | qentry = nicvf_get_nxt_sqentry(sq, qentry); | ||
1064 | imm = (struct sq_imm_subdesc *)GET_SQ_DESC(sq, qentry); | ||
1065 | memset(imm, 0, SND_QUEUE_DESC_SIZE); | ||
1066 | imm->subdesc_type = SQ_DESC_TYPE_IMMEDIATE; | ||
1067 | imm->len = 1; | ||
1068 | } | ||
1069 | |||
1026 | /* Segment a TSO packet into 'gso_size' segments and append | 1070 | /* Segment a TSO packet into 'gso_size' segments and append |
1027 | * them to SQ for transfer | 1071 | * them to SQ for transfer |
1028 | */ | 1072 | */ |
@@ -1096,7 +1140,7 @@ static int nicvf_sq_append_tso(struct nicvf *nic, struct snd_queue *sq, | |||
1096 | int nicvf_sq_append_skb(struct nicvf *nic, struct sk_buff *skb) | 1140 | int nicvf_sq_append_skb(struct nicvf *nic, struct sk_buff *skb) |
1097 | { | 1141 | { |
1098 | int i, size; | 1142 | int i, size; |
1099 | int subdesc_cnt; | 1143 | int subdesc_cnt, tso_sqe = 0; |
1100 | int sq_num, qentry; | 1144 | int sq_num, qentry; |
1101 | struct queue_set *qs; | 1145 | struct queue_set *qs; |
1102 | struct snd_queue *sq; | 1146 | struct snd_queue *sq; |
@@ -1131,6 +1175,7 @@ int nicvf_sq_append_skb(struct nicvf *nic, struct sk_buff *skb) | |||
1131 | /* Add SQ header subdesc */ | 1175 | /* Add SQ header subdesc */ |
1132 | nicvf_sq_add_hdr_subdesc(nic, sq, qentry, subdesc_cnt - 1, | 1176 | nicvf_sq_add_hdr_subdesc(nic, sq, qentry, subdesc_cnt - 1, |
1133 | skb, skb->len); | 1177 | skb, skb->len); |
1178 | tso_sqe = qentry; | ||
1134 | 1179 | ||
1135 | /* Add SQ gather subdescs */ | 1180 | /* Add SQ gather subdescs */ |
1136 | qentry = nicvf_get_nxt_sqentry(sq, qentry); | 1181 | qentry = nicvf_get_nxt_sqentry(sq, qentry); |
@@ -1154,6 +1199,11 @@ int nicvf_sq_append_skb(struct nicvf *nic, struct sk_buff *skb) | |||
1154 | } | 1199 | } |
1155 | 1200 | ||
1156 | doorbell: | 1201 | doorbell: |
1202 | if (nic->t88 && skb_shinfo(skb)->gso_size) { | ||
1203 | qentry = nicvf_get_nxt_sqentry(sq, qentry); | ||
1204 | nicvf_sq_add_cqe_subdesc(sq, qentry, tso_sqe, skb); | ||
1205 | } | ||
1206 | |||
1157 | /* make sure all memory stores are done before ringing doorbell */ | 1207 | /* make sure all memory stores are done before ringing doorbell */ |
1158 | smp_wmb(); | 1208 | smp_wmb(); |
1159 | 1209 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 2e2aa9fec9bb..edd23386b47d 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | |||
@@ -419,8 +419,8 @@ struct link_config { | |||
419 | unsigned short supported; /* link capabilities */ | 419 | unsigned short supported; /* link capabilities */ |
420 | unsigned short advertising; /* advertised capabilities */ | 420 | unsigned short advertising; /* advertised capabilities */ |
421 | unsigned short lp_advertising; /* peer advertised capabilities */ | 421 | unsigned short lp_advertising; /* peer advertised capabilities */ |
422 | unsigned short requested_speed; /* speed user has requested */ | 422 | unsigned int requested_speed; /* speed user has requested */ |
423 | unsigned short speed; /* actual link speed */ | 423 | unsigned int speed; /* actual link speed */ |
424 | unsigned char requested_fc; /* flow control user has requested */ | 424 | unsigned char requested_fc; /* flow control user has requested */ |
425 | unsigned char fc; /* actual link flow control */ | 425 | unsigned char fc; /* actual link flow control */ |
426 | unsigned char autoneg; /* autonegotiating? */ | 426 | unsigned char autoneg; /* autonegotiating? */ |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index c45de49dc963..3ceafb55d6da 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
@@ -4305,10 +4305,17 @@ static const struct pci_error_handlers cxgb4_eeh = { | |||
4305 | .resume = eeh_resume, | 4305 | .resume = eeh_resume, |
4306 | }; | 4306 | }; |
4307 | 4307 | ||
4308 | /* Return true if the Link Configuration supports "High Speeds" (those greater | ||
4309 | * than 1Gb/s). | ||
4310 | */ | ||
4308 | static inline bool is_x_10g_port(const struct link_config *lc) | 4311 | static inline bool is_x_10g_port(const struct link_config *lc) |
4309 | { | 4312 | { |
4310 | return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0 || | 4313 | unsigned int speeds, high_speeds; |
4311 | (lc->supported & FW_PORT_CAP_SPEED_40G) != 0; | 4314 | |
4315 | speeds = FW_PORT_CAP_SPEED_V(FW_PORT_CAP_SPEED_G(lc->supported)); | ||
4316 | high_speeds = speeds & ~(FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G); | ||
4317 | |||
4318 | return high_speeds != 0; | ||
4312 | } | 4319 | } |
4313 | 4320 | ||
4314 | static inline void init_rspq(struct adapter *adap, struct sge_rspq *q, | 4321 | static inline void init_rspq(struct adapter *adap, struct sge_rspq *q, |
@@ -4335,6 +4342,11 @@ static void cfg_queues(struct adapter *adap) | |||
4335 | #endif | 4342 | #endif |
4336 | int ciq_size; | 4343 | int ciq_size; |
4337 | 4344 | ||
4345 | /* Reduce memory usage in kdump environment, disable all offload. | ||
4346 | */ | ||
4347 | if (is_kdump_kernel()) | ||
4348 | adap->params.offload = 0; | ||
4349 | |||
4338 | for_each_port(adap, i) | 4350 | for_each_port(adap, i) |
4339 | n10g += is_x_10g_port(&adap2pinfo(adap, i)->link_cfg); | 4351 | n10g += is_x_10g_port(&adap2pinfo(adap, i)->link_cfg); |
4340 | #ifdef CONFIG_CHELSIO_T4_DCB | 4352 | #ifdef CONFIG_CHELSIO_T4_DCB |
@@ -4365,11 +4377,6 @@ static void cfg_queues(struct adapter *adap) | |||
4365 | if (q10g > netif_get_num_default_rss_queues()) | 4377 | if (q10g > netif_get_num_default_rss_queues()) |
4366 | q10g = netif_get_num_default_rss_queues(); | 4378 | q10g = netif_get_num_default_rss_queues(); |
4367 | 4379 | ||
4368 | /* Reduce memory usage in kdump environment, disable all offload. | ||
4369 | */ | ||
4370 | if (is_kdump_kernel()) | ||
4371 | adap->params.offload = 0; | ||
4372 | |||
4373 | for_each_port(adap, i) { | 4380 | for_each_port(adap, i) { |
4374 | struct port_info *pi = adap2pinfo(adap, i); | 4381 | struct port_info *pi = adap2pinfo(adap, i); |
4375 | 4382 | ||
@@ -4756,8 +4763,12 @@ static void print_port_info(const struct net_device *dev) | |||
4756 | bufp += sprintf(bufp, "1000/"); | 4763 | bufp += sprintf(bufp, "1000/"); |
4757 | if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G) | 4764 | if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G) |
4758 | bufp += sprintf(bufp, "10G/"); | 4765 | bufp += sprintf(bufp, "10G/"); |
4766 | if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_25G) | ||
4767 | bufp += sprintf(bufp, "25G/"); | ||
4759 | if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G) | 4768 | if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G) |
4760 | bufp += sprintf(bufp, "40G/"); | 4769 | bufp += sprintf(bufp, "40G/"); |
4770 | if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100G) | ||
4771 | bufp += sprintf(bufp, "100G/"); | ||
4761 | if (bufp != buf) | 4772 | if (bufp != buf) |
4762 | --bufp; | 4773 | --bufp; |
4763 | sprintf(bufp, "BASE-%s", t4_get_port_type_description(pi->port_type)); | 4774 | sprintf(bufp, "BASE-%s", t4_get_port_type_description(pi->port_type)); |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index dc92c80a75f4..660204bff726 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | |||
@@ -3627,7 +3627,8 @@ void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf) | |||
3627 | } | 3627 | } |
3628 | 3628 | ||
3629 | #define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\ | 3629 | #define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\ |
3630 | FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G | \ | 3630 | FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_25G | \ |
3631 | FW_PORT_CAP_SPEED_40G | FW_PORT_CAP_SPEED_100G | \ | ||
3631 | FW_PORT_CAP_ANEG) | 3632 | FW_PORT_CAP_ANEG) |
3632 | 3633 | ||
3633 | /** | 3634 | /** |
@@ -7196,8 +7197,12 @@ void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl) | |||
7196 | speed = 1000; | 7197 | speed = 1000; |
7197 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G)) | 7198 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G)) |
7198 | speed = 10000; | 7199 | speed = 10000; |
7200 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_25G)) | ||
7201 | speed = 25000; | ||
7199 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G)) | 7202 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G)) |
7200 | speed = 40000; | 7203 | speed = 40000; |
7204 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100G)) | ||
7205 | speed = 100000; | ||
7201 | 7206 | ||
7202 | lc = &pi->link_cfg; | 7207 | lc = &pi->link_cfg; |
7203 | 7208 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index a89b30720e38..30507d44422c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | |||
@@ -2265,6 +2265,12 @@ enum fw_port_cap { | |||
2265 | FW_PORT_CAP_802_3_ASM_DIR = 0x8000, | 2265 | FW_PORT_CAP_802_3_ASM_DIR = 0x8000, |
2266 | }; | 2266 | }; |
2267 | 2267 | ||
2268 | #define FW_PORT_CAP_SPEED_S 0 | ||
2269 | #define FW_PORT_CAP_SPEED_M 0x3f | ||
2270 | #define FW_PORT_CAP_SPEED_V(x) ((x) << FW_PORT_CAP_SPEED_S) | ||
2271 | #define FW_PORT_CAP_SPEED_G(x) \ | ||
2272 | (((x) >> FW_PORT_CAP_SPEED_S) & FW_PORT_CAP_SPEED_M) | ||
2273 | |||
2268 | enum fw_port_mdi { | 2274 | enum fw_port_mdi { |
2269 | FW_PORT_CAP_MDI_UNCHANGED, | 2275 | FW_PORT_CAP_MDI_UNCHANGED, |
2270 | FW_PORT_CAP_MDI_AUTO, | 2276 | FW_PORT_CAP_MDI_AUTO, |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h index 8ee541431e8b..17a2bbcf93f0 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | |||
@@ -108,8 +108,8 @@ struct link_config { | |||
108 | unsigned int supported; /* link capabilities */ | 108 | unsigned int supported; /* link capabilities */ |
109 | unsigned int advertising; /* advertised capabilities */ | 109 | unsigned int advertising; /* advertised capabilities */ |
110 | unsigned short lp_advertising; /* peer advertised capabilities */ | 110 | unsigned short lp_advertising; /* peer advertised capabilities */ |
111 | unsigned short requested_speed; /* speed user has requested */ | 111 | unsigned int requested_speed; /* speed user has requested */ |
112 | unsigned short speed; /* actual link speed */ | 112 | unsigned int speed; /* actual link speed */ |
113 | unsigned char requested_fc; /* flow control user has requested */ | 113 | unsigned char requested_fc; /* flow control user has requested */ |
114 | unsigned char fc; /* actual link flow control */ | 114 | unsigned char fc; /* actual link flow control */ |
115 | unsigned char autoneg; /* autonegotiating? */ | 115 | unsigned char autoneg; /* autonegotiating? */ |
@@ -271,10 +271,17 @@ static inline bool is_10g_port(const struct link_config *lc) | |||
271 | return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0; | 271 | return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0; |
272 | } | 272 | } |
273 | 273 | ||
274 | /* Return true if the Link Configuration supports "High Speeds" (those greater | ||
275 | * than 1Gb/s). | ||
276 | */ | ||
274 | static inline bool is_x_10g_port(const struct link_config *lc) | 277 | static inline bool is_x_10g_port(const struct link_config *lc) |
275 | { | 278 | { |
276 | return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0 || | 279 | unsigned int speeds, high_speeds; |
277 | (lc->supported & FW_PORT_CAP_SPEED_40G) != 0; | 280 | |
281 | speeds = FW_PORT_CAP_SPEED_V(FW_PORT_CAP_SPEED_G(lc->supported)); | ||
282 | high_speeds = speeds & ~(FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G); | ||
283 | |||
284 | return high_speeds != 0; | ||
278 | } | 285 | } |
279 | 286 | ||
280 | static inline unsigned int core_ticks_per_usec(const struct adapter *adapter) | 287 | static inline unsigned int core_ticks_per_usec(const struct adapter *adapter) |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index 427bfa71388b..b5622b1689e9 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | |||
@@ -314,8 +314,9 @@ int t4vf_wr_mbox_core(struct adapter *adapter, const void *cmd, int size, | |||
314 | } | 314 | } |
315 | 315 | ||
316 | #define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\ | 316 | #define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\ |
317 | FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G | \ | 317 | FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_25G | \ |
318 | FW_PORT_CAP_SPEED_100G | FW_PORT_CAP_ANEG) | 318 | FW_PORT_CAP_SPEED_40G | FW_PORT_CAP_SPEED_100G | \ |
319 | FW_PORT_CAP_ANEG) | ||
319 | 320 | ||
320 | /** | 321 | /** |
321 | * init_link_config - initialize a link's SW state | 322 | * init_link_config - initialize a link's SW state |
@@ -1712,8 +1713,12 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) | |||
1712 | speed = 1000; | 1713 | speed = 1000; |
1713 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G)) | 1714 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G)) |
1714 | speed = 10000; | 1715 | speed = 10000; |
1716 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_25G)) | ||
1717 | speed = 25000; | ||
1715 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G)) | 1718 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G)) |
1716 | speed = 40000; | 1719 | speed = 40000; |
1720 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100G)) | ||
1721 | speed = 100000; | ||
1717 | 1722 | ||
1718 | /* | 1723 | /* |
1719 | * Scan all of our "ports" (Virtual Interfaces) looking for | 1724 | * Scan all of our "ports" (Virtual Interfaces) looking for |
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index d20935dc8399..4b4f5bc0e279 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
@@ -2922,17 +2922,25 @@ static bool gfar_add_rx_frag(struct gfar_rx_buff *rxb, u32 lstatus, | |||
2922 | { | 2922 | { |
2923 | unsigned int size = lstatus & BD_LENGTH_MASK; | 2923 | unsigned int size = lstatus & BD_LENGTH_MASK; |
2924 | struct page *page = rxb->page; | 2924 | struct page *page = rxb->page; |
2925 | bool last = !!(lstatus & BD_LFLAG(RXBD_LAST)); | ||
2925 | 2926 | ||
2926 | /* Remove the FCS from the packet length */ | 2927 | /* Remove the FCS from the packet length */ |
2927 | if (likely(lstatus & BD_LFLAG(RXBD_LAST))) | 2928 | if (last) |
2928 | size -= ETH_FCS_LEN; | 2929 | size -= ETH_FCS_LEN; |
2929 | 2930 | ||
2930 | if (likely(first)) | 2931 | if (likely(first)) { |
2931 | skb_put(skb, size); | 2932 | skb_put(skb, size); |
2932 | else | 2933 | } else { |
2933 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, | 2934 | /* the last fragments' length contains the full frame length */ |
2934 | rxb->page_offset + RXBUF_ALIGNMENT, | 2935 | if (last) |
2935 | size, GFAR_RXB_TRUESIZE); | 2936 | size -= skb->len; |
2937 | |||
2938 | /* in case the last fragment consisted only of the FCS */ | ||
2939 | if (size > 0) | ||
2940 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, | ||
2941 | rxb->page_offset + RXBUF_ALIGNMENT, | ||
2942 | size, GFAR_RXB_TRUESIZE); | ||
2943 | } | ||
2936 | 2944 | ||
2937 | /* try reuse page */ | 2945 | /* try reuse page */ |
2938 | if (unlikely(page_count(page) != 1)) | 2946 | if (unlikely(page_count(page) != 1)) |
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 373fd094f2f3..6e8a9c8467b9 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h | |||
@@ -100,7 +100,8 @@ extern const char gfar_driver_version[]; | |||
100 | #define DEFAULT_RX_LFC_THR 16 | 100 | #define DEFAULT_RX_LFC_THR 16 |
101 | #define DEFAULT_LFC_PTVVAL 4 | 101 | #define DEFAULT_LFC_PTVVAL 4 |
102 | 102 | ||
103 | #define GFAR_RXB_SIZE 1536 | 103 | /* prevent fragmenation by HW in DSA environments */ |
104 | #define GFAR_RXB_SIZE roundup(1536 + 8, 64) | ||
104 | #define GFAR_SKBFRAG_SIZE (RXBUF_ALIGNMENT + GFAR_RXB_SIZE \ | 105 | #define GFAR_SKBFRAG_SIZE (RXBUF_ALIGNMENT + GFAR_RXB_SIZE \ |
105 | + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) | 106 | + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) |
106 | #define GFAR_RXB_TRUESIZE 2048 | 107 | #define GFAR_RXB_TRUESIZE 2048 |
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c index ff8b6a468b24..6ea872287307 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c | |||
@@ -328,9 +328,10 @@ static void hns_ppe_init_hw(struct hns_ppe_cb *ppe_cb) | |||
328 | static void hns_ppe_uninit_hw(struct hns_ppe_cb *ppe_cb) | 328 | static void hns_ppe_uninit_hw(struct hns_ppe_cb *ppe_cb) |
329 | { | 329 | { |
330 | u32 port; | 330 | u32 port; |
331 | struct dsaf_device *dsaf_dev = ppe_cb->ppe_common_cb->dsaf_dev; | ||
332 | 331 | ||
333 | if (ppe_cb->ppe_common_cb) { | 332 | if (ppe_cb->ppe_common_cb) { |
333 | struct dsaf_device *dsaf_dev = ppe_cb->ppe_common_cb->dsaf_dev; | ||
334 | |||
334 | port = ppe_cb->index; | 335 | port = ppe_cb->index; |
335 | dsaf_dev->misc_op->ppe_srst(dsaf_dev, port, 0); | 336 | dsaf_dev->misc_op->ppe_srst(dsaf_dev, port, 0); |
336 | } | 337 | } |
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index 4c9771d57d6e..7af09cbc53f0 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c | |||
@@ -977,7 +977,37 @@ static void emac_set_multicast_list(struct net_device *ndev) | |||
977 | dev->mcast_pending = 1; | 977 | dev->mcast_pending = 1; |
978 | return; | 978 | return; |
979 | } | 979 | } |
980 | |||
981 | mutex_lock(&dev->link_lock); | ||
980 | __emac_set_multicast_list(dev); | 982 | __emac_set_multicast_list(dev); |
983 | mutex_unlock(&dev->link_lock); | ||
984 | } | ||
985 | |||
986 | static int emac_set_mac_address(struct net_device *ndev, void *sa) | ||
987 | { | ||
988 | struct emac_instance *dev = netdev_priv(ndev); | ||
989 | struct sockaddr *addr = sa; | ||
990 | struct emac_regs __iomem *p = dev->emacp; | ||
991 | |||
992 | if (!is_valid_ether_addr(addr->sa_data)) | ||
993 | return -EADDRNOTAVAIL; | ||
994 | |||
995 | mutex_lock(&dev->link_lock); | ||
996 | |||
997 | memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len); | ||
998 | |||
999 | emac_rx_disable(dev); | ||
1000 | emac_tx_disable(dev); | ||
1001 | out_be32(&p->iahr, (ndev->dev_addr[0] << 8) | ndev->dev_addr[1]); | ||
1002 | out_be32(&p->ialr, (ndev->dev_addr[2] << 24) | | ||
1003 | (ndev->dev_addr[3] << 16) | (ndev->dev_addr[4] << 8) | | ||
1004 | ndev->dev_addr[5]); | ||
1005 | emac_tx_enable(dev); | ||
1006 | emac_rx_enable(dev); | ||
1007 | |||
1008 | mutex_unlock(&dev->link_lock); | ||
1009 | |||
1010 | return 0; | ||
981 | } | 1011 | } |
982 | 1012 | ||
983 | static int emac_resize_rx_ring(struct emac_instance *dev, int new_mtu) | 1013 | static int emac_resize_rx_ring(struct emac_instance *dev, int new_mtu) |
@@ -2686,7 +2716,7 @@ static const struct net_device_ops emac_netdev_ops = { | |||
2686 | .ndo_do_ioctl = emac_ioctl, | 2716 | .ndo_do_ioctl = emac_ioctl, |
2687 | .ndo_tx_timeout = emac_tx_timeout, | 2717 | .ndo_tx_timeout = emac_tx_timeout, |
2688 | .ndo_validate_addr = eth_validate_addr, | 2718 | .ndo_validate_addr = eth_validate_addr, |
2689 | .ndo_set_mac_address = eth_mac_addr, | 2719 | .ndo_set_mac_address = emac_set_mac_address, |
2690 | .ndo_start_xmit = emac_start_xmit, | 2720 | .ndo_start_xmit = emac_start_xmit, |
2691 | .ndo_change_mtu = eth_change_mtu, | 2721 | .ndo_change_mtu = eth_change_mtu, |
2692 | }; | 2722 | }; |
@@ -2699,7 +2729,7 @@ static const struct net_device_ops emac_gige_netdev_ops = { | |||
2699 | .ndo_do_ioctl = emac_ioctl, | 2729 | .ndo_do_ioctl = emac_ioctl, |
2700 | .ndo_tx_timeout = emac_tx_timeout, | 2730 | .ndo_tx_timeout = emac_tx_timeout, |
2701 | .ndo_validate_addr = eth_validate_addr, | 2731 | .ndo_validate_addr = eth_validate_addr, |
2702 | .ndo_set_mac_address = eth_mac_addr, | 2732 | .ndo_set_mac_address = emac_set_mac_address, |
2703 | .ndo_start_xmit = emac_start_xmit_sg, | 2733 | .ndo_start_xmit = emac_start_xmit_sg, |
2704 | .ndo_change_mtu = emac_change_mtu, | 2734 | .ndo_change_mtu = emac_change_mtu, |
2705 | }; | 2735 | }; |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_client.c b/drivers/net/ethernet/intel/i40e/i40e_client.c index e1370c556a3c..618f18436618 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_client.c +++ b/drivers/net/ethernet/intel/i40e/i40e_client.c | |||
@@ -199,6 +199,7 @@ void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi) | |||
199 | void i40e_notify_client_of_netdev_open(struct i40e_vsi *vsi) | 199 | void i40e_notify_client_of_netdev_open(struct i40e_vsi *vsi) |
200 | { | 200 | { |
201 | struct i40e_client_instance *cdev; | 201 | struct i40e_client_instance *cdev; |
202 | int ret = 0; | ||
202 | 203 | ||
203 | if (!vsi) | 204 | if (!vsi) |
204 | return; | 205 | return; |
@@ -211,7 +212,14 @@ void i40e_notify_client_of_netdev_open(struct i40e_vsi *vsi) | |||
211 | "Cannot locate client instance open routine\n"); | 212 | "Cannot locate client instance open routine\n"); |
212 | continue; | 213 | continue; |
213 | } | 214 | } |
214 | cdev->client->ops->open(&cdev->lan_info, cdev->client); | 215 | if (!(test_bit(__I40E_CLIENT_INSTANCE_OPENED, |
216 | &cdev->state))) { | ||
217 | ret = cdev->client->ops->open(&cdev->lan_info, | ||
218 | cdev->client); | ||
219 | if (!ret) | ||
220 | set_bit(__I40E_CLIENT_INSTANCE_OPENED, | ||
221 | &cdev->state); | ||
222 | } | ||
215 | } | 223 | } |
216 | } | 224 | } |
217 | mutex_unlock(&i40e_client_instance_mutex); | 225 | mutex_unlock(&i40e_client_instance_mutex); |
@@ -407,12 +415,14 @@ struct i40e_vsi *i40e_vsi_lookup(struct i40e_pf *pf, | |||
407 | * i40e_client_add_instance - add a client instance struct to the instance list | 415 | * i40e_client_add_instance - add a client instance struct to the instance list |
408 | * @pf: pointer to the board struct | 416 | * @pf: pointer to the board struct |
409 | * @client: pointer to a client struct in the client list. | 417 | * @client: pointer to a client struct in the client list. |
418 | * @existing: if there was already an existing instance | ||
410 | * | 419 | * |
411 | * Returns cdev ptr on success, NULL on failure | 420 | * Returns cdev ptr on success or if already exists, NULL on failure |
412 | **/ | 421 | **/ |
413 | static | 422 | static |
414 | struct i40e_client_instance *i40e_client_add_instance(struct i40e_pf *pf, | 423 | struct i40e_client_instance *i40e_client_add_instance(struct i40e_pf *pf, |
415 | struct i40e_client *client) | 424 | struct i40e_client *client, |
425 | bool *existing) | ||
416 | { | 426 | { |
417 | struct i40e_client_instance *cdev; | 427 | struct i40e_client_instance *cdev; |
418 | struct netdev_hw_addr *mac = NULL; | 428 | struct netdev_hw_addr *mac = NULL; |
@@ -421,7 +431,7 @@ struct i40e_client_instance *i40e_client_add_instance(struct i40e_pf *pf, | |||
421 | mutex_lock(&i40e_client_instance_mutex); | 431 | mutex_lock(&i40e_client_instance_mutex); |
422 | list_for_each_entry(cdev, &i40e_client_instances, list) { | 432 | list_for_each_entry(cdev, &i40e_client_instances, list) { |
423 | if ((cdev->lan_info.pf == pf) && (cdev->client == client)) { | 433 | if ((cdev->lan_info.pf == pf) && (cdev->client == client)) { |
424 | cdev = NULL; | 434 | *existing = true; |
425 | goto out; | 435 | goto out; |
426 | } | 436 | } |
427 | } | 437 | } |
@@ -505,6 +515,7 @@ void i40e_client_subtask(struct i40e_pf *pf) | |||
505 | { | 515 | { |
506 | struct i40e_client_instance *cdev; | 516 | struct i40e_client_instance *cdev; |
507 | struct i40e_client *client; | 517 | struct i40e_client *client; |
518 | bool existing = false; | ||
508 | int ret = 0; | 519 | int ret = 0; |
509 | 520 | ||
510 | if (!(pf->flags & I40E_FLAG_SERVICE_CLIENT_REQUESTED)) | 521 | if (!(pf->flags & I40E_FLAG_SERVICE_CLIENT_REQUESTED)) |
@@ -528,18 +539,25 @@ void i40e_client_subtask(struct i40e_pf *pf) | |||
528 | /* check if L2 VSI is up, if not we are not ready */ | 539 | /* check if L2 VSI is up, if not we are not ready */ |
529 | if (test_bit(__I40E_DOWN, &pf->vsi[pf->lan_vsi]->state)) | 540 | if (test_bit(__I40E_DOWN, &pf->vsi[pf->lan_vsi]->state)) |
530 | continue; | 541 | continue; |
542 | } else { | ||
543 | dev_warn(&pf->pdev->dev, "This client %s is being instanciated at probe\n", | ||
544 | client->name); | ||
531 | } | 545 | } |
532 | 546 | ||
533 | /* Add the client instance to the instance list */ | 547 | /* Add the client instance to the instance list */ |
534 | cdev = i40e_client_add_instance(pf, client); | 548 | cdev = i40e_client_add_instance(pf, client, &existing); |
535 | if (!cdev) | 549 | if (!cdev) |
536 | continue; | 550 | continue; |
537 | 551 | ||
538 | /* Also up the ref_cnt of no. of instances of this client */ | 552 | if (!existing) { |
539 | atomic_inc(&client->ref_cnt); | 553 | /* Also up the ref_cnt for no. of instances of this |
540 | dev_info(&pf->pdev->dev, "Added instance of Client %s to PF%d bus=0x%02x func=0x%02x\n", | 554 | * client. |
541 | client->name, pf->hw.pf_id, | 555 | */ |
542 | pf->hw.bus.device, pf->hw.bus.func); | 556 | atomic_inc(&client->ref_cnt); |
557 | dev_info(&pf->pdev->dev, "Added instance of Client %s to PF%d bus=0x%02x func=0x%02x\n", | ||
558 | client->name, pf->hw.pf_id, | ||
559 | pf->hw.bus.device, pf->hw.bus.func); | ||
560 | } | ||
543 | 561 | ||
544 | /* Send an Open request to the client */ | 562 | /* Send an Open request to the client */ |
545 | atomic_inc(&cdev->ref_cnt); | 563 | atomic_inc(&cdev->ref_cnt); |
@@ -588,7 +606,8 @@ int i40e_lan_add_device(struct i40e_pf *pf) | |||
588 | pf->hw.pf_id, pf->hw.bus.device, pf->hw.bus.func); | 606 | pf->hw.pf_id, pf->hw.bus.device, pf->hw.bus.func); |
589 | 607 | ||
590 | /* Since in some cases register may have happened before a device gets | 608 | /* Since in some cases register may have happened before a device gets |
591 | * added, we can schedule a subtask to go initiate the clients. | 609 | * added, we can schedule a subtask to go initiate the clients if |
610 | * they can be launched at probe time. | ||
592 | */ | 611 | */ |
593 | pf->flags |= I40E_FLAG_SERVICE_CLIENT_REQUESTED; | 612 | pf->flags |= I40E_FLAG_SERVICE_CLIENT_REQUESTED; |
594 | i40e_service_event_schedule(pf); | 613 | i40e_service_event_schedule(pf); |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index c6ac7a61812f..d0b3a1bb82ca 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c | |||
@@ -5113,9 +5113,13 @@ static int i40e_init_pf_dcb(struct i40e_pf *pf) | |||
5113 | DCB_CAP_DCBX_VER_IEEE; | 5113 | DCB_CAP_DCBX_VER_IEEE; |
5114 | 5114 | ||
5115 | pf->flags |= I40E_FLAG_DCB_CAPABLE; | 5115 | pf->flags |= I40E_FLAG_DCB_CAPABLE; |
5116 | /* Enable DCB tagging only when more than one TC */ | 5116 | /* Enable DCB tagging only when more than one TC |
5117 | * or explicitly disable if only one TC | ||
5118 | */ | ||
5117 | if (i40e_dcb_get_num_tc(&hw->local_dcbx_config) > 1) | 5119 | if (i40e_dcb_get_num_tc(&hw->local_dcbx_config) > 1) |
5118 | pf->flags |= I40E_FLAG_DCB_ENABLED; | 5120 | pf->flags |= I40E_FLAG_DCB_ENABLED; |
5121 | else | ||
5122 | pf->flags &= ~I40E_FLAG_DCB_ENABLED; | ||
5119 | dev_dbg(&pf->pdev->dev, | 5123 | dev_dbg(&pf->pdev->dev, |
5120 | "DCBX offload is supported for this PF.\n"); | 5124 | "DCBX offload is supported for this PF.\n"); |
5121 | } | 5125 | } |
@@ -5431,7 +5435,6 @@ int i40e_open(struct net_device *netdev) | |||
5431 | wr32(&pf->hw, I40E_GLLAN_TSOMSK_L, be32_to_cpu(TCP_FLAG_CWR) >> 16); | 5435 | wr32(&pf->hw, I40E_GLLAN_TSOMSK_L, be32_to_cpu(TCP_FLAG_CWR) >> 16); |
5432 | 5436 | ||
5433 | udp_tunnel_get_rx_info(netdev); | 5437 | udp_tunnel_get_rx_info(netdev); |
5434 | i40e_notify_client_of_netdev_open(vsi); | ||
5435 | 5438 | ||
5436 | return 0; | 5439 | return 0; |
5437 | } | 5440 | } |
@@ -5717,7 +5720,7 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf, | |||
5717 | u8 type; | 5720 | u8 type; |
5718 | 5721 | ||
5719 | /* Not DCB capable or capability disabled */ | 5722 | /* Not DCB capable or capability disabled */ |
5720 | if (!(pf->flags & I40E_FLAG_DCB_CAPABLE)) | 5723 | if (!(pf->flags & I40E_FLAG_DCB_ENABLED)) |
5721 | return ret; | 5724 | return ret; |
5722 | 5725 | ||
5723 | /* Ignore if event is not for Nearest Bridge */ | 5726 | /* Ignore if event is not for Nearest Bridge */ |
@@ -7897,6 +7900,7 @@ static int i40e_init_interrupt_scheme(struct i40e_pf *pf) | |||
7897 | #endif | 7900 | #endif |
7898 | I40E_FLAG_RSS_ENABLED | | 7901 | I40E_FLAG_RSS_ENABLED | |
7899 | I40E_FLAG_DCB_CAPABLE | | 7902 | I40E_FLAG_DCB_CAPABLE | |
7903 | I40E_FLAG_DCB_ENABLED | | ||
7900 | I40E_FLAG_SRIOV_ENABLED | | 7904 | I40E_FLAG_SRIOV_ENABLED | |
7901 | I40E_FLAG_FD_SB_ENABLED | | 7905 | I40E_FLAG_FD_SB_ENABLED | |
7902 | I40E_FLAG_FD_ATR_ENABLED | | 7906 | I40E_FLAG_FD_ATR_ENABLED | |
@@ -10503,6 +10507,7 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf) | |||
10503 | I40E_FLAG_FD_SB_ENABLED | | 10507 | I40E_FLAG_FD_SB_ENABLED | |
10504 | I40E_FLAG_FD_ATR_ENABLED | | 10508 | I40E_FLAG_FD_ATR_ENABLED | |
10505 | I40E_FLAG_DCB_CAPABLE | | 10509 | I40E_FLAG_DCB_CAPABLE | |
10510 | I40E_FLAG_DCB_ENABLED | | ||
10506 | I40E_FLAG_SRIOV_ENABLED | | 10511 | I40E_FLAG_SRIOV_ENABLED | |
10507 | I40E_FLAG_VMDQ_ENABLED); | 10512 | I40E_FLAG_VMDQ_ENABLED); |
10508 | } else if (!(pf->flags & (I40E_FLAG_RSS_ENABLED | | 10513 | } else if (!(pf->flags & (I40E_FLAG_RSS_ENABLED | |
@@ -10526,7 +10531,8 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf) | |||
10526 | /* Not enough queues for all TCs */ | 10531 | /* Not enough queues for all TCs */ |
10527 | if ((pf->flags & I40E_FLAG_DCB_CAPABLE) && | 10532 | if ((pf->flags & I40E_FLAG_DCB_CAPABLE) && |
10528 | (queues_left < I40E_MAX_TRAFFIC_CLASS)) { | 10533 | (queues_left < I40E_MAX_TRAFFIC_CLASS)) { |
10529 | pf->flags &= ~I40E_FLAG_DCB_CAPABLE; | 10534 | pf->flags &= ~(I40E_FLAG_DCB_CAPABLE | |
10535 | I40E_FLAG_DCB_ENABLED); | ||
10530 | dev_info(&pf->pdev->dev, "not enough queues for DCB. DCB is disabled.\n"); | 10536 | dev_info(&pf->pdev->dev, "not enough queues for DCB. DCB is disabled.\n"); |
10531 | } | 10537 | } |
10532 | pf->num_lan_qps = max_t(int, pf->rss_size_max, | 10538 | pf->num_lan_qps = max_t(int, pf->rss_size_max, |
@@ -10923,7 +10929,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
10923 | err = i40e_init_pf_dcb(pf); | 10929 | err = i40e_init_pf_dcb(pf); |
10924 | if (err) { | 10930 | if (err) { |
10925 | dev_info(&pdev->dev, "DCB init failed %d, disabled\n", err); | 10931 | dev_info(&pdev->dev, "DCB init failed %d, disabled\n", err); |
10926 | pf->flags &= ~I40E_FLAG_DCB_CAPABLE; | 10932 | pf->flags &= ~(I40E_FLAG_DCB_CAPABLE & I40E_FLAG_DCB_ENABLED); |
10927 | /* Continue without DCB enabled */ | 10933 | /* Continue without DCB enabled */ |
10928 | } | 10934 | } |
10929 | #endif /* CONFIG_I40E_DCB */ | 10935 | #endif /* CONFIG_I40E_DCB */ |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c index b4217f30e89c..c47b605e8651 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c | |||
@@ -2958,8 +2958,10 @@ s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) | |||
2958 | } | 2958 | } |
2959 | 2959 | ||
2960 | /* was that the last pool using this rar? */ | 2960 | /* was that the last pool using this rar? */ |
2961 | if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0) | 2961 | if (mpsar_lo == 0 && mpsar_hi == 0 && |
2962 | rar != 0 && rar != hw->mac.san_mac_rar_index) | ||
2962 | hw->mac.ops.clear_rar(hw, rar); | 2963 | hw->mac.ops.clear_rar(hw, rar); |
2964 | |||
2963 | return 0; | 2965 | return 0; |
2964 | } | 2966 | } |
2965 | 2967 | ||
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index f1609542adf1..3743af8f1ded 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | |||
@@ -50,6 +50,10 @@ static const struct mtk_ethtool_stats { | |||
50 | MTK_ETHTOOL_STAT(rx_flow_control_packets), | 50 | MTK_ETHTOOL_STAT(rx_flow_control_packets), |
51 | }; | 51 | }; |
52 | 52 | ||
53 | static const char * const mtk_clks_source_name[] = { | ||
54 | "ethif", "esw", "gp1", "gp2" | ||
55 | }; | ||
56 | |||
53 | void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg) | 57 | void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg) |
54 | { | 58 | { |
55 | __raw_writel(val, eth->base + reg); | 59 | __raw_writel(val, eth->base + reg); |
@@ -291,7 +295,7 @@ err_phy: | |||
291 | static int mtk_mdio_init(struct mtk_eth *eth) | 295 | static int mtk_mdio_init(struct mtk_eth *eth) |
292 | { | 296 | { |
293 | struct device_node *mii_np; | 297 | struct device_node *mii_np; |
294 | int err; | 298 | int ret; |
295 | 299 | ||
296 | mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus"); | 300 | mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus"); |
297 | if (!mii_np) { | 301 | if (!mii_np) { |
@@ -300,13 +304,13 @@ static int mtk_mdio_init(struct mtk_eth *eth) | |||
300 | } | 304 | } |
301 | 305 | ||
302 | if (!of_device_is_available(mii_np)) { | 306 | if (!of_device_is_available(mii_np)) { |
303 | err = 0; | 307 | ret = -ENODEV; |
304 | goto err_put_node; | 308 | goto err_put_node; |
305 | } | 309 | } |
306 | 310 | ||
307 | eth->mii_bus = mdiobus_alloc(); | 311 | eth->mii_bus = devm_mdiobus_alloc(eth->dev); |
308 | if (!eth->mii_bus) { | 312 | if (!eth->mii_bus) { |
309 | err = -ENOMEM; | 313 | ret = -ENOMEM; |
310 | goto err_put_node; | 314 | goto err_put_node; |
311 | } | 315 | } |
312 | 316 | ||
@@ -317,19 +321,11 @@ static int mtk_mdio_init(struct mtk_eth *eth) | |||
317 | eth->mii_bus->parent = eth->dev; | 321 | eth->mii_bus->parent = eth->dev; |
318 | 322 | ||
319 | snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%s", mii_np->name); | 323 | snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%s", mii_np->name); |
320 | err = of_mdiobus_register(eth->mii_bus, mii_np); | 324 | ret = of_mdiobus_register(eth->mii_bus, mii_np); |
321 | if (err) | ||
322 | goto err_free_bus; | ||
323 | |||
324 | return 0; | ||
325 | |||
326 | err_free_bus: | ||
327 | mdiobus_free(eth->mii_bus); | ||
328 | 325 | ||
329 | err_put_node: | 326 | err_put_node: |
330 | of_node_put(mii_np); | 327 | of_node_put(mii_np); |
331 | eth->mii_bus = NULL; | 328 | return ret; |
332 | return err; | ||
333 | } | 329 | } |
334 | 330 | ||
335 | static void mtk_mdio_cleanup(struct mtk_eth *eth) | 331 | static void mtk_mdio_cleanup(struct mtk_eth *eth) |
@@ -338,8 +334,6 @@ static void mtk_mdio_cleanup(struct mtk_eth *eth) | |||
338 | return; | 334 | return; |
339 | 335 | ||
340 | mdiobus_unregister(eth->mii_bus); | 336 | mdiobus_unregister(eth->mii_bus); |
341 | of_node_put(eth->mii_bus->dev.of_node); | ||
342 | mdiobus_free(eth->mii_bus); | ||
343 | } | 337 | } |
344 | 338 | ||
345 | static inline void mtk_irq_disable(struct mtk_eth *eth, u32 mask) | 339 | static inline void mtk_irq_disable(struct mtk_eth *eth, u32 mask) |
@@ -588,14 +582,15 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, | |||
588 | dma_addr_t mapped_addr; | 582 | dma_addr_t mapped_addr; |
589 | unsigned int nr_frags; | 583 | unsigned int nr_frags; |
590 | int i, n_desc = 1; | 584 | int i, n_desc = 1; |
591 | u32 txd4 = 0; | 585 | u32 txd4 = 0, fport; |
592 | 586 | ||
593 | itxd = ring->next_free; | 587 | itxd = ring->next_free; |
594 | if (itxd == ring->last_free) | 588 | if (itxd == ring->last_free) |
595 | return -ENOMEM; | 589 | return -ENOMEM; |
596 | 590 | ||
597 | /* set the forward port */ | 591 | /* set the forward port */ |
598 | txd4 |= (mac->id + 1) << TX_DMA_FPORT_SHIFT; | 592 | fport = (mac->id + 1) << TX_DMA_FPORT_SHIFT; |
593 | txd4 |= fport; | ||
599 | 594 | ||
600 | tx_buf = mtk_desc_to_tx_buf(ring, itxd); | 595 | tx_buf = mtk_desc_to_tx_buf(ring, itxd); |
601 | memset(tx_buf, 0, sizeof(*tx_buf)); | 596 | memset(tx_buf, 0, sizeof(*tx_buf)); |
@@ -653,7 +648,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, | |||
653 | WRITE_ONCE(txd->txd3, (TX_DMA_SWC | | 648 | WRITE_ONCE(txd->txd3, (TX_DMA_SWC | |
654 | TX_DMA_PLEN0(frag_map_size) | | 649 | TX_DMA_PLEN0(frag_map_size) | |
655 | last_frag * TX_DMA_LS0)); | 650 | last_frag * TX_DMA_LS0)); |
656 | WRITE_ONCE(txd->txd4, 0); | 651 | WRITE_ONCE(txd->txd4, fport); |
657 | 652 | ||
658 | tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC; | 653 | tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC; |
659 | tx_buf = mtk_desc_to_tx_buf(ring, txd); | 654 | tx_buf = mtk_desc_to_tx_buf(ring, txd); |
@@ -865,7 +860,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, | |||
865 | /* receive data */ | 860 | /* receive data */ |
866 | skb = build_skb(data, ring->frag_size); | 861 | skb = build_skb(data, ring->frag_size); |
867 | if (unlikely(!skb)) { | 862 | if (unlikely(!skb)) { |
868 | put_page(virt_to_head_page(new_data)); | 863 | skb_free_frag(new_data); |
869 | netdev->stats.rx_dropped++; | 864 | netdev->stats.rx_dropped++; |
870 | goto release_desc; | 865 | goto release_desc; |
871 | } | 866 | } |
@@ -1506,10 +1501,7 @@ static void mtk_uninit(struct net_device *dev) | |||
1506 | struct mtk_eth *eth = mac->hw; | 1501 | struct mtk_eth *eth = mac->hw; |
1507 | 1502 | ||
1508 | phy_disconnect(mac->phy_dev); | 1503 | phy_disconnect(mac->phy_dev); |
1509 | mtk_mdio_cleanup(eth); | ||
1510 | mtk_irq_disable(eth, ~0); | 1504 | mtk_irq_disable(eth, ~0); |
1511 | free_irq(eth->irq[1], dev); | ||
1512 | free_irq(eth->irq[2], dev); | ||
1513 | } | 1505 | } |
1514 | 1506 | ||
1515 | static int mtk_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 1507 | static int mtk_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
@@ -1813,6 +1805,7 @@ static int mtk_probe(struct platform_device *pdev) | |||
1813 | if (!eth) | 1805 | if (!eth) |
1814 | return -ENOMEM; | 1806 | return -ENOMEM; |
1815 | 1807 | ||
1808 | eth->dev = &pdev->dev; | ||
1816 | eth->base = devm_ioremap_resource(&pdev->dev, res); | 1809 | eth->base = devm_ioremap_resource(&pdev->dev, res); |
1817 | if (IS_ERR(eth->base)) | 1810 | if (IS_ERR(eth->base)) |
1818 | return PTR_ERR(eth->base); | 1811 | return PTR_ERR(eth->base); |
@@ -1847,21 +1840,21 @@ static int mtk_probe(struct platform_device *pdev) | |||
1847 | return -ENXIO; | 1840 | return -ENXIO; |
1848 | } | 1841 | } |
1849 | } | 1842 | } |
1843 | for (i = 0; i < ARRAY_SIZE(eth->clks); i++) { | ||
1844 | eth->clks[i] = devm_clk_get(eth->dev, | ||
1845 | mtk_clks_source_name[i]); | ||
1846 | if (IS_ERR(eth->clks[i])) { | ||
1847 | if (PTR_ERR(eth->clks[i]) == -EPROBE_DEFER) | ||
1848 | return -EPROBE_DEFER; | ||
1849 | return -ENODEV; | ||
1850 | } | ||
1851 | } | ||
1850 | 1852 | ||
1851 | eth->clk_ethif = devm_clk_get(&pdev->dev, "ethif"); | 1853 | clk_prepare_enable(eth->clks[MTK_CLK_ETHIF]); |
1852 | eth->clk_esw = devm_clk_get(&pdev->dev, "esw"); | 1854 | clk_prepare_enable(eth->clks[MTK_CLK_ESW]); |
1853 | eth->clk_gp1 = devm_clk_get(&pdev->dev, "gp1"); | 1855 | clk_prepare_enable(eth->clks[MTK_CLK_GP1]); |
1854 | eth->clk_gp2 = devm_clk_get(&pdev->dev, "gp2"); | 1856 | clk_prepare_enable(eth->clks[MTK_CLK_GP2]); |
1855 | if (IS_ERR(eth->clk_esw) || IS_ERR(eth->clk_gp1) || | ||
1856 | IS_ERR(eth->clk_gp2) || IS_ERR(eth->clk_ethif)) | ||
1857 | return -ENODEV; | ||
1858 | |||
1859 | clk_prepare_enable(eth->clk_ethif); | ||
1860 | clk_prepare_enable(eth->clk_esw); | ||
1861 | clk_prepare_enable(eth->clk_gp1); | ||
1862 | clk_prepare_enable(eth->clk_gp2); | ||
1863 | 1857 | ||
1864 | eth->dev = &pdev->dev; | ||
1865 | eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE); | 1858 | eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE); |
1866 | INIT_WORK(ð->pending_work, mtk_pending_work); | 1859 | INIT_WORK(ð->pending_work, mtk_pending_work); |
1867 | 1860 | ||
@@ -1903,15 +1896,24 @@ err_free_dev: | |||
1903 | static int mtk_remove(struct platform_device *pdev) | 1896 | static int mtk_remove(struct platform_device *pdev) |
1904 | { | 1897 | { |
1905 | struct mtk_eth *eth = platform_get_drvdata(pdev); | 1898 | struct mtk_eth *eth = platform_get_drvdata(pdev); |
1899 | int i; | ||
1906 | 1900 | ||
1907 | clk_disable_unprepare(eth->clk_ethif); | 1901 | /* stop all devices to make sure that dma is properly shut down */ |
1908 | clk_disable_unprepare(eth->clk_esw); | 1902 | for (i = 0; i < MTK_MAC_COUNT; i++) { |
1909 | clk_disable_unprepare(eth->clk_gp1); | 1903 | if (!eth->netdev[i]) |
1910 | clk_disable_unprepare(eth->clk_gp2); | 1904 | continue; |
1905 | mtk_stop(eth->netdev[i]); | ||
1906 | } | ||
1907 | |||
1908 | clk_disable_unprepare(eth->clks[MTK_CLK_ETHIF]); | ||
1909 | clk_disable_unprepare(eth->clks[MTK_CLK_ESW]); | ||
1910 | clk_disable_unprepare(eth->clks[MTK_CLK_GP1]); | ||
1911 | clk_disable_unprepare(eth->clks[MTK_CLK_GP2]); | ||
1911 | 1912 | ||
1912 | netif_napi_del(ð->tx_napi); | 1913 | netif_napi_del(ð->tx_napi); |
1913 | netif_napi_del(ð->rx_napi); | 1914 | netif_napi_del(ð->rx_napi); |
1914 | mtk_cleanup(eth); | 1915 | mtk_cleanup(eth); |
1916 | mtk_mdio_cleanup(eth); | ||
1915 | platform_set_drvdata(pdev, NULL); | 1917 | platform_set_drvdata(pdev, NULL); |
1916 | 1918 | ||
1917 | return 0; | 1919 | return 0; |
@@ -1921,6 +1923,7 @@ const struct of_device_id of_mtk_match[] = { | |||
1921 | { .compatible = "mediatek,mt7623-eth" }, | 1923 | { .compatible = "mediatek,mt7623-eth" }, |
1922 | {}, | 1924 | {}, |
1923 | }; | 1925 | }; |
1926 | MODULE_DEVICE_TABLE(of, of_mtk_match); | ||
1924 | 1927 | ||
1925 | static struct platform_driver mtk_driver = { | 1928 | static struct platform_driver mtk_driver = { |
1926 | .probe = mtk_probe, | 1929 | .probe = mtk_probe, |
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h index f82e3acb947b..6e1ade7a25c5 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h | |||
@@ -290,6 +290,17 @@ enum mtk_tx_flags { | |||
290 | MTK_TX_FLAGS_PAGE0 = 0x02, | 290 | MTK_TX_FLAGS_PAGE0 = 0x02, |
291 | }; | 291 | }; |
292 | 292 | ||
293 | /* This enum allows us to identify how the clock is defined on the array of the | ||
294 | * clock in the order | ||
295 | */ | ||
296 | enum mtk_clks_map { | ||
297 | MTK_CLK_ETHIF, | ||
298 | MTK_CLK_ESW, | ||
299 | MTK_CLK_GP1, | ||
300 | MTK_CLK_GP2, | ||
301 | MTK_CLK_MAX | ||
302 | }; | ||
303 | |||
293 | /* struct mtk_tx_buf - This struct holds the pointers to the memory pointed at | 304 | /* struct mtk_tx_buf - This struct holds the pointers to the memory pointed at |
294 | * by the TX descriptor s | 305 | * by the TX descriptor s |
295 | * @skb: The SKB pointer of the packet being sent | 306 | * @skb: The SKB pointer of the packet being sent |
@@ -370,10 +381,7 @@ struct mtk_rx_ring { | |||
370 | * @scratch_ring: Newer SoCs need memory for a second HW managed TX ring | 381 | * @scratch_ring: Newer SoCs need memory for a second HW managed TX ring |
371 | * @phy_scratch_ring: physical address of scratch_ring | 382 | * @phy_scratch_ring: physical address of scratch_ring |
372 | * @scratch_head: The scratch memory that scratch_ring points to. | 383 | * @scratch_head: The scratch memory that scratch_ring points to. |
373 | * @clk_ethif: The ethif clock | 384 | * @clks: clock array for all clocks required |
374 | * @clk_esw: The switch clock | ||
375 | * @clk_gp1: The gmac1 clock | ||
376 | * @clk_gp2: The gmac2 clock | ||
377 | * @mii_bus: If there is a bus we need to create an instance for it | 385 | * @mii_bus: If there is a bus we need to create an instance for it |
378 | * @pending_work: The workqueue used to reset the dma ring | 386 | * @pending_work: The workqueue used to reset the dma ring |
379 | */ | 387 | */ |
@@ -400,10 +408,8 @@ struct mtk_eth { | |||
400 | struct mtk_tx_dma *scratch_ring; | 408 | struct mtk_tx_dma *scratch_ring; |
401 | dma_addr_t phy_scratch_ring; | 409 | dma_addr_t phy_scratch_ring; |
402 | void *scratch_head; | 410 | void *scratch_head; |
403 | struct clk *clk_ethif; | 411 | struct clk *clks[MTK_CLK_MAX]; |
404 | struct clk *clk_esw; | 412 | |
405 | struct clk *clk_gp1; | ||
406 | struct clk *clk_gp2; | ||
407 | struct mii_bus *mii_bus; | 413 | struct mii_bus *mii_bus; |
408 | struct work_struct pending_work; | 414 | struct work_struct pending_work; |
409 | }; | 415 | }; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c index 99c6bbdff501..b04760a5034b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c | |||
@@ -94,7 +94,7 @@ static u8 mlx4_en_dcbnl_getcap(struct net_device *dev, int capid, u8 *cap) | |||
94 | *cap = true; | 94 | *cap = true; |
95 | break; | 95 | break; |
96 | case DCB_CAP_ATTR_DCBX: | 96 | case DCB_CAP_ATTR_DCBX: |
97 | *cap = priv->cee_params.dcbx_cap; | 97 | *cap = priv->dcbx_cap; |
98 | break; | 98 | break; |
99 | case DCB_CAP_ATTR_PFC_TCS: | 99 | case DCB_CAP_ATTR_PFC_TCS: |
100 | *cap = 1 << mlx4_max_tc(priv->mdev->dev); | 100 | *cap = 1 << mlx4_max_tc(priv->mdev->dev); |
@@ -111,14 +111,14 @@ static u8 mlx4_en_dcbnl_getpfcstate(struct net_device *netdev) | |||
111 | { | 111 | { |
112 | struct mlx4_en_priv *priv = netdev_priv(netdev); | 112 | struct mlx4_en_priv *priv = netdev_priv(netdev); |
113 | 113 | ||
114 | return priv->cee_params.dcb_cfg.pfc_state; | 114 | return priv->cee_config.pfc_state; |
115 | } | 115 | } |
116 | 116 | ||
117 | static void mlx4_en_dcbnl_setpfcstate(struct net_device *netdev, u8 state) | 117 | static void mlx4_en_dcbnl_setpfcstate(struct net_device *netdev, u8 state) |
118 | { | 118 | { |
119 | struct mlx4_en_priv *priv = netdev_priv(netdev); | 119 | struct mlx4_en_priv *priv = netdev_priv(netdev); |
120 | 120 | ||
121 | priv->cee_params.dcb_cfg.pfc_state = state; | 121 | priv->cee_config.pfc_state = state; |
122 | } | 122 | } |
123 | 123 | ||
124 | static void mlx4_en_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority, | 124 | static void mlx4_en_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority, |
@@ -126,7 +126,7 @@ static void mlx4_en_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority, | |||
126 | { | 126 | { |
127 | struct mlx4_en_priv *priv = netdev_priv(netdev); | 127 | struct mlx4_en_priv *priv = netdev_priv(netdev); |
128 | 128 | ||
129 | *setting = priv->cee_params.dcb_cfg.tc_config[priority].dcb_pfc; | 129 | *setting = priv->cee_config.dcb_pfc[priority]; |
130 | } | 130 | } |
131 | 131 | ||
132 | static void mlx4_en_dcbnl_set_pfc_cfg(struct net_device *netdev, int priority, | 132 | static void mlx4_en_dcbnl_set_pfc_cfg(struct net_device *netdev, int priority, |
@@ -134,8 +134,8 @@ static void mlx4_en_dcbnl_set_pfc_cfg(struct net_device *netdev, int priority, | |||
134 | { | 134 | { |
135 | struct mlx4_en_priv *priv = netdev_priv(netdev); | 135 | struct mlx4_en_priv *priv = netdev_priv(netdev); |
136 | 136 | ||
137 | priv->cee_params.dcb_cfg.tc_config[priority].dcb_pfc = setting; | 137 | priv->cee_config.dcb_pfc[priority] = setting; |
138 | priv->cee_params.dcb_cfg.pfc_state = true; | 138 | priv->cee_config.pfc_state = true; |
139 | } | 139 | } |
140 | 140 | ||
141 | static int mlx4_en_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num) | 141 | static int mlx4_en_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num) |
@@ -157,13 +157,11 @@ static u8 mlx4_en_dcbnl_set_all(struct net_device *netdev) | |||
157 | { | 157 | { |
158 | struct mlx4_en_priv *priv = netdev_priv(netdev); | 158 | struct mlx4_en_priv *priv = netdev_priv(netdev); |
159 | struct mlx4_en_dev *mdev = priv->mdev; | 159 | struct mlx4_en_dev *mdev = priv->mdev; |
160 | struct mlx4_en_cee_config *dcb_cfg = &priv->cee_params.dcb_cfg; | ||
161 | int err = 0; | ||
162 | 160 | ||
163 | if (!(priv->cee_params.dcbx_cap & DCB_CAP_DCBX_VER_CEE)) | 161 | if (!(priv->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) |
164 | return -EINVAL; | 162 | return 1; |
165 | 163 | ||
166 | if (dcb_cfg->pfc_state) { | 164 | if (priv->cee_config.pfc_state) { |
167 | int tc; | 165 | int tc; |
168 | 166 | ||
169 | priv->prof->rx_pause = 0; | 167 | priv->prof->rx_pause = 0; |
@@ -171,7 +169,7 @@ static u8 mlx4_en_dcbnl_set_all(struct net_device *netdev) | |||
171 | for (tc = 0; tc < CEE_DCBX_MAX_PRIO; tc++) { | 169 | for (tc = 0; tc < CEE_DCBX_MAX_PRIO; tc++) { |
172 | u8 tc_mask = 1 << tc; | 170 | u8 tc_mask = 1 << tc; |
173 | 171 | ||
174 | switch (dcb_cfg->tc_config[tc].dcb_pfc) { | 172 | switch (priv->cee_config.dcb_pfc[tc]) { |
175 | case pfc_disabled: | 173 | case pfc_disabled: |
176 | priv->prof->tx_ppp &= ~tc_mask; | 174 | priv->prof->tx_ppp &= ~tc_mask; |
177 | priv->prof->rx_ppp &= ~tc_mask; | 175 | priv->prof->rx_ppp &= ~tc_mask; |
@@ -199,15 +197,17 @@ static u8 mlx4_en_dcbnl_set_all(struct net_device *netdev) | |||
199 | en_dbg(DRV, priv, "Set pfc off\n"); | 197 | en_dbg(DRV, priv, "Set pfc off\n"); |
200 | } | 198 | } |
201 | 199 | ||
202 | err = mlx4_SET_PORT_general(mdev->dev, priv->port, | 200 | if (mlx4_SET_PORT_general(mdev->dev, priv->port, |
203 | priv->rx_skb_size + ETH_FCS_LEN, | 201 | priv->rx_skb_size + ETH_FCS_LEN, |
204 | priv->prof->tx_pause, | 202 | priv->prof->tx_pause, |
205 | priv->prof->tx_ppp, | 203 | priv->prof->tx_ppp, |
206 | priv->prof->rx_pause, | 204 | priv->prof->rx_pause, |
207 | priv->prof->rx_ppp); | 205 | priv->prof->rx_ppp)) { |
208 | if (err) | ||
209 | en_err(priv, "Failed setting pause params\n"); | 206 | en_err(priv, "Failed setting pause params\n"); |
210 | return err; | 207 | return 1; |
208 | } | ||
209 | |||
210 | return 0; | ||
211 | } | 211 | } |
212 | 212 | ||
213 | static u8 mlx4_en_dcbnl_get_state(struct net_device *dev) | 213 | static u8 mlx4_en_dcbnl_get_state(struct net_device *dev) |
@@ -225,7 +225,7 @@ static u8 mlx4_en_dcbnl_set_state(struct net_device *dev, u8 state) | |||
225 | struct mlx4_en_priv *priv = netdev_priv(dev); | 225 | struct mlx4_en_priv *priv = netdev_priv(dev); |
226 | int num_tcs = 0; | 226 | int num_tcs = 0; |
227 | 227 | ||
228 | if (!(priv->cee_params.dcbx_cap & DCB_CAP_DCBX_VER_CEE)) | 228 | if (!(priv->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) |
229 | return 1; | 229 | return 1; |
230 | 230 | ||
231 | if (!!(state) == !!(priv->flags & MLX4_EN_FLAG_DCB_ENABLED)) | 231 | if (!!(state) == !!(priv->flags & MLX4_EN_FLAG_DCB_ENABLED)) |
@@ -238,7 +238,10 @@ static u8 mlx4_en_dcbnl_set_state(struct net_device *dev, u8 state) | |||
238 | priv->flags &= ~MLX4_EN_FLAG_DCB_ENABLED; | 238 | priv->flags &= ~MLX4_EN_FLAG_DCB_ENABLED; |
239 | } | 239 | } |
240 | 240 | ||
241 | return mlx4_en_setup_tc(dev, num_tcs); | 241 | if (mlx4_en_setup_tc(dev, num_tcs)) |
242 | return 1; | ||
243 | |||
244 | return 0; | ||
242 | } | 245 | } |
243 | 246 | ||
244 | /* On success returns a non-zero 802.1p user priority bitmap | 247 | /* On success returns a non-zero 802.1p user priority bitmap |
@@ -252,7 +255,7 @@ static int mlx4_en_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) | |||
252 | .selector = idtype, | 255 | .selector = idtype, |
253 | .protocol = id, | 256 | .protocol = id, |
254 | }; | 257 | }; |
255 | if (!(priv->cee_params.dcbx_cap & DCB_CAP_DCBX_VER_CEE)) | 258 | if (!(priv->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) |
256 | return 0; | 259 | return 0; |
257 | 260 | ||
258 | return dcb_getapp(netdev, &app); | 261 | return dcb_getapp(netdev, &app); |
@@ -264,7 +267,7 @@ static int mlx4_en_dcbnl_setapp(struct net_device *netdev, u8 idtype, | |||
264 | struct mlx4_en_priv *priv = netdev_priv(netdev); | 267 | struct mlx4_en_priv *priv = netdev_priv(netdev); |
265 | struct dcb_app app; | 268 | struct dcb_app app; |
266 | 269 | ||
267 | if (!(priv->cee_params.dcbx_cap & DCB_CAP_DCBX_VER_CEE)) | 270 | if (!(priv->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) |
268 | return -EINVAL; | 271 | return -EINVAL; |
269 | 272 | ||
270 | memset(&app, 0, sizeof(struct dcb_app)); | 273 | memset(&app, 0, sizeof(struct dcb_app)); |
@@ -433,7 +436,7 @@ static u8 mlx4_en_dcbnl_getdcbx(struct net_device *dev) | |||
433 | { | 436 | { |
434 | struct mlx4_en_priv *priv = netdev_priv(dev); | 437 | struct mlx4_en_priv *priv = netdev_priv(dev); |
435 | 438 | ||
436 | return priv->cee_params.dcbx_cap; | 439 | return priv->dcbx_cap; |
437 | } | 440 | } |
438 | 441 | ||
439 | static u8 mlx4_en_dcbnl_setdcbx(struct net_device *dev, u8 mode) | 442 | static u8 mlx4_en_dcbnl_setdcbx(struct net_device *dev, u8 mode) |
@@ -442,7 +445,7 @@ static u8 mlx4_en_dcbnl_setdcbx(struct net_device *dev, u8 mode) | |||
442 | struct ieee_ets ets = {0}; | 445 | struct ieee_ets ets = {0}; |
443 | struct ieee_pfc pfc = {0}; | 446 | struct ieee_pfc pfc = {0}; |
444 | 447 | ||
445 | if (mode == priv->cee_params.dcbx_cap) | 448 | if (mode == priv->dcbx_cap) |
446 | return 0; | 449 | return 0; |
447 | 450 | ||
448 | if ((mode & DCB_CAP_DCBX_LLD_MANAGED) || | 451 | if ((mode & DCB_CAP_DCBX_LLD_MANAGED) || |
@@ -451,7 +454,7 @@ static u8 mlx4_en_dcbnl_setdcbx(struct net_device *dev, u8 mode) | |||
451 | !(mode & DCB_CAP_DCBX_HOST)) | 454 | !(mode & DCB_CAP_DCBX_HOST)) |
452 | goto err; | 455 | goto err; |
453 | 456 | ||
454 | priv->cee_params.dcbx_cap = mode; | 457 | priv->dcbx_cap = mode; |
455 | 458 | ||
456 | ets.ets_cap = IEEE_8021QAZ_MAX_TCS; | 459 | ets.ets_cap = IEEE_8021QAZ_MAX_TCS; |
457 | pfc.pfc_cap = IEEE_8021QAZ_MAX_TCS; | 460 | pfc.pfc_cap = IEEE_8021QAZ_MAX_TCS; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 4198e9bf89d0..fedb829276f4 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -71,10 +71,11 @@ int mlx4_en_setup_tc(struct net_device *dev, u8 up) | |||
71 | #ifdef CONFIG_MLX4_EN_DCB | 71 | #ifdef CONFIG_MLX4_EN_DCB |
72 | if (!mlx4_is_slave(priv->mdev->dev)) { | 72 | if (!mlx4_is_slave(priv->mdev->dev)) { |
73 | if (up) { | 73 | if (up) { |
74 | priv->flags |= MLX4_EN_FLAG_DCB_ENABLED; | 74 | if (priv->dcbx_cap) |
75 | priv->flags |= MLX4_EN_FLAG_DCB_ENABLED; | ||
75 | } else { | 76 | } else { |
76 | priv->flags &= ~MLX4_EN_FLAG_DCB_ENABLED; | 77 | priv->flags &= ~MLX4_EN_FLAG_DCB_ENABLED; |
77 | priv->cee_params.dcb_cfg.pfc_state = false; | 78 | priv->cee_config.pfc_state = false; |
78 | } | 79 | } |
79 | } | 80 | } |
80 | #endif /* CONFIG_MLX4_EN_DCB */ | 81 | #endif /* CONFIG_MLX4_EN_DCB */ |
@@ -3048,9 +3049,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | |||
3048 | struct mlx4_en_priv *priv; | 3049 | struct mlx4_en_priv *priv; |
3049 | int i; | 3050 | int i; |
3050 | int err; | 3051 | int err; |
3051 | #ifdef CONFIG_MLX4_EN_DCB | ||
3052 | struct tc_configuration *tc; | ||
3053 | #endif | ||
3054 | 3052 | ||
3055 | dev = alloc_etherdev_mqs(sizeof(struct mlx4_en_priv), | 3053 | dev = alloc_etherdev_mqs(sizeof(struct mlx4_en_priv), |
3056 | MAX_TX_RINGS, MAX_RX_RINGS); | 3054 | MAX_TX_RINGS, MAX_RX_RINGS); |
@@ -3117,16 +3115,13 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | |||
3117 | priv->msg_enable = MLX4_EN_MSG_LEVEL; | 3115 | priv->msg_enable = MLX4_EN_MSG_LEVEL; |
3118 | #ifdef CONFIG_MLX4_EN_DCB | 3116 | #ifdef CONFIG_MLX4_EN_DCB |
3119 | if (!mlx4_is_slave(priv->mdev->dev)) { | 3117 | if (!mlx4_is_slave(priv->mdev->dev)) { |
3120 | priv->cee_params.dcbx_cap = DCB_CAP_DCBX_VER_CEE | | 3118 | priv->dcbx_cap = DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_HOST | |
3121 | DCB_CAP_DCBX_HOST | | 3119 | DCB_CAP_DCBX_VER_IEEE; |
3122 | DCB_CAP_DCBX_VER_IEEE; | ||
3123 | priv->flags |= MLX4_EN_DCB_ENABLED; | 3120 | priv->flags |= MLX4_EN_DCB_ENABLED; |
3124 | priv->cee_params.dcb_cfg.pfc_state = false; | 3121 | priv->cee_config.pfc_state = false; |
3125 | 3122 | ||
3126 | for (i = 0; i < MLX4_EN_NUM_UP; i++) { | 3123 | for (i = 0; i < MLX4_EN_NUM_UP; i++) |
3127 | tc = &priv->cee_params.dcb_cfg.tc_config[i]; | 3124 | priv->cee_config.dcb_pfc[i] = pfc_disabled; |
3128 | tc->dcb_pfc = pfc_disabled; | ||
3129 | } | ||
3130 | 3125 | ||
3131 | if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ETS_CFG) { | 3126 | if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ETS_CFG) { |
3132 | dev->dcbnl_ops = &mlx4_en_dcbnl_ops; | 3127 | dev->dcbnl_ops = &mlx4_en_dcbnl_ops; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 9df87ca0515a..e2509bba3e7c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
@@ -818,7 +818,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) | |||
818 | real_size = get_real_size(skb, shinfo, dev, &lso_header_size, | 818 | real_size = get_real_size(skb, shinfo, dev, &lso_header_size, |
819 | &inline_ok, &fragptr); | 819 | &inline_ok, &fragptr); |
820 | if (unlikely(!real_size)) | 820 | if (unlikely(!real_size)) |
821 | goto tx_drop; | 821 | goto tx_drop_count; |
822 | 822 | ||
823 | /* Align descriptor to TXBB size */ | 823 | /* Align descriptor to TXBB size */ |
824 | desc_size = ALIGN(real_size, TXBB_SIZE); | 824 | desc_size = ALIGN(real_size, TXBB_SIZE); |
@@ -826,7 +826,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) | |||
826 | if (unlikely(nr_txbb > MAX_DESC_TXBBS)) { | 826 | if (unlikely(nr_txbb > MAX_DESC_TXBBS)) { |
827 | if (netif_msg_tx_err(priv)) | 827 | if (netif_msg_tx_err(priv)) |
828 | en_warn(priv, "Oversized header or SG list\n"); | 828 | en_warn(priv, "Oversized header or SG list\n"); |
829 | goto tx_drop; | 829 | goto tx_drop_count; |
830 | } | 830 | } |
831 | 831 | ||
832 | bf_ok = ring->bf_enabled; | 832 | bf_ok = ring->bf_enabled; |
@@ -1071,9 +1071,10 @@ tx_drop_unmap: | |||
1071 | PCI_DMA_TODEVICE); | 1071 | PCI_DMA_TODEVICE); |
1072 | } | 1072 | } |
1073 | 1073 | ||
1074 | tx_drop_count: | ||
1075 | ring->tx_dropped++; | ||
1074 | tx_drop: | 1076 | tx_drop: |
1075 | dev_kfree_skb_any(skb); | 1077 | dev_kfree_skb_any(skb); |
1076 | ring->tx_dropped++; | ||
1077 | return NETDEV_TX_OK; | 1078 | return NETDEV_TX_OK; |
1078 | } | 1079 | } |
1079 | 1080 | ||
@@ -1106,7 +1107,7 @@ netdev_tx_t mlx4_en_xmit_frame(struct mlx4_en_rx_alloc *frame, | |||
1106 | goto tx_drop; | 1107 | goto tx_drop; |
1107 | 1108 | ||
1108 | if (mlx4_en_is_tx_ring_full(ring)) | 1109 | if (mlx4_en_is_tx_ring_full(ring)) |
1109 | goto tx_drop; | 1110 | goto tx_drop_count; |
1110 | 1111 | ||
1111 | /* fetch ring->cons far ahead before needing it to avoid stall */ | 1112 | /* fetch ring->cons far ahead before needing it to avoid stall */ |
1112 | ring_cons = READ_ONCE(ring->cons); | 1113 | ring_cons = READ_ONCE(ring->cons); |
@@ -1176,7 +1177,8 @@ netdev_tx_t mlx4_en_xmit_frame(struct mlx4_en_rx_alloc *frame, | |||
1176 | 1177 | ||
1177 | return NETDEV_TX_OK; | 1178 | return NETDEV_TX_OK; |
1178 | 1179 | ||
1179 | tx_drop: | 1180 | tx_drop_count: |
1180 | ring->tx_dropped++; | 1181 | ring->tx_dropped++; |
1182 | tx_drop: | ||
1181 | return NETDEV_TX_BUSY; | 1183 | return NETDEV_TX_BUSY; |
1182 | } | 1184 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index f613977455e0..cf8f8a72a801 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c | |||
@@ -1305,8 +1305,8 @@ int mlx4_init_eq_table(struct mlx4_dev *dev) | |||
1305 | return 0; | 1305 | return 0; |
1306 | 1306 | ||
1307 | err_out_unmap: | 1307 | err_out_unmap: |
1308 | while (i >= 0) | 1308 | while (i > 0) |
1309 | mlx4_free_eq(dev, &priv->eq_table.eq[i--]); | 1309 | mlx4_free_eq(dev, &priv->eq_table.eq[--i]); |
1310 | #ifdef CONFIG_RFS_ACCEL | 1310 | #ifdef CONFIG_RFS_ACCEL |
1311 | for (i = 1; i <= dev->caps.num_ports; i++) { | 1311 | for (i = 1; i <= dev->caps.num_ports; i++) { |
1312 | if (mlx4_priv(dev)->port[i].rmap) { | 1312 | if (mlx4_priv(dev)->port[i].rmap) { |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 75dd2e3d3059..7183ac4135d2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -2970,6 +2970,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) | |||
2970 | mlx4_err(dev, "Failed to create mtu file for port %d\n", port); | 2970 | mlx4_err(dev, "Failed to create mtu file for port %d\n", port); |
2971 | device_remove_file(&info->dev->persist->pdev->dev, | 2971 | device_remove_file(&info->dev->persist->pdev->dev, |
2972 | &info->port_attr); | 2972 | &info->port_attr); |
2973 | devlink_port_unregister(&info->devlink_port); | ||
2973 | info->port = -1; | 2974 | info->port = -1; |
2974 | } | 2975 | } |
2975 | 2976 | ||
@@ -2984,6 +2985,8 @@ static void mlx4_cleanup_port_info(struct mlx4_port_info *info) | |||
2984 | device_remove_file(&info->dev->persist->pdev->dev, &info->port_attr); | 2985 | device_remove_file(&info->dev->persist->pdev->dev, &info->port_attr); |
2985 | device_remove_file(&info->dev->persist->pdev->dev, | 2986 | device_remove_file(&info->dev->persist->pdev->dev, |
2986 | &info->port_mtu_attr); | 2987 | &info->port_mtu_attr); |
2988 | devlink_port_unregister(&info->devlink_port); | ||
2989 | |||
2987 | #ifdef CONFIG_RFS_ACCEL | 2990 | #ifdef CONFIG_RFS_ACCEL |
2988 | free_irq_cpu_rmap(info->rmap); | 2991 | free_irq_cpu_rmap(info->rmap); |
2989 | info->rmap = NULL; | 2992 | info->rmap = NULL; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 2c2913dcae98..9099dbd04951 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
@@ -482,20 +482,10 @@ enum dcb_pfc_type { | |||
482 | pfc_enabled_rx | 482 | pfc_enabled_rx |
483 | }; | 483 | }; |
484 | 484 | ||
485 | struct tc_configuration { | ||
486 | enum dcb_pfc_type dcb_pfc; | ||
487 | }; | ||
488 | |||
489 | struct mlx4_en_cee_config { | 485 | struct mlx4_en_cee_config { |
490 | bool pfc_state; | 486 | bool pfc_state; |
491 | struct tc_configuration tc_config[MLX4_EN_NUM_UP]; | 487 | enum dcb_pfc_type dcb_pfc[MLX4_EN_NUM_UP]; |
492 | }; | 488 | }; |
493 | |||
494 | struct mlx4_en_cee_params { | ||
495 | u8 dcbx_cap; | ||
496 | struct mlx4_en_cee_config dcb_cfg; | ||
497 | }; | ||
498 | |||
499 | #endif | 489 | #endif |
500 | 490 | ||
501 | struct ethtool_flow_id { | 491 | struct ethtool_flow_id { |
@@ -624,7 +614,8 @@ struct mlx4_en_priv { | |||
624 | struct ieee_ets ets; | 614 | struct ieee_ets ets; |
625 | u16 maxrate[IEEE_8021QAZ_MAX_TCS]; | 615 | u16 maxrate[IEEE_8021QAZ_MAX_TCS]; |
626 | enum dcbnl_cndd_states cndd_state[IEEE_8021QAZ_MAX_TCS]; | 616 | enum dcbnl_cndd_states cndd_state[IEEE_8021QAZ_MAX_TCS]; |
627 | struct mlx4_en_cee_params cee_params; | 617 | struct mlx4_en_cee_config cee_config; |
618 | u8 dcbx_cap; | ||
628 | #endif | 619 | #endif |
629 | #ifdef CONFIG_RFS_ACCEL | 620 | #ifdef CONFIG_RFS_ACCEL |
630 | spinlock_t filters_lock; | 621 | spinlock_t filters_lock; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index 3d2095e5c61c..c5b2064297a1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c | |||
@@ -52,7 +52,7 @@ | |||
52 | 52 | ||
53 | #define MLX4_FLAG_V_IGNORE_FCS_MASK 0x2 | 53 | #define MLX4_FLAG_V_IGNORE_FCS_MASK 0x2 |
54 | #define MLX4_IGNORE_FCS_MASK 0x1 | 54 | #define MLX4_IGNORE_FCS_MASK 0x1 |
55 | #define MLNX4_TX_MAX_NUMBER 8 | 55 | #define MLX4_TC_MAX_NUMBER 8 |
56 | 56 | ||
57 | void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table) | 57 | void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table) |
58 | { | 58 | { |
@@ -2022,7 +2022,7 @@ int mlx4_max_tc(struct mlx4_dev *dev) | |||
2022 | u8 num_tc = dev->caps.max_tc_eth; | 2022 | u8 num_tc = dev->caps.max_tc_eth; |
2023 | 2023 | ||
2024 | if (!num_tc) | 2024 | if (!num_tc) |
2025 | num_tc = MLNX4_TX_MAX_NUMBER; | 2025 | num_tc = MLX4_TC_MAX_NUMBER; |
2026 | 2026 | ||
2027 | return num_tc; | 2027 | return num_tc; |
2028 | } | 2028 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c index d6e2a1cae19a..c2ec01a22d55 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c | |||
@@ -143,13 +143,14 @@ static struct mlx5_cmd_layout *get_inst(struct mlx5_cmd *cmd, int idx) | |||
143 | return cmd->cmd_buf + (idx << cmd->log_stride); | 143 | return cmd->cmd_buf + (idx << cmd->log_stride); |
144 | } | 144 | } |
145 | 145 | ||
146 | static u8 xor8_buf(void *buf, int len) | 146 | static u8 xor8_buf(void *buf, size_t offset, int len) |
147 | { | 147 | { |
148 | u8 *ptr = buf; | 148 | u8 *ptr = buf; |
149 | u8 sum = 0; | 149 | u8 sum = 0; |
150 | int i; | 150 | int i; |
151 | int end = len + offset; | ||
151 | 152 | ||
152 | for (i = 0; i < len; i++) | 153 | for (i = offset; i < end; i++) |
153 | sum ^= ptr[i]; | 154 | sum ^= ptr[i]; |
154 | 155 | ||
155 | return sum; | 156 | return sum; |
@@ -157,41 +158,49 @@ static u8 xor8_buf(void *buf, int len) | |||
157 | 158 | ||
158 | static int verify_block_sig(struct mlx5_cmd_prot_block *block) | 159 | static int verify_block_sig(struct mlx5_cmd_prot_block *block) |
159 | { | 160 | { |
160 | if (xor8_buf(block->rsvd0, sizeof(*block) - sizeof(block->data) - 1) != 0xff) | 161 | size_t rsvd0_off = offsetof(struct mlx5_cmd_prot_block, rsvd0); |
162 | int xor_len = sizeof(*block) - sizeof(block->data) - 1; | ||
163 | |||
164 | if (xor8_buf(block, rsvd0_off, xor_len) != 0xff) | ||
161 | return -EINVAL; | 165 | return -EINVAL; |
162 | 166 | ||
163 | if (xor8_buf(block, sizeof(*block)) != 0xff) | 167 | if (xor8_buf(block, 0, sizeof(*block)) != 0xff) |
164 | return -EINVAL; | 168 | return -EINVAL; |
165 | 169 | ||
166 | return 0; | 170 | return 0; |
167 | } | 171 | } |
168 | 172 | ||
169 | static void calc_block_sig(struct mlx5_cmd_prot_block *block, u8 token, | 173 | static void calc_block_sig(struct mlx5_cmd_prot_block *block) |
170 | int csum) | ||
171 | { | 174 | { |
172 | block->token = token; | 175 | int ctrl_xor_len = sizeof(*block) - sizeof(block->data) - 2; |
173 | if (csum) { | 176 | size_t rsvd0_off = offsetof(struct mlx5_cmd_prot_block, rsvd0); |
174 | block->ctrl_sig = ~xor8_buf(block->rsvd0, sizeof(*block) - | 177 | |
175 | sizeof(block->data) - 2); | 178 | block->ctrl_sig = ~xor8_buf(block, rsvd0_off, ctrl_xor_len); |
176 | block->sig = ~xor8_buf(block, sizeof(*block) - 1); | 179 | block->sig = ~xor8_buf(block, 0, sizeof(*block) - 1); |
177 | } | ||
178 | } | 180 | } |
179 | 181 | ||
180 | static void calc_chain_sig(struct mlx5_cmd_msg *msg, u8 token, int csum) | 182 | static void calc_chain_sig(struct mlx5_cmd_msg *msg) |
181 | { | 183 | { |
182 | struct mlx5_cmd_mailbox *next = msg->next; | 184 | struct mlx5_cmd_mailbox *next = msg->next; |
183 | 185 | int size = msg->len; | |
184 | while (next) { | 186 | int blen = size - min_t(int, sizeof(msg->first.data), size); |
185 | calc_block_sig(next->buf, token, csum); | 187 | int n = (blen + MLX5_CMD_DATA_BLOCK_SIZE - 1) |
188 | / MLX5_CMD_DATA_BLOCK_SIZE; | ||
189 | int i = 0; | ||
190 | |||
191 | for (i = 0; i < n && next; i++) { | ||
192 | calc_block_sig(next->buf); | ||
186 | next = next->next; | 193 | next = next->next; |
187 | } | 194 | } |
188 | } | 195 | } |
189 | 196 | ||
190 | static void set_signature(struct mlx5_cmd_work_ent *ent, int csum) | 197 | static void set_signature(struct mlx5_cmd_work_ent *ent, int csum) |
191 | { | 198 | { |
192 | ent->lay->sig = ~xor8_buf(ent->lay, sizeof(*ent->lay)); | 199 | ent->lay->sig = ~xor8_buf(ent->lay, 0, sizeof(*ent->lay)); |
193 | calc_chain_sig(ent->in, ent->token, csum); | 200 | if (csum) { |
194 | calc_chain_sig(ent->out, ent->token, csum); | 201 | calc_chain_sig(ent->in); |
202 | calc_chain_sig(ent->out); | ||
203 | } | ||
195 | } | 204 | } |
196 | 205 | ||
197 | static void poll_timeout(struct mlx5_cmd_work_ent *ent) | 206 | static void poll_timeout(struct mlx5_cmd_work_ent *ent) |
@@ -222,12 +231,17 @@ static int verify_signature(struct mlx5_cmd_work_ent *ent) | |||
222 | struct mlx5_cmd_mailbox *next = ent->out->next; | 231 | struct mlx5_cmd_mailbox *next = ent->out->next; |
223 | int err; | 232 | int err; |
224 | u8 sig; | 233 | u8 sig; |
234 | int size = ent->out->len; | ||
235 | int blen = size - min_t(int, sizeof(ent->out->first.data), size); | ||
236 | int n = (blen + MLX5_CMD_DATA_BLOCK_SIZE - 1) | ||
237 | / MLX5_CMD_DATA_BLOCK_SIZE; | ||
238 | int i = 0; | ||
225 | 239 | ||
226 | sig = xor8_buf(ent->lay, sizeof(*ent->lay)); | 240 | sig = xor8_buf(ent->lay, 0, sizeof(*ent->lay)); |
227 | if (sig != 0xff) | 241 | if (sig != 0xff) |
228 | return -EINVAL; | 242 | return -EINVAL; |
229 | 243 | ||
230 | while (next) { | 244 | for (i = 0; i < n && next; i++) { |
231 | err = verify_block_sig(next->buf); | 245 | err = verify_block_sig(next->buf); |
232 | if (err) | 246 | if (err) |
233 | return err; | 247 | return err; |
@@ -656,7 +670,6 @@ static void cmd_work_handler(struct work_struct *work) | |||
656 | spin_unlock_irqrestore(&cmd->alloc_lock, flags); | 670 | spin_unlock_irqrestore(&cmd->alloc_lock, flags); |
657 | } | 671 | } |
658 | 672 | ||
659 | ent->token = alloc_token(cmd); | ||
660 | cmd->ent_arr[ent->idx] = ent; | 673 | cmd->ent_arr[ent->idx] = ent; |
661 | lay = get_inst(cmd, ent->idx); | 674 | lay = get_inst(cmd, ent->idx); |
662 | ent->lay = lay; | 675 | ent->lay = lay; |
@@ -766,7 +779,8 @@ static u8 *get_status_ptr(struct mlx5_outbox_hdr *out) | |||
766 | static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in, | 779 | static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in, |
767 | struct mlx5_cmd_msg *out, void *uout, int uout_size, | 780 | struct mlx5_cmd_msg *out, void *uout, int uout_size, |
768 | mlx5_cmd_cbk_t callback, | 781 | mlx5_cmd_cbk_t callback, |
769 | void *context, int page_queue, u8 *status) | 782 | void *context, int page_queue, u8 *status, |
783 | u8 token) | ||
770 | { | 784 | { |
771 | struct mlx5_cmd *cmd = &dev->cmd; | 785 | struct mlx5_cmd *cmd = &dev->cmd; |
772 | struct mlx5_cmd_work_ent *ent; | 786 | struct mlx5_cmd_work_ent *ent; |
@@ -783,6 +797,8 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in, | |||
783 | if (IS_ERR(ent)) | 797 | if (IS_ERR(ent)) |
784 | return PTR_ERR(ent); | 798 | return PTR_ERR(ent); |
785 | 799 | ||
800 | ent->token = token; | ||
801 | |||
786 | if (!callback) | 802 | if (!callback) |
787 | init_completion(&ent->done); | 803 | init_completion(&ent->done); |
788 | 804 | ||
@@ -854,7 +870,8 @@ static const struct file_operations fops = { | |||
854 | .write = dbg_write, | 870 | .write = dbg_write, |
855 | }; | 871 | }; |
856 | 872 | ||
857 | static int mlx5_copy_to_msg(struct mlx5_cmd_msg *to, void *from, int size) | 873 | static int mlx5_copy_to_msg(struct mlx5_cmd_msg *to, void *from, int size, |
874 | u8 token) | ||
858 | { | 875 | { |
859 | struct mlx5_cmd_prot_block *block; | 876 | struct mlx5_cmd_prot_block *block; |
860 | struct mlx5_cmd_mailbox *next; | 877 | struct mlx5_cmd_mailbox *next; |
@@ -880,6 +897,7 @@ static int mlx5_copy_to_msg(struct mlx5_cmd_msg *to, void *from, int size) | |||
880 | memcpy(block->data, from, copy); | 897 | memcpy(block->data, from, copy); |
881 | from += copy; | 898 | from += copy; |
882 | size -= copy; | 899 | size -= copy; |
900 | block->token = token; | ||
883 | next = next->next; | 901 | next = next->next; |
884 | } | 902 | } |
885 | 903 | ||
@@ -949,7 +967,8 @@ static void free_cmd_box(struct mlx5_core_dev *dev, | |||
949 | } | 967 | } |
950 | 968 | ||
951 | static struct mlx5_cmd_msg *mlx5_alloc_cmd_msg(struct mlx5_core_dev *dev, | 969 | static struct mlx5_cmd_msg *mlx5_alloc_cmd_msg(struct mlx5_core_dev *dev, |
952 | gfp_t flags, int size) | 970 | gfp_t flags, int size, |
971 | u8 token) | ||
953 | { | 972 | { |
954 | struct mlx5_cmd_mailbox *tmp, *head = NULL; | 973 | struct mlx5_cmd_mailbox *tmp, *head = NULL; |
955 | struct mlx5_cmd_prot_block *block; | 974 | struct mlx5_cmd_prot_block *block; |
@@ -978,6 +997,7 @@ static struct mlx5_cmd_msg *mlx5_alloc_cmd_msg(struct mlx5_core_dev *dev, | |||
978 | tmp->next = head; | 997 | tmp->next = head; |
979 | block->next = cpu_to_be64(tmp->next ? tmp->next->dma : 0); | 998 | block->next = cpu_to_be64(tmp->next ? tmp->next->dma : 0); |
980 | block->block_num = cpu_to_be32(n - i - 1); | 999 | block->block_num = cpu_to_be32(n - i - 1); |
1000 | block->token = token; | ||
981 | head = tmp; | 1001 | head = tmp; |
982 | } | 1002 | } |
983 | msg->next = head; | 1003 | msg->next = head; |
@@ -1352,7 +1372,7 @@ static struct mlx5_cmd_msg *alloc_msg(struct mlx5_core_dev *dev, int in_size, | |||
1352 | } | 1372 | } |
1353 | 1373 | ||
1354 | if (IS_ERR(msg)) | 1374 | if (IS_ERR(msg)) |
1355 | msg = mlx5_alloc_cmd_msg(dev, gfp, in_size); | 1375 | msg = mlx5_alloc_cmd_msg(dev, gfp, in_size, 0); |
1356 | 1376 | ||
1357 | return msg; | 1377 | return msg; |
1358 | } | 1378 | } |
@@ -1377,6 +1397,7 @@ static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out, | |||
1377 | int err; | 1397 | int err; |
1378 | u8 status = 0; | 1398 | u8 status = 0; |
1379 | u32 drv_synd; | 1399 | u32 drv_synd; |
1400 | u8 token; | ||
1380 | 1401 | ||
1381 | if (pci_channel_offline(dev->pdev) || | 1402 | if (pci_channel_offline(dev->pdev) || |
1382 | dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) { | 1403 | dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) { |
@@ -1395,20 +1416,22 @@ static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out, | |||
1395 | return err; | 1416 | return err; |
1396 | } | 1417 | } |
1397 | 1418 | ||
1398 | err = mlx5_copy_to_msg(inb, in, in_size); | 1419 | token = alloc_token(&dev->cmd); |
1420 | |||
1421 | err = mlx5_copy_to_msg(inb, in, in_size, token); | ||
1399 | if (err) { | 1422 | if (err) { |
1400 | mlx5_core_warn(dev, "err %d\n", err); | 1423 | mlx5_core_warn(dev, "err %d\n", err); |
1401 | goto out_in; | 1424 | goto out_in; |
1402 | } | 1425 | } |
1403 | 1426 | ||
1404 | outb = mlx5_alloc_cmd_msg(dev, gfp, out_size); | 1427 | outb = mlx5_alloc_cmd_msg(dev, gfp, out_size, token); |
1405 | if (IS_ERR(outb)) { | 1428 | if (IS_ERR(outb)) { |
1406 | err = PTR_ERR(outb); | 1429 | err = PTR_ERR(outb); |
1407 | goto out_in; | 1430 | goto out_in; |
1408 | } | 1431 | } |
1409 | 1432 | ||
1410 | err = mlx5_cmd_invoke(dev, inb, outb, out, out_size, callback, context, | 1433 | err = mlx5_cmd_invoke(dev, inb, outb, out, out_size, callback, context, |
1411 | pages_queue, &status); | 1434 | pages_queue, &status, token); |
1412 | if (err) | 1435 | if (err) |
1413 | goto out_out; | 1436 | goto out_out; |
1414 | 1437 | ||
@@ -1476,7 +1499,7 @@ static int create_msg_cache(struct mlx5_core_dev *dev) | |||
1476 | INIT_LIST_HEAD(&cmd->cache.med.head); | 1499 | INIT_LIST_HEAD(&cmd->cache.med.head); |
1477 | 1500 | ||
1478 | for (i = 0; i < NUM_LONG_LISTS; i++) { | 1501 | for (i = 0; i < NUM_LONG_LISTS; i++) { |
1479 | msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, LONG_LIST_SIZE); | 1502 | msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, LONG_LIST_SIZE, 0); |
1480 | if (IS_ERR(msg)) { | 1503 | if (IS_ERR(msg)) { |
1481 | err = PTR_ERR(msg); | 1504 | err = PTR_ERR(msg); |
1482 | goto ex_err; | 1505 | goto ex_err; |
@@ -1486,7 +1509,7 @@ static int create_msg_cache(struct mlx5_core_dev *dev) | |||
1486 | } | 1509 | } |
1487 | 1510 | ||
1488 | for (i = 0; i < NUM_MED_LISTS; i++) { | 1511 | for (i = 0; i < NUM_MED_LISTS; i++) { |
1489 | msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, MED_LIST_SIZE); | 1512 | msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, MED_LIST_SIZE, 0); |
1490 | if (IS_ERR(msg)) { | 1513 | if (IS_ERR(msg)) { |
1491 | err = PTR_ERR(msg); | 1514 | err = PTR_ERR(msg); |
1492 | goto ex_err; | 1515 | goto ex_err; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index 1b495efa7490..bf722aa88cf0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h | |||
@@ -73,8 +73,12 @@ | |||
73 | #define MLX5_MPWRQ_PAGES_PER_WQE BIT(MLX5_MPWRQ_WQE_PAGE_ORDER) | 73 | #define MLX5_MPWRQ_PAGES_PER_WQE BIT(MLX5_MPWRQ_WQE_PAGE_ORDER) |
74 | #define MLX5_MPWRQ_STRIDES_PER_PAGE (MLX5_MPWRQ_NUM_STRIDES >> \ | 74 | #define MLX5_MPWRQ_STRIDES_PER_PAGE (MLX5_MPWRQ_NUM_STRIDES >> \ |
75 | MLX5_MPWRQ_WQE_PAGE_ORDER) | 75 | MLX5_MPWRQ_WQE_PAGE_ORDER) |
76 | #define MLX5_CHANNEL_MAX_NUM_MTTS (ALIGN(MLX5_MPWRQ_PAGES_PER_WQE, 8) * \ | 76 | |
77 | BIT(MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW)) | 77 | #define MLX5_MTT_OCTW(npages) (ALIGN(npages, 8) / 2) |
78 | #define MLX5E_REQUIRED_MTTS(rqs, wqes)\ | ||
79 | (rqs * wqes * ALIGN(MLX5_MPWRQ_PAGES_PER_WQE, 8)) | ||
80 | #define MLX5E_VALID_NUM_MTTS(num_mtts) (MLX5_MTT_OCTW(num_mtts) <= U16_MAX) | ||
81 | |||
78 | #define MLX5_UMR_ALIGN (2048) | 82 | #define MLX5_UMR_ALIGN (2048) |
79 | #define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD (128) | 83 | #define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD (128) |
80 | 84 | ||
@@ -219,9 +223,8 @@ struct mlx5e_tstamp { | |||
219 | }; | 223 | }; |
220 | 224 | ||
221 | enum { | 225 | enum { |
222 | MLX5E_RQ_STATE_POST_WQES_ENABLE, | 226 | MLX5E_RQ_STATE_FLUSH, |
223 | MLX5E_RQ_STATE_UMR_WQE_IN_PROGRESS, | 227 | MLX5E_RQ_STATE_UMR_WQE_IN_PROGRESS, |
224 | MLX5E_RQ_STATE_FLUSH_TIMEOUT, | ||
225 | MLX5E_RQ_STATE_AM, | 228 | MLX5E_RQ_STATE_AM, |
226 | }; | 229 | }; |
227 | 230 | ||
@@ -304,6 +307,7 @@ struct mlx5e_rq { | |||
304 | 307 | ||
305 | unsigned long state; | 308 | unsigned long state; |
306 | int ix; | 309 | int ix; |
310 | u32 mpwqe_mtt_offset; | ||
307 | 311 | ||
308 | struct mlx5e_rx_am am; /* Adaptive Moderation */ | 312 | struct mlx5e_rx_am am; /* Adaptive Moderation */ |
309 | 313 | ||
@@ -365,9 +369,8 @@ struct mlx5e_sq_dma { | |||
365 | }; | 369 | }; |
366 | 370 | ||
367 | enum { | 371 | enum { |
368 | MLX5E_SQ_STATE_WAKE_TXQ_ENABLE, | 372 | MLX5E_SQ_STATE_FLUSH, |
369 | MLX5E_SQ_STATE_BF_ENABLE, | 373 | MLX5E_SQ_STATE_BF_ENABLE, |
370 | MLX5E_SQ_STATE_TX_TIMEOUT, | ||
371 | }; | 374 | }; |
372 | 375 | ||
373 | struct mlx5e_ico_wqe_info { | 376 | struct mlx5e_ico_wqe_info { |
@@ -698,7 +701,6 @@ int mlx5e_napi_poll(struct napi_struct *napi, int budget); | |||
698 | bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget); | 701 | bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget); |
699 | int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget); | 702 | int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget); |
700 | void mlx5e_free_tx_descs(struct mlx5e_sq *sq); | 703 | void mlx5e_free_tx_descs(struct mlx5e_sq *sq); |
701 | void mlx5e_free_rx_descs(struct mlx5e_rq *rq); | ||
702 | 704 | ||
703 | void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe); | 705 | void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe); |
704 | void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe); | 706 | void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe); |
@@ -814,11 +816,6 @@ static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev) | |||
814 | MLX5E_MAX_NUM_CHANNELS); | 816 | MLX5E_MAX_NUM_CHANNELS); |
815 | } | 817 | } |
816 | 818 | ||
817 | static inline int mlx5e_get_mtt_octw(int npages) | ||
818 | { | ||
819 | return ALIGN(npages, 8) / 2; | ||
820 | } | ||
821 | |||
822 | extern const struct ethtool_ops mlx5e_ethtool_ops; | 819 | extern const struct ethtool_ops mlx5e_ethtool_ops; |
823 | #ifdef CONFIG_MLX5_CORE_EN_DCB | 820 | #ifdef CONFIG_MLX5_CORE_EN_DCB |
824 | extern const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops; | 821 | extern const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c index 673043ccd76c..9cce153e1035 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c | |||
@@ -139,7 +139,7 @@ int mlx5e_refresh_tirs_self_loopback_enable(struct mlx5_core_dev *mdev) | |||
139 | struct mlx5e_tir *tir; | 139 | struct mlx5e_tir *tir; |
140 | void *in; | 140 | void *in; |
141 | int inlen; | 141 | int inlen; |
142 | int err; | 142 | int err = 0; |
143 | 143 | ||
144 | inlen = MLX5_ST_SZ_BYTES(modify_tir_in); | 144 | inlen = MLX5_ST_SZ_BYTES(modify_tir_in); |
145 | in = mlx5_vzalloc(inlen); | 145 | in = mlx5_vzalloc(inlen); |
@@ -151,10 +151,11 @@ int mlx5e_refresh_tirs_self_loopback_enable(struct mlx5_core_dev *mdev) | |||
151 | list_for_each_entry(tir, &mdev->mlx5e_res.td.tirs_list, list) { | 151 | list_for_each_entry(tir, &mdev->mlx5e_res.td.tirs_list, list) { |
152 | err = mlx5_core_modify_tir(mdev, tir->tirn, in, inlen); | 152 | err = mlx5_core_modify_tir(mdev, tir->tirn, in, inlen); |
153 | if (err) | 153 | if (err) |
154 | return err; | 154 | goto out; |
155 | } | 155 | } |
156 | 156 | ||
157 | out: | ||
157 | kvfree(in); | 158 | kvfree(in); |
158 | 159 | ||
159 | return 0; | 160 | return err; |
160 | } | 161 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c index caa9a3ccc3f3..762af16ed021 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | |||
@@ -127,29 +127,40 @@ int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets) | |||
127 | return mlx5_set_port_tc_bw_alloc(mdev, tc_tx_bw); | 127 | return mlx5_set_port_tc_bw_alloc(mdev, tc_tx_bw); |
128 | } | 128 | } |
129 | 129 | ||
130 | static int mlx5e_dbcnl_validate_ets(struct ieee_ets *ets) | 130 | static int mlx5e_dbcnl_validate_ets(struct net_device *netdev, |
131 | struct ieee_ets *ets) | ||
131 | { | 132 | { |
132 | int bw_sum = 0; | 133 | int bw_sum = 0; |
133 | int i; | 134 | int i; |
134 | 135 | ||
135 | /* Validate Priority */ | 136 | /* Validate Priority */ |
136 | for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { | 137 | for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { |
137 | if (ets->prio_tc[i] >= MLX5E_MAX_PRIORITY) | 138 | if (ets->prio_tc[i] >= MLX5E_MAX_PRIORITY) { |
139 | netdev_err(netdev, | ||
140 | "Failed to validate ETS: priority value greater than max(%d)\n", | ||
141 | MLX5E_MAX_PRIORITY); | ||
138 | return -EINVAL; | 142 | return -EINVAL; |
143 | } | ||
139 | } | 144 | } |
140 | 145 | ||
141 | /* Validate Bandwidth Sum */ | 146 | /* Validate Bandwidth Sum */ |
142 | for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { | 147 | for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { |
143 | if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) { | 148 | if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) { |
144 | if (!ets->tc_tx_bw[i]) | 149 | if (!ets->tc_tx_bw[i]) { |
150 | netdev_err(netdev, | ||
151 | "Failed to validate ETS: BW 0 is illegal\n"); | ||
145 | return -EINVAL; | 152 | return -EINVAL; |
153 | } | ||
146 | 154 | ||
147 | bw_sum += ets->tc_tx_bw[i]; | 155 | bw_sum += ets->tc_tx_bw[i]; |
148 | } | 156 | } |
149 | } | 157 | } |
150 | 158 | ||
151 | if (bw_sum != 0 && bw_sum != 100) | 159 | if (bw_sum != 0 && bw_sum != 100) { |
160 | netdev_err(netdev, | ||
161 | "Failed to validate ETS: BW sum is illegal\n"); | ||
152 | return -EINVAL; | 162 | return -EINVAL; |
163 | } | ||
153 | return 0; | 164 | return 0; |
154 | } | 165 | } |
155 | 166 | ||
@@ -159,7 +170,7 @@ static int mlx5e_dcbnl_ieee_setets(struct net_device *netdev, | |||
159 | struct mlx5e_priv *priv = netdev_priv(netdev); | 170 | struct mlx5e_priv *priv = netdev_priv(netdev); |
160 | int err; | 171 | int err; |
161 | 172 | ||
162 | err = mlx5e_dbcnl_validate_ets(ets); | 173 | err = mlx5e_dbcnl_validate_ets(netdev, ets); |
163 | if (err) | 174 | if (err) |
164 | return err; | 175 | return err; |
165 | 176 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index 4a3757e60441..7a346bb2ed00 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | |||
@@ -331,7 +331,7 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev, | |||
331 | if (mlx5e_query_global_pause_combined(priv)) { | 331 | if (mlx5e_query_global_pause_combined(priv)) { |
332 | for (i = 0; i < NUM_PPORT_PER_PRIO_PFC_COUNTERS; i++) { | 332 | for (i = 0; i < NUM_PPORT_PER_PRIO_PFC_COUNTERS; i++) { |
333 | data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[0], | 333 | data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[0], |
334 | pport_per_prio_pfc_stats_desc, 0); | 334 | pport_per_prio_pfc_stats_desc, i); |
335 | } | 335 | } |
336 | } | 336 | } |
337 | 337 | ||
@@ -352,15 +352,61 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev, | |||
352 | sq_stats_desc, j); | 352 | sq_stats_desc, j); |
353 | } | 353 | } |
354 | 354 | ||
355 | static u32 mlx5e_rx_wqes_to_packets(struct mlx5e_priv *priv, int rq_wq_type, | ||
356 | int num_wqe) | ||
357 | { | ||
358 | int packets_per_wqe; | ||
359 | int stride_size; | ||
360 | int num_strides; | ||
361 | int wqe_size; | ||
362 | |||
363 | if (rq_wq_type != MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) | ||
364 | return num_wqe; | ||
365 | |||
366 | stride_size = 1 << priv->params.mpwqe_log_stride_sz; | ||
367 | num_strides = 1 << priv->params.mpwqe_log_num_strides; | ||
368 | wqe_size = stride_size * num_strides; | ||
369 | |||
370 | packets_per_wqe = wqe_size / | ||
371 | ALIGN(ETH_DATA_LEN, stride_size); | ||
372 | return (1 << (order_base_2(num_wqe * packets_per_wqe) - 1)); | ||
373 | } | ||
374 | |||
375 | static u32 mlx5e_packets_to_rx_wqes(struct mlx5e_priv *priv, int rq_wq_type, | ||
376 | int num_packets) | ||
377 | { | ||
378 | int packets_per_wqe; | ||
379 | int stride_size; | ||
380 | int num_strides; | ||
381 | int wqe_size; | ||
382 | int num_wqes; | ||
383 | |||
384 | if (rq_wq_type != MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) | ||
385 | return num_packets; | ||
386 | |||
387 | stride_size = 1 << priv->params.mpwqe_log_stride_sz; | ||
388 | num_strides = 1 << priv->params.mpwqe_log_num_strides; | ||
389 | wqe_size = stride_size * num_strides; | ||
390 | |||
391 | num_packets = (1 << order_base_2(num_packets)); | ||
392 | |||
393 | packets_per_wqe = wqe_size / | ||
394 | ALIGN(ETH_DATA_LEN, stride_size); | ||
395 | num_wqes = DIV_ROUND_UP(num_packets, packets_per_wqe); | ||
396 | return 1 << (order_base_2(num_wqes)); | ||
397 | } | ||
398 | |||
355 | static void mlx5e_get_ringparam(struct net_device *dev, | 399 | static void mlx5e_get_ringparam(struct net_device *dev, |
356 | struct ethtool_ringparam *param) | 400 | struct ethtool_ringparam *param) |
357 | { | 401 | { |
358 | struct mlx5e_priv *priv = netdev_priv(dev); | 402 | struct mlx5e_priv *priv = netdev_priv(dev); |
359 | int rq_wq_type = priv->params.rq_wq_type; | 403 | int rq_wq_type = priv->params.rq_wq_type; |
360 | 404 | ||
361 | param->rx_max_pending = 1 << mlx5_max_log_rq_size(rq_wq_type); | 405 | param->rx_max_pending = mlx5e_rx_wqes_to_packets(priv, rq_wq_type, |
406 | 1 << mlx5_max_log_rq_size(rq_wq_type)); | ||
362 | param->tx_max_pending = 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE; | 407 | param->tx_max_pending = 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE; |
363 | param->rx_pending = 1 << priv->params.log_rq_size; | 408 | param->rx_pending = mlx5e_rx_wqes_to_packets(priv, rq_wq_type, |
409 | 1 << priv->params.log_rq_size); | ||
364 | param->tx_pending = 1 << priv->params.log_sq_size; | 410 | param->tx_pending = 1 << priv->params.log_sq_size; |
365 | } | 411 | } |
366 | 412 | ||
@@ -370,9 +416,13 @@ static int mlx5e_set_ringparam(struct net_device *dev, | |||
370 | struct mlx5e_priv *priv = netdev_priv(dev); | 416 | struct mlx5e_priv *priv = netdev_priv(dev); |
371 | bool was_opened; | 417 | bool was_opened; |
372 | int rq_wq_type = priv->params.rq_wq_type; | 418 | int rq_wq_type = priv->params.rq_wq_type; |
419 | u32 rx_pending_wqes; | ||
420 | u32 min_rq_size; | ||
421 | u32 max_rq_size; | ||
373 | u16 min_rx_wqes; | 422 | u16 min_rx_wqes; |
374 | u8 log_rq_size; | 423 | u8 log_rq_size; |
375 | u8 log_sq_size; | 424 | u8 log_sq_size; |
425 | u32 num_mtts; | ||
376 | int err = 0; | 426 | int err = 0; |
377 | 427 | ||
378 | if (param->rx_jumbo_pending) { | 428 | if (param->rx_jumbo_pending) { |
@@ -385,18 +435,36 @@ static int mlx5e_set_ringparam(struct net_device *dev, | |||
385 | __func__); | 435 | __func__); |
386 | return -EINVAL; | 436 | return -EINVAL; |
387 | } | 437 | } |
388 | if (param->rx_pending < (1 << mlx5_min_log_rq_size(rq_wq_type))) { | 438 | |
439 | min_rq_size = mlx5e_rx_wqes_to_packets(priv, rq_wq_type, | ||
440 | 1 << mlx5_min_log_rq_size(rq_wq_type)); | ||
441 | max_rq_size = mlx5e_rx_wqes_to_packets(priv, rq_wq_type, | ||
442 | 1 << mlx5_max_log_rq_size(rq_wq_type)); | ||
443 | rx_pending_wqes = mlx5e_packets_to_rx_wqes(priv, rq_wq_type, | ||
444 | param->rx_pending); | ||
445 | |||
446 | if (param->rx_pending < min_rq_size) { | ||
389 | netdev_info(dev, "%s: rx_pending (%d) < min (%d)\n", | 447 | netdev_info(dev, "%s: rx_pending (%d) < min (%d)\n", |
390 | __func__, param->rx_pending, | 448 | __func__, param->rx_pending, |
391 | 1 << mlx5_min_log_rq_size(rq_wq_type)); | 449 | min_rq_size); |
392 | return -EINVAL; | 450 | return -EINVAL; |
393 | } | 451 | } |
394 | if (param->rx_pending > (1 << mlx5_max_log_rq_size(rq_wq_type))) { | 452 | if (param->rx_pending > max_rq_size) { |
395 | netdev_info(dev, "%s: rx_pending (%d) > max (%d)\n", | 453 | netdev_info(dev, "%s: rx_pending (%d) > max (%d)\n", |
396 | __func__, param->rx_pending, | 454 | __func__, param->rx_pending, |
397 | 1 << mlx5_max_log_rq_size(rq_wq_type)); | 455 | max_rq_size); |
398 | return -EINVAL; | 456 | return -EINVAL; |
399 | } | 457 | } |
458 | |||
459 | num_mtts = MLX5E_REQUIRED_MTTS(priv->params.num_channels, | ||
460 | rx_pending_wqes); | ||
461 | if (priv->params.rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ && | ||
462 | !MLX5E_VALID_NUM_MTTS(num_mtts)) { | ||
463 | netdev_info(dev, "%s: rx_pending (%d) request can't be satisfied, try to reduce.\n", | ||
464 | __func__, param->rx_pending); | ||
465 | return -EINVAL; | ||
466 | } | ||
467 | |||
400 | if (param->tx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) { | 468 | if (param->tx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) { |
401 | netdev_info(dev, "%s: tx_pending (%d) < min (%d)\n", | 469 | netdev_info(dev, "%s: tx_pending (%d) < min (%d)\n", |
402 | __func__, param->tx_pending, | 470 | __func__, param->tx_pending, |
@@ -410,9 +478,9 @@ static int mlx5e_set_ringparam(struct net_device *dev, | |||
410 | return -EINVAL; | 478 | return -EINVAL; |
411 | } | 479 | } |
412 | 480 | ||
413 | log_rq_size = order_base_2(param->rx_pending); | 481 | log_rq_size = order_base_2(rx_pending_wqes); |
414 | log_sq_size = order_base_2(param->tx_pending); | 482 | log_sq_size = order_base_2(param->tx_pending); |
415 | min_rx_wqes = mlx5_min_rx_wqes(rq_wq_type, param->rx_pending); | 483 | min_rx_wqes = mlx5_min_rx_wqes(rq_wq_type, rx_pending_wqes); |
416 | 484 | ||
417 | if (log_rq_size == priv->params.log_rq_size && | 485 | if (log_rq_size == priv->params.log_rq_size && |
418 | log_sq_size == priv->params.log_sq_size && | 486 | log_sq_size == priv->params.log_sq_size && |
@@ -454,6 +522,7 @@ static int mlx5e_set_channels(struct net_device *dev, | |||
454 | unsigned int count = ch->combined_count; | 522 | unsigned int count = ch->combined_count; |
455 | bool arfs_enabled; | 523 | bool arfs_enabled; |
456 | bool was_opened; | 524 | bool was_opened; |
525 | u32 num_mtts; | ||
457 | int err = 0; | 526 | int err = 0; |
458 | 527 | ||
459 | if (!count) { | 528 | if (!count) { |
@@ -472,6 +541,14 @@ static int mlx5e_set_channels(struct net_device *dev, | |||
472 | return -EINVAL; | 541 | return -EINVAL; |
473 | } | 542 | } |
474 | 543 | ||
544 | num_mtts = MLX5E_REQUIRED_MTTS(count, BIT(priv->params.log_rq_size)); | ||
545 | if (priv->params.rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ && | ||
546 | !MLX5E_VALID_NUM_MTTS(num_mtts)) { | ||
547 | netdev_info(dev, "%s: rx count (%d) request can't be satisfied, try to reduce.\n", | ||
548 | __func__, count); | ||
549 | return -EINVAL; | ||
550 | } | ||
551 | |||
475 | if (priv->params.num_channels == count) | 552 | if (priv->params.num_channels == count) |
476 | return 0; | 553 | return 0; |
477 | 554 | ||
@@ -582,9 +659,10 @@ out: | |||
582 | static void ptys2ethtool_supported_link(unsigned long *supported_modes, | 659 | static void ptys2ethtool_supported_link(unsigned long *supported_modes, |
583 | u32 eth_proto_cap) | 660 | u32 eth_proto_cap) |
584 | { | 661 | { |
662 | unsigned long proto_cap = eth_proto_cap; | ||
585 | int proto; | 663 | int proto; |
586 | 664 | ||
587 | for_each_set_bit(proto, (unsigned long *)ð_proto_cap, MLX5E_LINK_MODES_NUMBER) | 665 | for_each_set_bit(proto, &proto_cap, MLX5E_LINK_MODES_NUMBER) |
588 | bitmap_or(supported_modes, supported_modes, | 666 | bitmap_or(supported_modes, supported_modes, |
589 | ptys2ethtool_table[proto].supported, | 667 | ptys2ethtool_table[proto].supported, |
590 | __ETHTOOL_LINK_MODE_MASK_NBITS); | 668 | __ETHTOOL_LINK_MODE_MASK_NBITS); |
@@ -593,9 +671,10 @@ static void ptys2ethtool_supported_link(unsigned long *supported_modes, | |||
593 | static void ptys2ethtool_adver_link(unsigned long *advertising_modes, | 671 | static void ptys2ethtool_adver_link(unsigned long *advertising_modes, |
594 | u32 eth_proto_cap) | 672 | u32 eth_proto_cap) |
595 | { | 673 | { |
674 | unsigned long proto_cap = eth_proto_cap; | ||
596 | int proto; | 675 | int proto; |
597 | 676 | ||
598 | for_each_set_bit(proto, (unsigned long *)ð_proto_cap, MLX5E_LINK_MODES_NUMBER) | 677 | for_each_set_bit(proto, &proto_cap, MLX5E_LINK_MODES_NUMBER) |
599 | bitmap_or(advertising_modes, advertising_modes, | 678 | bitmap_or(advertising_modes, advertising_modes, |
600 | ptys2ethtool_table[proto].advertised, | 679 | ptys2ethtool_table[proto].advertised, |
601 | __ETHTOOL_LINK_MODE_MASK_NBITS); | 680 | __ETHTOOL_LINK_MODE_MASK_NBITS); |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 870bea37c57c..2459c7f3db8d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c | |||
@@ -39,13 +39,6 @@ | |||
39 | #include "eswitch.h" | 39 | #include "eswitch.h" |
40 | #include "vxlan.h" | 40 | #include "vxlan.h" |
41 | 41 | ||
42 | enum { | ||
43 | MLX5_EN_QP_FLUSH_TIMEOUT_MS = 5000, | ||
44 | MLX5_EN_QP_FLUSH_MSLEEP_QUANT = 20, | ||
45 | MLX5_EN_QP_FLUSH_MAX_ITER = MLX5_EN_QP_FLUSH_TIMEOUT_MS / | ||
46 | MLX5_EN_QP_FLUSH_MSLEEP_QUANT, | ||
47 | }; | ||
48 | |||
49 | struct mlx5e_rq_param { | 42 | struct mlx5e_rq_param { |
50 | u32 rqc[MLX5_ST_SZ_DW(rqc)]; | 43 | u32 rqc[MLX5_ST_SZ_DW(rqc)]; |
51 | struct mlx5_wq_param wq; | 44 | struct mlx5_wq_param wq; |
@@ -162,6 +155,7 @@ static void mlx5e_update_sw_counters(struct mlx5e_priv *priv) | |||
162 | s->tx_queue_stopped += sq_stats->stopped; | 155 | s->tx_queue_stopped += sq_stats->stopped; |
163 | s->tx_queue_wake += sq_stats->wake; | 156 | s->tx_queue_wake += sq_stats->wake; |
164 | s->tx_queue_dropped += sq_stats->dropped; | 157 | s->tx_queue_dropped += sq_stats->dropped; |
158 | s->tx_xmit_more += sq_stats->xmit_more; | ||
165 | s->tx_csum_partial_inner += sq_stats->csum_partial_inner; | 159 | s->tx_csum_partial_inner += sq_stats->csum_partial_inner; |
166 | tx_offload_none += sq_stats->csum_none; | 160 | tx_offload_none += sq_stats->csum_none; |
167 | } | 161 | } |
@@ -340,6 +334,9 @@ static int mlx5e_create_rq(struct mlx5e_channel *c, | |||
340 | rq->alloc_wqe = mlx5e_alloc_rx_mpwqe; | 334 | rq->alloc_wqe = mlx5e_alloc_rx_mpwqe; |
341 | rq->dealloc_wqe = mlx5e_dealloc_rx_mpwqe; | 335 | rq->dealloc_wqe = mlx5e_dealloc_rx_mpwqe; |
342 | 336 | ||
337 | rq->mpwqe_mtt_offset = c->ix * | ||
338 | MLX5E_REQUIRED_MTTS(1, BIT(priv->params.log_rq_size)); | ||
339 | |||
343 | rq->mpwqe_stride_sz = BIT(priv->params.mpwqe_log_stride_sz); | 340 | rq->mpwqe_stride_sz = BIT(priv->params.mpwqe_log_stride_sz); |
344 | rq->mpwqe_num_strides = BIT(priv->params.mpwqe_log_num_strides); | 341 | rq->mpwqe_num_strides = BIT(priv->params.mpwqe_log_num_strides); |
345 | rq->wqe_sz = rq->mpwqe_stride_sz * rq->mpwqe_num_strides; | 342 | rq->wqe_sz = rq->mpwqe_stride_sz * rq->mpwqe_num_strides; |
@@ -428,7 +425,6 @@ static int mlx5e_enable_rq(struct mlx5e_rq *rq, struct mlx5e_rq_param *param) | |||
428 | 425 | ||
429 | MLX5_SET(rqc, rqc, cqn, rq->cq.mcq.cqn); | 426 | MLX5_SET(rqc, rqc, cqn, rq->cq.mcq.cqn); |
430 | MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RST); | 427 | MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RST); |
431 | MLX5_SET(rqc, rqc, flush_in_error_en, 1); | ||
432 | MLX5_SET(rqc, rqc, vsd, priv->params.vlan_strip_disable); | 428 | MLX5_SET(rqc, rqc, vsd, priv->params.vlan_strip_disable); |
433 | MLX5_SET(wq, wq, log_wq_pg_sz, rq->wq_ctrl.buf.page_shift - | 429 | MLX5_SET(wq, wq, log_wq_pg_sz, rq->wq_ctrl.buf.page_shift - |
434 | MLX5_ADAPTER_PAGE_SHIFT); | 430 | MLX5_ADAPTER_PAGE_SHIFT); |
@@ -525,6 +521,27 @@ static int mlx5e_wait_for_min_rx_wqes(struct mlx5e_rq *rq) | |||
525 | return -ETIMEDOUT; | 521 | return -ETIMEDOUT; |
526 | } | 522 | } |
527 | 523 | ||
524 | static void mlx5e_free_rx_descs(struct mlx5e_rq *rq) | ||
525 | { | ||
526 | struct mlx5_wq_ll *wq = &rq->wq; | ||
527 | struct mlx5e_rx_wqe *wqe; | ||
528 | __be16 wqe_ix_be; | ||
529 | u16 wqe_ix; | ||
530 | |||
531 | /* UMR WQE (if in progress) is always at wq->head */ | ||
532 | if (test_bit(MLX5E_RQ_STATE_UMR_WQE_IN_PROGRESS, &rq->state)) | ||
533 | mlx5e_free_rx_fragmented_mpwqe(rq, &rq->wqe_info[wq->head]); | ||
534 | |||
535 | while (!mlx5_wq_ll_is_empty(wq)) { | ||
536 | wqe_ix_be = *wq->tail_next; | ||
537 | wqe_ix = be16_to_cpu(wqe_ix_be); | ||
538 | wqe = mlx5_wq_ll_get_wqe(&rq->wq, wqe_ix); | ||
539 | rq->dealloc_wqe(rq, wqe_ix); | ||
540 | mlx5_wq_ll_pop(&rq->wq, wqe_ix_be, | ||
541 | &wqe->next.next_wqe_index); | ||
542 | } | ||
543 | } | ||
544 | |||
528 | static int mlx5e_open_rq(struct mlx5e_channel *c, | 545 | static int mlx5e_open_rq(struct mlx5e_channel *c, |
529 | struct mlx5e_rq_param *param, | 546 | struct mlx5e_rq_param *param, |
530 | struct mlx5e_rq *rq) | 547 | struct mlx5e_rq *rq) |
@@ -548,8 +565,6 @@ static int mlx5e_open_rq(struct mlx5e_channel *c, | |||
548 | if (param->am_enabled) | 565 | if (param->am_enabled) |
549 | set_bit(MLX5E_RQ_STATE_AM, &c->rq.state); | 566 | set_bit(MLX5E_RQ_STATE_AM, &c->rq.state); |
550 | 567 | ||
551 | set_bit(MLX5E_RQ_STATE_POST_WQES_ENABLE, &rq->state); | ||
552 | |||
553 | sq->ico_wqe_info[pi].opcode = MLX5_OPCODE_NOP; | 568 | sq->ico_wqe_info[pi].opcode = MLX5_OPCODE_NOP; |
554 | sq->ico_wqe_info[pi].num_wqebbs = 1; | 569 | sq->ico_wqe_info[pi].num_wqebbs = 1; |
555 | mlx5e_send_nop(sq, true); /* trigger mlx5e_post_rx_wqes() */ | 570 | mlx5e_send_nop(sq, true); /* trigger mlx5e_post_rx_wqes() */ |
@@ -566,23 +581,8 @@ err_destroy_rq: | |||
566 | 581 | ||
567 | static void mlx5e_close_rq(struct mlx5e_rq *rq) | 582 | static void mlx5e_close_rq(struct mlx5e_rq *rq) |
568 | { | 583 | { |
569 | int tout = 0; | 584 | set_bit(MLX5E_RQ_STATE_FLUSH, &rq->state); |
570 | int err; | ||
571 | |||
572 | clear_bit(MLX5E_RQ_STATE_POST_WQES_ENABLE, &rq->state); | ||
573 | napi_synchronize(&rq->channel->napi); /* prevent mlx5e_post_rx_wqes */ | 585 | napi_synchronize(&rq->channel->napi); /* prevent mlx5e_post_rx_wqes */ |
574 | |||
575 | err = mlx5e_modify_rq_state(rq, MLX5_RQC_STATE_RDY, MLX5_RQC_STATE_ERR); | ||
576 | while (!mlx5_wq_ll_is_empty(&rq->wq) && !err && | ||
577 | tout++ < MLX5_EN_QP_FLUSH_MAX_ITER) | ||
578 | msleep(MLX5_EN_QP_FLUSH_MSLEEP_QUANT); | ||
579 | |||
580 | if (err || tout == MLX5_EN_QP_FLUSH_MAX_ITER) | ||
581 | set_bit(MLX5E_RQ_STATE_FLUSH_TIMEOUT, &rq->state); | ||
582 | |||
583 | /* avoid destroying rq before mlx5e_poll_rx_cq() is done with it */ | ||
584 | napi_synchronize(&rq->channel->napi); | ||
585 | |||
586 | cancel_work_sync(&rq->am.work); | 586 | cancel_work_sync(&rq->am.work); |
587 | 587 | ||
588 | mlx5e_disable_rq(rq); | 588 | mlx5e_disable_rq(rq); |
@@ -821,7 +821,6 @@ static int mlx5e_open_sq(struct mlx5e_channel *c, | |||
821 | goto err_disable_sq; | 821 | goto err_disable_sq; |
822 | 822 | ||
823 | if (sq->txq) { | 823 | if (sq->txq) { |
824 | set_bit(MLX5E_SQ_STATE_WAKE_TXQ_ENABLE, &sq->state); | ||
825 | netdev_tx_reset_queue(sq->txq); | 824 | netdev_tx_reset_queue(sq->txq); |
826 | netif_tx_start_queue(sq->txq); | 825 | netif_tx_start_queue(sq->txq); |
827 | } | 826 | } |
@@ -845,38 +844,20 @@ static inline void netif_tx_disable_queue(struct netdev_queue *txq) | |||
845 | 844 | ||
846 | static void mlx5e_close_sq(struct mlx5e_sq *sq) | 845 | static void mlx5e_close_sq(struct mlx5e_sq *sq) |
847 | { | 846 | { |
848 | int tout = 0; | 847 | set_bit(MLX5E_SQ_STATE_FLUSH, &sq->state); |
849 | int err; | 848 | /* prevent netif_tx_wake_queue */ |
849 | napi_synchronize(&sq->channel->napi); | ||
850 | 850 | ||
851 | if (sq->txq) { | 851 | if (sq->txq) { |
852 | clear_bit(MLX5E_SQ_STATE_WAKE_TXQ_ENABLE, &sq->state); | ||
853 | /* prevent netif_tx_wake_queue */ | ||
854 | napi_synchronize(&sq->channel->napi); | ||
855 | netif_tx_disable_queue(sq->txq); | 852 | netif_tx_disable_queue(sq->txq); |
856 | 853 | ||
857 | /* ensure hw is notified of all pending wqes */ | 854 | /* last doorbell out, godspeed .. */ |
858 | if (mlx5e_sq_has_room_for(sq, 1)) | 855 | if (mlx5e_sq_has_room_for(sq, 1)) |
859 | mlx5e_send_nop(sq, true); | 856 | mlx5e_send_nop(sq, true); |
860 | |||
861 | err = mlx5e_modify_sq(sq, MLX5_SQC_STATE_RDY, | ||
862 | MLX5_SQC_STATE_ERR, false, 0); | ||
863 | if (err) | ||
864 | set_bit(MLX5E_SQ_STATE_TX_TIMEOUT, &sq->state); | ||
865 | } | ||
866 | |||
867 | /* wait till sq is empty, unless a TX timeout occurred on this SQ */ | ||
868 | while (sq->cc != sq->pc && | ||
869 | !test_bit(MLX5E_SQ_STATE_TX_TIMEOUT, &sq->state)) { | ||
870 | msleep(MLX5_EN_QP_FLUSH_MSLEEP_QUANT); | ||
871 | if (tout++ > MLX5_EN_QP_FLUSH_MAX_ITER) | ||
872 | set_bit(MLX5E_SQ_STATE_TX_TIMEOUT, &sq->state); | ||
873 | } | 857 | } |
874 | 858 | ||
875 | /* avoid destroying sq before mlx5e_poll_tx_cq() is done with it */ | ||
876 | napi_synchronize(&sq->channel->napi); | ||
877 | |||
878 | mlx5e_free_tx_descs(sq); | ||
879 | mlx5e_disable_sq(sq); | 859 | mlx5e_disable_sq(sq); |
860 | mlx5e_free_tx_descs(sq); | ||
880 | mlx5e_destroy_sq(sq); | 861 | mlx5e_destroy_sq(sq); |
881 | } | 862 | } |
882 | 863 | ||
@@ -1826,10 +1807,6 @@ int mlx5e_open_locked(struct net_device *netdev) | |||
1826 | netif_set_real_num_tx_queues(netdev, num_txqs); | 1807 | netif_set_real_num_tx_queues(netdev, num_txqs); |
1827 | netif_set_real_num_rx_queues(netdev, priv->params.num_channels); | 1808 | netif_set_real_num_rx_queues(netdev, priv->params.num_channels); |
1828 | 1809 | ||
1829 | err = mlx5e_set_dev_port_mtu(netdev); | ||
1830 | if (err) | ||
1831 | goto err_clear_state_opened_flag; | ||
1832 | |||
1833 | err = mlx5e_open_channels(priv); | 1810 | err = mlx5e_open_channels(priv); |
1834 | if (err) { | 1811 | if (err) { |
1835 | netdev_err(netdev, "%s: mlx5e_open_channels failed, %d\n", | 1812 | netdev_err(netdev, "%s: mlx5e_open_channels failed, %d\n", |
@@ -2573,6 +2550,7 @@ static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu) | |||
2573 | u16 max_mtu; | 2550 | u16 max_mtu; |
2574 | u16 min_mtu; | 2551 | u16 min_mtu; |
2575 | int err = 0; | 2552 | int err = 0; |
2553 | bool reset; | ||
2576 | 2554 | ||
2577 | mlx5_query_port_max_mtu(mdev, &max_mtu, 1); | 2555 | mlx5_query_port_max_mtu(mdev, &max_mtu, 1); |
2578 | 2556 | ||
@@ -2588,13 +2566,18 @@ static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu) | |||
2588 | 2566 | ||
2589 | mutex_lock(&priv->state_lock); | 2567 | mutex_lock(&priv->state_lock); |
2590 | 2568 | ||
2569 | reset = !priv->params.lro_en && | ||
2570 | (priv->params.rq_wq_type != | ||
2571 | MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ); | ||
2572 | |||
2591 | was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state); | 2573 | was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state); |
2592 | if (was_opened) | 2574 | if (was_opened && reset) |
2593 | mlx5e_close_locked(netdev); | 2575 | mlx5e_close_locked(netdev); |
2594 | 2576 | ||
2595 | netdev->mtu = new_mtu; | 2577 | netdev->mtu = new_mtu; |
2578 | mlx5e_set_dev_port_mtu(netdev); | ||
2596 | 2579 | ||
2597 | if (was_opened) | 2580 | if (was_opened && reset) |
2598 | err = mlx5e_open_locked(netdev); | 2581 | err = mlx5e_open_locked(netdev); |
2599 | 2582 | ||
2600 | mutex_unlock(&priv->state_lock); | 2583 | mutex_unlock(&priv->state_lock); |
@@ -2794,7 +2777,7 @@ static void mlx5e_tx_timeout(struct net_device *dev) | |||
2794 | if (!netif_xmit_stopped(netdev_get_tx_queue(dev, i))) | 2777 | if (!netif_xmit_stopped(netdev_get_tx_queue(dev, i))) |
2795 | continue; | 2778 | continue; |
2796 | sched_work = true; | 2779 | sched_work = true; |
2797 | set_bit(MLX5E_SQ_STATE_TX_TIMEOUT, &sq->state); | 2780 | set_bit(MLX5E_SQ_STATE_FLUSH, &sq->state); |
2798 | netdev_err(dev, "TX timeout on queue: %d, SQ: 0x%x, CQ: 0x%x, SQ Cons: 0x%x SQ Prod: 0x%x\n", | 2781 | netdev_err(dev, "TX timeout on queue: %d, SQ: 0x%x, CQ: 0x%x, SQ Cons: 0x%x SQ Prod: 0x%x\n", |
2799 | i, sq->sqn, sq->cq.mcq.cqn, sq->cc, sq->pc); | 2782 | i, sq->sqn, sq->cq.mcq.cqn, sq->cc, sq->pc); |
2800 | } | 2783 | } |
@@ -3231,8 +3214,8 @@ static int mlx5e_create_umr_mkey(struct mlx5e_priv *priv) | |||
3231 | struct mlx5_create_mkey_mbox_in *in; | 3214 | struct mlx5_create_mkey_mbox_in *in; |
3232 | struct mlx5_mkey_seg *mkc; | 3215 | struct mlx5_mkey_seg *mkc; |
3233 | int inlen = sizeof(*in); | 3216 | int inlen = sizeof(*in); |
3234 | u64 npages = | 3217 | u64 npages = MLX5E_REQUIRED_MTTS(priv->profile->max_nch(mdev), |
3235 | priv->profile->max_nch(mdev) * MLX5_CHANNEL_MAX_NUM_MTTS; | 3218 | BIT(MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW)); |
3236 | int err; | 3219 | int err; |
3237 | 3220 | ||
3238 | in = mlx5_vzalloc(inlen); | 3221 | in = mlx5_vzalloc(inlen); |
@@ -3246,10 +3229,12 @@ static int mlx5e_create_umr_mkey(struct mlx5e_priv *priv) | |||
3246 | MLX5_PERM_LOCAL_WRITE | | 3229 | MLX5_PERM_LOCAL_WRITE | |
3247 | MLX5_ACCESS_MODE_MTT; | 3230 | MLX5_ACCESS_MODE_MTT; |
3248 | 3231 | ||
3232 | npages = min_t(u32, ALIGN(U16_MAX, 4) * 2, npages); | ||
3233 | |||
3249 | mkc->qpn_mkey7_0 = cpu_to_be32(0xffffff << 8); | 3234 | mkc->qpn_mkey7_0 = cpu_to_be32(0xffffff << 8); |
3250 | mkc->flags_pd = cpu_to_be32(mdev->mlx5e_res.pdn); | 3235 | mkc->flags_pd = cpu_to_be32(mdev->mlx5e_res.pdn); |
3251 | mkc->len = cpu_to_be64(npages << PAGE_SHIFT); | 3236 | mkc->len = cpu_to_be64(npages << PAGE_SHIFT); |
3252 | mkc->xlt_oct_size = cpu_to_be32(mlx5e_get_mtt_octw(npages)); | 3237 | mkc->xlt_oct_size = cpu_to_be32(MLX5_MTT_OCTW(npages)); |
3253 | mkc->log2_page_size = PAGE_SHIFT; | 3238 | mkc->log2_page_size = PAGE_SHIFT; |
3254 | 3239 | ||
3255 | err = mlx5_core_create_mkey(mdev, &priv->umr_mkey, in, inlen, NULL, | 3240 | err = mlx5_core_create_mkey(mdev, &priv->umr_mkey, in, inlen, NULL, |
@@ -3385,6 +3370,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv) | |||
3385 | queue_work(priv->wq, &priv->set_rx_mode_work); | 3370 | queue_work(priv->wq, &priv->set_rx_mode_work); |
3386 | 3371 | ||
3387 | if (MLX5_CAP_GEN(mdev, vport_group_manager)) { | 3372 | if (MLX5_CAP_GEN(mdev, vport_group_manager)) { |
3373 | mlx5_query_nic_vport_mac_address(mdev, 0, rep.hw_id); | ||
3388 | rep.load = mlx5e_nic_rep_load; | 3374 | rep.load = mlx5e_nic_rep_load; |
3389 | rep.unload = mlx5e_nic_rep_unload; | 3375 | rep.unload = mlx5e_nic_rep_unload; |
3390 | rep.vport = 0; | 3376 | rep.vport = 0; |
@@ -3463,6 +3449,8 @@ void *mlx5e_create_netdev(struct mlx5_core_dev *mdev, | |||
3463 | 3449 | ||
3464 | mlx5e_init_l2_addr(priv); | 3450 | mlx5e_init_l2_addr(priv); |
3465 | 3451 | ||
3452 | mlx5e_set_dev_port_mtu(netdev); | ||
3453 | |||
3466 | err = register_netdev(netdev); | 3454 | err = register_netdev(netdev); |
3467 | if (err) { | 3455 | if (err) { |
3468 | mlx5_core_err(mdev, "register_netdev failed, %d\n", err); | 3456 | mlx5_core_err(mdev, "register_netdev failed, %d\n", err); |
@@ -3501,16 +3489,20 @@ static void mlx5e_register_vport_rep(struct mlx5_core_dev *mdev) | |||
3501 | struct mlx5_eswitch *esw = mdev->priv.eswitch; | 3489 | struct mlx5_eswitch *esw = mdev->priv.eswitch; |
3502 | int total_vfs = MLX5_TOTAL_VPORTS(mdev); | 3490 | int total_vfs = MLX5_TOTAL_VPORTS(mdev); |
3503 | int vport; | 3491 | int vport; |
3492 | u8 mac[ETH_ALEN]; | ||
3504 | 3493 | ||
3505 | if (!MLX5_CAP_GEN(mdev, vport_group_manager)) | 3494 | if (!MLX5_CAP_GEN(mdev, vport_group_manager)) |
3506 | return; | 3495 | return; |
3507 | 3496 | ||
3497 | mlx5_query_nic_vport_mac_address(mdev, 0, mac); | ||
3498 | |||
3508 | for (vport = 1; vport < total_vfs; vport++) { | 3499 | for (vport = 1; vport < total_vfs; vport++) { |
3509 | struct mlx5_eswitch_rep rep; | 3500 | struct mlx5_eswitch_rep rep; |
3510 | 3501 | ||
3511 | rep.load = mlx5e_vport_rep_load; | 3502 | rep.load = mlx5e_vport_rep_load; |
3512 | rep.unload = mlx5e_vport_rep_unload; | 3503 | rep.unload = mlx5e_vport_rep_unload; |
3513 | rep.vport = vport; | 3504 | rep.vport = vport; |
3505 | ether_addr_copy(rep.hw_id, mac); | ||
3514 | mlx5_eswitch_register_vport_rep(esw, &rep); | 3506 | mlx5_eswitch_register_vport_rep(esw, &rep); |
3515 | } | 3507 | } |
3516 | } | 3508 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 1c7d8b8314bf..134de4a11f1d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | |||
@@ -135,17 +135,16 @@ static const struct ethtool_ops mlx5e_rep_ethtool_ops = { | |||
135 | int mlx5e_attr_get(struct net_device *dev, struct switchdev_attr *attr) | 135 | int mlx5e_attr_get(struct net_device *dev, struct switchdev_attr *attr) |
136 | { | 136 | { |
137 | struct mlx5e_priv *priv = netdev_priv(dev); | 137 | struct mlx5e_priv *priv = netdev_priv(dev); |
138 | struct mlx5_eswitch_rep *rep = priv->ppriv; | ||
138 | struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; | 139 | struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; |
139 | u8 mac[ETH_ALEN]; | ||
140 | 140 | ||
141 | if (esw->mode == SRIOV_NONE) | 141 | if (esw->mode == SRIOV_NONE) |
142 | return -EOPNOTSUPP; | 142 | return -EOPNOTSUPP; |
143 | 143 | ||
144 | switch (attr->id) { | 144 | switch (attr->id) { |
145 | case SWITCHDEV_ATTR_ID_PORT_PARENT_ID: | 145 | case SWITCHDEV_ATTR_ID_PORT_PARENT_ID: |
146 | mlx5_query_nic_vport_mac_address(priv->mdev, 0, mac); | ||
147 | attr->u.ppid.id_len = ETH_ALEN; | 146 | attr->u.ppid.id_len = ETH_ALEN; |
148 | memcpy(&attr->u.ppid.id, &mac, ETH_ALEN); | 147 | ether_addr_copy(attr->u.ppid.id, rep->hw_id); |
149 | break; | 148 | break; |
150 | default: | 149 | default: |
151 | return -EOPNOTSUPP; | 150 | return -EOPNOTSUPP; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c index 9f2a16a507e0..e7c969df3dad 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | |||
@@ -324,9 +324,9 @@ mlx5e_copy_skb_header_fragmented_mpwqe(struct device *pdev, | |||
324 | } | 324 | } |
325 | } | 325 | } |
326 | 326 | ||
327 | static u16 mlx5e_get_wqe_mtt_offset(u16 rq_ix, u16 wqe_ix) | 327 | static u32 mlx5e_get_wqe_mtt_offset(struct mlx5e_rq *rq, u16 wqe_ix) |
328 | { | 328 | { |
329 | return rq_ix * MLX5_CHANNEL_MAX_NUM_MTTS + | 329 | return rq->mpwqe_mtt_offset + |
330 | wqe_ix * ALIGN(MLX5_MPWRQ_PAGES_PER_WQE, 8); | 330 | wqe_ix * ALIGN(MLX5_MPWRQ_PAGES_PER_WQE, 8); |
331 | } | 331 | } |
332 | 332 | ||
@@ -340,7 +340,7 @@ static void mlx5e_build_umr_wqe(struct mlx5e_rq *rq, | |||
340 | struct mlx5_wqe_data_seg *dseg = &wqe->data; | 340 | struct mlx5_wqe_data_seg *dseg = &wqe->data; |
341 | struct mlx5e_mpw_info *wi = &rq->wqe_info[ix]; | 341 | struct mlx5e_mpw_info *wi = &rq->wqe_info[ix]; |
342 | u8 ds_cnt = DIV_ROUND_UP(sizeof(*wqe), MLX5_SEND_WQE_DS); | 342 | u8 ds_cnt = DIV_ROUND_UP(sizeof(*wqe), MLX5_SEND_WQE_DS); |
343 | u16 umr_wqe_mtt_offset = mlx5e_get_wqe_mtt_offset(rq->ix, ix); | 343 | u32 umr_wqe_mtt_offset = mlx5e_get_wqe_mtt_offset(rq, ix); |
344 | 344 | ||
345 | memset(wqe, 0, sizeof(*wqe)); | 345 | memset(wqe, 0, sizeof(*wqe)); |
346 | cseg->opmod_idx_opcode = | 346 | cseg->opmod_idx_opcode = |
@@ -353,9 +353,9 @@ static void mlx5e_build_umr_wqe(struct mlx5e_rq *rq, | |||
353 | 353 | ||
354 | ucseg->flags = MLX5_UMR_TRANSLATION_OFFSET_EN; | 354 | ucseg->flags = MLX5_UMR_TRANSLATION_OFFSET_EN; |
355 | ucseg->klm_octowords = | 355 | ucseg->klm_octowords = |
356 | cpu_to_be16(mlx5e_get_mtt_octw(MLX5_MPWRQ_PAGES_PER_WQE)); | 356 | cpu_to_be16(MLX5_MTT_OCTW(MLX5_MPWRQ_PAGES_PER_WQE)); |
357 | ucseg->bsf_octowords = | 357 | ucseg->bsf_octowords = |
358 | cpu_to_be16(mlx5e_get_mtt_octw(umr_wqe_mtt_offset)); | 358 | cpu_to_be16(MLX5_MTT_OCTW(umr_wqe_mtt_offset)); |
359 | ucseg->mkey_mask = cpu_to_be64(MLX5_MKEY_MASK_FREE); | 359 | ucseg->mkey_mask = cpu_to_be64(MLX5_MKEY_MASK_FREE); |
360 | 360 | ||
361 | dseg->lkey = sq->mkey_be; | 361 | dseg->lkey = sq->mkey_be; |
@@ -423,7 +423,7 @@ static int mlx5e_alloc_rx_fragmented_mpwqe(struct mlx5e_rq *rq, | |||
423 | { | 423 | { |
424 | struct mlx5e_mpw_info *wi = &rq->wqe_info[ix]; | 424 | struct mlx5e_mpw_info *wi = &rq->wqe_info[ix]; |
425 | int mtt_sz = mlx5e_get_wqe_mtt_sz(); | 425 | int mtt_sz = mlx5e_get_wqe_mtt_sz(); |
426 | u32 dma_offset = mlx5e_get_wqe_mtt_offset(rq->ix, ix) << PAGE_SHIFT; | 426 | u64 dma_offset = (u64)mlx5e_get_wqe_mtt_offset(rq, ix) << PAGE_SHIFT; |
427 | int i; | 427 | int i; |
428 | 428 | ||
429 | wi->umr.dma_info = kmalloc(sizeof(*wi->umr.dma_info) * | 429 | wi->umr.dma_info = kmalloc(sizeof(*wi->umr.dma_info) * |
@@ -506,6 +506,12 @@ void mlx5e_post_rx_fragmented_mpwqe(struct mlx5e_rq *rq) | |||
506 | struct mlx5e_rx_wqe *wqe = mlx5_wq_ll_get_wqe(wq, wq->head); | 506 | struct mlx5e_rx_wqe *wqe = mlx5_wq_ll_get_wqe(wq, wq->head); |
507 | 507 | ||
508 | clear_bit(MLX5E_RQ_STATE_UMR_WQE_IN_PROGRESS, &rq->state); | 508 | clear_bit(MLX5E_RQ_STATE_UMR_WQE_IN_PROGRESS, &rq->state); |
509 | |||
510 | if (unlikely(test_bit(MLX5E_RQ_STATE_FLUSH, &rq->state))) { | ||
511 | mlx5e_free_rx_fragmented_mpwqe(rq, &rq->wqe_info[wq->head]); | ||
512 | return; | ||
513 | } | ||
514 | |||
509 | mlx5_wq_ll_push(wq, be16_to_cpu(wqe->next.next_wqe_index)); | 515 | mlx5_wq_ll_push(wq, be16_to_cpu(wqe->next.next_wqe_index)); |
510 | rq->stats.mpwqe_frag++; | 516 | rq->stats.mpwqe_frag++; |
511 | 517 | ||
@@ -595,26 +601,9 @@ void mlx5e_dealloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix) | |||
595 | wi->free_wqe(rq, wi); | 601 | wi->free_wqe(rq, wi); |
596 | } | 602 | } |
597 | 603 | ||
598 | void mlx5e_free_rx_descs(struct mlx5e_rq *rq) | ||
599 | { | ||
600 | struct mlx5_wq_ll *wq = &rq->wq; | ||
601 | struct mlx5e_rx_wqe *wqe; | ||
602 | __be16 wqe_ix_be; | ||
603 | u16 wqe_ix; | ||
604 | |||
605 | while (!mlx5_wq_ll_is_empty(wq)) { | ||
606 | wqe_ix_be = *wq->tail_next; | ||
607 | wqe_ix = be16_to_cpu(wqe_ix_be); | ||
608 | wqe = mlx5_wq_ll_get_wqe(&rq->wq, wqe_ix); | ||
609 | rq->dealloc_wqe(rq, wqe_ix); | ||
610 | mlx5_wq_ll_pop(&rq->wq, wqe_ix_be, | ||
611 | &wqe->next.next_wqe_index); | ||
612 | } | ||
613 | } | ||
614 | |||
615 | #define RQ_CANNOT_POST(rq) \ | 604 | #define RQ_CANNOT_POST(rq) \ |
616 | (!test_bit(MLX5E_RQ_STATE_POST_WQES_ENABLE, &rq->state) || \ | 605 | (test_bit(MLX5E_RQ_STATE_FLUSH, &rq->state) || \ |
617 | test_bit(MLX5E_RQ_STATE_UMR_WQE_IN_PROGRESS, &rq->state)) | 606 | test_bit(MLX5E_RQ_STATE_UMR_WQE_IN_PROGRESS, &rq->state)) |
618 | 607 | ||
619 | bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq) | 608 | bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq) |
620 | { | 609 | { |
@@ -648,24 +637,32 @@ bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq) | |||
648 | static void mlx5e_lro_update_hdr(struct sk_buff *skb, struct mlx5_cqe64 *cqe, | 637 | static void mlx5e_lro_update_hdr(struct sk_buff *skb, struct mlx5_cqe64 *cqe, |
649 | u32 cqe_bcnt) | 638 | u32 cqe_bcnt) |
650 | { | 639 | { |
651 | struct ethhdr *eth = (struct ethhdr *)(skb->data); | 640 | struct ethhdr *eth = (struct ethhdr *)(skb->data); |
652 | struct iphdr *ipv4 = (struct iphdr *)(skb->data + ETH_HLEN); | 641 | struct iphdr *ipv4; |
653 | struct ipv6hdr *ipv6 = (struct ipv6hdr *)(skb->data + ETH_HLEN); | 642 | struct ipv6hdr *ipv6; |
654 | struct tcphdr *tcp; | 643 | struct tcphdr *tcp; |
644 | int network_depth = 0; | ||
645 | __be16 proto; | ||
646 | u16 tot_len; | ||
655 | 647 | ||
656 | u8 l4_hdr_type = get_cqe_l4_hdr_type(cqe); | 648 | u8 l4_hdr_type = get_cqe_l4_hdr_type(cqe); |
657 | int tcp_ack = ((CQE_L4_HDR_TYPE_TCP_ACK_NO_DATA == l4_hdr_type) || | 649 | int tcp_ack = ((CQE_L4_HDR_TYPE_TCP_ACK_NO_DATA == l4_hdr_type) || |
658 | (CQE_L4_HDR_TYPE_TCP_ACK_AND_DATA == l4_hdr_type)); | 650 | (CQE_L4_HDR_TYPE_TCP_ACK_AND_DATA == l4_hdr_type)); |
659 | 651 | ||
660 | u16 tot_len = cqe_bcnt - ETH_HLEN; | 652 | skb->mac_len = ETH_HLEN; |
653 | proto = __vlan_get_protocol(skb, eth->h_proto, &network_depth); | ||
654 | |||
655 | ipv4 = (struct iphdr *)(skb->data + network_depth); | ||
656 | ipv6 = (struct ipv6hdr *)(skb->data + network_depth); | ||
657 | tot_len = cqe_bcnt - network_depth; | ||
661 | 658 | ||
662 | if (eth->h_proto == htons(ETH_P_IP)) { | 659 | if (proto == htons(ETH_P_IP)) { |
663 | tcp = (struct tcphdr *)(skb->data + ETH_HLEN + | 660 | tcp = (struct tcphdr *)(skb->data + network_depth + |
664 | sizeof(struct iphdr)); | 661 | sizeof(struct iphdr)); |
665 | ipv6 = NULL; | 662 | ipv6 = NULL; |
666 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; | 663 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; |
667 | } else { | 664 | } else { |
668 | tcp = (struct tcphdr *)(skb->data + ETH_HLEN + | 665 | tcp = (struct tcphdr *)(skb->data + network_depth + |
669 | sizeof(struct ipv6hdr)); | 666 | sizeof(struct ipv6hdr)); |
670 | ipv4 = NULL; | 667 | ipv4 = NULL; |
671 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; | 668 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; |
@@ -916,7 +913,7 @@ int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget) | |||
916 | struct mlx5e_rq *rq = container_of(cq, struct mlx5e_rq, cq); | 913 | struct mlx5e_rq *rq = container_of(cq, struct mlx5e_rq, cq); |
917 | int work_done = 0; | 914 | int work_done = 0; |
918 | 915 | ||
919 | if (unlikely(test_bit(MLX5E_RQ_STATE_FLUSH_TIMEOUT, &rq->state))) | 916 | if (unlikely(test_bit(MLX5E_RQ_STATE_FLUSH, &rq->state))) |
920 | return 0; | 917 | return 0; |
921 | 918 | ||
922 | if (cq->decmprs_left) | 919 | if (cq->decmprs_left) |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h index 7b9d8a989b52..499487ce3b53 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h | |||
@@ -70,6 +70,7 @@ struct mlx5e_sw_stats { | |||
70 | u64 tx_queue_stopped; | 70 | u64 tx_queue_stopped; |
71 | u64 tx_queue_wake; | 71 | u64 tx_queue_wake; |
72 | u64 tx_queue_dropped; | 72 | u64 tx_queue_dropped; |
73 | u64 tx_xmit_more; | ||
73 | u64 rx_wqe_err; | 74 | u64 rx_wqe_err; |
74 | u64 rx_mpwqe_filler; | 75 | u64 rx_mpwqe_filler; |
75 | u64 rx_mpwqe_frag; | 76 | u64 rx_mpwqe_frag; |
@@ -101,6 +102,7 @@ static const struct counter_desc sw_stats_desc[] = { | |||
101 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_stopped) }, | 102 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_stopped) }, |
102 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_wake) }, | 103 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_wake) }, |
103 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_dropped) }, | 104 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_dropped) }, |
105 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xmit_more) }, | ||
104 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_wqe_err) }, | 106 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_wqe_err) }, |
105 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_filler) }, | 107 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_filler) }, |
106 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_frag) }, | 108 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_frag) }, |
@@ -298,6 +300,7 @@ struct mlx5e_sq_stats { | |||
298 | /* commonly accessed in data path */ | 300 | /* commonly accessed in data path */ |
299 | u64 packets; | 301 | u64 packets; |
300 | u64 bytes; | 302 | u64 bytes; |
303 | u64 xmit_more; | ||
301 | u64 tso_packets; | 304 | u64 tso_packets; |
302 | u64 tso_bytes; | 305 | u64 tso_bytes; |
303 | u64 tso_inner_packets; | 306 | u64 tso_inner_packets; |
@@ -324,6 +327,7 @@ static const struct counter_desc sq_stats_desc[] = { | |||
324 | { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, stopped) }, | 327 | { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, stopped) }, |
325 | { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, wake) }, | 328 | { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, wake) }, |
326 | { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, dropped) }, | 329 | { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, dropped) }, |
330 | { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, xmit_more) }, | ||
327 | }; | 331 | }; |
328 | 332 | ||
329 | #define NUM_SW_COUNTERS ARRAY_SIZE(sw_stats_desc) | 333 | #define NUM_SW_COUNTERS ARRAY_SIZE(sw_stats_desc) |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index dc8b1cb0fdc8..22cfc4ac1837 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | |||
@@ -170,7 +170,7 @@ static int parse_cls_flower(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec | |||
170 | if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CONTROL)) { | 170 | if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CONTROL)) { |
171 | struct flow_dissector_key_control *key = | 171 | struct flow_dissector_key_control *key = |
172 | skb_flow_dissector_target(f->dissector, | 172 | skb_flow_dissector_target(f->dissector, |
173 | FLOW_DISSECTOR_KEY_BASIC, | 173 | FLOW_DISSECTOR_KEY_CONTROL, |
174 | f->key); | 174 | f->key); |
175 | addr_type = key->addr_type; | 175 | addr_type = key->addr_type; |
176 | } | 176 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c index e073bf59890d..eb0e72537f10 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c | |||
@@ -356,6 +356,7 @@ static netdev_tx_t mlx5e_sq_xmit(struct mlx5e_sq *sq, struct sk_buff *skb) | |||
356 | sq->stats.stopped++; | 356 | sq->stats.stopped++; |
357 | } | 357 | } |
358 | 358 | ||
359 | sq->stats.xmit_more += skb->xmit_more; | ||
359 | if (!skb->xmit_more || netif_xmit_stopped(sq->txq)) { | 360 | if (!skb->xmit_more || netif_xmit_stopped(sq->txq)) { |
360 | int bf_sz = 0; | 361 | int bf_sz = 0; |
361 | 362 | ||
@@ -394,35 +395,6 @@ netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev) | |||
394 | return mlx5e_sq_xmit(sq, skb); | 395 | return mlx5e_sq_xmit(sq, skb); |
395 | } | 396 | } |
396 | 397 | ||
397 | void mlx5e_free_tx_descs(struct mlx5e_sq *sq) | ||
398 | { | ||
399 | struct mlx5e_tx_wqe_info *wi; | ||
400 | struct sk_buff *skb; | ||
401 | u16 ci; | ||
402 | int i; | ||
403 | |||
404 | while (sq->cc != sq->pc) { | ||
405 | ci = sq->cc & sq->wq.sz_m1; | ||
406 | skb = sq->skb[ci]; | ||
407 | wi = &sq->wqe_info[ci]; | ||
408 | |||
409 | if (!skb) { /* nop */ | ||
410 | sq->cc++; | ||
411 | continue; | ||
412 | } | ||
413 | |||
414 | for (i = 0; i < wi->num_dma; i++) { | ||
415 | struct mlx5e_sq_dma *dma = | ||
416 | mlx5e_dma_get(sq, sq->dma_fifo_cc++); | ||
417 | |||
418 | mlx5e_tx_dma_unmap(sq->pdev, dma); | ||
419 | } | ||
420 | |||
421 | dev_kfree_skb_any(skb); | ||
422 | sq->cc += wi->num_wqebbs; | ||
423 | } | ||
424 | } | ||
425 | |||
426 | bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget) | 398 | bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget) |
427 | { | 399 | { |
428 | struct mlx5e_sq *sq; | 400 | struct mlx5e_sq *sq; |
@@ -434,7 +406,7 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget) | |||
434 | 406 | ||
435 | sq = container_of(cq, struct mlx5e_sq, cq); | 407 | sq = container_of(cq, struct mlx5e_sq, cq); |
436 | 408 | ||
437 | if (unlikely(test_bit(MLX5E_SQ_STATE_TX_TIMEOUT, &sq->state))) | 409 | if (unlikely(test_bit(MLX5E_SQ_STATE_FLUSH, &sq->state))) |
438 | return false; | 410 | return false; |
439 | 411 | ||
440 | npkts = 0; | 412 | npkts = 0; |
@@ -512,11 +484,39 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget) | |||
512 | netdev_tx_completed_queue(sq->txq, npkts, nbytes); | 484 | netdev_tx_completed_queue(sq->txq, npkts, nbytes); |
513 | 485 | ||
514 | if (netif_tx_queue_stopped(sq->txq) && | 486 | if (netif_tx_queue_stopped(sq->txq) && |
515 | mlx5e_sq_has_room_for(sq, MLX5E_SQ_STOP_ROOM) && | 487 | mlx5e_sq_has_room_for(sq, MLX5E_SQ_STOP_ROOM)) { |
516 | likely(test_bit(MLX5E_SQ_STATE_WAKE_TXQ_ENABLE, &sq->state))) { | 488 | netif_tx_wake_queue(sq->txq); |
517 | netif_tx_wake_queue(sq->txq); | 489 | sq->stats.wake++; |
518 | sq->stats.wake++; | ||
519 | } | 490 | } |
520 | 491 | ||
521 | return (i == MLX5E_TX_CQ_POLL_BUDGET); | 492 | return (i == MLX5E_TX_CQ_POLL_BUDGET); |
522 | } | 493 | } |
494 | |||
495 | void mlx5e_free_tx_descs(struct mlx5e_sq *sq) | ||
496 | { | ||
497 | struct mlx5e_tx_wqe_info *wi; | ||
498 | struct sk_buff *skb; | ||
499 | u16 ci; | ||
500 | int i; | ||
501 | |||
502 | while (sq->cc != sq->pc) { | ||
503 | ci = sq->cc & sq->wq.sz_m1; | ||
504 | skb = sq->skb[ci]; | ||
505 | wi = &sq->wqe_info[ci]; | ||
506 | |||
507 | if (!skb) { /* nop */ | ||
508 | sq->cc++; | ||
509 | continue; | ||
510 | } | ||
511 | |||
512 | for (i = 0; i < wi->num_dma; i++) { | ||
513 | struct mlx5e_sq_dma *dma = | ||
514 | mlx5e_dma_get(sq, sq->dma_fifo_cc++); | ||
515 | |||
516 | mlx5e_tx_dma_unmap(sq->pdev, dma); | ||
517 | } | ||
518 | |||
519 | dev_kfree_skb_any(skb); | ||
520 | sq->cc += wi->num_wqebbs; | ||
521 | } | ||
522 | } | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c index 64ae2e800daa..9bf33bb69210 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c | |||
@@ -51,16 +51,18 @@ struct mlx5_cqe64 *mlx5e_get_cqe(struct mlx5e_cq *cq) | |||
51 | 51 | ||
52 | static void mlx5e_poll_ico_cq(struct mlx5e_cq *cq) | 52 | static void mlx5e_poll_ico_cq(struct mlx5e_cq *cq) |
53 | { | 53 | { |
54 | struct mlx5e_sq *sq = container_of(cq, struct mlx5e_sq, cq); | ||
54 | struct mlx5_wq_cyc *wq; | 55 | struct mlx5_wq_cyc *wq; |
55 | struct mlx5_cqe64 *cqe; | 56 | struct mlx5_cqe64 *cqe; |
56 | struct mlx5e_sq *sq; | ||
57 | u16 sqcc; | 57 | u16 sqcc; |
58 | 58 | ||
59 | if (unlikely(test_bit(MLX5E_SQ_STATE_FLUSH, &sq->state))) | ||
60 | return; | ||
61 | |||
59 | cqe = mlx5e_get_cqe(cq); | 62 | cqe = mlx5e_get_cqe(cq); |
60 | if (likely(!cqe)) | 63 | if (likely(!cqe)) |
61 | return; | 64 | return; |
62 | 65 | ||
63 | sq = container_of(cq, struct mlx5e_sq, cq); | ||
64 | wq = &sq->wq; | 66 | wq = &sq->wq; |
65 | 67 | ||
66 | /* sq->cc must be updated only after mlx5_cqwq_update_db_record(), | 68 | /* sq->cc must be updated only after mlx5_cqwq_update_db_record(), |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index f6d667797ee1..b247949df135 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | |||
@@ -1451,7 +1451,8 @@ static void esw_enable_vport(struct mlx5_eswitch *esw, int vport_num, | |||
1451 | 1451 | ||
1452 | esw_debug(esw->dev, "Enabling VPORT(%d)\n", vport_num); | 1452 | esw_debug(esw->dev, "Enabling VPORT(%d)\n", vport_num); |
1453 | 1453 | ||
1454 | if (vport_num) { /* Only VFs need ACLs for VST and spoofchk filtering */ | 1454 | /* Only VFs need ACLs for VST and spoofchk filtering */ |
1455 | if (vport_num && esw->mode == SRIOV_LEGACY) { | ||
1455 | esw_vport_ingress_config(esw, vport); | 1456 | esw_vport_ingress_config(esw, vport); |
1456 | esw_vport_egress_config(esw, vport); | 1457 | esw_vport_egress_config(esw, vport); |
1457 | } | 1458 | } |
@@ -1502,7 +1503,7 @@ static void esw_disable_vport(struct mlx5_eswitch *esw, int vport_num) | |||
1502 | */ | 1503 | */ |
1503 | esw_vport_change_handle_locked(vport); | 1504 | esw_vport_change_handle_locked(vport); |
1504 | vport->enabled_events = 0; | 1505 | vport->enabled_events = 0; |
1505 | if (vport_num) { | 1506 | if (vport_num && esw->mode == SRIOV_LEGACY) { |
1506 | esw_vport_disable_egress_acl(esw, vport); | 1507 | esw_vport_disable_egress_acl(esw, vport); |
1507 | esw_vport_disable_ingress_acl(esw, vport); | 1508 | esw_vport_disable_ingress_acl(esw, vport); |
1508 | } | 1509 | } |
@@ -1553,6 +1554,7 @@ int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode) | |||
1553 | 1554 | ||
1554 | abort: | 1555 | abort: |
1555 | esw_enable_vport(esw, 0, UC_ADDR_CHANGE); | 1556 | esw_enable_vport(esw, 0, UC_ADDR_CHANGE); |
1557 | esw->mode = SRIOV_NONE; | ||
1556 | return err; | 1558 | return err; |
1557 | } | 1559 | } |
1558 | 1560 | ||
@@ -1767,7 +1769,7 @@ int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw, | |||
1767 | vport, err); | 1769 | vport, err); |
1768 | 1770 | ||
1769 | mutex_lock(&esw->state_lock); | 1771 | mutex_lock(&esw->state_lock); |
1770 | if (evport->enabled) | 1772 | if (evport->enabled && esw->mode == SRIOV_LEGACY) |
1771 | err = esw_vport_ingress_config(esw, evport); | 1773 | err = esw_vport_ingress_config(esw, evport); |
1772 | mutex_unlock(&esw->state_lock); | 1774 | mutex_unlock(&esw->state_lock); |
1773 | return err; | 1775 | return err; |
@@ -1839,7 +1841,7 @@ int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw, | |||
1839 | mutex_lock(&esw->state_lock); | 1841 | mutex_lock(&esw->state_lock); |
1840 | evport->vlan = vlan; | 1842 | evport->vlan = vlan; |
1841 | evport->qos = qos; | 1843 | evport->qos = qos; |
1842 | if (evport->enabled) { | 1844 | if (evport->enabled && esw->mode == SRIOV_LEGACY) { |
1843 | err = esw_vport_ingress_config(esw, evport); | 1845 | err = esw_vport_ingress_config(esw, evport); |
1844 | if (err) | 1846 | if (err) |
1845 | goto out; | 1847 | goto out; |
@@ -1868,10 +1870,11 @@ int mlx5_eswitch_set_vport_spoofchk(struct mlx5_eswitch *esw, | |||
1868 | mutex_lock(&esw->state_lock); | 1870 | mutex_lock(&esw->state_lock); |
1869 | pschk = evport->spoofchk; | 1871 | pschk = evport->spoofchk; |
1870 | evport->spoofchk = spoofchk; | 1872 | evport->spoofchk = spoofchk; |
1871 | if (evport->enabled) | 1873 | if (evport->enabled && esw->mode == SRIOV_LEGACY) { |
1872 | err = esw_vport_ingress_config(esw, evport); | 1874 | err = esw_vport_ingress_config(esw, evport); |
1873 | if (err) | 1875 | if (err) |
1874 | evport->spoofchk = pschk; | 1876 | evport->spoofchk = pschk; |
1877 | } | ||
1875 | mutex_unlock(&esw->state_lock); | 1878 | mutex_unlock(&esw->state_lock); |
1876 | 1879 | ||
1877 | return err; | 1880 | return err; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h index c0b05603fc31..a96140971d77 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | |||
@@ -174,6 +174,7 @@ struct mlx5_eswitch_rep { | |||
174 | void *priv_data; | 174 | void *priv_data; |
175 | struct list_head vport_sqs_list; | 175 | struct list_head vport_sqs_list; |
176 | bool valid; | 176 | bool valid; |
177 | u8 hw_id[ETH_ALEN]; | ||
177 | }; | 178 | }; |
178 | 179 | ||
179 | struct mlx5_esw_offload { | 180 | struct mlx5_esw_offload { |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index a357e8eeeed8..7de40e6b0c25 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | |||
@@ -113,7 +113,7 @@ mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *esw, int vport, u32 sqn | |||
113 | dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT; | 113 | dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT; |
114 | dest.vport_num = vport; | 114 | dest.vport_num = vport; |
115 | 115 | ||
116 | flow_rule = mlx5_add_flow_rule(esw->fdb_table.fdb, spec, | 116 | flow_rule = mlx5_add_flow_rule(esw->fdb_table.offloads.fdb, spec, |
117 | MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, | 117 | MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, |
118 | 0, &dest); | 118 | 0, &dest); |
119 | if (IS_ERR(flow_rule)) | 119 | if (IS_ERR(flow_rule)) |
@@ -446,7 +446,7 @@ out: | |||
446 | 446 | ||
447 | static int esw_offloads_start(struct mlx5_eswitch *esw) | 447 | static int esw_offloads_start(struct mlx5_eswitch *esw) |
448 | { | 448 | { |
449 | int err, num_vfs = esw->dev->priv.sriov.num_vfs; | 449 | int err, err1, num_vfs = esw->dev->priv.sriov.num_vfs; |
450 | 450 | ||
451 | if (esw->mode != SRIOV_LEGACY) { | 451 | if (esw->mode != SRIOV_LEGACY) { |
452 | esw_warn(esw->dev, "Can't set offloads mode, SRIOV legacy not enabled\n"); | 452 | esw_warn(esw->dev, "Can't set offloads mode, SRIOV legacy not enabled\n"); |
@@ -455,8 +455,12 @@ static int esw_offloads_start(struct mlx5_eswitch *esw) | |||
455 | 455 | ||
456 | mlx5_eswitch_disable_sriov(esw); | 456 | mlx5_eswitch_disable_sriov(esw); |
457 | err = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_OFFLOADS); | 457 | err = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_OFFLOADS); |
458 | if (err) | 458 | if (err) { |
459 | esw_warn(esw->dev, "Failed set eswitch to offloads, err %d\n", err); | 459 | esw_warn(esw->dev, "Failed setting eswitch to offloads, err %d\n", err); |
460 | err1 = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_LEGACY); | ||
461 | if (err1) | ||
462 | esw_warn(esw->dev, "Failed setting eswitch back to legacy, err %d\n", err); | ||
463 | } | ||
460 | return err; | 464 | return err; |
461 | } | 465 | } |
462 | 466 | ||
@@ -508,12 +512,16 @@ create_ft_err: | |||
508 | 512 | ||
509 | static int esw_offloads_stop(struct mlx5_eswitch *esw) | 513 | static int esw_offloads_stop(struct mlx5_eswitch *esw) |
510 | { | 514 | { |
511 | int err, num_vfs = esw->dev->priv.sriov.num_vfs; | 515 | int err, err1, num_vfs = esw->dev->priv.sriov.num_vfs; |
512 | 516 | ||
513 | mlx5_eswitch_disable_sriov(esw); | 517 | mlx5_eswitch_disable_sriov(esw); |
514 | err = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_LEGACY); | 518 | err = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_LEGACY); |
515 | if (err) | 519 | if (err) { |
516 | esw_warn(esw->dev, "Failed set eswitch legacy mode. err %d\n", err); | 520 | esw_warn(esw->dev, "Failed setting eswitch to legacy, err %d\n", err); |
521 | err1 = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_OFFLOADS); | ||
522 | if (err1) | ||
523 | esw_warn(esw->dev, "Failed setting eswitch back to offloads, err %d\n", err); | ||
524 | } | ||
517 | 525 | ||
518 | return err; | 526 | return err; |
519 | } | 527 | } |
@@ -535,7 +543,7 @@ void esw_offloads_cleanup(struct mlx5_eswitch *esw, int nvports) | |||
535 | esw_destroy_offloads_fdb_table(esw); | 543 | esw_destroy_offloads_fdb_table(esw); |
536 | } | 544 | } |
537 | 545 | ||
538 | static int mlx5_esw_mode_from_devlink(u16 mode, u16 *mlx5_mode) | 546 | static int esw_mode_from_devlink(u16 mode, u16 *mlx5_mode) |
539 | { | 547 | { |
540 | switch (mode) { | 548 | switch (mode) { |
541 | case DEVLINK_ESWITCH_MODE_LEGACY: | 549 | case DEVLINK_ESWITCH_MODE_LEGACY: |
@@ -551,6 +559,22 @@ static int mlx5_esw_mode_from_devlink(u16 mode, u16 *mlx5_mode) | |||
551 | return 0; | 559 | return 0; |
552 | } | 560 | } |
553 | 561 | ||
562 | static int esw_mode_to_devlink(u16 mlx5_mode, u16 *mode) | ||
563 | { | ||
564 | switch (mlx5_mode) { | ||
565 | case SRIOV_LEGACY: | ||
566 | *mode = DEVLINK_ESWITCH_MODE_LEGACY; | ||
567 | break; | ||
568 | case SRIOV_OFFLOADS: | ||
569 | *mode = DEVLINK_ESWITCH_MODE_SWITCHDEV; | ||
570 | break; | ||
571 | default: | ||
572 | return -EINVAL; | ||
573 | } | ||
574 | |||
575 | return 0; | ||
576 | } | ||
577 | |||
554 | int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode) | 578 | int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode) |
555 | { | 579 | { |
556 | struct mlx5_core_dev *dev; | 580 | struct mlx5_core_dev *dev; |
@@ -566,7 +590,7 @@ int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode) | |||
566 | if (cur_mlx5_mode == SRIOV_NONE) | 590 | if (cur_mlx5_mode == SRIOV_NONE) |
567 | return -EOPNOTSUPP; | 591 | return -EOPNOTSUPP; |
568 | 592 | ||
569 | if (mlx5_esw_mode_from_devlink(mode, &mlx5_mode)) | 593 | if (esw_mode_from_devlink(mode, &mlx5_mode)) |
570 | return -EINVAL; | 594 | return -EINVAL; |
571 | 595 | ||
572 | if (cur_mlx5_mode == mlx5_mode) | 596 | if (cur_mlx5_mode == mlx5_mode) |
@@ -592,9 +616,7 @@ int mlx5_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode) | |||
592 | if (dev->priv.eswitch->mode == SRIOV_NONE) | 616 | if (dev->priv.eswitch->mode == SRIOV_NONE) |
593 | return -EOPNOTSUPP; | 617 | return -EOPNOTSUPP; |
594 | 618 | ||
595 | *mode = dev->priv.eswitch->mode; | 619 | return esw_mode_to_devlink(dev->priv.eswitch->mode, mode); |
596 | |||
597 | return 0; | ||
598 | } | 620 | } |
599 | 621 | ||
600 | void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw, | 622 | void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c index 9134010e2921..287ade151ec8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c | |||
@@ -425,11 +425,11 @@ struct mlx5_cmd_fc_bulk * | |||
425 | mlx5_cmd_fc_bulk_alloc(struct mlx5_core_dev *dev, u16 id, int num) | 425 | mlx5_cmd_fc_bulk_alloc(struct mlx5_core_dev *dev, u16 id, int num) |
426 | { | 426 | { |
427 | struct mlx5_cmd_fc_bulk *b; | 427 | struct mlx5_cmd_fc_bulk *b; |
428 | int outlen = sizeof(*b) + | 428 | int outlen = |
429 | MLX5_ST_SZ_BYTES(query_flow_counter_out) + | 429 | MLX5_ST_SZ_BYTES(query_flow_counter_out) + |
430 | MLX5_ST_SZ_BYTES(traffic_counter) * num; | 430 | MLX5_ST_SZ_BYTES(traffic_counter) * num; |
431 | 431 | ||
432 | b = kzalloc(outlen, GFP_KERNEL); | 432 | b = kzalloc(sizeof(*b) + outlen, GFP_KERNEL); |
433 | if (!b) | 433 | if (!b) |
434 | return NULL; | 434 | return NULL; |
435 | 435 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 75bb8c864557..3d6c1f65e586 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | |||
@@ -80,7 +80,7 @@ | |||
80 | LEFTOVERS_NUM_PRIOS) | 80 | LEFTOVERS_NUM_PRIOS) |
81 | 81 | ||
82 | #define ETHTOOL_PRIO_NUM_LEVELS 1 | 82 | #define ETHTOOL_PRIO_NUM_LEVELS 1 |
83 | #define ETHTOOL_NUM_PRIOS 10 | 83 | #define ETHTOOL_NUM_PRIOS 11 |
84 | #define ETHTOOL_MIN_LEVEL (KERNEL_MIN_LEVEL + ETHTOOL_NUM_PRIOS) | 84 | #define ETHTOOL_MIN_LEVEL (KERNEL_MIN_LEVEL + ETHTOOL_NUM_PRIOS) |
85 | /* Vlan, mac, ttc, aRFS */ | 85 | /* Vlan, mac, ttc, aRFS */ |
86 | #define KERNEL_NIC_PRIO_NUM_LEVELS 4 | 86 | #define KERNEL_NIC_PRIO_NUM_LEVELS 4 |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c index c2877e9de8a1..3a9195b4169d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c | |||
@@ -126,12 +126,21 @@ static struct rb_node *mlx5_fc_stats_query(struct mlx5_core_dev *dev, | |||
126 | for (node = &first->node; node; node = rb_next(node)) { | 126 | for (node = &first->node; node; node = rb_next(node)) { |
127 | struct mlx5_fc *counter = rb_entry(node, struct mlx5_fc, node); | 127 | struct mlx5_fc *counter = rb_entry(node, struct mlx5_fc, node); |
128 | struct mlx5_fc_cache *c = &counter->cache; | 128 | struct mlx5_fc_cache *c = &counter->cache; |
129 | u64 packets; | ||
130 | u64 bytes; | ||
129 | 131 | ||
130 | if (counter->id > last_id) | 132 | if (counter->id > last_id) |
131 | break; | 133 | break; |
132 | 134 | ||
133 | mlx5_cmd_fc_bulk_get(dev, b, | 135 | mlx5_cmd_fc_bulk_get(dev, b, |
134 | counter->id, &c->packets, &c->bytes); | 136 | counter->id, &packets, &bytes); |
137 | |||
138 | if (c->packets == packets) | ||
139 | continue; | ||
140 | |||
141 | c->packets = packets; | ||
142 | c->bytes = bytes; | ||
143 | c->lastuse = jiffies; | ||
135 | } | 144 | } |
136 | 145 | ||
137 | out: | 146 | out: |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 4f491d43e77d..2385bae92672 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c | |||
@@ -1420,36 +1420,12 @@ static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev, | |||
1420 | dev_info(&pdev->dev, "%s was called\n", __func__); | 1420 | dev_info(&pdev->dev, "%s was called\n", __func__); |
1421 | mlx5_enter_error_state(dev); | 1421 | mlx5_enter_error_state(dev); |
1422 | mlx5_unload_one(dev, priv); | 1422 | mlx5_unload_one(dev, priv); |
1423 | pci_save_state(pdev); | ||
1423 | mlx5_pci_disable_device(dev); | 1424 | mlx5_pci_disable_device(dev); |
1424 | return state == pci_channel_io_perm_failure ? | 1425 | return state == pci_channel_io_perm_failure ? |
1425 | PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET; | 1426 | PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET; |
1426 | } | 1427 | } |
1427 | 1428 | ||
1428 | static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev) | ||
1429 | { | ||
1430 | struct mlx5_core_dev *dev = pci_get_drvdata(pdev); | ||
1431 | int err = 0; | ||
1432 | |||
1433 | dev_info(&pdev->dev, "%s was called\n", __func__); | ||
1434 | |||
1435 | err = mlx5_pci_enable_device(dev); | ||
1436 | if (err) { | ||
1437 | dev_err(&pdev->dev, "%s: mlx5_pci_enable_device failed with error code: %d\n" | ||
1438 | , __func__, err); | ||
1439 | return PCI_ERS_RESULT_DISCONNECT; | ||
1440 | } | ||
1441 | pci_set_master(pdev); | ||
1442 | pci_set_power_state(pdev, PCI_D0); | ||
1443 | pci_restore_state(pdev); | ||
1444 | |||
1445 | return err ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED; | ||
1446 | } | ||
1447 | |||
1448 | void mlx5_disable_device(struct mlx5_core_dev *dev) | ||
1449 | { | ||
1450 | mlx5_pci_err_detected(dev->pdev, 0); | ||
1451 | } | ||
1452 | |||
1453 | /* wait for the device to show vital signs by waiting | 1429 | /* wait for the device to show vital signs by waiting |
1454 | * for the health counter to start counting. | 1430 | * for the health counter to start counting. |
1455 | */ | 1431 | */ |
@@ -1477,21 +1453,44 @@ static int wait_vital(struct pci_dev *pdev) | |||
1477 | return -ETIMEDOUT; | 1453 | return -ETIMEDOUT; |
1478 | } | 1454 | } |
1479 | 1455 | ||
1480 | static void mlx5_pci_resume(struct pci_dev *pdev) | 1456 | static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev) |
1481 | { | 1457 | { |
1482 | struct mlx5_core_dev *dev = pci_get_drvdata(pdev); | 1458 | struct mlx5_core_dev *dev = pci_get_drvdata(pdev); |
1483 | struct mlx5_priv *priv = &dev->priv; | ||
1484 | int err; | 1459 | int err; |
1485 | 1460 | ||
1486 | dev_info(&pdev->dev, "%s was called\n", __func__); | 1461 | dev_info(&pdev->dev, "%s was called\n", __func__); |
1487 | 1462 | ||
1488 | pci_save_state(pdev); | 1463 | err = mlx5_pci_enable_device(dev); |
1489 | err = wait_vital(pdev); | ||
1490 | if (err) { | 1464 | if (err) { |
1465 | dev_err(&pdev->dev, "%s: mlx5_pci_enable_device failed with error code: %d\n" | ||
1466 | , __func__, err); | ||
1467 | return PCI_ERS_RESULT_DISCONNECT; | ||
1468 | } | ||
1469 | |||
1470 | pci_set_master(pdev); | ||
1471 | pci_restore_state(pdev); | ||
1472 | |||
1473 | if (wait_vital(pdev)) { | ||
1491 | dev_err(&pdev->dev, "%s: wait_vital timed out\n", __func__); | 1474 | dev_err(&pdev->dev, "%s: wait_vital timed out\n", __func__); |
1492 | return; | 1475 | return PCI_ERS_RESULT_DISCONNECT; |
1493 | } | 1476 | } |
1494 | 1477 | ||
1478 | return PCI_ERS_RESULT_RECOVERED; | ||
1479 | } | ||
1480 | |||
1481 | void mlx5_disable_device(struct mlx5_core_dev *dev) | ||
1482 | { | ||
1483 | mlx5_pci_err_detected(dev->pdev, 0); | ||
1484 | } | ||
1485 | |||
1486 | static void mlx5_pci_resume(struct pci_dev *pdev) | ||
1487 | { | ||
1488 | struct mlx5_core_dev *dev = pci_get_drvdata(pdev); | ||
1489 | struct mlx5_priv *priv = &dev->priv; | ||
1490 | int err; | ||
1491 | |||
1492 | dev_info(&pdev->dev, "%s was called\n", __func__); | ||
1493 | |||
1495 | err = mlx5_load_one(dev, priv); | 1494 | err = mlx5_load_one(dev, priv); |
1496 | if (err) | 1495 | if (err) |
1497 | dev_err(&pdev->dev, "%s: mlx5_load_one failed with error code: %d\n" | 1496 | dev_err(&pdev->dev, "%s: mlx5_load_one failed with error code: %d\n" |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/port.h b/drivers/net/ethernet/mellanox/mlxsw/port.h index f33b997f2b61..af371a82c35b 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/port.h +++ b/drivers/net/ethernet/mellanox/mlxsw/port.h | |||
@@ -56,6 +56,7 @@ | |||
56 | #define MLXSW_PORT_PHY_BITS_MASK (MLXSW_PORT_MAX_PHY_PORTS - 1) | 56 | #define MLXSW_PORT_PHY_BITS_MASK (MLXSW_PORT_MAX_PHY_PORTS - 1) |
57 | 57 | ||
58 | #define MLXSW_PORT_CPU_PORT 0x0 | 58 | #define MLXSW_PORT_CPU_PORT 0x0 |
59 | #define MLXSW_PORT_ROUTER_PORT (MLXSW_PORT_MAX_PHY_PORTS + 2) | ||
59 | 60 | ||
60 | #define MLXSW_PORT_DONT_CARE (MLXSW_PORT_MAX_PORTS) | 61 | #define MLXSW_PORT_DONT_CARE (MLXSW_PORT_MAX_PORTS) |
61 | 62 | ||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index 1f8168906811..d48873bcbddf 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <generated/utsrelease.h> | 56 | #include <generated/utsrelease.h> |
57 | #include <net/pkt_cls.h> | 57 | #include <net/pkt_cls.h> |
58 | #include <net/tc_act/tc_mirred.h> | 58 | #include <net/tc_act/tc_mirred.h> |
59 | #include <net/netevent.h> | ||
59 | 60 | ||
60 | #include "spectrum.h" | 61 | #include "spectrum.h" |
61 | #include "core.h" | 62 | #include "core.h" |
@@ -2105,6 +2106,13 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port, | |||
2105 | dev->netdev_ops = &mlxsw_sp_port_netdev_ops; | 2106 | dev->netdev_ops = &mlxsw_sp_port_netdev_ops; |
2106 | dev->ethtool_ops = &mlxsw_sp_port_ethtool_ops; | 2107 | dev->ethtool_ops = &mlxsw_sp_port_ethtool_ops; |
2107 | 2108 | ||
2109 | err = mlxsw_sp_port_swid_set(mlxsw_sp_port, 0); | ||
2110 | if (err) { | ||
2111 | dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set SWID\n", | ||
2112 | mlxsw_sp_port->local_port); | ||
2113 | goto err_port_swid_set; | ||
2114 | } | ||
2115 | |||
2108 | err = mlxsw_sp_port_dev_addr_init(mlxsw_sp_port); | 2116 | err = mlxsw_sp_port_dev_addr_init(mlxsw_sp_port); |
2109 | if (err) { | 2117 | if (err) { |
2110 | dev_err(mlxsw_sp->bus_info->dev, "Port %d: Unable to init port mac address\n", | 2118 | dev_err(mlxsw_sp->bus_info->dev, "Port %d: Unable to init port mac address\n", |
@@ -2130,13 +2138,6 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port, | |||
2130 | goto err_port_system_port_mapping_set; | 2138 | goto err_port_system_port_mapping_set; |
2131 | } | 2139 | } |
2132 | 2140 | ||
2133 | err = mlxsw_sp_port_swid_set(mlxsw_sp_port, 0); | ||
2134 | if (err) { | ||
2135 | dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set SWID\n", | ||
2136 | mlxsw_sp_port->local_port); | ||
2137 | goto err_port_swid_set; | ||
2138 | } | ||
2139 | |||
2140 | err = mlxsw_sp_port_speed_by_width_set(mlxsw_sp_port, width); | 2141 | err = mlxsw_sp_port_speed_by_width_set(mlxsw_sp_port, width); |
2141 | if (err) { | 2142 | if (err) { |
2142 | dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to enable speeds\n", | 2143 | dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to enable speeds\n", |
@@ -2218,10 +2219,10 @@ err_port_buffers_init: | |||
2218 | err_port_admin_status_set: | 2219 | err_port_admin_status_set: |
2219 | err_port_mtu_set: | 2220 | err_port_mtu_set: |
2220 | err_port_speed_by_width_set: | 2221 | err_port_speed_by_width_set: |
2221 | mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT); | ||
2222 | err_port_swid_set: | ||
2223 | err_port_system_port_mapping_set: | 2222 | err_port_system_port_mapping_set: |
2224 | err_dev_addr_init: | 2223 | err_dev_addr_init: |
2224 | mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT); | ||
2225 | err_port_swid_set: | ||
2225 | free_percpu(mlxsw_sp_port->pcpu_stats); | 2226 | free_percpu(mlxsw_sp_port->pcpu_stats); |
2226 | err_alloc_stats: | 2227 | err_alloc_stats: |
2227 | kfree(mlxsw_sp_port->untagged_vlans); | 2228 | kfree(mlxsw_sp_port->untagged_vlans); |
@@ -3324,6 +3325,39 @@ static struct mlxsw_sp_fid *mlxsw_sp_bridge_fid_get(struct mlxsw_sp *mlxsw_sp, | |||
3324 | return mlxsw_sp_fid_find(mlxsw_sp, fid); | 3325 | return mlxsw_sp_fid_find(mlxsw_sp, fid); |
3325 | } | 3326 | } |
3326 | 3327 | ||
3328 | static enum mlxsw_flood_table_type mlxsw_sp_flood_table_type_get(u16 fid) | ||
3329 | { | ||
3330 | return mlxsw_sp_fid_is_vfid(fid) ? MLXSW_REG_SFGC_TABLE_TYPE_FID : | ||
3331 | MLXSW_REG_SFGC_TABLE_TYPE_FID_OFFEST; | ||
3332 | } | ||
3333 | |||
3334 | static u16 mlxsw_sp_flood_table_index_get(u16 fid) | ||
3335 | { | ||
3336 | return mlxsw_sp_fid_is_vfid(fid) ? mlxsw_sp_fid_to_vfid(fid) : fid; | ||
3337 | } | ||
3338 | |||
3339 | static int mlxsw_sp_router_port_flood_set(struct mlxsw_sp *mlxsw_sp, u16 fid, | ||
3340 | bool set) | ||
3341 | { | ||
3342 | enum mlxsw_flood_table_type table_type; | ||
3343 | char *sftr_pl; | ||
3344 | u16 index; | ||
3345 | int err; | ||
3346 | |||
3347 | sftr_pl = kmalloc(MLXSW_REG_SFTR_LEN, GFP_KERNEL); | ||
3348 | if (!sftr_pl) | ||
3349 | return -ENOMEM; | ||
3350 | |||
3351 | table_type = mlxsw_sp_flood_table_type_get(fid); | ||
3352 | index = mlxsw_sp_flood_table_index_get(fid); | ||
3353 | mlxsw_reg_sftr_pack(sftr_pl, MLXSW_SP_FLOOD_TABLE_BM, index, table_type, | ||
3354 | 1, MLXSW_PORT_ROUTER_PORT, set); | ||
3355 | err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sftr), sftr_pl); | ||
3356 | |||
3357 | kfree(sftr_pl); | ||
3358 | return err; | ||
3359 | } | ||
3360 | |||
3327 | static enum mlxsw_reg_ritr_if_type mlxsw_sp_rif_type_get(u16 fid) | 3361 | static enum mlxsw_reg_ritr_if_type mlxsw_sp_rif_type_get(u16 fid) |
3328 | { | 3362 | { |
3329 | if (mlxsw_sp_fid_is_vfid(fid)) | 3363 | if (mlxsw_sp_fid_is_vfid(fid)) |
@@ -3360,10 +3394,14 @@ static int mlxsw_sp_rif_bridge_create(struct mlxsw_sp *mlxsw_sp, | |||
3360 | if (rif == MLXSW_SP_RIF_MAX) | 3394 | if (rif == MLXSW_SP_RIF_MAX) |
3361 | return -ERANGE; | 3395 | return -ERANGE; |
3362 | 3396 | ||
3363 | err = mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, true); | 3397 | err = mlxsw_sp_router_port_flood_set(mlxsw_sp, f->fid, true); |
3364 | if (err) | 3398 | if (err) |
3365 | return err; | 3399 | return err; |
3366 | 3400 | ||
3401 | err = mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, true); | ||
3402 | if (err) | ||
3403 | goto err_rif_bridge_op; | ||
3404 | |||
3367 | err = mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, f->fid, true); | 3405 | err = mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, f->fid, true); |
3368 | if (err) | 3406 | if (err) |
3369 | goto err_rif_fdb_op; | 3407 | goto err_rif_fdb_op; |
@@ -3385,6 +3423,8 @@ err_rif_alloc: | |||
3385 | mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, f->fid, false); | 3423 | mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, f->fid, false); |
3386 | err_rif_fdb_op: | 3424 | err_rif_fdb_op: |
3387 | mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, false); | 3425 | mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, false); |
3426 | err_rif_bridge_op: | ||
3427 | mlxsw_sp_router_port_flood_set(mlxsw_sp, f->fid, false); | ||
3388 | return err; | 3428 | return err; |
3389 | } | 3429 | } |
3390 | 3430 | ||
@@ -3404,6 +3444,8 @@ void mlxsw_sp_rif_bridge_destroy(struct mlxsw_sp *mlxsw_sp, | |||
3404 | 3444 | ||
3405 | mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, false); | 3445 | mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, false); |
3406 | 3446 | ||
3447 | mlxsw_sp_router_port_flood_set(mlxsw_sp, f->fid, false); | ||
3448 | |||
3407 | netdev_dbg(l3_dev, "RIF=%d destroyed\n", rif); | 3449 | netdev_dbg(l3_dev, "RIF=%d destroyed\n", rif); |
3408 | } | 3450 | } |
3409 | 3451 | ||
@@ -4500,18 +4542,26 @@ static struct notifier_block mlxsw_sp_inetaddr_nb __read_mostly = { | |||
4500 | .priority = 10, /* Must be called before FIB notifier block */ | 4542 | .priority = 10, /* Must be called before FIB notifier block */ |
4501 | }; | 4543 | }; |
4502 | 4544 | ||
4545 | static struct notifier_block mlxsw_sp_router_netevent_nb __read_mostly = { | ||
4546 | .notifier_call = mlxsw_sp_router_netevent_event, | ||
4547 | }; | ||
4548 | |||
4503 | static int __init mlxsw_sp_module_init(void) | 4549 | static int __init mlxsw_sp_module_init(void) |
4504 | { | 4550 | { |
4505 | int err; | 4551 | int err; |
4506 | 4552 | ||
4507 | register_netdevice_notifier(&mlxsw_sp_netdevice_nb); | 4553 | register_netdevice_notifier(&mlxsw_sp_netdevice_nb); |
4508 | register_inetaddr_notifier(&mlxsw_sp_inetaddr_nb); | 4554 | register_inetaddr_notifier(&mlxsw_sp_inetaddr_nb); |
4555 | register_netevent_notifier(&mlxsw_sp_router_netevent_nb); | ||
4556 | |||
4509 | err = mlxsw_core_driver_register(&mlxsw_sp_driver); | 4557 | err = mlxsw_core_driver_register(&mlxsw_sp_driver); |
4510 | if (err) | 4558 | if (err) |
4511 | goto err_core_driver_register; | 4559 | goto err_core_driver_register; |
4512 | return 0; | 4560 | return 0; |
4513 | 4561 | ||
4514 | err_core_driver_register: | 4562 | err_core_driver_register: |
4563 | unregister_netevent_notifier(&mlxsw_sp_router_netevent_nb); | ||
4564 | unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb); | ||
4515 | unregister_netdevice_notifier(&mlxsw_sp_netdevice_nb); | 4565 | unregister_netdevice_notifier(&mlxsw_sp_netdevice_nb); |
4516 | return err; | 4566 | return err; |
4517 | } | 4567 | } |
@@ -4519,6 +4569,7 @@ err_core_driver_register: | |||
4519 | static void __exit mlxsw_sp_module_exit(void) | 4569 | static void __exit mlxsw_sp_module_exit(void) |
4520 | { | 4570 | { |
4521 | mlxsw_core_driver_unregister(&mlxsw_sp_driver); | 4571 | mlxsw_core_driver_unregister(&mlxsw_sp_driver); |
4572 | unregister_netevent_notifier(&mlxsw_sp_router_netevent_nb); | ||
4522 | unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb); | 4573 | unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb); |
4523 | unregister_netdevice_notifier(&mlxsw_sp_netdevice_nb); | 4574 | unregister_netdevice_notifier(&mlxsw_sp_netdevice_nb); |
4524 | } | 4575 | } |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index ab3feb81bd43..ac48abebe904 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h | |||
@@ -587,6 +587,8 @@ int mlxsw_sp_router_neigh_construct(struct net_device *dev, | |||
587 | struct neighbour *n); | 587 | struct neighbour *n); |
588 | void mlxsw_sp_router_neigh_destroy(struct net_device *dev, | 588 | void mlxsw_sp_router_neigh_destroy(struct net_device *dev, |
589 | struct neighbour *n); | 589 | struct neighbour *n); |
590 | int mlxsw_sp_router_netevent_event(struct notifier_block *unused, | ||
591 | unsigned long event, void *ptr); | ||
590 | 592 | ||
591 | int mlxsw_sp_kvdl_alloc(struct mlxsw_sp *mlxsw_sp, unsigned int entry_count); | 593 | int mlxsw_sp_kvdl_alloc(struct mlxsw_sp *mlxsw_sp, unsigned int entry_count); |
592 | void mlxsw_sp_kvdl_free(struct mlxsw_sp *mlxsw_sp, int entry_index); | 594 | void mlxsw_sp_kvdl_free(struct mlxsw_sp *mlxsw_sp, int entry_index); |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c index 237418a0e6e0..953b214f38d0 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c | |||
@@ -717,22 +717,18 @@ int mlxsw_sp_sb_tc_pool_bind_set(struct mlxsw_core_port *mlxsw_core_port, | |||
717 | u8 local_port = mlxsw_sp_port->local_port; | 717 | u8 local_port = mlxsw_sp_port->local_port; |
718 | u8 pg_buff = tc_index; | 718 | u8 pg_buff = tc_index; |
719 | enum mlxsw_reg_sbxx_dir dir = pool_type; | 719 | enum mlxsw_reg_sbxx_dir dir = pool_type; |
720 | u8 pool = pool_index; | 720 | u8 pool = pool_get(pool_index); |
721 | u32 max_buff; | 721 | u32 max_buff; |
722 | int err; | 722 | int err; |
723 | 723 | ||
724 | if (dir != dir_get(pool_index)) | ||
725 | return -EINVAL; | ||
726 | |||
724 | err = mlxsw_sp_sb_threshold_in(mlxsw_sp, pool, dir, | 727 | err = mlxsw_sp_sb_threshold_in(mlxsw_sp, pool, dir, |
725 | threshold, &max_buff); | 728 | threshold, &max_buff); |
726 | if (err) | 729 | if (err) |
727 | return err; | 730 | return err; |
728 | 731 | ||
729 | if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS) { | ||
730 | if (pool < MLXSW_SP_SB_POOL_COUNT) | ||
731 | return -EINVAL; | ||
732 | pool -= MLXSW_SP_SB_POOL_COUNT; | ||
733 | } else if (pool >= MLXSW_SP_SB_POOL_COUNT) { | ||
734 | return -EINVAL; | ||
735 | } | ||
736 | return mlxsw_sp_sb_cm_write(mlxsw_sp, local_port, pg_buff, dir, | 732 | return mlxsw_sp_sb_cm_write(mlxsw_sp, local_port, pg_buff, dir, |
737 | 0, max_buff, pool); | 733 | 0, max_buff, pool); |
738 | } | 734 | } |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 90bb93b037ec..3f5c51da6d3e 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | |||
@@ -107,6 +107,7 @@ mlxsw_sp_prefix_usage_clear(struct mlxsw_sp_prefix_usage *prefix_usage, | |||
107 | } | 107 | } |
108 | 108 | ||
109 | struct mlxsw_sp_fib_key { | 109 | struct mlxsw_sp_fib_key { |
110 | struct net_device *dev; | ||
110 | unsigned char addr[sizeof(struct in6_addr)]; | 111 | unsigned char addr[sizeof(struct in6_addr)]; |
111 | unsigned char prefix_len; | 112 | unsigned char prefix_len; |
112 | }; | 113 | }; |
@@ -123,7 +124,7 @@ struct mlxsw_sp_fib_entry { | |||
123 | struct rhash_head ht_node; | 124 | struct rhash_head ht_node; |
124 | struct mlxsw_sp_fib_key key; | 125 | struct mlxsw_sp_fib_key key; |
125 | enum mlxsw_sp_fib_entry_type type; | 126 | enum mlxsw_sp_fib_entry_type type; |
126 | u8 added:1; | 127 | unsigned int ref_count; |
127 | u16 rif; /* used for action local */ | 128 | u16 rif; /* used for action local */ |
128 | struct mlxsw_sp_vr *vr; | 129 | struct mlxsw_sp_vr *vr; |
129 | struct list_head nexthop_group_node; | 130 | struct list_head nexthop_group_node; |
@@ -171,13 +172,15 @@ static void mlxsw_sp_fib_entry_remove(struct mlxsw_sp_fib *fib, | |||
171 | 172 | ||
172 | static struct mlxsw_sp_fib_entry * | 173 | static struct mlxsw_sp_fib_entry * |
173 | mlxsw_sp_fib_entry_create(struct mlxsw_sp_fib *fib, const void *addr, | 174 | mlxsw_sp_fib_entry_create(struct mlxsw_sp_fib *fib, const void *addr, |
174 | size_t addr_len, unsigned char prefix_len) | 175 | size_t addr_len, unsigned char prefix_len, |
176 | struct net_device *dev) | ||
175 | { | 177 | { |
176 | struct mlxsw_sp_fib_entry *fib_entry; | 178 | struct mlxsw_sp_fib_entry *fib_entry; |
177 | 179 | ||
178 | fib_entry = kzalloc(sizeof(*fib_entry), GFP_KERNEL); | 180 | fib_entry = kzalloc(sizeof(*fib_entry), GFP_KERNEL); |
179 | if (!fib_entry) | 181 | if (!fib_entry) |
180 | return NULL; | 182 | return NULL; |
183 | fib_entry->key.dev = dev; | ||
181 | memcpy(fib_entry->key.addr, addr, addr_len); | 184 | memcpy(fib_entry->key.addr, addr, addr_len); |
182 | fib_entry->key.prefix_len = prefix_len; | 185 | fib_entry->key.prefix_len = prefix_len; |
183 | return fib_entry; | 186 | return fib_entry; |
@@ -190,10 +193,13 @@ static void mlxsw_sp_fib_entry_destroy(struct mlxsw_sp_fib_entry *fib_entry) | |||
190 | 193 | ||
191 | static struct mlxsw_sp_fib_entry * | 194 | static struct mlxsw_sp_fib_entry * |
192 | mlxsw_sp_fib_entry_lookup(struct mlxsw_sp_fib *fib, const void *addr, | 195 | mlxsw_sp_fib_entry_lookup(struct mlxsw_sp_fib *fib, const void *addr, |
193 | size_t addr_len, unsigned char prefix_len) | 196 | size_t addr_len, unsigned char prefix_len, |
197 | struct net_device *dev) | ||
194 | { | 198 | { |
195 | struct mlxsw_sp_fib_key key = {{ 0 } }; | 199 | struct mlxsw_sp_fib_key key; |
196 | 200 | ||
201 | memset(&key, 0, sizeof(key)); | ||
202 | key.dev = dev; | ||
197 | memcpy(key.addr, addr, addr_len); | 203 | memcpy(key.addr, addr, addr_len); |
198 | key.prefix_len = prefix_len; | 204 | key.prefix_len = prefix_len; |
199 | return rhashtable_lookup_fast(&fib->ht, &key, mlxsw_sp_fib_ht_params); | 205 | return rhashtable_lookup_fast(&fib->ht, &key, mlxsw_sp_fib_ht_params); |
@@ -657,7 +663,7 @@ int mlxsw_sp_router_neigh_construct(struct net_device *dev, | |||
657 | return 0; | 663 | return 0; |
658 | } | 664 | } |
659 | 665 | ||
660 | r = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev); | 666 | r = mlxsw_sp_rif_find_by_dev(mlxsw_sp, n->dev); |
661 | if (WARN_ON(!r)) | 667 | if (WARN_ON(!r)) |
662 | return -EINVAL; | 668 | return -EINVAL; |
663 | 669 | ||
@@ -938,8 +944,8 @@ static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work) | |||
938 | mlxsw_sp_port_dev_put(mlxsw_sp_port); | 944 | mlxsw_sp_port_dev_put(mlxsw_sp_port); |
939 | } | 945 | } |
940 | 946 | ||
941 | static int mlxsw_sp_router_netevent_event(struct notifier_block *unused, | 947 | int mlxsw_sp_router_netevent_event(struct notifier_block *unused, |
942 | unsigned long event, void *ptr) | 948 | unsigned long event, void *ptr) |
943 | { | 949 | { |
944 | struct mlxsw_sp_neigh_entry *neigh_entry; | 950 | struct mlxsw_sp_neigh_entry *neigh_entry; |
945 | struct mlxsw_sp_port *mlxsw_sp_port; | 951 | struct mlxsw_sp_port *mlxsw_sp_port; |
@@ -1009,10 +1015,6 @@ static int mlxsw_sp_router_netevent_event(struct notifier_block *unused, | |||
1009 | return NOTIFY_DONE; | 1015 | return NOTIFY_DONE; |
1010 | } | 1016 | } |
1011 | 1017 | ||
1012 | static struct notifier_block mlxsw_sp_router_netevent_nb __read_mostly = { | ||
1013 | .notifier_call = mlxsw_sp_router_netevent_event, | ||
1014 | }; | ||
1015 | |||
1016 | static int mlxsw_sp_neigh_init(struct mlxsw_sp *mlxsw_sp) | 1018 | static int mlxsw_sp_neigh_init(struct mlxsw_sp *mlxsw_sp) |
1017 | { | 1019 | { |
1018 | int err; | 1020 | int err; |
@@ -1027,10 +1029,6 @@ static int mlxsw_sp_neigh_init(struct mlxsw_sp *mlxsw_sp) | |||
1027 | */ | 1029 | */ |
1028 | mlxsw_sp_router_neighs_update_interval_init(mlxsw_sp); | 1030 | mlxsw_sp_router_neighs_update_interval_init(mlxsw_sp); |
1029 | 1031 | ||
1030 | err = register_netevent_notifier(&mlxsw_sp_router_netevent_nb); | ||
1031 | if (err) | ||
1032 | goto err_register_netevent_notifier; | ||
1033 | |||
1034 | /* Create the delayed works for the activity_update */ | 1032 | /* Create the delayed works for the activity_update */ |
1035 | INIT_DELAYED_WORK(&mlxsw_sp->router.neighs_update.dw, | 1033 | INIT_DELAYED_WORK(&mlxsw_sp->router.neighs_update.dw, |
1036 | mlxsw_sp_router_neighs_update_work); | 1034 | mlxsw_sp_router_neighs_update_work); |
@@ -1039,17 +1037,12 @@ static int mlxsw_sp_neigh_init(struct mlxsw_sp *mlxsw_sp) | |||
1039 | mlxsw_core_schedule_dw(&mlxsw_sp->router.neighs_update.dw, 0); | 1037 | mlxsw_core_schedule_dw(&mlxsw_sp->router.neighs_update.dw, 0); |
1040 | mlxsw_core_schedule_dw(&mlxsw_sp->router.nexthop_probe_dw, 0); | 1038 | mlxsw_core_schedule_dw(&mlxsw_sp->router.nexthop_probe_dw, 0); |
1041 | return 0; | 1039 | return 0; |
1042 | |||
1043 | err_register_netevent_notifier: | ||
1044 | rhashtable_destroy(&mlxsw_sp->router.neigh_ht); | ||
1045 | return err; | ||
1046 | } | 1040 | } |
1047 | 1041 | ||
1048 | static void mlxsw_sp_neigh_fini(struct mlxsw_sp *mlxsw_sp) | 1042 | static void mlxsw_sp_neigh_fini(struct mlxsw_sp *mlxsw_sp) |
1049 | { | 1043 | { |
1050 | cancel_delayed_work_sync(&mlxsw_sp->router.neighs_update.dw); | 1044 | cancel_delayed_work_sync(&mlxsw_sp->router.neighs_update.dw); |
1051 | cancel_delayed_work_sync(&mlxsw_sp->router.nexthop_probe_dw); | 1045 | cancel_delayed_work_sync(&mlxsw_sp->router.nexthop_probe_dw); |
1052 | unregister_netevent_notifier(&mlxsw_sp_router_netevent_nb); | ||
1053 | rhashtable_destroy(&mlxsw_sp->router.neigh_ht); | 1046 | rhashtable_destroy(&mlxsw_sp->router.neigh_ht); |
1054 | } | 1047 | } |
1055 | 1048 | ||
@@ -1524,7 +1517,14 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp) | |||
1524 | return err; | 1517 | return err; |
1525 | mlxsw_sp_lpm_init(mlxsw_sp); | 1518 | mlxsw_sp_lpm_init(mlxsw_sp); |
1526 | mlxsw_sp_vrs_init(mlxsw_sp); | 1519 | mlxsw_sp_vrs_init(mlxsw_sp); |
1527 | return mlxsw_sp_neigh_init(mlxsw_sp); | 1520 | err = mlxsw_sp_neigh_init(mlxsw_sp); |
1521 | if (err) | ||
1522 | goto err_neigh_init; | ||
1523 | return 0; | ||
1524 | |||
1525 | err_neigh_init: | ||
1526 | __mlxsw_sp_router_fini(mlxsw_sp); | ||
1527 | return err; | ||
1528 | } | 1528 | } |
1529 | 1529 | ||
1530 | void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp) | 1530 | void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp) |
@@ -1626,11 +1626,8 @@ static int mlxsw_sp_fib_entry_op(struct mlxsw_sp *mlxsw_sp, | |||
1626 | static int mlxsw_sp_fib_entry_update(struct mlxsw_sp *mlxsw_sp, | 1626 | static int mlxsw_sp_fib_entry_update(struct mlxsw_sp *mlxsw_sp, |
1627 | struct mlxsw_sp_fib_entry *fib_entry) | 1627 | struct mlxsw_sp_fib_entry *fib_entry) |
1628 | { | 1628 | { |
1629 | enum mlxsw_reg_ralue_op op; | 1629 | return mlxsw_sp_fib_entry_op(mlxsw_sp, fib_entry, |
1630 | 1630 | MLXSW_REG_RALUE_OP_WRITE_WRITE); | |
1631 | op = !fib_entry->added ? MLXSW_REG_RALUE_OP_WRITE_WRITE : | ||
1632 | MLXSW_REG_RALUE_OP_WRITE_UPDATE; | ||
1633 | return mlxsw_sp_fib_entry_op(mlxsw_sp, fib_entry, op); | ||
1634 | } | 1631 | } |
1635 | 1632 | ||
1636 | static int mlxsw_sp_fib_entry_del(struct mlxsw_sp *mlxsw_sp, | 1633 | static int mlxsw_sp_fib_entry_del(struct mlxsw_sp *mlxsw_sp, |
@@ -1695,34 +1692,93 @@ mlxsw_sp_router_fib4_entry_fini(struct mlxsw_sp *mlxsw_sp, | |||
1695 | mlxsw_sp_nexthop_group_put(mlxsw_sp, fib_entry); | 1692 | mlxsw_sp_nexthop_group_put(mlxsw_sp, fib_entry); |
1696 | } | 1693 | } |
1697 | 1694 | ||
1698 | static int | 1695 | static struct mlxsw_sp_fib_entry * |
1699 | mlxsw_sp_router_fib4_add_prepare(struct mlxsw_sp_port *mlxsw_sp_port, | 1696 | mlxsw_sp_fib_entry_get(struct mlxsw_sp *mlxsw_sp, |
1700 | const struct switchdev_obj_ipv4_fib *fib4, | 1697 | const struct switchdev_obj_ipv4_fib *fib4) |
1701 | struct switchdev_trans *trans) | ||
1702 | { | 1698 | { |
1703 | struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; | ||
1704 | struct mlxsw_sp_router_fib4_add_info *info; | ||
1705 | struct mlxsw_sp_fib_entry *fib_entry; | 1699 | struct mlxsw_sp_fib_entry *fib_entry; |
1700 | struct fib_info *fi = fib4->fi; | ||
1706 | struct mlxsw_sp_vr *vr; | 1701 | struct mlxsw_sp_vr *vr; |
1707 | int err; | 1702 | int err; |
1708 | 1703 | ||
1709 | vr = mlxsw_sp_vr_get(mlxsw_sp, fib4->dst_len, fib4->tb_id, | 1704 | vr = mlxsw_sp_vr_get(mlxsw_sp, fib4->dst_len, fib4->tb_id, |
1710 | MLXSW_SP_L3_PROTO_IPV4); | 1705 | MLXSW_SP_L3_PROTO_IPV4); |
1711 | if (IS_ERR(vr)) | 1706 | if (IS_ERR(vr)) |
1712 | return PTR_ERR(vr); | 1707 | return ERR_CAST(vr); |
1713 | 1708 | ||
1709 | fib_entry = mlxsw_sp_fib_entry_lookup(vr->fib, &fib4->dst, | ||
1710 | sizeof(fib4->dst), | ||
1711 | fib4->dst_len, fi->fib_dev); | ||
1712 | if (fib_entry) { | ||
1713 | /* Already exists, just take a reference */ | ||
1714 | fib_entry->ref_count++; | ||
1715 | return fib_entry; | ||
1716 | } | ||
1714 | fib_entry = mlxsw_sp_fib_entry_create(vr->fib, &fib4->dst, | 1717 | fib_entry = mlxsw_sp_fib_entry_create(vr->fib, &fib4->dst, |
1715 | sizeof(fib4->dst), fib4->dst_len); | 1718 | sizeof(fib4->dst), |
1719 | fib4->dst_len, fi->fib_dev); | ||
1716 | if (!fib_entry) { | 1720 | if (!fib_entry) { |
1717 | err = -ENOMEM; | 1721 | err = -ENOMEM; |
1718 | goto err_fib_entry_create; | 1722 | goto err_fib_entry_create; |
1719 | } | 1723 | } |
1720 | fib_entry->vr = vr; | 1724 | fib_entry->vr = vr; |
1725 | fib_entry->ref_count = 1; | ||
1721 | 1726 | ||
1722 | err = mlxsw_sp_router_fib4_entry_init(mlxsw_sp, fib4, fib_entry); | 1727 | err = mlxsw_sp_router_fib4_entry_init(mlxsw_sp, fib4, fib_entry); |
1723 | if (err) | 1728 | if (err) |
1724 | goto err_fib4_entry_init; | 1729 | goto err_fib4_entry_init; |
1725 | 1730 | ||
1731 | return fib_entry; | ||
1732 | |||
1733 | err_fib4_entry_init: | ||
1734 | mlxsw_sp_fib_entry_destroy(fib_entry); | ||
1735 | err_fib_entry_create: | ||
1736 | mlxsw_sp_vr_put(mlxsw_sp, vr); | ||
1737 | |||
1738 | return ERR_PTR(err); | ||
1739 | } | ||
1740 | |||
1741 | static struct mlxsw_sp_fib_entry * | ||
1742 | mlxsw_sp_fib_entry_find(struct mlxsw_sp *mlxsw_sp, | ||
1743 | const struct switchdev_obj_ipv4_fib *fib4) | ||
1744 | { | ||
1745 | struct mlxsw_sp_vr *vr; | ||
1746 | |||
1747 | vr = mlxsw_sp_vr_find(mlxsw_sp, fib4->tb_id, MLXSW_SP_L3_PROTO_IPV4); | ||
1748 | if (!vr) | ||
1749 | return NULL; | ||
1750 | |||
1751 | return mlxsw_sp_fib_entry_lookup(vr->fib, &fib4->dst, | ||
1752 | sizeof(fib4->dst), fib4->dst_len, | ||
1753 | fib4->fi->fib_dev); | ||
1754 | } | ||
1755 | |||
1756 | void mlxsw_sp_fib_entry_put(struct mlxsw_sp *mlxsw_sp, | ||
1757 | struct mlxsw_sp_fib_entry *fib_entry) | ||
1758 | { | ||
1759 | struct mlxsw_sp_vr *vr = fib_entry->vr; | ||
1760 | |||
1761 | if (--fib_entry->ref_count == 0) { | ||
1762 | mlxsw_sp_router_fib4_entry_fini(mlxsw_sp, fib_entry); | ||
1763 | mlxsw_sp_fib_entry_destroy(fib_entry); | ||
1764 | } | ||
1765 | mlxsw_sp_vr_put(mlxsw_sp, vr); | ||
1766 | } | ||
1767 | |||
1768 | static int | ||
1769 | mlxsw_sp_router_fib4_add_prepare(struct mlxsw_sp_port *mlxsw_sp_port, | ||
1770 | const struct switchdev_obj_ipv4_fib *fib4, | ||
1771 | struct switchdev_trans *trans) | ||
1772 | { | ||
1773 | struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; | ||
1774 | struct mlxsw_sp_router_fib4_add_info *info; | ||
1775 | struct mlxsw_sp_fib_entry *fib_entry; | ||
1776 | int err; | ||
1777 | |||
1778 | fib_entry = mlxsw_sp_fib_entry_get(mlxsw_sp, fib4); | ||
1779 | if (IS_ERR(fib_entry)) | ||
1780 | return PTR_ERR(fib_entry); | ||
1781 | |||
1726 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 1782 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
1727 | if (!info) { | 1783 | if (!info) { |
1728 | err = -ENOMEM; | 1784 | err = -ENOMEM; |
@@ -1736,11 +1792,7 @@ mlxsw_sp_router_fib4_add_prepare(struct mlxsw_sp_port *mlxsw_sp_port, | |||
1736 | return 0; | 1792 | return 0; |
1737 | 1793 | ||
1738 | err_alloc_info: | 1794 | err_alloc_info: |
1739 | mlxsw_sp_router_fib4_entry_fini(mlxsw_sp, fib_entry); | 1795 | mlxsw_sp_fib_entry_put(mlxsw_sp, fib_entry); |
1740 | err_fib4_entry_init: | ||
1741 | mlxsw_sp_fib_entry_destroy(fib_entry); | ||
1742 | err_fib_entry_create: | ||
1743 | mlxsw_sp_vr_put(mlxsw_sp, vr); | ||
1744 | return err; | 1796 | return err; |
1745 | } | 1797 | } |
1746 | 1798 | ||
@@ -1759,11 +1811,14 @@ mlxsw_sp_router_fib4_add_commit(struct mlxsw_sp_port *mlxsw_sp_port, | |||
1759 | fib_entry = info->fib_entry; | 1811 | fib_entry = info->fib_entry; |
1760 | kfree(info); | 1812 | kfree(info); |
1761 | 1813 | ||
1814 | if (fib_entry->ref_count != 1) | ||
1815 | return 0; | ||
1816 | |||
1762 | vr = fib_entry->vr; | 1817 | vr = fib_entry->vr; |
1763 | err = mlxsw_sp_fib_entry_insert(fib_entry->vr->fib, fib_entry); | 1818 | err = mlxsw_sp_fib_entry_insert(vr->fib, fib_entry); |
1764 | if (err) | 1819 | if (err) |
1765 | goto err_fib_entry_insert; | 1820 | goto err_fib_entry_insert; |
1766 | err = mlxsw_sp_fib_entry_update(mlxsw_sp, fib_entry); | 1821 | err = mlxsw_sp_fib_entry_update(mlxsw_sp_port->mlxsw_sp, fib_entry); |
1767 | if (err) | 1822 | if (err) |
1768 | goto err_fib_entry_add; | 1823 | goto err_fib_entry_add; |
1769 | return 0; | 1824 | return 0; |
@@ -1771,9 +1826,7 @@ mlxsw_sp_router_fib4_add_commit(struct mlxsw_sp_port *mlxsw_sp_port, | |||
1771 | err_fib_entry_add: | 1826 | err_fib_entry_add: |
1772 | mlxsw_sp_fib_entry_remove(vr->fib, fib_entry); | 1827 | mlxsw_sp_fib_entry_remove(vr->fib, fib_entry); |
1773 | err_fib_entry_insert: | 1828 | err_fib_entry_insert: |
1774 | mlxsw_sp_router_fib4_entry_fini(mlxsw_sp, fib_entry); | 1829 | mlxsw_sp_fib_entry_put(mlxsw_sp, fib_entry); |
1775 | mlxsw_sp_fib_entry_destroy(fib_entry); | ||
1776 | mlxsw_sp_vr_put(mlxsw_sp, vr); | ||
1777 | return err; | 1830 | return err; |
1778 | } | 1831 | } |
1779 | 1832 | ||
@@ -1793,23 +1846,18 @@ int mlxsw_sp_router_fib4_del(struct mlxsw_sp_port *mlxsw_sp_port, | |||
1793 | { | 1846 | { |
1794 | struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; | 1847 | struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; |
1795 | struct mlxsw_sp_fib_entry *fib_entry; | 1848 | struct mlxsw_sp_fib_entry *fib_entry; |
1796 | struct mlxsw_sp_vr *vr; | ||
1797 | 1849 | ||
1798 | vr = mlxsw_sp_vr_find(mlxsw_sp, fib4->tb_id, MLXSW_SP_L3_PROTO_IPV4); | 1850 | fib_entry = mlxsw_sp_fib_entry_find(mlxsw_sp, fib4); |
1799 | if (!vr) { | ||
1800 | dev_warn(mlxsw_sp->bus_info->dev, "Failed to find virtual router for FIB4 entry being removed.\n"); | ||
1801 | return -ENOENT; | ||
1802 | } | ||
1803 | fib_entry = mlxsw_sp_fib_entry_lookup(vr->fib, &fib4->dst, | ||
1804 | sizeof(fib4->dst), fib4->dst_len); | ||
1805 | if (!fib_entry) { | 1851 | if (!fib_entry) { |
1806 | dev_warn(mlxsw_sp->bus_info->dev, "Failed to find FIB4 entry being removed.\n"); | 1852 | dev_warn(mlxsw_sp->bus_info->dev, "Failed to find FIB4 entry being removed.\n"); |
1807 | return -ENOENT; | 1853 | return -ENOENT; |
1808 | } | 1854 | } |
1809 | mlxsw_sp_fib_entry_del(mlxsw_sp_port->mlxsw_sp, fib_entry); | 1855 | |
1810 | mlxsw_sp_fib_entry_remove(vr->fib, fib_entry); | 1856 | if (fib_entry->ref_count == 1) { |
1811 | mlxsw_sp_router_fib4_entry_fini(mlxsw_sp, fib_entry); | 1857 | mlxsw_sp_fib_entry_del(mlxsw_sp, fib_entry); |
1812 | mlxsw_sp_fib_entry_destroy(fib_entry); | 1858 | mlxsw_sp_fib_entry_remove(fib_entry->vr->fib, fib_entry); |
1813 | mlxsw_sp_vr_put(mlxsw_sp, vr); | 1859 | } |
1860 | |||
1861 | mlxsw_sp_fib_entry_put(mlxsw_sp, fib_entry); | ||
1814 | return 0; | 1862 | return 0; |
1815 | } | 1863 | } |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c index d1b59cdfacc1..7b654c517b91 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | |||
@@ -167,8 +167,8 @@ static int mlxsw_sp_port_attr_stp_state_set(struct mlxsw_sp_port *mlxsw_sp_port, | |||
167 | } | 167 | } |
168 | 168 | ||
169 | static int __mlxsw_sp_port_flood_set(struct mlxsw_sp_port *mlxsw_sp_port, | 169 | static int __mlxsw_sp_port_flood_set(struct mlxsw_sp_port *mlxsw_sp_port, |
170 | u16 idx_begin, u16 idx_end, bool set, | 170 | u16 idx_begin, u16 idx_end, bool uc_set, |
171 | bool only_uc) | 171 | bool bm_set) |
172 | { | 172 | { |
173 | struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; | 173 | struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; |
174 | u16 local_port = mlxsw_sp_port->local_port; | 174 | u16 local_port = mlxsw_sp_port->local_port; |
@@ -187,28 +187,22 @@ static int __mlxsw_sp_port_flood_set(struct mlxsw_sp_port *mlxsw_sp_port, | |||
187 | return -ENOMEM; | 187 | return -ENOMEM; |
188 | 188 | ||
189 | mlxsw_reg_sftr_pack(sftr_pl, MLXSW_SP_FLOOD_TABLE_UC, idx_begin, | 189 | mlxsw_reg_sftr_pack(sftr_pl, MLXSW_SP_FLOOD_TABLE_UC, idx_begin, |
190 | table_type, range, local_port, set); | 190 | table_type, range, local_port, uc_set); |
191 | err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sftr), sftr_pl); | 191 | err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sftr), sftr_pl); |
192 | if (err) | 192 | if (err) |
193 | goto buffer_out; | 193 | goto buffer_out; |
194 | 194 | ||
195 | /* Flooding control allows one to decide whether a given port will | ||
196 | * flood unicast traffic for which there is no FDB entry. | ||
197 | */ | ||
198 | if (only_uc) | ||
199 | goto buffer_out; | ||
200 | |||
201 | mlxsw_reg_sftr_pack(sftr_pl, MLXSW_SP_FLOOD_TABLE_BM, idx_begin, | 195 | mlxsw_reg_sftr_pack(sftr_pl, MLXSW_SP_FLOOD_TABLE_BM, idx_begin, |
202 | table_type, range, local_port, set); | 196 | table_type, range, local_port, bm_set); |
203 | err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sftr), sftr_pl); | 197 | err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sftr), sftr_pl); |
204 | if (err) | 198 | if (err) |
205 | goto err_flood_bm_set; | 199 | goto err_flood_bm_set; |
206 | else | 200 | |
207 | goto buffer_out; | 201 | goto buffer_out; |
208 | 202 | ||
209 | err_flood_bm_set: | 203 | err_flood_bm_set: |
210 | mlxsw_reg_sftr_pack(sftr_pl, MLXSW_SP_FLOOD_TABLE_UC, idx_begin, | 204 | mlxsw_reg_sftr_pack(sftr_pl, MLXSW_SP_FLOOD_TABLE_UC, idx_begin, |
211 | table_type, range, local_port, !set); | 205 | table_type, range, local_port, !uc_set); |
212 | mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sftr), sftr_pl); | 206 | mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sftr), sftr_pl); |
213 | buffer_out: | 207 | buffer_out: |
214 | kfree(sftr_pl); | 208 | kfree(sftr_pl); |
@@ -257,8 +251,7 @@ int mlxsw_sp_vport_flood_set(struct mlxsw_sp_port *mlxsw_sp_vport, u16 fid, | |||
257 | * the start of the vFIDs range. | 251 | * the start of the vFIDs range. |
258 | */ | 252 | */ |
259 | vfid = mlxsw_sp_fid_to_vfid(fid); | 253 | vfid = mlxsw_sp_fid_to_vfid(fid); |
260 | return __mlxsw_sp_port_flood_set(mlxsw_sp_vport, vfid, vfid, set, | 254 | return __mlxsw_sp_port_flood_set(mlxsw_sp_vport, vfid, vfid, set, set); |
261 | false); | ||
262 | } | 255 | } |
263 | 256 | ||
264 | static int mlxsw_sp_port_attr_br_flags_set(struct mlxsw_sp_port *mlxsw_sp_port, | 257 | static int mlxsw_sp_port_attr_br_flags_set(struct mlxsw_sp_port *mlxsw_sp_port, |
@@ -460,6 +453,9 @@ static int __mlxsw_sp_port_fid_join(struct mlxsw_sp_port *mlxsw_sp_port, | |||
460 | { | 453 | { |
461 | struct mlxsw_sp_fid *f; | 454 | struct mlxsw_sp_fid *f; |
462 | 455 | ||
456 | if (test_bit(fid, mlxsw_sp_port->active_vlans)) | ||
457 | return 0; | ||
458 | |||
463 | f = mlxsw_sp_fid_find(mlxsw_sp_port->mlxsw_sp, fid); | 459 | f = mlxsw_sp_fid_find(mlxsw_sp_port->mlxsw_sp, fid); |
464 | if (!f) { | 460 | if (!f) { |
465 | f = mlxsw_sp_fid_create(mlxsw_sp_port->mlxsw_sp, fid); | 461 | f = mlxsw_sp_fid_create(mlxsw_sp_port->mlxsw_sp, fid); |
@@ -517,7 +513,7 @@ static int mlxsw_sp_port_fid_join(struct mlxsw_sp_port *mlxsw_sp_port, | |||
517 | } | 513 | } |
518 | 514 | ||
519 | err = __mlxsw_sp_port_flood_set(mlxsw_sp_port, fid_begin, fid_end, | 515 | err = __mlxsw_sp_port_flood_set(mlxsw_sp_port, fid_begin, fid_end, |
520 | true, false); | 516 | mlxsw_sp_port->uc_flood, true); |
521 | if (err) | 517 | if (err) |
522 | goto err_port_flood_set; | 518 | goto err_port_flood_set; |
523 | 519 | ||
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index 88678c172b19..39dadfca84ef 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c | |||
@@ -41,7 +41,6 @@ | |||
41 | * Chris Telfer <chris.telfer@netronome.com> | 41 | * Chris Telfer <chris.telfer@netronome.com> |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/version.h> | ||
45 | #include <linux/module.h> | 44 | #include <linux/module.h> |
46 | #include <linux/kernel.h> | 45 | #include <linux/kernel.h> |
47 | #include <linux/init.h> | 46 | #include <linux/init.h> |
@@ -1441,10 +1440,6 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget) | |||
1441 | 1440 | ||
1442 | nfp_net_set_hash(nn->netdev, skb, rxd); | 1441 | nfp_net_set_hash(nn->netdev, skb, rxd); |
1443 | 1442 | ||
1444 | /* Pad small frames to minimum */ | ||
1445 | if (skb_put_padto(skb, 60)) | ||
1446 | break; | ||
1447 | |||
1448 | /* Stats update */ | 1443 | /* Stats update */ |
1449 | u64_stats_update_begin(&r_vec->rx_sync); | 1444 | u64_stats_update_begin(&r_vec->rx_sync); |
1450 | r_vec->rx_pkts++; | 1445 | r_vec->rx_pkts++; |
@@ -2049,12 +2044,16 @@ static int nfp_net_netdev_open(struct net_device *netdev) | |||
2049 | 2044 | ||
2050 | nn->rx_rings = kcalloc(nn->num_rx_rings, sizeof(*nn->rx_rings), | 2045 | nn->rx_rings = kcalloc(nn->num_rx_rings, sizeof(*nn->rx_rings), |
2051 | GFP_KERNEL); | 2046 | GFP_KERNEL); |
2052 | if (!nn->rx_rings) | 2047 | if (!nn->rx_rings) { |
2048 | err = -ENOMEM; | ||
2053 | goto err_free_lsc; | 2049 | goto err_free_lsc; |
2050 | } | ||
2054 | nn->tx_rings = kcalloc(nn->num_tx_rings, sizeof(*nn->tx_rings), | 2051 | nn->tx_rings = kcalloc(nn->num_tx_rings, sizeof(*nn->tx_rings), |
2055 | GFP_KERNEL); | 2052 | GFP_KERNEL); |
2056 | if (!nn->tx_rings) | 2053 | if (!nn->tx_rings) { |
2054 | err = -ENOMEM; | ||
2057 | goto err_free_rx_rings; | 2055 | goto err_free_rx_rings; |
2056 | } | ||
2058 | 2057 | ||
2059 | for (r = 0; r < nn->num_r_vecs; r++) { | 2058 | for (r = 0; r < nn->num_r_vecs; r++) { |
2060 | err = nfp_net_prepare_vector(nn, &nn->r_vecs[r], r); | 2059 | err = nfp_net_prepare_vector(nn, &nn->r_vecs[r], r); |
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c index 7d7933d00b8f..4c9897220969 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c | |||
@@ -40,7 +40,6 @@ | |||
40 | * Brad Petrus <brad.petrus@netronome.com> | 40 | * Brad Petrus <brad.petrus@netronome.com> |
41 | */ | 41 | */ |
42 | 42 | ||
43 | #include <linux/version.h> | ||
44 | #include <linux/kernel.h> | 43 | #include <linux/kernel.h> |
45 | #include <linux/netdevice.h> | 44 | #include <linux/netdevice.h> |
46 | #include <linux/etherdevice.h> | 45 | #include <linux/etherdevice.h> |
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_netvf_main.c b/drivers/net/ethernet/netronome/nfp/nfp_netvf_main.c index 37abef016a0a..f7062cb648e1 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_netvf_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_netvf_main.c | |||
@@ -38,7 +38,6 @@ | |||
38 | * Rolf Neugebauer <rolf.neugebauer@netronome.com> | 38 | * Rolf Neugebauer <rolf.neugebauer@netronome.com> |
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include <linux/version.h> | ||
42 | #include <linux/module.h> | 41 | #include <linux/module.h> |
43 | #include <linux/kernel.h> | 42 | #include <linux/kernel.h> |
44 | #include <linux/init.h> | 43 | #include <linux/init.h> |
@@ -134,7 +133,7 @@ static int nfp_netvf_pci_probe(struct pci_dev *pdev, | |||
134 | } | 133 | } |
135 | 134 | ||
136 | nfp_net_get_fw_version(&fw_ver, ctrl_bar); | 135 | nfp_net_get_fw_version(&fw_ver, ctrl_bar); |
137 | if (fw_ver.class != NFP_NET_CFG_VERSION_CLASS_GENERIC) { | 136 | if (fw_ver.resv || fw_ver.class != NFP_NET_CFG_VERSION_CLASS_GENERIC) { |
138 | dev_err(&pdev->dev, "Unknown Firmware ABI %d.%d.%d.%d\n", | 137 | dev_err(&pdev->dev, "Unknown Firmware ABI %d.%d.%d.%d\n", |
139 | fw_ver.resv, fw_ver.class, fw_ver.major, fw_ver.minor); | 138 | fw_ver.resv, fw_ver.class, fw_ver.major, fw_ver.minor); |
140 | err = -EINVAL; | 139 | err = -EINVAL; |
@@ -142,9 +141,7 @@ static int nfp_netvf_pci_probe(struct pci_dev *pdev, | |||
142 | } | 141 | } |
143 | 142 | ||
144 | /* Determine stride */ | 143 | /* Determine stride */ |
145 | if (nfp_net_fw_ver_eq(&fw_ver, 0, 0, 0, 0) || | 144 | if (nfp_net_fw_ver_eq(&fw_ver, 0, 0, 0, 1)) { |
146 | nfp_net_fw_ver_eq(&fw_ver, 0, 0, 0, 1) || | ||
147 | nfp_net_fw_ver_eq(&fw_ver, 0, 0, 0x12, 0x48)) { | ||
148 | stride = 2; | 145 | stride = 2; |
149 | tx_bar_no = NFP_NET_Q0_BAR; | 146 | tx_bar_no = NFP_NET_Q0_BAR; |
150 | rx_bar_no = NFP_NET_Q1_BAR; | 147 | rx_bar_no = NFP_NET_Q1_BAR; |
diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c index 4d4ecba0aad9..8e13ec84c538 100644 --- a/drivers/net/ethernet/nxp/lpc_eth.c +++ b/drivers/net/ethernet/nxp/lpc_eth.c | |||
@@ -475,14 +475,6 @@ static void __lpc_get_mac(struct netdata_local *pldat, u8 *mac) | |||
475 | mac[5] = tmp >> 8; | 475 | mac[5] = tmp >> 8; |
476 | } | 476 | } |
477 | 477 | ||
478 | static void __lpc_eth_clock_enable(struct netdata_local *pldat, bool enable) | ||
479 | { | ||
480 | if (enable) | ||
481 | clk_prepare_enable(pldat->clk); | ||
482 | else | ||
483 | clk_disable_unprepare(pldat->clk); | ||
484 | } | ||
485 | |||
486 | static void __lpc_params_setup(struct netdata_local *pldat) | 478 | static void __lpc_params_setup(struct netdata_local *pldat) |
487 | { | 479 | { |
488 | u32 tmp; | 480 | u32 tmp; |
@@ -1056,7 +1048,7 @@ static int lpc_eth_close(struct net_device *ndev) | |||
1056 | writel(0, LPC_ENET_MAC2(pldat->net_base)); | 1048 | writel(0, LPC_ENET_MAC2(pldat->net_base)); |
1057 | spin_unlock_irqrestore(&pldat->lock, flags); | 1049 | spin_unlock_irqrestore(&pldat->lock, flags); |
1058 | 1050 | ||
1059 | __lpc_eth_clock_enable(pldat, false); | 1051 | clk_disable_unprepare(pldat->clk); |
1060 | 1052 | ||
1061 | return 0; | 1053 | return 0; |
1062 | } | 1054 | } |
@@ -1197,11 +1189,14 @@ static int lpc_eth_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) | |||
1197 | static int lpc_eth_open(struct net_device *ndev) | 1189 | static int lpc_eth_open(struct net_device *ndev) |
1198 | { | 1190 | { |
1199 | struct netdata_local *pldat = netdev_priv(ndev); | 1191 | struct netdata_local *pldat = netdev_priv(ndev); |
1192 | int ret; | ||
1200 | 1193 | ||
1201 | if (netif_msg_ifup(pldat)) | 1194 | if (netif_msg_ifup(pldat)) |
1202 | dev_dbg(&pldat->pdev->dev, "enabling %s\n", ndev->name); | 1195 | dev_dbg(&pldat->pdev->dev, "enabling %s\n", ndev->name); |
1203 | 1196 | ||
1204 | __lpc_eth_clock_enable(pldat, true); | 1197 | ret = clk_prepare_enable(pldat->clk); |
1198 | if (ret) | ||
1199 | return ret; | ||
1205 | 1200 | ||
1206 | /* Suspended PHY makes LPC ethernet core block, so resume now */ | 1201 | /* Suspended PHY makes LPC ethernet core block, so resume now */ |
1207 | phy_resume(ndev->phydev); | 1202 | phy_resume(ndev->phydev); |
@@ -1320,7 +1315,9 @@ static int lpc_eth_drv_probe(struct platform_device *pdev) | |||
1320 | } | 1315 | } |
1321 | 1316 | ||
1322 | /* Enable network clock */ | 1317 | /* Enable network clock */ |
1323 | __lpc_eth_clock_enable(pldat, true); | 1318 | ret = clk_prepare_enable(pldat->clk); |
1319 | if (ret) | ||
1320 | goto err_out_clk_put; | ||
1324 | 1321 | ||
1325 | /* Map IO space */ | 1322 | /* Map IO space */ |
1326 | pldat->net_base = ioremap(res->start, resource_size(res)); | 1323 | pldat->net_base = ioremap(res->start, resource_size(res)); |
@@ -1454,6 +1451,7 @@ err_out_iounmap: | |||
1454 | iounmap(pldat->net_base); | 1451 | iounmap(pldat->net_base); |
1455 | err_out_disable_clocks: | 1452 | err_out_disable_clocks: |
1456 | clk_disable_unprepare(pldat->clk); | 1453 | clk_disable_unprepare(pldat->clk); |
1454 | err_out_clk_put: | ||
1457 | clk_put(pldat->clk); | 1455 | clk_put(pldat->clk); |
1458 | err_out_free_dev: | 1456 | err_out_free_dev: |
1459 | free_netdev(ndev); | 1457 | free_netdev(ndev); |
diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h index 35e53771533f..45ab74676573 100644 --- a/drivers/net/ethernet/qlogic/qed/qed.h +++ b/drivers/net/ethernet/qlogic/qed/qed.h | |||
@@ -561,9 +561,18 @@ struct qed_dev { | |||
561 | static inline u8 qed_concrete_to_sw_fid(struct qed_dev *cdev, | 561 | static inline u8 qed_concrete_to_sw_fid(struct qed_dev *cdev, |
562 | u32 concrete_fid) | 562 | u32 concrete_fid) |
563 | { | 563 | { |
564 | u8 vfid = GET_FIELD(concrete_fid, PXP_CONCRETE_FID_VFID); | ||
564 | u8 pfid = GET_FIELD(concrete_fid, PXP_CONCRETE_FID_PFID); | 565 | u8 pfid = GET_FIELD(concrete_fid, PXP_CONCRETE_FID_PFID); |
566 | u8 vf_valid = GET_FIELD(concrete_fid, | ||
567 | PXP_CONCRETE_FID_VFVALID); | ||
568 | u8 sw_fid; | ||
565 | 569 | ||
566 | return pfid; | 570 | if (vf_valid) |
571 | sw_fid = vfid + MAX_NUM_PFS; | ||
572 | else | ||
573 | sw_fid = pfid; | ||
574 | |||
575 | return sw_fid; | ||
567 | } | 576 | } |
568 | 577 | ||
569 | #define PURE_LB_TC 8 | 578 | #define PURE_LB_TC 8 |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c index 226cb08cc055..3656d2fd673d 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include "qed_dcbx.h" | 19 | #include "qed_dcbx.h" |
20 | #include "qed_hsi.h" | 20 | #include "qed_hsi.h" |
21 | #include "qed_sp.h" | 21 | #include "qed_sp.h" |
22 | #include "qed_sriov.h" | ||
22 | #ifdef CONFIG_DCB | 23 | #ifdef CONFIG_DCB |
23 | #include <linux/qed/qed_eth_if.h> | 24 | #include <linux/qed/qed_eth_if.h> |
24 | #endif | 25 | #endif |
@@ -945,6 +946,9 @@ static int qed_dcbx_query_params(struct qed_hwfn *p_hwfn, | |||
945 | struct qed_ptt *p_ptt; | 946 | struct qed_ptt *p_ptt; |
946 | int rc; | 947 | int rc; |
947 | 948 | ||
949 | if (IS_VF(p_hwfn->cdev)) | ||
950 | return -EINVAL; | ||
951 | |||
948 | p_ptt = qed_ptt_acquire(p_hwfn); | 952 | p_ptt = qed_ptt_acquire(p_hwfn); |
949 | if (!p_ptt) | 953 | if (!p_ptt) |
950 | return -EBUSY; | 954 | return -EBUSY; |
@@ -984,6 +988,7 @@ qed_dcbx_set_pfc_data(struct qed_hwfn *p_hwfn, | |||
984 | if (p_params->pfc.prio[i]) | 988 | if (p_params->pfc.prio[i]) |
985 | pfc_map |= BIT(i); | 989 | pfc_map |= BIT(i); |
986 | 990 | ||
991 | *pfc &= ~DCBX_PFC_PRI_EN_BITMAP_MASK; | ||
987 | *pfc |= (pfc_map << DCBX_PFC_PRI_EN_BITMAP_SHIFT); | 992 | *pfc |= (pfc_map << DCBX_PFC_PRI_EN_BITMAP_SHIFT); |
988 | 993 | ||
989 | DP_VERBOSE(p_hwfn, QED_MSG_DCB, "pfc = 0x%x\n", *pfc); | 994 | DP_VERBOSE(p_hwfn, QED_MSG_DCB, "pfc = 0x%x\n", *pfc); |
@@ -1058,24 +1063,33 @@ qed_dcbx_set_app_data(struct qed_hwfn *p_hwfn, | |||
1058 | 1063 | ||
1059 | for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) { | 1064 | for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) { |
1060 | entry = &p_app->app_pri_tbl[i].entry; | 1065 | entry = &p_app->app_pri_tbl[i].entry; |
1066 | *entry = 0; | ||
1061 | if (ieee) { | 1067 | if (ieee) { |
1062 | *entry &= ~DCBX_APP_SF_IEEE_MASK; | 1068 | *entry &= ~(DCBX_APP_SF_IEEE_MASK | DCBX_APP_SF_MASK); |
1063 | switch (p_params->app_entry[i].sf_ieee) { | 1069 | switch (p_params->app_entry[i].sf_ieee) { |
1064 | case QED_DCBX_SF_IEEE_ETHTYPE: | 1070 | case QED_DCBX_SF_IEEE_ETHTYPE: |
1065 | *entry |= ((u32)DCBX_APP_SF_IEEE_ETHTYPE << | 1071 | *entry |= ((u32)DCBX_APP_SF_IEEE_ETHTYPE << |
1066 | DCBX_APP_SF_IEEE_SHIFT); | 1072 | DCBX_APP_SF_IEEE_SHIFT); |
1073 | *entry |= ((u32)DCBX_APP_SF_ETHTYPE << | ||
1074 | DCBX_APP_SF_SHIFT); | ||
1067 | break; | 1075 | break; |
1068 | case QED_DCBX_SF_IEEE_TCP_PORT: | 1076 | case QED_DCBX_SF_IEEE_TCP_PORT: |
1069 | *entry |= ((u32)DCBX_APP_SF_IEEE_TCP_PORT << | 1077 | *entry |= ((u32)DCBX_APP_SF_IEEE_TCP_PORT << |
1070 | DCBX_APP_SF_IEEE_SHIFT); | 1078 | DCBX_APP_SF_IEEE_SHIFT); |
1079 | *entry |= ((u32)DCBX_APP_SF_PORT << | ||
1080 | DCBX_APP_SF_SHIFT); | ||
1071 | break; | 1081 | break; |
1072 | case QED_DCBX_SF_IEEE_UDP_PORT: | 1082 | case QED_DCBX_SF_IEEE_UDP_PORT: |
1073 | *entry |= ((u32)DCBX_APP_SF_IEEE_UDP_PORT << | 1083 | *entry |= ((u32)DCBX_APP_SF_IEEE_UDP_PORT << |
1074 | DCBX_APP_SF_IEEE_SHIFT); | 1084 | DCBX_APP_SF_IEEE_SHIFT); |
1085 | *entry |= ((u32)DCBX_APP_SF_PORT << | ||
1086 | DCBX_APP_SF_SHIFT); | ||
1075 | break; | 1087 | break; |
1076 | case QED_DCBX_SF_IEEE_TCP_UDP_PORT: | 1088 | case QED_DCBX_SF_IEEE_TCP_UDP_PORT: |
1077 | *entry |= ((u32)DCBX_APP_SF_IEEE_TCP_UDP_PORT << | 1089 | *entry |= ((u32)DCBX_APP_SF_IEEE_TCP_UDP_PORT << |
1078 | DCBX_APP_SF_IEEE_SHIFT); | 1090 | DCBX_APP_SF_IEEE_SHIFT); |
1091 | *entry |= ((u32)DCBX_APP_SF_PORT << | ||
1092 | DCBX_APP_SF_SHIFT); | ||
1079 | break; | 1093 | break; |
1080 | } | 1094 | } |
1081 | } else { | 1095 | } else { |
@@ -1175,7 +1189,7 @@ int qed_dcbx_get_config_params(struct qed_hwfn *p_hwfn, | |||
1175 | return 0; | 1189 | return 0; |
1176 | } | 1190 | } |
1177 | 1191 | ||
1178 | dcbx_info = kmalloc(sizeof(*dcbx_info), GFP_KERNEL); | 1192 | dcbx_info = kzalloc(sizeof(*dcbx_info), GFP_KERNEL); |
1179 | if (!dcbx_info) { | 1193 | if (!dcbx_info) { |
1180 | DP_ERR(p_hwfn, "Failed to allocate struct qed_dcbx_info\n"); | 1194 | DP_ERR(p_hwfn, "Failed to allocate struct qed_dcbx_info\n"); |
1181 | return -ENOMEM; | 1195 | return -ENOMEM; |
@@ -1212,7 +1226,7 @@ static struct qed_dcbx_get *qed_dcbnl_get_dcbx(struct qed_hwfn *hwfn, | |||
1212 | { | 1226 | { |
1213 | struct qed_dcbx_get *dcbx_info; | 1227 | struct qed_dcbx_get *dcbx_info; |
1214 | 1228 | ||
1215 | dcbx_info = kmalloc(sizeof(*dcbx_info), GFP_KERNEL); | 1229 | dcbx_info = kzalloc(sizeof(*dcbx_info), GFP_KERNEL); |
1216 | if (!dcbx_info) { | 1230 | if (!dcbx_info) { |
1217 | DP_ERR(hwfn->cdev, "Failed to allocate memory for dcbx_info\n"); | 1231 | DP_ERR(hwfn->cdev, "Failed to allocate memory for dcbx_info\n"); |
1218 | return NULL; | 1232 | return NULL; |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c index a240f26344a4..f776a77794c5 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c | |||
@@ -1153,8 +1153,8 @@ qed_mcp_send_drv_version(struct qed_hwfn *p_hwfn, | |||
1153 | p_drv_version = &union_data.drv_version; | 1153 | p_drv_version = &union_data.drv_version; |
1154 | p_drv_version->version = p_ver->version; | 1154 | p_drv_version->version = p_ver->version; |
1155 | 1155 | ||
1156 | for (i = 0; i < MCP_DRV_VER_STR_SIZE - 1; i += 4) { | 1156 | for (i = 0; i < (MCP_DRV_VER_STR_SIZE - 4) / sizeof(u32); i++) { |
1157 | val = cpu_to_be32(p_ver->name[i]); | 1157 | val = cpu_to_be32(*((u32 *)&p_ver->name[i * sizeof(u32)])); |
1158 | *(__be32 *)&p_drv_version->name[i * sizeof(u32)] = val; | 1158 | *(__be32 *)&p_drv_version->name[i * sizeof(u32)] = val; |
1159 | } | 1159 | } |
1160 | 1160 | ||
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index e4bd02e46e57..9544e4c41359 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c | |||
@@ -722,11 +722,14 @@ netdev_tx_t qede_start_xmit(struct sk_buff *skb, | |||
722 | txq->tx_db.data.bd_prod = | 722 | txq->tx_db.data.bd_prod = |
723 | cpu_to_le16(qed_chain_get_prod_idx(&txq->tx_pbl)); | 723 | cpu_to_le16(qed_chain_get_prod_idx(&txq->tx_pbl)); |
724 | 724 | ||
725 | if (!skb->xmit_more || netif_tx_queue_stopped(netdev_txq)) | 725 | if (!skb->xmit_more || netif_xmit_stopped(netdev_txq)) |
726 | qede_update_tx_producer(txq); | 726 | qede_update_tx_producer(txq); |
727 | 727 | ||
728 | if (unlikely(qed_chain_get_elem_left(&txq->tx_pbl) | 728 | if (unlikely(qed_chain_get_elem_left(&txq->tx_pbl) |
729 | < (MAX_SKB_FRAGS + 1))) { | 729 | < (MAX_SKB_FRAGS + 1))) { |
730 | if (skb->xmit_more) | ||
731 | qede_update_tx_producer(txq); | ||
732 | |||
730 | netif_tx_stop_queue(netdev_txq); | 733 | netif_tx_stop_queue(netdev_txq); |
731 | DP_VERBOSE(edev, NETIF_MSG_TX_QUEUED, | 734 | DP_VERBOSE(edev, NETIF_MSG_TX_QUEUED, |
732 | "Stop queue was called\n"); | 735 | "Stop queue was called\n"); |
@@ -2517,7 +2520,8 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level, | |||
2517 | edev->ops->register_ops(cdev, &qede_ll_ops, edev); | 2520 | edev->ops->register_ops(cdev, &qede_ll_ops, edev); |
2518 | 2521 | ||
2519 | #ifdef CONFIG_DCB | 2522 | #ifdef CONFIG_DCB |
2520 | qede_set_dcbnl_ops(edev->ndev); | 2523 | if (!IS_VF(edev)) |
2524 | qede_set_dcbnl_ops(edev->ndev); | ||
2521 | #endif | 2525 | #endif |
2522 | 2526 | ||
2523 | INIT_DELAYED_WORK(&edev->sp_task, qede_sp_task); | 2527 | INIT_DELAYED_WORK(&edev->sp_task, qede_sp_task); |
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index deae10d7426d..5297bf77211c 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c | |||
@@ -467,8 +467,8 @@ static int cp_rx_poll(struct napi_struct *napi, int budget) | |||
467 | unsigned int rx_tail = cp->rx_tail; | 467 | unsigned int rx_tail = cp->rx_tail; |
468 | int rx; | 468 | int rx; |
469 | 469 | ||
470 | rx_status_loop: | ||
471 | rx = 0; | 470 | rx = 0; |
471 | rx_status_loop: | ||
472 | cpw16(IntrStatus, cp_rx_intr_mask); | 472 | cpw16(IntrStatus, cp_rx_intr_mask); |
473 | 473 | ||
474 | while (rx < budget) { | 474 | while (rx < budget) { |
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 799d58d86e6d..054e795df90f 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
@@ -201,9 +201,14 @@ static const u16 sh_eth_offset_fast_rz[SH_ETH_MAX_REGISTER_OFFSET] = { | |||
201 | 201 | ||
202 | [ARSTR] = 0x0000, | 202 | [ARSTR] = 0x0000, |
203 | [TSU_CTRST] = 0x0004, | 203 | [TSU_CTRST] = 0x0004, |
204 | [TSU_FWSLC] = 0x0038, | ||
204 | [TSU_VTAG0] = 0x0058, | 205 | [TSU_VTAG0] = 0x0058, |
205 | [TSU_ADSBSY] = 0x0060, | 206 | [TSU_ADSBSY] = 0x0060, |
206 | [TSU_TEN] = 0x0064, | 207 | [TSU_TEN] = 0x0064, |
208 | [TSU_POST1] = 0x0070, | ||
209 | [TSU_POST2] = 0x0074, | ||
210 | [TSU_POST3] = 0x0078, | ||
211 | [TSU_POST4] = 0x007c, | ||
207 | [TSU_ADRH0] = 0x0100, | 212 | [TSU_ADRH0] = 0x0100, |
208 | 213 | ||
209 | [TXNLCR0] = 0x0080, | 214 | [TXNLCR0] = 0x0080, |
@@ -2786,6 +2791,8 @@ static void sh_eth_tsu_init(struct sh_eth_private *mdp) | |||
2786 | { | 2791 | { |
2787 | if (sh_eth_is_rz_fast_ether(mdp)) { | 2792 | if (sh_eth_is_rz_fast_ether(mdp)) { |
2788 | sh_eth_tsu_write(mdp, 0, TSU_TEN); /* Disable all CAM entry */ | 2793 | sh_eth_tsu_write(mdp, 0, TSU_TEN); /* Disable all CAM entry */ |
2794 | sh_eth_tsu_write(mdp, TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, | ||
2795 | TSU_FWSLC); /* Enable POST registers */ | ||
2789 | return; | 2796 | return; |
2790 | } | 2797 | } |
2791 | 2798 | ||
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index f658fee74f18..e00a669e9e09 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c | |||
@@ -1517,13 +1517,14 @@ static void efx_ef10_get_stat_mask(struct efx_nic *efx, unsigned long *mask) | |||
1517 | } | 1517 | } |
1518 | 1518 | ||
1519 | #if BITS_PER_LONG == 64 | 1519 | #if BITS_PER_LONG == 64 |
1520 | BUILD_BUG_ON(BITS_TO_LONGS(EF10_STAT_COUNT) != 2); | ||
1520 | mask[0] = raw_mask[0]; | 1521 | mask[0] = raw_mask[0]; |
1521 | mask[1] = raw_mask[1]; | 1522 | mask[1] = raw_mask[1]; |
1522 | #else | 1523 | #else |
1524 | BUILD_BUG_ON(BITS_TO_LONGS(EF10_STAT_COUNT) != 3); | ||
1523 | mask[0] = raw_mask[0] & 0xffffffff; | 1525 | mask[0] = raw_mask[0] & 0xffffffff; |
1524 | mask[1] = raw_mask[0] >> 32; | 1526 | mask[1] = raw_mask[0] >> 32; |
1525 | mask[2] = raw_mask[1] & 0xffffffff; | 1527 | mask[2] = raw_mask[1] & 0xffffffff; |
1526 | mask[3] = raw_mask[1] >> 32; | ||
1527 | #endif | 1528 | #endif |
1528 | } | 1529 | } |
1529 | 1530 | ||
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 726b80f45906..503a3b6dce91 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c | |||
@@ -2275,6 +2275,13 @@ static int smc_drv_probe(struct platform_device *pdev) | |||
2275 | if (pd) { | 2275 | if (pd) { |
2276 | memcpy(&lp->cfg, pd, sizeof(lp->cfg)); | 2276 | memcpy(&lp->cfg, pd, sizeof(lp->cfg)); |
2277 | lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags); | 2277 | lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags); |
2278 | |||
2279 | if (!SMC_8BIT(lp) && !SMC_16BIT(lp)) { | ||
2280 | dev_err(&pdev->dev, | ||
2281 | "at least one of 8-bit or 16-bit access support is required.\n"); | ||
2282 | ret = -ENXIO; | ||
2283 | goto out_free_netdev; | ||
2284 | } | ||
2278 | } | 2285 | } |
2279 | 2286 | ||
2280 | #if IS_BUILTIN(CONFIG_OF) | 2287 | #if IS_BUILTIN(CONFIG_OF) |
diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h index 1a55c7976df0..ea8465467469 100644 --- a/drivers/net/ethernet/smsc/smc91x.h +++ b/drivers/net/ethernet/smsc/smc91x.h | |||
@@ -37,6 +37,27 @@ | |||
37 | #include <linux/smc91x.h> | 37 | #include <linux/smc91x.h> |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * Any 16-bit access is performed with two 8-bit accesses if the hardware | ||
41 | * can't do it directly. Most registers are 16-bit so those are mandatory. | ||
42 | */ | ||
43 | #define SMC_outw_b(x, a, r) \ | ||
44 | do { \ | ||
45 | unsigned int __val16 = (x); \ | ||
46 | unsigned int __reg = (r); \ | ||
47 | SMC_outb(__val16, a, __reg); \ | ||
48 | SMC_outb(__val16 >> 8, a, __reg + (1 << SMC_IO_SHIFT)); \ | ||
49 | } while (0) | ||
50 | |||
51 | #define SMC_inw_b(a, r) \ | ||
52 | ({ \ | ||
53 | unsigned int __val16; \ | ||
54 | unsigned int __reg = r; \ | ||
55 | __val16 = SMC_inb(a, __reg); \ | ||
56 | __val16 |= SMC_inb(a, __reg + (1 << SMC_IO_SHIFT)) << 8; \ | ||
57 | __val16; \ | ||
58 | }) | ||
59 | |||
60 | /* | ||
40 | * Define your architecture specific bus configuration parameters here. | 61 | * Define your architecture specific bus configuration parameters here. |
41 | */ | 62 | */ |
42 | 63 | ||
@@ -55,10 +76,30 @@ | |||
55 | #define SMC_IO_SHIFT (lp->io_shift) | 76 | #define SMC_IO_SHIFT (lp->io_shift) |
56 | 77 | ||
57 | #define SMC_inb(a, r) readb((a) + (r)) | 78 | #define SMC_inb(a, r) readb((a) + (r)) |
58 | #define SMC_inw(a, r) readw((a) + (r)) | 79 | #define SMC_inw(a, r) \ |
80 | ({ \ | ||
81 | unsigned int __smc_r = r; \ | ||
82 | SMC_16BIT(lp) ? readw((a) + __smc_r) : \ | ||
83 | SMC_8BIT(lp) ? SMC_inw_b(a, __smc_r) : \ | ||
84 | ({ BUG(); 0; }); \ | ||
85 | }) | ||
86 | |||
59 | #define SMC_inl(a, r) readl((a) + (r)) | 87 | #define SMC_inl(a, r) readl((a) + (r)) |
60 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) | 88 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) |
89 | #define SMC_outw(v, a, r) \ | ||
90 | do { \ | ||
91 | unsigned int __v = v, __smc_r = r; \ | ||
92 | if (SMC_16BIT(lp)) \ | ||
93 | __SMC_outw(__v, a, __smc_r); \ | ||
94 | else if (SMC_8BIT(lp)) \ | ||
95 | SMC_outw_b(__v, a, __smc_r); \ | ||
96 | else \ | ||
97 | BUG(); \ | ||
98 | } while (0) | ||
99 | |||
61 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) | 100 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) |
101 | #define SMC_insb(a, r, p, l) readsb((a) + (r), p, l) | ||
102 | #define SMC_outsb(a, r, p, l) writesb((a) + (r), p, l) | ||
62 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) | 103 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) |
63 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) | 104 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) |
64 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) | 105 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) |
@@ -66,7 +107,7 @@ | |||
66 | #define SMC_IRQ_FLAGS (-1) /* from resource */ | 107 | #define SMC_IRQ_FLAGS (-1) /* from resource */ |
67 | 108 | ||
68 | /* We actually can't write halfwords properly if not word aligned */ | 109 | /* We actually can't write halfwords properly if not word aligned */ |
69 | static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg) | 110 | static inline void __SMC_outw(u16 val, void __iomem *ioaddr, int reg) |
70 | { | 111 | { |
71 | if ((machine_is_mainstone() || machine_is_stargate2() || | 112 | if ((machine_is_mainstone() || machine_is_stargate2() || |
72 | machine_is_pxa_idp()) && reg & 2) { | 113 | machine_is_pxa_idp()) && reg & 2) { |
@@ -416,24 +457,8 @@ smc_pxa_dma_insw(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma, | |||
416 | 457 | ||
417 | #if ! SMC_CAN_USE_16BIT | 458 | #if ! SMC_CAN_USE_16BIT |
418 | 459 | ||
419 | /* | 460 | #define SMC_outw(x, ioaddr, reg) SMC_outw_b(x, ioaddr, reg) |
420 | * Any 16-bit access is performed with two 8-bit accesses if the hardware | 461 | #define SMC_inw(ioaddr, reg) SMC_inw_b(ioaddr, reg) |
421 | * can't do it directly. Most registers are 16-bit so those are mandatory. | ||
422 | */ | ||
423 | #define SMC_outw(x, ioaddr, reg) \ | ||
424 | do { \ | ||
425 | unsigned int __val16 = (x); \ | ||
426 | SMC_outb( __val16, ioaddr, reg ); \ | ||
427 | SMC_outb( __val16 >> 8, ioaddr, reg + (1 << SMC_IO_SHIFT));\ | ||
428 | } while (0) | ||
429 | #define SMC_inw(ioaddr, reg) \ | ||
430 | ({ \ | ||
431 | unsigned int __val16; \ | ||
432 | __val16 = SMC_inb( ioaddr, reg ); \ | ||
433 | __val16 |= SMC_inb( ioaddr, reg + (1 << SMC_IO_SHIFT)) << 8; \ | ||
434 | __val16; \ | ||
435 | }) | ||
436 | |||
437 | #define SMC_insw(a, r, p, l) BUG() | 462 | #define SMC_insw(a, r, p, l) BUG() |
438 | #define SMC_outsw(a, r, p, l) BUG() | 463 | #define SMC_outsw(a, r, p, l) BUG() |
439 | 464 | ||
@@ -445,7 +470,9 @@ smc_pxa_dma_insw(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma, | |||
445 | #endif | 470 | #endif |
446 | 471 | ||
447 | #if ! SMC_CAN_USE_8BIT | 472 | #if ! SMC_CAN_USE_8BIT |
473 | #undef SMC_inb | ||
448 | #define SMC_inb(ioaddr, reg) ({ BUG(); 0; }) | 474 | #define SMC_inb(ioaddr, reg) ({ BUG(); 0; }) |
475 | #undef SMC_outb | ||
449 | #define SMC_outb(x, ioaddr, reg) BUG() | 476 | #define SMC_outb(x, ioaddr, reg) BUG() |
450 | #define SMC_insb(a, r, p, l) BUG() | 477 | #define SMC_insb(a, r, p, l) BUG() |
451 | #define SMC_outsb(a, r, p, l) BUG() | 478 | #define SMC_outsb(a, r, p, l) BUG() |
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index ca3134540d2d..4f8910b7db2e 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c | |||
@@ -1099,15 +1099,8 @@ static int smsc911x_mii_init(struct platform_device *pdev, | |||
1099 | goto err_out_free_bus_2; | 1099 | goto err_out_free_bus_2; |
1100 | } | 1100 | } |
1101 | 1101 | ||
1102 | if (smsc911x_mii_probe(dev) < 0) { | ||
1103 | SMSC_WARN(pdata, probe, "Error registering mii bus"); | ||
1104 | goto err_out_unregister_bus_3; | ||
1105 | } | ||
1106 | |||
1107 | return 0; | 1102 | return 0; |
1108 | 1103 | ||
1109 | err_out_unregister_bus_3: | ||
1110 | mdiobus_unregister(pdata->mii_bus); | ||
1111 | err_out_free_bus_2: | 1104 | err_out_free_bus_2: |
1112 | mdiobus_free(pdata->mii_bus); | 1105 | mdiobus_free(pdata->mii_bus); |
1113 | err_out_1: | 1106 | err_out_1: |
@@ -1514,23 +1507,90 @@ static void smsc911x_disable_irq_chip(struct net_device *dev) | |||
1514 | smsc911x_reg_write(pdata, INT_STS, 0xFFFFFFFF); | 1507 | smsc911x_reg_write(pdata, INT_STS, 0xFFFFFFFF); |
1515 | } | 1508 | } |
1516 | 1509 | ||
1510 | static irqreturn_t smsc911x_irqhandler(int irq, void *dev_id) | ||
1511 | { | ||
1512 | struct net_device *dev = dev_id; | ||
1513 | struct smsc911x_data *pdata = netdev_priv(dev); | ||
1514 | u32 intsts = smsc911x_reg_read(pdata, INT_STS); | ||
1515 | u32 inten = smsc911x_reg_read(pdata, INT_EN); | ||
1516 | int serviced = IRQ_NONE; | ||
1517 | u32 temp; | ||
1518 | |||
1519 | if (unlikely(intsts & inten & INT_STS_SW_INT_)) { | ||
1520 | temp = smsc911x_reg_read(pdata, INT_EN); | ||
1521 | temp &= (~INT_EN_SW_INT_EN_); | ||
1522 | smsc911x_reg_write(pdata, INT_EN, temp); | ||
1523 | smsc911x_reg_write(pdata, INT_STS, INT_STS_SW_INT_); | ||
1524 | pdata->software_irq_signal = 1; | ||
1525 | smp_wmb(); | ||
1526 | serviced = IRQ_HANDLED; | ||
1527 | } | ||
1528 | |||
1529 | if (unlikely(intsts & inten & INT_STS_RXSTOP_INT_)) { | ||
1530 | /* Called when there is a multicast update scheduled and | ||
1531 | * it is now safe to complete the update */ | ||
1532 | SMSC_TRACE(pdata, intr, "RX Stop interrupt"); | ||
1533 | smsc911x_reg_write(pdata, INT_STS, INT_STS_RXSTOP_INT_); | ||
1534 | if (pdata->multicast_update_pending) | ||
1535 | smsc911x_rx_multicast_update_workaround(pdata); | ||
1536 | serviced = IRQ_HANDLED; | ||
1537 | } | ||
1538 | |||
1539 | if (intsts & inten & INT_STS_TDFA_) { | ||
1540 | temp = smsc911x_reg_read(pdata, FIFO_INT); | ||
1541 | temp |= FIFO_INT_TX_AVAIL_LEVEL_; | ||
1542 | smsc911x_reg_write(pdata, FIFO_INT, temp); | ||
1543 | smsc911x_reg_write(pdata, INT_STS, INT_STS_TDFA_); | ||
1544 | netif_wake_queue(dev); | ||
1545 | serviced = IRQ_HANDLED; | ||
1546 | } | ||
1547 | |||
1548 | if (unlikely(intsts & inten & INT_STS_RXE_)) { | ||
1549 | SMSC_TRACE(pdata, intr, "RX Error interrupt"); | ||
1550 | smsc911x_reg_write(pdata, INT_STS, INT_STS_RXE_); | ||
1551 | serviced = IRQ_HANDLED; | ||
1552 | } | ||
1553 | |||
1554 | if (likely(intsts & inten & INT_STS_RSFL_)) { | ||
1555 | if (likely(napi_schedule_prep(&pdata->napi))) { | ||
1556 | /* Disable Rx interrupts */ | ||
1557 | temp = smsc911x_reg_read(pdata, INT_EN); | ||
1558 | temp &= (~INT_EN_RSFL_EN_); | ||
1559 | smsc911x_reg_write(pdata, INT_EN, temp); | ||
1560 | /* Schedule a NAPI poll */ | ||
1561 | __napi_schedule(&pdata->napi); | ||
1562 | } else { | ||
1563 | SMSC_WARN(pdata, rx_err, "napi_schedule_prep failed"); | ||
1564 | } | ||
1565 | serviced = IRQ_HANDLED; | ||
1566 | } | ||
1567 | |||
1568 | return serviced; | ||
1569 | } | ||
1570 | |||
1517 | static int smsc911x_open(struct net_device *dev) | 1571 | static int smsc911x_open(struct net_device *dev) |
1518 | { | 1572 | { |
1519 | struct smsc911x_data *pdata = netdev_priv(dev); | 1573 | struct smsc911x_data *pdata = netdev_priv(dev); |
1520 | unsigned int timeout; | 1574 | unsigned int timeout; |
1521 | unsigned int temp; | 1575 | unsigned int temp; |
1522 | unsigned int intcfg; | 1576 | unsigned int intcfg; |
1577 | int retval; | ||
1578 | int irq_flags; | ||
1523 | 1579 | ||
1524 | /* if the phy is not yet registered, retry later*/ | 1580 | /* find and start the given phy */ |
1525 | if (!dev->phydev) { | 1581 | if (!dev->phydev) { |
1526 | SMSC_WARN(pdata, hw, "phy_dev is NULL"); | 1582 | retval = smsc911x_mii_probe(dev); |
1527 | return -EAGAIN; | 1583 | if (retval < 0) { |
1584 | SMSC_WARN(pdata, probe, "Error starting phy"); | ||
1585 | goto out; | ||
1586 | } | ||
1528 | } | 1587 | } |
1529 | 1588 | ||
1530 | /* Reset the LAN911x */ | 1589 | /* Reset the LAN911x */ |
1531 | if (smsc911x_soft_reset(pdata)) { | 1590 | retval = smsc911x_soft_reset(pdata); |
1591 | if (retval) { | ||
1532 | SMSC_WARN(pdata, hw, "soft reset failed"); | 1592 | SMSC_WARN(pdata, hw, "soft reset failed"); |
1533 | return -EIO; | 1593 | goto mii_free_out; |
1534 | } | 1594 | } |
1535 | 1595 | ||
1536 | smsc911x_reg_write(pdata, HW_CFG, 0x00050000); | 1596 | smsc911x_reg_write(pdata, HW_CFG, 0x00050000); |
@@ -1586,6 +1646,15 @@ static int smsc911x_open(struct net_device *dev) | |||
1586 | pdata->software_irq_signal = 0; | 1646 | pdata->software_irq_signal = 0; |
1587 | smp_wmb(); | 1647 | smp_wmb(); |
1588 | 1648 | ||
1649 | irq_flags = irq_get_trigger_type(dev->irq); | ||
1650 | retval = request_irq(dev->irq, smsc911x_irqhandler, | ||
1651 | irq_flags | IRQF_SHARED, dev->name, dev); | ||
1652 | if (retval) { | ||
1653 | SMSC_WARN(pdata, probe, | ||
1654 | "Unable to claim requested irq: %d", dev->irq); | ||
1655 | goto mii_free_out; | ||
1656 | } | ||
1657 | |||
1589 | temp = smsc911x_reg_read(pdata, INT_EN); | 1658 | temp = smsc911x_reg_read(pdata, INT_EN); |
1590 | temp |= INT_EN_SW_INT_EN_; | 1659 | temp |= INT_EN_SW_INT_EN_; |
1591 | smsc911x_reg_write(pdata, INT_EN, temp); | 1660 | smsc911x_reg_write(pdata, INT_EN, temp); |
@@ -1600,7 +1669,8 @@ static int smsc911x_open(struct net_device *dev) | |||
1600 | if (!pdata->software_irq_signal) { | 1669 | if (!pdata->software_irq_signal) { |
1601 | netdev_warn(dev, "ISR failed signaling test (IRQ %d)\n", | 1670 | netdev_warn(dev, "ISR failed signaling test (IRQ %d)\n", |
1602 | dev->irq); | 1671 | dev->irq); |
1603 | return -ENODEV; | 1672 | retval = -ENODEV; |
1673 | goto irq_stop_out; | ||
1604 | } | 1674 | } |
1605 | SMSC_TRACE(pdata, ifup, "IRQ handler passed test using IRQ %d", | 1675 | SMSC_TRACE(pdata, ifup, "IRQ handler passed test using IRQ %d", |
1606 | dev->irq); | 1676 | dev->irq); |
@@ -1646,6 +1716,14 @@ static int smsc911x_open(struct net_device *dev) | |||
1646 | 1716 | ||
1647 | netif_start_queue(dev); | 1717 | netif_start_queue(dev); |
1648 | return 0; | 1718 | return 0; |
1719 | |||
1720 | irq_stop_out: | ||
1721 | free_irq(dev->irq, dev); | ||
1722 | mii_free_out: | ||
1723 | phy_disconnect(dev->phydev); | ||
1724 | dev->phydev = NULL; | ||
1725 | out: | ||
1726 | return retval; | ||
1649 | } | 1727 | } |
1650 | 1728 | ||
1651 | /* Entry point for stopping the interface */ | 1729 | /* Entry point for stopping the interface */ |
@@ -1667,9 +1745,15 @@ static int smsc911x_stop(struct net_device *dev) | |||
1667 | dev->stats.rx_dropped += smsc911x_reg_read(pdata, RX_DROP); | 1745 | dev->stats.rx_dropped += smsc911x_reg_read(pdata, RX_DROP); |
1668 | smsc911x_tx_update_txcounters(dev); | 1746 | smsc911x_tx_update_txcounters(dev); |
1669 | 1747 | ||
1748 | free_irq(dev->irq, dev); | ||
1749 | |||
1670 | /* Bring the PHY down */ | 1750 | /* Bring the PHY down */ |
1671 | if (dev->phydev) | 1751 | if (dev->phydev) { |
1672 | phy_stop(dev->phydev); | 1752 | phy_stop(dev->phydev); |
1753 | phy_disconnect(dev->phydev); | ||
1754 | dev->phydev = NULL; | ||
1755 | } | ||
1756 | netif_carrier_off(dev); | ||
1673 | 1757 | ||
1674 | SMSC_TRACE(pdata, ifdown, "Interface stopped"); | 1758 | SMSC_TRACE(pdata, ifdown, "Interface stopped"); |
1675 | return 0; | 1759 | return 0; |
@@ -1811,67 +1895,6 @@ static void smsc911x_set_multicast_list(struct net_device *dev) | |||
1811 | spin_unlock_irqrestore(&pdata->mac_lock, flags); | 1895 | spin_unlock_irqrestore(&pdata->mac_lock, flags); |
1812 | } | 1896 | } |
1813 | 1897 | ||
1814 | static irqreturn_t smsc911x_irqhandler(int irq, void *dev_id) | ||
1815 | { | ||
1816 | struct net_device *dev = dev_id; | ||
1817 | struct smsc911x_data *pdata = netdev_priv(dev); | ||
1818 | u32 intsts = smsc911x_reg_read(pdata, INT_STS); | ||
1819 | u32 inten = smsc911x_reg_read(pdata, INT_EN); | ||
1820 | int serviced = IRQ_NONE; | ||
1821 | u32 temp; | ||
1822 | |||
1823 | if (unlikely(intsts & inten & INT_STS_SW_INT_)) { | ||
1824 | temp = smsc911x_reg_read(pdata, INT_EN); | ||
1825 | temp &= (~INT_EN_SW_INT_EN_); | ||
1826 | smsc911x_reg_write(pdata, INT_EN, temp); | ||
1827 | smsc911x_reg_write(pdata, INT_STS, INT_STS_SW_INT_); | ||
1828 | pdata->software_irq_signal = 1; | ||
1829 | smp_wmb(); | ||
1830 | serviced = IRQ_HANDLED; | ||
1831 | } | ||
1832 | |||
1833 | if (unlikely(intsts & inten & INT_STS_RXSTOP_INT_)) { | ||
1834 | /* Called when there is a multicast update scheduled and | ||
1835 | * it is now safe to complete the update */ | ||
1836 | SMSC_TRACE(pdata, intr, "RX Stop interrupt"); | ||
1837 | smsc911x_reg_write(pdata, INT_STS, INT_STS_RXSTOP_INT_); | ||
1838 | if (pdata->multicast_update_pending) | ||
1839 | smsc911x_rx_multicast_update_workaround(pdata); | ||
1840 | serviced = IRQ_HANDLED; | ||
1841 | } | ||
1842 | |||
1843 | if (intsts & inten & INT_STS_TDFA_) { | ||
1844 | temp = smsc911x_reg_read(pdata, FIFO_INT); | ||
1845 | temp |= FIFO_INT_TX_AVAIL_LEVEL_; | ||
1846 | smsc911x_reg_write(pdata, FIFO_INT, temp); | ||
1847 | smsc911x_reg_write(pdata, INT_STS, INT_STS_TDFA_); | ||
1848 | netif_wake_queue(dev); | ||
1849 | serviced = IRQ_HANDLED; | ||
1850 | } | ||
1851 | |||
1852 | if (unlikely(intsts & inten & INT_STS_RXE_)) { | ||
1853 | SMSC_TRACE(pdata, intr, "RX Error interrupt"); | ||
1854 | smsc911x_reg_write(pdata, INT_STS, INT_STS_RXE_); | ||
1855 | serviced = IRQ_HANDLED; | ||
1856 | } | ||
1857 | |||
1858 | if (likely(intsts & inten & INT_STS_RSFL_)) { | ||
1859 | if (likely(napi_schedule_prep(&pdata->napi))) { | ||
1860 | /* Disable Rx interrupts */ | ||
1861 | temp = smsc911x_reg_read(pdata, INT_EN); | ||
1862 | temp &= (~INT_EN_RSFL_EN_); | ||
1863 | smsc911x_reg_write(pdata, INT_EN, temp); | ||
1864 | /* Schedule a NAPI poll */ | ||
1865 | __napi_schedule(&pdata->napi); | ||
1866 | } else { | ||
1867 | SMSC_WARN(pdata, rx_err, "napi_schedule_prep failed"); | ||
1868 | } | ||
1869 | serviced = IRQ_HANDLED; | ||
1870 | } | ||
1871 | |||
1872 | return serviced; | ||
1873 | } | ||
1874 | |||
1875 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1898 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1876 | static void smsc911x_poll_controller(struct net_device *dev) | 1899 | static void smsc911x_poll_controller(struct net_device *dev) |
1877 | { | 1900 | { |
@@ -2291,16 +2314,14 @@ static int smsc911x_drv_remove(struct platform_device *pdev) | |||
2291 | pdata = netdev_priv(dev); | 2314 | pdata = netdev_priv(dev); |
2292 | BUG_ON(!pdata); | 2315 | BUG_ON(!pdata); |
2293 | BUG_ON(!pdata->ioaddr); | 2316 | BUG_ON(!pdata->ioaddr); |
2294 | BUG_ON(!dev->phydev); | 2317 | WARN_ON(dev->phydev); |
2295 | 2318 | ||
2296 | SMSC_TRACE(pdata, ifdown, "Stopping driver"); | 2319 | SMSC_TRACE(pdata, ifdown, "Stopping driver"); |
2297 | 2320 | ||
2298 | phy_disconnect(dev->phydev); | ||
2299 | mdiobus_unregister(pdata->mii_bus); | 2321 | mdiobus_unregister(pdata->mii_bus); |
2300 | mdiobus_free(pdata->mii_bus); | 2322 | mdiobus_free(pdata->mii_bus); |
2301 | 2323 | ||
2302 | unregister_netdev(dev); | 2324 | unregister_netdev(dev); |
2303 | free_irq(dev->irq, dev); | ||
2304 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 2325 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
2305 | "smsc911x-memory"); | 2326 | "smsc911x-memory"); |
2306 | if (!res) | 2327 | if (!res) |
@@ -2385,8 +2406,7 @@ static int smsc911x_drv_probe(struct platform_device *pdev) | |||
2385 | struct smsc911x_data *pdata; | 2406 | struct smsc911x_data *pdata; |
2386 | struct smsc911x_platform_config *config = dev_get_platdata(&pdev->dev); | 2407 | struct smsc911x_platform_config *config = dev_get_platdata(&pdev->dev); |
2387 | struct resource *res; | 2408 | struct resource *res; |
2388 | unsigned int intcfg = 0; | 2409 | int res_size, irq; |
2389 | int res_size, irq, irq_flags; | ||
2390 | int retval; | 2410 | int retval; |
2391 | 2411 | ||
2392 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 2412 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
@@ -2425,7 +2445,6 @@ static int smsc911x_drv_probe(struct platform_device *pdev) | |||
2425 | 2445 | ||
2426 | pdata = netdev_priv(dev); | 2446 | pdata = netdev_priv(dev); |
2427 | dev->irq = irq; | 2447 | dev->irq = irq; |
2428 | irq_flags = irq_get_trigger_type(irq); | ||
2429 | pdata->ioaddr = ioremap_nocache(res->start, res_size); | 2448 | pdata->ioaddr = ioremap_nocache(res->start, res_size); |
2430 | 2449 | ||
2431 | pdata->dev = dev; | 2450 | pdata->dev = dev; |
@@ -2472,43 +2491,23 @@ static int smsc911x_drv_probe(struct platform_device *pdev) | |||
2472 | if (retval < 0) | 2491 | if (retval < 0) |
2473 | goto out_disable_resources; | 2492 | goto out_disable_resources; |
2474 | 2493 | ||
2475 | /* configure irq polarity and type before connecting isr */ | 2494 | netif_carrier_off(dev); |
2476 | if (pdata->config.irq_polarity == SMSC911X_IRQ_POLARITY_ACTIVE_HIGH) | ||
2477 | intcfg |= INT_CFG_IRQ_POL_; | ||
2478 | |||
2479 | if (pdata->config.irq_type == SMSC911X_IRQ_TYPE_PUSH_PULL) | ||
2480 | intcfg |= INT_CFG_IRQ_TYPE_; | ||
2481 | |||
2482 | smsc911x_reg_write(pdata, INT_CFG, intcfg); | ||
2483 | |||
2484 | /* Ensure interrupts are globally disabled before connecting ISR */ | ||
2485 | smsc911x_disable_irq_chip(dev); | ||
2486 | 2495 | ||
2487 | retval = request_irq(dev->irq, smsc911x_irqhandler, | 2496 | retval = smsc911x_mii_init(pdev, dev); |
2488 | irq_flags | IRQF_SHARED, dev->name, dev); | ||
2489 | if (retval) { | 2497 | if (retval) { |
2490 | SMSC_WARN(pdata, probe, | 2498 | SMSC_WARN(pdata, probe, "Error %i initialising mii", retval); |
2491 | "Unable to claim requested irq: %d", dev->irq); | ||
2492 | goto out_disable_resources; | 2499 | goto out_disable_resources; |
2493 | } | 2500 | } |
2494 | 2501 | ||
2495 | netif_carrier_off(dev); | ||
2496 | |||
2497 | retval = register_netdev(dev); | 2502 | retval = register_netdev(dev); |
2498 | if (retval) { | 2503 | if (retval) { |
2499 | SMSC_WARN(pdata, probe, "Error %i registering device", retval); | 2504 | SMSC_WARN(pdata, probe, "Error %i registering device", retval); |
2500 | goto out_free_irq; | 2505 | goto out_disable_resources; |
2501 | } else { | 2506 | } else { |
2502 | SMSC_TRACE(pdata, probe, | 2507 | SMSC_TRACE(pdata, probe, |
2503 | "Network interface: \"%s\"", dev->name); | 2508 | "Network interface: \"%s\"", dev->name); |
2504 | } | 2509 | } |
2505 | 2510 | ||
2506 | retval = smsc911x_mii_init(pdev, dev); | ||
2507 | if (retval) { | ||
2508 | SMSC_WARN(pdata, probe, "Error %i initialising mii", retval); | ||
2509 | goto out_unregister_netdev_5; | ||
2510 | } | ||
2511 | |||
2512 | spin_lock_irq(&pdata->mac_lock); | 2511 | spin_lock_irq(&pdata->mac_lock); |
2513 | 2512 | ||
2514 | /* Check if mac address has been specified when bringing interface up */ | 2513 | /* Check if mac address has been specified when bringing interface up */ |
@@ -2544,10 +2543,6 @@ static int smsc911x_drv_probe(struct platform_device *pdev) | |||
2544 | 2543 | ||
2545 | return 0; | 2544 | return 0; |
2546 | 2545 | ||
2547 | out_unregister_netdev_5: | ||
2548 | unregister_netdev(dev); | ||
2549 | out_free_irq: | ||
2550 | free_irq(dev->irq, dev); | ||
2551 | out_disable_resources: | 2546 | out_disable_resources: |
2552 | pm_runtime_put(&pdev->dev); | 2547 | pm_runtime_put(&pdev->dev); |
2553 | pm_runtime_disable(&pdev->dev); | 2548 | pm_runtime_disable(&pdev->dev); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index cbefe9e2207c..885a5e64519d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | |||
@@ -261,7 +261,7 @@ static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode) | |||
261 | } | 261 | } |
262 | if (mode & WAKE_UCAST) { | 262 | if (mode & WAKE_UCAST) { |
263 | pr_debug("GMAC: WOL on global unicast\n"); | 263 | pr_debug("GMAC: WOL on global unicast\n"); |
264 | pmt |= global_unicast; | 264 | pmt |= power_down | global_unicast | wake_up_frame_en; |
265 | } | 265 | } |
266 | 266 | ||
267 | writel(pmt, ioaddr + GMAC_PMT); | 267 | writel(pmt, ioaddr + GMAC_PMT); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index df5580dcdfed..51019b794be5 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | |||
@@ -102,7 +102,7 @@ static void dwmac4_pmt(struct mac_device_info *hw, unsigned long mode) | |||
102 | } | 102 | } |
103 | if (mode & WAKE_UCAST) { | 103 | if (mode & WAKE_UCAST) { |
104 | pr_debug("GMAC: WOL on global unicast\n"); | 104 | pr_debug("GMAC: WOL on global unicast\n"); |
105 | pmt |= global_unicast; | 105 | pmt |= power_down | global_unicast | wake_up_frame_en; |
106 | } | 106 | } |
107 | 107 | ||
108 | writel(pmt, ioaddr + GMAC_PMT); | 108 | writel(pmt, ioaddr + GMAC_PMT); |
diff --git a/drivers/net/ethernet/synopsys/dwc_eth_qos.c b/drivers/net/ethernet/synopsys/dwc_eth_qos.c index 9f159a775af3..4490ebaed127 100644 --- a/drivers/net/ethernet/synopsys/dwc_eth_qos.c +++ b/drivers/net/ethernet/synopsys/dwc_eth_qos.c | |||
@@ -1246,7 +1246,7 @@ static int dwceqos_mii_init(struct net_local *lp) | |||
1246 | lp->mii_bus->read = &dwceqos_mdio_read; | 1246 | lp->mii_bus->read = &dwceqos_mdio_read; |
1247 | lp->mii_bus->write = &dwceqos_mdio_write; | 1247 | lp->mii_bus->write = &dwceqos_mdio_write; |
1248 | lp->mii_bus->priv = lp; | 1248 | lp->mii_bus->priv = lp; |
1249 | lp->mii_bus->parent = &lp->ndev->dev; | 1249 | lp->mii_bus->parent = &lp->pdev->dev; |
1250 | 1250 | ||
1251 | of_address_to_resource(lp->pdev->dev.of_node, 0, &res); | 1251 | of_address_to_resource(lp->pdev->dev.of_node, 0, &res); |
1252 | snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "%.8llx", | 1252 | snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "%.8llx", |
@@ -1622,13 +1622,7 @@ static void dwceqos_init_hw(struct net_local *lp) | |||
1622 | DWCEQOS_MMC_CTRL_RSTONRD); | 1622 | DWCEQOS_MMC_CTRL_RSTONRD); |
1623 | dwceqos_enable_mmc_interrupt(lp); | 1623 | dwceqos_enable_mmc_interrupt(lp); |
1624 | 1624 | ||
1625 | /* Enable Interrupts */ | 1625 | dwceqos_write(lp, REG_DWCEQOS_DMA_CH0_IE, 0); |
1626 | dwceqos_write(lp, REG_DWCEQOS_DMA_CH0_IE, | ||
1627 | DWCEQOS_DMA_CH0_IE_NIE | | ||
1628 | DWCEQOS_DMA_CH0_IE_RIE | DWCEQOS_DMA_CH0_IE_TIE | | ||
1629 | DWCEQOS_DMA_CH0_IE_AIE | | ||
1630 | DWCEQOS_DMA_CH0_IE_FBEE); | ||
1631 | |||
1632 | dwceqos_write(lp, REG_DWCEQOS_MAC_IE, 0); | 1626 | dwceqos_write(lp, REG_DWCEQOS_MAC_IE, 0); |
1633 | 1627 | ||
1634 | dwceqos_write(lp, REG_DWCEQOS_MAC_CFG, DWCEQOS_MAC_CFG_IPC | | 1628 | dwceqos_write(lp, REG_DWCEQOS_MAC_CFG, DWCEQOS_MAC_CFG_IPC | |
@@ -1905,6 +1899,15 @@ static int dwceqos_open(struct net_device *ndev) | |||
1905 | netif_start_queue(ndev); | 1899 | netif_start_queue(ndev); |
1906 | tasklet_enable(&lp->tx_bdreclaim_tasklet); | 1900 | tasklet_enable(&lp->tx_bdreclaim_tasklet); |
1907 | 1901 | ||
1902 | /* Enable Interrupts -- do this only after we enable NAPI and the | ||
1903 | * tasklet. | ||
1904 | */ | ||
1905 | dwceqos_write(lp, REG_DWCEQOS_DMA_CH0_IE, | ||
1906 | DWCEQOS_DMA_CH0_IE_NIE | | ||
1907 | DWCEQOS_DMA_CH0_IE_RIE | DWCEQOS_DMA_CH0_IE_TIE | | ||
1908 | DWCEQOS_DMA_CH0_IE_AIE | | ||
1909 | DWCEQOS_DMA_CH0_IE_FBEE); | ||
1910 | |||
1908 | return 0; | 1911 | return 0; |
1909 | } | 1912 | } |
1910 | 1913 | ||
@@ -2850,25 +2853,17 @@ static int dwceqos_probe(struct platform_device *pdev) | |||
2850 | 2853 | ||
2851 | ndev->features = ndev->hw_features; | 2854 | ndev->features = ndev->hw_features; |
2852 | 2855 | ||
2853 | netif_napi_add(ndev, &lp->napi, dwceqos_rx_poll, NAPI_POLL_WEIGHT); | ||
2854 | |||
2855 | ret = register_netdev(ndev); | ||
2856 | if (ret) { | ||
2857 | dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); | ||
2858 | goto err_out_clk_dis_aper; | ||
2859 | } | ||
2860 | |||
2861 | lp->phy_ref_clk = devm_clk_get(&pdev->dev, "phy_ref_clk"); | 2856 | lp->phy_ref_clk = devm_clk_get(&pdev->dev, "phy_ref_clk"); |
2862 | if (IS_ERR(lp->phy_ref_clk)) { | 2857 | if (IS_ERR(lp->phy_ref_clk)) { |
2863 | dev_err(&pdev->dev, "phy_ref_clk clock not found.\n"); | 2858 | dev_err(&pdev->dev, "phy_ref_clk clock not found.\n"); |
2864 | ret = PTR_ERR(lp->phy_ref_clk); | 2859 | ret = PTR_ERR(lp->phy_ref_clk); |
2865 | goto err_out_unregister_netdev; | 2860 | goto err_out_clk_dis_aper; |
2866 | } | 2861 | } |
2867 | 2862 | ||
2868 | ret = clk_prepare_enable(lp->phy_ref_clk); | 2863 | ret = clk_prepare_enable(lp->phy_ref_clk); |
2869 | if (ret) { | 2864 | if (ret) { |
2870 | dev_err(&pdev->dev, "Unable to enable device clock.\n"); | 2865 | dev_err(&pdev->dev, "Unable to enable device clock.\n"); |
2871 | goto err_out_unregister_netdev; | 2866 | goto err_out_clk_dis_aper; |
2872 | } | 2867 | } |
2873 | 2868 | ||
2874 | lp->phy_node = of_parse_phandle(lp->pdev->dev.of_node, | 2869 | lp->phy_node = of_parse_phandle(lp->pdev->dev.of_node, |
@@ -2877,7 +2872,7 @@ static int dwceqos_probe(struct platform_device *pdev) | |||
2877 | ret = of_phy_register_fixed_link(lp->pdev->dev.of_node); | 2872 | ret = of_phy_register_fixed_link(lp->pdev->dev.of_node); |
2878 | if (ret < 0) { | 2873 | if (ret < 0) { |
2879 | dev_err(&pdev->dev, "invalid fixed-link"); | 2874 | dev_err(&pdev->dev, "invalid fixed-link"); |
2880 | goto err_out_unregister_clk_notifier; | 2875 | goto err_out_clk_dis_phy; |
2881 | } | 2876 | } |
2882 | 2877 | ||
2883 | lp->phy_node = of_node_get(lp->pdev->dev.of_node); | 2878 | lp->phy_node = of_node_get(lp->pdev->dev.of_node); |
@@ -2886,7 +2881,7 @@ static int dwceqos_probe(struct platform_device *pdev) | |||
2886 | ret = of_get_phy_mode(lp->pdev->dev.of_node); | 2881 | ret = of_get_phy_mode(lp->pdev->dev.of_node); |
2887 | if (ret < 0) { | 2882 | if (ret < 0) { |
2888 | dev_err(&lp->pdev->dev, "error in getting phy i/f\n"); | 2883 | dev_err(&lp->pdev->dev, "error in getting phy i/f\n"); |
2889 | goto err_out_unregister_clk_notifier; | 2884 | goto err_out_clk_dis_phy; |
2890 | } | 2885 | } |
2891 | 2886 | ||
2892 | lp->phy_interface = ret; | 2887 | lp->phy_interface = ret; |
@@ -2894,14 +2889,14 @@ static int dwceqos_probe(struct platform_device *pdev) | |||
2894 | ret = dwceqos_mii_init(lp); | 2889 | ret = dwceqos_mii_init(lp); |
2895 | if (ret) { | 2890 | if (ret) { |
2896 | dev_err(&lp->pdev->dev, "error in dwceqos_mii_init\n"); | 2891 | dev_err(&lp->pdev->dev, "error in dwceqos_mii_init\n"); |
2897 | goto err_out_unregister_clk_notifier; | 2892 | goto err_out_clk_dis_phy; |
2898 | } | 2893 | } |
2899 | 2894 | ||
2900 | ret = dwceqos_mii_probe(ndev); | 2895 | ret = dwceqos_mii_probe(ndev); |
2901 | if (ret != 0) { | 2896 | if (ret != 0) { |
2902 | netdev_err(ndev, "mii_probe fail.\n"); | 2897 | netdev_err(ndev, "mii_probe fail.\n"); |
2903 | ret = -ENXIO; | 2898 | ret = -ENXIO; |
2904 | goto err_out_unregister_clk_notifier; | 2899 | goto err_out_clk_dis_phy; |
2905 | } | 2900 | } |
2906 | 2901 | ||
2907 | dwceqos_set_umac_addr(lp, lp->ndev->dev_addr, 0); | 2902 | dwceqos_set_umac_addr(lp, lp->ndev->dev_addr, 0); |
@@ -2919,7 +2914,7 @@ static int dwceqos_probe(struct platform_device *pdev) | |||
2919 | if (ret) { | 2914 | if (ret) { |
2920 | dev_err(&lp->pdev->dev, "Unable to retrieve DT, error %d\n", | 2915 | dev_err(&lp->pdev->dev, "Unable to retrieve DT, error %d\n", |
2921 | ret); | 2916 | ret); |
2922 | goto err_out_unregister_clk_notifier; | 2917 | goto err_out_clk_dis_phy; |
2923 | } | 2918 | } |
2924 | dev_info(&lp->pdev->dev, "pdev->id %d, baseaddr 0x%08lx, irq %d\n", | 2919 | dev_info(&lp->pdev->dev, "pdev->id %d, baseaddr 0x%08lx, irq %d\n", |
2925 | pdev->id, ndev->base_addr, ndev->irq); | 2920 | pdev->id, ndev->base_addr, ndev->irq); |
@@ -2929,18 +2924,24 @@ static int dwceqos_probe(struct platform_device *pdev) | |||
2929 | if (ret) { | 2924 | if (ret) { |
2930 | dev_err(&lp->pdev->dev, "Unable to request IRQ %d, error %d\n", | 2925 | dev_err(&lp->pdev->dev, "Unable to request IRQ %d, error %d\n", |
2931 | ndev->irq, ret); | 2926 | ndev->irq, ret); |
2932 | goto err_out_unregister_clk_notifier; | 2927 | goto err_out_clk_dis_phy; |
2933 | } | 2928 | } |
2934 | 2929 | ||
2935 | if (netif_msg_probe(lp)) | 2930 | if (netif_msg_probe(lp)) |
2936 | netdev_dbg(ndev, "net_local@%p\n", lp); | 2931 | netdev_dbg(ndev, "net_local@%p\n", lp); |
2937 | 2932 | ||
2933 | netif_napi_add(ndev, &lp->napi, dwceqos_rx_poll, NAPI_POLL_WEIGHT); | ||
2934 | |||
2935 | ret = register_netdev(ndev); | ||
2936 | if (ret) { | ||
2937 | dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); | ||
2938 | goto err_out_clk_dis_phy; | ||
2939 | } | ||
2940 | |||
2938 | return 0; | 2941 | return 0; |
2939 | 2942 | ||
2940 | err_out_unregister_clk_notifier: | 2943 | err_out_clk_dis_phy: |
2941 | clk_disable_unprepare(lp->phy_ref_clk); | 2944 | clk_disable_unprepare(lp->phy_ref_clk); |
2942 | err_out_unregister_netdev: | ||
2943 | unregister_netdev(ndev); | ||
2944 | err_out_clk_dis_aper: | 2945 | err_out_clk_dis_aper: |
2945 | clk_disable_unprepare(lp->apb_pclk); | 2946 | clk_disable_unprepare(lp->apb_pclk); |
2946 | err_out_free_netdev: | 2947 | err_out_free_netdev: |
diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c index 7452b5f9d024..7108c68f16d3 100644 --- a/drivers/net/ethernet/tehuti/tehuti.c +++ b/drivers/net/ethernet/tehuti/tehuti.c | |||
@@ -1987,7 +1987,7 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1987 | if ((readl(nic->regs + FPGA_VER) & 0xFFF) >= 378) { | 1987 | if ((readl(nic->regs + FPGA_VER) & 0xFFF) >= 378) { |
1988 | err = pci_enable_msi(pdev); | 1988 | err = pci_enable_msi(pdev); |
1989 | if (err) | 1989 | if (err) |
1990 | pr_err("Can't eneble msi. error is %d\n", err); | 1990 | pr_err("Can't enable msi. error is %d\n", err); |
1991 | else | 1991 | else |
1992 | nic->irq_type = IRQ_MSI; | 1992 | nic->irq_type = IRQ_MSI; |
1993 | } else | 1993 | } else |
diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 3cee84a24815..93dc10b10c09 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c | |||
@@ -1131,11 +1131,13 @@ static int xemaclite_of_probe(struct platform_device *ofdev) | |||
1131 | lp->rx_ping_pong = get_bool(ofdev, "xlnx,rx-ping-pong"); | 1131 | lp->rx_ping_pong = get_bool(ofdev, "xlnx,rx-ping-pong"); |
1132 | mac_address = of_get_mac_address(ofdev->dev.of_node); | 1132 | mac_address = of_get_mac_address(ofdev->dev.of_node); |
1133 | 1133 | ||
1134 | if (mac_address) | 1134 | if (mac_address) { |
1135 | /* Set the MAC address. */ | 1135 | /* Set the MAC address. */ |
1136 | memcpy(ndev->dev_addr, mac_address, ETH_ALEN); | 1136 | memcpy(ndev->dev_addr, mac_address, ETH_ALEN); |
1137 | else | 1137 | } else { |
1138 | dev_warn(dev, "No MAC address found\n"); | 1138 | dev_warn(dev, "No MAC address found, using random\n"); |
1139 | eth_hw_addr_random(ndev); | ||
1140 | } | ||
1139 | 1141 | ||
1140 | /* Clear the Tx CSR's in case this is a restart */ | 1142 | /* Clear the Tx CSR's in case this is a restart */ |
1141 | __raw_writel(0, lp->base_addr + XEL_TSR_OFFSET); | 1143 | __raw_writel(0, lp->base_addr + XEL_TSR_OFFSET); |
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 47a64342cc16..b4863e4e522b 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig | |||
@@ -303,6 +303,7 @@ config MDIO_HISI_FEMAC | |||
303 | 303 | ||
304 | config MDIO_XGENE | 304 | config MDIO_XGENE |
305 | tristate "APM X-Gene SoC MDIO bus controller" | 305 | tristate "APM X-Gene SoC MDIO bus controller" |
306 | depends on ARCH_XGENE || COMPILE_TEST | ||
306 | help | 307 | help |
307 | This module provides a driver for the MDIO busses found in the | 308 | This module provides a driver for the MDIO busses found in the |
308 | APM X-Gene SoC's. | 309 | APM X-Gene SoC's. |
diff --git a/drivers/net/phy/mdio-xgene.c b/drivers/net/phy/mdio-xgene.c index 775674808249..92af182951be 100644 --- a/drivers/net/phy/mdio-xgene.c +++ b/drivers/net/phy/mdio-xgene.c | |||
@@ -424,10 +424,8 @@ static int xgene_mdio_remove(struct platform_device *pdev) | |||
424 | mdiobus_unregister(mdio_bus); | 424 | mdiobus_unregister(mdio_bus); |
425 | mdiobus_free(mdio_bus); | 425 | mdiobus_free(mdio_bus); |
426 | 426 | ||
427 | if (dev->of_node) { | 427 | if (dev->of_node) |
428 | if (IS_ERR(pdata->clk)) | 428 | clk_disable_unprepare(pdata->clk); |
429 | clk_disable_unprepare(pdata->clk); | ||
430 | } | ||
431 | 429 | ||
432 | return 0; | 430 | return 0; |
433 | } | 431 | } |
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 053e87905b94..885ac9cbab5a 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c | |||
@@ -964,7 +964,7 @@ static struct phy_driver ksphy_driver[] = { | |||
964 | .get_strings = kszphy_get_strings, | 964 | .get_strings = kszphy_get_strings, |
965 | .get_stats = kszphy_get_stats, | 965 | .get_stats = kszphy_get_stats, |
966 | .suspend = genphy_suspend, | 966 | .suspend = genphy_suspend, |
967 | .resume = genphy_resume, | 967 | .resume = kszphy_resume, |
968 | }, { | 968 | }, { |
969 | .phy_id = PHY_ID_KSZ8873MLL, | 969 | .phy_id = PHY_ID_KSZ8873MLL, |
970 | .phy_id_mask = MICREL_PHY_ID_MASK, | 970 | .phy_id_mask = MICREL_PHY_ID_MASK, |
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index c5dc2c363f96..c6f66832a1a6 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
@@ -722,8 +722,10 @@ phy_err: | |||
722 | int phy_start_interrupts(struct phy_device *phydev) | 722 | int phy_start_interrupts(struct phy_device *phydev) |
723 | { | 723 | { |
724 | atomic_set(&phydev->irq_disable, 0); | 724 | atomic_set(&phydev->irq_disable, 0); |
725 | if (request_irq(phydev->irq, phy_interrupt, 0, "phy_interrupt", | 725 | if (request_irq(phydev->irq, phy_interrupt, |
726 | phydev) < 0) { | 726 | IRQF_SHARED, |
727 | "phy_interrupt", | ||
728 | phydev) < 0) { | ||
727 | pr_warn("%s: Can't get IRQ %d (PHY)\n", | 729 | pr_warn("%s: Can't get IRQ %d (PHY)\n", |
728 | phydev->mdio.bus->name, phydev->irq); | 730 | phydev->mdio.bus->name, phydev->irq); |
729 | phydev->irq = PHY_POLL; | 731 | phydev->irq = PHY_POLL; |
diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c index cdb19b385d42..b228bea7931f 100644 --- a/drivers/net/team/team_mode_loadbalance.c +++ b/drivers/net/team/team_mode_loadbalance.c | |||
@@ -14,9 +14,23 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
16 | #include <linux/netdevice.h> | 16 | #include <linux/netdevice.h> |
17 | #include <linux/etherdevice.h> | ||
17 | #include <linux/filter.h> | 18 | #include <linux/filter.h> |
18 | #include <linux/if_team.h> | 19 | #include <linux/if_team.h> |
19 | 20 | ||
21 | static rx_handler_result_t lb_receive(struct team *team, struct team_port *port, | ||
22 | struct sk_buff *skb) | ||
23 | { | ||
24 | if (unlikely(skb->protocol == htons(ETH_P_SLOW))) { | ||
25 | /* LACPDU packets should go to exact delivery */ | ||
26 | const unsigned char *dest = eth_hdr(skb)->h_dest; | ||
27 | |||
28 | if (is_link_local_ether_addr(dest) && dest[5] == 0x02) | ||
29 | return RX_HANDLER_EXACT; | ||
30 | } | ||
31 | return RX_HANDLER_ANOTHER; | ||
32 | } | ||
33 | |||
20 | struct lb_priv; | 34 | struct lb_priv; |
21 | 35 | ||
22 | typedef struct team_port *lb_select_tx_port_func_t(struct team *, | 36 | typedef struct team_port *lb_select_tx_port_func_t(struct team *, |
@@ -652,6 +666,7 @@ static const struct team_mode_ops lb_mode_ops = { | |||
652 | .port_enter = lb_port_enter, | 666 | .port_enter = lb_port_enter, |
653 | .port_leave = lb_port_leave, | 667 | .port_leave = lb_port_leave, |
654 | .port_disabled = lb_port_disabled, | 668 | .port_disabled = lb_port_disabled, |
669 | .receive = lb_receive, | ||
655 | .transmit = lb_transmit, | 670 | .transmit = lb_transmit, |
656 | }; | 671 | }; |
657 | 672 | ||
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 9c8b5bc2b9d8..6f9df375c5d4 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -894,11 +894,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) | |||
894 | if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC))) | 894 | if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC))) |
895 | goto drop; | 895 | goto drop; |
896 | 896 | ||
897 | if (skb->sk && sk_fullsock(skb->sk)) { | 897 | skb_tx_timestamp(skb); |
898 | sock_tx_timestamp(skb->sk, skb->sk->sk_tsflags, | ||
899 | &skb_shinfo(skb)->tx_flags); | ||
900 | sw_tx_timestamp(skb); | ||
901 | } | ||
902 | 898 | ||
903 | /* Orphan the skb - required as we might hang on to it | 899 | /* Orphan the skb - required as we might hang on to it |
904 | * for indefinite time. | 900 | * for indefinite time. |
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 770212baaf05..528b9c9c4e60 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c | |||
@@ -1009,6 +1009,7 @@ static int kaweth_probe( | |||
1009 | struct net_device *netdev; | 1009 | struct net_device *netdev; |
1010 | const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 1010 | const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
1011 | int result = 0; | 1011 | int result = 0; |
1012 | int rv = -EIO; | ||
1012 | 1013 | ||
1013 | dev_dbg(dev, | 1014 | dev_dbg(dev, |
1014 | "Kawasaki Device Probe (Device number:%d): 0x%4.4x:0x%4.4x:0x%4.4x\n", | 1015 | "Kawasaki Device Probe (Device number:%d): 0x%4.4x:0x%4.4x:0x%4.4x\n", |
@@ -1029,6 +1030,7 @@ static int kaweth_probe( | |||
1029 | kaweth = netdev_priv(netdev); | 1030 | kaweth = netdev_priv(netdev); |
1030 | kaweth->dev = udev; | 1031 | kaweth->dev = udev; |
1031 | kaweth->net = netdev; | 1032 | kaweth->net = netdev; |
1033 | kaweth->intf = intf; | ||
1032 | 1034 | ||
1033 | spin_lock_init(&kaweth->device_lock); | 1035 | spin_lock_init(&kaweth->device_lock); |
1034 | init_waitqueue_head(&kaweth->term_wait); | 1036 | init_waitqueue_head(&kaweth->term_wait); |
@@ -1048,6 +1050,10 @@ static int kaweth_probe( | |||
1048 | /* Download the firmware */ | 1050 | /* Download the firmware */ |
1049 | dev_info(dev, "Downloading firmware...\n"); | 1051 | dev_info(dev, "Downloading firmware...\n"); |
1050 | kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL); | 1052 | kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL); |
1053 | if (!kaweth->firmware_buf) { | ||
1054 | rv = -ENOMEM; | ||
1055 | goto err_free_netdev; | ||
1056 | } | ||
1051 | if ((result = kaweth_download_firmware(kaweth, | 1057 | if ((result = kaweth_download_firmware(kaweth, |
1052 | "kaweth/new_code.bin", | 1058 | "kaweth/new_code.bin", |
1053 | 100, | 1059 | 100, |
@@ -1139,8 +1145,6 @@ err_fw: | |||
1139 | 1145 | ||
1140 | dev_dbg(dev, "Initializing net device.\n"); | 1146 | dev_dbg(dev, "Initializing net device.\n"); |
1141 | 1147 | ||
1142 | kaweth->intf = intf; | ||
1143 | |||
1144 | kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL); | 1148 | kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL); |
1145 | if (!kaweth->tx_urb) | 1149 | if (!kaweth->tx_urb) |
1146 | goto err_free_netdev; | 1150 | goto err_free_netdev; |
@@ -1204,7 +1208,7 @@ err_only_tx: | |||
1204 | err_free_netdev: | 1208 | err_free_netdev: |
1205 | free_netdev(netdev); | 1209 | free_netdev(netdev); |
1206 | 1210 | ||
1207 | return -EIO; | 1211 | return rv; |
1208 | } | 1212 | } |
1209 | 1213 | ||
1210 | /**************************************************************** | 1214 | /**************************************************************** |
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index f41a8ad4740e..c254248863d4 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #define NETNEXT_VERSION "08" | 32 | #define NETNEXT_VERSION "08" |
33 | 33 | ||
34 | /* Information for net */ | 34 | /* Information for net */ |
35 | #define NET_VERSION "5" | 35 | #define NET_VERSION "6" |
36 | 36 | ||
37 | #define DRIVER_VERSION "v1." NETNEXT_VERSION "." NET_VERSION | 37 | #define DRIVER_VERSION "v1." NETNEXT_VERSION "." NET_VERSION |
38 | #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>" | 38 | #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>" |
@@ -2552,6 +2552,77 @@ static void r8152_aldps_en(struct r8152 *tp, bool enable) | |||
2552 | } | 2552 | } |
2553 | } | 2553 | } |
2554 | 2554 | ||
2555 | static inline void r8152_mmd_indirect(struct r8152 *tp, u16 dev, u16 reg) | ||
2556 | { | ||
2557 | ocp_reg_write(tp, OCP_EEE_AR, FUN_ADDR | dev); | ||
2558 | ocp_reg_write(tp, OCP_EEE_DATA, reg); | ||
2559 | ocp_reg_write(tp, OCP_EEE_AR, FUN_DATA | dev); | ||
2560 | } | ||
2561 | |||
2562 | static u16 r8152_mmd_read(struct r8152 *tp, u16 dev, u16 reg) | ||
2563 | { | ||
2564 | u16 data; | ||
2565 | |||
2566 | r8152_mmd_indirect(tp, dev, reg); | ||
2567 | data = ocp_reg_read(tp, OCP_EEE_DATA); | ||
2568 | ocp_reg_write(tp, OCP_EEE_AR, 0x0000); | ||
2569 | |||
2570 | return data; | ||
2571 | } | ||
2572 | |||
2573 | static void r8152_mmd_write(struct r8152 *tp, u16 dev, u16 reg, u16 data) | ||
2574 | { | ||
2575 | r8152_mmd_indirect(tp, dev, reg); | ||
2576 | ocp_reg_write(tp, OCP_EEE_DATA, data); | ||
2577 | ocp_reg_write(tp, OCP_EEE_AR, 0x0000); | ||
2578 | } | ||
2579 | |||
2580 | static void r8152_eee_en(struct r8152 *tp, bool enable) | ||
2581 | { | ||
2582 | u16 config1, config2, config3; | ||
2583 | u32 ocp_data; | ||
2584 | |||
2585 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); | ||
2586 | config1 = ocp_reg_read(tp, OCP_EEE_CONFIG1) & ~sd_rise_time_mask; | ||
2587 | config2 = ocp_reg_read(tp, OCP_EEE_CONFIG2); | ||
2588 | config3 = ocp_reg_read(tp, OCP_EEE_CONFIG3) & ~fast_snr_mask; | ||
2589 | |||
2590 | if (enable) { | ||
2591 | ocp_data |= EEE_RX_EN | EEE_TX_EN; | ||
2592 | config1 |= EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | RX_QUIET_EN; | ||
2593 | config1 |= sd_rise_time(1); | ||
2594 | config2 |= RG_DACQUIET_EN | RG_LDVQUIET_EN; | ||
2595 | config3 |= fast_snr(42); | ||
2596 | } else { | ||
2597 | ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); | ||
2598 | config1 &= ~(EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | | ||
2599 | RX_QUIET_EN); | ||
2600 | config1 |= sd_rise_time(7); | ||
2601 | config2 &= ~(RG_DACQUIET_EN | RG_LDVQUIET_EN); | ||
2602 | config3 |= fast_snr(511); | ||
2603 | } | ||
2604 | |||
2605 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); | ||
2606 | ocp_reg_write(tp, OCP_EEE_CONFIG1, config1); | ||
2607 | ocp_reg_write(tp, OCP_EEE_CONFIG2, config2); | ||
2608 | ocp_reg_write(tp, OCP_EEE_CONFIG3, config3); | ||
2609 | } | ||
2610 | |||
2611 | static void r8152b_enable_eee(struct r8152 *tp) | ||
2612 | { | ||
2613 | r8152_eee_en(tp, true); | ||
2614 | r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, MDIO_EEE_100TX); | ||
2615 | } | ||
2616 | |||
2617 | static void r8152b_enable_fc(struct r8152 *tp) | ||
2618 | { | ||
2619 | u16 anar; | ||
2620 | |||
2621 | anar = r8152_mdio_read(tp, MII_ADVERTISE); | ||
2622 | anar |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; | ||
2623 | r8152_mdio_write(tp, MII_ADVERTISE, anar); | ||
2624 | } | ||
2625 | |||
2555 | static void rtl8152_disable(struct r8152 *tp) | 2626 | static void rtl8152_disable(struct r8152 *tp) |
2556 | { | 2627 | { |
2557 | r8152_aldps_en(tp, false); | 2628 | r8152_aldps_en(tp, false); |
@@ -2561,13 +2632,9 @@ static void rtl8152_disable(struct r8152 *tp) | |||
2561 | 2632 | ||
2562 | static void r8152b_hw_phy_cfg(struct r8152 *tp) | 2633 | static void r8152b_hw_phy_cfg(struct r8152 *tp) |
2563 | { | 2634 | { |
2564 | u16 data; | 2635 | r8152b_enable_eee(tp); |
2565 | 2636 | r8152_aldps_en(tp, true); | |
2566 | data = r8152_mdio_read(tp, MII_BMCR); | 2637 | r8152b_enable_fc(tp); |
2567 | if (data & BMCR_PDOWN) { | ||
2568 | data &= ~BMCR_PDOWN; | ||
2569 | r8152_mdio_write(tp, MII_BMCR, data); | ||
2570 | } | ||
2571 | 2638 | ||
2572 | set_bit(PHY_RESET, &tp->flags); | 2639 | set_bit(PHY_RESET, &tp->flags); |
2573 | } | 2640 | } |
@@ -2701,20 +2768,52 @@ static void r8152b_enter_oob(struct r8152 *tp) | |||
2701 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); | 2768 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); |
2702 | } | 2769 | } |
2703 | 2770 | ||
2771 | static void r8153_aldps_en(struct r8152 *tp, bool enable) | ||
2772 | { | ||
2773 | u16 data; | ||
2774 | |||
2775 | data = ocp_reg_read(tp, OCP_POWER_CFG); | ||
2776 | if (enable) { | ||
2777 | data |= EN_ALDPS; | ||
2778 | ocp_reg_write(tp, OCP_POWER_CFG, data); | ||
2779 | } else { | ||
2780 | data &= ~EN_ALDPS; | ||
2781 | ocp_reg_write(tp, OCP_POWER_CFG, data); | ||
2782 | msleep(20); | ||
2783 | } | ||
2784 | } | ||
2785 | |||
2786 | static void r8153_eee_en(struct r8152 *tp, bool enable) | ||
2787 | { | ||
2788 | u32 ocp_data; | ||
2789 | u16 config; | ||
2790 | |||
2791 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); | ||
2792 | config = ocp_reg_read(tp, OCP_EEE_CFG); | ||
2793 | |||
2794 | if (enable) { | ||
2795 | ocp_data |= EEE_RX_EN | EEE_TX_EN; | ||
2796 | config |= EEE10_EN; | ||
2797 | } else { | ||
2798 | ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); | ||
2799 | config &= ~EEE10_EN; | ||
2800 | } | ||
2801 | |||
2802 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); | ||
2803 | ocp_reg_write(tp, OCP_EEE_CFG, config); | ||
2804 | } | ||
2805 | |||
2704 | static void r8153_hw_phy_cfg(struct r8152 *tp) | 2806 | static void r8153_hw_phy_cfg(struct r8152 *tp) |
2705 | { | 2807 | { |
2706 | u32 ocp_data; | 2808 | u32 ocp_data; |
2707 | u16 data; | 2809 | u16 data; |
2708 | 2810 | ||
2709 | if (tp->version == RTL_VER_03 || tp->version == RTL_VER_04 || | 2811 | /* disable ALDPS before updating the PHY parameters */ |
2710 | tp->version == RTL_VER_05) | 2812 | r8153_aldps_en(tp, false); |
2711 | ocp_reg_write(tp, OCP_ADC_CFG, CKADSEL_L | ADC_EN | EN_EMI_L); | ||
2712 | 2813 | ||
2713 | data = r8152_mdio_read(tp, MII_BMCR); | 2814 | /* disable EEE before updating the PHY parameters */ |
2714 | if (data & BMCR_PDOWN) { | 2815 | r8153_eee_en(tp, false); |
2715 | data &= ~BMCR_PDOWN; | 2816 | ocp_reg_write(tp, OCP_EEE_ADV, 0); |
2716 | r8152_mdio_write(tp, MII_BMCR, data); | ||
2717 | } | ||
2718 | 2817 | ||
2719 | if (tp->version == RTL_VER_03) { | 2818 | if (tp->version == RTL_VER_03) { |
2720 | data = ocp_reg_read(tp, OCP_EEE_CFG); | 2819 | data = ocp_reg_read(tp, OCP_EEE_CFG); |
@@ -2745,6 +2844,12 @@ static void r8153_hw_phy_cfg(struct r8152 *tp) | |||
2745 | sram_write(tp, SRAM_10M_AMP1, 0x00af); | 2844 | sram_write(tp, SRAM_10M_AMP1, 0x00af); |
2746 | sram_write(tp, SRAM_10M_AMP2, 0x0208); | 2845 | sram_write(tp, SRAM_10M_AMP2, 0x0208); |
2747 | 2846 | ||
2847 | r8153_eee_en(tp, true); | ||
2848 | ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX); | ||
2849 | |||
2850 | r8153_aldps_en(tp, true); | ||
2851 | r8152b_enable_fc(tp); | ||
2852 | |||
2748 | set_bit(PHY_RESET, &tp->flags); | 2853 | set_bit(PHY_RESET, &tp->flags); |
2749 | } | 2854 | } |
2750 | 2855 | ||
@@ -2866,21 +2971,6 @@ static void r8153_enter_oob(struct r8152 *tp) | |||
2866 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); | 2971 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); |
2867 | } | 2972 | } |
2868 | 2973 | ||
2869 | static void r8153_aldps_en(struct r8152 *tp, bool enable) | ||
2870 | { | ||
2871 | u16 data; | ||
2872 | |||
2873 | data = ocp_reg_read(tp, OCP_POWER_CFG); | ||
2874 | if (enable) { | ||
2875 | data |= EN_ALDPS; | ||
2876 | ocp_reg_write(tp, OCP_POWER_CFG, data); | ||
2877 | } else { | ||
2878 | data &= ~EN_ALDPS; | ||
2879 | ocp_reg_write(tp, OCP_POWER_CFG, data); | ||
2880 | msleep(20); | ||
2881 | } | ||
2882 | } | ||
2883 | |||
2884 | static void rtl8153_disable(struct r8152 *tp) | 2974 | static void rtl8153_disable(struct r8152 *tp) |
2885 | { | 2975 | { |
2886 | r8153_aldps_en(tp, false); | 2976 | r8153_aldps_en(tp, false); |
@@ -3246,103 +3336,6 @@ static int rtl8152_close(struct net_device *netdev) | |||
3246 | return res; | 3336 | return res; |
3247 | } | 3337 | } |
3248 | 3338 | ||
3249 | static inline void r8152_mmd_indirect(struct r8152 *tp, u16 dev, u16 reg) | ||
3250 | { | ||
3251 | ocp_reg_write(tp, OCP_EEE_AR, FUN_ADDR | dev); | ||
3252 | ocp_reg_write(tp, OCP_EEE_DATA, reg); | ||
3253 | ocp_reg_write(tp, OCP_EEE_AR, FUN_DATA | dev); | ||
3254 | } | ||
3255 | |||
3256 | static u16 r8152_mmd_read(struct r8152 *tp, u16 dev, u16 reg) | ||
3257 | { | ||
3258 | u16 data; | ||
3259 | |||
3260 | r8152_mmd_indirect(tp, dev, reg); | ||
3261 | data = ocp_reg_read(tp, OCP_EEE_DATA); | ||
3262 | ocp_reg_write(tp, OCP_EEE_AR, 0x0000); | ||
3263 | |||
3264 | return data; | ||
3265 | } | ||
3266 | |||
3267 | static void r8152_mmd_write(struct r8152 *tp, u16 dev, u16 reg, u16 data) | ||
3268 | { | ||
3269 | r8152_mmd_indirect(tp, dev, reg); | ||
3270 | ocp_reg_write(tp, OCP_EEE_DATA, data); | ||
3271 | ocp_reg_write(tp, OCP_EEE_AR, 0x0000); | ||
3272 | } | ||
3273 | |||
3274 | static void r8152_eee_en(struct r8152 *tp, bool enable) | ||
3275 | { | ||
3276 | u16 config1, config2, config3; | ||
3277 | u32 ocp_data; | ||
3278 | |||
3279 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); | ||
3280 | config1 = ocp_reg_read(tp, OCP_EEE_CONFIG1) & ~sd_rise_time_mask; | ||
3281 | config2 = ocp_reg_read(tp, OCP_EEE_CONFIG2); | ||
3282 | config3 = ocp_reg_read(tp, OCP_EEE_CONFIG3) & ~fast_snr_mask; | ||
3283 | |||
3284 | if (enable) { | ||
3285 | ocp_data |= EEE_RX_EN | EEE_TX_EN; | ||
3286 | config1 |= EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | RX_QUIET_EN; | ||
3287 | config1 |= sd_rise_time(1); | ||
3288 | config2 |= RG_DACQUIET_EN | RG_LDVQUIET_EN; | ||
3289 | config3 |= fast_snr(42); | ||
3290 | } else { | ||
3291 | ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); | ||
3292 | config1 &= ~(EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | | ||
3293 | RX_QUIET_EN); | ||
3294 | config1 |= sd_rise_time(7); | ||
3295 | config2 &= ~(RG_DACQUIET_EN | RG_LDVQUIET_EN); | ||
3296 | config3 |= fast_snr(511); | ||
3297 | } | ||
3298 | |||
3299 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); | ||
3300 | ocp_reg_write(tp, OCP_EEE_CONFIG1, config1); | ||
3301 | ocp_reg_write(tp, OCP_EEE_CONFIG2, config2); | ||
3302 | ocp_reg_write(tp, OCP_EEE_CONFIG3, config3); | ||
3303 | } | ||
3304 | |||
3305 | static void r8152b_enable_eee(struct r8152 *tp) | ||
3306 | { | ||
3307 | r8152_eee_en(tp, true); | ||
3308 | r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, MDIO_EEE_100TX); | ||
3309 | } | ||
3310 | |||
3311 | static void r8153_eee_en(struct r8152 *tp, bool enable) | ||
3312 | { | ||
3313 | u32 ocp_data; | ||
3314 | u16 config; | ||
3315 | |||
3316 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); | ||
3317 | config = ocp_reg_read(tp, OCP_EEE_CFG); | ||
3318 | |||
3319 | if (enable) { | ||
3320 | ocp_data |= EEE_RX_EN | EEE_TX_EN; | ||
3321 | config |= EEE10_EN; | ||
3322 | } else { | ||
3323 | ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); | ||
3324 | config &= ~EEE10_EN; | ||
3325 | } | ||
3326 | |||
3327 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); | ||
3328 | ocp_reg_write(tp, OCP_EEE_CFG, config); | ||
3329 | } | ||
3330 | |||
3331 | static void r8153_enable_eee(struct r8152 *tp) | ||
3332 | { | ||
3333 | r8153_eee_en(tp, true); | ||
3334 | ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX); | ||
3335 | } | ||
3336 | |||
3337 | static void r8152b_enable_fc(struct r8152 *tp) | ||
3338 | { | ||
3339 | u16 anar; | ||
3340 | |||
3341 | anar = r8152_mdio_read(tp, MII_ADVERTISE); | ||
3342 | anar |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; | ||
3343 | r8152_mdio_write(tp, MII_ADVERTISE, anar); | ||
3344 | } | ||
3345 | |||
3346 | static void rtl_tally_reset(struct r8152 *tp) | 3339 | static void rtl_tally_reset(struct r8152 *tp) |
3347 | { | 3340 | { |
3348 | u32 ocp_data; | 3341 | u32 ocp_data; |
@@ -3355,10 +3348,17 @@ static void rtl_tally_reset(struct r8152 *tp) | |||
3355 | static void r8152b_init(struct r8152 *tp) | 3348 | static void r8152b_init(struct r8152 *tp) |
3356 | { | 3349 | { |
3357 | u32 ocp_data; | 3350 | u32 ocp_data; |
3351 | u16 data; | ||
3358 | 3352 | ||
3359 | if (test_bit(RTL8152_UNPLUG, &tp->flags)) | 3353 | if (test_bit(RTL8152_UNPLUG, &tp->flags)) |
3360 | return; | 3354 | return; |
3361 | 3355 | ||
3356 | data = r8152_mdio_read(tp, MII_BMCR); | ||
3357 | if (data & BMCR_PDOWN) { | ||
3358 | data &= ~BMCR_PDOWN; | ||
3359 | r8152_mdio_write(tp, MII_BMCR, data); | ||
3360 | } | ||
3361 | |||
3362 | r8152_aldps_en(tp, false); | 3362 | r8152_aldps_en(tp, false); |
3363 | 3363 | ||
3364 | if (tp->version == RTL_VER_01) { | 3364 | if (tp->version == RTL_VER_01) { |
@@ -3380,9 +3380,6 @@ static void r8152b_init(struct r8152 *tp) | |||
3380 | SPDWN_RXDV_MSK | SPDWN_LINKCHG_MSK; | 3380 | SPDWN_RXDV_MSK | SPDWN_LINKCHG_MSK; |
3381 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_GPHY_INTR_IMR, ocp_data); | 3381 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_GPHY_INTR_IMR, ocp_data); |
3382 | 3382 | ||
3383 | r8152b_enable_eee(tp); | ||
3384 | r8152_aldps_en(tp, true); | ||
3385 | r8152b_enable_fc(tp); | ||
3386 | rtl_tally_reset(tp); | 3383 | rtl_tally_reset(tp); |
3387 | 3384 | ||
3388 | /* enable rx aggregation */ | 3385 | /* enable rx aggregation */ |
@@ -3394,12 +3391,12 @@ static void r8152b_init(struct r8152 *tp) | |||
3394 | static void r8153_init(struct r8152 *tp) | 3391 | static void r8153_init(struct r8152 *tp) |
3395 | { | 3392 | { |
3396 | u32 ocp_data; | 3393 | u32 ocp_data; |
3394 | u16 data; | ||
3397 | int i; | 3395 | int i; |
3398 | 3396 | ||
3399 | if (test_bit(RTL8152_UNPLUG, &tp->flags)) | 3397 | if (test_bit(RTL8152_UNPLUG, &tp->flags)) |
3400 | return; | 3398 | return; |
3401 | 3399 | ||
3402 | r8153_aldps_en(tp, false); | ||
3403 | r8153_u1u2en(tp, false); | 3400 | r8153_u1u2en(tp, false); |
3404 | 3401 | ||
3405 | for (i = 0; i < 500; i++) { | 3402 | for (i = 0; i < 500; i++) { |
@@ -3416,6 +3413,23 @@ static void r8153_init(struct r8152 *tp) | |||
3416 | msleep(20); | 3413 | msleep(20); |
3417 | } | 3414 | } |
3418 | 3415 | ||
3416 | if (tp->version == RTL_VER_03 || tp->version == RTL_VER_04 || | ||
3417 | tp->version == RTL_VER_05) | ||
3418 | ocp_reg_write(tp, OCP_ADC_CFG, CKADSEL_L | ADC_EN | EN_EMI_L); | ||
3419 | |||
3420 | data = r8152_mdio_read(tp, MII_BMCR); | ||
3421 | if (data & BMCR_PDOWN) { | ||
3422 | data &= ~BMCR_PDOWN; | ||
3423 | r8152_mdio_write(tp, MII_BMCR, data); | ||
3424 | } | ||
3425 | |||
3426 | for (i = 0; i < 500; i++) { | ||
3427 | ocp_data = ocp_reg_read(tp, OCP_PHY_STATUS) & PHY_STAT_MASK; | ||
3428 | if (ocp_data == PHY_STAT_LAN_ON) | ||
3429 | break; | ||
3430 | msleep(20); | ||
3431 | } | ||
3432 | |||
3419 | usb_disable_lpm(tp->udev); | 3433 | usb_disable_lpm(tp->udev); |
3420 | r8153_u2p3en(tp, false); | 3434 | r8153_u2p3en(tp, false); |
3421 | 3435 | ||
@@ -3483,9 +3497,6 @@ static void r8153_init(struct r8152 *tp) | |||
3483 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, 0); | 3497 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, 0); |
3484 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, 0); | 3498 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, 0); |
3485 | 3499 | ||
3486 | r8153_enable_eee(tp); | ||
3487 | r8153_aldps_en(tp, true); | ||
3488 | r8152b_enable_fc(tp); | ||
3489 | rtl_tally_reset(tp); | 3500 | rtl_tally_reset(tp); |
3490 | r8153_u2p3en(tp, true); | 3501 | r8153_u2p3en(tp, true); |
3491 | } | 3502 | } |
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index c68fe495d3f9..4244b9d4418e 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c | |||
@@ -914,7 +914,9 @@ vmxnet3_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, | |||
914 | { | 914 | { |
915 | struct Vmxnet3_TxDataDesc *tdd; | 915 | struct Vmxnet3_TxDataDesc *tdd; |
916 | 916 | ||
917 | tdd = tq->data_ring.base + tq->tx_ring.next2fill; | 917 | tdd = (struct Vmxnet3_TxDataDesc *)((u8 *)tq->data_ring.base + |
918 | tq->tx_ring.next2fill * | ||
919 | tq->txdata_desc_size); | ||
918 | 920 | ||
919 | memcpy(tdd->data, skb->data, ctx->copy_size); | 921 | memcpy(tdd->data, skb->data, ctx->copy_size); |
920 | netdev_dbg(adapter->netdev, | 922 | netdev_dbg(adapter->netdev, |
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index 74fc03072b87..7dc37a090549 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h | |||
@@ -69,10 +69,10 @@ | |||
69 | /* | 69 | /* |
70 | * Version numbers | 70 | * Version numbers |
71 | */ | 71 | */ |
72 | #define VMXNET3_DRIVER_VERSION_STRING "1.4.9.0-k" | 72 | #define VMXNET3_DRIVER_VERSION_STRING "1.4.a.0-k" |
73 | 73 | ||
74 | /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ | 74 | /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ |
75 | #define VMXNET3_DRIVER_VERSION_NUM 0x01040900 | 75 | #define VMXNET3_DRIVER_VERSION_NUM 0x01040a00 |
76 | 76 | ||
77 | #if defined(CONFIG_PCI_MSI) | 77 | #if defined(CONFIG_PCI_MSI) |
78 | /* RSS only makes sense if MSI-X is supported. */ | 78 | /* RSS only makes sense if MSI-X is supported. */ |
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index c0dda6fc0921..6e65832051d6 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -2782,14 +2782,15 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev, | |||
2782 | struct net_device *lowerdev = NULL; | 2782 | struct net_device *lowerdev = NULL; |
2783 | 2783 | ||
2784 | if (conf->flags & VXLAN_F_GPE) { | 2784 | if (conf->flags & VXLAN_F_GPE) { |
2785 | if (conf->flags & ~VXLAN_F_ALLOWED_GPE) | ||
2786 | return -EINVAL; | ||
2787 | /* For now, allow GPE only together with COLLECT_METADATA. | 2785 | /* For now, allow GPE only together with COLLECT_METADATA. |
2788 | * This can be relaxed later; in such case, the other side | 2786 | * This can be relaxed later; in such case, the other side |
2789 | * of the PtP link will have to be provided. | 2787 | * of the PtP link will have to be provided. |
2790 | */ | 2788 | */ |
2791 | if (!(conf->flags & VXLAN_F_COLLECT_METADATA)) | 2789 | if ((conf->flags & ~VXLAN_F_ALLOWED_GPE) || |
2790 | !(conf->flags & VXLAN_F_COLLECT_METADATA)) { | ||
2791 | pr_info("unsupported combination of extensions\n"); | ||
2792 | return -EINVAL; | 2792 | return -EINVAL; |
2793 | } | ||
2793 | 2794 | ||
2794 | vxlan_raw_setup(dev); | 2795 | vxlan_raw_setup(dev); |
2795 | } else { | 2796 | } else { |
@@ -2842,6 +2843,9 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev, | |||
2842 | dev->mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM); | 2843 | dev->mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM); |
2843 | 2844 | ||
2844 | needed_headroom = lowerdev->hard_header_len; | 2845 | needed_headroom = lowerdev->hard_header_len; |
2846 | } else if (vxlan_addr_multicast(&dst->remote_ip)) { | ||
2847 | pr_info("multicast destination requires interface to be specified\n"); | ||
2848 | return -EINVAL; | ||
2845 | } | 2849 | } |
2846 | 2850 | ||
2847 | if (conf->mtu) { | 2851 | if (conf->mtu) { |
@@ -2874,8 +2878,10 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev, | |||
2874 | tmp->cfg.saddr.sa.sa_family == AF_INET6) == use_ipv6 && | 2878 | tmp->cfg.saddr.sa.sa_family == AF_INET6) == use_ipv6 && |
2875 | tmp->cfg.dst_port == vxlan->cfg.dst_port && | 2879 | tmp->cfg.dst_port == vxlan->cfg.dst_port && |
2876 | (tmp->flags & VXLAN_F_RCV_FLAGS) == | 2880 | (tmp->flags & VXLAN_F_RCV_FLAGS) == |
2877 | (vxlan->flags & VXLAN_F_RCV_FLAGS)) | 2881 | (vxlan->flags & VXLAN_F_RCV_FLAGS)) { |
2878 | return -EEXIST; | 2882 | pr_info("duplicate VNI %u\n", be32_to_cpu(conf->vni)); |
2883 | return -EEXIST; | ||
2884 | } | ||
2879 | } | 2885 | } |
2880 | 2886 | ||
2881 | dev->ethtool_ops = &vxlan_ethtool_ops; | 2887 | dev->ethtool_ops = &vxlan_ethtool_ops; |
@@ -2909,7 +2915,6 @@ static int vxlan_newlink(struct net *src_net, struct net_device *dev, | |||
2909 | struct nlattr *tb[], struct nlattr *data[]) | 2915 | struct nlattr *tb[], struct nlattr *data[]) |
2910 | { | 2916 | { |
2911 | struct vxlan_config conf; | 2917 | struct vxlan_config conf; |
2912 | int err; | ||
2913 | 2918 | ||
2914 | memset(&conf, 0, sizeof(conf)); | 2919 | memset(&conf, 0, sizeof(conf)); |
2915 | 2920 | ||
@@ -3018,26 +3023,7 @@ static int vxlan_newlink(struct net *src_net, struct net_device *dev, | |||
3018 | if (tb[IFLA_MTU]) | 3023 | if (tb[IFLA_MTU]) |
3019 | conf.mtu = nla_get_u32(tb[IFLA_MTU]); | 3024 | conf.mtu = nla_get_u32(tb[IFLA_MTU]); |
3020 | 3025 | ||
3021 | err = vxlan_dev_configure(src_net, dev, &conf); | 3026 | return vxlan_dev_configure(src_net, dev, &conf); |
3022 | switch (err) { | ||
3023 | case -ENODEV: | ||
3024 | pr_info("ifindex %d does not exist\n", conf.remote_ifindex); | ||
3025 | break; | ||
3026 | |||
3027 | case -EPERM: | ||
3028 | pr_info("IPv6 is disabled via sysctl\n"); | ||
3029 | break; | ||
3030 | |||
3031 | case -EEXIST: | ||
3032 | pr_info("duplicate VNI %u\n", be32_to_cpu(conf.vni)); | ||
3033 | break; | ||
3034 | |||
3035 | case -EINVAL: | ||
3036 | pr_info("unsupported combination of extensions\n"); | ||
3037 | break; | ||
3038 | } | ||
3039 | |||
3040 | return err; | ||
3041 | } | 3027 | } |
3042 | 3028 | ||
3043 | static void vxlan_dellink(struct net_device *dev, struct list_head *head) | 3029 | static void vxlan_dellink(struct net_device *dev, struct list_head *head) |
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 78db5d679f19..24c8d65bcf34 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c | |||
@@ -1525,7 +1525,7 @@ static void ath10k_htt_rx_h_filter(struct ath10k *ar, | |||
1525 | static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) | 1525 | static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) |
1526 | { | 1526 | { |
1527 | struct ath10k *ar = htt->ar; | 1527 | struct ath10k *ar = htt->ar; |
1528 | static struct ieee80211_rx_status rx_status; | 1528 | struct ieee80211_rx_status *rx_status = &htt->rx_status; |
1529 | struct sk_buff_head amsdu; | 1529 | struct sk_buff_head amsdu; |
1530 | int ret; | 1530 | int ret; |
1531 | 1531 | ||
@@ -1549,11 +1549,11 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) | |||
1549 | return ret; | 1549 | return ret; |
1550 | } | 1550 | } |
1551 | 1551 | ||
1552 | ath10k_htt_rx_h_ppdu(ar, &amsdu, &rx_status, 0xffff); | 1552 | ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff); |
1553 | ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0); | 1553 | ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0); |
1554 | ath10k_htt_rx_h_filter(ar, &amsdu, &rx_status); | 1554 | ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); |
1555 | ath10k_htt_rx_h_mpdu(ar, &amsdu, &rx_status); | 1555 | ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); |
1556 | ath10k_htt_rx_h_deliver(ar, &amsdu, &rx_status); | 1556 | ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status); |
1557 | 1557 | ||
1558 | return 0; | 1558 | return 0; |
1559 | } | 1559 | } |
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 9a22c478dd1b..07933c51a850 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c | |||
@@ -3162,7 +3162,6 @@ static int ath10k_pci_probe(struct pci_dev *pdev, | |||
3162 | pci_hard_reset = ath10k_pci_qca988x_chip_reset; | 3162 | pci_hard_reset = ath10k_pci_qca988x_chip_reset; |
3163 | break; | 3163 | break; |
3164 | case QCA9887_1_0_DEVICE_ID: | 3164 | case QCA9887_1_0_DEVICE_ID: |
3165 | dev_warn(&pdev->dev, "QCA9887 support is still experimental, there are likely bugs. You have been warned.\n"); | ||
3166 | hw_rev = ATH10K_HW_QCA9887; | 3165 | hw_rev = ATH10K_HW_QCA9887; |
3167 | pci_ps = false; | 3166 | pci_ps = false; |
3168 | pci_soft_reset = ath10k_pci_warm_reset; | 3167 | pci_soft_reset = ath10k_pci_warm_reset; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index d1d0c06d627c..14b13f07cd1f 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -2482,6 +2482,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2482 | return -EINVAL; | 2482 | return -EINVAL; |
2483 | } | 2483 | } |
2484 | 2484 | ||
2485 | ath9k_gpio_cap_init(ah); | ||
2486 | |||
2485 | if (AR_SREV_9485(ah) || | 2487 | if (AR_SREV_9485(ah) || |
2486 | AR_SREV_9285(ah) || | 2488 | AR_SREV_9285(ah) || |
2487 | AR_SREV_9330(ah) || | 2489 | AR_SREV_9330(ah) || |
@@ -2531,8 +2533,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2531 | else | 2533 | else |
2532 | pCap->hw_caps &= ~ATH9K_HW_CAP_HT; | 2534 | pCap->hw_caps &= ~ATH9K_HW_CAP_HT; |
2533 | 2535 | ||
2534 | ath9k_gpio_cap_init(ah); | ||
2535 | |||
2536 | if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) | 2536 | if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) |
2537 | pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX; | 2537 | pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX; |
2538 | else | 2538 | else |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a394622c9022..7cb65c303f8d 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -718,9 +718,12 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
718 | if (!ath_complete_reset(sc, false)) | 718 | if (!ath_complete_reset(sc, false)) |
719 | ah->reset_power_on = false; | 719 | ah->reset_power_on = false; |
720 | 720 | ||
721 | if (ah->led_pin >= 0) | 721 | if (ah->led_pin >= 0) { |
722 | ath9k_hw_set_gpio(ah, ah->led_pin, | 722 | ath9k_hw_set_gpio(ah, ah->led_pin, |
723 | (ah->config.led_active_high) ? 1 : 0); | 723 | (ah->config.led_active_high) ? 1 : 0); |
724 | ath9k_hw_gpio_request_out(ah, ah->led_pin, NULL, | ||
725 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
726 | } | ||
724 | 727 | ||
725 | /* | 728 | /* |
726 | * Reset key cache to sane defaults (all entries cleared) instead of | 729 | * Reset key cache to sane defaults (all entries cleared) instead of |
@@ -864,9 +867,11 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
864 | 867 | ||
865 | spin_lock_bh(&sc->sc_pcu_lock); | 868 | spin_lock_bh(&sc->sc_pcu_lock); |
866 | 869 | ||
867 | if (ah->led_pin >= 0) | 870 | if (ah->led_pin >= 0) { |
868 | ath9k_hw_set_gpio(ah, ah->led_pin, | 871 | ath9k_hw_set_gpio(ah, ah->led_pin, |
869 | (ah->config.led_active_high) ? 0 : 1); | 872 | (ah->config.led_active_high) ? 0 : 1); |
873 | ath9k_hw_gpio_request_in(ah, ah->led_pin, NULL); | ||
874 | } | ||
870 | 875 | ||
871 | ath_prepare_reset(sc); | 876 | ath_prepare_reset(sc); |
872 | 877 | ||
@@ -1154,6 +1159,7 @@ void ath9k_calculate_summary_state(struct ath_softc *sc, | |||
1154 | bool changed = (iter_data.primary_sta != ctx->primary_sta); | 1159 | bool changed = (iter_data.primary_sta != ctx->primary_sta); |
1155 | 1160 | ||
1156 | if (iter_data.primary_sta) { | 1161 | if (iter_data.primary_sta) { |
1162 | iter_data.primary_beacon_vif = iter_data.primary_sta; | ||
1157 | iter_data.beacons = true; | 1163 | iter_data.beacons = true; |
1158 | ath9k_set_assoc_state(sc, iter_data.primary_sta, | 1164 | ath9k_set_assoc_state(sc, iter_data.primary_sta, |
1159 | changed); | 1165 | changed); |
@@ -1563,13 +1569,13 @@ static int ath9k_sta_state(struct ieee80211_hw *hw, | |||
1563 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1569 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1564 | int ret = 0; | 1570 | int ret = 0; |
1565 | 1571 | ||
1566 | if (old_state == IEEE80211_STA_AUTH && | 1572 | if (old_state == IEEE80211_STA_NOTEXIST && |
1567 | new_state == IEEE80211_STA_ASSOC) { | 1573 | new_state == IEEE80211_STA_NONE) { |
1568 | ret = ath9k_sta_add(hw, vif, sta); | 1574 | ret = ath9k_sta_add(hw, vif, sta); |
1569 | ath_dbg(common, CONFIG, | 1575 | ath_dbg(common, CONFIG, |
1570 | "Add station: %pM\n", sta->addr); | 1576 | "Add station: %pM\n", sta->addr); |
1571 | } else if (old_state == IEEE80211_STA_ASSOC && | 1577 | } else if (old_state == IEEE80211_STA_NONE && |
1572 | new_state == IEEE80211_STA_AUTH) { | 1578 | new_state == IEEE80211_STA_NOTEXIST) { |
1573 | ret = ath9k_sta_remove(hw, vif, sta); | 1579 | ret = ath9k_sta_remove(hw, vif, sta); |
1574 | ath_dbg(common, CONFIG, | 1580 | ath_dbg(common, CONFIG, |
1575 | "Remove station: %pM\n", sta->addr); | 1581 | "Remove station: %pM\n", sta->addr); |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 2628d5e12c64..b8aec5e5ef93 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | |||
@@ -4527,7 +4527,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, | |||
4527 | (u8 *)&settings->beacon.head[ie_offset], | 4527 | (u8 *)&settings->beacon.head[ie_offset], |
4528 | settings->beacon.head_len - ie_offset, | 4528 | settings->beacon.head_len - ie_offset, |
4529 | WLAN_EID_SSID); | 4529 | WLAN_EID_SSID); |
4530 | if (!ssid_ie) | 4530 | if (!ssid_ie || ssid_ie->len > IEEE80211_MAX_SSID_LEN) |
4531 | return -EINVAL; | 4531 | return -EINVAL; |
4532 | 4532 | ||
4533 | memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len); | 4533 | memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len); |
@@ -5635,7 +5635,7 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp, | |||
5635 | ifevent->action, ifevent->flags, ifevent->ifidx, | 5635 | ifevent->action, ifevent->flags, ifevent->ifidx, |
5636 | ifevent->bsscfgidx); | 5636 | ifevent->bsscfgidx); |
5637 | 5637 | ||
5638 | mutex_lock(&event->vif_event_lock); | 5638 | spin_lock(&event->vif_event_lock); |
5639 | event->action = ifevent->action; | 5639 | event->action = ifevent->action; |
5640 | vif = event->vif; | 5640 | vif = event->vif; |
5641 | 5641 | ||
@@ -5643,7 +5643,7 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp, | |||
5643 | case BRCMF_E_IF_ADD: | 5643 | case BRCMF_E_IF_ADD: |
5644 | /* waiting process may have timed out */ | 5644 | /* waiting process may have timed out */ |
5645 | if (!cfg->vif_event.vif) { | 5645 | if (!cfg->vif_event.vif) { |
5646 | mutex_unlock(&event->vif_event_lock); | 5646 | spin_unlock(&event->vif_event_lock); |
5647 | return -EBADF; | 5647 | return -EBADF; |
5648 | } | 5648 | } |
5649 | 5649 | ||
@@ -5654,24 +5654,24 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp, | |||
5654 | ifp->ndev->ieee80211_ptr = &vif->wdev; | 5654 | ifp->ndev->ieee80211_ptr = &vif->wdev; |
5655 | SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy)); | 5655 | SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy)); |
5656 | } | 5656 | } |
5657 | mutex_unlock(&event->vif_event_lock); | 5657 | spin_unlock(&event->vif_event_lock); |
5658 | wake_up(&event->vif_wq); | 5658 | wake_up(&event->vif_wq); |
5659 | return 0; | 5659 | return 0; |
5660 | 5660 | ||
5661 | case BRCMF_E_IF_DEL: | 5661 | case BRCMF_E_IF_DEL: |
5662 | mutex_unlock(&event->vif_event_lock); | 5662 | spin_unlock(&event->vif_event_lock); |
5663 | /* event may not be upon user request */ | 5663 | /* event may not be upon user request */ |
5664 | if (brcmf_cfg80211_vif_event_armed(cfg)) | 5664 | if (brcmf_cfg80211_vif_event_armed(cfg)) |
5665 | wake_up(&event->vif_wq); | 5665 | wake_up(&event->vif_wq); |
5666 | return 0; | 5666 | return 0; |
5667 | 5667 | ||
5668 | case BRCMF_E_IF_CHANGE: | 5668 | case BRCMF_E_IF_CHANGE: |
5669 | mutex_unlock(&event->vif_event_lock); | 5669 | spin_unlock(&event->vif_event_lock); |
5670 | wake_up(&event->vif_wq); | 5670 | wake_up(&event->vif_wq); |
5671 | return 0; | 5671 | return 0; |
5672 | 5672 | ||
5673 | default: | 5673 | default: |
5674 | mutex_unlock(&event->vif_event_lock); | 5674 | spin_unlock(&event->vif_event_lock); |
5675 | break; | 5675 | break; |
5676 | } | 5676 | } |
5677 | return -EINVAL; | 5677 | return -EINVAL; |
@@ -5792,7 +5792,7 @@ static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg) | |||
5792 | static void init_vif_event(struct brcmf_cfg80211_vif_event *event) | 5792 | static void init_vif_event(struct brcmf_cfg80211_vif_event *event) |
5793 | { | 5793 | { |
5794 | init_waitqueue_head(&event->vif_wq); | 5794 | init_waitqueue_head(&event->vif_wq); |
5795 | mutex_init(&event->vif_event_lock); | 5795 | spin_lock_init(&event->vif_event_lock); |
5796 | } | 5796 | } |
5797 | 5797 | ||
5798 | static s32 brcmf_dongle_roam(struct brcmf_if *ifp) | 5798 | static s32 brcmf_dongle_roam(struct brcmf_if *ifp) |
@@ -6691,9 +6691,9 @@ static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event, | |||
6691 | { | 6691 | { |
6692 | u8 evt_action; | 6692 | u8 evt_action; |
6693 | 6693 | ||
6694 | mutex_lock(&event->vif_event_lock); | 6694 | spin_lock(&event->vif_event_lock); |
6695 | evt_action = event->action; | 6695 | evt_action = event->action; |
6696 | mutex_unlock(&event->vif_event_lock); | 6696 | spin_unlock(&event->vif_event_lock); |
6697 | return evt_action == action; | 6697 | return evt_action == action; |
6698 | } | 6698 | } |
6699 | 6699 | ||
@@ -6702,10 +6702,10 @@ void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg, | |||
6702 | { | 6702 | { |
6703 | struct brcmf_cfg80211_vif_event *event = &cfg->vif_event; | 6703 | struct brcmf_cfg80211_vif_event *event = &cfg->vif_event; |
6704 | 6704 | ||
6705 | mutex_lock(&event->vif_event_lock); | 6705 | spin_lock(&event->vif_event_lock); |
6706 | event->vif = vif; | 6706 | event->vif = vif; |
6707 | event->action = 0; | 6707 | event->action = 0; |
6708 | mutex_unlock(&event->vif_event_lock); | 6708 | spin_unlock(&event->vif_event_lock); |
6709 | } | 6709 | } |
6710 | 6710 | ||
6711 | bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg) | 6711 | bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg) |
@@ -6713,9 +6713,9 @@ bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg) | |||
6713 | struct brcmf_cfg80211_vif_event *event = &cfg->vif_event; | 6713 | struct brcmf_cfg80211_vif_event *event = &cfg->vif_event; |
6714 | bool armed; | 6714 | bool armed; |
6715 | 6715 | ||
6716 | mutex_lock(&event->vif_event_lock); | 6716 | spin_lock(&event->vif_event_lock); |
6717 | armed = event->vif != NULL; | 6717 | armed = event->vif != NULL; |
6718 | mutex_unlock(&event->vif_event_lock); | 6718 | spin_unlock(&event->vif_event_lock); |
6719 | 6719 | ||
6720 | return armed; | 6720 | return armed; |
6721 | } | 6721 | } |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h index 7d77f869b7f1..8889832c17e0 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | |||
@@ -227,7 +227,7 @@ struct escan_info { | |||
227 | */ | 227 | */ |
228 | struct brcmf_cfg80211_vif_event { | 228 | struct brcmf_cfg80211_vif_event { |
229 | wait_queue_head_t vif_wq; | 229 | wait_queue_head_t vif_wq; |
230 | struct mutex vif_event_lock; | 230 | spinlock_t vif_event_lock; |
231 | u8 action; | 231 | u8 action; |
232 | struct brcmf_cfg80211_vif *vif; | 232 | struct brcmf_cfg80211_vif *vif; |
233 | }; | 233 | }; |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index 8d16f0204985..65e8c8766441 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | |||
@@ -743,7 +743,7 @@ static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx, | |||
743 | * serious troublesome side effects. The p2p module will clean | 743 | * serious troublesome side effects. The p2p module will clean |
744 | * up the ifp if needed. | 744 | * up the ifp if needed. |
745 | */ | 745 | */ |
746 | brcmf_p2p_ifp_removed(ifp); | 746 | brcmf_p2p_ifp_removed(ifp, rtnl_locked); |
747 | kfree(ifp); | 747 | kfree(ifp); |
748 | } | 748 | } |
749 | } | 749 | } |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c index 66f942f7448e..de19c7c92bc6 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | |||
@@ -2297,7 +2297,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) | |||
2297 | return err; | 2297 | return err; |
2298 | } | 2298 | } |
2299 | 2299 | ||
2300 | void brcmf_p2p_ifp_removed(struct brcmf_if *ifp) | 2300 | void brcmf_p2p_ifp_removed(struct brcmf_if *ifp, bool rtnl_locked) |
2301 | { | 2301 | { |
2302 | struct brcmf_cfg80211_info *cfg; | 2302 | struct brcmf_cfg80211_info *cfg; |
2303 | struct brcmf_cfg80211_vif *vif; | 2303 | struct brcmf_cfg80211_vif *vif; |
@@ -2306,9 +2306,11 @@ void brcmf_p2p_ifp_removed(struct brcmf_if *ifp) | |||
2306 | vif = ifp->vif; | 2306 | vif = ifp->vif; |
2307 | cfg = wdev_to_cfg(&vif->wdev); | 2307 | cfg = wdev_to_cfg(&vif->wdev); |
2308 | cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; | 2308 | cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; |
2309 | rtnl_lock(); | 2309 | if (!rtnl_locked) |
2310 | rtnl_lock(); | ||
2310 | cfg80211_unregister_wdev(&vif->wdev); | 2311 | cfg80211_unregister_wdev(&vif->wdev); |
2311 | rtnl_unlock(); | 2312 | if (!rtnl_locked) |
2313 | rtnl_unlock(); | ||
2312 | brcmf_free_vif(vif); | 2314 | brcmf_free_vif(vif); |
2313 | } | 2315 | } |
2314 | 2316 | ||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h index a3bd18c2360b..8ce9447533ef 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h | |||
@@ -155,7 +155,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name, | |||
155 | int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev); | 155 | int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev); |
156 | int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg, | 156 | int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg, |
157 | enum brcmf_fil_p2p_if_types if_type); | 157 | enum brcmf_fil_p2p_if_types if_type); |
158 | void brcmf_p2p_ifp_removed(struct brcmf_if *ifp); | 158 | void brcmf_p2p_ifp_removed(struct brcmf_if *ifp, bool rtnl_locked); |
159 | int brcmf_p2p_start_device(struct wiphy *wiphy, struct wireless_dev *wdev); | 159 | int brcmf_p2p_start_device(struct wiphy *wiphy, struct wireless_dev *wdev); |
160 | void brcmf_p2p_stop_device(struct wiphy *wiphy, struct wireless_dev *wdev); | 160 | void brcmf_p2p_stop_device(struct wiphy *wiphy, struct wireless_dev *wdev); |
161 | int brcmf_p2p_scan_prep(struct wiphy *wiphy, | 161 | int brcmf_p2p_scan_prep(struct wiphy *wiphy, |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c index 1abcabb9b6cd..46b52bf705fb 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c | |||
@@ -960,5 +960,6 @@ int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id) | |||
960 | } | 960 | } |
961 | 961 | ||
962 | mvm->fw_dbg_conf = conf_id; | 962 | mvm->fw_dbg_conf = conf_id; |
963 | return ret; | 963 | |
964 | return 0; | ||
964 | } | 965 | } |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.h index f7dff7612c9c..e9f1be9da7d4 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.h | |||
@@ -105,7 +105,8 @@ iwl_fw_dbg_trigger_vif_match(struct iwl_fw_dbg_trigger_tlv *trig, | |||
105 | { | 105 | { |
106 | u32 trig_vif = le32_to_cpu(trig->vif_type); | 106 | u32 trig_vif = le32_to_cpu(trig->vif_type); |
107 | 107 | ||
108 | return trig_vif == IWL_FW_DBG_CONF_VIF_ANY || vif->type == trig_vif; | 108 | return trig_vif == IWL_FW_DBG_CONF_VIF_ANY || |
109 | ieee80211_vif_type_p2p(vif) == trig_vif; | ||
109 | } | 110 | } |
110 | 111 | ||
111 | static inline bool | 112 | static inline bool |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 6d6064534d59..5dd77e336617 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | |||
@@ -624,6 +624,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
624 | hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN | | 624 | hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN | |
625 | NL80211_FEATURE_LOW_PRIORITY_SCAN | | 625 | NL80211_FEATURE_LOW_PRIORITY_SCAN | |
626 | NL80211_FEATURE_P2P_GO_OPPPS | | 626 | NL80211_FEATURE_P2P_GO_OPPPS | |
627 | NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE | | ||
627 | NL80211_FEATURE_DYNAMIC_SMPS | | 628 | NL80211_FEATURE_DYNAMIC_SMPS | |
628 | NL80211_FEATURE_STATIC_SMPS | | 629 | NL80211_FEATURE_STATIC_SMPS | |
629 | NL80211_FEATURE_SUPPORTS_WMM_ADMISSION; | 630 | NL80211_FEATURE_SUPPORTS_WMM_ADMISSION; |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index b4fc86d5d7ef..6a615bb73042 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | |||
@@ -467,6 +467,8 @@ struct iwl_mvm_vif { | |||
467 | static inline struct iwl_mvm_vif * | 467 | static inline struct iwl_mvm_vif * |
468 | iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif) | 468 | iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif) |
469 | { | 469 | { |
470 | if (!vif) | ||
471 | return NULL; | ||
470 | return (void *)vif->drv_priv; | 472 | return (void *)vif->drv_priv; |
471 | } | 473 | } |
472 | 474 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index c6585ab48df3..b3a87a31de30 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c | |||
@@ -513,6 +513,15 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) | |||
513 | int hdrlen = ieee80211_hdrlen(hdr->frame_control); | 513 | int hdrlen = ieee80211_hdrlen(hdr->frame_control); |
514 | int queue; | 514 | int queue; |
515 | 515 | ||
516 | /* IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets that can be used | ||
517 | * in 2 different types of vifs, P2P & STATION. P2P uses the offchannel | ||
518 | * queue. STATION (HS2.0) uses the auxiliary context of the FW, | ||
519 | * and hence needs to be sent on the aux queue | ||
520 | */ | ||
521 | if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE && | ||
522 | skb_info->control.vif->type == NL80211_IFTYPE_STATION) | ||
523 | IEEE80211_SKB_CB(skb)->hw_queue = mvm->aux_queue; | ||
524 | |||
516 | memcpy(&info, skb->cb, sizeof(info)); | 525 | memcpy(&info, skb->cb, sizeof(info)); |
517 | 526 | ||
518 | if (WARN_ON_ONCE(info.flags & IEEE80211_TX_CTL_AMPDU)) | 527 | if (WARN_ON_ONCE(info.flags & IEEE80211_TX_CTL_AMPDU)) |
@@ -526,16 +535,6 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) | |||
526 | /* This holds the amsdu headers length */ | 535 | /* This holds the amsdu headers length */ |
527 | skb_info->driver_data[0] = (void *)(uintptr_t)0; | 536 | skb_info->driver_data[0] = (void *)(uintptr_t)0; |
528 | 537 | ||
529 | /* | ||
530 | * IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets that can be used | ||
531 | * in 2 different types of vifs, P2P & STATION. P2P uses the offchannel | ||
532 | * queue. STATION (HS2.0) uses the auxiliary context of the FW, | ||
533 | * and hence needs to be sent on the aux queue | ||
534 | */ | ||
535 | if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE && | ||
536 | info.control.vif->type == NL80211_IFTYPE_STATION) | ||
537 | IEEE80211_SKB_CB(skb)->hw_queue = mvm->aux_queue; | ||
538 | |||
539 | queue = info.hw_queue; | 538 | queue = info.hw_queue; |
540 | 539 | ||
541 | /* | 540 | /* |
diff --git a/drivers/net/wireless/marvell/mwifiex/11n_aggr.c b/drivers/net/wireless/marvell/mwifiex/11n_aggr.c index dc49c3de1f25..c47d6366875d 100644 --- a/drivers/net/wireless/marvell/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/marvell/mwifiex/11n_aggr.c | |||
@@ -205,7 +205,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
205 | 205 | ||
206 | do { | 206 | do { |
207 | /* Check if AMSDU can accommodate this MSDU */ | 207 | /* Check if AMSDU can accommodate this MSDU */ |
208 | if (skb_tailroom(skb_aggr) < (skb_src->len + LLC_SNAP_LEN)) | 208 | if ((skb_aggr->len + skb_src->len + LLC_SNAP_LEN) > |
209 | adapter->tx_buf_size) | ||
209 | break; | 210 | break; |
210 | 211 | ||
211 | skb_src = skb_dequeue(&pra_list->skb_head); | 212 | skb_src = skb_dequeue(&pra_list->skb_head); |
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index 6a31f2610c23..daf4c7867102 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c | |||
@@ -271,6 +271,11 @@ static int netback_probe(struct xenbus_device *dev, | |||
271 | be->dev = dev; | 271 | be->dev = dev; |
272 | dev_set_drvdata(&dev->dev, be); | 272 | dev_set_drvdata(&dev->dev, be); |
273 | 273 | ||
274 | be->state = XenbusStateInitialising; | ||
275 | err = xenbus_switch_state(dev, XenbusStateInitialising); | ||
276 | if (err) | ||
277 | goto fail; | ||
278 | |||
274 | sg = 1; | 279 | sg = 1; |
275 | 280 | ||
276 | do { | 281 | do { |
@@ -383,11 +388,6 @@ static int netback_probe(struct xenbus_device *dev, | |||
383 | 388 | ||
384 | be->hotplug_script = script; | 389 | be->hotplug_script = script; |
385 | 390 | ||
386 | err = xenbus_switch_state(dev, XenbusStateInitWait); | ||
387 | if (err) | ||
388 | goto fail; | ||
389 | |||
390 | be->state = XenbusStateInitWait; | ||
391 | 391 | ||
392 | /* This kicks hotplug scripts, so do it immediately. */ | 392 | /* This kicks hotplug scripts, so do it immediately. */ |
393 | err = backend_create_xenvif(be); | 393 | err = backend_create_xenvif(be); |
@@ -492,20 +492,20 @@ static inline void backend_switch_state(struct backend_info *be, | |||
492 | 492 | ||
493 | /* Handle backend state transitions: | 493 | /* Handle backend state transitions: |
494 | * | 494 | * |
495 | * The backend state starts in InitWait and the following transitions are | 495 | * The backend state starts in Initialising and the following transitions are |
496 | * allowed. | 496 | * allowed. |
497 | * | 497 | * |
498 | * InitWait -> Connected | 498 | * Initialising -> InitWait -> Connected |
499 | * | 499 | * \ |
500 | * ^ \ | | 500 | * \ ^ \ | |
501 | * | \ | | 501 | * \ | \ | |
502 | * | \ | | 502 | * \ | \ | |
503 | * | \ | | 503 | * \ | \ | |
504 | * | \ | | 504 | * \ | \ | |
505 | * | \ | | 505 | * \ | \ | |
506 | * | V V | 506 | * V | V V |
507 | * | 507 | * |
508 | * Closed <-> Closing | 508 | * Closed <-> Closing |
509 | * | 509 | * |
510 | * The state argument specifies the eventual state of the backend and the | 510 | * The state argument specifies the eventual state of the backend and the |
511 | * function transitions to that state via the shortest path. | 511 | * function transitions to that state via the shortest path. |
@@ -515,6 +515,20 @@ static void set_backend_state(struct backend_info *be, | |||
515 | { | 515 | { |
516 | while (be->state != state) { | 516 | while (be->state != state) { |
517 | switch (be->state) { | 517 | switch (be->state) { |
518 | case XenbusStateInitialising: | ||
519 | switch (state) { | ||
520 | case XenbusStateInitWait: | ||
521 | case XenbusStateConnected: | ||
522 | case XenbusStateClosing: | ||
523 | backend_switch_state(be, XenbusStateInitWait); | ||
524 | break; | ||
525 | case XenbusStateClosed: | ||
526 | backend_switch_state(be, XenbusStateClosed); | ||
527 | break; | ||
528 | default: | ||
529 | BUG(); | ||
530 | } | ||
531 | break; | ||
518 | case XenbusStateClosed: | 532 | case XenbusStateClosed: |
519 | switch (state) { | 533 | switch (state) { |
520 | case XenbusStateInitWait: | 534 | case XenbusStateInitWait: |
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index 458daf927336..935866fe5ec2 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c | |||
@@ -185,8 +185,12 @@ long nvdimm_clear_poison(struct device *dev, phys_addr_t phys, | |||
185 | return -ENXIO; | 185 | return -ENXIO; |
186 | 186 | ||
187 | nd_desc = nvdimm_bus->nd_desc; | 187 | nd_desc = nvdimm_bus->nd_desc; |
188 | /* | ||
189 | * if ndctl does not exist, it's PMEM_LEGACY and | ||
190 | * we want to just pretend everything is handled. | ||
191 | */ | ||
188 | if (!nd_desc->ndctl) | 192 | if (!nd_desc->ndctl) |
189 | return -ENXIO; | 193 | return len; |
190 | 194 | ||
191 | memset(&ars_cap, 0, sizeof(ars_cap)); | 195 | memset(&ars_cap, 0, sizeof(ars_cap)); |
192 | ars_cap.address = phys; | 196 | ars_cap.address = phys; |
diff --git a/drivers/nvme/host/Kconfig b/drivers/nvme/host/Kconfig index db39d53cdfb9..f7d37a62f874 100644 --- a/drivers/nvme/host/Kconfig +++ b/drivers/nvme/host/Kconfig | |||
@@ -30,8 +30,8 @@ config NVME_FABRICS | |||
30 | 30 | ||
31 | config NVME_RDMA | 31 | config NVME_RDMA |
32 | tristate "NVM Express over Fabrics RDMA host driver" | 32 | tristate "NVM Express over Fabrics RDMA host driver" |
33 | depends on INFINIBAND | 33 | depends on INFINIBAND && BLOCK |
34 | depends on BLK_DEV_NVME | 34 | select NVME_CORE |
35 | select NVME_FABRICS | 35 | select NVME_FABRICS |
36 | select SG_POOL | 36 | select SG_POOL |
37 | help | 37 | help |
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 7ff2e820bbf4..2feacc70bf61 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c | |||
@@ -81,10 +81,12 @@ EXPORT_SYMBOL_GPL(nvme_cancel_request); | |||
81 | bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, | 81 | bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, |
82 | enum nvme_ctrl_state new_state) | 82 | enum nvme_ctrl_state new_state) |
83 | { | 83 | { |
84 | enum nvme_ctrl_state old_state = ctrl->state; | 84 | enum nvme_ctrl_state old_state; |
85 | bool changed = false; | 85 | bool changed = false; |
86 | 86 | ||
87 | spin_lock_irq(&ctrl->lock); | 87 | spin_lock_irq(&ctrl->lock); |
88 | |||
89 | old_state = ctrl->state; | ||
88 | switch (new_state) { | 90 | switch (new_state) { |
89 | case NVME_CTRL_LIVE: | 91 | case NVME_CTRL_LIVE: |
90 | switch (old_state) { | 92 | switch (old_state) { |
@@ -140,11 +142,12 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, | |||
140 | default: | 142 | default: |
141 | break; | 143 | break; |
142 | } | 144 | } |
143 | spin_unlock_irq(&ctrl->lock); | ||
144 | 145 | ||
145 | if (changed) | 146 | if (changed) |
146 | ctrl->state = new_state; | 147 | ctrl->state = new_state; |
147 | 148 | ||
149 | spin_unlock_irq(&ctrl->lock); | ||
150 | |||
148 | return changed; | 151 | return changed; |
149 | } | 152 | } |
150 | EXPORT_SYMBOL_GPL(nvme_change_ctrl_state); | 153 | EXPORT_SYMBOL_GPL(nvme_change_ctrl_state); |
@@ -608,7 +611,7 @@ int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned nsid, | |||
608 | 611 | ||
609 | ret = __nvme_submit_sync_cmd(dev->admin_q, &c, &cqe, NULL, 0, 0, | 612 | ret = __nvme_submit_sync_cmd(dev->admin_q, &c, &cqe, NULL, 0, 0, |
610 | NVME_QID_ANY, 0, 0); | 613 | NVME_QID_ANY, 0, 0); |
611 | if (ret >= 0) | 614 | if (ret >= 0 && result) |
612 | *result = le32_to_cpu(cqe.result); | 615 | *result = le32_to_cpu(cqe.result); |
613 | return ret; | 616 | return ret; |
614 | } | 617 | } |
@@ -628,7 +631,7 @@ int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11, | |||
628 | 631 | ||
629 | ret = __nvme_submit_sync_cmd(dev->admin_q, &c, &cqe, NULL, 0, 0, | 632 | ret = __nvme_submit_sync_cmd(dev->admin_q, &c, &cqe, NULL, 0, 0, |
630 | NVME_QID_ANY, 0, 0); | 633 | NVME_QID_ANY, 0, 0); |
631 | if (ret >= 0) | 634 | if (ret >= 0 && result) |
632 | *result = le32_to_cpu(cqe.result); | 635 | *result = le32_to_cpu(cqe.result); |
633 | return ret; | 636 | return ret; |
634 | } | 637 | } |
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c index dc996761042f..4eff49174466 100644 --- a/drivers/nvme/host/fabrics.c +++ b/drivers/nvme/host/fabrics.c | |||
@@ -47,8 +47,10 @@ static struct nvmf_host *nvmf_host_add(const char *hostnqn) | |||
47 | 47 | ||
48 | mutex_lock(&nvmf_hosts_mutex); | 48 | mutex_lock(&nvmf_hosts_mutex); |
49 | host = __nvmf_host_find(hostnqn); | 49 | host = __nvmf_host_find(hostnqn); |
50 | if (host) | 50 | if (host) { |
51 | kref_get(&host->ref); | ||
51 | goto out_unlock; | 52 | goto out_unlock; |
53 | } | ||
52 | 54 | ||
53 | host = kmalloc(sizeof(*host), GFP_KERNEL); | 55 | host = kmalloc(sizeof(*host), GFP_KERNEL); |
54 | if (!host) | 56 | if (!host) |
@@ -56,7 +58,7 @@ static struct nvmf_host *nvmf_host_add(const char *hostnqn) | |||
56 | 58 | ||
57 | kref_init(&host->ref); | 59 | kref_init(&host->ref); |
58 | memcpy(host->nqn, hostnqn, NVMF_NQN_SIZE); | 60 | memcpy(host->nqn, hostnqn, NVMF_NQN_SIZE); |
59 | uuid_le_gen(&host->id); | 61 | uuid_be_gen(&host->id); |
60 | 62 | ||
61 | list_add_tail(&host->list, &nvmf_hosts); | 63 | list_add_tail(&host->list, &nvmf_hosts); |
62 | out_unlock: | 64 | out_unlock: |
@@ -73,9 +75,9 @@ static struct nvmf_host *nvmf_host_default(void) | |||
73 | return NULL; | 75 | return NULL; |
74 | 76 | ||
75 | kref_init(&host->ref); | 77 | kref_init(&host->ref); |
76 | uuid_le_gen(&host->id); | 78 | uuid_be_gen(&host->id); |
77 | snprintf(host->nqn, NVMF_NQN_SIZE, | 79 | snprintf(host->nqn, NVMF_NQN_SIZE, |
78 | "nqn.2014-08.org.nvmexpress:NVMf:uuid:%pUl", &host->id); | 80 | "nqn.2014-08.org.nvmexpress:NVMf:uuid:%pUb", &host->id); |
79 | 81 | ||
80 | mutex_lock(&nvmf_hosts_mutex); | 82 | mutex_lock(&nvmf_hosts_mutex); |
81 | list_add_tail(&host->list, &nvmf_hosts); | 83 | list_add_tail(&host->list, &nvmf_hosts); |
@@ -363,7 +365,14 @@ int nvmf_connect_admin_queue(struct nvme_ctrl *ctrl) | |||
363 | cmd.connect.opcode = nvme_fabrics_command; | 365 | cmd.connect.opcode = nvme_fabrics_command; |
364 | cmd.connect.fctype = nvme_fabrics_type_connect; | 366 | cmd.connect.fctype = nvme_fabrics_type_connect; |
365 | cmd.connect.qid = 0; | 367 | cmd.connect.qid = 0; |
366 | cmd.connect.sqsize = cpu_to_le16(ctrl->sqsize); | 368 | |
369 | /* | ||
370 | * fabrics spec sets a minimum of depth 32 for admin queue, | ||
371 | * so set the queue with this depth always until | ||
372 | * justification otherwise. | ||
373 | */ | ||
374 | cmd.connect.sqsize = cpu_to_le16(NVMF_AQ_DEPTH - 1); | ||
375 | |||
367 | /* | 376 | /* |
368 | * Set keep-alive timeout in seconds granularity (ms * 1000) | 377 | * Set keep-alive timeout in seconds granularity (ms * 1000) |
369 | * and add a grace period for controller kato enforcement | 378 | * and add a grace period for controller kato enforcement |
@@ -375,7 +384,7 @@ int nvmf_connect_admin_queue(struct nvme_ctrl *ctrl) | |||
375 | if (!data) | 384 | if (!data) |
376 | return -ENOMEM; | 385 | return -ENOMEM; |
377 | 386 | ||
378 | memcpy(&data->hostid, &ctrl->opts->host->id, sizeof(uuid_le)); | 387 | memcpy(&data->hostid, &ctrl->opts->host->id, sizeof(uuid_be)); |
379 | data->cntlid = cpu_to_le16(0xffff); | 388 | data->cntlid = cpu_to_le16(0xffff); |
380 | strncpy(data->subsysnqn, ctrl->opts->subsysnqn, NVMF_NQN_SIZE); | 389 | strncpy(data->subsysnqn, ctrl->opts->subsysnqn, NVMF_NQN_SIZE); |
381 | strncpy(data->hostnqn, ctrl->opts->host->nqn, NVMF_NQN_SIZE); | 390 | strncpy(data->hostnqn, ctrl->opts->host->nqn, NVMF_NQN_SIZE); |
@@ -434,7 +443,7 @@ int nvmf_connect_io_queue(struct nvme_ctrl *ctrl, u16 qid) | |||
434 | if (!data) | 443 | if (!data) |
435 | return -ENOMEM; | 444 | return -ENOMEM; |
436 | 445 | ||
437 | memcpy(&data->hostid, &ctrl->opts->host->id, sizeof(uuid_le)); | 446 | memcpy(&data->hostid, &ctrl->opts->host->id, sizeof(uuid_be)); |
438 | data->cntlid = cpu_to_le16(ctrl->cntlid); | 447 | data->cntlid = cpu_to_le16(ctrl->cntlid); |
439 | strncpy(data->subsysnqn, ctrl->opts->subsysnqn, NVMF_NQN_SIZE); | 448 | strncpy(data->subsysnqn, ctrl->opts->subsysnqn, NVMF_NQN_SIZE); |
440 | strncpy(data->hostnqn, ctrl->opts->host->nqn, NVMF_NQN_SIZE); | 449 | strncpy(data->hostnqn, ctrl->opts->host->nqn, NVMF_NQN_SIZE); |
diff --git a/drivers/nvme/host/fabrics.h b/drivers/nvme/host/fabrics.h index 89df52c8be97..46e460aee52d 100644 --- a/drivers/nvme/host/fabrics.h +++ b/drivers/nvme/host/fabrics.h | |||
@@ -34,7 +34,7 @@ struct nvmf_host { | |||
34 | struct kref ref; | 34 | struct kref ref; |
35 | struct list_head list; | 35 | struct list_head list; |
36 | char nqn[NVMF_NQN_SIZE]; | 36 | char nqn[NVMF_NQN_SIZE]; |
37 | uuid_le id; | 37 | uuid_be id; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | /** | 40 | /** |
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 8dcf5a960951..60f7eab11865 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c | |||
@@ -1693,7 +1693,12 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) | |||
1693 | nvme_suspend_queue(dev->queues[i]); | 1693 | nvme_suspend_queue(dev->queues[i]); |
1694 | 1694 | ||
1695 | if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) { | 1695 | if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) { |
1696 | nvme_suspend_queue(dev->queues[0]); | 1696 | /* A device might become IO incapable very soon during |
1697 | * probe, before the admin queue is configured. Thus, | ||
1698 | * queue_count can be 0 here. | ||
1699 | */ | ||
1700 | if (dev->queue_count) | ||
1701 | nvme_suspend_queue(dev->queues[0]); | ||
1697 | } else { | 1702 | } else { |
1698 | nvme_disable_io_queues(dev); | 1703 | nvme_disable_io_queues(dev); |
1699 | nvme_disable_admin_queue(dev, shutdown); | 1704 | nvme_disable_admin_queue(dev, shutdown); |
@@ -2112,6 +2117,8 @@ static const struct pci_device_id nvme_id_table[] = { | |||
2112 | .driver_data = NVME_QUIRK_IDENTIFY_CNS, }, | 2117 | .driver_data = NVME_QUIRK_IDENTIFY_CNS, }, |
2113 | { PCI_DEVICE(0x1c58, 0x0003), /* HGST adapter */ | 2118 | { PCI_DEVICE(0x1c58, 0x0003), /* HGST adapter */ |
2114 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, | 2119 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, |
2120 | { PCI_DEVICE(0x1c5f, 0x0540), /* Memblaze Pblaze4 adapter */ | ||
2121 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, | ||
2115 | { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) }, | 2122 | { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) }, |
2116 | { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) }, | 2123 | { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) }, |
2117 | { 0, } | 2124 | { 0, } |
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 8d2875b4c56d..fbdb2267e460 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c | |||
@@ -43,10 +43,6 @@ | |||
43 | 43 | ||
44 | #define NVME_RDMA_MAX_INLINE_SEGMENTS 1 | 44 | #define NVME_RDMA_MAX_INLINE_SEGMENTS 1 |
45 | 45 | ||
46 | #define NVME_RDMA_MAX_PAGES_PER_MR 512 | ||
47 | |||
48 | #define NVME_RDMA_DEF_RECONNECT_DELAY 20 | ||
49 | |||
50 | /* | 46 | /* |
51 | * We handle AEN commands ourselves and don't even let the | 47 | * We handle AEN commands ourselves and don't even let the |
52 | * block layer know about them. | 48 | * block layer know about them. |
@@ -77,7 +73,6 @@ struct nvme_rdma_request { | |||
77 | u32 num_sge; | 73 | u32 num_sge; |
78 | int nents; | 74 | int nents; |
79 | bool inline_data; | 75 | bool inline_data; |
80 | bool need_inval; | ||
81 | struct ib_reg_wr reg_wr; | 76 | struct ib_reg_wr reg_wr; |
82 | struct ib_cqe reg_cqe; | 77 | struct ib_cqe reg_cqe; |
83 | struct nvme_rdma_queue *queue; | 78 | struct nvme_rdma_queue *queue; |
@@ -87,6 +82,8 @@ struct nvme_rdma_request { | |||
87 | 82 | ||
88 | enum nvme_rdma_queue_flags { | 83 | enum nvme_rdma_queue_flags { |
89 | NVME_RDMA_Q_CONNECTED = (1 << 0), | 84 | NVME_RDMA_Q_CONNECTED = (1 << 0), |
85 | NVME_RDMA_IB_QUEUE_ALLOCATED = (1 << 1), | ||
86 | NVME_RDMA_Q_DELETING = (1 << 2), | ||
90 | }; | 87 | }; |
91 | 88 | ||
92 | struct nvme_rdma_queue { | 89 | struct nvme_rdma_queue { |
@@ -286,7 +283,7 @@ static int nvme_rdma_reinit_request(void *data, struct request *rq) | |||
286 | struct nvme_rdma_request *req = blk_mq_rq_to_pdu(rq); | 283 | struct nvme_rdma_request *req = blk_mq_rq_to_pdu(rq); |
287 | int ret = 0; | 284 | int ret = 0; |
288 | 285 | ||
289 | if (!req->need_inval) | 286 | if (!req->mr->need_inval) |
290 | goto out; | 287 | goto out; |
291 | 288 | ||
292 | ib_dereg_mr(req->mr); | 289 | ib_dereg_mr(req->mr); |
@@ -296,9 +293,10 @@ static int nvme_rdma_reinit_request(void *data, struct request *rq) | |||
296 | if (IS_ERR(req->mr)) { | 293 | if (IS_ERR(req->mr)) { |
297 | ret = PTR_ERR(req->mr); | 294 | ret = PTR_ERR(req->mr); |
298 | req->mr = NULL; | 295 | req->mr = NULL; |
296 | goto out; | ||
299 | } | 297 | } |
300 | 298 | ||
301 | req->need_inval = false; | 299 | req->mr->need_inval = false; |
302 | 300 | ||
303 | out: | 301 | out: |
304 | return ret; | 302 | return ret; |
@@ -485,9 +483,14 @@ out_err: | |||
485 | 483 | ||
486 | static void nvme_rdma_destroy_queue_ib(struct nvme_rdma_queue *queue) | 484 | static void nvme_rdma_destroy_queue_ib(struct nvme_rdma_queue *queue) |
487 | { | 485 | { |
488 | struct nvme_rdma_device *dev = queue->device; | 486 | struct nvme_rdma_device *dev; |
489 | struct ib_device *ibdev = dev->dev; | 487 | struct ib_device *ibdev; |
488 | |||
489 | if (!test_and_clear_bit(NVME_RDMA_IB_QUEUE_ALLOCATED, &queue->flags)) | ||
490 | return; | ||
490 | 491 | ||
492 | dev = queue->device; | ||
493 | ibdev = dev->dev; | ||
491 | rdma_destroy_qp(queue->cm_id); | 494 | rdma_destroy_qp(queue->cm_id); |
492 | ib_free_cq(queue->ib_cq); | 495 | ib_free_cq(queue->ib_cq); |
493 | 496 | ||
@@ -538,6 +541,7 @@ static int nvme_rdma_create_queue_ib(struct nvme_rdma_queue *queue, | |||
538 | ret = -ENOMEM; | 541 | ret = -ENOMEM; |
539 | goto out_destroy_qp; | 542 | goto out_destroy_qp; |
540 | } | 543 | } |
544 | set_bit(NVME_RDMA_IB_QUEUE_ALLOCATED, &queue->flags); | ||
541 | 545 | ||
542 | return 0; | 546 | return 0; |
543 | 547 | ||
@@ -590,11 +594,13 @@ static int nvme_rdma_init_queue(struct nvme_rdma_ctrl *ctrl, | |||
590 | goto out_destroy_cm_id; | 594 | goto out_destroy_cm_id; |
591 | } | 595 | } |
592 | 596 | ||
597 | clear_bit(NVME_RDMA_Q_DELETING, &queue->flags); | ||
593 | set_bit(NVME_RDMA_Q_CONNECTED, &queue->flags); | 598 | set_bit(NVME_RDMA_Q_CONNECTED, &queue->flags); |
594 | 599 | ||
595 | return 0; | 600 | return 0; |
596 | 601 | ||
597 | out_destroy_cm_id: | 602 | out_destroy_cm_id: |
603 | nvme_rdma_destroy_queue_ib(queue); | ||
598 | rdma_destroy_id(queue->cm_id); | 604 | rdma_destroy_id(queue->cm_id); |
599 | return ret; | 605 | return ret; |
600 | } | 606 | } |
@@ -613,7 +619,7 @@ static void nvme_rdma_free_queue(struct nvme_rdma_queue *queue) | |||
613 | 619 | ||
614 | static void nvme_rdma_stop_and_free_queue(struct nvme_rdma_queue *queue) | 620 | static void nvme_rdma_stop_and_free_queue(struct nvme_rdma_queue *queue) |
615 | { | 621 | { |
616 | if (!test_and_clear_bit(NVME_RDMA_Q_CONNECTED, &queue->flags)) | 622 | if (test_and_set_bit(NVME_RDMA_Q_DELETING, &queue->flags)) |
617 | return; | 623 | return; |
618 | nvme_rdma_stop_queue(queue); | 624 | nvme_rdma_stop_queue(queue); |
619 | nvme_rdma_free_queue(queue); | 625 | nvme_rdma_free_queue(queue); |
@@ -645,7 +651,8 @@ static int nvme_rdma_init_io_queues(struct nvme_rdma_ctrl *ctrl) | |||
645 | int i, ret; | 651 | int i, ret; |
646 | 652 | ||
647 | for (i = 1; i < ctrl->queue_count; i++) { | 653 | for (i = 1; i < ctrl->queue_count; i++) { |
648 | ret = nvme_rdma_init_queue(ctrl, i, ctrl->ctrl.sqsize); | 654 | ret = nvme_rdma_init_queue(ctrl, i, |
655 | ctrl->ctrl.opts->queue_size); | ||
649 | if (ret) { | 656 | if (ret) { |
650 | dev_info(ctrl->ctrl.device, | 657 | dev_info(ctrl->ctrl.device, |
651 | "failed to initialize i/o queue: %d\n", ret); | 658 | "failed to initialize i/o queue: %d\n", ret); |
@@ -656,7 +663,7 @@ static int nvme_rdma_init_io_queues(struct nvme_rdma_ctrl *ctrl) | |||
656 | return 0; | 663 | return 0; |
657 | 664 | ||
658 | out_free_queues: | 665 | out_free_queues: |
659 | for (; i >= 1; i--) | 666 | for (i--; i >= 1; i--) |
660 | nvme_rdma_stop_and_free_queue(&ctrl->queues[i]); | 667 | nvme_rdma_stop_and_free_queue(&ctrl->queues[i]); |
661 | 668 | ||
662 | return ret; | 669 | return ret; |
@@ -765,8 +772,13 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work) | |||
765 | { | 772 | { |
766 | struct nvme_rdma_ctrl *ctrl = container_of(work, | 773 | struct nvme_rdma_ctrl *ctrl = container_of(work, |
767 | struct nvme_rdma_ctrl, err_work); | 774 | struct nvme_rdma_ctrl, err_work); |
775 | int i; | ||
768 | 776 | ||
769 | nvme_stop_keep_alive(&ctrl->ctrl); | 777 | nvme_stop_keep_alive(&ctrl->ctrl); |
778 | |||
779 | for (i = 0; i < ctrl->queue_count; i++) | ||
780 | clear_bit(NVME_RDMA_Q_CONNECTED, &ctrl->queues[i].flags); | ||
781 | |||
770 | if (ctrl->queue_count > 1) | 782 | if (ctrl->queue_count > 1) |
771 | nvme_stop_queues(&ctrl->ctrl); | 783 | nvme_stop_queues(&ctrl->ctrl); |
772 | blk_mq_stop_hw_queues(ctrl->ctrl.admin_q); | 784 | blk_mq_stop_hw_queues(ctrl->ctrl.admin_q); |
@@ -849,7 +861,7 @@ static void nvme_rdma_unmap_data(struct nvme_rdma_queue *queue, | |||
849 | if (!blk_rq_bytes(rq)) | 861 | if (!blk_rq_bytes(rq)) |
850 | return; | 862 | return; |
851 | 863 | ||
852 | if (req->need_inval) { | 864 | if (req->mr->need_inval) { |
853 | res = nvme_rdma_inv_rkey(queue, req); | 865 | res = nvme_rdma_inv_rkey(queue, req); |
854 | if (res < 0) { | 866 | if (res < 0) { |
855 | dev_err(ctrl->ctrl.device, | 867 | dev_err(ctrl->ctrl.device, |
@@ -935,7 +947,7 @@ static int nvme_rdma_map_sg_fr(struct nvme_rdma_queue *queue, | |||
935 | IB_ACCESS_REMOTE_READ | | 947 | IB_ACCESS_REMOTE_READ | |
936 | IB_ACCESS_REMOTE_WRITE; | 948 | IB_ACCESS_REMOTE_WRITE; |
937 | 949 | ||
938 | req->need_inval = true; | 950 | req->mr->need_inval = true; |
939 | 951 | ||
940 | sg->addr = cpu_to_le64(req->mr->iova); | 952 | sg->addr = cpu_to_le64(req->mr->iova); |
941 | put_unaligned_le24(req->mr->length, sg->length); | 953 | put_unaligned_le24(req->mr->length, sg->length); |
@@ -958,7 +970,7 @@ static int nvme_rdma_map_data(struct nvme_rdma_queue *queue, | |||
958 | 970 | ||
959 | req->num_sge = 1; | 971 | req->num_sge = 1; |
960 | req->inline_data = false; | 972 | req->inline_data = false; |
961 | req->need_inval = false; | 973 | req->mr->need_inval = false; |
962 | 974 | ||
963 | c->common.flags |= NVME_CMD_SGL_METABUF; | 975 | c->common.flags |= NVME_CMD_SGL_METABUF; |
964 | 976 | ||
@@ -1145,7 +1157,7 @@ static int nvme_rdma_process_nvme_rsp(struct nvme_rdma_queue *queue, | |||
1145 | 1157 | ||
1146 | if ((wc->wc_flags & IB_WC_WITH_INVALIDATE) && | 1158 | if ((wc->wc_flags & IB_WC_WITH_INVALIDATE) && |
1147 | wc->ex.invalidate_rkey == req->mr->rkey) | 1159 | wc->ex.invalidate_rkey == req->mr->rkey) |
1148 | req->need_inval = false; | 1160 | req->mr->need_inval = false; |
1149 | 1161 | ||
1150 | blk_mq_complete_request(rq, status); | 1162 | blk_mq_complete_request(rq, status); |
1151 | 1163 | ||
@@ -1278,8 +1290,22 @@ static int nvme_rdma_route_resolved(struct nvme_rdma_queue *queue) | |||
1278 | 1290 | ||
1279 | priv.recfmt = cpu_to_le16(NVME_RDMA_CM_FMT_1_0); | 1291 | priv.recfmt = cpu_to_le16(NVME_RDMA_CM_FMT_1_0); |
1280 | priv.qid = cpu_to_le16(nvme_rdma_queue_idx(queue)); | 1292 | priv.qid = cpu_to_le16(nvme_rdma_queue_idx(queue)); |
1281 | priv.hrqsize = cpu_to_le16(queue->queue_size); | 1293 | /* |
1282 | priv.hsqsize = cpu_to_le16(queue->queue_size); | 1294 | * set the admin queue depth to the minimum size |
1295 | * specified by the Fabrics standard. | ||
1296 | */ | ||
1297 | if (priv.qid == 0) { | ||
1298 | priv.hrqsize = cpu_to_le16(NVMF_AQ_DEPTH); | ||
1299 | priv.hsqsize = cpu_to_le16(NVMF_AQ_DEPTH - 1); | ||
1300 | } else { | ||
1301 | /* | ||
1302 | * current interpretation of the fabrics spec | ||
1303 | * is at minimum you make hrqsize sqsize+1, or a | ||
1304 | * 1's based representation of sqsize. | ||
1305 | */ | ||
1306 | priv.hrqsize = cpu_to_le16(queue->queue_size); | ||
1307 | priv.hsqsize = cpu_to_le16(queue->ctrl->ctrl.sqsize); | ||
1308 | } | ||
1283 | 1309 | ||
1284 | ret = rdma_connect(queue->cm_id, ¶m); | 1310 | ret = rdma_connect(queue->cm_id, ¶m); |
1285 | if (ret) { | 1311 | if (ret) { |
@@ -1295,58 +1321,6 @@ out_destroy_queue_ib: | |||
1295 | return ret; | 1321 | return ret; |
1296 | } | 1322 | } |
1297 | 1323 | ||
1298 | /** | ||
1299 | * nvme_rdma_device_unplug() - Handle RDMA device unplug | ||
1300 | * @queue: Queue that owns the cm_id that caught the event | ||
1301 | * | ||
1302 | * DEVICE_REMOVAL event notifies us that the RDMA device is about | ||
1303 | * to unplug so we should take care of destroying our RDMA resources. | ||
1304 | * This event will be generated for each allocated cm_id. | ||
1305 | * | ||
1306 | * In our case, the RDMA resources are managed per controller and not | ||
1307 | * only per queue. So the way we handle this is we trigger an implicit | ||
1308 | * controller deletion upon the first DEVICE_REMOVAL event we see, and | ||
1309 | * hold the event inflight until the controller deletion is completed. | ||
1310 | * | ||
1311 | * One exception that we need to handle is the destruction of the cm_id | ||
1312 | * that caught the event. Since we hold the callout until the controller | ||
1313 | * deletion is completed, we'll deadlock if the controller deletion will | ||
1314 | * call rdma_destroy_id on this queue's cm_id. Thus, we claim ownership | ||
1315 | * of destroying this queue before-hand, destroy the queue resources, | ||
1316 | * then queue the controller deletion which won't destroy this queue and | ||
1317 | * we destroy the cm_id implicitely by returning a non-zero rc to the callout. | ||
1318 | */ | ||
1319 | static int nvme_rdma_device_unplug(struct nvme_rdma_queue *queue) | ||
1320 | { | ||
1321 | struct nvme_rdma_ctrl *ctrl = queue->ctrl; | ||
1322 | int ret; | ||
1323 | |||
1324 | /* Own the controller deletion */ | ||
1325 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_DELETING)) | ||
1326 | return 0; | ||
1327 | |||
1328 | dev_warn(ctrl->ctrl.device, | ||
1329 | "Got rdma device removal event, deleting ctrl\n"); | ||
1330 | |||
1331 | /* Get rid of reconnect work if its running */ | ||
1332 | cancel_delayed_work_sync(&ctrl->reconnect_work); | ||
1333 | |||
1334 | /* Disable the queue so ctrl delete won't free it */ | ||
1335 | if (test_and_clear_bit(NVME_RDMA_Q_CONNECTED, &queue->flags)) { | ||
1336 | /* Free this queue ourselves */ | ||
1337 | nvme_rdma_stop_queue(queue); | ||
1338 | nvme_rdma_destroy_queue_ib(queue); | ||
1339 | |||
1340 | /* Return non-zero so the cm_id will destroy implicitly */ | ||
1341 | ret = 1; | ||
1342 | } | ||
1343 | |||
1344 | /* Queue controller deletion */ | ||
1345 | queue_work(nvme_rdma_wq, &ctrl->delete_work); | ||
1346 | flush_work(&ctrl->delete_work); | ||
1347 | return ret; | ||
1348 | } | ||
1349 | |||
1350 | static int nvme_rdma_cm_handler(struct rdma_cm_id *cm_id, | 1324 | static int nvme_rdma_cm_handler(struct rdma_cm_id *cm_id, |
1351 | struct rdma_cm_event *ev) | 1325 | struct rdma_cm_event *ev) |
1352 | { | 1326 | { |
@@ -1388,8 +1362,8 @@ static int nvme_rdma_cm_handler(struct rdma_cm_id *cm_id, | |||
1388 | nvme_rdma_error_recovery(queue->ctrl); | 1362 | nvme_rdma_error_recovery(queue->ctrl); |
1389 | break; | 1363 | break; |
1390 | case RDMA_CM_EVENT_DEVICE_REMOVAL: | 1364 | case RDMA_CM_EVENT_DEVICE_REMOVAL: |
1391 | /* return 1 means impliciy CM ID destroy */ | 1365 | /* device removal is handled via the ib_client API */ |
1392 | return nvme_rdma_device_unplug(queue); | 1366 | break; |
1393 | default: | 1367 | default: |
1394 | dev_err(queue->ctrl->ctrl.device, | 1368 | dev_err(queue->ctrl->ctrl.device, |
1395 | "Unexpected RDMA CM event (%d)\n", ev->event); | 1369 | "Unexpected RDMA CM event (%d)\n", ev->event); |
@@ -1461,7 +1435,7 @@ static int nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx, | |||
1461 | if (rq->cmd_type == REQ_TYPE_FS && req_op(rq) == REQ_OP_FLUSH) | 1435 | if (rq->cmd_type == REQ_TYPE_FS && req_op(rq) == REQ_OP_FLUSH) |
1462 | flush = true; | 1436 | flush = true; |
1463 | ret = nvme_rdma_post_send(queue, sqe, req->sge, req->num_sge, | 1437 | ret = nvme_rdma_post_send(queue, sqe, req->sge, req->num_sge, |
1464 | req->need_inval ? &req->reg_wr.wr : NULL, flush); | 1438 | req->mr->need_inval ? &req->reg_wr.wr : NULL, flush); |
1465 | if (ret) { | 1439 | if (ret) { |
1466 | nvme_rdma_unmap_data(queue, rq); | 1440 | nvme_rdma_unmap_data(queue, rq); |
1467 | goto err; | 1441 | goto err; |
@@ -1690,15 +1664,19 @@ static int __nvme_rdma_del_ctrl(struct nvme_rdma_ctrl *ctrl) | |||
1690 | static int nvme_rdma_del_ctrl(struct nvme_ctrl *nctrl) | 1664 | static int nvme_rdma_del_ctrl(struct nvme_ctrl *nctrl) |
1691 | { | 1665 | { |
1692 | struct nvme_rdma_ctrl *ctrl = to_rdma_ctrl(nctrl); | 1666 | struct nvme_rdma_ctrl *ctrl = to_rdma_ctrl(nctrl); |
1693 | int ret; | 1667 | int ret = 0; |
1694 | 1668 | ||
1669 | /* | ||
1670 | * Keep a reference until all work is flushed since | ||
1671 | * __nvme_rdma_del_ctrl can free the ctrl mem | ||
1672 | */ | ||
1673 | if (!kref_get_unless_zero(&ctrl->ctrl.kref)) | ||
1674 | return -EBUSY; | ||
1695 | ret = __nvme_rdma_del_ctrl(ctrl); | 1675 | ret = __nvme_rdma_del_ctrl(ctrl); |
1696 | if (ret) | 1676 | if (!ret) |
1697 | return ret; | 1677 | flush_work(&ctrl->delete_work); |
1698 | 1678 | nvme_put_ctrl(&ctrl->ctrl); | |
1699 | flush_work(&ctrl->delete_work); | 1679 | return ret; |
1700 | |||
1701 | return 0; | ||
1702 | } | 1680 | } |
1703 | 1681 | ||
1704 | static void nvme_rdma_remove_ctrl_work(struct work_struct *work) | 1682 | static void nvme_rdma_remove_ctrl_work(struct work_struct *work) |
@@ -1816,7 +1794,7 @@ static int nvme_rdma_create_io_queues(struct nvme_rdma_ctrl *ctrl) | |||
1816 | 1794 | ||
1817 | memset(&ctrl->tag_set, 0, sizeof(ctrl->tag_set)); | 1795 | memset(&ctrl->tag_set, 0, sizeof(ctrl->tag_set)); |
1818 | ctrl->tag_set.ops = &nvme_rdma_mq_ops; | 1796 | ctrl->tag_set.ops = &nvme_rdma_mq_ops; |
1819 | ctrl->tag_set.queue_depth = ctrl->ctrl.sqsize; | 1797 | ctrl->tag_set.queue_depth = ctrl->ctrl.opts->queue_size; |
1820 | ctrl->tag_set.reserved_tags = 1; /* fabric connect */ | 1798 | ctrl->tag_set.reserved_tags = 1; /* fabric connect */ |
1821 | ctrl->tag_set.numa_node = NUMA_NO_NODE; | 1799 | ctrl->tag_set.numa_node = NUMA_NO_NODE; |
1822 | ctrl->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; | 1800 | ctrl->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; |
@@ -1914,7 +1892,7 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev, | |||
1914 | spin_lock_init(&ctrl->lock); | 1892 | spin_lock_init(&ctrl->lock); |
1915 | 1893 | ||
1916 | ctrl->queue_count = opts->nr_io_queues + 1; /* +1 for admin queue */ | 1894 | ctrl->queue_count = opts->nr_io_queues + 1; /* +1 for admin queue */ |
1917 | ctrl->ctrl.sqsize = opts->queue_size; | 1895 | ctrl->ctrl.sqsize = opts->queue_size - 1; |
1918 | ctrl->ctrl.kato = opts->kato; | 1896 | ctrl->ctrl.kato = opts->kato; |
1919 | 1897 | ||
1920 | ret = -ENOMEM; | 1898 | ret = -ENOMEM; |
@@ -1995,27 +1973,57 @@ static struct nvmf_transport_ops nvme_rdma_transport = { | |||
1995 | .create_ctrl = nvme_rdma_create_ctrl, | 1973 | .create_ctrl = nvme_rdma_create_ctrl, |
1996 | }; | 1974 | }; |
1997 | 1975 | ||
1976 | static void nvme_rdma_add_one(struct ib_device *ib_device) | ||
1977 | { | ||
1978 | } | ||
1979 | |||
1980 | static void nvme_rdma_remove_one(struct ib_device *ib_device, void *client_data) | ||
1981 | { | ||
1982 | struct nvme_rdma_ctrl *ctrl; | ||
1983 | |||
1984 | /* Delete all controllers using this device */ | ||
1985 | mutex_lock(&nvme_rdma_ctrl_mutex); | ||
1986 | list_for_each_entry(ctrl, &nvme_rdma_ctrl_list, list) { | ||
1987 | if (ctrl->device->dev != ib_device) | ||
1988 | continue; | ||
1989 | dev_info(ctrl->ctrl.device, | ||
1990 | "Removing ctrl: NQN \"%s\", addr %pISp\n", | ||
1991 | ctrl->ctrl.opts->subsysnqn, &ctrl->addr); | ||
1992 | __nvme_rdma_del_ctrl(ctrl); | ||
1993 | } | ||
1994 | mutex_unlock(&nvme_rdma_ctrl_mutex); | ||
1995 | |||
1996 | flush_workqueue(nvme_rdma_wq); | ||
1997 | } | ||
1998 | |||
1999 | static struct ib_client nvme_rdma_ib_client = { | ||
2000 | .name = "nvme_rdma", | ||
2001 | .add = nvme_rdma_add_one, | ||
2002 | .remove = nvme_rdma_remove_one | ||
2003 | }; | ||
2004 | |||
1998 | static int __init nvme_rdma_init_module(void) | 2005 | static int __init nvme_rdma_init_module(void) |
1999 | { | 2006 | { |
2007 | int ret; | ||
2008 | |||
2000 | nvme_rdma_wq = create_workqueue("nvme_rdma_wq"); | 2009 | nvme_rdma_wq = create_workqueue("nvme_rdma_wq"); |
2001 | if (!nvme_rdma_wq) | 2010 | if (!nvme_rdma_wq) |
2002 | return -ENOMEM; | 2011 | return -ENOMEM; |
2003 | 2012 | ||
2013 | ret = ib_register_client(&nvme_rdma_ib_client); | ||
2014 | if (ret) { | ||
2015 | destroy_workqueue(nvme_rdma_wq); | ||
2016 | return ret; | ||
2017 | } | ||
2018 | |||
2004 | nvmf_register_transport(&nvme_rdma_transport); | 2019 | nvmf_register_transport(&nvme_rdma_transport); |
2005 | return 0; | 2020 | return 0; |
2006 | } | 2021 | } |
2007 | 2022 | ||
2008 | static void __exit nvme_rdma_cleanup_module(void) | 2023 | static void __exit nvme_rdma_cleanup_module(void) |
2009 | { | 2024 | { |
2010 | struct nvme_rdma_ctrl *ctrl; | ||
2011 | |||
2012 | nvmf_unregister_transport(&nvme_rdma_transport); | 2025 | nvmf_unregister_transport(&nvme_rdma_transport); |
2013 | 2026 | ib_unregister_client(&nvme_rdma_ib_client); | |
2014 | mutex_lock(&nvme_rdma_ctrl_mutex); | ||
2015 | list_for_each_entry(ctrl, &nvme_rdma_ctrl_list, list) | ||
2016 | __nvme_rdma_del_ctrl(ctrl); | ||
2017 | mutex_unlock(&nvme_rdma_ctrl_mutex); | ||
2018 | |||
2019 | destroy_workqueue(nvme_rdma_wq); | 2027 | destroy_workqueue(nvme_rdma_wq); |
2020 | } | 2028 | } |
2021 | 2029 | ||
diff --git a/drivers/nvme/target/Kconfig b/drivers/nvme/target/Kconfig index a5c31cbeb481..3a5b9d0576cb 100644 --- a/drivers/nvme/target/Kconfig +++ b/drivers/nvme/target/Kconfig | |||
@@ -15,8 +15,8 @@ config NVME_TARGET | |||
15 | 15 | ||
16 | config NVME_TARGET_LOOP | 16 | config NVME_TARGET_LOOP |
17 | tristate "NVMe loopback device support" | 17 | tristate "NVMe loopback device support" |
18 | depends on BLK_DEV_NVME | ||
19 | depends on NVME_TARGET | 18 | depends on NVME_TARGET |
19 | select NVME_CORE | ||
20 | select NVME_FABRICS | 20 | select NVME_FABRICS |
21 | select SG_POOL | 21 | select SG_POOL |
22 | help | 22 | help |
diff --git a/drivers/nvme/target/loop.c b/drivers/nvme/target/loop.c index 7affd40a6b33..395e60dad835 100644 --- a/drivers/nvme/target/loop.c +++ b/drivers/nvme/target/loop.c | |||
@@ -556,7 +556,7 @@ static int nvme_loop_create_io_queues(struct nvme_loop_ctrl *ctrl) | |||
556 | 556 | ||
557 | memset(&ctrl->tag_set, 0, sizeof(ctrl->tag_set)); | 557 | memset(&ctrl->tag_set, 0, sizeof(ctrl->tag_set)); |
558 | ctrl->tag_set.ops = &nvme_loop_mq_ops; | 558 | ctrl->tag_set.ops = &nvme_loop_mq_ops; |
559 | ctrl->tag_set.queue_depth = ctrl->ctrl.sqsize; | 559 | ctrl->tag_set.queue_depth = ctrl->ctrl.opts->queue_size; |
560 | ctrl->tag_set.reserved_tags = 1; /* fabric connect */ | 560 | ctrl->tag_set.reserved_tags = 1; /* fabric connect */ |
561 | ctrl->tag_set.numa_node = NUMA_NO_NODE; | 561 | ctrl->tag_set.numa_node = NUMA_NO_NODE; |
562 | ctrl->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; | 562 | ctrl->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; |
@@ -620,7 +620,7 @@ static struct nvme_ctrl *nvme_loop_create_ctrl(struct device *dev, | |||
620 | 620 | ||
621 | ret = -ENOMEM; | 621 | ret = -ENOMEM; |
622 | 622 | ||
623 | ctrl->ctrl.sqsize = opts->queue_size; | 623 | ctrl->ctrl.sqsize = opts->queue_size - 1; |
624 | ctrl->ctrl.kato = opts->kato; | 624 | ctrl->ctrl.kato = opts->kato; |
625 | 625 | ||
626 | ctrl->queues = kcalloc(opts->nr_io_queues + 1, sizeof(*ctrl->queues), | 626 | ctrl->queues = kcalloc(opts->nr_io_queues + 1, sizeof(*ctrl->queues), |
diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c index b4d648536c3e..1cbe6e053b5b 100644 --- a/drivers/nvme/target/rdma.c +++ b/drivers/nvme/target/rdma.c | |||
@@ -978,10 +978,11 @@ static void nvmet_rdma_release_queue_work(struct work_struct *w) | |||
978 | container_of(w, struct nvmet_rdma_queue, release_work); | 978 | container_of(w, struct nvmet_rdma_queue, release_work); |
979 | struct rdma_cm_id *cm_id = queue->cm_id; | 979 | struct rdma_cm_id *cm_id = queue->cm_id; |
980 | struct nvmet_rdma_device *dev = queue->dev; | 980 | struct nvmet_rdma_device *dev = queue->dev; |
981 | enum nvmet_rdma_queue_state state = queue->state; | ||
981 | 982 | ||
982 | nvmet_rdma_free_queue(queue); | 983 | nvmet_rdma_free_queue(queue); |
983 | 984 | ||
984 | if (queue->state != NVMET_RDMA_IN_DEVICE_REMOVAL) | 985 | if (state != NVMET_RDMA_IN_DEVICE_REMOVAL) |
985 | rdma_destroy_id(cm_id); | 986 | rdma_destroy_id(cm_id); |
986 | 987 | ||
987 | kref_put(&dev->ref, nvmet_rdma_free_dev); | 988 | kref_put(&dev->ref, nvmet_rdma_free_dev); |
@@ -1003,10 +1004,10 @@ nvmet_rdma_parse_cm_connect_req(struct rdma_conn_param *conn, | |||
1003 | queue->host_qid = le16_to_cpu(req->qid); | 1004 | queue->host_qid = le16_to_cpu(req->qid); |
1004 | 1005 | ||
1005 | /* | 1006 | /* |
1006 | * req->hsqsize corresponds to our recv queue size | 1007 | * req->hsqsize corresponds to our recv queue size plus 1 |
1007 | * req->hrqsize corresponds to our send queue size | 1008 | * req->hrqsize corresponds to our send queue size |
1008 | */ | 1009 | */ |
1009 | queue->recv_queue_size = le16_to_cpu(req->hsqsize); | 1010 | queue->recv_queue_size = le16_to_cpu(req->hsqsize) + 1; |
1010 | queue->send_queue_size = le16_to_cpu(req->hrqsize); | 1011 | queue->send_queue_size = le16_to_cpu(req->hrqsize); |
1011 | 1012 | ||
1012 | if (!queue->host_qid && queue->recv_queue_size > NVMF_AQ_DEPTH) | 1013 | if (!queue->host_qid && queue->recv_queue_size > NVMF_AQ_DEPTH) |
diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c index 5f4a2e04c8d7..add66236215c 100644 --- a/drivers/pci/host-bridge.c +++ b/drivers/pci/host-bridge.c | |||
@@ -44,6 +44,7 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge, | |||
44 | bridge->release_fn = release_fn; | 44 | bridge->release_fn = release_fn; |
45 | bridge->release_data = release_data; | 45 | bridge->release_data = release_data; |
46 | } | 46 | } |
47 | EXPORT_SYMBOL_GPL(pci_set_host_bridge_release); | ||
47 | 48 | ||
48 | void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, | 49 | void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, |
49 | struct resource *res) | 50 | struct resource *res) |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index eafa6138a6b8..98f12223c734 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -1069,7 +1069,7 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec, | |||
1069 | nvec = maxvec; | 1069 | nvec = maxvec; |
1070 | 1070 | ||
1071 | for (;;) { | 1071 | for (;;) { |
1072 | if (!(flags & PCI_IRQ_NOAFFINITY)) { | 1072 | if (flags & PCI_IRQ_AFFINITY) { |
1073 | dev->irq_affinity = irq_create_affinity_mask(&nvec); | 1073 | dev->irq_affinity = irq_create_affinity_mask(&nvec); |
1074 | if (nvec < minvec) | 1074 | if (nvec < minvec) |
1075 | return -ENOSPC; | 1075 | return -ENOSPC; |
@@ -1105,7 +1105,7 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec, | |||
1105 | **/ | 1105 | **/ |
1106 | int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) | 1106 | int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) |
1107 | { | 1107 | { |
1108 | return __pci_enable_msi_range(dev, minvec, maxvec, PCI_IRQ_NOAFFINITY); | 1108 | return __pci_enable_msi_range(dev, minvec, maxvec, 0); |
1109 | } | 1109 | } |
1110 | EXPORT_SYMBOL(pci_enable_msi_range); | 1110 | EXPORT_SYMBOL(pci_enable_msi_range); |
1111 | 1111 | ||
@@ -1120,7 +1120,7 @@ static int __pci_enable_msix_range(struct pci_dev *dev, | |||
1120 | return -ERANGE; | 1120 | return -ERANGE; |
1121 | 1121 | ||
1122 | for (;;) { | 1122 | for (;;) { |
1123 | if (!(flags & PCI_IRQ_NOAFFINITY)) { | 1123 | if (flags & PCI_IRQ_AFFINITY) { |
1124 | dev->irq_affinity = irq_create_affinity_mask(&nvec); | 1124 | dev->irq_affinity = irq_create_affinity_mask(&nvec); |
1125 | if (nvec < minvec) | 1125 | if (nvec < minvec) |
1126 | return -ENOSPC; | 1126 | return -ENOSPC; |
@@ -1160,8 +1160,7 @@ static int __pci_enable_msix_range(struct pci_dev *dev, | |||
1160 | int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, | 1160 | int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, |
1161 | int minvec, int maxvec) | 1161 | int minvec, int maxvec) |
1162 | { | 1162 | { |
1163 | return __pci_enable_msix_range(dev, entries, minvec, maxvec, | 1163 | return __pci_enable_msix_range(dev, entries, minvec, maxvec, 0); |
1164 | PCI_IRQ_NOAFFINITY); | ||
1165 | } | 1164 | } |
1166 | EXPORT_SYMBOL(pci_enable_msix_range); | 1165 | EXPORT_SYMBOL(pci_enable_msix_range); |
1167 | 1166 | ||
@@ -1187,22 +1186,25 @@ int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, | |||
1187 | { | 1186 | { |
1188 | int vecs = -ENOSPC; | 1187 | int vecs = -ENOSPC; |
1189 | 1188 | ||
1190 | if (!(flags & PCI_IRQ_NOMSIX)) { | 1189 | if (flags & PCI_IRQ_MSIX) { |
1191 | vecs = __pci_enable_msix_range(dev, NULL, min_vecs, max_vecs, | 1190 | vecs = __pci_enable_msix_range(dev, NULL, min_vecs, max_vecs, |
1192 | flags); | 1191 | flags); |
1193 | if (vecs > 0) | 1192 | if (vecs > 0) |
1194 | return vecs; | 1193 | return vecs; |
1195 | } | 1194 | } |
1196 | 1195 | ||
1197 | if (!(flags & PCI_IRQ_NOMSI)) { | 1196 | if (flags & PCI_IRQ_MSI) { |
1198 | vecs = __pci_enable_msi_range(dev, min_vecs, max_vecs, flags); | 1197 | vecs = __pci_enable_msi_range(dev, min_vecs, max_vecs, flags); |
1199 | if (vecs > 0) | 1198 | if (vecs > 0) |
1200 | return vecs; | 1199 | return vecs; |
1201 | } | 1200 | } |
1202 | 1201 | ||
1203 | /* use legacy irq if allowed */ | 1202 | /* use legacy irq if allowed */ |
1204 | if (!(flags & PCI_IRQ_NOLEGACY) && min_vecs == 1) | 1203 | if ((flags & PCI_IRQ_LEGACY) && min_vecs == 1) { |
1204 | pci_intx(dev, 1); | ||
1205 | return 1; | 1205 | return 1; |
1206 | } | ||
1207 | |||
1206 | return vecs; | 1208 | return vecs; |
1207 | } | 1209 | } |
1208 | EXPORT_SYMBOL(pci_alloc_irq_vectors); | 1210 | EXPORT_SYMBOL(pci_alloc_irq_vectors); |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 37ff0158e45f..44e0ff37480b 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -3327,9 +3327,9 @@ static void quirk_apple_wait_for_thunderbolt(struct pci_dev *dev) | |||
3327 | if (nhi->vendor != PCI_VENDOR_ID_INTEL | 3327 | if (nhi->vendor != PCI_VENDOR_ID_INTEL |
3328 | || (nhi->device != PCI_DEVICE_ID_INTEL_LIGHT_RIDGE && | 3328 | || (nhi->device != PCI_DEVICE_ID_INTEL_LIGHT_RIDGE && |
3329 | nhi->device != PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C && | 3329 | nhi->device != PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C && |
3330 | nhi->device != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI && | ||
3330 | nhi->device != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI) | 3331 | nhi->device != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI) |
3331 | || nhi->subsystem_vendor != 0x2222 | 3332 | || nhi->class != PCI_CLASS_SYSTEM_OTHER << 8) |
3332 | || nhi->subsystem_device != 0x1111) | ||
3333 | goto out; | 3333 | goto out; |
3334 | dev_info(&dev->dev, "quirk: waiting for thunderbolt to reestablish PCI tunnels...\n"); | 3334 | dev_info(&dev->dev, "quirk: waiting for thunderbolt to reestablish PCI tunnels...\n"); |
3335 | device_pm_wait_for_dev(&dev->dev, &nhi->dev); | 3335 | device_pm_wait_for_dev(&dev->dev, &nhi->dev); |
@@ -3344,6 +3344,9 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, | |||
3344 | PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C, | 3344 | PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C, |
3345 | quirk_apple_wait_for_thunderbolt); | 3345 | quirk_apple_wait_for_thunderbolt); |
3346 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, | 3346 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, |
3347 | PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_BRIDGE, | ||
3348 | quirk_apple_wait_for_thunderbolt); | ||
3349 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, | ||
3347 | PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_BRIDGE, | 3350 | PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_BRIDGE, |
3348 | quirk_apple_wait_for_thunderbolt); | 3351 | quirk_apple_wait_for_thunderbolt); |
3349 | #endif | 3352 | #endif |
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index d1ef7acf6930..f9357e09e9b3 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
@@ -40,6 +40,7 @@ static void pci_destroy_dev(struct pci_dev *dev) | |||
40 | list_del(&dev->bus_list); | 40 | list_del(&dev->bus_list); |
41 | up_write(&pci_bus_sem); | 41 | up_write(&pci_bus_sem); |
42 | 42 | ||
43 | pci_bridge_d3_device_removed(dev); | ||
43 | pci_free_resources(dev); | 44 | pci_free_resources(dev); |
44 | put_device(&dev->dev); | 45 | put_device(&dev->dev); |
45 | } | 46 | } |
@@ -96,8 +97,6 @@ static void pci_remove_bus_device(struct pci_dev *dev) | |||
96 | dev->subordinate = NULL; | 97 | dev->subordinate = NULL; |
97 | } | 98 | } |
98 | 99 | ||
99 | pci_bridge_d3_device_removed(dev); | ||
100 | |||
101 | pci_destroy_dev(dev); | 100 | pci_destroy_dev(dev); |
102 | } | 101 | } |
103 | 102 | ||
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 489ea1098c96..69b5e811ea2b 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -977,7 +977,7 @@ static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
977 | 977 | ||
978 | /************************ runtime PM support ***************************/ | 978 | /************************ runtime PM support ***************************/ |
979 | 979 | ||
980 | static int pcmcia_dev_suspend(struct device *dev, pm_message_t state); | 980 | static int pcmcia_dev_suspend(struct device *dev); |
981 | static int pcmcia_dev_resume(struct device *dev); | 981 | static int pcmcia_dev_resume(struct device *dev); |
982 | 982 | ||
983 | static int runtime_suspend(struct device *dev) | 983 | static int runtime_suspend(struct device *dev) |
@@ -985,7 +985,7 @@ static int runtime_suspend(struct device *dev) | |||
985 | int rc; | 985 | int rc; |
986 | 986 | ||
987 | device_lock(dev); | 987 | device_lock(dev); |
988 | rc = pcmcia_dev_suspend(dev, PMSG_SUSPEND); | 988 | rc = pcmcia_dev_suspend(dev); |
989 | device_unlock(dev); | 989 | device_unlock(dev); |
990 | return rc; | 990 | return rc; |
991 | } | 991 | } |
@@ -1135,7 +1135,7 @@ ATTRIBUTE_GROUPS(pcmcia_dev); | |||
1135 | 1135 | ||
1136 | /* PM support, also needed for reset */ | 1136 | /* PM support, also needed for reset */ |
1137 | 1137 | ||
1138 | static int pcmcia_dev_suspend(struct device *dev, pm_message_t state) | 1138 | static int pcmcia_dev_suspend(struct device *dev) |
1139 | { | 1139 | { |
1140 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | 1140 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); |
1141 | struct pcmcia_driver *p_drv = NULL; | 1141 | struct pcmcia_driver *p_drv = NULL; |
@@ -1410,6 +1410,9 @@ static struct class_interface pcmcia_bus_interface __refdata = { | |||
1410 | .remove_dev = &pcmcia_bus_remove_socket, | 1410 | .remove_dev = &pcmcia_bus_remove_socket, |
1411 | }; | 1411 | }; |
1412 | 1412 | ||
1413 | static const struct dev_pm_ops pcmcia_bus_pm_ops = { | ||
1414 | SET_SYSTEM_SLEEP_PM_OPS(pcmcia_dev_suspend, pcmcia_dev_resume) | ||
1415 | }; | ||
1413 | 1416 | ||
1414 | struct bus_type pcmcia_bus_type = { | 1417 | struct bus_type pcmcia_bus_type = { |
1415 | .name = "pcmcia", | 1418 | .name = "pcmcia", |
@@ -1418,8 +1421,7 @@ struct bus_type pcmcia_bus_type = { | |||
1418 | .dev_groups = pcmcia_dev_groups, | 1421 | .dev_groups = pcmcia_dev_groups, |
1419 | .probe = pcmcia_device_probe, | 1422 | .probe = pcmcia_device_probe, |
1420 | .remove = pcmcia_device_remove, | 1423 | .remove = pcmcia_device_remove, |
1421 | .suspend = pcmcia_dev_suspend, | 1424 | .pm = &pcmcia_bus_pm_ops, |
1422 | .resume = pcmcia_dev_resume, | ||
1423 | }; | 1425 | }; |
1424 | 1426 | ||
1425 | 1427 | ||
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 483f919e0d2e..91b5f5724cba 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c | |||
@@ -214,9 +214,8 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt, | |||
214 | } | 214 | } |
215 | #endif | 215 | #endif |
216 | 216 | ||
217 | void pxa2xx_configure_sockets(struct device *dev) | 217 | void pxa2xx_configure_sockets(struct device *dev, struct pcmcia_low_level *ops) |
218 | { | 218 | { |
219 | struct pcmcia_low_level *ops = dev->platform_data; | ||
220 | /* | 219 | /* |
221 | * We have at least one socket, so set MECR:CIT | 220 | * We have at least one socket, so set MECR:CIT |
222 | * (Card Is There) | 221 | * (Card Is There) |
@@ -322,7 +321,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) | |||
322 | goto err1; | 321 | goto err1; |
323 | } | 322 | } |
324 | 323 | ||
325 | pxa2xx_configure_sockets(&dev->dev); | 324 | pxa2xx_configure_sockets(&dev->dev, ops); |
326 | dev_set_drvdata(&dev->dev, sinfo); | 325 | dev_set_drvdata(&dev->dev, sinfo); |
327 | 326 | ||
328 | return 0; | 327 | return 0; |
@@ -348,7 +347,9 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev) | |||
348 | 347 | ||
349 | static int pxa2xx_drv_pcmcia_resume(struct device *dev) | 348 | static int pxa2xx_drv_pcmcia_resume(struct device *dev) |
350 | { | 349 | { |
351 | pxa2xx_configure_sockets(dev); | 350 | struct pcmcia_low_level *ops = (struct pcmcia_low_level *)dev->platform_data; |
351 | |||
352 | pxa2xx_configure_sockets(dev, ops); | ||
352 | return 0; | 353 | return 0; |
353 | } | 354 | } |
354 | 355 | ||
diff --git a/drivers/pcmcia/pxa2xx_base.h b/drivers/pcmcia/pxa2xx_base.h index b609b45469ed..e58c7a415418 100644 --- a/drivers/pcmcia/pxa2xx_base.h +++ b/drivers/pcmcia/pxa2xx_base.h | |||
@@ -1,4 +1,4 @@ | |||
1 | int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt); | 1 | int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt); |
2 | void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops); | 2 | void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops); |
3 | void pxa2xx_configure_sockets(struct device *dev); | 3 | void pxa2xx_configure_sockets(struct device *dev, struct pcmcia_low_level *ops); |
4 | 4 | ||
diff --git a/drivers/pcmcia/sa1111_badge4.c b/drivers/pcmcia/sa1111_badge4.c index 12f0dd091477..2f490930430d 100644 --- a/drivers/pcmcia/sa1111_badge4.c +++ b/drivers/pcmcia/sa1111_badge4.c | |||
@@ -134,20 +134,14 @@ static struct pcmcia_low_level badge4_pcmcia_ops = { | |||
134 | 134 | ||
135 | int pcmcia_badge4_init(struct sa1111_dev *dev) | 135 | int pcmcia_badge4_init(struct sa1111_dev *dev) |
136 | { | 136 | { |
137 | int ret = -ENODEV; | 137 | printk(KERN_INFO |
138 | 138 | "%s: badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d\n", | |
139 | if (machine_is_badge4()) { | 139 | __func__, |
140 | printk(KERN_INFO | 140 | badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc); |
141 | "%s: badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d\n", | 141 | |
142 | __func__, | 142 | sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops); |
143 | badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc); | 143 | return sa1111_pcmcia_add(dev, &badge4_pcmcia_ops, |
144 | 144 | sa11xx_drv_pcmcia_add_one); | |
145 | sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops); | ||
146 | ret = sa1111_pcmcia_add(dev, &badge4_pcmcia_ops, | ||
147 | sa11xx_drv_pcmcia_add_one); | ||
148 | } | ||
149 | |||
150 | return ret; | ||
151 | } | 145 | } |
152 | 146 | ||
153 | static int __init pcmv_setup(char *s) | 147 | static int __init pcmv_setup(char *s) |
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index a1531feb8460..3d95dffcff7a 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include <mach/hardware.h> | 19 | #include <mach/hardware.h> |
20 | #include <asm/hardware/sa1111.h> | 20 | #include <asm/hardware/sa1111.h> |
21 | #include <asm/mach-types.h> | ||
21 | #include <asm/irq.h> | 22 | #include <asm/irq.h> |
22 | 23 | ||
23 | #include "sa1111_generic.h" | 24 | #include "sa1111_generic.h" |
@@ -203,19 +204,30 @@ static int pcmcia_probe(struct sa1111_dev *dev) | |||
203 | sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + PCSSR); | 204 | sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + PCSSR); |
204 | sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + PCCR); | 205 | sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + PCCR); |
205 | 206 | ||
207 | ret = -ENODEV; | ||
206 | #ifdef CONFIG_SA1100_BADGE4 | 208 | #ifdef CONFIG_SA1100_BADGE4 |
207 | pcmcia_badge4_init(dev); | 209 | if (machine_is_badge4()) |
210 | ret = pcmcia_badge4_init(dev); | ||
208 | #endif | 211 | #endif |
209 | #ifdef CONFIG_SA1100_JORNADA720 | 212 | #ifdef CONFIG_SA1100_JORNADA720 |
210 | pcmcia_jornada720_init(dev); | 213 | if (machine_is_jornada720()) |
214 | ret = pcmcia_jornada720_init(dev); | ||
211 | #endif | 215 | #endif |
212 | #ifdef CONFIG_ARCH_LUBBOCK | 216 | #ifdef CONFIG_ARCH_LUBBOCK |
213 | pcmcia_lubbock_init(dev); | 217 | if (machine_is_lubbock()) |
218 | ret = pcmcia_lubbock_init(dev); | ||
214 | #endif | 219 | #endif |
215 | #ifdef CONFIG_ASSABET_NEPONSET | 220 | #ifdef CONFIG_ASSABET_NEPONSET |
216 | pcmcia_neponset_init(dev); | 221 | if (machine_is_assabet()) |
222 | ret = pcmcia_neponset_init(dev); | ||
217 | #endif | 223 | #endif |
218 | return 0; | 224 | |
225 | if (ret) { | ||
226 | release_mem_region(dev->res.start, 512); | ||
227 | sa1111_disable_device(dev); | ||
228 | } | ||
229 | |||
230 | return ret; | ||
219 | } | 231 | } |
220 | 232 | ||
221 | static int pcmcia_remove(struct sa1111_dev *dev) | 233 | static int pcmcia_remove(struct sa1111_dev *dev) |
diff --git a/drivers/pcmcia/sa1111_jornada720.c b/drivers/pcmcia/sa1111_jornada720.c index c2c30580c83f..480a3ede27c8 100644 --- a/drivers/pcmcia/sa1111_jornada720.c +++ b/drivers/pcmcia/sa1111_jornada720.c | |||
@@ -94,22 +94,17 @@ static struct pcmcia_low_level jornada720_pcmcia_ops = { | |||
94 | 94 | ||
95 | int pcmcia_jornada720_init(struct sa1111_dev *sadev) | 95 | int pcmcia_jornada720_init(struct sa1111_dev *sadev) |
96 | { | 96 | { |
97 | int ret = -ENODEV; | 97 | unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3; |
98 | 98 | ||
99 | if (machine_is_jornada720()) { | 99 | /* Fixme: why messing around with SA11x0's GPIO1? */ |
100 | unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3; | 100 | GRER |= 0x00000002; |
101 | 101 | ||
102 | GRER |= 0x00000002; | 102 | /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */ |
103 | sa1111_set_io_dir(sadev, pin, 0, 0); | ||
104 | sa1111_set_io(sadev, pin, 0); | ||
105 | sa1111_set_sleep_io(sadev, pin, 0); | ||
103 | 106 | ||
104 | /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */ | 107 | sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops); |
105 | sa1111_set_io_dir(sadev, pin, 0, 0); | 108 | return sa1111_pcmcia_add(sadev, &jornada720_pcmcia_ops, |
106 | sa1111_set_io(sadev, pin, 0); | 109 | sa11xx_drv_pcmcia_add_one); |
107 | sa1111_set_sleep_io(sadev, pin, 0); | ||
108 | |||
109 | sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops); | ||
110 | ret = sa1111_pcmcia_add(sadev, &jornada720_pcmcia_ops, | ||
111 | sa11xx_drv_pcmcia_add_one); | ||
112 | } | ||
113 | |||
114 | return ret; | ||
115 | } | 110 | } |
diff --git a/drivers/pcmcia/sa1111_lubbock.c b/drivers/pcmcia/sa1111_lubbock.c index c5caf5790451..e741f499c875 100644 --- a/drivers/pcmcia/sa1111_lubbock.c +++ b/drivers/pcmcia/sa1111_lubbock.c | |||
@@ -210,27 +210,21 @@ static struct pcmcia_low_level lubbock_pcmcia_ops = { | |||
210 | 210 | ||
211 | int pcmcia_lubbock_init(struct sa1111_dev *sadev) | 211 | int pcmcia_lubbock_init(struct sa1111_dev *sadev) |
212 | { | 212 | { |
213 | int ret = -ENODEV; | 213 | /* |
214 | 214 | * Set GPIO_A<3:0> to be outputs for the MAX1600, | |
215 | if (machine_is_lubbock()) { | 215 | * and switch to standby mode. |
216 | /* | 216 | */ |
217 | * Set GPIO_A<3:0> to be outputs for the MAX1600, | 217 | sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0); |
218 | * and switch to standby mode. | 218 | sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); |
219 | */ | 219 | sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); |
220 | sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0); | ||
221 | sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); | ||
222 | sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); | ||
223 | |||
224 | /* Set CF Socket 1 power to standby mode. */ | ||
225 | lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); | ||
226 | 220 | ||
227 | pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops); | 221 | /* Set CF Socket 1 power to standby mode. */ |
228 | pxa2xx_configure_sockets(&sadev->dev); | 222 | lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); |
229 | ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops, | ||
230 | pxa2xx_drv_pcmcia_add_one); | ||
231 | } | ||
232 | 223 | ||
233 | return ret; | 224 | pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops); |
225 | pxa2xx_configure_sockets(&sadev->dev, &lubbock_pcmcia_ops); | ||
226 | return sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops, | ||
227 | pxa2xx_drv_pcmcia_add_one); | ||
234 | } | 228 | } |
235 | 229 | ||
236 | MODULE_LICENSE("GPL"); | 230 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/pcmcia/sa1111_neponset.c b/drivers/pcmcia/sa1111_neponset.c index 1d78739c4c07..019c395eb4bf 100644 --- a/drivers/pcmcia/sa1111_neponset.c +++ b/drivers/pcmcia/sa1111_neponset.c | |||
@@ -110,20 +110,14 @@ static struct pcmcia_low_level neponset_pcmcia_ops = { | |||
110 | 110 | ||
111 | int pcmcia_neponset_init(struct sa1111_dev *sadev) | 111 | int pcmcia_neponset_init(struct sa1111_dev *sadev) |
112 | { | 112 | { |
113 | int ret = -ENODEV; | 113 | /* |
114 | 114 | * Set GPIO_A<3:0> to be outputs for the MAX1600, | |
115 | if (machine_is_assabet()) { | 115 | * and switch to standby mode. |
116 | /* | 116 | */ |
117 | * Set GPIO_A<3:0> to be outputs for the MAX1600, | 117 | sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0); |
118 | * and switch to standby mode. | 118 | sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); |
119 | */ | 119 | sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); |
120 | sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0); | 120 | sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops); |
121 | sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); | 121 | return sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops, |
122 | sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); | 122 | sa11xx_drv_pcmcia_add_one); |
123 | sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops); | ||
124 | ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops, | ||
125 | sa11xx_drv_pcmcia_add_one); | ||
126 | } | ||
127 | |||
128 | return ret; | ||
129 | } | 123 | } |
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c index 9f6ec87b9f9e..48140ac73ed6 100644 --- a/drivers/pcmcia/sa11xx_base.c +++ b/drivers/pcmcia/sa11xx_base.c | |||
@@ -144,19 +144,19 @@ static int | |||
144 | sa1100_pcmcia_show_timing(struct soc_pcmcia_socket *skt, char *buf) | 144 | sa1100_pcmcia_show_timing(struct soc_pcmcia_socket *skt, char *buf) |
145 | { | 145 | { |
146 | struct soc_pcmcia_timing timing; | 146 | struct soc_pcmcia_timing timing; |
147 | unsigned int clock = clk_get_rate(skt->clk); | 147 | unsigned int clock = clk_get_rate(skt->clk) / 1000; |
148 | unsigned long mecr = MECR; | 148 | unsigned long mecr = MECR; |
149 | char *p = buf; | 149 | char *p = buf; |
150 | 150 | ||
151 | soc_common_pcmcia_get_timing(skt, &timing); | 151 | soc_common_pcmcia_get_timing(skt, &timing); |
152 | 152 | ||
153 | p+=sprintf(p, "I/O : %u (%u)\n", timing.io, | 153 | p+=sprintf(p, "I/O : %uns (%uns)\n", timing.io, |
154 | sa1100_pcmcia_cmd_time(clock, MECR_BSIO_GET(mecr, skt->nr))); | 154 | sa1100_pcmcia_cmd_time(clock, MECR_BSIO_GET(mecr, skt->nr))); |
155 | 155 | ||
156 | p+=sprintf(p, "attribute: %u (%u)\n", timing.attr, | 156 | p+=sprintf(p, "attribute: %uns (%uns)\n", timing.attr, |
157 | sa1100_pcmcia_cmd_time(clock, MECR_BSA_GET(mecr, skt->nr))); | 157 | sa1100_pcmcia_cmd_time(clock, MECR_BSA_GET(mecr, skt->nr))); |
158 | 158 | ||
159 | p+=sprintf(p, "common : %u (%u)\n", timing.mem, | 159 | p+=sprintf(p, "common : %uns (%uns)\n", timing.mem, |
160 | sa1100_pcmcia_cmd_time(clock, MECR_BSM_GET(mecr, skt->nr))); | 160 | sa1100_pcmcia_cmd_time(clock, MECR_BSM_GET(mecr, skt->nr))); |
161 | 161 | ||
162 | return p - buf; | 162 | return p - buf; |
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index eed5e9c05353..d5ca760c4eb2 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c | |||
@@ -235,7 +235,7 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt) | |||
235 | stat |= skt->cs_state.Vcc ? SS_POWERON : 0; | 235 | stat |= skt->cs_state.Vcc ? SS_POWERON : 0; |
236 | 236 | ||
237 | if (skt->cs_state.flags & SS_IOCARD) | 237 | if (skt->cs_state.flags & SS_IOCARD) |
238 | stat |= state.bvd1 ? SS_STSCHG : 0; | 238 | stat |= state.bvd1 ? 0 : SS_STSCHG; |
239 | else { | 239 | else { |
240 | if (state.bvd1 == 0) | 240 | if (state.bvd1 == 0) |
241 | stat |= SS_BATDEAD; | 241 | stat |= SS_BATDEAD; |
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index c494613c1909..f5e1008a223d 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c | |||
@@ -925,6 +925,7 @@ static int of_pmu_irq_cfg(struct arm_pmu *pmu) | |||
925 | if (i > 0 && spi != using_spi) { | 925 | if (i > 0 && spi != using_spi) { |
926 | pr_err("PPI/SPI IRQ type mismatch for %s!\n", | 926 | pr_err("PPI/SPI IRQ type mismatch for %s!\n", |
927 | dn->name); | 927 | dn->name); |
928 | of_node_put(dn); | ||
928 | kfree(irqs); | 929 | kfree(irqs); |
929 | return -EINVAL; | 930 | return -EINVAL; |
930 | } | 931 | } |
@@ -969,7 +970,7 @@ static int of_pmu_irq_cfg(struct arm_pmu *pmu) | |||
969 | if (cpumask_weight(&pmu->supported_cpus) == 0) { | 970 | if (cpumask_weight(&pmu->supported_cpus) == 0) { |
970 | int irq = platform_get_irq(pdev, 0); | 971 | int irq = platform_get_irq(pdev, 0); |
971 | 972 | ||
972 | if (irq_is_percpu(irq)) { | 973 | if (irq >= 0 && irq_is_percpu(irq)) { |
973 | /* If using PPIs, check the affinity of the partition */ | 974 | /* If using PPIs, check the affinity of the partition */ |
974 | int ret; | 975 | int ret; |
975 | 976 | ||
diff --git a/drivers/phy/phy-brcm-sata.c b/drivers/phy/phy-brcm-sata.c index 18d662610075..8ffc44afdb75 100644 --- a/drivers/phy/phy-brcm-sata.c +++ b/drivers/phy/phy-brcm-sata.c | |||
@@ -367,7 +367,7 @@ static int brcm_sata_phy_init(struct phy *phy) | |||
367 | rc = -ENODEV; | 367 | rc = -ENODEV; |
368 | }; | 368 | }; |
369 | 369 | ||
370 | return 0; | 370 | return rc; |
371 | } | 371 | } |
372 | 372 | ||
373 | static const struct phy_ops phy_ops = { | 373 | static const struct phy_ops phy_ops = { |
diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c index 0a45bc6088ae..8c7eb335622e 100644 --- a/drivers/phy/phy-sun4i-usb.c +++ b/drivers/phy/phy-sun4i-usb.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/power_supply.h> | 40 | #include <linux/power_supply.h> |
41 | #include <linux/regulator/consumer.h> | 41 | #include <linux/regulator/consumer.h> |
42 | #include <linux/reset.h> | 42 | #include <linux/reset.h> |
43 | #include <linux/usb/of.h> | ||
43 | #include <linux/workqueue.h> | 44 | #include <linux/workqueue.h> |
44 | 45 | ||
45 | #define REG_ISCR 0x00 | 46 | #define REG_ISCR 0x00 |
@@ -110,6 +111,7 @@ struct sun4i_usb_phy_cfg { | |||
110 | struct sun4i_usb_phy_data { | 111 | struct sun4i_usb_phy_data { |
111 | void __iomem *base; | 112 | void __iomem *base; |
112 | const struct sun4i_usb_phy_cfg *cfg; | 113 | const struct sun4i_usb_phy_cfg *cfg; |
114 | enum usb_dr_mode dr_mode; | ||
113 | struct mutex mutex; | 115 | struct mutex mutex; |
114 | struct sun4i_usb_phy { | 116 | struct sun4i_usb_phy { |
115 | struct phy *phy; | 117 | struct phy *phy; |
@@ -120,6 +122,7 @@ struct sun4i_usb_phy_data { | |||
120 | bool regulator_on; | 122 | bool regulator_on; |
121 | int index; | 123 | int index; |
122 | } phys[MAX_PHYS]; | 124 | } phys[MAX_PHYS]; |
125 | int first_phy; | ||
123 | /* phy0 / otg related variables */ | 126 | /* phy0 / otg related variables */ |
124 | struct extcon_dev *extcon; | 127 | struct extcon_dev *extcon; |
125 | bool phy0_init; | 128 | bool phy0_init; |
@@ -285,16 +288,10 @@ static int sun4i_usb_phy_init(struct phy *_phy) | |||
285 | sun4i_usb_phy0_update_iscr(_phy, 0, ISCR_DPDM_PULLUP_EN); | 288 | sun4i_usb_phy0_update_iscr(_phy, 0, ISCR_DPDM_PULLUP_EN); |
286 | sun4i_usb_phy0_update_iscr(_phy, 0, ISCR_ID_PULLUP_EN); | 289 | sun4i_usb_phy0_update_iscr(_phy, 0, ISCR_ID_PULLUP_EN); |
287 | 290 | ||
288 | if (data->id_det_gpio) { | 291 | /* Force ISCR and cable state updates */ |
289 | /* OTG mode, force ISCR and cable state updates */ | 292 | data->id_det = -1; |
290 | data->id_det = -1; | 293 | data->vbus_det = -1; |
291 | data->vbus_det = -1; | 294 | queue_delayed_work(system_wq, &data->detect, 0); |
292 | queue_delayed_work(system_wq, &data->detect, 0); | ||
293 | } else { | ||
294 | /* Host only mode */ | ||
295 | sun4i_usb_phy0_set_id_detect(_phy, 0); | ||
296 | sun4i_usb_phy0_set_vbus_detect(_phy, 1); | ||
297 | } | ||
298 | } | 295 | } |
299 | 296 | ||
300 | return 0; | 297 | return 0; |
@@ -319,6 +316,19 @@ static int sun4i_usb_phy_exit(struct phy *_phy) | |||
319 | return 0; | 316 | return 0; |
320 | } | 317 | } |
321 | 318 | ||
319 | static int sun4i_usb_phy0_get_id_det(struct sun4i_usb_phy_data *data) | ||
320 | { | ||
321 | switch (data->dr_mode) { | ||
322 | case USB_DR_MODE_OTG: | ||
323 | return gpiod_get_value_cansleep(data->id_det_gpio); | ||
324 | case USB_DR_MODE_HOST: | ||
325 | return 0; | ||
326 | case USB_DR_MODE_PERIPHERAL: | ||
327 | default: | ||
328 | return 1; | ||
329 | } | ||
330 | } | ||
331 | |||
322 | static int sun4i_usb_phy0_get_vbus_det(struct sun4i_usb_phy_data *data) | 332 | static int sun4i_usb_phy0_get_vbus_det(struct sun4i_usb_phy_data *data) |
323 | { | 333 | { |
324 | if (data->vbus_det_gpio) | 334 | if (data->vbus_det_gpio) |
@@ -432,7 +442,10 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work) | |||
432 | struct phy *phy0 = data->phys[0].phy; | 442 | struct phy *phy0 = data->phys[0].phy; |
433 | int id_det, vbus_det, id_notify = 0, vbus_notify = 0; | 443 | int id_det, vbus_det, id_notify = 0, vbus_notify = 0; |
434 | 444 | ||
435 | id_det = gpiod_get_value_cansleep(data->id_det_gpio); | 445 | if (phy0 == NULL) |
446 | return; | ||
447 | |||
448 | id_det = sun4i_usb_phy0_get_id_det(data); | ||
436 | vbus_det = sun4i_usb_phy0_get_vbus_det(data); | 449 | vbus_det = sun4i_usb_phy0_get_vbus_det(data); |
437 | 450 | ||
438 | mutex_lock(&phy0->mutex); | 451 | mutex_lock(&phy0->mutex); |
@@ -448,7 +461,8 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work) | |||
448 | * without vbus detection report vbus low for long enough for | 461 | * without vbus detection report vbus low for long enough for |
449 | * the musb-ip to end the current device session. | 462 | * the musb-ip to end the current device session. |
450 | */ | 463 | */ |
451 | if (!sun4i_usb_phy0_have_vbus_det(data) && id_det == 0) { | 464 | if (data->dr_mode == USB_DR_MODE_OTG && |
465 | !sun4i_usb_phy0_have_vbus_det(data) && id_det == 0) { | ||
452 | sun4i_usb_phy0_set_vbus_detect(phy0, 0); | 466 | sun4i_usb_phy0_set_vbus_detect(phy0, 0); |
453 | msleep(200); | 467 | msleep(200); |
454 | sun4i_usb_phy0_set_vbus_detect(phy0, 1); | 468 | sun4i_usb_phy0_set_vbus_detect(phy0, 1); |
@@ -474,7 +488,8 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work) | |||
474 | * without vbus detection report vbus low for long enough to | 488 | * without vbus detection report vbus low for long enough to |
475 | * the musb-ip to end the current host session. | 489 | * the musb-ip to end the current host session. |
476 | */ | 490 | */ |
477 | if (!sun4i_usb_phy0_have_vbus_det(data) && id_det == 1) { | 491 | if (data->dr_mode == USB_DR_MODE_OTG && |
492 | !sun4i_usb_phy0_have_vbus_det(data) && id_det == 1) { | ||
478 | mutex_lock(&phy0->mutex); | 493 | mutex_lock(&phy0->mutex); |
479 | sun4i_usb_phy0_set_vbus_detect(phy0, 0); | 494 | sun4i_usb_phy0_set_vbus_detect(phy0, 0); |
480 | msleep(1000); | 495 | msleep(1000); |
@@ -519,7 +534,8 @@ static struct phy *sun4i_usb_phy_xlate(struct device *dev, | |||
519 | { | 534 | { |
520 | struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); | 535 | struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); |
521 | 536 | ||
522 | if (args->args[0] >= data->cfg->num_phys) | 537 | if (args->args[0] < data->first_phy || |
538 | args->args[0] >= data->cfg->num_phys) | ||
523 | return ERR_PTR(-ENODEV); | 539 | return ERR_PTR(-ENODEV); |
524 | 540 | ||
525 | return data->phys[args->args[0]].phy; | 541 | return data->phys[args->args[0]].phy; |
@@ -593,13 +609,17 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) | |||
593 | return -EPROBE_DEFER; | 609 | return -EPROBE_DEFER; |
594 | } | 610 | } |
595 | 611 | ||
596 | /* vbus_det without id_det makes no sense, and is not supported */ | 612 | data->dr_mode = of_usb_get_dr_mode_by_phy(np, 0); |
597 | if (sun4i_usb_phy0_have_vbus_det(data) && !data->id_det_gpio) { | 613 | switch (data->dr_mode) { |
598 | dev_err(dev, "usb0_id_det missing or invalid\n"); | 614 | case USB_DR_MODE_OTG: |
599 | return -ENODEV; | 615 | /* otg without id_det makes no sense, and is not supported */ |
600 | } | 616 | if (!data->id_det_gpio) { |
601 | 617 | dev_err(dev, "usb0_id_det missing or invalid\n"); | |
602 | if (data->id_det_gpio) { | 618 | return -ENODEV; |
619 | } | ||
620 | /* fall through */ | ||
621 | case USB_DR_MODE_HOST: | ||
622 | case USB_DR_MODE_PERIPHERAL: | ||
603 | data->extcon = devm_extcon_dev_allocate(dev, | 623 | data->extcon = devm_extcon_dev_allocate(dev, |
604 | sun4i_usb_phy0_cable); | 624 | sun4i_usb_phy0_cable); |
605 | if (IS_ERR(data->extcon)) | 625 | if (IS_ERR(data->extcon)) |
@@ -610,9 +630,13 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) | |||
610 | dev_err(dev, "failed to register extcon: %d\n", ret); | 630 | dev_err(dev, "failed to register extcon: %d\n", ret); |
611 | return ret; | 631 | return ret; |
612 | } | 632 | } |
633 | break; | ||
634 | default: | ||
635 | dev_info(dev, "dr_mode unknown, not registering usb phy0\n"); | ||
636 | data->first_phy = 1; | ||
613 | } | 637 | } |
614 | 638 | ||
615 | for (i = 0; i < data->cfg->num_phys; i++) { | 639 | for (i = data->first_phy; i < data->cfg->num_phys; i++) { |
616 | struct sun4i_usb_phy *phy = data->phys + i; | 640 | struct sun4i_usb_phy *phy = data->phys + i; |
617 | char name[16]; | 641 | char name[16]; |
618 | 642 | ||
diff --git a/drivers/phy/phy-sun9i-usb.c b/drivers/phy/phy-sun9i-usb.c index ac4f31abefe3..28fce4bce638 100644 --- a/drivers/phy/phy-sun9i-usb.c +++ b/drivers/phy/phy-sun9i-usb.c | |||
@@ -141,9 +141,9 @@ static int sun9i_usb_phy_probe(struct platform_device *pdev) | |||
141 | } | 141 | } |
142 | 142 | ||
143 | phy->hsic_clk = devm_clk_get(dev, "hsic_12M"); | 143 | phy->hsic_clk = devm_clk_get(dev, "hsic_12M"); |
144 | if (IS_ERR(phy->clk)) { | 144 | if (IS_ERR(phy->hsic_clk)) { |
145 | dev_err(dev, "failed to get hsic_12M clock\n"); | 145 | dev_err(dev, "failed to get hsic_12M clock\n"); |
146 | return PTR_ERR(phy->clk); | 146 | return PTR_ERR(phy->hsic_clk); |
147 | } | 147 | } |
148 | 148 | ||
149 | phy->reset = devm_reset_control_get(dev, "hsic"); | 149 | phy->reset = devm_reset_control_get(dev, "hsic"); |
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 5749a4eee746..0fe8fad25e4d 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c | |||
@@ -1539,12 +1539,11 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) | |||
1539 | offset += range->npins; | 1539 | offset += range->npins; |
1540 | } | 1540 | } |
1541 | 1541 | ||
1542 | /* Mask and clear all interrupts */ | 1542 | /* Clear all interrupts */ |
1543 | chv_writel(0, pctrl->regs + CHV_INTMASK); | ||
1544 | chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); | 1543 | chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); |
1545 | 1544 | ||
1546 | ret = gpiochip_irqchip_add(chip, &chv_gpio_irqchip, 0, | 1545 | ret = gpiochip_irqchip_add(chip, &chv_gpio_irqchip, 0, |
1547 | handle_simple_irq, IRQ_TYPE_NONE); | 1546 | handle_bad_irq, IRQ_TYPE_NONE); |
1548 | if (ret) { | 1547 | if (ret) { |
1549 | dev_err(pctrl->dev, "failed to add IRQ chip\n"); | 1548 | dev_err(pctrl->dev, "failed to add IRQ chip\n"); |
1550 | goto fail; | 1549 | goto fail; |
diff --git a/drivers/pinctrl/pinctrl-pistachio.c b/drivers/pinctrl/pinctrl-pistachio.c index 7bad200bd67c..55375b1b3cc8 100644 --- a/drivers/pinctrl/pinctrl-pistachio.c +++ b/drivers/pinctrl/pinctrl-pistachio.c | |||
@@ -809,17 +809,17 @@ static const struct pistachio_pin_group pistachio_groups[] = { | |||
809 | PADS_FUNCTION_SELECT2, 12, 0x3), | 809 | PADS_FUNCTION_SELECT2, 12, 0x3), |
810 | MFIO_MUX_PIN_GROUP(83, MIPS_PLL_LOCK, MIPS_TRACE_DATA, USB_DEBUG, | 810 | MFIO_MUX_PIN_GROUP(83, MIPS_PLL_LOCK, MIPS_TRACE_DATA, USB_DEBUG, |
811 | PADS_FUNCTION_SELECT2, 14, 0x3), | 811 | PADS_FUNCTION_SELECT2, 14, 0x3), |
812 | MFIO_MUX_PIN_GROUP(84, SYS_PLL_LOCK, MIPS_TRACE_DATA, USB_DEBUG, | 812 | MFIO_MUX_PIN_GROUP(84, AUDIO_PLL_LOCK, MIPS_TRACE_DATA, USB_DEBUG, |
813 | PADS_FUNCTION_SELECT2, 16, 0x3), | 813 | PADS_FUNCTION_SELECT2, 16, 0x3), |
814 | MFIO_MUX_PIN_GROUP(85, WIFI_PLL_LOCK, MIPS_TRACE_DATA, SDHOST_DEBUG, | 814 | MFIO_MUX_PIN_GROUP(85, RPU_V_PLL_LOCK, MIPS_TRACE_DATA, SDHOST_DEBUG, |
815 | PADS_FUNCTION_SELECT2, 18, 0x3), | 815 | PADS_FUNCTION_SELECT2, 18, 0x3), |
816 | MFIO_MUX_PIN_GROUP(86, BT_PLL_LOCK, MIPS_TRACE_DATA, SDHOST_DEBUG, | 816 | MFIO_MUX_PIN_GROUP(86, RPU_L_PLL_LOCK, MIPS_TRACE_DATA, SDHOST_DEBUG, |
817 | PADS_FUNCTION_SELECT2, 20, 0x3), | 817 | PADS_FUNCTION_SELECT2, 20, 0x3), |
818 | MFIO_MUX_PIN_GROUP(87, RPU_V_PLL_LOCK, DREQ2, SOCIF_DEBUG, | 818 | MFIO_MUX_PIN_GROUP(87, SYS_PLL_LOCK, DREQ2, SOCIF_DEBUG, |
819 | PADS_FUNCTION_SELECT2, 22, 0x3), | 819 | PADS_FUNCTION_SELECT2, 22, 0x3), |
820 | MFIO_MUX_PIN_GROUP(88, RPU_L_PLL_LOCK, DREQ3, SOCIF_DEBUG, | 820 | MFIO_MUX_PIN_GROUP(88, WIFI_PLL_LOCK, DREQ3, SOCIF_DEBUG, |
821 | PADS_FUNCTION_SELECT2, 24, 0x3), | 821 | PADS_FUNCTION_SELECT2, 24, 0x3), |
822 | MFIO_MUX_PIN_GROUP(89, AUDIO_PLL_LOCK, DREQ4, DREQ5, | 822 | MFIO_MUX_PIN_GROUP(89, BT_PLL_LOCK, DREQ4, DREQ5, |
823 | PADS_FUNCTION_SELECT2, 26, 0x3), | 823 | PADS_FUNCTION_SELECT2, 26, 0x3), |
824 | PIN_GROUP(TCK, "tck"), | 824 | PIN_GROUP(TCK, "tck"), |
825 | PIN_GROUP(TRSTN, "trstn"), | 825 | PIN_GROUP(TRSTN, "trstn"), |
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c index ce483b03a263..f9d661e5c14a 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c | |||
@@ -485,12 +485,12 @@ static const struct sunxi_desc_pin sun8i_a23_pins[] = { | |||
485 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8), | 485 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8), |
486 | SUNXI_FUNCTION(0x0, "gpio_in"), | 486 | SUNXI_FUNCTION(0x0, "gpio_in"), |
487 | SUNXI_FUNCTION(0x1, "gpio_out"), | 487 | SUNXI_FUNCTION(0x1, "gpio_out"), |
488 | SUNXI_FUNCTION(0x2, "uart2"), /* RTS */ | 488 | SUNXI_FUNCTION(0x2, "uart1"), /* RTS */ |
489 | SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 8)), /* PG_EINT8 */ | 489 | SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 8)), /* PG_EINT8 */ |
490 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9), | 490 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9), |
491 | SUNXI_FUNCTION(0x0, "gpio_in"), | 491 | SUNXI_FUNCTION(0x0, "gpio_in"), |
492 | SUNXI_FUNCTION(0x1, "gpio_out"), | 492 | SUNXI_FUNCTION(0x1, "gpio_out"), |
493 | SUNXI_FUNCTION(0x2, "uart2"), /* CTS */ | 493 | SUNXI_FUNCTION(0x2, "uart1"), /* CTS */ |
494 | SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 9)), /* PG_EINT9 */ | 494 | SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 9)), /* PG_EINT9 */ |
495 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10), | 495 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10), |
496 | SUNXI_FUNCTION(0x0, "gpio_in"), | 496 | SUNXI_FUNCTION(0x0, "gpio_in"), |
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c index 3040abe6f73a..3131cac2b76f 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c | |||
@@ -407,12 +407,12 @@ static const struct sunxi_desc_pin sun8i_a33_pins[] = { | |||
407 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8), | 407 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8), |
408 | SUNXI_FUNCTION(0x0, "gpio_in"), | 408 | SUNXI_FUNCTION(0x0, "gpio_in"), |
409 | SUNXI_FUNCTION(0x1, "gpio_out"), | 409 | SUNXI_FUNCTION(0x1, "gpio_out"), |
410 | SUNXI_FUNCTION(0x2, "uart2"), /* RTS */ | 410 | SUNXI_FUNCTION(0x2, "uart1"), /* RTS */ |
411 | SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 8)), /* PG_EINT8 */ | 411 | SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 8)), /* PG_EINT8 */ |
412 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9), | 412 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9), |
413 | SUNXI_FUNCTION(0x0, "gpio_in"), | 413 | SUNXI_FUNCTION(0x0, "gpio_in"), |
414 | SUNXI_FUNCTION(0x1, "gpio_out"), | 414 | SUNXI_FUNCTION(0x1, "gpio_out"), |
415 | SUNXI_FUNCTION(0x2, "uart2"), /* CTS */ | 415 | SUNXI_FUNCTION(0x2, "uart1"), /* CTS */ |
416 | SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 9)), /* PG_EINT9 */ | 416 | SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 9)), /* PG_EINT9 */ |
417 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10), | 417 | SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10), |
418 | SUNXI_FUNCTION(0x0, "gpio_in"), | 418 | SUNXI_FUNCTION(0x0, "gpio_in"), |
diff --git a/drivers/platform/olpc/olpc-ec.c b/drivers/platform/olpc/olpc-ec.c index f99b183d5296..374a8028fec7 100644 --- a/drivers/platform/olpc/olpc-ec.c +++ b/drivers/platform/olpc/olpc-ec.c | |||
@@ -1,6 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Generic driver for the OLPC Embedded Controller. | 2 | * Generic driver for the OLPC Embedded Controller. |
3 | * | 3 | * |
4 | * Author: Andres Salomon <dilinger@queued.net> | ||
5 | * | ||
4 | * Copyright (C) 2011-2012 One Laptop per Child Foundation. | 6 | * Copyright (C) 2011-2012 One Laptop per Child Foundation. |
5 | * | 7 | * |
6 | * Licensed under the GPL v2 or later. | 8 | * Licensed under the GPL v2 or later. |
@@ -12,7 +14,7 @@ | |||
12 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
13 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
14 | #include <linux/workqueue.h> | 16 | #include <linux/workqueue.h> |
15 | #include <linux/module.h> | 17 | #include <linux/init.h> |
16 | #include <linux/list.h> | 18 | #include <linux/list.h> |
17 | #include <linux/olpc-ec.h> | 19 | #include <linux/olpc-ec.h> |
18 | #include <asm/olpc.h> | 20 | #include <asm/olpc.h> |
@@ -326,8 +328,4 @@ static int __init olpc_ec_init_module(void) | |||
326 | { | 328 | { |
327 | return platform_driver_register(&olpc_ec_plat_driver); | 329 | return platform_driver_register(&olpc_ec_plat_driver); |
328 | } | 330 | } |
329 | |||
330 | arch_initcall(olpc_ec_init_module); | 331 | arch_initcall(olpc_ec_init_module); |
331 | |||
332 | MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); | ||
333 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/platform/x86/intel_pmic_gpio.c b/drivers/platform/x86/intel_pmic_gpio.c index 63b371d6ee55..91ae58510d92 100644 --- a/drivers/platform/x86/intel_pmic_gpio.c +++ b/drivers/platform/x86/intel_pmic_gpio.c | |||
@@ -1,6 +1,8 @@ | |||
1 | /* Moorestown PMIC GPIO (access through IPC) driver | 1 | /* Moorestown PMIC GPIO (access through IPC) driver |
2 | * Copyright (c) 2008 - 2009, Intel Corporation. | 2 | * Copyright (c) 2008 - 2009, Intel Corporation. |
3 | * | 3 | * |
4 | * Author: Alek Du <alek.du@intel.com> | ||
5 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | 6 | * 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 as | 7 | * it under the terms of the GNU General Public License version 2 as |
6 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
@@ -21,7 +23,6 @@ | |||
21 | 23 | ||
22 | #define pr_fmt(fmt) "%s: " fmt, __func__ | 24 | #define pr_fmt(fmt) "%s: " fmt, __func__ |
23 | 25 | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
26 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
27 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
@@ -322,9 +323,4 @@ static int __init platform_pmic_gpio_init(void) | |||
322 | { | 323 | { |
323 | return platform_driver_register(&platform_pmic_gpio_driver); | 324 | return platform_driver_register(&platform_pmic_gpio_driver); |
324 | } | 325 | } |
325 | |||
326 | subsys_initcall(platform_pmic_gpio_init); | 326 | subsys_initcall(platform_pmic_gpio_init); |
327 | |||
328 | MODULE_AUTHOR("Alek Du <alek.du@intel.com>"); | ||
329 | MODULE_DESCRIPTION("Intel Moorestown PMIC GPIO driver"); | ||
330 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 32f0f014a067..9d19b9a62011 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c | |||
@@ -1161,7 +1161,7 @@ static int tsi721_rio_map_inb_mem(struct rio_mport *mport, dma_addr_t lstart, | |||
1161 | } else if (ibw_start < (ib_win->rstart + ib_win->size) && | 1161 | } else if (ibw_start < (ib_win->rstart + ib_win->size) && |
1162 | (ibw_start + ibw_size) > ib_win->rstart) { | 1162 | (ibw_start + ibw_size) > ib_win->rstart) { |
1163 | /* Return error if address translation involved */ | 1163 | /* Return error if address translation involved */ |
1164 | if (direct && ib_win->xlat) { | 1164 | if (!direct || ib_win->xlat) { |
1165 | ret = -EFAULT; | 1165 | ret = -EFAULT; |
1166 | break; | 1166 | break; |
1167 | } | 1167 | } |
diff --git a/drivers/rapidio/rio_cm.c b/drivers/rapidio/rio_cm.c index 3fa17ac8df54..cebc296463ad 100644 --- a/drivers/rapidio/rio_cm.c +++ b/drivers/rapidio/rio_cm.c | |||
@@ -2247,17 +2247,30 @@ static int rio_cm_shutdown(struct notifier_block *nb, unsigned long code, | |||
2247 | { | 2247 | { |
2248 | struct rio_channel *ch; | 2248 | struct rio_channel *ch; |
2249 | unsigned int i; | 2249 | unsigned int i; |
2250 | LIST_HEAD(list); | ||
2250 | 2251 | ||
2251 | riocm_debug(EXIT, "."); | 2252 | riocm_debug(EXIT, "."); |
2252 | 2253 | ||
2254 | /* | ||
2255 | * If there are any channels left in connected state send | ||
2256 | * close notification to the connection partner. | ||
2257 | * First build a list of channels that require a closing | ||
2258 | * notification because function riocm_send_close() should | ||
2259 | * be called outside of spinlock protected code. | ||
2260 | */ | ||
2253 | spin_lock_bh(&idr_lock); | 2261 | spin_lock_bh(&idr_lock); |
2254 | idr_for_each_entry(&ch_idr, ch, i) { | 2262 | idr_for_each_entry(&ch_idr, ch, i) { |
2255 | riocm_debug(EXIT, "close ch %d", ch->id); | 2263 | if (ch->state == RIO_CM_CONNECTED) { |
2256 | if (ch->state == RIO_CM_CONNECTED) | 2264 | riocm_debug(EXIT, "close ch %d", ch->id); |
2257 | riocm_send_close(ch); | 2265 | idr_remove(&ch_idr, ch->id); |
2266 | list_add(&ch->ch_node, &list); | ||
2267 | } | ||
2258 | } | 2268 | } |
2259 | spin_unlock_bh(&idr_lock); | 2269 | spin_unlock_bh(&idr_lock); |
2260 | 2270 | ||
2271 | list_for_each_entry(ch, &list, ch_node) | ||
2272 | riocm_send_close(ch); | ||
2273 | |||
2261 | return NOTIFY_DONE; | 2274 | return NOTIFY_DONE; |
2262 | } | 2275 | } |
2263 | 2276 | ||
diff --git a/drivers/regulator/max14577-regulator.c b/drivers/regulator/max14577-regulator.c index b2daa6641417..c9ff26199711 100644 --- a/drivers/regulator/max14577-regulator.c +++ b/drivers/regulator/max14577-regulator.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * max14577.c - Regulator driver for the Maxim 14577/77836 | 2 | * max14577.c - Regulator driver for the Maxim 14577/77836 |
3 | * | 3 | * |
4 | * Copyright (C) 2013,2014 Samsung Electronics | 4 | * Copyright (C) 2013,2014 Samsung Electronics |
5 | * Krzysztof Kozlowski <k.kozlowski@samsung.com> | 5 | * Krzysztof Kozlowski <krzk@kernel.org> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -331,7 +331,7 @@ static void __exit max14577_regulator_exit(void) | |||
331 | } | 331 | } |
332 | module_exit(max14577_regulator_exit); | 332 | module_exit(max14577_regulator_exit); |
333 | 333 | ||
334 | MODULE_AUTHOR("Krzysztof Kozlowski <k.kozlowski@samsung.com>"); | 334 | MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>"); |
335 | MODULE_DESCRIPTION("Maxim 14577/77836 regulator driver"); | 335 | MODULE_DESCRIPTION("Maxim 14577/77836 regulator driver"); |
336 | MODULE_LICENSE("GPL"); | 336 | MODULE_LICENSE("GPL"); |
337 | MODULE_ALIAS("platform:max14577-regulator"); | 337 | MODULE_ALIAS("platform:max14577-regulator"); |
diff --git a/drivers/regulator/max77693-regulator.c b/drivers/regulator/max77693-regulator.c index de730fd3f8a5..cfbb9512e486 100644 --- a/drivers/regulator/max77693-regulator.c +++ b/drivers/regulator/max77693-regulator.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2013-2015 Samsung Electronics | 4 | * Copyright (C) 2013-2015 Samsung Electronics |
5 | * Jonghwa Lee <jonghwa3.lee@samsung.com> | 5 | * Jonghwa Lee <jonghwa3.lee@samsung.com> |
6 | * Krzysztof Kozlowski <k.kozlowski.k@gmail.com> | 6 | * Krzysztof Kozlowski <krzk@kernel.org> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -314,5 +314,5 @@ module_exit(max77693_pmic_cleanup); | |||
314 | 314 | ||
315 | MODULE_DESCRIPTION("MAXIM 77693/77843 regulator driver"); | 315 | MODULE_DESCRIPTION("MAXIM 77693/77843 regulator driver"); |
316 | MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>"); | 316 | MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>"); |
317 | MODULE_AUTHOR("Krzysztof Kozlowski <k.kozlowski.k@gmail.com>"); | 317 | MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>"); |
318 | MODULE_LICENSE("GPL"); | 318 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index 5022fa8d10c6..8ed46a9a55c8 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c | |||
@@ -178,20 +178,21 @@ static const struct regulator_desc pma8084_hfsmps = { | |||
178 | static const struct regulator_desc pma8084_ftsmps = { | 178 | static const struct regulator_desc pma8084_ftsmps = { |
179 | .linear_ranges = (struct regulator_linear_range[]) { | 179 | .linear_ranges = (struct regulator_linear_range[]) { |
180 | REGULATOR_LINEAR_RANGE(350000, 0, 184, 5000), | 180 | REGULATOR_LINEAR_RANGE(350000, 0, 184, 5000), |
181 | REGULATOR_LINEAR_RANGE(700000, 185, 339, 10000), | 181 | REGULATOR_LINEAR_RANGE(1280000, 185, 261, 10000), |
182 | }, | 182 | }, |
183 | .n_linear_ranges = 2, | 183 | .n_linear_ranges = 2, |
184 | .n_voltages = 340, | 184 | .n_voltages = 262, |
185 | .ops = &rpm_smps_ldo_ops, | 185 | .ops = &rpm_smps_ldo_ops, |
186 | }; | 186 | }; |
187 | 187 | ||
188 | static const struct regulator_desc pma8084_pldo = { | 188 | static const struct regulator_desc pma8084_pldo = { |
189 | .linear_ranges = (struct regulator_linear_range[]) { | 189 | .linear_ranges = (struct regulator_linear_range[]) { |
190 | REGULATOR_LINEAR_RANGE(750000, 0, 30, 25000), | 190 | REGULATOR_LINEAR_RANGE( 750000, 0, 63, 12500), |
191 | REGULATOR_LINEAR_RANGE(1500000, 31, 99, 50000), | 191 | REGULATOR_LINEAR_RANGE(1550000, 64, 126, 25000), |
192 | REGULATOR_LINEAR_RANGE(3100000, 127, 163, 50000), | ||
192 | }, | 193 | }, |
193 | .n_linear_ranges = 2, | 194 | .n_linear_ranges = 3, |
194 | .n_voltages = 100, | 195 | .n_voltages = 164, |
195 | .ops = &rpm_smps_ldo_ops, | 196 | .ops = &rpm_smps_ldo_ops, |
196 | }; | 197 | }; |
197 | 198 | ||
@@ -221,29 +222,30 @@ static const struct regulator_desc pm8x41_hfsmps = { | |||
221 | static const struct regulator_desc pm8841_ftsmps = { | 222 | static const struct regulator_desc pm8841_ftsmps = { |
222 | .linear_ranges = (struct regulator_linear_range[]) { | 223 | .linear_ranges = (struct regulator_linear_range[]) { |
223 | REGULATOR_LINEAR_RANGE(350000, 0, 184, 5000), | 224 | REGULATOR_LINEAR_RANGE(350000, 0, 184, 5000), |
224 | REGULATOR_LINEAR_RANGE(700000, 185, 339, 10000), | 225 | REGULATOR_LINEAR_RANGE(1280000, 185, 261, 10000), |
225 | }, | 226 | }, |
226 | .n_linear_ranges = 2, | 227 | .n_linear_ranges = 2, |
227 | .n_voltages = 340, | 228 | .n_voltages = 262, |
228 | .ops = &rpm_smps_ldo_ops, | 229 | .ops = &rpm_smps_ldo_ops, |
229 | }; | 230 | }; |
230 | 231 | ||
231 | static const struct regulator_desc pm8941_boost = { | 232 | static const struct regulator_desc pm8941_boost = { |
232 | .linear_ranges = (struct regulator_linear_range[]) { | 233 | .linear_ranges = (struct regulator_linear_range[]) { |
233 | REGULATOR_LINEAR_RANGE(4000000, 0, 15, 100000), | 234 | REGULATOR_LINEAR_RANGE(4000000, 0, 30, 50000), |
234 | }, | 235 | }, |
235 | .n_linear_ranges = 1, | 236 | .n_linear_ranges = 1, |
236 | .n_voltages = 16, | 237 | .n_voltages = 31, |
237 | .ops = &rpm_smps_ldo_ops, | 238 | .ops = &rpm_smps_ldo_ops, |
238 | }; | 239 | }; |
239 | 240 | ||
240 | static const struct regulator_desc pm8941_pldo = { | 241 | static const struct regulator_desc pm8941_pldo = { |
241 | .linear_ranges = (struct regulator_linear_range[]) { | 242 | .linear_ranges = (struct regulator_linear_range[]) { |
242 | REGULATOR_LINEAR_RANGE( 750000, 0, 30, 25000), | 243 | REGULATOR_LINEAR_RANGE( 750000, 0, 63, 12500), |
243 | REGULATOR_LINEAR_RANGE(1500000, 31, 99, 50000), | 244 | REGULATOR_LINEAR_RANGE(1550000, 64, 126, 25000), |
245 | REGULATOR_LINEAR_RANGE(3100000, 127, 163, 50000), | ||
244 | }, | 246 | }, |
245 | .n_linear_ranges = 2, | 247 | .n_linear_ranges = 3, |
246 | .n_voltages = 100, | 248 | .n_voltages = 164, |
247 | .ops = &rpm_smps_ldo_ops, | 249 | .ops = &rpm_smps_ldo_ops, |
248 | }; | 250 | }; |
249 | 251 | ||
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index bf40063de202..6d4b68c483f3 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h | |||
@@ -999,6 +999,7 @@ struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *, | |||
999 | __u16, __u16, | 999 | __u16, __u16, |
1000 | enum qeth_prot_versions); | 1000 | enum qeth_prot_versions); |
1001 | int qeth_set_features(struct net_device *, netdev_features_t); | 1001 | int qeth_set_features(struct net_device *, netdev_features_t); |
1002 | int qeth_recover_features(struct net_device *); | ||
1002 | netdev_features_t qeth_fix_features(struct net_device *, netdev_features_t); | 1003 | netdev_features_t qeth_fix_features(struct net_device *, netdev_features_t); |
1003 | 1004 | ||
1004 | /* exports for OSN */ | 1005 | /* exports for OSN */ |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 7dba6c8537a1..20cf29613043 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
@@ -3619,7 +3619,8 @@ static void qeth_qdio_cq_handler(struct qeth_card *card, | |||
3619 | int e; | 3619 | int e; |
3620 | 3620 | ||
3621 | e = 0; | 3621 | e = 0; |
3622 | while (buffer->element[e].addr) { | 3622 | while ((e < QDIO_MAX_ELEMENTS_PER_BUFFER) && |
3623 | buffer->element[e].addr) { | ||
3623 | unsigned long phys_aob_addr; | 3624 | unsigned long phys_aob_addr; |
3624 | 3625 | ||
3625 | phys_aob_addr = (unsigned long) buffer->element[e].addr; | 3626 | phys_aob_addr = (unsigned long) buffer->element[e].addr; |
@@ -6131,6 +6132,35 @@ static int qeth_set_ipa_tso(struct qeth_card *card, int on) | |||
6131 | return rc; | 6132 | return rc; |
6132 | } | 6133 | } |
6133 | 6134 | ||
6135 | /* try to restore device features on a device after recovery */ | ||
6136 | int qeth_recover_features(struct net_device *dev) | ||
6137 | { | ||
6138 | struct qeth_card *card = dev->ml_priv; | ||
6139 | netdev_features_t recover = dev->features; | ||
6140 | |||
6141 | if (recover & NETIF_F_IP_CSUM) { | ||
6142 | if (qeth_set_ipa_csum(card, 1, IPA_OUTBOUND_CHECKSUM)) | ||
6143 | recover ^= NETIF_F_IP_CSUM; | ||
6144 | } | ||
6145 | if (recover & NETIF_F_RXCSUM) { | ||
6146 | if (qeth_set_ipa_csum(card, 1, IPA_INBOUND_CHECKSUM)) | ||
6147 | recover ^= NETIF_F_RXCSUM; | ||
6148 | } | ||
6149 | if (recover & NETIF_F_TSO) { | ||
6150 | if (qeth_set_ipa_tso(card, 1)) | ||
6151 | recover ^= NETIF_F_TSO; | ||
6152 | } | ||
6153 | |||
6154 | if (recover == dev->features) | ||
6155 | return 0; | ||
6156 | |||
6157 | dev_warn(&card->gdev->dev, | ||
6158 | "Device recovery failed to restore all offload features\n"); | ||
6159 | dev->features = recover; | ||
6160 | return -EIO; | ||
6161 | } | ||
6162 | EXPORT_SYMBOL_GPL(qeth_recover_features); | ||
6163 | |||
6134 | int qeth_set_features(struct net_device *dev, netdev_features_t features) | 6164 | int qeth_set_features(struct net_device *dev, netdev_features_t features) |
6135 | { | 6165 | { |
6136 | struct qeth_card *card = dev->ml_priv; | 6166 | struct qeth_card *card = dev->ml_priv; |
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 7bc20c5188bc..bb27058fa9f0 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
@@ -1124,14 +1124,11 @@ static int qeth_l2_setup_netdev(struct qeth_card *card) | |||
1124 | card->dev->hw_features |= NETIF_F_RXCSUM; | 1124 | card->dev->hw_features |= NETIF_F_RXCSUM; |
1125 | card->dev->vlan_features |= NETIF_F_RXCSUM; | 1125 | card->dev->vlan_features |= NETIF_F_RXCSUM; |
1126 | } | 1126 | } |
1127 | /* Turn on SG per default */ | ||
1128 | card->dev->features |= NETIF_F_SG; | ||
1129 | } | 1127 | } |
1130 | card->info.broadcast_capable = 1; | 1128 | card->info.broadcast_capable = 1; |
1131 | qeth_l2_request_initial_mac(card); | 1129 | qeth_l2_request_initial_mac(card); |
1132 | card->dev->gso_max_size = (QETH_MAX_BUFFER_ELEMENTS(card) - 1) * | 1130 | card->dev->gso_max_size = (QETH_MAX_BUFFER_ELEMENTS(card) - 1) * |
1133 | PAGE_SIZE; | 1131 | PAGE_SIZE; |
1134 | card->dev->gso_max_segs = (QETH_MAX_BUFFER_ELEMENTS(card) - 1); | ||
1135 | SET_NETDEV_DEV(card->dev, &card->gdev->dev); | 1132 | SET_NETDEV_DEV(card->dev, &card->gdev->dev); |
1136 | netif_napi_add(card->dev, &card->napi, qeth_l2_poll, QETH_NAPI_WEIGHT); | 1133 | netif_napi_add(card->dev, &card->napi, qeth_l2_poll, QETH_NAPI_WEIGHT); |
1137 | netif_carrier_off(card->dev); | 1134 | netif_carrier_off(card->dev); |
@@ -1246,6 +1243,9 @@ contin: | |||
1246 | } | 1243 | } |
1247 | /* this also sets saved unicast addresses */ | 1244 | /* this also sets saved unicast addresses */ |
1248 | qeth_l2_set_rx_mode(card->dev); | 1245 | qeth_l2_set_rx_mode(card->dev); |
1246 | rtnl_lock(); | ||
1247 | qeth_recover_features(card->dev); | ||
1248 | rtnl_unlock(); | ||
1249 | } | 1249 | } |
1250 | /* let user_space know that device is online */ | 1250 | /* let user_space know that device is online */ |
1251 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); | 1251 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); |
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 72934666fedf..272d9e7419be 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
@@ -257,6 +257,11 @@ int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr) | |||
257 | if (addr->in_progress) | 257 | if (addr->in_progress) |
258 | return -EINPROGRESS; | 258 | return -EINPROGRESS; |
259 | 259 | ||
260 | if (!qeth_card_hw_is_reachable(card)) { | ||
261 | addr->disp_flag = QETH_DISP_ADDR_DELETE; | ||
262 | return 0; | ||
263 | } | ||
264 | |||
260 | rc = qeth_l3_deregister_addr_entry(card, addr); | 265 | rc = qeth_l3_deregister_addr_entry(card, addr); |
261 | 266 | ||
262 | hash_del(&addr->hnode); | 267 | hash_del(&addr->hnode); |
@@ -296,6 +301,11 @@ int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr) | |||
296 | hash_add(card->ip_htable, &addr->hnode, | 301 | hash_add(card->ip_htable, &addr->hnode, |
297 | qeth_l3_ipaddr_hash(addr)); | 302 | qeth_l3_ipaddr_hash(addr)); |
298 | 303 | ||
304 | if (!qeth_card_hw_is_reachable(card)) { | ||
305 | addr->disp_flag = QETH_DISP_ADDR_ADD; | ||
306 | return 0; | ||
307 | } | ||
308 | |||
299 | /* qeth_l3_register_addr_entry can go to sleep | 309 | /* qeth_l3_register_addr_entry can go to sleep |
300 | * if we add a IPV4 addr. It is caused by the reason | 310 | * if we add a IPV4 addr. It is caused by the reason |
301 | * that SETIP ipa cmd starts ARP staff for IPV4 addr. | 311 | * that SETIP ipa cmd starts ARP staff for IPV4 addr. |
@@ -390,12 +400,16 @@ static void qeth_l3_recover_ip(struct qeth_card *card) | |||
390 | int i; | 400 | int i; |
391 | int rc; | 401 | int rc; |
392 | 402 | ||
393 | QETH_CARD_TEXT(card, 4, "recoverip"); | 403 | QETH_CARD_TEXT(card, 4, "recovrip"); |
394 | 404 | ||
395 | spin_lock_bh(&card->ip_lock); | 405 | spin_lock_bh(&card->ip_lock); |
396 | 406 | ||
397 | hash_for_each_safe(card->ip_htable, i, tmp, addr, hnode) { | 407 | hash_for_each_safe(card->ip_htable, i, tmp, addr, hnode) { |
398 | if (addr->disp_flag == QETH_DISP_ADDR_ADD) { | 408 | if (addr->disp_flag == QETH_DISP_ADDR_DELETE) { |
409 | qeth_l3_deregister_addr_entry(card, addr); | ||
410 | hash_del(&addr->hnode); | ||
411 | kfree(addr); | ||
412 | } else if (addr->disp_flag == QETH_DISP_ADDR_ADD) { | ||
399 | if (addr->proto == QETH_PROT_IPV4) { | 413 | if (addr->proto == QETH_PROT_IPV4) { |
400 | addr->in_progress = 1; | 414 | addr->in_progress = 1; |
401 | spin_unlock_bh(&card->ip_lock); | 415 | spin_unlock_bh(&card->ip_lock); |
@@ -407,10 +421,8 @@ static void qeth_l3_recover_ip(struct qeth_card *card) | |||
407 | 421 | ||
408 | if (!rc) { | 422 | if (!rc) { |
409 | addr->disp_flag = QETH_DISP_ADDR_DO_NOTHING; | 423 | addr->disp_flag = QETH_DISP_ADDR_DO_NOTHING; |
410 | if (addr->ref_counter < 1) { | 424 | if (addr->ref_counter < 1) |
411 | qeth_l3_delete_ip(card, addr); | 425 | qeth_l3_delete_ip(card, addr); |
412 | kfree(addr); | ||
413 | } | ||
414 | } else { | 426 | } else { |
415 | hash_del(&addr->hnode); | 427 | hash_del(&addr->hnode); |
416 | kfree(addr); | 428 | kfree(addr); |
@@ -689,7 +701,7 @@ int qeth_l3_add_vipa(struct qeth_card *card, enum qeth_prot_versions proto, | |||
689 | 701 | ||
690 | spin_lock_bh(&card->ip_lock); | 702 | spin_lock_bh(&card->ip_lock); |
691 | 703 | ||
692 | if (!qeth_l3_ip_from_hash(card, ipaddr)) | 704 | if (qeth_l3_ip_from_hash(card, ipaddr)) |
693 | rc = -EEXIST; | 705 | rc = -EEXIST; |
694 | else | 706 | else |
695 | qeth_l3_add_ip(card, ipaddr); | 707 | qeth_l3_add_ip(card, ipaddr); |
@@ -757,7 +769,7 @@ int qeth_l3_add_rxip(struct qeth_card *card, enum qeth_prot_versions proto, | |||
757 | 769 | ||
758 | spin_lock_bh(&card->ip_lock); | 770 | spin_lock_bh(&card->ip_lock); |
759 | 771 | ||
760 | if (!qeth_l3_ip_from_hash(card, ipaddr)) | 772 | if (qeth_l3_ip_from_hash(card, ipaddr)) |
761 | rc = -EEXIST; | 773 | rc = -EEXIST; |
762 | else | 774 | else |
763 | qeth_l3_add_ip(card, ipaddr); | 775 | qeth_l3_add_ip(card, ipaddr); |
@@ -3108,7 +3120,6 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) | |||
3108 | card->dev->vlan_features = NETIF_F_SG | | 3120 | card->dev->vlan_features = NETIF_F_SG | |
3109 | NETIF_F_RXCSUM | NETIF_F_IP_CSUM | | 3121 | NETIF_F_RXCSUM | NETIF_F_IP_CSUM | |
3110 | NETIF_F_TSO; | 3122 | NETIF_F_TSO; |
3111 | card->dev->features = NETIF_F_SG; | ||
3112 | } | 3123 | } |
3113 | } | 3124 | } |
3114 | } else if (card->info.type == QETH_CARD_TYPE_IQD) { | 3125 | } else if (card->info.type == QETH_CARD_TYPE_IQD) { |
@@ -3136,7 +3147,6 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) | |||
3136 | netif_keep_dst(card->dev); | 3147 | netif_keep_dst(card->dev); |
3137 | card->dev->gso_max_size = (QETH_MAX_BUFFER_ELEMENTS(card) - 1) * | 3148 | card->dev->gso_max_size = (QETH_MAX_BUFFER_ELEMENTS(card) - 1) * |
3138 | PAGE_SIZE; | 3149 | PAGE_SIZE; |
3139 | card->dev->gso_max_segs = (QETH_MAX_BUFFER_ELEMENTS(card) - 1); | ||
3140 | 3150 | ||
3141 | SET_NETDEV_DEV(card->dev, &card->gdev->dev); | 3151 | SET_NETDEV_DEV(card->dev, &card->gdev->dev); |
3142 | netif_napi_add(card->dev, &card->napi, qeth_l3_poll, QETH_NAPI_WEIGHT); | 3152 | netif_napi_add(card->dev, &card->napi, qeth_l3_poll, QETH_NAPI_WEIGHT); |
@@ -3269,6 +3279,7 @@ contin: | |||
3269 | else | 3279 | else |
3270 | dev_open(card->dev); | 3280 | dev_open(card->dev); |
3271 | qeth_l3_set_multicast_list(card->dev); | 3281 | qeth_l3_set_multicast_list(card->dev); |
3282 | qeth_recover_features(card->dev); | ||
3272 | rtnl_unlock(); | 3283 | rtnl_unlock(); |
3273 | } | 3284 | } |
3274 | qeth_trace_features(card); | 3285 | qeth_trace_features(card); |
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index 65645b11fc19..0e00a5ce0f00 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c | |||
@@ -297,7 +297,9 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev, | |||
297 | addr->u.a6.pfxlen = 0; | 297 | addr->u.a6.pfxlen = 0; |
298 | addr->type = QETH_IP_TYPE_NORMAL; | 298 | addr->type = QETH_IP_TYPE_NORMAL; |
299 | 299 | ||
300 | spin_lock_bh(&card->ip_lock); | ||
300 | qeth_l3_delete_ip(card, addr); | 301 | qeth_l3_delete_ip(card, addr); |
302 | spin_unlock_bh(&card->ip_lock); | ||
301 | kfree(addr); | 303 | kfree(addr); |
302 | } | 304 | } |
303 | 305 | ||
@@ -329,7 +331,10 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev, | |||
329 | addr->type = QETH_IP_TYPE_NORMAL; | 331 | addr->type = QETH_IP_TYPE_NORMAL; |
330 | } else | 332 | } else |
331 | return -ENOMEM; | 333 | return -ENOMEM; |
334 | |||
335 | spin_lock_bh(&card->ip_lock); | ||
332 | qeth_l3_add_ip(card, addr); | 336 | qeth_l3_add_ip(card, addr); |
337 | spin_unlock_bh(&card->ip_lock); | ||
333 | kfree(addr); | 338 | kfree(addr); |
334 | 339 | ||
335 | return count; | 340 | return count; |
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 83458f7a2824..6dc96c8dfe75 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c | |||
@@ -361,8 +361,9 @@ static const char * const snstext[] = { | |||
361 | 361 | ||
362 | /* Get sense key string or NULL if not available */ | 362 | /* Get sense key string or NULL if not available */ |
363 | const char * | 363 | const char * |
364 | scsi_sense_key_string(unsigned char key) { | 364 | scsi_sense_key_string(unsigned char key) |
365 | if (key <= 0xE) | 365 | { |
366 | if (key < ARRAY_SIZE(snstext)) | ||
366 | return snstext[key]; | 367 | return snstext[key]; |
367 | return NULL; | 368 | return NULL; |
368 | } | 369 | } |
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index eaccd651ccda..246456925335 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c | |||
@@ -246,6 +246,10 @@ static struct { | |||
246 | {"IBM", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, | 246 | {"IBM", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, |
247 | {"SUN", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, | 247 | {"SUN", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, |
248 | {"DELL", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, | 248 | {"DELL", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, |
249 | {"STK", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, | ||
250 | {"NETAPP", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, | ||
251 | {"LSI", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, | ||
252 | {"ENGENIO", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, | ||
249 | {"SMSC", "USB 2 HS-CF", NULL, BLIST_SPARSELUN | BLIST_INQUIRY_36}, | 253 | {"SMSC", "USB 2 HS-CF", NULL, BLIST_SPARSELUN | BLIST_INQUIRY_36}, |
250 | {"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN}, | 254 | {"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN}, |
251 | {"SONY", "TSL", NULL, BLIST_FORCELUN}, /* DDS3 & DDS4 autoloaders */ | 255 | {"SONY", "TSL", NULL, BLIST_FORCELUN}, /* DDS3 & DDS4 autoloaders */ |
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 3f0ff072184b..60b651bfaa01 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c | |||
@@ -341,22 +341,6 @@ static int do_sas_phy_delete(struct device *dev, void *data) | |||
341 | } | 341 | } |
342 | 342 | ||
343 | /** | 343 | /** |
344 | * is_sas_attached - check if device is SAS attached | ||
345 | * @sdev: scsi device to check | ||
346 | * | ||
347 | * returns true if the device is SAS attached | ||
348 | */ | ||
349 | int is_sas_attached(struct scsi_device *sdev) | ||
350 | { | ||
351 | struct Scsi_Host *shost = sdev->host; | ||
352 | |||
353 | return shost->transportt->host_attrs.ac.class == | ||
354 | &sas_host_class.class; | ||
355 | } | ||
356 | EXPORT_SYMBOL(is_sas_attached); | ||
357 | |||
358 | |||
359 | /** | ||
360 | * sas_remove_children - tear down a devices SAS data structures | 344 | * sas_remove_children - tear down a devices SAS data structures |
361 | * @dev: device belonging to the sas object | 345 | * @dev: device belonging to the sas object |
362 | * | 346 | * |
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 0e8601aa877a..8c9a35c91705 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c | |||
@@ -587,7 +587,7 @@ static void ses_match_to_enclosure(struct enclosure_device *edev, | |||
587 | 587 | ||
588 | ses_enclosure_data_process(edev, to_scsi_device(edev->edev.parent), 0); | 588 | ses_enclosure_data_process(edev, to_scsi_device(edev->edev.parent), 0); |
589 | 589 | ||
590 | if (is_sas_attached(sdev)) | 590 | if (scsi_is_sas_rphy(&sdev->sdev_gendev)) |
591 | efd.addr = sas_get_address(sdev); | 591 | efd.addr = sas_get_address(sdev); |
592 | 592 | ||
593 | if (efd.addr) { | 593 | if (efd.addr) { |
diff --git a/drivers/scsi/wd719x.c b/drivers/scsi/wd719x.c index e3da1a2fdb66..2a9da2e0ea6b 100644 --- a/drivers/scsi/wd719x.c +++ b/drivers/scsi/wd719x.c | |||
@@ -962,7 +962,7 @@ static void wd719x_pci_remove(struct pci_dev *pdev) | |||
962 | scsi_host_put(sh); | 962 | scsi_host_put(sh); |
963 | } | 963 | } |
964 | 964 | ||
965 | static DEFINE_PCI_DEVICE_TABLE(wd719x_pci_table) = { | 965 | static const struct pci_device_id wd719x_pci_table[] = { |
966 | { PCI_DEVICE(PCI_VENDOR_ID_WD, 0x3296) }, | 966 | { PCI_DEVICE(PCI_VENDOR_ID_WD, 0x3296) }, |
967 | {} | 967 | {} |
968 | }; | 968 | }; |
diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c index 823cbc92d1e7..7a37090dabbe 100644 --- a/drivers/spi/spi-img-spfi.c +++ b/drivers/spi/spi-img-spfi.c | |||
@@ -720,8 +720,6 @@ static int img_spfi_remove(struct platform_device *pdev) | |||
720 | clk_disable_unprepare(spfi->sys_clk); | 720 | clk_disable_unprepare(spfi->sys_clk); |
721 | } | 721 | } |
722 | 722 | ||
723 | spi_master_put(master); | ||
724 | |||
725 | return 0; | 723 | return 0; |
726 | } | 724 | } |
727 | 725 | ||
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 0be89e052428..899d7a8f0889 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c | |||
@@ -685,7 +685,6 @@ static int mtk_spi_remove(struct platform_device *pdev) | |||
685 | pm_runtime_disable(&pdev->dev); | 685 | pm_runtime_disable(&pdev->dev); |
686 | 686 | ||
687 | mtk_spi_reset(mdata); | 687 | mtk_spi_reset(mdata); |
688 | spi_master_put(master); | ||
689 | 688 | ||
690 | return 0; | 689 | return 0; |
691 | } | 690 | } |
diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index f3df522db93b..58d2d48e16a5 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c | |||
@@ -214,6 +214,7 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, | |||
214 | return PTR_ERR(ssp->clk); | 214 | return PTR_ERR(ssp->clk); |
215 | 215 | ||
216 | memset(&pi, 0, sizeof(pi)); | 216 | memset(&pi, 0, sizeof(pi)); |
217 | pi.fwnode = dev->dev.fwnode; | ||
217 | pi.parent = &dev->dev; | 218 | pi.parent = &dev->dev; |
218 | pi.name = "pxa2xx-spi"; | 219 | pi.name = "pxa2xx-spi"; |
219 | pi.id = ssp->port_id; | 220 | pi.id = ssp->port_id; |
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index c338ef1136f6..7f1555621f8e 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c | |||
@@ -1030,7 +1030,6 @@ static int spi_qup_remove(struct platform_device *pdev) | |||
1030 | 1030 | ||
1031 | pm_runtime_put_noidle(&pdev->dev); | 1031 | pm_runtime_put_noidle(&pdev->dev); |
1032 | pm_runtime_disable(&pdev->dev); | 1032 | pm_runtime_disable(&pdev->dev); |
1033 | spi_master_put(master); | ||
1034 | 1033 | ||
1035 | return 0; | 1034 | return 0; |
1036 | } | 1035 | } |
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 0f83ad1d5a58..1de3a772eb7d 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c | |||
@@ -262,6 +262,9 @@ static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p, | |||
262 | 262 | ||
263 | for (k = 0; k < ARRAY_SIZE(sh_msiof_spi_div_table); k++) { | 263 | for (k = 0; k < ARRAY_SIZE(sh_msiof_spi_div_table); k++) { |
264 | brps = DIV_ROUND_UP(div, sh_msiof_spi_div_table[k].div); | 264 | brps = DIV_ROUND_UP(div, sh_msiof_spi_div_table[k].div); |
265 | /* SCR_BRDV_DIV_1 is valid only if BRPS is x 1/1 or x 1/2 */ | ||
266 | if (sh_msiof_spi_div_table[k].div == 1 && brps > 2) | ||
267 | continue; | ||
265 | if (brps <= 32) /* max of brdv is 32 */ | 268 | if (brps <= 32) /* max of brdv is 32 */ |
266 | break; | 269 | break; |
267 | } | 270 | } |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 51ad42fad567..200ca228d885 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -960,7 +960,7 @@ static int spi_transfer_one_message(struct spi_master *master, | |||
960 | struct spi_transfer *xfer; | 960 | struct spi_transfer *xfer; |
961 | bool keep_cs = false; | 961 | bool keep_cs = false; |
962 | int ret = 0; | 962 | int ret = 0; |
963 | unsigned long ms = 1; | 963 | unsigned long long ms = 1; |
964 | struct spi_statistics *statm = &master->statistics; | 964 | struct spi_statistics *statm = &master->statistics; |
965 | struct spi_statistics *stats = &msg->spi->statistics; | 965 | struct spi_statistics *stats = &msg->spi->statistics; |
966 | 966 | ||
@@ -991,9 +991,13 @@ static int spi_transfer_one_message(struct spi_master *master, | |||
991 | 991 | ||
992 | if (ret > 0) { | 992 | if (ret > 0) { |
993 | ret = 0; | 993 | ret = 0; |
994 | ms = xfer->len * 8 * 1000 / xfer->speed_hz; | 994 | ms = 8LL * 1000LL * xfer->len; |
995 | do_div(ms, xfer->speed_hz); | ||
995 | ms += ms + 100; /* some tolerance */ | 996 | ms += ms + 100; /* some tolerance */ |
996 | 997 | ||
998 | if (ms > UINT_MAX) | ||
999 | ms = UINT_MAX; | ||
1000 | |||
997 | ms = wait_for_completion_timeout(&master->xfer_completion, | 1001 | ms = wait_for_completion_timeout(&master->xfer_completion, |
998 | msecs_to_jiffies(ms)); | 1002 | msecs_to_jiffies(ms)); |
999 | } | 1003 | } |
@@ -1159,6 +1163,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread) | |||
1159 | if (ret < 0) { | 1163 | if (ret < 0) { |
1160 | dev_err(&master->dev, "Failed to power device: %d\n", | 1164 | dev_err(&master->dev, "Failed to power device: %d\n", |
1161 | ret); | 1165 | ret); |
1166 | mutex_unlock(&master->io_mutex); | ||
1162 | return; | 1167 | return; |
1163 | } | 1168 | } |
1164 | } | 1169 | } |
@@ -1174,6 +1179,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread) | |||
1174 | 1179 | ||
1175 | if (master->auto_runtime_pm) | 1180 | if (master->auto_runtime_pm) |
1176 | pm_runtime_put(master->dev.parent); | 1181 | pm_runtime_put(master->dev.parent); |
1182 | mutex_unlock(&master->io_mutex); | ||
1177 | return; | 1183 | return; |
1178 | } | 1184 | } |
1179 | } | 1185 | } |
diff --git a/drivers/staging/comedi/drivers/adv_pci1760.c b/drivers/staging/comedi/drivers/adv_pci1760.c index d7dd1e55e347..9f525ff7290c 100644 --- a/drivers/staging/comedi/drivers/adv_pci1760.c +++ b/drivers/staging/comedi/drivers/adv_pci1760.c | |||
@@ -196,6 +196,7 @@ static int pci1760_pwm_ns_to_div(unsigned int flags, unsigned int ns) | |||
196 | break; | 196 | break; |
197 | case CMDF_ROUND_DOWN: | 197 | case CMDF_ROUND_DOWN: |
198 | divisor = ns / PCI1760_PWM_TIMEBASE; | 198 | divisor = ns / PCI1760_PWM_TIMEBASE; |
199 | break; | ||
199 | default: | 200 | default: |
200 | return -EINVAL; | 201 | return -EINVAL; |
201 | } | 202 | } |
diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 4ab186669f0c..ec5b9a23494d 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c | |||
@@ -56,11 +56,6 @@ | |||
56 | 56 | ||
57 | #define N_CHANS 8 | 57 | #define N_CHANS 8 |
58 | 58 | ||
59 | enum waveform_state_bits { | ||
60 | WAVEFORM_AI_RUNNING, | ||
61 | WAVEFORM_AO_RUNNING | ||
62 | }; | ||
63 | |||
64 | /* Data unique to this driver */ | 59 | /* Data unique to this driver */ |
65 | struct waveform_private { | 60 | struct waveform_private { |
66 | struct timer_list ai_timer; /* timer for AI commands */ | 61 | struct timer_list ai_timer; /* timer for AI commands */ |
@@ -68,7 +63,6 @@ struct waveform_private { | |||
68 | unsigned int wf_amplitude; /* waveform amplitude in microvolts */ | 63 | unsigned int wf_amplitude; /* waveform amplitude in microvolts */ |
69 | unsigned int wf_period; /* waveform period in microseconds */ | 64 | unsigned int wf_period; /* waveform period in microseconds */ |
70 | unsigned int wf_current; /* current time in waveform period */ | 65 | unsigned int wf_current; /* current time in waveform period */ |
71 | unsigned long state_bits; | ||
72 | unsigned int ai_scan_period; /* AI scan period in usec */ | 66 | unsigned int ai_scan_period; /* AI scan period in usec */ |
73 | unsigned int ai_convert_period; /* AI conversion period in usec */ | 67 | unsigned int ai_convert_period; /* AI conversion period in usec */ |
74 | struct timer_list ao_timer; /* timer for AO commands */ | 68 | struct timer_list ao_timer; /* timer for AO commands */ |
@@ -191,10 +185,6 @@ static void waveform_ai_timer(unsigned long arg) | |||
191 | unsigned int nsamples; | 185 | unsigned int nsamples; |
192 | unsigned int time_increment; | 186 | unsigned int time_increment; |
193 | 187 | ||
194 | /* check command is still active */ | ||
195 | if (!test_bit(WAVEFORM_AI_RUNNING, &devpriv->state_bits)) | ||
196 | return; | ||
197 | |||
198 | now = ktime_to_us(ktime_get()); | 188 | now = ktime_to_us(ktime_get()); |
199 | nsamples = comedi_nsamples_left(s, UINT_MAX); | 189 | nsamples = comedi_nsamples_left(s, UINT_MAX); |
200 | 190 | ||
@@ -386,11 +376,6 @@ static int waveform_ai_cmd(struct comedi_device *dev, | |||
386 | */ | 376 | */ |
387 | devpriv->ai_timer.expires = | 377 | devpriv->ai_timer.expires = |
388 | jiffies + usecs_to_jiffies(devpriv->ai_convert_period) + 1; | 378 | jiffies + usecs_to_jiffies(devpriv->ai_convert_period) + 1; |
389 | |||
390 | /* mark command as active */ | ||
391 | smp_mb__before_atomic(); | ||
392 | set_bit(WAVEFORM_AI_RUNNING, &devpriv->state_bits); | ||
393 | smp_mb__after_atomic(); | ||
394 | add_timer(&devpriv->ai_timer); | 379 | add_timer(&devpriv->ai_timer); |
395 | return 0; | 380 | return 0; |
396 | } | 381 | } |
@@ -400,11 +385,12 @@ static int waveform_ai_cancel(struct comedi_device *dev, | |||
400 | { | 385 | { |
401 | struct waveform_private *devpriv = dev->private; | 386 | struct waveform_private *devpriv = dev->private; |
402 | 387 | ||
403 | /* mark command as no longer active */ | 388 | if (in_softirq()) { |
404 | clear_bit(WAVEFORM_AI_RUNNING, &devpriv->state_bits); | 389 | /* Assume we were called from the timer routine itself. */ |
405 | smp_mb__after_atomic(); | 390 | del_timer(&devpriv->ai_timer); |
406 | /* cannot call del_timer_sync() as may be called from timer routine */ | 391 | } else { |
407 | del_timer(&devpriv->ai_timer); | 392 | del_timer_sync(&devpriv->ai_timer); |
393 | } | ||
408 | return 0; | 394 | return 0; |
409 | } | 395 | } |
410 | 396 | ||
@@ -436,10 +422,6 @@ static void waveform_ao_timer(unsigned long arg) | |||
436 | u64 scans_since; | 422 | u64 scans_since; |
437 | unsigned int scans_avail = 0; | 423 | unsigned int scans_avail = 0; |
438 | 424 | ||
439 | /* check command is still active */ | ||
440 | if (!test_bit(WAVEFORM_AO_RUNNING, &devpriv->state_bits)) | ||
441 | return; | ||
442 | |||
443 | /* determine number of scan periods since last time */ | 425 | /* determine number of scan periods since last time */ |
444 | now = ktime_to_us(ktime_get()); | 426 | now = ktime_to_us(ktime_get()); |
445 | scans_since = now - devpriv->ao_last_scan_time; | 427 | scans_since = now - devpriv->ao_last_scan_time; |
@@ -518,11 +500,6 @@ static int waveform_ao_inttrig_start(struct comedi_device *dev, | |||
518 | devpriv->ao_last_scan_time = ktime_to_us(ktime_get()); | 500 | devpriv->ao_last_scan_time = ktime_to_us(ktime_get()); |
519 | devpriv->ao_timer.expires = | 501 | devpriv->ao_timer.expires = |
520 | jiffies + usecs_to_jiffies(devpriv->ao_scan_period); | 502 | jiffies + usecs_to_jiffies(devpriv->ao_scan_period); |
521 | |||
522 | /* mark command as active */ | ||
523 | smp_mb__before_atomic(); | ||
524 | set_bit(WAVEFORM_AO_RUNNING, &devpriv->state_bits); | ||
525 | smp_mb__after_atomic(); | ||
526 | add_timer(&devpriv->ao_timer); | 503 | add_timer(&devpriv->ao_timer); |
527 | 504 | ||
528 | return 1; | 505 | return 1; |
@@ -608,11 +585,12 @@ static int waveform_ao_cancel(struct comedi_device *dev, | |||
608 | struct waveform_private *devpriv = dev->private; | 585 | struct waveform_private *devpriv = dev->private; |
609 | 586 | ||
610 | s->async->inttrig = NULL; | 587 | s->async->inttrig = NULL; |
611 | /* mark command as no longer active */ | 588 | if (in_softirq()) { |
612 | clear_bit(WAVEFORM_AO_RUNNING, &devpriv->state_bits); | 589 | /* Assume we were called from the timer routine itself. */ |
613 | smp_mb__after_atomic(); | 590 | del_timer(&devpriv->ao_timer); |
614 | /* cannot call del_timer_sync() as may be called from timer routine */ | 591 | } else { |
615 | del_timer(&devpriv->ao_timer); | 592 | del_timer_sync(&devpriv->ao_timer); |
593 | } | ||
616 | return 0; | 594 | return 0; |
617 | } | 595 | } |
618 | 596 | ||
diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 65daef0c00d5..0f4eb954aa80 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c | |||
@@ -634,7 +634,7 @@ static const void *daqboard2000_find_boardinfo(struct comedi_device *dev, | |||
634 | const struct daq200_boardtype *board; | 634 | const struct daq200_boardtype *board; |
635 | int i; | 635 | int i; |
636 | 636 | ||
637 | if (pcidev->subsystem_device != PCI_VENDOR_ID_IOTECH) | 637 | if (pcidev->subsystem_vendor != PCI_VENDOR_ID_IOTECH) |
638 | return NULL; | 638 | return NULL; |
639 | 639 | ||
640 | for (i = 0; i < ARRAY_SIZE(boardtypes); i++) { | 640 | for (i = 0; i < ARRAY_SIZE(boardtypes); i++) { |
diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index 904f637797b6..8bbd93814340 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c | |||
@@ -588,8 +588,8 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
588 | s = &dev->subdevices[0]; | 588 | s = &dev->subdevices[0]; |
589 | s->type = COMEDI_SUBD_AI; | 589 | s->type = COMEDI_SUBD_AI; |
590 | s->subdev_flags = SDF_READABLE | | 590 | s->subdev_flags = SDF_READABLE | |
591 | (it->options[2] == 1) ? SDF_DIFF : | 591 | ((it->options[2] == 1) ? SDF_DIFF : |
592 | (it->options[2] == 2) ? SDF_COMMON : SDF_GROUND; | 592 | (it->options[2] == 2) ? SDF_COMMON : SDF_GROUND); |
593 | s->n_chan = (it->options[2] == 1) ? 8 : 16; | 593 | s->n_chan = (it->options[2] == 1) ? 8 : 16; |
594 | s->maxdata = 0x0fff; | 594 | s->maxdata = 0x0fff; |
595 | s->range_table = board->is_pgh ? &dt2811_pgh_ai_ranges | 595 | s->range_table = board->is_pgh ? &dt2811_pgh_ai_ranges |
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 8dabb19519a5..0f97d7b611d7 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c | |||
@@ -2772,7 +2772,15 @@ static int ni_ao_inttrig(struct comedi_device *dev, | |||
2772 | int i; | 2772 | int i; |
2773 | static const int timeout = 1000; | 2773 | static const int timeout = 1000; |
2774 | 2774 | ||
2775 | if (trig_num != cmd->start_arg) | 2775 | /* |
2776 | * Require trig_num == cmd->start_arg when cmd->start_src == TRIG_INT. | ||
2777 | * For backwards compatibility, also allow trig_num == 0 when | ||
2778 | * cmd->start_src != TRIG_INT (i.e. when cmd->start_src == TRIG_EXT); | ||
2779 | * in that case, the internal trigger is being used as a pre-trigger | ||
2780 | * before the external trigger. | ||
2781 | */ | ||
2782 | if (!(trig_num == cmd->start_arg || | ||
2783 | (trig_num == 0 && cmd->start_src != TRIG_INT))) | ||
2776 | return -EINVAL; | 2784 | return -EINVAL; |
2777 | 2785 | ||
2778 | /* | 2786 | /* |
@@ -5480,7 +5488,7 @@ static int ni_E_init(struct comedi_device *dev, | |||
5480 | s->maxdata = (devpriv->is_m_series) ? 0xffffffff | 5488 | s->maxdata = (devpriv->is_m_series) ? 0xffffffff |
5481 | : 0x00ffffff; | 5489 | : 0x00ffffff; |
5482 | s->insn_read = ni_tio_insn_read; | 5490 | s->insn_read = ni_tio_insn_read; |
5483 | s->insn_write = ni_tio_insn_read; | 5491 | s->insn_write = ni_tio_insn_write; |
5484 | s->insn_config = ni_tio_insn_config; | 5492 | s->insn_config = ni_tio_insn_config; |
5485 | #ifdef PCIDMA | 5493 | #ifdef PCIDMA |
5486 | if (dev->irq && devpriv->mite) { | 5494 | if (dev->irq && devpriv->mite) { |
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 170ac980abcb..24c348d2f5bb 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c | |||
@@ -419,6 +419,7 @@ static ssize_t ad5933_store(struct device *dev, | |||
419 | mutex_lock(&indio_dev->mlock); | 419 | mutex_lock(&indio_dev->mlock); |
420 | switch ((u32)this_attr->address) { | 420 | switch ((u32)this_attr->address) { |
421 | case AD5933_OUT_RANGE: | 421 | case AD5933_OUT_RANGE: |
422 | ret = -EINVAL; | ||
422 | for (i = 0; i < 4; i++) | 423 | for (i = 0; i < 4; i++) |
423 | if (val == st->range_avail[i]) { | 424 | if (val == st->range_avail[i]) { |
424 | st->ctrl_hb &= ~AD5933_CTRL_RANGE(0x3); | 425 | st->ctrl_hb &= ~AD5933_CTRL_RANGE(0x3); |
@@ -426,7 +427,6 @@ static ssize_t ad5933_store(struct device *dev, | |||
426 | ret = ad5933_cmd(st, 0); | 427 | ret = ad5933_cmd(st, 0); |
427 | break; | 428 | break; |
428 | } | 429 | } |
429 | ret = -EINVAL; | ||
430 | break; | 430 | break; |
431 | case AD5933_IN_PGA_GAIN: | 431 | case AD5933_IN_PGA_GAIN: |
432 | if (sysfs_streq(buf, "1")) { | 432 | if (sysfs_streq(buf, "1")) { |
diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 3664bfd0178b..2c4dc69731e8 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c | |||
@@ -388,6 +388,7 @@ static int ll_lookup_it_finish(struct ptlrpc_request *request, | |||
388 | struct inode *inode = NULL; | 388 | struct inode *inode = NULL; |
389 | __u64 bits = 0; | 389 | __u64 bits = 0; |
390 | int rc = 0; | 390 | int rc = 0; |
391 | struct dentry *alias; | ||
391 | 392 | ||
392 | /* NB 1 request reference will be taken away by ll_intent_lock() | 393 | /* NB 1 request reference will be taken away by ll_intent_lock() |
393 | * when I return | 394 | * when I return |
@@ -412,26 +413,12 @@ static int ll_lookup_it_finish(struct ptlrpc_request *request, | |||
412 | */ | 413 | */ |
413 | } | 414 | } |
414 | 415 | ||
415 | /* Only hash *de if it is unhashed (new dentry). | 416 | alias = ll_splice_alias(inode, *de); |
416 | * Atoimc_open may passing hashed dentries for open. | 417 | if (IS_ERR(alias)) { |
417 | */ | 418 | rc = PTR_ERR(alias); |
418 | if (d_unhashed(*de)) { | 419 | goto out; |
419 | struct dentry *alias; | ||
420 | |||
421 | alias = ll_splice_alias(inode, *de); | ||
422 | if (IS_ERR(alias)) { | ||
423 | rc = PTR_ERR(alias); | ||
424 | goto out; | ||
425 | } | ||
426 | *de = alias; | ||
427 | } else if (!it_disposition(it, DISP_LOOKUP_NEG) && | ||
428 | !it_disposition(it, DISP_OPEN_CREATE)) { | ||
429 | /* With DISP_OPEN_CREATE dentry will be | ||
430 | * instantiated in ll_create_it. | ||
431 | */ | ||
432 | LASSERT(!d_inode(*de)); | ||
433 | d_instantiate(*de, inode); | ||
434 | } | 420 | } |
421 | *de = alias; | ||
435 | 422 | ||
436 | if (!it_disposition(it, DISP_LOOKUP_NEG)) { | 423 | if (!it_disposition(it, DISP_LOOKUP_NEG)) { |
437 | /* we have lookup look - unhide dentry */ | 424 | /* we have lookup look - unhide dentry */ |
@@ -587,6 +574,24 @@ static int ll_atomic_open(struct inode *dir, struct dentry *dentry, | |||
587 | dentry, PFID(ll_inode2fid(dir)), dir, file, open_flags, mode, | 574 | dentry, PFID(ll_inode2fid(dir)), dir, file, open_flags, mode, |
588 | *opened); | 575 | *opened); |
589 | 576 | ||
577 | /* Only negative dentries enter here */ | ||
578 | LASSERT(!d_inode(dentry)); | ||
579 | |||
580 | if (!d_in_lookup(dentry)) { | ||
581 | /* A valid negative dentry that just passed revalidation, | ||
582 | * there's little point to try and open it server-side, | ||
583 | * even though there's a minuscle chance it might succeed. | ||
584 | * Either way it's a valid race to just return -ENOENT here. | ||
585 | */ | ||
586 | if (!(open_flags & O_CREAT)) | ||
587 | return -ENOENT; | ||
588 | |||
589 | /* Otherwise we just unhash it to be rehashed afresh via | ||
590 | * lookup if necessary | ||
591 | */ | ||
592 | d_drop(dentry); | ||
593 | } | ||
594 | |||
590 | it = kzalloc(sizeof(*it), GFP_NOFS); | 595 | it = kzalloc(sizeof(*it), GFP_NOFS); |
591 | if (!it) | 596 | if (!it) |
592 | return -ENOMEM; | 597 | return -ENOMEM; |
diff --git a/drivers/staging/media/cec/TODO b/drivers/staging/media/cec/TODO index a10d4f82b954..13224694a8ae 100644 --- a/drivers/staging/media/cec/TODO +++ b/drivers/staging/media/cec/TODO | |||
@@ -12,6 +12,7 @@ Hopefully this will happen later in 2016. | |||
12 | 12 | ||
13 | Other TODOs: | 13 | Other TODOs: |
14 | 14 | ||
15 | - There are two possible replies to CEC_MSG_INITIATE_ARC. How to handle that? | ||
15 | - Add a flag to inhibit passing CEC RC messages to the rc subsystem. | 16 | - Add a flag to inhibit passing CEC RC messages to the rc subsystem. |
16 | Applications should be able to choose this when calling S_LOG_ADDRS. | 17 | Applications should be able to choose this when calling S_LOG_ADDRS. |
17 | - If the reply field of cec_msg is set then when the reply arrives it | 18 | - If the reply field of cec_msg is set then when the reply arrives it |
diff --git a/drivers/staging/media/cec/cec-adap.c b/drivers/staging/media/cec/cec-adap.c index b2393bbacb26..946986f3ac0d 100644 --- a/drivers/staging/media/cec/cec-adap.c +++ b/drivers/staging/media/cec/cec-adap.c | |||
@@ -124,10 +124,10 @@ static void cec_queue_event(struct cec_adapter *adap, | |||
124 | u64 ts = ktime_get_ns(); | 124 | u64 ts = ktime_get_ns(); |
125 | struct cec_fh *fh; | 125 | struct cec_fh *fh; |
126 | 126 | ||
127 | mutex_lock(&adap->devnode.fhs_lock); | 127 | mutex_lock(&adap->devnode.lock); |
128 | list_for_each_entry(fh, &adap->devnode.fhs, list) | 128 | list_for_each_entry(fh, &adap->devnode.fhs, list) |
129 | cec_queue_event_fh(fh, ev, ts); | 129 | cec_queue_event_fh(fh, ev, ts); |
130 | mutex_unlock(&adap->devnode.fhs_lock); | 130 | mutex_unlock(&adap->devnode.lock); |
131 | } | 131 | } |
132 | 132 | ||
133 | /* | 133 | /* |
@@ -191,12 +191,12 @@ static void cec_queue_msg_monitor(struct cec_adapter *adap, | |||
191 | u32 monitor_mode = valid_la ? CEC_MODE_MONITOR : | 191 | u32 monitor_mode = valid_la ? CEC_MODE_MONITOR : |
192 | CEC_MODE_MONITOR_ALL; | 192 | CEC_MODE_MONITOR_ALL; |
193 | 193 | ||
194 | mutex_lock(&adap->devnode.fhs_lock); | 194 | mutex_lock(&adap->devnode.lock); |
195 | list_for_each_entry(fh, &adap->devnode.fhs, list) { | 195 | list_for_each_entry(fh, &adap->devnode.fhs, list) { |
196 | if (fh->mode_follower >= monitor_mode) | 196 | if (fh->mode_follower >= monitor_mode) |
197 | cec_queue_msg_fh(fh, msg); | 197 | cec_queue_msg_fh(fh, msg); |
198 | } | 198 | } |
199 | mutex_unlock(&adap->devnode.fhs_lock); | 199 | mutex_unlock(&adap->devnode.lock); |
200 | } | 200 | } |
201 | 201 | ||
202 | /* | 202 | /* |
@@ -207,12 +207,12 @@ static void cec_queue_msg_followers(struct cec_adapter *adap, | |||
207 | { | 207 | { |
208 | struct cec_fh *fh; | 208 | struct cec_fh *fh; |
209 | 209 | ||
210 | mutex_lock(&adap->devnode.fhs_lock); | 210 | mutex_lock(&adap->devnode.lock); |
211 | list_for_each_entry(fh, &adap->devnode.fhs, list) { | 211 | list_for_each_entry(fh, &adap->devnode.fhs, list) { |
212 | if (fh->mode_follower == CEC_MODE_FOLLOWER) | 212 | if (fh->mode_follower == CEC_MODE_FOLLOWER) |
213 | cec_queue_msg_fh(fh, msg); | 213 | cec_queue_msg_fh(fh, msg); |
214 | } | 214 | } |
215 | mutex_unlock(&adap->devnode.fhs_lock); | 215 | mutex_unlock(&adap->devnode.lock); |
216 | } | 216 | } |
217 | 217 | ||
218 | /* Notify userspace of an adapter state change. */ | 218 | /* Notify userspace of an adapter state change. */ |
@@ -851,6 +851,9 @@ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) | |||
851 | if (!valid_la || msg->len <= 1) | 851 | if (!valid_la || msg->len <= 1) |
852 | return; | 852 | return; |
853 | 853 | ||
854 | if (adap->log_addrs.log_addr_mask == 0) | ||
855 | return; | ||
856 | |||
854 | /* | 857 | /* |
855 | * Process the message on the protocol level. If is_reply is true, | 858 | * Process the message on the protocol level. If is_reply is true, |
856 | * then cec_receive_notify() won't pass on the reply to the listener(s) | 859 | * then cec_receive_notify() won't pass on the reply to the listener(s) |
@@ -1047,11 +1050,17 @@ static int cec_config_thread_func(void *arg) | |||
1047 | dprintk(1, "could not claim LA %d\n", i); | 1050 | dprintk(1, "could not claim LA %d\n", i); |
1048 | } | 1051 | } |
1049 | 1052 | ||
1053 | if (adap->log_addrs.log_addr_mask == 0 && | ||
1054 | !(las->flags & CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK)) | ||
1055 | goto unconfigure; | ||
1056 | |||
1050 | configured: | 1057 | configured: |
1051 | if (adap->log_addrs.log_addr_mask == 0) { | 1058 | if (adap->log_addrs.log_addr_mask == 0) { |
1052 | /* Fall back to unregistered */ | 1059 | /* Fall back to unregistered */ |
1053 | las->log_addr[0] = CEC_LOG_ADDR_UNREGISTERED; | 1060 | las->log_addr[0] = CEC_LOG_ADDR_UNREGISTERED; |
1054 | las->log_addr_mask = 1 << las->log_addr[0]; | 1061 | las->log_addr_mask = 1 << las->log_addr[0]; |
1062 | for (i = 1; i < las->num_log_addrs; i++) | ||
1063 | las->log_addr[i] = CEC_LOG_ADDR_INVALID; | ||
1055 | } | 1064 | } |
1056 | adap->is_configured = true; | 1065 | adap->is_configured = true; |
1057 | adap->is_configuring = false; | 1066 | adap->is_configuring = false; |
@@ -1070,6 +1079,8 @@ configured: | |||
1070 | cec_report_features(adap, i); | 1079 | cec_report_features(adap, i); |
1071 | cec_report_phys_addr(adap, i); | 1080 | cec_report_phys_addr(adap, i); |
1072 | } | 1081 | } |
1082 | for (i = las->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) | ||
1083 | las->log_addr[i] = CEC_LOG_ADDR_INVALID; | ||
1073 | mutex_lock(&adap->lock); | 1084 | mutex_lock(&adap->lock); |
1074 | adap->kthread_config = NULL; | 1085 | adap->kthread_config = NULL; |
1075 | mutex_unlock(&adap->lock); | 1086 | mutex_unlock(&adap->lock); |
@@ -1398,7 +1409,6 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, | |||
1398 | u8 init_laddr = cec_msg_initiator(msg); | 1409 | u8 init_laddr = cec_msg_initiator(msg); |
1399 | u8 devtype = cec_log_addr2dev(adap, dest_laddr); | 1410 | u8 devtype = cec_log_addr2dev(adap, dest_laddr); |
1400 | int la_idx = cec_log_addr2idx(adap, dest_laddr); | 1411 | int la_idx = cec_log_addr2idx(adap, dest_laddr); |
1401 | bool is_directed = la_idx >= 0; | ||
1402 | bool from_unregistered = init_laddr == 0xf; | 1412 | bool from_unregistered = init_laddr == 0xf; |
1403 | struct cec_msg tx_cec_msg = { }; | 1413 | struct cec_msg tx_cec_msg = { }; |
1404 | 1414 | ||
@@ -1560,7 +1570,7 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, | |||
1560 | * Unprocessed messages are aborted if userspace isn't doing | 1570 | * Unprocessed messages are aborted if userspace isn't doing |
1561 | * any processing either. | 1571 | * any processing either. |
1562 | */ | 1572 | */ |
1563 | if (is_directed && !is_reply && !adap->follower_cnt && | 1573 | if (!is_broadcast && !is_reply && !adap->follower_cnt && |
1564 | !adap->cec_follower && msg->msg[1] != CEC_MSG_FEATURE_ABORT) | 1574 | !adap->cec_follower && msg->msg[1] != CEC_MSG_FEATURE_ABORT) |
1565 | return cec_feature_abort(adap, msg); | 1575 | return cec_feature_abort(adap, msg); |
1566 | break; | 1576 | break; |
diff --git a/drivers/staging/media/cec/cec-api.c b/drivers/staging/media/cec/cec-api.c index 7be7615a0fdf..e274e2f22398 100644 --- a/drivers/staging/media/cec/cec-api.c +++ b/drivers/staging/media/cec/cec-api.c | |||
@@ -162,7 +162,7 @@ static long cec_adap_s_log_addrs(struct cec_adapter *adap, struct cec_fh *fh, | |||
162 | return -ENOTTY; | 162 | return -ENOTTY; |
163 | if (copy_from_user(&log_addrs, parg, sizeof(log_addrs))) | 163 | if (copy_from_user(&log_addrs, parg, sizeof(log_addrs))) |
164 | return -EFAULT; | 164 | return -EFAULT; |
165 | log_addrs.flags = 0; | 165 | log_addrs.flags &= CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK; |
166 | mutex_lock(&adap->lock); | 166 | mutex_lock(&adap->lock); |
167 | if (!adap->is_configuring && | 167 | if (!adap->is_configuring && |
168 | (!log_addrs.num_log_addrs || !adap->is_configured) && | 168 | (!log_addrs.num_log_addrs || !adap->is_configured) && |
@@ -435,7 +435,7 @@ static long cec_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
435 | void __user *parg = (void __user *)arg; | 435 | void __user *parg = (void __user *)arg; |
436 | 436 | ||
437 | if (!devnode->registered) | 437 | if (!devnode->registered) |
438 | return -EIO; | 438 | return -ENODEV; |
439 | 439 | ||
440 | switch (cmd) { | 440 | switch (cmd) { |
441 | case CEC_ADAP_G_CAPS: | 441 | case CEC_ADAP_G_CAPS: |
@@ -508,14 +508,14 @@ static int cec_open(struct inode *inode, struct file *filp) | |||
508 | 508 | ||
509 | filp->private_data = fh; | 509 | filp->private_data = fh; |
510 | 510 | ||
511 | mutex_lock(&devnode->fhs_lock); | 511 | mutex_lock(&devnode->lock); |
512 | /* Queue up initial state events */ | 512 | /* Queue up initial state events */ |
513 | ev_state.state_change.phys_addr = adap->phys_addr; | 513 | ev_state.state_change.phys_addr = adap->phys_addr; |
514 | ev_state.state_change.log_addr_mask = adap->log_addrs.log_addr_mask; | 514 | ev_state.state_change.log_addr_mask = adap->log_addrs.log_addr_mask; |
515 | cec_queue_event_fh(fh, &ev_state, 0); | 515 | cec_queue_event_fh(fh, &ev_state, 0); |
516 | 516 | ||
517 | list_add(&fh->list, &devnode->fhs); | 517 | list_add(&fh->list, &devnode->fhs); |
518 | mutex_unlock(&devnode->fhs_lock); | 518 | mutex_unlock(&devnode->lock); |
519 | 519 | ||
520 | return 0; | 520 | return 0; |
521 | } | 521 | } |
@@ -540,9 +540,9 @@ static int cec_release(struct inode *inode, struct file *filp) | |||
540 | cec_monitor_all_cnt_dec(adap); | 540 | cec_monitor_all_cnt_dec(adap); |
541 | mutex_unlock(&adap->lock); | 541 | mutex_unlock(&adap->lock); |
542 | 542 | ||
543 | mutex_lock(&devnode->fhs_lock); | 543 | mutex_lock(&devnode->lock); |
544 | list_del(&fh->list); | 544 | list_del(&fh->list); |
545 | mutex_unlock(&devnode->fhs_lock); | 545 | mutex_unlock(&devnode->lock); |
546 | 546 | ||
547 | /* Unhook pending transmits from this filehandle. */ | 547 | /* Unhook pending transmits from this filehandle. */ |
548 | mutex_lock(&adap->lock); | 548 | mutex_lock(&adap->lock); |
diff --git a/drivers/staging/media/cec/cec-core.c b/drivers/staging/media/cec/cec-core.c index 112a5fae12f5..3b1e4d2b190d 100644 --- a/drivers/staging/media/cec/cec-core.c +++ b/drivers/staging/media/cec/cec-core.c | |||
@@ -51,31 +51,29 @@ int cec_get_device(struct cec_devnode *devnode) | |||
51 | { | 51 | { |
52 | /* | 52 | /* |
53 | * Check if the cec device is available. This needs to be done with | 53 | * Check if the cec device is available. This needs to be done with |
54 | * the cec_devnode_lock held to prevent an open/unregister race: | 54 | * the devnode->lock held to prevent an open/unregister race: |
55 | * without the lock, the device could be unregistered and freed between | 55 | * without the lock, the device could be unregistered and freed between |
56 | * the devnode->registered check and get_device() calls, leading to | 56 | * the devnode->registered check and get_device() calls, leading to |
57 | * a crash. | 57 | * a crash. |
58 | */ | 58 | */ |
59 | mutex_lock(&cec_devnode_lock); | 59 | mutex_lock(&devnode->lock); |
60 | /* | 60 | /* |
61 | * return ENXIO if the cec device has been removed | 61 | * return ENXIO if the cec device has been removed |
62 | * already or if it is not registered anymore. | 62 | * already or if it is not registered anymore. |
63 | */ | 63 | */ |
64 | if (!devnode->registered) { | 64 | if (!devnode->registered) { |
65 | mutex_unlock(&cec_devnode_lock); | 65 | mutex_unlock(&devnode->lock); |
66 | return -ENXIO; | 66 | return -ENXIO; |
67 | } | 67 | } |
68 | /* and increase the device refcount */ | 68 | /* and increase the device refcount */ |
69 | get_device(&devnode->dev); | 69 | get_device(&devnode->dev); |
70 | mutex_unlock(&cec_devnode_lock); | 70 | mutex_unlock(&devnode->lock); |
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
74 | void cec_put_device(struct cec_devnode *devnode) | 74 | void cec_put_device(struct cec_devnode *devnode) |
75 | { | 75 | { |
76 | mutex_lock(&cec_devnode_lock); | ||
77 | put_device(&devnode->dev); | 76 | put_device(&devnode->dev); |
78 | mutex_unlock(&cec_devnode_lock); | ||
79 | } | 77 | } |
80 | 78 | ||
81 | /* Called when the last user of the cec device exits. */ | 79 | /* Called when the last user of the cec device exits. */ |
@@ -84,11 +82,10 @@ static void cec_devnode_release(struct device *cd) | |||
84 | struct cec_devnode *devnode = to_cec_devnode(cd); | 82 | struct cec_devnode *devnode = to_cec_devnode(cd); |
85 | 83 | ||
86 | mutex_lock(&cec_devnode_lock); | 84 | mutex_lock(&cec_devnode_lock); |
87 | |||
88 | /* Mark device node number as free */ | 85 | /* Mark device node number as free */ |
89 | clear_bit(devnode->minor, cec_devnode_nums); | 86 | clear_bit(devnode->minor, cec_devnode_nums); |
90 | |||
91 | mutex_unlock(&cec_devnode_lock); | 87 | mutex_unlock(&cec_devnode_lock); |
88 | |||
92 | cec_delete_adapter(to_cec_adapter(devnode)); | 89 | cec_delete_adapter(to_cec_adapter(devnode)); |
93 | } | 90 | } |
94 | 91 | ||
@@ -117,7 +114,7 @@ static int __must_check cec_devnode_register(struct cec_devnode *devnode, | |||
117 | 114 | ||
118 | /* Initialization */ | 115 | /* Initialization */ |
119 | INIT_LIST_HEAD(&devnode->fhs); | 116 | INIT_LIST_HEAD(&devnode->fhs); |
120 | mutex_init(&devnode->fhs_lock); | 117 | mutex_init(&devnode->lock); |
121 | 118 | ||
122 | /* Part 1: Find a free minor number */ | 119 | /* Part 1: Find a free minor number */ |
123 | mutex_lock(&cec_devnode_lock); | 120 | mutex_lock(&cec_devnode_lock); |
@@ -160,7 +157,9 @@ static int __must_check cec_devnode_register(struct cec_devnode *devnode, | |||
160 | cdev_del: | 157 | cdev_del: |
161 | cdev_del(&devnode->cdev); | 158 | cdev_del(&devnode->cdev); |
162 | clr_bit: | 159 | clr_bit: |
160 | mutex_lock(&cec_devnode_lock); | ||
163 | clear_bit(devnode->minor, cec_devnode_nums); | 161 | clear_bit(devnode->minor, cec_devnode_nums); |
162 | mutex_unlock(&cec_devnode_lock); | ||
164 | return ret; | 163 | return ret; |
165 | } | 164 | } |
166 | 165 | ||
@@ -177,17 +176,21 @@ static void cec_devnode_unregister(struct cec_devnode *devnode) | |||
177 | { | 176 | { |
178 | struct cec_fh *fh; | 177 | struct cec_fh *fh; |
179 | 178 | ||
179 | mutex_lock(&devnode->lock); | ||
180 | |||
180 | /* Check if devnode was never registered or already unregistered */ | 181 | /* Check if devnode was never registered or already unregistered */ |
181 | if (!devnode->registered || devnode->unregistered) | 182 | if (!devnode->registered || devnode->unregistered) { |
183 | mutex_unlock(&devnode->lock); | ||
182 | return; | 184 | return; |
185 | } | ||
183 | 186 | ||
184 | mutex_lock(&devnode->fhs_lock); | ||
185 | list_for_each_entry(fh, &devnode->fhs, list) | 187 | list_for_each_entry(fh, &devnode->fhs, list) |
186 | wake_up_interruptible(&fh->wait); | 188 | wake_up_interruptible(&fh->wait); |
187 | mutex_unlock(&devnode->fhs_lock); | ||
188 | 189 | ||
189 | devnode->registered = false; | 190 | devnode->registered = false; |
190 | devnode->unregistered = true; | 191 | devnode->unregistered = true; |
192 | mutex_unlock(&devnode->lock); | ||
193 | |||
191 | device_del(&devnode->dev); | 194 | device_del(&devnode->dev); |
192 | cdev_del(&devnode->cdev); | 195 | cdev_del(&devnode->cdev); |
193 | put_device(&devnode->dev); | 196 | put_device(&devnode->dev); |
diff --git a/drivers/staging/media/pulse8-cec/pulse8-cec.c b/drivers/staging/media/pulse8-cec/pulse8-cec.c index 94f8590492dc..ed8bd95ad6d0 100644 --- a/drivers/staging/media/pulse8-cec/pulse8-cec.c +++ b/drivers/staging/media/pulse8-cec/pulse8-cec.c | |||
@@ -114,14 +114,11 @@ static void pulse8_irq_work_handler(struct work_struct *work) | |||
114 | cec_transmit_done(pulse8->adap, CEC_TX_STATUS_OK, | 114 | cec_transmit_done(pulse8->adap, CEC_TX_STATUS_OK, |
115 | 0, 0, 0, 0); | 115 | 0, 0, 0, 0); |
116 | break; | 116 | break; |
117 | case MSGCODE_TRANSMIT_FAILED_LINE: | ||
118 | cec_transmit_done(pulse8->adap, CEC_TX_STATUS_ARB_LOST, | ||
119 | 1, 0, 0, 0); | ||
120 | break; | ||
121 | case MSGCODE_TRANSMIT_FAILED_ACK: | 117 | case MSGCODE_TRANSMIT_FAILED_ACK: |
122 | cec_transmit_done(pulse8->adap, CEC_TX_STATUS_NACK, | 118 | cec_transmit_done(pulse8->adap, CEC_TX_STATUS_NACK, |
123 | 0, 1, 0, 0); | 119 | 0, 1, 0, 0); |
124 | break; | 120 | break; |
121 | case MSGCODE_TRANSMIT_FAILED_LINE: | ||
125 | case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: | 122 | case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: |
126 | case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: | 123 | case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: |
127 | cec_transmit_done(pulse8->adap, CEC_TX_STATUS_ERROR, | 124 | cec_transmit_done(pulse8->adap, CEC_TX_STATUS_ERROR, |
@@ -170,6 +167,9 @@ static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data, | |||
170 | case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: | 167 | case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: |
171 | schedule_work(&pulse8->work); | 168 | schedule_work(&pulse8->work); |
172 | break; | 169 | break; |
170 | case MSGCODE_HIGH_ERROR: | ||
171 | case MSGCODE_LOW_ERROR: | ||
172 | case MSGCODE_RECEIVE_FAILED: | ||
173 | case MSGCODE_TIMEOUT_ERROR: | 173 | case MSGCODE_TIMEOUT_ERROR: |
174 | break; | 174 | break; |
175 | case MSGCODE_COMMAND_ACCEPTED: | 175 | case MSGCODE_COMMAND_ACCEPTED: |
@@ -388,7 +388,7 @@ static int pulse8_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, | |||
388 | int err; | 388 | int err; |
389 | 389 | ||
390 | cmd[0] = MSGCODE_TRANSMIT_IDLETIME; | 390 | cmd[0] = MSGCODE_TRANSMIT_IDLETIME; |
391 | cmd[1] = 3; | 391 | cmd[1] = signal_free_time; |
392 | err = pulse8_send_and_wait(pulse8, cmd, 2, | 392 | err = pulse8_send_and_wait(pulse8, cmd, 2, |
393 | MSGCODE_COMMAND_ACCEPTED, 1); | 393 | MSGCODE_COMMAND_ACCEPTED, 1); |
394 | cmd[0] = MSGCODE_TRANSMIT_ACK_POLARITY; | 394 | cmd[0] = MSGCODE_TRANSMIT_ACK_POLARITY; |
diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 0b1760cba6e3..78f524fcd214 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c | |||
@@ -3363,7 +3363,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) | |||
3363 | if (!hif_workqueue) { | 3363 | if (!hif_workqueue) { |
3364 | netdev_err(vif->ndev, "Failed to create workqueue\n"); | 3364 | netdev_err(vif->ndev, "Failed to create workqueue\n"); |
3365 | result = -ENOMEM; | 3365 | result = -ENOMEM; |
3366 | goto _fail_mq_; | 3366 | goto _fail_; |
3367 | } | 3367 | } |
3368 | 3368 | ||
3369 | setup_timer(&periodic_rssi, GetPeriodicRSSI, | 3369 | setup_timer(&periodic_rssi, GetPeriodicRSSI, |
@@ -3391,7 +3391,6 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) | |||
3391 | 3391 | ||
3392 | clients_count++; | 3392 | clients_count++; |
3393 | 3393 | ||
3394 | _fail_mq_: | ||
3395 | destroy_workqueue(hif_workqueue); | 3394 | destroy_workqueue(hif_workqueue); |
3396 | _fail_: | 3395 | _fail_: |
3397 | return result; | 3396 | return result; |
diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 3a66255f14fc..32215110d597 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c | |||
@@ -648,7 +648,7 @@ void wilc1000_wlan_deinit(struct net_device *dev) | |||
648 | mutex_unlock(&wl->hif_cs); | 648 | mutex_unlock(&wl->hif_cs); |
649 | } | 649 | } |
650 | if (&wl->txq_event) | 650 | if (&wl->txq_event) |
651 | wait_for_completion(&wl->txq_event); | 651 | complete(&wl->txq_event); |
652 | 652 | ||
653 | wlan_deinitialize_threads(dev); | 653 | wlan_deinitialize_threads(dev); |
654 | deinit_irq(dev); | 654 | deinit_irq(dev); |
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 9092600a1794..2c2e8aca8305 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | |||
@@ -1191,7 +1191,7 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, | |||
1191 | struct wilc_priv *priv; | 1191 | struct wilc_priv *priv; |
1192 | struct wilc_vif *vif; | 1192 | struct wilc_vif *vif; |
1193 | u32 i = 0; | 1193 | u32 i = 0; |
1194 | u32 associatedsta = 0; | 1194 | u32 associatedsta = ~0; |
1195 | u32 inactive_time = 0; | 1195 | u32 inactive_time = 0; |
1196 | priv = wiphy_priv(wiphy); | 1196 | priv = wiphy_priv(wiphy); |
1197 | vif = netdev_priv(dev); | 1197 | vif = netdev_priv(dev); |
@@ -1204,7 +1204,7 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, | |||
1204 | } | 1204 | } |
1205 | } | 1205 | } |
1206 | 1206 | ||
1207 | if (associatedsta == -1) { | 1207 | if (associatedsta == ~0) { |
1208 | netdev_err(dev, "sta required is not associated\n"); | 1208 | netdev_err(dev, "sta required is not associated\n"); |
1209 | return -ENOENT; | 1209 | return -ENOENT; |
1210 | } | 1210 | } |
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 3788ed74c9ab..a32b41783b77 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c | |||
@@ -740,12 +740,22 @@ static int cpufreq_power2state(struct thermal_cooling_device *cdev, | |||
740 | } | 740 | } |
741 | 741 | ||
742 | /* Bind cpufreq callbacks to thermal cooling device ops */ | 742 | /* Bind cpufreq callbacks to thermal cooling device ops */ |
743 | |||
743 | static struct thermal_cooling_device_ops cpufreq_cooling_ops = { | 744 | static struct thermal_cooling_device_ops cpufreq_cooling_ops = { |
744 | .get_max_state = cpufreq_get_max_state, | 745 | .get_max_state = cpufreq_get_max_state, |
745 | .get_cur_state = cpufreq_get_cur_state, | 746 | .get_cur_state = cpufreq_get_cur_state, |
746 | .set_cur_state = cpufreq_set_cur_state, | 747 | .set_cur_state = cpufreq_set_cur_state, |
747 | }; | 748 | }; |
748 | 749 | ||
750 | static struct thermal_cooling_device_ops cpufreq_power_cooling_ops = { | ||
751 | .get_max_state = cpufreq_get_max_state, | ||
752 | .get_cur_state = cpufreq_get_cur_state, | ||
753 | .set_cur_state = cpufreq_set_cur_state, | ||
754 | .get_requested_power = cpufreq_get_requested_power, | ||
755 | .state2power = cpufreq_state2power, | ||
756 | .power2state = cpufreq_power2state, | ||
757 | }; | ||
758 | |||
749 | /* Notifier for cpufreq policy change */ | 759 | /* Notifier for cpufreq policy change */ |
750 | static struct notifier_block thermal_cpufreq_notifier_block = { | 760 | static struct notifier_block thermal_cpufreq_notifier_block = { |
751 | .notifier_call = cpufreq_thermal_notifier, | 761 | .notifier_call = cpufreq_thermal_notifier, |
@@ -795,6 +805,7 @@ __cpufreq_cooling_register(struct device_node *np, | |||
795 | struct cpumask temp_mask; | 805 | struct cpumask temp_mask; |
796 | unsigned int freq, i, num_cpus; | 806 | unsigned int freq, i, num_cpus; |
797 | int ret; | 807 | int ret; |
808 | struct thermal_cooling_device_ops *cooling_ops; | ||
798 | 809 | ||
799 | cpumask_and(&temp_mask, clip_cpus, cpu_online_mask); | 810 | cpumask_and(&temp_mask, clip_cpus, cpu_online_mask); |
800 | policy = cpufreq_cpu_get(cpumask_first(&temp_mask)); | 811 | policy = cpufreq_cpu_get(cpumask_first(&temp_mask)); |
@@ -850,10 +861,6 @@ __cpufreq_cooling_register(struct device_node *np, | |||
850 | cpumask_copy(&cpufreq_dev->allowed_cpus, clip_cpus); | 861 | cpumask_copy(&cpufreq_dev->allowed_cpus, clip_cpus); |
851 | 862 | ||
852 | if (capacitance) { | 863 | if (capacitance) { |
853 | cpufreq_cooling_ops.get_requested_power = | ||
854 | cpufreq_get_requested_power; | ||
855 | cpufreq_cooling_ops.state2power = cpufreq_state2power; | ||
856 | cpufreq_cooling_ops.power2state = cpufreq_power2state; | ||
857 | cpufreq_dev->plat_get_static_power = plat_static_func; | 864 | cpufreq_dev->plat_get_static_power = plat_static_func; |
858 | 865 | ||
859 | ret = build_dyn_power_table(cpufreq_dev, capacitance); | 866 | ret = build_dyn_power_table(cpufreq_dev, capacitance); |
@@ -861,6 +868,10 @@ __cpufreq_cooling_register(struct device_node *np, | |||
861 | cool_dev = ERR_PTR(ret); | 868 | cool_dev = ERR_PTR(ret); |
862 | goto free_table; | 869 | goto free_table; |
863 | } | 870 | } |
871 | |||
872 | cooling_ops = &cpufreq_power_cooling_ops; | ||
873 | } else { | ||
874 | cooling_ops = &cpufreq_cooling_ops; | ||
864 | } | 875 | } |
865 | 876 | ||
866 | ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); | 877 | ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); |
@@ -885,7 +896,7 @@ __cpufreq_cooling_register(struct device_node *np, | |||
885 | cpufreq_dev->id); | 896 | cpufreq_dev->id); |
886 | 897 | ||
887 | cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev, | 898 | cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev, |
888 | &cpufreq_cooling_ops); | 899 | cooling_ops); |
889 | if (IS_ERR(cool_dev)) | 900 | if (IS_ERR(cool_dev)) |
890 | goto remove_idr; | 901 | goto remove_idr; |
891 | 902 | ||
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index c5547bd711db..e473548b5d28 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c | |||
@@ -471,8 +471,6 @@ MODULE_DEVICE_TABLE(of, of_imx_thermal_match); | |||
471 | 471 | ||
472 | static int imx_thermal_probe(struct platform_device *pdev) | 472 | static int imx_thermal_probe(struct platform_device *pdev) |
473 | { | 473 | { |
474 | const struct of_device_id *of_id = | ||
475 | of_match_device(of_imx_thermal_match, &pdev->dev); | ||
476 | struct imx_thermal_data *data; | 474 | struct imx_thermal_data *data; |
477 | struct regmap *map; | 475 | struct regmap *map; |
478 | int measure_freq; | 476 | int measure_freq; |
@@ -490,7 +488,7 @@ static int imx_thermal_probe(struct platform_device *pdev) | |||
490 | } | 488 | } |
491 | data->tempmon = map; | 489 | data->tempmon = map; |
492 | 490 | ||
493 | data->socdata = of_id->data; | 491 | data->socdata = of_device_get_match_data(&pdev->dev); |
494 | 492 | ||
495 | /* make sure the IRQ flag is clear before enabling irq on i.MX6SX */ | 493 | /* make sure the IRQ flag is clear before enabling irq on i.MX6SX */ |
496 | if (data->socdata->version == TEMPMON_IMX6SX) { | 494 | if (data->socdata->version == TEMPMON_IMX6SX) { |
diff --git a/drivers/thermal/int340x_thermal/int3406_thermal.c b/drivers/thermal/int340x_thermal/int3406_thermal.c index a578cd257db4..1891f34ab7fc 100644 --- a/drivers/thermal/int340x_thermal/int3406_thermal.c +++ b/drivers/thermal/int340x_thermal/int3406_thermal.c | |||
@@ -225,7 +225,6 @@ static struct platform_driver int3406_thermal_driver = { | |||
225 | .remove = int3406_thermal_remove, | 225 | .remove = int3406_thermal_remove, |
226 | .driver = { | 226 | .driver = { |
227 | .name = "int3406 thermal", | 227 | .name = "int3406 thermal", |
228 | .owner = THIS_MODULE, | ||
229 | .acpi_match_table = int3406_thermal_match, | 228 | .acpi_match_table = int3406_thermal_match, |
230 | }, | 229 | }, |
231 | }; | 230 | }; |
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index 71a339271fa5..5f817923f374 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c | |||
@@ -504,6 +504,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) | |||
504 | if (IS_ERR(priv->zone)) { | 504 | if (IS_ERR(priv->zone)) { |
505 | dev_err(dev, "can't register thermal zone\n"); | 505 | dev_err(dev, "can't register thermal zone\n"); |
506 | ret = PTR_ERR(priv->zone); | 506 | ret = PTR_ERR(priv->zone); |
507 | priv->zone = NULL; | ||
507 | goto error_unregister; | 508 | goto error_unregister; |
508 | } | 509 | } |
509 | 510 | ||
diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index 9c15344b657a..a8c20413dbda 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c | |||
@@ -651,6 +651,12 @@ static struct pci_device_id nhi_ids[] = { | |||
651 | { | 651 | { |
652 | .class = PCI_CLASS_SYSTEM_OTHER << 8, .class_mask = ~0, | 652 | .class = PCI_CLASS_SYSTEM_OTHER << 8, .class_mask = ~0, |
653 | .vendor = PCI_VENDOR_ID_INTEL, | 653 | .vendor = PCI_VENDOR_ID_INTEL, |
654 | .device = PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI, | ||
655 | .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, | ||
656 | }, | ||
657 | { | ||
658 | .class = PCI_CLASS_SYSTEM_OTHER << 8, .class_mask = ~0, | ||
659 | .vendor = PCI_VENDOR_ID_INTEL, | ||
654 | .device = PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI, | 660 | .device = PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI, |
655 | .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, | 661 | .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, |
656 | }, | 662 | }, |
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 1e116f53d6dd..9840fdecb73b 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c | |||
@@ -372,7 +372,9 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, u64 route) | |||
372 | 372 | ||
373 | if (sw->config.device_id != PCI_DEVICE_ID_INTEL_LIGHT_RIDGE && | 373 | if (sw->config.device_id != PCI_DEVICE_ID_INTEL_LIGHT_RIDGE && |
374 | sw->config.device_id != PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C && | 374 | sw->config.device_id != PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C && |
375 | sw->config.device_id != PCI_DEVICE_ID_INTEL_PORT_RIDGE) | 375 | sw->config.device_id != PCI_DEVICE_ID_INTEL_PORT_RIDGE && |
376 | sw->config.device_id != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_BRIDGE && | ||
377 | sw->config.device_id != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_BRIDGE) | ||
376 | tb_sw_warn(sw, "unsupported switch device id %#x\n", | 378 | tb_sw_warn(sw, "unsupported switch device id %#x\n", |
377 | sw->config.device_id); | 379 | sw->config.device_id); |
378 | 380 | ||
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 122e0e4029fe..1a16feac9a36 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h | |||
@@ -15,8 +15,6 @@ | |||
15 | #include <linux/serial_reg.h> | 15 | #include <linux/serial_reg.h> |
16 | #include <linux/dmaengine.h> | 16 | #include <linux/dmaengine.h> |
17 | 17 | ||
18 | #include "../serial_mctrl_gpio.h" | ||
19 | |||
20 | struct uart_8250_dma { | 18 | struct uart_8250_dma { |
21 | int (*tx_dma)(struct uart_8250_port *p); | 19 | int (*tx_dma)(struct uart_8250_port *p); |
22 | int (*rx_dma)(struct uart_8250_port *p); | 20 | int (*rx_dma)(struct uart_8250_port *p); |
@@ -133,43 +131,12 @@ void serial8250_em485_destroy(struct uart_8250_port *p); | |||
133 | 131 | ||
134 | static inline void serial8250_out_MCR(struct uart_8250_port *up, int value) | 132 | static inline void serial8250_out_MCR(struct uart_8250_port *up, int value) |
135 | { | 133 | { |
136 | int mctrl_gpio = 0; | ||
137 | |||
138 | serial_out(up, UART_MCR, value); | 134 | serial_out(up, UART_MCR, value); |
139 | |||
140 | if (value & UART_MCR_RTS) | ||
141 | mctrl_gpio |= TIOCM_RTS; | ||
142 | if (value & UART_MCR_DTR) | ||
143 | mctrl_gpio |= TIOCM_DTR; | ||
144 | |||
145 | mctrl_gpio_set(up->gpios, mctrl_gpio); | ||
146 | } | 135 | } |
147 | 136 | ||
148 | static inline int serial8250_in_MCR(struct uart_8250_port *up) | 137 | static inline int serial8250_in_MCR(struct uart_8250_port *up) |
149 | { | 138 | { |
150 | int mctrl, mctrl_gpio = 0; | 139 | return serial_in(up, UART_MCR); |
151 | |||
152 | mctrl = serial_in(up, UART_MCR); | ||
153 | |||
154 | /* save current MCR values */ | ||
155 | if (mctrl & UART_MCR_RTS) | ||
156 | mctrl_gpio |= TIOCM_RTS; | ||
157 | if (mctrl & UART_MCR_DTR) | ||
158 | mctrl_gpio |= TIOCM_DTR; | ||
159 | |||
160 | mctrl_gpio = mctrl_gpio_get_outputs(up->gpios, &mctrl_gpio); | ||
161 | |||
162 | if (mctrl_gpio & TIOCM_RTS) | ||
163 | mctrl |= UART_MCR_RTS; | ||
164 | else | ||
165 | mctrl &= ~UART_MCR_RTS; | ||
166 | |||
167 | if (mctrl_gpio & TIOCM_DTR) | ||
168 | mctrl |= UART_MCR_DTR; | ||
169 | else | ||
170 | mctrl &= ~UART_MCR_DTR; | ||
171 | |||
172 | return mctrl; | ||
173 | } | 140 | } |
174 | 141 | ||
175 | #if defined(__alpha__) && !defined(CONFIG_PCI) | 142 | #if defined(__alpha__) && !defined(CONFIG_PCI) |
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 13ad5c3d2e68..dcf43f66404f 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c | |||
@@ -974,8 +974,6 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
974 | 974 | ||
975 | uart = serial8250_find_match_or_unused(&up->port); | 975 | uart = serial8250_find_match_or_unused(&up->port); |
976 | if (uart && uart->port.type != PORT_8250_CIR) { | 976 | if (uart && uart->port.type != PORT_8250_CIR) { |
977 | struct mctrl_gpios *gpios; | ||
978 | |||
979 | if (uart->port.dev) | 977 | if (uart->port.dev) |
980 | uart_remove_one_port(&serial8250_reg, &uart->port); | 978 | uart_remove_one_port(&serial8250_reg, &uart->port); |
981 | 979 | ||
@@ -1013,13 +1011,6 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
1013 | if (up->port.flags & UPF_FIXED_TYPE) | 1011 | if (up->port.flags & UPF_FIXED_TYPE) |
1014 | uart->port.type = up->port.type; | 1012 | uart->port.type = up->port.type; |
1015 | 1013 | ||
1016 | gpios = mctrl_gpio_init(&uart->port, 0); | ||
1017 | if (IS_ERR(gpios)) { | ||
1018 | if (PTR_ERR(gpios) != -ENOSYS) | ||
1019 | return PTR_ERR(gpios); | ||
1020 | } else | ||
1021 | uart->gpios = gpios; | ||
1022 | |||
1023 | serial8250_set_defaults(uart); | 1014 | serial8250_set_defaults(uart); |
1024 | 1015 | ||
1025 | /* Possibly override default I/O functions. */ | 1016 | /* Possibly override default I/O functions. */ |
diff --git a/drivers/tty/serial/8250/8250_fintek.c b/drivers/tty/serial/8250/8250_fintek.c index 737b4b3957b0..0facc789fe7d 100644 --- a/drivers/tty/serial/8250/8250_fintek.c +++ b/drivers/tty/serial/8250/8250_fintek.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #define IO_ADDR2 0x60 | 31 | #define IO_ADDR2 0x60 |
32 | #define LDN 0x7 | 32 | #define LDN 0x7 |
33 | 33 | ||
34 | #define IRQ_MODE 0x70 | 34 | #define FINTEK_IRQ_MODE 0x70 |
35 | #define IRQ_SHARE BIT(4) | 35 | #define IRQ_SHARE BIT(4) |
36 | #define IRQ_MODE_MASK (BIT(6) | BIT(5)) | 36 | #define IRQ_MODE_MASK (BIT(6) | BIT(5)) |
37 | #define IRQ_LEVEL_LOW 0 | 37 | #define IRQ_LEVEL_LOW 0 |
@@ -195,7 +195,7 @@ static int fintek_8250_set_irq_mode(struct fintek_8250 *pdata, bool level_mode) | |||
195 | outb(LDN, pdata->base_port + ADDR_PORT); | 195 | outb(LDN, pdata->base_port + ADDR_PORT); |
196 | outb(pdata->index, pdata->base_port + DATA_PORT); | 196 | outb(pdata->index, pdata->base_port + DATA_PORT); |
197 | 197 | ||
198 | outb(IRQ_MODE, pdata->base_port + ADDR_PORT); | 198 | outb(FINTEK_IRQ_MODE, pdata->base_port + ADDR_PORT); |
199 | tmp = inb(pdata->base_port + DATA_PORT); | 199 | tmp = inb(pdata->base_port + DATA_PORT); |
200 | 200 | ||
201 | tmp &= ~IRQ_MODE_MASK; | 201 | tmp &= ~IRQ_MODE_MASK; |
diff --git a/drivers/tty/serial/8250/8250_mid.c b/drivers/tty/serial/8250/8250_mid.c index 339de9cd0866..20c5db2f4264 100644 --- a/drivers/tty/serial/8250/8250_mid.c +++ b/drivers/tty/serial/8250/8250_mid.c | |||
@@ -168,6 +168,9 @@ static void mid8250_set_termios(struct uart_port *p, | |||
168 | unsigned long w = BIT(24) - 1; | 168 | unsigned long w = BIT(24) - 1; |
169 | unsigned long mul, div; | 169 | unsigned long mul, div; |
170 | 170 | ||
171 | /* Gracefully handle the B0 case: fall back to B9600 */ | ||
172 | fuart = fuart ? fuart : 9600 * 16; | ||
173 | |||
171 | if (mid->board->freq < fuart) { | 174 | if (mid->board->freq < fuart) { |
172 | /* Find prescaler value that satisfies Fuart < Fref */ | 175 | /* Find prescaler value that satisfies Fuart < Fref */ |
173 | if (mid->board->freq > baud) | 176 | if (mid->board->freq > baud) |
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index e14982f36a04..61ad6c3b20a0 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c | |||
@@ -134,21 +134,18 @@ static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
134 | 134 | ||
135 | serial8250_do_set_mctrl(port, mctrl); | 135 | serial8250_do_set_mctrl(port, mctrl); |
136 | 136 | ||
137 | if (IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(up->gpios, | 137 | /* |
138 | UART_GPIO_RTS))) { | 138 | * Turn off autoRTS if RTS is lowered and restore autoRTS setting |
139 | /* | 139 | * if RTS is raised |
140 | * Turn off autoRTS if RTS is lowered and restore autoRTS | 140 | */ |
141 | * setting if RTS is raised | 141 | lcr = serial_in(up, UART_LCR); |
142 | */ | 142 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
143 | lcr = serial_in(up, UART_LCR); | 143 | if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS)) |
144 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 144 | priv->efr |= UART_EFR_RTS; |
145 | if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS)) | 145 | else |
146 | priv->efr |= UART_EFR_RTS; | 146 | priv->efr &= ~UART_EFR_RTS; |
147 | else | 147 | serial_out(up, UART_EFR, priv->efr); |
148 | priv->efr &= ~UART_EFR_RTS; | 148 | serial_out(up, UART_LCR, lcr); |
149 | serial_out(up, UART_EFR, priv->efr); | ||
150 | serial_out(up, UART_LCR, lcr); | ||
151 | } | ||
152 | } | 149 | } |
153 | 150 | ||
154 | /* | 151 | /* |
@@ -449,9 +446,7 @@ static void omap_8250_set_termios(struct uart_port *port, | |||
449 | priv->efr = 0; | 446 | priv->efr = 0; |
450 | up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF); | 447 | up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF); |
451 | 448 | ||
452 | if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW | 449 | if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { |
453 | && IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(up->gpios, | ||
454 | UART_GPIO_RTS))) { | ||
455 | /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */ | 450 | /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */ |
456 | up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; | 451 | up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; |
457 | priv->efr |= UART_EFR_CTS; | 452 | priv->efr |= UART_EFR_CTS; |
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 20ebaea5c414..bc51b32b2774 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
@@ -1950,6 +1950,43 @@ pci_wch_ch38x_setup(struct serial_private *priv, | |||
1950 | #define PCI_DEVICE_ID_PERICOM_PI7C9X7954 0x7954 | 1950 | #define PCI_DEVICE_ID_PERICOM_PI7C9X7954 0x7954 |
1951 | #define PCI_DEVICE_ID_PERICOM_PI7C9X7958 0x7958 | 1951 | #define PCI_DEVICE_ID_PERICOM_PI7C9X7958 0x7958 |
1952 | 1952 | ||
1953 | #define PCI_VENDOR_ID_ACCESIO 0x494f | ||
1954 | #define PCI_DEVICE_ID_ACCESIO_PCIE_COM_2SDB 0x1051 | ||
1955 | #define PCI_DEVICE_ID_ACCESIO_MPCIE_COM_2S 0x1053 | ||
1956 | #define PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SDB 0x105C | ||
1957 | #define PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4S 0x105E | ||
1958 | #define PCI_DEVICE_ID_ACCESIO_PCIE_COM232_2DB 0x1091 | ||
1959 | #define PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_2 0x1093 | ||
1960 | #define PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4DB 0x1099 | ||
1961 | #define PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_4 0x109B | ||
1962 | #define PCI_DEVICE_ID_ACCESIO_PCIE_COM_2SMDB 0x10D1 | ||
1963 | #define PCI_DEVICE_ID_ACCESIO_MPCIE_COM_2SM 0x10D3 | ||
1964 | #define PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SMDB 0x10DA | ||
1965 | #define PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4SM 0x10DC | ||
1966 | #define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_1 0x1108 | ||
1967 | #define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_2 0x1110 | ||
1968 | #define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_2 0x1111 | ||
1969 | #define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_4 0x1118 | ||
1970 | #define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_4 0x1119 | ||
1971 | #define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_2S 0x1152 | ||
1972 | #define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S 0x115A | ||
1973 | #define PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_2 0x1190 | ||
1974 | #define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_2 0x1191 | ||
1975 | #define PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4 0x1198 | ||
1976 | #define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4 0x1199 | ||
1977 | #define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_2SM 0x11D0 | ||
1978 | #define PCI_DEVICE_ID_ACCESIO_PCIE_COM422_4 0x105A | ||
1979 | #define PCI_DEVICE_ID_ACCESIO_PCIE_COM485_4 0x105B | ||
1980 | #define PCI_DEVICE_ID_ACCESIO_PCIE_COM422_8 0x106A | ||
1981 | #define PCI_DEVICE_ID_ACCESIO_PCIE_COM485_8 0x106B | ||
1982 | #define PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4 0x1098 | ||
1983 | #define PCI_DEVICE_ID_ACCESIO_PCIE_COM232_8 0x10A9 | ||
1984 | #define PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SM 0x10D9 | ||
1985 | #define PCI_DEVICE_ID_ACCESIO_PCIE_COM_8SM 0x10E9 | ||
1986 | #define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM 0x11D8 | ||
1987 | |||
1988 | |||
1989 | |||
1953 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ | 1990 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ |
1954 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 | 1991 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 |
1955 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588 | 1992 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588 |
@@ -5113,6 +5150,108 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
5113 | 0, | 5150 | 0, |
5114 | 0, pbn_pericom_PI7C9X7958 }, | 5151 | 0, pbn_pericom_PI7C9X7958 }, |
5115 | /* | 5152 | /* |
5153 | * ACCES I/O Products quad | ||
5154 | */ | ||
5155 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_2SDB, | ||
5156 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5157 | pbn_pericom_PI7C9X7954 }, | ||
5158 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM_2S, | ||
5159 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5160 | pbn_pericom_PI7C9X7954 }, | ||
5161 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SDB, | ||
5162 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5163 | pbn_pericom_PI7C9X7954 }, | ||
5164 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4S, | ||
5165 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5166 | pbn_pericom_PI7C9X7954 }, | ||
5167 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM232_2DB, | ||
5168 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5169 | pbn_pericom_PI7C9X7954 }, | ||
5170 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_2, | ||
5171 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5172 | pbn_pericom_PI7C9X7954 }, | ||
5173 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4DB, | ||
5174 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5175 | pbn_pericom_PI7C9X7954 }, | ||
5176 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_4, | ||
5177 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5178 | pbn_pericom_PI7C9X7954 }, | ||
5179 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_2SMDB, | ||
5180 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5181 | pbn_pericom_PI7C9X7954 }, | ||
5182 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM_2SM, | ||
5183 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5184 | pbn_pericom_PI7C9X7954 }, | ||
5185 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SMDB, | ||
5186 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5187 | pbn_pericom_PI7C9X7954 }, | ||
5188 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4SM, | ||
5189 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5190 | pbn_pericom_PI7C9X7954 }, | ||
5191 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_1, | ||
5192 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5193 | pbn_pericom_PI7C9X7954 }, | ||
5194 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_2, | ||
5195 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5196 | pbn_pericom_PI7C9X7954 }, | ||
5197 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_2, | ||
5198 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5199 | pbn_pericom_PI7C9X7954 }, | ||
5200 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_4, | ||
5201 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5202 | pbn_pericom_PI7C9X7954 }, | ||
5203 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_4, | ||
5204 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5205 | pbn_pericom_PI7C9X7954 }, | ||
5206 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM_2S, | ||
5207 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5208 | pbn_pericom_PI7C9X7954 }, | ||
5209 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S, | ||
5210 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5211 | pbn_pericom_PI7C9X7954 }, | ||
5212 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_2, | ||
5213 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5214 | pbn_pericom_PI7C9X7954 }, | ||
5215 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_2, | ||
5216 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5217 | pbn_pericom_PI7C9X7954 }, | ||
5218 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4, | ||
5219 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5220 | pbn_pericom_PI7C9X7954 }, | ||
5221 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4, | ||
5222 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5223 | pbn_pericom_PI7C9X7954 }, | ||
5224 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM_2SM, | ||
5225 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5226 | pbn_pericom_PI7C9X7954 }, | ||
5227 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM422_4, | ||
5228 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5229 | pbn_pericom_PI7C9X7958 }, | ||
5230 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM485_4, | ||
5231 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5232 | pbn_pericom_PI7C9X7958 }, | ||
5233 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM422_8, | ||
5234 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5235 | pbn_pericom_PI7C9X7958 }, | ||
5236 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM485_8, | ||
5237 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5238 | pbn_pericom_PI7C9X7958 }, | ||
5239 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4, | ||
5240 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5241 | pbn_pericom_PI7C9X7958 }, | ||
5242 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM232_8, | ||
5243 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5244 | pbn_pericom_PI7C9X7958 }, | ||
5245 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SM, | ||
5246 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5247 | pbn_pericom_PI7C9X7958 }, | ||
5248 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_8SM, | ||
5249 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5250 | pbn_pericom_PI7C9X7958 }, | ||
5251 | { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM, | ||
5252 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5253 | pbn_pericom_PI7C9X7958 }, | ||
5254 | /* | ||
5116 | * Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke) | 5255 | * Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke) |
5117 | */ | 5256 | */ |
5118 | { PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560, | 5257 | { PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560, |
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 7481b95c6d84..bdfa659b9606 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c | |||
@@ -1618,8 +1618,6 @@ static void serial8250_disable_ms(struct uart_port *port) | |||
1618 | if (up->bugs & UART_BUG_NOMSR) | 1618 | if (up->bugs & UART_BUG_NOMSR) |
1619 | return; | 1619 | return; |
1620 | 1620 | ||
1621 | mctrl_gpio_disable_ms(up->gpios); | ||
1622 | |||
1623 | up->ier &= ~UART_IER_MSI; | 1621 | up->ier &= ~UART_IER_MSI; |
1624 | serial_port_out(port, UART_IER, up->ier); | 1622 | serial_port_out(port, UART_IER, up->ier); |
1625 | } | 1623 | } |
@@ -1632,8 +1630,6 @@ static void serial8250_enable_ms(struct uart_port *port) | |||
1632 | if (up->bugs & UART_BUG_NOMSR) | 1630 | if (up->bugs & UART_BUG_NOMSR) |
1633 | return; | 1631 | return; |
1634 | 1632 | ||
1635 | mctrl_gpio_enable_ms(up->gpios); | ||
1636 | |||
1637 | up->ier |= UART_IER_MSI; | 1633 | up->ier |= UART_IER_MSI; |
1638 | 1634 | ||
1639 | serial8250_rpm_get(up); | 1635 | serial8250_rpm_get(up); |
@@ -1917,8 +1913,7 @@ unsigned int serial8250_do_get_mctrl(struct uart_port *port) | |||
1917 | ret |= TIOCM_DSR; | 1913 | ret |= TIOCM_DSR; |
1918 | if (status & UART_MSR_CTS) | 1914 | if (status & UART_MSR_CTS) |
1919 | ret |= TIOCM_CTS; | 1915 | ret |= TIOCM_CTS; |
1920 | 1916 | return ret; | |
1921 | return mctrl_gpio_get(up->gpios, &ret); | ||
1922 | } | 1917 | } |
1923 | EXPORT_SYMBOL_GPL(serial8250_do_get_mctrl); | 1918 | EXPORT_SYMBOL_GPL(serial8250_do_get_mctrl); |
1924 | 1919 | ||
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index c9ec839a5ddf..7c6f7afca5dd 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig | |||
@@ -6,7 +6,6 @@ | |||
6 | config SERIAL_8250 | 6 | config SERIAL_8250 |
7 | tristate "8250/16550 and compatible serial support" | 7 | tristate "8250/16550 and compatible serial support" |
8 | select SERIAL_CORE | 8 | select SERIAL_CORE |
9 | select SERIAL_MCTRL_GPIO if GPIOLIB | ||
10 | ---help--- | 9 | ---help--- |
11 | This selects whether you want to include the driver for the standard | 10 | This selects whether you want to include the driver for the standard |
12 | serial ports. The standard answer is Y. People who might say N | 11 | serial ports. The standard answer is Y. People who might say N |
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 065f5d97aa67..b93356834bb5 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c | |||
@@ -949,6 +949,15 @@ static int isr_setup_status_phase(struct ci_hdrc *ci) | |||
949 | int retval; | 949 | int retval; |
950 | struct ci_hw_ep *hwep; | 950 | struct ci_hw_ep *hwep; |
951 | 951 | ||
952 | /* | ||
953 | * Unexpected USB controller behavior, caused by bad signal integrity | ||
954 | * or ground reference problems, can lead to isr_setup_status_phase | ||
955 | * being called with ci->status equal to NULL. | ||
956 | * If this situation occurs, you should review your USB hardware design. | ||
957 | */ | ||
958 | if (WARN_ON_ONCE(!ci->status)) | ||
959 | return -EPIPE; | ||
960 | |||
952 | hwep = (ci->ep0_dir == TX) ? ci->ep0out : ci->ep0in; | 961 | hwep = (ci->ep0_dir == TX) ? ci->ep0out : ci->ep0in; |
953 | ci->status->context = ci; | 962 | ci->status->context = ci; |
954 | ci->status->complete = isr_setup_status_complete; | 963 | ci->status->complete = isr_setup_status_complete; |
@@ -1596,8 +1605,11 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on) | |||
1596 | { | 1605 | { |
1597 | struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); | 1606 | struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); |
1598 | 1607 | ||
1599 | /* Data+ pullup controlled by OTG state machine in OTG fsm mode */ | 1608 | /* |
1600 | if (ci_otg_is_fsm_mode(ci)) | 1609 | * Data+ pullup controlled by OTG state machine in OTG fsm mode; |
1610 | * and don't touch Data+ in host mode for dual role config. | ||
1611 | */ | ||
1612 | if (ci_otg_is_fsm_mode(ci) || ci->role == CI_ROLE_HOST) | ||
1601 | return 0; | 1613 | return 0; |
1602 | 1614 | ||
1603 | pm_runtime_get_sync(&ci->gadget.dev); | 1615 | pm_runtime_get_sync(&ci->gadget.dev); |
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 051163189810..a2d90aca779f 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
@@ -187,7 +187,7 @@ static const unsigned short high_speed_maxpacket_maxes[4] = { | |||
187 | [USB_ENDPOINT_XFER_CONTROL] = 64, | 187 | [USB_ENDPOINT_XFER_CONTROL] = 64, |
188 | [USB_ENDPOINT_XFER_ISOC] = 1024, | 188 | [USB_ENDPOINT_XFER_ISOC] = 1024, |
189 | [USB_ENDPOINT_XFER_BULK] = 512, | 189 | [USB_ENDPOINT_XFER_BULK] = 512, |
190 | [USB_ENDPOINT_XFER_INT] = 1023, | 190 | [USB_ENDPOINT_XFER_INT] = 1024, |
191 | }; | 191 | }; |
192 | static const unsigned short super_speed_maxpacket_maxes[4] = { | 192 | static const unsigned short super_speed_maxpacket_maxes[4] = { |
193 | [USB_ENDPOINT_XFER_CONTROL] = 512, | 193 | [USB_ENDPOINT_XFER_CONTROL] = 512, |
@@ -240,8 +240,10 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, | |||
240 | memcpy(&endpoint->desc, d, n); | 240 | memcpy(&endpoint->desc, d, n); |
241 | INIT_LIST_HEAD(&endpoint->urb_list); | 241 | INIT_LIST_HEAD(&endpoint->urb_list); |
242 | 242 | ||
243 | /* Fix up bInterval values outside the legal range. Use 32 ms if no | 243 | /* |
244 | * proper value can be guessed. */ | 244 | * Fix up bInterval values outside the legal range. |
245 | * Use 10 or 8 ms if no proper value can be guessed. | ||
246 | */ | ||
245 | i = 0; /* i = min, j = max, n = default */ | 247 | i = 0; /* i = min, j = max, n = default */ |
246 | j = 255; | 248 | j = 255; |
247 | if (usb_endpoint_xfer_int(d)) { | 249 | if (usb_endpoint_xfer_int(d)) { |
@@ -250,13 +252,15 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, | |||
250 | case USB_SPEED_SUPER_PLUS: | 252 | case USB_SPEED_SUPER_PLUS: |
251 | case USB_SPEED_SUPER: | 253 | case USB_SPEED_SUPER: |
252 | case USB_SPEED_HIGH: | 254 | case USB_SPEED_HIGH: |
253 | /* Many device manufacturers are using full-speed | 255 | /* |
256 | * Many device manufacturers are using full-speed | ||
254 | * bInterval values in high-speed interrupt endpoint | 257 | * bInterval values in high-speed interrupt endpoint |
255 | * descriptors. Try to fix those and fall back to a | 258 | * descriptors. Try to fix those and fall back to an |
256 | * 32 ms default value otherwise. */ | 259 | * 8-ms default value otherwise. |
260 | */ | ||
257 | n = fls(d->bInterval*8); | 261 | n = fls(d->bInterval*8); |
258 | if (n == 0) | 262 | if (n == 0) |
259 | n = 9; /* 32 ms = 2^(9-1) uframes */ | 263 | n = 7; /* 8 ms = 2^(7-1) uframes */ |
260 | j = 16; | 264 | j = 16; |
261 | 265 | ||
262 | /* | 266 | /* |
@@ -271,10 +275,12 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, | |||
271 | } | 275 | } |
272 | break; | 276 | break; |
273 | default: /* USB_SPEED_FULL or _LOW */ | 277 | default: /* USB_SPEED_FULL or _LOW */ |
274 | /* For low-speed, 10 ms is the official minimum. | 278 | /* |
279 | * For low-speed, 10 ms is the official minimum. | ||
275 | * But some "overclocked" devices might want faster | 280 | * But some "overclocked" devices might want faster |
276 | * polling so we'll allow it. */ | 281 | * polling so we'll allow it. |
277 | n = 32; | 282 | */ |
283 | n = 10; | ||
278 | break; | 284 | break; |
279 | } | 285 | } |
280 | } else if (usb_endpoint_xfer_isoc(d)) { | 286 | } else if (usb_endpoint_xfer_isoc(d)) { |
@@ -282,10 +288,10 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, | |||
282 | j = 16; | 288 | j = 16; |
283 | switch (to_usb_device(ddev)->speed) { | 289 | switch (to_usb_device(ddev)->speed) { |
284 | case USB_SPEED_HIGH: | 290 | case USB_SPEED_HIGH: |
285 | n = 9; /* 32 ms = 2^(9-1) uframes */ | 291 | n = 7; /* 8 ms = 2^(7-1) uframes */ |
286 | break; | 292 | break; |
287 | default: /* USB_SPEED_FULL */ | 293 | default: /* USB_SPEED_FULL */ |
288 | n = 6; /* 32 ms = 2^(6-1) frames */ | 294 | n = 4; /* 8 ms = 2^(4-1) frames */ |
289 | break; | 295 | break; |
290 | } | 296 | } |
291 | } | 297 | } |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e6a6d67c8705..09c8d9ca61ae 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -1709,11 +1709,17 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb | |||
1709 | as->urb->start_frame = uurb->start_frame; | 1709 | as->urb->start_frame = uurb->start_frame; |
1710 | as->urb->number_of_packets = number_of_packets; | 1710 | as->urb->number_of_packets = number_of_packets; |
1711 | as->urb->stream_id = stream_id; | 1711 | as->urb->stream_id = stream_id; |
1712 | if (uurb->type == USBDEVFS_URB_TYPE_ISO || | 1712 | |
1713 | ps->dev->speed == USB_SPEED_HIGH) | 1713 | if (ep->desc.bInterval) { |
1714 | as->urb->interval = 1 << min(15, ep->desc.bInterval - 1); | 1714 | if (uurb->type == USBDEVFS_URB_TYPE_ISO || |
1715 | else | 1715 | ps->dev->speed == USB_SPEED_HIGH || |
1716 | as->urb->interval = ep->desc.bInterval; | 1716 | ps->dev->speed >= USB_SPEED_SUPER) |
1717 | as->urb->interval = 1 << | ||
1718 | min(15, ep->desc.bInterval - 1); | ||
1719 | else | ||
1720 | as->urb->interval = ep->desc.bInterval; | ||
1721 | } | ||
1722 | |||
1717 | as->urb->context = as; | 1723 | as->urb->context = as; |
1718 | as->urb->complete = async_completed; | 1724 | as->urb->complete = async_completed; |
1719 | for (totlen = u = 0; u < number_of_packets; u++) { | 1725 | for (totlen = u = 0; u < number_of_packets; u++) { |
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 9fae0291cd69..d64551243789 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h | |||
@@ -868,6 +868,7 @@ struct dwc2_hsotg { | |||
868 | void *priv; | 868 | void *priv; |
869 | int irq; | 869 | int irq; |
870 | struct clk *clk; | 870 | struct clk *clk; |
871 | struct reset_control *reset; | ||
871 | 872 | ||
872 | unsigned int queuing_high_bandwidth:1; | 873 | unsigned int queuing_high_bandwidth:1; |
873 | unsigned int srp_success:1; | 874 | unsigned int srp_success:1; |
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index fc6f5251de5d..530959a8a6d1 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/platform_device.h> | 45 | #include <linux/platform_device.h> |
46 | #include <linux/phy/phy.h> | 46 | #include <linux/phy/phy.h> |
47 | #include <linux/platform_data/s3c-hsotg.h> | 47 | #include <linux/platform_data/s3c-hsotg.h> |
48 | #include <linux/reset.h> | ||
48 | 49 | ||
49 | #include <linux/usb/of.h> | 50 | #include <linux/usb/of.h> |
50 | 51 | ||
@@ -337,6 +338,24 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) | |||
337 | { | 338 | { |
338 | int i, ret; | 339 | int i, ret; |
339 | 340 | ||
341 | hsotg->reset = devm_reset_control_get_optional(hsotg->dev, "dwc2"); | ||
342 | if (IS_ERR(hsotg->reset)) { | ||
343 | ret = PTR_ERR(hsotg->reset); | ||
344 | switch (ret) { | ||
345 | case -ENOENT: | ||
346 | case -ENOTSUPP: | ||
347 | hsotg->reset = NULL; | ||
348 | break; | ||
349 | default: | ||
350 | dev_err(hsotg->dev, "error getting reset control %d\n", | ||
351 | ret); | ||
352 | return ret; | ||
353 | } | ||
354 | } | ||
355 | |||
356 | if (hsotg->reset) | ||
357 | reset_control_deassert(hsotg->reset); | ||
358 | |||
340 | /* Set default UTMI width */ | 359 | /* Set default UTMI width */ |
341 | hsotg->phyif = GUSBCFG_PHYIF16; | 360 | hsotg->phyif = GUSBCFG_PHYIF16; |
342 | 361 | ||
@@ -434,6 +453,9 @@ static int dwc2_driver_remove(struct platform_device *dev) | |||
434 | if (hsotg->ll_hw_enabled) | 453 | if (hsotg->ll_hw_enabled) |
435 | dwc2_lowlevel_hw_disable(hsotg); | 454 | dwc2_lowlevel_hw_disable(hsotg); |
436 | 455 | ||
456 | if (hsotg->reset) | ||
457 | reset_control_assert(hsotg->reset); | ||
458 | |||
437 | return 0; | 459 | return 0; |
438 | } | 460 | } |
439 | 461 | ||
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 946643157b78..35d092456bec 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
@@ -1192,6 +1192,7 @@ static int dwc3_runtime_resume(struct device *dev) | |||
1192 | } | 1192 | } |
1193 | 1193 | ||
1194 | pm_runtime_mark_last_busy(dev); | 1194 | pm_runtime_mark_last_busy(dev); |
1195 | pm_runtime_put(dev); | ||
1195 | 1196 | ||
1196 | return 0; | 1197 | return 0; |
1197 | } | 1198 | } |
diff --git a/drivers/usb/dwc3/debug.h b/drivers/usb/dwc3/debug.h index 22dfc3dd6a13..33ab2a203c1b 100644 --- a/drivers/usb/dwc3/debug.h +++ b/drivers/usb/dwc3/debug.h | |||
@@ -192,7 +192,7 @@ dwc3_ep_event_string(const struct dwc3_event_depevt *event) | |||
192 | int ret; | 192 | int ret; |
193 | 193 | ||
194 | ret = sprintf(str, "ep%d%s: ", epnum >> 1, | 194 | ret = sprintf(str, "ep%d%s: ", epnum >> 1, |
195 | (epnum & 1) ? "in" : "in"); | 195 | (epnum & 1) ? "in" : "out"); |
196 | if (ret < 0) | 196 | if (ret < 0) |
197 | return "UNKNOWN"; | 197 | return "UNKNOWN"; |
198 | 198 | ||
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 2eb84d6c24a6..6df0f5dad9a4 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c | |||
@@ -243,6 +243,15 @@ static int dwc3_pci_runtime_suspend(struct device *dev) | |||
243 | return -EBUSY; | 243 | return -EBUSY; |
244 | } | 244 | } |
245 | 245 | ||
246 | static int dwc3_pci_runtime_resume(struct device *dev) | ||
247 | { | ||
248 | struct platform_device *dwc3 = dev_get_drvdata(dev); | ||
249 | |||
250 | return pm_runtime_get(&dwc3->dev); | ||
251 | } | ||
252 | #endif /* CONFIG_PM */ | ||
253 | |||
254 | #ifdef CONFIG_PM_SLEEP | ||
246 | static int dwc3_pci_pm_dummy(struct device *dev) | 255 | static int dwc3_pci_pm_dummy(struct device *dev) |
247 | { | 256 | { |
248 | /* | 257 | /* |
@@ -255,11 +264,11 @@ static int dwc3_pci_pm_dummy(struct device *dev) | |||
255 | */ | 264 | */ |
256 | return 0; | 265 | return 0; |
257 | } | 266 | } |
258 | #endif /* CONFIG_PM */ | 267 | #endif /* CONFIG_PM_SLEEP */ |
259 | 268 | ||
260 | static struct dev_pm_ops dwc3_pci_dev_pm_ops = { | 269 | static struct dev_pm_ops dwc3_pci_dev_pm_ops = { |
261 | SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_pm_dummy, dwc3_pci_pm_dummy) | 270 | SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_pm_dummy, dwc3_pci_pm_dummy) |
262 | SET_RUNTIME_PM_OPS(dwc3_pci_runtime_suspend, dwc3_pci_pm_dummy, | 271 | SET_RUNTIME_PM_OPS(dwc3_pci_runtime_suspend, dwc3_pci_runtime_resume, |
263 | NULL) | 272 | NULL) |
264 | }; | 273 | }; |
265 | 274 | ||
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 1f5597ef945d..122e64df2f4d 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -1433,7 +1433,7 @@ static int dwc3_gadget_get_frame(struct usb_gadget *g) | |||
1433 | 1433 | ||
1434 | static int __dwc3_gadget_wakeup(struct dwc3 *dwc) | 1434 | static int __dwc3_gadget_wakeup(struct dwc3 *dwc) |
1435 | { | 1435 | { |
1436 | unsigned long timeout; | 1436 | int retries; |
1437 | 1437 | ||
1438 | int ret; | 1438 | int ret; |
1439 | u32 reg; | 1439 | u32 reg; |
@@ -1484,9 +1484,9 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc) | |||
1484 | } | 1484 | } |
1485 | 1485 | ||
1486 | /* poll until Link State changes to ON */ | 1486 | /* poll until Link State changes to ON */ |
1487 | timeout = jiffies + msecs_to_jiffies(100); | 1487 | retries = 20000; |
1488 | 1488 | ||
1489 | while (!time_after(jiffies, timeout)) { | 1489 | while (retries--) { |
1490 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); | 1490 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); |
1491 | 1491 | ||
1492 | /* in HS, means ON */ | 1492 | /* in HS, means ON */ |
diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c index d58bfc32be9e..007ec6e4a5d4 100644 --- a/drivers/usb/gadget/function/f_eem.c +++ b/drivers/usb/gadget/function/f_eem.c | |||
@@ -341,11 +341,15 @@ static struct sk_buff *eem_wrap(struct gether *port, struct sk_buff *skb) | |||
341 | { | 341 | { |
342 | struct sk_buff *skb2 = NULL; | 342 | struct sk_buff *skb2 = NULL; |
343 | struct usb_ep *in = port->in_ep; | 343 | struct usb_ep *in = port->in_ep; |
344 | int padlen = 0; | 344 | int headroom, tailroom, padlen = 0; |
345 | u16 len = skb->len; | 345 | u16 len; |
346 | 346 | ||
347 | int headroom = skb_headroom(skb); | 347 | if (!skb) |
348 | int tailroom = skb_tailroom(skb); | 348 | return NULL; |
349 | |||
350 | len = skb->len; | ||
351 | headroom = skb_headroom(skb); | ||
352 | tailroom = skb_tailroom(skb); | ||
349 | 353 | ||
350 | /* When (len + EEM_HLEN + ETH_FCS_LEN) % in->maxpacket) is 0, | 354 | /* When (len + EEM_HLEN + ETH_FCS_LEN) % in->maxpacket) is 0, |
351 | * stick two bytes of zero-length EEM packet on the end. | 355 | * stick two bytes of zero-length EEM packet on the end. |
diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index c8005823b190..16562e461121 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c | |||
@@ -374,6 +374,9 @@ static struct sk_buff *rndis_add_header(struct gether *port, | |||
374 | { | 374 | { |
375 | struct sk_buff *skb2; | 375 | struct sk_buff *skb2; |
376 | 376 | ||
377 | if (!skb) | ||
378 | return NULL; | ||
379 | |||
377 | skb2 = skb_realloc_headroom(skb, sizeof(struct rndis_packet_msg_type)); | 380 | skb2 = skb_realloc_headroom(skb, sizeof(struct rndis_packet_msg_type)); |
378 | rndis_add_hdr(skb2); | 381 | rndis_add_hdr(skb2); |
379 | 382 | ||
diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 6ded6345cd09..e0cd1e4c8892 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c | |||
@@ -375,10 +375,15 @@ __acquires(&port->port_lock) | |||
375 | */ | 375 | */ |
376 | { | 376 | { |
377 | struct list_head *pool = &port->write_pool; | 377 | struct list_head *pool = &port->write_pool; |
378 | struct usb_ep *in = port->port_usb->in; | 378 | struct usb_ep *in; |
379 | int status = 0; | 379 | int status = 0; |
380 | bool do_tty_wake = false; | 380 | bool do_tty_wake = false; |
381 | 381 | ||
382 | if (!port->port_usb) | ||
383 | return status; | ||
384 | |||
385 | in = port->port_usb->in; | ||
386 | |||
382 | while (!port->write_busy && !list_empty(pool)) { | 387 | while (!port->write_busy && !list_empty(pool)) { |
383 | struct usb_request *req; | 388 | struct usb_request *req; |
384 | int len; | 389 | int len; |
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 934f83881c30..40c04bb25f2f 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c | |||
@@ -827,7 +827,7 @@ void usb_gadget_unmap_request_by_dev(struct device *dev, | |||
827 | return; | 827 | return; |
828 | 828 | ||
829 | if (req->num_mapped_sgs) { | 829 | if (req->num_mapped_sgs) { |
830 | dma_unmap_sg(dev, req->sg, req->num_mapped_sgs, | 830 | dma_unmap_sg(dev, req->sg, req->num_sgs, |
831 | is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | 831 | is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); |
832 | 832 | ||
833 | req->num_mapped_sgs = 0; | 833 | req->num_mapped_sgs = 0; |
diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index cf8819a5c5b2..8bb011ea78f7 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c | |||
@@ -1878,11 +1878,8 @@ static int qe_get_frame(struct usb_gadget *gadget) | |||
1878 | 1878 | ||
1879 | tmp = in_be16(&udc->usb_param->frame_n); | 1879 | tmp = in_be16(&udc->usb_param->frame_n); |
1880 | if (tmp & 0x8000) | 1880 | if (tmp & 0x8000) |
1881 | tmp = tmp & 0x07ff; | 1881 | return tmp & 0x07ff; |
1882 | else | 1882 | return -EINVAL; |
1883 | tmp = -EINVAL; | ||
1884 | |||
1885 | return (int)tmp; | ||
1886 | } | 1883 | } |
1887 | 1884 | ||
1888 | static int fsl_qe_start(struct usb_gadget *gadget, | 1885 | static int fsl_qe_start(struct usb_gadget *gadget, |
diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 93a3bec81df7..fb8fc34827ab 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c | |||
@@ -106,6 +106,7 @@ | |||
106 | 106 | ||
107 | /* DRD_CON */ | 107 | /* DRD_CON */ |
108 | #define DRD_CON_PERI_CON BIT(24) | 108 | #define DRD_CON_PERI_CON BIT(24) |
109 | #define DRD_CON_VBOUT BIT(0) | ||
109 | 110 | ||
110 | /* USB_INT_ENA_1 and USB_INT_STA_1 */ | 111 | /* USB_INT_ENA_1 and USB_INT_STA_1 */ |
111 | #define USB_INT_1_B3_PLLWKUP BIT(31) | 112 | #define USB_INT_1_B3_PLLWKUP BIT(31) |
@@ -363,6 +364,7 @@ static void usb3_init_epc_registers(struct renesas_usb3 *usb3) | |||
363 | { | 364 | { |
364 | /* FIXME: How to change host / peripheral mode as well? */ | 365 | /* FIXME: How to change host / peripheral mode as well? */ |
365 | usb3_set_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON); | 366 | usb3_set_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON); |
367 | usb3_clear_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON); | ||
366 | 368 | ||
367 | usb3_write(usb3, ~0, USB3_USB_INT_STA_1); | 369 | usb3_write(usb3, ~0, USB3_USB_INT_STA_1); |
368 | usb3_enable_irq_1(usb3, USB_INT_1_VBUS_CNG); | 370 | usb3_enable_irq_1(usb3, USB_INT_1_VBUS_CNG); |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index fd9fd12e4861..797137e26549 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -850,6 +850,10 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) | |||
850 | spin_lock_irqsave(&xhci->lock, flags); | 850 | spin_lock_irqsave(&xhci->lock, flags); |
851 | 851 | ||
852 | ep->stop_cmds_pending--; | 852 | ep->stop_cmds_pending--; |
853 | if (xhci->xhc_state & XHCI_STATE_REMOVING) { | ||
854 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
855 | return; | ||
856 | } | ||
853 | if (xhci->xhc_state & XHCI_STATE_DYING) { | 857 | if (xhci->xhc_state & XHCI_STATE_DYING) { |
854 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | 858 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, |
855 | "Stop EP timer ran, but another timer marked " | 859 | "Stop EP timer ran, but another timer marked " |
@@ -903,7 +907,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) | |||
903 | spin_unlock_irqrestore(&xhci->lock, flags); | 907 | spin_unlock_irqrestore(&xhci->lock, flags); |
904 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | 908 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, |
905 | "Calling usb_hc_died()"); | 909 | "Calling usb_hc_died()"); |
906 | usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); | 910 | usb_hc_died(xhci_to_hcd(xhci)); |
907 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | 911 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, |
908 | "xHCI host controller is dead."); | 912 | "xHCI host controller is dead."); |
909 | } | 913 | } |
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 886526b5fcdd..73cfa13fc0dc 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
@@ -87,7 +87,7 @@ config USB_MUSB_DA8XX | |||
87 | config USB_MUSB_TUSB6010 | 87 | config USB_MUSB_TUSB6010 |
88 | tristate "TUSB6010" | 88 | tristate "TUSB6010" |
89 | depends on HAS_IOMEM | 89 | depends on HAS_IOMEM |
90 | depends on ARCH_OMAP2PLUS || COMPILE_TEST | 90 | depends on (ARCH_OMAP2PLUS || COMPILE_TEST) && !BLACKFIN |
91 | depends on NOP_USB_XCEIV = USB_MUSB_HDRC # both built-in or both modules | 91 | depends on NOP_USB_XCEIV = USB_MUSB_HDRC # both built-in or both modules |
92 | 92 | ||
93 | config USB_MUSB_OMAP2PLUS | 93 | config USB_MUSB_OMAP2PLUS |
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index 192248f974ec..fe08e776fec3 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c | |||
@@ -290,6 +290,7 @@ int musb_hub_control( | |||
290 | u32 temp; | 290 | u32 temp; |
291 | int retval = 0; | 291 | int retval = 0; |
292 | unsigned long flags; | 292 | unsigned long flags; |
293 | bool start_musb = false; | ||
293 | 294 | ||
294 | spin_lock_irqsave(&musb->lock, flags); | 295 | spin_lock_irqsave(&musb->lock, flags); |
295 | 296 | ||
@@ -390,7 +391,7 @@ int musb_hub_control( | |||
390 | * logic relating to VBUS power-up. | 391 | * logic relating to VBUS power-up. |
391 | */ | 392 | */ |
392 | if (!hcd->self.is_b_host && musb_has_gadget(musb)) | 393 | if (!hcd->self.is_b_host && musb_has_gadget(musb)) |
393 | musb_start(musb); | 394 | start_musb = true; |
394 | break; | 395 | break; |
395 | case USB_PORT_FEAT_RESET: | 396 | case USB_PORT_FEAT_RESET: |
396 | musb_port_reset(musb, true); | 397 | musb_port_reset(musb, true); |
@@ -451,5 +452,9 @@ error: | |||
451 | retval = -EPIPE; | 452 | retval = -EPIPE; |
452 | } | 453 | } |
453 | spin_unlock_irqrestore(&musb->lock, flags); | 454 | spin_unlock_irqrestore(&musb->lock, flags); |
455 | |||
456 | if (start_musb) | ||
457 | musb_start(musb); | ||
458 | |||
454 | return retval; | 459 | return retval; |
455 | } | 460 | } |
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index 980c9dee09eb..427efb5eebae 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c | |||
@@ -144,14 +144,18 @@ static irqreturn_t nop_gpio_vbus_thread(int irq, void *data) | |||
144 | int usb_gen_phy_init(struct usb_phy *phy) | 144 | int usb_gen_phy_init(struct usb_phy *phy) |
145 | { | 145 | { |
146 | struct usb_phy_generic *nop = dev_get_drvdata(phy->dev); | 146 | struct usb_phy_generic *nop = dev_get_drvdata(phy->dev); |
147 | int ret; | ||
147 | 148 | ||
148 | if (!IS_ERR(nop->vcc)) { | 149 | if (!IS_ERR(nop->vcc)) { |
149 | if (regulator_enable(nop->vcc)) | 150 | if (regulator_enable(nop->vcc)) |
150 | dev_err(phy->dev, "Failed to enable power\n"); | 151 | dev_err(phy->dev, "Failed to enable power\n"); |
151 | } | 152 | } |
152 | 153 | ||
153 | if (!IS_ERR(nop->clk)) | 154 | if (!IS_ERR(nop->clk)) { |
154 | clk_prepare_enable(nop->clk); | 155 | ret = clk_prepare_enable(nop->clk); |
156 | if (ret) | ||
157 | return ret; | ||
158 | } | ||
155 | 159 | ||
156 | nop_reset(nop); | 160 | nop_reset(nop); |
157 | 161 | ||
diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index d4be5d594896..28965ef4f824 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c | |||
@@ -282,9 +282,16 @@ static irqreturn_t usbhs_interrupt(int irq, void *data) | |||
282 | if (usbhs_mod_is_host(priv)) | 282 | if (usbhs_mod_is_host(priv)) |
283 | usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC); | 283 | usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC); |
284 | 284 | ||
285 | usbhs_write(priv, BRDYSTS, ~irq_state.brdysts); | 285 | /* |
286 | * The driver should not clear the xxxSTS after the line of | ||
287 | * "call irq callback functions" because each "if" statement is | ||
288 | * possible to call the callback function for avoiding any side effects. | ||
289 | */ | ||
290 | if (irq_state.intsts0 & BRDY) | ||
291 | usbhs_write(priv, BRDYSTS, ~irq_state.brdysts); | ||
286 | usbhs_write(priv, NRDYSTS, ~irq_state.nrdysts); | 292 | usbhs_write(priv, NRDYSTS, ~irq_state.nrdysts); |
287 | usbhs_write(priv, BEMPSTS, ~irq_state.bempsts); | 293 | if (irq_state.intsts0 & BEMP) |
294 | usbhs_write(priv, BEMPSTS, ~irq_state.bempsts); | ||
288 | 295 | ||
289 | /* | 296 | /* |
290 | * call irq callback functions | 297 | * call irq callback functions |
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 92bc83b92d10..c4c64740a3e7 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
@@ -1076,7 +1076,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) | |||
1076 | 1076 | ||
1077 | gpriv->transceiver = usb_get_phy(USB_PHY_TYPE_UNDEFINED); | 1077 | gpriv->transceiver = usb_get_phy(USB_PHY_TYPE_UNDEFINED); |
1078 | dev_info(dev, "%stransceiver found\n", | 1078 | dev_info(dev, "%stransceiver found\n", |
1079 | gpriv->transceiver ? "" : "no "); | 1079 | !IS_ERR(gpriv->transceiver) ? "" : "no "); |
1080 | 1080 | ||
1081 | /* | 1081 | /* |
1082 | * CAUTION | 1082 | * CAUTION |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 5608af4a369d..de9992b492b0 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -1252,7 +1252,7 @@ static int mos7720_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1252 | 1252 | ||
1253 | if (urb->transfer_buffer == NULL) { | 1253 | if (urb->transfer_buffer == NULL) { |
1254 | urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, | 1254 | urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, |
1255 | GFP_KERNEL); | 1255 | GFP_ATOMIC); |
1256 | if (!urb->transfer_buffer) | 1256 | if (!urb->transfer_buffer) |
1257 | goto exit; | 1257 | goto exit; |
1258 | } | 1258 | } |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index ed378fb232e7..57426d703a09 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -1340,8 +1340,8 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1340 | } | 1340 | } |
1341 | 1341 | ||
1342 | if (urb->transfer_buffer == NULL) { | 1342 | if (urb->transfer_buffer == NULL) { |
1343 | urb->transfer_buffer = | 1343 | urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, |
1344 | kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); | 1344 | GFP_ATOMIC); |
1345 | if (!urb->transfer_buffer) | 1345 | if (!urb->transfer_buffer) |
1346 | goto exit; | 1346 | goto exit; |
1347 | } | 1347 | } |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index bc472584a229..9894e341c6ac 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -525,6 +525,12 @@ static void option_instat_callback(struct urb *urb); | |||
525 | #define VIATELECOM_VENDOR_ID 0x15eb | 525 | #define VIATELECOM_VENDOR_ID 0x15eb |
526 | #define VIATELECOM_PRODUCT_CDS7 0x0001 | 526 | #define VIATELECOM_PRODUCT_CDS7 0x0001 |
527 | 527 | ||
528 | /* WeTelecom products */ | ||
529 | #define WETELECOM_VENDOR_ID 0x22de | ||
530 | #define WETELECOM_PRODUCT_WMD200 0x6801 | ||
531 | #define WETELECOM_PRODUCT_6802 0x6802 | ||
532 | #define WETELECOM_PRODUCT_WMD300 0x6803 | ||
533 | |||
528 | struct option_blacklist_info { | 534 | struct option_blacklist_info { |
529 | /* bitmask of interface numbers blacklisted for send_setup */ | 535 | /* bitmask of interface numbers blacklisted for send_setup */ |
530 | const unsigned long sendsetup; | 536 | const unsigned long sendsetup; |
@@ -1991,6 +1997,9 @@ static const struct usb_device_id option_ids[] = { | |||
1991 | { USB_DEVICE_INTERFACE_CLASS(0x2020, 0x4000, 0xff) }, /* OLICARD300 - MT6225 */ | 1997 | { USB_DEVICE_INTERFACE_CLASS(0x2020, 0x4000, 0xff) }, /* OLICARD300 - MT6225 */ |
1992 | { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) }, | 1998 | { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) }, |
1993 | { USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) }, | 1999 | { USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) }, |
2000 | { USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_WMD200, 0xff, 0xff, 0xff) }, | ||
2001 | { USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_6802, 0xff, 0xff, 0xff) }, | ||
2002 | { USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_WMD300, 0xff, 0xff, 0xff) }, | ||
1994 | { } /* Terminating entry */ | 2003 | { } /* Terminating entry */ |
1995 | }; | 2004 | }; |
1996 | MODULE_DEVICE_TABLE(usb, option_ids); | 2005 | MODULE_DEVICE_TABLE(usb, option_ids); |
diff --git a/drivers/usb/serial/usb-serial-simple.c b/drivers/usb/serial/usb-serial-simple.c index a204782ae530..e98b6e57b703 100644 --- a/drivers/usb/serial/usb-serial-simple.c +++ b/drivers/usb/serial/usb-serial-simple.c | |||
@@ -54,7 +54,8 @@ DEVICE(funsoft, FUNSOFT_IDS); | |||
54 | /* Infineon Flashloader driver */ | 54 | /* Infineon Flashloader driver */ |
55 | #define FLASHLOADER_IDS() \ | 55 | #define FLASHLOADER_IDS() \ |
56 | { USB_DEVICE_INTERFACE_CLASS(0x058b, 0x0041, USB_CLASS_CDC_DATA) }, \ | 56 | { USB_DEVICE_INTERFACE_CLASS(0x058b, 0x0041, USB_CLASS_CDC_DATA) }, \ |
57 | { USB_DEVICE(0x8087, 0x0716) } | 57 | { USB_DEVICE(0x8087, 0x0716) }, \ |
58 | { USB_DEVICE(0x8087, 0x0801) } | ||
58 | DEVICE(flashloader, FLASHLOADER_IDS); | 59 | DEVICE(flashloader, FLASHLOADER_IDS); |
59 | 60 | ||
60 | /* Google Serial USB SubClass */ | 61 | /* Google Serial USB SubClass */ |
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 9d6320e8ff3e..6e29d053843d 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c | |||
@@ -88,7 +88,7 @@ struct vhost_scsi_cmd { | |||
88 | struct scatterlist *tvc_prot_sgl; | 88 | struct scatterlist *tvc_prot_sgl; |
89 | struct page **tvc_upages; | 89 | struct page **tvc_upages; |
90 | /* Pointer to response header iovec */ | 90 | /* Pointer to response header iovec */ |
91 | struct iovec *tvc_resp_iov; | 91 | struct iovec tvc_resp_iov; |
92 | /* Pointer to vhost_scsi for our device */ | 92 | /* Pointer to vhost_scsi for our device */ |
93 | struct vhost_scsi *tvc_vhost; | 93 | struct vhost_scsi *tvc_vhost; |
94 | /* Pointer to vhost_virtqueue for the cmd */ | 94 | /* Pointer to vhost_virtqueue for the cmd */ |
@@ -547,7 +547,7 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work) | |||
547 | memcpy(v_rsp.sense, cmd->tvc_sense_buf, | 547 | memcpy(v_rsp.sense, cmd->tvc_sense_buf, |
548 | se_cmd->scsi_sense_length); | 548 | se_cmd->scsi_sense_length); |
549 | 549 | ||
550 | iov_iter_init(&iov_iter, READ, cmd->tvc_resp_iov, | 550 | iov_iter_init(&iov_iter, READ, &cmd->tvc_resp_iov, |
551 | cmd->tvc_in_iovs, sizeof(v_rsp)); | 551 | cmd->tvc_in_iovs, sizeof(v_rsp)); |
552 | ret = copy_to_iter(&v_rsp, sizeof(v_rsp), &iov_iter); | 552 | ret = copy_to_iter(&v_rsp, sizeof(v_rsp), &iov_iter); |
553 | if (likely(ret == sizeof(v_rsp))) { | 553 | if (likely(ret == sizeof(v_rsp))) { |
@@ -1044,7 +1044,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) | |||
1044 | } | 1044 | } |
1045 | cmd->tvc_vhost = vs; | 1045 | cmd->tvc_vhost = vs; |
1046 | cmd->tvc_vq = vq; | 1046 | cmd->tvc_vq = vq; |
1047 | cmd->tvc_resp_iov = &vq->iov[out]; | 1047 | cmd->tvc_resp_iov = vq->iov[out]; |
1048 | cmd->tvc_in_iovs = in; | 1048 | cmd->tvc_in_iovs = in; |
1049 | 1049 | ||
1050 | pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n", | 1050 | pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n", |
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index e383ecdaca59..ed9c9eeedfe5 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
@@ -167,7 +167,7 @@ static bool vring_use_dma_api(struct virtio_device *vdev) | |||
167 | * making all of the arch DMA ops work on the vring device itself | 167 | * making all of the arch DMA ops work on the vring device itself |
168 | * is a mess. For now, we use the parent device for DMA ops. | 168 | * is a mess. For now, we use the parent device for DMA ops. |
169 | */ | 169 | */ |
170 | struct device *vring_dma_dev(const struct vring_virtqueue *vq) | 170 | static struct device *vring_dma_dev(const struct vring_virtqueue *vq) |
171 | { | 171 | { |
172 | return vq->vq.vdev->dev.parent; | 172 | return vq->vq.vdev->dev.parent; |
173 | } | 173 | } |
diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c index 7487971f9f78..c1010f018bd8 100644 --- a/drivers/xen/xenbus/xenbus_dev_frontend.c +++ b/drivers/xen/xenbus/xenbus_dev_frontend.c | |||
@@ -316,7 +316,7 @@ static int xenbus_write_transaction(unsigned msg_type, | |||
316 | rc = -ENOMEM; | 316 | rc = -ENOMEM; |
317 | goto out; | 317 | goto out; |
318 | } | 318 | } |
319 | } else { | 319 | } else if (msg_type == XS_TRANSACTION_END) { |
320 | list_for_each_entry(trans, &u->transactions, list) | 320 | list_for_each_entry(trans, &u->transactions, list) |
321 | if (trans->handle.id == u->u.msg.tx_id) | 321 | if (trans->handle.id == u->u.msg.tx_id) |
322 | break; | 322 | break; |
@@ -239,7 +239,12 @@ static struct dentry *aio_mount(struct file_system_type *fs_type, | |||
239 | static const struct dentry_operations ops = { | 239 | static const struct dentry_operations ops = { |
240 | .d_dname = simple_dname, | 240 | .d_dname = simple_dname, |
241 | }; | 241 | }; |
242 | return mount_pseudo(fs_type, "aio:", NULL, &ops, AIO_RING_MAGIC); | 242 | struct dentry *root = mount_pseudo(fs_type, "aio:", NULL, &ops, |
243 | AIO_RING_MAGIC); | ||
244 | |||
245 | if (!IS_ERR(root)) | ||
246 | root->d_sb->s_iflags |= SB_I_NOEXEC; | ||
247 | return root; | ||
243 | } | 248 | } |
244 | 249 | ||
245 | /* aio_setup | 250 | /* aio_setup |
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index b493909e7492..d8e6d421c27f 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c | |||
@@ -417,6 +417,7 @@ static struct dentry *should_expire(struct dentry *dentry, | |||
417 | } | 417 | } |
418 | return NULL; | 418 | return NULL; |
419 | } | 419 | } |
420 | |||
420 | /* | 421 | /* |
421 | * Find an eligible tree to time-out | 422 | * Find an eligible tree to time-out |
422 | * A tree is eligible if :- | 423 | * A tree is eligible if :- |
@@ -432,6 +433,7 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb, | |||
432 | struct dentry *root = sb->s_root; | 433 | struct dentry *root = sb->s_root; |
433 | struct dentry *dentry; | 434 | struct dentry *dentry; |
434 | struct dentry *expired; | 435 | struct dentry *expired; |
436 | struct dentry *found; | ||
435 | struct autofs_info *ino; | 437 | struct autofs_info *ino; |
436 | 438 | ||
437 | if (!root) | 439 | if (!root) |
@@ -442,31 +444,46 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb, | |||
442 | 444 | ||
443 | dentry = NULL; | 445 | dentry = NULL; |
444 | while ((dentry = get_next_positive_subdir(dentry, root))) { | 446 | while ((dentry = get_next_positive_subdir(dentry, root))) { |
447 | int flags = how; | ||
448 | |||
445 | spin_lock(&sbi->fs_lock); | 449 | spin_lock(&sbi->fs_lock); |
446 | ino = autofs4_dentry_ino(dentry); | 450 | ino = autofs4_dentry_ino(dentry); |
447 | if (ino->flags & AUTOFS_INF_WANT_EXPIRE) | 451 | if (ino->flags & AUTOFS_INF_WANT_EXPIRE) { |
448 | expired = NULL; | ||
449 | else | ||
450 | expired = should_expire(dentry, mnt, timeout, how); | ||
451 | if (!expired) { | ||
452 | spin_unlock(&sbi->fs_lock); | 452 | spin_unlock(&sbi->fs_lock); |
453 | continue; | 453 | continue; |
454 | } | 454 | } |
455 | spin_unlock(&sbi->fs_lock); | ||
456 | |||
457 | expired = should_expire(dentry, mnt, timeout, flags); | ||
458 | if (!expired) | ||
459 | continue; | ||
460 | |||
461 | spin_lock(&sbi->fs_lock); | ||
455 | ino = autofs4_dentry_ino(expired); | 462 | ino = autofs4_dentry_ino(expired); |
456 | ino->flags |= AUTOFS_INF_WANT_EXPIRE; | 463 | ino->flags |= AUTOFS_INF_WANT_EXPIRE; |
457 | spin_unlock(&sbi->fs_lock); | 464 | spin_unlock(&sbi->fs_lock); |
458 | synchronize_rcu(); | 465 | synchronize_rcu(); |
459 | spin_lock(&sbi->fs_lock); | ||
460 | if (should_expire(expired, mnt, timeout, how)) { | ||
461 | if (expired != dentry) | ||
462 | dput(dentry); | ||
463 | goto found; | ||
464 | } | ||
465 | 466 | ||
467 | /* Make sure a reference is not taken on found if | ||
468 | * things have changed. | ||
469 | */ | ||
470 | flags &= ~AUTOFS_EXP_LEAVES; | ||
471 | found = should_expire(expired, mnt, timeout, how); | ||
472 | if (!found || found != expired) | ||
473 | /* Something has changed, continue */ | ||
474 | goto next; | ||
475 | |||
476 | if (expired != dentry) | ||
477 | dput(dentry); | ||
478 | |||
479 | spin_lock(&sbi->fs_lock); | ||
480 | goto found; | ||
481 | next: | ||
482 | spin_lock(&sbi->fs_lock); | ||
466 | ino->flags &= ~AUTOFS_INF_WANT_EXPIRE; | 483 | ino->flags &= ~AUTOFS_INF_WANT_EXPIRE; |
484 | spin_unlock(&sbi->fs_lock); | ||
467 | if (expired != dentry) | 485 | if (expired != dentry) |
468 | dput(expired); | 486 | dput(expired); |
469 | spin_unlock(&sbi->fs_lock); | ||
470 | } | 487 | } |
471 | return NULL; | 488 | return NULL; |
472 | 489 | ||
@@ -483,6 +500,7 @@ int autofs4_expire_wait(struct dentry *dentry, int rcu_walk) | |||
483 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | 500 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
484 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | 501 | struct autofs_info *ino = autofs4_dentry_ino(dentry); |
485 | int status; | 502 | int status; |
503 | int state; | ||
486 | 504 | ||
487 | /* Block on any pending expire */ | 505 | /* Block on any pending expire */ |
488 | if (!(ino->flags & AUTOFS_INF_WANT_EXPIRE)) | 506 | if (!(ino->flags & AUTOFS_INF_WANT_EXPIRE)) |
@@ -490,8 +508,19 @@ int autofs4_expire_wait(struct dentry *dentry, int rcu_walk) | |||
490 | if (rcu_walk) | 508 | if (rcu_walk) |
491 | return -ECHILD; | 509 | return -ECHILD; |
492 | 510 | ||
511 | retry: | ||
493 | spin_lock(&sbi->fs_lock); | 512 | spin_lock(&sbi->fs_lock); |
494 | if (ino->flags & AUTOFS_INF_EXPIRING) { | 513 | state = ino->flags & (AUTOFS_INF_WANT_EXPIRE | AUTOFS_INF_EXPIRING); |
514 | if (state == AUTOFS_INF_WANT_EXPIRE) { | ||
515 | spin_unlock(&sbi->fs_lock); | ||
516 | /* | ||
517 | * Possibly being selected for expire, wait until | ||
518 | * it's selected or not. | ||
519 | */ | ||
520 | schedule_timeout_uninterruptible(HZ/10); | ||
521 | goto retry; | ||
522 | } | ||
523 | if (state & AUTOFS_INF_EXPIRING) { | ||
495 | spin_unlock(&sbi->fs_lock); | 524 | spin_unlock(&sbi->fs_lock); |
496 | 525 | ||
497 | pr_debug("waiting for expire %p name=%pd\n", dentry, dentry); | 526 | pr_debug("waiting for expire %p name=%pd\n", dentry, dentry); |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 7f6aff3f72eb..e5495f37c6ed 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -853,6 +853,7 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
853 | current->flags |= PF_RANDOMIZE; | 853 | current->flags |= PF_RANDOMIZE; |
854 | 854 | ||
855 | setup_new_exec(bprm); | 855 | setup_new_exec(bprm); |
856 | install_exec_creds(bprm); | ||
856 | 857 | ||
857 | /* Do this so that we can load the interpreter, if need be. We will | 858 | /* Do this so that we can load the interpreter, if need be. We will |
858 | change some of these later */ | 859 | change some of these later */ |
@@ -1044,7 +1045,6 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
1044 | goto out; | 1045 | goto out; |
1045 | #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */ | 1046 | #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */ |
1046 | 1047 | ||
1047 | install_exec_creds(bprm); | ||
1048 | retval = create_elf_tables(bprm, &loc->elf_ex, | 1048 | retval = create_elf_tables(bprm, &loc->elf_ex, |
1049 | load_addr, interp_load_addr); | 1049 | load_addr, interp_load_addr); |
1050 | if (retval < 0) | 1050 | if (retval < 0) |
diff --git a/fs/block_dev.c b/fs/block_dev.c index c3cdde87cc8c..08ae99343d92 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -249,7 +249,8 @@ struct super_block *freeze_bdev(struct block_device *bdev) | |||
249 | * thaw_bdev drops it. | 249 | * thaw_bdev drops it. |
250 | */ | 250 | */ |
251 | sb = get_super(bdev); | 251 | sb = get_super(bdev); |
252 | drop_super(sb); | 252 | if (sb) |
253 | drop_super(sb); | ||
253 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 254 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
254 | return sb; | 255 | return sb; |
255 | } | 256 | } |
@@ -646,7 +647,7 @@ static struct dentry *bd_mount(struct file_system_type *fs_type, | |||
646 | { | 647 | { |
647 | struct dentry *dent; | 648 | struct dentry *dent; |
648 | dent = mount_pseudo(fs_type, "bdev:", &bdev_sops, NULL, BDEVFS_MAGIC); | 649 | dent = mount_pseudo(fs_type, "bdev:", &bdev_sops, NULL, BDEVFS_MAGIC); |
649 | if (dent) | 650 | if (!IS_ERR(dent)) |
650 | dent->d_sb->s_iflags |= SB_I_CGROUPWB; | 651 | dent->d_sb->s_iflags |= SB_I_CGROUPWB; |
651 | return dent; | 652 | return dent; |
652 | } | 653 | } |
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 2b88439c2ee8..455a6b2fd539 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
@@ -589,6 +589,7 @@ static void __merge_refs(struct list_head *head, int mode) | |||
589 | 589 | ||
590 | list_del(&ref2->list); | 590 | list_del(&ref2->list); |
591 | kmem_cache_free(btrfs_prelim_ref_cache, ref2); | 591 | kmem_cache_free(btrfs_prelim_ref_cache, ref2); |
592 | cond_resched(); | ||
592 | } | 593 | } |
593 | 594 | ||
594 | } | 595 | } |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 2fe8f89091a3..33fe03551105 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -427,6 +427,7 @@ struct btrfs_space_info { | |||
427 | struct list_head ro_bgs; | 427 | struct list_head ro_bgs; |
428 | struct list_head priority_tickets; | 428 | struct list_head priority_tickets; |
429 | struct list_head tickets; | 429 | struct list_head tickets; |
430 | u64 tickets_id; | ||
430 | 431 | ||
431 | struct rw_semaphore groups_sem; | 432 | struct rw_semaphore groups_sem; |
432 | /* for block groups in our same type */ | 433 | /* for block groups in our same type */ |
@@ -1028,6 +1029,7 @@ struct btrfs_fs_info { | |||
1028 | struct btrfs_workqueue *qgroup_rescan_workers; | 1029 | struct btrfs_workqueue *qgroup_rescan_workers; |
1029 | struct completion qgroup_rescan_completion; | 1030 | struct completion qgroup_rescan_completion; |
1030 | struct btrfs_work qgroup_rescan_work; | 1031 | struct btrfs_work qgroup_rescan_work; |
1032 | bool qgroup_rescan_running; /* protected by qgroup_rescan_lock */ | ||
1031 | 1033 | ||
1032 | /* filesystem state */ | 1034 | /* filesystem state */ |
1033 | unsigned long fs_state; | 1035 | unsigned long fs_state; |
@@ -1079,6 +1081,8 @@ struct btrfs_fs_info { | |||
1079 | struct list_head pinned_chunks; | 1081 | struct list_head pinned_chunks; |
1080 | 1082 | ||
1081 | int creating_free_space_tree; | 1083 | int creating_free_space_tree; |
1084 | /* Used to record internally whether fs has been frozen */ | ||
1085 | int fs_frozen; | ||
1082 | }; | 1086 | }; |
1083 | 1087 | ||
1084 | struct btrfs_subvolume_writers { | 1088 | struct btrfs_subvolume_writers { |
@@ -2578,7 +2582,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, | |||
2578 | struct btrfs_root *root, | 2582 | struct btrfs_root *root, |
2579 | u64 root_objectid, u64 owner, u64 offset, | 2583 | u64 root_objectid, u64 owner, u64 offset, |
2580 | struct btrfs_key *ins); | 2584 | struct btrfs_key *ins); |
2581 | int btrfs_reserve_extent(struct btrfs_root *root, u64 num_bytes, | 2585 | int btrfs_reserve_extent(struct btrfs_root *root, u64 ram_bytes, u64 num_bytes, |
2582 | u64 min_alloc_size, u64 empty_size, u64 hint_byte, | 2586 | u64 min_alloc_size, u64 empty_size, u64 hint_byte, |
2583 | struct btrfs_key *ins, int is_data, int delalloc); | 2587 | struct btrfs_key *ins, int is_data, int delalloc); |
2584 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 2588 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c index d9ddcfc18c91..ac02e041464b 100644 --- a/fs/btrfs/delayed-ref.c +++ b/fs/btrfs/delayed-ref.c | |||
@@ -541,7 +541,6 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info, | |||
541 | struct btrfs_delayed_ref_head *existing; | 541 | struct btrfs_delayed_ref_head *existing; |
542 | struct btrfs_delayed_ref_head *head_ref = NULL; | 542 | struct btrfs_delayed_ref_head *head_ref = NULL; |
543 | struct btrfs_delayed_ref_root *delayed_refs; | 543 | struct btrfs_delayed_ref_root *delayed_refs; |
544 | struct btrfs_qgroup_extent_record *qexisting; | ||
545 | int count_mod = 1; | 544 | int count_mod = 1; |
546 | int must_insert_reserved = 0; | 545 | int must_insert_reserved = 0; |
547 | 546 | ||
@@ -606,10 +605,8 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info, | |||
606 | qrecord->num_bytes = num_bytes; | 605 | qrecord->num_bytes = num_bytes; |
607 | qrecord->old_roots = NULL; | 606 | qrecord->old_roots = NULL; |
608 | 607 | ||
609 | qexisting = btrfs_qgroup_insert_dirty_extent(fs_info, | 608 | if(btrfs_qgroup_insert_dirty_extent_nolock(fs_info, |
610 | delayed_refs, | 609 | delayed_refs, qrecord)) |
611 | qrecord); | ||
612 | if (qexisting) | ||
613 | kfree(qrecord); | 610 | kfree(qrecord); |
614 | } | 611 | } |
615 | 612 | ||
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 59febfb8d04a..54bc8c7c6bcd 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -559,8 +559,29 @@ static noinline int check_leaf(struct btrfs_root *root, | |||
559 | u32 nritems = btrfs_header_nritems(leaf); | 559 | u32 nritems = btrfs_header_nritems(leaf); |
560 | int slot; | 560 | int slot; |
561 | 561 | ||
562 | if (nritems == 0) | 562 | if (nritems == 0) { |
563 | struct btrfs_root *check_root; | ||
564 | |||
565 | key.objectid = btrfs_header_owner(leaf); | ||
566 | key.type = BTRFS_ROOT_ITEM_KEY; | ||
567 | key.offset = (u64)-1; | ||
568 | |||
569 | check_root = btrfs_get_fs_root(root->fs_info, &key, false); | ||
570 | /* | ||
571 | * The only reason we also check NULL here is that during | ||
572 | * open_ctree() some roots has not yet been set up. | ||
573 | */ | ||
574 | if (!IS_ERR_OR_NULL(check_root)) { | ||
575 | /* if leaf is the root, then it's fine */ | ||
576 | if (leaf->start != | ||
577 | btrfs_root_bytenr(&check_root->root_item)) { | ||
578 | CORRUPT("non-root leaf's nritems is 0", | ||
579 | leaf, root, 0); | ||
580 | return -EIO; | ||
581 | } | ||
582 | } | ||
563 | return 0; | 583 | return 0; |
584 | } | ||
564 | 585 | ||
565 | /* Check the 0 item */ | 586 | /* Check the 0 item */ |
566 | if (btrfs_item_offset_nr(leaf, 0) + btrfs_item_size_nr(leaf, 0) != | 587 | if (btrfs_item_offset_nr(leaf, 0) + btrfs_item_size_nr(leaf, 0) != |
@@ -612,6 +633,19 @@ static noinline int check_leaf(struct btrfs_root *root, | |||
612 | return 0; | 633 | return 0; |
613 | } | 634 | } |
614 | 635 | ||
636 | static int check_node(struct btrfs_root *root, struct extent_buffer *node) | ||
637 | { | ||
638 | unsigned long nr = btrfs_header_nritems(node); | ||
639 | |||
640 | if (nr == 0 || nr > BTRFS_NODEPTRS_PER_BLOCK(root)) { | ||
641 | btrfs_crit(root->fs_info, | ||
642 | "corrupt node: block %llu root %llu nritems %lu", | ||
643 | node->start, root->objectid, nr); | ||
644 | return -EIO; | ||
645 | } | ||
646 | return 0; | ||
647 | } | ||
648 | |||
615 | static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio, | 649 | static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio, |
616 | u64 phy_offset, struct page *page, | 650 | u64 phy_offset, struct page *page, |
617 | u64 start, u64 end, int mirror) | 651 | u64 start, u64 end, int mirror) |
@@ -682,6 +716,9 @@ static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio, | |||
682 | ret = -EIO; | 716 | ret = -EIO; |
683 | } | 717 | } |
684 | 718 | ||
719 | if (found_level > 0 && check_node(root, eb)) | ||
720 | ret = -EIO; | ||
721 | |||
685 | if (!ret) | 722 | if (!ret) |
686 | set_extent_buffer_uptodate(eb); | 723 | set_extent_buffer_uptodate(eb); |
687 | err: | 724 | err: |
@@ -1618,8 +1655,8 @@ fail: | |||
1618 | return ret; | 1655 | return ret; |
1619 | } | 1656 | } |
1620 | 1657 | ||
1621 | static struct btrfs_root *btrfs_lookup_fs_root(struct btrfs_fs_info *fs_info, | 1658 | struct btrfs_root *btrfs_lookup_fs_root(struct btrfs_fs_info *fs_info, |
1622 | u64 root_id) | 1659 | u64 root_id) |
1623 | { | 1660 | { |
1624 | struct btrfs_root *root; | 1661 | struct btrfs_root *root; |
1625 | 1662 | ||
@@ -2298,6 +2335,7 @@ static void btrfs_init_qgroup(struct btrfs_fs_info *fs_info) | |||
2298 | fs_info->quota_enabled = 0; | 2335 | fs_info->quota_enabled = 0; |
2299 | fs_info->pending_quota_state = 0; | 2336 | fs_info->pending_quota_state = 0; |
2300 | fs_info->qgroup_ulist = NULL; | 2337 | fs_info->qgroup_ulist = NULL; |
2338 | fs_info->qgroup_rescan_running = false; | ||
2301 | mutex_init(&fs_info->qgroup_rescan_lock); | 2339 | mutex_init(&fs_info->qgroup_rescan_lock); |
2302 | } | 2340 | } |
2303 | 2341 | ||
@@ -2624,6 +2662,7 @@ int open_ctree(struct super_block *sb, | |||
2624 | atomic_set(&fs_info->qgroup_op_seq, 0); | 2662 | atomic_set(&fs_info->qgroup_op_seq, 0); |
2625 | atomic_set(&fs_info->reada_works_cnt, 0); | 2663 | atomic_set(&fs_info->reada_works_cnt, 0); |
2626 | atomic64_set(&fs_info->tree_mod_seq, 0); | 2664 | atomic64_set(&fs_info->tree_mod_seq, 0); |
2665 | fs_info->fs_frozen = 0; | ||
2627 | fs_info->sb = sb; | 2666 | fs_info->sb = sb; |
2628 | fs_info->max_inline = BTRFS_DEFAULT_MAX_INLINE; | 2667 | fs_info->max_inline = BTRFS_DEFAULT_MAX_INLINE; |
2629 | fs_info->metadata_ratio = 0; | 2668 | fs_info->metadata_ratio = 0; |
@@ -3739,8 +3778,15 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info, | |||
3739 | if (btrfs_root_refs(&root->root_item) == 0) | 3778 | if (btrfs_root_refs(&root->root_item) == 0) |
3740 | synchronize_srcu(&fs_info->subvol_srcu); | 3779 | synchronize_srcu(&fs_info->subvol_srcu); |
3741 | 3780 | ||
3742 | if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) | 3781 | if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) { |
3743 | btrfs_free_log(NULL, root); | 3782 | btrfs_free_log(NULL, root); |
3783 | if (root->reloc_root) { | ||
3784 | free_extent_buffer(root->reloc_root->node); | ||
3785 | free_extent_buffer(root->reloc_root->commit_root); | ||
3786 | btrfs_put_fs_root(root->reloc_root); | ||
3787 | root->reloc_root = NULL; | ||
3788 | } | ||
3789 | } | ||
3744 | 3790 | ||
3745 | if (root->free_ino_pinned) | 3791 | if (root->free_ino_pinned) |
3746 | __btrfs_remove_free_space_cache(root->free_ino_pinned); | 3792 | __btrfs_remove_free_space_cache(root->free_ino_pinned); |
@@ -3851,7 +3897,7 @@ void close_ctree(struct btrfs_root *root) | |||
3851 | smp_mb(); | 3897 | smp_mb(); |
3852 | 3898 | ||
3853 | /* wait for the qgroup rescan worker to stop */ | 3899 | /* wait for the qgroup rescan worker to stop */ |
3854 | btrfs_qgroup_wait_for_completion(fs_info); | 3900 | btrfs_qgroup_wait_for_completion(fs_info, false); |
3855 | 3901 | ||
3856 | /* wait for the uuid_scan task to finish */ | 3902 | /* wait for the uuid_scan task to finish */ |
3857 | down(&fs_info->uuid_tree_rescan_sem); | 3903 | down(&fs_info->uuid_tree_rescan_sem); |
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index b3207a0e09f7..f19a982f5a4f 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h | |||
@@ -68,6 +68,8 @@ struct extent_buffer *btrfs_find_tree_block(struct btrfs_fs_info *fs_info, | |||
68 | struct btrfs_root *btrfs_read_fs_root(struct btrfs_root *tree_root, | 68 | struct btrfs_root *btrfs_read_fs_root(struct btrfs_root *tree_root, |
69 | struct btrfs_key *location); | 69 | struct btrfs_key *location); |
70 | int btrfs_init_fs_root(struct btrfs_root *root); | 70 | int btrfs_init_fs_root(struct btrfs_root *root); |
71 | struct btrfs_root *btrfs_lookup_fs_root(struct btrfs_fs_info *fs_info, | ||
72 | u64 root_id); | ||
71 | int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info, | 73 | int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info, |
72 | struct btrfs_root *root); | 74 | struct btrfs_root *root); |
73 | void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info); | 75 | void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 61b494e8e604..665da8f66ff1 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -60,21 +60,6 @@ enum { | |||
60 | CHUNK_ALLOC_FORCE = 2, | 60 | CHUNK_ALLOC_FORCE = 2, |
61 | }; | 61 | }; |
62 | 62 | ||
63 | /* | ||
64 | * Control how reservations are dealt with. | ||
65 | * | ||
66 | * RESERVE_FREE - freeing a reservation. | ||
67 | * RESERVE_ALLOC - allocating space and we need to update bytes_may_use for | ||
68 | * ENOSPC accounting | ||
69 | * RESERVE_ALLOC_NO_ACCOUNT - allocating space and we should not update | ||
70 | * bytes_may_use as the ENOSPC accounting is done elsewhere | ||
71 | */ | ||
72 | enum { | ||
73 | RESERVE_FREE = 0, | ||
74 | RESERVE_ALLOC = 1, | ||
75 | RESERVE_ALLOC_NO_ACCOUNT = 2, | ||
76 | }; | ||
77 | |||
78 | static int update_block_group(struct btrfs_trans_handle *trans, | 63 | static int update_block_group(struct btrfs_trans_handle *trans, |
79 | struct btrfs_root *root, u64 bytenr, | 64 | struct btrfs_root *root, u64 bytenr, |
80 | u64 num_bytes, int alloc); | 65 | u64 num_bytes, int alloc); |
@@ -104,9 +89,10 @@ static int find_next_key(struct btrfs_path *path, int level, | |||
104 | struct btrfs_key *key); | 89 | struct btrfs_key *key); |
105 | static void dump_space_info(struct btrfs_space_info *info, u64 bytes, | 90 | static void dump_space_info(struct btrfs_space_info *info, u64 bytes, |
106 | int dump_block_groups); | 91 | int dump_block_groups); |
107 | static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, | 92 | static int btrfs_add_reserved_bytes(struct btrfs_block_group_cache *cache, |
108 | u64 num_bytes, int reserve, | 93 | u64 ram_bytes, u64 num_bytes, int delalloc); |
109 | int delalloc); | 94 | static int btrfs_free_reserved_bytes(struct btrfs_block_group_cache *cache, |
95 | u64 num_bytes, int delalloc); | ||
110 | static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv, | 96 | static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv, |
111 | u64 num_bytes); | 97 | u64 num_bytes); |
112 | int btrfs_pin_extent(struct btrfs_root *root, | 98 | int btrfs_pin_extent(struct btrfs_root *root, |
@@ -3501,7 +3487,6 @@ again: | |||
3501 | dcs = BTRFS_DC_SETUP; | 3487 | dcs = BTRFS_DC_SETUP; |
3502 | else if (ret == -ENOSPC) | 3488 | else if (ret == -ENOSPC) |
3503 | set_bit(BTRFS_TRANS_CACHE_ENOSPC, &trans->transaction->flags); | 3489 | set_bit(BTRFS_TRANS_CACHE_ENOSPC, &trans->transaction->flags); |
3504 | btrfs_free_reserved_data_space(inode, 0, num_pages); | ||
3505 | 3490 | ||
3506 | out_put: | 3491 | out_put: |
3507 | iput(inode); | 3492 | iput(inode); |
@@ -4286,13 +4271,10 @@ int btrfs_check_data_free_space(struct inode *inode, u64 start, u64 len) | |||
4286 | if (ret < 0) | 4271 | if (ret < 0) |
4287 | return ret; | 4272 | return ret; |
4288 | 4273 | ||
4289 | /* | 4274 | /* Use new btrfs_qgroup_reserve_data to reserve precious data space. */ |
4290 | * Use new btrfs_qgroup_reserve_data to reserve precious data space | ||
4291 | * | ||
4292 | * TODO: Find a good method to avoid reserve data space for NOCOW | ||
4293 | * range, but don't impact performance on quota disable case. | ||
4294 | */ | ||
4295 | ret = btrfs_qgroup_reserve_data(inode, start, len); | 4275 | ret = btrfs_qgroup_reserve_data(inode, start, len); |
4276 | if (ret) | ||
4277 | btrfs_free_reserved_data_space_noquota(inode, start, len); | ||
4296 | return ret; | 4278 | return ret; |
4297 | } | 4279 | } |
4298 | 4280 | ||
@@ -4472,6 +4454,15 @@ void check_system_chunk(struct btrfs_trans_handle *trans, | |||
4472 | } | 4454 | } |
4473 | } | 4455 | } |
4474 | 4456 | ||
4457 | /* | ||
4458 | * If force is CHUNK_ALLOC_FORCE: | ||
4459 | * - return 1 if it successfully allocates a chunk, | ||
4460 | * - return errors including -ENOSPC otherwise. | ||
4461 | * If force is NOT CHUNK_ALLOC_FORCE: | ||
4462 | * - return 0 if it doesn't need to allocate a new chunk, | ||
4463 | * - return 1 if it successfully allocates a chunk, | ||
4464 | * - return errors including -ENOSPC otherwise. | ||
4465 | */ | ||
4475 | static int do_chunk_alloc(struct btrfs_trans_handle *trans, | 4466 | static int do_chunk_alloc(struct btrfs_trans_handle *trans, |
4476 | struct btrfs_root *extent_root, u64 flags, int force) | 4467 | struct btrfs_root *extent_root, u64 flags, int force) |
4477 | { | 4468 | { |
@@ -4882,7 +4873,7 @@ static int flush_space(struct btrfs_root *root, | |||
4882 | btrfs_get_alloc_profile(root, 0), | 4873 | btrfs_get_alloc_profile(root, 0), |
4883 | CHUNK_ALLOC_NO_FORCE); | 4874 | CHUNK_ALLOC_NO_FORCE); |
4884 | btrfs_end_transaction(trans, root); | 4875 | btrfs_end_transaction(trans, root); |
4885 | if (ret == -ENOSPC) | 4876 | if (ret > 0 || ret == -ENOSPC) |
4886 | ret = 0; | 4877 | ret = 0; |
4887 | break; | 4878 | break; |
4888 | case COMMIT_TRANS: | 4879 | case COMMIT_TRANS: |
@@ -4907,11 +4898,6 @@ btrfs_calc_reclaim_metadata_size(struct btrfs_root *root, | |||
4907 | u64 expected; | 4898 | u64 expected; |
4908 | u64 to_reclaim = 0; | 4899 | u64 to_reclaim = 0; |
4909 | 4900 | ||
4910 | to_reclaim = min_t(u64, num_online_cpus() * SZ_1M, SZ_16M); | ||
4911 | if (can_overcommit(root, space_info, to_reclaim, | ||
4912 | BTRFS_RESERVE_FLUSH_ALL)) | ||
4913 | return 0; | ||
4914 | |||
4915 | list_for_each_entry(ticket, &space_info->tickets, list) | 4901 | list_for_each_entry(ticket, &space_info->tickets, list) |
4916 | to_reclaim += ticket->bytes; | 4902 | to_reclaim += ticket->bytes; |
4917 | list_for_each_entry(ticket, &space_info->priority_tickets, list) | 4903 | list_for_each_entry(ticket, &space_info->priority_tickets, list) |
@@ -4919,6 +4905,11 @@ btrfs_calc_reclaim_metadata_size(struct btrfs_root *root, | |||
4919 | if (to_reclaim) | 4905 | if (to_reclaim) |
4920 | return to_reclaim; | 4906 | return to_reclaim; |
4921 | 4907 | ||
4908 | to_reclaim = min_t(u64, num_online_cpus() * SZ_1M, SZ_16M); | ||
4909 | if (can_overcommit(root, space_info, to_reclaim, | ||
4910 | BTRFS_RESERVE_FLUSH_ALL)) | ||
4911 | return 0; | ||
4912 | |||
4922 | used = space_info->bytes_used + space_info->bytes_reserved + | 4913 | used = space_info->bytes_used + space_info->bytes_reserved + |
4923 | space_info->bytes_pinned + space_info->bytes_readonly + | 4914 | space_info->bytes_pinned + space_info->bytes_readonly + |
4924 | space_info->bytes_may_use; | 4915 | space_info->bytes_may_use; |
@@ -4972,12 +4963,12 @@ static void wake_all_tickets(struct list_head *head) | |||
4972 | */ | 4963 | */ |
4973 | static void btrfs_async_reclaim_metadata_space(struct work_struct *work) | 4964 | static void btrfs_async_reclaim_metadata_space(struct work_struct *work) |
4974 | { | 4965 | { |
4975 | struct reserve_ticket *last_ticket = NULL; | ||
4976 | struct btrfs_fs_info *fs_info; | 4966 | struct btrfs_fs_info *fs_info; |
4977 | struct btrfs_space_info *space_info; | 4967 | struct btrfs_space_info *space_info; |
4978 | u64 to_reclaim; | 4968 | u64 to_reclaim; |
4979 | int flush_state; | 4969 | int flush_state; |
4980 | int commit_cycles = 0; | 4970 | int commit_cycles = 0; |
4971 | u64 last_tickets_id; | ||
4981 | 4972 | ||
4982 | fs_info = container_of(work, struct btrfs_fs_info, async_reclaim_work); | 4973 | fs_info = container_of(work, struct btrfs_fs_info, async_reclaim_work); |
4983 | space_info = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA); | 4974 | space_info = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA); |
@@ -4990,8 +4981,7 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work) | |||
4990 | spin_unlock(&space_info->lock); | 4981 | spin_unlock(&space_info->lock); |
4991 | return; | 4982 | return; |
4992 | } | 4983 | } |
4993 | last_ticket = list_first_entry(&space_info->tickets, | 4984 | last_tickets_id = space_info->tickets_id; |
4994 | struct reserve_ticket, list); | ||
4995 | spin_unlock(&space_info->lock); | 4985 | spin_unlock(&space_info->lock); |
4996 | 4986 | ||
4997 | flush_state = FLUSH_DELAYED_ITEMS_NR; | 4987 | flush_state = FLUSH_DELAYED_ITEMS_NR; |
@@ -5011,10 +5001,10 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work) | |||
5011 | space_info); | 5001 | space_info); |
5012 | ticket = list_first_entry(&space_info->tickets, | 5002 | ticket = list_first_entry(&space_info->tickets, |
5013 | struct reserve_ticket, list); | 5003 | struct reserve_ticket, list); |
5014 | if (last_ticket == ticket) { | 5004 | if (last_tickets_id == space_info->tickets_id) { |
5015 | flush_state++; | 5005 | flush_state++; |
5016 | } else { | 5006 | } else { |
5017 | last_ticket = ticket; | 5007 | last_tickets_id = space_info->tickets_id; |
5018 | flush_state = FLUSH_DELAYED_ITEMS_NR; | 5008 | flush_state = FLUSH_DELAYED_ITEMS_NR; |
5019 | if (commit_cycles) | 5009 | if (commit_cycles) |
5020 | commit_cycles--; | 5010 | commit_cycles--; |
@@ -5390,6 +5380,7 @@ again: | |||
5390 | list_del_init(&ticket->list); | 5380 | list_del_init(&ticket->list); |
5391 | num_bytes -= ticket->bytes; | 5381 | num_bytes -= ticket->bytes; |
5392 | ticket->bytes = 0; | 5382 | ticket->bytes = 0; |
5383 | space_info->tickets_id++; | ||
5393 | wake_up(&ticket->wait); | 5384 | wake_up(&ticket->wait); |
5394 | } else { | 5385 | } else { |
5395 | ticket->bytes -= num_bytes; | 5386 | ticket->bytes -= num_bytes; |
@@ -5432,6 +5423,7 @@ again: | |||
5432 | num_bytes -= ticket->bytes; | 5423 | num_bytes -= ticket->bytes; |
5433 | space_info->bytes_may_use += ticket->bytes; | 5424 | space_info->bytes_may_use += ticket->bytes; |
5434 | ticket->bytes = 0; | 5425 | ticket->bytes = 0; |
5426 | space_info->tickets_id++; | ||
5435 | wake_up(&ticket->wait); | 5427 | wake_up(&ticket->wait); |
5436 | } else { | 5428 | } else { |
5437 | trace_btrfs_space_reservation(fs_info, "space_info", | 5429 | trace_btrfs_space_reservation(fs_info, "space_info", |
@@ -6497,19 +6489,15 @@ void btrfs_wait_block_group_reservations(struct btrfs_block_group_cache *bg) | |||
6497 | } | 6489 | } |
6498 | 6490 | ||
6499 | /** | 6491 | /** |
6500 | * btrfs_update_reserved_bytes - update the block_group and space info counters | 6492 | * btrfs_add_reserved_bytes - update the block_group and space info counters |
6501 | * @cache: The cache we are manipulating | 6493 | * @cache: The cache we are manipulating |
6494 | * @ram_bytes: The number of bytes of file content, and will be same to | ||
6495 | * @num_bytes except for the compress path. | ||
6502 | * @num_bytes: The number of bytes in question | 6496 | * @num_bytes: The number of bytes in question |
6503 | * @reserve: One of the reservation enums | ||
6504 | * @delalloc: The blocks are allocated for the delalloc write | 6497 | * @delalloc: The blocks are allocated for the delalloc write |
6505 | * | 6498 | * |
6506 | * This is called by the allocator when it reserves space, or by somebody who is | 6499 | * This is called by the allocator when it reserves space. Metadata |
6507 | * freeing space that was never actually used on disk. For example if you | 6500 | * reservations should be called with RESERVE_ALLOC so we do the proper |
6508 | * reserve some space for a new leaf in transaction A and before transaction A | ||
6509 | * commits you free that leaf, you call this with reserve set to 0 in order to | ||
6510 | * clear the reservation. | ||
6511 | * | ||
6512 | * Metadata reservations should be called with RESERVE_ALLOC so we do the proper | ||
6513 | * ENOSPC accounting. For data we handle the reservation through clearing the | 6501 | * ENOSPC accounting. For data we handle the reservation through clearing the |
6514 | * delalloc bits in the io_tree. We have to do this since we could end up | 6502 | * delalloc bits in the io_tree. We have to do this since we could end up |
6515 | * allocating less disk space for the amount of data we have reserved in the | 6503 | * allocating less disk space for the amount of data we have reserved in the |
@@ -6519,44 +6507,63 @@ void btrfs_wait_block_group_reservations(struct btrfs_block_group_cache *bg) | |||
6519 | * make the reservation and return -EAGAIN, otherwise this function always | 6507 | * make the reservation and return -EAGAIN, otherwise this function always |
6520 | * succeeds. | 6508 | * succeeds. |
6521 | */ | 6509 | */ |
6522 | static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, | 6510 | static int btrfs_add_reserved_bytes(struct btrfs_block_group_cache *cache, |
6523 | u64 num_bytes, int reserve, int delalloc) | 6511 | u64 ram_bytes, u64 num_bytes, int delalloc) |
6524 | { | 6512 | { |
6525 | struct btrfs_space_info *space_info = cache->space_info; | 6513 | struct btrfs_space_info *space_info = cache->space_info; |
6526 | int ret = 0; | 6514 | int ret = 0; |
6527 | 6515 | ||
6528 | spin_lock(&space_info->lock); | 6516 | spin_lock(&space_info->lock); |
6529 | spin_lock(&cache->lock); | 6517 | spin_lock(&cache->lock); |
6530 | if (reserve != RESERVE_FREE) { | 6518 | if (cache->ro) { |
6531 | if (cache->ro) { | 6519 | ret = -EAGAIN; |
6532 | ret = -EAGAIN; | ||
6533 | } else { | ||
6534 | cache->reserved += num_bytes; | ||
6535 | space_info->bytes_reserved += num_bytes; | ||
6536 | if (reserve == RESERVE_ALLOC) { | ||
6537 | trace_btrfs_space_reservation(cache->fs_info, | ||
6538 | "space_info", space_info->flags, | ||
6539 | num_bytes, 0); | ||
6540 | space_info->bytes_may_use -= num_bytes; | ||
6541 | } | ||
6542 | |||
6543 | if (delalloc) | ||
6544 | cache->delalloc_bytes += num_bytes; | ||
6545 | } | ||
6546 | } else { | 6520 | } else { |
6547 | if (cache->ro) | 6521 | cache->reserved += num_bytes; |
6548 | space_info->bytes_readonly += num_bytes; | 6522 | space_info->bytes_reserved += num_bytes; |
6549 | cache->reserved -= num_bytes; | ||
6550 | space_info->bytes_reserved -= num_bytes; | ||
6551 | 6523 | ||
6524 | trace_btrfs_space_reservation(cache->fs_info, | ||
6525 | "space_info", space_info->flags, | ||
6526 | ram_bytes, 0); | ||
6527 | space_info->bytes_may_use -= ram_bytes; | ||
6552 | if (delalloc) | 6528 | if (delalloc) |
6553 | cache->delalloc_bytes -= num_bytes; | 6529 | cache->delalloc_bytes += num_bytes; |
6554 | } | 6530 | } |
6555 | spin_unlock(&cache->lock); | 6531 | spin_unlock(&cache->lock); |
6556 | spin_unlock(&space_info->lock); | 6532 | spin_unlock(&space_info->lock); |
6557 | return ret; | 6533 | return ret; |
6558 | } | 6534 | } |
6559 | 6535 | ||
6536 | /** | ||
6537 | * btrfs_free_reserved_bytes - update the block_group and space info counters | ||
6538 | * @cache: The cache we are manipulating | ||
6539 | * @num_bytes: The number of bytes in question | ||
6540 | * @delalloc: The blocks are allocated for the delalloc write | ||
6541 | * | ||
6542 | * This is called by somebody who is freeing space that was never actually used | ||
6543 | * on disk. For example if you reserve some space for a new leaf in transaction | ||
6544 | * A and before transaction A commits you free that leaf, you call this with | ||
6545 | * reserve set to 0 in order to clear the reservation. | ||
6546 | */ | ||
6547 | |||
6548 | static int btrfs_free_reserved_bytes(struct btrfs_block_group_cache *cache, | ||
6549 | u64 num_bytes, int delalloc) | ||
6550 | { | ||
6551 | struct btrfs_space_info *space_info = cache->space_info; | ||
6552 | int ret = 0; | ||
6553 | |||
6554 | spin_lock(&space_info->lock); | ||
6555 | spin_lock(&cache->lock); | ||
6556 | if (cache->ro) | ||
6557 | space_info->bytes_readonly += num_bytes; | ||
6558 | cache->reserved -= num_bytes; | ||
6559 | space_info->bytes_reserved -= num_bytes; | ||
6560 | |||
6561 | if (delalloc) | ||
6562 | cache->delalloc_bytes -= num_bytes; | ||
6563 | spin_unlock(&cache->lock); | ||
6564 | spin_unlock(&space_info->lock); | ||
6565 | return ret; | ||
6566 | } | ||
6560 | void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, | 6567 | void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, |
6561 | struct btrfs_root *root) | 6568 | struct btrfs_root *root) |
6562 | { | 6569 | { |
@@ -7191,7 +7198,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, | |||
7191 | WARN_ON(test_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)); | 7198 | WARN_ON(test_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)); |
7192 | 7199 | ||
7193 | btrfs_add_free_space(cache, buf->start, buf->len); | 7200 | btrfs_add_free_space(cache, buf->start, buf->len); |
7194 | btrfs_update_reserved_bytes(cache, buf->len, RESERVE_FREE, 0); | 7201 | btrfs_free_reserved_bytes(cache, buf->len, 0); |
7195 | btrfs_put_block_group(cache); | 7202 | btrfs_put_block_group(cache); |
7196 | trace_btrfs_reserved_extent_free(root, buf->start, buf->len); | 7203 | trace_btrfs_reserved_extent_free(root, buf->start, buf->len); |
7197 | pin = 0; | 7204 | pin = 0; |
@@ -7416,9 +7423,9 @@ btrfs_release_block_group(struct btrfs_block_group_cache *cache, | |||
7416 | * the free space extent currently. | 7423 | * the free space extent currently. |
7417 | */ | 7424 | */ |
7418 | static noinline int find_free_extent(struct btrfs_root *orig_root, | 7425 | static noinline int find_free_extent(struct btrfs_root *orig_root, |
7419 | u64 num_bytes, u64 empty_size, | 7426 | u64 ram_bytes, u64 num_bytes, u64 empty_size, |
7420 | u64 hint_byte, struct btrfs_key *ins, | 7427 | u64 hint_byte, struct btrfs_key *ins, |
7421 | u64 flags, int delalloc) | 7428 | u64 flags, int delalloc) |
7422 | { | 7429 | { |
7423 | int ret = 0; | 7430 | int ret = 0; |
7424 | struct btrfs_root *root = orig_root->fs_info->extent_root; | 7431 | struct btrfs_root *root = orig_root->fs_info->extent_root; |
@@ -7430,8 +7437,6 @@ static noinline int find_free_extent(struct btrfs_root *orig_root, | |||
7430 | struct btrfs_space_info *space_info; | 7437 | struct btrfs_space_info *space_info; |
7431 | int loop = 0; | 7438 | int loop = 0; |
7432 | int index = __get_raid_index(flags); | 7439 | int index = __get_raid_index(flags); |
7433 | int alloc_type = (flags & BTRFS_BLOCK_GROUP_DATA) ? | ||
7434 | RESERVE_ALLOC_NO_ACCOUNT : RESERVE_ALLOC; | ||
7435 | bool failed_cluster_refill = false; | 7440 | bool failed_cluster_refill = false; |
7436 | bool failed_alloc = false; | 7441 | bool failed_alloc = false; |
7437 | bool use_cluster = true; | 7442 | bool use_cluster = true; |
@@ -7763,8 +7768,8 @@ checks: | |||
7763 | search_start - offset); | 7768 | search_start - offset); |
7764 | BUG_ON(offset > search_start); | 7769 | BUG_ON(offset > search_start); |
7765 | 7770 | ||
7766 | ret = btrfs_update_reserved_bytes(block_group, num_bytes, | 7771 | ret = btrfs_add_reserved_bytes(block_group, ram_bytes, |
7767 | alloc_type, delalloc); | 7772 | num_bytes, delalloc); |
7768 | if (ret == -EAGAIN) { | 7773 | if (ret == -EAGAIN) { |
7769 | btrfs_add_free_space(block_group, offset, num_bytes); | 7774 | btrfs_add_free_space(block_group, offset, num_bytes); |
7770 | goto loop; | 7775 | goto loop; |
@@ -7936,7 +7941,7 @@ again: | |||
7936 | up_read(&info->groups_sem); | 7941 | up_read(&info->groups_sem); |
7937 | } | 7942 | } |
7938 | 7943 | ||
7939 | int btrfs_reserve_extent(struct btrfs_root *root, | 7944 | int btrfs_reserve_extent(struct btrfs_root *root, u64 ram_bytes, |
7940 | u64 num_bytes, u64 min_alloc_size, | 7945 | u64 num_bytes, u64 min_alloc_size, |
7941 | u64 empty_size, u64 hint_byte, | 7946 | u64 empty_size, u64 hint_byte, |
7942 | struct btrfs_key *ins, int is_data, int delalloc) | 7947 | struct btrfs_key *ins, int is_data, int delalloc) |
@@ -7948,8 +7953,8 @@ int btrfs_reserve_extent(struct btrfs_root *root, | |||
7948 | flags = btrfs_get_alloc_profile(root, is_data); | 7953 | flags = btrfs_get_alloc_profile(root, is_data); |
7949 | again: | 7954 | again: |
7950 | WARN_ON(num_bytes < root->sectorsize); | 7955 | WARN_ON(num_bytes < root->sectorsize); |
7951 | ret = find_free_extent(root, num_bytes, empty_size, hint_byte, ins, | 7956 | ret = find_free_extent(root, ram_bytes, num_bytes, empty_size, |
7952 | flags, delalloc); | 7957 | hint_byte, ins, flags, delalloc); |
7953 | if (!ret && !is_data) { | 7958 | if (!ret && !is_data) { |
7954 | btrfs_dec_block_group_reservations(root->fs_info, | 7959 | btrfs_dec_block_group_reservations(root->fs_info, |
7955 | ins->objectid); | 7960 | ins->objectid); |
@@ -7958,6 +7963,7 @@ again: | |||
7958 | num_bytes = min(num_bytes >> 1, ins->offset); | 7963 | num_bytes = min(num_bytes >> 1, ins->offset); |
7959 | num_bytes = round_down(num_bytes, root->sectorsize); | 7964 | num_bytes = round_down(num_bytes, root->sectorsize); |
7960 | num_bytes = max(num_bytes, min_alloc_size); | 7965 | num_bytes = max(num_bytes, min_alloc_size); |
7966 | ram_bytes = num_bytes; | ||
7961 | if (num_bytes == min_alloc_size) | 7967 | if (num_bytes == min_alloc_size) |
7962 | final_tried = true; | 7968 | final_tried = true; |
7963 | goto again; | 7969 | goto again; |
@@ -7995,7 +8001,7 @@ static int __btrfs_free_reserved_extent(struct btrfs_root *root, | |||
7995 | if (btrfs_test_opt(root->fs_info, DISCARD)) | 8001 | if (btrfs_test_opt(root->fs_info, DISCARD)) |
7996 | ret = btrfs_discard_extent(root, start, len, NULL); | 8002 | ret = btrfs_discard_extent(root, start, len, NULL); |
7997 | btrfs_add_free_space(cache, start, len); | 8003 | btrfs_add_free_space(cache, start, len); |
7998 | btrfs_update_reserved_bytes(cache, len, RESERVE_FREE, delalloc); | 8004 | btrfs_free_reserved_bytes(cache, len, delalloc); |
7999 | trace_btrfs_reserved_extent_free(root, start, len); | 8005 | trace_btrfs_reserved_extent_free(root, start, len); |
8000 | } | 8006 | } |
8001 | 8007 | ||
@@ -8208,6 +8214,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, | |||
8208 | { | 8214 | { |
8209 | int ret; | 8215 | int ret; |
8210 | struct btrfs_block_group_cache *block_group; | 8216 | struct btrfs_block_group_cache *block_group; |
8217 | struct btrfs_space_info *space_info; | ||
8211 | 8218 | ||
8212 | /* | 8219 | /* |
8213 | * Mixed block groups will exclude before processing the log so we only | 8220 | * Mixed block groups will exclude before processing the log so we only |
@@ -8223,9 +8230,14 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, | |||
8223 | if (!block_group) | 8230 | if (!block_group) |
8224 | return -EINVAL; | 8231 | return -EINVAL; |
8225 | 8232 | ||
8226 | ret = btrfs_update_reserved_bytes(block_group, ins->offset, | 8233 | space_info = block_group->space_info; |
8227 | RESERVE_ALLOC_NO_ACCOUNT, 0); | 8234 | spin_lock(&space_info->lock); |
8228 | BUG_ON(ret); /* logic error */ | 8235 | spin_lock(&block_group->lock); |
8236 | space_info->bytes_reserved += ins->offset; | ||
8237 | block_group->reserved += ins->offset; | ||
8238 | spin_unlock(&block_group->lock); | ||
8239 | spin_unlock(&space_info->lock); | ||
8240 | |||
8229 | ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, | 8241 | ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, |
8230 | 0, owner, offset, ins, 1); | 8242 | 0, owner, offset, ins, 1); |
8231 | btrfs_put_block_group(block_group); | 8243 | btrfs_put_block_group(block_group); |
@@ -8368,7 +8380,7 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, | |||
8368 | if (IS_ERR(block_rsv)) | 8380 | if (IS_ERR(block_rsv)) |
8369 | return ERR_CAST(block_rsv); | 8381 | return ERR_CAST(block_rsv); |
8370 | 8382 | ||
8371 | ret = btrfs_reserve_extent(root, blocksize, blocksize, | 8383 | ret = btrfs_reserve_extent(root, blocksize, blocksize, blocksize, |
8372 | empty_size, hint, &ins, 0, 0); | 8384 | empty_size, hint, &ins, 0, 0); |
8373 | if (ret) | 8385 | if (ret) |
8374 | goto out_unuse; | 8386 | goto out_unuse; |
@@ -8521,35 +8533,6 @@ reada: | |||
8521 | wc->reada_slot = slot; | 8533 | wc->reada_slot = slot; |
8522 | } | 8534 | } |
8523 | 8535 | ||
8524 | /* | ||
8525 | * These may not be seen by the usual inc/dec ref code so we have to | ||
8526 | * add them here. | ||
8527 | */ | ||
8528 | static int record_one_subtree_extent(struct btrfs_trans_handle *trans, | ||
8529 | struct btrfs_root *root, u64 bytenr, | ||
8530 | u64 num_bytes) | ||
8531 | { | ||
8532 | struct btrfs_qgroup_extent_record *qrecord; | ||
8533 | struct btrfs_delayed_ref_root *delayed_refs; | ||
8534 | |||
8535 | qrecord = kmalloc(sizeof(*qrecord), GFP_NOFS); | ||
8536 | if (!qrecord) | ||
8537 | return -ENOMEM; | ||
8538 | |||
8539 | qrecord->bytenr = bytenr; | ||
8540 | qrecord->num_bytes = num_bytes; | ||
8541 | qrecord->old_roots = NULL; | ||
8542 | |||
8543 | delayed_refs = &trans->transaction->delayed_refs; | ||
8544 | spin_lock(&delayed_refs->lock); | ||
8545 | if (btrfs_qgroup_insert_dirty_extent(trans->fs_info, | ||
8546 | delayed_refs, qrecord)) | ||
8547 | kfree(qrecord); | ||
8548 | spin_unlock(&delayed_refs->lock); | ||
8549 | |||
8550 | return 0; | ||
8551 | } | ||
8552 | |||
8553 | static int account_leaf_items(struct btrfs_trans_handle *trans, | 8536 | static int account_leaf_items(struct btrfs_trans_handle *trans, |
8554 | struct btrfs_root *root, | 8537 | struct btrfs_root *root, |
8555 | struct extent_buffer *eb) | 8538 | struct extent_buffer *eb) |
@@ -8583,7 +8566,8 @@ static int account_leaf_items(struct btrfs_trans_handle *trans, | |||
8583 | 8566 | ||
8584 | num_bytes = btrfs_file_extent_disk_num_bytes(eb, fi); | 8567 | num_bytes = btrfs_file_extent_disk_num_bytes(eb, fi); |
8585 | 8568 | ||
8586 | ret = record_one_subtree_extent(trans, root, bytenr, num_bytes); | 8569 | ret = btrfs_qgroup_insert_dirty_extent(trans, root->fs_info, |
8570 | bytenr, num_bytes, GFP_NOFS); | ||
8587 | if (ret) | 8571 | if (ret) |
8588 | return ret; | 8572 | return ret; |
8589 | } | 8573 | } |
@@ -8732,8 +8716,9 @@ walk_down: | |||
8732 | btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); | 8716 | btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); |
8733 | path->locks[level] = BTRFS_READ_LOCK_BLOCKING; | 8717 | path->locks[level] = BTRFS_READ_LOCK_BLOCKING; |
8734 | 8718 | ||
8735 | ret = record_one_subtree_extent(trans, root, child_bytenr, | 8719 | ret = btrfs_qgroup_insert_dirty_extent(trans, |
8736 | root->nodesize); | 8720 | root->fs_info, child_bytenr, |
8721 | root->nodesize, GFP_NOFS); | ||
8737 | if (ret) | 8722 | if (ret) |
8738 | goto out; | 8723 | goto out; |
8739 | } | 8724 | } |
@@ -9906,6 +9891,7 @@ static int find_first_block_group(struct btrfs_root *root, | |||
9906 | } else { | 9891 | } else { |
9907 | ret = 0; | 9892 | ret = 0; |
9908 | } | 9893 | } |
9894 | free_extent_map(em); | ||
9909 | goto out; | 9895 | goto out; |
9910 | } | 9896 | } |
9911 | path->slots[0]++; | 9897 | path->slots[0]++; |
@@ -9942,6 +9928,7 @@ void btrfs_put_block_group_cache(struct btrfs_fs_info *info) | |||
9942 | block_group->iref = 0; | 9928 | block_group->iref = 0; |
9943 | block_group->inode = NULL; | 9929 | block_group->inode = NULL; |
9944 | spin_unlock(&block_group->lock); | 9930 | spin_unlock(&block_group->lock); |
9931 | ASSERT(block_group->io_ctl.inode == NULL); | ||
9945 | iput(inode); | 9932 | iput(inode); |
9946 | last = block_group->key.objectid + block_group->key.offset; | 9933 | last = block_group->key.objectid + block_group->key.offset; |
9947 | btrfs_put_block_group(block_group); | 9934 | btrfs_put_block_group(block_group); |
@@ -9999,6 +9986,10 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) | |||
9999 | free_excluded_extents(info->extent_root, block_group); | 9986 | free_excluded_extents(info->extent_root, block_group); |
10000 | 9987 | ||
10001 | btrfs_remove_free_space_cache(block_group); | 9988 | btrfs_remove_free_space_cache(block_group); |
9989 | ASSERT(list_empty(&block_group->dirty_list)); | ||
9990 | ASSERT(list_empty(&block_group->io_list)); | ||
9991 | ASSERT(list_empty(&block_group->bg_list)); | ||
9992 | ASSERT(atomic_read(&block_group->count) == 1); | ||
10002 | btrfs_put_block_group(block_group); | 9993 | btrfs_put_block_group(block_group); |
10003 | 9994 | ||
10004 | spin_lock(&info->block_group_cache_lock); | 9995 | spin_lock(&info->block_group_cache_lock); |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index bc2729a7612d..28cd88fccc7e 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #define EXTENT_DAMAGED (1U << 14) | 20 | #define EXTENT_DAMAGED (1U << 14) |
21 | #define EXTENT_NORESERVE (1U << 15) | 21 | #define EXTENT_NORESERVE (1U << 15) |
22 | #define EXTENT_QGROUP_RESERVED (1U << 16) | 22 | #define EXTENT_QGROUP_RESERVED (1U << 16) |
23 | #define EXTENT_CLEAR_DATA_RESV (1U << 17) | ||
23 | #define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) | 24 | #define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) |
24 | #define EXTENT_CTLBITS (EXTENT_DO_ACCOUNTING | EXTENT_FIRST_DELALLOC) | 25 | #define EXTENT_CTLBITS (EXTENT_DO_ACCOUNTING | EXTENT_FIRST_DELALLOC) |
25 | 26 | ||
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 5842423f8f47..fea31a4a6e36 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -2070,7 +2070,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
2070 | } | 2070 | } |
2071 | trans->sync = true; | 2071 | trans->sync = true; |
2072 | 2072 | ||
2073 | btrfs_init_log_ctx(&ctx); | 2073 | btrfs_init_log_ctx(&ctx, inode); |
2074 | 2074 | ||
2075 | ret = btrfs_log_dentry_safe(trans, root, dentry, start, end, &ctx); | 2075 | ret = btrfs_log_dentry_safe(trans, root, dentry, start, end, &ctx); |
2076 | if (ret < 0) { | 2076 | if (ret < 0) { |
@@ -2675,6 +2675,7 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
2675 | 2675 | ||
2676 | alloc_start = round_down(offset, blocksize); | 2676 | alloc_start = round_down(offset, blocksize); |
2677 | alloc_end = round_up(offset + len, blocksize); | 2677 | alloc_end = round_up(offset + len, blocksize); |
2678 | cur_offset = alloc_start; | ||
2678 | 2679 | ||
2679 | /* Make sure we aren't being give some crap mode */ | 2680 | /* Make sure we aren't being give some crap mode */ |
2680 | if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) | 2681 | if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) |
@@ -2767,7 +2768,6 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
2767 | 2768 | ||
2768 | /* First, check if we exceed the qgroup limit */ | 2769 | /* First, check if we exceed the qgroup limit */ |
2769 | INIT_LIST_HEAD(&reserve_list); | 2770 | INIT_LIST_HEAD(&reserve_list); |
2770 | cur_offset = alloc_start; | ||
2771 | while (1) { | 2771 | while (1) { |
2772 | em = btrfs_get_extent(inode, NULL, 0, cur_offset, | 2772 | em = btrfs_get_extent(inode, NULL, 0, cur_offset, |
2773 | alloc_end - cur_offset, 0); | 2773 | alloc_end - cur_offset, 0); |
@@ -2794,6 +2794,14 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
2794 | last_byte - cur_offset); | 2794 | last_byte - cur_offset); |
2795 | if (ret < 0) | 2795 | if (ret < 0) |
2796 | break; | 2796 | break; |
2797 | } else { | ||
2798 | /* | ||
2799 | * Do not need to reserve unwritten extent for this | ||
2800 | * range, free reserved data space first, otherwise | ||
2801 | * it'll result in false ENOSPC error. | ||
2802 | */ | ||
2803 | btrfs_free_reserved_data_space(inode, cur_offset, | ||
2804 | last_byte - cur_offset); | ||
2797 | } | 2805 | } |
2798 | free_extent_map(em); | 2806 | free_extent_map(em); |
2799 | cur_offset = last_byte; | 2807 | cur_offset = last_byte; |
@@ -2811,6 +2819,9 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
2811 | range->start, | 2819 | range->start, |
2812 | range->len, 1 << inode->i_blkbits, | 2820 | range->len, 1 << inode->i_blkbits, |
2813 | offset + len, &alloc_hint); | 2821 | offset + len, &alloc_hint); |
2822 | else | ||
2823 | btrfs_free_reserved_data_space(inode, range->start, | ||
2824 | range->len); | ||
2814 | list_del(&range->list); | 2825 | list_del(&range->list); |
2815 | kfree(range); | 2826 | kfree(range); |
2816 | } | 2827 | } |
@@ -2845,18 +2856,11 @@ out_unlock: | |||
2845 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, | 2856 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, |
2846 | &cached_state, GFP_KERNEL); | 2857 | &cached_state, GFP_KERNEL); |
2847 | out: | 2858 | out: |
2848 | /* | ||
2849 | * As we waited the extent range, the data_rsv_map must be empty | ||
2850 | * in the range, as written data range will be released from it. | ||
2851 | * And for prealloacted extent, it will also be released when | ||
2852 | * its metadata is written. | ||
2853 | * So this is completely used as cleanup. | ||
2854 | */ | ||
2855 | btrfs_qgroup_free_data(inode, alloc_start, alloc_end - alloc_start); | ||
2856 | inode_unlock(inode); | 2859 | inode_unlock(inode); |
2857 | /* Let go of our reservation. */ | 2860 | /* Let go of our reservation. */ |
2858 | btrfs_free_reserved_data_space(inode, alloc_start, | 2861 | if (ret != 0) |
2859 | alloc_end - alloc_start); | 2862 | btrfs_free_reserved_data_space(inode, alloc_start, |
2863 | alloc_end - cur_offset); | ||
2860 | return ret; | 2864 | return ret; |
2861 | } | 2865 | } |
2862 | 2866 | ||
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index aa6fabaee72e..359ee861b5a4 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c | |||
@@ -495,10 +495,9 @@ again: | |||
495 | ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, prealloc, | 495 | ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, prealloc, |
496 | prealloc, prealloc, &alloc_hint); | 496 | prealloc, prealloc, &alloc_hint); |
497 | if (ret) { | 497 | if (ret) { |
498 | btrfs_delalloc_release_space(inode, 0, prealloc); | 498 | btrfs_delalloc_release_metadata(inode, prealloc); |
499 | goto out_put; | 499 | goto out_put; |
500 | } | 500 | } |
501 | btrfs_free_reserved_data_space(inode, 0, prealloc); | ||
502 | 501 | ||
503 | ret = btrfs_write_out_ino_cache(root, trans, path, inode); | 502 | ret = btrfs_write_out_ino_cache(root, trans, path, inode); |
504 | out_put: | 503 | out_put: |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 08dfc57e2270..e6811c42e41e 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -566,6 +566,8 @@ cont: | |||
566 | PAGE_SET_WRITEBACK | | 566 | PAGE_SET_WRITEBACK | |
567 | page_error_op | | 567 | page_error_op | |
568 | PAGE_END_WRITEBACK); | 568 | PAGE_END_WRITEBACK); |
569 | btrfs_free_reserved_data_space_noquota(inode, start, | ||
570 | end - start + 1); | ||
569 | goto free_pages_out; | 571 | goto free_pages_out; |
570 | } | 572 | } |
571 | } | 573 | } |
@@ -742,7 +744,7 @@ retry: | |||
742 | lock_extent(io_tree, async_extent->start, | 744 | lock_extent(io_tree, async_extent->start, |
743 | async_extent->start + async_extent->ram_size - 1); | 745 | async_extent->start + async_extent->ram_size - 1); |
744 | 746 | ||
745 | ret = btrfs_reserve_extent(root, | 747 | ret = btrfs_reserve_extent(root, async_extent->ram_size, |
746 | async_extent->compressed_size, | 748 | async_extent->compressed_size, |
747 | async_extent->compressed_size, | 749 | async_extent->compressed_size, |
748 | 0, alloc_hint, &ins, 1, 1); | 750 | 0, alloc_hint, &ins, 1, 1); |
@@ -969,7 +971,8 @@ static noinline int cow_file_range(struct inode *inode, | |||
969 | EXTENT_DEFRAG, PAGE_UNLOCK | | 971 | EXTENT_DEFRAG, PAGE_UNLOCK | |
970 | PAGE_CLEAR_DIRTY | PAGE_SET_WRITEBACK | | 972 | PAGE_CLEAR_DIRTY | PAGE_SET_WRITEBACK | |
971 | PAGE_END_WRITEBACK); | 973 | PAGE_END_WRITEBACK); |
972 | 974 | btrfs_free_reserved_data_space_noquota(inode, start, | |
975 | end - start + 1); | ||
973 | *nr_written = *nr_written + | 976 | *nr_written = *nr_written + |
974 | (end - start + PAGE_SIZE) / PAGE_SIZE; | 977 | (end - start + PAGE_SIZE) / PAGE_SIZE; |
975 | *page_started = 1; | 978 | *page_started = 1; |
@@ -989,7 +992,7 @@ static noinline int cow_file_range(struct inode *inode, | |||
989 | unsigned long op; | 992 | unsigned long op; |
990 | 993 | ||
991 | cur_alloc_size = disk_num_bytes; | 994 | cur_alloc_size = disk_num_bytes; |
992 | ret = btrfs_reserve_extent(root, cur_alloc_size, | 995 | ret = btrfs_reserve_extent(root, cur_alloc_size, cur_alloc_size, |
993 | root->sectorsize, 0, alloc_hint, | 996 | root->sectorsize, 0, alloc_hint, |
994 | &ins, 1, 1); | 997 | &ins, 1, 1); |
995 | if (ret < 0) | 998 | if (ret < 0) |
@@ -1489,8 +1492,10 @@ out_check: | |||
1489 | extent_clear_unlock_delalloc(inode, cur_offset, | 1492 | extent_clear_unlock_delalloc(inode, cur_offset, |
1490 | cur_offset + num_bytes - 1, | 1493 | cur_offset + num_bytes - 1, |
1491 | locked_page, EXTENT_LOCKED | | 1494 | locked_page, EXTENT_LOCKED | |
1492 | EXTENT_DELALLOC, PAGE_UNLOCK | | 1495 | EXTENT_DELALLOC | |
1493 | PAGE_SET_PRIVATE2); | 1496 | EXTENT_CLEAR_DATA_RESV, |
1497 | PAGE_UNLOCK | PAGE_SET_PRIVATE2); | ||
1498 | |||
1494 | if (!nolock && nocow) | 1499 | if (!nolock && nocow) |
1495 | btrfs_end_write_no_snapshoting(root); | 1500 | btrfs_end_write_no_snapshoting(root); |
1496 | cur_offset = extent_end; | 1501 | cur_offset = extent_end; |
@@ -1807,7 +1812,9 @@ static void btrfs_clear_bit_hook(struct inode *inode, | |||
1807 | return; | 1812 | return; |
1808 | 1813 | ||
1809 | if (root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID | 1814 | if (root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID |
1810 | && do_list && !(state->state & EXTENT_NORESERVE)) | 1815 | && do_list && !(state->state & EXTENT_NORESERVE) |
1816 | && (*bits & (EXTENT_DO_ACCOUNTING | | ||
1817 | EXTENT_CLEAR_DATA_RESV))) | ||
1811 | btrfs_free_reserved_data_space_noquota(inode, | 1818 | btrfs_free_reserved_data_space_noquota(inode, |
1812 | state->start, len); | 1819 | state->start, len); |
1813 | 1820 | ||
@@ -7251,7 +7258,7 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode, | |||
7251 | int ret; | 7258 | int ret; |
7252 | 7259 | ||
7253 | alloc_hint = get_extent_allocation_hint(inode, start, len); | 7260 | alloc_hint = get_extent_allocation_hint(inode, start, len); |
7254 | ret = btrfs_reserve_extent(root, len, root->sectorsize, 0, | 7261 | ret = btrfs_reserve_extent(root, len, len, root->sectorsize, 0, |
7255 | alloc_hint, &ins, 1, 1); | 7262 | alloc_hint, &ins, 1, 1); |
7256 | if (ret) | 7263 | if (ret) |
7257 | return ERR_PTR(ret); | 7264 | return ERR_PTR(ret); |
@@ -7751,6 +7758,13 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, | |||
7751 | ret = PTR_ERR(em2); | 7758 | ret = PTR_ERR(em2); |
7752 | goto unlock_err; | 7759 | goto unlock_err; |
7753 | } | 7760 | } |
7761 | /* | ||
7762 | * For inode marked NODATACOW or extent marked PREALLOC, | ||
7763 | * use the existing or preallocated extent, so does not | ||
7764 | * need to adjust btrfs_space_info's bytes_may_use. | ||
7765 | */ | ||
7766 | btrfs_free_reserved_data_space_noquota(inode, | ||
7767 | start, len); | ||
7754 | goto unlock; | 7768 | goto unlock; |
7755 | } | 7769 | } |
7756 | } | 7770 | } |
@@ -7785,7 +7799,6 @@ unlock: | |||
7785 | i_size_write(inode, start + len); | 7799 | i_size_write(inode, start + len); |
7786 | 7800 | ||
7787 | adjust_dio_outstanding_extents(inode, dio_data, len); | 7801 | adjust_dio_outstanding_extents(inode, dio_data, len); |
7788 | btrfs_free_reserved_data_space(inode, start, len); | ||
7789 | WARN_ON(dio_data->reserve < len); | 7802 | WARN_ON(dio_data->reserve < len); |
7790 | dio_data->reserve -= len; | 7803 | dio_data->reserve -= len; |
7791 | dio_data->unsubmitted_oe_range_end = start + len; | 7804 | dio_data->unsubmitted_oe_range_end = start + len; |
@@ -10306,6 +10319,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, | |||
10306 | u64 last_alloc = (u64)-1; | 10319 | u64 last_alloc = (u64)-1; |
10307 | int ret = 0; | 10320 | int ret = 0; |
10308 | bool own_trans = true; | 10321 | bool own_trans = true; |
10322 | u64 end = start + num_bytes - 1; | ||
10309 | 10323 | ||
10310 | if (trans) | 10324 | if (trans) |
10311 | own_trans = false; | 10325 | own_trans = false; |
@@ -10327,8 +10341,8 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, | |||
10327 | * sized chunks. | 10341 | * sized chunks. |
10328 | */ | 10342 | */ |
10329 | cur_bytes = min(cur_bytes, last_alloc); | 10343 | cur_bytes = min(cur_bytes, last_alloc); |
10330 | ret = btrfs_reserve_extent(root, cur_bytes, min_size, 0, | 10344 | ret = btrfs_reserve_extent(root, cur_bytes, cur_bytes, |
10331 | *alloc_hint, &ins, 1, 0); | 10345 | min_size, 0, *alloc_hint, &ins, 1, 0); |
10332 | if (ret) { | 10346 | if (ret) { |
10333 | if (own_trans) | 10347 | if (own_trans) |
10334 | btrfs_end_transaction(trans, root); | 10348 | btrfs_end_transaction(trans, root); |
@@ -10414,6 +10428,9 @@ next: | |||
10414 | if (own_trans) | 10428 | if (own_trans) |
10415 | btrfs_end_transaction(trans, root); | 10429 | btrfs_end_transaction(trans, root); |
10416 | } | 10430 | } |
10431 | if (cur_offset < end) | ||
10432 | btrfs_free_reserved_data_space(inode, cur_offset, | ||
10433 | end - cur_offset + 1); | ||
10417 | return ret; | 10434 | return ret; |
10418 | } | 10435 | } |
10419 | 10436 | ||
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 14ed1e9e6bc8..7fd939bfbd99 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -1634,6 +1634,9 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file, | |||
1634 | int namelen; | 1634 | int namelen; |
1635 | int ret = 0; | 1635 | int ret = 0; |
1636 | 1636 | ||
1637 | if (!S_ISDIR(file_inode(file)->i_mode)) | ||
1638 | return -ENOTDIR; | ||
1639 | |||
1637 | ret = mnt_want_write_file(file); | 1640 | ret = mnt_want_write_file(file); |
1638 | if (ret) | 1641 | if (ret) |
1639 | goto out; | 1642 | goto out; |
@@ -1691,6 +1694,9 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, | |||
1691 | struct btrfs_ioctl_vol_args *vol_args; | 1694 | struct btrfs_ioctl_vol_args *vol_args; |
1692 | int ret; | 1695 | int ret; |
1693 | 1696 | ||
1697 | if (!S_ISDIR(file_inode(file)->i_mode)) | ||
1698 | return -ENOTDIR; | ||
1699 | |||
1694 | vol_args = memdup_user(arg, sizeof(*vol_args)); | 1700 | vol_args = memdup_user(arg, sizeof(*vol_args)); |
1695 | if (IS_ERR(vol_args)) | 1701 | if (IS_ERR(vol_args)) |
1696 | return PTR_ERR(vol_args); | 1702 | return PTR_ERR(vol_args); |
@@ -1714,6 +1720,9 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file, | |||
1714 | bool readonly = false; | 1720 | bool readonly = false; |
1715 | struct btrfs_qgroup_inherit *inherit = NULL; | 1721 | struct btrfs_qgroup_inherit *inherit = NULL; |
1716 | 1722 | ||
1723 | if (!S_ISDIR(file_inode(file)->i_mode)) | ||
1724 | return -ENOTDIR; | ||
1725 | |||
1717 | vol_args = memdup_user(arg, sizeof(*vol_args)); | 1726 | vol_args = memdup_user(arg, sizeof(*vol_args)); |
1718 | if (IS_ERR(vol_args)) | 1727 | if (IS_ERR(vol_args)) |
1719 | return PTR_ERR(vol_args); | 1728 | return PTR_ERR(vol_args); |
@@ -2357,6 +2366,9 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
2357 | int ret; | 2366 | int ret; |
2358 | int err = 0; | 2367 | int err = 0; |
2359 | 2368 | ||
2369 | if (!S_ISDIR(dir->i_mode)) | ||
2370 | return -ENOTDIR; | ||
2371 | |||
2360 | vol_args = memdup_user(arg, sizeof(*vol_args)); | 2372 | vol_args = memdup_user(arg, sizeof(*vol_args)); |
2361 | if (IS_ERR(vol_args)) | 2373 | if (IS_ERR(vol_args)) |
2362 | return PTR_ERR(vol_args); | 2374 | return PTR_ERR(vol_args); |
@@ -5084,7 +5096,7 @@ static long btrfs_ioctl_quota_rescan_wait(struct file *file, void __user *arg) | |||
5084 | if (!capable(CAP_SYS_ADMIN)) | 5096 | if (!capable(CAP_SYS_ADMIN)) |
5085 | return -EPERM; | 5097 | return -EPERM; |
5086 | 5098 | ||
5087 | return btrfs_qgroup_wait_for_completion(root->fs_info); | 5099 | return btrfs_qgroup_wait_for_completion(root->fs_info, true); |
5088 | } | 5100 | } |
5089 | 5101 | ||
5090 | static long _btrfs_ioctl_set_received_subvol(struct file *file, | 5102 | static long _btrfs_ioctl_set_received_subvol(struct file *file, |
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 93ee1c18ef9d..8db2e29fdcf4 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c | |||
@@ -995,7 +995,7 @@ int btrfs_quota_disable(struct btrfs_trans_handle *trans, | |||
995 | goto out; | 995 | goto out; |
996 | fs_info->quota_enabled = 0; | 996 | fs_info->quota_enabled = 0; |
997 | fs_info->pending_quota_state = 0; | 997 | fs_info->pending_quota_state = 0; |
998 | btrfs_qgroup_wait_for_completion(fs_info); | 998 | btrfs_qgroup_wait_for_completion(fs_info, false); |
999 | spin_lock(&fs_info->qgroup_lock); | 999 | spin_lock(&fs_info->qgroup_lock); |
1000 | quota_root = fs_info->quota_root; | 1000 | quota_root = fs_info->quota_root; |
1001 | fs_info->quota_root = NULL; | 1001 | fs_info->quota_root = NULL; |
@@ -1453,10 +1453,9 @@ int btrfs_qgroup_prepare_account_extents(struct btrfs_trans_handle *trans, | |||
1453 | return ret; | 1453 | return ret; |
1454 | } | 1454 | } |
1455 | 1455 | ||
1456 | struct btrfs_qgroup_extent_record * | 1456 | int btrfs_qgroup_insert_dirty_extent_nolock(struct btrfs_fs_info *fs_info, |
1457 | btrfs_qgroup_insert_dirty_extent(struct btrfs_fs_info *fs_info, | 1457 | struct btrfs_delayed_ref_root *delayed_refs, |
1458 | struct btrfs_delayed_ref_root *delayed_refs, | 1458 | struct btrfs_qgroup_extent_record *record) |
1459 | struct btrfs_qgroup_extent_record *record) | ||
1460 | { | 1459 | { |
1461 | struct rb_node **p = &delayed_refs->dirty_extent_root.rb_node; | 1460 | struct rb_node **p = &delayed_refs->dirty_extent_root.rb_node; |
1462 | struct rb_node *parent_node = NULL; | 1461 | struct rb_node *parent_node = NULL; |
@@ -1475,12 +1474,42 @@ btrfs_qgroup_insert_dirty_extent(struct btrfs_fs_info *fs_info, | |||
1475 | else if (bytenr > entry->bytenr) | 1474 | else if (bytenr > entry->bytenr) |
1476 | p = &(*p)->rb_right; | 1475 | p = &(*p)->rb_right; |
1477 | else | 1476 | else |
1478 | return entry; | 1477 | return 1; |
1479 | } | 1478 | } |
1480 | 1479 | ||
1481 | rb_link_node(&record->node, parent_node, p); | 1480 | rb_link_node(&record->node, parent_node, p); |
1482 | rb_insert_color(&record->node, &delayed_refs->dirty_extent_root); | 1481 | rb_insert_color(&record->node, &delayed_refs->dirty_extent_root); |
1483 | return NULL; | 1482 | return 0; |
1483 | } | ||
1484 | |||
1485 | int btrfs_qgroup_insert_dirty_extent(struct btrfs_trans_handle *trans, | ||
1486 | struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes, | ||
1487 | gfp_t gfp_flag) | ||
1488 | { | ||
1489 | struct btrfs_qgroup_extent_record *record; | ||
1490 | struct btrfs_delayed_ref_root *delayed_refs; | ||
1491 | int ret; | ||
1492 | |||
1493 | if (!fs_info->quota_enabled || bytenr == 0 || num_bytes == 0) | ||
1494 | return 0; | ||
1495 | if (WARN_ON(trans == NULL)) | ||
1496 | return -EINVAL; | ||
1497 | record = kmalloc(sizeof(*record), gfp_flag); | ||
1498 | if (!record) | ||
1499 | return -ENOMEM; | ||
1500 | |||
1501 | delayed_refs = &trans->transaction->delayed_refs; | ||
1502 | record->bytenr = bytenr; | ||
1503 | record->num_bytes = num_bytes; | ||
1504 | record->old_roots = NULL; | ||
1505 | |||
1506 | spin_lock(&delayed_refs->lock); | ||
1507 | ret = btrfs_qgroup_insert_dirty_extent_nolock(fs_info, delayed_refs, | ||
1508 | record); | ||
1509 | spin_unlock(&delayed_refs->lock); | ||
1510 | if (ret > 0) | ||
1511 | kfree(record); | ||
1512 | return 0; | ||
1484 | } | 1513 | } |
1485 | 1514 | ||
1486 | #define UPDATE_NEW 0 | 1515 | #define UPDATE_NEW 0 |
@@ -2303,6 +2332,10 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work) | |||
2303 | int err = -ENOMEM; | 2332 | int err = -ENOMEM; |
2304 | int ret = 0; | 2333 | int ret = 0; |
2305 | 2334 | ||
2335 | mutex_lock(&fs_info->qgroup_rescan_lock); | ||
2336 | fs_info->qgroup_rescan_running = true; | ||
2337 | mutex_unlock(&fs_info->qgroup_rescan_lock); | ||
2338 | |||
2306 | path = btrfs_alloc_path(); | 2339 | path = btrfs_alloc_path(); |
2307 | if (!path) | 2340 | if (!path) |
2308 | goto out; | 2341 | goto out; |
@@ -2369,6 +2402,9 @@ out: | |||
2369 | } | 2402 | } |
2370 | 2403 | ||
2371 | done: | 2404 | done: |
2405 | mutex_lock(&fs_info->qgroup_rescan_lock); | ||
2406 | fs_info->qgroup_rescan_running = false; | ||
2407 | mutex_unlock(&fs_info->qgroup_rescan_lock); | ||
2372 | complete_all(&fs_info->qgroup_rescan_completion); | 2408 | complete_all(&fs_info->qgroup_rescan_completion); |
2373 | } | 2409 | } |
2374 | 2410 | ||
@@ -2487,20 +2523,26 @@ btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info) | |||
2487 | return 0; | 2523 | return 0; |
2488 | } | 2524 | } |
2489 | 2525 | ||
2490 | int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info) | 2526 | int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info, |
2527 | bool interruptible) | ||
2491 | { | 2528 | { |
2492 | int running; | 2529 | int running; |
2493 | int ret = 0; | 2530 | int ret = 0; |
2494 | 2531 | ||
2495 | mutex_lock(&fs_info->qgroup_rescan_lock); | 2532 | mutex_lock(&fs_info->qgroup_rescan_lock); |
2496 | spin_lock(&fs_info->qgroup_lock); | 2533 | spin_lock(&fs_info->qgroup_lock); |
2497 | running = fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN; | 2534 | running = fs_info->qgroup_rescan_running; |
2498 | spin_unlock(&fs_info->qgroup_lock); | 2535 | spin_unlock(&fs_info->qgroup_lock); |
2499 | mutex_unlock(&fs_info->qgroup_rescan_lock); | 2536 | mutex_unlock(&fs_info->qgroup_rescan_lock); |
2500 | 2537 | ||
2501 | if (running) | 2538 | if (!running) |
2539 | return 0; | ||
2540 | |||
2541 | if (interruptible) | ||
2502 | ret = wait_for_completion_interruptible( | 2542 | ret = wait_for_completion_interruptible( |
2503 | &fs_info->qgroup_rescan_completion); | 2543 | &fs_info->qgroup_rescan_completion); |
2544 | else | ||
2545 | wait_for_completion(&fs_info->qgroup_rescan_completion); | ||
2504 | 2546 | ||
2505 | return ret; | 2547 | return ret; |
2506 | } | 2548 | } |
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h index 710887c06aaf..1bc64c864b62 100644 --- a/fs/btrfs/qgroup.h +++ b/fs/btrfs/qgroup.h | |||
@@ -46,7 +46,8 @@ int btrfs_quota_disable(struct btrfs_trans_handle *trans, | |||
46 | struct btrfs_fs_info *fs_info); | 46 | struct btrfs_fs_info *fs_info); |
47 | int btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info); | 47 | int btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info); |
48 | void btrfs_qgroup_rescan_resume(struct btrfs_fs_info *fs_info); | 48 | void btrfs_qgroup_rescan_resume(struct btrfs_fs_info *fs_info); |
49 | int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info); | 49 | int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info, |
50 | bool interruptible); | ||
50 | int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, | 51 | int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, |
51 | struct btrfs_fs_info *fs_info, u64 src, u64 dst); | 52 | struct btrfs_fs_info *fs_info, u64 src, u64 dst); |
52 | int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, | 53 | int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, |
@@ -63,10 +64,35 @@ void btrfs_free_qgroup_config(struct btrfs_fs_info *fs_info); | |||
63 | struct btrfs_delayed_extent_op; | 64 | struct btrfs_delayed_extent_op; |
64 | int btrfs_qgroup_prepare_account_extents(struct btrfs_trans_handle *trans, | 65 | int btrfs_qgroup_prepare_account_extents(struct btrfs_trans_handle *trans, |
65 | struct btrfs_fs_info *fs_info); | 66 | struct btrfs_fs_info *fs_info); |
66 | struct btrfs_qgroup_extent_record * | 67 | /* |
67 | btrfs_qgroup_insert_dirty_extent(struct btrfs_fs_info *fs_info, | 68 | * Insert one dirty extent record into @delayed_refs, informing qgroup to |
68 | struct btrfs_delayed_ref_root *delayed_refs, | 69 | * account that extent at commit trans time. |
69 | struct btrfs_qgroup_extent_record *record); | 70 | * |
71 | * No lock version, caller must acquire delayed ref lock and allocate memory. | ||
72 | * | ||
73 | * Return 0 for success insert | ||
74 | * Return >0 for existing record, caller can free @record safely. | ||
75 | * Error is not possible | ||
76 | */ | ||
77 | int btrfs_qgroup_insert_dirty_extent_nolock( | ||
78 | struct btrfs_fs_info *fs_info, | ||
79 | struct btrfs_delayed_ref_root *delayed_refs, | ||
80 | struct btrfs_qgroup_extent_record *record); | ||
81 | |||
82 | /* | ||
83 | * Insert one dirty extent record into @delayed_refs, informing qgroup to | ||
84 | * account that extent at commit trans time. | ||
85 | * | ||
86 | * Better encapsulated version. | ||
87 | * | ||
88 | * Return 0 if the operation is done. | ||
89 | * Return <0 for error, like memory allocation failure or invalid parameter | ||
90 | * (NULL trans) | ||
91 | */ | ||
92 | int btrfs_qgroup_insert_dirty_extent(struct btrfs_trans_handle *trans, | ||
93 | struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes, | ||
94 | gfp_t gfp_flag); | ||
95 | |||
70 | int | 96 | int |
71 | btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, | 97 | btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, |
72 | struct btrfs_fs_info *fs_info, | 98 | struct btrfs_fs_info *fs_info, |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index b26a5aea41b4..c0c13dc6fe12 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "async-thread.h" | 31 | #include "async-thread.h" |
32 | #include "free-space-cache.h" | 32 | #include "free-space-cache.h" |
33 | #include "inode-map.h" | 33 | #include "inode-map.h" |
34 | #include "qgroup.h" | ||
34 | 35 | ||
35 | /* | 36 | /* |
36 | * backref_node, mapping_node and tree_block start with this | 37 | * backref_node, mapping_node and tree_block start with this |
@@ -3037,15 +3038,19 @@ int prealloc_file_extent_cluster(struct inode *inode, | |||
3037 | u64 num_bytes; | 3038 | u64 num_bytes; |
3038 | int nr = 0; | 3039 | int nr = 0; |
3039 | int ret = 0; | 3040 | int ret = 0; |
3041 | u64 prealloc_start = cluster->start - offset; | ||
3042 | u64 prealloc_end = cluster->end - offset; | ||
3043 | u64 cur_offset; | ||
3040 | 3044 | ||
3041 | BUG_ON(cluster->start != cluster->boundary[0]); | 3045 | BUG_ON(cluster->start != cluster->boundary[0]); |
3042 | inode_lock(inode); | 3046 | inode_lock(inode); |
3043 | 3047 | ||
3044 | ret = btrfs_check_data_free_space(inode, cluster->start, | 3048 | ret = btrfs_check_data_free_space(inode, prealloc_start, |
3045 | cluster->end + 1 - cluster->start); | 3049 | prealloc_end + 1 - prealloc_start); |
3046 | if (ret) | 3050 | if (ret) |
3047 | goto out; | 3051 | goto out; |
3048 | 3052 | ||
3053 | cur_offset = prealloc_start; | ||
3049 | while (nr < cluster->nr) { | 3054 | while (nr < cluster->nr) { |
3050 | start = cluster->boundary[nr] - offset; | 3055 | start = cluster->boundary[nr] - offset; |
3051 | if (nr + 1 < cluster->nr) | 3056 | if (nr + 1 < cluster->nr) |
@@ -3055,16 +3060,21 @@ int prealloc_file_extent_cluster(struct inode *inode, | |||
3055 | 3060 | ||
3056 | lock_extent(&BTRFS_I(inode)->io_tree, start, end); | 3061 | lock_extent(&BTRFS_I(inode)->io_tree, start, end); |
3057 | num_bytes = end + 1 - start; | 3062 | num_bytes = end + 1 - start; |
3063 | if (cur_offset < start) | ||
3064 | btrfs_free_reserved_data_space(inode, cur_offset, | ||
3065 | start - cur_offset); | ||
3058 | ret = btrfs_prealloc_file_range(inode, 0, start, | 3066 | ret = btrfs_prealloc_file_range(inode, 0, start, |
3059 | num_bytes, num_bytes, | 3067 | num_bytes, num_bytes, |
3060 | end + 1, &alloc_hint); | 3068 | end + 1, &alloc_hint); |
3069 | cur_offset = end + 1; | ||
3061 | unlock_extent(&BTRFS_I(inode)->io_tree, start, end); | 3070 | unlock_extent(&BTRFS_I(inode)->io_tree, start, end); |
3062 | if (ret) | 3071 | if (ret) |
3063 | break; | 3072 | break; |
3064 | nr++; | 3073 | nr++; |
3065 | } | 3074 | } |
3066 | btrfs_free_reserved_data_space(inode, cluster->start, | 3075 | if (cur_offset < prealloc_end) |
3067 | cluster->end + 1 - cluster->start); | 3076 | btrfs_free_reserved_data_space(inode, cur_offset, |
3077 | prealloc_end + 1 - cur_offset); | ||
3068 | out: | 3078 | out: |
3069 | inode_unlock(inode); | 3079 | inode_unlock(inode); |
3070 | return ret; | 3080 | return ret; |
@@ -3916,6 +3926,90 @@ int prepare_to_relocate(struct reloc_control *rc) | |||
3916 | return 0; | 3926 | return 0; |
3917 | } | 3927 | } |
3918 | 3928 | ||
3929 | /* | ||
3930 | * Qgroup fixer for data chunk relocation. | ||
3931 | * The data relocation is done in the following steps | ||
3932 | * 1) Copy data extents into data reloc tree | ||
3933 | * 2) Create tree reloc tree(special snapshot) for related subvolumes | ||
3934 | * 3) Modify file extents in tree reloc tree | ||
3935 | * 4) Merge tree reloc tree with original fs tree, by swapping tree blocks | ||
3936 | * | ||
3937 | * The problem is, data and tree reloc tree are not accounted to qgroup, | ||
3938 | * and 4) will only info qgroup to track tree blocks change, not file extents | ||
3939 | * in the tree blocks. | ||
3940 | * | ||
3941 | * The good news is, related data extents are all in data reloc tree, so we | ||
3942 | * only need to info qgroup to track all file extents in data reloc tree | ||
3943 | * before commit trans. | ||
3944 | */ | ||
3945 | static int qgroup_fix_relocated_data_extents(struct btrfs_trans_handle *trans, | ||
3946 | struct reloc_control *rc) | ||
3947 | { | ||
3948 | struct btrfs_fs_info *fs_info = rc->extent_root->fs_info; | ||
3949 | struct inode *inode = rc->data_inode; | ||
3950 | struct btrfs_root *data_reloc_root = BTRFS_I(inode)->root; | ||
3951 | struct btrfs_path *path; | ||
3952 | struct btrfs_key key; | ||
3953 | int ret = 0; | ||
3954 | |||
3955 | if (!fs_info->quota_enabled) | ||
3956 | return 0; | ||
3957 | |||
3958 | /* | ||
3959 | * Only for stage where we update data pointers the qgroup fix is | ||
3960 | * valid. | ||
3961 | * For MOVING_DATA stage, we will miss the timing of swapping tree | ||
3962 | * blocks, and won't fix it. | ||
3963 | */ | ||
3964 | if (!(rc->stage == UPDATE_DATA_PTRS && rc->extents_found)) | ||
3965 | return 0; | ||
3966 | |||
3967 | path = btrfs_alloc_path(); | ||
3968 | if (!path) | ||
3969 | return -ENOMEM; | ||
3970 | key.objectid = btrfs_ino(inode); | ||
3971 | key.type = BTRFS_EXTENT_DATA_KEY; | ||
3972 | key.offset = 0; | ||
3973 | |||
3974 | ret = btrfs_search_slot(NULL, data_reloc_root, &key, path, 0, 0); | ||
3975 | if (ret < 0) | ||
3976 | goto out; | ||
3977 | |||
3978 | lock_extent(&BTRFS_I(inode)->io_tree, 0, (u64)-1); | ||
3979 | while (1) { | ||
3980 | struct btrfs_file_extent_item *fi; | ||
3981 | |||
3982 | btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); | ||
3983 | if (key.objectid > btrfs_ino(inode)) | ||
3984 | break; | ||
3985 | if (key.type != BTRFS_EXTENT_DATA_KEY) | ||
3986 | goto next; | ||
3987 | fi = btrfs_item_ptr(path->nodes[0], path->slots[0], | ||
3988 | struct btrfs_file_extent_item); | ||
3989 | if (btrfs_file_extent_type(path->nodes[0], fi) != | ||
3990 | BTRFS_FILE_EXTENT_REG) | ||
3991 | goto next; | ||
3992 | ret = btrfs_qgroup_insert_dirty_extent(trans, fs_info, | ||
3993 | btrfs_file_extent_disk_bytenr(path->nodes[0], fi), | ||
3994 | btrfs_file_extent_disk_num_bytes(path->nodes[0], fi), | ||
3995 | GFP_NOFS); | ||
3996 | if (ret < 0) | ||
3997 | break; | ||
3998 | next: | ||
3999 | ret = btrfs_next_item(data_reloc_root, path); | ||
4000 | if (ret < 0) | ||
4001 | break; | ||
4002 | if (ret > 0) { | ||
4003 | ret = 0; | ||
4004 | break; | ||
4005 | } | ||
4006 | } | ||
4007 | unlock_extent(&BTRFS_I(inode)->io_tree, 0 , (u64)-1); | ||
4008 | out: | ||
4009 | btrfs_free_path(path); | ||
4010 | return ret; | ||
4011 | } | ||
4012 | |||
3919 | static noinline_for_stack int relocate_block_group(struct reloc_control *rc) | 4013 | static noinline_for_stack int relocate_block_group(struct reloc_control *rc) |
3920 | { | 4014 | { |
3921 | struct rb_root blocks = RB_ROOT; | 4015 | struct rb_root blocks = RB_ROOT; |
@@ -4102,10 +4196,18 @@ restart: | |||
4102 | 4196 | ||
4103 | /* get rid of pinned extents */ | 4197 | /* get rid of pinned extents */ |
4104 | trans = btrfs_join_transaction(rc->extent_root); | 4198 | trans = btrfs_join_transaction(rc->extent_root); |
4105 | if (IS_ERR(trans)) | 4199 | if (IS_ERR(trans)) { |
4106 | err = PTR_ERR(trans); | 4200 | err = PTR_ERR(trans); |
4107 | else | 4201 | goto out_free; |
4108 | btrfs_commit_transaction(trans, rc->extent_root); | 4202 | } |
4203 | ret = qgroup_fix_relocated_data_extents(trans, rc); | ||
4204 | if (ret < 0) { | ||
4205 | btrfs_abort_transaction(trans, ret); | ||
4206 | if (!err) | ||
4207 | err = ret; | ||
4208 | goto out_free; | ||
4209 | } | ||
4210 | btrfs_commit_transaction(trans, rc->extent_root); | ||
4109 | out_free: | 4211 | out_free: |
4110 | btrfs_free_block_rsv(rc->extent_root, rc->block_rsv); | 4212 | btrfs_free_block_rsv(rc->extent_root, rc->block_rsv); |
4111 | btrfs_free_path(path); | 4213 | btrfs_free_path(path); |
@@ -4468,10 +4570,16 @@ int btrfs_recover_relocation(struct btrfs_root *root) | |||
4468 | unset_reloc_control(rc); | 4570 | unset_reloc_control(rc); |
4469 | 4571 | ||
4470 | trans = btrfs_join_transaction(rc->extent_root); | 4572 | trans = btrfs_join_transaction(rc->extent_root); |
4471 | if (IS_ERR(trans)) | 4573 | if (IS_ERR(trans)) { |
4472 | err = PTR_ERR(trans); | 4574 | err = PTR_ERR(trans); |
4473 | else | 4575 | goto out_free; |
4474 | err = btrfs_commit_transaction(trans, rc->extent_root); | 4576 | } |
4577 | err = qgroup_fix_relocated_data_extents(trans, rc); | ||
4578 | if (err < 0) { | ||
4579 | btrfs_abort_transaction(trans, err); | ||
4580 | goto out_free; | ||
4581 | } | ||
4582 | err = btrfs_commit_transaction(trans, rc->extent_root); | ||
4475 | out_free: | 4583 | out_free: |
4476 | kfree(rc); | 4584 | kfree(rc); |
4477 | out: | 4585 | out: |
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 7fd7e1830cfe..091296062456 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c | |||
@@ -272,6 +272,23 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root) | |||
272 | root_key.objectid = key.offset; | 272 | root_key.objectid = key.offset; |
273 | key.offset++; | 273 | key.offset++; |
274 | 274 | ||
275 | /* | ||
276 | * The root might have been inserted already, as before we look | ||
277 | * for orphan roots, log replay might have happened, which | ||
278 | * triggers a transaction commit and qgroup accounting, which | ||
279 | * in turn reads and inserts fs roots while doing backref | ||
280 | * walking. | ||
281 | */ | ||
282 | root = btrfs_lookup_fs_root(tree_root->fs_info, | ||
283 | root_key.objectid); | ||
284 | if (root) { | ||
285 | WARN_ON(!test_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, | ||
286 | &root->state)); | ||
287 | if (btrfs_root_refs(&root->root_item) == 0) | ||
288 | btrfs_add_dead_root(root); | ||
289 | continue; | ||
290 | } | ||
291 | |||
275 | root = btrfs_read_fs_root(tree_root, &root_key); | 292 | root = btrfs_read_fs_root(tree_root, &root_key); |
276 | err = PTR_ERR_OR_ZERO(root); | 293 | err = PTR_ERR_OR_ZERO(root); |
277 | if (err && err != -ENOENT) { | 294 | if (err && err != -ENOENT) { |
@@ -310,16 +327,8 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root) | |||
310 | set_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state); | 327 | set_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state); |
311 | 328 | ||
312 | err = btrfs_insert_fs_root(root->fs_info, root); | 329 | err = btrfs_insert_fs_root(root->fs_info, root); |
313 | /* | ||
314 | * The root might have been inserted already, as before we look | ||
315 | * for orphan roots, log replay might have happened, which | ||
316 | * triggers a transaction commit and qgroup accounting, which | ||
317 | * in turn reads and inserts fs roots while doing backref | ||
318 | * walking. | ||
319 | */ | ||
320 | if (err == -EEXIST) | ||
321 | err = 0; | ||
322 | if (err) { | 330 | if (err) { |
331 | BUG_ON(err == -EEXIST); | ||
323 | btrfs_free_fs_root(root); | 332 | btrfs_free_fs_root(root); |
324 | break; | 333 | break; |
325 | } | 334 | } |
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index efe129fe2678..a87675ffd02b 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
@@ -4268,10 +4268,12 @@ static int process_all_refs(struct send_ctx *sctx, | |||
4268 | } | 4268 | } |
4269 | btrfs_release_path(path); | 4269 | btrfs_release_path(path); |
4270 | 4270 | ||
4271 | /* | ||
4272 | * We don't actually care about pending_move as we are simply | ||
4273 | * re-creating this inode and will be rename'ing it into place once we | ||
4274 | * rename the parent directory. | ||
4275 | */ | ||
4271 | ret = process_recorded_refs(sctx, &pending_move); | 4276 | ret = process_recorded_refs(sctx, &pending_move); |
4272 | /* Only applicable to an incremental send. */ | ||
4273 | ASSERT(pending_move == 0); | ||
4274 | |||
4275 | out: | 4277 | out: |
4276 | btrfs_free_path(path); | 4278 | btrfs_free_path(path); |
4277 | return ret; | 4279 | return ret; |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 864ce334f696..4071fe2bd098 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -2241,6 +2241,13 @@ static int btrfs_freeze(struct super_block *sb) | |||
2241 | struct btrfs_trans_handle *trans; | 2241 | struct btrfs_trans_handle *trans; |
2242 | struct btrfs_root *root = btrfs_sb(sb)->tree_root; | 2242 | struct btrfs_root *root = btrfs_sb(sb)->tree_root; |
2243 | 2243 | ||
2244 | root->fs_info->fs_frozen = 1; | ||
2245 | /* | ||
2246 | * We don't need a barrier here, we'll wait for any transaction that | ||
2247 | * could be in progress on other threads (and do delayed iputs that | ||
2248 | * we want to avoid on a frozen filesystem), or do the commit | ||
2249 | * ourselves. | ||
2250 | */ | ||
2244 | trans = btrfs_attach_transaction_barrier(root); | 2251 | trans = btrfs_attach_transaction_barrier(root); |
2245 | if (IS_ERR(trans)) { | 2252 | if (IS_ERR(trans)) { |
2246 | /* no transaction, don't bother */ | 2253 | /* no transaction, don't bother */ |
@@ -2251,6 +2258,14 @@ static int btrfs_freeze(struct super_block *sb) | |||
2251 | return btrfs_commit_transaction(trans, root); | 2258 | return btrfs_commit_transaction(trans, root); |
2252 | } | 2259 | } |
2253 | 2260 | ||
2261 | static int btrfs_unfreeze(struct super_block *sb) | ||
2262 | { | ||
2263 | struct btrfs_root *root = btrfs_sb(sb)->tree_root; | ||
2264 | |||
2265 | root->fs_info->fs_frozen = 0; | ||
2266 | return 0; | ||
2267 | } | ||
2268 | |||
2254 | static int btrfs_show_devname(struct seq_file *m, struct dentry *root) | 2269 | static int btrfs_show_devname(struct seq_file *m, struct dentry *root) |
2255 | { | 2270 | { |
2256 | struct btrfs_fs_info *fs_info = btrfs_sb(root->d_sb); | 2271 | struct btrfs_fs_info *fs_info = btrfs_sb(root->d_sb); |
@@ -2299,6 +2314,7 @@ static const struct super_operations btrfs_super_ops = { | |||
2299 | .statfs = btrfs_statfs, | 2314 | .statfs = btrfs_statfs, |
2300 | .remount_fs = btrfs_remount, | 2315 | .remount_fs = btrfs_remount, |
2301 | .freeze_fs = btrfs_freeze, | 2316 | .freeze_fs = btrfs_freeze, |
2317 | .unfreeze_fs = btrfs_unfreeze, | ||
2302 | }; | 2318 | }; |
2303 | 2319 | ||
2304 | static const struct file_operations btrfs_ctl_fops = { | 2320 | static const struct file_operations btrfs_ctl_fops = { |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 9cca0a721961..95d41919d034 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -2278,8 +2278,13 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
2278 | 2278 | ||
2279 | kmem_cache_free(btrfs_trans_handle_cachep, trans); | 2279 | kmem_cache_free(btrfs_trans_handle_cachep, trans); |
2280 | 2280 | ||
2281 | /* | ||
2282 | * If fs has been frozen, we can not handle delayed iputs, otherwise | ||
2283 | * it'll result in deadlock about SB_FREEZE_FS. | ||
2284 | */ | ||
2281 | if (current != root->fs_info->transaction_kthread && | 2285 | if (current != root->fs_info->transaction_kthread && |
2282 | current != root->fs_info->cleaner_kthread) | 2286 | current != root->fs_info->cleaner_kthread && |
2287 | !root->fs_info->fs_frozen) | ||
2283 | btrfs_run_delayed_iputs(root); | 2288 | btrfs_run_delayed_iputs(root); |
2284 | 2289 | ||
2285 | return ret; | 2290 | return ret; |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index fff3f3efa436..ef9c55bc7907 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "backref.h" | 27 | #include "backref.h" |
28 | #include "hash.h" | 28 | #include "hash.h" |
29 | #include "compression.h" | 29 | #include "compression.h" |
30 | #include "qgroup.h" | ||
30 | 31 | ||
31 | /* magic values for the inode_only field in btrfs_log_inode: | 32 | /* magic values for the inode_only field in btrfs_log_inode: |
32 | * | 33 | * |
@@ -680,6 +681,21 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
680 | ins.type = BTRFS_EXTENT_ITEM_KEY; | 681 | ins.type = BTRFS_EXTENT_ITEM_KEY; |
681 | offset = key->offset - btrfs_file_extent_offset(eb, item); | 682 | offset = key->offset - btrfs_file_extent_offset(eb, item); |
682 | 683 | ||
684 | /* | ||
685 | * Manually record dirty extent, as here we did a shallow | ||
686 | * file extent item copy and skip normal backref update, | ||
687 | * but modifying extent tree all by ourselves. | ||
688 | * So need to manually record dirty extent for qgroup, | ||
689 | * as the owner of the file extent changed from log tree | ||
690 | * (doesn't affect qgroup) to fs/file tree(affects qgroup) | ||
691 | */ | ||
692 | ret = btrfs_qgroup_insert_dirty_extent(trans, root->fs_info, | ||
693 | btrfs_file_extent_disk_bytenr(eb, item), | ||
694 | btrfs_file_extent_disk_num_bytes(eb, item), | ||
695 | GFP_NOFS); | ||
696 | if (ret < 0) | ||
697 | goto out; | ||
698 | |||
683 | if (ins.objectid > 0) { | 699 | if (ins.objectid > 0) { |
684 | u64 csum_start; | 700 | u64 csum_start; |
685 | u64 csum_end; | 701 | u64 csum_end; |
@@ -2807,7 +2823,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
2807 | */ | 2823 | */ |
2808 | mutex_unlock(&root->log_mutex); | 2824 | mutex_unlock(&root->log_mutex); |
2809 | 2825 | ||
2810 | btrfs_init_log_ctx(&root_log_ctx); | 2826 | btrfs_init_log_ctx(&root_log_ctx, NULL); |
2811 | 2827 | ||
2812 | mutex_lock(&log_root_tree->log_mutex); | 2828 | mutex_lock(&log_root_tree->log_mutex); |
2813 | atomic_inc(&log_root_tree->log_batch); | 2829 | atomic_inc(&log_root_tree->log_batch); |
@@ -2851,6 +2867,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
2851 | 2867 | ||
2852 | if (log_root_tree->log_transid_committed >= root_log_ctx.log_transid) { | 2868 | if (log_root_tree->log_transid_committed >= root_log_ctx.log_transid) { |
2853 | blk_finish_plug(&plug); | 2869 | blk_finish_plug(&plug); |
2870 | list_del_init(&root_log_ctx.list); | ||
2854 | mutex_unlock(&log_root_tree->log_mutex); | 2871 | mutex_unlock(&log_root_tree->log_mutex); |
2855 | ret = root_log_ctx.log_ret; | 2872 | ret = root_log_ctx.log_ret; |
2856 | goto out; | 2873 | goto out; |
@@ -4741,7 +4758,8 @@ again: | |||
4741 | if (ret < 0) { | 4758 | if (ret < 0) { |
4742 | err = ret; | 4759 | err = ret; |
4743 | goto out_unlock; | 4760 | goto out_unlock; |
4744 | } else if (ret > 0) { | 4761 | } else if (ret > 0 && ctx && |
4762 | other_ino != btrfs_ino(ctx->inode)) { | ||
4745 | struct btrfs_key inode_key; | 4763 | struct btrfs_key inode_key; |
4746 | struct inode *other_inode; | 4764 | struct inode *other_inode; |
4747 | 4765 | ||
diff --git a/fs/btrfs/tree-log.h b/fs/btrfs/tree-log.h index a9f1b75d080d..ab858e31ccbc 100644 --- a/fs/btrfs/tree-log.h +++ b/fs/btrfs/tree-log.h | |||
@@ -30,15 +30,18 @@ struct btrfs_log_ctx { | |||
30 | int log_transid; | 30 | int log_transid; |
31 | int io_err; | 31 | int io_err; |
32 | bool log_new_dentries; | 32 | bool log_new_dentries; |
33 | struct inode *inode; | ||
33 | struct list_head list; | 34 | struct list_head list; |
34 | }; | 35 | }; |
35 | 36 | ||
36 | static inline void btrfs_init_log_ctx(struct btrfs_log_ctx *ctx) | 37 | static inline void btrfs_init_log_ctx(struct btrfs_log_ctx *ctx, |
38 | struct inode *inode) | ||
37 | { | 39 | { |
38 | ctx->log_ret = 0; | 40 | ctx->log_ret = 0; |
39 | ctx->log_transid = 0; | 41 | ctx->log_transid = 0; |
40 | ctx->io_err = 0; | 42 | ctx->io_err = 0; |
41 | ctx->log_new_dentries = false; | 43 | ctx->log_new_dentries = false; |
44 | ctx->inode = inode; | ||
42 | INIT_LIST_HEAD(&ctx->list); | 45 | INIT_LIST_HEAD(&ctx->list); |
43 | } | 46 | } |
44 | 47 | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 51f125508771..035efce603a9 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -834,10 +834,6 @@ static void __free_device(struct work_struct *work) | |||
834 | struct btrfs_device *device; | 834 | struct btrfs_device *device; |
835 | 835 | ||
836 | device = container_of(work, struct btrfs_device, rcu_work); | 836 | device = container_of(work, struct btrfs_device, rcu_work); |
837 | |||
838 | if (device->bdev) | ||
839 | blkdev_put(device->bdev, device->mode); | ||
840 | |||
841 | rcu_string_free(device->name); | 837 | rcu_string_free(device->name); |
842 | kfree(device); | 838 | kfree(device); |
843 | } | 839 | } |
@@ -852,6 +848,17 @@ static void free_device(struct rcu_head *head) | |||
852 | schedule_work(&device->rcu_work); | 848 | schedule_work(&device->rcu_work); |
853 | } | 849 | } |
854 | 850 | ||
851 | static void btrfs_close_bdev(struct btrfs_device *device) | ||
852 | { | ||
853 | if (device->bdev && device->writeable) { | ||
854 | sync_blockdev(device->bdev); | ||
855 | invalidate_bdev(device->bdev); | ||
856 | } | ||
857 | |||
858 | if (device->bdev) | ||
859 | blkdev_put(device->bdev, device->mode); | ||
860 | } | ||
861 | |||
855 | static void btrfs_close_one_device(struct btrfs_device *device) | 862 | static void btrfs_close_one_device(struct btrfs_device *device) |
856 | { | 863 | { |
857 | struct btrfs_fs_devices *fs_devices = device->fs_devices; | 864 | struct btrfs_fs_devices *fs_devices = device->fs_devices; |
@@ -870,10 +877,7 @@ static void btrfs_close_one_device(struct btrfs_device *device) | |||
870 | if (device->missing) | 877 | if (device->missing) |
871 | fs_devices->missing_devices--; | 878 | fs_devices->missing_devices--; |
872 | 879 | ||
873 | if (device->bdev && device->writeable) { | 880 | btrfs_close_bdev(device); |
874 | sync_blockdev(device->bdev); | ||
875 | invalidate_bdev(device->bdev); | ||
876 | } | ||
877 | 881 | ||
878 | new_device = btrfs_alloc_device(NULL, &device->devid, | 882 | new_device = btrfs_alloc_device(NULL, &device->devid, |
879 | device->uuid); | 883 | device->uuid); |
@@ -1932,6 +1936,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid) | |||
1932 | btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device); | 1936 | btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device); |
1933 | } | 1937 | } |
1934 | 1938 | ||
1939 | btrfs_close_bdev(device); | ||
1940 | |||
1935 | call_rcu(&device->rcu, free_device); | 1941 | call_rcu(&device->rcu, free_device); |
1936 | 1942 | ||
1937 | num_devices = btrfs_super_num_devices(root->fs_info->super_copy) - 1; | 1943 | num_devices = btrfs_super_num_devices(root->fs_info->super_copy) - 1; |
@@ -2025,6 +2031,9 @@ void btrfs_rm_dev_replace_free_srcdev(struct btrfs_fs_info *fs_info, | |||
2025 | /* zero out the old super if it is writable */ | 2031 | /* zero out the old super if it is writable */ |
2026 | btrfs_scratch_superblocks(srcdev->bdev, srcdev->name->str); | 2032 | btrfs_scratch_superblocks(srcdev->bdev, srcdev->name->str); |
2027 | } | 2033 | } |
2034 | |||
2035 | btrfs_close_bdev(srcdev); | ||
2036 | |||
2028 | call_rcu(&srcdev->rcu, free_device); | 2037 | call_rcu(&srcdev->rcu, free_device); |
2029 | 2038 | ||
2030 | /* | 2039 | /* |
@@ -2080,6 +2089,8 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info, | |||
2080 | * the device_list_mutex lock. | 2089 | * the device_list_mutex lock. |
2081 | */ | 2090 | */ |
2082 | btrfs_scratch_superblocks(tgtdev->bdev, tgtdev->name->str); | 2091 | btrfs_scratch_superblocks(tgtdev->bdev, tgtdev->name->str); |
2092 | |||
2093 | btrfs_close_bdev(tgtdev); | ||
2083 | call_rcu(&tgtdev->rcu, free_device); | 2094 | call_rcu(&tgtdev->rcu, free_device); |
2084 | } | 2095 | } |
2085 | 2096 | ||
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index c64a0b794d49..df4b3e6fa563 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -597,7 +597,7 @@ static bool need_reset_readdir(struct ceph_file_info *fi, loff_t new_pos) | |||
597 | if (is_hash_order(new_pos)) { | 597 | if (is_hash_order(new_pos)) { |
598 | /* no need to reset last_name for a forward seek when | 598 | /* no need to reset last_name for a forward seek when |
599 | * dentries are sotred in hash order */ | 599 | * dentries are sotred in hash order */ |
600 | } else if (fi->frag |= fpos_frag(new_pos)) { | 600 | } else if (fi->frag != fpos_frag(new_pos)) { |
601 | return true; | 601 | return true; |
602 | } | 602 | } |
603 | rinfo = fi->last_readdir ? &fi->last_readdir->r_reply_info : NULL; | 603 | rinfo = fi->last_readdir ? &fi->last_readdir->r_reply_info : NULL; |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 6bbec5e784cd..14ae4b8e1a3c 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -609,6 +609,9 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) | |||
609 | char *s, *p; | 609 | char *s, *p; |
610 | char sep; | 610 | char sep; |
611 | 611 | ||
612 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) | ||
613 | return dget(sb->s_root); | ||
614 | |||
612 | full_path = cifs_build_path_to_root(vol, cifs_sb, | 615 | full_path = cifs_build_path_to_root(vol, cifs_sb, |
613 | cifs_sb_master_tcon(cifs_sb)); | 616 | cifs_sb_master_tcon(cifs_sb)); |
614 | if (full_path == NULL) | 617 | if (full_path == NULL) |
@@ -686,26 +689,22 @@ cifs_do_mount(struct file_system_type *fs_type, | |||
686 | cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL); | 689 | cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL); |
687 | if (cifs_sb->mountdata == NULL) { | 690 | if (cifs_sb->mountdata == NULL) { |
688 | root = ERR_PTR(-ENOMEM); | 691 | root = ERR_PTR(-ENOMEM); |
689 | goto out_cifs_sb; | 692 | goto out_free; |
690 | } | 693 | } |
691 | 694 | ||
692 | if (volume_info->prepath) { | 695 | rc = cifs_setup_cifs_sb(volume_info, cifs_sb); |
693 | cifs_sb->prepath = kstrdup(volume_info->prepath, GFP_KERNEL); | 696 | if (rc) { |
694 | if (cifs_sb->prepath == NULL) { | 697 | root = ERR_PTR(rc); |
695 | root = ERR_PTR(-ENOMEM); | 698 | goto out_free; |
696 | goto out_cifs_sb; | ||
697 | } | ||
698 | } | 699 | } |
699 | 700 | ||
700 | cifs_setup_cifs_sb(volume_info, cifs_sb); | ||
701 | |||
702 | rc = cifs_mount(cifs_sb, volume_info); | 701 | rc = cifs_mount(cifs_sb, volume_info); |
703 | if (rc) { | 702 | if (rc) { |
704 | if (!(flags & MS_SILENT)) | 703 | if (!(flags & MS_SILENT)) |
705 | cifs_dbg(VFS, "cifs_mount failed w/return code = %d\n", | 704 | cifs_dbg(VFS, "cifs_mount failed w/return code = %d\n", |
706 | rc); | 705 | rc); |
707 | root = ERR_PTR(rc); | 706 | root = ERR_PTR(rc); |
708 | goto out_mountdata; | 707 | goto out_free; |
709 | } | 708 | } |
710 | 709 | ||
711 | mnt_data.vol = volume_info; | 710 | mnt_data.vol = volume_info; |
@@ -735,11 +734,7 @@ cifs_do_mount(struct file_system_type *fs_type, | |||
735 | sb->s_flags |= MS_ACTIVE; | 734 | sb->s_flags |= MS_ACTIVE; |
736 | } | 735 | } |
737 | 736 | ||
738 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) | 737 | root = cifs_get_root(volume_info, sb); |
739 | root = dget(sb->s_root); | ||
740 | else | ||
741 | root = cifs_get_root(volume_info, sb); | ||
742 | |||
743 | if (IS_ERR(root)) | 738 | if (IS_ERR(root)) |
744 | goto out_super; | 739 | goto out_super; |
745 | 740 | ||
@@ -752,9 +747,9 @@ out: | |||
752 | cifs_cleanup_volume_info(volume_info); | 747 | cifs_cleanup_volume_info(volume_info); |
753 | return root; | 748 | return root; |
754 | 749 | ||
755 | out_mountdata: | 750 | out_free: |
751 | kfree(cifs_sb->prepath); | ||
756 | kfree(cifs_sb->mountdata); | 752 | kfree(cifs_sb->mountdata); |
757 | out_cifs_sb: | ||
758 | kfree(cifs_sb); | 753 | kfree(cifs_sb); |
759 | out_nls: | 754 | out_nls: |
760 | unload_nls(volume_info->local_nls); | 755 | unload_nls(volume_info->local_nls); |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 1243bd326591..95dab43646f0 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -184,7 +184,7 @@ extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf, | |||
184 | unsigned int to_read); | 184 | unsigned int to_read); |
185 | extern int cifs_read_page_from_socket(struct TCP_Server_Info *server, | 185 | extern int cifs_read_page_from_socket(struct TCP_Server_Info *server, |
186 | struct page *page, unsigned int to_read); | 186 | struct page *page, unsigned int to_read); |
187 | extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, | 187 | extern int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, |
188 | struct cifs_sb_info *cifs_sb); | 188 | struct cifs_sb_info *cifs_sb); |
189 | extern int cifs_match_super(struct super_block *, void *); | 189 | extern int cifs_match_super(struct super_block *, void *); |
190 | extern void cifs_cleanup_volume_info(struct smb_vol *pvolume_info); | 190 | extern void cifs_cleanup_volume_info(struct smb_vol *pvolume_info); |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 7ae03283bd61..2e4f4bad8b1e 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -2781,6 +2781,24 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data) | |||
2781 | return 1; | 2781 | return 1; |
2782 | } | 2782 | } |
2783 | 2783 | ||
2784 | static int | ||
2785 | match_prepath(struct super_block *sb, struct cifs_mnt_data *mnt_data) | ||
2786 | { | ||
2787 | struct cifs_sb_info *old = CIFS_SB(sb); | ||
2788 | struct cifs_sb_info *new = mnt_data->cifs_sb; | ||
2789 | |||
2790 | if (old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) { | ||
2791 | if (!(new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH)) | ||
2792 | return 0; | ||
2793 | /* The prepath should be null terminated strings */ | ||
2794 | if (strcmp(new->prepath, old->prepath)) | ||
2795 | return 0; | ||
2796 | |||
2797 | return 1; | ||
2798 | } | ||
2799 | return 0; | ||
2800 | } | ||
2801 | |||
2784 | int | 2802 | int |
2785 | cifs_match_super(struct super_block *sb, void *data) | 2803 | cifs_match_super(struct super_block *sb, void *data) |
2786 | { | 2804 | { |
@@ -2808,7 +2826,8 @@ cifs_match_super(struct super_block *sb, void *data) | |||
2808 | 2826 | ||
2809 | if (!match_server(tcp_srv, volume_info) || | 2827 | if (!match_server(tcp_srv, volume_info) || |
2810 | !match_session(ses, volume_info) || | 2828 | !match_session(ses, volume_info) || |
2811 | !match_tcon(tcon, volume_info->UNC)) { | 2829 | !match_tcon(tcon, volume_info->UNC) || |
2830 | !match_prepath(sb, mnt_data)) { | ||
2812 | rc = 0; | 2831 | rc = 0; |
2813 | goto out; | 2832 | goto out; |
2814 | } | 2833 | } |
@@ -3222,7 +3241,7 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon, | |||
3222 | } | 3241 | } |
3223 | } | 3242 | } |
3224 | 3243 | ||
3225 | void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, | 3244 | int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, |
3226 | struct cifs_sb_info *cifs_sb) | 3245 | struct cifs_sb_info *cifs_sb) |
3227 | { | 3246 | { |
3228 | INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); | 3247 | INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); |
@@ -3316,6 +3335,14 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, | |||
3316 | 3335 | ||
3317 | if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm)) | 3336 | if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm)) |
3318 | cifs_dbg(VFS, "mount option dynperm ignored if cifsacl mount option supported\n"); | 3337 | cifs_dbg(VFS, "mount option dynperm ignored if cifsacl mount option supported\n"); |
3338 | |||
3339 | if (pvolume_info->prepath) { | ||
3340 | cifs_sb->prepath = kstrdup(pvolume_info->prepath, GFP_KERNEL); | ||
3341 | if (cifs_sb->prepath == NULL) | ||
3342 | return -ENOMEM; | ||
3343 | } | ||
3344 | |||
3345 | return 0; | ||
3319 | } | 3346 | } |
3320 | 3347 | ||
3321 | static void | 3348 | static void |
diff --git a/fs/configfs/file.c b/fs/configfs/file.c index c30cf49b69d2..2c6312db8516 100644 --- a/fs/configfs/file.c +++ b/fs/configfs/file.c | |||
@@ -333,6 +333,7 @@ configfs_write_bin_file(struct file *file, const char __user *buf, | |||
333 | if (bin_attr->cb_max_size && | 333 | if (bin_attr->cb_max_size && |
334 | *ppos + count > bin_attr->cb_max_size) { | 334 | *ppos + count > bin_attr->cb_max_size) { |
335 | len = -EFBIG; | 335 | len = -EFBIG; |
336 | goto out; | ||
336 | } | 337 | } |
337 | 338 | ||
338 | tbuf = vmalloc(*ppos + count); | 339 | tbuf = vmalloc(*ppos + count); |
diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c index 0f9961eede1e..ed115acb5dee 100644 --- a/fs/crypto/policy.c +++ b/fs/crypto/policy.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/random.h> | 11 | #include <linux/random.h> |
12 | #include <linux/string.h> | 12 | #include <linux/string.h> |
13 | #include <linux/fscrypto.h> | 13 | #include <linux/fscrypto.h> |
14 | #include <linux/mount.h> | ||
14 | 15 | ||
15 | static int inode_has_encryption_context(struct inode *inode) | 16 | static int inode_has_encryption_context(struct inode *inode) |
16 | { | 17 | { |
@@ -92,26 +93,42 @@ static int create_encryption_context_from_policy(struct inode *inode, | |||
92 | return inode->i_sb->s_cop->set_context(inode, &ctx, sizeof(ctx), NULL); | 93 | return inode->i_sb->s_cop->set_context(inode, &ctx, sizeof(ctx), NULL); |
93 | } | 94 | } |
94 | 95 | ||
95 | int fscrypt_process_policy(struct inode *inode, | 96 | int fscrypt_process_policy(struct file *filp, |
96 | const struct fscrypt_policy *policy) | 97 | const struct fscrypt_policy *policy) |
97 | { | 98 | { |
99 | struct inode *inode = file_inode(filp); | ||
100 | int ret; | ||
101 | |||
102 | if (!inode_owner_or_capable(inode)) | ||
103 | return -EACCES; | ||
104 | |||
98 | if (policy->version != 0) | 105 | if (policy->version != 0) |
99 | return -EINVAL; | 106 | return -EINVAL; |
100 | 107 | ||
108 | ret = mnt_want_write_file(filp); | ||
109 | if (ret) | ||
110 | return ret; | ||
111 | |||
101 | if (!inode_has_encryption_context(inode)) { | 112 | if (!inode_has_encryption_context(inode)) { |
102 | if (!inode->i_sb->s_cop->empty_dir) | 113 | if (!S_ISDIR(inode->i_mode)) |
103 | return -EOPNOTSUPP; | 114 | ret = -EINVAL; |
104 | if (!inode->i_sb->s_cop->empty_dir(inode)) | 115 | else if (!inode->i_sb->s_cop->empty_dir) |
105 | return -ENOTEMPTY; | 116 | ret = -EOPNOTSUPP; |
106 | return create_encryption_context_from_policy(inode, policy); | 117 | else if (!inode->i_sb->s_cop->empty_dir(inode)) |
118 | ret = -ENOTEMPTY; | ||
119 | else | ||
120 | ret = create_encryption_context_from_policy(inode, | ||
121 | policy); | ||
122 | } else if (!is_encryption_context_consistent_with_policy(inode, | ||
123 | policy)) { | ||
124 | printk(KERN_WARNING | ||
125 | "%s: Policy inconsistent with encryption context\n", | ||
126 | __func__); | ||
127 | ret = -EINVAL; | ||
107 | } | 128 | } |
108 | 129 | ||
109 | if (is_encryption_context_consistent_with_policy(inode, policy)) | 130 | mnt_drop_write_file(filp); |
110 | return 0; | 131 | return ret; |
111 | |||
112 | printk(KERN_WARNING "%s: Policy inconsistent with encryption context\n", | ||
113 | __func__); | ||
114 | return -EINVAL; | ||
115 | } | 132 | } |
116 | EXPORT_SYMBOL(fscrypt_process_policy); | 133 | EXPORT_SYMBOL(fscrypt_process_policy); |
117 | 134 | ||
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index d116453b0276..79a5941c2474 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
@@ -585,7 +585,8 @@ struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv) | |||
585 | */ | 585 | */ |
586 | void *devpts_get_priv(struct dentry *dentry) | 586 | void *devpts_get_priv(struct dentry *dentry) |
587 | { | 587 | { |
588 | WARN_ON_ONCE(dentry->d_sb->s_magic != DEVPTS_SUPER_MAGIC); | 588 | if (dentry->d_sb->s_magic != DEVPTS_SUPER_MAGIC) |
589 | return NULL; | ||
589 | return dentry->d_fsdata; | 590 | return dentry->d_fsdata; |
590 | } | 591 | } |
591 | 592 | ||
diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c index eea64912c9c0..466f7d60edc2 100644 --- a/fs/dlm/debug_fs.c +++ b/fs/dlm/debug_fs.c | |||
@@ -607,20 +607,54 @@ static const struct file_operations format2_fops; | |||
607 | static const struct file_operations format3_fops; | 607 | static const struct file_operations format3_fops; |
608 | static const struct file_operations format4_fops; | 608 | static const struct file_operations format4_fops; |
609 | 609 | ||
610 | static int table_open(struct inode *inode, struct file *file) | 610 | static int table_open1(struct inode *inode, struct file *file) |
611 | { | 611 | { |
612 | struct seq_file *seq; | 612 | struct seq_file *seq; |
613 | int ret = -1; | 613 | int ret; |
614 | 614 | ||
615 | if (file->f_op == &format1_fops) | 615 | ret = seq_open(file, &format1_seq_ops); |
616 | ret = seq_open(file, &format1_seq_ops); | 616 | if (ret) |
617 | else if (file->f_op == &format2_fops) | 617 | return ret; |
618 | ret = seq_open(file, &format2_seq_ops); | 618 | |
619 | else if (file->f_op == &format3_fops) | 619 | seq = file->private_data; |
620 | ret = seq_open(file, &format3_seq_ops); | 620 | seq->private = inode->i_private; /* the dlm_ls */ |
621 | else if (file->f_op == &format4_fops) | 621 | return 0; |
622 | ret = seq_open(file, &format4_seq_ops); | 622 | } |
623 | |||
624 | static int table_open2(struct inode *inode, struct file *file) | ||
625 | { | ||
626 | struct seq_file *seq; | ||
627 | int ret; | ||
628 | |||
629 | ret = seq_open(file, &format2_seq_ops); | ||
630 | if (ret) | ||
631 | return ret; | ||
632 | |||
633 | seq = file->private_data; | ||
634 | seq->private = inode->i_private; /* the dlm_ls */ | ||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | static int table_open3(struct inode *inode, struct file *file) | ||
639 | { | ||
640 | struct seq_file *seq; | ||
641 | int ret; | ||
642 | |||
643 | ret = seq_open(file, &format3_seq_ops); | ||
644 | if (ret) | ||
645 | return ret; | ||
646 | |||
647 | seq = file->private_data; | ||
648 | seq->private = inode->i_private; /* the dlm_ls */ | ||
649 | return 0; | ||
650 | } | ||
651 | |||
652 | static int table_open4(struct inode *inode, struct file *file) | ||
653 | { | ||
654 | struct seq_file *seq; | ||
655 | int ret; | ||
623 | 656 | ||
657 | ret = seq_open(file, &format4_seq_ops); | ||
624 | if (ret) | 658 | if (ret) |
625 | return ret; | 659 | return ret; |
626 | 660 | ||
@@ -631,7 +665,7 @@ static int table_open(struct inode *inode, struct file *file) | |||
631 | 665 | ||
632 | static const struct file_operations format1_fops = { | 666 | static const struct file_operations format1_fops = { |
633 | .owner = THIS_MODULE, | 667 | .owner = THIS_MODULE, |
634 | .open = table_open, | 668 | .open = table_open1, |
635 | .read = seq_read, | 669 | .read = seq_read, |
636 | .llseek = seq_lseek, | 670 | .llseek = seq_lseek, |
637 | .release = seq_release | 671 | .release = seq_release |
@@ -639,7 +673,7 @@ static const struct file_operations format1_fops = { | |||
639 | 673 | ||
640 | static const struct file_operations format2_fops = { | 674 | static const struct file_operations format2_fops = { |
641 | .owner = THIS_MODULE, | 675 | .owner = THIS_MODULE, |
642 | .open = table_open, | 676 | .open = table_open2, |
643 | .read = seq_read, | 677 | .read = seq_read, |
644 | .llseek = seq_lseek, | 678 | .llseek = seq_lseek, |
645 | .release = seq_release | 679 | .release = seq_release |
@@ -647,7 +681,7 @@ static const struct file_operations format2_fops = { | |||
647 | 681 | ||
648 | static const struct file_operations format3_fops = { | 682 | static const struct file_operations format3_fops = { |
649 | .owner = THIS_MODULE, | 683 | .owner = THIS_MODULE, |
650 | .open = table_open, | 684 | .open = table_open3, |
651 | .read = seq_read, | 685 | .read = seq_read, |
652 | .llseek = seq_lseek, | 686 | .llseek = seq_lseek, |
653 | .release = seq_release | 687 | .release = seq_release |
@@ -655,7 +689,7 @@ static const struct file_operations format3_fops = { | |||
655 | 689 | ||
656 | static const struct file_operations format4_fops = { | 690 | static const struct file_operations format4_fops = { |
657 | .owner = THIS_MODULE, | 691 | .owner = THIS_MODULE, |
658 | .open = table_open, | 692 | .open = table_open4, |
659 | .read = seq_read, | 693 | .read = seq_read, |
660 | .llseek = seq_lseek, | 694 | .llseek = seq_lseek, |
661 | .release = seq_release | 695 | .release = seq_release |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 3131747199e1..c6ea25a190f8 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -5466,8 +5466,6 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) | |||
5466 | sbi->s_want_extra_isize, | 5466 | sbi->s_want_extra_isize, |
5467 | iloc, handle); | 5467 | iloc, handle); |
5468 | if (ret) { | 5468 | if (ret) { |
5469 | ext4_set_inode_state(inode, | ||
5470 | EXT4_STATE_NO_EXPAND); | ||
5471 | if (mnt_count != | 5469 | if (mnt_count != |
5472 | le16_to_cpu(sbi->s_es->s_mnt_count)) { | 5470 | le16_to_cpu(sbi->s_es->s_mnt_count)) { |
5473 | ext4_warning(inode->i_sb, | 5471 | ext4_warning(inode->i_sb, |
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 10686fd67fb4..1bb7df5e4536 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
@@ -776,7 +776,7 @@ resizefs_out: | |||
776 | (struct fscrypt_policy __user *)arg, | 776 | (struct fscrypt_policy __user *)arg, |
777 | sizeof(policy))) | 777 | sizeof(policy))) |
778 | return -EFAULT; | 778 | return -EFAULT; |
779 | return fscrypt_process_policy(inode, &policy); | 779 | return fscrypt_process_policy(filp, &policy); |
780 | #else | 780 | #else |
781 | return -EOPNOTSUPP; | 781 | return -EOPNOTSUPP; |
782 | #endif | 782 | #endif |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 1c593aa0218e..3ec8708989ca 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -2211,6 +2211,7 @@ void ext4_group_desc_csum_set(struct super_block *sb, __u32 block_group, | |||
2211 | 2211 | ||
2212 | /* Called at mount-time, super-block is locked */ | 2212 | /* Called at mount-time, super-block is locked */ |
2213 | static int ext4_check_descriptors(struct super_block *sb, | 2213 | static int ext4_check_descriptors(struct super_block *sb, |
2214 | ext4_fsblk_t sb_block, | ||
2214 | ext4_group_t *first_not_zeroed) | 2215 | ext4_group_t *first_not_zeroed) |
2215 | { | 2216 | { |
2216 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2217 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
@@ -2241,6 +2242,11 @@ static int ext4_check_descriptors(struct super_block *sb, | |||
2241 | grp = i; | 2242 | grp = i; |
2242 | 2243 | ||
2243 | block_bitmap = ext4_block_bitmap(sb, gdp); | 2244 | block_bitmap = ext4_block_bitmap(sb, gdp); |
2245 | if (block_bitmap == sb_block) { | ||
2246 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " | ||
2247 | "Block bitmap for group %u overlaps " | ||
2248 | "superblock", i); | ||
2249 | } | ||
2244 | if (block_bitmap < first_block || block_bitmap > last_block) { | 2250 | if (block_bitmap < first_block || block_bitmap > last_block) { |
2245 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " | 2251 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |
2246 | "Block bitmap for group %u not in group " | 2252 | "Block bitmap for group %u not in group " |
@@ -2248,6 +2254,11 @@ static int ext4_check_descriptors(struct super_block *sb, | |||
2248 | return 0; | 2254 | return 0; |
2249 | } | 2255 | } |
2250 | inode_bitmap = ext4_inode_bitmap(sb, gdp); | 2256 | inode_bitmap = ext4_inode_bitmap(sb, gdp); |
2257 | if (inode_bitmap == sb_block) { | ||
2258 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " | ||
2259 | "Inode bitmap for group %u overlaps " | ||
2260 | "superblock", i); | ||
2261 | } | ||
2251 | if (inode_bitmap < first_block || inode_bitmap > last_block) { | 2262 | if (inode_bitmap < first_block || inode_bitmap > last_block) { |
2252 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " | 2263 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |
2253 | "Inode bitmap for group %u not in group " | 2264 | "Inode bitmap for group %u not in group " |
@@ -2255,6 +2266,11 @@ static int ext4_check_descriptors(struct super_block *sb, | |||
2255 | return 0; | 2266 | return 0; |
2256 | } | 2267 | } |
2257 | inode_table = ext4_inode_table(sb, gdp); | 2268 | inode_table = ext4_inode_table(sb, gdp); |
2269 | if (inode_table == sb_block) { | ||
2270 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " | ||
2271 | "Inode table for group %u overlaps " | ||
2272 | "superblock", i); | ||
2273 | } | ||
2258 | if (inode_table < first_block || | 2274 | if (inode_table < first_block || |
2259 | inode_table + sbi->s_itb_per_group - 1 > last_block) { | 2275 | inode_table + sbi->s_itb_per_group - 1 > last_block) { |
2260 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " | 2276 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |
@@ -3757,7 +3773,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3757 | goto failed_mount2; | 3773 | goto failed_mount2; |
3758 | } | 3774 | } |
3759 | } | 3775 | } |
3760 | if (!ext4_check_descriptors(sb, &first_not_zeroed)) { | 3776 | if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { |
3761 | ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); | 3777 | ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); |
3762 | ret = -EFSCORRUPTED; | 3778 | ret = -EFSCORRUPTED; |
3763 | goto failed_mount2; | 3779 | goto failed_mount2; |
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 39e9cfb1b371..2eb935ca5d9e 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
@@ -1353,15 +1353,19 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, | |||
1353 | size_t min_offs, free; | 1353 | size_t min_offs, free; |
1354 | int total_ino; | 1354 | int total_ino; |
1355 | void *base, *start, *end; | 1355 | void *base, *start, *end; |
1356 | int extra_isize = 0, error = 0, tried_min_extra_isize = 0; | 1356 | int error = 0, tried_min_extra_isize = 0; |
1357 | int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize); | 1357 | int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize); |
1358 | int isize_diff; /* How much do we need to grow i_extra_isize */ | ||
1358 | 1359 | ||
1359 | down_write(&EXT4_I(inode)->xattr_sem); | 1360 | down_write(&EXT4_I(inode)->xattr_sem); |
1361 | /* | ||
1362 | * Set EXT4_STATE_NO_EXPAND to avoid recursion when marking inode dirty | ||
1363 | */ | ||
1364 | ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND); | ||
1360 | retry: | 1365 | retry: |
1361 | if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) { | 1366 | isize_diff = new_extra_isize - EXT4_I(inode)->i_extra_isize; |
1362 | up_write(&EXT4_I(inode)->xattr_sem); | 1367 | if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) |
1363 | return 0; | 1368 | goto out; |
1364 | } | ||
1365 | 1369 | ||
1366 | header = IHDR(inode, raw_inode); | 1370 | header = IHDR(inode, raw_inode); |
1367 | entry = IFIRST(header); | 1371 | entry = IFIRST(header); |
@@ -1382,7 +1386,7 @@ retry: | |||
1382 | goto cleanup; | 1386 | goto cleanup; |
1383 | 1387 | ||
1384 | free = ext4_xattr_free_space(last, &min_offs, base, &total_ino); | 1388 | free = ext4_xattr_free_space(last, &min_offs, base, &total_ino); |
1385 | if (free >= new_extra_isize) { | 1389 | if (free >= isize_diff) { |
1386 | entry = IFIRST(header); | 1390 | entry = IFIRST(header); |
1387 | ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize | 1391 | ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize |
1388 | - new_extra_isize, (void *)raw_inode + | 1392 | - new_extra_isize, (void *)raw_inode + |
@@ -1390,8 +1394,7 @@ retry: | |||
1390 | (void *)header, total_ino, | 1394 | (void *)header, total_ino, |
1391 | inode->i_sb->s_blocksize); | 1395 | inode->i_sb->s_blocksize); |
1392 | EXT4_I(inode)->i_extra_isize = new_extra_isize; | 1396 | EXT4_I(inode)->i_extra_isize = new_extra_isize; |
1393 | error = 0; | 1397 | goto out; |
1394 | goto cleanup; | ||
1395 | } | 1398 | } |
1396 | 1399 | ||
1397 | /* | 1400 | /* |
@@ -1414,7 +1417,7 @@ retry: | |||
1414 | end = bh->b_data + bh->b_size; | 1417 | end = bh->b_data + bh->b_size; |
1415 | min_offs = end - base; | 1418 | min_offs = end - base; |
1416 | free = ext4_xattr_free_space(first, &min_offs, base, NULL); | 1419 | free = ext4_xattr_free_space(first, &min_offs, base, NULL); |
1417 | if (free < new_extra_isize) { | 1420 | if (free < isize_diff) { |
1418 | if (!tried_min_extra_isize && s_min_extra_isize) { | 1421 | if (!tried_min_extra_isize && s_min_extra_isize) { |
1419 | tried_min_extra_isize++; | 1422 | tried_min_extra_isize++; |
1420 | new_extra_isize = s_min_extra_isize; | 1423 | new_extra_isize = s_min_extra_isize; |
@@ -1428,7 +1431,7 @@ retry: | |||
1428 | free = inode->i_sb->s_blocksize; | 1431 | free = inode->i_sb->s_blocksize; |
1429 | } | 1432 | } |
1430 | 1433 | ||
1431 | while (new_extra_isize > 0) { | 1434 | while (isize_diff > 0) { |
1432 | size_t offs, size, entry_size; | 1435 | size_t offs, size, entry_size; |
1433 | struct ext4_xattr_entry *small_entry = NULL; | 1436 | struct ext4_xattr_entry *small_entry = NULL; |
1434 | struct ext4_xattr_info i = { | 1437 | struct ext4_xattr_info i = { |
@@ -1459,7 +1462,7 @@ retry: | |||
1459 | EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) + | 1462 | EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) + |
1460 | EXT4_XATTR_LEN(last->e_name_len); | 1463 | EXT4_XATTR_LEN(last->e_name_len); |
1461 | if (total_size <= free && total_size < min_total_size) { | 1464 | if (total_size <= free && total_size < min_total_size) { |
1462 | if (total_size < new_extra_isize) { | 1465 | if (total_size < isize_diff) { |
1463 | small_entry = last; | 1466 | small_entry = last; |
1464 | } else { | 1467 | } else { |
1465 | entry = last; | 1468 | entry = last; |
@@ -1514,22 +1517,22 @@ retry: | |||
1514 | error = ext4_xattr_ibody_set(handle, inode, &i, is); | 1517 | error = ext4_xattr_ibody_set(handle, inode, &i, is); |
1515 | if (error) | 1518 | if (error) |
1516 | goto cleanup; | 1519 | goto cleanup; |
1520 | total_ino -= entry_size; | ||
1517 | 1521 | ||
1518 | entry = IFIRST(header); | 1522 | entry = IFIRST(header); |
1519 | if (entry_size + EXT4_XATTR_SIZE(size) >= new_extra_isize) | 1523 | if (entry_size + EXT4_XATTR_SIZE(size) >= isize_diff) |
1520 | shift_bytes = new_extra_isize; | 1524 | shift_bytes = isize_diff; |
1521 | else | 1525 | else |
1522 | shift_bytes = entry_size + size; | 1526 | shift_bytes = entry_size + EXT4_XATTR_SIZE(size); |
1523 | /* Adjust the offsets and shift the remaining entries ahead */ | 1527 | /* Adjust the offsets and shift the remaining entries ahead */ |
1524 | ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize - | 1528 | ext4_xattr_shift_entries(entry, -shift_bytes, |
1525 | shift_bytes, (void *)raw_inode + | 1529 | (void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE + |
1526 | EXT4_GOOD_OLD_INODE_SIZE + extra_isize + shift_bytes, | 1530 | EXT4_I(inode)->i_extra_isize + shift_bytes, |
1527 | (void *)header, total_ino - entry_size, | 1531 | (void *)header, total_ino, inode->i_sb->s_blocksize); |
1528 | inode->i_sb->s_blocksize); | ||
1529 | 1532 | ||
1530 | extra_isize += shift_bytes; | 1533 | isize_diff -= shift_bytes; |
1531 | new_extra_isize -= shift_bytes; | 1534 | EXT4_I(inode)->i_extra_isize += shift_bytes; |
1532 | EXT4_I(inode)->i_extra_isize = extra_isize; | 1535 | header = IHDR(inode, raw_inode); |
1533 | 1536 | ||
1534 | i.name = b_entry_name; | 1537 | i.name = b_entry_name; |
1535 | i.value = buffer; | 1538 | i.value = buffer; |
@@ -1551,6 +1554,8 @@ retry: | |||
1551 | kfree(bs); | 1554 | kfree(bs); |
1552 | } | 1555 | } |
1553 | brelse(bh); | 1556 | brelse(bh); |
1557 | out: | ||
1558 | ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND); | ||
1554 | up_write(&EXT4_I(inode)->xattr_sem); | 1559 | up_write(&EXT4_I(inode)->xattr_sem); |
1555 | return 0; | 1560 | return 0; |
1556 | 1561 | ||
@@ -1562,6 +1567,10 @@ cleanup: | |||
1562 | kfree(is); | 1567 | kfree(is); |
1563 | kfree(bs); | 1568 | kfree(bs); |
1564 | brelse(bh); | 1569 | brelse(bh); |
1570 | /* | ||
1571 | * We deliberately leave EXT4_STATE_NO_EXPAND set here since inode | ||
1572 | * size expansion failed. | ||
1573 | */ | ||
1565 | up_write(&EXT4_I(inode)->xattr_sem); | 1574 | up_write(&EXT4_I(inode)->xattr_sem); |
1566 | return error; | 1575 | return error; |
1567 | } | 1576 | } |
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h index 69dd3e6566e0..a92e783fa057 100644 --- a/fs/ext4/xattr.h +++ b/fs/ext4/xattr.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define EXT4_XATTR_INDEX_SYSTEM 7 | 24 | #define EXT4_XATTR_INDEX_SYSTEM 7 |
25 | #define EXT4_XATTR_INDEX_RICHACL 8 | 25 | #define EXT4_XATTR_INDEX_RICHACL 8 |
26 | #define EXT4_XATTR_INDEX_ENCRYPTION 9 | 26 | #define EXT4_XATTR_INDEX_ENCRYPTION 9 |
27 | #define EXT4_XATTR_INDEX_HURD 10 /* Reserved for Hurd */ | ||
27 | 28 | ||
28 | struct ext4_xattr_header { | 29 | struct ext4_xattr_header { |
29 | __le32 h_magic; /* magic number for identification */ | 30 | __le32 h_magic; /* magic number for identification */ |
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index d64d2a515cb2..ccb401eebc11 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
@@ -1699,11 +1699,11 @@ static int f2fs_write_end(struct file *file, | |||
1699 | trace_f2fs_write_end(inode, pos, len, copied); | 1699 | trace_f2fs_write_end(inode, pos, len, copied); |
1700 | 1700 | ||
1701 | set_page_dirty(page); | 1701 | set_page_dirty(page); |
1702 | f2fs_put_page(page, 1); | ||
1703 | 1702 | ||
1704 | if (pos + copied > i_size_read(inode)) | 1703 | if (pos + copied > i_size_read(inode)) |
1705 | f2fs_i_size_write(inode, pos + copied); | 1704 | f2fs_i_size_write(inode, pos + copied); |
1706 | 1705 | ||
1706 | f2fs_put_page(page, 1); | ||
1707 | f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); | 1707 | f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); |
1708 | return copied; | 1708 | return copied; |
1709 | } | 1709 | } |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 675fa79d86f6..14f5fe2b841e 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -538,7 +538,7 @@ struct f2fs_nm_info { | |||
538 | /* NAT cache management */ | 538 | /* NAT cache management */ |
539 | struct radix_tree_root nat_root;/* root of the nat entry cache */ | 539 | struct radix_tree_root nat_root;/* root of the nat entry cache */ |
540 | struct radix_tree_root nat_set_root;/* root of the nat set cache */ | 540 | struct radix_tree_root nat_set_root;/* root of the nat set cache */ |
541 | struct percpu_rw_semaphore nat_tree_lock; /* protect nat_tree_lock */ | 541 | struct rw_semaphore nat_tree_lock; /* protect nat_tree_lock */ |
542 | struct list_head nat_entries; /* cached nat entry list (clean) */ | 542 | struct list_head nat_entries; /* cached nat entry list (clean) */ |
543 | unsigned int nat_cnt; /* the # of cached nat entries */ | 543 | unsigned int nat_cnt; /* the # of cached nat entries */ |
544 | unsigned int dirty_nat_cnt; /* total num of nat entries in set */ | 544 | unsigned int dirty_nat_cnt; /* total num of nat entries in set */ |
@@ -787,7 +787,7 @@ struct f2fs_sb_info { | |||
787 | struct f2fs_checkpoint *ckpt; /* raw checkpoint pointer */ | 787 | struct f2fs_checkpoint *ckpt; /* raw checkpoint pointer */ |
788 | struct inode *meta_inode; /* cache meta blocks */ | 788 | struct inode *meta_inode; /* cache meta blocks */ |
789 | struct mutex cp_mutex; /* checkpoint procedure lock */ | 789 | struct mutex cp_mutex; /* checkpoint procedure lock */ |
790 | struct percpu_rw_semaphore cp_rwsem; /* blocking FS operations */ | 790 | struct rw_semaphore cp_rwsem; /* blocking FS operations */ |
791 | struct rw_semaphore node_write; /* locking node writes */ | 791 | struct rw_semaphore node_write; /* locking node writes */ |
792 | wait_queue_head_t cp_wait; | 792 | wait_queue_head_t cp_wait; |
793 | unsigned long last_time[MAX_TIME]; /* to store time in jiffies */ | 793 | unsigned long last_time[MAX_TIME]; /* to store time in jiffies */ |
@@ -1074,22 +1074,22 @@ static inline void clear_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f) | |||
1074 | 1074 | ||
1075 | static inline void f2fs_lock_op(struct f2fs_sb_info *sbi) | 1075 | static inline void f2fs_lock_op(struct f2fs_sb_info *sbi) |
1076 | { | 1076 | { |
1077 | percpu_down_read(&sbi->cp_rwsem); | 1077 | down_read(&sbi->cp_rwsem); |
1078 | } | 1078 | } |
1079 | 1079 | ||
1080 | static inline void f2fs_unlock_op(struct f2fs_sb_info *sbi) | 1080 | static inline void f2fs_unlock_op(struct f2fs_sb_info *sbi) |
1081 | { | 1081 | { |
1082 | percpu_up_read(&sbi->cp_rwsem); | 1082 | up_read(&sbi->cp_rwsem); |
1083 | } | 1083 | } |
1084 | 1084 | ||
1085 | static inline void f2fs_lock_all(struct f2fs_sb_info *sbi) | 1085 | static inline void f2fs_lock_all(struct f2fs_sb_info *sbi) |
1086 | { | 1086 | { |
1087 | percpu_down_write(&sbi->cp_rwsem); | 1087 | down_write(&sbi->cp_rwsem); |
1088 | } | 1088 | } |
1089 | 1089 | ||
1090 | static inline void f2fs_unlock_all(struct f2fs_sb_info *sbi) | 1090 | static inline void f2fs_unlock_all(struct f2fs_sb_info *sbi) |
1091 | { | 1091 | { |
1092 | percpu_up_write(&sbi->cp_rwsem); | 1092 | up_write(&sbi->cp_rwsem); |
1093 | } | 1093 | } |
1094 | 1094 | ||
1095 | static inline int __get_cp_reason(struct f2fs_sb_info *sbi) | 1095 | static inline int __get_cp_reason(struct f2fs_sb_info *sbi) |
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 0e493f63ea41..28f4f4cbb8d8 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
@@ -1757,21 +1757,14 @@ static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg) | |||
1757 | { | 1757 | { |
1758 | struct fscrypt_policy policy; | 1758 | struct fscrypt_policy policy; |
1759 | struct inode *inode = file_inode(filp); | 1759 | struct inode *inode = file_inode(filp); |
1760 | int ret; | ||
1761 | 1760 | ||
1762 | if (copy_from_user(&policy, (struct fscrypt_policy __user *)arg, | 1761 | if (copy_from_user(&policy, (struct fscrypt_policy __user *)arg, |
1763 | sizeof(policy))) | 1762 | sizeof(policy))) |
1764 | return -EFAULT; | 1763 | return -EFAULT; |
1765 | 1764 | ||
1766 | ret = mnt_want_write_file(filp); | ||
1767 | if (ret) | ||
1768 | return ret; | ||
1769 | |||
1770 | f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); | 1765 | f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); |
1771 | ret = fscrypt_process_policy(inode, &policy); | ||
1772 | 1766 | ||
1773 | mnt_drop_write_file(filp); | 1767 | return fscrypt_process_policy(filp, &policy); |
1774 | return ret; | ||
1775 | } | 1768 | } |
1776 | 1769 | ||
1777 | static int f2fs_ioc_get_encryption_policy(struct file *filp, unsigned long arg) | 1770 | static int f2fs_ioc_get_encryption_policy(struct file *filp, unsigned long arg) |
@@ -2086,15 +2079,19 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in, | |||
2086 | if (unlikely(f2fs_readonly(src->i_sb))) | 2079 | if (unlikely(f2fs_readonly(src->i_sb))) |
2087 | return -EROFS; | 2080 | return -EROFS; |
2088 | 2081 | ||
2089 | if (S_ISDIR(src->i_mode) || S_ISDIR(dst->i_mode)) | 2082 | if (!S_ISREG(src->i_mode) || !S_ISREG(dst->i_mode)) |
2090 | return -EISDIR; | 2083 | return -EINVAL; |
2091 | 2084 | ||
2092 | if (f2fs_encrypted_inode(src) || f2fs_encrypted_inode(dst)) | 2085 | if (f2fs_encrypted_inode(src) || f2fs_encrypted_inode(dst)) |
2093 | return -EOPNOTSUPP; | 2086 | return -EOPNOTSUPP; |
2094 | 2087 | ||
2095 | inode_lock(src); | 2088 | inode_lock(src); |
2096 | if (src != dst) | 2089 | if (src != dst) { |
2097 | inode_lock(dst); | 2090 | if (!inode_trylock(dst)) { |
2091 | ret = -EBUSY; | ||
2092 | goto out; | ||
2093 | } | ||
2094 | } | ||
2098 | 2095 | ||
2099 | ret = -EINVAL; | 2096 | ret = -EINVAL; |
2100 | if (pos_in + len > src->i_size || pos_in + len < pos_in) | 2097 | if (pos_in + len > src->i_size || pos_in + len < pos_in) |
@@ -2152,6 +2149,7 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in, | |||
2152 | out_unlock: | 2149 | out_unlock: |
2153 | if (src != dst) | 2150 | if (src != dst) |
2154 | inode_unlock(dst); | 2151 | inode_unlock(dst); |
2152 | out: | ||
2155 | inode_unlock(src); | 2153 | inode_unlock(src); |
2156 | return ret; | 2154 | return ret; |
2157 | } | 2155 | } |
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index b2fa4b615925..f75d197d5beb 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c | |||
@@ -206,14 +206,14 @@ int need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid) | |||
206 | struct nat_entry *e; | 206 | struct nat_entry *e; |
207 | bool need = false; | 207 | bool need = false; |
208 | 208 | ||
209 | percpu_down_read(&nm_i->nat_tree_lock); | 209 | down_read(&nm_i->nat_tree_lock); |
210 | e = __lookup_nat_cache(nm_i, nid); | 210 | e = __lookup_nat_cache(nm_i, nid); |
211 | if (e) { | 211 | if (e) { |
212 | if (!get_nat_flag(e, IS_CHECKPOINTED) && | 212 | if (!get_nat_flag(e, IS_CHECKPOINTED) && |
213 | !get_nat_flag(e, HAS_FSYNCED_INODE)) | 213 | !get_nat_flag(e, HAS_FSYNCED_INODE)) |
214 | need = true; | 214 | need = true; |
215 | } | 215 | } |
216 | percpu_up_read(&nm_i->nat_tree_lock); | 216 | up_read(&nm_i->nat_tree_lock); |
217 | return need; | 217 | return need; |
218 | } | 218 | } |
219 | 219 | ||
@@ -223,11 +223,11 @@ bool is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid) | |||
223 | struct nat_entry *e; | 223 | struct nat_entry *e; |
224 | bool is_cp = true; | 224 | bool is_cp = true; |
225 | 225 | ||
226 | percpu_down_read(&nm_i->nat_tree_lock); | 226 | down_read(&nm_i->nat_tree_lock); |
227 | e = __lookup_nat_cache(nm_i, nid); | 227 | e = __lookup_nat_cache(nm_i, nid); |
228 | if (e && !get_nat_flag(e, IS_CHECKPOINTED)) | 228 | if (e && !get_nat_flag(e, IS_CHECKPOINTED)) |
229 | is_cp = false; | 229 | is_cp = false; |
230 | percpu_up_read(&nm_i->nat_tree_lock); | 230 | up_read(&nm_i->nat_tree_lock); |
231 | return is_cp; | 231 | return is_cp; |
232 | } | 232 | } |
233 | 233 | ||
@@ -237,13 +237,13 @@ bool need_inode_block_update(struct f2fs_sb_info *sbi, nid_t ino) | |||
237 | struct nat_entry *e; | 237 | struct nat_entry *e; |
238 | bool need_update = true; | 238 | bool need_update = true; |
239 | 239 | ||
240 | percpu_down_read(&nm_i->nat_tree_lock); | 240 | down_read(&nm_i->nat_tree_lock); |
241 | e = __lookup_nat_cache(nm_i, ino); | 241 | e = __lookup_nat_cache(nm_i, ino); |
242 | if (e && get_nat_flag(e, HAS_LAST_FSYNC) && | 242 | if (e && get_nat_flag(e, HAS_LAST_FSYNC) && |
243 | (get_nat_flag(e, IS_CHECKPOINTED) || | 243 | (get_nat_flag(e, IS_CHECKPOINTED) || |
244 | get_nat_flag(e, HAS_FSYNCED_INODE))) | 244 | get_nat_flag(e, HAS_FSYNCED_INODE))) |
245 | need_update = false; | 245 | need_update = false; |
246 | percpu_up_read(&nm_i->nat_tree_lock); | 246 | up_read(&nm_i->nat_tree_lock); |
247 | return need_update; | 247 | return need_update; |
248 | } | 248 | } |
249 | 249 | ||
@@ -284,7 +284,7 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, | |||
284 | struct f2fs_nm_info *nm_i = NM_I(sbi); | 284 | struct f2fs_nm_info *nm_i = NM_I(sbi); |
285 | struct nat_entry *e; | 285 | struct nat_entry *e; |
286 | 286 | ||
287 | percpu_down_write(&nm_i->nat_tree_lock); | 287 | down_write(&nm_i->nat_tree_lock); |
288 | e = __lookup_nat_cache(nm_i, ni->nid); | 288 | e = __lookup_nat_cache(nm_i, ni->nid); |
289 | if (!e) { | 289 | if (!e) { |
290 | e = grab_nat_entry(nm_i, ni->nid); | 290 | e = grab_nat_entry(nm_i, ni->nid); |
@@ -334,7 +334,7 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, | |||
334 | set_nat_flag(e, HAS_FSYNCED_INODE, true); | 334 | set_nat_flag(e, HAS_FSYNCED_INODE, true); |
335 | set_nat_flag(e, HAS_LAST_FSYNC, fsync_done); | 335 | set_nat_flag(e, HAS_LAST_FSYNC, fsync_done); |
336 | } | 336 | } |
337 | percpu_up_write(&nm_i->nat_tree_lock); | 337 | up_write(&nm_i->nat_tree_lock); |
338 | } | 338 | } |
339 | 339 | ||
340 | int try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink) | 340 | int try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink) |
@@ -342,7 +342,8 @@ int try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink) | |||
342 | struct f2fs_nm_info *nm_i = NM_I(sbi); | 342 | struct f2fs_nm_info *nm_i = NM_I(sbi); |
343 | int nr = nr_shrink; | 343 | int nr = nr_shrink; |
344 | 344 | ||
345 | percpu_down_write(&nm_i->nat_tree_lock); | 345 | if (!down_write_trylock(&nm_i->nat_tree_lock)) |
346 | return 0; | ||
346 | 347 | ||
347 | while (nr_shrink && !list_empty(&nm_i->nat_entries)) { | 348 | while (nr_shrink && !list_empty(&nm_i->nat_entries)) { |
348 | struct nat_entry *ne; | 349 | struct nat_entry *ne; |
@@ -351,7 +352,7 @@ int try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink) | |||
351 | __del_from_nat_cache(nm_i, ne); | 352 | __del_from_nat_cache(nm_i, ne); |
352 | nr_shrink--; | 353 | nr_shrink--; |
353 | } | 354 | } |
354 | percpu_up_write(&nm_i->nat_tree_lock); | 355 | up_write(&nm_i->nat_tree_lock); |
355 | return nr - nr_shrink; | 356 | return nr - nr_shrink; |
356 | } | 357 | } |
357 | 358 | ||
@@ -373,13 +374,13 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni) | |||
373 | ni->nid = nid; | 374 | ni->nid = nid; |
374 | 375 | ||
375 | /* Check nat cache */ | 376 | /* Check nat cache */ |
376 | percpu_down_read(&nm_i->nat_tree_lock); | 377 | down_read(&nm_i->nat_tree_lock); |
377 | e = __lookup_nat_cache(nm_i, nid); | 378 | e = __lookup_nat_cache(nm_i, nid); |
378 | if (e) { | 379 | if (e) { |
379 | ni->ino = nat_get_ino(e); | 380 | ni->ino = nat_get_ino(e); |
380 | ni->blk_addr = nat_get_blkaddr(e); | 381 | ni->blk_addr = nat_get_blkaddr(e); |
381 | ni->version = nat_get_version(e); | 382 | ni->version = nat_get_version(e); |
382 | percpu_up_read(&nm_i->nat_tree_lock); | 383 | up_read(&nm_i->nat_tree_lock); |
383 | return; | 384 | return; |
384 | } | 385 | } |
385 | 386 | ||
@@ -403,11 +404,11 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni) | |||
403 | node_info_from_raw_nat(ni, &ne); | 404 | node_info_from_raw_nat(ni, &ne); |
404 | f2fs_put_page(page, 1); | 405 | f2fs_put_page(page, 1); |
405 | cache: | 406 | cache: |
406 | percpu_up_read(&nm_i->nat_tree_lock); | 407 | up_read(&nm_i->nat_tree_lock); |
407 | /* cache nat entry */ | 408 | /* cache nat entry */ |
408 | percpu_down_write(&nm_i->nat_tree_lock); | 409 | down_write(&nm_i->nat_tree_lock); |
409 | cache_nat_entry(sbi, nid, &ne); | 410 | cache_nat_entry(sbi, nid, &ne); |
410 | percpu_up_write(&nm_i->nat_tree_lock); | 411 | up_write(&nm_i->nat_tree_lock); |
411 | } | 412 | } |
412 | 413 | ||
413 | /* | 414 | /* |
@@ -1788,7 +1789,7 @@ void build_free_nids(struct f2fs_sb_info *sbi) | |||
1788 | ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES, | 1789 | ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES, |
1789 | META_NAT, true); | 1790 | META_NAT, true); |
1790 | 1791 | ||
1791 | percpu_down_read(&nm_i->nat_tree_lock); | 1792 | down_read(&nm_i->nat_tree_lock); |
1792 | 1793 | ||
1793 | while (1) { | 1794 | while (1) { |
1794 | struct page *page = get_current_nat_page(sbi, nid); | 1795 | struct page *page = get_current_nat_page(sbi, nid); |
@@ -1820,7 +1821,7 @@ void build_free_nids(struct f2fs_sb_info *sbi) | |||
1820 | remove_free_nid(nm_i, nid); | 1821 | remove_free_nid(nm_i, nid); |
1821 | } | 1822 | } |
1822 | up_read(&curseg->journal_rwsem); | 1823 | up_read(&curseg->journal_rwsem); |
1823 | percpu_up_read(&nm_i->nat_tree_lock); | 1824 | up_read(&nm_i->nat_tree_lock); |
1824 | 1825 | ||
1825 | ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nm_i->next_scan_nid), | 1826 | ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nm_i->next_scan_nid), |
1826 | nm_i->ra_nid_pages, META_NAT, false); | 1827 | nm_i->ra_nid_pages, META_NAT, false); |
@@ -2209,7 +2210,7 @@ void flush_nat_entries(struct f2fs_sb_info *sbi) | |||
2209 | if (!nm_i->dirty_nat_cnt) | 2210 | if (!nm_i->dirty_nat_cnt) |
2210 | return; | 2211 | return; |
2211 | 2212 | ||
2212 | percpu_down_write(&nm_i->nat_tree_lock); | 2213 | down_write(&nm_i->nat_tree_lock); |
2213 | 2214 | ||
2214 | /* | 2215 | /* |
2215 | * if there are no enough space in journal to store dirty nat | 2216 | * if there are no enough space in journal to store dirty nat |
@@ -2232,7 +2233,7 @@ void flush_nat_entries(struct f2fs_sb_info *sbi) | |||
2232 | list_for_each_entry_safe(set, tmp, &sets, set_list) | 2233 | list_for_each_entry_safe(set, tmp, &sets, set_list) |
2233 | __flush_nat_entry_set(sbi, set); | 2234 | __flush_nat_entry_set(sbi, set); |
2234 | 2235 | ||
2235 | percpu_up_write(&nm_i->nat_tree_lock); | 2236 | up_write(&nm_i->nat_tree_lock); |
2236 | 2237 | ||
2237 | f2fs_bug_on(sbi, nm_i->dirty_nat_cnt); | 2238 | f2fs_bug_on(sbi, nm_i->dirty_nat_cnt); |
2238 | } | 2239 | } |
@@ -2268,8 +2269,7 @@ static int init_node_manager(struct f2fs_sb_info *sbi) | |||
2268 | 2269 | ||
2269 | mutex_init(&nm_i->build_lock); | 2270 | mutex_init(&nm_i->build_lock); |
2270 | spin_lock_init(&nm_i->free_nid_list_lock); | 2271 | spin_lock_init(&nm_i->free_nid_list_lock); |
2271 | if (percpu_init_rwsem(&nm_i->nat_tree_lock)) | 2272 | init_rwsem(&nm_i->nat_tree_lock); |
2272 | return -ENOMEM; | ||
2273 | 2273 | ||
2274 | nm_i->next_scan_nid = le32_to_cpu(sbi->ckpt->next_free_nid); | 2274 | nm_i->next_scan_nid = le32_to_cpu(sbi->ckpt->next_free_nid); |
2275 | nm_i->bitmap_size = __bitmap_size(sbi, NAT_BITMAP); | 2275 | nm_i->bitmap_size = __bitmap_size(sbi, NAT_BITMAP); |
@@ -2326,7 +2326,7 @@ void destroy_node_manager(struct f2fs_sb_info *sbi) | |||
2326 | spin_unlock(&nm_i->free_nid_list_lock); | 2326 | spin_unlock(&nm_i->free_nid_list_lock); |
2327 | 2327 | ||
2328 | /* destroy nat cache */ | 2328 | /* destroy nat cache */ |
2329 | percpu_down_write(&nm_i->nat_tree_lock); | 2329 | down_write(&nm_i->nat_tree_lock); |
2330 | while ((found = __gang_lookup_nat_cache(nm_i, | 2330 | while ((found = __gang_lookup_nat_cache(nm_i, |
2331 | nid, NATVEC_SIZE, natvec))) { | 2331 | nid, NATVEC_SIZE, natvec))) { |
2332 | unsigned idx; | 2332 | unsigned idx; |
@@ -2351,9 +2351,8 @@ void destroy_node_manager(struct f2fs_sb_info *sbi) | |||
2351 | kmem_cache_free(nat_entry_set_slab, setvec[idx]); | 2351 | kmem_cache_free(nat_entry_set_slab, setvec[idx]); |
2352 | } | 2352 | } |
2353 | } | 2353 | } |
2354 | percpu_up_write(&nm_i->nat_tree_lock); | 2354 | up_write(&nm_i->nat_tree_lock); |
2355 | 2355 | ||
2356 | percpu_free_rwsem(&nm_i->nat_tree_lock); | ||
2357 | kfree(nm_i->nat_bitmap); | 2356 | kfree(nm_i->nat_bitmap); |
2358 | sbi->nm_info = NULL; | 2357 | sbi->nm_info = NULL; |
2359 | kfree(nm_i); | 2358 | kfree(nm_i); |
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 1b86d3f638ef..7f863a645ab1 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
@@ -706,8 +706,6 @@ static void destroy_percpu_info(struct f2fs_sb_info *sbi) | |||
706 | percpu_counter_destroy(&sbi->nr_pages[i]); | 706 | percpu_counter_destroy(&sbi->nr_pages[i]); |
707 | percpu_counter_destroy(&sbi->alloc_valid_block_count); | 707 | percpu_counter_destroy(&sbi->alloc_valid_block_count); |
708 | percpu_counter_destroy(&sbi->total_valid_inode_count); | 708 | percpu_counter_destroy(&sbi->total_valid_inode_count); |
709 | |||
710 | percpu_free_rwsem(&sbi->cp_rwsem); | ||
711 | } | 709 | } |
712 | 710 | ||
713 | static void f2fs_put_super(struct super_block *sb) | 711 | static void f2fs_put_super(struct super_block *sb) |
@@ -1483,9 +1481,6 @@ static int init_percpu_info(struct f2fs_sb_info *sbi) | |||
1483 | { | 1481 | { |
1484 | int i, err; | 1482 | int i, err; |
1485 | 1483 | ||
1486 | if (percpu_init_rwsem(&sbi->cp_rwsem)) | ||
1487 | return -ENOMEM; | ||
1488 | |||
1489 | for (i = 0; i < NR_COUNT_TYPE; i++) { | 1484 | for (i = 0; i < NR_COUNT_TYPE; i++) { |
1490 | err = percpu_counter_init(&sbi->nr_pages[i], 0, GFP_KERNEL); | 1485 | err = percpu_counter_init(&sbi->nr_pages[i], 0, GFP_KERNEL); |
1491 | if (err) | 1486 | if (err) |
@@ -1686,6 +1681,7 @@ try_onemore: | |||
1686 | sbi->write_io[i].bio = NULL; | 1681 | sbi->write_io[i].bio = NULL; |
1687 | } | 1682 | } |
1688 | 1683 | ||
1684 | init_rwsem(&sbi->cp_rwsem); | ||
1689 | init_waitqueue_head(&sbi->cp_wait); | 1685 | init_waitqueue_head(&sbi->cp_wait); |
1690 | init_sb_info(sbi); | 1686 | init_sb_info(sbi); |
1691 | 1687 | ||
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index f394aff59c36..3988b43c2f5a 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -530,13 +530,13 @@ void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos, | |||
530 | req->out.args[0].size = count; | 530 | req->out.args[0].size = count; |
531 | } | 531 | } |
532 | 532 | ||
533 | static void fuse_release_user_pages(struct fuse_req *req, int write) | 533 | static void fuse_release_user_pages(struct fuse_req *req, bool should_dirty) |
534 | { | 534 | { |
535 | unsigned i; | 535 | unsigned i; |
536 | 536 | ||
537 | for (i = 0; i < req->num_pages; i++) { | 537 | for (i = 0; i < req->num_pages; i++) { |
538 | struct page *page = req->pages[i]; | 538 | struct page *page = req->pages[i]; |
539 | if (write) | 539 | if (should_dirty) |
540 | set_page_dirty_lock(page); | 540 | set_page_dirty_lock(page); |
541 | put_page(page); | 541 | put_page(page); |
542 | } | 542 | } |
@@ -1320,6 +1320,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, | |||
1320 | loff_t *ppos, int flags) | 1320 | loff_t *ppos, int flags) |
1321 | { | 1321 | { |
1322 | int write = flags & FUSE_DIO_WRITE; | 1322 | int write = flags & FUSE_DIO_WRITE; |
1323 | bool should_dirty = !write && iter_is_iovec(iter); | ||
1323 | int cuse = flags & FUSE_DIO_CUSE; | 1324 | int cuse = flags & FUSE_DIO_CUSE; |
1324 | struct file *file = io->file; | 1325 | struct file *file = io->file; |
1325 | struct inode *inode = file->f_mapping->host; | 1326 | struct inode *inode = file->f_mapping->host; |
@@ -1363,7 +1364,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, | |||
1363 | nres = fuse_send_read(req, io, pos, nbytes, owner); | 1364 | nres = fuse_send_read(req, io, pos, nbytes, owner); |
1364 | 1365 | ||
1365 | if (!io->async) | 1366 | if (!io->async) |
1366 | fuse_release_user_pages(req, !write); | 1367 | fuse_release_user_pages(req, should_dirty); |
1367 | if (req->out.h.error) { | 1368 | if (req->out.h.error) { |
1368 | err = req->out.h.error; | 1369 | err = req->out.h.error; |
1369 | break; | 1370 | break; |
diff --git a/fs/ioctl.c b/fs/ioctl.c index 0f56deb24ce6..c415668c86d4 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
@@ -568,7 +568,7 @@ static int ioctl_fsthaw(struct file *filp) | |||
568 | return thaw_super(sb); | 568 | return thaw_super(sb); |
569 | } | 569 | } |
570 | 570 | ||
571 | static long ioctl_file_dedupe_range(struct file *file, void __user *arg) | 571 | static int ioctl_file_dedupe_range(struct file *file, void __user *arg) |
572 | { | 572 | { |
573 | struct file_dedupe_range __user *argp = arg; | 573 | struct file_dedupe_range __user *argp = arg; |
574 | struct file_dedupe_range *same = NULL; | 574 | struct file_dedupe_range *same = NULL; |
@@ -582,6 +582,10 @@ static long ioctl_file_dedupe_range(struct file *file, void __user *arg) | |||
582 | } | 582 | } |
583 | 583 | ||
584 | size = offsetof(struct file_dedupe_range __user, info[count]); | 584 | size = offsetof(struct file_dedupe_range __user, info[count]); |
585 | if (size > PAGE_SIZE) { | ||
586 | ret = -ENOMEM; | ||
587 | goto out; | ||
588 | } | ||
585 | 589 | ||
586 | same = memdup_user(argp, size); | 590 | same = memdup_user(argp, size); |
587 | if (IS_ERR(same)) { | 591 | if (IS_ERR(same)) { |
diff --git a/fs/iomap.c b/fs/iomap.c index 0342254646e3..706270f21b35 100644 --- a/fs/iomap.c +++ b/fs/iomap.c | |||
@@ -428,9 +428,12 @@ static int iomap_to_fiemap(struct fiemap_extent_info *fi, | |||
428 | break; | 428 | break; |
429 | } | 429 | } |
430 | 430 | ||
431 | if (iomap->flags & IOMAP_F_MERGED) | ||
432 | flags |= FIEMAP_EXTENT_MERGED; | ||
433 | |||
431 | return fiemap_fill_next_extent(fi, iomap->offset, | 434 | return fiemap_fill_next_extent(fi, iomap->offset, |
432 | iomap->blkno != IOMAP_NULL_BLOCK ? iomap->blkno << 9: 0, | 435 | iomap->blkno != IOMAP_NULL_BLOCK ? iomap->blkno << 9: 0, |
433 | iomap->length, flags | FIEMAP_EXTENT_MERGED); | 436 | iomap->length, flags); |
434 | 437 | ||
435 | } | 438 | } |
436 | 439 | ||
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index e1574008adc9..2bcb86e6e6ca 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c | |||
@@ -840,21 +840,35 @@ repeat: | |||
840 | mutex_lock(&kernfs_mutex); | 840 | mutex_lock(&kernfs_mutex); |
841 | 841 | ||
842 | list_for_each_entry(info, &kernfs_root(kn)->supers, node) { | 842 | list_for_each_entry(info, &kernfs_root(kn)->supers, node) { |
843 | struct kernfs_node *parent; | ||
843 | struct inode *inode; | 844 | struct inode *inode; |
844 | struct dentry *dentry; | ||
845 | 845 | ||
846 | /* | ||
847 | * We want fsnotify_modify() on @kn but as the | ||
848 | * modifications aren't originating from userland don't | ||
849 | * have the matching @file available. Look up the inodes | ||
850 | * and generate the events manually. | ||
851 | */ | ||
846 | inode = ilookup(info->sb, kn->ino); | 852 | inode = ilookup(info->sb, kn->ino); |
847 | if (!inode) | 853 | if (!inode) |
848 | continue; | 854 | continue; |
849 | 855 | ||
850 | dentry = d_find_any_alias(inode); | 856 | parent = kernfs_get_parent(kn); |
851 | if (dentry) { | 857 | if (parent) { |
852 | fsnotify_parent(NULL, dentry, FS_MODIFY); | 858 | struct inode *p_inode; |
853 | fsnotify(inode, FS_MODIFY, inode, FSNOTIFY_EVENT_INODE, | 859 | |
854 | NULL, 0); | 860 | p_inode = ilookup(info->sb, parent->ino); |
855 | dput(dentry); | 861 | if (p_inode) { |
862 | fsnotify(p_inode, FS_MODIFY | FS_EVENT_ON_CHILD, | ||
863 | inode, FSNOTIFY_EVENT_INODE, kn->name, 0); | ||
864 | iput(p_inode); | ||
865 | } | ||
866 | |||
867 | kernfs_put(parent); | ||
856 | } | 868 | } |
857 | 869 | ||
870 | fsnotify(inode, FS_MODIFY, inode, FSNOTIFY_EVENT_INODE, | ||
871 | kn->name, 0); | ||
858 | iput(inode); | 872 | iput(inode); |
859 | } | 873 | } |
860 | 874 | ||
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c index f55a4e756047..217847679f0e 100644 --- a/fs/nfs/blocklayout/blocklayout.c +++ b/fs/nfs/blocklayout/blocklayout.c | |||
@@ -346,7 +346,7 @@ static void bl_write_cleanup(struct work_struct *work) | |||
346 | PAGE_SIZE - 1) & (loff_t)PAGE_MASK; | 346 | PAGE_SIZE - 1) & (loff_t)PAGE_MASK; |
347 | 347 | ||
348 | ext_tree_mark_written(bl, start >> SECTOR_SHIFT, | 348 | ext_tree_mark_written(bl, start >> SECTOR_SHIFT, |
349 | (end - start) >> SECTOR_SHIFT); | 349 | (end - start) >> SECTOR_SHIFT, end); |
350 | } | 350 | } |
351 | 351 | ||
352 | pnfs_ld_write_done(hdr); | 352 | pnfs_ld_write_done(hdr); |
diff --git a/fs/nfs/blocklayout/blocklayout.h b/fs/nfs/blocklayout/blocklayout.h index 18e6fd0b9506..efc007f00742 100644 --- a/fs/nfs/blocklayout/blocklayout.h +++ b/fs/nfs/blocklayout/blocklayout.h | |||
@@ -141,6 +141,7 @@ struct pnfs_block_layout { | |||
141 | struct rb_root bl_ext_ro; | 141 | struct rb_root bl_ext_ro; |
142 | spinlock_t bl_ext_lock; /* Protects list manipulation */ | 142 | spinlock_t bl_ext_lock; /* Protects list manipulation */ |
143 | bool bl_scsi_layout; | 143 | bool bl_scsi_layout; |
144 | u64 bl_lwb; | ||
144 | }; | 145 | }; |
145 | 146 | ||
146 | static inline struct pnfs_block_layout * | 147 | static inline struct pnfs_block_layout * |
@@ -182,7 +183,7 @@ int ext_tree_insert(struct pnfs_block_layout *bl, | |||
182 | int ext_tree_remove(struct pnfs_block_layout *bl, bool rw, sector_t start, | 183 | int ext_tree_remove(struct pnfs_block_layout *bl, bool rw, sector_t start, |
183 | sector_t end); | 184 | sector_t end); |
184 | int ext_tree_mark_written(struct pnfs_block_layout *bl, sector_t start, | 185 | int ext_tree_mark_written(struct pnfs_block_layout *bl, sector_t start, |
185 | sector_t len); | 186 | sector_t len, u64 lwb); |
186 | bool ext_tree_lookup(struct pnfs_block_layout *bl, sector_t isect, | 187 | bool ext_tree_lookup(struct pnfs_block_layout *bl, sector_t isect, |
187 | struct pnfs_block_extent *ret, bool rw); | 188 | struct pnfs_block_extent *ret, bool rw); |
188 | int ext_tree_prepare_commit(struct nfs4_layoutcommit_args *arg); | 189 | int ext_tree_prepare_commit(struct nfs4_layoutcommit_args *arg); |
diff --git a/fs/nfs/blocklayout/extent_tree.c b/fs/nfs/blocklayout/extent_tree.c index 992bcb19c11e..c85fbfd2d0d9 100644 --- a/fs/nfs/blocklayout/extent_tree.c +++ b/fs/nfs/blocklayout/extent_tree.c | |||
@@ -402,7 +402,7 @@ ext_tree_split(struct rb_root *root, struct pnfs_block_extent *be, | |||
402 | 402 | ||
403 | int | 403 | int |
404 | ext_tree_mark_written(struct pnfs_block_layout *bl, sector_t start, | 404 | ext_tree_mark_written(struct pnfs_block_layout *bl, sector_t start, |
405 | sector_t len) | 405 | sector_t len, u64 lwb) |
406 | { | 406 | { |
407 | struct rb_root *root = &bl->bl_ext_rw; | 407 | struct rb_root *root = &bl->bl_ext_rw; |
408 | sector_t end = start + len; | 408 | sector_t end = start + len; |
@@ -471,6 +471,8 @@ ext_tree_mark_written(struct pnfs_block_layout *bl, sector_t start, | |||
471 | } | 471 | } |
472 | } | 472 | } |
473 | out: | 473 | out: |
474 | if (bl->bl_lwb < lwb) | ||
475 | bl->bl_lwb = lwb; | ||
474 | spin_unlock(&bl->bl_ext_lock); | 476 | spin_unlock(&bl->bl_ext_lock); |
475 | 477 | ||
476 | __ext_put_deviceids(&tmp); | 478 | __ext_put_deviceids(&tmp); |
@@ -518,7 +520,7 @@ static __be32 *encode_scsi_range(struct pnfs_block_extent *be, __be32 *p) | |||
518 | } | 520 | } |
519 | 521 | ||
520 | static int ext_tree_encode_commit(struct pnfs_block_layout *bl, __be32 *p, | 522 | static int ext_tree_encode_commit(struct pnfs_block_layout *bl, __be32 *p, |
521 | size_t buffer_size, size_t *count) | 523 | size_t buffer_size, size_t *count, __u64 *lastbyte) |
522 | { | 524 | { |
523 | struct pnfs_block_extent *be; | 525 | struct pnfs_block_extent *be; |
524 | int ret = 0; | 526 | int ret = 0; |
@@ -542,6 +544,8 @@ static int ext_tree_encode_commit(struct pnfs_block_layout *bl, __be32 *p, | |||
542 | p = encode_block_extent(be, p); | 544 | p = encode_block_extent(be, p); |
543 | be->be_tag = EXTENT_COMMITTING; | 545 | be->be_tag = EXTENT_COMMITTING; |
544 | } | 546 | } |
547 | *lastbyte = bl->bl_lwb - 1; | ||
548 | bl->bl_lwb = 0; | ||
545 | spin_unlock(&bl->bl_ext_lock); | 549 | spin_unlock(&bl->bl_ext_lock); |
546 | 550 | ||
547 | return ret; | 551 | return ret; |
@@ -564,7 +568,7 @@ ext_tree_prepare_commit(struct nfs4_layoutcommit_args *arg) | |||
564 | arg->layoutupdate_pages = &arg->layoutupdate_page; | 568 | arg->layoutupdate_pages = &arg->layoutupdate_page; |
565 | 569 | ||
566 | retry: | 570 | retry: |
567 | ret = ext_tree_encode_commit(bl, start_p + 1, buffer_size, &count); | 571 | ret = ext_tree_encode_commit(bl, start_p + 1, buffer_size, &count, &arg->lastbytewritten); |
568 | if (unlikely(ret)) { | 572 | if (unlikely(ret)) { |
569 | ext_tree_free_commitdata(arg, buffer_size); | 573 | ext_tree_free_commitdata(arg, buffer_size); |
570 | 574 | ||
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index a7f2e6e33305..52a28311e2a4 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
@@ -275,6 +275,7 @@ static int nfs_callback_up_net(int minorversion, struct svc_serv *serv, | |||
275 | err_socks: | 275 | err_socks: |
276 | svc_rpcb_cleanup(serv, net); | 276 | svc_rpcb_cleanup(serv, net); |
277 | err_bind: | 277 | err_bind: |
278 | nn->cb_users[minorversion]--; | ||
278 | dprintk("NFS: Couldn't create callback socket: err = %d; " | 279 | dprintk("NFS: Couldn't create callback socket: err = %d; " |
279 | "net = %p\n", ret, net); | 280 | "net = %p\n", ret, net); |
280 | return ret; | 281 | return ret; |
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index c92a75e066a6..f953ef6b2f2e 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
@@ -454,11 +454,8 @@ static bool referring_call_exists(struct nfs_client *clp, | |||
454 | ((u32 *)&rclist->rcl_sessionid.data)[3], | 454 | ((u32 *)&rclist->rcl_sessionid.data)[3], |
455 | ref->rc_sequenceid, ref->rc_slotid); | 455 | ref->rc_sequenceid, ref->rc_slotid); |
456 | 456 | ||
457 | spin_lock(&tbl->slot_tbl_lock); | 457 | status = nfs4_slot_wait_on_seqid(tbl, ref->rc_slotid, |
458 | status = (test_bit(ref->rc_slotid, tbl->used_slots) && | 458 | ref->rc_sequenceid, HZ >> 1) < 0; |
459 | tbl->slots[ref->rc_slotid].seq_nr == | ||
460 | ref->rc_sequenceid); | ||
461 | spin_unlock(&tbl->slot_tbl_lock); | ||
462 | if (status) | 459 | if (status) |
463 | goto out; | 460 | goto out; |
464 | } | 461 | } |
@@ -487,7 +484,6 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, | |||
487 | goto out; | 484 | goto out; |
488 | 485 | ||
489 | tbl = &clp->cl_session->bc_slot_table; | 486 | tbl = &clp->cl_session->bc_slot_table; |
490 | slot = tbl->slots + args->csa_slotid; | ||
491 | 487 | ||
492 | /* Set up res before grabbing the spinlock */ | 488 | /* Set up res before grabbing the spinlock */ |
493 | memcpy(&res->csr_sessionid, &args->csa_sessionid, | 489 | memcpy(&res->csr_sessionid, &args->csa_sessionid, |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 003ebce4bbc4..1e106780a237 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -426,7 +426,7 @@ EXPORT_SYMBOL_GPL(nfs_mark_client_ready); | |||
426 | * Initialise the timeout values for a connection | 426 | * Initialise the timeout values for a connection |
427 | */ | 427 | */ |
428 | void nfs_init_timeout_values(struct rpc_timeout *to, int proto, | 428 | void nfs_init_timeout_values(struct rpc_timeout *to, int proto, |
429 | unsigned int timeo, unsigned int retrans) | 429 | int timeo, int retrans) |
430 | { | 430 | { |
431 | to->to_initval = timeo * HZ / 10; | 431 | to->to_initval = timeo * HZ / 10; |
432 | to->to_retries = retrans; | 432 | to->to_retries = retrans; |
@@ -434,9 +434,9 @@ void nfs_init_timeout_values(struct rpc_timeout *to, int proto, | |||
434 | switch (proto) { | 434 | switch (proto) { |
435 | case XPRT_TRANSPORT_TCP: | 435 | case XPRT_TRANSPORT_TCP: |
436 | case XPRT_TRANSPORT_RDMA: | 436 | case XPRT_TRANSPORT_RDMA: |
437 | if (to->to_retries == 0) | 437 | if (retrans == NFS_UNSPEC_RETRANS) |
438 | to->to_retries = NFS_DEF_TCP_RETRANS; | 438 | to->to_retries = NFS_DEF_TCP_RETRANS; |
439 | if (to->to_initval == 0) | 439 | if (timeo == NFS_UNSPEC_TIMEO || to->to_retries == 0) |
440 | to->to_initval = NFS_DEF_TCP_TIMEO * HZ / 10; | 440 | to->to_initval = NFS_DEF_TCP_TIMEO * HZ / 10; |
441 | if (to->to_initval > NFS_MAX_TCP_TIMEOUT) | 441 | if (to->to_initval > NFS_MAX_TCP_TIMEOUT) |
442 | to->to_initval = NFS_MAX_TCP_TIMEOUT; | 442 | to->to_initval = NFS_MAX_TCP_TIMEOUT; |
@@ -449,9 +449,9 @@ void nfs_init_timeout_values(struct rpc_timeout *to, int proto, | |||
449 | to->to_exponential = 0; | 449 | to->to_exponential = 0; |
450 | break; | 450 | break; |
451 | case XPRT_TRANSPORT_UDP: | 451 | case XPRT_TRANSPORT_UDP: |
452 | if (to->to_retries == 0) | 452 | if (retrans == NFS_UNSPEC_RETRANS) |
453 | to->to_retries = NFS_DEF_UDP_RETRANS; | 453 | to->to_retries = NFS_DEF_UDP_RETRANS; |
454 | if (!to->to_initval) | 454 | if (timeo == NFS_UNSPEC_TIMEO || to->to_initval == 0) |
455 | to->to_initval = NFS_DEF_UDP_TIMEO * HZ / 10; | 455 | to->to_initval = NFS_DEF_UDP_TIMEO * HZ / 10; |
456 | if (to->to_initval > NFS_MAX_UDP_TIMEOUT) | 456 | if (to->to_initval > NFS_MAX_UDP_TIMEOUT) |
457 | to->to_initval = NFS_MAX_UDP_TIMEOUT; | 457 | to->to_initval = NFS_MAX_UDP_TIMEOUT; |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 7d620970f2e1..ca699ddc11c1 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -657,7 +657,10 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from) | |||
657 | if (result <= 0) | 657 | if (result <= 0) |
658 | goto out; | 658 | goto out; |
659 | 659 | ||
660 | written = generic_write_sync(iocb, result); | 660 | result = generic_write_sync(iocb, result); |
661 | if (result < 0) | ||
662 | goto out; | ||
663 | written = result; | ||
661 | iocb->ki_pos += written; | 664 | iocb->ki_pos += written; |
662 | 665 | ||
663 | /* Return error values */ | 666 | /* Return error values */ |
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index e6206eaf2bdf..51b51369704c 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c | |||
@@ -37,6 +37,7 @@ ff_layout_alloc_layout_hdr(struct inode *inode, gfp_t gfp_flags) | |||
37 | if (ffl) { | 37 | if (ffl) { |
38 | INIT_LIST_HEAD(&ffl->error_list); | 38 | INIT_LIST_HEAD(&ffl->error_list); |
39 | INIT_LIST_HEAD(&ffl->mirrors); | 39 | INIT_LIST_HEAD(&ffl->mirrors); |
40 | ffl->last_report_time = ktime_get(); | ||
40 | return &ffl->generic_hdr; | 41 | return &ffl->generic_hdr; |
41 | } else | 42 | } else |
42 | return NULL; | 43 | return NULL; |
@@ -640,19 +641,18 @@ nfs4_ff_layoutstat_start_io(struct nfs4_ff_layout_mirror *mirror, | |||
640 | { | 641 | { |
641 | static const ktime_t notime = {0}; | 642 | static const ktime_t notime = {0}; |
642 | s64 report_interval = FF_LAYOUTSTATS_REPORT_INTERVAL; | 643 | s64 report_interval = FF_LAYOUTSTATS_REPORT_INTERVAL; |
644 | struct nfs4_flexfile_layout *ffl = FF_LAYOUT_FROM_HDR(mirror->layout); | ||
643 | 645 | ||
644 | nfs4_ff_start_busy_timer(&layoutstat->busy_timer, now); | 646 | nfs4_ff_start_busy_timer(&layoutstat->busy_timer, now); |
645 | if (ktime_equal(mirror->start_time, notime)) | 647 | if (ktime_equal(mirror->start_time, notime)) |
646 | mirror->start_time = now; | 648 | mirror->start_time = now; |
647 | if (ktime_equal(mirror->last_report_time, notime)) | ||
648 | mirror->last_report_time = now; | ||
649 | if (mirror->report_interval != 0) | 649 | if (mirror->report_interval != 0) |
650 | report_interval = (s64)mirror->report_interval * 1000LL; | 650 | report_interval = (s64)mirror->report_interval * 1000LL; |
651 | else if (layoutstats_timer != 0) | 651 | else if (layoutstats_timer != 0) |
652 | report_interval = (s64)layoutstats_timer * 1000LL; | 652 | report_interval = (s64)layoutstats_timer * 1000LL; |
653 | if (ktime_to_ms(ktime_sub(now, mirror->last_report_time)) >= | 653 | if (ktime_to_ms(ktime_sub(now, ffl->last_report_time)) >= |
654 | report_interval) { | 654 | report_interval) { |
655 | mirror->last_report_time = now; | 655 | ffl->last_report_time = now; |
656 | return true; | 656 | return true; |
657 | } | 657 | } |
658 | 658 | ||
@@ -806,11 +806,14 @@ ff_layout_choose_best_ds_for_read(struct pnfs_layout_segment *lseg, | |||
806 | { | 806 | { |
807 | struct nfs4_ff_layout_segment *fls = FF_LAYOUT_LSEG(lseg); | 807 | struct nfs4_ff_layout_segment *fls = FF_LAYOUT_LSEG(lseg); |
808 | struct nfs4_pnfs_ds *ds; | 808 | struct nfs4_pnfs_ds *ds; |
809 | bool fail_return = false; | ||
809 | int idx; | 810 | int idx; |
810 | 811 | ||
811 | /* mirrors are sorted by efficiency */ | 812 | /* mirrors are sorted by efficiency */ |
812 | for (idx = start_idx; idx < fls->mirror_array_cnt; idx++) { | 813 | for (idx = start_idx; idx < fls->mirror_array_cnt; idx++) { |
813 | ds = nfs4_ff_layout_prepare_ds(lseg, idx, false); | 814 | if (idx+1 == fls->mirror_array_cnt) |
815 | fail_return = true; | ||
816 | ds = nfs4_ff_layout_prepare_ds(lseg, idx, fail_return); | ||
814 | if (ds) { | 817 | if (ds) { |
815 | *best_idx = idx; | 818 | *best_idx = idx; |
816 | return ds; | 819 | return ds; |
@@ -859,6 +862,7 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio, | |||
859 | struct nfs4_pnfs_ds *ds; | 862 | struct nfs4_pnfs_ds *ds; |
860 | int ds_idx; | 863 | int ds_idx; |
861 | 864 | ||
865 | retry: | ||
862 | /* Use full layout for now */ | 866 | /* Use full layout for now */ |
863 | if (!pgio->pg_lseg) | 867 | if (!pgio->pg_lseg) |
864 | ff_layout_pg_get_read(pgio, req, false); | 868 | ff_layout_pg_get_read(pgio, req, false); |
@@ -871,10 +875,13 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio, | |||
871 | 875 | ||
872 | ds = ff_layout_choose_best_ds_for_read(pgio->pg_lseg, 0, &ds_idx); | 876 | ds = ff_layout_choose_best_ds_for_read(pgio->pg_lseg, 0, &ds_idx); |
873 | if (!ds) { | 877 | if (!ds) { |
874 | if (ff_layout_no_fallback_to_mds(pgio->pg_lseg)) | 878 | if (!ff_layout_no_fallback_to_mds(pgio->pg_lseg)) |
875 | goto out_pnfs; | ||
876 | else | ||
877 | goto out_mds; | 879 | goto out_mds; |
880 | pnfs_put_lseg(pgio->pg_lseg); | ||
881 | pgio->pg_lseg = NULL; | ||
882 | /* Sleep for 1 second before retrying */ | ||
883 | ssleep(1); | ||
884 | goto retry; | ||
878 | } | 885 | } |
879 | 886 | ||
880 | mirror = FF_LAYOUT_COMP(pgio->pg_lseg, ds_idx); | 887 | mirror = FF_LAYOUT_COMP(pgio->pg_lseg, ds_idx); |
@@ -890,12 +897,6 @@ out_mds: | |||
890 | pnfs_put_lseg(pgio->pg_lseg); | 897 | pnfs_put_lseg(pgio->pg_lseg); |
891 | pgio->pg_lseg = NULL; | 898 | pgio->pg_lseg = NULL; |
892 | nfs_pageio_reset_read_mds(pgio); | 899 | nfs_pageio_reset_read_mds(pgio); |
893 | return; | ||
894 | |||
895 | out_pnfs: | ||
896 | pnfs_set_lo_fail(pgio->pg_lseg); | ||
897 | pnfs_put_lseg(pgio->pg_lseg); | ||
898 | pgio->pg_lseg = NULL; | ||
899 | } | 900 | } |
900 | 901 | ||
901 | static void | 902 | static void |
@@ -909,6 +910,7 @@ ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio, | |||
909 | int i; | 910 | int i; |
910 | int status; | 911 | int status; |
911 | 912 | ||
913 | retry: | ||
912 | if (!pgio->pg_lseg) { | 914 | if (!pgio->pg_lseg) { |
913 | pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, | 915 | pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, |
914 | req->wb_context, | 916 | req->wb_context, |
@@ -940,10 +942,13 @@ ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio, | |||
940 | for (i = 0; i < pgio->pg_mirror_count; i++) { | 942 | for (i = 0; i < pgio->pg_mirror_count; i++) { |
941 | ds = nfs4_ff_layout_prepare_ds(pgio->pg_lseg, i, true); | 943 | ds = nfs4_ff_layout_prepare_ds(pgio->pg_lseg, i, true); |
942 | if (!ds) { | 944 | if (!ds) { |
943 | if (ff_layout_no_fallback_to_mds(pgio->pg_lseg)) | 945 | if (!ff_layout_no_fallback_to_mds(pgio->pg_lseg)) |
944 | goto out_pnfs; | ||
945 | else | ||
946 | goto out_mds; | 946 | goto out_mds; |
947 | pnfs_put_lseg(pgio->pg_lseg); | ||
948 | pgio->pg_lseg = NULL; | ||
949 | /* Sleep for 1 second before retrying */ | ||
950 | ssleep(1); | ||
951 | goto retry; | ||
947 | } | 952 | } |
948 | pgm = &pgio->pg_mirrors[i]; | 953 | pgm = &pgio->pg_mirrors[i]; |
949 | mirror = FF_LAYOUT_COMP(pgio->pg_lseg, i); | 954 | mirror = FF_LAYOUT_COMP(pgio->pg_lseg, i); |
@@ -956,12 +961,6 @@ out_mds: | |||
956 | pnfs_put_lseg(pgio->pg_lseg); | 961 | pnfs_put_lseg(pgio->pg_lseg); |
957 | pgio->pg_lseg = NULL; | 962 | pgio->pg_lseg = NULL; |
958 | nfs_pageio_reset_write_mds(pgio); | 963 | nfs_pageio_reset_write_mds(pgio); |
959 | return; | ||
960 | |||
961 | out_pnfs: | ||
962 | pnfs_set_lo_fail(pgio->pg_lseg); | ||
963 | pnfs_put_lseg(pgio->pg_lseg); | ||
964 | pgio->pg_lseg = NULL; | ||
965 | } | 964 | } |
966 | 965 | ||
967 | static unsigned int | 966 | static unsigned int |
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.h b/fs/nfs/flexfilelayout/flexfilelayout.h index 1bcdb15d0c41..3ee0c9fcea76 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.h +++ b/fs/nfs/flexfilelayout/flexfilelayout.h | |||
@@ -84,7 +84,6 @@ struct nfs4_ff_layout_mirror { | |||
84 | struct nfs4_ff_layoutstat read_stat; | 84 | struct nfs4_ff_layoutstat read_stat; |
85 | struct nfs4_ff_layoutstat write_stat; | 85 | struct nfs4_ff_layoutstat write_stat; |
86 | ktime_t start_time; | 86 | ktime_t start_time; |
87 | ktime_t last_report_time; | ||
88 | u32 report_interval; | 87 | u32 report_interval; |
89 | }; | 88 | }; |
90 | 89 | ||
@@ -101,6 +100,7 @@ struct nfs4_flexfile_layout { | |||
101 | struct pnfs_ds_commit_info commit_info; | 100 | struct pnfs_ds_commit_info commit_info; |
102 | struct list_head mirrors; | 101 | struct list_head mirrors; |
103 | struct list_head error_list; /* nfs4_ff_layout_ds_err */ | 102 | struct list_head error_list; /* nfs4_ff_layout_ds_err */ |
103 | ktime_t last_report_time; /* Layoutstat report times */ | ||
104 | }; | 104 | }; |
105 | 105 | ||
106 | static inline struct nfs4_flexfile_layout * | 106 | static inline struct nfs4_flexfile_layout * |
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c index 0aa36be71fce..f7a3f6b05369 100644 --- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c +++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c | |||
@@ -17,8 +17,8 @@ | |||
17 | 17 | ||
18 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD | 18 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD |
19 | 19 | ||
20 | static unsigned int dataserver_timeo = NFS4_DEF_DS_TIMEO; | 20 | static unsigned int dataserver_timeo = NFS_DEF_TCP_RETRANS; |
21 | static unsigned int dataserver_retrans = NFS4_DEF_DS_RETRANS; | 21 | static unsigned int dataserver_retrans; |
22 | 22 | ||
23 | void nfs4_ff_layout_put_deviceid(struct nfs4_ff_layout_ds *mirror_ds) | 23 | void nfs4_ff_layout_put_deviceid(struct nfs4_ff_layout_ds *mirror_ds) |
24 | { | 24 | { |
@@ -379,7 +379,7 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx, | |||
379 | 379 | ||
380 | devid = &mirror->mirror_ds->id_node; | 380 | devid = &mirror->mirror_ds->id_node; |
381 | if (ff_layout_test_devid_unavailable(devid)) | 381 | if (ff_layout_test_devid_unavailable(devid)) |
382 | goto out; | 382 | goto out_fail; |
383 | 383 | ||
384 | ds = mirror->mirror_ds->ds; | 384 | ds = mirror->mirror_ds->ds; |
385 | /* matching smp_wmb() in _nfs4_pnfs_v3/4_ds_connect */ | 385 | /* matching smp_wmb() in _nfs4_pnfs_v3/4_ds_connect */ |
@@ -405,15 +405,16 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx, | |||
405 | mirror->mirror_ds->ds_versions[0].rsize = max_payload; | 405 | mirror->mirror_ds->ds_versions[0].rsize = max_payload; |
406 | if (mirror->mirror_ds->ds_versions[0].wsize > max_payload) | 406 | if (mirror->mirror_ds->ds_versions[0].wsize > max_payload) |
407 | mirror->mirror_ds->ds_versions[0].wsize = max_payload; | 407 | mirror->mirror_ds->ds_versions[0].wsize = max_payload; |
408 | } else { | 408 | goto out; |
409 | ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout), | ||
410 | mirror, lseg->pls_range.offset, | ||
411 | lseg->pls_range.length, NFS4ERR_NXIO, | ||
412 | OP_ILLEGAL, GFP_NOIO); | ||
413 | if (fail_return || !ff_layout_has_available_ds(lseg)) | ||
414 | pnfs_error_mark_layout_for_return(ino, lseg); | ||
415 | ds = NULL; | ||
416 | } | 409 | } |
410 | ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout), | ||
411 | mirror, lseg->pls_range.offset, | ||
412 | lseg->pls_range.length, NFS4ERR_NXIO, | ||
413 | OP_ILLEGAL, GFP_NOIO); | ||
414 | out_fail: | ||
415 | if (fail_return || !ff_layout_has_available_ds(lseg)) | ||
416 | pnfs_error_mark_layout_for_return(ino, lseg); | ||
417 | ds = NULL; | ||
417 | out: | 418 | out: |
418 | return ds; | 419 | return ds; |
419 | } | 420 | } |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 7ce5e023c3c3..74935a19e4bf 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -58,6 +58,9 @@ struct nfs_clone_mount { | |||
58 | */ | 58 | */ |
59 | #define NFS_UNSPEC_PORT (-1) | 59 | #define NFS_UNSPEC_PORT (-1) |
60 | 60 | ||
61 | #define NFS_UNSPEC_RETRANS (UINT_MAX) | ||
62 | #define NFS_UNSPEC_TIMEO (UINT_MAX) | ||
63 | |||
61 | /* | 64 | /* |
62 | * Maximum number of pages that readdir can use for creating | 65 | * Maximum number of pages that readdir can use for creating |
63 | * a vmapped array of pages. | 66 | * a vmapped array of pages. |
@@ -156,7 +159,7 @@ struct nfs_client *nfs_get_client(const struct nfs_client_initdata *, | |||
156 | int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *, struct nfs_fattr *); | 159 | int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *, struct nfs_fattr *); |
157 | void nfs_server_insert_lists(struct nfs_server *); | 160 | void nfs_server_insert_lists(struct nfs_server *); |
158 | void nfs_server_remove_lists(struct nfs_server *); | 161 | void nfs_server_remove_lists(struct nfs_server *); |
159 | void nfs_init_timeout_values(struct rpc_timeout *, int, unsigned int, unsigned int); | 162 | void nfs_init_timeout_values(struct rpc_timeout *to, int proto, int timeo, int retrans); |
160 | int nfs_init_server_rpcclient(struct nfs_server *, const struct rpc_timeout *t, | 163 | int nfs_init_server_rpcclient(struct nfs_server *, const struct rpc_timeout *t, |
161 | rpc_authflavor_t); | 164 | rpc_authflavor_t); |
162 | struct nfs_server *nfs_alloc_server(void); | 165 | struct nfs_server *nfs_alloc_server(void); |
diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 6f4752734804..64b43b4ad9dd 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c | |||
@@ -318,10 +318,22 @@ static void | |||
318 | nfs42_layoutstat_prepare(struct rpc_task *task, void *calldata) | 318 | nfs42_layoutstat_prepare(struct rpc_task *task, void *calldata) |
319 | { | 319 | { |
320 | struct nfs42_layoutstat_data *data = calldata; | 320 | struct nfs42_layoutstat_data *data = calldata; |
321 | struct nfs_server *server = NFS_SERVER(data->args.inode); | 321 | struct inode *inode = data->inode; |
322 | struct nfs_server *server = NFS_SERVER(inode); | ||
323 | struct pnfs_layout_hdr *lo; | ||
322 | 324 | ||
325 | spin_lock(&inode->i_lock); | ||
326 | lo = NFS_I(inode)->layout; | ||
327 | if (!pnfs_layout_is_valid(lo)) { | ||
328 | spin_unlock(&inode->i_lock); | ||
329 | rpc_exit(task, 0); | ||
330 | return; | ||
331 | } | ||
332 | nfs4_stateid_copy(&data->args.stateid, &lo->plh_stateid); | ||
333 | spin_unlock(&inode->i_lock); | ||
323 | nfs41_setup_sequence(nfs4_get_session(server), &data->args.seq_args, | 334 | nfs41_setup_sequence(nfs4_get_session(server), &data->args.seq_args, |
324 | &data->res.seq_res, task); | 335 | &data->res.seq_res, task); |
336 | |||
325 | } | 337 | } |
326 | 338 | ||
327 | static void | 339 | static void |
@@ -341,11 +353,11 @@ nfs42_layoutstat_done(struct rpc_task *task, void *calldata) | |||
341 | case -NFS4ERR_ADMIN_REVOKED: | 353 | case -NFS4ERR_ADMIN_REVOKED: |
342 | case -NFS4ERR_DELEG_REVOKED: | 354 | case -NFS4ERR_DELEG_REVOKED: |
343 | case -NFS4ERR_STALE_STATEID: | 355 | case -NFS4ERR_STALE_STATEID: |
344 | case -NFS4ERR_OLD_STATEID: | ||
345 | case -NFS4ERR_BAD_STATEID: | 356 | case -NFS4ERR_BAD_STATEID: |
346 | spin_lock(&inode->i_lock); | 357 | spin_lock(&inode->i_lock); |
347 | lo = NFS_I(inode)->layout; | 358 | lo = NFS_I(inode)->layout; |
348 | if (lo && nfs4_stateid_match(&data->args.stateid, | 359 | if (pnfs_layout_is_valid(lo) && |
360 | nfs4_stateid_match(&data->args.stateid, | ||
349 | &lo->plh_stateid)) { | 361 | &lo->plh_stateid)) { |
350 | LIST_HEAD(head); | 362 | LIST_HEAD(head); |
351 | 363 | ||
@@ -359,11 +371,23 @@ nfs42_layoutstat_done(struct rpc_task *task, void *calldata) | |||
359 | } else | 371 | } else |
360 | spin_unlock(&inode->i_lock); | 372 | spin_unlock(&inode->i_lock); |
361 | break; | 373 | break; |
374 | case -NFS4ERR_OLD_STATEID: | ||
375 | spin_lock(&inode->i_lock); | ||
376 | lo = NFS_I(inode)->layout; | ||
377 | if (pnfs_layout_is_valid(lo) && | ||
378 | nfs4_stateid_match_other(&data->args.stateid, | ||
379 | &lo->plh_stateid)) { | ||
380 | /* Do we need to delay before resending? */ | ||
381 | if (!nfs4_stateid_is_newer(&lo->plh_stateid, | ||
382 | &data->args.stateid)) | ||
383 | rpc_delay(task, HZ); | ||
384 | rpc_restart_call_prepare(task); | ||
385 | } | ||
386 | spin_unlock(&inode->i_lock); | ||
387 | break; | ||
362 | case -ENOTSUPP: | 388 | case -ENOTSUPP: |
363 | case -EOPNOTSUPP: | 389 | case -EOPNOTSUPP: |
364 | NFS_SERVER(inode)->caps &= ~NFS_CAP_LAYOUTSTATS; | 390 | NFS_SERVER(inode)->caps &= ~NFS_CAP_LAYOUTSTATS; |
365 | default: | ||
366 | break; | ||
367 | } | 391 | } |
368 | 392 | ||
369 | dprintk("%s server returns %d\n", __func__, task->tk_status); | 393 | dprintk("%s server returns %d\n", __func__, task->tk_status); |
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 8d7d08d4f95f..cd3b7cfdde16 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c | |||
@@ -817,6 +817,11 @@ static int nfs4_set_client(struct nfs_server *server, | |||
817 | goto error; | 817 | goto error; |
818 | } | 818 | } |
819 | 819 | ||
820 | if (server->nfs_client == clp) { | ||
821 | error = -ELOOP; | ||
822 | goto error; | ||
823 | } | ||
824 | |||
820 | /* | 825 | /* |
821 | * Query for the lease time on clientid setup or renewal | 826 | * Query for the lease time on clientid setup or renewal |
822 | * | 827 | * |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 1949bbd806eb..a9dec32ba9ba 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -634,15 +634,11 @@ out_sleep: | |||
634 | } | 634 | } |
635 | EXPORT_SYMBOL_GPL(nfs40_setup_sequence); | 635 | EXPORT_SYMBOL_GPL(nfs40_setup_sequence); |
636 | 636 | ||
637 | static int nfs40_sequence_done(struct rpc_task *task, | 637 | static void nfs40_sequence_free_slot(struct nfs4_sequence_res *res) |
638 | struct nfs4_sequence_res *res) | ||
639 | { | 638 | { |
640 | struct nfs4_slot *slot = res->sr_slot; | 639 | struct nfs4_slot *slot = res->sr_slot; |
641 | struct nfs4_slot_table *tbl; | 640 | struct nfs4_slot_table *tbl; |
642 | 641 | ||
643 | if (slot == NULL) | ||
644 | goto out; | ||
645 | |||
646 | tbl = slot->table; | 642 | tbl = slot->table; |
647 | spin_lock(&tbl->slot_tbl_lock); | 643 | spin_lock(&tbl->slot_tbl_lock); |
648 | if (!nfs41_wake_and_assign_slot(tbl, slot)) | 644 | if (!nfs41_wake_and_assign_slot(tbl, slot)) |
@@ -650,7 +646,13 @@ static int nfs40_sequence_done(struct rpc_task *task, | |||
650 | spin_unlock(&tbl->slot_tbl_lock); | 646 | spin_unlock(&tbl->slot_tbl_lock); |
651 | 647 | ||
652 | res->sr_slot = NULL; | 648 | res->sr_slot = NULL; |
653 | out: | 649 | } |
650 | |||
651 | static int nfs40_sequence_done(struct rpc_task *task, | ||
652 | struct nfs4_sequence_res *res) | ||
653 | { | ||
654 | if (res->sr_slot != NULL) | ||
655 | nfs40_sequence_free_slot(res); | ||
654 | return 1; | 656 | return 1; |
655 | } | 657 | } |
656 | 658 | ||
@@ -666,6 +668,11 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res) | |||
666 | tbl = slot->table; | 668 | tbl = slot->table; |
667 | session = tbl->session; | 669 | session = tbl->session; |
668 | 670 | ||
671 | /* Bump the slot sequence number */ | ||
672 | if (slot->seq_done) | ||
673 | slot->seq_nr++; | ||
674 | slot->seq_done = 0; | ||
675 | |||
669 | spin_lock(&tbl->slot_tbl_lock); | 676 | spin_lock(&tbl->slot_tbl_lock); |
670 | /* Be nice to the server: try to ensure that the last transmitted | 677 | /* Be nice to the server: try to ensure that the last transmitted |
671 | * value for highest_user_slotid <= target_highest_slotid | 678 | * value for highest_user_slotid <= target_highest_slotid |
@@ -686,9 +693,12 @@ out_unlock: | |||
686 | res->sr_slot = NULL; | 693 | res->sr_slot = NULL; |
687 | if (send_new_highest_used_slotid) | 694 | if (send_new_highest_used_slotid) |
688 | nfs41_notify_server(session->clp); | 695 | nfs41_notify_server(session->clp); |
696 | if (waitqueue_active(&tbl->slot_waitq)) | ||
697 | wake_up_all(&tbl->slot_waitq); | ||
689 | } | 698 | } |
690 | 699 | ||
691 | int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) | 700 | static int nfs41_sequence_process(struct rpc_task *task, |
701 | struct nfs4_sequence_res *res) | ||
692 | { | 702 | { |
693 | struct nfs4_session *session; | 703 | struct nfs4_session *session; |
694 | struct nfs4_slot *slot = res->sr_slot; | 704 | struct nfs4_slot *slot = res->sr_slot; |
@@ -714,7 +724,7 @@ int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) | |||
714 | switch (res->sr_status) { | 724 | switch (res->sr_status) { |
715 | case 0: | 725 | case 0: |
716 | /* Update the slot's sequence and clientid lease timer */ | 726 | /* Update the slot's sequence and clientid lease timer */ |
717 | ++slot->seq_nr; | 727 | slot->seq_done = 1; |
718 | clp = session->clp; | 728 | clp = session->clp; |
719 | do_renew_lease(clp, res->sr_timestamp); | 729 | do_renew_lease(clp, res->sr_timestamp); |
720 | /* Check sequence flags */ | 730 | /* Check sequence flags */ |
@@ -769,16 +779,16 @@ int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) | |||
769 | goto retry_nowait; | 779 | goto retry_nowait; |
770 | default: | 780 | default: |
771 | /* Just update the slot sequence no. */ | 781 | /* Just update the slot sequence no. */ |
772 | ++slot->seq_nr; | 782 | slot->seq_done = 1; |
773 | } | 783 | } |
774 | out: | 784 | out: |
775 | /* The session may be reset by one of the error handlers. */ | 785 | /* The session may be reset by one of the error handlers. */ |
776 | dprintk("%s: Error %d free the slot \n", __func__, res->sr_status); | 786 | dprintk("%s: Error %d free the slot \n", __func__, res->sr_status); |
777 | nfs41_sequence_free_slot(res); | ||
778 | out_noaction: | 787 | out_noaction: |
779 | return ret; | 788 | return ret; |
780 | retry_nowait: | 789 | retry_nowait: |
781 | if (rpc_restart_call_prepare(task)) { | 790 | if (rpc_restart_call_prepare(task)) { |
791 | nfs41_sequence_free_slot(res); | ||
782 | task->tk_status = 0; | 792 | task->tk_status = 0; |
783 | ret = 0; | 793 | ret = 0; |
784 | } | 794 | } |
@@ -789,8 +799,37 @@ out_retry: | |||
789 | rpc_delay(task, NFS4_POLL_RETRY_MAX); | 799 | rpc_delay(task, NFS4_POLL_RETRY_MAX); |
790 | return 0; | 800 | return 0; |
791 | } | 801 | } |
802 | |||
803 | int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) | ||
804 | { | ||
805 | if (!nfs41_sequence_process(task, res)) | ||
806 | return 0; | ||
807 | if (res->sr_slot != NULL) | ||
808 | nfs41_sequence_free_slot(res); | ||
809 | return 1; | ||
810 | |||
811 | } | ||
792 | EXPORT_SYMBOL_GPL(nfs41_sequence_done); | 812 | EXPORT_SYMBOL_GPL(nfs41_sequence_done); |
793 | 813 | ||
814 | static int nfs4_sequence_process(struct rpc_task *task, struct nfs4_sequence_res *res) | ||
815 | { | ||
816 | if (res->sr_slot == NULL) | ||
817 | return 1; | ||
818 | if (res->sr_slot->table->session != NULL) | ||
819 | return nfs41_sequence_process(task, res); | ||
820 | return nfs40_sequence_done(task, res); | ||
821 | } | ||
822 | |||
823 | static void nfs4_sequence_free_slot(struct nfs4_sequence_res *res) | ||
824 | { | ||
825 | if (res->sr_slot != NULL) { | ||
826 | if (res->sr_slot->table->session != NULL) | ||
827 | nfs41_sequence_free_slot(res); | ||
828 | else | ||
829 | nfs40_sequence_free_slot(res); | ||
830 | } | ||
831 | } | ||
832 | |||
794 | int nfs4_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) | 833 | int nfs4_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) |
795 | { | 834 | { |
796 | if (res->sr_slot == NULL) | 835 | if (res->sr_slot == NULL) |
@@ -920,6 +959,17 @@ static int nfs4_setup_sequence(const struct nfs_server *server, | |||
920 | args, res, task); | 959 | args, res, task); |
921 | } | 960 | } |
922 | 961 | ||
962 | static int nfs4_sequence_process(struct rpc_task *task, struct nfs4_sequence_res *res) | ||
963 | { | ||
964 | return nfs40_sequence_done(task, res); | ||
965 | } | ||
966 | |||
967 | static void nfs4_sequence_free_slot(struct nfs4_sequence_res *res) | ||
968 | { | ||
969 | if (res->sr_slot != NULL) | ||
970 | nfs40_sequence_free_slot(res); | ||
971 | } | ||
972 | |||
923 | int nfs4_sequence_done(struct rpc_task *task, | 973 | int nfs4_sequence_done(struct rpc_task *task, |
924 | struct nfs4_sequence_res *res) | 974 | struct nfs4_sequence_res *res) |
925 | { | 975 | { |
@@ -1197,6 +1247,7 @@ static void nfs4_opendata_free(struct kref *kref) | |||
1197 | struct super_block *sb = p->dentry->d_sb; | 1247 | struct super_block *sb = p->dentry->d_sb; |
1198 | 1248 | ||
1199 | nfs_free_seqid(p->o_arg.seqid); | 1249 | nfs_free_seqid(p->o_arg.seqid); |
1250 | nfs4_sequence_free_slot(&p->o_res.seq_res); | ||
1200 | if (p->state != NULL) | 1251 | if (p->state != NULL) |
1201 | nfs4_put_open_state(p->state); | 1252 | nfs4_put_open_state(p->state); |
1202 | nfs4_put_state_owner(p->owner); | 1253 | nfs4_put_state_owner(p->owner); |
@@ -1656,9 +1707,14 @@ err: | |||
1656 | static struct nfs4_state * | 1707 | static struct nfs4_state * |
1657 | nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data) | 1708 | nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data) |
1658 | { | 1709 | { |
1710 | struct nfs4_state *ret; | ||
1711 | |||
1659 | if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) | 1712 | if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) |
1660 | return _nfs4_opendata_reclaim_to_nfs4_state(data); | 1713 | ret =_nfs4_opendata_reclaim_to_nfs4_state(data); |
1661 | return _nfs4_opendata_to_nfs4_state(data); | 1714 | else |
1715 | ret = _nfs4_opendata_to_nfs4_state(data); | ||
1716 | nfs4_sequence_free_slot(&data->o_res.seq_res); | ||
1717 | return ret; | ||
1662 | } | 1718 | } |
1663 | 1719 | ||
1664 | static struct nfs_open_context *nfs4_state_find_open_context(struct nfs4_state *state) | 1720 | static struct nfs_open_context *nfs4_state_find_open_context(struct nfs4_state *state) |
@@ -2056,7 +2112,7 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata) | |||
2056 | 2112 | ||
2057 | data->rpc_status = task->tk_status; | 2113 | data->rpc_status = task->tk_status; |
2058 | 2114 | ||
2059 | if (!nfs4_sequence_done(task, &data->o_res.seq_res)) | 2115 | if (!nfs4_sequence_process(task, &data->o_res.seq_res)) |
2060 | return; | 2116 | return; |
2061 | 2117 | ||
2062 | if (task->tk_status == 0) { | 2118 | if (task->tk_status == 0) { |
@@ -7514,12 +7570,20 @@ static int _nfs4_proc_create_session(struct nfs_client *clp, | |||
7514 | status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); | 7570 | status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); |
7515 | trace_nfs4_create_session(clp, status); | 7571 | trace_nfs4_create_session(clp, status); |
7516 | 7572 | ||
7573 | switch (status) { | ||
7574 | case -NFS4ERR_STALE_CLIENTID: | ||
7575 | case -NFS4ERR_DELAY: | ||
7576 | case -ETIMEDOUT: | ||
7577 | case -EACCES: | ||
7578 | case -EAGAIN: | ||
7579 | goto out; | ||
7580 | }; | ||
7581 | |||
7582 | clp->cl_seqid++; | ||
7517 | if (!status) { | 7583 | if (!status) { |
7518 | /* Verify the session's negotiated channel_attrs values */ | 7584 | /* Verify the session's negotiated channel_attrs values */ |
7519 | status = nfs4_verify_channel_attrs(&args, &res); | 7585 | status = nfs4_verify_channel_attrs(&args, &res); |
7520 | /* Increment the clientid slot sequence id */ | 7586 | /* Increment the clientid slot sequence id */ |
7521 | if (clp->cl_seqid == res.seqid) | ||
7522 | clp->cl_seqid++; | ||
7523 | if (status) | 7587 | if (status) |
7524 | goto out; | 7588 | goto out; |
7525 | nfs4_update_session(session, &res); | 7589 | nfs4_update_session(session, &res); |
@@ -7864,7 +7928,7 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata) | |||
7864 | struct nfs4_layoutget *lgp = calldata; | 7928 | struct nfs4_layoutget *lgp = calldata; |
7865 | 7929 | ||
7866 | dprintk("--> %s\n", __func__); | 7930 | dprintk("--> %s\n", __func__); |
7867 | nfs41_sequence_done(task, &lgp->res.seq_res); | 7931 | nfs41_sequence_process(task, &lgp->res.seq_res); |
7868 | dprintk("<-- %s\n", __func__); | 7932 | dprintk("<-- %s\n", __func__); |
7869 | } | 7933 | } |
7870 | 7934 | ||
@@ -8080,6 +8144,7 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, long *timeout, gfp_t gfp_flags) | |||
8080 | /* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */ | 8144 | /* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */ |
8081 | if (status == 0 && lgp->res.layoutp->len) | 8145 | if (status == 0 && lgp->res.layoutp->len) |
8082 | lseg = pnfs_layout_process(lgp); | 8146 | lseg = pnfs_layout_process(lgp); |
8147 | nfs4_sequence_free_slot(&lgp->res.seq_res); | ||
8083 | rpc_put_task(task); | 8148 | rpc_put_task(task); |
8084 | dprintk("<-- %s status=%d\n", __func__, status); | 8149 | dprintk("<-- %s status=%d\n", __func__, status); |
8085 | if (status) | 8150 | if (status) |
@@ -8106,7 +8171,7 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata) | |||
8106 | 8171 | ||
8107 | dprintk("--> %s\n", __func__); | 8172 | dprintk("--> %s\n", __func__); |
8108 | 8173 | ||
8109 | if (!nfs41_sequence_done(task, &lrp->res.seq_res)) | 8174 | if (!nfs41_sequence_process(task, &lrp->res.seq_res)) |
8110 | return; | 8175 | return; |
8111 | 8176 | ||
8112 | server = NFS_SERVER(lrp->args.inode); | 8177 | server = NFS_SERVER(lrp->args.inode); |
@@ -8118,6 +8183,7 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata) | |||
8118 | case -NFS4ERR_DELAY: | 8183 | case -NFS4ERR_DELAY: |
8119 | if (nfs4_async_handle_error(task, server, NULL, NULL) != -EAGAIN) | 8184 | if (nfs4_async_handle_error(task, server, NULL, NULL) != -EAGAIN) |
8120 | break; | 8185 | break; |
8186 | nfs4_sequence_free_slot(&lrp->res.seq_res); | ||
8121 | rpc_restart_call_prepare(task); | 8187 | rpc_restart_call_prepare(task); |
8122 | return; | 8188 | return; |
8123 | } | 8189 | } |
@@ -8132,12 +8198,16 @@ static void nfs4_layoutreturn_release(void *calldata) | |||
8132 | 8198 | ||
8133 | dprintk("--> %s\n", __func__); | 8199 | dprintk("--> %s\n", __func__); |
8134 | spin_lock(&lo->plh_inode->i_lock); | 8200 | spin_lock(&lo->plh_inode->i_lock); |
8135 | pnfs_mark_matching_lsegs_invalid(lo, &freeme, &lrp->args.range, | 8201 | if (lrp->res.lrs_present) { |
8136 | be32_to_cpu(lrp->args.stateid.seqid)); | 8202 | pnfs_mark_matching_lsegs_invalid(lo, &freeme, |
8137 | if (lrp->res.lrs_present && pnfs_layout_is_valid(lo)) | 8203 | &lrp->args.range, |
8204 | be32_to_cpu(lrp->args.stateid.seqid)); | ||
8138 | pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); | 8205 | pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); |
8206 | } else | ||
8207 | pnfs_mark_layout_stateid_invalid(lo, &freeme); | ||
8139 | pnfs_clear_layoutreturn_waitbit(lo); | 8208 | pnfs_clear_layoutreturn_waitbit(lo); |
8140 | spin_unlock(&lo->plh_inode->i_lock); | 8209 | spin_unlock(&lo->plh_inode->i_lock); |
8210 | nfs4_sequence_free_slot(&lrp->res.seq_res); | ||
8141 | pnfs_free_lseg_list(&freeme); | 8211 | pnfs_free_lseg_list(&freeme); |
8142 | pnfs_put_layout_hdr(lrp->args.layout); | 8212 | pnfs_put_layout_hdr(lrp->args.layout); |
8143 | nfs_iput_and_deactive(lrp->inode); | 8213 | nfs_iput_and_deactive(lrp->inode); |
diff --git a/fs/nfs/nfs4session.c b/fs/nfs/nfs4session.c index 332d06e64fa9..b62973045a3e 100644 --- a/fs/nfs/nfs4session.c +++ b/fs/nfs/nfs4session.c | |||
@@ -28,6 +28,7 @@ static void nfs4_init_slot_table(struct nfs4_slot_table *tbl, const char *queue) | |||
28 | tbl->highest_used_slotid = NFS4_NO_SLOT; | 28 | tbl->highest_used_slotid = NFS4_NO_SLOT; |
29 | spin_lock_init(&tbl->slot_tbl_lock); | 29 | spin_lock_init(&tbl->slot_tbl_lock); |
30 | rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, queue); | 30 | rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, queue); |
31 | init_waitqueue_head(&tbl->slot_waitq); | ||
31 | init_completion(&tbl->complete); | 32 | init_completion(&tbl->complete); |
32 | } | 33 | } |
33 | 34 | ||
@@ -172,6 +173,58 @@ struct nfs4_slot *nfs4_lookup_slot(struct nfs4_slot_table *tbl, u32 slotid) | |||
172 | return ERR_PTR(-E2BIG); | 173 | return ERR_PTR(-E2BIG); |
173 | } | 174 | } |
174 | 175 | ||
176 | static int nfs4_slot_get_seqid(struct nfs4_slot_table *tbl, u32 slotid, | ||
177 | u32 *seq_nr) | ||
178 | __must_hold(&tbl->slot_tbl_lock) | ||
179 | { | ||
180 | struct nfs4_slot *slot; | ||
181 | |||
182 | slot = nfs4_lookup_slot(tbl, slotid); | ||
183 | if (IS_ERR(slot)) | ||
184 | return PTR_ERR(slot); | ||
185 | *seq_nr = slot->seq_nr; | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | /* | ||
190 | * nfs4_slot_seqid_in_use - test if a slot sequence id is still in use | ||
191 | * | ||
192 | * Given a slot table, slot id and sequence number, determine if the | ||
193 | * RPC call in question is still in flight. This function is mainly | ||
194 | * intended for use by the callback channel. | ||
195 | */ | ||
196 | static bool nfs4_slot_seqid_in_use(struct nfs4_slot_table *tbl, | ||
197 | u32 slotid, u32 seq_nr) | ||
198 | { | ||
199 | u32 cur_seq; | ||
200 | bool ret = false; | ||
201 | |||
202 | spin_lock(&tbl->slot_tbl_lock); | ||
203 | if (nfs4_slot_get_seqid(tbl, slotid, &cur_seq) == 0 && | ||
204 | cur_seq == seq_nr && test_bit(slotid, tbl->used_slots)) | ||
205 | ret = true; | ||
206 | spin_unlock(&tbl->slot_tbl_lock); | ||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | /* | ||
211 | * nfs4_slot_wait_on_seqid - wait until a slot sequence id is complete | ||
212 | * | ||
213 | * Given a slot table, slot id and sequence number, wait until the | ||
214 | * corresponding RPC call completes. This function is mainly | ||
215 | * intended for use by the callback channel. | ||
216 | */ | ||
217 | int nfs4_slot_wait_on_seqid(struct nfs4_slot_table *tbl, | ||
218 | u32 slotid, u32 seq_nr, | ||
219 | unsigned long timeout) | ||
220 | { | ||
221 | if (wait_event_timeout(tbl->slot_waitq, | ||
222 | !nfs4_slot_seqid_in_use(tbl, slotid, seq_nr), | ||
223 | timeout) == 0) | ||
224 | return -ETIMEDOUT; | ||
225 | return 0; | ||
226 | } | ||
227 | |||
175 | /* | 228 | /* |
176 | * nfs4_alloc_slot - efficiently look for a free slot | 229 | * nfs4_alloc_slot - efficiently look for a free slot |
177 | * | 230 | * |
diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h index 5b51298d1d03..f703b755351b 100644 --- a/fs/nfs/nfs4session.h +++ b/fs/nfs/nfs4session.h | |||
@@ -21,7 +21,8 @@ struct nfs4_slot { | |||
21 | unsigned long generation; | 21 | unsigned long generation; |
22 | u32 slot_nr; | 22 | u32 slot_nr; |
23 | u32 seq_nr; | 23 | u32 seq_nr; |
24 | unsigned int interrupted : 1; | 24 | unsigned int interrupted : 1, |
25 | seq_done : 1; | ||
25 | }; | 26 | }; |
26 | 27 | ||
27 | /* Sessions */ | 28 | /* Sessions */ |
@@ -36,6 +37,7 @@ struct nfs4_slot_table { | |||
36 | unsigned long used_slots[SLOT_TABLE_SZ]; /* used/unused bitmap */ | 37 | unsigned long used_slots[SLOT_TABLE_SZ]; /* used/unused bitmap */ |
37 | spinlock_t slot_tbl_lock; | 38 | spinlock_t slot_tbl_lock; |
38 | struct rpc_wait_queue slot_tbl_waitq; /* allocators may wait here */ | 39 | struct rpc_wait_queue slot_tbl_waitq; /* allocators may wait here */ |
40 | wait_queue_head_t slot_waitq; /* Completion wait on slot */ | ||
39 | u32 max_slots; /* # slots in table */ | 41 | u32 max_slots; /* # slots in table */ |
40 | u32 max_slotid; /* Max allowed slotid value */ | 42 | u32 max_slotid; /* Max allowed slotid value */ |
41 | u32 highest_used_slotid; /* sent to server on each SEQ. | 43 | u32 highest_used_slotid; /* sent to server on each SEQ. |
@@ -78,6 +80,9 @@ extern int nfs4_setup_slot_table(struct nfs4_slot_table *tbl, | |||
78 | extern void nfs4_shutdown_slot_table(struct nfs4_slot_table *tbl); | 80 | extern void nfs4_shutdown_slot_table(struct nfs4_slot_table *tbl); |
79 | extern struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl); | 81 | extern struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl); |
80 | extern struct nfs4_slot *nfs4_lookup_slot(struct nfs4_slot_table *tbl, u32 slotid); | 82 | extern struct nfs4_slot *nfs4_lookup_slot(struct nfs4_slot_table *tbl, u32 slotid); |
83 | extern int nfs4_slot_wait_on_seqid(struct nfs4_slot_table *tbl, | ||
84 | u32 slotid, u32 seq_nr, | ||
85 | unsigned long timeout); | ||
81 | extern bool nfs4_try_to_lock_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot); | 86 | extern bool nfs4_try_to_lock_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot); |
82 | extern void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot); | 87 | extern void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot); |
83 | extern void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl); | 88 | extern void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl); |
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 70806cae0d36..2c93a85eda51 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -365,7 +365,8 @@ pnfs_layout_remove_lseg(struct pnfs_layout_hdr *lo, | |||
365 | /* Matched by pnfs_get_layout_hdr in pnfs_layout_insert_lseg */ | 365 | /* Matched by pnfs_get_layout_hdr in pnfs_layout_insert_lseg */ |
366 | atomic_dec(&lo->plh_refcount); | 366 | atomic_dec(&lo->plh_refcount); |
367 | if (list_empty(&lo->plh_segs)) { | 367 | if (list_empty(&lo->plh_segs)) { |
368 | set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); | 368 | if (atomic_read(&lo->plh_outstanding) == 0) |
369 | set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); | ||
369 | clear_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags); | 370 | clear_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags); |
370 | } | 371 | } |
371 | rpc_wake_up(&NFS_SERVER(inode)->roc_rpcwaitq); | 372 | rpc_wake_up(&NFS_SERVER(inode)->roc_rpcwaitq); |
@@ -768,17 +769,32 @@ pnfs_destroy_all_layouts(struct nfs_client *clp) | |||
768 | pnfs_destroy_layouts_byclid(clp, false); | 769 | pnfs_destroy_layouts_byclid(clp, false); |
769 | } | 770 | } |
770 | 771 | ||
772 | static void | ||
773 | pnfs_clear_layoutreturn_info(struct pnfs_layout_hdr *lo) | ||
774 | { | ||
775 | lo->plh_return_iomode = 0; | ||
776 | lo->plh_return_seq = 0; | ||
777 | clear_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags); | ||
778 | } | ||
779 | |||
771 | /* update lo->plh_stateid with new if is more recent */ | 780 | /* update lo->plh_stateid with new if is more recent */ |
772 | void | 781 | void |
773 | pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new, | 782 | pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new, |
774 | bool update_barrier) | 783 | bool update_barrier) |
775 | { | 784 | { |
776 | u32 oldseq, newseq, new_barrier = 0; | 785 | u32 oldseq, newseq, new_barrier = 0; |
777 | bool invalid = !pnfs_layout_is_valid(lo); | ||
778 | 786 | ||
779 | oldseq = be32_to_cpu(lo->plh_stateid.seqid); | 787 | oldseq = be32_to_cpu(lo->plh_stateid.seqid); |
780 | newseq = be32_to_cpu(new->seqid); | 788 | newseq = be32_to_cpu(new->seqid); |
781 | if (invalid || pnfs_seqid_is_newer(newseq, oldseq)) { | 789 | |
790 | if (!pnfs_layout_is_valid(lo)) { | ||
791 | nfs4_stateid_copy(&lo->plh_stateid, new); | ||
792 | lo->plh_barrier = newseq; | ||
793 | pnfs_clear_layoutreturn_info(lo); | ||
794 | clear_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); | ||
795 | return; | ||
796 | } | ||
797 | if (pnfs_seqid_is_newer(newseq, oldseq)) { | ||
782 | nfs4_stateid_copy(&lo->plh_stateid, new); | 798 | nfs4_stateid_copy(&lo->plh_stateid, new); |
783 | /* | 799 | /* |
784 | * Because of wraparound, we want to keep the barrier | 800 | * Because of wraparound, we want to keep the barrier |
@@ -790,7 +806,7 @@ pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new, | |||
790 | new_barrier = be32_to_cpu(new->seqid); | 806 | new_barrier = be32_to_cpu(new->seqid); |
791 | else if (new_barrier == 0) | 807 | else if (new_barrier == 0) |
792 | return; | 808 | return; |
793 | if (invalid || pnfs_seqid_is_newer(new_barrier, lo->plh_barrier)) | 809 | if (pnfs_seqid_is_newer(new_barrier, lo->plh_barrier)) |
794 | lo->plh_barrier = new_barrier; | 810 | lo->plh_barrier = new_barrier; |
795 | } | 811 | } |
796 | 812 | ||
@@ -886,19 +902,14 @@ void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo) | |||
886 | rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq); | 902 | rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq); |
887 | } | 903 | } |
888 | 904 | ||
889 | static void | ||
890 | pnfs_clear_layoutreturn_info(struct pnfs_layout_hdr *lo) | ||
891 | { | ||
892 | lo->plh_return_iomode = 0; | ||
893 | lo->plh_return_seq = 0; | ||
894 | clear_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags); | ||
895 | } | ||
896 | |||
897 | static bool | 905 | static bool |
898 | pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo, | 906 | pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo, |
899 | nfs4_stateid *stateid, | 907 | nfs4_stateid *stateid, |
900 | enum pnfs_iomode *iomode) | 908 | enum pnfs_iomode *iomode) |
901 | { | 909 | { |
910 | /* Serialise LAYOUTGET/LAYOUTRETURN */ | ||
911 | if (atomic_read(&lo->plh_outstanding) != 0) | ||
912 | return false; | ||
902 | if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) | 913 | if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) |
903 | return false; | 914 | return false; |
904 | pnfs_get_layout_hdr(lo); | 915 | pnfs_get_layout_hdr(lo); |
@@ -1555,6 +1566,7 @@ pnfs_update_layout(struct inode *ino, | |||
1555 | } | 1566 | } |
1556 | 1567 | ||
1557 | lookup_again: | 1568 | lookup_again: |
1569 | nfs4_client_recover_expired_lease(clp); | ||
1558 | first = false; | 1570 | first = false; |
1559 | spin_lock(&ino->i_lock); | 1571 | spin_lock(&ino->i_lock); |
1560 | lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags); | 1572 | lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags); |
@@ -1797,16 +1809,11 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) | |||
1797 | */ | 1809 | */ |
1798 | pnfs_mark_layout_stateid_invalid(lo, &free_me); | 1810 | pnfs_mark_layout_stateid_invalid(lo, &free_me); |
1799 | 1811 | ||
1800 | nfs4_stateid_copy(&lo->plh_stateid, &res->stateid); | 1812 | pnfs_set_layout_stateid(lo, &res->stateid, true); |
1801 | lo->plh_barrier = be32_to_cpu(res->stateid.seqid); | ||
1802 | } | 1813 | } |
1803 | 1814 | ||
1804 | pnfs_get_lseg(lseg); | 1815 | pnfs_get_lseg(lseg); |
1805 | pnfs_layout_insert_lseg(lo, lseg, &free_me); | 1816 | pnfs_layout_insert_lseg(lo, lseg, &free_me); |
1806 | if (!pnfs_layout_is_valid(lo)) { | ||
1807 | pnfs_clear_layoutreturn_info(lo); | ||
1808 | clear_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); | ||
1809 | } | ||
1810 | 1817 | ||
1811 | 1818 | ||
1812 | if (res->return_on_close) | 1819 | if (res->return_on_close) |
@@ -2510,7 +2517,6 @@ pnfs_report_layoutstat(struct inode *inode, gfp_t gfp_flags) | |||
2510 | 2517 | ||
2511 | data->args.fh = NFS_FH(inode); | 2518 | data->args.fh = NFS_FH(inode); |
2512 | data->args.inode = inode; | 2519 | data->args.inode = inode; |
2513 | nfs4_stateid_copy(&data->args.stateid, &hdr->plh_stateid); | ||
2514 | status = ld->prepare_layoutstats(&data->args); | 2520 | status = ld->prepare_layoutstats(&data->args); |
2515 | if (status) | 2521 | if (status) |
2516 | goto out_free; | 2522 | goto out_free; |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 18d446e1a82b..d39601381adf 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -923,6 +923,8 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void) | |||
923 | 923 | ||
924 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 924 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
925 | if (data) { | 925 | if (data) { |
926 | data->timeo = NFS_UNSPEC_TIMEO; | ||
927 | data->retrans = NFS_UNSPEC_RETRANS; | ||
926 | data->acregmin = NFS_DEF_ACREGMIN; | 928 | data->acregmin = NFS_DEF_ACREGMIN; |
927 | data->acregmax = NFS_DEF_ACREGMAX; | 929 | data->acregmax = NFS_DEF_ACREGMAX; |
928 | data->acdirmin = NFS_DEF_ACDIRMIN; | 930 | data->acdirmin = NFS_DEF_ACDIRMIN; |
@@ -1189,6 +1191,19 @@ static int nfs_get_option_ul(substring_t args[], unsigned long *option) | |||
1189 | return rc; | 1191 | return rc; |
1190 | } | 1192 | } |
1191 | 1193 | ||
1194 | static int nfs_get_option_ul_bound(substring_t args[], unsigned long *option, | ||
1195 | unsigned long l_bound, unsigned long u_bound) | ||
1196 | { | ||
1197 | int ret; | ||
1198 | |||
1199 | ret = nfs_get_option_ul(args, option); | ||
1200 | if (ret != 0) | ||
1201 | return ret; | ||
1202 | if (*option < l_bound || *option > u_bound) | ||
1203 | return -ERANGE; | ||
1204 | return 0; | ||
1205 | } | ||
1206 | |||
1192 | /* | 1207 | /* |
1193 | * Error-check and convert a string of mount options from user space into | 1208 | * Error-check and convert a string of mount options from user space into |
1194 | * a data structure. The whole mount string is processed; bad options are | 1209 | * a data structure. The whole mount string is processed; bad options are |
@@ -1352,12 +1367,12 @@ static int nfs_parse_mount_options(char *raw, | |||
1352 | mnt->bsize = option; | 1367 | mnt->bsize = option; |
1353 | break; | 1368 | break; |
1354 | case Opt_timeo: | 1369 | case Opt_timeo: |
1355 | if (nfs_get_option_ul(args, &option) || option == 0) | 1370 | if (nfs_get_option_ul_bound(args, &option, 1, INT_MAX)) |
1356 | goto out_invalid_value; | 1371 | goto out_invalid_value; |
1357 | mnt->timeo = option; | 1372 | mnt->timeo = option; |
1358 | break; | 1373 | break; |
1359 | case Opt_retrans: | 1374 | case Opt_retrans: |
1360 | if (nfs_get_option_ul(args, &option) || option == 0) | 1375 | if (nfs_get_option_ul_bound(args, &option, 0, INT_MAX)) |
1361 | goto out_invalid_value; | 1376 | goto out_invalid_value; |
1362 | mnt->retrans = option; | 1377 | mnt->retrans = option; |
1363 | break; | 1378 | break; |
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index d2f97ecca6a5..e0e5f7c3c99f 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
@@ -67,18 +67,7 @@ static int fanotify_get_response(struct fsnotify_group *group, | |||
67 | 67 | ||
68 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); | 68 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); |
69 | 69 | ||
70 | wait_event(group->fanotify_data.access_waitq, event->response || | 70 | wait_event(group->fanotify_data.access_waitq, event->response); |
71 | atomic_read(&group->fanotify_data.bypass_perm)); | ||
72 | |||
73 | if (!event->response) { /* bypass_perm set */ | ||
74 | /* | ||
75 | * Event was canceled because group is being destroyed. Remove | ||
76 | * it from group's event list because we are responsible for | ||
77 | * freeing the permission event. | ||
78 | */ | ||
79 | fsnotify_remove_event(group, &event->fae.fse); | ||
80 | return 0; | ||
81 | } | ||
82 | 71 | ||
83 | /* userspace responded, convert to something usable */ | 72 | /* userspace responded, convert to something usable */ |
84 | switch (event->response) { | 73 | switch (event->response) { |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 8e8e6bcd1d43..a64313868d3a 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -358,16 +358,20 @@ static int fanotify_release(struct inode *ignored, struct file *file) | |||
358 | 358 | ||
359 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | 359 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS |
360 | struct fanotify_perm_event_info *event, *next; | 360 | struct fanotify_perm_event_info *event, *next; |
361 | struct fsnotify_event *fsn_event; | ||
361 | 362 | ||
362 | /* | 363 | /* |
363 | * There may be still new events arriving in the notification queue | 364 | * Stop new events from arriving in the notification queue. since |
364 | * but since userspace cannot use fanotify fd anymore, no event can | 365 | * userspace cannot use fanotify fd anymore, no event can enter or |
365 | * enter or leave access_list by now. | 366 | * leave access_list by now either. |
366 | */ | 367 | */ |
367 | spin_lock(&group->fanotify_data.access_lock); | 368 | fsnotify_group_stop_queueing(group); |
368 | |||
369 | atomic_inc(&group->fanotify_data.bypass_perm); | ||
370 | 369 | ||
370 | /* | ||
371 | * Process all permission events on access_list and notification queue | ||
372 | * and simulate reply from userspace. | ||
373 | */ | ||
374 | spin_lock(&group->fanotify_data.access_lock); | ||
371 | list_for_each_entry_safe(event, next, &group->fanotify_data.access_list, | 375 | list_for_each_entry_safe(event, next, &group->fanotify_data.access_list, |
372 | fae.fse.list) { | 376 | fae.fse.list) { |
373 | pr_debug("%s: found group=%p event=%p\n", __func__, group, | 377 | pr_debug("%s: found group=%p event=%p\n", __func__, group, |
@@ -379,12 +383,21 @@ static int fanotify_release(struct inode *ignored, struct file *file) | |||
379 | spin_unlock(&group->fanotify_data.access_lock); | 383 | spin_unlock(&group->fanotify_data.access_lock); |
380 | 384 | ||
381 | /* | 385 | /* |
382 | * Since bypass_perm is set, newly queued events will not wait for | 386 | * Destroy all non-permission events. For permission events just |
383 | * access response. Wake up the already sleeping ones now. | 387 | * dequeue them and set the response. They will be freed once the |
384 | * synchronize_srcu() in fsnotify_destroy_group() will wait for all | 388 | * response is consumed and fanotify_get_response() returns. |
385 | * processes sleeping in fanotify_handle_event() waiting for access | ||
386 | * response and thus also for all permission events to be freed. | ||
387 | */ | 389 | */ |
390 | mutex_lock(&group->notification_mutex); | ||
391 | while (!fsnotify_notify_queue_is_empty(group)) { | ||
392 | fsn_event = fsnotify_remove_first_event(group); | ||
393 | if (!(fsn_event->mask & FAN_ALL_PERM_EVENTS)) | ||
394 | fsnotify_destroy_event(group, fsn_event); | ||
395 | else | ||
396 | FANOTIFY_PE(fsn_event)->response = FAN_ALLOW; | ||
397 | } | ||
398 | mutex_unlock(&group->notification_mutex); | ||
399 | |||
400 | /* Response for all permission events it set, wakeup waiters */ | ||
388 | wake_up(&group->fanotify_data.access_waitq); | 401 | wake_up(&group->fanotify_data.access_waitq); |
389 | #endif | 402 | #endif |
390 | 403 | ||
@@ -755,7 +768,6 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
755 | spin_lock_init(&group->fanotify_data.access_lock); | 768 | spin_lock_init(&group->fanotify_data.access_lock); |
756 | init_waitqueue_head(&group->fanotify_data.access_waitq); | 769 | init_waitqueue_head(&group->fanotify_data.access_waitq); |
757 | INIT_LIST_HEAD(&group->fanotify_data.access_list); | 770 | INIT_LIST_HEAD(&group->fanotify_data.access_list); |
758 | atomic_set(&group->fanotify_data.bypass_perm, 0); | ||
759 | #endif | 771 | #endif |
760 | switch (flags & FAN_ALL_CLASS_BITS) { | 772 | switch (flags & FAN_ALL_CLASS_BITS) { |
761 | case FAN_CLASS_NOTIF: | 773 | case FAN_CLASS_NOTIF: |
diff --git a/fs/notify/group.c b/fs/notify/group.c index 3e2dd85be5dd..b47f7cfdcaa4 100644 --- a/fs/notify/group.c +++ b/fs/notify/group.c | |||
@@ -40,6 +40,17 @@ static void fsnotify_final_destroy_group(struct fsnotify_group *group) | |||
40 | } | 40 | } |
41 | 41 | ||
42 | /* | 42 | /* |
43 | * Stop queueing new events for this group. Once this function returns | ||
44 | * fsnotify_add_event() will not add any new events to the group's queue. | ||
45 | */ | ||
46 | void fsnotify_group_stop_queueing(struct fsnotify_group *group) | ||
47 | { | ||
48 | mutex_lock(&group->notification_mutex); | ||
49 | group->shutdown = true; | ||
50 | mutex_unlock(&group->notification_mutex); | ||
51 | } | ||
52 | |||
53 | /* | ||
43 | * Trying to get rid of a group. Remove all marks, flush all events and release | 54 | * Trying to get rid of a group. Remove all marks, flush all events and release |
44 | * the group reference. | 55 | * the group reference. |
45 | * Note that another thread calling fsnotify_clear_marks_by_group() may still | 56 | * Note that another thread calling fsnotify_clear_marks_by_group() may still |
@@ -47,6 +58,14 @@ static void fsnotify_final_destroy_group(struct fsnotify_group *group) | |||
47 | */ | 58 | */ |
48 | void fsnotify_destroy_group(struct fsnotify_group *group) | 59 | void fsnotify_destroy_group(struct fsnotify_group *group) |
49 | { | 60 | { |
61 | /* | ||
62 | * Stop queueing new events. The code below is careful enough to not | ||
63 | * require this but fanotify needs to stop queuing events even before | ||
64 | * fsnotify_destroy_group() is called and this makes the other callers | ||
65 | * of fsnotify_destroy_group() to see the same behavior. | ||
66 | */ | ||
67 | fsnotify_group_stop_queueing(group); | ||
68 | |||
50 | /* clear all inode marks for this group, attach them to destroy_list */ | 69 | /* clear all inode marks for this group, attach them to destroy_list */ |
51 | fsnotify_detach_group_marks(group); | 70 | fsnotify_detach_group_marks(group); |
52 | 71 | ||
diff --git a/fs/notify/notification.c b/fs/notify/notification.c index a95d8e037aeb..e455e83ceeeb 100644 --- a/fs/notify/notification.c +++ b/fs/notify/notification.c | |||
@@ -82,7 +82,8 @@ void fsnotify_destroy_event(struct fsnotify_group *group, | |||
82 | * Add an event to the group notification queue. The group can later pull this | 82 | * Add an event to the group notification queue. The group can later pull this |
83 | * event off the queue to deal with. The function returns 0 if the event was | 83 | * event off the queue to deal with. The function returns 0 if the event was |
84 | * added to the queue, 1 if the event was merged with some other queued event, | 84 | * added to the queue, 1 if the event was merged with some other queued event, |
85 | * 2 if the queue of events has overflown. | 85 | * 2 if the event was not queued - either the queue of events has overflown |
86 | * or the group is shutting down. | ||
86 | */ | 87 | */ |
87 | int fsnotify_add_event(struct fsnotify_group *group, | 88 | int fsnotify_add_event(struct fsnotify_group *group, |
88 | struct fsnotify_event *event, | 89 | struct fsnotify_event *event, |
@@ -96,6 +97,11 @@ int fsnotify_add_event(struct fsnotify_group *group, | |||
96 | 97 | ||
97 | mutex_lock(&group->notification_mutex); | 98 | mutex_lock(&group->notification_mutex); |
98 | 99 | ||
100 | if (group->shutdown) { | ||
101 | mutex_unlock(&group->notification_mutex); | ||
102 | return 2; | ||
103 | } | ||
104 | |||
99 | if (group->q_len >= group->max_events) { | 105 | if (group->q_len >= group->max_events) { |
100 | ret = 2; | 106 | ret = 2; |
101 | /* Queue overflow event only if it isn't already queued */ | 107 | /* Queue overflow event only if it isn't already queued */ |
@@ -126,21 +132,6 @@ queue: | |||
126 | } | 132 | } |
127 | 133 | ||
128 | /* | 134 | /* |
129 | * Remove @event from group's notification queue. It is the responsibility of | ||
130 | * the caller to destroy the event. | ||
131 | */ | ||
132 | void fsnotify_remove_event(struct fsnotify_group *group, | ||
133 | struct fsnotify_event *event) | ||
134 | { | ||
135 | mutex_lock(&group->notification_mutex); | ||
136 | if (!list_empty(&event->list)) { | ||
137 | list_del_init(&event->list); | ||
138 | group->q_len--; | ||
139 | } | ||
140 | mutex_unlock(&group->notification_mutex); | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * Remove and return the first event from the notification list. It is the | 135 | * Remove and return the first event from the notification list. It is the |
145 | * responsibility of the caller to destroy the obtained event | 136 | * responsibility of the caller to destroy the obtained event |
146 | */ | 137 | */ |
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 7dabbc31060e..f165f867f332 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -5922,7 +5922,6 @@ bail: | |||
5922 | } | 5922 | } |
5923 | 5923 | ||
5924 | static int ocfs2_replay_truncate_records(struct ocfs2_super *osb, | 5924 | static int ocfs2_replay_truncate_records(struct ocfs2_super *osb, |
5925 | handle_t *handle, | ||
5926 | struct inode *data_alloc_inode, | 5925 | struct inode *data_alloc_inode, |
5927 | struct buffer_head *data_alloc_bh) | 5926 | struct buffer_head *data_alloc_bh) |
5928 | { | 5927 | { |
@@ -5935,11 +5934,19 @@ static int ocfs2_replay_truncate_records(struct ocfs2_super *osb, | |||
5935 | struct ocfs2_truncate_log *tl; | 5934 | struct ocfs2_truncate_log *tl; |
5936 | struct inode *tl_inode = osb->osb_tl_inode; | 5935 | struct inode *tl_inode = osb->osb_tl_inode; |
5937 | struct buffer_head *tl_bh = osb->osb_tl_bh; | 5936 | struct buffer_head *tl_bh = osb->osb_tl_bh; |
5937 | handle_t *handle; | ||
5938 | 5938 | ||
5939 | di = (struct ocfs2_dinode *) tl_bh->b_data; | 5939 | di = (struct ocfs2_dinode *) tl_bh->b_data; |
5940 | tl = &di->id2.i_dealloc; | 5940 | tl = &di->id2.i_dealloc; |
5941 | i = le16_to_cpu(tl->tl_used) - 1; | 5941 | i = le16_to_cpu(tl->tl_used) - 1; |
5942 | while (i >= 0) { | 5942 | while (i >= 0) { |
5943 | handle = ocfs2_start_trans(osb, OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC); | ||
5944 | if (IS_ERR(handle)) { | ||
5945 | status = PTR_ERR(handle); | ||
5946 | mlog_errno(status); | ||
5947 | goto bail; | ||
5948 | } | ||
5949 | |||
5943 | /* Caller has given us at least enough credits to | 5950 | /* Caller has given us at least enough credits to |
5944 | * update the truncate log dinode */ | 5951 | * update the truncate log dinode */ |
5945 | status = ocfs2_journal_access_di(handle, INODE_CACHE(tl_inode), tl_bh, | 5952 | status = ocfs2_journal_access_di(handle, INODE_CACHE(tl_inode), tl_bh, |
@@ -5974,12 +5981,7 @@ static int ocfs2_replay_truncate_records(struct ocfs2_super *osb, | |||
5974 | } | 5981 | } |
5975 | } | 5982 | } |
5976 | 5983 | ||
5977 | status = ocfs2_extend_trans(handle, | 5984 | ocfs2_commit_trans(osb, handle); |
5978 | OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC); | ||
5979 | if (status < 0) { | ||
5980 | mlog_errno(status); | ||
5981 | goto bail; | ||
5982 | } | ||
5983 | i--; | 5985 | i--; |
5984 | } | 5986 | } |
5985 | 5987 | ||
@@ -5994,7 +5996,6 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
5994 | { | 5996 | { |
5995 | int status; | 5997 | int status; |
5996 | unsigned int num_to_flush; | 5998 | unsigned int num_to_flush; |
5997 | handle_t *handle; | ||
5998 | struct inode *tl_inode = osb->osb_tl_inode; | 5999 | struct inode *tl_inode = osb->osb_tl_inode; |
5999 | struct inode *data_alloc_inode = NULL; | 6000 | struct inode *data_alloc_inode = NULL; |
6000 | struct buffer_head *tl_bh = osb->osb_tl_bh; | 6001 | struct buffer_head *tl_bh = osb->osb_tl_bh; |
@@ -6038,21 +6039,11 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
6038 | goto out_mutex; | 6039 | goto out_mutex; |
6039 | } | 6040 | } |
6040 | 6041 | ||
6041 | handle = ocfs2_start_trans(osb, OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC); | 6042 | status = ocfs2_replay_truncate_records(osb, data_alloc_inode, |
6042 | if (IS_ERR(handle)) { | ||
6043 | status = PTR_ERR(handle); | ||
6044 | mlog_errno(status); | ||
6045 | goto out_unlock; | ||
6046 | } | ||
6047 | |||
6048 | status = ocfs2_replay_truncate_records(osb, handle, data_alloc_inode, | ||
6049 | data_alloc_bh); | 6043 | data_alloc_bh); |
6050 | if (status < 0) | 6044 | if (status < 0) |
6051 | mlog_errno(status); | 6045 | mlog_errno(status); |
6052 | 6046 | ||
6053 | ocfs2_commit_trans(osb, handle); | ||
6054 | |||
6055 | out_unlock: | ||
6056 | brelse(data_alloc_bh); | 6047 | brelse(data_alloc_bh); |
6057 | ocfs2_inode_unlock(data_alloc_inode, 1); | 6048 | ocfs2_inode_unlock(data_alloc_inode, 1); |
6058 | 6049 | ||
@@ -6413,43 +6404,34 @@ static int ocfs2_free_cached_blocks(struct ocfs2_super *osb, | |||
6413 | goto out_mutex; | 6404 | goto out_mutex; |
6414 | } | 6405 | } |
6415 | 6406 | ||
6416 | handle = ocfs2_start_trans(osb, OCFS2_SUBALLOC_FREE); | ||
6417 | if (IS_ERR(handle)) { | ||
6418 | ret = PTR_ERR(handle); | ||
6419 | mlog_errno(ret); | ||
6420 | goto out_unlock; | ||
6421 | } | ||
6422 | |||
6423 | while (head) { | 6407 | while (head) { |
6424 | if (head->free_bg) | 6408 | if (head->free_bg) |
6425 | bg_blkno = head->free_bg; | 6409 | bg_blkno = head->free_bg; |
6426 | else | 6410 | else |
6427 | bg_blkno = ocfs2_which_suballoc_group(head->free_blk, | 6411 | bg_blkno = ocfs2_which_suballoc_group(head->free_blk, |
6428 | head->free_bit); | 6412 | head->free_bit); |
6413 | handle = ocfs2_start_trans(osb, OCFS2_SUBALLOC_FREE); | ||
6414 | if (IS_ERR(handle)) { | ||
6415 | ret = PTR_ERR(handle); | ||
6416 | mlog_errno(ret); | ||
6417 | goto out_unlock; | ||
6418 | } | ||
6419 | |||
6429 | trace_ocfs2_free_cached_blocks( | 6420 | trace_ocfs2_free_cached_blocks( |
6430 | (unsigned long long)head->free_blk, head->free_bit); | 6421 | (unsigned long long)head->free_blk, head->free_bit); |
6431 | 6422 | ||
6432 | ret = ocfs2_free_suballoc_bits(handle, inode, di_bh, | 6423 | ret = ocfs2_free_suballoc_bits(handle, inode, di_bh, |
6433 | head->free_bit, bg_blkno, 1); | 6424 | head->free_bit, bg_blkno, 1); |
6434 | if (ret) { | 6425 | if (ret) |
6435 | mlog_errno(ret); | 6426 | mlog_errno(ret); |
6436 | goto out_journal; | ||
6437 | } | ||
6438 | 6427 | ||
6439 | ret = ocfs2_extend_trans(handle, OCFS2_SUBALLOC_FREE); | 6428 | ocfs2_commit_trans(osb, handle); |
6440 | if (ret) { | ||
6441 | mlog_errno(ret); | ||
6442 | goto out_journal; | ||
6443 | } | ||
6444 | 6429 | ||
6445 | tmp = head; | 6430 | tmp = head; |
6446 | head = head->free_next; | 6431 | head = head->free_next; |
6447 | kfree(tmp); | 6432 | kfree(tmp); |
6448 | } | 6433 | } |
6449 | 6434 | ||
6450 | out_journal: | ||
6451 | ocfs2_commit_trans(osb, handle); | ||
6452 | |||
6453 | out_unlock: | 6435 | out_unlock: |
6454 | ocfs2_inode_unlock(inode, 1); | 6436 | ocfs2_inode_unlock(inode, 1); |
6455 | brelse(di_bh); | 6437 | brelse(di_bh); |
diff --git a/fs/ocfs2/cluster/tcp_internal.h b/fs/ocfs2/cluster/tcp_internal.h index 94b18369b1cc..b95e7df5b76a 100644 --- a/fs/ocfs2/cluster/tcp_internal.h +++ b/fs/ocfs2/cluster/tcp_internal.h | |||
@@ -44,9 +44,6 @@ | |||
44 | * version here in tcp_internal.h should not need to be bumped for | 44 | * version here in tcp_internal.h should not need to be bumped for |
45 | * filesystem locking changes. | 45 | * filesystem locking changes. |
46 | * | 46 | * |
47 | * New in version 12 | ||
48 | * - Negotiate hb timeout when storage is down. | ||
49 | * | ||
50 | * New in version 11 | 47 | * New in version 11 |
51 | * - Negotiation of filesystem locking in the dlm join. | 48 | * - Negotiation of filesystem locking in the dlm join. |
52 | * | 49 | * |
@@ -78,7 +75,7 @@ | |||
78 | * - full 64 bit i_size in the metadata lock lvbs | 75 | * - full 64 bit i_size in the metadata lock lvbs |
79 | * - introduction of "rw" lock and pushing meta/data locking down | 76 | * - introduction of "rw" lock and pushing meta/data locking down |
80 | */ | 77 | */ |
81 | #define O2NET_PROTOCOL_VERSION 12ULL | 78 | #define O2NET_PROTOCOL_VERSION 11ULL |
82 | struct o2net_handshake { | 79 | struct o2net_handshake { |
83 | __be64 protocol_version; | 80 | __be64 protocol_version; |
84 | __be64 connector_id; | 81 | __be64 connector_id; |
diff --git a/fs/ocfs2/dlm/dlmconvert.c b/fs/ocfs2/dlm/dlmconvert.c index cdeafb4e7ed6..0bb128659d4b 100644 --- a/fs/ocfs2/dlm/dlmconvert.c +++ b/fs/ocfs2/dlm/dlmconvert.c | |||
@@ -268,7 +268,6 @@ enum dlm_status dlmconvert_remote(struct dlm_ctxt *dlm, | |||
268 | struct dlm_lock *lock, int flags, int type) | 268 | struct dlm_lock *lock, int flags, int type) |
269 | { | 269 | { |
270 | enum dlm_status status; | 270 | enum dlm_status status; |
271 | u8 old_owner = res->owner; | ||
272 | 271 | ||
273 | mlog(0, "type=%d, convert_type=%d, busy=%d\n", lock->ml.type, | 272 | mlog(0, "type=%d, convert_type=%d, busy=%d\n", lock->ml.type, |
274 | lock->ml.convert_type, res->state & DLM_LOCK_RES_IN_PROGRESS); | 273 | lock->ml.convert_type, res->state & DLM_LOCK_RES_IN_PROGRESS); |
@@ -335,7 +334,6 @@ enum dlm_status dlmconvert_remote(struct dlm_ctxt *dlm, | |||
335 | 334 | ||
336 | spin_lock(&res->spinlock); | 335 | spin_lock(&res->spinlock); |
337 | res->state &= ~DLM_LOCK_RES_IN_PROGRESS; | 336 | res->state &= ~DLM_LOCK_RES_IN_PROGRESS; |
338 | lock->convert_pending = 0; | ||
339 | /* if it failed, move it back to granted queue. | 337 | /* if it failed, move it back to granted queue. |
340 | * if master returns DLM_NORMAL and then down before sending ast, | 338 | * if master returns DLM_NORMAL and then down before sending ast, |
341 | * it may have already been moved to granted queue, reset to | 339 | * it may have already been moved to granted queue, reset to |
@@ -344,12 +342,14 @@ enum dlm_status dlmconvert_remote(struct dlm_ctxt *dlm, | |||
344 | if (status != DLM_NOTQUEUED) | 342 | if (status != DLM_NOTQUEUED) |
345 | dlm_error(status); | 343 | dlm_error(status); |
346 | dlm_revert_pending_convert(res, lock); | 344 | dlm_revert_pending_convert(res, lock); |
347 | } else if ((res->state & DLM_LOCK_RES_RECOVERING) || | 345 | } else if (!lock->convert_pending) { |
348 | (old_owner != res->owner)) { | 346 | mlog(0, "%s: res %.*s, owner died and lock has been moved back " |
349 | mlog(0, "res %.*s is in recovering or has been recovered.\n", | 347 | "to granted list, retry convert.\n", |
350 | res->lockname.len, res->lockname.name); | 348 | dlm->name, res->lockname.len, res->lockname.name); |
351 | status = DLM_RECOVERING; | 349 | status = DLM_RECOVERING; |
352 | } | 350 | } |
351 | |||
352 | lock->convert_pending = 0; | ||
353 | bail: | 353 | bail: |
354 | spin_unlock(&res->spinlock); | 354 | spin_unlock(&res->spinlock); |
355 | 355 | ||
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 4e7b0dc22450..0b055bfb8e86 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1506,7 +1506,8 @@ static int ocfs2_zero_partial_clusters(struct inode *inode, | |||
1506 | u64 start, u64 len) | 1506 | u64 start, u64 len) |
1507 | { | 1507 | { |
1508 | int ret = 0; | 1508 | int ret = 0; |
1509 | u64 tmpend, end = start + len; | 1509 | u64 tmpend = 0; |
1510 | u64 end = start + len; | ||
1510 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 1511 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
1511 | unsigned int csize = osb->s_clustersize; | 1512 | unsigned int csize = osb->s_clustersize; |
1512 | handle_t *handle; | 1513 | handle_t *handle; |
@@ -1538,18 +1539,31 @@ static int ocfs2_zero_partial_clusters(struct inode *inode, | |||
1538 | } | 1539 | } |
1539 | 1540 | ||
1540 | /* | 1541 | /* |
1541 | * We want to get the byte offset of the end of the 1st cluster. | 1542 | * If start is on a cluster boundary and end is somewhere in another |
1543 | * cluster, we have not COWed the cluster starting at start, unless | ||
1544 | * end is also within the same cluster. So, in this case, we skip this | ||
1545 | * first call to ocfs2_zero_range_for_truncate() truncate and move on | ||
1546 | * to the next one. | ||
1542 | */ | 1547 | */ |
1543 | tmpend = (u64)osb->s_clustersize + (start & ~(osb->s_clustersize - 1)); | 1548 | if ((start & (csize - 1)) != 0) { |
1544 | if (tmpend > end) | 1549 | /* |
1545 | tmpend = end; | 1550 | * We want to get the byte offset of the end of the 1st |
1551 | * cluster. | ||
1552 | */ | ||
1553 | tmpend = (u64)osb->s_clustersize + | ||
1554 | (start & ~(osb->s_clustersize - 1)); | ||
1555 | if (tmpend > end) | ||
1556 | tmpend = end; | ||
1546 | 1557 | ||
1547 | trace_ocfs2_zero_partial_clusters_range1((unsigned long long)start, | 1558 | trace_ocfs2_zero_partial_clusters_range1( |
1548 | (unsigned long long)tmpend); | 1559 | (unsigned long long)start, |
1560 | (unsigned long long)tmpend); | ||
1549 | 1561 | ||
1550 | ret = ocfs2_zero_range_for_truncate(inode, handle, start, tmpend); | 1562 | ret = ocfs2_zero_range_for_truncate(inode, handle, start, |
1551 | if (ret) | 1563 | tmpend); |
1552 | mlog_errno(ret); | 1564 | if (ret) |
1565 | mlog_errno(ret); | ||
1566 | } | ||
1553 | 1567 | ||
1554 | if (tmpend < end) { | 1568 | if (tmpend < end) { |
1555 | /* | 1569 | /* |
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index ea47120a85ff..6ad3533940ba 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
@@ -1199,14 +1199,24 @@ retry: | |||
1199 | inode_unlock((*ac)->ac_inode); | 1199 | inode_unlock((*ac)->ac_inode); |
1200 | 1200 | ||
1201 | ret = ocfs2_try_to_free_truncate_log(osb, bits_wanted); | 1201 | ret = ocfs2_try_to_free_truncate_log(osb, bits_wanted); |
1202 | if (ret == 1) | 1202 | if (ret == 1) { |
1203 | iput((*ac)->ac_inode); | ||
1204 | (*ac)->ac_inode = NULL; | ||
1203 | goto retry; | 1205 | goto retry; |
1206 | } | ||
1204 | 1207 | ||
1205 | if (ret < 0) | 1208 | if (ret < 0) |
1206 | mlog_errno(ret); | 1209 | mlog_errno(ret); |
1207 | 1210 | ||
1208 | inode_lock((*ac)->ac_inode); | 1211 | inode_lock((*ac)->ac_inode); |
1209 | ocfs2_inode_lock((*ac)->ac_inode, NULL, 1); | 1212 | ret = ocfs2_inode_lock((*ac)->ac_inode, NULL, 1); |
1213 | if (ret < 0) { | ||
1214 | mlog_errno(ret); | ||
1215 | inode_unlock((*ac)->ac_inode); | ||
1216 | iput((*ac)->ac_inode); | ||
1217 | (*ac)->ac_inode = NULL; | ||
1218 | goto bail; | ||
1219 | } | ||
1210 | } | 1220 | } |
1211 | if (status < 0) { | 1221 | if (status < 0) { |
1212 | if (status != -ENOSPC) | 1222 | if (status != -ENOSPC) |
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 54e5d6681786..43fdc2765aea 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c | |||
@@ -80,6 +80,8 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new) | |||
80 | } | 80 | } |
81 | 81 | ||
82 | for (name = buf; name < (buf + list_size); name += strlen(name) + 1) { | 82 | for (name = buf; name < (buf + list_size); name += strlen(name) + 1) { |
83 | if (ovl_is_private_xattr(name)) | ||
84 | continue; | ||
83 | retry: | 85 | retry: |
84 | size = vfs_getxattr(old, name, value, value_size); | 86 | size = vfs_getxattr(old, name, value, value_size); |
85 | if (size == -ERANGE) | 87 | if (size == -ERANGE) |
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 12bcd07b9e32..1560fdc09a5f 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c | |||
@@ -12,6 +12,8 @@ | |||
12 | #include <linux/xattr.h> | 12 | #include <linux/xattr.h> |
13 | #include <linux/security.h> | 13 | #include <linux/security.h> |
14 | #include <linux/cred.h> | 14 | #include <linux/cred.h> |
15 | #include <linux/posix_acl.h> | ||
16 | #include <linux/posix_acl_xattr.h> | ||
15 | #include "overlayfs.h" | 17 | #include "overlayfs.h" |
16 | 18 | ||
17 | void ovl_cleanup(struct inode *wdir, struct dentry *wdentry) | 19 | void ovl_cleanup(struct inode *wdir, struct dentry *wdentry) |
@@ -186,6 +188,9 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode, | |||
186 | struct dentry *newdentry; | 188 | struct dentry *newdentry; |
187 | int err; | 189 | int err; |
188 | 190 | ||
191 | if (!hardlink && !IS_POSIXACL(udir)) | ||
192 | stat->mode &= ~current_umask(); | ||
193 | |||
189 | inode_lock_nested(udir, I_MUTEX_PARENT); | 194 | inode_lock_nested(udir, I_MUTEX_PARENT); |
190 | newdentry = lookup_one_len(dentry->d_name.name, upperdir, | 195 | newdentry = lookup_one_len(dentry->d_name.name, upperdir, |
191 | dentry->d_name.len); | 196 | dentry->d_name.len); |
@@ -335,6 +340,32 @@ out_free: | |||
335 | return ret; | 340 | return ret; |
336 | } | 341 | } |
337 | 342 | ||
343 | static int ovl_set_upper_acl(struct dentry *upperdentry, const char *name, | ||
344 | const struct posix_acl *acl) | ||
345 | { | ||
346 | void *buffer; | ||
347 | size_t size; | ||
348 | int err; | ||
349 | |||
350 | if (!IS_ENABLED(CONFIG_FS_POSIX_ACL) || !acl) | ||
351 | return 0; | ||
352 | |||
353 | size = posix_acl_to_xattr(NULL, acl, NULL, 0); | ||
354 | buffer = kmalloc(size, GFP_KERNEL); | ||
355 | if (!buffer) | ||
356 | return -ENOMEM; | ||
357 | |||
358 | size = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); | ||
359 | err = size; | ||
360 | if (err < 0) | ||
361 | goto out_free; | ||
362 | |||
363 | err = vfs_setxattr(upperdentry, name, buffer, size, XATTR_CREATE); | ||
364 | out_free: | ||
365 | kfree(buffer); | ||
366 | return err; | ||
367 | } | ||
368 | |||
338 | static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode, | 369 | static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode, |
339 | struct kstat *stat, const char *link, | 370 | struct kstat *stat, const char *link, |
340 | struct dentry *hardlink) | 371 | struct dentry *hardlink) |
@@ -346,10 +377,18 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode, | |||
346 | struct dentry *upper; | 377 | struct dentry *upper; |
347 | struct dentry *newdentry; | 378 | struct dentry *newdentry; |
348 | int err; | 379 | int err; |
380 | struct posix_acl *acl, *default_acl; | ||
349 | 381 | ||
350 | if (WARN_ON(!workdir)) | 382 | if (WARN_ON(!workdir)) |
351 | return -EROFS; | 383 | return -EROFS; |
352 | 384 | ||
385 | if (!hardlink) { | ||
386 | err = posix_acl_create(dentry->d_parent->d_inode, | ||
387 | &stat->mode, &default_acl, &acl); | ||
388 | if (err) | ||
389 | return err; | ||
390 | } | ||
391 | |||
353 | err = ovl_lock_rename_workdir(workdir, upperdir); | 392 | err = ovl_lock_rename_workdir(workdir, upperdir); |
354 | if (err) | 393 | if (err) |
355 | goto out; | 394 | goto out; |
@@ -384,6 +423,17 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode, | |||
384 | if (err) | 423 | if (err) |
385 | goto out_cleanup; | 424 | goto out_cleanup; |
386 | } | 425 | } |
426 | if (!hardlink) { | ||
427 | err = ovl_set_upper_acl(newdentry, XATTR_NAME_POSIX_ACL_ACCESS, | ||
428 | acl); | ||
429 | if (err) | ||
430 | goto out_cleanup; | ||
431 | |||
432 | err = ovl_set_upper_acl(newdentry, XATTR_NAME_POSIX_ACL_DEFAULT, | ||
433 | default_acl); | ||
434 | if (err) | ||
435 | goto out_cleanup; | ||
436 | } | ||
387 | 437 | ||
388 | if (!hardlink && S_ISDIR(stat->mode)) { | 438 | if (!hardlink && S_ISDIR(stat->mode)) { |
389 | err = ovl_set_opaque(newdentry); | 439 | err = ovl_set_opaque(newdentry); |
@@ -410,6 +460,10 @@ out_dput: | |||
410 | out_unlock: | 460 | out_unlock: |
411 | unlock_rename(workdir, upperdir); | 461 | unlock_rename(workdir, upperdir); |
412 | out: | 462 | out: |
463 | if (!hardlink) { | ||
464 | posix_acl_release(acl); | ||
465 | posix_acl_release(default_acl); | ||
466 | } | ||
413 | return err; | 467 | return err; |
414 | 468 | ||
415 | out_cleanup: | 469 | out_cleanup: |
@@ -950,9 +1004,9 @@ const struct inode_operations ovl_dir_inode_operations = { | |||
950 | .permission = ovl_permission, | 1004 | .permission = ovl_permission, |
951 | .getattr = ovl_dir_getattr, | 1005 | .getattr = ovl_dir_getattr, |
952 | .setxattr = generic_setxattr, | 1006 | .setxattr = generic_setxattr, |
953 | .getxattr = ovl_getxattr, | 1007 | .getxattr = generic_getxattr, |
954 | .listxattr = ovl_listxattr, | 1008 | .listxattr = ovl_listxattr, |
955 | .removexattr = ovl_removexattr, | 1009 | .removexattr = generic_removexattr, |
956 | .get_acl = ovl_get_acl, | 1010 | .get_acl = ovl_get_acl, |
957 | .update_time = ovl_update_time, | 1011 | .update_time = ovl_update_time, |
958 | }; | 1012 | }; |
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 1b885c156028..c75625c1efa3 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/fs.h> | 10 | #include <linux/fs.h> |
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/xattr.h> | 12 | #include <linux/xattr.h> |
13 | #include <linux/posix_acl.h> | ||
13 | #include "overlayfs.h" | 14 | #include "overlayfs.h" |
14 | 15 | ||
15 | static int ovl_copy_up_truncate(struct dentry *dentry) | 16 | static int ovl_copy_up_truncate(struct dentry *dentry) |
@@ -191,32 +192,44 @@ static int ovl_readlink(struct dentry *dentry, char __user *buf, int bufsiz) | |||
191 | return err; | 192 | return err; |
192 | } | 193 | } |
193 | 194 | ||
194 | static bool ovl_is_private_xattr(const char *name) | 195 | bool ovl_is_private_xattr(const char *name) |
195 | { | 196 | { |
196 | #define OVL_XATTR_PRE_NAME OVL_XATTR_PREFIX "." | 197 | return strncmp(name, OVL_XATTR_PREFIX, |
197 | return strncmp(name, OVL_XATTR_PRE_NAME, | 198 | sizeof(OVL_XATTR_PREFIX) - 1) == 0; |
198 | sizeof(OVL_XATTR_PRE_NAME) - 1) == 0; | ||
199 | } | 199 | } |
200 | 200 | ||
201 | int ovl_setxattr(struct dentry *dentry, struct inode *inode, | 201 | int ovl_xattr_set(struct dentry *dentry, const char *name, const void *value, |
202 | const char *name, const void *value, | 202 | size_t size, int flags) |
203 | size_t size, int flags) | ||
204 | { | 203 | { |
205 | int err; | 204 | int err; |
206 | struct dentry *upperdentry; | 205 | struct path realpath; |
206 | enum ovl_path_type type = ovl_path_real(dentry, &realpath); | ||
207 | const struct cred *old_cred; | 207 | const struct cred *old_cred; |
208 | 208 | ||
209 | err = ovl_want_write(dentry); | 209 | err = ovl_want_write(dentry); |
210 | if (err) | 210 | if (err) |
211 | goto out; | 211 | goto out; |
212 | 212 | ||
213 | if (!value && !OVL_TYPE_UPPER(type)) { | ||
214 | err = vfs_getxattr(realpath.dentry, name, NULL, 0); | ||
215 | if (err < 0) | ||
216 | goto out_drop_write; | ||
217 | } | ||
218 | |||
213 | err = ovl_copy_up(dentry); | 219 | err = ovl_copy_up(dentry); |
214 | if (err) | 220 | if (err) |
215 | goto out_drop_write; | 221 | goto out_drop_write; |
216 | 222 | ||
217 | upperdentry = ovl_dentry_upper(dentry); | 223 | if (!OVL_TYPE_UPPER(type)) |
224 | ovl_path_upper(dentry, &realpath); | ||
225 | |||
218 | old_cred = ovl_override_creds(dentry->d_sb); | 226 | old_cred = ovl_override_creds(dentry->d_sb); |
219 | err = vfs_setxattr(upperdentry, name, value, size, flags); | 227 | if (value) |
228 | err = vfs_setxattr(realpath.dentry, name, value, size, flags); | ||
229 | else { | ||
230 | WARN_ON(flags != XATTR_REPLACE); | ||
231 | err = vfs_removexattr(realpath.dentry, name); | ||
232 | } | ||
220 | revert_creds(old_cred); | 233 | revert_creds(old_cred); |
221 | 234 | ||
222 | out_drop_write: | 235 | out_drop_write: |
@@ -225,16 +238,13 @@ out: | |||
225 | return err; | 238 | return err; |
226 | } | 239 | } |
227 | 240 | ||
228 | ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode, | 241 | int ovl_xattr_get(struct dentry *dentry, const char *name, |
229 | const char *name, void *value, size_t size) | 242 | void *value, size_t size) |
230 | { | 243 | { |
231 | struct dentry *realdentry = ovl_dentry_real(dentry); | 244 | struct dentry *realdentry = ovl_dentry_real(dentry); |
232 | ssize_t res; | 245 | ssize_t res; |
233 | const struct cred *old_cred; | 246 | const struct cred *old_cred; |
234 | 247 | ||
235 | if (ovl_is_private_xattr(name)) | ||
236 | return -ENODATA; | ||
237 | |||
238 | old_cred = ovl_override_creds(dentry->d_sb); | 248 | old_cred = ovl_override_creds(dentry->d_sb); |
239 | res = vfs_getxattr(realdentry, name, value, size); | 249 | res = vfs_getxattr(realdentry, name, value, size); |
240 | revert_creds(old_cred); | 250 | revert_creds(old_cred); |
@@ -245,7 +255,8 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) | |||
245 | { | 255 | { |
246 | struct dentry *realdentry = ovl_dentry_real(dentry); | 256 | struct dentry *realdentry = ovl_dentry_real(dentry); |
247 | ssize_t res; | 257 | ssize_t res; |
248 | int off; | 258 | size_t len; |
259 | char *s; | ||
249 | const struct cred *old_cred; | 260 | const struct cred *old_cred; |
250 | 261 | ||
251 | old_cred = ovl_override_creds(dentry->d_sb); | 262 | old_cred = ovl_override_creds(dentry->d_sb); |
@@ -255,73 +266,39 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) | |||
255 | return res; | 266 | return res; |
256 | 267 | ||
257 | /* filter out private xattrs */ | 268 | /* filter out private xattrs */ |
258 | for (off = 0; off < res;) { | 269 | for (s = list, len = res; len;) { |
259 | char *s = list + off; | 270 | size_t slen = strnlen(s, len) + 1; |
260 | size_t slen = strlen(s) + 1; | ||
261 | 271 | ||
262 | BUG_ON(off + slen > res); | 272 | /* underlying fs providing us with an broken xattr list? */ |
273 | if (WARN_ON(slen > len)) | ||
274 | return -EIO; | ||
263 | 275 | ||
276 | len -= slen; | ||
264 | if (ovl_is_private_xattr(s)) { | 277 | if (ovl_is_private_xattr(s)) { |
265 | res -= slen; | 278 | res -= slen; |
266 | memmove(s, s + slen, res - off); | 279 | memmove(s, s + slen, len); |
267 | } else { | 280 | } else { |
268 | off += slen; | 281 | s += slen; |
269 | } | 282 | } |
270 | } | 283 | } |
271 | 284 | ||
272 | return res; | 285 | return res; |
273 | } | 286 | } |
274 | 287 | ||
275 | int ovl_removexattr(struct dentry *dentry, const char *name) | ||
276 | { | ||
277 | int err; | ||
278 | struct path realpath; | ||
279 | enum ovl_path_type type = ovl_path_real(dentry, &realpath); | ||
280 | const struct cred *old_cred; | ||
281 | |||
282 | err = ovl_want_write(dentry); | ||
283 | if (err) | ||
284 | goto out; | ||
285 | |||
286 | err = -ENODATA; | ||
287 | if (ovl_is_private_xattr(name)) | ||
288 | goto out_drop_write; | ||
289 | |||
290 | if (!OVL_TYPE_UPPER(type)) { | ||
291 | err = vfs_getxattr(realpath.dentry, name, NULL, 0); | ||
292 | if (err < 0) | ||
293 | goto out_drop_write; | ||
294 | |||
295 | err = ovl_copy_up(dentry); | ||
296 | if (err) | ||
297 | goto out_drop_write; | ||
298 | |||
299 | ovl_path_upper(dentry, &realpath); | ||
300 | } | ||
301 | |||
302 | old_cred = ovl_override_creds(dentry->d_sb); | ||
303 | err = vfs_removexattr(realpath.dentry, name); | ||
304 | revert_creds(old_cred); | ||
305 | out_drop_write: | ||
306 | ovl_drop_write(dentry); | ||
307 | out: | ||
308 | return err; | ||
309 | } | ||
310 | |||
311 | struct posix_acl *ovl_get_acl(struct inode *inode, int type) | 288 | struct posix_acl *ovl_get_acl(struct inode *inode, int type) |
312 | { | 289 | { |
313 | struct inode *realinode = ovl_inode_real(inode, NULL); | 290 | struct inode *realinode = ovl_inode_real(inode, NULL); |
314 | const struct cred *old_cred; | 291 | const struct cred *old_cred; |
315 | struct posix_acl *acl; | 292 | struct posix_acl *acl; |
316 | 293 | ||
317 | if (!IS_POSIXACL(realinode)) | 294 | if (!IS_ENABLED(CONFIG_FS_POSIX_ACL) || !IS_POSIXACL(realinode)) |
318 | return NULL; | 295 | return NULL; |
319 | 296 | ||
320 | if (!realinode->i_op->get_acl) | 297 | if (!realinode->i_op->get_acl) |
321 | return NULL; | 298 | return NULL; |
322 | 299 | ||
323 | old_cred = ovl_override_creds(inode->i_sb); | 300 | old_cred = ovl_override_creds(inode->i_sb); |
324 | acl = realinode->i_op->get_acl(realinode, type); | 301 | acl = get_acl(realinode, type); |
325 | revert_creds(old_cred); | 302 | revert_creds(old_cred); |
326 | 303 | ||
327 | return acl; | 304 | return acl; |
@@ -391,9 +368,9 @@ static const struct inode_operations ovl_file_inode_operations = { | |||
391 | .permission = ovl_permission, | 368 | .permission = ovl_permission, |
392 | .getattr = ovl_getattr, | 369 | .getattr = ovl_getattr, |
393 | .setxattr = generic_setxattr, | 370 | .setxattr = generic_setxattr, |
394 | .getxattr = ovl_getxattr, | 371 | .getxattr = generic_getxattr, |
395 | .listxattr = ovl_listxattr, | 372 | .listxattr = ovl_listxattr, |
396 | .removexattr = ovl_removexattr, | 373 | .removexattr = generic_removexattr, |
397 | .get_acl = ovl_get_acl, | 374 | .get_acl = ovl_get_acl, |
398 | .update_time = ovl_update_time, | 375 | .update_time = ovl_update_time, |
399 | }; | 376 | }; |
@@ -404,9 +381,9 @@ static const struct inode_operations ovl_symlink_inode_operations = { | |||
404 | .readlink = ovl_readlink, | 381 | .readlink = ovl_readlink, |
405 | .getattr = ovl_getattr, | 382 | .getattr = ovl_getattr, |
406 | .setxattr = generic_setxattr, | 383 | .setxattr = generic_setxattr, |
407 | .getxattr = ovl_getxattr, | 384 | .getxattr = generic_getxattr, |
408 | .listxattr = ovl_listxattr, | 385 | .listxattr = ovl_listxattr, |
409 | .removexattr = ovl_removexattr, | 386 | .removexattr = generic_removexattr, |
410 | .update_time = ovl_update_time, | 387 | .update_time = ovl_update_time, |
411 | }; | 388 | }; |
412 | 389 | ||
@@ -415,6 +392,9 @@ static void ovl_fill_inode(struct inode *inode, umode_t mode) | |||
415 | inode->i_ino = get_next_ino(); | 392 | inode->i_ino = get_next_ino(); |
416 | inode->i_mode = mode; | 393 | inode->i_mode = mode; |
417 | inode->i_flags |= S_NOCMTIME; | 394 | inode->i_flags |= S_NOCMTIME; |
395 | #ifdef CONFIG_FS_POSIX_ACL | ||
396 | inode->i_acl = inode->i_default_acl = ACL_DONT_CACHE; | ||
397 | #endif | ||
418 | 398 | ||
419 | mode &= S_IFMT; | 399 | mode &= S_IFMT; |
420 | switch (mode) { | 400 | switch (mode) { |
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index e4f5c9536bfe..5813ccff8cd9 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h | |||
@@ -24,8 +24,8 @@ enum ovl_path_type { | |||
24 | (OVL_TYPE_MERGE(type) || !OVL_TYPE_UPPER(type)) | 24 | (OVL_TYPE_MERGE(type) || !OVL_TYPE_UPPER(type)) |
25 | 25 | ||
26 | 26 | ||
27 | #define OVL_XATTR_PREFIX XATTR_TRUSTED_PREFIX "overlay" | 27 | #define OVL_XATTR_PREFIX XATTR_TRUSTED_PREFIX "overlay." |
28 | #define OVL_XATTR_OPAQUE OVL_XATTR_PREFIX ".opaque" | 28 | #define OVL_XATTR_OPAQUE OVL_XATTR_PREFIX "opaque" |
29 | 29 | ||
30 | #define OVL_ISUPPER_MASK 1UL | 30 | #define OVL_ISUPPER_MASK 1UL |
31 | 31 | ||
@@ -179,20 +179,21 @@ int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list); | |||
179 | void ovl_cleanup_whiteouts(struct dentry *upper, struct list_head *list); | 179 | void ovl_cleanup_whiteouts(struct dentry *upper, struct list_head *list); |
180 | void ovl_cache_free(struct list_head *list); | 180 | void ovl_cache_free(struct list_head *list); |
181 | int ovl_check_d_type_supported(struct path *realpath); | 181 | int ovl_check_d_type_supported(struct path *realpath); |
182 | void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt, | ||
183 | struct dentry *dentry, int level); | ||
182 | 184 | ||
183 | /* inode.c */ | 185 | /* inode.c */ |
184 | int ovl_setattr(struct dentry *dentry, struct iattr *attr); | 186 | int ovl_setattr(struct dentry *dentry, struct iattr *attr); |
185 | int ovl_permission(struct inode *inode, int mask); | 187 | int ovl_permission(struct inode *inode, int mask); |
186 | int ovl_setxattr(struct dentry *dentry, struct inode *inode, | 188 | int ovl_xattr_set(struct dentry *dentry, const char *name, const void *value, |
187 | const char *name, const void *value, | 189 | size_t size, int flags); |
188 | size_t size, int flags); | 190 | int ovl_xattr_get(struct dentry *dentry, const char *name, |
189 | ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode, | 191 | void *value, size_t size); |
190 | const char *name, void *value, size_t size); | ||
191 | ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); | 192 | ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); |
192 | int ovl_removexattr(struct dentry *dentry, const char *name); | ||
193 | struct posix_acl *ovl_get_acl(struct inode *inode, int type); | 193 | struct posix_acl *ovl_get_acl(struct inode *inode, int type); |
194 | int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags); | 194 | int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags); |
195 | int ovl_update_time(struct inode *inode, struct timespec *ts, int flags); | 195 | int ovl_update_time(struct inode *inode, struct timespec *ts, int flags); |
196 | bool ovl_is_private_xattr(const char *name); | ||
196 | 197 | ||
197 | struct inode *ovl_new_inode(struct super_block *sb, umode_t mode); | 198 | struct inode *ovl_new_inode(struct super_block *sb, umode_t mode); |
198 | struct inode *ovl_get_inode(struct super_block *sb, struct inode *realinode); | 199 | struct inode *ovl_get_inode(struct super_block *sb, struct inode *realinode); |
diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index cf37fc76fc9f..f241b4ee3d8a 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c | |||
@@ -248,7 +248,7 @@ static inline int ovl_dir_read(struct path *realpath, | |||
248 | err = rdd->err; | 248 | err = rdd->err; |
249 | } while (!err && rdd->count); | 249 | } while (!err && rdd->count); |
250 | 250 | ||
251 | if (!err && rdd->first_maybe_whiteout) | 251 | if (!err && rdd->first_maybe_whiteout && rdd->dentry) |
252 | err = ovl_check_whiteouts(realpath->dentry, rdd); | 252 | err = ovl_check_whiteouts(realpath->dentry, rdd); |
253 | 253 | ||
254 | fput(realfile); | 254 | fput(realfile); |
@@ -606,3 +606,64 @@ int ovl_check_d_type_supported(struct path *realpath) | |||
606 | 606 | ||
607 | return rdd.d_type_supported; | 607 | return rdd.d_type_supported; |
608 | } | 608 | } |
609 | |||
610 | static void ovl_workdir_cleanup_recurse(struct path *path, int level) | ||
611 | { | ||
612 | int err; | ||
613 | struct inode *dir = path->dentry->d_inode; | ||
614 | LIST_HEAD(list); | ||
615 | struct ovl_cache_entry *p; | ||
616 | struct ovl_readdir_data rdd = { | ||
617 | .ctx.actor = ovl_fill_merge, | ||
618 | .dentry = NULL, | ||
619 | .list = &list, | ||
620 | .root = RB_ROOT, | ||
621 | .is_lowest = false, | ||
622 | }; | ||
623 | |||
624 | err = ovl_dir_read(path, &rdd); | ||
625 | if (err) | ||
626 | goto out; | ||
627 | |||
628 | inode_lock_nested(dir, I_MUTEX_PARENT); | ||
629 | list_for_each_entry(p, &list, l_node) { | ||
630 | struct dentry *dentry; | ||
631 | |||
632 | if (p->name[0] == '.') { | ||
633 | if (p->len == 1) | ||
634 | continue; | ||
635 | if (p->len == 2 && p->name[1] == '.') | ||
636 | continue; | ||
637 | } | ||
638 | dentry = lookup_one_len(p->name, path->dentry, p->len); | ||
639 | if (IS_ERR(dentry)) | ||
640 | continue; | ||
641 | if (dentry->d_inode) | ||
642 | ovl_workdir_cleanup(dir, path->mnt, dentry, level); | ||
643 | dput(dentry); | ||
644 | } | ||
645 | inode_unlock(dir); | ||
646 | out: | ||
647 | ovl_cache_free(&list); | ||
648 | } | ||
649 | |||
650 | void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt, | ||
651 | struct dentry *dentry, int level) | ||
652 | { | ||
653 | int err; | ||
654 | |||
655 | if (!d_is_dir(dentry) || level > 1) { | ||
656 | ovl_cleanup(dir, dentry); | ||
657 | return; | ||
658 | } | ||
659 | |||
660 | err = ovl_do_rmdir(dir, dentry); | ||
661 | if (err) { | ||
662 | struct path path = { .mnt = mnt, .dentry = dentry }; | ||
663 | |||
664 | inode_unlock(dir); | ||
665 | ovl_workdir_cleanup_recurse(&path, level + 1); | ||
666 | inode_lock_nested(dir, I_MUTEX_PARENT); | ||
667 | ovl_cleanup(dir, dentry); | ||
668 | } | ||
669 | } | ||
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 4036132842b5..e2a94a26767b 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c | |||
@@ -814,6 +814,10 @@ retry: | |||
814 | struct kstat stat = { | 814 | struct kstat stat = { |
815 | .mode = S_IFDIR | 0, | 815 | .mode = S_IFDIR | 0, |
816 | }; | 816 | }; |
817 | struct iattr attr = { | ||
818 | .ia_valid = ATTR_MODE, | ||
819 | .ia_mode = stat.mode, | ||
820 | }; | ||
817 | 821 | ||
818 | if (work->d_inode) { | 822 | if (work->d_inode) { |
819 | err = -EEXIST; | 823 | err = -EEXIST; |
@@ -821,7 +825,7 @@ retry: | |||
821 | goto out_dput; | 825 | goto out_dput; |
822 | 826 | ||
823 | retried = true; | 827 | retried = true; |
824 | ovl_cleanup(dir, work); | 828 | ovl_workdir_cleanup(dir, mnt, work, 0); |
825 | dput(work); | 829 | dput(work); |
826 | goto retry; | 830 | goto retry; |
827 | } | 831 | } |
@@ -829,6 +833,21 @@ retry: | |||
829 | err = ovl_create_real(dir, work, &stat, NULL, NULL, true); | 833 | err = ovl_create_real(dir, work, &stat, NULL, NULL, true); |
830 | if (err) | 834 | if (err) |
831 | goto out_dput; | 835 | goto out_dput; |
836 | |||
837 | err = vfs_removexattr(work, XATTR_NAME_POSIX_ACL_DEFAULT); | ||
838 | if (err && err != -ENODATA && err != -EOPNOTSUPP) | ||
839 | goto out_dput; | ||
840 | |||
841 | err = vfs_removexattr(work, XATTR_NAME_POSIX_ACL_ACCESS); | ||
842 | if (err && err != -ENODATA && err != -EOPNOTSUPP) | ||
843 | goto out_dput; | ||
844 | |||
845 | /* Clear any inherited mode bits */ | ||
846 | inode_lock(work->d_inode); | ||
847 | err = notify_change(work, &attr, NULL); | ||
848 | inode_unlock(work->d_inode); | ||
849 | if (err) | ||
850 | goto out_dput; | ||
832 | } | 851 | } |
833 | out_unlock: | 852 | out_unlock: |
834 | inode_unlock(dir); | 853 | inode_unlock(dir); |
@@ -967,10 +986,19 @@ static unsigned int ovl_split_lowerdirs(char *str) | |||
967 | return ctr; | 986 | return ctr; |
968 | } | 987 | } |
969 | 988 | ||
970 | static int ovl_posix_acl_xattr_set(const struct xattr_handler *handler, | 989 | static int __maybe_unused |
971 | struct dentry *dentry, struct inode *inode, | 990 | ovl_posix_acl_xattr_get(const struct xattr_handler *handler, |
972 | const char *name, const void *value, | 991 | struct dentry *dentry, struct inode *inode, |
973 | size_t size, int flags) | 992 | const char *name, void *buffer, size_t size) |
993 | { | ||
994 | return ovl_xattr_get(dentry, handler->name, buffer, size); | ||
995 | } | ||
996 | |||
997 | static int __maybe_unused | ||
998 | ovl_posix_acl_xattr_set(const struct xattr_handler *handler, | ||
999 | struct dentry *dentry, struct inode *inode, | ||
1000 | const char *name, const void *value, | ||
1001 | size_t size, int flags) | ||
974 | { | 1002 | { |
975 | struct dentry *workdir = ovl_workdir(dentry); | 1003 | struct dentry *workdir = ovl_workdir(dentry); |
976 | struct inode *realinode = ovl_inode_real(inode, NULL); | 1004 | struct inode *realinode = ovl_inode_real(inode, NULL); |
@@ -998,19 +1026,22 @@ static int ovl_posix_acl_xattr_set(const struct xattr_handler *handler, | |||
998 | 1026 | ||
999 | posix_acl_release(acl); | 1027 | posix_acl_release(acl); |
1000 | 1028 | ||
1001 | return ovl_setxattr(dentry, inode, handler->name, value, size, flags); | 1029 | err = ovl_xattr_set(dentry, handler->name, value, size, flags); |
1030 | if (!err) | ||
1031 | ovl_copyattr(ovl_inode_real(inode, NULL), inode); | ||
1032 | |||
1033 | return err; | ||
1002 | 1034 | ||
1003 | out_acl_release: | 1035 | out_acl_release: |
1004 | posix_acl_release(acl); | 1036 | posix_acl_release(acl); |
1005 | return err; | 1037 | return err; |
1006 | } | 1038 | } |
1007 | 1039 | ||
1008 | static int ovl_other_xattr_set(const struct xattr_handler *handler, | 1040 | static int ovl_own_xattr_get(const struct xattr_handler *handler, |
1009 | struct dentry *dentry, struct inode *inode, | 1041 | struct dentry *dentry, struct inode *inode, |
1010 | const char *name, const void *value, | 1042 | const char *name, void *buffer, size_t size) |
1011 | size_t size, int flags) | ||
1012 | { | 1043 | { |
1013 | return ovl_setxattr(dentry, inode, name, value, size, flags); | 1044 | return -EPERM; |
1014 | } | 1045 | } |
1015 | 1046 | ||
1016 | static int ovl_own_xattr_set(const struct xattr_handler *handler, | 1047 | static int ovl_own_xattr_set(const struct xattr_handler *handler, |
@@ -1021,42 +1052,59 @@ static int ovl_own_xattr_set(const struct xattr_handler *handler, | |||
1021 | return -EPERM; | 1052 | return -EPERM; |
1022 | } | 1053 | } |
1023 | 1054 | ||
1024 | static const struct xattr_handler ovl_posix_acl_access_xattr_handler = { | 1055 | static int ovl_other_xattr_get(const struct xattr_handler *handler, |
1056 | struct dentry *dentry, struct inode *inode, | ||
1057 | const char *name, void *buffer, size_t size) | ||
1058 | { | ||
1059 | return ovl_xattr_get(dentry, name, buffer, size); | ||
1060 | } | ||
1061 | |||
1062 | static int ovl_other_xattr_set(const struct xattr_handler *handler, | ||
1063 | struct dentry *dentry, struct inode *inode, | ||
1064 | const char *name, const void *value, | ||
1065 | size_t size, int flags) | ||
1066 | { | ||
1067 | return ovl_xattr_set(dentry, name, value, size, flags); | ||
1068 | } | ||
1069 | |||
1070 | static const struct xattr_handler __maybe_unused | ||
1071 | ovl_posix_acl_access_xattr_handler = { | ||
1025 | .name = XATTR_NAME_POSIX_ACL_ACCESS, | 1072 | .name = XATTR_NAME_POSIX_ACL_ACCESS, |
1026 | .flags = ACL_TYPE_ACCESS, | 1073 | .flags = ACL_TYPE_ACCESS, |
1074 | .get = ovl_posix_acl_xattr_get, | ||
1027 | .set = ovl_posix_acl_xattr_set, | 1075 | .set = ovl_posix_acl_xattr_set, |
1028 | }; | 1076 | }; |
1029 | 1077 | ||
1030 | static const struct xattr_handler ovl_posix_acl_default_xattr_handler = { | 1078 | static const struct xattr_handler __maybe_unused |
1079 | ovl_posix_acl_default_xattr_handler = { | ||
1031 | .name = XATTR_NAME_POSIX_ACL_DEFAULT, | 1080 | .name = XATTR_NAME_POSIX_ACL_DEFAULT, |
1032 | .flags = ACL_TYPE_DEFAULT, | 1081 | .flags = ACL_TYPE_DEFAULT, |
1082 | .get = ovl_posix_acl_xattr_get, | ||
1033 | .set = ovl_posix_acl_xattr_set, | 1083 | .set = ovl_posix_acl_xattr_set, |
1034 | }; | 1084 | }; |
1035 | 1085 | ||
1036 | static const struct xattr_handler ovl_own_xattr_handler = { | 1086 | static const struct xattr_handler ovl_own_xattr_handler = { |
1037 | .prefix = OVL_XATTR_PREFIX, | 1087 | .prefix = OVL_XATTR_PREFIX, |
1088 | .get = ovl_own_xattr_get, | ||
1038 | .set = ovl_own_xattr_set, | 1089 | .set = ovl_own_xattr_set, |
1039 | }; | 1090 | }; |
1040 | 1091 | ||
1041 | static const struct xattr_handler ovl_other_xattr_handler = { | 1092 | static const struct xattr_handler ovl_other_xattr_handler = { |
1042 | .prefix = "", /* catch all */ | 1093 | .prefix = "", /* catch all */ |
1094 | .get = ovl_other_xattr_get, | ||
1043 | .set = ovl_other_xattr_set, | 1095 | .set = ovl_other_xattr_set, |
1044 | }; | 1096 | }; |
1045 | 1097 | ||
1046 | static const struct xattr_handler *ovl_xattr_handlers[] = { | 1098 | static const struct xattr_handler *ovl_xattr_handlers[] = { |
1099 | #ifdef CONFIG_FS_POSIX_ACL | ||
1047 | &ovl_posix_acl_access_xattr_handler, | 1100 | &ovl_posix_acl_access_xattr_handler, |
1048 | &ovl_posix_acl_default_xattr_handler, | 1101 | &ovl_posix_acl_default_xattr_handler, |
1102 | #endif | ||
1049 | &ovl_own_xattr_handler, | 1103 | &ovl_own_xattr_handler, |
1050 | &ovl_other_xattr_handler, | 1104 | &ovl_other_xattr_handler, |
1051 | NULL | 1105 | NULL |
1052 | }; | 1106 | }; |
1053 | 1107 | ||
1054 | static const struct xattr_handler *ovl_xattr_noacl_handlers[] = { | ||
1055 | &ovl_own_xattr_handler, | ||
1056 | &ovl_other_xattr_handler, | ||
1057 | NULL, | ||
1058 | }; | ||
1059 | |||
1060 | static int ovl_fill_super(struct super_block *sb, void *data, int silent) | 1108 | static int ovl_fill_super(struct super_block *sb, void *data, int silent) |
1061 | { | 1109 | { |
1062 | struct path upperpath = { NULL, NULL }; | 1110 | struct path upperpath = { NULL, NULL }; |
@@ -1132,7 +1180,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) | |||
1132 | err = -EINVAL; | 1180 | err = -EINVAL; |
1133 | stacklen = ovl_split_lowerdirs(lowertmp); | 1181 | stacklen = ovl_split_lowerdirs(lowertmp); |
1134 | if (stacklen > OVL_MAX_STACK) { | 1182 | if (stacklen > OVL_MAX_STACK) { |
1135 | pr_err("overlayfs: too many lower directries, limit is %d\n", | 1183 | pr_err("overlayfs: too many lower directories, limit is %d\n", |
1136 | OVL_MAX_STACK); | 1184 | OVL_MAX_STACK); |
1137 | goto out_free_lowertmp; | 1185 | goto out_free_lowertmp; |
1138 | } else if (!ufs->config.upperdir && stacklen == 1) { | 1186 | } else if (!ufs->config.upperdir && stacklen == 1) { |
@@ -1269,10 +1317,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) | |||
1269 | 1317 | ||
1270 | sb->s_magic = OVERLAYFS_SUPER_MAGIC; | 1318 | sb->s_magic = OVERLAYFS_SUPER_MAGIC; |
1271 | sb->s_op = &ovl_super_operations; | 1319 | sb->s_op = &ovl_super_operations; |
1272 | if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) | 1320 | sb->s_xattr = ovl_xattr_handlers; |
1273 | sb->s_xattr = ovl_xattr_handlers; | ||
1274 | else | ||
1275 | sb->s_xattr = ovl_xattr_noacl_handlers; | ||
1276 | sb->s_root = root_dentry; | 1321 | sb->s_root = root_dentry; |
1277 | sb->s_fs_info = ufs; | 1322 | sb->s_fs_info = ufs; |
1278 | sb->s_flags |= MS_POSIXACL; | 1323 | sb->s_flags |= MS_POSIXACL; |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 54e270262979..ac0df4dde823 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1556,18 +1556,13 @@ static const struct file_operations proc_pid_set_comm_operations = { | |||
1556 | static int proc_exe_link(struct dentry *dentry, struct path *exe_path) | 1556 | static int proc_exe_link(struct dentry *dentry, struct path *exe_path) |
1557 | { | 1557 | { |
1558 | struct task_struct *task; | 1558 | struct task_struct *task; |
1559 | struct mm_struct *mm; | ||
1560 | struct file *exe_file; | 1559 | struct file *exe_file; |
1561 | 1560 | ||
1562 | task = get_proc_task(d_inode(dentry)); | 1561 | task = get_proc_task(d_inode(dentry)); |
1563 | if (!task) | 1562 | if (!task) |
1564 | return -ENOENT; | 1563 | return -ENOENT; |
1565 | mm = get_task_mm(task); | 1564 | exe_file = get_task_exe_file(task); |
1566 | put_task_struct(task); | 1565 | put_task_struct(task); |
1567 | if (!mm) | ||
1568 | return -ENOENT; | ||
1569 | exe_file = get_mm_exe_file(mm); | ||
1570 | mmput(mm); | ||
1571 | if (exe_file) { | 1566 | if (exe_file) { |
1572 | *exe_path = exe_file->f_path; | 1567 | *exe_path = exe_file->f_path; |
1573 | path_get(&exe_file->f_path); | 1568 | path_get(&exe_file->f_path); |
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index a939f5ed7f89..5c89a07e3d7f 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c | |||
@@ -430,6 +430,7 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) | |||
430 | static ssize_t | 430 | static ssize_t |
431 | read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) | 431 | read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) |
432 | { | 432 | { |
433 | char *buf = file->private_data; | ||
433 | ssize_t acc = 0; | 434 | ssize_t acc = 0; |
434 | size_t size, tsz; | 435 | size_t size, tsz; |
435 | size_t elf_buflen; | 436 | size_t elf_buflen; |
@@ -500,23 +501,20 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) | |||
500 | if (clear_user(buffer, tsz)) | 501 | if (clear_user(buffer, tsz)) |
501 | return -EFAULT; | 502 | return -EFAULT; |
502 | } else if (is_vmalloc_or_module_addr((void *)start)) { | 503 | } else if (is_vmalloc_or_module_addr((void *)start)) { |
503 | char * elf_buf; | 504 | vread(buf, (char *)start, tsz); |
504 | |||
505 | elf_buf = kzalloc(tsz, GFP_KERNEL); | ||
506 | if (!elf_buf) | ||
507 | return -ENOMEM; | ||
508 | vread(elf_buf, (char *)start, tsz); | ||
509 | /* we have to zero-fill user buffer even if no read */ | 505 | /* we have to zero-fill user buffer even if no read */ |
510 | if (copy_to_user(buffer, elf_buf, tsz)) { | 506 | if (copy_to_user(buffer, buf, tsz)) |
511 | kfree(elf_buf); | ||
512 | return -EFAULT; | 507 | return -EFAULT; |
513 | } | ||
514 | kfree(elf_buf); | ||
515 | } else { | 508 | } else { |
516 | if (kern_addr_valid(start)) { | 509 | if (kern_addr_valid(start)) { |
517 | unsigned long n; | 510 | unsigned long n; |
518 | 511 | ||
519 | n = copy_to_user(buffer, (char *)start, tsz); | 512 | /* |
513 | * Using bounce buffer to bypass the | ||
514 | * hardened user copy kernel text checks. | ||
515 | */ | ||
516 | memcpy(buf, (char *) start, tsz); | ||
517 | n = copy_to_user(buffer, buf, tsz); | ||
520 | /* | 518 | /* |
521 | * We cannot distinguish between fault on source | 519 | * We cannot distinguish between fault on source |
522 | * and fault on destination. When this happens | 520 | * and fault on destination. When this happens |
@@ -549,6 +547,11 @@ static int open_kcore(struct inode *inode, struct file *filp) | |||
549 | { | 547 | { |
550 | if (!capable(CAP_SYS_RAWIO)) | 548 | if (!capable(CAP_SYS_RAWIO)) |
551 | return -EPERM; | 549 | return -EPERM; |
550 | |||
551 | filp->private_data = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
552 | if (!filp->private_data) | ||
553 | return -ENOMEM; | ||
554 | |||
552 | if (kcore_need_update) | 555 | if (kcore_need_update) |
553 | kcore_update_ram(); | 556 | kcore_update_ram(); |
554 | if (i_size_read(inode) != proc_root_kcore->size) { | 557 | if (i_size_read(inode) != proc_root_kcore->size) { |
@@ -559,10 +562,16 @@ static int open_kcore(struct inode *inode, struct file *filp) | |||
559 | return 0; | 562 | return 0; |
560 | } | 563 | } |
561 | 564 | ||
565 | static int release_kcore(struct inode *inode, struct file *file) | ||
566 | { | ||
567 | kfree(file->private_data); | ||
568 | return 0; | ||
569 | } | ||
562 | 570 | ||
563 | static const struct file_operations proc_kcore_operations = { | 571 | static const struct file_operations proc_kcore_operations = { |
564 | .read = read_kcore, | 572 | .read = read_kcore, |
565 | .open = open_kcore, | 573 | .open = open_kcore, |
574 | .release = release_kcore, | ||
566 | .llseek = default_llseek, | 575 | .llseek = default_llseek, |
567 | }; | 576 | }; |
568 | 577 | ||
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 187d84ef9de9..f6fa99eca515 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -581,6 +581,8 @@ static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr, | |||
581 | mss->anonymous_thp += HPAGE_PMD_SIZE; | 581 | mss->anonymous_thp += HPAGE_PMD_SIZE; |
582 | else if (PageSwapBacked(page)) | 582 | else if (PageSwapBacked(page)) |
583 | mss->shmem_thp += HPAGE_PMD_SIZE; | 583 | mss->shmem_thp += HPAGE_PMD_SIZE; |
584 | else if (is_zone_device_page(page)) | ||
585 | /* pass */; | ||
584 | else | 586 | else |
585 | VM_BUG_ON_PAGE(1, page); | 587 | VM_BUG_ON_PAGE(1, page); |
586 | smaps_account(mss, page, true, pmd_young(*pmd), pmd_dirty(*pmd)); | 588 | smaps_account(mss, page, true, pmd_young(*pmd), pmd_dirty(*pmd)); |
diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c index 183a212694bf..12af0490322f 100644 --- a/fs/ramfs/file-mmu.c +++ b/fs/ramfs/file-mmu.c | |||
@@ -27,9 +27,17 @@ | |||
27 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
29 | #include <linux/ramfs.h> | 29 | #include <linux/ramfs.h> |
30 | #include <linux/sched.h> | ||
30 | 31 | ||
31 | #include "internal.h" | 32 | #include "internal.h" |
32 | 33 | ||
34 | static unsigned long ramfs_mmu_get_unmapped_area(struct file *file, | ||
35 | unsigned long addr, unsigned long len, unsigned long pgoff, | ||
36 | unsigned long flags) | ||
37 | { | ||
38 | return current->mm->get_unmapped_area(file, addr, len, pgoff, flags); | ||
39 | } | ||
40 | |||
33 | const struct file_operations ramfs_file_operations = { | 41 | const struct file_operations ramfs_file_operations = { |
34 | .read_iter = generic_file_read_iter, | 42 | .read_iter = generic_file_read_iter, |
35 | .write_iter = generic_file_write_iter, | 43 | .write_iter = generic_file_write_iter, |
@@ -38,6 +46,7 @@ const struct file_operations ramfs_file_operations = { | |||
38 | .splice_read = generic_file_splice_read, | 46 | .splice_read = generic_file_splice_read, |
39 | .splice_write = iter_file_splice_write, | 47 | .splice_write = iter_file_splice_write, |
40 | .llseek = generic_file_llseek, | 48 | .llseek = generic_file_llseek, |
49 | .get_unmapped_area = ramfs_mmu_get_unmapped_area, | ||
41 | }; | 50 | }; |
42 | 51 | ||
43 | const struct inode_operations ramfs_file_inode_operations = { | 52 | const struct inode_operations ramfs_file_inode_operations = { |
diff --git a/fs/seq_file.c b/fs/seq_file.c index 19f532e7d35e..6dc4296eed62 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
@@ -223,8 +223,10 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) | |||
223 | size -= n; | 223 | size -= n; |
224 | buf += n; | 224 | buf += n; |
225 | copied += n; | 225 | copied += n; |
226 | if (!m->count) | 226 | if (!m->count) { |
227 | m->from = 0; | ||
227 | m->index++; | 228 | m->index++; |
229 | } | ||
228 | if (!size) | 230 | if (!size) |
229 | goto Done; | 231 | goto Done; |
230 | } | 232 | } |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index f35523d4fa3a..b803213d1307 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -114,9 +114,15 @@ static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf, | |||
114 | * If buf != of->prealloc_buf, we don't know how | 114 | * If buf != of->prealloc_buf, we don't know how |
115 | * large it is, so cannot safely pass it to ->show | 115 | * large it is, so cannot safely pass it to ->show |
116 | */ | 116 | */ |
117 | if (pos || WARN_ON_ONCE(buf != of->prealloc_buf)) | 117 | if (WARN_ON_ONCE(buf != of->prealloc_buf)) |
118 | return 0; | 118 | return 0; |
119 | len = ops->show(kobj, of->kn->priv, buf); | 119 | len = ops->show(kobj, of->kn->priv, buf); |
120 | if (pos) { | ||
121 | if (len <= pos) | ||
122 | return 0; | ||
123 | len -= pos; | ||
124 | memmove(buf, buf + pos, len); | ||
125 | } | ||
120 | return min(count, len); | 126 | return min(count, len); |
121 | } | 127 | } |
122 | 128 | ||
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c index b45345d701e7..51157da3f76e 100644 --- a/fs/ubifs/tnc_commit.c +++ b/fs/ubifs/tnc_commit.c | |||
@@ -370,7 +370,7 @@ static int layout_in_gaps(struct ubifs_info *c, int cnt) | |||
370 | 370 | ||
371 | p = c->gap_lebs; | 371 | p = c->gap_lebs; |
372 | do { | 372 | do { |
373 | ubifs_assert(p < c->gap_lebs + sizeof(int) * c->lst.idx_lebs); | 373 | ubifs_assert(p < c->gap_lebs + c->lst.idx_lebs); |
374 | written = layout_leb_in_gaps(c, p); | 374 | written = layout_leb_in_gaps(c, p); |
375 | if (written < 0) { | 375 | if (written < 0) { |
376 | err = written; | 376 | err = written; |
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index e237811f09ce..11a004114eba 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c | |||
@@ -575,7 +575,8 @@ static int ubifs_xattr_get(const struct xattr_handler *handler, | |||
575 | dbg_gen("xattr '%s', ino %lu ('%pd'), buf size %zd", name, | 575 | dbg_gen("xattr '%s', ino %lu ('%pd'), buf size %zd", name, |
576 | inode->i_ino, dentry, size); | 576 | inode->i_ino, dentry, size); |
577 | 577 | ||
578 | return __ubifs_getxattr(inode, name, buffer, size); | 578 | name = xattr_full_name(handler, name); |
579 | return __ubifs_getxattr(inode, name, buffer, size); | ||
579 | } | 580 | } |
580 | 581 | ||
581 | static int ubifs_xattr_set(const struct xattr_handler *handler, | 582 | static int ubifs_xattr_set(const struct xattr_handler *handler, |
@@ -586,6 +587,8 @@ static int ubifs_xattr_set(const struct xattr_handler *handler, | |||
586 | dbg_gen("xattr '%s', host ino %lu ('%pd'), size %zd", | 587 | dbg_gen("xattr '%s', host ino %lu ('%pd'), size %zd", |
587 | name, inode->i_ino, dentry, size); | 588 | name, inode->i_ino, dentry, size); |
588 | 589 | ||
590 | name = xattr_full_name(handler, name); | ||
591 | |||
589 | if (value) | 592 | if (value) |
590 | return __ubifs_setxattr(inode, name, value, size, flags); | 593 | return __ubifs_setxattr(inode, name, value, size, flags); |
591 | else | 594 | else |
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 3dd8f1d54498..05b5243d89f6 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c | |||
@@ -2278,6 +2278,8 @@ xfs_alloc_log_agf( | |||
2278 | offsetof(xfs_agf_t, agf_btreeblks), | 2278 | offsetof(xfs_agf_t, agf_btreeblks), |
2279 | offsetof(xfs_agf_t, agf_uuid), | 2279 | offsetof(xfs_agf_t, agf_uuid), |
2280 | offsetof(xfs_agf_t, agf_rmap_blocks), | 2280 | offsetof(xfs_agf_t, agf_rmap_blocks), |
2281 | /* needed so that we don't log the whole rest of the structure: */ | ||
2282 | offsetof(xfs_agf_t, agf_spare64), | ||
2281 | sizeof(xfs_agf_t) | 2283 | sizeof(xfs_agf_t) |
2282 | }; | 2284 | }; |
2283 | 2285 | ||
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index b5c213a051cd..08569792fe20 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c | |||
@@ -1814,6 +1814,10 @@ xfs_btree_lookup( | |||
1814 | 1814 | ||
1815 | XFS_BTREE_STATS_INC(cur, lookup); | 1815 | XFS_BTREE_STATS_INC(cur, lookup); |
1816 | 1816 | ||
1817 | /* No such thing as a zero-level tree. */ | ||
1818 | if (cur->bc_nlevels == 0) | ||
1819 | return -EFSCORRUPTED; | ||
1820 | |||
1817 | block = NULL; | 1821 | block = NULL; |
1818 | keyno = 0; | 1822 | keyno = 0; |
1819 | 1823 | ||
@@ -4554,15 +4558,22 @@ xfs_btree_simple_query_range( | |||
4554 | if (error) | 4558 | if (error) |
4555 | goto out; | 4559 | goto out; |
4556 | 4560 | ||
4561 | /* Nothing? See if there's anything to the right. */ | ||
4562 | if (!stat) { | ||
4563 | error = xfs_btree_increment(cur, 0, &stat); | ||
4564 | if (error) | ||
4565 | goto out; | ||
4566 | } | ||
4567 | |||
4557 | while (stat) { | 4568 | while (stat) { |
4558 | /* Find the record. */ | 4569 | /* Find the record. */ |
4559 | error = xfs_btree_get_rec(cur, &recp, &stat); | 4570 | error = xfs_btree_get_rec(cur, &recp, &stat); |
4560 | if (error || !stat) | 4571 | if (error || !stat) |
4561 | break; | 4572 | break; |
4562 | cur->bc_ops->init_high_key_from_rec(&rec_key, recp); | ||
4563 | 4573 | ||
4564 | /* Skip if high_key(rec) < low_key. */ | 4574 | /* Skip if high_key(rec) < low_key. */ |
4565 | if (firstrec) { | 4575 | if (firstrec) { |
4576 | cur->bc_ops->init_high_key_from_rec(&rec_key, recp); | ||
4566 | firstrec = false; | 4577 | firstrec = false; |
4567 | diff = cur->bc_ops->diff_two_keys(cur, low_key, | 4578 | diff = cur->bc_ops->diff_two_keys(cur, low_key, |
4568 | &rec_key); | 4579 | &rec_key); |
@@ -4571,6 +4582,7 @@ xfs_btree_simple_query_range( | |||
4571 | } | 4582 | } |
4572 | 4583 | ||
4573 | /* Stop if high_key < low_key(rec). */ | 4584 | /* Stop if high_key < low_key(rec). */ |
4585 | cur->bc_ops->init_key_from_rec(&rec_key, recp); | ||
4574 | diff = cur->bc_ops->diff_two_keys(cur, &rec_key, high_key); | 4586 | diff = cur->bc_ops->diff_two_keys(cur, &rec_key, high_key); |
4575 | if (diff > 0) | 4587 | if (diff > 0) |
4576 | break; | 4588 | break; |
diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 054a2032fdb3..c221d0ecd52e 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c | |||
@@ -194,7 +194,7 @@ xfs_defer_trans_abort( | |||
194 | /* Abort intent items. */ | 194 | /* Abort intent items. */ |
195 | list_for_each_entry(dfp, &dop->dop_pending, dfp_list) { | 195 | list_for_each_entry(dfp, &dop->dop_pending, dfp_list) { |
196 | trace_xfs_defer_pending_abort(tp->t_mountp, dfp); | 196 | trace_xfs_defer_pending_abort(tp->t_mountp, dfp); |
197 | if (dfp->dfp_committed) | 197 | if (!dfp->dfp_done) |
198 | dfp->dfp_type->abort_intent(dfp->dfp_intent); | 198 | dfp->dfp_type->abort_intent(dfp->dfp_intent); |
199 | } | 199 | } |
200 | 200 | ||
@@ -290,7 +290,6 @@ xfs_defer_finish( | |||
290 | struct xfs_defer_pending *dfp; | 290 | struct xfs_defer_pending *dfp; |
291 | struct list_head *li; | 291 | struct list_head *li; |
292 | struct list_head *n; | 292 | struct list_head *n; |
293 | void *done_item = NULL; | ||
294 | void *state; | 293 | void *state; |
295 | int error = 0; | 294 | int error = 0; |
296 | void (*cleanup_fn)(struct xfs_trans *, void *, int); | 295 | void (*cleanup_fn)(struct xfs_trans *, void *, int); |
@@ -309,19 +308,11 @@ xfs_defer_finish( | |||
309 | if (error) | 308 | if (error) |
310 | goto out; | 309 | goto out; |
311 | 310 | ||
312 | /* Mark all pending intents as committed. */ | ||
313 | list_for_each_entry_reverse(dfp, &dop->dop_pending, dfp_list) { | ||
314 | if (dfp->dfp_committed) | ||
315 | break; | ||
316 | trace_xfs_defer_pending_commit((*tp)->t_mountp, dfp); | ||
317 | dfp->dfp_committed = true; | ||
318 | } | ||
319 | |||
320 | /* Log an intent-done item for the first pending item. */ | 311 | /* Log an intent-done item for the first pending item. */ |
321 | dfp = list_first_entry(&dop->dop_pending, | 312 | dfp = list_first_entry(&dop->dop_pending, |
322 | struct xfs_defer_pending, dfp_list); | 313 | struct xfs_defer_pending, dfp_list); |
323 | trace_xfs_defer_pending_finish((*tp)->t_mountp, dfp); | 314 | trace_xfs_defer_pending_finish((*tp)->t_mountp, dfp); |
324 | done_item = dfp->dfp_type->create_done(*tp, dfp->dfp_intent, | 315 | dfp->dfp_done = dfp->dfp_type->create_done(*tp, dfp->dfp_intent, |
325 | dfp->dfp_count); | 316 | dfp->dfp_count); |
326 | cleanup_fn = dfp->dfp_type->finish_cleanup; | 317 | cleanup_fn = dfp->dfp_type->finish_cleanup; |
327 | 318 | ||
@@ -331,7 +322,7 @@ xfs_defer_finish( | |||
331 | list_del(li); | 322 | list_del(li); |
332 | dfp->dfp_count--; | 323 | dfp->dfp_count--; |
333 | error = dfp->dfp_type->finish_item(*tp, dop, li, | 324 | error = dfp->dfp_type->finish_item(*tp, dop, li, |
334 | done_item, &state); | 325 | dfp->dfp_done, &state); |
335 | if (error) { | 326 | if (error) { |
336 | /* | 327 | /* |
337 | * Clean up after ourselves and jump out. | 328 | * Clean up after ourselves and jump out. |
@@ -428,8 +419,8 @@ xfs_defer_add( | |||
428 | dfp = kmem_alloc(sizeof(struct xfs_defer_pending), | 419 | dfp = kmem_alloc(sizeof(struct xfs_defer_pending), |
429 | KM_SLEEP | KM_NOFS); | 420 | KM_SLEEP | KM_NOFS); |
430 | dfp->dfp_type = defer_op_types[type]; | 421 | dfp->dfp_type = defer_op_types[type]; |
431 | dfp->dfp_committed = false; | ||
432 | dfp->dfp_intent = NULL; | 422 | dfp->dfp_intent = NULL; |
423 | dfp->dfp_done = NULL; | ||
433 | dfp->dfp_count = 0; | 424 | dfp->dfp_count = 0; |
434 | INIT_LIST_HEAD(&dfp->dfp_work); | 425 | INIT_LIST_HEAD(&dfp->dfp_work); |
435 | list_add_tail(&dfp->dfp_list, &dop->dop_intake); | 426 | list_add_tail(&dfp->dfp_list, &dop->dop_intake); |
diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index cc3981c48296..e96533d178cf 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h | |||
@@ -30,8 +30,8 @@ struct xfs_defer_op_type; | |||
30 | struct xfs_defer_pending { | 30 | struct xfs_defer_pending { |
31 | const struct xfs_defer_op_type *dfp_type; /* function pointers */ | 31 | const struct xfs_defer_op_type *dfp_type; /* function pointers */ |
32 | struct list_head dfp_list; /* pending items */ | 32 | struct list_head dfp_list; /* pending items */ |
33 | bool dfp_committed; /* committed trans? */ | ||
34 | void *dfp_intent; /* log intent item */ | 33 | void *dfp_intent; /* log intent item */ |
34 | void *dfp_done; /* log done item */ | ||
35 | struct list_head dfp_work; /* work items */ | 35 | struct list_head dfp_work; /* work items */ |
36 | unsigned int dfp_count; /* # extent items */ | 36 | unsigned int dfp_count; /* # extent items */ |
37 | }; | 37 | }; |
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index e6a8bea0f7ba..270fb5cf4fa1 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h | |||
@@ -674,7 +674,8 @@ typedef struct xfs_agf { | |||
674 | #define XFS_AGF_BTREEBLKS 0x00000800 | 674 | #define XFS_AGF_BTREEBLKS 0x00000800 |
675 | #define XFS_AGF_UUID 0x00001000 | 675 | #define XFS_AGF_UUID 0x00001000 |
676 | #define XFS_AGF_RMAP_BLOCKS 0x00002000 | 676 | #define XFS_AGF_RMAP_BLOCKS 0x00002000 |
677 | #define XFS_AGF_NUM_BITS 14 | 677 | #define XFS_AGF_SPARE64 0x00004000 |
678 | #define XFS_AGF_NUM_BITS 15 | ||
678 | #define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1) | 679 | #define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1) |
679 | 680 | ||
680 | #define XFS_AGF_FLAGS \ | 681 | #define XFS_AGF_FLAGS \ |
@@ -691,7 +692,8 @@ typedef struct xfs_agf { | |||
691 | { XFS_AGF_LONGEST, "LONGEST" }, \ | 692 | { XFS_AGF_LONGEST, "LONGEST" }, \ |
692 | { XFS_AGF_BTREEBLKS, "BTREEBLKS" }, \ | 693 | { XFS_AGF_BTREEBLKS, "BTREEBLKS" }, \ |
693 | { XFS_AGF_UUID, "UUID" }, \ | 694 | { XFS_AGF_UUID, "UUID" }, \ |
694 | { XFS_AGF_RMAP_BLOCKS, "RMAP_BLOCKS" } | 695 | { XFS_AGF_RMAP_BLOCKS, "RMAP_BLOCKS" }, \ |
696 | { XFS_AGF_SPARE64, "SPARE64" } | ||
695 | 697 | ||
696 | /* disk block (xfs_daddr_t) in the AG */ | 698 | /* disk block (xfs_daddr_t) in the AG */ |
697 | #define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log)) | 699 | #define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log)) |
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 0e3d4f5ec33c..4aecc5fefe96 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c | |||
@@ -583,7 +583,8 @@ xfs_sb_verify( | |||
583 | * Only check the in progress field for the primary superblock as | 583 | * Only check the in progress field for the primary superblock as |
584 | * mkfs.xfs doesn't clear it from secondary superblocks. | 584 | * mkfs.xfs doesn't clear it from secondary superblocks. |
585 | */ | 585 | */ |
586 | return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR, | 586 | return xfs_mount_validate_sb(mp, &sb, |
587 | bp->b_maps[0].bm_bn == XFS_SB_DADDR, | ||
587 | check_version); | 588 | check_version); |
588 | } | 589 | } |
589 | 590 | ||
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 607cc29bba21..b5b9bffe3520 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -1611,7 +1611,7 @@ xfs_wait_buftarg( | |||
1611 | */ | 1611 | */ |
1612 | while (percpu_counter_sum(&btp->bt_io_count)) | 1612 | while (percpu_counter_sum(&btp->bt_io_count)) |
1613 | delay(100); | 1613 | delay(100); |
1614 | drain_workqueue(btp->bt_mount->m_buf_workqueue); | 1614 | flush_workqueue(btp->bt_mount->m_buf_workqueue); |
1615 | 1615 | ||
1616 | /* loop until there is nothing left on the lru list. */ | 1616 | /* loop until there is nothing left on the lru list. */ |
1617 | while (list_lru_count(&btp->bt_lru)) { | 1617 | while (list_lru_count(&btp->bt_lru)) { |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 24ef83ef04de..fd6be45b3a1e 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -1574,9 +1574,16 @@ xfs_fs_fill_super( | |||
1574 | } | 1574 | } |
1575 | } | 1575 | } |
1576 | 1576 | ||
1577 | if (xfs_sb_version_hasrmapbt(&mp->m_sb)) | 1577 | if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { |
1578 | if (mp->m_sb.sb_rblocks) { | ||
1579 | xfs_alert(mp, | ||
1580 | "EXPERIMENTAL reverse mapping btree not compatible with realtime device!"); | ||
1581 | error = -EINVAL; | ||
1582 | goto out_filestream_unmount; | ||
1583 | } | ||
1578 | xfs_alert(mp, | 1584 | xfs_alert(mp, |
1579 | "EXPERIMENTAL reverse mapping btree feature enabled. Use at your own risk!"); | 1585 | "EXPERIMENTAL reverse mapping btree feature enabled. Use at your own risk!"); |
1586 | } | ||
1580 | 1587 | ||
1581 | error = xfs_mountfs(mp); | 1588 | error = xfs_mountfs(mp); |
1582 | if (error) | 1589 | if (error) |
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 7e88bec3f359..d303a665dba9 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h | |||
@@ -2295,7 +2295,7 @@ DECLARE_EVENT_CLASS(xfs_defer_pending_class, | |||
2295 | __entry->dev = mp ? mp->m_super->s_dev : 0; | 2295 | __entry->dev = mp ? mp->m_super->s_dev : 0; |
2296 | __entry->type = dfp->dfp_type->type; | 2296 | __entry->type = dfp->dfp_type->type; |
2297 | __entry->intent = dfp->dfp_intent; | 2297 | __entry->intent = dfp->dfp_intent; |
2298 | __entry->committed = dfp->dfp_committed; | 2298 | __entry->committed = dfp->dfp_done != NULL; |
2299 | __entry->nr = dfp->dfp_count; | 2299 | __entry->nr = dfp->dfp_count; |
2300 | ), | 2300 | ), |
2301 | TP_printk("dev %d:%d optype %d intent %p committed %d nr %d\n", | 2301 | TP_printk("dev %d:%d optype %d intent %p committed %d nr %d\n", |
diff --git a/include/asm-generic/uaccess.h b/include/asm-generic/uaccess.h index 1bfa602958f2..6df9b0749671 100644 --- a/include/asm-generic/uaccess.h +++ b/include/asm-generic/uaccess.h | |||
@@ -72,6 +72,7 @@ struct exception_table_entry | |||
72 | /* Returns 0 if exception not found and fixup otherwise. */ | 72 | /* Returns 0 if exception not found and fixup otherwise. */ |
73 | extern unsigned long search_exception_table(unsigned long); | 73 | extern unsigned long search_exception_table(unsigned long); |
74 | 74 | ||
75 | |||
75 | /* | 76 | /* |
76 | * architectures with an MMU should override these two | 77 | * architectures with an MMU should override these two |
77 | */ | 78 | */ |
@@ -230,14 +231,18 @@ extern int __put_user_bad(void) __attribute__((noreturn)); | |||
230 | might_fault(); \ | 231 | might_fault(); \ |
231 | access_ok(VERIFY_READ, __p, sizeof(*ptr)) ? \ | 232 | access_ok(VERIFY_READ, __p, sizeof(*ptr)) ? \ |
232 | __get_user((x), (__typeof__(*(ptr)) *)__p) : \ | 233 | __get_user((x), (__typeof__(*(ptr)) *)__p) : \ |
233 | -EFAULT; \ | 234 | ((x) = (__typeof__(*(ptr)))0,-EFAULT); \ |
234 | }) | 235 | }) |
235 | 236 | ||
236 | #ifndef __get_user_fn | 237 | #ifndef __get_user_fn |
237 | static inline int __get_user_fn(size_t size, const void __user *ptr, void *x) | 238 | static inline int __get_user_fn(size_t size, const void __user *ptr, void *x) |
238 | { | 239 | { |
239 | size = __copy_from_user(x, ptr, size); | 240 | size_t n = __copy_from_user(x, ptr, size); |
240 | return size ? -EFAULT : size; | 241 | if (unlikely(n)) { |
242 | memset(x + (size - n), 0, n); | ||
243 | return -EFAULT; | ||
244 | } | ||
245 | return 0; | ||
241 | } | 246 | } |
242 | 247 | ||
243 | #define __get_user_fn(sz, u, k) __get_user_fn(sz, u, k) | 248 | #define __get_user_fn(sz, u, k) __get_user_fn(sz, u, k) |
@@ -257,11 +262,13 @@ extern int __get_user_bad(void) __attribute__((noreturn)); | |||
257 | static inline long copy_from_user(void *to, | 262 | static inline long copy_from_user(void *to, |
258 | const void __user * from, unsigned long n) | 263 | const void __user * from, unsigned long n) |
259 | { | 264 | { |
265 | unsigned long res = n; | ||
260 | might_fault(); | 266 | might_fault(); |
261 | if (access_ok(VERIFY_READ, from, n)) | 267 | if (likely(access_ok(VERIFY_READ, from, n))) |
262 | return __copy_from_user(to, from, n); | 268 | res = __copy_from_user(to, from, n); |
263 | else | 269 | if (unlikely(res)) |
264 | return n; | 270 | memset(to + (n - res), 0, res); |
271 | return res; | ||
265 | } | 272 | } |
266 | 273 | ||
267 | static inline long copy_to_user(void __user *to, | 274 | static inline long copy_to_user(void __user *to, |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 4d8452c2384b..c5eaf2f80a4c 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -1056,7 +1056,7 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev, | |||
1056 | return NULL; | 1056 | return NULL; |
1057 | } | 1057 | } |
1058 | 1058 | ||
1059 | #define ACPI_DECLARE_PROBE_ENTRY(table, name, table_id, subtable, validate, data, fn) \ | 1059 | #define ACPI_DECLARE_PROBE_ENTRY(table, name, table_id, subtable, valid, data, fn) \ |
1060 | static const void * __acpi_table_##name[] \ | 1060 | static const void * __acpi_table_##name[] \ |
1061 | __attribute__((unused)) \ | 1061 | __attribute__((unused)) \ |
1062 | = { (void *) table_id, \ | 1062 | = { (void *) table_id, \ |
diff --git a/include/linux/bio.h b/include/linux/bio.h index 59ffaa68b11b..23ddf4b46a9b 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
@@ -71,7 +71,8 @@ static inline bool bio_has_data(struct bio *bio) | |||
71 | { | 71 | { |
72 | if (bio && | 72 | if (bio && |
73 | bio->bi_iter.bi_size && | 73 | bio->bi_iter.bi_size && |
74 | bio_op(bio) != REQ_OP_DISCARD) | 74 | bio_op(bio) != REQ_OP_DISCARD && |
75 | bio_op(bio) != REQ_OP_SECURE_ERASE) | ||
75 | return true; | 76 | return true; |
76 | 77 | ||
77 | return false; | 78 | return false; |
@@ -79,7 +80,9 @@ static inline bool bio_has_data(struct bio *bio) | |||
79 | 80 | ||
80 | static inline bool bio_no_advance_iter(struct bio *bio) | 81 | static inline bool bio_no_advance_iter(struct bio *bio) |
81 | { | 82 | { |
82 | return bio_op(bio) == REQ_OP_DISCARD || bio_op(bio) == REQ_OP_WRITE_SAME; | 83 | return bio_op(bio) == REQ_OP_DISCARD || |
84 | bio_op(bio) == REQ_OP_SECURE_ERASE || | ||
85 | bio_op(bio) == REQ_OP_WRITE_SAME; | ||
83 | } | 86 | } |
84 | 87 | ||
85 | static inline bool bio_is_rw(struct bio *bio) | 88 | static inline bool bio_is_rw(struct bio *bio) |
@@ -199,6 +202,9 @@ static inline unsigned bio_segments(struct bio *bio) | |||
199 | if (bio_op(bio) == REQ_OP_DISCARD) | 202 | if (bio_op(bio) == REQ_OP_DISCARD) |
200 | return 1; | 203 | return 1; |
201 | 204 | ||
205 | if (bio_op(bio) == REQ_OP_SECURE_ERASE) | ||
206 | return 1; | ||
207 | |||
202 | if (bio_op(bio) == REQ_OP_WRITE_SAME) | 208 | if (bio_op(bio) == REQ_OP_WRITE_SAME) |
203 | return 1; | 209 | return 1; |
204 | 210 | ||
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 2c210b6a7bcf..e79055c8b577 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -882,7 +882,7 @@ static inline unsigned int blk_rq_cur_sectors(const struct request *rq) | |||
882 | static inline unsigned int blk_queue_get_max_sectors(struct request_queue *q, | 882 | static inline unsigned int blk_queue_get_max_sectors(struct request_queue *q, |
883 | int op) | 883 | int op) |
884 | { | 884 | { |
885 | if (unlikely(op == REQ_OP_DISCARD)) | 885 | if (unlikely(op == REQ_OP_DISCARD || op == REQ_OP_SECURE_ERASE)) |
886 | return min(q->limits.max_discard_sectors, UINT_MAX >> 9); | 886 | return min(q->limits.max_discard_sectors, UINT_MAX >> 9); |
887 | 887 | ||
888 | if (unlikely(op == REQ_OP_WRITE_SAME)) | 888 | if (unlikely(op == REQ_OP_WRITE_SAME)) |
@@ -913,7 +913,9 @@ static inline unsigned int blk_rq_get_max_sectors(struct request *rq, | |||
913 | if (unlikely(rq->cmd_type != REQ_TYPE_FS)) | 913 | if (unlikely(rq->cmd_type != REQ_TYPE_FS)) |
914 | return q->limits.max_hw_sectors; | 914 | return q->limits.max_hw_sectors; |
915 | 915 | ||
916 | if (!q->limits.chunk_sectors || (req_op(rq) == REQ_OP_DISCARD)) | 916 | if (!q->limits.chunk_sectors || |
917 | req_op(rq) == REQ_OP_DISCARD || | ||
918 | req_op(rq) == REQ_OP_SECURE_ERASE) | ||
917 | return blk_queue_get_max_sectors(q, req_op(rq)); | 919 | return blk_queue_get_max_sectors(q, req_op(rq)); |
918 | 920 | ||
919 | return min(blk_max_size_offset(q, offset), | 921 | return min(blk_max_size_offset(q, offset), |
diff --git a/include/linux/cec-funcs.h b/include/linux/cec-funcs.h index 82c3d3b7269d..138bbf721e70 100644 --- a/include/linux/cec-funcs.h +++ b/include/linux/cec-funcs.h | |||
@@ -162,10 +162,11 @@ static inline void cec_msg_standby(struct cec_msg *msg) | |||
162 | 162 | ||
163 | 163 | ||
164 | /* One Touch Record Feature */ | 164 | /* One Touch Record Feature */ |
165 | static inline void cec_msg_record_off(struct cec_msg *msg) | 165 | static inline void cec_msg_record_off(struct cec_msg *msg, bool reply) |
166 | { | 166 | { |
167 | msg->len = 2; | 167 | msg->len = 2; |
168 | msg->msg[1] = CEC_MSG_RECORD_OFF; | 168 | msg->msg[1] = CEC_MSG_RECORD_OFF; |
169 | msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0; | ||
169 | } | 170 | } |
170 | 171 | ||
171 | struct cec_op_arib_data { | 172 | struct cec_op_arib_data { |
@@ -227,7 +228,7 @@ static inline void cec_set_digital_service_id(__u8 *msg, | |||
227 | if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) { | 228 | if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) { |
228 | *msg++ = (digital->channel.channel_number_fmt << 2) | | 229 | *msg++ = (digital->channel.channel_number_fmt << 2) | |
229 | (digital->channel.major >> 8); | 230 | (digital->channel.major >> 8); |
230 | *msg++ = digital->channel.major && 0xff; | 231 | *msg++ = digital->channel.major & 0xff; |
231 | *msg++ = digital->channel.minor >> 8; | 232 | *msg++ = digital->channel.minor >> 8; |
232 | *msg++ = digital->channel.minor & 0xff; | 233 | *msg++ = digital->channel.minor & 0xff; |
233 | *msg++ = 0; | 234 | *msg++ = 0; |
@@ -323,6 +324,7 @@ static inline void cec_msg_record_on_phys_addr(struct cec_msg *msg, | |||
323 | } | 324 | } |
324 | 325 | ||
325 | static inline void cec_msg_record_on(struct cec_msg *msg, | 326 | static inline void cec_msg_record_on(struct cec_msg *msg, |
327 | bool reply, | ||
326 | const struct cec_op_record_src *rec_src) | 328 | const struct cec_op_record_src *rec_src) |
327 | { | 329 | { |
328 | switch (rec_src->type) { | 330 | switch (rec_src->type) { |
@@ -346,6 +348,7 @@ static inline void cec_msg_record_on(struct cec_msg *msg, | |||
346 | rec_src->ext_phys_addr.phys_addr); | 348 | rec_src->ext_phys_addr.phys_addr); |
347 | break; | 349 | break; |
348 | } | 350 | } |
351 | msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0; | ||
349 | } | 352 | } |
350 | 353 | ||
351 | static inline void cec_ops_record_on(const struct cec_msg *msg, | 354 | static inline void cec_ops_record_on(const struct cec_msg *msg, |
@@ -1141,6 +1144,75 @@ static inline void cec_msg_give_device_vendor_id(struct cec_msg *msg, | |||
1141 | msg->reply = reply ? CEC_MSG_DEVICE_VENDOR_ID : 0; | 1144 | msg->reply = reply ? CEC_MSG_DEVICE_VENDOR_ID : 0; |
1142 | } | 1145 | } |
1143 | 1146 | ||
1147 | static inline void cec_msg_vendor_command(struct cec_msg *msg, | ||
1148 | __u8 size, const __u8 *vendor_cmd) | ||
1149 | { | ||
1150 | if (size > 14) | ||
1151 | size = 14; | ||
1152 | msg->len = 2 + size; | ||
1153 | msg->msg[1] = CEC_MSG_VENDOR_COMMAND; | ||
1154 | memcpy(msg->msg + 2, vendor_cmd, size); | ||
1155 | } | ||
1156 | |||
1157 | static inline void cec_ops_vendor_command(const struct cec_msg *msg, | ||
1158 | __u8 *size, | ||
1159 | const __u8 **vendor_cmd) | ||
1160 | { | ||
1161 | *size = msg->len - 2; | ||
1162 | |||
1163 | if (*size > 14) | ||
1164 | *size = 14; | ||
1165 | *vendor_cmd = msg->msg + 2; | ||
1166 | } | ||
1167 | |||
1168 | static inline void cec_msg_vendor_command_with_id(struct cec_msg *msg, | ||
1169 | __u32 vendor_id, __u8 size, | ||
1170 | const __u8 *vendor_cmd) | ||
1171 | { | ||
1172 | if (size > 11) | ||
1173 | size = 11; | ||
1174 | msg->len = 5 + size; | ||
1175 | msg->msg[1] = CEC_MSG_VENDOR_COMMAND_WITH_ID; | ||
1176 | msg->msg[2] = vendor_id >> 16; | ||
1177 | msg->msg[3] = (vendor_id >> 8) & 0xff; | ||
1178 | msg->msg[4] = vendor_id & 0xff; | ||
1179 | memcpy(msg->msg + 5, vendor_cmd, size); | ||
1180 | } | ||
1181 | |||
1182 | static inline void cec_ops_vendor_command_with_id(const struct cec_msg *msg, | ||
1183 | __u32 *vendor_id, __u8 *size, | ||
1184 | const __u8 **vendor_cmd) | ||
1185 | { | ||
1186 | *size = msg->len - 5; | ||
1187 | |||
1188 | if (*size > 11) | ||
1189 | *size = 11; | ||
1190 | *vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4]; | ||
1191 | *vendor_cmd = msg->msg + 5; | ||
1192 | } | ||
1193 | |||
1194 | static inline void cec_msg_vendor_remote_button_down(struct cec_msg *msg, | ||
1195 | __u8 size, | ||
1196 | const __u8 *rc_code) | ||
1197 | { | ||
1198 | if (size > 14) | ||
1199 | size = 14; | ||
1200 | msg->len = 2 + size; | ||
1201 | msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN; | ||
1202 | memcpy(msg->msg + 2, rc_code, size); | ||
1203 | } | ||
1204 | |||
1205 | static inline void cec_ops_vendor_remote_button_down(const struct cec_msg *msg, | ||
1206 | __u8 *size, | ||
1207 | const __u8 **rc_code) | ||
1208 | { | ||
1209 | *size = msg->len - 2; | ||
1210 | |||
1211 | if (*size > 14) | ||
1212 | *size = 14; | ||
1213 | *rc_code = msg->msg + 2; | ||
1214 | } | ||
1215 | |||
1144 | static inline void cec_msg_vendor_remote_button_up(struct cec_msg *msg) | 1216 | static inline void cec_msg_vendor_remote_button_up(struct cec_msg *msg) |
1145 | { | 1217 | { |
1146 | msg->len = 2; | 1218 | msg->len = 2; |
@@ -1277,7 +1349,7 @@ static inline void cec_msg_user_control_pressed(struct cec_msg *msg, | |||
1277 | msg->len += 4; | 1349 | msg->len += 4; |
1278 | msg->msg[3] = (ui_cmd->channel_identifier.channel_number_fmt << 2) | | 1350 | msg->msg[3] = (ui_cmd->channel_identifier.channel_number_fmt << 2) | |
1279 | (ui_cmd->channel_identifier.major >> 8); | 1351 | (ui_cmd->channel_identifier.major >> 8); |
1280 | msg->msg[4] = ui_cmd->channel_identifier.major && 0xff; | 1352 | msg->msg[4] = ui_cmd->channel_identifier.major & 0xff; |
1281 | msg->msg[5] = ui_cmd->channel_identifier.minor >> 8; | 1353 | msg->msg[5] = ui_cmd->channel_identifier.minor >> 8; |
1282 | msg->msg[6] = ui_cmd->channel_identifier.minor & 0xff; | 1354 | msg->msg[6] = ui_cmd->channel_identifier.minor & 0xff; |
1283 | break; | 1355 | break; |
diff --git a/include/linux/cec.h b/include/linux/cec.h index b3e22893a002..851968e803fa 100644 --- a/include/linux/cec.h +++ b/include/linux/cec.h | |||
@@ -364,7 +364,7 @@ struct cec_caps { | |||
364 | * @num_log_addrs: how many logical addresses should be claimed. Set by the | 364 | * @num_log_addrs: how many logical addresses should be claimed. Set by the |
365 | * caller. | 365 | * caller. |
366 | * @vendor_id: the vendor ID of the device. Set by the caller. | 366 | * @vendor_id: the vendor ID of the device. Set by the caller. |
367 | * @flags: set to 0. | 367 | * @flags: flags. |
368 | * @osd_name: the OSD name of the device. Set by the caller. | 368 | * @osd_name: the OSD name of the device. Set by the caller. |
369 | * @primary_device_type: the primary device type for each logical address. | 369 | * @primary_device_type: the primary device type for each logical address. |
370 | * Set by the caller. | 370 | * Set by the caller. |
@@ -389,6 +389,9 @@ struct cec_log_addrs { | |||
389 | __u8 features[CEC_MAX_LOG_ADDRS][12]; | 389 | __u8 features[CEC_MAX_LOG_ADDRS][12]; |
390 | }; | 390 | }; |
391 | 391 | ||
392 | /* Allow a fallback to unregistered */ | ||
393 | #define CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK (1 << 0) | ||
394 | |||
392 | /* Events */ | 395 | /* Events */ |
393 | 396 | ||
394 | /* Event that occurs when the adapter state changes */ | 397 | /* Event that occurs when the adapter state changes */ |
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index e2949397c19b..573c5a18908f 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h | |||
@@ -158,7 +158,7 @@ | |||
158 | #define __compiler_offsetof(a, b) \ | 158 | #define __compiler_offsetof(a, b) \ |
159 | __builtin_offsetof(a, b) | 159 | __builtin_offsetof(a, b) |
160 | 160 | ||
161 | #if GCC_VERSION >= 40100 && GCC_VERSION < 40600 | 161 | #if GCC_VERSION >= 40100 |
162 | # define __compiletime_object_size(obj) __builtin_object_size(obj, 0) | 162 | # define __compiletime_object_size(obj) __builtin_object_size(obj, 0) |
163 | #endif | 163 | #endif |
164 | 164 | ||
@@ -242,7 +242,11 @@ | |||
242 | */ | 242 | */ |
243 | #define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) | 243 | #define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) |
244 | 244 | ||
245 | #ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP | 245 | /* |
246 | * sparse (__CHECKER__) pretends to be gcc, but can't do constant | ||
247 | * folding in __builtin_bswap*() (yet), so don't set these for it. | ||
248 | */ | ||
249 | #if defined(CONFIG_ARCH_USE_BUILTIN_BSWAP) && !defined(__CHECKER__) | ||
246 | #if GCC_VERSION >= 40400 | 250 | #if GCC_VERSION >= 40400 |
247 | #define __HAVE_BUILTIN_BSWAP32__ | 251 | #define __HAVE_BUILTIN_BSWAP32__ |
248 | #define __HAVE_BUILTIN_BSWAP64__ | 252 | #define __HAVE_BUILTIN_BSWAP64__ |
@@ -250,7 +254,7 @@ | |||
250 | #if GCC_VERSION >= 40800 | 254 | #if GCC_VERSION >= 40800 |
251 | #define __HAVE_BUILTIN_BSWAP16__ | 255 | #define __HAVE_BUILTIN_BSWAP16__ |
252 | #endif | 256 | #endif |
253 | #endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */ | 257 | #endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP && !__CHECKER__ */ |
254 | 258 | ||
255 | #if GCC_VERSION >= 50000 | 259 | #if GCC_VERSION >= 50000 |
256 | #define KASAN_ABI_VERSION 4 | 260 | #define KASAN_ABI_VERSION 4 |
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 436aa4e42221..668569844d37 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
@@ -527,13 +527,14 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s | |||
527 | * object's lifetime is managed by something other than RCU. That | 527 | * object's lifetime is managed by something other than RCU. That |
528 | * "something other" might be reference counting or simple immortality. | 528 | * "something other" might be reference counting or simple immortality. |
529 | * | 529 | * |
530 | * The seemingly unused size_t variable is to validate @p is indeed a pointer | 530 | * The seemingly unused variable ___typecheck_p validates that @p is |
531 | * type by making sure it can be dereferenced. | 531 | * indeed a pointer type by using a pointer to typeof(*p) as the type. |
532 | * Taking a pointer to typeof(*p) again is needed in case p is void *. | ||
532 | */ | 533 | */ |
533 | #define lockless_dereference(p) \ | 534 | #define lockless_dereference(p) \ |
534 | ({ \ | 535 | ({ \ |
535 | typeof(p) _________p1 = READ_ONCE(p); \ | 536 | typeof(p) _________p1 = READ_ONCE(p); \ |
536 | size_t __maybe_unused __size_of_ptr = sizeof(*(p)); \ | 537 | typeof(*(p)) *___typecheck_p __maybe_unused; \ |
537 | smp_read_barrier_depends(); /* Dependency order vs. p above. */ \ | 538 | smp_read_barrier_depends(); /* Dependency order vs. p above. */ \ |
538 | (_________p1); \ | 539 | (_________p1); \ |
539 | }) | 540 | }) |
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 242bf530edfc..34bd80512a0c 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef __CPUHOTPLUG_H | 1 | #ifndef __CPUHOTPLUG_H |
2 | #define __CPUHOTPLUG_H | 2 | #define __CPUHOTPLUG_H |
3 | 3 | ||
4 | #include <linux/types.h> | ||
5 | |||
4 | enum cpuhp_state { | 6 | enum cpuhp_state { |
5 | CPUHP_OFFLINE, | 7 | CPUHP_OFFLINE, |
6 | CPUHP_CREATE_THREADS, | 8 | CPUHP_CREATE_THREADS, |
diff --git a/include/linux/efi.h b/include/linux/efi.h index 7f5a58225385..0148a3046b48 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h | |||
@@ -118,6 +118,15 @@ typedef struct { | |||
118 | u32 imagesize; | 118 | u32 imagesize; |
119 | } efi_capsule_header_t; | 119 | } efi_capsule_header_t; |
120 | 120 | ||
121 | struct efi_boot_memmap { | ||
122 | efi_memory_desc_t **map; | ||
123 | unsigned long *map_size; | ||
124 | unsigned long *desc_size; | ||
125 | u32 *desc_ver; | ||
126 | unsigned long *key_ptr; | ||
127 | unsigned long *buff_size; | ||
128 | }; | ||
129 | |||
121 | /* | 130 | /* |
122 | * EFI capsule flags | 131 | * EFI capsule flags |
123 | */ | 132 | */ |
@@ -946,7 +955,7 @@ extern int efi_memattr_apply_permissions(struct mm_struct *mm, | |||
946 | /* Iterate through an efi_memory_map */ | 955 | /* Iterate through an efi_memory_map */ |
947 | #define for_each_efi_memory_desc_in_map(m, md) \ | 956 | #define for_each_efi_memory_desc_in_map(m, md) \ |
948 | for ((md) = (m)->map; \ | 957 | for ((md) = (m)->map; \ |
949 | ((void *)(md) + (m)->desc_size) <= (m)->map_end; \ | 958 | (md) && ((void *)(md) + (m)->desc_size) <= (m)->map_end; \ |
950 | (md) = (void *)(md) + (m)->desc_size) | 959 | (md) = (void *)(md) + (m)->desc_size) |
951 | 960 | ||
952 | /** | 961 | /** |
@@ -1371,11 +1380,7 @@ char *efi_convert_cmdline(efi_system_table_t *sys_table_arg, | |||
1371 | efi_loaded_image_t *image, int *cmd_line_len); | 1380 | efi_loaded_image_t *image, int *cmd_line_len); |
1372 | 1381 | ||
1373 | efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg, | 1382 | efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg, |
1374 | efi_memory_desc_t **map, | 1383 | struct efi_boot_memmap *map); |
1375 | unsigned long *map_size, | ||
1376 | unsigned long *desc_size, | ||
1377 | u32 *desc_ver, | ||
1378 | unsigned long *key_ptr); | ||
1379 | 1384 | ||
1380 | efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg, | 1385 | efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg, |
1381 | unsigned long size, unsigned long align, | 1386 | unsigned long size, unsigned long align, |
@@ -1457,4 +1462,14 @@ extern void efi_call_virt_check_flags(unsigned long flags, const char *call); | |||
1457 | arch_efi_call_virt_teardown(); \ | 1462 | arch_efi_call_virt_teardown(); \ |
1458 | }) | 1463 | }) |
1459 | 1464 | ||
1465 | typedef efi_status_t (*efi_exit_boot_map_processing)( | ||
1466 | efi_system_table_t *sys_table_arg, | ||
1467 | struct efi_boot_memmap *map, | ||
1468 | void *priv); | ||
1469 | |||
1470 | efi_status_t efi_exit_boot_services(efi_system_table_t *sys_table, | ||
1471 | void *handle, | ||
1472 | struct efi_boot_memmap *map, | ||
1473 | void *priv, | ||
1474 | efi_exit_boot_map_processing priv_func); | ||
1460 | #endif /* _LINUX_EFI_H */ | 1475 | #endif /* _LINUX_EFI_H */ |
diff --git a/include/linux/fence.h b/include/linux/fence.h index 8cc719a63728..2ac6fa5f4712 100644 --- a/include/linux/fence.h +++ b/include/linux/fence.h | |||
@@ -49,8 +49,6 @@ struct fence_cb; | |||
49 | * @timestamp: Timestamp when the fence was signaled. | 49 | * @timestamp: Timestamp when the fence was signaled. |
50 | * @status: Optional, only valid if < 0, must be set before calling | 50 | * @status: Optional, only valid if < 0, must be set before calling |
51 | * fence_signal, indicates that the fence has completed with an error. | 51 | * fence_signal, indicates that the fence has completed with an error. |
52 | * @child_list: list of children fences | ||
53 | * @active_list: list of active fences | ||
54 | * | 52 | * |
55 | * the flags member must be manipulated and read using the appropriate | 53 | * the flags member must be manipulated and read using the appropriate |
56 | * atomic ops (bit_*), so taking the spinlock will not be needed most | 54 | * atomic ops (bit_*), so taking the spinlock will not be needed most |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 3523bf62f328..901e25d495cc 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -574,6 +574,7 @@ static inline void mapping_allow_writable(struct address_space *mapping) | |||
574 | 574 | ||
575 | struct posix_acl; | 575 | struct posix_acl; |
576 | #define ACL_NOT_CACHED ((void *)(-1)) | 576 | #define ACL_NOT_CACHED ((void *)(-1)) |
577 | #define ACL_DONT_CACHE ((void *)(-3)) | ||
577 | 578 | ||
578 | static inline struct posix_acl * | 579 | static inline struct posix_acl * |
579 | uncached_acl_sentinel(struct task_struct *task) | 580 | uncached_acl_sentinel(struct task_struct *task) |
diff --git a/include/linux/fscrypto.h b/include/linux/fscrypto.h index cfa6cde25f8e..76cff18bb032 100644 --- a/include/linux/fscrypto.h +++ b/include/linux/fscrypto.h | |||
@@ -274,8 +274,7 @@ extern void fscrypt_restore_control_page(struct page *); | |||
274 | extern int fscrypt_zeroout_range(struct inode *, pgoff_t, sector_t, | 274 | extern int fscrypt_zeroout_range(struct inode *, pgoff_t, sector_t, |
275 | unsigned int); | 275 | unsigned int); |
276 | /* policy.c */ | 276 | /* policy.c */ |
277 | extern int fscrypt_process_policy(struct inode *, | 277 | extern int fscrypt_process_policy(struct file *, const struct fscrypt_policy *); |
278 | const struct fscrypt_policy *); | ||
279 | extern int fscrypt_get_policy(struct inode *, struct fscrypt_policy *); | 278 | extern int fscrypt_get_policy(struct inode *, struct fscrypt_policy *); |
280 | extern int fscrypt_has_permitted_context(struct inode *, struct inode *); | 279 | extern int fscrypt_has_permitted_context(struct inode *, struct inode *); |
281 | extern int fscrypt_inherit_context(struct inode *, struct inode *, | 280 | extern int fscrypt_inherit_context(struct inode *, struct inode *, |
@@ -345,7 +344,7 @@ static inline int fscrypt_notsupp_zeroout_range(struct inode *i, pgoff_t p, | |||
345 | } | 344 | } |
346 | 345 | ||
347 | /* policy.c */ | 346 | /* policy.c */ |
348 | static inline int fscrypt_notsupp_process_policy(struct inode *i, | 347 | static inline int fscrypt_notsupp_process_policy(struct file *f, |
349 | const struct fscrypt_policy *p) | 348 | const struct fscrypt_policy *p) |
350 | { | 349 | { |
351 | return -EOPNOTSUPP; | 350 | return -EOPNOTSUPP; |
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 58205f33af02..7268ed076be8 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
@@ -148,6 +148,7 @@ struct fsnotify_group { | |||
148 | #define FS_PRIO_1 1 /* fanotify content based access control */ | 148 | #define FS_PRIO_1 1 /* fanotify content based access control */ |
149 | #define FS_PRIO_2 2 /* fanotify pre-content access */ | 149 | #define FS_PRIO_2 2 /* fanotify pre-content access */ |
150 | unsigned int priority; | 150 | unsigned int priority; |
151 | bool shutdown; /* group is being shut down, don't queue more events */ | ||
151 | 152 | ||
152 | /* stores all fastpath marks assoc with this group so they can be cleaned on unregister */ | 153 | /* stores all fastpath marks assoc with this group so they can be cleaned on unregister */ |
153 | struct mutex mark_mutex; /* protect marks_list */ | 154 | struct mutex mark_mutex; /* protect marks_list */ |
@@ -179,7 +180,6 @@ struct fsnotify_group { | |||
179 | spinlock_t access_lock; | 180 | spinlock_t access_lock; |
180 | struct list_head access_list; | 181 | struct list_head access_list; |
181 | wait_queue_head_t access_waitq; | 182 | wait_queue_head_t access_waitq; |
182 | atomic_t bypass_perm; | ||
183 | #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */ | 183 | #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */ |
184 | int f_flags; | 184 | int f_flags; |
185 | unsigned int max_marks; | 185 | unsigned int max_marks; |
@@ -292,6 +292,8 @@ extern struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *op | |||
292 | extern void fsnotify_get_group(struct fsnotify_group *group); | 292 | extern void fsnotify_get_group(struct fsnotify_group *group); |
293 | /* drop reference on a group from fsnotify_alloc_group */ | 293 | /* drop reference on a group from fsnotify_alloc_group */ |
294 | extern void fsnotify_put_group(struct fsnotify_group *group); | 294 | extern void fsnotify_put_group(struct fsnotify_group *group); |
295 | /* group destruction begins, stop queuing new events */ | ||
296 | extern void fsnotify_group_stop_queueing(struct fsnotify_group *group); | ||
295 | /* destroy group */ | 297 | /* destroy group */ |
296 | extern void fsnotify_destroy_group(struct fsnotify_group *group); | 298 | extern void fsnotify_destroy_group(struct fsnotify_group *group); |
297 | /* fasync handler function */ | 299 | /* fasync handler function */ |
@@ -304,8 +306,6 @@ extern int fsnotify_add_event(struct fsnotify_group *group, | |||
304 | struct fsnotify_event *event, | 306 | struct fsnotify_event *event, |
305 | int (*merge)(struct list_head *, | 307 | int (*merge)(struct list_head *, |
306 | struct fsnotify_event *)); | 308 | struct fsnotify_event *)); |
307 | /* Remove passed event from groups notification queue */ | ||
308 | extern void fsnotify_remove_event(struct fsnotify_group *group, struct fsnotify_event *event); | ||
309 | /* true if the group notification queue is empty */ | 309 | /* true if the group notification queue is empty */ |
310 | extern bool fsnotify_notify_queue_is_empty(struct fsnotify_group *group); | 310 | extern bool fsnotify_notify_queue_is_empty(struct fsnotify_group *group); |
311 | /* return, but do not dequeue the first event on the notification queue */ | 311 | /* return, but do not dequeue the first event on the notification queue */ |
diff --git a/include/linux/host1x.h b/include/linux/host1x.h index d2ba7d334039..1ffbf2a8cb99 100644 --- a/include/linux/host1x.h +++ b/include/linux/host1x.h | |||
@@ -304,6 +304,8 @@ struct tegra_mipi_device; | |||
304 | 304 | ||
305 | struct tegra_mipi_device *tegra_mipi_request(struct device *device); | 305 | struct tegra_mipi_device *tegra_mipi_request(struct device *device); |
306 | void tegra_mipi_free(struct tegra_mipi_device *device); | 306 | void tegra_mipi_free(struct tegra_mipi_device *device); |
307 | int tegra_mipi_enable(struct tegra_mipi_device *device); | ||
308 | int tegra_mipi_disable(struct tegra_mipi_device *device); | ||
307 | int tegra_mipi_calibrate(struct tegra_mipi_device *device); | 309 | int tegra_mipi_calibrate(struct tegra_mipi_device *device); |
308 | 310 | ||
309 | #endif | 311 | #endif |
diff --git a/include/linux/iio/sw_trigger.h b/include/linux/iio/sw_trigger.h index 5198f8ed08a4..c97eab67558f 100644 --- a/include/linux/iio/sw_trigger.h +++ b/include/linux/iio/sw_trigger.h | |||
@@ -62,7 +62,7 @@ void iio_swt_group_init_type_name(struct iio_sw_trigger *t, | |||
62 | const char *name, | 62 | const char *name, |
63 | struct config_item_type *type) | 63 | struct config_item_type *type) |
64 | { | 64 | { |
65 | #ifdef CONFIG_CONFIGFS_FS | 65 | #if IS_ENABLED(CONFIG_CONFIGFS_FS) |
66 | config_group_init_type_name(&t->group, name, type); | 66 | config_group_init_type_name(&t->group, name, type); |
67 | #endif | 67 | #endif |
68 | } | 68 | } |
diff --git a/include/linux/iomap.h b/include/linux/iomap.h index 3267df461012..3d70ece10313 100644 --- a/include/linux/iomap.h +++ b/include/linux/iomap.h | |||
@@ -19,6 +19,11 @@ struct vm_fault; | |||
19 | #define IOMAP_UNWRITTEN 0x04 /* blocks allocated @blkno in unwritten state */ | 19 | #define IOMAP_UNWRITTEN 0x04 /* blocks allocated @blkno in unwritten state */ |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * Flags for iomap mappings: | ||
23 | */ | ||
24 | #define IOMAP_F_MERGED 0x01 /* contains multiple blocks/extents */ | ||
25 | |||
26 | /* | ||
22 | * Magic value for blkno: | 27 | * Magic value for blkno: |
23 | */ | 28 | */ |
24 | #define IOMAP_NULL_BLOCK -1LL /* blkno is not valid */ | 29 | #define IOMAP_NULL_BLOCK -1LL /* blkno is not valid */ |
@@ -27,7 +32,8 @@ struct iomap { | |||
27 | sector_t blkno; /* 1st sector of mapping, 512b units */ | 32 | sector_t blkno; /* 1st sector of mapping, 512b units */ |
28 | loff_t offset; /* file offset of mapping, bytes */ | 33 | loff_t offset; /* file offset of mapping, bytes */ |
29 | u64 length; /* length of mapping, bytes */ | 34 | u64 length; /* length of mapping, bytes */ |
30 | int type; /* type of mapping */ | 35 | u16 type; /* type of mapping */ |
36 | u16 flags; /* flags for mapping */ | ||
31 | struct block_device *bdev; /* block device for I/O */ | 37 | struct block_device *bdev; /* block device for I/O */ |
32 | }; | 38 | }; |
33 | 39 | ||
diff --git a/include/linux/irq.h b/include/linux/irq.h index b52424eaa0ed..0ac26c892fe2 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -945,6 +945,16 @@ static inline void irq_gc_lock(struct irq_chip_generic *gc) { } | |||
945 | static inline void irq_gc_unlock(struct irq_chip_generic *gc) { } | 945 | static inline void irq_gc_unlock(struct irq_chip_generic *gc) { } |
946 | #endif | 946 | #endif |
947 | 947 | ||
948 | /* | ||
949 | * The irqsave variants are for usage in non interrupt code. Do not use | ||
950 | * them in irq_chip callbacks. Use irq_gc_lock() instead. | ||
951 | */ | ||
952 | #define irq_gc_lock_irqsave(gc, flags) \ | ||
953 | raw_spin_lock_irqsave(&(gc)->lock, flags) | ||
954 | |||
955 | #define irq_gc_unlock_irqrestore(gc, flags) \ | ||
956 | raw_spin_unlock_irqrestore(&(gc)->lock, flags) | ||
957 | |||
948 | static inline void irq_reg_writel(struct irq_chip_generic *gc, | 958 | static inline void irq_reg_writel(struct irq_chip_generic *gc, |
949 | u32 val, int reg_offset) | 959 | u32 val, int reg_offset) |
950 | { | 960 | { |
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index 56b0b7ec66aa..99ac022edc60 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h | |||
@@ -337,6 +337,7 @@ | |||
337 | */ | 337 | */ |
338 | #define E_ITS_MOVI_UNMAPPED_INTERRUPT 0x010107 | 338 | #define E_ITS_MOVI_UNMAPPED_INTERRUPT 0x010107 |
339 | #define E_ITS_MOVI_UNMAPPED_COLLECTION 0x010109 | 339 | #define E_ITS_MOVI_UNMAPPED_COLLECTION 0x010109 |
340 | #define E_ITS_INT_UNMAPPED_INTERRUPT 0x010307 | ||
340 | #define E_ITS_CLEAR_UNMAPPED_INTERRUPT 0x010507 | 341 | #define E_ITS_CLEAR_UNMAPPED_INTERRUPT 0x010507 |
341 | #define E_ITS_MAPD_DEVICE_OOR 0x010801 | 342 | #define E_ITS_MAPD_DEVICE_OOR 0x010801 |
342 | #define E_ITS_MAPC_PROCNUM_OOR 0x010902 | 343 | #define E_ITS_MAPC_PROCNUM_OOR 0x010902 |
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index 4429d255c8ab..5e5b2969d931 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h | |||
@@ -195,6 +195,7 @@ static inline bool vma_migratable(struct vm_area_struct *vma) | |||
195 | } | 195 | } |
196 | 196 | ||
197 | extern int mpol_misplaced(struct page *, struct vm_area_struct *, unsigned long); | 197 | extern int mpol_misplaced(struct page *, struct vm_area_struct *, unsigned long); |
198 | extern void mpol_put_task_policy(struct task_struct *); | ||
198 | 199 | ||
199 | #else | 200 | #else |
200 | 201 | ||
@@ -297,5 +298,8 @@ static inline int mpol_misplaced(struct page *page, struct vm_area_struct *vma, | |||
297 | return -1; /* no node preference */ | 298 | return -1; /* no node preference */ |
298 | } | 299 | } |
299 | 300 | ||
301 | static inline void mpol_put_task_policy(struct task_struct *task) | ||
302 | { | ||
303 | } | ||
300 | #endif /* CONFIG_NUMA */ | 304 | #endif /* CONFIG_NUMA */ |
301 | #endif | 305 | #endif |
diff --git a/include/linux/mfd/da8xx-cfgchip.h b/include/linux/mfd/da8xx-cfgchip.h new file mode 100644 index 000000000000..304985e288d2 --- /dev/null +++ b/include/linux/mfd/da8xx-cfgchip.h | |||
@@ -0,0 +1,153 @@ | |||
1 | /* | ||
2 | * TI DaVinci DA8xx CHIPCFGx registers for syscon consumers. | ||
3 | * | ||
4 | * Copyright (C) 2016 David Lechner <david@lechnology.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
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 | #ifndef __LINUX_MFD_DA8XX_CFGCHIP_H | ||
18 | #define __LINUX_MFD_DA8XX_CFGCHIP_H | ||
19 | |||
20 | #include <linux/bitops.h> | ||
21 | |||
22 | /* register offset (32-bit registers) */ | ||
23 | #define CFGCHIP(n) ((n) * 4) | ||
24 | |||
25 | /* CFGCHIP0 (PLL0/EDMA3_0) register bits */ | ||
26 | #define CFGCHIP0_PLL_MASTER_LOCK BIT(4) | ||
27 | #define CFGCHIP0_EDMA30TC1DBS(n) ((n) << 2) | ||
28 | #define CFGCHIP0_EDMA30TC1DBS_MASK CFGCHIP0_EDMA30TC1DBS(0x3) | ||
29 | #define CFGCHIP0_EDMA30TC1DBS_16 CFGCHIP0_EDMA30TC1DBS(0x0) | ||
30 | #define CFGCHIP0_EDMA30TC1DBS_32 CFGCHIP0_EDMA30TC1DBS(0x1) | ||
31 | #define CFGCHIP0_EDMA30TC1DBS_64 CFGCHIP0_EDMA30TC1DBS(0x2) | ||
32 | #define CFGCHIP0_EDMA30TC0DBS(n) ((n) << 0) | ||
33 | #define CFGCHIP0_EDMA30TC0DBS_MASK CFGCHIP0_EDMA30TC0DBS(0x3) | ||
34 | #define CFGCHIP0_EDMA30TC0DBS_16 CFGCHIP0_EDMA30TC0DBS(0x0) | ||
35 | #define CFGCHIP0_EDMA30TC0DBS_32 CFGCHIP0_EDMA30TC0DBS(0x1) | ||
36 | #define CFGCHIP0_EDMA30TC0DBS_64 CFGCHIP0_EDMA30TC0DBS(0x2) | ||
37 | |||
38 | /* CFGCHIP1 (eCAP/HPI/EDMA3_1/eHRPWM TBCLK/McASP0 AMUTEIN) register bits */ | ||
39 | #define CFGCHIP1_CAP2SRC(n) ((n) << 27) | ||
40 | #define CFGCHIP1_CAP2SRC_MASK CFGCHIP1_CAP2SRC(0x1f) | ||
41 | #define CFGCHIP1_CAP2SRC_ECAP_PIN CFGCHIP1_CAP2SRC(0x0) | ||
42 | #define CFGCHIP1_CAP2SRC_MCASP0_TX CFGCHIP1_CAP2SRC(0x1) | ||
43 | #define CFGCHIP1_CAP2SRC_MCASP0_RX CFGCHIP1_CAP2SRC(0x2) | ||
44 | #define CFGCHIP1_CAP2SRC_EMAC_C0_RX_THRESHOLD CFGCHIP1_CAP2SRC(0x7) | ||
45 | #define CFGCHIP1_CAP2SRC_EMAC_C0_RX CFGCHIP1_CAP2SRC(0x8) | ||
46 | #define CFGCHIP1_CAP2SRC_EMAC_C0_TX CFGCHIP1_CAP2SRC(0x9) | ||
47 | #define CFGCHIP1_CAP2SRC_EMAC_C0_MISC CFGCHIP1_CAP2SRC(0xa) | ||
48 | #define CFGCHIP1_CAP2SRC_EMAC_C1_RX_THRESHOLD CFGCHIP1_CAP2SRC(0xb) | ||
49 | #define CFGCHIP1_CAP2SRC_EMAC_C1_RX CFGCHIP1_CAP2SRC(0xc) | ||
50 | #define CFGCHIP1_CAP2SRC_EMAC_C1_TX CFGCHIP1_CAP2SRC(0xd) | ||
51 | #define CFGCHIP1_CAP2SRC_EMAC_C1_MISC CFGCHIP1_CAP2SRC(0xe) | ||
52 | #define CFGCHIP1_CAP2SRC_EMAC_C2_RX_THRESHOLD CFGCHIP1_CAP2SRC(0xf) | ||
53 | #define CFGCHIP1_CAP2SRC_EMAC_C2_RX CFGCHIP1_CAP2SRC(0x10) | ||
54 | #define CFGCHIP1_CAP2SRC_EMAC_C2_TX CFGCHIP1_CAP2SRC(0x11) | ||
55 | #define CFGCHIP1_CAP2SRC_EMAC_C2_MISC CFGCHIP1_CAP2SRC(0x12) | ||
56 | #define CFGCHIP1_CAP1SRC(n) ((n) << 22) | ||
57 | #define CFGCHIP1_CAP1SRC_MASK CFGCHIP1_CAP1SRC(0x1f) | ||
58 | #define CFGCHIP1_CAP1SRC_ECAP_PIN CFGCHIP1_CAP1SRC(0x0) | ||
59 | #define CFGCHIP1_CAP1SRC_MCASP0_TX CFGCHIP1_CAP1SRC(0x1) | ||
60 | #define CFGCHIP1_CAP1SRC_MCASP0_RX CFGCHIP1_CAP1SRC(0x2) | ||
61 | #define CFGCHIP1_CAP1SRC_EMAC_C0_RX_THRESHOLD CFGCHIP1_CAP1SRC(0x7) | ||
62 | #define CFGCHIP1_CAP1SRC_EMAC_C0_RX CFGCHIP1_CAP1SRC(0x8) | ||
63 | #define CFGCHIP1_CAP1SRC_EMAC_C0_TX CFGCHIP1_CAP1SRC(0x9) | ||
64 | #define CFGCHIP1_CAP1SRC_EMAC_C0_MISC CFGCHIP1_CAP1SRC(0xa) | ||
65 | #define CFGCHIP1_CAP1SRC_EMAC_C1_RX_THRESHOLD CFGCHIP1_CAP1SRC(0xb) | ||
66 | #define CFGCHIP1_CAP1SRC_EMAC_C1_RX CFGCHIP1_CAP1SRC(0xc) | ||
67 | #define CFGCHIP1_CAP1SRC_EMAC_C1_TX CFGCHIP1_CAP1SRC(0xd) | ||
68 | #define CFGCHIP1_CAP1SRC_EMAC_C1_MISC CFGCHIP1_CAP1SRC(0xe) | ||
69 | #define CFGCHIP1_CAP1SRC_EMAC_C2_RX_THRESHOLD CFGCHIP1_CAP1SRC(0xf) | ||
70 | #define CFGCHIP1_CAP1SRC_EMAC_C2_RX CFGCHIP1_CAP1SRC(0x10) | ||
71 | #define CFGCHIP1_CAP1SRC_EMAC_C2_TX CFGCHIP1_CAP1SRC(0x11) | ||
72 | #define CFGCHIP1_CAP1SRC_EMAC_C2_MISC CFGCHIP1_CAP1SRC(0x12) | ||
73 | #define CFGCHIP1_CAP0SRC(n) ((n) << 17) | ||
74 | #define CFGCHIP1_CAP0SRC_MASK CFGCHIP1_CAP0SRC(0x1f) | ||
75 | #define CFGCHIP1_CAP0SRC_ECAP_PIN CFGCHIP1_CAP0SRC(0x0) | ||
76 | #define CFGCHIP1_CAP0SRC_MCASP0_TX CFGCHIP1_CAP0SRC(0x1) | ||
77 | #define CFGCHIP1_CAP0SRC_MCASP0_RX CFGCHIP1_CAP0SRC(0x2) | ||
78 | #define CFGCHIP1_CAP0SRC_EMAC_C0_RX_THRESHOLD CFGCHIP1_CAP0SRC(0x7) | ||
79 | #define CFGCHIP1_CAP0SRC_EMAC_C0_RX CFGCHIP1_CAP0SRC(0x8) | ||
80 | #define CFGCHIP1_CAP0SRC_EMAC_C0_TX CFGCHIP1_CAP0SRC(0x9) | ||
81 | #define CFGCHIP1_CAP0SRC_EMAC_C0_MISC CFGCHIP1_CAP0SRC(0xa) | ||
82 | #define CFGCHIP1_CAP0SRC_EMAC_C1_RX_THRESHOLD CFGCHIP1_CAP0SRC(0xb) | ||
83 | #define CFGCHIP1_CAP0SRC_EMAC_C1_RX CFGCHIP1_CAP0SRC(0xc) | ||
84 | #define CFGCHIP1_CAP0SRC_EMAC_C1_TX CFGCHIP1_CAP0SRC(0xd) | ||
85 | #define CFGCHIP1_CAP0SRC_EMAC_C1_MISC CFGCHIP1_CAP0SRC(0xe) | ||
86 | #define CFGCHIP1_CAP0SRC_EMAC_C2_RX_THRESHOLD CFGCHIP1_CAP0SRC(0xf) | ||
87 | #define CFGCHIP1_CAP0SRC_EMAC_C2_RX CFGCHIP1_CAP0SRC(0x10) | ||
88 | #define CFGCHIP1_CAP0SRC_EMAC_C2_TX CFGCHIP1_CAP0SRC(0x11) | ||
89 | #define CFGCHIP1_CAP0SRC_EMAC_C2_MISC CFGCHIP1_CAP0SRC(0x12) | ||
90 | #define CFGCHIP1_HPIBYTEAD BIT(16) | ||
91 | #define CFGCHIP1_HPIENA BIT(15) | ||
92 | #define CFGCHIP0_EDMA31TC0DBS(n) ((n) << 13) | ||
93 | #define CFGCHIP0_EDMA31TC0DBS_MASK CFGCHIP0_EDMA31TC0DBS(0x3) | ||
94 | #define CFGCHIP0_EDMA31TC0DBS_16 CFGCHIP0_EDMA31TC0DBS(0x0) | ||
95 | #define CFGCHIP0_EDMA31TC0DBS_32 CFGCHIP0_EDMA31TC0DBS(0x1) | ||
96 | #define CFGCHIP0_EDMA31TC0DBS_64 CFGCHIP0_EDMA31TC0DBS(0x2) | ||
97 | #define CFGCHIP1_TBCLKSYNC BIT(12) | ||
98 | #define CFGCHIP1_AMUTESEL0(n) ((n) << 0) | ||
99 | #define CFGCHIP1_AMUTESEL0_MASK CFGCHIP1_AMUTESEL0(0xf) | ||
100 | #define CFGCHIP1_AMUTESEL0_LOW CFGCHIP1_AMUTESEL0(0x0) | ||
101 | #define CFGCHIP1_AMUTESEL0_BANK_0 CFGCHIP1_AMUTESEL0(0x1) | ||
102 | #define CFGCHIP1_AMUTESEL0_BANK_1 CFGCHIP1_AMUTESEL0(0x2) | ||
103 | #define CFGCHIP1_AMUTESEL0_BANK_2 CFGCHIP1_AMUTESEL0(0x3) | ||
104 | #define CFGCHIP1_AMUTESEL0_BANK_3 CFGCHIP1_AMUTESEL0(0x4) | ||
105 | #define CFGCHIP1_AMUTESEL0_BANK_4 CFGCHIP1_AMUTESEL0(0x5) | ||
106 | #define CFGCHIP1_AMUTESEL0_BANK_5 CFGCHIP1_AMUTESEL0(0x6) | ||
107 | #define CFGCHIP1_AMUTESEL0_BANK_6 CFGCHIP1_AMUTESEL0(0x7) | ||
108 | #define CFGCHIP1_AMUTESEL0_BANK_7 CFGCHIP1_AMUTESEL0(0x8) | ||
109 | |||
110 | /* CFGCHIP2 (USB PHY) register bits */ | ||
111 | #define CFGCHIP2_PHYCLKGD BIT(17) | ||
112 | #define CFGCHIP2_VBUSSENSE BIT(16) | ||
113 | #define CFGCHIP2_RESET BIT(15) | ||
114 | #define CFGCHIP2_OTGMODE(n) ((n) << 13) | ||
115 | #define CFGCHIP2_OTGMODE_MASK CFGCHIP2_OTGMODE(0x3) | ||
116 | #define CFGCHIP2_OTGMODE_NO_OVERRIDE CFGCHIP2_OTGMODE(0x0) | ||
117 | #define CFGCHIP2_OTGMODE_FORCE_HOST CFGCHIP2_OTGMODE(0x1) | ||
118 | #define CFGCHIP2_OTGMODE_FORCE_DEVICE CFGCHIP2_OTGMODE(0x2) | ||
119 | #define CFGCHIP2_OTGMODE_FORCE_HOST_VBUS_LOW CFGCHIP2_OTGMODE(0x3) | ||
120 | #define CFGCHIP2_USB1PHYCLKMUX BIT(12) | ||
121 | #define CFGCHIP2_USB2PHYCLKMUX BIT(11) | ||
122 | #define CFGCHIP2_PHYPWRDN BIT(10) | ||
123 | #define CFGCHIP2_OTGPWRDN BIT(9) | ||
124 | #define CFGCHIP2_DATPOL BIT(8) | ||
125 | #define CFGCHIP2_USB1SUSPENDM BIT(7) | ||
126 | #define CFGCHIP2_PHY_PLLON BIT(6) | ||
127 | #define CFGCHIP2_SESENDEN BIT(5) | ||
128 | #define CFGCHIP2_VBDTCTEN BIT(4) | ||
129 | #define CFGCHIP2_REFFREQ(n) ((n) << 0) | ||
130 | #define CFGCHIP2_REFFREQ_MASK CFGCHIP2_REFFREQ(0xf) | ||
131 | #define CFGCHIP2_REFFREQ_12MHZ CFGCHIP2_REFFREQ(0x1) | ||
132 | #define CFGCHIP2_REFFREQ_24MHZ CFGCHIP2_REFFREQ(0x2) | ||
133 | #define CFGCHIP2_REFFREQ_48MHZ CFGCHIP2_REFFREQ(0x3) | ||
134 | #define CFGCHIP2_REFFREQ_19_2MHZ CFGCHIP2_REFFREQ(0x4) | ||
135 | #define CFGCHIP2_REFFREQ_38_4MHZ CFGCHIP2_REFFREQ(0x5) | ||
136 | #define CFGCHIP2_REFFREQ_13MHZ CFGCHIP2_REFFREQ(0x6) | ||
137 | #define CFGCHIP2_REFFREQ_26MHZ CFGCHIP2_REFFREQ(0x7) | ||
138 | #define CFGCHIP2_REFFREQ_20MHZ CFGCHIP2_REFFREQ(0x8) | ||
139 | #define CFGCHIP2_REFFREQ_40MHZ CFGCHIP2_REFFREQ(0x9) | ||
140 | |||
141 | /* CFGCHIP3 (EMAC/uPP/PLL1/ASYNC3/PRU/DIV4.5/EMIFA) register bits */ | ||
142 | #define CFGCHIP3_RMII_SEL BIT(8) | ||
143 | #define CFGCHIP3_UPP_TX_CLKSRC BIT(6) | ||
144 | #define CFGCHIP3_PLL1_MASTER_LOCK BIT(5) | ||
145 | #define CFGCHIP3_ASYNC3_CLKSRC BIT(4) | ||
146 | #define CFGCHIP3_PRUEVTSEL BIT(3) | ||
147 | #define CFGCHIP3_DIV45PENA BIT(2) | ||
148 | #define CFGCHIP3_EMA_CLKSRC BIT(1) | ||
149 | |||
150 | /* CFGCHIP4 (McASP0 AMUNTEIN) register bits */ | ||
151 | #define CFGCHIP4_AMUTECLR0 BIT(0) | ||
152 | |||
153 | #endif /* __LINUX_MFD_DA8XX_CFGCHIP_H */ | ||
diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h index 2567a87872b0..7f55b8b41032 100644 --- a/include/linux/mfd/ti_am335x_tscadc.h +++ b/include/linux/mfd/ti_am335x_tscadc.h | |||
@@ -138,16 +138,16 @@ | |||
138 | /* | 138 | /* |
139 | * time in us for processing a single channel, calculated as follows: | 139 | * time in us for processing a single channel, calculated as follows: |
140 | * | 140 | * |
141 | * num cycles = open delay + (sample delay + conv time) * averaging | 141 | * max num cycles = open delay + (sample delay + conv time) * averaging |
142 | * | 142 | * |
143 | * num cycles: 152 + (1 + 13) * 16 = 376 | 143 | * max num cycles: 262143 + (255 + 13) * 16 = 266431 |
144 | * | 144 | * |
145 | * clock frequency: 26MHz / 8 = 3.25MHz | 145 | * clock frequency: 26MHz / 8 = 3.25MHz |
146 | * clock period: 1 / 3.25MHz = 308ns | 146 | * clock period: 1 / 3.25MHz = 308ns |
147 | * | 147 | * |
148 | * processing time: 376 * 308ns = 116us | 148 | * max processing time: 266431 * 308ns = 83ms(approx) |
149 | */ | 149 | */ |
150 | #define IDLE_TIMEOUT 116 /* microsec */ | 150 | #define IDLE_TIMEOUT 83 /* milliseconds */ |
151 | 151 | ||
152 | #define TSCADC_CELLS 2 | 152 | #define TSCADC_CELLS 2 |
153 | 153 | ||
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index 21bc4557b67a..d1f9a581aca8 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h | |||
@@ -6710,9 +6710,10 @@ struct mlx5_ifc_pude_reg_bits { | |||
6710 | }; | 6710 | }; |
6711 | 6711 | ||
6712 | struct mlx5_ifc_ptys_reg_bits { | 6712 | struct mlx5_ifc_ptys_reg_bits { |
6713 | u8 an_disable_cap[0x1]; | 6713 | u8 reserved_at_0[0x1]; |
6714 | u8 an_disable_admin[0x1]; | 6714 | u8 an_disable_admin[0x1]; |
6715 | u8 reserved_at_2[0x6]; | 6715 | u8 an_disable_cap[0x1]; |
6716 | u8 reserved_at_3[0x5]; | ||
6716 | u8 local_port[0x8]; | 6717 | u8 local_port[0x8]; |
6717 | u8 reserved_at_10[0xd]; | 6718 | u8 reserved_at_10[0xd]; |
6718 | u8 proto_mask[0x3]; | 6719 | u8 proto_mask[0x3]; |
diff --git a/include/linux/mm.h b/include/linux/mm.h index 08ed53eeedd5..ef815b9cd426 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -2014,6 +2014,7 @@ extern void mm_drop_all_locks(struct mm_struct *mm); | |||
2014 | 2014 | ||
2015 | extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file); | 2015 | extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file); |
2016 | extern struct file *get_mm_exe_file(struct mm_struct *mm); | 2016 | extern struct file *get_mm_exe_file(struct mm_struct *mm); |
2017 | extern struct file *get_task_exe_file(struct task_struct *task); | ||
2017 | 2018 | ||
2018 | extern bool may_expand_vm(struct mm_struct *, vm_flags_t, unsigned long npages); | 2019 | extern bool may_expand_vm(struct mm_struct *, vm_flags_t, unsigned long npages); |
2019 | extern void vm_stat_account(struct mm_struct *, vm_flags_t, long npages); | 2020 | extern void vm_stat_account(struct mm_struct *, vm_flags_t, long npages); |
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index d572b78b65e1..7f2ae99e5daf 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
@@ -828,9 +828,21 @@ unsigned long __init node_memmap_size_bytes(int, unsigned long, unsigned long); | |||
828 | */ | 828 | */ |
829 | #define zone_idx(zone) ((zone) - (zone)->zone_pgdat->node_zones) | 829 | #define zone_idx(zone) ((zone) - (zone)->zone_pgdat->node_zones) |
830 | 830 | ||
831 | static inline int populated_zone(struct zone *zone) | 831 | /* |
832 | * Returns true if a zone has pages managed by the buddy allocator. | ||
833 | * All the reclaim decisions have to use this function rather than | ||
834 | * populated_zone(). If the whole zone is reserved then we can easily | ||
835 | * end up with populated_zone() && !managed_zone(). | ||
836 | */ | ||
837 | static inline bool managed_zone(struct zone *zone) | ||
838 | { | ||
839 | return zone->managed_pages; | ||
840 | } | ||
841 | |||
842 | /* Returns true if a zone has memory */ | ||
843 | static inline bool populated_zone(struct zone *zone) | ||
832 | { | 844 | { |
833 | return (!!zone->present_pages); | 845 | return zone->present_pages; |
834 | } | 846 | } |
835 | 847 | ||
836 | extern int movable_zone; | 848 | extern int movable_zone; |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 3a788bf0affd..e8d79d4ebcfe 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -3267,6 +3267,7 @@ static inline void napi_free_frags(struct napi_struct *napi) | |||
3267 | napi->skb = NULL; | 3267 | napi->skb = NULL; |
3268 | } | 3268 | } |
3269 | 3269 | ||
3270 | bool netdev_is_rx_handler_busy(struct net_device *dev); | ||
3270 | int netdev_rx_handler_register(struct net_device *dev, | 3271 | int netdev_rx_handler_register(struct net_device *dev, |
3271 | rx_handler_func_t *rx_handler, | 3272 | rx_handler_func_t *rx_handler, |
3272 | void *rx_handler_data); | 3273 | void *rx_handler_data); |
diff --git a/include/linux/netfilter/nfnetlink_acct.h b/include/linux/netfilter/nfnetlink_acct.h index 80ca889b164e..664da0048625 100644 --- a/include/linux/netfilter/nfnetlink_acct.h +++ b/include/linux/netfilter/nfnetlink_acct.h | |||
@@ -15,6 +15,6 @@ struct nf_acct; | |||
15 | struct nf_acct *nfnl_acct_find_get(struct net *net, const char *filter_name); | 15 | struct nf_acct *nfnl_acct_find_get(struct net *net, const char *filter_name); |
16 | void nfnl_acct_put(struct nf_acct *acct); | 16 | void nfnl_acct_put(struct nf_acct *acct); |
17 | void nfnl_acct_update(const struct sk_buff *skb, struct nf_acct *nfacct); | 17 | void nfnl_acct_update(const struct sk_buff *skb, struct nf_acct *nfacct); |
18 | extern int nfnl_acct_overquota(const struct sk_buff *skb, | 18 | int nfnl_acct_overquota(struct net *net, const struct sk_buff *skb, |
19 | struct nf_acct *nfacct); | 19 | struct nf_acct *nfacct); |
20 | #endif /* _NFNL_ACCT_H */ | 20 | #endif /* _NFNL_ACCT_H */ |
diff --git a/include/linux/nvme.h b/include/linux/nvme.h index d8b37bab2887..7676557ce357 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h | |||
@@ -794,7 +794,7 @@ struct nvmf_connect_command { | |||
794 | }; | 794 | }; |
795 | 795 | ||
796 | struct nvmf_connect_data { | 796 | struct nvmf_connect_data { |
797 | uuid_le hostid; | 797 | uuid_be hostid; |
798 | __le16 cntlid; | 798 | __le16 cntlid; |
799 | char resv4[238]; | 799 | char resv4[238]; |
800 | char subsysnqn[NVMF_NQN_FIELD_LEN]; | 800 | char subsysnqn[NVMF_NQN_FIELD_LEN]; |
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 66a1260b33de..01e84436cddf 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h | |||
@@ -571,56 +571,57 @@ static inline int fault_in_pages_readable(const char __user *uaddr, int size) | |||
571 | */ | 571 | */ |
572 | static inline int fault_in_multipages_writeable(char __user *uaddr, int size) | 572 | static inline int fault_in_multipages_writeable(char __user *uaddr, int size) |
573 | { | 573 | { |
574 | int ret = 0; | ||
575 | char __user *end = uaddr + size - 1; | 574 | char __user *end = uaddr + size - 1; |
576 | 575 | ||
577 | if (unlikely(size == 0)) | 576 | if (unlikely(size == 0)) |
578 | return ret; | 577 | return 0; |
579 | 578 | ||
579 | if (unlikely(uaddr > end)) | ||
580 | return -EFAULT; | ||
580 | /* | 581 | /* |
581 | * Writing zeroes into userspace here is OK, because we know that if | 582 | * Writing zeroes into userspace here is OK, because we know that if |
582 | * the zero gets there, we'll be overwriting it. | 583 | * the zero gets there, we'll be overwriting it. |
583 | */ | 584 | */ |
584 | while (uaddr <= end) { | 585 | do { |
585 | ret = __put_user(0, uaddr); | 586 | if (unlikely(__put_user(0, uaddr) != 0)) |
586 | if (ret != 0) | 587 | return -EFAULT; |
587 | return ret; | ||
588 | uaddr += PAGE_SIZE; | 588 | uaddr += PAGE_SIZE; |
589 | } | 589 | } while (uaddr <= end); |
590 | 590 | ||
591 | /* Check whether the range spilled into the next page. */ | 591 | /* Check whether the range spilled into the next page. */ |
592 | if (((unsigned long)uaddr & PAGE_MASK) == | 592 | if (((unsigned long)uaddr & PAGE_MASK) == |
593 | ((unsigned long)end & PAGE_MASK)) | 593 | ((unsigned long)end & PAGE_MASK)) |
594 | ret = __put_user(0, end); | 594 | return __put_user(0, end); |
595 | 595 | ||
596 | return ret; | 596 | return 0; |
597 | } | 597 | } |
598 | 598 | ||
599 | static inline int fault_in_multipages_readable(const char __user *uaddr, | 599 | static inline int fault_in_multipages_readable(const char __user *uaddr, |
600 | int size) | 600 | int size) |
601 | { | 601 | { |
602 | volatile char c; | 602 | volatile char c; |
603 | int ret = 0; | ||
604 | const char __user *end = uaddr + size - 1; | 603 | const char __user *end = uaddr + size - 1; |
605 | 604 | ||
606 | if (unlikely(size == 0)) | 605 | if (unlikely(size == 0)) |
607 | return ret; | 606 | return 0; |
608 | 607 | ||
609 | while (uaddr <= end) { | 608 | if (unlikely(uaddr > end)) |
610 | ret = __get_user(c, uaddr); | 609 | return -EFAULT; |
611 | if (ret != 0) | 610 | |
612 | return ret; | 611 | do { |
612 | if (unlikely(__get_user(c, uaddr) != 0)) | ||
613 | return -EFAULT; | ||
613 | uaddr += PAGE_SIZE; | 614 | uaddr += PAGE_SIZE; |
614 | } | 615 | } while (uaddr <= end); |
615 | 616 | ||
616 | /* Check whether the range spilled into the next page. */ | 617 | /* Check whether the range spilled into the next page. */ |
617 | if (((unsigned long)uaddr & PAGE_MASK) == | 618 | if (((unsigned long)uaddr & PAGE_MASK) == |
618 | ((unsigned long)end & PAGE_MASK)) { | 619 | ((unsigned long)end & PAGE_MASK)) { |
619 | ret = __get_user(c, end); | 620 | return __get_user(c, end); |
620 | (void)c; | ||
621 | } | 621 | } |
622 | 622 | ||
623 | return ret; | 623 | (void)c; |
624 | return 0; | ||
624 | } | 625 | } |
625 | 626 | ||
626 | int add_to_page_cache_locked(struct page *page, struct address_space *mapping, | 627 | int add_to_page_cache_locked(struct page *page, struct address_space *mapping, |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 2599a980340f..0ab835965669 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -683,15 +683,6 @@ struct pci_driver { | |||
683 | #define to_pci_driver(drv) container_of(drv, struct pci_driver, driver) | 683 | #define to_pci_driver(drv) container_of(drv, struct pci_driver, driver) |
684 | 684 | ||
685 | /** | 685 | /** |
686 | * DEFINE_PCI_DEVICE_TABLE - macro used to describe a pci device table | ||
687 | * @_table: device table name | ||
688 | * | ||
689 | * This macro is deprecated and should not be used in new code. | ||
690 | */ | ||
691 | #define DEFINE_PCI_DEVICE_TABLE(_table) \ | ||
692 | const struct pci_device_id _table[] | ||
693 | |||
694 | /** | ||
695 | * PCI_DEVICE - macro used to describe a specific pci device | 686 | * PCI_DEVICE - macro used to describe a specific pci device |
696 | * @vend: the 16 bit PCI Vendor ID | 687 | * @vend: the 16 bit PCI Vendor ID |
697 | * @dev: the 16 bit PCI Device ID | 688 | * @dev: the 16 bit PCI Device ID |
@@ -1251,10 +1242,12 @@ resource_size_t pcibios_iov_resource_alignment(struct pci_dev *dev, int resno); | |||
1251 | int pci_set_vga_state(struct pci_dev *pdev, bool decode, | 1242 | int pci_set_vga_state(struct pci_dev *pdev, bool decode, |
1252 | unsigned int command_bits, u32 flags); | 1243 | unsigned int command_bits, u32 flags); |
1253 | 1244 | ||
1254 | #define PCI_IRQ_NOLEGACY (1 << 0) /* don't use legacy interrupts */ | 1245 | #define PCI_IRQ_LEGACY (1 << 0) /* allow legacy interrupts */ |
1255 | #define PCI_IRQ_NOMSI (1 << 1) /* don't use MSI interrupts */ | 1246 | #define PCI_IRQ_MSI (1 << 1) /* allow MSI interrupts */ |
1256 | #define PCI_IRQ_NOMSIX (1 << 2) /* don't use MSI-X interrupts */ | 1247 | #define PCI_IRQ_MSIX (1 << 2) /* allow MSI-X interrupts */ |
1257 | #define PCI_IRQ_NOAFFINITY (1 << 3) /* don't auto-assign affinity */ | 1248 | #define PCI_IRQ_AFFINITY (1 << 3) /* auto-assign affinity */ |
1249 | #define PCI_IRQ_ALL_TYPES \ | ||
1250 | (PCI_IRQ_LEGACY | PCI_IRQ_MSI | PCI_IRQ_MSIX) | ||
1258 | 1251 | ||
1259 | /* kmem_cache style wrapper around pci_alloc_consistent() */ | 1252 | /* kmem_cache style wrapper around pci_alloc_consistent() */ |
1260 | 1253 | ||
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index 923266cd294a..48ec7651989b 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h | |||
@@ -111,7 +111,6 @@ struct uart_8250_port { | |||
111 | * if no_console_suspend | 111 | * if no_console_suspend |
112 | */ | 112 | */ |
113 | unsigned char probe; | 113 | unsigned char probe; |
114 | struct mctrl_gpios *gpios; | ||
115 | #define UART_PROBE_RSA (1 << 0) | 114 | #define UART_PROBE_RSA (1 << 0) |
116 | 115 | ||
117 | /* | 116 | /* |
diff --git a/include/linux/smc91x.h b/include/linux/smc91x.h index 76199b75d584..e302c447e057 100644 --- a/include/linux/smc91x.h +++ b/include/linux/smc91x.h | |||
@@ -1,6 +1,16 @@ | |||
1 | #ifndef __SMC91X_H__ | 1 | #ifndef __SMC91X_H__ |
2 | #define __SMC91X_H__ | 2 | #define __SMC91X_H__ |
3 | 3 | ||
4 | /* | ||
5 | * These bits define which access sizes a platform can support, rather | ||
6 | * than the maximal access size. So, if your platform can do 16-bit | ||
7 | * and 32-bit accesses to the SMC91x device, but not 8-bit, set both | ||
8 | * SMC91X_USE_16BIT and SMC91X_USE_32BIT. | ||
9 | * | ||
10 | * The SMC91x driver requires at least one of SMC91X_USE_8BIT or | ||
11 | * SMC91X_USE_16BIT to be supported - just setting SMC91X_USE_32BIT is | ||
12 | * an invalid configuration. | ||
13 | */ | ||
4 | #define SMC91X_USE_8BIT (1 << 0) | 14 | #define SMC91X_USE_8BIT (1 << 0) |
5 | #define SMC91X_USE_16BIT (1 << 1) | 15 | #define SMC91X_USE_16BIT (1 << 1) |
6 | #define SMC91X_USE_32BIT (1 << 2) | 16 | #define SMC91X_USE_32BIT (1 << 2) |
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 697e160c78d0..a4f7203a9017 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h | |||
@@ -42,6 +42,8 @@ extern int proc_dostring(struct ctl_table *, int, | |||
42 | void __user *, size_t *, loff_t *); | 42 | void __user *, size_t *, loff_t *); |
43 | extern int proc_dointvec(struct ctl_table *, int, | 43 | extern int proc_dointvec(struct ctl_table *, int, |
44 | void __user *, size_t *, loff_t *); | 44 | void __user *, size_t *, loff_t *); |
45 | extern int proc_douintvec(struct ctl_table *, int, | ||
46 | void __user *, size_t *, loff_t *); | ||
45 | extern int proc_dointvec_minmax(struct ctl_table *, int, | 47 | extern int proc_dointvec_minmax(struct ctl_table *, int, |
46 | void __user *, size_t *, loff_t *); | 48 | void __user *, size_t *, loff_t *); |
47 | extern int proc_dointvec_jiffies(struct ctl_table *, int, | 49 | extern int proc_dointvec_jiffies(struct ctl_table *, int, |
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index cbd8990e2e77..2b5b10eed74f 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h | |||
@@ -118,10 +118,11 @@ static inline int arch_within_stack_frames(const void * const stack, | |||
118 | extern void __check_object_size(const void *ptr, unsigned long n, | 118 | extern void __check_object_size(const void *ptr, unsigned long n, |
119 | bool to_user); | 119 | bool to_user); |
120 | 120 | ||
121 | static inline void check_object_size(const void *ptr, unsigned long n, | 121 | static __always_inline void check_object_size(const void *ptr, unsigned long n, |
122 | bool to_user) | 122 | bool to_user) |
123 | { | 123 | { |
124 | __check_object_size(ptr, n, to_user); | 124 | if (!__builtin_constant_p(n)) |
125 | __check_object_size(ptr, n, to_user); | ||
125 | } | 126 | } |
126 | #else | 127 | #else |
127 | static inline void check_object_size(const void *ptr, unsigned long n, | 128 | static inline void check_object_size(const void *ptr, unsigned long n, |
diff --git a/include/linux/uio.h b/include/linux/uio.h index 1b5d1cd796e2..75b4aaf31a9d 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h | |||
@@ -76,7 +76,7 @@ size_t iov_iter_copy_from_user_atomic(struct page *page, | |||
76 | struct iov_iter *i, unsigned long offset, size_t bytes); | 76 | struct iov_iter *i, unsigned long offset, size_t bytes); |
77 | void iov_iter_advance(struct iov_iter *i, size_t bytes); | 77 | void iov_iter_advance(struct iov_iter *i, size_t bytes); |
78 | int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes); | 78 | int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes); |
79 | int iov_iter_fault_in_multipages_readable(struct iov_iter *i, size_t bytes); | 79 | #define iov_iter_fault_in_multipages_readable iov_iter_fault_in_readable |
80 | size_t iov_iter_single_seg_count(const struct iov_iter *i); | 80 | size_t iov_iter_single_seg_count(const struct iov_iter *i); |
81 | size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes, | 81 | size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes, |
82 | struct iov_iter *i); | 82 | struct iov_iter *i); |
diff --git a/include/media/cec.h b/include/media/cec.h index dc7854b855f3..fdb5d600e4bb 100644 --- a/include/media/cec.h +++ b/include/media/cec.h | |||
@@ -57,8 +57,8 @@ struct cec_devnode { | |||
57 | int minor; | 57 | int minor; |
58 | bool registered; | 58 | bool registered; |
59 | bool unregistered; | 59 | bool unregistered; |
60 | struct mutex fhs_lock; | ||
61 | struct list_head fhs; | 60 | struct list_head fhs; |
61 | struct mutex lock; | ||
62 | }; | 62 | }; |
63 | 63 | ||
64 | struct cec_adapter; | 64 | struct cec_adapter; |
diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 9b4c418bebd8..fd60eccb59a6 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h | |||
@@ -52,7 +52,7 @@ struct unix_sock { | |||
52 | struct sock sk; | 52 | struct sock sk; |
53 | struct unix_address *addr; | 53 | struct unix_address *addr; |
54 | struct path path; | 54 | struct path path; |
55 | struct mutex readlock; | 55 | struct mutex iolock, bindlock; |
56 | struct sock *peer; | 56 | struct sock *peer; |
57 | struct list_head link; | 57 | struct list_head link; |
58 | atomic_long_t inflight; | 58 | atomic_long_t inflight; |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 9c23f4d33e06..beb7610d64e9 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -1102,6 +1102,7 @@ struct station_info { | |||
1102 | struct cfg80211_tid_stats pertid[IEEE80211_NUM_TIDS + 1]; | 1102 | struct cfg80211_tid_stats pertid[IEEE80211_NUM_TIDS + 1]; |
1103 | }; | 1103 | }; |
1104 | 1104 | ||
1105 | #if IS_ENABLED(CONFIG_CFG80211) | ||
1105 | /** | 1106 | /** |
1106 | * cfg80211_get_station - retrieve information about a given station | 1107 | * cfg80211_get_station - retrieve information about a given station |
1107 | * @dev: the device where the station is supposed to be connected to | 1108 | * @dev: the device where the station is supposed to be connected to |
@@ -1114,6 +1115,14 @@ struct station_info { | |||
1114 | */ | 1115 | */ |
1115 | int cfg80211_get_station(struct net_device *dev, const u8 *mac_addr, | 1116 | int cfg80211_get_station(struct net_device *dev, const u8 *mac_addr, |
1116 | struct station_info *sinfo); | 1117 | struct station_info *sinfo); |
1118 | #else | ||
1119 | static inline int cfg80211_get_station(struct net_device *dev, | ||
1120 | const u8 *mac_addr, | ||
1121 | struct station_info *sinfo) | ||
1122 | { | ||
1123 | return -ENOENT; | ||
1124 | } | ||
1125 | #endif | ||
1117 | 1126 | ||
1118 | /** | 1127 | /** |
1119 | * enum monitor_flags - monitor flags | 1128 | * enum monitor_flags - monitor flags |
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 4079fc18ffe4..7d4a72e75f33 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h | |||
@@ -111,6 +111,7 @@ struct fib_info { | |||
111 | unsigned char fib_scope; | 111 | unsigned char fib_scope; |
112 | unsigned char fib_type; | 112 | unsigned char fib_type; |
113 | __be32 fib_prefsrc; | 113 | __be32 fib_prefsrc; |
114 | u32 fib_tb_id; | ||
114 | u32 fib_priority; | 115 | u32 fib_priority; |
115 | u32 *fib_metrics; | 116 | u32 *fib_metrics; |
116 | #define fib_mtu fib_metrics[RTAX_MTU-1] | 117 | #define fib_mtu fib_metrics[RTAX_MTU-1] |
@@ -319,7 +320,7 @@ void fib_flush_external(struct net *net); | |||
319 | /* Exported by fib_semantics.c */ | 320 | /* Exported by fib_semantics.c */ |
320 | int ip_fib_check_default(__be32 gw, struct net_device *dev); | 321 | int ip_fib_check_default(__be32 gw, struct net_device *dev); |
321 | int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force); | 322 | int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force); |
322 | int fib_sync_down_addr(struct net *net, __be32 local); | 323 | int fib_sync_down_addr(struct net_device *dev, __be32 local); |
323 | int fib_sync_up(struct net_device *dev, unsigned int nh_flags); | 324 | int fib_sync_up(struct net_device *dev, unsigned int nh_flags); |
324 | 325 | ||
325 | extern u32 fib_multipath_secret __read_mostly; | 326 | extern u32 fib_multipath_secret __read_mostly; |
diff --git a/include/net/netfilter/nf_conntrack_synproxy.h b/include/net/netfilter/nf_conntrack_synproxy.h index 6793614e6502..e6937318546c 100644 --- a/include/net/netfilter/nf_conntrack_synproxy.h +++ b/include/net/netfilter/nf_conntrack_synproxy.h | |||
@@ -27,6 +27,20 @@ static inline struct nf_conn_synproxy *nfct_synproxy_ext_add(struct nf_conn *ct) | |||
27 | #endif | 27 | #endif |
28 | } | 28 | } |
29 | 29 | ||
30 | static inline bool nf_ct_add_synproxy(struct nf_conn *ct, | ||
31 | const struct nf_conn *tmpl) | ||
32 | { | ||
33 | if (tmpl && nfct_synproxy(tmpl)) { | ||
34 | if (!nfct_seqadj_ext_add(ct)) | ||
35 | return false; | ||
36 | |||
37 | if (!nfct_synproxy_ext_add(ct)) | ||
38 | return false; | ||
39 | } | ||
40 | |||
41 | return true; | ||
42 | } | ||
43 | |||
30 | struct synproxy_stats { | 44 | struct synproxy_stats { |
31 | unsigned int syn_received; | 45 | unsigned int syn_received; |
32 | unsigned int cookie_invalid; | 46 | unsigned int cookie_invalid; |
diff --git a/include/net/netfilter/nft_meta.h b/include/net/netfilter/nft_meta.h index d27588c8dbd9..1139cde0fdc5 100644 --- a/include/net/netfilter/nft_meta.h +++ b/include/net/netfilter/nft_meta.h | |||
@@ -36,4 +36,8 @@ void nft_meta_set_eval(const struct nft_expr *expr, | |||
36 | void nft_meta_set_destroy(const struct nft_ctx *ctx, | 36 | void nft_meta_set_destroy(const struct nft_ctx *ctx, |
37 | const struct nft_expr *expr); | 37 | const struct nft_expr *expr); |
38 | 38 | ||
39 | int nft_meta_set_validate(const struct nft_ctx *ctx, | ||
40 | const struct nft_expr *expr, | ||
41 | const struct nft_data **data); | ||
42 | |||
39 | #endif | 43 | #endif |
diff --git a/include/net/netfilter/nft_reject.h b/include/net/netfilter/nft_reject.h index 60fa1530006b..02e28c529b29 100644 --- a/include/net/netfilter/nft_reject.h +++ b/include/net/netfilter/nft_reject.h | |||
@@ -8,6 +8,10 @@ struct nft_reject { | |||
8 | 8 | ||
9 | extern const struct nla_policy nft_reject_policy[]; | 9 | extern const struct nla_policy nft_reject_policy[]; |
10 | 10 | ||
11 | int nft_reject_validate(const struct nft_ctx *ctx, | ||
12 | const struct nft_expr *expr, | ||
13 | const struct nft_data **data); | ||
14 | |||
11 | int nft_reject_init(const struct nft_ctx *ctx, | 15 | int nft_reject_init(const struct nft_ctx *ctx, |
12 | const struct nft_expr *expr, | 16 | const struct nft_expr *expr, |
13 | const struct nlattr * const tb[]); | 17 | const struct nlattr * const tb[]); |
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index efc01743b9d6..bafe2a0ab908 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h | |||
@@ -382,7 +382,7 @@ enum { | |||
382 | ADDIP_SERIAL_SIGN_BIT = (1<<31) | 382 | ADDIP_SERIAL_SIGN_BIT = (1<<31) |
383 | }; | 383 | }; |
384 | 384 | ||
385 | static inline int ADDIP_SERIAL_gte(__u16 s, __u16 t) | 385 | static inline int ADDIP_SERIAL_gte(__u32 s, __u32 t) |
386 | { | 386 | { |
387 | return ((s) == (t)) || (((t) - (s)) & ADDIP_SERIAL_SIGN_BIT); | 387 | return ((s) == (t)) || (((t) - (s)) & ADDIP_SERIAL_SIGN_BIT); |
388 | } | 388 | } |
diff --git a/include/net/sock.h b/include/net/sock.h index ff5be7e8ddea..8741988e6880 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -1332,6 +1332,16 @@ static inline void sk_mem_uncharge(struct sock *sk, int size) | |||
1332 | if (!sk_has_account(sk)) | 1332 | if (!sk_has_account(sk)) |
1333 | return; | 1333 | return; |
1334 | sk->sk_forward_alloc += size; | 1334 | sk->sk_forward_alloc += size; |
1335 | |||
1336 | /* Avoid a possible overflow. | ||
1337 | * TCP send queues can make this happen, if sk_mem_reclaim() | ||
1338 | * is not called and more than 2 GBytes are released at once. | ||
1339 | * | ||
1340 | * If we reach 2 MBytes, reclaim 1 MBytes right now, there is | ||
1341 | * no need to hold that much forward allocation anyway. | ||
1342 | */ | ||
1343 | if (unlikely(sk->sk_forward_alloc >= 1 << 21)) | ||
1344 | __sk_mem_reclaim(sk, 1 << 20); | ||
1335 | } | 1345 | } |
1336 | 1346 | ||
1337 | static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb) | 1347 | static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb) |
diff --git a/include/net/tcp.h b/include/net/tcp.h index c00e7d51bb18..7717302cab91 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -1523,6 +1523,8 @@ static inline void tcp_check_send_head(struct sock *sk, struct sk_buff *skb_unli | |||
1523 | { | 1523 | { |
1524 | if (sk->sk_send_head == skb_unlinked) | 1524 | if (sk->sk_send_head == skb_unlinked) |
1525 | sk->sk_send_head = NULL; | 1525 | sk->sk_send_head = NULL; |
1526 | if (tcp_sk(sk)->highest_sack == skb_unlinked) | ||
1527 | tcp_sk(sk)->highest_sack = NULL; | ||
1526 | } | 1528 | } |
1527 | 1529 | ||
1528 | static inline void tcp_init_send_head(struct sock *sk) | 1530 | static inline void tcp_init_send_head(struct sock *sk) |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index adfebd6f243c..17934312eecb 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -1540,8 +1540,10 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family); | |||
1540 | void xfrm4_local_error(struct sk_buff *skb, u32 mtu); | 1540 | void xfrm4_local_error(struct sk_buff *skb, u32 mtu); |
1541 | int xfrm6_extract_header(struct sk_buff *skb); | 1541 | int xfrm6_extract_header(struct sk_buff *skb); |
1542 | int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb); | 1542 | int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb); |
1543 | int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi); | 1543 | int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi, |
1544 | struct ip6_tnl *t); | ||
1544 | int xfrm6_transport_finish(struct sk_buff *skb, int async); | 1545 | int xfrm6_transport_finish(struct sk_buff *skb, int async); |
1546 | int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t); | ||
1545 | int xfrm6_rcv(struct sk_buff *skb); | 1547 | int xfrm6_rcv(struct sk_buff *skb); |
1546 | int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | 1548 | int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, |
1547 | xfrm_address_t *saddr, u8 proto); | 1549 | xfrm_address_t *saddr, u8 proto); |
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 8e90dd28bb75..e1f96737c2a1 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h | |||
@@ -2115,22 +2115,17 @@ static inline bool ib_is_udata_cleared(struct ib_udata *udata, | |||
2115 | size_t len) | 2115 | size_t len) |
2116 | { | 2116 | { |
2117 | const void __user *p = udata->inbuf + offset; | 2117 | const void __user *p = udata->inbuf + offset; |
2118 | bool ret = false; | 2118 | bool ret; |
2119 | u8 *buf; | 2119 | u8 *buf; |
2120 | 2120 | ||
2121 | if (len > USHRT_MAX) | 2121 | if (len > USHRT_MAX) |
2122 | return false; | 2122 | return false; |
2123 | 2123 | ||
2124 | buf = kmalloc(len, GFP_KERNEL); | 2124 | buf = memdup_user(p, len); |
2125 | if (!buf) | 2125 | if (IS_ERR(buf)) |
2126 | return false; | 2126 | return false; |
2127 | 2127 | ||
2128 | if (copy_from_user(buf, p, len)) | ||
2129 | goto free; | ||
2130 | |||
2131 | ret = !memchr_inv(buf, 0, len); | 2128 | ret = !memchr_inv(buf, 0, len); |
2132 | |||
2133 | free: | ||
2134 | kfree(buf); | 2129 | kfree(buf); |
2135 | return ret; | 2130 | return ret; |
2136 | } | 2131 | } |
diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index 13c0b2ba1b6c..73d870918939 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h | |||
@@ -11,12 +11,12 @@ struct sas_rphy; | |||
11 | struct request; | 11 | struct request; |
12 | 12 | ||
13 | #if !IS_ENABLED(CONFIG_SCSI_SAS_ATTRS) | 13 | #if !IS_ENABLED(CONFIG_SCSI_SAS_ATTRS) |
14 | static inline int is_sas_attached(struct scsi_device *sdev) | 14 | static inline int scsi_is_sas_rphy(const struct device *sdev) |
15 | { | 15 | { |
16 | return 0; | 16 | return 0; |
17 | } | 17 | } |
18 | #else | 18 | #else |
19 | extern int is_sas_attached(struct scsi_device *sdev); | 19 | extern int scsi_is_sas_rphy(const struct device *); |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | static inline int sas_protocol_ata(enum sas_protocol proto) | 22 | static inline int sas_protocol_ata(enum sas_protocol proto) |
@@ -202,7 +202,6 @@ extern int sas_rphy_add(struct sas_rphy *); | |||
202 | extern void sas_rphy_remove(struct sas_rphy *); | 202 | extern void sas_rphy_remove(struct sas_rphy *); |
203 | extern void sas_rphy_delete(struct sas_rphy *); | 203 | extern void sas_rphy_delete(struct sas_rphy *); |
204 | extern void sas_rphy_unlink(struct sas_rphy *); | 204 | extern void sas_rphy_unlink(struct sas_rphy *); |
205 | extern int scsi_is_sas_rphy(const struct device *); | ||
206 | 205 | ||
207 | struct sas_port *sas_port_alloc(struct device *, int); | 206 | struct sas_port *sas_port_alloc(struct device *, int); |
208 | struct sas_port *sas_port_alloc_num(struct device *); | 207 | struct sas_port *sas_port_alloc_num(struct device *); |
diff --git a/include/sound/da7219.h b/include/sound/da7219.h index 02876acdc840..409ef1397fd3 100644 --- a/include/sound/da7219.h +++ b/include/sound/da7219.h | |||
@@ -34,6 +34,8 @@ enum da7219_mic_amp_in_sel { | |||
34 | struct da7219_aad_pdata; | 34 | struct da7219_aad_pdata; |
35 | 35 | ||
36 | struct da7219_pdata { | 36 | struct da7219_pdata { |
37 | bool wakeup_source; | ||
38 | |||
37 | /* Mic */ | 39 | /* Mic */ |
38 | enum da7219_micbias_voltage micbias_lvl; | 40 | enum da7219_micbias_voltage micbias_lvl; |
39 | enum da7219_mic_amp_in_sel mic_amp_in_sel; | 41 | enum da7219_mic_amp_in_sel mic_amp_in_sel; |
diff --git a/include/sound/l3.h b/include/sound/l3.h index 423a08f0f1b0..1471da22adad 100644 --- a/include/sound/l3.h +++ b/include/sound/l3.h | |||
@@ -2,9 +2,15 @@ | |||
2 | #define _L3_H_ 1 | 2 | #define _L3_H_ 1 |
3 | 3 | ||
4 | struct l3_pins { | 4 | struct l3_pins { |
5 | void (*setdat)(int); | 5 | void (*setdat)(struct l3_pins *, int); |
6 | void (*setclk)(int); | 6 | void (*setclk)(struct l3_pins *, int); |
7 | void (*setmode)(int); | 7 | void (*setmode)(struct l3_pins *, int); |
8 | |||
9 | int gpio_data; | ||
10 | int gpio_clk; | ||
11 | int gpio_mode; | ||
12 | int use_gpios; | ||
13 | |||
8 | int data_hold; | 14 | int data_hold; |
9 | int data_setup; | 15 | int data_setup; |
10 | int clock_high; | 16 | int clock_high; |
@@ -13,6 +19,9 @@ struct l3_pins { | |||
13 | int mode_setup; | 19 | int mode_setup; |
14 | }; | 20 | }; |
15 | 21 | ||
22 | struct device; | ||
23 | |||
16 | int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len); | 24 | int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len); |
25 | int l3_set_gpio_ops(struct device *dev, struct l3_pins *adap); | ||
17 | 26 | ||
18 | #endif | 27 | #endif |
diff --git a/include/sound/rt5660.h b/include/sound/rt5660.h new file mode 100644 index 000000000000..065f83a24db6 --- /dev/null +++ b/include/sound/rt5660.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * linux/sound/rt5660.h -- Platform data for RT5660 | ||
3 | * | ||
4 | * Copyright 2016 Realtek Semiconductor Corp. | ||
5 | * Author: Oder Chiou <oder_chiou@realtek.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 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef __LINUX_SND_RT5660_H | ||
13 | #define __LINUX_SND_RT5660_H | ||
14 | |||
15 | enum rt5660_dmic1_data_pin { | ||
16 | RT5660_DMIC1_NULL, | ||
17 | RT5660_DMIC1_DATA_GPIO2, | ||
18 | RT5660_DMIC1_DATA_IN1P, | ||
19 | }; | ||
20 | |||
21 | struct rt5660_platform_data { | ||
22 | /* IN1 & IN3 can optionally be differential */ | ||
23 | bool in1_diff; | ||
24 | bool in3_diff; | ||
25 | bool use_ldo2; | ||
26 | bool poweroff_codec_in_suspend; | ||
27 | |||
28 | enum rt5660_dmic1_data_pin dmic1_data_pin; | ||
29 | }; | ||
30 | |||
31 | #endif | ||
diff --git a/include/sound/s3c24xx_uda134x.h b/include/sound/s3c24xx_uda134x.h index 33df4cb909d3..ffaf1f098c8e 100644 --- a/include/sound/s3c24xx_uda134x.h +++ b/include/sound/s3c24xx_uda134x.h | |||
@@ -7,7 +7,6 @@ struct s3c24xx_uda134x_platform_data { | |||
7 | int l3_clk; | 7 | int l3_clk; |
8 | int l3_mode; | 8 | int l3_mode; |
9 | int l3_data; | 9 | int l3_data; |
10 | void (*power) (int); | ||
11 | int model; | 10 | int model; |
12 | }; | 11 | }; |
13 | 12 | ||
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h index 86088aed9002..fd6412551145 100644 --- a/include/sound/simple_card_utils.h +++ b/include/sound/simple_card_utils.h | |||
@@ -27,10 +27,45 @@ int asoc_simple_card_parse_daifmt(struct device *dev, | |||
27 | struct device_node *codec, | 27 | struct device_node *codec, |
28 | char *prefix, | 28 | char *prefix, |
29 | unsigned int *retfmt); | 29 | unsigned int *retfmt); |
30 | __printf(3, 4) | ||
30 | int asoc_simple_card_set_dailink_name(struct device *dev, | 31 | int asoc_simple_card_set_dailink_name(struct device *dev, |
31 | struct snd_soc_dai_link *dai_link, | 32 | struct snd_soc_dai_link *dai_link, |
32 | const char *fmt, ...); | 33 | const char *fmt, ...); |
33 | int asoc_simple_card_parse_card_name(struct snd_soc_card *card, | 34 | int asoc_simple_card_parse_card_name(struct snd_soc_card *card, |
34 | char *prefix); | 35 | char *prefix); |
35 | 36 | ||
37 | #define asoc_simple_card_parse_clk_cpu(node, dai_link, simple_dai) \ | ||
38 | asoc_simple_card_parse_clk(node, dai_link->cpu_of_node, simple_dai) | ||
39 | #define asoc_simple_card_parse_clk_codec(node, dai_link, simple_dai) \ | ||
40 | asoc_simple_card_parse_clk(node, dai_link->codec_of_node, simple_dai) | ||
41 | int asoc_simple_card_parse_clk(struct device_node *node, | ||
42 | struct device_node *dai_of_node, | ||
43 | struct asoc_simple_dai *simple_dai); | ||
44 | |||
45 | #define asoc_simple_card_parse_cpu(node, dai_link, \ | ||
46 | list_name, cells_name, is_single_link) \ | ||
47 | asoc_simple_card_parse_dai(node, &dai_link->cpu_of_node, \ | ||
48 | &dai_link->cpu_dai_name, list_name, cells_name, is_single_link) | ||
49 | #define asoc_simple_card_parse_codec(node, dai_link, list_name, cells_name) \ | ||
50 | asoc_simple_card_parse_dai(node, &dai_link->codec_of_node, \ | ||
51 | &dai_link->codec_dai_name, list_name, cells_name, NULL) | ||
52 | #define asoc_simple_card_parse_platform(node, dai_link, list_name, cells_name) \ | ||
53 | asoc_simple_card_parse_dai(node, &dai_link->platform_of_node, \ | ||
54 | NULL, list_name, cells_name, NULL) | ||
55 | int asoc_simple_card_parse_dai(struct device_node *node, | ||
56 | struct device_node **endpoint_np, | ||
57 | const char **dai_name, | ||
58 | const char *list_name, | ||
59 | const char *cells_name, | ||
60 | int *is_single_links); | ||
61 | |||
62 | int asoc_simple_card_init_dai(struct snd_soc_dai *dai, | ||
63 | struct asoc_simple_dai *simple_dai); | ||
64 | |||
65 | int asoc_simple_card_canonicalize_dailink(struct snd_soc_dai_link *dai_link); | ||
66 | void asoc_simple_card_canonicalize_cpu(struct snd_soc_dai_link *dai_link, | ||
67 | int is_single_links); | ||
68 | |||
69 | int asoc_simple_card_clean_reference(struct snd_soc_card *card); | ||
70 | |||
36 | #endif /* __SIMPLE_CARD_CORE_H */ | 71 | #endif /* __SIMPLE_CARD_CORE_H */ |
diff --git a/include/sound/soc.h b/include/sound/soc.h index 6144882cc96a..4f1c784e44f6 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -898,14 +898,6 @@ struct snd_soc_codec_driver { | |||
898 | int (*resume)(struct snd_soc_codec *); | 898 | int (*resume)(struct snd_soc_codec *); |
899 | struct snd_soc_component_driver component_driver; | 899 | struct snd_soc_component_driver component_driver; |
900 | 900 | ||
901 | /* Default control and setup, added after probe() is run */ | ||
902 | const struct snd_kcontrol_new *controls; | ||
903 | int num_controls; | ||
904 | const struct snd_soc_dapm_widget *dapm_widgets; | ||
905 | int num_dapm_widgets; | ||
906 | const struct snd_soc_dapm_route *dapm_routes; | ||
907 | int num_dapm_routes; | ||
908 | |||
909 | /* codec wide operations */ | 901 | /* codec wide operations */ |
910 | int (*set_sysclk)(struct snd_soc_codec *codec, | 902 | int (*set_sysclk)(struct snd_soc_codec *codec, |
911 | int clk_id, int source, unsigned int freq, int dir); | 903 | int clk_id, int source, unsigned int freq, int dir); |
@@ -1547,17 +1539,6 @@ static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platfo | |||
1547 | return snd_soc_component_get_drvdata(&platform->component); | 1539 | return snd_soc_component_get_drvdata(&platform->component); |
1548 | } | 1540 | } |
1549 | 1541 | ||
1550 | static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd, | ||
1551 | void *data) | ||
1552 | { | ||
1553 | dev_set_drvdata(rtd->dev, data); | ||
1554 | } | ||
1555 | |||
1556 | static inline void *snd_soc_pcm_get_drvdata(struct snd_soc_pcm_runtime *rtd) | ||
1557 | { | ||
1558 | return dev_get_drvdata(rtd->dev); | ||
1559 | } | ||
1560 | |||
1561 | static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card) | 1542 | static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card) |
1562 | { | 1543 | { |
1563 | INIT_LIST_HEAD(&card->codec_dev_list); | 1544 | INIT_LIST_HEAD(&card->codec_dev_list); |
diff --git a/include/uapi/linux/atm_zatm.h b/include/uapi/linux/atm_zatm.h index 9c9c6ad55f14..5cd4d4d2dd1d 100644 --- a/include/uapi/linux/atm_zatm.h +++ b/include/uapi/linux/atm_zatm.h | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include <linux/atmapi.h> | 15 | #include <linux/atmapi.h> |
16 | #include <linux/atmioc.h> | 16 | #include <linux/atmioc.h> |
17 | #include <linux/time.h> | ||
17 | 18 | ||
18 | #define ZATM_GETPOOL _IOW('a',ATMIOC_SARPRV+1,struct atmif_sioc) | 19 | #define ZATM_GETPOOL _IOW('a',ATMIOC_SARPRV+1,struct atmif_sioc) |
19 | /* get pool statistics */ | 20 | /* get pool statistics */ |
diff --git a/include/uapi/linux/if_pppol2tp.h b/include/uapi/linux/if_pppol2tp.h index 163e8adac2d6..4bd1f55d6377 100644 --- a/include/uapi/linux/if_pppol2tp.h +++ b/include/uapi/linux/if_pppol2tp.h | |||
@@ -16,7 +16,8 @@ | |||
16 | #define _UAPI__LINUX_IF_PPPOL2TP_H | 16 | #define _UAPI__LINUX_IF_PPPOL2TP_H |
17 | 17 | ||
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | 19 | #include <linux/in.h> | |
20 | #include <linux/in6.h> | ||
20 | 21 | ||
21 | /* Structure used to connect() the socket to a particular tunnel UDP | 22 | /* Structure used to connect() the socket to a particular tunnel UDP |
22 | * socket over IPv4. | 23 | * socket over IPv4. |
diff --git a/include/uapi/linux/if_pppox.h b/include/uapi/linux/if_pppox.h index e128769331b5..d37bbb17a007 100644 --- a/include/uapi/linux/if_pppox.h +++ b/include/uapi/linux/if_pppox.h | |||
@@ -21,8 +21,11 @@ | |||
21 | #include <asm/byteorder.h> | 21 | #include <asm/byteorder.h> |
22 | 22 | ||
23 | #include <linux/socket.h> | 23 | #include <linux/socket.h> |
24 | #include <linux/if.h> | ||
24 | #include <linux/if_ether.h> | 25 | #include <linux/if_ether.h> |
25 | #include <linux/if_pppol2tp.h> | 26 | #include <linux/if_pppol2tp.h> |
27 | #include <linux/in.h> | ||
28 | #include <linux/in6.h> | ||
26 | 29 | ||
27 | /* For user-space programs to pick up these definitions | 30 | /* For user-space programs to pick up these definitions |
28 | * which they wouldn't get otherwise without defining __KERNEL__ | 31 | * which they wouldn't get otherwise without defining __KERNEL__ |
diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h index 1046f5515174..777b6cdb1b7b 100644 --- a/include/uapi/linux/if_tunnel.h +++ b/include/uapi/linux/if_tunnel.h | |||
@@ -2,6 +2,9 @@ | |||
2 | #define _UAPI_IF_TUNNEL_H_ | 2 | #define _UAPI_IF_TUNNEL_H_ |
3 | 3 | ||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #include <linux/if.h> | ||
6 | #include <linux/ip.h> | ||
7 | #include <linux/in6.h> | ||
5 | #include <asm/byteorder.h> | 8 | #include <asm/byteorder.h> |
6 | 9 | ||
7 | 10 | ||
diff --git a/include/uapi/linux/ipx.h b/include/uapi/linux/ipx.h index 3d48014cdd71..30f031db12f6 100644 --- a/include/uapi/linux/ipx.h +++ b/include/uapi/linux/ipx.h | |||
@@ -1,11 +1,13 @@ | |||
1 | #ifndef _IPX_H_ | 1 | #ifndef _IPX_H_ |
2 | #define _IPX_H_ | 2 | #define _IPX_H_ |
3 | #include <linux/libc-compat.h> /* for compatibility with glibc netipx/ipx.h */ | ||
3 | #include <linux/types.h> | 4 | #include <linux/types.h> |
4 | #include <linux/sockios.h> | 5 | #include <linux/sockios.h> |
5 | #include <linux/socket.h> | 6 | #include <linux/socket.h> |
6 | #define IPX_NODE_LEN 6 | 7 | #define IPX_NODE_LEN 6 |
7 | #define IPX_MTU 576 | 8 | #define IPX_MTU 576 |
8 | 9 | ||
10 | #if __UAPI_DEF_SOCKADDR_IPX | ||
9 | struct sockaddr_ipx { | 11 | struct sockaddr_ipx { |
10 | __kernel_sa_family_t sipx_family; | 12 | __kernel_sa_family_t sipx_family; |
11 | __be16 sipx_port; | 13 | __be16 sipx_port; |
@@ -14,6 +16,7 @@ struct sockaddr_ipx { | |||
14 | __u8 sipx_type; | 16 | __u8 sipx_type; |
15 | unsigned char sipx_zero; /* 16 byte fill */ | 17 | unsigned char sipx_zero; /* 16 byte fill */ |
16 | }; | 18 | }; |
19 | #endif /* __UAPI_DEF_SOCKADDR_IPX */ | ||
17 | 20 | ||
18 | /* | 21 | /* |
19 | * So we can fit the extra info for SIOCSIFADDR into the address nicely | 22 | * So we can fit the extra info for SIOCSIFADDR into the address nicely |
@@ -23,12 +26,15 @@ struct sockaddr_ipx { | |||
23 | #define IPX_DLTITF 0 | 26 | #define IPX_DLTITF 0 |
24 | #define IPX_CRTITF 1 | 27 | #define IPX_CRTITF 1 |
25 | 28 | ||
29 | #if __UAPI_DEF_IPX_ROUTE_DEFINITION | ||
26 | struct ipx_route_definition { | 30 | struct ipx_route_definition { |
27 | __be32 ipx_network; | 31 | __be32 ipx_network; |
28 | __be32 ipx_router_network; | 32 | __be32 ipx_router_network; |
29 | unsigned char ipx_router_node[IPX_NODE_LEN]; | 33 | unsigned char ipx_router_node[IPX_NODE_LEN]; |
30 | }; | 34 | }; |
35 | #endif /* __UAPI_DEF_IPX_ROUTE_DEFINITION */ | ||
31 | 36 | ||
37 | #if __UAPI_DEF_IPX_INTERFACE_DEFINITION | ||
32 | struct ipx_interface_definition { | 38 | struct ipx_interface_definition { |
33 | __be32 ipx_network; | 39 | __be32 ipx_network; |
34 | unsigned char ipx_device[16]; | 40 | unsigned char ipx_device[16]; |
@@ -45,16 +51,20 @@ struct ipx_interface_definition { | |||
45 | #define IPX_INTERNAL 2 | 51 | #define IPX_INTERNAL 2 |
46 | unsigned char ipx_node[IPX_NODE_LEN]; | 52 | unsigned char ipx_node[IPX_NODE_LEN]; |
47 | }; | 53 | }; |
48 | 54 | #endif /* __UAPI_DEF_IPX_INTERFACE_DEFINITION */ | |
55 | |||
56 | #if __UAPI_DEF_IPX_CONFIG_DATA | ||
49 | struct ipx_config_data { | 57 | struct ipx_config_data { |
50 | unsigned char ipxcfg_auto_select_primary; | 58 | unsigned char ipxcfg_auto_select_primary; |
51 | unsigned char ipxcfg_auto_create_interfaces; | 59 | unsigned char ipxcfg_auto_create_interfaces; |
52 | }; | 60 | }; |
61 | #endif /* __UAPI_DEF_IPX_CONFIG_DATA */ | ||
53 | 62 | ||
54 | /* | 63 | /* |
55 | * OLD Route Definition for backward compatibility. | 64 | * OLD Route Definition for backward compatibility. |
56 | */ | 65 | */ |
57 | 66 | ||
67 | #if __UAPI_DEF_IPX_ROUTE_DEF | ||
58 | struct ipx_route_def { | 68 | struct ipx_route_def { |
59 | __be32 ipx_network; | 69 | __be32 ipx_network; |
60 | __be32 ipx_router_network; | 70 | __be32 ipx_router_network; |
@@ -67,6 +77,7 @@ struct ipx_route_def { | |||
67 | #define IPX_RT_BLUEBOOK 2 | 77 | #define IPX_RT_BLUEBOOK 2 |
68 | #define IPX_RT_ROUTED 1 | 78 | #define IPX_RT_ROUTED 1 |
69 | }; | 79 | }; |
80 | #endif /* __UAPI_DEF_IPX_ROUTE_DEF */ | ||
70 | 81 | ||
71 | #define SIOCAIPXITFCRT (SIOCPROTOPRIVATE) | 82 | #define SIOCAIPXITFCRT (SIOCPROTOPRIVATE) |
72 | #define SIOCAIPXPRISLT (SIOCPROTOPRIVATE + 1) | 83 | #define SIOCAIPXPRISLT (SIOCPROTOPRIVATE + 1) |
diff --git a/include/uapi/linux/libc-compat.h b/include/uapi/linux/libc-compat.h index e4f048ee7043..44b8a6bd5fe1 100644 --- a/include/uapi/linux/libc-compat.h +++ b/include/uapi/linux/libc-compat.h | |||
@@ -139,6 +139,25 @@ | |||
139 | 139 | ||
140 | #endif /* _NETINET_IN_H */ | 140 | #endif /* _NETINET_IN_H */ |
141 | 141 | ||
142 | /* Coordinate with glibc netipx/ipx.h header. */ | ||
143 | #if defined(__NETIPX_IPX_H) | ||
144 | |||
145 | #define __UAPI_DEF_SOCKADDR_IPX 0 | ||
146 | #define __UAPI_DEF_IPX_ROUTE_DEFINITION 0 | ||
147 | #define __UAPI_DEF_IPX_INTERFACE_DEFINITION 0 | ||
148 | #define __UAPI_DEF_IPX_CONFIG_DATA 0 | ||
149 | #define __UAPI_DEF_IPX_ROUTE_DEF 0 | ||
150 | |||
151 | #else /* defined(__NETIPX_IPX_H) */ | ||
152 | |||
153 | #define __UAPI_DEF_SOCKADDR_IPX 1 | ||
154 | #define __UAPI_DEF_IPX_ROUTE_DEFINITION 1 | ||
155 | #define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1 | ||
156 | #define __UAPI_DEF_IPX_CONFIG_DATA 1 | ||
157 | #define __UAPI_DEF_IPX_ROUTE_DEF 1 | ||
158 | |||
159 | #endif /* defined(__NETIPX_IPX_H) */ | ||
160 | |||
142 | /* Definitions for xattr.h */ | 161 | /* Definitions for xattr.h */ |
143 | #if defined(_SYS_XATTR_H) | 162 | #if defined(_SYS_XATTR_H) |
144 | #define __UAPI_DEF_XATTR 0 | 163 | #define __UAPI_DEF_XATTR 0 |
@@ -179,6 +198,13 @@ | |||
179 | #define __UAPI_DEF_IN6_PKTINFO 1 | 198 | #define __UAPI_DEF_IN6_PKTINFO 1 |
180 | #define __UAPI_DEF_IP6_MTUINFO 1 | 199 | #define __UAPI_DEF_IP6_MTUINFO 1 |
181 | 200 | ||
201 | /* Definitions for ipx.h */ | ||
202 | #define __UAPI_DEF_SOCKADDR_IPX 1 | ||
203 | #define __UAPI_DEF_IPX_ROUTE_DEFINITION 1 | ||
204 | #define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1 | ||
205 | #define __UAPI_DEF_IPX_CONFIG_DATA 1 | ||
206 | #define __UAPI_DEF_IPX_ROUTE_DEF 1 | ||
207 | |||
182 | /* Definitions for xattr.h */ | 208 | /* Definitions for xattr.h */ |
183 | #define __UAPI_DEF_XATTR 1 | 209 | #define __UAPI_DEF_XATTR 1 |
184 | 210 | ||
diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h index d95a3018f6a1..54c3b4f4aceb 100644 --- a/include/uapi/linux/openvswitch.h +++ b/include/uapi/linux/openvswitch.h | |||
@@ -583,7 +583,7 @@ enum ovs_userspace_attr { | |||
583 | #define OVS_USERSPACE_ATTR_MAX (__OVS_USERSPACE_ATTR_MAX - 1) | 583 | #define OVS_USERSPACE_ATTR_MAX (__OVS_USERSPACE_ATTR_MAX - 1) |
584 | 584 | ||
585 | struct ovs_action_trunc { | 585 | struct ovs_action_trunc { |
586 | uint32_t max_len; /* Max packet size in bytes. */ | 586 | __u32 max_len; /* Max packet size in bytes. */ |
587 | }; | 587 | }; |
588 | 588 | ||
589 | /** | 589 | /** |
@@ -632,8 +632,8 @@ enum ovs_hash_alg { | |||
632 | * @hash_basis: basis used for computing hash. | 632 | * @hash_basis: basis used for computing hash. |
633 | */ | 633 | */ |
634 | struct ovs_action_hash { | 634 | struct ovs_action_hash { |
635 | uint32_t hash_alg; /* One of ovs_hash_alg. */ | 635 | __u32 hash_alg; /* One of ovs_hash_alg. */ |
636 | uint32_t hash_basis; | 636 | __u32 hash_basis; |
637 | }; | 637 | }; |
638 | 638 | ||
639 | /** | 639 | /** |
diff --git a/include/uapi/sound/Kbuild b/include/uapi/sound/Kbuild index 691984cb0b91..9578d8bdbf31 100644 --- a/include/uapi/sound/Kbuild +++ b/include/uapi/sound/Kbuild | |||
@@ -13,3 +13,4 @@ header-y += sb16_csp.h | |||
13 | header-y += sfnt_info.h | 13 | header-y += sfnt_info.h |
14 | header-y += tlv.h | 14 | header-y += tlv.h |
15 | header-y += usb_stream.h | 15 | header-y += usb_stream.h |
16 | header-y += snd_sst_tokens.h | ||
diff --git a/include/uapi/sound/asoc.h b/include/uapi/sound/asoc.h index e4701a3c6331..33d00a4ce656 100644 --- a/include/uapi/sound/asoc.h +++ b/include/uapi/sound/asoc.h | |||
@@ -83,7 +83,7 @@ | |||
83 | #define SND_SOC_TPLG_NUM_TEXTS 16 | 83 | #define SND_SOC_TPLG_NUM_TEXTS 16 |
84 | 84 | ||
85 | /* ABI version */ | 85 | /* ABI version */ |
86 | #define SND_SOC_TPLG_ABI_VERSION 0x4 | 86 | #define SND_SOC_TPLG_ABI_VERSION 0x5 |
87 | 87 | ||
88 | /* Max size of TLV data */ | 88 | /* Max size of TLV data */ |
89 | #define SND_SOC_TPLG_TLV_SIZE 32 | 89 | #define SND_SOC_TPLG_TLV_SIZE 32 |
@@ -105,7 +105,8 @@ | |||
105 | #define SND_SOC_TPLG_TYPE_CODEC_LINK 9 | 105 | #define SND_SOC_TPLG_TYPE_CODEC_LINK 9 |
106 | #define SND_SOC_TPLG_TYPE_BACKEND_LINK 10 | 106 | #define SND_SOC_TPLG_TYPE_BACKEND_LINK 10 |
107 | #define SND_SOC_TPLG_TYPE_PDATA 11 | 107 | #define SND_SOC_TPLG_TYPE_PDATA 11 |
108 | #define SND_SOC_TPLG_TYPE_MAX SND_SOC_TPLG_TYPE_PDATA | 108 | #define SND_SOC_TPLG_TYPE_BE_DAI 12 |
109 | #define SND_SOC_TPLG_TYPE_MAX SND_SOC_TPLG_TYPE_BE_DAI | ||
109 | 110 | ||
110 | /* vendor block IDs - please add new vendor types to end */ | 111 | /* vendor block IDs - please add new vendor types to end */ |
111 | #define SND_SOC_TPLG_TYPE_VENDOR_FW 1000 | 112 | #define SND_SOC_TPLG_TYPE_VENDOR_FW 1000 |
@@ -124,6 +125,11 @@ | |||
124 | #define SND_SOC_TPLG_TUPLE_TYPE_WORD 4 | 125 | #define SND_SOC_TPLG_TUPLE_TYPE_WORD 4 |
125 | #define SND_SOC_TPLG_TUPLE_TYPE_SHORT 5 | 126 | #define SND_SOC_TPLG_TUPLE_TYPE_SHORT 5 |
126 | 127 | ||
128 | /* BE DAI flags */ | ||
129 | #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES (1 << 0) | ||
130 | #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS (1 << 1) | ||
131 | #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS (1 << 2) | ||
132 | |||
127 | /* | 133 | /* |
128 | * Block Header. | 134 | * Block Header. |
129 | * This header precedes all object and object arrays below. | 135 | * This header precedes all object and object arrays below. |
@@ -251,6 +257,7 @@ struct snd_soc_tplg_stream_caps { | |||
251 | __le32 period_size_max; /* max period size bytes */ | 257 | __le32 period_size_max; /* max period size bytes */ |
252 | __le32 buffer_size_min; /* min buffer size bytes */ | 258 | __le32 buffer_size_min; /* min buffer size bytes */ |
253 | __le32 buffer_size_max; /* max buffer size bytes */ | 259 | __le32 buffer_size_max; /* max buffer size bytes */ |
260 | __le32 sig_bits; /* number of bits of content */ | ||
254 | } __attribute__((packed)); | 261 | } __attribute__((packed)); |
255 | 262 | ||
256 | /* | 263 | /* |
@@ -285,6 +292,8 @@ struct snd_soc_tplg_manifest { | |||
285 | __le32 graph_elems; /* number of graph elements */ | 292 | __le32 graph_elems; /* number of graph elements */ |
286 | __le32 pcm_elems; /* number of PCM elements */ | 293 | __le32 pcm_elems; /* number of PCM elements */ |
287 | __le32 dai_link_elems; /* number of DAI link elements */ | 294 | __le32 dai_link_elems; /* number of DAI link elements */ |
295 | __le32 be_dai_elems; /* number of BE DAI elements */ | ||
296 | __le32 reserved[20]; /* reserved for new ABI element types */ | ||
288 | struct snd_soc_tplg_private priv; | 297 | struct snd_soc_tplg_private priv; |
289 | } __attribute__((packed)); | 298 | } __attribute__((packed)); |
290 | 299 | ||
@@ -450,4 +459,26 @@ struct snd_soc_tplg_link_config { | |||
450 | struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */ | 459 | struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */ |
451 | __le32 num_streams; /* number of streams */ | 460 | __le32 num_streams; /* number of streams */ |
452 | } __attribute__((packed)); | 461 | } __attribute__((packed)); |
462 | |||
463 | /* | ||
464 | * Describes SW/FW specific features of BE DAI. | ||
465 | * | ||
466 | * File block representation for BE DAI :- | ||
467 | * +-----------------------------------+-----+ | ||
468 | * | struct snd_soc_tplg_hdr | 1 | | ||
469 | * +-----------------------------------+-----+ | ||
470 | * | struct snd_soc_tplg_be_dai | N | | ||
471 | * +-----------------------------------+-----+ | ||
472 | */ | ||
473 | struct snd_soc_tplg_be_dai { | ||
474 | __le32 size; /* in bytes of this structure */ | ||
475 | char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* name - used to match */ | ||
476 | __le32 dai_id; /* unique ID - used to match */ | ||
477 | __le32 playback; /* supports playback mode */ | ||
478 | __le32 capture; /* supports capture mode */ | ||
479 | struct snd_soc_tplg_stream_caps caps[2]; /* playback and capture for DAI */ | ||
480 | __le32 flag_mask; /* bitmask of flags to configure */ | ||
481 | __le32 flags; /* SND_SOC_TPLG_DAI_FLGBIT_* */ | ||
482 | struct snd_soc_tplg_private priv; | ||
483 | } __attribute__((packed)); | ||
453 | #endif | 484 | #endif |
diff --git a/include/uapi/sound/snd_sst_tokens.h b/include/uapi/sound/snd_sst_tokens.h new file mode 100644 index 000000000000..1ee2e943d66a --- /dev/null +++ b/include/uapi/sound/snd_sst_tokens.h | |||
@@ -0,0 +1,214 @@ | |||
1 | /* | ||
2 | * snd_sst_tokens.h - Intel SST tokens definition | ||
3 | * | ||
4 | * Copyright (C) 2016 Intel Corp | ||
5 | * Author: Shreyas NC <shreyas.nc@intel.com> | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
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 as version 2, as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | */ | ||
17 | #ifndef __SND_SST_TOKENS_H__ | ||
18 | #define __SND_SST_TOKENS_H__ | ||
19 | |||
20 | /** | ||
21 | * %SKL_TKN_UUID: Module UUID | ||
22 | * | ||
23 | * %SKL_TKN_U8_BLOCK_TYPE: Type of the private data block.Can be: | ||
24 | * tuples, bytes, short and words | ||
25 | * | ||
26 | * %SKL_TKN_U8_IN_PIN_TYPE: Input pin type, | ||
27 | * homogenous=0, heterogenous=1 | ||
28 | * | ||
29 | * %SKL_TKN_U8_OUT_PIN_TYPE: Output pin type, | ||
30 | * homogenous=0, heterogenous=1 | ||
31 | * %SKL_TKN_U8_DYN_IN_PIN: Configure Input pin dynamically | ||
32 | * if true | ||
33 | * | ||
34 | * %SKL_TKN_U8_DYN_OUT_PIN: Configure Output pin dynamically | ||
35 | * if true | ||
36 | * | ||
37 | * %SKL_TKN_U8_IN_QUEUE_COUNT: Store the number of Input pins | ||
38 | * | ||
39 | * %SKL_TKN_U8_OUT_QUEUE_COUNT: Store the number of Output pins | ||
40 | * | ||
41 | * %SKL_TKN_U8_TIME_SLOT: TDM slot number | ||
42 | * | ||
43 | * %SKL_TKN_U8_CORE_ID: Stores module affinity value.Can take | ||
44 | * the values: | ||
45 | * SKL_AFFINITY_CORE_0 = 0, | ||
46 | * SKL_AFFINITY_CORE_1, | ||
47 | * SKL_AFFINITY_CORE_MAX | ||
48 | * | ||
49 | * %SKL_TKN_U8_MOD_TYPE: Module type value. | ||
50 | * | ||
51 | * %SKL_TKN_U8_CONN_TYPE: Module connection type can be a FE, | ||
52 | * BE or NONE as defined : | ||
53 | * SKL_PIPE_CONN_TYPE_NONE = 0, | ||
54 | * SKL_PIPE_CONN_TYPE_FE = 1 (HOST_DMA) | ||
55 | * SKL_PIPE_CONN_TYPE_BE = 2 (LINK_DMA) | ||
56 | * | ||
57 | * %SKL_TKN_U8_DEV_TYPE: Type of device to which the module is | ||
58 | * connected | ||
59 | * Can take the values: | ||
60 | * SKL_DEVICE_BT = 0x0, | ||
61 | * SKL_DEVICE_DMIC = 0x1, | ||
62 | * SKL_DEVICE_I2S = 0x2, | ||
63 | * SKL_DEVICE_SLIMBUS = 0x3, | ||
64 | * SKL_DEVICE_HDALINK = 0x4, | ||
65 | * SKL_DEVICE_HDAHOST = 0x5, | ||
66 | * SKL_DEVICE_NONE | ||
67 | * | ||
68 | * %SKL_TKN_U8_HW_CONN_TYPE: Connection type of the HW to which the | ||
69 | * module is connected | ||
70 | * SKL_CONN_NONE = 0, | ||
71 | * SKL_CONN_SOURCE = 1, | ||
72 | * SKL_CONN_SINK = 2 | ||
73 | * | ||
74 | * %SKL_TKN_U16_PIN_INST_ID: Stores the pin instance id | ||
75 | * | ||
76 | * %SKL_TKN_U16_MOD_INST_ID: Stores the mdule instance id | ||
77 | * | ||
78 | * %SKL_TKN_U32_MAX_MCPS: Module max mcps value | ||
79 | * | ||
80 | * %SKL_TKN_U32_MEM_PAGES: Module resource pages | ||
81 | * | ||
82 | * %SKL_TKN_U32_OBS: Stores Output Buffer size | ||
83 | * | ||
84 | * %SKL_TKN_U32_IBS: Stores input buffer size | ||
85 | * | ||
86 | * %SKL_TKN_U32_VBUS_ID: Module VBUS_ID. PDM=0, SSP0=0, | ||
87 | * SSP1=1,SSP2=2, | ||
88 | * SSP3=3, SSP4=4, | ||
89 | * SSP5=5, SSP6=6,INVALID | ||
90 | * | ||
91 | * %SKL_TKN_U32_PARAMS_FIXUP: Module Params fixup mask | ||
92 | * %SKL_TKN_U32_CONVERTER: Module params converter mask | ||
93 | * %SKL_TKN_U32_PIPE_ID: Stores the pipe id | ||
94 | * | ||
95 | * %SKL_TKN_U32_PIPE_CONN_TYPE: Type of the token to which the pipe is | ||
96 | * connected to. It can be | ||
97 | * SKL_PIPE_CONN_TYPE_NONE = 0, | ||
98 | * SKL_PIPE_CONN_TYPE_FE = 1 (HOST_DMA), | ||
99 | * SKL_PIPE_CONN_TYPE_BE = 2 (LINK_DMA), | ||
100 | * | ||
101 | * %SKL_TKN_U32_PIPE_PRIORITY: Pipe priority value | ||
102 | * %SKL_TKN_U32_PIPE_MEM_PGS: Pipe resource pages | ||
103 | * | ||
104 | * %SKL_TKN_U32_DIR_PIN_COUNT: Value for the direction to set input/output | ||
105 | * formats and the pin count. | ||
106 | * The first 4 bits have the direction | ||
107 | * value and the next 4 have | ||
108 | * the pin count value. | ||
109 | * SKL_DIR_IN = 0, SKL_DIR_OUT = 1. | ||
110 | * The input and output formats | ||
111 | * share the same set of tokens | ||
112 | * with the distinction between input | ||
113 | * and output made by reading direction | ||
114 | * token. | ||
115 | * | ||
116 | * %SKL_TKN_U32_FMT_CH: Supported channel count | ||
117 | * | ||
118 | * %SKL_TKN_U32_FMT_FREQ: Supported frequency/sample rate | ||
119 | * | ||
120 | * %SKL_TKN_U32_FMT_BIT_DEPTH: Supported container size | ||
121 | * | ||
122 | * %SKL_TKN_U32_FMT_SAMPLE_SIZE:Number of samples in the container | ||
123 | * | ||
124 | * %SKL_TKN_U32_FMT_CH_CONFIG: Supported channel configurations for the | ||
125 | * input/output. | ||
126 | * | ||
127 | * %SKL_TKN_U32_FMT_INTERLEAVE: Interleaving style which can be per | ||
128 | * channel or per sample. The values can be : | ||
129 | * SKL_INTERLEAVING_PER_CHANNEL = 0, | ||
130 | * SKL_INTERLEAVING_PER_SAMPLE = 1, | ||
131 | * | ||
132 | * %SKL_TKN_U32_FMT_SAMPLE_TYPE: | ||
133 | * Specifies the sample type. Can take the | ||
134 | * values: SKL_SAMPLE_TYPE_INT_MSB = 0, | ||
135 | * SKL_SAMPLE_TYPE_INT_LSB = 1, | ||
136 | * SKL_SAMPLE_TYPE_INT_SIGNED = 2, | ||
137 | * SKL_SAMPLE_TYPE_INT_UNSIGNED = 3, | ||
138 | * SKL_SAMPLE_TYPE_FLOAT = 4 | ||
139 | * | ||
140 | * %SKL_TKN_U32_CH_MAP: Channel map values | ||
141 | * %SKL_TKN_U32_MOD_SET_PARAMS: It can take these values: | ||
142 | * SKL_PARAM_DEFAULT, SKL_PARAM_INIT, | ||
143 | * SKL_PARAM_SET, SKL_PARAM_BIND | ||
144 | * | ||
145 | * %SKL_TKN_U32_MOD_PARAM_ID: ID of the module params | ||
146 | * | ||
147 | * %SKL_TKN_U32_CAPS_SET_PARAMS: | ||
148 | * Set params value | ||
149 | * | ||
150 | * %SKL_TKN_U32_CAPS_PARAMS_ID: Params ID | ||
151 | * | ||
152 | * %SKL_TKN_U32_CAPS_SIZE: Caps size | ||
153 | * | ||
154 | * %SKL_TKN_U32_PROC_DOMAIN: Specify processing domain | ||
155 | * | ||
156 | * %SKL_TKN_U32_LIB_COUNT: Specifies the number of libraries | ||
157 | * | ||
158 | * %SKL_TKN_STR_LIB_NAME: Specifies the library name | ||
159 | * | ||
160 | * module_id and loadable flags dont have tokens as these values will be | ||
161 | * read from the DSP FW manifest | ||
162 | */ | ||
163 | enum SKL_TKNS { | ||
164 | SKL_TKN_UUID = 1, | ||
165 | SKL_TKN_U8_NUM_BLOCKS, | ||
166 | SKL_TKN_U8_BLOCK_TYPE, | ||
167 | SKL_TKN_U8_IN_PIN_TYPE, | ||
168 | SKL_TKN_U8_OUT_PIN_TYPE, | ||
169 | SKL_TKN_U8_DYN_IN_PIN, | ||
170 | SKL_TKN_U8_DYN_OUT_PIN, | ||
171 | SKL_TKN_U8_IN_QUEUE_COUNT, | ||
172 | SKL_TKN_U8_OUT_QUEUE_COUNT, | ||
173 | SKL_TKN_U8_TIME_SLOT, | ||
174 | SKL_TKN_U8_CORE_ID, | ||
175 | SKL_TKN_U8_MOD_TYPE, | ||
176 | SKL_TKN_U8_CONN_TYPE, | ||
177 | SKL_TKN_U8_DEV_TYPE, | ||
178 | SKL_TKN_U8_HW_CONN_TYPE, | ||
179 | SKL_TKN_U16_MOD_INST_ID, | ||
180 | SKL_TKN_U16_BLOCK_SIZE, | ||
181 | SKL_TKN_U32_MAX_MCPS, | ||
182 | SKL_TKN_U32_MEM_PAGES, | ||
183 | SKL_TKN_U32_OBS, | ||
184 | SKL_TKN_U32_IBS, | ||
185 | SKL_TKN_U32_VBUS_ID, | ||
186 | SKL_TKN_U32_PARAMS_FIXUP, | ||
187 | SKL_TKN_U32_CONVERTER, | ||
188 | SKL_TKN_U32_PIPE_ID, | ||
189 | SKL_TKN_U32_PIPE_CONN_TYPE, | ||
190 | SKL_TKN_U32_PIPE_PRIORITY, | ||
191 | SKL_TKN_U32_PIPE_MEM_PGS, | ||
192 | SKL_TKN_U32_DIR_PIN_COUNT, | ||
193 | SKL_TKN_U32_FMT_CH, | ||
194 | SKL_TKN_U32_FMT_FREQ, | ||
195 | SKL_TKN_U32_FMT_BIT_DEPTH, | ||
196 | SKL_TKN_U32_FMT_SAMPLE_SIZE, | ||
197 | SKL_TKN_U32_FMT_CH_CONFIG, | ||
198 | SKL_TKN_U32_FMT_INTERLEAVE, | ||
199 | SKL_TKN_U32_FMT_SAMPLE_TYPE, | ||
200 | SKL_TKN_U32_FMT_CH_MAP, | ||
201 | SKL_TKN_U32_PIN_MOD_ID, | ||
202 | SKL_TKN_U32_PIN_INST_ID, | ||
203 | SKL_TKN_U32_MOD_SET_PARAMS, | ||
204 | SKL_TKN_U32_MOD_PARAM_ID, | ||
205 | SKL_TKN_U32_CAPS_SET_PARAMS, | ||
206 | SKL_TKN_U32_CAPS_PARAMS_ID, | ||
207 | SKL_TKN_U32_CAPS_SIZE, | ||
208 | SKL_TKN_U32_PROC_DOMAIN, | ||
209 | SKL_TKN_U32_LIB_COUNT, | ||
210 | SKL_TKN_STR_LIB_NAME, | ||
211 | SKL_TKN_MAX = SKL_TKN_STR_LIB_NAME, | ||
212 | }; | ||
213 | |||
214 | #endif | ||
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index 9a37c541822f..b5486e648607 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h | |||
@@ -9,8 +9,8 @@ | |||
9 | 9 | ||
10 | DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu); | 10 | DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu); |
11 | 11 | ||
12 | DECLARE_PER_CPU(int, xen_vcpu_id); | 12 | DECLARE_PER_CPU(uint32_t, xen_vcpu_id); |
13 | static inline int xen_vcpu_nr(int cpu) | 13 | static inline uint32_t xen_vcpu_nr(int cpu) |
14 | { | 14 | { |
15 | return per_cpu(xen_vcpu_id, cpu); | 15 | return per_cpu(xen_vcpu_id, cpu); |
16 | } | 16 | } |
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index d6709eb70970..0d302a87f21b 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c | |||
@@ -19,6 +19,7 @@ | |||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/file.h> | ||
22 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
23 | #include <linux/audit.h> | 24 | #include <linux/audit.h> |
24 | #include <linux/kthread.h> | 25 | #include <linux/kthread.h> |
@@ -544,10 +545,11 @@ int audit_exe_compare(struct task_struct *tsk, struct audit_fsnotify_mark *mark) | |||
544 | unsigned long ino; | 545 | unsigned long ino; |
545 | dev_t dev; | 546 | dev_t dev; |
546 | 547 | ||
547 | rcu_read_lock(); | 548 | exe_file = get_task_exe_file(tsk); |
548 | exe_file = rcu_dereference(tsk->mm->exe_file); | 549 | if (!exe_file) |
550 | return 0; | ||
549 | ino = exe_file->f_inode->i_ino; | 551 | ino = exe_file->f_inode->i_ino; |
550 | dev = exe_file->f_inode->i_sb->s_dev; | 552 | dev = exe_file->f_inode->i_sb->s_dev; |
551 | rcu_read_unlock(); | 553 | fput(exe_file); |
552 | return audit_mark_compare(mark, ino, dev); | 554 | return audit_mark_compare(mark, ino, dev); |
553 | } | 555 | } |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index d1c51b7f5221..5e8dab5bf9ad 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -6270,6 +6270,12 @@ void cgroup_sk_alloc(struct sock_cgroup_data *skcd) | |||
6270 | if (cgroup_sk_alloc_disabled) | 6270 | if (cgroup_sk_alloc_disabled) |
6271 | return; | 6271 | return; |
6272 | 6272 | ||
6273 | /* Socket clone path */ | ||
6274 | if (skcd->val) { | ||
6275 | cgroup_get(sock_cgroup_ptr(skcd)); | ||
6276 | return; | ||
6277 | } | ||
6278 | |||
6273 | rcu_read_lock(); | 6279 | rcu_read_lock(); |
6274 | 6280 | ||
6275 | while (true) { | 6281 | while (true) { |
diff --git a/kernel/configs/tiny.config b/kernel/configs/tiny.config index c2de56ab0fce..7fa0c4ae6394 100644 --- a/kernel/configs/tiny.config +++ b/kernel/configs/tiny.config | |||
@@ -1,4 +1,12 @@ | |||
1 | # CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set | ||
1 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 2 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
3 | # CONFIG_KERNEL_GZIP is not set | ||
4 | # CONFIG_KERNEL_BZIP2 is not set | ||
5 | # CONFIG_KERNEL_LZMA is not set | ||
2 | CONFIG_KERNEL_XZ=y | 6 | CONFIG_KERNEL_XZ=y |
7 | # CONFIG_KERNEL_LZO is not set | ||
8 | # CONFIG_KERNEL_LZ4 is not set | ||
3 | CONFIG_OPTIMIZE_INLINING=y | 9 | CONFIG_OPTIMIZE_INLINING=y |
10 | # CONFIG_SLAB is not set | ||
11 | # CONFIG_SLUB is not set | ||
4 | CONFIG_SLOB=y | 12 | CONFIG_SLOB=y |
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index c7fd2778ed50..c27e53326bef 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -2069,6 +2069,20 @@ static void cpuset_bind(struct cgroup_subsys_state *root_css) | |||
2069 | mutex_unlock(&cpuset_mutex); | 2069 | mutex_unlock(&cpuset_mutex); |
2070 | } | 2070 | } |
2071 | 2071 | ||
2072 | /* | ||
2073 | * Make sure the new task conform to the current state of its parent, | ||
2074 | * which could have been changed by cpuset just after it inherits the | ||
2075 | * state from the parent and before it sits on the cgroup's task list. | ||
2076 | */ | ||
2077 | void cpuset_fork(struct task_struct *task) | ||
2078 | { | ||
2079 | if (task_css_is_root(task, cpuset_cgrp_id)) | ||
2080 | return; | ||
2081 | |||
2082 | set_cpus_allowed_ptr(task, ¤t->cpus_allowed); | ||
2083 | task->mems_allowed = current->mems_allowed; | ||
2084 | } | ||
2085 | |||
2072 | struct cgroup_subsys cpuset_cgrp_subsys = { | 2086 | struct cgroup_subsys cpuset_cgrp_subsys = { |
2073 | .css_alloc = cpuset_css_alloc, | 2087 | .css_alloc = cpuset_css_alloc, |
2074 | .css_online = cpuset_css_online, | 2088 | .css_online = cpuset_css_online, |
@@ -2079,6 +2093,7 @@ struct cgroup_subsys cpuset_cgrp_subsys = { | |||
2079 | .attach = cpuset_attach, | 2093 | .attach = cpuset_attach, |
2080 | .post_attach = cpuset_post_attach, | 2094 | .post_attach = cpuset_post_attach, |
2081 | .bind = cpuset_bind, | 2095 | .bind = cpuset_bind, |
2096 | .fork = cpuset_fork, | ||
2082 | .legacy_cftypes = files, | 2097 | .legacy_cftypes = files, |
2083 | .early_init = true, | 2098 | .early_init = true, |
2084 | }; | 2099 | }; |
diff --git a/kernel/events/core.c b/kernel/events/core.c index 5650f5317e0c..fc9bb2225291 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -2496,11 +2496,11 @@ static int __perf_event_stop(void *info) | |||
2496 | return 0; | 2496 | return 0; |
2497 | } | 2497 | } |
2498 | 2498 | ||
2499 | static int perf_event_restart(struct perf_event *event) | 2499 | static int perf_event_stop(struct perf_event *event, int restart) |
2500 | { | 2500 | { |
2501 | struct stop_event_data sd = { | 2501 | struct stop_event_data sd = { |
2502 | .event = event, | 2502 | .event = event, |
2503 | .restart = 1, | 2503 | .restart = restart, |
2504 | }; | 2504 | }; |
2505 | int ret = 0; | 2505 | int ret = 0; |
2506 | 2506 | ||
@@ -3549,10 +3549,18 @@ static int perf_event_read(struct perf_event *event, bool group) | |||
3549 | .group = group, | 3549 | .group = group, |
3550 | .ret = 0, | 3550 | .ret = 0, |
3551 | }; | 3551 | }; |
3552 | ret = smp_call_function_single(event->oncpu, __perf_event_read, &data, 1); | 3552 | /* |
3553 | /* The event must have been read from an online CPU: */ | 3553 | * Purposely ignore the smp_call_function_single() return |
3554 | WARN_ON_ONCE(ret); | 3554 | * value. |
3555 | ret = ret ? : data.ret; | 3555 | * |
3556 | * If event->oncpu isn't a valid CPU it means the event got | ||
3557 | * scheduled out and that will have updated the event count. | ||
3558 | * | ||
3559 | * Therefore, either way, we'll have an up-to-date event count | ||
3560 | * after this. | ||
3561 | */ | ||
3562 | (void)smp_call_function_single(event->oncpu, __perf_event_read, &data, 1); | ||
3563 | ret = data.ret; | ||
3556 | } else if (event->state == PERF_EVENT_STATE_INACTIVE) { | 3564 | } else if (event->state == PERF_EVENT_STATE_INACTIVE) { |
3557 | struct perf_event_context *ctx = event->ctx; | 3565 | struct perf_event_context *ctx = event->ctx; |
3558 | unsigned long flags; | 3566 | unsigned long flags; |
@@ -3921,7 +3929,7 @@ static void exclusive_event_destroy(struct perf_event *event) | |||
3921 | 3929 | ||
3922 | static bool exclusive_event_match(struct perf_event *e1, struct perf_event *e2) | 3930 | static bool exclusive_event_match(struct perf_event *e1, struct perf_event *e2) |
3923 | { | 3931 | { |
3924 | if ((e1->pmu->capabilities & PERF_PMU_CAP_EXCLUSIVE) && | 3932 | if ((e1->pmu == e2->pmu) && |
3925 | (e1->cpu == e2->cpu || | 3933 | (e1->cpu == e2->cpu || |
3926 | e1->cpu == -1 || | 3934 | e1->cpu == -1 || |
3927 | e2->cpu == -1)) | 3935 | e2->cpu == -1)) |
@@ -4837,6 +4845,19 @@ static void ring_buffer_attach(struct perf_event *event, | |||
4837 | spin_unlock_irqrestore(&rb->event_lock, flags); | 4845 | spin_unlock_irqrestore(&rb->event_lock, flags); |
4838 | } | 4846 | } |
4839 | 4847 | ||
4848 | /* | ||
4849 | * Avoid racing with perf_mmap_close(AUX): stop the event | ||
4850 | * before swizzling the event::rb pointer; if it's getting | ||
4851 | * unmapped, its aux_mmap_count will be 0 and it won't | ||
4852 | * restart. See the comment in __perf_pmu_output_stop(). | ||
4853 | * | ||
4854 | * Data will inevitably be lost when set_output is done in | ||
4855 | * mid-air, but then again, whoever does it like this is | ||
4856 | * not in for the data anyway. | ||
4857 | */ | ||
4858 | if (has_aux(event)) | ||
4859 | perf_event_stop(event, 0); | ||
4860 | |||
4840 | rcu_assign_pointer(event->rb, rb); | 4861 | rcu_assign_pointer(event->rb, rb); |
4841 | 4862 | ||
4842 | if (old_rb) { | 4863 | if (old_rb) { |
@@ -6112,7 +6133,7 @@ static void perf_event_addr_filters_exec(struct perf_event *event, void *data) | |||
6112 | raw_spin_unlock_irqrestore(&ifh->lock, flags); | 6133 | raw_spin_unlock_irqrestore(&ifh->lock, flags); |
6113 | 6134 | ||
6114 | if (restart) | 6135 | if (restart) |
6115 | perf_event_restart(event); | 6136 | perf_event_stop(event, 1); |
6116 | } | 6137 | } |
6117 | 6138 | ||
6118 | void perf_event_exec(void) | 6139 | void perf_event_exec(void) |
@@ -6156,7 +6177,13 @@ static void __perf_event_output_stop(struct perf_event *event, void *data) | |||
6156 | 6177 | ||
6157 | /* | 6178 | /* |
6158 | * In case of inheritance, it will be the parent that links to the | 6179 | * In case of inheritance, it will be the parent that links to the |
6159 | * ring-buffer, but it will be the child that's actually using it: | 6180 | * ring-buffer, but it will be the child that's actually using it. |
6181 | * | ||
6182 | * We are using event::rb to determine if the event should be stopped, | ||
6183 | * however this may race with ring_buffer_attach() (through set_output), | ||
6184 | * which will make us skip the event that actually needs to be stopped. | ||
6185 | * So ring_buffer_attach() has to stop an aux event before re-assigning | ||
6186 | * its rb pointer. | ||
6160 | */ | 6187 | */ |
6161 | if (rcu_dereference(parent->rb) == rb) | 6188 | if (rcu_dereference(parent->rb) == rb) |
6162 | ro->err = __perf_event_stop(&sd); | 6189 | ro->err = __perf_event_stop(&sd); |
@@ -6166,7 +6193,7 @@ static int __perf_pmu_output_stop(void *info) | |||
6166 | { | 6193 | { |
6167 | struct perf_event *event = info; | 6194 | struct perf_event *event = info; |
6168 | struct pmu *pmu = event->pmu; | 6195 | struct pmu *pmu = event->pmu; |
6169 | struct perf_cpu_context *cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); | 6196 | struct perf_cpu_context *cpuctx = this_cpu_ptr(pmu->pmu_cpu_context); |
6170 | struct remote_output ro = { | 6197 | struct remote_output ro = { |
6171 | .rb = event->rb, | 6198 | .rb = event->rb, |
6172 | }; | 6199 | }; |
@@ -6670,7 +6697,7 @@ static void __perf_addr_filters_adjust(struct perf_event *event, void *data) | |||
6670 | raw_spin_unlock_irqrestore(&ifh->lock, flags); | 6697 | raw_spin_unlock_irqrestore(&ifh->lock, flags); |
6671 | 6698 | ||
6672 | if (restart) | 6699 | if (restart) |
6673 | perf_event_restart(event); | 6700 | perf_event_stop(event, 1); |
6674 | } | 6701 | } |
6675 | 6702 | ||
6676 | /* | 6703 | /* |
@@ -7859,7 +7886,7 @@ static void perf_event_addr_filters_apply(struct perf_event *event) | |||
7859 | mmput(mm); | 7886 | mmput(mm); |
7860 | 7887 | ||
7861 | restart: | 7888 | restart: |
7862 | perf_event_restart(event); | 7889 | perf_event_stop(event, 1); |
7863 | } | 7890 | } |
7864 | 7891 | ||
7865 | /* | 7892 | /* |
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c index ae9b90dc9a5a..257fa460b846 100644 --- a/kernel/events/ring_buffer.c +++ b/kernel/events/ring_buffer.c | |||
@@ -330,15 +330,22 @@ void *perf_aux_output_begin(struct perf_output_handle *handle, | |||
330 | if (!rb) | 330 | if (!rb) |
331 | return NULL; | 331 | return NULL; |
332 | 332 | ||
333 | if (!rb_has_aux(rb) || !atomic_inc_not_zero(&rb->aux_refcount)) | 333 | if (!rb_has_aux(rb)) |
334 | goto err; | 334 | goto err; |
335 | 335 | ||
336 | /* | 336 | /* |
337 | * If rb::aux_mmap_count is zero (and rb_has_aux() above went through), | 337 | * If aux_mmap_count is zero, the aux buffer is in perf_mmap_close(), |
338 | * the aux buffer is in perf_mmap_close(), about to get freed. | 338 | * about to get freed, so we leave immediately. |
339 | * | ||
340 | * Checking rb::aux_mmap_count and rb::refcount has to be done in | ||
341 | * the same order, see perf_mmap_close. Otherwise we end up freeing | ||
342 | * aux pages in this path, which is a bug, because in_atomic(). | ||
339 | */ | 343 | */ |
340 | if (!atomic_read(&rb->aux_mmap_count)) | 344 | if (!atomic_read(&rb->aux_mmap_count)) |
341 | goto err_put; | 345 | goto err; |
346 | |||
347 | if (!atomic_inc_not_zero(&rb->aux_refcount)) | ||
348 | goto err; | ||
342 | 349 | ||
343 | /* | 350 | /* |
344 | * Nesting is not supported for AUX area, make sure nested | 351 | * Nesting is not supported for AUX area, make sure nested |
diff --git a/kernel/exit.c b/kernel/exit.c index 2f974ae042a6..091a78be3b09 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -848,12 +848,7 @@ void do_exit(long code) | |||
848 | TASKS_RCU(preempt_enable()); | 848 | TASKS_RCU(preempt_enable()); |
849 | exit_notify(tsk, group_dead); | 849 | exit_notify(tsk, group_dead); |
850 | proc_exit_connector(tsk); | 850 | proc_exit_connector(tsk); |
851 | #ifdef CONFIG_NUMA | 851 | mpol_put_task_policy(tsk); |
852 | task_lock(tsk); | ||
853 | mpol_put(tsk->mempolicy); | ||
854 | tsk->mempolicy = NULL; | ||
855 | task_unlock(tsk); | ||
856 | #endif | ||
857 | #ifdef CONFIG_FUTEX | 852 | #ifdef CONFIG_FUTEX |
858 | if (unlikely(current->pi_state_cache)) | 853 | if (unlikely(current->pi_state_cache)) |
859 | kfree(current->pi_state_cache); | 854 | kfree(current->pi_state_cache); |
diff --git a/kernel/fork.c b/kernel/fork.c index 52e725d4a866..beb31725f7e2 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -799,6 +799,29 @@ struct file *get_mm_exe_file(struct mm_struct *mm) | |||
799 | EXPORT_SYMBOL(get_mm_exe_file); | 799 | EXPORT_SYMBOL(get_mm_exe_file); |
800 | 800 | ||
801 | /** | 801 | /** |
802 | * get_task_exe_file - acquire a reference to the task's executable file | ||
803 | * | ||
804 | * Returns %NULL if task's mm (if any) has no associated executable file or | ||
805 | * this is a kernel thread with borrowed mm (see the comment above get_task_mm). | ||
806 | * User must release file via fput(). | ||
807 | */ | ||
808 | struct file *get_task_exe_file(struct task_struct *task) | ||
809 | { | ||
810 | struct file *exe_file = NULL; | ||
811 | struct mm_struct *mm; | ||
812 | |||
813 | task_lock(task); | ||
814 | mm = task->mm; | ||
815 | if (mm) { | ||
816 | if (!(task->flags & PF_KTHREAD)) | ||
817 | exe_file = get_mm_exe_file(mm); | ||
818 | } | ||
819 | task_unlock(task); | ||
820 | return exe_file; | ||
821 | } | ||
822 | EXPORT_SYMBOL(get_task_exe_file); | ||
823 | |||
824 | /** | ||
802 | * get_task_mm - acquire a reference to the task's mm | 825 | * get_task_mm - acquire a reference to the task's mm |
803 | * | 826 | * |
804 | * Returns %NULL if the task has no mm. Checks PF_KTHREAD (meaning | 827 | * Returns %NULL if the task has no mm. Checks PF_KTHREAD (meaning |
@@ -913,14 +936,12 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) | |||
913 | deactivate_mm(tsk, mm); | 936 | deactivate_mm(tsk, mm); |
914 | 937 | ||
915 | /* | 938 | /* |
916 | * If we're exiting normally, clear a user-space tid field if | 939 | * Signal userspace if we're not exiting with a core dump |
917 | * requested. We leave this alone when dying by signal, to leave | 940 | * because we want to leave the value intact for debugging |
918 | * the value intact in a core dump, and to save the unnecessary | 941 | * purposes. |
919 | * trouble, say, a killed vfork parent shouldn't touch this mm. | ||
920 | * Userland only wants this done for a sys_exit. | ||
921 | */ | 942 | */ |
922 | if (tsk->clear_child_tid) { | 943 | if (tsk->clear_child_tid) { |
923 | if (!(tsk->flags & PF_SIGNALED) && | 944 | if (!(tsk->signal->flags & SIGNAL_GROUP_COREDUMP) && |
924 | atomic_read(&mm->mm_users) > 1) { | 945 | atomic_read(&mm->mm_users) > 1) { |
925 | /* | 946 | /* |
926 | * We don't check the error code - if userspace has | 947 | * We don't check the error code - if userspace has |
@@ -1404,7 +1425,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1404 | p->real_start_time = ktime_get_boot_ns(); | 1425 | p->real_start_time = ktime_get_boot_ns(); |
1405 | p->io_context = NULL; | 1426 | p->io_context = NULL; |
1406 | p->audit_context = NULL; | 1427 | p->audit_context = NULL; |
1407 | threadgroup_change_begin(current); | ||
1408 | cgroup_fork(p); | 1428 | cgroup_fork(p); |
1409 | #ifdef CONFIG_NUMA | 1429 | #ifdef CONFIG_NUMA |
1410 | p->mempolicy = mpol_dup(p->mempolicy); | 1430 | p->mempolicy = mpol_dup(p->mempolicy); |
@@ -1556,6 +1576,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1556 | INIT_LIST_HEAD(&p->thread_group); | 1576 | INIT_LIST_HEAD(&p->thread_group); |
1557 | p->task_works = NULL; | 1577 | p->task_works = NULL; |
1558 | 1578 | ||
1579 | threadgroup_change_begin(current); | ||
1559 | /* | 1580 | /* |
1560 | * Ensure that the cgroup subsystem policies allow the new process to be | 1581 | * Ensure that the cgroup subsystem policies allow the new process to be |
1561 | * forked. It should be noted the the new process's css_set can be changed | 1582 | * forked. It should be noted the the new process's css_set can be changed |
@@ -1656,6 +1677,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1656 | bad_fork_cancel_cgroup: | 1677 | bad_fork_cancel_cgroup: |
1657 | cgroup_cancel_fork(p); | 1678 | cgroup_cancel_fork(p); |
1658 | bad_fork_free_pid: | 1679 | bad_fork_free_pid: |
1680 | threadgroup_change_end(current); | ||
1659 | if (pid != &init_struct_pid) | 1681 | if (pid != &init_struct_pid) |
1660 | free_pid(pid); | 1682 | free_pid(pid); |
1661 | bad_fork_cleanup_thread: | 1683 | bad_fork_cleanup_thread: |
@@ -1688,7 +1710,6 @@ bad_fork_cleanup_policy: | |||
1688 | mpol_put(p->mempolicy); | 1710 | mpol_put(p->mempolicy); |
1689 | bad_fork_cleanup_threadgroup_lock: | 1711 | bad_fork_cleanup_threadgroup_lock: |
1690 | #endif | 1712 | #endif |
1691 | threadgroup_change_end(current); | ||
1692 | delayacct_tsk_free(p); | 1713 | delayacct_tsk_free(p); |
1693 | bad_fork_cleanup_count: | 1714 | bad_fork_cleanup_count: |
1694 | atomic_dec(&p->cred->user->processes); | 1715 | atomic_dec(&p->cred->user->processes); |
diff --git a/kernel/irq/affinity.c b/kernel/irq/affinity.c index f68959341c0f..32f6cfcff212 100644 --- a/kernel/irq/affinity.c +++ b/kernel/irq/affinity.c | |||
@@ -39,6 +39,7 @@ struct cpumask *irq_create_affinity_mask(unsigned int *nr_vecs) | |||
39 | return NULL; | 39 | return NULL; |
40 | } | 40 | } |
41 | 41 | ||
42 | get_online_cpus(); | ||
42 | if (max_vecs >= num_online_cpus()) { | 43 | if (max_vecs >= num_online_cpus()) { |
43 | cpumask_copy(affinity_mask, cpu_online_mask); | 44 | cpumask_copy(affinity_mask, cpu_online_mask); |
44 | *nr_vecs = num_online_cpus(); | 45 | *nr_vecs = num_online_cpus(); |
@@ -56,6 +57,7 @@ struct cpumask *irq_create_affinity_mask(unsigned int *nr_vecs) | |||
56 | } | 57 | } |
57 | *nr_vecs = vecs; | 58 | *nr_vecs = vecs; |
58 | } | 59 | } |
60 | put_online_cpus(); | ||
59 | 61 | ||
60 | return affinity_mask; | 62 | return affinity_mask; |
61 | } | 63 | } |
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index b4c1bc7c9ca2..26ba5654d9d5 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
@@ -820,6 +820,21 @@ __irq_do_set_handler(struct irq_desc *desc, irq_flow_handler_t handle, | |||
820 | desc->name = name; | 820 | desc->name = name; |
821 | 821 | ||
822 | if (handle != handle_bad_irq && is_chained) { | 822 | if (handle != handle_bad_irq && is_chained) { |
823 | unsigned int type = irqd_get_trigger_type(&desc->irq_data); | ||
824 | |||
825 | /* | ||
826 | * We're about to start this interrupt immediately, | ||
827 | * hence the need to set the trigger configuration. | ||
828 | * But the .set_type callback may have overridden the | ||
829 | * flow handler, ignoring that we're dealing with a | ||
830 | * chained interrupt. Reset it immediately because we | ||
831 | * do know better. | ||
832 | */ | ||
833 | if (type != IRQ_TYPE_NONE) { | ||
834 | __irq_set_trigger(desc, type); | ||
835 | desc->handle_irq = handle; | ||
836 | } | ||
837 | |||
823 | irq_settings_set_noprobe(desc); | 838 | irq_settings_set_noprobe(desc); |
824 | irq_settings_set_norequest(desc); | 839 | irq_settings_set_norequest(desc); |
825 | irq_settings_set_nothread(desc); | 840 | irq_settings_set_nothread(desc); |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 73a2b786b5e9..9530fcd27704 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -1681,8 +1681,10 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler, | |||
1681 | action->dev_id = dev_id; | 1681 | action->dev_id = dev_id; |
1682 | 1682 | ||
1683 | retval = irq_chip_pm_get(&desc->irq_data); | 1683 | retval = irq_chip_pm_get(&desc->irq_data); |
1684 | if (retval < 0) | 1684 | if (retval < 0) { |
1685 | kfree(action); | ||
1685 | return retval; | 1686 | return retval; |
1687 | } | ||
1686 | 1688 | ||
1687 | chip_bus_lock(desc); | 1689 | chip_bus_lock(desc); |
1688 | retval = __setup_irq(irq, desc, action); | 1690 | retval = __setup_irq(irq, desc, action); |
@@ -1985,8 +1987,10 @@ int request_percpu_irq(unsigned int irq, irq_handler_t handler, | |||
1985 | action->percpu_dev_id = dev_id; | 1987 | action->percpu_dev_id = dev_id; |
1986 | 1988 | ||
1987 | retval = irq_chip_pm_get(&desc->irq_data); | 1989 | retval = irq_chip_pm_get(&desc->irq_data); |
1988 | if (retval < 0) | 1990 | if (retval < 0) { |
1991 | kfree(action); | ||
1989 | return retval; | 1992 | return retval; |
1993 | } | ||
1990 | 1994 | ||
1991 | chip_bus_lock(desc); | 1995 | chip_bus_lock(desc); |
1992 | retval = __setup_irq(irq, desc, action); | 1996 | retval = __setup_irq(irq, desc, action); |
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index 503bc2d348e5..037c321c5618 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c | |||
@@ -887,7 +887,10 @@ int kexec_load_purgatory(struct kimage *image, unsigned long min, | |||
887 | return 0; | 887 | return 0; |
888 | out: | 888 | out: |
889 | vfree(pi->sechdrs); | 889 | vfree(pi->sechdrs); |
890 | pi->sechdrs = NULL; | ||
891 | |||
890 | vfree(pi->purgatory_buf); | 892 | vfree(pi->purgatory_buf); |
893 | pi->purgatory_buf = NULL; | ||
891 | return ret; | 894 | return ret; |
892 | } | 895 | } |
893 | 896 | ||
diff --git a/kernel/memremap.c b/kernel/memremap.c index 251d16b4cb41..b501e390bb34 100644 --- a/kernel/memremap.c +++ b/kernel/memremap.c | |||
@@ -247,6 +247,7 @@ static void devm_memremap_pages_release(struct device *dev, void *data) | |||
247 | align_start = res->start & ~(SECTION_SIZE - 1); | 247 | align_start = res->start & ~(SECTION_SIZE - 1); |
248 | align_size = ALIGN(resource_size(res), SECTION_SIZE); | 248 | align_size = ALIGN(resource_size(res), SECTION_SIZE); |
249 | arch_remove_memory(align_start, align_size); | 249 | arch_remove_memory(align_start, align_size); |
250 | untrack_pfn(NULL, PHYS_PFN(align_start), align_size); | ||
250 | pgmap_radix_release(res); | 251 | pgmap_radix_release(res); |
251 | dev_WARN_ONCE(dev, pgmap->altmap && pgmap->altmap->alloc, | 252 | dev_WARN_ONCE(dev, pgmap->altmap && pgmap->altmap->alloc, |
252 | "%s: failed to free all reserved pages\n", __func__); | 253 | "%s: failed to free all reserved pages\n", __func__); |
@@ -282,6 +283,7 @@ void *devm_memremap_pages(struct device *dev, struct resource *res, | |||
282 | struct percpu_ref *ref, struct vmem_altmap *altmap) | 283 | struct percpu_ref *ref, struct vmem_altmap *altmap) |
283 | { | 284 | { |
284 | resource_size_t key, align_start, align_size, align_end; | 285 | resource_size_t key, align_start, align_size, align_end; |
286 | pgprot_t pgprot = PAGE_KERNEL; | ||
285 | struct dev_pagemap *pgmap; | 287 | struct dev_pagemap *pgmap; |
286 | struct page_map *page_map; | 288 | struct page_map *page_map; |
287 | int error, nid, is_ram; | 289 | int error, nid, is_ram; |
@@ -351,6 +353,11 @@ void *devm_memremap_pages(struct device *dev, struct resource *res, | |||
351 | if (nid < 0) | 353 | if (nid < 0) |
352 | nid = numa_mem_id(); | 354 | nid = numa_mem_id(); |
353 | 355 | ||
356 | error = track_pfn_remap(NULL, &pgprot, PHYS_PFN(align_start), 0, | ||
357 | align_size); | ||
358 | if (error) | ||
359 | goto err_pfn_remap; | ||
360 | |||
354 | error = arch_add_memory(nid, align_start, align_size, true); | 361 | error = arch_add_memory(nid, align_start, align_size, true); |
355 | if (error) | 362 | if (error) |
356 | goto err_add_memory; | 363 | goto err_add_memory; |
@@ -371,6 +378,8 @@ void *devm_memremap_pages(struct device *dev, struct resource *res, | |||
371 | return __va(res->start); | 378 | return __va(res->start); |
372 | 379 | ||
373 | err_add_memory: | 380 | err_add_memory: |
381 | untrack_pfn(NULL, PHYS_PFN(align_start), align_size); | ||
382 | err_pfn_remap: | ||
374 | err_radix: | 383 | err_radix: |
375 | pgmap_radix_release(res); | 384 | pgmap_radix_release(res); |
376 | devres_free(page_map); | 385 | devres_free(page_map); |
diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 97b0df71303e..168ff442ebde 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c | |||
@@ -482,7 +482,16 @@ void pm_qos_update_request(struct pm_qos_request *req, | |||
482 | return; | 482 | return; |
483 | } | 483 | } |
484 | 484 | ||
485 | cancel_delayed_work_sync(&req->work); | 485 | /* |
486 | * This function may be called very early during boot, for example, | ||
487 | * from of_clk_init(), where irq needs to stay disabled. | ||
488 | * cancel_delayed_work_sync() assumes that irq is enabled on | ||
489 | * invocation and re-enables it on return. Avoid calling it until | ||
490 | * workqueue is initialized. | ||
491 | */ | ||
492 | if (keventd_up()) | ||
493 | cancel_delayed_work_sync(&req->work); | ||
494 | |||
486 | __pm_qos_update_request(req, new_value); | 495 | __pm_qos_update_request(req, new_value); |
487 | } | 496 | } |
488 | EXPORT_SYMBOL_GPL(pm_qos_update_request); | 497 | EXPORT_SYMBOL_GPL(pm_qos_update_request); |
diff --git a/kernel/printk/braille.c b/kernel/printk/braille.c index 276762f3a460..d5760c42f042 100644 --- a/kernel/printk/braille.c +++ b/kernel/printk/braille.c | |||
@@ -9,10 +9,10 @@ | |||
9 | 9 | ||
10 | char *_braille_console_setup(char **str, char **brl_options) | 10 | char *_braille_console_setup(char **str, char **brl_options) |
11 | { | 11 | { |
12 | if (!memcmp(*str, "brl,", 4)) { | 12 | if (!strncmp(*str, "brl,", 4)) { |
13 | *brl_options = ""; | 13 | *brl_options = ""; |
14 | *str += 4; | 14 | *str += 4; |
15 | } else if (!memcmp(str, "brl=", 4)) { | 15 | } else if (!strncmp(*str, "brl=", 4)) { |
16 | *brl_options = *str + 4; | 16 | *brl_options = *str + 4; |
17 | *str = strchr(*brl_options, ','); | 17 | *str = strchr(*brl_options, ','); |
18 | if (!*str) | 18 | if (!*str) |
diff --git a/kernel/printk/nmi.c b/kernel/printk/nmi.c index b69eb8a2876f..16bab471c7e2 100644 --- a/kernel/printk/nmi.c +++ b/kernel/printk/nmi.c | |||
@@ -99,27 +99,33 @@ again: | |||
99 | return add; | 99 | return add; |
100 | } | 100 | } |
101 | 101 | ||
102 | /* | 102 | static void printk_nmi_flush_line(const char *text, int len) |
103 | * printk one line from the temporary buffer from @start index until | ||
104 | * and including the @end index. | ||
105 | */ | ||
106 | static void print_nmi_seq_line(struct nmi_seq_buf *s, int start, int end) | ||
107 | { | 103 | { |
108 | const char *buf = s->buffer + start; | ||
109 | |||
110 | /* | 104 | /* |
111 | * The buffers are flushed in NMI only on panic. The messages must | 105 | * The buffers are flushed in NMI only on panic. The messages must |
112 | * go only into the ring buffer at this stage. Consoles will get | 106 | * go only into the ring buffer at this stage. Consoles will get |
113 | * explicitly called later when a crashdump is not generated. | 107 | * explicitly called later when a crashdump is not generated. |
114 | */ | 108 | */ |
115 | if (in_nmi()) | 109 | if (in_nmi()) |
116 | printk_deferred("%.*s", (end - start) + 1, buf); | 110 | printk_deferred("%.*s", len, text); |
117 | else | 111 | else |
118 | printk("%.*s", (end - start) + 1, buf); | 112 | printk("%.*s", len, text); |
119 | 113 | ||
120 | } | 114 | } |
121 | 115 | ||
122 | /* | 116 | /* |
117 | * printk one line from the temporary buffer from @start index until | ||
118 | * and including the @end index. | ||
119 | */ | ||
120 | static void printk_nmi_flush_seq_line(struct nmi_seq_buf *s, | ||
121 | int start, int end) | ||
122 | { | ||
123 | const char *buf = s->buffer + start; | ||
124 | |||
125 | printk_nmi_flush_line(buf, (end - start) + 1); | ||
126 | } | ||
127 | |||
128 | /* | ||
123 | * Flush data from the associated per_CPU buffer. The function | 129 | * Flush data from the associated per_CPU buffer. The function |
124 | * can be called either via IRQ work or independently. | 130 | * can be called either via IRQ work or independently. |
125 | */ | 131 | */ |
@@ -150,9 +156,11 @@ more: | |||
150 | * the buffer an unexpected way. If we printed something then | 156 | * the buffer an unexpected way. If we printed something then |
151 | * @len must only increase. | 157 | * @len must only increase. |
152 | */ | 158 | */ |
153 | if (i && i >= len) | 159 | if (i && i >= len) { |
154 | pr_err("printk_nmi_flush: internal error: i=%d >= len=%zu\n", | 160 | const char *msg = "printk_nmi_flush: internal error\n"; |
155 | i, len); | 161 | |
162 | printk_nmi_flush_line(msg, strlen(msg)); | ||
163 | } | ||
156 | 164 | ||
157 | if (!len) | 165 | if (!len) |
158 | goto out; /* Someone else has already flushed the buffer. */ | 166 | goto out; /* Someone else has already flushed the buffer. */ |
@@ -166,14 +174,14 @@ more: | |||
166 | /* Print line by line. */ | 174 | /* Print line by line. */ |
167 | for (; i < size; i++) { | 175 | for (; i < size; i++) { |
168 | if (s->buffer[i] == '\n') { | 176 | if (s->buffer[i] == '\n') { |
169 | print_nmi_seq_line(s, last_i, i); | 177 | printk_nmi_flush_seq_line(s, last_i, i); |
170 | last_i = i + 1; | 178 | last_i = i + 1; |
171 | } | 179 | } |
172 | } | 180 | } |
173 | /* Check if there was a partial line. */ | 181 | /* Check if there was a partial line. */ |
174 | if (last_i < size) { | 182 | if (last_i < size) { |
175 | print_nmi_seq_line(s, last_i, size - 1); | 183 | printk_nmi_flush_seq_line(s, last_i, size - 1); |
176 | pr_cont("\n"); | 184 | printk_nmi_flush_line("\n", strlen("\n")); |
177 | } | 185 | } |
178 | 186 | ||
179 | /* | 187 | /* |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 2a906f20fba7..44817c640e99 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -2016,6 +2016,28 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) | |||
2016 | success = 1; /* we're going to change ->state */ | 2016 | success = 1; /* we're going to change ->state */ |
2017 | cpu = task_cpu(p); | 2017 | cpu = task_cpu(p); |
2018 | 2018 | ||
2019 | /* | ||
2020 | * Ensure we load p->on_rq _after_ p->state, otherwise it would | ||
2021 | * be possible to, falsely, observe p->on_rq == 0 and get stuck | ||
2022 | * in smp_cond_load_acquire() below. | ||
2023 | * | ||
2024 | * sched_ttwu_pending() try_to_wake_up() | ||
2025 | * [S] p->on_rq = 1; [L] P->state | ||
2026 | * UNLOCK rq->lock -----. | ||
2027 | * \ | ||
2028 | * +--- RMB | ||
2029 | * schedule() / | ||
2030 | * LOCK rq->lock -----' | ||
2031 | * UNLOCK rq->lock | ||
2032 | * | ||
2033 | * [task p] | ||
2034 | * [S] p->state = UNINTERRUPTIBLE [L] p->on_rq | ||
2035 | * | ||
2036 | * Pairs with the UNLOCK+LOCK on rq->lock from the | ||
2037 | * last wakeup of our task and the schedule that got our task | ||
2038 | * current. | ||
2039 | */ | ||
2040 | smp_rmb(); | ||
2019 | if (p->on_rq && ttwu_remote(p, wake_flags)) | 2041 | if (p->on_rq && ttwu_remote(p, wake_flags)) |
2020 | goto stat; | 2042 | goto stat; |
2021 | 2043 | ||
diff --git a/kernel/seccomp.c b/kernel/seccomp.c index ef6c6c3f9d8a..0db7c8a2afe2 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c | |||
@@ -605,12 +605,16 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd, | |||
605 | ptrace_event(PTRACE_EVENT_SECCOMP, data); | 605 | ptrace_event(PTRACE_EVENT_SECCOMP, data); |
606 | /* | 606 | /* |
607 | * The delivery of a fatal signal during event | 607 | * The delivery of a fatal signal during event |
608 | * notification may silently skip tracer notification. | 608 | * notification may silently skip tracer notification, |
609 | * Terminating the task now avoids executing a system | 609 | * which could leave us with a potentially unmodified |
610 | * call that may not be intended. | 610 | * syscall that the tracer would have liked to have |
611 | * changed. Since the process is about to die, we just | ||
612 | * force the syscall to be skipped and let the signal | ||
613 | * kill the process and correctly handle any tracer exit | ||
614 | * notifications. | ||
611 | */ | 615 | */ |
612 | if (fatal_signal_pending(current)) | 616 | if (fatal_signal_pending(current)) |
613 | do_exit(SIGSYS); | 617 | goto skip; |
614 | /* Check if the tracer forced the syscall to be skipped. */ | 618 | /* Check if the tracer forced the syscall to be skipped. */ |
615 | this_syscall = syscall_get_nr(current, task_pt_regs(current)); | 619 | this_syscall = syscall_get_nr(current, task_pt_regs(current)); |
616 | if (this_syscall < 0) | 620 | if (this_syscall < 0) |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index b43d0b27c1fe..a13bbdaab47d 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -2140,6 +2140,21 @@ static int do_proc_dointvec_conv(bool *negp, unsigned long *lvalp, | |||
2140 | return 0; | 2140 | return 0; |
2141 | } | 2141 | } |
2142 | 2142 | ||
2143 | static int do_proc_douintvec_conv(bool *negp, unsigned long *lvalp, | ||
2144 | int *valp, | ||
2145 | int write, void *data) | ||
2146 | { | ||
2147 | if (write) { | ||
2148 | if (*negp) | ||
2149 | return -EINVAL; | ||
2150 | *valp = *lvalp; | ||
2151 | } else { | ||
2152 | unsigned int val = *valp; | ||
2153 | *lvalp = (unsigned long)val; | ||
2154 | } | ||
2155 | return 0; | ||
2156 | } | ||
2157 | |||
2143 | static const char proc_wspace_sep[] = { ' ', '\t', '\n' }; | 2158 | static const char proc_wspace_sep[] = { ' ', '\t', '\n' }; |
2144 | 2159 | ||
2145 | static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, | 2160 | static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, |
@@ -2259,8 +2274,27 @@ static int do_proc_dointvec(struct ctl_table *table, int write, | |||
2259 | int proc_dointvec(struct ctl_table *table, int write, | 2274 | int proc_dointvec(struct ctl_table *table, int write, |
2260 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2275 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2261 | { | 2276 | { |
2262 | return do_proc_dointvec(table,write,buffer,lenp,ppos, | 2277 | return do_proc_dointvec(table, write, buffer, lenp, ppos, NULL, NULL); |
2263 | NULL,NULL); | 2278 | } |
2279 | |||
2280 | /** | ||
2281 | * proc_douintvec - read a vector of unsigned integers | ||
2282 | * @table: the sysctl table | ||
2283 | * @write: %TRUE if this is a write to the sysctl file | ||
2284 | * @buffer: the user buffer | ||
2285 | * @lenp: the size of the user buffer | ||
2286 | * @ppos: file position | ||
2287 | * | ||
2288 | * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer | ||
2289 | * values from/to the user buffer, treated as an ASCII string. | ||
2290 | * | ||
2291 | * Returns 0 on success. | ||
2292 | */ | ||
2293 | int proc_douintvec(struct ctl_table *table, int write, | ||
2294 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
2295 | { | ||
2296 | return do_proc_dointvec(table, write, buffer, lenp, ppos, | ||
2297 | do_proc_douintvec_conv, NULL); | ||
2264 | } | 2298 | } |
2265 | 2299 | ||
2266 | /* | 2300 | /* |
@@ -2858,6 +2892,12 @@ int proc_dointvec(struct ctl_table *table, int write, | |||
2858 | return -ENOSYS; | 2892 | return -ENOSYS; |
2859 | } | 2893 | } |
2860 | 2894 | ||
2895 | int proc_douintvec(struct ctl_table *table, int write, | ||
2896 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
2897 | { | ||
2898 | return -ENOSYS; | ||
2899 | } | ||
2900 | |||
2861 | int proc_dointvec_minmax(struct ctl_table *table, int write, | 2901 | int proc_dointvec_minmax(struct ctl_table *table, int write, |
2862 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2902 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2863 | { | 2903 | { |
@@ -2903,6 +2943,7 @@ int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, | |||
2903 | * exception granted :-) | 2943 | * exception granted :-) |
2904 | */ | 2944 | */ |
2905 | EXPORT_SYMBOL(proc_dointvec); | 2945 | EXPORT_SYMBOL(proc_dointvec); |
2946 | EXPORT_SYMBOL(proc_douintvec); | ||
2906 | EXPORT_SYMBOL(proc_dointvec_jiffies); | 2947 | EXPORT_SYMBOL(proc_dointvec_jiffies); |
2907 | EXPORT_SYMBOL(proc_dointvec_minmax); | 2948 | EXPORT_SYMBOL(proc_dointvec_minmax); |
2908 | EXPORT_SYMBOL(proc_dointvec_userhz_jiffies); | 2949 | EXPORT_SYMBOL(proc_dointvec_userhz_jiffies); |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 204fdc86863d..2ec7c00228f3 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -908,10 +908,11 @@ static void __tick_nohz_idle_enter(struct tick_sched *ts) | |||
908 | ktime_t now, expires; | 908 | ktime_t now, expires; |
909 | int cpu = smp_processor_id(); | 909 | int cpu = smp_processor_id(); |
910 | 910 | ||
911 | now = tick_nohz_start_idle(ts); | ||
912 | |||
911 | if (can_stop_idle_tick(cpu, ts)) { | 913 | if (can_stop_idle_tick(cpu, ts)) { |
912 | int was_stopped = ts->tick_stopped; | 914 | int was_stopped = ts->tick_stopped; |
913 | 915 | ||
914 | now = tick_nohz_start_idle(ts); | ||
915 | ts->idle_calls++; | 916 | ts->idle_calls++; |
916 | 917 | ||
917 | expires = tick_nohz_stop_sched_tick(ts, now, cpu); | 918 | expires = tick_nohz_stop_sched_tick(ts, now, cpu); |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 3b65746c7f15..e07fb093f819 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -401,7 +401,10 @@ static __always_inline u64 __ktime_get_fast_ns(struct tk_fast *tkf) | |||
401 | do { | 401 | do { |
402 | seq = raw_read_seqcount_latch(&tkf->seq); | 402 | seq = raw_read_seqcount_latch(&tkf->seq); |
403 | tkr = tkf->base + (seq & 0x01); | 403 | tkr = tkf->base + (seq & 0x01); |
404 | now = ktime_to_ns(tkr->base) + timekeeping_get_ns(tkr); | 404 | now = ktime_to_ns(tkr->base); |
405 | |||
406 | now += clocksource_delta(tkr->read(tkr->clock), | ||
407 | tkr->cycle_last, tkr->mask); | ||
405 | } while (read_seqcount_retry(&tkf->seq, seq)); | 408 | } while (read_seqcount_retry(&tkf->seq, seq)); |
406 | 409 | ||
407 | return now; | 410 | return now; |
diff --git a/kernel/time/timekeeping_debug.c b/kernel/time/timekeeping_debug.c index f6bd65236712..107310a6f36f 100644 --- a/kernel/time/timekeeping_debug.c +++ b/kernel/time/timekeeping_debug.c | |||
@@ -23,7 +23,9 @@ | |||
23 | 23 | ||
24 | #include "timekeeping_internal.h" | 24 | #include "timekeeping_internal.h" |
25 | 25 | ||
26 | static unsigned int sleep_time_bin[32] = {0}; | 26 | #define NUM_BINS 32 |
27 | |||
28 | static unsigned int sleep_time_bin[NUM_BINS] = {0}; | ||
27 | 29 | ||
28 | static int tk_debug_show_sleep_time(struct seq_file *s, void *data) | 30 | static int tk_debug_show_sleep_time(struct seq_file *s, void *data) |
29 | { | 31 | { |
@@ -69,6 +71,9 @@ late_initcall(tk_debug_sleep_time_init); | |||
69 | 71 | ||
70 | void tk_debug_account_sleep_time(struct timespec64 *t) | 72 | void tk_debug_account_sleep_time(struct timespec64 *t) |
71 | { | 73 | { |
72 | sleep_time_bin[fls(t->tv_sec)]++; | 74 | /* Cap bin index so we don't overflow the array */ |
75 | int bin = min(fls(t->tv_sec), NUM_BINS-1); | ||
76 | |||
77 | sleep_time_bin[bin]++; | ||
73 | } | 78 | } |
74 | 79 | ||
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 7598e6ca817a..dbafc5df03f3 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c | |||
@@ -223,7 +223,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, | |||
223 | what |= MASK_TC_BIT(op_flags, META); | 223 | what |= MASK_TC_BIT(op_flags, META); |
224 | what |= MASK_TC_BIT(op_flags, PREFLUSH); | 224 | what |= MASK_TC_BIT(op_flags, PREFLUSH); |
225 | what |= MASK_TC_BIT(op_flags, FUA); | 225 | what |= MASK_TC_BIT(op_flags, FUA); |
226 | if (op == REQ_OP_DISCARD) | 226 | if (op == REQ_OP_DISCARD || op == REQ_OP_SECURE_ERASE) |
227 | what |= BLK_TC_ACT(BLK_TC_DISCARD); | 227 | what |= BLK_TC_ACT(BLK_TC_DISCARD); |
228 | if (op == REQ_OP_FLUSH) | 228 | if (op == REQ_OP_FLUSH) |
229 | what |= BLK_TC_ACT(BLK_TC_FLUSH); | 229 | what |= BLK_TC_ACT(BLK_TC_FLUSH); |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index dade4c9559cc..7bc56762ca35 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -5124,19 +5124,20 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, | |||
5124 | struct trace_iterator *iter = filp->private_data; | 5124 | struct trace_iterator *iter = filp->private_data; |
5125 | ssize_t sret; | 5125 | ssize_t sret; |
5126 | 5126 | ||
5127 | /* return any leftover data */ | ||
5128 | sret = trace_seq_to_user(&iter->seq, ubuf, cnt); | ||
5129 | if (sret != -EBUSY) | ||
5130 | return sret; | ||
5131 | |||
5132 | trace_seq_init(&iter->seq); | ||
5133 | |||
5134 | /* | 5127 | /* |
5135 | * Avoid more than one consumer on a single file descriptor | 5128 | * Avoid more than one consumer on a single file descriptor |
5136 | * This is just a matter of traces coherency, the ring buffer itself | 5129 | * This is just a matter of traces coherency, the ring buffer itself |
5137 | * is protected. | 5130 | * is protected. |
5138 | */ | 5131 | */ |
5139 | mutex_lock(&iter->mutex); | 5132 | mutex_lock(&iter->mutex); |
5133 | |||
5134 | /* return any leftover data */ | ||
5135 | sret = trace_seq_to_user(&iter->seq, ubuf, cnt); | ||
5136 | if (sret != -EBUSY) | ||
5137 | goto out; | ||
5138 | |||
5139 | trace_seq_init(&iter->seq); | ||
5140 | |||
5140 | if (iter->trace->read) { | 5141 | if (iter->trace->read) { |
5141 | sret = iter->trace->read(iter, filp, ubuf, cnt, ppos); | 5142 | sret = iter->trace->read(iter, filp, ubuf, cnt, ppos); |
5142 | if (sret) | 5143 | if (sret) |
@@ -6163,9 +6164,6 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
6163 | return -EBUSY; | 6164 | return -EBUSY; |
6164 | #endif | 6165 | #endif |
6165 | 6166 | ||
6166 | if (splice_grow_spd(pipe, &spd)) | ||
6167 | return -ENOMEM; | ||
6168 | |||
6169 | if (*ppos & (PAGE_SIZE - 1)) | 6167 | if (*ppos & (PAGE_SIZE - 1)) |
6170 | return -EINVAL; | 6168 | return -EINVAL; |
6171 | 6169 | ||
@@ -6175,6 +6173,9 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
6175 | len &= PAGE_MASK; | 6173 | len &= PAGE_MASK; |
6176 | } | 6174 | } |
6177 | 6175 | ||
6176 | if (splice_grow_spd(pipe, &spd)) | ||
6177 | return -ENOMEM; | ||
6178 | |||
6178 | again: | 6179 | again: |
6179 | trace_access_lock(iter->cpu_file); | 6180 | trace_access_lock(iter->cpu_file); |
6180 | entries = ring_buffer_entries_cpu(iter->trace_buffer->buffer, iter->cpu_file); | 6181 | entries = ring_buffer_entries_cpu(iter->trace_buffer->buffer, iter->cpu_file); |
@@ -6232,19 +6233,21 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
6232 | /* did we read anything? */ | 6233 | /* did we read anything? */ |
6233 | if (!spd.nr_pages) { | 6234 | if (!spd.nr_pages) { |
6234 | if (ret) | 6235 | if (ret) |
6235 | return ret; | 6236 | goto out; |
6236 | 6237 | ||
6238 | ret = -EAGAIN; | ||
6237 | if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK)) | 6239 | if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK)) |
6238 | return -EAGAIN; | 6240 | goto out; |
6239 | 6241 | ||
6240 | ret = wait_on_pipe(iter, true); | 6242 | ret = wait_on_pipe(iter, true); |
6241 | if (ret) | 6243 | if (ret) |
6242 | return ret; | 6244 | goto out; |
6243 | 6245 | ||
6244 | goto again; | 6246 | goto again; |
6245 | } | 6247 | } |
6246 | 6248 | ||
6247 | ret = splice_to_pipe(pipe, &spd); | 6249 | ret = splice_to_pipe(pipe, &spd); |
6250 | out: | ||
6248 | splice_shrink_spd(&spd); | 6251 | splice_shrink_spd(&spd); |
6249 | 6252 | ||
6250 | return ret; | 6253 | return ret; |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 2307d7c89dac..cab7405f48d2 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -821,7 +821,7 @@ config DETECT_HUNG_TASK | |||
821 | help | 821 | help |
822 | Say Y here to enable the kernel to detect "hung tasks", | 822 | Say Y here to enable the kernel to detect "hung tasks", |
823 | which are bugs that cause the task to be stuck in | 823 | which are bugs that cause the task to be stuck in |
824 | uninterruptible "D" state indefinitiley. | 824 | uninterruptible "D" state indefinitely. |
825 | 825 | ||
826 | When a hung task is detected, the kernel will print the | 826 | When a hung task is detected, the kernel will print the |
827 | current stack trace (which you should report), but the | 827 | current stack trace (which you should report), but the |
@@ -1686,24 +1686,6 @@ config LATENCYTOP | |||
1686 | Enable this option if you want to use the LatencyTOP tool | 1686 | Enable this option if you want to use the LatencyTOP tool |
1687 | to find out which userspace is blocking on what kernel operations. | 1687 | to find out which userspace is blocking on what kernel operations. |
1688 | 1688 | ||
1689 | config ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS | ||
1690 | bool | ||
1691 | |||
1692 | config DEBUG_STRICT_USER_COPY_CHECKS | ||
1693 | bool "Strict user copy size checks" | ||
1694 | depends on ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS | ||
1695 | depends on DEBUG_KERNEL && !TRACE_BRANCH_PROFILING | ||
1696 | help | ||
1697 | Enabling this option turns a certain set of sanity checks for user | ||
1698 | copy operations into compile time failures. | ||
1699 | |||
1700 | The copy_from_user() etc checks are there to help test if there | ||
1701 | are sufficient security checks on the length argument of | ||
1702 | the copy operation, by having gcc prove that the argument is | ||
1703 | within bounds. | ||
1704 | |||
1705 | If unsure, say N. | ||
1706 | |||
1707 | source kernel/trace/Kconfig | 1689 | source kernel/trace/Kconfig |
1708 | 1690 | ||
1709 | menu "Runtime Testing" | 1691 | menu "Runtime Testing" |
diff --git a/lib/Makefile b/lib/Makefile index cfa68eb269e4..5dc77a8ec297 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -24,7 +24,6 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ | |||
24 | is_single_threaded.o plist.o decompress.o kobject_uevent.o \ | 24 | is_single_threaded.o plist.o decompress.o kobject_uevent.o \ |
25 | earlycpio.o seq_buf.o nmi_backtrace.o nodemask.o | 25 | earlycpio.o seq_buf.o nmi_backtrace.o nodemask.o |
26 | 26 | ||
27 | obj-$(CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS) += usercopy.o | ||
28 | lib-$(CONFIG_MMU) += ioremap.o | 27 | lib-$(CONFIG_MMU) += ioremap.o |
29 | lib-$(CONFIG_SMP) += cpumask.o | 28 | lib-$(CONFIG_SMP) += cpumask.o |
30 | lib-$(CONFIG_HAS_DMA) += dma-noop.o | 29 | lib-$(CONFIG_HAS_DMA) += dma-noop.o |
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 9e8c7386b3a0..7e3138cfc8c9 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c | |||
@@ -291,33 +291,13 @@ done: | |||
291 | } | 291 | } |
292 | 292 | ||
293 | /* | 293 | /* |
294 | * Fault in the first iovec of the given iov_iter, to a maximum length | ||
295 | * of bytes. Returns 0 on success, or non-zero if the memory could not be | ||
296 | * accessed (ie. because it is an invalid address). | ||
297 | * | ||
298 | * writev-intensive code may want this to prefault several iovecs -- that | ||
299 | * would be possible (callers must not rely on the fact that _only_ the | ||
300 | * first iovec will be faulted with the current implementation). | ||
301 | */ | ||
302 | int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes) | ||
303 | { | ||
304 | if (!(i->type & (ITER_BVEC|ITER_KVEC))) { | ||
305 | char __user *buf = i->iov->iov_base + i->iov_offset; | ||
306 | bytes = min(bytes, i->iov->iov_len - i->iov_offset); | ||
307 | return fault_in_pages_readable(buf, bytes); | ||
308 | } | ||
309 | return 0; | ||
310 | } | ||
311 | EXPORT_SYMBOL(iov_iter_fault_in_readable); | ||
312 | |||
313 | /* | ||
314 | * Fault in one or more iovecs of the given iov_iter, to a maximum length of | 294 | * Fault in one or more iovecs of the given iov_iter, to a maximum length of |
315 | * bytes. For each iovec, fault in each page that constitutes the iovec. | 295 | * bytes. For each iovec, fault in each page that constitutes the iovec. |
316 | * | 296 | * |
317 | * Return 0 on success, or non-zero if the memory could not be accessed (i.e. | 297 | * Return 0 on success, or non-zero if the memory could not be accessed (i.e. |
318 | * because it is an invalid address). | 298 | * because it is an invalid address). |
319 | */ | 299 | */ |
320 | int iov_iter_fault_in_multipages_readable(struct iov_iter *i, size_t bytes) | 300 | int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes) |
321 | { | 301 | { |
322 | size_t skip = i->iov_offset; | 302 | size_t skip = i->iov_offset; |
323 | const struct iovec *iov; | 303 | const struct iovec *iov; |
@@ -334,7 +314,7 @@ int iov_iter_fault_in_multipages_readable(struct iov_iter *i, size_t bytes) | |||
334 | } | 314 | } |
335 | return 0; | 315 | return 0; |
336 | } | 316 | } |
337 | EXPORT_SYMBOL(iov_iter_fault_in_multipages_readable); | 317 | EXPORT_SYMBOL(iov_iter_fault_in_readable); |
338 | 318 | ||
339 | void iov_iter_init(struct iov_iter *i, int direction, | 319 | void iov_iter_init(struct iov_iter *i, int direction, |
340 | const struct iovec *iov, unsigned long nr_segs, | 320 | const struct iovec *iov, unsigned long nr_segs, |
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 1b7bf7314141..91f0727e3cad 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -105,10 +105,10 @@ static unsigned int radix_tree_descend(struct radix_tree_node *parent, | |||
105 | 105 | ||
106 | #ifdef CONFIG_RADIX_TREE_MULTIORDER | 106 | #ifdef CONFIG_RADIX_TREE_MULTIORDER |
107 | if (radix_tree_is_internal_node(entry)) { | 107 | if (radix_tree_is_internal_node(entry)) { |
108 | unsigned long siboff = get_slot_offset(parent, entry); | 108 | if (is_sibling_entry(parent, entry)) { |
109 | if (siboff < RADIX_TREE_MAP_SIZE) { | 109 | void **sibentry = (void **) entry_to_node(entry); |
110 | offset = siboff; | 110 | offset = get_slot_offset(parent, sibentry); |
111 | entry = rcu_dereference_raw(parent->slots[offset]); | 111 | entry = rcu_dereference_raw(*sibentry); |
112 | } | 112 | } |
113 | } | 113 | } |
114 | #endif | 114 | #endif |
diff --git a/lib/rhashtable.c b/lib/rhashtable.c index 5ba520b544d7..56054e541a0f 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c | |||
@@ -77,17 +77,18 @@ static int alloc_bucket_locks(struct rhashtable *ht, struct bucket_table *tbl, | |||
77 | size = min_t(unsigned int, size, tbl->size >> 1); | 77 | size = min_t(unsigned int, size, tbl->size >> 1); |
78 | 78 | ||
79 | if (sizeof(spinlock_t) != 0) { | 79 | if (sizeof(spinlock_t) != 0) { |
80 | tbl->locks = NULL; | ||
80 | #ifdef CONFIG_NUMA | 81 | #ifdef CONFIG_NUMA |
81 | if (size * sizeof(spinlock_t) > PAGE_SIZE && | 82 | if (size * sizeof(spinlock_t) > PAGE_SIZE && |
82 | gfp == GFP_KERNEL) | 83 | gfp == GFP_KERNEL) |
83 | tbl->locks = vmalloc(size * sizeof(spinlock_t)); | 84 | tbl->locks = vmalloc(size * sizeof(spinlock_t)); |
84 | else | ||
85 | #endif | 85 | #endif |
86 | if (gfp != GFP_KERNEL) | 86 | if (gfp != GFP_KERNEL) |
87 | gfp |= __GFP_NOWARN | __GFP_NORETRY; | 87 | gfp |= __GFP_NOWARN | __GFP_NORETRY; |
88 | 88 | ||
89 | tbl->locks = kmalloc_array(size, sizeof(spinlock_t), | 89 | if (!tbl->locks) |
90 | gfp); | 90 | tbl->locks = kmalloc_array(size, sizeof(spinlock_t), |
91 | gfp); | ||
91 | if (!tbl->locks) | 92 | if (!tbl->locks) |
92 | return -ENOMEM; | 93 | return -ENOMEM; |
93 | for (i = 0; i < size; i++) | 94 | for (i = 0; i < size; i++) |
diff --git a/lib/test_hash.c b/lib/test_hash.c index 66c5fc8351e8..cac20c5fb304 100644 --- a/lib/test_hash.c +++ b/lib/test_hash.c | |||
@@ -143,7 +143,7 @@ static int __init | |||
143 | test_hash_init(void) | 143 | test_hash_init(void) |
144 | { | 144 | { |
145 | char buf[SIZE+1]; | 145 | char buf[SIZE+1]; |
146 | u32 string_or = 0, hash_or[2][33] = { 0 }; | 146 | u32 string_or = 0, hash_or[2][33] = { { 0, } }; |
147 | unsigned tests = 0; | 147 | unsigned tests = 0; |
148 | unsigned long long h64 = 0; | 148 | unsigned long long h64 = 0; |
149 | int i, j; | 149 | int i, j; |
@@ -219,21 +219,27 @@ test_hash_init(void) | |||
219 | } | 219 | } |
220 | 220 | ||
221 | /* Issue notices about skipped tests. */ | 221 | /* Issue notices about skipped tests. */ |
222 | #ifndef HAVE_ARCH__HASH_32 | 222 | #ifdef HAVE_ARCH__HASH_32 |
223 | pr_info("__hash_32() has no arch implementation to test."); | 223 | #if HAVE_ARCH__HASH_32 != 1 |
224 | #elif HAVE_ARCH__HASH_32 != 1 | ||
225 | pr_info("__hash_32() is arch-specific; not compared to generic."); | 224 | pr_info("__hash_32() is arch-specific; not compared to generic."); |
226 | #endif | 225 | #endif |
227 | #ifndef HAVE_ARCH_HASH_32 | 226 | #else |
228 | pr_info("hash_32() has no arch implementation to test."); | 227 | pr_info("__hash_32() has no arch implementation to test."); |
229 | #elif HAVE_ARCH_HASH_32 != 1 | 228 | #endif |
229 | #ifdef HAVE_ARCH_HASH_32 | ||
230 | #if HAVE_ARCH_HASH_32 != 1 | ||
230 | pr_info("hash_32() is arch-specific; not compared to generic."); | 231 | pr_info("hash_32() is arch-specific; not compared to generic."); |
231 | #endif | 232 | #endif |
232 | #ifndef HAVE_ARCH_HASH_64 | 233 | #else |
233 | pr_info("hash_64() has no arch implementation to test."); | 234 | pr_info("hash_32() has no arch implementation to test."); |
234 | #elif HAVE_ARCH_HASH_64 != 1 | 235 | #endif |
236 | #ifdef HAVE_ARCH_HASH_64 | ||
237 | #if HAVE_ARCH_HASH_64 != 1 | ||
235 | pr_info("hash_64() is arch-specific; not compared to generic."); | 238 | pr_info("hash_64() is arch-specific; not compared to generic."); |
236 | #endif | 239 | #endif |
240 | #else | ||
241 | pr_info("hash_64() has no arch implementation to test."); | ||
242 | #endif | ||
237 | 243 | ||
238 | pr_notice("%u tests passed.", tests); | 244 | pr_notice("%u tests passed.", tests); |
239 | 245 | ||
diff --git a/lib/usercopy.c b/lib/usercopy.c deleted file mode 100644 index 4f5b1ddbcd25..000000000000 --- a/lib/usercopy.c +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | #include <linux/export.h> | ||
2 | #include <linux/bug.h> | ||
3 | #include <linux/uaccess.h> | ||
4 | |||
5 | void copy_from_user_overflow(void) | ||
6 | { | ||
7 | WARN(1, "Buffer overflow detected!\n"); | ||
8 | } | ||
9 | EXPORT_SYMBOL(copy_from_user_overflow); | ||
diff --git a/mm/Kconfig b/mm/Kconfig index 78a23c5c302d..be0ee11fa0d9 100644 --- a/mm/Kconfig +++ b/mm/Kconfig | |||
@@ -262,7 +262,14 @@ config COMPACTION | |||
262 | select MIGRATION | 262 | select MIGRATION |
263 | depends on MMU | 263 | depends on MMU |
264 | help | 264 | help |
265 | Allows the compaction of memory for the allocation of huge pages. | 265 | Compaction is the only memory management component to form |
266 | high order (larger physically contiguous) memory blocks | ||
267 | reliably. The page allocator relies on compaction heavily and | ||
268 | the lack of the feature can lead to unexpected OOM killer | ||
269 | invocations for high order memory requests. You shouldn't | ||
270 | disable this option unless there really is a strong reason for | ||
271 | it and then we would be really interested to hear about that at | ||
272 | linux-mm@kvack.org. | ||
266 | 273 | ||
267 | # | 274 | # |
268 | # support for page migration | 275 | # support for page migration |
diff --git a/mm/debug.c b/mm/debug.c index 8865bfb41b0b..74c7cae4f683 100644 --- a/mm/debug.c +++ b/mm/debug.c | |||
@@ -42,9 +42,11 @@ const struct trace_print_flags vmaflag_names[] = { | |||
42 | 42 | ||
43 | void __dump_page(struct page *page, const char *reason) | 43 | void __dump_page(struct page *page, const char *reason) |
44 | { | 44 | { |
45 | int mapcount = PageSlab(page) ? 0 : page_mapcount(page); | ||
46 | |||
45 | pr_emerg("page:%p count:%d mapcount:%d mapping:%p index:%#lx", | 47 | pr_emerg("page:%p count:%d mapcount:%d mapping:%p index:%#lx", |
46 | page, page_ref_count(page), page_mapcount(page), | 48 | page, page_ref_count(page), mapcount, |
47 | page->mapping, page->index); | 49 | page->mapping, page_to_pgoff(page)); |
48 | if (PageCompound(page)) | 50 | if (PageCompound(page)) |
49 | pr_cont(" compound_mapcount: %d", compound_mapcount(page)); | 51 | pr_cont(" compound_mapcount: %d", compound_mapcount(page)); |
50 | pr_cont("\n"); | 52 | pr_cont("\n"); |
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 2373f0a7d340..53ae6d00656a 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
@@ -1078,7 +1078,7 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma, | |||
1078 | goto out; | 1078 | goto out; |
1079 | 1079 | ||
1080 | page = pmd_page(*pmd); | 1080 | page = pmd_page(*pmd); |
1081 | VM_BUG_ON_PAGE(!PageHead(page), page); | 1081 | VM_BUG_ON_PAGE(!PageHead(page) && !is_zone_device_page(page), page); |
1082 | if (flags & FOLL_TOUCH) | 1082 | if (flags & FOLL_TOUCH) |
1083 | touch_pmd(vma, addr, pmd); | 1083 | touch_pmd(vma, addr, pmd); |
1084 | if ((flags & FOLL_MLOCK) && (vma->vm_flags & VM_LOCKED)) { | 1084 | if ((flags & FOLL_MLOCK) && (vma->vm_flags & VM_LOCKED)) { |
@@ -1116,7 +1116,7 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma, | |||
1116 | } | 1116 | } |
1117 | skip_mlock: | 1117 | skip_mlock: |
1118 | page += (addr & ~HPAGE_PMD_MASK) >> PAGE_SHIFT; | 1118 | page += (addr & ~HPAGE_PMD_MASK) >> PAGE_SHIFT; |
1119 | VM_BUG_ON_PAGE(!PageCompound(page), page); | 1119 | VM_BUG_ON_PAGE(!PageCompound(page) && !is_zone_device_page(page), page); |
1120 | if (flags & FOLL_GET) | 1120 | if (flags & FOLL_GET) |
1121 | get_page(page); | 1121 | get_page(page); |
1122 | 1122 | ||
@@ -1138,9 +1138,6 @@ int do_huge_pmd_numa_page(struct fault_env *fe, pmd_t pmd) | |||
1138 | bool was_writable; | 1138 | bool was_writable; |
1139 | int flags = 0; | 1139 | int flags = 0; |
1140 | 1140 | ||
1141 | /* A PROT_NONE fault should not end up here */ | ||
1142 | BUG_ON(!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))); | ||
1143 | |||
1144 | fe->ptl = pmd_lock(vma->vm_mm, fe->pmd); | 1141 | fe->ptl = pmd_lock(vma->vm_mm, fe->pmd); |
1145 | if (unlikely(!pmd_same(pmd, *fe->pmd))) | 1142 | if (unlikely(!pmd_same(pmd, *fe->pmd))) |
1146 | goto out_unlock; | 1143 | goto out_unlock; |
@@ -1512,7 +1509,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, | |||
1512 | struct page *page; | 1509 | struct page *page; |
1513 | pgtable_t pgtable; | 1510 | pgtable_t pgtable; |
1514 | pmd_t _pmd; | 1511 | pmd_t _pmd; |
1515 | bool young, write, dirty; | 1512 | bool young, write, dirty, soft_dirty; |
1516 | unsigned long addr; | 1513 | unsigned long addr; |
1517 | int i; | 1514 | int i; |
1518 | 1515 | ||
@@ -1546,6 +1543,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, | |||
1546 | write = pmd_write(*pmd); | 1543 | write = pmd_write(*pmd); |
1547 | young = pmd_young(*pmd); | 1544 | young = pmd_young(*pmd); |
1548 | dirty = pmd_dirty(*pmd); | 1545 | dirty = pmd_dirty(*pmd); |
1546 | soft_dirty = pmd_soft_dirty(*pmd); | ||
1549 | 1547 | ||
1550 | pmdp_huge_split_prepare(vma, haddr, pmd); | 1548 | pmdp_huge_split_prepare(vma, haddr, pmd); |
1551 | pgtable = pgtable_trans_huge_withdraw(mm, pmd); | 1549 | pgtable = pgtable_trans_huge_withdraw(mm, pmd); |
@@ -1562,6 +1560,8 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, | |||
1562 | swp_entry_t swp_entry; | 1560 | swp_entry_t swp_entry; |
1563 | swp_entry = make_migration_entry(page + i, write); | 1561 | swp_entry = make_migration_entry(page + i, write); |
1564 | entry = swp_entry_to_pte(swp_entry); | 1562 | entry = swp_entry_to_pte(swp_entry); |
1563 | if (soft_dirty) | ||
1564 | entry = pte_swp_mksoft_dirty(entry); | ||
1565 | } else { | 1565 | } else { |
1566 | entry = mk_pte(page + i, vma->vm_page_prot); | 1566 | entry = mk_pte(page + i, vma->vm_page_prot); |
1567 | entry = maybe_mkwrite(entry, vma); | 1567 | entry = maybe_mkwrite(entry, vma); |
@@ -1569,6 +1569,8 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, | |||
1569 | entry = pte_wrprotect(entry); | 1569 | entry = pte_wrprotect(entry); |
1570 | if (!young) | 1570 | if (!young) |
1571 | entry = pte_mkold(entry); | 1571 | entry = pte_mkold(entry); |
1572 | if (soft_dirty) | ||
1573 | entry = pte_mksoft_dirty(entry); | ||
1572 | } | 1574 | } |
1573 | if (dirty) | 1575 | if (dirty) |
1574 | SetPageDirty(page + i); | 1576 | SetPageDirty(page + i); |
diff --git a/mm/khugepaged.c b/mm/khugepaged.c index 79c52d0061af..728d7790dc2d 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c | |||
@@ -838,7 +838,8 @@ static bool hugepage_vma_check(struct vm_area_struct *vma) | |||
838 | * value (scan code). | 838 | * value (scan code). |
839 | */ | 839 | */ |
840 | 840 | ||
841 | static int hugepage_vma_revalidate(struct mm_struct *mm, unsigned long address) | 841 | static int hugepage_vma_revalidate(struct mm_struct *mm, unsigned long address, |
842 | struct vm_area_struct **vmap) | ||
842 | { | 843 | { |
843 | struct vm_area_struct *vma; | 844 | struct vm_area_struct *vma; |
844 | unsigned long hstart, hend; | 845 | unsigned long hstart, hend; |
@@ -846,7 +847,7 @@ static int hugepage_vma_revalidate(struct mm_struct *mm, unsigned long address) | |||
846 | if (unlikely(khugepaged_test_exit(mm))) | 847 | if (unlikely(khugepaged_test_exit(mm))) |
847 | return SCAN_ANY_PROCESS; | 848 | return SCAN_ANY_PROCESS; |
848 | 849 | ||
849 | vma = find_vma(mm, address); | 850 | *vmap = vma = find_vma(mm, address); |
850 | if (!vma) | 851 | if (!vma) |
851 | return SCAN_VMA_NULL; | 852 | return SCAN_VMA_NULL; |
852 | 853 | ||
@@ -881,6 +882,11 @@ static bool __collapse_huge_page_swapin(struct mm_struct *mm, | |||
881 | .pmd = pmd, | 882 | .pmd = pmd, |
882 | }; | 883 | }; |
883 | 884 | ||
885 | /* we only decide to swapin, if there is enough young ptes */ | ||
886 | if (referenced < HPAGE_PMD_NR/2) { | ||
887 | trace_mm_collapse_huge_page_swapin(mm, swapped_in, referenced, 0); | ||
888 | return false; | ||
889 | } | ||
884 | fe.pte = pte_offset_map(pmd, address); | 890 | fe.pte = pte_offset_map(pmd, address); |
885 | for (; fe.address < address + HPAGE_PMD_NR*PAGE_SIZE; | 891 | for (; fe.address < address + HPAGE_PMD_NR*PAGE_SIZE; |
886 | fe.pte++, fe.address += PAGE_SIZE) { | 892 | fe.pte++, fe.address += PAGE_SIZE) { |
@@ -888,17 +894,12 @@ static bool __collapse_huge_page_swapin(struct mm_struct *mm, | |||
888 | if (!is_swap_pte(pteval)) | 894 | if (!is_swap_pte(pteval)) |
889 | continue; | 895 | continue; |
890 | swapped_in++; | 896 | swapped_in++; |
891 | /* we only decide to swapin, if there is enough young ptes */ | ||
892 | if (referenced < HPAGE_PMD_NR/2) { | ||
893 | trace_mm_collapse_huge_page_swapin(mm, swapped_in, referenced, 0); | ||
894 | return false; | ||
895 | } | ||
896 | ret = do_swap_page(&fe, pteval); | 897 | ret = do_swap_page(&fe, pteval); |
897 | 898 | ||
898 | /* do_swap_page returns VM_FAULT_RETRY with released mmap_sem */ | 899 | /* do_swap_page returns VM_FAULT_RETRY with released mmap_sem */ |
899 | if (ret & VM_FAULT_RETRY) { | 900 | if (ret & VM_FAULT_RETRY) { |
900 | down_read(&mm->mmap_sem); | 901 | down_read(&mm->mmap_sem); |
901 | if (hugepage_vma_revalidate(mm, address)) { | 902 | if (hugepage_vma_revalidate(mm, address, &fe.vma)) { |
902 | /* vma is no longer available, don't continue to swapin */ | 903 | /* vma is no longer available, don't continue to swapin */ |
903 | trace_mm_collapse_huge_page_swapin(mm, swapped_in, referenced, 0); | 904 | trace_mm_collapse_huge_page_swapin(mm, swapped_in, referenced, 0); |
904 | return false; | 905 | return false; |
@@ -923,7 +924,6 @@ static bool __collapse_huge_page_swapin(struct mm_struct *mm, | |||
923 | static void collapse_huge_page(struct mm_struct *mm, | 924 | static void collapse_huge_page(struct mm_struct *mm, |
924 | unsigned long address, | 925 | unsigned long address, |
925 | struct page **hpage, | 926 | struct page **hpage, |
926 | struct vm_area_struct *vma, | ||
927 | int node, int referenced) | 927 | int node, int referenced) |
928 | { | 928 | { |
929 | pmd_t *pmd, _pmd; | 929 | pmd_t *pmd, _pmd; |
@@ -933,6 +933,7 @@ static void collapse_huge_page(struct mm_struct *mm, | |||
933 | spinlock_t *pmd_ptl, *pte_ptl; | 933 | spinlock_t *pmd_ptl, *pte_ptl; |
934 | int isolated = 0, result = 0; | 934 | int isolated = 0, result = 0; |
935 | struct mem_cgroup *memcg; | 935 | struct mem_cgroup *memcg; |
936 | struct vm_area_struct *vma; | ||
936 | unsigned long mmun_start; /* For mmu_notifiers */ | 937 | unsigned long mmun_start; /* For mmu_notifiers */ |
937 | unsigned long mmun_end; /* For mmu_notifiers */ | 938 | unsigned long mmun_end; /* For mmu_notifiers */ |
938 | gfp_t gfp; | 939 | gfp_t gfp; |
@@ -961,7 +962,7 @@ static void collapse_huge_page(struct mm_struct *mm, | |||
961 | } | 962 | } |
962 | 963 | ||
963 | down_read(&mm->mmap_sem); | 964 | down_read(&mm->mmap_sem); |
964 | result = hugepage_vma_revalidate(mm, address); | 965 | result = hugepage_vma_revalidate(mm, address, &vma); |
965 | if (result) { | 966 | if (result) { |
966 | mem_cgroup_cancel_charge(new_page, memcg, true); | 967 | mem_cgroup_cancel_charge(new_page, memcg, true); |
967 | up_read(&mm->mmap_sem); | 968 | up_read(&mm->mmap_sem); |
@@ -994,7 +995,7 @@ static void collapse_huge_page(struct mm_struct *mm, | |||
994 | * handled by the anon_vma lock + PG_lock. | 995 | * handled by the anon_vma lock + PG_lock. |
995 | */ | 996 | */ |
996 | down_write(&mm->mmap_sem); | 997 | down_write(&mm->mmap_sem); |
997 | result = hugepage_vma_revalidate(mm, address); | 998 | result = hugepage_vma_revalidate(mm, address, &vma); |
998 | if (result) | 999 | if (result) |
999 | goto out; | 1000 | goto out; |
1000 | /* check if the pmd is still valid */ | 1001 | /* check if the pmd is still valid */ |
@@ -1202,7 +1203,7 @@ out_unmap: | |||
1202 | if (ret) { | 1203 | if (ret) { |
1203 | node = khugepaged_find_target_node(); | 1204 | node = khugepaged_find_target_node(); |
1204 | /* collapse_huge_page will return with the mmap_sem released */ | 1205 | /* collapse_huge_page will return with the mmap_sem released */ |
1205 | collapse_huge_page(mm, address, hpage, vma, node, referenced); | 1206 | collapse_huge_page(mm, address, hpage, node, referenced); |
1206 | } | 1207 | } |
1207 | out: | 1208 | out: |
1208 | trace_mm_khugepaged_scan_pmd(mm, page, writable, referenced, | 1209 | trace_mm_khugepaged_scan_pmd(mm, page, writable, referenced, |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 2ff0289ad061..4be518d4e68a 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -1740,17 +1740,22 @@ static DEFINE_MUTEX(percpu_charge_mutex); | |||
1740 | static bool consume_stock(struct mem_cgroup *memcg, unsigned int nr_pages) | 1740 | static bool consume_stock(struct mem_cgroup *memcg, unsigned int nr_pages) |
1741 | { | 1741 | { |
1742 | struct memcg_stock_pcp *stock; | 1742 | struct memcg_stock_pcp *stock; |
1743 | unsigned long flags; | ||
1743 | bool ret = false; | 1744 | bool ret = false; |
1744 | 1745 | ||
1745 | if (nr_pages > CHARGE_BATCH) | 1746 | if (nr_pages > CHARGE_BATCH) |
1746 | return ret; | 1747 | return ret; |
1747 | 1748 | ||
1748 | stock = &get_cpu_var(memcg_stock); | 1749 | local_irq_save(flags); |
1750 | |||
1751 | stock = this_cpu_ptr(&memcg_stock); | ||
1749 | if (memcg == stock->cached && stock->nr_pages >= nr_pages) { | 1752 | if (memcg == stock->cached && stock->nr_pages >= nr_pages) { |
1750 | stock->nr_pages -= nr_pages; | 1753 | stock->nr_pages -= nr_pages; |
1751 | ret = true; | 1754 | ret = true; |
1752 | } | 1755 | } |
1753 | put_cpu_var(memcg_stock); | 1756 | |
1757 | local_irq_restore(flags); | ||
1758 | |||
1754 | return ret; | 1759 | return ret; |
1755 | } | 1760 | } |
1756 | 1761 | ||
@@ -1771,15 +1776,18 @@ static void drain_stock(struct memcg_stock_pcp *stock) | |||
1771 | stock->cached = NULL; | 1776 | stock->cached = NULL; |
1772 | } | 1777 | } |
1773 | 1778 | ||
1774 | /* | ||
1775 | * This must be called under preempt disabled or must be called by | ||
1776 | * a thread which is pinned to local cpu. | ||
1777 | */ | ||
1778 | static void drain_local_stock(struct work_struct *dummy) | 1779 | static void drain_local_stock(struct work_struct *dummy) |
1779 | { | 1780 | { |
1780 | struct memcg_stock_pcp *stock = this_cpu_ptr(&memcg_stock); | 1781 | struct memcg_stock_pcp *stock; |
1782 | unsigned long flags; | ||
1783 | |||
1784 | local_irq_save(flags); | ||
1785 | |||
1786 | stock = this_cpu_ptr(&memcg_stock); | ||
1781 | drain_stock(stock); | 1787 | drain_stock(stock); |
1782 | clear_bit(FLUSHING_CACHED_CHARGE, &stock->flags); | 1788 | clear_bit(FLUSHING_CACHED_CHARGE, &stock->flags); |
1789 | |||
1790 | local_irq_restore(flags); | ||
1783 | } | 1791 | } |
1784 | 1792 | ||
1785 | /* | 1793 | /* |
@@ -1788,14 +1796,19 @@ static void drain_local_stock(struct work_struct *dummy) | |||
1788 | */ | 1796 | */ |
1789 | static void refill_stock(struct mem_cgroup *memcg, unsigned int nr_pages) | 1797 | static void refill_stock(struct mem_cgroup *memcg, unsigned int nr_pages) |
1790 | { | 1798 | { |
1791 | struct memcg_stock_pcp *stock = &get_cpu_var(memcg_stock); | 1799 | struct memcg_stock_pcp *stock; |
1800 | unsigned long flags; | ||
1801 | |||
1802 | local_irq_save(flags); | ||
1792 | 1803 | ||
1804 | stock = this_cpu_ptr(&memcg_stock); | ||
1793 | if (stock->cached != memcg) { /* reset if necessary */ | 1805 | if (stock->cached != memcg) { /* reset if necessary */ |
1794 | drain_stock(stock); | 1806 | drain_stock(stock); |
1795 | stock->cached = memcg; | 1807 | stock->cached = memcg; |
1796 | } | 1808 | } |
1797 | stock->nr_pages += nr_pages; | 1809 | stock->nr_pages += nr_pages; |
1798 | put_cpu_var(memcg_stock); | 1810 | |
1811 | local_irq_restore(flags); | ||
1799 | } | 1812 | } |
1800 | 1813 | ||
1801 | /* | 1814 | /* |
@@ -4082,24 +4095,6 @@ static void mem_cgroup_id_get_many(struct mem_cgroup *memcg, unsigned int n) | |||
4082 | atomic_add(n, &memcg->id.ref); | 4095 | atomic_add(n, &memcg->id.ref); |
4083 | } | 4096 | } |
4084 | 4097 | ||
4085 | static struct mem_cgroup *mem_cgroup_id_get_online(struct mem_cgroup *memcg) | ||
4086 | { | ||
4087 | while (!atomic_inc_not_zero(&memcg->id.ref)) { | ||
4088 | /* | ||
4089 | * The root cgroup cannot be destroyed, so it's refcount must | ||
4090 | * always be >= 1. | ||
4091 | */ | ||
4092 | if (WARN_ON_ONCE(memcg == root_mem_cgroup)) { | ||
4093 | VM_BUG_ON(1); | ||
4094 | break; | ||
4095 | } | ||
4096 | memcg = parent_mem_cgroup(memcg); | ||
4097 | if (!memcg) | ||
4098 | memcg = root_mem_cgroup; | ||
4099 | } | ||
4100 | return memcg; | ||
4101 | } | ||
4102 | |||
4103 | static void mem_cgroup_id_put_many(struct mem_cgroup *memcg, unsigned int n) | 4098 | static void mem_cgroup_id_put_many(struct mem_cgroup *memcg, unsigned int n) |
4104 | { | 4099 | { |
4105 | if (atomic_sub_and_test(n, &memcg->id.ref)) { | 4100 | if (atomic_sub_and_test(n, &memcg->id.ref)) { |
@@ -5821,6 +5816,24 @@ static int __init mem_cgroup_init(void) | |||
5821 | subsys_initcall(mem_cgroup_init); | 5816 | subsys_initcall(mem_cgroup_init); |
5822 | 5817 | ||
5823 | #ifdef CONFIG_MEMCG_SWAP | 5818 | #ifdef CONFIG_MEMCG_SWAP |
5819 | static struct mem_cgroup *mem_cgroup_id_get_online(struct mem_cgroup *memcg) | ||
5820 | { | ||
5821 | while (!atomic_inc_not_zero(&memcg->id.ref)) { | ||
5822 | /* | ||
5823 | * The root cgroup cannot be destroyed, so it's refcount must | ||
5824 | * always be >= 1. | ||
5825 | */ | ||
5826 | if (WARN_ON_ONCE(memcg == root_mem_cgroup)) { | ||
5827 | VM_BUG_ON(1); | ||
5828 | break; | ||
5829 | } | ||
5830 | memcg = parent_mem_cgroup(memcg); | ||
5831 | if (!memcg) | ||
5832 | memcg = root_mem_cgroup; | ||
5833 | } | ||
5834 | return memcg; | ||
5835 | } | ||
5836 | |||
5824 | /** | 5837 | /** |
5825 | * mem_cgroup_swapout - transfer a memsw charge to swap | 5838 | * mem_cgroup_swapout - transfer a memsw charge to swap |
5826 | * @page: page whose memsw charge to transfer | 5839 | * @page: page whose memsw charge to transfer |
diff --git a/mm/memory.c b/mm/memory.c index 83be99d9d8a1..793fe0f9841c 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -3351,9 +3351,6 @@ static int do_numa_page(struct fault_env *fe, pte_t pte) | |||
3351 | bool was_writable = pte_write(pte); | 3351 | bool was_writable = pte_write(pte); |
3352 | int flags = 0; | 3352 | int flags = 0; |
3353 | 3353 | ||
3354 | /* A PROT_NONE fault should not end up here */ | ||
3355 | BUG_ON(!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))); | ||
3356 | |||
3357 | /* | 3354 | /* |
3358 | * The "pte" at this point cannot be used safely without | 3355 | * The "pte" at this point cannot be used safely without |
3359 | * validation through pte_unmap_same(). It's of NUMA type but | 3356 | * validation through pte_unmap_same(). It's of NUMA type but |
@@ -3458,6 +3455,11 @@ static int wp_huge_pmd(struct fault_env *fe, pmd_t orig_pmd) | |||
3458 | return VM_FAULT_FALLBACK; | 3455 | return VM_FAULT_FALLBACK; |
3459 | } | 3456 | } |
3460 | 3457 | ||
3458 | static inline bool vma_is_accessible(struct vm_area_struct *vma) | ||
3459 | { | ||
3460 | return vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE); | ||
3461 | } | ||
3462 | |||
3461 | /* | 3463 | /* |
3462 | * These routines also need to handle stuff like marking pages dirty | 3464 | * These routines also need to handle stuff like marking pages dirty |
3463 | * and/or accessed for architectures that don't do it in hardware (most | 3465 | * and/or accessed for architectures that don't do it in hardware (most |
@@ -3524,7 +3526,7 @@ static int handle_pte_fault(struct fault_env *fe) | |||
3524 | if (!pte_present(entry)) | 3526 | if (!pte_present(entry)) |
3525 | return do_swap_page(fe, entry); | 3527 | return do_swap_page(fe, entry); |
3526 | 3528 | ||
3527 | if (pte_protnone(entry)) | 3529 | if (pte_protnone(entry) && vma_is_accessible(fe->vma)) |
3528 | return do_numa_page(fe, entry); | 3530 | return do_numa_page(fe, entry); |
3529 | 3531 | ||
3530 | fe->ptl = pte_lockptr(fe->vma->vm_mm, fe->pmd); | 3532 | fe->ptl = pte_lockptr(fe->vma->vm_mm, fe->pmd); |
@@ -3590,7 +3592,7 @@ static int __handle_mm_fault(struct vm_area_struct *vma, unsigned long address, | |||
3590 | 3592 | ||
3591 | barrier(); | 3593 | barrier(); |
3592 | if (pmd_trans_huge(orig_pmd) || pmd_devmap(orig_pmd)) { | 3594 | if (pmd_trans_huge(orig_pmd) || pmd_devmap(orig_pmd)) { |
3593 | if (pmd_protnone(orig_pmd)) | 3595 | if (pmd_protnone(orig_pmd) && vma_is_accessible(vma)) |
3594 | return do_huge_pmd_numa_page(&fe, orig_pmd); | 3596 | return do_huge_pmd_numa_page(&fe, orig_pmd); |
3595 | 3597 | ||
3596 | if ((fe.flags & FAULT_FLAG_WRITE) && | 3598 | if ((fe.flags & FAULT_FLAG_WRITE) && |
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 41266dc29f33..b58906b6215c 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -1567,7 +1567,9 @@ static struct page *new_node_page(struct page *page, unsigned long private, | |||
1567 | return alloc_huge_page_node(page_hstate(compound_head(page)), | 1567 | return alloc_huge_page_node(page_hstate(compound_head(page)), |
1568 | next_node_in(nid, nmask)); | 1568 | next_node_in(nid, nmask)); |
1569 | 1569 | ||
1570 | node_clear(nid, nmask); | 1570 | if (nid != next_node_in(nid, nmask)) |
1571 | node_clear(nid, nmask); | ||
1572 | |||
1571 | if (PageHighMem(page) | 1573 | if (PageHighMem(page) |
1572 | || (zone_idx(page_zone(page)) == ZONE_MOVABLE)) | 1574 | || (zone_idx(page_zone(page)) == ZONE_MOVABLE)) |
1573 | gfp_mask |= __GFP_HIGHMEM; | 1575 | gfp_mask |= __GFP_HIGHMEM; |
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index d8c4e38fb5f4..2da72a5b6ecc 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -2336,6 +2336,23 @@ out: | |||
2336 | return ret; | 2336 | return ret; |
2337 | } | 2337 | } |
2338 | 2338 | ||
2339 | /* | ||
2340 | * Drop the (possibly final) reference to task->mempolicy. It needs to be | ||
2341 | * dropped after task->mempolicy is set to NULL so that any allocation done as | ||
2342 | * part of its kmem_cache_free(), such as by KASAN, doesn't reference a freed | ||
2343 | * policy. | ||
2344 | */ | ||
2345 | void mpol_put_task_policy(struct task_struct *task) | ||
2346 | { | ||
2347 | struct mempolicy *pol; | ||
2348 | |||
2349 | task_lock(task); | ||
2350 | pol = task->mempolicy; | ||
2351 | task->mempolicy = NULL; | ||
2352 | task_unlock(task); | ||
2353 | mpol_put(pol); | ||
2354 | } | ||
2355 | |||
2339 | static void sp_delete(struct shared_policy *sp, struct sp_node *n) | 2356 | static void sp_delete(struct shared_policy *sp, struct sp_node *n) |
2340 | { | 2357 | { |
2341 | pr_debug("deleting %lx-l%lx\n", n->start, n->end); | 2358 | pr_debug("deleting %lx-l%lx\n", n->start, n->end); |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 3fbe73a6fe4b..a2214c64ed3c 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -3137,54 +3137,6 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, | |||
3137 | return NULL; | 3137 | return NULL; |
3138 | } | 3138 | } |
3139 | 3139 | ||
3140 | static inline bool | ||
3141 | should_compact_retry(struct alloc_context *ac, int order, int alloc_flags, | ||
3142 | enum compact_result compact_result, | ||
3143 | enum compact_priority *compact_priority, | ||
3144 | int compaction_retries) | ||
3145 | { | ||
3146 | int max_retries = MAX_COMPACT_RETRIES; | ||
3147 | |||
3148 | if (!order) | ||
3149 | return false; | ||
3150 | |||
3151 | /* | ||
3152 | * compaction considers all the zone as desperately out of memory | ||
3153 | * so it doesn't really make much sense to retry except when the | ||
3154 | * failure could be caused by insufficient priority | ||
3155 | */ | ||
3156 | if (compaction_failed(compact_result)) { | ||
3157 | if (*compact_priority > MIN_COMPACT_PRIORITY) { | ||
3158 | (*compact_priority)--; | ||
3159 | return true; | ||
3160 | } | ||
3161 | return false; | ||
3162 | } | ||
3163 | |||
3164 | /* | ||
3165 | * make sure the compaction wasn't deferred or didn't bail out early | ||
3166 | * due to locks contention before we declare that we should give up. | ||
3167 | * But do not retry if the given zonelist is not suitable for | ||
3168 | * compaction. | ||
3169 | */ | ||
3170 | if (compaction_withdrawn(compact_result)) | ||
3171 | return compaction_zonelist_suitable(ac, order, alloc_flags); | ||
3172 | |||
3173 | /* | ||
3174 | * !costly requests are much more important than __GFP_REPEAT | ||
3175 | * costly ones because they are de facto nofail and invoke OOM | ||
3176 | * killer to move on while costly can fail and users are ready | ||
3177 | * to cope with that. 1/4 retries is rather arbitrary but we | ||
3178 | * would need much more detailed feedback from compaction to | ||
3179 | * make a better decision. | ||
3180 | */ | ||
3181 | if (order > PAGE_ALLOC_COSTLY_ORDER) | ||
3182 | max_retries /= 4; | ||
3183 | if (compaction_retries <= max_retries) | ||
3184 | return true; | ||
3185 | |||
3186 | return false; | ||
3187 | } | ||
3188 | #else | 3140 | #else |
3189 | static inline struct page * | 3141 | static inline struct page * |
3190 | __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, | 3142 | __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, |
@@ -3195,6 +3147,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, | |||
3195 | return NULL; | 3147 | return NULL; |
3196 | } | 3148 | } |
3197 | 3149 | ||
3150 | #endif /* CONFIG_COMPACTION */ | ||
3151 | |||
3198 | static inline bool | 3152 | static inline bool |
3199 | should_compact_retry(struct alloc_context *ac, unsigned int order, int alloc_flags, | 3153 | should_compact_retry(struct alloc_context *ac, unsigned int order, int alloc_flags, |
3200 | enum compact_result compact_result, | 3154 | enum compact_result compact_result, |
@@ -3221,7 +3175,6 @@ should_compact_retry(struct alloc_context *ac, unsigned int order, int alloc_fla | |||
3221 | } | 3175 | } |
3222 | return false; | 3176 | return false; |
3223 | } | 3177 | } |
3224 | #endif /* CONFIG_COMPACTION */ | ||
3225 | 3178 | ||
3226 | /* Perform direct synchronous page reclaim */ | 3179 | /* Perform direct synchronous page reclaim */ |
3227 | static int | 3180 | static int |
@@ -4407,7 +4360,7 @@ static int build_zonelists_node(pg_data_t *pgdat, struct zonelist *zonelist, | |||
4407 | do { | 4360 | do { |
4408 | zone_type--; | 4361 | zone_type--; |
4409 | zone = pgdat->node_zones + zone_type; | 4362 | zone = pgdat->node_zones + zone_type; |
4410 | if (populated_zone(zone)) { | 4363 | if (managed_zone(zone)) { |
4411 | zoneref_set_zone(zone, | 4364 | zoneref_set_zone(zone, |
4412 | &zonelist->_zonerefs[nr_zones++]); | 4365 | &zonelist->_zonerefs[nr_zones++]); |
4413 | check_highest_zone(zone_type); | 4366 | check_highest_zone(zone_type); |
@@ -4645,7 +4598,7 @@ static void build_zonelists_in_zone_order(pg_data_t *pgdat, int nr_nodes) | |||
4645 | for (j = 0; j < nr_nodes; j++) { | 4598 | for (j = 0; j < nr_nodes; j++) { |
4646 | node = node_order[j]; | 4599 | node = node_order[j]; |
4647 | z = &NODE_DATA(node)->node_zones[zone_type]; | 4600 | z = &NODE_DATA(node)->node_zones[zone_type]; |
4648 | if (populated_zone(z)) { | 4601 | if (managed_zone(z)) { |
4649 | zoneref_set_zone(z, | 4602 | zoneref_set_zone(z, |
4650 | &zonelist->_zonerefs[pos++]); | 4603 | &zonelist->_zonerefs[pos++]); |
4651 | check_highest_zone(zone_type); | 4604 | check_highest_zone(zone_type); |
diff --git a/mm/page_io.c b/mm/page_io.c index 16bd82fad38c..eafe5ddc2b54 100644 --- a/mm/page_io.c +++ b/mm/page_io.c | |||
@@ -264,6 +264,7 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc, | |||
264 | int ret; | 264 | int ret; |
265 | struct swap_info_struct *sis = page_swap_info(page); | 265 | struct swap_info_struct *sis = page_swap_info(page); |
266 | 266 | ||
267 | BUG_ON(!PageSwapCache(page)); | ||
267 | if (sis->flags & SWP_FILE) { | 268 | if (sis->flags & SWP_FILE) { |
268 | struct kiocb kiocb; | 269 | struct kiocb kiocb; |
269 | struct file *swap_file = sis->swap_file; | 270 | struct file *swap_file = sis->swap_file; |
@@ -337,6 +338,7 @@ int swap_readpage(struct page *page) | |||
337 | int ret = 0; | 338 | int ret = 0; |
338 | struct swap_info_struct *sis = page_swap_info(page); | 339 | struct swap_info_struct *sis = page_swap_info(page); |
339 | 340 | ||
341 | BUG_ON(!PageSwapCache(page)); | ||
340 | VM_BUG_ON_PAGE(!PageLocked(page), page); | 342 | VM_BUG_ON_PAGE(!PageLocked(page), page); |
341 | VM_BUG_ON_PAGE(PageUptodate(page), page); | 343 | VM_BUG_ON_PAGE(PageUptodate(page), page); |
342 | if (frontswap_load(page) == 0) { | 344 | if (frontswap_load(page) == 0) { |
@@ -386,6 +388,7 @@ int swap_set_page_dirty(struct page *page) | |||
386 | 388 | ||
387 | if (sis->flags & SWP_FILE) { | 389 | if (sis->flags & SWP_FILE) { |
388 | struct address_space *mapping = sis->swap_file->f_mapping; | 390 | struct address_space *mapping = sis->swap_file->f_mapping; |
391 | BUG_ON(!PageSwapCache(page)); | ||
389 | return mapping->a_ops->set_page_dirty(page); | 392 | return mapping->a_ops->set_page_dirty(page); |
390 | } else { | 393 | } else { |
391 | return __set_page_dirty_no_writeback(page); | 394 | return __set_page_dirty_no_writeback(page); |
diff --git a/mm/readahead.c b/mm/readahead.c index 65ec288dc057..c8a955b1297e 100644 --- a/mm/readahead.c +++ b/mm/readahead.c | |||
@@ -8,6 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/dax.h> | ||
11 | #include <linux/gfp.h> | 12 | #include <linux/gfp.h> |
12 | #include <linux/export.h> | 13 | #include <linux/export.h> |
13 | #include <linux/blkdev.h> | 14 | #include <linux/blkdev.h> |
@@ -544,6 +545,14 @@ do_readahead(struct address_space *mapping, struct file *filp, | |||
544 | if (!mapping || !mapping->a_ops) | 545 | if (!mapping || !mapping->a_ops) |
545 | return -EINVAL; | 546 | return -EINVAL; |
546 | 547 | ||
548 | /* | ||
549 | * Readahead doesn't make sense for DAX inodes, but we don't want it | ||
550 | * to report a failure either. Instead, we just return success and | ||
551 | * don't do any work. | ||
552 | */ | ||
553 | if (dax_mapping(mapping)) | ||
554 | return 0; | ||
555 | |||
547 | return force_page_cache_readahead(mapping, filp, index, nr); | 556 | return force_page_cache_readahead(mapping, filp, index, nr); |
548 | } | 557 | } |
549 | 558 | ||
diff --git a/mm/shmem.c b/mm/shmem.c index fd8b2b5741b1..971fc83e6402 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -270,7 +270,7 @@ bool shmem_charge(struct inode *inode, long pages) | |||
270 | info->alloced -= pages; | 270 | info->alloced -= pages; |
271 | shmem_recalc_inode(inode); | 271 | shmem_recalc_inode(inode); |
272 | spin_unlock_irqrestore(&info->lock, flags); | 272 | spin_unlock_irqrestore(&info->lock, flags); |
273 | 273 | shmem_unacct_blocks(info->flags, pages); | |
274 | return false; | 274 | return false; |
275 | } | 275 | } |
276 | percpu_counter_add(&sbinfo->used_blocks, pages); | 276 | percpu_counter_add(&sbinfo->used_blocks, pages); |
@@ -291,6 +291,7 @@ void shmem_uncharge(struct inode *inode, long pages) | |||
291 | 291 | ||
292 | if (sbinfo->max_blocks) | 292 | if (sbinfo->max_blocks) |
293 | percpu_counter_sub(&sbinfo->used_blocks, pages); | 293 | percpu_counter_sub(&sbinfo->used_blocks, pages); |
294 | shmem_unacct_blocks(info->flags, pages); | ||
294 | } | 295 | } |
295 | 296 | ||
296 | /* | 297 | /* |
@@ -1980,7 +1981,7 @@ unsigned long shmem_get_unmapped_area(struct file *file, | |||
1980 | return addr; | 1981 | return addr; |
1981 | sb = shm_mnt->mnt_sb; | 1982 | sb = shm_mnt->mnt_sb; |
1982 | } | 1983 | } |
1983 | if (SHMEM_SB(sb)->huge != SHMEM_HUGE_NEVER) | 1984 | if (SHMEM_SB(sb)->huge == SHMEM_HUGE_NEVER) |
1984 | return addr; | 1985 | return addr; |
1985 | } | 1986 | } |
1986 | 1987 | ||
diff --git a/mm/swapfile.c b/mm/swapfile.c index 78cfa292a29a..2657accc6e2b 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -2724,7 +2724,6 @@ int swapcache_prepare(swp_entry_t entry) | |||
2724 | struct swap_info_struct *page_swap_info(struct page *page) | 2724 | struct swap_info_struct *page_swap_info(struct page *page) |
2725 | { | 2725 | { |
2726 | swp_entry_t swap = { .val = page_private(page) }; | 2726 | swp_entry_t swap = { .val = page_private(page) }; |
2727 | BUG_ON(!PageSwapCache(page)); | ||
2728 | return swap_info[swp_type(swap)]; | 2727 | return swap_info[swp_type(swap)]; |
2729 | } | 2728 | } |
2730 | 2729 | ||
diff --git a/mm/usercopy.c b/mm/usercopy.c index 8ebae91a6b55..3c8da0af9695 100644 --- a/mm/usercopy.c +++ b/mm/usercopy.c | |||
@@ -83,7 +83,7 @@ static bool overlaps(const void *ptr, unsigned long n, unsigned long low, | |||
83 | unsigned long check_high = check_low + n; | 83 | unsigned long check_high = check_low + n; |
84 | 84 | ||
85 | /* Does not overlap if entirely above or entirely below. */ | 85 | /* Does not overlap if entirely above or entirely below. */ |
86 | if (check_low >= high || check_high < low) | 86 | if (check_low >= high || check_high <= low) |
87 | return false; | 87 | return false; |
88 | 88 | ||
89 | return true; | 89 | return true; |
@@ -124,7 +124,7 @@ static inline const char *check_kernel_text_object(const void *ptr, | |||
124 | static inline const char *check_bogus_address(const void *ptr, unsigned long n) | 124 | static inline const char *check_bogus_address(const void *ptr, unsigned long n) |
125 | { | 125 | { |
126 | /* Reject if object wraps past end of memory. */ | 126 | /* Reject if object wraps past end of memory. */ |
127 | if (ptr + n < ptr) | 127 | if ((unsigned long)ptr + n < (unsigned long)ptr) |
128 | return "<wrapped address>"; | 128 | return "<wrapped address>"; |
129 | 129 | ||
130 | /* Reject if NULL or ZERO-allocation. */ | 130 | /* Reject if NULL or ZERO-allocation. */ |
@@ -134,31 +134,16 @@ static inline const char *check_bogus_address(const void *ptr, unsigned long n) | |||
134 | return NULL; | 134 | return NULL; |
135 | } | 135 | } |
136 | 136 | ||
137 | static inline const char *check_heap_object(const void *ptr, unsigned long n, | 137 | /* Checks for allocs that are marked in some way as spanning multiple pages. */ |
138 | bool to_user) | 138 | static inline const char *check_page_span(const void *ptr, unsigned long n, |
139 | struct page *page, bool to_user) | ||
139 | { | 140 | { |
140 | struct page *page, *endpage; | 141 | #ifdef CONFIG_HARDENED_USERCOPY_PAGESPAN |
141 | const void *end = ptr + n - 1; | 142 | const void *end = ptr + n - 1; |
143 | struct page *endpage; | ||
142 | bool is_reserved, is_cma; | 144 | bool is_reserved, is_cma; |
143 | 145 | ||
144 | /* | 146 | /* |
145 | * Some architectures (arm64) return true for virt_addr_valid() on | ||
146 | * vmalloced addresses. Work around this by checking for vmalloc | ||
147 | * first. | ||
148 | */ | ||
149 | if (is_vmalloc_addr(ptr)) | ||
150 | return NULL; | ||
151 | |||
152 | if (!virt_addr_valid(ptr)) | ||
153 | return NULL; | ||
154 | |||
155 | page = virt_to_head_page(ptr); | ||
156 | |||
157 | /* Check slab allocator for flags and size. */ | ||
158 | if (PageSlab(page)) | ||
159 | return __check_heap_object(ptr, n, page); | ||
160 | |||
161 | /* | ||
162 | * Sometimes the kernel data regions are not marked Reserved (see | 147 | * Sometimes the kernel data regions are not marked Reserved (see |
163 | * check below). And sometimes [_sdata,_edata) does not cover | 148 | * check below). And sometimes [_sdata,_edata) does not cover |
164 | * rodata and/or bss, so check each range explicitly. | 149 | * rodata and/or bss, so check each range explicitly. |
@@ -186,7 +171,7 @@ static inline const char *check_heap_object(const void *ptr, unsigned long n, | |||
186 | ((unsigned long)end & (unsigned long)PAGE_MASK))) | 171 | ((unsigned long)end & (unsigned long)PAGE_MASK))) |
187 | return NULL; | 172 | return NULL; |
188 | 173 | ||
189 | /* Allow if start and end are inside the same compound page. */ | 174 | /* Allow if fully inside the same compound (__GFP_COMP) page. */ |
190 | endpage = virt_to_head_page(end); | 175 | endpage = virt_to_head_page(end); |
191 | if (likely(endpage == page)) | 176 | if (likely(endpage == page)) |
192 | return NULL; | 177 | return NULL; |
@@ -199,20 +184,47 @@ static inline const char *check_heap_object(const void *ptr, unsigned long n, | |||
199 | is_reserved = PageReserved(page); | 184 | is_reserved = PageReserved(page); |
200 | is_cma = is_migrate_cma_page(page); | 185 | is_cma = is_migrate_cma_page(page); |
201 | if (!is_reserved && !is_cma) | 186 | if (!is_reserved && !is_cma) |
202 | goto reject; | 187 | return "<spans multiple pages>"; |
203 | 188 | ||
204 | for (ptr += PAGE_SIZE; ptr <= end; ptr += PAGE_SIZE) { | 189 | for (ptr += PAGE_SIZE; ptr <= end; ptr += PAGE_SIZE) { |
205 | page = virt_to_head_page(ptr); | 190 | page = virt_to_head_page(ptr); |
206 | if (is_reserved && !PageReserved(page)) | 191 | if (is_reserved && !PageReserved(page)) |
207 | goto reject; | 192 | return "<spans Reserved and non-Reserved pages>"; |
208 | if (is_cma && !is_migrate_cma_page(page)) | 193 | if (is_cma && !is_migrate_cma_page(page)) |
209 | goto reject; | 194 | return "<spans CMA and non-CMA pages>"; |
210 | } | 195 | } |
196 | #endif | ||
211 | 197 | ||
212 | return NULL; | 198 | return NULL; |
199 | } | ||
200 | |||
201 | static inline const char *check_heap_object(const void *ptr, unsigned long n, | ||
202 | bool to_user) | ||
203 | { | ||
204 | struct page *page; | ||
205 | |||
206 | /* | ||
207 | * Some architectures (arm64) return true for virt_addr_valid() on | ||
208 | * vmalloced addresses. Work around this by checking for vmalloc | ||
209 | * first. | ||
210 | * | ||
211 | * We also need to check for module addresses explicitly since we | ||
212 | * may copy static data from modules to userspace | ||
213 | */ | ||
214 | if (is_vmalloc_or_module_addr(ptr)) | ||
215 | return NULL; | ||
216 | |||
217 | if (!virt_addr_valid(ptr)) | ||
218 | return NULL; | ||
219 | |||
220 | page = virt_to_head_page(ptr); | ||
221 | |||
222 | /* Check slab allocator for flags and size. */ | ||
223 | if (PageSlab(page)) | ||
224 | return __check_heap_object(ptr, n, page); | ||
213 | 225 | ||
214 | reject: | 226 | /* Verify object does not incorrectly span multiple pages. */ |
215 | return "<spans multiple pages>"; | 227 | return check_page_span(ptr, n, page, to_user); |
216 | } | 228 | } |
217 | 229 | ||
218 | /* | 230 | /* |
diff --git a/mm/vmscan.c b/mm/vmscan.c index 374d95d04178..0fe8b7113868 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1665,7 +1665,7 @@ static bool inactive_reclaimable_pages(struct lruvec *lruvec, | |||
1665 | 1665 | ||
1666 | for (zid = sc->reclaim_idx; zid >= 0; zid--) { | 1666 | for (zid = sc->reclaim_idx; zid >= 0; zid--) { |
1667 | zone = &pgdat->node_zones[zid]; | 1667 | zone = &pgdat->node_zones[zid]; |
1668 | if (!populated_zone(zone)) | 1668 | if (!managed_zone(zone)) |
1669 | continue; | 1669 | continue; |
1670 | 1670 | ||
1671 | if (zone_page_state_snapshot(zone, NR_ZONE_LRU_BASE + | 1671 | if (zone_page_state_snapshot(zone, NR_ZONE_LRU_BASE + |
@@ -2036,7 +2036,7 @@ static bool inactive_list_is_low(struct lruvec *lruvec, bool file, | |||
2036 | struct zone *zone = &pgdat->node_zones[zid]; | 2036 | struct zone *zone = &pgdat->node_zones[zid]; |
2037 | unsigned long inactive_zone, active_zone; | 2037 | unsigned long inactive_zone, active_zone; |
2038 | 2038 | ||
2039 | if (!populated_zone(zone)) | 2039 | if (!managed_zone(zone)) |
2040 | continue; | 2040 | continue; |
2041 | 2041 | ||
2042 | inactive_zone = zone_page_state(zone, | 2042 | inactive_zone = zone_page_state(zone, |
@@ -2171,7 +2171,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, | |||
2171 | 2171 | ||
2172 | for (z = 0; z < MAX_NR_ZONES; z++) { | 2172 | for (z = 0; z < MAX_NR_ZONES; z++) { |
2173 | struct zone *zone = &pgdat->node_zones[z]; | 2173 | struct zone *zone = &pgdat->node_zones[z]; |
2174 | if (!populated_zone(zone)) | 2174 | if (!managed_zone(zone)) |
2175 | continue; | 2175 | continue; |
2176 | 2176 | ||
2177 | total_high_wmark += high_wmark_pages(zone); | 2177 | total_high_wmark += high_wmark_pages(zone); |
@@ -2303,23 +2303,6 @@ out: | |||
2303 | } | 2303 | } |
2304 | } | 2304 | } |
2305 | 2305 | ||
2306 | #ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH | ||
2307 | static void init_tlb_ubc(void) | ||
2308 | { | ||
2309 | /* | ||
2310 | * This deliberately does not clear the cpumask as it's expensive | ||
2311 | * and unnecessary. If there happens to be data in there then the | ||
2312 | * first SWAP_CLUSTER_MAX pages will send an unnecessary IPI and | ||
2313 | * then will be cleared. | ||
2314 | */ | ||
2315 | current->tlb_ubc.flush_required = false; | ||
2316 | } | ||
2317 | #else | ||
2318 | static inline void init_tlb_ubc(void) | ||
2319 | { | ||
2320 | } | ||
2321 | #endif /* CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH */ | ||
2322 | |||
2323 | /* | 2306 | /* |
2324 | * This is a basic per-node page freer. Used by both kswapd and direct reclaim. | 2307 | * This is a basic per-node page freer. Used by both kswapd and direct reclaim. |
2325 | */ | 2308 | */ |
@@ -2355,8 +2338,6 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc | |||
2355 | scan_adjusted = (global_reclaim(sc) && !current_is_kswapd() && | 2338 | scan_adjusted = (global_reclaim(sc) && !current_is_kswapd() && |
2356 | sc->priority == DEF_PRIORITY); | 2339 | sc->priority == DEF_PRIORITY); |
2357 | 2340 | ||
2358 | init_tlb_ubc(); | ||
2359 | |||
2360 | blk_start_plug(&plug); | 2341 | blk_start_plug(&plug); |
2361 | while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] || | 2342 | while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] || |
2362 | nr[LRU_INACTIVE_FILE]) { | 2343 | nr[LRU_INACTIVE_FILE]) { |
@@ -2510,7 +2491,7 @@ static inline bool should_continue_reclaim(struct pglist_data *pgdat, | |||
2510 | /* If compaction would go ahead or the allocation would succeed, stop */ | 2491 | /* If compaction would go ahead or the allocation would succeed, stop */ |
2511 | for (z = 0; z <= sc->reclaim_idx; z++) { | 2492 | for (z = 0; z <= sc->reclaim_idx; z++) { |
2512 | struct zone *zone = &pgdat->node_zones[z]; | 2493 | struct zone *zone = &pgdat->node_zones[z]; |
2513 | if (!populated_zone(zone)) | 2494 | if (!managed_zone(zone)) |
2514 | continue; | 2495 | continue; |
2515 | 2496 | ||
2516 | switch (compaction_suitable(zone, sc->order, 0, sc->reclaim_idx)) { | 2497 | switch (compaction_suitable(zone, sc->order, 0, sc->reclaim_idx)) { |
@@ -2840,7 +2821,7 @@ static bool pfmemalloc_watermark_ok(pg_data_t *pgdat) | |||
2840 | 2821 | ||
2841 | for (i = 0; i <= ZONE_NORMAL; i++) { | 2822 | for (i = 0; i <= ZONE_NORMAL; i++) { |
2842 | zone = &pgdat->node_zones[i]; | 2823 | zone = &pgdat->node_zones[i]; |
2843 | if (!populated_zone(zone) || | 2824 | if (!managed_zone(zone) || |
2844 | pgdat_reclaimable_pages(pgdat) == 0) | 2825 | pgdat_reclaimable_pages(pgdat) == 0) |
2845 | continue; | 2826 | continue; |
2846 | 2827 | ||
@@ -3141,7 +3122,7 @@ static bool prepare_kswapd_sleep(pg_data_t *pgdat, int order, int classzone_idx) | |||
3141 | for (i = 0; i <= classzone_idx; i++) { | 3122 | for (i = 0; i <= classzone_idx; i++) { |
3142 | struct zone *zone = pgdat->node_zones + i; | 3123 | struct zone *zone = pgdat->node_zones + i; |
3143 | 3124 | ||
3144 | if (!populated_zone(zone)) | 3125 | if (!managed_zone(zone)) |
3145 | continue; | 3126 | continue; |
3146 | 3127 | ||
3147 | if (!zone_balanced(zone, order, classzone_idx)) | 3128 | if (!zone_balanced(zone, order, classzone_idx)) |
@@ -3169,7 +3150,7 @@ static bool kswapd_shrink_node(pg_data_t *pgdat, | |||
3169 | sc->nr_to_reclaim = 0; | 3150 | sc->nr_to_reclaim = 0; |
3170 | for (z = 0; z <= sc->reclaim_idx; z++) { | 3151 | for (z = 0; z <= sc->reclaim_idx; z++) { |
3171 | zone = pgdat->node_zones + z; | 3152 | zone = pgdat->node_zones + z; |
3172 | if (!populated_zone(zone)) | 3153 | if (!managed_zone(zone)) |
3173 | continue; | 3154 | continue; |
3174 | 3155 | ||
3175 | sc->nr_to_reclaim += max(high_wmark_pages(zone), SWAP_CLUSTER_MAX); | 3156 | sc->nr_to_reclaim += max(high_wmark_pages(zone), SWAP_CLUSTER_MAX); |
@@ -3242,7 +3223,7 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int classzone_idx) | |||
3242 | if (buffer_heads_over_limit) { | 3223 | if (buffer_heads_over_limit) { |
3243 | for (i = MAX_NR_ZONES - 1; i >= 0; i--) { | 3224 | for (i = MAX_NR_ZONES - 1; i >= 0; i--) { |
3244 | zone = pgdat->node_zones + i; | 3225 | zone = pgdat->node_zones + i; |
3245 | if (!populated_zone(zone)) | 3226 | if (!managed_zone(zone)) |
3246 | continue; | 3227 | continue; |
3247 | 3228 | ||
3248 | sc.reclaim_idx = i; | 3229 | sc.reclaim_idx = i; |
@@ -3262,7 +3243,7 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int classzone_idx) | |||
3262 | */ | 3243 | */ |
3263 | for (i = classzone_idx; i >= 0; i--) { | 3244 | for (i = classzone_idx; i >= 0; i--) { |
3264 | zone = pgdat->node_zones + i; | 3245 | zone = pgdat->node_zones + i; |
3265 | if (!populated_zone(zone)) | 3246 | if (!managed_zone(zone)) |
3266 | continue; | 3247 | continue; |
3267 | 3248 | ||
3268 | if (zone_balanced(zone, sc.order, classzone_idx)) | 3249 | if (zone_balanced(zone, sc.order, classzone_idx)) |
@@ -3508,7 +3489,7 @@ void wakeup_kswapd(struct zone *zone, int order, enum zone_type classzone_idx) | |||
3508 | pg_data_t *pgdat; | 3489 | pg_data_t *pgdat; |
3509 | int z; | 3490 | int z; |
3510 | 3491 | ||
3511 | if (!populated_zone(zone)) | 3492 | if (!managed_zone(zone)) |
3512 | return; | 3493 | return; |
3513 | 3494 | ||
3514 | if (!cpuset_zone_allowed(zone, GFP_KERNEL | __GFP_HARDWALL)) | 3495 | if (!cpuset_zone_allowed(zone, GFP_KERNEL | __GFP_HARDWALL)) |
@@ -3522,7 +3503,7 @@ void wakeup_kswapd(struct zone *zone, int order, enum zone_type classzone_idx) | |||
3522 | /* Only wake kswapd if all zones are unbalanced */ | 3503 | /* Only wake kswapd if all zones are unbalanced */ |
3523 | for (z = 0; z <= classzone_idx; z++) { | 3504 | for (z = 0; z <= classzone_idx; z++) { |
3524 | zone = pgdat->node_zones + z; | 3505 | zone = pgdat->node_zones + z; |
3525 | if (!populated_zone(zone)) | 3506 | if (!managed_zone(zone)) |
3526 | continue; | 3507 | continue; |
3527 | 3508 | ||
3528 | if (zone_balanced(zone, order, classzone_idx)) | 3509 | if (zone_balanced(zone, order, classzone_idx)) |
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c index 7d170010beb9..ee08540ce503 100644 --- a/net/batman-adv/bat_v_elp.c +++ b/net/batman-adv/bat_v_elp.c | |||
@@ -335,7 +335,7 @@ int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface) | |||
335 | goto out; | 335 | goto out; |
336 | 336 | ||
337 | skb_reserve(hard_iface->bat_v.elp_skb, ETH_HLEN + NET_IP_ALIGN); | 337 | skb_reserve(hard_iface->bat_v.elp_skb, ETH_HLEN + NET_IP_ALIGN); |
338 | elp_buff = skb_push(hard_iface->bat_v.elp_skb, BATADV_ELP_HLEN); | 338 | elp_buff = skb_put(hard_iface->bat_v.elp_skb, BATADV_ELP_HLEN); |
339 | elp_packet = (struct batadv_elp_packet *)elp_buff; | 339 | elp_packet = (struct batadv_elp_packet *)elp_buff; |
340 | memset(elp_packet, 0, BATADV_ELP_HLEN); | 340 | memset(elp_packet, 0, BATADV_ELP_HLEN); |
341 | 341 | ||
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 7602c001e92b..3d199478c405 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -470,6 +470,29 @@ static int batadv_check_unicast_packet(struct batadv_priv *bat_priv, | |||
470 | } | 470 | } |
471 | 471 | ||
472 | /** | 472 | /** |
473 | * batadv_last_bonding_get - Get last_bonding_candidate of orig_node | ||
474 | * @orig_node: originator node whose last bonding candidate should be retrieved | ||
475 | * | ||
476 | * Return: last bonding candidate of router or NULL if not found | ||
477 | * | ||
478 | * The object is returned with refcounter increased by 1. | ||
479 | */ | ||
480 | static struct batadv_orig_ifinfo * | ||
481 | batadv_last_bonding_get(struct batadv_orig_node *orig_node) | ||
482 | { | ||
483 | struct batadv_orig_ifinfo *last_bonding_candidate; | ||
484 | |||
485 | spin_lock_bh(&orig_node->neigh_list_lock); | ||
486 | last_bonding_candidate = orig_node->last_bonding_candidate; | ||
487 | |||
488 | if (last_bonding_candidate) | ||
489 | kref_get(&last_bonding_candidate->refcount); | ||
490 | spin_unlock_bh(&orig_node->neigh_list_lock); | ||
491 | |||
492 | return last_bonding_candidate; | ||
493 | } | ||
494 | |||
495 | /** | ||
473 | * batadv_last_bonding_replace - Replace last_bonding_candidate of orig_node | 496 | * batadv_last_bonding_replace - Replace last_bonding_candidate of orig_node |
474 | * @orig_node: originator node whose bonding candidates should be replaced | 497 | * @orig_node: originator node whose bonding candidates should be replaced |
475 | * @new_candidate: new bonding candidate or NULL | 498 | * @new_candidate: new bonding candidate or NULL |
@@ -539,7 +562,7 @@ batadv_find_router(struct batadv_priv *bat_priv, | |||
539 | * router - obviously there are no other candidates. | 562 | * router - obviously there are no other candidates. |
540 | */ | 563 | */ |
541 | rcu_read_lock(); | 564 | rcu_read_lock(); |
542 | last_candidate = orig_node->last_bonding_candidate; | 565 | last_candidate = batadv_last_bonding_get(orig_node); |
543 | if (last_candidate) | 566 | if (last_candidate) |
544 | last_cand_router = rcu_dereference(last_candidate->router); | 567 | last_cand_router = rcu_dereference(last_candidate->router); |
545 | 568 | ||
@@ -631,6 +654,9 @@ next: | |||
631 | batadv_orig_ifinfo_put(next_candidate); | 654 | batadv_orig_ifinfo_put(next_candidate); |
632 | } | 655 | } |
633 | 656 | ||
657 | if (last_candidate) | ||
658 | batadv_orig_ifinfo_put(last_candidate); | ||
659 | |||
634 | return router; | 660 | return router; |
635 | } | 661 | } |
636 | 662 | ||
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index ece45e0683fd..0b5f729d08d2 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -250,7 +250,7 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | |||
250 | 250 | ||
251 | skb_free_datagram(sk, skb); | 251 | skb_free_datagram(sk, skb); |
252 | 252 | ||
253 | if (msg->msg_flags & MSG_TRUNC) | 253 | if (flags & MSG_TRUNC) |
254 | copied = skblen; | 254 | copied = skblen; |
255 | 255 | ||
256 | return err ? : copied; | 256 | return err ? : copied; |
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index c045b3c54768..b0e23dfc5c34 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c | |||
@@ -262,6 +262,8 @@ int __hci_req_sync(struct hci_dev *hdev, int (*func)(struct hci_request *req, | |||
262 | break; | 262 | break; |
263 | } | 263 | } |
264 | 264 | ||
265 | kfree_skb(hdev->req_skb); | ||
266 | hdev->req_skb = NULL; | ||
265 | hdev->req_status = hdev->req_result = 0; | 267 | hdev->req_status = hdev->req_result = 0; |
266 | 268 | ||
267 | BT_DBG("%s end: err %d", hdev->name, err); | 269 | BT_DBG("%s end: err %d", hdev->name, err); |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 6ef8a01a9ad4..96f04b7b9556 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -1091,7 +1091,7 @@ static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, | |||
1091 | 1091 | ||
1092 | skb_free_datagram(sk, skb); | 1092 | skb_free_datagram(sk, skb); |
1093 | 1093 | ||
1094 | if (msg->msg_flags & MSG_TRUNC) | 1094 | if (flags & MSG_TRUNC) |
1095 | copied = skblen; | 1095 | copied = skblen; |
1096 | 1096 | ||
1097 | return err ? : copied; | 1097 | return err ? : copied; |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 54ceb1f2cc9a..d4cad29b033f 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | #include <linux/debugfs.h> | 33 | #include <linux/debugfs.h> |
34 | #include <linux/crc16.h> | 34 | #include <linux/crc16.h> |
35 | #include <linux/filter.h> | ||
35 | 36 | ||
36 | #include <net/bluetooth/bluetooth.h> | 37 | #include <net/bluetooth/bluetooth.h> |
37 | #include <net/bluetooth/hci_core.h> | 38 | #include <net/bluetooth/hci_core.h> |
@@ -5835,6 +5836,9 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, | |||
5835 | if (chan->sdu) | 5836 | if (chan->sdu) |
5836 | break; | 5837 | break; |
5837 | 5838 | ||
5839 | if (!pskb_may_pull(skb, L2CAP_SDULEN_SIZE)) | ||
5840 | break; | ||
5841 | |||
5838 | chan->sdu_len = get_unaligned_le16(skb->data); | 5842 | chan->sdu_len = get_unaligned_le16(skb->data); |
5839 | skb_pull(skb, L2CAP_SDULEN_SIZE); | 5843 | skb_pull(skb, L2CAP_SDULEN_SIZE); |
5840 | 5844 | ||
@@ -6610,6 +6614,10 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) | |||
6610 | goto drop; | 6614 | goto drop; |
6611 | } | 6615 | } |
6612 | 6616 | ||
6617 | if ((chan->mode == L2CAP_MODE_ERTM || | ||
6618 | chan->mode == L2CAP_MODE_STREAMING) && sk_filter(chan->data, skb)) | ||
6619 | goto drop; | ||
6620 | |||
6613 | if (!control->sframe) { | 6621 | if (!control->sframe) { |
6614 | int err; | 6622 | int err; |
6615 | 6623 | ||
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 1842141baedb..a8ba752732c9 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -1019,7 +1019,7 @@ static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, | |||
1019 | goto done; | 1019 | goto done; |
1020 | 1020 | ||
1021 | if (pi->rx_busy_skb) { | 1021 | if (pi->rx_busy_skb) { |
1022 | if (!sock_queue_rcv_skb(sk, pi->rx_busy_skb)) | 1022 | if (!__sock_queue_rcv_skb(sk, pi->rx_busy_skb)) |
1023 | pi->rx_busy_skb = NULL; | 1023 | pi->rx_busy_skb = NULL; |
1024 | else | 1024 | else |
1025 | goto done; | 1025 | goto done; |
@@ -1270,7 +1270,17 @@ static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) | |||
1270 | goto done; | 1270 | goto done; |
1271 | } | 1271 | } |
1272 | 1272 | ||
1273 | err = sock_queue_rcv_skb(sk, skb); | 1273 | if (chan->mode != L2CAP_MODE_ERTM && |
1274 | chan->mode != L2CAP_MODE_STREAMING) { | ||
1275 | /* Even if no filter is attached, we could potentially | ||
1276 | * get errors from security modules, etc. | ||
1277 | */ | ||
1278 | err = sk_filter(sk, skb); | ||
1279 | if (err) | ||
1280 | goto done; | ||
1281 | } | ||
1282 | |||
1283 | err = __sock_queue_rcv_skb(sk, skb); | ||
1274 | 1284 | ||
1275 | /* For ERTM, handle one skb that doesn't fit into the recv | 1285 | /* For ERTM, handle one skb that doesn't fit into the recv |
1276 | * buffer. This is important to do because the data frames | 1286 | * buffer. This is important to do because the data frames |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 8e486203d133..abe11f085479 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -80,13 +80,10 @@ static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br, | |||
80 | 80 | ||
81 | BR_INPUT_SKB_CB(skb)->proxyarp_replied = false; | 81 | BR_INPUT_SKB_CB(skb)->proxyarp_replied = false; |
82 | 82 | ||
83 | if (dev->flags & IFF_NOARP) | 83 | if ((dev->flags & IFF_NOARP) || |
84 | !pskb_may_pull(skb, arp_hdr_len(dev))) | ||
84 | return; | 85 | return; |
85 | 86 | ||
86 | if (!pskb_may_pull(skb, arp_hdr_len(dev))) { | ||
87 | dev->stats.tx_dropped++; | ||
88 | return; | ||
89 | } | ||
90 | parp = arp_hdr(skb); | 87 | parp = arp_hdr(skb); |
91 | 88 | ||
92 | if (parp->ar_pro != htons(ETH_P_IP) || | 89 | if (parp->ar_pro != htons(ETH_P_IP) || |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index a5423a1eec05..c5fea9393946 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -1138,7 +1138,7 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br, | |||
1138 | } else { | 1138 | } else { |
1139 | err = br_ip6_multicast_add_group(br, port, | 1139 | err = br_ip6_multicast_add_group(br, port, |
1140 | &grec->grec_mca, vid); | 1140 | &grec->grec_mca, vid); |
1141 | if (!err) | 1141 | if (err) |
1142 | break; | 1142 | break; |
1143 | } | 1143 | } |
1144 | } | 1144 | } |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index cceac5bb658f..0833c251aef7 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -368,6 +368,8 @@ ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par, | |||
368 | 368 | ||
369 | match = xt_find_match(NFPROTO_BRIDGE, m->u.name, 0); | 369 | match = xt_find_match(NFPROTO_BRIDGE, m->u.name, 0); |
370 | if (IS_ERR(match) || match->family != NFPROTO_BRIDGE) { | 370 | if (IS_ERR(match) || match->family != NFPROTO_BRIDGE) { |
371 | if (!IS_ERR(match)) | ||
372 | module_put(match->me); | ||
371 | request_module("ebt_%s", m->u.name); | 373 | request_module("ebt_%s", m->u.name); |
372 | match = xt_find_match(NFPROTO_BRIDGE, m->u.name, 0); | 374 | match = xt_find_match(NFPROTO_BRIDGE, m->u.name, 0); |
373 | } | 375 | } |
diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c index 4b901d9f2e7c..ad47a921b701 100644 --- a/net/bridge/netfilter/nft_meta_bridge.c +++ b/net/bridge/netfilter/nft_meta_bridge.c | |||
@@ -86,6 +86,7 @@ static const struct nft_expr_ops nft_meta_bridge_set_ops = { | |||
86 | .init = nft_meta_set_init, | 86 | .init = nft_meta_set_init, |
87 | .destroy = nft_meta_set_destroy, | 87 | .destroy = nft_meta_set_destroy, |
88 | .dump = nft_meta_set_dump, | 88 | .dump = nft_meta_set_dump, |
89 | .validate = nft_meta_set_validate, | ||
89 | }; | 90 | }; |
90 | 91 | ||
91 | static const struct nft_expr_ops * | 92 | static const struct nft_expr_ops * |
diff --git a/net/core/dev.c b/net/core/dev.c index dd6ce598de89..ea6312057a71 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3975,6 +3975,22 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret, | |||
3975 | } | 3975 | } |
3976 | 3976 | ||
3977 | /** | 3977 | /** |
3978 | * netdev_is_rx_handler_busy - check if receive handler is registered | ||
3979 | * @dev: device to check | ||
3980 | * | ||
3981 | * Check if a receive handler is already registered for a given device. | ||
3982 | * Return true if there one. | ||
3983 | * | ||
3984 | * The caller must hold the rtnl_mutex. | ||
3985 | */ | ||
3986 | bool netdev_is_rx_handler_busy(struct net_device *dev) | ||
3987 | { | ||
3988 | ASSERT_RTNL(); | ||
3989 | return dev && rtnl_dereference(dev->rx_handler); | ||
3990 | } | ||
3991 | EXPORT_SYMBOL_GPL(netdev_is_rx_handler_busy); | ||
3992 | |||
3993 | /** | ||
3978 | * netdev_rx_handler_register - register receive handler | 3994 | * netdev_rx_handler_register - register receive handler |
3979 | * @dev: device to register a handler for | 3995 | * @dev: device to register a handler for |
3980 | * @rx_handler: receive handler to register | 3996 | * @rx_handler: receive handler to register |
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 61ad43f61c5e..52742a02814f 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c | |||
@@ -680,11 +680,13 @@ EXPORT_SYMBOL_GPL(__skb_get_hash_symmetric); | |||
680 | void __skb_get_hash(struct sk_buff *skb) | 680 | void __skb_get_hash(struct sk_buff *skb) |
681 | { | 681 | { |
682 | struct flow_keys keys; | 682 | struct flow_keys keys; |
683 | u32 hash; | ||
683 | 684 | ||
684 | __flow_hash_secret_init(); | 685 | __flow_hash_secret_init(); |
685 | 686 | ||
686 | __skb_set_sw_hash(skb, ___skb_get_hash(skb, &keys, hashrnd), | 687 | hash = ___skb_get_hash(skb, &keys, hashrnd); |
687 | flow_keys_have_l4(&keys)); | 688 | |
689 | __skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys)); | ||
688 | } | 690 | } |
689 | EXPORT_SYMBOL(__skb_get_hash); | 691 | EXPORT_SYMBOL(__skb_get_hash); |
690 | 692 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index 25dab8b60223..fd7b41edf1ce 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -1362,7 +1362,6 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, | |||
1362 | if (!try_module_get(prot->owner)) | 1362 | if (!try_module_get(prot->owner)) |
1363 | goto out_free_sec; | 1363 | goto out_free_sec; |
1364 | sk_tx_queue_clear(sk); | 1364 | sk_tx_queue_clear(sk); |
1365 | cgroup_sk_alloc(&sk->sk_cgrp_data); | ||
1366 | } | 1365 | } |
1367 | 1366 | ||
1368 | return sk; | 1367 | return sk; |
@@ -1422,6 +1421,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, | |||
1422 | sock_net_set(sk, net); | 1421 | sock_net_set(sk, net); |
1423 | atomic_set(&sk->sk_wmem_alloc, 1); | 1422 | atomic_set(&sk->sk_wmem_alloc, 1); |
1424 | 1423 | ||
1424 | cgroup_sk_alloc(&sk->sk_cgrp_data); | ||
1425 | sock_update_classid(&sk->sk_cgrp_data); | 1425 | sock_update_classid(&sk->sk_cgrp_data); |
1426 | sock_update_netprioidx(&sk->sk_cgrp_data); | 1426 | sock_update_netprioidx(&sk->sk_cgrp_data); |
1427 | } | 1427 | } |
@@ -1566,6 +1566,9 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) | |||
1566 | newsk->sk_priority = 0; | 1566 | newsk->sk_priority = 0; |
1567 | newsk->sk_incoming_cpu = raw_smp_processor_id(); | 1567 | newsk->sk_incoming_cpu = raw_smp_processor_id(); |
1568 | atomic64_set(&newsk->sk_cookie, 0); | 1568 | atomic64_set(&newsk->sk_cookie, 0); |
1569 | |||
1570 | cgroup_sk_alloc(&newsk->sk_cgrp_data); | ||
1571 | |||
1569 | /* | 1572 | /* |
1570 | * Before updating sk_refcnt, we must commit prior changes to memory | 1573 | * Before updating sk_refcnt, we must commit prior changes to memory |
1571 | * (Documentation/RCU/rculist_nulls.txt for details) | 1574 | * (Documentation/RCU/rculist_nulls.txt for details) |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 415e117967c7..062a67ca9a21 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -2232,7 +2232,7 @@ static struct devinet_sysctl_table { | |||
2232 | }; | 2232 | }; |
2233 | 2233 | ||
2234 | static int __devinet_sysctl_register(struct net *net, char *dev_name, | 2234 | static int __devinet_sysctl_register(struct net *net, char *dev_name, |
2235 | struct ipv4_devconf *p) | 2235 | int ifindex, struct ipv4_devconf *p) |
2236 | { | 2236 | { |
2237 | int i; | 2237 | int i; |
2238 | struct devinet_sysctl_table *t; | 2238 | struct devinet_sysctl_table *t; |
@@ -2255,6 +2255,8 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name, | |||
2255 | goto free; | 2255 | goto free; |
2256 | 2256 | ||
2257 | p->sysctl = t; | 2257 | p->sysctl = t; |
2258 | |||
2259 | inet_netconf_notify_devconf(net, NETCONFA_ALL, ifindex, p); | ||
2258 | return 0; | 2260 | return 0; |
2259 | 2261 | ||
2260 | free: | 2262 | free: |
@@ -2286,7 +2288,7 @@ static int devinet_sysctl_register(struct in_device *idev) | |||
2286 | if (err) | 2288 | if (err) |
2287 | return err; | 2289 | return err; |
2288 | err = __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name, | 2290 | err = __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name, |
2289 | &idev->cnf); | 2291 | idev->dev->ifindex, &idev->cnf); |
2290 | if (err) | 2292 | if (err) |
2291 | neigh_sysctl_unregister(idev->arp_parms); | 2293 | neigh_sysctl_unregister(idev->arp_parms); |
2292 | return err; | 2294 | return err; |
@@ -2347,11 +2349,12 @@ static __net_init int devinet_init_net(struct net *net) | |||
2347 | } | 2349 | } |
2348 | 2350 | ||
2349 | #ifdef CONFIG_SYSCTL | 2351 | #ifdef CONFIG_SYSCTL |
2350 | err = __devinet_sysctl_register(net, "all", all); | 2352 | err = __devinet_sysctl_register(net, "all", NETCONFA_IFINDEX_ALL, all); |
2351 | if (err < 0) | 2353 | if (err < 0) |
2352 | goto err_reg_all; | 2354 | goto err_reg_all; |
2353 | 2355 | ||
2354 | err = __devinet_sysctl_register(net, "default", dflt); | 2356 | err = __devinet_sysctl_register(net, "default", |
2357 | NETCONFA_IFINDEX_DEFAULT, dflt); | ||
2355 | if (err < 0) | 2358 | if (err < 0) |
2356 | goto err_reg_dflt; | 2359 | goto err_reg_dflt; |
2357 | 2360 | ||
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index ef2ebeb89d0f..1b25daf8c7f1 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -509,6 +509,7 @@ static int rtentry_to_fib_config(struct net *net, int cmd, struct rtentry *rt, | |||
509 | if (!dev) | 509 | if (!dev) |
510 | return -ENODEV; | 510 | return -ENODEV; |
511 | cfg->fc_oif = dev->ifindex; | 511 | cfg->fc_oif = dev->ifindex; |
512 | cfg->fc_table = l3mdev_fib_table(dev); | ||
512 | if (colon) { | 513 | if (colon) { |
513 | struct in_ifaddr *ifa; | 514 | struct in_ifaddr *ifa; |
514 | struct in_device *in_dev = __in_dev_get_rtnl(dev); | 515 | struct in_device *in_dev = __in_dev_get_rtnl(dev); |
@@ -1027,7 +1028,7 @@ no_promotions: | |||
1027 | * First of all, we scan fib_info list searching | 1028 | * First of all, we scan fib_info list searching |
1028 | * for stray nexthop entries, then ignite fib_flush. | 1029 | * for stray nexthop entries, then ignite fib_flush. |
1029 | */ | 1030 | */ |
1030 | if (fib_sync_down_addr(dev_net(dev), ifa->ifa_local)) | 1031 | if (fib_sync_down_addr(dev, ifa->ifa_local)) |
1031 | fib_flush(dev_net(dev)); | 1032 | fib_flush(dev_net(dev)); |
1032 | } | 1033 | } |
1033 | } | 1034 | } |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 539fa264e67d..e9f56225e53f 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -1057,6 +1057,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg) | |||
1057 | fi->fib_priority = cfg->fc_priority; | 1057 | fi->fib_priority = cfg->fc_priority; |
1058 | fi->fib_prefsrc = cfg->fc_prefsrc; | 1058 | fi->fib_prefsrc = cfg->fc_prefsrc; |
1059 | fi->fib_type = cfg->fc_type; | 1059 | fi->fib_type = cfg->fc_type; |
1060 | fi->fib_tb_id = cfg->fc_table; | ||
1060 | 1061 | ||
1061 | fi->fib_nhs = nhs; | 1062 | fi->fib_nhs = nhs; |
1062 | change_nexthops(fi) { | 1063 | change_nexthops(fi) { |
@@ -1337,18 +1338,21 @@ nla_put_failure: | |||
1337 | * referring to it. | 1338 | * referring to it. |
1338 | * - device went down -> we must shutdown all nexthops going via it. | 1339 | * - device went down -> we must shutdown all nexthops going via it. |
1339 | */ | 1340 | */ |
1340 | int fib_sync_down_addr(struct net *net, __be32 local) | 1341 | int fib_sync_down_addr(struct net_device *dev, __be32 local) |
1341 | { | 1342 | { |
1342 | int ret = 0; | 1343 | int ret = 0; |
1343 | unsigned int hash = fib_laddr_hashfn(local); | 1344 | unsigned int hash = fib_laddr_hashfn(local); |
1344 | struct hlist_head *head = &fib_info_laddrhash[hash]; | 1345 | struct hlist_head *head = &fib_info_laddrhash[hash]; |
1346 | struct net *net = dev_net(dev); | ||
1347 | int tb_id = l3mdev_fib_table(dev); | ||
1345 | struct fib_info *fi; | 1348 | struct fib_info *fi; |
1346 | 1349 | ||
1347 | if (!fib_info_laddrhash || local == 0) | 1350 | if (!fib_info_laddrhash || local == 0) |
1348 | return 0; | 1351 | return 0; |
1349 | 1352 | ||
1350 | hlist_for_each_entry(fi, head, fib_lhash) { | 1353 | hlist_for_each_entry(fi, head, fib_lhash) { |
1351 | if (!net_eq(fi->fib_net, net)) | 1354 | if (!net_eq(fi->fib_net, net) || |
1355 | fi->fib_tb_id != tb_id) | ||
1352 | continue; | 1356 | continue; |
1353 | if (fi->fib_prefsrc == local) { | 1357 | if (fi->fib_prefsrc == local) { |
1354 | fi->fib_flags |= RTNH_F_DEAD; | 1358 | fi->fib_flags |= RTNH_F_DEAD; |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index febca0f1008c..e2ffc2a5c7db 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -249,7 +249,7 @@ static inline unsigned long get_index(t_key key, struct key_vector *kv) | |||
249 | * index into the parent's child array. That is, they will be used to find | 249 | * index into the parent's child array. That is, they will be used to find |
250 | * 'n' among tp's children. | 250 | * 'n' among tp's children. |
251 | * | 251 | * |
252 | * The bits from (n->pos + n->bits) to (tn->pos - 1) - "S" - are skipped bits | 252 | * The bits from (n->pos + n->bits) to (tp->pos - 1) - "S" - are skipped bits |
253 | * for the node n. | 253 | * for the node n. |
254 | * | 254 | * |
255 | * All the bits we have seen so far are significant to the node n. The rest | 255 | * All the bits we have seen so far are significant to the node n. The rest |
@@ -258,7 +258,7 @@ static inline unsigned long get_index(t_key key, struct key_vector *kv) | |||
258 | * The bits from (n->pos) to (n->pos + n->bits - 1) - "C" - are the index into | 258 | * The bits from (n->pos) to (n->pos + n->bits - 1) - "C" - are the index into |
259 | * n's child array, and will of course be different for each child. | 259 | * n's child array, and will of course be different for each child. |
260 | * | 260 | * |
261 | * The rest of the bits, from 0 to (n->pos + n->bits), are completely unknown | 261 | * The rest of the bits, from 0 to (n->pos -1) - "u" - are completely unknown |
262 | * at this point. | 262 | * at this point. |
263 | */ | 263 | */ |
264 | 264 | ||
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 4b351af3e67b..d6feabb03516 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -312,6 +312,7 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
312 | { | 312 | { |
313 | const struct iphdr *iph = ip_hdr(skb); | 313 | const struct iphdr *iph = ip_hdr(skb); |
314 | struct rtable *rt; | 314 | struct rtable *rt; |
315 | struct net_device *dev = skb->dev; | ||
315 | 316 | ||
316 | /* if ingress device is enslaved to an L3 master device pass the | 317 | /* if ingress device is enslaved to an L3 master device pass the |
317 | * skb to its handler for processing | 318 | * skb to its handler for processing |
@@ -341,7 +342,7 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
341 | */ | 342 | */ |
342 | if (!skb_valid_dst(skb)) { | 343 | if (!skb_valid_dst(skb)) { |
343 | int err = ip_route_input_noref(skb, iph->daddr, iph->saddr, | 344 | int err = ip_route_input_noref(skb, iph->daddr, iph->saddr, |
344 | iph->tos, skb->dev); | 345 | iph->tos, dev); |
345 | if (unlikely(err)) { | 346 | if (unlikely(err)) { |
346 | if (err == -EXDEV) | 347 | if (err == -EXDEV) |
347 | __NET_INC_STATS(net, LINUX_MIB_IPRPFILTER); | 348 | __NET_INC_STATS(net, LINUX_MIB_IPRPFILTER); |
@@ -370,7 +371,7 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
370 | __IP_UPD_PO_STATS(net, IPSTATS_MIB_INBCAST, skb->len); | 371 | __IP_UPD_PO_STATS(net, IPSTATS_MIB_INBCAST, skb->len); |
371 | } else if (skb->pkt_type == PACKET_BROADCAST || | 372 | } else if (skb->pkt_type == PACKET_BROADCAST || |
372 | skb->pkt_type == PACKET_MULTICAST) { | 373 | skb->pkt_type == PACKET_MULTICAST) { |
373 | struct in_device *in_dev = __in_dev_get_rcu(skb->dev); | 374 | struct in_device *in_dev = __in_dev_get_rcu(dev); |
374 | 375 | ||
375 | /* RFC 1122 3.3.6: | 376 | /* RFC 1122 3.3.6: |
376 | * | 377 | * |
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index 9d847c302551..0f227db0e9ac 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c | |||
@@ -73,9 +73,11 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, | |||
73 | skb_dst_set(skb, &rt->dst); | 73 | skb_dst_set(skb, &rt->dst); |
74 | memset(IPCB(skb), 0, sizeof(*IPCB(skb))); | 74 | memset(IPCB(skb), 0, sizeof(*IPCB(skb))); |
75 | 75 | ||
76 | if (skb_iif && proto == IPPROTO_UDP) { | 76 | if (skb_iif && !(df & htons(IP_DF))) { |
77 | /* Arrived from an ingress interface and got udp encapuslated. | 77 | /* Arrived from an ingress interface, got encapsulated, with |
78 | * The encapsulated network segment length may exceed dst mtu. | 78 | * fragmentation of encapulating frames allowed. |
79 | * If skb is gso, the resulting encapsulated network segments | ||
80 | * may exceed dst mtu. | ||
79 | * Allow IP Fragmentation of segments. | 81 | * Allow IP Fragmentation of segments. |
80 | */ | 82 | */ |
81 | IPCB(skb)->flags |= IPSKB_FRAG_SEGS; | 83 | IPCB(skb)->flags |= IPSKB_FRAG_SEGS; |
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index cc701fa70b12..5d7944f394d9 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
@@ -88,6 +88,7 @@ static int vti_rcv_cb(struct sk_buff *skb, int err) | |||
88 | struct net_device *dev; | 88 | struct net_device *dev; |
89 | struct pcpu_sw_netstats *tstats; | 89 | struct pcpu_sw_netstats *tstats; |
90 | struct xfrm_state *x; | 90 | struct xfrm_state *x; |
91 | struct xfrm_mode *inner_mode; | ||
91 | struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4; | 92 | struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4; |
92 | u32 orig_mark = skb->mark; | 93 | u32 orig_mark = skb->mark; |
93 | int ret; | 94 | int ret; |
@@ -105,7 +106,19 @@ static int vti_rcv_cb(struct sk_buff *skb, int err) | |||
105 | } | 106 | } |
106 | 107 | ||
107 | x = xfrm_input_state(skb); | 108 | x = xfrm_input_state(skb); |
108 | family = x->inner_mode->afinfo->family; | 109 | |
110 | inner_mode = x->inner_mode; | ||
111 | |||
112 | if (x->sel.family == AF_UNSPEC) { | ||
113 | inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); | ||
114 | if (inner_mode == NULL) { | ||
115 | XFRM_INC_STATS(dev_net(skb->dev), | ||
116 | LINUX_MIB_XFRMINSTATEMODEERROR); | ||
117 | return -EINVAL; | ||
118 | } | ||
119 | } | ||
120 | |||
121 | family = inner_mode->afinfo->family; | ||
109 | 122 | ||
110 | skb->mark = be32_to_cpu(tunnel->parms.i_key); | 123 | skb->mark = be32_to_cpu(tunnel->parms.i_key); |
111 | ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family); | 124 | ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family); |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 26253328d227..a87bcd2d4a94 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -2076,6 +2076,7 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, | |||
2076 | struct rta_mfc_stats mfcs; | 2076 | struct rta_mfc_stats mfcs; |
2077 | struct nlattr *mp_attr; | 2077 | struct nlattr *mp_attr; |
2078 | struct rtnexthop *nhp; | 2078 | struct rtnexthop *nhp; |
2079 | unsigned long lastuse; | ||
2079 | int ct; | 2080 | int ct; |
2080 | 2081 | ||
2081 | /* If cache is unresolved, don't try to parse IIF and OIF */ | 2082 | /* If cache is unresolved, don't try to parse IIF and OIF */ |
@@ -2105,12 +2106,14 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, | |||
2105 | 2106 | ||
2106 | nla_nest_end(skb, mp_attr); | 2107 | nla_nest_end(skb, mp_attr); |
2107 | 2108 | ||
2109 | lastuse = READ_ONCE(c->mfc_un.res.lastuse); | ||
2110 | lastuse = time_after_eq(jiffies, lastuse) ? jiffies - lastuse : 0; | ||
2111 | |||
2108 | mfcs.mfcs_packets = c->mfc_un.res.pkt; | 2112 | mfcs.mfcs_packets = c->mfc_un.res.pkt; |
2109 | mfcs.mfcs_bytes = c->mfc_un.res.bytes; | 2113 | mfcs.mfcs_bytes = c->mfc_un.res.bytes; |
2110 | mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if; | 2114 | mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if; |
2111 | if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) || | 2115 | if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) || |
2112 | nla_put_u64_64bit(skb, RTA_EXPIRES, | 2116 | nla_put_u64_64bit(skb, RTA_EXPIRES, jiffies_to_clock_t(lastuse), |
2113 | jiffies_to_clock_t(c->mfc_un.res.lastuse), | ||
2114 | RTA_PAD)) | 2117 | RTA_PAD)) |
2115 | return -EMSGSIZE; | 2118 | return -EMSGSIZE; |
2116 | 2119 | ||
diff --git a/net/ipv4/netfilter/nft_chain_route_ipv4.c b/net/ipv4/netfilter/nft_chain_route_ipv4.c index 2375b0a8be46..30493beb611a 100644 --- a/net/ipv4/netfilter/nft_chain_route_ipv4.c +++ b/net/ipv4/netfilter/nft_chain_route_ipv4.c | |||
@@ -31,6 +31,7 @@ static unsigned int nf_route_table_hook(void *priv, | |||
31 | __be32 saddr, daddr; | 31 | __be32 saddr, daddr; |
32 | u_int8_t tos; | 32 | u_int8_t tos; |
33 | const struct iphdr *iph; | 33 | const struct iphdr *iph; |
34 | int err; | ||
34 | 35 | ||
35 | /* root is playing with raw sockets. */ | 36 | /* root is playing with raw sockets. */ |
36 | if (skb->len < sizeof(struct iphdr) || | 37 | if (skb->len < sizeof(struct iphdr) || |
@@ -46,15 +47,17 @@ static unsigned int nf_route_table_hook(void *priv, | |||
46 | tos = iph->tos; | 47 | tos = iph->tos; |
47 | 48 | ||
48 | ret = nft_do_chain(&pkt, priv); | 49 | ret = nft_do_chain(&pkt, priv); |
49 | if (ret != NF_DROP && ret != NF_QUEUE) { | 50 | if (ret != NF_DROP && ret != NF_STOLEN) { |
50 | iph = ip_hdr(skb); | 51 | iph = ip_hdr(skb); |
51 | 52 | ||
52 | if (iph->saddr != saddr || | 53 | if (iph->saddr != saddr || |
53 | iph->daddr != daddr || | 54 | iph->daddr != daddr || |
54 | skb->mark != mark || | 55 | skb->mark != mark || |
55 | iph->tos != tos) | 56 | iph->tos != tos) { |
56 | if (ip_route_me_harder(state->net, skb, RTN_UNSPEC)) | 57 | err = ip_route_me_harder(state->net, skb, RTN_UNSPEC); |
57 | ret = NF_DROP; | 58 | if (err < 0) |
59 | ret = NF_DROP_ERR(err); | ||
60 | } | ||
58 | } | 61 | } |
59 | return ret; | 62 | return ret; |
60 | } | 63 | } |
diff --git a/net/ipv4/netfilter/nft_reject_ipv4.c b/net/ipv4/netfilter/nft_reject_ipv4.c index c24f41c816b3..2c2553b9026c 100644 --- a/net/ipv4/netfilter/nft_reject_ipv4.c +++ b/net/ipv4/netfilter/nft_reject_ipv4.c | |||
@@ -46,6 +46,7 @@ static const struct nft_expr_ops nft_reject_ipv4_ops = { | |||
46 | .eval = nft_reject_ipv4_eval, | 46 | .eval = nft_reject_ipv4_eval, |
47 | .init = nft_reject_init, | 47 | .init = nft_reject_init, |
48 | .dump = nft_reject_dump, | 48 | .dump = nft_reject_dump, |
49 | .validate = nft_reject_validate, | ||
49 | }; | 50 | }; |
50 | 51 | ||
51 | static struct nft_expr_type nft_reject_ipv4_type __read_mostly = { | 52 | static struct nft_expr_type nft_reject_ipv4_type __read_mostly = { |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a1f2830d8110..b5b47a26d4ec 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -476,12 +476,18 @@ u32 ip_idents_reserve(u32 hash, int segs) | |||
476 | atomic_t *p_id = ip_idents + hash % IP_IDENTS_SZ; | 476 | atomic_t *p_id = ip_idents + hash % IP_IDENTS_SZ; |
477 | u32 old = ACCESS_ONCE(*p_tstamp); | 477 | u32 old = ACCESS_ONCE(*p_tstamp); |
478 | u32 now = (u32)jiffies; | 478 | u32 now = (u32)jiffies; |
479 | u32 delta = 0; | 479 | u32 new, delta = 0; |
480 | 480 | ||
481 | if (old != now && cmpxchg(p_tstamp, old, now) == old) | 481 | if (old != now && cmpxchg(p_tstamp, old, now) == old) |
482 | delta = prandom_u32_max(now - old); | 482 | delta = prandom_u32_max(now - old); |
483 | 483 | ||
484 | return atomic_add_return(segs + delta, p_id) - segs; | 484 | /* Do not use atomic_add_return() as it makes UBSAN unhappy */ |
485 | do { | ||
486 | old = (u32)atomic_read(p_id); | ||
487 | new = old + delta + segs; | ||
488 | } while (atomic_cmpxchg(p_id, old, new) != old); | ||
489 | |||
490 | return new - segs; | ||
485 | } | 491 | } |
486 | EXPORT_SYMBOL(ip_idents_reserve); | 492 | EXPORT_SYMBOL(ip_idents_reserve); |
487 | 493 | ||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 032a96d78c99..ffbb218de520 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -3193,7 +3193,6 @@ int tcp_abort(struct sock *sk, int err) | |||
3193 | local_bh_enable(); | 3193 | local_bh_enable(); |
3194 | return 0; | 3194 | return 0; |
3195 | } | 3195 | } |
3196 | sock_gen_put(sk); | ||
3197 | return -EOPNOTSUPP; | 3196 | return -EOPNOTSUPP; |
3198 | } | 3197 | } |
3199 | 3198 | ||
@@ -3222,7 +3221,6 @@ int tcp_abort(struct sock *sk, int err) | |||
3222 | bh_unlock_sock(sk); | 3221 | bh_unlock_sock(sk); |
3223 | local_bh_enable(); | 3222 | local_bh_enable(); |
3224 | release_sock(sk); | 3223 | release_sock(sk); |
3225 | sock_put(sk); | ||
3226 | return 0; | 3224 | return 0; |
3227 | } | 3225 | } |
3228 | EXPORT_SYMBOL_GPL(tcp_abort); | 3226 | EXPORT_SYMBOL_GPL(tcp_abort); |
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c index 4d610934fb39..a748c74aa8b7 100644 --- a/net/ipv4/tcp_diag.c +++ b/net/ipv4/tcp_diag.c | |||
@@ -54,11 +54,16 @@ static int tcp_diag_destroy(struct sk_buff *in_skb, | |||
54 | { | 54 | { |
55 | struct net *net = sock_net(in_skb->sk); | 55 | struct net *net = sock_net(in_skb->sk); |
56 | struct sock *sk = inet_diag_find_one_icsk(net, &tcp_hashinfo, req); | 56 | struct sock *sk = inet_diag_find_one_icsk(net, &tcp_hashinfo, req); |
57 | int err; | ||
57 | 58 | ||
58 | if (IS_ERR(sk)) | 59 | if (IS_ERR(sk)) |
59 | return PTR_ERR(sk); | 60 | return PTR_ERR(sk); |
60 | 61 | ||
61 | return sock_diag_destroy(sk, ECONNABORTED); | 62 | err = sock_diag_destroy(sk, ECONNABORTED); |
63 | |||
64 | sock_gen_put(sk); | ||
65 | |||
66 | return err; | ||
62 | } | 67 | } |
63 | #endif | 68 | #endif |
64 | 69 | ||
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index 54d9f9b0120f..4e777a3243f9 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c | |||
@@ -150,6 +150,7 @@ void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb) | |||
150 | tp->segs_in = 0; | 150 | tp->segs_in = 0; |
151 | tcp_segs_in(tp, skb); | 151 | tcp_segs_in(tp, skb); |
152 | __skb_pull(skb, tcp_hdrlen(skb)); | 152 | __skb_pull(skb, tcp_hdrlen(skb)); |
153 | sk_forced_mem_schedule(sk, skb->truesize); | ||
153 | skb_set_owner_r(skb, sk); | 154 | skb_set_owner_r(skb, sk); |
154 | 155 | ||
155 | TCP_SKB_CB(skb)->seq++; | 156 | TCP_SKB_CB(skb)->seq++; |
@@ -226,6 +227,7 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk, | |||
226 | tcp_fastopen_add_skb(child, skb); | 227 | tcp_fastopen_add_skb(child, skb); |
227 | 228 | ||
228 | tcp_rsk(req)->rcv_nxt = tp->rcv_nxt; | 229 | tcp_rsk(req)->rcv_nxt = tp->rcv_nxt; |
230 | tp->rcv_wup = tp->rcv_nxt; | ||
229 | /* tcp_conn_request() is sending the SYNACK, | 231 | /* tcp_conn_request() is sending the SYNACK, |
230 | * and queues the child into listener accept queue. | 232 | * and queues the child into listener accept queue. |
231 | */ | 233 | */ |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 3ebf45b38bc3..08323bd95f2a 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -5885,7 +5885,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) | |||
5885 | * so release it. | 5885 | * so release it. |
5886 | */ | 5886 | */ |
5887 | if (req) { | 5887 | if (req) { |
5888 | tp->total_retrans = req->num_retrans; | 5888 | inet_csk(sk)->icsk_retransmits = 0; |
5889 | reqsk_fastopen_remove(sk, req, false); | 5889 | reqsk_fastopen_remove(sk, req, false); |
5890 | } else { | 5890 | } else { |
5891 | /* Make sure socket is routed, for correct metrics. */ | 5891 | /* Make sure socket is routed, for correct metrics. */ |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 32b048e524d6..7158d4f8dae4 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -814,8 +814,14 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, | |||
814 | u32 seq = (sk->sk_state == TCP_LISTEN) ? tcp_rsk(req)->snt_isn + 1 : | 814 | u32 seq = (sk->sk_state == TCP_LISTEN) ? tcp_rsk(req)->snt_isn + 1 : |
815 | tcp_sk(sk)->snd_nxt; | 815 | tcp_sk(sk)->snd_nxt; |
816 | 816 | ||
817 | /* RFC 7323 2.3 | ||
818 | * The window field (SEG.WND) of every outgoing segment, with the | ||
819 | * exception of <SYN> segments, MUST be right-shifted by | ||
820 | * Rcv.Wind.Shift bits: | ||
821 | */ | ||
817 | tcp_v4_send_ack(sock_net(sk), skb, seq, | 822 | tcp_v4_send_ack(sock_net(sk), skb, seq, |
818 | tcp_rsk(req)->rcv_nxt, req->rsk_rcv_wnd, | 823 | tcp_rsk(req)->rcv_nxt, |
824 | req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, | ||
819 | tcp_time_stamp, | 825 | tcp_time_stamp, |
820 | req->ts_recent, | 826 | req->ts_recent, |
821 | 0, | 827 | 0, |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index bdaef7fd6e47..5288cec4a2b2 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2605,7 +2605,8 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs) | |||
2605 | * copying overhead: fragmentation, tunneling, mangling etc. | 2605 | * copying overhead: fragmentation, tunneling, mangling etc. |
2606 | */ | 2606 | */ |
2607 | if (atomic_read(&sk->sk_wmem_alloc) > | 2607 | if (atomic_read(&sk->sk_wmem_alloc) > |
2608 | min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf)) | 2608 | min_t(u32, sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), |
2609 | sk->sk_sndbuf)) | ||
2609 | return -EAGAIN; | 2610 | return -EAGAIN; |
2610 | 2611 | ||
2611 | if (skb_still_in_host_queue(sk, skb)) | 2612 | if (skb_still_in_host_queue(sk, skb)) |
@@ -2830,7 +2831,7 @@ begin_fwd: | |||
2830 | if (tcp_retransmit_skb(sk, skb, segs)) | 2831 | if (tcp_retransmit_skb(sk, skb, segs)) |
2831 | return; | 2832 | return; |
2832 | 2833 | ||
2833 | NET_INC_STATS(sock_net(sk), mib_idx); | 2834 | NET_ADD_STATS(sock_net(sk), mib_idx, tcp_skb_pcount(skb)); |
2834 | 2835 | ||
2835 | if (tcp_in_cwnd_reduction(sk)) | 2836 | if (tcp_in_cwnd_reduction(sk)) |
2836 | tp->prr_out += tcp_skb_pcount(skb); | 2837 | tp->prr_out += tcp_skb_pcount(skb); |
@@ -3567,6 +3568,8 @@ int tcp_rtx_synack(const struct sock *sk, struct request_sock *req) | |||
3567 | if (!res) { | 3568 | if (!res) { |
3568 | __TCP_INC_STATS(sock_net(sk), TCP_MIB_RETRANSSEGS); | 3569 | __TCP_INC_STATS(sock_net(sk), TCP_MIB_RETRANSSEGS); |
3569 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPSYNRETRANS); | 3570 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPSYNRETRANS); |
3571 | if (unlikely(tcp_passive_fastopen(sk))) | ||
3572 | tcp_sk(sk)->total_retrans++; | ||
3570 | } | 3573 | } |
3571 | return res; | 3574 | return res; |
3572 | } | 3575 | } |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index d84930b2dd95..f712b411f6ed 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -384,6 +384,7 @@ static void tcp_fastopen_synack_timer(struct sock *sk) | |||
384 | */ | 384 | */ |
385 | inet_rtx_syn_ack(sk, req); | 385 | inet_rtx_syn_ack(sk, req); |
386 | req->num_timeout++; | 386 | req->num_timeout++; |
387 | icsk->icsk_retransmits++; | ||
387 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, | 388 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, |
388 | TCP_TIMEOUT_INIT << req->num_timeout, TCP_RTO_MAX); | 389 | TCP_TIMEOUT_INIT << req->num_timeout, TCP_RTO_MAX); |
389 | } | 390 | } |
diff --git a/net/ipv4/tcp_yeah.c b/net/ipv4/tcp_yeah.c index 028eb046ea40..9c5fc973267f 100644 --- a/net/ipv4/tcp_yeah.c +++ b/net/ipv4/tcp_yeah.c | |||
@@ -76,7 +76,7 @@ static void tcp_yeah_cong_avoid(struct sock *sk, u32 ack, u32 acked) | |||
76 | if (!tcp_is_cwnd_limited(sk)) | 76 | if (!tcp_is_cwnd_limited(sk)) |
77 | return; | 77 | return; |
78 | 78 | ||
79 | if (tp->snd_cwnd <= tp->snd_ssthresh) | 79 | if (tcp_in_slow_start(tp)) |
80 | tcp_slow_start(tp, acked); | 80 | tcp_slow_start(tp, acked); |
81 | 81 | ||
82 | else if (!yeah->doing_reno_now) { | 82 | else if (!yeah->doing_reno_now) { |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index e61f7cd65d08..5fdcb8d108d4 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1182,13 +1182,13 @@ out: | |||
1182 | * @sk: socket | 1182 | * @sk: socket |
1183 | * | 1183 | * |
1184 | * Drops all bad checksum frames, until a valid one is found. | 1184 | * Drops all bad checksum frames, until a valid one is found. |
1185 | * Returns the length of found skb, or 0 if none is found. | 1185 | * Returns the length of found skb, or -1 if none is found. |
1186 | */ | 1186 | */ |
1187 | static unsigned int first_packet_length(struct sock *sk) | 1187 | static int first_packet_length(struct sock *sk) |
1188 | { | 1188 | { |
1189 | struct sk_buff_head list_kill, *rcvq = &sk->sk_receive_queue; | 1189 | struct sk_buff_head list_kill, *rcvq = &sk->sk_receive_queue; |
1190 | struct sk_buff *skb; | 1190 | struct sk_buff *skb; |
1191 | unsigned int res; | 1191 | int res; |
1192 | 1192 | ||
1193 | __skb_queue_head_init(&list_kill); | 1193 | __skb_queue_head_init(&list_kill); |
1194 | 1194 | ||
@@ -1203,7 +1203,7 @@ static unsigned int first_packet_length(struct sock *sk) | |||
1203 | __skb_unlink(skb, rcvq); | 1203 | __skb_unlink(skb, rcvq); |
1204 | __skb_queue_tail(&list_kill, skb); | 1204 | __skb_queue_tail(&list_kill, skb); |
1205 | } | 1205 | } |
1206 | res = skb ? skb->len : 0; | 1206 | res = skb ? skb->len : -1; |
1207 | spin_unlock_bh(&rcvq->lock); | 1207 | spin_unlock_bh(&rcvq->lock); |
1208 | 1208 | ||
1209 | if (!skb_queue_empty(&list_kill)) { | 1209 | if (!skb_queue_empty(&list_kill)) { |
@@ -1232,7 +1232,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
1232 | 1232 | ||
1233 | case SIOCINQ: | 1233 | case SIOCINQ: |
1234 | { | 1234 | { |
1235 | unsigned int amount = first_packet_length(sk); | 1235 | int amount = max_t(int, 0, first_packet_length(sk)); |
1236 | 1236 | ||
1237 | return put_user(amount, (int __user *)arg); | 1237 | return put_user(amount, (int __user *)arg); |
1238 | } | 1238 | } |
@@ -2184,7 +2184,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
2184 | 2184 | ||
2185 | /* Check for false positives due to checksum errors */ | 2185 | /* Check for false positives due to checksum errors */ |
2186 | if ((mask & POLLRDNORM) && !(file->f_flags & O_NONBLOCK) && | 2186 | if ((mask & POLLRDNORM) && !(file->f_flags & O_NONBLOCK) && |
2187 | !(sk->sk_shutdown & RCV_SHUTDOWN) && !first_packet_length(sk)) | 2187 | !(sk->sk_shutdown & RCV_SHUTDOWN) && first_packet_length(sk) == -1) |
2188 | mask &= ~(POLLIN | POLLRDNORM); | 2188 | mask &= ~(POLLIN | POLLRDNORM); |
2189 | 2189 | ||
2190 | return mask; | 2190 | return mask; |
@@ -2216,7 +2216,6 @@ struct proto udp_prot = { | |||
2216 | .sysctl_wmem = &sysctl_udp_wmem_min, | 2216 | .sysctl_wmem = &sysctl_udp_wmem_min, |
2217 | .sysctl_rmem = &sysctl_udp_rmem_min, | 2217 | .sysctl_rmem = &sysctl_udp_rmem_min, |
2218 | .obj_size = sizeof(struct udp_sock), | 2218 | .obj_size = sizeof(struct udp_sock), |
2219 | .slab_flags = SLAB_DESTROY_BY_RCU, | ||
2220 | .h.udp_table = &udp_table, | 2219 | .h.udp_table = &udp_table, |
2221 | #ifdef CONFIG_COMPAT | 2220 | #ifdef CONFIG_COMPAT |
2222 | .compat_setsockopt = compat_udp_setsockopt, | 2221 | .compat_setsockopt = compat_udp_setsockopt, |
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c index 3b3efbda48e1..2eea073e27ef 100644 --- a/net/ipv4/udplite.c +++ b/net/ipv4/udplite.c | |||
@@ -55,7 +55,6 @@ struct proto udplite_prot = { | |||
55 | .unhash = udp_lib_unhash, | 55 | .unhash = udp_lib_unhash, |
56 | .get_port = udp_v4_get_port, | 56 | .get_port = udp_v4_get_port, |
57 | .obj_size = sizeof(struct udp_sock), | 57 | .obj_size = sizeof(struct udp_sock), |
58 | .slab_flags = SLAB_DESTROY_BY_RCU, | ||
59 | .h.udp_table = &udplite_table, | 58 | .h.udp_table = &udplite_table, |
60 | #ifdef CONFIG_COMPAT | 59 | #ifdef CONFIG_COMPAT |
61 | .compat_setsockopt = compat_udp_setsockopt, | 60 | .compat_setsockopt = compat_udp_setsockopt, |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index b644a23c3db0..41f5b504a782 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -29,7 +29,7 @@ static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4, | |||
29 | memset(fl4, 0, sizeof(*fl4)); | 29 | memset(fl4, 0, sizeof(*fl4)); |
30 | fl4->daddr = daddr->a4; | 30 | fl4->daddr = daddr->a4; |
31 | fl4->flowi4_tos = tos; | 31 | fl4->flowi4_tos = tos; |
32 | fl4->flowi4_oif = oif; | 32 | fl4->flowi4_oif = l3mdev_master_ifindex_by_index(net, oif); |
33 | if (saddr) | 33 | if (saddr) |
34 | fl4->saddr = saddr->a4; | 34 | fl4->saddr = saddr->a4; |
35 | 35 | ||
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index df8425fcbc2c..2f1f5d439788 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -778,7 +778,14 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf) | |||
778 | } | 778 | } |
779 | 779 | ||
780 | if (p == &net->ipv6.devconf_all->forwarding) { | 780 | if (p == &net->ipv6.devconf_all->forwarding) { |
781 | int old_dflt = net->ipv6.devconf_dflt->forwarding; | ||
782 | |||
781 | net->ipv6.devconf_dflt->forwarding = newf; | 783 | net->ipv6.devconf_dflt->forwarding = newf; |
784 | if ((!newf) ^ (!old_dflt)) | ||
785 | inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING, | ||
786 | NETCONFA_IFINDEX_DEFAULT, | ||
787 | net->ipv6.devconf_dflt); | ||
788 | |||
782 | addrconf_forward_change(net, newf); | 789 | addrconf_forward_change(net, newf); |
783 | if ((!newf) ^ (!old)) | 790 | if ((!newf) ^ (!old)) |
784 | inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING, | 791 | inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING, |
@@ -1872,7 +1879,6 @@ static int addrconf_dad_end(struct inet6_ifaddr *ifp) | |||
1872 | 1879 | ||
1873 | void addrconf_dad_failure(struct inet6_ifaddr *ifp) | 1880 | void addrconf_dad_failure(struct inet6_ifaddr *ifp) |
1874 | { | 1881 | { |
1875 | struct in6_addr addr; | ||
1876 | struct inet6_dev *idev = ifp->idev; | 1882 | struct inet6_dev *idev = ifp->idev; |
1877 | struct net *net = dev_net(ifp->idev->dev); | 1883 | struct net *net = dev_net(ifp->idev->dev); |
1878 | 1884 | ||
@@ -1934,18 +1940,6 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp) | |||
1934 | in6_ifa_put(ifp2); | 1940 | in6_ifa_put(ifp2); |
1935 | lock_errdad: | 1941 | lock_errdad: |
1936 | spin_lock_bh(&ifp->lock); | 1942 | spin_lock_bh(&ifp->lock); |
1937 | } else if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6) { | ||
1938 | addr.s6_addr32[0] = htonl(0xfe800000); | ||
1939 | addr.s6_addr32[1] = 0; | ||
1940 | |||
1941 | if (!ipv6_generate_eui64(addr.s6_addr + 8, idev->dev) && | ||
1942 | ipv6_addr_equal(&ifp->addr, &addr)) { | ||
1943 | /* DAD failed for link-local based on MAC address */ | ||
1944 | idev->cnf.disable_ipv6 = 1; | ||
1945 | |||
1946 | pr_info("%s: IPv6 being disabled!\n", | ||
1947 | ifp->idev->dev->name); | ||
1948 | } | ||
1949 | } | 1943 | } |
1950 | 1944 | ||
1951 | errdad: | 1945 | errdad: |
@@ -1954,6 +1948,7 @@ errdad: | |||
1954 | spin_unlock_bh(&ifp->lock); | 1948 | spin_unlock_bh(&ifp->lock); |
1955 | 1949 | ||
1956 | addrconf_mod_dad_work(ifp, 0); | 1950 | addrconf_mod_dad_work(ifp, 0); |
1951 | in6_ifa_put(ifp); | ||
1957 | } | 1952 | } |
1958 | 1953 | ||
1959 | /* Join to solicited addr multicast group. | 1954 | /* Join to solicited addr multicast group. |
@@ -3821,6 +3816,7 @@ static void addrconf_dad_work(struct work_struct *w) | |||
3821 | dad_work); | 3816 | dad_work); |
3822 | struct inet6_dev *idev = ifp->idev; | 3817 | struct inet6_dev *idev = ifp->idev; |
3823 | struct in6_addr mcaddr; | 3818 | struct in6_addr mcaddr; |
3819 | bool disable_ipv6 = false; | ||
3824 | 3820 | ||
3825 | enum { | 3821 | enum { |
3826 | DAD_PROCESS, | 3822 | DAD_PROCESS, |
@@ -3837,6 +3833,24 @@ static void addrconf_dad_work(struct work_struct *w) | |||
3837 | } else if (ifp->state == INET6_IFADDR_STATE_ERRDAD) { | 3833 | } else if (ifp->state == INET6_IFADDR_STATE_ERRDAD) { |
3838 | action = DAD_ABORT; | 3834 | action = DAD_ABORT; |
3839 | ifp->state = INET6_IFADDR_STATE_POSTDAD; | 3835 | ifp->state = INET6_IFADDR_STATE_POSTDAD; |
3836 | |||
3837 | if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6 && | ||
3838 | !(ifp->flags & IFA_F_STABLE_PRIVACY)) { | ||
3839 | struct in6_addr addr; | ||
3840 | |||
3841 | addr.s6_addr32[0] = htonl(0xfe800000); | ||
3842 | addr.s6_addr32[1] = 0; | ||
3843 | |||
3844 | if (!ipv6_generate_eui64(addr.s6_addr + 8, idev->dev) && | ||
3845 | ipv6_addr_equal(&ifp->addr, &addr)) { | ||
3846 | /* DAD failed for link-local based on MAC */ | ||
3847 | idev->cnf.disable_ipv6 = 1; | ||
3848 | |||
3849 | pr_info("%s: IPv6 being disabled!\n", | ||
3850 | ifp->idev->dev->name); | ||
3851 | disable_ipv6 = true; | ||
3852 | } | ||
3853 | } | ||
3840 | } | 3854 | } |
3841 | spin_unlock_bh(&ifp->lock); | 3855 | spin_unlock_bh(&ifp->lock); |
3842 | 3856 | ||
@@ -3844,7 +3858,10 @@ static void addrconf_dad_work(struct work_struct *w) | |||
3844 | addrconf_dad_begin(ifp); | 3858 | addrconf_dad_begin(ifp); |
3845 | goto out; | 3859 | goto out; |
3846 | } else if (action == DAD_ABORT) { | 3860 | } else if (action == DAD_ABORT) { |
3861 | in6_ifa_hold(ifp); | ||
3847 | addrconf_dad_stop(ifp, 1); | 3862 | addrconf_dad_stop(ifp, 1); |
3863 | if (disable_ipv6) | ||
3864 | addrconf_ifdown(idev->dev, 0); | ||
3848 | goto out; | 3865 | goto out; |
3849 | } | 3866 | } |
3850 | 3867 | ||
@@ -6017,7 +6034,7 @@ static const struct ctl_table addrconf_sysctl[] = { | |||
6017 | static int __addrconf_sysctl_register(struct net *net, char *dev_name, | 6034 | static int __addrconf_sysctl_register(struct net *net, char *dev_name, |
6018 | struct inet6_dev *idev, struct ipv6_devconf *p) | 6035 | struct inet6_dev *idev, struct ipv6_devconf *p) |
6019 | { | 6036 | { |
6020 | int i; | 6037 | int i, ifindex; |
6021 | struct ctl_table *table; | 6038 | struct ctl_table *table; |
6022 | char path[sizeof("net/ipv6/conf/") + IFNAMSIZ]; | 6039 | char path[sizeof("net/ipv6/conf/") + IFNAMSIZ]; |
6023 | 6040 | ||
@@ -6037,6 +6054,13 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name, | |||
6037 | if (!p->sysctl_header) | 6054 | if (!p->sysctl_header) |
6038 | goto free; | 6055 | goto free; |
6039 | 6056 | ||
6057 | if (!strcmp(dev_name, "all")) | ||
6058 | ifindex = NETCONFA_IFINDEX_ALL; | ||
6059 | else if (!strcmp(dev_name, "default")) | ||
6060 | ifindex = NETCONFA_IFINDEX_DEFAULT; | ||
6061 | else | ||
6062 | ifindex = idev->dev->ifindex; | ||
6063 | inet6_netconf_notify_devconf(net, NETCONFA_ALL, ifindex, p); | ||
6040 | return 0; | 6064 | return 0; |
6041 | 6065 | ||
6042 | free: | 6066 | free: |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 7b0481e3738f..888543debe4e 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -1174,6 +1174,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1174 | encap_limit = t->parms.encap_limit; | 1174 | encap_limit = t->parms.encap_limit; |
1175 | 1175 | ||
1176 | memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); | 1176 | memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); |
1177 | fl6.flowi6_proto = IPPROTO_IPIP; | ||
1177 | 1178 | ||
1178 | dsfield = ipv4_get_dsfield(iph); | 1179 | dsfield = ipv4_get_dsfield(iph); |
1179 | 1180 | ||
@@ -1233,6 +1234,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1233 | encap_limit = t->parms.encap_limit; | 1234 | encap_limit = t->parms.encap_limit; |
1234 | 1235 | ||
1235 | memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); | 1236 | memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); |
1237 | fl6.flowi6_proto = IPPROTO_IPV6; | ||
1236 | 1238 | ||
1237 | dsfield = ipv6_get_dsfield(ipv6h); | 1239 | dsfield = ipv6_get_dsfield(ipv6h); |
1238 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) | 1240 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) |
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index d90a11f14040..5bd3afdcc771 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
@@ -321,11 +321,9 @@ static int vti6_rcv(struct sk_buff *skb) | |||
321 | goto discard; | 321 | goto discard; |
322 | } | 322 | } |
323 | 323 | ||
324 | XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t; | ||
325 | |||
326 | rcu_read_unlock(); | 324 | rcu_read_unlock(); |
327 | 325 | ||
328 | return xfrm6_rcv(skb); | 326 | return xfrm6_rcv_tnl(skb, t); |
329 | } | 327 | } |
330 | rcu_read_unlock(); | 328 | rcu_read_unlock(); |
331 | return -EINVAL; | 329 | return -EINVAL; |
@@ -340,6 +338,7 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err) | |||
340 | struct net_device *dev; | 338 | struct net_device *dev; |
341 | struct pcpu_sw_netstats *tstats; | 339 | struct pcpu_sw_netstats *tstats; |
342 | struct xfrm_state *x; | 340 | struct xfrm_state *x; |
341 | struct xfrm_mode *inner_mode; | ||
343 | struct ip6_tnl *t = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6; | 342 | struct ip6_tnl *t = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6; |
344 | u32 orig_mark = skb->mark; | 343 | u32 orig_mark = skb->mark; |
345 | int ret; | 344 | int ret; |
@@ -357,7 +356,19 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err) | |||
357 | } | 356 | } |
358 | 357 | ||
359 | x = xfrm_input_state(skb); | 358 | x = xfrm_input_state(skb); |
360 | family = x->inner_mode->afinfo->family; | 359 | |
360 | inner_mode = x->inner_mode; | ||
361 | |||
362 | if (x->sel.family == AF_UNSPEC) { | ||
363 | inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); | ||
364 | if (inner_mode == NULL) { | ||
365 | XFRM_INC_STATS(dev_net(skb->dev), | ||
366 | LINUX_MIB_XFRMINSTATEMODEERROR); | ||
367 | return -EINVAL; | ||
368 | } | ||
369 | } | ||
370 | |||
371 | family = inner_mode->afinfo->family; | ||
361 | 372 | ||
362 | skb->mark = be32_to_cpu(t->parms.i_key); | 373 | skb->mark = be32_to_cpu(t->parms.i_key); |
363 | ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family); | 374 | ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family); |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 6122f9c5cc49..fccb5dd91902 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -2239,6 +2239,7 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb, | |||
2239 | struct rta_mfc_stats mfcs; | 2239 | struct rta_mfc_stats mfcs; |
2240 | struct nlattr *mp_attr; | 2240 | struct nlattr *mp_attr; |
2241 | struct rtnexthop *nhp; | 2241 | struct rtnexthop *nhp; |
2242 | unsigned long lastuse; | ||
2242 | int ct; | 2243 | int ct; |
2243 | 2244 | ||
2244 | /* If cache is unresolved, don't try to parse IIF and OIF */ | 2245 | /* If cache is unresolved, don't try to parse IIF and OIF */ |
@@ -2269,12 +2270,14 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb, | |||
2269 | 2270 | ||
2270 | nla_nest_end(skb, mp_attr); | 2271 | nla_nest_end(skb, mp_attr); |
2271 | 2272 | ||
2273 | lastuse = READ_ONCE(c->mfc_un.res.lastuse); | ||
2274 | lastuse = time_after_eq(jiffies, lastuse) ? jiffies - lastuse : 0; | ||
2275 | |||
2272 | mfcs.mfcs_packets = c->mfc_un.res.pkt; | 2276 | mfcs.mfcs_packets = c->mfc_un.res.pkt; |
2273 | mfcs.mfcs_bytes = c->mfc_un.res.bytes; | 2277 | mfcs.mfcs_bytes = c->mfc_un.res.bytes; |
2274 | mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if; | 2278 | mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if; |
2275 | if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) || | 2279 | if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) || |
2276 | nla_put_u64_64bit(skb, RTA_EXPIRES, | 2280 | nla_put_u64_64bit(skb, RTA_EXPIRES, jiffies_to_clock_t(lastuse), |
2277 | jiffies_to_clock_t(c->mfc_un.res.lastuse), | ||
2278 | RTA_PAD)) | 2281 | RTA_PAD)) |
2279 | return -EMSGSIZE; | 2282 | return -EMSGSIZE; |
2280 | 2283 | ||
diff --git a/net/ipv6/netfilter/nft_chain_route_ipv6.c b/net/ipv6/netfilter/nft_chain_route_ipv6.c index 71d995ff3108..2535223ba956 100644 --- a/net/ipv6/netfilter/nft_chain_route_ipv6.c +++ b/net/ipv6/netfilter/nft_chain_route_ipv6.c | |||
@@ -31,6 +31,7 @@ static unsigned int nf_route_table_hook(void *priv, | |||
31 | struct in6_addr saddr, daddr; | 31 | struct in6_addr saddr, daddr; |
32 | u_int8_t hop_limit; | 32 | u_int8_t hop_limit; |
33 | u32 mark, flowlabel; | 33 | u32 mark, flowlabel; |
34 | int err; | ||
34 | 35 | ||
35 | /* malformed packet, drop it */ | 36 | /* malformed packet, drop it */ |
36 | if (nft_set_pktinfo_ipv6(&pkt, skb, state) < 0) | 37 | if (nft_set_pktinfo_ipv6(&pkt, skb, state) < 0) |
@@ -46,13 +47,16 @@ static unsigned int nf_route_table_hook(void *priv, | |||
46 | flowlabel = *((u32 *)ipv6_hdr(skb)); | 47 | flowlabel = *((u32 *)ipv6_hdr(skb)); |
47 | 48 | ||
48 | ret = nft_do_chain(&pkt, priv); | 49 | ret = nft_do_chain(&pkt, priv); |
49 | if (ret != NF_DROP && ret != NF_QUEUE && | 50 | if (ret != NF_DROP && ret != NF_STOLEN && |
50 | (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) || | 51 | (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) || |
51 | memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) || | 52 | memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) || |
52 | skb->mark != mark || | 53 | skb->mark != mark || |
53 | ipv6_hdr(skb)->hop_limit != hop_limit || | 54 | ipv6_hdr(skb)->hop_limit != hop_limit || |
54 | flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) | 55 | flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) { |
55 | return ip6_route_me_harder(state->net, skb) == 0 ? ret : NF_DROP; | 56 | err = ip6_route_me_harder(state->net, skb); |
57 | if (err < 0) | ||
58 | ret = NF_DROP_ERR(err); | ||
59 | } | ||
56 | 60 | ||
57 | return ret; | 61 | return ret; |
58 | } | 62 | } |
diff --git a/net/ipv6/netfilter/nft_reject_ipv6.c b/net/ipv6/netfilter/nft_reject_ipv6.c index 533cd5719c59..92bda9908bb9 100644 --- a/net/ipv6/netfilter/nft_reject_ipv6.c +++ b/net/ipv6/netfilter/nft_reject_ipv6.c | |||
@@ -47,6 +47,7 @@ static const struct nft_expr_ops nft_reject_ipv6_ops = { | |||
47 | .eval = nft_reject_ipv6_eval, | 47 | .eval = nft_reject_ipv6_eval, |
48 | .init = nft_reject_init, | 48 | .init = nft_reject_init, |
49 | .dump = nft_reject_dump, | 49 | .dump = nft_reject_dump, |
50 | .validate = nft_reject_validate, | ||
50 | }; | 51 | }; |
51 | 52 | ||
52 | static struct nft_expr_type nft_reject_ipv6_type __read_mostly = { | 53 | static struct nft_expr_type nft_reject_ipv6_type __read_mostly = { |
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index 0900352c924c..0e983b694ee8 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c | |||
@@ -126,8 +126,10 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
126 | rt = (struct rt6_info *) dst; | 126 | rt = (struct rt6_info *) dst; |
127 | 127 | ||
128 | np = inet6_sk(sk); | 128 | np = inet6_sk(sk); |
129 | if (!np) | 129 | if (!np) { |
130 | return -EBADF; | 130 | err = -EBADF; |
131 | goto dst_err_out; | ||
132 | } | ||
131 | 133 | ||
132 | if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) | 134 | if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) |
133 | fl6.flowi6_oif = np->mcast_oif; | 135 | fl6.flowi6_oif = np->mcast_oif; |
@@ -163,6 +165,9 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
163 | } | 165 | } |
164 | release_sock(sk); | 166 | release_sock(sk); |
165 | 167 | ||
168 | dst_err_out: | ||
169 | dst_release(dst); | ||
170 | |||
166 | if (err) | 171 | if (err) |
167 | return err; | 172 | return err; |
168 | 173 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 49817555449e..e3a224b97905 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -1986,9 +1986,18 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg) | |||
1986 | if (!(gwa_type & IPV6_ADDR_UNICAST)) | 1986 | if (!(gwa_type & IPV6_ADDR_UNICAST)) |
1987 | goto out; | 1987 | goto out; |
1988 | 1988 | ||
1989 | if (cfg->fc_table) | 1989 | if (cfg->fc_table) { |
1990 | grt = ip6_nh_lookup_table(net, cfg, gw_addr); | 1990 | grt = ip6_nh_lookup_table(net, cfg, gw_addr); |
1991 | 1991 | ||
1992 | if (grt) { | ||
1993 | if (grt->rt6i_flags & RTF_GATEWAY || | ||
1994 | (dev && dev != grt->dst.dev)) { | ||
1995 | ip6_rt_put(grt); | ||
1996 | grt = NULL; | ||
1997 | } | ||
1998 | } | ||
1999 | } | ||
2000 | |||
1992 | if (!grt) | 2001 | if (!grt) |
1993 | grt = rt6_lookup(net, gw_addr, NULL, | 2002 | grt = rt6_lookup(net, gw_addr, NULL, |
1994 | cfg->fc_ifindex, 1); | 2003 | cfg->fc_ifindex, 1); |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 33df8b8575cc..94f4f89d73e7 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -944,9 +944,15 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, | |||
944 | /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV | 944 | /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV |
945 | * sk->sk_state == TCP_SYN_RECV -> for Fast Open. | 945 | * sk->sk_state == TCP_SYN_RECV -> for Fast Open. |
946 | */ | 946 | */ |
947 | /* RFC 7323 2.3 | ||
948 | * The window field (SEG.WND) of every outgoing segment, with the | ||
949 | * exception of <SYN> segments, MUST be right-shifted by | ||
950 | * Rcv.Wind.Shift bits: | ||
951 | */ | ||
947 | tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN) ? | 952 | tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN) ? |
948 | tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt, | 953 | tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt, |
949 | tcp_rsk(req)->rcv_nxt, req->rsk_rcv_wnd, | 954 | tcp_rsk(req)->rcv_nxt, |
955 | req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, | ||
950 | tcp_time_stamp, req->ts_recent, sk->sk_bound_dev_if, | 956 | tcp_time_stamp, req->ts_recent, sk->sk_bound_dev_if, |
951 | tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr), | 957 | tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr), |
952 | 0, 0); | 958 | 0, 0); |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 81e2f98b958d..19ac3a1c308d 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -1460,7 +1460,6 @@ struct proto udpv6_prot = { | |||
1460 | .sysctl_wmem = &sysctl_udp_wmem_min, | 1460 | .sysctl_wmem = &sysctl_udp_wmem_min, |
1461 | .sysctl_rmem = &sysctl_udp_rmem_min, | 1461 | .sysctl_rmem = &sysctl_udp_rmem_min, |
1462 | .obj_size = sizeof(struct udp6_sock), | 1462 | .obj_size = sizeof(struct udp6_sock), |
1463 | .slab_flags = SLAB_DESTROY_BY_RCU, | ||
1464 | .h.udp_table = &udp_table, | 1463 | .h.udp_table = &udp_table, |
1465 | #ifdef CONFIG_COMPAT | 1464 | #ifdef CONFIG_COMPAT |
1466 | .compat_setsockopt = compat_udpv6_setsockopt, | 1465 | .compat_setsockopt = compat_udpv6_setsockopt, |
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c index 9cf097e206e9..fd6ef414899b 100644 --- a/net/ipv6/udplite.c +++ b/net/ipv6/udplite.c | |||
@@ -50,7 +50,6 @@ struct proto udplitev6_prot = { | |||
50 | .unhash = udp_lib_unhash, | 50 | .unhash = udp_lib_unhash, |
51 | .get_port = udp_v6_get_port, | 51 | .get_port = udp_v6_get_port, |
52 | .obj_size = sizeof(struct udp6_sock), | 52 | .obj_size = sizeof(struct udp6_sock), |
53 | .slab_flags = SLAB_DESTROY_BY_RCU, | ||
54 | .h.udp_table = &udplite_table, | 53 | .h.udp_table = &udplite_table, |
55 | #ifdef CONFIG_COMPAT | 54 | #ifdef CONFIG_COMPAT |
56 | .compat_setsockopt = compat_udpv6_setsockopt, | 55 | .compat_setsockopt = compat_udpv6_setsockopt, |
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index 0eaab1fa6be5..b5789562aded 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c | |||
@@ -21,8 +21,10 @@ int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb) | |||
21 | return xfrm6_extract_header(skb); | 21 | return xfrm6_extract_header(skb); |
22 | } | 22 | } |
23 | 23 | ||
24 | int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) | 24 | int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi, |
25 | struct ip6_tnl *t) | ||
25 | { | 26 | { |
27 | XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t; | ||
26 | XFRM_SPI_SKB_CB(skb)->family = AF_INET6; | 28 | XFRM_SPI_SKB_CB(skb)->family = AF_INET6; |
27 | XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr); | 29 | XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr); |
28 | return xfrm_input(skb, nexthdr, spi, 0); | 30 | return xfrm_input(skb, nexthdr, spi, 0); |
@@ -48,13 +50,18 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async) | |||
48 | return -1; | 50 | return -1; |
49 | } | 51 | } |
50 | 52 | ||
51 | int xfrm6_rcv(struct sk_buff *skb) | 53 | int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t) |
52 | { | 54 | { |
53 | return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff], | 55 | return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff], |
54 | 0); | 56 | 0, t); |
55 | } | 57 | } |
56 | EXPORT_SYMBOL(xfrm6_rcv); | 58 | EXPORT_SYMBOL(xfrm6_rcv_tnl); |
57 | 59 | ||
60 | int xfrm6_rcv(struct sk_buff *skb) | ||
61 | { | ||
62 | return xfrm6_rcv_tnl(skb, NULL); | ||
63 | } | ||
64 | EXPORT_SYMBOL(xfrm6_rcv); | ||
58 | int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | 65 | int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, |
59 | xfrm_address_t *saddr, u8 proto) | 66 | xfrm_address_t *saddr, u8 proto) |
60 | { | 67 | { |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 6cc97003e4a9..70a86adad875 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -36,7 +36,7 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif, | |||
36 | int err; | 36 | int err; |
37 | 37 | ||
38 | memset(&fl6, 0, sizeof(fl6)); | 38 | memset(&fl6, 0, sizeof(fl6)); |
39 | fl6.flowi6_oif = oif; | 39 | fl6.flowi6_oif = l3mdev_master_ifindex_by_index(net, oif); |
40 | fl6.flowi6_flags = FLOWI_FLAG_SKIP_NH_OIF; | 40 | fl6.flowi6_flags = FLOWI_FLAG_SKIP_NH_OIF; |
41 | memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr)); | 41 | memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr)); |
42 | if (saddr) | 42 | if (saddr) |
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index 5743044cd660..e1c0bbe7996c 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c | |||
@@ -236,7 +236,7 @@ static int xfrm6_tunnel_rcv(struct sk_buff *skb) | |||
236 | __be32 spi; | 236 | __be32 spi; |
237 | 237 | ||
238 | spi = xfrm6_tunnel_spi_lookup(net, (const xfrm_address_t *)&iph->saddr); | 238 | spi = xfrm6_tunnel_spi_lookup(net, (const xfrm_address_t *)&iph->saddr); |
239 | return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi); | 239 | return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi, NULL); |
240 | } | 240 | } |
241 | 241 | ||
242 | static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | 242 | static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 8d2f7c9b491d..ccc244406fb9 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -832,7 +832,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
832 | struct sock *sk = sock->sk; | 832 | struct sock *sk = sock->sk; |
833 | struct irda_sock *new, *self = irda_sk(sk); | 833 | struct irda_sock *new, *self = irda_sk(sk); |
834 | struct sock *newsk; | 834 | struct sock *newsk; |
835 | struct sk_buff *skb; | 835 | struct sk_buff *skb = NULL; |
836 | int err; | 836 | int err; |
837 | 837 | ||
838 | err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0); | 838 | err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0); |
@@ -900,7 +900,6 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
900 | err = -EPERM; /* value does not seem to make sense. -arnd */ | 900 | err = -EPERM; /* value does not seem to make sense. -arnd */ |
901 | if (!new->tsap) { | 901 | if (!new->tsap) { |
902 | pr_debug("%s(), dup failed!\n", __func__); | 902 | pr_debug("%s(), dup failed!\n", __func__); |
903 | kfree_skb(skb); | ||
904 | goto out; | 903 | goto out; |
905 | } | 904 | } |
906 | 905 | ||
@@ -919,7 +918,6 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
919 | /* Clean up the original one to keep it in listen state */ | 918 | /* Clean up the original one to keep it in listen state */ |
920 | irttp_listen(self->tsap); | 919 | irttp_listen(self->tsap); |
921 | 920 | ||
922 | kfree_skb(skb); | ||
923 | sk->sk_ack_backlog--; | 921 | sk->sk_ack_backlog--; |
924 | 922 | ||
925 | newsock->state = SS_CONNECTED; | 923 | newsock->state = SS_CONNECTED; |
@@ -927,6 +925,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
927 | irda_connect_response(new); | 925 | irda_connect_response(new); |
928 | err = 0; | 926 | err = 0; |
929 | out: | 927 | out: |
928 | kfree_skb(skb); | ||
930 | release_sock(sk); | 929 | release_sock(sk); |
931 | return err; | 930 | return err; |
932 | } | 931 | } |
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c index cb39e05b166c..411693288648 100644 --- a/net/kcm/kcmsock.c +++ b/net/kcm/kcmsock.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/socket.h> | 13 | #include <linux/socket.h> |
14 | #include <linux/uaccess.h> | 14 | #include <linux/uaccess.h> |
15 | #include <linux/workqueue.h> | 15 | #include <linux/workqueue.h> |
16 | #include <linux/syscalls.h> | ||
16 | #include <net/kcm.h> | 17 | #include <net/kcm.h> |
17 | #include <net/netns/generic.h> | 18 | #include <net/netns/generic.h> |
18 | #include <net/sock.h> | 19 | #include <net/sock.h> |
@@ -2029,7 +2030,7 @@ static int kcm_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
2029 | if (copy_to_user((void __user *)arg, &info, | 2030 | if (copy_to_user((void __user *)arg, &info, |
2030 | sizeof(info))) { | 2031 | sizeof(info))) { |
2031 | err = -EFAULT; | 2032 | err = -EFAULT; |
2032 | sock_release(newsock); | 2033 | sys_close(info.fd); |
2033 | } | 2034 | } |
2034 | } | 2035 | } |
2035 | 2036 | ||
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 1e40dacaa137..a2ed3bda4ddc 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -1855,6 +1855,9 @@ static __net_exit void l2tp_exit_net(struct net *net) | |||
1855 | (void)l2tp_tunnel_delete(tunnel); | 1855 | (void)l2tp_tunnel_delete(tunnel); |
1856 | } | 1856 | } |
1857 | rcu_read_unlock_bh(); | 1857 | rcu_read_unlock_bh(); |
1858 | |||
1859 | flush_workqueue(l2tp_wq); | ||
1860 | rcu_barrier(); | ||
1858 | } | 1861 | } |
1859 | 1862 | ||
1860 | static struct pernet_operations l2tp_net_ops = { | 1863 | static struct pernet_operations l2tp_net_ops = { |
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index d9560aa2dba3..232cb92033e8 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c | |||
@@ -856,7 +856,7 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr, | |||
856 | error = -ENOTCONN; | 856 | error = -ENOTCONN; |
857 | if (sk == NULL) | 857 | if (sk == NULL) |
858 | goto end; | 858 | goto end; |
859 | if (sk->sk_state != PPPOX_CONNECTED) | 859 | if (!(sk->sk_state & PPPOX_CONNECTED)) |
860 | goto end; | 860 | goto end; |
861 | 861 | ||
862 | error = -EBADF; | 862 | error = -EBADF; |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index a9aff6079c42..afa94687d5e1 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -261,10 +261,16 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, | |||
261 | .timeout = timeout, | 261 | .timeout = timeout, |
262 | .ssn = start_seq_num, | 262 | .ssn = start_seq_num, |
263 | }; | 263 | }; |
264 | |||
265 | int i, ret = -EOPNOTSUPP; | 264 | int i, ret = -EOPNOTSUPP; |
266 | u16 status = WLAN_STATUS_REQUEST_DECLINED; | 265 | u16 status = WLAN_STATUS_REQUEST_DECLINED; |
267 | 266 | ||
267 | if (tid >= IEEE80211_FIRST_TSPEC_TSID) { | ||
268 | ht_dbg(sta->sdata, | ||
269 | "STA %pM requests BA session on unsupported tid %d\n", | ||
270 | sta->sta.addr, tid); | ||
271 | goto end_no_lock; | ||
272 | } | ||
273 | |||
268 | if (!sta->sta.ht_cap.ht_supported) { | 274 | if (!sta->sta.ht_cap.ht_supported) { |
269 | ht_dbg(sta->sdata, | 275 | ht_dbg(sta->sdata, |
270 | "STA %pM erroneously requests BA session on tid %d w/o QoS\n", | 276 | "STA %pM erroneously requests BA session on tid %d w/o QoS\n", |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 5650c46bf91a..45319cc01121 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -584,6 +584,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
584 | ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW)) | 584 | ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW)) |
585 | return -EINVAL; | 585 | return -EINVAL; |
586 | 586 | ||
587 | if (WARN_ON(tid >= IEEE80211_FIRST_TSPEC_TSID)) | ||
588 | return -EINVAL; | ||
589 | |||
587 | ht_dbg(sdata, "Open BA session requested for %pM tid %u\n", | 590 | ht_dbg(sdata, "Open BA session requested for %pM tid %u\n", |
588 | pubsta->addr, tid); | 591 | pubsta->addr, tid); |
589 | 592 | ||
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 8f9c3bde835f..faccef977670 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -746,6 +746,7 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata, | |||
746 | sta = next_hop_deref_protected(mpath); | 746 | sta = next_hop_deref_protected(mpath); |
747 | if (mpath->flags & MESH_PATH_ACTIVE && | 747 | if (mpath->flags & MESH_PATH_ACTIVE && |
748 | ether_addr_equal(ta, sta->sta.addr) && | 748 | ether_addr_equal(ta, sta->sta.addr) && |
749 | !(mpath->flags & MESH_PATH_FIXED) && | ||
749 | (!(mpath->flags & MESH_PATH_SN_VALID) || | 750 | (!(mpath->flags & MESH_PATH_SN_VALID) || |
750 | SN_GT(target_sn, mpath->sn) || target_sn == 0)) { | 751 | SN_GT(target_sn, mpath->sn) || target_sn == 0)) { |
751 | mpath->flags &= ~MESH_PATH_ACTIVE; | 752 | mpath->flags &= ~MESH_PATH_ACTIVE; |
@@ -1012,7 +1013,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) | |||
1012 | goto enddiscovery; | 1013 | goto enddiscovery; |
1013 | 1014 | ||
1014 | spin_lock_bh(&mpath->state_lock); | 1015 | spin_lock_bh(&mpath->state_lock); |
1015 | if (mpath->flags & MESH_PATH_DELETED) { | 1016 | if (mpath->flags & (MESH_PATH_DELETED | MESH_PATH_FIXED)) { |
1016 | spin_unlock_bh(&mpath->state_lock); | 1017 | spin_unlock_bh(&mpath->state_lock); |
1017 | goto enddiscovery; | 1018 | goto enddiscovery; |
1018 | } | 1019 | } |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 6db2ddfa0695..f0e6175a9821 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -826,7 +826,7 @@ void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop) | |||
826 | mpath->metric = 0; | 826 | mpath->metric = 0; |
827 | mpath->hop_count = 0; | 827 | mpath->hop_count = 0; |
828 | mpath->exp_time = 0; | 828 | mpath->exp_time = 0; |
829 | mpath->flags |= MESH_PATH_FIXED; | 829 | mpath->flags = MESH_PATH_FIXED | MESH_PATH_SN_VALID; |
830 | mesh_path_activate(mpath); | 830 | mesh_path_activate(mpath); |
831 | spin_unlock_bh(&mpath->state_lock); | 831 | spin_unlock_bh(&mpath->state_lock); |
832 | mesh_path_tx_pending(mpath); | 832 | mesh_path_tx_pending(mpath); |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 76b737dcc36f..aa58df80ede0 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -1616,7 +1616,6 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | |||
1616 | 1616 | ||
1617 | sta_info_recalc_tim(sta); | 1617 | sta_info_recalc_tim(sta); |
1618 | } else { | 1618 | } else { |
1619 | unsigned long tids = sta->txq_buffered_tids & driver_release_tids; | ||
1620 | int tid; | 1619 | int tid; |
1621 | 1620 | ||
1622 | /* | 1621 | /* |
@@ -1648,7 +1647,8 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | |||
1648 | for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) { | 1647 | for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) { |
1649 | struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]); | 1648 | struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]); |
1650 | 1649 | ||
1651 | if (!(tids & BIT(tid)) || txqi->tin.backlog_packets) | 1650 | if (!(driver_release_tids & BIT(tid)) || |
1651 | txqi->tin.backlog_packets) | ||
1652 | continue; | 1652 | continue; |
1653 | 1653 | ||
1654 | sta_info_recalc_tim(sta); | 1654 | sta_info_recalc_tim(sta); |
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index b5d28f14b9cf..afca7d103684 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c | |||
@@ -333,10 +333,11 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata, | |||
333 | if (!uc.center_freq1) | 333 | if (!uc.center_freq1) |
334 | return; | 334 | return; |
335 | 335 | ||
336 | /* proceed to downgrade the chandef until usable or the same */ | 336 | /* proceed to downgrade the chandef until usable or the same as AP BW */ |
337 | while (uc.width > max_width || | 337 | while (uc.width > max_width || |
338 | !cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &uc, | 338 | (uc.width > sta->tdls_chandef.width && |
339 | sdata->wdev.iftype)) | 339 | !cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &uc, |
340 | sdata->wdev.iftype))) | ||
340 | ieee80211_chandef_downgrade(&uc); | 341 | ieee80211_chandef_downgrade(&uc); |
341 | 342 | ||
342 | if (!cfg80211_chandef_identical(&uc, &sta->tdls_chandef)) { | 343 | if (!cfg80211_chandef_identical(&uc, &sta->tdls_chandef)) { |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 502396694f47..18b285e06bc8 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -796,6 +796,36 @@ static __le16 ieee80211_tx_next_seq(struct sta_info *sta, int tid) | |||
796 | return ret; | 796 | return ret; |
797 | } | 797 | } |
798 | 798 | ||
799 | static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local, | ||
800 | struct ieee80211_vif *vif, | ||
801 | struct ieee80211_sta *pubsta, | ||
802 | struct sk_buff *skb) | ||
803 | { | ||
804 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
805 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
806 | struct ieee80211_txq *txq = NULL; | ||
807 | |||
808 | if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) || | ||
809 | (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE)) | ||
810 | return NULL; | ||
811 | |||
812 | if (!ieee80211_is_data(hdr->frame_control)) | ||
813 | return NULL; | ||
814 | |||
815 | if (pubsta) { | ||
816 | u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; | ||
817 | |||
818 | txq = pubsta->txq[tid]; | ||
819 | } else if (vif) { | ||
820 | txq = vif->txq; | ||
821 | } | ||
822 | |||
823 | if (!txq) | ||
824 | return NULL; | ||
825 | |||
826 | return to_txq_info(txq); | ||
827 | } | ||
828 | |||
799 | static ieee80211_tx_result debug_noinline | 829 | static ieee80211_tx_result debug_noinline |
800 | ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | 830 | ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) |
801 | { | 831 | { |
@@ -853,7 +883,8 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | |||
853 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; | 883 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; |
854 | tx->sta->tx_stats.msdu[tid]++; | 884 | tx->sta->tx_stats.msdu[tid]++; |
855 | 885 | ||
856 | if (!tx->sta->sta.txq[0]) | 886 | if (!ieee80211_get_txq(tx->local, info->control.vif, &tx->sta->sta, |
887 | tx->skb)) | ||
857 | hdr->seq_ctrl = ieee80211_tx_next_seq(tx->sta, tid); | 888 | hdr->seq_ctrl = ieee80211_tx_next_seq(tx->sta, tid); |
858 | 889 | ||
859 | return TX_CONTINUE; | 890 | return TX_CONTINUE; |
@@ -1243,36 +1274,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1243 | return TX_CONTINUE; | 1274 | return TX_CONTINUE; |
1244 | } | 1275 | } |
1245 | 1276 | ||
1246 | static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local, | ||
1247 | struct ieee80211_vif *vif, | ||
1248 | struct ieee80211_sta *pubsta, | ||
1249 | struct sk_buff *skb) | ||
1250 | { | ||
1251 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
1252 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1253 | struct ieee80211_txq *txq = NULL; | ||
1254 | |||
1255 | if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) || | ||
1256 | (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE)) | ||
1257 | return NULL; | ||
1258 | |||
1259 | if (!ieee80211_is_data(hdr->frame_control)) | ||
1260 | return NULL; | ||
1261 | |||
1262 | if (pubsta) { | ||
1263 | u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; | ||
1264 | |||
1265 | txq = pubsta->txq[tid]; | ||
1266 | } else if (vif) { | ||
1267 | txq = vif->txq; | ||
1268 | } | ||
1269 | |||
1270 | if (!txq) | ||
1271 | return NULL; | ||
1272 | |||
1273 | return to_txq_info(txq); | ||
1274 | } | ||
1275 | |||
1276 | static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb) | 1277 | static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb) |
1277 | { | 1278 | { |
1278 | IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time(); | 1279 | IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time(); |
@@ -1514,8 +1515,12 @@ out: | |||
1514 | spin_unlock_bh(&fq->lock); | 1515 | spin_unlock_bh(&fq->lock); |
1515 | 1516 | ||
1516 | if (skb && skb_has_frag_list(skb) && | 1517 | if (skb && skb_has_frag_list(skb) && |
1517 | !ieee80211_hw_check(&local->hw, TX_FRAG_LIST)) | 1518 | !ieee80211_hw_check(&local->hw, TX_FRAG_LIST)) { |
1518 | skb_linearize(skb); | 1519 | if (skb_linearize(skb)) { |
1520 | ieee80211_free_txskb(&local->hw, skb); | ||
1521 | return NULL; | ||
1522 | } | ||
1523 | } | ||
1519 | 1524 | ||
1520 | return skb; | 1525 | return skb; |
1521 | } | 1526 | } |
@@ -3264,7 +3269,7 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, | |||
3264 | 3269 | ||
3265 | if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { | 3270 | if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { |
3266 | *ieee80211_get_qos_ctl(hdr) = tid; | 3271 | *ieee80211_get_qos_ctl(hdr) = tid; |
3267 | if (!sta->sta.txq[0]) | 3272 | if (!ieee80211_get_txq(local, &sdata->vif, &sta->sta, skb)) |
3268 | hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid); | 3273 | hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid); |
3269 | } else { | 3274 | } else { |
3270 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | 3275 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index dd2c43abf9e2..9934b0c93c1e 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -1035,9 +1035,9 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, | |||
1035 | if (IS_ERR(ct)) | 1035 | if (IS_ERR(ct)) |
1036 | return (struct nf_conntrack_tuple_hash *)ct; | 1036 | return (struct nf_conntrack_tuple_hash *)ct; |
1037 | 1037 | ||
1038 | if (tmpl && nfct_synproxy(tmpl)) { | 1038 | if (!nf_ct_add_synproxy(ct, tmpl)) { |
1039 | nfct_seqadj_ext_add(ct); | 1039 | nf_conntrack_free(ct); |
1040 | nfct_synproxy_ext_add(ct); | 1040 | return ERR_PTR(-ENOMEM); |
1041 | } | 1041 | } |
1042 | 1042 | ||
1043 | timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL; | 1043 | timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL; |
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 958a1455ca7f..9f267c3ffb39 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c | |||
@@ -205,6 +205,7 @@ static int ct_seq_show(struct seq_file *s, void *v) | |||
205 | struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash); | 205 | struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash); |
206 | const struct nf_conntrack_l3proto *l3proto; | 206 | const struct nf_conntrack_l3proto *l3proto; |
207 | const struct nf_conntrack_l4proto *l4proto; | 207 | const struct nf_conntrack_l4proto *l4proto; |
208 | struct net *net = seq_file_net(s); | ||
208 | int ret = 0; | 209 | int ret = 0; |
209 | 210 | ||
210 | NF_CT_ASSERT(ct); | 211 | NF_CT_ASSERT(ct); |
@@ -215,6 +216,9 @@ static int ct_seq_show(struct seq_file *s, void *v) | |||
215 | if (NF_CT_DIRECTION(hash)) | 216 | if (NF_CT_DIRECTION(hash)) |
216 | goto release; | 217 | goto release; |
217 | 218 | ||
219 | if (!net_eq(nf_ct_net(ct), net)) | ||
220 | goto release; | ||
221 | |||
218 | l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct)); | 222 | l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct)); |
219 | NF_CT_ASSERT(l3proto); | 223 | NF_CT_ASSERT(l3proto); |
220 | l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct)); | 224 | l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct)); |
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c index de31818417b8..ecee105bbada 100644 --- a/net/netfilter/nf_nat_core.c +++ b/net/netfilter/nf_nat_core.c | |||
@@ -441,7 +441,8 @@ nf_nat_setup_info(struct nf_conn *ct, | |||
441 | ct->status |= IPS_DST_NAT; | 441 | ct->status |= IPS_DST_NAT; |
442 | 442 | ||
443 | if (nfct_help(ct)) | 443 | if (nfct_help(ct)) |
444 | nfct_seqadj_ext_add(ct); | 444 | if (!nfct_seqadj_ext_add(ct)) |
445 | return NF_DROP; | ||
445 | } | 446 | } |
446 | 447 | ||
447 | if (maniptype == NF_NAT_MANIP_SRC) { | 448 | if (maniptype == NF_NAT_MANIP_SRC) { |
@@ -807,7 +808,7 @@ nfnetlink_parse_nat_setup(struct nf_conn *ct, | |||
807 | if (err < 0) | 808 | if (err < 0) |
808 | return err; | 809 | return err; |
809 | 810 | ||
810 | return nf_nat_setup_info(ct, &range, manip); | 811 | return nf_nat_setup_info(ct, &range, manip) == NF_DROP ? -ENOMEM : 0; |
811 | } | 812 | } |
812 | #else | 813 | #else |
813 | static int | 814 | static int |
diff --git a/net/netfilter/nf_tables_netdev.c b/net/netfilter/nf_tables_netdev.c index 5eefe4a355c6..75d696f11045 100644 --- a/net/netfilter/nf_tables_netdev.c +++ b/net/netfilter/nf_tables_netdev.c | |||
@@ -30,7 +30,6 @@ nft_netdev_set_pktinfo_ipv4(struct nft_pktinfo *pkt, | |||
30 | if (!iph) | 30 | if (!iph) |
31 | return; | 31 | return; |
32 | 32 | ||
33 | iph = ip_hdr(skb); | ||
34 | if (iph->ihl < 5 || iph->version != 4) | 33 | if (iph->ihl < 5 || iph->version != 4) |
35 | return; | 34 | return; |
36 | 35 | ||
diff --git a/net/netfilter/nf_tables_trace.c b/net/netfilter/nf_tables_trace.c index 39eb1cc62e91..fa24a5b398b1 100644 --- a/net/netfilter/nf_tables_trace.c +++ b/net/netfilter/nf_tables_trace.c | |||
@@ -237,7 +237,7 @@ void nft_trace_notify(struct nft_traceinfo *info) | |||
237 | break; | 237 | break; |
238 | case NFT_TRACETYPE_POLICY: | 238 | case NFT_TRACETYPE_POLICY: |
239 | if (nla_put_be32(skb, NFTA_TRACE_POLICY, | 239 | if (nla_put_be32(skb, NFTA_TRACE_POLICY, |
240 | info->basechain->policy)) | 240 | htonl(info->basechain->policy))) |
241 | goto nla_put_failure; | 241 | goto nla_put_failure; |
242 | break; | 242 | break; |
243 | } | 243 | } |
diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c index 1b4de4bd6958..d44d89b56127 100644 --- a/net/netfilter/nfnetlink_acct.c +++ b/net/netfilter/nfnetlink_acct.c | |||
@@ -326,14 +326,14 @@ static int nfnl_acct_try_del(struct nf_acct *cur) | |||
326 | { | 326 | { |
327 | int ret = 0; | 327 | int ret = 0; |
328 | 328 | ||
329 | /* we want to avoid races with nfnl_acct_find_get. */ | 329 | /* We want to avoid races with nfnl_acct_put. So only when the current |
330 | if (atomic_dec_and_test(&cur->refcnt)) { | 330 | * refcnt is 1, we decrease it to 0. |
331 | */ | ||
332 | if (atomic_cmpxchg(&cur->refcnt, 1, 0) == 1) { | ||
331 | /* We are protected by nfnl mutex. */ | 333 | /* We are protected by nfnl mutex. */ |
332 | list_del_rcu(&cur->head); | 334 | list_del_rcu(&cur->head); |
333 | kfree_rcu(cur, rcu_head); | 335 | kfree_rcu(cur, rcu_head); |
334 | } else { | 336 | } else { |
335 | /* still in use, restore reference counter. */ | ||
336 | atomic_inc(&cur->refcnt); | ||
337 | ret = -EBUSY; | 337 | ret = -EBUSY; |
338 | } | 338 | } |
339 | return ret; | 339 | return ret; |
@@ -343,12 +343,12 @@ static int nfnl_acct_del(struct net *net, struct sock *nfnl, | |||
343 | struct sk_buff *skb, const struct nlmsghdr *nlh, | 343 | struct sk_buff *skb, const struct nlmsghdr *nlh, |
344 | const struct nlattr * const tb[]) | 344 | const struct nlattr * const tb[]) |
345 | { | 345 | { |
346 | char *acct_name; | 346 | struct nf_acct *cur, *tmp; |
347 | struct nf_acct *cur; | ||
348 | int ret = -ENOENT; | 347 | int ret = -ENOENT; |
348 | char *acct_name; | ||
349 | 349 | ||
350 | if (!tb[NFACCT_NAME]) { | 350 | if (!tb[NFACCT_NAME]) { |
351 | list_for_each_entry(cur, &net->nfnl_acct_list, head) | 351 | list_for_each_entry_safe(cur, tmp, &net->nfnl_acct_list, head) |
352 | nfnl_acct_try_del(cur); | 352 | nfnl_acct_try_del(cur); |
353 | 353 | ||
354 | return 0; | 354 | return 0; |
@@ -443,7 +443,7 @@ void nfnl_acct_update(const struct sk_buff *skb, struct nf_acct *nfacct) | |||
443 | } | 443 | } |
444 | EXPORT_SYMBOL_GPL(nfnl_acct_update); | 444 | EXPORT_SYMBOL_GPL(nfnl_acct_update); |
445 | 445 | ||
446 | static void nfnl_overquota_report(struct nf_acct *nfacct) | 446 | static void nfnl_overquota_report(struct net *net, struct nf_acct *nfacct) |
447 | { | 447 | { |
448 | int ret; | 448 | int ret; |
449 | struct sk_buff *skb; | 449 | struct sk_buff *skb; |
@@ -458,11 +458,12 @@ static void nfnl_overquota_report(struct nf_acct *nfacct) | |||
458 | kfree_skb(skb); | 458 | kfree_skb(skb); |
459 | return; | 459 | return; |
460 | } | 460 | } |
461 | netlink_broadcast(init_net.nfnl, skb, 0, NFNLGRP_ACCT_QUOTA, | 461 | netlink_broadcast(net->nfnl, skb, 0, NFNLGRP_ACCT_QUOTA, |
462 | GFP_ATOMIC); | 462 | GFP_ATOMIC); |
463 | } | 463 | } |
464 | 464 | ||
465 | int nfnl_acct_overquota(const struct sk_buff *skb, struct nf_acct *nfacct) | 465 | int nfnl_acct_overquota(struct net *net, const struct sk_buff *skb, |
466 | struct nf_acct *nfacct) | ||
466 | { | 467 | { |
467 | u64 now; | 468 | u64 now; |
468 | u64 *quota; | 469 | u64 *quota; |
@@ -480,7 +481,7 @@ int nfnl_acct_overquota(const struct sk_buff *skb, struct nf_acct *nfacct) | |||
480 | 481 | ||
481 | if (now >= *quota && | 482 | if (now >= *quota && |
482 | !test_and_set_bit(NFACCT_OVERQUOTA_BIT, &nfacct->flags)) { | 483 | !test_and_set_bit(NFACCT_OVERQUOTA_BIT, &nfacct->flags)) { |
483 | nfnl_overquota_report(nfacct); | 484 | nfnl_overquota_report(net, nfacct); |
484 | } | 485 | } |
485 | 486 | ||
486 | return ret; | 487 | return ret; |
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c index 4cdcd969b64c..139e0867e56e 100644 --- a/net/netfilter/nfnetlink_cttimeout.c +++ b/net/netfilter/nfnetlink_cttimeout.c | |||
@@ -98,31 +98,28 @@ static int cttimeout_new_timeout(struct net *net, struct sock *ctnl, | |||
98 | break; | 98 | break; |
99 | } | 99 | } |
100 | 100 | ||
101 | l4proto = nf_ct_l4proto_find_get(l3num, l4num); | ||
102 | |||
103 | /* This protocol is not supportted, skip. */ | ||
104 | if (l4proto->l4proto != l4num) { | ||
105 | ret = -EOPNOTSUPP; | ||
106 | goto err_proto_put; | ||
107 | } | ||
108 | |||
109 | if (matching) { | 101 | if (matching) { |
110 | if (nlh->nlmsg_flags & NLM_F_REPLACE) { | 102 | if (nlh->nlmsg_flags & NLM_F_REPLACE) { |
111 | /* You cannot replace one timeout policy by another of | 103 | /* You cannot replace one timeout policy by another of |
112 | * different kind, sorry. | 104 | * different kind, sorry. |
113 | */ | 105 | */ |
114 | if (matching->l3num != l3num || | 106 | if (matching->l3num != l3num || |
115 | matching->l4proto->l4proto != l4num) { | 107 | matching->l4proto->l4proto != l4num) |
116 | ret = -EINVAL; | 108 | return -EINVAL; |
117 | goto err_proto_put; | 109 | |
118 | } | 110 | return ctnl_timeout_parse_policy(&matching->data, |
119 | 111 | matching->l4proto, net, | |
120 | ret = ctnl_timeout_parse_policy(&matching->data, | 112 | cda[CTA_TIMEOUT_DATA]); |
121 | l4proto, net, | ||
122 | cda[CTA_TIMEOUT_DATA]); | ||
123 | return ret; | ||
124 | } | 113 | } |
125 | ret = -EBUSY; | 114 | |
115 | return -EBUSY; | ||
116 | } | ||
117 | |||
118 | l4proto = nf_ct_l4proto_find_get(l3num, l4num); | ||
119 | |||
120 | /* This protocol is not supportted, skip. */ | ||
121 | if (l4proto->l4proto != l4num) { | ||
122 | ret = -EOPNOTSUPP; | ||
126 | goto err_proto_put; | 123 | goto err_proto_put; |
127 | } | 124 | } |
128 | 125 | ||
@@ -305,7 +302,16 @@ static void ctnl_untimeout(struct net *net, struct ctnl_timeout *timeout) | |||
305 | const struct hlist_nulls_node *nn; | 302 | const struct hlist_nulls_node *nn; |
306 | unsigned int last_hsize; | 303 | unsigned int last_hsize; |
307 | spinlock_t *lock; | 304 | spinlock_t *lock; |
308 | int i; | 305 | int i, cpu; |
306 | |||
307 | for_each_possible_cpu(cpu) { | ||
308 | struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu); | ||
309 | |||
310 | spin_lock_bh(&pcpu->lock); | ||
311 | hlist_nulls_for_each_entry(h, nn, &pcpu->unconfirmed, hnnode) | ||
312 | untimeout(h, timeout); | ||
313 | spin_unlock_bh(&pcpu->lock); | ||
314 | } | ||
309 | 315 | ||
310 | local_bh_disable(); | 316 | local_bh_disable(); |
311 | restart: | 317 | restart: |
@@ -330,16 +336,16 @@ static int ctnl_timeout_try_del(struct net *net, struct ctnl_timeout *timeout) | |||
330 | { | 336 | { |
331 | int ret = 0; | 337 | int ret = 0; |
332 | 338 | ||
333 | /* we want to avoid races with nf_ct_timeout_find_get. */ | 339 | /* We want to avoid races with ctnl_timeout_put. So only when the |
334 | if (atomic_dec_and_test(&timeout->refcnt)) { | 340 | * current refcnt is 1, we decrease it to 0. |
341 | */ | ||
342 | if (atomic_cmpxchg(&timeout->refcnt, 1, 0) == 1) { | ||
335 | /* We are protected by nfnl mutex. */ | 343 | /* We are protected by nfnl mutex. */ |
336 | list_del_rcu(&timeout->head); | 344 | list_del_rcu(&timeout->head); |
337 | nf_ct_l4proto_put(timeout->l4proto); | 345 | nf_ct_l4proto_put(timeout->l4proto); |
338 | ctnl_untimeout(net, timeout); | 346 | ctnl_untimeout(net, timeout); |
339 | kfree_rcu(timeout, rcu_head); | 347 | kfree_rcu(timeout, rcu_head); |
340 | } else { | 348 | } else { |
341 | /* still in use, restore reference counter. */ | ||
342 | atomic_inc(&timeout->refcnt); | ||
343 | ret = -EBUSY; | 349 | ret = -EBUSY; |
344 | } | 350 | } |
345 | return ret; | 351 | return ret; |
@@ -350,12 +356,13 @@ static int cttimeout_del_timeout(struct net *net, struct sock *ctnl, | |||
350 | const struct nlmsghdr *nlh, | 356 | const struct nlmsghdr *nlh, |
351 | const struct nlattr * const cda[]) | 357 | const struct nlattr * const cda[]) |
352 | { | 358 | { |
353 | struct ctnl_timeout *cur; | 359 | struct ctnl_timeout *cur, *tmp; |
354 | int ret = -ENOENT; | 360 | int ret = -ENOENT; |
355 | char *name; | 361 | char *name; |
356 | 362 | ||
357 | if (!cda[CTA_TIMEOUT_NAME]) { | 363 | if (!cda[CTA_TIMEOUT_NAME]) { |
358 | list_for_each_entry(cur, &net->nfct_timeout_list, head) | 364 | list_for_each_entry_safe(cur, tmp, &net->nfct_timeout_list, |
365 | head) | ||
359 | ctnl_timeout_try_del(net, cur); | 366 | ctnl_timeout_try_del(net, cur); |
360 | 367 | ||
361 | return 0; | 368 | return 0; |
@@ -543,7 +550,9 @@ err: | |||
543 | 550 | ||
544 | static void ctnl_timeout_put(struct ctnl_timeout *timeout) | 551 | static void ctnl_timeout_put(struct ctnl_timeout *timeout) |
545 | { | 552 | { |
546 | atomic_dec(&timeout->refcnt); | 553 | if (atomic_dec_and_test(&timeout->refcnt)) |
554 | kfree_rcu(timeout, rcu_head); | ||
555 | |||
547 | module_put(THIS_MODULE); | 556 | module_put(THIS_MODULE); |
548 | } | 557 | } |
549 | #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ | 558 | #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ |
@@ -591,7 +600,9 @@ static void __net_exit cttimeout_net_exit(struct net *net) | |||
591 | list_for_each_entry_safe(cur, tmp, &net->nfct_timeout_list, head) { | 600 | list_for_each_entry_safe(cur, tmp, &net->nfct_timeout_list, head) { |
592 | list_del_rcu(&cur->head); | 601 | list_del_rcu(&cur->head); |
593 | nf_ct_l4proto_put(cur->l4proto); | 602 | nf_ct_l4proto_put(cur->l4proto); |
594 | kfree_rcu(cur, rcu_head); | 603 | |
604 | if (atomic_dec_and_test(&cur->refcnt)) | ||
605 | kfree_rcu(cur, rcu_head); | ||
595 | } | 606 | } |
596 | } | 607 | } |
597 | 608 | ||
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index cbcfdfb586a6..6577db524ef6 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -1147,6 +1147,7 @@ MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_ULOG); | |||
1147 | MODULE_ALIAS_NF_LOGGER(AF_INET, 1); | 1147 | MODULE_ALIAS_NF_LOGGER(AF_INET, 1); |
1148 | MODULE_ALIAS_NF_LOGGER(AF_INET6, 1); | 1148 | MODULE_ALIAS_NF_LOGGER(AF_INET6, 1); |
1149 | MODULE_ALIAS_NF_LOGGER(AF_BRIDGE, 1); | 1149 | MODULE_ALIAS_NF_LOGGER(AF_BRIDGE, 1); |
1150 | MODULE_ALIAS_NF_LOGGER(3, 1); /* NFPROTO_ARP */ | ||
1150 | 1151 | ||
1151 | module_init(nfnetlink_log_init); | 1152 | module_init(nfnetlink_log_init); |
1152 | module_exit(nfnetlink_log_fini); | 1153 | module_exit(nfnetlink_log_fini); |
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index 2863f3493038..8a6bc7630912 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c | |||
@@ -291,10 +291,16 @@ int nft_meta_get_init(const struct nft_ctx *ctx, | |||
291 | } | 291 | } |
292 | EXPORT_SYMBOL_GPL(nft_meta_get_init); | 292 | EXPORT_SYMBOL_GPL(nft_meta_get_init); |
293 | 293 | ||
294 | static int nft_meta_set_init_pkttype(const struct nft_ctx *ctx) | 294 | int nft_meta_set_validate(const struct nft_ctx *ctx, |
295 | const struct nft_expr *expr, | ||
296 | const struct nft_data **data) | ||
295 | { | 297 | { |
298 | struct nft_meta *priv = nft_expr_priv(expr); | ||
296 | unsigned int hooks; | 299 | unsigned int hooks; |
297 | 300 | ||
301 | if (priv->key != NFT_META_PKTTYPE) | ||
302 | return 0; | ||
303 | |||
298 | switch (ctx->afi->family) { | 304 | switch (ctx->afi->family) { |
299 | case NFPROTO_BRIDGE: | 305 | case NFPROTO_BRIDGE: |
300 | hooks = 1 << NF_BR_PRE_ROUTING; | 306 | hooks = 1 << NF_BR_PRE_ROUTING; |
@@ -308,6 +314,7 @@ static int nft_meta_set_init_pkttype(const struct nft_ctx *ctx) | |||
308 | 314 | ||
309 | return nft_chain_validate_hooks(ctx->chain, hooks); | 315 | return nft_chain_validate_hooks(ctx->chain, hooks); |
310 | } | 316 | } |
317 | EXPORT_SYMBOL_GPL(nft_meta_set_validate); | ||
311 | 318 | ||
312 | int nft_meta_set_init(const struct nft_ctx *ctx, | 319 | int nft_meta_set_init(const struct nft_ctx *ctx, |
313 | const struct nft_expr *expr, | 320 | const struct nft_expr *expr, |
@@ -327,15 +334,16 @@ int nft_meta_set_init(const struct nft_ctx *ctx, | |||
327 | len = sizeof(u8); | 334 | len = sizeof(u8); |
328 | break; | 335 | break; |
329 | case NFT_META_PKTTYPE: | 336 | case NFT_META_PKTTYPE: |
330 | err = nft_meta_set_init_pkttype(ctx); | ||
331 | if (err) | ||
332 | return err; | ||
333 | len = sizeof(u8); | 337 | len = sizeof(u8); |
334 | break; | 338 | break; |
335 | default: | 339 | default: |
336 | return -EOPNOTSUPP; | 340 | return -EOPNOTSUPP; |
337 | } | 341 | } |
338 | 342 | ||
343 | err = nft_meta_set_validate(ctx, expr, NULL); | ||
344 | if (err < 0) | ||
345 | return err; | ||
346 | |||
339 | priv->sreg = nft_parse_register(tb[NFTA_META_SREG]); | 347 | priv->sreg = nft_parse_register(tb[NFTA_META_SREG]); |
340 | err = nft_validate_register_load(priv->sreg, len); | 348 | err = nft_validate_register_load(priv->sreg, len); |
341 | if (err < 0) | 349 | if (err < 0) |
@@ -407,6 +415,7 @@ static const struct nft_expr_ops nft_meta_set_ops = { | |||
407 | .init = nft_meta_set_init, | 415 | .init = nft_meta_set_init, |
408 | .destroy = nft_meta_set_destroy, | 416 | .destroy = nft_meta_set_destroy, |
409 | .dump = nft_meta_set_dump, | 417 | .dump = nft_meta_set_dump, |
418 | .validate = nft_meta_set_validate, | ||
410 | }; | 419 | }; |
411 | 420 | ||
412 | static const struct nft_expr_ops * | 421 | static const struct nft_expr_ops * |
diff --git a/net/netfilter/nft_reject.c b/net/netfilter/nft_reject.c index 0522fc9bfb0a..c64de3f7379d 100644 --- a/net/netfilter/nft_reject.c +++ b/net/netfilter/nft_reject.c | |||
@@ -26,11 +26,27 @@ const struct nla_policy nft_reject_policy[NFTA_REJECT_MAX + 1] = { | |||
26 | }; | 26 | }; |
27 | EXPORT_SYMBOL_GPL(nft_reject_policy); | 27 | EXPORT_SYMBOL_GPL(nft_reject_policy); |
28 | 28 | ||
29 | int nft_reject_validate(const struct nft_ctx *ctx, | ||
30 | const struct nft_expr *expr, | ||
31 | const struct nft_data **data) | ||
32 | { | ||
33 | return nft_chain_validate_hooks(ctx->chain, | ||
34 | (1 << NF_INET_LOCAL_IN) | | ||
35 | (1 << NF_INET_FORWARD) | | ||
36 | (1 << NF_INET_LOCAL_OUT)); | ||
37 | } | ||
38 | EXPORT_SYMBOL_GPL(nft_reject_validate); | ||
39 | |||
29 | int nft_reject_init(const struct nft_ctx *ctx, | 40 | int nft_reject_init(const struct nft_ctx *ctx, |
30 | const struct nft_expr *expr, | 41 | const struct nft_expr *expr, |
31 | const struct nlattr * const tb[]) | 42 | const struct nlattr * const tb[]) |
32 | { | 43 | { |
33 | struct nft_reject *priv = nft_expr_priv(expr); | 44 | struct nft_reject *priv = nft_expr_priv(expr); |
45 | int err; | ||
46 | |||
47 | err = nft_reject_validate(ctx, expr, NULL); | ||
48 | if (err < 0) | ||
49 | return err; | ||
34 | 50 | ||
35 | if (tb[NFTA_REJECT_TYPE] == NULL) | 51 | if (tb[NFTA_REJECT_TYPE] == NULL) |
36 | return -EINVAL; | 52 | return -EINVAL; |
diff --git a/net/netfilter/nft_reject_inet.c b/net/netfilter/nft_reject_inet.c index 759ca5248a3d..e79d9ca2ffee 100644 --- a/net/netfilter/nft_reject_inet.c +++ b/net/netfilter/nft_reject_inet.c | |||
@@ -66,7 +66,11 @@ static int nft_reject_inet_init(const struct nft_ctx *ctx, | |||
66 | const struct nlattr * const tb[]) | 66 | const struct nlattr * const tb[]) |
67 | { | 67 | { |
68 | struct nft_reject *priv = nft_expr_priv(expr); | 68 | struct nft_reject *priv = nft_expr_priv(expr); |
69 | int icmp_code; | 69 | int icmp_code, err; |
70 | |||
71 | err = nft_reject_validate(ctx, expr, NULL); | ||
72 | if (err < 0) | ||
73 | return err; | ||
70 | 74 | ||
71 | if (tb[NFTA_REJECT_TYPE] == NULL) | 75 | if (tb[NFTA_REJECT_TYPE] == NULL) |
72 | return -EINVAL; | 76 | return -EINVAL; |
@@ -124,6 +128,7 @@ static const struct nft_expr_ops nft_reject_inet_ops = { | |||
124 | .eval = nft_reject_inet_eval, | 128 | .eval = nft_reject_inet_eval, |
125 | .init = nft_reject_inet_init, | 129 | .init = nft_reject_inet_init, |
126 | .dump = nft_reject_inet_dump, | 130 | .dump = nft_reject_inet_dump, |
131 | .validate = nft_reject_validate, | ||
127 | }; | 132 | }; |
128 | 133 | ||
129 | static struct nft_expr_type nft_reject_inet_type __read_mostly = { | 134 | static struct nft_expr_type nft_reject_inet_type __read_mostly = { |
diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c index 7f4414d26a66..663c4c3c9072 100644 --- a/net/netfilter/xt_TPROXY.c +++ b/net/netfilter/xt_TPROXY.c | |||
@@ -127,6 +127,8 @@ nf_tproxy_get_sock_v4(struct net *net, struct sk_buff *skb, void *hp, | |||
127 | daddr, dport, | 127 | daddr, dport, |
128 | in->ifindex); | 128 | in->ifindex); |
129 | 129 | ||
130 | if (sk && !atomic_inc_not_zero(&sk->sk_refcnt)) | ||
131 | sk = NULL; | ||
130 | /* NOTE: we return listeners even if bound to | 132 | /* NOTE: we return listeners even if bound to |
131 | * 0.0.0.0, those are filtered out in | 133 | * 0.0.0.0, those are filtered out in |
132 | * xt_socket, since xt_TPROXY needs 0 bound | 134 | * xt_socket, since xt_TPROXY needs 0 bound |
@@ -195,6 +197,8 @@ nf_tproxy_get_sock_v6(struct net *net, struct sk_buff *skb, int thoff, void *hp, | |||
195 | daddr, ntohs(dport), | 197 | daddr, ntohs(dport), |
196 | in->ifindex); | 198 | in->ifindex); |
197 | 199 | ||
200 | if (sk && !atomic_inc_not_zero(&sk->sk_refcnt)) | ||
201 | sk = NULL; | ||
198 | /* NOTE: we return listeners even if bound to | 202 | /* NOTE: we return listeners even if bound to |
199 | * 0.0.0.0, those are filtered out in | 203 | * 0.0.0.0, those are filtered out in |
200 | * xt_socket, since xt_TPROXY needs 0 bound | 204 | * xt_socket, since xt_TPROXY needs 0 bound |
diff --git a/net/netfilter/xt_nfacct.c b/net/netfilter/xt_nfacct.c index 3048a7e3a90a..cf327593852a 100644 --- a/net/netfilter/xt_nfacct.c +++ b/net/netfilter/xt_nfacct.c | |||
@@ -26,7 +26,7 @@ static bool nfacct_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
26 | 26 | ||
27 | nfnl_acct_update(skb, info->nfacct); | 27 | nfnl_acct_update(skb, info->nfacct); |
28 | 28 | ||
29 | overquota = nfnl_acct_overquota(skb, info->nfacct); | 29 | overquota = nfnl_acct_overquota(par->net, skb, info->nfacct); |
30 | 30 | ||
31 | return overquota == NFACCT_UNDERQUOTA ? false : true; | 31 | return overquota == NFACCT_UNDERQUOTA ? false : true; |
32 | } | 32 | } |
diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c index 141a06eeb1e5..e87cd81315e1 100644 --- a/net/sched/act_ife.c +++ b/net/sched/act_ife.c | |||
@@ -53,7 +53,7 @@ int ife_tlv_meta_encode(void *skbdata, u16 attrtype, u16 dlen, const void *dval) | |||
53 | u32 *tlv = (u32 *)(skbdata); | 53 | u32 *tlv = (u32 *)(skbdata); |
54 | u16 totlen = nla_total_size(dlen); /*alignment + hdr */ | 54 | u16 totlen = nla_total_size(dlen); /*alignment + hdr */ |
55 | char *dptr = (char *)tlv + NLA_HDRLEN; | 55 | char *dptr = (char *)tlv + NLA_HDRLEN; |
56 | u32 htlv = attrtype << 16 | totlen; | 56 | u32 htlv = attrtype << 16 | dlen; |
57 | 57 | ||
58 | *tlv = htonl(htlv); | 58 | *tlv = htonl(htlv); |
59 | memset(dptr, 0, totlen - NLA_HDRLEN); | 59 | memset(dptr, 0, totlen - NLA_HDRLEN); |
@@ -135,7 +135,7 @@ EXPORT_SYMBOL_GPL(ife_release_meta_gen); | |||
135 | 135 | ||
136 | int ife_validate_meta_u32(void *val, int len) | 136 | int ife_validate_meta_u32(void *val, int len) |
137 | { | 137 | { |
138 | if (len == 4) | 138 | if (len == sizeof(u32)) |
139 | return 0; | 139 | return 0; |
140 | 140 | ||
141 | return -EINVAL; | 141 | return -EINVAL; |
@@ -144,8 +144,8 @@ EXPORT_SYMBOL_GPL(ife_validate_meta_u32); | |||
144 | 144 | ||
145 | int ife_validate_meta_u16(void *val, int len) | 145 | int ife_validate_meta_u16(void *val, int len) |
146 | { | 146 | { |
147 | /* length will include padding */ | 147 | /* length will not include padding */ |
148 | if (len == NLA_ALIGN(2)) | 148 | if (len == sizeof(u16)) |
149 | return 0; | 149 | return 0; |
150 | 150 | ||
151 | return -EINVAL; | 151 | return -EINVAL; |
@@ -652,12 +652,14 @@ static int tcf_ife_decode(struct sk_buff *skb, const struct tc_action *a, | |||
652 | u8 *tlvdata = (u8 *)tlv; | 652 | u8 *tlvdata = (u8 *)tlv; |
653 | u16 mtype = tlv->type; | 653 | u16 mtype = tlv->type; |
654 | u16 mlen = tlv->len; | 654 | u16 mlen = tlv->len; |
655 | u16 alen; | ||
655 | 656 | ||
656 | mtype = ntohs(mtype); | 657 | mtype = ntohs(mtype); |
657 | mlen = ntohs(mlen); | 658 | mlen = ntohs(mlen); |
659 | alen = NLA_ALIGN(mlen); | ||
658 | 660 | ||
659 | if (find_decode_metaid(skb, ife, mtype, (mlen - 4), | 661 | if (find_decode_metaid(skb, ife, mtype, (mlen - NLA_HDRLEN), |
660 | (void *)(tlvdata + 4))) { | 662 | (void *)(tlvdata + NLA_HDRLEN))) { |
661 | /* abuse overlimits to count when we receive metadata | 663 | /* abuse overlimits to count when we receive metadata |
662 | * but dont have an ops for it | 664 | * but dont have an ops for it |
663 | */ | 665 | */ |
@@ -666,8 +668,8 @@ static int tcf_ife_decode(struct sk_buff *skb, const struct tc_action *a, | |||
666 | ife->tcf_qstats.overlimits++; | 668 | ife->tcf_qstats.overlimits++; |
667 | } | 669 | } |
668 | 670 | ||
669 | tlvdata += mlen; | 671 | tlvdata += alen; |
670 | ifehdrln -= mlen; | 672 | ifehdrln -= alen; |
671 | tlv = (struct meta_tlvhdr *)tlvdata; | 673 | tlv = (struct meta_tlvhdr *)tlvdata; |
672 | } | 674 | } |
673 | 675 | ||
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index e95b67cd5718..657c13362b19 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -643,18 +643,19 @@ struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue, | |||
643 | struct Qdisc *sch; | 643 | struct Qdisc *sch; |
644 | 644 | ||
645 | if (!try_module_get(ops->owner)) | 645 | if (!try_module_get(ops->owner)) |
646 | goto errout; | 646 | return NULL; |
647 | 647 | ||
648 | sch = qdisc_alloc(dev_queue, ops); | 648 | sch = qdisc_alloc(dev_queue, ops); |
649 | if (IS_ERR(sch)) | 649 | if (IS_ERR(sch)) { |
650 | goto errout; | 650 | module_put(ops->owner); |
651 | return NULL; | ||
652 | } | ||
651 | sch->parent = parentid; | 653 | sch->parent = parentid; |
652 | 654 | ||
653 | if (!ops->init || ops->init(sch, NULL) == 0) | 655 | if (!ops->init || ops->init(sch, NULL) == 0) |
654 | return sch; | 656 | return sch; |
655 | 657 | ||
656 | qdisc_destroy(sch); | 658 | qdisc_destroy(sch); |
657 | errout: | ||
658 | return NULL; | 659 | return NULL; |
659 | } | 660 | } |
660 | EXPORT_SYMBOL(qdisc_create_dflt); | 661 | EXPORT_SYMBOL(qdisc_create_dflt); |
diff --git a/net/sctp/input.c b/net/sctp/input.c index c182db7d691f..1555fb8c68e0 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -119,7 +119,13 @@ int sctp_rcv(struct sk_buff *skb) | |||
119 | skb_transport_offset(skb)) | 119 | skb_transport_offset(skb)) |
120 | goto discard_it; | 120 | goto discard_it; |
121 | 121 | ||
122 | if (!pskb_may_pull(skb, sizeof(struct sctphdr))) | 122 | /* If the packet is fragmented and we need to do crc checking, |
123 | * it's better to just linearize it otherwise crc computing | ||
124 | * takes longer. | ||
125 | */ | ||
126 | if ((!(skb_shinfo(skb)->gso_type & SKB_GSO_SCTP) && | ||
127 | skb_linearize(skb)) || | ||
128 | !pskb_may_pull(skb, sizeof(struct sctphdr))) | ||
123 | goto discard_it; | 129 | goto discard_it; |
124 | 130 | ||
125 | /* Pull up the IP header. */ | 131 | /* Pull up the IP header. */ |
@@ -790,27 +796,34 @@ struct sctp_hash_cmp_arg { | |||
790 | static inline int sctp_hash_cmp(struct rhashtable_compare_arg *arg, | 796 | static inline int sctp_hash_cmp(struct rhashtable_compare_arg *arg, |
791 | const void *ptr) | 797 | const void *ptr) |
792 | { | 798 | { |
799 | struct sctp_transport *t = (struct sctp_transport *)ptr; | ||
793 | const struct sctp_hash_cmp_arg *x = arg->key; | 800 | const struct sctp_hash_cmp_arg *x = arg->key; |
794 | const struct sctp_transport *t = ptr; | 801 | struct sctp_association *asoc; |
795 | struct sctp_association *asoc = t->asoc; | 802 | int err = 1; |
796 | const struct net *net = x->net; | ||
797 | 803 | ||
798 | if (!sctp_cmp_addr_exact(&t->ipaddr, x->paddr)) | 804 | if (!sctp_cmp_addr_exact(&t->ipaddr, x->paddr)) |
799 | return 1; | 805 | return err; |
800 | if (!net_eq(sock_net(asoc->base.sk), net)) | 806 | if (!sctp_transport_hold(t)) |
801 | return 1; | 807 | return err; |
808 | |||
809 | asoc = t->asoc; | ||
810 | if (!net_eq(sock_net(asoc->base.sk), x->net)) | ||
811 | goto out; | ||
802 | if (x->ep) { | 812 | if (x->ep) { |
803 | if (x->ep != asoc->ep) | 813 | if (x->ep != asoc->ep) |
804 | return 1; | 814 | goto out; |
805 | } else { | 815 | } else { |
806 | if (x->laddr->v4.sin_port != htons(asoc->base.bind_addr.port)) | 816 | if (x->laddr->v4.sin_port != htons(asoc->base.bind_addr.port)) |
807 | return 1; | 817 | goto out; |
808 | if (!sctp_bind_addr_match(&asoc->base.bind_addr, | 818 | if (!sctp_bind_addr_match(&asoc->base.bind_addr, |
809 | x->laddr, sctp_sk(asoc->base.sk))) | 819 | x->laddr, sctp_sk(asoc->base.sk))) |
810 | return 1; | 820 | goto out; |
811 | } | 821 | } |
812 | 822 | ||
813 | return 0; | 823 | err = 0; |
824 | out: | ||
825 | sctp_transport_put(t); | ||
826 | return err; | ||
814 | } | 827 | } |
815 | 828 | ||
816 | static inline u32 sctp_hash_obj(const void *data, u32 len, u32 seed) | 829 | static inline u32 sctp_hash_obj(const void *data, u32 len, u32 seed) |
@@ -1177,9 +1190,6 @@ static struct sctp_association *__sctp_rcv_lookup_harder(struct net *net, | |||
1177 | if ((skb_shinfo(skb)->gso_type & SKB_GSO_SCTP) == SKB_GSO_SCTP) | 1190 | if ((skb_shinfo(skb)->gso_type & SKB_GSO_SCTP) == SKB_GSO_SCTP) |
1178 | return NULL; | 1191 | return NULL; |
1179 | 1192 | ||
1180 | if (skb_linearize(skb)) | ||
1181 | return NULL; | ||
1182 | |||
1183 | ch = (sctp_chunkhdr_t *) skb->data; | 1193 | ch = (sctp_chunkhdr_t *) skb->data; |
1184 | 1194 | ||
1185 | /* The code below will attempt to walk the chunk and extract | 1195 | /* The code below will attempt to walk the chunk and extract |
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c index c30ddb0f3190..6437aa97cfd7 100644 --- a/net/sctp/inqueue.c +++ b/net/sctp/inqueue.c | |||
@@ -170,19 +170,6 @@ next_chunk: | |||
170 | 170 | ||
171 | chunk = list_entry(entry, struct sctp_chunk, list); | 171 | chunk = list_entry(entry, struct sctp_chunk, list); |
172 | 172 | ||
173 | /* Linearize if it's not GSO */ | ||
174 | if ((skb_shinfo(chunk->skb)->gso_type & SKB_GSO_SCTP) != SKB_GSO_SCTP && | ||
175 | skb_is_nonlinear(chunk->skb)) { | ||
176 | if (skb_linearize(chunk->skb)) { | ||
177 | __SCTP_INC_STATS(dev_net(chunk->skb->dev), SCTP_MIB_IN_PKT_DISCARDS); | ||
178 | sctp_chunk_free(chunk); | ||
179 | goto next_chunk; | ||
180 | } | ||
181 | |||
182 | /* Update sctp_hdr as it probably changed */ | ||
183 | chunk->sctp_hdr = sctp_hdr(chunk->skb); | ||
184 | } | ||
185 | |||
186 | if ((skb_shinfo(chunk->skb)->gso_type & SKB_GSO_SCTP) == SKB_GSO_SCTP) { | 173 | if ((skb_shinfo(chunk->skb)->gso_type & SKB_GSO_SCTP) == SKB_GSO_SCTP) { |
187 | /* GSO-marked skbs but without frags, handle | 174 | /* GSO-marked skbs but without frags, handle |
188 | * them normally | 175 | * them normally |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 1f1682b9a6a8..31b7bc35895d 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -878,7 +878,7 @@ static sctp_xmit_t sctp_packet_will_fit(struct sctp_packet *packet, | |||
878 | struct sctp_chunk *chunk, | 878 | struct sctp_chunk *chunk, |
879 | u16 chunk_len) | 879 | u16 chunk_len) |
880 | { | 880 | { |
881 | size_t psize, pmtu; | 881 | size_t psize, pmtu, maxsize; |
882 | sctp_xmit_t retval = SCTP_XMIT_OK; | 882 | sctp_xmit_t retval = SCTP_XMIT_OK; |
883 | 883 | ||
884 | psize = packet->size; | 884 | psize = packet->size; |
@@ -906,6 +906,17 @@ static sctp_xmit_t sctp_packet_will_fit(struct sctp_packet *packet, | |||
906 | goto out; | 906 | goto out; |
907 | } | 907 | } |
908 | 908 | ||
909 | /* Similarly, if this chunk was built before a PMTU | ||
910 | * reduction, we have to fragment it at IP level now. So | ||
911 | * if the packet already contains something, we need to | ||
912 | * flush. | ||
913 | */ | ||
914 | maxsize = pmtu - packet->overhead; | ||
915 | if (packet->auth) | ||
916 | maxsize -= WORD_ROUND(packet->auth->skb->len); | ||
917 | if (chunk_len > maxsize) | ||
918 | retval = SCTP_XMIT_PMTU_FULL; | ||
919 | |||
909 | /* It is also okay to fragment if the chunk we are | 920 | /* It is also okay to fragment if the chunk we are |
910 | * adding is a control chunk, but only if current packet | 921 | * adding is a control chunk, but only if current packet |
911 | * is not a GSO one otherwise it causes fragmentation of | 922 | * is not a GSO one otherwise it causes fragmentation of |
diff --git a/net/sctp/sctp_diag.c b/net/sctp/sctp_diag.c index bb691538adc8..f3508aa75815 100644 --- a/net/sctp/sctp_diag.c +++ b/net/sctp/sctp_diag.c | |||
@@ -424,11 +424,13 @@ static int sctp_diag_dump_one(struct sk_buff *in_skb, | |||
424 | paddr.v4.sin_family = AF_INET; | 424 | paddr.v4.sin_family = AF_INET; |
425 | } else { | 425 | } else { |
426 | laddr.v6.sin6_port = req->id.idiag_sport; | 426 | laddr.v6.sin6_port = req->id.idiag_sport; |
427 | memcpy(&laddr.v6.sin6_addr, req->id.idiag_src, 64); | 427 | memcpy(&laddr.v6.sin6_addr, req->id.idiag_src, |
428 | sizeof(laddr.v6.sin6_addr)); | ||
428 | laddr.v6.sin6_family = AF_INET6; | 429 | laddr.v6.sin6_family = AF_INET6; |
429 | 430 | ||
430 | paddr.v6.sin6_port = req->id.idiag_dport; | 431 | paddr.v6.sin6_port = req->id.idiag_dport; |
431 | memcpy(&paddr.v6.sin6_addr, req->id.idiag_dst, 64); | 432 | memcpy(&paddr.v6.sin6_addr, req->id.idiag_dst, |
433 | sizeof(paddr.v6.sin6_addr)); | ||
432 | paddr.v6.sin6_family = AF_INET6; | 434 | paddr.v6.sin6_family = AF_INET6; |
433 | } | 435 | } |
434 | 436 | ||
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 1d281816f2bf..d8582028b346 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -569,9 +569,10 @@ gss_svc_searchbyctx(struct cache_detail *cd, struct xdr_netobj *handle) | |||
569 | struct rsc *found; | 569 | struct rsc *found; |
570 | 570 | ||
571 | memset(&rsci, 0, sizeof(rsci)); | 571 | memset(&rsci, 0, sizeof(rsci)); |
572 | rsci.handle.data = handle->data; | 572 | if (dup_to_netobj(&rsci.handle, handle->data, handle->len)) |
573 | rsci.handle.len = handle->len; | 573 | return NULL; |
574 | found = rsc_lookup(cd, &rsci); | 574 | found = rsc_lookup(cd, &rsci); |
575 | rsc_free(&rsci); | ||
575 | if (!found) | 576 | if (!found) |
576 | return NULL; | 577 | return NULL; |
577 | if (cache_check(cd, &found->h, NULL)) | 578 | if (cache_check(cd, &found->h, NULL)) |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 7f79fb7dc6a0..66f23b376fa0 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -453,7 +453,7 @@ static struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args, | |||
453 | struct rpc_xprt_switch *xps; | 453 | struct rpc_xprt_switch *xps; |
454 | 454 | ||
455 | if (args->bc_xprt && args->bc_xprt->xpt_bc_xps) { | 455 | if (args->bc_xprt && args->bc_xprt->xpt_bc_xps) { |
456 | WARN_ON(args->protocol != XPRT_TRANSPORT_BC_TCP); | 456 | WARN_ON_ONCE(!(args->protocol & XPRT_TRANSPORT_BC)); |
457 | xps = args->bc_xprt->xpt_bc_xps; | 457 | xps = args->bc_xprt->xpt_bc_xps; |
458 | xprt_switch_get(xps); | 458 | xprt_switch_get(xps); |
459 | } else { | 459 | } else { |
@@ -520,7 +520,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
520 | char servername[48]; | 520 | char servername[48]; |
521 | 521 | ||
522 | if (args->bc_xprt) { | 522 | if (args->bc_xprt) { |
523 | WARN_ON(args->protocol != XPRT_TRANSPORT_BC_TCP); | 523 | WARN_ON_ONCE(!(args->protocol & XPRT_TRANSPORT_BC)); |
524 | xprt = args->bc_xprt->xpt_bc_xprt; | 524 | xprt = args->bc_xprt->xpt_bc_xprt; |
525 | if (xprt) { | 525 | if (xprt) { |
526 | xprt_get(xprt); | 526 | xprt_get(xprt); |
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 536d0be3f61b..799cce6cbe45 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/slab.h> | 51 | #include <linux/slab.h> |
52 | #include <linux/prefetch.h> | 52 | #include <linux/prefetch.h> |
53 | #include <linux/sunrpc/addr.h> | 53 | #include <linux/sunrpc/addr.h> |
54 | #include <linux/sunrpc/svc_rdma.h> | ||
54 | #include <asm/bitops.h> | 55 | #include <asm/bitops.h> |
55 | #include <linux/module.h> /* try_module_get()/module_put() */ | 56 | #include <linux/module.h> /* try_module_get()/module_put() */ |
56 | 57 | ||
@@ -923,7 +924,7 @@ rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt) | |||
923 | } | 924 | } |
924 | 925 | ||
925 | INIT_LIST_HEAD(&buf->rb_recv_bufs); | 926 | INIT_LIST_HEAD(&buf->rb_recv_bufs); |
926 | for (i = 0; i < buf->rb_max_requests; i++) { | 927 | for (i = 0; i < buf->rb_max_requests + RPCRDMA_MAX_BC_REQUESTS; i++) { |
927 | struct rpcrdma_rep *rep; | 928 | struct rpcrdma_rep *rep; |
928 | 929 | ||
929 | rep = rpcrdma_create_rep(r_xprt); | 930 | rep = rpcrdma_create_rep(r_xprt); |
@@ -1018,6 +1019,7 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf) | |||
1018 | rep = rpcrdma_buffer_get_rep_locked(buf); | 1019 | rep = rpcrdma_buffer_get_rep_locked(buf); |
1019 | rpcrdma_destroy_rep(ia, rep); | 1020 | rpcrdma_destroy_rep(ia, rep); |
1020 | } | 1021 | } |
1022 | buf->rb_send_count = 0; | ||
1021 | 1023 | ||
1022 | spin_lock(&buf->rb_reqslock); | 1024 | spin_lock(&buf->rb_reqslock); |
1023 | while (!list_empty(&buf->rb_allreqs)) { | 1025 | while (!list_empty(&buf->rb_allreqs)) { |
@@ -1032,6 +1034,7 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf) | |||
1032 | spin_lock(&buf->rb_reqslock); | 1034 | spin_lock(&buf->rb_reqslock); |
1033 | } | 1035 | } |
1034 | spin_unlock(&buf->rb_reqslock); | 1036 | spin_unlock(&buf->rb_reqslock); |
1037 | buf->rb_recv_count = 0; | ||
1035 | 1038 | ||
1036 | rpcrdma_destroy_mrs(buf); | 1039 | rpcrdma_destroy_mrs(buf); |
1037 | } | 1040 | } |
@@ -1074,8 +1077,27 @@ rpcrdma_put_mw(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mw *mw) | |||
1074 | spin_unlock(&buf->rb_mwlock); | 1077 | spin_unlock(&buf->rb_mwlock); |
1075 | } | 1078 | } |
1076 | 1079 | ||
1080 | static struct rpcrdma_rep * | ||
1081 | rpcrdma_buffer_get_rep(struct rpcrdma_buffer *buffers) | ||
1082 | { | ||
1083 | /* If an RPC previously completed without a reply (say, a | ||
1084 | * credential problem or a soft timeout occurs) then hold off | ||
1085 | * on supplying more Receive buffers until the number of new | ||
1086 | * pending RPCs catches up to the number of posted Receives. | ||
1087 | */ | ||
1088 | if (unlikely(buffers->rb_send_count < buffers->rb_recv_count)) | ||
1089 | return NULL; | ||
1090 | |||
1091 | if (unlikely(list_empty(&buffers->rb_recv_bufs))) | ||
1092 | return NULL; | ||
1093 | buffers->rb_recv_count++; | ||
1094 | return rpcrdma_buffer_get_rep_locked(buffers); | ||
1095 | } | ||
1096 | |||
1077 | /* | 1097 | /* |
1078 | * Get a set of request/reply buffers. | 1098 | * Get a set of request/reply buffers. |
1099 | * | ||
1100 | * Reply buffer (if available) is attached to send buffer upon return. | ||
1079 | */ | 1101 | */ |
1080 | struct rpcrdma_req * | 1102 | struct rpcrdma_req * |
1081 | rpcrdma_buffer_get(struct rpcrdma_buffer *buffers) | 1103 | rpcrdma_buffer_get(struct rpcrdma_buffer *buffers) |
@@ -1085,21 +1107,15 @@ rpcrdma_buffer_get(struct rpcrdma_buffer *buffers) | |||
1085 | spin_lock(&buffers->rb_lock); | 1107 | spin_lock(&buffers->rb_lock); |
1086 | if (list_empty(&buffers->rb_send_bufs)) | 1108 | if (list_empty(&buffers->rb_send_bufs)) |
1087 | goto out_reqbuf; | 1109 | goto out_reqbuf; |
1110 | buffers->rb_send_count++; | ||
1088 | req = rpcrdma_buffer_get_req_locked(buffers); | 1111 | req = rpcrdma_buffer_get_req_locked(buffers); |
1089 | if (list_empty(&buffers->rb_recv_bufs)) | 1112 | req->rl_reply = rpcrdma_buffer_get_rep(buffers); |
1090 | goto out_repbuf; | ||
1091 | req->rl_reply = rpcrdma_buffer_get_rep_locked(buffers); | ||
1092 | spin_unlock(&buffers->rb_lock); | 1113 | spin_unlock(&buffers->rb_lock); |
1093 | return req; | 1114 | return req; |
1094 | 1115 | ||
1095 | out_reqbuf: | 1116 | out_reqbuf: |
1096 | spin_unlock(&buffers->rb_lock); | 1117 | spin_unlock(&buffers->rb_lock); |
1097 | pr_warn("rpcrdma: out of request buffers (%p)\n", buffers); | 1118 | pr_warn("RPC: %s: out of request buffers\n", __func__); |
1098 | return NULL; | ||
1099 | out_repbuf: | ||
1100 | list_add(&req->rl_free, &buffers->rb_send_bufs); | ||
1101 | spin_unlock(&buffers->rb_lock); | ||
1102 | pr_warn("rpcrdma: out of reply buffers (%p)\n", buffers); | ||
1103 | return NULL; | 1119 | return NULL; |
1104 | } | 1120 | } |
1105 | 1121 | ||
@@ -1117,9 +1133,12 @@ rpcrdma_buffer_put(struct rpcrdma_req *req) | |||
1117 | req->rl_reply = NULL; | 1133 | req->rl_reply = NULL; |
1118 | 1134 | ||
1119 | spin_lock(&buffers->rb_lock); | 1135 | spin_lock(&buffers->rb_lock); |
1136 | buffers->rb_send_count--; | ||
1120 | list_add_tail(&req->rl_free, &buffers->rb_send_bufs); | 1137 | list_add_tail(&req->rl_free, &buffers->rb_send_bufs); |
1121 | if (rep) | 1138 | if (rep) { |
1139 | buffers->rb_recv_count--; | ||
1122 | list_add_tail(&rep->rr_list, &buffers->rb_recv_bufs); | 1140 | list_add_tail(&rep->rr_list, &buffers->rb_recv_bufs); |
1141 | } | ||
1123 | spin_unlock(&buffers->rb_lock); | 1142 | spin_unlock(&buffers->rb_lock); |
1124 | } | 1143 | } |
1125 | 1144 | ||
@@ -1133,8 +1152,7 @@ rpcrdma_recv_buffer_get(struct rpcrdma_req *req) | |||
1133 | struct rpcrdma_buffer *buffers = req->rl_buffer; | 1152 | struct rpcrdma_buffer *buffers = req->rl_buffer; |
1134 | 1153 | ||
1135 | spin_lock(&buffers->rb_lock); | 1154 | spin_lock(&buffers->rb_lock); |
1136 | if (!list_empty(&buffers->rb_recv_bufs)) | 1155 | req->rl_reply = rpcrdma_buffer_get_rep(buffers); |
1137 | req->rl_reply = rpcrdma_buffer_get_rep_locked(buffers); | ||
1138 | spin_unlock(&buffers->rb_lock); | 1156 | spin_unlock(&buffers->rb_lock); |
1139 | } | 1157 | } |
1140 | 1158 | ||
@@ -1148,6 +1166,7 @@ rpcrdma_recv_buffer_put(struct rpcrdma_rep *rep) | |||
1148 | struct rpcrdma_buffer *buffers = &rep->rr_rxprt->rx_buf; | 1166 | struct rpcrdma_buffer *buffers = &rep->rr_rxprt->rx_buf; |
1149 | 1167 | ||
1150 | spin_lock(&buffers->rb_lock); | 1168 | spin_lock(&buffers->rb_lock); |
1169 | buffers->rb_recv_count--; | ||
1151 | list_add_tail(&rep->rr_list, &buffers->rb_recv_bufs); | 1170 | list_add_tail(&rep->rr_list, &buffers->rb_recv_bufs); |
1152 | spin_unlock(&buffers->rb_lock); | 1171 | spin_unlock(&buffers->rb_lock); |
1153 | } | 1172 | } |
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index 670fad57153a..a71b0f5897d8 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h | |||
@@ -321,6 +321,7 @@ struct rpcrdma_buffer { | |||
321 | char *rb_pool; | 321 | char *rb_pool; |
322 | 322 | ||
323 | spinlock_t rb_lock; /* protect buf lists */ | 323 | spinlock_t rb_lock; /* protect buf lists */ |
324 | int rb_send_count, rb_recv_count; | ||
324 | struct list_head rb_send_bufs; | 325 | struct list_head rb_send_bufs; |
325 | struct list_head rb_recv_bufs; | 326 | struct list_head rb_recv_bufs; |
326 | u32 rb_max_requests; | 327 | u32 rb_max_requests; |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 8ede3bc52481..bf168838a029 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -1074,7 +1074,7 @@ static void xs_udp_data_receive(struct sock_xprt *transport) | |||
1074 | skb = skb_recv_datagram(sk, 0, 1, &err); | 1074 | skb = skb_recv_datagram(sk, 0, 1, &err); |
1075 | if (skb != NULL) { | 1075 | if (skb != NULL) { |
1076 | xs_udp_data_read_skb(&transport->xprt, sk, skb); | 1076 | xs_udp_data_read_skb(&transport->xprt, sk, skb); |
1077 | skb_free_datagram(sk, skb); | 1077 | skb_free_datagram_locked(sk, skb); |
1078 | continue; | 1078 | continue; |
1079 | } | 1079 | } |
1080 | if (!test_and_clear_bit(XPRT_SOCK_DATA_READY, &transport->sock_state)) | 1080 | if (!test_and_clear_bit(XPRT_SOCK_DATA_READY, &transport->sock_state)) |
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 6b626a64b517..a04fe9be1c60 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c | |||
@@ -62,6 +62,8 @@ static void publ_to_item(struct distr_item *i, struct publication *p) | |||
62 | 62 | ||
63 | /** | 63 | /** |
64 | * named_prepare_buf - allocate & initialize a publication message | 64 | * named_prepare_buf - allocate & initialize a publication message |
65 | * | ||
66 | * The buffer returned is of size INT_H_SIZE + payload size | ||
65 | */ | 67 | */ |
66 | static struct sk_buff *named_prepare_buf(struct net *net, u32 type, u32 size, | 68 | static struct sk_buff *named_prepare_buf(struct net *net, u32 type, u32 size, |
67 | u32 dest) | 69 | u32 dest) |
@@ -141,9 +143,9 @@ static void named_distribute(struct net *net, struct sk_buff_head *list, | |||
141 | struct publication *publ; | 143 | struct publication *publ; |
142 | struct sk_buff *skb = NULL; | 144 | struct sk_buff *skb = NULL; |
143 | struct distr_item *item = NULL; | 145 | struct distr_item *item = NULL; |
144 | uint msg_dsz = (tipc_node_get_mtu(net, dnode, 0) / ITEM_SIZE) * | 146 | u32 msg_dsz = ((tipc_node_get_mtu(net, dnode, 0) - INT_H_SIZE) / |
145 | ITEM_SIZE; | 147 | ITEM_SIZE) * ITEM_SIZE; |
146 | uint msg_rem = msg_dsz; | 148 | u32 msg_rem = msg_dsz; |
147 | 149 | ||
148 | list_for_each_entry(publ, pls, local_list) { | 150 | list_for_each_entry(publ, pls, local_list) { |
149 | /* Prepare next buffer: */ | 151 | /* Prepare next buffer: */ |
diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c index b016c011970b..ae7e14cae085 100644 --- a/net/tipc/udp_media.c +++ b/net/tipc/udp_media.c | |||
@@ -396,10 +396,13 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b, | |||
396 | tuncfg.encap_destroy = NULL; | 396 | tuncfg.encap_destroy = NULL; |
397 | setup_udp_tunnel_sock(net, ub->ubsock, &tuncfg); | 397 | setup_udp_tunnel_sock(net, ub->ubsock, &tuncfg); |
398 | 398 | ||
399 | if (enable_mcast(ub, remote)) | 399 | err = enable_mcast(ub, remote); |
400 | if (err) | ||
400 | goto err; | 401 | goto err; |
401 | return 0; | 402 | return 0; |
402 | err: | 403 | err: |
404 | if (ub->ubsock) | ||
405 | udp_tunnel_sock_release(ub->ubsock); | ||
403 | kfree(ub); | 406 | kfree(ub); |
404 | return err; | 407 | return err; |
405 | } | 408 | } |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index f1dffe84f0d5..8309687a56b0 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -661,11 +661,11 @@ static int unix_set_peek_off(struct sock *sk, int val) | |||
661 | { | 661 | { |
662 | struct unix_sock *u = unix_sk(sk); | 662 | struct unix_sock *u = unix_sk(sk); |
663 | 663 | ||
664 | if (mutex_lock_interruptible(&u->readlock)) | 664 | if (mutex_lock_interruptible(&u->iolock)) |
665 | return -EINTR; | 665 | return -EINTR; |
666 | 666 | ||
667 | sk->sk_peek_off = val; | 667 | sk->sk_peek_off = val; |
668 | mutex_unlock(&u->readlock); | 668 | mutex_unlock(&u->iolock); |
669 | 669 | ||
670 | return 0; | 670 | return 0; |
671 | } | 671 | } |
@@ -779,7 +779,8 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern) | |||
779 | spin_lock_init(&u->lock); | 779 | spin_lock_init(&u->lock); |
780 | atomic_long_set(&u->inflight, 0); | 780 | atomic_long_set(&u->inflight, 0); |
781 | INIT_LIST_HEAD(&u->link); | 781 | INIT_LIST_HEAD(&u->link); |
782 | mutex_init(&u->readlock); /* single task reading lock */ | 782 | mutex_init(&u->iolock); /* single task reading lock */ |
783 | mutex_init(&u->bindlock); /* single task binding lock */ | ||
783 | init_waitqueue_head(&u->peer_wait); | 784 | init_waitqueue_head(&u->peer_wait); |
784 | init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay); | 785 | init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay); |
785 | unix_insert_socket(unix_sockets_unbound(sk), sk); | 786 | unix_insert_socket(unix_sockets_unbound(sk), sk); |
@@ -848,7 +849,7 @@ static int unix_autobind(struct socket *sock) | |||
848 | int err; | 849 | int err; |
849 | unsigned int retries = 0; | 850 | unsigned int retries = 0; |
850 | 851 | ||
851 | err = mutex_lock_interruptible(&u->readlock); | 852 | err = mutex_lock_interruptible(&u->bindlock); |
852 | if (err) | 853 | if (err) |
853 | return err; | 854 | return err; |
854 | 855 | ||
@@ -895,7 +896,7 @@ retry: | |||
895 | spin_unlock(&unix_table_lock); | 896 | spin_unlock(&unix_table_lock); |
896 | err = 0; | 897 | err = 0; |
897 | 898 | ||
898 | out: mutex_unlock(&u->readlock); | 899 | out: mutex_unlock(&u->bindlock); |
899 | return err; | 900 | return err; |
900 | } | 901 | } |
901 | 902 | ||
@@ -954,20 +955,32 @@ fail: | |||
954 | return NULL; | 955 | return NULL; |
955 | } | 956 | } |
956 | 957 | ||
957 | static int unix_mknod(struct dentry *dentry, const struct path *path, umode_t mode, | 958 | static int unix_mknod(const char *sun_path, umode_t mode, struct path *res) |
958 | struct path *res) | ||
959 | { | 959 | { |
960 | int err; | 960 | struct dentry *dentry; |
961 | struct path path; | ||
962 | int err = 0; | ||
963 | /* | ||
964 | * Get the parent directory, calculate the hash for last | ||
965 | * component. | ||
966 | */ | ||
967 | dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0); | ||
968 | err = PTR_ERR(dentry); | ||
969 | if (IS_ERR(dentry)) | ||
970 | return err; | ||
961 | 971 | ||
962 | err = security_path_mknod(path, dentry, mode, 0); | 972 | /* |
973 | * All right, let's create it. | ||
974 | */ | ||
975 | err = security_path_mknod(&path, dentry, mode, 0); | ||
963 | if (!err) { | 976 | if (!err) { |
964 | err = vfs_mknod(d_inode(path->dentry), dentry, mode, 0); | 977 | err = vfs_mknod(d_inode(path.dentry), dentry, mode, 0); |
965 | if (!err) { | 978 | if (!err) { |
966 | res->mnt = mntget(path->mnt); | 979 | res->mnt = mntget(path.mnt); |
967 | res->dentry = dget(dentry); | 980 | res->dentry = dget(dentry); |
968 | } | 981 | } |
969 | } | 982 | } |
970 | 983 | done_path_create(&path, dentry); | |
971 | return err; | 984 | return err; |
972 | } | 985 | } |
973 | 986 | ||
@@ -978,12 +991,10 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
978 | struct unix_sock *u = unix_sk(sk); | 991 | struct unix_sock *u = unix_sk(sk); |
979 | struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr; | 992 | struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr; |
980 | char *sun_path = sunaddr->sun_path; | 993 | char *sun_path = sunaddr->sun_path; |
981 | int err, name_err; | 994 | int err; |
982 | unsigned int hash; | 995 | unsigned int hash; |
983 | struct unix_address *addr; | 996 | struct unix_address *addr; |
984 | struct hlist_head *list; | 997 | struct hlist_head *list; |
985 | struct path path; | ||
986 | struct dentry *dentry; | ||
987 | 998 | ||
988 | err = -EINVAL; | 999 | err = -EINVAL; |
989 | if (sunaddr->sun_family != AF_UNIX) | 1000 | if (sunaddr->sun_family != AF_UNIX) |
@@ -999,34 +1010,14 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
999 | goto out; | 1010 | goto out; |
1000 | addr_len = err; | 1011 | addr_len = err; |
1001 | 1012 | ||
1002 | name_err = 0; | 1013 | err = mutex_lock_interruptible(&u->bindlock); |
1003 | dentry = NULL; | ||
1004 | if (sun_path[0]) { | ||
1005 | /* Get the parent directory, calculate the hash for last | ||
1006 | * component. | ||
1007 | */ | ||
1008 | dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0); | ||
1009 | |||
1010 | if (IS_ERR(dentry)) { | ||
1011 | /* delay report until after 'already bound' check */ | ||
1012 | name_err = PTR_ERR(dentry); | ||
1013 | dentry = NULL; | ||
1014 | } | ||
1015 | } | ||
1016 | |||
1017 | err = mutex_lock_interruptible(&u->readlock); | ||
1018 | if (err) | 1014 | if (err) |
1019 | goto out_path; | 1015 | goto out; |
1020 | 1016 | ||
1021 | err = -EINVAL; | 1017 | err = -EINVAL; |
1022 | if (u->addr) | 1018 | if (u->addr) |
1023 | goto out_up; | 1019 | goto out_up; |
1024 | 1020 | ||
1025 | if (name_err) { | ||
1026 | err = name_err == -EEXIST ? -EADDRINUSE : name_err; | ||
1027 | goto out_up; | ||
1028 | } | ||
1029 | |||
1030 | err = -ENOMEM; | 1021 | err = -ENOMEM; |
1031 | addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL); | 1022 | addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL); |
1032 | if (!addr) | 1023 | if (!addr) |
@@ -1037,11 +1028,11 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1037 | addr->hash = hash ^ sk->sk_type; | 1028 | addr->hash = hash ^ sk->sk_type; |
1038 | atomic_set(&addr->refcnt, 1); | 1029 | atomic_set(&addr->refcnt, 1); |
1039 | 1030 | ||
1040 | if (dentry) { | 1031 | if (sun_path[0]) { |
1041 | struct path u_path; | 1032 | struct path path; |
1042 | umode_t mode = S_IFSOCK | | 1033 | umode_t mode = S_IFSOCK | |
1043 | (SOCK_INODE(sock)->i_mode & ~current_umask()); | 1034 | (SOCK_INODE(sock)->i_mode & ~current_umask()); |
1044 | err = unix_mknod(dentry, &path, mode, &u_path); | 1035 | err = unix_mknod(sun_path, mode, &path); |
1045 | if (err) { | 1036 | if (err) { |
1046 | if (err == -EEXIST) | 1037 | if (err == -EEXIST) |
1047 | err = -EADDRINUSE; | 1038 | err = -EADDRINUSE; |
@@ -1049,9 +1040,9 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1049 | goto out_up; | 1040 | goto out_up; |
1050 | } | 1041 | } |
1051 | addr->hash = UNIX_HASH_SIZE; | 1042 | addr->hash = UNIX_HASH_SIZE; |
1052 | hash = d_real_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1); | 1043 | hash = d_real_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE - 1); |
1053 | spin_lock(&unix_table_lock); | 1044 | spin_lock(&unix_table_lock); |
1054 | u->path = u_path; | 1045 | u->path = path; |
1055 | list = &unix_socket_table[hash]; | 1046 | list = &unix_socket_table[hash]; |
1056 | } else { | 1047 | } else { |
1057 | spin_lock(&unix_table_lock); | 1048 | spin_lock(&unix_table_lock); |
@@ -1073,11 +1064,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1073 | out_unlock: | 1064 | out_unlock: |
1074 | spin_unlock(&unix_table_lock); | 1065 | spin_unlock(&unix_table_lock); |
1075 | out_up: | 1066 | out_up: |
1076 | mutex_unlock(&u->readlock); | 1067 | mutex_unlock(&u->bindlock); |
1077 | out_path: | ||
1078 | if (dentry) | ||
1079 | done_path_create(&path, dentry); | ||
1080 | |||
1081 | out: | 1068 | out: |
1082 | return err; | 1069 | return err; |
1083 | } | 1070 | } |
@@ -1969,17 +1956,17 @@ static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page, | |||
1969 | if (false) { | 1956 | if (false) { |
1970 | alloc_skb: | 1957 | alloc_skb: |
1971 | unix_state_unlock(other); | 1958 | unix_state_unlock(other); |
1972 | mutex_unlock(&unix_sk(other)->readlock); | 1959 | mutex_unlock(&unix_sk(other)->iolock); |
1973 | newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT, | 1960 | newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT, |
1974 | &err, 0); | 1961 | &err, 0); |
1975 | if (!newskb) | 1962 | if (!newskb) |
1976 | goto err; | 1963 | goto err; |
1977 | } | 1964 | } |
1978 | 1965 | ||
1979 | /* we must acquire readlock as we modify already present | 1966 | /* we must acquire iolock as we modify already present |
1980 | * skbs in the sk_receive_queue and mess with skb->len | 1967 | * skbs in the sk_receive_queue and mess with skb->len |
1981 | */ | 1968 | */ |
1982 | err = mutex_lock_interruptible(&unix_sk(other)->readlock); | 1969 | err = mutex_lock_interruptible(&unix_sk(other)->iolock); |
1983 | if (err) { | 1970 | if (err) { |
1984 | err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS; | 1971 | err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS; |
1985 | goto err; | 1972 | goto err; |
@@ -2046,7 +2033,7 @@ alloc_skb: | |||
2046 | } | 2033 | } |
2047 | 2034 | ||
2048 | unix_state_unlock(other); | 2035 | unix_state_unlock(other); |
2049 | mutex_unlock(&unix_sk(other)->readlock); | 2036 | mutex_unlock(&unix_sk(other)->iolock); |
2050 | 2037 | ||
2051 | other->sk_data_ready(other); | 2038 | other->sk_data_ready(other); |
2052 | scm_destroy(&scm); | 2039 | scm_destroy(&scm); |
@@ -2055,7 +2042,7 @@ alloc_skb: | |||
2055 | err_state_unlock: | 2042 | err_state_unlock: |
2056 | unix_state_unlock(other); | 2043 | unix_state_unlock(other); |
2057 | err_unlock: | 2044 | err_unlock: |
2058 | mutex_unlock(&unix_sk(other)->readlock); | 2045 | mutex_unlock(&unix_sk(other)->iolock); |
2059 | err: | 2046 | err: |
2060 | kfree_skb(newskb); | 2047 | kfree_skb(newskb); |
2061 | if (send_sigpipe && !(flags & MSG_NOSIGNAL)) | 2048 | if (send_sigpipe && !(flags & MSG_NOSIGNAL)) |
@@ -2123,7 +2110,7 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, | |||
2123 | timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | 2110 | timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); |
2124 | 2111 | ||
2125 | do { | 2112 | do { |
2126 | mutex_lock(&u->readlock); | 2113 | mutex_lock(&u->iolock); |
2127 | 2114 | ||
2128 | skip = sk_peek_offset(sk, flags); | 2115 | skip = sk_peek_offset(sk, flags); |
2129 | skb = __skb_try_recv_datagram(sk, flags, &peeked, &skip, &err, | 2116 | skb = __skb_try_recv_datagram(sk, flags, &peeked, &skip, &err, |
@@ -2131,14 +2118,14 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, | |||
2131 | if (skb) | 2118 | if (skb) |
2132 | break; | 2119 | break; |
2133 | 2120 | ||
2134 | mutex_unlock(&u->readlock); | 2121 | mutex_unlock(&u->iolock); |
2135 | 2122 | ||
2136 | if (err != -EAGAIN) | 2123 | if (err != -EAGAIN) |
2137 | break; | 2124 | break; |
2138 | } while (timeo && | 2125 | } while (timeo && |
2139 | !__skb_wait_for_more_packets(sk, &err, &timeo, last)); | 2126 | !__skb_wait_for_more_packets(sk, &err, &timeo, last)); |
2140 | 2127 | ||
2141 | if (!skb) { /* implies readlock unlocked */ | 2128 | if (!skb) { /* implies iolock unlocked */ |
2142 | unix_state_lock(sk); | 2129 | unix_state_lock(sk); |
2143 | /* Signal EOF on disconnected non-blocking SEQPACKET socket. */ | 2130 | /* Signal EOF on disconnected non-blocking SEQPACKET socket. */ |
2144 | if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN && | 2131 | if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN && |
@@ -2203,7 +2190,7 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, | |||
2203 | 2190 | ||
2204 | out_free: | 2191 | out_free: |
2205 | skb_free_datagram(sk, skb); | 2192 | skb_free_datagram(sk, skb); |
2206 | mutex_unlock(&u->readlock); | 2193 | mutex_unlock(&u->iolock); |
2207 | out: | 2194 | out: |
2208 | return err; | 2195 | return err; |
2209 | } | 2196 | } |
@@ -2298,7 +2285,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state) | |||
2298 | /* Lock the socket to prevent queue disordering | 2285 | /* Lock the socket to prevent queue disordering |
2299 | * while sleeps in memcpy_tomsg | 2286 | * while sleeps in memcpy_tomsg |
2300 | */ | 2287 | */ |
2301 | mutex_lock(&u->readlock); | 2288 | mutex_lock(&u->iolock); |
2302 | 2289 | ||
2303 | if (flags & MSG_PEEK) | 2290 | if (flags & MSG_PEEK) |
2304 | skip = sk_peek_offset(sk, flags); | 2291 | skip = sk_peek_offset(sk, flags); |
@@ -2340,7 +2327,7 @@ again: | |||
2340 | break; | 2327 | break; |
2341 | } | 2328 | } |
2342 | 2329 | ||
2343 | mutex_unlock(&u->readlock); | 2330 | mutex_unlock(&u->iolock); |
2344 | 2331 | ||
2345 | timeo = unix_stream_data_wait(sk, timeo, last, | 2332 | timeo = unix_stream_data_wait(sk, timeo, last, |
2346 | last_len); | 2333 | last_len); |
@@ -2351,7 +2338,7 @@ again: | |||
2351 | goto out; | 2338 | goto out; |
2352 | } | 2339 | } |
2353 | 2340 | ||
2354 | mutex_lock(&u->readlock); | 2341 | mutex_lock(&u->iolock); |
2355 | goto redo; | 2342 | goto redo; |
2356 | unlock: | 2343 | unlock: |
2357 | unix_state_unlock(sk); | 2344 | unix_state_unlock(sk); |
@@ -2454,7 +2441,7 @@ unlock: | |||
2454 | } | 2441 | } |
2455 | } while (size); | 2442 | } while (size); |
2456 | 2443 | ||
2457 | mutex_unlock(&u->readlock); | 2444 | mutex_unlock(&u->iolock); |
2458 | if (state->msg) | 2445 | if (state->msg) |
2459 | scm_recv(sock, state->msg, &scm, flags); | 2446 | scm_recv(sock, state->msg, &scm, flags); |
2460 | else | 2447 | else |
@@ -2495,9 +2482,9 @@ static ssize_t skb_unix_socket_splice(struct sock *sk, | |||
2495 | int ret; | 2482 | int ret; |
2496 | struct unix_sock *u = unix_sk(sk); | 2483 | struct unix_sock *u = unix_sk(sk); |
2497 | 2484 | ||
2498 | mutex_unlock(&u->readlock); | 2485 | mutex_unlock(&u->iolock); |
2499 | ret = splice_to_pipe(pipe, spd); | 2486 | ret = splice_to_pipe(pipe, spd); |
2500 | mutex_lock(&u->readlock); | 2487 | mutex_lock(&u->iolock); |
2501 | 2488 | ||
2502 | return ret; | 2489 | return ret; |
2503 | } | 2490 | } |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f02653a08993..4809f4d2cdcc 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -6978,7 +6978,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) | |||
6978 | 6978 | ||
6979 | params.n_counter_offsets_presp = len / sizeof(u16); | 6979 | params.n_counter_offsets_presp = len / sizeof(u16); |
6980 | if (rdev->wiphy.max_num_csa_counters && | 6980 | if (rdev->wiphy.max_num_csa_counters && |
6981 | (params.n_counter_offsets_beacon > | 6981 | (params.n_counter_offsets_presp > |
6982 | rdev->wiphy.max_num_csa_counters)) | 6982 | rdev->wiphy.max_num_csa_counters)) |
6983 | return -EINVAL; | 6983 | return -EINVAL; |
6984 | 6984 | ||
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index dbb2738e356a..6250b1cfcde5 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c | |||
@@ -958,29 +958,8 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, | |||
958 | return private(dev, iwr, cmd, info, handler); | 958 | return private(dev, iwr, cmd, info, handler); |
959 | } | 959 | } |
960 | /* Old driver API : call driver ioctl handler */ | 960 | /* Old driver API : call driver ioctl handler */ |
961 | if (dev->netdev_ops->ndo_do_ioctl) { | 961 | if (dev->netdev_ops->ndo_do_ioctl) |
962 | #ifdef CONFIG_COMPAT | 962 | return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd); |
963 | if (info->flags & IW_REQUEST_FLAG_COMPAT) { | ||
964 | int ret = 0; | ||
965 | struct iwreq iwr_lcl; | ||
966 | struct compat_iw_point *iwp_compat = (void *) &iwr->u.data; | ||
967 | |||
968 | memcpy(&iwr_lcl, iwr, sizeof(struct iwreq)); | ||
969 | iwr_lcl.u.data.pointer = compat_ptr(iwp_compat->pointer); | ||
970 | iwr_lcl.u.data.length = iwp_compat->length; | ||
971 | iwr_lcl.u.data.flags = iwp_compat->flags; | ||
972 | |||
973 | ret = dev->netdev_ops->ndo_do_ioctl(dev, (void *) &iwr_lcl, cmd); | ||
974 | |||
975 | iwp_compat->pointer = ptr_to_compat(iwr_lcl.u.data.pointer); | ||
976 | iwp_compat->length = iwr_lcl.u.data.length; | ||
977 | iwp_compat->flags = iwr_lcl.u.data.flags; | ||
978 | |||
979 | return ret; | ||
980 | } else | ||
981 | #endif | ||
982 | return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd); | ||
983 | } | ||
984 | return -EOPNOTSUPP; | 963 | return -EOPNOTSUPP; |
985 | } | 964 | } |
986 | 965 | ||
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 1c4ad477ce93..6e3f0254d8a1 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
@@ -207,15 +207,15 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
207 | family = XFRM_SPI_SKB_CB(skb)->family; | 207 | family = XFRM_SPI_SKB_CB(skb)->family; |
208 | 208 | ||
209 | /* if tunnel is present override skb->mark value with tunnel i_key */ | 209 | /* if tunnel is present override skb->mark value with tunnel i_key */ |
210 | if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) { | 210 | switch (family) { |
211 | switch (family) { | 211 | case AF_INET: |
212 | case AF_INET: | 212 | if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) |
213 | mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key); | 213 | mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key); |
214 | break; | 214 | break; |
215 | case AF_INET6: | 215 | case AF_INET6: |
216 | if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6) | ||
216 | mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key); | 217 | mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key); |
217 | break; | 218 | break; |
218 | } | ||
219 | } | 219 | } |
220 | 220 | ||
221 | /* Allocate new secpath or COW existing one. */ | 221 | /* Allocate new secpath or COW existing one. */ |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index b5e665b3cfb0..45f9cf97ea25 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -626,6 +626,10 @@ static void xfrm_hash_rebuild(struct work_struct *work) | |||
626 | 626 | ||
627 | /* re-insert all policies by order of creation */ | 627 | /* re-insert all policies by order of creation */ |
628 | list_for_each_entry_reverse(policy, &net->xfrm.policy_all, walk.all) { | 628 | list_for_each_entry_reverse(policy, &net->xfrm.policy_all, walk.all) { |
629 | if (xfrm_policy_id2dir(policy->index) >= XFRM_POLICY_MAX) { | ||
630 | /* skip socket policies */ | ||
631 | continue; | ||
632 | } | ||
629 | newpos = NULL; | 633 | newpos = NULL; |
630 | chain = policy_hash_bysel(net, &policy->selector, | 634 | chain = policy_hash_bysel(net, &policy->selector, |
631 | policy->family, | 635 | policy->family, |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 9895a8c56d8c..a30f898dc1c5 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -332,6 +332,7 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x) | |||
332 | { | 332 | { |
333 | tasklet_hrtimer_cancel(&x->mtimer); | 333 | tasklet_hrtimer_cancel(&x->mtimer); |
334 | del_timer_sync(&x->rtimer); | 334 | del_timer_sync(&x->rtimer); |
335 | kfree(x->aead); | ||
335 | kfree(x->aalg); | 336 | kfree(x->aalg); |
336 | kfree(x->ealg); | 337 | kfree(x->ealg); |
337 | kfree(x->calg); | 338 | kfree(x->calg); |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index d516845e16e3..08892091cfe3 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -581,9 +581,12 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, | |||
581 | if (err) | 581 | if (err) |
582 | goto error; | 582 | goto error; |
583 | 583 | ||
584 | if (attrs[XFRMA_SEC_CTX] && | 584 | if (attrs[XFRMA_SEC_CTX]) { |
585 | security_xfrm_state_alloc(x, nla_data(attrs[XFRMA_SEC_CTX]))) | 585 | err = security_xfrm_state_alloc(x, |
586 | goto error; | 586 | nla_data(attrs[XFRMA_SEC_CTX])); |
587 | if (err) | ||
588 | goto error; | ||
589 | } | ||
587 | 590 | ||
588 | if ((err = xfrm_alloc_replay_state_esn(&x->replay_esn, &x->preplay_esn, | 591 | if ((err = xfrm_alloc_replay_state_esn(&x->replay_esn, &x->preplay_esn, |
589 | attrs[XFRMA_REPLAY_ESN_VAL]))) | 592 | attrs[XFRMA_REPLAY_ESN_VAL]))) |
@@ -896,7 +899,8 @@ static int xfrm_dump_sa_done(struct netlink_callback *cb) | |||
896 | struct sock *sk = cb->skb->sk; | 899 | struct sock *sk = cb->skb->sk; |
897 | struct net *net = sock_net(sk); | 900 | struct net *net = sock_net(sk); |
898 | 901 | ||
899 | xfrm_state_walk_done(walk, net); | 902 | if (cb->args[0]) |
903 | xfrm_state_walk_done(walk, net); | ||
900 | return 0; | 904 | return 0; |
901 | } | 905 | } |
902 | 906 | ||
@@ -921,8 +925,6 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb) | |||
921 | u8 proto = 0; | 925 | u8 proto = 0; |
922 | int err; | 926 | int err; |
923 | 927 | ||
924 | cb->args[0] = 1; | ||
925 | |||
926 | err = nlmsg_parse(cb->nlh, 0, attrs, XFRMA_MAX, | 928 | err = nlmsg_parse(cb->nlh, 0, attrs, XFRMA_MAX, |
927 | xfrma_policy); | 929 | xfrma_policy); |
928 | if (err < 0) | 930 | if (err < 0) |
@@ -939,6 +941,7 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb) | |||
939 | proto = nla_get_u8(attrs[XFRMA_PROTO]); | 941 | proto = nla_get_u8(attrs[XFRMA_PROTO]); |
940 | 942 | ||
941 | xfrm_state_walk_init(walk, proto, filter); | 943 | xfrm_state_walk_init(walk, proto, filter); |
944 | cb->args[0] = 1; | ||
942 | } | 945 | } |
943 | 946 | ||
944 | (void) xfrm_state_walk(net, walk, dump_one_state, &info); | 947 | (void) xfrm_state_walk(net, walk, dump_one_state, &info); |
@@ -2051,9 +2054,6 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2051 | if (up->hard) { | 2054 | if (up->hard) { |
2052 | xfrm_policy_delete(xp, p->dir); | 2055 | xfrm_policy_delete(xp, p->dir); |
2053 | xfrm_audit_policy_delete(xp, 1, true); | 2056 | xfrm_audit_policy_delete(xp, 1, true); |
2054 | } else { | ||
2055 | // reset the timers here? | ||
2056 | WARN(1, "Don't know what to do with soft policy expire\n"); | ||
2057 | } | 2057 | } |
2058 | km_policy_expired(xp, p->dir, up->hard, nlh->nlmsg_pid); | 2058 | km_policy_expired(xp, p->dir, up->hard, nlh->nlmsg_pid); |
2059 | 2059 | ||
@@ -2117,7 +2117,7 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2117 | 2117 | ||
2118 | err = verify_newpolicy_info(&ua->policy); | 2118 | err = verify_newpolicy_info(&ua->policy); |
2119 | if (err) | 2119 | if (err) |
2120 | goto bad_policy; | 2120 | goto free_state; |
2121 | 2121 | ||
2122 | /* build an XP */ | 2122 | /* build an XP */ |
2123 | xp = xfrm_policy_construct(net, &ua->policy, attrs, &err); | 2123 | xp = xfrm_policy_construct(net, &ua->policy, attrs, &err); |
@@ -2149,8 +2149,6 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2149 | 2149 | ||
2150 | return 0; | 2150 | return 0; |
2151 | 2151 | ||
2152 | bad_policy: | ||
2153 | WARN(1, "BAD policy passed\n"); | ||
2154 | free_state: | 2152 | free_state: |
2155 | kfree(x); | 2153 | kfree(x); |
2156 | nomem: | 2154 | nomem: |
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 4de3cc42fc50..206a6b346a8d 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
@@ -3570,15 +3570,6 @@ sub process { | |||
3570 | } | 3570 | } |
3571 | } | 3571 | } |
3572 | 3572 | ||
3573 | # check for uses of DEFINE_PCI_DEVICE_TABLE | ||
3574 | if ($line =~ /\bDEFINE_PCI_DEVICE_TABLE\s*\(\s*(\w+)\s*\)\s*=/) { | ||
3575 | if (WARN("DEFINE_PCI_DEVICE_TABLE", | ||
3576 | "Prefer struct pci_device_id over deprecated DEFINE_PCI_DEVICE_TABLE\n" . $herecurr) && | ||
3577 | $fix) { | ||
3578 | $fixed[$fixlinenr] =~ s/\b(?:static\s+|)DEFINE_PCI_DEVICE_TABLE\s*\(\s*(\w+)\s*\)\s*=\s*/static const struct pci_device_id $1\[\] = /; | ||
3579 | } | ||
3580 | } | ||
3581 | |||
3582 | # check for new typedefs, only function parameters and sparse annotations | 3573 | # check for new typedefs, only function parameters and sparse annotations |
3583 | # make sense. | 3574 | # make sense. |
3584 | if ($line =~ /\btypedef\s/ && | 3575 | if ($line =~ /\btypedef\s/ && |
diff --git a/scripts/faddr2line b/scripts/faddr2line new file mode 100755 index 000000000000..450b33257339 --- /dev/null +++ b/scripts/faddr2line | |||
@@ -0,0 +1,177 @@ | |||
1 | #!/bin/bash | ||
2 | # | ||
3 | # Translate stack dump function offsets. | ||
4 | # | ||
5 | # addr2line doesn't work with KASLR addresses. This works similarly to | ||
6 | # addr2line, but instead takes the 'func+0x123' format as input: | ||
7 | # | ||
8 | # $ ./scripts/faddr2line ~/k/vmlinux meminfo_proc_show+0x5/0x568 | ||
9 | # meminfo_proc_show+0x5/0x568: | ||
10 | # meminfo_proc_show at fs/proc/meminfo.c:27 | ||
11 | # | ||
12 | # If the address is part of an inlined function, the full inline call chain is | ||
13 | # printed: | ||
14 | # | ||
15 | # $ ./scripts/faddr2line ~/k/vmlinux native_write_msr+0x6/0x27 | ||
16 | # native_write_msr+0x6/0x27: | ||
17 | # arch_static_branch at arch/x86/include/asm/msr.h:121 | ||
18 | # (inlined by) static_key_false at include/linux/jump_label.h:125 | ||
19 | # (inlined by) native_write_msr at arch/x86/include/asm/msr.h:125 | ||
20 | # | ||
21 | # The function size after the '/' in the input is optional, but recommended. | ||
22 | # It's used to help disambiguate any duplicate symbol names, which can occur | ||
23 | # rarely. If the size is omitted for a duplicate symbol then it's possible for | ||
24 | # multiple code sites to be printed: | ||
25 | # | ||
26 | # $ ./scripts/faddr2line ~/k/vmlinux raw_ioctl+0x5 | ||
27 | # raw_ioctl+0x5/0x20: | ||
28 | # raw_ioctl at drivers/char/raw.c:122 | ||
29 | # | ||
30 | # raw_ioctl+0x5/0xb1: | ||
31 | # raw_ioctl at net/ipv4/raw.c:876 | ||
32 | # | ||
33 | # Multiple addresses can be specified on a single command line: | ||
34 | # | ||
35 | # $ ./scripts/faddr2line ~/k/vmlinux type_show+0x10/45 free_reserved_area+0x90 | ||
36 | # type_show+0x10/0x2d: | ||
37 | # type_show at drivers/video/backlight/backlight.c:213 | ||
38 | # | ||
39 | # free_reserved_area+0x90/0x123: | ||
40 | # free_reserved_area at mm/page_alloc.c:6429 (discriminator 2) | ||
41 | |||
42 | |||
43 | set -o errexit | ||
44 | set -o nounset | ||
45 | |||
46 | command -v awk >/dev/null 2>&1 || die "awk isn't installed" | ||
47 | command -v readelf >/dev/null 2>&1 || die "readelf isn't installed" | ||
48 | command -v addr2line >/dev/null 2>&1 || die "addr2line isn't installed" | ||
49 | |||
50 | usage() { | ||
51 | echo "usage: faddr2line <object file> <func+offset> <func+offset>..." >&2 | ||
52 | exit 1 | ||
53 | } | ||
54 | |||
55 | warn() { | ||
56 | echo "$1" >&2 | ||
57 | } | ||
58 | |||
59 | die() { | ||
60 | echo "ERROR: $1" >&2 | ||
61 | exit 1 | ||
62 | } | ||
63 | |||
64 | # Try to figure out the source directory prefix so we can remove it from the | ||
65 | # addr2line output. HACK ALERT: This assumes that start_kernel() is in | ||
66 | # kernel/init.c! This only works for vmlinux. Otherwise it falls back to | ||
67 | # printing the absolute path. | ||
68 | find_dir_prefix() { | ||
69 | local objfile=$1 | ||
70 | |||
71 | local start_kernel_addr=$(readelf -sW $objfile | awk '$8 == "start_kernel" {printf "0x%s", $2}') | ||
72 | [[ -z $start_kernel_addr ]] && return | ||
73 | |||
74 | local file_line=$(addr2line -e $objfile $start_kernel_addr) | ||
75 | [[ -z $file_line ]] && return | ||
76 | |||
77 | local prefix=${file_line%init/main.c:*} | ||
78 | if [[ -z $prefix ]] || [[ $prefix = $file_line ]]; then | ||
79 | return | ||
80 | fi | ||
81 | |||
82 | DIR_PREFIX=$prefix | ||
83 | return 0 | ||
84 | } | ||
85 | |||
86 | __faddr2line() { | ||
87 | local objfile=$1 | ||
88 | local func_addr=$2 | ||
89 | local dir_prefix=$3 | ||
90 | local print_warnings=$4 | ||
91 | |||
92 | local func=${func_addr%+*} | ||
93 | local offset=${func_addr#*+} | ||
94 | offset=${offset%/*} | ||
95 | local size= | ||
96 | [[ $func_addr =~ "/" ]] && size=${func_addr#*/} | ||
97 | |||
98 | if [[ -z $func ]] || [[ -z $offset ]] || [[ $func = $func_addr ]]; then | ||
99 | warn "bad func+offset $func_addr" | ||
100 | DONE=1 | ||
101 | return | ||
102 | fi | ||
103 | |||
104 | # Go through each of the object's symbols which match the func name. | ||
105 | # In rare cases there might be duplicates. | ||
106 | while read symbol; do | ||
107 | local fields=($symbol) | ||
108 | local sym_base=0x${fields[1]} | ||
109 | local sym_size=${fields[2]} | ||
110 | local sym_type=${fields[3]} | ||
111 | |||
112 | # calculate the address | ||
113 | local addr=$(($sym_base + $offset)) | ||
114 | if [[ -z $addr ]] || [[ $addr = 0 ]]; then | ||
115 | warn "bad address: $sym_base + $offset" | ||
116 | DONE=1 | ||
117 | return | ||
118 | fi | ||
119 | local hexaddr=0x$(printf %x $addr) | ||
120 | |||
121 | # weed out non-function symbols | ||
122 | if [[ $sym_type != "FUNC" ]]; then | ||
123 | [[ $print_warnings = 1 ]] && | ||
124 | echo "skipping $func address at $hexaddr due to non-function symbol" | ||
125 | continue | ||
126 | fi | ||
127 | |||
128 | # if the user provided a size, make sure it matches the symbol's size | ||
129 | if [[ -n $size ]] && [[ $size -ne $sym_size ]]; then | ||
130 | [[ $print_warnings = 1 ]] && | ||
131 | echo "skipping $func address at $hexaddr due to size mismatch ($size != $sym_size)" | ||
132 | continue; | ||
133 | fi | ||
134 | |||
135 | # make sure the provided offset is within the symbol's range | ||
136 | if [[ $offset -gt $sym_size ]]; then | ||
137 | [[ $print_warnings = 1 ]] && | ||
138 | echo "skipping $func address at $hexaddr due to size mismatch ($offset > $sym_size)" | ||
139 | continue | ||
140 | fi | ||
141 | |||
142 | # separate multiple entries with a blank line | ||
143 | [[ $FIRST = 0 ]] && echo | ||
144 | FIRST=0 | ||
145 | |||
146 | local hexsize=0x$(printf %x $sym_size) | ||
147 | echo "$func+$offset/$hexsize:" | ||
148 | addr2line -fpie $objfile $hexaddr | sed "s; $dir_prefix\(\./\)*; ;" | ||
149 | DONE=1 | ||
150 | |||
151 | done < <(readelf -sW $objfile | awk -v f=$func '$8 == f {print}') | ||
152 | } | ||
153 | |||
154 | [[ $# -lt 2 ]] && usage | ||
155 | |||
156 | objfile=$1 | ||
157 | [[ ! -f $objfile ]] && die "can't find objfile $objfile" | ||
158 | shift | ||
159 | |||
160 | DIR_PREFIX=supercalifragilisticexpialidocious | ||
161 | find_dir_prefix $objfile | ||
162 | |||
163 | FIRST=1 | ||
164 | while [[ $# -gt 0 ]]; do | ||
165 | func_addr=$1 | ||
166 | shift | ||
167 | |||
168 | # print any matches found | ||
169 | DONE=0 | ||
170 | __faddr2line $objfile $func_addr $DIR_PREFIX 0 | ||
171 | |||
172 | # if no match was found, print warnings | ||
173 | if [[ $DONE = 0 ]]; then | ||
174 | __faddr2line $objfile $func_addr $DIR_PREFIX 1 | ||
175 | warn "no match for $func_addr" | ||
176 | fi | ||
177 | done | ||
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 49a00d54b835..aed4511f0304 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl | |||
@@ -2136,9 +2136,11 @@ sub vcs_file_exists { | |||
2136 | 2136 | ||
2137 | my $cmd = $VCS_cmds{"file_exists_cmd"}; | 2137 | my $cmd = $VCS_cmds{"file_exists_cmd"}; |
2138 | $cmd =~ s/(\$\w+)/$1/eeg; # interpolate $cmd | 2138 | $cmd =~ s/(\$\w+)/$1/eeg; # interpolate $cmd |
2139 | 2139 | $cmd .= " 2>&1"; | |
2140 | $exists = &{$VCS_cmds{"execute_cmd"}}($cmd); | 2140 | $exists = &{$VCS_cmds{"execute_cmd"}}($cmd); |
2141 | 2141 | ||
2142 | return 0 if ($? != 0); | ||
2143 | |||
2142 | return $exists; | 2144 | return $exists; |
2143 | } | 2145 | } |
2144 | 2146 | ||
diff --git a/scripts/package/builddeb b/scripts/package/builddeb index e1c09e2f9be7..8ea9fd2b6573 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb | |||
@@ -332,7 +332,9 @@ if grep -q '^CONFIG_STACK_VALIDATION=y' $KCONFIG_CONFIG ; then | |||
332 | (cd $objtree; find tools/objtool -type f -executable) >> "$objtree/debian/hdrobjfiles" | 332 | (cd $objtree; find tools/objtool -type f -executable) >> "$objtree/debian/hdrobjfiles" |
333 | fi | 333 | fi |
334 | (cd $objtree; find arch/$SRCARCH/include Module.symvers include scripts -type f) >> "$objtree/debian/hdrobjfiles" | 334 | (cd $objtree; find arch/$SRCARCH/include Module.symvers include scripts -type f) >> "$objtree/debian/hdrobjfiles" |
335 | (cd $objtree; find scripts/gcc-plugins -name \*.so -o -name gcc-common.h) >> "$objtree/debian/hdrobjfiles" | 335 | if grep -q '^CONFIG_GCC_PLUGINS=y' $KCONFIG_CONFIG ; then |
336 | (cd $objtree; find scripts/gcc-plugins -name \*.so -o -name gcc-common.h) >> "$objtree/debian/hdrobjfiles" | ||
337 | fi | ||
336 | destdir=$kernel_headers_dir/usr/src/linux-headers-$version | 338 | destdir=$kernel_headers_dir/usr/src/linux-headers-$version |
337 | mkdir -p "$destdir" | 339 | mkdir -p "$destdir" |
338 | (cd $srctree; tar -c -f - -T -) < "$objtree/debian/hdrsrcfiles" | (cd $destdir; tar -xf -) | 340 | (cd $srctree; tar -c -f - -T -) < "$objtree/debian/hdrsrcfiles" | (cd $destdir; tar -xf -) |
diff --git a/scripts/tags.sh b/scripts/tags.sh index ed7eef24ef89..b3775a9604ea 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh | |||
@@ -206,7 +206,6 @@ regex_c=( | |||
206 | '/\<DEFINE_PER_CPU_SHARED_ALIGNED([^,]*, *\([[:alnum:]_]*\)/\1/v/' | 206 | '/\<DEFINE_PER_CPU_SHARED_ALIGNED([^,]*, *\([[:alnum:]_]*\)/\1/v/' |
207 | '/\<DECLARE_WAIT_QUEUE_HEAD(\([[:alnum:]_]*\)/\1/v/' | 207 | '/\<DECLARE_WAIT_QUEUE_HEAD(\([[:alnum:]_]*\)/\1/v/' |
208 | '/\<DECLARE_\(TASKLET\|WORK\|DELAYED_WORK\)(\([[:alnum:]_]*\)/\2/v/' | 208 | '/\<DECLARE_\(TASKLET\|WORK\|DELAYED_WORK\)(\([[:alnum:]_]*\)/\2/v/' |
209 | '/\<DEFINE_PCI_DEVICE_TABLE(\([[:alnum:]_]*\)/\1/v/' | ||
210 | '/\(^\s\)OFFSET(\([[:alnum:]_]*\)/\2/v/' | 209 | '/\(^\s\)OFFSET(\([[:alnum:]_]*\)/\2/v/' |
211 | '/\(^\s\)DEFINE(\([[:alnum:]_]*\)/\2/v/' | 210 | '/\(^\s\)DEFINE(\([[:alnum:]_]*\)/\2/v/' |
212 | '/\<DEFINE_HASHTABLE(\([[:alnum:]_]*\)/\1/v/' | 211 | '/\<DEFINE_HASHTABLE(\([[:alnum:]_]*\)/\1/v/' |
diff --git a/security/Kconfig b/security/Kconfig index da10d9b573a4..118f4549404e 100644 --- a/security/Kconfig +++ b/security/Kconfig | |||
@@ -147,6 +147,17 @@ config HARDENED_USERCOPY | |||
147 | or are part of the kernel text. This kills entire classes | 147 | or are part of the kernel text. This kills entire classes |
148 | of heap overflow exploits and similar kernel memory exposures. | 148 | of heap overflow exploits and similar kernel memory exposures. |
149 | 149 | ||
150 | config HARDENED_USERCOPY_PAGESPAN | ||
151 | bool "Refuse to copy allocations that span multiple pages" | ||
152 | depends on HARDENED_USERCOPY | ||
153 | depends on EXPERT | ||
154 | help | ||
155 | When a multi-page allocation is done without __GFP_COMP, | ||
156 | hardened usercopy will reject attempts to copy it. There are, | ||
157 | however, several cases of this in the kernel that have not all | ||
158 | been removed. This config is intended to be used only while | ||
159 | trying to find such users. | ||
160 | |||
150 | source security/selinux/Kconfig | 161 | source security/selinux/Kconfig |
151 | source security/smack/Kconfig | 162 | source security/smack/Kconfig |
152 | source security/tomoyo/Kconfig | 163 | source security/tomoyo/Kconfig |
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c index 5adbfc32242f..17a06105ccb6 100644 --- a/security/keys/encrypted-keys/encrypted.c +++ b/security/keys/encrypted-keys/encrypted.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/rcupdate.h> | 29 | #include <linux/rcupdate.h> |
30 | #include <linux/scatterlist.h> | 30 | #include <linux/scatterlist.h> |
31 | #include <linux/ctype.h> | 31 | #include <linux/ctype.h> |
32 | #include <crypto/aes.h> | ||
32 | #include <crypto/hash.h> | 33 | #include <crypto/hash.h> |
33 | #include <crypto/sha.h> | 34 | #include <crypto/sha.h> |
34 | #include <crypto/skcipher.h> | 35 | #include <crypto/skcipher.h> |
@@ -478,6 +479,7 @@ static int derived_key_encrypt(struct encrypted_key_payload *epayload, | |||
478 | struct crypto_skcipher *tfm; | 479 | struct crypto_skcipher *tfm; |
479 | struct skcipher_request *req; | 480 | struct skcipher_request *req; |
480 | unsigned int encrypted_datalen; | 481 | unsigned int encrypted_datalen; |
482 | u8 iv[AES_BLOCK_SIZE]; | ||
481 | unsigned int padlen; | 483 | unsigned int padlen; |
482 | char pad[16]; | 484 | char pad[16]; |
483 | int ret; | 485 | int ret; |
@@ -500,8 +502,8 @@ static int derived_key_encrypt(struct encrypted_key_payload *epayload, | |||
500 | sg_init_table(sg_out, 1); | 502 | sg_init_table(sg_out, 1); |
501 | sg_set_buf(sg_out, epayload->encrypted_data, encrypted_datalen); | 503 | sg_set_buf(sg_out, epayload->encrypted_data, encrypted_datalen); |
502 | 504 | ||
503 | skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen, | 505 | memcpy(iv, epayload->iv, sizeof(iv)); |
504 | epayload->iv); | 506 | skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen, iv); |
505 | ret = crypto_skcipher_encrypt(req); | 507 | ret = crypto_skcipher_encrypt(req); |
506 | tfm = crypto_skcipher_reqtfm(req); | 508 | tfm = crypto_skcipher_reqtfm(req); |
507 | skcipher_request_free(req); | 509 | skcipher_request_free(req); |
@@ -581,6 +583,7 @@ static int derived_key_decrypt(struct encrypted_key_payload *epayload, | |||
581 | struct crypto_skcipher *tfm; | 583 | struct crypto_skcipher *tfm; |
582 | struct skcipher_request *req; | 584 | struct skcipher_request *req; |
583 | unsigned int encrypted_datalen; | 585 | unsigned int encrypted_datalen; |
586 | u8 iv[AES_BLOCK_SIZE]; | ||
584 | char pad[16]; | 587 | char pad[16]; |
585 | int ret; | 588 | int ret; |
586 | 589 | ||
@@ -599,8 +602,8 @@ static int derived_key_decrypt(struct encrypted_key_payload *epayload, | |||
599 | epayload->decrypted_datalen); | 602 | epayload->decrypted_datalen); |
600 | sg_set_buf(&sg_out[1], pad, sizeof pad); | 603 | sg_set_buf(&sg_out[1], pad, sizeof pad); |
601 | 604 | ||
602 | skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen, | 605 | memcpy(iv, epayload->iv, sizeof(iv)); |
603 | epayload->iv); | 606 | skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen, iv); |
604 | ret = crypto_skcipher_decrypt(req); | 607 | ret = crypto_skcipher_decrypt(req); |
605 | tfm = crypto_skcipher_reqtfm(req); | 608 | tfm = crypto_skcipher_reqtfm(req); |
606 | skcipher_request_free(req); | 609 | skcipher_request_free(req); |
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index d1fb035f44db..504c7cd7f58a 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c | |||
@@ -897,7 +897,7 @@ static int acp_dma_close(struct snd_pcm_substream *substream) | |||
897 | return 0; | 897 | return 0; |
898 | } | 898 | } |
899 | 899 | ||
900 | static struct snd_pcm_ops acp_dma_ops = { | 900 | static const struct snd_pcm_ops acp_dma_ops = { |
901 | .open = acp_dma_open, | 901 | .open = acp_dma_open, |
902 | .close = acp_dma_close, | 902 | .close = acp_dma_close, |
903 | .ioctl = snd_pcm_lib_ioctl, | 903 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c index 6d9b8b44e2da..89ac5f5a93eb 100644 --- a/sound/soc/atmel/atmel-classd.c +++ b/sound/soc/atmel/atmel-classd.c | |||
@@ -308,9 +308,11 @@ static struct regmap *atmel_classd_codec_get_remap(struct device *dev) | |||
308 | 308 | ||
309 | static struct snd_soc_codec_driver soc_codec_dev_classd = { | 309 | static struct snd_soc_codec_driver soc_codec_dev_classd = { |
310 | .probe = atmel_classd_codec_probe, | 310 | .probe = atmel_classd_codec_probe, |
311 | .controls = atmel_classd_snd_controls, | ||
312 | .num_controls = ARRAY_SIZE(atmel_classd_snd_controls), | ||
313 | .get_regmap = atmel_classd_codec_get_remap, | 311 | .get_regmap = atmel_classd_codec_get_remap, |
312 | .component_driver = { | ||
313 | .controls = atmel_classd_snd_controls, | ||
314 | .num_controls = ARRAY_SIZE(atmel_classd_snd_controls), | ||
315 | }, | ||
314 | }; | 316 | }; |
315 | 317 | ||
316 | /* codec dai component */ | 318 | /* codec dai component */ |
diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c index da861b44413f..91b7069c3499 100644 --- a/sound/soc/atmel/atmel-pcm-pdc.c +++ b/sound/soc/atmel/atmel-pcm-pdc.c | |||
@@ -381,7 +381,7 @@ static int atmel_pcm_close(struct snd_pcm_substream *substream) | |||
381 | return 0; | 381 | return 0; |
382 | } | 382 | } |
383 | 383 | ||
384 | static struct snd_pcm_ops atmel_pcm_ops = { | 384 | static const struct snd_pcm_ops atmel_pcm_ops = { |
385 | .open = atmel_pcm_open, | 385 | .open = atmel_pcm_open, |
386 | .close = atmel_pcm_close, | 386 | .close = atmel_pcm_close, |
387 | .ioctl = snd_pcm_lib_ioctl, | 387 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/soc/atmel/atmel-pdmic.c b/sound/soc/atmel/atmel-pdmic.c index 5f56da60c92f..c917df7715d1 100644 --- a/sound/soc/atmel/atmel-pdmic.c +++ b/sound/soc/atmel/atmel-pdmic.c | |||
@@ -80,7 +80,7 @@ static struct atmel_pdmic_pdata *atmel_pdmic_dt_init(struct device *dev) | |||
80 | 80 | ||
81 | if (pdata->mic_max_freq < pdata->mic_min_freq) { | 81 | if (pdata->mic_max_freq < pdata->mic_min_freq) { |
82 | dev_err(dev, | 82 | dev_err(dev, |
83 | "mic-max-freq should not less than mic-min-freq\n"); | 83 | "mic-max-freq should not be less than mic-min-freq\n"); |
84 | return ERR_PTR(-EINVAL); | 84 | return ERR_PTR(-EINVAL); |
85 | } | 85 | } |
86 | 86 | ||
@@ -115,8 +115,10 @@ static int atmel_pdmic_cpu_dai_startup(struct snd_pcm_substream *substream, | |||
115 | return ret; | 115 | return ret; |
116 | 116 | ||
117 | ret = clk_prepare_enable(dd->pclk); | 117 | ret = clk_prepare_enable(dd->pclk); |
118 | if (ret) | 118 | if (ret) { |
119 | clk_disable_unprepare(dd->gclk); | ||
119 | return ret; | 120 | return ret; |
121 | } | ||
120 | 122 | ||
121 | /* Clear all bits in the Control Register(PDMIC_CR) */ | 123 | /* Clear all bits in the Control Register(PDMIC_CR) */ |
122 | regmap_write(dd->regmap, PDMIC_CR, 0); | 124 | regmap_write(dd->regmap, PDMIC_CR, 0); |
@@ -283,7 +285,7 @@ static const DECLARE_TLV_DB_RANGE(mic_gain_tlv, | |||
283 | 8, ARRAY_SIZE(mic_gain_table)-1, TLV_DB_SCALE_ITEM(-6500, 100, 0), | 285 | 8, ARRAY_SIZE(mic_gain_table)-1, TLV_DB_SCALE_ITEM(-6500, 100, 0), |
284 | ); | 286 | ); |
285 | 287 | ||
286 | int pdmic_get_mic_volsw(struct snd_kcontrol *kcontrol, | 288 | static int pdmic_get_mic_volsw(struct snd_kcontrol *kcontrol, |
287 | struct snd_ctl_elem_value *ucontrol) | 289 | struct snd_ctl_elem_value *ucontrol) |
288 | { | 290 | { |
289 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | 291 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
@@ -357,8 +359,10 @@ static int atmel_pdmic_codec_probe(struct snd_soc_codec *codec) | |||
357 | 359 | ||
358 | static struct snd_soc_codec_driver soc_codec_dev_pdmic = { | 360 | static struct snd_soc_codec_driver soc_codec_dev_pdmic = { |
359 | .probe = atmel_pdmic_codec_probe, | 361 | .probe = atmel_pdmic_codec_probe, |
360 | .controls = atmel_pdmic_snd_controls, | 362 | .component_driver = { |
361 | .num_controls = ARRAY_SIZE(atmel_pdmic_snd_controls), | 363 | .controls = atmel_pdmic_snd_controls, |
364 | .num_controls = ARRAY_SIZE(atmel_pdmic_snd_controls), | ||
365 | }, | ||
362 | }; | 366 | }; |
363 | 367 | ||
364 | /* codec dai component */ | 368 | /* codec dai component */ |
@@ -596,7 +600,7 @@ static int atmel_pdmic_probe(struct platform_device *pdev) | |||
596 | dd->irq = platform_get_irq(pdev, 0); | 600 | dd->irq = platform_get_irq(pdev, 0); |
597 | if (dd->irq < 0) { | 601 | if (dd->irq < 0) { |
598 | ret = dd->irq; | 602 | ret = dd->irq; |
599 | dev_err(dev, "failed to could not get irq: %d\n", ret); | 603 | dev_err(dev, "failed to get irq: %d\n", ret); |
600 | return ret; | 604 | return ret; |
601 | } | 605 | } |
602 | 606 | ||
@@ -614,7 +618,7 @@ static int atmel_pdmic_probe(struct platform_device *pdev) | |||
614 | return ret; | 618 | return ret; |
615 | } | 619 | } |
616 | 620 | ||
617 | /* The gclk clock frequency must always be tree times | 621 | /* The gclk clock frequency must always be three times |
618 | * lower than the pclk clock frequency | 622 | * lower than the pclk clock frequency |
619 | */ | 623 | */ |
620 | ret = clk_set_rate(dd->gclk, clk_get_rate(dd->pclk)/3); | 624 | ret = clk_set_rate(dd->gclk, clk_get_rate(dd->pclk)/3); |
@@ -649,7 +653,7 @@ static int atmel_pdmic_probe(struct platform_device *pdev) | |||
649 | return ret; | 653 | return ret; |
650 | } | 654 | } |
651 | 655 | ||
652 | /* Get the minimal and maximal sample rate that micphone supports */ | 656 | /* Get the minimal and maximal sample rate that the microphone supports */ |
653 | atmel_pdmic_get_sample_rate(dd, &rate_min, &rate_max); | 657 | atmel_pdmic_get_sample_rate(dd, &rate_min, &rate_max); |
654 | 658 | ||
655 | /* register cpu dai */ | 659 | /* register cpu dai */ |
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index e8bed6b0c9db..b013a4c62b63 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c | |||
@@ -1361,12 +1361,14 @@ static struct snd_soc_codec_driver soc_codec_dev_pm860x = { | |||
1361 | .set_bias_level = pm860x_set_bias_level, | 1361 | .set_bias_level = pm860x_set_bias_level, |
1362 | .get_regmap = pm860x_get_regmap, | 1362 | .get_regmap = pm860x_get_regmap, |
1363 | 1363 | ||
1364 | .controls = pm860x_snd_controls, | 1364 | .component_driver = { |
1365 | .num_controls = ARRAY_SIZE(pm860x_snd_controls), | 1365 | .controls = pm860x_snd_controls, |
1366 | .dapm_widgets = pm860x_dapm_widgets, | 1366 | .num_controls = ARRAY_SIZE(pm860x_snd_controls), |
1367 | .num_dapm_widgets = ARRAY_SIZE(pm860x_dapm_widgets), | 1367 | .dapm_widgets = pm860x_dapm_widgets, |
1368 | .dapm_routes = pm860x_dapm_routes, | 1368 | .num_dapm_widgets = ARRAY_SIZE(pm860x_dapm_widgets), |
1369 | .num_dapm_routes = ARRAY_SIZE(pm860x_dapm_routes), | 1369 | .dapm_routes = pm860x_dapm_routes, |
1370 | .num_dapm_routes = ARRAY_SIZE(pm860x_dapm_routes), | ||
1371 | }, | ||
1370 | }; | 1372 | }; |
1371 | 1373 | ||
1372 | static int pm860x_codec_probe(struct platform_device *pdev) | 1374 | static int pm860x_codec_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 1cd6ab344d67..c67667bb970f 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -92,6 +92,7 @@ config SND_SOC_ALL_CODECS | |||
92 | select SND_SOC_MAX9877 if I2C | 92 | select SND_SOC_MAX9877 if I2C |
93 | select SND_SOC_MC13783 if MFD_MC13XXX | 93 | select SND_SOC_MC13783 if MFD_MC13XXX |
94 | select SND_SOC_ML26124 if I2C | 94 | select SND_SOC_ML26124 if I2C |
95 | select SND_SOC_NAU8810 if I2C | ||
95 | select SND_SOC_NAU8825 if I2C | 96 | select SND_SOC_NAU8825 if I2C |
96 | select SND_SOC_HDMI_CODEC | 97 | select SND_SOC_HDMI_CODEC |
97 | select SND_SOC_PCM1681 if I2C | 98 | select SND_SOC_PCM1681 if I2C |
@@ -112,6 +113,8 @@ config SND_SOC_ALL_CODECS | |||
112 | select SND_SOC_RT5645 if I2C | 113 | select SND_SOC_RT5645 if I2C |
113 | select SND_SOC_RT5651 if I2C | 114 | select SND_SOC_RT5651 if I2C |
114 | select SND_SOC_RT5659 if I2C | 115 | select SND_SOC_RT5659 if I2C |
116 | select SND_SOC_RT5660 if I2C | ||
117 | select SND_SOC_RT5663 if I2C | ||
115 | select SND_SOC_RT5670 if I2C | 118 | select SND_SOC_RT5670 if I2C |
116 | select SND_SOC_RT5677 if I2C && SPI_MASTER | 119 | select SND_SOC_RT5677 if I2C && SPI_MASTER |
117 | select SND_SOC_SGTL5000 if I2C | 120 | select SND_SOC_SGTL5000 if I2C |
@@ -645,6 +648,8 @@ config SND_SOC_RL6231 | |||
645 | default y if SND_SOC_RT5645=y | 648 | default y if SND_SOC_RT5645=y |
646 | default y if SND_SOC_RT5651=y | 649 | default y if SND_SOC_RT5651=y |
647 | default y if SND_SOC_RT5659=y | 650 | default y if SND_SOC_RT5659=y |
651 | default y if SND_SOC_RT5660=y | ||
652 | default y if SND_SOC_RT5663=y | ||
648 | default y if SND_SOC_RT5670=y | 653 | default y if SND_SOC_RT5670=y |
649 | default y if SND_SOC_RT5677=y | 654 | default y if SND_SOC_RT5677=y |
650 | default m if SND_SOC_RT5514=m | 655 | default m if SND_SOC_RT5514=m |
@@ -653,6 +658,8 @@ config SND_SOC_RL6231 | |||
653 | default m if SND_SOC_RT5645=m | 658 | default m if SND_SOC_RT5645=m |
654 | default m if SND_SOC_RT5651=m | 659 | default m if SND_SOC_RT5651=m |
655 | default m if SND_SOC_RT5659=m | 660 | default m if SND_SOC_RT5659=m |
661 | default m if SND_SOC_RT5660=m | ||
662 | default m if SND_SOC_RT5663=m | ||
656 | default m if SND_SOC_RT5670=m | 663 | default m if SND_SOC_RT5670=m |
657 | default m if SND_SOC_RT5677=m | 664 | default m if SND_SOC_RT5677=m |
658 | 665 | ||
@@ -665,6 +672,7 @@ config SND_SOC_RL6347A | |||
665 | 672 | ||
666 | config SND_SOC_RT286 | 673 | config SND_SOC_RT286 |
667 | tristate | 674 | tristate |
675 | select SND_SOC_RT5663 | ||
668 | depends on I2C | 676 | depends on I2C |
669 | 677 | ||
670 | config SND_SOC_RT298 | 678 | config SND_SOC_RT298 |
@@ -697,6 +705,12 @@ config SND_SOC_RT5651 | |||
697 | config SND_SOC_RT5659 | 705 | config SND_SOC_RT5659 |
698 | tristate | 706 | tristate |
699 | 707 | ||
708 | config SND_SOC_RT5660 | ||
709 | tristate | ||
710 | |||
711 | config SND_SOC_RT5663 | ||
712 | tristate | ||
713 | |||
700 | config SND_SOC_RT5670 | 714 | config SND_SOC_RT5670 |
701 | tristate | 715 | tristate |
702 | 716 | ||
@@ -1064,6 +1078,10 @@ config SND_SOC_MC13783 | |||
1064 | config SND_SOC_ML26124 | 1078 | config SND_SOC_ML26124 |
1065 | tristate | 1079 | tristate |
1066 | 1080 | ||
1081 | config SND_SOC_NAU8810 | ||
1082 | tristate "Nuvoton Technology Corporation NAU88C10 CODEC" | ||
1083 | depends on I2C | ||
1084 | |||
1067 | config SND_SOC_NAU8825 | 1085 | config SND_SOC_NAU8825 |
1068 | tristate | 1086 | tristate |
1069 | 1087 | ||
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 58036af2c7d9..958cd4912fbc 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -86,6 +86,7 @@ snd-soc-max9850-objs := max9850.o | |||
86 | snd-soc-max9860-objs := max9860.o | 86 | snd-soc-max9860-objs := max9860.o |
87 | snd-soc-mc13783-objs := mc13783.o | 87 | snd-soc-mc13783-objs := mc13783.o |
88 | snd-soc-ml26124-objs := ml26124.o | 88 | snd-soc-ml26124-objs := ml26124.o |
89 | snd-soc-nau8810-objs := nau8810.o | ||
89 | snd-soc-nau8825-objs := nau8825.o | 90 | snd-soc-nau8825-objs := nau8825.o |
90 | snd-soc-hdmi-codec-objs := hdmi-codec.o | 91 | snd-soc-hdmi-codec-objs := hdmi-codec.o |
91 | snd-soc-pcm1681-objs := pcm1681.o | 92 | snd-soc-pcm1681-objs := pcm1681.o |
@@ -112,6 +113,8 @@ snd-soc-rt5640-objs := rt5640.o | |||
112 | snd-soc-rt5645-objs := rt5645.o | 113 | snd-soc-rt5645-objs := rt5645.o |
113 | snd-soc-rt5651-objs := rt5651.o | 114 | snd-soc-rt5651-objs := rt5651.o |
114 | snd-soc-rt5659-objs := rt5659.o | 115 | snd-soc-rt5659-objs := rt5659.o |
116 | snd-soc-rt5660-objs := rt5660.o | ||
117 | snd-soc-rt5663-objs := rt5663.o | ||
115 | snd-soc-rt5670-objs := rt5670.o | 118 | snd-soc-rt5670-objs := rt5670.o |
116 | snd-soc-rt5677-objs := rt5677.o | 119 | snd-soc-rt5677-objs := rt5677.o |
117 | snd-soc-rt5677-spi-objs := rt5677-spi.o | 120 | snd-soc-rt5677-spi-objs := rt5677-spi.o |
@@ -307,6 +310,7 @@ obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o | |||
307 | obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o | 310 | obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o |
308 | obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o | 311 | obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o |
309 | obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o | 312 | obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o |
313 | obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o | ||
310 | obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o | 314 | obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o |
311 | obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o | 315 | obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o |
312 | obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o | 316 | obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o |
@@ -333,6 +337,8 @@ obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o | |||
333 | obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o | 337 | obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o |
334 | obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o | 338 | obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o |
335 | obj-$(CONFIG_SND_SOC_RT5659) += snd-soc-rt5659.o | 339 | obj-$(CONFIG_SND_SOC_RT5659) += snd-soc-rt5659.o |
340 | obj-$(CONFIG_SND_SOC_RT5660) += snd-soc-rt5660.o | ||
341 | obj-$(CONFIG_SND_SOC_RT5663) += snd-soc-rt5663.o | ||
336 | obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o | 342 | obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o |
337 | obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o | 343 | obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o |
338 | obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o | 344 | obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o |
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 2fc89155f14a..935ff7cb71c5 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c | |||
@@ -2408,28 +2408,28 @@ static void ab8500_codec_of_probe(struct device *dev, struct device_node *np, | |||
2408 | { | 2408 | { |
2409 | u32 value; | 2409 | u32 value; |
2410 | 2410 | ||
2411 | if (of_get_property(np, "stericsson,amic1-type-single-ended", NULL)) | 2411 | if (of_property_read_bool(np, "stericsson,amic1-type-single-ended")) |
2412 | codec->amics.mic1_type = AMIC_TYPE_SINGLE_ENDED; | 2412 | codec->amics.mic1_type = AMIC_TYPE_SINGLE_ENDED; |
2413 | else | 2413 | else |
2414 | codec->amics.mic1_type = AMIC_TYPE_DIFFERENTIAL; | 2414 | codec->amics.mic1_type = AMIC_TYPE_DIFFERENTIAL; |
2415 | 2415 | ||
2416 | if (of_get_property(np, "stericsson,amic2-type-single-ended", NULL)) | 2416 | if (of_property_read_bool(np, "stericsson,amic2-type-single-ended")) |
2417 | codec->amics.mic2_type = AMIC_TYPE_SINGLE_ENDED; | 2417 | codec->amics.mic2_type = AMIC_TYPE_SINGLE_ENDED; |
2418 | else | 2418 | else |
2419 | codec->amics.mic2_type = AMIC_TYPE_DIFFERENTIAL; | 2419 | codec->amics.mic2_type = AMIC_TYPE_DIFFERENTIAL; |
2420 | 2420 | ||
2421 | /* Has a non-standard Vamic been requested? */ | 2421 | /* Has a non-standard Vamic been requested? */ |
2422 | if (of_get_property(np, "stericsson,amic1a-bias-vamic2", NULL)) | 2422 | if (of_property_read_bool(np, "stericsson,amic1a-bias-vamic2")) |
2423 | codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC2; | 2423 | codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC2; |
2424 | else | 2424 | else |
2425 | codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC1; | 2425 | codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC1; |
2426 | 2426 | ||
2427 | if (of_get_property(np, "stericsson,amic1b-bias-vamic2", NULL)) | 2427 | if (of_property_read_bool(np, "stericsson,amic1b-bias-vamic2")) |
2428 | codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC2; | 2428 | codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC2; |
2429 | else | 2429 | else |
2430 | codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC1; | 2430 | codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC1; |
2431 | 2431 | ||
2432 | if (of_get_property(np, "stericsson,amic2-bias-vamic1", NULL)) | 2432 | if (of_property_read_bool(np, "stericsson,amic2-bias-vamic1")) |
2433 | codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC1; | 2433 | codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC1; |
2434 | else | 2434 | else |
2435 | codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC2; | 2435 | codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC2; |
@@ -2525,12 +2525,14 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec) | |||
2525 | 2525 | ||
2526 | static struct snd_soc_codec_driver ab8500_codec_driver = { | 2526 | static struct snd_soc_codec_driver ab8500_codec_driver = { |
2527 | .probe = ab8500_codec_probe, | 2527 | .probe = ab8500_codec_probe, |
2528 | .controls = ab8500_ctrls, | 2528 | .component_driver = { |
2529 | .num_controls = ARRAY_SIZE(ab8500_ctrls), | 2529 | .controls = ab8500_ctrls, |
2530 | .dapm_widgets = ab8500_dapm_widgets, | 2530 | .num_controls = ARRAY_SIZE(ab8500_ctrls), |
2531 | .num_dapm_widgets = ARRAY_SIZE(ab8500_dapm_widgets), | 2531 | .dapm_widgets = ab8500_dapm_widgets, |
2532 | .dapm_routes = ab8500_dapm_routes, | 2532 | .num_dapm_widgets = ARRAY_SIZE(ab8500_dapm_widgets), |
2533 | .num_dapm_routes = ARRAY_SIZE(ab8500_dapm_routes), | 2533 | .dapm_routes = ab8500_dapm_routes, |
2534 | .num_dapm_routes = ARRAY_SIZE(ab8500_dapm_routes), | ||
2535 | }, | ||
2534 | }; | 2536 | }; |
2535 | 2537 | ||
2536 | static int ab8500_codec_driver_probe(struct platform_device *pdev) | 2538 | static int ab8500_codec_driver_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index 5b3224c63943..f7f04c6be01e 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c | |||
@@ -117,10 +117,12 @@ static struct snd_soc_codec_driver soc_codec_dev_ac97 = { | |||
117 | .suspend = ac97_soc_suspend, | 117 | .suspend = ac97_soc_suspend, |
118 | .resume = ac97_soc_resume, | 118 | .resume = ac97_soc_resume, |
119 | 119 | ||
120 | .dapm_widgets = ac97_widgets, | 120 | .component_driver = { |
121 | .num_dapm_widgets = ARRAY_SIZE(ac97_widgets), | 121 | .dapm_widgets = ac97_widgets, |
122 | .dapm_routes = ac97_routes, | 122 | .num_dapm_widgets = ARRAY_SIZE(ac97_widgets), |
123 | .num_dapm_routes = ARRAY_SIZE(ac97_routes), | 123 | .dapm_routes = ac97_routes, |
124 | .num_dapm_routes = ARRAY_SIZE(ac97_routes), | ||
125 | }, | ||
124 | }; | 126 | }; |
125 | 127 | ||
126 | static int ac97_probe(struct platform_device *pdev) | 128 | static int ac97_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index e2ce6c4d7ece..a478239aadac 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c | |||
@@ -327,12 +327,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1836 = { | |||
327 | .suspend = ad1836_suspend, | 327 | .suspend = ad1836_suspend, |
328 | .resume = ad1836_resume, | 328 | .resume = ad1836_resume, |
329 | 329 | ||
330 | .controls = ad183x_controls, | 330 | .component_driver = { |
331 | .num_controls = ARRAY_SIZE(ad183x_controls), | 331 | .controls = ad183x_controls, |
332 | .dapm_widgets = ad183x_dapm_widgets, | 332 | .num_controls = ARRAY_SIZE(ad183x_controls), |
333 | .num_dapm_widgets = ARRAY_SIZE(ad183x_dapm_widgets), | 333 | .dapm_widgets = ad183x_dapm_widgets, |
334 | .dapm_routes = ad183x_dapm_routes, | 334 | .num_dapm_widgets = ARRAY_SIZE(ad183x_dapm_widgets), |
335 | .num_dapm_routes = ARRAY_SIZE(ad183x_dapm_routes), | 335 | .dapm_routes = ad183x_dapm_routes, |
336 | .num_dapm_routes = ARRAY_SIZE(ad183x_dapm_routes), | ||
337 | }, | ||
336 | }; | 338 | }; |
337 | 339 | ||
338 | static const struct reg_default ad1836_reg_defaults[] = { | 340 | static const struct reg_default ad1836_reg_defaults[] = { |
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 3a3f3f2343d7..d643557d89a7 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c | |||
@@ -410,12 +410,14 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec) | |||
410 | 410 | ||
411 | static struct snd_soc_codec_driver soc_codec_dev_ad193x = { | 411 | static struct snd_soc_codec_driver soc_codec_dev_ad193x = { |
412 | .probe = ad193x_codec_probe, | 412 | .probe = ad193x_codec_probe, |
413 | .controls = ad193x_snd_controls, | 413 | .component_driver = { |
414 | .num_controls = ARRAY_SIZE(ad193x_snd_controls), | 414 | .controls = ad193x_snd_controls, |
415 | .dapm_widgets = ad193x_dapm_widgets, | 415 | .num_controls = ARRAY_SIZE(ad193x_snd_controls), |
416 | .num_dapm_widgets = ARRAY_SIZE(ad193x_dapm_widgets), | 416 | .dapm_widgets = ad193x_dapm_widgets, |
417 | .dapm_routes = audio_paths, | 417 | .num_dapm_widgets = ARRAY_SIZE(ad193x_dapm_widgets), |
418 | .num_dapm_routes = ARRAY_SIZE(audio_paths), | 418 | .dapm_routes = audio_paths, |
419 | .num_dapm_routes = ARRAY_SIZE(audio_paths), | ||
420 | }, | ||
419 | }; | 421 | }; |
420 | 422 | ||
421 | const struct regmap_config ad193x_regmap_config = { | 423 | const struct regmap_config ad193x_regmap_config = { |
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 9ef20dbccbe3..b7c1b9f4bf5f 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c | |||
@@ -299,12 +299,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1980 = { | |||
299 | .probe = ad1980_soc_probe, | 299 | .probe = ad1980_soc_probe, |
300 | .remove = ad1980_soc_remove, | 300 | .remove = ad1980_soc_remove, |
301 | 301 | ||
302 | .controls = ad1980_snd_ac97_controls, | 302 | .component_driver = { |
303 | .num_controls = ARRAY_SIZE(ad1980_snd_ac97_controls), | 303 | .controls = ad1980_snd_ac97_controls, |
304 | .dapm_widgets = ad1980_dapm_widgets, | 304 | .num_controls = ARRAY_SIZE(ad1980_snd_ac97_controls), |
305 | .num_dapm_widgets = ARRAY_SIZE(ad1980_dapm_widgets), | 305 | .dapm_widgets = ad1980_dapm_widgets, |
306 | .dapm_routes = ad1980_dapm_routes, | 306 | .num_dapm_widgets = ARRAY_SIZE(ad1980_dapm_widgets), |
307 | .num_dapm_routes = ARRAY_SIZE(ad1980_dapm_routes), | 307 | .dapm_routes = ad1980_dapm_routes, |
308 | .num_dapm_routes = ARRAY_SIZE(ad1980_dapm_routes), | ||
309 | }, | ||
308 | }; | 310 | }; |
309 | 311 | ||
310 | static int ad1980_probe(struct platform_device *pdev) | 312 | static int ad1980_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c index a9400aef60b5..3e358a49442d 100644 --- a/sound/soc/codecs/ad73311.c +++ b/sound/soc/codecs/ad73311.c | |||
@@ -55,10 +55,12 @@ static struct snd_soc_dai_driver ad73311_dai = { | |||
55 | }; | 55 | }; |
56 | 56 | ||
57 | static struct snd_soc_codec_driver soc_codec_dev_ad73311 = { | 57 | static struct snd_soc_codec_driver soc_codec_dev_ad73311 = { |
58 | .dapm_widgets = ad73311_dapm_widgets, | 58 | .component_driver = { |
59 | .num_dapm_widgets = ARRAY_SIZE(ad73311_dapm_widgets), | 59 | .dapm_widgets = ad73311_dapm_widgets, |
60 | .dapm_routes = ad73311_dapm_routes, | 60 | .num_dapm_widgets = ARRAY_SIZE(ad73311_dapm_widgets), |
61 | .num_dapm_routes = ARRAY_SIZE(ad73311_dapm_routes), | 61 | .dapm_routes = ad73311_dapm_routes, |
62 | .num_dapm_routes = ARRAY_SIZE(ad73311_dapm_routes), | ||
63 | }, | ||
62 | }; | 64 | }; |
63 | 65 | ||
64 | static int ad73311_probe(struct platform_device *pdev) | 66 | static int ad73311_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 1556b360fa15..8fa9045571ff 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c | |||
@@ -1466,12 +1466,14 @@ static struct snd_soc_codec_driver adau1373_codec_driver = { | |||
1466 | 1466 | ||
1467 | .set_pll = adau1373_set_pll, | 1467 | .set_pll = adau1373_set_pll, |
1468 | 1468 | ||
1469 | .controls = adau1373_controls, | 1469 | .component_driver = { |
1470 | .num_controls = ARRAY_SIZE(adau1373_controls), | 1470 | .controls = adau1373_controls, |
1471 | .dapm_widgets = adau1373_dapm_widgets, | 1471 | .num_controls = ARRAY_SIZE(adau1373_controls), |
1472 | .num_dapm_widgets = ARRAY_SIZE(adau1373_dapm_widgets), | 1472 | .dapm_widgets = adau1373_dapm_widgets, |
1473 | .dapm_routes = adau1373_dapm_routes, | 1473 | .num_dapm_widgets = ARRAY_SIZE(adau1373_dapm_widgets), |
1474 | .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes), | 1474 | .dapm_routes = adau1373_dapm_routes, |
1475 | .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes), | ||
1476 | }, | ||
1475 | }; | 1477 | }; |
1476 | 1478 | ||
1477 | static int adau1373_i2c_probe(struct i2c_client *client, | 1479 | static int adau1373_i2c_probe(struct i2c_client *client, |
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index de53c0d7bf10..3bad1bc8c00a 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c | |||
@@ -765,13 +765,14 @@ static struct snd_soc_codec_driver adau1701_codec_drv = { | |||
765 | .set_bias_level = adau1701_set_bias_level, | 765 | .set_bias_level = adau1701_set_bias_level, |
766 | .idle_bias_off = true, | 766 | .idle_bias_off = true, |
767 | 767 | ||
768 | .controls = adau1701_controls, | 768 | .component_driver = { |
769 | .num_controls = ARRAY_SIZE(adau1701_controls), | 769 | .controls = adau1701_controls, |
770 | .dapm_widgets = adau1701_dapm_widgets, | 770 | .num_controls = ARRAY_SIZE(adau1701_controls), |
771 | .num_dapm_widgets = ARRAY_SIZE(adau1701_dapm_widgets), | 771 | .dapm_widgets = adau1701_dapm_widgets, |
772 | .dapm_routes = adau1701_dapm_routes, | 772 | .num_dapm_widgets = ARRAY_SIZE(adau1701_dapm_widgets), |
773 | .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes), | 773 | .dapm_routes = adau1701_dapm_routes, |
774 | 774 | .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes), | |
775 | }, | ||
775 | .set_sysclk = adau1701_set_sysclk, | 776 | .set_sysclk = adau1701_set_sysclk, |
776 | }; | 777 | }; |
777 | 778 | ||
diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c index b95d29dbd13d..3bc3cc559dde 100644 --- a/sound/soc/codecs/adau1761.c +++ b/sound/soc/codecs/adau1761.c | |||
@@ -719,12 +719,14 @@ static const struct snd_soc_codec_driver adau1761_codec_driver = { | |||
719 | .set_bias_level = adau1761_set_bias_level, | 719 | .set_bias_level = adau1761_set_bias_level, |
720 | .suspend_bias_off = true, | 720 | .suspend_bias_off = true, |
721 | 721 | ||
722 | .controls = adau1761_controls, | 722 | .component_driver = { |
723 | .num_controls = ARRAY_SIZE(adau1761_controls), | 723 | .controls = adau1761_controls, |
724 | .dapm_widgets = adau1x61_dapm_widgets, | 724 | .num_controls = ARRAY_SIZE(adau1761_controls), |
725 | .num_dapm_widgets = ARRAY_SIZE(adau1x61_dapm_widgets), | 725 | .dapm_widgets = adau1x61_dapm_widgets, |
726 | .dapm_routes = adau1x61_dapm_routes, | 726 | .num_dapm_widgets = ARRAY_SIZE(adau1x61_dapm_widgets), |
727 | .num_dapm_routes = ARRAY_SIZE(adau1x61_dapm_routes), | 727 | .dapm_routes = adau1x61_dapm_routes, |
728 | .num_dapm_routes = ARRAY_SIZE(adau1x61_dapm_routes), | ||
729 | }, | ||
728 | }; | 730 | }; |
729 | 731 | ||
730 | #define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ | 732 | #define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ |
diff --git a/sound/soc/codecs/adau1781.c b/sound/soc/codecs/adau1781.c index bc1bb56dae63..546071c6c0d0 100644 --- a/sound/soc/codecs/adau1781.c +++ b/sound/soc/codecs/adau1781.c | |||
@@ -432,12 +432,14 @@ static const struct snd_soc_codec_driver adau1781_codec_driver = { | |||
432 | .set_bias_level = adau1781_set_bias_level, | 432 | .set_bias_level = adau1781_set_bias_level, |
433 | .suspend_bias_off = true, | 433 | .suspend_bias_off = true, |
434 | 434 | ||
435 | .controls = adau1781_controls, | 435 | .component_driver = { |
436 | .num_controls = ARRAY_SIZE(adau1781_controls), | 436 | .controls = adau1781_controls, |
437 | .dapm_widgets = adau1781_dapm_widgets, | 437 | .num_controls = ARRAY_SIZE(adau1781_controls), |
438 | .num_dapm_widgets = ARRAY_SIZE(adau1781_dapm_widgets), | 438 | .dapm_widgets = adau1781_dapm_widgets, |
439 | .dapm_routes = adau1781_dapm_routes, | 439 | .num_dapm_widgets = ARRAY_SIZE(adau1781_dapm_widgets), |
440 | .num_dapm_routes = ARRAY_SIZE(adau1781_dapm_routes), | 440 | .dapm_routes = adau1781_dapm_routes, |
441 | .num_dapm_routes = ARRAY_SIZE(adau1781_dapm_routes), | ||
442 | }, | ||
441 | }; | 443 | }; |
442 | 444 | ||
443 | #define ADAU1781_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ | 445 | #define ADAU1781_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ |
diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c index 9bdd15f408c1..b319db6a69f8 100644 --- a/sound/soc/codecs/adau1977.c +++ b/sound/soc/codecs/adau1977.c | |||
@@ -873,12 +873,14 @@ static struct snd_soc_codec_driver adau1977_codec_driver = { | |||
873 | .set_sysclk = adau1977_set_sysclk, | 873 | .set_sysclk = adau1977_set_sysclk, |
874 | .idle_bias_off = true, | 874 | .idle_bias_off = true, |
875 | 875 | ||
876 | .controls = adau1977_snd_controls, | 876 | .component_driver = { |
877 | .num_controls = ARRAY_SIZE(adau1977_snd_controls), | 877 | .controls = adau1977_snd_controls, |
878 | .dapm_widgets = adau1977_dapm_widgets, | 878 | .num_controls = ARRAY_SIZE(adau1977_snd_controls), |
879 | .num_dapm_widgets = ARRAY_SIZE(adau1977_dapm_widgets), | 879 | .dapm_widgets = adau1977_dapm_widgets, |
880 | .dapm_routes = adau1977_dapm_routes, | 880 | .num_dapm_widgets = ARRAY_SIZE(adau1977_dapm_widgets), |
881 | .num_dapm_routes = ARRAY_SIZE(adau1977_dapm_routes), | 881 | .dapm_routes = adau1977_dapm_routes, |
882 | .num_dapm_routes = ARRAY_SIZE(adau1977_dapm_routes), | ||
883 | }, | ||
882 | }; | 884 | }; |
883 | 885 | ||
884 | static int adau1977_setup_micbias(struct adau1977 *adau1977) | 886 | static int adau1977_setup_micbias(struct adau1977 *adau1977) |
diff --git a/sound/soc/codecs/adau7002.c b/sound/soc/codecs/adau7002.c index 9df72c6adcca..6384c5491de8 100644 --- a/sound/soc/codecs/adau7002.c +++ b/sound/soc/codecs/adau7002.c | |||
@@ -39,10 +39,12 @@ static struct snd_soc_dai_driver adau7002_dai = { | |||
39 | }; | 39 | }; |
40 | 40 | ||
41 | static const struct snd_soc_codec_driver adau7002_codec_driver = { | 41 | static const struct snd_soc_codec_driver adau7002_codec_driver = { |
42 | .dapm_widgets = adau7002_widgets, | 42 | .component_driver = { |
43 | .num_dapm_widgets = ARRAY_SIZE(adau7002_widgets), | 43 | .dapm_widgets = adau7002_widgets, |
44 | .dapm_routes = adau7002_routes, | 44 | .num_dapm_widgets = ARRAY_SIZE(adau7002_widgets), |
45 | .num_dapm_routes = ARRAY_SIZE(adau7002_routes), | 45 | .dapm_routes = adau7002_routes, |
46 | .num_dapm_routes = ARRAY_SIZE(adau7002_routes), | ||
47 | }, | ||
46 | }; | 48 | }; |
47 | 49 | ||
48 | static int adau7002_probe(struct platform_device *pdev) | 50 | static int adau7002_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index acff8d62059c..6e793ebb5883 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c | |||
@@ -834,12 +834,14 @@ static struct snd_soc_codec_driver adav80x_codec_driver = { | |||
834 | .set_pll = adav80x_set_pll, | 834 | .set_pll = adav80x_set_pll, |
835 | .set_sysclk = adav80x_set_sysclk, | 835 | .set_sysclk = adav80x_set_sysclk, |
836 | 836 | ||
837 | .controls = adav80x_controls, | 837 | .component_driver = { |
838 | .num_controls = ARRAY_SIZE(adav80x_controls), | 838 | .controls = adav80x_controls, |
839 | .dapm_widgets = adav80x_dapm_widgets, | 839 | .num_controls = ARRAY_SIZE(adav80x_controls), |
840 | .num_dapm_widgets = ARRAY_SIZE(adav80x_dapm_widgets), | 840 | .dapm_widgets = adav80x_dapm_widgets, |
841 | .dapm_routes = adav80x_dapm_routes, | 841 | .num_dapm_widgets = ARRAY_SIZE(adav80x_dapm_widgets), |
842 | .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes), | 842 | .dapm_routes = adav80x_dapm_routes, |
843 | .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes), | ||
844 | }, | ||
843 | }; | 845 | }; |
844 | 846 | ||
845 | int adav80x_bus_probe(struct device *dev, struct regmap *regmap) | 847 | int adav80x_bus_probe(struct device *dev, struct regmap *regmap) |
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c index c5be1bdc2c9a..90c756d183b4 100644 --- a/sound/soc/codecs/ads117x.c +++ b/sound/soc/codecs/ads117x.c | |||
@@ -59,10 +59,12 @@ static struct snd_soc_dai_driver ads117x_dai = { | |||
59 | }; | 59 | }; |
60 | 60 | ||
61 | static struct snd_soc_codec_driver soc_codec_dev_ads117x = { | 61 | static struct snd_soc_codec_driver soc_codec_dev_ads117x = { |
62 | .dapm_widgets = ads117x_dapm_widgets, | 62 | .component_driver = { |
63 | .num_dapm_widgets = ARRAY_SIZE(ads117x_dapm_widgets), | 63 | .dapm_widgets = ads117x_dapm_widgets, |
64 | .dapm_routes = ads117x_dapm_routes, | 64 | .num_dapm_widgets = ARRAY_SIZE(ads117x_dapm_widgets), |
65 | .num_dapm_routes = ARRAY_SIZE(ads117x_dapm_routes), | 65 | .dapm_routes = ads117x_dapm_routes, |
66 | .num_dapm_routes = ARRAY_SIZE(ads117x_dapm_routes), | ||
67 | }, | ||
66 | }; | 68 | }; |
67 | 69 | ||
68 | static int ads117x_probe(struct platform_device *pdev) | 70 | static int ads117x_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index 595d02d7602c..1a9d233c94d0 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c | |||
@@ -163,7 +163,10 @@ static struct snd_soc_dai_driver ak4104_dai = { | |||
163 | .stream_name = "Playback", | 163 | .stream_name = "Playback", |
164 | .channels_min = 2, | 164 | .channels_min = 2, |
165 | .channels_max = 2, | 165 | .channels_max = 2, |
166 | .rates = SNDRV_PCM_RATE_8000_192000, | 166 | .rates = SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | |
167 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | | ||
168 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | | ||
169 | SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, | ||
167 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | 170 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
168 | SNDRV_PCM_FMTBIT_S24_3LE | | 171 | SNDRV_PCM_FMTBIT_S24_3LE | |
169 | SNDRV_PCM_FMTBIT_S24_LE | 172 | SNDRV_PCM_FMTBIT_S24_LE |
@@ -245,10 +248,12 @@ static struct snd_soc_codec_driver soc_codec_device_ak4104 = { | |||
245 | .suspend = ak4104_soc_suspend, | 248 | .suspend = ak4104_soc_suspend, |
246 | .resume = ak4104_soc_resume, | 249 | .resume = ak4104_soc_resume, |
247 | 250 | ||
248 | .dapm_widgets = ak4104_dapm_widgets, | 251 | .component_driver = { |
249 | .num_dapm_widgets = ARRAY_SIZE(ak4104_dapm_widgets), | 252 | .dapm_widgets = ak4104_dapm_widgets, |
250 | .dapm_routes = ak4104_dapm_routes, | 253 | .num_dapm_widgets = ARRAY_SIZE(ak4104_dapm_widgets), |
251 | .num_dapm_routes = ARRAY_SIZE(ak4104_dapm_routes), | 254 | .dapm_routes = ak4104_dapm_routes, |
255 | .num_dapm_routes = ARRAY_SIZE(ak4104_dapm_routes), | ||
256 | } | ||
252 | }; | 257 | }; |
253 | 258 | ||
254 | static const struct regmap_config ak4104_regmap = { | 259 | static const struct regmap_config ak4104_regmap = { |
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 54428c64387b..66cfffde9a12 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c | |||
@@ -395,12 +395,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { | |||
395 | .set_bias_level = ak4535_set_bias_level, | 395 | .set_bias_level = ak4535_set_bias_level, |
396 | .suspend_bias_off = true, | 396 | .suspend_bias_off = true, |
397 | 397 | ||
398 | .controls = ak4535_snd_controls, | 398 | .component_driver = { |
399 | .num_controls = ARRAY_SIZE(ak4535_snd_controls), | 399 | .controls = ak4535_snd_controls, |
400 | .dapm_widgets = ak4535_dapm_widgets, | 400 | .num_controls = ARRAY_SIZE(ak4535_snd_controls), |
401 | .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), | 401 | .dapm_widgets = ak4535_dapm_widgets, |
402 | .dapm_routes = ak4535_audio_map, | 402 | .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), |
403 | .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map), | 403 | .dapm_routes = ak4535_audio_map, |
404 | .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map), | ||
405 | }, | ||
404 | }; | 406 | }; |
405 | 407 | ||
406 | static int ak4535_i2c_probe(struct i2c_client *i2c, | 408 | static int ak4535_i2c_probe(struct i2c_client *i2c, |
diff --git a/sound/soc/codecs/ak4554.c b/sound/soc/codecs/ak4554.c index 298dedc05140..b92c548b9d29 100644 --- a/sound/soc/codecs/ak4554.c +++ b/sound/soc/codecs/ak4554.c | |||
@@ -65,10 +65,12 @@ static struct snd_soc_dai_driver ak4554_dai = { | |||
65 | }; | 65 | }; |
66 | 66 | ||
67 | static struct snd_soc_codec_driver soc_codec_dev_ak4554 = { | 67 | static struct snd_soc_codec_driver soc_codec_dev_ak4554 = { |
68 | .dapm_widgets = ak4554_dapm_widgets, | 68 | .component_driver = { |
69 | .num_dapm_widgets = ARRAY_SIZE(ak4554_dapm_widgets), | 69 | .dapm_widgets = ak4554_dapm_widgets, |
70 | .dapm_routes = ak4554_dapm_routes, | 70 | .num_dapm_widgets = ARRAY_SIZE(ak4554_dapm_widgets), |
71 | .num_dapm_routes = ARRAY_SIZE(ak4554_dapm_routes), | 71 | .dapm_routes = ak4554_dapm_routes, |
72 | .num_dapm_routes = ARRAY_SIZE(ak4554_dapm_routes), | ||
73 | }, | ||
72 | }; | 74 | }; |
73 | 75 | ||
74 | static int ak4554_soc_probe(struct platform_device *pdev) | 76 | static int ak4554_soc_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c index 97798d250f08..e819dd8c82fd 100644 --- a/sound/soc/codecs/ak4613.c +++ b/sound/soc/codecs/ak4613.c | |||
@@ -458,12 +458,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4613 = { | |||
458 | .suspend = ak4613_suspend, | 458 | .suspend = ak4613_suspend, |
459 | .resume = ak4613_resume, | 459 | .resume = ak4613_resume, |
460 | .set_bias_level = ak4613_set_bias_level, | 460 | .set_bias_level = ak4613_set_bias_level, |
461 | .controls = ak4613_snd_controls, | 461 | .component_driver = { |
462 | .num_controls = ARRAY_SIZE(ak4613_snd_controls), | 462 | .controls = ak4613_snd_controls, |
463 | .dapm_widgets = ak4613_dapm_widgets, | 463 | .num_controls = ARRAY_SIZE(ak4613_snd_controls), |
464 | .num_dapm_widgets = ARRAY_SIZE(ak4613_dapm_widgets), | 464 | .dapm_widgets = ak4613_dapm_widgets, |
465 | .dapm_routes = ak4613_intercon, | 465 | .num_dapm_widgets = ARRAY_SIZE(ak4613_dapm_widgets), |
466 | .num_dapm_routes = ARRAY_SIZE(ak4613_intercon), | 466 | .dapm_routes = ak4613_intercon, |
467 | .num_dapm_routes = ARRAY_SIZE(ak4613_intercon), | ||
468 | }, | ||
467 | }; | 469 | }; |
468 | 470 | ||
469 | static void ak4613_parse_of(struct ak4613_priv *priv, | 471 | static void ak4613_parse_of(struct ak4613_priv *priv, |
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index b14176f8d884..c91717d08513 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c | |||
@@ -505,12 +505,14 @@ static struct snd_soc_dai_driver ak4641_dai[] = { | |||
505 | }; | 505 | }; |
506 | 506 | ||
507 | static struct snd_soc_codec_driver soc_codec_dev_ak4641 = { | 507 | static struct snd_soc_codec_driver soc_codec_dev_ak4641 = { |
508 | .controls = ak4641_snd_controls, | 508 | .component_driver = { |
509 | .num_controls = ARRAY_SIZE(ak4641_snd_controls), | 509 | .controls = ak4641_snd_controls, |
510 | .dapm_widgets = ak4641_dapm_widgets, | 510 | .num_controls = ARRAY_SIZE(ak4641_snd_controls), |
511 | .num_dapm_widgets = ARRAY_SIZE(ak4641_dapm_widgets), | 511 | .dapm_widgets = ak4641_dapm_widgets, |
512 | .dapm_routes = ak4641_audio_map, | 512 | .num_dapm_widgets = ARRAY_SIZE(ak4641_dapm_widgets), |
513 | .num_dapm_routes = ARRAY_SIZE(ak4641_audio_map), | 513 | .dapm_routes = ak4641_audio_map, |
514 | .num_dapm_routes = ARRAY_SIZE(ak4641_audio_map), | ||
515 | }, | ||
514 | .set_bias_level = ak4641_set_bias_level, | 516 | .set_bias_level = ak4641_set_bias_level, |
515 | .suspend_bias_off = true, | 517 | .suspend_bias_off = true, |
516 | }; | 518 | }; |
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index cc941d66ec3d..2609f95b7d19 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c | |||
@@ -555,12 +555,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { | |||
555 | .suspend = ak4642_suspend, | 555 | .suspend = ak4642_suspend, |
556 | .resume = ak4642_resume, | 556 | .resume = ak4642_resume, |
557 | .set_bias_level = ak4642_set_bias_level, | 557 | .set_bias_level = ak4642_set_bias_level, |
558 | .controls = ak4642_snd_controls, | 558 | .component_driver = { |
559 | .num_controls = ARRAY_SIZE(ak4642_snd_controls), | 559 | .controls = ak4642_snd_controls, |
560 | .dapm_widgets = ak4642_dapm_widgets, | 560 | .num_controls = ARRAY_SIZE(ak4642_snd_controls), |
561 | .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets), | 561 | .dapm_widgets = ak4642_dapm_widgets, |
562 | .dapm_routes = ak4642_intercon, | 562 | .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets), |
563 | .num_dapm_routes = ARRAY_SIZE(ak4642_intercon), | 563 | .dapm_routes = ak4642_intercon, |
564 | .num_dapm_routes = ARRAY_SIZE(ak4642_intercon), | ||
565 | }, | ||
564 | }; | 566 | }; |
565 | 567 | ||
566 | static const struct regmap_config ak4642_regmap = { | 568 | static const struct regmap_config ak4642_regmap = { |
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index c73a9f6914b6..6088afaabf62 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c | |||
@@ -612,12 +612,14 @@ static struct snd_soc_dai_driver ak4671_dai = { | |||
612 | 612 | ||
613 | static struct snd_soc_codec_driver soc_codec_dev_ak4671 = { | 613 | static struct snd_soc_codec_driver soc_codec_dev_ak4671 = { |
614 | .set_bias_level = ak4671_set_bias_level, | 614 | .set_bias_level = ak4671_set_bias_level, |
615 | .controls = ak4671_snd_controls, | 615 | .component_driver = { |
616 | .num_controls = ARRAY_SIZE(ak4671_snd_controls), | 616 | .controls = ak4671_snd_controls, |
617 | .dapm_widgets = ak4671_dapm_widgets, | 617 | .num_controls = ARRAY_SIZE(ak4671_snd_controls), |
618 | .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets), | 618 | .dapm_widgets = ak4671_dapm_widgets, |
619 | .dapm_routes = ak4671_intercon, | 619 | .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets), |
620 | .num_dapm_routes = ARRAY_SIZE(ak4671_intercon), | 620 | .dapm_routes = ak4671_intercon, |
621 | .num_dapm_routes = ARRAY_SIZE(ak4671_intercon), | ||
622 | }, | ||
621 | }; | 623 | }; |
622 | 624 | ||
623 | static const struct regmap_config ak4671_regmap = { | 625 | static const struct regmap_config ak4671_regmap = { |
diff --git a/sound/soc/codecs/ak5386.c b/sound/soc/codecs/ak5386.c index afa95360826d..0ef2df223336 100644 --- a/sound/soc/codecs/ak5386.c +++ b/sound/soc/codecs/ak5386.c | |||
@@ -74,10 +74,12 @@ static struct snd_soc_codec_driver soc_codec_ak5386 = { | |||
74 | .remove = ak5386_soc_remove, | 74 | .remove = ak5386_soc_remove, |
75 | .suspend = ak5386_soc_suspend, | 75 | .suspend = ak5386_soc_suspend, |
76 | .resume = ak5386_soc_resume, | 76 | .resume = ak5386_soc_resume, |
77 | .dapm_widgets = ak5386_dapm_widgets, | 77 | .component_driver = { |
78 | .num_dapm_widgets = ARRAY_SIZE(ak5386_dapm_widgets), | 78 | .dapm_widgets = ak5386_dapm_widgets, |
79 | .dapm_routes = ak5386_dapm_routes, | 79 | .num_dapm_widgets = ARRAY_SIZE(ak5386_dapm_widgets), |
80 | .num_dapm_routes = ARRAY_SIZE(ak5386_dapm_routes), | 80 | .dapm_routes = ak5386_dapm_routes, |
81 | .num_dapm_routes = ARRAY_SIZE(ak5386_dapm_routes), | ||
82 | }, | ||
81 | }; | 83 | }; |
82 | 84 | ||
83 | static int ak5386_set_dai_fmt(struct snd_soc_dai *codec_dai, | 85 | static int ak5386_set_dai_fmt(struct snd_soc_dai *codec_dai, |
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index 4d3ba33eb6f9..adb80d8719bd 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c | |||
@@ -1072,12 +1072,14 @@ static const struct snd_soc_codec_driver soc_codec_device_alc5632 = { | |||
1072 | .set_bias_level = alc5632_set_bias_level, | 1072 | .set_bias_level = alc5632_set_bias_level, |
1073 | .suspend_bias_off = true, | 1073 | .suspend_bias_off = true, |
1074 | 1074 | ||
1075 | .controls = alc5632_snd_controls, | 1075 | .component_driver = { |
1076 | .num_controls = ARRAY_SIZE(alc5632_snd_controls), | 1076 | .controls = alc5632_snd_controls, |
1077 | .dapm_widgets = alc5632_dapm_widgets, | 1077 | .num_controls = ARRAY_SIZE(alc5632_snd_controls), |
1078 | .num_dapm_widgets = ARRAY_SIZE(alc5632_dapm_widgets), | 1078 | .dapm_widgets = alc5632_dapm_widgets, |
1079 | .dapm_routes = alc5632_dapm_routes, | 1079 | .num_dapm_widgets = ARRAY_SIZE(alc5632_dapm_widgets), |
1080 | .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes), | 1080 | .dapm_routes = alc5632_dapm_routes, |
1081 | .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes), | ||
1082 | }, | ||
1081 | }; | 1083 | }; |
1082 | 1084 | ||
1083 | static const struct regmap_config alc5632_regmap = { | 1085 | static const struct regmap_config alc5632_regmap = { |
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index ecfdbfcae366..846ca079845f 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
@@ -109,7 +109,7 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, | |||
109 | break; | 109 | break; |
110 | } | 110 | } |
111 | 111 | ||
112 | return 0; | 112 | return arizona_out_ev(w, kcontrol, event); |
113 | } | 113 | } |
114 | 114 | ||
115 | static irqreturn_t arizona_thermal_warn(int irq, void *data) | 115 | static irqreturn_t arizona_thermal_warn(int irq, void *data) |
@@ -159,12 +159,14 @@ static irqreturn_t arizona_thermal_shutdown(int irq, void *data) | |||
159 | static const struct snd_soc_dapm_widget arizona_spkl = | 159 | static const struct snd_soc_dapm_widget arizona_spkl = |
160 | SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM, | 160 | SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM, |
161 | ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, | 161 | ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, |
162 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); | 162 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | |
163 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD); | ||
163 | 164 | ||
164 | static const struct snd_soc_dapm_widget arizona_spkr = | 165 | static const struct snd_soc_dapm_widget arizona_spkr = |
165 | SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM, | 166 | SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM, |
166 | ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, | 167 | ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, |
167 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); | 168 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | |
169 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD); | ||
168 | 170 | ||
169 | int arizona_init_spk(struct snd_soc_codec *codec) | 171 | int arizona_init_spk(struct snd_soc_codec *codec) |
170 | { | 172 | { |
@@ -864,6 +866,7 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
864 | { | 866 | { |
865 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | 867 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
866 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | 868 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); |
869 | struct arizona *arizona = priv->arizona; | ||
867 | 870 | ||
868 | switch (event) { | 871 | switch (event) { |
869 | case SND_SOC_DAPM_PRE_PMU: | 872 | case SND_SOC_DAPM_PRE_PMU: |
@@ -877,6 +880,18 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
877 | priv->out_up_pending++; | 880 | priv->out_up_pending++; |
878 | priv->out_up_delay += 17; | 881 | priv->out_up_delay += 17; |
879 | break; | 882 | break; |
883 | case ARIZONA_OUT4L_ENA_SHIFT: | ||
884 | case ARIZONA_OUT4R_ENA_SHIFT: | ||
885 | priv->out_up_pending++; | ||
886 | switch (arizona->type) { | ||
887 | case WM5102: | ||
888 | case WM8997: | ||
889 | break; | ||
890 | default: | ||
891 | priv->out_up_delay += 10; | ||
892 | break; | ||
893 | } | ||
894 | break; | ||
880 | default: | 895 | default: |
881 | break; | 896 | break; |
882 | } | 897 | } |
@@ -889,8 +904,12 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
889 | case ARIZONA_OUT2R_ENA_SHIFT: | 904 | case ARIZONA_OUT2R_ENA_SHIFT: |
890 | case ARIZONA_OUT3L_ENA_SHIFT: | 905 | case ARIZONA_OUT3L_ENA_SHIFT: |
891 | case ARIZONA_OUT3R_ENA_SHIFT: | 906 | case ARIZONA_OUT3R_ENA_SHIFT: |
907 | case ARIZONA_OUT4L_ENA_SHIFT: | ||
908 | case ARIZONA_OUT4R_ENA_SHIFT: | ||
892 | priv->out_up_pending--; | 909 | priv->out_up_pending--; |
893 | if (!priv->out_up_pending) { | 910 | if (!priv->out_up_pending && priv->out_up_delay) { |
911 | dev_dbg(codec->dev, "Power up delay: %d\n", | ||
912 | priv->out_up_delay); | ||
894 | msleep(priv->out_up_delay); | 913 | msleep(priv->out_up_delay); |
895 | priv->out_up_delay = 0; | 914 | priv->out_up_delay = 0; |
896 | } | 915 | } |
@@ -911,6 +930,21 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
911 | priv->out_down_pending++; | 930 | priv->out_down_pending++; |
912 | priv->out_down_delay++; | 931 | priv->out_down_delay++; |
913 | break; | 932 | break; |
933 | case ARIZONA_OUT4L_ENA_SHIFT: | ||
934 | case ARIZONA_OUT4R_ENA_SHIFT: | ||
935 | priv->out_down_pending++; | ||
936 | switch (arizona->type) { | ||
937 | case WM5102: | ||
938 | case WM8997: | ||
939 | break; | ||
940 | case WM8998: | ||
941 | case WM1814: | ||
942 | priv->out_down_delay += 5; | ||
943 | break; | ||
944 | default: | ||
945 | priv->out_down_delay++; | ||
946 | break; | ||
947 | } | ||
914 | default: | 948 | default: |
915 | break; | 949 | break; |
916 | } | 950 | } |
@@ -923,8 +957,12 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
923 | case ARIZONA_OUT2R_ENA_SHIFT: | 957 | case ARIZONA_OUT2R_ENA_SHIFT: |
924 | case ARIZONA_OUT3L_ENA_SHIFT: | 958 | case ARIZONA_OUT3L_ENA_SHIFT: |
925 | case ARIZONA_OUT3R_ENA_SHIFT: | 959 | case ARIZONA_OUT3R_ENA_SHIFT: |
960 | case ARIZONA_OUT4L_ENA_SHIFT: | ||
961 | case ARIZONA_OUT4R_ENA_SHIFT: | ||
926 | priv->out_down_pending--; | 962 | priv->out_down_pending--; |
927 | if (!priv->out_down_pending) { | 963 | if (!priv->out_down_pending && priv->out_down_delay) { |
964 | dev_dbg(codec->dev, "Power down delay: %d\n", | ||
965 | priv->out_down_delay); | ||
928 | msleep(priv->out_down_delay); | 966 | msleep(priv->out_down_delay); |
929 | priv->out_down_delay = 0; | 967 | priv->out_down_delay = 0; |
930 | } | 968 | } |
@@ -1920,8 +1958,8 @@ static struct { | |||
1920 | 1958 | ||
1921 | struct arizona_fll_cfg { | 1959 | struct arizona_fll_cfg { |
1922 | int n; | 1960 | int n; |
1923 | int theta; | 1961 | unsigned int theta; |
1924 | int lambda; | 1962 | unsigned int lambda; |
1925 | int refdiv; | 1963 | int refdiv; |
1926 | int outdiv; | 1964 | int outdiv; |
1927 | int fratio; | 1965 | int fratio; |
@@ -2188,13 +2226,13 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base, | |||
2188 | ARIZONA_FLL1_CTRL_UPD | cfg->n); | 2226 | ARIZONA_FLL1_CTRL_UPD | cfg->n); |
2189 | } | 2227 | } |
2190 | 2228 | ||
2191 | static int arizona_is_enabled_fll(struct arizona_fll *fll) | 2229 | static int arizona_is_enabled_fll(struct arizona_fll *fll, int base) |
2192 | { | 2230 | { |
2193 | struct arizona *arizona = fll->arizona; | 2231 | struct arizona *arizona = fll->arizona; |
2194 | unsigned int reg; | 2232 | unsigned int reg; |
2195 | int ret; | 2233 | int ret; |
2196 | 2234 | ||
2197 | ret = regmap_read(arizona->regmap, fll->base + 1, ®); | 2235 | ret = regmap_read(arizona->regmap, base + 1, ®); |
2198 | if (ret != 0) { | 2236 | if (ret != 0) { |
2199 | arizona_fll_err(fll, "Failed to read current state: %d\n", | 2237 | arizona_fll_err(fll, "Failed to read current state: %d\n", |
2200 | ret); | 2238 | ret); |
@@ -2208,21 +2246,24 @@ static int arizona_enable_fll(struct arizona_fll *fll) | |||
2208 | { | 2246 | { |
2209 | struct arizona *arizona = fll->arizona; | 2247 | struct arizona *arizona = fll->arizona; |
2210 | bool use_sync = false; | 2248 | bool use_sync = false; |
2211 | int already_enabled = arizona_is_enabled_fll(fll); | 2249 | int already_enabled = arizona_is_enabled_fll(fll, fll->base); |
2250 | int sync_enabled = arizona_is_enabled_fll(fll, fll->base + 0x10); | ||
2212 | struct arizona_fll_cfg cfg; | 2251 | struct arizona_fll_cfg cfg; |
2213 | int i; | 2252 | int i; |
2214 | unsigned int val; | 2253 | unsigned int val; |
2215 | 2254 | ||
2216 | if (already_enabled < 0) | 2255 | if (already_enabled < 0) |
2217 | return already_enabled; | 2256 | return already_enabled; |
2257 | if (sync_enabled < 0) | ||
2258 | return sync_enabled; | ||
2218 | 2259 | ||
2219 | if (already_enabled) { | 2260 | if (already_enabled) { |
2220 | /* Facilitate smooth refclk across the transition */ | 2261 | /* Facilitate smooth refclk across the transition */ |
2221 | regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9, | ||
2222 | ARIZONA_FLL1_GAIN_MASK, 0); | ||
2223 | regmap_update_bits(fll->arizona->regmap, fll->base + 1, | 2262 | regmap_update_bits(fll->arizona->regmap, fll->base + 1, |
2224 | ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN); | 2263 | ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN); |
2225 | udelay(32); | 2264 | udelay(32); |
2265 | regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9, | ||
2266 | ARIZONA_FLL1_GAIN_MASK, 0); | ||
2226 | } | 2267 | } |
2227 | 2268 | ||
2228 | /* | 2269 | /* |
@@ -2233,6 +2274,10 @@ static int arizona_enable_fll(struct arizona_fll *fll) | |||
2233 | fll->ref_src != fll->sync_src) { | 2274 | fll->ref_src != fll->sync_src) { |
2234 | arizona_calc_fll(fll, &cfg, fll->ref_freq, false); | 2275 | arizona_calc_fll(fll, &cfg, fll->ref_freq, false); |
2235 | 2276 | ||
2277 | /* Ref path hardcodes lambda to 65536 when sync is on */ | ||
2278 | if (fll->sync_src >= 0 && cfg.lambda) | ||
2279 | cfg.theta = (cfg.theta * (1 << 16)) / cfg.lambda; | ||
2280 | |||
2236 | arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src, | 2281 | arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src, |
2237 | false); | 2282 | false); |
2238 | if (fll->sync_src >= 0) { | 2283 | if (fll->sync_src >= 0) { |
@@ -2255,6 +2300,9 @@ static int arizona_enable_fll(struct arizona_fll *fll) | |||
2255 | return -EINVAL; | 2300 | return -EINVAL; |
2256 | } | 2301 | } |
2257 | 2302 | ||
2303 | if (already_enabled && !!sync_enabled != use_sync) | ||
2304 | arizona_fll_warn(fll, "Synchroniser changed on active FLL\n"); | ||
2305 | |||
2258 | /* | 2306 | /* |
2259 | * Increase the bandwidth if we're not using a low frequency | 2307 | * Increase the bandwidth if we're not using a low frequency |
2260 | * sync source. | 2308 | * sync source. |
@@ -2268,14 +2316,14 @@ static int arizona_enable_fll(struct arizona_fll *fll) | |||
2268 | ARIZONA_FLL1_SYNC_BW); | 2316 | ARIZONA_FLL1_SYNC_BW); |
2269 | 2317 | ||
2270 | if (!already_enabled) | 2318 | if (!already_enabled) |
2271 | pm_runtime_get(arizona->dev); | 2319 | pm_runtime_get_sync(arizona->dev); |
2272 | 2320 | ||
2273 | regmap_update_bits_async(arizona->regmap, fll->base + 1, | ||
2274 | ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); | ||
2275 | if (use_sync) | 2321 | if (use_sync) |
2276 | regmap_update_bits_async(arizona->regmap, fll->base + 0x11, | 2322 | regmap_update_bits_async(arizona->regmap, fll->base + 0x11, |
2277 | ARIZONA_FLL1_SYNC_ENA, | 2323 | ARIZONA_FLL1_SYNC_ENA, |
2278 | ARIZONA_FLL1_SYNC_ENA); | 2324 | ARIZONA_FLL1_SYNC_ENA); |
2325 | regmap_update_bits_async(arizona->regmap, fll->base + 1, | ||
2326 | ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); | ||
2279 | 2327 | ||
2280 | if (already_enabled) | 2328 | if (already_enabled) |
2281 | regmap_update_bits_async(arizona->regmap, fll->base + 1, | 2329 | regmap_update_bits_async(arizona->regmap, fll->base + 1, |
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 69da1ef3a17c..850aa338ba29 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h | |||
@@ -190,20 +190,21 @@ extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; | |||
190 | 190 | ||
191 | #define ARIZONA_DSP_ROUTES(name) \ | 191 | #define ARIZONA_DSP_ROUTES(name) \ |
192 | { name, NULL, name " Preloader"}, \ | 192 | { name, NULL, name " Preloader"}, \ |
193 | { name " Preloader", NULL, name " Aux 1" }, \ | 193 | { name " Preloader", NULL, "SYSCLK" }, \ |
194 | { name " Preloader", NULL, name " Aux 2" }, \ | 194 | { name, NULL, name " Aux 1" }, \ |
195 | { name " Preloader", NULL, name " Aux 3" }, \ | 195 | { name, NULL, name " Aux 2" }, \ |
196 | { name " Preloader", NULL, name " Aux 4" }, \ | 196 | { name, NULL, name " Aux 3" }, \ |
197 | { name " Preloader", NULL, name " Aux 5" }, \ | 197 | { name, NULL, name " Aux 4" }, \ |
198 | { name " Preloader", NULL, name " Aux 6" }, \ | 198 | { name, NULL, name " Aux 5" }, \ |
199 | { name, NULL, name " Aux 6" }, \ | ||
199 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \ | 200 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \ |
200 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \ | 201 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \ |
201 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \ | 202 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \ |
202 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \ | 203 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \ |
203 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \ | 204 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \ |
204 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \ | 205 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \ |
205 | ARIZONA_MIXER_ROUTES(name " Preloader", name "L"), \ | 206 | ARIZONA_MIXER_ROUTES(name, name "L"), \ |
206 | ARIZONA_MIXER_ROUTES(name " Preloader", name "R") | 207 | ARIZONA_MIXER_ROUTES(name, name "R") |
207 | 208 | ||
208 | #define ARIZONA_EQ_CONTROL(xname, xbase) \ | 209 | #define ARIZONA_EQ_CONTROL(xname, xbase) \ |
209 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 210 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c index 2a8d0ee141d4..8014e697d540 100644 --- a/sound/soc/codecs/bt-sco.c +++ b/sound/soc/codecs/bt-sco.c | |||
@@ -63,10 +63,12 @@ static struct snd_soc_dai_driver bt_sco_dai[] = { | |||
63 | }; | 63 | }; |
64 | 64 | ||
65 | static struct snd_soc_codec_driver soc_codec_dev_bt_sco = { | 65 | static struct snd_soc_codec_driver soc_codec_dev_bt_sco = { |
66 | .dapm_widgets = bt_sco_widgets, | 66 | .component_driver = { |
67 | .num_dapm_widgets = ARRAY_SIZE(bt_sco_widgets), | 67 | .dapm_widgets = bt_sco_widgets, |
68 | .dapm_routes = bt_sco_routes, | 68 | .num_dapm_widgets = ARRAY_SIZE(bt_sco_widgets), |
69 | .num_dapm_routes = ARRAY_SIZE(bt_sco_routes), | 69 | .dapm_routes = bt_sco_routes, |
70 | .num_dapm_routes = ARRAY_SIZE(bt_sco_routes), | ||
71 | }, | ||
70 | }; | 72 | }; |
71 | 73 | ||
72 | static int bt_sco_probe(struct platform_device *pdev) | 74 | static int bt_sco_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 1c895a53001d..7a2d9a2ee427 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c | |||
@@ -131,8 +131,10 @@ static struct regmap *cq93vc_get_regmap(struct device *dev) | |||
131 | static struct snd_soc_codec_driver soc_codec_dev_cq93vc = { | 131 | static struct snd_soc_codec_driver soc_codec_dev_cq93vc = { |
132 | .set_bias_level = cq93vc_set_bias_level, | 132 | .set_bias_level = cq93vc_set_bias_level, |
133 | .get_regmap = cq93vc_get_regmap, | 133 | .get_regmap = cq93vc_get_regmap, |
134 | .controls = cq93vc_snd_controls, | 134 | .component_driver = { |
135 | .num_controls = ARRAY_SIZE(cq93vc_snd_controls), | 135 | .controls = cq93vc_snd_controls, |
136 | .num_controls = ARRAY_SIZE(cq93vc_snd_controls), | ||
137 | }, | ||
136 | }; | 138 | }; |
137 | 139 | ||
138 | static int cq93vc_platform_probe(struct platform_device *pdev) | 140 | static int cq93vc_platform_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c index 287d13740be4..7e9806206648 100644 --- a/sound/soc/codecs/cs35l32.c +++ b/sound/soc/codecs/cs35l32.c | |||
@@ -231,13 +231,14 @@ static int cs35l32_codec_set_sysclk(struct snd_soc_codec *codec, | |||
231 | static const struct snd_soc_codec_driver soc_codec_dev_cs35l32 = { | 231 | static const struct snd_soc_codec_driver soc_codec_dev_cs35l32 = { |
232 | .set_sysclk = cs35l32_codec_set_sysclk, | 232 | .set_sysclk = cs35l32_codec_set_sysclk, |
233 | 233 | ||
234 | .dapm_widgets = cs35l32_dapm_widgets, | 234 | .component_driver = { |
235 | .num_dapm_widgets = ARRAY_SIZE(cs35l32_dapm_widgets), | 235 | .controls = cs35l32_snd_controls, |
236 | .dapm_routes = cs35l32_audio_map, | 236 | .num_controls = ARRAY_SIZE(cs35l32_snd_controls), |
237 | .num_dapm_routes = ARRAY_SIZE(cs35l32_audio_map), | 237 | .dapm_widgets = cs35l32_dapm_widgets, |
238 | 238 | .num_dapm_widgets = ARRAY_SIZE(cs35l32_dapm_widgets), | |
239 | .controls = cs35l32_snd_controls, | 239 | .dapm_routes = cs35l32_audio_map, |
240 | .num_controls = ARRAY_SIZE(cs35l32_snd_controls), | 240 | .num_dapm_routes = ARRAY_SIZE(cs35l32_audio_map), |
241 | }, | ||
241 | }; | 242 | }; |
242 | 243 | ||
243 | /* Current and threshold powerup sequence Pg37 in datasheet */ | 244 | /* Current and threshold powerup sequence Pg37 in datasheet */ |
diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c index 6f9c1addcd7f..6df29fa30fb9 100644 --- a/sound/soc/codecs/cs35l33.c +++ b/sound/soc/codecs/cs35l33.c | |||
@@ -837,13 +837,14 @@ static struct snd_soc_codec_driver soc_codec_dev_cs35l33 = { | |||
837 | .set_bias_level = cs35l33_set_bias_level, | 837 | .set_bias_level = cs35l33_set_bias_level, |
838 | .set_sysclk = cs35l33_codec_set_sysclk, | 838 | .set_sysclk = cs35l33_codec_set_sysclk, |
839 | 839 | ||
840 | .dapm_widgets = cs35l33_dapm_widgets, | 840 | .component_driver = { |
841 | .num_dapm_widgets = ARRAY_SIZE(cs35l33_dapm_widgets), | 841 | .controls = cs35l33_snd_controls, |
842 | .dapm_routes = cs35l33_audio_map, | 842 | .num_controls = ARRAY_SIZE(cs35l33_snd_controls), |
843 | .num_dapm_routes = ARRAY_SIZE(cs35l33_audio_map), | 843 | .dapm_widgets = cs35l33_dapm_widgets, |
844 | .controls = cs35l33_snd_controls, | 844 | .num_dapm_widgets = ARRAY_SIZE(cs35l33_dapm_widgets), |
845 | .num_controls = ARRAY_SIZE(cs35l33_snd_controls), | 845 | .dapm_routes = cs35l33_audio_map, |
846 | 846 | .num_dapm_routes = ARRAY_SIZE(cs35l33_audio_map), | |
847 | }, | ||
847 | .idle_bias_off = true, | 848 | .idle_bias_off = true, |
848 | }; | 849 | }; |
849 | 850 | ||
diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c index 55db19ddc5ff..fd966bb851cb 100644 --- a/sound/soc/codecs/cs4265.c +++ b/sound/soc/codecs/cs4265.c | |||
@@ -547,13 +547,14 @@ static struct snd_soc_dai_driver cs4265_dai[] = { | |||
547 | static const struct snd_soc_codec_driver soc_codec_cs4265 = { | 547 | static const struct snd_soc_codec_driver soc_codec_cs4265 = { |
548 | .set_bias_level = cs4265_set_bias_level, | 548 | .set_bias_level = cs4265_set_bias_level, |
549 | 549 | ||
550 | .dapm_widgets = cs4265_dapm_widgets, | 550 | .component_driver = { |
551 | .num_dapm_widgets = ARRAY_SIZE(cs4265_dapm_widgets), | 551 | .controls = cs4265_snd_controls, |
552 | .dapm_routes = cs4265_audio_map, | 552 | .num_controls = ARRAY_SIZE(cs4265_snd_controls), |
553 | .num_dapm_routes = ARRAY_SIZE(cs4265_audio_map), | 553 | .dapm_widgets = cs4265_dapm_widgets, |
554 | 554 | .num_dapm_widgets = ARRAY_SIZE(cs4265_dapm_widgets), | |
555 | .controls = cs4265_snd_controls, | 555 | .dapm_routes = cs4265_audio_map, |
556 | .num_controls = ARRAY_SIZE(cs4265_snd_controls), | 556 | .num_dapm_routes = ARRAY_SIZE(cs4265_audio_map), |
557 | }, | ||
557 | }; | 558 | }; |
558 | 559 | ||
559 | static const struct regmap_config cs4265_regmap = { | 560 | static const struct regmap_config cs4265_regmap = { |
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index e07807d96b68..18baea2f7d65 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c | |||
@@ -617,12 +617,14 @@ static const struct snd_soc_codec_driver soc_codec_device_cs4270 = { | |||
617 | .suspend = cs4270_soc_suspend, | 617 | .suspend = cs4270_soc_suspend, |
618 | .resume = cs4270_soc_resume, | 618 | .resume = cs4270_soc_resume, |
619 | 619 | ||
620 | .controls = cs4270_snd_controls, | 620 | .component_driver = { |
621 | .num_controls = ARRAY_SIZE(cs4270_snd_controls), | 621 | .controls = cs4270_snd_controls, |
622 | .dapm_widgets = cs4270_dapm_widgets, | 622 | .num_controls = ARRAY_SIZE(cs4270_snd_controls), |
623 | .num_dapm_widgets = ARRAY_SIZE(cs4270_dapm_widgets), | 623 | .dapm_widgets = cs4270_dapm_widgets, |
624 | .dapm_routes = cs4270_dapm_routes, | 624 | .num_dapm_widgets = ARRAY_SIZE(cs4270_dapm_widgets), |
625 | .num_dapm_routes = ARRAY_SIZE(cs4270_dapm_routes), | 625 | .dapm_routes = cs4270_dapm_routes, |
626 | .num_dapm_routes = ARRAY_SIZE(cs4270_dapm_routes), | ||
627 | }, | ||
626 | }; | 628 | }; |
627 | 629 | ||
628 | /* | 630 | /* |
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index 0c0010b25421..8c0f3b89b5bc 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c | |||
@@ -645,12 +645,14 @@ static struct snd_soc_codec_driver soc_codec_dev_cs4271 = { | |||
645 | .suspend = cs4271_soc_suspend, | 645 | .suspend = cs4271_soc_suspend, |
646 | .resume = cs4271_soc_resume, | 646 | .resume = cs4271_soc_resume, |
647 | 647 | ||
648 | .controls = cs4271_snd_controls, | 648 | .component_driver = { |
649 | .num_controls = ARRAY_SIZE(cs4271_snd_controls), | 649 | .controls = cs4271_snd_controls, |
650 | .dapm_widgets = cs4271_dapm_widgets, | 650 | .num_controls = ARRAY_SIZE(cs4271_snd_controls), |
651 | .num_dapm_widgets = ARRAY_SIZE(cs4271_dapm_widgets), | 651 | .dapm_widgets = cs4271_dapm_widgets, |
652 | .dapm_routes = cs4271_dapm_routes, | 652 | .num_dapm_widgets = ARRAY_SIZE(cs4271_dapm_widgets), |
653 | .num_dapm_routes = ARRAY_SIZE(cs4271_dapm_routes), | 653 | .dapm_routes = cs4271_dapm_routes, |
654 | .num_dapm_routes = ARRAY_SIZE(cs4271_dapm_routes), | ||
655 | }, | ||
654 | }; | 656 | }; |
655 | 657 | ||
656 | static int cs4271_common_probe(struct device *dev, | 658 | static int cs4271_common_probe(struct device *dev, |
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 35488f14e237..96cfe38943cd 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c | |||
@@ -507,12 +507,14 @@ static int cs42l51_codec_probe(struct snd_soc_codec *codec) | |||
507 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { | 507 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { |
508 | .probe = cs42l51_codec_probe, | 508 | .probe = cs42l51_codec_probe, |
509 | 509 | ||
510 | .controls = cs42l51_snd_controls, | 510 | .component_driver = { |
511 | .num_controls = ARRAY_SIZE(cs42l51_snd_controls), | 511 | .controls = cs42l51_snd_controls, |
512 | .dapm_widgets = cs42l51_dapm_widgets, | 512 | .num_controls = ARRAY_SIZE(cs42l51_snd_controls), |
513 | .num_dapm_widgets = ARRAY_SIZE(cs42l51_dapm_widgets), | 513 | .dapm_widgets = cs42l51_dapm_widgets, |
514 | .dapm_routes = cs42l51_routes, | 514 | .num_dapm_widgets = ARRAY_SIZE(cs42l51_dapm_widgets), |
515 | .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), | 515 | .dapm_routes = cs42l51_routes, |
516 | .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), | ||
517 | }, | ||
516 | }; | 518 | }; |
517 | 519 | ||
518 | const struct regmap_config cs42l51_regmap = { | 520 | const struct regmap_config cs42l51_regmap = { |
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 47b97fcefb0b..0d9c4a57301b 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c | |||
@@ -1056,13 +1056,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_cs42l52 = { | |||
1056 | .set_bias_level = cs42l52_set_bias_level, | 1056 | .set_bias_level = cs42l52_set_bias_level, |
1057 | .suspend_bias_off = true, | 1057 | .suspend_bias_off = true, |
1058 | 1058 | ||
1059 | .dapm_widgets = cs42l52_dapm_widgets, | 1059 | .component_driver = { |
1060 | .num_dapm_widgets = ARRAY_SIZE(cs42l52_dapm_widgets), | 1060 | .controls = cs42l52_snd_controls, |
1061 | .dapm_routes = cs42l52_audio_map, | 1061 | .num_controls = ARRAY_SIZE(cs42l52_snd_controls), |
1062 | .num_dapm_routes = ARRAY_SIZE(cs42l52_audio_map), | 1062 | .dapm_widgets = cs42l52_dapm_widgets, |
1063 | 1063 | .num_dapm_widgets = ARRAY_SIZE(cs42l52_dapm_widgets), | |
1064 | .controls = cs42l52_snd_controls, | 1064 | .dapm_routes = cs42l52_audio_map, |
1065 | .num_controls = ARRAY_SIZE(cs42l52_snd_controls), | 1065 | .num_dapm_routes = ARRAY_SIZE(cs42l52_audio_map), |
1066 | }, | ||
1066 | }; | 1067 | }; |
1067 | 1068 | ||
1068 | /* Current and threshold powerup sequence Pg37 */ | 1069 | /* Current and threshold powerup sequence Pg37 */ |
diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index eec1ff853b98..54c1768bc818 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c | |||
@@ -1121,13 +1121,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_cs42l56 = { | |||
1121 | .set_bias_level = cs42l56_set_bias_level, | 1121 | .set_bias_level = cs42l56_set_bias_level, |
1122 | .suspend_bias_off = true, | 1122 | .suspend_bias_off = true, |
1123 | 1123 | ||
1124 | .dapm_widgets = cs42l56_dapm_widgets, | 1124 | .component_driver = { |
1125 | .num_dapm_widgets = ARRAY_SIZE(cs42l56_dapm_widgets), | 1125 | .controls = cs42l56_snd_controls, |
1126 | .dapm_routes = cs42l56_audio_map, | 1126 | .num_controls = ARRAY_SIZE(cs42l56_snd_controls), |
1127 | .num_dapm_routes = ARRAY_SIZE(cs42l56_audio_map), | 1127 | .dapm_widgets = cs42l56_dapm_widgets, |
1128 | 1128 | .num_dapm_widgets = ARRAY_SIZE(cs42l56_dapm_widgets), | |
1129 | .controls = cs42l56_snd_controls, | 1129 | .dapm_routes = cs42l56_audio_map, |
1130 | .num_controls = ARRAY_SIZE(cs42l56_snd_controls), | 1130 | .num_dapm_routes = ARRAY_SIZE(cs42l56_audio_map), |
1131 | }, | ||
1131 | }; | 1132 | }; |
1132 | 1133 | ||
1133 | static const struct regmap_config cs42l56_regmap = { | 1134 | static const struct regmap_config cs42l56_regmap = { |
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 42a8fd4e1f9b..71ba5605495f 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c | |||
@@ -794,7 +794,7 @@ struct cs42l73_mclk_div { | |||
794 | u8 mmcc; | 794 | u8 mmcc; |
795 | }; | 795 | }; |
796 | 796 | ||
797 | static struct cs42l73_mclk_div cs42l73_mclk_coeffs[] = { | 797 | static const struct cs42l73_mclk_div cs42l73_mclk_coeffs[] = { |
798 | /* MCLK, Sample Rate, xMMCC[5:0] */ | 798 | /* MCLK, Sample Rate, xMMCC[5:0] */ |
799 | {5644800, 11025, 0x30}, | 799 | {5644800, 11025, 0x30}, |
800 | {5644800, 22050, 0x20}, | 800 | {5644800, 22050, 0x20}, |
@@ -844,7 +844,7 @@ struct cs42l73_mclkx_div { | |||
844 | u8 mclkdiv; | 844 | u8 mclkdiv; |
845 | }; | 845 | }; |
846 | 846 | ||
847 | static struct cs42l73_mclkx_div cs42l73_mclkx_coeffs[] = { | 847 | static const struct cs42l73_mclkx_div cs42l73_mclkx_coeffs[] = { |
848 | {5644800, 1, 0}, /* 5644800 */ | 848 | {5644800, 1, 0}, /* 5644800 */ |
849 | {6000000, 1, 0}, /* 6000000 */ | 849 | {6000000, 1, 0}, /* 6000000 */ |
850 | {6144000, 1, 0}, /* 6144000 */ | 850 | {6144000, 1, 0}, /* 6144000 */ |
@@ -1257,13 +1257,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_cs42l73 = { | |||
1257 | .set_bias_level = cs42l73_set_bias_level, | 1257 | .set_bias_level = cs42l73_set_bias_level, |
1258 | .suspend_bias_off = true, | 1258 | .suspend_bias_off = true, |
1259 | 1259 | ||
1260 | .dapm_widgets = cs42l73_dapm_widgets, | 1260 | .component_driver = { |
1261 | .num_dapm_widgets = ARRAY_SIZE(cs42l73_dapm_widgets), | 1261 | .controls = cs42l73_snd_controls, |
1262 | .dapm_routes = cs42l73_audio_map, | 1262 | .num_controls = ARRAY_SIZE(cs42l73_snd_controls), |
1263 | .num_dapm_routes = ARRAY_SIZE(cs42l73_audio_map), | 1263 | .dapm_widgets = cs42l73_dapm_widgets, |
1264 | 1264 | .num_dapm_widgets = ARRAY_SIZE(cs42l73_dapm_widgets), | |
1265 | .controls = cs42l73_snd_controls, | 1265 | .dapm_routes = cs42l73_audio_map, |
1266 | .num_controls = ARRAY_SIZE(cs42l73_snd_controls), | 1266 | .num_dapm_routes = ARRAY_SIZE(cs42l73_audio_map), |
1267 | }, | ||
1267 | }; | 1268 | }; |
1268 | 1269 | ||
1269 | static const struct regmap_config cs42l73_regmap = { | 1270 | static const struct regmap_config cs42l73_regmap = { |
diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c index 1179101b2b05..b4d87379d2bc 100644 --- a/sound/soc/codecs/cs42xx8.c +++ b/sound/soc/codecs/cs42xx8.c | |||
@@ -411,12 +411,14 @@ static const struct snd_soc_codec_driver cs42xx8_driver = { | |||
411 | .probe = cs42xx8_codec_probe, | 411 | .probe = cs42xx8_codec_probe, |
412 | .idle_bias_off = true, | 412 | .idle_bias_off = true, |
413 | 413 | ||
414 | .controls = cs42xx8_snd_controls, | 414 | .component_driver = { |
415 | .num_controls = ARRAY_SIZE(cs42xx8_snd_controls), | 415 | .controls = cs42xx8_snd_controls, |
416 | .dapm_widgets = cs42xx8_dapm_widgets, | 416 | .num_controls = ARRAY_SIZE(cs42xx8_snd_controls), |
417 | .num_dapm_widgets = ARRAY_SIZE(cs42xx8_dapm_widgets), | 417 | .dapm_widgets = cs42xx8_dapm_widgets, |
418 | .dapm_routes = cs42xx8_dapm_routes, | 418 | .num_dapm_widgets = ARRAY_SIZE(cs42xx8_dapm_widgets), |
419 | .num_dapm_routes = ARRAY_SIZE(cs42xx8_dapm_routes), | 419 | .dapm_routes = cs42xx8_dapm_routes, |
420 | .num_dapm_routes = ARRAY_SIZE(cs42xx8_dapm_routes), | ||
421 | }, | ||
420 | }; | 422 | }; |
421 | 423 | ||
422 | const struct cs42xx8_driver_data cs42448_data = { | 424 | const struct cs42xx8_driver_data cs42448_data = { |
diff --git a/sound/soc/codecs/cs4349.c b/sound/soc/codecs/cs4349.c index 0ac8fc5ed4ae..231ca935cdf3 100644 --- a/sound/soc/codecs/cs4349.c +++ b/sound/soc/codecs/cs4349.c | |||
@@ -256,13 +256,14 @@ static struct snd_soc_dai_driver cs4349_dai = { | |||
256 | }; | 256 | }; |
257 | 257 | ||
258 | static struct snd_soc_codec_driver soc_codec_dev_cs4349 = { | 258 | static struct snd_soc_codec_driver soc_codec_dev_cs4349 = { |
259 | .controls = cs4349_snd_controls, | 259 | .component_driver = { |
260 | .num_controls = ARRAY_SIZE(cs4349_snd_controls), | 260 | .controls = cs4349_snd_controls, |
261 | 261 | .num_controls = ARRAY_SIZE(cs4349_snd_controls), | |
262 | .dapm_widgets = cs4349_dapm_widgets, | 262 | .dapm_widgets = cs4349_dapm_widgets, |
263 | .num_dapm_widgets = ARRAY_SIZE(cs4349_dapm_widgets), | 263 | .num_dapm_widgets = ARRAY_SIZE(cs4349_dapm_widgets), |
264 | .dapm_routes = cs4349_routes, | 264 | .dapm_routes = cs4349_routes, |
265 | .num_dapm_routes = ARRAY_SIZE(cs4349_routes), | 265 | .num_dapm_routes = ARRAY_SIZE(cs4349_routes), |
266 | }, | ||
266 | }; | 267 | }; |
267 | 268 | ||
268 | static const struct regmap_config cs4349_regmap = { | 269 | static const struct regmap_config cs4349_regmap = { |
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c index 954a4f5d3338..5b22564f037c 100644 --- a/sound/soc/codecs/cs47l24.c +++ b/sound/soc/codecs/cs47l24.c | |||
@@ -746,6 +746,16 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = { | |||
746 | { "IN2L", NULL, "SYSCLK" }, | 746 | { "IN2L", NULL, "SYSCLK" }, |
747 | { "IN2R", NULL, "SYSCLK" }, | 747 | { "IN2R", NULL, "SYSCLK" }, |
748 | 748 | ||
749 | { "ASRC1L", NULL, "SYSCLK" }, | ||
750 | { "ASRC1R", NULL, "SYSCLK" }, | ||
751 | { "ASRC2L", NULL, "SYSCLK" }, | ||
752 | { "ASRC2R", NULL, "SYSCLK" }, | ||
753 | |||
754 | { "ASRC1L", NULL, "ASYNCCLK" }, | ||
755 | { "ASRC1R", NULL, "ASYNCCLK" }, | ||
756 | { "ASRC2L", NULL, "ASYNCCLK" }, | ||
757 | { "ASRC2R", NULL, "ASYNCCLK" }, | ||
758 | |||
749 | { "MICBIAS1", NULL, "MICVDD" }, | 759 | { "MICBIAS1", NULL, "MICVDD" }, |
750 | { "MICBIAS2", NULL, "MICVDD" }, | 760 | { "MICBIAS2", NULL, "MICVDD" }, |
751 | 761 | ||
@@ -804,7 +814,6 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = { | |||
804 | { "AIF3 Capture", NULL, "SYSCLK" }, | 814 | { "AIF3 Capture", NULL, "SYSCLK" }, |
805 | 815 | ||
806 | { "Voice Control DSP", NULL, "DSP3" }, | 816 | { "Voice Control DSP", NULL, "DSP3" }, |
807 | { "Voice Control DSP", NULL, "SYSCLK" }, | ||
808 | 817 | ||
809 | { "IN1L PGA", NULL, "IN1L" }, | 818 | { "IN1L PGA", NULL, "IN1L" }, |
810 | { "IN1R PGA", NULL, "IN1R" }, | 819 | { "IN1R PGA", NULL, "IN1R" }, |
@@ -813,7 +822,6 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = { | |||
813 | { "IN2R PGA", NULL, "IN2R" }, | 822 | { "IN2R PGA", NULL, "IN2R" }, |
814 | 823 | ||
815 | { "Audio Trace DSP", NULL, "DSP2" }, | 824 | { "Audio Trace DSP", NULL, "DSP2" }, |
816 | { "Audio Trace DSP", NULL, "SYSCLK" }, | ||
817 | 825 | ||
818 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), | 826 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), |
819 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), | 827 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), |
@@ -1190,12 +1198,14 @@ static struct snd_soc_codec_driver soc_codec_dev_cs47l24 = { | |||
1190 | .set_sysclk = arizona_set_sysclk, | 1198 | .set_sysclk = arizona_set_sysclk, |
1191 | .set_pll = cs47l24_set_fll, | 1199 | .set_pll = cs47l24_set_fll, |
1192 | 1200 | ||
1193 | .controls = cs47l24_snd_controls, | 1201 | .component_driver = { |
1194 | .num_controls = ARRAY_SIZE(cs47l24_snd_controls), | 1202 | .controls = cs47l24_snd_controls, |
1195 | .dapm_widgets = cs47l24_dapm_widgets, | 1203 | .num_controls = ARRAY_SIZE(cs47l24_snd_controls), |
1196 | .num_dapm_widgets = ARRAY_SIZE(cs47l24_dapm_widgets), | 1204 | .dapm_widgets = cs47l24_dapm_widgets, |
1197 | .dapm_routes = cs47l24_dapm_routes, | 1205 | .num_dapm_widgets = ARRAY_SIZE(cs47l24_dapm_widgets), |
1198 | .num_dapm_routes = ARRAY_SIZE(cs47l24_dapm_routes), | 1206 | .dapm_routes = cs47l24_dapm_routes, |
1207 | .num_dapm_routes = ARRAY_SIZE(cs47l24_dapm_routes), | ||
1208 | }, | ||
1199 | }; | 1209 | }; |
1200 | 1210 | ||
1201 | static struct snd_compr_ops cs47l24_compr_ops = { | 1211 | static struct snd_compr_ops cs47l24_compr_ops = { |
diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c index 2c0d9c430a8c..cb47fb595ff4 100644 --- a/sound/soc/codecs/cs53l30.c +++ b/sound/soc/codecs/cs53l30.c | |||
@@ -466,7 +466,7 @@ struct cs53l30_mclk_div { | |||
466 | u8 mclk_int_scale; | 466 | u8 mclk_int_scale; |
467 | }; | 467 | }; |
468 | 468 | ||
469 | static struct cs53l30_mclk_div cs53l30_mclk_coeffs[] = { | 469 | static const struct cs53l30_mclk_div cs53l30_mclk_coeffs[] = { |
470 | /* NOTE: Enable MCLK_INT_SCALE to save power. */ | 470 | /* NOTE: Enable MCLK_INT_SCALE to save power. */ |
471 | 471 | ||
472 | /* MCLK, Sample Rate, asp_rate, internal_fs_ratio, mclk_int_scale */ | 472 | /* MCLK, Sample Rate, asp_rate, internal_fs_ratio, mclk_int_scale */ |
@@ -511,7 +511,7 @@ struct cs53l30_mclkx_div { | |||
511 | u8 mclkdiv; | 511 | u8 mclkdiv; |
512 | }; | 512 | }; |
513 | 513 | ||
514 | static struct cs53l30_mclkx_div cs53l30_mclkx_coeffs[] = { | 514 | static const struct cs53l30_mclkx_div cs53l30_mclkx_coeffs[] = { |
515 | {5644800, 1, CS53L30_MCLK_DIV_BY_1}, | 515 | {5644800, 1, CS53L30_MCLK_DIV_BY_1}, |
516 | {6000000, 1, CS53L30_MCLK_DIV_BY_1}, | 516 | {6000000, 1, CS53L30_MCLK_DIV_BY_1}, |
517 | {6144000, 1, CS53L30_MCLK_DIV_BY_1}, | 517 | {6144000, 1, CS53L30_MCLK_DIV_BY_1}, |
@@ -897,13 +897,14 @@ static struct snd_soc_codec_driver cs53l30_driver = { | |||
897 | .set_bias_level = cs53l30_set_bias_level, | 897 | .set_bias_level = cs53l30_set_bias_level, |
898 | .idle_bias_off = true, | 898 | .idle_bias_off = true, |
899 | 899 | ||
900 | .dapm_widgets = cs53l30_dapm_widgets, | 900 | .component_driver = { |
901 | .num_dapm_widgets = ARRAY_SIZE(cs53l30_dapm_widgets), | 901 | .controls = cs53l30_snd_controls, |
902 | .dapm_routes = cs53l30_dapm_routes, | 902 | .num_controls = ARRAY_SIZE(cs53l30_snd_controls), |
903 | .num_dapm_routes = ARRAY_SIZE(cs53l30_dapm_routes), | 903 | .dapm_widgets = cs53l30_dapm_widgets, |
904 | 904 | .num_dapm_widgets = ARRAY_SIZE(cs53l30_dapm_widgets), | |
905 | .controls = cs53l30_snd_controls, | 905 | .dapm_routes = cs53l30_dapm_routes, |
906 | .num_controls = ARRAY_SIZE(cs53l30_snd_controls), | 906 | .num_dapm_routes = ARRAY_SIZE(cs53l30_dapm_routes), |
907 | }, | ||
907 | }; | 908 | }; |
908 | 909 | ||
909 | static struct regmap_config cs53l30_regmap = { | 910 | static struct regmap_config cs53l30_regmap = { |
@@ -999,8 +1000,8 @@ static int cs53l30_i2c_probe(struct i2c_client *client, | |||
999 | /* Check if MCLK provided */ | 1000 | /* Check if MCLK provided */ |
1000 | cs53l30->mclk = devm_clk_get(dev, "mclk"); | 1001 | cs53l30->mclk = devm_clk_get(dev, "mclk"); |
1001 | if (IS_ERR(cs53l30->mclk)) { | 1002 | if (IS_ERR(cs53l30->mclk)) { |
1002 | if (PTR_ERR(cs53l30->mclk) == -EPROBE_DEFER) { | 1003 | if (PTR_ERR(cs53l30->mclk) != -ENOENT) { |
1003 | ret = -EPROBE_DEFER; | 1004 | ret = PTR_ERR(cs53l30->mclk); |
1004 | goto error; | 1005 | goto error; |
1005 | } | 1006 | } |
1006 | /* Otherwise mark the mclk pointer to NULL */ | 1007 | /* Otherwise mark the mclk pointer to NULL */ |
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index fb3885fe0afb..2c12471e42a6 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c | |||
@@ -407,10 +407,12 @@ static struct snd_soc_codec_driver cx20442_codec_dev = { | |||
407 | .reg_word_size = sizeof(u8), | 407 | .reg_word_size = sizeof(u8), |
408 | .read = cx20442_read_reg_cache, | 408 | .read = cx20442_read_reg_cache, |
409 | .write = cx20442_write, | 409 | .write = cx20442_write, |
410 | .dapm_widgets = cx20442_dapm_widgets, | 410 | .component_driver = { |
411 | .num_dapm_widgets = ARRAY_SIZE(cx20442_dapm_widgets), | 411 | .dapm_widgets = cx20442_dapm_widgets, |
412 | .dapm_routes = cx20442_audio_map, | 412 | .num_dapm_widgets = ARRAY_SIZE(cx20442_dapm_widgets), |
413 | .num_dapm_routes = ARRAY_SIZE(cx20442_audio_map), | 413 | .dapm_routes = cx20442_audio_map, |
414 | .num_dapm_routes = ARRAY_SIZE(cx20442_audio_map), | ||
415 | }, | ||
414 | }; | 416 | }; |
415 | 417 | ||
416 | static int cx20442_platform_probe(struct platform_device *pdev) | 418 | static int cx20442_platform_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index af23a61b7b28..17053dfc94cf 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c | |||
@@ -1167,13 +1167,14 @@ static int da7210_probe(struct snd_soc_codec *codec) | |||
1167 | static struct snd_soc_codec_driver soc_codec_dev_da7210 = { | 1167 | static struct snd_soc_codec_driver soc_codec_dev_da7210 = { |
1168 | .probe = da7210_probe, | 1168 | .probe = da7210_probe, |
1169 | 1169 | ||
1170 | .controls = da7210_snd_controls, | 1170 | .component_driver = { |
1171 | .num_controls = ARRAY_SIZE(da7210_snd_controls), | 1171 | .controls = da7210_snd_controls, |
1172 | 1172 | .num_controls = ARRAY_SIZE(da7210_snd_controls), | |
1173 | .dapm_widgets = da7210_dapm_widgets, | 1173 | .dapm_widgets = da7210_dapm_widgets, |
1174 | .num_dapm_widgets = ARRAY_SIZE(da7210_dapm_widgets), | 1174 | .num_dapm_widgets = ARRAY_SIZE(da7210_dapm_widgets), |
1175 | .dapm_routes = da7210_audio_map, | 1175 | .dapm_routes = da7210_audio_map, |
1176 | .num_dapm_routes = ARRAY_SIZE(da7210_audio_map), | 1176 | .num_dapm_routes = ARRAY_SIZE(da7210_audio_map), |
1177 | }, | ||
1177 | }; | 1178 | }; |
1178 | 1179 | ||
1179 | #if IS_ENABLED(CONFIG_I2C) | 1180 | #if IS_ENABLED(CONFIG_I2C) |
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index bcf1834c5648..12da55882c06 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c | |||
@@ -750,11 +750,18 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w, | |||
750 | snd_soc_update_bits(codec, DA7213_PC_COUNT, | 750 | snd_soc_update_bits(codec, DA7213_PC_COUNT, |
751 | DA7213_PC_FREERUN_MASK, 0); | 751 | DA7213_PC_FREERUN_MASK, 0); |
752 | 752 | ||
753 | /* Slave mode, if SRM not enabled no need for status checks */ | 753 | /* If SRM not enabled then nothing more to do */ |
754 | pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL); | 754 | pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL); |
755 | if (!(pll_ctrl & DA7213_PLL_SRM_EN)) | 755 | if (!(pll_ctrl & DA7213_PLL_SRM_EN)) |
756 | return 0; | 756 | return 0; |
757 | 757 | ||
758 | /* Assist 32KHz mode PLL lock */ | ||
759 | if (pll_ctrl & DA7213_PLL_32K_MODE) { | ||
760 | snd_soc_write(codec, 0xF0, 0x8B); | ||
761 | snd_soc_write(codec, 0xF2, 0x03); | ||
762 | snd_soc_write(codec, 0xF0, 0x00); | ||
763 | } | ||
764 | |||
758 | /* Check SRM has locked */ | 765 | /* Check SRM has locked */ |
759 | do { | 766 | do { |
760 | pll_status = snd_soc_read(codec, DA7213_PLL_STATUS); | 767 | pll_status = snd_soc_read(codec, DA7213_PLL_STATUS); |
@@ -771,6 +778,14 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w, | |||
771 | 778 | ||
772 | return 0; | 779 | return 0; |
773 | case SND_SOC_DAPM_POST_PMD: | 780 | case SND_SOC_DAPM_POST_PMD: |
781 | /* Revert 32KHz PLL lock udpates if applied previously */ | ||
782 | pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL); | ||
783 | if (pll_ctrl & DA7213_PLL_32K_MODE) { | ||
784 | snd_soc_write(codec, 0xF0, 0x8B); | ||
785 | snd_soc_write(codec, 0xF2, 0x01); | ||
786 | snd_soc_write(codec, 0xF0, 0x00); | ||
787 | } | ||
788 | |||
774 | /* PC free-running */ | 789 | /* PC free-running */ |
775 | snd_soc_update_bits(codec, DA7213_PC_COUNT, | 790 | snd_soc_update_bits(codec, DA7213_PC_COUNT, |
776 | DA7213_PC_FREERUN_MASK, | 791 | DA7213_PC_FREERUN_MASK, |
@@ -1297,10 +1312,13 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
1297 | 1312 | ||
1298 | switch (clk_id) { | 1313 | switch (clk_id) { |
1299 | case DA7213_CLKSRC_MCLK: | 1314 | case DA7213_CLKSRC_MCLK: |
1300 | da7213->mclk_squarer_en = false; | 1315 | snd_soc_update_bits(codec, DA7213_PLL_CTRL, |
1316 | DA7213_PLL_MCLK_SQR_EN, 0); | ||
1301 | break; | 1317 | break; |
1302 | case DA7213_CLKSRC_MCLK_SQR: | 1318 | case DA7213_CLKSRC_MCLK_SQR: |
1303 | da7213->mclk_squarer_en = true; | 1319 | snd_soc_update_bits(codec, DA7213_PLL_CTRL, |
1320 | DA7213_PLL_MCLK_SQR_EN, | ||
1321 | DA7213_PLL_MCLK_SQR_EN); | ||
1304 | break; | 1322 | break; |
1305 | default: | 1323 | default: |
1306 | dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id); | 1324 | dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id); |
@@ -1324,7 +1342,7 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
1324 | return 0; | 1342 | return 0; |
1325 | } | 1343 | } |
1326 | 1344 | ||
1327 | /* Supported PLL input frequencies are 5MHz - 54MHz. */ | 1345 | /* Supported PLL input frequencies are 32KHz, 5MHz - 54MHz. */ |
1328 | static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | 1346 | static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, |
1329 | int source, unsigned int fref, unsigned int fout) | 1347 | int source, unsigned int fref, unsigned int fout) |
1330 | { | 1348 | { |
@@ -1336,22 +1354,26 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
1336 | u32 freq_ref; | 1354 | u32 freq_ref; |
1337 | u64 frac_div; | 1355 | u64 frac_div; |
1338 | 1356 | ||
1339 | /* Reset PLL configuration */ | ||
1340 | snd_soc_write(codec, DA7213_PLL_CTRL, 0); | ||
1341 | |||
1342 | pll_ctrl = 0; | ||
1343 | |||
1344 | /* Workout input divider based on MCLK rate */ | 1357 | /* Workout input divider based on MCLK rate */ |
1345 | if (da7213->mclk_rate == 32768) { | 1358 | if (da7213->mclk_rate == 32768) { |
1359 | if (!da7213->master) { | ||
1360 | dev_err(codec->dev, | ||
1361 | "32KHz only valid if codec is clock master\n"); | ||
1362 | return -EINVAL; | ||
1363 | } | ||
1364 | |||
1346 | /* 32KHz PLL Mode */ | 1365 | /* 32KHz PLL Mode */ |
1347 | indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ; | 1366 | indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ; |
1348 | indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL; | 1367 | indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL; |
1368 | source = DA7213_SYSCLK_PLL_32KHZ; | ||
1349 | freq_ref = 3750000; | 1369 | freq_ref = 3750000; |
1350 | pll_ctrl |= DA7213_PLL_32K_MODE; | 1370 | |
1351 | } else { | 1371 | } else { |
1352 | /* 5 - 54MHz MCLK */ | ||
1353 | if (da7213->mclk_rate < 5000000) { | 1372 | if (da7213->mclk_rate < 5000000) { |
1354 | goto pll_err; | 1373 | dev_err(codec->dev, |
1374 | "PLL input clock %d below valid range\n", | ||
1375 | da7213->mclk_rate); | ||
1376 | return -EINVAL; | ||
1355 | } else if (da7213->mclk_rate <= 9000000) { | 1377 | } else if (da7213->mclk_rate <= 9000000) { |
1356 | indiv_bits = DA7213_PLL_INDIV_5_TO_9_MHZ; | 1378 | indiv_bits = DA7213_PLL_INDIV_5_TO_9_MHZ; |
1357 | indiv = DA7213_PLL_INDIV_5_TO_9_MHZ_VAL; | 1379 | indiv = DA7213_PLL_INDIV_5_TO_9_MHZ_VAL; |
@@ -1365,32 +1387,44 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
1365 | indiv_bits = DA7213_PLL_INDIV_36_TO_54_MHZ; | 1387 | indiv_bits = DA7213_PLL_INDIV_36_TO_54_MHZ; |
1366 | indiv = DA7213_PLL_INDIV_36_TO_54_MHZ_VAL; | 1388 | indiv = DA7213_PLL_INDIV_36_TO_54_MHZ_VAL; |
1367 | } else { | 1389 | } else { |
1368 | goto pll_err; | 1390 | dev_err(codec->dev, |
1391 | "PLL input clock %d above valid range\n", | ||
1392 | da7213->mclk_rate); | ||
1393 | return -EINVAL; | ||
1369 | } | 1394 | } |
1370 | freq_ref = (da7213->mclk_rate / indiv); | 1395 | freq_ref = (da7213->mclk_rate / indiv); |
1371 | } | 1396 | } |
1372 | 1397 | ||
1373 | pll_ctrl |= indiv_bits; | 1398 | pll_ctrl = indiv_bits; |
1374 | 1399 | ||
1375 | /* PLL Bypass mode */ | 1400 | /* Configure PLL */ |
1376 | if (source == DA7213_SYSCLK_MCLK) { | 1401 | switch (source) { |
1377 | snd_soc_write(codec, DA7213_PLL_CTRL, pll_ctrl); | 1402 | case DA7213_SYSCLK_MCLK: |
1403 | snd_soc_update_bits(codec, DA7213_PLL_CTRL, | ||
1404 | DA7213_PLL_INDIV_MASK | | ||
1405 | DA7213_PLL_MODE_MASK, pll_ctrl); | ||
1378 | return 0; | 1406 | return 0; |
1379 | } | 1407 | case DA7213_SYSCLK_PLL: |
1408 | break; | ||
1409 | case DA7213_SYSCLK_PLL_SRM: | ||
1410 | pll_ctrl |= DA7213_PLL_SRM_EN; | ||
1411 | fout = DA7213_PLL_FREQ_OUT_94310400; | ||
1412 | break; | ||
1413 | case DA7213_SYSCLK_PLL_32KHZ: | ||
1414 | if (da7213->mclk_rate != 32768) { | ||
1415 | dev_err(codec->dev, | ||
1416 | "32KHz mode only valid with 32KHz MCLK\n"); | ||
1417 | return -EINVAL; | ||
1418 | } | ||
1380 | 1419 | ||
1381 | /* | 1420 | pll_ctrl |= DA7213_PLL_32K_MODE | DA7213_PLL_SRM_EN; |
1382 | * If Codec is slave and SRM enabled, | ||
1383 | * freq_out is (98304000 + 90316800)/2 = 94310400 | ||
1384 | */ | ||
1385 | if (!da7213->master && da7213->srm_en) { | ||
1386 | fout = DA7213_PLL_FREQ_OUT_94310400; | 1421 | fout = DA7213_PLL_FREQ_OUT_94310400; |
1387 | pll_ctrl |= DA7213_PLL_SRM_EN; | 1422 | break; |
1423 | default: | ||
1424 | dev_err(codec->dev, "Invalid PLL config\n"); | ||
1425 | return -EINVAL; | ||
1388 | } | 1426 | } |
1389 | 1427 | ||
1390 | /* Enable MCLK squarer if required */ | ||
1391 | if (da7213->mclk_squarer_en) | ||
1392 | pll_ctrl |= DA7213_PLL_MCLK_SQR_EN; | ||
1393 | |||
1394 | /* Calculate dividers for PLL */ | 1428 | /* Calculate dividers for PLL */ |
1395 | pll_integer = fout / freq_ref; | 1429 | pll_integer = fout / freq_ref; |
1396 | frac_div = (u64)(fout % freq_ref) * 8192ULL; | 1430 | frac_div = (u64)(fout % freq_ref) * 8192ULL; |
@@ -1405,14 +1439,19 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
1405 | 1439 | ||
1406 | /* Enable PLL */ | 1440 | /* Enable PLL */ |
1407 | pll_ctrl |= DA7213_PLL_EN; | 1441 | pll_ctrl |= DA7213_PLL_EN; |
1408 | snd_soc_write(codec, DA7213_PLL_CTRL, pll_ctrl); | 1442 | snd_soc_update_bits(codec, DA7213_PLL_CTRL, |
1443 | DA7213_PLL_INDIV_MASK | DA7213_PLL_MODE_MASK, | ||
1444 | pll_ctrl); | ||
1445 | |||
1446 | /* Assist 32KHz mode PLL lock */ | ||
1447 | if (source == DA7213_SYSCLK_PLL_32KHZ) { | ||
1448 | snd_soc_write(codec, 0xF0, 0x8B); | ||
1449 | snd_soc_write(codec, 0xF1, 0x03); | ||
1450 | snd_soc_write(codec, 0xF1, 0x01); | ||
1451 | snd_soc_write(codec, 0xF0, 0x00); | ||
1452 | } | ||
1409 | 1453 | ||
1410 | return 0; | 1454 | return 0; |
1411 | |||
1412 | pll_err: | ||
1413 | dev_err(codec_dai->dev, "Unsupported PLL input frequency %d\n", | ||
1414 | da7213->mclk_rate); | ||
1415 | return -EINVAL; | ||
1416 | } | 1455 | } |
1417 | 1456 | ||
1418 | /* DAI operations */ | 1457 | /* DAI operations */ |
@@ -1454,11 +1493,10 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec, | |||
1454 | 1493 | ||
1455 | switch (level) { | 1494 | switch (level) { |
1456 | case SND_SOC_BIAS_ON: | 1495 | case SND_SOC_BIAS_ON: |
1457 | case SND_SOC_BIAS_PREPARE: | ||
1458 | break; | 1496 | break; |
1459 | case SND_SOC_BIAS_STANDBY: | 1497 | case SND_SOC_BIAS_PREPARE: |
1460 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { | 1498 | /* Enable MCLK for transition to ON state */ |
1461 | /* MCLK */ | 1499 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) { |
1462 | if (da7213->mclk) { | 1500 | if (da7213->mclk) { |
1463 | ret = clk_prepare_enable(da7213->mclk); | 1501 | ret = clk_prepare_enable(da7213->mclk); |
1464 | if (ret) { | 1502 | if (ret) { |
@@ -1467,21 +1505,24 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec, | |||
1467 | return ret; | 1505 | return ret; |
1468 | } | 1506 | } |
1469 | } | 1507 | } |
1470 | 1508 | } | |
1509 | break; | ||
1510 | case SND_SOC_BIAS_STANDBY: | ||
1511 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { | ||
1471 | /* Enable VMID reference & master bias */ | 1512 | /* Enable VMID reference & master bias */ |
1472 | snd_soc_update_bits(codec, DA7213_REFERENCES, | 1513 | snd_soc_update_bits(codec, DA7213_REFERENCES, |
1473 | DA7213_VMID_EN | DA7213_BIAS_EN, | 1514 | DA7213_VMID_EN | DA7213_BIAS_EN, |
1474 | DA7213_VMID_EN | DA7213_BIAS_EN); | 1515 | DA7213_VMID_EN | DA7213_BIAS_EN); |
1516 | } else { | ||
1517 | /* Remove MCLK */ | ||
1518 | if (da7213->mclk) | ||
1519 | clk_disable_unprepare(da7213->mclk); | ||
1475 | } | 1520 | } |
1476 | break; | 1521 | break; |
1477 | case SND_SOC_BIAS_OFF: | 1522 | case SND_SOC_BIAS_OFF: |
1478 | /* Disable VMID reference & master bias */ | 1523 | /* Disable VMID reference & master bias */ |
1479 | snd_soc_update_bits(codec, DA7213_REFERENCES, | 1524 | snd_soc_update_bits(codec, DA7213_REFERENCES, |
1480 | DA7213_VMID_EN | DA7213_BIAS_EN, 0); | 1525 | DA7213_VMID_EN | DA7213_BIAS_EN, 0); |
1481 | |||
1482 | /* MCLK */ | ||
1483 | if (da7213->mclk) | ||
1484 | clk_disable_unprepare(da7213->mclk); | ||
1485 | break; | 1526 | break; |
1486 | } | 1527 | } |
1487 | return 0; | 1528 | return 0; |
@@ -1605,9 +1646,6 @@ static int da7213_probe(struct snd_soc_codec *codec) | |||
1605 | DA7213_ALC_CALIB_MODE_MAN, 0); | 1646 | DA7213_ALC_CALIB_MODE_MAN, 0); |
1606 | da7213->alc_calib_auto = true; | 1647 | da7213->alc_calib_auto = true; |
1607 | 1648 | ||
1608 | /* Default to using SRM for slave mode */ | ||
1609 | da7213->srm_en = true; | ||
1610 | |||
1611 | /* Default PC counter to free-running */ | 1649 | /* Default PC counter to free-running */ |
1612 | snd_soc_update_bits(codec, DA7213_PC_COUNT, DA7213_PC_FREERUN_MASK, | 1650 | snd_soc_update_bits(codec, DA7213_PC_COUNT, DA7213_PC_FREERUN_MASK, |
1613 | DA7213_PC_FREERUN_MASK); | 1651 | DA7213_PC_FREERUN_MASK); |
@@ -1740,13 +1778,14 @@ static struct snd_soc_codec_driver soc_codec_dev_da7213 = { | |||
1740 | .probe = da7213_probe, | 1778 | .probe = da7213_probe, |
1741 | .set_bias_level = da7213_set_bias_level, | 1779 | .set_bias_level = da7213_set_bias_level, |
1742 | 1780 | ||
1743 | .controls = da7213_snd_controls, | 1781 | .component_driver = { |
1744 | .num_controls = ARRAY_SIZE(da7213_snd_controls), | 1782 | .controls = da7213_snd_controls, |
1745 | 1783 | .num_controls = ARRAY_SIZE(da7213_snd_controls), | |
1746 | .dapm_widgets = da7213_dapm_widgets, | 1784 | .dapm_widgets = da7213_dapm_widgets, |
1747 | .num_dapm_widgets = ARRAY_SIZE(da7213_dapm_widgets), | 1785 | .num_dapm_widgets = ARRAY_SIZE(da7213_dapm_widgets), |
1748 | .dapm_routes = da7213_audio_map, | 1786 | .dapm_routes = da7213_audio_map, |
1749 | .num_dapm_routes = ARRAY_SIZE(da7213_audio_map), | 1787 | .num_dapm_routes = ARRAY_SIZE(da7213_audio_map), |
1788 | }, | ||
1750 | }; | 1789 | }; |
1751 | 1790 | ||
1752 | static const struct regmap_config da7213_regmap_config = { | 1791 | static const struct regmap_config da7213_regmap_config = { |
diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h index fbb7a356a501..16ef56f77cd4 100644 --- a/sound/soc/codecs/da7213.h +++ b/sound/soc/codecs/da7213.h | |||
@@ -172,6 +172,7 @@ | |||
172 | #define DA7213_PLL_32K_MODE (0x1 << 5) | 172 | #define DA7213_PLL_32K_MODE (0x1 << 5) |
173 | #define DA7213_PLL_SRM_EN (0x1 << 6) | 173 | #define DA7213_PLL_SRM_EN (0x1 << 6) |
174 | #define DA7213_PLL_EN (0x1 << 7) | 174 | #define DA7213_PLL_EN (0x1 << 7) |
175 | #define DA7213_PLL_MODE_MASK (0x7 << 5) | ||
175 | 176 | ||
176 | /* DA7213_DAI_CLK_MODE = 0x28 */ | 177 | /* DA7213_DAI_CLK_MODE = 0x28 */ |
177 | #define DA7213_DAI_BCLKS_PER_WCLK_32 (0x0 << 0) | 178 | #define DA7213_DAI_BCLKS_PER_WCLK_32 (0x0 << 0) |
@@ -499,8 +500,6 @@ | |||
499 | #define DA7213_ALC_AVG_ITERATIONS 5 | 500 | #define DA7213_ALC_AVG_ITERATIONS 5 |
500 | 501 | ||
501 | /* PLL related */ | 502 | /* PLL related */ |
502 | #define DA7213_SYSCLK_MCLK 0 | ||
503 | #define DA7213_SYSCLK_PLL 1 | ||
504 | #define DA7213_PLL_FREQ_OUT_90316800 90316800 | 503 | #define DA7213_PLL_FREQ_OUT_90316800 90316800 |
505 | #define DA7213_PLL_FREQ_OUT_98304000 98304000 | 504 | #define DA7213_PLL_FREQ_OUT_98304000 98304000 |
506 | #define DA7213_PLL_FREQ_OUT_94310400 94310400 | 505 | #define DA7213_PLL_FREQ_OUT_94310400 94310400 |
@@ -515,6 +514,13 @@ enum da7213_clk_src { | |||
515 | DA7213_CLKSRC_MCLK_SQR, | 514 | DA7213_CLKSRC_MCLK_SQR, |
516 | }; | 515 | }; |
517 | 516 | ||
517 | enum da7213_sys_clk { | ||
518 | DA7213_SYSCLK_MCLK = 0, | ||
519 | DA7213_SYSCLK_PLL, | ||
520 | DA7213_SYSCLK_PLL_SRM, | ||
521 | DA7213_SYSCLK_PLL_32KHZ | ||
522 | }; | ||
523 | |||
518 | /* Codec private data */ | 524 | /* Codec private data */ |
519 | struct da7213_priv { | 525 | struct da7213_priv { |
520 | struct regmap *regmap; | 526 | struct regmap *regmap; |
@@ -522,8 +528,6 @@ struct da7213_priv { | |||
522 | unsigned int mclk_rate; | 528 | unsigned int mclk_rate; |
523 | int clk_src; | 529 | int clk_src; |
524 | bool master; | 530 | bool master; |
525 | bool mclk_squarer_en; | ||
526 | bool srm_en; | ||
527 | bool alc_calib_auto; | 531 | bool alc_calib_auto; |
528 | bool alc_en; | 532 | bool alc_en; |
529 | struct da7213_platform_data *pdata; | 533 | struct da7213_platform_data *pdata; |
diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c index 99ce23e113bf..c69e97654fc6 100644 --- a/sound/soc/codecs/da7218.c +++ b/sound/soc/codecs/da7218.c | |||
@@ -1819,7 +1819,7 @@ static int da7218_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
1819 | if (da7218->mclk_rate == freq) | 1819 | if (da7218->mclk_rate == freq) |
1820 | return 0; | 1820 | return 0; |
1821 | 1821 | ||
1822 | if (((freq < 2000000) && (freq != 32768)) || (freq > 54000000)) { | 1822 | if ((freq < 2000000) || (freq > 54000000)) { |
1823 | dev_err(codec_dai->dev, "Unsupported MCLK value %d\n", | 1823 | dev_err(codec_dai->dev, "Unsupported MCLK value %d\n", |
1824 | freq); | 1824 | freq); |
1825 | return -EINVAL; | 1825 | return -EINVAL; |
@@ -1866,11 +1866,8 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
1866 | u32 freq_ref; | 1866 | u32 freq_ref; |
1867 | u64 frac_div; | 1867 | u64 frac_div; |
1868 | 1868 | ||
1869 | /* Verify 32KHz, 2MHz - 54MHz MCLK provided, and set input divider */ | 1869 | /* Verify 2MHz - 54MHz MCLK provided, and set input divider */ |
1870 | if (da7218->mclk_rate == 32768) { | 1870 | if (da7218->mclk_rate < 2000000) { |
1871 | indiv_bits = DA7218_PLL_INDIV_9_TO_18_MHZ; | ||
1872 | indiv = DA7218_PLL_INDIV_9_TO_18_MHZ_VAL; | ||
1873 | } else if (da7218->mclk_rate < 2000000) { | ||
1874 | dev_err(codec->dev, "PLL input clock %d below valid range\n", | 1871 | dev_err(codec->dev, "PLL input clock %d below valid range\n", |
1875 | da7218->mclk_rate); | 1872 | da7218->mclk_rate); |
1876 | return -EINVAL; | 1873 | return -EINVAL; |
@@ -1911,9 +1908,6 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
1911 | case DA7218_SYSCLK_PLL_SRM: | 1908 | case DA7218_SYSCLK_PLL_SRM: |
1912 | pll_ctrl |= DA7218_PLL_MODE_SRM; | 1909 | pll_ctrl |= DA7218_PLL_MODE_SRM; |
1913 | break; | 1910 | break; |
1914 | case DA7218_SYSCLK_PLL_32KHZ: | ||
1915 | pll_ctrl |= DA7218_PLL_MODE_32KHZ; | ||
1916 | break; | ||
1917 | default: | 1911 | default: |
1918 | dev_err(codec->dev, "Invalid PLL config\n"); | 1912 | dev_err(codec->dev, "Invalid PLL config\n"); |
1919 | return -EINVAL; | 1913 | return -EINVAL; |
@@ -2589,20 +2583,22 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec, | |||
2589 | 2583 | ||
2590 | switch (level) { | 2584 | switch (level) { |
2591 | case SND_SOC_BIAS_ON: | 2585 | case SND_SOC_BIAS_ON: |
2592 | case SND_SOC_BIAS_PREPARE: | ||
2593 | break; | 2586 | break; |
2594 | case SND_SOC_BIAS_STANDBY: | 2587 | case SND_SOC_BIAS_PREPARE: |
2595 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { | 2588 | /* Enable MCLK for transition to ON state */ |
2596 | /* MCLK */ | 2589 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) { |
2597 | if (da7218->mclk) { | 2590 | if (da7218->mclk) { |
2598 | ret = clk_prepare_enable(da7218->mclk); | 2591 | ret = clk_prepare_enable(da7218->mclk); |
2599 | if (ret) { | 2592 | if (ret) { |
2600 | dev_err(codec->dev, | 2593 | dev_err(codec->dev, "Failed to enable mclk\n"); |
2601 | "Failed to enable mclk\n"); | ||
2602 | return ret; | 2594 | return ret; |
2603 | } | 2595 | } |
2604 | } | 2596 | } |
2597 | } | ||
2605 | 2598 | ||
2599 | break; | ||
2600 | case SND_SOC_BIAS_STANDBY: | ||
2601 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { | ||
2606 | /* Master bias */ | 2602 | /* Master bias */ |
2607 | snd_soc_update_bits(codec, DA7218_REFERENCES, | 2603 | snd_soc_update_bits(codec, DA7218_REFERENCES, |
2608 | DA7218_BIAS_EN_MASK, | 2604 | DA7218_BIAS_EN_MASK, |
@@ -2612,6 +2608,10 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec, | |||
2612 | snd_soc_update_bits(codec, DA7218_LDO_CTRL, | 2608 | snd_soc_update_bits(codec, DA7218_LDO_CTRL, |
2613 | DA7218_LDO_EN_MASK, | 2609 | DA7218_LDO_EN_MASK, |
2614 | DA7218_LDO_EN_MASK); | 2610 | DA7218_LDO_EN_MASK); |
2611 | } else { | ||
2612 | /* Remove MCLK */ | ||
2613 | if (da7218->mclk) | ||
2614 | clk_disable_unprepare(da7218->mclk); | ||
2615 | } | 2615 | } |
2616 | break; | 2616 | break; |
2617 | case SND_SOC_BIAS_OFF: | 2617 | case SND_SOC_BIAS_OFF: |
@@ -2625,10 +2625,6 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec, | |||
2625 | snd_soc_update_bits(codec, DA7218_REFERENCES, | 2625 | snd_soc_update_bits(codec, DA7218_REFERENCES, |
2626 | DA7218_BIAS_EN_MASK, 0); | 2626 | DA7218_BIAS_EN_MASK, 0); |
2627 | } | 2627 | } |
2628 | |||
2629 | /* MCLK */ | ||
2630 | if (da7218->mclk) | ||
2631 | clk_disable_unprepare(da7218->mclk); | ||
2632 | break; | 2628 | break; |
2633 | } | 2629 | } |
2634 | 2630 | ||
@@ -3045,13 +3041,14 @@ static struct snd_soc_codec_driver soc_codec_dev_da7218 = { | |||
3045 | .resume = da7218_resume, | 3041 | .resume = da7218_resume, |
3046 | .set_bias_level = da7218_set_bias_level, | 3042 | .set_bias_level = da7218_set_bias_level, |
3047 | 3043 | ||
3048 | .controls = da7218_snd_controls, | 3044 | .component_driver = { |
3049 | .num_controls = ARRAY_SIZE(da7218_snd_controls), | 3045 | .controls = da7218_snd_controls, |
3050 | 3046 | .num_controls = ARRAY_SIZE(da7218_snd_controls), | |
3051 | .dapm_widgets = da7218_dapm_widgets, | 3047 | .dapm_widgets = da7218_dapm_widgets, |
3052 | .num_dapm_widgets = ARRAY_SIZE(da7218_dapm_widgets), | 3048 | .num_dapm_widgets = ARRAY_SIZE(da7218_dapm_widgets), |
3053 | .dapm_routes = da7218_audio_map, | 3049 | .dapm_routes = da7218_audio_map, |
3054 | .num_dapm_routes = ARRAY_SIZE(da7218_audio_map), | 3050 | .num_dapm_routes = ARRAY_SIZE(da7218_audio_map), |
3051 | }, | ||
3055 | }; | 3052 | }; |
3056 | 3053 | ||
3057 | 3054 | ||
diff --git a/sound/soc/codecs/da7218.h b/sound/soc/codecs/da7218.h index 477cd37723cf..4f7ec21069a4 100644 --- a/sound/soc/codecs/da7218.h +++ b/sound/soc/codecs/da7218.h | |||
@@ -888,7 +888,6 @@ | |||
888 | #define DA7218_PLL_MODE_BYPASS (0x0 << 6) | 888 | #define DA7218_PLL_MODE_BYPASS (0x0 << 6) |
889 | #define DA7218_PLL_MODE_NORMAL (0x1 << 6) | 889 | #define DA7218_PLL_MODE_NORMAL (0x1 << 6) |
890 | #define DA7218_PLL_MODE_SRM (0x2 << 6) | 890 | #define DA7218_PLL_MODE_SRM (0x2 << 6) |
891 | #define DA7218_PLL_MODE_32KHZ (0x3 << 6) | ||
892 | 891 | ||
893 | /* DA7218_PLL_FRAC_TOP = 0x92 */ | 892 | /* DA7218_PLL_FRAC_TOP = 0x92 */ |
894 | #define DA7218_PLL_FBDIV_FRAC_TOP_SHIFT 0 | 893 | #define DA7218_PLL_FBDIV_FRAC_TOP_SHIFT 0 |
@@ -1371,7 +1370,6 @@ enum da7218_sys_clk { | |||
1371 | DA7218_SYSCLK_MCLK = 0, | 1370 | DA7218_SYSCLK_MCLK = 0, |
1372 | DA7218_SYSCLK_PLL, | 1371 | DA7218_SYSCLK_PLL, |
1373 | DA7218_SYSCLK_PLL_SRM, | 1372 | DA7218_SYSCLK_PLL_SRM, |
1374 | DA7218_SYSCLK_PLL_32KHZ | ||
1375 | }; | 1373 | }; |
1376 | 1374 | ||
1377 | enum da7218_dev_id { | 1375 | enum da7218_dev_id { |
diff --git a/sound/soc/codecs/da7219-aad.c b/sound/soc/codecs/da7219-aad.c index f0057cd223a4..2b8914dd5990 100644 --- a/sound/soc/codecs/da7219-aad.c +++ b/sound/soc/codecs/da7219-aad.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/clk.h> | ||
16 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
17 | #include <linux/property.h> | 18 | #include <linux/property.h> |
18 | #include <linux/pm_wakeirq.h> | 19 | #include <linux/pm_wakeirq.h> |
@@ -114,13 +115,38 @@ static void da7219_aad_hptest_work(struct work_struct *work) | |||
114 | struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); | 115 | struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); |
115 | 116 | ||
116 | u16 tonegen_freq_hptest; | 117 | u16 tonegen_freq_hptest; |
117 | u8 accdet_cfg8; | 118 | u8 pll_srm_sts, gain_ramp_ctrl, accdet_cfg8; |
118 | int report = 0; | 119 | int report = 0, ret = 0; |
119 | 120 | ||
120 | /* Lock DAPM and any Kcontrols that are affected by this test */ | 121 | /* Lock DAPM and any Kcontrols that are affected by this test */ |
121 | snd_soc_dapm_mutex_lock(dapm); | 122 | snd_soc_dapm_mutex_lock(dapm); |
122 | mutex_lock(&da7219->lock); | 123 | mutex_lock(&da7219->lock); |
123 | 124 | ||
125 | /* Ensure MCLK is available for HP test procedure */ | ||
126 | if (da7219->mclk) { | ||
127 | ret = clk_prepare_enable(da7219->mclk); | ||
128 | if (ret) { | ||
129 | dev_err(codec->dev, "Failed to enable mclk - %d\n", ret); | ||
130 | mutex_unlock(&da7219->lock); | ||
131 | snd_soc_dapm_mutex_unlock(dapm); | ||
132 | return; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * If MCLK not present, then we're using the internal oscillator and | ||
138 | * require different frequency settings to achieve the same result. | ||
139 | */ | ||
140 | pll_srm_sts = snd_soc_read(codec, DA7219_PLL_SRM_STS); | ||
141 | if (pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) | ||
142 | tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ); | ||
143 | else | ||
144 | tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC); | ||
145 | |||
146 | /* Ensure gain ramping at fastest rate */ | ||
147 | gain_ramp_ctrl = snd_soc_read(codec, DA7219_GAIN_RAMP_CTRL); | ||
148 | snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8); | ||
149 | |||
124 | /* Bypass cache so it saves current settings */ | 150 | /* Bypass cache so it saves current settings */ |
125 | regcache_cache_bypass(da7219->regmap, true); | 151 | regcache_cache_bypass(da7219->regmap, true); |
126 | 152 | ||
@@ -183,9 +209,15 @@ static void da7219_aad_hptest_work(struct work_struct *work) | |||
183 | snd_soc_write(codec, DA7219_HP_R_CTRL, | 209 | snd_soc_write(codec, DA7219_HP_R_CTRL, |
184 | DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK); | 210 | DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK); |
185 | 211 | ||
212 | /* | ||
213 | * If we're running from the internal oscillator then give audio paths | ||
214 | * time to settle before running test. | ||
215 | */ | ||
216 | if (!(pll_srm_sts & DA7219_PLL_SRM_STS_MCLK)) | ||
217 | msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY); | ||
218 | |||
186 | /* Configure & start Tone Generator */ | 219 | /* Configure & start Tone Generator */ |
187 | snd_soc_write(codec, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK); | 220 | snd_soc_write(codec, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK); |
188 | tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ); | ||
189 | regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L, | 221 | regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L, |
190 | &tonegen_freq_hptest, sizeof(tonegen_freq_hptest)); | 222 | &tonegen_freq_hptest, sizeof(tonegen_freq_hptest)); |
191 | snd_soc_update_bits(codec, DA7219_TONE_GEN_CFG2, | 223 | snd_soc_update_bits(codec, DA7219_TONE_GEN_CFG2, |
@@ -244,12 +276,26 @@ static void da7219_aad_hptest_work(struct work_struct *work) | |||
244 | snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8, | 276 | snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8, |
245 | DA7219_HPTEST_EN_MASK, 0); | 277 | DA7219_HPTEST_EN_MASK, 0); |
246 | 278 | ||
279 | /* | ||
280 | * If we're running from the internal oscillator then give audio paths | ||
281 | * time to settle before allowing headphones to be driven as required. | ||
282 | */ | ||
283 | if (!(pll_srm_sts & DA7219_PLL_SRM_STS_MCLK)) | ||
284 | msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY); | ||
285 | |||
286 | /* Restore gain ramping rate */ | ||
287 | snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL, gain_ramp_ctrl); | ||
288 | |||
247 | /* Drive Headphones/lineout */ | 289 | /* Drive Headphones/lineout */ |
248 | snd_soc_update_bits(codec, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK, | 290 | snd_soc_update_bits(codec, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK, |
249 | DA7219_HP_L_AMP_OE_MASK); | 291 | DA7219_HP_L_AMP_OE_MASK); |
250 | snd_soc_update_bits(codec, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK, | 292 | snd_soc_update_bits(codec, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK, |
251 | DA7219_HP_R_AMP_OE_MASK); | 293 | DA7219_HP_R_AMP_OE_MASK); |
252 | 294 | ||
295 | /* Remove MCLK, if previously enabled */ | ||
296 | if (da7219->mclk) | ||
297 | clk_disable_unprepare(da7219->mclk); | ||
298 | |||
253 | mutex_unlock(&da7219->lock); | 299 | mutex_unlock(&da7219->lock); |
254 | snd_soc_dapm_mutex_unlock(dapm); | 300 | snd_soc_dapm_mutex_unlock(dapm); |
255 | 301 | ||
@@ -751,6 +797,62 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec) | |||
751 | 797 | ||
752 | 798 | ||
753 | /* | 799 | /* |
800 | * Suspend/Resume | ||
801 | */ | ||
802 | |||
803 | void da7219_aad_suspend(struct snd_soc_codec *codec) | ||
804 | { | ||
805 | struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); | ||
806 | struct da7219_aad_priv *da7219_aad = da7219->aad; | ||
807 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | ||
808 | u8 micbias_ctrl; | ||
809 | |||
810 | if (da7219_aad->jack) { | ||
811 | /* Disable jack detection during suspend */ | ||
812 | snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1, | ||
813 | DA7219_ACCDET_EN_MASK, 0); | ||
814 | |||
815 | /* | ||
816 | * If we have a 4-pole jack inserted, then micbias will be | ||
817 | * enabled. We can disable micbias here, and keep a note to | ||
818 | * re-enable it on resume. If jack removal occurred during | ||
819 | * suspend then this will be dealt with through the IRQ handler. | ||
820 | */ | ||
821 | if (da7219_aad->jack_inserted) { | ||
822 | micbias_ctrl = snd_soc_read(codec, DA7219_MICBIAS_CTRL); | ||
823 | if (micbias_ctrl & DA7219_MICBIAS1_EN_MASK) { | ||
824 | snd_soc_dapm_disable_pin(dapm, "Mic Bias"); | ||
825 | snd_soc_dapm_sync(dapm); | ||
826 | da7219_aad->micbias_resume_enable = true; | ||
827 | } | ||
828 | } | ||
829 | } | ||
830 | } | ||
831 | |||
832 | void da7219_aad_resume(struct snd_soc_codec *codec) | ||
833 | { | ||
834 | struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); | ||
835 | struct da7219_aad_priv *da7219_aad = da7219->aad; | ||
836 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | ||
837 | |||
838 | if (da7219_aad->jack) { | ||
839 | /* Re-enable micbias if previously enabled for 4-pole jack */ | ||
840 | if (da7219_aad->jack_inserted && | ||
841 | da7219_aad->micbias_resume_enable) { | ||
842 | snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); | ||
843 | snd_soc_dapm_sync(dapm); | ||
844 | da7219_aad->micbias_resume_enable = false; | ||
845 | } | ||
846 | |||
847 | /* Re-enable jack detection */ | ||
848 | snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1, | ||
849 | DA7219_ACCDET_EN_MASK, | ||
850 | DA7219_ACCDET_EN_MASK); | ||
851 | } | ||
852 | } | ||
853 | |||
854 | |||
855 | /* | ||
754 | * Init/Exit | 856 | * Init/Exit |
755 | */ | 857 | */ |
756 | 858 | ||
diff --git a/sound/soc/codecs/da7219-aad.h b/sound/soc/codecs/da7219-aad.h index 4fccf677cd06..117a3d7ccd31 100644 --- a/sound/soc/codecs/da7219-aad.h +++ b/sound/soc/codecs/da7219-aad.h | |||
@@ -176,8 +176,10 @@ | |||
176 | #define DA7219_AAD_MICBIAS_CHK_DELAY 10 | 176 | #define DA7219_AAD_MICBIAS_CHK_DELAY 10 |
177 | #define DA7219_AAD_MICBIAS_CHK_RETRIES 5 | 177 | #define DA7219_AAD_MICBIAS_CHK_RETRIES 5 |
178 | 178 | ||
179 | #define DA7219_AAD_HPTEST_RAMP_FREQ 0x28 | 179 | #define DA7219_AAD_HPTEST_RAMP_FREQ 0x28 |
180 | #define DA7219_AAD_HPTEST_PERIOD 65 | 180 | #define DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC 0x4D |
181 | #define DA7219_AAD_HPTEST_PERIOD 65 | ||
182 | #define DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY 20 | ||
181 | 183 | ||
182 | enum da7219_aad_event_regs { | 184 | enum da7219_aad_event_regs { |
183 | DA7219_AAD_IRQ_REG_A = 0, | 185 | DA7219_AAD_IRQ_REG_A = 0, |
@@ -199,12 +201,17 @@ struct da7219_aad_priv { | |||
199 | struct work_struct hptest_work; | 201 | struct work_struct hptest_work; |
200 | 202 | ||
201 | struct snd_soc_jack *jack; | 203 | struct snd_soc_jack *jack; |
204 | bool micbias_resume_enable; | ||
202 | bool jack_inserted; | 205 | bool jack_inserted; |
203 | }; | 206 | }; |
204 | 207 | ||
205 | /* AAD control */ | 208 | /* AAD control */ |
206 | void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack); | 209 | void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack); |
207 | 210 | ||
211 | /* Suspend/Resume */ | ||
212 | void da7219_aad_suspend(struct snd_soc_codec *codec); | ||
213 | void da7219_aad_resume(struct snd_soc_codec *codec); | ||
214 | |||
208 | /* Init/Exit */ | 215 | /* Init/Exit */ |
209 | int da7219_aad_init(struct snd_soc_codec *codec); | 216 | int da7219_aad_init(struct snd_soc_codec *codec); |
210 | void da7219_aad_exit(struct snd_soc_codec *codec); | 217 | void da7219_aad_exit(struct snd_soc_codec *codec); |
diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index 50ea94317cb3..1152aa5e7c39 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c | |||
@@ -801,7 +801,7 @@ static int da7219_dai_event(struct snd_soc_dapm_widget *w, | |||
801 | ++i; | 801 | ++i; |
802 | msleep(50); | 802 | msleep(50); |
803 | } | 803 | } |
804 | } while ((i < DA7219_SRM_CHECK_RETRIES) & (!srm_lock)); | 804 | } while ((i < DA7219_SRM_CHECK_RETRIES) && (!srm_lock)); |
805 | 805 | ||
806 | if (!srm_lock) | 806 | if (!srm_lock) |
807 | dev_warn(codec->dev, "SRM failed to lock\n"); | 807 | dev_warn(codec->dev, "SRM failed to lock\n"); |
@@ -1482,6 +1482,8 @@ static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_codec *codec) | |||
1482 | if (!pdata) | 1482 | if (!pdata) |
1483 | return NULL; | 1483 | return NULL; |
1484 | 1484 | ||
1485 | pdata->wakeup_source = device_property_read_bool(dev, "wakeup-source"); | ||
1486 | |||
1485 | if (device_property_read_u32(dev, "dlg,micbias-lvl", &of_val32) >= 0) | 1487 | if (device_property_read_u32(dev, "dlg,micbias-lvl", &of_val32) >= 0) |
1486 | pdata->micbias_lvl = da7219_fw_micbias_lvl(dev, of_val32); | 1488 | pdata->micbias_lvl = da7219_fw_micbias_lvl(dev, of_val32); |
1487 | else | 1489 | else |
@@ -1508,11 +1510,10 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec, | |||
1508 | 1510 | ||
1509 | switch (level) { | 1511 | switch (level) { |
1510 | case SND_SOC_BIAS_ON: | 1512 | case SND_SOC_BIAS_ON: |
1511 | case SND_SOC_BIAS_PREPARE: | ||
1512 | break; | 1513 | break; |
1513 | case SND_SOC_BIAS_STANDBY: | 1514 | case SND_SOC_BIAS_PREPARE: |
1514 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { | 1515 | /* Enable MCLK for transition to ON state */ |
1515 | /* MCLK */ | 1516 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) { |
1516 | if (da7219->mclk) { | 1517 | if (da7219->mclk) { |
1517 | ret = clk_prepare_enable(da7219->mclk); | 1518 | ret = clk_prepare_enable(da7219->mclk); |
1518 | if (ret) { | 1519 | if (ret) { |
@@ -1521,22 +1522,28 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec, | |||
1521 | return ret; | 1522 | return ret; |
1522 | } | 1523 | } |
1523 | } | 1524 | } |
1525 | } | ||
1524 | 1526 | ||
1527 | break; | ||
1528 | case SND_SOC_BIAS_STANDBY: | ||
1529 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) | ||
1525 | /* Master bias */ | 1530 | /* Master bias */ |
1526 | snd_soc_update_bits(codec, DA7219_REFERENCES, | 1531 | snd_soc_update_bits(codec, DA7219_REFERENCES, |
1527 | DA7219_BIAS_EN_MASK, | 1532 | DA7219_BIAS_EN_MASK, |
1528 | DA7219_BIAS_EN_MASK); | 1533 | DA7219_BIAS_EN_MASK); |
1534 | |||
1535 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_PREPARE) { | ||
1536 | /* Remove MCLK */ | ||
1537 | if (da7219->mclk) | ||
1538 | clk_disable_unprepare(da7219->mclk); | ||
1529 | } | 1539 | } |
1530 | break; | 1540 | break; |
1531 | case SND_SOC_BIAS_OFF: | 1541 | case SND_SOC_BIAS_OFF: |
1532 | /* Only disable master bias if jack detection not active */ | 1542 | /* Only disable master bias if we're not a wake-up source */ |
1533 | if (!da7219->aad->jack) | 1543 | if (!da7219->wakeup_source) |
1534 | snd_soc_update_bits(codec, DA7219_REFERENCES, | 1544 | snd_soc_update_bits(codec, DA7219_REFERENCES, |
1535 | DA7219_BIAS_EN_MASK, 0); | 1545 | DA7219_BIAS_EN_MASK, 0); |
1536 | 1546 | ||
1537 | /* MCLK */ | ||
1538 | if (da7219->mclk) | ||
1539 | clk_disable_unprepare(da7219->mclk); | ||
1540 | break; | 1547 | break; |
1541 | } | 1548 | } |
1542 | 1549 | ||
@@ -1599,6 +1606,8 @@ static void da7219_handle_pdata(struct snd_soc_codec *codec) | |||
1599 | if (pdata) { | 1606 | if (pdata) { |
1600 | u8 micbias_lvl = 0; | 1607 | u8 micbias_lvl = 0; |
1601 | 1608 | ||
1609 | da7219->wakeup_source = pdata->wakeup_source; | ||
1610 | |||
1602 | /* Mic Bias voltages */ | 1611 | /* Mic Bias voltages */ |
1603 | switch (pdata->micbias_lvl) { | 1612 | switch (pdata->micbias_lvl) { |
1604 | case DA7219_MICBIAS_1_6V: | 1613 | case DA7219_MICBIAS_1_6V: |
@@ -1733,11 +1742,11 @@ static int da7219_suspend(struct snd_soc_codec *codec) | |||
1733 | { | 1742 | { |
1734 | struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); | 1743 | struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); |
1735 | 1744 | ||
1736 | snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF); | 1745 | /* Suspend AAD if we're not a wake-up source */ |
1746 | if (!da7219->wakeup_source) | ||
1747 | da7219_aad_suspend(codec); | ||
1737 | 1748 | ||
1738 | /* Put device into standby mode if jack detection disabled */ | 1749 | snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF); |
1739 | if (!da7219->aad->jack) | ||
1740 | snd_soc_write(codec, DA7219_SYSTEM_ACTIVE, 0); | ||
1741 | 1750 | ||
1742 | return 0; | 1751 | return 0; |
1743 | } | 1752 | } |
@@ -1746,13 +1755,12 @@ static int da7219_resume(struct snd_soc_codec *codec) | |||
1746 | { | 1755 | { |
1747 | struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); | 1756 | struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); |
1748 | 1757 | ||
1749 | /* Put device into active mode if previously pushed to standby */ | ||
1750 | if (!da7219->aad->jack) | ||
1751 | snd_soc_write(codec, DA7219_SYSTEM_ACTIVE, | ||
1752 | DA7219_SYSTEM_ACTIVE_MASK); | ||
1753 | |||
1754 | snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1758 | snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1755 | 1759 | ||
1760 | /* Resume AAD if previously suspended */ | ||
1761 | if (!da7219->wakeup_source) | ||
1762 | da7219_aad_resume(codec); | ||
1763 | |||
1756 | return 0; | 1764 | return 0; |
1757 | } | 1765 | } |
1758 | #else | 1766 | #else |
@@ -1767,13 +1775,14 @@ static struct snd_soc_codec_driver soc_codec_dev_da7219 = { | |||
1767 | .resume = da7219_resume, | 1775 | .resume = da7219_resume, |
1768 | .set_bias_level = da7219_set_bias_level, | 1776 | .set_bias_level = da7219_set_bias_level, |
1769 | 1777 | ||
1770 | .controls = da7219_snd_controls, | 1778 | .component_driver = { |
1771 | .num_controls = ARRAY_SIZE(da7219_snd_controls), | 1779 | .controls = da7219_snd_controls, |
1772 | 1780 | .num_controls = ARRAY_SIZE(da7219_snd_controls), | |
1773 | .dapm_widgets = da7219_dapm_widgets, | 1781 | .dapm_widgets = da7219_dapm_widgets, |
1774 | .num_dapm_widgets = ARRAY_SIZE(da7219_dapm_widgets), | 1782 | .num_dapm_widgets = ARRAY_SIZE(da7219_dapm_widgets), |
1775 | .dapm_routes = da7219_audio_map, | 1783 | .dapm_routes = da7219_audio_map, |
1776 | .num_dapm_routes = ARRAY_SIZE(da7219_audio_map), | 1784 | .num_dapm_routes = ARRAY_SIZE(da7219_audio_map), |
1785 | }, | ||
1777 | }; | 1786 | }; |
1778 | 1787 | ||
1779 | 1788 | ||
@@ -1921,7 +1930,8 @@ static int da7219_i2c_probe(struct i2c_client *i2c, | |||
1921 | const struct i2c_device_id *id) | 1930 | const struct i2c_device_id *id) |
1922 | { | 1931 | { |
1923 | struct da7219_priv *da7219; | 1932 | struct da7219_priv *da7219; |
1924 | int ret; | 1933 | unsigned int system_active, system_status; |
1934 | int i, ret; | ||
1925 | 1935 | ||
1926 | da7219 = devm_kzalloc(&i2c->dev, sizeof(struct da7219_priv), | 1936 | da7219 = devm_kzalloc(&i2c->dev, sizeof(struct da7219_priv), |
1927 | GFP_KERNEL); | 1937 | GFP_KERNEL); |
@@ -1937,6 +1947,37 @@ static int da7219_i2c_probe(struct i2c_client *i2c, | |||
1937 | return ret; | 1947 | return ret; |
1938 | } | 1948 | } |
1939 | 1949 | ||
1950 | regcache_cache_bypass(da7219->regmap, true); | ||
1951 | |||
1952 | /* Disable audio paths if still active from previous start */ | ||
1953 | regmap_read(da7219->regmap, DA7219_SYSTEM_ACTIVE, &system_active); | ||
1954 | if (system_active) { | ||
1955 | regmap_write(da7219->regmap, DA7219_GAIN_RAMP_CTRL, | ||
1956 | DA7219_GAIN_RAMP_RATE_NOMINAL); | ||
1957 | regmap_write(da7219->regmap, DA7219_SYSTEM_MODES_INPUT, 0x00); | ||
1958 | regmap_write(da7219->regmap, DA7219_SYSTEM_MODES_OUTPUT, 0x01); | ||
1959 | |||
1960 | for (i = 0; i < DA7219_SYS_STAT_CHECK_RETRIES; ++i) { | ||
1961 | regmap_read(da7219->regmap, DA7219_SYSTEM_STATUS, | ||
1962 | &system_status); | ||
1963 | if (!system_status) | ||
1964 | break; | ||
1965 | |||
1966 | msleep(DA7219_SYS_STAT_CHECK_DELAY); | ||
1967 | } | ||
1968 | } | ||
1969 | |||
1970 | /* Soft reset codec */ | ||
1971 | regmap_write_bits(da7219->regmap, DA7219_ACCDET_CONFIG_1, | ||
1972 | DA7219_ACCDET_EN_MASK, 0); | ||
1973 | regmap_write_bits(da7219->regmap, DA7219_CIF_CTRL, | ||
1974 | DA7219_CIF_REG_SOFT_RESET_MASK, | ||
1975 | DA7219_CIF_REG_SOFT_RESET_MASK); | ||
1976 | regmap_write_bits(da7219->regmap, DA7219_SYSTEM_ACTIVE, | ||
1977 | DA7219_SYSTEM_ACTIVE_MASK, 0); | ||
1978 | |||
1979 | regcache_cache_bypass(da7219->regmap, false); | ||
1980 | |||
1940 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7219, | 1981 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7219, |
1941 | &da7219_dai, 1); | 1982 | &da7219_dai, 1); |
1942 | if (ret < 0) { | 1983 | if (ret < 0) { |
diff --git a/sound/soc/codecs/da7219.h b/sound/soc/codecs/da7219.h index ff2a2f02ce40..66d3bad86739 100644 --- a/sound/soc/codecs/da7219.h +++ b/sound/soc/codecs/da7219.h | |||
@@ -224,6 +224,7 @@ | |||
224 | #define DA7219_PLL_SRM_STATE_MASK (0xF << 0) | 224 | #define DA7219_PLL_SRM_STATE_MASK (0xF << 0) |
225 | #define DA7219_PLL_SRM_STATUS_SHIFT 4 | 225 | #define DA7219_PLL_SRM_STATUS_SHIFT 4 |
226 | #define DA7219_PLL_SRM_STATUS_MASK (0xF << 4) | 226 | #define DA7219_PLL_SRM_STATUS_MASK (0xF << 4) |
227 | #define DA7219_PLL_SRM_STS_MCLK (0x1 << 4) | ||
227 | #define DA7219_PLL_SRM_STS_SRM_LOCK (0x1 << 7) | 228 | #define DA7219_PLL_SRM_STS_SRM_LOCK (0x1 << 7) |
228 | 229 | ||
229 | /* DA7219_DIG_ROUTING_DAI = 0x2A */ | 230 | /* DA7219_DIG_ROUTING_DAI = 0x2A */ |
@@ -576,6 +577,8 @@ | |||
576 | /* DA7219_GAIN_RAMP_CTRL = 0x92 */ | 577 | /* DA7219_GAIN_RAMP_CTRL = 0x92 */ |
577 | #define DA7219_GAIN_RAMP_RATE_SHIFT 0 | 578 | #define DA7219_GAIN_RAMP_RATE_SHIFT 0 |
578 | #define DA7219_GAIN_RAMP_RATE_MASK (0x3 << 0) | 579 | #define DA7219_GAIN_RAMP_RATE_MASK (0x3 << 0) |
580 | #define DA7219_GAIN_RAMP_RATE_X8 (0x0 << 0) | ||
581 | #define DA7219_GAIN_RAMP_RATE_NOMINAL (0x1 << 0) | ||
579 | #define DA7219_GAIN_RAMP_RATE_MAX 4 | 582 | #define DA7219_GAIN_RAMP_RATE_MAX 4 |
580 | 583 | ||
581 | /* DA7219_PC_COUNT = 0x94 */ | 584 | /* DA7219_PC_COUNT = 0x94 */ |
@@ -770,6 +773,10 @@ | |||
770 | /* SRM */ | 773 | /* SRM */ |
771 | #define DA7219_SRM_CHECK_RETRIES 8 | 774 | #define DA7219_SRM_CHECK_RETRIES 8 |
772 | 775 | ||
776 | /* System Controller */ | ||
777 | #define DA7219_SYS_STAT_CHECK_RETRIES 6 | ||
778 | #define DA7219_SYS_STAT_CHECK_DELAY 50 | ||
779 | |||
773 | enum da7219_clk_src { | 780 | enum da7219_clk_src { |
774 | DA7219_CLKSRC_MCLK = 0, | 781 | DA7219_CLKSRC_MCLK = 0, |
775 | DA7219_CLKSRC_MCLK_SQR, | 782 | DA7219_CLKSRC_MCLK_SQR, |
@@ -796,6 +803,7 @@ struct da7219_priv { | |||
796 | struct da7219_aad_priv *aad; | 803 | struct da7219_aad_priv *aad; |
797 | struct da7219_pdata *pdata; | 804 | struct da7219_pdata *pdata; |
798 | 805 | ||
806 | bool wakeup_source; | ||
799 | struct regulator_bulk_data supplies[DA7219_NUM_SUPPLIES]; | 807 | struct regulator_bulk_data supplies[DA7219_NUM_SUPPLIES]; |
800 | struct regmap *regmap; | 808 | struct regmap *regmap; |
801 | struct mutex lock; | 809 | struct mutex lock; |
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index 461506a4ca6a..c1cc1c1c28f2 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c | |||
@@ -1501,12 +1501,14 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec, | |||
1501 | 1501 | ||
1502 | static struct snd_soc_codec_driver soc_codec_dev_da732x = { | 1502 | static struct snd_soc_codec_driver soc_codec_dev_da732x = { |
1503 | .set_bias_level = da732x_set_bias_level, | 1503 | .set_bias_level = da732x_set_bias_level, |
1504 | .controls = da732x_snd_controls, | 1504 | .component_driver = { |
1505 | .num_controls = ARRAY_SIZE(da732x_snd_controls), | 1505 | .controls = da732x_snd_controls, |
1506 | .dapm_widgets = da732x_dapm_widgets, | 1506 | .num_controls = ARRAY_SIZE(da732x_snd_controls), |
1507 | .num_dapm_widgets = ARRAY_SIZE(da732x_dapm_widgets), | 1507 | .dapm_widgets = da732x_dapm_widgets, |
1508 | .dapm_routes = da732x_dapm_routes, | 1508 | .num_dapm_widgets = ARRAY_SIZE(da732x_dapm_widgets), |
1509 | .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes), | 1509 | .dapm_routes = da732x_dapm_routes, |
1510 | .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes), | ||
1511 | }, | ||
1510 | .set_pll = da732x_set_dai_pll, | 1512 | .set_pll = da732x_set_dai_pll, |
1511 | }; | 1513 | }; |
1512 | 1514 | ||
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index 0b2ede8db978..4efb5f897a0c 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c | |||
@@ -1455,13 +1455,14 @@ static struct snd_soc_codec_driver soc_codec_dev_da9055 = { | |||
1455 | .probe = da9055_probe, | 1455 | .probe = da9055_probe, |
1456 | .set_bias_level = da9055_set_bias_level, | 1456 | .set_bias_level = da9055_set_bias_level, |
1457 | 1457 | ||
1458 | .controls = da9055_snd_controls, | 1458 | .component_driver = { |
1459 | .num_controls = ARRAY_SIZE(da9055_snd_controls), | 1459 | .controls = da9055_snd_controls, |
1460 | 1460 | .num_controls = ARRAY_SIZE(da9055_snd_controls), | |
1461 | .dapm_widgets = da9055_dapm_widgets, | 1461 | .dapm_widgets = da9055_dapm_widgets, |
1462 | .num_dapm_widgets = ARRAY_SIZE(da9055_dapm_widgets), | 1462 | .num_dapm_widgets = ARRAY_SIZE(da9055_dapm_widgets), |
1463 | .dapm_routes = da9055_audio_map, | 1463 | .dapm_routes = da9055_audio_map, |
1464 | .num_dapm_routes = ARRAY_SIZE(da9055_audio_map), | 1464 | .num_dapm_routes = ARRAY_SIZE(da9055_audio_map), |
1465 | }, | ||
1465 | }; | 1466 | }; |
1466 | 1467 | ||
1467 | static const struct regmap_config da9055_regmap_config = { | 1468 | static const struct regmap_config da9055_regmap_config = { |
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index fde53251c047..c82b9dc41e9a 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c | |||
@@ -51,10 +51,12 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
51 | }; | 51 | }; |
52 | 52 | ||
53 | static struct snd_soc_codec_driver soc_dmic = { | 53 | static struct snd_soc_codec_driver soc_dmic = { |
54 | .dapm_widgets = dmic_dapm_widgets, | 54 | .component_driver = { |
55 | .num_dapm_widgets = ARRAY_SIZE(dmic_dapm_widgets), | 55 | .dapm_widgets = dmic_dapm_widgets, |
56 | .dapm_routes = intercon, | 56 | .num_dapm_widgets = ARRAY_SIZE(dmic_dapm_widgets), |
57 | .num_dapm_routes = ARRAY_SIZE(intercon), | 57 | .dapm_routes = intercon, |
58 | .num_dapm_routes = ARRAY_SIZE(intercon), | ||
59 | }, | ||
58 | }; | 60 | }; |
59 | 61 | ||
60 | static int dmic_dev_probe(struct platform_device *pdev) | 62 | static int dmic_dev_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index 2086d7107622..37722194b107 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c | |||
@@ -823,12 +823,14 @@ static struct snd_soc_codec_driver es8328_codec_driver = { | |||
823 | .set_bias_level = es8328_set_bias_level, | 823 | .set_bias_level = es8328_set_bias_level, |
824 | .suspend_bias_off = true, | 824 | .suspend_bias_off = true, |
825 | 825 | ||
826 | .controls = es8328_snd_controls, | 826 | .component_driver = { |
827 | .num_controls = ARRAY_SIZE(es8328_snd_controls), | 827 | .controls = es8328_snd_controls, |
828 | .dapm_widgets = es8328_dapm_widgets, | 828 | .num_controls = ARRAY_SIZE(es8328_snd_controls), |
829 | .num_dapm_widgets = ARRAY_SIZE(es8328_dapm_widgets), | 829 | .dapm_widgets = es8328_dapm_widgets, |
830 | .dapm_routes = es8328_dapm_routes, | 830 | .num_dapm_widgets = ARRAY_SIZE(es8328_dapm_widgets), |
831 | .num_dapm_routes = ARRAY_SIZE(es8328_dapm_routes), | 831 | .dapm_routes = es8328_dapm_routes, |
832 | .num_dapm_routes = ARRAY_SIZE(es8328_dapm_routes), | ||
833 | }, | ||
832 | }; | 834 | }; |
833 | 835 | ||
834 | int es8328_probe(struct device *dev, struct regmap *regmap) | 836 | int es8328_probe(struct device *dev, struct regmap *regmap) |
diff --git a/sound/soc/codecs/gtm601.c b/sound/soc/codecs/gtm601.c index 0b80052996d3..926b1a4e37d4 100644 --- a/sound/soc/codecs/gtm601.c +++ b/sound/soc/codecs/gtm601.c | |||
@@ -52,10 +52,12 @@ static struct snd_soc_dai_driver gtm601_dai = { | |||
52 | }; | 52 | }; |
53 | 53 | ||
54 | static const struct snd_soc_codec_driver soc_codec_dev_gtm601 = { | 54 | static const struct snd_soc_codec_driver soc_codec_dev_gtm601 = { |
55 | .dapm_widgets = gtm601_dapm_widgets, | 55 | .component_driver = { |
56 | .num_dapm_widgets = ARRAY_SIZE(gtm601_dapm_widgets), | 56 | .dapm_widgets = gtm601_dapm_widgets, |
57 | .dapm_routes = gtm601_dapm_routes, | 57 | .num_dapm_widgets = ARRAY_SIZE(gtm601_dapm_widgets), |
58 | .num_dapm_routes = ARRAY_SIZE(gtm601_dapm_routes), | 58 | .dapm_routes = gtm601_dapm_routes, |
59 | .num_dapm_routes = ARRAY_SIZE(gtm601_dapm_routes), | ||
60 | }, | ||
59 | }; | 61 | }; |
60 | 62 | ||
61 | static int gtm601_platform_probe(struct platform_device *pdev) | 63 | static int gtm601_platform_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index 4e181b270d95..c602c4960924 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c | |||
@@ -614,7 +614,7 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream, | |||
614 | (!pin->eld.eld_valid)) { | 614 | (!pin->eld.eld_valid)) { |
615 | 615 | ||
616 | dev_warn(&hdac->hdac.dev, | 616 | dev_warn(&hdac->hdac.dev, |
617 | "Failed: montior present? %d ELD valid?: %d for pin: %d\n", | 617 | "Failed: monitor present? %d ELD valid?: %d for pin: %d\n", |
618 | pin->eld.monitor_present, pin->eld.eld_valid, pin->nid); | 618 | pin->eld.monitor_present, pin->eld.eld_valid, pin->nid); |
619 | 619 | ||
620 | return 0; | 620 | return 0; |
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index f27d115626db..b904492d7744 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c | |||
@@ -24,6 +24,15 @@ | |||
24 | 24 | ||
25 | #include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */ | 25 | #include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */ |
26 | 26 | ||
27 | struct hdmi_device { | ||
28 | struct device *dev; | ||
29 | struct list_head list; | ||
30 | int cnt; | ||
31 | }; | ||
32 | #define pos_to_hdmi_device(pos) container_of((pos), struct hdmi_device, list) | ||
33 | LIST_HEAD(hdmi_device_list); | ||
34 | |||
35 | #define DAI_NAME_SIZE 16 | ||
27 | struct hdmi_codec_priv { | 36 | struct hdmi_codec_priv { |
28 | struct hdmi_codec_pdata hcd; | 37 | struct hdmi_codec_pdata hcd; |
29 | struct snd_soc_dai_driver *daidrv; | 38 | struct snd_soc_dai_driver *daidrv; |
@@ -320,7 +329,6 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = { | |||
320 | SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) | 329 | SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) |
321 | 330 | ||
322 | static struct snd_soc_dai_driver hdmi_i2s_dai = { | 331 | static struct snd_soc_dai_driver hdmi_i2s_dai = { |
323 | .name = "i2s-hifi", | ||
324 | .id = DAI_ID_I2S, | 332 | .id = DAI_ID_I2S, |
325 | .playback = { | 333 | .playback = { |
326 | .stream_name = "Playback", | 334 | .stream_name = "Playback", |
@@ -334,7 +342,6 @@ static struct snd_soc_dai_driver hdmi_i2s_dai = { | |||
334 | }; | 342 | }; |
335 | 343 | ||
336 | static const struct snd_soc_dai_driver hdmi_spdif_dai = { | 344 | static const struct snd_soc_dai_driver hdmi_spdif_dai = { |
337 | .name = "spdif-hifi", | ||
338 | .id = DAI_ID_SPDIF, | 345 | .id = DAI_ID_SPDIF, |
339 | .playback = { | 346 | .playback = { |
340 | .stream_name = "Playback", | 347 | .stream_name = "Playback", |
@@ -346,13 +353,37 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = { | |||
346 | .ops = &hdmi_dai_ops, | 353 | .ops = &hdmi_dai_ops, |
347 | }; | 354 | }; |
348 | 355 | ||
356 | static char hdmi_dai_name[][DAI_NAME_SIZE] = { | ||
357 | "hdmi-hifi.0", | ||
358 | "hdmi-hifi.1", | ||
359 | "hdmi-hifi.2", | ||
360 | "hdmi-hifi.3", | ||
361 | }; | ||
362 | |||
363 | static int hdmi_of_xlate_dai_name(struct snd_soc_component *component, | ||
364 | struct of_phandle_args *args, | ||
365 | const char **dai_name) | ||
366 | { | ||
367 | int id = args->args[0]; | ||
368 | |||
369 | if (id < ARRAY_SIZE(hdmi_dai_name)) { | ||
370 | *dai_name = hdmi_dai_name[id]; | ||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | return -EAGAIN; | ||
375 | } | ||
376 | |||
349 | static struct snd_soc_codec_driver hdmi_codec = { | 377 | static struct snd_soc_codec_driver hdmi_codec = { |
350 | .controls = hdmi_controls, | 378 | .component_driver = { |
351 | .num_controls = ARRAY_SIZE(hdmi_controls), | 379 | .controls = hdmi_controls, |
352 | .dapm_widgets = hdmi_widgets, | 380 | .num_controls = ARRAY_SIZE(hdmi_controls), |
353 | .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets), | 381 | .dapm_widgets = hdmi_widgets, |
354 | .dapm_routes = hdmi_routes, | 382 | .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets), |
355 | .num_dapm_routes = ARRAY_SIZE(hdmi_routes), | 383 | .dapm_routes = hdmi_routes, |
384 | .num_dapm_routes = ARRAY_SIZE(hdmi_routes), | ||
385 | .of_xlate_dai_name = hdmi_of_xlate_dai_name, | ||
386 | }, | ||
356 | }; | 387 | }; |
357 | 388 | ||
358 | static int hdmi_codec_probe(struct platform_device *pdev) | 389 | static int hdmi_codec_probe(struct platform_device *pdev) |
@@ -360,6 +391,8 @@ static int hdmi_codec_probe(struct platform_device *pdev) | |||
360 | struct hdmi_codec_pdata *hcd = pdev->dev.platform_data; | 391 | struct hdmi_codec_pdata *hcd = pdev->dev.platform_data; |
361 | struct device *dev = &pdev->dev; | 392 | struct device *dev = &pdev->dev; |
362 | struct hdmi_codec_priv *hcp; | 393 | struct hdmi_codec_priv *hcp; |
394 | struct hdmi_device *hd; | ||
395 | struct list_head *pos; | ||
363 | int dai_count, i = 0; | 396 | int dai_count, i = 0; |
364 | int ret; | 397 | int ret; |
365 | 398 | ||
@@ -381,6 +414,31 @@ static int hdmi_codec_probe(struct platform_device *pdev) | |||
381 | if (!hcp) | 414 | if (!hcp) |
382 | return -ENOMEM; | 415 | return -ENOMEM; |
383 | 416 | ||
417 | hd = NULL; | ||
418 | list_for_each(pos, &hdmi_device_list) { | ||
419 | struct hdmi_device *tmp = pos_to_hdmi_device(pos); | ||
420 | |||
421 | if (tmp->dev == dev->parent) { | ||
422 | hd = tmp; | ||
423 | break; | ||
424 | } | ||
425 | } | ||
426 | |||
427 | if (!hd) { | ||
428 | hd = devm_kzalloc(dev, sizeof(*hd), GFP_KERNEL); | ||
429 | if (!hd) | ||
430 | return -ENOMEM; | ||
431 | |||
432 | hd->dev = dev->parent; | ||
433 | |||
434 | list_add_tail(&hd->list, &hdmi_device_list); | ||
435 | } | ||
436 | |||
437 | if (hd->cnt >= ARRAY_SIZE(hdmi_dai_name)) { | ||
438 | dev_err(dev, "too many hdmi codec are deteced\n"); | ||
439 | return -EINVAL; | ||
440 | } | ||
441 | |||
384 | hcp->hcd = *hcd; | 442 | hcp->hcd = *hcd; |
385 | mutex_init(&hcp->current_stream_lock); | 443 | mutex_init(&hcp->current_stream_lock); |
386 | 444 | ||
@@ -393,11 +451,14 @@ static int hdmi_codec_probe(struct platform_device *pdev) | |||
393 | hcp->daidrv[i] = hdmi_i2s_dai; | 451 | hcp->daidrv[i] = hdmi_i2s_dai; |
394 | hcp->daidrv[i].playback.channels_max = | 452 | hcp->daidrv[i].playback.channels_max = |
395 | hcd->max_i2s_channels; | 453 | hcd->max_i2s_channels; |
454 | hcp->daidrv[i].name = hdmi_dai_name[hd->cnt++]; | ||
396 | i++; | 455 | i++; |
397 | } | 456 | } |
398 | 457 | ||
399 | if (hcd->spdif) | 458 | if (hcd->spdif) { |
400 | hcp->daidrv[i] = hdmi_spdif_dai; | 459 | hcp->daidrv[i] = hdmi_spdif_dai; |
460 | hcp->daidrv[i].name = hdmi_dai_name[hd->cnt++]; | ||
461 | } | ||
401 | 462 | ||
402 | ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv, | 463 | ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv, |
403 | dai_count); | 464 | dai_count); |
diff --git a/sound/soc/codecs/inno_rk3036.c b/sound/soc/codecs/inno_rk3036.c index 9b6e8840a1b5..b918ba5c8ce5 100644 --- a/sound/soc/codecs/inno_rk3036.c +++ b/sound/soc/codecs/inno_rk3036.c | |||
@@ -380,12 +380,14 @@ static struct snd_soc_codec_driver rk3036_codec_driver = { | |||
380 | .probe = rk3036_codec_probe, | 380 | .probe = rk3036_codec_probe, |
381 | .remove = rk3036_codec_remove, | 381 | .remove = rk3036_codec_remove, |
382 | .set_bias_level = rk3036_codec_set_bias_level, | 382 | .set_bias_level = rk3036_codec_set_bias_level, |
383 | .controls = rk3036_codec_dapm_controls, | 383 | .component_driver = { |
384 | .num_controls = ARRAY_SIZE(rk3036_codec_dapm_controls), | 384 | .controls = rk3036_codec_dapm_controls, |
385 | .dapm_routes = rk3036_codec_dapm_routes, | 385 | .num_controls = ARRAY_SIZE(rk3036_codec_dapm_controls), |
386 | .num_dapm_routes = ARRAY_SIZE(rk3036_codec_dapm_routes), | 386 | .dapm_routes = rk3036_codec_dapm_routes, |
387 | .dapm_widgets = rk3036_codec_dapm_widgets, | 387 | .num_dapm_routes = ARRAY_SIZE(rk3036_codec_dapm_routes), |
388 | .num_dapm_widgets = ARRAY_SIZE(rk3036_codec_dapm_widgets), | 388 | .dapm_widgets = rk3036_codec_dapm_widgets, |
389 | .num_dapm_widgets = ARRAY_SIZE(rk3036_codec_dapm_widgets), | ||
390 | }, | ||
389 | }; | 391 | }; |
390 | 392 | ||
391 | static const struct regmap_config rk3036_codec_regmap_config = { | 393 | static const struct regmap_config rk3036_codec_regmap_config = { |
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index be448373d39a..a4b0eded984a 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c | |||
@@ -1089,12 +1089,14 @@ static struct snd_soc_dai_driver isabelle_dai[] = { | |||
1089 | 1089 | ||
1090 | static struct snd_soc_codec_driver soc_codec_dev_isabelle = { | 1090 | static struct snd_soc_codec_driver soc_codec_dev_isabelle = { |
1091 | .set_bias_level = isabelle_set_bias_level, | 1091 | .set_bias_level = isabelle_set_bias_level, |
1092 | .controls = isabelle_snd_controls, | 1092 | .component_driver = { |
1093 | .num_controls = ARRAY_SIZE(isabelle_snd_controls), | 1093 | .controls = isabelle_snd_controls, |
1094 | .dapm_widgets = isabelle_dapm_widgets, | 1094 | .num_controls = ARRAY_SIZE(isabelle_snd_controls), |
1095 | .num_dapm_widgets = ARRAY_SIZE(isabelle_dapm_widgets), | 1095 | .dapm_widgets = isabelle_dapm_widgets, |
1096 | .dapm_routes = isabelle_intercon, | 1096 | .num_dapm_widgets = ARRAY_SIZE(isabelle_dapm_widgets), |
1097 | .num_dapm_routes = ARRAY_SIZE(isabelle_intercon), | 1097 | .dapm_routes = isabelle_intercon, |
1098 | .num_dapm_routes = ARRAY_SIZE(isabelle_intercon), | ||
1099 | }, | ||
1098 | .idle_bias_off = true, | 1100 | .idle_bias_off = true, |
1099 | }; | 1101 | }; |
1100 | 1102 | ||
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index 1f5ab99956ed..0290fab383da 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c | |||
@@ -298,12 +298,14 @@ static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = { | |||
298 | .set_bias_level = jz4740_codec_set_bias_level, | 298 | .set_bias_level = jz4740_codec_set_bias_level, |
299 | .suspend_bias_off = true, | 299 | .suspend_bias_off = true, |
300 | 300 | ||
301 | .controls = jz4740_codec_controls, | 301 | .component_driver = { |
302 | .num_controls = ARRAY_SIZE(jz4740_codec_controls), | 302 | .controls = jz4740_codec_controls, |
303 | .dapm_widgets = jz4740_codec_dapm_widgets, | 303 | .num_controls = ARRAY_SIZE(jz4740_codec_controls), |
304 | .num_dapm_widgets = ARRAY_SIZE(jz4740_codec_dapm_widgets), | 304 | .dapm_widgets = jz4740_codec_dapm_widgets, |
305 | .dapm_routes = jz4740_codec_dapm_routes, | 305 | .num_dapm_widgets = ARRAY_SIZE(jz4740_codec_dapm_widgets), |
306 | .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes), | 306 | .dapm_routes = jz4740_codec_dapm_routes, |
307 | .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes), | ||
308 | }, | ||
307 | }; | 309 | }; |
308 | 310 | ||
309 | static const struct regmap_config jz4740_codec_regmap_config = { | 311 | static const struct regmap_config jz4740_codec_regmap_config = { |
diff --git a/sound/soc/codecs/l3.c b/sound/soc/codecs/l3.c index 5353af58862c..a10ea3c716c6 100644 --- a/sound/soc/codecs/l3.c +++ b/sound/soc/codecs/l3.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/device.h> | ||
24 | #include <linux/gpio.h> | ||
23 | 25 | ||
24 | #include <sound/l3.h> | 26 | #include <sound/l3.h> |
25 | 27 | ||
@@ -32,11 +34,11 @@ static void sendbyte(struct l3_pins *adap, unsigned int byte) | |||
32 | int i; | 34 | int i; |
33 | 35 | ||
34 | for (i = 0; i < 8; i++) { | 36 | for (i = 0; i < 8; i++) { |
35 | adap->setclk(0); | 37 | adap->setclk(adap, 0); |
36 | udelay(adap->data_hold); | 38 | udelay(adap->data_hold); |
37 | adap->setdat(byte & 1); | 39 | adap->setdat(adap, byte & 1); |
38 | udelay(adap->data_setup); | 40 | udelay(adap->data_setup); |
39 | adap->setclk(1); | 41 | adap->setclk(adap, 1); |
40 | udelay(adap->clock_high); | 42 | udelay(adap->clock_high); |
41 | byte >>= 1; | 43 | byte >>= 1; |
42 | } | 44 | } |
@@ -55,10 +57,10 @@ static void sendbytes(struct l3_pins *adap, const u8 *buf, | |||
55 | for (i = 0; i < len; i++) { | 57 | for (i = 0; i < len; i++) { |
56 | if (i) { | 58 | if (i) { |
57 | udelay(adap->mode_hold); | 59 | udelay(adap->mode_hold); |
58 | adap->setmode(0); | 60 | adap->setmode(adap, 0); |
59 | udelay(adap->mode); | 61 | udelay(adap->mode); |
60 | } | 62 | } |
61 | adap->setmode(1); | 63 | adap->setmode(adap, 1); |
62 | udelay(adap->mode_setup); | 64 | udelay(adap->mode_setup); |
63 | sendbyte(adap, buf[i]); | 65 | sendbyte(adap, buf[i]); |
64 | } | 66 | } |
@@ -66,26 +68,71 @@ static void sendbytes(struct l3_pins *adap, const u8 *buf, | |||
66 | 68 | ||
67 | int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len) | 69 | int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len) |
68 | { | 70 | { |
69 | adap->setclk(1); | 71 | adap->setclk(adap, 1); |
70 | adap->setdat(1); | 72 | adap->setdat(adap, 1); |
71 | adap->setmode(1); | 73 | adap->setmode(adap, 1); |
72 | udelay(adap->mode); | 74 | udelay(adap->mode); |
73 | 75 | ||
74 | adap->setmode(0); | 76 | adap->setmode(adap, 0); |
75 | udelay(adap->mode_setup); | 77 | udelay(adap->mode_setup); |
76 | sendbyte(adap, addr); | 78 | sendbyte(adap, addr); |
77 | udelay(adap->mode_hold); | 79 | udelay(adap->mode_hold); |
78 | 80 | ||
79 | sendbytes(adap, data, len); | 81 | sendbytes(adap, data, len); |
80 | 82 | ||
81 | adap->setclk(1); | 83 | adap->setclk(adap, 1); |
82 | adap->setdat(1); | 84 | adap->setdat(adap, 1); |
83 | adap->setmode(0); | 85 | adap->setmode(adap, 0); |
84 | 86 | ||
85 | return len; | 87 | return len; |
86 | } | 88 | } |
87 | EXPORT_SYMBOL_GPL(l3_write); | 89 | EXPORT_SYMBOL_GPL(l3_write); |
88 | 90 | ||
91 | |||
92 | static void l3_set_clk(struct l3_pins *adap, int val) | ||
93 | { | ||
94 | gpio_set_value(adap->gpio_clk, val); | ||
95 | } | ||
96 | |||
97 | static void l3_set_data(struct l3_pins *adap, int val) | ||
98 | { | ||
99 | gpio_set_value(adap->gpio_data, val); | ||
100 | } | ||
101 | |||
102 | static void l3_set_mode(struct l3_pins *adap, int val) | ||
103 | { | ||
104 | gpio_set_value(adap->gpio_mode, val); | ||
105 | } | ||
106 | |||
107 | int l3_set_gpio_ops(struct device *dev, struct l3_pins *adap) | ||
108 | { | ||
109 | int ret; | ||
110 | |||
111 | if (!adap->use_gpios) | ||
112 | return -EINVAL; | ||
113 | |||
114 | ret = devm_gpio_request_one(dev, adap->gpio_data, | ||
115 | GPIOF_OUT_INIT_LOW, "l3_data"); | ||
116 | if (ret < 0) | ||
117 | return ret; | ||
118 | adap->setdat = l3_set_data; | ||
119 | |||
120 | ret = devm_gpio_request_one(dev, adap->gpio_clk, | ||
121 | GPIOF_OUT_INIT_LOW, "l3_clk"); | ||
122 | if (ret < 0) | ||
123 | return ret; | ||
124 | adap->setclk = l3_set_clk; | ||
125 | |||
126 | ret = devm_gpio_request_one(dev, adap->gpio_mode, | ||
127 | GPIOF_OUT_INIT_LOW, "l3_mode"); | ||
128 | if (ret < 0) | ||
129 | return ret; | ||
130 | adap->setmode = l3_set_mode; | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | EXPORT_SYMBOL_GPL(l3_set_gpio_ops); | ||
135 | |||
89 | MODULE_DESCRIPTION("L3 bit-banging driver"); | 136 | MODULE_DESCRIPTION("L3 bit-banging driver"); |
90 | MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>"); | 137 | MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>"); |
91 | MODULE_LICENSE("GPL"); | 138 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index 9af5640e3446..8d413c2677cc 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c | |||
@@ -1391,12 +1391,14 @@ static struct snd_soc_dai_driver lm49453_dai[] = { | |||
1391 | 1391 | ||
1392 | static struct snd_soc_codec_driver soc_codec_dev_lm49453 = { | 1392 | static struct snd_soc_codec_driver soc_codec_dev_lm49453 = { |
1393 | .set_bias_level = lm49453_set_bias_level, | 1393 | .set_bias_level = lm49453_set_bias_level, |
1394 | .controls = lm49453_snd_controls, | 1394 | .component_driver = { |
1395 | .num_controls = ARRAY_SIZE(lm49453_snd_controls), | 1395 | .controls = lm49453_snd_controls, |
1396 | .dapm_widgets = lm49453_dapm_widgets, | 1396 | .num_controls = ARRAY_SIZE(lm49453_snd_controls), |
1397 | .num_dapm_widgets = ARRAY_SIZE(lm49453_dapm_widgets), | 1397 | .dapm_widgets = lm49453_dapm_widgets, |
1398 | .dapm_routes = lm49453_audio_map, | 1398 | .num_dapm_widgets = ARRAY_SIZE(lm49453_dapm_widgets), |
1399 | .num_dapm_routes = ARRAY_SIZE(lm49453_audio_map), | 1399 | .dapm_routes = lm49453_audio_map, |
1400 | .num_dapm_routes = ARRAY_SIZE(lm49453_audio_map), | ||
1401 | }, | ||
1400 | .idle_bias_off = true, | 1402 | .idle_bias_off = true, |
1401 | }; | 1403 | }; |
1402 | 1404 | ||
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index fc22804cabc5..72f77455582e 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c | |||
@@ -1704,12 +1704,14 @@ static struct snd_soc_codec_driver soc_codec_dev_max98088 = { | |||
1704 | .set_bias_level = max98088_set_bias_level, | 1704 | .set_bias_level = max98088_set_bias_level, |
1705 | .suspend_bias_off = true, | 1705 | .suspend_bias_off = true, |
1706 | 1706 | ||
1707 | .controls = max98088_snd_controls, | 1707 | .component_driver = { |
1708 | .num_controls = ARRAY_SIZE(max98088_snd_controls), | 1708 | .controls = max98088_snd_controls, |
1709 | .dapm_widgets = max98088_dapm_widgets, | 1709 | .num_controls = ARRAY_SIZE(max98088_snd_controls), |
1710 | .num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets), | 1710 | .dapm_widgets = max98088_dapm_widgets, |
1711 | .dapm_routes = max98088_audio_map, | 1711 | .num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets), |
1712 | .num_dapm_routes = ARRAY_SIZE(max98088_audio_map), | 1712 | .dapm_routes = max98088_audio_map, |
1713 | .num_dapm_routes = ARRAY_SIZE(max98088_audio_map), | ||
1714 | }, | ||
1713 | }; | 1715 | }; |
1714 | 1716 | ||
1715 | static int max98088_i2c_probe(struct i2c_client *i2c, | 1717 | static int max98088_i2c_probe(struct i2c_client *i2c, |
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 3577003f39cf..6f8a757876ed 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c | |||
@@ -2108,12 +2108,14 @@ static struct snd_soc_codec_driver soc_codec_dev_max98095 = { | |||
2108 | .suspend = max98095_suspend, | 2108 | .suspend = max98095_suspend, |
2109 | .resume = max98095_resume, | 2109 | .resume = max98095_resume, |
2110 | .set_bias_level = max98095_set_bias_level, | 2110 | .set_bias_level = max98095_set_bias_level, |
2111 | .controls = max98095_snd_controls, | 2111 | .component_driver = { |
2112 | .num_controls = ARRAY_SIZE(max98095_snd_controls), | 2112 | .controls = max98095_snd_controls, |
2113 | .dapm_widgets = max98095_dapm_widgets, | 2113 | .num_controls = ARRAY_SIZE(max98095_snd_controls), |
2114 | .num_dapm_widgets = ARRAY_SIZE(max98095_dapm_widgets), | 2114 | .dapm_widgets = max98095_dapm_widgets, |
2115 | .dapm_routes = max98095_audio_map, | 2115 | .num_dapm_widgets = ARRAY_SIZE(max98095_dapm_widgets), |
2116 | .num_dapm_routes = ARRAY_SIZE(max98095_audio_map), | 2116 | .dapm_routes = max98095_audio_map, |
2117 | .num_dapm_routes = ARRAY_SIZE(max98095_audio_map), | ||
2118 | }, | ||
2117 | }; | 2119 | }; |
2118 | 2120 | ||
2119 | static int max98095_i2c_probe(struct i2c_client *i2c, | 2121 | static int max98095_i2c_probe(struct i2c_client *i2c, |
diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c index 5b1dfb1518fb..6a6b68a4cb52 100644 --- a/sound/soc/codecs/max98357a.c +++ b/sound/soc/codecs/max98357a.c | |||
@@ -74,10 +74,12 @@ static int max98357a_codec_probe(struct snd_soc_codec *codec) | |||
74 | 74 | ||
75 | static struct snd_soc_codec_driver max98357a_codec_driver = { | 75 | static struct snd_soc_codec_driver max98357a_codec_driver = { |
76 | .probe = max98357a_codec_probe, | 76 | .probe = max98357a_codec_probe, |
77 | .dapm_widgets = max98357a_dapm_widgets, | 77 | .component_driver = { |
78 | .num_dapm_widgets = ARRAY_SIZE(max98357a_dapm_widgets), | 78 | .dapm_widgets = max98357a_dapm_widgets, |
79 | .dapm_routes = max98357a_dapm_routes, | 79 | .num_dapm_widgets = ARRAY_SIZE(max98357a_dapm_widgets), |
80 | .num_dapm_routes = ARRAY_SIZE(max98357a_dapm_routes), | 80 | .dapm_routes = max98357a_dapm_routes, |
81 | .num_dapm_routes = ARRAY_SIZE(max98357a_dapm_routes), | ||
82 | }, | ||
81 | }; | 83 | }; |
82 | 84 | ||
83 | static const struct snd_soc_dai_ops max98357a_dai_ops = { | 85 | static const struct snd_soc_dai_ops max98357a_dai_ops = { |
diff --git a/sound/soc/codecs/max98371.c b/sound/soc/codecs/max98371.c index 02352ed8961c..781be9ba8dba 100644 --- a/sound/soc/codecs/max98371.c +++ b/sound/soc/codecs/max98371.c | |||
@@ -426,7 +426,6 @@ MODULE_DEVICE_TABLE(of, max98371_of_match); | |||
426 | static struct i2c_driver max98371_i2c_driver = { | 426 | static struct i2c_driver max98371_i2c_driver = { |
427 | .driver = { | 427 | .driver = { |
428 | .name = "max98371", | 428 | .name = "max98371", |
429 | .owner = THIS_MODULE, | ||
430 | .pm = NULL, | 429 | .pm = NULL, |
431 | .of_match_table = of_match_ptr(max98371_of_match), | 430 | .of_match_table = of_match_ptr(max98371_of_match), |
432 | }, | 431 | }, |
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c index c14a79d026a1..0610840733d1 100644 --- a/sound/soc/codecs/max9850.c +++ b/sound/soc/codecs/max9850.c | |||
@@ -306,12 +306,14 @@ static struct snd_soc_codec_driver soc_codec_dev_max9850 = { | |||
306 | .set_bias_level = max9850_set_bias_level, | 306 | .set_bias_level = max9850_set_bias_level, |
307 | .suspend_bias_off = true, | 307 | .suspend_bias_off = true, |
308 | 308 | ||
309 | .controls = max9850_controls, | 309 | .component_driver = { |
310 | .num_controls = ARRAY_SIZE(max9850_controls), | 310 | .controls = max9850_controls, |
311 | .dapm_widgets = max9850_dapm_widgets, | 311 | .num_controls = ARRAY_SIZE(max9850_controls), |
312 | .num_dapm_widgets = ARRAY_SIZE(max9850_dapm_widgets), | 312 | .dapm_widgets = max9850_dapm_widgets, |
313 | .dapm_routes = max9850_dapm_routes, | 313 | .num_dapm_widgets = ARRAY_SIZE(max9850_dapm_widgets), |
314 | .num_dapm_routes = ARRAY_SIZE(max9850_dapm_routes), | 314 | .dapm_routes = max9850_dapm_routes, |
315 | .num_dapm_routes = ARRAY_SIZE(max9850_dapm_routes), | ||
316 | }, | ||
315 | }; | 317 | }; |
316 | 318 | ||
317 | static int max9850_i2c_probe(struct i2c_client *i2c, | 319 | static int max9850_i2c_probe(struct i2c_client *i2c, |
diff --git a/sound/soc/codecs/max9860.c b/sound/soc/codecs/max9860.c index 68074c92a7c0..499bdbfd0a2d 100644 --- a/sound/soc/codecs/max9860.c +++ b/sound/soc/codecs/max9860.c | |||
@@ -538,12 +538,14 @@ static struct snd_soc_codec_driver max9860_codec_driver = { | |||
538 | .set_bias_level = max9860_set_bias_level, | 538 | .set_bias_level = max9860_set_bias_level, |
539 | .idle_bias_off = true, | 539 | .idle_bias_off = true, |
540 | 540 | ||
541 | .controls = max9860_controls, | 541 | .component_driver = { |
542 | .num_controls = ARRAY_SIZE(max9860_controls), | 542 | .controls = max9860_controls, |
543 | .dapm_widgets = max9860_dapm_widgets, | 543 | .num_controls = ARRAY_SIZE(max9860_controls), |
544 | .num_dapm_widgets = ARRAY_SIZE(max9860_dapm_widgets), | 544 | .dapm_widgets = max9860_dapm_widgets, |
545 | .dapm_routes = max9860_dapm_routes, | 545 | .num_dapm_widgets = ARRAY_SIZE(max9860_dapm_widgets), |
546 | .num_dapm_routes = ARRAY_SIZE(max9860_dapm_routes), | 546 | .dapm_routes = max9860_dapm_routes, |
547 | .num_dapm_routes = ARRAY_SIZE(max9860_dapm_routes), | ||
548 | }, | ||
547 | }; | 549 | }; |
548 | 550 | ||
549 | #ifdef CONFIG_PM | 551 | #ifdef CONFIG_PM |
diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c index 2a22fddeb6af..42e2e407e287 100644 --- a/sound/soc/codecs/max9867.c +++ b/sound/soc/codecs/max9867.c | |||
@@ -38,11 +38,10 @@ static DECLARE_TLV_DB_SCALE(max9860_capture_tlv, -600, 200, 0); | |||
38 | static DECLARE_TLV_DB_SCALE(max9860_mic_tlv, 2000, 100, 1); | 38 | static DECLARE_TLV_DB_SCALE(max9860_mic_tlv, 2000, 100, 1); |
39 | static DECLARE_TLV_DB_SCALE(max9860_adc_left_tlv, -1200, 100, 1); | 39 | static DECLARE_TLV_DB_SCALE(max9860_adc_left_tlv, -1200, 100, 1); |
40 | static DECLARE_TLV_DB_SCALE(max9860_adc_right_tlv, -1200, 100, 1); | 40 | static DECLARE_TLV_DB_SCALE(max9860_adc_right_tlv, -1200, 100, 1); |
41 | static const unsigned int max98088_micboost_tlv[] = { | 41 | static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max98088_micboost_tlv, |
42 | TLV_DB_RANGE_HEAD(2), | ||
43 | 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0), | 42 | 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0), |
44 | 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), | 43 | 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), |
45 | }; | 44 | ); |
46 | 45 | ||
47 | static const struct snd_kcontrol_new max9867_snd_controls[] = { | 46 | static const struct snd_kcontrol_new max9867_snd_controls[] = { |
48 | SOC_DOUBLE_R("Master Playback Volume", MAX9867_LEFTVOL, | 47 | SOC_DOUBLE_R("Master Playback Volume", MAX9867_LEFTVOL, |
@@ -417,12 +416,14 @@ static int max9867_probe(struct snd_soc_codec *codec) | |||
417 | 416 | ||
418 | static struct snd_soc_codec_driver max9867_codec = { | 417 | static struct snd_soc_codec_driver max9867_codec = { |
419 | .probe = max9867_probe, | 418 | .probe = max9867_probe, |
420 | .controls = max9867_snd_controls, | 419 | .component_driver = { |
421 | .num_controls = ARRAY_SIZE(max9867_snd_controls), | 420 | .controls = max9867_snd_controls, |
422 | .dapm_routes = max9867_audio_map, | 421 | .num_controls = ARRAY_SIZE(max9867_snd_controls), |
423 | .num_dapm_routes = ARRAY_SIZE(max9867_audio_map), | 422 | .dapm_routes = max9867_audio_map, |
424 | .dapm_widgets = max9867_dapm_widgets, | 423 | .num_dapm_routes = ARRAY_SIZE(max9867_audio_map), |
425 | .num_dapm_widgets = ARRAY_SIZE(max9867_dapm_widgets), | 424 | .dapm_widgets = max9867_dapm_widgets, |
425 | .num_dapm_widgets = ARRAY_SIZE(max9867_dapm_widgets), | ||
426 | }, | ||
426 | }; | 427 | }; |
427 | 428 | ||
428 | static bool max9867_volatile_register(struct device *dev, unsigned int reg) | 429 | static bool max9867_volatile_register(struct device *dev, unsigned int reg) |
diff --git a/sound/soc/codecs/max98925.c b/sound/soc/codecs/max98925.c index 5990de317999..327eaa25c9bd 100644 --- a/sound/soc/codecs/max98925.c +++ b/sound/soc/codecs/max98925.c | |||
@@ -540,12 +540,14 @@ static int max98925_probe(struct snd_soc_codec *codec) | |||
540 | 540 | ||
541 | static const struct snd_soc_codec_driver soc_codec_dev_max98925 = { | 541 | static const struct snd_soc_codec_driver soc_codec_dev_max98925 = { |
542 | .probe = max98925_probe, | 542 | .probe = max98925_probe, |
543 | .controls = max98925_snd_controls, | 543 | .component_driver = { |
544 | .num_controls = ARRAY_SIZE(max98925_snd_controls), | 544 | .controls = max98925_snd_controls, |
545 | .dapm_routes = max98925_audio_map, | 545 | .num_controls = ARRAY_SIZE(max98925_snd_controls), |
546 | .num_dapm_routes = ARRAY_SIZE(max98925_audio_map), | 546 | .dapm_routes = max98925_audio_map, |
547 | .dapm_widgets = max98925_dapm_widgets, | 547 | .num_dapm_routes = ARRAY_SIZE(max98925_audio_map), |
548 | .num_dapm_widgets = ARRAY_SIZE(max98925_dapm_widgets), | 548 | .dapm_widgets = max98925_dapm_widgets, |
549 | .num_dapm_widgets = ARRAY_SIZE(max98925_dapm_widgets), | ||
550 | }, | ||
549 | }; | 551 | }; |
550 | 552 | ||
551 | static const struct regmap_config max98925_regmap = { | 553 | static const struct regmap_config max98925_regmap = { |
diff --git a/sound/soc/codecs/max98926.c b/sound/soc/codecs/max98926.c index 8d14adae5cc5..1eff7e0b092e 100644 --- a/sound/soc/codecs/max98926.c +++ b/sound/soc/codecs/max98926.c | |||
@@ -347,7 +347,7 @@ static int max98926_dai_set_fmt(struct snd_soc_dai *codec_dai, | |||
347 | max98926_set_sense_data(max98926); | 347 | max98926_set_sense_data(max98926); |
348 | break; | 348 | break; |
349 | default: | 349 | default: |
350 | dev_err(codec->dev, "DAI clock mode unsupported"); | 350 | dev_err(codec->dev, "DAI clock mode unsupported\n"); |
351 | return -EINVAL; | 351 | return -EINVAL; |
352 | } | 352 | } |
353 | 353 | ||
@@ -364,7 +364,7 @@ static int max98926_dai_set_fmt(struct snd_soc_dai *codec_dai, | |||
364 | invert = MAX98926_DAI_BCI_MASK | MAX98926_DAI_WCI_MASK; | 364 | invert = MAX98926_DAI_BCI_MASK | MAX98926_DAI_WCI_MASK; |
365 | break; | 365 | break; |
366 | default: | 366 | default: |
367 | dev_err(codec->dev, "DAI invert mode unsupported"); | 367 | dev_err(codec->dev, "DAI invert mode unsupported\n"); |
368 | return -EINVAL; | 368 | return -EINVAL; |
369 | } | 369 | } |
370 | 370 | ||
@@ -408,7 +408,7 @@ static int max98926_dai_hw_params(struct snd_pcm_substream *substream, | |||
408 | max98926->ch_size = 32; | 408 | max98926->ch_size = 32; |
409 | break; | 409 | break; |
410 | default: | 410 | default: |
411 | dev_dbg(codec->dev, "format unsupported %d", | 411 | dev_dbg(codec->dev, "format unsupported %d\n", |
412 | params_format(params)); | 412 | params_format(params)); |
413 | return -EINVAL; | 413 | return -EINVAL; |
414 | } | 414 | } |
@@ -498,12 +498,14 @@ static int max98926_probe(struct snd_soc_codec *codec) | |||
498 | 498 | ||
499 | static struct snd_soc_codec_driver soc_codec_dev_max98926 = { | 499 | static struct snd_soc_codec_driver soc_codec_dev_max98926 = { |
500 | .probe = max98926_probe, | 500 | .probe = max98926_probe, |
501 | .controls = max98926_snd_controls, | 501 | .component_driver = { |
502 | .num_controls = ARRAY_SIZE(max98926_snd_controls), | 502 | .controls = max98926_snd_controls, |
503 | .dapm_routes = max98926_audio_map, | 503 | .num_controls = ARRAY_SIZE(max98926_snd_controls), |
504 | .num_dapm_routes = ARRAY_SIZE(max98926_audio_map), | 504 | .dapm_routes = max98926_audio_map, |
505 | .dapm_widgets = max98926_dapm_widgets, | 505 | .num_dapm_routes = ARRAY_SIZE(max98926_audio_map), |
506 | .num_dapm_widgets = ARRAY_SIZE(max98926_dapm_widgets), | 506 | .dapm_widgets = max98926_dapm_widgets, |
507 | .num_dapm_widgets = ARRAY_SIZE(max98926_dapm_widgets), | ||
508 | }, | ||
507 | }; | 509 | }; |
508 | 510 | ||
509 | static const struct regmap_config max98926_regmap = { | 511 | static const struct regmap_config max98926_regmap = { |
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 3e770cbe7f0f..90562703dcfd 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c | |||
@@ -737,12 +737,14 @@ static struct snd_soc_codec_driver soc_codec_dev_mc13783 = { | |||
737 | .probe = mc13783_probe, | 737 | .probe = mc13783_probe, |
738 | .remove = mc13783_remove, | 738 | .remove = mc13783_remove, |
739 | .get_regmap = mc13783_get_regmap, | 739 | .get_regmap = mc13783_get_regmap, |
740 | .controls = mc13783_control_list, | 740 | .component_driver = { |
741 | .num_controls = ARRAY_SIZE(mc13783_control_list), | 741 | .controls = mc13783_control_list, |
742 | .dapm_widgets = mc13783_dapm_widgets, | 742 | .num_controls = ARRAY_SIZE(mc13783_control_list), |
743 | .num_dapm_widgets = ARRAY_SIZE(mc13783_dapm_widgets), | 743 | .dapm_widgets = mc13783_dapm_widgets, |
744 | .dapm_routes = mc13783_routes, | 744 | .num_dapm_widgets = ARRAY_SIZE(mc13783_dapm_widgets), |
745 | .num_dapm_routes = ARRAY_SIZE(mc13783_routes), | 745 | .dapm_routes = mc13783_routes, |
746 | .num_dapm_routes = ARRAY_SIZE(mc13783_routes), | ||
747 | }, | ||
746 | }; | 748 | }; |
747 | 749 | ||
748 | static int __init mc13783_codec_probe(struct platform_device *pdev) | 750 | static int __init mc13783_codec_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c index f561c78b9e0e..69e5e18880c5 100644 --- a/sound/soc/codecs/ml26124.c +++ b/sound/soc/codecs/ml26124.c | |||
@@ -541,12 +541,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ml26124 = { | |||
541 | .probe = ml26124_probe, | 541 | .probe = ml26124_probe, |
542 | .set_bias_level = ml26124_set_bias_level, | 542 | .set_bias_level = ml26124_set_bias_level, |
543 | .suspend_bias_off = true, | 543 | .suspend_bias_off = true, |
544 | .dapm_widgets = ml26124_dapm_widgets, | 544 | .component_driver = { |
545 | .num_dapm_widgets = ARRAY_SIZE(ml26124_dapm_widgets), | 545 | .controls = ml26124_snd_controls, |
546 | .dapm_routes = ml26124_intercon, | 546 | .num_controls = ARRAY_SIZE(ml26124_snd_controls), |
547 | .num_dapm_routes = ARRAY_SIZE(ml26124_intercon), | 547 | .dapm_widgets = ml26124_dapm_widgets, |
548 | .controls = ml26124_snd_controls, | 548 | .num_dapm_widgets = ARRAY_SIZE(ml26124_dapm_widgets), |
549 | .num_controls = ARRAY_SIZE(ml26124_snd_controls), | 549 | .dapm_routes = ml26124_intercon, |
550 | .num_dapm_routes = ARRAY_SIZE(ml26124_intercon), | ||
551 | }, | ||
550 | }; | 552 | }; |
551 | 553 | ||
552 | static const struct regmap_config ml26124_i2c_regmap = { | 554 | static const struct regmap_config ml26124_i2c_regmap = { |
diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c new file mode 100644 index 000000000000..e45518629968 --- /dev/null +++ b/sound/soc/codecs/nau8810.c | |||
@@ -0,0 +1,884 @@ | |||
1 | /* | ||
2 | * nau8810.c -- NAU8810 ALSA Soc Audio driver | ||
3 | * | ||
4 | * Copyright 2016 Nuvoton Technology Corp. | ||
5 | * | ||
6 | * Author: David Lin <ctlin0@nuvoton.com> | ||
7 | * | ||
8 | * Based on WM8974.c | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/moduleparam.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/pm.h> | ||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/regmap.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <sound/core.h> | ||
25 | #include <sound/pcm.h> | ||
26 | #include <sound/pcm_params.h> | ||
27 | #include <sound/soc.h> | ||
28 | #include <sound/initval.h> | ||
29 | #include <sound/tlv.h> | ||
30 | |||
31 | #include "nau8810.h" | ||
32 | |||
33 | #define NAU_PLL_FREQ_MAX 100000000 | ||
34 | #define NAU_PLL_FREQ_MIN 90000000 | ||
35 | #define NAU_PLL_REF_MAX 33000000 | ||
36 | #define NAU_PLL_REF_MIN 8000000 | ||
37 | #define NAU_PLL_OPTOP_MIN 6 | ||
38 | |||
39 | |||
40 | static const int nau8810_mclk_scaler[] = { 10, 15, 20, 30, 40, 60, 80, 120 }; | ||
41 | |||
42 | static const struct reg_default nau8810_reg_defaults[] = { | ||
43 | { NAU8810_REG_POWER1, 0x0000 }, | ||
44 | { NAU8810_REG_POWER2, 0x0000 }, | ||
45 | { NAU8810_REG_POWER3, 0x0000 }, | ||
46 | { NAU8810_REG_IFACE, 0x0050 }, | ||
47 | { NAU8810_REG_COMP, 0x0000 }, | ||
48 | { NAU8810_REG_CLOCK, 0x0140 }, | ||
49 | { NAU8810_REG_SMPLR, 0x0000 }, | ||
50 | { NAU8810_REG_DAC, 0x0000 }, | ||
51 | { NAU8810_REG_DACGAIN, 0x00FF }, | ||
52 | { NAU8810_REG_ADC, 0x0100 }, | ||
53 | { NAU8810_REG_ADCGAIN, 0x00FF }, | ||
54 | { NAU8810_REG_EQ1, 0x012C }, | ||
55 | { NAU8810_REG_EQ2, 0x002C }, | ||
56 | { NAU8810_REG_EQ3, 0x002C }, | ||
57 | { NAU8810_REG_EQ4, 0x002C }, | ||
58 | { NAU8810_REG_EQ5, 0x002C }, | ||
59 | { NAU8810_REG_DACLIM1, 0x0032 }, | ||
60 | { NAU8810_REG_DACLIM2, 0x0000 }, | ||
61 | { NAU8810_REG_NOTCH1, 0x0000 }, | ||
62 | { NAU8810_REG_NOTCH2, 0x0000 }, | ||
63 | { NAU8810_REG_NOTCH3, 0x0000 }, | ||
64 | { NAU8810_REG_NOTCH4, 0x0000 }, | ||
65 | { NAU8810_REG_ALC1, 0x0038 }, | ||
66 | { NAU8810_REG_ALC2, 0x000B }, | ||
67 | { NAU8810_REG_ALC3, 0x0032 }, | ||
68 | { NAU8810_REG_NOISEGATE, 0x0000 }, | ||
69 | { NAU8810_REG_PLLN, 0x0008 }, | ||
70 | { NAU8810_REG_PLLK1, 0x000C }, | ||
71 | { NAU8810_REG_PLLK2, 0x0093 }, | ||
72 | { NAU8810_REG_PLLK3, 0x00E9 }, | ||
73 | { NAU8810_REG_ATTEN, 0x0000 }, | ||
74 | { NAU8810_REG_INPUT_SIGNAL, 0x0003 }, | ||
75 | { NAU8810_REG_PGAGAIN, 0x0010 }, | ||
76 | { NAU8810_REG_ADCBOOST, 0x0100 }, | ||
77 | { NAU8810_REG_OUTPUT, 0x0002 }, | ||
78 | { NAU8810_REG_SPKMIX, 0x0001 }, | ||
79 | { NAU8810_REG_SPKGAIN, 0x0039 }, | ||
80 | { NAU8810_REG_MONOMIX, 0x0001 }, | ||
81 | { NAU8810_REG_POWER4, 0x0000 }, | ||
82 | { NAU8810_REG_TSLOTCTL1, 0x0000 }, | ||
83 | { NAU8810_REG_TSLOTCTL2, 0x0020 }, | ||
84 | { NAU8810_REG_DEVICE_REVID, 0x0000 }, | ||
85 | { NAU8810_REG_I2C_DEVICEID, 0x001A }, | ||
86 | { NAU8810_REG_ADDITIONID, 0x00CA }, | ||
87 | { NAU8810_REG_RESERVE, 0x0124 }, | ||
88 | { NAU8810_REG_OUTCTL, 0x0001 }, | ||
89 | { NAU8810_REG_ALC1ENHAN1, 0x0010 }, | ||
90 | { NAU8810_REG_ALC1ENHAN2, 0x0000 }, | ||
91 | { NAU8810_REG_MISCCTL, 0x0000 }, | ||
92 | { NAU8810_REG_OUTTIEOFF, 0x0000 }, | ||
93 | { NAU8810_REG_AGCP2POUT, 0x0000 }, | ||
94 | { NAU8810_REG_AGCPOUT, 0x0000 }, | ||
95 | { NAU8810_REG_AMTCTL, 0x0000 }, | ||
96 | { NAU8810_REG_OUTTIEOFFMAN, 0x0000 }, | ||
97 | }; | ||
98 | |||
99 | static bool nau8810_readable_reg(struct device *dev, unsigned int reg) | ||
100 | { | ||
101 | switch (reg) { | ||
102 | case NAU8810_REG_RESET ... NAU8810_REG_SMPLR: | ||
103 | case NAU8810_REG_DAC ... NAU8810_REG_DACGAIN: | ||
104 | case NAU8810_REG_ADC ... NAU8810_REG_ADCGAIN: | ||
105 | case NAU8810_REG_EQ1 ... NAU8810_REG_EQ5: | ||
106 | case NAU8810_REG_DACLIM1 ... NAU8810_REG_DACLIM2: | ||
107 | case NAU8810_REG_NOTCH1 ... NAU8810_REG_NOTCH4: | ||
108 | case NAU8810_REG_ALC1 ... NAU8810_REG_ATTEN: | ||
109 | case NAU8810_REG_INPUT_SIGNAL ... NAU8810_REG_PGAGAIN: | ||
110 | case NAU8810_REG_ADCBOOST: | ||
111 | case NAU8810_REG_OUTPUT ... NAU8810_REG_SPKMIX: | ||
112 | case NAU8810_REG_SPKGAIN: | ||
113 | case NAU8810_REG_MONOMIX: | ||
114 | case NAU8810_REG_POWER4 ... NAU8810_REG_TSLOTCTL2: | ||
115 | case NAU8810_REG_DEVICE_REVID ... NAU8810_REG_RESERVE: | ||
116 | case NAU8810_REG_OUTCTL ... NAU8810_REG_ALC1ENHAN2: | ||
117 | case NAU8810_REG_MISCCTL: | ||
118 | case NAU8810_REG_OUTTIEOFF ... NAU8810_REG_OUTTIEOFFMAN: | ||
119 | return true; | ||
120 | default: | ||
121 | return false; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | static bool nau8810_writeable_reg(struct device *dev, unsigned int reg) | ||
126 | { | ||
127 | switch (reg) { | ||
128 | case NAU8810_REG_RESET ... NAU8810_REG_SMPLR: | ||
129 | case NAU8810_REG_DAC ... NAU8810_REG_DACGAIN: | ||
130 | case NAU8810_REG_ADC ... NAU8810_REG_ADCGAIN: | ||
131 | case NAU8810_REG_EQ1 ... NAU8810_REG_EQ5: | ||
132 | case NAU8810_REG_DACLIM1 ... NAU8810_REG_DACLIM2: | ||
133 | case NAU8810_REG_NOTCH1 ... NAU8810_REG_NOTCH4: | ||
134 | case NAU8810_REG_ALC1 ... NAU8810_REG_ATTEN: | ||
135 | case NAU8810_REG_INPUT_SIGNAL ... NAU8810_REG_PGAGAIN: | ||
136 | case NAU8810_REG_ADCBOOST: | ||
137 | case NAU8810_REG_OUTPUT ... NAU8810_REG_SPKMIX: | ||
138 | case NAU8810_REG_SPKGAIN: | ||
139 | case NAU8810_REG_MONOMIX: | ||
140 | case NAU8810_REG_POWER4 ... NAU8810_REG_TSLOTCTL2: | ||
141 | case NAU8810_REG_OUTCTL ... NAU8810_REG_ALC1ENHAN2: | ||
142 | case NAU8810_REG_MISCCTL: | ||
143 | case NAU8810_REG_OUTTIEOFF ... NAU8810_REG_OUTTIEOFFMAN: | ||
144 | return true; | ||
145 | default: | ||
146 | return false; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | static bool nau8810_volatile_reg(struct device *dev, unsigned int reg) | ||
151 | { | ||
152 | switch (reg) { | ||
153 | case NAU8810_REG_RESET: | ||
154 | case NAU8810_REG_DEVICE_REVID ... NAU8810_REG_RESERVE: | ||
155 | return true; | ||
156 | default: | ||
157 | return false; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | /* The EQ parameters get function is to get the 5 band equalizer control. | ||
162 | * The regmap raw read can't work here because regmap doesn't provide | ||
163 | * value format for value width of 9 bits. Therefore, the driver reads data | ||
164 | * from cache and makes value format according to the endianness of | ||
165 | * bytes type control element. | ||
166 | */ | ||
167 | static int nau8810_eq_get(struct snd_kcontrol *kcontrol, | ||
168 | struct snd_ctl_elem_value *ucontrol) | ||
169 | { | ||
170 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
171 | struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec); | ||
172 | struct soc_bytes_ext *params = (void *)kcontrol->private_value; | ||
173 | int i, reg, reg_val; | ||
174 | u16 *val; | ||
175 | |||
176 | val = (u16 *)ucontrol->value.bytes.data; | ||
177 | reg = NAU8810_REG_EQ1; | ||
178 | for (i = 0; i < params->max / sizeof(u16); i++) { | ||
179 | regmap_read(nau8810->regmap, reg + i, ®_val); | ||
180 | /* conversion of 16-bit integers between native CPU format | ||
181 | * and big endian format | ||
182 | */ | ||
183 | reg_val = cpu_to_be16(reg_val); | ||
184 | memcpy(val + i, ®_val, sizeof(reg_val)); | ||
185 | } | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | /* The EQ parameters put function is to make configuration of 5 band equalizer | ||
191 | * control. These configuration includes central frequency, equalizer gain, | ||
192 | * cut-off frequency, bandwidth control, and equalizer path. | ||
193 | * The regmap raw write can't work here because regmap doesn't provide | ||
194 | * register and value format for register with address 7 bits and value 9 bits. | ||
195 | * Therefore, the driver makes value format according to the endianness of | ||
196 | * bytes type control element and writes data to codec. | ||
197 | */ | ||
198 | static int nau8810_eq_put(struct snd_kcontrol *kcontrol, | ||
199 | struct snd_ctl_elem_value *ucontrol) | ||
200 | { | ||
201 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
202 | struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec); | ||
203 | struct soc_bytes_ext *params = (void *)kcontrol->private_value; | ||
204 | void *data; | ||
205 | u16 *val, value; | ||
206 | int i, reg, ret; | ||
207 | |||
208 | data = kmemdup(ucontrol->value.bytes.data, | ||
209 | params->max, GFP_KERNEL | GFP_DMA); | ||
210 | if (!data) | ||
211 | return -ENOMEM; | ||
212 | |||
213 | val = (u16 *)data; | ||
214 | reg = NAU8810_REG_EQ1; | ||
215 | for (i = 0; i < params->max / sizeof(u16); i++) { | ||
216 | /* conversion of 16-bit integers between native CPU format | ||
217 | * and big endian format | ||
218 | */ | ||
219 | value = be16_to_cpu(*(val + i)); | ||
220 | ret = regmap_write(nau8810->regmap, reg + i, value); | ||
221 | if (ret) { | ||
222 | dev_err(codec->dev, "EQ configuration fail, register: %x ret: %d\n", | ||
223 | reg + i, ret); | ||
224 | kfree(data); | ||
225 | return ret; | ||
226 | } | ||
227 | } | ||
228 | kfree(data); | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static const char * const nau8810_companding[] = { | ||
234 | "Off", "NC", "u-law", "A-law" }; | ||
235 | |||
236 | static const struct soc_enum nau8810_companding_adc_enum = | ||
237 | SOC_ENUM_SINGLE(NAU8810_REG_COMP, NAU8810_ADCCM_SFT, | ||
238 | ARRAY_SIZE(nau8810_companding), nau8810_companding); | ||
239 | |||
240 | static const struct soc_enum nau8810_companding_dac_enum = | ||
241 | SOC_ENUM_SINGLE(NAU8810_REG_COMP, NAU8810_DACCM_SFT, | ||
242 | ARRAY_SIZE(nau8810_companding), nau8810_companding); | ||
243 | |||
244 | static const char * const nau8810_deemp[] = { | ||
245 | "None", "32kHz", "44.1kHz", "48kHz" }; | ||
246 | |||
247 | static const struct soc_enum nau8810_deemp_enum = | ||
248 | SOC_ENUM_SINGLE(NAU8810_REG_DAC, NAU8810_DEEMP_SFT, | ||
249 | ARRAY_SIZE(nau8810_deemp), nau8810_deemp); | ||
250 | |||
251 | static const char * const nau8810_eqmode[] = {"Capture", "Playback" }; | ||
252 | |||
253 | static const struct soc_enum nau8810_eqmode_enum = | ||
254 | SOC_ENUM_SINGLE(NAU8810_REG_EQ1, NAU8810_EQM_SFT, | ||
255 | ARRAY_SIZE(nau8810_eqmode), nau8810_eqmode); | ||
256 | |||
257 | static const char * const nau8810_alc[] = {"Normal", "Limiter" }; | ||
258 | |||
259 | static const struct soc_enum nau8810_alc_enum = | ||
260 | SOC_ENUM_SINGLE(NAU8810_REG_ALC3, NAU8810_ALCM_SFT, | ||
261 | ARRAY_SIZE(nau8810_alc), nau8810_alc); | ||
262 | |||
263 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1); | ||
264 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); | ||
265 | static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0); | ||
266 | static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0); | ||
267 | |||
268 | static const struct snd_kcontrol_new nau8810_snd_controls[] = { | ||
269 | SOC_ENUM("ADC Companding", nau8810_companding_adc_enum), | ||
270 | SOC_ENUM("DAC Companding", nau8810_companding_dac_enum), | ||
271 | SOC_ENUM("DAC De-emphasis", nau8810_deemp_enum), | ||
272 | |||
273 | SOC_ENUM("EQ Function", nau8810_eqmode_enum), | ||
274 | SND_SOC_BYTES_EXT("EQ Parameters", 10, | ||
275 | nau8810_eq_get, nau8810_eq_put), | ||
276 | |||
277 | SOC_SINGLE("DAC Inversion Switch", NAU8810_REG_DAC, | ||
278 | NAU8810_DACPL_SFT, 1, 0), | ||
279 | SOC_SINGLE_TLV("Playback Volume", NAU8810_REG_DACGAIN, | ||
280 | NAU8810_DACGAIN_SFT, 0xff, 0, digital_tlv), | ||
281 | |||
282 | SOC_SINGLE("High Pass Filter Switch", NAU8810_REG_ADC, | ||
283 | NAU8810_HPFEN_SFT, 1, 0), | ||
284 | SOC_SINGLE("High Pass Cut Off", NAU8810_REG_ADC, | ||
285 | NAU8810_HPF_SFT, 0x7, 0), | ||
286 | |||
287 | SOC_SINGLE("ADC Inversion Switch", NAU8810_REG_ADC, | ||
288 | NAU8810_ADCPL_SFT, 1, 0), | ||
289 | SOC_SINGLE_TLV("Capture Volume", NAU8810_REG_ADCGAIN, | ||
290 | NAU8810_ADCGAIN_SFT, 0xff, 0, digital_tlv), | ||
291 | |||
292 | SOC_SINGLE_TLV("EQ1 Volume", NAU8810_REG_EQ1, | ||
293 | NAU8810_EQ1GC_SFT, 0x18, 1, eq_tlv), | ||
294 | SOC_SINGLE_TLV("EQ2 Volume", NAU8810_REG_EQ2, | ||
295 | NAU8810_EQ2GC_SFT, 0x18, 1, eq_tlv), | ||
296 | SOC_SINGLE_TLV("EQ3 Volume", NAU8810_REG_EQ3, | ||
297 | NAU8810_EQ3GC_SFT, 0x18, 1, eq_tlv), | ||
298 | SOC_SINGLE_TLV("EQ4 Volume", NAU8810_REG_EQ4, | ||
299 | NAU8810_EQ4GC_SFT, 0x18, 1, eq_tlv), | ||
300 | SOC_SINGLE_TLV("EQ5 Volume", NAU8810_REG_EQ5, | ||
301 | NAU8810_EQ5GC_SFT, 0x18, 1, eq_tlv), | ||
302 | |||
303 | SOC_SINGLE("DAC Limiter Switch", NAU8810_REG_DACLIM1, | ||
304 | NAU8810_DACLIMEN_SFT, 1, 0), | ||
305 | SOC_SINGLE("DAC Limiter Decay", NAU8810_REG_DACLIM1, | ||
306 | NAU8810_DACLIMDCY_SFT, 0xf, 0), | ||
307 | SOC_SINGLE("DAC Limiter Attack", NAU8810_REG_DACLIM1, | ||
308 | NAU8810_DACLIMATK_SFT, 0xf, 0), | ||
309 | SOC_SINGLE("DAC Limiter Threshold", NAU8810_REG_DACLIM2, | ||
310 | NAU8810_DACLIMTHL_SFT, 0x7, 0), | ||
311 | SOC_SINGLE("DAC Limiter Boost", NAU8810_REG_DACLIM2, | ||
312 | NAU8810_DACLIMBST_SFT, 0xf, 0), | ||
313 | |||
314 | SOC_ENUM("ALC Mode", nau8810_alc_enum), | ||
315 | SOC_SINGLE("ALC Enable Switch", NAU8810_REG_ALC1, | ||
316 | NAU8810_ALCEN_SFT, 1, 0), | ||
317 | SOC_SINGLE("ALC Max Volume", NAU8810_REG_ALC1, | ||
318 | NAU8810_ALCMXGAIN_SFT, 0x7, 0), | ||
319 | SOC_SINGLE("ALC Min Volume", NAU8810_REG_ALC1, | ||
320 | NAU8810_ALCMINGAIN_SFT, 0x7, 0), | ||
321 | SOC_SINGLE("ALC ZC Switch", NAU8810_REG_ALC2, | ||
322 | NAU8810_ALCZC_SFT, 1, 0), | ||
323 | SOC_SINGLE("ALC Hold", NAU8810_REG_ALC2, | ||
324 | NAU8810_ALCHT_SFT, 0xf, 0), | ||
325 | SOC_SINGLE("ALC Target", NAU8810_REG_ALC2, | ||
326 | NAU8810_ALCSL_SFT, 0xf, 0), | ||
327 | SOC_SINGLE("ALC Decay", NAU8810_REG_ALC3, | ||
328 | NAU8810_ALCDCY_SFT, 0xf, 0), | ||
329 | SOC_SINGLE("ALC Attack", NAU8810_REG_ALC3, | ||
330 | NAU8810_ALCATK_SFT, 0xf, 0), | ||
331 | SOC_SINGLE("ALC Noise Gate Switch", NAU8810_REG_NOISEGATE, | ||
332 | NAU8810_ALCNEN_SFT, 1, 0), | ||
333 | SOC_SINGLE("ALC Noise Gate Threshold", NAU8810_REG_NOISEGATE, | ||
334 | NAU8810_ALCNTH_SFT, 0x7, 0), | ||
335 | |||
336 | SOC_SINGLE("PGA ZC Switch", NAU8810_REG_PGAGAIN, | ||
337 | NAU8810_PGAZC_SFT, 1, 0), | ||
338 | SOC_SINGLE_TLV("PGA Volume", NAU8810_REG_PGAGAIN, | ||
339 | NAU8810_PGAGAIN_SFT, 0x3f, 0, inpga_tlv), | ||
340 | |||
341 | SOC_SINGLE("Speaker ZC Switch", NAU8810_REG_SPKGAIN, | ||
342 | NAU8810_SPKZC_SFT, 1, 0), | ||
343 | SOC_SINGLE("Speaker Mute Switch", NAU8810_REG_SPKGAIN, | ||
344 | NAU8810_SPKMT_SFT, 1, 0), | ||
345 | SOC_SINGLE_TLV("Speaker Volume", NAU8810_REG_SPKGAIN, | ||
346 | NAU8810_SPKGAIN_SFT, 0x3f, 0, spk_tlv), | ||
347 | |||
348 | SOC_SINGLE("Capture Boost(+20dB)", NAU8810_REG_ADCBOOST, | ||
349 | NAU8810_PGABST_SFT, 1, 0), | ||
350 | SOC_SINGLE("Mono Mute Switch", NAU8810_REG_MONOMIX, | ||
351 | NAU8810_MOUTMXMT_SFT, 1, 0), | ||
352 | |||
353 | SOC_SINGLE("DAC Oversampling Rate(128x) Switch", NAU8810_REG_DAC, | ||
354 | NAU8810_DACOS_SFT, 1, 0), | ||
355 | SOC_SINGLE("ADC Oversampling Rate(128x) Switch", NAU8810_REG_ADC, | ||
356 | NAU8810_ADCOS_SFT, 1, 0), | ||
357 | }; | ||
358 | |||
359 | /* Speaker Output Mixer */ | ||
360 | static const struct snd_kcontrol_new nau8810_speaker_mixer_controls[] = { | ||
361 | SOC_DAPM_SINGLE("Line Bypass Switch", NAU8810_REG_SPKMIX, | ||
362 | NAU8810_BYPSPK_SFT, 1, 0), | ||
363 | SOC_DAPM_SINGLE("PCM Playback Switch", NAU8810_REG_SPKMIX, | ||
364 | NAU8810_DACSPK_SFT, 1, 0), | ||
365 | }; | ||
366 | |||
367 | /* Mono Output Mixer */ | ||
368 | static const struct snd_kcontrol_new nau8810_mono_mixer_controls[] = { | ||
369 | SOC_DAPM_SINGLE("Line Bypass Switch", NAU8810_REG_MONOMIX, | ||
370 | NAU8810_BYPMOUT_SFT, 1, 0), | ||
371 | SOC_DAPM_SINGLE("PCM Playback Switch", NAU8810_REG_MONOMIX, | ||
372 | NAU8810_DACMOUT_SFT, 1, 0), | ||
373 | }; | ||
374 | |||
375 | /* PGA Mute */ | ||
376 | static const struct snd_kcontrol_new nau8810_inpga_mute[] = { | ||
377 | SOC_DAPM_SINGLE("PGA Mute Switch", NAU8810_REG_PGAGAIN, | ||
378 | NAU8810_PGAMT_SFT, 1, 0), | ||
379 | }; | ||
380 | |||
381 | /* Input PGA */ | ||
382 | static const struct snd_kcontrol_new nau8810_inpga[] = { | ||
383 | SOC_DAPM_SINGLE("MicN Switch", NAU8810_REG_INPUT_SIGNAL, | ||
384 | NAU8810_NMICPGA_SFT, 1, 0), | ||
385 | SOC_DAPM_SINGLE("MicP Switch", NAU8810_REG_INPUT_SIGNAL, | ||
386 | NAU8810_PMICPGA_SFT, 1, 0), | ||
387 | }; | ||
388 | |||
389 | /* Mic Input boost vol */ | ||
390 | static const struct snd_kcontrol_new nau8810_mic_boost_controls = | ||
391 | SOC_DAPM_SINGLE("Mic Volume", NAU8810_REG_ADCBOOST, | ||
392 | NAU8810_PMICBSTGAIN_SFT, 0x7, 0); | ||
393 | |||
394 | /* Loopback Switch */ | ||
395 | static const struct snd_kcontrol_new nau8810_loopback = | ||
396 | SOC_DAPM_SINGLE("Switch", NAU8810_REG_COMP, | ||
397 | NAU8810_ADDAP_SFT, 1, 0); | ||
398 | |||
399 | static int check_mclk_select_pll(struct snd_soc_dapm_widget *source, | ||
400 | struct snd_soc_dapm_widget *sink) | ||
401 | { | ||
402 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
403 | struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec); | ||
404 | unsigned int value; | ||
405 | |||
406 | regmap_read(nau8810->regmap, NAU8810_REG_CLOCK, &value); | ||
407 | return (value & NAU8810_CLKM_MASK); | ||
408 | } | ||
409 | |||
410 | static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = { | ||
411 | SND_SOC_DAPM_MIXER("Speaker Mixer", NAU8810_REG_POWER3, | ||
412 | NAU8810_SPKMX_EN_SFT, 0, &nau8810_speaker_mixer_controls[0], | ||
413 | ARRAY_SIZE(nau8810_speaker_mixer_controls)), | ||
414 | SND_SOC_DAPM_MIXER("Mono Mixer", NAU8810_REG_POWER3, | ||
415 | NAU8810_MOUTMX_EN_SFT, 0, &nau8810_mono_mixer_controls[0], | ||
416 | ARRAY_SIZE(nau8810_mono_mixer_controls)), | ||
417 | SND_SOC_DAPM_DAC("DAC", "HiFi Playback", NAU8810_REG_POWER3, | ||
418 | NAU8810_DAC_EN_SFT, 0), | ||
419 | SND_SOC_DAPM_ADC("ADC", "HiFi Capture", NAU8810_REG_POWER2, | ||
420 | NAU8810_ADC_EN_SFT, 0), | ||
421 | SND_SOC_DAPM_PGA("SpkN Out", NAU8810_REG_POWER3, | ||
422 | NAU8810_NSPK_EN_SFT, 0, NULL, 0), | ||
423 | SND_SOC_DAPM_PGA("SpkP Out", NAU8810_REG_POWER3, | ||
424 | NAU8810_PSPK_EN_SFT, 0, NULL, 0), | ||
425 | SND_SOC_DAPM_PGA("Mono Out", NAU8810_REG_POWER3, | ||
426 | NAU8810_MOUT_EN_SFT, 0, NULL, 0), | ||
427 | |||
428 | SND_SOC_DAPM_MIXER("Input PGA", NAU8810_REG_POWER2, | ||
429 | NAU8810_PGA_EN_SFT, 0, nau8810_inpga, | ||
430 | ARRAY_SIZE(nau8810_inpga)), | ||
431 | SND_SOC_DAPM_MIXER("Input Boost Stage", NAU8810_REG_POWER2, | ||
432 | NAU8810_BST_EN_SFT, 0, nau8810_inpga_mute, | ||
433 | ARRAY_SIZE(nau8810_inpga_mute)), | ||
434 | |||
435 | SND_SOC_DAPM_SUPPLY("Mic Bias", NAU8810_REG_POWER1, | ||
436 | NAU8810_MICBIAS_EN_SFT, 0, NULL, 0), | ||
437 | SND_SOC_DAPM_SUPPLY("PLL", NAU8810_REG_POWER1, | ||
438 | NAU8810_PLL_EN_SFT, 0, NULL, 0), | ||
439 | |||
440 | SND_SOC_DAPM_SWITCH("Digital Loopback", SND_SOC_NOPM, 0, 0, | ||
441 | &nau8810_loopback), | ||
442 | |||
443 | SND_SOC_DAPM_INPUT("MICN"), | ||
444 | SND_SOC_DAPM_INPUT("MICP"), | ||
445 | SND_SOC_DAPM_OUTPUT("MONOOUT"), | ||
446 | SND_SOC_DAPM_OUTPUT("SPKOUTP"), | ||
447 | SND_SOC_DAPM_OUTPUT("SPKOUTN"), | ||
448 | }; | ||
449 | |||
450 | static const struct snd_soc_dapm_route nau8810_dapm_routes[] = { | ||
451 | {"DAC", NULL, "PLL", check_mclk_select_pll}, | ||
452 | |||
453 | /* Mono output mixer */ | ||
454 | {"Mono Mixer", "PCM Playback Switch", "DAC"}, | ||
455 | {"Mono Mixer", "Line Bypass Switch", "Input Boost Stage"}, | ||
456 | |||
457 | /* Speaker output mixer */ | ||
458 | {"Speaker Mixer", "PCM Playback Switch", "DAC"}, | ||
459 | {"Speaker Mixer", "Line Bypass Switch", "Input Boost Stage"}, | ||
460 | |||
461 | /* Outputs */ | ||
462 | {"Mono Out", NULL, "Mono Mixer"}, | ||
463 | {"MONOOUT", NULL, "Mono Out"}, | ||
464 | {"SpkN Out", NULL, "Speaker Mixer"}, | ||
465 | {"SpkP Out", NULL, "Speaker Mixer"}, | ||
466 | {"SPKOUTN", NULL, "SpkN Out"}, | ||
467 | {"SPKOUTP", NULL, "SpkP Out"}, | ||
468 | |||
469 | /* Input Boost Stage */ | ||
470 | {"ADC", NULL, "Input Boost Stage"}, | ||
471 | {"ADC", NULL, "PLL", check_mclk_select_pll}, | ||
472 | {"Input Boost Stage", NULL, "Input PGA"}, | ||
473 | {"Input Boost Stage", NULL, "MICP"}, | ||
474 | |||
475 | /* Input PGA */ | ||
476 | {"Input PGA", NULL, "Mic Bias"}, | ||
477 | {"Input PGA", "MicN Switch", "MICN"}, | ||
478 | {"Input PGA", "MicP Switch", "MICP"}, | ||
479 | |||
480 | /* Digital Looptack */ | ||
481 | {"Digital Loopback", "Switch", "ADC"}, | ||
482 | {"DAC", NULL, "Digital Loopback"}, | ||
483 | }; | ||
484 | |||
485 | static int nau8810_set_sysclk(struct snd_soc_dai *dai, | ||
486 | int clk_id, unsigned int freq, int dir) | ||
487 | { | ||
488 | struct snd_soc_codec *codec = dai->codec; | ||
489 | struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec); | ||
490 | |||
491 | nau8810->clk_id = clk_id; | ||
492 | nau8810->sysclk = freq; | ||
493 | dev_dbg(nau8810->dev, "master sysclk %dHz, source %s\n", | ||
494 | freq, clk_id == NAU8810_SCLK_PLL ? "PLL" : "MCLK"); | ||
495 | |||
496 | return 0; | ||
497 | } | ||
498 | |||
499 | static int nau88l0_calc_pll(unsigned int pll_in, | ||
500 | unsigned int fs, struct nau8810_pll *pll_param) | ||
501 | { | ||
502 | u64 f2, f2_max, pll_ratio; | ||
503 | int i, scal_sel; | ||
504 | |||
505 | if (pll_in > NAU_PLL_REF_MAX || pll_in < NAU_PLL_REF_MIN) | ||
506 | return -EINVAL; | ||
507 | |||
508 | f2_max = 0; | ||
509 | scal_sel = ARRAY_SIZE(nau8810_mclk_scaler); | ||
510 | for (i = 0; i < ARRAY_SIZE(nau8810_mclk_scaler); i++) { | ||
511 | f2 = 256 * fs * 4 * nau8810_mclk_scaler[i] / 10; | ||
512 | if (f2 > NAU_PLL_FREQ_MIN && f2 < NAU_PLL_FREQ_MAX && | ||
513 | f2_max < f2) { | ||
514 | f2_max = f2; | ||
515 | scal_sel = i; | ||
516 | } | ||
517 | } | ||
518 | if (ARRAY_SIZE(nau8810_mclk_scaler) == scal_sel) | ||
519 | return -EINVAL; | ||
520 | pll_param->mclk_scaler = scal_sel; | ||
521 | f2 = f2_max; | ||
522 | |||
523 | /* Calculate the PLL 4-bit integer input and the PLL 24-bit fractional | ||
524 | * input; round up the 24+4bit. | ||
525 | */ | ||
526 | pll_ratio = div_u64(f2 << 28, pll_in); | ||
527 | pll_param->pre_factor = 0; | ||
528 | if (((pll_ratio >> 28) & 0xF) < NAU_PLL_OPTOP_MIN) { | ||
529 | pll_ratio <<= 1; | ||
530 | pll_param->pre_factor = 1; | ||
531 | } | ||
532 | pll_param->pll_int = (pll_ratio >> 28) & 0xF; | ||
533 | pll_param->pll_frac = ((pll_ratio & 0xFFFFFFF) >> 4); | ||
534 | |||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int nau8810_set_pll(struct snd_soc_dai *codec_dai, int pll_id, | ||
539 | int source, unsigned int freq_in, unsigned int freq_out) | ||
540 | { | ||
541 | struct snd_soc_codec *codec = codec_dai->codec; | ||
542 | struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec); | ||
543 | struct regmap *map = nau8810->regmap; | ||
544 | struct nau8810_pll *pll_param = &nau8810->pll; | ||
545 | int ret, fs; | ||
546 | |||
547 | fs = freq_out / 256; | ||
548 | ret = nau88l0_calc_pll(freq_in, fs, pll_param); | ||
549 | if (ret < 0) { | ||
550 | dev_err(nau8810->dev, "Unsupported input clock %d\n", freq_in); | ||
551 | return ret; | ||
552 | } | ||
553 | dev_info(nau8810->dev, "pll_int=%x pll_frac=%x mclk_scaler=%x pre_factor=%x\n", | ||
554 | pll_param->pll_int, pll_param->pll_frac, pll_param->mclk_scaler, | ||
555 | pll_param->pre_factor); | ||
556 | |||
557 | regmap_update_bits(map, NAU8810_REG_PLLN, | ||
558 | NAU8810_PLLMCLK_DIV2 | NAU8810_PLLN_MASK, | ||
559 | (pll_param->pre_factor ? NAU8810_PLLMCLK_DIV2 : 0) | | ||
560 | pll_param->pll_int); | ||
561 | regmap_write(map, NAU8810_REG_PLLK1, | ||
562 | (pll_param->pll_frac >> NAU8810_PLLK1_SFT) & | ||
563 | NAU8810_PLLK1_MASK); | ||
564 | regmap_write(map, NAU8810_REG_PLLK2, | ||
565 | (pll_param->pll_frac >> NAU8810_PLLK2_SFT) & | ||
566 | NAU8810_PLLK2_MASK); | ||
567 | regmap_write(map, NAU8810_REG_PLLK3, | ||
568 | pll_param->pll_frac & NAU8810_PLLK3_MASK); | ||
569 | regmap_update_bits(map, NAU8810_REG_CLOCK, NAU8810_MCLKSEL_MASK, | ||
570 | pll_param->mclk_scaler << NAU8810_MCLKSEL_SFT); | ||
571 | regmap_update_bits(map, NAU8810_REG_CLOCK, | ||
572 | NAU8810_CLKM_MASK, NAU8810_CLKM_PLL); | ||
573 | |||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static int nau8810_set_dai_fmt(struct snd_soc_dai *codec_dai, | ||
578 | unsigned int fmt) | ||
579 | { | ||
580 | struct snd_soc_codec *codec = codec_dai->codec; | ||
581 | struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec); | ||
582 | u16 ctrl1_val = 0, ctrl2_val = 0; | ||
583 | |||
584 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
585 | case SND_SOC_DAIFMT_CBM_CFM: | ||
586 | ctrl2_val |= NAU8810_CLKIO_MASTER; | ||
587 | break; | ||
588 | case SND_SOC_DAIFMT_CBS_CFS: | ||
589 | break; | ||
590 | default: | ||
591 | return -EINVAL; | ||
592 | } | ||
593 | |||
594 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
595 | case SND_SOC_DAIFMT_I2S: | ||
596 | ctrl1_val |= NAU8810_AIFMT_I2S; | ||
597 | break; | ||
598 | case SND_SOC_DAIFMT_RIGHT_J: | ||
599 | break; | ||
600 | case SND_SOC_DAIFMT_LEFT_J: | ||
601 | ctrl1_val |= NAU8810_AIFMT_LEFT; | ||
602 | break; | ||
603 | case SND_SOC_DAIFMT_DSP_A: | ||
604 | ctrl1_val |= NAU8810_AIFMT_PCM_A; | ||
605 | break; | ||
606 | default: | ||
607 | return -EINVAL; | ||
608 | } | ||
609 | |||
610 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
611 | case SND_SOC_DAIFMT_NB_NF: | ||
612 | break; | ||
613 | case SND_SOC_DAIFMT_IB_IF: | ||
614 | ctrl1_val |= NAU8810_BCLKP_IB | NAU8810_FSP_IF; | ||
615 | break; | ||
616 | case SND_SOC_DAIFMT_IB_NF: | ||
617 | ctrl1_val |= NAU8810_BCLKP_IB; | ||
618 | break; | ||
619 | case SND_SOC_DAIFMT_NB_IF: | ||
620 | ctrl1_val |= NAU8810_FSP_IF; | ||
621 | break; | ||
622 | default: | ||
623 | return -EINVAL; | ||
624 | } | ||
625 | |||
626 | regmap_update_bits(nau8810->regmap, NAU8810_REG_IFACE, | ||
627 | NAU8810_AIFMT_MASK | NAU8810_FSP_IF | | ||
628 | NAU8810_BCLKP_IB, ctrl1_val); | ||
629 | regmap_update_bits(nau8810->regmap, NAU8810_REG_CLOCK, | ||
630 | NAU8810_CLKIO_MASK, ctrl2_val); | ||
631 | |||
632 | return 0; | ||
633 | } | ||
634 | |||
635 | static int nau8810_mclk_clkdiv(struct nau8810 *nau8810, int rate) | ||
636 | { | ||
637 | int i, sclk, imclk = rate * 256, div = 0; | ||
638 | |||
639 | if (!nau8810->sysclk) { | ||
640 | dev_err(nau8810->dev, "Make mclk div configuration fail because of invalid system clock\n"); | ||
641 | return -EINVAL; | ||
642 | } | ||
643 | |||
644 | /* Configure the master clock prescaler div to make system | ||
645 | * clock to approximate the internal master clock (IMCLK); | ||
646 | * and large or equal to IMCLK. | ||
647 | */ | ||
648 | for (i = 1; i < ARRAY_SIZE(nau8810_mclk_scaler); i++) { | ||
649 | sclk = (nau8810->sysclk * 10) / | ||
650 | nau8810_mclk_scaler[i]; | ||
651 | if (sclk < imclk) | ||
652 | break; | ||
653 | div = i; | ||
654 | } | ||
655 | dev_dbg(nau8810->dev, | ||
656 | "master clock prescaler %x for fs %d\n", div, rate); | ||
657 | |||
658 | /* master clock from MCLK and disable PLL */ | ||
659 | regmap_update_bits(nau8810->regmap, NAU8810_REG_CLOCK, | ||
660 | NAU8810_MCLKSEL_MASK, (div << NAU8810_MCLKSEL_SFT)); | ||
661 | regmap_update_bits(nau8810->regmap, NAU8810_REG_CLOCK, | ||
662 | NAU8810_CLKM_MASK, NAU8810_CLKM_MCLK); | ||
663 | |||
664 | return 0; | ||
665 | } | ||
666 | |||
667 | static int nau8810_pcm_hw_params(struct snd_pcm_substream *substream, | ||
668 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | ||
669 | { | ||
670 | struct snd_soc_codec *codec = dai->codec; | ||
671 | struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec); | ||
672 | int val_len = 0, val_rate = 0, ret = 0; | ||
673 | |||
674 | switch (params_width(params)) { | ||
675 | case 16: | ||
676 | break; | ||
677 | case 20: | ||
678 | val_len |= NAU8810_WLEN_20; | ||
679 | break; | ||
680 | case 24: | ||
681 | val_len |= NAU8810_WLEN_24; | ||
682 | break; | ||
683 | case 32: | ||
684 | val_len |= NAU8810_WLEN_32; | ||
685 | break; | ||
686 | } | ||
687 | |||
688 | switch (params_rate(params)) { | ||
689 | case 8000: | ||
690 | val_rate |= NAU8810_SMPLR_8K; | ||
691 | break; | ||
692 | case 11025: | ||
693 | val_rate |= NAU8810_SMPLR_12K; | ||
694 | break; | ||
695 | case 16000: | ||
696 | val_rate |= NAU8810_SMPLR_16K; | ||
697 | break; | ||
698 | case 22050: | ||
699 | val_rate |= NAU8810_SMPLR_24K; | ||
700 | break; | ||
701 | case 32000: | ||
702 | val_rate |= NAU8810_SMPLR_32K; | ||
703 | break; | ||
704 | case 44100: | ||
705 | case 48000: | ||
706 | break; | ||
707 | } | ||
708 | |||
709 | regmap_update_bits(nau8810->regmap, NAU8810_REG_IFACE, | ||
710 | NAU8810_WLEN_MASK, val_len); | ||
711 | regmap_update_bits(nau8810->regmap, NAU8810_REG_SMPLR, | ||
712 | NAU8810_SMPLR_MASK, val_rate); | ||
713 | |||
714 | /* If the master clock is from MCLK, provide the runtime FS for driver | ||
715 | * to get the master clock prescaler configuration. | ||
716 | */ | ||
717 | if (nau8810->clk_id == NAU8810_SCLK_MCLK) { | ||
718 | ret = nau8810_mclk_clkdiv(nau8810, params_rate(params)); | ||
719 | if (ret < 0) | ||
720 | dev_err(nau8810->dev, "MCLK div configuration fail\n"); | ||
721 | } | ||
722 | |||
723 | return ret; | ||
724 | } | ||
725 | |||
726 | static int nau8810_set_bias_level(struct snd_soc_codec *codec, | ||
727 | enum snd_soc_bias_level level) | ||
728 | { | ||
729 | struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec); | ||
730 | struct regmap *map = nau8810->regmap; | ||
731 | |||
732 | switch (level) { | ||
733 | case SND_SOC_BIAS_ON: | ||
734 | case SND_SOC_BIAS_PREPARE: | ||
735 | regmap_update_bits(map, NAU8810_REG_POWER1, | ||
736 | NAU8810_REFIMP_MASK, NAU8810_REFIMP_80K); | ||
737 | break; | ||
738 | |||
739 | case SND_SOC_BIAS_STANDBY: | ||
740 | regmap_update_bits(map, NAU8810_REG_POWER1, | ||
741 | NAU8810_IOBUF_EN | NAU8810_ABIAS_EN, | ||
742 | NAU8810_IOBUF_EN | NAU8810_ABIAS_EN); | ||
743 | |||
744 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { | ||
745 | regcache_sync(map); | ||
746 | regmap_update_bits(map, NAU8810_REG_POWER1, | ||
747 | NAU8810_REFIMP_MASK, NAU8810_REFIMP_3K); | ||
748 | mdelay(100); | ||
749 | } | ||
750 | regmap_update_bits(map, NAU8810_REG_POWER1, | ||
751 | NAU8810_REFIMP_MASK, NAU8810_REFIMP_300K); | ||
752 | break; | ||
753 | |||
754 | case SND_SOC_BIAS_OFF: | ||
755 | regmap_write(map, NAU8810_REG_POWER1, 0); | ||
756 | regmap_write(map, NAU8810_REG_POWER2, 0); | ||
757 | regmap_write(map, NAU8810_REG_POWER3, 0); | ||
758 | break; | ||
759 | } | ||
760 | |||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | |||
765 | #define NAU8810_RATES (SNDRV_PCM_RATE_8000_48000) | ||
766 | |||
767 | #define NAU8810_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
768 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) | ||
769 | |||
770 | static const struct snd_soc_dai_ops nau8810_ops = { | ||
771 | .hw_params = nau8810_pcm_hw_params, | ||
772 | .set_fmt = nau8810_set_dai_fmt, | ||
773 | .set_sysclk = nau8810_set_sysclk, | ||
774 | .set_pll = nau8810_set_pll, | ||
775 | }; | ||
776 | |||
777 | static struct snd_soc_dai_driver nau8810_dai = { | ||
778 | .name = "nau8810-hifi", | ||
779 | .playback = { | ||
780 | .stream_name = "Playback", | ||
781 | .channels_min = 1, | ||
782 | .channels_max = 2, /* Only 1 channel of data */ | ||
783 | .rates = NAU8810_RATES, | ||
784 | .formats = NAU8810_FORMATS, | ||
785 | }, | ||
786 | .capture = { | ||
787 | .stream_name = "Capture", | ||
788 | .channels_min = 1, | ||
789 | .channels_max = 2, /* Only 1 channel of data */ | ||
790 | .rates = NAU8810_RATES, | ||
791 | .formats = NAU8810_FORMATS, | ||
792 | }, | ||
793 | .ops = &nau8810_ops, | ||
794 | .symmetric_rates = 1, | ||
795 | }; | ||
796 | |||
797 | static const struct regmap_config nau8810_regmap_config = { | ||
798 | .reg_bits = 7, | ||
799 | .val_bits = 9, | ||
800 | |||
801 | .max_register = NAU8810_REG_MAX, | ||
802 | .readable_reg = nau8810_readable_reg, | ||
803 | .writeable_reg = nau8810_writeable_reg, | ||
804 | .volatile_reg = nau8810_volatile_reg, | ||
805 | |||
806 | .cache_type = REGCACHE_RBTREE, | ||
807 | .reg_defaults = nau8810_reg_defaults, | ||
808 | .num_reg_defaults = ARRAY_SIZE(nau8810_reg_defaults), | ||
809 | }; | ||
810 | |||
811 | static struct snd_soc_codec_driver nau8810_codec_driver = { | ||
812 | .set_bias_level = nau8810_set_bias_level, | ||
813 | .suspend_bias_off = true, | ||
814 | |||
815 | .component_driver = { | ||
816 | .controls = nau8810_snd_controls, | ||
817 | .num_controls = ARRAY_SIZE(nau8810_snd_controls), | ||
818 | .dapm_widgets = nau8810_dapm_widgets, | ||
819 | .num_dapm_widgets = ARRAY_SIZE(nau8810_dapm_widgets), | ||
820 | .dapm_routes = nau8810_dapm_routes, | ||
821 | .num_dapm_routes = ARRAY_SIZE(nau8810_dapm_routes), | ||
822 | }, | ||
823 | }; | ||
824 | |||
825 | static int nau8810_i2c_probe(struct i2c_client *i2c, | ||
826 | const struct i2c_device_id *id) | ||
827 | { | ||
828 | struct device *dev = &i2c->dev; | ||
829 | struct nau8810 *nau8810 = dev_get_platdata(dev); | ||
830 | |||
831 | if (!nau8810) { | ||
832 | nau8810 = devm_kzalloc(dev, sizeof(*nau8810), GFP_KERNEL); | ||
833 | if (!nau8810) | ||
834 | return -ENOMEM; | ||
835 | } | ||
836 | i2c_set_clientdata(i2c, nau8810); | ||
837 | |||
838 | nau8810->regmap = devm_regmap_init_i2c(i2c, &nau8810_regmap_config); | ||
839 | if (IS_ERR(nau8810->regmap)) | ||
840 | return PTR_ERR(nau8810->regmap); | ||
841 | nau8810->dev = dev; | ||
842 | |||
843 | regmap_write(nau8810->regmap, NAU8810_REG_RESET, 0x00); | ||
844 | |||
845 | return snd_soc_register_codec(dev, | ||
846 | &nau8810_codec_driver, &nau8810_dai, 1); | ||
847 | } | ||
848 | |||
849 | static int nau8810_i2c_remove(struct i2c_client *client) | ||
850 | { | ||
851 | snd_soc_unregister_codec(&client->dev); | ||
852 | |||
853 | return 0; | ||
854 | } | ||
855 | |||
856 | static const struct i2c_device_id nau8810_i2c_id[] = { | ||
857 | { "nau8810", 0 }, | ||
858 | { } | ||
859 | }; | ||
860 | MODULE_DEVICE_TABLE(i2c, nau8810_i2c_id); | ||
861 | |||
862 | #ifdef CONFIG_OF | ||
863 | static const struct of_device_id nau8810_of_match[] = { | ||
864 | { .compatible = "nuvoton,nau8810", }, | ||
865 | { } | ||
866 | }; | ||
867 | MODULE_DEVICE_TABLE(of, nau8810_of_match); | ||
868 | #endif | ||
869 | |||
870 | static struct i2c_driver nau8810_i2c_driver = { | ||
871 | .driver = { | ||
872 | .name = "nau8810", | ||
873 | .of_match_table = of_match_ptr(nau8810_of_match), | ||
874 | }, | ||
875 | .probe = nau8810_i2c_probe, | ||
876 | .remove = nau8810_i2c_remove, | ||
877 | .id_table = nau8810_i2c_id, | ||
878 | }; | ||
879 | |||
880 | module_i2c_driver(nau8810_i2c_driver); | ||
881 | |||
882 | MODULE_DESCRIPTION("ASoC NAU8810 driver"); | ||
883 | MODULE_AUTHOR("David Lin <ctlin0@nuvoton.com>"); | ||
884 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/nau8810.h b/sound/soc/codecs/nau8810.h new file mode 100644 index 000000000000..df882658ca91 --- /dev/null +++ b/sound/soc/codecs/nau8810.h | |||
@@ -0,0 +1,281 @@ | |||
1 | /* | ||
2 | * NAU8810 ALSA SoC audio driver | ||
3 | * | ||
4 | * Copyright 2016 Nuvoton Technology Corp. | ||
5 | * Author: David Lin <ctlin0@nuvoton.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 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef __NAU8810_H__ | ||
13 | #define __NAU8810_H__ | ||
14 | |||
15 | #define NAU8810_REG_RESET 0x00 | ||
16 | #define NAU8810_REG_POWER1 0x01 | ||
17 | #define NAU8810_REG_POWER2 0x02 | ||
18 | #define NAU8810_REG_POWER3 0x03 | ||
19 | #define NAU8810_REG_IFACE 0x04 | ||
20 | #define NAU8810_REG_COMP 0x05 | ||
21 | #define NAU8810_REG_CLOCK 0x06 | ||
22 | #define NAU8810_REG_SMPLR 0x07 | ||
23 | #define NAU8810_REG_DAC 0x0A | ||
24 | #define NAU8810_REG_DACGAIN 0x0B | ||
25 | #define NAU8810_REG_ADC 0x0E | ||
26 | #define NAU8810_REG_ADCGAIN 0x0F | ||
27 | #define NAU8810_REG_EQ1 0x12 | ||
28 | #define NAU8810_REG_EQ2 0x13 | ||
29 | #define NAU8810_REG_EQ3 0x14 | ||
30 | #define NAU8810_REG_EQ4 0x15 | ||
31 | #define NAU8810_REG_EQ5 0x16 | ||
32 | #define NAU8810_REG_DACLIM1 0x18 | ||
33 | #define NAU8810_REG_DACLIM2 0x19 | ||
34 | #define NAU8810_REG_NOTCH1 0x1B | ||
35 | #define NAU8810_REG_NOTCH2 0x1C | ||
36 | #define NAU8810_REG_NOTCH3 0x1D | ||
37 | #define NAU8810_REG_NOTCH4 0x1E | ||
38 | #define NAU8810_REG_ALC1 0x20 | ||
39 | #define NAU8810_REG_ALC2 0x21 | ||
40 | #define NAU8810_REG_ALC3 0x22 | ||
41 | #define NAU8810_REG_NOISEGATE 0x23 | ||
42 | #define NAU8810_REG_PLLN 0x24 | ||
43 | #define NAU8810_REG_PLLK1 0x25 | ||
44 | #define NAU8810_REG_PLLK2 0x26 | ||
45 | #define NAU8810_REG_PLLK3 0x27 | ||
46 | #define NAU8810_REG_ATTEN 0x28 | ||
47 | #define NAU8810_REG_INPUT_SIGNAL 0x2C | ||
48 | #define NAU8810_REG_PGAGAIN 0x2D | ||
49 | #define NAU8810_REG_ADCBOOST 0x2F | ||
50 | #define NAU8810_REG_OUTPUT 0x31 | ||
51 | #define NAU8810_REG_SPKMIX 0x32 | ||
52 | #define NAU8810_REG_SPKGAIN 0x36 | ||
53 | #define NAU8810_REG_MONOMIX 0x38 | ||
54 | #define NAU8810_REG_POWER4 0x3A | ||
55 | #define NAU8810_REG_TSLOTCTL1 0x3B | ||
56 | #define NAU8810_REG_TSLOTCTL2 0x3C | ||
57 | #define NAU8810_REG_DEVICE_REVID 0x3E | ||
58 | #define NAU8810_REG_I2C_DEVICEID 0x3F | ||
59 | #define NAU8810_REG_ADDITIONID 0x40 | ||
60 | #define NAU8810_REG_RESERVE 0x41 | ||
61 | #define NAU8810_REG_OUTCTL 0x45 | ||
62 | #define NAU8810_REG_ALC1ENHAN1 0x46 | ||
63 | #define NAU8810_REG_ALC1ENHAN2 0x47 | ||
64 | #define NAU8810_REG_MISCCTL 0x49 | ||
65 | #define NAU8810_REG_OUTTIEOFF 0x4B | ||
66 | #define NAU8810_REG_AGCP2POUT 0x4C | ||
67 | #define NAU8810_REG_AGCPOUT 0x4D | ||
68 | #define NAU8810_REG_AMTCTL 0x4E | ||
69 | #define NAU8810_REG_OUTTIEOFFMAN 0x4F | ||
70 | #define NAU8810_REG_MAX NAU8810_REG_OUTTIEOFFMAN | ||
71 | |||
72 | |||
73 | /* NAU8810_REG_POWER1 (0x1) */ | ||
74 | #define NAU8810_DCBUF_EN (0x1 << 8) | ||
75 | #define NAU8810_PLL_EN_SFT 5 | ||
76 | #define NAU8810_MICBIAS_EN_SFT 4 | ||
77 | #define NAU8810_ABIAS_EN (0x1 << 3) | ||
78 | #define NAU8810_IOBUF_EN (0x1 << 2) | ||
79 | #define NAU8810_REFIMP_MASK 0x3 | ||
80 | #define NAU8810_REFIMP_DIS 0x0 | ||
81 | #define NAU8810_REFIMP_80K 0x1 | ||
82 | #define NAU8810_REFIMP_300K 0x2 | ||
83 | #define NAU8810_REFIMP_3K 0x3 | ||
84 | |||
85 | /* NAU8810_REG_POWER2 (0x2) */ | ||
86 | #define NAU8810_BST_EN_SFT 4 | ||
87 | #define NAU8810_PGA_EN_SFT 2 | ||
88 | #define NAU8810_ADC_EN_SFT 0 | ||
89 | |||
90 | /* NAU8810_REG_POWER3 (0x3) */ | ||
91 | #define NAU8810_DAC_EN_SFT 0 | ||
92 | #define NAU8810_SPKMX_EN_SFT 2 | ||
93 | #define NAU8810_MOUTMX_EN_SFT 3 | ||
94 | #define NAU8810_PSPK_EN_SFT 5 | ||
95 | #define NAU8810_NSPK_EN_SFT 6 | ||
96 | #define NAU8810_MOUT_EN_SFT 7 | ||
97 | |||
98 | /* NAU8810_REG_IFACE (0x4) */ | ||
99 | #define NAU8810_AIFMT_SFT 3 | ||
100 | #define NAU8810_AIFMT_MASK (0x3 << NAU8810_AIFMT_SFT) | ||
101 | #define NAU8810_AIFMT_RIGHT (0x0 << NAU8810_AIFMT_SFT) | ||
102 | #define NAU8810_AIFMT_LEFT (0x1 << NAU8810_AIFMT_SFT) | ||
103 | #define NAU8810_AIFMT_I2S (0x2 << NAU8810_AIFMT_SFT) | ||
104 | #define NAU8810_AIFMT_PCM_A (0x3 << NAU8810_AIFMT_SFT) | ||
105 | #define NAU8810_WLEN_SFT 5 | ||
106 | #define NAU8810_WLEN_MASK (0x3 << NAU8810_WLEN_SFT) | ||
107 | #define NAU8810_WLEN_16 (0x0 << NAU8810_WLEN_SFT) | ||
108 | #define NAU8810_WLEN_20 (0x1 << NAU8810_WLEN_SFT) | ||
109 | #define NAU8810_WLEN_24 (0x2 << NAU8810_WLEN_SFT) | ||
110 | #define NAU8810_WLEN_32 (0x3 << NAU8810_WLEN_SFT) | ||
111 | #define NAU8810_FSP_IF (0x1 << 7) | ||
112 | #define NAU8810_BCLKP_IB (0x1 << 8) | ||
113 | |||
114 | /* NAU8810_REG_COMP (0x5) */ | ||
115 | #define NAU8810_ADDAP_SFT 0 | ||
116 | #define NAU8810_ADCCM_SFT 1 | ||
117 | #define NAU8810_DACCM_SFT 3 | ||
118 | |||
119 | /* NAU8810_REG_CLOCK (0x6) */ | ||
120 | #define NAU8810_CLKIO_MASK 0x1 | ||
121 | #define NAU8810_CLKIO_SLAVE 0x0 | ||
122 | #define NAU8810_CLKIO_MASTER 0x1 | ||
123 | #define NAU8810_BCLKSEL_SFT 2 | ||
124 | #define NAU8810_BCLKSEL_MASK (0x7 << NAU8810_BCLKSEL_SFT) | ||
125 | #define NAU8810_BCLKDIV_1 (0x0 << NAU8810_BCLKSEL_SFT) | ||
126 | #define NAU8810_BCLKDIV_2 (0x1 << NAU8810_BCLKSEL_SFT) | ||
127 | #define NAU8810_BCLKDIV_4 (0x2 << NAU8810_BCLKSEL_SFT) | ||
128 | #define NAU8810_BCLKDIV_8 (0x3 << NAU8810_BCLKSEL_SFT) | ||
129 | #define NAU8810_BCLKDIV_16 (0x4 << NAU8810_BCLKSEL_SFT) | ||
130 | #define NAU8810_BCLKDIV_32 (0x5 << NAU8810_BCLKSEL_SFT) | ||
131 | #define NAU8810_MCLKSEL_SFT 5 | ||
132 | #define NAU8810_MCLKSEL_MASK (0x7 << NAU8810_MCLKSEL_SFT) | ||
133 | #define NAU8810_CLKM_SFT 8 | ||
134 | #define NAU8810_CLKM_MASK (0x1 << NAU8810_CLKM_SFT) | ||
135 | #define NAU8810_CLKM_MCLK (0x0 << NAU8810_CLKM_SFT) | ||
136 | #define NAU8810_CLKM_PLL (0x1 << NAU8810_CLKM_SFT) | ||
137 | |||
138 | /* NAU8810_REG_SMPLR (0x7) */ | ||
139 | #define NAU8810_SMPLR_SFT 1 | ||
140 | #define NAU8810_SMPLR_MASK (0x7 << NAU8810_SMPLR_SFT) | ||
141 | #define NAU8810_SMPLR_48K (0x0 << NAU8810_SMPLR_SFT) | ||
142 | #define NAU8810_SMPLR_32K (0x1 << NAU8810_SMPLR_SFT) | ||
143 | #define NAU8810_SMPLR_24K (0x2 << NAU8810_SMPLR_SFT) | ||
144 | #define NAU8810_SMPLR_16K (0x3 << NAU8810_SMPLR_SFT) | ||
145 | #define NAU8810_SMPLR_12K (0x4 << NAU8810_SMPLR_SFT) | ||
146 | #define NAU8810_SMPLR_8K (0x5 << NAU8810_SMPLR_SFT) | ||
147 | |||
148 | /* NAU8810_REG_DAC (0xA) */ | ||
149 | #define NAU8810_DACPL_SFT 0 | ||
150 | #define NAU8810_DACOS_SFT 3 | ||
151 | #define NAU8810_DEEMP_SFT 4 | ||
152 | |||
153 | /* NAU8810_REG_DACGAIN (0xB) */ | ||
154 | #define NAU8810_DACGAIN_SFT 0 | ||
155 | |||
156 | /* NAU8810_REG_ADC (0xE) */ | ||
157 | #define NAU8810_ADCPL_SFT 0 | ||
158 | #define NAU8810_ADCOS_SFT 3 | ||
159 | #define NAU8810_HPF_SFT 4 | ||
160 | #define NAU8810_HPFEN_SFT 8 | ||
161 | |||
162 | /* NAU8810_REG_ADCGAIN (0xF) */ | ||
163 | #define NAU8810_ADCGAIN_SFT 0 | ||
164 | |||
165 | /* NAU8810_REG_EQ1 (0x12) */ | ||
166 | #define NAU8810_EQ1GC_SFT 0 | ||
167 | #define NAU8810_EQ1CF_SFT 5 | ||
168 | #define NAU8810_EQM_SFT 8 | ||
169 | |||
170 | /* NAU8810_REG_EQ2 (0x13) */ | ||
171 | #define NAU8810_EQ2GC_SFT 0 | ||
172 | #define NAU8810_EQ2CF_SFT 5 | ||
173 | #define NAU8810_EQ2BW_SFT 8 | ||
174 | |||
175 | /* NAU8810_REG_EQ3 (0x14) */ | ||
176 | #define NAU8810_EQ3GC_SFT 0 | ||
177 | #define NAU8810_EQ3CF_SFT 5 | ||
178 | #define NAU8810_EQ3BW_SFT 8 | ||
179 | |||
180 | /* NAU8810_REG_EQ4 (0x15) */ | ||
181 | #define NAU8810_EQ4GC_SFT 0 | ||
182 | #define NAU8810_EQ4CF_SFT 5 | ||
183 | #define NAU8810_EQ4BW_SFT 8 | ||
184 | |||
185 | /* NAU8810_REG_EQ5 (0x16) */ | ||
186 | #define NAU8810_EQ5GC_SFT 0 | ||
187 | #define NAU8810_EQ5CF_SFT 5 | ||
188 | |||
189 | /* NAU8810_REG_DACLIM1 (0x18) */ | ||
190 | #define NAU8810_DACLIMATK_SFT 0 | ||
191 | #define NAU8810_DACLIMDCY_SFT 4 | ||
192 | #define NAU8810_DACLIMEN_SFT 8 | ||
193 | |||
194 | /* NAU8810_REG_DACLIM2 (0x19) */ | ||
195 | #define NAU8810_DACLIMBST_SFT 0 | ||
196 | #define NAU8810_DACLIMTHL_SFT 4 | ||
197 | |||
198 | /* NAU8810_REG_ALC1 (0x20) */ | ||
199 | #define NAU8810_ALCMINGAIN_SFT 0 | ||
200 | #define NAU8810_ALCMXGAIN_SFT 3 | ||
201 | #define NAU8810_ALCEN_SFT 8 | ||
202 | |||
203 | /* NAU8810_REG_ALC2 (0x21) */ | ||
204 | #define NAU8810_ALCSL_SFT 0 | ||
205 | #define NAU8810_ALCHT_SFT 4 | ||
206 | #define NAU8810_ALCZC_SFT 8 | ||
207 | |||
208 | /* NAU8810_REG_ALC3 (0x22) */ | ||
209 | #define NAU8810_ALCATK_SFT 0 | ||
210 | #define NAU8810_ALCDCY_SFT 4 | ||
211 | #define NAU8810_ALCM_SFT 8 | ||
212 | |||
213 | /* NAU8810_REG_NOISEGATE (0x23) */ | ||
214 | #define NAU8810_ALCNTH_SFT 0 | ||
215 | #define NAU8810_ALCNEN_SFT 3 | ||
216 | |||
217 | /* NAU8810_REG_PLLN (0x24) */ | ||
218 | #define NAU8810_PLLN_MASK 0xF | ||
219 | #define NAU8810_PLLMCLK_DIV2 (0x1 << 4) | ||
220 | |||
221 | /* NAU8810_REG_PLLK1 (0x25) */ | ||
222 | #define NAU8810_PLLK1_SFT 18 | ||
223 | #define NAU8810_PLLK1_MASK 0x3F | ||
224 | |||
225 | /* NAU8810_REG_PLLK2 (0x26) */ | ||
226 | #define NAU8810_PLLK2_SFT 9 | ||
227 | #define NAU8810_PLLK2_MASK 0x1FF | ||
228 | |||
229 | /* NAU8810_REG_PLLK3 (0x27) */ | ||
230 | #define NAU8810_PLLK3_MASK 0x1FF | ||
231 | |||
232 | /* NAU8810_REG_INPUT_SIGNAL (0x2C) */ | ||
233 | #define NAU8810_PMICPGA_SFT 0 | ||
234 | #define NAU8810_NMICPGA_SFT 1 | ||
235 | |||
236 | /* NAU8810_REG_PGAGAIN (0x2D) */ | ||
237 | #define NAU8810_PGAGAIN_SFT 0 | ||
238 | #define NAU8810_PGAMT_SFT 6 | ||
239 | #define NAU8810_PGAZC_SFT 7 | ||
240 | |||
241 | /* NAU8810_REG_ADCBOOST (0x2F) */ | ||
242 | #define NAU8810_PMICBSTGAIN_SFT 4 | ||
243 | #define NAU8810_PGABST_SFT 8 | ||
244 | |||
245 | /* NAU8810_REG_SPKMIX (0x32) */ | ||
246 | #define NAU8810_DACSPK_SFT 0 | ||
247 | #define NAU8810_BYPSPK_SFT 1 | ||
248 | |||
249 | /* NAU8810_REG_SPKGAIN (0x36) */ | ||
250 | #define NAU8810_SPKGAIN_SFT 0 | ||
251 | #define NAU8810_SPKMT_SFT 6 | ||
252 | #define NAU8810_SPKZC_SFT 7 | ||
253 | |||
254 | /* NAU8810_REG_MONOMIX (0x38) */ | ||
255 | #define NAU8810_DACMOUT_SFT 0 | ||
256 | #define NAU8810_BYPMOUT_SFT 1 | ||
257 | #define NAU8810_MOUTMXMT_SFT 6 | ||
258 | |||
259 | |||
260 | /* System Clock Source */ | ||
261 | enum { | ||
262 | NAU8810_SCLK_MCLK, | ||
263 | NAU8810_SCLK_PLL, | ||
264 | }; | ||
265 | |||
266 | struct nau8810_pll { | ||
267 | int pre_factor; | ||
268 | int mclk_scaler; | ||
269 | int pll_frac; | ||
270 | int pll_int; | ||
271 | }; | ||
272 | |||
273 | struct nau8810 { | ||
274 | struct device *dev; | ||
275 | struct regmap *regmap; | ||
276 | struct nau8810_pll pll; | ||
277 | int sysclk; | ||
278 | int clk_id; | ||
279 | }; | ||
280 | |||
281 | #endif | ||
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c index 2e59a85e360b..e643be91d762 100644 --- a/sound/soc/codecs/nau8825.c +++ b/sound/soc/codecs/nau8825.c | |||
@@ -1907,7 +1907,7 @@ static int nau8825_calc_fll_param(unsigned int fll_in, unsigned int fs, | |||
1907 | /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional | 1907 | /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional |
1908 | * input based on FDCO, FREF and FLL ratio. | 1908 | * input based on FDCO, FREF and FLL ratio. |
1909 | */ | 1909 | */ |
1910 | fvco = div_u64(fvco << 16, fref * fll_param->ratio); | 1910 | fvco = div_u64(fvco_max << 16, fref * fll_param->ratio); |
1911 | fll_param->fll_int = (fvco >> 16) & 0x3FF; | 1911 | fll_param->fll_int = (fvco >> 16) & 0x3FF; |
1912 | fll_param->fll_frac = fvco & 0xFFFF; | 1912 | fll_param->fll_frac = fvco & 0xFFFF; |
1913 | return 0; | 1913 | return 0; |
@@ -2256,12 +2256,14 @@ static struct snd_soc_codec_driver nau8825_codec_driver = { | |||
2256 | .suspend = nau8825_suspend, | 2256 | .suspend = nau8825_suspend, |
2257 | .resume = nau8825_resume, | 2257 | .resume = nau8825_resume, |
2258 | 2258 | ||
2259 | .controls = nau8825_controls, | 2259 | .component_driver = { |
2260 | .num_controls = ARRAY_SIZE(nau8825_controls), | 2260 | .controls = nau8825_controls, |
2261 | .dapm_widgets = nau8825_dapm_widgets, | 2261 | .num_controls = ARRAY_SIZE(nau8825_controls), |
2262 | .num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets), | 2262 | .dapm_widgets = nau8825_dapm_widgets, |
2263 | .dapm_routes = nau8825_dapm_routes, | 2263 | .num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets), |
2264 | .num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes), | 2264 | .dapm_routes = nau8825_dapm_routes, |
2265 | .num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes), | ||
2266 | }, | ||
2265 | }; | 2267 | }; |
2266 | 2268 | ||
2267 | static void nau8825_reset_chip(struct regmap *regmap) | 2269 | static void nau8825_reset_chip(struct regmap *regmap) |
diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c index 33e1fc2d1598..0b14efab6280 100644 --- a/sound/soc/codecs/pcm1681.c +++ b/sound/soc/codecs/pcm1681.c | |||
@@ -289,12 +289,14 @@ static const struct regmap_config pcm1681_regmap = { | |||
289 | }; | 289 | }; |
290 | 290 | ||
291 | static struct snd_soc_codec_driver soc_codec_dev_pcm1681 = { | 291 | static struct snd_soc_codec_driver soc_codec_dev_pcm1681 = { |
292 | .controls = pcm1681_controls, | 292 | .component_driver = { |
293 | .num_controls = ARRAY_SIZE(pcm1681_controls), | 293 | .controls = pcm1681_controls, |
294 | .dapm_widgets = pcm1681_dapm_widgets, | 294 | .num_controls = ARRAY_SIZE(pcm1681_controls), |
295 | .num_dapm_widgets = ARRAY_SIZE(pcm1681_dapm_widgets), | 295 | .dapm_widgets = pcm1681_dapm_widgets, |
296 | .dapm_routes = pcm1681_dapm_routes, | 296 | .num_dapm_widgets = ARRAY_SIZE(pcm1681_dapm_widgets), |
297 | .num_dapm_routes = ARRAY_SIZE(pcm1681_dapm_routes), | 297 | .dapm_routes = pcm1681_dapm_routes, |
298 | .num_dapm_routes = ARRAY_SIZE(pcm1681_dapm_routes), | ||
299 | }, | ||
298 | }; | 300 | }; |
299 | 301 | ||
300 | static const struct i2c_device_id pcm1681_i2c_id[] = { | 302 | static const struct i2c_device_id pcm1681_i2c_id[] = { |
diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c index 88fbdd184aa0..b813a154ddd9 100644 --- a/sound/soc/codecs/pcm179x.c +++ b/sound/soc/codecs/pcm179x.c | |||
@@ -206,12 +206,14 @@ const struct regmap_config pcm179x_regmap_config = { | |||
206 | EXPORT_SYMBOL_GPL(pcm179x_regmap_config); | 206 | EXPORT_SYMBOL_GPL(pcm179x_regmap_config); |
207 | 207 | ||
208 | static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { | 208 | static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { |
209 | .controls = pcm179x_controls, | 209 | .component_driver = { |
210 | .num_controls = ARRAY_SIZE(pcm179x_controls), | 210 | .controls = pcm179x_controls, |
211 | .dapm_widgets = pcm179x_dapm_widgets, | 211 | .num_controls = ARRAY_SIZE(pcm179x_controls), |
212 | .num_dapm_widgets = ARRAY_SIZE(pcm179x_dapm_widgets), | 212 | .dapm_widgets = pcm179x_dapm_widgets, |
213 | .dapm_routes = pcm179x_dapm_routes, | 213 | .num_dapm_widgets = ARRAY_SIZE(pcm179x_dapm_widgets), |
214 | .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes), | 214 | .dapm_routes = pcm179x_dapm_routes, |
215 | .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes), | ||
216 | }, | ||
215 | }; | 217 | }; |
216 | 218 | ||
217 | int pcm179x_common_init(struct device *dev, struct regmap *regmap) | 219 | int pcm179x_common_init(struct device *dev, struct regmap *regmap) |
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c index 8fb445f33f6f..708af05486f6 100644 --- a/sound/soc/codecs/pcm3008.c +++ b/sound/soc/codecs/pcm3008.c | |||
@@ -99,10 +99,12 @@ static struct snd_soc_dai_driver pcm3008_dai = { | |||
99 | }; | 99 | }; |
100 | 100 | ||
101 | static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = { | 101 | static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = { |
102 | .dapm_widgets = pcm3008_dapm_widgets, | 102 | .component_driver = { |
103 | .num_dapm_widgets = ARRAY_SIZE(pcm3008_dapm_widgets), | 103 | .dapm_widgets = pcm3008_dapm_widgets, |
104 | .dapm_routes = pcm3008_dapm_routes, | 104 | .num_dapm_widgets = ARRAY_SIZE(pcm3008_dapm_widgets), |
105 | .num_dapm_routes = ARRAY_SIZE(pcm3008_dapm_routes), | 105 | .dapm_routes = pcm3008_dapm_routes, |
106 | .num_dapm_routes = ARRAY_SIZE(pcm3008_dapm_routes), | ||
107 | }, | ||
106 | }; | 108 | }; |
107 | 109 | ||
108 | static int pcm3008_codec_probe(struct platform_device *pdev) | 110 | static int pcm3008_codec_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index 992a77edcd5d..39bc02d5bc5d 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c | |||
@@ -599,12 +599,14 @@ EXPORT_SYMBOL_GPL(pcm3168a_regmap); | |||
599 | 599 | ||
600 | static const struct snd_soc_codec_driver pcm3168a_driver = { | 600 | static const struct snd_soc_codec_driver pcm3168a_driver = { |
601 | .idle_bias_off = true, | 601 | .idle_bias_off = true, |
602 | .controls = pcm3168a_snd_controls, | 602 | .component_driver = { |
603 | .num_controls = ARRAY_SIZE(pcm3168a_snd_controls), | 603 | .controls = pcm3168a_snd_controls, |
604 | .dapm_widgets = pcm3168a_dapm_widgets, | 604 | .num_controls = ARRAY_SIZE(pcm3168a_snd_controls), |
605 | .num_dapm_widgets = ARRAY_SIZE(pcm3168a_dapm_widgets), | 605 | .dapm_widgets = pcm3168a_dapm_widgets, |
606 | .dapm_routes = pcm3168a_dapm_routes, | 606 | .num_dapm_widgets = ARRAY_SIZE(pcm3168a_dapm_widgets), |
607 | .num_dapm_routes = ARRAY_SIZE(pcm3168a_dapm_routes) | 607 | .dapm_routes = pcm3168a_dapm_routes, |
608 | .num_dapm_routes = ARRAY_SIZE(pcm3168a_dapm_routes) | ||
609 | }, | ||
608 | }; | 610 | }; |
609 | 611 | ||
610 | int pcm3168a_probe(struct device *dev, struct regmap *regmap) | 612 | int pcm3168a_probe(struct device *dev, struct regmap *regmap) |
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index 047c48953a20..72b19e62f626 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c | |||
@@ -1348,12 +1348,14 @@ static struct snd_soc_codec_driver pcm512x_codec_driver = { | |||
1348 | .set_bias_level = pcm512x_set_bias_level, | 1348 | .set_bias_level = pcm512x_set_bias_level, |
1349 | .idle_bias_off = true, | 1349 | .idle_bias_off = true, |
1350 | 1350 | ||
1351 | .controls = pcm512x_controls, | 1351 | .component_driver = { |
1352 | .num_controls = ARRAY_SIZE(pcm512x_controls), | 1352 | .controls = pcm512x_controls, |
1353 | .dapm_widgets = pcm512x_dapm_widgets, | 1353 | .num_controls = ARRAY_SIZE(pcm512x_controls), |
1354 | .num_dapm_widgets = ARRAY_SIZE(pcm512x_dapm_widgets), | 1354 | .dapm_widgets = pcm512x_dapm_widgets, |
1355 | .dapm_routes = pcm512x_dapm_routes, | 1355 | .num_dapm_widgets = ARRAY_SIZE(pcm512x_dapm_widgets), |
1356 | .num_dapm_routes = ARRAY_SIZE(pcm512x_dapm_routes), | 1356 | .dapm_routes = pcm512x_dapm_routes, |
1357 | .num_dapm_routes = ARRAY_SIZE(pcm512x_dapm_routes), | ||
1358 | }, | ||
1357 | }; | 1359 | }; |
1358 | 1360 | ||
1359 | static const struct regmap_range_cfg pcm512x_range = { | 1361 | static const struct regmap_range_cfg pcm512x_range = { |
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 74c0e4eb3788..9c365a7f758d 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c | |||
@@ -1053,12 +1053,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt286 = { | |||
1053 | .resume = rt286_resume, | 1053 | .resume = rt286_resume, |
1054 | .set_bias_level = rt286_set_bias_level, | 1054 | .set_bias_level = rt286_set_bias_level, |
1055 | .idle_bias_off = true, | 1055 | .idle_bias_off = true, |
1056 | .controls = rt286_snd_controls, | 1056 | .component_driver = { |
1057 | .num_controls = ARRAY_SIZE(rt286_snd_controls), | 1057 | .controls = rt286_snd_controls, |
1058 | .dapm_widgets = rt286_dapm_widgets, | 1058 | .num_controls = ARRAY_SIZE(rt286_snd_controls), |
1059 | .num_dapm_widgets = ARRAY_SIZE(rt286_dapm_widgets), | 1059 | .dapm_widgets = rt286_dapm_widgets, |
1060 | .dapm_routes = rt286_dapm_routes, | 1060 | .num_dapm_widgets = ARRAY_SIZE(rt286_dapm_widgets), |
1061 | .num_dapm_routes = ARRAY_SIZE(rt286_dapm_routes), | 1061 | .dapm_routes = rt286_dapm_routes, |
1062 | .num_dapm_routes = ARRAY_SIZE(rt286_dapm_routes), | ||
1063 | }, | ||
1062 | }; | 1064 | }; |
1063 | 1065 | ||
1064 | static const struct regmap_config rt286_regmap = { | 1066 | static const struct regmap_config rt286_regmap = { |
diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index f80cfe4d2ef2..55558643166f 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c | |||
@@ -1095,12 +1095,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt298 = { | |||
1095 | .resume = rt298_resume, | 1095 | .resume = rt298_resume, |
1096 | .set_bias_level = rt298_set_bias_level, | 1096 | .set_bias_level = rt298_set_bias_level, |
1097 | .idle_bias_off = true, | 1097 | .idle_bias_off = true, |
1098 | .controls = rt298_snd_controls, | 1098 | .component_driver = { |
1099 | .num_controls = ARRAY_SIZE(rt298_snd_controls), | 1099 | .controls = rt298_snd_controls, |
1100 | .dapm_widgets = rt298_dapm_widgets, | 1100 | .num_controls = ARRAY_SIZE(rt298_snd_controls), |
1101 | .num_dapm_widgets = ARRAY_SIZE(rt298_dapm_widgets), | 1101 | .dapm_widgets = rt298_dapm_widgets, |
1102 | .dapm_routes = rt298_dapm_routes, | 1102 | .num_dapm_widgets = ARRAY_SIZE(rt298_dapm_widgets), |
1103 | .num_dapm_routes = ARRAY_SIZE(rt298_dapm_routes), | 1103 | .dapm_routes = rt298_dapm_routes, |
1104 | .num_dapm_routes = ARRAY_SIZE(rt298_dapm_routes), | ||
1105 | }, | ||
1104 | }; | 1106 | }; |
1105 | 1107 | ||
1106 | static const struct regmap_config rt298_regmap = { | 1108 | static const struct regmap_config rt298_regmap = { |
diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c index 77ff8ebe6dfb..09103aab0cb2 100644 --- a/sound/soc/codecs/rt5514-spi.c +++ b/sound/soc/codecs/rt5514-spi.c | |||
@@ -236,7 +236,7 @@ static snd_pcm_uframes_t rt5514_spi_pcm_pointer( | |||
236 | return bytes_to_frames(runtime, rt5514_dsp->dma_offset); | 236 | return bytes_to_frames(runtime, rt5514_dsp->dma_offset); |
237 | } | 237 | } |
238 | 238 | ||
239 | static struct snd_pcm_ops rt5514_spi_pcm_ops = { | 239 | static const struct snd_pcm_ops rt5514_spi_pcm_ops = { |
240 | .open = rt5514_spi_pcm_open, | 240 | .open = rt5514_spi_pcm_open, |
241 | .hw_params = rt5514_spi_hw_params, | 241 | .hw_params = rt5514_spi_hw_params, |
242 | .hw_free = rt5514_spi_hw_free, | 242 | .hw_free = rt5514_spi_hw_free, |
diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c index 7162f05101d9..f24b7cfd3a89 100644 --- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c | |||
@@ -278,7 +278,7 @@ static const DECLARE_TLV_DB_RANGE(bst_tlv, | |||
278 | 8, 8, TLV_DB_SCALE_ITEM(1700, 0, 0) | 278 | 8, 8, TLV_DB_SCALE_ITEM(1700, 0, 0) |
279 | ); | 279 | ); |
280 | 280 | ||
281 | static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); | 281 | static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1725, 75, 0); |
282 | 282 | ||
283 | static int rt5514_dsp_voice_wake_up_get(struct snd_kcontrol *kcontrol, | 283 | static int rt5514_dsp_voice_wake_up_get(struct snd_kcontrol *kcontrol, |
284 | struct snd_ctl_elem_value *ucontrol) | 284 | struct snd_ctl_elem_value *ucontrol) |
@@ -352,10 +352,10 @@ static const struct snd_kcontrol_new rt5514_snd_controls[] = { | |||
352 | SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST, | 352 | SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST, |
353 | RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv), | 353 | RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv), |
354 | SOC_DOUBLE_R_TLV("ADC1 Capture Volume", RT5514_DOWNFILTER0_CTRL1, | 354 | SOC_DOUBLE_R_TLV("ADC1 Capture Volume", RT5514_DOWNFILTER0_CTRL1, |
355 | RT5514_DOWNFILTER0_CTRL2, RT5514_AD_GAIN_SFT, 127, 0, | 355 | RT5514_DOWNFILTER0_CTRL2, RT5514_AD_GAIN_SFT, 63, 0, |
356 | adc_vol_tlv), | 356 | adc_vol_tlv), |
357 | SOC_DOUBLE_R_TLV("ADC2 Capture Volume", RT5514_DOWNFILTER1_CTRL1, | 357 | SOC_DOUBLE_R_TLV("ADC2 Capture Volume", RT5514_DOWNFILTER1_CTRL1, |
358 | RT5514_DOWNFILTER1_CTRL2, RT5514_AD_GAIN_SFT, 127, 0, | 358 | RT5514_DOWNFILTER1_CTRL2, RT5514_AD_GAIN_SFT, 63, 0, |
359 | adc_vol_tlv), | 359 | adc_vol_tlv), |
360 | SOC_SINGLE_EXT("DSP Voice Wake Up", SND_SOC_NOPM, 0, 1, 0, | 360 | SOC_SINGLE_EXT("DSP Voice Wake Up", SND_SOC_NOPM, 0, 1, 0, |
361 | rt5514_dsp_voice_wake_up_get, rt5514_dsp_voice_wake_up_put), | 361 | rt5514_dsp_voice_wake_up_get, rt5514_dsp_voice_wake_up_put), |
@@ -1023,12 +1023,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5514 = { | |||
1023 | .probe = rt5514_probe, | 1023 | .probe = rt5514_probe, |
1024 | .idle_bias_off = true, | 1024 | .idle_bias_off = true, |
1025 | .set_bias_level = rt5514_set_bias_level, | 1025 | .set_bias_level = rt5514_set_bias_level, |
1026 | .controls = rt5514_snd_controls, | 1026 | .component_driver = { |
1027 | .num_controls = ARRAY_SIZE(rt5514_snd_controls), | 1027 | .controls = rt5514_snd_controls, |
1028 | .dapm_widgets = rt5514_dapm_widgets, | 1028 | .num_controls = ARRAY_SIZE(rt5514_snd_controls), |
1029 | .num_dapm_widgets = ARRAY_SIZE(rt5514_dapm_widgets), | 1029 | .dapm_widgets = rt5514_dapm_widgets, |
1030 | .dapm_routes = rt5514_dapm_routes, | 1030 | .num_dapm_widgets = ARRAY_SIZE(rt5514_dapm_widgets), |
1031 | .num_dapm_routes = ARRAY_SIZE(rt5514_dapm_routes), | 1031 | .dapm_routes = rt5514_dapm_routes, |
1032 | .num_dapm_routes = ARRAY_SIZE(rt5514_dapm_routes), | ||
1033 | }, | ||
1032 | }; | 1034 | }; |
1033 | 1035 | ||
1034 | static const struct regmap_config rt5514_i2c_regmap = { | 1036 | static const struct regmap_config rt5514_i2c_regmap = { |
diff --git a/sound/soc/codecs/rt5514.h b/sound/soc/codecs/rt5514.h index 68883c68e999..229de0e2c88c 100644 --- a/sound/soc/codecs/rt5514.h +++ b/sound/soc/codecs/rt5514.h | |||
@@ -196,8 +196,8 @@ | |||
196 | #define RT5514_AD_AD_MIX_BIT 10 | 196 | #define RT5514_AD_AD_MIX_BIT 10 |
197 | #define RT5514_AD_AD_MUTE (0x1 << 7) | 197 | #define RT5514_AD_AD_MUTE (0x1 << 7) |
198 | #define RT5514_AD_AD_MUTE_BIT 7 | 198 | #define RT5514_AD_AD_MUTE_BIT 7 |
199 | #define RT5514_AD_GAIN_MASK (0x7f << 0) | 199 | #define RT5514_AD_GAIN_MASK (0x3f << 1) |
200 | #define RT5514_AD_GAIN_SFT 0 | 200 | #define RT5514_AD_GAIN_SFT 1 |
201 | 201 | ||
202 | /* RT5514_ANA_CTRL_MICBST (0x2220) */ | 202 | /* RT5514_ANA_CTRL_MICBST (0x2220) */ |
203 | #define RT5514_SEL_BSTL_MASK (0xf << 4) | 203 | #define RT5514_SEL_BSTL_MASK (0xf << 4) |
diff --git a/sound/soc/codecs/rt5616.c b/sound/soc/codecs/rt5616.c index f527b5b2817b..d1f273b24991 100644 --- a/sound/soc/codecs/rt5616.c +++ b/sound/soc/codecs/rt5616.c | |||
@@ -294,8 +294,7 @@ static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); | |||
294 | static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); | 294 | static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); |
295 | 295 | ||
296 | /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ | 296 | /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ |
297 | static unsigned int bst_tlv[] = { | 297 | static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(bst_tlv, |
298 | TLV_DB_RANGE_HEAD(7), | ||
299 | 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), | 298 | 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), |
300 | 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), | 299 | 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), |
301 | 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), | 300 | 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), |
@@ -303,7 +302,7 @@ static unsigned int bst_tlv[] = { | |||
303 | 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0), | 302 | 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0), |
304 | 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0), | 303 | 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0), |
305 | 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0), | 304 | 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0), |
306 | }; | 305 | ); |
307 | 306 | ||
308 | static const struct snd_kcontrol_new rt5616_snd_controls[] = { | 307 | static const struct snd_kcontrol_new rt5616_snd_controls[] = { |
309 | /* Headphone Output Volume */ | 308 | /* Headphone Output Volume */ |
@@ -1267,14 +1266,14 @@ static int rt5616_resume(struct snd_soc_codec *codec) | |||
1267 | #define RT5616_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | 1266 | #define RT5616_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ |
1268 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) | 1267 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) |
1269 | 1268 | ||
1270 | struct snd_soc_dai_ops rt5616_aif_dai_ops = { | 1269 | static struct snd_soc_dai_ops rt5616_aif_dai_ops = { |
1271 | .hw_params = rt5616_hw_params, | 1270 | .hw_params = rt5616_hw_params, |
1272 | .set_fmt = rt5616_set_dai_fmt, | 1271 | .set_fmt = rt5616_set_dai_fmt, |
1273 | .set_sysclk = rt5616_set_dai_sysclk, | 1272 | .set_sysclk = rt5616_set_dai_sysclk, |
1274 | .set_pll = rt5616_set_dai_pll, | 1273 | .set_pll = rt5616_set_dai_pll, |
1275 | }; | 1274 | }; |
1276 | 1275 | ||
1277 | struct snd_soc_dai_driver rt5616_dai[] = { | 1276 | static struct snd_soc_dai_driver rt5616_dai[] = { |
1278 | { | 1277 | { |
1279 | .name = "rt5616-aif1", | 1278 | .name = "rt5616-aif1", |
1280 | .id = RT5616_AIF1, | 1279 | .id = RT5616_AIF1, |
@@ -1302,12 +1301,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5616 = { | |||
1302 | .resume = rt5616_resume, | 1301 | .resume = rt5616_resume, |
1303 | .set_bias_level = rt5616_set_bias_level, | 1302 | .set_bias_level = rt5616_set_bias_level, |
1304 | .idle_bias_off = true, | 1303 | .idle_bias_off = true, |
1305 | .controls = rt5616_snd_controls, | 1304 | .component_driver = { |
1306 | .num_controls = ARRAY_SIZE(rt5616_snd_controls), | 1305 | .controls = rt5616_snd_controls, |
1307 | .dapm_widgets = rt5616_dapm_widgets, | 1306 | .num_controls = ARRAY_SIZE(rt5616_snd_controls), |
1308 | .num_dapm_widgets = ARRAY_SIZE(rt5616_dapm_widgets), | 1307 | .dapm_widgets = rt5616_dapm_widgets, |
1309 | .dapm_routes = rt5616_dapm_routes, | 1308 | .num_dapm_widgets = ARRAY_SIZE(rt5616_dapm_widgets), |
1310 | .num_dapm_routes = ARRAY_SIZE(rt5616_dapm_routes), | 1309 | .dapm_routes = rt5616_dapm_routes, |
1310 | .num_dapm_routes = ARRAY_SIZE(rt5616_dapm_routes), | ||
1311 | }, | ||
1311 | }; | 1312 | }; |
1312 | 1313 | ||
1313 | static const struct regmap_config rt5616_regmap = { | 1314 | static const struct regmap_config rt5616_regmap = { |
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 1be2bab7dee3..0e418089c053 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c | |||
@@ -1657,12 +1657,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5631 = { | |||
1657 | .probe = rt5631_probe, | 1657 | .probe = rt5631_probe, |
1658 | .set_bias_level = rt5631_set_bias_level, | 1658 | .set_bias_level = rt5631_set_bias_level, |
1659 | .suspend_bias_off = true, | 1659 | .suspend_bias_off = true, |
1660 | .controls = rt5631_snd_controls, | 1660 | .component_driver = { |
1661 | .num_controls = ARRAY_SIZE(rt5631_snd_controls), | 1661 | .controls = rt5631_snd_controls, |
1662 | .dapm_widgets = rt5631_dapm_widgets, | 1662 | .num_controls = ARRAY_SIZE(rt5631_snd_controls), |
1663 | .num_dapm_widgets = ARRAY_SIZE(rt5631_dapm_widgets), | 1663 | .dapm_widgets = rt5631_dapm_widgets, |
1664 | .dapm_routes = rt5631_dapm_routes, | 1664 | .num_dapm_widgets = ARRAY_SIZE(rt5631_dapm_widgets), |
1665 | .num_dapm_routes = ARRAY_SIZE(rt5631_dapm_routes), | 1665 | .dapm_routes = rt5631_dapm_routes, |
1666 | .num_dapm_routes = ARRAY_SIZE(rt5631_dapm_routes), | ||
1667 | }, | ||
1666 | }; | 1668 | }; |
1667 | 1669 | ||
1668 | static const struct i2c_device_id rt5631_i2c_id[] = { | 1670 | static const struct i2c_device_id rt5631_i2c_id[] = { |
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 09e8988bbb2d..3cc1135fc2cd 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c | |||
@@ -1870,6 +1870,9 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai, | |||
1870 | case RT5640_SCLK_S_PLL1: | 1870 | case RT5640_SCLK_S_PLL1: |
1871 | reg_val |= RT5640_SCLK_SRC_PLL1; | 1871 | reg_val |= RT5640_SCLK_SRC_PLL1; |
1872 | break; | 1872 | break; |
1873 | case RT5640_SCLK_S_RCCLK: | ||
1874 | reg_val |= RT5640_SCLK_SRC_RCCLK; | ||
1875 | break; | ||
1873 | default: | 1876 | default: |
1874 | dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); | 1877 | dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); |
1875 | return -EINVAL; | 1878 | return -EINVAL; |
@@ -2261,12 +2264,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5640 = { | |||
2261 | .resume = rt5640_resume, | 2264 | .resume = rt5640_resume, |
2262 | .set_bias_level = rt5640_set_bias_level, | 2265 | .set_bias_level = rt5640_set_bias_level, |
2263 | .idle_bias_off = true, | 2266 | .idle_bias_off = true, |
2264 | .controls = rt5640_snd_controls, | 2267 | .component_driver = { |
2265 | .num_controls = ARRAY_SIZE(rt5640_snd_controls), | 2268 | .controls = rt5640_snd_controls, |
2266 | .dapm_widgets = rt5640_dapm_widgets, | 2269 | .num_controls = ARRAY_SIZE(rt5640_snd_controls), |
2267 | .num_dapm_widgets = ARRAY_SIZE(rt5640_dapm_widgets), | 2270 | .dapm_widgets = rt5640_dapm_widgets, |
2268 | .dapm_routes = rt5640_dapm_routes, | 2271 | .num_dapm_widgets = ARRAY_SIZE(rt5640_dapm_widgets), |
2269 | .num_dapm_routes = ARRAY_SIZE(rt5640_dapm_routes), | 2272 | .dapm_routes = rt5640_dapm_routes, |
2273 | .num_dapm_routes = ARRAY_SIZE(rt5640_dapm_routes), | ||
2274 | }, | ||
2270 | }; | 2275 | }; |
2271 | 2276 | ||
2272 | static const struct regmap_config rt5640_regmap = { | 2277 | static const struct regmap_config rt5640_regmap = { |
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h index 58b664b06c16..90c88711c72a 100644 --- a/sound/soc/codecs/rt5640.h +++ b/sound/soc/codecs/rt5640.h | |||
@@ -984,6 +984,7 @@ | |||
984 | #define RT5640_SCLK_SRC_SFT 14 | 984 | #define RT5640_SCLK_SRC_SFT 14 |
985 | #define RT5640_SCLK_SRC_MCLK (0x0 << 14) | 985 | #define RT5640_SCLK_SRC_MCLK (0x0 << 14) |
986 | #define RT5640_SCLK_SRC_PLL1 (0x1 << 14) | 986 | #define RT5640_SCLK_SRC_PLL1 (0x1 << 14) |
987 | #define RT5640_SCLK_SRC_RCCLK (0x2 << 14) | ||
987 | #define RT5640_PLL1_SRC_MASK (0x3 << 12) | 988 | #define RT5640_PLL1_SRC_MASK (0x3 << 12) |
988 | #define RT5640_PLL1_SRC_SFT 12 | 989 | #define RT5640_PLL1_SRC_SFT 12 |
989 | #define RT5640_PLL1_SRC_MCLK (0x0 << 12) | 990 | #define RT5640_PLL1_SRC_MCLK (0x0 << 12) |
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 490bfe661346..10c2a564a715 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c | |||
@@ -3484,12 +3484,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5645 = { | |||
3484 | .resume = rt5645_resume, | 3484 | .resume = rt5645_resume, |
3485 | .set_bias_level = rt5645_set_bias_level, | 3485 | .set_bias_level = rt5645_set_bias_level, |
3486 | .idle_bias_off = true, | 3486 | .idle_bias_off = true, |
3487 | .controls = rt5645_snd_controls, | 3487 | .component_driver = { |
3488 | .num_controls = ARRAY_SIZE(rt5645_snd_controls), | 3488 | .controls = rt5645_snd_controls, |
3489 | .dapm_widgets = rt5645_dapm_widgets, | 3489 | .num_controls = ARRAY_SIZE(rt5645_snd_controls), |
3490 | .num_dapm_widgets = ARRAY_SIZE(rt5645_dapm_widgets), | 3490 | .dapm_widgets = rt5645_dapm_widgets, |
3491 | .dapm_routes = rt5645_dapm_routes, | 3491 | .num_dapm_widgets = ARRAY_SIZE(rt5645_dapm_widgets), |
3492 | .num_dapm_routes = ARRAY_SIZE(rt5645_dapm_routes), | 3492 | .dapm_routes = rt5645_dapm_routes, |
3493 | .num_dapm_routes = ARRAY_SIZE(rt5645_dapm_routes), | ||
3494 | }, | ||
3493 | }; | 3495 | }; |
3494 | 3496 | ||
3495 | static const struct regmap_config rt5645_regmap = { | 3497 | static const struct regmap_config rt5645_regmap = { |
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index 7a6197042423..f5d34153e21f 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c | |||
@@ -1712,12 +1712,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5651 = { | |||
1712 | .resume = rt5651_resume, | 1712 | .resume = rt5651_resume, |
1713 | .set_bias_level = rt5651_set_bias_level, | 1713 | .set_bias_level = rt5651_set_bias_level, |
1714 | .idle_bias_off = true, | 1714 | .idle_bias_off = true, |
1715 | .controls = rt5651_snd_controls, | 1715 | .component_driver = { |
1716 | .num_controls = ARRAY_SIZE(rt5651_snd_controls), | 1716 | .controls = rt5651_snd_controls, |
1717 | .dapm_widgets = rt5651_dapm_widgets, | 1717 | .num_controls = ARRAY_SIZE(rt5651_snd_controls), |
1718 | .num_dapm_widgets = ARRAY_SIZE(rt5651_dapm_widgets), | 1718 | .dapm_widgets = rt5651_dapm_widgets, |
1719 | .dapm_routes = rt5651_dapm_routes, | 1719 | .num_dapm_widgets = ARRAY_SIZE(rt5651_dapm_widgets), |
1720 | .num_dapm_routes = ARRAY_SIZE(rt5651_dapm_routes), | 1720 | .dapm_routes = rt5651_dapm_routes, |
1721 | .num_dapm_routes = ARRAY_SIZE(rt5651_dapm_routes), | ||
1722 | }, | ||
1721 | }; | 1723 | }; |
1722 | 1724 | ||
1723 | static const struct regmap_config rt5651_regmap = { | 1725 | static const struct regmap_config rt5651_regmap = { |
diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c index 1b30914c2d91..db54550aed60 100644 --- a/sound/soc/codecs/rt5659.c +++ b/sound/soc/codecs/rt5659.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/clk.h> | ||
12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
13 | #include <linux/moduleparam.h> | 14 | #include <linux/moduleparam.h> |
14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
@@ -3565,7 +3566,9 @@ static int rt5659_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) | |||
3565 | static int rt5659_set_bias_level(struct snd_soc_codec *codec, | 3566 | static int rt5659_set_bias_level(struct snd_soc_codec *codec, |
3566 | enum snd_soc_bias_level level) | 3567 | enum snd_soc_bias_level level) |
3567 | { | 3568 | { |
3569 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | ||
3568 | struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec); | 3570 | struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec); |
3571 | int ret; | ||
3569 | 3572 | ||
3570 | switch (level) { | 3573 | switch (level) { |
3571 | case SND_SOC_BIAS_PREPARE: | 3574 | case SND_SOC_BIAS_PREPARE: |
@@ -3582,6 +3585,17 @@ static int rt5659_set_bias_level(struct snd_soc_codec *codec, | |||
3582 | RT5659_PWR_FV1 | RT5659_PWR_FV2); | 3585 | RT5659_PWR_FV1 | RT5659_PWR_FV2); |
3583 | break; | 3586 | break; |
3584 | 3587 | ||
3588 | case SND_SOC_BIAS_STANDBY: | ||
3589 | if (dapm->bias_level == SND_SOC_BIAS_OFF) { | ||
3590 | ret = clk_prepare_enable(rt5659->mclk); | ||
3591 | if (ret) { | ||
3592 | dev_err(codec->dev, | ||
3593 | "failed to enable MCLK: %d\n", ret); | ||
3594 | return ret; | ||
3595 | } | ||
3596 | } | ||
3597 | break; | ||
3598 | |||
3585 | case SND_SOC_BIAS_OFF: | 3599 | case SND_SOC_BIAS_OFF: |
3586 | regmap_update_bits(rt5659->regmap, RT5659_PWR_DIG_1, | 3600 | regmap_update_bits(rt5659->regmap, RT5659_PWR_DIG_1, |
3587 | RT5659_PWR_LDO, 0); | 3601 | RT5659_PWR_LDO, 0); |
@@ -3591,6 +3605,7 @@ static int rt5659_set_bias_level(struct snd_soc_codec *codec, | |||
3591 | RT5659_PWR_MB | RT5659_PWR_VREF2); | 3605 | RT5659_PWR_MB | RT5659_PWR_VREF2); |
3592 | regmap_update_bits(rt5659->regmap, RT5659_DIG_MISC, | 3606 | regmap_update_bits(rt5659->regmap, RT5659_DIG_MISC, |
3593 | RT5659_DIG_GATE_CTRL, 0); | 3607 | RT5659_DIG_GATE_CTRL, 0); |
3608 | clk_disable_unprepare(rt5659->mclk); | ||
3594 | break; | 3609 | break; |
3595 | 3610 | ||
3596 | default: | 3611 | default: |
@@ -3722,12 +3737,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5659 = { | |||
3722 | .resume = rt5659_resume, | 3737 | .resume = rt5659_resume, |
3723 | .set_bias_level = rt5659_set_bias_level, | 3738 | .set_bias_level = rt5659_set_bias_level, |
3724 | .idle_bias_off = true, | 3739 | .idle_bias_off = true, |
3725 | .controls = rt5659_snd_controls, | 3740 | .component_driver = { |
3726 | .num_controls = ARRAY_SIZE(rt5659_snd_controls), | 3741 | .controls = rt5659_snd_controls, |
3727 | .dapm_widgets = rt5659_dapm_widgets, | 3742 | .num_controls = ARRAY_SIZE(rt5659_snd_controls), |
3728 | .num_dapm_widgets = ARRAY_SIZE(rt5659_dapm_widgets), | 3743 | .dapm_widgets = rt5659_dapm_widgets, |
3729 | .dapm_routes = rt5659_dapm_routes, | 3744 | .num_dapm_widgets = ARRAY_SIZE(rt5659_dapm_widgets), |
3730 | .num_dapm_routes = ARRAY_SIZE(rt5659_dapm_routes), | 3745 | .dapm_routes = rt5659_dapm_routes, |
3746 | .num_dapm_routes = ARRAY_SIZE(rt5659_dapm_routes), | ||
3747 | }, | ||
3731 | }; | 3748 | }; |
3732 | 3749 | ||
3733 | 3750 | ||
@@ -4020,6 +4037,15 @@ static int rt5659_i2c_probe(struct i2c_client *i2c, | |||
4020 | 4037 | ||
4021 | regmap_write(rt5659->regmap, RT5659_RESET, 0); | 4038 | regmap_write(rt5659->regmap, RT5659_RESET, 0); |
4022 | 4039 | ||
4040 | /* Check if MCLK provided */ | ||
4041 | rt5659->mclk = devm_clk_get(&i2c->dev, "mclk"); | ||
4042 | if (IS_ERR(rt5659->mclk)) { | ||
4043 | if (PTR_ERR(rt5659->mclk) != -ENOENT) | ||
4044 | return PTR_ERR(rt5659->mclk); | ||
4045 | /* Otherwise mark the mclk pointer to NULL */ | ||
4046 | rt5659->mclk = NULL; | ||
4047 | } | ||
4048 | |||
4023 | rt5659_calibrate(rt5659); | 4049 | rt5659_calibrate(rt5659); |
4024 | 4050 | ||
4025 | /* line in diff mode*/ | 4051 | /* line in diff mode*/ |
@@ -4163,6 +4189,9 @@ static int rt5659_i2c_probe(struct i2c_client *i2c, | |||
4163 | if (ret) | 4189 | if (ret) |
4164 | dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret); | 4190 | dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret); |
4165 | 4191 | ||
4192 | /* Enable IRQ output for GPIO1 pin any way */ | ||
4193 | regmap_update_bits(rt5659->regmap, RT5659_GPIO_CTRL_1, | ||
4194 | RT5659_GP1_PIN_MASK, RT5659_GP1_PIN_IRQ); | ||
4166 | } | 4195 | } |
4167 | 4196 | ||
4168 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5659, | 4197 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5659, |
diff --git a/sound/soc/codecs/rt5659.h b/sound/soc/codecs/rt5659.h index d31c9e5bcec8..8f1aeef08489 100644 --- a/sound/soc/codecs/rt5659.h +++ b/sound/soc/codecs/rt5659.h | |||
@@ -180,9 +180,9 @@ | |||
180 | #define RT5659_IRQ_CTRL_1 0x00b6 | 180 | #define RT5659_IRQ_CTRL_1 0x00b6 |
181 | #define RT5659_IRQ_CTRL_2 0x00b7 | 181 | #define RT5659_IRQ_CTRL_2 0x00b7 |
182 | #define RT5659_IRQ_CTRL_3 0x00b8 | 182 | #define RT5659_IRQ_CTRL_3 0x00b8 |
183 | #define RT5659_IRQ_CTRL_4 0x00b9 | 183 | #define RT5659_IRQ_CTRL_4 0x00ba |
184 | #define RT5659_IRQ_CTRL_5 0x00ba | 184 | #define RT5659_IRQ_CTRL_5 0x00bb |
185 | #define RT5659_IRQ_CTRL_6 0x00bb | 185 | #define RT5659_IRQ_CTRL_6 0x00bc |
186 | #define RT5659_INT_ST_1 0x00be | 186 | #define RT5659_INT_ST_1 0x00be |
187 | #define RT5659_INT_ST_2 0x00bf | 187 | #define RT5659_INT_ST_2 0x00bf |
188 | #define RT5659_GPIO_CTRL_1 0x00c0 | 188 | #define RT5659_GPIO_CTRL_1 0x00c0 |
@@ -1796,6 +1796,7 @@ struct rt5659_priv { | |||
1796 | struct gpio_desc *gpiod_reset; | 1796 | struct gpio_desc *gpiod_reset; |
1797 | struct snd_soc_jack *hs_jack; | 1797 | struct snd_soc_jack *hs_jack; |
1798 | struct delayed_work jack_detect_work; | 1798 | struct delayed_work jack_detect_work; |
1799 | struct clk *mclk; | ||
1799 | 1800 | ||
1800 | int sysclk; | 1801 | int sysclk; |
1801 | int sysclk_src; | 1802 | int sysclk_src; |
diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c new file mode 100644 index 000000000000..9f0933ced804 --- /dev/null +++ b/sound/soc/codecs/rt5660.c | |||
@@ -0,0 +1,1353 @@ | |||
1 | /* | ||
2 | * rt5660.c -- RT5660 ALSA SoC audio codec driver | ||
3 | * | ||
4 | * Copyright 2016 Realtek Semiconductor Corp. | ||
5 | * Author: Oder Chiou <oder_chiou@realtek.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 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/moduleparam.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/pm.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/regmap.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/of_gpio.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/spi/spi.h> | ||
24 | #include <linux/acpi.h> | ||
25 | #include <sound/core.h> | ||
26 | #include <sound/pcm.h> | ||
27 | #include <sound/pcm_params.h> | ||
28 | #include <sound/soc.h> | ||
29 | #include <sound/soc-dapm.h> | ||
30 | #include <sound/initval.h> | ||
31 | #include <sound/tlv.h> | ||
32 | |||
33 | #include "rl6231.h" | ||
34 | #include "rt5660.h" | ||
35 | |||
36 | #define RT5660_DEVICE_ID 0x6338 | ||
37 | |||
38 | #define RT5660_PR_RANGE_BASE (0xff + 1) | ||
39 | #define RT5660_PR_SPACING 0x100 | ||
40 | |||
41 | #define RT5660_PR_BASE (RT5660_PR_RANGE_BASE + (0 * RT5660_PR_SPACING)) | ||
42 | |||
43 | static const struct regmap_range_cfg rt5660_ranges[] = { | ||
44 | { .name = "PR", .range_min = RT5660_PR_BASE, | ||
45 | .range_max = RT5660_PR_BASE + 0xf3, | ||
46 | .selector_reg = RT5660_PRIV_INDEX, | ||
47 | .selector_mask = 0xff, | ||
48 | .selector_shift = 0x0, | ||
49 | .window_start = RT5660_PRIV_DATA, | ||
50 | .window_len = 0x1, }, | ||
51 | }; | ||
52 | |||
53 | static const struct reg_sequence rt5660_patch[] = { | ||
54 | { RT5660_ALC_PGA_CTRL2, 0x44c3 }, | ||
55 | { RT5660_PR_BASE + 0x3d, 0x2600 }, | ||
56 | }; | ||
57 | |||
58 | static const struct reg_default rt5660_reg[] = { | ||
59 | { 0x00, 0x0000 }, | ||
60 | { 0x01, 0xc800 }, | ||
61 | { 0x02, 0xc8c8 }, | ||
62 | { 0x0d, 0x1010 }, | ||
63 | { 0x0e, 0x1010 }, | ||
64 | { 0x19, 0xafaf }, | ||
65 | { 0x1c, 0x2f2f }, | ||
66 | { 0x1e, 0x0000 }, | ||
67 | { 0x27, 0x6060 }, | ||
68 | { 0x29, 0x8080 }, | ||
69 | { 0x2a, 0x4242 }, | ||
70 | { 0x2f, 0x0000 }, | ||
71 | { 0x3b, 0x0000 }, | ||
72 | { 0x3c, 0x007f }, | ||
73 | { 0x3d, 0x0000 }, | ||
74 | { 0x3e, 0x007f }, | ||
75 | { 0x45, 0xe000 }, | ||
76 | { 0x46, 0x003e }, | ||
77 | { 0x48, 0xf800 }, | ||
78 | { 0x4a, 0x0004 }, | ||
79 | { 0x4d, 0x0000 }, | ||
80 | { 0x4e, 0x0000 }, | ||
81 | { 0x4f, 0x01ff }, | ||
82 | { 0x50, 0x0000 }, | ||
83 | { 0x51, 0x0000 }, | ||
84 | { 0x52, 0x01ff }, | ||
85 | { 0x61, 0x0000 }, | ||
86 | { 0x62, 0x0000 }, | ||
87 | { 0x63, 0x00c0 }, | ||
88 | { 0x64, 0x0000 }, | ||
89 | { 0x65, 0x0000 }, | ||
90 | { 0x66, 0x0000 }, | ||
91 | { 0x70, 0x8000 }, | ||
92 | { 0x73, 0x7000 }, | ||
93 | { 0x74, 0x3c00 }, | ||
94 | { 0x75, 0x2800 }, | ||
95 | { 0x80, 0x0000 }, | ||
96 | { 0x81, 0x0000 }, | ||
97 | { 0x82, 0x0000 }, | ||
98 | { 0x8c, 0x0228 }, | ||
99 | { 0x8d, 0xa000 }, | ||
100 | { 0x8e, 0x0000 }, | ||
101 | { 0x92, 0x0000 }, | ||
102 | { 0x93, 0x3000 }, | ||
103 | { 0xa1, 0x0059 }, | ||
104 | { 0xa2, 0x0001 }, | ||
105 | { 0xa3, 0x5c80 }, | ||
106 | { 0xa4, 0x0146 }, | ||
107 | { 0xa5, 0x1f1f }, | ||
108 | { 0xa6, 0x78c6 }, | ||
109 | { 0xa7, 0xe5ec }, | ||
110 | { 0xa8, 0xba61 }, | ||
111 | { 0xa9, 0x3c78 }, | ||
112 | { 0xaa, 0x8ae2 }, | ||
113 | { 0xab, 0xe5ec }, | ||
114 | { 0xac, 0xc600 }, | ||
115 | { 0xad, 0xba61 }, | ||
116 | { 0xae, 0x17ed }, | ||
117 | { 0xb0, 0x2080 }, | ||
118 | { 0xb1, 0x0000 }, | ||
119 | { 0xb3, 0x001f }, | ||
120 | { 0xb4, 0x020c }, | ||
121 | { 0xb5, 0x1f00 }, | ||
122 | { 0xb6, 0x0000 }, | ||
123 | { 0xb7, 0x4000 }, | ||
124 | { 0xbb, 0x0000 }, | ||
125 | { 0xbd, 0x0000 }, | ||
126 | { 0xbe, 0x0000 }, | ||
127 | { 0xbf, 0x0100 }, | ||
128 | { 0xc0, 0x0000 }, | ||
129 | { 0xc2, 0x0000 }, | ||
130 | { 0xd3, 0xa220 }, | ||
131 | { 0xd9, 0x0809 }, | ||
132 | { 0xda, 0x0000 }, | ||
133 | { 0xe0, 0x8000 }, | ||
134 | { 0xe1, 0x0200 }, | ||
135 | { 0xe2, 0x8000 }, | ||
136 | { 0xe3, 0x0200 }, | ||
137 | { 0xe4, 0x0f20 }, | ||
138 | { 0xe5, 0x001f }, | ||
139 | { 0xe6, 0x020c }, | ||
140 | { 0xe7, 0x1f00 }, | ||
141 | { 0xe8, 0x0000 }, | ||
142 | { 0xe9, 0x4000 }, | ||
143 | { 0xea, 0x00a6 }, | ||
144 | { 0xeb, 0x04c3 }, | ||
145 | { 0xec, 0x27c8 }, | ||
146 | { 0xed, 0x7418 }, | ||
147 | { 0xee, 0xbf50 }, | ||
148 | { 0xef, 0x0045 }, | ||
149 | { 0xf0, 0x0007 }, | ||
150 | { 0xfa, 0x0000 }, | ||
151 | { 0xfd, 0x0000 }, | ||
152 | { 0xfe, 0x10ec }, | ||
153 | { 0xff, 0x6338 }, | ||
154 | }; | ||
155 | |||
156 | static bool rt5660_volatile_register(struct device *dev, unsigned int reg) | ||
157 | { | ||
158 | int i; | ||
159 | |||
160 | for (i = 0; i < ARRAY_SIZE(rt5660_ranges); i++) | ||
161 | if ((reg >= rt5660_ranges[i].window_start && | ||
162 | reg <= rt5660_ranges[i].window_start + | ||
163 | rt5660_ranges[i].window_len) || | ||
164 | (reg >= rt5660_ranges[i].range_min && | ||
165 | reg <= rt5660_ranges[i].range_max)) | ||
166 | return true; | ||
167 | |||
168 | switch (reg) { | ||
169 | case RT5660_RESET: | ||
170 | case RT5660_PRIV_DATA: | ||
171 | case RT5660_EQ_CTRL1: | ||
172 | case RT5660_IRQ_CTRL2: | ||
173 | case RT5660_INT_IRQ_ST: | ||
174 | case RT5660_VENDOR_ID: | ||
175 | case RT5660_VENDOR_ID1: | ||
176 | case RT5660_VENDOR_ID2: | ||
177 | return true; | ||
178 | default: | ||
179 | return false; | ||
180 | } | ||
181 | } | ||
182 | |||
183 | static bool rt5660_readable_register(struct device *dev, unsigned int reg) | ||
184 | { | ||
185 | int i; | ||
186 | |||
187 | for (i = 0; i < ARRAY_SIZE(rt5660_ranges); i++) | ||
188 | if ((reg >= rt5660_ranges[i].window_start && | ||
189 | reg <= rt5660_ranges[i].window_start + | ||
190 | rt5660_ranges[i].window_len) || | ||
191 | (reg >= rt5660_ranges[i].range_min && | ||
192 | reg <= rt5660_ranges[i].range_max)) | ||
193 | return true; | ||
194 | |||
195 | switch (reg) { | ||
196 | case RT5660_RESET: | ||
197 | case RT5660_SPK_VOL: | ||
198 | case RT5660_LOUT_VOL: | ||
199 | case RT5660_IN1_IN2: | ||
200 | case RT5660_IN3_IN4: | ||
201 | case RT5660_DAC1_DIG_VOL: | ||
202 | case RT5660_STO1_ADC_DIG_VOL: | ||
203 | case RT5660_ADC_BST_VOL1: | ||
204 | case RT5660_STO1_ADC_MIXER: | ||
205 | case RT5660_AD_DA_MIXER: | ||
206 | case RT5660_STO_DAC_MIXER: | ||
207 | case RT5660_DIG_INF1_DATA: | ||
208 | case RT5660_REC_L1_MIXER: | ||
209 | case RT5660_REC_L2_MIXER: | ||
210 | case RT5660_REC_R1_MIXER: | ||
211 | case RT5660_REC_R2_MIXER: | ||
212 | case RT5660_LOUT_MIXER: | ||
213 | case RT5660_SPK_MIXER: | ||
214 | case RT5660_SPO_MIXER: | ||
215 | case RT5660_SPO_CLSD_RATIO: | ||
216 | case RT5660_OUT_L_GAIN1: | ||
217 | case RT5660_OUT_L_GAIN2: | ||
218 | case RT5660_OUT_L1_MIXER: | ||
219 | case RT5660_OUT_R_GAIN1: | ||
220 | case RT5660_OUT_R_GAIN2: | ||
221 | case RT5660_OUT_R1_MIXER: | ||
222 | case RT5660_PWR_DIG1: | ||
223 | case RT5660_PWR_DIG2: | ||
224 | case RT5660_PWR_ANLG1: | ||
225 | case RT5660_PWR_ANLG2: | ||
226 | case RT5660_PWR_MIXER: | ||
227 | case RT5660_PWR_VOL: | ||
228 | case RT5660_PRIV_INDEX: | ||
229 | case RT5660_PRIV_DATA: | ||
230 | case RT5660_I2S1_SDP: | ||
231 | case RT5660_ADDA_CLK1: | ||
232 | case RT5660_ADDA_CLK2: | ||
233 | case RT5660_DMIC_CTRL1: | ||
234 | case RT5660_GLB_CLK: | ||
235 | case RT5660_PLL_CTRL1: | ||
236 | case RT5660_PLL_CTRL2: | ||
237 | case RT5660_CLSD_AMP_OC_CTRL: | ||
238 | case RT5660_CLSD_AMP_CTRL: | ||
239 | case RT5660_LOUT_AMP_CTRL: | ||
240 | case RT5660_SPK_AMP_SPKVDD: | ||
241 | case RT5660_MICBIAS: | ||
242 | case RT5660_CLSD_OUT_CTRL1: | ||
243 | case RT5660_CLSD_OUT_CTRL2: | ||
244 | case RT5660_DIPOLE_MIC_CTRL1: | ||
245 | case RT5660_DIPOLE_MIC_CTRL2: | ||
246 | case RT5660_DIPOLE_MIC_CTRL3: | ||
247 | case RT5660_DIPOLE_MIC_CTRL4: | ||
248 | case RT5660_DIPOLE_MIC_CTRL5: | ||
249 | case RT5660_DIPOLE_MIC_CTRL6: | ||
250 | case RT5660_DIPOLE_MIC_CTRL7: | ||
251 | case RT5660_DIPOLE_MIC_CTRL8: | ||
252 | case RT5660_DIPOLE_MIC_CTRL9: | ||
253 | case RT5660_DIPOLE_MIC_CTRL10: | ||
254 | case RT5660_DIPOLE_MIC_CTRL11: | ||
255 | case RT5660_DIPOLE_MIC_CTRL12: | ||
256 | case RT5660_EQ_CTRL1: | ||
257 | case RT5660_EQ_CTRL2: | ||
258 | case RT5660_DRC_AGC_CTRL1: | ||
259 | case RT5660_DRC_AGC_CTRL2: | ||
260 | case RT5660_DRC_AGC_CTRL3: | ||
261 | case RT5660_DRC_AGC_CTRL4: | ||
262 | case RT5660_DRC_AGC_CTRL5: | ||
263 | case RT5660_JD_CTRL: | ||
264 | case RT5660_IRQ_CTRL1: | ||
265 | case RT5660_IRQ_CTRL2: | ||
266 | case RT5660_INT_IRQ_ST: | ||
267 | case RT5660_GPIO_CTRL1: | ||
268 | case RT5660_GPIO_CTRL2: | ||
269 | case RT5660_WIND_FILTER_CTRL1: | ||
270 | case RT5660_SV_ZCD1: | ||
271 | case RT5660_SV_ZCD2: | ||
272 | case RT5660_DRC1_LM_CTRL1: | ||
273 | case RT5660_DRC1_LM_CTRL2: | ||
274 | case RT5660_DRC2_LM_CTRL1: | ||
275 | case RT5660_DRC2_LM_CTRL2: | ||
276 | case RT5660_MULTI_DRC_CTRL: | ||
277 | case RT5660_DRC2_CTRL1: | ||
278 | case RT5660_DRC2_CTRL2: | ||
279 | case RT5660_DRC2_CTRL3: | ||
280 | case RT5660_DRC2_CTRL4: | ||
281 | case RT5660_DRC2_CTRL5: | ||
282 | case RT5660_ALC_PGA_CTRL1: | ||
283 | case RT5660_ALC_PGA_CTRL2: | ||
284 | case RT5660_ALC_PGA_CTRL3: | ||
285 | case RT5660_ALC_PGA_CTRL4: | ||
286 | case RT5660_ALC_PGA_CTRL5: | ||
287 | case RT5660_ALC_PGA_CTRL6: | ||
288 | case RT5660_ALC_PGA_CTRL7: | ||
289 | case RT5660_GEN_CTRL1: | ||
290 | case RT5660_GEN_CTRL2: | ||
291 | case RT5660_GEN_CTRL3: | ||
292 | case RT5660_VENDOR_ID: | ||
293 | case RT5660_VENDOR_ID1: | ||
294 | case RT5660_VENDOR_ID2: | ||
295 | return true; | ||
296 | default: | ||
297 | return false; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | static const DECLARE_TLV_DB_SCALE(rt5660_out_vol_tlv, -4650, 150, 0); | ||
302 | static const DECLARE_TLV_DB_SCALE(rt5660_dac_vol_tlv, -6525, 75, 0); | ||
303 | static const DECLARE_TLV_DB_SCALE(rt5660_adc_vol_tlv, -1725, 75, 0); | ||
304 | static const DECLARE_TLV_DB_SCALE(rt5660_adc_bst_tlv, 0, 1200, 0); | ||
305 | static const DECLARE_TLV_DB_SCALE(rt5660_bst_tlv, -1200, 75, 0); | ||
306 | |||
307 | static const struct snd_kcontrol_new rt5660_snd_controls[] = { | ||
308 | /* Speaker Output Volume */ | ||
309 | SOC_SINGLE("Speaker Playback Switch", RT5660_SPK_VOL, RT5660_L_MUTE_SFT, | ||
310 | 1, 1), | ||
311 | SOC_SINGLE_TLV("Speaker Playback Volume", RT5660_SPK_VOL, | ||
312 | RT5660_L_VOL_SFT, 39, 1, rt5660_out_vol_tlv), | ||
313 | |||
314 | /* OUTPUT Control */ | ||
315 | SOC_DOUBLE("OUT Playback Switch", RT5660_LOUT_VOL, RT5660_L_MUTE_SFT, | ||
316 | RT5660_R_MUTE_SFT, 1, 1), | ||
317 | SOC_DOUBLE_TLV("OUT Playback Volume", RT5660_LOUT_VOL, RT5660_L_VOL_SFT, | ||
318 | RT5660_R_VOL_SFT, 39, 1, rt5660_out_vol_tlv), | ||
319 | |||
320 | /* DAC Digital Volume */ | ||
321 | SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5660_DAC1_DIG_VOL, | ||
322 | RT5660_DAC_L1_VOL_SFT, RT5660_DAC_R1_VOL_SFT, 87, 0, | ||
323 | rt5660_dac_vol_tlv), | ||
324 | |||
325 | /* IN1/IN2/IN3 Control */ | ||
326 | SOC_SINGLE_TLV("IN1 Boost Volume", RT5660_IN1_IN2, RT5660_BST_SFT1, 69, | ||
327 | 0, rt5660_bst_tlv), | ||
328 | SOC_SINGLE_TLV("IN2 Boost Volume", RT5660_IN1_IN2, RT5660_BST_SFT2, 69, | ||
329 | 0, rt5660_bst_tlv), | ||
330 | SOC_SINGLE_TLV("IN3 Boost Volume", RT5660_IN3_IN4, RT5660_BST_SFT3, 69, | ||
331 | 0, rt5660_bst_tlv), | ||
332 | |||
333 | /* ADC Digital Volume Control */ | ||
334 | SOC_DOUBLE("ADC Capture Switch", RT5660_STO1_ADC_DIG_VOL, | ||
335 | RT5660_L_MUTE_SFT, RT5660_R_MUTE_SFT, 1, 1), | ||
336 | SOC_DOUBLE_TLV("ADC Capture Volume", RT5660_STO1_ADC_DIG_VOL, | ||
337 | RT5660_ADC_L_VOL_SFT, RT5660_ADC_R_VOL_SFT, 63, 0, | ||
338 | rt5660_adc_vol_tlv), | ||
339 | |||
340 | /* ADC Boost Volume Control */ | ||
341 | SOC_DOUBLE_TLV("STO1 ADC Boost Gain Volume", RT5660_ADC_BST_VOL1, | ||
342 | RT5660_STO1_ADC_L_BST_SFT, RT5660_STO1_ADC_R_BST_SFT, 3, 0, | ||
343 | rt5660_adc_bst_tlv), | ||
344 | }; | ||
345 | |||
346 | /** | ||
347 | * rt5660_set_dmic_clk - Set parameter of dmic. | ||
348 | * | ||
349 | * @w: DAPM widget. | ||
350 | * @kcontrol: The kcontrol of this widget. | ||
351 | * @event: Event id. | ||
352 | * | ||
353 | */ | ||
354 | static int rt5660_set_dmic_clk(struct snd_soc_dapm_widget *w, | ||
355 | struct snd_kcontrol *kcontrol, int event) | ||
356 | { | ||
357 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
358 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
359 | int idx, rate; | ||
360 | |||
361 | rate = rt5660->sysclk / rl6231_get_pre_div(rt5660->regmap, | ||
362 | RT5660_ADDA_CLK1, RT5660_I2S_PD1_SFT); | ||
363 | idx = rl6231_calc_dmic_clk(rate); | ||
364 | if (idx < 0) | ||
365 | dev_err(codec->dev, "Failed to set DMIC clock\n"); | ||
366 | else | ||
367 | snd_soc_update_bits(codec, RT5660_DMIC_CTRL1, | ||
368 | RT5660_DMIC_CLK_MASK, idx << RT5660_DMIC_CLK_SFT); | ||
369 | |||
370 | return idx; | ||
371 | } | ||
372 | |||
373 | static int rt5660_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, | ||
374 | struct snd_soc_dapm_widget *sink) | ||
375 | { | ||
376 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
377 | unsigned int val; | ||
378 | |||
379 | val = snd_soc_read(codec, RT5660_GLB_CLK); | ||
380 | val &= RT5660_SCLK_SRC_MASK; | ||
381 | if (val == RT5660_SCLK_SRC_PLL1) | ||
382 | return 1; | ||
383 | else | ||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | /* Digital Mixer */ | ||
388 | static const struct snd_kcontrol_new rt5660_sto1_adc_l_mix[] = { | ||
389 | SOC_DAPM_SINGLE("ADC1 Switch", RT5660_STO1_ADC_MIXER, | ||
390 | RT5660_M_ADC_L1_SFT, 1, 1), | ||
391 | SOC_DAPM_SINGLE("ADC2 Switch", RT5660_STO1_ADC_MIXER, | ||
392 | RT5660_M_ADC_L2_SFT, 1, 1), | ||
393 | }; | ||
394 | |||
395 | static const struct snd_kcontrol_new rt5660_sto1_adc_r_mix[] = { | ||
396 | SOC_DAPM_SINGLE("ADC1 Switch", RT5660_STO1_ADC_MIXER, | ||
397 | RT5660_M_ADC_R1_SFT, 1, 1), | ||
398 | SOC_DAPM_SINGLE("ADC2 Switch", RT5660_STO1_ADC_MIXER, | ||
399 | RT5660_M_ADC_R2_SFT, 1, 1), | ||
400 | }; | ||
401 | |||
402 | static const struct snd_kcontrol_new rt5660_dac_l_mix[] = { | ||
403 | SOC_DAPM_SINGLE("Stereo ADC Switch", RT5660_AD_DA_MIXER, | ||
404 | RT5660_M_ADCMIX_L_SFT, 1, 1), | ||
405 | SOC_DAPM_SINGLE("DAC1 Switch", RT5660_AD_DA_MIXER, | ||
406 | RT5660_M_DAC1_L_SFT, 1, 1), | ||
407 | }; | ||
408 | |||
409 | static const struct snd_kcontrol_new rt5660_dac_r_mix[] = { | ||
410 | SOC_DAPM_SINGLE("Stereo ADC Switch", RT5660_AD_DA_MIXER, | ||
411 | RT5660_M_ADCMIX_R_SFT, 1, 1), | ||
412 | SOC_DAPM_SINGLE("DAC1 Switch", RT5660_AD_DA_MIXER, | ||
413 | RT5660_M_DAC1_R_SFT, 1, 1), | ||
414 | }; | ||
415 | |||
416 | static const struct snd_kcontrol_new rt5660_sto_dac_l_mix[] = { | ||
417 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5660_STO_DAC_MIXER, | ||
418 | RT5660_M_DAC_L1_SFT, 1, 1), | ||
419 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5660_STO_DAC_MIXER, | ||
420 | RT5660_M_DAC_R1_STO_L_SFT, 1, 1), | ||
421 | }; | ||
422 | |||
423 | static const struct snd_kcontrol_new rt5660_sto_dac_r_mix[] = { | ||
424 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5660_STO_DAC_MIXER, | ||
425 | RT5660_M_DAC_R1_SFT, 1, 1), | ||
426 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5660_STO_DAC_MIXER, | ||
427 | RT5660_M_DAC_L1_STO_R_SFT, 1, 1), | ||
428 | }; | ||
429 | |||
430 | /* Analog Input Mixer */ | ||
431 | static const struct snd_kcontrol_new rt5660_rec_l_mix[] = { | ||
432 | SOC_DAPM_SINGLE("BST3 Switch", RT5660_REC_L2_MIXER, | ||
433 | RT5660_M_BST3_RM_L_SFT, 1, 1), | ||
434 | SOC_DAPM_SINGLE("BST2 Switch", RT5660_REC_L2_MIXER, | ||
435 | RT5660_M_BST2_RM_L_SFT, 1, 1), | ||
436 | SOC_DAPM_SINGLE("BST1 Switch", RT5660_REC_L2_MIXER, | ||
437 | RT5660_M_BST1_RM_L_SFT, 1, 1), | ||
438 | SOC_DAPM_SINGLE("OUT MIXL Switch", RT5660_REC_L2_MIXER, | ||
439 | RT5660_M_OM_L_RM_L_SFT, 1, 1), | ||
440 | }; | ||
441 | |||
442 | static const struct snd_kcontrol_new rt5660_rec_r_mix[] = { | ||
443 | SOC_DAPM_SINGLE("BST3 Switch", RT5660_REC_R2_MIXER, | ||
444 | RT5660_M_BST3_RM_R_SFT, 1, 1), | ||
445 | SOC_DAPM_SINGLE("BST2 Switch", RT5660_REC_R2_MIXER, | ||
446 | RT5660_M_BST2_RM_R_SFT, 1, 1), | ||
447 | SOC_DAPM_SINGLE("BST1 Switch", RT5660_REC_R2_MIXER, | ||
448 | RT5660_M_BST1_RM_R_SFT, 1, 1), | ||
449 | SOC_DAPM_SINGLE("OUT MIXR Switch", RT5660_REC_R2_MIXER, | ||
450 | RT5660_M_OM_R_RM_R_SFT, 1, 1), | ||
451 | }; | ||
452 | |||
453 | static const struct snd_kcontrol_new rt5660_spk_mix[] = { | ||
454 | SOC_DAPM_SINGLE("BST3 Switch", RT5660_SPK_MIXER, | ||
455 | RT5660_M_BST3_SM_SFT, 1, 1), | ||
456 | SOC_DAPM_SINGLE("BST1 Switch", RT5660_SPK_MIXER, | ||
457 | RT5660_M_BST1_SM_SFT, 1, 1), | ||
458 | SOC_DAPM_SINGLE("DACL Switch", RT5660_SPK_MIXER, | ||
459 | RT5660_M_DACL_SM_SFT, 1, 1), | ||
460 | SOC_DAPM_SINGLE("DACR Switch", RT5660_SPK_MIXER, | ||
461 | RT5660_M_DACR_SM_SFT, 1, 1), | ||
462 | SOC_DAPM_SINGLE("OUTMIXL Switch", RT5660_SPK_MIXER, | ||
463 | RT5660_M_OM_L_SM_SFT, 1, 1), | ||
464 | }; | ||
465 | |||
466 | static const struct snd_kcontrol_new rt5660_out_l_mix[] = { | ||
467 | SOC_DAPM_SINGLE("BST3 Switch", RT5660_OUT_L1_MIXER, | ||
468 | RT5660_M_BST3_OM_L_SFT, 1, 1), | ||
469 | SOC_DAPM_SINGLE("BST2 Switch", RT5660_OUT_L1_MIXER, | ||
470 | RT5660_M_BST2_OM_L_SFT, 1, 1), | ||
471 | SOC_DAPM_SINGLE("BST1 Switch", RT5660_OUT_L1_MIXER, | ||
472 | RT5660_M_BST1_OM_L_SFT, 1, 1), | ||
473 | SOC_DAPM_SINGLE("RECMIXL Switch", RT5660_OUT_L1_MIXER, | ||
474 | RT5660_M_RM_L_OM_L_SFT, 1, 1), | ||
475 | SOC_DAPM_SINGLE("DACR Switch", RT5660_OUT_L1_MIXER, | ||
476 | RT5660_M_DAC_R_OM_L_SFT, 1, 1), | ||
477 | SOC_DAPM_SINGLE("DACL Switch", RT5660_OUT_L1_MIXER, | ||
478 | RT5660_M_DAC_L_OM_L_SFT, 1, 1), | ||
479 | }; | ||
480 | |||
481 | static const struct snd_kcontrol_new rt5660_out_r_mix[] = { | ||
482 | SOC_DAPM_SINGLE("BST2 Switch", RT5660_OUT_R1_MIXER, | ||
483 | RT5660_M_BST2_OM_R_SFT, 1, 1), | ||
484 | SOC_DAPM_SINGLE("BST1 Switch", RT5660_OUT_R1_MIXER, | ||
485 | RT5660_M_BST1_OM_R_SFT, 1, 1), | ||
486 | SOC_DAPM_SINGLE("RECMIXR Switch", RT5660_OUT_R1_MIXER, | ||
487 | RT5660_M_RM_R_OM_R_SFT, 1, 1), | ||
488 | SOC_DAPM_SINGLE("DACR Switch", RT5660_OUT_R1_MIXER, | ||
489 | RT5660_M_DAC_R_OM_R_SFT, 1, 1), | ||
490 | SOC_DAPM_SINGLE("DACL Switch", RT5660_OUT_R1_MIXER, | ||
491 | RT5660_M_DAC_L_OM_R_SFT, 1, 1), | ||
492 | }; | ||
493 | |||
494 | static const struct snd_kcontrol_new rt5660_spo_mix[] = { | ||
495 | SOC_DAPM_SINGLE("DACR Switch", RT5660_SPO_MIXER, | ||
496 | RT5660_M_DAC_R_SPM_SFT, 1, 1), | ||
497 | SOC_DAPM_SINGLE("DACL Switch", RT5660_SPO_MIXER, | ||
498 | RT5660_M_DAC_L_SPM_SFT, 1, 1), | ||
499 | SOC_DAPM_SINGLE("SPKVOL Switch", RT5660_SPO_MIXER, | ||
500 | RT5660_M_SV_SPM_SFT, 1, 1), | ||
501 | SOC_DAPM_SINGLE("BST1 Switch", RT5660_SPO_MIXER, | ||
502 | RT5660_M_BST1_SPM_SFT, 1, 1), | ||
503 | }; | ||
504 | |||
505 | static const struct snd_kcontrol_new rt5660_lout_mix[] = { | ||
506 | SOC_DAPM_SINGLE("DAC Switch", RT5660_LOUT_MIXER, | ||
507 | RT5660_M_DAC1_LM_SFT, 1, 1), | ||
508 | SOC_DAPM_SINGLE("OUTMIX Switch", RT5660_LOUT_MIXER, | ||
509 | RT5660_M_LOVOL_LM_SFT, 1, 1), | ||
510 | }; | ||
511 | |||
512 | static const struct snd_kcontrol_new spk_vol_control = | ||
513 | SOC_DAPM_SINGLE("Switch", RT5660_SPK_VOL, | ||
514 | RT5660_VOL_L_SFT, 1, 1); | ||
515 | |||
516 | static const struct snd_kcontrol_new lout_l_vol_control = | ||
517 | SOC_DAPM_SINGLE("Switch", RT5660_LOUT_VOL, | ||
518 | RT5660_VOL_L_SFT, 1, 1); | ||
519 | |||
520 | static const struct snd_kcontrol_new lout_r_vol_control = | ||
521 | SOC_DAPM_SINGLE("Switch", RT5660_LOUT_VOL, | ||
522 | RT5660_VOL_R_SFT, 1, 1); | ||
523 | |||
524 | /* Interface data select */ | ||
525 | static const char * const rt5660_data_select[] = { | ||
526 | "L/R", "R/L", "L/L", "R/R" | ||
527 | }; | ||
528 | |||
529 | static const SOC_ENUM_SINGLE_DECL(rt5660_if1_dac_enum, | ||
530 | RT5660_DIG_INF1_DATA, RT5660_IF1_DAC_IN_SFT, rt5660_data_select); | ||
531 | |||
532 | static const SOC_ENUM_SINGLE_DECL(rt5660_if1_adc_enum, | ||
533 | RT5660_DIG_INF1_DATA, RT5660_IF1_ADC_IN_SFT, rt5660_data_select); | ||
534 | |||
535 | static const struct snd_kcontrol_new rt5660_if1_dac_swap_mux = | ||
536 | SOC_DAPM_ENUM("IF1 DAC Swap Source", rt5660_if1_dac_enum); | ||
537 | |||
538 | static const struct snd_kcontrol_new rt5660_if1_adc_swap_mux = | ||
539 | SOC_DAPM_ENUM("IF1 ADC Swap Source", rt5660_if1_adc_enum); | ||
540 | |||
541 | static int rt5660_lout_event(struct snd_soc_dapm_widget *w, | ||
542 | struct snd_kcontrol *kcontrol, int event) | ||
543 | { | ||
544 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
545 | |||
546 | switch (event) { | ||
547 | case SND_SOC_DAPM_POST_PMU: | ||
548 | snd_soc_update_bits(codec, RT5660_LOUT_AMP_CTRL, | ||
549 | RT5660_LOUT_CO_MASK | RT5660_LOUT_CB_MASK, | ||
550 | RT5660_LOUT_CO_EN | RT5660_LOUT_CB_PU); | ||
551 | break; | ||
552 | |||
553 | case SND_SOC_DAPM_PRE_PMD: | ||
554 | snd_soc_update_bits(codec, RT5660_LOUT_AMP_CTRL, | ||
555 | RT5660_LOUT_CO_MASK | RT5660_LOUT_CB_MASK, | ||
556 | RT5660_LOUT_CO_DIS | RT5660_LOUT_CB_PD); | ||
557 | break; | ||
558 | |||
559 | default: | ||
560 | return 0; | ||
561 | } | ||
562 | |||
563 | return 0; | ||
564 | } | ||
565 | |||
566 | static const struct snd_soc_dapm_widget rt5660_dapm_widgets[] = { | ||
567 | SND_SOC_DAPM_SUPPLY("LDO2", RT5660_PWR_ANLG1, | ||
568 | RT5660_PWR_LDO2_BIT, 0, NULL, 0), | ||
569 | SND_SOC_DAPM_SUPPLY("PLL1", RT5660_PWR_ANLG2, | ||
570 | RT5660_PWR_PLL_BIT, 0, NULL, 0), | ||
571 | |||
572 | /* MICBIAS */ | ||
573 | SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5660_PWR_ANLG2, | ||
574 | RT5660_PWR_MB1_BIT, 0, NULL, 0), | ||
575 | SND_SOC_DAPM_SUPPLY("MICBIAS2", RT5660_PWR_ANLG2, | ||
576 | RT5660_PWR_MB2_BIT, 0, NULL, 0), | ||
577 | |||
578 | /* Input Side */ | ||
579 | /* Input Lines */ | ||
580 | SND_SOC_DAPM_INPUT("DMIC L1"), | ||
581 | SND_SOC_DAPM_INPUT("DMIC R1"), | ||
582 | |||
583 | SND_SOC_DAPM_INPUT("IN1P"), | ||
584 | SND_SOC_DAPM_INPUT("IN1N"), | ||
585 | SND_SOC_DAPM_INPUT("IN2P"), | ||
586 | SND_SOC_DAPM_INPUT("IN3P"), | ||
587 | SND_SOC_DAPM_INPUT("IN3N"), | ||
588 | |||
589 | SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0, | ||
590 | rt5660_set_dmic_clk, SND_SOC_DAPM_PRE_PMU), | ||
591 | SND_SOC_DAPM_SUPPLY("DMIC Power", RT5660_DMIC_CTRL1, | ||
592 | RT5660_DMIC_1_EN_SFT, 0, NULL, 0), | ||
593 | |||
594 | /* Boost */ | ||
595 | SND_SOC_DAPM_PGA("BST1", RT5660_PWR_ANLG2, RT5660_PWR_BST1_BIT, 0, | ||
596 | NULL, 0), | ||
597 | SND_SOC_DAPM_PGA("BST2", RT5660_PWR_ANLG2, RT5660_PWR_BST2_BIT, 0, | ||
598 | NULL, 0), | ||
599 | SND_SOC_DAPM_PGA("BST3", RT5660_PWR_ANLG2, RT5660_PWR_BST3_BIT, 0, | ||
600 | NULL, 0), | ||
601 | |||
602 | /* REC Mixer */ | ||
603 | SND_SOC_DAPM_MIXER("RECMIXL", RT5660_PWR_MIXER, RT5660_PWR_RM_L_BIT, | ||
604 | 0, rt5660_rec_l_mix, ARRAY_SIZE(rt5660_rec_l_mix)), | ||
605 | SND_SOC_DAPM_MIXER("RECMIXR", RT5660_PWR_MIXER, RT5660_PWR_RM_R_BIT, | ||
606 | 0, rt5660_rec_r_mix, ARRAY_SIZE(rt5660_rec_r_mix)), | ||
607 | |||
608 | /* ADCs */ | ||
609 | SND_SOC_DAPM_ADC("ADC L", NULL, SND_SOC_NOPM, 0, 0), | ||
610 | SND_SOC_DAPM_ADC("ADC R", NULL, SND_SOC_NOPM, 0, 0), | ||
611 | |||
612 | SND_SOC_DAPM_SUPPLY("ADC L power", RT5660_PWR_DIG1, | ||
613 | RT5660_PWR_ADC_L_BIT, 0, NULL, 0), | ||
614 | SND_SOC_DAPM_SUPPLY("ADC R power", RT5660_PWR_DIG1, | ||
615 | RT5660_PWR_ADC_R_BIT, 0, NULL, 0), | ||
616 | SND_SOC_DAPM_SUPPLY("ADC clock", RT5660_PR_BASE + RT5660_CHOP_DAC_ADC, | ||
617 | 12, 0, NULL, 0), | ||
618 | |||
619 | /* ADC Mixer */ | ||
620 | SND_SOC_DAPM_SUPPLY("adc stereo1 filter", RT5660_PWR_DIG2, | ||
621 | RT5660_PWR_ADC_S1F_BIT, 0, NULL, 0), | ||
622 | SND_SOC_DAPM_MIXER("Sto1 ADC MIXL", SND_SOC_NOPM, 0, 0, | ||
623 | rt5660_sto1_adc_l_mix, ARRAY_SIZE(rt5660_sto1_adc_l_mix)), | ||
624 | SND_SOC_DAPM_MIXER("Sto1 ADC MIXR", SND_SOC_NOPM, 0, 0, | ||
625 | rt5660_sto1_adc_r_mix, ARRAY_SIZE(rt5660_sto1_adc_r_mix)), | ||
626 | |||
627 | /* ADC */ | ||
628 | SND_SOC_DAPM_ADC("Stereo1 ADC MIXL", NULL, RT5660_STO1_ADC_DIG_VOL, | ||
629 | RT5660_L_MUTE_SFT, 1), | ||
630 | SND_SOC_DAPM_ADC("Stereo1 ADC MIXR", NULL, RT5660_STO1_ADC_DIG_VOL, | ||
631 | RT5660_R_MUTE_SFT, 1), | ||
632 | |||
633 | /* Digital Interface */ | ||
634 | SND_SOC_DAPM_SUPPLY("I2S1", RT5660_PWR_DIG1, RT5660_PWR_I2S1_BIT, 0, | ||
635 | NULL, 0), | ||
636 | SND_SOC_DAPM_PGA("IF1 DAC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
637 | SND_SOC_DAPM_PGA("IF1 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
638 | SND_SOC_DAPM_PGA("IF1 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
639 | SND_SOC_DAPM_MUX("IF1 DAC Swap Mux", SND_SOC_NOPM, 0, 0, | ||
640 | &rt5660_if1_dac_swap_mux), | ||
641 | SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
642 | SND_SOC_DAPM_MUX("IF1 ADC Swap Mux", SND_SOC_NOPM, 0, 0, | ||
643 | &rt5660_if1_adc_swap_mux), | ||
644 | |||
645 | /* Audio Interface */ | ||
646 | SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
647 | SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
648 | |||
649 | /* Output Side */ | ||
650 | /* DAC mixer before sound effect */ | ||
651 | SND_SOC_DAPM_MIXER("DAC1 MIXL", SND_SOC_NOPM, 0, 0, rt5660_dac_l_mix, | ||
652 | ARRAY_SIZE(rt5660_dac_l_mix)), | ||
653 | SND_SOC_DAPM_MIXER("DAC1 MIXR", SND_SOC_NOPM, 0, 0, rt5660_dac_r_mix, | ||
654 | ARRAY_SIZE(rt5660_dac_r_mix)), | ||
655 | |||
656 | /* DAC Mixer */ | ||
657 | SND_SOC_DAPM_SUPPLY("dac stereo1 filter", RT5660_PWR_DIG2, | ||
658 | RT5660_PWR_DAC_S1F_BIT, 0, NULL, 0), | ||
659 | SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, | ||
660 | rt5660_sto_dac_l_mix, ARRAY_SIZE(rt5660_sto_dac_l_mix)), | ||
661 | SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, | ||
662 | rt5660_sto_dac_r_mix, ARRAY_SIZE(rt5660_sto_dac_r_mix)), | ||
663 | |||
664 | /* DACs */ | ||
665 | SND_SOC_DAPM_DAC("DAC L1", NULL, RT5660_PWR_DIG1, | ||
666 | RT5660_PWR_DAC_L1_BIT, 0), | ||
667 | SND_SOC_DAPM_DAC("DAC R1", NULL, RT5660_PWR_DIG1, | ||
668 | RT5660_PWR_DAC_R1_BIT, 0), | ||
669 | |||
670 | /* OUT Mixer */ | ||
671 | SND_SOC_DAPM_MIXER("SPK MIX", RT5660_PWR_MIXER, RT5660_PWR_SM_BIT, | ||
672 | 0, rt5660_spk_mix, ARRAY_SIZE(rt5660_spk_mix)), | ||
673 | SND_SOC_DAPM_MIXER("OUT MIXL", RT5660_PWR_MIXER, RT5660_PWR_OM_L_BIT, | ||
674 | 0, rt5660_out_l_mix, ARRAY_SIZE(rt5660_out_l_mix)), | ||
675 | SND_SOC_DAPM_MIXER("OUT MIXR", RT5660_PWR_MIXER, RT5660_PWR_OM_R_BIT, | ||
676 | 0, rt5660_out_r_mix, ARRAY_SIZE(rt5660_out_r_mix)), | ||
677 | |||
678 | /* Output Volume */ | ||
679 | SND_SOC_DAPM_SWITCH("SPKVOL", RT5660_PWR_VOL, | ||
680 | RT5660_PWR_SV_BIT, 0, &spk_vol_control), | ||
681 | SND_SOC_DAPM_PGA("DAC 1", SND_SOC_NOPM, | ||
682 | 0, 0, NULL, 0), | ||
683 | SND_SOC_DAPM_PGA("LOUTVOL", SND_SOC_NOPM, | ||
684 | 0, 0, NULL, 0), | ||
685 | SND_SOC_DAPM_SWITCH("LOUTVOL L", SND_SOC_NOPM, | ||
686 | RT5660_PWR_LV_L_BIT, 0, &lout_l_vol_control), | ||
687 | SND_SOC_DAPM_SWITCH("LOUTVOL R", SND_SOC_NOPM, | ||
688 | RT5660_PWR_LV_R_BIT, 0, &lout_r_vol_control), | ||
689 | |||
690 | /* HPO/LOUT/Mono Mixer */ | ||
691 | SND_SOC_DAPM_MIXER("SPO MIX", SND_SOC_NOPM, 0, | ||
692 | 0, rt5660_spo_mix, ARRAY_SIZE(rt5660_spo_mix)), | ||
693 | SND_SOC_DAPM_MIXER("LOUT MIX", SND_SOC_NOPM, 0, 0, | ||
694 | rt5660_lout_mix, ARRAY_SIZE(rt5660_lout_mix)), | ||
695 | SND_SOC_DAPM_SUPPLY("VREF HP", RT5660_GEN_CTRL1, | ||
696 | RT5660_PWR_VREF_HP_SFT, 0, NULL, 0), | ||
697 | SND_SOC_DAPM_PGA_S("LOUT amp", 1, RT5660_PWR_ANLG1, | ||
698 | RT5660_PWR_HA_BIT, 0, rt5660_lout_event, | ||
699 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
700 | SND_SOC_DAPM_PGA_S("SPK amp", 1, RT5660_PWR_DIG1, | ||
701 | RT5660_PWR_CLS_D_BIT, 0, NULL, 0), | ||
702 | |||
703 | /* Output Lines */ | ||
704 | SND_SOC_DAPM_OUTPUT("LOUTL"), | ||
705 | SND_SOC_DAPM_OUTPUT("LOUTR"), | ||
706 | SND_SOC_DAPM_OUTPUT("SPO"), | ||
707 | }; | ||
708 | |||
709 | static const struct snd_soc_dapm_route rt5660_dapm_routes[] = { | ||
710 | { "MICBIAS1", NULL, "LDO2" }, | ||
711 | { "MICBIAS2", NULL, "LDO2" }, | ||
712 | |||
713 | { "BST1", NULL, "IN1P" }, | ||
714 | { "BST1", NULL, "IN1N" }, | ||
715 | { "BST2", NULL, "IN2P" }, | ||
716 | { "BST3", NULL, "IN3P" }, | ||
717 | { "BST3", NULL, "IN3N" }, | ||
718 | |||
719 | { "RECMIXL", "BST3 Switch", "BST3" }, | ||
720 | { "RECMIXL", "BST2 Switch", "BST2" }, | ||
721 | { "RECMIXL", "BST1 Switch", "BST1" }, | ||
722 | { "RECMIXL", "OUT MIXL Switch", "OUT MIXL" }, | ||
723 | |||
724 | { "RECMIXR", "BST3 Switch", "BST3" }, | ||
725 | { "RECMIXR", "BST2 Switch", "BST2" }, | ||
726 | { "RECMIXR", "BST1 Switch", "BST1" }, | ||
727 | { "RECMIXR", "OUT MIXR Switch", "OUT MIXR" }, | ||
728 | |||
729 | { "ADC L", NULL, "RECMIXL" }, | ||
730 | { "ADC L", NULL, "ADC L power" }, | ||
731 | { "ADC L", NULL, "ADC clock" }, | ||
732 | { "ADC R", NULL, "RECMIXR" }, | ||
733 | { "ADC R", NULL, "ADC R power" }, | ||
734 | { "ADC R", NULL, "ADC clock" }, | ||
735 | |||
736 | {"DMIC L1", NULL, "DMIC CLK"}, | ||
737 | {"DMIC L1", NULL, "DMIC Power"}, | ||
738 | {"DMIC R1", NULL, "DMIC CLK"}, | ||
739 | {"DMIC R1", NULL, "DMIC Power"}, | ||
740 | |||
741 | { "Sto1 ADC MIXL", "ADC1 Switch", "ADC L" }, | ||
742 | { "Sto1 ADC MIXL", "ADC2 Switch", "DMIC L1" }, | ||
743 | { "Sto1 ADC MIXR", "ADC1 Switch", "ADC R" }, | ||
744 | { "Sto1 ADC MIXR", "ADC2 Switch", "DMIC R1" }, | ||
745 | |||
746 | { "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" }, | ||
747 | { "Stereo1 ADC MIXL", NULL, "adc stereo1 filter" }, | ||
748 | { "adc stereo1 filter", NULL, "PLL1", rt5660_is_sys_clk_from_pll }, | ||
749 | |||
750 | { "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" }, | ||
751 | { "Stereo1 ADC MIXR", NULL, "adc stereo1 filter" }, | ||
752 | { "adc stereo1 filter", NULL, "PLL1", rt5660_is_sys_clk_from_pll }, | ||
753 | |||
754 | { "IF1 ADC", NULL, "Stereo1 ADC MIXL" }, | ||
755 | { "IF1 ADC", NULL, "Stereo1 ADC MIXR" }, | ||
756 | { "IF1 ADC", NULL, "I2S1" }, | ||
757 | |||
758 | { "IF1 ADC Swap Mux", "L/R", "IF1 ADC" }, | ||
759 | { "IF1 ADC Swap Mux", "R/L", "IF1 ADC" }, | ||
760 | { "IF1 ADC Swap Mux", "L/L", "IF1 ADC" }, | ||
761 | { "IF1 ADC Swap Mux", "R/R", "IF1 ADC" }, | ||
762 | { "AIF1TX", NULL, "IF1 ADC Swap Mux" }, | ||
763 | |||
764 | { "IF1 DAC", NULL, "AIF1RX" }, | ||
765 | { "IF1 DAC", NULL, "I2S1" }, | ||
766 | |||
767 | { "IF1 DAC Swap Mux", "L/R", "IF1 DAC" }, | ||
768 | { "IF1 DAC Swap Mux", "R/L", "IF1 DAC" }, | ||
769 | { "IF1 DAC Swap Mux", "L/L", "IF1 DAC" }, | ||
770 | { "IF1 DAC Swap Mux", "R/R", "IF1 DAC" }, | ||
771 | |||
772 | { "IF1 DAC L", NULL, "IF1 DAC Swap Mux" }, | ||
773 | { "IF1 DAC R", NULL, "IF1 DAC Swap Mux" }, | ||
774 | |||
775 | { "DAC1 MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL" }, | ||
776 | { "DAC1 MIXL", "DAC1 Switch", "IF1 DAC L" }, | ||
777 | { "DAC1 MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR" }, | ||
778 | { "DAC1 MIXR", "DAC1 Switch", "IF1 DAC R" }, | ||
779 | |||
780 | { "Stereo DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" }, | ||
781 | { "Stereo DAC MIXL", "DAC R1 Switch", "DAC1 MIXR" }, | ||
782 | { "Stereo DAC MIXL", NULL, "dac stereo1 filter" }, | ||
783 | { "dac stereo1 filter", NULL, "PLL1", rt5660_is_sys_clk_from_pll }, | ||
784 | { "Stereo DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" }, | ||
785 | { "Stereo DAC MIXR", "DAC L1 Switch", "DAC1 MIXL" }, | ||
786 | { "Stereo DAC MIXR", NULL, "dac stereo1 filter" }, | ||
787 | { "dac stereo1 filter", NULL, "PLL1", rt5660_is_sys_clk_from_pll }, | ||
788 | |||
789 | { "DAC L1", NULL, "Stereo DAC MIXL" }, | ||
790 | { "DAC R1", NULL, "Stereo DAC MIXR" }, | ||
791 | |||
792 | { "SPK MIX", "BST3 Switch", "BST3" }, | ||
793 | { "SPK MIX", "BST1 Switch", "BST1" }, | ||
794 | { "SPK MIX", "DACL Switch", "DAC L1" }, | ||
795 | { "SPK MIX", "DACR Switch", "DAC R1" }, | ||
796 | { "SPK MIX", "OUTMIXL Switch", "OUT MIXL" }, | ||
797 | |||
798 | { "OUT MIXL", "BST3 Switch", "BST3" }, | ||
799 | { "OUT MIXL", "BST2 Switch", "BST2" }, | ||
800 | { "OUT MIXL", "BST1 Switch", "BST1" }, | ||
801 | { "OUT MIXL", "RECMIXL Switch", "RECMIXL" }, | ||
802 | { "OUT MIXL", "DACR Switch", "DAC R1" }, | ||
803 | { "OUT MIXL", "DACL Switch", "DAC L1" }, | ||
804 | |||
805 | { "OUT MIXR", "BST2 Switch", "BST2" }, | ||
806 | { "OUT MIXR", "BST1 Switch", "BST1" }, | ||
807 | { "OUT MIXR", "RECMIXR Switch", "RECMIXR" }, | ||
808 | { "OUT MIXR", "DACR Switch", "DAC R1" }, | ||
809 | { "OUT MIXR", "DACL Switch", "DAC L1" }, | ||
810 | |||
811 | { "SPO MIX", "DACR Switch", "DAC R1" }, | ||
812 | { "SPO MIX", "DACL Switch", "DAC L1" }, | ||
813 | { "SPO MIX", "SPKVOL Switch", "SPKVOL" }, | ||
814 | { "SPO MIX", "BST1 Switch", "BST1" }, | ||
815 | |||
816 | { "SPKVOL", "Switch", "SPK MIX" }, | ||
817 | { "LOUTVOL L", "Switch", "OUT MIXL" }, | ||
818 | { "LOUTVOL R", "Switch", "OUT MIXR" }, | ||
819 | |||
820 | { "LOUTVOL", NULL, "LOUTVOL L" }, | ||
821 | { "LOUTVOL", NULL, "LOUTVOL R" }, | ||
822 | |||
823 | { "DAC 1", NULL, "DAC L1" }, | ||
824 | { "DAC 1", NULL, "DAC R1" }, | ||
825 | |||
826 | { "LOUT MIX", "DAC Switch", "DAC 1" }, | ||
827 | { "LOUT MIX", "OUTMIX Switch", "LOUTVOL" }, | ||
828 | |||
829 | { "LOUT amp", NULL, "LOUT MIX" }, | ||
830 | { "LOUT amp", NULL, "VREF HP" }, | ||
831 | { "LOUTL", NULL, "LOUT amp" }, | ||
832 | { "LOUTR", NULL, "LOUT amp" }, | ||
833 | |||
834 | { "SPK amp", NULL, "SPO MIX" }, | ||
835 | { "SPO", NULL, "SPK amp" }, | ||
836 | }; | ||
837 | |||
838 | static int rt5660_hw_params(struct snd_pcm_substream *substream, | ||
839 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | ||
840 | { | ||
841 | struct snd_soc_codec *codec = dai->codec; | ||
842 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
843 | unsigned int val_len = 0, val_clk, mask_clk; | ||
844 | int pre_div, bclk_ms, frame_size; | ||
845 | |||
846 | rt5660->lrck[dai->id] = params_rate(params); | ||
847 | pre_div = rl6231_get_clk_info(rt5660->sysclk, rt5660->lrck[dai->id]); | ||
848 | if (pre_div < 0) { | ||
849 | dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n", | ||
850 | rt5660->lrck[dai->id], dai->id); | ||
851 | return -EINVAL; | ||
852 | } | ||
853 | |||
854 | frame_size = snd_soc_params_to_frame_size(params); | ||
855 | if (frame_size < 0) { | ||
856 | dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size); | ||
857 | return frame_size; | ||
858 | } | ||
859 | |||
860 | if (frame_size > 32) | ||
861 | bclk_ms = 1; | ||
862 | else | ||
863 | bclk_ms = 0; | ||
864 | |||
865 | rt5660->bclk[dai->id] = rt5660->lrck[dai->id] * (32 << bclk_ms); | ||
866 | |||
867 | dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n", | ||
868 | rt5660->bclk[dai->id], rt5660->lrck[dai->id]); | ||
869 | dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n", | ||
870 | bclk_ms, pre_div, dai->id); | ||
871 | |||
872 | switch (params_width(params)) { | ||
873 | case 16: | ||
874 | break; | ||
875 | case 20: | ||
876 | val_len |= RT5660_I2S_DL_20; | ||
877 | break; | ||
878 | case 24: | ||
879 | val_len |= RT5660_I2S_DL_24; | ||
880 | break; | ||
881 | case 8: | ||
882 | val_len |= RT5660_I2S_DL_8; | ||
883 | break; | ||
884 | default: | ||
885 | return -EINVAL; | ||
886 | } | ||
887 | |||
888 | switch (dai->id) { | ||
889 | case RT5660_AIF1: | ||
890 | mask_clk = RT5660_I2S_BCLK_MS1_MASK | RT5660_I2S_PD1_MASK; | ||
891 | val_clk = bclk_ms << RT5660_I2S_BCLK_MS1_SFT | | ||
892 | pre_div << RT5660_I2S_PD1_SFT; | ||
893 | snd_soc_update_bits(codec, RT5660_I2S1_SDP, RT5660_I2S_DL_MASK, | ||
894 | val_len); | ||
895 | snd_soc_update_bits(codec, RT5660_ADDA_CLK1, mask_clk, val_clk); | ||
896 | break; | ||
897 | |||
898 | default: | ||
899 | dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id); | ||
900 | return -EINVAL; | ||
901 | } | ||
902 | |||
903 | return 0; | ||
904 | } | ||
905 | |||
906 | static int rt5660_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
907 | { | ||
908 | struct snd_soc_codec *codec = dai->codec; | ||
909 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
910 | unsigned int reg_val = 0; | ||
911 | |||
912 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
913 | case SND_SOC_DAIFMT_CBM_CFM: | ||
914 | rt5660->master[dai->id] = 1; | ||
915 | break; | ||
916 | |||
917 | case SND_SOC_DAIFMT_CBS_CFS: | ||
918 | reg_val |= RT5660_I2S_MS_S; | ||
919 | rt5660->master[dai->id] = 0; | ||
920 | break; | ||
921 | |||
922 | default: | ||
923 | return -EINVAL; | ||
924 | } | ||
925 | |||
926 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
927 | case SND_SOC_DAIFMT_NB_NF: | ||
928 | break; | ||
929 | |||
930 | case SND_SOC_DAIFMT_IB_NF: | ||
931 | reg_val |= RT5660_I2S_BP_INV; | ||
932 | break; | ||
933 | |||
934 | default: | ||
935 | return -EINVAL; | ||
936 | } | ||
937 | |||
938 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
939 | case SND_SOC_DAIFMT_I2S: | ||
940 | break; | ||
941 | |||
942 | case SND_SOC_DAIFMT_LEFT_J: | ||
943 | reg_val |= RT5660_I2S_DF_LEFT; | ||
944 | break; | ||
945 | |||
946 | case SND_SOC_DAIFMT_DSP_A: | ||
947 | reg_val |= RT5660_I2S_DF_PCM_A; | ||
948 | break; | ||
949 | |||
950 | case SND_SOC_DAIFMT_DSP_B: | ||
951 | reg_val |= RT5660_I2S_DF_PCM_B; | ||
952 | break; | ||
953 | |||
954 | default: | ||
955 | return -EINVAL; | ||
956 | } | ||
957 | |||
958 | switch (dai->id) { | ||
959 | case RT5660_AIF1: | ||
960 | snd_soc_update_bits(codec, RT5660_I2S1_SDP, | ||
961 | RT5660_I2S_MS_MASK | RT5660_I2S_BP_MASK | | ||
962 | RT5660_I2S_DF_MASK, reg_val); | ||
963 | break; | ||
964 | |||
965 | default: | ||
966 | dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id); | ||
967 | return -EINVAL; | ||
968 | } | ||
969 | |||
970 | return 0; | ||
971 | } | ||
972 | |||
973 | static int rt5660_set_dai_sysclk(struct snd_soc_dai *dai, | ||
974 | int clk_id, unsigned int freq, int dir) | ||
975 | { | ||
976 | struct snd_soc_codec *codec = dai->codec; | ||
977 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
978 | unsigned int reg_val = 0; | ||
979 | |||
980 | if (freq == rt5660->sysclk && clk_id == rt5660->sysclk_src) | ||
981 | return 0; | ||
982 | |||
983 | switch (clk_id) { | ||
984 | case RT5660_SCLK_S_MCLK: | ||
985 | reg_val |= RT5660_SCLK_SRC_MCLK; | ||
986 | break; | ||
987 | |||
988 | case RT5660_SCLK_S_PLL1: | ||
989 | reg_val |= RT5660_SCLK_SRC_PLL1; | ||
990 | break; | ||
991 | |||
992 | case RT5660_SCLK_S_RCCLK: | ||
993 | reg_val |= RT5660_SCLK_SRC_RCCLK; | ||
994 | break; | ||
995 | |||
996 | default: | ||
997 | dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); | ||
998 | return -EINVAL; | ||
999 | } | ||
1000 | |||
1001 | snd_soc_update_bits(codec, RT5660_GLB_CLK, RT5660_SCLK_SRC_MASK, | ||
1002 | reg_val); | ||
1003 | |||
1004 | rt5660->sysclk = freq; | ||
1005 | rt5660->sysclk_src = clk_id; | ||
1006 | |||
1007 | dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); | ||
1008 | |||
1009 | return 0; | ||
1010 | } | ||
1011 | |||
1012 | static int rt5660_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, | ||
1013 | unsigned int freq_in, unsigned int freq_out) | ||
1014 | { | ||
1015 | struct snd_soc_codec *codec = dai->codec; | ||
1016 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
1017 | struct rl6231_pll_code pll_code; | ||
1018 | int ret; | ||
1019 | |||
1020 | if (source == rt5660->pll_src && freq_in == rt5660->pll_in && | ||
1021 | freq_out == rt5660->pll_out) | ||
1022 | return 0; | ||
1023 | |||
1024 | if (!freq_in || !freq_out) { | ||
1025 | dev_dbg(codec->dev, "PLL disabled\n"); | ||
1026 | |||
1027 | rt5660->pll_in = 0; | ||
1028 | rt5660->pll_out = 0; | ||
1029 | snd_soc_update_bits(codec, RT5660_GLB_CLK, | ||
1030 | RT5660_SCLK_SRC_MASK, RT5660_SCLK_SRC_MCLK); | ||
1031 | return 0; | ||
1032 | } | ||
1033 | |||
1034 | switch (source) { | ||
1035 | case RT5660_PLL1_S_MCLK: | ||
1036 | snd_soc_update_bits(codec, RT5660_GLB_CLK, | ||
1037 | RT5660_PLL1_SRC_MASK, RT5660_PLL1_SRC_MCLK); | ||
1038 | break; | ||
1039 | |||
1040 | case RT5660_PLL1_S_BCLK: | ||
1041 | snd_soc_update_bits(codec, RT5660_GLB_CLK, | ||
1042 | RT5660_PLL1_SRC_MASK, RT5660_PLL1_SRC_BCLK1); | ||
1043 | break; | ||
1044 | |||
1045 | default: | ||
1046 | dev_err(codec->dev, "Unknown PLL source %d\n", source); | ||
1047 | return -EINVAL; | ||
1048 | } | ||
1049 | |||
1050 | ret = rl6231_pll_calc(freq_in, freq_out, &pll_code); | ||
1051 | if (ret < 0) { | ||
1052 | dev_err(codec->dev, "Unsupport input clock %d\n", freq_in); | ||
1053 | return ret; | ||
1054 | } | ||
1055 | |||
1056 | dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n", | ||
1057 | pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code), | ||
1058 | pll_code.n_code, pll_code.k_code); | ||
1059 | |||
1060 | snd_soc_write(codec, RT5660_PLL_CTRL1, | ||
1061 | pll_code.n_code << RT5660_PLL_N_SFT | pll_code.k_code); | ||
1062 | snd_soc_write(codec, RT5660_PLL_CTRL2, | ||
1063 | (pll_code.m_bp ? 0 : pll_code.m_code) << RT5660_PLL_M_SFT | | ||
1064 | pll_code.m_bp << RT5660_PLL_M_BP_SFT); | ||
1065 | |||
1066 | rt5660->pll_in = freq_in; | ||
1067 | rt5660->pll_out = freq_out; | ||
1068 | rt5660->pll_src = source; | ||
1069 | |||
1070 | return 0; | ||
1071 | } | ||
1072 | |||
1073 | static int rt5660_set_bias_level(struct snd_soc_codec *codec, | ||
1074 | enum snd_soc_bias_level level) | ||
1075 | { | ||
1076 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
1077 | int ret; | ||
1078 | |||
1079 | switch (level) { | ||
1080 | case SND_SOC_BIAS_ON: | ||
1081 | break; | ||
1082 | |||
1083 | case SND_SOC_BIAS_PREPARE: | ||
1084 | snd_soc_update_bits(codec, RT5660_GEN_CTRL1, | ||
1085 | RT5660_DIG_GATE_CTRL, RT5660_DIG_GATE_CTRL); | ||
1086 | |||
1087 | if (IS_ERR(rt5660->mclk)) | ||
1088 | break; | ||
1089 | |||
1090 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) { | ||
1091 | clk_disable_unprepare(rt5660->mclk); | ||
1092 | } else { | ||
1093 | ret = clk_prepare_enable(rt5660->mclk); | ||
1094 | if (ret) | ||
1095 | return ret; | ||
1096 | } | ||
1097 | break; | ||
1098 | |||
1099 | case SND_SOC_BIAS_STANDBY: | ||
1100 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { | ||
1101 | snd_soc_update_bits(codec, RT5660_PWR_ANLG1, | ||
1102 | RT5660_PWR_VREF1 | RT5660_PWR_MB | | ||
1103 | RT5660_PWR_BG | RT5660_PWR_VREF2, | ||
1104 | RT5660_PWR_VREF1 | RT5660_PWR_MB | | ||
1105 | RT5660_PWR_BG | RT5660_PWR_VREF2); | ||
1106 | usleep_range(10000, 15000); | ||
1107 | snd_soc_update_bits(codec, RT5660_PWR_ANLG1, | ||
1108 | RT5660_PWR_FV1 | RT5660_PWR_FV2, | ||
1109 | RT5660_PWR_FV1 | RT5660_PWR_FV2); | ||
1110 | } | ||
1111 | break; | ||
1112 | |||
1113 | case SND_SOC_BIAS_OFF: | ||
1114 | snd_soc_update_bits(codec, RT5660_GEN_CTRL1, | ||
1115 | RT5660_DIG_GATE_CTRL, 0); | ||
1116 | break; | ||
1117 | |||
1118 | default: | ||
1119 | break; | ||
1120 | } | ||
1121 | |||
1122 | return 0; | ||
1123 | } | ||
1124 | |||
1125 | static int rt5660_probe(struct snd_soc_codec *codec) | ||
1126 | { | ||
1127 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
1128 | |||
1129 | rt5660->codec = codec; | ||
1130 | |||
1131 | return 0; | ||
1132 | } | ||
1133 | |||
1134 | static int rt5660_remove(struct snd_soc_codec *codec) | ||
1135 | { | ||
1136 | return snd_soc_write(codec, RT5660_RESET, 0); | ||
1137 | } | ||
1138 | |||
1139 | #ifdef CONFIG_PM | ||
1140 | static int rt5660_suspend(struct snd_soc_codec *codec) | ||
1141 | { | ||
1142 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
1143 | |||
1144 | regcache_cache_only(rt5660->regmap, true); | ||
1145 | regcache_mark_dirty(rt5660->regmap); | ||
1146 | |||
1147 | return 0; | ||
1148 | } | ||
1149 | |||
1150 | static int rt5660_resume(struct snd_soc_codec *codec) | ||
1151 | { | ||
1152 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
1153 | |||
1154 | if (rt5660->pdata.poweroff_codec_in_suspend) | ||
1155 | usleep_range(350000, 400000); | ||
1156 | |||
1157 | regcache_cache_only(rt5660->regmap, false); | ||
1158 | regcache_sync(rt5660->regmap); | ||
1159 | |||
1160 | return 0; | ||
1161 | } | ||
1162 | #else | ||
1163 | #define rt5660_suspend NULL | ||
1164 | #define rt5660_resume NULL | ||
1165 | #endif | ||
1166 | |||
1167 | #define RT5660_STEREO_RATES SNDRV_PCM_RATE_8000_192000 | ||
1168 | #define RT5660_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
1169 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) | ||
1170 | |||
1171 | static const struct snd_soc_dai_ops rt5660_aif_dai_ops = { | ||
1172 | .hw_params = rt5660_hw_params, | ||
1173 | .set_fmt = rt5660_set_dai_fmt, | ||
1174 | .set_sysclk = rt5660_set_dai_sysclk, | ||
1175 | .set_pll = rt5660_set_dai_pll, | ||
1176 | }; | ||
1177 | |||
1178 | static struct snd_soc_dai_driver rt5660_dai[] = { | ||
1179 | { | ||
1180 | .name = "rt5660-aif1", | ||
1181 | .id = RT5660_AIF1, | ||
1182 | .playback = { | ||
1183 | .stream_name = "AIF1 Playback", | ||
1184 | .channels_min = 1, | ||
1185 | .channels_max = 2, | ||
1186 | .rates = RT5660_STEREO_RATES, | ||
1187 | .formats = RT5660_FORMATS, | ||
1188 | }, | ||
1189 | .capture = { | ||
1190 | .stream_name = "AIF1 Capture", | ||
1191 | .channels_min = 1, | ||
1192 | .channels_max = 2, | ||
1193 | .rates = RT5660_STEREO_RATES, | ||
1194 | .formats = RT5660_FORMATS, | ||
1195 | }, | ||
1196 | .ops = &rt5660_aif_dai_ops, | ||
1197 | }, | ||
1198 | }; | ||
1199 | |||
1200 | static struct snd_soc_codec_driver soc_codec_dev_rt5660 = { | ||
1201 | .probe = rt5660_probe, | ||
1202 | .remove = rt5660_remove, | ||
1203 | .suspend = rt5660_suspend, | ||
1204 | .resume = rt5660_resume, | ||
1205 | .set_bias_level = rt5660_set_bias_level, | ||
1206 | .idle_bias_off = true, | ||
1207 | .component_driver = { | ||
1208 | .controls = rt5660_snd_controls, | ||
1209 | .num_controls = ARRAY_SIZE(rt5660_snd_controls), | ||
1210 | .dapm_widgets = rt5660_dapm_widgets, | ||
1211 | .num_dapm_widgets = ARRAY_SIZE(rt5660_dapm_widgets), | ||
1212 | .dapm_routes = rt5660_dapm_routes, | ||
1213 | .num_dapm_routes = ARRAY_SIZE(rt5660_dapm_routes), | ||
1214 | }, | ||
1215 | }; | ||
1216 | |||
1217 | static const struct regmap_config rt5660_regmap = { | ||
1218 | .reg_bits = 8, | ||
1219 | .val_bits = 16, | ||
1220 | .use_single_rw = true, | ||
1221 | |||
1222 | .max_register = RT5660_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5660_ranges) * | ||
1223 | RT5660_PR_SPACING), | ||
1224 | .volatile_reg = rt5660_volatile_register, | ||
1225 | .readable_reg = rt5660_readable_register, | ||
1226 | |||
1227 | .cache_type = REGCACHE_RBTREE, | ||
1228 | .reg_defaults = rt5660_reg, | ||
1229 | .num_reg_defaults = ARRAY_SIZE(rt5660_reg), | ||
1230 | .ranges = rt5660_ranges, | ||
1231 | .num_ranges = ARRAY_SIZE(rt5660_ranges), | ||
1232 | }; | ||
1233 | |||
1234 | static const struct i2c_device_id rt5660_i2c_id[] = { | ||
1235 | { "rt5660", 0 }, | ||
1236 | { } | ||
1237 | }; | ||
1238 | MODULE_DEVICE_TABLE(i2c, rt5660_i2c_id); | ||
1239 | |||
1240 | static const struct of_device_id rt5660_of_match[] = { | ||
1241 | { .compatible = "realtek,rt5660", }, | ||
1242 | {}, | ||
1243 | }; | ||
1244 | MODULE_DEVICE_TABLE(of, rt5660_of_match); | ||
1245 | |||
1246 | static const struct acpi_device_id rt5660_acpi_match[] = { | ||
1247 | { "10EC5660", 0 }, | ||
1248 | { }, | ||
1249 | }; | ||
1250 | MODULE_DEVICE_TABLE(acpi, rt5660_acpi_match); | ||
1251 | |||
1252 | static int rt5660_parse_dt(struct rt5660_priv *rt5660, struct device *dev) | ||
1253 | { | ||
1254 | rt5660->pdata.in1_diff = device_property_read_bool(dev, | ||
1255 | "realtek,in1-differential"); | ||
1256 | rt5660->pdata.in3_diff = device_property_read_bool(dev, | ||
1257 | "realtek,in3-differential"); | ||
1258 | rt5660->pdata.poweroff_codec_in_suspend = device_property_read_bool(dev, | ||
1259 | "realtek,poweroff-in-suspend"); | ||
1260 | device_property_read_u32(dev, "realtek,dmic1-data-pin", | ||
1261 | &rt5660->pdata.dmic1_data_pin); | ||
1262 | |||
1263 | return 0; | ||
1264 | } | ||
1265 | |||
1266 | static int rt5660_i2c_probe(struct i2c_client *i2c, | ||
1267 | const struct i2c_device_id *id) | ||
1268 | { | ||
1269 | struct rt5660_platform_data *pdata = dev_get_platdata(&i2c->dev); | ||
1270 | struct rt5660_priv *rt5660; | ||
1271 | int ret; | ||
1272 | unsigned int val; | ||
1273 | |||
1274 | rt5660 = devm_kzalloc(&i2c->dev, sizeof(struct rt5660_priv), | ||
1275 | GFP_KERNEL); | ||
1276 | |||
1277 | if (rt5660 == NULL) | ||
1278 | return -ENOMEM; | ||
1279 | |||
1280 | /* Check if MCLK provided */ | ||
1281 | rt5660->mclk = devm_clk_get(&i2c->dev, "mclk"); | ||
1282 | if (PTR_ERR(rt5660->mclk) == -EPROBE_DEFER) | ||
1283 | return -EPROBE_DEFER; | ||
1284 | |||
1285 | i2c_set_clientdata(i2c, rt5660); | ||
1286 | |||
1287 | if (pdata) | ||
1288 | rt5660->pdata = *pdata; | ||
1289 | else if (i2c->dev.of_node) | ||
1290 | rt5660_parse_dt(rt5660, &i2c->dev); | ||
1291 | |||
1292 | rt5660->regmap = devm_regmap_init_i2c(i2c, &rt5660_regmap); | ||
1293 | if (IS_ERR(rt5660->regmap)) { | ||
1294 | ret = PTR_ERR(rt5660->regmap); | ||
1295 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | ||
1296 | ret); | ||
1297 | return ret; | ||
1298 | } | ||
1299 | |||
1300 | regmap_read(rt5660->regmap, RT5660_VENDOR_ID2, &val); | ||
1301 | if (val != RT5660_DEVICE_ID) { | ||
1302 | dev_err(&i2c->dev, | ||
1303 | "Device with ID register %#x is not rt5660\n", val); | ||
1304 | return -ENODEV; | ||
1305 | } | ||
1306 | |||
1307 | regmap_write(rt5660->regmap, RT5660_RESET, 0); | ||
1308 | |||
1309 | ret = regmap_register_patch(rt5660->regmap, rt5660_patch, | ||
1310 | ARRAY_SIZE(rt5660_patch)); | ||
1311 | if (ret != 0) | ||
1312 | dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret); | ||
1313 | |||
1314 | if (rt5660->pdata.dmic1_data_pin) { | ||
1315 | regmap_update_bits(rt5660->regmap, RT5660_GPIO_CTRL1, | ||
1316 | RT5660_GP1_PIN_MASK, RT5660_GP1_PIN_DMIC1_SCL); | ||
1317 | |||
1318 | if (rt5660->pdata.dmic1_data_pin == RT5660_DMIC1_DATA_GPIO2) | ||
1319 | regmap_update_bits(rt5660->regmap, RT5660_DMIC_CTRL1, | ||
1320 | RT5660_SEL_DMIC_DATA_MASK, | ||
1321 | RT5660_SEL_DMIC_DATA_GPIO2); | ||
1322 | else if (rt5660->pdata.dmic1_data_pin == RT5660_DMIC1_DATA_IN1P) | ||
1323 | regmap_update_bits(rt5660->regmap, RT5660_DMIC_CTRL1, | ||
1324 | RT5660_SEL_DMIC_DATA_MASK, | ||
1325 | RT5660_SEL_DMIC_DATA_IN1P); | ||
1326 | } | ||
1327 | |||
1328 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5660, | ||
1329 | rt5660_dai, ARRAY_SIZE(rt5660_dai)); | ||
1330 | } | ||
1331 | |||
1332 | static int rt5660_i2c_remove(struct i2c_client *i2c) | ||
1333 | { | ||
1334 | snd_soc_unregister_codec(&i2c->dev); | ||
1335 | |||
1336 | return 0; | ||
1337 | } | ||
1338 | |||
1339 | static struct i2c_driver rt5660_i2c_driver = { | ||
1340 | .driver = { | ||
1341 | .name = "rt5660", | ||
1342 | .acpi_match_table = ACPI_PTR(rt5660_acpi_match), | ||
1343 | .of_match_table = of_match_ptr(rt5660_of_match), | ||
1344 | }, | ||
1345 | .probe = rt5660_i2c_probe, | ||
1346 | .remove = rt5660_i2c_remove, | ||
1347 | .id_table = rt5660_i2c_id, | ||
1348 | }; | ||
1349 | module_i2c_driver(rt5660_i2c_driver); | ||
1350 | |||
1351 | MODULE_DESCRIPTION("ASoC RT5660 driver"); | ||
1352 | MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>"); | ||
1353 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/rt5660.h b/sound/soc/codecs/rt5660.h new file mode 100644 index 000000000000..6cdb9269ec9e --- /dev/null +++ b/sound/soc/codecs/rt5660.h | |||
@@ -0,0 +1,847 @@ | |||
1 | /* | ||
2 | * rt5660.h -- RT5660 ALSA SoC audio driver | ||
3 | * | ||
4 | * Copyright 2016 Realtek Semiconductor Corp. | ||
5 | * Author: Oder Chiou <oder_chiou@realtek.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 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef _RT5660_H | ||
13 | #define _RT5660_H | ||
14 | |||
15 | #include <linux/clk.h> | ||
16 | #include <sound/rt5660.h> | ||
17 | |||
18 | /* Info */ | ||
19 | #define RT5660_RESET 0x00 | ||
20 | #define RT5660_VENDOR_ID 0xfd | ||
21 | #define RT5660_VENDOR_ID1 0xfe | ||
22 | #define RT5660_VENDOR_ID2 0xff | ||
23 | /* I/O - Output */ | ||
24 | #define RT5660_SPK_VOL 0x01 | ||
25 | #define RT5660_LOUT_VOL 0x02 | ||
26 | /* I/O - Input */ | ||
27 | #define RT5660_IN1_IN2 0x0d | ||
28 | #define RT5660_IN3_IN4 0x0e | ||
29 | /* I/O - ADC/DAC/DMIC */ | ||
30 | #define RT5660_DAC1_DIG_VOL 0x19 | ||
31 | #define RT5660_STO1_ADC_DIG_VOL 0x1c | ||
32 | #define RT5660_ADC_BST_VOL1 0x1e | ||
33 | /* Mixer - D-D */ | ||
34 | #define RT5660_STO1_ADC_MIXER 0x27 | ||
35 | #define RT5660_AD_DA_MIXER 0x29 | ||
36 | #define RT5660_STO_DAC_MIXER 0x2a | ||
37 | #define RT5660_DIG_INF1_DATA 0x2f | ||
38 | /* Mixer - ADC */ | ||
39 | #define RT5660_REC_L1_MIXER 0x3b | ||
40 | #define RT5660_REC_L2_MIXER 0x3c | ||
41 | #define RT5660_REC_R1_MIXER 0x3d | ||
42 | #define RT5660_REC_R2_MIXER 0x3e | ||
43 | /* Mixer - DAC */ | ||
44 | #define RT5660_LOUT_MIXER 0x45 | ||
45 | #define RT5660_SPK_MIXER 0x46 | ||
46 | #define RT5660_SPO_MIXER 0x48 | ||
47 | #define RT5660_SPO_CLSD_RATIO 0x4a | ||
48 | #define RT5660_OUT_L_GAIN1 0x4d | ||
49 | #define RT5660_OUT_L_GAIN2 0x4e | ||
50 | #define RT5660_OUT_L1_MIXER 0x4f | ||
51 | #define RT5660_OUT_R_GAIN1 0x50 | ||
52 | #define RT5660_OUT_R_GAIN2 0x51 | ||
53 | #define RT5660_OUT_R1_MIXER 0x52 | ||
54 | /* Power */ | ||
55 | #define RT5660_PWR_DIG1 0x61 | ||
56 | #define RT5660_PWR_DIG2 0x62 | ||
57 | #define RT5660_PWR_ANLG1 0x63 | ||
58 | #define RT5660_PWR_ANLG2 0x64 | ||
59 | #define RT5660_PWR_MIXER 0x65 | ||
60 | #define RT5660_PWR_VOL 0x66 | ||
61 | /* Private Register Control */ | ||
62 | #define RT5660_PRIV_INDEX 0x6a | ||
63 | #define RT5660_PRIV_DATA 0x6c | ||
64 | /* Format - ADC/DAC */ | ||
65 | #define RT5660_I2S1_SDP 0x70 | ||
66 | #define RT5660_ADDA_CLK1 0x73 | ||
67 | #define RT5660_ADDA_CLK2 0x74 | ||
68 | #define RT5660_DMIC_CTRL1 0x75 | ||
69 | /* Function - Analog */ | ||
70 | #define RT5660_GLB_CLK 0x80 | ||
71 | #define RT5660_PLL_CTRL1 0x81 | ||
72 | #define RT5660_PLL_CTRL2 0x82 | ||
73 | #define RT5660_CLSD_AMP_OC_CTRL 0x8c | ||
74 | #define RT5660_CLSD_AMP_CTRL 0x8d | ||
75 | #define RT5660_LOUT_AMP_CTRL 0x8e | ||
76 | #define RT5660_SPK_AMP_SPKVDD 0x92 | ||
77 | #define RT5660_MICBIAS 0x93 | ||
78 | #define RT5660_CLSD_OUT_CTRL1 0xa1 | ||
79 | #define RT5660_CLSD_OUT_CTRL2 0xa2 | ||
80 | #define RT5660_DIPOLE_MIC_CTRL1 0xa3 | ||
81 | #define RT5660_DIPOLE_MIC_CTRL2 0xa4 | ||
82 | #define RT5660_DIPOLE_MIC_CTRL3 0xa5 | ||
83 | #define RT5660_DIPOLE_MIC_CTRL4 0xa6 | ||
84 | #define RT5660_DIPOLE_MIC_CTRL5 0xa7 | ||
85 | #define RT5660_DIPOLE_MIC_CTRL6 0xa8 | ||
86 | #define RT5660_DIPOLE_MIC_CTRL7 0xa9 | ||
87 | #define RT5660_DIPOLE_MIC_CTRL8 0xaa | ||
88 | #define RT5660_DIPOLE_MIC_CTRL9 0xab | ||
89 | #define RT5660_DIPOLE_MIC_CTRL10 0xac | ||
90 | #define RT5660_DIPOLE_MIC_CTRL11 0xad | ||
91 | #define RT5660_DIPOLE_MIC_CTRL12 0xae | ||
92 | /* Function - Digital */ | ||
93 | #define RT5660_EQ_CTRL1 0xb0 | ||
94 | #define RT5660_EQ_CTRL2 0xb1 | ||
95 | #define RT5660_DRC_AGC_CTRL1 0xb3 | ||
96 | #define RT5660_DRC_AGC_CTRL2 0xb4 | ||
97 | #define RT5660_DRC_AGC_CTRL3 0xb5 | ||
98 | #define RT5660_DRC_AGC_CTRL4 0xb6 | ||
99 | #define RT5660_DRC_AGC_CTRL5 0xb7 | ||
100 | #define RT5660_JD_CTRL 0xbb | ||
101 | #define RT5660_IRQ_CTRL1 0xbd | ||
102 | #define RT5660_IRQ_CTRL2 0xbe | ||
103 | #define RT5660_INT_IRQ_ST 0xbf | ||
104 | #define RT5660_GPIO_CTRL1 0xc0 | ||
105 | #define RT5660_GPIO_CTRL2 0xc2 | ||
106 | #define RT5660_WIND_FILTER_CTRL1 0xd3 | ||
107 | #define RT5660_SV_ZCD1 0xd9 | ||
108 | #define RT5660_SV_ZCD2 0xda | ||
109 | #define RT5660_DRC1_LM_CTRL1 0xe0 | ||
110 | #define RT5660_DRC1_LM_CTRL2 0xe1 | ||
111 | #define RT5660_DRC2_LM_CTRL1 0xe2 | ||
112 | #define RT5660_DRC2_LM_CTRL2 0xe3 | ||
113 | #define RT5660_MULTI_DRC_CTRL 0xe4 | ||
114 | #define RT5660_DRC2_CTRL1 0xe5 | ||
115 | #define RT5660_DRC2_CTRL2 0xe6 | ||
116 | #define RT5660_DRC2_CTRL3 0xe7 | ||
117 | #define RT5660_DRC2_CTRL4 0xe8 | ||
118 | #define RT5660_DRC2_CTRL5 0xe9 | ||
119 | #define RT5660_ALC_PGA_CTRL1 0xea | ||
120 | #define RT5660_ALC_PGA_CTRL2 0xeb | ||
121 | #define RT5660_ALC_PGA_CTRL3 0xec | ||
122 | #define RT5660_ALC_PGA_CTRL4 0xed | ||
123 | #define RT5660_ALC_PGA_CTRL5 0xee | ||
124 | #define RT5660_ALC_PGA_CTRL6 0xef | ||
125 | #define RT5660_ALC_PGA_CTRL7 0xf0 | ||
126 | |||
127 | /* General Control */ | ||
128 | #define RT5660_GEN_CTRL1 0xfa | ||
129 | #define RT5660_GEN_CTRL2 0xfb | ||
130 | #define RT5660_GEN_CTRL3 0xfc | ||
131 | |||
132 | /* Index of Codec Private Register definition */ | ||
133 | #define RT5660_CHOP_DAC_ADC 0x3d | ||
134 | |||
135 | /* Global Definition */ | ||
136 | #define RT5660_L_MUTE (0x1 << 15) | ||
137 | #define RT5660_L_MUTE_SFT 15 | ||
138 | #define RT5660_VOL_L_MUTE (0x1 << 14) | ||
139 | #define RT5660_VOL_L_SFT 14 | ||
140 | #define RT5660_R_MUTE (0x1 << 7) | ||
141 | #define RT5660_R_MUTE_SFT 7 | ||
142 | #define RT5660_VOL_R_MUTE (0x1 << 6) | ||
143 | #define RT5660_VOL_R_SFT 6 | ||
144 | #define RT5660_L_VOL_MASK (0x3f << 8) | ||
145 | #define RT5660_L_VOL_SFT 8 | ||
146 | #define RT5660_R_VOL_MASK (0x3f) | ||
147 | #define RT5660_R_VOL_SFT 0 | ||
148 | |||
149 | /* IN1 and IN2 Control (0x0d) */ | ||
150 | #define RT5660_IN_DF1 (0x1 << 15) | ||
151 | #define RT5660_IN_SFT1 15 | ||
152 | #define RT5660_BST_MASK1 (0x7f << 8) | ||
153 | #define RT5660_BST_SFT1 8 | ||
154 | #define RT5660_IN_DF2 (0x1 << 7) | ||
155 | #define RT5660_IN_SFT2 7 | ||
156 | #define RT5660_BST_MASK2 (0x7f << 0) | ||
157 | #define RT5660_BST_SFT2 0 | ||
158 | |||
159 | /* IN3 and IN4 Control (0x0e) */ | ||
160 | #define RT5660_IN_DF3 (0x1 << 15) | ||
161 | #define RT5660_IN_SFT3 15 | ||
162 | #define RT5660_BST_MASK3 (0x7f << 8) | ||
163 | #define RT5660_BST_SFT3 8 | ||
164 | #define RT5660_IN_DF4 (0x1 << 7) | ||
165 | #define RT5660_IN_SFT4 7 | ||
166 | #define RT5660_BST_MASK4 (0x7f << 0) | ||
167 | #define RT5660_BST_SFT4 0 | ||
168 | |||
169 | /* DAC1 Digital Volume (0x19) */ | ||
170 | #define RT5660_DAC_L1_VOL_MASK (0x7f << 9) | ||
171 | #define RT5660_DAC_L1_VOL_SFT 9 | ||
172 | #define RT5660_DAC_R1_VOL_MASK (0x7f << 1) | ||
173 | #define RT5660_DAC_R1_VOL_SFT 1 | ||
174 | |||
175 | /* ADC Digital Volume Control (0x1c) */ | ||
176 | #define RT5660_ADC_L_VOL_MASK (0x3f << 9) | ||
177 | #define RT5660_ADC_L_VOL_SFT 9 | ||
178 | #define RT5660_ADC_R_VOL_MASK (0x3f << 1) | ||
179 | #define RT5660_ADC_R_VOL_SFT 1 | ||
180 | |||
181 | /* ADC Boost Volume Control (0x1e) */ | ||
182 | #define RT5660_STO1_ADC_L_BST_MASK (0x3 << 14) | ||
183 | #define RT5660_STO1_ADC_L_BST_SFT 14 | ||
184 | #define RT5660_STO1_ADC_R_BST_MASK (0x3 << 12) | ||
185 | #define RT5660_STO1_ADC_R_BST_SFT 12 | ||
186 | |||
187 | /* Stereo ADC Mixer Control (0x27) */ | ||
188 | #define RT5660_M_ADC_L1 (0x1 << 14) | ||
189 | #define RT5660_M_ADC_L1_SFT 14 | ||
190 | #define RT5660_M_ADC_L2 (0x1 << 13) | ||
191 | #define RT5660_M_ADC_L2_SFT 13 | ||
192 | #define RT5660_M_ADC_R1 (0x1 << 6) | ||
193 | #define RT5660_M_ADC_R1_SFT 6 | ||
194 | #define RT5660_M_ADC_R2 (0x1 << 5) | ||
195 | #define RT5660_M_ADC_R2_SFT 5 | ||
196 | |||
197 | /* ADC Mixer to DAC Mixer Control (0x29) */ | ||
198 | #define RT5660_M_ADCMIX_L (0x1 << 15) | ||
199 | #define RT5660_M_ADCMIX_L_SFT 15 | ||
200 | #define RT5660_M_DAC1_L (0x1 << 14) | ||
201 | #define RT5660_M_DAC1_L_SFT 14 | ||
202 | #define RT5660_M_ADCMIX_R (0x1 << 7) | ||
203 | #define RT5660_M_ADCMIX_R_SFT 7 | ||
204 | #define RT5660_M_DAC1_R (0x1 << 6) | ||
205 | #define RT5660_M_DAC1_R_SFT 6 | ||
206 | |||
207 | /* Stereo DAC Mixer Control (0x2a) */ | ||
208 | #define RT5660_M_DAC_L1 (0x1 << 14) | ||
209 | #define RT5660_M_DAC_L1_SFT 14 | ||
210 | #define RT5660_DAC_L1_STO_L_VOL_MASK (0x1 << 13) | ||
211 | #define RT5660_DAC_L1_STO_L_VOL_SFT 13 | ||
212 | #define RT5660_M_DAC_R1_STO_L (0x1 << 9) | ||
213 | #define RT5660_M_DAC_R1_STO_L_SFT 9 | ||
214 | #define RT5660_DAC_R1_STO_L_VOL_MASK (0x1 << 8) | ||
215 | #define RT5660_DAC_R1_STO_L_VOL_SFT 8 | ||
216 | #define RT5660_M_DAC_R1 (0x1 << 6) | ||
217 | #define RT5660_M_DAC_R1_SFT 6 | ||
218 | #define RT5660_DAC_R1_STO_R_VOL_MASK (0x1 << 5) | ||
219 | #define RT5660_DAC_R1_STO_R_VOL_SFT 5 | ||
220 | #define RT5660_M_DAC_L1_STO_R (0x1 << 1) | ||
221 | #define RT5660_M_DAC_L1_STO_R_SFT 1 | ||
222 | #define RT5660_DAC_L1_STO_R_VOL_MASK (0x1) | ||
223 | #define RT5660_DAC_L1_STO_R_VOL_SFT 0 | ||
224 | |||
225 | /* Digital Interface Data Control (0x2f) */ | ||
226 | #define RT5660_IF1_DAC_IN_SEL (0x3 << 14) | ||
227 | #define RT5660_IF1_DAC_IN_SFT 14 | ||
228 | #define RT5660_IF1_ADC_IN_SEL (0x3 << 12) | ||
229 | #define RT5660_IF1_ADC_IN_SFT 12 | ||
230 | |||
231 | /* REC Left Mixer Control 1 (0x3b) */ | ||
232 | #define RT5660_G_BST3_RM_L_MASK (0x7 << 4) | ||
233 | #define RT5660_G_BST3_RM_L_SFT 4 | ||
234 | #define RT5660_G_BST2_RM_L_MASK (0x7 << 1) | ||
235 | #define RT5660_G_BST2_RM_L_SFT 1 | ||
236 | |||
237 | /* REC Left Mixer Control 2 (0x3c) */ | ||
238 | #define RT5660_G_BST1_RM_L_MASK (0x7 << 13) | ||
239 | #define RT5660_G_BST1_RM_L_SFT 13 | ||
240 | #define RT5660_G_OM_L_RM_L_MASK (0x7 << 10) | ||
241 | #define RT5660_G_OM_L_RM_L_SFT 10 | ||
242 | #define RT5660_M_BST3_RM_L (0x1 << 3) | ||
243 | #define RT5660_M_BST3_RM_L_SFT 3 | ||
244 | #define RT5660_M_BST2_RM_L (0x1 << 2) | ||
245 | #define RT5660_M_BST2_RM_L_SFT 2 | ||
246 | #define RT5660_M_BST1_RM_L (0x1 << 1) | ||
247 | #define RT5660_M_BST1_RM_L_SFT 1 | ||
248 | #define RT5660_M_OM_L_RM_L (0x1) | ||
249 | #define RT5660_M_OM_L_RM_L_SFT 0 | ||
250 | |||
251 | /* REC Right Mixer Control 1 (0x3d) */ | ||
252 | #define RT5660_G_BST3_RM_R_MASK (0x7 << 4) | ||
253 | #define RT5660_G_BST3_RM_R_SFT 4 | ||
254 | #define RT5660_G_BST2_RM_R_MASK (0x7 << 1) | ||
255 | #define RT5660_G_BST2_RM_R_SFT 1 | ||
256 | |||
257 | /* REC Right Mixer Control 2 (0x3e) */ | ||
258 | #define RT5660_G_BST1_RM_R_MASK (0x7 << 13) | ||
259 | #define RT5660_G_BST1_RM_R_SFT 13 | ||
260 | #define RT5660_G_OM_R_RM_R_MASK (0x7 << 10) | ||
261 | #define RT5660_G_OM_R_RM_R_SFT 10 | ||
262 | #define RT5660_M_BST3_RM_R (0x1 << 3) | ||
263 | #define RT5660_M_BST3_RM_R_SFT 3 | ||
264 | #define RT5660_M_BST2_RM_R (0x1 << 2) | ||
265 | #define RT5660_M_BST2_RM_R_SFT 2 | ||
266 | #define RT5660_M_BST1_RM_R (0x1 << 1) | ||
267 | #define RT5660_M_BST1_RM_R_SFT 1 | ||
268 | #define RT5660_M_OM_R_RM_R (0x1) | ||
269 | #define RT5660_M_OM_R_RM_R_SFT 0 | ||
270 | |||
271 | /* LOUTMIX Control (0x45) */ | ||
272 | #define RT5660_M_DAC1_LM (0x1 << 14) | ||
273 | #define RT5660_M_DAC1_LM_SFT 14 | ||
274 | #define RT5660_M_LOVOL_M (0x1 << 13) | ||
275 | #define RT5660_M_LOVOL_LM_SFT 13 | ||
276 | |||
277 | /* SPK Mixer Control (0x46) */ | ||
278 | #define RT5660_G_BST3_SM_MASK (0x3 << 14) | ||
279 | #define RT5660_G_BST3_SM_SFT 14 | ||
280 | #define RT5660_G_BST1_SM_MASK (0x3 << 12) | ||
281 | #define RT5660_G_BST1_SM_SFT 12 | ||
282 | #define RT5660_G_DACl_SM_MASK (0x3 << 10) | ||
283 | #define RT5660_G_DACl_SM_SFT 10 | ||
284 | #define RT5660_G_DACR_SM_MASK (0x3 << 8) | ||
285 | #define RT5660_G_DACR_SM_SFT 8 | ||
286 | #define RT5660_G_OM_L_SM_MASK (0x3 << 6) | ||
287 | #define RT5660_G_OM_L_SM_SFT 6 | ||
288 | #define RT5660_M_DACR_SM (0x1 << 5) | ||
289 | #define RT5660_M_DACR_SM_SFT 5 | ||
290 | #define RT5660_M_BST1_SM (0x1 << 4) | ||
291 | #define RT5660_M_BST1_SM_SFT 4 | ||
292 | #define RT5660_M_BST3_SM (0x1 << 3) | ||
293 | #define RT5660_M_BST3_SM_SFT 3 | ||
294 | #define RT5660_M_DACL_SM (0x1 << 2) | ||
295 | #define RT5660_M_DACL_SM_SFT 2 | ||
296 | #define RT5660_M_OM_L_SM (0x1 << 1) | ||
297 | #define RT5660_M_OM_L_SM_SFT 1 | ||
298 | |||
299 | /* SPOMIX Control (0x48) */ | ||
300 | #define RT5660_M_DAC_R_SPM (0x1 << 14) | ||
301 | #define RT5660_M_DAC_R_SPM_SFT 14 | ||
302 | #define RT5660_M_DAC_L_SPM (0x1 << 13) | ||
303 | #define RT5660_M_DAC_L_SPM_SFT 13 | ||
304 | #define RT5660_M_SV_SPM (0x1 << 12) | ||
305 | #define RT5660_M_SV_SPM_SFT 12 | ||
306 | #define RT5660_M_BST1_SPM (0x1 << 11) | ||
307 | #define RT5660_M_BST1_SPM_SFT 11 | ||
308 | |||
309 | /* Output Left Mixer Control 1 (0x4d) */ | ||
310 | #define RT5660_G_BST3_OM_L_MASK (0x7 << 13) | ||
311 | #define RT5660_G_BST3_OM_L_SFT 13 | ||
312 | #define RT5660_G_BST2_OM_L_MASK (0x7 << 10) | ||
313 | #define RT5660_G_BST2_OM_L_SFT 10 | ||
314 | #define RT5660_G_BST1_OM_L_MASK (0x7 << 7) | ||
315 | #define RT5660_G_BST1_OM_L_SFT 7 | ||
316 | #define RT5660_G_RM_L_OM_L_MASK (0x7 << 1) | ||
317 | #define RT5660_G_RM_L_OM_L_SFT 1 | ||
318 | |||
319 | /* Output Left Mixer Control 2 (0x4e) */ | ||
320 | #define RT5660_G_DAC_R1_OM_L_MASK (0x7 << 10) | ||
321 | #define RT5660_G_DAC_R1_OM_L_SFT 10 | ||
322 | #define RT5660_G_DAC_L1_OM_L_MASK (0x7 << 7) | ||
323 | #define RT5660_G_DAC_L1_OM_L_SFT 7 | ||
324 | |||
325 | /* Output Left Mixer Control 3 (0x4f) */ | ||
326 | #define RT5660_M_BST3_OM_L (0x1 << 5) | ||
327 | #define RT5660_M_BST3_OM_L_SFT 5 | ||
328 | #define RT5660_M_BST2_OM_L (0x1 << 4) | ||
329 | #define RT5660_M_BST2_OM_L_SFT 4 | ||
330 | #define RT5660_M_BST1_OM_L (0x1 << 3) | ||
331 | #define RT5660_M_BST1_OM_L_SFT 3 | ||
332 | #define RT5660_M_RM_L_OM_L (0x1 << 2) | ||
333 | #define RT5660_M_RM_L_OM_L_SFT 2 | ||
334 | #define RT5660_M_DAC_R_OM_L (0x1 << 1) | ||
335 | #define RT5660_M_DAC_R_OM_L_SFT 1 | ||
336 | #define RT5660_M_DAC_L_OM_L (0x1) | ||
337 | #define RT5660_M_DAC_L_OM_L_SFT 0 | ||
338 | |||
339 | /* Output Right Mixer Control 1 (0x50) */ | ||
340 | #define RT5660_G_BST2_OM_R_MASK (0x7 << 10) | ||
341 | #define RT5660_G_BST2_OM_R_SFT 10 | ||
342 | #define RT5660_G_BST1_OM_R_MASK (0x7 << 7) | ||
343 | #define RT5660_G_BST1_OM_R_SFT 7 | ||
344 | #define RT5660_G_RM_R_OM_R_MASK (0x7 << 1) | ||
345 | #define RT5660_G_RM_R_OM_R_SFT 1 | ||
346 | |||
347 | /* Output Right Mixer Control 2 (0x51) */ | ||
348 | #define RT5660_G_DAC_L_OM_R_MASK (0x7 << 10) | ||
349 | #define RT5660_G_DAC_L_OM_R_SFT 10 | ||
350 | #define RT5660_G_DAC_R_OM_R_MASK (0x7 << 7) | ||
351 | #define RT5660_G_DAC_R_OM_R_SFT 7 | ||
352 | |||
353 | /* Output Right Mixer Control 3 (0x52) */ | ||
354 | #define RT5660_M_BST2_OM_R (0x1 << 4) | ||
355 | #define RT5660_M_BST2_OM_R_SFT 4 | ||
356 | #define RT5660_M_BST1_OM_R (0x1 << 3) | ||
357 | #define RT5660_M_BST1_OM_R_SFT 3 | ||
358 | #define RT5660_M_RM_R_OM_R (0x1 << 2) | ||
359 | #define RT5660_M_RM_R_OM_R_SFT 2 | ||
360 | #define RT5660_M_DAC_L_OM_R (0x1 << 1) | ||
361 | #define RT5660_M_DAC_L_OM_R_SFT 1 | ||
362 | #define RT5660_M_DAC_R_OM_R (0x1) | ||
363 | #define RT5660_M_DAC_R_OM_R_SFT 0 | ||
364 | |||
365 | /* Power Management for Digital 1 (0x61) */ | ||
366 | #define RT5660_PWR_I2S1 (0x1 << 15) | ||
367 | #define RT5660_PWR_I2S1_BIT 15 | ||
368 | #define RT5660_PWR_DAC_L1 (0x1 << 12) | ||
369 | #define RT5660_PWR_DAC_L1_BIT 12 | ||
370 | #define RT5660_PWR_DAC_R1 (0x1 << 11) | ||
371 | #define RT5660_PWR_DAC_R1_BIT 11 | ||
372 | #define RT5660_PWR_ADC_L (0x1 << 2) | ||
373 | #define RT5660_PWR_ADC_L_BIT 2 | ||
374 | #define RT5660_PWR_ADC_R (0x1 << 1) | ||
375 | #define RT5660_PWR_ADC_R_BIT 1 | ||
376 | #define RT5660_PWR_CLS_D (0x1) | ||
377 | #define RT5660_PWR_CLS_D_BIT 0 | ||
378 | |||
379 | /* Power Management for Digital 2 (0x62) */ | ||
380 | #define RT5660_PWR_ADC_S1F (0x1 << 15) | ||
381 | #define RT5660_PWR_ADC_S1F_BIT 15 | ||
382 | #define RT5660_PWR_DAC_S1F (0x1 << 11) | ||
383 | #define RT5660_PWR_DAC_S1F_BIT 11 | ||
384 | |||
385 | /* Power Management for Analog 1 (0x63) */ | ||
386 | #define RT5660_PWR_VREF1 (0x1 << 15) | ||
387 | #define RT5660_PWR_VREF1_BIT 15 | ||
388 | #define RT5660_PWR_FV1 (0x1 << 14) | ||
389 | #define RT5660_PWR_FV1_BIT 14 | ||
390 | #define RT5660_PWR_MB (0x1 << 13) | ||
391 | #define RT5660_PWR_MB_BIT 13 | ||
392 | #define RT5660_PWR_BG (0x1 << 11) | ||
393 | #define RT5660_PWR_BG_BIT 11 | ||
394 | #define RT5660_PWR_HP_L (0x1 << 7) | ||
395 | #define RT5660_PWR_HP_L_BIT 7 | ||
396 | #define RT5660_PWR_HP_R (0x1 << 6) | ||
397 | #define RT5660_PWR_HP_R_BIT 6 | ||
398 | #define RT5660_PWR_HA (0x1 << 5) | ||
399 | #define RT5660_PWR_HA_BIT 5 | ||
400 | #define RT5660_PWR_VREF2 (0x1 << 4) | ||
401 | #define RT5660_PWR_VREF2_BIT 4 | ||
402 | #define RT5660_PWR_FV2 (0x1 << 3) | ||
403 | #define RT5660_PWR_FV2_BIT 3 | ||
404 | #define RT5660_PWR_LDO2 (0x1 << 2) | ||
405 | #define RT5660_PWR_LDO2_BIT 2 | ||
406 | |||
407 | /* Power Management for Analog 2 (0x64) */ | ||
408 | #define RT5660_PWR_BST1 (0x1 << 15) | ||
409 | #define RT5660_PWR_BST1_BIT 15 | ||
410 | #define RT5660_PWR_BST2 (0x1 << 14) | ||
411 | #define RT5660_PWR_BST2_BIT 14 | ||
412 | #define RT5660_PWR_BST3 (0x1 << 13) | ||
413 | #define RT5660_PWR_BST3_BIT 13 | ||
414 | #define RT5660_PWR_MB1 (0x1 << 11) | ||
415 | #define RT5660_PWR_MB1_BIT 11 | ||
416 | #define RT5660_PWR_MB2 (0x1 << 10) | ||
417 | #define RT5660_PWR_MB2_BIT 10 | ||
418 | #define RT5660_PWR_PLL (0x1 << 9) | ||
419 | #define RT5660_PWR_PLL_BIT 9 | ||
420 | |||
421 | /* Power Management for Mixer (0x65) */ | ||
422 | #define RT5660_PWR_OM_L (0x1 << 15) | ||
423 | #define RT5660_PWR_OM_L_BIT 15 | ||
424 | #define RT5660_PWR_OM_R (0x1 << 14) | ||
425 | #define RT5660_PWR_OM_R_BIT 14 | ||
426 | #define RT5660_PWR_SM (0x1 << 13) | ||
427 | #define RT5660_PWR_SM_BIT 13 | ||
428 | #define RT5660_PWR_RM_L (0x1 << 11) | ||
429 | #define RT5660_PWR_RM_L_BIT 11 | ||
430 | #define RT5660_PWR_RM_R (0x1 << 10) | ||
431 | #define RT5660_PWR_RM_R_BIT 10 | ||
432 | |||
433 | /* Power Management for Volume (0x66) */ | ||
434 | #define RT5660_PWR_SV (0x1 << 15) | ||
435 | #define RT5660_PWR_SV_BIT 15 | ||
436 | #define RT5660_PWR_LV_L (0x1 << 11) | ||
437 | #define RT5660_PWR_LV_L_BIT 11 | ||
438 | #define RT5660_PWR_LV_R (0x1 << 10) | ||
439 | #define RT5660_PWR_LV_R_BIT 10 | ||
440 | |||
441 | /* I2S1 Audio Serial Data Port Control (0x70) */ | ||
442 | #define RT5660_I2S_MS_MASK (0x1 << 15) | ||
443 | #define RT5660_I2S_MS_SFT 15 | ||
444 | #define RT5660_I2S_MS_M (0x0 << 15) | ||
445 | #define RT5660_I2S_MS_S (0x1 << 15) | ||
446 | #define RT5660_I2S_O_CP_MASK (0x3 << 10) | ||
447 | #define RT5660_I2S_O_CP_SFT 10 | ||
448 | #define RT5660_I2S_O_CP_OFF (0x0 << 10) | ||
449 | #define RT5660_I2S_O_CP_U_LAW (0x1 << 10) | ||
450 | #define RT5660_I2S_O_CP_A_LAW (0x2 << 10) | ||
451 | #define RT5660_I2S_I_CP_MASK (0x3 << 8) | ||
452 | #define RT5660_I2S_I_CP_SFT 8 | ||
453 | #define RT5660_I2S_I_CP_OFF (0x0 << 8) | ||
454 | #define RT5660_I2S_I_CP_U_LAW (0x1 << 8) | ||
455 | #define RT5660_I2S_I_CP_A_LAW (0x2 << 8) | ||
456 | #define RT5660_I2S_BP_MASK (0x1 << 7) | ||
457 | #define RT5660_I2S_BP_SFT 7 | ||
458 | #define RT5660_I2S_BP_NOR (0x0 << 7) | ||
459 | #define RT5660_I2S_BP_INV (0x1 << 7) | ||
460 | #define RT5660_I2S_DL_MASK (0x3 << 2) | ||
461 | #define RT5660_I2S_DL_SFT 2 | ||
462 | #define RT5660_I2S_DL_16 (0x0 << 2) | ||
463 | #define RT5660_I2S_DL_20 (0x1 << 2) | ||
464 | #define RT5660_I2S_DL_24 (0x2 << 2) | ||
465 | #define RT5660_I2S_DL_8 (0x3 << 2) | ||
466 | #define RT5660_I2S_DF_MASK (0x3) | ||
467 | #define RT5660_I2S_DF_SFT 0 | ||
468 | #define RT5660_I2S_DF_I2S (0x0) | ||
469 | #define RT5660_I2S_DF_LEFT (0x1) | ||
470 | #define RT5660_I2S_DF_PCM_A (0x2) | ||
471 | #define RT5660_I2S_DF_PCM_B (0x3) | ||
472 | |||
473 | /* ADC/DAC Clock Control 1 (0x73) */ | ||
474 | #define RT5660_I2S_BCLK_MS1_MASK (0x1 << 15) | ||
475 | #define RT5660_I2S_BCLK_MS1_SFT 15 | ||
476 | #define RT5660_I2S_BCLK_MS1_32 (0x0 << 15) | ||
477 | #define RT5660_I2S_BCLK_MS1_64 (0x1 << 15) | ||
478 | #define RT5660_I2S_PD1_MASK (0x7 << 12) | ||
479 | #define RT5660_I2S_PD1_SFT 12 | ||
480 | #define RT5660_I2S_PD1_1 (0x0 << 12) | ||
481 | #define RT5660_I2S_PD1_2 (0x1 << 12) | ||
482 | #define RT5660_I2S_PD1_3 (0x2 << 12) | ||
483 | #define RT5660_I2S_PD1_4 (0x3 << 12) | ||
484 | #define RT5660_I2S_PD1_6 (0x4 << 12) | ||
485 | #define RT5660_I2S_PD1_8 (0x5 << 12) | ||
486 | #define RT5660_I2S_PD1_12 (0x6 << 12) | ||
487 | #define RT5660_I2S_PD1_16 (0x7 << 12) | ||
488 | #define RT5660_DAC_OSR_MASK (0x3 << 2) | ||
489 | #define RT5660_DAC_OSR_SFT 2 | ||
490 | #define RT5660_DAC_OSR_128 (0x0 << 2) | ||
491 | #define RT5660_DAC_OSR_64 (0x1 << 2) | ||
492 | #define RT5660_DAC_OSR_32 (0x2 << 2) | ||
493 | #define RT5660_DAC_OSR_16 (0x3 << 2) | ||
494 | #define RT5660_ADC_OSR_MASK (0x3) | ||
495 | #define RT5660_ADC_OSR_SFT 0 | ||
496 | #define RT5660_ADC_OSR_128 (0x0) | ||
497 | #define RT5660_ADC_OSR_64 (0x1) | ||
498 | #define RT5660_ADC_OSR_32 (0x2) | ||
499 | #define RT5660_ADC_OSR_16 (0x3) | ||
500 | |||
501 | /* ADC/DAC Clock Control 2 (0x74) */ | ||
502 | #define RT5660_RESET_ADF (0x1 << 13) | ||
503 | #define RT5660_RESET_ADF_SFT 13 | ||
504 | #define RT5660_RESET_DAF (0x1 << 12) | ||
505 | #define RT5660_RESET_DAF_SFT 12 | ||
506 | #define RT5660_DAHPF_EN (0x1 << 11) | ||
507 | #define RT5660_DAHPF_EN_SFT 11 | ||
508 | #define RT5660_ADHPF_EN (0x1 << 10) | ||
509 | #define RT5660_ADHPF_EN_SFT 10 | ||
510 | |||
511 | /* Digital Microphone Control (0x75) */ | ||
512 | #define RT5660_DMIC_1_EN_MASK (0x1 << 15) | ||
513 | #define RT5660_DMIC_1_EN_SFT 15 | ||
514 | #define RT5660_DMIC_1_DIS (0x0 << 15) | ||
515 | #define RT5660_DMIC_1_EN (0x1 << 15) | ||
516 | #define RT5660_DMIC_1L_LH_MASK (0x1 << 13) | ||
517 | #define RT5660_DMIC_1L_LH_SFT 13 | ||
518 | #define RT5660_DMIC_1L_LH_RISING (0x0 << 13) | ||
519 | #define RT5660_DMIC_1L_LH_FALLING (0x1 << 13) | ||
520 | #define RT5660_DMIC_1R_LH_MASK (0x1 << 12) | ||
521 | #define RT5660_DMIC_1R_LH_SFT 12 | ||
522 | #define RT5660_DMIC_1R_LH_RISING (0x0 << 12) | ||
523 | #define RT5660_DMIC_1R_LH_FALLING (0x1 << 12) | ||
524 | #define RT5660_SEL_DMIC_DATA_MASK (0x1 << 11) | ||
525 | #define RT5660_SEL_DMIC_DATA_SFT 11 | ||
526 | #define RT5660_SEL_DMIC_DATA_GPIO2 (0x0 << 11) | ||
527 | #define RT5660_SEL_DMIC_DATA_IN1P (0x1 << 11) | ||
528 | #define RT5660_DMIC_CLK_MASK (0x7 << 5) | ||
529 | #define RT5660_DMIC_CLK_SFT 5 | ||
530 | |||
531 | /* Global Clock Control (0x80) */ | ||
532 | #define RT5660_SCLK_SRC_MASK (0x3 << 14) | ||
533 | #define RT5660_SCLK_SRC_SFT 14 | ||
534 | #define RT5660_SCLK_SRC_MCLK (0x0 << 14) | ||
535 | #define RT5660_SCLK_SRC_PLL1 (0x1 << 14) | ||
536 | #define RT5660_SCLK_SRC_RCCLK (0x2 << 14) | ||
537 | #define RT5660_PLL1_SRC_MASK (0x3 << 12) | ||
538 | #define RT5660_PLL1_SRC_SFT 12 | ||
539 | #define RT5660_PLL1_SRC_MCLK (0x0 << 12) | ||
540 | #define RT5660_PLL1_SRC_BCLK1 (0x1 << 12) | ||
541 | #define RT5660_PLL1_SRC_RCCLK (0x2 << 12) | ||
542 | #define RT5660_PLL1_PD_MASK (0x1 << 3) | ||
543 | #define RT5660_PLL1_PD_SFT 3 | ||
544 | #define RT5660_PLL1_PD_1 (0x0 << 3) | ||
545 | #define RT5660_PLL1_PD_2 (0x1 << 3) | ||
546 | |||
547 | #define RT5660_PLL_INP_MAX 40000000 | ||
548 | #define RT5660_PLL_INP_MIN 256000 | ||
549 | /* PLL M/N/K Code Control 1 (0x81) */ | ||
550 | #define RT5660_PLL_N_MAX 0x1ff | ||
551 | #define RT5660_PLL_N_MASK (RT5660_PLL_N_MAX << 7) | ||
552 | #define RT5660_PLL_N_SFT 7 | ||
553 | #define RT5660_PLL_K_MAX 0x1f | ||
554 | #define RT5660_PLL_K_MASK (RT5660_PLL_K_MAX) | ||
555 | #define RT5660_PLL_K_SFT 0 | ||
556 | |||
557 | /* PLL M/N/K Code Control 2 (0x82) */ | ||
558 | #define RT5660_PLL_M_MAX 0xf | ||
559 | #define RT5660_PLL_M_MASK (RT5660_PLL_M_MAX << 12) | ||
560 | #define RT5660_PLL_M_SFT 12 | ||
561 | #define RT5660_PLL_M_BP (0x1 << 11) | ||
562 | #define RT5660_PLL_M_BP_SFT 11 | ||
563 | |||
564 | /* Class D Over Current Control (0x8c) */ | ||
565 | #define RT5660_CLSD_OC_MASK (0x1 << 9) | ||
566 | #define RT5660_CLSD_OC_SFT 9 | ||
567 | #define RT5660_CLSD_OC_PU (0x0 << 9) | ||
568 | #define RT5660_CLSD_OC_PD (0x1 << 9) | ||
569 | #define RT5660_AUTO_PD_MASK (0x1 << 8) | ||
570 | #define RT5660_AUTO_PD_SFT 8 | ||
571 | #define RT5660_AUTO_PD_DIS (0x0 << 8) | ||
572 | #define RT5660_AUTO_PD_EN (0x1 << 8) | ||
573 | #define RT5660_CLSD_OC_TH_MASK (0x3f) | ||
574 | #define RT5660_CLSD_OC_TH_SFT 0 | ||
575 | |||
576 | /* Class D Output Control (0x8d) */ | ||
577 | #define RT5660_CLSD_RATIO_MASK (0xf << 12) | ||
578 | #define RT5660_CLSD_RATIO_SFT 12 | ||
579 | |||
580 | /* Lout Amp Control 1 (0x8e) */ | ||
581 | #define RT5660_LOUT_CO_MASK (0x1 << 4) | ||
582 | #define RT5660_LOUT_CO_SFT 4 | ||
583 | #define RT5660_LOUT_CO_DIS (0x0 << 4) | ||
584 | #define RT5660_LOUT_CO_EN (0x1 << 4) | ||
585 | #define RT5660_LOUT_CB_MASK (0x1) | ||
586 | #define RT5660_LOUT_CB_SFT 0 | ||
587 | #define RT5660_LOUT_CB_PD (0x0) | ||
588 | #define RT5660_LOUT_CB_PU (0x1) | ||
589 | |||
590 | /* SPKVDD detection control (0x92) */ | ||
591 | #define RT5660_SPKVDD_DET_MASK (0x1 << 15) | ||
592 | #define RT5660_SPKVDD_DET_SFT 15 | ||
593 | #define RT5660_SPKVDD_DET_DIS (0x0 << 15) | ||
594 | #define RT5660_SPKVDD_DET_EN (0x1 << 15) | ||
595 | #define RT5660_SPK_AG_MASK (0x1 << 14) | ||
596 | #define RT5660_SPK_AG_SFT 14 | ||
597 | #define RT5660_SPK_AG_DIS (0x0 << 14) | ||
598 | #define RT5660_SPK_AG_EN (0x1 << 14) | ||
599 | |||
600 | /* Micbias Control (0x93) */ | ||
601 | #define RT5660_MIC1_BS_MASK (0x1 << 15) | ||
602 | #define RT5660_MIC1_BS_SFT 15 | ||
603 | #define RT5660_MIC1_BS_9AV (0x0 << 15) | ||
604 | #define RT5660_MIC1_BS_75AV (0x1 << 15) | ||
605 | #define RT5660_MIC2_BS_MASK (0x1 << 14) | ||
606 | #define RT5660_MIC2_BS_SFT 14 | ||
607 | #define RT5660_MIC2_BS_9AV (0x0 << 14) | ||
608 | #define RT5660_MIC2_BS_75AV (0x1 << 14) | ||
609 | #define RT5660_MIC1_OVCD_MASK (0x1 << 11) | ||
610 | #define RT5660_MIC1_OVCD_SFT 11 | ||
611 | #define RT5660_MIC1_OVCD_DIS (0x0 << 11) | ||
612 | #define RT5660_MIC1_OVCD_EN (0x1 << 11) | ||
613 | #define RT5660_MIC1_OVTH_MASK (0x3 << 9) | ||
614 | #define RT5660_MIC1_OVTH_SFT 9 | ||
615 | #define RT5660_MIC1_OVTH_600UA (0x0 << 9) | ||
616 | #define RT5660_MIC1_OVTH_1500UA (0x1 << 9) | ||
617 | #define RT5660_MIC1_OVTH_2000UA (0x2 << 9) | ||
618 | #define RT5660_MIC2_OVCD_MASK (0x1 << 8) | ||
619 | #define RT5660_MIC2_OVCD_SFT 8 | ||
620 | #define RT5660_MIC2_OVCD_DIS (0x0 << 8) | ||
621 | #define RT5660_MIC2_OVCD_EN (0x1 << 8) | ||
622 | #define RT5660_MIC2_OVTH_MASK (0x3 << 6) | ||
623 | #define RT5660_MIC2_OVTH_SFT 6 | ||
624 | #define RT5660_MIC2_OVTH_600UA (0x0 << 6) | ||
625 | #define RT5660_MIC2_OVTH_1500UA (0x1 << 6) | ||
626 | #define RT5660_MIC2_OVTH_2000UA (0x2 << 6) | ||
627 | #define RT5660_PWR_CLK25M_MASK (0x1 << 4) | ||
628 | #define RT5660_PWR_CLK25M_SFT 4 | ||
629 | #define RT5660_PWR_CLK25M_PD (0x0 << 4) | ||
630 | #define RT5660_PWR_CLK25M_PU (0x1 << 4) | ||
631 | |||
632 | /* EQ Control 1 (0xb0) */ | ||
633 | #define RT5660_EQ_SRC_MASK (0x1 << 15) | ||
634 | #define RT5660_EQ_SRC_SFT 15 | ||
635 | #define RT5660_EQ_SRC_DAC (0x0 << 15) | ||
636 | #define RT5660_EQ_SRC_ADC (0x1 << 15) | ||
637 | #define RT5660_EQ_UPD (0x1 << 14) | ||
638 | #define RT5660_EQ_UPD_BIT 14 | ||
639 | |||
640 | /* Jack Detect Control (0xbb) */ | ||
641 | #define RT5660_JD_MASK (0x3 << 14) | ||
642 | #define RT5660_JD_SFT 14 | ||
643 | #define RT5660_JD_DIS (0x0 << 14) | ||
644 | #define RT5660_JD_GPIO1 (0x1 << 14) | ||
645 | #define RT5660_JD_GPIO2 (0x2 << 14) | ||
646 | #define RT5660_JD_LOUT_MASK (0x1 << 11) | ||
647 | #define RT5660_JD_LOUT_SFT 11 | ||
648 | #define RT5660_JD_LOUT_DIS (0x0 << 11) | ||
649 | #define RT5660_JD_LOUT_EN (0x1 << 11) | ||
650 | #define RT5660_JD_LOUT_TRG_MASK (0x1 << 10) | ||
651 | #define RT5660_JD_LOUT_TRG_SFT 10 | ||
652 | #define RT5660_JD_LOUT_TRG_LO (0x0 << 10) | ||
653 | #define RT5660_JD_LOUT_TRG_HI (0x1 << 10) | ||
654 | #define RT5660_JD_SPO_MASK (0x1 << 9) | ||
655 | #define RT5660_JD_SPO_SFT 9 | ||
656 | #define RT5660_JD_SPO_DIS (0x0 << 9) | ||
657 | #define RT5660_JD_SPO_EN (0x1 << 9) | ||
658 | #define RT5660_JD_SPO_TRG_MASK (0x1 << 8) | ||
659 | #define RT5660_JD_SPO_TRG_SFT 8 | ||
660 | #define RT5660_JD_SPO_TRG_LO (0x0 << 8) | ||
661 | #define RT5660_JD_SPO_TRG_HI (0x1 << 8) | ||
662 | |||
663 | /* IRQ Control 1 (0xbd) */ | ||
664 | #define RT5660_IRQ_JD_MASK (0x1 << 15) | ||
665 | #define RT5660_IRQ_JD_SFT 15 | ||
666 | #define RT5660_IRQ_JD_BP (0x0 << 15) | ||
667 | #define RT5660_IRQ_JD_NOR (0x1 << 15) | ||
668 | #define RT5660_IRQ_OT_MASK (0x1 << 14) | ||
669 | #define RT5660_IRQ_OT_SFT 14 | ||
670 | #define RT5660_IRQ_OT_BP (0x0 << 14) | ||
671 | #define RT5660_IRQ_OT_NOR (0x1 << 14) | ||
672 | #define RT5660_JD_STKY_MASK (0x1 << 13) | ||
673 | #define RT5660_JD_STKY_SFT 13 | ||
674 | #define RT5660_JD_STKY_DIS (0x0 << 13) | ||
675 | #define RT5660_JD_STKY_EN (0x1 << 13) | ||
676 | #define RT5660_OT_STKY_MASK (0x1 << 12) | ||
677 | #define RT5660_OT_STKY_SFT 12 | ||
678 | #define RT5660_OT_STKY_DIS (0x0 << 12) | ||
679 | #define RT5660_OT_STKY_EN (0x1 << 12) | ||
680 | #define RT5660_JD_P_MASK (0x1 << 11) | ||
681 | #define RT5660_JD_P_SFT 11 | ||
682 | #define RT5660_JD_P_NOR (0x0 << 11) | ||
683 | #define RT5660_JD_P_INV (0x1 << 11) | ||
684 | #define RT5660_OT_P_MASK (0x1 << 10) | ||
685 | #define RT5660_OT_P_SFT 10 | ||
686 | #define RT5660_OT_P_NOR (0x0 << 10) | ||
687 | #define RT5660_OT_P_INV (0x1 << 10) | ||
688 | |||
689 | /* IRQ Control 2 (0xbe) */ | ||
690 | #define RT5660_IRQ_MB1_OC_MASK (0x1 << 15) | ||
691 | #define RT5660_IRQ_MB1_OC_SFT 15 | ||
692 | #define RT5660_IRQ_MB1_OC_BP (0x0 << 15) | ||
693 | #define RT5660_IRQ_MB1_OC_NOR (0x1 << 15) | ||
694 | #define RT5660_IRQ_MB2_OC_MASK (0x1 << 14) | ||
695 | #define RT5660_IRQ_MB2_OC_SFT 14 | ||
696 | #define RT5660_IRQ_MB2_OC_BP (0x0 << 14) | ||
697 | #define RT5660_IRQ_MB2_OC_NOR (0x1 << 14) | ||
698 | #define RT5660_MB1_OC_STKY_MASK (0x1 << 11) | ||
699 | #define RT5660_MB1_OC_STKY_SFT 11 | ||
700 | #define RT5660_MB1_OC_STKY_DIS (0x0 << 11) | ||
701 | #define RT5660_MB1_OC_STKY_EN (0x1 << 11) | ||
702 | #define RT5660_MB2_OC_STKY_MASK (0x1 << 10) | ||
703 | #define RT5660_MB2_OC_STKY_SFT 10 | ||
704 | #define RT5660_MB2_OC_STKY_DIS (0x0 << 10) | ||
705 | #define RT5660_MB2_OC_STKY_EN (0x1 << 10) | ||
706 | #define RT5660_MB1_OC_P_MASK (0x1 << 7) | ||
707 | #define RT5660_MB1_OC_P_SFT 7 | ||
708 | #define RT5660_MB1_OC_P_NOR (0x0 << 7) | ||
709 | #define RT5660_MB1_OC_P_INV (0x1 << 7) | ||
710 | #define RT5660_MB2_OC_P_MASK (0x1 << 6) | ||
711 | #define RT5660_MB2_OC_P_SFT 6 | ||
712 | #define RT5660_MB2_OC_P_NOR (0x0 << 6) | ||
713 | #define RT5660_MB2_OC_P_INV (0x1 << 6) | ||
714 | #define RT5660_MB1_OC_CLR (0x1 << 3) | ||
715 | #define RT5660_MB1_OC_CLR_SFT 3 | ||
716 | #define RT5660_MB2_OC_CLR (0x1 << 2) | ||
717 | #define RT5660_MB2_OC_CLR_SFT 2 | ||
718 | |||
719 | /* GPIO Control 1 (0xc0) */ | ||
720 | #define RT5660_GP2_PIN_MASK (0x1 << 14) | ||
721 | #define RT5660_GP2_PIN_SFT 14 | ||
722 | #define RT5660_GP2_PIN_GPIO2 (0x0 << 14) | ||
723 | #define RT5660_GP2_PIN_DMIC1_SDA (0x1 << 14) | ||
724 | #define RT5660_GP1_PIN_MASK (0x3 << 12) | ||
725 | #define RT5660_GP1_PIN_SFT 12 | ||
726 | #define RT5660_GP1_PIN_GPIO1 (0x0 << 12) | ||
727 | #define RT5660_GP1_PIN_DMIC1_SCL (0x1 << 12) | ||
728 | #define RT5660_GP1_PIN_IRQ (0x2 << 12) | ||
729 | #define RT5660_GPIO_M_MASK (0x1 << 9) | ||
730 | #define RT5660_GPIO_M_SFT 9 | ||
731 | #define RT5660_GPIO_M_FLT (0x0 << 9) | ||
732 | #define RT5660_GPIO_M_PH (0x1 << 9) | ||
733 | |||
734 | /* GPIO Control 3 (0xc2) */ | ||
735 | #define RT5660_GP2_PF_MASK (0x1 << 5) | ||
736 | #define RT5660_GP2_PF_SFT 5 | ||
737 | #define RT5660_GP2_PF_IN (0x0 << 5) | ||
738 | #define RT5660_GP2_PF_OUT (0x1 << 5) | ||
739 | #define RT5660_GP2_OUT_MASK (0x1 << 4) | ||
740 | #define RT5660_GP2_OUT_SFT 4 | ||
741 | #define RT5660_GP2_OUT_LO (0x0 << 4) | ||
742 | #define RT5660_GP2_OUT_HI (0x1 << 4) | ||
743 | #define RT5660_GP2_P_MASK (0x1 << 3) | ||
744 | #define RT5660_GP2_P_SFT 3 | ||
745 | #define RT5660_GP2_P_NOR (0x0 << 3) | ||
746 | #define RT5660_GP2_P_INV (0x1 << 3) | ||
747 | #define RT5660_GP1_PF_MASK (0x1 << 2) | ||
748 | #define RT5660_GP1_PF_SFT 2 | ||
749 | #define RT5660_GP1_PF_IN (0x0 << 2) | ||
750 | #define RT5660_GP1_PF_OUT (0x1 << 2) | ||
751 | #define RT5660_GP1_OUT_MASK (0x1 << 1) | ||
752 | #define RT5660_GP1_OUT_SFT 1 | ||
753 | #define RT5660_GP1_OUT_LO (0x0 << 1) | ||
754 | #define RT5660_GP1_OUT_HI (0x1 << 1) | ||
755 | #define RT5660_GP1_P_MASK (0x1) | ||
756 | #define RT5660_GP1_P_SFT 0 | ||
757 | #define RT5660_GP1_P_NOR (0x0) | ||
758 | #define RT5660_GP1_P_INV (0x1) | ||
759 | |||
760 | /* Soft volume and zero cross control 1 (0xd9) */ | ||
761 | #define RT5660_SV_MASK (0x1 << 15) | ||
762 | #define RT5660_SV_SFT 15 | ||
763 | #define RT5660_SV_DIS (0x0 << 15) | ||
764 | #define RT5660_SV_EN (0x1 << 15) | ||
765 | #define RT5660_SPO_SV_MASK (0x1 << 14) | ||
766 | #define RT5660_SPO_SV_SFT 14 | ||
767 | #define RT5660_SPO_SV_DIS (0x0 << 14) | ||
768 | #define RT5660_SPO_SV_EN (0x1 << 14) | ||
769 | #define RT5660_OUT_SV_MASK (0x1 << 12) | ||
770 | #define RT5660_OUT_SV_SFT 12 | ||
771 | #define RT5660_OUT_SV_DIS (0x0 << 12) | ||
772 | #define RT5660_OUT_SV_EN (0x1 << 12) | ||
773 | #define RT5660_ZCD_DIG_MASK (0x1 << 11) | ||
774 | #define RT5660_ZCD_DIG_SFT 11 | ||
775 | #define RT5660_ZCD_DIG_DIS (0x0 << 11) | ||
776 | #define RT5660_ZCD_DIG_EN (0x1 << 11) | ||
777 | #define RT5660_ZCD_MASK (0x1 << 10) | ||
778 | #define RT5660_ZCD_SFT 10 | ||
779 | #define RT5660_ZCD_PD (0x0 << 10) | ||
780 | #define RT5660_ZCD_PU (0x1 << 10) | ||
781 | #define RT5660_SV_DLY_MASK (0xf) | ||
782 | #define RT5660_SV_DLY_SFT 0 | ||
783 | |||
784 | /* Soft volume and zero cross control 2 (0xda) */ | ||
785 | #define RT5660_ZCD_SPO_MASK (0x1 << 15) | ||
786 | #define RT5660_ZCD_SPO_SFT 15 | ||
787 | #define RT5660_ZCD_SPO_DIS (0x0 << 15) | ||
788 | #define RT5660_ZCD_SPO_EN (0x1 << 15) | ||
789 | #define RT5660_ZCD_OMR_MASK (0x1 << 8) | ||
790 | #define RT5660_ZCD_OMR_SFT 8 | ||
791 | #define RT5660_ZCD_OMR_DIS (0x0 << 8) | ||
792 | #define RT5660_ZCD_OMR_EN (0x1 << 8) | ||
793 | #define RT5660_ZCD_OML_MASK (0x1 << 7) | ||
794 | #define RT5660_ZCD_OML_SFT 7 | ||
795 | #define RT5660_ZCD_OML_DIS (0x0 << 7) | ||
796 | #define RT5660_ZCD_OML_EN (0x1 << 7) | ||
797 | #define RT5660_ZCD_SPM_MASK (0x1 << 6) | ||
798 | #define RT5660_ZCD_SPM_SFT 6 | ||
799 | #define RT5660_ZCD_SPM_DIS (0x0 << 6) | ||
800 | #define RT5660_ZCD_SPM_EN (0x1 << 6) | ||
801 | #define RT5660_ZCD_RMR_MASK (0x1 << 5) | ||
802 | #define RT5660_ZCD_RMR_SFT 5 | ||
803 | #define RT5660_ZCD_RMR_DIS (0x0 << 5) | ||
804 | #define RT5660_ZCD_RMR_EN (0x1 << 5) | ||
805 | #define RT5660_ZCD_RML_MASK (0x1 << 4) | ||
806 | #define RT5660_ZCD_RML_SFT 4 | ||
807 | #define RT5660_ZCD_RML_DIS (0x0 << 4) | ||
808 | #define RT5660_ZCD_RML_EN (0x1 << 4) | ||
809 | |||
810 | /* General Control 1 (0xfa) */ | ||
811 | #define RT5660_PWR_VREF_HP (0x1 << 11) | ||
812 | #define RT5660_PWR_VREF_HP_SFT 11 | ||
813 | #define RT5660_DIG_GATE_CTRL (0x1) | ||
814 | #define RT5660_DIG_GATE_CTRL_SFT 0 | ||
815 | |||
816 | /* System Clock Source */ | ||
817 | #define RT5660_SCLK_S_MCLK 0 | ||
818 | #define RT5660_SCLK_S_PLL1 1 | ||
819 | #define RT5660_SCLK_S_RCCLK 2 | ||
820 | |||
821 | /* PLL1 Source */ | ||
822 | #define RT5660_PLL1_S_MCLK 0 | ||
823 | #define RT5660_PLL1_S_BCLK 1 | ||
824 | |||
825 | enum { | ||
826 | RT5660_AIF1, | ||
827 | RT5660_AIFS, | ||
828 | }; | ||
829 | |||
830 | struct rt5660_priv { | ||
831 | struct snd_soc_codec *codec; | ||
832 | struct rt5660_platform_data pdata; | ||
833 | struct regmap *regmap; | ||
834 | struct clk *mclk; | ||
835 | |||
836 | int sysclk; | ||
837 | int sysclk_src; | ||
838 | int lrck[RT5660_AIFS]; | ||
839 | int bclk[RT5660_AIFS]; | ||
840 | int master[RT5660_AIFS]; | ||
841 | |||
842 | int pll_src; | ||
843 | int pll_in; | ||
844 | int pll_out; | ||
845 | }; | ||
846 | |||
847 | #endif | ||
diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c new file mode 100644 index 000000000000..01a18d88f1eb --- /dev/null +++ b/sound/soc/codecs/rt5663.c | |||
@@ -0,0 +1,3218 @@ | |||
1 | /* | ||
2 | * rt5663.c -- RT5668/RT5663 ALSA SoC audio codec driver | ||
3 | * | ||
4 | * Copyright 2016 Realtek Semiconductor Corp. | ||
5 | * Author: Jack Yu <jack.yu@realtek.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 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/moduleparam.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/pm.h> | ||
16 | #include <linux/i2c.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/spi/spi.h> | ||
19 | #include <linux/acpi.h> | ||
20 | #include <linux/workqueue.h> | ||
21 | #include <sound/core.h> | ||
22 | #include <sound/pcm.h> | ||
23 | #include <sound/pcm_params.h> | ||
24 | #include <sound/jack.h> | ||
25 | #include <sound/soc.h> | ||
26 | #include <sound/soc-dapm.h> | ||
27 | #include <sound/initval.h> | ||
28 | #include <sound/tlv.h> | ||
29 | |||
30 | #include "rt5663.h" | ||
31 | #include "rl6231.h" | ||
32 | |||
33 | #define RT5668_DEVICE_ID 0x6451 | ||
34 | #define RT5663_DEVICE_ID 0x6406 | ||
35 | |||
36 | enum { | ||
37 | CODEC_TYPE_RT5668, | ||
38 | CODEC_TYPE_RT5663, | ||
39 | }; | ||
40 | |||
41 | struct rt5663_priv { | ||
42 | struct snd_soc_codec *codec; | ||
43 | struct regmap *regmap; | ||
44 | struct delayed_work jack_detect_work; | ||
45 | struct snd_soc_jack *hs_jack; | ||
46 | struct timer_list btn_check_timer; | ||
47 | |||
48 | int codec_type; | ||
49 | int sysclk; | ||
50 | int sysclk_src; | ||
51 | int lrck; | ||
52 | |||
53 | int pll_src; | ||
54 | int pll_in; | ||
55 | int pll_out; | ||
56 | |||
57 | int jack_type; | ||
58 | }; | ||
59 | |||
60 | static const struct reg_default rt5668_reg[] = { | ||
61 | { 0x0000, 0x0000 }, | ||
62 | { 0x0001, 0xc8c8 }, | ||
63 | { 0x0002, 0x8080 }, | ||
64 | { 0x0003, 0x8000 }, | ||
65 | { 0x0004, 0xc80a }, | ||
66 | { 0x0005, 0x0000 }, | ||
67 | { 0x0006, 0x0000 }, | ||
68 | { 0x0007, 0x0000 }, | ||
69 | { 0x000a, 0x0000 }, | ||
70 | { 0x000b, 0x0000 }, | ||
71 | { 0x000c, 0x0000 }, | ||
72 | { 0x000d, 0x0000 }, | ||
73 | { 0x000f, 0x0808 }, | ||
74 | { 0x0010, 0x4000 }, | ||
75 | { 0x0011, 0x0000 }, | ||
76 | { 0x0012, 0x1404 }, | ||
77 | { 0x0013, 0x1000 }, | ||
78 | { 0x0014, 0xa00a }, | ||
79 | { 0x0015, 0x0404 }, | ||
80 | { 0x0016, 0x0404 }, | ||
81 | { 0x0017, 0x0011 }, | ||
82 | { 0x0018, 0xafaf }, | ||
83 | { 0x0019, 0xafaf }, | ||
84 | { 0x001a, 0xafaf }, | ||
85 | { 0x001b, 0x0011 }, | ||
86 | { 0x001c, 0x2f2f }, | ||
87 | { 0x001d, 0x2f2f }, | ||
88 | { 0x001e, 0x2f2f }, | ||
89 | { 0x001f, 0x0000 }, | ||
90 | { 0x0020, 0x0000 }, | ||
91 | { 0x0021, 0x0000 }, | ||
92 | { 0x0022, 0x5757 }, | ||
93 | { 0x0023, 0x0039 }, | ||
94 | { 0x0024, 0x000b }, | ||
95 | { 0x0026, 0xc0c0 }, | ||
96 | { 0x0027, 0xc0c0 }, | ||
97 | { 0x0028, 0xc0c0 }, | ||
98 | { 0x0029, 0x8080 }, | ||
99 | { 0x002a, 0xaaaa }, | ||
100 | { 0x002b, 0xaaaa }, | ||
101 | { 0x002c, 0xaba8 }, | ||
102 | { 0x002d, 0x0000 }, | ||
103 | { 0x002e, 0x0000 }, | ||
104 | { 0x002f, 0x0000 }, | ||
105 | { 0x0030, 0x0000 }, | ||
106 | { 0x0031, 0x5000 }, | ||
107 | { 0x0032, 0x0000 }, | ||
108 | { 0x0033, 0x0000 }, | ||
109 | { 0x0034, 0x0000 }, | ||
110 | { 0x0035, 0x0000 }, | ||
111 | { 0x003a, 0x0000 }, | ||
112 | { 0x003b, 0x0000 }, | ||
113 | { 0x003c, 0x00ff }, | ||
114 | { 0x003d, 0x0000 }, | ||
115 | { 0x003e, 0x00ff }, | ||
116 | { 0x003f, 0x0000 }, | ||
117 | { 0x0040, 0x0000 }, | ||
118 | { 0x0041, 0x00ff }, | ||
119 | { 0x0042, 0x0000 }, | ||
120 | { 0x0043, 0x00ff }, | ||
121 | { 0x0044, 0x0c0c }, | ||
122 | { 0x0049, 0xc00b }, | ||
123 | { 0x004a, 0x0000 }, | ||
124 | { 0x004b, 0x031f }, | ||
125 | { 0x004d, 0x0000 }, | ||
126 | { 0x004e, 0x001f }, | ||
127 | { 0x004f, 0x0000 }, | ||
128 | { 0x0050, 0x001f }, | ||
129 | { 0x0052, 0xf000 }, | ||
130 | { 0x0061, 0x0000 }, | ||
131 | { 0x0062, 0x0000 }, | ||
132 | { 0x0063, 0x003e }, | ||
133 | { 0x0064, 0x0000 }, | ||
134 | { 0x0065, 0x0000 }, | ||
135 | { 0x0066, 0x003f }, | ||
136 | { 0x0067, 0x0000 }, | ||
137 | { 0x006b, 0x0000 }, | ||
138 | { 0x006d, 0xff00 }, | ||
139 | { 0x006e, 0x2808 }, | ||
140 | { 0x006f, 0x000a }, | ||
141 | { 0x0070, 0x8000 }, | ||
142 | { 0x0071, 0x8000 }, | ||
143 | { 0x0072, 0x8000 }, | ||
144 | { 0x0073, 0x7000 }, | ||
145 | { 0x0074, 0x7770 }, | ||
146 | { 0x0075, 0x0002 }, | ||
147 | { 0x0076, 0x0001 }, | ||
148 | { 0x0078, 0x00f0 }, | ||
149 | { 0x0079, 0x0000 }, | ||
150 | { 0x007a, 0x0000 }, | ||
151 | { 0x007b, 0x0000 }, | ||
152 | { 0x007c, 0x0000 }, | ||
153 | { 0x007d, 0x0123 }, | ||
154 | { 0x007e, 0x4500 }, | ||
155 | { 0x007f, 0x8003 }, | ||
156 | { 0x0080, 0x0000 }, | ||
157 | { 0x0081, 0x0000 }, | ||
158 | { 0x0082, 0x0000 }, | ||
159 | { 0x0083, 0x0000 }, | ||
160 | { 0x0084, 0x0000 }, | ||
161 | { 0x0085, 0x0000 }, | ||
162 | { 0x0086, 0x0008 }, | ||
163 | { 0x0087, 0x0000 }, | ||
164 | { 0x0088, 0x0000 }, | ||
165 | { 0x0089, 0x0000 }, | ||
166 | { 0x008a, 0x0000 }, | ||
167 | { 0x008b, 0x0000 }, | ||
168 | { 0x008c, 0x0003 }, | ||
169 | { 0x008e, 0x0060 }, | ||
170 | { 0x008f, 0x1000 }, | ||
171 | { 0x0091, 0x0c26 }, | ||
172 | { 0x0092, 0x0073 }, | ||
173 | { 0x0093, 0x0000 }, | ||
174 | { 0x0094, 0x0080 }, | ||
175 | { 0x0098, 0x0000 }, | ||
176 | { 0x0099, 0x0000 }, | ||
177 | { 0x009a, 0x0007 }, | ||
178 | { 0x009f, 0x0000 }, | ||
179 | { 0x00a0, 0x0000 }, | ||
180 | { 0x00a1, 0x0002 }, | ||
181 | { 0x00a2, 0x0001 }, | ||
182 | { 0x00a3, 0x0002 }, | ||
183 | { 0x00a4, 0x0001 }, | ||
184 | { 0x00ae, 0x2040 }, | ||
185 | { 0x00af, 0x0000 }, | ||
186 | { 0x00b6, 0x0000 }, | ||
187 | { 0x00b7, 0x0000 }, | ||
188 | { 0x00b8, 0x0000 }, | ||
189 | { 0x00b9, 0x0000 }, | ||
190 | { 0x00ba, 0x0002 }, | ||
191 | { 0x00bb, 0x0000 }, | ||
192 | { 0x00be, 0x0000 }, | ||
193 | { 0x00c0, 0x0000 }, | ||
194 | { 0x00c1, 0x0aaa }, | ||
195 | { 0x00c2, 0xaa80 }, | ||
196 | { 0x00c3, 0x0003 }, | ||
197 | { 0x00c4, 0x0000 }, | ||
198 | { 0x00d0, 0x0000 }, | ||
199 | { 0x00d1, 0x2244 }, | ||
200 | { 0x00d2, 0x0000 }, | ||
201 | { 0x00d3, 0x3300 }, | ||
202 | { 0x00d4, 0x2200 }, | ||
203 | { 0x00d9, 0x0809 }, | ||
204 | { 0x00da, 0x0000 }, | ||
205 | { 0x00db, 0x0008 }, | ||
206 | { 0x00dc, 0x00c0 }, | ||
207 | { 0x00dd, 0x6724 }, | ||
208 | { 0x00de, 0x3131 }, | ||
209 | { 0x00df, 0x0008 }, | ||
210 | { 0x00e0, 0x4000 }, | ||
211 | { 0x00e1, 0x3131 }, | ||
212 | { 0x00e2, 0x600c }, | ||
213 | { 0x00ea, 0xb320 }, | ||
214 | { 0x00eb, 0x0000 }, | ||
215 | { 0x00ec, 0xb300 }, | ||
216 | { 0x00ed, 0x0000 }, | ||
217 | { 0x00ee, 0xb320 }, | ||
218 | { 0x00ef, 0x0000 }, | ||
219 | { 0x00f0, 0x0201 }, | ||
220 | { 0x00f1, 0x0ddd }, | ||
221 | { 0x00f2, 0x0ddd }, | ||
222 | { 0x00f6, 0x0000 }, | ||
223 | { 0x00f7, 0x0000 }, | ||
224 | { 0x00f8, 0x0000 }, | ||
225 | { 0x00fa, 0x0000 }, | ||
226 | { 0x00fb, 0x0000 }, | ||
227 | { 0x00fc, 0x0000 }, | ||
228 | { 0x00fd, 0x0000 }, | ||
229 | { 0x00fe, 0x10ec }, | ||
230 | { 0x00ff, 0x6451 }, | ||
231 | { 0x0100, 0xaaaa }, | ||
232 | { 0x0101, 0x000a }, | ||
233 | { 0x010a, 0xaaaa }, | ||
234 | { 0x010b, 0xa0a0 }, | ||
235 | { 0x010c, 0xaeae }, | ||
236 | { 0x010d, 0xaaaa }, | ||
237 | { 0x010e, 0xaaaa }, | ||
238 | { 0x010f, 0xaaaa }, | ||
239 | { 0x0110, 0xe002 }, | ||
240 | { 0x0111, 0xa602 }, | ||
241 | { 0x0112, 0xaaaa }, | ||
242 | { 0x0113, 0x2000 }, | ||
243 | { 0x0117, 0x0f00 }, | ||
244 | { 0x0125, 0x0420 }, | ||
245 | { 0x0132, 0x0000 }, | ||
246 | { 0x0133, 0x0000 }, | ||
247 | { 0x0136, 0x5555 }, | ||
248 | { 0x0137, 0x5540 }, | ||
249 | { 0x0138, 0x3700 }, | ||
250 | { 0x0139, 0x79a1 }, | ||
251 | { 0x013a, 0x2020 }, | ||
252 | { 0x013b, 0x2020 }, | ||
253 | { 0x013c, 0x2005 }, | ||
254 | { 0x013f, 0x0000 }, | ||
255 | { 0x0145, 0x0002 }, | ||
256 | { 0x0146, 0x0000 }, | ||
257 | { 0x0147, 0x0000 }, | ||
258 | { 0x0148, 0x0000 }, | ||
259 | { 0x0160, 0x4ec0 }, | ||
260 | { 0x0161, 0x0080 }, | ||
261 | { 0x0162, 0x0200 }, | ||
262 | { 0x0163, 0x0800 }, | ||
263 | { 0x0164, 0x0000 }, | ||
264 | { 0x0165, 0x0000 }, | ||
265 | { 0x0166, 0x0000 }, | ||
266 | { 0x0167, 0x000f }, | ||
267 | { 0x0168, 0x000f }, | ||
268 | { 0x0170, 0x4e80 }, | ||
269 | { 0x0171, 0x0080 }, | ||
270 | { 0x0172, 0x0200 }, | ||
271 | { 0x0173, 0x0800 }, | ||
272 | { 0x0174, 0x00ff }, | ||
273 | { 0x0175, 0x0000 }, | ||
274 | { 0x0190, 0x4131 }, | ||
275 | { 0x0191, 0x4131 }, | ||
276 | { 0x0192, 0x4131 }, | ||
277 | { 0x0193, 0x4131 }, | ||
278 | { 0x0194, 0x0000 }, | ||
279 | { 0x0195, 0x0000 }, | ||
280 | { 0x0196, 0x0000 }, | ||
281 | { 0x0197, 0x0000 }, | ||
282 | { 0x0198, 0x0000 }, | ||
283 | { 0x0199, 0x0000 }, | ||
284 | { 0x01a0, 0x1e64 }, | ||
285 | { 0x01a1, 0x06a3 }, | ||
286 | { 0x01a2, 0x0000 }, | ||
287 | { 0x01a3, 0x0000 }, | ||
288 | { 0x01a4, 0x0000 }, | ||
289 | { 0x01a5, 0x0000 }, | ||
290 | { 0x01a6, 0x0000 }, | ||
291 | { 0x01a7, 0x0000 }, | ||
292 | { 0x01a8, 0x0000 }, | ||
293 | { 0x01a9, 0x0000 }, | ||
294 | { 0x01aa, 0x0000 }, | ||
295 | { 0x01ab, 0x0000 }, | ||
296 | { 0x01b5, 0x0000 }, | ||
297 | { 0x01b6, 0x01c3 }, | ||
298 | { 0x01b7, 0x02a0 }, | ||
299 | { 0x01b8, 0x03e9 }, | ||
300 | { 0x01b9, 0x1389 }, | ||
301 | { 0x01ba, 0xc351 }, | ||
302 | { 0x01bb, 0x0009 }, | ||
303 | { 0x01bc, 0x0018 }, | ||
304 | { 0x01bd, 0x002a }, | ||
305 | { 0x01be, 0x004c }, | ||
306 | { 0x01bf, 0x0097 }, | ||
307 | { 0x01c0, 0x433d }, | ||
308 | { 0x01c1, 0x0000 }, | ||
309 | { 0x01c2, 0x0000 }, | ||
310 | { 0x01c3, 0x0000 }, | ||
311 | { 0x01c4, 0x0000 }, | ||
312 | { 0x01c5, 0x0000 }, | ||
313 | { 0x01c6, 0x0000 }, | ||
314 | { 0x01c7, 0x0000 }, | ||
315 | { 0x01c8, 0x40af }, | ||
316 | { 0x01c9, 0x0702 }, | ||
317 | { 0x01ca, 0x0000 }, | ||
318 | { 0x01cb, 0x0000 }, | ||
319 | { 0x01cc, 0x5757 }, | ||
320 | { 0x01cd, 0x5757 }, | ||
321 | { 0x01ce, 0x5757 }, | ||
322 | { 0x01cf, 0x5757 }, | ||
323 | { 0x01d0, 0x5757 }, | ||
324 | { 0x01d1, 0x5757 }, | ||
325 | { 0x01d2, 0x5757 }, | ||
326 | { 0x01d3, 0x5757 }, | ||
327 | { 0x01d4, 0x5757 }, | ||
328 | { 0x01d5, 0x5757 }, | ||
329 | { 0x01d6, 0x003c }, | ||
330 | { 0x01da, 0x0000 }, | ||
331 | { 0x01db, 0x0000 }, | ||
332 | { 0x01dc, 0x0000 }, | ||
333 | { 0x01de, 0x7c00 }, | ||
334 | { 0x01df, 0x0320 }, | ||
335 | { 0x01e0, 0x06a1 }, | ||
336 | { 0x01e1, 0x0000 }, | ||
337 | { 0x01e2, 0x0000 }, | ||
338 | { 0x01e3, 0x0000 }, | ||
339 | { 0x01e4, 0x0000 }, | ||
340 | { 0x01e5, 0x0000 }, | ||
341 | { 0x01e6, 0x0001 }, | ||
342 | { 0x01e7, 0x0000 }, | ||
343 | { 0x01e8, 0x0000 }, | ||
344 | { 0x01ea, 0x0000 }, | ||
345 | { 0x01eb, 0x0000 }, | ||
346 | { 0x01ec, 0x0000 }, | ||
347 | { 0x01ed, 0x0000 }, | ||
348 | { 0x01ee, 0x0000 }, | ||
349 | { 0x01ef, 0x0000 }, | ||
350 | { 0x01f0, 0x0000 }, | ||
351 | { 0x01f1, 0x0000 }, | ||
352 | { 0x01f2, 0x0000 }, | ||
353 | { 0x01f3, 0x0000 }, | ||
354 | { 0x01f4, 0x0000 }, | ||
355 | { 0x0200, 0x0000 }, | ||
356 | { 0x0201, 0x0000 }, | ||
357 | { 0x0202, 0x0000 }, | ||
358 | { 0x0203, 0x0000 }, | ||
359 | { 0x0204, 0x0000 }, | ||
360 | { 0x0205, 0x0000 }, | ||
361 | { 0x0206, 0x0000 }, | ||
362 | { 0x0207, 0x0000 }, | ||
363 | { 0x0208, 0x0000 }, | ||
364 | { 0x0210, 0x60b1 }, | ||
365 | { 0x0211, 0xa000 }, | ||
366 | { 0x0212, 0x024c }, | ||
367 | { 0x0213, 0xf7ff }, | ||
368 | { 0x0214, 0x024c }, | ||
369 | { 0x0215, 0x0102 }, | ||
370 | { 0x0216, 0x00a3 }, | ||
371 | { 0x0217, 0x0048 }, | ||
372 | { 0x0218, 0x92c0 }, | ||
373 | { 0x0219, 0x0000 }, | ||
374 | { 0x021a, 0x00c8 }, | ||
375 | { 0x021b, 0x0020 }, | ||
376 | { 0x02fa, 0x0000 }, | ||
377 | { 0x02fb, 0x0000 }, | ||
378 | { 0x02fc, 0x0000 }, | ||
379 | { 0x02ff, 0x0110 }, | ||
380 | { 0x0300, 0x001f }, | ||
381 | { 0x0301, 0x032c }, | ||
382 | { 0x0302, 0x5f21 }, | ||
383 | { 0x0303, 0x4000 }, | ||
384 | { 0x0304, 0x4000 }, | ||
385 | { 0x0305, 0x06d5 }, | ||
386 | { 0x0306, 0x8000 }, | ||
387 | { 0x0307, 0x0700 }, | ||
388 | { 0x0310, 0x4560 }, | ||
389 | { 0x0311, 0xa4a8 }, | ||
390 | { 0x0312, 0x7418 }, | ||
391 | { 0x0313, 0x0000 }, | ||
392 | { 0x0314, 0x0006 }, | ||
393 | { 0x0315, 0xffff }, | ||
394 | { 0x0316, 0xc400 }, | ||
395 | { 0x0317, 0x0000 }, | ||
396 | { 0x0330, 0x00a6 }, | ||
397 | { 0x0331, 0x04c3 }, | ||
398 | { 0x0332, 0x27c8 }, | ||
399 | { 0x0333, 0xbf50 }, | ||
400 | { 0x0334, 0x0045 }, | ||
401 | { 0x0335, 0x0007 }, | ||
402 | { 0x0336, 0x7418 }, | ||
403 | { 0x0337, 0x0501 }, | ||
404 | { 0x0338, 0x0000 }, | ||
405 | { 0x0339, 0x0010 }, | ||
406 | { 0x033a, 0x1010 }, | ||
407 | { 0x03c0, 0x7e00 }, | ||
408 | { 0x03c1, 0x8000 }, | ||
409 | { 0x03c2, 0x8000 }, | ||
410 | { 0x03c3, 0x8000 }, | ||
411 | { 0x03c4, 0x8000 }, | ||
412 | { 0x03c5, 0x8000 }, | ||
413 | { 0x03c6, 0x8000 }, | ||
414 | { 0x03c7, 0x8000 }, | ||
415 | { 0x03c8, 0x8000 }, | ||
416 | { 0x03c9, 0x8000 }, | ||
417 | { 0x03ca, 0x8000 }, | ||
418 | { 0x03cb, 0x8000 }, | ||
419 | { 0x03cc, 0x8000 }, | ||
420 | { 0x03d0, 0x0000 }, | ||
421 | { 0x03d1, 0x0000 }, | ||
422 | { 0x03d2, 0x0000 }, | ||
423 | { 0x03d3, 0x0000 }, | ||
424 | { 0x03d4, 0x2000 }, | ||
425 | { 0x03d5, 0x2000 }, | ||
426 | { 0x03d6, 0x0000 }, | ||
427 | { 0x03d7, 0x0000 }, | ||
428 | { 0x03d8, 0x2000 }, | ||
429 | { 0x03d9, 0x2000 }, | ||
430 | { 0x03da, 0x2000 }, | ||
431 | { 0x03db, 0x2000 }, | ||
432 | { 0x03dc, 0x0000 }, | ||
433 | { 0x03dd, 0x0000 }, | ||
434 | { 0x03de, 0x0000 }, | ||
435 | { 0x03df, 0x2000 }, | ||
436 | { 0x03e0, 0x0000 }, | ||
437 | { 0x03e1, 0x0000 }, | ||
438 | { 0x03e2, 0x0000 }, | ||
439 | { 0x03e3, 0x0000 }, | ||
440 | { 0x03e4, 0x0000 }, | ||
441 | { 0x03e5, 0x0000 }, | ||
442 | { 0x03e6, 0x0000 }, | ||
443 | { 0x03e7, 0x0000 }, | ||
444 | { 0x03e8, 0x0000 }, | ||
445 | { 0x03e9, 0x0000 }, | ||
446 | { 0x03ea, 0x0000 }, | ||
447 | { 0x03eb, 0x0000 }, | ||
448 | { 0x03ec, 0x0000 }, | ||
449 | { 0x03ed, 0x0000 }, | ||
450 | { 0x03ee, 0x0000 }, | ||
451 | { 0x03ef, 0x0000 }, | ||
452 | { 0x03f0, 0x0800 }, | ||
453 | { 0x03f1, 0x0800 }, | ||
454 | { 0x03f2, 0x0800 }, | ||
455 | { 0x03f3, 0x0800 }, | ||
456 | { 0x03fe, 0x0000 }, | ||
457 | { 0x03ff, 0x0000 }, | ||
458 | { 0x07f0, 0x0000 }, | ||
459 | { 0x07fa, 0x0000 }, | ||
460 | }; | ||
461 | |||
462 | static const struct reg_default rt5663_reg[] = { | ||
463 | { 0x0000, 0x0000 }, | ||
464 | { 0x0002, 0x0008 }, | ||
465 | { 0x0005, 0x1000 }, | ||
466 | { 0x0006, 0x1000 }, | ||
467 | { 0x000a, 0x0000 }, | ||
468 | { 0x0010, 0x000f }, | ||
469 | { 0x0015, 0x42c1 }, | ||
470 | { 0x0016, 0x0000 }, | ||
471 | { 0x0018, 0x000b }, | ||
472 | { 0x0019, 0xafaf }, | ||
473 | { 0x001c, 0x2f2f }, | ||
474 | { 0x001f, 0x0000 }, | ||
475 | { 0x0022, 0x5757 }, | ||
476 | { 0x0023, 0x0039 }, | ||
477 | { 0x0026, 0xc0c0 }, | ||
478 | { 0x0029, 0x8080 }, | ||
479 | { 0x002a, 0xa0a0 }, | ||
480 | { 0x002c, 0x000c }, | ||
481 | { 0x002d, 0x0000 }, | ||
482 | { 0x0040, 0x0808 }, | ||
483 | { 0x0061, 0x0000 }, | ||
484 | { 0x0062, 0x0000 }, | ||
485 | { 0x0063, 0x003e }, | ||
486 | { 0x0064, 0x0000 }, | ||
487 | { 0x0065, 0x0000 }, | ||
488 | { 0x0066, 0x0000 }, | ||
489 | { 0x006b, 0x0000 }, | ||
490 | { 0x006e, 0x0000 }, | ||
491 | { 0x006f, 0x0000 }, | ||
492 | { 0x0070, 0x8020 }, | ||
493 | { 0x0073, 0x1000 }, | ||
494 | { 0x0074, 0xe400 }, | ||
495 | { 0x0075, 0x0002 }, | ||
496 | { 0x0076, 0x0001 }, | ||
497 | { 0x0077, 0x00f0 }, | ||
498 | { 0x0078, 0x0000 }, | ||
499 | { 0x0079, 0x0000 }, | ||
500 | { 0x007a, 0x0123 }, | ||
501 | { 0x007b, 0x8003 }, | ||
502 | { 0x0080, 0x0000 }, | ||
503 | { 0x0081, 0x0000 }, | ||
504 | { 0x0082, 0x0000 }, | ||
505 | { 0x0083, 0x0000 }, | ||
506 | { 0x0084, 0x0000 }, | ||
507 | { 0x0086, 0x0008 }, | ||
508 | { 0x0087, 0x0000 }, | ||
509 | { 0x008a, 0x0000 }, | ||
510 | { 0x008b, 0x0000 }, | ||
511 | { 0x008c, 0x0003 }, | ||
512 | { 0x008e, 0x0004 }, | ||
513 | { 0x008f, 0x1000 }, | ||
514 | { 0x0090, 0x0646 }, | ||
515 | { 0x0091, 0x0e3e }, | ||
516 | { 0x0092, 0x1071 }, | ||
517 | { 0x0093, 0x0000 }, | ||
518 | { 0x0094, 0x0080 }, | ||
519 | { 0x0097, 0x0000 }, | ||
520 | { 0x0098, 0x0000 }, | ||
521 | { 0x009a, 0x0000 }, | ||
522 | { 0x009f, 0x0000 }, | ||
523 | { 0x00ae, 0x2000 }, | ||
524 | { 0x00af, 0x0000 }, | ||
525 | { 0x00b6, 0x0000 }, | ||
526 | { 0x00b7, 0x0000 }, | ||
527 | { 0x00b8, 0x0000 }, | ||
528 | { 0x00ba, 0x0000 }, | ||
529 | { 0x00bb, 0x0000 }, | ||
530 | { 0x00be, 0x0000 }, | ||
531 | { 0x00bf, 0x0000 }, | ||
532 | { 0x00c0, 0x0000 }, | ||
533 | { 0x00c1, 0x0000 }, | ||
534 | { 0x00c5, 0x0000 }, | ||
535 | { 0x00cb, 0xa02f }, | ||
536 | { 0x00cc, 0x0000 }, | ||
537 | { 0x00cd, 0x0e02 }, | ||
538 | { 0x00d9, 0x08f9 }, | ||
539 | { 0x00db, 0x0008 }, | ||
540 | { 0x00dc, 0x00c0 }, | ||
541 | { 0x00dd, 0x6724 }, | ||
542 | { 0x00de, 0x3131 }, | ||
543 | { 0x00df, 0x0008 }, | ||
544 | { 0x00e0, 0x4000 }, | ||
545 | { 0x00e1, 0x3131 }, | ||
546 | { 0x00e2, 0x0043 }, | ||
547 | { 0x00e4, 0x400b }, | ||
548 | { 0x00e5, 0x8031 }, | ||
549 | { 0x00e6, 0x3080 }, | ||
550 | { 0x00e7, 0x4100 }, | ||
551 | { 0x00e8, 0x1400 }, | ||
552 | { 0x00e9, 0xe00a }, | ||
553 | { 0x00ea, 0x0404 }, | ||
554 | { 0x00eb, 0x0404 }, | ||
555 | { 0x00ec, 0xb320 }, | ||
556 | { 0x00ed, 0x0000 }, | ||
557 | { 0x00f4, 0x0000 }, | ||
558 | { 0x00f6, 0x0000 }, | ||
559 | { 0x00f8, 0x0000 }, | ||
560 | { 0x00fa, 0x8000 }, | ||
561 | { 0x00fd, 0x0001 }, | ||
562 | { 0x00fe, 0x10ec }, | ||
563 | { 0x00ff, 0x6406 }, | ||
564 | { 0x0100, 0xa0a0 }, | ||
565 | { 0x0108, 0x4444 }, | ||
566 | { 0x0109, 0x4444 }, | ||
567 | { 0x010a, 0xaaaa }, | ||
568 | { 0x010b, 0x00a0 }, | ||
569 | { 0x010c, 0x8aaa }, | ||
570 | { 0x010d, 0xaaaa }, | ||
571 | { 0x010e, 0x2aaa }, | ||
572 | { 0x010f, 0x002a }, | ||
573 | { 0x0110, 0xa0a4 }, | ||
574 | { 0x0111, 0x4602 }, | ||
575 | { 0x0112, 0x0101 }, | ||
576 | { 0x0113, 0x2000 }, | ||
577 | { 0x0114, 0x0000 }, | ||
578 | { 0x0116, 0x0000 }, | ||
579 | { 0x0117, 0x0f00 }, | ||
580 | { 0x0118, 0x0006 }, | ||
581 | { 0x0125, 0x2224 }, | ||
582 | { 0x0126, 0x5550 }, | ||
583 | { 0x0127, 0x0400 }, | ||
584 | { 0x0128, 0x7711 }, | ||
585 | { 0x0132, 0x0004 }, | ||
586 | { 0x0137, 0x5441 }, | ||
587 | { 0x0139, 0x79a1 }, | ||
588 | { 0x013a, 0x30c0 }, | ||
589 | { 0x013b, 0x2000 }, | ||
590 | { 0x013c, 0x2005 }, | ||
591 | { 0x013d, 0x30c0 }, | ||
592 | { 0x013e, 0x0000 }, | ||
593 | { 0x0140, 0x3700 }, | ||
594 | { 0x0141, 0x1f00 }, | ||
595 | { 0x0144, 0x0000 }, | ||
596 | { 0x0145, 0x0002 }, | ||
597 | { 0x0146, 0x0000 }, | ||
598 | { 0x0160, 0x0e80 }, | ||
599 | { 0x0161, 0x0020 }, | ||
600 | { 0x0162, 0x0080 }, | ||
601 | { 0x0163, 0x0800 }, | ||
602 | { 0x0164, 0x0000 }, | ||
603 | { 0x0165, 0x0000 }, | ||
604 | { 0x0166, 0x0000 }, | ||
605 | { 0x0167, 0x1417 }, | ||
606 | { 0x0168, 0x0017 }, | ||
607 | { 0x0169, 0x0017 }, | ||
608 | { 0x0180, 0x2000 }, | ||
609 | { 0x0181, 0x0000 }, | ||
610 | { 0x0182, 0x0000 }, | ||
611 | { 0x0183, 0x2000 }, | ||
612 | { 0x0184, 0x0000 }, | ||
613 | { 0x0185, 0x0000 }, | ||
614 | { 0x01b0, 0x4b30 }, | ||
615 | { 0x01b1, 0x0000 }, | ||
616 | { 0x01b2, 0xd870 }, | ||
617 | { 0x01b3, 0x0000 }, | ||
618 | { 0x01b4, 0x0030 }, | ||
619 | { 0x01b5, 0x5757 }, | ||
620 | { 0x01b6, 0x5757 }, | ||
621 | { 0x01b7, 0x5757 }, | ||
622 | { 0x01b8, 0x5757 }, | ||
623 | { 0x01c0, 0x433d }, | ||
624 | { 0x01c1, 0x0540 }, | ||
625 | { 0x01c2, 0x0000 }, | ||
626 | { 0x01c3, 0x0000 }, | ||
627 | { 0x01c4, 0x0000 }, | ||
628 | { 0x01c5, 0x0009 }, | ||
629 | { 0x01c6, 0x0018 }, | ||
630 | { 0x01c7, 0x002a }, | ||
631 | { 0x01c8, 0x004c }, | ||
632 | { 0x01c9, 0x0097 }, | ||
633 | { 0x01ca, 0x01c3 }, | ||
634 | { 0x01cb, 0x03e9 }, | ||
635 | { 0x01cc, 0x1389 }, | ||
636 | { 0x01cd, 0xc351 }, | ||
637 | { 0x01ce, 0x0000 }, | ||
638 | { 0x01cf, 0x0000 }, | ||
639 | { 0x01d0, 0x0000 }, | ||
640 | { 0x01d1, 0x0000 }, | ||
641 | { 0x01d2, 0x0000 }, | ||
642 | { 0x01d3, 0x003c }, | ||
643 | { 0x01d4, 0x5757 }, | ||
644 | { 0x01d5, 0x5757 }, | ||
645 | { 0x01d6, 0x5757 }, | ||
646 | { 0x01d7, 0x5757 }, | ||
647 | { 0x01d8, 0x5757 }, | ||
648 | { 0x01d9, 0x5757 }, | ||
649 | { 0x01da, 0x0000 }, | ||
650 | { 0x01db, 0x0000 }, | ||
651 | { 0x01dd, 0x0009 }, | ||
652 | { 0x01de, 0x7f00 }, | ||
653 | { 0x01df, 0x00c8 }, | ||
654 | { 0x01e0, 0x0691 }, | ||
655 | { 0x01e1, 0x0000 }, | ||
656 | { 0x01e2, 0x0000 }, | ||
657 | { 0x01e3, 0x0000 }, | ||
658 | { 0x01e4, 0x0000 }, | ||
659 | { 0x01e5, 0x0040 }, | ||
660 | { 0x01e6, 0x0000 }, | ||
661 | { 0x01e7, 0x0000 }, | ||
662 | { 0x01e8, 0x0000 }, | ||
663 | { 0x01ea, 0x0000 }, | ||
664 | { 0x01eb, 0x0000 }, | ||
665 | { 0x01ec, 0x0000 }, | ||
666 | { 0x01ed, 0x0000 }, | ||
667 | { 0x01ee, 0x0000 }, | ||
668 | { 0x01ef, 0x0000 }, | ||
669 | { 0x01f0, 0x0000 }, | ||
670 | { 0x01f1, 0x0000 }, | ||
671 | { 0x01f2, 0x0000 }, | ||
672 | { 0x0200, 0x0000 }, | ||
673 | { 0x0201, 0x2244 }, | ||
674 | { 0x0202, 0xaaaa }, | ||
675 | { 0x0250, 0x8010 }, | ||
676 | { 0x0251, 0x0000 }, | ||
677 | { 0x0252, 0x028a }, | ||
678 | { 0x02fa, 0x0000 }, | ||
679 | { 0x02fb, 0x0000 }, | ||
680 | { 0x02fc, 0x0000 }, | ||
681 | { 0x0300, 0x0000 }, | ||
682 | { 0x03d0, 0x0000 }, | ||
683 | { 0x03d1, 0x0000 }, | ||
684 | { 0x03d2, 0x0000 }, | ||
685 | { 0x03d3, 0x0000 }, | ||
686 | { 0x03d4, 0x2000 }, | ||
687 | { 0x03d5, 0x2000 }, | ||
688 | { 0x03d6, 0x0000 }, | ||
689 | { 0x03d7, 0x0000 }, | ||
690 | { 0x03d8, 0x2000 }, | ||
691 | { 0x03d9, 0x2000 }, | ||
692 | { 0x03da, 0x2000 }, | ||
693 | { 0x03db, 0x2000 }, | ||
694 | { 0x03dc, 0x0000 }, | ||
695 | { 0x03dd, 0x0000 }, | ||
696 | { 0x03de, 0x0000 }, | ||
697 | { 0x03df, 0x2000 }, | ||
698 | { 0x03e0, 0x0000 }, | ||
699 | { 0x03e1, 0x0000 }, | ||
700 | { 0x03e2, 0x0000 }, | ||
701 | { 0x03e3, 0x0000 }, | ||
702 | { 0x03e4, 0x0000 }, | ||
703 | { 0x03e5, 0x0000 }, | ||
704 | { 0x03e6, 0x0000 }, | ||
705 | { 0x03e7, 0x0000 }, | ||
706 | { 0x03e8, 0x0000 }, | ||
707 | { 0x03e9, 0x0000 }, | ||
708 | { 0x03ea, 0x0000 }, | ||
709 | { 0x03eb, 0x0000 }, | ||
710 | { 0x03ec, 0x0000 }, | ||
711 | { 0x03ed, 0x0000 }, | ||
712 | { 0x03ee, 0x0000 }, | ||
713 | { 0x03ef, 0x0000 }, | ||
714 | { 0x03f0, 0x0800 }, | ||
715 | { 0x03f1, 0x0800 }, | ||
716 | { 0x03f2, 0x0800 }, | ||
717 | { 0x03f3, 0x0800 }, | ||
718 | }; | ||
719 | |||
720 | static bool rt5663_volatile_register(struct device *dev, unsigned int reg) | ||
721 | { | ||
722 | switch (reg) { | ||
723 | case RT5663_RESET: | ||
724 | case RT5663_SIL_DET_CTL: | ||
725 | case RT5663_HP_IMP_GAIN_2: | ||
726 | case RT5663_AD_DA_MIXER: | ||
727 | case RT5663_FRAC_DIV_2: | ||
728 | case RT5663_MICBIAS_1: | ||
729 | case RT5663_ASRC_11_2: | ||
730 | case RT5663_ADC_EQ_1: | ||
731 | case RT5663_INT_ST_1: | ||
732 | case RT5663_INT_ST_2: | ||
733 | case RT5663_GPIO_STA: | ||
734 | case RT5663_SIN_GEN_1: | ||
735 | case RT5663_IL_CMD_1: | ||
736 | case RT5663_IL_CMD_5: | ||
737 | case RT5663_IL_CMD_PWRSAV1: | ||
738 | case RT5663_EM_JACK_TYPE_1: | ||
739 | case RT5663_EM_JACK_TYPE_2: | ||
740 | case RT5663_EM_JACK_TYPE_3: | ||
741 | case RT5663_JD_CTRL2: | ||
742 | case RT5663_VENDOR_ID: | ||
743 | case RT5663_VENDOR_ID_1: | ||
744 | case RT5663_VENDOR_ID_2: | ||
745 | case RT5663_PLL_INT_REG: | ||
746 | case RT5663_SOFT_RAMP: | ||
747 | case RT5663_STO_DRE_1: | ||
748 | case RT5663_STO_DRE_5: | ||
749 | case RT5663_STO_DRE_6: | ||
750 | case RT5663_STO_DRE_7: | ||
751 | case RT5663_MIC_DECRO_1: | ||
752 | case RT5663_MIC_DECRO_4: | ||
753 | case RT5663_HP_IMP_SEN_1: | ||
754 | case RT5663_HP_IMP_SEN_3: | ||
755 | case RT5663_HP_IMP_SEN_4: | ||
756 | case RT5663_HP_IMP_SEN_5: | ||
757 | case RT5663_HP_CALIB_1_1: | ||
758 | case RT5663_HP_CALIB_9: | ||
759 | case RT5663_HP_CALIB_ST1: | ||
760 | case RT5663_HP_CALIB_ST2: | ||
761 | case RT5663_HP_CALIB_ST3: | ||
762 | case RT5663_HP_CALIB_ST4: | ||
763 | case RT5663_HP_CALIB_ST5: | ||
764 | case RT5663_HP_CALIB_ST6: | ||
765 | case RT5663_HP_CALIB_ST7: | ||
766 | case RT5663_HP_CALIB_ST8: | ||
767 | case RT5663_HP_CALIB_ST9: | ||
768 | case RT5663_ANA_JD: | ||
769 | return true; | ||
770 | default: | ||
771 | return false; | ||
772 | } | ||
773 | } | ||
774 | |||
775 | static bool rt5663_readable_register(struct device *dev, unsigned int reg) | ||
776 | { | ||
777 | switch (reg) { | ||
778 | case RT5663_RESET: | ||
779 | case RT5663_HP_OUT_EN: | ||
780 | case RT5663_HP_LCH_DRE: | ||
781 | case RT5663_HP_RCH_DRE: | ||
782 | case RT5663_CALIB_BST: | ||
783 | case RT5663_RECMIX: | ||
784 | case RT5663_SIL_DET_CTL: | ||
785 | case RT5663_PWR_SAV_SILDET: | ||
786 | case RT5663_SIDETONE_CTL: | ||
787 | case RT5663_STO1_DAC_DIG_VOL: | ||
788 | case RT5663_STO1_ADC_DIG_VOL: | ||
789 | case RT5663_STO1_BOOST: | ||
790 | case RT5663_HP_IMP_GAIN_1: | ||
791 | case RT5663_HP_IMP_GAIN_2: | ||
792 | case RT5663_STO1_ADC_MIXER: | ||
793 | case RT5663_AD_DA_MIXER: | ||
794 | case RT5663_STO_DAC_MIXER: | ||
795 | case RT5663_DIG_SIDE_MIXER: | ||
796 | case RT5663_BYPASS_STO_DAC: | ||
797 | case RT5663_CALIB_REC_MIX: | ||
798 | case RT5663_PWR_DIG_1: | ||
799 | case RT5663_PWR_DIG_2: | ||
800 | case RT5663_PWR_ANLG_1: | ||
801 | case RT5663_PWR_ANLG_2: | ||
802 | case RT5663_PWR_ANLG_3: | ||
803 | case RT5663_PWR_MIXER: | ||
804 | case RT5663_SIG_CLK_DET: | ||
805 | case RT5663_PRE_DIV_GATING_1: | ||
806 | case RT5663_PRE_DIV_GATING_2: | ||
807 | case RT5663_I2S1_SDP: | ||
808 | case RT5663_ADDA_CLK_1: | ||
809 | case RT5663_ADDA_RST: | ||
810 | case RT5663_FRAC_DIV_1: | ||
811 | case RT5663_FRAC_DIV_2: | ||
812 | case RT5663_TDM_1: | ||
813 | case RT5663_TDM_2: | ||
814 | case RT5663_TDM_3: | ||
815 | case RT5663_TDM_4: | ||
816 | case RT5663_TDM_5: | ||
817 | case RT5663_GLB_CLK: | ||
818 | case RT5663_PLL_1: | ||
819 | case RT5663_PLL_2: | ||
820 | case RT5663_ASRC_1: | ||
821 | case RT5663_ASRC_2: | ||
822 | case RT5663_ASRC_4: | ||
823 | case RT5663_DUMMY_REG: | ||
824 | case RT5663_ASRC_8: | ||
825 | case RT5663_ASRC_9: | ||
826 | case RT5663_ASRC_11: | ||
827 | case RT5663_DEPOP_1: | ||
828 | case RT5663_DEPOP_2: | ||
829 | case RT5663_DEPOP_3: | ||
830 | case RT5663_HP_CHARGE_PUMP_1: | ||
831 | case RT5663_HP_CHARGE_PUMP_2: | ||
832 | case RT5663_MICBIAS_1: | ||
833 | case RT5663_RC_CLK: | ||
834 | case RT5663_ASRC_11_2: | ||
835 | case RT5663_DUMMY_REG_2: | ||
836 | case RT5663_REC_PATH_GAIN: | ||
837 | case RT5663_AUTO_1MRC_CLK: | ||
838 | case RT5663_ADC_EQ_1: | ||
839 | case RT5663_ADC_EQ_2: | ||
840 | case RT5663_IRQ_1: | ||
841 | case RT5663_IRQ_2: | ||
842 | case RT5663_IRQ_3: | ||
843 | case RT5663_IRQ_4: | ||
844 | case RT5663_IRQ_5: | ||
845 | case RT5663_INT_ST_1: | ||
846 | case RT5663_INT_ST_2: | ||
847 | case RT5663_GPIO_1: | ||
848 | case RT5663_GPIO_2: | ||
849 | case RT5663_GPIO_STA: | ||
850 | case RT5663_SIN_GEN_1: | ||
851 | case RT5663_SIN_GEN_2: | ||
852 | case RT5663_SIN_GEN_3: | ||
853 | case RT5663_SOF_VOL_ZC1: | ||
854 | case RT5663_IL_CMD_1: | ||
855 | case RT5663_IL_CMD_2: | ||
856 | case RT5663_IL_CMD_3: | ||
857 | case RT5663_IL_CMD_4: | ||
858 | case RT5663_IL_CMD_5: | ||
859 | case RT5663_IL_CMD_6: | ||
860 | case RT5663_IL_CMD_7: | ||
861 | case RT5663_IL_CMD_8: | ||
862 | case RT5663_IL_CMD_PWRSAV1: | ||
863 | case RT5663_IL_CMD_PWRSAV2: | ||
864 | case RT5663_EM_JACK_TYPE_1: | ||
865 | case RT5663_EM_JACK_TYPE_2: | ||
866 | case RT5663_EM_JACK_TYPE_3: | ||
867 | case RT5663_EM_JACK_TYPE_4: | ||
868 | case RT5663_EM_JACK_TYPE_5: | ||
869 | case RT5663_EM_JACK_TYPE_6: | ||
870 | case RT5663_STO1_HPF_ADJ1: | ||
871 | case RT5663_STO1_HPF_ADJ2: | ||
872 | case RT5663_FAST_OFF_MICBIAS: | ||
873 | case RT5663_JD_CTRL1: | ||
874 | case RT5663_JD_CTRL2: | ||
875 | case RT5663_DIG_MISC: | ||
876 | case RT5663_VENDOR_ID: | ||
877 | case RT5663_VENDOR_ID_1: | ||
878 | case RT5663_VENDOR_ID_2: | ||
879 | case RT5663_DIG_VOL_ZCD: | ||
880 | case RT5663_ANA_BIAS_CUR_1: | ||
881 | case RT5663_ANA_BIAS_CUR_2: | ||
882 | case RT5663_ANA_BIAS_CUR_3: | ||
883 | case RT5663_ANA_BIAS_CUR_4: | ||
884 | case RT5663_ANA_BIAS_CUR_5: | ||
885 | case RT5663_ANA_BIAS_CUR_6: | ||
886 | case RT5663_BIAS_CUR_5: | ||
887 | case RT5663_BIAS_CUR_6: | ||
888 | case RT5663_BIAS_CUR_7: | ||
889 | case RT5663_BIAS_CUR_8: | ||
890 | case RT5663_DACREF_LDO: | ||
891 | case RT5663_DUMMY_REG_3: | ||
892 | case RT5663_BIAS_CUR_9: | ||
893 | case RT5663_DUMMY_REG_4: | ||
894 | case RT5663_VREFADJ_OP: | ||
895 | case RT5663_VREF_RECMIX: | ||
896 | case RT5663_CHARGE_PUMP_1: | ||
897 | case RT5663_CHARGE_PUMP_1_2: | ||
898 | case RT5663_CHARGE_PUMP_1_3: | ||
899 | case RT5663_CHARGE_PUMP_2: | ||
900 | case RT5663_DIG_IN_PIN1: | ||
901 | case RT5663_PAD_DRV_CTL: | ||
902 | case RT5663_PLL_INT_REG: | ||
903 | case RT5663_CHOP_DAC_L: | ||
904 | case RT5663_CHOP_ADC: | ||
905 | case RT5663_CALIB_ADC: | ||
906 | case RT5663_CHOP_DAC_R: | ||
907 | case RT5663_DUMMY_CTL_DACLR: | ||
908 | case RT5663_DUMMY_REG_5: | ||
909 | case RT5663_SOFT_RAMP: | ||
910 | case RT5663_TEST_MODE_1: | ||
911 | case RT5663_TEST_MODE_2: | ||
912 | case RT5663_TEST_MODE_3: | ||
913 | case RT5663_STO_DRE_1: | ||
914 | case RT5663_STO_DRE_2: | ||
915 | case RT5663_STO_DRE_3: | ||
916 | case RT5663_STO_DRE_4: | ||
917 | case RT5663_STO_DRE_5: | ||
918 | case RT5663_STO_DRE_6: | ||
919 | case RT5663_STO_DRE_7: | ||
920 | case RT5663_STO_DRE_8: | ||
921 | case RT5663_STO_DRE_9: | ||
922 | case RT5663_STO_DRE_10: | ||
923 | case RT5663_MIC_DECRO_1: | ||
924 | case RT5663_MIC_DECRO_2: | ||
925 | case RT5663_MIC_DECRO_3: | ||
926 | case RT5663_MIC_DECRO_4: | ||
927 | case RT5663_MIC_DECRO_5: | ||
928 | case RT5663_MIC_DECRO_6: | ||
929 | case RT5663_HP_DECRO_1: | ||
930 | case RT5663_HP_DECRO_2: | ||
931 | case RT5663_HP_DECRO_3: | ||
932 | case RT5663_HP_DECRO_4: | ||
933 | case RT5663_HP_DECOUP: | ||
934 | case RT5663_HP_IMP_SEN_MAP8: | ||
935 | case RT5663_HP_IMP_SEN_MAP9: | ||
936 | case RT5663_HP_IMP_SEN_MAP10: | ||
937 | case RT5663_HP_IMP_SEN_MAP11: | ||
938 | case RT5663_HP_IMP_SEN_1: | ||
939 | case RT5663_HP_IMP_SEN_2: | ||
940 | case RT5663_HP_IMP_SEN_3: | ||
941 | case RT5663_HP_IMP_SEN_4: | ||
942 | case RT5663_HP_IMP_SEN_5: | ||
943 | case RT5663_HP_IMP_SEN_6: | ||
944 | case RT5663_HP_IMP_SEN_7: | ||
945 | case RT5663_HP_IMP_SEN_8: | ||
946 | case RT5663_HP_IMP_SEN_9: | ||
947 | case RT5663_HP_IMP_SEN_10: | ||
948 | case RT5663_HP_IMP_SEN_11: | ||
949 | case RT5663_HP_IMP_SEN_12: | ||
950 | case RT5663_HP_IMP_SEN_13: | ||
951 | case RT5663_HP_IMP_SEN_14: | ||
952 | case RT5663_HP_IMP_SEN_15: | ||
953 | case RT5663_HP_IMP_SEN_16: | ||
954 | case RT5663_HP_IMP_SEN_17: | ||
955 | case RT5663_HP_IMP_SEN_18: | ||
956 | case RT5663_HP_IMP_SEN_19: | ||
957 | case RT5663_HP_IMPSEN_DIG5: | ||
958 | case RT5663_HP_IMPSEN_MAP1: | ||
959 | case RT5663_HP_IMPSEN_MAP2: | ||
960 | case RT5663_HP_IMPSEN_MAP3: | ||
961 | case RT5663_HP_IMPSEN_MAP4: | ||
962 | case RT5663_HP_IMPSEN_MAP5: | ||
963 | case RT5663_HP_IMPSEN_MAP7: | ||
964 | case RT5663_HP_LOGIC_1: | ||
965 | case RT5663_HP_LOGIC_2: | ||
966 | case RT5663_HP_CALIB_1: | ||
967 | case RT5663_HP_CALIB_1_1: | ||
968 | case RT5663_HP_CALIB_2: | ||
969 | case RT5663_HP_CALIB_3: | ||
970 | case RT5663_HP_CALIB_4: | ||
971 | case RT5663_HP_CALIB_5: | ||
972 | case RT5663_HP_CALIB_5_1: | ||
973 | case RT5663_HP_CALIB_6: | ||
974 | case RT5663_HP_CALIB_7: | ||
975 | case RT5663_HP_CALIB_9: | ||
976 | case RT5663_HP_CALIB_10: | ||
977 | case RT5663_HP_CALIB_11: | ||
978 | case RT5663_HP_CALIB_ST1: | ||
979 | case RT5663_HP_CALIB_ST2: | ||
980 | case RT5663_HP_CALIB_ST3: | ||
981 | case RT5663_HP_CALIB_ST4: | ||
982 | case RT5663_HP_CALIB_ST5: | ||
983 | case RT5663_HP_CALIB_ST6: | ||
984 | case RT5663_HP_CALIB_ST7: | ||
985 | case RT5663_HP_CALIB_ST8: | ||
986 | case RT5663_HP_CALIB_ST9: | ||
987 | case RT5663_HP_AMP_DET: | ||
988 | case RT5663_DUMMY_REG_6: | ||
989 | case RT5663_HP_BIAS: | ||
990 | case RT5663_CBJ_1: | ||
991 | case RT5663_CBJ_2: | ||
992 | case RT5663_CBJ_3: | ||
993 | case RT5663_DUMMY_1: | ||
994 | case RT5663_DUMMY_2: | ||
995 | case RT5663_DUMMY_3: | ||
996 | case RT5663_ANA_JD: | ||
997 | case RT5663_ADC_LCH_LPF1_A1: | ||
998 | case RT5663_ADC_RCH_LPF1_A1: | ||
999 | case RT5663_ADC_LCH_LPF1_H0: | ||
1000 | case RT5663_ADC_RCH_LPF1_H0: | ||
1001 | case RT5663_ADC_LCH_BPF1_A1: | ||
1002 | case RT5663_ADC_RCH_BPF1_A1: | ||
1003 | case RT5663_ADC_LCH_BPF1_A2: | ||
1004 | case RT5663_ADC_RCH_BPF1_A2: | ||
1005 | case RT5663_ADC_LCH_BPF1_H0: | ||
1006 | case RT5663_ADC_RCH_BPF1_H0: | ||
1007 | case RT5663_ADC_LCH_BPF2_A1: | ||
1008 | case RT5663_ADC_RCH_BPF2_A1: | ||
1009 | case RT5663_ADC_LCH_BPF2_A2: | ||
1010 | case RT5663_ADC_RCH_BPF2_A2: | ||
1011 | case RT5663_ADC_LCH_BPF2_H0: | ||
1012 | case RT5663_ADC_RCH_BPF2_H0: | ||
1013 | case RT5663_ADC_LCH_BPF3_A1: | ||
1014 | case RT5663_ADC_RCH_BPF3_A1: | ||
1015 | case RT5663_ADC_LCH_BPF3_A2: | ||
1016 | case RT5663_ADC_RCH_BPF3_A2: | ||
1017 | case RT5663_ADC_LCH_BPF3_H0: | ||
1018 | case RT5663_ADC_RCH_BPF3_H0: | ||
1019 | case RT5663_ADC_LCH_BPF4_A1: | ||
1020 | case RT5663_ADC_RCH_BPF4_A1: | ||
1021 | case RT5663_ADC_LCH_BPF4_A2: | ||
1022 | case RT5663_ADC_RCH_BPF4_A2: | ||
1023 | case RT5663_ADC_LCH_BPF4_H0: | ||
1024 | case RT5663_ADC_RCH_BPF4_H0: | ||
1025 | case RT5663_ADC_LCH_HPF1_A1: | ||
1026 | case RT5663_ADC_RCH_HPF1_A1: | ||
1027 | case RT5663_ADC_LCH_HPF1_H0: | ||
1028 | case RT5663_ADC_RCH_HPF1_H0: | ||
1029 | case RT5663_ADC_EQ_PRE_VOL_L: | ||
1030 | case RT5663_ADC_EQ_PRE_VOL_R: | ||
1031 | case RT5663_ADC_EQ_POST_VOL_L: | ||
1032 | case RT5663_ADC_EQ_POST_VOL_R: | ||
1033 | return true; | ||
1034 | default: | ||
1035 | return false; | ||
1036 | } | ||
1037 | } | ||
1038 | |||
1039 | static bool rt5668_volatile_register(struct device *dev, unsigned int reg) | ||
1040 | { | ||
1041 | switch (reg) { | ||
1042 | case RT5663_RESET: | ||
1043 | case RT5668_CBJ_TYPE_2: | ||
1044 | case RT5668_PDM_OUT_CTL: | ||
1045 | case RT5668_PDM_I2C_DATA_CTL1: | ||
1046 | case RT5668_PDM_I2C_DATA_CTL4: | ||
1047 | case RT5668_ALC_BK_GAIN: | ||
1048 | case RT5663_PLL_2: | ||
1049 | case RT5663_MICBIAS_1: | ||
1050 | case RT5663_ADC_EQ_1: | ||
1051 | case RT5663_INT_ST_1: | ||
1052 | case RT5668_GPIO_STA: | ||
1053 | case RT5663_IL_CMD_1: | ||
1054 | case RT5663_IL_CMD_5: | ||
1055 | case RT5668_A_JD_CTRL: | ||
1056 | case RT5663_JD_CTRL2: | ||
1057 | case RT5663_VENDOR_ID: | ||
1058 | case RT5663_VENDOR_ID_1: | ||
1059 | case RT5663_VENDOR_ID_2: | ||
1060 | case RT5663_STO_DRE_1: | ||
1061 | case RT5663_STO_DRE_5: | ||
1062 | case RT5663_STO_DRE_6: | ||
1063 | case RT5663_STO_DRE_7: | ||
1064 | case RT5668_MONO_DYNA_6: | ||
1065 | case RT5668_STO1_SIL_DET: | ||
1066 | case RT5668_MONOL_SIL_DET: | ||
1067 | case RT5668_MONOR_SIL_DET: | ||
1068 | case RT5668_STO2_DAC_SIL: | ||
1069 | case RT5668_MONO_AMP_CAL_ST1: | ||
1070 | case RT5668_MONO_AMP_CAL_ST2: | ||
1071 | case RT5668_MONO_AMP_CAL_ST3: | ||
1072 | case RT5668_MONO_AMP_CAL_ST4: | ||
1073 | case RT5663_HP_IMP_SEN_2: | ||
1074 | case RT5663_HP_IMP_SEN_3: | ||
1075 | case RT5663_HP_IMP_SEN_4: | ||
1076 | case RT5663_HP_IMP_SEN_10: | ||
1077 | case RT5663_HP_CALIB_1: | ||
1078 | case RT5663_HP_CALIB_10: | ||
1079 | case RT5663_HP_CALIB_ST1: | ||
1080 | case RT5663_HP_CALIB_ST4: | ||
1081 | case RT5663_HP_CALIB_ST5: | ||
1082 | case RT5663_HP_CALIB_ST6: | ||
1083 | case RT5663_HP_CALIB_ST7: | ||
1084 | case RT5663_HP_CALIB_ST8: | ||
1085 | case RT5663_HP_CALIB_ST9: | ||
1086 | case RT5668_HP_CALIB_ST10: | ||
1087 | case RT5668_HP_CALIB_ST11: | ||
1088 | return true; | ||
1089 | default: | ||
1090 | return false; | ||
1091 | } | ||
1092 | } | ||
1093 | |||
1094 | static bool rt5668_readable_register(struct device *dev, unsigned int reg) | ||
1095 | { | ||
1096 | switch (reg) { | ||
1097 | case RT5668_LOUT_CTRL: | ||
1098 | case RT5668_HP_AMP_2: | ||
1099 | case RT5668_MONO_OUT: | ||
1100 | case RT5668_MONO_GAIN: | ||
1101 | case RT5668_AEC_BST: | ||
1102 | case RT5668_IN1_IN2: | ||
1103 | case RT5668_IN3_IN4: | ||
1104 | case RT5668_INL1_INR1: | ||
1105 | case RT5668_CBJ_TYPE_2: | ||
1106 | case RT5668_CBJ_TYPE_3: | ||
1107 | case RT5668_CBJ_TYPE_4: | ||
1108 | case RT5668_CBJ_TYPE_5: | ||
1109 | case RT5668_CBJ_TYPE_8: | ||
1110 | case RT5668_DAC3_DIG_VOL: | ||
1111 | case RT5668_DAC3_CTRL: | ||
1112 | case RT5668_MONO_ADC_DIG_VOL: | ||
1113 | case RT5668_STO2_ADC_DIG_VOL: | ||
1114 | case RT5668_MONO_ADC_BST_GAIN: | ||
1115 | case RT5668_STO2_ADC_BST_GAIN: | ||
1116 | case RT5668_SIDETONE_CTRL: | ||
1117 | case RT5668_MONO1_ADC_MIXER: | ||
1118 | case RT5668_STO2_ADC_MIXER: | ||
1119 | case RT5668_MONO_DAC_MIXER: | ||
1120 | case RT5668_DAC2_SRC_CTRL: | ||
1121 | case RT5668_IF_3_4_DATA_CTL: | ||
1122 | case RT5668_IF_5_DATA_CTL: | ||
1123 | case RT5668_PDM_OUT_CTL: | ||
1124 | case RT5668_PDM_I2C_DATA_CTL1: | ||
1125 | case RT5668_PDM_I2C_DATA_CTL2: | ||
1126 | case RT5668_PDM_I2C_DATA_CTL3: | ||
1127 | case RT5668_PDM_I2C_DATA_CTL4: | ||
1128 | case RT5668_RECMIX1_NEW: | ||
1129 | case RT5668_RECMIX1L_0: | ||
1130 | case RT5668_RECMIX1L: | ||
1131 | case RT5668_RECMIX1R_0: | ||
1132 | case RT5668_RECMIX1R: | ||
1133 | case RT5668_RECMIX2_NEW: | ||
1134 | case RT5668_RECMIX2_L_2: | ||
1135 | case RT5668_RECMIX2_R: | ||
1136 | case RT5668_RECMIX2_R_2: | ||
1137 | case RT5668_CALIB_REC_LR: | ||
1138 | case RT5668_ALC_BK_GAIN: | ||
1139 | case RT5668_MONOMIX_GAIN: | ||
1140 | case RT5668_MONOMIX_IN_GAIN: | ||
1141 | case RT5668_OUT_MIXL_GAIN: | ||
1142 | case RT5668_OUT_LMIX_IN_GAIN: | ||
1143 | case RT5668_OUT_RMIX_IN_GAIN: | ||
1144 | case RT5668_OUT_RMIX_IN_GAIN1: | ||
1145 | case RT5668_LOUT_MIXER_CTRL: | ||
1146 | case RT5668_PWR_VOL: | ||
1147 | case RT5668_ADCDAC_RST: | ||
1148 | case RT5668_I2S34_SDP: | ||
1149 | case RT5668_I2S5_SDP: | ||
1150 | case RT5668_TDM_5: | ||
1151 | case RT5668_TDM_6: | ||
1152 | case RT5668_TDM_7: | ||
1153 | case RT5668_TDM_8: | ||
1154 | case RT5668_ASRC_3: | ||
1155 | case RT5668_ASRC_6: | ||
1156 | case RT5668_ASRC_7: | ||
1157 | case RT5668_PLL_TRK_13: | ||
1158 | case RT5668_I2S_M_CLK_CTL: | ||
1159 | case RT5668_FDIV_I2S34_M_CLK: | ||
1160 | case RT5668_FDIV_I2S34_M_CLK2: | ||
1161 | case RT5668_FDIV_I2S5_M_CLK: | ||
1162 | case RT5668_FDIV_I2S5_M_CLK2: | ||
1163 | case RT5668_IRQ_4: | ||
1164 | case RT5668_GPIO_3: | ||
1165 | case RT5668_GPIO_4: | ||
1166 | case RT5668_GPIO_STA: | ||
1167 | case RT5668_HP_AMP_DET1: | ||
1168 | case RT5668_HP_AMP_DET2: | ||
1169 | case RT5668_HP_AMP_DET3: | ||
1170 | case RT5668_MID_BD_HP_AMP: | ||
1171 | case RT5668_LOW_BD_HP_AMP: | ||
1172 | case RT5668_SOF_VOL_ZC2: | ||
1173 | case RT5668_ADC_STO2_ADJ1: | ||
1174 | case RT5668_ADC_STO2_ADJ2: | ||
1175 | case RT5668_A_JD_CTRL: | ||
1176 | case RT5668_JD1_TRES_CTRL: | ||
1177 | case RT5668_JD2_TRES_CTRL: | ||
1178 | case RT5668_JD_CTRL2: | ||
1179 | case RT5668_DUM_REG_2: | ||
1180 | case RT5668_DUM_REG_3: | ||
1181 | case RT5663_VENDOR_ID: | ||
1182 | case RT5663_VENDOR_ID_1: | ||
1183 | case RT5663_VENDOR_ID_2: | ||
1184 | case RT5668_DACADC_DIG_VOL2: | ||
1185 | case RT5668_DIG_IN_PIN2: | ||
1186 | case RT5668_PAD_DRV_CTL1: | ||
1187 | case RT5668_SOF_RAM_DEPOP: | ||
1188 | case RT5668_VOL_TEST: | ||
1189 | case RT5668_TEST_MODE_3: | ||
1190 | case RT5668_TEST_MODE_4: | ||
1191 | case RT5663_STO_DRE_9: | ||
1192 | case RT5668_MONO_DYNA_1: | ||
1193 | case RT5668_MONO_DYNA_2: | ||
1194 | case RT5668_MONO_DYNA_3: | ||
1195 | case RT5668_MONO_DYNA_4: | ||
1196 | case RT5668_MONO_DYNA_5: | ||
1197 | case RT5668_MONO_DYNA_6: | ||
1198 | case RT5668_STO1_SIL_DET: | ||
1199 | case RT5668_MONOL_SIL_DET: | ||
1200 | case RT5668_MONOR_SIL_DET: | ||
1201 | case RT5668_STO2_DAC_SIL: | ||
1202 | case RT5668_PWR_SAV_CTL1: | ||
1203 | case RT5668_PWR_SAV_CTL2: | ||
1204 | case RT5668_PWR_SAV_CTL3: | ||
1205 | case RT5668_PWR_SAV_CTL4: | ||
1206 | case RT5668_PWR_SAV_CTL5: | ||
1207 | case RT5668_PWR_SAV_CTL6: | ||
1208 | case RT5668_MONO_AMP_CAL1: | ||
1209 | case RT5668_MONO_AMP_CAL2: | ||
1210 | case RT5668_MONO_AMP_CAL3: | ||
1211 | case RT5668_MONO_AMP_CAL4: | ||
1212 | case RT5668_MONO_AMP_CAL5: | ||
1213 | case RT5668_MONO_AMP_CAL6: | ||
1214 | case RT5668_MONO_AMP_CAL7: | ||
1215 | case RT5668_MONO_AMP_CAL_ST1: | ||
1216 | case RT5668_MONO_AMP_CAL_ST2: | ||
1217 | case RT5668_MONO_AMP_CAL_ST3: | ||
1218 | case RT5668_MONO_AMP_CAL_ST4: | ||
1219 | case RT5668_MONO_AMP_CAL_ST5: | ||
1220 | case RT5668_HP_IMP_SEN_13: | ||
1221 | case RT5668_HP_IMP_SEN_14: | ||
1222 | case RT5668_HP_IMP_SEN_6: | ||
1223 | case RT5668_HP_IMP_SEN_7: | ||
1224 | case RT5668_HP_IMP_SEN_8: | ||
1225 | case RT5668_HP_IMP_SEN_9: | ||
1226 | case RT5668_HP_IMP_SEN_10: | ||
1227 | case RT5668_HP_LOGIC_3: | ||
1228 | case RT5668_HP_CALIB_ST10: | ||
1229 | case RT5668_HP_CALIB_ST11: | ||
1230 | case RT5668_PRO_REG_TBL_4: | ||
1231 | case RT5668_PRO_REG_TBL_5: | ||
1232 | case RT5668_PRO_REG_TBL_6: | ||
1233 | case RT5668_PRO_REG_TBL_7: | ||
1234 | case RT5668_PRO_REG_TBL_8: | ||
1235 | case RT5668_PRO_REG_TBL_9: | ||
1236 | case RT5668_SAR_ADC_INL_1: | ||
1237 | case RT5668_SAR_ADC_INL_2: | ||
1238 | case RT5668_SAR_ADC_INL_3: | ||
1239 | case RT5668_SAR_ADC_INL_4: | ||
1240 | case RT5668_SAR_ADC_INL_5: | ||
1241 | case RT5668_SAR_ADC_INL_6: | ||
1242 | case RT5668_SAR_ADC_INL_7: | ||
1243 | case RT5668_SAR_ADC_INL_8: | ||
1244 | case RT5668_SAR_ADC_INL_9: | ||
1245 | case RT5668_SAR_ADC_INL_10: | ||
1246 | case RT5668_SAR_ADC_INL_11: | ||
1247 | case RT5668_SAR_ADC_INL_12: | ||
1248 | case RT5668_DRC_CTRL_1: | ||
1249 | case RT5668_DRC1_CTRL_2: | ||
1250 | case RT5668_DRC1_CTRL_3: | ||
1251 | case RT5668_DRC1_CTRL_4: | ||
1252 | case RT5668_DRC1_CTRL_5: | ||
1253 | case RT5668_DRC1_CTRL_6: | ||
1254 | case RT5668_DRC1_HD_CTRL_1: | ||
1255 | case RT5668_DRC1_HD_CTRL_2: | ||
1256 | case RT5668_DRC1_PRI_REG_1: | ||
1257 | case RT5668_DRC1_PRI_REG_2: | ||
1258 | case RT5668_DRC1_PRI_REG_3: | ||
1259 | case RT5668_DRC1_PRI_REG_4: | ||
1260 | case RT5668_DRC1_PRI_REG_5: | ||
1261 | case RT5668_DRC1_PRI_REG_6: | ||
1262 | case RT5668_DRC1_PRI_REG_7: | ||
1263 | case RT5668_DRC1_PRI_REG_8: | ||
1264 | case RT5668_ALC_PGA_CTL_1: | ||
1265 | case RT5668_ALC_PGA_CTL_2: | ||
1266 | case RT5668_ALC_PGA_CTL_3: | ||
1267 | case RT5668_ALC_PGA_CTL_4: | ||
1268 | case RT5668_ALC_PGA_CTL_5: | ||
1269 | case RT5668_ALC_PGA_CTL_6: | ||
1270 | case RT5668_ALC_PGA_CTL_7: | ||
1271 | case RT5668_ALC_PGA_CTL_8: | ||
1272 | case RT5668_ALC_PGA_REG_1: | ||
1273 | case RT5668_ALC_PGA_REG_2: | ||
1274 | case RT5668_ALC_PGA_REG_3: | ||
1275 | case RT5668_ADC_EQ_RECOV_1: | ||
1276 | case RT5668_ADC_EQ_RECOV_2: | ||
1277 | case RT5668_ADC_EQ_RECOV_3: | ||
1278 | case RT5668_ADC_EQ_RECOV_4: | ||
1279 | case RT5668_ADC_EQ_RECOV_5: | ||
1280 | case RT5668_ADC_EQ_RECOV_6: | ||
1281 | case RT5668_ADC_EQ_RECOV_7: | ||
1282 | case RT5668_ADC_EQ_RECOV_8: | ||
1283 | case RT5668_ADC_EQ_RECOV_9: | ||
1284 | case RT5668_ADC_EQ_RECOV_10: | ||
1285 | case RT5668_ADC_EQ_RECOV_11: | ||
1286 | case RT5668_ADC_EQ_RECOV_12: | ||
1287 | case RT5668_ADC_EQ_RECOV_13: | ||
1288 | case RT5668_VID_HIDDEN: | ||
1289 | case RT5668_VID_CUSTOMER: | ||
1290 | case RT5668_SCAN_MODE: | ||
1291 | case RT5668_I2C_BYPA: | ||
1292 | return true; | ||
1293 | case RT5663_TDM_1: | ||
1294 | case RT5663_DEPOP_3: | ||
1295 | case RT5663_ASRC_11_2: | ||
1296 | case RT5663_INT_ST_2: | ||
1297 | case RT5663_GPIO_STA: | ||
1298 | case RT5663_SIN_GEN_1: | ||
1299 | case RT5663_SIN_GEN_2: | ||
1300 | case RT5663_SIN_GEN_3: | ||
1301 | case RT5663_IL_CMD_PWRSAV1: | ||
1302 | case RT5663_IL_CMD_PWRSAV2: | ||
1303 | case RT5663_EM_JACK_TYPE_1: | ||
1304 | case RT5663_EM_JACK_TYPE_2: | ||
1305 | case RT5663_EM_JACK_TYPE_3: | ||
1306 | case RT5663_EM_JACK_TYPE_4: | ||
1307 | case RT5663_FAST_OFF_MICBIAS: | ||
1308 | case RT5663_ANA_BIAS_CUR_1: | ||
1309 | case RT5663_ANA_BIAS_CUR_2: | ||
1310 | case RT5663_BIAS_CUR_9: | ||
1311 | case RT5663_DUMMY_REG_4: | ||
1312 | case RT5663_VREF_RECMIX: | ||
1313 | case RT5663_CHARGE_PUMP_1_2: | ||
1314 | case RT5663_CHARGE_PUMP_1_3: | ||
1315 | case RT5663_CHARGE_PUMP_2: | ||
1316 | case RT5663_CHOP_DAC_R: | ||
1317 | case RT5663_DUMMY_CTL_DACLR: | ||
1318 | case RT5663_DUMMY_REG_5: | ||
1319 | case RT5663_SOFT_RAMP: | ||
1320 | case RT5663_TEST_MODE_1: | ||
1321 | case RT5663_STO_DRE_10: | ||
1322 | case RT5663_MIC_DECRO_1: | ||
1323 | case RT5663_MIC_DECRO_2: | ||
1324 | case RT5663_MIC_DECRO_3: | ||
1325 | case RT5663_MIC_DECRO_4: | ||
1326 | case RT5663_MIC_DECRO_5: | ||
1327 | case RT5663_MIC_DECRO_6: | ||
1328 | case RT5663_HP_DECRO_1: | ||
1329 | case RT5663_HP_DECRO_2: | ||
1330 | case RT5663_HP_DECRO_3: | ||
1331 | case RT5663_HP_DECRO_4: | ||
1332 | case RT5663_HP_DECOUP: | ||
1333 | case RT5663_HP_IMPSEN_MAP4: | ||
1334 | case RT5663_HP_IMPSEN_MAP5: | ||
1335 | case RT5663_HP_IMPSEN_MAP7: | ||
1336 | case RT5663_HP_CALIB_1: | ||
1337 | case RT5663_CBJ_1: | ||
1338 | case RT5663_CBJ_2: | ||
1339 | case RT5663_CBJ_3: | ||
1340 | return false; | ||
1341 | default: | ||
1342 | return rt5663_readable_register(dev, reg); | ||
1343 | } | ||
1344 | } | ||
1345 | |||
1346 | static const DECLARE_TLV_DB_SCALE(rt5663_hp_vol_tlv, -2400, 150, 0); | ||
1347 | static const DECLARE_TLV_DB_SCALE(rt5668_hp_vol_tlv, -2250, 150, 0); | ||
1348 | static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6525, 75, 0); | ||
1349 | static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1725, 75, 0); | ||
1350 | |||
1351 | /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ | ||
1352 | static const DECLARE_TLV_DB_RANGE(in_bst_tlv, | ||
1353 | 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), | ||
1354 | 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), | ||
1355 | 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), | ||
1356 | 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0), | ||
1357 | 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0), | ||
1358 | 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0), | ||
1359 | 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0) | ||
1360 | ); | ||
1361 | |||
1362 | /* Interface data select */ | ||
1363 | static const char * const rt5663_if1_adc_data_select[] = { | ||
1364 | "L/R", "R/L", "L/L", "R/R" | ||
1365 | }; | ||
1366 | |||
1367 | static SOC_ENUM_SINGLE_DECL(rt5663_if1_adc_enum, RT5663_TDM_2, | ||
1368 | RT5663_DATA_SWAP_ADCDAT1_SHIFT, rt5663_if1_adc_data_select); | ||
1369 | |||
1370 | static void rt5663_enable_push_button_irq(struct snd_soc_codec *codec, | ||
1371 | bool enable) | ||
1372 | { | ||
1373 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
1374 | |||
1375 | if (enable) { | ||
1376 | snd_soc_update_bits(codec, RT5663_IL_CMD_6, | ||
1377 | RT5668_EN_4BTN_INL_MASK, RT5668_EN_4BTN_INL_EN); | ||
1378 | /* reset in-line command */ | ||
1379 | snd_soc_update_bits(codec, RT5663_IL_CMD_6, | ||
1380 | RT5668_RESET_4BTN_INL_MASK, | ||
1381 | RT5668_RESET_4BTN_INL_RESET); | ||
1382 | snd_soc_update_bits(codec, RT5663_IL_CMD_6, | ||
1383 | RT5668_RESET_4BTN_INL_MASK, | ||
1384 | RT5668_RESET_4BTN_INL_NOR); | ||
1385 | switch (rt5663->codec_type) { | ||
1386 | case CODEC_TYPE_RT5668: | ||
1387 | snd_soc_update_bits(codec, RT5663_IRQ_3, | ||
1388 | RT5668_EN_IRQ_INLINE_MASK, | ||
1389 | RT5668_EN_IRQ_INLINE_NOR); | ||
1390 | break; | ||
1391 | case CODEC_TYPE_RT5663: | ||
1392 | snd_soc_update_bits(codec, RT5663_IRQ_2, | ||
1393 | RT5663_EN_IRQ_INLINE_MASK, | ||
1394 | RT5663_EN_IRQ_INLINE_NOR); | ||
1395 | break; | ||
1396 | default: | ||
1397 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
1398 | } | ||
1399 | } else { | ||
1400 | switch (rt5663->codec_type) { | ||
1401 | case CODEC_TYPE_RT5668: | ||
1402 | snd_soc_update_bits(codec, RT5663_IRQ_3, | ||
1403 | RT5668_EN_IRQ_INLINE_MASK, | ||
1404 | RT5668_EN_IRQ_INLINE_BYP); | ||
1405 | break; | ||
1406 | case CODEC_TYPE_RT5663: | ||
1407 | snd_soc_update_bits(codec, RT5663_IRQ_2, | ||
1408 | RT5663_EN_IRQ_INLINE_MASK, | ||
1409 | RT5663_EN_IRQ_INLINE_BYP); | ||
1410 | break; | ||
1411 | default: | ||
1412 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
1413 | } | ||
1414 | snd_soc_update_bits(codec, RT5663_IL_CMD_6, | ||
1415 | RT5668_EN_4BTN_INL_MASK, RT5668_EN_4BTN_INL_DIS); | ||
1416 | /* reset in-line command */ | ||
1417 | snd_soc_update_bits(codec, RT5663_IL_CMD_6, | ||
1418 | RT5668_RESET_4BTN_INL_MASK, | ||
1419 | RT5668_RESET_4BTN_INL_RESET); | ||
1420 | snd_soc_update_bits(codec, RT5663_IL_CMD_6, | ||
1421 | RT5668_RESET_4BTN_INL_MASK, | ||
1422 | RT5668_RESET_4BTN_INL_NOR); | ||
1423 | } | ||
1424 | } | ||
1425 | |||
1426 | /** | ||
1427 | * rt5668_jack_detect - Detect headset. | ||
1428 | * @codec: SoC audio codec device. | ||
1429 | * @jack_insert: Jack insert or not. | ||
1430 | * | ||
1431 | * Detect whether is headset or not when jack inserted. | ||
1432 | * | ||
1433 | * Returns detect status. | ||
1434 | */ | ||
1435 | |||
1436 | static int rt5668_jack_detect(struct snd_soc_codec *codec, int jack_insert) | ||
1437 | { | ||
1438 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | ||
1439 | struct rt5663_priv *rt5668 = snd_soc_codec_get_drvdata(codec); | ||
1440 | int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30}; | ||
1441 | |||
1442 | dev_dbg(codec->dev, "%s jack_insert:%d\n", __func__, jack_insert); | ||
1443 | if (jack_insert) { | ||
1444 | snd_soc_write(codec, RT5668_CBJ_TYPE_2, 0x8040); | ||
1445 | snd_soc_write(codec, RT5668_CBJ_TYPE_3, 0x1484); | ||
1446 | |||
1447 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); | ||
1448 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS2"); | ||
1449 | snd_soc_dapm_force_enable_pin(dapm, "Mic Det Power"); | ||
1450 | snd_soc_dapm_force_enable_pin(dapm, "CBJ Power"); | ||
1451 | snd_soc_dapm_sync(dapm); | ||
1452 | snd_soc_update_bits(codec, RT5663_RC_CLK, | ||
1453 | RT5668_DIG_1M_CLK_MASK, RT5668_DIG_1M_CLK_EN); | ||
1454 | snd_soc_update_bits(codec, RT5663_RECMIX, 0x8, 0x8); | ||
1455 | |||
1456 | while (i < 5) { | ||
1457 | msleep(sleep_time[i]); | ||
1458 | val = snd_soc_read(codec, RT5668_CBJ_TYPE_2) & 0x0003; | ||
1459 | if (val == 0x1 || val == 0x2 || val == 0x3) | ||
1460 | break; | ||
1461 | dev_dbg(codec->dev, "%s: MX-0011 val=%x sleep %d\n", | ||
1462 | __func__, val, sleep_time[i]); | ||
1463 | i++; | ||
1464 | } | ||
1465 | dev_dbg(codec->dev, "%s val = %d\n", __func__, val); | ||
1466 | switch (val) { | ||
1467 | case 1: | ||
1468 | case 2: | ||
1469 | rt5668->jack_type = SND_JACK_HEADSET; | ||
1470 | rt5663_enable_push_button_irq(codec, true); | ||
1471 | break; | ||
1472 | default: | ||
1473 | snd_soc_dapm_disable_pin(dapm, "MICBIAS1"); | ||
1474 | snd_soc_dapm_disable_pin(dapm, "MICBIAS2"); | ||
1475 | snd_soc_dapm_disable_pin(dapm, "Mic Det Power"); | ||
1476 | snd_soc_dapm_disable_pin(dapm, "CBJ Power"); | ||
1477 | snd_soc_dapm_sync(dapm); | ||
1478 | rt5668->jack_type = SND_JACK_HEADPHONE; | ||
1479 | break; | ||
1480 | } | ||
1481 | } else { | ||
1482 | snd_soc_update_bits(codec, RT5663_RECMIX, 0x8, 0x0); | ||
1483 | |||
1484 | if (rt5668->jack_type == SND_JACK_HEADSET) { | ||
1485 | rt5663_enable_push_button_irq(codec, false); | ||
1486 | snd_soc_dapm_disable_pin(dapm, "MICBIAS1"); | ||
1487 | snd_soc_dapm_disable_pin(dapm, "MICBIAS2"); | ||
1488 | snd_soc_dapm_disable_pin(dapm, "Mic Det Power"); | ||
1489 | snd_soc_dapm_disable_pin(dapm, "CBJ Power"); | ||
1490 | snd_soc_dapm_sync(dapm); | ||
1491 | } | ||
1492 | rt5668->jack_type = 0; | ||
1493 | } | ||
1494 | |||
1495 | dev_dbg(codec->dev, "jack_type = %d\n", rt5668->jack_type); | ||
1496 | return rt5668->jack_type; | ||
1497 | } | ||
1498 | |||
1499 | /** | ||
1500 | * rt5663_jack_detect - Detect headset. | ||
1501 | * @codec: SoC audio codec device. | ||
1502 | * @jack_insert: Jack insert or not. | ||
1503 | * | ||
1504 | * Detect whether is headset or not when jack inserted. | ||
1505 | * | ||
1506 | * Returns detect status. | ||
1507 | */ | ||
1508 | static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert) | ||
1509 | { | ||
1510 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
1511 | int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30}; | ||
1512 | |||
1513 | dev_dbg(codec->dev, "%s jack_insert:%d\n", __func__, jack_insert); | ||
1514 | |||
1515 | if (jack_insert) { | ||
1516 | snd_soc_update_bits(codec, RT5663_DIG_MISC, | ||
1517 | RT5668_DIG_GATE_CTRL_MASK, RT5668_DIG_GATE_CTRL_EN); | ||
1518 | snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, | ||
1519 | RT5663_SI_HP_MASK | RT5668_OSW_HP_L_MASK | | ||
1520 | RT5668_OSW_HP_R_MASK, RT5663_SI_HP_EN | | ||
1521 | RT5668_OSW_HP_L_DIS | RT5668_OSW_HP_R_DIS); | ||
1522 | snd_soc_update_bits(codec, RT5663_DUMMY_1, | ||
1523 | RT5663_EMB_CLK_MASK | RT5663_HPA_CPL_BIAS_MASK | | ||
1524 | RT5663_HPA_CPR_BIAS_MASK, RT5663_EMB_CLK_EN | | ||
1525 | RT5663_HPA_CPL_BIAS_1 | RT5663_HPA_CPR_BIAS_1); | ||
1526 | snd_soc_update_bits(codec, RT5663_CBJ_1, | ||
1527 | RT5663_INBUF_CBJ_BST1_MASK | RT5663_CBJ_SENSE_BST1_MASK, | ||
1528 | RT5663_INBUF_CBJ_BST1_ON | RT5663_CBJ_SENSE_BST1_L); | ||
1529 | snd_soc_update_bits(codec, RT5663_IL_CMD_2, | ||
1530 | RT5663_PWR_MIC_DET_MASK, RT5663_PWR_MIC_DET_ON); | ||
1531 | /* BST1 power on for JD */ | ||
1532 | snd_soc_update_bits(codec, RT5663_PWR_ANLG_2, | ||
1533 | RT5668_PWR_BST1_MASK, RT5668_PWR_BST1_ON); | ||
1534 | snd_soc_update_bits(codec, RT5663_EM_JACK_TYPE_1, | ||
1535 | RT5663_CBJ_DET_MASK | RT5663_EXT_JD_MASK | | ||
1536 | RT5663_POL_EXT_JD_MASK, RT5663_CBJ_DET_EN | | ||
1537 | RT5663_EXT_JD_EN | RT5663_POL_EXT_JD_EN); | ||
1538 | snd_soc_update_bits(codec, RT5663_PWR_ANLG_1, | ||
1539 | RT5668_PWR_MB_MASK | RT5668_LDO1_DVO_MASK | | ||
1540 | RT5668_AMP_HP_MASK, RT5668_PWR_MB | | ||
1541 | RT5668_LDO1_DVO_0_9V | RT5668_AMP_HP_3X); | ||
1542 | snd_soc_update_bits(codec, RT5663_AUTO_1MRC_CLK, | ||
1543 | RT5668_IRQ_POW_SAV_MASK, RT5668_IRQ_POW_SAV_EN); | ||
1544 | snd_soc_update_bits(codec, RT5663_IRQ_1, | ||
1545 | RT5663_EN_IRQ_JD1_MASK, RT5663_EN_IRQ_JD1_EN); | ||
1546 | while (i < 5) { | ||
1547 | msleep(sleep_time[i]); | ||
1548 | val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) & | ||
1549 | 0x0003; | ||
1550 | i++; | ||
1551 | if (val == 0x1 || val == 0x2 || val == 0x3) | ||
1552 | break; | ||
1553 | dev_dbg(codec->dev, "%s: MX-00e7 val=%x sleep %d\n", | ||
1554 | __func__, val, sleep_time[i]); | ||
1555 | } | ||
1556 | dev_dbg(codec->dev, "%s val = %d\n", __func__, val); | ||
1557 | switch (val) { | ||
1558 | case 1: | ||
1559 | case 2: | ||
1560 | rt5663->jack_type = SND_JACK_HEADSET; | ||
1561 | rt5663_enable_push_button_irq(codec, true); | ||
1562 | break; | ||
1563 | default: | ||
1564 | rt5663->jack_type = SND_JACK_HEADPHONE; | ||
1565 | break; | ||
1566 | } | ||
1567 | } else { | ||
1568 | if (rt5663->jack_type == SND_JACK_HEADSET) | ||
1569 | rt5663_enable_push_button_irq(codec, false); | ||
1570 | rt5663->jack_type = 0; | ||
1571 | } | ||
1572 | |||
1573 | dev_dbg(codec->dev, "jack_type = %d\n", rt5663->jack_type); | ||
1574 | return rt5663->jack_type; | ||
1575 | } | ||
1576 | |||
1577 | static int rt5663_button_detect(struct snd_soc_codec *codec) | ||
1578 | { | ||
1579 | int btn_type, val; | ||
1580 | |||
1581 | val = snd_soc_read(codec, RT5663_IL_CMD_5); | ||
1582 | dev_dbg(codec->dev, "%s: val=0x%x\n", __func__, val); | ||
1583 | btn_type = val & 0xfff0; | ||
1584 | snd_soc_write(codec, RT5663_IL_CMD_5, val); | ||
1585 | |||
1586 | return btn_type; | ||
1587 | } | ||
1588 | |||
1589 | static irqreturn_t rt5663_irq(int irq, void *data) | ||
1590 | { | ||
1591 | struct rt5663_priv *rt5663 = data; | ||
1592 | |||
1593 | dev_dbg(rt5663->codec->dev, "%s IRQ queue work\n", __func__); | ||
1594 | |||
1595 | queue_delayed_work(system_wq, &rt5663->jack_detect_work, | ||
1596 | msecs_to_jiffies(250)); | ||
1597 | |||
1598 | return IRQ_HANDLED; | ||
1599 | } | ||
1600 | |||
1601 | int rt5663_set_jack_detect(struct snd_soc_codec *codec, | ||
1602 | struct snd_soc_jack *hs_jack) | ||
1603 | { | ||
1604 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
1605 | |||
1606 | rt5663->hs_jack = hs_jack; | ||
1607 | |||
1608 | rt5663_irq(0, rt5663); | ||
1609 | |||
1610 | return 0; | ||
1611 | } | ||
1612 | EXPORT_SYMBOL_GPL(rt5663_set_jack_detect); | ||
1613 | |||
1614 | static bool rt5663_check_jd_status(struct snd_soc_codec *codec) | ||
1615 | { | ||
1616 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
1617 | int val = snd_soc_read(codec, RT5663_INT_ST_1); | ||
1618 | |||
1619 | dev_dbg(codec->dev, "%s val=%x\n", __func__, val); | ||
1620 | |||
1621 | /* JD1 */ | ||
1622 | switch (rt5663->codec_type) { | ||
1623 | case CODEC_TYPE_RT5668: | ||
1624 | return !(val & 0x2000); | ||
1625 | case CODEC_TYPE_RT5663: | ||
1626 | return !(val & 0x1000); | ||
1627 | default: | ||
1628 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
1629 | } | ||
1630 | |||
1631 | return false; | ||
1632 | } | ||
1633 | |||
1634 | static void rt5663_jack_detect_work(struct work_struct *work) | ||
1635 | { | ||
1636 | struct rt5663_priv *rt5663 = | ||
1637 | container_of(work, struct rt5663_priv, jack_detect_work.work); | ||
1638 | struct snd_soc_codec *codec = rt5663->codec; | ||
1639 | int btn_type, report = 0; | ||
1640 | |||
1641 | if (!codec) | ||
1642 | return; | ||
1643 | |||
1644 | if (rt5663_check_jd_status(codec)) { | ||
1645 | /* jack in */ | ||
1646 | if (rt5663->jack_type == 0) { | ||
1647 | /* jack was out, report jack type */ | ||
1648 | switch (rt5663->codec_type) { | ||
1649 | case CODEC_TYPE_RT5668: | ||
1650 | report = rt5668_jack_detect(rt5663->codec, 1); | ||
1651 | break; | ||
1652 | case CODEC_TYPE_RT5663: | ||
1653 | report = rt5663_jack_detect(rt5663->codec, 1); | ||
1654 | break; | ||
1655 | default: | ||
1656 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
1657 | } | ||
1658 | } else { | ||
1659 | /* jack is already in, report button event */ | ||
1660 | report = SND_JACK_HEADSET; | ||
1661 | btn_type = rt5663_button_detect(rt5663->codec); | ||
1662 | /** | ||
1663 | * rt5663 can report three kinds of button behavior, | ||
1664 | * one click, double click and hold. However, | ||
1665 | * currently we will report button pressed/released | ||
1666 | * event. So all the three button behaviors are | ||
1667 | * treated as button pressed. | ||
1668 | */ | ||
1669 | switch (btn_type) { | ||
1670 | case 0x8000: | ||
1671 | case 0x4000: | ||
1672 | case 0x2000: | ||
1673 | report |= SND_JACK_BTN_0; | ||
1674 | break; | ||
1675 | case 0x1000: | ||
1676 | case 0x0800: | ||
1677 | case 0x0400: | ||
1678 | report |= SND_JACK_BTN_1; | ||
1679 | break; | ||
1680 | case 0x0200: | ||
1681 | case 0x0100: | ||
1682 | case 0x0080: | ||
1683 | report |= SND_JACK_BTN_2; | ||
1684 | break; | ||
1685 | case 0x0040: | ||
1686 | case 0x0020: | ||
1687 | case 0x0010: | ||
1688 | report |= SND_JACK_BTN_3; | ||
1689 | break; | ||
1690 | case 0x0000: /* unpressed */ | ||
1691 | break; | ||
1692 | default: | ||
1693 | btn_type = 0; | ||
1694 | dev_err(rt5663->codec->dev, | ||
1695 | "Unexpected button code 0x%04x\n", | ||
1696 | btn_type); | ||
1697 | break; | ||
1698 | } | ||
1699 | /* button release or spurious interrput*/ | ||
1700 | if (btn_type == 0) | ||
1701 | report = rt5663->jack_type; | ||
1702 | } | ||
1703 | } else { | ||
1704 | /* jack out */ | ||
1705 | switch (rt5663->codec_type) { | ||
1706 | case CODEC_TYPE_RT5668: | ||
1707 | report = rt5668_jack_detect(rt5663->codec, 0); | ||
1708 | break; | ||
1709 | case CODEC_TYPE_RT5663: | ||
1710 | report = rt5663_jack_detect(rt5663->codec, 0); | ||
1711 | break; | ||
1712 | default: | ||
1713 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
1714 | } | ||
1715 | } | ||
1716 | dev_dbg(codec->dev, "%s jack report: 0x%04x\n", __func__, report); | ||
1717 | snd_soc_jack_report(rt5663->hs_jack, report, SND_JACK_HEADSET | | ||
1718 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | | ||
1719 | SND_JACK_BTN_2 | SND_JACK_BTN_3); | ||
1720 | } | ||
1721 | |||
1722 | static const struct snd_kcontrol_new rt5663_snd_controls[] = { | ||
1723 | /* DAC Digital Volume */ | ||
1724 | SOC_DOUBLE_TLV("DAC Playback Volume", RT5663_STO1_DAC_DIG_VOL, | ||
1725 | RT5668_DAC_L1_VOL_SHIFT + 1, RT5668_DAC_R1_VOL_SHIFT + 1, | ||
1726 | 87, 0, dac_vol_tlv), | ||
1727 | /* ADC Digital Volume Control */ | ||
1728 | SOC_DOUBLE("ADC Capture Switch", RT5663_STO1_ADC_DIG_VOL, | ||
1729 | RT5668_ADC_L_MUTE_SHIFT, RT5668_ADC_R_MUTE_SHIFT, 1, 1), | ||
1730 | SOC_DOUBLE_TLV("ADC Capture Volume", RT5663_STO1_ADC_DIG_VOL, | ||
1731 | RT5668_ADC_L_VOL_SHIFT + 1, RT5668_ADC_R_VOL_SHIFT + 1, | ||
1732 | 63, 0, adc_vol_tlv), | ||
1733 | }; | ||
1734 | |||
1735 | static const struct snd_kcontrol_new rt5668_specific_controls[] = { | ||
1736 | /* Headphone Output Volume */ | ||
1737 | SOC_DOUBLE_R_TLV("Headphone Playback Volume", RT5663_HP_LCH_DRE, | ||
1738 | RT5663_HP_RCH_DRE, RT5668_GAIN_HP_SHIFT, 15, 1, | ||
1739 | rt5668_hp_vol_tlv), | ||
1740 | /* Mic Boost Volume */ | ||
1741 | SOC_SINGLE_TLV("IN1 Capture Volume", RT5668_AEC_BST, | ||
1742 | RT5668_GAIN_CBJ_SHIFT, 8, 0, in_bst_tlv), | ||
1743 | }; | ||
1744 | |||
1745 | static const struct snd_kcontrol_new rt5663_specific_controls[] = { | ||
1746 | /* Headphone Output Volume */ | ||
1747 | SOC_DOUBLE_R_TLV("Headphone Playback Volume", RT5663_STO_DRE_9, | ||
1748 | RT5663_STO_DRE_10, RT5663_DRE_GAIN_HP_SHIFT, 23, 1, | ||
1749 | rt5663_hp_vol_tlv), | ||
1750 | /* Mic Boost Volume*/ | ||
1751 | SOC_SINGLE_TLV("IN1 Capture Volume", RT5663_CBJ_2, | ||
1752 | RT5663_GAIN_BST1_SHIFT, 8, 0, in_bst_tlv), | ||
1753 | /* Data Swap for Slot0/1 in ADCDAT1 */ | ||
1754 | SOC_ENUM("IF1 ADC Data Swap", rt5663_if1_adc_enum), | ||
1755 | }; | ||
1756 | |||
1757 | static int rt5663_is_sys_clk_from_pll(struct snd_soc_dapm_widget *w, | ||
1758 | struct snd_soc_dapm_widget *sink) | ||
1759 | { | ||
1760 | unsigned int val; | ||
1761 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
1762 | |||
1763 | val = snd_soc_read(codec, RT5663_GLB_CLK); | ||
1764 | val &= RT5663_SCLK_SRC_MASK; | ||
1765 | if (val == RT5663_SCLK_SRC_PLL1) | ||
1766 | return 1; | ||
1767 | else | ||
1768 | return 0; | ||
1769 | } | ||
1770 | |||
1771 | static int rt5663_is_using_asrc(struct snd_soc_dapm_widget *w, | ||
1772 | struct snd_soc_dapm_widget *sink) | ||
1773 | { | ||
1774 | unsigned int reg, shift, val; | ||
1775 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
1776 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
1777 | |||
1778 | if (rt5663->codec_type == CODEC_TYPE_RT5668) { | ||
1779 | switch (w->shift) { | ||
1780 | case RT5668_ADC_STO1_ASRC_SHIFT: | ||
1781 | reg = RT5668_ASRC_3; | ||
1782 | shift = RT5668_AD_STO1_TRACK_SHIFT; | ||
1783 | break; | ||
1784 | case RT5668_DAC_STO1_ASRC_SHIFT: | ||
1785 | reg = RT5663_ASRC_2; | ||
1786 | shift = RT5668_DA_STO1_TRACK_SHIFT; | ||
1787 | break; | ||
1788 | default: | ||
1789 | return 0; | ||
1790 | } | ||
1791 | } else { | ||
1792 | switch (w->shift) { | ||
1793 | case RT5663_ADC_STO1_ASRC_SHIFT: | ||
1794 | reg = RT5663_ASRC_2; | ||
1795 | shift = RT5663_AD_STO1_TRACK_SHIFT; | ||
1796 | break; | ||
1797 | case RT5663_DAC_STO1_ASRC_SHIFT: | ||
1798 | reg = RT5663_ASRC_2; | ||
1799 | shift = RT5663_DA_STO1_TRACK_SHIFT; | ||
1800 | break; | ||
1801 | default: | ||
1802 | return 0; | ||
1803 | } | ||
1804 | } | ||
1805 | |||
1806 | val = (snd_soc_read(codec, reg) >> shift) & 0x7; | ||
1807 | |||
1808 | if (val) | ||
1809 | return 1; | ||
1810 | |||
1811 | return 0; | ||
1812 | } | ||
1813 | |||
1814 | static int rt5663_i2s_use_asrc(struct snd_soc_dapm_widget *source, | ||
1815 | struct snd_soc_dapm_widget *sink) | ||
1816 | { | ||
1817 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
1818 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
1819 | int da_asrc_en, ad_asrc_en; | ||
1820 | |||
1821 | da_asrc_en = (snd_soc_read(codec, RT5663_ASRC_2) & | ||
1822 | RT5663_DA_STO1_TRACK_MASK) ? 1 : 0; | ||
1823 | switch (rt5663->codec_type) { | ||
1824 | case CODEC_TYPE_RT5668: | ||
1825 | ad_asrc_en = (snd_soc_read(codec, RT5668_ASRC_3) & | ||
1826 | RT5668_AD_STO1_TRACK_MASK) ? 1 : 0; | ||
1827 | break; | ||
1828 | case CODEC_TYPE_RT5663: | ||
1829 | ad_asrc_en = (snd_soc_read(codec, RT5663_ASRC_2) & | ||
1830 | RT5663_AD_STO1_TRACK_MASK) ? 1 : 0; | ||
1831 | break; | ||
1832 | default: | ||
1833 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
1834 | return 1; | ||
1835 | } | ||
1836 | |||
1837 | if (da_asrc_en || ad_asrc_en) | ||
1838 | if (rt5663->sysclk > rt5663->lrck * 384) | ||
1839 | return 1; | ||
1840 | |||
1841 | dev_err(codec->dev, "sysclk < 384 x fs, disable i2s asrc\n"); | ||
1842 | |||
1843 | return 0; | ||
1844 | } | ||
1845 | |||
1846 | /** | ||
1847 | * rt5663_sel_asrc_clk_src - select ASRC clock source for a set of filters | ||
1848 | * @codec: SoC audio codec device. | ||
1849 | * @filter_mask: mask of filters. | ||
1850 | * @clk_src: clock source | ||
1851 | * | ||
1852 | * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5668 can | ||
1853 | * only support standard 32fs or 64fs i2s format, ASRC should be enabled to | ||
1854 | * support special i2s clock format such as Intel's 100fs(100 * sampling rate). | ||
1855 | * ASRC function will track i2s clock and generate a corresponding system clock | ||
1856 | * for codec. This function provides an API to select the clock source for a | ||
1857 | * set of filters specified by the mask. And the codec driver will turn on ASRC | ||
1858 | * for these filters if ASRC is selected as their clock source. | ||
1859 | */ | ||
1860 | int rt5663_sel_asrc_clk_src(struct snd_soc_codec *codec, | ||
1861 | unsigned int filter_mask, unsigned int clk_src) | ||
1862 | { | ||
1863 | struct rt5663_priv *rt5668 = snd_soc_codec_get_drvdata(codec); | ||
1864 | unsigned int asrc2_mask = 0; | ||
1865 | unsigned int asrc2_value = 0; | ||
1866 | unsigned int asrc3_mask = 0; | ||
1867 | unsigned int asrc3_value = 0; | ||
1868 | |||
1869 | switch (clk_src) { | ||
1870 | case RT5663_CLK_SEL_SYS: | ||
1871 | case RT5663_CLK_SEL_I2S1_ASRC: | ||
1872 | break; | ||
1873 | |||
1874 | default: | ||
1875 | return -EINVAL; | ||
1876 | } | ||
1877 | |||
1878 | if (filter_mask & RT5663_DA_STEREO_FILTER) { | ||
1879 | asrc2_mask |= RT5668_DA_STO1_TRACK_MASK; | ||
1880 | asrc2_value |= clk_src << RT5668_DA_STO1_TRACK_SHIFT; | ||
1881 | } | ||
1882 | |||
1883 | if (filter_mask & RT5663_AD_STEREO_FILTER) { | ||
1884 | switch (rt5668->codec_type) { | ||
1885 | case CODEC_TYPE_RT5668: | ||
1886 | asrc3_mask |= RT5668_AD_STO1_TRACK_MASK; | ||
1887 | asrc3_value |= clk_src << RT5668_AD_STO1_TRACK_SHIFT; | ||
1888 | break; | ||
1889 | case CODEC_TYPE_RT5663: | ||
1890 | asrc2_mask |= RT5663_AD_STO1_TRACK_MASK; | ||
1891 | asrc2_value |= clk_src << RT5663_AD_STO1_TRACK_SHIFT; | ||
1892 | break; | ||
1893 | default: | ||
1894 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
1895 | } | ||
1896 | } | ||
1897 | |||
1898 | if (asrc2_mask) | ||
1899 | snd_soc_update_bits(codec, RT5663_ASRC_2, asrc2_mask, | ||
1900 | asrc2_value); | ||
1901 | |||
1902 | if (asrc3_mask) | ||
1903 | snd_soc_update_bits(codec, RT5668_ASRC_3, asrc3_mask, | ||
1904 | asrc3_value); | ||
1905 | |||
1906 | return 0; | ||
1907 | } | ||
1908 | EXPORT_SYMBOL_GPL(rt5663_sel_asrc_clk_src); | ||
1909 | |||
1910 | /* Analog Mixer */ | ||
1911 | static const struct snd_kcontrol_new rt5668_recmix1l[] = { | ||
1912 | SOC_DAPM_SINGLE("BST2 Switch", RT5668_RECMIX1L, | ||
1913 | RT5668_RECMIX1L_BST2_SHIFT, 1, 1), | ||
1914 | SOC_DAPM_SINGLE("BST1 CBJ Switch", RT5668_RECMIX1L, | ||
1915 | RT5668_RECMIX1L_BST1_CBJ_SHIFT, 1, 1), | ||
1916 | }; | ||
1917 | |||
1918 | static const struct snd_kcontrol_new rt5668_recmix1r[] = { | ||
1919 | SOC_DAPM_SINGLE("BST2 Switch", RT5668_RECMIX1R, | ||
1920 | RT5668_RECMIX1R_BST2_SHIFT, 1, 1), | ||
1921 | }; | ||
1922 | |||
1923 | /* Digital Mixer */ | ||
1924 | static const struct snd_kcontrol_new rt5663_sto1_adc_l_mix[] = { | ||
1925 | SOC_DAPM_SINGLE("ADC1 Switch", RT5663_STO1_ADC_MIXER, | ||
1926 | RT5668_M_STO1_ADC_L1_SHIFT, 1, 1), | ||
1927 | SOC_DAPM_SINGLE("ADC2 Switch", RT5663_STO1_ADC_MIXER, | ||
1928 | RT5668_M_STO1_ADC_L2_SHIFT, 1, 1), | ||
1929 | }; | ||
1930 | |||
1931 | static const struct snd_kcontrol_new rt5668_sto1_adc_r_mix[] = { | ||
1932 | SOC_DAPM_SINGLE("ADC1 Switch", RT5663_STO1_ADC_MIXER, | ||
1933 | RT5668_M_STO1_ADC_R1_SHIFT, 1, 1), | ||
1934 | SOC_DAPM_SINGLE("ADC2 Switch", RT5663_STO1_ADC_MIXER, | ||
1935 | RT5668_M_STO1_ADC_R2_SHIFT, 1, 1), | ||
1936 | }; | ||
1937 | |||
1938 | static const struct snd_kcontrol_new rt5663_adda_l_mix[] = { | ||
1939 | SOC_DAPM_SINGLE("ADC L Switch", RT5663_AD_DA_MIXER, | ||
1940 | RT5668_M_ADCMIX_L_SHIFT, 1, 1), | ||
1941 | SOC_DAPM_SINGLE("DAC L Switch", RT5663_AD_DA_MIXER, | ||
1942 | RT5668_M_DAC1_L_SHIFT, 1, 1), | ||
1943 | }; | ||
1944 | |||
1945 | static const struct snd_kcontrol_new rt5663_adda_r_mix[] = { | ||
1946 | SOC_DAPM_SINGLE("ADC R Switch", RT5663_AD_DA_MIXER, | ||
1947 | RT5668_M_ADCMIX_R_SHIFT, 1, 1), | ||
1948 | SOC_DAPM_SINGLE("DAC R Switch", RT5663_AD_DA_MIXER, | ||
1949 | RT5668_M_DAC1_R_SHIFT, 1, 1), | ||
1950 | }; | ||
1951 | |||
1952 | static const struct snd_kcontrol_new rt5663_sto1_dac_l_mix[] = { | ||
1953 | SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER, | ||
1954 | RT5668_M_DAC_L1_STO_L_SHIFT, 1, 1), | ||
1955 | SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER, | ||
1956 | RT5668_M_DAC_R1_STO_L_SHIFT, 1, 1), | ||
1957 | }; | ||
1958 | |||
1959 | static const struct snd_kcontrol_new rt5663_sto1_dac_r_mix[] = { | ||
1960 | SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER, | ||
1961 | RT5668_M_DAC_L1_STO_R_SHIFT, 1, 1), | ||
1962 | SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER, | ||
1963 | RT5668_M_DAC_R1_STO_R_SHIFT, 1, 1), | ||
1964 | }; | ||
1965 | |||
1966 | /* Out Switch */ | ||
1967 | static const struct snd_kcontrol_new rt5668_hpo_switch = | ||
1968 | SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5668_HP_AMP_2, | ||
1969 | RT5668_EN_DAC_HPO_SHIFT, 1, 0); | ||
1970 | |||
1971 | /* Stereo ADC source */ | ||
1972 | static const char * const rt5668_sto1_adc_src[] = { | ||
1973 | "ADC L", "ADC R" | ||
1974 | }; | ||
1975 | |||
1976 | static SOC_ENUM_SINGLE_DECL(rt5668_sto1_adcl_enum, RT5663_STO1_ADC_MIXER, | ||
1977 | RT5668_STO1_ADC_L_SRC_SHIFT, rt5668_sto1_adc_src); | ||
1978 | |||
1979 | static const struct snd_kcontrol_new rt5668_sto1_adcl_mux = | ||
1980 | SOC_DAPM_ENUM("STO1 ADC L Mux", rt5668_sto1_adcl_enum); | ||
1981 | |||
1982 | static SOC_ENUM_SINGLE_DECL(rt5668_sto1_adcr_enum, RT5663_STO1_ADC_MIXER, | ||
1983 | RT5668_STO1_ADC_R_SRC_SHIFT, rt5668_sto1_adc_src); | ||
1984 | |||
1985 | static const struct snd_kcontrol_new rt5668_sto1_adcr_mux = | ||
1986 | SOC_DAPM_ENUM("STO1 ADC R Mux", rt5668_sto1_adcr_enum); | ||
1987 | |||
1988 | /* RT5663: Analog DACL1 input source */ | ||
1989 | static const char * const rt5663_alg_dacl_src[] = { | ||
1990 | "DAC L", "STO DAC MIXL" | ||
1991 | }; | ||
1992 | |||
1993 | static SOC_ENUM_SINGLE_DECL(rt5663_alg_dacl_enum, RT5663_BYPASS_STO_DAC, | ||
1994 | RT5663_DACL1_SRC_SHIFT, rt5663_alg_dacl_src); | ||
1995 | |||
1996 | static const struct snd_kcontrol_new rt5663_alg_dacl_mux = | ||
1997 | SOC_DAPM_ENUM("DAC L Mux", rt5663_alg_dacl_enum); | ||
1998 | |||
1999 | /* RT5663: Analog DACR1 input source */ | ||
2000 | static const char * const rt5663_alg_dacr_src[] = { | ||
2001 | "DAC R", "STO DAC MIXR" | ||
2002 | }; | ||
2003 | |||
2004 | static SOC_ENUM_SINGLE_DECL(rt5663_alg_dacr_enum, RT5663_BYPASS_STO_DAC, | ||
2005 | RT5663_DACR1_SRC_SHIFT, rt5663_alg_dacr_src); | ||
2006 | |||
2007 | static const struct snd_kcontrol_new rt5663_alg_dacr_mux = | ||
2008 | SOC_DAPM_ENUM("DAC R Mux", rt5663_alg_dacr_enum); | ||
2009 | |||
2010 | static int rt5663_hp_event(struct snd_soc_dapm_widget *w, | ||
2011 | struct snd_kcontrol *kcontrol, int event) | ||
2012 | { | ||
2013 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
2014 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2015 | |||
2016 | switch (event) { | ||
2017 | case SND_SOC_DAPM_POST_PMU: | ||
2018 | if (rt5663->codec_type == CODEC_TYPE_RT5668) { | ||
2019 | snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, | ||
2020 | RT5668_SEL_PM_HP_SHIFT, RT5668_SEL_PM_HP_HIGH); | ||
2021 | snd_soc_update_bits(codec, RT5663_HP_LOGIC_2, | ||
2022 | RT5668_HP_SIG_SRC1_MASK, | ||
2023 | RT5668_HP_SIG_SRC1_SILENCE); | ||
2024 | } else { | ||
2025 | snd_soc_write(codec, RT5663_DEPOP_2, 0x3003); | ||
2026 | snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x000b, | ||
2027 | 0x000b); | ||
2028 | snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, | ||
2029 | 0x0030); | ||
2030 | snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, | ||
2031 | RT5668_OVCD_HP_MASK, RT5668_OVCD_HP_DIS); | ||
2032 | snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_2, 0x1371); | ||
2033 | snd_soc_write(codec, RT5663_HP_BIAS, 0xabba); | ||
2034 | snd_soc_write(codec, RT5663_CHARGE_PUMP_1, 0x2224); | ||
2035 | snd_soc_write(codec, RT5663_ANA_BIAS_CUR_1, 0x7766); | ||
2036 | snd_soc_write(codec, RT5663_HP_BIAS, 0xafaa); | ||
2037 | snd_soc_write(codec, RT5663_CHARGE_PUMP_2, 0x7777); | ||
2038 | snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, | ||
2039 | 0x3000); | ||
2040 | } | ||
2041 | break; | ||
2042 | |||
2043 | case SND_SOC_DAPM_PRE_PMD: | ||
2044 | if (rt5663->codec_type == CODEC_TYPE_RT5668) { | ||
2045 | snd_soc_update_bits(codec, RT5663_HP_LOGIC_2, | ||
2046 | RT5668_HP_SIG_SRC1_MASK, | ||
2047 | RT5668_HP_SIG_SRC1_REG); | ||
2048 | } else { | ||
2049 | snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x0); | ||
2050 | snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, | ||
2051 | RT5668_OVCD_HP_MASK, RT5668_OVCD_HP_EN); | ||
2052 | snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0x0); | ||
2053 | snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x000b, | ||
2054 | 0x000b); | ||
2055 | } | ||
2056 | break; | ||
2057 | |||
2058 | default: | ||
2059 | return 0; | ||
2060 | } | ||
2061 | |||
2062 | return 0; | ||
2063 | } | ||
2064 | |||
2065 | static int rt5668_bst2_power(struct snd_soc_dapm_widget *w, | ||
2066 | struct snd_kcontrol *kcontrol, int event) | ||
2067 | { | ||
2068 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
2069 | |||
2070 | switch (event) { | ||
2071 | case SND_SOC_DAPM_POST_PMU: | ||
2072 | snd_soc_update_bits(codec, RT5663_PWR_ANLG_2, | ||
2073 | RT5668_PWR_BST2_MASK | RT5668_PWR_BST2_OP_MASK, | ||
2074 | RT5668_PWR_BST2 | RT5668_PWR_BST2_OP); | ||
2075 | break; | ||
2076 | |||
2077 | case SND_SOC_DAPM_PRE_PMD: | ||
2078 | snd_soc_update_bits(codec, RT5663_PWR_ANLG_2, | ||
2079 | RT5668_PWR_BST2_MASK | RT5668_PWR_BST2_OP_MASK, 0); | ||
2080 | break; | ||
2081 | |||
2082 | default: | ||
2083 | return 0; | ||
2084 | } | ||
2085 | |||
2086 | return 0; | ||
2087 | } | ||
2088 | |||
2089 | static int rt5663_pre_div_power(struct snd_soc_dapm_widget *w, | ||
2090 | struct snd_kcontrol *kcontrol, int event) | ||
2091 | { | ||
2092 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
2093 | |||
2094 | switch (event) { | ||
2095 | case SND_SOC_DAPM_POST_PMU: | ||
2096 | snd_soc_write(codec, RT5663_PRE_DIV_GATING_1, 0xff00); | ||
2097 | snd_soc_write(codec, RT5663_PRE_DIV_GATING_2, 0xfffc); | ||
2098 | break; | ||
2099 | |||
2100 | case SND_SOC_DAPM_PRE_PMD: | ||
2101 | snd_soc_write(codec, RT5663_PRE_DIV_GATING_1, 0x0000); | ||
2102 | snd_soc_write(codec, RT5663_PRE_DIV_GATING_2, 0x0000); | ||
2103 | break; | ||
2104 | |||
2105 | default: | ||
2106 | return 0; | ||
2107 | } | ||
2108 | |||
2109 | return 0; | ||
2110 | } | ||
2111 | |||
2112 | static const struct snd_soc_dapm_widget rt5663_dapm_widgets[] = { | ||
2113 | SND_SOC_DAPM_SUPPLY("PLL", RT5663_PWR_ANLG_3, RT5668_PWR_PLL_SHIFT, 0, | ||
2114 | NULL, 0), | ||
2115 | |||
2116 | /* micbias */ | ||
2117 | SND_SOC_DAPM_MICBIAS("MICBIAS1", RT5663_PWR_ANLG_2, | ||
2118 | RT5668_PWR_MB1_SHIFT, 0), | ||
2119 | SND_SOC_DAPM_MICBIAS("MICBIAS2", RT5663_PWR_ANLG_2, | ||
2120 | RT5668_PWR_MB2_SHIFT, 0), | ||
2121 | |||
2122 | /* Input Lines */ | ||
2123 | SND_SOC_DAPM_INPUT("IN1P"), | ||
2124 | SND_SOC_DAPM_INPUT("IN1N"), | ||
2125 | |||
2126 | /* REC Mixer Power */ | ||
2127 | SND_SOC_DAPM_SUPPLY("RECMIX1L Power", RT5663_PWR_ANLG_2, | ||
2128 | RT5668_PWR_RECMIX1_SHIFT, 0, NULL, 0), | ||
2129 | |||
2130 | /* ADCs */ | ||
2131 | SND_SOC_DAPM_ADC("ADC L", NULL, SND_SOC_NOPM, 0, 0), | ||
2132 | SND_SOC_DAPM_SUPPLY("ADC L Power", RT5663_PWR_DIG_1, | ||
2133 | RT5668_PWR_ADC_L1_SHIFT, 0, NULL, 0), | ||
2134 | SND_SOC_DAPM_SUPPLY("ADC Clock", RT5663_CHOP_ADC, | ||
2135 | RT5668_CKGEN_ADCC_SHIFT, 0, NULL, 0), | ||
2136 | |||
2137 | /* ADC Mixer */ | ||
2138 | SND_SOC_DAPM_MIXER("STO1 ADC MIXL", SND_SOC_NOPM, | ||
2139 | 0, 0, rt5663_sto1_adc_l_mix, | ||
2140 | ARRAY_SIZE(rt5663_sto1_adc_l_mix)), | ||
2141 | |||
2142 | /* ADC Filter Power */ | ||
2143 | SND_SOC_DAPM_SUPPLY("STO1 ADC Filter", RT5663_PWR_DIG_2, | ||
2144 | RT5668_PWR_ADC_S1F_SHIFT, 0, NULL, 0), | ||
2145 | |||
2146 | /* Digital Interface */ | ||
2147 | SND_SOC_DAPM_SUPPLY("I2S", RT5663_PWR_DIG_1, RT5668_PWR_I2S1_SHIFT, 0, | ||
2148 | NULL, 0), | ||
2149 | SND_SOC_DAPM_PGA("IF DAC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2150 | SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2151 | SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2152 | SND_SOC_DAPM_PGA("IF1 ADC1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2153 | SND_SOC_DAPM_PGA("IF ADC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2154 | |||
2155 | /* Audio Interface */ | ||
2156 | SND_SOC_DAPM_AIF_IN("AIFRX", "AIF Playback", 0, SND_SOC_NOPM, 0, 0), | ||
2157 | SND_SOC_DAPM_AIF_OUT("AIFTX", "AIF Capture", 0, SND_SOC_NOPM, 0, 0), | ||
2158 | |||
2159 | /* DAC mixer before sound effect */ | ||
2160 | SND_SOC_DAPM_MIXER("ADDA MIXL", SND_SOC_NOPM, 0, 0, rt5663_adda_l_mix, | ||
2161 | ARRAY_SIZE(rt5663_adda_l_mix)), | ||
2162 | SND_SOC_DAPM_MIXER("ADDA MIXR", SND_SOC_NOPM, 0, 0, rt5663_adda_r_mix, | ||
2163 | ARRAY_SIZE(rt5663_adda_r_mix)), | ||
2164 | SND_SOC_DAPM_PGA("DAC L1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2165 | SND_SOC_DAPM_PGA("DAC R1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2166 | |||
2167 | /* DAC Mixer */ | ||
2168 | SND_SOC_DAPM_SUPPLY("STO1 DAC Filter", RT5663_PWR_DIG_2, | ||
2169 | RT5668_PWR_DAC_S1F_SHIFT, 0, NULL, 0), | ||
2170 | SND_SOC_DAPM_MIXER("STO1 DAC MIXL", SND_SOC_NOPM, 0, 0, | ||
2171 | rt5663_sto1_dac_l_mix, ARRAY_SIZE(rt5663_sto1_dac_l_mix)), | ||
2172 | SND_SOC_DAPM_MIXER("STO1 DAC MIXR", SND_SOC_NOPM, 0, 0, | ||
2173 | rt5663_sto1_dac_r_mix, ARRAY_SIZE(rt5663_sto1_dac_r_mix)), | ||
2174 | |||
2175 | /* DACs */ | ||
2176 | SND_SOC_DAPM_SUPPLY("STO1 DAC L Power", RT5663_PWR_DIG_1, | ||
2177 | RT5668_PWR_DAC_L1_SHIFT, 0, NULL, 0), | ||
2178 | SND_SOC_DAPM_SUPPLY("STO1 DAC R Power", RT5663_PWR_DIG_1, | ||
2179 | RT5668_PWR_DAC_R1_SHIFT, 0, NULL, 0), | ||
2180 | SND_SOC_DAPM_DAC("DAC L", NULL, SND_SOC_NOPM, 0, 0), | ||
2181 | SND_SOC_DAPM_DAC("DAC R", NULL, SND_SOC_NOPM, 0, 0), | ||
2182 | |||
2183 | /* Headphone*/ | ||
2184 | SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5663_hp_event, | ||
2185 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
2186 | |||
2187 | /* Output Lines */ | ||
2188 | SND_SOC_DAPM_OUTPUT("HPOL"), | ||
2189 | SND_SOC_DAPM_OUTPUT("HPOR"), | ||
2190 | }; | ||
2191 | |||
2192 | static const struct snd_soc_dapm_widget rt5668_specific_dapm_widgets[] = { | ||
2193 | SND_SOC_DAPM_SUPPLY("LDO2", RT5663_PWR_ANLG_3, | ||
2194 | RT5668_PWR_LDO2_SHIFT, 0, NULL, 0), | ||
2195 | SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5668_PWR_VOL, | ||
2196 | RT5668_PWR_MIC_DET_SHIFT, 0, NULL, 0), | ||
2197 | SND_SOC_DAPM_SUPPLY("LDO DAC", RT5663_PWR_DIG_1, | ||
2198 | RT5668_PWR_LDO_DACREF_SHIFT, 0, NULL, 0), | ||
2199 | |||
2200 | /* ASRC */ | ||
2201 | SND_SOC_DAPM_SUPPLY("I2S ASRC", RT5663_ASRC_1, | ||
2202 | RT5668_I2S1_ASRC_SHIFT, 0, NULL, 0), | ||
2203 | SND_SOC_DAPM_SUPPLY("DAC ASRC", RT5663_ASRC_1, | ||
2204 | RT5668_DAC_STO1_ASRC_SHIFT, 0, NULL, 0), | ||
2205 | SND_SOC_DAPM_SUPPLY("ADC ASRC", RT5663_ASRC_1, | ||
2206 | RT5668_ADC_STO1_ASRC_SHIFT, 0, NULL, 0), | ||
2207 | |||
2208 | /* Input Lines */ | ||
2209 | SND_SOC_DAPM_INPUT("IN2P"), | ||
2210 | SND_SOC_DAPM_INPUT("IN2N"), | ||
2211 | |||
2212 | /* Boost */ | ||
2213 | SND_SOC_DAPM_PGA("BST1 CBJ", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2214 | SND_SOC_DAPM_SUPPLY("CBJ Power", RT5663_PWR_ANLG_3, | ||
2215 | RT5668_PWR_CBJ_SHIFT, 0, NULL, 0), | ||
2216 | SND_SOC_DAPM_PGA("BST2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2217 | SND_SOC_DAPM_SUPPLY("BST2 Power", SND_SOC_NOPM, 0, 0, | ||
2218 | rt5668_bst2_power, SND_SOC_DAPM_PRE_PMD | | ||
2219 | SND_SOC_DAPM_POST_PMU), | ||
2220 | |||
2221 | /* REC Mixer */ | ||
2222 | SND_SOC_DAPM_MIXER("RECMIX1L", SND_SOC_NOPM, 0, 0, rt5668_recmix1l, | ||
2223 | ARRAY_SIZE(rt5668_recmix1l)), | ||
2224 | SND_SOC_DAPM_MIXER("RECMIX1R", SND_SOC_NOPM, 0, 0, rt5668_recmix1r, | ||
2225 | ARRAY_SIZE(rt5668_recmix1r)), | ||
2226 | SND_SOC_DAPM_SUPPLY("RECMIX1R Power", RT5663_PWR_ANLG_2, | ||
2227 | RT5668_PWR_RECMIX2_SHIFT, 0, NULL, 0), | ||
2228 | |||
2229 | /* ADC */ | ||
2230 | SND_SOC_DAPM_ADC("ADC R", NULL, SND_SOC_NOPM, 0, 0), | ||
2231 | SND_SOC_DAPM_SUPPLY("ADC R Power", RT5663_PWR_DIG_1, | ||
2232 | RT5668_PWR_ADC_R1_SHIFT, 0, NULL, 0), | ||
2233 | |||
2234 | /* ADC Mux */ | ||
2235 | SND_SOC_DAPM_PGA("STO1 ADC L1", RT5663_STO1_ADC_MIXER, | ||
2236 | RT5668_STO1_ADC_L1_SRC_SHIFT, 0, NULL, 0), | ||
2237 | SND_SOC_DAPM_PGA("STO1 ADC R1", RT5663_STO1_ADC_MIXER, | ||
2238 | RT5668_STO1_ADC_R1_SRC_SHIFT, 0, NULL, 0), | ||
2239 | SND_SOC_DAPM_PGA("STO1 ADC L2", RT5663_STO1_ADC_MIXER, | ||
2240 | RT5668_STO1_ADC_L2_SRC_SHIFT, 1, NULL, 0), | ||
2241 | SND_SOC_DAPM_PGA("STO1 ADC R2", RT5663_STO1_ADC_MIXER, | ||
2242 | RT5668_STO1_ADC_R2_SRC_SHIFT, 1, NULL, 0), | ||
2243 | |||
2244 | SND_SOC_DAPM_MUX("STO1 ADC L Mux", SND_SOC_NOPM, 0, 0, | ||
2245 | &rt5668_sto1_adcl_mux), | ||
2246 | SND_SOC_DAPM_MUX("STO1 ADC R Mux", SND_SOC_NOPM, 0, 0, | ||
2247 | &rt5668_sto1_adcr_mux), | ||
2248 | |||
2249 | /* ADC Mix */ | ||
2250 | SND_SOC_DAPM_MIXER("STO1 ADC MIXR", SND_SOC_NOPM, 0, 0, | ||
2251 | rt5668_sto1_adc_r_mix, ARRAY_SIZE(rt5668_sto1_adc_r_mix)), | ||
2252 | |||
2253 | /* Analog DAC Clock */ | ||
2254 | SND_SOC_DAPM_SUPPLY("DAC Clock", RT5663_CHOP_DAC_L, | ||
2255 | RT5668_CKGEN_DAC1_SHIFT, 0, NULL, 0), | ||
2256 | |||
2257 | /* Headphone out */ | ||
2258 | SND_SOC_DAPM_SWITCH("HPO Playback", SND_SOC_NOPM, 0, 0, | ||
2259 | &rt5668_hpo_switch), | ||
2260 | }; | ||
2261 | |||
2262 | static const struct snd_soc_dapm_widget rt5663_specific_dapm_widgets[] = { | ||
2263 | /* System Clock Pre Divider Gating */ | ||
2264 | SND_SOC_DAPM_SUPPLY("Pre Div Power", SND_SOC_NOPM, 0, 0, | ||
2265 | rt5663_pre_div_power, SND_SOC_DAPM_POST_PMU | | ||
2266 | SND_SOC_DAPM_PRE_PMD), | ||
2267 | |||
2268 | /* LDO */ | ||
2269 | SND_SOC_DAPM_SUPPLY("LDO ADC", RT5663_PWR_DIG_1, | ||
2270 | RT5668_PWR_LDO_DACREF_SHIFT, 0, NULL, 0), | ||
2271 | |||
2272 | /* ASRC */ | ||
2273 | SND_SOC_DAPM_SUPPLY("I2S ASRC", RT5663_ASRC_1, | ||
2274 | RT5663_I2S1_ASRC_SHIFT, 0, NULL, 0), | ||
2275 | SND_SOC_DAPM_SUPPLY("DAC ASRC", RT5663_ASRC_1, | ||
2276 | RT5663_DAC_STO1_ASRC_SHIFT, 0, NULL, 0), | ||
2277 | SND_SOC_DAPM_SUPPLY("ADC ASRC", RT5663_ASRC_1, | ||
2278 | RT5663_ADC_STO1_ASRC_SHIFT, 0, NULL, 0), | ||
2279 | |||
2280 | /* Boost */ | ||
2281 | SND_SOC_DAPM_PGA("BST1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2282 | |||
2283 | /* STO ADC */ | ||
2284 | SND_SOC_DAPM_PGA("STO1 ADC L1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2285 | SND_SOC_DAPM_PGA("STO1 ADC L2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2286 | |||
2287 | /* Analog DAC source */ | ||
2288 | SND_SOC_DAPM_MUX("DAC L Mux", SND_SOC_NOPM, 0, 0, &rt5663_alg_dacl_mux), | ||
2289 | SND_SOC_DAPM_MUX("DAC R Mux", SND_SOC_NOPM, 0, 0, &rt5663_alg_dacr_mux), | ||
2290 | }; | ||
2291 | |||
2292 | static const struct snd_soc_dapm_route rt5663_dapm_routes[] = { | ||
2293 | /* PLL */ | ||
2294 | { "I2S", NULL, "PLL", rt5663_is_sys_clk_from_pll }, | ||
2295 | |||
2296 | /* ASRC */ | ||
2297 | { "STO1 ADC Filter", NULL, "ADC ASRC", rt5663_is_using_asrc }, | ||
2298 | { "STO1 DAC Filter", NULL, "DAC ASRC", rt5663_is_using_asrc }, | ||
2299 | { "I2S", NULL, "I2S ASRC", rt5663_i2s_use_asrc }, | ||
2300 | |||
2301 | { "ADC L", NULL, "ADC L Power" }, | ||
2302 | { "ADC L", NULL, "ADC Clock" }, | ||
2303 | |||
2304 | { "STO1 ADC L2", NULL, "STO1 DAC MIXL" }, | ||
2305 | |||
2306 | { "STO1 ADC MIXL", "ADC1 Switch", "STO1 ADC L1" }, | ||
2307 | { "STO1 ADC MIXL", "ADC2 Switch", "STO1 ADC L2" }, | ||
2308 | { "STO1 ADC MIXL", NULL, "STO1 ADC Filter" }, | ||
2309 | |||
2310 | { "IF1 ADC1", NULL, "STO1 ADC MIXL" }, | ||
2311 | { "IF ADC", NULL, "IF1 ADC1" }, | ||
2312 | { "AIFTX", NULL, "IF ADC" }, | ||
2313 | { "AIFTX", NULL, "I2S" }, | ||
2314 | |||
2315 | { "AIFRX", NULL, "I2S" }, | ||
2316 | { "IF DAC", NULL, "AIFRX" }, | ||
2317 | { "IF1 DAC1 L", NULL, "IF DAC" }, | ||
2318 | { "IF1 DAC1 R", NULL, "IF DAC" }, | ||
2319 | |||
2320 | { "ADDA MIXL", "ADC L Switch", "STO1 ADC MIXL" }, | ||
2321 | { "ADDA MIXL", "DAC L Switch", "IF1 DAC1 L" }, | ||
2322 | { "ADDA MIXL", NULL, "STO1 DAC Filter" }, | ||
2323 | { "ADDA MIXL", NULL, "STO1 DAC L Power" }, | ||
2324 | { "ADDA MIXR", "DAC R Switch", "IF1 DAC1 R" }, | ||
2325 | { "ADDA MIXR", NULL, "STO1 DAC Filter" }, | ||
2326 | { "ADDA MIXR", NULL, "STO1 DAC R Power" }, | ||
2327 | |||
2328 | { "DAC L1", NULL, "ADDA MIXL" }, | ||
2329 | { "DAC R1", NULL, "ADDA MIXR" }, | ||
2330 | |||
2331 | { "STO1 DAC MIXL", "DAC L Switch", "DAC L1" }, | ||
2332 | { "STO1 DAC MIXL", "DAC R Switch", "DAC R1" }, | ||
2333 | { "STO1 DAC MIXL", NULL, "STO1 DAC L Power" }, | ||
2334 | { "STO1 DAC MIXL", NULL, "STO1 DAC Filter" }, | ||
2335 | { "STO1 DAC MIXR", "DAC R Switch", "DAC R1" }, | ||
2336 | { "STO1 DAC MIXR", "DAC L Switch", "DAC L1" }, | ||
2337 | { "STO1 DAC MIXR", NULL, "STO1 DAC R Power" }, | ||
2338 | { "STO1 DAC MIXR", NULL, "STO1 DAC Filter" }, | ||
2339 | |||
2340 | { "HP Amp", NULL, "DAC L" }, | ||
2341 | { "HP Amp", NULL, "DAC R" }, | ||
2342 | }; | ||
2343 | |||
2344 | static const struct snd_soc_dapm_route rt5668_specific_dapm_routes[] = { | ||
2345 | { "MICBIAS1", NULL, "LDO2" }, | ||
2346 | { "MICBIAS2", NULL, "LDO2" }, | ||
2347 | |||
2348 | { "BST1 CBJ", NULL, "IN1P" }, | ||
2349 | { "BST1 CBJ", NULL, "IN1N" }, | ||
2350 | { "BST1 CBJ", NULL, "CBJ Power" }, | ||
2351 | |||
2352 | { "BST2", NULL, "IN2P" }, | ||
2353 | { "BST2", NULL, "IN2N" }, | ||
2354 | { "BST2", NULL, "BST2 Power" }, | ||
2355 | |||
2356 | { "RECMIX1L", "BST2 Switch", "BST2" }, | ||
2357 | { "RECMIX1L", "BST1 CBJ Switch", "BST1 CBJ" }, | ||
2358 | { "RECMIX1L", NULL, "RECMIX1L Power" }, | ||
2359 | { "RECMIX1R", "BST2 Switch", "BST2" }, | ||
2360 | { "RECMIX1R", NULL, "RECMIX1R Power" }, | ||
2361 | |||
2362 | { "ADC L", NULL, "RECMIX1L" }, | ||
2363 | { "ADC R", NULL, "RECMIX1R" }, | ||
2364 | { "ADC R", NULL, "ADC R Power" }, | ||
2365 | { "ADC R", NULL, "ADC Clock" }, | ||
2366 | |||
2367 | { "STO1 ADC L Mux", "ADC L", "ADC L" }, | ||
2368 | { "STO1 ADC L Mux", "ADC R", "ADC R" }, | ||
2369 | { "STO1 ADC L1", NULL, "STO1 ADC L Mux" }, | ||
2370 | |||
2371 | { "STO1 ADC R Mux", "ADC L", "ADC L" }, | ||
2372 | { "STO1 ADC R Mux", "ADC R", "ADC R" }, | ||
2373 | { "STO1 ADC R1", NULL, "STO1 ADC R Mux" }, | ||
2374 | { "STO1 ADC R2", NULL, "STO1 DAC MIXR" }, | ||
2375 | |||
2376 | { "STO1 ADC MIXR", "ADC1 Switch", "STO1 ADC R1" }, | ||
2377 | { "STO1 ADC MIXR", "ADC2 Switch", "STO1 ADC R2" }, | ||
2378 | { "STO1 ADC MIXR", NULL, "STO1 ADC Filter" }, | ||
2379 | |||
2380 | { "IF1 ADC1", NULL, "STO1 ADC MIXR" }, | ||
2381 | |||
2382 | { "ADDA MIXR", "ADC R Switch", "STO1 ADC MIXR" }, | ||
2383 | |||
2384 | { "DAC L", NULL, "STO1 DAC MIXL" }, | ||
2385 | { "DAC L", NULL, "LDO DAC" }, | ||
2386 | { "DAC L", NULL, "DAC Clock" }, | ||
2387 | { "DAC R", NULL, "STO1 DAC MIXR" }, | ||
2388 | { "DAC R", NULL, "LDO DAC" }, | ||
2389 | { "DAC R", NULL, "DAC Clock" }, | ||
2390 | |||
2391 | { "HPO Playback", "Switch", "HP Amp" }, | ||
2392 | { "HPOL", NULL, "HPO Playback" }, | ||
2393 | { "HPOR", NULL, "HPO Playback" }, | ||
2394 | }; | ||
2395 | |||
2396 | static const struct snd_soc_dapm_route rt5663_specific_dapm_routes[] = { | ||
2397 | { "I2S", NULL, "Pre Div Power" }, | ||
2398 | |||
2399 | { "BST1", NULL, "IN1P" }, | ||
2400 | { "BST1", NULL, "IN1N" }, | ||
2401 | { "BST1", NULL, "RECMIX1L Power" }, | ||
2402 | |||
2403 | { "ADC L", NULL, "BST1" }, | ||
2404 | |||
2405 | { "STO1 ADC L1", NULL, "ADC L" }, | ||
2406 | |||
2407 | { "DAC L Mux", "DAC L", "DAC L1" }, | ||
2408 | { "DAC L Mux", "STO DAC MIXL", "STO1 DAC MIXL" }, | ||
2409 | { "DAC R Mux", "DAC R", "DAC R1"}, | ||
2410 | { "DAC R Mux", "STO DAC MIXR", "STO1 DAC MIXR" }, | ||
2411 | |||
2412 | { "DAC L", NULL, "DAC L Mux" }, | ||
2413 | { "DAC R", NULL, "DAC R Mux" }, | ||
2414 | |||
2415 | { "HPOL", NULL, "HP Amp" }, | ||
2416 | { "HPOR", NULL, "HP Amp" }, | ||
2417 | }; | ||
2418 | |||
2419 | static int rt5663_hw_params(struct snd_pcm_substream *substream, | ||
2420 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | ||
2421 | { | ||
2422 | struct snd_soc_codec *codec = dai->codec; | ||
2423 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2424 | unsigned int val_len = 0; | ||
2425 | int pre_div; | ||
2426 | |||
2427 | rt5663->lrck = params_rate(params); | ||
2428 | |||
2429 | dev_dbg(dai->dev, "bclk is %dHz and sysclk is %dHz\n", | ||
2430 | rt5663->lrck, rt5663->sysclk); | ||
2431 | |||
2432 | pre_div = rl6231_get_clk_info(rt5663->sysclk, rt5663->lrck); | ||
2433 | if (pre_div < 0) { | ||
2434 | dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n", | ||
2435 | rt5663->lrck, dai->id); | ||
2436 | return -EINVAL; | ||
2437 | } | ||
2438 | |||
2439 | dev_dbg(dai->dev, "pre_div is %d for iis %d\n", pre_div, dai->id); | ||
2440 | |||
2441 | switch (params_width(params)) { | ||
2442 | case 8: | ||
2443 | val_len = RT5668_I2S_DL_8; | ||
2444 | break; | ||
2445 | case 16: | ||
2446 | val_len = RT5668_I2S_DL_16; | ||
2447 | break; | ||
2448 | case 20: | ||
2449 | val_len = RT5668_I2S_DL_20; | ||
2450 | break; | ||
2451 | case 24: | ||
2452 | val_len = RT5668_I2S_DL_24; | ||
2453 | break; | ||
2454 | default: | ||
2455 | return -EINVAL; | ||
2456 | } | ||
2457 | |||
2458 | snd_soc_update_bits(codec, RT5663_I2S1_SDP, | ||
2459 | RT5668_I2S_DL_MASK, val_len); | ||
2460 | |||
2461 | snd_soc_update_bits(codec, RT5663_ADDA_CLK_1, | ||
2462 | RT5668_I2S_PD1_MASK, pre_div << RT5668_I2S_PD1_SHIFT); | ||
2463 | |||
2464 | return 0; | ||
2465 | } | ||
2466 | |||
2467 | static int rt5663_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
2468 | { | ||
2469 | struct snd_soc_codec *codec = dai->codec; | ||
2470 | unsigned int reg_val = 0; | ||
2471 | |||
2472 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
2473 | case SND_SOC_DAIFMT_CBM_CFM: | ||
2474 | break; | ||
2475 | case SND_SOC_DAIFMT_CBS_CFS: | ||
2476 | reg_val |= RT5668_I2S_MS_S; | ||
2477 | break; | ||
2478 | default: | ||
2479 | return -EINVAL; | ||
2480 | } | ||
2481 | |||
2482 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
2483 | case SND_SOC_DAIFMT_NB_NF: | ||
2484 | break; | ||
2485 | case SND_SOC_DAIFMT_IB_NF: | ||
2486 | reg_val |= RT5668_I2S_BP_INV; | ||
2487 | break; | ||
2488 | default: | ||
2489 | return -EINVAL; | ||
2490 | } | ||
2491 | |||
2492 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
2493 | case SND_SOC_DAIFMT_I2S: | ||
2494 | break; | ||
2495 | case SND_SOC_DAIFMT_LEFT_J: | ||
2496 | reg_val |= RT5668_I2S_DF_LEFT; | ||
2497 | break; | ||
2498 | case SND_SOC_DAIFMT_DSP_A: | ||
2499 | reg_val |= RT5668_I2S_DF_PCM_A; | ||
2500 | break; | ||
2501 | case SND_SOC_DAIFMT_DSP_B: | ||
2502 | reg_val |= RT5668_I2S_DF_PCM_B; | ||
2503 | break; | ||
2504 | default: | ||
2505 | return -EINVAL; | ||
2506 | } | ||
2507 | |||
2508 | snd_soc_update_bits(codec, RT5663_I2S1_SDP, RT5668_I2S_MS_MASK | | ||
2509 | RT5668_I2S_BP_MASK | RT5668_I2S_DF_MASK, reg_val); | ||
2510 | |||
2511 | return 0; | ||
2512 | } | ||
2513 | |||
2514 | static int rt5663_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, | ||
2515 | unsigned int freq, int dir) | ||
2516 | { | ||
2517 | struct snd_soc_codec *codec = dai->codec; | ||
2518 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2519 | unsigned int reg_val = 0; | ||
2520 | |||
2521 | if (freq == rt5663->sysclk && clk_id == rt5663->sysclk_src) | ||
2522 | return 0; | ||
2523 | |||
2524 | switch (clk_id) { | ||
2525 | case RT5663_SCLK_S_MCLK: | ||
2526 | reg_val |= RT5663_SCLK_SRC_MCLK; | ||
2527 | break; | ||
2528 | case RT5663_SCLK_S_PLL1: | ||
2529 | reg_val |= RT5663_SCLK_SRC_PLL1; | ||
2530 | break; | ||
2531 | case RT5663_SCLK_S_RCCLK: | ||
2532 | reg_val |= RT5663_SCLK_SRC_RCCLK; | ||
2533 | break; | ||
2534 | default: | ||
2535 | dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); | ||
2536 | return -EINVAL; | ||
2537 | } | ||
2538 | snd_soc_update_bits(codec, RT5663_GLB_CLK, RT5668_SCLK_SRC_MASK, | ||
2539 | reg_val); | ||
2540 | rt5663->sysclk = freq; | ||
2541 | rt5663->sysclk_src = clk_id; | ||
2542 | |||
2543 | dev_dbg(codec->dev, "Sysclk is %dHz and clock id is %d\n", | ||
2544 | freq, clk_id); | ||
2545 | |||
2546 | return 0; | ||
2547 | } | ||
2548 | |||
2549 | static int rt5663_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, | ||
2550 | unsigned int freq_in, unsigned int freq_out) | ||
2551 | { | ||
2552 | struct snd_soc_codec *codec = dai->codec; | ||
2553 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2554 | struct rl6231_pll_code pll_code; | ||
2555 | int ret; | ||
2556 | int mask, shift, val; | ||
2557 | |||
2558 | if (source == rt5663->pll_src && freq_in == rt5663->pll_in && | ||
2559 | freq_out == rt5663->pll_out) | ||
2560 | return 0; | ||
2561 | |||
2562 | if (!freq_in || !freq_out) { | ||
2563 | dev_dbg(codec->dev, "PLL disabled\n"); | ||
2564 | |||
2565 | rt5663->pll_in = 0; | ||
2566 | rt5663->pll_out = 0; | ||
2567 | snd_soc_update_bits(codec, RT5663_GLB_CLK, | ||
2568 | RT5663_SCLK_SRC_MASK, RT5663_SCLK_SRC_MCLK); | ||
2569 | return 0; | ||
2570 | } | ||
2571 | |||
2572 | switch (rt5663->codec_type) { | ||
2573 | case CODEC_TYPE_RT5668: | ||
2574 | mask = RT5668_PLL1_SRC_MASK; | ||
2575 | shift = RT5668_PLL1_SRC_SHIFT; | ||
2576 | break; | ||
2577 | case CODEC_TYPE_RT5663: | ||
2578 | mask = RT5663_PLL1_SRC_MASK; | ||
2579 | shift = RT5663_PLL1_SRC_SHIFT; | ||
2580 | break; | ||
2581 | default: | ||
2582 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
2583 | return -EINVAL; | ||
2584 | } | ||
2585 | |||
2586 | switch (source) { | ||
2587 | case RT5663_PLL1_S_MCLK: | ||
2588 | val = 0x0; | ||
2589 | break; | ||
2590 | case RT5663_PLL1_S_BCLK1: | ||
2591 | val = 0x1; | ||
2592 | break; | ||
2593 | default: | ||
2594 | dev_err(codec->dev, "Unknown PLL source %d\n", source); | ||
2595 | return -EINVAL; | ||
2596 | } | ||
2597 | snd_soc_update_bits(codec, RT5663_GLB_CLK, mask, (val << shift)); | ||
2598 | |||
2599 | ret = rl6231_pll_calc(freq_in, freq_out, &pll_code); | ||
2600 | if (ret < 0) { | ||
2601 | dev_err(codec->dev, "Unsupport input clock %d\n", freq_in); | ||
2602 | return ret; | ||
2603 | } | ||
2604 | |||
2605 | dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n", pll_code.m_bp, | ||
2606 | (pll_code.m_bp ? 0 : pll_code.m_code), pll_code.n_code, | ||
2607 | pll_code.k_code); | ||
2608 | |||
2609 | snd_soc_write(codec, RT5663_PLL_1, | ||
2610 | pll_code.n_code << RT5668_PLL_N_SHIFT | pll_code.k_code); | ||
2611 | snd_soc_write(codec, RT5663_PLL_2, | ||
2612 | (pll_code.m_bp ? 0 : pll_code.m_code) << RT5668_PLL_M_SHIFT | | ||
2613 | pll_code.m_bp << RT5668_PLL_M_BP_SHIFT); | ||
2614 | |||
2615 | rt5663->pll_in = freq_in; | ||
2616 | rt5663->pll_out = freq_out; | ||
2617 | rt5663->pll_src = source; | ||
2618 | |||
2619 | return 0; | ||
2620 | } | ||
2621 | |||
2622 | static int rt5663_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, | ||
2623 | unsigned int rx_mask, int slots, int slot_width) | ||
2624 | { | ||
2625 | struct snd_soc_codec *codec = dai->codec; | ||
2626 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2627 | unsigned int val = 0, reg; | ||
2628 | |||
2629 | if (rx_mask || tx_mask) | ||
2630 | val |= RT5668_TDM_MODE_TDM; | ||
2631 | |||
2632 | switch (slots) { | ||
2633 | case 4: | ||
2634 | val |= RT5668_TDM_IN_CH_4; | ||
2635 | val |= RT5668_TDM_OUT_CH_4; | ||
2636 | break; | ||
2637 | case 6: | ||
2638 | val |= RT5668_TDM_IN_CH_6; | ||
2639 | val |= RT5668_TDM_OUT_CH_6; | ||
2640 | break; | ||
2641 | case 8: | ||
2642 | val |= RT5668_TDM_IN_CH_8; | ||
2643 | val |= RT5668_TDM_OUT_CH_8; | ||
2644 | break; | ||
2645 | case 2: | ||
2646 | break; | ||
2647 | default: | ||
2648 | return -EINVAL; | ||
2649 | } | ||
2650 | |||
2651 | switch (slot_width) { | ||
2652 | case 20: | ||
2653 | val |= RT5668_TDM_IN_LEN_20; | ||
2654 | val |= RT5668_TDM_OUT_LEN_20; | ||
2655 | break; | ||
2656 | case 24: | ||
2657 | val |= RT5668_TDM_IN_LEN_24; | ||
2658 | val |= RT5668_TDM_OUT_LEN_24; | ||
2659 | break; | ||
2660 | case 32: | ||
2661 | val |= RT5668_TDM_IN_LEN_32; | ||
2662 | val |= RT5668_TDM_OUT_LEN_32; | ||
2663 | break; | ||
2664 | case 16: | ||
2665 | break; | ||
2666 | default: | ||
2667 | return -EINVAL; | ||
2668 | } | ||
2669 | |||
2670 | switch (rt5663->codec_type) { | ||
2671 | case CODEC_TYPE_RT5668: | ||
2672 | reg = RT5663_TDM_2; | ||
2673 | break; | ||
2674 | case CODEC_TYPE_RT5663: | ||
2675 | reg = RT5663_TDM_1; | ||
2676 | break; | ||
2677 | default: | ||
2678 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
2679 | return -EINVAL; | ||
2680 | } | ||
2681 | |||
2682 | snd_soc_update_bits(codec, reg, RT5668_TDM_MODE_MASK | | ||
2683 | RT5668_TDM_IN_CH_MASK | RT5668_TDM_OUT_CH_MASK | | ||
2684 | RT5668_TDM_IN_LEN_MASK | RT5668_TDM_OUT_LEN_MASK, val); | ||
2685 | |||
2686 | return 0; | ||
2687 | } | ||
2688 | |||
2689 | static int rt5663_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) | ||
2690 | { | ||
2691 | struct snd_soc_codec *codec = dai->codec; | ||
2692 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2693 | unsigned int reg; | ||
2694 | |||
2695 | dev_dbg(codec->dev, "%s ratio = %d\n", __func__, ratio); | ||
2696 | |||
2697 | if (rt5663->codec_type == CODEC_TYPE_RT5668) | ||
2698 | reg = RT5668_TDM_8; | ||
2699 | else | ||
2700 | reg = RT5663_TDM_5; | ||
2701 | |||
2702 | switch (ratio) { | ||
2703 | case 32: | ||
2704 | snd_soc_update_bits(codec, reg, | ||
2705 | RT5663_TDM_LENGTN_MASK, | ||
2706 | RT5663_TDM_LENGTN_16); | ||
2707 | break; | ||
2708 | case 40: | ||
2709 | snd_soc_update_bits(codec, reg, | ||
2710 | RT5663_TDM_LENGTN_MASK, | ||
2711 | RT5663_TDM_LENGTN_20); | ||
2712 | break; | ||
2713 | case 48: | ||
2714 | snd_soc_update_bits(codec, reg, | ||
2715 | RT5663_TDM_LENGTN_MASK, | ||
2716 | RT5663_TDM_LENGTN_24); | ||
2717 | break; | ||
2718 | case 64: | ||
2719 | snd_soc_update_bits(codec, reg, | ||
2720 | RT5663_TDM_LENGTN_MASK, | ||
2721 | RT5663_TDM_LENGTN_32); | ||
2722 | break; | ||
2723 | default: | ||
2724 | dev_err(codec->dev, "Invalid ratio!\n"); | ||
2725 | return -EINVAL; | ||
2726 | } | ||
2727 | |||
2728 | return 0; | ||
2729 | } | ||
2730 | |||
2731 | static int rt5663_set_bias_level(struct snd_soc_codec *codec, | ||
2732 | enum snd_soc_bias_level level) | ||
2733 | { | ||
2734 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2735 | |||
2736 | switch (level) { | ||
2737 | case SND_SOC_BIAS_ON: | ||
2738 | snd_soc_update_bits(codec, RT5663_PWR_ANLG_1, | ||
2739 | RT5668_PWR_FV1_MASK | RT5668_PWR_FV2_MASK, | ||
2740 | RT5668_PWR_FV1 | RT5668_PWR_FV2); | ||
2741 | break; | ||
2742 | |||
2743 | case SND_SOC_BIAS_PREPARE: | ||
2744 | if (rt5663->codec_type == CODEC_TYPE_RT5668) { | ||
2745 | snd_soc_update_bits(codec, RT5663_DIG_MISC, | ||
2746 | RT5668_DIG_GATE_CTRL_MASK, | ||
2747 | RT5668_DIG_GATE_CTRL_EN); | ||
2748 | snd_soc_update_bits(codec, RT5663_SIG_CLK_DET, | ||
2749 | RT5668_EN_ANA_CLK_DET_MASK | | ||
2750 | RT5668_PWR_CLK_DET_MASK, | ||
2751 | RT5668_EN_ANA_CLK_DET_AUTO | | ||
2752 | RT5668_PWR_CLK_DET_EN); | ||
2753 | } | ||
2754 | break; | ||
2755 | |||
2756 | case SND_SOC_BIAS_STANDBY: | ||
2757 | if (rt5663->codec_type == CODEC_TYPE_RT5668) | ||
2758 | snd_soc_update_bits(codec, RT5663_DIG_MISC, | ||
2759 | RT5668_DIG_GATE_CTRL_MASK, | ||
2760 | RT5668_DIG_GATE_CTRL_DIS); | ||
2761 | snd_soc_update_bits(codec, RT5663_PWR_ANLG_1, | ||
2762 | RT5668_PWR_VREF1_MASK | RT5668_PWR_VREF2_MASK | | ||
2763 | RT5668_PWR_FV1_MASK | RT5668_PWR_FV2_MASK | | ||
2764 | RT5668_PWR_MB_MASK, RT5668_PWR_VREF1 | | ||
2765 | RT5668_PWR_VREF2 | RT5668_PWR_MB); | ||
2766 | usleep_range(10000, 10005); | ||
2767 | if (rt5663->codec_type == CODEC_TYPE_RT5668) { | ||
2768 | snd_soc_update_bits(codec, RT5663_SIG_CLK_DET, | ||
2769 | RT5668_EN_ANA_CLK_DET_MASK | | ||
2770 | RT5668_PWR_CLK_DET_MASK, | ||
2771 | RT5668_EN_ANA_CLK_DET_DIS | | ||
2772 | RT5668_PWR_CLK_DET_DIS); | ||
2773 | } | ||
2774 | break; | ||
2775 | |||
2776 | case SND_SOC_BIAS_OFF: | ||
2777 | snd_soc_update_bits(codec, RT5663_PWR_ANLG_1, | ||
2778 | RT5668_PWR_VREF1_MASK | RT5668_PWR_VREF2_MASK | | ||
2779 | RT5668_PWR_FV1 | RT5668_PWR_FV2, 0x0); | ||
2780 | break; | ||
2781 | |||
2782 | default: | ||
2783 | break; | ||
2784 | } | ||
2785 | |||
2786 | return 0; | ||
2787 | } | ||
2788 | |||
2789 | static int rt5663_probe(struct snd_soc_codec *codec) | ||
2790 | { | ||
2791 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | ||
2792 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2793 | |||
2794 | rt5663->codec = codec; | ||
2795 | |||
2796 | switch (rt5663->codec_type) { | ||
2797 | case CODEC_TYPE_RT5668: | ||
2798 | snd_soc_dapm_new_controls(dapm, | ||
2799 | rt5668_specific_dapm_widgets, | ||
2800 | ARRAY_SIZE(rt5668_specific_dapm_widgets)); | ||
2801 | snd_soc_dapm_add_routes(dapm, | ||
2802 | rt5668_specific_dapm_routes, | ||
2803 | ARRAY_SIZE(rt5668_specific_dapm_routes)); | ||
2804 | snd_soc_add_codec_controls(codec, rt5668_specific_controls, | ||
2805 | ARRAY_SIZE(rt5668_specific_controls)); | ||
2806 | break; | ||
2807 | case CODEC_TYPE_RT5663: | ||
2808 | snd_soc_dapm_new_controls(dapm, | ||
2809 | rt5663_specific_dapm_widgets, | ||
2810 | ARRAY_SIZE(rt5663_specific_dapm_widgets)); | ||
2811 | snd_soc_dapm_add_routes(dapm, | ||
2812 | rt5663_specific_dapm_routes, | ||
2813 | ARRAY_SIZE(rt5663_specific_dapm_routes)); | ||
2814 | snd_soc_add_codec_controls(codec, rt5663_specific_controls, | ||
2815 | ARRAY_SIZE(rt5663_specific_controls)); | ||
2816 | break; | ||
2817 | } | ||
2818 | |||
2819 | return 0; | ||
2820 | } | ||
2821 | |||
2822 | static int rt5663_remove(struct snd_soc_codec *codec) | ||
2823 | { | ||
2824 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2825 | |||
2826 | regmap_write(rt5663->regmap, RT5663_RESET, 0); | ||
2827 | |||
2828 | return 0; | ||
2829 | } | ||
2830 | |||
2831 | #ifdef CONFIG_PM | ||
2832 | static int rt5663_suspend(struct snd_soc_codec *codec) | ||
2833 | { | ||
2834 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2835 | |||
2836 | regcache_cache_only(rt5663->regmap, true); | ||
2837 | regcache_mark_dirty(rt5663->regmap); | ||
2838 | |||
2839 | return 0; | ||
2840 | } | ||
2841 | |||
2842 | static int rt5663_resume(struct snd_soc_codec *codec) | ||
2843 | { | ||
2844 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2845 | |||
2846 | regcache_cache_only(rt5663->regmap, false); | ||
2847 | regcache_sync(rt5663->regmap); | ||
2848 | |||
2849 | return 0; | ||
2850 | } | ||
2851 | #else | ||
2852 | #define rt5663_suspend NULL | ||
2853 | #define rt5663_resume NULL | ||
2854 | #endif | ||
2855 | |||
2856 | #define RT5663_STEREO_RATES SNDRV_PCM_RATE_8000_192000 | ||
2857 | #define RT5663_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
2858 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) | ||
2859 | |||
2860 | static struct snd_soc_dai_ops rt5663_aif_dai_ops = { | ||
2861 | .hw_params = rt5663_hw_params, | ||
2862 | .set_fmt = rt5663_set_dai_fmt, | ||
2863 | .set_sysclk = rt5663_set_dai_sysclk, | ||
2864 | .set_pll = rt5663_set_dai_pll, | ||
2865 | .set_tdm_slot = rt5663_set_tdm_slot, | ||
2866 | .set_bclk_ratio = rt5663_set_bclk_ratio, | ||
2867 | }; | ||
2868 | |||
2869 | static struct snd_soc_dai_driver rt5663_dai[] = { | ||
2870 | { | ||
2871 | .name = "rt5663-aif", | ||
2872 | .id = RT5663_AIF, | ||
2873 | .playback = { | ||
2874 | .stream_name = "AIF Playback", | ||
2875 | .channels_min = 1, | ||
2876 | .channels_max = 2, | ||
2877 | .rates = RT5663_STEREO_RATES, | ||
2878 | .formats = RT5663_FORMATS, | ||
2879 | }, | ||
2880 | .capture = { | ||
2881 | .stream_name = "AIF Capture", | ||
2882 | .channels_min = 1, | ||
2883 | .channels_max = 2, | ||
2884 | .rates = RT5663_STEREO_RATES, | ||
2885 | .formats = RT5663_FORMATS, | ||
2886 | }, | ||
2887 | .ops = &rt5663_aif_dai_ops, | ||
2888 | }, | ||
2889 | }; | ||
2890 | |||
2891 | static struct snd_soc_codec_driver soc_codec_dev_rt5663 = { | ||
2892 | .probe = rt5663_probe, | ||
2893 | .remove = rt5663_remove, | ||
2894 | .suspend = rt5663_suspend, | ||
2895 | .resume = rt5663_resume, | ||
2896 | .set_bias_level = rt5663_set_bias_level, | ||
2897 | .idle_bias_off = true, | ||
2898 | .component_driver = { | ||
2899 | .controls = rt5663_snd_controls, | ||
2900 | .num_controls = ARRAY_SIZE(rt5663_snd_controls), | ||
2901 | .dapm_widgets = rt5663_dapm_widgets, | ||
2902 | .num_dapm_widgets = ARRAY_SIZE(rt5663_dapm_widgets), | ||
2903 | .dapm_routes = rt5663_dapm_routes, | ||
2904 | .num_dapm_routes = ARRAY_SIZE(rt5663_dapm_routes), | ||
2905 | } | ||
2906 | }; | ||
2907 | |||
2908 | static const struct regmap_config rt5668_regmap = { | ||
2909 | .reg_bits = 16, | ||
2910 | .val_bits = 16, | ||
2911 | .use_single_rw = true, | ||
2912 | .max_register = 0x07fa, | ||
2913 | .volatile_reg = rt5668_volatile_register, | ||
2914 | .readable_reg = rt5668_readable_register, | ||
2915 | .cache_type = REGCACHE_RBTREE, | ||
2916 | .reg_defaults = rt5668_reg, | ||
2917 | .num_reg_defaults = ARRAY_SIZE(rt5668_reg), | ||
2918 | }; | ||
2919 | |||
2920 | static const struct regmap_config rt5663_regmap = { | ||
2921 | .reg_bits = 16, | ||
2922 | .val_bits = 16, | ||
2923 | .use_single_rw = true, | ||
2924 | .max_register = 0x03f3, | ||
2925 | .volatile_reg = rt5663_volatile_register, | ||
2926 | .readable_reg = rt5663_readable_register, | ||
2927 | .cache_type = REGCACHE_RBTREE, | ||
2928 | .reg_defaults = rt5663_reg, | ||
2929 | .num_reg_defaults = ARRAY_SIZE(rt5663_reg), | ||
2930 | }; | ||
2931 | |||
2932 | static const struct regmap_config temp_regmap = { | ||
2933 | .name = "nocache", | ||
2934 | .reg_bits = 16, | ||
2935 | .val_bits = 16, | ||
2936 | .use_single_rw = true, | ||
2937 | .max_register = 0x03f3, | ||
2938 | .cache_type = REGCACHE_NONE, | ||
2939 | }; | ||
2940 | |||
2941 | static const struct i2c_device_id rt5663_i2c_id[] = { | ||
2942 | { "rt5668", 0 }, | ||
2943 | { "rt5663", 0 }, | ||
2944 | {} | ||
2945 | }; | ||
2946 | MODULE_DEVICE_TABLE(i2c, rt5663_i2c_id); | ||
2947 | |||
2948 | #if defined(CONFIG_OF) | ||
2949 | static const struct of_device_id rt5663_of_match[] = { | ||
2950 | { .compatible = "realtek,rt5668", }, | ||
2951 | { .compatible = "realtek,rt5663", }, | ||
2952 | {}, | ||
2953 | }; | ||
2954 | MODULE_DEVICE_TABLE(of, rt5663_of_match); | ||
2955 | #endif | ||
2956 | |||
2957 | #ifdef CONFIG_ACPI | ||
2958 | static struct acpi_device_id rt5663_acpi_match[] = { | ||
2959 | { "10EC5668", 0}, | ||
2960 | { "10EC5663", 0}, | ||
2961 | {}, | ||
2962 | }; | ||
2963 | MODULE_DEVICE_TABLE(acpi, rt5663_acpi_match); | ||
2964 | #endif | ||
2965 | |||
2966 | static void rt5668_calibrate(struct rt5663_priv *rt5668) | ||
2967 | { | ||
2968 | regmap_write(rt5668->regmap, RT5663_BIAS_CUR_8, 0xa402); | ||
2969 | regmap_write(rt5668->regmap, RT5663_PWR_DIG_1, 0x0100); | ||
2970 | regmap_write(rt5668->regmap, RT5663_RECMIX, 0x4040); | ||
2971 | regmap_write(rt5668->regmap, RT5663_DIG_MISC, 0x0001); | ||
2972 | regmap_write(rt5668->regmap, RT5663_RC_CLK, 0x0380); | ||
2973 | regmap_write(rt5668->regmap, RT5663_GLB_CLK, 0x8000); | ||
2974 | regmap_write(rt5668->regmap, RT5663_ADDA_CLK_1, 0x1000); | ||
2975 | regmap_write(rt5668->regmap, RT5663_CHOP_DAC_L, 0x3030); | ||
2976 | regmap_write(rt5668->regmap, RT5663_CALIB_ADC, 0x3c05); | ||
2977 | regmap_write(rt5668->regmap, RT5663_PWR_ANLG_1, 0xa23e); | ||
2978 | msleep(40); | ||
2979 | regmap_write(rt5668->regmap, RT5663_PWR_ANLG_1, 0xf23e); | ||
2980 | regmap_write(rt5668->regmap, RT5663_HP_CALIB_2, 0x0321); | ||
2981 | regmap_write(rt5668->regmap, RT5663_HP_CALIB_1, 0xfc00); | ||
2982 | msleep(500); | ||
2983 | } | ||
2984 | |||
2985 | static void rt5663_calibrate(struct rt5663_priv *rt5668) | ||
2986 | { | ||
2987 | int value, count; | ||
2988 | |||
2989 | regmap_write(rt5668->regmap, RT5663_RC_CLK, 0x0280); | ||
2990 | regmap_write(rt5668->regmap, RT5663_GLB_CLK, 0x8000); | ||
2991 | regmap_write(rt5668->regmap, RT5663_DIG_MISC, 0x8001); | ||
2992 | regmap_write(rt5668->regmap, RT5663_VREF_RECMIX, 0x0032); | ||
2993 | regmap_write(rt5668->regmap, RT5663_PWR_ANLG_1, 0xa2be); | ||
2994 | msleep(20); | ||
2995 | regmap_write(rt5668->regmap, RT5663_PWR_ANLG_1, 0xf2be); | ||
2996 | regmap_write(rt5668->regmap, RT5663_PWR_DIG_2, 0x8400); | ||
2997 | regmap_write(rt5668->regmap, RT5663_CHOP_ADC, 0x3000); | ||
2998 | regmap_write(rt5668->regmap, RT5663_DEPOP_1, 0x003b); | ||
2999 | regmap_write(rt5668->regmap, RT5663_PWR_DIG_1, 0x8df8); | ||
3000 | regmap_write(rt5668->regmap, RT5663_PWR_ANLG_2, 0x0003); | ||
3001 | regmap_write(rt5668->regmap, RT5663_PWR_ANLG_3, 0x018c); | ||
3002 | regmap_write(rt5668->regmap, RT5663_ADDA_CLK_1, 0x1111); | ||
3003 | regmap_write(rt5668->regmap, RT5663_PRE_DIV_GATING_1, 0xffff); | ||
3004 | regmap_write(rt5668->regmap, RT5663_PRE_DIV_GATING_2, 0xffff); | ||
3005 | regmap_write(rt5668->regmap, RT5663_DEPOP_2, 0x3003); | ||
3006 | regmap_write(rt5668->regmap, RT5663_DEPOP_1, 0x003b); | ||
3007 | regmap_write(rt5668->regmap, RT5663_HP_CHARGE_PUMP_1, 0x1e32); | ||
3008 | regmap_write(rt5668->regmap, RT5663_HP_CHARGE_PUMP_2, 0x1371); | ||
3009 | regmap_write(rt5668->regmap, RT5663_DACREF_LDO, 0x3b0b); | ||
3010 | regmap_write(rt5668->regmap, RT5663_STO_DAC_MIXER, 0x2080); | ||
3011 | regmap_write(rt5668->regmap, RT5663_BYPASS_STO_DAC, 0x000c); | ||
3012 | regmap_write(rt5668->regmap, RT5663_HP_BIAS, 0xabba); | ||
3013 | regmap_write(rt5668->regmap, RT5663_CHARGE_PUMP_1, 0x2224); | ||
3014 | regmap_write(rt5668->regmap, RT5663_HP_OUT_EN, 0x8088); | ||
3015 | regmap_write(rt5668->regmap, RT5663_STO_DRE_9, 0x0017); | ||
3016 | regmap_write(rt5668->regmap, RT5663_STO_DRE_10, 0x0017); | ||
3017 | regmap_write(rt5668->regmap, RT5663_STO1_ADC_MIXER, 0x4040); | ||
3018 | regmap_write(rt5668->regmap, RT5663_RECMIX, 0x0005); | ||
3019 | regmap_write(rt5668->regmap, RT5663_ADDA_RST, 0xc000); | ||
3020 | regmap_write(rt5668->regmap, RT5663_STO1_HPF_ADJ1, 0x3320); | ||
3021 | regmap_write(rt5668->regmap, RT5663_HP_CALIB_2, 0x00c9); | ||
3022 | regmap_write(rt5668->regmap, RT5663_DUMMY_1, 0x004c); | ||
3023 | regmap_write(rt5668->regmap, RT5663_ANA_BIAS_CUR_1, 0x7766); | ||
3024 | regmap_write(rt5668->regmap, RT5663_BIAS_CUR_8, 0x4702); | ||
3025 | msleep(200); | ||
3026 | regmap_write(rt5668->regmap, RT5663_HP_CALIB_1, 0x0069); | ||
3027 | regmap_write(rt5668->regmap, RT5663_HP_CALIB_3, 0x06c2); | ||
3028 | regmap_write(rt5668->regmap, RT5663_HP_CALIB_1_1, 0x7b00); | ||
3029 | regmap_write(rt5668->regmap, RT5663_HP_CALIB_1_1, 0xfb00); | ||
3030 | count = 0; | ||
3031 | while (true) { | ||
3032 | regmap_read(rt5668->regmap, RT5663_HP_CALIB_1_1, &value); | ||
3033 | if (value & 0x8000) | ||
3034 | usleep_range(10000, 10005); | ||
3035 | else | ||
3036 | break; | ||
3037 | |||
3038 | if (count > 200) | ||
3039 | return; | ||
3040 | count++; | ||
3041 | } | ||
3042 | } | ||
3043 | |||
3044 | static int rt5663_i2c_probe(struct i2c_client *i2c, | ||
3045 | const struct i2c_device_id *id) | ||
3046 | { | ||
3047 | struct rt5663_priv *rt5663; | ||
3048 | int ret; | ||
3049 | unsigned int val; | ||
3050 | struct regmap *regmap; | ||
3051 | |||
3052 | rt5663 = devm_kzalloc(&i2c->dev, sizeof(struct rt5663_priv), | ||
3053 | GFP_KERNEL); | ||
3054 | |||
3055 | if (rt5663 == NULL) | ||
3056 | return -ENOMEM; | ||
3057 | |||
3058 | i2c_set_clientdata(i2c, rt5663); | ||
3059 | |||
3060 | regmap = devm_regmap_init_i2c(i2c, &temp_regmap); | ||
3061 | if (IS_ERR(regmap)) { | ||
3062 | ret = PTR_ERR(regmap); | ||
3063 | dev_err(&i2c->dev, "Failed to allocate temp register map: %d\n", | ||
3064 | ret); | ||
3065 | return ret; | ||
3066 | } | ||
3067 | regmap_read(regmap, RT5663_VENDOR_ID_2, &val); | ||
3068 | switch (val) { | ||
3069 | case RT5668_DEVICE_ID: | ||
3070 | rt5663->regmap = devm_regmap_init_i2c(i2c, &rt5668_regmap); | ||
3071 | rt5663->codec_type = CODEC_TYPE_RT5668; | ||
3072 | break; | ||
3073 | case RT5663_DEVICE_ID: | ||
3074 | rt5663->regmap = devm_regmap_init_i2c(i2c, &rt5663_regmap); | ||
3075 | rt5663->codec_type = CODEC_TYPE_RT5663; | ||
3076 | break; | ||
3077 | default: | ||
3078 | dev_err(&i2c->dev, | ||
3079 | "Device with ID register %#x is not rt5663 or rt5668\n", | ||
3080 | val); | ||
3081 | return -ENODEV; | ||
3082 | } | ||
3083 | |||
3084 | if (IS_ERR(rt5663->regmap)) { | ||
3085 | ret = PTR_ERR(rt5663->regmap); | ||
3086 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | ||
3087 | ret); | ||
3088 | return ret; | ||
3089 | } | ||
3090 | |||
3091 | /* reset and calibrate */ | ||
3092 | regmap_write(rt5663->regmap, RT5663_RESET, 0); | ||
3093 | regcache_cache_bypass(rt5663->regmap, true); | ||
3094 | switch (rt5663->codec_type) { | ||
3095 | case CODEC_TYPE_RT5668: | ||
3096 | rt5668_calibrate(rt5663); | ||
3097 | break; | ||
3098 | case CODEC_TYPE_RT5663: | ||
3099 | rt5663_calibrate(rt5663); | ||
3100 | break; | ||
3101 | default: | ||
3102 | dev_err(&i2c->dev, "%s:Unknown codec type\n", __func__); | ||
3103 | } | ||
3104 | regcache_cache_bypass(rt5663->regmap, false); | ||
3105 | regmap_write(rt5663->regmap, RT5663_RESET, 0); | ||
3106 | dev_dbg(&i2c->dev, "calibrate done\n"); | ||
3107 | |||
3108 | /* GPIO1 as IRQ */ | ||
3109 | regmap_update_bits(rt5663->regmap, RT5663_GPIO_1, RT5668_GP1_PIN_MASK, | ||
3110 | RT5668_GP1_PIN_IRQ); | ||
3111 | /* 4btn inline command debounce */ | ||
3112 | regmap_update_bits(rt5663->regmap, RT5663_IL_CMD_5, | ||
3113 | RT5668_4BTN_CLK_DEB_MASK, RT5668_4BTN_CLK_DEB_65MS); | ||
3114 | |||
3115 | switch (rt5663->codec_type) { | ||
3116 | case CODEC_TYPE_RT5668: | ||
3117 | regmap_write(rt5663->regmap, RT5663_BIAS_CUR_8, 0xa402); | ||
3118 | /* JD1 */ | ||
3119 | regmap_update_bits(rt5663->regmap, RT5663_AUTO_1MRC_CLK, | ||
3120 | RT5668_IRQ_POW_SAV_MASK | RT5668_IRQ_POW_SAV_JD1_MASK, | ||
3121 | RT5668_IRQ_POW_SAV_EN | RT5668_IRQ_POW_SAV_JD1_EN); | ||
3122 | regmap_update_bits(rt5663->regmap, RT5663_PWR_ANLG_2, | ||
3123 | RT5668_PWR_JD1_MASK, RT5668_PWR_JD1); | ||
3124 | regmap_update_bits(rt5663->regmap, RT5663_IRQ_1, | ||
3125 | RT5668_EN_CB_JD_MASK, RT5668_EN_CB_JD_EN); | ||
3126 | |||
3127 | regmap_update_bits(rt5663->regmap, RT5663_HP_LOGIC_2, | ||
3128 | RT5668_HP_SIG_SRC1_MASK, RT5668_HP_SIG_SRC1_REG); | ||
3129 | regmap_update_bits(rt5663->regmap, RT5663_RECMIX, | ||
3130 | RT5668_VREF_BIAS_MASK | RT5668_CBJ_DET_MASK | | ||
3131 | RT5668_DET_TYPE_MASK, RT5668_VREF_BIAS_REG | | ||
3132 | RT5668_CBJ_DET_EN | RT5668_DET_TYPE_QFN); | ||
3133 | /* Set GPIO4 and GPIO8 as input for combo jack */ | ||
3134 | regmap_update_bits(rt5663->regmap, RT5663_GPIO_2, | ||
3135 | RT5668_GP4_PIN_CONF_MASK, RT5668_GP4_PIN_CONF_INPUT); | ||
3136 | regmap_update_bits(rt5663->regmap, RT5668_GPIO_3, | ||
3137 | RT5668_GP8_PIN_CONF_MASK, RT5668_GP8_PIN_CONF_INPUT); | ||
3138 | regmap_update_bits(rt5663->regmap, RT5663_PWR_ANLG_1, | ||
3139 | RT5668_LDO1_DVO_MASK | RT5668_AMP_HP_MASK, | ||
3140 | RT5668_LDO1_DVO_0_9V | RT5668_AMP_HP_3X); | ||
3141 | break; | ||
3142 | case CODEC_TYPE_RT5663: | ||
3143 | regmap_write(rt5663->regmap, RT5663_VREF_RECMIX, 0x0032); | ||
3144 | regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xa2be); | ||
3145 | msleep(20); | ||
3146 | regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xf2be); | ||
3147 | regmap_update_bits(rt5663->regmap, RT5663_GPIO_2, | ||
3148 | RT5663_GP1_PIN_CONF_MASK, RT5663_GP1_PIN_CONF_OUTPUT); | ||
3149 | /* DACREF LDO control */ | ||
3150 | regmap_update_bits(rt5663->regmap, RT5663_DACREF_LDO, 0x3e0e, | ||
3151 | 0x3a0a); | ||
3152 | regmap_update_bits(rt5663->regmap, RT5663_RECMIX, | ||
3153 | RT5663_RECMIX1_BST1_MASK, RT5663_RECMIX1_BST1_ON); | ||
3154 | regmap_update_bits(rt5663->regmap, RT5663_TDM_2, | ||
3155 | RT5663_DATA_SWAP_ADCDAT1_MASK, | ||
3156 | RT5663_DATA_SWAP_ADCDAT1_LL); | ||
3157 | break; | ||
3158 | default: | ||
3159 | dev_err(&i2c->dev, "%s:Unknown codec type\n", __func__); | ||
3160 | } | ||
3161 | |||
3162 | INIT_DELAYED_WORK(&rt5663->jack_detect_work, rt5663_jack_detect_work); | ||
3163 | |||
3164 | if (i2c->irq) { | ||
3165 | ret = request_irq(i2c->irq, rt5663_irq, | ||
3166 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | ||
3167 | | IRQF_ONESHOT, "rt5663", rt5663); | ||
3168 | if (ret) | ||
3169 | dev_err(&i2c->dev, "%s Failed to reguest IRQ: %d\n", | ||
3170 | __func__, ret); | ||
3171 | } | ||
3172 | |||
3173 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5663, | ||
3174 | rt5663_dai, ARRAY_SIZE(rt5663_dai)); | ||
3175 | |||
3176 | if (ret) { | ||
3177 | if (i2c->irq) | ||
3178 | free_irq(i2c->irq, rt5663); | ||
3179 | } | ||
3180 | |||
3181 | return ret; | ||
3182 | } | ||
3183 | |||
3184 | static int rt5663_i2c_remove(struct i2c_client *i2c) | ||
3185 | { | ||
3186 | struct rt5663_priv *rt5663 = i2c_get_clientdata(i2c); | ||
3187 | |||
3188 | if (i2c->irq) | ||
3189 | free_irq(i2c->irq, rt5663); | ||
3190 | |||
3191 | snd_soc_unregister_codec(&i2c->dev); | ||
3192 | |||
3193 | return 0; | ||
3194 | } | ||
3195 | |||
3196 | static void rt5663_i2c_shutdown(struct i2c_client *client) | ||
3197 | { | ||
3198 | struct rt5663_priv *rt5663 = i2c_get_clientdata(client); | ||
3199 | |||
3200 | regmap_write(rt5663->regmap, RT5663_RESET, 0); | ||
3201 | } | ||
3202 | |||
3203 | static struct i2c_driver rt5663_i2c_driver = { | ||
3204 | .driver = { | ||
3205 | .name = "rt5663", | ||
3206 | .acpi_match_table = ACPI_PTR(rt5663_acpi_match), | ||
3207 | .of_match_table = of_match_ptr(rt5663_of_match), | ||
3208 | }, | ||
3209 | .probe = rt5663_i2c_probe, | ||
3210 | .remove = rt5663_i2c_remove, | ||
3211 | .shutdown = rt5663_i2c_shutdown, | ||
3212 | .id_table = rt5663_i2c_id, | ||
3213 | }; | ||
3214 | module_i2c_driver(rt5663_i2c_driver); | ||
3215 | |||
3216 | MODULE_DESCRIPTION("ASoC RT5663 driver"); | ||
3217 | MODULE_AUTHOR("Jack Yu <jack.yu@realtek.com>"); | ||
3218 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/rt5663.h b/sound/soc/codecs/rt5663.h new file mode 100644 index 000000000000..2cc8f28080f6 --- /dev/null +++ b/sound/soc/codecs/rt5663.h | |||
@@ -0,0 +1,1121 @@ | |||
1 | /* | ||
2 | * rt5663.h -- RT5663 ALSA SoC audio driver | ||
3 | * | ||
4 | * Copyright 2016 Realtek Microelectronics | ||
5 | * Author: Jack Yu <jack.yu@realtek.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 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef __RT5663_H__ | ||
13 | #define __RT5663_H__ | ||
14 | |||
15 | /* Info */ | ||
16 | #define RT5663_RESET 0x0000 | ||
17 | #define RT5663_VENDOR_ID 0x00fd | ||
18 | #define RT5663_VENDOR_ID_1 0x00fe | ||
19 | #define RT5663_VENDOR_ID_2 0x00ff | ||
20 | |||
21 | #define RT5668_LOUT_CTRL 0x0001 | ||
22 | #define RT5668_HP_AMP_2 0x0003 | ||
23 | #define RT5668_MONO_OUT 0x0004 | ||
24 | #define RT5668_MONO_GAIN 0x0007 | ||
25 | |||
26 | #define RT5668_AEC_BST 0x000b | ||
27 | #define RT5668_IN1_IN2 0x000c | ||
28 | #define RT5668_IN3_IN4 0x000d | ||
29 | #define RT5668_INL1_INR1 0x000f | ||
30 | #define RT5668_CBJ_TYPE_2 0x0011 | ||
31 | #define RT5668_CBJ_TYPE_3 0x0012 | ||
32 | #define RT5668_CBJ_TYPE_4 0x0013 | ||
33 | #define RT5668_CBJ_TYPE_5 0x0014 | ||
34 | #define RT5668_CBJ_TYPE_8 0x0017 | ||
35 | |||
36 | /* I/O - ADC/DAC/DMIC */ | ||
37 | #define RT5668_DAC3_DIG_VOL 0x001a | ||
38 | #define RT5668_DAC3_CTRL 0x001b | ||
39 | #define RT5668_MONO_ADC_DIG_VOL 0x001d | ||
40 | #define RT5668_STO2_ADC_DIG_VOL 0x001e | ||
41 | #define RT5668_MONO_ADC_BST_GAIN 0x0020 | ||
42 | #define RT5668_STO2_ADC_BST_GAIN 0x0021 | ||
43 | #define RT5668_SIDETONE_CTRL 0x0024 | ||
44 | /* Mixer - D-D */ | ||
45 | #define RT5668_MONO1_ADC_MIXER 0x0027 | ||
46 | #define RT5668_STO2_ADC_MIXER 0x0028 | ||
47 | #define RT5668_MONO_DAC_MIXER 0x002b | ||
48 | #define RT5668_DAC2_SRC_CTRL 0x002e | ||
49 | #define RT5668_IF_3_4_DATA_CTL 0x002f | ||
50 | #define RT5668_IF_5_DATA_CTL 0x0030 | ||
51 | #define RT5668_PDM_OUT_CTL 0x0031 | ||
52 | #define RT5668_PDM_I2C_DATA_CTL1 0x0032 | ||
53 | #define RT5668_PDM_I2C_DATA_CTL2 0x0033 | ||
54 | #define RT5668_PDM_I2C_DATA_CTL3 0x0034 | ||
55 | #define RT5668_PDM_I2C_DATA_CTL4 0x0035 | ||
56 | |||
57 | /*Mixer - Analog*/ | ||
58 | #define RT5668_RECMIX1_NEW 0x003a | ||
59 | #define RT5668_RECMIX1L_0 0x003b | ||
60 | #define RT5668_RECMIX1L 0x003c | ||
61 | #define RT5668_RECMIX1R_0 0x003d | ||
62 | #define RT5668_RECMIX1R 0x003e | ||
63 | #define RT5668_RECMIX2_NEW 0x003f | ||
64 | #define RT5668_RECMIX2_L_2 0x0041 | ||
65 | #define RT5668_RECMIX2_R 0x0042 | ||
66 | #define RT5668_RECMIX2_R_2 0x0043 | ||
67 | #define RT5668_CALIB_REC_LR 0x0044 | ||
68 | #define RT5668_ALC_BK_GAIN 0x0049 | ||
69 | #define RT5668_MONOMIX_GAIN 0x004a | ||
70 | #define RT5668_MONOMIX_IN_GAIN 0x004b | ||
71 | #define RT5668_OUT_MIXL_GAIN 0x004d | ||
72 | #define RT5668_OUT_LMIX_IN_GAIN 0x004e | ||
73 | #define RT5668_OUT_RMIX_IN_GAIN 0x004f | ||
74 | #define RT5668_OUT_RMIX_IN_GAIN1 0x0050 | ||
75 | #define RT5668_LOUT_MIXER_CTRL 0x0052 | ||
76 | /* Power */ | ||
77 | #define RT5668_PWR_VOL 0x0067 | ||
78 | |||
79 | #define RT5668_ADCDAC_RST 0x006d | ||
80 | /* Format - ADC/DAC */ | ||
81 | #define RT5668_I2S34_SDP 0x0071 | ||
82 | #define RT5668_I2S5_SDP 0x0072 | ||
83 | /* Format - TDM Control */ | ||
84 | #define RT5668_TDM_5 0x007c | ||
85 | #define RT5668_TDM_6 0x007d | ||
86 | #define RT5668_TDM_7 0x007e | ||
87 | #define RT5668_TDM_8 0x007f | ||
88 | |||
89 | /* Function - Analog */ | ||
90 | #define RT5668_ASRC_3 0x0085 | ||
91 | #define RT5668_ASRC_6 0x0088 | ||
92 | #define RT5668_ASRC_7 0x0089 | ||
93 | #define RT5668_PLL_TRK_13 0x0099 | ||
94 | #define RT5668_I2S_M_CLK_CTL 0x00a0 | ||
95 | #define RT5668_FDIV_I2S34_M_CLK 0x00a1 | ||
96 | #define RT5668_FDIV_I2S34_M_CLK2 0x00a2 | ||
97 | #define RT5668_FDIV_I2S5_M_CLK 0x00a3 | ||
98 | #define RT5668_FDIV_I2S5_M_CLK2 0x00a4 | ||
99 | |||
100 | /* Function - Digital */ | ||
101 | #define RT5668_IRQ_4 0x00b9 | ||
102 | #define RT5668_GPIO_3 0x00c2 | ||
103 | #define RT5668_GPIO_4 0x00c3 | ||
104 | #define RT5668_GPIO_STA 0x00c4 | ||
105 | #define RT5668_HP_AMP_DET1 0x00d0 | ||
106 | #define RT5668_HP_AMP_DET2 0x00d1 | ||
107 | #define RT5668_HP_AMP_DET3 0x00d2 | ||
108 | #define RT5668_MID_BD_HP_AMP 0x00d3 | ||
109 | #define RT5668_LOW_BD_HP_AMP 0x00d4 | ||
110 | #define RT5668_SOF_VOL_ZC2 0x00da | ||
111 | #define RT5668_ADC_STO2_ADJ1 0x00ee | ||
112 | #define RT5668_ADC_STO2_ADJ2 0x00ef | ||
113 | /* General Control */ | ||
114 | #define RT5668_A_JD_CTRL 0x00f0 | ||
115 | #define RT5668_JD1_TRES_CTRL 0x00f1 | ||
116 | #define RT5668_JD2_TRES_CTRL 0x00f2 | ||
117 | #define RT5668_JD_CTRL2 0x00f7 | ||
118 | #define RT5668_DUM_REG_2 0x00fb | ||
119 | #define RT5668_DUM_REG_3 0x00fc | ||
120 | |||
121 | |||
122 | #define RT5668_DACADC_DIG_VOL2 0x0101 | ||
123 | #define RT5668_DIG_IN_PIN2 0x0133 | ||
124 | #define RT5668_PAD_DRV_CTL1 0x0136 | ||
125 | #define RT5668_SOF_RAM_DEPOP 0x0138 | ||
126 | #define RT5668_VOL_TEST 0x013f | ||
127 | #define RT5668_TEST_MODE_3 0x0147 | ||
128 | #define RT5668_TEST_MODE_4 0x0148 | ||
129 | #define RT5668_MONO_DYNA_1 0x0170 | ||
130 | #define RT5668_MONO_DYNA_2 0x0171 | ||
131 | #define RT5668_MONO_DYNA_3 0x0172 | ||
132 | #define RT5668_MONO_DYNA_4 0x0173 | ||
133 | #define RT5668_MONO_DYNA_5 0x0174 | ||
134 | #define RT5668_MONO_DYNA_6 0x0175 | ||
135 | #define RT5668_STO1_SIL_DET 0x0190 | ||
136 | #define RT5668_MONOL_SIL_DET 0x0191 | ||
137 | #define RT5668_MONOR_SIL_DET 0x0192 | ||
138 | #define RT5668_STO2_DAC_SIL 0x0193 | ||
139 | #define RT5668_PWR_SAV_CTL1 0x0194 | ||
140 | #define RT5668_PWR_SAV_CTL2 0x0195 | ||
141 | #define RT5668_PWR_SAV_CTL3 0x0196 | ||
142 | #define RT5668_PWR_SAV_CTL4 0x0197 | ||
143 | #define RT5668_PWR_SAV_CTL5 0x0198 | ||
144 | #define RT5668_PWR_SAV_CTL6 0x0199 | ||
145 | #define RT5668_MONO_AMP_CAL1 0x01a0 | ||
146 | #define RT5668_MONO_AMP_CAL2 0x01a1 | ||
147 | #define RT5668_MONO_AMP_CAL3 0x01a2 | ||
148 | #define RT5668_MONO_AMP_CAL4 0x01a3 | ||
149 | #define RT5668_MONO_AMP_CAL5 0x01a4 | ||
150 | #define RT5668_MONO_AMP_CAL6 0x01a5 | ||
151 | #define RT5668_MONO_AMP_CAL7 0x01a6 | ||
152 | #define RT5668_MONO_AMP_CAL_ST1 0x01a7 | ||
153 | #define RT5668_MONO_AMP_CAL_ST2 0x01a8 | ||
154 | #define RT5668_MONO_AMP_CAL_ST3 0x01a9 | ||
155 | #define RT5668_MONO_AMP_CAL_ST4 0x01aa | ||
156 | #define RT5668_MONO_AMP_CAL_ST5 0x01ab | ||
157 | #define RT5668_HP_IMP_SEN_13 0x01b9 | ||
158 | #define RT5668_HP_IMP_SEN_14 0x01ba | ||
159 | #define RT5668_HP_IMP_SEN_6 0x01bb | ||
160 | #define RT5668_HP_IMP_SEN_7 0x01bc | ||
161 | #define RT5668_HP_IMP_SEN_8 0x01bd | ||
162 | #define RT5668_HP_IMP_SEN_9 0x01be | ||
163 | #define RT5668_HP_IMP_SEN_10 0x01bf | ||
164 | #define RT5668_HP_LOGIC_3 0x01dc | ||
165 | #define RT5668_HP_CALIB_ST10 0x01f3 | ||
166 | #define RT5668_HP_CALIB_ST11 0x01f4 | ||
167 | #define RT5668_PRO_REG_TBL_4 0x0203 | ||
168 | #define RT5668_PRO_REG_TBL_5 0x0204 | ||
169 | #define RT5668_PRO_REG_TBL_6 0x0205 | ||
170 | #define RT5668_PRO_REG_TBL_7 0x0206 | ||
171 | #define RT5668_PRO_REG_TBL_8 0x0207 | ||
172 | #define RT5668_PRO_REG_TBL_9 0x0208 | ||
173 | #define RT5668_SAR_ADC_INL_1 0x0210 | ||
174 | #define RT5668_SAR_ADC_INL_2 0x0211 | ||
175 | #define RT5668_SAR_ADC_INL_3 0x0212 | ||
176 | #define RT5668_SAR_ADC_INL_4 0x0213 | ||
177 | #define RT5668_SAR_ADC_INL_5 0x0214 | ||
178 | #define RT5668_SAR_ADC_INL_6 0x0215 | ||
179 | #define RT5668_SAR_ADC_INL_7 0x0216 | ||
180 | #define RT5668_SAR_ADC_INL_8 0x0217 | ||
181 | #define RT5668_SAR_ADC_INL_9 0x0218 | ||
182 | #define RT5668_SAR_ADC_INL_10 0x0219 | ||
183 | #define RT5668_SAR_ADC_INL_11 0x021a | ||
184 | #define RT5668_SAR_ADC_INL_12 0x021b | ||
185 | #define RT5668_DRC_CTRL_1 0x02ff | ||
186 | #define RT5668_DRC1_CTRL_2 0x0301 | ||
187 | #define RT5668_DRC1_CTRL_3 0x0302 | ||
188 | #define RT5668_DRC1_CTRL_4 0x0303 | ||
189 | #define RT5668_DRC1_CTRL_5 0x0304 | ||
190 | #define RT5668_DRC1_CTRL_6 0x0305 | ||
191 | #define RT5668_DRC1_HD_CTRL_1 0x0306 | ||
192 | #define RT5668_DRC1_HD_CTRL_2 0x0307 | ||
193 | #define RT5668_DRC1_PRI_REG_1 0x0310 | ||
194 | #define RT5668_DRC1_PRI_REG_2 0x0311 | ||
195 | #define RT5668_DRC1_PRI_REG_3 0x0312 | ||
196 | #define RT5668_DRC1_PRI_REG_4 0x0313 | ||
197 | #define RT5668_DRC1_PRI_REG_5 0x0314 | ||
198 | #define RT5668_DRC1_PRI_REG_6 0x0315 | ||
199 | #define RT5668_DRC1_PRI_REG_7 0x0316 | ||
200 | #define RT5668_DRC1_PRI_REG_8 0x0317 | ||
201 | #define RT5668_ALC_PGA_CTL_1 0x0330 | ||
202 | #define RT5668_ALC_PGA_CTL_2 0x0331 | ||
203 | #define RT5668_ALC_PGA_CTL_3 0x0332 | ||
204 | #define RT5668_ALC_PGA_CTL_4 0x0333 | ||
205 | #define RT5668_ALC_PGA_CTL_5 0x0334 | ||
206 | #define RT5668_ALC_PGA_CTL_6 0x0335 | ||
207 | #define RT5668_ALC_PGA_CTL_7 0x0336 | ||
208 | #define RT5668_ALC_PGA_CTL_8 0x0337 | ||
209 | #define RT5668_ALC_PGA_REG_1 0x0338 | ||
210 | #define RT5668_ALC_PGA_REG_2 0x0339 | ||
211 | #define RT5668_ALC_PGA_REG_3 0x033a | ||
212 | #define RT5668_ADC_EQ_RECOV_1 0x03c0 | ||
213 | #define RT5668_ADC_EQ_RECOV_2 0x03c1 | ||
214 | #define RT5668_ADC_EQ_RECOV_3 0x03c2 | ||
215 | #define RT5668_ADC_EQ_RECOV_4 0x03c3 | ||
216 | #define RT5668_ADC_EQ_RECOV_5 0x03c4 | ||
217 | #define RT5668_ADC_EQ_RECOV_6 0x03c5 | ||
218 | #define RT5668_ADC_EQ_RECOV_7 0x03c6 | ||
219 | #define RT5668_ADC_EQ_RECOV_8 0x03c7 | ||
220 | #define RT5668_ADC_EQ_RECOV_9 0x03c8 | ||
221 | #define RT5668_ADC_EQ_RECOV_10 0x03c9 | ||
222 | #define RT5668_ADC_EQ_RECOV_11 0x03ca | ||
223 | #define RT5668_ADC_EQ_RECOV_12 0x03cb | ||
224 | #define RT5668_ADC_EQ_RECOV_13 0x03cc | ||
225 | #define RT5668_VID_HIDDEN 0x03fe | ||
226 | #define RT5668_VID_CUSTOMER 0x03ff | ||
227 | #define RT5668_SCAN_MODE 0x07f0 | ||
228 | #define RT5668_I2C_BYPA 0x07fa | ||
229 | |||
230 | /* Headphone Amp Control 2 (0x0003) */ | ||
231 | #define RT5668_EN_DAC_HPO_MASK (0x1 << 14) | ||
232 | #define RT5668_EN_DAC_HPO_SHIFT 14 | ||
233 | #define RT5668_EN_DAC_HPO_DIS (0x0 << 14) | ||
234 | #define RT5668_EN_DAC_HPO_EN (0x1 << 14) | ||
235 | |||
236 | /*Headphone Amp L/R Analog Gain and Digital NG2 Gain Control (0x0005 0x0006)*/ | ||
237 | #define RT5668_GAIN_HP (0x1f << 8) | ||
238 | #define RT5668_GAIN_HP_SHIFT 8 | ||
239 | |||
240 | /* AEC BST Control (0x000b) */ | ||
241 | #define RT5668_GAIN_CBJ_MASK (0xf << 8) | ||
242 | #define RT5668_GAIN_CBJ_SHIFT 8 | ||
243 | |||
244 | /* IN1 Control / MIC GND REF (0x000c) */ | ||
245 | #define RT5668_IN1_DF_MASK (0x1 << 15) | ||
246 | #define RT5668_IN1_DF_SHIFT 15 | ||
247 | |||
248 | /* Combo Jack and Type Detection Control 1 (0x0010) */ | ||
249 | #define RT5668_CBJ_DET_MASK (0x1 << 15) | ||
250 | #define RT5668_CBJ_DET_SHIFT 15 | ||
251 | #define RT5668_CBJ_DET_DIS (0x0 << 15) | ||
252 | #define RT5668_CBJ_DET_EN (0x1 << 15) | ||
253 | #define RT5668_DET_TYPE_MASK (0x1 << 12) | ||
254 | #define RT5668_DET_TYPE_SHIFT 12 | ||
255 | #define RT5668_DET_TYPE_WLCSP (0x0 << 12) | ||
256 | #define RT5668_DET_TYPE_QFN (0x1 << 12) | ||
257 | #define RT5668_VREF_BIAS_MASK (0x1 << 6) | ||
258 | #define RT5668_VREF_BIAS_SHIFT 6 | ||
259 | #define RT5668_VREF_BIAS_FSM (0x0 << 6) | ||
260 | #define RT5668_VREF_BIAS_REG (0x1 << 6) | ||
261 | |||
262 | /* REC Left Mixer Control 2 (0x003c) */ | ||
263 | #define RT5668_RECMIX1L_BST1_CBJ (0x1 << 7) | ||
264 | #define RT5668_RECMIX1L_BST1_CBJ_SHIFT 7 | ||
265 | #define RT5668_RECMIX1L_BST2 (0x1 << 4) | ||
266 | #define RT5668_RECMIX1L_BST2_SHIFT 4 | ||
267 | |||
268 | /* REC Right Mixer Control 2 (0x003e) */ | ||
269 | #define RT5668_RECMIX1R_BST2 (0x1 << 4) | ||
270 | #define RT5668_RECMIX1R_BST2_SHIFT 4 | ||
271 | |||
272 | /* DAC1 Digital Volume (0x0019) */ | ||
273 | #define RT5668_DAC_L1_VOL_MASK (0xff << 8) | ||
274 | #define RT5668_DAC_L1_VOL_SHIFT 8 | ||
275 | #define RT5668_DAC_R1_VOL_MASK (0xff) | ||
276 | #define RT5668_DAC_R1_VOL_SHIFT 0 | ||
277 | |||
278 | /* ADC Digital Volume Control (0x001c) */ | ||
279 | #define RT5668_ADC_L_MUTE_MASK (0x1 << 15) | ||
280 | #define RT5668_ADC_L_MUTE_SHIFT 15 | ||
281 | #define RT5668_ADC_L_VOL_MASK (0x7f << 8) | ||
282 | #define RT5668_ADC_L_VOL_SHIFT 8 | ||
283 | #define RT5668_ADC_R_MUTE_MASK (0x1 << 7) | ||
284 | #define RT5668_ADC_R_MUTE_SHIFT 7 | ||
285 | #define RT5668_ADC_R_VOL_MASK (0x7f) | ||
286 | #define RT5668_ADC_R_VOL_SHIFT 0 | ||
287 | |||
288 | /* Stereo ADC Mixer Control (0x0026) */ | ||
289 | #define RT5668_M_STO1_ADC_L1 (0x1 << 15) | ||
290 | #define RT5668_M_STO1_ADC_L1_SHIFT 15 | ||
291 | #define RT5668_M_STO1_ADC_L2 (0x1 << 14) | ||
292 | #define RT5668_M_STO1_ADC_L2_SHIFT 14 | ||
293 | #define RT5668_STO1_ADC_L1_SRC (0x1 << 13) | ||
294 | #define RT5668_STO1_ADC_L1_SRC_SHIFT 13 | ||
295 | #define RT5668_STO1_ADC_L2_SRC (0x1 << 12) | ||
296 | #define RT5668_STO1_ADC_L2_SRC_SHIFT 12 | ||
297 | #define RT5668_STO1_ADC_L_SRC (0x3 << 10) | ||
298 | #define RT5668_STO1_ADC_L_SRC_SHIFT 10 | ||
299 | #define RT5668_M_STO1_ADC_R1 (0x1 << 7) | ||
300 | #define RT5668_M_STO1_ADC_R1_SHIFT 7 | ||
301 | #define RT5668_M_STO1_ADC_R2 (0x1 << 6) | ||
302 | #define RT5668_M_STO1_ADC_R2_SHIFT 6 | ||
303 | #define RT5668_STO1_ADC_R1_SRC (0x1 << 5) | ||
304 | #define RT5668_STO1_ADC_R1_SRC_SHIFT 5 | ||
305 | #define RT5668_STO1_ADC_R2_SRC (0x1 << 4) | ||
306 | #define RT5668_STO1_ADC_R2_SRC_SHIFT 4 | ||
307 | #define RT5668_STO1_ADC_R_SRC (0x3 << 2) | ||
308 | #define RT5668_STO1_ADC_R_SRC_SHIFT 2 | ||
309 | |||
310 | /* ADC Mixer to DAC Mixer Control (0x0029) */ | ||
311 | #define RT5668_M_ADCMIX_L (0x1 << 15) | ||
312 | #define RT5668_M_ADCMIX_L_SHIFT 15 | ||
313 | #define RT5668_M_DAC1_L (0x1 << 14) | ||
314 | #define RT5668_M_DAC1_L_SHIFT 14 | ||
315 | #define RT5668_M_ADCMIX_R (0x1 << 7) | ||
316 | #define RT5668_M_ADCMIX_R_SHIFT 7 | ||
317 | #define RT5668_M_DAC1_R (0x1 << 6) | ||
318 | #define RT5668_M_DAC1_R_SHIFT 6 | ||
319 | |||
320 | /* Stereo DAC Mixer Control (0x002a) */ | ||
321 | #define RT5668_M_DAC_L1_STO_L (0x1 << 15) | ||
322 | #define RT5668_M_DAC_L1_STO_L_SHIFT 15 | ||
323 | #define RT5668_M_DAC_R1_STO_L (0x1 << 13) | ||
324 | #define RT5668_M_DAC_R1_STO_L_SHIFT 13 | ||
325 | #define RT5668_M_DAC_L1_STO_R (0x1 << 7) | ||
326 | #define RT5668_M_DAC_L1_STO_R_SHIFT 7 | ||
327 | #define RT5668_M_DAC_R1_STO_R (0x1 << 5) | ||
328 | #define RT5668_M_DAC_R1_STO_R_SHIFT 5 | ||
329 | |||
330 | /* Power Management for Digital 1 (0x0061) */ | ||
331 | #define RT5668_PWR_I2S1 (0x1 << 15) | ||
332 | #define RT5668_PWR_I2S1_SHIFT 15 | ||
333 | #define RT5668_PWR_DAC_L1 (0x1 << 11) | ||
334 | #define RT5668_PWR_DAC_L1_SHIFT 11 | ||
335 | #define RT5668_PWR_DAC_R1 (0x1 << 10) | ||
336 | #define RT5668_PWR_DAC_R1_SHIFT 10 | ||
337 | #define RT5668_PWR_LDO_DACREF_MASK (0x1 << 8) | ||
338 | #define RT5668_PWR_LDO_DACREF_SHIFT 8 | ||
339 | #define RT5668_PWR_LDO_DACREF_ON (0x1 << 8) | ||
340 | #define RT5668_PWR_LDO_DACREF_DOWN (0x0 << 8) | ||
341 | #define RT5668_PWR_LDO_SHIFT 8 | ||
342 | #define RT5668_PWR_ADC_L1 (0x1 << 4) | ||
343 | #define RT5668_PWR_ADC_L1_SHIFT 4 | ||
344 | #define RT5668_PWR_ADC_R1 (0x1 << 3) | ||
345 | #define RT5668_PWR_ADC_R1_SHIFT 3 | ||
346 | |||
347 | /* Power Management for Digital 2 (0x0062) */ | ||
348 | #define RT5668_PWR_ADC_S1F (0x1 << 15) | ||
349 | #define RT5668_PWR_ADC_S1F_SHIFT 15 | ||
350 | #define RT5668_PWR_DAC_S1F (0x1 << 10) | ||
351 | #define RT5668_PWR_DAC_S1F_SHIFT 10 | ||
352 | |||
353 | /* Power Management for Analog 1 (0x0063) */ | ||
354 | #define RT5668_PWR_VREF1 (0x1 << 15) | ||
355 | #define RT5668_PWR_VREF1_MASK (0x1 << 15) | ||
356 | #define RT5668_PWR_VREF1_SHIFT 15 | ||
357 | #define RT5668_PWR_FV1 (0x1 << 14) | ||
358 | #define RT5668_PWR_FV1_MASK (0x1 << 14) | ||
359 | #define RT5668_PWR_FV1_SHIFT 14 | ||
360 | #define RT5668_PWR_VREF2 (0x1 << 13) | ||
361 | #define RT5668_PWR_VREF2_MASK (0x1 << 13) | ||
362 | #define RT5668_PWR_VREF2_SHIFT 13 | ||
363 | #define RT5668_PWR_FV2 (0x1 << 12) | ||
364 | #define RT5668_PWR_FV2_MASK (0x1 << 12) | ||
365 | #define RT5668_PWR_FV2_SHIFT 12 | ||
366 | #define RT5668_PWR_MB (0x1 << 9) | ||
367 | #define RT5668_PWR_MB_MASK (0x1 << 9) | ||
368 | #define RT5668_PWR_MB_SHIFT 9 | ||
369 | #define RT5668_AMP_HP_MASK (0x3 << 2) | ||
370 | #define RT5668_AMP_HP_SHIFT 2 | ||
371 | #define RT5668_AMP_HP_1X (0x0 << 2) | ||
372 | #define RT5668_AMP_HP_3X (0x1 << 2) | ||
373 | #define RT5668_AMP_HP_5X (0x3 << 2) | ||
374 | #define RT5668_LDO1_DVO_MASK (0x3) | ||
375 | #define RT5668_LDO1_DVO_SHIFT 0 | ||
376 | #define RT5668_LDO1_DVO_0_9V (0x0) | ||
377 | #define RT5668_LDO1_DVO_1_0V (0x1) | ||
378 | #define RT5668_LDO1_DVO_1_2V (0x2) | ||
379 | #define RT5668_LDO1_DVO_1_4V (0x3) | ||
380 | |||
381 | /* Power Management for Analog 2 (0x0064) */ | ||
382 | #define RT5668_PWR_BST1 (0x1 << 15) | ||
383 | #define RT5668_PWR_BST1_MASK (0x1 << 15) | ||
384 | #define RT5668_PWR_BST1_SHIFT 15 | ||
385 | #define RT5668_PWR_BST1_OFF (0x0 << 15) | ||
386 | #define RT5668_PWR_BST1_ON (0x1 << 15) | ||
387 | #define RT5668_PWR_BST2 (0x1 << 14) | ||
388 | #define RT5668_PWR_BST2_MASK (0x1 << 14) | ||
389 | #define RT5668_PWR_BST2_SHIFT 14 | ||
390 | #define RT5668_PWR_MB1 (0x1 << 11) | ||
391 | #define RT5668_PWR_MB1_SHIFT 11 | ||
392 | #define RT5668_PWR_MB2 (0x1 << 10) | ||
393 | #define RT5668_PWR_MB2_SHIFT 10 | ||
394 | #define RT5668_PWR_BST2_OP (0x1 << 6) | ||
395 | #define RT5668_PWR_BST2_OP_MASK (0x1 << 6) | ||
396 | #define RT5668_PWR_BST2_OP_SHIFT 6 | ||
397 | #define RT5668_PWR_JD1 (0x1 << 3) | ||
398 | #define RT5668_PWR_JD1_MASK (0x1 << 3) | ||
399 | #define RT5668_PWR_JD1_SHIFT 3 | ||
400 | #define RT5668_PWR_JD2 (0x1 << 2) | ||
401 | #define RT5668_PWR_JD2_MASK (0x1 << 2) | ||
402 | #define RT5668_PWR_JD2_SHIFT 2 | ||
403 | #define RT5668_PWR_RECMIX1 (0x1 << 1) | ||
404 | #define RT5668_PWR_RECMIX1_SHIFT 1 | ||
405 | #define RT5668_PWR_RECMIX2 (0x1) | ||
406 | #define RT5668_PWR_RECMIX2_SHIFT 0 | ||
407 | |||
408 | /* Power Management for Analog 3 (0x0065) */ | ||
409 | #define RT5668_PWR_CBJ_MASK (0x1 << 9) | ||
410 | #define RT5668_PWR_CBJ_SHIFT 9 | ||
411 | #define RT5668_PWR_CBJ_OFF (0x0 << 9) | ||
412 | #define RT5668_PWR_CBJ_ON (0x1 << 9) | ||
413 | #define RT5668_PWR_PLL (0x1 << 6) | ||
414 | #define RT5668_PWR_PLL_SHIFT 6 | ||
415 | #define RT5668_PWR_LDO2 (0x1 << 2) | ||
416 | #define RT5668_PWR_LDO2_SHIFT 2 | ||
417 | |||
418 | /* Power Management for Volume (0x0067) */ | ||
419 | #define RT5668_PWR_MIC_DET (0x1 << 5) | ||
420 | #define RT5668_PWR_MIC_DET_SHIFT 5 | ||
421 | |||
422 | /* MCLK and System Clock Detection Control (0x006b) */ | ||
423 | #define RT5668_EN_ANA_CLK_DET_MASK (0x1 << 15) | ||
424 | #define RT5668_EN_ANA_CLK_DET_SHIFT 15 | ||
425 | #define RT5668_EN_ANA_CLK_DET_DIS (0x0 << 15) | ||
426 | #define RT5668_EN_ANA_CLK_DET_AUTO (0x1 << 15) | ||
427 | #define RT5668_PWR_CLK_DET_MASK (0x1) | ||
428 | #define RT5668_PWR_CLK_DET_SHIFT 0 | ||
429 | #define RT5668_PWR_CLK_DET_DIS (0x0) | ||
430 | #define RT5668_PWR_CLK_DET_EN (0x1) | ||
431 | |||
432 | /* I2S1 Audio Serial Data Port Control (0x0070) */ | ||
433 | #define RT5668_I2S_MS_MASK (0x1 << 15) | ||
434 | #define RT5668_I2S_MS_SHIFT 15 | ||
435 | #define RT5668_I2S_MS_M (0x0 << 15) | ||
436 | #define RT5668_I2S_MS_S (0x1 << 15) | ||
437 | #define RT5668_I2S_BP_MASK (0x1 << 8) | ||
438 | #define RT5668_I2S_BP_SHIFT 8 | ||
439 | #define RT5668_I2S_BP_NOR (0x0 << 8) | ||
440 | #define RT5668_I2S_BP_INV (0x1 << 8) | ||
441 | #define RT5668_I2S_DL_MASK (0x3 << 4) | ||
442 | #define RT5668_I2S_DL_SHIFT 4 | ||
443 | #define RT5668_I2S_DL_16 (0x0 << 4) | ||
444 | #define RT5668_I2S_DL_20 (0x1 << 4) | ||
445 | #define RT5668_I2S_DL_24 (0x2 << 4) | ||
446 | #define RT5668_I2S_DL_8 (0x3 << 4) | ||
447 | #define RT5668_I2S_DF_MASK (0x7) | ||
448 | #define RT5668_I2S_DF_SHIFT 0 | ||
449 | #define RT5668_I2S_DF_I2S (0x0) | ||
450 | #define RT5668_I2S_DF_LEFT (0x1) | ||
451 | #define RT5668_I2S_DF_PCM_A (0x2) | ||
452 | #define RT5668_I2S_DF_PCM_B (0x3) | ||
453 | #define RT5668_I2S_DF_PCM_A_N (0x6) | ||
454 | #define RT5668_I2S_DF_PCM_B_N (0x7) | ||
455 | |||
456 | /* ADC/DAC Clock Control 1 (0x0073) */ | ||
457 | #define RT5668_I2S_PD1_MASK (0x7 << 12) | ||
458 | #define RT5668_I2S_PD1_SHIFT 12 | ||
459 | #define RT5668_M_I2S_DIV_MASK (0x7 << 8) | ||
460 | #define RT5668_M_I2S_DIV_SHIFT 8 | ||
461 | #define RT5668_CLK_SRC_MASK (0x3 << 4) | ||
462 | #define RT5668_CLK_SRC_MCLK (0x0 << 4) | ||
463 | #define RT5668_CLK_SRC_PLL_OUT (0x1 << 4) | ||
464 | #define RT5668_CLK_SRC_DIV (0x2 << 4) | ||
465 | #define RT5668_CLK_SRC_RC (0x3 << 4) | ||
466 | #define RT5668_DAC_OSR_MASK (0x3 << 2) | ||
467 | #define RT5668_DAC_OSR_SHIFT 2 | ||
468 | #define RT5668_DAC_OSR_128 (0x0 << 2) | ||
469 | #define RT5668_DAC_OSR_64 (0x1 << 2) | ||
470 | #define RT5668_DAC_OSR_32 (0x2 << 2) | ||
471 | #define RT5668_ADC_OSR_MASK (0x3) | ||
472 | #define RT5668_ADC_OSR_SHIFT 0 | ||
473 | #define RT5668_ADC_OSR_128 (0x0) | ||
474 | #define RT5668_ADC_OSR_64 (0x1) | ||
475 | #define RT5668_ADC_OSR_32 (0x2) | ||
476 | |||
477 | /* TDM1 control 1 (0x0078) */ | ||
478 | #define RT5668_TDM_MODE_MASK (0x1 << 15) | ||
479 | #define RT5668_TDM_MODE_SHIFT 15 | ||
480 | #define RT5668_TDM_MODE_I2S (0x0 << 15) | ||
481 | #define RT5668_TDM_MODE_TDM (0x1 << 15) | ||
482 | #define RT5668_TDM_IN_CH_MASK (0x3 << 10) | ||
483 | #define RT5668_TDM_IN_CH_SHIFT 10 | ||
484 | #define RT5668_TDM_IN_CH_2 (0x0 << 10) | ||
485 | #define RT5668_TDM_IN_CH_4 (0x1 << 10) | ||
486 | #define RT5668_TDM_IN_CH_6 (0x2 << 10) | ||
487 | #define RT5668_TDM_IN_CH_8 (0x3 << 10) | ||
488 | #define RT5668_TDM_OUT_CH_MASK (0x3 << 8) | ||
489 | #define RT5668_TDM_OUT_CH_SHIFT 8 | ||
490 | #define RT5668_TDM_OUT_CH_2 (0x0 << 8) | ||
491 | #define RT5668_TDM_OUT_CH_4 (0x1 << 8) | ||
492 | #define RT5668_TDM_OUT_CH_6 (0x2 << 8) | ||
493 | #define RT5668_TDM_OUT_CH_8 (0x3 << 8) | ||
494 | #define RT5668_TDM_IN_LEN_MASK (0x3 << 6) | ||
495 | #define RT5668_TDM_IN_LEN_SHIFT 6 | ||
496 | #define RT5668_TDM_IN_LEN_16 (0x0 << 6) | ||
497 | #define RT5668_TDM_IN_LEN_20 (0x1 << 6) | ||
498 | #define RT5668_TDM_IN_LEN_24 (0x2 << 6) | ||
499 | #define RT5668_TDM_IN_LEN_32 (0x3 << 6) | ||
500 | #define RT5668_TDM_OUT_LEN_MASK (0x3 << 4) | ||
501 | #define RT5668_TDM_OUT_LEN_SHIFT 4 | ||
502 | #define RT5668_TDM_OUT_LEN_16 (0x0 << 4) | ||
503 | #define RT5668_TDM_OUT_LEN_20 (0x1 << 4) | ||
504 | #define RT5668_TDM_OUT_LEN_24 (0x2 << 4) | ||
505 | #define RT5668_TDM_OUT_LEN_32 (0x3 << 4) | ||
506 | |||
507 | /* Global Clock Control (0x0080) */ | ||
508 | #define RT5668_SCLK_SRC_MASK (0x3 << 14) | ||
509 | #define RT5668_SCLK_SRC_SHIFT 14 | ||
510 | #define RT5668_SCLK_SRC_MCLK (0x0 << 14) | ||
511 | #define RT5668_SCLK_SRC_PLL1 (0x1 << 14) | ||
512 | #define RT5668_SCLK_SRC_RCCLK (0x2 << 14) | ||
513 | #define RT5668_PLL1_SRC_MASK (0x7 << 8) | ||
514 | #define RT5668_PLL1_SRC_SHIFT 8 | ||
515 | #define RT5668_PLL1_SRC_MCLK (0x0 << 8) | ||
516 | #define RT5668_PLL1_SRC_BCLK1 (0x1 << 8) | ||
517 | #define RT5668_PLL1_PD_MASK (0x1 << 4) | ||
518 | #define RT5668_PLL1_PD_SHIFT 4 | ||
519 | |||
520 | #define RT5668_PLL_INP_MAX 40000000 | ||
521 | #define RT5668_PLL_INP_MIN 256000 | ||
522 | /* PLL M/N/K Code Control 1 (0x0081) */ | ||
523 | #define RT5668_PLL_N_MAX 0x001ff | ||
524 | #define RT5668_PLL_N_MASK (RT5668_PLL_N_MAX << 7) | ||
525 | #define RT5668_PLL_N_SHIFT 7 | ||
526 | #define RT5668_PLL_K_MAX 0x001f | ||
527 | #define RT5668_PLL_K_MASK (RT5668_PLL_K_MAX) | ||
528 | #define RT5668_PLL_K_SHIFT 0 | ||
529 | |||
530 | /* PLL M/N/K Code Control 2 (0x0082) */ | ||
531 | #define RT5668_PLL_M_MAX 0x00f | ||
532 | #define RT5668_PLL_M_MASK (RT5668_PLL_M_MAX << 12) | ||
533 | #define RT5668_PLL_M_SHIFT 12 | ||
534 | #define RT5668_PLL_M_BP (0x1 << 11) | ||
535 | #define RT5668_PLL_M_BP_SHIFT 11 | ||
536 | |||
537 | /* PLL tracking mode 1 (0x0083) */ | ||
538 | #define RT5668_I2S1_ASRC_MASK (0x1 << 13) | ||
539 | #define RT5668_I2S1_ASRC_SHIFT 13 | ||
540 | #define RT5668_DAC_STO1_ASRC_MASK (0x1 << 12) | ||
541 | #define RT5668_DAC_STO1_ASRC_SHIFT 12 | ||
542 | #define RT5668_ADC_STO1_ASRC_MASK (0x1 << 4) | ||
543 | #define RT5668_ADC_STO1_ASRC_SHIFT 4 | ||
544 | |||
545 | /* PLL tracking mode 2 (0x0084)*/ | ||
546 | #define RT5668_DA_STO1_TRACK_MASK (0x7 << 12) | ||
547 | #define RT5668_DA_STO1_TRACK_SHIFT 12 | ||
548 | #define RT5668_DA_STO1_TRACK_SYSCLK (0x0 << 12) | ||
549 | #define RT5668_DA_STO1_TRACK_I2S1 (0x1 << 12) | ||
550 | |||
551 | /* PLL tracking mode 3 (0x0085)*/ | ||
552 | #define RT5668_AD_STO1_TRACK_MASK (0x7 << 12) | ||
553 | #define RT5668_AD_STO1_TRACK_SHIFT 12 | ||
554 | #define RT5668_AD_STO1_TRACK_SYSCLK (0x0 << 12) | ||
555 | #define RT5668_AD_STO1_TRACK_I2S1 (0x1 << 12) | ||
556 | |||
557 | /* HPOUT Charge pump control 1 (0x0091) */ | ||
558 | #define RT5668_OSW_HP_L_MASK (0x1 << 11) | ||
559 | #define RT5668_OSW_HP_L_SHIFT 11 | ||
560 | #define RT5668_OSW_HP_L_EN (0x1 << 11) | ||
561 | #define RT5668_OSW_HP_L_DIS (0x0 << 11) | ||
562 | #define RT5668_OSW_HP_R_MASK (0x1 << 10) | ||
563 | #define RT5668_OSW_HP_R_SHIFT 10 | ||
564 | #define RT5668_OSW_HP_R_EN (0x1 << 10) | ||
565 | #define RT5668_OSW_HP_R_DIS (0x0 << 10) | ||
566 | #define RT5668_SEL_PM_HP_MASK (0x3 << 8) | ||
567 | #define RT5668_SEL_PM_HP_SHIFT 8 | ||
568 | #define RT5668_SEL_PM_HP_0_6 (0x0 << 8) | ||
569 | #define RT5668_SEL_PM_HP_0_9 (0x1 << 8) | ||
570 | #define RT5668_SEL_PM_HP_1_8 (0x2 << 8) | ||
571 | #define RT5668_SEL_PM_HP_HIGH (0x3 << 8) | ||
572 | #define RT5668_OVCD_HP_MASK (0x1 << 2) | ||
573 | #define RT5668_OVCD_HP_SHIFT 2 | ||
574 | #define RT5668_OVCD_HP_EN (0x1 << 2) | ||
575 | #define RT5668_OVCD_HP_DIS (0x0 << 2) | ||
576 | |||
577 | /* RC Clock Control (0x0094) */ | ||
578 | #define RT5668_DIG_25M_CLK_MASK (0x1 << 9) | ||
579 | #define RT5668_DIG_25M_CLK_SHIFT 9 | ||
580 | #define RT5668_DIG_25M_CLK_DIS (0x0 << 9) | ||
581 | #define RT5668_DIG_25M_CLK_EN (0x1 << 9) | ||
582 | #define RT5668_DIG_1M_CLK_MASK (0x1 << 8) | ||
583 | #define RT5668_DIG_1M_CLK_SHIFT 8 | ||
584 | #define RT5668_DIG_1M_CLK_DIS (0x0 << 8) | ||
585 | #define RT5668_DIG_1M_CLK_EN (0x1 << 8) | ||
586 | |||
587 | /* Auto Turn On 1M RC CLK (0x009f) */ | ||
588 | #define RT5668_IRQ_POW_SAV_MASK (0x1 << 15) | ||
589 | #define RT5668_IRQ_POW_SAV_SHIFT 15 | ||
590 | #define RT5668_IRQ_POW_SAV_DIS (0x0 << 15) | ||
591 | #define RT5668_IRQ_POW_SAV_EN (0x1 << 15) | ||
592 | #define RT5668_IRQ_POW_SAV_JD1_MASK (0x1 << 14) | ||
593 | #define RT5668_IRQ_POW_SAV_JD1_SHIFT 14 | ||
594 | #define RT5668_IRQ_POW_SAV_JD1_DIS (0x0 << 14) | ||
595 | #define RT5668_IRQ_POW_SAV_JD1_EN (0x1 << 14) | ||
596 | |||
597 | /* IRQ Control 1 (0x00b6) */ | ||
598 | #define RT5668_EN_CB_JD_MASK (0x1 << 3) | ||
599 | #define RT5668_EN_CB_JD_SHIFT 3 | ||
600 | #define RT5668_EN_CB_JD_EN (0x1 << 3) | ||
601 | #define RT5668_EN_CB_JD_DIS (0x0 << 3) | ||
602 | |||
603 | /* IRQ Control 3 (0x00b8) */ | ||
604 | #define RT5668_EN_IRQ_INLINE_MASK (0x1 << 6) | ||
605 | #define RT5668_EN_IRQ_INLINE_SHIFT 6 | ||
606 | #define RT5668_EN_IRQ_INLINE_BYP (0x0 << 6) | ||
607 | #define RT5668_EN_IRQ_INLINE_NOR (0x1 << 6) | ||
608 | |||
609 | /* GPIO Control 1 (0x00c0) */ | ||
610 | #define RT5668_GP1_PIN_MASK (0x1 << 15) | ||
611 | #define RT5668_GP1_PIN_SHIFT 15 | ||
612 | #define RT5668_GP1_PIN_GPIO1 (0x0 << 15) | ||
613 | #define RT5668_GP1_PIN_IRQ (0x1 << 15) | ||
614 | |||
615 | /* GPIO Control 2 (0x00c1) */ | ||
616 | #define RT5668_GP4_PIN_CONF_MASK (0x1 << 5) | ||
617 | #define RT5668_GP4_PIN_CONF_SHIFT 5 | ||
618 | #define RT5668_GP4_PIN_CONF_INPUT (0x0 << 5) | ||
619 | #define RT5668_GP4_PIN_CONF_OUTPUT (0x1 << 5) | ||
620 | |||
621 | /* GPIO Control 2 (0x00c2) */ | ||
622 | #define RT5668_GP8_PIN_CONF_MASK (0x1 << 13) | ||
623 | #define RT5668_GP8_PIN_CONF_SHIFT 13 | ||
624 | #define RT5668_GP8_PIN_CONF_INPUT (0x0 << 13) | ||
625 | #define RT5668_GP8_PIN_CONF_OUTPUT (0x1 << 13) | ||
626 | |||
627 | /* 4 Buttons Inline Command Function 1 (0x00df) */ | ||
628 | #define RT5668_4BTN_CLK_DEB_MASK (0x3 << 2) | ||
629 | #define RT5668_4BTN_CLK_DEB_SHIFT 2 | ||
630 | #define RT5668_4BTN_CLK_DEB_8MS (0x0 << 2) | ||
631 | #define RT5668_4BTN_CLK_DEB_16MS (0x1 << 2) | ||
632 | #define RT5668_4BTN_CLK_DEB_32MS (0x2 << 2) | ||
633 | #define RT5668_4BTN_CLK_DEB_65MS (0x3 << 2) | ||
634 | |||
635 | /* Inline Command Function 6 (0x00e0) */ | ||
636 | #define RT5668_EN_4BTN_INL_MASK (0x1 << 15) | ||
637 | #define RT5668_EN_4BTN_INL_SHIFT 15 | ||
638 | #define RT5668_EN_4BTN_INL_DIS (0x0 << 15) | ||
639 | #define RT5668_EN_4BTN_INL_EN (0x1 << 15) | ||
640 | #define RT5668_RESET_4BTN_INL_MASK (0x1 << 14) | ||
641 | #define RT5668_RESET_4BTN_INL_SHIFT 14 | ||
642 | #define RT5668_RESET_4BTN_INL_RESET (0x0 << 14) | ||
643 | #define RT5668_RESET_4BTN_INL_NOR (0x1 << 14) | ||
644 | |||
645 | /* Digital Misc Control (0x00fa) */ | ||
646 | #define RT5668_DIG_GATE_CTRL_MASK 0x1 | ||
647 | #define RT5668_DIG_GATE_CTRL_SHIFT (0) | ||
648 | #define RT5668_DIG_GATE_CTRL_DIS 0x0 | ||
649 | #define RT5668_DIG_GATE_CTRL_EN 0x1 | ||
650 | |||
651 | /* Chopper and Clock control for DAC L (0x013a)*/ | ||
652 | #define RT5668_CKXEN_DAC1_MASK (0x1 << 13) | ||
653 | #define RT5668_CKXEN_DAC1_SHIFT 13 | ||
654 | #define RT5668_CKGEN_DAC1_MASK (0x1 << 12) | ||
655 | #define RT5668_CKGEN_DAC1_SHIFT 12 | ||
656 | |||
657 | /* Chopper and Clock control for ADC (0x013b)*/ | ||
658 | #define RT5668_CKXEN_ADCC_MASK (0x1 << 13) | ||
659 | #define RT5668_CKXEN_ADCC_SHIFT 13 | ||
660 | #define RT5668_CKGEN_ADCC_MASK (0x1 << 12) | ||
661 | #define RT5668_CKGEN_ADCC_SHIFT 12 | ||
662 | |||
663 | /* HP Behavior Logic Control 2 (0x01db) */ | ||
664 | #define RT5668_HP_SIG_SRC1_MASK (0x3) | ||
665 | #define RT5668_HP_SIG_SRC1_SHIFT 0 | ||
666 | #define RT5668_HP_SIG_SRC1_HP_DC (0x0) | ||
667 | #define RT5668_HP_SIG_SRC1_HP_CALIB (0x1) | ||
668 | #define RT5668_HP_SIG_SRC1_REG (0x2) | ||
669 | #define RT5668_HP_SIG_SRC1_SILENCE (0x3) | ||
670 | |||
671 | /* RT5663 specific register */ | ||
672 | #define RT5663_HP_OUT_EN 0x0002 | ||
673 | #define RT5663_HP_LCH_DRE 0x0005 | ||
674 | #define RT5663_HP_RCH_DRE 0x0006 | ||
675 | #define RT5663_CALIB_BST 0x000a | ||
676 | #define RT5663_RECMIX 0x0010 | ||
677 | #define RT5663_SIL_DET_CTL 0x0015 | ||
678 | #define RT5663_PWR_SAV_SILDET 0x0016 | ||
679 | #define RT5663_SIDETONE_CTL 0x0018 | ||
680 | #define RT5663_STO1_DAC_DIG_VOL 0x0019 | ||
681 | #define RT5663_STO1_ADC_DIG_VOL 0x001c | ||
682 | #define RT5663_STO1_BOOST 0x001f | ||
683 | #define RT5663_HP_IMP_GAIN_1 0x0022 | ||
684 | #define RT5663_HP_IMP_GAIN_2 0x0023 | ||
685 | #define RT5663_STO1_ADC_MIXER 0x0026 | ||
686 | #define RT5663_AD_DA_MIXER 0x0029 | ||
687 | #define RT5663_STO_DAC_MIXER 0x002a | ||
688 | #define RT5663_DIG_SIDE_MIXER 0x002c | ||
689 | #define RT5663_BYPASS_STO_DAC 0x002d | ||
690 | #define RT5663_CALIB_REC_MIX 0x0040 | ||
691 | #define RT5663_PWR_DIG_1 0x0061 | ||
692 | #define RT5663_PWR_DIG_2 0x0062 | ||
693 | #define RT5663_PWR_ANLG_1 0x0063 | ||
694 | #define RT5663_PWR_ANLG_2 0x0064 | ||
695 | #define RT5663_PWR_ANLG_3 0x0065 | ||
696 | #define RT5663_PWR_MIXER 0x0066 | ||
697 | #define RT5663_SIG_CLK_DET 0x006b | ||
698 | #define RT5663_PRE_DIV_GATING_1 0x006e | ||
699 | #define RT5663_PRE_DIV_GATING_2 0x006f | ||
700 | #define RT5663_I2S1_SDP 0x0070 | ||
701 | #define RT5663_ADDA_CLK_1 0x0073 | ||
702 | #define RT5663_ADDA_RST 0x0074 | ||
703 | #define RT5663_FRAC_DIV_1 0x0075 | ||
704 | #define RT5663_FRAC_DIV_2 0x0076 | ||
705 | #define RT5663_TDM_1 0x0077 | ||
706 | #define RT5663_TDM_2 0x0078 | ||
707 | #define RT5663_TDM_3 0x0079 | ||
708 | #define RT5663_TDM_4 0x007a | ||
709 | #define RT5663_TDM_5 0x007b | ||
710 | #define RT5663_GLB_CLK 0x0080 | ||
711 | #define RT5663_PLL_1 0x0081 | ||
712 | #define RT5663_PLL_2 0x0082 | ||
713 | #define RT5663_ASRC_1 0x0083 | ||
714 | #define RT5663_ASRC_2 0x0084 | ||
715 | #define RT5663_ASRC_4 0x0086 | ||
716 | #define RT5663_DUMMY_REG 0x0087 | ||
717 | #define RT5663_ASRC_8 0x008a | ||
718 | #define RT5663_ASRC_9 0x008b | ||
719 | #define RT5663_ASRC_11 0x008c | ||
720 | #define RT5663_DEPOP_1 0x008e | ||
721 | #define RT5663_DEPOP_2 0x008f | ||
722 | #define RT5663_DEPOP_3 0x0090 | ||
723 | #define RT5663_HP_CHARGE_PUMP_1 0x0091 | ||
724 | #define RT5663_HP_CHARGE_PUMP_2 0x0092 | ||
725 | #define RT5663_MICBIAS_1 0x0093 | ||
726 | #define RT5663_RC_CLK 0x0094 | ||
727 | #define RT5663_ASRC_11_2 0x0097 | ||
728 | #define RT5663_DUMMY_REG_2 0x0098 | ||
729 | #define RT5663_REC_PATH_GAIN 0x009a | ||
730 | #define RT5663_AUTO_1MRC_CLK 0x009f | ||
731 | #define RT5663_ADC_EQ_1 0x00ae | ||
732 | #define RT5663_ADC_EQ_2 0x00af | ||
733 | #define RT5663_IRQ_1 0x00b6 | ||
734 | #define RT5663_IRQ_2 0x00b7 | ||
735 | #define RT5663_IRQ_3 0x00b8 | ||
736 | #define RT5663_IRQ_4 0x00ba | ||
737 | #define RT5663_IRQ_5 0x00bb | ||
738 | #define RT5663_INT_ST_1 0x00be | ||
739 | #define RT5663_INT_ST_2 0x00bf | ||
740 | #define RT5663_GPIO_1 0x00c0 | ||
741 | #define RT5663_GPIO_2 0x00c1 | ||
742 | #define RT5663_GPIO_STA 0x00c5 | ||
743 | #define RT5663_SIN_GEN_1 0x00cb | ||
744 | #define RT5663_SIN_GEN_2 0x00cc | ||
745 | #define RT5663_SIN_GEN_3 0x00cd | ||
746 | #define RT5663_SOF_VOL_ZC1 0x00d9 | ||
747 | #define RT5663_IL_CMD_1 0x00db | ||
748 | #define RT5663_IL_CMD_2 0x00dc | ||
749 | #define RT5663_IL_CMD_3 0x00dd | ||
750 | #define RT5663_IL_CMD_4 0x00de | ||
751 | #define RT5663_IL_CMD_5 0x00df | ||
752 | #define RT5663_IL_CMD_6 0x00e0 | ||
753 | #define RT5663_IL_CMD_7 0x00e1 | ||
754 | #define RT5663_IL_CMD_8 0x00e2 | ||
755 | #define RT5663_IL_CMD_PWRSAV1 0x00e4 | ||
756 | #define RT5663_IL_CMD_PWRSAV2 0x00e5 | ||
757 | #define RT5663_EM_JACK_TYPE_1 0x00e6 | ||
758 | #define RT5663_EM_JACK_TYPE_2 0x00e7 | ||
759 | #define RT5663_EM_JACK_TYPE_3 0x00e8 | ||
760 | #define RT5663_EM_JACK_TYPE_4 0x00e9 | ||
761 | #define RT5663_EM_JACK_TYPE_5 0x00ea | ||
762 | #define RT5663_EM_JACK_TYPE_6 0x00eb | ||
763 | #define RT5663_STO1_HPF_ADJ1 0x00ec | ||
764 | #define RT5663_STO1_HPF_ADJ2 0x00ed | ||
765 | #define RT5663_FAST_OFF_MICBIAS 0x00f4 | ||
766 | #define RT5663_JD_CTRL1 0x00f6 | ||
767 | #define RT5663_JD_CTRL2 0x00f8 | ||
768 | #define RT5663_DIG_MISC 0x00fa | ||
769 | #define RT5663_DIG_VOL_ZCD 0x0100 | ||
770 | #define RT5663_ANA_BIAS_CUR_1 0x0108 | ||
771 | #define RT5663_ANA_BIAS_CUR_2 0x0109 | ||
772 | #define RT5663_ANA_BIAS_CUR_3 0x010a | ||
773 | #define RT5663_ANA_BIAS_CUR_4 0x010b | ||
774 | #define RT5663_ANA_BIAS_CUR_5 0x010c | ||
775 | #define RT5663_ANA_BIAS_CUR_6 0x010d | ||
776 | #define RT5663_BIAS_CUR_5 0x010e | ||
777 | #define RT5663_BIAS_CUR_6 0x010f | ||
778 | #define RT5663_BIAS_CUR_7 0x0110 | ||
779 | #define RT5663_BIAS_CUR_8 0x0111 | ||
780 | #define RT5663_DACREF_LDO 0x0112 | ||
781 | #define RT5663_DUMMY_REG_3 0x0113 | ||
782 | #define RT5663_BIAS_CUR_9 0x0114 | ||
783 | #define RT5663_DUMMY_REG_4 0x0116 | ||
784 | #define RT5663_VREFADJ_OP 0x0117 | ||
785 | #define RT5663_VREF_RECMIX 0x0118 | ||
786 | #define RT5663_CHARGE_PUMP_1 0x0125 | ||
787 | #define RT5663_CHARGE_PUMP_1_2 0x0126 | ||
788 | #define RT5663_CHARGE_PUMP_1_3 0x0127 | ||
789 | #define RT5663_CHARGE_PUMP_2 0x0128 | ||
790 | #define RT5663_DIG_IN_PIN1 0x0132 | ||
791 | #define RT5663_PAD_DRV_CTL 0x0137 | ||
792 | #define RT5663_PLL_INT_REG 0x0139 | ||
793 | #define RT5663_CHOP_DAC_L 0x013a | ||
794 | #define RT5663_CHOP_ADC 0x013b | ||
795 | #define RT5663_CALIB_ADC 0x013c | ||
796 | #define RT5663_CHOP_DAC_R 0x013d | ||
797 | #define RT5663_DUMMY_CTL_DACLR 0x013e | ||
798 | #define RT5663_DUMMY_REG_5 0x0140 | ||
799 | #define RT5663_SOFT_RAMP 0x0141 | ||
800 | #define RT5663_TEST_MODE_1 0x0144 | ||
801 | #define RT5663_TEST_MODE_2 0x0145 | ||
802 | #define RT5663_TEST_MODE_3 0x0146 | ||
803 | #define RT5663_STO_DRE_1 0x0160 | ||
804 | #define RT5663_STO_DRE_2 0x0161 | ||
805 | #define RT5663_STO_DRE_3 0x0162 | ||
806 | #define RT5663_STO_DRE_4 0x0163 | ||
807 | #define RT5663_STO_DRE_5 0x0164 | ||
808 | #define RT5663_STO_DRE_6 0x0165 | ||
809 | #define RT5663_STO_DRE_7 0x0166 | ||
810 | #define RT5663_STO_DRE_8 0x0167 | ||
811 | #define RT5663_STO_DRE_9 0x0168 | ||
812 | #define RT5663_STO_DRE_10 0x0169 | ||
813 | #define RT5663_MIC_DECRO_1 0x0180 | ||
814 | #define RT5663_MIC_DECRO_2 0x0181 | ||
815 | #define RT5663_MIC_DECRO_3 0x0182 | ||
816 | #define RT5663_MIC_DECRO_4 0x0183 | ||
817 | #define RT5663_MIC_DECRO_5 0x0184 | ||
818 | #define RT5663_MIC_DECRO_6 0x0185 | ||
819 | #define RT5663_HP_DECRO_1 0x01b0 | ||
820 | #define RT5663_HP_DECRO_2 0x01b1 | ||
821 | #define RT5663_HP_DECRO_3 0x01b2 | ||
822 | #define RT5663_HP_DECRO_4 0x01b3 | ||
823 | #define RT5663_HP_DECOUP 0x01b4 | ||
824 | #define RT5663_HP_IMP_SEN_MAP8 0x01b5 | ||
825 | #define RT5663_HP_IMP_SEN_MAP9 0x01b6 | ||
826 | #define RT5663_HP_IMP_SEN_MAP10 0x01b7 | ||
827 | #define RT5663_HP_IMP_SEN_MAP11 0x01b8 | ||
828 | #define RT5663_HP_IMP_SEN_1 0x01c0 | ||
829 | #define RT5663_HP_IMP_SEN_2 0x01c1 | ||
830 | #define RT5663_HP_IMP_SEN_3 0x01c2 | ||
831 | #define RT5663_HP_IMP_SEN_4 0x01c3 | ||
832 | #define RT5663_HP_IMP_SEN_5 0x01c4 | ||
833 | #define RT5663_HP_IMP_SEN_6 0x01c5 | ||
834 | #define RT5663_HP_IMP_SEN_7 0x01c6 | ||
835 | #define RT5663_HP_IMP_SEN_8 0x01c7 | ||
836 | #define RT5663_HP_IMP_SEN_9 0x01c8 | ||
837 | #define RT5663_HP_IMP_SEN_10 0x01c9 | ||
838 | #define RT5663_HP_IMP_SEN_11 0x01ca | ||
839 | #define RT5663_HP_IMP_SEN_12 0x01cb | ||
840 | #define RT5663_HP_IMP_SEN_13 0x01cc | ||
841 | #define RT5663_HP_IMP_SEN_14 0x01cd | ||
842 | #define RT5663_HP_IMP_SEN_15 0x01ce | ||
843 | #define RT5663_HP_IMP_SEN_16 0x01cf | ||
844 | #define RT5663_HP_IMP_SEN_17 0x01d0 | ||
845 | #define RT5663_HP_IMP_SEN_18 0x01d1 | ||
846 | #define RT5663_HP_IMP_SEN_19 0x01d2 | ||
847 | #define RT5663_HP_IMPSEN_DIG5 0x01d3 | ||
848 | #define RT5663_HP_IMPSEN_MAP1 0x01d4 | ||
849 | #define RT5663_HP_IMPSEN_MAP2 0x01d5 | ||
850 | #define RT5663_HP_IMPSEN_MAP3 0x01d6 | ||
851 | #define RT5663_HP_IMPSEN_MAP4 0x01d7 | ||
852 | #define RT5663_HP_IMPSEN_MAP5 0x01d8 | ||
853 | #define RT5663_HP_IMPSEN_MAP7 0x01d9 | ||
854 | #define RT5663_HP_LOGIC_1 0x01da | ||
855 | #define RT5663_HP_LOGIC_2 0x01db | ||
856 | #define RT5663_HP_CALIB_1 0x01dd | ||
857 | #define RT5663_HP_CALIB_1_1 0x01de | ||
858 | #define RT5663_HP_CALIB_2 0x01df | ||
859 | #define RT5663_HP_CALIB_3 0x01e0 | ||
860 | #define RT5663_HP_CALIB_4 0x01e1 | ||
861 | #define RT5663_HP_CALIB_5 0x01e2 | ||
862 | #define RT5663_HP_CALIB_5_1 0x01e3 | ||
863 | #define RT5663_HP_CALIB_6 0x01e4 | ||
864 | #define RT5663_HP_CALIB_7 0x01e5 | ||
865 | #define RT5663_HP_CALIB_9 0x01e6 | ||
866 | #define RT5663_HP_CALIB_10 0x01e7 | ||
867 | #define RT5663_HP_CALIB_11 0x01e8 | ||
868 | #define RT5663_HP_CALIB_ST1 0x01ea | ||
869 | #define RT5663_HP_CALIB_ST2 0x01eb | ||
870 | #define RT5663_HP_CALIB_ST3 0x01ec | ||
871 | #define RT5663_HP_CALIB_ST4 0x01ed | ||
872 | #define RT5663_HP_CALIB_ST5 0x01ee | ||
873 | #define RT5663_HP_CALIB_ST6 0x01ef | ||
874 | #define RT5663_HP_CALIB_ST7 0x01f0 | ||
875 | #define RT5663_HP_CALIB_ST8 0x01f1 | ||
876 | #define RT5663_HP_CALIB_ST9 0x01f2 | ||
877 | #define RT5663_HP_AMP_DET 0x0200 | ||
878 | #define RT5663_DUMMY_REG_6 0x0201 | ||
879 | #define RT5663_HP_BIAS 0x0202 | ||
880 | #define RT5663_CBJ_1 0x0250 | ||
881 | #define RT5663_CBJ_2 0x0251 | ||
882 | #define RT5663_CBJ_3 0x0252 | ||
883 | #define RT5663_DUMMY_1 0x02fa | ||
884 | #define RT5663_DUMMY_2 0x02fb | ||
885 | #define RT5663_DUMMY_3 0x02fc | ||
886 | #define RT5663_ANA_JD 0x0300 | ||
887 | #define RT5663_ADC_LCH_LPF1_A1 0x03d0 | ||
888 | #define RT5663_ADC_RCH_LPF1_A1 0x03d1 | ||
889 | #define RT5663_ADC_LCH_LPF1_H0 0x03d2 | ||
890 | #define RT5663_ADC_RCH_LPF1_H0 0x03d3 | ||
891 | #define RT5663_ADC_LCH_BPF1_A1 0x03d4 | ||
892 | #define RT5663_ADC_RCH_BPF1_A1 0x03d5 | ||
893 | #define RT5663_ADC_LCH_BPF1_A2 0x03d6 | ||
894 | #define RT5663_ADC_RCH_BPF1_A2 0x03d7 | ||
895 | #define RT5663_ADC_LCH_BPF1_H0 0x03d8 | ||
896 | #define RT5663_ADC_RCH_BPF1_H0 0x03d9 | ||
897 | #define RT5663_ADC_LCH_BPF2_A1 0x03da | ||
898 | #define RT5663_ADC_RCH_BPF2_A1 0x03db | ||
899 | #define RT5663_ADC_LCH_BPF2_A2 0x03dc | ||
900 | #define RT5663_ADC_RCH_BPF2_A2 0x03dd | ||
901 | #define RT5663_ADC_LCH_BPF2_H0 0x03de | ||
902 | #define RT5663_ADC_RCH_BPF2_H0 0x03df | ||
903 | #define RT5663_ADC_LCH_BPF3_A1 0x03e0 | ||
904 | #define RT5663_ADC_RCH_BPF3_A1 0x03e1 | ||
905 | #define RT5663_ADC_LCH_BPF3_A2 0x03e2 | ||
906 | #define RT5663_ADC_RCH_BPF3_A2 0x03e3 | ||
907 | #define RT5663_ADC_LCH_BPF3_H0 0x03e4 | ||
908 | #define RT5663_ADC_RCH_BPF3_H0 0x03e5 | ||
909 | #define RT5663_ADC_LCH_BPF4_A1 0x03e6 | ||
910 | #define RT5663_ADC_RCH_BPF4_A1 0x03e7 | ||
911 | #define RT5663_ADC_LCH_BPF4_A2 0x03e8 | ||
912 | #define RT5663_ADC_RCH_BPF4_A2 0x03e9 | ||
913 | #define RT5663_ADC_LCH_BPF4_H0 0x03ea | ||
914 | #define RT5663_ADC_RCH_BPF4_H0 0x03eb | ||
915 | #define RT5663_ADC_LCH_HPF1_A1 0x03ec | ||
916 | #define RT5663_ADC_RCH_HPF1_A1 0x03ed | ||
917 | #define RT5663_ADC_LCH_HPF1_H0 0x03ee | ||
918 | #define RT5663_ADC_RCH_HPF1_H0 0x03ef | ||
919 | #define RT5663_ADC_EQ_PRE_VOL_L 0x03f0 | ||
920 | #define RT5663_ADC_EQ_PRE_VOL_R 0x03f1 | ||
921 | #define RT5663_ADC_EQ_POST_VOL_L 0x03f2 | ||
922 | #define RT5663_ADC_EQ_POST_VOL_R 0x03f3 | ||
923 | |||
924 | /* RT5663: RECMIX Control (0x0010) */ | ||
925 | #define RT5663_RECMIX1_BST1_MASK (0x1) | ||
926 | #define RT5663_RECMIX1_BST1_SHIFT 0 | ||
927 | #define RT5663_RECMIX1_BST1_ON (0x0) | ||
928 | #define RT5663_RECMIX1_BST1_OFF (0x1) | ||
929 | |||
930 | /* RT5663: Bypass Stereo1 DAC Mixer Control (0x002d) */ | ||
931 | #define RT5663_DACL1_SRC_MASK (0x1 << 3) | ||
932 | #define RT5663_DACL1_SRC_SHIFT 3 | ||
933 | #define RT5663_DACR1_SRC_MASK (0x1 << 2) | ||
934 | #define RT5663_DACR1_SRC_SHIFT 2 | ||
935 | |||
936 | /* RT5663: TDM control 2 (0x0078) */ | ||
937 | #define RT5663_DATA_SWAP_ADCDAT1_MASK (0x3 << 14) | ||
938 | #define RT5663_DATA_SWAP_ADCDAT1_SHIFT 14 | ||
939 | #define RT5663_DATA_SWAP_ADCDAT1_LR (0x0 << 14) | ||
940 | #define RT5663_DATA_SWAP_ADCDAT1_RL (0x1 << 14) | ||
941 | #define RT5663_DATA_SWAP_ADCDAT1_LL (0x2 << 14) | ||
942 | #define RT5663_DATA_SWAP_ADCDAT1_RR (0x3 << 14) | ||
943 | |||
944 | /* RT5663: TDM control 5 (0x007b) */ | ||
945 | #define RT5663_TDM_LENGTN_MASK (0x3) | ||
946 | #define RT5663_TDM_LENGTN_SHIFT 0 | ||
947 | #define RT5663_TDM_LENGTN_16 (0x0) | ||
948 | #define RT5663_TDM_LENGTN_20 (0x1) | ||
949 | #define RT5663_TDM_LENGTN_24 (0x2) | ||
950 | #define RT5663_TDM_LENGTN_32 (0x3) | ||
951 | |||
952 | /* RT5663: Global Clock Control (0x0080) */ | ||
953 | #define RT5663_SCLK_SRC_MASK (0x3 << 14) | ||
954 | #define RT5663_SCLK_SRC_SHIFT 14 | ||
955 | #define RT5663_SCLK_SRC_MCLK (0x0 << 14) | ||
956 | #define RT5663_SCLK_SRC_PLL1 (0x1 << 14) | ||
957 | #define RT5663_SCLK_SRC_RCCLK (0x2 << 14) | ||
958 | #define RT5663_PLL1_SRC_MASK (0x7 << 11) | ||
959 | #define RT5663_PLL1_SRC_SHIFT 11 | ||
960 | #define RT5663_PLL1_SRC_MCLK (0x0 << 11) | ||
961 | #define RT5663_PLL1_SRC_BCLK1 (0x1 << 11) | ||
962 | |||
963 | /* PLL tracking mode 1 (0x0083) */ | ||
964 | #define RT5663_I2S1_ASRC_MASK (0x1 << 11) | ||
965 | #define RT5663_I2S1_ASRC_SHIFT 11 | ||
966 | #define RT5663_DAC_STO1_ASRC_MASK (0x1 << 10) | ||
967 | #define RT5663_DAC_STO1_ASRC_SHIFT 10 | ||
968 | #define RT5663_ADC_STO1_ASRC_MASK (0x1 << 3) | ||
969 | #define RT5663_ADC_STO1_ASRC_SHIFT 3 | ||
970 | |||
971 | /* PLL tracking mode 2 (0x0084)*/ | ||
972 | #define RT5663_DA_STO1_TRACK_MASK (0x7 << 12) | ||
973 | #define RT5663_DA_STO1_TRACK_SHIFT 12 | ||
974 | #define RT5663_DA_STO1_TRACK_SYSCLK (0x0 << 12) | ||
975 | #define RT5663_DA_STO1_TRACK_I2S1 (0x1 << 12) | ||
976 | #define RT5663_AD_STO1_TRACK_MASK (0x7) | ||
977 | #define RT5663_AD_STO1_TRACK_SHIFT 0 | ||
978 | #define RT5663_AD_STO1_TRACK_SYSCLK (0x0) | ||
979 | #define RT5663_AD_STO1_TRACK_I2S1 (0x1) | ||
980 | |||
981 | /* RT5663: HPOUT Charge pump control 1 (0x0091) */ | ||
982 | #define RT5663_SI_HP_MASK (0x1 << 12) | ||
983 | #define RT5663_SI_HP_SHIFT 12 | ||
984 | #define RT5663_SI_HP_EN (0x1 << 12) | ||
985 | #define RT5663_SI_HP_DIS (0x0 << 12) | ||
986 | |||
987 | /* RT5663: GPIO Control 2 (0x00b6) */ | ||
988 | #define RT5663_GP1_PIN_CONF_MASK (0x1 << 2) | ||
989 | #define RT5663_GP1_PIN_CONF_SHIFT 2 | ||
990 | #define RT5663_GP1_PIN_CONF_OUTPUT (0x1 << 2) | ||
991 | #define RT5663_GP1_PIN_CONF_INPUT (0x0 << 2) | ||
992 | |||
993 | /* RT5663: GPIO Control 2 (0x00b7) */ | ||
994 | #define RT5663_EN_IRQ_INLINE_MASK (0x1 << 3) | ||
995 | #define RT5663_EN_IRQ_INLINE_SHIFT 3 | ||
996 | #define RT5663_EN_IRQ_INLINE_NOR (0x1 << 3) | ||
997 | #define RT5663_EN_IRQ_INLINE_BYP (0x0 << 3) | ||
998 | |||
999 | /* RT5663: IRQ Control 1 (0x00c1) */ | ||
1000 | #define RT5663_EN_IRQ_JD1_MASK (0x1 << 6) | ||
1001 | #define RT5663_EN_IRQ_JD1_SHIFT 6 | ||
1002 | #define RT5663_EN_IRQ_JD1_EN (0x1 << 6) | ||
1003 | #define RT5663_EN_IRQ_JD1_DIS (0x0 << 6) | ||
1004 | |||
1005 | /* RT5663: Inline Command Function 2 (0x00dc) */ | ||
1006 | #define RT5663_PWR_MIC_DET_MASK (0x1) | ||
1007 | #define RT5663_PWR_MIC_DET_SHIFT 0 | ||
1008 | #define RT5663_PWR_MIC_DET_ON (0x1) | ||
1009 | #define RT5663_PWR_MIC_DET_OFF (0x0) | ||
1010 | |||
1011 | /* RT5663: Embeeded Jack and Type Detection Control 1 (0x00e6)*/ | ||
1012 | #define RT5663_CBJ_DET_MASK (0x1 << 15) | ||
1013 | #define RT5663_CBJ_DET_SHIFT 15 | ||
1014 | #define RT5663_CBJ_DET_DIS (0x0 << 15) | ||
1015 | #define RT5663_CBJ_DET_EN (0x1 << 15) | ||
1016 | #define RT5663_EXT_JD_MASK (0x1 << 11) | ||
1017 | #define RT5663_EXT_JD_SHIFT 11 | ||
1018 | #define RT5663_EXT_JD_EN (0x1 << 11) | ||
1019 | #define RT5663_EXT_JD_DIS (0x0 << 11) | ||
1020 | #define RT5663_POL_EXT_JD_MASK (0x1 << 10) | ||
1021 | #define RT5663_POL_EXT_JD_SHIFT 10 | ||
1022 | #define RT5663_POL_EXT_JD_EN (0x1 << 10) | ||
1023 | #define RT5663_POL_EXT_JD_DIS (0x0 << 10) | ||
1024 | |||
1025 | /* RT5663: DACREF LDO Control (0x0112)*/ | ||
1026 | #define RT5663_PWR_LDO_DACREFL_MASK (0x1 << 9) | ||
1027 | #define RT5663_PWR_LDO_DACREFL_SHIFT 9 | ||
1028 | #define RT5663_PWR_LDO_DACREFR_MASK (0x1 << 1) | ||
1029 | #define RT5663_PWR_LDO_DACREFR_SHIFT 1 | ||
1030 | |||
1031 | /* RT5663: Stereo Dynamic Range Enhancement Control 9 (0x0168, 0x0169)*/ | ||
1032 | #define RT5663_DRE_GAIN_HP_MASK (0x1f) | ||
1033 | #define RT5663_DRE_GAIN_HP_SHIFT 0 | ||
1034 | |||
1035 | /* RT5663: Combo Jack Control (0x0250) */ | ||
1036 | #define RT5663_INBUF_CBJ_BST1_MASK (0x1 << 11) | ||
1037 | #define RT5663_INBUF_CBJ_BST1_SHIFT 11 | ||
1038 | #define RT5663_INBUF_CBJ_BST1_ON (0x1 << 11) | ||
1039 | #define RT5663_INBUF_CBJ_BST1_OFF (0x0 << 11) | ||
1040 | #define RT5663_CBJ_SENSE_BST1_MASK (0x1 << 10) | ||
1041 | #define RT5663_CBJ_SENSE_BST1_SHIFT 10 | ||
1042 | #define RT5663_CBJ_SENSE_BST1_L (0x1 << 10) | ||
1043 | #define RT5663_CBJ_SENSE_BST1_R (0x0 << 10) | ||
1044 | |||
1045 | /* RT5663: Combo Jack Control (0x0251) */ | ||
1046 | #define RT5663_GAIN_BST1_MASK (0xf) | ||
1047 | #define RT5663_GAIN_BST1_SHIFT 0 | ||
1048 | |||
1049 | /* RT5663: Dummy register 1 (0x02fa) */ | ||
1050 | #define RT5663_EMB_CLK_MASK (0x1 << 9) | ||
1051 | #define RT5663_EMB_CLK_SHIFT 9 | ||
1052 | #define RT5663_EMB_CLK_EN (0x1 << 9) | ||
1053 | #define RT5663_EMB_CLK_DIS (0x0 << 9) | ||
1054 | #define RT5663_HPA_CPL_BIAS_MASK (0x7 << 6) | ||
1055 | #define RT5663_HPA_CPL_BIAS_SHIFT 6 | ||
1056 | #define RT5663_HPA_CPL_BIAS_0_5 (0x0 << 6) | ||
1057 | #define RT5663_HPA_CPL_BIAS_1 (0x1 << 6) | ||
1058 | #define RT5663_HPA_CPL_BIAS_2 (0x2 << 6) | ||
1059 | #define RT5663_HPA_CPL_BIAS_3 (0x3 << 6) | ||
1060 | #define RT5663_HPA_CPL_BIAS_4_1 (0x4 << 6) | ||
1061 | #define RT5663_HPA_CPL_BIAS_4_2 (0x5 << 6) | ||
1062 | #define RT5663_HPA_CPL_BIAS_6 (0x6 << 6) | ||
1063 | #define RT5663_HPA_CPL_BIAS_8 (0x7 << 6) | ||
1064 | #define RT5663_HPA_CPR_BIAS_MASK (0x7 << 3) | ||
1065 | #define RT5663_HPA_CPR_BIAS_SHIFT 3 | ||
1066 | #define RT5663_HPA_CPR_BIAS_0_5 (0x0 << 3) | ||
1067 | #define RT5663_HPA_CPR_BIAS_1 (0x1 << 3) | ||
1068 | #define RT5663_HPA_CPR_BIAS_2 (0x2 << 3) | ||
1069 | #define RT5663_HPA_CPR_BIAS_3 (0x3 << 3) | ||
1070 | #define RT5663_HPA_CPR_BIAS_4_1 (0x4 << 3) | ||
1071 | #define RT5663_HPA_CPR_BIAS_4_2 (0x5 << 3) | ||
1072 | #define RT5663_HPA_CPR_BIAS_6 (0x6 << 3) | ||
1073 | #define RT5663_HPA_CPR_BIAS_8 (0x7 << 3) | ||
1074 | #define RT5663_DUMMY_BIAS_MASK (0x7) | ||
1075 | #define RT5663_DUMMY_BIAS_SHIFT 0 | ||
1076 | #define RT5663_DUMMY_BIAS_0_5 (0x0) | ||
1077 | #define RT5663_DUMMY_BIAS_1 (0x1) | ||
1078 | #define RT5663_DUMMY_BIAS_2 (0x2) | ||
1079 | #define RT5663_DUMMY_BIAS_3 (0x3) | ||
1080 | #define RT5663_DUMMY_BIAS_4_1 (0x4) | ||
1081 | #define RT5663_DUMMY_BIAS_4_2 (0x5) | ||
1082 | #define RT5663_DUMMY_BIAS_6 (0x6) | ||
1083 | #define RT5663_DUMMY_BIAS_8 (0x7) | ||
1084 | |||
1085 | |||
1086 | /* System Clock Source */ | ||
1087 | enum { | ||
1088 | RT5663_SCLK_S_MCLK, | ||
1089 | RT5663_SCLK_S_PLL1, | ||
1090 | RT5663_SCLK_S_RCCLK, | ||
1091 | }; | ||
1092 | |||
1093 | /* PLL1 Source */ | ||
1094 | enum { | ||
1095 | RT5663_PLL1_S_MCLK, | ||
1096 | RT5663_PLL1_S_BCLK1, | ||
1097 | }; | ||
1098 | |||
1099 | enum { | ||
1100 | RT5663_AIF, | ||
1101 | RT5663_AIFS, | ||
1102 | }; | ||
1103 | |||
1104 | /* asrc clock source */ | ||
1105 | enum { | ||
1106 | RT5663_CLK_SEL_SYS = 0x0, | ||
1107 | RT5663_CLK_SEL_I2S1_ASRC = 0x1, | ||
1108 | }; | ||
1109 | |||
1110 | /* filter mask */ | ||
1111 | enum { | ||
1112 | RT5663_DA_STEREO_FILTER = 0x1, | ||
1113 | RT5663_AD_STEREO_FILTER = 0x2, | ||
1114 | }; | ||
1115 | |||
1116 | int rt5663_set_jack_detect(struct snd_soc_codec *codec, | ||
1117 | struct snd_soc_jack *hs_jack); | ||
1118 | int rt5663_sel_asrc_clk_src(struct snd_soc_codec *codec, | ||
1119 | unsigned int filter_mask, unsigned int clk_src); | ||
1120 | |||
1121 | #endif /* __RT5663_H__ */ | ||
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 8ef467f64f03..49caf1393aeb 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c | |||
@@ -2777,12 +2777,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5670 = { | |||
2777 | .resume = rt5670_resume, | 2777 | .resume = rt5670_resume, |
2778 | .set_bias_level = rt5670_set_bias_level, | 2778 | .set_bias_level = rt5670_set_bias_level, |
2779 | .idle_bias_off = true, | 2779 | .idle_bias_off = true, |
2780 | .controls = rt5670_snd_controls, | 2780 | .component_driver = { |
2781 | .num_controls = ARRAY_SIZE(rt5670_snd_controls), | 2781 | .controls = rt5670_snd_controls, |
2782 | .dapm_widgets = rt5670_dapm_widgets, | 2782 | .num_controls = ARRAY_SIZE(rt5670_snd_controls), |
2783 | .num_dapm_widgets = ARRAY_SIZE(rt5670_dapm_widgets), | 2783 | .dapm_widgets = rt5670_dapm_widgets, |
2784 | .dapm_routes = rt5670_dapm_routes, | 2784 | .num_dapm_widgets = ARRAY_SIZE(rt5670_dapm_widgets), |
2785 | .num_dapm_routes = ARRAY_SIZE(rt5670_dapm_routes), | 2785 | .dapm_routes = rt5670_dapm_routes, |
2786 | .num_dapm_routes = ARRAY_SIZE(rt5670_dapm_routes), | ||
2787 | }, | ||
2786 | }; | 2788 | }; |
2787 | 2789 | ||
2788 | static const struct regmap_config rt5670_regmap = { | 2790 | static const struct regmap_config rt5670_regmap = { |
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index da9483c1c6fb..abc802a5a479 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/acpi.h> | ||
12 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
14 | #include <linux/moduleparam.h> | 15 | #include <linux/moduleparam.h> |
@@ -40,6 +41,15 @@ | |||
40 | 41 | ||
41 | #define RT5677_PR_BASE (RT5677_PR_RANGE_BASE + (0 * RT5677_PR_SPACING)) | 42 | #define RT5677_PR_BASE (RT5677_PR_RANGE_BASE + (0 * RT5677_PR_SPACING)) |
42 | 43 | ||
44 | /* GPIO indexes defined by ACPI */ | ||
45 | enum { | ||
46 | RT5677_GPIO_PLUG_DET = 0, | ||
47 | RT5677_GPIO_MIC_PRESENT_L = 1, | ||
48 | RT5677_GPIO_HOTWORD_DET_L = 2, | ||
49 | RT5677_GPIO_DSP_INT = 3, | ||
50 | RT5677_GPIO_HP_AMP_SHDN_L = 4, | ||
51 | }; | ||
52 | |||
43 | static const struct regmap_range_cfg rt5677_ranges[] = { | 53 | static const struct regmap_range_cfg rt5677_ranges[] = { |
44 | { | 54 | { |
45 | .name = "PR", | 55 | .name = "PR", |
@@ -4657,7 +4667,7 @@ static int rt5677_to_irq(struct gpio_chip *chip, unsigned offset) | |||
4657 | return regmap_irq_get_virq(data, irq); | 4667 | return regmap_irq_get_virq(data, irq); |
4658 | } | 4668 | } |
4659 | 4669 | ||
4660 | static struct gpio_chip rt5677_template_chip = { | 4670 | static const struct gpio_chip rt5677_template_chip = { |
4661 | .label = "rt5677", | 4671 | .label = "rt5677", |
4662 | .owner = THIS_MODULE, | 4672 | .owner = THIS_MODULE, |
4663 | .direction_output = rt5677_gpio_direction_out, | 4673 | .direction_output = rt5677_gpio_direction_out, |
@@ -4974,12 +4984,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5677 = { | |||
4974 | .resume = rt5677_resume, | 4984 | .resume = rt5677_resume, |
4975 | .set_bias_level = rt5677_set_bias_level, | 4985 | .set_bias_level = rt5677_set_bias_level, |
4976 | .idle_bias_off = true, | 4986 | .idle_bias_off = true, |
4977 | .controls = rt5677_snd_controls, | 4987 | .component_driver = { |
4978 | .num_controls = ARRAY_SIZE(rt5677_snd_controls), | 4988 | .controls = rt5677_snd_controls, |
4979 | .dapm_widgets = rt5677_dapm_widgets, | 4989 | .num_controls = ARRAY_SIZE(rt5677_snd_controls), |
4980 | .num_dapm_widgets = ARRAY_SIZE(rt5677_dapm_widgets), | 4990 | .dapm_widgets = rt5677_dapm_widgets, |
4981 | .dapm_routes = rt5677_dapm_routes, | 4991 | .num_dapm_widgets = ARRAY_SIZE(rt5677_dapm_widgets), |
4982 | .num_dapm_routes = ARRAY_SIZE(rt5677_dapm_routes), | 4992 | .dapm_routes = rt5677_dapm_routes, |
4993 | .num_dapm_routes = ARRAY_SIZE(rt5677_dapm_routes), | ||
4994 | }, | ||
4983 | }; | 4995 | }; |
4984 | 4996 | ||
4985 | static const struct regmap_config rt5677_regmap_physical = { | 4997 | static const struct regmap_config rt5677_regmap_physical = { |
@@ -5018,10 +5030,47 @@ static const struct regmap_config rt5677_regmap = { | |||
5018 | static const struct i2c_device_id rt5677_i2c_id[] = { | 5030 | static const struct i2c_device_id rt5677_i2c_id[] = { |
5019 | { "rt5677", RT5677 }, | 5031 | { "rt5677", RT5677 }, |
5020 | { "rt5676", RT5676 }, | 5032 | { "rt5676", RT5676 }, |
5033 | { "RT5677CE:00", RT5677 }, | ||
5021 | { } | 5034 | { } |
5022 | }; | 5035 | }; |
5023 | MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); | 5036 | MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); |
5024 | 5037 | ||
5038 | static const struct acpi_gpio_params plug_det_gpio = { RT5677_GPIO_PLUG_DET, 0, false }; | ||
5039 | static const struct acpi_gpio_params mic_present_gpio = { RT5677_GPIO_MIC_PRESENT_L, 0, false }; | ||
5040 | static const struct acpi_gpio_params headphone_enable_gpio = { RT5677_GPIO_HP_AMP_SHDN_L, 0, false }; | ||
5041 | |||
5042 | static const struct acpi_gpio_mapping bdw_rt5677_gpios[] = { | ||
5043 | { "plug-det-gpios", &plug_det_gpio, 1 }, | ||
5044 | { "mic-present-gpios", &mic_present_gpio, 1 }, | ||
5045 | { "headphone-enable-gpios", &headphone_enable_gpio, 1 }, | ||
5046 | { NULL }, | ||
5047 | }; | ||
5048 | |||
5049 | static void rt5677_read_acpi_properties(struct rt5677_priv *rt5677, | ||
5050 | struct device *dev) | ||
5051 | { | ||
5052 | int ret; | ||
5053 | u32 val; | ||
5054 | |||
5055 | ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), | ||
5056 | bdw_rt5677_gpios); | ||
5057 | if (ret) | ||
5058 | dev_warn(dev, "Failed to add driver gpios\n"); | ||
5059 | |||
5060 | if (!device_property_read_u32(dev, "DCLK", &val)) | ||
5061 | rt5677->pdata.dmic2_clk_pin = val; | ||
5062 | |||
5063 | rt5677->pdata.in1_diff = device_property_read_bool(dev, "IN1"); | ||
5064 | rt5677->pdata.in2_diff = device_property_read_bool(dev, "IN2"); | ||
5065 | rt5677->pdata.lout1_diff = device_property_read_bool(dev, "OUT1"); | ||
5066 | rt5677->pdata.lout2_diff = device_property_read_bool(dev, "OUT2"); | ||
5067 | rt5677->pdata.lout3_diff = device_property_read_bool(dev, "OUT3"); | ||
5068 | |||
5069 | device_property_read_u32(dev, "JD1", &rt5677->pdata.jd1_gpio); | ||
5070 | device_property_read_u32(dev, "JD2", &rt5677->pdata.jd2_gpio); | ||
5071 | device_property_read_u32(dev, "JD3", &rt5677->pdata.jd3_gpio); | ||
5072 | } | ||
5073 | |||
5025 | static void rt5677_read_device_properties(struct rt5677_priv *rt5677, | 5074 | static void rt5677_read_device_properties(struct rt5677_priv *rt5677, |
5026 | struct device *dev) | 5075 | struct device *dev) |
5027 | { | 5076 | { |
@@ -5127,8 +5176,12 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, | |||
5127 | 5176 | ||
5128 | if (pdata) | 5177 | if (pdata) |
5129 | rt5677->pdata = *pdata; | 5178 | rt5677->pdata = *pdata; |
5130 | else | 5179 | else if (i2c->dev.of_node) |
5131 | rt5677_read_device_properties(rt5677, &i2c->dev); | 5180 | rt5677_read_device_properties(rt5677, &i2c->dev); |
5181 | else if (ACPI_HANDLE(&i2c->dev)) | ||
5182 | rt5677_read_acpi_properties(rt5677, &i2c->dev); | ||
5183 | else | ||
5184 | return -EINVAL; | ||
5132 | 5185 | ||
5133 | /* pow-ldo2 and reset are optional. The codec pins may be statically | 5186 | /* pow-ldo2 and reset are optional. The codec pins may be statically |
5134 | * connected on the board without gpios. If the gpio device property | 5187 | * connected on the board without gpios. If the gpio device property |
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 527b759c1562..1589325855bc 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c | |||
@@ -411,6 +411,8 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = { | |||
411 | 0, 8, | 411 | 0, 8, |
412 | 0x7f, 1, | 412 | 0x7f, 1, |
413 | headphone_volume), | 413 | headphone_volume), |
414 | SOC_SINGLE("Headphone Playback Switch", SGTL5000_CHIP_ANA_CTRL, | ||
415 | 4, 1, 1), | ||
414 | SOC_SINGLE("Headphone Playback ZC Switch", SGTL5000_CHIP_ANA_CTRL, | 416 | SOC_SINGLE("Headphone Playback ZC Switch", SGTL5000_CHIP_ANA_CTRL, |
415 | 5, 1, 0), | 417 | 5, 1, 0), |
416 | 418 | ||
@@ -423,6 +425,7 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = { | |||
423 | SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT, | 425 | SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT, |
424 | 0x1f, 1, | 426 | 0x1f, 1, |
425 | lineout_volume), | 427 | lineout_volume), |
428 | SOC_SINGLE("Lineout Playback Switch", SGTL5000_CHIP_ANA_CTRL, 8, 1, 1), | ||
426 | }; | 429 | }; |
427 | 430 | ||
428 | /* mute the codec used by alsa core */ | 431 | /* mute the codec used by alsa core */ |
@@ -1151,12 +1154,14 @@ static struct snd_soc_codec_driver sgtl5000_driver = { | |||
1151 | .remove = sgtl5000_remove, | 1154 | .remove = sgtl5000_remove, |
1152 | .set_bias_level = sgtl5000_set_bias_level, | 1155 | .set_bias_level = sgtl5000_set_bias_level, |
1153 | .suspend_bias_off = true, | 1156 | .suspend_bias_off = true, |
1154 | .controls = sgtl5000_snd_controls, | 1157 | .component_driver = { |
1155 | .num_controls = ARRAY_SIZE(sgtl5000_snd_controls), | 1158 | .controls = sgtl5000_snd_controls, |
1156 | .dapm_widgets = sgtl5000_dapm_widgets, | 1159 | .num_controls = ARRAY_SIZE(sgtl5000_snd_controls), |
1157 | .num_dapm_widgets = ARRAY_SIZE(sgtl5000_dapm_widgets), | 1160 | .dapm_widgets = sgtl5000_dapm_widgets, |
1158 | .dapm_routes = sgtl5000_dapm_routes, | 1161 | .num_dapm_widgets = ARRAY_SIZE(sgtl5000_dapm_widgets), |
1159 | .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes), | 1162 | .dapm_routes = sgtl5000_dapm_routes, |
1163 | .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes), | ||
1164 | }, | ||
1160 | }; | 1165 | }; |
1161 | 1166 | ||
1162 | static const struct regmap_config sgtl5000_regmap = { | 1167 | static const struct regmap_config sgtl5000_regmap = { |
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index a8402d0af0ea..5344f4aa8fde 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c | |||
@@ -238,10 +238,12 @@ static struct regmap *si476x_get_regmap(struct device *dev) | |||
238 | 238 | ||
239 | static struct snd_soc_codec_driver soc_codec_dev_si476x = { | 239 | static struct snd_soc_codec_driver soc_codec_dev_si476x = { |
240 | .get_regmap = si476x_get_regmap, | 240 | .get_regmap = si476x_get_regmap, |
241 | .dapm_widgets = si476x_dapm_widgets, | 241 | .component_driver = { |
242 | .num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets), | 242 | .dapm_widgets = si476x_dapm_widgets, |
243 | .dapm_routes = si476x_dapm_routes, | 243 | .num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets), |
244 | .num_dapm_routes = ARRAY_SIZE(si476x_dapm_routes), | 244 | .dapm_routes = si476x_dapm_routes, |
245 | .num_dapm_routes = ARRAY_SIZE(si476x_dapm_routes), | ||
246 | }, | ||
245 | }; | 247 | }; |
246 | 248 | ||
247 | static int si476x_platform_probe(struct platform_device *pdev) | 249 | static int si476x_platform_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index 3a7de0159f24..eae54c37cff9 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c | |||
@@ -888,12 +888,14 @@ static struct snd_soc_codec_driver sn95031_codec = { | |||
888 | .set_bias_level = sn95031_set_vaud_bias, | 888 | .set_bias_level = sn95031_set_vaud_bias, |
889 | .idle_bias_off = true, | 889 | .idle_bias_off = true, |
890 | 890 | ||
891 | .controls = sn95031_snd_controls, | 891 | .component_driver = { |
892 | .num_controls = ARRAY_SIZE(sn95031_snd_controls), | 892 | .controls = sn95031_snd_controls, |
893 | .dapm_widgets = sn95031_dapm_widgets, | 893 | .num_controls = ARRAY_SIZE(sn95031_snd_controls), |
894 | .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets), | 894 | .dapm_widgets = sn95031_dapm_widgets, |
895 | .dapm_routes = sn95031_audio_map, | 895 | .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets), |
896 | .num_dapm_routes = ARRAY_SIZE(sn95031_audio_map), | 896 | .dapm_routes = sn95031_audio_map, |
897 | .num_dapm_routes = ARRAY_SIZE(sn95031_audio_map), | ||
898 | }, | ||
897 | }; | 899 | }; |
898 | 900 | ||
899 | static int sn95031_device_probe(struct platform_device *pdev) | 901 | static int sn95031_device_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/spdif_receiver.c b/sound/soc/codecs/spdif_receiver.c index 3ec41ccbf4e2..234f87b54838 100644 --- a/sound/soc/codecs/spdif_receiver.c +++ b/sound/soc/codecs/spdif_receiver.c | |||
@@ -38,10 +38,12 @@ static const struct snd_soc_dapm_route dir_routes[] = { | |||
38 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) | 38 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) |
39 | 39 | ||
40 | static struct snd_soc_codec_driver soc_codec_spdif_dir = { | 40 | static struct snd_soc_codec_driver soc_codec_spdif_dir = { |
41 | .dapm_widgets = dir_widgets, | 41 | .component_driver = { |
42 | .num_dapm_widgets = ARRAY_SIZE(dir_widgets), | 42 | .dapm_widgets = dir_widgets, |
43 | .dapm_routes = dir_routes, | 43 | .num_dapm_widgets = ARRAY_SIZE(dir_widgets), |
44 | .num_dapm_routes = ARRAY_SIZE(dir_routes), | 44 | .dapm_routes = dir_routes, |
45 | .num_dapm_routes = ARRAY_SIZE(dir_routes), | ||
46 | }, | ||
45 | }; | 47 | }; |
46 | 48 | ||
47 | static struct snd_soc_dai_driver dir_stub_dai = { | 49 | static struct snd_soc_dai_driver dir_stub_dai = { |
diff --git a/sound/soc/codecs/spdif_transmitter.c b/sound/soc/codecs/spdif_transmitter.c index ef634a9ad673..ee367536a498 100644 --- a/sound/soc/codecs/spdif_transmitter.c +++ b/sound/soc/codecs/spdif_transmitter.c | |||
@@ -38,10 +38,12 @@ static const struct snd_soc_dapm_route dit_routes[] = { | |||
38 | }; | 38 | }; |
39 | 39 | ||
40 | static struct snd_soc_codec_driver soc_codec_spdif_dit = { | 40 | static struct snd_soc_codec_driver soc_codec_spdif_dit = { |
41 | .dapm_widgets = dit_widgets, | 41 | .component_driver = { |
42 | .num_dapm_widgets = ARRAY_SIZE(dit_widgets), | 42 | .dapm_widgets = dit_widgets, |
43 | .dapm_routes = dit_routes, | 43 | .num_dapm_widgets = ARRAY_SIZE(dit_widgets), |
44 | .num_dapm_routes = ARRAY_SIZE(dit_routes), | 44 | .dapm_routes = dit_routes, |
45 | .num_dapm_routes = ARRAY_SIZE(dit_routes), | ||
46 | }, | ||
45 | }; | 47 | }; |
46 | 48 | ||
47 | static struct snd_soc_dai_driver dit_stub_dai = { | 49 | static struct snd_soc_dai_driver dit_stub_dai = { |
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c index e2e0bfa7ec20..38a85f3adc80 100644 --- a/sound/soc/codecs/ssm2518.c +++ b/sound/soc/codecs/ssm2518.c | |||
@@ -715,12 +715,14 @@ static struct snd_soc_codec_driver ssm2518_codec_driver = { | |||
715 | .set_sysclk = ssm2518_set_sysclk, | 715 | .set_sysclk = ssm2518_set_sysclk, |
716 | .idle_bias_off = true, | 716 | .idle_bias_off = true, |
717 | 717 | ||
718 | .controls = ssm2518_snd_controls, | 718 | .component_driver = { |
719 | .num_controls = ARRAY_SIZE(ssm2518_snd_controls), | 719 | .controls = ssm2518_snd_controls, |
720 | .dapm_widgets = ssm2518_dapm_widgets, | 720 | .num_controls = ARRAY_SIZE(ssm2518_snd_controls), |
721 | .num_dapm_widgets = ARRAY_SIZE(ssm2518_dapm_widgets), | 721 | .dapm_widgets = ssm2518_dapm_widgets, |
722 | .dapm_routes = ssm2518_routes, | 722 | .num_dapm_widgets = ARRAY_SIZE(ssm2518_dapm_widgets), |
723 | .num_dapm_routes = ARRAY_SIZE(ssm2518_routes), | 723 | .dapm_routes = ssm2518_routes, |
724 | .num_dapm_routes = ARRAY_SIZE(ssm2518_routes), | ||
725 | }, | ||
724 | }; | 726 | }; |
725 | 727 | ||
726 | static const struct regmap_config ssm2518_regmap_config = { | 728 | static const struct regmap_config ssm2518_regmap_config = { |
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 4452fea0b118..993bde29ca1b 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c | |||
@@ -597,12 +597,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { | |||
597 | .set_bias_level = ssm2602_set_bias_level, | 597 | .set_bias_level = ssm2602_set_bias_level, |
598 | .suspend_bias_off = true, | 598 | .suspend_bias_off = true, |
599 | 599 | ||
600 | .controls = ssm260x_snd_controls, | 600 | .component_driver = { |
601 | .num_controls = ARRAY_SIZE(ssm260x_snd_controls), | 601 | .controls = ssm260x_snd_controls, |
602 | .dapm_widgets = ssm260x_dapm_widgets, | 602 | .num_controls = ARRAY_SIZE(ssm260x_snd_controls), |
603 | .num_dapm_widgets = ARRAY_SIZE(ssm260x_dapm_widgets), | 603 | .dapm_widgets = ssm260x_dapm_widgets, |
604 | .dapm_routes = ssm260x_routes, | 604 | .num_dapm_widgets = ARRAY_SIZE(ssm260x_dapm_widgets), |
605 | .num_dapm_routes = ARRAY_SIZE(ssm260x_routes), | 605 | .dapm_routes = ssm260x_routes, |
606 | .num_dapm_routes = ARRAY_SIZE(ssm260x_routes), | ||
607 | }, | ||
606 | }; | 608 | }; |
607 | 609 | ||
608 | static bool ssm2602_register_volatile(struct device *dev, unsigned int reg) | 610 | static bool ssm2602_register_volatile(struct device *dev, unsigned int reg) |
diff --git a/sound/soc/codecs/ssm4567.c b/sound/soc/codecs/ssm4567.c index 080c78e88e10..2bb5a11c9ba1 100644 --- a/sound/soc/codecs/ssm4567.c +++ b/sound/soc/codecs/ssm4567.c | |||
@@ -421,12 +421,14 @@ static struct snd_soc_codec_driver ssm4567_codec_driver = { | |||
421 | .set_bias_level = ssm4567_set_bias_level, | 421 | .set_bias_level = ssm4567_set_bias_level, |
422 | .idle_bias_off = true, | 422 | .idle_bias_off = true, |
423 | 423 | ||
424 | .controls = ssm4567_snd_controls, | 424 | .component_driver = { |
425 | .num_controls = ARRAY_SIZE(ssm4567_snd_controls), | 425 | .controls = ssm4567_snd_controls, |
426 | .dapm_widgets = ssm4567_dapm_widgets, | 426 | .num_controls = ARRAY_SIZE(ssm4567_snd_controls), |
427 | .num_dapm_widgets = ARRAY_SIZE(ssm4567_dapm_widgets), | 427 | .dapm_widgets = ssm4567_dapm_widgets, |
428 | .dapm_routes = ssm4567_routes, | 428 | .num_dapm_widgets = ARRAY_SIZE(ssm4567_dapm_widgets), |
429 | .num_dapm_routes = ARRAY_SIZE(ssm4567_routes), | 429 | .dapm_routes = ssm4567_routes, |
430 | .num_dapm_routes = ARRAY_SIZE(ssm4567_routes), | ||
431 | }, | ||
430 | }; | 432 | }; |
431 | 433 | ||
432 | static const struct regmap_config ssm4567_regmap_config = { | 434 | static const struct regmap_config ssm4567_regmap_config = { |
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index a9844b2ac829..0790ae8530d9 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c | |||
@@ -991,12 +991,14 @@ static const struct snd_soc_codec_driver sta32x_codec = { | |||
991 | .remove = sta32x_remove, | 991 | .remove = sta32x_remove, |
992 | .set_bias_level = sta32x_set_bias_level, | 992 | .set_bias_level = sta32x_set_bias_level, |
993 | .suspend_bias_off = true, | 993 | .suspend_bias_off = true, |
994 | .controls = sta32x_snd_controls, | 994 | .component_driver = { |
995 | .num_controls = ARRAY_SIZE(sta32x_snd_controls), | 995 | .controls = sta32x_snd_controls, |
996 | .dapm_widgets = sta32x_dapm_widgets, | 996 | .num_controls = ARRAY_SIZE(sta32x_snd_controls), |
997 | .num_dapm_widgets = ARRAY_SIZE(sta32x_dapm_widgets), | 997 | .dapm_widgets = sta32x_dapm_widgets, |
998 | .dapm_routes = sta32x_dapm_routes, | 998 | .num_dapm_widgets = ARRAY_SIZE(sta32x_dapm_widgets), |
999 | .num_dapm_routes = ARRAY_SIZE(sta32x_dapm_routes), | 999 | .dapm_routes = sta32x_dapm_routes, |
1000 | .num_dapm_routes = ARRAY_SIZE(sta32x_dapm_routes), | ||
1001 | }, | ||
1000 | }; | 1002 | }; |
1001 | 1003 | ||
1002 | static const struct regmap_config sta32x_regmap = { | 1004 | static const struct regmap_config sta32x_regmap = { |
diff --git a/sound/soc/codecs/sta350.c b/sound/soc/codecs/sta350.c index 33a4612f0a07..9644c20f44e3 100644 --- a/sound/soc/codecs/sta350.c +++ b/sound/soc/codecs/sta350.c | |||
@@ -1057,12 +1057,14 @@ static const struct snd_soc_codec_driver sta350_codec = { | |||
1057 | .remove = sta350_remove, | 1057 | .remove = sta350_remove, |
1058 | .set_bias_level = sta350_set_bias_level, | 1058 | .set_bias_level = sta350_set_bias_level, |
1059 | .suspend_bias_off = true, | 1059 | .suspend_bias_off = true, |
1060 | .controls = sta350_snd_controls, | 1060 | .component_driver = { |
1061 | .num_controls = ARRAY_SIZE(sta350_snd_controls), | 1061 | .controls = sta350_snd_controls, |
1062 | .dapm_widgets = sta350_dapm_widgets, | 1062 | .num_controls = ARRAY_SIZE(sta350_snd_controls), |
1063 | .num_dapm_widgets = ARRAY_SIZE(sta350_dapm_widgets), | 1063 | .dapm_widgets = sta350_dapm_widgets, |
1064 | .dapm_routes = sta350_dapm_routes, | 1064 | .num_dapm_widgets = ARRAY_SIZE(sta350_dapm_widgets), |
1065 | .num_dapm_routes = ARRAY_SIZE(sta350_dapm_routes), | 1065 | .dapm_routes = sta350_dapm_routes, |
1066 | .num_dapm_routes = ARRAY_SIZE(sta350_dapm_routes), | ||
1067 | }, | ||
1066 | }; | 1068 | }; |
1067 | 1069 | ||
1068 | static const struct regmap_config sta350_regmap = { | 1070 | static const struct regmap_config sta350_regmap = { |
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c index 2cdaca943a8c..d4b384e4b266 100644 --- a/sound/soc/codecs/sta529.c +++ b/sound/soc/codecs/sta529.c | |||
@@ -317,8 +317,10 @@ static const struct snd_soc_codec_driver sta529_codec_driver = { | |||
317 | .set_bias_level = sta529_set_bias_level, | 317 | .set_bias_level = sta529_set_bias_level, |
318 | .suspend_bias_off = true, | 318 | .suspend_bias_off = true, |
319 | 319 | ||
320 | .controls = sta529_snd_controls, | 320 | .component_driver = { |
321 | .num_controls = ARRAY_SIZE(sta529_snd_controls), | 321 | .controls = sta529_snd_controls, |
322 | .num_controls = ARRAY_SIZE(sta529_snd_controls), | ||
323 | }, | ||
322 | }; | 324 | }; |
323 | 325 | ||
324 | static const struct regmap_config sta529_regmap = { | 326 | static const struct regmap_config sta529_regmap = { |
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 0945c51df003..27f30d352867 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c | |||
@@ -85,10 +85,10 @@ static SOC_ENUM_SINGLE_DECL(stac9766_boost2_enum, | |||
85 | static SOC_ENUM_SINGLE_DECL(stac9766_stereo_mic_enum, | 85 | static SOC_ENUM_SINGLE_DECL(stac9766_stereo_mic_enum, |
86 | AC97_STAC_STEREO_MIC, 2, stac9766_stereo_mic); | 86 | AC97_STAC_STEREO_MIC, 2, stac9766_stereo_mic); |
87 | 87 | ||
88 | static const DECLARE_TLV_DB_LINEAR(master_tlv, -4600, 0); | 88 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(master_tlv, -4650, 150, 0); |
89 | static const DECLARE_TLV_DB_LINEAR(record_tlv, 0, 2250); | 89 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(record_tlv, 0, 150, 0); |
90 | static const DECLARE_TLV_DB_LINEAR(beep_tlv, -4500, 0); | 90 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(beep_tlv, -4500, 300, 0); |
91 | static const DECLARE_TLV_DB_LINEAR(mix_tlv, -3450, 1200); | 91 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(mix_tlv, -3450, 150, 0); |
92 | 92 | ||
93 | static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = { | 93 | static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = { |
94 | SOC_DOUBLE_TLV("Speaker Volume", AC97_MASTER, 8, 0, 31, 1, master_tlv), | 94 | SOC_DOUBLE_TLV("Speaker Volume", AC97_MASTER, 8, 0, 31, 1, master_tlv), |
@@ -320,8 +320,10 @@ static int stac9766_codec_remove(struct snd_soc_codec *codec) | |||
320 | } | 320 | } |
321 | 321 | ||
322 | static struct snd_soc_codec_driver soc_codec_dev_stac9766 = { | 322 | static struct snd_soc_codec_driver soc_codec_dev_stac9766 = { |
323 | .controls = stac9766_snd_ac97_controls, | 323 | .component_driver = { |
324 | .num_controls = ARRAY_SIZE(stac9766_snd_ac97_controls), | 324 | .controls = stac9766_snd_ac97_controls, |
325 | .num_controls = ARRAY_SIZE(stac9766_snd_ac97_controls), | ||
326 | }, | ||
325 | .write = stac9766_ac97_write, | 327 | .write = stac9766_ac97_write, |
326 | .read = stac9766_ac97_read, | 328 | .read = stac9766_ac97_read, |
327 | .set_bias_level = stac9766_set_bias_level, | 329 | .set_bias_level = stac9766_set_bias_level, |
diff --git a/sound/soc/codecs/sti-sas.c b/sound/soc/codecs/sti-sas.c index 160d61a66204..7b31ee9b82bc 100644 --- a/sound/soc/codecs/sti-sas.c +++ b/sound/soc/codecs/sti-sas.c | |||
@@ -591,11 +591,11 @@ static int sti_sas_driver_probe(struct platform_device *pdev) | |||
591 | sti_sas_dai[STI_SAS_DAI_ANALOG_OUT].ops = drvdata->dev_data->dac_ops; | 591 | sti_sas_dai[STI_SAS_DAI_ANALOG_OUT].ops = drvdata->dev_data->dac_ops; |
592 | 592 | ||
593 | /* Set dapms*/ | 593 | /* Set dapms*/ |
594 | sti_sas_driver.dapm_widgets = drvdata->dev_data->dapm_widgets; | 594 | sti_sas_driver.component_driver.dapm_widgets = drvdata->dev_data->dapm_widgets; |
595 | sti_sas_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets; | 595 | sti_sas_driver.component_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets; |
596 | 596 | ||
597 | sti_sas_driver.dapm_routes = drvdata->dev_data->dapm_routes; | 597 | sti_sas_driver.component_driver.dapm_routes = drvdata->dev_data->dapm_routes; |
598 | sti_sas_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes; | 598 | sti_sas_driver.component_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes; |
599 | 599 | ||
600 | /* Store context */ | 600 | /* Store context */ |
601 | dev_set_drvdata(&pdev->dev, drvdata); | 601 | dev_set_drvdata(&pdev->dev, drvdata); |
diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c index cc1d3981fa4b..baf455e8c2f7 100644 --- a/sound/soc/codecs/tas2552.c +++ b/sound/soc/codecs/tas2552.c | |||
@@ -667,12 +667,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tas2552 = { | |||
667 | .resume = tas2552_resume, | 667 | .resume = tas2552_resume, |
668 | .ignore_pmdown_time = true, | 668 | .ignore_pmdown_time = true, |
669 | 669 | ||
670 | .controls = tas2552_snd_controls, | 670 | .component_driver = { |
671 | .num_controls = ARRAY_SIZE(tas2552_snd_controls), | 671 | .controls = tas2552_snd_controls, |
672 | .dapm_widgets = tas2552_dapm_widgets, | 672 | .num_controls = ARRAY_SIZE(tas2552_snd_controls), |
673 | .num_dapm_widgets = ARRAY_SIZE(tas2552_dapm_widgets), | 673 | .dapm_widgets = tas2552_dapm_widgets, |
674 | .dapm_routes = tas2552_audio_map, | 674 | .num_dapm_widgets = ARRAY_SIZE(tas2552_dapm_widgets), |
675 | .num_dapm_routes = ARRAY_SIZE(tas2552_audio_map), | 675 | .dapm_routes = tas2552_audio_map, |
676 | .num_dapm_routes = ARRAY_SIZE(tas2552_audio_map), | ||
677 | }, | ||
676 | }; | 678 | }; |
677 | 679 | ||
678 | static const struct regmap_config tas2552_regmap_config = { | 680 | static const struct regmap_config tas2552_regmap_config = { |
diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index d49d25d51957..b7de857abb16 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c | |||
@@ -387,7 +387,7 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream, | |||
387 | val = index_in_array(tas5086_ratios, ARRAY_SIZE(tas5086_ratios), | 387 | val = index_in_array(tas5086_ratios, ARRAY_SIZE(tas5086_ratios), |
388 | priv->mclk / priv->rate); | 388 | priv->mclk / priv->rate); |
389 | if (val < 0) { | 389 | if (val < 0) { |
390 | dev_err(codec->dev, "Inavlid MCLK / Fs ratio\n"); | 390 | dev_err(codec->dev, "Invalid MCLK / Fs ratio\n"); |
391 | return -EINVAL; | 391 | return -EINVAL; |
392 | } | 392 | } |
393 | 393 | ||
@@ -890,12 +890,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tas5086 = { | |||
890 | .remove = tas5086_remove, | 890 | .remove = tas5086_remove, |
891 | .suspend = tas5086_soc_suspend, | 891 | .suspend = tas5086_soc_suspend, |
892 | .resume = tas5086_soc_resume, | 892 | .resume = tas5086_soc_resume, |
893 | .controls = tas5086_controls, | 893 | .component_driver = { |
894 | .num_controls = ARRAY_SIZE(tas5086_controls), | 894 | .controls = tas5086_controls, |
895 | .dapm_widgets = tas5086_dapm_widgets, | 895 | .num_controls = ARRAY_SIZE(tas5086_controls), |
896 | .num_dapm_widgets = ARRAY_SIZE(tas5086_dapm_widgets), | 896 | .dapm_widgets = tas5086_dapm_widgets, |
897 | .dapm_routes = tas5086_dapm_routes, | 897 | .num_dapm_widgets = ARRAY_SIZE(tas5086_dapm_widgets), |
898 | .num_dapm_routes = ARRAY_SIZE(tas5086_dapm_routes), | 898 | .dapm_routes = tas5086_dapm_routes, |
899 | .num_dapm_routes = ARRAY_SIZE(tas5086_dapm_routes), | ||
900 | }, | ||
899 | }; | 901 | }; |
900 | 902 | ||
901 | static const struct i2c_device_id tas5086_i2c_id[] = { | 903 | static const struct i2c_device_id tas5086_i2c_id[] = { |
diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c index d8baca3f8413..df5e5cb33baa 100644 --- a/sound/soc/codecs/tas571x.c +++ b/sound/soc/codecs/tas571x.c | |||
@@ -658,10 +658,12 @@ static const struct snd_soc_codec_driver tas571x_codec = { | |||
658 | .set_bias_level = tas571x_set_bias_level, | 658 | .set_bias_level = tas571x_set_bias_level, |
659 | .idle_bias_off = true, | 659 | .idle_bias_off = true, |
660 | 660 | ||
661 | .dapm_widgets = tas571x_dapm_widgets, | 661 | .component_driver = { |
662 | .num_dapm_widgets = ARRAY_SIZE(tas571x_dapm_widgets), | 662 | .dapm_widgets = tas571x_dapm_widgets, |
663 | .dapm_routes = tas571x_dapm_routes, | 663 | .num_dapm_widgets = ARRAY_SIZE(tas571x_dapm_widgets), |
664 | .num_dapm_routes = ARRAY_SIZE(tas571x_dapm_routes), | 664 | .dapm_routes = tas571x_dapm_routes, |
665 | .num_dapm_routes = ARRAY_SIZE(tas571x_dapm_routes), | ||
666 | }, | ||
665 | }; | 667 | }; |
666 | 668 | ||
667 | static struct snd_soc_dai_driver tas571x_dai = { | 669 | static struct snd_soc_dai_driver tas571x_dai = { |
@@ -754,8 +756,8 @@ static int tas571x_i2c_probe(struct i2c_client *client, | |||
754 | 756 | ||
755 | 757 | ||
756 | memcpy(&priv->codec_driver, &tas571x_codec, sizeof(priv->codec_driver)); | 758 | memcpy(&priv->codec_driver, &tas571x_codec, sizeof(priv->codec_driver)); |
757 | priv->codec_driver.controls = priv->chip->controls; | 759 | priv->codec_driver.component_driver.controls = priv->chip->controls; |
758 | priv->codec_driver.num_controls = priv->chip->num_controls; | 760 | priv->codec_driver.component_driver.num_controls = priv->chip->num_controls; |
759 | 761 | ||
760 | if (priv->chip->vol_reg_size == 2) { | 762 | if (priv->chip->vol_reg_size == 2) { |
761 | /* | 763 | /* |
diff --git a/sound/soc/codecs/tas5720.c b/sound/soc/codecs/tas5720.c index f54fb46b77c2..c65b917598d2 100644 --- a/sound/soc/codecs/tas5720.c +++ b/sound/soc/codecs/tas5720.c | |||
@@ -489,12 +489,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tas5720 = { | |||
489 | .suspend = tas5720_suspend, | 489 | .suspend = tas5720_suspend, |
490 | .resume = tas5720_resume, | 490 | .resume = tas5720_resume, |
491 | 491 | ||
492 | .controls = tas5720_snd_controls, | 492 | .component_driver = { |
493 | .num_controls = ARRAY_SIZE(tas5720_snd_controls), | 493 | .controls = tas5720_snd_controls, |
494 | .dapm_widgets = tas5720_dapm_widgets, | 494 | .num_controls = ARRAY_SIZE(tas5720_snd_controls), |
495 | .num_dapm_widgets = ARRAY_SIZE(tas5720_dapm_widgets), | 495 | .dapm_widgets = tas5720_dapm_widgets, |
496 | .dapm_routes = tas5720_audio_map, | 496 | .num_dapm_widgets = ARRAY_SIZE(tas5720_dapm_widgets), |
497 | .num_dapm_routes = ARRAY_SIZE(tas5720_audio_map), | 497 | .dapm_routes = tas5720_audio_map, |
498 | .num_dapm_routes = ARRAY_SIZE(tas5720_audio_map), | ||
499 | }, | ||
498 | }; | 500 | }; |
499 | 501 | ||
500 | /* PCM rates supported by the TAS5720 driver */ | 502 | /* PCM rates supported by the TAS5720 driver */ |
diff --git a/sound/soc/codecs/tfa9879.c b/sound/soc/codecs/tfa9879.c index cb5310d89c0f..95e0a7abeb7a 100644 --- a/sound/soc/codecs/tfa9879.c +++ b/sound/soc/codecs/tfa9879.c | |||
@@ -231,13 +231,14 @@ static const struct snd_soc_dapm_route tfa9879_dapm_routes[] = { | |||
231 | }; | 231 | }; |
232 | 232 | ||
233 | static const struct snd_soc_codec_driver tfa9879_codec = { | 233 | static const struct snd_soc_codec_driver tfa9879_codec = { |
234 | .controls = tfa9879_controls, | 234 | .component_driver = { |
235 | .num_controls = ARRAY_SIZE(tfa9879_controls), | 235 | .controls = tfa9879_controls, |
236 | 236 | .num_controls = ARRAY_SIZE(tfa9879_controls), | |
237 | .dapm_widgets = tfa9879_dapm_widgets, | 237 | .dapm_widgets = tfa9879_dapm_widgets, |
238 | .num_dapm_widgets = ARRAY_SIZE(tfa9879_dapm_widgets), | 238 | .num_dapm_widgets = ARRAY_SIZE(tfa9879_dapm_widgets), |
239 | .dapm_routes = tfa9879_dapm_routes, | 239 | .dapm_routes = tfa9879_dapm_routes, |
240 | .num_dapm_routes = ARRAY_SIZE(tfa9879_dapm_routes), | 240 | .num_dapm_routes = ARRAY_SIZE(tfa9879_dapm_routes), |
241 | }, | ||
241 | }; | 242 | }; |
242 | 243 | ||
243 | static const struct regmap_config tfa9879_regmap = { | 244 | static const struct regmap_config tfa9879_regmap = { |
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index cd8c02b6e4de..410cae0f2060 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c | |||
@@ -583,12 +583,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { | |||
583 | .set_bias_level = tlv320aic23_set_bias_level, | 583 | .set_bias_level = tlv320aic23_set_bias_level, |
584 | .suspend_bias_off = true, | 584 | .suspend_bias_off = true, |
585 | 585 | ||
586 | .controls = tlv320aic23_snd_controls, | 586 | .component_driver = { |
587 | .num_controls = ARRAY_SIZE(tlv320aic23_snd_controls), | 587 | .controls = tlv320aic23_snd_controls, |
588 | .dapm_widgets = tlv320aic23_dapm_widgets, | 588 | .num_controls = ARRAY_SIZE(tlv320aic23_snd_controls), |
589 | .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), | 589 | .dapm_widgets = tlv320aic23_dapm_widgets, |
590 | .dapm_routes = tlv320aic23_intercon, | 590 | .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), |
591 | .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon), | 591 | .dapm_routes = tlv320aic23_intercon, |
592 | .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon), | ||
593 | }, | ||
592 | }; | 594 | }; |
593 | 595 | ||
594 | int tlv320aic23_probe(struct device *dev, struct regmap *regmap) | 596 | int tlv320aic23_probe(struct device *dev, struct regmap *regmap) |
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 2c904d7150ad..14aa96d41719 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c | |||
@@ -321,12 +321,14 @@ static int aic26_probe(struct snd_soc_codec *codec) | |||
321 | 321 | ||
322 | static struct snd_soc_codec_driver aic26_soc_codec_dev = { | 322 | static struct snd_soc_codec_driver aic26_soc_codec_dev = { |
323 | .probe = aic26_probe, | 323 | .probe = aic26_probe, |
324 | .controls = aic26_snd_controls, | 324 | .component_driver = { |
325 | .num_controls = ARRAY_SIZE(aic26_snd_controls), | 325 | .controls = aic26_snd_controls, |
326 | .dapm_widgets = tlv320aic26_dapm_widgets, | 326 | .num_controls = ARRAY_SIZE(aic26_snd_controls), |
327 | .num_dapm_widgets = ARRAY_SIZE(tlv320aic26_dapm_widgets), | 327 | .dapm_widgets = tlv320aic26_dapm_widgets, |
328 | .dapm_routes = tlv320aic26_dapm_routes, | 328 | .num_dapm_widgets = ARRAY_SIZE(tlv320aic26_dapm_widgets), |
329 | .num_dapm_routes = ARRAY_SIZE(tlv320aic26_dapm_routes), | 329 | .dapm_routes = tlv320aic26_dapm_routes, |
330 | .num_dapm_routes = ARRAY_SIZE(tlv320aic26_dapm_routes), | ||
331 | }, | ||
330 | }; | 332 | }; |
331 | 333 | ||
332 | static const struct regmap_config aic26_regmap = { | 334 | static const struct regmap_config aic26_regmap = { |
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index 3c5e1df01c19..be1a64bfd320 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c | |||
@@ -273,10 +273,20 @@ static const DECLARE_TLV_DB_SCALE(sp_vol_tlv, -6350, 50, 0); | |||
273 | /* | 273 | /* |
274 | * controls to be exported to the user space | 274 | * controls to be exported to the user space |
275 | */ | 275 | */ |
276 | static const struct snd_kcontrol_new aic31xx_snd_controls[] = { | 276 | static const struct snd_kcontrol_new common31xx_snd_controls[] = { |
277 | SOC_DOUBLE_R_S_TLV("DAC Playback Volume", AIC31XX_LDACVOL, | 277 | SOC_DOUBLE_R_S_TLV("DAC Playback Volume", AIC31XX_LDACVOL, |
278 | AIC31XX_RDACVOL, 0, -127, 48, 7, 0, dac_vol_tlv), | 278 | AIC31XX_RDACVOL, 0, -127, 48, 7, 0, dac_vol_tlv), |
279 | 279 | ||
280 | SOC_DOUBLE_R("HP Driver Playback Switch", AIC31XX_HPLGAIN, | ||
281 | AIC31XX_HPRGAIN, 2, 1, 0), | ||
282 | SOC_DOUBLE_R_TLV("HP Driver Playback Volume", AIC31XX_HPLGAIN, | ||
283 | AIC31XX_HPRGAIN, 3, 0x09, 0, hp_drv_tlv), | ||
284 | |||
285 | SOC_DOUBLE_R_TLV("HP Analog Playback Volume", AIC31XX_LANALOGHPL, | ||
286 | AIC31XX_RANALOGHPR, 0, 0x7F, 1, hp_vol_tlv), | ||
287 | }; | ||
288 | |||
289 | static const struct snd_kcontrol_new aic31xx_snd_controls[] = { | ||
280 | SOC_SINGLE_TLV("ADC Fine Capture Volume", AIC31XX_ADCFGA, 4, 4, 1, | 290 | SOC_SINGLE_TLV("ADC Fine Capture Volume", AIC31XX_ADCFGA, 4, 4, 1, |
281 | adc_fgain_tlv), | 291 | adc_fgain_tlv), |
282 | 292 | ||
@@ -286,14 +296,6 @@ static const struct snd_kcontrol_new aic31xx_snd_controls[] = { | |||
286 | 296 | ||
287 | SOC_SINGLE_TLV("Mic PGA Capture Volume", AIC31XX_MICPGA, 0, | 297 | SOC_SINGLE_TLV("Mic PGA Capture Volume", AIC31XX_MICPGA, 0, |
288 | 119, 0, mic_pga_tlv), | 298 | 119, 0, mic_pga_tlv), |
289 | |||
290 | SOC_DOUBLE_R("HP Driver Playback Switch", AIC31XX_HPLGAIN, | ||
291 | AIC31XX_HPRGAIN, 2, 1, 0), | ||
292 | SOC_DOUBLE_R_TLV("HP Driver Playback Volume", AIC31XX_HPLGAIN, | ||
293 | AIC31XX_HPRGAIN, 3, 0x09, 0, hp_drv_tlv), | ||
294 | |||
295 | SOC_DOUBLE_R_TLV("HP Analog Playback Volume", AIC31XX_LANALOGHPL, | ||
296 | AIC31XX_RANALOGHPR, 0, 0x7F, 1, hp_vol_tlv), | ||
297 | }; | 299 | }; |
298 | 300 | ||
299 | static const struct snd_kcontrol_new aic311x_snd_controls[] = { | 301 | static const struct snd_kcontrol_new aic311x_snd_controls[] = { |
@@ -397,17 +399,28 @@ static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w, | |||
397 | return 0; | 399 | return 0; |
398 | } | 400 | } |
399 | 401 | ||
400 | static const struct snd_kcontrol_new left_output_switches[] = { | 402 | static const struct snd_kcontrol_new aic31xx_left_output_switches[] = { |
401 | SOC_DAPM_SINGLE("From Left DAC", AIC31XX_DACMIXERROUTE, 6, 1, 0), | 403 | SOC_DAPM_SINGLE("From Left DAC", AIC31XX_DACMIXERROUTE, 6, 1, 0), |
402 | SOC_DAPM_SINGLE("From MIC1LP", AIC31XX_DACMIXERROUTE, 5, 1, 0), | 404 | SOC_DAPM_SINGLE("From MIC1LP", AIC31XX_DACMIXERROUTE, 5, 1, 0), |
403 | SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 4, 1, 0), | 405 | SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 4, 1, 0), |
404 | }; | 406 | }; |
405 | 407 | ||
406 | static const struct snd_kcontrol_new right_output_switches[] = { | 408 | static const struct snd_kcontrol_new aic31xx_right_output_switches[] = { |
407 | SOC_DAPM_SINGLE("From Right DAC", AIC31XX_DACMIXERROUTE, 2, 1, 0), | 409 | SOC_DAPM_SINGLE("From Right DAC", AIC31XX_DACMIXERROUTE, 2, 1, 0), |
408 | SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 1, 1, 0), | 410 | SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 1, 1, 0), |
409 | }; | 411 | }; |
410 | 412 | ||
413 | static const struct snd_kcontrol_new dac31xx_left_output_switches[] = { | ||
414 | SOC_DAPM_SINGLE("From Left DAC", AIC31XX_DACMIXERROUTE, 6, 1, 0), | ||
415 | SOC_DAPM_SINGLE("From AIN1", AIC31XX_DACMIXERROUTE, 5, 1, 0), | ||
416 | SOC_DAPM_SINGLE("From AIN2", AIC31XX_DACMIXERROUTE, 4, 1, 0), | ||
417 | }; | ||
418 | |||
419 | static const struct snd_kcontrol_new dac31xx_right_output_switches[] = { | ||
420 | SOC_DAPM_SINGLE("From Right DAC", AIC31XX_DACMIXERROUTE, 2, 1, 0), | ||
421 | SOC_DAPM_SINGLE("From AIN2", AIC31XX_DACMIXERROUTE, 1, 1, 0), | ||
422 | }; | ||
423 | |||
411 | static const struct snd_kcontrol_new p_term_mic1lp = | 424 | static const struct snd_kcontrol_new p_term_mic1lp = |
412 | SOC_DAPM_ENUM("MIC1LP P-Terminal", mic1lp_p_enum); | 425 | SOC_DAPM_ENUM("MIC1LP P-Terminal", mic1lp_p_enum); |
413 | 426 | ||
@@ -457,7 +470,7 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w, | |||
457 | return 0; | 470 | return 0; |
458 | } | 471 | } |
459 | 472 | ||
460 | static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = { | 473 | static const struct snd_soc_dapm_widget common31xx_dapm_widgets[] = { |
461 | SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0), | 474 | SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0), |
462 | 475 | ||
463 | SND_SOC_DAPM_MUX("DAC Left Input", | 476 | SND_SOC_DAPM_MUX("DAC Left Input", |
@@ -473,14 +486,7 @@ static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = { | |||
473 | AIC31XX_DACSETUP, 6, 0, aic31xx_dapm_power_event, | 486 | AIC31XX_DACSETUP, 6, 0, aic31xx_dapm_power_event, |
474 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | 487 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), |
475 | 488 | ||
476 | /* Output Mixers */ | 489 | /* HP */ |
477 | SND_SOC_DAPM_MIXER("Output Left", SND_SOC_NOPM, 0, 0, | ||
478 | left_output_switches, | ||
479 | ARRAY_SIZE(left_output_switches)), | ||
480 | SND_SOC_DAPM_MIXER("Output Right", SND_SOC_NOPM, 0, 0, | ||
481 | right_output_switches, | ||
482 | ARRAY_SIZE(right_output_switches)), | ||
483 | |||
484 | SND_SOC_DAPM_SWITCH("HP Left", SND_SOC_NOPM, 0, 0, | 490 | SND_SOC_DAPM_SWITCH("HP Left", SND_SOC_NOPM, 0, 0, |
485 | &aic31xx_dapm_hpl_switch), | 491 | &aic31xx_dapm_hpl_switch), |
486 | SND_SOC_DAPM_SWITCH("HP Right", SND_SOC_NOPM, 0, 0, | 492 | SND_SOC_DAPM_SWITCH("HP Right", SND_SOC_NOPM, 0, 0, |
@@ -494,10 +500,34 @@ static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = { | |||
494 | NULL, 0, aic31xx_dapm_power_event, | 500 | NULL, 0, aic31xx_dapm_power_event, |
495 | SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), | 501 | SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), |
496 | 502 | ||
497 | /* ADC */ | 503 | /* Mic Bias */ |
498 | SND_SOC_DAPM_ADC_E("ADC", "Capture", AIC31XX_ADCSETUP, 7, 0, | 504 | SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, mic_bias_event, |
499 | aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU | | 505 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
500 | SND_SOC_DAPM_POST_PMD), | 506 | |
507 | /* Outputs */ | ||
508 | SND_SOC_DAPM_OUTPUT("HPL"), | ||
509 | SND_SOC_DAPM_OUTPUT("HPR"), | ||
510 | }; | ||
511 | |||
512 | static const struct snd_soc_dapm_widget dac31xx_dapm_widgets[] = { | ||
513 | /* Inputs */ | ||
514 | SND_SOC_DAPM_INPUT("AIN1"), | ||
515 | SND_SOC_DAPM_INPUT("AIN2"), | ||
516 | |||
517 | /* Output Mixers */ | ||
518 | SND_SOC_DAPM_MIXER("Output Left", SND_SOC_NOPM, 0, 0, | ||
519 | dac31xx_left_output_switches, | ||
520 | ARRAY_SIZE(dac31xx_left_output_switches)), | ||
521 | SND_SOC_DAPM_MIXER("Output Right", SND_SOC_NOPM, 0, 0, | ||
522 | dac31xx_right_output_switches, | ||
523 | ARRAY_SIZE(dac31xx_right_output_switches)), | ||
524 | }; | ||
525 | |||
526 | static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = { | ||
527 | /* Inputs */ | ||
528 | SND_SOC_DAPM_INPUT("MIC1LP"), | ||
529 | SND_SOC_DAPM_INPUT("MIC1RP"), | ||
530 | SND_SOC_DAPM_INPUT("MIC1LM"), | ||
501 | 531 | ||
502 | /* Input Selection to MIC_PGA */ | 532 | /* Input Selection to MIC_PGA */ |
503 | SND_SOC_DAPM_MUX("MIC1LP P-Terminal", SND_SOC_NOPM, 0, 0, | 533 | SND_SOC_DAPM_MUX("MIC1LP P-Terminal", SND_SOC_NOPM, 0, 0, |
@@ -507,24 +537,25 @@ static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = { | |||
507 | SND_SOC_DAPM_MUX("MIC1LM P-Terminal", SND_SOC_NOPM, 0, 0, | 537 | SND_SOC_DAPM_MUX("MIC1LM P-Terminal", SND_SOC_NOPM, 0, 0, |
508 | &p_term_mic1lm), | 538 | &p_term_mic1lm), |
509 | 539 | ||
540 | /* ADC */ | ||
541 | SND_SOC_DAPM_ADC_E("ADC", "Capture", AIC31XX_ADCSETUP, 7, 0, | ||
542 | aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU | | ||
543 | SND_SOC_DAPM_POST_PMD), | ||
544 | |||
510 | SND_SOC_DAPM_MUX("MIC1LM M-Terminal", SND_SOC_NOPM, 0, 0, | 545 | SND_SOC_DAPM_MUX("MIC1LM M-Terminal", SND_SOC_NOPM, 0, 0, |
511 | &m_term_mic1lm), | 546 | &m_term_mic1lm), |
547 | |||
512 | /* Enabling & Disabling MIC Gain Ctl */ | 548 | /* Enabling & Disabling MIC Gain Ctl */ |
513 | SND_SOC_DAPM_PGA("MIC_GAIN_CTL", AIC31XX_MICPGA, | 549 | SND_SOC_DAPM_PGA("MIC_GAIN_CTL", AIC31XX_MICPGA, |
514 | 7, 1, NULL, 0), | 550 | 7, 1, NULL, 0), |
515 | 551 | ||
516 | /* Mic Bias */ | 552 | /* Output Mixers */ |
517 | SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, mic_bias_event, | 553 | SND_SOC_DAPM_MIXER("Output Left", SND_SOC_NOPM, 0, 0, |
518 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 554 | aic31xx_left_output_switches, |
519 | 555 | ARRAY_SIZE(aic31xx_left_output_switches)), | |
520 | /* Outputs */ | 556 | SND_SOC_DAPM_MIXER("Output Right", SND_SOC_NOPM, 0, 0, |
521 | SND_SOC_DAPM_OUTPUT("HPL"), | 557 | aic31xx_right_output_switches, |
522 | SND_SOC_DAPM_OUTPUT("HPR"), | 558 | ARRAY_SIZE(aic31xx_right_output_switches)), |
523 | |||
524 | /* Inputs */ | ||
525 | SND_SOC_DAPM_INPUT("MIC1LP"), | ||
526 | SND_SOC_DAPM_INPUT("MIC1RP"), | ||
527 | SND_SOC_DAPM_INPUT("MIC1LM"), | ||
528 | }; | 559 | }; |
529 | 560 | ||
530 | static const struct snd_soc_dapm_widget aic311x_dapm_widgets[] = { | 561 | static const struct snd_soc_dapm_widget aic311x_dapm_widgets[] = { |
@@ -554,7 +585,7 @@ static const struct snd_soc_dapm_widget aic310x_dapm_widgets[] = { | |||
554 | }; | 585 | }; |
555 | 586 | ||
556 | static const struct snd_soc_dapm_route | 587 | static const struct snd_soc_dapm_route |
557 | aic31xx_audio_map[] = { | 588 | common31xx_audio_map[] = { |
558 | /* DAC Input Routing */ | 589 | /* DAC Input Routing */ |
559 | {"DAC Left Input", "Left Data", "DAC IN"}, | 590 | {"DAC Left Input", "Left Data", "DAC IN"}, |
560 | {"DAC Left Input", "Right Data", "DAC IN"}, | 591 | {"DAC Left Input", "Right Data", "DAC IN"}, |
@@ -565,6 +596,31 @@ aic31xx_audio_map[] = { | |||
565 | {"DAC Left", NULL, "DAC Left Input"}, | 596 | {"DAC Left", NULL, "DAC Left Input"}, |
566 | {"DAC Right", NULL, "DAC Right Input"}, | 597 | {"DAC Right", NULL, "DAC Right Input"}, |
567 | 598 | ||
599 | /* HPL path */ | ||
600 | {"HP Left", "Switch", "Output Left"}, | ||
601 | {"HPL Driver", NULL, "HP Left"}, | ||
602 | {"HPL", NULL, "HPL Driver"}, | ||
603 | |||
604 | /* HPR path */ | ||
605 | {"HP Right", "Switch", "Output Right"}, | ||
606 | {"HPR Driver", NULL, "HP Right"}, | ||
607 | {"HPR", NULL, "HPR Driver"}, | ||
608 | }; | ||
609 | |||
610 | static const struct snd_soc_dapm_route | ||
611 | dac31xx_audio_map[] = { | ||
612 | /* Left Output */ | ||
613 | {"Output Left", "From Left DAC", "DAC Left"}, | ||
614 | {"Output Left", "From AIN1", "AIN1"}, | ||
615 | {"Output Left", "From AIN2", "AIN2"}, | ||
616 | |||
617 | /* Right Output */ | ||
618 | {"Output Right", "From Right DAC", "DAC Right"}, | ||
619 | {"Output Right", "From AIN2", "AIN2"}, | ||
620 | }; | ||
621 | |||
622 | static const struct snd_soc_dapm_route | ||
623 | aic31xx_audio_map[] = { | ||
568 | /* Mic input */ | 624 | /* Mic input */ |
569 | {"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"}, | 625 | {"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"}, |
570 | {"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"}, | 626 | {"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"}, |
@@ -595,16 +651,6 @@ aic31xx_audio_map[] = { | |||
595 | /* Right Output */ | 651 | /* Right Output */ |
596 | {"Output Right", "From Right DAC", "DAC Right"}, | 652 | {"Output Right", "From Right DAC", "DAC Right"}, |
597 | {"Output Right", "From MIC1RP", "MIC1RP"}, | 653 | {"Output Right", "From MIC1RP", "MIC1RP"}, |
598 | |||
599 | /* HPL path */ | ||
600 | {"HP Left", "Switch", "Output Left"}, | ||
601 | {"HPL Driver", NULL, "HP Left"}, | ||
602 | {"HPL", NULL, "HPL Driver"}, | ||
603 | |||
604 | /* HPR path */ | ||
605 | {"HP Right", "Switch", "Output Right"}, | ||
606 | {"HPR Driver", NULL, "HP Right"}, | ||
607 | {"HPR", NULL, "HPR Driver"}, | ||
608 | }; | 654 | }; |
609 | 655 | ||
610 | static const struct snd_soc_dapm_route | 656 | static const struct snd_soc_dapm_route |
@@ -633,6 +679,13 @@ static int aic31xx_add_controls(struct snd_soc_codec *codec) | |||
633 | int ret = 0; | 679 | int ret = 0; |
634 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | 680 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); |
635 | 681 | ||
682 | if (!(aic31xx->pdata.codec_type & DAC31XX_BIT)) | ||
683 | ret = snd_soc_add_codec_controls( | ||
684 | codec, aic31xx_snd_controls, | ||
685 | ARRAY_SIZE(aic31xx_snd_controls)); | ||
686 | if (ret) | ||
687 | return ret; | ||
688 | |||
636 | if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) | 689 | if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) |
637 | ret = snd_soc_add_codec_controls( | 690 | ret = snd_soc_add_codec_controls( |
638 | codec, aic311x_snd_controls, | 691 | codec, aic311x_snd_controls, |
@@ -651,6 +704,30 @@ static int aic31xx_add_widgets(struct snd_soc_codec *codec) | |||
651 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | 704 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); |
652 | int ret = 0; | 705 | int ret = 0; |
653 | 706 | ||
707 | if (aic31xx->pdata.codec_type & DAC31XX_BIT) { | ||
708 | ret = snd_soc_dapm_new_controls( | ||
709 | dapm, dac31xx_dapm_widgets, | ||
710 | ARRAY_SIZE(dac31xx_dapm_widgets)); | ||
711 | if (ret) | ||
712 | return ret; | ||
713 | |||
714 | ret = snd_soc_dapm_add_routes(dapm, dac31xx_audio_map, | ||
715 | ARRAY_SIZE(dac31xx_audio_map)); | ||
716 | if (ret) | ||
717 | return ret; | ||
718 | } else { | ||
719 | ret = snd_soc_dapm_new_controls( | ||
720 | dapm, aic31xx_dapm_widgets, | ||
721 | ARRAY_SIZE(aic31xx_dapm_widgets)); | ||
722 | if (ret) | ||
723 | return ret; | ||
724 | |||
725 | ret = snd_soc_dapm_add_routes(dapm, aic31xx_audio_map, | ||
726 | ARRAY_SIZE(aic31xx_audio_map)); | ||
727 | if (ret) | ||
728 | return ret; | ||
729 | } | ||
730 | |||
654 | if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) { | 731 | if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) { |
655 | ret = snd_soc_dapm_new_controls( | 732 | ret = snd_soc_dapm_new_controls( |
656 | dapm, aic311x_dapm_widgets, | 733 | dapm, aic311x_dapm_widgets, |
@@ -1114,12 +1191,14 @@ static struct snd_soc_codec_driver soc_codec_driver_aic31xx = { | |||
1114 | .set_bias_level = aic31xx_set_bias_level, | 1191 | .set_bias_level = aic31xx_set_bias_level, |
1115 | .suspend_bias_off = true, | 1192 | .suspend_bias_off = true, |
1116 | 1193 | ||
1117 | .controls = aic31xx_snd_controls, | 1194 | .component_driver = { |
1118 | .num_controls = ARRAY_SIZE(aic31xx_snd_controls), | 1195 | .controls = common31xx_snd_controls, |
1119 | .dapm_widgets = aic31xx_dapm_widgets, | 1196 | .num_controls = ARRAY_SIZE(common31xx_snd_controls), |
1120 | .num_dapm_widgets = ARRAY_SIZE(aic31xx_dapm_widgets), | 1197 | .dapm_widgets = common31xx_dapm_widgets, |
1121 | .dapm_routes = aic31xx_audio_map, | 1198 | .num_dapm_widgets = ARRAY_SIZE(common31xx_dapm_widgets), |
1122 | .num_dapm_routes = ARRAY_SIZE(aic31xx_audio_map), | 1199 | .dapm_routes = common31xx_audio_map, |
1200 | .num_dapm_routes = ARRAY_SIZE(common31xx_audio_map), | ||
1201 | }, | ||
1123 | }; | 1202 | }; |
1124 | 1203 | ||
1125 | static const struct snd_soc_dai_ops aic31xx_dai_ops = { | 1204 | static const struct snd_soc_dai_ops aic31xx_dai_ops = { |
@@ -1129,19 +1208,34 @@ static const struct snd_soc_dai_ops aic31xx_dai_ops = { | |||
1129 | .digital_mute = aic31xx_dac_mute, | 1208 | .digital_mute = aic31xx_dac_mute, |
1130 | }; | 1209 | }; |
1131 | 1210 | ||
1211 | static struct snd_soc_dai_driver dac31xx_dai_driver[] = { | ||
1212 | { | ||
1213 | .name = "tlv32dac31xx-hifi", | ||
1214 | .playback = { | ||
1215 | .stream_name = "Playback", | ||
1216 | .channels_min = 2, | ||
1217 | .channels_max = 2, | ||
1218 | .rates = AIC31XX_RATES, | ||
1219 | .formats = AIC31XX_FORMATS, | ||
1220 | }, | ||
1221 | .ops = &aic31xx_dai_ops, | ||
1222 | .symmetric_rates = 1, | ||
1223 | } | ||
1224 | }; | ||
1225 | |||
1132 | static struct snd_soc_dai_driver aic31xx_dai_driver[] = { | 1226 | static struct snd_soc_dai_driver aic31xx_dai_driver[] = { |
1133 | { | 1227 | { |
1134 | .name = "tlv320aic31xx-hifi", | 1228 | .name = "tlv320aic31xx-hifi", |
1135 | .playback = { | 1229 | .playback = { |
1136 | .stream_name = "Playback", | 1230 | .stream_name = "Playback", |
1137 | .channels_min = 1, | 1231 | .channels_min = 2, |
1138 | .channels_max = 2, | 1232 | .channels_max = 2, |
1139 | .rates = AIC31XX_RATES, | 1233 | .rates = AIC31XX_RATES, |
1140 | .formats = AIC31XX_FORMATS, | 1234 | .formats = AIC31XX_FORMATS, |
1141 | }, | 1235 | }, |
1142 | .capture = { | 1236 | .capture = { |
1143 | .stream_name = "Capture", | 1237 | .stream_name = "Capture", |
1144 | .channels_min = 1, | 1238 | .channels_min = 2, |
1145 | .channels_max = 2, | 1239 | .channels_max = 2, |
1146 | .rates = AIC31XX_RATES, | 1240 | .rates = AIC31XX_RATES, |
1147 | .formats = AIC31XX_FORMATS, | 1241 | .formats = AIC31XX_FORMATS, |
@@ -1259,9 +1353,16 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c, | |||
1259 | if (ret) | 1353 | if (ret) |
1260 | return ret; | 1354 | return ret; |
1261 | 1355 | ||
1262 | return snd_soc_register_codec(&i2c->dev, &soc_codec_driver_aic31xx, | 1356 | if (aic31xx->pdata.codec_type & DAC31XX_BIT) |
1263 | aic31xx_dai_driver, | 1357 | return snd_soc_register_codec(&i2c->dev, |
1264 | ARRAY_SIZE(aic31xx_dai_driver)); | 1358 | &soc_codec_driver_aic31xx, |
1359 | dac31xx_dai_driver, | ||
1360 | ARRAY_SIZE(dac31xx_dai_driver)); | ||
1361 | else | ||
1362 | return snd_soc_register_codec(&i2c->dev, | ||
1363 | &soc_codec_driver_aic31xx, | ||
1364 | aic31xx_dai_driver, | ||
1365 | ARRAY_SIZE(aic31xx_dai_driver)); | ||
1265 | } | 1366 | } |
1266 | 1367 | ||
1267 | static int aic31xx_i2c_remove(struct i2c_client *i2c) | 1368 | static int aic31xx_i2c_remove(struct i2c_client *i2c) |
@@ -1277,6 +1378,7 @@ static const struct i2c_device_id aic31xx_i2c_id[] = { | |||
1277 | { "tlv320aic3110", AIC3110 }, | 1378 | { "tlv320aic3110", AIC3110 }, |
1278 | { "tlv320aic3120", AIC3120 }, | 1379 | { "tlv320aic3120", AIC3120 }, |
1279 | { "tlv320aic3111", AIC3111 }, | 1380 | { "tlv320aic3111", AIC3111 }, |
1381 | { "tlv320dac3100", DAC3100 }, | ||
1280 | { } | 1382 | { } |
1281 | }; | 1383 | }; |
1282 | MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id); | 1384 | MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id); |
diff --git a/sound/soc/codecs/tlv320aic31xx.h b/sound/soc/codecs/tlv320aic31xx.h index ac9b146526eb..5acd5b69fb83 100644 --- a/sound/soc/codecs/tlv320aic31xx.h +++ b/sound/soc/codecs/tlv320aic31xx.h | |||
@@ -24,12 +24,14 @@ | |||
24 | 24 | ||
25 | #define AIC31XX_STEREO_CLASS_D_BIT 0x1 | 25 | #define AIC31XX_STEREO_CLASS_D_BIT 0x1 |
26 | #define AIC31XX_MINIDSP_BIT 0x2 | 26 | #define AIC31XX_MINIDSP_BIT 0x2 |
27 | #define DAC31XX_BIT 0x4 | ||
27 | 28 | ||
28 | enum aic31xx_type { | 29 | enum aic31xx_type { |
29 | AIC3100 = 0, | 30 | AIC3100 = 0, |
30 | AIC3110 = AIC31XX_STEREO_CLASS_D_BIT, | 31 | AIC3110 = AIC31XX_STEREO_CLASS_D_BIT, |
31 | AIC3120 = AIC31XX_MINIDSP_BIT, | 32 | AIC3120 = AIC31XX_MINIDSP_BIT, |
32 | AIC3111 = (AIC31XX_STEREO_CLASS_D_BIT | AIC31XX_MINIDSP_BIT), | 33 | AIC3111 = (AIC31XX_STEREO_CLASS_D_BIT | AIC31XX_MINIDSP_BIT), |
34 | DAC3100 = DAC31XX_BIT, | ||
33 | }; | 35 | }; |
34 | 36 | ||
35 | struct aic31xx_pdata { | 37 | struct aic31xx_pdata { |
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 85d4978d0384..28fdfc5ec544 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c | |||
@@ -797,12 +797,14 @@ static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = { | |||
797 | .set_bias_level = aic32x4_set_bias_level, | 797 | .set_bias_level = aic32x4_set_bias_level, |
798 | .suspend_bias_off = true, | 798 | .suspend_bias_off = true, |
799 | 799 | ||
800 | .controls = aic32x4_snd_controls, | 800 | .component_driver = { |
801 | .num_controls = ARRAY_SIZE(aic32x4_snd_controls), | 801 | .controls = aic32x4_snd_controls, |
802 | .dapm_widgets = aic32x4_dapm_widgets, | 802 | .num_controls = ARRAY_SIZE(aic32x4_snd_controls), |
803 | .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets), | 803 | .dapm_widgets = aic32x4_dapm_widgets, |
804 | .dapm_routes = aic32x4_dapm_routes, | 804 | .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets), |
805 | .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), | 805 | .dapm_routes = aic32x4_dapm_routes, |
806 | .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), | ||
807 | }, | ||
806 | }; | 808 | }; |
807 | 809 | ||
808 | static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4, | 810 | static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4, |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index a564759845f9..5a8d96ec058c 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -1670,12 +1670,14 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = { | |||
1670 | .idle_bias_off = true, | 1670 | .idle_bias_off = true, |
1671 | .probe = aic3x_probe, | 1671 | .probe = aic3x_probe, |
1672 | .remove = aic3x_remove, | 1672 | .remove = aic3x_remove, |
1673 | .controls = aic3x_snd_controls, | 1673 | .component_driver = { |
1674 | .num_controls = ARRAY_SIZE(aic3x_snd_controls), | 1674 | .controls = aic3x_snd_controls, |
1675 | .dapm_widgets = aic3x_dapm_widgets, | 1675 | .num_controls = ARRAY_SIZE(aic3x_snd_controls), |
1676 | .num_dapm_widgets = ARRAY_SIZE(aic3x_dapm_widgets), | 1676 | .dapm_widgets = aic3x_dapm_widgets, |
1677 | .dapm_routes = intercon, | 1677 | .num_dapm_widgets = ARRAY_SIZE(aic3x_dapm_widgets), |
1678 | .num_dapm_routes = ARRAY_SIZE(intercon), | 1678 | .dapm_routes = intercon, |
1679 | .num_dapm_routes = ARRAY_SIZE(intercon), | ||
1680 | }, | ||
1679 | }; | 1681 | }; |
1680 | 1682 | ||
1681 | /* | 1683 | /* |
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index f7a6ce7e5fb1..7bcf01efdf9a 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c | |||
@@ -90,7 +90,6 @@ static const char *dac33_supply_names[DAC33_NUM_SUPPLIES] = { | |||
90 | 90 | ||
91 | struct tlv320dac33_priv { | 91 | struct tlv320dac33_priv { |
92 | struct mutex mutex; | 92 | struct mutex mutex; |
93 | struct workqueue_struct *dac33_wq; | ||
94 | struct work_struct work; | 93 | struct work_struct work; |
95 | struct snd_soc_codec *codec; | 94 | struct snd_soc_codec *codec; |
96 | struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES]; | 95 | struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES]; |
@@ -771,7 +770,7 @@ static irqreturn_t dac33_interrupt_handler(int irq, void *dev) | |||
771 | 770 | ||
772 | /* Do not schedule the workqueue in Mode7 */ | 771 | /* Do not schedule the workqueue in Mode7 */ |
773 | if (dac33->fifo_mode != DAC33_FIFO_MODE7) | 772 | if (dac33->fifo_mode != DAC33_FIFO_MODE7) |
774 | queue_work(dac33->dac33_wq, &dac33->work); | 773 | schedule_work(&dac33->work); |
775 | 774 | ||
776 | return IRQ_HANDLED; | 775 | return IRQ_HANDLED; |
777 | } | 776 | } |
@@ -1127,7 +1126,7 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd, | |||
1127 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 1126 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
1128 | if (dac33->fifo_mode) { | 1127 | if (dac33->fifo_mode) { |
1129 | dac33->state = DAC33_PREFILL; | 1128 | dac33->state = DAC33_PREFILL; |
1130 | queue_work(dac33->dac33_wq, &dac33->work); | 1129 | schedule_work(&dac33->work); |
1131 | } | 1130 | } |
1132 | break; | 1131 | break; |
1133 | case SNDRV_PCM_TRIGGER_STOP: | 1132 | case SNDRV_PCM_TRIGGER_STOP: |
@@ -1135,7 +1134,7 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd, | |||
1135 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 1134 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
1136 | if (dac33->fifo_mode) { | 1135 | if (dac33->fifo_mode) { |
1137 | dac33->state = DAC33_FLUSH; | 1136 | dac33->state = DAC33_FLUSH; |
1138 | queue_work(dac33->dac33_wq, &dac33->work); | 1137 | schedule_work(&dac33->work); |
1139 | } | 1138 | } |
1140 | break; | 1139 | break; |
1141 | default: | 1140 | default: |
@@ -1410,14 +1409,6 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) | |||
1410 | dac33->irq = -1; | 1409 | dac33->irq = -1; |
1411 | } | 1410 | } |
1412 | if (dac33->irq != -1) { | 1411 | if (dac33->irq != -1) { |
1413 | /* Setup work queue */ | ||
1414 | dac33->dac33_wq = | ||
1415 | create_singlethread_workqueue("tlv320dac33"); | ||
1416 | if (dac33->dac33_wq == NULL) { | ||
1417 | free_irq(dac33->irq, codec); | ||
1418 | return -ENOMEM; | ||
1419 | } | ||
1420 | |||
1421 | INIT_WORK(&dac33->work, dac33_work); | 1412 | INIT_WORK(&dac33->work, dac33_work); |
1422 | } | 1413 | } |
1423 | } | 1414 | } |
@@ -1437,7 +1428,7 @@ static int dac33_soc_remove(struct snd_soc_codec *codec) | |||
1437 | 1428 | ||
1438 | if (dac33->irq >= 0) { | 1429 | if (dac33->irq >= 0) { |
1439 | free_irq(dac33->irq, dac33->codec); | 1430 | free_irq(dac33->irq, dac33->codec); |
1440 | destroy_workqueue(dac33->dac33_wq); | 1431 | flush_work(&dac33->work); |
1441 | } | 1432 | } |
1442 | return 0; | 1433 | return 0; |
1443 | } | 1434 | } |
@@ -1453,12 +1444,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { | |||
1453 | .probe = dac33_soc_probe, | 1444 | .probe = dac33_soc_probe, |
1454 | .remove = dac33_soc_remove, | 1445 | .remove = dac33_soc_remove, |
1455 | 1446 | ||
1456 | .controls = dac33_snd_controls, | 1447 | .component_driver = { |
1457 | .num_controls = ARRAY_SIZE(dac33_snd_controls), | 1448 | .controls = dac33_snd_controls, |
1458 | .dapm_widgets = dac33_dapm_widgets, | 1449 | .num_controls = ARRAY_SIZE(dac33_snd_controls), |
1459 | .num_dapm_widgets = ARRAY_SIZE(dac33_dapm_widgets), | 1450 | .dapm_widgets = dac33_dapm_widgets, |
1460 | .dapm_routes = audio_map, | 1451 | .num_dapm_widgets = ARRAY_SIZE(dac33_dapm_widgets), |
1461 | .num_dapm_routes = ARRAY_SIZE(audio_map), | 1452 | .dapm_routes = audio_map, |
1453 | .num_dapm_routes = ARRAY_SIZE(audio_map), | ||
1454 | }, | ||
1462 | }; | 1455 | }; |
1463 | 1456 | ||
1464 | #define DAC33_RATES (SNDRV_PCM_RATE_44100 | \ | 1457 | #define DAC33_RATES (SNDRV_PCM_RATE_44100 | \ |
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index f1ea052a822e..2e014c80d113 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c | |||
@@ -52,7 +52,7 @@ struct tpa6130a2_data { | |||
52 | 52 | ||
53 | static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable) | 53 | static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable) |
54 | { | 54 | { |
55 | int ret; | 55 | int ret = 0, ret2; |
56 | 56 | ||
57 | if (enable) { | 57 | if (enable) { |
58 | ret = regulator_enable(data->supply); | 58 | ret = regulator_enable(data->supply); |
@@ -64,7 +64,30 @@ static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable) | |||
64 | /* Power on */ | 64 | /* Power on */ |
65 | if (data->power_gpio >= 0) | 65 | if (data->power_gpio >= 0) |
66 | gpio_set_value(data->power_gpio, 1); | 66 | gpio_set_value(data->power_gpio, 1); |
67 | |||
68 | /* Sync registers */ | ||
69 | regcache_cache_only(data->regmap, false); | ||
70 | ret = regcache_sync(data->regmap); | ||
71 | if (ret != 0) { | ||
72 | dev_err(data->dev, | ||
73 | "Failed to sync registers: %d\n", ret); | ||
74 | regcache_cache_only(data->regmap, true); | ||
75 | if (data->power_gpio >= 0) | ||
76 | gpio_set_value(data->power_gpio, 0); | ||
77 | ret2 = regulator_disable(data->supply); | ||
78 | if (ret2 != 0) | ||
79 | dev_err(data->dev, | ||
80 | "Failed to disable supply: %d\n", ret2); | ||
81 | return ret; | ||
82 | } | ||
67 | } else { | 83 | } else { |
84 | /* Powered off device does not retain registers. While device | ||
85 | * is off, any register updates (i.e. volume changes) should | ||
86 | * happen in cache only. | ||
87 | */ | ||
88 | regcache_mark_dirty(data->regmap); | ||
89 | regcache_cache_only(data->regmap, true); | ||
90 | |||
68 | /* Power off */ | 91 | /* Power off */ |
69 | if (data->power_gpio >= 0) | 92 | if (data->power_gpio >= 0) |
70 | gpio_set_value(data->power_gpio, 0); | 93 | gpio_set_value(data->power_gpio, 0); |
@@ -75,9 +98,6 @@ static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable) | |||
75 | "Failed to disable supply: %d\n", ret); | 98 | "Failed to disable supply: %d\n", ret); |
76 | return ret; | 99 | return ret; |
77 | } | 100 | } |
78 | |||
79 | /* device regs does not match the cache state anymore */ | ||
80 | regcache_mark_dirty(data->regmap); | ||
81 | } | 101 | } |
82 | 102 | ||
83 | return ret; | 103 | return ret; |
@@ -88,25 +108,14 @@ static int tpa6130a2_power_event(struct snd_soc_dapm_widget *w, | |||
88 | { | 108 | { |
89 | struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm); | 109 | struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm); |
90 | struct tpa6130a2_data *data = snd_soc_component_get_drvdata(c); | 110 | struct tpa6130a2_data *data = snd_soc_component_get_drvdata(c); |
91 | int ret; | ||
92 | 111 | ||
93 | /* before widget power up */ | ||
94 | if (SND_SOC_DAPM_EVENT_ON(event)) { | 112 | if (SND_SOC_DAPM_EVENT_ON(event)) { |
95 | /* Turn on the chip */ | 113 | /* Before widget power up: turn chip on, sync registers */ |
96 | tpa6130a2_power(data, true); | 114 | return tpa6130a2_power(data, true); |
97 | /* Sync the registers */ | ||
98 | ret = regcache_sync(data->regmap); | ||
99 | if (ret < 0) { | ||
100 | dev_err(c->dev, "Failed to initialize chip\n"); | ||
101 | tpa6130a2_power(data, false); | ||
102 | return ret; | ||
103 | } | ||
104 | /* after widget power down */ | ||
105 | } else { | 115 | } else { |
106 | tpa6130a2_power(data, false); | 116 | /* After widget power down: turn chip off */ |
117 | return tpa6130a2_power(data, false); | ||
107 | } | 118 | } |
108 | |||
109 | return 0; | ||
110 | } | 119 | } |
111 | 120 | ||
112 | /* | 121 | /* |
@@ -190,7 +199,7 @@ static const struct snd_soc_dapm_route tpa6130a2_dapm_routes[] = { | |||
190 | { "Right PGA", NULL, "Power" }, | 199 | { "Right PGA", NULL, "Power" }, |
191 | }; | 200 | }; |
192 | 201 | ||
193 | struct snd_soc_component_driver tpa6130a2_component_driver = { | 202 | static const struct snd_soc_component_driver tpa6130a2_component_driver = { |
194 | .name = "tpa6130a2", | 203 | .name = "tpa6130a2", |
195 | .probe = tpa6130a2_component_probe, | 204 | .probe = tpa6130a2_component_probe, |
196 | .dapm_widgets = tpa6130a2_dapm_widgets, | 205 | .dapm_widgets = tpa6130a2_dapm_widgets, |
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index a5a4e9f75c57..a2104d68169d 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -2199,12 +2199,14 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { | |||
2199 | .set_bias_level = twl4030_set_bias_level, | 2199 | .set_bias_level = twl4030_set_bias_level, |
2200 | .idle_bias_off = true, | 2200 | .idle_bias_off = true, |
2201 | 2201 | ||
2202 | .controls = twl4030_snd_controls, | 2202 | .component_driver = { |
2203 | .num_controls = ARRAY_SIZE(twl4030_snd_controls), | 2203 | .controls = twl4030_snd_controls, |
2204 | .dapm_widgets = twl4030_dapm_widgets, | 2204 | .num_controls = ARRAY_SIZE(twl4030_snd_controls), |
2205 | .num_dapm_widgets = ARRAY_SIZE(twl4030_dapm_widgets), | 2205 | .dapm_widgets = twl4030_dapm_widgets, |
2206 | .dapm_routes = intercon, | 2206 | .num_dapm_widgets = ARRAY_SIZE(twl4030_dapm_widgets), |
2207 | .num_dapm_routes = ARRAY_SIZE(intercon), | 2207 | .dapm_routes = intercon, |
2208 | .num_dapm_routes = ARRAY_SIZE(intercon), | ||
2209 | }, | ||
2208 | }; | 2210 | }; |
2209 | 2211 | ||
2210 | static int twl4030_codec_probe(struct platform_device *pdev) | 2212 | static int twl4030_codec_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 1f7081043566..748036e851ea 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c | |||
@@ -1156,12 +1156,14 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = { | |||
1156 | .suspend_bias_off = true, | 1156 | .suspend_bias_off = true, |
1157 | .ignore_pmdown_time = true, | 1157 | .ignore_pmdown_time = true, |
1158 | 1158 | ||
1159 | .controls = twl6040_snd_controls, | 1159 | .component_driver = { |
1160 | .num_controls = ARRAY_SIZE(twl6040_snd_controls), | 1160 | .controls = twl6040_snd_controls, |
1161 | .dapm_widgets = twl6040_dapm_widgets, | 1161 | .num_controls = ARRAY_SIZE(twl6040_snd_controls), |
1162 | .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets), | 1162 | .dapm_widgets = twl6040_dapm_widgets, |
1163 | .dapm_routes = intercon, | 1163 | .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets), |
1164 | .num_dapm_routes = ARRAY_SIZE(intercon), | 1164 | .dapm_routes = intercon, |
1165 | .num_dapm_routes = ARRAY_SIZE(intercon), | ||
1166 | }, | ||
1165 | }; | 1167 | }; |
1166 | 1168 | ||
1167 | static int twl6040_codec_probe(struct platform_device *pdev) | 1169 | static int twl6040_codec_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index e4c694c758b8..5fdee874406d 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c | |||
@@ -523,10 +523,12 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = { | |||
523 | .set_bias_level = uda134x_set_bias_level, | 523 | .set_bias_level = uda134x_set_bias_level, |
524 | .suspend_bias_off = true, | 524 | .suspend_bias_off = true, |
525 | 525 | ||
526 | .dapm_widgets = uda134x_dapm_widgets, | 526 | .component_driver = { |
527 | .num_dapm_widgets = ARRAY_SIZE(uda134x_dapm_widgets), | 527 | .dapm_widgets = uda134x_dapm_widgets, |
528 | .dapm_routes = uda134x_dapm_routes, | 528 | .num_dapm_widgets = ARRAY_SIZE(uda134x_dapm_widgets), |
529 | .num_dapm_routes = ARRAY_SIZE(uda134x_dapm_routes), | 529 | .dapm_routes = uda134x_dapm_routes, |
530 | .num_dapm_routes = ARRAY_SIZE(uda134x_dapm_routes), | ||
531 | }, | ||
530 | }; | 532 | }; |
531 | 533 | ||
532 | static const struct regmap_config uda134x_regmap_config = { | 534 | static const struct regmap_config uda134x_regmap_config = { |
@@ -544,6 +546,7 @@ static int uda134x_codec_probe(struct platform_device *pdev) | |||
544 | { | 546 | { |
545 | struct uda134x_platform_data *pd = pdev->dev.platform_data; | 547 | struct uda134x_platform_data *pd = pdev->dev.platform_data; |
546 | struct uda134x_priv *uda134x; | 548 | struct uda134x_priv *uda134x; |
549 | int ret; | ||
547 | 550 | ||
548 | if (!pd) { | 551 | if (!pd) { |
549 | dev_err(&pdev->dev, "Missing L3 bitbang function\n"); | 552 | dev_err(&pdev->dev, "Missing L3 bitbang function\n"); |
@@ -557,6 +560,12 @@ static int uda134x_codec_probe(struct platform_device *pdev) | |||
557 | uda134x->pd = pd; | 560 | uda134x->pd = pd; |
558 | platform_set_drvdata(pdev, uda134x); | 561 | platform_set_drvdata(pdev, uda134x); |
559 | 562 | ||
563 | if (pd->l3.use_gpios) { | ||
564 | ret = l3_set_gpio_ops(&pdev->dev, &uda134x->pd->l3); | ||
565 | if (ret < 0) | ||
566 | return ret; | ||
567 | } | ||
568 | |||
560 | uda134x->regmap = devm_regmap_init(&pdev->dev, NULL, pd, | 569 | uda134x->regmap = devm_regmap_init(&pdev->dev, NULL, pd, |
561 | &uda134x_regmap_config); | 570 | &uda134x_regmap_config); |
562 | if (IS_ERR(uda134x->regmap)) | 571 | if (IS_ERR(uda134x->regmap)) |
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 35f0469ebb16..533e3bb444e4 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c | |||
@@ -765,12 +765,14 @@ static struct snd_soc_codec_driver soc_codec_dev_uda1380 = { | |||
765 | .reg_cache_default = uda1380_reg, | 765 | .reg_cache_default = uda1380_reg, |
766 | .reg_cache_step = 1, | 766 | .reg_cache_step = 1, |
767 | 767 | ||
768 | .controls = uda1380_snd_controls, | 768 | .component_driver = { |
769 | .num_controls = ARRAY_SIZE(uda1380_snd_controls), | 769 | .controls = uda1380_snd_controls, |
770 | .dapm_widgets = uda1380_dapm_widgets, | 770 | .num_controls = ARRAY_SIZE(uda1380_snd_controls), |
771 | .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets), | 771 | .dapm_widgets = uda1380_dapm_widgets, |
772 | .dapm_routes = uda1380_dapm_routes, | 772 | .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets), |
773 | .num_dapm_routes = ARRAY_SIZE(uda1380_dapm_routes), | 773 | .dapm_routes = uda1380_dapm_routes, |
774 | .num_dapm_routes = ARRAY_SIZE(uda1380_dapm_routes), | ||
775 | }, | ||
774 | }; | 776 | }; |
775 | 777 | ||
776 | #if IS_ENABLED(CONFIG_I2C) | 778 | #if IS_ENABLED(CONFIG_I2C) |
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index 1b79778098d2..fcffb6e707d9 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c | |||
@@ -484,12 +484,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wl1273 = { | |||
484 | .probe = wl1273_probe, | 484 | .probe = wl1273_probe, |
485 | .remove = wl1273_remove, | 485 | .remove = wl1273_remove, |
486 | 486 | ||
487 | .controls = wl1273_controls, | 487 | .component_driver = { |
488 | .num_controls = ARRAY_SIZE(wl1273_controls), | 488 | .controls = wl1273_controls, |
489 | .dapm_widgets = wl1273_dapm_widgets, | 489 | .num_controls = ARRAY_SIZE(wl1273_controls), |
490 | .num_dapm_widgets = ARRAY_SIZE(wl1273_dapm_widgets), | 490 | .dapm_widgets = wl1273_dapm_widgets, |
491 | .dapm_routes = wl1273_dapm_routes, | 491 | .num_dapm_widgets = ARRAY_SIZE(wl1273_dapm_widgets), |
492 | .num_dapm_routes = ARRAY_SIZE(wl1273_dapm_routes), | 492 | .dapm_routes = wl1273_dapm_routes, |
493 | .num_dapm_routes = ARRAY_SIZE(wl1273_dapm_routes), | ||
494 | }, | ||
493 | }; | 495 | }; |
494 | 496 | ||
495 | static int wl1273_platform_probe(struct platform_device *pdev) | 497 | static int wl1273_platform_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c index e3c34bdc2772..0eb5dcf4c29d 100644 --- a/sound/soc/codecs/wm0010.c +++ b/sound/soc/codecs/wm0010.c | |||
@@ -789,16 +789,18 @@ static int wm0010_set_sysclk(struct snd_soc_codec *codec, int source, | |||
789 | 789 | ||
790 | static int wm0010_probe(struct snd_soc_codec *codec); | 790 | static int wm0010_probe(struct snd_soc_codec *codec); |
791 | 791 | ||
792 | static struct snd_soc_codec_driver soc_codec_dev_wm0010 = { | 792 | static const struct snd_soc_codec_driver soc_codec_dev_wm0010 = { |
793 | .probe = wm0010_probe, | 793 | .probe = wm0010_probe, |
794 | .set_bias_level = wm0010_set_bias_level, | 794 | .set_bias_level = wm0010_set_bias_level, |
795 | .set_sysclk = wm0010_set_sysclk, | 795 | .set_sysclk = wm0010_set_sysclk, |
796 | .idle_bias_off = true, | 796 | .idle_bias_off = true, |
797 | 797 | ||
798 | .dapm_widgets = wm0010_dapm_widgets, | 798 | .component_driver = { |
799 | .num_dapm_widgets = ARRAY_SIZE(wm0010_dapm_widgets), | 799 | .dapm_widgets = wm0010_dapm_widgets, |
800 | .dapm_routes = wm0010_dapm_routes, | 800 | .num_dapm_widgets = ARRAY_SIZE(wm0010_dapm_widgets), |
801 | .num_dapm_routes = ARRAY_SIZE(wm0010_dapm_routes), | 801 | .dapm_routes = wm0010_dapm_routes, |
802 | .num_dapm_routes = ARRAY_SIZE(wm0010_dapm_routes), | ||
803 | }, | ||
802 | }; | 804 | }; |
803 | 805 | ||
804 | #define WM0010_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) | 806 | #define WM0010_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) |
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c index ec45c5b220b1..cf5f0580df6a 100644 --- a/sound/soc/codecs/wm1250-ev1.c +++ b/sound/soc/codecs/wm1250-ev1.c | |||
@@ -141,12 +141,13 @@ static struct snd_soc_dai_driver wm1250_ev1_dai = { | |||
141 | .ops = &wm1250_ev1_ops, | 141 | .ops = &wm1250_ev1_ops, |
142 | }; | 142 | }; |
143 | 143 | ||
144 | static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = { | 144 | static const struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = { |
145 | .dapm_widgets = wm1250_ev1_dapm_widgets, | 145 | .component_driver = { |
146 | .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets), | 146 | .dapm_widgets = wm1250_ev1_dapm_widgets, |
147 | .dapm_routes = wm1250_ev1_dapm_routes, | 147 | .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets), |
148 | .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes), | 148 | .dapm_routes = wm1250_ev1_dapm_routes, |
149 | 149 | .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes), | |
150 | }, | ||
150 | .set_bias_level = wm1250_ev1_set_bias_level, | 151 | .set_bias_level = wm1250_ev1_set_bias_level, |
151 | .idle_bias_off = true, | 152 | .idle_bias_off = true, |
152 | }; | 153 | }; |
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index f2664396be6f..23cde3a0dc11 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -799,18 +799,20 @@ static int wm2000_remove(struct snd_soc_codec *codec) | |||
799 | return wm2000_anc_transition(wm2000, ANC_OFF); | 799 | return wm2000_anc_transition(wm2000, ANC_OFF); |
800 | } | 800 | } |
801 | 801 | ||
802 | static struct snd_soc_codec_driver soc_codec_dev_wm2000 = { | 802 | static const struct snd_soc_codec_driver soc_codec_dev_wm2000 = { |
803 | .probe = wm2000_probe, | 803 | .probe = wm2000_probe, |
804 | .remove = wm2000_remove, | 804 | .remove = wm2000_remove, |
805 | .suspend = wm2000_suspend, | 805 | .suspend = wm2000_suspend, |
806 | .resume = wm2000_resume, | 806 | .resume = wm2000_resume, |
807 | 807 | ||
808 | .dapm_widgets = wm2000_dapm_widgets, | 808 | .component_driver = { |
809 | .num_dapm_widgets = ARRAY_SIZE(wm2000_dapm_widgets), | 809 | .controls = wm2000_controls, |
810 | .dapm_routes = wm2000_audio_map, | 810 | .num_controls = ARRAY_SIZE(wm2000_controls), |
811 | .num_dapm_routes = ARRAY_SIZE(wm2000_audio_map), | 811 | .dapm_widgets = wm2000_dapm_widgets, |
812 | .controls = wm2000_controls, | 812 | .num_dapm_widgets = ARRAY_SIZE(wm2000_dapm_widgets), |
813 | .num_controls = ARRAY_SIZE(wm2000_controls), | 813 | .dapm_routes = wm2000_audio_map, |
814 | .num_dapm_routes = ARRAY_SIZE(wm2000_audio_map), | ||
815 | }, | ||
814 | }; | 816 | }; |
815 | 817 | ||
816 | static int wm2000_i2c_probe(struct i2c_client *i2c, | 818 | static int wm2000_i2c_probe(struct i2c_client *i2c, |
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index fd1439ecb50a..606bf88abfc4 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c | |||
@@ -2103,7 +2103,7 @@ static struct snd_soc_dai_driver wm2200_dai = { | |||
2103 | .ops = &wm2200_dai_ops, | 2103 | .ops = &wm2200_dai_ops, |
2104 | }; | 2104 | }; |
2105 | 2105 | ||
2106 | static struct snd_soc_codec_driver soc_codec_wm2200 = { | 2106 | static const struct snd_soc_codec_driver soc_codec_wm2200 = { |
2107 | .probe = wm2200_probe, | 2107 | .probe = wm2200_probe, |
2108 | 2108 | ||
2109 | .idle_bias_off = true, | 2109 | .idle_bias_off = true, |
@@ -2111,12 +2111,14 @@ static struct snd_soc_codec_driver soc_codec_wm2200 = { | |||
2111 | .set_sysclk = wm2200_set_sysclk, | 2111 | .set_sysclk = wm2200_set_sysclk, |
2112 | .set_pll = wm2200_set_fll, | 2112 | .set_pll = wm2200_set_fll, |
2113 | 2113 | ||
2114 | .controls = wm2200_snd_controls, | 2114 | .component_driver = { |
2115 | .num_controls = ARRAY_SIZE(wm2200_snd_controls), | 2115 | .controls = wm2200_snd_controls, |
2116 | .dapm_widgets = wm2200_dapm_widgets, | 2116 | .num_controls = ARRAY_SIZE(wm2200_snd_controls), |
2117 | .num_dapm_widgets = ARRAY_SIZE(wm2200_dapm_widgets), | 2117 | .dapm_widgets = wm2200_dapm_widgets, |
2118 | .dapm_routes = wm2200_dapm_routes, | 2118 | .num_dapm_widgets = ARRAY_SIZE(wm2200_dapm_widgets), |
2119 | .num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes), | 2119 | .dapm_routes = wm2200_dapm_routes, |
2120 | .num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes), | ||
2121 | }, | ||
2120 | }; | 2122 | }; |
2121 | 2123 | ||
2122 | static irqreturn_t wm2200_irq(int irq, void *data) | 2124 | static irqreturn_t wm2200_irq(int irq, void *data) |
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 512a9d25fe6f..560575000cc5 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c | |||
@@ -2285,7 +2285,7 @@ static int wm5100_gpio_direction_in(struct gpio_chip *chip, unsigned offset) | |||
2285 | (1 << WM5100_GP1_DIR_SHIFT)); | 2285 | (1 << WM5100_GP1_DIR_SHIFT)); |
2286 | } | 2286 | } |
2287 | 2287 | ||
2288 | static struct gpio_chip wm5100_template_chip = { | 2288 | static const struct gpio_chip wm5100_template_chip = { |
2289 | .label = "wm5100", | 2289 | .label = "wm5100", |
2290 | .owner = THIS_MODULE, | 2290 | .owner = THIS_MODULE, |
2291 | .direction_output = wm5100_gpio_direction_out, | 2291 | .direction_output = wm5100_gpio_direction_out, |
@@ -2381,7 +2381,7 @@ static int wm5100_remove(struct snd_soc_codec *codec) | |||
2381 | return 0; | 2381 | return 0; |
2382 | } | 2382 | } |
2383 | 2383 | ||
2384 | static struct snd_soc_codec_driver soc_codec_dev_wm5100 = { | 2384 | static const struct snd_soc_codec_driver soc_codec_dev_wm5100 = { |
2385 | .probe = wm5100_probe, | 2385 | .probe = wm5100_probe, |
2386 | .remove = wm5100_remove, | 2386 | .remove = wm5100_remove, |
2387 | 2387 | ||
@@ -2390,12 +2390,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5100 = { | |||
2390 | .idle_bias_off = 1, | 2390 | .idle_bias_off = 1, |
2391 | 2391 | ||
2392 | .seq_notifier = wm5100_seq_notifier, | 2392 | .seq_notifier = wm5100_seq_notifier, |
2393 | .controls = wm5100_snd_controls, | 2393 | .component_driver = { |
2394 | .num_controls = ARRAY_SIZE(wm5100_snd_controls), | 2394 | .controls = wm5100_snd_controls, |
2395 | .dapm_widgets = wm5100_dapm_widgets, | 2395 | .num_controls = ARRAY_SIZE(wm5100_snd_controls), |
2396 | .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets), | 2396 | .dapm_widgets = wm5100_dapm_widgets, |
2397 | .dapm_routes = wm5100_dapm_routes, | 2397 | .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets), |
2398 | .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes), | 2398 | .dapm_routes = wm5100_dapm_routes, |
2399 | .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes), | ||
2400 | }, | ||
2399 | }; | 2401 | }; |
2400 | 2402 | ||
2401 | static const struct regmap_config wm5100_regmap = { | 2403 | static const struct regmap_config wm5100_regmap = { |
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 846deed6af41..93876c6d48ee 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
@@ -1521,6 +1521,16 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { | |||
1521 | { "IN3L", NULL, "SYSCLK" }, | 1521 | { "IN3L", NULL, "SYSCLK" }, |
1522 | { "IN3R", NULL, "SYSCLK" }, | 1522 | { "IN3R", NULL, "SYSCLK" }, |
1523 | 1523 | ||
1524 | { "ASRC1L", NULL, "SYSCLK" }, | ||
1525 | { "ASRC1R", NULL, "SYSCLK" }, | ||
1526 | { "ASRC2L", NULL, "SYSCLK" }, | ||
1527 | { "ASRC2R", NULL, "SYSCLK" }, | ||
1528 | |||
1529 | { "ASRC1L", NULL, "ASYNCCLK" }, | ||
1530 | { "ASRC1R", NULL, "ASYNCCLK" }, | ||
1531 | { "ASRC2L", NULL, "ASYNCCLK" }, | ||
1532 | { "ASRC2R", NULL, "ASYNCCLK" }, | ||
1533 | |||
1524 | { "MICBIAS1", NULL, "MICVDD" }, | 1534 | { "MICBIAS1", NULL, "MICVDD" }, |
1525 | { "MICBIAS2", NULL, "MICVDD" }, | 1535 | { "MICBIAS2", NULL, "MICVDD" }, |
1526 | { "MICBIAS3", NULL, "MICVDD" }, | 1536 | { "MICBIAS3", NULL, "MICVDD" }, |
@@ -1600,7 +1610,6 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { | |||
1600 | { "Slim3 Capture", NULL, "SYSCLK" }, | 1610 | { "Slim3 Capture", NULL, "SYSCLK" }, |
1601 | 1611 | ||
1602 | { "Audio Trace DSP", NULL, "DSP1" }, | 1612 | { "Audio Trace DSP", NULL, "DSP1" }, |
1603 | { "Audio Trace DSP", NULL, "SYSCLK" }, | ||
1604 | 1613 | ||
1605 | { "IN1L PGA", NULL, "IN1L" }, | 1614 | { "IN1L PGA", NULL, "IN1L" }, |
1606 | { "IN1R PGA", NULL, "IN1R" }, | 1615 | { "IN1R PGA", NULL, "IN1R" }, |
@@ -1990,7 +1999,7 @@ static struct regmap *wm5102_get_regmap(struct device *dev) | |||
1990 | return priv->core.arizona->regmap; | 1999 | return priv->core.arizona->regmap; |
1991 | } | 2000 | } |
1992 | 2001 | ||
1993 | static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { | 2002 | static const struct snd_soc_codec_driver soc_codec_dev_wm5102 = { |
1994 | .probe = wm5102_codec_probe, | 2003 | .probe = wm5102_codec_probe, |
1995 | .remove = wm5102_codec_remove, | 2004 | .remove = wm5102_codec_remove, |
1996 | .get_regmap = wm5102_get_regmap, | 2005 | .get_regmap = wm5102_get_regmap, |
@@ -2000,12 +2009,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { | |||
2000 | .set_sysclk = arizona_set_sysclk, | 2009 | .set_sysclk = arizona_set_sysclk, |
2001 | .set_pll = wm5102_set_fll, | 2010 | .set_pll = wm5102_set_fll, |
2002 | 2011 | ||
2003 | .controls = wm5102_snd_controls, | 2012 | .component_driver = { |
2004 | .num_controls = ARRAY_SIZE(wm5102_snd_controls), | 2013 | .controls = wm5102_snd_controls, |
2005 | .dapm_widgets = wm5102_dapm_widgets, | 2014 | .num_controls = ARRAY_SIZE(wm5102_snd_controls), |
2006 | .num_dapm_widgets = ARRAY_SIZE(wm5102_dapm_widgets), | 2015 | .dapm_widgets = wm5102_dapm_widgets, |
2007 | .dapm_routes = wm5102_dapm_routes, | 2016 | .num_dapm_widgets = ARRAY_SIZE(wm5102_dapm_widgets), |
2008 | .num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes), | 2017 | .dapm_routes = wm5102_dapm_routes, |
2018 | .num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes), | ||
2019 | }, | ||
2009 | }; | 2020 | }; |
2010 | 2021 | ||
2011 | static struct snd_compr_ops wm5102_compr_ops = { | 2022 | static struct snd_compr_ops wm5102_compr_ops = { |
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 156547026a40..06bae3b23fce 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
@@ -1745,6 +1745,16 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { | |||
1745 | { "IN4L", NULL, "SYSCLK" }, | 1745 | { "IN4L", NULL, "SYSCLK" }, |
1746 | { "IN4R", NULL, "SYSCLK" }, | 1746 | { "IN4R", NULL, "SYSCLK" }, |
1747 | 1747 | ||
1748 | { "ASRC1L", NULL, "SYSCLK" }, | ||
1749 | { "ASRC1R", NULL, "SYSCLK" }, | ||
1750 | { "ASRC2L", NULL, "SYSCLK" }, | ||
1751 | { "ASRC2R", NULL, "SYSCLK" }, | ||
1752 | |||
1753 | { "ASRC1L", NULL, "ASYNCCLK" }, | ||
1754 | { "ASRC1R", NULL, "ASYNCCLK" }, | ||
1755 | { "ASRC2L", NULL, "ASYNCCLK" }, | ||
1756 | { "ASRC2R", NULL, "ASYNCCLK" }, | ||
1757 | |||
1748 | { "MICBIAS1", NULL, "MICVDD" }, | 1758 | { "MICBIAS1", NULL, "MICVDD" }, |
1749 | { "MICBIAS2", NULL, "MICVDD" }, | 1759 | { "MICBIAS2", NULL, "MICVDD" }, |
1750 | { "MICBIAS3", NULL, "MICVDD" }, | 1760 | { "MICBIAS3", NULL, "MICVDD" }, |
@@ -1832,10 +1842,8 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { | |||
1832 | { "Slim3 Capture", NULL, "SYSCLK" }, | 1842 | { "Slim3 Capture", NULL, "SYSCLK" }, |
1833 | 1843 | ||
1834 | { "Voice Control DSP", NULL, "DSP3" }, | 1844 | { "Voice Control DSP", NULL, "DSP3" }, |
1835 | { "Voice Control DSP", NULL, "SYSCLK" }, | ||
1836 | 1845 | ||
1837 | { "Audio Trace DSP", NULL, "DSP1" }, | 1846 | { "Audio Trace DSP", NULL, "DSP1" }, |
1838 | { "Audio Trace DSP", NULL, "SYSCLK" }, | ||
1839 | 1847 | ||
1840 | { "IN1L PGA", NULL, "IN1L" }, | 1848 | { "IN1L PGA", NULL, "IN1L" }, |
1841 | { "IN1R PGA", NULL, "IN1R" }, | 1849 | { "IN1R PGA", NULL, "IN1R" }, |
@@ -2347,7 +2355,7 @@ static struct regmap *wm5110_get_regmap(struct device *dev) | |||
2347 | return priv->core.arizona->regmap; | 2355 | return priv->core.arizona->regmap; |
2348 | } | 2356 | } |
2349 | 2357 | ||
2350 | static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { | 2358 | static const struct snd_soc_codec_driver soc_codec_dev_wm5110 = { |
2351 | .probe = wm5110_codec_probe, | 2359 | .probe = wm5110_codec_probe, |
2352 | .remove = wm5110_codec_remove, | 2360 | .remove = wm5110_codec_remove, |
2353 | .get_regmap = wm5110_get_regmap, | 2361 | .get_regmap = wm5110_get_regmap, |
@@ -2357,12 +2365,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { | |||
2357 | .set_sysclk = arizona_set_sysclk, | 2365 | .set_sysclk = arizona_set_sysclk, |
2358 | .set_pll = wm5110_set_fll, | 2366 | .set_pll = wm5110_set_fll, |
2359 | 2367 | ||
2360 | .controls = wm5110_snd_controls, | 2368 | .component_driver = { |
2361 | .num_controls = ARRAY_SIZE(wm5110_snd_controls), | 2369 | .controls = wm5110_snd_controls, |
2362 | .dapm_widgets = wm5110_dapm_widgets, | 2370 | .num_controls = ARRAY_SIZE(wm5110_snd_controls), |
2363 | .num_dapm_widgets = ARRAY_SIZE(wm5110_dapm_widgets), | 2371 | .dapm_widgets = wm5110_dapm_widgets, |
2364 | .dapm_routes = wm5110_dapm_routes, | 2372 | .num_dapm_widgets = ARRAY_SIZE(wm5110_dapm_widgets), |
2365 | .num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes), | 2373 | .dapm_routes = wm5110_dapm_routes, |
2374 | .num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes), | ||
2375 | }, | ||
2366 | }; | 2376 | }; |
2367 | 2377 | ||
2368 | static struct snd_compr_ops wm5110_compr_ops = { | 2378 | static struct snd_compr_ops wm5110_compr_ops = { |
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index ffbf3df8ae97..2efc5b41ad0f 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
@@ -1587,19 +1587,21 @@ static struct regmap *wm8350_get_regmap(struct device *dev) | |||
1587 | return wm8350->regmap; | 1587 | return wm8350->regmap; |
1588 | } | 1588 | } |
1589 | 1589 | ||
1590 | static struct snd_soc_codec_driver soc_codec_dev_wm8350 = { | 1590 | static const struct snd_soc_codec_driver soc_codec_dev_wm8350 = { |
1591 | .probe = wm8350_codec_probe, | 1591 | .probe = wm8350_codec_probe, |
1592 | .remove = wm8350_codec_remove, | 1592 | .remove = wm8350_codec_remove, |
1593 | .get_regmap = wm8350_get_regmap, | 1593 | .get_regmap = wm8350_get_regmap, |
1594 | .set_bias_level = wm8350_set_bias_level, | 1594 | .set_bias_level = wm8350_set_bias_level, |
1595 | .suspend_bias_off = true, | 1595 | .suspend_bias_off = true, |
1596 | 1596 | ||
1597 | .controls = wm8350_snd_controls, | 1597 | .component_driver = { |
1598 | .num_controls = ARRAY_SIZE(wm8350_snd_controls), | 1598 | .controls = wm8350_snd_controls, |
1599 | .dapm_widgets = wm8350_dapm_widgets, | 1599 | .num_controls = ARRAY_SIZE(wm8350_snd_controls), |
1600 | .num_dapm_widgets = ARRAY_SIZE(wm8350_dapm_widgets), | 1600 | .dapm_widgets = wm8350_dapm_widgets, |
1601 | .dapm_routes = wm8350_dapm_routes, | 1601 | .num_dapm_widgets = ARRAY_SIZE(wm8350_dapm_widgets), |
1602 | .num_dapm_routes = ARRAY_SIZE(wm8350_dapm_routes), | 1602 | .dapm_routes = wm8350_dapm_routes, |
1603 | .num_dapm_routes = ARRAY_SIZE(wm8350_dapm_routes), | ||
1604 | }, | ||
1603 | }; | 1605 | }; |
1604 | 1606 | ||
1605 | static int wm8350_probe(struct platform_device *pdev) | 1607 | static int wm8350_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index b1d346aa4696..6c59fb933bd6 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c | |||
@@ -1332,19 +1332,21 @@ static struct regmap *wm8400_get_regmap(struct device *dev) | |||
1332 | return wm8400->regmap; | 1332 | return wm8400->regmap; |
1333 | } | 1333 | } |
1334 | 1334 | ||
1335 | static struct snd_soc_codec_driver soc_codec_dev_wm8400 = { | 1335 | static const struct snd_soc_codec_driver soc_codec_dev_wm8400 = { |
1336 | .probe = wm8400_codec_probe, | 1336 | .probe = wm8400_codec_probe, |
1337 | .remove = wm8400_codec_remove, | 1337 | .remove = wm8400_codec_remove, |
1338 | .get_regmap = wm8400_get_regmap, | 1338 | .get_regmap = wm8400_get_regmap, |
1339 | .set_bias_level = wm8400_set_bias_level, | 1339 | .set_bias_level = wm8400_set_bias_level, |
1340 | .suspend_bias_off = true, | 1340 | .suspend_bias_off = true, |
1341 | 1341 | ||
1342 | .controls = wm8400_snd_controls, | 1342 | .component_driver = { |
1343 | .num_controls = ARRAY_SIZE(wm8400_snd_controls), | 1343 | .controls = wm8400_snd_controls, |
1344 | .dapm_widgets = wm8400_dapm_widgets, | 1344 | .num_controls = ARRAY_SIZE(wm8400_snd_controls), |
1345 | .num_dapm_widgets = ARRAY_SIZE(wm8400_dapm_widgets), | 1345 | .dapm_widgets = wm8400_dapm_widgets, |
1346 | .dapm_routes = wm8400_dapm_routes, | 1346 | .num_dapm_widgets = ARRAY_SIZE(wm8400_dapm_widgets), |
1347 | .num_dapm_routes = ARRAY_SIZE(wm8400_dapm_routes), | 1347 | .dapm_routes = wm8400_dapm_routes, |
1348 | .num_dapm_routes = ARRAY_SIZE(wm8400_dapm_routes), | ||
1349 | }, | ||
1348 | }; | 1350 | }; |
1349 | 1351 | ||
1350 | static int wm8400_probe(struct platform_device *pdev) | 1352 | static int wm8400_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 99e40e629cca..119ceac684ae 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c | |||
@@ -581,17 +581,19 @@ static int wm8510_probe(struct snd_soc_codec *codec) | |||
581 | return 0; | 581 | return 0; |
582 | } | 582 | } |
583 | 583 | ||
584 | static struct snd_soc_codec_driver soc_codec_dev_wm8510 = { | 584 | static const struct snd_soc_codec_driver soc_codec_dev_wm8510 = { |
585 | .probe = wm8510_probe, | 585 | .probe = wm8510_probe, |
586 | .set_bias_level = wm8510_set_bias_level, | 586 | .set_bias_level = wm8510_set_bias_level, |
587 | .suspend_bias_off = true, | 587 | .suspend_bias_off = true, |
588 | 588 | ||
589 | .controls = wm8510_snd_controls, | 589 | .component_driver = { |
590 | .num_controls = ARRAY_SIZE(wm8510_snd_controls), | 590 | .controls = wm8510_snd_controls, |
591 | .dapm_widgets = wm8510_dapm_widgets, | 591 | .num_controls = ARRAY_SIZE(wm8510_snd_controls), |
592 | .num_dapm_widgets = ARRAY_SIZE(wm8510_dapm_widgets), | 592 | .dapm_widgets = wm8510_dapm_widgets, |
593 | .dapm_routes = wm8510_dapm_routes, | 593 | .num_dapm_widgets = ARRAY_SIZE(wm8510_dapm_widgets), |
594 | .num_dapm_routes = ARRAY_SIZE(wm8510_dapm_routes), | 594 | .dapm_routes = wm8510_dapm_routes, |
595 | .num_dapm_routes = ARRAY_SIZE(wm8510_dapm_routes), | ||
596 | }, | ||
595 | }; | 597 | }; |
596 | 598 | ||
597 | static const struct of_device_id wm8510_of_match[] = { | 599 | static const struct of_device_id wm8510_of_match[] = { |
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index aa287a3965e7..deb2e075428e 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c | |||
@@ -413,17 +413,19 @@ static int wm8523_probe(struct snd_soc_codec *codec) | |||
413 | return 0; | 413 | return 0; |
414 | } | 414 | } |
415 | 415 | ||
416 | static struct snd_soc_codec_driver soc_codec_dev_wm8523 = { | 416 | static const struct snd_soc_codec_driver soc_codec_dev_wm8523 = { |
417 | .probe = wm8523_probe, | 417 | .probe = wm8523_probe, |
418 | .set_bias_level = wm8523_set_bias_level, | 418 | .set_bias_level = wm8523_set_bias_level, |
419 | .suspend_bias_off = true, | 419 | .suspend_bias_off = true, |
420 | 420 | ||
421 | .controls = wm8523_controls, | 421 | .component_driver = { |
422 | .num_controls = ARRAY_SIZE(wm8523_controls), | 422 | .controls = wm8523_controls, |
423 | .dapm_widgets = wm8523_dapm_widgets, | 423 | .num_controls = ARRAY_SIZE(wm8523_controls), |
424 | .num_dapm_widgets = ARRAY_SIZE(wm8523_dapm_widgets), | 424 | .dapm_widgets = wm8523_dapm_widgets, |
425 | .dapm_routes = wm8523_dapm_routes, | 425 | .num_dapm_widgets = ARRAY_SIZE(wm8523_dapm_widgets), |
426 | .num_dapm_routes = ARRAY_SIZE(wm8523_dapm_routes), | 426 | .dapm_routes = wm8523_dapm_routes, |
427 | .num_dapm_routes = ARRAY_SIZE(wm8523_dapm_routes), | ||
428 | }, | ||
427 | }; | 429 | }; |
428 | 430 | ||
429 | static const struct of_device_id wm8523_of_match[] = { | 431 | static const struct of_device_id wm8523_of_match[] = { |
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 66602bf02f6e..faa7287a5253 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c | |||
@@ -899,17 +899,19 @@ static int wm8580_remove(struct snd_soc_codec *codec) | |||
899 | return 0; | 899 | return 0; |
900 | } | 900 | } |
901 | 901 | ||
902 | static struct snd_soc_codec_driver soc_codec_dev_wm8580 = { | 902 | static const struct snd_soc_codec_driver soc_codec_dev_wm8580 = { |
903 | .probe = wm8580_probe, | 903 | .probe = wm8580_probe, |
904 | .remove = wm8580_remove, | 904 | .remove = wm8580_remove, |
905 | .set_bias_level = wm8580_set_bias_level, | 905 | .set_bias_level = wm8580_set_bias_level, |
906 | 906 | ||
907 | .controls = wm8580_snd_controls, | 907 | .component_driver = { |
908 | .num_controls = ARRAY_SIZE(wm8580_snd_controls), | 908 | .controls = wm8580_snd_controls, |
909 | .dapm_widgets = wm8580_dapm_widgets, | 909 | .num_controls = ARRAY_SIZE(wm8580_snd_controls), |
910 | .num_dapm_widgets = ARRAY_SIZE(wm8580_dapm_widgets), | 910 | .dapm_widgets = wm8580_dapm_widgets, |
911 | .dapm_routes = wm8580_dapm_routes, | 911 | .num_dapm_widgets = ARRAY_SIZE(wm8580_dapm_widgets), |
912 | .num_dapm_routes = ARRAY_SIZE(wm8580_dapm_routes), | 912 | .dapm_routes = wm8580_dapm_routes, |
913 | .num_dapm_routes = ARRAY_SIZE(wm8580_dapm_routes), | ||
914 | }, | ||
913 | }; | 915 | }; |
914 | 916 | ||
915 | static const struct of_device_id wm8580_of_match[] = { | 917 | static const struct of_device_id wm8580_of_match[] = { |
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index c759ec068e97..2b376c9c99af 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c | |||
@@ -367,17 +367,19 @@ static int wm8711_probe(struct snd_soc_codec *codec) | |||
367 | 367 | ||
368 | } | 368 | } |
369 | 369 | ||
370 | static struct snd_soc_codec_driver soc_codec_dev_wm8711 = { | 370 | static const struct snd_soc_codec_driver soc_codec_dev_wm8711 = { |
371 | .probe = wm8711_probe, | 371 | .probe = wm8711_probe, |
372 | .set_bias_level = wm8711_set_bias_level, | 372 | .set_bias_level = wm8711_set_bias_level, |
373 | .suspend_bias_off = true, | 373 | .suspend_bias_off = true, |
374 | 374 | ||
375 | .controls = wm8711_snd_controls, | 375 | .component_driver = { |
376 | .num_controls = ARRAY_SIZE(wm8711_snd_controls), | 376 | .controls = wm8711_snd_controls, |
377 | .dapm_widgets = wm8711_dapm_widgets, | 377 | .num_controls = ARRAY_SIZE(wm8711_snd_controls), |
378 | .num_dapm_widgets = ARRAY_SIZE(wm8711_dapm_widgets), | 378 | .dapm_widgets = wm8711_dapm_widgets, |
379 | .dapm_routes = wm8711_intercon, | 379 | .num_dapm_widgets = ARRAY_SIZE(wm8711_dapm_widgets), |
380 | .num_dapm_routes = ARRAY_SIZE(wm8711_intercon), | 380 | .dapm_routes = wm8711_intercon, |
381 | .num_dapm_routes = ARRAY_SIZE(wm8711_intercon), | ||
382 | }, | ||
381 | }; | 383 | }; |
382 | 384 | ||
383 | static const struct of_device_id wm8711_of_match[] = { | 385 | static const struct of_device_id wm8711_of_match[] = { |
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c index bb25a75f92a2..7fde077a014b 100644 --- a/sound/soc/codecs/wm8727.c +++ b/sound/soc/codecs/wm8727.c | |||
@@ -53,11 +53,13 @@ static struct snd_soc_dai_driver wm8727_dai = { | |||
53 | }, | 53 | }, |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static struct snd_soc_codec_driver soc_codec_dev_wm8727 = { | 56 | static const struct snd_soc_codec_driver soc_codec_dev_wm8727 = { |
57 | .dapm_widgets = wm8727_dapm_widgets, | 57 | .component_driver = { |
58 | .num_dapm_widgets = ARRAY_SIZE(wm8727_dapm_widgets), | 58 | .dapm_widgets = wm8727_dapm_widgets, |
59 | .dapm_routes = wm8727_dapm_routes, | 59 | .num_dapm_widgets = ARRAY_SIZE(wm8727_dapm_widgets), |
60 | .num_dapm_routes = ARRAY_SIZE(wm8727_dapm_routes), | 60 | .dapm_routes = wm8727_dapm_routes, |
61 | .num_dapm_routes = ARRAY_SIZE(wm8727_dapm_routes), | ||
62 | }, | ||
61 | }; | 63 | }; |
62 | 64 | ||
63 | static int wm8727_probe(struct platform_device *pdev) | 65 | static int wm8727_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 1564e6926527..797cc6e7c70f 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c | |||
@@ -211,16 +211,18 @@ static struct snd_soc_dai_driver wm8728_dai = { | |||
211 | .ops = &wm8728_dai_ops, | 211 | .ops = &wm8728_dai_ops, |
212 | }; | 212 | }; |
213 | 213 | ||
214 | static struct snd_soc_codec_driver soc_codec_dev_wm8728 = { | 214 | static const struct snd_soc_codec_driver soc_codec_dev_wm8728 = { |
215 | .set_bias_level = wm8728_set_bias_level, | 215 | .set_bias_level = wm8728_set_bias_level, |
216 | .suspend_bias_off = true, | 216 | .suspend_bias_off = true, |
217 | 217 | ||
218 | .controls = wm8728_snd_controls, | 218 | .component_driver = { |
219 | .num_controls = ARRAY_SIZE(wm8728_snd_controls), | 219 | .controls = wm8728_snd_controls, |
220 | .dapm_widgets = wm8728_dapm_widgets, | 220 | .num_controls = ARRAY_SIZE(wm8728_snd_controls), |
221 | .num_dapm_widgets = ARRAY_SIZE(wm8728_dapm_widgets), | 221 | .dapm_widgets = wm8728_dapm_widgets, |
222 | .dapm_routes = wm8728_intercon, | 222 | .num_dapm_widgets = ARRAY_SIZE(wm8728_dapm_widgets), |
223 | .num_dapm_routes = ARRAY_SIZE(wm8728_intercon), | 223 | .dapm_routes = wm8728_intercon, |
224 | .num_dapm_routes = ARRAY_SIZE(wm8728_intercon), | ||
225 | }, | ||
224 | }; | 226 | }; |
225 | 227 | ||
226 | static const struct of_device_id wm8728_of_match[] = { | 228 | static const struct of_device_id wm8728_of_match[] = { |
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index d18261a44256..4f9a1eb28120 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
@@ -628,16 +628,18 @@ err_regulator_enable: | |||
628 | return ret; | 628 | return ret; |
629 | } | 629 | } |
630 | 630 | ||
631 | static struct snd_soc_codec_driver soc_codec_dev_wm8731 = { | 631 | static const struct snd_soc_codec_driver soc_codec_dev_wm8731 = { |
632 | .set_bias_level = wm8731_set_bias_level, | 632 | .set_bias_level = wm8731_set_bias_level, |
633 | .suspend_bias_off = true, | 633 | .suspend_bias_off = true, |
634 | 634 | ||
635 | .dapm_widgets = wm8731_dapm_widgets, | 635 | .component_driver = { |
636 | .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), | 636 | .controls = wm8731_snd_controls, |
637 | .dapm_routes = wm8731_intercon, | 637 | .num_controls = ARRAY_SIZE(wm8731_snd_controls), |
638 | .num_dapm_routes = ARRAY_SIZE(wm8731_intercon), | 638 | .dapm_widgets = wm8731_dapm_widgets, |
639 | .controls = wm8731_snd_controls, | 639 | .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), |
640 | .num_controls = ARRAY_SIZE(wm8731_snd_controls), | 640 | .dapm_routes = wm8731_intercon, |
641 | .num_dapm_routes = ARRAY_SIZE(wm8731_intercon), | ||
642 | }, | ||
641 | }; | 643 | }; |
642 | 644 | ||
643 | static const struct of_device_id wm8731_of_match[] = { | 645 | static const struct of_device_id wm8731_of_match[] = { |
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index e7807601e675..f0cb1c4afe3c 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c | |||
@@ -573,17 +573,19 @@ err_get: | |||
573 | return ret; | 573 | return ret; |
574 | } | 574 | } |
575 | 575 | ||
576 | static struct snd_soc_codec_driver soc_codec_dev_wm8737 = { | 576 | static const struct snd_soc_codec_driver soc_codec_dev_wm8737 = { |
577 | .probe = wm8737_probe, | 577 | .probe = wm8737_probe, |
578 | .set_bias_level = wm8737_set_bias_level, | 578 | .set_bias_level = wm8737_set_bias_level, |
579 | .suspend_bias_off = true, | 579 | .suspend_bias_off = true, |
580 | 580 | ||
581 | .controls = wm8737_snd_controls, | 581 | .component_driver = { |
582 | .num_controls = ARRAY_SIZE(wm8737_snd_controls), | 582 | .controls = wm8737_snd_controls, |
583 | .dapm_widgets = wm8737_dapm_widgets, | 583 | .num_controls = ARRAY_SIZE(wm8737_snd_controls), |
584 | .num_dapm_widgets = ARRAY_SIZE(wm8737_dapm_widgets), | 584 | .dapm_widgets = wm8737_dapm_widgets, |
585 | .dapm_routes = intercon, | 585 | .num_dapm_widgets = ARRAY_SIZE(wm8737_dapm_widgets), |
586 | .num_dapm_routes = ARRAY_SIZE(intercon), | 586 | .dapm_routes = intercon, |
587 | .num_dapm_routes = ARRAY_SIZE(intercon), | ||
588 | }, | ||
587 | }; | 589 | }; |
588 | 590 | ||
589 | static const struct of_device_id wm8737_of_match[] = { | 591 | static const struct of_device_id wm8737_of_match[] = { |
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 36ef91fe0511..565d477cd790 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c | |||
@@ -497,15 +497,17 @@ static int wm8741_remove(struct snd_soc_codec *codec) | |||
497 | return 0; | 497 | return 0; |
498 | } | 498 | } |
499 | 499 | ||
500 | static struct snd_soc_codec_driver soc_codec_dev_wm8741 = { | 500 | static const struct snd_soc_codec_driver soc_codec_dev_wm8741 = { |
501 | .probe = wm8741_probe, | 501 | .probe = wm8741_probe, |
502 | .remove = wm8741_remove, | 502 | .remove = wm8741_remove, |
503 | .resume = wm8741_resume, | 503 | .resume = wm8741_resume, |
504 | 504 | ||
505 | .dapm_widgets = wm8741_dapm_widgets, | 505 | .component_driver = { |
506 | .num_dapm_widgets = ARRAY_SIZE(wm8741_dapm_widgets), | 506 | .dapm_widgets = wm8741_dapm_widgets, |
507 | .dapm_routes = wm8741_dapm_routes, | 507 | .num_dapm_widgets = ARRAY_SIZE(wm8741_dapm_widgets), |
508 | .num_dapm_routes = ARRAY_SIZE(wm8741_dapm_routes), | 508 | .dapm_routes = wm8741_dapm_routes, |
509 | .num_dapm_routes = ARRAY_SIZE(wm8741_dapm_routes), | ||
510 | }, | ||
509 | }; | 511 | }; |
510 | 512 | ||
511 | static const struct of_device_id wm8741_of_match[] = { | 513 | static const struct of_device_id wm8741_of_match[] = { |
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index bd9dcd2161bc..0da2bbaf06d1 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c | |||
@@ -708,17 +708,19 @@ static int wm8750_probe(struct snd_soc_codec *codec) | |||
708 | return ret; | 708 | return ret; |
709 | } | 709 | } |
710 | 710 | ||
711 | static struct snd_soc_codec_driver soc_codec_dev_wm8750 = { | 711 | static const struct snd_soc_codec_driver soc_codec_dev_wm8750 = { |
712 | .probe = wm8750_probe, | 712 | .probe = wm8750_probe, |
713 | .set_bias_level = wm8750_set_bias_level, | 713 | .set_bias_level = wm8750_set_bias_level, |
714 | .suspend_bias_off = true, | 714 | .suspend_bias_off = true, |
715 | 715 | ||
716 | .controls = wm8750_snd_controls, | 716 | .component_driver = { |
717 | .num_controls = ARRAY_SIZE(wm8750_snd_controls), | 717 | .controls = wm8750_snd_controls, |
718 | .dapm_widgets = wm8750_dapm_widgets, | 718 | .num_controls = ARRAY_SIZE(wm8750_snd_controls), |
719 | .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), | 719 | .dapm_widgets = wm8750_dapm_widgets, |
720 | .dapm_routes = wm8750_dapm_routes, | 720 | .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), |
721 | .num_dapm_routes = ARRAY_SIZE(wm8750_dapm_routes), | 721 | .dapm_routes = wm8750_dapm_routes, |
722 | .num_dapm_routes = ARRAY_SIZE(wm8750_dapm_routes), | ||
723 | }, | ||
722 | }; | 724 | }; |
723 | 725 | ||
724 | static const struct of_device_id wm8750_of_match[] = { | 726 | static const struct of_device_id wm8750_of_match[] = { |
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index cdcc91282e8a..9bdf5447f6f6 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c | |||
@@ -1478,18 +1478,20 @@ static int wm8753_probe(struct snd_soc_codec *codec) | |||
1478 | return 0; | 1478 | return 0; |
1479 | } | 1479 | } |
1480 | 1480 | ||
1481 | static struct snd_soc_codec_driver soc_codec_dev_wm8753 = { | 1481 | static const struct snd_soc_codec_driver soc_codec_dev_wm8753 = { |
1482 | .probe = wm8753_probe, | 1482 | .probe = wm8753_probe, |
1483 | .resume = wm8753_resume, | 1483 | .resume = wm8753_resume, |
1484 | .set_bias_level = wm8753_set_bias_level, | 1484 | .set_bias_level = wm8753_set_bias_level, |
1485 | .suspend_bias_off = true, | 1485 | .suspend_bias_off = true, |
1486 | 1486 | ||
1487 | .controls = wm8753_snd_controls, | 1487 | .component_driver = { |
1488 | .num_controls = ARRAY_SIZE(wm8753_snd_controls), | 1488 | .controls = wm8753_snd_controls, |
1489 | .dapm_widgets = wm8753_dapm_widgets, | 1489 | .num_controls = ARRAY_SIZE(wm8753_snd_controls), |
1490 | .num_dapm_widgets = ARRAY_SIZE(wm8753_dapm_widgets), | 1490 | .dapm_widgets = wm8753_dapm_widgets, |
1491 | .dapm_routes = wm8753_dapm_routes, | 1491 | .num_dapm_widgets = ARRAY_SIZE(wm8753_dapm_widgets), |
1492 | .num_dapm_routes = ARRAY_SIZE(wm8753_dapm_routes), | 1492 | .dapm_routes = wm8753_dapm_routes, |
1493 | .num_dapm_routes = ARRAY_SIZE(wm8753_dapm_routes), | ||
1494 | }, | ||
1493 | }; | 1495 | }; |
1494 | 1496 | ||
1495 | static const struct of_device_id wm8753_of_match[] = { | 1497 | static const struct of_device_id wm8753_of_match[] = { |
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index df6178464b00..d6edcbbdec12 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c | |||
@@ -608,17 +608,19 @@ err_reg_enable: | |||
608 | return ret; | 608 | return ret; |
609 | } | 609 | } |
610 | 610 | ||
611 | static struct snd_soc_codec_driver soc_codec_dev_wm8770 = { | 611 | static const struct snd_soc_codec_driver soc_codec_dev_wm8770 = { |
612 | .probe = wm8770_probe, | 612 | .probe = wm8770_probe, |
613 | .set_bias_level = wm8770_set_bias_level, | 613 | .set_bias_level = wm8770_set_bias_level, |
614 | .idle_bias_off = true, | 614 | .idle_bias_off = true, |
615 | 615 | ||
616 | .controls = wm8770_snd_controls, | 616 | .component_driver = { |
617 | .num_controls = ARRAY_SIZE(wm8770_snd_controls), | 617 | .controls = wm8770_snd_controls, |
618 | .dapm_widgets = wm8770_dapm_widgets, | 618 | .num_controls = ARRAY_SIZE(wm8770_snd_controls), |
619 | .num_dapm_widgets = ARRAY_SIZE(wm8770_dapm_widgets), | 619 | .dapm_widgets = wm8770_dapm_widgets, |
620 | .dapm_routes = wm8770_intercon, | 620 | .num_dapm_widgets = ARRAY_SIZE(wm8770_dapm_widgets), |
621 | .num_dapm_routes = ARRAY_SIZE(wm8770_intercon), | 621 | .dapm_routes = wm8770_intercon, |
622 | .num_dapm_routes = ARRAY_SIZE(wm8770_intercon), | ||
623 | }, | ||
622 | }; | 624 | }; |
623 | 625 | ||
624 | static const struct of_device_id wm8770_of_match[] = { | 626 | static const struct of_device_id wm8770_of_match[] = { |
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 5af44f9a8cf2..ae30480b3976 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c | |||
@@ -425,17 +425,19 @@ static int wm8776_probe(struct snd_soc_codec *codec) | |||
425 | return ret; | 425 | return ret; |
426 | } | 426 | } |
427 | 427 | ||
428 | static struct snd_soc_codec_driver soc_codec_dev_wm8776 = { | 428 | static const struct snd_soc_codec_driver soc_codec_dev_wm8776 = { |
429 | .probe = wm8776_probe, | 429 | .probe = wm8776_probe, |
430 | .set_bias_level = wm8776_set_bias_level, | 430 | .set_bias_level = wm8776_set_bias_level, |
431 | .suspend_bias_off = true, | 431 | .suspend_bias_off = true, |
432 | 432 | ||
433 | .controls = wm8776_snd_controls, | 433 | .component_driver = { |
434 | .num_controls = ARRAY_SIZE(wm8776_snd_controls), | 434 | .controls = wm8776_snd_controls, |
435 | .dapm_widgets = wm8776_dapm_widgets, | 435 | .num_controls = ARRAY_SIZE(wm8776_snd_controls), |
436 | .num_dapm_widgets = ARRAY_SIZE(wm8776_dapm_widgets), | 436 | .dapm_widgets = wm8776_dapm_widgets, |
437 | .dapm_routes = routes, | 437 | .num_dapm_widgets = ARRAY_SIZE(wm8776_dapm_widgets), |
438 | .num_dapm_routes = ARRAY_SIZE(routes), | 438 | .dapm_routes = routes, |
439 | .num_dapm_routes = ARRAY_SIZE(routes), | ||
440 | }, | ||
439 | }; | 441 | }; |
440 | 442 | ||
441 | static const struct of_device_id wm8776_of_match[] = { | 443 | static const struct of_device_id wm8776_of_match[] = { |
diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c index fb55fd845d27..bcda21018505 100644 --- a/sound/soc/codecs/wm8782.c +++ b/sound/soc/codecs/wm8782.c | |||
@@ -50,11 +50,13 @@ static struct snd_soc_dai_driver wm8782_dai = { | |||
50 | }, | 50 | }, |
51 | }; | 51 | }; |
52 | 52 | ||
53 | static struct snd_soc_codec_driver soc_codec_dev_wm8782 = { | 53 | static const struct snd_soc_codec_driver soc_codec_dev_wm8782 = { |
54 | .dapm_widgets = wm8782_dapm_widgets, | 54 | .component_driver = { |
55 | .num_dapm_widgets = ARRAY_SIZE(wm8782_dapm_widgets), | 55 | .dapm_widgets = wm8782_dapm_widgets, |
56 | .dapm_routes = wm8782_dapm_routes, | 56 | .num_dapm_widgets = ARRAY_SIZE(wm8782_dapm_widgets), |
57 | .num_dapm_routes = ARRAY_SIZE(wm8782_dapm_routes), | 57 | .dapm_routes = wm8782_dapm_routes, |
58 | .num_dapm_routes = ARRAY_SIZE(wm8782_dapm_routes), | ||
59 | }, | ||
58 | }; | 60 | }; |
59 | 61 | ||
60 | static int wm8782_probe(struct platform_device *pdev) | 62 | static int wm8782_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 8d914702cae4..af95d648265b 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c | |||
@@ -545,10 +545,12 @@ static struct snd_soc_dai_driver wm8804_dai = { | |||
545 | static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = { | 545 | static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = { |
546 | .idle_bias_off = true, | 546 | .idle_bias_off = true, |
547 | 547 | ||
548 | .dapm_widgets = wm8804_dapm_widgets, | 548 | .component_driver = { |
549 | .num_dapm_widgets = ARRAY_SIZE(wm8804_dapm_widgets), | 549 | .dapm_widgets = wm8804_dapm_widgets, |
550 | .dapm_routes = wm8804_dapm_routes, | 550 | .num_dapm_widgets = ARRAY_SIZE(wm8804_dapm_widgets), |
551 | .num_dapm_routes = ARRAY_SIZE(wm8804_dapm_routes), | 551 | .dapm_routes = wm8804_dapm_routes, |
552 | .num_dapm_routes = ARRAY_SIZE(wm8804_dapm_routes), | ||
553 | }, | ||
552 | }; | 554 | }; |
553 | 555 | ||
554 | const struct regmap_config wm8804_regmap_config = { | 556 | const struct regmap_config wm8804_regmap_config = { |
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 5d8dca88d612..c77b49a29311 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c | |||
@@ -1208,18 +1208,20 @@ static int wm8900_probe(struct snd_soc_codec *codec) | |||
1208 | return 0; | 1208 | return 0; |
1209 | } | 1209 | } |
1210 | 1210 | ||
1211 | static struct snd_soc_codec_driver soc_codec_dev_wm8900 = { | 1211 | static const struct snd_soc_codec_driver soc_codec_dev_wm8900 = { |
1212 | .probe = wm8900_probe, | 1212 | .probe = wm8900_probe, |
1213 | .suspend = wm8900_suspend, | 1213 | .suspend = wm8900_suspend, |
1214 | .resume = wm8900_resume, | 1214 | .resume = wm8900_resume, |
1215 | .set_bias_level = wm8900_set_bias_level, | 1215 | .set_bias_level = wm8900_set_bias_level, |
1216 | 1216 | ||
1217 | .controls = wm8900_snd_controls, | 1217 | .component_driver = { |
1218 | .num_controls = ARRAY_SIZE(wm8900_snd_controls), | 1218 | .controls = wm8900_snd_controls, |
1219 | .dapm_widgets = wm8900_dapm_widgets, | 1219 | .num_controls = ARRAY_SIZE(wm8900_snd_controls), |
1220 | .num_dapm_widgets = ARRAY_SIZE(wm8900_dapm_widgets), | 1220 | .dapm_widgets = wm8900_dapm_widgets, |
1221 | .dapm_routes = wm8900_dapm_routes, | 1221 | .num_dapm_widgets = ARRAY_SIZE(wm8900_dapm_widgets), |
1222 | .num_dapm_routes = ARRAY_SIZE(wm8900_dapm_routes), | 1222 | .dapm_routes = wm8900_dapm_routes, |
1223 | .num_dapm_routes = ARRAY_SIZE(wm8900_dapm_routes), | ||
1224 | }, | ||
1223 | }; | 1225 | }; |
1224 | 1226 | ||
1225 | static const struct regmap_config wm8900_regmap = { | 1227 | static const struct regmap_config wm8900_regmap = { |
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index a26ca490cf31..6e887c2c42b1 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c | |||
@@ -1830,7 +1830,7 @@ static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
1830 | !!value << WM8903_GP1_LVL_SHIFT); | 1830 | !!value << WM8903_GP1_LVL_SHIFT); |
1831 | } | 1831 | } |
1832 | 1832 | ||
1833 | static struct gpio_chip wm8903_template_chip = { | 1833 | static const struct gpio_chip wm8903_template_chip = { |
1834 | .label = "wm8903", | 1834 | .label = "wm8903", |
1835 | .owner = THIS_MODULE, | 1835 | .owner = THIS_MODULE, |
1836 | .request = wm8903_gpio_request, | 1836 | .request = wm8903_gpio_request, |
@@ -1874,18 +1874,20 @@ static void wm8903_free_gpio(struct wm8903_priv *wm8903) | |||
1874 | } | 1874 | } |
1875 | #endif | 1875 | #endif |
1876 | 1876 | ||
1877 | static struct snd_soc_codec_driver soc_codec_dev_wm8903 = { | 1877 | static const struct snd_soc_codec_driver soc_codec_dev_wm8903 = { |
1878 | .resume = wm8903_resume, | 1878 | .resume = wm8903_resume, |
1879 | .set_bias_level = wm8903_set_bias_level, | 1879 | .set_bias_level = wm8903_set_bias_level, |
1880 | .seq_notifier = wm8903_seq_notifier, | 1880 | .seq_notifier = wm8903_seq_notifier, |
1881 | .suspend_bias_off = true, | 1881 | .suspend_bias_off = true, |
1882 | 1882 | ||
1883 | .controls = wm8903_snd_controls, | 1883 | .component_driver = { |
1884 | .num_controls = ARRAY_SIZE(wm8903_snd_controls), | 1884 | .controls = wm8903_snd_controls, |
1885 | .dapm_widgets = wm8903_dapm_widgets, | 1885 | .num_controls = ARRAY_SIZE(wm8903_snd_controls), |
1886 | .num_dapm_widgets = ARRAY_SIZE(wm8903_dapm_widgets), | 1886 | .dapm_widgets = wm8903_dapm_widgets, |
1887 | .dapm_routes = wm8903_intercon, | 1887 | .num_dapm_widgets = ARRAY_SIZE(wm8903_dapm_widgets), |
1888 | .num_dapm_routes = ARRAY_SIZE(wm8903_intercon), | 1888 | .dapm_routes = wm8903_intercon, |
1889 | .num_dapm_routes = ARRAY_SIZE(wm8903_intercon), | ||
1890 | }, | ||
1889 | }; | 1891 | }; |
1890 | 1892 | ||
1891 | static const struct regmap_config wm8903_regmap = { | 1893 | static const struct regmap_config wm8903_regmap = { |
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index edd7a7709194..4fd350e8420d 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c | |||
@@ -2086,7 +2086,7 @@ static int wm8904_remove(struct snd_soc_codec *codec) | |||
2086 | return 0; | 2086 | return 0; |
2087 | } | 2087 | } |
2088 | 2088 | ||
2089 | static struct snd_soc_codec_driver soc_codec_dev_wm8904 = { | 2089 | static const struct snd_soc_codec_driver soc_codec_dev_wm8904 = { |
2090 | .probe = wm8904_probe, | 2090 | .probe = wm8904_probe, |
2091 | .remove = wm8904_remove, | 2091 | .remove = wm8904_remove, |
2092 | .set_bias_level = wm8904_set_bias_level, | 2092 | .set_bias_level = wm8904_set_bias_level, |
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 1c600819f768..b5935625feeb 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c | |||
@@ -723,17 +723,19 @@ static int wm8940_probe(struct snd_soc_codec *codec) | |||
723 | return ret; | 723 | return ret; |
724 | } | 724 | } |
725 | 725 | ||
726 | static struct snd_soc_codec_driver soc_codec_dev_wm8940 = { | 726 | static const struct snd_soc_codec_driver soc_codec_dev_wm8940 = { |
727 | .probe = wm8940_probe, | 727 | .probe = wm8940_probe, |
728 | .set_bias_level = wm8940_set_bias_level, | 728 | .set_bias_level = wm8940_set_bias_level, |
729 | .suspend_bias_off = true, | 729 | .suspend_bias_off = true, |
730 | 730 | ||
731 | .controls = wm8940_snd_controls, | 731 | .component_driver = { |
732 | .num_controls = ARRAY_SIZE(wm8940_snd_controls), | 732 | .controls = wm8940_snd_controls, |
733 | .dapm_widgets = wm8940_dapm_widgets, | 733 | .num_controls = ARRAY_SIZE(wm8940_snd_controls), |
734 | .num_dapm_widgets = ARRAY_SIZE(wm8940_dapm_widgets), | 734 | .dapm_widgets = wm8940_dapm_widgets, |
735 | .dapm_routes = wm8940_dapm_routes, | 735 | .num_dapm_widgets = ARRAY_SIZE(wm8940_dapm_widgets), |
736 | .num_dapm_routes = ARRAY_SIZE(wm8940_dapm_routes), | 736 | .dapm_routes = wm8940_dapm_routes, |
737 | .num_dapm_routes = ARRAY_SIZE(wm8940_dapm_routes), | ||
738 | }, | ||
737 | }; | 739 | }; |
738 | 740 | ||
739 | static const struct regmap_config wm8940_regmap = { | 741 | static const struct regmap_config wm8940_regmap = { |
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 9db00d53abe7..1edc7b1df31d 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c | |||
@@ -940,17 +940,19 @@ err_enable: | |||
940 | return ret; | 940 | return ret; |
941 | } | 941 | } |
942 | 942 | ||
943 | static struct snd_soc_codec_driver soc_codec_dev_wm8955 = { | 943 | static const struct snd_soc_codec_driver soc_codec_dev_wm8955 = { |
944 | .probe = wm8955_probe, | 944 | .probe = wm8955_probe, |
945 | .set_bias_level = wm8955_set_bias_level, | 945 | .set_bias_level = wm8955_set_bias_level, |
946 | .suspend_bias_off = true, | 946 | .suspend_bias_off = true, |
947 | 947 | ||
948 | .controls = wm8955_snd_controls, | 948 | .component_driver = { |
949 | .num_controls = ARRAY_SIZE(wm8955_snd_controls), | 949 | .controls = wm8955_snd_controls, |
950 | .dapm_widgets = wm8955_dapm_widgets, | 950 | .num_controls = ARRAY_SIZE(wm8955_snd_controls), |
951 | .num_dapm_widgets = ARRAY_SIZE(wm8955_dapm_widgets), | 951 | .dapm_widgets = wm8955_dapm_widgets, |
952 | .dapm_routes = wm8955_dapm_routes, | 952 | .num_dapm_widgets = ARRAY_SIZE(wm8955_dapm_widgets), |
953 | .num_dapm_routes = ARRAY_SIZE(wm8955_dapm_routes), | 953 | .dapm_routes = wm8955_dapm_routes, |
954 | .num_dapm_routes = ARRAY_SIZE(wm8955_dapm_routes), | ||
955 | }, | ||
954 | }; | 956 | }; |
955 | 957 | ||
956 | static const struct regmap_config wm8955_regmap = { | 958 | static const struct regmap_config wm8955_regmap = { |
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index d7f444f87460..3bf081a7e450 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
@@ -226,11 +226,10 @@ static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1); | |||
226 | static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0); | 226 | static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0); |
227 | static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); | 227 | static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); |
228 | static const DECLARE_TLV_DB_SCALE(lineinboost_tlv, -1500, 300, 1); | 228 | static const DECLARE_TLV_DB_SCALE(lineinboost_tlv, -1500, 300, 1); |
229 | static const unsigned int micboost_tlv[] = { | 229 | static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(micboost_tlv, |
230 | TLV_DB_RANGE_HEAD(2), | ||
231 | 0, 1, TLV_DB_SCALE_ITEM(0, 1300, 0), | 230 | 0, 1, TLV_DB_SCALE_ITEM(0, 1300, 0), |
232 | 2, 3, TLV_DB_SCALE_ITEM(2000, 900, 0), | 231 | 2, 3, TLV_DB_SCALE_ITEM(2000, 900, 0), |
233 | }; | 232 | ); |
234 | 233 | ||
235 | static const struct snd_kcontrol_new wm8960_snd_controls[] = { | 234 | static const struct snd_kcontrol_new wm8960_snd_controls[] = { |
236 | SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL, | 235 | SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL, |
@@ -1264,7 +1263,7 @@ static int wm8960_probe(struct snd_soc_codec *codec) | |||
1264 | return 0; | 1263 | return 0; |
1265 | } | 1264 | } |
1266 | 1265 | ||
1267 | static struct snd_soc_codec_driver soc_codec_dev_wm8960 = { | 1266 | static const struct snd_soc_codec_driver soc_codec_dev_wm8960 = { |
1268 | .probe = wm8960_probe, | 1267 | .probe = wm8960_probe, |
1269 | .set_bias_level = wm8960_set_bias_level, | 1268 | .set_bias_level = wm8960_set_bias_level, |
1270 | .suspend_bias_off = true, | 1269 | .suspend_bias_off = true, |
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index e30446a04740..e23ceac76015 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c | |||
@@ -882,18 +882,20 @@ static int wm8961_resume(struct snd_soc_codec *codec) | |||
882 | #define wm8961_resume NULL | 882 | #define wm8961_resume NULL |
883 | #endif | 883 | #endif |
884 | 884 | ||
885 | static struct snd_soc_codec_driver soc_codec_dev_wm8961 = { | 885 | static const struct snd_soc_codec_driver soc_codec_dev_wm8961 = { |
886 | .probe = wm8961_probe, | 886 | .probe = wm8961_probe, |
887 | .resume = wm8961_resume, | 887 | .resume = wm8961_resume, |
888 | .set_bias_level = wm8961_set_bias_level, | 888 | .set_bias_level = wm8961_set_bias_level, |
889 | .suspend_bias_off = true, | 889 | .suspend_bias_off = true, |
890 | 890 | ||
891 | .controls = wm8961_snd_controls, | 891 | .component_driver = { |
892 | .num_controls = ARRAY_SIZE(wm8961_snd_controls), | 892 | .controls = wm8961_snd_controls, |
893 | .dapm_widgets = wm8961_dapm_widgets, | 893 | .num_controls = ARRAY_SIZE(wm8961_snd_controls), |
894 | .num_dapm_widgets = ARRAY_SIZE(wm8961_dapm_widgets), | 894 | .dapm_widgets = wm8961_dapm_widgets, |
895 | .dapm_routes = audio_paths, | 895 | .num_dapm_widgets = ARRAY_SIZE(wm8961_dapm_widgets), |
896 | .num_dapm_routes = ARRAY_SIZE(audio_paths), | 896 | .dapm_routes = audio_paths, |
897 | .num_dapm_routes = ARRAY_SIZE(audio_paths), | ||
898 | }, | ||
897 | }; | 899 | }; |
898 | 900 | ||
899 | static const struct regmap_config wm8961_regmap = { | 901 | static const struct regmap_config wm8961_regmap = { |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index f3109da24769..fd2731d171dd 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -3357,7 +3357,7 @@ static int wm8962_gpio_direction_out(struct gpio_chip *chip, | |||
3357 | return 0; | 3357 | return 0; |
3358 | } | 3358 | } |
3359 | 3359 | ||
3360 | static struct gpio_chip wm8962_template_chip = { | 3360 | static const struct gpio_chip wm8962_template_chip = { |
3361 | .label = "wm8962", | 3361 | .label = "wm8962", |
3362 | .owner = THIS_MODULE, | 3362 | .owner = THIS_MODULE, |
3363 | .request = wm8962_gpio_request, | 3363 | .request = wm8962_gpio_request, |
@@ -3479,7 +3479,7 @@ static int wm8962_remove(struct snd_soc_codec *codec) | |||
3479 | return 0; | 3479 | return 0; |
3480 | } | 3480 | } |
3481 | 3481 | ||
3482 | static struct snd_soc_codec_driver soc_codec_dev_wm8962 = { | 3482 | static const struct snd_soc_codec_driver soc_codec_dev_wm8962 = { |
3483 | .probe = wm8962_probe, | 3483 | .probe = wm8962_probe, |
3484 | .remove = wm8962_remove, | 3484 | .remove = wm8962_remove, |
3485 | .set_bias_level = wm8962_set_bias_level, | 3485 | .set_bias_level = wm8962_set_bias_level, |
@@ -3713,7 +3713,7 @@ static int wm8962_i2c_probe(struct i2c_client *i2c, | |||
3713 | ARRAY_SIZE(wm8962_dc_measure)); | 3713 | ARRAY_SIZE(wm8962_dc_measure)); |
3714 | if (ret != 0) | 3714 | if (ret != 0) |
3715 | dev_err(&i2c->dev, | 3715 | dev_err(&i2c->dev, |
3716 | "Failed to configure for DC mesurement: %d\n", | 3716 | "Failed to configure for DC measurement: %d\n", |
3717 | ret); | 3717 | ret); |
3718 | } | 3718 | } |
3719 | 3719 | ||
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 2cdde32c43c6..887d31cf3945 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c | |||
@@ -649,17 +649,19 @@ static int wm8971_probe(struct snd_soc_codec *codec) | |||
649 | return 0; | 649 | return 0; |
650 | } | 650 | } |
651 | 651 | ||
652 | static struct snd_soc_codec_driver soc_codec_dev_wm8971 = { | 652 | static const struct snd_soc_codec_driver soc_codec_dev_wm8971 = { |
653 | .probe = wm8971_probe, | 653 | .probe = wm8971_probe, |
654 | .set_bias_level = wm8971_set_bias_level, | 654 | .set_bias_level = wm8971_set_bias_level, |
655 | .suspend_bias_off = true, | 655 | .suspend_bias_off = true, |
656 | 656 | ||
657 | .controls = wm8971_snd_controls, | 657 | .component_driver = { |
658 | .num_controls = ARRAY_SIZE(wm8971_snd_controls), | 658 | .controls = wm8971_snd_controls, |
659 | .dapm_widgets = wm8971_dapm_widgets, | 659 | .num_controls = ARRAY_SIZE(wm8971_snd_controls), |
660 | .num_dapm_widgets = ARRAY_SIZE(wm8971_dapm_widgets), | 660 | .dapm_widgets = wm8971_dapm_widgets, |
661 | .dapm_routes = wm8971_dapm_routes, | 661 | .num_dapm_widgets = ARRAY_SIZE(wm8971_dapm_widgets), |
662 | .num_dapm_routes = ARRAY_SIZE(wm8971_dapm_routes), | 662 | .dapm_routes = wm8971_dapm_routes, |
663 | .num_dapm_routes = ARRAY_SIZE(wm8971_dapm_routes), | ||
664 | }, | ||
663 | }; | 665 | }; |
664 | 666 | ||
665 | static const struct regmap_config wm8971_regmap = { | 667 | static const struct regmap_config wm8971_regmap = { |
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index dc8c3b1ebb6f..d414ddd6e197 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c | |||
@@ -676,17 +676,19 @@ static int wm8974_probe(struct snd_soc_codec *codec) | |||
676 | return 0; | 676 | return 0; |
677 | } | 677 | } |
678 | 678 | ||
679 | static struct snd_soc_codec_driver soc_codec_dev_wm8974 = { | 679 | static const struct snd_soc_codec_driver soc_codec_dev_wm8974 = { |
680 | .probe = wm8974_probe, | 680 | .probe = wm8974_probe, |
681 | .set_bias_level = wm8974_set_bias_level, | 681 | .set_bias_level = wm8974_set_bias_level, |
682 | .suspend_bias_off = true, | 682 | .suspend_bias_off = true, |
683 | 683 | ||
684 | .controls = wm8974_snd_controls, | 684 | .component_driver = { |
685 | .num_controls = ARRAY_SIZE(wm8974_snd_controls), | 685 | .controls = wm8974_snd_controls, |
686 | .dapm_widgets = wm8974_dapm_widgets, | 686 | .num_controls = ARRAY_SIZE(wm8974_snd_controls), |
687 | .num_dapm_widgets = ARRAY_SIZE(wm8974_dapm_widgets), | 687 | .dapm_widgets = wm8974_dapm_widgets, |
688 | .dapm_routes = wm8974_dapm_routes, | 688 | .num_dapm_widgets = ARRAY_SIZE(wm8974_dapm_widgets), |
689 | .num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes), | 689 | .dapm_routes = wm8974_dapm_routes, |
690 | .num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes), | ||
691 | }, | ||
690 | }; | 692 | }; |
691 | 693 | ||
692 | static int wm8974_i2c_probe(struct i2c_client *i2c, | 694 | static int wm8974_i2c_probe(struct i2c_client *i2c, |
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index d36d6001fbb7..90b2d418ef60 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c | |||
@@ -993,18 +993,20 @@ static int wm8978_probe(struct snd_soc_codec *codec) | |||
993 | return 0; | 993 | return 0; |
994 | } | 994 | } |
995 | 995 | ||
996 | static struct snd_soc_codec_driver soc_codec_dev_wm8978 = { | 996 | static const struct snd_soc_codec_driver soc_codec_dev_wm8978 = { |
997 | .probe = wm8978_probe, | 997 | .probe = wm8978_probe, |
998 | .suspend = wm8978_suspend, | 998 | .suspend = wm8978_suspend, |
999 | .resume = wm8978_resume, | 999 | .resume = wm8978_resume, |
1000 | .set_bias_level = wm8978_set_bias_level, | 1000 | .set_bias_level = wm8978_set_bias_level, |
1001 | 1001 | ||
1002 | .controls = wm8978_snd_controls, | 1002 | .component_driver = { |
1003 | .num_controls = ARRAY_SIZE(wm8978_snd_controls), | 1003 | .controls = wm8978_snd_controls, |
1004 | .dapm_widgets = wm8978_dapm_widgets, | 1004 | .num_controls = ARRAY_SIZE(wm8978_snd_controls), |
1005 | .num_dapm_widgets = ARRAY_SIZE(wm8978_dapm_widgets), | 1005 | .dapm_widgets = wm8978_dapm_widgets, |
1006 | .dapm_routes = wm8978_dapm_routes, | 1006 | .num_dapm_widgets = ARRAY_SIZE(wm8978_dapm_widgets), |
1007 | .num_dapm_routes = ARRAY_SIZE(wm8978_dapm_routes), | 1007 | .dapm_routes = wm8978_dapm_routes, |
1008 | .num_dapm_routes = ARRAY_SIZE(wm8978_dapm_routes), | ||
1009 | }, | ||
1008 | }; | 1010 | }; |
1009 | 1011 | ||
1010 | static const struct regmap_config wm8978_regmap_config = { | 1012 | static const struct regmap_config wm8978_regmap_config = { |
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index 0c002a5712cb..bfdbe72ee687 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c | |||
@@ -976,16 +976,18 @@ static struct snd_soc_dai_driver wm8983_dai = { | |||
976 | .symmetric_rates = 1 | 976 | .symmetric_rates = 1 |
977 | }; | 977 | }; |
978 | 978 | ||
979 | static struct snd_soc_codec_driver soc_codec_dev_wm8983 = { | 979 | static const struct snd_soc_codec_driver soc_codec_dev_wm8983 = { |
980 | .probe = wm8983_probe, | 980 | .probe = wm8983_probe, |
981 | .set_bias_level = wm8983_set_bias_level, | 981 | .set_bias_level = wm8983_set_bias_level, |
982 | .suspend_bias_off = true, | 982 | .suspend_bias_off = true, |
983 | .controls = wm8983_snd_controls, | 983 | .component_driver = { |
984 | .num_controls = ARRAY_SIZE(wm8983_snd_controls), | 984 | .controls = wm8983_snd_controls, |
985 | .dapm_widgets = wm8983_dapm_widgets, | 985 | .num_controls = ARRAY_SIZE(wm8983_snd_controls), |
986 | .num_dapm_widgets = ARRAY_SIZE(wm8983_dapm_widgets), | 986 | .dapm_widgets = wm8983_dapm_widgets, |
987 | .dapm_routes = wm8983_audio_map, | 987 | .num_dapm_widgets = ARRAY_SIZE(wm8983_dapm_widgets), |
988 | .num_dapm_routes = ARRAY_SIZE(wm8983_audio_map), | 988 | .dapm_routes = wm8983_audio_map, |
989 | .num_dapm_routes = ARRAY_SIZE(wm8983_audio_map), | ||
990 | }, | ||
989 | }; | 991 | }; |
990 | 992 | ||
991 | static const struct regmap_config wm8983_regmap = { | 993 | static const struct regmap_config wm8983_regmap = { |
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index 7347abff4b2c..05344f974ff3 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c | |||
@@ -1105,17 +1105,19 @@ static struct snd_soc_dai_driver wm8985_dai = { | |||
1105 | .symmetric_rates = 1 | 1105 | .symmetric_rates = 1 |
1106 | }; | 1106 | }; |
1107 | 1107 | ||
1108 | static struct snd_soc_codec_driver soc_codec_dev_wm8985 = { | 1108 | static const struct snd_soc_codec_driver soc_codec_dev_wm8985 = { |
1109 | .probe = wm8985_probe, | 1109 | .probe = wm8985_probe, |
1110 | .set_bias_level = wm8985_set_bias_level, | 1110 | .set_bias_level = wm8985_set_bias_level, |
1111 | .suspend_bias_off = true, | 1111 | .suspend_bias_off = true, |
1112 | 1112 | ||
1113 | .controls = wm8985_common_snd_controls, | 1113 | .component_driver = { |
1114 | .num_controls = ARRAY_SIZE(wm8985_common_snd_controls), | 1114 | .controls = wm8985_common_snd_controls, |
1115 | .dapm_widgets = wm8985_common_dapm_widgets, | 1115 | .num_controls = ARRAY_SIZE(wm8985_common_snd_controls), |
1116 | .num_dapm_widgets = ARRAY_SIZE(wm8985_common_dapm_widgets), | 1116 | .dapm_widgets = wm8985_common_dapm_widgets, |
1117 | .dapm_routes = wm8985_common_dapm_routes, | 1117 | .num_dapm_widgets = ARRAY_SIZE(wm8985_common_dapm_widgets), |
1118 | .num_dapm_routes = ARRAY_SIZE(wm8985_common_dapm_routes), | 1118 | .dapm_routes = wm8985_common_dapm_routes, |
1119 | .num_dapm_routes = ARRAY_SIZE(wm8985_common_dapm_routes), | ||
1120 | }, | ||
1119 | }; | 1121 | }; |
1120 | 1122 | ||
1121 | static const struct regmap_config wm8985_regmap = { | 1123 | static const struct regmap_config wm8985_regmap = { |
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 895721a256f0..b0d0219532f2 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c | |||
@@ -817,12 +817,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm8988 = { | |||
817 | .set_bias_level = wm8988_set_bias_level, | 817 | .set_bias_level = wm8988_set_bias_level, |
818 | .suspend_bias_off = true, | 818 | .suspend_bias_off = true, |
819 | 819 | ||
820 | .controls = wm8988_snd_controls, | 820 | .component_driver = { |
821 | .num_controls = ARRAY_SIZE(wm8988_snd_controls), | 821 | .controls = wm8988_snd_controls, |
822 | .dapm_widgets = wm8988_dapm_widgets, | 822 | .num_controls = ARRAY_SIZE(wm8988_snd_controls), |
823 | .num_dapm_widgets = ARRAY_SIZE(wm8988_dapm_widgets), | 823 | .dapm_widgets = wm8988_dapm_widgets, |
824 | .dapm_routes = wm8988_dapm_routes, | 824 | .num_dapm_widgets = ARRAY_SIZE(wm8988_dapm_widgets), |
825 | .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes), | 825 | .dapm_routes = wm8988_dapm_routes, |
826 | .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes), | ||
827 | }, | ||
826 | }; | 828 | }; |
827 | 829 | ||
828 | static const struct regmap_config wm8988_regmap = { | 830 | static const struct regmap_config wm8988_regmap = { |
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 23ecd30d8bca..a8945001e696 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c | |||
@@ -1294,17 +1294,19 @@ static int wm8990_probe(struct snd_soc_codec *codec) | |||
1294 | return 0; | 1294 | return 0; |
1295 | } | 1295 | } |
1296 | 1296 | ||
1297 | static struct snd_soc_codec_driver soc_codec_dev_wm8990 = { | 1297 | static const struct snd_soc_codec_driver soc_codec_dev_wm8990 = { |
1298 | .probe = wm8990_probe, | 1298 | .probe = wm8990_probe, |
1299 | .set_bias_level = wm8990_set_bias_level, | 1299 | .set_bias_level = wm8990_set_bias_level, |
1300 | .suspend_bias_off = true, | 1300 | .suspend_bias_off = true, |
1301 | 1301 | ||
1302 | .controls = wm8990_snd_controls, | 1302 | .component_driver = { |
1303 | .num_controls = ARRAY_SIZE(wm8990_snd_controls), | 1303 | .controls = wm8990_snd_controls, |
1304 | .dapm_widgets = wm8990_dapm_widgets, | 1304 | .num_controls = ARRAY_SIZE(wm8990_snd_controls), |
1305 | .num_dapm_widgets = ARRAY_SIZE(wm8990_dapm_widgets), | 1305 | .dapm_widgets = wm8990_dapm_widgets, |
1306 | .dapm_routes = wm8990_dapm_routes, | 1306 | .num_dapm_widgets = ARRAY_SIZE(wm8990_dapm_widgets), |
1307 | .num_dapm_routes = ARRAY_SIZE(wm8990_dapm_routes), | 1307 | .dapm_routes = wm8990_dapm_routes, |
1308 | .num_dapm_routes = ARRAY_SIZE(wm8990_dapm_routes), | ||
1309 | }, | ||
1308 | }; | 1310 | }; |
1309 | 1311 | ||
1310 | static const struct regmap_config wm8990_regmap = { | 1312 | static const struct regmap_config wm8990_regmap = { |
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index c9ee0ac6a654..802c0694e5c3 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c | |||
@@ -111,14 +111,24 @@ static bool wm8991_volatile(struct device *dev, unsigned int reg) | |||
111 | } | 111 | } |
112 | } | 112 | } |
113 | 113 | ||
114 | static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv, -1500, 600); | 114 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(in_pga_tlv, -1650, 150, 0); |
115 | static const DECLARE_TLV_DB_LINEAR(in_pga_tlv, -1650, 3000); | 115 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(out_mix_tlv, -2100, 300, 0); |
116 | static const DECLARE_TLV_DB_LINEAR(out_mix_tlv, 0, -2100); | 116 | static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(out_pga_tlv, |
117 | static const DECLARE_TLV_DB_LINEAR(out_pga_tlv, -7300, 600); | 117 | 0x00, 0x2f, SNDRV_CTL_TLVD_DB_SCALE_ITEM(SNDRV_CTL_TLVD_DB_GAIN_MUTE, 0, 1), |
118 | static const DECLARE_TLV_DB_LINEAR(out_omix_tlv, -600, 0); | 118 | 0x30, 0x7f, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-7300, 100, 0), |
119 | static const DECLARE_TLV_DB_LINEAR(out_dac_tlv, -7163, 0); | 119 | ); |
120 | static const DECLARE_TLV_DB_LINEAR(in_adc_tlv, -7163, 1763); | 120 | static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(out_dac_tlv, |
121 | static const DECLARE_TLV_DB_LINEAR(out_sidetone_tlv, -3600, 0); | 121 | 0x00, 0xbf, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-71625, 375, 1), |
122 | 0xc0, 0xff, SNDRV_CTL_TLVD_DB_SCALE_ITEM(0, 0, 0), | ||
123 | ); | ||
124 | static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(in_adc_tlv, | ||
125 | 0x00, 0xef, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-71625, 375, 1), | ||
126 | 0xf0, 0xff, SNDRV_CTL_TLVD_DB_SCALE_ITEM(17625, 0, 0), | ||
127 | ); | ||
128 | static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(out_sidetone_tlv, | ||
129 | 0x00, 0x0c, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-3600, 300, 0), | ||
130 | 0x0d, 0x0f, SNDRV_CTL_TLVD_DB_SCALE_ITEM(0, 0, 0), | ||
131 | ); | ||
122 | 132 | ||
123 | static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, | 133 | static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, |
124 | struct snd_ctl_elem_value *ucontrol) | 134 | struct snd_ctl_elem_value *ucontrol) |
@@ -398,7 +408,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w, | |||
398 | } | 408 | } |
399 | 409 | ||
400 | /* INMIX dB values */ | 410 | /* INMIX dB values */ |
401 | static const DECLARE_TLV_DB_LINEAR(in_mix_tlv, -1200, 600); | 411 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(in_mix_tlv, -1200, 300, 1); |
402 | 412 | ||
403 | /* Left In PGA Connections */ | 413 | /* Left In PGA Connections */ |
404 | static const struct snd_kcontrol_new wm8991_dapm_lin12_pga_controls[] = { | 414 | static const struct snd_kcontrol_new wm8991_dapm_lin12_pga_controls[] = { |
@@ -1232,16 +1242,18 @@ static struct snd_soc_dai_driver wm8991_dai = { | |||
1232 | .ops = &wm8991_ops | 1242 | .ops = &wm8991_ops |
1233 | }; | 1243 | }; |
1234 | 1244 | ||
1235 | static struct snd_soc_codec_driver soc_codec_dev_wm8991 = { | 1245 | static const struct snd_soc_codec_driver soc_codec_dev_wm8991 = { |
1236 | .set_bias_level = wm8991_set_bias_level, | 1246 | .set_bias_level = wm8991_set_bias_level, |
1237 | .suspend_bias_off = true, | 1247 | .suspend_bias_off = true, |
1238 | 1248 | ||
1239 | .controls = wm8991_snd_controls, | 1249 | .component_driver = { |
1240 | .num_controls = ARRAY_SIZE(wm8991_snd_controls), | 1250 | .controls = wm8991_snd_controls, |
1241 | .dapm_widgets = wm8991_dapm_widgets, | 1251 | .num_controls = ARRAY_SIZE(wm8991_snd_controls), |
1242 | .num_dapm_widgets = ARRAY_SIZE(wm8991_dapm_widgets), | 1252 | .dapm_widgets = wm8991_dapm_widgets, |
1243 | .dapm_routes = wm8991_dapm_routes, | 1253 | .num_dapm_widgets = ARRAY_SIZE(wm8991_dapm_widgets), |
1244 | .num_dapm_routes = ARRAY_SIZE(wm8991_dapm_routes), | 1254 | .dapm_routes = wm8991_dapm_routes, |
1255 | .num_dapm_routes = ARRAY_SIZE(wm8991_dapm_routes), | ||
1256 | }, | ||
1245 | }; | 1257 | }; |
1246 | 1258 | ||
1247 | static const struct regmap_config wm8991_regmap = { | 1259 | static const struct regmap_config wm8991_regmap = { |
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 8668c4c391b0..195f7bf6eb22 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
@@ -1613,7 +1613,7 @@ static const struct regmap_config wm8993_regmap = { | |||
1613 | .num_reg_defaults = ARRAY_SIZE(wm8993_reg_defaults), | 1613 | .num_reg_defaults = ARRAY_SIZE(wm8993_reg_defaults), |
1614 | }; | 1614 | }; |
1615 | 1615 | ||
1616 | static struct snd_soc_codec_driver soc_codec_dev_wm8993 = { | 1616 | static const struct snd_soc_codec_driver soc_codec_dev_wm8993 = { |
1617 | .probe = wm8993_probe, | 1617 | .probe = wm8993_probe, |
1618 | .suspend = wm8993_suspend, | 1618 | .suspend = wm8993_suspend, |
1619 | .resume = wm8993_resume, | 1619 | .resume = wm8993_resume, |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index a18aecb49935..3896523b71e9 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -4439,7 +4439,7 @@ static struct regmap *wm8994_get_regmap(struct device *dev) | |||
4439 | return control->regmap; | 4439 | return control->regmap; |
4440 | } | 4440 | } |
4441 | 4441 | ||
4442 | static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { | 4442 | static const struct snd_soc_codec_driver soc_codec_dev_wm8994 = { |
4443 | .probe = wm8994_codec_probe, | 4443 | .probe = wm8994_codec_probe, |
4444 | .remove = wm8994_codec_remove, | 4444 | .remove = wm8994_codec_remove, |
4445 | .suspend = wm8994_codec_suspend, | 4445 | .suspend = wm8994_codec_suspend, |
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index 24500bafb0a8..19b08a5cae62 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c | |||
@@ -2192,12 +2192,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm8995 = { | |||
2192 | .set_bias_level = wm8995_set_bias_level, | 2192 | .set_bias_level = wm8995_set_bias_level, |
2193 | .idle_bias_off = true, | 2193 | .idle_bias_off = true, |
2194 | 2194 | ||
2195 | .controls = wm8995_snd_controls, | 2195 | .component_driver = { |
2196 | .num_controls = ARRAY_SIZE(wm8995_snd_controls), | 2196 | .controls = wm8995_snd_controls, |
2197 | .dapm_widgets = wm8995_dapm_widgets, | 2197 | .num_controls = ARRAY_SIZE(wm8995_snd_controls), |
2198 | .num_dapm_widgets = ARRAY_SIZE(wm8995_dapm_widgets), | 2198 | .dapm_widgets = wm8995_dapm_widgets, |
2199 | .dapm_routes = wm8995_intercon, | 2199 | .num_dapm_widgets = ARRAY_SIZE(wm8995_dapm_widgets), |
2200 | .num_dapm_routes = ARRAY_SIZE(wm8995_intercon), | 2200 | .dapm_routes = wm8995_intercon, |
2201 | .num_dapm_routes = ARRAY_SIZE(wm8995_intercon), | ||
2202 | }, | ||
2201 | }; | 2203 | }; |
2202 | 2204 | ||
2203 | static const struct regmap_config wm8995_regmap = { | 2205 | static const struct regmap_config wm8995_regmap = { |
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index a73044251218..8affa4969120 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c | |||
@@ -2184,7 +2184,7 @@ static int wm8996_gpio_direction_in(struct gpio_chip *chip, unsigned offset) | |||
2184 | (1 << WM8996_GP1_DIR_SHIFT)); | 2184 | (1 << WM8996_GP1_DIR_SHIFT)); |
2185 | } | 2185 | } |
2186 | 2186 | ||
2187 | static struct gpio_chip wm8996_template_chip = { | 2187 | static const struct gpio_chip wm8996_template_chip = { |
2188 | .label = "wm8996", | 2188 | .label = "wm8996", |
2189 | .owner = THIS_MODULE, | 2189 | .owner = THIS_MODULE, |
2190 | .direction_output = wm8996_gpio_direction_out, | 2190 | .direction_output = wm8996_gpio_direction_out, |
@@ -2684,18 +2684,20 @@ static int wm8996_remove(struct snd_soc_codec *codec) | |||
2684 | return 0; | 2684 | return 0; |
2685 | } | 2685 | } |
2686 | 2686 | ||
2687 | static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { | 2687 | static const struct snd_soc_codec_driver soc_codec_dev_wm8996 = { |
2688 | .probe = wm8996_probe, | 2688 | .probe = wm8996_probe, |
2689 | .remove = wm8996_remove, | 2689 | .remove = wm8996_remove, |
2690 | .set_bias_level = wm8996_set_bias_level, | 2690 | .set_bias_level = wm8996_set_bias_level, |
2691 | .idle_bias_off = true, | 2691 | .idle_bias_off = true, |
2692 | .seq_notifier = wm8996_seq_notifier, | 2692 | .seq_notifier = wm8996_seq_notifier, |
2693 | .controls = wm8996_snd_controls, | 2693 | .component_driver = { |
2694 | .num_controls = ARRAY_SIZE(wm8996_snd_controls), | 2694 | .controls = wm8996_snd_controls, |
2695 | .dapm_widgets = wm8996_dapm_widgets, | 2695 | .num_controls = ARRAY_SIZE(wm8996_snd_controls), |
2696 | .num_dapm_widgets = ARRAY_SIZE(wm8996_dapm_widgets), | 2696 | .dapm_widgets = wm8996_dapm_widgets, |
2697 | .dapm_routes = wm8996_dapm_routes, | 2697 | .num_dapm_widgets = ARRAY_SIZE(wm8996_dapm_widgets), |
2698 | .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes), | 2698 | .dapm_routes = wm8996_dapm_routes, |
2699 | .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes), | ||
2700 | }, | ||
2699 | .set_pll = wm8996_set_fll, | 2701 | .set_pll = wm8996_set_fll, |
2700 | }; | 2702 | }; |
2701 | 2703 | ||
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 6b0785b5a5c5..2f2821b3382f 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c | |||
@@ -1095,7 +1095,7 @@ static struct regmap *wm8997_get_regmap(struct device *dev) | |||
1095 | return priv->core.arizona->regmap; | 1095 | return priv->core.arizona->regmap; |
1096 | } | 1096 | } |
1097 | 1097 | ||
1098 | static struct snd_soc_codec_driver soc_codec_dev_wm8997 = { | 1098 | static const struct snd_soc_codec_driver soc_codec_dev_wm8997 = { |
1099 | .probe = wm8997_codec_probe, | 1099 | .probe = wm8997_codec_probe, |
1100 | .remove = wm8997_codec_remove, | 1100 | .remove = wm8997_codec_remove, |
1101 | .get_regmap = wm8997_get_regmap, | 1101 | .get_regmap = wm8997_get_regmap, |
@@ -1105,12 +1105,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8997 = { | |||
1105 | .set_sysclk = arizona_set_sysclk, | 1105 | .set_sysclk = arizona_set_sysclk, |
1106 | .set_pll = wm8997_set_fll, | 1106 | .set_pll = wm8997_set_fll, |
1107 | 1107 | ||
1108 | .controls = wm8997_snd_controls, | 1108 | .component_driver = { |
1109 | .num_controls = ARRAY_SIZE(wm8997_snd_controls), | 1109 | .controls = wm8997_snd_controls, |
1110 | .dapm_widgets = wm8997_dapm_widgets, | 1110 | .num_controls = ARRAY_SIZE(wm8997_snd_controls), |
1111 | .num_dapm_widgets = ARRAY_SIZE(wm8997_dapm_widgets), | 1111 | .dapm_widgets = wm8997_dapm_widgets, |
1112 | .dapm_routes = wm8997_dapm_routes, | 1112 | .num_dapm_widgets = ARRAY_SIZE(wm8997_dapm_widgets), |
1113 | .num_dapm_routes = ARRAY_SIZE(wm8997_dapm_routes), | 1113 | .dapm_routes = wm8997_dapm_routes, |
1114 | .num_dapm_routes = ARRAY_SIZE(wm8997_dapm_routes), | ||
1115 | }, | ||
1114 | }; | 1116 | }; |
1115 | 1117 | ||
1116 | static int wm8997_probe(struct platform_device *pdev) | 1118 | static int wm8997_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c index 3a5c896a2d13..bcc2e1060a6c 100644 --- a/sound/soc/codecs/wm8998.c +++ b/sound/soc/codecs/wm8998.c | |||
@@ -966,6 +966,16 @@ static const struct snd_soc_dapm_route wm8998_dapm_routes[] = { | |||
966 | { "IN2A", NULL, "SYSCLK" }, | 966 | { "IN2A", NULL, "SYSCLK" }, |
967 | { "IN2B", NULL, "SYSCLK" }, | 967 | { "IN2B", NULL, "SYSCLK" }, |
968 | 968 | ||
969 | { "ASRC1L", NULL, "SYSCLK" }, | ||
970 | { "ASRC1R", NULL, "SYSCLK" }, | ||
971 | { "ASRC2L", NULL, "SYSCLK" }, | ||
972 | { "ASRC2R", NULL, "SYSCLK" }, | ||
973 | |||
974 | { "ASRC1L", NULL, "ASYNCCLK" }, | ||
975 | { "ASRC1R", NULL, "ASYNCCLK" }, | ||
976 | { "ASRC2L", NULL, "ASYNCCLK" }, | ||
977 | { "ASRC2R", NULL, "ASYNCCLK" }, | ||
978 | |||
969 | { "SPD1", NULL, "SYSCLK" }, | 979 | { "SPD1", NULL, "SYSCLK" }, |
970 | { "SPD1", NULL, "SPD1TX1" }, | 980 | { "SPD1", NULL, "SPD1TX1" }, |
971 | { "SPD1", NULL, "SPD1TX2" }, | 981 | { "SPD1", NULL, "SPD1TX2" }, |
@@ -1351,7 +1361,7 @@ static struct regmap *wm8998_get_regmap(struct device *dev) | |||
1351 | return priv->core.arizona->regmap; | 1361 | return priv->core.arizona->regmap; |
1352 | } | 1362 | } |
1353 | 1363 | ||
1354 | static struct snd_soc_codec_driver soc_codec_dev_wm8998 = { | 1364 | static const struct snd_soc_codec_driver soc_codec_dev_wm8998 = { |
1355 | .probe = wm8998_codec_probe, | 1365 | .probe = wm8998_codec_probe, |
1356 | .remove = wm8998_codec_remove, | 1366 | .remove = wm8998_codec_remove, |
1357 | .get_regmap = wm8998_get_regmap, | 1367 | .get_regmap = wm8998_get_regmap, |
@@ -1361,12 +1371,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8998 = { | |||
1361 | .set_sysclk = arizona_set_sysclk, | 1371 | .set_sysclk = arizona_set_sysclk, |
1362 | .set_pll = wm8998_set_fll, | 1372 | .set_pll = wm8998_set_fll, |
1363 | 1373 | ||
1364 | .controls = wm8998_snd_controls, | 1374 | .component_driver = { |
1365 | .num_controls = ARRAY_SIZE(wm8998_snd_controls), | 1375 | .controls = wm8998_snd_controls, |
1366 | .dapm_widgets = wm8998_dapm_widgets, | 1376 | .num_controls = ARRAY_SIZE(wm8998_snd_controls), |
1367 | .num_dapm_widgets = ARRAY_SIZE(wm8998_dapm_widgets), | 1377 | .dapm_widgets = wm8998_dapm_widgets, |
1368 | .dapm_routes = wm8998_dapm_routes, | 1378 | .num_dapm_widgets = ARRAY_SIZE(wm8998_dapm_widgets), |
1369 | .num_dapm_routes = ARRAY_SIZE(wm8998_dapm_routes), | 1379 | .dapm_routes = wm8998_dapm_routes, |
1380 | .num_dapm_routes = ARRAY_SIZE(wm8998_dapm_routes), | ||
1381 | }, | ||
1370 | }; | 1382 | }; |
1371 | 1383 | ||
1372 | static int wm8998_probe(struct platform_device *pdev) | 1384 | static int wm8998_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 363b3b667616..856867ec2813 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c | |||
@@ -1274,7 +1274,7 @@ static int wm9081_probe(struct snd_soc_codec *codec) | |||
1274 | return 0; | 1274 | return 0; |
1275 | } | 1275 | } |
1276 | 1276 | ||
1277 | static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { | 1277 | static const struct snd_soc_codec_driver soc_codec_dev_wm9081 = { |
1278 | .probe = wm9081_probe, | 1278 | .probe = wm9081_probe, |
1279 | 1279 | ||
1280 | .set_sysclk = wm9081_set_sysclk, | 1280 | .set_sysclk = wm9081_set_sysclk, |
@@ -1282,12 +1282,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { | |||
1282 | 1282 | ||
1283 | .idle_bias_off = true, | 1283 | .idle_bias_off = true, |
1284 | 1284 | ||
1285 | .controls = wm9081_snd_controls, | 1285 | .component_driver = { |
1286 | .num_controls = ARRAY_SIZE(wm9081_snd_controls), | 1286 | .controls = wm9081_snd_controls, |
1287 | .dapm_widgets = wm9081_dapm_widgets, | 1287 | .num_controls = ARRAY_SIZE(wm9081_snd_controls), |
1288 | .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets), | 1288 | .dapm_widgets = wm9081_dapm_widgets, |
1289 | .dapm_routes = wm9081_audio_paths, | 1289 | .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets), |
1290 | .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths), | 1290 | .dapm_routes = wm9081_audio_paths, |
1291 | .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths), | ||
1292 | }, | ||
1291 | }; | 1293 | }; |
1292 | 1294 | ||
1293 | static const struct regmap_config wm9081_regmap = { | 1295 | static const struct regmap_config wm9081_regmap = { |
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 5d737290f547..5a131385cb2f 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c | |||
@@ -550,7 +550,7 @@ static int wm9090_probe(struct snd_soc_codec *codec) | |||
550 | return 0; | 550 | return 0; |
551 | } | 551 | } |
552 | 552 | ||
553 | static struct snd_soc_codec_driver soc_codec_dev_wm9090 = { | 553 | static const struct snd_soc_codec_driver soc_codec_dev_wm9090 = { |
554 | .probe = wm9090_probe, | 554 | .probe = wm9090_probe, |
555 | .set_bias_level = wm9090_set_bias_level, | 555 | .set_bias_level = wm9090_set_bias_level, |
556 | .suspend_bias_off = true, | 556 | .suspend_bias_off = true, |
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 744842c76a60..dcdd055db57b 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c | |||
@@ -352,7 +352,7 @@ static int wm9705_soc_remove(struct snd_soc_codec *codec) | |||
352 | return 0; | 352 | return 0; |
353 | } | 353 | } |
354 | 354 | ||
355 | static struct snd_soc_codec_driver soc_codec_dev_wm9705 = { | 355 | static const struct snd_soc_codec_driver soc_codec_dev_wm9705 = { |
356 | .probe = wm9705_soc_probe, | 356 | .probe = wm9705_soc_probe, |
357 | .remove = wm9705_soc_remove, | 357 | .remove = wm9705_soc_remove, |
358 | .suspend = wm9705_soc_suspend, | 358 | .suspend = wm9705_soc_suspend, |
@@ -364,12 +364,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9705 = { | |||
364 | .reg_cache_step = 2, | 364 | .reg_cache_step = 2, |
365 | .reg_cache_default = wm9705_reg, | 365 | .reg_cache_default = wm9705_reg, |
366 | 366 | ||
367 | .controls = wm9705_snd_ac97_controls, | 367 | .component_driver = { |
368 | .num_controls = ARRAY_SIZE(wm9705_snd_ac97_controls), | 368 | .controls = wm9705_snd_ac97_controls, |
369 | .dapm_widgets = wm9705_dapm_widgets, | 369 | .num_controls = ARRAY_SIZE(wm9705_snd_ac97_controls), |
370 | .num_dapm_widgets = ARRAY_SIZE(wm9705_dapm_widgets), | 370 | .dapm_widgets = wm9705_dapm_widgets, |
371 | .dapm_routes = wm9705_audio_map, | 371 | .num_dapm_widgets = ARRAY_SIZE(wm9705_dapm_widgets), |
372 | .num_dapm_routes = ARRAY_SIZE(wm9705_audio_map), | 372 | .dapm_routes = wm9705_audio_map, |
373 | .num_dapm_routes = ARRAY_SIZE(wm9705_audio_map), | ||
374 | }, | ||
373 | }; | 375 | }; |
374 | 376 | ||
375 | static int wm9705_probe(struct platform_device *pdev) | 377 | static int wm9705_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 488a92224249..557709eac698 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c | |||
@@ -669,7 +669,7 @@ static int wm9712_soc_remove(struct snd_soc_codec *codec) | |||
669 | return 0; | 669 | return 0; |
670 | } | 670 | } |
671 | 671 | ||
672 | static struct snd_soc_codec_driver soc_codec_dev_wm9712 = { | 672 | static const struct snd_soc_codec_driver soc_codec_dev_wm9712 = { |
673 | .probe = wm9712_soc_probe, | 673 | .probe = wm9712_soc_probe, |
674 | .remove = wm9712_soc_remove, | 674 | .remove = wm9712_soc_remove, |
675 | .resume = wm9712_soc_resume, | 675 | .resume = wm9712_soc_resume, |
@@ -682,12 +682,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9712 = { | |||
682 | .reg_cache_step = 2, | 682 | .reg_cache_step = 2, |
683 | .reg_cache_default = wm9712_reg, | 683 | .reg_cache_default = wm9712_reg, |
684 | 684 | ||
685 | .controls = wm9712_snd_ac97_controls, | 685 | .component_driver = { |
686 | .num_controls = ARRAY_SIZE(wm9712_snd_ac97_controls), | 686 | .controls = wm9712_snd_ac97_controls, |
687 | .dapm_widgets = wm9712_dapm_widgets, | 687 | .num_controls = ARRAY_SIZE(wm9712_snd_ac97_controls), |
688 | .num_dapm_widgets = ARRAY_SIZE(wm9712_dapm_widgets), | 688 | .dapm_widgets = wm9712_dapm_widgets, |
689 | .dapm_routes = wm9712_audio_map, | 689 | .num_dapm_widgets = ARRAY_SIZE(wm9712_dapm_widgets), |
690 | .num_dapm_routes = ARRAY_SIZE(wm9712_audio_map), | 690 | .dapm_routes = wm9712_audio_map, |
691 | .num_dapm_routes = ARRAY_SIZE(wm9712_audio_map), | ||
692 | }, | ||
691 | }; | 693 | }; |
692 | 694 | ||
693 | static int wm9712_probe(struct platform_device *pdev) | 695 | static int wm9712_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 9849643ef809..e4301ddb1b84 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c | |||
@@ -1235,19 +1235,21 @@ static int wm9713_soc_remove(struct snd_soc_codec *codec) | |||
1235 | return 0; | 1235 | return 0; |
1236 | } | 1236 | } |
1237 | 1237 | ||
1238 | static struct snd_soc_codec_driver soc_codec_dev_wm9713 = { | 1238 | static const struct snd_soc_codec_driver soc_codec_dev_wm9713 = { |
1239 | .probe = wm9713_soc_probe, | 1239 | .probe = wm9713_soc_probe, |
1240 | .remove = wm9713_soc_remove, | 1240 | .remove = wm9713_soc_remove, |
1241 | .suspend = wm9713_soc_suspend, | 1241 | .suspend = wm9713_soc_suspend, |
1242 | .resume = wm9713_soc_resume, | 1242 | .resume = wm9713_soc_resume, |
1243 | .set_bias_level = wm9713_set_bias_level, | 1243 | .set_bias_level = wm9713_set_bias_level, |
1244 | 1244 | ||
1245 | .controls = wm9713_snd_ac97_controls, | 1245 | .component_driver = { |
1246 | .num_controls = ARRAY_SIZE(wm9713_snd_ac97_controls), | 1246 | .controls = wm9713_snd_ac97_controls, |
1247 | .dapm_widgets = wm9713_dapm_widgets, | 1247 | .num_controls = ARRAY_SIZE(wm9713_snd_ac97_controls), |
1248 | .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets), | 1248 | .dapm_widgets = wm9713_dapm_widgets, |
1249 | .dapm_routes = wm9713_audio_map, | 1249 | .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets), |
1250 | .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map), | 1250 | .dapm_routes = wm9713_audio_map, |
1251 | .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map), | ||
1252 | }, | ||
1251 | }; | 1253 | }; |
1252 | 1254 | ||
1253 | static int wm9713_probe(struct platform_device *pdev) | 1255 | static int wm9713_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 21fbe7d07063..b943dde8dbe5 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
@@ -480,7 +480,7 @@ static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file, | |||
480 | 480 | ||
481 | mutex_lock(&dsp->pwr_lock); | 481 | mutex_lock(&dsp->pwr_lock); |
482 | 482 | ||
483 | if (!dsp->wmfw_file_name || !dsp->running) | 483 | if (!dsp->wmfw_file_name || !dsp->booted) |
484 | ret = 0; | 484 | ret = 0; |
485 | else | 485 | else |
486 | ret = simple_read_from_buffer(user_buf, count, ppos, | 486 | ret = simple_read_from_buffer(user_buf, count, ppos, |
@@ -500,7 +500,7 @@ static ssize_t wm_adsp_debugfs_bin_read(struct file *file, | |||
500 | 500 | ||
501 | mutex_lock(&dsp->pwr_lock); | 501 | mutex_lock(&dsp->pwr_lock); |
502 | 502 | ||
503 | if (!dsp->bin_file_name || !dsp->running) | 503 | if (!dsp->bin_file_name || !dsp->booted) |
504 | ret = 0; | 504 | ret = 0; |
505 | else | 505 | else |
506 | ret = simple_read_from_buffer(user_buf, count, ppos, | 506 | ret = simple_read_from_buffer(user_buf, count, ppos, |
@@ -554,6 +554,9 @@ static void wm_adsp2_init_debugfs(struct wm_adsp *dsp, | |||
554 | if (!root) | 554 | if (!root) |
555 | goto err; | 555 | goto err; |
556 | 556 | ||
557 | if (!debugfs_create_bool("booted", S_IRUGO, root, &dsp->booted)) | ||
558 | goto err; | ||
559 | |||
557 | if (!debugfs_create_bool("running", S_IRUGO, root, &dsp->running)) | 560 | if (!debugfs_create_bool("running", S_IRUGO, root, &dsp->running)) |
558 | goto err; | 561 | goto err; |
559 | 562 | ||
@@ -637,7 +640,7 @@ static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, | |||
637 | 640 | ||
638 | mutex_lock(&dsp[e->shift_l].pwr_lock); | 641 | mutex_lock(&dsp[e->shift_l].pwr_lock); |
639 | 642 | ||
640 | if (dsp[e->shift_l].running || dsp[e->shift_l].compr) | 643 | if (dsp[e->shift_l].booted || dsp[e->shift_l].compr) |
641 | ret = -EBUSY; | 644 | ret = -EBUSY; |
642 | else | 645 | else |
643 | dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0]; | 646 | dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0]; |
@@ -789,7 +792,7 @@ static int wm_coeff_put(struct snd_kcontrol *kctl, | |||
789 | memcpy(ctl->cache, p, ctl->len); | 792 | memcpy(ctl->cache, p, ctl->len); |
790 | 793 | ||
791 | ctl->set = 1; | 794 | ctl->set = 1; |
792 | if (ctl->enabled) | 795 | if (ctl->enabled && ctl->dsp->running) |
793 | ret = wm_coeff_write_control(ctl, p, ctl->len); | 796 | ret = wm_coeff_write_control(ctl, p, ctl->len); |
794 | 797 | ||
795 | mutex_unlock(&ctl->dsp->pwr_lock); | 798 | mutex_unlock(&ctl->dsp->pwr_lock); |
@@ -811,7 +814,7 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl, | |||
811 | ret = -EFAULT; | 814 | ret = -EFAULT; |
812 | } else { | 815 | } else { |
813 | ctl->set = 1; | 816 | ctl->set = 1; |
814 | if (ctl->enabled) | 817 | if (ctl->enabled && ctl->dsp->running) |
815 | ret = wm_coeff_write_control(ctl, ctl->cache, size); | 818 | ret = wm_coeff_write_control(ctl, ctl->cache, size); |
816 | } | 819 | } |
817 | 820 | ||
@@ -871,12 +874,12 @@ static int wm_coeff_get(struct snd_kcontrol *kctl, | |||
871 | mutex_lock(&ctl->dsp->pwr_lock); | 874 | mutex_lock(&ctl->dsp->pwr_lock); |
872 | 875 | ||
873 | if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { | 876 | if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { |
874 | if (ctl->enabled) | 877 | if (ctl->enabled && ctl->dsp->running) |
875 | ret = wm_coeff_read_control(ctl, p, ctl->len); | 878 | ret = wm_coeff_read_control(ctl, p, ctl->len); |
876 | else | 879 | else |
877 | ret = -EPERM; | 880 | ret = -EPERM; |
878 | } else { | 881 | } else { |
879 | if (!ctl->flags && ctl->enabled) | 882 | if (!ctl->flags && ctl->enabled && ctl->dsp->running) |
880 | ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len); | 883 | ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len); |
881 | 884 | ||
882 | memcpy(p, ctl->cache, ctl->len); | 885 | memcpy(p, ctl->cache, ctl->len); |
@@ -898,12 +901,12 @@ static int wm_coeff_tlv_get(struct snd_kcontrol *kctl, | |||
898 | mutex_lock(&ctl->dsp->pwr_lock); | 901 | mutex_lock(&ctl->dsp->pwr_lock); |
899 | 902 | ||
900 | if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { | 903 | if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { |
901 | if (ctl->enabled) | 904 | if (ctl->enabled && ctl->dsp->running) |
902 | ret = wm_coeff_read_control(ctl, ctl->cache, size); | 905 | ret = wm_coeff_read_control(ctl, ctl->cache, size); |
903 | else | 906 | else |
904 | ret = -EPERM; | 907 | ret = -EPERM; |
905 | } else { | 908 | } else { |
906 | if (!ctl->flags && ctl->enabled) | 909 | if (!ctl->flags && ctl->enabled && ctl->dsp->running) |
907 | ret = wm_coeff_read_control(ctl, ctl->cache, size); | 910 | ret = wm_coeff_read_control(ctl, ctl->cache, size); |
908 | } | 911 | } |
909 | 912 | ||
@@ -2166,13 +2169,20 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, | |||
2166 | if (ret != 0) | 2169 | if (ret != 0) |
2167 | goto err_ena; | 2170 | goto err_ena; |
2168 | 2171 | ||
2172 | dsp->booted = true; | ||
2173 | |||
2169 | /* Start the core running */ | 2174 | /* Start the core running */ |
2170 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, | 2175 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, |
2171 | ADSP1_CORE_ENA | ADSP1_START, | 2176 | ADSP1_CORE_ENA | ADSP1_START, |
2172 | ADSP1_CORE_ENA | ADSP1_START); | 2177 | ADSP1_CORE_ENA | ADSP1_START); |
2178 | |||
2179 | dsp->running = true; | ||
2173 | break; | 2180 | break; |
2174 | 2181 | ||
2175 | case SND_SOC_DAPM_PRE_PMD: | 2182 | case SND_SOC_DAPM_PRE_PMD: |
2183 | dsp->running = false; | ||
2184 | dsp->booted = false; | ||
2185 | |||
2176 | /* Halt the core */ | 2186 | /* Halt the core */ |
2177 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, | 2187 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, |
2178 | ADSP1_CORE_ENA | ADSP1_START, 0); | 2188 | ADSP1_CORE_ENA | ADSP1_START, 0); |
@@ -2227,7 +2237,7 @@ static int wm_adsp2_ena(struct wm_adsp *dsp) | |||
2227 | if (val & ADSP2_RAM_RDY) | 2237 | if (val & ADSP2_RAM_RDY) |
2228 | break; | 2238 | break; |
2229 | 2239 | ||
2230 | msleep(1); | 2240 | usleep_range(250, 500); |
2231 | } | 2241 | } |
2232 | 2242 | ||
2233 | if (!(val & ADSP2_RAM_RDY)) { | 2243 | if (!(val & ADSP2_RAM_RDY)) { |
@@ -2249,6 +2259,11 @@ static void wm_adsp2_boot_work(struct work_struct *work) | |||
2249 | 2259 | ||
2250 | mutex_lock(&dsp->pwr_lock); | 2260 | mutex_lock(&dsp->pwr_lock); |
2251 | 2261 | ||
2262 | ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | ||
2263 | ADSP2_MEM_ENA, ADSP2_MEM_ENA); | ||
2264 | if (ret != 0) | ||
2265 | goto err_mutex; | ||
2266 | |||
2252 | ret = wm_adsp2_ena(dsp); | 2267 | ret = wm_adsp2_ena(dsp); |
2253 | if (ret != 0) | 2268 | if (ret != 0) |
2254 | goto err_mutex; | 2269 | goto err_mutex; |
@@ -2270,13 +2285,14 @@ static void wm_adsp2_boot_work(struct work_struct *work) | |||
2270 | if (ret != 0) | 2285 | if (ret != 0) |
2271 | goto err_ena; | 2286 | goto err_ena; |
2272 | 2287 | ||
2273 | /* Sync set controls */ | 2288 | dsp->booted = true; |
2274 | ret = wm_coeff_sync_controls(dsp); | 2289 | |
2290 | /* Turn DSP back off until we are ready to run */ | ||
2291 | ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | ||
2292 | ADSP2_SYS_ENA, 0); | ||
2275 | if (ret != 0) | 2293 | if (ret != 0) |
2276 | goto err_ena; | 2294 | goto err_ena; |
2277 | 2295 | ||
2278 | dsp->running = true; | ||
2279 | |||
2280 | mutex_unlock(&dsp->pwr_lock); | 2296 | mutex_unlock(&dsp->pwr_lock); |
2281 | 2297 | ||
2282 | return; | 2298 | return; |
@@ -2307,6 +2323,7 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, | |||
2307 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | 2323 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
2308 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); | 2324 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); |
2309 | struct wm_adsp *dsp = &dsps[w->shift]; | 2325 | struct wm_adsp *dsp = &dsps[w->shift]; |
2326 | struct wm_coeff_ctl *ctl; | ||
2310 | 2327 | ||
2311 | dsp->card = codec->component.card; | 2328 | dsp->card = codec->component.card; |
2312 | 2329 | ||
@@ -2315,6 +2332,24 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, | |||
2315 | wm_adsp2_set_dspclk(dsp, freq); | 2332 | wm_adsp2_set_dspclk(dsp, freq); |
2316 | queue_work(system_unbound_wq, &dsp->boot_work); | 2333 | queue_work(system_unbound_wq, &dsp->boot_work); |
2317 | break; | 2334 | break; |
2335 | case SND_SOC_DAPM_PRE_PMD: | ||
2336 | wm_adsp_debugfs_clear(dsp); | ||
2337 | |||
2338 | dsp->fw_id = 0; | ||
2339 | dsp->fw_id_version = 0; | ||
2340 | |||
2341 | dsp->booted = false; | ||
2342 | |||
2343 | regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | ||
2344 | ADSP2_MEM_ENA, 0); | ||
2345 | |||
2346 | list_for_each_entry(ctl, &dsp->ctl_list, list) | ||
2347 | ctl->enabled = 0; | ||
2348 | |||
2349 | wm_adsp_free_alg_regions(dsp); | ||
2350 | |||
2351 | adsp_dbg(dsp, "Shutdown complete\n"); | ||
2352 | break; | ||
2318 | default: | 2353 | default: |
2319 | break; | 2354 | break; |
2320 | } | 2355 | } |
@@ -2329,16 +2364,24 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, | |||
2329 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | 2364 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
2330 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); | 2365 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); |
2331 | struct wm_adsp *dsp = &dsps[w->shift]; | 2366 | struct wm_adsp *dsp = &dsps[w->shift]; |
2332 | struct wm_coeff_ctl *ctl; | ||
2333 | int ret; | 2367 | int ret; |
2334 | 2368 | ||
2335 | switch (event) { | 2369 | switch (event) { |
2336 | case SND_SOC_DAPM_POST_PMU: | 2370 | case SND_SOC_DAPM_POST_PMU: |
2337 | flush_work(&dsp->boot_work); | 2371 | flush_work(&dsp->boot_work); |
2338 | 2372 | ||
2339 | if (!dsp->running) | 2373 | if (!dsp->booted) |
2340 | return -EIO; | 2374 | return -EIO; |
2341 | 2375 | ||
2376 | ret = wm_adsp2_ena(dsp); | ||
2377 | if (ret != 0) | ||
2378 | goto err; | ||
2379 | |||
2380 | /* Sync set controls */ | ||
2381 | ret = wm_coeff_sync_controls(dsp); | ||
2382 | if (ret != 0) | ||
2383 | goto err; | ||
2384 | |||
2342 | ret = regmap_update_bits(dsp->regmap, | 2385 | ret = regmap_update_bits(dsp->regmap, |
2343 | dsp->base + ADSP2_CONTROL, | 2386 | dsp->base + ADSP2_CONTROL, |
2344 | ADSP2_CORE_ENA | ADSP2_START, | 2387 | ADSP2_CORE_ENA | ADSP2_START, |
@@ -2346,6 +2389,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, | |||
2346 | if (ret != 0) | 2389 | if (ret != 0) |
2347 | goto err; | 2390 | goto err; |
2348 | 2391 | ||
2392 | dsp->running = true; | ||
2393 | |||
2349 | mutex_lock(&dsp->pwr_lock); | 2394 | mutex_lock(&dsp->pwr_lock); |
2350 | 2395 | ||
2351 | if (wm_adsp_fw[dsp->fw].num_caps != 0) | 2396 | if (wm_adsp_fw[dsp->fw].num_caps != 0) |
@@ -2361,10 +2406,6 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, | |||
2361 | 2406 | ||
2362 | mutex_lock(&dsp->pwr_lock); | 2407 | mutex_lock(&dsp->pwr_lock); |
2363 | 2408 | ||
2364 | wm_adsp_debugfs_clear(dsp); | ||
2365 | |||
2366 | dsp->fw_id = 0; | ||
2367 | dsp->fw_id_version = 0; | ||
2368 | dsp->running = false; | 2409 | dsp->running = false; |
2369 | 2410 | ||
2370 | regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | 2411 | regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, |
@@ -2378,17 +2419,12 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, | |||
2378 | regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | 2419 | regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, |
2379 | ADSP2_SYS_ENA, 0); | 2420 | ADSP2_SYS_ENA, 0); |
2380 | 2421 | ||
2381 | list_for_each_entry(ctl, &dsp->ctl_list, list) | ||
2382 | ctl->enabled = 0; | ||
2383 | |||
2384 | wm_adsp_free_alg_regions(dsp); | ||
2385 | |||
2386 | if (wm_adsp_fw[dsp->fw].num_caps != 0) | 2422 | if (wm_adsp_fw[dsp->fw].num_caps != 0) |
2387 | wm_adsp_buffer_free(dsp); | 2423 | wm_adsp_buffer_free(dsp); |
2388 | 2424 | ||
2389 | mutex_unlock(&dsp->pwr_lock); | 2425 | mutex_unlock(&dsp->pwr_lock); |
2390 | 2426 | ||
2391 | adsp_dbg(dsp, "Shutdown complete\n"); | 2427 | adsp_dbg(dsp, "Execution stopped\n"); |
2392 | break; | 2428 | break; |
2393 | 2429 | ||
2394 | default: | 2430 | default: |
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index be3b5bcb7f17..362dd7ce60d8 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h | |||
@@ -61,6 +61,8 @@ struct wm_adsp { | |||
61 | 61 | ||
62 | int fw; | 62 | int fw; |
63 | int fw_ver; | 63 | int fw_ver; |
64 | |||
65 | bool booted; | ||
64 | bool running; | 66 | bool running; |
65 | 67 | ||
66 | struct list_head ctl_list; | 68 | struct list_head ctl_list; |
@@ -85,9 +87,10 @@ struct wm_adsp { | |||
85 | wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) | 87 | wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) |
86 | 88 | ||
87 | #define WM_ADSP2(wname, num, event_fn) \ | 89 | #define WM_ADSP2(wname, num, event_fn) \ |
88 | { .id = snd_soc_dapm_dai_link, .name = wname " Preloader", \ | 90 | { .id = snd_soc_dapm_supply, .name = wname " Preloader", \ |
89 | .reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \ | 91 | .reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \ |
90 | .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }, \ | 92 | .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD, \ |
93 | .subseq = 100, /* Ensure we run after SYSCLK supply widget */ }, \ | ||
91 | { .id = snd_soc_dapm_out_drv, .name = wname, \ | 94 | { .id = snd_soc_dapm_out_drv, .name = wname, \ |
92 | .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \ | 95 | .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \ |
93 | .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } | 96 | .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 05c2d33aa74d..3c5a9804d3f5 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -1218,7 +1218,7 @@ static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params, | |||
1218 | 1218 | ||
1219 | snd_mask_none(&nfmt); | 1219 | snd_mask_none(&nfmt); |
1220 | 1220 | ||
1221 | for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { | 1221 | for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) { |
1222 | if (snd_mask_test(fmt, i)) { | 1222 | if (snd_mask_test(fmt, i)) { |
1223 | uint sbits = snd_pcm_format_width(i); | 1223 | uint sbits = snd_pcm_format_width(i); |
1224 | int ppm; | 1224 | int ppm; |
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c index dc97f4349e66..2998954a1c74 100644 --- a/sound/soc/dwc/designware_i2s.c +++ b/sound/soc/dwc/designware_i2s.c | |||
@@ -577,7 +577,6 @@ static int dw_configure_dai_by_dt(struct dw_i2s_dev *dev, | |||
577 | dev->capability |= DWC_I2S_PLAY; | 577 | dev->capability |= DWC_I2S_PLAY; |
578 | dev->play_dma_data.dt.addr = res->start + I2S_TXDMA; | 578 | dev->play_dma_data.dt.addr = res->start + I2S_TXDMA; |
579 | dev->play_dma_data.dt.addr_width = bus_widths[idx]; | 579 | dev->play_dma_data.dt.addr_width = bus_widths[idx]; |
580 | dev->play_dma_data.dt.chan_name = "TX"; | ||
581 | dev->play_dma_data.dt.fifo_size = fifo_depth * | 580 | dev->play_dma_data.dt.fifo_size = fifo_depth * |
582 | (fifo_width[idx2]) >> 8; | 581 | (fifo_width[idx2]) >> 8; |
583 | dev->play_dma_data.dt.maxburst = 16; | 582 | dev->play_dma_data.dt.maxburst = 16; |
@@ -588,7 +587,6 @@ static int dw_configure_dai_by_dt(struct dw_i2s_dev *dev, | |||
588 | dev->capability |= DWC_I2S_RECORD; | 587 | dev->capability |= DWC_I2S_RECORD; |
589 | dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA; | 588 | dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA; |
590 | dev->capture_dma_data.dt.addr_width = bus_widths[idx]; | 589 | dev->capture_dma_data.dt.addr_width = bus_widths[idx]; |
591 | dev->capture_dma_data.dt.chan_name = "RX"; | ||
592 | dev->capture_dma_data.dt.fifo_size = fifo_depth * | 590 | dev->capture_dma_data.dt.fifo_size = fifo_depth * |
593 | (fifo_width[idx2] >> 8); | 591 | (fifo_width[idx2] >> 8); |
594 | dev->capture_dma_data.dt.maxburst = 16; | 592 | dev->capture_dma_data.dt.maxburst = 16; |
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index c1a0e01cb8e7..1d82f68305c3 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c | |||
@@ -726,7 +726,7 @@ static const struct regmap_config fsl_asrc_regmap_config = { | |||
726 | .readable_reg = fsl_asrc_readable_reg, | 726 | .readable_reg = fsl_asrc_readable_reg, |
727 | .volatile_reg = fsl_asrc_volatile_reg, | 727 | .volatile_reg = fsl_asrc_volatile_reg, |
728 | .writeable_reg = fsl_asrc_writeable_reg, | 728 | .writeable_reg = fsl_asrc_writeable_reg, |
729 | .cache_type = REGCACHE_RBTREE, | 729 | .cache_type = REGCACHE_FLAT, |
730 | }; | 730 | }; |
731 | 731 | ||
732 | /** | 732 | /** |
@@ -879,7 +879,7 @@ static int fsl_asrc_probe(struct platform_device *pdev) | |||
879 | } | 879 | } |
880 | } | 880 | } |
881 | 881 | ||
882 | if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx35-asrc")) { | 882 | if (of_device_is_compatible(np, "fsl,imx35-asrc")) { |
883 | asrc_priv->channel_bits = 3; | 883 | asrc_priv->channel_bits = 3; |
884 | clk_map[IN] = input_clk_map_imx35; | 884 | clk_map[IN] = input_clk_map_imx35; |
885 | clk_map[OUT] = output_clk_map_imx35; | 885 | clk_map[OUT] = output_clk_map_imx35; |
@@ -892,7 +892,7 @@ static int fsl_asrc_probe(struct platform_device *pdev) | |||
892 | ret = fsl_asrc_init(asrc_priv); | 892 | ret = fsl_asrc_init(asrc_priv); |
893 | if (ret) { | 893 | if (ret) { |
894 | dev_err(&pdev->dev, "failed to init asrc %d\n", ret); | 894 | dev_err(&pdev->dev, "failed to init asrc %d\n", ret); |
895 | return -EINVAL; | 895 | return ret; |
896 | } | 896 | } |
897 | 897 | ||
898 | asrc_priv->channel_avail = 10; | 898 | asrc_priv->channel_avail = 10; |
@@ -901,14 +901,14 @@ static int fsl_asrc_probe(struct platform_device *pdev) | |||
901 | &asrc_priv->asrc_rate); | 901 | &asrc_priv->asrc_rate); |
902 | if (ret) { | 902 | if (ret) { |
903 | dev_err(&pdev->dev, "failed to get output rate\n"); | 903 | dev_err(&pdev->dev, "failed to get output rate\n"); |
904 | return -EINVAL; | 904 | return ret; |
905 | } | 905 | } |
906 | 906 | ||
907 | ret = of_property_read_u32(np, "fsl,asrc-width", | 907 | ret = of_property_read_u32(np, "fsl,asrc-width", |
908 | &asrc_priv->asrc_width); | 908 | &asrc_priv->asrc_width); |
909 | if (ret) { | 909 | if (ret) { |
910 | dev_err(&pdev->dev, "failed to get output width\n"); | 910 | dev_err(&pdev->dev, "failed to get output width\n"); |
911 | return -EINVAL; | 911 | return ret; |
912 | } | 912 | } |
913 | 913 | ||
914 | if (asrc_priv->asrc_width != 16 && asrc_priv->asrc_width != 24) { | 914 | if (asrc_priv->asrc_width != 16 && asrc_priv->asrc_width != 24) { |
@@ -933,8 +933,6 @@ static int fsl_asrc_probe(struct platform_device *pdev) | |||
933 | return ret; | 933 | return ret; |
934 | } | 934 | } |
935 | 935 | ||
936 | dev_info(&pdev->dev, "driver registered\n"); | ||
937 | |||
938 | return 0; | 936 | return 0; |
939 | } | 937 | } |
940 | 938 | ||
diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c index ffc000bc1f15..dc30d780f874 100644 --- a/sound/soc/fsl/fsl_asrc_dma.c +++ b/sound/soc/fsl/fsl_asrc_dma.c | |||
@@ -322,7 +322,7 @@ static snd_pcm_uframes_t fsl_asrc_dma_pcm_pointer(struct snd_pcm_substream *subs | |||
322 | return bytes_to_frames(substream->runtime, pair->pos); | 322 | return bytes_to_frames(substream->runtime, pair->pos); |
323 | } | 323 | } |
324 | 324 | ||
325 | static struct snd_pcm_ops fsl_asrc_dma_pcm_ops = { | 325 | static const struct snd_pcm_ops fsl_asrc_dma_pcm_ops = { |
326 | .ioctl = snd_pcm_lib_ioctl, | 326 | .ioctl = snd_pcm_lib_ioctl, |
327 | .hw_params = fsl_asrc_dma_hw_params, | 327 | .hw_params = fsl_asrc_dma_hw_params, |
328 | .hw_free = fsl_asrc_dma_hw_free, | 328 | .hw_free = fsl_asrc_dma_hw_free, |
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 26a90e12ede4..38bfd46f4ad8 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c | |||
@@ -77,19 +77,19 @@ static irqreturn_t esai_isr(int irq, void *devid) | |||
77 | regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr); | 77 | regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr); |
78 | 78 | ||
79 | if (esr & ESAI_ESR_TINIT_MASK) | 79 | if (esr & ESAI_ESR_TINIT_MASK) |
80 | dev_dbg(&pdev->dev, "isr: Transmition Initialized\n"); | 80 | dev_dbg(&pdev->dev, "isr: Transmission Initialized\n"); |
81 | 81 | ||
82 | if (esr & ESAI_ESR_RFF_MASK) | 82 | if (esr & ESAI_ESR_RFF_MASK) |
83 | dev_warn(&pdev->dev, "isr: Receiving overrun\n"); | 83 | dev_warn(&pdev->dev, "isr: Receiving overrun\n"); |
84 | 84 | ||
85 | if (esr & ESAI_ESR_TFE_MASK) | 85 | if (esr & ESAI_ESR_TFE_MASK) |
86 | dev_warn(&pdev->dev, "isr: Transmition underrun\n"); | 86 | dev_warn(&pdev->dev, "isr: Transmission underrun\n"); |
87 | 87 | ||
88 | if (esr & ESAI_ESR_TLS_MASK) | 88 | if (esr & ESAI_ESR_TLS_MASK) |
89 | dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n"); | 89 | dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n"); |
90 | 90 | ||
91 | if (esr & ESAI_ESR_TDE_MASK) | 91 | if (esr & ESAI_ESR_TDE_MASK) |
92 | dev_dbg(&pdev->dev, "isr: Transmition data exception\n"); | 92 | dev_dbg(&pdev->dev, "isr: Transmission data exception\n"); |
93 | 93 | ||
94 | if (esr & ESAI_ESR_TED_MASK) | 94 | if (esr & ESAI_ESR_TED_MASK) |
95 | dev_dbg(&pdev->dev, "isr: Transmitting even slots\n"); | 95 | dev_dbg(&pdev->dev, "isr: Transmitting even slots\n"); |
@@ -781,7 +781,7 @@ static const struct regmap_config fsl_esai_regmap_config = { | |||
781 | .readable_reg = fsl_esai_readable_reg, | 781 | .readable_reg = fsl_esai_readable_reg, |
782 | .volatile_reg = fsl_esai_volatile_reg, | 782 | .volatile_reg = fsl_esai_volatile_reg, |
783 | .writeable_reg = fsl_esai_writeable_reg, | 783 | .writeable_reg = fsl_esai_writeable_reg, |
784 | .cache_type = REGCACHE_RBTREE, | 784 | .cache_type = REGCACHE_FLAT, |
785 | }; | 785 | }; |
786 | 786 | ||
787 | static int fsl_esai_probe(struct platform_device *pdev) | 787 | static int fsl_esai_probe(struct platform_device *pdev) |
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 2147994ab46f..9fadf7e31c5f 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c | |||
@@ -801,8 +801,8 @@ static int fsl_sai_probe(struct platform_device *pdev) | |||
801 | 801 | ||
802 | sai->pdev = pdev; | 802 | sai->pdev = pdev; |
803 | 803 | ||
804 | if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx6sx-sai") || | 804 | if (of_device_is_compatible(np, "fsl,imx6sx-sai") || |
805 | of_device_is_compatible(pdev->dev.of_node, "fsl,imx6ul-sai")) | 805 | of_device_is_compatible(np, "fsl,imx6ul-sai")) |
806 | sai->sai_on_imx = true; | 806 | sai->sai_on_imx = true; |
807 | 807 | ||
808 | sai->is_lsb_first = of_property_read_bool(np, "lsb-first"); | 808 | sai->is_lsb_first = of_property_read_bool(np, "lsb-first"); |
@@ -883,7 +883,7 @@ static int fsl_sai_probe(struct platform_device *pdev) | |||
883 | } | 883 | } |
884 | 884 | ||
885 | if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) && | 885 | if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) && |
886 | of_device_is_compatible(pdev->dev.of_node, "fsl,imx6ul-sai")) { | 886 | of_device_is_compatible(np, "fsl,imx6ul-sai")) { |
887 | gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr"); | 887 | gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr"); |
888 | if (IS_ERR(gpr)) { | 888 | if (IS_ERR(gpr)) { |
889 | dev_err(&pdev->dev, "cannot find iomuxc registers\n"); | 889 | dev_err(&pdev->dev, "cannot find iomuxc registers\n"); |
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index beec7934a265..1ff467c9598a 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c | |||
@@ -1103,7 +1103,7 @@ static const struct regmap_config fsl_spdif_regmap_config = { | |||
1103 | .readable_reg = fsl_spdif_readable_reg, | 1103 | .readable_reg = fsl_spdif_readable_reg, |
1104 | .volatile_reg = fsl_spdif_volatile_reg, | 1104 | .volatile_reg = fsl_spdif_volatile_reg, |
1105 | .writeable_reg = fsl_spdif_writeable_reg, | 1105 | .writeable_reg = fsl_spdif_writeable_reg, |
1106 | .cache_type = REGCACHE_RBTREE, | 1106 | .cache_type = REGCACHE_FLAT, |
1107 | }; | 1107 | }; |
1108 | 1108 | ||
1109 | static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, | 1109 | static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, |
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index bedec4a32581..50349437d961 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -182,7 +182,7 @@ static const struct regmap_config fsl_ssi_regconfig = { | |||
182 | .volatile_reg = fsl_ssi_volatile_reg, | 182 | .volatile_reg = fsl_ssi_volatile_reg, |
183 | .precious_reg = fsl_ssi_precious_reg, | 183 | .precious_reg = fsl_ssi_precious_reg, |
184 | .writeable_reg = fsl_ssi_writeable_reg, | 184 | .writeable_reg = fsl_ssi_writeable_reg, |
185 | .cache_type = REGCACHE_RBTREE, | 185 | .cache_type = REGCACHE_FLAT, |
186 | }; | 186 | }; |
187 | 187 | ||
188 | struct fsl_ssi_soc_data { | 188 | struct fsl_ssi_soc_data { |
diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig index c01c5dd68601..d023959b8cd6 100644 --- a/sound/soc/generic/Kconfig +++ b/sound/soc/generic/Kconfig | |||
@@ -6,3 +6,11 @@ config SND_SIMPLE_CARD | |||
6 | select SND_SIMPLE_CARD_UTILS | 6 | select SND_SIMPLE_CARD_UTILS |
7 | help | 7 | help |
8 | This option enables generic simple sound card support | 8 | This option enables generic simple sound card support |
9 | |||
10 | config SND_SIMPLE_SCU_CARD | ||
11 | tristate "ASoC Simple SCU sound card support" | ||
12 | depends on OF | ||
13 | select SND_SIMPLE_CARD_UTILS | ||
14 | help | ||
15 | This option enables generic simple SCU sound card support. | ||
16 | It supports DPCM of multi CPU single Codec system. | ||
diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile index 2d53c8d70705..ee750f3023ba 100644 --- a/sound/soc/generic/Makefile +++ b/sound/soc/generic/Makefile | |||
@@ -1,5 +1,7 @@ | |||
1 | snd-soc-simple-card-utils-objs := simple-card-utils.o | 1 | snd-soc-simple-card-utils-objs := simple-card-utils.o |
2 | snd-soc-simple-card-objs := simple-card.o | 2 | snd-soc-simple-card-objs := simple-card.o |
3 | snd-soc-simple-scu-card-objs := simple-scu-card.o | ||
3 | 4 | ||
4 | obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) += snd-soc-simple-card-utils.o | 5 | obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) += snd-soc-simple-card-utils.o |
5 | obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o | 6 | obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o |
7 | obj-$(CONFIG_SND_SIMPLE_SCU_CARD) += snd-soc-simple-scu-card.o | ||
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 9599de69a880..1cb39309f5d5 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #include <linux/clk.h> | ||
10 | #include <linux/module.h> | 11 | #include <linux/module.h> |
11 | #include <linux/of.h> | 12 | #include <linux/of.h> |
12 | #include <sound/simple_card_utils.h> | 13 | #include <sound/simple_card_utils.h> |
@@ -97,6 +98,146 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card, | |||
97 | } | 98 | } |
98 | EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name); | 99 | EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name); |
99 | 100 | ||
101 | int asoc_simple_card_parse_clk(struct device_node *node, | ||
102 | struct device_node *dai_of_node, | ||
103 | struct asoc_simple_dai *simple_dai) | ||
104 | { | ||
105 | struct clk *clk; | ||
106 | u32 val; | ||
107 | |||
108 | /* | ||
109 | * Parse dai->sysclk come from "clocks = <&xxx>" | ||
110 | * (if system has common clock) | ||
111 | * or "system-clock-frequency = <xxx>" | ||
112 | * or device's module clock. | ||
113 | */ | ||
114 | clk = of_clk_get(node, 0); | ||
115 | if (!IS_ERR(clk)) { | ||
116 | simple_dai->sysclk = clk_get_rate(clk); | ||
117 | simple_dai->clk = clk; | ||
118 | } else if (!of_property_read_u32(node, "system-clock-frequency", &val)) { | ||
119 | simple_dai->sysclk = val; | ||
120 | } else { | ||
121 | clk = of_clk_get(dai_of_node, 0); | ||
122 | if (!IS_ERR(clk)) | ||
123 | simple_dai->sysclk = clk_get_rate(clk); | ||
124 | } | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | EXPORT_SYMBOL_GPL(asoc_simple_card_parse_clk); | ||
129 | |||
130 | int asoc_simple_card_parse_dai(struct device_node *node, | ||
131 | struct device_node **dai_of_node, | ||
132 | const char **dai_name, | ||
133 | const char *list_name, | ||
134 | const char *cells_name, | ||
135 | int *is_single_link) | ||
136 | { | ||
137 | struct of_phandle_args args; | ||
138 | int ret; | ||
139 | |||
140 | if (!node) | ||
141 | return 0; | ||
142 | |||
143 | /* | ||
144 | * Get node via "sound-dai = <&phandle port>" | ||
145 | * it will be used as xxx_of_node on soc_bind_dai_link() | ||
146 | */ | ||
147 | ret = of_parse_phandle_with_args(node, list_name, cells_name, 0, &args); | ||
148 | if (ret) | ||
149 | return ret; | ||
150 | |||
151 | /* Get dai->name */ | ||
152 | if (dai_name) { | ||
153 | ret = snd_soc_of_get_dai_name(node, dai_name); | ||
154 | if (ret < 0) | ||
155 | return ret; | ||
156 | } | ||
157 | |||
158 | *dai_of_node = args.np; | ||
159 | |||
160 | if (is_single_link) | ||
161 | *is_single_link = !args.args_count; | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | EXPORT_SYMBOL_GPL(asoc_simple_card_parse_dai); | ||
166 | |||
167 | int asoc_simple_card_init_dai(struct snd_soc_dai *dai, | ||
168 | struct asoc_simple_dai *simple_dai) | ||
169 | { | ||
170 | int ret; | ||
171 | |||
172 | if (simple_dai->sysclk) { | ||
173 | ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk, 0); | ||
174 | if (ret && ret != -ENOTSUPP) { | ||
175 | dev_err(dai->dev, "simple-card: set_sysclk error\n"); | ||
176 | return ret; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | if (simple_dai->slots) { | ||
181 | ret = snd_soc_dai_set_tdm_slot(dai, | ||
182 | simple_dai->tx_slot_mask, | ||
183 | simple_dai->rx_slot_mask, | ||
184 | simple_dai->slots, | ||
185 | simple_dai->slot_width); | ||
186 | if (ret && ret != -ENOTSUPP) { | ||
187 | dev_err(dai->dev, "simple-card: set_tdm_slot error\n"); | ||
188 | return ret; | ||
189 | } | ||
190 | } | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | EXPORT_SYMBOL_GPL(asoc_simple_card_init_dai); | ||
195 | |||
196 | int asoc_simple_card_canonicalize_dailink(struct snd_soc_dai_link *dai_link) | ||
197 | { | ||
198 | if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) | ||
199 | return -EINVAL; | ||
200 | |||
201 | /* Assumes platform == cpu */ | ||
202 | if (!dai_link->platform_of_node) | ||
203 | dai_link->platform_of_node = dai_link->cpu_of_node; | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | EXPORT_SYMBOL_GPL(asoc_simple_card_canonicalize_dailink); | ||
208 | |||
209 | void asoc_simple_card_canonicalize_cpu(struct snd_soc_dai_link *dai_link, | ||
210 | int is_single_links) | ||
211 | { | ||
212 | /* | ||
213 | * In soc_bind_dai_link() will check cpu name after | ||
214 | * of_node matching if dai_link has cpu_dai_name. | ||
215 | * but, it will never match if name was created by | ||
216 | * fmt_single_name() remove cpu_dai_name if cpu_args | ||
217 | * was 0. See: | ||
218 | * fmt_single_name() | ||
219 | * fmt_multiple_name() | ||
220 | */ | ||
221 | if (is_single_links) | ||
222 | dai_link->cpu_dai_name = NULL; | ||
223 | } | ||
224 | EXPORT_SYMBOL_GPL(asoc_simple_card_canonicalize_cpu); | ||
225 | |||
226 | int asoc_simple_card_clean_reference(struct snd_soc_card *card) | ||
227 | { | ||
228 | struct snd_soc_dai_link *dai_link; | ||
229 | int num_links; | ||
230 | |||
231 | for (num_links = 0, dai_link = card->dai_link; | ||
232 | num_links < card->num_links; | ||
233 | num_links++, dai_link++) { | ||
234 | of_node_put(dai_link->cpu_of_node); | ||
235 | of_node_put(dai_link->codec_of_node); | ||
236 | } | ||
237 | return 0; | ||
238 | } | ||
239 | EXPORT_SYMBOL_GPL(asoc_simple_card_clean_reference); | ||
240 | |||
100 | /* Module information */ | 241 | /* Module information */ |
101 | MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); | 242 | MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); |
102 | MODULE_DESCRIPTION("ALSA SoC Simple Card Utils"); | 243 | MODULE_DESCRIPTION("ALSA SoC Simple Card Utils"); |
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 43295f024982..f608f8d23f3d 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c | |||
@@ -37,13 +37,15 @@ struct simple_card_data { | |||
37 | unsigned int mclk_fs; | 37 | unsigned int mclk_fs; |
38 | struct asoc_simple_jack hp_jack; | 38 | struct asoc_simple_jack hp_jack; |
39 | struct asoc_simple_jack mic_jack; | 39 | struct asoc_simple_jack mic_jack; |
40 | struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ | 40 | struct snd_soc_dai_link *dai_link; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | #define simple_priv_to_dev(priv) ((priv)->snd_card.dev) | 43 | #define simple_priv_to_dev(priv) ((priv)->snd_card.dev) |
44 | #define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i) | 44 | #define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i)) |
45 | #define simple_priv_to_props(priv, i) ((priv)->dai_props + i) | 45 | #define simple_priv_to_props(priv, i) ((priv)->dai_props + (i)) |
46 | 46 | ||
47 | #define DAI "sound-dai" | ||
48 | #define CELL "#sound-dai-cells" | ||
47 | #define PREFIX "simple-audio-card," | 49 | #define PREFIX "simple-audio-card," |
48 | 50 | ||
49 | #define asoc_simple_card_init_hp(card, sjack, prefix)\ | 51 | #define asoc_simple_card_init_hp(card, sjack, prefix)\ |
@@ -112,13 +114,13 @@ static int asoc_simple_card_startup(struct snd_pcm_substream *substream) | |||
112 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 114 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
113 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); | 115 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); |
114 | struct simple_dai_props *dai_props = | 116 | struct simple_dai_props *dai_props = |
115 | &priv->dai_props[rtd->num]; | 117 | simple_priv_to_props(priv, rtd->num); |
116 | int ret; | 118 | int ret; |
117 | 119 | ||
118 | ret = clk_prepare_enable(dai_props->cpu_dai.clk); | 120 | ret = clk_prepare_enable(dai_props->cpu_dai.clk); |
119 | if (ret) | 121 | if (ret) |
120 | return ret; | 122 | return ret; |
121 | 123 | ||
122 | ret = clk_prepare_enable(dai_props->codec_dai.clk); | 124 | ret = clk_prepare_enable(dai_props->codec_dai.clk); |
123 | if (ret) | 125 | if (ret) |
124 | clk_disable_unprepare(dai_props->cpu_dai.clk); | 126 | clk_disable_unprepare(dai_props->cpu_dai.clk); |
@@ -131,7 +133,7 @@ static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream) | |||
131 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 133 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
132 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); | 134 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); |
133 | struct simple_dai_props *dai_props = | 135 | struct simple_dai_props *dai_props = |
134 | &priv->dai_props[rtd->num]; | 136 | simple_priv_to_props(priv, rtd->num); |
135 | 137 | ||
136 | clk_disable_unprepare(dai_props->cpu_dai.clk); | 138 | clk_disable_unprepare(dai_props->cpu_dai.clk); |
137 | 139 | ||
@@ -145,7 +147,8 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream, | |||
145 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 147 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
146 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 148 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
147 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); | 149 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); |
148 | struct simple_dai_props *dai_props = &priv->dai_props[rtd->num]; | 150 | struct simple_dai_props *dai_props = |
151 | simple_priv_to_props(priv, rtd->num); | ||
149 | unsigned int mclk, mclk_fs = 0; | 152 | unsigned int mclk, mclk_fs = 0; |
150 | int ret = 0; | 153 | int ret = 0; |
151 | 154 | ||
@@ -177,51 +180,20 @@ static struct snd_soc_ops asoc_simple_card_ops = { | |||
177 | .hw_params = asoc_simple_card_hw_params, | 180 | .hw_params = asoc_simple_card_hw_params, |
178 | }; | 181 | }; |
179 | 182 | ||
180 | static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, | ||
181 | struct asoc_simple_dai *set) | ||
182 | { | ||
183 | int ret; | ||
184 | |||
185 | if (set->sysclk) { | ||
186 | ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0); | ||
187 | if (ret && ret != -ENOTSUPP) { | ||
188 | dev_err(dai->dev, "simple-card: set_sysclk error\n"); | ||
189 | goto err; | ||
190 | } | ||
191 | } | ||
192 | |||
193 | if (set->slots) { | ||
194 | ret = snd_soc_dai_set_tdm_slot(dai, | ||
195 | set->tx_slot_mask, | ||
196 | set->rx_slot_mask, | ||
197 | set->slots, | ||
198 | set->slot_width); | ||
199 | if (ret && ret != -ENOTSUPP) { | ||
200 | dev_err(dai->dev, "simple-card: set_tdm_slot error\n"); | ||
201 | goto err; | ||
202 | } | ||
203 | } | ||
204 | |||
205 | ret = 0; | ||
206 | |||
207 | err: | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) | 183 | static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) |
212 | { | 184 | { |
213 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); | 185 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); |
214 | struct snd_soc_dai *codec = rtd->codec_dai; | 186 | struct snd_soc_dai *codec = rtd->codec_dai; |
215 | struct snd_soc_dai *cpu = rtd->cpu_dai; | 187 | struct snd_soc_dai *cpu = rtd->cpu_dai; |
216 | struct simple_dai_props *dai_props; | 188 | struct simple_dai_props *dai_props = |
189 | simple_priv_to_props(priv, rtd->num); | ||
217 | int ret; | 190 | int ret; |
218 | 191 | ||
219 | dai_props = &priv->dai_props[rtd->num]; | 192 | ret = asoc_simple_card_init_dai(codec, &dai_props->codec_dai); |
220 | ret = __asoc_simple_card_dai_init(codec, &dai_props->codec_dai); | ||
221 | if (ret < 0) | 193 | if (ret < 0) |
222 | return ret; | 194 | return ret; |
223 | 195 | ||
224 | ret = __asoc_simple_card_dai_init(cpu, &dai_props->cpu_dai); | 196 | ret = asoc_simple_card_init_dai(cpu, &dai_props->cpu_dai); |
225 | if (ret < 0) | 197 | if (ret < 0) |
226 | return ret; | 198 | return ret; |
227 | 199 | ||
@@ -236,78 +208,6 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) | |||
236 | return 0; | 208 | return 0; |
237 | } | 209 | } |
238 | 210 | ||
239 | static int | ||
240 | asoc_simple_card_sub_parse_of(struct device_node *np, | ||
241 | struct asoc_simple_dai *dai, | ||
242 | struct device_node **p_node, | ||
243 | const char **name, | ||
244 | int *args_count) | ||
245 | { | ||
246 | struct of_phandle_args args; | ||
247 | struct clk *clk; | ||
248 | u32 val; | ||
249 | int ret; | ||
250 | |||
251 | if (!np) | ||
252 | return 0; | ||
253 | |||
254 | /* | ||
255 | * Get node via "sound-dai = <&phandle port>" | ||
256 | * it will be used as xxx_of_node on soc_bind_dai_link() | ||
257 | */ | ||
258 | ret = of_parse_phandle_with_args(np, "sound-dai", | ||
259 | "#sound-dai-cells", 0, &args); | ||
260 | if (ret) | ||
261 | return ret; | ||
262 | |||
263 | *p_node = args.np; | ||
264 | |||
265 | if (args_count) | ||
266 | *args_count = args.args_count; | ||
267 | |||
268 | /* Get dai->name */ | ||
269 | if (name) { | ||
270 | ret = snd_soc_of_get_dai_name(np, name); | ||
271 | if (ret < 0) | ||
272 | return ret; | ||
273 | } | ||
274 | |||
275 | if (!dai) | ||
276 | return 0; | ||
277 | |||
278 | /* Parse TDM slot */ | ||
279 | ret = snd_soc_of_parse_tdm_slot(np, &dai->tx_slot_mask, | ||
280 | &dai->rx_slot_mask, | ||
281 | &dai->slots, &dai->slot_width); | ||
282 | if (ret) | ||
283 | return ret; | ||
284 | |||
285 | /* | ||
286 | * Parse dai->sysclk come from "clocks = <&xxx>" | ||
287 | * (if system has common clock) | ||
288 | * or "system-clock-frequency = <xxx>" | ||
289 | * or device's module clock. | ||
290 | */ | ||
291 | if (of_property_read_bool(np, "clocks")) { | ||
292 | clk = of_clk_get(np, 0); | ||
293 | if (IS_ERR(clk)) { | ||
294 | ret = PTR_ERR(clk); | ||
295 | return ret; | ||
296 | } | ||
297 | |||
298 | dai->sysclk = clk_get_rate(clk); | ||
299 | dai->clk = clk; | ||
300 | } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) { | ||
301 | dai->sysclk = val; | ||
302 | } else { | ||
303 | clk = of_clk_get(args.np, 0); | ||
304 | if (!IS_ERR(clk)) | ||
305 | dai->sysclk = clk_get_rate(clk); | ||
306 | } | ||
307 | |||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static int asoc_simple_card_dai_link_of(struct device_node *node, | 211 | static int asoc_simple_card_dai_link_of(struct device_node *node, |
312 | struct simple_card_data *priv, | 212 | struct simple_card_data *priv, |
313 | int idx, | 213 | int idx, |
@@ -316,13 +216,14 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, | |||
316 | struct device *dev = simple_priv_to_dev(priv); | 216 | struct device *dev = simple_priv_to_dev(priv); |
317 | struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx); | 217 | struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx); |
318 | struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx); | 218 | struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx); |
219 | struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai; | ||
220 | struct asoc_simple_dai *codec_dai = &dai_props->codec_dai; | ||
319 | struct device_node *cpu = NULL; | 221 | struct device_node *cpu = NULL; |
320 | struct device_node *plat = NULL; | 222 | struct device_node *plat = NULL; |
321 | struct device_node *codec = NULL; | 223 | struct device_node *codec = NULL; |
322 | char prop[128]; | 224 | char prop[128]; |
323 | char *prefix = ""; | 225 | char *prefix = ""; |
324 | int ret, cpu_args; | 226 | int ret, single_cpu; |
325 | u32 val; | ||
326 | 227 | ||
327 | /* For single DAI link & old style of DT node */ | 228 | /* For single DAI link & old style of DT node */ |
328 | if (is_top_level_node) | 229 | if (is_top_level_node) |
@@ -348,36 +249,46 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, | |||
348 | if (ret < 0) | 249 | if (ret < 0) |
349 | goto dai_link_of_err; | 250 | goto dai_link_of_err; |
350 | 251 | ||
351 | if (!of_property_read_u32(node, "mclk-fs", &val)) | 252 | of_property_read_u32(node, "mclk-fs", &dai_props->mclk_fs); |
352 | dai_props->mclk_fs = val; | ||
353 | 253 | ||
354 | ret = asoc_simple_card_sub_parse_of(cpu, &dai_props->cpu_dai, | 254 | ret = asoc_simple_card_parse_cpu(cpu, dai_link, |
355 | &dai_link->cpu_of_node, | 255 | DAI, CELL, &single_cpu); |
356 | &dai_link->cpu_dai_name, | ||
357 | &cpu_args); | ||
358 | if (ret < 0) | 256 | if (ret < 0) |
359 | goto dai_link_of_err; | 257 | goto dai_link_of_err; |
360 | 258 | ||
361 | ret = asoc_simple_card_sub_parse_of(codec, &dai_props->codec_dai, | 259 | ret = asoc_simple_card_parse_codec(codec, dai_link, DAI, CELL); |
362 | &dai_link->codec_of_node, | ||
363 | &dai_link->codec_dai_name, NULL); | ||
364 | if (ret < 0) | 260 | if (ret < 0) |
365 | goto dai_link_of_err; | 261 | goto dai_link_of_err; |
366 | 262 | ||
367 | ret = asoc_simple_card_sub_parse_of(plat, NULL, | 263 | ret = asoc_simple_card_parse_platform(plat, dai_link, DAI, CELL); |
368 | &dai_link->platform_of_node, | ||
369 | NULL, NULL); | ||
370 | if (ret < 0) | 264 | if (ret < 0) |
371 | goto dai_link_of_err; | 265 | goto dai_link_of_err; |
372 | 266 | ||
373 | if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) { | 267 | ret = snd_soc_of_parse_tdm_slot(cpu, &cpu_dai->tx_slot_mask, |
374 | ret = -EINVAL; | 268 | &cpu_dai->rx_slot_mask, |
269 | &cpu_dai->slots, | ||
270 | &cpu_dai->slot_width); | ||
271 | if (ret < 0) | ||
272 | goto dai_link_of_err; | ||
273 | |||
274 | ret = snd_soc_of_parse_tdm_slot(codec, &codec_dai->tx_slot_mask, | ||
275 | &codec_dai->rx_slot_mask, | ||
276 | &codec_dai->slots, | ||
277 | &codec_dai->slot_width); | ||
278 | if (ret < 0) | ||
279 | goto dai_link_of_err; | ||
280 | |||
281 | ret = asoc_simple_card_parse_clk_cpu(cpu, dai_link, cpu_dai); | ||
282 | if (ret < 0) | ||
375 | goto dai_link_of_err; | 283 | goto dai_link_of_err; |
376 | } | ||
377 | 284 | ||
378 | /* Assumes platform == cpu */ | 285 | ret = asoc_simple_card_parse_clk_codec(codec, dai_link, codec_dai); |
379 | if (!dai_link->platform_of_node) | 286 | if (ret < 0) |
380 | dai_link->platform_of_node = dai_link->cpu_of_node; | 287 | goto dai_link_of_err; |
288 | |||
289 | ret = asoc_simple_card_canonicalize_dailink(dai_link); | ||
290 | if (ret < 0) | ||
291 | goto dai_link_of_err; | ||
381 | 292 | ||
382 | ret = asoc_simple_card_set_dailink_name(dev, dai_link, | 293 | ret = asoc_simple_card_set_dailink_name(dev, dai_link, |
383 | "%s-%s", | 294 | "%s-%s", |
@@ -398,17 +309,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, | |||
398 | dai_link->codec_dai_name, | 309 | dai_link->codec_dai_name, |
399 | dai_props->codec_dai.sysclk); | 310 | dai_props->codec_dai.sysclk); |
400 | 311 | ||
401 | /* | 312 | asoc_simple_card_canonicalize_cpu(dai_link, single_cpu); |
402 | * In soc_bind_dai_link() will check cpu name after | ||
403 | * of_node matching if dai_link has cpu_dai_name. | ||
404 | * but, it will never match if name was created by | ||
405 | * fmt_single_name() remove cpu_dai_name if cpu_args | ||
406 | * was 0. See: | ||
407 | * fmt_single_name() | ||
408 | * fmt_multiple_name() | ||
409 | */ | ||
410 | if (!cpu_args) | ||
411 | dai_link->cpu_dai_name = NULL; | ||
412 | 313 | ||
413 | dai_link_of_err: | 314 | dai_link_of_err: |
414 | of_node_put(cpu); | 315 | of_node_put(cpu); |
@@ -417,22 +318,54 @@ dai_link_of_err: | |||
417 | return ret; | 318 | return ret; |
418 | } | 319 | } |
419 | 320 | ||
321 | static int asoc_simple_card_parse_aux_devs(struct device_node *node, | ||
322 | struct simple_card_data *priv) | ||
323 | { | ||
324 | struct device *dev = simple_priv_to_dev(priv); | ||
325 | struct device_node *aux_node; | ||
326 | int i, n, len; | ||
327 | |||
328 | if (!of_find_property(node, PREFIX "aux-devs", &len)) | ||
329 | return 0; /* Ok to have no aux-devs */ | ||
330 | |||
331 | n = len / sizeof(__be32); | ||
332 | if (n <= 0) | ||
333 | return -EINVAL; | ||
334 | |||
335 | priv->snd_card.aux_dev = devm_kzalloc(dev, | ||
336 | n * sizeof(*priv->snd_card.aux_dev), GFP_KERNEL); | ||
337 | if (!priv->snd_card.aux_dev) | ||
338 | return -ENOMEM; | ||
339 | |||
340 | for (i = 0; i < n; i++) { | ||
341 | aux_node = of_parse_phandle(node, PREFIX "aux-devs", i); | ||
342 | if (!aux_node) | ||
343 | return -EINVAL; | ||
344 | priv->snd_card.aux_dev[i].codec_of_node = aux_node; | ||
345 | } | ||
346 | |||
347 | priv->snd_card.num_aux_devs = n; | ||
348 | return 0; | ||
349 | } | ||
350 | |||
420 | static int asoc_simple_card_parse_of(struct device_node *node, | 351 | static int asoc_simple_card_parse_of(struct device_node *node, |
421 | struct simple_card_data *priv) | 352 | struct simple_card_data *priv) |
422 | { | 353 | { |
423 | struct device *dev = simple_priv_to_dev(priv); | 354 | struct device *dev = simple_priv_to_dev(priv); |
424 | u32 val; | 355 | struct device_node *dai_link; |
425 | int ret; | 356 | int ret; |
426 | 357 | ||
427 | if (!node) | 358 | if (!node) |
428 | return -EINVAL; | 359 | return -EINVAL; |
429 | 360 | ||
361 | dai_link = of_get_child_by_name(node, PREFIX "dai-link"); | ||
362 | |||
430 | /* The off-codec widgets */ | 363 | /* The off-codec widgets */ |
431 | if (of_property_read_bool(node, PREFIX "widgets")) { | 364 | if (of_property_read_bool(node, PREFIX "widgets")) { |
432 | ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card, | 365 | ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card, |
433 | PREFIX "widgets"); | 366 | PREFIX "widgets"); |
434 | if (ret) | 367 | if (ret) |
435 | return ret; | 368 | goto card_parse_end; |
436 | } | 369 | } |
437 | 370 | ||
438 | /* DAPM routes */ | 371 | /* DAPM routes */ |
@@ -440,16 +373,14 @@ static int asoc_simple_card_parse_of(struct device_node *node, | |||
440 | ret = snd_soc_of_parse_audio_routing(&priv->snd_card, | 373 | ret = snd_soc_of_parse_audio_routing(&priv->snd_card, |
441 | PREFIX "routing"); | 374 | PREFIX "routing"); |
442 | if (ret) | 375 | if (ret) |
443 | return ret; | 376 | goto card_parse_end; |
444 | } | 377 | } |
445 | 378 | ||
446 | /* Factor to mclk, used in hw_params() */ | 379 | /* Factor to mclk, used in hw_params() */ |
447 | ret = of_property_read_u32(node, PREFIX "mclk-fs", &val); | 380 | of_property_read_u32(node, PREFIX "mclk-fs", &priv->mclk_fs); |
448 | if (ret == 0) | ||
449 | priv->mclk_fs = val; | ||
450 | 381 | ||
451 | /* Single/Muti DAI link(s) & New style of DT node */ | 382 | /* Single/Muti DAI link(s) & New style of DT node */ |
452 | if (of_get_child_by_name(node, PREFIX "dai-link")) { | 383 | if (dai_link) { |
453 | struct device_node *np = NULL; | 384 | struct device_node *np = NULL; |
454 | int i = 0; | 385 | int i = 0; |
455 | 386 | ||
@@ -459,7 +390,7 @@ static int asoc_simple_card_parse_of(struct device_node *node, | |||
459 | i, false); | 390 | i, false); |
460 | if (ret < 0) { | 391 | if (ret < 0) { |
461 | of_node_put(np); | 392 | of_node_put(np); |
462 | return ret; | 393 | goto card_parse_end; |
463 | } | 394 | } |
464 | i++; | 395 | i++; |
465 | } | 396 | } |
@@ -467,66 +398,55 @@ static int asoc_simple_card_parse_of(struct device_node *node, | |||
467 | /* For single DAI link & old style of DT node */ | 398 | /* For single DAI link & old style of DT node */ |
468 | ret = asoc_simple_card_dai_link_of(node, priv, 0, true); | 399 | ret = asoc_simple_card_dai_link_of(node, priv, 0, true); |
469 | if (ret < 0) | 400 | if (ret < 0) |
470 | return ret; | 401 | goto card_parse_end; |
471 | } | 402 | } |
472 | 403 | ||
473 | ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX); | 404 | ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX); |
474 | if (ret) | 405 | if (ret < 0) |
475 | return ret; | 406 | goto card_parse_end; |
476 | 407 | ||
477 | return 0; | 408 | ret = asoc_simple_card_parse_aux_devs(node, priv); |
478 | } | ||
479 | 409 | ||
480 | /* Decrease the reference count of the device nodes */ | 410 | card_parse_end: |
481 | static int asoc_simple_card_unref(struct snd_soc_card *card) | 411 | of_node_put(dai_link); |
482 | { | ||
483 | struct snd_soc_dai_link *dai_link; | ||
484 | int num_links; | ||
485 | 412 | ||
486 | for (num_links = 0, dai_link = card->dai_link; | 413 | return ret; |
487 | num_links < card->num_links; | ||
488 | num_links++, dai_link++) { | ||
489 | of_node_put(dai_link->cpu_of_node); | ||
490 | of_node_put(dai_link->codec_of_node); | ||
491 | } | ||
492 | return 0; | ||
493 | } | 414 | } |
494 | 415 | ||
495 | static int asoc_simple_card_probe(struct platform_device *pdev) | 416 | static int asoc_simple_card_probe(struct platform_device *pdev) |
496 | { | 417 | { |
497 | struct simple_card_data *priv; | 418 | struct simple_card_data *priv; |
498 | struct snd_soc_dai_link *dai_link; | 419 | struct snd_soc_dai_link *dai_link; |
420 | struct simple_dai_props *dai_props; | ||
499 | struct device_node *np = pdev->dev.of_node; | 421 | struct device_node *np = pdev->dev.of_node; |
500 | struct device *dev = &pdev->dev; | 422 | struct device *dev = &pdev->dev; |
501 | int num_links, ret; | 423 | int num, ret; |
502 | 424 | ||
503 | /* Get the number of DAI links */ | 425 | /* Get the number of DAI links */ |
504 | if (np && of_get_child_by_name(np, PREFIX "dai-link")) | 426 | if (np && of_get_child_by_name(np, PREFIX "dai-link")) |
505 | num_links = of_get_child_count(np); | 427 | num = of_get_child_count(np); |
506 | else | 428 | else |
507 | num_links = 1; | 429 | num = 1; |
508 | 430 | ||
509 | /* Allocate the private data and the DAI link array */ | 431 | /* Allocate the private data and the DAI link array */ |
510 | priv = devm_kzalloc(dev, | 432 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
511 | sizeof(*priv) + sizeof(*dai_link) * num_links, | ||
512 | GFP_KERNEL); | ||
513 | if (!priv) | 433 | if (!priv) |
514 | return -ENOMEM; | 434 | return -ENOMEM; |
515 | 435 | ||
516 | /* Init snd_soc_card */ | 436 | dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL); |
517 | priv->snd_card.owner = THIS_MODULE; | 437 | dai_link = devm_kzalloc(dev, sizeof(*dai_link) * num, GFP_KERNEL); |
518 | priv->snd_card.dev = dev; | 438 | if (!dai_props || !dai_link) |
519 | dai_link = priv->dai_link; | ||
520 | priv->snd_card.dai_link = dai_link; | ||
521 | priv->snd_card.num_links = num_links; | ||
522 | |||
523 | /* Get room for the other properties */ | ||
524 | priv->dai_props = devm_kzalloc(dev, | ||
525 | sizeof(*priv->dai_props) * num_links, | ||
526 | GFP_KERNEL); | ||
527 | if (!priv->dai_props) | ||
528 | return -ENOMEM; | 439 | return -ENOMEM; |
529 | 440 | ||
441 | priv->dai_props = dai_props; | ||
442 | priv->dai_link = dai_link; | ||
443 | |||
444 | /* Init snd_soc_card */ | ||
445 | priv->snd_card.owner = THIS_MODULE; | ||
446 | priv->snd_card.dev = dev; | ||
447 | priv->snd_card.dai_link = priv->dai_link; | ||
448 | priv->snd_card.num_links = num; | ||
449 | |||
530 | if (np && of_device_is_available(np)) { | 450 | if (np && of_device_is_available(np)) { |
531 | 451 | ||
532 | ret = asoc_simple_card_parse_of(np, priv); | 452 | ret = asoc_simple_card_parse_of(np, priv); |
@@ -567,7 +487,6 @@ static int asoc_simple_card_probe(struct platform_device *pdev) | |||
567 | sizeof(priv->dai_props->cpu_dai)); | 487 | sizeof(priv->dai_props->cpu_dai)); |
568 | memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai, | 488 | memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai, |
569 | sizeof(priv->dai_props->codec_dai)); | 489 | sizeof(priv->dai_props->codec_dai)); |
570 | |||
571 | } | 490 | } |
572 | 491 | ||
573 | snd_soc_card_set_drvdata(&priv->snd_card, priv); | 492 | snd_soc_card_set_drvdata(&priv->snd_card, priv); |
@@ -575,9 +494,9 @@ static int asoc_simple_card_probe(struct platform_device *pdev) | |||
575 | ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); | 494 | ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); |
576 | if (ret >= 0) | 495 | if (ret >= 0) |
577 | return ret; | 496 | return ret; |
578 | |||
579 | err: | 497 | err: |
580 | asoc_simple_card_unref(&priv->snd_card); | 498 | asoc_simple_card_clean_reference(&priv->snd_card); |
499 | |||
581 | return ret; | 500 | return ret; |
582 | } | 501 | } |
583 | 502 | ||
@@ -589,7 +508,7 @@ static int asoc_simple_card_remove(struct platform_device *pdev) | |||
589 | asoc_simple_card_remove_jack(&priv->hp_jack); | 508 | asoc_simple_card_remove_jack(&priv->hp_jack); |
590 | asoc_simple_card_remove_jack(&priv->mic_jack); | 509 | asoc_simple_card_remove_jack(&priv->mic_jack); |
591 | 510 | ||
592 | return asoc_simple_card_unref(card); | 511 | return asoc_simple_card_clean_reference(card); |
593 | } | 512 | } |
594 | 513 | ||
595 | static const struct of_device_id asoc_simple_of_match[] = { | 514 | static const struct of_device_id asoc_simple_of_match[] = { |
@@ -611,6 +530,6 @@ static struct platform_driver asoc_simple_card = { | |||
611 | module_platform_driver(asoc_simple_card); | 530 | module_platform_driver(asoc_simple_card); |
612 | 531 | ||
613 | MODULE_ALIAS("platform:asoc-simple-card"); | 532 | MODULE_ALIAS("platform:asoc-simple-card"); |
614 | MODULE_LICENSE("GPL"); | 533 | MODULE_LICENSE("GPL v2"); |
615 | MODULE_DESCRIPTION("ASoC Simple Sound Card"); | 534 | MODULE_DESCRIPTION("ASoC Simple Sound Card"); |
616 | MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); | 535 | MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); |
diff --git a/sound/soc/generic/simple-scu-card.c b/sound/soc/generic/simple-scu-card.c new file mode 100644 index 000000000000..b9973a56bcb0 --- /dev/null +++ b/sound/soc/generic/simple-scu-card.c | |||
@@ -0,0 +1,345 @@ | |||
1 | /* | ||
2 | * ASoC simple SCU sound card support | ||
3 | * | ||
4 | * Copyright (C) 2015 Renesas Solutions Corp. | ||
5 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | ||
6 | * | ||
7 | * based on ${LINUX}/sound/soc/generic/simple-card.c | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | #include <linux/clk.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/of_device.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <sound/jack.h> | ||
21 | #include <sound/soc.h> | ||
22 | #include <sound/soc-dai.h> | ||
23 | #include <sound/simple_card_utils.h> | ||
24 | |||
25 | struct asoc_simple_card_priv { | ||
26 | struct snd_soc_card snd_card; | ||
27 | struct snd_soc_codec_conf codec_conf; | ||
28 | struct asoc_simple_dai *dai_props; | ||
29 | struct snd_soc_dai_link *dai_link; | ||
30 | u32 convert_rate; | ||
31 | u32 convert_channels; | ||
32 | }; | ||
33 | |||
34 | #define simple_priv_to_dev(priv) ((priv)->snd_card.dev) | ||
35 | #define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i)) | ||
36 | #define simple_priv_to_props(priv, i) ((priv)->dai_props + (i)) | ||
37 | |||
38 | #define DAI "sound-dai" | ||
39 | #define CELL "#sound-dai-cells" | ||
40 | #define PREFIX "simple-audio-card," | ||
41 | |||
42 | static int asoc_simple_card_startup(struct snd_pcm_substream *substream) | ||
43 | { | ||
44 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
45 | struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
46 | struct asoc_simple_dai *dai_props = | ||
47 | simple_priv_to_props(priv, rtd->num); | ||
48 | |||
49 | return clk_prepare_enable(dai_props->clk); | ||
50 | } | ||
51 | |||
52 | static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream) | ||
53 | { | ||
54 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
55 | struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
56 | struct asoc_simple_dai *dai_props = | ||
57 | simple_priv_to_props(priv, rtd->num); | ||
58 | |||
59 | clk_disable_unprepare(dai_props->clk); | ||
60 | } | ||
61 | |||
62 | static struct snd_soc_ops asoc_simple_card_ops = { | ||
63 | .startup = asoc_simple_card_startup, | ||
64 | .shutdown = asoc_simple_card_shutdown, | ||
65 | }; | ||
66 | |||
67 | static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) | ||
68 | { | ||
69 | struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
70 | struct snd_soc_dai *dai; | ||
71 | struct snd_soc_dai_link *dai_link; | ||
72 | struct asoc_simple_dai *dai_props; | ||
73 | int num = rtd->num; | ||
74 | |||
75 | dai_link = simple_priv_to_link(priv, num); | ||
76 | dai_props = simple_priv_to_props(priv, num); | ||
77 | dai = dai_link->dynamic ? | ||
78 | rtd->cpu_dai : | ||
79 | rtd->codec_dai; | ||
80 | |||
81 | return asoc_simple_card_init_dai(dai, dai_props); | ||
82 | } | ||
83 | |||
84 | static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, | ||
85 | struct snd_pcm_hw_params *params) | ||
86 | { | ||
87 | struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
88 | struct snd_interval *rate = hw_param_interval(params, | ||
89 | SNDRV_PCM_HW_PARAM_RATE); | ||
90 | struct snd_interval *channels = hw_param_interval(params, | ||
91 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
92 | |||
93 | if (priv->convert_rate) | ||
94 | rate->min = | ||
95 | rate->max = priv->convert_rate; | ||
96 | |||
97 | if (priv->convert_channels) | ||
98 | channels->min = | ||
99 | channels->max = priv->convert_channels; | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static int asoc_simple_card_parse_links(struct device_node *np, | ||
105 | struct asoc_simple_card_priv *priv, | ||
106 | unsigned int daifmt, | ||
107 | int idx, bool is_fe) | ||
108 | { | ||
109 | struct device *dev = simple_priv_to_dev(priv); | ||
110 | struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx); | ||
111 | struct asoc_simple_dai *dai_props = simple_priv_to_props(priv, idx); | ||
112 | int ret; | ||
113 | |||
114 | if (is_fe) { | ||
115 | int is_single_links = 0; | ||
116 | |||
117 | /* BE is dummy */ | ||
118 | dai_link->codec_of_node = NULL; | ||
119 | dai_link->codec_dai_name = "snd-soc-dummy-dai"; | ||
120 | dai_link->codec_name = "snd-soc-dummy"; | ||
121 | |||
122 | /* FE settings */ | ||
123 | dai_link->dynamic = 1; | ||
124 | dai_link->dpcm_merged_format = 1; | ||
125 | |||
126 | ret = asoc_simple_card_parse_cpu(np, dai_link, DAI, CELL, | ||
127 | &is_single_links); | ||
128 | if (ret) | ||
129 | return ret; | ||
130 | |||
131 | ret = asoc_simple_card_parse_clk_cpu(np, dai_link, dai_props); | ||
132 | if (ret < 0) | ||
133 | return ret; | ||
134 | |||
135 | ret = asoc_simple_card_set_dailink_name(dev, dai_link, | ||
136 | "fe.%s", | ||
137 | dai_link->cpu_dai_name); | ||
138 | if (ret < 0) | ||
139 | return ret; | ||
140 | |||
141 | asoc_simple_card_canonicalize_cpu(dai_link, is_single_links); | ||
142 | } else { | ||
143 | /* FE is dummy */ | ||
144 | dai_link->cpu_of_node = NULL; | ||
145 | dai_link->cpu_dai_name = "snd-soc-dummy-dai"; | ||
146 | dai_link->cpu_name = "snd-soc-dummy"; | ||
147 | |||
148 | /* BE settings */ | ||
149 | dai_link->no_pcm = 1; | ||
150 | dai_link->be_hw_params_fixup = asoc_simple_card_be_hw_params_fixup; | ||
151 | |||
152 | ret = asoc_simple_card_parse_codec(np, dai_link, DAI, CELL); | ||
153 | if (ret < 0) | ||
154 | return ret; | ||
155 | |||
156 | ret = asoc_simple_card_parse_clk_codec(np, dai_link, dai_props); | ||
157 | if (ret < 0) | ||
158 | return ret; | ||
159 | |||
160 | ret = asoc_simple_card_set_dailink_name(dev, dai_link, | ||
161 | "be.%s", | ||
162 | dai_link->codec_dai_name); | ||
163 | if (ret < 0) | ||
164 | return ret; | ||
165 | |||
166 | snd_soc_of_parse_audio_prefix(&priv->snd_card, | ||
167 | &priv->codec_conf, | ||
168 | dai_link->codec_of_node, | ||
169 | PREFIX "prefix"); | ||
170 | } | ||
171 | |||
172 | ret = snd_soc_of_parse_tdm_slot(np, | ||
173 | &dai_props->tx_slot_mask, | ||
174 | &dai_props->rx_slot_mask, | ||
175 | &dai_props->slots, | ||
176 | &dai_props->slot_width); | ||
177 | if (ret) | ||
178 | return ret; | ||
179 | |||
180 | ret = asoc_simple_card_canonicalize_dailink(dai_link); | ||
181 | if (ret < 0) | ||
182 | return ret; | ||
183 | |||
184 | dai_link->dai_fmt = daifmt; | ||
185 | dai_link->dpcm_playback = 1; | ||
186 | dai_link->dpcm_capture = 1; | ||
187 | dai_link->ops = &asoc_simple_card_ops; | ||
188 | dai_link->init = asoc_simple_card_dai_init; | ||
189 | |||
190 | dev_dbg(dev, "\t%s / %04x / %d\n", | ||
191 | dai_link->name, | ||
192 | dai_link->dai_fmt, | ||
193 | dai_props->sysclk); | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static int asoc_simple_card_dai_link_of(struct device_node *node, | ||
199 | struct asoc_simple_card_priv *priv) | ||
200 | { | ||
201 | struct device *dev = simple_priv_to_dev(priv); | ||
202 | struct device_node *np; | ||
203 | unsigned int daifmt = 0; | ||
204 | int ret, i; | ||
205 | bool is_fe; | ||
206 | |||
207 | /* find 1st codec */ | ||
208 | np = of_get_child_by_name(node, PREFIX "codec"); | ||
209 | if (!np) | ||
210 | return -ENODEV; | ||
211 | |||
212 | ret = asoc_simple_card_parse_daifmt(dev, node, np, | ||
213 | PREFIX, &daifmt); | ||
214 | if (ret < 0) | ||
215 | return ret; | ||
216 | |||
217 | i = 0; | ||
218 | for_each_child_of_node(node, np) { | ||
219 | is_fe = false; | ||
220 | if (strcmp(np->name, PREFIX "cpu") == 0) | ||
221 | is_fe = true; | ||
222 | |||
223 | ret = asoc_simple_card_parse_links(np, priv, daifmt, i, is_fe); | ||
224 | if (ret < 0) | ||
225 | return ret; | ||
226 | i++; | ||
227 | } | ||
228 | |||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | static int asoc_simple_card_parse_of(struct device_node *node, | ||
233 | struct asoc_simple_card_priv *priv, | ||
234 | struct device *dev) | ||
235 | { | ||
236 | struct asoc_simple_dai *props; | ||
237 | struct snd_soc_dai_link *links; | ||
238 | int ret; | ||
239 | int num; | ||
240 | |||
241 | if (!node) | ||
242 | return -EINVAL; | ||
243 | |||
244 | num = of_get_child_count(node); | ||
245 | props = devm_kzalloc(dev, sizeof(*props) * num, GFP_KERNEL); | ||
246 | links = devm_kzalloc(dev, sizeof(*links) * num, GFP_KERNEL); | ||
247 | if (!props || !links) | ||
248 | return -ENOMEM; | ||
249 | |||
250 | priv->dai_props = props; | ||
251 | priv->dai_link = links; | ||
252 | |||
253 | /* Init snd_soc_card */ | ||
254 | priv->snd_card.owner = THIS_MODULE; | ||
255 | priv->snd_card.dev = dev; | ||
256 | priv->snd_card.dai_link = priv->dai_link; | ||
257 | priv->snd_card.num_links = num; | ||
258 | priv->snd_card.codec_conf = &priv->codec_conf; | ||
259 | priv->snd_card.num_configs = 1; | ||
260 | |||
261 | ret = snd_soc_of_parse_audio_routing(&priv->snd_card, PREFIX "routing"); | ||
262 | if (ret < 0) | ||
263 | return ret; | ||
264 | |||
265 | /* sampling rate convert */ | ||
266 | of_property_read_u32(node, PREFIX "convert-rate", &priv->convert_rate); | ||
267 | |||
268 | /* channels transfer */ | ||
269 | of_property_read_u32(node, PREFIX "convert-channels", &priv->convert_channels); | ||
270 | |||
271 | ret = asoc_simple_card_dai_link_of(node, priv); | ||
272 | if (ret < 0) | ||
273 | return ret; | ||
274 | |||
275 | ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX); | ||
276 | if (ret < 0) | ||
277 | return ret; | ||
278 | |||
279 | dev_dbg(dev, "New card: %s\n", | ||
280 | priv->snd_card.name ? priv->snd_card.name : ""); | ||
281 | dev_dbg(dev, "convert_rate %d\n", priv->convert_rate); | ||
282 | dev_dbg(dev, "convert_channels %d\n", priv->convert_channels); | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static int asoc_simple_card_probe(struct platform_device *pdev) | ||
288 | { | ||
289 | struct asoc_simple_card_priv *priv; | ||
290 | struct device_node *np = pdev->dev.of_node; | ||
291 | struct device *dev = &pdev->dev; | ||
292 | int ret; | ||
293 | |||
294 | /* Allocate the private data */ | ||
295 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
296 | if (!priv) | ||
297 | return -ENOMEM; | ||
298 | |||
299 | ret = asoc_simple_card_parse_of(np, priv, dev); | ||
300 | if (ret < 0) { | ||
301 | if (ret != -EPROBE_DEFER) | ||
302 | dev_err(dev, "parse error %d\n", ret); | ||
303 | goto err; | ||
304 | } | ||
305 | |||
306 | snd_soc_card_set_drvdata(&priv->snd_card, priv); | ||
307 | |||
308 | ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); | ||
309 | if (ret >= 0) | ||
310 | return ret; | ||
311 | err: | ||
312 | asoc_simple_card_clean_reference(&priv->snd_card); | ||
313 | |||
314 | return ret; | ||
315 | } | ||
316 | |||
317 | static int asoc_simple_card_remove(struct platform_device *pdev) | ||
318 | { | ||
319 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
320 | |||
321 | return asoc_simple_card_clean_reference(card); | ||
322 | } | ||
323 | |||
324 | static const struct of_device_id asoc_simple_of_match[] = { | ||
325 | { .compatible = "renesas,rsrc-card", }, | ||
326 | { .compatible = "simple-scu-audio-card", }, | ||
327 | {}, | ||
328 | }; | ||
329 | MODULE_DEVICE_TABLE(of, asoc_simple_of_match); | ||
330 | |||
331 | static struct platform_driver asoc_simple_card = { | ||
332 | .driver = { | ||
333 | .name = "simple-scu-audio-card", | ||
334 | .of_match_table = asoc_simple_of_match, | ||
335 | }, | ||
336 | .probe = asoc_simple_card_probe, | ||
337 | .remove = asoc_simple_card_remove, | ||
338 | }; | ||
339 | |||
340 | module_platform_driver(asoc_simple_card); | ||
341 | |||
342 | MODULE_ALIAS("platform:asoc-simple-scu-card"); | ||
343 | MODULE_LICENSE("GPL v2"); | ||
344 | MODULE_DESCRIPTION("ASoC Simple SCU Sound Card"); | ||
345 | MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); | ||
diff --git a/sound/soc/img/pistachio-internal-dac.c b/sound/soc/img/pistachio-internal-dac.c index 162a0fd68c7b..53e11c6d4e22 100644 --- a/sound/soc/img/pistachio-internal-dac.c +++ b/sound/soc/img/pistachio-internal-dac.c | |||
@@ -134,12 +134,14 @@ static int pistachio_internal_dac_codec_probe(struct snd_soc_codec *codec) | |||
134 | static const struct snd_soc_codec_driver pistachio_internal_dac_driver = { | 134 | static const struct snd_soc_codec_driver pistachio_internal_dac_driver = { |
135 | .probe = pistachio_internal_dac_codec_probe, | 135 | .probe = pistachio_internal_dac_codec_probe, |
136 | .idle_bias_off = true, | 136 | .idle_bias_off = true, |
137 | .controls = pistachio_internal_dac_snd_controls, | 137 | .component_driver = { |
138 | .num_controls = ARRAY_SIZE(pistachio_internal_dac_snd_controls), | 138 | .controls = pistachio_internal_dac_snd_controls, |
139 | .dapm_widgets = pistachio_internal_dac_widgets, | 139 | .num_controls = ARRAY_SIZE(pistachio_internal_dac_snd_controls), |
140 | .num_dapm_widgets = ARRAY_SIZE(pistachio_internal_dac_widgets), | 140 | .dapm_widgets = pistachio_internal_dac_widgets, |
141 | .dapm_routes = pistachio_internal_dac_routes, | 141 | .num_dapm_widgets = ARRAY_SIZE(pistachio_internal_dac_widgets), |
142 | .num_dapm_routes = ARRAY_SIZE(pistachio_internal_dac_routes), | 142 | .dapm_routes = pistachio_internal_dac_routes, |
143 | .num_dapm_routes = ARRAY_SIZE(pistachio_internal_dac_routes), | ||
144 | }, | ||
143 | }; | 145 | }; |
144 | 146 | ||
145 | static int pistachio_internal_dac_probe(struct platform_device *pdev) | 147 | static int pistachio_internal_dac_probe(struct platform_device *pdev) |
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index a20c3dfbcb5d..26eb5a0a5575 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig | |||
@@ -25,6 +25,7 @@ config SND_SST_IPC_ACPI | |||
25 | tristate | 25 | tristate |
26 | select SND_SST_IPC | 26 | select SND_SST_IPC |
27 | select SND_SOC_INTEL_SST | 27 | select SND_SOC_INTEL_SST |
28 | select IOSF_MBI | ||
28 | 29 | ||
29 | config SND_SOC_INTEL_SST | 30 | config SND_SOC_INTEL_SST |
30 | tristate | 31 | tristate |
@@ -120,6 +121,17 @@ config SND_SOC_INTEL_BYT_MAX98090_MACH | |||
120 | This adds audio driver for Intel Baytrail platform based boards | 121 | This adds audio driver for Intel Baytrail platform based boards |
121 | with the MAX98090 audio codec. | 122 | with the MAX98090 audio codec. |
122 | 123 | ||
124 | config SND_SOC_INTEL_BDW_RT5677_MACH | ||
125 | tristate "ASoC Audio driver for Intel Broadwell with RT5677 codec" | ||
126 | depends on X86_INTEL_LPSS && GPIOLIB && I2C && DW_DMAC | ||
127 | depends on DW_DMAC_CORE=y | ||
128 | select SND_SOC_INTEL_SST | ||
129 | select SND_SOC_INTEL_HASWELL | ||
130 | select SND_SOC_RT5677 | ||
131 | help | ||
132 | This adds support for Intel Broadwell platform based boards with | ||
133 | the RT5677 audio codec. | ||
134 | |||
123 | config SND_SOC_INTEL_BROADWELL_MACH | 135 | config SND_SOC_INTEL_BROADWELL_MACH |
124 | tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" | 136 | tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" |
125 | depends on X86_INTEL_LPSS && I2C && DW_DMAC && \ | 137 | depends on X86_INTEL_LPSS && I2C && DW_DMAC && \ |
diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c index 98720a93de8a..0838478c4c3f 100644 --- a/sound/soc/intel/atom/sst-atom-controls.c +++ b/sound/soc/intel/atom/sst-atom-controls.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * sst-atom-controls.c - Intel MID Platform driver DPCM ALSA controls for Mrfld | 2 | * sst-atom-controls.c - Intel MID Platform driver DPCM ALSA controls for Mrfld |
3 | * | 3 | * |
4 | * Copyright (C) 2013-14 Intel Corp | 4 | * Copyright (C) 2013-14 Intel Corp |
@@ -534,6 +534,7 @@ static const DECLARE_TLV_DB_SCALE(sst_gain_tlv_common, SST_GAIN_MIN_VALUE * 10, | |||
534 | 534 | ||
535 | /* Look up table to convert MIXER SW bit regs to SWM inputs */ | 535 | /* Look up table to convert MIXER SW bit regs to SWM inputs */ |
536 | static const uint swm_mixer_input_ids[SST_SWM_INPUT_COUNT] = { | 536 | static const uint swm_mixer_input_ids[SST_SWM_INPUT_COUNT] = { |
537 | [SST_IP_MODEM] = SST_SWM_IN_MODEM, | ||
537 | [SST_IP_CODEC0] = SST_SWM_IN_CODEC0, | 538 | [SST_IP_CODEC0] = SST_SWM_IN_CODEC0, |
538 | [SST_IP_CODEC1] = SST_SWM_IN_CODEC1, | 539 | [SST_IP_CODEC1] = SST_SWM_IN_CODEC1, |
539 | [SST_IP_LOOP0] = SST_SWM_IN_SPROT_LOOP, | 540 | [SST_IP_LOOP0] = SST_SWM_IN_SPROT_LOOP, |
@@ -674,6 +675,7 @@ static int sst_swm_mixer_event(struct snd_soc_dapm_widget *w, | |||
674 | /* SBA mixers - 16 inputs */ | 675 | /* SBA mixers - 16 inputs */ |
675 | #define SST_SBA_DECLARE_MIX_CONTROLS(kctl_name) \ | 676 | #define SST_SBA_DECLARE_MIX_CONTROLS(kctl_name) \ |
676 | static const struct snd_kcontrol_new kctl_name[] = { \ | 677 | static const struct snd_kcontrol_new kctl_name[] = { \ |
678 | SOC_DAPM_SINGLE("modem_in Switch", SND_SOC_NOPM, SST_IP_MODEM, 1, 0), \ | ||
677 | SOC_DAPM_SINGLE("codec_in0 Switch", SND_SOC_NOPM, SST_IP_CODEC0, 1, 0), \ | 679 | SOC_DAPM_SINGLE("codec_in0 Switch", SND_SOC_NOPM, SST_IP_CODEC0, 1, 0), \ |
678 | SOC_DAPM_SINGLE("codec_in1 Switch", SND_SOC_NOPM, SST_IP_CODEC1, 1, 0), \ | 680 | SOC_DAPM_SINGLE("codec_in1 Switch", SND_SOC_NOPM, SST_IP_CODEC1, 1, 0), \ |
679 | SOC_DAPM_SINGLE("sprot_loop_in Switch", SND_SOC_NOPM, SST_IP_LOOP0, 1, 0), \ | 681 | SOC_DAPM_SINGLE("sprot_loop_in Switch", SND_SOC_NOPM, SST_IP_LOOP0, 1, 0), \ |
@@ -684,6 +686,7 @@ static int sst_swm_mixer_event(struct snd_soc_dapm_widget *w, | |||
684 | } | 686 | } |
685 | 687 | ||
686 | #define SST_SBA_MIXER_GRAPH_MAP(mix_name) \ | 688 | #define SST_SBA_MIXER_GRAPH_MAP(mix_name) \ |
689 | { mix_name, "modem_in Switch", "modem_in" }, \ | ||
687 | { mix_name, "codec_in0 Switch", "codec_in0" }, \ | 690 | { mix_name, "codec_in0 Switch", "codec_in0" }, \ |
688 | { mix_name, "codec_in1 Switch", "codec_in1" }, \ | 691 | { mix_name, "codec_in1 Switch", "codec_in1" }, \ |
689 | { mix_name, "sprot_loop_in Switch", "sprot_loop_in" }, \ | 692 | { mix_name, "sprot_loop_in Switch", "sprot_loop_in" }, \ |
@@ -713,6 +716,7 @@ SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_media_l2_controls); | |||
713 | SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_voip_controls); | 716 | SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_voip_controls); |
714 | SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec0_controls); | 717 | SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec0_controls); |
715 | SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec1_controls); | 718 | SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec1_controls); |
719 | SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_modem_controls); | ||
716 | 720 | ||
717 | /* | 721 | /* |
718 | * sst_handle_vb_timer - Start/Stop the DSP scheduler | 722 | * sst_handle_vb_timer - Start/Stop the DSP scheduler |
@@ -931,17 +935,26 @@ void sst_fill_ssp_defaults(struct snd_soc_dai *dai) | |||
931 | int send_ssp_cmd(struct snd_soc_dai *dai, const char *id, bool enable) | 935 | int send_ssp_cmd(struct snd_soc_dai *dai, const char *id, bool enable) |
932 | { | 936 | { |
933 | struct sst_data *drv = snd_soc_dai_get_drvdata(dai); | 937 | struct sst_data *drv = snd_soc_dai_get_drvdata(dai); |
934 | const struct sst_ssp_config *config; | 938 | int ssp_id; |
935 | 939 | ||
936 | dev_info(dai->dev, "Enter: enable=%d port_name=%s\n", enable, id); | 940 | dev_info(dai->dev, "Enter: enable=%d port_name=%s\n", enable, id); |
937 | 941 | ||
942 | if (strcmp(id, "ssp0-port") == 0) | ||
943 | ssp_id = SSP_MODEM; | ||
944 | else if (strcmp(id, "ssp2-port") == 0) | ||
945 | ssp_id = SSP_CODEC; | ||
946 | else { | ||
947 | dev_dbg(dai->dev, "port %s is not supported\n", id); | ||
948 | return -1; | ||
949 | } | ||
950 | |||
938 | SST_FILL_DEFAULT_DESTINATION(drv->ssp_cmd.header.dst); | 951 | SST_FILL_DEFAULT_DESTINATION(drv->ssp_cmd.header.dst); |
939 | drv->ssp_cmd.header.command_id = SBA_HW_SET_SSP; | 952 | drv->ssp_cmd.header.command_id = SBA_HW_SET_SSP; |
940 | drv->ssp_cmd.header.length = sizeof(struct sst_cmd_sba_hw_set_ssp) | 953 | drv->ssp_cmd.header.length = sizeof(struct sst_cmd_sba_hw_set_ssp) |
941 | - sizeof(struct sst_dsp_header); | 954 | - sizeof(struct sst_dsp_header); |
942 | 955 | ||
943 | config = &sst_ssp_configs; | 956 | drv->ssp_cmd.selection = ssp_id; |
944 | dev_dbg(dai->dev, "ssp_id: %u\n", config->ssp_id); | 957 | dev_dbg(dai->dev, "ssp_id: %u\n", ssp_id); |
945 | 958 | ||
946 | if (enable) | 959 | if (enable) |
947 | drv->ssp_cmd.switch_state = SST_SWITCH_ON; | 960 | drv->ssp_cmd.switch_state = SST_SWITCH_ON; |
@@ -1047,8 +1060,10 @@ static int sst_set_media_loop(struct snd_soc_dapm_widget *w, | |||
1047 | } | 1060 | } |
1048 | 1061 | ||
1049 | static const struct snd_soc_dapm_widget sst_dapm_widgets[] = { | 1062 | static const struct snd_soc_dapm_widget sst_dapm_widgets[] = { |
1063 | SST_AIF_IN("modem_in", sst_set_be_modules), | ||
1050 | SST_AIF_IN("codec_in0", sst_set_be_modules), | 1064 | SST_AIF_IN("codec_in0", sst_set_be_modules), |
1051 | SST_AIF_IN("codec_in1", sst_set_be_modules), | 1065 | SST_AIF_IN("codec_in1", sst_set_be_modules), |
1066 | SST_AIF_OUT("modem_out", sst_set_be_modules), | ||
1052 | SST_AIF_OUT("codec_out0", sst_set_be_modules), | 1067 | SST_AIF_OUT("codec_out0", sst_set_be_modules), |
1053 | SST_AIF_OUT("codec_out1", sst_set_be_modules), | 1068 | SST_AIF_OUT("codec_out1", sst_set_be_modules), |
1054 | 1069 | ||
@@ -1103,6 +1118,9 @@ static const struct snd_soc_dapm_widget sst_dapm_widgets[] = { | |||
1103 | sst_mix_codec0_controls, sst_swm_mixer_event), | 1118 | sst_mix_codec0_controls, sst_swm_mixer_event), |
1104 | SST_SWM_MIXER("codec_out1 mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_CODEC1, | 1119 | SST_SWM_MIXER("codec_out1 mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_CODEC1, |
1105 | sst_mix_codec1_controls, sst_swm_mixer_event), | 1120 | sst_mix_codec1_controls, sst_swm_mixer_event), |
1121 | SST_SWM_MIXER("modem_out mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_MODEM, | ||
1122 | sst_mix_modem_controls, sst_swm_mixer_event), | ||
1123 | |||
1106 | }; | 1124 | }; |
1107 | 1125 | ||
1108 | static const struct snd_soc_dapm_route intercon[] = { | 1126 | static const struct snd_soc_dapm_route intercon[] = { |
@@ -1148,6 +1166,9 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
1148 | SST_SBA_MIXER_GRAPH_MAP("codec_out0 mix 0"), | 1166 | SST_SBA_MIXER_GRAPH_MAP("codec_out0 mix 0"), |
1149 | {"codec_out1", NULL, "codec_out1 mix 0"}, | 1167 | {"codec_out1", NULL, "codec_out1 mix 0"}, |
1150 | SST_SBA_MIXER_GRAPH_MAP("codec_out1 mix 0"), | 1168 | SST_SBA_MIXER_GRAPH_MAP("codec_out1 mix 0"), |
1169 | {"modem_out", NULL, "modem_out mix 0"}, | ||
1170 | SST_SBA_MIXER_GRAPH_MAP("modem_out mix 0"), | ||
1171 | |||
1151 | 1172 | ||
1152 | }; | 1173 | }; |
1153 | static const char * const slot_names[] = { | 1174 | static const char * const slot_names[] = { |
@@ -1217,6 +1238,9 @@ static const struct snd_kcontrol_new sst_gain_controls[] = { | |||
1217 | SST_GAIN("media_loop2_out", SST_PATH_INDEX_MEDIA_LOOP2_OUT, SST_TASK_SBA, 0, &sst_gains[13]), | 1238 | SST_GAIN("media_loop2_out", SST_PATH_INDEX_MEDIA_LOOP2_OUT, SST_TASK_SBA, 0, &sst_gains[13]), |
1218 | SST_GAIN("sprot_loop_out", SST_PATH_INDEX_SPROT_LOOP_OUT, SST_TASK_SBA, 0, &sst_gains[14]), | 1239 | SST_GAIN("sprot_loop_out", SST_PATH_INDEX_SPROT_LOOP_OUT, SST_TASK_SBA, 0, &sst_gains[14]), |
1219 | SST_VOLUME("media0_in", SST_PATH_INDEX_MEDIA0_IN, SST_TASK_MMX, 0, &sst_gains[15]), | 1240 | SST_VOLUME("media0_in", SST_PATH_INDEX_MEDIA0_IN, SST_TASK_MMX, 0, &sst_gains[15]), |
1241 | SST_GAIN("modem_in", SST_PATH_INDEX_MODEM_IN, SST_TASK_SBA, 0, &sst_gains[16]), | ||
1242 | SST_GAIN("modem_out", SST_PATH_INDEX_MODEM_OUT, SST_TASK_SBA, 0, &sst_gains[17]), | ||
1243 | |||
1220 | }; | 1244 | }; |
1221 | 1245 | ||
1222 | #define SST_GAIN_NUM_CONTROLS 3 | 1246 | #define SST_GAIN_NUM_CONTROLS 3 |
diff --git a/sound/soc/intel/atom/sst-atom-controls.h b/sound/soc/intel/atom/sst-atom-controls.h index e0113112f668..351d81469685 100644 --- a/sound/soc/intel/atom/sst-atom-controls.h +++ b/sound/soc/intel/atom/sst-atom-controls.h | |||
@@ -35,6 +35,8 @@ enum { | |||
35 | /* define a bit for each mixer input */ | 35 | /* define a bit for each mixer input */ |
36 | #define SST_MIX_IP(x) (x) | 36 | #define SST_MIX_IP(x) (x) |
37 | 37 | ||
38 | #define SST_IP_MODEM SST_MIX_IP(0) | ||
39 | #define SST_IP_BT SST_MIX_IP(1) | ||
38 | #define SST_IP_CODEC0 SST_MIX_IP(2) | 40 | #define SST_IP_CODEC0 SST_MIX_IP(2) |
39 | #define SST_IP_CODEC1 SST_MIX_IP(3) | 41 | #define SST_IP_CODEC1 SST_MIX_IP(3) |
40 | #define SST_IP_LOOP0 SST_MIX_IP(4) | 42 | #define SST_IP_LOOP0 SST_MIX_IP(4) |
@@ -63,6 +65,7 @@ enum { | |||
63 | * Audio DSP Path Ids. Specified by the audio DSP FW | 65 | * Audio DSP Path Ids. Specified by the audio DSP FW |
64 | */ | 66 | */ |
65 | enum sst_path_index { | 67 | enum sst_path_index { |
68 | SST_PATH_INDEX_MODEM_OUT = (0x00 << SST_PATH_ID_SHIFT), | ||
66 | SST_PATH_INDEX_CODEC_OUT0 = (0x02 << SST_PATH_ID_SHIFT), | 69 | SST_PATH_INDEX_CODEC_OUT0 = (0x02 << SST_PATH_ID_SHIFT), |
67 | SST_PATH_INDEX_CODEC_OUT1 = (0x03 << SST_PATH_ID_SHIFT), | 70 | SST_PATH_INDEX_CODEC_OUT1 = (0x03 << SST_PATH_ID_SHIFT), |
68 | 71 | ||
@@ -80,6 +83,7 @@ enum sst_path_index { | |||
80 | 83 | ||
81 | 84 | ||
82 | /* Start of input paths */ | 85 | /* Start of input paths */ |
86 | SST_PATH_INDEX_MODEM_IN = (0x80 << SST_PATH_ID_SHIFT), | ||
83 | SST_PATH_INDEX_CODEC_IN0 = (0x82 << SST_PATH_ID_SHIFT), | 87 | SST_PATH_INDEX_CODEC_IN0 = (0x82 << SST_PATH_ID_SHIFT), |
84 | SST_PATH_INDEX_CODEC_IN1 = (0x83 << SST_PATH_ID_SHIFT), | 88 | SST_PATH_INDEX_CODEC_IN1 = (0x83 << SST_PATH_ID_SHIFT), |
85 | 89 | ||
@@ -105,6 +109,7 @@ enum sst_path_index { | |||
105 | * path IDs | 109 | * path IDs |
106 | */ | 110 | */ |
107 | enum sst_swm_inputs { | 111 | enum sst_swm_inputs { |
112 | SST_SWM_IN_MODEM = (SST_PATH_INDEX_MODEM_IN | SST_DEFAULT_CELL_NBR), | ||
108 | SST_SWM_IN_CODEC0 = (SST_PATH_INDEX_CODEC_IN0 | SST_DEFAULT_CELL_NBR), | 113 | SST_SWM_IN_CODEC0 = (SST_PATH_INDEX_CODEC_IN0 | SST_DEFAULT_CELL_NBR), |
109 | SST_SWM_IN_CODEC1 = (SST_PATH_INDEX_CODEC_IN1 | SST_DEFAULT_CELL_NBR), | 114 | SST_SWM_IN_CODEC1 = (SST_PATH_INDEX_CODEC_IN1 | SST_DEFAULT_CELL_NBR), |
110 | SST_SWM_IN_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_IN | SST_DEFAULT_CELL_NBR), | 115 | SST_SWM_IN_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_IN | SST_DEFAULT_CELL_NBR), |
@@ -124,6 +129,7 @@ enum sst_swm_inputs { | |||
124 | * path IDs | 129 | * path IDs |
125 | */ | 130 | */ |
126 | enum sst_swm_outputs { | 131 | enum sst_swm_outputs { |
132 | SST_SWM_OUT_MODEM = (SST_PATH_INDEX_MODEM_OUT | SST_DEFAULT_CELL_NBR), | ||
127 | SST_SWM_OUT_CODEC0 = (SST_PATH_INDEX_CODEC_OUT0 | SST_DEFAULT_CELL_NBR), | 133 | SST_SWM_OUT_CODEC0 = (SST_PATH_INDEX_CODEC_OUT0 | SST_DEFAULT_CELL_NBR), |
128 | SST_SWM_OUT_CODEC1 = (SST_PATH_INDEX_CODEC_OUT1 | SST_DEFAULT_CELL_NBR), | 134 | SST_SWM_OUT_CODEC1 = (SST_PATH_INDEX_CODEC_OUT1 | SST_DEFAULT_CELL_NBR), |
129 | SST_SWM_OUT_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_OUT | SST_DEFAULT_CELL_NBR), | 135 | SST_SWM_OUT_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_OUT | SST_DEFAULT_CELL_NBR), |
diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c index 52ed434cbca6..25c6d87c818e 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c | |||
@@ -670,7 +670,7 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer | |||
670 | return str_info->buffer_ptr; | 670 | return str_info->buffer_ptr; |
671 | } | 671 | } |
672 | 672 | ||
673 | static struct snd_pcm_ops sst_platform_ops = { | 673 | static const struct snd_pcm_ops sst_platform_ops = { |
674 | .open = sst_platform_open, | 674 | .open = sst_platform_open, |
675 | .ioctl = snd_pcm_lib_ioctl, | 675 | .ioctl = snd_pcm_lib_ioctl, |
676 | .trigger = sst_platform_pcm_trigger, | 676 | .trigger = sst_platform_pcm_trigger, |
diff --git a/sound/soc/intel/atom/sst/sst.c b/sound/soc/intel/atom/sst/sst.c index a4b458e77089..9b6e27385dc9 100644 --- a/sound/soc/intel/atom/sst/sst.c +++ b/sound/soc/intel/atom/sst/sst.c | |||
@@ -190,7 +190,8 @@ int sst_driver_ops(struct intel_sst_drv *sst) | |||
190 | 190 | ||
191 | default: | 191 | default: |
192 | dev_err(sst->dev, | 192 | dev_err(sst->dev, |
193 | "SST Driver capablities missing for dev_id: %x", sst->dev_id); | 193 | "SST Driver capabilities missing for dev_id: %x", |
194 | sst->dev_id); | ||
194 | return -EINVAL; | 195 | return -EINVAL; |
195 | }; | 196 | }; |
196 | } | 197 | } |
@@ -441,7 +442,7 @@ static int intel_sst_suspend(struct device *dev) | |||
441 | struct stream_info *stream = &ctx->streams[i]; | 442 | struct stream_info *stream = &ctx->streams[i]; |
442 | 443 | ||
443 | if (stream->status == STREAM_RUNNING) { | 444 | if (stream->status == STREAM_RUNNING) { |
444 | dev_err(dev, "stream %d is running, cant susupend, abort\n", i); | 445 | dev_err(dev, "stream %d is running, can't suspend, abort\n", i); |
445 | return -EBUSY; | 446 | return -EBUSY; |
446 | } | 447 | } |
447 | } | 448 | } |
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c index 4d3184971227..ba5c0d71720a 100644 --- a/sound/soc/intel/atom/sst/sst_acpi.c +++ b/sound/soc/intel/atom/sst/sst_acpi.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <acpi/platform/aclinux.h> | 39 | #include <acpi/platform/aclinux.h> |
40 | #include <acpi/actypes.h> | 40 | #include <acpi/actypes.h> |
41 | #include <acpi/acpi_bus.h> | 41 | #include <acpi/acpi_bus.h> |
42 | #include <asm/cpu_device_id.h> | ||
43 | #include <asm/iosf_mbi.h> | ||
42 | #include "../sst-mfld-platform.h" | 44 | #include "../sst-mfld-platform.h" |
43 | #include "../../common/sst-dsp.h" | 45 | #include "../../common/sst-dsp.h" |
44 | #include "../../common/sst-acpi.h" | 46 | #include "../../common/sst-acpi.h" |
@@ -113,6 +115,28 @@ static const struct sst_res_info byt_rvp_res_info = { | |||
113 | .acpi_ipc_irq_index = 5, | 115 | .acpi_ipc_irq_index = 5, |
114 | }; | 116 | }; |
115 | 117 | ||
118 | /* BYTCR has different BIOS from BYT */ | ||
119 | static const struct sst_res_info bytcr_res_info = { | ||
120 | .shim_offset = 0x140000, | ||
121 | .shim_size = 0x000100, | ||
122 | .shim_phy_addr = SST_BYT_SHIM_PHY_ADDR, | ||
123 | .ssp0_offset = 0xa0000, | ||
124 | .ssp0_size = 0x1000, | ||
125 | .dma0_offset = 0x98000, | ||
126 | .dma0_size = 0x4000, | ||
127 | .dma1_offset = 0x9c000, | ||
128 | .dma1_size = 0x4000, | ||
129 | .iram_offset = 0x0c0000, | ||
130 | .iram_size = 0x14000, | ||
131 | .dram_offset = 0x100000, | ||
132 | .dram_size = 0x28000, | ||
133 | .mbox_offset = 0x144000, | ||
134 | .mbox_size = 0x1000, | ||
135 | .acpi_lpe_res_index = 0, | ||
136 | .acpi_ddr_index = 2, | ||
137 | .acpi_ipc_irq_index = 0 | ||
138 | }; | ||
139 | |||
116 | static struct sst_platform_info byt_rvp_platform_data = { | 140 | static struct sst_platform_info byt_rvp_platform_data = { |
117 | .probe_data = &byt_fwparse_info, | 141 | .probe_data = &byt_fwparse_info, |
118 | .ipc_info = &byt_ipc_info, | 142 | .ipc_info = &byt_ipc_info, |
@@ -142,7 +166,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
142 | rsrc = platform_get_resource(pdev, IORESOURCE_MEM, | 166 | rsrc = platform_get_resource(pdev, IORESOURCE_MEM, |
143 | ctx->pdata->res_info->acpi_lpe_res_index); | 167 | ctx->pdata->res_info->acpi_lpe_res_index); |
144 | if (!rsrc) { | 168 | if (!rsrc) { |
145 | dev_err(ctx->dev, "Invalid SHIM base from IFWI"); | 169 | dev_err(ctx->dev, "Invalid SHIM base from IFWI\n"); |
146 | return -EIO; | 170 | return -EIO; |
147 | } | 171 | } |
148 | dev_info(ctx->dev, "LPE base: %#x size:%#x", (unsigned int) rsrc->start, | 172 | dev_info(ctx->dev, "LPE base: %#x size:%#x", (unsigned int) rsrc->start, |
@@ -154,7 +178,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
154 | ctx->iram = devm_ioremap_nocache(ctx->dev, ctx->iram_base, | 178 | ctx->iram = devm_ioremap_nocache(ctx->dev, ctx->iram_base, |
155 | ctx->pdata->res_info->iram_size); | 179 | ctx->pdata->res_info->iram_size); |
156 | if (!ctx->iram) { | 180 | if (!ctx->iram) { |
157 | dev_err(ctx->dev, "unable to map IRAM"); | 181 | dev_err(ctx->dev, "unable to map IRAM\n"); |
158 | return -EIO; | 182 | return -EIO; |
159 | } | 183 | } |
160 | 184 | ||
@@ -164,7 +188,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
164 | ctx->dram = devm_ioremap_nocache(ctx->dev, ctx->dram_base, | 188 | ctx->dram = devm_ioremap_nocache(ctx->dev, ctx->dram_base, |
165 | ctx->pdata->res_info->dram_size); | 189 | ctx->pdata->res_info->dram_size); |
166 | if (!ctx->dram) { | 190 | if (!ctx->dram) { |
167 | dev_err(ctx->dev, "unable to map DRAM"); | 191 | dev_err(ctx->dev, "unable to map DRAM\n"); |
168 | return -EIO; | 192 | return -EIO; |
169 | } | 193 | } |
170 | 194 | ||
@@ -173,7 +197,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
173 | ctx->shim = devm_ioremap_nocache(ctx->dev, ctx->shim_phy_add, | 197 | ctx->shim = devm_ioremap_nocache(ctx->dev, ctx->shim_phy_add, |
174 | ctx->pdata->res_info->shim_size); | 198 | ctx->pdata->res_info->shim_size); |
175 | if (!ctx->shim) { | 199 | if (!ctx->shim) { |
176 | dev_err(ctx->dev, "unable to map SHIM"); | 200 | dev_err(ctx->dev, "unable to map SHIM\n"); |
177 | return -EIO; | 201 | return -EIO; |
178 | } | 202 | } |
179 | 203 | ||
@@ -186,7 +210,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
186 | ctx->mailbox = devm_ioremap_nocache(ctx->dev, ctx->mailbox_add, | 210 | ctx->mailbox = devm_ioremap_nocache(ctx->dev, ctx->mailbox_add, |
187 | ctx->pdata->res_info->mbox_size); | 211 | ctx->pdata->res_info->mbox_size); |
188 | if (!ctx->mailbox) { | 212 | if (!ctx->mailbox) { |
189 | dev_err(ctx->dev, "unable to map mailbox"); | 213 | dev_err(ctx->dev, "unable to map mailbox\n"); |
190 | return -EIO; | 214 | return -EIO; |
191 | } | 215 | } |
192 | 216 | ||
@@ -196,7 +220,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
196 | rsrc = platform_get_resource(pdev, IORESOURCE_MEM, | 220 | rsrc = platform_get_resource(pdev, IORESOURCE_MEM, |
197 | ctx->pdata->res_info->acpi_ddr_index); | 221 | ctx->pdata->res_info->acpi_ddr_index); |
198 | if (!rsrc) { | 222 | if (!rsrc) { |
199 | dev_err(ctx->dev, "Invalid DDR base from IFWI"); | 223 | dev_err(ctx->dev, "Invalid DDR base from IFWI\n"); |
200 | return -EIO; | 224 | return -EIO; |
201 | } | 225 | } |
202 | ctx->ddr_base = rsrc->start; | 226 | ctx->ddr_base = rsrc->start; |
@@ -205,7 +229,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
205 | ctx->ddr = devm_ioremap_nocache(ctx->dev, ctx->ddr_base, | 229 | ctx->ddr = devm_ioremap_nocache(ctx->dev, ctx->ddr_base, |
206 | resource_size(rsrc)); | 230 | resource_size(rsrc)); |
207 | if (!ctx->ddr) { | 231 | if (!ctx->ddr) { |
208 | dev_err(ctx->dev, "unable to map DDR"); | 232 | dev_err(ctx->dev, "unable to map DDR\n"); |
209 | return -EIO; | 233 | return -EIO; |
210 | } | 234 | } |
211 | 235 | ||
@@ -215,6 +239,46 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
215 | return 0; | 239 | return 0; |
216 | } | 240 | } |
217 | 241 | ||
242 | |||
243 | static int is_byt_cr(struct device *dev, bool *bytcr) | ||
244 | { | ||
245 | int status = 0; | ||
246 | |||
247 | if (IS_ENABLED(CONFIG_IOSF_MBI)) { | ||
248 | static const struct x86_cpu_id cpu_ids[] = { | ||
249 | { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */ | ||
250 | {} | ||
251 | }; | ||
252 | u32 bios_status; | ||
253 | |||
254 | if (!x86_match_cpu(cpu_ids) || !iosf_mbi_available()) { | ||
255 | /* bail silently */ | ||
256 | return status; | ||
257 | } | ||
258 | |||
259 | status = iosf_mbi_read(BT_MBI_UNIT_PMC, /* 0x04 PUNIT */ | ||
260 | MBI_REG_READ, /* 0x10 */ | ||
261 | 0x006, /* BIOS_CONFIG */ | ||
262 | &bios_status); | ||
263 | |||
264 | if (status) { | ||
265 | dev_err(dev, "could not read PUNIT BIOS_CONFIG\n"); | ||
266 | } else { | ||
267 | /* bits 26:27 mirror PMIC options */ | ||
268 | bios_status = (bios_status >> 26) & 3; | ||
269 | |||
270 | if ((bios_status == 1) || (bios_status == 3)) | ||
271 | *bytcr = true; | ||
272 | else | ||
273 | dev_info(dev, "BYT-CR not detected\n"); | ||
274 | } | ||
275 | } else { | ||
276 | dev_info(dev, "IOSF_MBI not enabled, no BYT-CR detection\n"); | ||
277 | } | ||
278 | return status; | ||
279 | } | ||
280 | |||
281 | |||
218 | static int sst_acpi_probe(struct platform_device *pdev) | 282 | static int sst_acpi_probe(struct platform_device *pdev) |
219 | { | 283 | { |
220 | struct device *dev = &pdev->dev; | 284 | struct device *dev = &pdev->dev; |
@@ -226,11 +290,12 @@ static int sst_acpi_probe(struct platform_device *pdev) | |||
226 | struct platform_device *plat_dev; | 290 | struct platform_device *plat_dev; |
227 | struct sst_platform_info *pdata; | 291 | struct sst_platform_info *pdata; |
228 | unsigned int dev_id; | 292 | unsigned int dev_id; |
293 | bool bytcr = false; | ||
229 | 294 | ||
230 | id = acpi_match_device(dev->driver->acpi_match_table, dev); | 295 | id = acpi_match_device(dev->driver->acpi_match_table, dev); |
231 | if (!id) | 296 | if (!id) |
232 | return -ENODEV; | 297 | return -ENODEV; |
233 | dev_dbg(dev, "for %s", id->id); | 298 | dev_dbg(dev, "for %s\n", id->id); |
234 | 299 | ||
235 | mach = (struct sst_acpi_mach *)id->driver_data; | 300 | mach = (struct sst_acpi_mach *)id->driver_data; |
236 | mach = sst_acpi_find_machine(mach); | 301 | mach = sst_acpi_find_machine(mach); |
@@ -251,6 +316,18 @@ static int sst_acpi_probe(struct platform_device *pdev) | |||
251 | 316 | ||
252 | dev_dbg(dev, "ACPI device id: %x\n", dev_id); | 317 | dev_dbg(dev, "ACPI device id: %x\n", dev_id); |
253 | 318 | ||
319 | ret = sst_alloc_drv_context(&ctx, dev, dev_id); | ||
320 | if (ret < 0) | ||
321 | return ret; | ||
322 | |||
323 | ret = is_byt_cr(dev, &bytcr); | ||
324 | if (!((ret < 0) || (bytcr == false))) { | ||
325 | dev_info(dev, "Detected Baytrail-CR platform\n"); | ||
326 | |||
327 | /* override resource info */ | ||
328 | byt_rvp_platform_data.res_info = &bytcr_res_info; | ||
329 | } | ||
330 | |||
254 | plat_dev = platform_device_register_data(dev, pdata->platform, -1, | 331 | plat_dev = platform_device_register_data(dev, pdata->platform, -1, |
255 | NULL, 0); | 332 | NULL, 0); |
256 | if (IS_ERR(plat_dev)) { | 333 | if (IS_ERR(plat_dev)) { |
@@ -271,10 +348,6 @@ static int sst_acpi_probe(struct platform_device *pdev) | |||
271 | return PTR_ERR(mdev); | 348 | return PTR_ERR(mdev); |
272 | } | 349 | } |
273 | 350 | ||
274 | ret = sst_alloc_drv_context(&ctx, dev, dev_id); | ||
275 | if (ret < 0) | ||
276 | return ret; | ||
277 | |||
278 | /* Fill sst platform data */ | 351 | /* Fill sst platform data */ |
279 | ctx->pdata = pdata; | 352 | ctx->pdata = pdata; |
280 | strcpy(ctx->firmware_name, mach->fw_filename); | 353 | strcpy(ctx->firmware_name, mach->fw_filename); |
diff --git a/sound/soc/intel/atom/sst/sst_ipc.c b/sound/soc/intel/atom/sst/sst_ipc.c index 8afa6fe7b0b0..bfc889950bb2 100644 --- a/sound/soc/intel/atom/sst/sst_ipc.c +++ b/sound/soc/intel/atom/sst/sst_ipc.c | |||
@@ -267,6 +267,9 @@ static void process_fw_async_msg(struct intel_sst_drv *sst_drv_ctx, | |||
267 | "Period elapsed rcvd for pipe id 0x%x\n", | 267 | "Period elapsed rcvd for pipe id 0x%x\n", |
268 | pipe_id); | 268 | pipe_id); |
269 | stream = &sst_drv_ctx->streams[str_id]; | 269 | stream = &sst_drv_ctx->streams[str_id]; |
270 | /* If stream is dropped, skip processing this message*/ | ||
271 | if (stream->status == STREAM_INIT) | ||
272 | break; | ||
270 | if (stream->period_elapsed) | 273 | if (stream->period_elapsed) |
271 | stream->period_elapsed(stream->pcm_substream); | 274 | stream->period_elapsed(stream->pcm_substream); |
272 | if (stream->compr_cb) | 275 | if (stream->compr_cb) |
diff --git a/sound/soc/intel/atom/sst/sst_pvt.c b/sound/soc/intel/atom/sst/sst_pvt.c index adb32fefd693..b1e6b8f34a6a 100644 --- a/sound/soc/intel/atom/sst/sst_pvt.c +++ b/sound/soc/intel/atom/sst/sst_pvt.c | |||
@@ -279,17 +279,15 @@ int sst_prepare_and_post_msg(struct intel_sst_drv *sst, | |||
279 | 279 | ||
280 | if (response) { | 280 | if (response) { |
281 | ret = sst_wait_timeout(sst, block); | 281 | ret = sst_wait_timeout(sst, block); |
282 | if (ret < 0) { | 282 | if (ret < 0) |
283 | goto out; | 283 | goto out; |
284 | } else if(block->data) { | 284 | |
285 | if (!data) | 285 | if (data && block->data) { |
286 | goto out; | 286 | *data = kmemdup(block->data, block->size, GFP_KERNEL); |
287 | *data = kzalloc(block->size, GFP_KERNEL); | 287 | if (!*data) { |
288 | if (!(*data)) { | ||
289 | ret = -ENOMEM; | 288 | ret = -ENOMEM; |
290 | goto out; | 289 | goto out; |
291 | } else | 290 | } |
292 | memcpy(data, (void *) block->data, block->size); | ||
293 | } | 291 | } |
294 | } | 292 | } |
295 | out: | 293 | out: |
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index dac03a06bfd8..5639f10774e6 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile | |||
@@ -1,6 +1,7 @@ | |||
1 | snd-soc-sst-haswell-objs := haswell.o | 1 | snd-soc-sst-haswell-objs := haswell.o |
2 | snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o | 2 | snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o |
3 | snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o | 3 | snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o |
4 | snd-soc-sst-bdw-rt5677-mach-objs := bdw-rt5677.o | ||
4 | snd-soc-sst-broadwell-objs := broadwell.o | 5 | snd-soc-sst-broadwell-objs := broadwell.o |
5 | snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o | 6 | snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o |
6 | snd-soc-sst-bxt-rt298-objs := bxt_rt298.o | 7 | snd-soc-sst-bxt-rt298-objs := bxt_rt298.o |
@@ -19,6 +20,7 @@ obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o | |||
19 | obj-$(CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH) += snd-soc-sst-bxt-da7219_max98357a.o | 20 | obj-$(CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH) += snd-soc-sst-bxt-da7219_max98357a.o |
20 | obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o | 21 | obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o |
21 | obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o | 22 | obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o |
23 | obj-$(CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH) += snd-soc-sst-bdw-rt5677-mach.o | ||
22 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o | 24 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o |
23 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o | 25 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o |
24 | obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o | 26 | obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o |
diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c new file mode 100644 index 000000000000..547e6705bf6d --- /dev/null +++ b/sound/soc/intel/boards/bdw-rt5677.c | |||
@@ -0,0 +1,347 @@ | |||
1 | /* | ||
2 | * ASoC machine driver for Intel Broadwell platforms with RT5677 codec | ||
3 | * | ||
4 | * Copyright (c) 2014, The Chromium OS Authors. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/gpio/consumer.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <sound/core.h> | ||
24 | #include <sound/pcm.h> | ||
25 | #include <sound/soc.h> | ||
26 | #include <sound/pcm_params.h> | ||
27 | #include <sound/jack.h> | ||
28 | |||
29 | #include "../common/sst-dsp.h" | ||
30 | #include "../haswell/sst-haswell-ipc.h" | ||
31 | |||
32 | #include "../../codecs/rt5677.h" | ||
33 | |||
34 | struct bdw_rt5677_priv { | ||
35 | struct gpio_desc *gpio_hp_en; | ||
36 | struct snd_soc_codec *codec; | ||
37 | }; | ||
38 | |||
39 | static int bdw_rt5677_event_hp(struct snd_soc_dapm_widget *w, | ||
40 | struct snd_kcontrol *k, int event) | ||
41 | { | ||
42 | struct snd_soc_dapm_context *dapm = w->dapm; | ||
43 | struct snd_soc_card *card = dapm->card; | ||
44 | struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card); | ||
45 | |||
46 | if (SND_SOC_DAPM_EVENT_ON(event)) | ||
47 | msleep(70); | ||
48 | |||
49 | gpiod_set_value_cansleep(bdw_rt5677->gpio_hp_en, | ||
50 | SND_SOC_DAPM_EVENT_ON(event)); | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static const struct snd_soc_dapm_widget bdw_rt5677_widgets[] = { | ||
56 | SND_SOC_DAPM_HP("Headphone", bdw_rt5677_event_hp), | ||
57 | SND_SOC_DAPM_SPK("Speaker", NULL), | ||
58 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
59 | SND_SOC_DAPM_MIC("Local DMICs", NULL), | ||
60 | SND_SOC_DAPM_MIC("Remote DMICs", NULL), | ||
61 | }; | ||
62 | |||
63 | static const struct snd_soc_dapm_route bdw_rt5677_map[] = { | ||
64 | /* Speakers */ | ||
65 | {"Speaker", NULL, "PDM1L"}, | ||
66 | {"Speaker", NULL, "PDM1R"}, | ||
67 | |||
68 | /* Headset jack connectors */ | ||
69 | {"Headphone", NULL, "LOUT1"}, | ||
70 | {"Headphone", NULL, "LOUT2"}, | ||
71 | {"IN1P", NULL, "Headset Mic"}, | ||
72 | {"IN1N", NULL, "Headset Mic"}, | ||
73 | |||
74 | /* Digital MICs | ||
75 | * Local DMICs: the two DMICs on the mainboard | ||
76 | * Remote DMICs: the two DMICs on the camera module | ||
77 | */ | ||
78 | {"DMIC L1", NULL, "Remote DMICs"}, | ||
79 | {"DMIC R1", NULL, "Remote DMICs"}, | ||
80 | {"DMIC L2", NULL, "Local DMICs"}, | ||
81 | {"DMIC R2", NULL, "Local DMICs"}, | ||
82 | |||
83 | /* CODEC BE connections */ | ||
84 | {"SSP0 CODEC IN", NULL, "AIF1 Capture"}, | ||
85 | {"AIF1 Playback", NULL, "SSP0 CODEC OUT"}, | ||
86 | }; | ||
87 | |||
88 | static const struct snd_kcontrol_new bdw_rt5677_controls[] = { | ||
89 | SOC_DAPM_PIN_SWITCH("Speaker"), | ||
90 | SOC_DAPM_PIN_SWITCH("Headphone"), | ||
91 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | ||
92 | SOC_DAPM_PIN_SWITCH("Local DMICs"), | ||
93 | SOC_DAPM_PIN_SWITCH("Remote DMICs"), | ||
94 | }; | ||
95 | |||
96 | |||
97 | static struct snd_soc_jack headphone_jack; | ||
98 | static struct snd_soc_jack mic_jack; | ||
99 | |||
100 | static struct snd_soc_jack_pin headphone_jack_pin = { | ||
101 | .pin = "Headphone", | ||
102 | .mask = SND_JACK_HEADPHONE, | ||
103 | }; | ||
104 | |||
105 | static struct snd_soc_jack_pin mic_jack_pin = { | ||
106 | .pin = "Headset Mic", | ||
107 | .mask = SND_JACK_MICROPHONE, | ||
108 | }; | ||
109 | |||
110 | static struct snd_soc_jack_gpio headphone_jack_gpio = { | ||
111 | .name = "plug-det", | ||
112 | .report = SND_JACK_HEADPHONE, | ||
113 | .debounce_time = 200, | ||
114 | }; | ||
115 | |||
116 | static struct snd_soc_jack_gpio mic_jack_gpio = { | ||
117 | .name = "mic-present", | ||
118 | .report = SND_JACK_MICROPHONE, | ||
119 | .debounce_time = 200, | ||
120 | .invert = 1, | ||
121 | }; | ||
122 | |||
123 | static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, | ||
124 | struct snd_pcm_hw_params *params) | ||
125 | { | ||
126 | struct snd_interval *rate = hw_param_interval(params, | ||
127 | SNDRV_PCM_HW_PARAM_RATE); | ||
128 | struct snd_interval *channels = hw_param_interval(params, | ||
129 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
130 | |||
131 | /* The ADSP will covert the FE rate to 48k, stereo */ | ||
132 | rate->min = rate->max = 48000; | ||
133 | channels->min = channels->max = 2; | ||
134 | |||
135 | /* set SSP0 to 16 bit */ | ||
136 | snd_mask_set(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT - | ||
137 | SNDRV_PCM_HW_PARAM_FIRST_MASK], | ||
138 | SNDRV_PCM_FORMAT_S16_LE); | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static int bdw_rt5677_hw_params(struct snd_pcm_substream *substream, | ||
143 | struct snd_pcm_hw_params *params) | ||
144 | { | ||
145 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
146 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
147 | int ret; | ||
148 | |||
149 | ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_MCLK, 24576000, | ||
150 | SND_SOC_CLOCK_IN); | ||
151 | if (ret < 0) { | ||
152 | dev_err(rtd->dev, "can't set codec sysclk configuration\n"); | ||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | return ret; | ||
157 | } | ||
158 | |||
159 | static struct snd_soc_ops bdw_rt5677_ops = { | ||
160 | .hw_params = bdw_rt5677_hw_params, | ||
161 | }; | ||
162 | |||
163 | static int bdw_rt5677_rtd_init(struct snd_soc_pcm_runtime *rtd) | ||
164 | { | ||
165 | struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev); | ||
166 | struct sst_hsw *broadwell = pdata->dsp; | ||
167 | int ret; | ||
168 | |||
169 | /* Set ADSP SSP port settings */ | ||
170 | ret = sst_hsw_device_set_config(broadwell, SST_HSW_DEVICE_SSP_0, | ||
171 | SST_HSW_DEVICE_MCLK_FREQ_24_MHZ, | ||
172 | SST_HSW_DEVICE_CLOCK_MASTER, 9); | ||
173 | if (ret < 0) { | ||
174 | dev_err(rtd->dev, "error: failed to set device config\n"); | ||
175 | return ret; | ||
176 | } | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd) | ||
182 | { | ||
183 | struct bdw_rt5677_priv *bdw_rt5677 = | ||
184 | snd_soc_card_get_drvdata(rtd->card); | ||
185 | struct snd_soc_codec *codec = rtd->codec; | ||
186 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | ||
187 | |||
188 | /* Enable codec ASRC function for Stereo DAC/Stereo1 ADC/DMIC/I2S1. | ||
189 | * The ASRC clock source is clk_i2s1_asrc. | ||
190 | */ | ||
191 | rt5677_sel_asrc_clk_src(codec, RT5677_DA_STEREO_FILTER | | ||
192 | RT5677_AD_STEREO1_FILTER | RT5677_I2S1_SOURCE, | ||
193 | RT5677_CLK_SEL_I2S1_ASRC); | ||
194 | |||
195 | /* Request rt5677 GPIO for headphone amp control */ | ||
196 | bdw_rt5677->gpio_hp_en = devm_gpiod_get_index(codec->dev, | ||
197 | "headphone-enable", 0, 0); | ||
198 | if (IS_ERR(bdw_rt5677->gpio_hp_en)) { | ||
199 | dev_err(codec->dev, "Can't find HP_AMP_SHDN_L gpio\n"); | ||
200 | return PTR_ERR(bdw_rt5677->gpio_hp_en); | ||
201 | } | ||
202 | gpiod_direction_output(bdw_rt5677->gpio_hp_en, 0); | ||
203 | |||
204 | /* Create and initialize headphone jack */ | ||
205 | if (!snd_soc_card_jack_new(rtd->card, "Headphone Jack", | ||
206 | SND_JACK_HEADPHONE, &headphone_jack, | ||
207 | &headphone_jack_pin, 1)) { | ||
208 | headphone_jack_gpio.gpiod_dev = codec->dev; | ||
209 | if (snd_soc_jack_add_gpios(&headphone_jack, 1, | ||
210 | &headphone_jack_gpio)) | ||
211 | dev_err(codec->dev, "Can't add headphone jack gpio\n"); | ||
212 | } else { | ||
213 | dev_err(codec->dev, "Can't create headphone jack\n"); | ||
214 | } | ||
215 | |||
216 | /* Create and initialize mic jack */ | ||
217 | if (!snd_soc_card_jack_new(rtd->card, "Mic Jack", | ||
218 | SND_JACK_MICROPHONE, &mic_jack, | ||
219 | &mic_jack_pin, 1)) { | ||
220 | mic_jack_gpio.gpiod_dev = codec->dev; | ||
221 | if (snd_soc_jack_add_gpios(&mic_jack, 1, &mic_jack_gpio)) | ||
222 | dev_err(codec->dev, "Can't add mic jack gpio\n"); | ||
223 | } else { | ||
224 | dev_err(codec->dev, "Can't create mic jack\n"); | ||
225 | } | ||
226 | bdw_rt5677->codec = codec; | ||
227 | |||
228 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); | ||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | /* broadwell digital audio interface glue - connects codec <--> CPU */ | ||
233 | static struct snd_soc_dai_link bdw_rt5677_dais[] = { | ||
234 | /* Front End DAI links */ | ||
235 | { | ||
236 | .name = "System PCM", | ||
237 | .stream_name = "System Playback/Capture", | ||
238 | .cpu_dai_name = "System Pin", | ||
239 | .platform_name = "haswell-pcm-audio", | ||
240 | .dynamic = 1, | ||
241 | .codec_name = "snd-soc-dummy", | ||
242 | .codec_dai_name = "snd-soc-dummy-dai", | ||
243 | .init = bdw_rt5677_rtd_init, | ||
244 | .trigger = { | ||
245 | SND_SOC_DPCM_TRIGGER_POST, | ||
246 | SND_SOC_DPCM_TRIGGER_POST | ||
247 | }, | ||
248 | .dpcm_capture = 1, | ||
249 | .dpcm_playback = 1, | ||
250 | }, | ||
251 | |||
252 | /* Back End DAI links */ | ||
253 | { | ||
254 | /* SSP0 - Codec */ | ||
255 | .name = "Codec", | ||
256 | .id = 0, | ||
257 | .cpu_dai_name = "snd-soc-dummy-dai", | ||
258 | .platform_name = "snd-soc-dummy", | ||
259 | .no_pcm = 1, | ||
260 | .codec_name = "i2c-RT5677CE:00", | ||
261 | .codec_dai_name = "rt5677-aif1", | ||
262 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
263 | SND_SOC_DAIFMT_CBS_CFS, | ||
264 | .ignore_suspend = 1, | ||
265 | .ignore_pmdown_time = 1, | ||
266 | .be_hw_params_fixup = broadwell_ssp0_fixup, | ||
267 | .ops = &bdw_rt5677_ops, | ||
268 | .dpcm_playback = 1, | ||
269 | .dpcm_capture = 1, | ||
270 | .init = bdw_rt5677_init, | ||
271 | }, | ||
272 | }; | ||
273 | |||
274 | static int bdw_rt5677_suspend_pre(struct snd_soc_card *card) | ||
275 | { | ||
276 | struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card); | ||
277 | struct snd_soc_dapm_context *dapm; | ||
278 | |||
279 | if (bdw_rt5677->codec) { | ||
280 | dapm = snd_soc_codec_get_dapm(bdw_rt5677->codec); | ||
281 | snd_soc_dapm_disable_pin(dapm, "MICBIAS1"); | ||
282 | } | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static int bdw_rt5677_resume_post(struct snd_soc_card *card) | ||
287 | { | ||
288 | struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card); | ||
289 | struct snd_soc_dapm_context *dapm; | ||
290 | |||
291 | if (bdw_rt5677->codec) { | ||
292 | dapm = snd_soc_codec_get_dapm(bdw_rt5677->codec); | ||
293 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); | ||
294 | } | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | /* ASoC machine driver for Broadwell DSP + RT5677 */ | ||
299 | static struct snd_soc_card bdw_rt5677_card = { | ||
300 | .name = "bdw-rt5677", | ||
301 | .owner = THIS_MODULE, | ||
302 | .dai_link = bdw_rt5677_dais, | ||
303 | .num_links = ARRAY_SIZE(bdw_rt5677_dais), | ||
304 | .dapm_widgets = bdw_rt5677_widgets, | ||
305 | .num_dapm_widgets = ARRAY_SIZE(bdw_rt5677_widgets), | ||
306 | .dapm_routes = bdw_rt5677_map, | ||
307 | .num_dapm_routes = ARRAY_SIZE(bdw_rt5677_map), | ||
308 | .controls = bdw_rt5677_controls, | ||
309 | .num_controls = ARRAY_SIZE(bdw_rt5677_controls), | ||
310 | .fully_routed = true, | ||
311 | .suspend_pre = bdw_rt5677_suspend_pre, | ||
312 | .resume_post = bdw_rt5677_resume_post, | ||
313 | }; | ||
314 | |||
315 | static int bdw_rt5677_probe(struct platform_device *pdev) | ||
316 | { | ||
317 | struct bdw_rt5677_priv *bdw_rt5677; | ||
318 | |||
319 | bdw_rt5677_card.dev = &pdev->dev; | ||
320 | |||
321 | /* Allocate driver private struct */ | ||
322 | bdw_rt5677 = devm_kzalloc(&pdev->dev, sizeof(struct bdw_rt5677_priv), | ||
323 | GFP_KERNEL); | ||
324 | if (!bdw_rt5677) { | ||
325 | dev_err(&pdev->dev, "Can't allocate bdw_rt5677\n"); | ||
326 | return -ENOMEM; | ||
327 | } | ||
328 | |||
329 | snd_soc_card_set_drvdata(&bdw_rt5677_card, bdw_rt5677); | ||
330 | |||
331 | return devm_snd_soc_register_card(&pdev->dev, &bdw_rt5677_card); | ||
332 | } | ||
333 | |||
334 | static struct platform_driver bdw_rt5677_audio = { | ||
335 | .probe = bdw_rt5677_probe, | ||
336 | .driver = { | ||
337 | .name = "bdw-rt5677", | ||
338 | }, | ||
339 | }; | ||
340 | |||
341 | module_platform_driver(bdw_rt5677_audio) | ||
342 | |||
343 | /* Module information */ | ||
344 | MODULE_AUTHOR("Ben Zhang"); | ||
345 | MODULE_DESCRIPTION("Intel Broadwell RT5677 machine driver"); | ||
346 | MODULE_LICENSE("GPL v2"); | ||
347 | MODULE_ALIAS("platform:bdw-rt5677"); | ||
diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c index 3774b117d365..6532b8f0ab2f 100644 --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c | |||
@@ -37,6 +37,7 @@ enum { | |||
37 | BXT_DPCM_AUDIO_PB = 0, | 37 | BXT_DPCM_AUDIO_PB = 0, |
38 | BXT_DPCM_AUDIO_CP, | 38 | BXT_DPCM_AUDIO_CP, |
39 | BXT_DPCM_AUDIO_REF_CP, | 39 | BXT_DPCM_AUDIO_REF_CP, |
40 | BXT_DPCM_AUDIO_DMIC_CP, | ||
40 | BXT_DPCM_AUDIO_HDMI1_PB, | 41 | BXT_DPCM_AUDIO_HDMI1_PB, |
41 | BXT_DPCM_AUDIO_HDMI2_PB, | 42 | BXT_DPCM_AUDIO_HDMI2_PB, |
42 | BXT_DPCM_AUDIO_HDMI3_PB, | 43 | BXT_DPCM_AUDIO_HDMI3_PB, |
@@ -252,10 +253,56 @@ static struct snd_soc_ops broxton_da7219_ops = { | |||
252 | .hw_free = broxton_da7219_hw_free, | 253 | .hw_free = broxton_da7219_hw_free, |
253 | }; | 254 | }; |
254 | 255 | ||
256 | static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd, | ||
257 | struct snd_pcm_hw_params *params) | ||
258 | { | ||
259 | struct snd_interval *channels = hw_param_interval(params, | ||
260 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
261 | channels->min = channels->max = DUAL_CHANNEL; | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static int broxton_dmic_startup(struct snd_pcm_substream *substream) | ||
267 | { | ||
268 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
269 | |||
270 | runtime->hw.channels_max = DUAL_CHANNEL; | ||
271 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
272 | &constraints_channels); | ||
273 | |||
274 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | ||
275 | SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); | ||
276 | } | ||
277 | |||
278 | static const struct snd_soc_ops broxton_dmic_ops = { | ||
279 | .startup = broxton_dmic_startup, | ||
280 | }; | ||
281 | |||
282 | static const unsigned int rates_16000[] = { | ||
283 | 16000, | ||
284 | }; | ||
285 | |||
286 | static const struct snd_pcm_hw_constraint_list constraints_16000 = { | ||
287 | .count = ARRAY_SIZE(rates_16000), | ||
288 | .list = rates_16000, | ||
289 | }; | ||
290 | |||
291 | static int broxton_refcap_startup(struct snd_pcm_substream *substream) | ||
292 | { | ||
293 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | ||
294 | SNDRV_PCM_HW_PARAM_RATE, | ||
295 | &constraints_16000); | ||
296 | }; | ||
297 | |||
298 | static struct snd_soc_ops broxton_refcap_ops = { | ||
299 | .startup = broxton_refcap_startup, | ||
300 | }; | ||
301 | |||
255 | /* broxton digital audio interface glue - connects codec <--> CPU */ | 302 | /* broxton digital audio interface glue - connects codec <--> CPU */ |
256 | static struct snd_soc_dai_link broxton_dais[] = { | 303 | static struct snd_soc_dai_link broxton_dais[] = { |
257 | /* Front End DAI links */ | 304 | /* Front End DAI links */ |
258 | [BXT_DPCM_AUDIO_PB] | 305 | [BXT_DPCM_AUDIO_PB] = |
259 | { | 306 | { |
260 | .name = "Bxt Audio Port", | 307 | .name = "Bxt Audio Port", |
261 | .stream_name = "Audio", | 308 | .stream_name = "Audio", |
@@ -271,7 +318,7 @@ static struct snd_soc_dai_link broxton_dais[] = { | |||
271 | .dpcm_playback = 1, | 318 | .dpcm_playback = 1, |
272 | .ops = &broxton_da7219_fe_ops, | 319 | .ops = &broxton_da7219_fe_ops, |
273 | }, | 320 | }, |
274 | [BXT_DPCM_AUDIO_CP] | 321 | [BXT_DPCM_AUDIO_CP] = |
275 | { | 322 | { |
276 | .name = "Bxt Audio Capture Port", | 323 | .name = "Bxt Audio Capture Port", |
277 | .stream_name = "Audio Record", | 324 | .stream_name = "Audio Record", |
@@ -286,7 +333,7 @@ static struct snd_soc_dai_link broxton_dais[] = { | |||
286 | .dpcm_capture = 1, | 333 | .dpcm_capture = 1, |
287 | .ops = &broxton_da7219_fe_ops, | 334 | .ops = &broxton_da7219_fe_ops, |
288 | }, | 335 | }, |
289 | [BXT_DPCM_AUDIO_REF_CP] | 336 | [BXT_DPCM_AUDIO_REF_CP] = |
290 | { | 337 | { |
291 | .name = "Bxt Audio Reference cap", | 338 | .name = "Bxt Audio Reference cap", |
292 | .stream_name = "Refcap", | 339 | .stream_name = "Refcap", |
@@ -299,8 +346,23 @@ static struct snd_soc_dai_link broxton_dais[] = { | |||
299 | .ignore_suspend = 1, | 346 | .ignore_suspend = 1, |
300 | .nonatomic = 1, | 347 | .nonatomic = 1, |
301 | .dynamic = 1, | 348 | .dynamic = 1, |
349 | .ops = &broxton_refcap_ops, | ||
350 | }, | ||
351 | [BXT_DPCM_AUDIO_DMIC_CP] | ||
352 | { | ||
353 | .name = "Bxt Audio DMIC cap", | ||
354 | .stream_name = "dmiccap", | ||
355 | .cpu_dai_name = "DMIC Pin", | ||
356 | .codec_name = "snd-soc-dummy", | ||
357 | .codec_dai_name = "snd-soc-dummy-dai", | ||
358 | .platform_name = "0000:00:0e.0", | ||
359 | .init = NULL, | ||
360 | .dpcm_capture = 1, | ||
361 | .nonatomic = 1, | ||
362 | .dynamic = 1, | ||
363 | .ops = &broxton_dmic_ops, | ||
302 | }, | 364 | }, |
303 | [BXT_DPCM_AUDIO_HDMI1_PB] | 365 | [BXT_DPCM_AUDIO_HDMI1_PB] = |
304 | { | 366 | { |
305 | .name = "Bxt HDMI Port1", | 367 | .name = "Bxt HDMI Port1", |
306 | .stream_name = "Hdmi1", | 368 | .stream_name = "Hdmi1", |
@@ -313,7 +375,7 @@ static struct snd_soc_dai_link broxton_dais[] = { | |||
313 | .nonatomic = 1, | 375 | .nonatomic = 1, |
314 | .dynamic = 1, | 376 | .dynamic = 1, |
315 | }, | 377 | }, |
316 | [BXT_DPCM_AUDIO_HDMI2_PB] | 378 | [BXT_DPCM_AUDIO_HDMI2_PB] = |
317 | { | 379 | { |
318 | .name = "Bxt HDMI Port2", | 380 | .name = "Bxt HDMI Port2", |
319 | .stream_name = "Hdmi2", | 381 | .stream_name = "Hdmi2", |
@@ -326,7 +388,7 @@ static struct snd_soc_dai_link broxton_dais[] = { | |||
326 | .nonatomic = 1, | 388 | .nonatomic = 1, |
327 | .dynamic = 1, | 389 | .dynamic = 1, |
328 | }, | 390 | }, |
329 | [BXT_DPCM_AUDIO_HDMI3_PB] | 391 | [BXT_DPCM_AUDIO_HDMI3_PB] = |
330 | { | 392 | { |
331 | .name = "Bxt HDMI Port3", | 393 | .name = "Bxt HDMI Port3", |
332 | .stream_name = "Hdmi3", | 394 | .stream_name = "Hdmi3", |
@@ -382,6 +444,7 @@ static struct snd_soc_dai_link broxton_dais[] = { | |||
382 | .codec_dai_name = "dmic-hifi", | 444 | .codec_dai_name = "dmic-hifi", |
383 | .platform_name = "0000:00:0e.0", | 445 | .platform_name = "0000:00:0e.0", |
384 | .ignore_suspend = 1, | 446 | .ignore_suspend = 1, |
447 | .be_hw_params_fixup = broxton_dmic_fixup, | ||
385 | .dpcm_capture = 1, | 448 | .dpcm_capture = 1, |
386 | .no_pcm = 1, | 449 | .no_pcm = 1, |
387 | }, | 450 | }, |
diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c index 253d7bfbf511..d610bdca1608 100644 --- a/sound/soc/intel/boards/bxt_rt298.c +++ b/sound/soc/intel/boards/bxt_rt298.c | |||
@@ -271,7 +271,7 @@ static const struct snd_soc_ops broxton_rt286_fe_ops = { | |||
271 | /* broxton digital audio interface glue - connects codec <--> CPU */ | 271 | /* broxton digital audio interface glue - connects codec <--> CPU */ |
272 | static struct snd_soc_dai_link broxton_rt298_dais[] = { | 272 | static struct snd_soc_dai_link broxton_rt298_dais[] = { |
273 | /* Front End DAI links */ | 273 | /* Front End DAI links */ |
274 | [BXT_DPCM_AUDIO_PB] | 274 | [BXT_DPCM_AUDIO_PB] = |
275 | { | 275 | { |
276 | .name = "Bxt Audio Port", | 276 | .name = "Bxt Audio Port", |
277 | .stream_name = "Audio", | 277 | .stream_name = "Audio", |
@@ -286,7 +286,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { | |||
286 | .dpcm_playback = 1, | 286 | .dpcm_playback = 1, |
287 | .ops = &broxton_rt286_fe_ops, | 287 | .ops = &broxton_rt286_fe_ops, |
288 | }, | 288 | }, |
289 | [BXT_DPCM_AUDIO_CP] | 289 | [BXT_DPCM_AUDIO_CP] = |
290 | { | 290 | { |
291 | .name = "Bxt Audio Capture Port", | 291 | .name = "Bxt Audio Capture Port", |
292 | .stream_name = "Audio Record", | 292 | .stream_name = "Audio Record", |
@@ -300,7 +300,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { | |||
300 | .dpcm_capture = 1, | 300 | .dpcm_capture = 1, |
301 | .ops = &broxton_rt286_fe_ops, | 301 | .ops = &broxton_rt286_fe_ops, |
302 | }, | 302 | }, |
303 | [BXT_DPCM_AUDIO_REF_CP] | 303 | [BXT_DPCM_AUDIO_REF_CP] = |
304 | { | 304 | { |
305 | .name = "Bxt Audio Reference cap", | 305 | .name = "Bxt Audio Reference cap", |
306 | .stream_name = "refcap", | 306 | .stream_name = "refcap", |
@@ -313,7 +313,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { | |||
313 | .nonatomic = 1, | 313 | .nonatomic = 1, |
314 | .dynamic = 1, | 314 | .dynamic = 1, |
315 | }, | 315 | }, |
316 | [BXT_DPCM_AUDIO_DMIC_CP] | 316 | [BXT_DPCM_AUDIO_DMIC_CP] = |
317 | { | 317 | { |
318 | .name = "Bxt Audio DMIC cap", | 318 | .name = "Bxt Audio DMIC cap", |
319 | .stream_name = "dmiccap", | 319 | .stream_name = "dmiccap", |
@@ -327,7 +327,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { | |||
327 | .dynamic = 1, | 327 | .dynamic = 1, |
328 | .ops = &broxton_dmic_ops, | 328 | .ops = &broxton_dmic_ops, |
329 | }, | 329 | }, |
330 | [BXT_DPCM_AUDIO_HDMI1_PB] | 330 | [BXT_DPCM_AUDIO_HDMI1_PB] = |
331 | { | 331 | { |
332 | .name = "Bxt HDMI Port1", | 332 | .name = "Bxt HDMI Port1", |
333 | .stream_name = "Hdmi1", | 333 | .stream_name = "Hdmi1", |
@@ -340,7 +340,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { | |||
340 | .nonatomic = 1, | 340 | .nonatomic = 1, |
341 | .dynamic = 1, | 341 | .dynamic = 1, |
342 | }, | 342 | }, |
343 | [BXT_DPCM_AUDIO_HDMI2_PB] | 343 | [BXT_DPCM_AUDIO_HDMI2_PB] = |
344 | { | 344 | { |
345 | .name = "Bxt HDMI Port2", | 345 | .name = "Bxt HDMI Port2", |
346 | .stream_name = "Hdmi2", | 346 | .stream_name = "Hdmi2", |
@@ -353,7 +353,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { | |||
353 | .nonatomic = 1, | 353 | .nonatomic = 1, |
354 | .dynamic = 1, | 354 | .dynamic = 1, |
355 | }, | 355 | }, |
356 | [BXT_DPCM_AUDIO_HDMI3_PB] | 356 | [BXT_DPCM_AUDIO_HDMI3_PB] = |
357 | { | 357 | { |
358 | .name = "Bxt HDMI Port3", | 358 | .name = "Bxt HDMI Port3", |
359 | .stream_name = "Hdmi3", | 359 | .stream_name = "Hdmi3", |
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 88efb62439ba..bff77a1f27fc 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c | |||
@@ -24,6 +24,9 @@ | |||
24 | #include <linux/device.h> | 24 | #include <linux/device.h> |
25 | #include <linux/dmi.h> | 25 | #include <linux/dmi.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <asm/cpu_device_id.h> | ||
28 | #include <asm/platform_sst_audio.h> | ||
29 | #include <linux/clk.h> | ||
27 | #include <sound/pcm.h> | 30 | #include <sound/pcm.h> |
28 | #include <sound/pcm_params.h> | 31 | #include <sound/pcm_params.h> |
29 | #include <sound/soc.h> | 32 | #include <sound/soc.h> |
@@ -31,42 +34,153 @@ | |||
31 | #include "../../codecs/rt5640.h" | 34 | #include "../../codecs/rt5640.h" |
32 | #include "../atom/sst-atom-controls.h" | 35 | #include "../atom/sst-atom-controls.h" |
33 | #include "../common/sst-acpi.h" | 36 | #include "../common/sst-acpi.h" |
37 | #include "../common/sst-dsp.h" | ||
34 | 38 | ||
35 | enum { | 39 | enum { |
36 | BYT_RT5640_DMIC1_MAP, | 40 | BYT_RT5640_DMIC1_MAP, |
37 | BYT_RT5640_DMIC2_MAP, | 41 | BYT_RT5640_DMIC2_MAP, |
38 | BYT_RT5640_IN1_MAP, | 42 | BYT_RT5640_IN1_MAP, |
43 | BYT_RT5640_IN3_MAP, | ||
39 | }; | 44 | }; |
40 | 45 | ||
41 | #define BYT_RT5640_MAP(quirk) ((quirk) & 0xff) | 46 | #define BYT_RT5640_MAP(quirk) ((quirk) & 0xff) |
42 | #define BYT_RT5640_DMIC_EN BIT(16) | 47 | #define BYT_RT5640_DMIC_EN BIT(16) |
48 | #define BYT_RT5640_MONO_SPEAKER BIT(17) | ||
49 | #define BYT_RT5640_DIFF_MIC BIT(18) /* defaut is single-ended */ | ||
50 | #define BYT_RT5640_SSP2_AIF2 BIT(19) /* default is using AIF1 */ | ||
51 | #define BYT_RT5640_SSP0_AIF1 BIT(20) | ||
52 | #define BYT_RT5640_SSP0_AIF2 BIT(21) | ||
53 | #define BYT_RT5640_MCLK_EN BIT(22) | ||
54 | #define BYT_RT5640_MCLK_25MHZ BIT(23) | ||
55 | |||
56 | struct byt_rt5640_private { | ||
57 | struct clk *mclk; | ||
58 | }; | ||
43 | 59 | ||
44 | static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP | | 60 | static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP | |
45 | BYT_RT5640_DMIC_EN; | 61 | BYT_RT5640_DMIC_EN | |
62 | BYT_RT5640_MCLK_EN; | ||
63 | |||
64 | static void log_quirks(struct device *dev) | ||
65 | { | ||
66 | if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_DMIC1_MAP) | ||
67 | dev_info(dev, "quirk DMIC1_MAP enabled"); | ||
68 | if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_DMIC2_MAP) | ||
69 | dev_info(dev, "quirk DMIC2_MAP enabled"); | ||
70 | if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_IN1_MAP) | ||
71 | dev_info(dev, "quirk IN1_MAP enabled"); | ||
72 | if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_IN3_MAP) | ||
73 | dev_info(dev, "quirk IN3_MAP enabled"); | ||
74 | if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) | ||
75 | dev_info(dev, "quirk DMIC enabled"); | ||
76 | if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) | ||
77 | dev_info(dev, "quirk MONO_SPEAKER enabled"); | ||
78 | if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) | ||
79 | dev_info(dev, "quirk DIFF_MIC enabled"); | ||
80 | if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) | ||
81 | dev_info(dev, "quirk SSP2_AIF2 enabled"); | ||
82 | if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) | ||
83 | dev_info(dev, "quirk SSP0_AIF1 enabled"); | ||
84 | if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) | ||
85 | dev_info(dev, "quirk SSP0_AIF2 enabled"); | ||
86 | if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) | ||
87 | dev_info(dev, "quirk MCLK_EN enabled"); | ||
88 | if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) | ||
89 | dev_info(dev, "quirk MCLK_25MHZ enabled"); | ||
90 | } | ||
91 | |||
92 | |||
93 | #define BYT_CODEC_DAI1 "rt5640-aif1" | ||
94 | #define BYT_CODEC_DAI2 "rt5640-aif2" | ||
95 | |||
96 | static inline struct snd_soc_dai *byt_get_codec_dai(struct snd_soc_card *card) | ||
97 | { | ||
98 | struct snd_soc_pcm_runtime *rtd; | ||
99 | |||
100 | list_for_each_entry(rtd, &card->rtd_list, list) { | ||
101 | if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI1, | ||
102 | strlen(BYT_CODEC_DAI1))) | ||
103 | return rtd->codec_dai; | ||
104 | if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI2, | ||
105 | strlen(BYT_CODEC_DAI2))) | ||
106 | return rtd->codec_dai; | ||
107 | |||
108 | } | ||
109 | return NULL; | ||
110 | } | ||
111 | |||
112 | static int platform_clock_control(struct snd_soc_dapm_widget *w, | ||
113 | struct snd_kcontrol *k, int event) | ||
114 | { | ||
115 | struct snd_soc_dapm_context *dapm = w->dapm; | ||
116 | struct snd_soc_card *card = dapm->card; | ||
117 | struct snd_soc_dai *codec_dai; | ||
118 | struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); | ||
119 | int ret; | ||
120 | |||
121 | codec_dai = byt_get_codec_dai(card); | ||
122 | if (!codec_dai) { | ||
123 | dev_err(card->dev, | ||
124 | "Codec dai not found; Unable to set platform clock\n"); | ||
125 | return -EIO; | ||
126 | } | ||
127 | |||
128 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
129 | if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) { | ||
130 | ret = clk_prepare_enable(priv->mclk); | ||
131 | if (ret < 0) { | ||
132 | dev_err(card->dev, | ||
133 | "could not configure MCLK state"); | ||
134 | return ret; | ||
135 | } | ||
136 | } | ||
137 | ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1, | ||
138 | 48000 * 512, | ||
139 | SND_SOC_CLOCK_IN); | ||
140 | } else { | ||
141 | /* | ||
142 | * Set codec clock source to internal clock before | ||
143 | * turning off the platform clock. Codec needs clock | ||
144 | * for Jack detection and button press | ||
145 | */ | ||
146 | ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_RCCLK, | ||
147 | 0, | ||
148 | SND_SOC_CLOCK_IN); | ||
149 | if (!ret) { | ||
150 | if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) | ||
151 | clk_disable_unprepare(priv->mclk); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | if (ret < 0) { | ||
156 | dev_err(card->dev, "can't set codec sysclk: %d\n", ret); | ||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | return 0; | ||
161 | } | ||
46 | 162 | ||
47 | static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = { | 163 | static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = { |
48 | SND_SOC_DAPM_HP("Headphone", NULL), | 164 | SND_SOC_DAPM_HP("Headphone", NULL), |
49 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | 165 | SND_SOC_DAPM_MIC("Headset Mic", NULL), |
50 | SND_SOC_DAPM_MIC("Internal Mic", NULL), | 166 | SND_SOC_DAPM_MIC("Internal Mic", NULL), |
51 | SND_SOC_DAPM_SPK("Speaker", NULL), | 167 | SND_SOC_DAPM_SPK("Speaker", NULL), |
168 | SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, | ||
169 | platform_clock_control, SND_SOC_DAPM_PRE_PMU | | ||
170 | SND_SOC_DAPM_POST_PMD), | ||
171 | |||
52 | }; | 172 | }; |
53 | 173 | ||
54 | static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = { | 174 | static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = { |
55 | {"AIF1 Playback", NULL, "ssp2 Tx"}, | 175 | {"Headphone", NULL, "Platform Clock"}, |
56 | {"ssp2 Tx", NULL, "codec_out0"}, | 176 | {"Headset Mic", NULL, "Platform Clock"}, |
57 | {"ssp2 Tx", NULL, "codec_out1"}, | 177 | {"Internal Mic", NULL, "Platform Clock"}, |
58 | {"codec_in0", NULL, "ssp2 Rx"}, | 178 | {"Speaker", NULL, "Platform Clock"}, |
59 | {"codec_in1", NULL, "ssp2 Rx"}, | ||
60 | {"ssp2 Rx", NULL, "AIF1 Capture"}, | ||
61 | 179 | ||
62 | {"Headset Mic", NULL, "MICBIAS1"}, | 180 | {"Headset Mic", NULL, "MICBIAS1"}, |
63 | {"IN2P", NULL, "Headset Mic"}, | 181 | {"IN2P", NULL, "Headset Mic"}, |
64 | {"Headphone", NULL, "HPOL"}, | 182 | {"Headphone", NULL, "HPOL"}, |
65 | {"Headphone", NULL, "HPOR"}, | 183 | {"Headphone", NULL, "HPOR"}, |
66 | {"Speaker", NULL, "SPOLP"}, | ||
67 | {"Speaker", NULL, "SPOLN"}, | ||
68 | {"Speaker", NULL, "SPORP"}, | ||
69 | {"Speaker", NULL, "SPORN"}, | ||
70 | }; | 184 | }; |
71 | 185 | ||
72 | static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = { | 186 | static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = { |
@@ -82,6 +196,59 @@ static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = { | |||
82 | {"IN1P", NULL, "Internal Mic"}, | 196 | {"IN1P", NULL, "Internal Mic"}, |
83 | }; | 197 | }; |
84 | 198 | ||
199 | static const struct snd_soc_dapm_route byt_rt5640_intmic_in3_map[] = { | ||
200 | {"Internal Mic", NULL, "MICBIAS1"}, | ||
201 | {"IN3P", NULL, "Internal Mic"}, | ||
202 | }; | ||
203 | |||
204 | static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif1_map[] = { | ||
205 | {"ssp2 Tx", NULL, "codec_out0"}, | ||
206 | {"ssp2 Tx", NULL, "codec_out1"}, | ||
207 | {"codec_in0", NULL, "ssp2 Rx"}, | ||
208 | {"codec_in1", NULL, "ssp2 Rx"}, | ||
209 | |||
210 | {"AIF1 Playback", NULL, "ssp2 Tx"}, | ||
211 | {"ssp2 Rx", NULL, "AIF1 Capture"}, | ||
212 | }; | ||
213 | |||
214 | static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif2_map[] = { | ||
215 | {"ssp2 Tx", NULL, "codec_out0"}, | ||
216 | {"ssp2 Tx", NULL, "codec_out1"}, | ||
217 | {"codec_in0", NULL, "ssp2 Rx"}, | ||
218 | {"codec_in1", NULL, "ssp2 Rx"}, | ||
219 | |||
220 | {"AIF2 Playback", NULL, "ssp2 Tx"}, | ||
221 | {"ssp2 Rx", NULL, "AIF2 Capture"}, | ||
222 | }; | ||
223 | |||
224 | static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif1_map[] = { | ||
225 | {"ssp0 Tx", NULL, "modem_out"}, | ||
226 | {"modem_in", NULL, "ssp0 Rx"}, | ||
227 | |||
228 | {"AIF1 Playback", NULL, "ssp0 Tx"}, | ||
229 | {"ssp0 Rx", NULL, "AIF1 Capture"}, | ||
230 | }; | ||
231 | |||
232 | static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif2_map[] = { | ||
233 | {"ssp0 Tx", NULL, "modem_out"}, | ||
234 | {"modem_in", NULL, "ssp0 Rx"}, | ||
235 | |||
236 | {"AIF2 Playback", NULL, "ssp0 Tx"}, | ||
237 | {"ssp0 Rx", NULL, "AIF2 Capture"}, | ||
238 | }; | ||
239 | |||
240 | static const struct snd_soc_dapm_route byt_rt5640_stereo_spk_map[] = { | ||
241 | {"Speaker", NULL, "SPOLP"}, | ||
242 | {"Speaker", NULL, "SPOLN"}, | ||
243 | {"Speaker", NULL, "SPORP"}, | ||
244 | {"Speaker", NULL, "SPORN"}, | ||
245 | }; | ||
246 | |||
247 | static const struct snd_soc_dapm_route byt_rt5640_mono_spk_map[] = { | ||
248 | {"Speaker", NULL, "SPOLP"}, | ||
249 | {"Speaker", NULL, "SPOLN"}, | ||
250 | }; | ||
251 | |||
85 | static const struct snd_kcontrol_new byt_rt5640_controls[] = { | 252 | static const struct snd_kcontrol_new byt_rt5640_controls[] = { |
86 | SOC_DAPM_PIN_SWITCH("Headphone"), | 253 | SOC_DAPM_PIN_SWITCH("Headphone"), |
87 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | 254 | SOC_DAPM_PIN_SWITCH("Headset Mic"), |
@@ -96,19 +263,46 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream, | |||
96 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 263 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
97 | int ret; | 264 | int ret; |
98 | 265 | ||
99 | snd_soc_dai_set_bclk_ratio(codec_dai, 50); | ||
100 | |||
101 | ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1, | 266 | ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1, |
102 | params_rate(params) * 512, | 267 | params_rate(params) * 512, |
103 | SND_SOC_CLOCK_IN); | 268 | SND_SOC_CLOCK_IN); |
269 | |||
104 | if (ret < 0) { | 270 | if (ret < 0) { |
105 | dev_err(rtd->dev, "can't set codec clock %d\n", ret); | 271 | dev_err(rtd->dev, "can't set codec clock %d\n", ret); |
106 | return ret; | 272 | return ret; |
107 | } | 273 | } |
108 | 274 | ||
109 | ret = snd_soc_dai_set_pll(codec_dai, 0, RT5640_PLL1_S_BCLK1, | 275 | if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) { |
110 | params_rate(params) * 50, | 276 | /* use bitclock as PLL input */ |
111 | params_rate(params) * 512); | 277 | if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) || |
278 | (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) { | ||
279 | |||
280 | /* 2x16 bit slots on SSP0 */ | ||
281 | ret = snd_soc_dai_set_pll(codec_dai, 0, | ||
282 | RT5640_PLL1_S_BCLK1, | ||
283 | params_rate(params) * 32, | ||
284 | params_rate(params) * 512); | ||
285 | } else { | ||
286 | /* 2x15 bit slots on SSP2 */ | ||
287 | ret = snd_soc_dai_set_pll(codec_dai, 0, | ||
288 | RT5640_PLL1_S_BCLK1, | ||
289 | params_rate(params) * 50, | ||
290 | params_rate(params) * 512); | ||
291 | } | ||
292 | } else { | ||
293 | if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) { | ||
294 | ret = snd_soc_dai_set_pll(codec_dai, 0, | ||
295 | RT5640_PLL1_S_MCLK, | ||
296 | 25000000, | ||
297 | params_rate(params) * 512); | ||
298 | } else { | ||
299 | ret = snd_soc_dai_set_pll(codec_dai, 0, | ||
300 | RT5640_PLL1_S_MCLK, | ||
301 | 19200000, | ||
302 | params_rate(params) * 512); | ||
303 | } | ||
304 | } | ||
305 | |||
112 | if (ret < 0) { | 306 | if (ret < 0) { |
113 | dev_err(rtd->dev, "can't set codec pll: %d\n", ret); | 307 | dev_err(rtd->dev, "can't set codec pll: %d\n", ret); |
114 | return ret; | 308 | return ret; |
@@ -127,27 +321,73 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { | |||
127 | { | 321 | { |
128 | .callback = byt_rt5640_quirk_cb, | 322 | .callback = byt_rt5640_quirk_cb, |
129 | .matches = { | 323 | .matches = { |
130 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 324 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
131 | DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"), | 325 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"), |
326 | }, | ||
327 | .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP | | ||
328 | BYT_RT5640_MCLK_EN), | ||
329 | }, | ||
330 | { | ||
331 | .callback = byt_rt5640_quirk_cb, | ||
332 | .matches = { | ||
333 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
334 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"), | ||
132 | }, | 335 | }, |
133 | .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP, | 336 | .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP | |
337 | BYT_RT5640_MONO_SPEAKER | | ||
338 | BYT_RT5640_DIFF_MIC | | ||
339 | BYT_RT5640_SSP0_AIF2 | | ||
340 | BYT_RT5640_MCLK_EN | ||
341 | ), | ||
134 | }, | 342 | }, |
135 | { | 343 | { |
136 | .callback = byt_rt5640_quirk_cb, | 344 | .callback = byt_rt5640_quirk_cb, |
137 | .matches = { | 345 | .matches = { |
138 | DMI_MATCH(DMI_SYS_VENDOR, "DellInc."), | 346 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "DellInc."), |
139 | DMI_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"), | 347 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"), |
140 | }, | 348 | }, |
141 | .driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP | | 349 | .driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP | |
350 | BYT_RT5640_DMIC_EN | | ||
351 | BYT_RT5640_MCLK_EN), | ||
352 | }, | ||
353 | { | ||
354 | .callback = byt_rt5640_quirk_cb, | ||
355 | .matches = { | ||
356 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
357 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"), | ||
358 | }, | ||
359 | .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP | | ||
360 | BYT_RT5640_MCLK_EN), | ||
361 | }, | ||
362 | { | ||
363 | .callback = byt_rt5640_quirk_cb, | ||
364 | .matches = { | ||
365 | DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"), | ||
366 | DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"), | ||
367 | }, | ||
368 | .driver_data = (unsigned long *)(BYT_RT5640_DMIC1_MAP | | ||
142 | BYT_RT5640_DMIC_EN), | 369 | BYT_RT5640_DMIC_EN), |
143 | }, | 370 | }, |
144 | { | 371 | { |
145 | .callback = byt_rt5640_quirk_cb, | 372 | .callback = byt_rt5640_quirk_cb, |
146 | .matches = { | 373 | .matches = { |
147 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 374 | DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), |
148 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"), | 375 | DMI_MATCH(DMI_BOARD_NAME, "tPAD"), |
149 | }, | 376 | }, |
150 | .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP, | 377 | .driver_data = (unsigned long *)(BYT_RT5640_IN3_MAP | |
378 | BYT_RT5640_MCLK_EN | | ||
379 | BYT_RT5640_SSP0_AIF1), | ||
380 | }, | ||
381 | { | ||
382 | .callback = byt_rt5640_quirk_cb, | ||
383 | .matches = { | ||
384 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
385 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"), | ||
386 | }, | ||
387 | .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP | | ||
388 | BYT_RT5640_MCLK_EN | | ||
389 | BYT_RT5640_SSP0_AIF1), | ||
390 | |||
151 | }, | 391 | }, |
152 | {} | 392 | {} |
153 | }; | 393 | }; |
@@ -158,13 +398,18 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) | |||
158 | struct snd_soc_codec *codec = runtime->codec; | 398 | struct snd_soc_codec *codec = runtime->codec; |
159 | struct snd_soc_card *card = runtime->card; | 399 | struct snd_soc_card *card = runtime->card; |
160 | const struct snd_soc_dapm_route *custom_map; | 400 | const struct snd_soc_dapm_route *custom_map; |
401 | struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); | ||
161 | int num_routes; | 402 | int num_routes; |
162 | 403 | ||
163 | card->dapm.idle_bias_off = true; | 404 | card->dapm.idle_bias_off = true; |
164 | 405 | ||
165 | rt5640_sel_asrc_clk_src(codec, | 406 | rt5640_sel_asrc_clk_src(codec, |
166 | RT5640_DA_STEREO_FILTER | | 407 | RT5640_DA_STEREO_FILTER | |
167 | RT5640_AD_STEREO_FILTER, | 408 | RT5640_DA_MONO_L_FILTER | |
409 | RT5640_DA_MONO_R_FILTER | | ||
410 | RT5640_AD_STEREO_FILTER | | ||
411 | RT5640_AD_MONO_L_FILTER | | ||
412 | RT5640_AD_MONO_R_FILTER, | ||
168 | RT5640_CLK_SEL_ASRC); | 413 | RT5640_CLK_SEL_ASRC); |
169 | 414 | ||
170 | ret = snd_soc_add_card_controls(card, byt_rt5640_controls, | 415 | ret = snd_soc_add_card_controls(card, byt_rt5640_controls, |
@@ -179,6 +424,10 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) | |||
179 | custom_map = byt_rt5640_intmic_in1_map; | 424 | custom_map = byt_rt5640_intmic_in1_map; |
180 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map); | 425 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map); |
181 | break; | 426 | break; |
427 | case BYT_RT5640_IN3_MAP: | ||
428 | custom_map = byt_rt5640_intmic_in3_map; | ||
429 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map); | ||
430 | break; | ||
182 | case BYT_RT5640_DMIC2_MAP: | 431 | case BYT_RT5640_DMIC2_MAP: |
183 | custom_map = byt_rt5640_intmic_dmic2_map; | 432 | custom_map = byt_rt5640_intmic_dmic2_map; |
184 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map); | 433 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map); |
@@ -192,6 +441,43 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) | |||
192 | if (ret) | 441 | if (ret) |
193 | return ret; | 442 | return ret; |
194 | 443 | ||
444 | if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) { | ||
445 | ret = snd_soc_dapm_add_routes(&card->dapm, | ||
446 | byt_rt5640_ssp2_aif2_map, | ||
447 | ARRAY_SIZE(byt_rt5640_ssp2_aif2_map)); | ||
448 | } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) { | ||
449 | ret = snd_soc_dapm_add_routes(&card->dapm, | ||
450 | byt_rt5640_ssp0_aif1_map, | ||
451 | ARRAY_SIZE(byt_rt5640_ssp0_aif1_map)); | ||
452 | } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) { | ||
453 | ret = snd_soc_dapm_add_routes(&card->dapm, | ||
454 | byt_rt5640_ssp0_aif2_map, | ||
455 | ARRAY_SIZE(byt_rt5640_ssp0_aif2_map)); | ||
456 | } else { | ||
457 | ret = snd_soc_dapm_add_routes(&card->dapm, | ||
458 | byt_rt5640_ssp2_aif1_map, | ||
459 | ARRAY_SIZE(byt_rt5640_ssp2_aif1_map)); | ||
460 | } | ||
461 | if (ret) | ||
462 | return ret; | ||
463 | |||
464 | if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) { | ||
465 | ret = snd_soc_dapm_add_routes(&card->dapm, | ||
466 | byt_rt5640_mono_spk_map, | ||
467 | ARRAY_SIZE(byt_rt5640_mono_spk_map)); | ||
468 | } else { | ||
469 | ret = snd_soc_dapm_add_routes(&card->dapm, | ||
470 | byt_rt5640_stereo_spk_map, | ||
471 | ARRAY_SIZE(byt_rt5640_stereo_spk_map)); | ||
472 | } | ||
473 | if (ret) | ||
474 | return ret; | ||
475 | |||
476 | if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) { | ||
477 | snd_soc_update_bits(codec, RT5640_IN1_IN2, RT5640_IN_DF1, | ||
478 | RT5640_IN_DF1); | ||
479 | } | ||
480 | |||
195 | if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) { | 481 | if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) { |
196 | ret = rt5640_dmic_enable(codec, 0, 0); | 482 | ret = rt5640_dmic_enable(codec, 0, 0); |
197 | if (ret) | 483 | if (ret) |
@@ -201,6 +487,30 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) | |||
201 | snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); | 487 | snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); |
202 | snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); | 488 | snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); |
203 | 489 | ||
490 | if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) { | ||
491 | /* | ||
492 | * The firmware might enable the clock at | ||
493 | * boot (this information may or may not | ||
494 | * be reflected in the enable clock register). | ||
495 | * To change the rate we must disable the clock | ||
496 | * first to cover these cases. Due to common | ||
497 | * clock framework restrictions that do not allow | ||
498 | * to disable a clock that has not been enabled, | ||
499 | * we need to enable the clock first. | ||
500 | */ | ||
501 | ret = clk_prepare_enable(priv->mclk); | ||
502 | if (!ret) | ||
503 | clk_disable_unprepare(priv->mclk); | ||
504 | |||
505 | if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) | ||
506 | ret = clk_set_rate(priv->mclk, 25000000); | ||
507 | else | ||
508 | ret = clk_set_rate(priv->mclk, 19200000); | ||
509 | |||
510 | if (ret) | ||
511 | dev_err(card->dev, "unable to set MCLK rate\n"); | ||
512 | } | ||
513 | |||
204 | return ret; | 514 | return ret; |
205 | } | 515 | } |
206 | 516 | ||
@@ -221,34 +531,63 @@ static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd, | |||
221 | SNDRV_PCM_HW_PARAM_CHANNELS); | 531 | SNDRV_PCM_HW_PARAM_CHANNELS); |
222 | int ret; | 532 | int ret; |
223 | 533 | ||
224 | /* The DSP will covert the FE rate to 48k, stereo, 24bits */ | 534 | /* The DSP will covert the FE rate to 48k, stereo */ |
225 | rate->min = rate->max = 48000; | 535 | rate->min = rate->max = 48000; |
226 | channels->min = channels->max = 2; | 536 | channels->min = channels->max = 2; |
227 | 537 | ||
228 | /* set SSP2 to 24-bit */ | 538 | if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) || |
229 | params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); | 539 | (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) { |
540 | |||
541 | /* set SSP0 to 16-bit */ | ||
542 | params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); | ||
543 | |||
544 | /* | ||
545 | * Default mode for SSP configuration is TDM 4 slot, override config | ||
546 | * with explicit setting to I2S 2ch 16-bit. The word length is set with | ||
547 | * dai_set_tdm_slot() since there is no other API exposed | ||
548 | */ | ||
549 | ret = snd_soc_dai_set_fmt(rtd->cpu_dai, | ||
550 | SND_SOC_DAIFMT_I2S | | ||
551 | SND_SOC_DAIFMT_NB_IF | | ||
552 | SND_SOC_DAIFMT_CBS_CFS | ||
553 | ); | ||
554 | if (ret < 0) { | ||
555 | dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); | ||
556 | return ret; | ||
557 | } | ||
230 | 558 | ||
231 | /* | 559 | ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 16); |
232 | * Default mode for SSP configuration is TDM 4 slot, override config | 560 | if (ret < 0) { |
233 | * with explicit setting to I2S 2ch 24-bit. The word length is set with | 561 | dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); |
234 | * dai_set_tdm_slot() since there is no other API exposed | 562 | return ret; |
235 | */ | 563 | } |
236 | ret = snd_soc_dai_set_fmt(rtd->cpu_dai, | ||
237 | SND_SOC_DAIFMT_I2S | | ||
238 | SND_SOC_DAIFMT_NB_IF | | ||
239 | SND_SOC_DAIFMT_CBS_CFS | ||
240 | ); | ||
241 | if (ret < 0) { | ||
242 | dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); | ||
243 | return ret; | ||
244 | } | ||
245 | 564 | ||
246 | ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24); | 565 | } else { |
247 | if (ret < 0) { | 566 | |
248 | dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); | 567 | /* set SSP2 to 24-bit */ |
249 | return ret; | 568 | params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); |
250 | } | 569 | |
570 | /* | ||
571 | * Default mode for SSP configuration is TDM 4 slot, override config | ||
572 | * with explicit setting to I2S 2ch 24-bit. The word length is set with | ||
573 | * dai_set_tdm_slot() since there is no other API exposed | ||
574 | */ | ||
575 | ret = snd_soc_dai_set_fmt(rtd->cpu_dai, | ||
576 | SND_SOC_DAIFMT_I2S | | ||
577 | SND_SOC_DAIFMT_NB_IF | | ||
578 | SND_SOC_DAIFMT_CBS_CFS | ||
579 | ); | ||
580 | if (ret < 0) { | ||
581 | dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); | ||
582 | return ret; | ||
583 | } | ||
251 | 584 | ||
585 | ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24); | ||
586 | if (ret < 0) { | ||
587 | dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); | ||
588 | return ret; | ||
589 | } | ||
590 | } | ||
252 | return 0; | 591 | return 0; |
253 | } | 592 | } |
254 | 593 | ||
@@ -305,10 +644,10 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = { | |||
305 | { | 644 | { |
306 | .name = "SSP2-Codec", | 645 | .name = "SSP2-Codec", |
307 | .id = 1, | 646 | .id = 1, |
308 | .cpu_dai_name = "ssp2-port", | 647 | .cpu_dai_name = "ssp2-port", /* overwritten for ssp0 routing */ |
309 | .platform_name = "sst-mfld-platform", | 648 | .platform_name = "sst-mfld-platform", |
310 | .no_pcm = 1, | 649 | .no_pcm = 1, |
311 | .codec_dai_name = "rt5640-aif1", | 650 | .codec_dai_name = "rt5640-aif1", /* changed w/ quirk */ |
312 | .codec_name = "i2c-10EC5640:00", /* overwritten with HID */ | 651 | .codec_name = "i2c-10EC5640:00", /* overwritten with HID */ |
313 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 652 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
314 | | SND_SOC_DAIFMT_CBS_CFS, | 653 | | SND_SOC_DAIFMT_CBS_CFS, |
@@ -335,6 +674,21 @@ static struct snd_soc_card byt_rt5640_card = { | |||
335 | }; | 674 | }; |
336 | 675 | ||
337 | static char byt_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ | 676 | static char byt_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ |
677 | static char byt_rt5640_codec_aif_name[12]; /* = "rt5640-aif[1|2]" */ | ||
678 | static char byt_rt5640_cpu_dai_name[10]; /* = "ssp[0|2]-port" */ | ||
679 | |||
680 | static bool is_valleyview(void) | ||
681 | { | ||
682 | static const struct x86_cpu_id cpu_ids[] = { | ||
683 | { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */ | ||
684 | {} | ||
685 | }; | ||
686 | |||
687 | if (!x86_match_cpu(cpu_ids)) | ||
688 | return false; | ||
689 | return true; | ||
690 | } | ||
691 | |||
338 | 692 | ||
339 | static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) | 693 | static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) |
340 | { | 694 | { |
@@ -343,10 +697,16 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) | |||
343 | const char *i2c_name = NULL; | 697 | const char *i2c_name = NULL; |
344 | int i; | 698 | int i; |
345 | int dai_index; | 699 | int dai_index; |
700 | struct byt_rt5640_private *priv; | ||
701 | |||
702 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); | ||
703 | if (!priv) | ||
704 | return -ENOMEM; | ||
346 | 705 | ||
347 | /* register the soc card */ | 706 | /* register the soc card */ |
348 | byt_rt5640_card.dev = &pdev->dev; | 707 | byt_rt5640_card.dev = &pdev->dev; |
349 | mach = byt_rt5640_card.dev->platform_data; | 708 | mach = byt_rt5640_card.dev->platform_data; |
709 | snd_soc_card_set_drvdata(&byt_rt5640_card, priv); | ||
350 | 710 | ||
351 | /* fix index of codec dai */ | 711 | /* fix index of codec dai */ |
352 | dai_index = MERR_DPCM_COMPR + 1; | 712 | dai_index = MERR_DPCM_COMPR + 1; |
@@ -366,8 +726,57 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) | |||
366 | byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name; | 726 | byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name; |
367 | } | 727 | } |
368 | 728 | ||
729 | /* | ||
730 | * swap SSP0 if bytcr is detected | ||
731 | * (will be overridden if DMI quirk is detected) | ||
732 | */ | ||
733 | if (is_valleyview()) { | ||
734 | struct sst_platform_info *p_info = mach->pdata; | ||
735 | const struct sst_res_info *res_info = p_info->res_info; | ||
736 | |||
737 | /* TODO: use CHAN package info from BIOS to detect AIF1/AIF2 */ | ||
738 | if (res_info->acpi_ipc_irq_index == 0) { | ||
739 | byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2; | ||
740 | } | ||
741 | } | ||
742 | |||
369 | /* check quirks before creating card */ | 743 | /* check quirks before creating card */ |
370 | dmi_check_system(byt_rt5640_quirk_table); | 744 | dmi_check_system(byt_rt5640_quirk_table); |
745 | log_quirks(&pdev->dev); | ||
746 | |||
747 | if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) || | ||
748 | (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) { | ||
749 | |||
750 | /* fixup codec aif name */ | ||
751 | snprintf(byt_rt5640_codec_aif_name, | ||
752 | sizeof(byt_rt5640_codec_aif_name), | ||
753 | "%s", "rt5640-aif2"); | ||
754 | |||
755 | byt_rt5640_dais[dai_index].codec_dai_name = | ||
756 | byt_rt5640_codec_aif_name; | ||
757 | } | ||
758 | |||
759 | if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) || | ||
760 | (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) { | ||
761 | |||
762 | /* fixup cpu dai name name */ | ||
763 | snprintf(byt_rt5640_cpu_dai_name, | ||
764 | sizeof(byt_rt5640_cpu_dai_name), | ||
765 | "%s", "ssp0-port"); | ||
766 | |||
767 | byt_rt5640_dais[dai_index].cpu_dai_name = | ||
768 | byt_rt5640_cpu_dai_name; | ||
769 | } | ||
770 | |||
771 | if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && (is_valleyview())) { | ||
772 | priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); | ||
773 | if (IS_ERR(priv->mclk)) { | ||
774 | dev_err(&pdev->dev, | ||
775 | "Failed to get MCLK from pmc_plt_clk_3: %ld\n", | ||
776 | PTR_ERR(priv->mclk)); | ||
777 | return PTR_ERR(priv->mclk); | ||
778 | } | ||
779 | } | ||
371 | 780 | ||
372 | ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card); | 781 | ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card); |
373 | 782 | ||
diff --git a/sound/soc/intel/common/sst-acpi.c b/sound/soc/intel/common/sst-acpi.c index 2c5eda14d510..1285cc597b6b 100644 --- a/sound/soc/intel/common/sst-acpi.c +++ b/sound/soc/intel/common/sst-acpi.c | |||
@@ -199,6 +199,7 @@ static struct sst_acpi_desc sst_acpi_haswell_desc = { | |||
199 | 199 | ||
200 | static struct sst_acpi_mach broadwell_machines[] = { | 200 | static struct sst_acpi_mach broadwell_machines[] = { |
201 | { "INT343A", "broadwell-audio", "intel/IntcSST2.bin", NULL, NULL, NULL }, | 201 | { "INT343A", "broadwell-audio", "intel/IntcSST2.bin", NULL, NULL, NULL }, |
202 | { "RT5677CE", "bdw-rt5677", "intel/IntcSST2.bin", NULL, NULL, NULL }, | ||
202 | {} | 203 | {} |
203 | }; | 204 | }; |
204 | 205 | ||
diff --git a/sound/soc/intel/haswell/sst-haswell-pcm.c b/sound/soc/intel/haswell/sst-haswell-pcm.c index 3154525c2b83..9e4094e2c6e3 100644 --- a/sound/soc/intel/haswell/sst-haswell-pcm.c +++ b/sound/soc/intel/haswell/sst-haswell-pcm.c | |||
@@ -871,7 +871,7 @@ out: | |||
871 | return ret; | 871 | return ret; |
872 | } | 872 | } |
873 | 873 | ||
874 | static struct snd_pcm_ops hsw_pcm_ops = { | 874 | static const struct snd_pcm_ops hsw_pcm_ops = { |
875 | .open = hsw_pcm_open, | 875 | .open = hsw_pcm_open, |
876 | .close = hsw_pcm_close, | 876 | .close = hsw_pcm_close, |
877 | .ioctl = snd_pcm_lib_ioctl, | 877 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c index 2663781278aa..1d251d59bcb9 100644 --- a/sound/soc/intel/skylake/bxt-sst.c +++ b/sound/soc/intel/skylake/bxt-sst.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "../common/sst-dsp.h" | 23 | #include "../common/sst-dsp.h" |
24 | #include "../common/sst-dsp-priv.h" | 24 | #include "../common/sst-dsp-priv.h" |
25 | #include "skl-sst-ipc.h" | 25 | #include "skl-sst-ipc.h" |
26 | #include "skl-tplg-interface.h" | ||
26 | 27 | ||
27 | #define BXT_BASEFW_TIMEOUT 3000 | 28 | #define BXT_BASEFW_TIMEOUT 3000 |
28 | #define BXT_INIT_TIMEOUT 500 | 29 | #define BXT_INIT_TIMEOUT 500 |
@@ -40,11 +41,73 @@ | |||
40 | #define BXT_INSTANCE_ID 0 | 41 | #define BXT_INSTANCE_ID 0 |
41 | #define BXT_BASE_FW_MODULE_ID 0 | 42 | #define BXT_BASE_FW_MODULE_ID 0 |
42 | 43 | ||
44 | #define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000 | ||
45 | |||
43 | static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) | 46 | static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) |
44 | { | 47 | { |
45 | return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE); | 48 | return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE); |
46 | } | 49 | } |
47 | 50 | ||
51 | static int | ||
52 | bxt_load_library(struct sst_dsp *ctx, struct skl_dfw_manifest *minfo) | ||
53 | { | ||
54 | struct snd_dma_buffer dmab; | ||
55 | struct skl_sst *skl = ctx->thread_context; | ||
56 | const struct firmware *fw = NULL; | ||
57 | struct firmware stripped_fw; | ||
58 | int ret = 0, i, dma_id, stream_tag; | ||
59 | |||
60 | /* library indices start from 1 to N. 0 represents base FW */ | ||
61 | for (i = 1; i < minfo->lib_count; i++) { | ||
62 | ret = request_firmware(&fw, minfo->lib[i].name, ctx->dev); | ||
63 | if (ret < 0) { | ||
64 | dev_err(ctx->dev, "Request lib %s failed:%d\n", | ||
65 | minfo->lib[i].name, ret); | ||
66 | return ret; | ||
67 | } | ||
68 | |||
69 | if (skl->is_first_boot) { | ||
70 | ret = snd_skl_parse_uuids(ctx, fw, | ||
71 | BXT_ADSP_FW_BIN_HDR_OFFSET, i); | ||
72 | if (ret < 0) | ||
73 | goto load_library_failed; | ||
74 | } | ||
75 | |||
76 | stripped_fw.data = fw->data; | ||
77 | stripped_fw.size = fw->size; | ||
78 | skl_dsp_strip_extended_manifest(&stripped_fw); | ||
79 | |||
80 | stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, | ||
81 | stripped_fw.size, &dmab); | ||
82 | if (stream_tag <= 0) { | ||
83 | dev_err(ctx->dev, "Lib prepare DMA err: %x\n", | ||
84 | stream_tag); | ||
85 | ret = stream_tag; | ||
86 | goto load_library_failed; | ||
87 | } | ||
88 | |||
89 | dma_id = stream_tag - 1; | ||
90 | memcpy(dmab.area, stripped_fw.data, stripped_fw.size); | ||
91 | |||
92 | ctx->dsp_ops.trigger(ctx->dev, true, stream_tag); | ||
93 | ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i); | ||
94 | if (ret < 0) | ||
95 | dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n", | ||
96 | minfo->lib[i].name, ret); | ||
97 | |||
98 | ctx->dsp_ops.trigger(ctx->dev, false, stream_tag); | ||
99 | ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag); | ||
100 | release_firmware(fw); | ||
101 | fw = NULL; | ||
102 | } | ||
103 | |||
104 | return ret; | ||
105 | |||
106 | load_library_failed: | ||
107 | release_firmware(fw); | ||
108 | return ret; | ||
109 | } | ||
110 | |||
48 | /* | 111 | /* |
49 | * First boot sequence has some extra steps. Core 0 waits for power | 112 | * First boot sequence has some extra steps. Core 0 waits for power |
50 | * status on core 1, so power up core 1 also momentarily, keep it in | 113 | * status on core 1, so power up core 1 also momentarily, keep it in |
@@ -157,8 +220,6 @@ static int sst_transfer_fw_host_dma(struct sst_dsp *ctx) | |||
157 | return ret; | 220 | return ret; |
158 | } | 221 | } |
159 | 222 | ||
160 | #define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000 | ||
161 | |||
162 | static int bxt_load_base_firmware(struct sst_dsp *ctx) | 223 | static int bxt_load_base_firmware(struct sst_dsp *ctx) |
163 | { | 224 | { |
164 | struct firmware stripped_fw; | 225 | struct firmware stripped_fw; |
@@ -175,9 +236,12 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx) | |||
175 | if (ctx->fw == NULL) | 236 | if (ctx->fw == NULL) |
176 | goto sst_load_base_firmware_failed; | 237 | goto sst_load_base_firmware_failed; |
177 | 238 | ||
178 | ret = snd_skl_parse_uuids(ctx, BXT_ADSP_FW_BIN_HDR_OFFSET); | 239 | /* prase uuids on first boot */ |
179 | if (ret < 0) | 240 | if (skl->is_first_boot) { |
180 | goto sst_load_base_firmware_failed; | 241 | ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0); |
242 | if (ret < 0) | ||
243 | goto sst_load_base_firmware_failed; | ||
244 | } | ||
181 | 245 | ||
182 | stripped_fw.data = ctx->fw->data; | 246 | stripped_fw.data = ctx->fw->data; |
183 | stripped_fw.size = ctx->fw->size; | 247 | stripped_fw.size = ctx->fw->size; |
@@ -230,12 +294,23 @@ static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) | |||
230 | int ret; | 294 | int ret; |
231 | struct skl_ipc_dxstate_info dx; | 295 | struct skl_ipc_dxstate_info dx; |
232 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); | 296 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); |
297 | struct skl_dfw_manifest *minfo = &skl->manifest; | ||
233 | 298 | ||
234 | if (skl->fw_loaded == false) { | 299 | if (skl->fw_loaded == false) { |
235 | skl->boot_complete = false; | 300 | skl->boot_complete = false; |
236 | ret = bxt_load_base_firmware(ctx); | 301 | ret = bxt_load_base_firmware(ctx); |
237 | if (ret < 0) | 302 | if (ret < 0) { |
238 | dev_err(ctx->dev, "reload fw failed: %d\n", ret); | 303 | dev_err(ctx->dev, "reload fw failed: %d\n", ret); |
304 | return ret; | ||
305 | } | ||
306 | |||
307 | if (minfo->lib_count > 1) { | ||
308 | ret = bxt_load_library(ctx, minfo); | ||
309 | if (ret < 0) { | ||
310 | dev_err(ctx->dev, "reload libs failed: %d\n", ret); | ||
311 | return ret; | ||
312 | } | ||
313 | } | ||
239 | return ret; | 314 | return ret; |
240 | } | 315 | } |
241 | 316 | ||
@@ -329,7 +404,7 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) | |||
329 | 404 | ||
330 | ret = skl_dsp_disable_core(ctx, core_mask); | 405 | ret = skl_dsp_disable_core(ctx, core_mask); |
331 | if (ret < 0) { | 406 | if (ret < 0) { |
332 | dev_err(ctx->dev, "Failed to disable core %d", ret); | 407 | dev_err(ctx->dev, "Failed to disable core %d\n", ret); |
333 | return ret; | 408 | return ret; |
334 | } | 409 | } |
335 | skl->cores.state[core_id] = SKL_DSP_RESET; | 410 | skl->cores.state[core_id] = SKL_DSP_RESET; |
@@ -341,6 +416,7 @@ static struct skl_dsp_fw_ops bxt_fw_ops = { | |||
341 | .set_state_D3 = bxt_set_dsp_D3, | 416 | .set_state_D3 = bxt_set_dsp_D3, |
342 | .load_fw = bxt_load_base_firmware, | 417 | .load_fw = bxt_load_base_firmware, |
343 | .get_fw_errcode = bxt_get_errorcode, | 418 | .get_fw_errcode = bxt_get_errorcode, |
419 | .load_library = bxt_load_library, | ||
344 | }; | 420 | }; |
345 | 421 | ||
346 | static struct sst_ops skl_ops = { | 422 | static struct sst_ops skl_ops = { |
@@ -397,22 +473,40 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | |||
397 | skl->cores.count = 2; | 473 | skl->cores.count = 2; |
398 | skl->boot_complete = false; | 474 | skl->boot_complete = false; |
399 | init_waitqueue_head(&skl->boot_wait); | 475 | init_waitqueue_head(&skl->boot_wait); |
476 | skl->is_first_boot = true; | ||
477 | |||
478 | if (dsp) | ||
479 | *dsp = skl; | ||
480 | |||
481 | return 0; | ||
482 | } | ||
483 | EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); | ||
484 | |||
485 | int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx) | ||
486 | { | ||
487 | int ret; | ||
488 | struct sst_dsp *sst = ctx->dsp; | ||
400 | 489 | ||
401 | ret = sst->fw_ops.load_fw(sst); | 490 | ret = sst->fw_ops.load_fw(sst); |
402 | if (ret < 0) { | 491 | if (ret < 0) { |
403 | dev_err(dev, "Load base fw failed: %x", ret); | 492 | dev_err(dev, "Load base fw failed: %x\n", ret); |
404 | return ret; | 493 | return ret; |
405 | } | 494 | } |
406 | 495 | ||
407 | skl_dsp_init_core_state(sst); | 496 | skl_dsp_init_core_state(sst); |
408 | 497 | ||
409 | if (dsp) | 498 | if (ctx->manifest.lib_count > 1) { |
410 | *dsp = skl; | 499 | ret = sst->fw_ops.load_library(sst, &ctx->manifest); |
500 | if (ret < 0) { | ||
501 | dev_err(dev, "Load Library failed : %x\n", ret); | ||
502 | return ret; | ||
503 | } | ||
504 | } | ||
505 | ctx->is_first_boot = false; | ||
411 | 506 | ||
412 | return 0; | 507 | return 0; |
413 | } | 508 | } |
414 | EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); | 509 | EXPORT_SYMBOL_GPL(bxt_sst_init_fw); |
415 | |||
416 | 510 | ||
417 | void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) | 511 | void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) |
418 | { | 512 | { |
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index 83a731fc884e..805b7f2173f3 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c | |||
@@ -203,32 +203,35 @@ static const struct skl_dsp_ops dsp_ops[] = { | |||
203 | .id = 0x9d70, | 203 | .id = 0x9d70, |
204 | .loader_ops = skl_get_loader_ops, | 204 | .loader_ops = skl_get_loader_ops, |
205 | .init = skl_sst_dsp_init, | 205 | .init = skl_sst_dsp_init, |
206 | .init_fw = skl_sst_init_fw, | ||
206 | .cleanup = skl_sst_dsp_cleanup | 207 | .cleanup = skl_sst_dsp_cleanup |
207 | }, | 208 | }, |
208 | { | 209 | { |
209 | .id = 0x9d71, | 210 | .id = 0x9d71, |
210 | .loader_ops = skl_get_loader_ops, | 211 | .loader_ops = skl_get_loader_ops, |
211 | .init = skl_sst_dsp_init, | 212 | .init = skl_sst_dsp_init, |
213 | .init_fw = skl_sst_init_fw, | ||
212 | .cleanup = skl_sst_dsp_cleanup | 214 | .cleanup = skl_sst_dsp_cleanup |
213 | }, | 215 | }, |
214 | { | 216 | { |
215 | .id = 0x5a98, | 217 | .id = 0x5a98, |
216 | .loader_ops = bxt_get_loader_ops, | 218 | .loader_ops = bxt_get_loader_ops, |
217 | .init = bxt_sst_dsp_init, | 219 | .init = bxt_sst_dsp_init, |
220 | .init_fw = bxt_sst_init_fw, | ||
218 | .cleanup = bxt_sst_dsp_cleanup | 221 | .cleanup = bxt_sst_dsp_cleanup |
219 | }, | 222 | }, |
220 | }; | 223 | }; |
221 | 224 | ||
222 | static int skl_get_dsp_ops(int pci_id) | 225 | const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id) |
223 | { | 226 | { |
224 | int i; | 227 | int i; |
225 | 228 | ||
226 | for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) { | 229 | for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) { |
227 | if (dsp_ops[i].id == pci_id) | 230 | if (dsp_ops[i].id == pci_id) |
228 | return i; | 231 | return &dsp_ops[i]; |
229 | } | 232 | } |
230 | 233 | ||
231 | return -EINVAL; | 234 | return NULL; |
232 | } | 235 | } |
233 | 236 | ||
234 | int skl_init_dsp(struct skl *skl) | 237 | int skl_init_dsp(struct skl *skl) |
@@ -238,7 +241,8 @@ int skl_init_dsp(struct skl *skl) | |||
238 | struct hdac_bus *bus = ebus_to_hbus(ebus); | 241 | struct hdac_bus *bus = ebus_to_hbus(ebus); |
239 | struct skl_dsp_loader_ops loader_ops; | 242 | struct skl_dsp_loader_ops loader_ops; |
240 | int irq = bus->irq; | 243 | int irq = bus->irq; |
241 | int ret, index; | 244 | const struct skl_dsp_ops *ops; |
245 | int ret; | ||
242 | 246 | ||
243 | /* enable ppcap interrupt */ | 247 | /* enable ppcap interrupt */ |
244 | snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); | 248 | snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); |
@@ -251,18 +255,18 @@ int skl_init_dsp(struct skl *skl) | |||
251 | return -ENXIO; | 255 | return -ENXIO; |
252 | } | 256 | } |
253 | 257 | ||
254 | index = skl_get_dsp_ops(skl->pci->device); | 258 | ops = skl_get_dsp_ops(skl->pci->device); |
255 | if (index < 0) | 259 | if (!ops) |
256 | return -EINVAL; | 260 | return -EIO; |
257 | 261 | ||
258 | loader_ops = dsp_ops[index].loader_ops(); | 262 | loader_ops = ops->loader_ops(); |
259 | ret = dsp_ops[index].init(bus->dev, mmio_base, irq, | 263 | ret = ops->init(bus->dev, mmio_base, irq, |
260 | skl->fw_name, loader_ops, &skl->skl_sst); | 264 | skl->fw_name, loader_ops, |
265 | &skl->skl_sst); | ||
261 | 266 | ||
262 | if (ret < 0) | 267 | if (ret < 0) |
263 | return ret; | 268 | return ret; |
264 | 269 | ||
265 | skl_dsp_enable_notification(skl->skl_sst, false); | ||
266 | dev_dbg(bus->dev, "dsp registration status=%d\n", ret); | 270 | dev_dbg(bus->dev, "dsp registration status=%d\n", ret); |
267 | 271 | ||
268 | return ret; | 272 | return ret; |
@@ -273,16 +277,16 @@ int skl_free_dsp(struct skl *skl) | |||
273 | struct hdac_ext_bus *ebus = &skl->ebus; | 277 | struct hdac_ext_bus *ebus = &skl->ebus; |
274 | struct hdac_bus *bus = ebus_to_hbus(ebus); | 278 | struct hdac_bus *bus = ebus_to_hbus(ebus); |
275 | struct skl_sst *ctx = skl->skl_sst; | 279 | struct skl_sst *ctx = skl->skl_sst; |
276 | int index; | 280 | const struct skl_dsp_ops *ops; |
277 | 281 | ||
278 | /* disable ppcap interrupt */ | 282 | /* disable ppcap interrupt */ |
279 | snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false); | 283 | snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false); |
280 | 284 | ||
281 | index = skl_get_dsp_ops(skl->pci->device); | 285 | ops = skl_get_dsp_ops(skl->pci->device); |
282 | if (index < 0) | 286 | if (!ops) |
283 | return -EIO; | 287 | return -EIO; |
284 | 288 | ||
285 | dsp_ops[index].cleanup(bus->dev, ctx); | 289 | ops->cleanup(bus->dev, ctx); |
286 | 290 | ||
287 | if (ctx->dsp->addr.lpe) | 291 | if (ctx->dsp->addr.lpe) |
288 | iounmap(ctx->dsp->addr.lpe); | 292 | iounmap(ctx->dsp->addr.lpe); |
@@ -323,6 +327,10 @@ int skl_resume_dsp(struct skl *skl) | |||
323 | snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); | 327 | snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); |
324 | snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true); | 328 | snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true); |
325 | 329 | ||
330 | /* check if DSP 1st boot is done */ | ||
331 | if (skl->skl_sst->is_first_boot == true) | ||
332 | return 0; | ||
333 | |||
326 | ret = skl_dsp_wake(ctx->dsp); | 334 | ret = skl_dsp_wake(ctx->dsp); |
327 | if (ret < 0) | 335 | if (ret < 0) |
328 | return ret; | 336 | return ret; |
@@ -672,6 +680,7 @@ static u16 skl_get_module_param_size(struct skl_sst *ctx, | |||
672 | return param_size; | 680 | return param_size; |
673 | 681 | ||
674 | case SKL_MODULE_TYPE_BASE_OUTFMT: | 682 | case SKL_MODULE_TYPE_BASE_OUTFMT: |
683 | case SKL_MODULE_TYPE_KPB: | ||
675 | return sizeof(struct skl_base_outfmt_cfg); | 684 | return sizeof(struct skl_base_outfmt_cfg); |
676 | 685 | ||
677 | default: | 686 | default: |
@@ -725,6 +734,7 @@ static int skl_set_module_format(struct skl_sst *ctx, | |||
725 | break; | 734 | break; |
726 | 735 | ||
727 | case SKL_MODULE_TYPE_BASE_OUTFMT: | 736 | case SKL_MODULE_TYPE_BASE_OUTFMT: |
737 | case SKL_MODULE_TYPE_KPB: | ||
728 | skl_set_base_outfmt_format(ctx, module_config, *param_data); | 738 | skl_set_base_outfmt_format(ctx, module_config, *param_data); |
729 | break; | 739 | break; |
730 | 740 | ||
@@ -779,6 +789,7 @@ static int skl_alloc_queue(struct skl_module_pin *mpin, | |||
779 | mpin[i].in_use = true; | 789 | mpin[i].in_use = true; |
780 | mpin[i].id.module_id = id.module_id; | 790 | mpin[i].id.module_id = id.module_id; |
781 | mpin[i].id.instance_id = id.instance_id; | 791 | mpin[i].id.instance_id = id.instance_id; |
792 | mpin[i].id.pvt_id = id.pvt_id; | ||
782 | mpin[i].tgt_mcfg = tgt_cfg; | 793 | mpin[i].tgt_mcfg = tgt_cfg; |
783 | return i; | 794 | return i; |
784 | } | 795 | } |
@@ -802,6 +813,7 @@ static void skl_free_queue(struct skl_module_pin *mpin, int q_index) | |||
802 | mpin[q_index].in_use = false; | 813 | mpin[q_index].in_use = false; |
803 | mpin[q_index].id.module_id = 0; | 814 | mpin[q_index].id.module_id = 0; |
804 | mpin[q_index].id.instance_id = 0; | 815 | mpin[q_index].id.instance_id = 0; |
816 | mpin[q_index].id.pvt_id = 0; | ||
805 | } | 817 | } |
806 | mpin[q_index].pin_state = SKL_PIN_UNBIND; | 818 | mpin[q_index].pin_state = SKL_PIN_UNBIND; |
807 | mpin[q_index].tgt_mcfg = NULL; | 819 | mpin[q_index].tgt_mcfg = NULL; |
@@ -842,7 +854,7 @@ int skl_init_module(struct skl_sst *ctx, | |||
842 | struct skl_ipc_init_instance_msg msg; | 854 | struct skl_ipc_init_instance_msg msg; |
843 | 855 | ||
844 | dev_dbg(ctx->dev, "%s: module_id = %d instance=%d\n", __func__, | 856 | dev_dbg(ctx->dev, "%s: module_id = %d instance=%d\n", __func__, |
845 | mconfig->id.module_id, mconfig->id.instance_id); | 857 | mconfig->id.module_id, mconfig->id.pvt_id); |
846 | 858 | ||
847 | if (mconfig->pipe->state != SKL_PIPE_CREATED) { | 859 | if (mconfig->pipe->state != SKL_PIPE_CREATED) { |
848 | dev_err(ctx->dev, "Pipe not created state= %d pipe_id= %d\n", | 860 | dev_err(ctx->dev, "Pipe not created state= %d pipe_id= %d\n", |
@@ -858,10 +870,11 @@ int skl_init_module(struct skl_sst *ctx, | |||
858 | } | 870 | } |
859 | 871 | ||
860 | msg.module_id = mconfig->id.module_id; | 872 | msg.module_id = mconfig->id.module_id; |
861 | msg.instance_id = mconfig->id.instance_id; | 873 | msg.instance_id = mconfig->id.pvt_id; |
862 | msg.ppl_instance_id = mconfig->pipe->ppl_id; | 874 | msg.ppl_instance_id = mconfig->pipe->ppl_id; |
863 | msg.param_data_size = module_config_size; | 875 | msg.param_data_size = module_config_size; |
864 | msg.core_id = mconfig->core_id; | 876 | msg.core_id = mconfig->core_id; |
877 | msg.domain = mconfig->domain; | ||
865 | 878 | ||
866 | ret = skl_ipc_init_instance(&ctx->ipc, &msg, param_data); | 879 | ret = skl_ipc_init_instance(&ctx->ipc, &msg, param_data); |
867 | if (ret < 0) { | 880 | if (ret < 0) { |
@@ -878,9 +891,9 @@ static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg | |||
878 | *src_module, struct skl_module_cfg *dst_module) | 891 | *src_module, struct skl_module_cfg *dst_module) |
879 | { | 892 | { |
880 | dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n", | 893 | dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n", |
881 | __func__, src_module->id.module_id, src_module->id.instance_id); | 894 | __func__, src_module->id.module_id, src_module->id.pvt_id); |
882 | dev_dbg(ctx->dev, "%s: dst_module=%d dst_instacne=%d\n", __func__, | 895 | dev_dbg(ctx->dev, "%s: dst_module=%d dst_instacne=%d\n", __func__, |
883 | dst_module->id.module_id, dst_module->id.instance_id); | 896 | dst_module->id.module_id, dst_module->id.pvt_id); |
884 | 897 | ||
885 | dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n", | 898 | dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n", |
886 | src_module->m_state, dst_module->m_state); | 899 | src_module->m_state, dst_module->m_state); |
@@ -927,9 +940,9 @@ int skl_unbind_modules(struct skl_sst *ctx, | |||
927 | return 0; | 940 | return 0; |
928 | 941 | ||
929 | msg.module_id = src_mcfg->id.module_id; | 942 | msg.module_id = src_mcfg->id.module_id; |
930 | msg.instance_id = src_mcfg->id.instance_id; | 943 | msg.instance_id = src_mcfg->id.pvt_id; |
931 | msg.dst_module_id = dst_mcfg->id.module_id; | 944 | msg.dst_module_id = dst_mcfg->id.module_id; |
932 | msg.dst_instance_id = dst_mcfg->id.instance_id; | 945 | msg.dst_instance_id = dst_mcfg->id.pvt_id; |
933 | msg.bind = false; | 946 | msg.bind = false; |
934 | 947 | ||
935 | ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); | 948 | ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); |
@@ -988,9 +1001,9 @@ int skl_bind_modules(struct skl_sst *ctx, | |||
988 | msg.src_queue, msg.dst_queue); | 1001 | msg.src_queue, msg.dst_queue); |
989 | 1002 | ||
990 | msg.module_id = src_mcfg->id.module_id; | 1003 | msg.module_id = src_mcfg->id.module_id; |
991 | msg.instance_id = src_mcfg->id.instance_id; | 1004 | msg.instance_id = src_mcfg->id.pvt_id; |
992 | msg.dst_module_id = dst_mcfg->id.module_id; | 1005 | msg.dst_module_id = dst_mcfg->id.module_id; |
993 | msg.dst_instance_id = dst_mcfg->id.instance_id; | 1006 | msg.dst_instance_id = dst_mcfg->id.pvt_id; |
994 | msg.bind = true; | 1007 | msg.bind = true; |
995 | 1008 | ||
996 | ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); | 1009 | ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); |
@@ -1168,7 +1181,7 @@ int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size, | |||
1168 | struct skl_ipc_large_config_msg msg; | 1181 | struct skl_ipc_large_config_msg msg; |
1169 | 1182 | ||
1170 | msg.module_id = mcfg->id.module_id; | 1183 | msg.module_id = mcfg->id.module_id; |
1171 | msg.instance_id = mcfg->id.instance_id; | 1184 | msg.instance_id = mcfg->id.pvt_id; |
1172 | msg.param_data_size = size; | 1185 | msg.param_data_size = size; |
1173 | msg.large_param_id = param_id; | 1186 | msg.large_param_id = param_id; |
1174 | 1187 | ||
@@ -1181,7 +1194,7 @@ int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size, | |||
1181 | struct skl_ipc_large_config_msg msg; | 1194 | struct skl_ipc_large_config_msg msg; |
1182 | 1195 | ||
1183 | msg.module_id = mcfg->id.module_id; | 1196 | msg.module_id = mcfg->id.module_id; |
1184 | msg.instance_id = mcfg->id.instance_id; | 1197 | msg.instance_id = mcfg->id.pvt_id; |
1185 | msg.param_data_size = size; | 1198 | msg.param_data_size = size; |
1186 | msg.large_param_id = param_id; | 1199 | msg.large_param_id = param_id; |
1187 | 1200 | ||
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 5ae86c227d45..58c728662600 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c | |||
@@ -648,7 +648,8 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { | |||
648 | .channels_min = HDA_MONO, | 648 | .channels_min = HDA_MONO, |
649 | .channels_max = HDA_STEREO, | 649 | .channels_max = HDA_STEREO, |
650 | .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000, | 650 | .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000, |
651 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, | 651 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
652 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, | ||
652 | }, | 653 | }, |
653 | .capture = { | 654 | .capture = { |
654 | .stream_name = "System Capture", | 655 | .stream_name = "System Capture", |
@@ -1020,7 +1021,7 @@ static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream, | |||
1020 | { | 1021 | { |
1021 | struct hdac_ext_bus *ebus = get_bus_ctx(substream); | 1022 | struct hdac_ext_bus *ebus = get_bus_ctx(substream); |
1022 | 1023 | ||
1023 | if ((ebus_to_hbus(ebus))->ppcap) | 1024 | if (!(ebus_to_hbus(ebus))->ppcap) |
1024 | return skl_coupled_trigger(substream, cmd); | 1025 | return skl_coupled_trigger(substream, cmd); |
1025 | 1026 | ||
1026 | return 0; | 1027 | return 0; |
@@ -1093,7 +1094,7 @@ static int skl_get_time_info(struct snd_pcm_substream *substream, | |||
1093 | return 0; | 1094 | return 0; |
1094 | } | 1095 | } |
1095 | 1096 | ||
1096 | static struct snd_pcm_ops skl_platform_ops = { | 1097 | static const struct snd_pcm_ops skl_platform_ops = { |
1097 | .open = skl_platform_open, | 1098 | .open = skl_platform_open, |
1098 | .ioctl = snd_pcm_lib_ioctl, | 1099 | .ioctl = snd_pcm_lib_ioctl, |
1099 | .trigger = skl_platform_pcm_trigger, | 1100 | .trigger = skl_platform_pcm_trigger, |
@@ -1138,12 +1139,40 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
1138 | return retval; | 1139 | return retval; |
1139 | } | 1140 | } |
1140 | 1141 | ||
1142 | static int skl_populate_modules(struct skl *skl) | ||
1143 | { | ||
1144 | struct skl_pipeline *p; | ||
1145 | struct skl_pipe_module *m; | ||
1146 | struct snd_soc_dapm_widget *w; | ||
1147 | struct skl_module_cfg *mconfig; | ||
1148 | int ret; | ||
1149 | |||
1150 | list_for_each_entry(p, &skl->ppl_list, node) { | ||
1151 | list_for_each_entry(m, &p->pipe->w_list, node) { | ||
1152 | |||
1153 | w = m->w; | ||
1154 | mconfig = w->priv; | ||
1155 | |||
1156 | ret = snd_skl_get_module_info(skl->skl_sst, mconfig); | ||
1157 | if (ret < 0) { | ||
1158 | dev_err(skl->skl_sst->dev, | ||
1159 | "query module info failed:%d\n", ret); | ||
1160 | goto err; | ||
1161 | } | ||
1162 | } | ||
1163 | } | ||
1164 | err: | ||
1165 | return ret; | ||
1166 | } | ||
1167 | |||
1141 | static int skl_platform_soc_probe(struct snd_soc_platform *platform) | 1168 | static int skl_platform_soc_probe(struct snd_soc_platform *platform) |
1142 | { | 1169 | { |
1143 | struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev); | 1170 | struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev); |
1144 | struct skl *skl = ebus_to_skl(ebus); | 1171 | struct skl *skl = ebus_to_skl(ebus); |
1172 | const struct skl_dsp_ops *ops; | ||
1145 | int ret; | 1173 | int ret; |
1146 | 1174 | ||
1175 | pm_runtime_get_sync(platform->dev); | ||
1147 | if ((ebus_to_hbus(ebus))->ppcap) { | 1176 | if ((ebus_to_hbus(ebus))->ppcap) { |
1148 | ret = skl_tplg_init(platform, ebus); | 1177 | ret = skl_tplg_init(platform, ebus); |
1149 | if (ret < 0) { | 1178 | if (ret < 0) { |
@@ -1151,7 +1180,26 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform) | |||
1151 | return ret; | 1180 | return ret; |
1152 | } | 1181 | } |
1153 | skl->platform = platform; | 1182 | skl->platform = platform; |
1183 | |||
1184 | /* load the firmwares, since all is set */ | ||
1185 | ops = skl_get_dsp_ops(skl->pci->device); | ||
1186 | if (!ops) | ||
1187 | return -EIO; | ||
1188 | |||
1189 | if (skl->skl_sst->is_first_boot == false) { | ||
1190 | dev_err(platform->dev, "DSP reports first boot done!!!\n"); | ||
1191 | return -EIO; | ||
1192 | } | ||
1193 | |||
1194 | ret = ops->init_fw(platform->dev, skl->skl_sst); | ||
1195 | if (ret < 0) { | ||
1196 | dev_err(platform->dev, "Failed to boot first fw: %d\n", ret); | ||
1197 | return ret; | ||
1198 | } | ||
1199 | skl_populate_modules(skl); | ||
1154 | } | 1200 | } |
1201 | pm_runtime_mark_last_busy(platform->dev); | ||
1202 | pm_runtime_put_autosuspend(platform->dev); | ||
1155 | 1203 | ||
1156 | return 0; | 1204 | return 0; |
1157 | } | 1205 | } |
diff --git a/sound/soc/intel/skylake/skl-sst-cldma.c b/sound/soc/intel/skylake/skl-sst-cldma.c index da2329d17f4d..efa2532114ba 100644 --- a/sound/soc/intel/skylake/skl-sst-cldma.c +++ b/sound/soc/intel/skylake/skl-sst-cldma.c | |||
@@ -341,14 +341,14 @@ int skl_cldma_prepare(struct sst_dsp *ctx) | |||
341 | ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev, | 341 | ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev, |
342 | &ctx->cl_dev.dmab_data, ctx->cl_dev.bufsize); | 342 | &ctx->cl_dev.dmab_data, ctx->cl_dev.bufsize); |
343 | if (ret < 0) { | 343 | if (ret < 0) { |
344 | dev_err(ctx->dev, "Alloc buffer for base fw failed: %x", ret); | 344 | dev_err(ctx->dev, "Alloc buffer for base fw failed: %x\n", ret); |
345 | return ret; | 345 | return ret; |
346 | } | 346 | } |
347 | /* Setup Code loader BDL */ | 347 | /* Setup Code loader BDL */ |
348 | ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev, | 348 | ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev, |
349 | &ctx->cl_dev.dmab_bdl, PAGE_SIZE); | 349 | &ctx->cl_dev.dmab_bdl, PAGE_SIZE); |
350 | if (ret < 0) { | 350 | if (ret < 0) { |
351 | dev_err(ctx->dev, "Alloc buffer for blde failed: %x", ret); | 351 | dev_err(ctx->dev, "Alloc buffer for blde failed: %x\n", ret); |
352 | ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_data); | 352 | ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_data); |
353 | return ret; | 353 | return ret; |
354 | } | 354 | } |
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h index 0f8629ef79ac..b9e71d051fb1 100644 --- a/sound/soc/intel/skylake/skl-sst-dsp.h +++ b/sound/soc/intel/skylake/skl-sst-dsp.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <sound/memalloc.h> | 20 | #include <sound/memalloc.h> |
21 | #include "skl-sst-cldma.h" | 21 | #include "skl-sst-cldma.h" |
22 | #include "skl-tplg-interface.h" | 22 | #include "skl-tplg-interface.h" |
23 | #include "skl-topology.h" | ||
23 | 24 | ||
24 | struct sst_dsp; | 25 | struct sst_dsp; |
25 | struct skl_sst; | 26 | struct skl_sst; |
@@ -133,6 +134,8 @@ enum skl_dsp_states { | |||
133 | struct skl_dsp_fw_ops { | 134 | struct skl_dsp_fw_ops { |
134 | int (*load_fw)(struct sst_dsp *ctx); | 135 | int (*load_fw)(struct sst_dsp *ctx); |
135 | /* FW module parser/loader */ | 136 | /* FW module parser/loader */ |
137 | int (*load_library)(struct sst_dsp *ctx, | ||
138 | struct skl_dfw_manifest *minfo); | ||
136 | int (*parse_fw)(struct sst_dsp *ctx); | 139 | int (*parse_fw)(struct sst_dsp *ctx); |
137 | int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id); | 140 | int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id); |
138 | int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id); | 141 | int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id); |
@@ -203,12 +206,21 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | |||
203 | int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | 206 | int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, |
204 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, | 207 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, |
205 | struct skl_sst **dsp); | 208 | struct skl_sst **dsp); |
209 | int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx); | ||
210 | int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx); | ||
206 | void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); | 211 | void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); |
207 | void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); | 212 | void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); |
208 | 213 | ||
209 | int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid, | 214 | int snd_skl_get_module_info(struct skl_sst *ctx, |
210 | struct skl_dfw_module *dfw_config); | 215 | struct skl_module_cfg *mconfig); |
211 | int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset); | 216 | int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw, |
217 | unsigned int offset, int index); | ||
218 | int skl_get_pvt_id(struct skl_sst *ctx, | ||
219 | struct skl_module_cfg *mconfig); | ||
220 | int skl_put_pvt_id(struct skl_sst *ctx, | ||
221 | struct skl_module_cfg *mconfig); | ||
222 | int skl_get_pvt_instance_id_map(struct skl_sst *ctx, | ||
223 | int module_id, int instance_id); | ||
212 | void skl_freeup_uuid_list(struct skl_sst *ctx); | 224 | void skl_freeup_uuid_list(struct skl_sst *ctx); |
213 | 225 | ||
214 | int skl_dsp_strip_extended_manifest(struct firmware *fw); | 226 | int skl_dsp_strip_extended_manifest(struct firmware *fw); |
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c index 96f2f6889b18..0bd01e62622c 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.c +++ b/sound/soc/intel/skylake/skl-sst-ipc.c | |||
@@ -114,6 +114,11 @@ | |||
114 | #define IPC_CORE_ID(x) (((x) & IPC_CORE_ID_MASK) \ | 114 | #define IPC_CORE_ID(x) (((x) & IPC_CORE_ID_MASK) \ |
115 | << IPC_CORE_ID_SHIFT) | 115 | << IPC_CORE_ID_SHIFT) |
116 | 116 | ||
117 | #define IPC_DOMAIN_SHIFT 28 | ||
118 | #define IPC_DOMAIN_MASK 0x1 | ||
119 | #define IPC_DOMAIN(x) (((x) & IPC_DOMAIN_MASK) \ | ||
120 | << IPC_DOMAIN_SHIFT) | ||
121 | |||
117 | /* Bind/Unbind message extension register */ | 122 | /* Bind/Unbind message extension register */ |
118 | #define IPC_DST_MOD_ID_SHIFT 0 | 123 | #define IPC_DST_MOD_ID_SHIFT 0 |
119 | #define IPC_DST_MOD_ID(x) (((x) & IPC_MOD_ID_MASK) \ | 124 | #define IPC_DST_MOD_ID(x) (((x) & IPC_MOD_ID_MASK) \ |
@@ -190,6 +195,7 @@ enum skl_ipc_glb_type { | |||
190 | IPC_GLB_GET_PPL_CONTEXT_SIZE = 21, | 195 | IPC_GLB_GET_PPL_CONTEXT_SIZE = 21, |
191 | IPC_GLB_SAVE_PPL = 22, | 196 | IPC_GLB_SAVE_PPL = 22, |
192 | IPC_GLB_RESTORE_PPL = 23, | 197 | IPC_GLB_RESTORE_PPL = 23, |
198 | IPC_GLB_LOAD_LIBRARY = 24, | ||
193 | IPC_GLB_NOTIFY = 26, | 199 | IPC_GLB_NOTIFY = 26, |
194 | IPC_GLB_MAX_IPC_MSG_NUMBER = 31 /* Maximum message number */ | 200 | IPC_GLB_MAX_IPC_MSG_NUMBER = 31 /* Maximum message number */ |
195 | }; | 201 | }; |
@@ -338,7 +344,7 @@ static int skl_ipc_process_notification(struct sst_generic_ipc *ipc, | |||
338 | break; | 344 | break; |
339 | 345 | ||
340 | default: | 346 | default: |
341 | dev_err(ipc->dev, "ipc: Unhandled error msg=%x", | 347 | dev_err(ipc->dev, "ipc: Unhandled error msg=%x\n", |
342 | header.primary); | 348 | header.primary); |
343 | break; | 349 | break; |
344 | } | 350 | } |
@@ -379,13 +385,13 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc, | |||
379 | break; | 385 | break; |
380 | 386 | ||
381 | default: | 387 | default: |
382 | dev_err(ipc->dev, "Unknown ipc reply: 0x%x", reply); | 388 | dev_err(ipc->dev, "Unknown ipc reply: 0x%x\n", reply); |
383 | msg->errno = -EINVAL; | 389 | msg->errno = -EINVAL; |
384 | break; | 390 | break; |
385 | } | 391 | } |
386 | 392 | ||
387 | if (reply != IPC_GLB_REPLY_SUCCESS) { | 393 | if (reply != IPC_GLB_REPLY_SUCCESS) { |
388 | dev_err(ipc->dev, "ipc FW reply: reply=%d", reply); | 394 | dev_err(ipc->dev, "ipc FW reply: reply=%d\n", reply); |
389 | dev_err(ipc->dev, "FW Error Code: %u\n", | 395 | dev_err(ipc->dev, "FW Error Code: %u\n", |
390 | ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp)); | 396 | ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp)); |
391 | } | 397 | } |
@@ -434,9 +440,9 @@ irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context) | |||
434 | hipcte = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCTE); | 440 | hipcte = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCTE); |
435 | header.primary = hipct; | 441 | header.primary = hipct; |
436 | header.extension = hipcte; | 442 | header.extension = hipcte; |
437 | dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x", | 443 | dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x\n", |
438 | header.primary); | 444 | header.primary); |
439 | dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x", | 445 | dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x\n", |
440 | header.extension); | 446 | header.extension); |
441 | 447 | ||
442 | if (IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) { | 448 | if (IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) { |
@@ -704,6 +710,7 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc, | |||
704 | header.extension = IPC_CORE_ID(msg->core_id); | 710 | header.extension = IPC_CORE_ID(msg->core_id); |
705 | header.extension |= IPC_PPL_INSTANCE_ID(msg->ppl_instance_id); | 711 | header.extension |= IPC_PPL_INSTANCE_ID(msg->ppl_instance_id); |
706 | header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size); | 712 | header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size); |
713 | header.extension |= IPC_DOMAIN(msg->domain); | ||
707 | 714 | ||
708 | dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, | 715 | dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, |
709 | header.primary, header.extension); | 716 | header.primary, header.extension); |
@@ -742,7 +749,7 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc, | |||
742 | header.extension); | 749 | header.extension); |
743 | ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); | 750 | ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); |
744 | if (ret < 0) { | 751 | if (ret < 0) { |
745 | dev_err(ipc->dev, "ipc: bind/unbind faileden"); | 752 | dev_err(ipc->dev, "ipc: bind/unbind failed\n"); |
746 | return ret; | 753 | return ret; |
747 | } | 754 | } |
748 | 755 | ||
@@ -902,3 +909,25 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, | |||
902 | return ret; | 909 | return ret; |
903 | } | 910 | } |
904 | EXPORT_SYMBOL_GPL(skl_ipc_get_large_config); | 911 | EXPORT_SYMBOL_GPL(skl_ipc_get_large_config); |
912 | |||
913 | int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, | ||
914 | u8 dma_id, u8 table_id) | ||
915 | { | ||
916 | struct skl_ipc_header header = {0}; | ||
917 | u64 *ipc_header = (u64 *)(&header); | ||
918 | int ret = 0; | ||
919 | |||
920 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); | ||
921 | header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST); | ||
922 | header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY); | ||
923 | header.primary |= IPC_MOD_INSTANCE_ID(table_id); | ||
924 | header.primary |= IPC_MOD_ID(dma_id); | ||
925 | |||
926 | ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); | ||
927 | |||
928 | if (ret < 0) | ||
929 | dev_err(ipc->dev, "ipc: load lib failed\n"); | ||
930 | |||
931 | return ret; | ||
932 | } | ||
933 | EXPORT_SYMBOL_GPL(skl_sst_ipc_load_library); | ||
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h index 2e3d4e80ef97..0334ed4af031 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.h +++ b/sound/soc/intel/skylake/skl-sst-ipc.h | |||
@@ -66,7 +66,7 @@ struct skl_sst { | |||
66 | 66 | ||
67 | /* callback for miscbdge */ | 67 | /* callback for miscbdge */ |
68 | void (*enable_miscbdcge)(struct device *dev, bool enable); | 68 | void (*enable_miscbdcge)(struct device *dev, bool enable); |
69 | /*Is CGCTL.MISCBDCGE disabled*/ | 69 | /* Is CGCTL.MISCBDCGE disabled */ |
70 | bool miscbdcg_disabled; | 70 | bool miscbdcg_disabled; |
71 | 71 | ||
72 | /* Populate module information */ | 72 | /* Populate module information */ |
@@ -75,8 +75,14 @@ struct skl_sst { | |||
75 | /* Is firmware loaded */ | 75 | /* Is firmware loaded */ |
76 | bool fw_loaded; | 76 | bool fw_loaded; |
77 | 77 | ||
78 | /* first boot ? */ | ||
79 | bool is_first_boot; | ||
80 | |||
78 | /* multi-core */ | 81 | /* multi-core */ |
79 | struct skl_dsp_cores cores; | 82 | struct skl_dsp_cores cores; |
83 | |||
84 | /* tplg manifest */ | ||
85 | struct skl_dfw_manifest manifest; | ||
80 | }; | 86 | }; |
81 | 87 | ||
82 | struct skl_ipc_init_instance_msg { | 88 | struct skl_ipc_init_instance_msg { |
@@ -85,6 +91,7 @@ struct skl_ipc_init_instance_msg { | |||
85 | u16 param_data_size; | 91 | u16 param_data_size; |
86 | u8 ppl_instance_id; | 92 | u8 ppl_instance_id; |
87 | u8 core_id; | 93 | u8 core_id; |
94 | u8 domain; | ||
88 | }; | 95 | }; |
89 | 96 | ||
90 | struct skl_ipc_bind_unbind_msg { | 97 | struct skl_ipc_bind_unbind_msg { |
@@ -145,6 +152,9 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, | |||
145 | int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, | 152 | int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, |
146 | struct skl_ipc_large_config_msg *msg, u32 *param); | 153 | struct skl_ipc_large_config_msg *msg, u32 *param); |
147 | 154 | ||
155 | int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, | ||
156 | u8 dma_id, u8 table_id); | ||
157 | |||
148 | void skl_ipc_int_enable(struct sst_dsp *dsp); | 158 | void skl_ipc_int_enable(struct sst_dsp *dsp); |
149 | void skl_ipc_op_int_enable(struct sst_dsp *ctx); | 159 | void skl_ipc_op_int_enable(struct sst_dsp *ctx); |
150 | void skl_ipc_op_int_disable(struct sst_dsp *ctx); | 160 | void skl_ipc_op_int_disable(struct sst_dsp *ctx); |
diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c index ddcb52a51854..8dc03039b311 100644 --- a/sound/soc/intel/skylake/skl-sst-utils.c +++ b/sound/soc/intel/skylake/skl-sst-utils.c | |||
@@ -28,11 +28,6 @@ | |||
28 | /* FW Extended Manifest Header id = $AE1 */ | 28 | /* FW Extended Manifest Header id = $AE1 */ |
29 | #define SKL_EXT_MANIFEST_HEADER_MAGIC 0x31454124 | 29 | #define SKL_EXT_MANIFEST_HEADER_MAGIC 0x31454124 |
30 | 30 | ||
31 | struct skl_dfw_module_mod { | ||
32 | char name[100]; | ||
33 | struct skl_dfw_module skl_dfw_mod; | ||
34 | }; | ||
35 | |||
36 | struct UUID { | 31 | struct UUID { |
37 | u8 id[16]; | 32 | u8 id[16]; |
38 | }; | 33 | }; |
@@ -99,10 +94,15 @@ struct adsp_fw_hdr { | |||
99 | u32 load_offset; | 94 | u32 load_offset; |
100 | } __packed; | 95 | } __packed; |
101 | 96 | ||
97 | #define MAX_INSTANCE_BUFF 2 | ||
98 | |||
102 | struct uuid_module { | 99 | struct uuid_module { |
103 | uuid_le uuid; | 100 | uuid_le uuid; |
104 | int id; | 101 | int id; |
105 | int is_loadable; | 102 | int is_loadable; |
103 | int max_instance; | ||
104 | u64 pvt_id[MAX_INSTANCE_BUFF]; | ||
105 | int *instance_id; | ||
106 | 106 | ||
107 | struct list_head list; | 107 | struct list_head list; |
108 | }; | 108 | }; |
@@ -115,13 +115,13 @@ struct skl_ext_manifest_hdr { | |||
115 | u32 entries; | 115 | u32 entries; |
116 | }; | 116 | }; |
117 | 117 | ||
118 | int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid, | 118 | int snd_skl_get_module_info(struct skl_sst *ctx, |
119 | struct skl_dfw_module *dfw_config) | 119 | struct skl_module_cfg *mconfig) |
120 | { | 120 | { |
121 | struct uuid_module *module; | 121 | struct uuid_module *module; |
122 | uuid_le *uuid_mod; | 122 | uuid_le *uuid_mod; |
123 | 123 | ||
124 | uuid_mod = (uuid_le *)uuid; | 124 | uuid_mod = (uuid_le *)mconfig->guid; |
125 | 125 | ||
126 | if (list_empty(&ctx->uuid_list)) { | 126 | if (list_empty(&ctx->uuid_list)) { |
127 | dev_err(ctx->dev, "Module list is empty\n"); | 127 | dev_err(ctx->dev, "Module list is empty\n"); |
@@ -130,8 +130,8 @@ int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid, | |||
130 | 130 | ||
131 | list_for_each_entry(module, &ctx->uuid_list, list) { | 131 | list_for_each_entry(module, &ctx->uuid_list, list) { |
132 | if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { | 132 | if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { |
133 | dfw_config->module_id = module->id; | 133 | mconfig->id.module_id = module->id; |
134 | dfw_config->is_loadable = module->is_loadable; | 134 | mconfig->is_loadable = module->is_loadable; |
135 | 135 | ||
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
@@ -141,15 +141,154 @@ int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid, | |||
141 | } | 141 | } |
142 | EXPORT_SYMBOL_GPL(snd_skl_get_module_info); | 142 | EXPORT_SYMBOL_GPL(snd_skl_get_module_info); |
143 | 143 | ||
144 | static int skl_get_pvtid_map(struct uuid_module *module, int instance_id) | ||
145 | { | ||
146 | int pvt_id; | ||
147 | |||
148 | for (pvt_id = 0; pvt_id < module->max_instance; pvt_id++) { | ||
149 | if (module->instance_id[pvt_id] == instance_id) | ||
150 | return pvt_id; | ||
151 | } | ||
152 | return -EINVAL; | ||
153 | } | ||
154 | |||
155 | int skl_get_pvt_instance_id_map(struct skl_sst *ctx, | ||
156 | int module_id, int instance_id) | ||
157 | { | ||
158 | struct uuid_module *module; | ||
159 | |||
160 | list_for_each_entry(module, &ctx->uuid_list, list) { | ||
161 | if (module->id == module_id) | ||
162 | return skl_get_pvtid_map(module, instance_id); | ||
163 | } | ||
164 | |||
165 | return -EINVAL; | ||
166 | } | ||
167 | EXPORT_SYMBOL_GPL(skl_get_pvt_instance_id_map); | ||
168 | |||
169 | static inline int skl_getid_32(struct uuid_module *module, u64 *val, | ||
170 | int word1_mask, int word2_mask) | ||
171 | { | ||
172 | int index, max_inst, pvt_id; | ||
173 | u32 mask_val; | ||
174 | |||
175 | max_inst = module->max_instance; | ||
176 | mask_val = (u32)(*val >> word1_mask); | ||
177 | |||
178 | if (mask_val != 0xffffffff) { | ||
179 | index = ffz(mask_val); | ||
180 | pvt_id = index + word1_mask + word2_mask; | ||
181 | if (pvt_id <= (max_inst - 1)) { | ||
182 | *val |= 1 << (index + word1_mask); | ||
183 | return pvt_id; | ||
184 | } | ||
185 | } | ||
186 | |||
187 | return -EINVAL; | ||
188 | } | ||
189 | |||
190 | static inline int skl_pvtid_128(struct uuid_module *module) | ||
191 | { | ||
192 | int j, i, word1_mask, word2_mask = 0, pvt_id; | ||
193 | |||
194 | for (j = 0; j < MAX_INSTANCE_BUFF; j++) { | ||
195 | word1_mask = 0; | ||
196 | |||
197 | for (i = 0; i < 2; i++) { | ||
198 | pvt_id = skl_getid_32(module, &module->pvt_id[j], | ||
199 | word1_mask, word2_mask); | ||
200 | if (pvt_id >= 0) | ||
201 | return pvt_id; | ||
202 | |||
203 | word1_mask += 32; | ||
204 | if ((word1_mask + word2_mask) >= module->max_instance) | ||
205 | return -EINVAL; | ||
206 | } | ||
207 | |||
208 | word2_mask += 64; | ||
209 | if (word2_mask >= module->max_instance) | ||
210 | return -EINVAL; | ||
211 | } | ||
212 | |||
213 | return -EINVAL; | ||
214 | } | ||
215 | |||
216 | /** | ||
217 | * skl_get_pvt_id: generate a private id for use as module id | ||
218 | * | ||
219 | * @ctx: driver context | ||
220 | * @mconfig: module configuration data | ||
221 | * | ||
222 | * This generates a 128 bit private unique id for a module TYPE so that | ||
223 | * module instance is unique | ||
224 | */ | ||
225 | int skl_get_pvt_id(struct skl_sst *ctx, struct skl_module_cfg *mconfig) | ||
226 | { | ||
227 | struct uuid_module *module; | ||
228 | uuid_le *uuid_mod; | ||
229 | int pvt_id; | ||
230 | |||
231 | uuid_mod = (uuid_le *)mconfig->guid; | ||
232 | |||
233 | list_for_each_entry(module, &ctx->uuid_list, list) { | ||
234 | if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { | ||
235 | |||
236 | pvt_id = skl_pvtid_128(module); | ||
237 | if (pvt_id >= 0) { | ||
238 | module->instance_id[pvt_id] = | ||
239 | mconfig->id.instance_id; | ||
240 | return pvt_id; | ||
241 | } | ||
242 | } | ||
243 | } | ||
244 | |||
245 | return -EINVAL; | ||
246 | } | ||
247 | EXPORT_SYMBOL_GPL(skl_get_pvt_id); | ||
248 | |||
249 | /** | ||
250 | * skl_put_pvt_id: free up the private id allocated | ||
251 | * | ||
252 | * @ctx: driver context | ||
253 | * @mconfig: module configuration data | ||
254 | * | ||
255 | * This frees a 128 bit private unique id previously generated | ||
256 | */ | ||
257 | int skl_put_pvt_id(struct skl_sst *ctx, struct skl_module_cfg *mconfig) | ||
258 | { | ||
259 | int i; | ||
260 | uuid_le *uuid_mod; | ||
261 | struct uuid_module *module; | ||
262 | |||
263 | uuid_mod = (uuid_le *)mconfig->guid; | ||
264 | list_for_each_entry(module, &ctx->uuid_list, list) { | ||
265 | if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { | ||
266 | |||
267 | if (mconfig->id.pvt_id != 0) | ||
268 | i = (mconfig->id.pvt_id) / 64; | ||
269 | else | ||
270 | i = 0; | ||
271 | |||
272 | module->pvt_id[i] &= ~(1 << (mconfig->id.pvt_id)); | ||
273 | mconfig->id.pvt_id = -1; | ||
274 | return 0; | ||
275 | } | ||
276 | } | ||
277 | |||
278 | return -EINVAL; | ||
279 | } | ||
280 | EXPORT_SYMBOL_GPL(skl_put_pvt_id); | ||
281 | |||
144 | /* | 282 | /* |
145 | * Parse the firmware binary to get the UUID, module id | 283 | * Parse the firmware binary to get the UUID, module id |
146 | * and loadable flags | 284 | * and loadable flags |
147 | */ | 285 | */ |
148 | int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset) | 286 | int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw, |
287 | unsigned int offset, int index) | ||
149 | { | 288 | { |
150 | struct adsp_fw_hdr *adsp_hdr; | 289 | struct adsp_fw_hdr *adsp_hdr; |
151 | struct adsp_module_entry *mod_entry; | 290 | struct adsp_module_entry *mod_entry; |
152 | int i, num_entry; | 291 | int i, num_entry, size; |
153 | uuid_le *uuid_bin; | 292 | uuid_le *uuid_bin; |
154 | const char *buf; | 293 | const char *buf; |
155 | struct skl_sst *skl = ctx->thread_context; | 294 | struct skl_sst *skl = ctx->thread_context; |
@@ -158,8 +297,8 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset) | |||
158 | unsigned int safe_file; | 297 | unsigned int safe_file; |
159 | 298 | ||
160 | /* Get the FW pointer to derive ADSP header */ | 299 | /* Get the FW pointer to derive ADSP header */ |
161 | stripped_fw.data = ctx->fw->data; | 300 | stripped_fw.data = fw->data; |
162 | stripped_fw.size = ctx->fw->size; | 301 | stripped_fw.size = fw->size; |
163 | 302 | ||
164 | skl_dsp_strip_extended_manifest(&stripped_fw); | 303 | skl_dsp_strip_extended_manifest(&stripped_fw); |
165 | 304 | ||
@@ -210,8 +349,15 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset) | |||
210 | uuid_bin = (uuid_le *)mod_entry->uuid.id; | 349 | uuid_bin = (uuid_le *)mod_entry->uuid.id; |
211 | memcpy(&module->uuid, uuid_bin, sizeof(module->uuid)); | 350 | memcpy(&module->uuid, uuid_bin, sizeof(module->uuid)); |
212 | 351 | ||
213 | module->id = i; | 352 | module->id = (i | (index << 12)); |
214 | module->is_loadable = mod_entry->type.load_type; | 353 | module->is_loadable = mod_entry->type.load_type; |
354 | module->max_instance = mod_entry->instance_max_count; | ||
355 | size = sizeof(int) * mod_entry->instance_max_count; | ||
356 | module->instance_id = devm_kzalloc(ctx->dev, size, GFP_KERNEL); | ||
357 | if (!module->instance_id) { | ||
358 | kfree(module); | ||
359 | return -ENOMEM; | ||
360 | } | ||
215 | 361 | ||
216 | list_add_tail(&module->list, &skl->uuid_list); | 362 | list_add_tail(&module->list, &skl->uuid_list); |
217 | 363 | ||
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c index 588f899ceb65..8fc3178bc79c 100644 --- a/sound/soc/intel/skylake/skl-sst.c +++ b/sound/soc/intel/skylake/skl-sst.c | |||
@@ -88,13 +88,15 @@ static int skl_load_base_firmware(struct sst_dsp *ctx) | |||
88 | } | 88 | } |
89 | } | 89 | } |
90 | 90 | ||
91 | ret = snd_skl_parse_uuids(ctx, SKL_ADSP_FW_BIN_HDR_OFFSET); | 91 | /* prase uuids on first boot */ |
92 | if (ret < 0) { | 92 | if (skl->is_first_boot) { |
93 | dev_err(ctx->dev, | 93 | ret = snd_skl_parse_uuids(ctx, ctx->fw, SKL_ADSP_FW_BIN_HDR_OFFSET, 0); |
94 | "UUID parsing err: %d\n", ret); | 94 | if (ret < 0) { |
95 | release_firmware(ctx->fw); | 95 | dev_err(ctx->dev, "UUID parsing err: %d\n", ret); |
96 | skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); | 96 | release_firmware(ctx->fw); |
97 | return ret; | 97 | skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); |
98 | return ret; | ||
99 | } | ||
98 | } | 100 | } |
99 | 101 | ||
100 | /* check for extended manifest */ | 102 | /* check for extended manifest */ |
@@ -105,13 +107,13 @@ static int skl_load_base_firmware(struct sst_dsp *ctx) | |||
105 | 107 | ||
106 | ret = skl_dsp_boot(ctx); | 108 | ret = skl_dsp_boot(ctx); |
107 | if (ret < 0) { | 109 | if (ret < 0) { |
108 | dev_err(ctx->dev, "Boot dsp core failed ret: %d", ret); | 110 | dev_err(ctx->dev, "Boot dsp core failed ret: %d\n", ret); |
109 | goto skl_load_base_firmware_failed; | 111 | goto skl_load_base_firmware_failed; |
110 | } | 112 | } |
111 | 113 | ||
112 | ret = skl_cldma_prepare(ctx); | 114 | ret = skl_cldma_prepare(ctx); |
113 | if (ret < 0) { | 115 | if (ret < 0) { |
114 | dev_err(ctx->dev, "CL dma prepare failed : %d", ret); | 116 | dev_err(ctx->dev, "CL dma prepare failed : %d\n", ret); |
115 | goto skl_load_base_firmware_failed; | 117 | goto skl_load_base_firmware_failed; |
116 | } | 118 | } |
117 | 119 | ||
@@ -484,25 +486,32 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | |||
484 | return ret; | 486 | return ret; |
485 | 487 | ||
486 | skl->cores.count = 2; | 488 | skl->cores.count = 2; |
489 | skl->is_first_boot = true; | ||
490 | |||
491 | if (dsp) | ||
492 | *dsp = skl; | ||
493 | |||
494 | return ret; | ||
495 | } | ||
496 | EXPORT_SYMBOL_GPL(skl_sst_dsp_init); | ||
497 | |||
498 | int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx) | ||
499 | { | ||
500 | int ret; | ||
501 | struct sst_dsp *sst = ctx->dsp; | ||
487 | 502 | ||
488 | ret = sst->fw_ops.load_fw(sst); | 503 | ret = sst->fw_ops.load_fw(sst); |
489 | if (ret < 0) { | 504 | if (ret < 0) { |
490 | dev_err(dev, "Load base fw failed : %d", ret); | 505 | dev_err(dev, "Load base fw failed : %d\n", ret); |
491 | goto cleanup; | 506 | return ret; |
492 | } | 507 | } |
493 | 508 | ||
494 | skl_dsp_init_core_state(sst); | 509 | skl_dsp_init_core_state(sst); |
510 | ctx->is_first_boot = false; | ||
495 | 511 | ||
496 | if (dsp) | 512 | return 0; |
497 | *dsp = skl; | ||
498 | |||
499 | return ret; | ||
500 | |||
501 | cleanup: | ||
502 | skl_sst_dsp_cleanup(dev, skl); | ||
503 | return ret; | ||
504 | } | 513 | } |
505 | EXPORT_SYMBOL_GPL(skl_sst_dsp_init); | 514 | EXPORT_SYMBOL_GPL(skl_sst_init_fw); |
506 | 515 | ||
507 | void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) | 516 | void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) |
508 | { | 517 | { |
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index cc0150fc2601..b5b1934d8550 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/firmware.h> | 21 | #include <linux/firmware.h> |
22 | #include <sound/soc.h> | 22 | #include <sound/soc.h> |
23 | #include <sound/soc-topology.h> | 23 | #include <sound/soc-topology.h> |
24 | #include <uapi/sound/snd_sst_tokens.h> | ||
24 | #include "skl-sst-dsp.h" | 25 | #include "skl-sst-dsp.h" |
25 | #include "skl-sst-ipc.h" | 26 | #include "skl-sst-ipc.h" |
26 | #include "skl-topology.h" | 27 | #include "skl-topology.h" |
@@ -32,6 +33,8 @@ | |||
32 | #define SKL_CH_FIXUP_MASK (1 << 0) | 33 | #define SKL_CH_FIXUP_MASK (1 << 0) |
33 | #define SKL_RATE_FIXUP_MASK (1 << 1) | 34 | #define SKL_RATE_FIXUP_MASK (1 << 1) |
34 | #define SKL_FMT_FIXUP_MASK (1 << 2) | 35 | #define SKL_FMT_FIXUP_MASK (1 << 2) |
36 | #define SKL_IN_DIR_BIT_MASK BIT(0) | ||
37 | #define SKL_PIN_COUNT_MASK GENMASK(7, 4) | ||
35 | 38 | ||
36 | /* | 39 | /* |
37 | * SKL DSP driver modelling uses only few DAPM widgets so for rest we will | 40 | * SKL DSP driver modelling uses only few DAPM widgets so for rest we will |
@@ -473,6 +476,14 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) | |||
473 | w = w_module->w; | 476 | w = w_module->w; |
474 | mconfig = w->priv; | 477 | mconfig = w->priv; |
475 | 478 | ||
479 | /* check if module ids are populated */ | ||
480 | if (mconfig->id.module_id < 0) { | ||
481 | dev_err(skl->skl_sst->dev, | ||
482 | "module %pUL id not populated\n", | ||
483 | (uuid_le *)mconfig->guid); | ||
484 | return -EIO; | ||
485 | } | ||
486 | |||
476 | /* check resource available */ | 487 | /* check resource available */ |
477 | if (!skl_is_pipe_mcps_avail(skl, mconfig)) | 488 | if (!skl_is_pipe_mcps_avail(skl, mconfig)) |
478 | return -ENOMEM; | 489 | return -ENOMEM; |
@@ -494,12 +505,15 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) | |||
494 | * FE/BE params | 505 | * FE/BE params |
495 | */ | 506 | */ |
496 | skl_tplg_update_module_params(w, ctx); | 507 | skl_tplg_update_module_params(w, ctx); |
497 | 508 | mconfig->id.pvt_id = skl_get_pvt_id(ctx, mconfig); | |
509 | if (mconfig->id.pvt_id < 0) | ||
510 | return ret; | ||
498 | skl_tplg_set_module_init_data(w); | 511 | skl_tplg_set_module_init_data(w); |
499 | ret = skl_init_module(ctx, mconfig); | 512 | ret = skl_init_module(ctx, mconfig); |
500 | if (ret < 0) | 513 | if (ret < 0) { |
514 | skl_put_pvt_id(ctx, mconfig); | ||
501 | return ret; | 515 | return ret; |
502 | 516 | } | |
503 | skl_tplg_alloc_pipe_mcps(skl, mconfig); | 517 | skl_tplg_alloc_pipe_mcps(skl, mconfig); |
504 | ret = skl_tplg_set_module_params(w, ctx); | 518 | ret = skl_tplg_set_module_params(w, ctx); |
505 | if (ret < 0) | 519 | if (ret < 0) |
@@ -512,6 +526,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) | |||
512 | static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, | 526 | static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, |
513 | struct skl_pipe *pipe) | 527 | struct skl_pipe *pipe) |
514 | { | 528 | { |
529 | int ret; | ||
515 | struct skl_pipe_module *w_module = NULL; | 530 | struct skl_pipe_module *w_module = NULL; |
516 | struct skl_module_cfg *mconfig = NULL; | 531 | struct skl_module_cfg *mconfig = NULL; |
517 | 532 | ||
@@ -519,9 +534,13 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, | |||
519 | mconfig = w_module->w->priv; | 534 | mconfig = w_module->w->priv; |
520 | 535 | ||
521 | if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod && | 536 | if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod && |
522 | mconfig->m_state > SKL_MODULE_UNINIT) | 537 | mconfig->m_state > SKL_MODULE_UNINIT) { |
523 | return ctx->dsp->fw_ops.unload_mod(ctx->dsp, | 538 | ret = ctx->dsp->fw_ops.unload_mod(ctx->dsp, |
524 | mconfig->id.module_id); | 539 | mconfig->id.module_id); |
540 | if (ret < 0) | ||
541 | return -EIO; | ||
542 | } | ||
543 | skl_put_pvt_id(ctx, mconfig); | ||
525 | } | 544 | } |
526 | 545 | ||
527 | /* no modules to unload in this path, so return */ | 546 | /* no modules to unload in this path, so return */ |
@@ -588,6 +607,26 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, | |||
588 | return 0; | 607 | return 0; |
589 | } | 608 | } |
590 | 609 | ||
610 | static int skl_fill_sink_instance_id(struct skl_sst *ctx, | ||
611 | struct skl_algo_data *alg_data) | ||
612 | { | ||
613 | struct skl_kpb_params *params = (struct skl_kpb_params *)alg_data->params; | ||
614 | struct skl_mod_inst_map *inst; | ||
615 | int i, pvt_id; | ||
616 | |||
617 | inst = params->map; | ||
618 | |||
619 | for (i = 0; i < params->num_modules; i++) { | ||
620 | pvt_id = skl_get_pvt_instance_id_map(ctx, | ||
621 | inst->mod_id, inst->inst_id); | ||
622 | if (pvt_id < 0) | ||
623 | return -EINVAL; | ||
624 | inst->inst_id = pvt_id; | ||
625 | inst++; | ||
626 | } | ||
627 | return 0; | ||
628 | } | ||
629 | |||
591 | /* | 630 | /* |
592 | * Some modules require params to be set after the module is bound to | 631 | * Some modules require params to be set after the module is bound to |
593 | * all pins connected. | 632 | * all pins connected. |
@@ -636,6 +675,8 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w, | |||
636 | bc = (struct skl_algo_data *)sb->dobj.private; | 675 | bc = (struct skl_algo_data *)sb->dobj.private; |
637 | 676 | ||
638 | if (bc->set_params == SKL_PARAM_BIND) { | 677 | if (bc->set_params == SKL_PARAM_BIND) { |
678 | if (mconfig->m_type == SKL_MODULE_TYPE_KPB) | ||
679 | skl_fill_sink_instance_id(ctx, bc); | ||
639 | ret = skl_set_module_params(ctx, | 680 | ret = skl_set_module_params(ctx, |
640 | (u32 *)bc->params, bc->max, | 681 | (u32 *)bc->params, bc->max, |
641 | bc->param_id, mconfig); | 682 | bc->param_id, mconfig); |
@@ -1460,85 +1501,570 @@ static const struct snd_soc_tplg_bytes_ext_ops skl_tlv_ops[] = { | |||
1460 | skl_tplg_tlv_control_set}, | 1501 | skl_tplg_tlv_control_set}, |
1461 | }; | 1502 | }; |
1462 | 1503 | ||
1463 | /* | 1504 | static int skl_tplg_fill_pipe_tkn(struct device *dev, |
1464 | * The topology binary passes the pin info for a module so initialize the pin | 1505 | struct skl_pipe *pipe, u32 tkn, |
1465 | * info passed into module instance | 1506 | u32 tkn_val) |
1466 | */ | ||
1467 | static void skl_fill_module_pin_info(struct skl_dfw_module_pin *dfw_pin, | ||
1468 | struct skl_module_pin *m_pin, | ||
1469 | bool is_dynamic, int max_pin) | ||
1470 | { | 1507 | { |
1471 | int i; | ||
1472 | 1508 | ||
1473 | for (i = 0; i < max_pin; i++) { | 1509 | switch (tkn) { |
1474 | m_pin[i].id.module_id = dfw_pin[i].module_id; | 1510 | case SKL_TKN_U32_PIPE_CONN_TYPE: |
1475 | m_pin[i].id.instance_id = dfw_pin[i].instance_id; | 1511 | pipe->conn_type = tkn_val; |
1476 | m_pin[i].in_use = false; | 1512 | break; |
1477 | m_pin[i].is_dynamic = is_dynamic; | 1513 | |
1478 | m_pin[i].pin_state = SKL_PIN_UNBIND; | 1514 | case SKL_TKN_U32_PIPE_PRIORITY: |
1515 | pipe->pipe_priority = tkn_val; | ||
1516 | break; | ||
1517 | |||
1518 | case SKL_TKN_U32_PIPE_MEM_PGS: | ||
1519 | pipe->memory_pages = tkn_val; | ||
1520 | break; | ||
1521 | |||
1522 | default: | ||
1523 | dev_err(dev, "Token not handled %d\n", tkn); | ||
1524 | return -EINVAL; | ||
1479 | } | 1525 | } |
1526 | |||
1527 | return 0; | ||
1480 | } | 1528 | } |
1481 | 1529 | ||
1482 | /* | 1530 | /* |
1483 | * Add pipeline from topology binary into driver pipeline list | 1531 | * Add pipeline by parsing the relevant tokens |
1484 | * | 1532 | * Return an existing pipe if the pipe already exists. |
1485 | * If already added we return that instance | ||
1486 | * Otherwise we create a new instance and add into driver list | ||
1487 | */ | 1533 | */ |
1488 | static struct skl_pipe *skl_tplg_add_pipe(struct device *dev, | 1534 | static int skl_tplg_add_pipe(struct device *dev, |
1489 | struct skl *skl, struct skl_dfw_pipe *dfw_pipe) | 1535 | struct skl_module_cfg *mconfig, struct skl *skl, |
1536 | struct snd_soc_tplg_vendor_value_elem *tkn_elem) | ||
1490 | { | 1537 | { |
1491 | struct skl_pipeline *ppl; | 1538 | struct skl_pipeline *ppl; |
1492 | struct skl_pipe *pipe; | 1539 | struct skl_pipe *pipe; |
1493 | struct skl_pipe_params *params; | 1540 | struct skl_pipe_params *params; |
1494 | 1541 | ||
1495 | list_for_each_entry(ppl, &skl->ppl_list, node) { | 1542 | list_for_each_entry(ppl, &skl->ppl_list, node) { |
1496 | if (ppl->pipe->ppl_id == dfw_pipe->pipe_id) | 1543 | if (ppl->pipe->ppl_id == tkn_elem->value) { |
1497 | return ppl->pipe; | 1544 | mconfig->pipe = ppl->pipe; |
1545 | return EEXIST; | ||
1546 | } | ||
1498 | } | 1547 | } |
1499 | 1548 | ||
1500 | ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL); | 1549 | ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL); |
1501 | if (!ppl) | 1550 | if (!ppl) |
1502 | return NULL; | 1551 | return -ENOMEM; |
1503 | 1552 | ||
1504 | pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL); | 1553 | pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL); |
1505 | if (!pipe) | 1554 | if (!pipe) |
1506 | return NULL; | 1555 | return -ENOMEM; |
1507 | 1556 | ||
1508 | params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL); | 1557 | params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL); |
1509 | if (!params) | 1558 | if (!params) |
1510 | return NULL; | 1559 | return -ENOMEM; |
1511 | 1560 | ||
1512 | pipe->ppl_id = dfw_pipe->pipe_id; | ||
1513 | pipe->memory_pages = dfw_pipe->memory_pages; | ||
1514 | pipe->pipe_priority = dfw_pipe->pipe_priority; | ||
1515 | pipe->conn_type = dfw_pipe->conn_type; | ||
1516 | pipe->state = SKL_PIPE_INVALID; | ||
1517 | pipe->p_params = params; | 1561 | pipe->p_params = params; |
1562 | pipe->ppl_id = tkn_elem->value; | ||
1518 | INIT_LIST_HEAD(&pipe->w_list); | 1563 | INIT_LIST_HEAD(&pipe->w_list); |
1519 | 1564 | ||
1520 | ppl->pipe = pipe; | 1565 | ppl->pipe = pipe; |
1521 | list_add(&ppl->node, &skl->ppl_list); | 1566 | list_add(&ppl->node, &skl->ppl_list); |
1522 | 1567 | ||
1523 | return ppl->pipe; | 1568 | mconfig->pipe = pipe; |
1569 | mconfig->pipe->state = SKL_PIPE_INVALID; | ||
1570 | |||
1571 | return 0; | ||
1572 | } | ||
1573 | |||
1574 | static int skl_tplg_fill_pin(struct device *dev, u32 tkn, | ||
1575 | struct skl_module_pin *m_pin, | ||
1576 | int pin_index, u32 value) | ||
1577 | { | ||
1578 | switch (tkn) { | ||
1579 | case SKL_TKN_U32_PIN_MOD_ID: | ||
1580 | m_pin[pin_index].id.module_id = value; | ||
1581 | break; | ||
1582 | |||
1583 | case SKL_TKN_U32_PIN_INST_ID: | ||
1584 | m_pin[pin_index].id.instance_id = value; | ||
1585 | break; | ||
1586 | |||
1587 | default: | ||
1588 | dev_err(dev, "%d Not a pin token\n", value); | ||
1589 | return -EINVAL; | ||
1590 | } | ||
1591 | |||
1592 | return 0; | ||
1593 | } | ||
1594 | |||
1595 | /* | ||
1596 | * Parse for pin config specific tokens to fill up the | ||
1597 | * module private data | ||
1598 | */ | ||
1599 | static int skl_tplg_fill_pins_info(struct device *dev, | ||
1600 | struct skl_module_cfg *mconfig, | ||
1601 | struct snd_soc_tplg_vendor_value_elem *tkn_elem, | ||
1602 | int dir, int pin_count) | ||
1603 | { | ||
1604 | int ret; | ||
1605 | struct skl_module_pin *m_pin; | ||
1606 | |||
1607 | switch (dir) { | ||
1608 | case SKL_DIR_IN: | ||
1609 | m_pin = mconfig->m_in_pin; | ||
1610 | break; | ||
1611 | |||
1612 | case SKL_DIR_OUT: | ||
1613 | m_pin = mconfig->m_out_pin; | ||
1614 | break; | ||
1615 | |||
1616 | default: | ||
1617 | dev_err(dev, "Invalid direction value\n"); | ||
1618 | return -EINVAL; | ||
1619 | } | ||
1620 | |||
1621 | ret = skl_tplg_fill_pin(dev, tkn_elem->token, | ||
1622 | m_pin, pin_count, tkn_elem->value); | ||
1623 | |||
1624 | if (ret < 0) | ||
1625 | return ret; | ||
1626 | |||
1627 | m_pin[pin_count].in_use = false; | ||
1628 | m_pin[pin_count].pin_state = SKL_PIN_UNBIND; | ||
1629 | |||
1630 | return 0; | ||
1631 | } | ||
1632 | |||
1633 | /* | ||
1634 | * Fill up input/output module config format based | ||
1635 | * on the direction | ||
1636 | */ | ||
1637 | static int skl_tplg_fill_fmt(struct device *dev, | ||
1638 | struct skl_module_cfg *mconfig, u32 tkn, | ||
1639 | u32 value, u32 dir, u32 pin_count) | ||
1640 | { | ||
1641 | struct skl_module_fmt *dst_fmt; | ||
1642 | |||
1643 | switch (dir) { | ||
1644 | case SKL_DIR_IN: | ||
1645 | dst_fmt = mconfig->in_fmt; | ||
1646 | dst_fmt += pin_count; | ||
1647 | break; | ||
1648 | |||
1649 | case SKL_DIR_OUT: | ||
1650 | dst_fmt = mconfig->out_fmt; | ||
1651 | dst_fmt += pin_count; | ||
1652 | break; | ||
1653 | |||
1654 | default: | ||
1655 | dev_err(dev, "Invalid direction value\n"); | ||
1656 | return -EINVAL; | ||
1657 | } | ||
1658 | |||
1659 | switch (tkn) { | ||
1660 | case SKL_TKN_U32_FMT_CH: | ||
1661 | dst_fmt->channels = value; | ||
1662 | break; | ||
1663 | |||
1664 | case SKL_TKN_U32_FMT_FREQ: | ||
1665 | dst_fmt->s_freq = value; | ||
1666 | break; | ||
1667 | |||
1668 | case SKL_TKN_U32_FMT_BIT_DEPTH: | ||
1669 | dst_fmt->bit_depth = value; | ||
1670 | break; | ||
1671 | |||
1672 | case SKL_TKN_U32_FMT_SAMPLE_SIZE: | ||
1673 | dst_fmt->valid_bit_depth = value; | ||
1674 | break; | ||
1675 | |||
1676 | case SKL_TKN_U32_FMT_CH_CONFIG: | ||
1677 | dst_fmt->ch_cfg = value; | ||
1678 | break; | ||
1679 | |||
1680 | case SKL_TKN_U32_FMT_INTERLEAVE: | ||
1681 | dst_fmt->interleaving_style = value; | ||
1682 | break; | ||
1683 | |||
1684 | case SKL_TKN_U32_FMT_SAMPLE_TYPE: | ||
1685 | dst_fmt->sample_type = value; | ||
1686 | break; | ||
1687 | |||
1688 | case SKL_TKN_U32_FMT_CH_MAP: | ||
1689 | dst_fmt->ch_map = value; | ||
1690 | break; | ||
1691 | |||
1692 | default: | ||
1693 | dev_err(dev, "Invalid token %d\n", tkn); | ||
1694 | return -EINVAL; | ||
1695 | } | ||
1696 | |||
1697 | return 0; | ||
1524 | } | 1698 | } |
1525 | 1699 | ||
1526 | static void skl_tplg_fill_fmt(struct skl_module_fmt *dst_fmt, | 1700 | static int skl_tplg_get_uuid(struct device *dev, struct skl_module_cfg *mconfig, |
1527 | struct skl_dfw_module_fmt *src_fmt, | 1701 | struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn) |
1528 | int pins) | 1702 | { |
1703 | if (uuid_tkn->token == SKL_TKN_UUID) | ||
1704 | memcpy(&mconfig->guid, &uuid_tkn->uuid, 16); | ||
1705 | else { | ||
1706 | dev_err(dev, "Not an UUID token tkn %d\n", uuid_tkn->token); | ||
1707 | return -EINVAL; | ||
1708 | } | ||
1709 | |||
1710 | return 0; | ||
1711 | } | ||
1712 | |||
1713 | static void skl_tplg_fill_pin_dynamic_val( | ||
1714 | struct skl_module_pin *mpin, u32 pin_count, u32 value) | ||
1529 | { | 1715 | { |
1530 | int i; | 1716 | int i; |
1531 | 1717 | ||
1532 | for (i = 0; i < pins; i++) { | 1718 | for (i = 0; i < pin_count; i++) |
1533 | dst_fmt[i].channels = src_fmt[i].channels; | 1719 | mpin[i].is_dynamic = value; |
1534 | dst_fmt[i].s_freq = src_fmt[i].freq; | 1720 | } |
1535 | dst_fmt[i].bit_depth = src_fmt[i].bit_depth; | 1721 | |
1536 | dst_fmt[i].valid_bit_depth = src_fmt[i].valid_bit_depth; | 1722 | /* |
1537 | dst_fmt[i].ch_cfg = src_fmt[i].ch_cfg; | 1723 | * Parse tokens to fill up the module private data |
1538 | dst_fmt[i].ch_map = src_fmt[i].ch_map; | 1724 | */ |
1539 | dst_fmt[i].interleaving_style = src_fmt[i].interleaving_style; | 1725 | static int skl_tplg_get_token(struct device *dev, |
1540 | dst_fmt[i].sample_type = src_fmt[i].sample_type; | 1726 | struct snd_soc_tplg_vendor_value_elem *tkn_elem, |
1727 | struct skl *skl, struct skl_module_cfg *mconfig) | ||
1728 | { | ||
1729 | int tkn_count = 0; | ||
1730 | int ret; | ||
1731 | static int is_pipe_exists; | ||
1732 | static int pin_index, dir; | ||
1733 | |||
1734 | if (tkn_elem->token > SKL_TKN_MAX) | ||
1735 | return -EINVAL; | ||
1736 | |||
1737 | switch (tkn_elem->token) { | ||
1738 | case SKL_TKN_U8_IN_QUEUE_COUNT: | ||
1739 | mconfig->max_in_queue = tkn_elem->value; | ||
1740 | mconfig->m_in_pin = devm_kzalloc(dev, mconfig->max_in_queue * | ||
1741 | sizeof(*mconfig->m_in_pin), | ||
1742 | GFP_KERNEL); | ||
1743 | if (!mconfig->m_in_pin) | ||
1744 | return -ENOMEM; | ||
1745 | |||
1746 | break; | ||
1747 | |||
1748 | case SKL_TKN_U8_OUT_QUEUE_COUNT: | ||
1749 | mconfig->max_out_queue = tkn_elem->value; | ||
1750 | mconfig->m_out_pin = devm_kzalloc(dev, mconfig->max_out_queue * | ||
1751 | sizeof(*mconfig->m_out_pin), | ||
1752 | GFP_KERNEL); | ||
1753 | |||
1754 | if (!mconfig->m_out_pin) | ||
1755 | return -ENOMEM; | ||
1756 | |||
1757 | break; | ||
1758 | |||
1759 | case SKL_TKN_U8_DYN_IN_PIN: | ||
1760 | if (!mconfig->m_in_pin) | ||
1761 | return -ENOMEM; | ||
1762 | |||
1763 | skl_tplg_fill_pin_dynamic_val(mconfig->m_in_pin, | ||
1764 | mconfig->max_in_queue, tkn_elem->value); | ||
1765 | |||
1766 | break; | ||
1767 | |||
1768 | case SKL_TKN_U8_DYN_OUT_PIN: | ||
1769 | if (!mconfig->m_out_pin) | ||
1770 | return -ENOMEM; | ||
1771 | |||
1772 | skl_tplg_fill_pin_dynamic_val(mconfig->m_out_pin, | ||
1773 | mconfig->max_out_queue, tkn_elem->value); | ||
1774 | |||
1775 | break; | ||
1776 | |||
1777 | case SKL_TKN_U8_TIME_SLOT: | ||
1778 | mconfig->time_slot = tkn_elem->value; | ||
1779 | break; | ||
1780 | |||
1781 | case SKL_TKN_U8_CORE_ID: | ||
1782 | mconfig->core_id = tkn_elem->value; | ||
1783 | |||
1784 | case SKL_TKN_U8_MOD_TYPE: | ||
1785 | mconfig->m_type = tkn_elem->value; | ||
1786 | break; | ||
1787 | |||
1788 | case SKL_TKN_U8_DEV_TYPE: | ||
1789 | mconfig->dev_type = tkn_elem->value; | ||
1790 | break; | ||
1791 | |||
1792 | case SKL_TKN_U8_HW_CONN_TYPE: | ||
1793 | mconfig->hw_conn_type = tkn_elem->value; | ||
1794 | break; | ||
1795 | |||
1796 | case SKL_TKN_U16_MOD_INST_ID: | ||
1797 | mconfig->id.instance_id = | ||
1798 | tkn_elem->value; | ||
1799 | break; | ||
1800 | |||
1801 | case SKL_TKN_U32_MEM_PAGES: | ||
1802 | mconfig->mem_pages = tkn_elem->value; | ||
1803 | break; | ||
1804 | |||
1805 | case SKL_TKN_U32_MAX_MCPS: | ||
1806 | mconfig->mcps = tkn_elem->value; | ||
1807 | break; | ||
1808 | |||
1809 | case SKL_TKN_U32_OBS: | ||
1810 | mconfig->obs = tkn_elem->value; | ||
1811 | break; | ||
1812 | |||
1813 | case SKL_TKN_U32_IBS: | ||
1814 | mconfig->ibs = tkn_elem->value; | ||
1815 | break; | ||
1816 | |||
1817 | case SKL_TKN_U32_VBUS_ID: | ||
1818 | mconfig->vbus_id = tkn_elem->value; | ||
1819 | break; | ||
1820 | |||
1821 | case SKL_TKN_U32_PARAMS_FIXUP: | ||
1822 | mconfig->params_fixup = tkn_elem->value; | ||
1823 | break; | ||
1824 | |||
1825 | case SKL_TKN_U32_CONVERTER: | ||
1826 | mconfig->converter = tkn_elem->value; | ||
1827 | break; | ||
1828 | |||
1829 | case SKL_TKN_U32_PIPE_ID: | ||
1830 | ret = skl_tplg_add_pipe(dev, | ||
1831 | mconfig, skl, tkn_elem); | ||
1832 | |||
1833 | if (ret < 0) | ||
1834 | return is_pipe_exists; | ||
1835 | |||
1836 | if (ret == EEXIST) | ||
1837 | is_pipe_exists = 1; | ||
1838 | |||
1839 | break; | ||
1840 | |||
1841 | case SKL_TKN_U32_PIPE_CONN_TYPE: | ||
1842 | case SKL_TKN_U32_PIPE_PRIORITY: | ||
1843 | case SKL_TKN_U32_PIPE_MEM_PGS: | ||
1844 | if (is_pipe_exists) { | ||
1845 | ret = skl_tplg_fill_pipe_tkn(dev, mconfig->pipe, | ||
1846 | tkn_elem->token, tkn_elem->value); | ||
1847 | if (ret < 0) | ||
1848 | return ret; | ||
1849 | } | ||
1850 | |||
1851 | break; | ||
1852 | |||
1853 | /* | ||
1854 | * SKL_TKN_U32_DIR_PIN_COUNT token has the value for both | ||
1855 | * direction and the pin count. The first four bits represent | ||
1856 | * direction and next four the pin count. | ||
1857 | */ | ||
1858 | case SKL_TKN_U32_DIR_PIN_COUNT: | ||
1859 | dir = tkn_elem->value & SKL_IN_DIR_BIT_MASK; | ||
1860 | pin_index = (tkn_elem->value & | ||
1861 | SKL_PIN_COUNT_MASK) >> 4; | ||
1862 | |||
1863 | break; | ||
1864 | |||
1865 | case SKL_TKN_U32_FMT_CH: | ||
1866 | case SKL_TKN_U32_FMT_FREQ: | ||
1867 | case SKL_TKN_U32_FMT_BIT_DEPTH: | ||
1868 | case SKL_TKN_U32_FMT_SAMPLE_SIZE: | ||
1869 | case SKL_TKN_U32_FMT_CH_CONFIG: | ||
1870 | case SKL_TKN_U32_FMT_INTERLEAVE: | ||
1871 | case SKL_TKN_U32_FMT_SAMPLE_TYPE: | ||
1872 | case SKL_TKN_U32_FMT_CH_MAP: | ||
1873 | ret = skl_tplg_fill_fmt(dev, mconfig, tkn_elem->token, | ||
1874 | tkn_elem->value, dir, pin_index); | ||
1875 | |||
1876 | if (ret < 0) | ||
1877 | return ret; | ||
1878 | |||
1879 | break; | ||
1880 | |||
1881 | case SKL_TKN_U32_PIN_MOD_ID: | ||
1882 | case SKL_TKN_U32_PIN_INST_ID: | ||
1883 | ret = skl_tplg_fill_pins_info(dev, | ||
1884 | mconfig, tkn_elem, dir, | ||
1885 | pin_index); | ||
1886 | if (ret < 0) | ||
1887 | return ret; | ||
1888 | |||
1889 | break; | ||
1890 | |||
1891 | case SKL_TKN_U32_CAPS_SIZE: | ||
1892 | mconfig->formats_config.caps_size = | ||
1893 | tkn_elem->value; | ||
1894 | |||
1895 | break; | ||
1896 | |||
1897 | case SKL_TKN_U32_PROC_DOMAIN: | ||
1898 | mconfig->domain = | ||
1899 | tkn_elem->value; | ||
1900 | |||
1901 | break; | ||
1902 | |||
1903 | case SKL_TKN_U8_IN_PIN_TYPE: | ||
1904 | case SKL_TKN_U8_OUT_PIN_TYPE: | ||
1905 | case SKL_TKN_U8_CONN_TYPE: | ||
1906 | break; | ||
1907 | |||
1908 | default: | ||
1909 | dev_err(dev, "Token %d not handled\n", | ||
1910 | tkn_elem->token); | ||
1911 | return -EINVAL; | ||
1912 | } | ||
1913 | |||
1914 | tkn_count++; | ||
1915 | |||
1916 | return tkn_count; | ||
1917 | } | ||
1918 | |||
1919 | /* | ||
1920 | * Parse the vendor array for specific tokens to construct | ||
1921 | * module private data | ||
1922 | */ | ||
1923 | static int skl_tplg_get_tokens(struct device *dev, | ||
1924 | char *pvt_data, struct skl *skl, | ||
1925 | struct skl_module_cfg *mconfig, int block_size) | ||
1926 | { | ||
1927 | struct snd_soc_tplg_vendor_array *array; | ||
1928 | struct snd_soc_tplg_vendor_value_elem *tkn_elem; | ||
1929 | int tkn_count = 0, ret; | ||
1930 | int off = 0, tuple_size = 0; | ||
1931 | |||
1932 | if (block_size <= 0) | ||
1933 | return -EINVAL; | ||
1934 | |||
1935 | while (tuple_size < block_size) { | ||
1936 | array = (struct snd_soc_tplg_vendor_array *)(pvt_data + off); | ||
1937 | |||
1938 | off += array->size; | ||
1939 | |||
1940 | switch (array->type) { | ||
1941 | case SND_SOC_TPLG_TUPLE_TYPE_STRING: | ||
1942 | dev_warn(dev, "no string tokens expected for skl tplg\n"); | ||
1943 | continue; | ||
1944 | |||
1945 | case SND_SOC_TPLG_TUPLE_TYPE_UUID: | ||
1946 | ret = skl_tplg_get_uuid(dev, mconfig, array->uuid); | ||
1947 | if (ret < 0) | ||
1948 | return ret; | ||
1949 | |||
1950 | tuple_size += sizeof(*array->uuid); | ||
1951 | |||
1952 | continue; | ||
1953 | |||
1954 | default: | ||
1955 | tkn_elem = array->value; | ||
1956 | tkn_count = 0; | ||
1957 | break; | ||
1958 | } | ||
1959 | |||
1960 | while (tkn_count <= (array->num_elems - 1)) { | ||
1961 | ret = skl_tplg_get_token(dev, tkn_elem, | ||
1962 | skl, mconfig); | ||
1963 | |||
1964 | if (ret < 0) | ||
1965 | return ret; | ||
1966 | |||
1967 | tkn_count = tkn_count + ret; | ||
1968 | tkn_elem++; | ||
1969 | } | ||
1970 | |||
1971 | tuple_size += tkn_count * sizeof(*tkn_elem); | ||
1972 | } | ||
1973 | |||
1974 | return 0; | ||
1975 | } | ||
1976 | |||
1977 | /* | ||
1978 | * Every data block is preceded by a descriptor to read the number | ||
1979 | * of data blocks, they type of the block and it's size | ||
1980 | */ | ||
1981 | static int skl_tplg_get_desc_blocks(struct device *dev, | ||
1982 | struct snd_soc_tplg_vendor_array *array) | ||
1983 | { | ||
1984 | struct snd_soc_tplg_vendor_value_elem *tkn_elem; | ||
1985 | |||
1986 | tkn_elem = array->value; | ||
1987 | |||
1988 | switch (tkn_elem->token) { | ||
1989 | case SKL_TKN_U8_NUM_BLOCKS: | ||
1990 | case SKL_TKN_U8_BLOCK_TYPE: | ||
1991 | case SKL_TKN_U16_BLOCK_SIZE: | ||
1992 | return tkn_elem->value; | ||
1993 | |||
1994 | default: | ||
1995 | dev_err(dev, "Invalid descriptor token %d\n", tkn_elem->token); | ||
1996 | break; | ||
1997 | } | ||
1998 | |||
1999 | return -EINVAL; | ||
2000 | } | ||
2001 | |||
2002 | /* | ||
2003 | * Parse the private data for the token and corresponding value. | ||
2004 | * The private data can have multiple data blocks. So, a data block | ||
2005 | * is preceded by a descriptor for number of blocks and a descriptor | ||
2006 | * for the type and size of the suceeding data block. | ||
2007 | */ | ||
2008 | static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w, | ||
2009 | struct skl *skl, struct device *dev, | ||
2010 | struct skl_module_cfg *mconfig) | ||
2011 | { | ||
2012 | struct snd_soc_tplg_vendor_array *array; | ||
2013 | int num_blocks, block_size = 0, block_type, off = 0; | ||
2014 | char *data; | ||
2015 | int ret; | ||
2016 | |||
2017 | /* Read the NUM_DATA_BLOCKS descriptor */ | ||
2018 | array = (struct snd_soc_tplg_vendor_array *)tplg_w->priv.data; | ||
2019 | ret = skl_tplg_get_desc_blocks(dev, array); | ||
2020 | if (ret < 0) | ||
2021 | return ret; | ||
2022 | num_blocks = ret; | ||
2023 | |||
2024 | off += array->size; | ||
2025 | array = (struct snd_soc_tplg_vendor_array *)(tplg_w->priv.data + off); | ||
2026 | |||
2027 | /* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */ | ||
2028 | while (num_blocks > 0) { | ||
2029 | ret = skl_tplg_get_desc_blocks(dev, array); | ||
2030 | |||
2031 | if (ret < 0) | ||
2032 | return ret; | ||
2033 | block_type = ret; | ||
2034 | off += array->size; | ||
2035 | |||
2036 | array = (struct snd_soc_tplg_vendor_array *) | ||
2037 | (tplg_w->priv.data + off); | ||
2038 | |||
2039 | ret = skl_tplg_get_desc_blocks(dev, array); | ||
2040 | |||
2041 | if (ret < 0) | ||
2042 | return ret; | ||
2043 | block_size = ret; | ||
2044 | off += array->size; | ||
2045 | |||
2046 | array = (struct snd_soc_tplg_vendor_array *) | ||
2047 | (tplg_w->priv.data + off); | ||
2048 | |||
2049 | data = (tplg_w->priv.data + off); | ||
2050 | |||
2051 | if (block_type == SKL_TYPE_TUPLE) { | ||
2052 | ret = skl_tplg_get_tokens(dev, data, | ||
2053 | skl, mconfig, block_size); | ||
2054 | |||
2055 | if (ret < 0) | ||
2056 | return ret; | ||
2057 | |||
2058 | --num_blocks; | ||
2059 | } else { | ||
2060 | if (mconfig->formats_config.caps_size > 0) | ||
2061 | memcpy(mconfig->formats_config.caps, data, | ||
2062 | mconfig->formats_config.caps_size); | ||
2063 | --num_blocks; | ||
2064 | } | ||
1541 | } | 2065 | } |
2066 | |||
2067 | return 0; | ||
1542 | } | 2068 | } |
1543 | 2069 | ||
1544 | static void skl_clear_pin_config(struct snd_soc_platform *platform, | 2070 | static void skl_clear_pin_config(struct snd_soc_platform *platform, |
@@ -1606,9 +2132,6 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, | |||
1606 | struct skl *skl = ebus_to_skl(ebus); | 2132 | struct skl *skl = ebus_to_skl(ebus); |
1607 | struct hdac_bus *bus = ebus_to_hbus(ebus); | 2133 | struct hdac_bus *bus = ebus_to_hbus(ebus); |
1608 | struct skl_module_cfg *mconfig; | 2134 | struct skl_module_cfg *mconfig; |
1609 | struct skl_pipe *pipe; | ||
1610 | struct skl_dfw_module *dfw_config = | ||
1611 | (struct skl_dfw_module *)tplg_w->priv.data; | ||
1612 | 2135 | ||
1613 | if (!tplg_w->priv.size) | 2136 | if (!tplg_w->priv.size) |
1614 | goto bind_event; | 2137 | goto bind_event; |
@@ -1619,76 +2142,17 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, | |||
1619 | return -ENOMEM; | 2142 | return -ENOMEM; |
1620 | 2143 | ||
1621 | w->priv = mconfig; | 2144 | w->priv = mconfig; |
1622 | memcpy(&mconfig->guid, &dfw_config->uuid, 16); | ||
1623 | 2145 | ||
1624 | ret = snd_skl_get_module_info(skl->skl_sst, mconfig->guid, dfw_config); | 2146 | /* |
2147 | * module binary can be loaded later, so set it to query when | ||
2148 | * module is load for a use case | ||
2149 | */ | ||
2150 | mconfig->id.module_id = -1; | ||
2151 | |||
2152 | /* Parse private data for tuples */ | ||
2153 | ret = skl_tplg_get_pvt_data(tplg_w, skl, bus->dev, mconfig); | ||
1625 | if (ret < 0) | 2154 | if (ret < 0) |
1626 | return ret; | 2155 | return ret; |
1627 | |||
1628 | mconfig->id.module_id = dfw_config->module_id; | ||
1629 | mconfig->id.instance_id = dfw_config->instance_id; | ||
1630 | mconfig->mcps = dfw_config->max_mcps; | ||
1631 | mconfig->ibs = dfw_config->ibs; | ||
1632 | mconfig->obs = dfw_config->obs; | ||
1633 | mconfig->core_id = dfw_config->core_id; | ||
1634 | mconfig->max_in_queue = dfw_config->max_in_queue; | ||
1635 | mconfig->max_out_queue = dfw_config->max_out_queue; | ||
1636 | mconfig->is_loadable = dfw_config->is_loadable; | ||
1637 | skl_tplg_fill_fmt(mconfig->in_fmt, dfw_config->in_fmt, | ||
1638 | MODULE_MAX_IN_PINS); | ||
1639 | skl_tplg_fill_fmt(mconfig->out_fmt, dfw_config->out_fmt, | ||
1640 | MODULE_MAX_OUT_PINS); | ||
1641 | |||
1642 | mconfig->params_fixup = dfw_config->params_fixup; | ||
1643 | mconfig->converter = dfw_config->converter; | ||
1644 | mconfig->m_type = dfw_config->module_type; | ||
1645 | mconfig->vbus_id = dfw_config->vbus_id; | ||
1646 | mconfig->mem_pages = dfw_config->mem_pages; | ||
1647 | |||
1648 | pipe = skl_tplg_add_pipe(bus->dev, skl, &dfw_config->pipe); | ||
1649 | if (pipe) | ||
1650 | mconfig->pipe = pipe; | ||
1651 | |||
1652 | mconfig->dev_type = dfw_config->dev_type; | ||
1653 | mconfig->hw_conn_type = dfw_config->hw_conn_type; | ||
1654 | mconfig->time_slot = dfw_config->time_slot; | ||
1655 | mconfig->formats_config.caps_size = dfw_config->caps.caps_size; | ||
1656 | |||
1657 | mconfig->m_in_pin = devm_kzalloc(bus->dev, (mconfig->max_in_queue) * | ||
1658 | sizeof(*mconfig->m_in_pin), | ||
1659 | GFP_KERNEL); | ||
1660 | if (!mconfig->m_in_pin) | ||
1661 | return -ENOMEM; | ||
1662 | |||
1663 | mconfig->m_out_pin = devm_kzalloc(bus->dev, (mconfig->max_out_queue) * | ||
1664 | sizeof(*mconfig->m_out_pin), | ||
1665 | GFP_KERNEL); | ||
1666 | if (!mconfig->m_out_pin) | ||
1667 | return -ENOMEM; | ||
1668 | |||
1669 | skl_fill_module_pin_info(dfw_config->in_pin, mconfig->m_in_pin, | ||
1670 | dfw_config->is_dynamic_in_pin, | ||
1671 | mconfig->max_in_queue); | ||
1672 | |||
1673 | skl_fill_module_pin_info(dfw_config->out_pin, mconfig->m_out_pin, | ||
1674 | dfw_config->is_dynamic_out_pin, | ||
1675 | mconfig->max_out_queue); | ||
1676 | |||
1677 | |||
1678 | if (mconfig->formats_config.caps_size == 0) | ||
1679 | goto bind_event; | ||
1680 | |||
1681 | mconfig->formats_config.caps = (u32 *)devm_kzalloc(bus->dev, | ||
1682 | mconfig->formats_config.caps_size, GFP_KERNEL); | ||
1683 | |||
1684 | if (mconfig->formats_config.caps == NULL) | ||
1685 | return -ENOMEM; | ||
1686 | |||
1687 | memcpy(mconfig->formats_config.caps, dfw_config->caps.caps, | ||
1688 | dfw_config->caps.caps_size); | ||
1689 | mconfig->formats_config.param_id = dfw_config->caps.param_id; | ||
1690 | mconfig->formats_config.set_params = dfw_config->caps.set_params; | ||
1691 | |||
1692 | bind_event: | 2156 | bind_event: |
1693 | if (tplg_w->event_type == 0) { | 2157 | if (tplg_w->event_type == 0) { |
1694 | dev_dbg(bus->dev, "ASoC: No event handler required\n"); | 2158 | dev_dbg(bus->dev, "ASoC: No event handler required\n"); |
@@ -1767,11 +2231,229 @@ static int skl_tplg_control_load(struct snd_soc_component *cmpnt, | |||
1767 | return 0; | 2231 | return 0; |
1768 | } | 2232 | } |
1769 | 2233 | ||
2234 | static int skl_tplg_fill_str_mfest_tkn(struct device *dev, | ||
2235 | struct snd_soc_tplg_vendor_string_elem *str_elem, | ||
2236 | struct skl_dfw_manifest *minfo) | ||
2237 | { | ||
2238 | int tkn_count = 0; | ||
2239 | static int ref_count; | ||
2240 | |||
2241 | switch (str_elem->token) { | ||
2242 | case SKL_TKN_STR_LIB_NAME: | ||
2243 | if (ref_count > minfo->lib_count - 1) { | ||
2244 | ref_count = 0; | ||
2245 | return -EINVAL; | ||
2246 | } | ||
2247 | |||
2248 | strncpy(minfo->lib[ref_count].name, str_elem->string, | ||
2249 | ARRAY_SIZE(minfo->lib[ref_count].name)); | ||
2250 | ref_count++; | ||
2251 | tkn_count++; | ||
2252 | break; | ||
2253 | |||
2254 | default: | ||
2255 | dev_err(dev, "Not a string token %d\n", str_elem->token); | ||
2256 | break; | ||
2257 | } | ||
2258 | |||
2259 | return tkn_count; | ||
2260 | } | ||
2261 | |||
2262 | static int skl_tplg_get_str_tkn(struct device *dev, | ||
2263 | struct snd_soc_tplg_vendor_array *array, | ||
2264 | struct skl_dfw_manifest *minfo) | ||
2265 | { | ||
2266 | int tkn_count = 0, ret; | ||
2267 | struct snd_soc_tplg_vendor_string_elem *str_elem; | ||
2268 | |||
2269 | str_elem = (struct snd_soc_tplg_vendor_string_elem *)array->value; | ||
2270 | while (tkn_count < array->num_elems) { | ||
2271 | ret = skl_tplg_fill_str_mfest_tkn(dev, str_elem, minfo); | ||
2272 | str_elem++; | ||
2273 | |||
2274 | if (ret < 0) | ||
2275 | return ret; | ||
2276 | |||
2277 | tkn_count = tkn_count + ret; | ||
2278 | } | ||
2279 | |||
2280 | return tkn_count; | ||
2281 | } | ||
2282 | |||
2283 | static int skl_tplg_get_int_tkn(struct device *dev, | ||
2284 | struct snd_soc_tplg_vendor_value_elem *tkn_elem, | ||
2285 | struct skl_dfw_manifest *minfo) | ||
2286 | { | ||
2287 | int tkn_count = 0; | ||
2288 | |||
2289 | switch (tkn_elem->token) { | ||
2290 | case SKL_TKN_U32_LIB_COUNT: | ||
2291 | minfo->lib_count = tkn_elem->value; | ||
2292 | tkn_count++; | ||
2293 | break; | ||
2294 | |||
2295 | default: | ||
2296 | dev_err(dev, "Not a manifest token %d\n", tkn_elem->token); | ||
2297 | return -EINVAL; | ||
2298 | } | ||
2299 | |||
2300 | return tkn_count; | ||
2301 | } | ||
2302 | |||
2303 | /* | ||
2304 | * Fill the manifest structure by parsing the tokens based on the | ||
2305 | * type. | ||
2306 | */ | ||
2307 | static int skl_tplg_get_manifest_tkn(struct device *dev, | ||
2308 | char *pvt_data, struct skl_dfw_manifest *minfo, | ||
2309 | int block_size) | ||
2310 | { | ||
2311 | int tkn_count = 0, ret; | ||
2312 | int off = 0, tuple_size = 0; | ||
2313 | struct snd_soc_tplg_vendor_array *array; | ||
2314 | struct snd_soc_tplg_vendor_value_elem *tkn_elem; | ||
2315 | |||
2316 | if (block_size <= 0) | ||
2317 | return -EINVAL; | ||
2318 | |||
2319 | while (tuple_size < block_size) { | ||
2320 | array = (struct snd_soc_tplg_vendor_array *)(pvt_data + off); | ||
2321 | off += array->size; | ||
2322 | switch (array->type) { | ||
2323 | case SND_SOC_TPLG_TUPLE_TYPE_STRING: | ||
2324 | ret = skl_tplg_get_str_tkn(dev, array, minfo); | ||
2325 | |||
2326 | if (ret < 0) | ||
2327 | return ret; | ||
2328 | tkn_count += ret; | ||
2329 | |||
2330 | tuple_size += tkn_count * | ||
2331 | sizeof(struct snd_soc_tplg_vendor_string_elem); | ||
2332 | continue; | ||
2333 | |||
2334 | case SND_SOC_TPLG_TUPLE_TYPE_UUID: | ||
2335 | dev_warn(dev, "no uuid tokens for skl tplf manifest\n"); | ||
2336 | continue; | ||
2337 | |||
2338 | default: | ||
2339 | tkn_elem = array->value; | ||
2340 | tkn_count = 0; | ||
2341 | break; | ||
2342 | } | ||
2343 | |||
2344 | while (tkn_count <= array->num_elems - 1) { | ||
2345 | ret = skl_tplg_get_int_tkn(dev, | ||
2346 | tkn_elem, minfo); | ||
2347 | if (ret < 0) | ||
2348 | return ret; | ||
2349 | |||
2350 | tkn_count = tkn_count + ret; | ||
2351 | tkn_elem++; | ||
2352 | tuple_size += tkn_count * | ||
2353 | sizeof(struct snd_soc_tplg_vendor_value_elem); | ||
2354 | break; | ||
2355 | } | ||
2356 | tkn_count = 0; | ||
2357 | } | ||
2358 | |||
2359 | return 0; | ||
2360 | } | ||
2361 | |||
2362 | /* | ||
2363 | * Parse manifest private data for tokens. The private data block is | ||
2364 | * preceded by descriptors for type and size of data block. | ||
2365 | */ | ||
2366 | static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest, | ||
2367 | struct device *dev, struct skl_dfw_manifest *minfo) | ||
2368 | { | ||
2369 | struct snd_soc_tplg_vendor_array *array; | ||
2370 | int num_blocks, block_size = 0, block_type, off = 0; | ||
2371 | char *data; | ||
2372 | int ret; | ||
2373 | |||
2374 | /* Read the NUM_DATA_BLOCKS descriptor */ | ||
2375 | array = (struct snd_soc_tplg_vendor_array *)manifest->priv.data; | ||
2376 | ret = skl_tplg_get_desc_blocks(dev, array); | ||
2377 | if (ret < 0) | ||
2378 | return ret; | ||
2379 | num_blocks = ret; | ||
2380 | |||
2381 | off += array->size; | ||
2382 | array = (struct snd_soc_tplg_vendor_array *) | ||
2383 | (manifest->priv.data + off); | ||
2384 | |||
2385 | /* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */ | ||
2386 | while (num_blocks > 0) { | ||
2387 | ret = skl_tplg_get_desc_blocks(dev, array); | ||
2388 | |||
2389 | if (ret < 0) | ||
2390 | return ret; | ||
2391 | block_type = ret; | ||
2392 | off += array->size; | ||
2393 | |||
2394 | array = (struct snd_soc_tplg_vendor_array *) | ||
2395 | (manifest->priv.data + off); | ||
2396 | |||
2397 | ret = skl_tplg_get_desc_blocks(dev, array); | ||
2398 | |||
2399 | if (ret < 0) | ||
2400 | return ret; | ||
2401 | block_size = ret; | ||
2402 | off += array->size; | ||
2403 | |||
2404 | array = (struct snd_soc_tplg_vendor_array *) | ||
2405 | (manifest->priv.data + off); | ||
2406 | |||
2407 | data = (manifest->priv.data + off); | ||
2408 | |||
2409 | if (block_type == SKL_TYPE_TUPLE) { | ||
2410 | ret = skl_tplg_get_manifest_tkn(dev, data, minfo, | ||
2411 | block_size); | ||
2412 | |||
2413 | if (ret < 0) | ||
2414 | return ret; | ||
2415 | |||
2416 | --num_blocks; | ||
2417 | } else { | ||
2418 | return -EINVAL; | ||
2419 | } | ||
2420 | } | ||
2421 | |||
2422 | return 0; | ||
2423 | } | ||
2424 | |||
2425 | static int skl_manifest_load(struct snd_soc_component *cmpnt, | ||
2426 | struct snd_soc_tplg_manifest *manifest) | ||
2427 | { | ||
2428 | struct skl_dfw_manifest *minfo; | ||
2429 | struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt); | ||
2430 | struct hdac_bus *bus = ebus_to_hbus(ebus); | ||
2431 | struct skl *skl = ebus_to_skl(ebus); | ||
2432 | int ret = 0; | ||
2433 | |||
2434 | /* proceed only if we have private data defined */ | ||
2435 | if (manifest->priv.size == 0) | ||
2436 | return 0; | ||
2437 | |||
2438 | minfo = &skl->skl_sst->manifest; | ||
2439 | |||
2440 | skl_tplg_get_manifest_data(manifest, bus->dev, minfo); | ||
2441 | |||
2442 | if (minfo->lib_count > HDA_MAX_LIB) { | ||
2443 | dev_err(bus->dev, "Exceeding max Library count. Got:%d\n", | ||
2444 | minfo->lib_count); | ||
2445 | ret = -EINVAL; | ||
2446 | } | ||
2447 | |||
2448 | return ret; | ||
2449 | } | ||
2450 | |||
1770 | static struct snd_soc_tplg_ops skl_tplg_ops = { | 2451 | static struct snd_soc_tplg_ops skl_tplg_ops = { |
1771 | .widget_load = skl_tplg_widget_load, | 2452 | .widget_load = skl_tplg_widget_load, |
1772 | .control_load = skl_tplg_control_load, | 2453 | .control_load = skl_tplg_control_load, |
1773 | .bytes_ext_ops = skl_tlv_ops, | 2454 | .bytes_ext_ops = skl_tlv_ops, |
1774 | .bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops), | 2455 | .bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops), |
2456 | .manifest = skl_manifest_load, | ||
1775 | }; | 2457 | }; |
1776 | 2458 | ||
1777 | /* | 2459 | /* |
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index 22d3ef83817d..a519360f42a6 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h | |||
@@ -133,7 +133,7 @@ struct skl_i2s_config_blob { | |||
133 | struct skl_dma_control { | 133 | struct skl_dma_control { |
134 | u32 node_id; | 134 | u32 node_id; |
135 | u32 config_length; | 135 | u32 config_length; |
136 | u32 config_data[1]; | 136 | u32 config_data[0]; |
137 | } __packed; | 137 | } __packed; |
138 | 138 | ||
139 | struct skl_cpr_cfg { | 139 | struct skl_cpr_cfg { |
@@ -215,9 +215,20 @@ struct skl_module_fmt { | |||
215 | 215 | ||
216 | struct skl_module_cfg; | 216 | struct skl_module_cfg; |
217 | 217 | ||
218 | struct skl_mod_inst_map { | ||
219 | u16 mod_id; | ||
220 | u16 inst_id; | ||
221 | }; | ||
222 | |||
223 | struct skl_kpb_params { | ||
224 | u32 num_modules; | ||
225 | struct skl_mod_inst_map map[0]; | ||
226 | }; | ||
227 | |||
218 | struct skl_module_inst_id { | 228 | struct skl_module_inst_id { |
219 | u32 module_id; | 229 | int module_id; |
220 | u32 instance_id; | 230 | u32 instance_id; |
231 | int pvt_id; | ||
221 | }; | 232 | }; |
222 | 233 | ||
223 | enum skl_module_pin_state { | 234 | enum skl_module_pin_state { |
diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h index a32e5e9cc530..2f6281e056d6 100644 --- a/sound/soc/intel/skylake/skl-tplg-interface.h +++ b/sound/soc/intel/skylake/skl-tplg-interface.h | |||
@@ -80,7 +80,8 @@ enum skl_module_type { | |||
80 | SKL_MODULE_TYPE_UPDWMIX, | 80 | SKL_MODULE_TYPE_UPDWMIX, |
81 | SKL_MODULE_TYPE_SRCINT, | 81 | SKL_MODULE_TYPE_SRCINT, |
82 | SKL_MODULE_TYPE_ALGO, | 82 | SKL_MODULE_TYPE_ALGO, |
83 | SKL_MODULE_TYPE_BASE_OUTFMT | 83 | SKL_MODULE_TYPE_BASE_OUTFMT, |
84 | SKL_MODULE_TYPE_KPB, | ||
84 | }; | 85 | }; |
85 | 86 | ||
86 | enum skl_core_affinity { | 87 | enum skl_core_affinity { |
@@ -148,84 +149,34 @@ enum skl_module_param_type { | |||
148 | SKL_PARAM_BIND | 149 | SKL_PARAM_BIND |
149 | }; | 150 | }; |
150 | 151 | ||
151 | struct skl_dfw_module_pin { | 152 | struct skl_dfw_algo_data { |
152 | u16 module_id; | ||
153 | u16 instance_id; | ||
154 | } __packed; | ||
155 | |||
156 | struct skl_dfw_module_fmt { | ||
157 | u32 channels; | ||
158 | u32 freq; | ||
159 | u32 bit_depth; | ||
160 | u32 valid_bit_depth; | ||
161 | u32 ch_cfg; | ||
162 | u32 interleaving_style; | ||
163 | u32 sample_type; | ||
164 | u32 ch_map; | ||
165 | } __packed; | ||
166 | |||
167 | struct skl_dfw_module_caps { | ||
168 | u32 set_params:2; | 153 | u32 set_params:2; |
169 | u32 rsvd:30; | 154 | u32 rsvd:30; |
170 | u32 param_id; | 155 | u32 param_id; |
171 | u32 caps_size; | 156 | u32 max; |
172 | u32 caps[HDA_SST_CFG_MAX]; | 157 | char params[0]; |
173 | }; | ||
174 | |||
175 | struct skl_dfw_pipe { | ||
176 | u8 pipe_id; | ||
177 | u8 pipe_priority; | ||
178 | u16 conn_type:4; | ||
179 | u16 rsvd:4; | ||
180 | u16 memory_pages:8; | ||
181 | } __packed; | 158 | } __packed; |
182 | 159 | ||
183 | struct skl_dfw_module { | 160 | #define LIB_NAME_LENGTH 128 |
184 | u8 uuid[16]; | 161 | #define HDA_MAX_LIB 16 |
185 | 162 | ||
186 | u16 module_id; | 163 | struct lib_info { |
187 | u16 instance_id; | 164 | char name[LIB_NAME_LENGTH]; |
188 | u32 max_mcps; | ||
189 | u32 mem_pages; | ||
190 | u32 obs; | ||
191 | u32 ibs; | ||
192 | u32 vbus_id; | ||
193 | |||
194 | u32 max_in_queue:8; | ||
195 | u32 max_out_queue:8; | ||
196 | u32 time_slot:8; | ||
197 | u32 core_id:4; | ||
198 | u32 rsvd1:4; | ||
199 | |||
200 | u32 module_type:8; | ||
201 | u32 conn_type:4; | ||
202 | u32 dev_type:4; | ||
203 | u32 hw_conn_type:4; | ||
204 | u32 rsvd2:12; | ||
205 | |||
206 | u32 params_fixup:8; | ||
207 | u32 converter:8; | ||
208 | u32 input_pin_type:1; | ||
209 | u32 output_pin_type:1; | ||
210 | u32 is_dynamic_in_pin:1; | ||
211 | u32 is_dynamic_out_pin:1; | ||
212 | u32 is_loadable:1; | ||
213 | u32 rsvd3:11; | ||
214 | |||
215 | struct skl_dfw_pipe pipe; | ||
216 | struct skl_dfw_module_fmt in_fmt[MAX_IN_QUEUE]; | ||
217 | struct skl_dfw_module_fmt out_fmt[MAX_OUT_QUEUE]; | ||
218 | struct skl_dfw_module_pin in_pin[MAX_IN_QUEUE]; | ||
219 | struct skl_dfw_module_pin out_pin[MAX_OUT_QUEUE]; | ||
220 | struct skl_dfw_module_caps caps; | ||
221 | } __packed; | 165 | } __packed; |
222 | 166 | ||
223 | struct skl_dfw_algo_data { | 167 | struct skl_dfw_manifest { |
224 | u32 set_params:2; | 168 | u32 lib_count; |
225 | u32 rsvd:30; | 169 | struct lib_info lib[HDA_MAX_LIB]; |
226 | u32 param_id; | ||
227 | u32 max; | ||
228 | char params[0]; | ||
229 | } __packed; | 170 | } __packed; |
230 | 171 | ||
172 | enum skl_tkn_dir { | ||
173 | SKL_DIR_IN, | ||
174 | SKL_DIR_OUT | ||
175 | }; | ||
176 | |||
177 | enum skl_tuple_type { | ||
178 | SKL_TYPE_TUPLE, | ||
179 | SKL_TYPE_DATA | ||
180 | }; | ||
181 | |||
231 | #endif | 182 | #endif |
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h index 9064e5b0d676..5d4fbb094c48 100644 --- a/sound/soc/intel/skylake/skl.h +++ b/sound/soc/intel/skylake/skl.h | |||
@@ -105,6 +105,7 @@ struct skl_dsp_ops { | |||
105 | int irq, const char *fw_name, | 105 | int irq, const char *fw_name, |
106 | struct skl_dsp_loader_ops loader_ops, | 106 | struct skl_dsp_loader_ops loader_ops, |
107 | struct skl_sst **skl_sst); | 107 | struct skl_sst **skl_sst); |
108 | int (*init_fw)(struct device *dev, struct skl_sst *ctx); | ||
108 | void (*cleanup)(struct device *dev, struct skl_sst *ctx); | 109 | void (*cleanup)(struct device *dev, struct skl_sst *ctx); |
109 | }; | 110 | }; |
110 | 111 | ||
@@ -123,4 +124,5 @@ int skl_free_dsp(struct skl *skl); | |||
123 | int skl_suspend_dsp(struct skl *skl); | 124 | int skl_suspend_dsp(struct skl *skl); |
124 | int skl_resume_dsp(struct skl *skl); | 125 | int skl_resume_dsp(struct skl *skl); |
125 | void skl_cleanup_resources(struct skl *skl); | 126 | void skl_cleanup_resources(struct skl *skl); |
127 | const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id); | ||
126 | #endif /* __SOUND_SOC_SKL_H */ | 128 | #endif /* __SOUND_SOC_SKL_H */ |
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index dbfdfe99c69d..dafd22e874e9 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c | |||
@@ -242,7 +242,7 @@ static snd_pcm_uframes_t kirkwood_dma_pointer(struct snd_pcm_substream | |||
242 | return count; | 242 | return count; |
243 | } | 243 | } |
244 | 244 | ||
245 | static struct snd_pcm_ops kirkwood_dma_ops = { | 245 | static const struct snd_pcm_ops kirkwood_dma_ops = { |
246 | .open = kirkwood_dma_open, | 246 | .open = kirkwood_dma_open, |
247 | .close = kirkwood_dma_close, | 247 | .close = kirkwood_dma_close, |
248 | .ioctl = snd_pcm_lib_ioctl, | 248 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediatek/common/mtk-afe-fe-dai.c index b788791b0a35..ac231d33d8fe 100644 --- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c +++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c | |||
@@ -23,7 +23,8 @@ | |||
23 | 23 | ||
24 | #define AFE_BASE_END_OFFSET 8 | 24 | #define AFE_BASE_END_OFFSET 8 |
25 | 25 | ||
26 | int mtk_regmap_update_bits(struct regmap *map, int reg, unsigned int mask, | 26 | static int mtk_regmap_update_bits(struct regmap *map, int reg, |
27 | unsigned int mask, | ||
27 | unsigned int val) | 28 | unsigned int val) |
28 | { | 29 | { |
29 | if (reg < 0) | 30 | if (reg < 0) |
@@ -31,7 +32,7 @@ int mtk_regmap_update_bits(struct regmap *map, int reg, unsigned int mask, | |||
31 | return regmap_update_bits(map, reg, mask, val); | 32 | return regmap_update_bits(map, reg, mask, val); |
32 | } | 33 | } |
33 | 34 | ||
34 | int mtk_regmap_write(struct regmap *map, int reg, unsigned int val) | 35 | static int mtk_regmap_write(struct regmap *map, int reg, unsigned int val) |
35 | { | 36 | { |
36 | if (reg < 0) | 37 | if (reg < 0) |
37 | return 0; | 38 | return 0; |
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c index 76ce33199bf9..06fec5699cc8 100644 --- a/sound/soc/omap/mcbsp.c +++ b/sound/soc/omap/mcbsp.c | |||
@@ -221,7 +221,8 @@ void omap_mcbsp_config(struct omap_mcbsp *mcbsp, | |||
221 | 221 | ||
222 | /* Enable TX/RX sync error interrupts by default */ | 222 | /* Enable TX/RX sync error interrupts by default */ |
223 | if (mcbsp->irq) | 223 | if (mcbsp->irq) |
224 | MCBSP_WRITE(mcbsp, IRQEN, RSYNCERREN | XSYNCERREN); | 224 | MCBSP_WRITE(mcbsp, IRQEN, RSYNCERREN | XSYNCERREN | |
225 | RUNDFLEN | ROVFLEN | XUNDFLEN | XOVFLEN); | ||
225 | } | 226 | } |
226 | 227 | ||
227 | /** | 228 | /** |
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index f61b3b58083b..89fe95e877db 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c | |||
@@ -305,23 +305,14 @@ static int omap_abe_probe(struct platform_device *pdev) | |||
305 | 305 | ||
306 | snd_soc_card_set_drvdata(card, priv); | 306 | snd_soc_card_set_drvdata(card, priv); |
307 | 307 | ||
308 | ret = snd_soc_register_card(card); | 308 | ret = devm_snd_soc_register_card(&pdev->dev, card); |
309 | if (ret) | 309 | if (ret) |
310 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", | 310 | dev_err(&pdev->dev, "devm_snd_soc_register_card() failed: %d\n", |
311 | ret); | 311 | ret); |
312 | 312 | ||
313 | return ret; | 313 | return ret; |
314 | } | 314 | } |
315 | 315 | ||
316 | static int omap_abe_remove(struct platform_device *pdev) | ||
317 | { | ||
318 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
319 | |||
320 | snd_soc_unregister_card(card); | ||
321 | |||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static const struct of_device_id omap_abe_of_match[] = { | 316 | static const struct of_device_id omap_abe_of_match[] = { |
326 | {.compatible = "ti,abe-twl6040", }, | 317 | {.compatible = "ti,abe-twl6040", }, |
327 | { }, | 318 | { }, |
@@ -335,7 +326,6 @@ static struct platform_driver omap_abe_driver = { | |||
335 | .of_match_table = omap_abe_of_match, | 326 | .of_match_table = omap_abe_of_match, |
336 | }, | 327 | }, |
337 | .probe = omap_abe_probe, | 328 | .probe = omap_abe_probe, |
338 | .remove = omap_abe_remove, | ||
339 | }; | 329 | }; |
340 | 330 | ||
341 | static int __init omap_abe_init(void) | 331 | static int __init omap_abe_init(void) |
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index a84f677234f0..94e9ff791f3a 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c | |||
@@ -58,7 +58,7 @@ static void omap_pcm_limit_supported_formats(void) | |||
58 | { | 58 | { |
59 | int i; | 59 | int i; |
60 | 60 | ||
61 | for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { | 61 | for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) { |
62 | switch (snd_pcm_format_physical_width(i)) { | 62 | switch (snd_pcm_format_physical_width(i)) { |
63 | case 8: | 63 | case 8: |
64 | case 16: | 64 | case 16: |
diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c index 1289543c8fb2..07f91e918b23 100644 --- a/sound/soc/qcom/apq8016_sbc.c +++ b/sound/soc/qcom/apq8016_sbc.c | |||
@@ -85,6 +85,15 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card) | |||
85 | return ERR_PTR(ret); | 85 | return ERR_PTR(ret); |
86 | } | 86 | } |
87 | 87 | ||
88 | /* DAPM routes */ | ||
89 | if (of_property_read_bool(node, "qcom,audio-routing")) { | ||
90 | ret = snd_soc_of_parse_audio_routing(card, | ||
91 | "qcom,audio-routing"); | ||
92 | if (ret) | ||
93 | return ERR_PTR(ret); | ||
94 | } | ||
95 | |||
96 | |||
88 | /* Populate links */ | 97 | /* Populate links */ |
89 | num_links = of_get_child_count(node); | 98 | num_links = of_get_child_count(node); |
90 | 99 | ||
@@ -147,6 +156,15 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card) | |||
147 | return data; | 156 | return data; |
148 | } | 157 | } |
149 | 158 | ||
159 | static const struct snd_soc_dapm_widget apq8016_sbc_dapm_widgets[] = { | ||
160 | |||
161 | SND_SOC_DAPM_MIC("Handset Mic", NULL), | ||
162 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
163 | SND_SOC_DAPM_MIC("Secondary Mic", NULL), | ||
164 | SND_SOC_DAPM_MIC("Digital Mic1", NULL), | ||
165 | SND_SOC_DAPM_MIC("Digital Mic2", NULL), | ||
166 | }; | ||
167 | |||
150 | static int apq8016_sbc_platform_probe(struct platform_device *pdev) | 168 | static int apq8016_sbc_platform_probe(struct platform_device *pdev) |
151 | { | 169 | { |
152 | struct device *dev = &pdev->dev; | 170 | struct device *dev = &pdev->dev; |
@@ -159,6 +177,8 @@ static int apq8016_sbc_platform_probe(struct platform_device *pdev) | |||
159 | return -ENOMEM; | 177 | return -ENOMEM; |
160 | 178 | ||
161 | card->dev = dev; | 179 | card->dev = dev; |
180 | card->dapm_widgets = apq8016_sbc_dapm_widgets; | ||
181 | card->num_dapm_widgets = ARRAY_SIZE(apq8016_sbc_dapm_widgets); | ||
162 | data = apq8016_sbc_parse_of(card); | 182 | data = apq8016_sbc_parse_of(card); |
163 | if (IS_ERR(data)) { | 183 | if (IS_ERR(data)) { |
164 | dev_err(&pdev->dev, "Error resolving dai links: %ld\n", | 184 | dev_err(&pdev->dev, "Error resolving dai links: %ld\n", |
diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c index db000c6987a1..e2ff538a8aa5 100644 --- a/sound/soc/qcom/lpass-platform.c +++ b/sound/soc/qcom/lpass-platform.c | |||
@@ -84,9 +84,9 @@ static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream, | |||
84 | struct snd_pcm_hw_params *params) | 84 | struct snd_pcm_hw_params *params) |
85 | { | 85 | { |
86 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 86 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
87 | struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime); | ||
88 | struct lpass_data *drvdata = | 87 | struct lpass_data *drvdata = |
89 | snd_soc_platform_get_drvdata(soc_runtime->platform); | 88 | snd_soc_platform_get_drvdata(soc_runtime->platform); |
89 | struct lpass_pcm_data *pcm_data = drvdata->private_data; | ||
90 | struct lpass_variant *v = drvdata->variant; | 90 | struct lpass_variant *v = drvdata->variant; |
91 | snd_pcm_format_t format = params_format(params); | 91 | snd_pcm_format_t format = params_format(params); |
92 | unsigned int channels = params_channels(params); | 92 | unsigned int channels = params_channels(params); |
@@ -177,9 +177,9 @@ static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream, | |||
177 | static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream) | 177 | static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream) |
178 | { | 178 | { |
179 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 179 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
180 | struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime); | ||
181 | struct lpass_data *drvdata = | 180 | struct lpass_data *drvdata = |
182 | snd_soc_platform_get_drvdata(soc_runtime->platform); | 181 | snd_soc_platform_get_drvdata(soc_runtime->platform); |
182 | struct lpass_pcm_data *pcm_data = drvdata->private_data; | ||
183 | struct lpass_variant *v = drvdata->variant; | 183 | struct lpass_variant *v = drvdata->variant; |
184 | unsigned int reg; | 184 | unsigned int reg; |
185 | int ret; | 185 | int ret; |
@@ -201,9 +201,9 @@ static int lpass_platform_pcmops_prepare(struct snd_pcm_substream *substream) | |||
201 | { | 201 | { |
202 | struct snd_pcm_runtime *runtime = substream->runtime; | 202 | struct snd_pcm_runtime *runtime = substream->runtime; |
203 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 203 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
204 | struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime); | ||
205 | struct lpass_data *drvdata = | 204 | struct lpass_data *drvdata = |
206 | snd_soc_platform_get_drvdata(soc_runtime->platform); | 205 | snd_soc_platform_get_drvdata(soc_runtime->platform); |
206 | struct lpass_pcm_data *pcm_data = drvdata->private_data; | ||
207 | struct lpass_variant *v = drvdata->variant; | 207 | struct lpass_variant *v = drvdata->variant; |
208 | int ret, ch, dir = substream->stream; | 208 | int ret, ch, dir = substream->stream; |
209 | 209 | ||
@@ -255,9 +255,9 @@ static int lpass_platform_pcmops_trigger(struct snd_pcm_substream *substream, | |||
255 | int cmd) | 255 | int cmd) |
256 | { | 256 | { |
257 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 257 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
258 | struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime); | ||
259 | struct lpass_data *drvdata = | 258 | struct lpass_data *drvdata = |
260 | snd_soc_platform_get_drvdata(soc_runtime->platform); | 259 | snd_soc_platform_get_drvdata(soc_runtime->platform); |
260 | struct lpass_pcm_data *pcm_data = drvdata->private_data; | ||
261 | struct lpass_variant *v = drvdata->variant; | 261 | struct lpass_variant *v = drvdata->variant; |
262 | int ret, ch, dir = substream->stream; | 262 | int ret, ch, dir = substream->stream; |
263 | 263 | ||
@@ -331,9 +331,9 @@ static snd_pcm_uframes_t lpass_platform_pcmops_pointer( | |||
331 | struct snd_pcm_substream *substream) | 331 | struct snd_pcm_substream *substream) |
332 | { | 332 | { |
333 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 333 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
334 | struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime); | ||
335 | struct lpass_data *drvdata = | 334 | struct lpass_data *drvdata = |
336 | snd_soc_platform_get_drvdata(soc_runtime->platform); | 335 | snd_soc_platform_get_drvdata(soc_runtime->platform); |
336 | struct lpass_pcm_data *pcm_data = drvdata->private_data; | ||
337 | struct lpass_variant *v = drvdata->variant; | 337 | struct lpass_variant *v = drvdata->variant; |
338 | unsigned int base_addr, curr_addr; | 338 | unsigned int base_addr, curr_addr; |
339 | int ret, ch, dir = substream->stream; | 339 | int ret, ch, dir = substream->stream; |
@@ -372,7 +372,7 @@ static int lpass_platform_pcmops_mmap(struct snd_pcm_substream *substream, | |||
372 | runtime->dma_bytes); | 372 | runtime->dma_bytes); |
373 | } | 373 | } |
374 | 374 | ||
375 | static struct snd_pcm_ops lpass_platform_pcm_ops = { | 375 | static const struct snd_pcm_ops lpass_platform_pcm_ops = { |
376 | .open = lpass_platform_pcmops_open, | 376 | .open = lpass_platform_pcmops_open, |
377 | .ioctl = snd_pcm_lib_ioctl, | 377 | .ioctl = snd_pcm_lib_ioctl, |
378 | .hw_params = lpass_platform_pcmops_hw_params, | 378 | .hw_params = lpass_platform_pcmops_hw_params, |
@@ -483,7 +483,7 @@ static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime) | |||
483 | return -ENOMEM; | 483 | return -ENOMEM; |
484 | 484 | ||
485 | data->i2s_port = cpu_dai->driver->id; | 485 | data->i2s_port = cpu_dai->driver->id; |
486 | snd_soc_pcm_set_drvdata(soc_runtime, data); | 486 | drvdata->private_data = data; |
487 | 487 | ||
488 | psubstream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; | 488 | psubstream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; |
489 | if (psubstream) { | 489 | if (psubstream) { |
@@ -570,8 +570,8 @@ static void lpass_platform_pcm_free(struct snd_pcm *pcm) | |||
570 | substream = pcm->streams[i].substream; | 570 | substream = pcm->streams[i].substream; |
571 | if (substream) { | 571 | if (substream) { |
572 | rt = substream->private_data; | 572 | rt = substream->private_data; |
573 | data = snd_soc_pcm_get_drvdata(rt); | ||
574 | drvdata = snd_soc_platform_get_drvdata(rt->platform); | 573 | drvdata = snd_soc_platform_get_drvdata(rt->platform); |
574 | data = drvdata->private_data; | ||
575 | 575 | ||
576 | ch = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 576 | ch = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
577 | ? data->rdma_ch | 577 | ? data->rdma_ch |
diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h index 30714ad1e138..35b3cea8207d 100644 --- a/sound/soc/qcom/lpass.h +++ b/sound/soc/qcom/lpass.h | |||
@@ -58,6 +58,8 @@ struct lpass_data { | |||
58 | /* 8016 specific */ | 58 | /* 8016 specific */ |
59 | struct clk *pcnoc_mport_clk; | 59 | struct clk *pcnoc_mport_clk; |
60 | struct clk *pcnoc_sway_clk; | 60 | struct clk *pcnoc_sway_clk; |
61 | |||
62 | void *private_data; | ||
61 | }; | 63 | }; |
62 | 64 | ||
63 | /* Vairant data per each SOC */ | 65 | /* Vairant data per each SOC */ |
diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig index f1e0c703e0d2..c783f9a22595 100644 --- a/sound/soc/rockchip/Kconfig +++ b/sound/soc/rockchip/Kconfig | |||
@@ -41,3 +41,15 @@ config SND_SOC_ROCKCHIP_RT5645 | |||
41 | help | 41 | help |
42 | Say Y or M here if you want to add support for SoC audio on Rockchip | 42 | Say Y or M here if you want to add support for SoC audio on Rockchip |
43 | boards using the RT5645/RT5650 codec, such as Veyron. | 43 | boards using the RT5645/RT5650 codec, such as Veyron. |
44 | |||
45 | config SND_SOC_RK3399_GRU_SOUND | ||
46 | tristate "ASoC support multiple codecs for Rockchip RK3399 GRU boards" | ||
47 | depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP && SPI | ||
48 | select SND_SOC_ROCKCHIP_I2S | ||
49 | select SND_SOC_MAX98357A | ||
50 | select SND_SOC_RT5514 | ||
51 | select SND_SOC_DA7219 | ||
52 | select SND_SOC_RT5514_SPI | ||
53 | help | ||
54 | Say Y or M here if you want to add support multiple codecs for SoC | ||
55 | audio on Rockchip RK3399 GRU boards. | ||
diff --git a/sound/soc/rockchip/Makefile b/sound/soc/rockchip/Makefile index c0bf560125f3..84e5c7c700e7 100644 --- a/sound/soc/rockchip/Makefile +++ b/sound/soc/rockchip/Makefile | |||
@@ -7,6 +7,8 @@ obj-$(CONFIG_SND_SOC_ROCKCHIP_SPDIF) += snd-soc-rockchip-spdif.o | |||
7 | 7 | ||
8 | snd-soc-rockchip-max98090-objs := rockchip_max98090.o | 8 | snd-soc-rockchip-max98090-objs := rockchip_max98090.o |
9 | snd-soc-rockchip-rt5645-objs := rockchip_rt5645.o | 9 | snd-soc-rockchip-rt5645-objs := rockchip_rt5645.o |
10 | snd-soc-rk3399-gru-sound-objs := rk3399_gru_sound.o | ||
10 | 11 | ||
11 | obj-$(CONFIG_SND_SOC_ROCKCHIP_MAX98090) += snd-soc-rockchip-max98090.o | 12 | obj-$(CONFIG_SND_SOC_ROCKCHIP_MAX98090) += snd-soc-rockchip-max98090.o |
12 | obj-$(CONFIG_SND_SOC_ROCKCHIP_RT5645) += snd-soc-rockchip-rt5645.o | 13 | obj-$(CONFIG_SND_SOC_ROCKCHIP_RT5645) += snd-soc-rockchip-rt5645.o |
14 | obj-$(CONFIG_SND_SOC_RK3399_GRU_SOUND) += snd-soc-rk3399-gru-sound.o | ||
diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c new file mode 100644 index 000000000000..9ed735a6cf49 --- /dev/null +++ b/sound/soc/rockchip/rk3399_gru_sound.c | |||
@@ -0,0 +1,397 @@ | |||
1 | /* | ||
2 | * Rockchip machine ASoC driver for boards using MAX98357A/RT5514/DA7219 | ||
3 | * | ||
4 | * Copyright (c) 2016, ROCKCHIP CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/of_gpio.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/spi/spi.h> | ||
26 | #include <linux/input.h> | ||
27 | #include <sound/core.h> | ||
28 | #include <sound/jack.h> | ||
29 | #include <sound/pcm.h> | ||
30 | #include <sound/pcm_params.h> | ||
31 | #include <sound/soc.h> | ||
32 | #include "rockchip_i2s.h" | ||
33 | #include "../codecs/da7219.h" | ||
34 | #include "../codecs/da7219-aad.h" | ||
35 | #include "../codecs/rt5514.h" | ||
36 | |||
37 | #define DRV_NAME "rk3399-gru-sound" | ||
38 | |||
39 | #define SOUND_FS 256 | ||
40 | |||
41 | unsigned int rt5514_dmic_delay; | ||
42 | |||
43 | static struct snd_soc_jack rockchip_sound_jack; | ||
44 | |||
45 | static const struct snd_soc_dapm_widget rockchip_dapm_widgets[] = { | ||
46 | SND_SOC_DAPM_HP("Headphones", NULL), | ||
47 | SND_SOC_DAPM_SPK("Speakers", NULL), | ||
48 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
49 | SND_SOC_DAPM_MIC("Int Mic", NULL), | ||
50 | }; | ||
51 | |||
52 | static const struct snd_soc_dapm_route rockchip_dapm_routes[] = { | ||
53 | /* Input Lines */ | ||
54 | {"MIC", NULL, "Headset Mic"}, | ||
55 | {"DMIC1L", NULL, "Int Mic"}, | ||
56 | {"DMIC1R", NULL, "Int Mic"}, | ||
57 | |||
58 | /* Output Lines */ | ||
59 | {"Headphones", NULL, "HPL"}, | ||
60 | {"Headphones", NULL, "HPR"}, | ||
61 | {"Speakers", NULL, "Speaker"}, | ||
62 | }; | ||
63 | |||
64 | static const struct snd_kcontrol_new rockchip_controls[] = { | ||
65 | SOC_DAPM_PIN_SWITCH("Headphones"), | ||
66 | SOC_DAPM_PIN_SWITCH("Speakers"), | ||
67 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | ||
68 | SOC_DAPM_PIN_SWITCH("Int Mic"), | ||
69 | }; | ||
70 | |||
71 | static int rockchip_sound_max98357a_hw_params(struct snd_pcm_substream *substream, | ||
72 | struct snd_pcm_hw_params *params) | ||
73 | { | ||
74 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
75 | unsigned int mclk; | ||
76 | int ret; | ||
77 | |||
78 | /* max98357a supports these sample rates */ | ||
79 | switch (params_rate(params)) { | ||
80 | case 8000: | ||
81 | case 16000: | ||
82 | case 48000: | ||
83 | case 96000: | ||
84 | mclk = params_rate(params) * SOUND_FS; | ||
85 | break; | ||
86 | default: | ||
87 | dev_err(rtd->card->dev, "%s() doesn't support this sample rate: %d\n", | ||
88 | __func__, params_rate(params)); | ||
89 | return -EINVAL; | ||
90 | } | ||
91 | |||
92 | ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0, mclk, 0); | ||
93 | if (ret) { | ||
94 | dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n", | ||
95 | __func__, mclk, ret); | ||
96 | return ret; | ||
97 | } | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static int rockchip_sound_rt5514_hw_params(struct snd_pcm_substream *substream, | ||
103 | struct snd_pcm_hw_params *params) | ||
104 | { | ||
105 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
106 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
107 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
108 | unsigned int mclk; | ||
109 | int ret; | ||
110 | |||
111 | mclk = params_rate(params) * SOUND_FS; | ||
112 | |||
113 | ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk, | ||
114 | SND_SOC_CLOCK_OUT); | ||
115 | if (ret < 0) { | ||
116 | dev_err(rtd->card->dev, "Can't set cpu clock out %d\n", ret); | ||
117 | return ret; | ||
118 | } | ||
119 | |||
120 | ret = snd_soc_dai_set_sysclk(codec_dai, RT5514_SCLK_S_MCLK, | ||
121 | mclk, SND_SOC_CLOCK_IN); | ||
122 | if (ret) { | ||
123 | dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n", | ||
124 | __func__, params_rate(params) * 512, ret); | ||
125 | return ret; | ||
126 | } | ||
127 | |||
128 | /* Wait for DMIC stable */ | ||
129 | msleep(rt5514_dmic_delay); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static int rockchip_sound_da7219_hw_params(struct snd_pcm_substream *substream, | ||
135 | struct snd_pcm_hw_params *params) | ||
136 | { | ||
137 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
138 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
139 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
140 | int mclk, ret; | ||
141 | |||
142 | /* in bypass mode, the mclk has to be one of the frequencies below */ | ||
143 | switch (params_rate(params)) { | ||
144 | case 8000: | ||
145 | case 16000: | ||
146 | case 24000: | ||
147 | case 32000: | ||
148 | case 48000: | ||
149 | case 64000: | ||
150 | case 96000: | ||
151 | mclk = 12288000; | ||
152 | break; | ||
153 | case 11025: | ||
154 | case 22050: | ||
155 | case 44100: | ||
156 | case 88200: | ||
157 | mclk = 11289600; | ||
158 | break; | ||
159 | default: | ||
160 | return -EINVAL; | ||
161 | } | ||
162 | |||
163 | ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk, | ||
164 | SND_SOC_CLOCK_OUT); | ||
165 | if (ret < 0) { | ||
166 | dev_err(codec_dai->dev, "Can't set cpu clock out %d\n", ret); | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, | ||
171 | SND_SOC_CLOCK_IN); | ||
172 | if (ret < 0) { | ||
173 | dev_err(codec_dai->dev, "Can't set codec clock in %d\n", ret); | ||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0); | ||
178 | if (ret < 0) { | ||
179 | dev_err(codec_dai->dev, "Can't set pll sysclk mclk %d\n", ret); | ||
180 | return ret; | ||
181 | } | ||
182 | |||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd) | ||
187 | { | ||
188 | struct snd_soc_codec *codec = rtd->codec_dais[0]->codec; | ||
189 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
190 | int ret; | ||
191 | |||
192 | /* We need default MCLK and PLL settings for the accessory detection */ | ||
193 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 12288000, | ||
194 | SND_SOC_CLOCK_IN); | ||
195 | if (ret < 0) { | ||
196 | dev_err(codec_dai->dev, "Init can't set codec clock in %d\n", ret); | ||
197 | return ret; | ||
198 | } | ||
199 | |||
200 | ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0); | ||
201 | if (ret < 0) { | ||
202 | dev_err(codec_dai->dev, "Init can't set pll sysclk mclk %d\n", ret); | ||
203 | return ret; | ||
204 | } | ||
205 | |||
206 | /* Enable Headset and 4 Buttons Jack detection */ | ||
207 | ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", | ||
208 | SND_JACK_HEADSET | SND_JACK_LINEOUT | | ||
209 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | | ||
210 | SND_JACK_BTN_2 | SND_JACK_BTN_3, | ||
211 | &rockchip_sound_jack, NULL, 0); | ||
212 | |||
213 | if (ret) { | ||
214 | dev_err(rtd->card->dev, "New Headset Jack failed! (%d)\n", ret); | ||
215 | return ret; | ||
216 | } | ||
217 | |||
218 | snd_jack_set_key(rockchip_sound_jack.jack, SND_JACK_BTN_0, KEY_MEDIA); | ||
219 | snd_jack_set_key( | ||
220 | rockchip_sound_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); | ||
221 | snd_jack_set_key( | ||
222 | rockchip_sound_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); | ||
223 | snd_jack_set_key( | ||
224 | rockchip_sound_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); | ||
225 | |||
226 | da7219_aad_jack_det(codec, &rockchip_sound_jack); | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static struct snd_soc_ops rockchip_sound_max98357a_ops = { | ||
232 | .hw_params = rockchip_sound_max98357a_hw_params, | ||
233 | }; | ||
234 | |||
235 | static struct snd_soc_ops rockchip_sound_rt5514_ops = { | ||
236 | .hw_params = rockchip_sound_rt5514_hw_params, | ||
237 | }; | ||
238 | |||
239 | static struct snd_soc_ops rockchip_sound_da7219_ops = { | ||
240 | .hw_params = rockchip_sound_da7219_hw_params, | ||
241 | }; | ||
242 | |||
243 | enum { | ||
244 | DAILINK_MAX98357A, | ||
245 | DAILINK_RT5514, | ||
246 | DAILINK_DA7219, | ||
247 | DAILINK_RT5514_DSP, | ||
248 | }; | ||
249 | |||
250 | #define DAILINK_ENTITIES (DAILINK_DA7219 + 1) | ||
251 | |||
252 | static struct snd_soc_dai_link rockchip_dailinks[] = { | ||
253 | [DAILINK_MAX98357A] = { | ||
254 | .name = "MAX98357A", | ||
255 | .stream_name = "MAX98357A PCM", | ||
256 | .codec_dai_name = "HiFi", | ||
257 | .ops = &rockchip_sound_max98357a_ops, | ||
258 | /* set max98357a as slave */ | ||
259 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
260 | SND_SOC_DAIFMT_CBS_CFS, | ||
261 | }, | ||
262 | [DAILINK_RT5514] = { | ||
263 | .name = "RT5514", | ||
264 | .stream_name = "RT5514 PCM", | ||
265 | .codec_dai_name = "rt5514-aif1", | ||
266 | .ops = &rockchip_sound_rt5514_ops, | ||
267 | /* set rt5514 as slave */ | ||
268 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
269 | SND_SOC_DAIFMT_CBS_CFS, | ||
270 | }, | ||
271 | [DAILINK_DA7219] = { | ||
272 | .name = "DA7219", | ||
273 | .stream_name = "DA7219 PCM", | ||
274 | .codec_dai_name = "da7219-hifi", | ||
275 | .init = rockchip_sound_da7219_init, | ||
276 | .ops = &rockchip_sound_da7219_ops, | ||
277 | /* set da7219 as slave */ | ||
278 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
279 | SND_SOC_DAIFMT_CBS_CFS, | ||
280 | }, | ||
281 | /* RT5514 DSP for voice wakeup via spi bus */ | ||
282 | [DAILINK_RT5514_DSP] = { | ||
283 | .name = "RT5514 DSP", | ||
284 | .stream_name = "Wake on Voice", | ||
285 | .codec_name = "snd-soc-dummy", | ||
286 | .codec_dai_name = "snd-soc-dummy-dai", | ||
287 | }, | ||
288 | }; | ||
289 | |||
290 | static struct snd_soc_card rockchip_sound_card = { | ||
291 | .name = "rk3399-gru-sound", | ||
292 | .owner = THIS_MODULE, | ||
293 | .dai_link = rockchip_dailinks, | ||
294 | .num_links = ARRAY_SIZE(rockchip_dailinks), | ||
295 | .dapm_widgets = rockchip_dapm_widgets, | ||
296 | .num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets), | ||
297 | .dapm_routes = rockchip_dapm_routes, | ||
298 | .num_dapm_routes = ARRAY_SIZE(rockchip_dapm_routes), | ||
299 | .controls = rockchip_controls, | ||
300 | .num_controls = ARRAY_SIZE(rockchip_controls), | ||
301 | }; | ||
302 | |||
303 | static int rockchip_sound_match_stub(struct device *dev, void *data) | ||
304 | { | ||
305 | return 1; | ||
306 | } | ||
307 | |||
308 | static int rockchip_sound_probe(struct platform_device *pdev) | ||
309 | { | ||
310 | struct snd_soc_card *card = &rockchip_sound_card; | ||
311 | struct device_node *cpu_node; | ||
312 | struct device *dev; | ||
313 | struct device_driver *drv; | ||
314 | int i, ret; | ||
315 | |||
316 | cpu_node = of_parse_phandle(pdev->dev.of_node, "rockchip,cpu", 0); | ||
317 | if (!cpu_node) { | ||
318 | dev_err(&pdev->dev, "Property 'rockchip,cpu' missing or invalid\n"); | ||
319 | return -EINVAL; | ||
320 | } | ||
321 | |||
322 | for (i = 0; i < DAILINK_ENTITIES; i++) { | ||
323 | rockchip_dailinks[i].platform_of_node = cpu_node; | ||
324 | rockchip_dailinks[i].cpu_of_node = cpu_node; | ||
325 | |||
326 | rockchip_dailinks[i].codec_of_node = | ||
327 | of_parse_phandle(pdev->dev.of_node, "rockchip,codec", i); | ||
328 | if (!rockchip_dailinks[i].codec_of_node) { | ||
329 | dev_err(&pdev->dev, | ||
330 | "Property[%d] 'rockchip,codec' missing or invalid\n", i); | ||
331 | return -EINVAL; | ||
332 | } | ||
333 | } | ||
334 | |||
335 | /** | ||
336 | * To acquire the spi driver of the rt5514 and set the dai-links names | ||
337 | * for soc_bind_dai_link | ||
338 | */ | ||
339 | drv = driver_find("rt5514", &spi_bus_type); | ||
340 | if (!drv) { | ||
341 | dev_err(&pdev->dev, "Can not find the rt5514 driver at the spi bus\n"); | ||
342 | return -EINVAL; | ||
343 | } | ||
344 | |||
345 | dev = driver_find_device(drv, NULL, NULL, rockchip_sound_match_stub); | ||
346 | if (!dev) { | ||
347 | dev_err(&pdev->dev, "Can not find the rt5514 device\n"); | ||
348 | return -ENODEV; | ||
349 | } | ||
350 | |||
351 | /* Set DMIC delay */ | ||
352 | ret = device_property_read_u32(&pdev->dev, "dmic-delay", | ||
353 | &rt5514_dmic_delay); | ||
354 | if (ret) { | ||
355 | rt5514_dmic_delay = 0; | ||
356 | dev_dbg(&pdev->dev, | ||
357 | "no optional property 'dmic-delay' found, default: no delay\n"); | ||
358 | } | ||
359 | |||
360 | rockchip_dailinks[DAILINK_RT5514_DSP].cpu_name = kstrdup_const(dev_name(dev), GFP_KERNEL); | ||
361 | rockchip_dailinks[DAILINK_RT5514_DSP].cpu_dai_name = kstrdup_const(dev_name(dev), GFP_KERNEL); | ||
362 | rockchip_dailinks[DAILINK_RT5514_DSP].platform_name = kstrdup_const(dev_name(dev), GFP_KERNEL); | ||
363 | |||
364 | card->dev = &pdev->dev; | ||
365 | platform_set_drvdata(pdev, card); | ||
366 | |||
367 | ret = devm_snd_soc_register_card(&pdev->dev, card); | ||
368 | if (ret) | ||
369 | dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", | ||
370 | __func__, ret); | ||
371 | |||
372 | return ret; | ||
373 | } | ||
374 | |||
375 | static const struct of_device_id rockchip_sound_of_match[] = { | ||
376 | { .compatible = "rockchip,rk3399-gru-sound", }, | ||
377 | {}, | ||
378 | }; | ||
379 | |||
380 | static struct platform_driver rockchip_sound_driver = { | ||
381 | .probe = rockchip_sound_probe, | ||
382 | .driver = { | ||
383 | .name = DRV_NAME, | ||
384 | .of_match_table = rockchip_sound_of_match, | ||
385 | #ifdef CONFIG_PM | ||
386 | .pm = &snd_soc_pm_ops, | ||
387 | #endif | ||
388 | }, | ||
389 | }; | ||
390 | |||
391 | module_platform_driver(rockchip_sound_driver); | ||
392 | |||
393 | MODULE_AUTHOR("Xing Zheng <zhengxing@rock-chips.com>"); | ||
394 | MODULE_DESCRIPTION("Rockchip ASoC Machine Driver"); | ||
395 | MODULE_LICENSE("GPL v2"); | ||
396 | MODULE_ALIAS("platform:" DRV_NAME); | ||
397 | MODULE_DEVICE_TABLE(of, rockchip_sound_of_match); | ||
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 652e8c5ea166..974915cb4c4f 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c | |||
@@ -57,6 +57,7 @@ static int i2s_runtime_suspend(struct device *dev) | |||
57 | { | 57 | { |
58 | struct rk_i2s_dev *i2s = dev_get_drvdata(dev); | 58 | struct rk_i2s_dev *i2s = dev_get_drvdata(dev); |
59 | 59 | ||
60 | regcache_cache_only(i2s->regmap, true); | ||
60 | clk_disable_unprepare(i2s->mclk); | 61 | clk_disable_unprepare(i2s->mclk); |
61 | 62 | ||
62 | return 0; | 63 | return 0; |
@@ -73,7 +74,14 @@ static int i2s_runtime_resume(struct device *dev) | |||
73 | return ret; | 74 | return ret; |
74 | } | 75 | } |
75 | 76 | ||
76 | return 0; | 77 | regcache_cache_only(i2s->regmap, false); |
78 | regcache_mark_dirty(i2s->regmap); | ||
79 | |||
80 | ret = regcache_sync(i2s->regmap); | ||
81 | if (ret) | ||
82 | clk_disable_unprepare(i2s->mclk); | ||
83 | |||
84 | return ret; | ||
77 | } | 85 | } |
78 | 86 | ||
79 | static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai) | 87 | static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai) |
diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c index 4ca265737eda..fa8101d1e16f 100644 --- a/sound/soc/rockchip/rockchip_spdif.c +++ b/sound/soc/rockchip/rockchip_spdif.c | |||
@@ -65,6 +65,7 @@ static int __maybe_unused rk_spdif_runtime_suspend(struct device *dev) | |||
65 | { | 65 | { |
66 | struct rk_spdif_dev *spdif = dev_get_drvdata(dev); | 66 | struct rk_spdif_dev *spdif = dev_get_drvdata(dev); |
67 | 67 | ||
68 | regcache_cache_only(spdif->regmap, true); | ||
68 | clk_disable_unprepare(spdif->mclk); | 69 | clk_disable_unprepare(spdif->mclk); |
69 | clk_disable_unprepare(spdif->hclk); | 70 | clk_disable_unprepare(spdif->hclk); |
70 | 71 | ||
@@ -88,7 +89,16 @@ static int __maybe_unused rk_spdif_runtime_resume(struct device *dev) | |||
88 | return ret; | 89 | return ret; |
89 | } | 90 | } |
90 | 91 | ||
91 | return 0; | 92 | regcache_cache_only(spdif->regmap, false); |
93 | regcache_mark_dirty(spdif->regmap); | ||
94 | |||
95 | ret = regcache_sync(spdif->regmap); | ||
96 | if (ret) { | ||
97 | clk_disable_unprepare(spdif->mclk); | ||
98 | clk_disable_unprepare(spdif->hclk); | ||
99 | } | ||
100 | |||
101 | return ret; | ||
92 | } | 102 | } |
93 | 103 | ||
94 | static int rk_spdif_hw_params(struct snd_pcm_substream *substream, | 104 | static int rk_spdif_hw_params(struct snd_pcm_substream *substream, |
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 7b722b0094d9..f6023b46c107 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig | |||
@@ -1,12 +1,14 @@ | |||
1 | config SND_SOC_SAMSUNG | 1 | menuconfig SND_SOC_SAMSUNG |
2 | tristate "ASoC support for Samsung" | 2 | tristate "ASoC support for Samsung" |
3 | depends on (PLAT_SAMSUNG || ARCH_EXYNOS) | 3 | depends on (PLAT_SAMSUNG || ARCH_EXYNOS) |
4 | select SND_SOC_GENERIC_DMAENGINE_PCM | 4 | select SND_SOC_GENERIC_DMAENGINE_PCM |
5 | help | 5 | ---help--- |
6 | Say Y or M if you want to add support for codecs attached to | 6 | Say Y or M if you want to add support for codecs attached to |
7 | the Samsung SoCs' Audio interfaces. You will also need to | 7 | the Samsung SoCs' Audio interfaces. You will also need to |
8 | select the audio interfaces to support below. | 8 | select the audio interfaces to support below. |
9 | 9 | ||
10 | if SND_SOC_SAMSUNG | ||
11 | |||
10 | config SND_S3C24XX_I2S | 12 | config SND_S3C24XX_I2S |
11 | tristate | 13 | tristate |
12 | 14 | ||
@@ -18,22 +20,22 @@ config SND_S3C2412_SOC_I2S | |||
18 | select SND_S3C_I2SV2_SOC | 20 | select SND_S3C_I2SV2_SOC |
19 | 21 | ||
20 | config SND_SAMSUNG_PCM | 22 | config SND_SAMSUNG_PCM |
21 | tristate | 23 | tristate "Samsung PCM interface support" |
22 | 24 | ||
23 | config SND_SAMSUNG_AC97 | 25 | config SND_SAMSUNG_AC97 |
24 | tristate | 26 | tristate |
25 | select SND_SOC_AC97_BUS | 27 | select SND_SOC_AC97_BUS |
26 | 28 | ||
27 | config SND_SAMSUNG_SPDIF | 29 | config SND_SAMSUNG_SPDIF |
28 | tristate | 30 | tristate "Samsung SPDIF transmitter support" |
29 | select SND_SOC_SPDIF | 31 | select SND_SOC_SPDIF |
30 | 32 | ||
31 | config SND_SAMSUNG_I2S | 33 | config SND_SAMSUNG_I2S |
32 | tristate | 34 | tristate "Samsung I2S interface support" |
33 | 35 | ||
34 | config SND_SOC_SAMSUNG_NEO1973_WM8753 | 36 | config SND_SOC_SAMSUNG_NEO1973_WM8753 |
35 | tristate "Audio support for Openmoko Neo1973 Smartphones (GTA02)" | 37 | tristate "Audio support for Openmoko Neo1973 Smartphones (GTA02)" |
36 | depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA02 | 38 | depends on MACH_NEO1973_GTA02 |
37 | select SND_S3C24XX_I2S | 39 | select SND_S3C24XX_I2S |
38 | select SND_SOC_WM8753 | 40 | select SND_SOC_WM8753 |
39 | select SND_SOC_BT_SCO | 41 | select SND_SOC_BT_SCO |
@@ -43,7 +45,7 @@ config SND_SOC_SAMSUNG_NEO1973_WM8753 | |||
43 | 45 | ||
44 | config SND_SOC_SAMSUNG_JIVE_WM8750 | 46 | config SND_SOC_SAMSUNG_JIVE_WM8750 |
45 | tristate "SoC I2S Audio support for Jive" | 47 | tristate "SoC I2S Audio support for Jive" |
46 | depends on SND_SOC_SAMSUNG && MACH_JIVE && I2C | 48 | depends on MACH_JIVE && I2C |
47 | select SND_SOC_WM8750 | 49 | select SND_SOC_WM8750 |
48 | select SND_S3C2412_SOC_I2S | 50 | select SND_S3C2412_SOC_I2S |
49 | help | 51 | help |
@@ -51,7 +53,7 @@ config SND_SOC_SAMSUNG_JIVE_WM8750 | |||
51 | 53 | ||
52 | config SND_SOC_SAMSUNG_SMDK_WM8580 | 54 | config SND_SOC_SAMSUNG_SMDK_WM8580 |
53 | tristate "SoC I2S Audio support for WM8580 on SMDK" | 55 | tristate "SoC I2S Audio support for WM8580 on SMDK" |
54 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) | 56 | depends on MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110 |
55 | depends on I2C | 57 | depends on I2C |
56 | select SND_SOC_WM8580 | 58 | select SND_SOC_WM8580 |
57 | select SND_SAMSUNG_I2S | 59 | select SND_SAMSUNG_I2S |
@@ -60,7 +62,6 @@ config SND_SOC_SAMSUNG_SMDK_WM8580 | |||
60 | 62 | ||
61 | config SND_SOC_SAMSUNG_SMDK_WM8994 | 63 | config SND_SOC_SAMSUNG_SMDK_WM8994 |
62 | tristate "SoC I2S Audio support for WM8994 on SMDK" | 64 | tristate "SoC I2S Audio support for WM8994 on SMDK" |
63 | depends on SND_SOC_SAMSUNG | ||
64 | depends on I2C=y | 65 | depends on I2C=y |
65 | select MFD_WM8994 | 66 | select MFD_WM8994 |
66 | select SND_SOC_WM8994 | 67 | select SND_SOC_WM8994 |
@@ -70,7 +71,7 @@ config SND_SOC_SAMSUNG_SMDK_WM8994 | |||
70 | 71 | ||
71 | config SND_SOC_SAMSUNG_SMDK2443_WM9710 | 72 | config SND_SOC_SAMSUNG_SMDK2443_WM9710 |
72 | tristate "SoC AC97 Audio support for SMDK2443 - WM9710" | 73 | tristate "SoC AC97 Audio support for SMDK2443 - WM9710" |
73 | depends on SND_SOC_SAMSUNG && MACH_SMDK2443 | 74 | depends on MACH_SMDK2443 |
74 | select AC97_BUS | 75 | select AC97_BUS |
75 | select SND_SOC_AC97_CODEC | 76 | select SND_SOC_AC97_CODEC |
76 | select SND_SAMSUNG_AC97 | 77 | select SND_SAMSUNG_AC97 |
@@ -80,7 +81,7 @@ config SND_SOC_SAMSUNG_SMDK2443_WM9710 | |||
80 | 81 | ||
81 | config SND_SOC_SAMSUNG_LN2440SBC_ALC650 | 82 | config SND_SOC_SAMSUNG_LN2440SBC_ALC650 |
82 | tristate "SoC AC97 Audio support for LN2440SBC - ALC650" | 83 | tristate "SoC AC97 Audio support for LN2440SBC - ALC650" |
83 | depends on SND_SOC_SAMSUNG && ARCH_S3C24XX | 84 | depends on ARCH_S3C24XX |
84 | select AC97_BUS | 85 | select AC97_BUS |
85 | select SND_SOC_AC97_CODEC | 86 | select SND_SOC_AC97_CODEC |
86 | select SND_SAMSUNG_AC97 | 87 | select SND_SAMSUNG_AC97 |
@@ -90,7 +91,7 @@ config SND_SOC_SAMSUNG_LN2440SBC_ALC650 | |||
90 | 91 | ||
91 | config SND_SOC_SAMSUNG_S3C24XX_UDA134X | 92 | config SND_SOC_SAMSUNG_S3C24XX_UDA134X |
92 | tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" | 93 | tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" |
93 | depends on SND_SOC_SAMSUNG && ARCH_S3C24XX | 94 | depends on ARCH_S3C24XX |
94 | select SND_S3C24XX_I2S | 95 | select SND_S3C24XX_I2S |
95 | select SND_SOC_L3 | 96 | select SND_SOC_L3 |
96 | select SND_SOC_UDA134X | 97 | select SND_SOC_UDA134X |
@@ -102,21 +103,21 @@ config SND_SOC_SAMSUNG_SIMTEC | |||
102 | 103 | ||
103 | config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23 | 104 | config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23 |
104 | tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" | 105 | tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" |
105 | depends on SND_SOC_SAMSUNG && ARCH_S3C24XX && I2C | 106 | depends on ARCH_S3C24XX && I2C |
106 | select SND_S3C24XX_I2S | 107 | select SND_S3C24XX_I2S |
107 | select SND_SOC_TLV320AIC23_I2C | 108 | select SND_SOC_TLV320AIC23_I2C |
108 | select SND_SOC_SAMSUNG_SIMTEC | 109 | select SND_SOC_SAMSUNG_SIMTEC |
109 | 110 | ||
110 | config SND_SOC_SAMSUNG_SIMTEC_HERMES | 111 | config SND_SOC_SAMSUNG_SIMTEC_HERMES |
111 | tristate "SoC I2S Audio support for Simtec Hermes board" | 112 | tristate "SoC I2S Audio support for Simtec Hermes board" |
112 | depends on SND_SOC_SAMSUNG && ARCH_S3C24XX && I2C | 113 | depends on ARCH_S3C24XX && I2C |
113 | select SND_S3C24XX_I2S | 114 | select SND_S3C24XX_I2S |
114 | select SND_SOC_TLV320AIC3X | 115 | select SND_SOC_TLV320AIC3X |
115 | select SND_SOC_SAMSUNG_SIMTEC | 116 | select SND_SOC_SAMSUNG_SIMTEC |
116 | 117 | ||
117 | config SND_SOC_SAMSUNG_H1940_UDA1380 | 118 | config SND_SOC_SAMSUNG_H1940_UDA1380 |
118 | tristate "Audio support for the HP iPAQ H1940" | 119 | tristate "Audio support for the HP iPAQ H1940" |
119 | depends on SND_SOC_SAMSUNG && ARCH_H1940 && I2C | 120 | depends on ARCH_H1940 && I2C |
120 | select SND_S3C24XX_I2S | 121 | select SND_S3C24XX_I2S |
121 | select SND_SOC_UDA1380 | 122 | select SND_SOC_UDA1380 |
122 | help | 123 | help |
@@ -124,7 +125,7 @@ config SND_SOC_SAMSUNG_H1940_UDA1380 | |||
124 | 125 | ||
125 | config SND_SOC_SAMSUNG_RX1950_UDA1380 | 126 | config SND_SOC_SAMSUNG_RX1950_UDA1380 |
126 | tristate "Audio support for the HP iPAQ RX1950" | 127 | tristate "Audio support for the HP iPAQ RX1950" |
127 | depends on SND_SOC_SAMSUNG && MACH_RX1950 && I2C | 128 | depends on MACH_RX1950 && I2C |
128 | select SND_S3C24XX_I2S | 129 | select SND_S3C24XX_I2S |
129 | select SND_SOC_UDA1380 | 130 | select SND_SOC_UDA1380 |
130 | help | 131 | help |
@@ -132,7 +133,7 @@ config SND_SOC_SAMSUNG_RX1950_UDA1380 | |||
132 | 133 | ||
133 | config SND_SOC_SAMSUNG_SMDK_WM9713 | 134 | config SND_SOC_SAMSUNG_SMDK_WM9713 |
134 | tristate "SoC AC97 Audio support for SMDK with WM9713" | 135 | tristate "SoC AC97 Audio support for SMDK with WM9713" |
135 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) | 136 | depends on MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110 |
136 | select SND_SOC_WM9713 | 137 | select SND_SOC_WM9713 |
137 | select SND_SAMSUNG_AC97 | 138 | select SND_SAMSUNG_AC97 |
138 | help | 139 | help |
@@ -140,20 +141,19 @@ config SND_SOC_SAMSUNG_SMDK_WM9713 | |||
140 | 141 | ||
141 | config SND_SOC_SMARTQ | 142 | config SND_SOC_SMARTQ |
142 | tristate "SoC I2S Audio support for SmartQ board" | 143 | tristate "SoC I2S Audio support for SmartQ board" |
143 | depends on SND_SOC_SAMSUNG && MACH_SMARTQ && I2C | 144 | depends on MACH_SMARTQ && I2C |
144 | select SND_SAMSUNG_I2S | 145 | select SND_SAMSUNG_I2S |
145 | select SND_SOC_WM8750 | 146 | select SND_SOC_WM8750 |
146 | 147 | ||
147 | config SND_SOC_SAMSUNG_SMDK_SPDIF | 148 | config SND_SOC_SAMSUNG_SMDK_SPDIF |
148 | tristate "SoC S/PDIF Audio support for SMDK" | 149 | tristate "SoC S/PDIF Audio support for SMDK" |
149 | depends on SND_SOC_SAMSUNG | ||
150 | select SND_SAMSUNG_SPDIF | 150 | select SND_SAMSUNG_SPDIF |
151 | help | 151 | help |
152 | Say Y if you want to add support for SoC S/PDIF audio on the SMDK. | 152 | Say Y if you want to add support for SoC S/PDIF audio on the SMDK. |
153 | 153 | ||
154 | config SND_SOC_SMDK_WM8580_PCM | 154 | config SND_SOC_SMDK_WM8580_PCM |
155 | tristate "SoC PCM Audio support for WM8580 on SMDK" | 155 | tristate "SoC PCM Audio support for WM8580 on SMDK" |
156 | depends on SND_SOC_SAMSUNG && (MACH_SMDKV210 || MACH_SMDKC110) | 156 | depends on MACH_SMDKV210 || MACH_SMDKC110 |
157 | depends on I2C | 157 | depends on I2C |
158 | select SND_SOC_WM8580 | 158 | select SND_SOC_WM8580 |
159 | select SND_SAMSUNG_PCM | 159 | select SND_SAMSUNG_PCM |
@@ -162,7 +162,6 @@ config SND_SOC_SMDK_WM8580_PCM | |||
162 | 162 | ||
163 | config SND_SOC_SMDK_WM8994_PCM | 163 | config SND_SOC_SMDK_WM8994_PCM |
164 | tristate "SoC PCM Audio support for WM8994 on SMDK" | 164 | tristate "SoC PCM Audio support for WM8994 on SMDK" |
165 | depends on SND_SOC_SAMSUNG | ||
166 | depends on I2C=y | 165 | depends on I2C=y |
167 | select MFD_WM8994 | 166 | select MFD_WM8994 |
168 | select SND_SOC_WM8994 | 167 | select SND_SOC_WM8994 |
@@ -172,7 +171,7 @@ config SND_SOC_SMDK_WM8994_PCM | |||
172 | 171 | ||
173 | config SND_SOC_SPEYSIDE | 172 | config SND_SOC_SPEYSIDE |
174 | tristate "Audio support for Wolfson Speyside" | 173 | tristate "Audio support for Wolfson Speyside" |
175 | depends on SND_SOC_SAMSUNG && I2C && SPI_MASTER | 174 | depends on I2C && SPI_MASTER |
176 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST | 175 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST |
177 | select SND_SAMSUNG_I2S | 176 | select SND_SAMSUNG_I2S |
178 | select SND_SOC_WM8996 | 177 | select SND_SOC_WM8996 |
@@ -182,14 +181,14 @@ config SND_SOC_SPEYSIDE | |||
182 | 181 | ||
183 | config SND_SOC_TOBERMORY | 182 | config SND_SOC_TOBERMORY |
184 | tristate "Audio support for Wolfson Tobermory" | 183 | tristate "Audio support for Wolfson Tobermory" |
185 | depends on SND_SOC_SAMSUNG && INPUT && I2C | 184 | depends on INPUT && I2C |
186 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST | 185 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST |
187 | select SND_SAMSUNG_I2S | 186 | select SND_SAMSUNG_I2S |
188 | select SND_SOC_WM8962 | 187 | select SND_SOC_WM8962 |
189 | 188 | ||
190 | config SND_SOC_BELLS | 189 | config SND_SOC_BELLS |
191 | tristate "Audio support for Wolfson Bells" | 190 | tristate "Audio support for Wolfson Bells" |
192 | depends on SND_SOC_SAMSUNG && MFD_ARIZONA && I2C && SPI_MASTER | 191 | depends on MFD_ARIZONA && I2C && SPI_MASTER |
193 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST | 192 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST |
194 | select SND_SAMSUNG_I2S | 193 | select SND_SAMSUNG_I2S |
195 | select SND_SOC_WM5102 | 194 | select SND_SOC_WM5102 |
@@ -200,7 +199,7 @@ config SND_SOC_BELLS | |||
200 | 199 | ||
201 | config SND_SOC_LOWLAND | 200 | config SND_SOC_LOWLAND |
202 | tristate "Audio support for Wolfson Lowland" | 201 | tristate "Audio support for Wolfson Lowland" |
203 | depends on SND_SOC_SAMSUNG && I2C | 202 | depends on I2C |
204 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST | 203 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST |
205 | select SND_SAMSUNG_I2S | 204 | select SND_SAMSUNG_I2S |
206 | select SND_SOC_WM5100 | 205 | select SND_SOC_WM5100 |
@@ -208,7 +207,7 @@ config SND_SOC_LOWLAND | |||
208 | 207 | ||
209 | config SND_SOC_LITTLEMILL | 208 | config SND_SOC_LITTLEMILL |
210 | tristate "Audio support for Wolfson Littlemill" | 209 | tristate "Audio support for Wolfson Littlemill" |
211 | depends on SND_SOC_SAMSUNG && I2C | 210 | depends on I2C |
212 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST | 211 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST |
213 | select SND_SAMSUNG_I2S | 212 | select SND_SAMSUNG_I2S |
214 | select MFD_WM8994 | 213 | select MFD_WM8994 |
@@ -216,7 +215,7 @@ config SND_SOC_LITTLEMILL | |||
216 | 215 | ||
217 | config SND_SOC_SNOW | 216 | config SND_SOC_SNOW |
218 | tristate "Audio support for Google Snow boards" | 217 | tristate "Audio support for Google Snow boards" |
219 | depends on SND_SOC_SAMSUNG && I2C | 218 | depends on I2C |
220 | select SND_SOC_MAX98090 | 219 | select SND_SOC_MAX98090 |
221 | select SND_SOC_MAX98095 | 220 | select SND_SOC_MAX98095 |
222 | select SND_SAMSUNG_I2S | 221 | select SND_SAMSUNG_I2S |
@@ -226,6 +225,8 @@ config SND_SOC_SNOW | |||
226 | 225 | ||
227 | config SND_SOC_ARNDALE_RT5631_ALC5631 | 226 | config SND_SOC_ARNDALE_RT5631_ALC5631 |
228 | tristate "Audio support for RT5631(ALC5631) on Arndale Board" | 227 | tristate "Audio support for RT5631(ALC5631) on Arndale Board" |
229 | depends on SND_SOC_SAMSUNG && I2C | 228 | depends on I2C |
230 | select SND_SAMSUNG_I2S | 229 | select SND_SAMSUNG_I2S |
231 | select SND_SOC_RT5631 | 230 | select SND_SOC_RT5631 |
231 | |||
232 | endif #SND_SOC_SAMSUNG | ||
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index 547d31032088..97d6700b1009 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c | |||
@@ -38,16 +38,16 @@ struct s3c_ac97_info { | |||
38 | }; | 38 | }; |
39 | static struct s3c_ac97_info s3c_ac97; | 39 | static struct s3c_ac97_info s3c_ac97; |
40 | 40 | ||
41 | static struct s3c_dma_params s3c_ac97_pcm_out = { | 41 | static struct snd_dmaengine_dai_dma_data s3c_ac97_pcm_out = { |
42 | .dma_size = 4, | 42 | .addr_width = 4, |
43 | }; | 43 | }; |
44 | 44 | ||
45 | static struct s3c_dma_params s3c_ac97_pcm_in = { | 45 | static struct snd_dmaengine_dai_dma_data s3c_ac97_pcm_in = { |
46 | .dma_size = 4, | 46 | .addr_width = 4, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static struct s3c_dma_params s3c_ac97_mic_in = { | 49 | static struct snd_dmaengine_dai_dma_data s3c_ac97_mic_in = { |
50 | .dma_size = 4, | 50 | .addr_width = 4, |
51 | }; | 51 | }; |
52 | 52 | ||
53 | static void s3c_ac97_activate(struct snd_ac97 *ac97) | 53 | static void s3c_ac97_activate(struct snd_ac97 *ac97) |
@@ -74,7 +74,7 @@ static void s3c_ac97_activate(struct snd_ac97 *ac97) | |||
74 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); | 74 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); |
75 | 75 | ||
76 | if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) | 76 | if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) |
77 | pr_err("AC97: Unable to activate!"); | 77 | pr_err("AC97: Unable to activate!\n"); |
78 | } | 78 | } |
79 | 79 | ||
80 | static unsigned short s3c_ac97_read(struct snd_ac97 *ac97, | 80 | static unsigned short s3c_ac97_read(struct snd_ac97 *ac97, |
@@ -100,7 +100,7 @@ static unsigned short s3c_ac97_read(struct snd_ac97 *ac97, | |||
100 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); | 100 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); |
101 | 101 | ||
102 | if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) | 102 | if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) |
103 | pr_err("AC97: Unable to read!"); | 103 | pr_err("AC97: Unable to read!\n"); |
104 | 104 | ||
105 | stat = readl(s3c_ac97.regs + S3C_AC97_STAT); | 105 | stat = readl(s3c_ac97.regs + S3C_AC97_STAT); |
106 | addr = (stat >> 16) & 0x7f; | 106 | addr = (stat >> 16) & 0x7f; |
@@ -137,7 +137,7 @@ static void s3c_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | |||
137 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); | 137 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); |
138 | 138 | ||
139 | if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) | 139 | if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) |
140 | pr_err("AC97: Unable to write!"); | 140 | pr_err("AC97: Unable to write!\n"); |
141 | 141 | ||
142 | ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); | 142 | ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); |
143 | ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; | 143 | ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; |
@@ -273,14 +273,14 @@ static const struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = { | |||
273 | 273 | ||
274 | static int s3c_ac97_dai_probe(struct snd_soc_dai *dai) | 274 | static int s3c_ac97_dai_probe(struct snd_soc_dai *dai) |
275 | { | 275 | { |
276 | samsung_asoc_init_dma_data(dai, &s3c_ac97_pcm_out, &s3c_ac97_pcm_in); | 276 | snd_soc_dai_init_dma_data(dai, &s3c_ac97_pcm_out, &s3c_ac97_pcm_in); |
277 | 277 | ||
278 | return 0; | 278 | return 0; |
279 | } | 279 | } |
280 | 280 | ||
281 | static int s3c_ac97_mic_dai_probe(struct snd_soc_dai *dai) | 281 | static int s3c_ac97_mic_dai_probe(struct snd_soc_dai *dai) |
282 | { | 282 | { |
283 | samsung_asoc_init_dma_data(dai, NULL, &s3c_ac97_mic_in); | 283 | snd_soc_dai_init_dma_data(dai, NULL, &s3c_ac97_mic_in); |
284 | 284 | ||
285 | return 0; | 285 | return 0; |
286 | } | 286 | } |
@@ -346,12 +346,12 @@ static int s3c_ac97_probe(struct platform_device *pdev) | |||
346 | if (IS_ERR(s3c_ac97.regs)) | 346 | if (IS_ERR(s3c_ac97.regs)) |
347 | return PTR_ERR(s3c_ac97.regs); | 347 | return PTR_ERR(s3c_ac97.regs); |
348 | 348 | ||
349 | s3c_ac97_pcm_out.slave = ac97_pdata->dma_playback; | 349 | s3c_ac97_pcm_out.filter_data = ac97_pdata->dma_playback; |
350 | s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; | 350 | s3c_ac97_pcm_out.addr = mem_res->start + S3C_AC97_PCM_DATA; |
351 | s3c_ac97_pcm_in.slave = ac97_pdata->dma_capture; | 351 | s3c_ac97_pcm_in.filter_data = ac97_pdata->dma_capture; |
352 | s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; | 352 | s3c_ac97_pcm_in.addr = mem_res->start + S3C_AC97_PCM_DATA; |
353 | s3c_ac97_mic_in.slave = ac97_pdata->dma_capture_mic; | 353 | s3c_ac97_mic_in.filter_data = ac97_pdata->dma_capture_mic; |
354 | s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA; | 354 | s3c_ac97_mic_in.addr = mem_res->start + S3C_AC97_MIC_DATA; |
355 | 355 | ||
356 | init_completion(&s3c_ac97.done); | 356 | init_completion(&s3c_ac97.done); |
357 | mutex_init(&s3c_ac97.lock); | 357 | mutex_init(&s3c_ac97.lock); |
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h index 3830f297e0b6..7ae580d677c8 100644 --- a/sound/soc/samsung/dma.h +++ b/sound/soc/samsung/dma.h | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * dma.h -- | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | 2 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License as published by the | 3 | * under the terms of the GNU General Public License as published by the |
6 | * Free Software Foundation; either version 2 of the License, or (at your | 4 | * Free Software Foundation; either version 2 of the License, or (at your |
@@ -9,27 +7,15 @@ | |||
9 | * ALSA PCM interface for the Samsung SoC | 7 | * ALSA PCM interface for the Samsung SoC |
10 | */ | 8 | */ |
11 | 9 | ||
12 | #ifndef _S3C_AUDIO_H | 10 | #ifndef _SAMSUNG_DMA_H |
13 | #define _S3C_AUDIO_H | 11 | #define _SAMSUNG_DMA_H |
14 | 12 | ||
15 | #include <sound/dmaengine_pcm.h> | 13 | #include <sound/dmaengine_pcm.h> |
16 | #include <linux/dmaengine.h> | ||
17 | |||
18 | struct s3c_dma_params { | ||
19 | void *slave; /* Channel ID */ | ||
20 | dma_addr_t dma_addr; | ||
21 | int dma_size; /* Size of the DMA transfer */ | ||
22 | char *ch_name; | ||
23 | struct snd_dmaengine_dai_dma_data dma_data; | ||
24 | }; | ||
25 | 14 | ||
26 | void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, | ||
27 | struct s3c_dma_params *playback, | ||
28 | struct s3c_dma_params *capture); | ||
29 | /* | 15 | /* |
30 | * @tx, @rx arguments can be NULL if the DMA channel names are "tx", "rx", | 16 | * @tx, @rx arguments can be NULL if the DMA channel names are "tx", "rx", |
31 | * otherwise actual DMA channel names must be passed to this function. | 17 | * otherwise actual DMA channel names must be passed to this function. |
32 | */ | 18 | */ |
33 | int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter, | 19 | int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter, |
34 | const char *tx, const char *rx); | 20 | const char *tx, const char *rx); |
35 | #endif | 21 | #endif /* _SAMSUNG_DMA_H */ |
diff --git a/sound/soc/samsung/dmaengine.c b/sound/soc/samsung/dmaengine.c index 2c87f380bfc4..9104c98deeb7 100644 --- a/sound/soc/samsung/dmaengine.c +++ b/sound/soc/samsung/dmaengine.c | |||
@@ -16,49 +16,18 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/amba/pl08x.h> | ||
20 | #include <linux/platform_data/dma-s3c24xx.h> | ||
21 | |||
22 | #include <sound/core.h> | 19 | #include <sound/core.h> |
23 | #include <sound/pcm.h> | 20 | #include <sound/pcm.h> |
24 | #include <sound/pcm_params.h> | 21 | #include <sound/pcm_params.h> |
25 | #include <sound/dmaengine_pcm.h> | 22 | #include <sound/dmaengine_pcm.h> |
26 | #include <sound/soc.h> | 23 | #include <sound/soc.h> |
27 | #include <sound/soc-dai.h> | ||
28 | 24 | ||
29 | #include "dma.h" | 25 | #include "dma.h" |
30 | 26 | ||
31 | void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, | ||
32 | struct s3c_dma_params *playback, | ||
33 | struct s3c_dma_params *capture) | ||
34 | { | ||
35 | struct snd_dmaengine_dai_dma_data *playback_data = NULL; | ||
36 | struct snd_dmaengine_dai_dma_data *capture_data = NULL; | ||
37 | |||
38 | if (playback) { | ||
39 | playback_data = &playback->dma_data; | ||
40 | playback_data->filter_data = playback->slave; | ||
41 | playback_data->chan_name = playback->ch_name; | ||
42 | playback_data->addr = playback->dma_addr; | ||
43 | playback_data->addr_width = playback->dma_size; | ||
44 | } | ||
45 | if (capture) { | ||
46 | capture_data = &capture->dma_data; | ||
47 | capture_data->filter_data = capture->slave; | ||
48 | capture_data->chan_name = capture->ch_name; | ||
49 | capture_data->addr = capture->dma_addr; | ||
50 | capture_data->addr_width = capture->dma_size; | ||
51 | } | ||
52 | |||
53 | snd_soc_dai_init_dma_data(dai, playback_data, capture_data); | ||
54 | } | ||
55 | EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data); | ||
56 | |||
57 | int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter, | 27 | int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter, |
58 | const char *tx, const char *rx) | 28 | const char *tx, const char *rx) |
59 | { | 29 | { |
60 | unsigned int flags = SND_DMAENGINE_PCM_FLAG_COMPAT; | 30 | unsigned int flags = SND_DMAENGINE_PCM_FLAG_COMPAT; |
61 | |||
62 | struct snd_dmaengine_pcm_config *pcm_conf; | 31 | struct snd_dmaengine_pcm_config *pcm_conf; |
63 | 32 | ||
64 | pcm_conf = devm_kzalloc(dev, sizeof(*pcm_conf), GFP_KERNEL); | 33 | pcm_conf = devm_kzalloc(dev, sizeof(*pcm_conf), GFP_KERNEL); |
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 50635ee8ff20..7e32cf4581f8 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c | |||
@@ -87,9 +87,9 @@ struct i2s_dai { | |||
87 | /* Driver for this DAI */ | 87 | /* Driver for this DAI */ |
88 | struct snd_soc_dai_driver i2s_dai_drv; | 88 | struct snd_soc_dai_driver i2s_dai_drv; |
89 | /* DMA parameters */ | 89 | /* DMA parameters */ |
90 | struct s3c_dma_params dma_playback; | 90 | struct snd_dmaengine_dai_dma_data dma_playback; |
91 | struct s3c_dma_params dma_capture; | 91 | struct snd_dmaengine_dai_dma_data dma_capture; |
92 | struct s3c_dma_params idma_playback; | 92 | struct snd_dmaengine_dai_dma_data idma_playback; |
93 | dma_filter_fn filter; | 93 | dma_filter_fn filter; |
94 | u32 quirks; | 94 | u32 quirks; |
95 | u32 suspend_i2smod; | 95 | u32 suspend_i2smod; |
@@ -692,15 +692,15 @@ static int i2s_hw_params(struct snd_pcm_substream *substream, | |||
692 | break; | 692 | break; |
693 | case 2: | 693 | case 2: |
694 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 694 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
695 | i2s->dma_playback.dma_size = 4; | 695 | i2s->dma_playback.addr_width = 4; |
696 | else | 696 | else |
697 | i2s->dma_capture.dma_size = 4; | 697 | i2s->dma_capture.addr_width = 4; |
698 | break; | 698 | break; |
699 | case 1: | 699 | case 1: |
700 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 700 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
701 | i2s->dma_playback.dma_size = 2; | 701 | i2s->dma_playback.addr_width = 2; |
702 | else | 702 | else |
703 | i2s->dma_capture.dma_size = 2; | 703 | i2s->dma_capture.addr_width = 2; |
704 | 704 | ||
705 | break; | 705 | break; |
706 | default: | 706 | default: |
@@ -754,7 +754,7 @@ static int i2s_hw_params(struct snd_pcm_substream *substream, | |||
754 | writel(mod, i2s->addr + I2SMOD); | 754 | writel(mod, i2s->addr + I2SMOD); |
755 | spin_unlock_irqrestore(i2s->lock, flags); | 755 | spin_unlock_irqrestore(i2s->lock, flags); |
756 | 756 | ||
757 | samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); | 757 | snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); |
758 | 758 | ||
759 | i2s->frmclk = params_rate(params); | 759 | i2s->frmclk = params_rate(params); |
760 | 760 | ||
@@ -991,10 +991,10 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) | |||
991 | unsigned long flags; | 991 | unsigned long flags; |
992 | 992 | ||
993 | if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */ | 993 | if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */ |
994 | samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback, | 994 | snd_soc_dai_init_dma_data(dai, &other->sec_dai->dma_playback, |
995 | NULL); | 995 | NULL); |
996 | } else { | 996 | } else { |
997 | samsung_asoc_init_dma_data(dai, &i2s->dma_playback, | 997 | snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, |
998 | &i2s->dma_capture); | 998 | &i2s->dma_capture); |
999 | 999 | ||
1000 | if (i2s->quirks & QUIRK_NEED_RSTCLR) | 1000 | if (i2s->quirks & QUIRK_NEED_RSTCLR) |
@@ -1002,7 +1002,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) | |||
1002 | 1002 | ||
1003 | if (i2s->quirks & QUIRK_SUPPORTS_IDMA) | 1003 | if (i2s->quirks & QUIRK_SUPPORTS_IDMA) |
1004 | idma_reg_addr_init(i2s->addr, | 1004 | idma_reg_addr_init(i2s->addr, |
1005 | i2s->sec_dai->idma_playback.dma_addr); | 1005 | i2s->sec_dai->idma_playback.addr); |
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | /* Reset any constraint on RFS and BFS */ | 1008 | /* Reset any constraint on RFS and BFS */ |
@@ -1262,8 +1262,8 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1262 | return -EINVAL; | 1262 | return -EINVAL; |
1263 | } | 1263 | } |
1264 | 1264 | ||
1265 | pri_dai->dma_playback.slave = i2s_pdata->dma_playback; | 1265 | pri_dai->dma_playback.filter_data = i2s_pdata->dma_playback; |
1266 | pri_dai->dma_capture.slave = i2s_pdata->dma_capture; | 1266 | pri_dai->dma_capture.filter_data = i2s_pdata->dma_capture; |
1267 | pri_dai->filter = i2s_pdata->dma_filter; | 1267 | pri_dai->filter = i2s_pdata->dma_filter; |
1268 | 1268 | ||
1269 | if (&i2s_pdata->type) | 1269 | if (&i2s_pdata->type) |
@@ -1302,12 +1302,12 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1302 | dev_err(&pdev->dev, "failed to enable clock: %d\n", ret); | 1302 | dev_err(&pdev->dev, "failed to enable clock: %d\n", ret); |
1303 | return ret; | 1303 | return ret; |
1304 | } | 1304 | } |
1305 | pri_dai->dma_playback.dma_addr = regs_base + I2STXD; | 1305 | pri_dai->dma_playback.addr = regs_base + I2STXD; |
1306 | pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; | 1306 | pri_dai->dma_capture.addr = regs_base + I2SRXD; |
1307 | pri_dai->dma_playback.ch_name = "tx"; | 1307 | pri_dai->dma_playback.chan_name = "tx"; |
1308 | pri_dai->dma_capture.ch_name = "rx"; | 1308 | pri_dai->dma_capture.chan_name = "rx"; |
1309 | pri_dai->dma_playback.dma_size = 4; | 1309 | pri_dai->dma_playback.addr_width = 4; |
1310 | pri_dai->dma_capture.dma_size = 4; | 1310 | pri_dai->dma_capture.addr_width = 4; |
1311 | pri_dai->quirks = quirks; | 1311 | pri_dai->quirks = quirks; |
1312 | pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs; | 1312 | pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs; |
1313 | 1313 | ||
@@ -1318,31 +1318,33 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1318 | sec_dai = i2s_alloc_dai(pdev, true); | 1318 | sec_dai = i2s_alloc_dai(pdev, true); |
1319 | if (!sec_dai) { | 1319 | if (!sec_dai) { |
1320 | dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); | 1320 | dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); |
1321 | return -ENOMEM; | 1321 | ret = -ENOMEM; |
1322 | goto err_disable_clk; | ||
1322 | } | 1323 | } |
1323 | 1324 | ||
1324 | sec_dai->lock = &pri_dai->spinlock; | 1325 | sec_dai->lock = &pri_dai->spinlock; |
1325 | sec_dai->variant_regs = pri_dai->variant_regs; | 1326 | sec_dai->variant_regs = pri_dai->variant_regs; |
1326 | sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; | 1327 | sec_dai->dma_playback.addr = regs_base + I2STXDS; |
1327 | sec_dai->dma_playback.ch_name = "tx-sec"; | 1328 | sec_dai->dma_playback.chan_name = "tx-sec"; |
1328 | 1329 | ||
1329 | if (!np) { | 1330 | if (!np) { |
1330 | sec_dai->dma_playback.slave = i2s_pdata->dma_play_sec; | 1331 | sec_dai->dma_playback.filter_data = i2s_pdata->dma_play_sec; |
1331 | sec_dai->filter = i2s_pdata->dma_filter; | 1332 | sec_dai->filter = i2s_pdata->dma_filter; |
1332 | } | 1333 | } |
1333 | 1334 | ||
1334 | sec_dai->dma_playback.dma_size = 4; | 1335 | sec_dai->dma_playback.addr_width = 4; |
1335 | sec_dai->addr = pri_dai->addr; | 1336 | sec_dai->addr = pri_dai->addr; |
1336 | sec_dai->clk = pri_dai->clk; | 1337 | sec_dai->clk = pri_dai->clk; |
1337 | sec_dai->quirks = quirks; | 1338 | sec_dai->quirks = quirks; |
1338 | sec_dai->idma_playback.dma_addr = idma_addr; | 1339 | sec_dai->idma_playback.addr = idma_addr; |
1339 | sec_dai->pri_dai = pri_dai; | 1340 | sec_dai->pri_dai = pri_dai; |
1340 | pri_dai->sec_dai = sec_dai; | 1341 | pri_dai->sec_dai = sec_dai; |
1341 | } | 1342 | } |
1342 | 1343 | ||
1343 | if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { | 1344 | if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { |
1344 | dev_err(&pdev->dev, "Unable to configure gpio\n"); | 1345 | dev_err(&pdev->dev, "Unable to configure gpio\n"); |
1345 | return -EINVAL; | 1346 | ret = -EINVAL; |
1347 | goto err_disable_clk; | ||
1346 | } | 1348 | } |
1347 | 1349 | ||
1348 | ret = devm_snd_soc_register_component(&pri_dai->pdev->dev, | 1350 | ret = devm_snd_soc_register_component(&pri_dai->pdev->dev, |
@@ -1366,6 +1368,8 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1366 | err_free_dai: | 1368 | err_free_dai: |
1367 | if (sec_dai) | 1369 | if (sec_dai) |
1368 | i2s_free_sec_dai(sec_dai); | 1370 | i2s_free_sec_dai(sec_dai); |
1371 | err_disable_clk: | ||
1372 | clk_disable_unprepare(pri_dai->clk); | ||
1369 | return ret; | 1373 | return ret; |
1370 | } | 1374 | } |
1371 | 1375 | ||
diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c index 4ed29ffc1c54..3e408158625d 100644 --- a/sound/soc/samsung/idma.c +++ b/sound/soc/samsung/idma.c | |||
@@ -22,7 +22,6 @@ | |||
22 | 22 | ||
23 | #include "i2s.h" | 23 | #include "i2s.h" |
24 | #include "idma.h" | 24 | #include "idma.h" |
25 | #include "dma.h" | ||
26 | #include "i2s-regs.h" | 25 | #include "i2s-regs.h" |
27 | 26 | ||
28 | #define ST_RUNNING (1<<0) | 27 | #define ST_RUNNING (1<<0) |
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index 490c1a87fd66..43e367a9acc3 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c | |||
@@ -127,25 +127,25 @@ struct s3c_pcm_info { | |||
127 | struct clk *pclk; | 127 | struct clk *pclk; |
128 | struct clk *cclk; | 128 | struct clk *cclk; |
129 | 129 | ||
130 | struct s3c_dma_params *dma_playback; | 130 | struct snd_dmaengine_dai_dma_data *dma_playback; |
131 | struct s3c_dma_params *dma_capture; | 131 | struct snd_dmaengine_dai_dma_data *dma_capture; |
132 | }; | 132 | }; |
133 | 133 | ||
134 | static struct s3c_dma_params s3c_pcm_stereo_out[] = { | 134 | static struct snd_dmaengine_dai_dma_data s3c_pcm_stereo_out[] = { |
135 | [0] = { | 135 | [0] = { |
136 | .dma_size = 4, | 136 | .addr_width = 4, |
137 | }, | 137 | }, |
138 | [1] = { | 138 | [1] = { |
139 | .dma_size = 4, | 139 | .addr_width = 4, |
140 | }, | 140 | }, |
141 | }; | 141 | }; |
142 | 142 | ||
143 | static struct s3c_dma_params s3c_pcm_stereo_in[] = { | 143 | static struct snd_dmaengine_dai_dma_data s3c_pcm_stereo_in[] = { |
144 | [0] = { | 144 | [0] = { |
145 | .dma_size = 4, | 145 | .addr_width = 4, |
146 | }, | 146 | }, |
147 | [1] = { | 147 | [1] = { |
148 | .dma_size = 4, | 148 | .addr_width = 4, |
149 | }, | 149 | }, |
150 | }; | 150 | }; |
151 | 151 | ||
@@ -552,15 +552,13 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) | |||
552 | } | 552 | } |
553 | clk_prepare_enable(pcm->pclk); | 553 | clk_prepare_enable(pcm->pclk); |
554 | 554 | ||
555 | s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start | 555 | s3c_pcm_stereo_in[pdev->id].addr = mem_res->start + S3C_PCM_RXFIFO; |
556 | + S3C_PCM_RXFIFO; | 556 | s3c_pcm_stereo_out[pdev->id].addr = mem_res->start + S3C_PCM_TXFIFO; |
557 | s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start | ||
558 | + S3C_PCM_TXFIFO; | ||
559 | 557 | ||
560 | filter = NULL; | 558 | filter = NULL; |
561 | if (pcm_pdata) { | 559 | if (pcm_pdata) { |
562 | s3c_pcm_stereo_in[pdev->id].slave = pcm_pdata->dma_capture; | 560 | s3c_pcm_stereo_in[pdev->id].filter_data = pcm_pdata->dma_capture; |
563 | s3c_pcm_stereo_out[pdev->id].slave = pcm_pdata->dma_playback; | 561 | s3c_pcm_stereo_out[pdev->id].filter_data = pcm_pdata->dma_playback; |
564 | filter = pcm_pdata->dma_filter; | 562 | filter = pcm_pdata->dma_filter; |
565 | } | 563 | } |
566 | 564 | ||
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c index bf8ae79b0fd2..644f186fd35c 100644 --- a/sound/soc/samsung/s3c-i2s-v2.c +++ b/sound/soc/samsung/s3c-i2s-v2.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | #include "regs-i2s-v2.h" | 25 | #include "regs-i2s-v2.h" |
26 | #include "s3c-i2s-v2.h" | 26 | #include "s3c-i2s-v2.h" |
27 | #include "dma.h" | ||
28 | 27 | ||
29 | #undef S3C_IIS_V2_SUPPORTED | 28 | #undef S3C_IIS_V2_SUPPORTED |
30 | 29 | ||
@@ -302,7 +301,7 @@ static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream, | |||
302 | struct snd_soc_dai *dai) | 301 | struct snd_soc_dai *dai) |
303 | { | 302 | { |
304 | struct s3c_i2sv2_info *i2s = to_info(dai); | 303 | struct s3c_i2sv2_info *i2s = to_info(dai); |
305 | struct s3c_dma_params *dma_data; | 304 | struct snd_dmaengine_dai_dma_data *dma_data; |
306 | u32 iismod; | 305 | u32 iismod; |
307 | 306 | ||
308 | pr_debug("Entered %s\n", __func__); | 307 | pr_debug("Entered %s\n", __func__); |
diff --git a/sound/soc/samsung/s3c-i2s-v2.h b/sound/soc/samsung/s3c-i2s-v2.h index d0684145ed1f..182d80564e37 100644 --- a/sound/soc/samsung/s3c-i2s-v2.h +++ b/sound/soc/samsung/s3c-i2s-v2.h | |||
@@ -60,8 +60,8 @@ struct s3c_i2sv2_info { | |||
60 | 60 | ||
61 | unsigned char master; | 61 | unsigned char master; |
62 | 62 | ||
63 | struct s3c_dma_params *dma_playback; | 63 | struct snd_dmaengine_dai_dma_data *dma_playback; |
64 | struct s3c_dma_params *dma_capture; | 64 | struct snd_dmaengine_dai_dma_data *dma_capture; |
65 | 65 | ||
66 | u32 suspend_iismod; | 66 | u32 suspend_iismod; |
67 | u32 suspend_iiscon; | 67 | u32 suspend_iiscon; |
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index d45dffb297d8..3e89fbc0c51d 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c | |||
@@ -34,14 +34,14 @@ | |||
34 | 34 | ||
35 | #include <linux/platform_data/asoc-s3c.h> | 35 | #include <linux/platform_data/asoc-s3c.h> |
36 | 36 | ||
37 | static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = { | 37 | static struct snd_dmaengine_dai_dma_data s3c2412_i2s_pcm_stereo_out = { |
38 | .ch_name = "tx", | 38 | .chan_name = "tx", |
39 | .dma_size = 4, | 39 | .addr_width = 4, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = { | 42 | static struct snd_dmaengine_dai_dma_data s3c2412_i2s_pcm_stereo_in = { |
43 | .ch_name = "rx", | 43 | .chan_name = "rx", |
44 | .dma_size = 4, | 44 | .addr_width = 4, |
45 | }; | 45 | }; |
46 | 46 | ||
47 | static struct s3c_i2sv2_info s3c2412_i2s; | 47 | static struct s3c_i2sv2_info s3c2412_i2s; |
@@ -52,8 +52,8 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai) | |||
52 | 52 | ||
53 | pr_debug("Entered %s\n", __func__); | 53 | pr_debug("Entered %s\n", __func__); |
54 | 54 | ||
55 | samsung_asoc_init_dma_data(dai, &s3c2412_i2s_pcm_stereo_out, | 55 | snd_soc_dai_init_dma_data(dai, &s3c2412_i2s_pcm_stereo_out, |
56 | &s3c2412_i2s_pcm_stereo_in); | 56 | &s3c2412_i2s_pcm_stereo_in); |
57 | 57 | ||
58 | ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS); | 58 | ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS); |
59 | if (ret) | 59 | if (ret) |
@@ -163,10 +163,10 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev) | |||
163 | if (IS_ERR(s3c2412_i2s.regs)) | 163 | if (IS_ERR(s3c2412_i2s.regs)) |
164 | return PTR_ERR(s3c2412_i2s.regs); | 164 | return PTR_ERR(s3c2412_i2s.regs); |
165 | 165 | ||
166 | s3c2412_i2s_pcm_stereo_out.dma_addr = res->start + S3C2412_IISTXD; | 166 | s3c2412_i2s_pcm_stereo_out.addr = res->start + S3C2412_IISTXD; |
167 | s3c2412_i2s_pcm_stereo_out.slave = pdata->dma_playback; | 167 | s3c2412_i2s_pcm_stereo_out.filter_data = pdata->dma_playback; |
168 | s3c2412_i2s_pcm_stereo_in.dma_addr = res->start + S3C2412_IISRXD; | 168 | s3c2412_i2s_pcm_stereo_in.addr = res->start + S3C2412_IISRXD; |
169 | s3c2412_i2s_pcm_stereo_in.slave = pdata->dma_capture; | 169 | s3c2412_i2s_pcm_stereo_in.filter_data = pdata->dma_capture; |
170 | 170 | ||
171 | ret = s3c_i2sv2_register_component(&pdev->dev, -1, | 171 | ret = s3c_i2sv2_register_component(&pdev->dev, -1, |
172 | &s3c2412_i2s_component, | 172 | &s3c2412_i2s_component, |
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index 3e76f2a75a24..c78a936a3099 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c | |||
@@ -32,14 +32,14 @@ | |||
32 | 32 | ||
33 | #include <linux/platform_data/asoc-s3c.h> | 33 | #include <linux/platform_data/asoc-s3c.h> |
34 | 34 | ||
35 | static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = { | 35 | static struct snd_dmaengine_dai_dma_data s3c24xx_i2s_pcm_stereo_out = { |
36 | .ch_name = "tx", | 36 | .chan_name = "tx", |
37 | .dma_size = 2, | 37 | .addr_width = 2, |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = { | 40 | static struct snd_dmaengine_dai_dma_data s3c24xx_i2s_pcm_stereo_in = { |
41 | .ch_name = "rx", | 41 | .chan_name = "rx", |
42 | .dma_size = 2, | 42 | .addr_width = 2, |
43 | }; | 43 | }; |
44 | 44 | ||
45 | struct s3c24xx_i2s_info { | 45 | struct s3c24xx_i2s_info { |
@@ -360,8 +360,8 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai) | |||
360 | { | 360 | { |
361 | pr_debug("Entered %s\n", __func__); | 361 | pr_debug("Entered %s\n", __func__); |
362 | 362 | ||
363 | samsung_asoc_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out, | 363 | snd_soc_dai_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out, |
364 | &s3c24xx_i2s_pcm_stereo_in); | 364 | &s3c24xx_i2s_pcm_stereo_in); |
365 | 365 | ||
366 | s3c24xx_i2s.iis_clk = devm_clk_get(dai->dev, "iis"); | 366 | s3c24xx_i2s.iis_clk = devm_clk_get(dai->dev, "iis"); |
367 | if (IS_ERR(s3c24xx_i2s.iis_clk)) { | 367 | if (IS_ERR(s3c24xx_i2s.iis_clk)) { |
@@ -469,10 +469,10 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev) | |||
469 | if (IS_ERR(s3c24xx_i2s.regs)) | 469 | if (IS_ERR(s3c24xx_i2s.regs)) |
470 | return PTR_ERR(s3c24xx_i2s.regs); | 470 | return PTR_ERR(s3c24xx_i2s.regs); |
471 | 471 | ||
472 | s3c24xx_i2s_pcm_stereo_out.dma_addr = res->start + S3C2410_IISFIFO; | 472 | s3c24xx_i2s_pcm_stereo_out.addr = res->start + S3C2410_IISFIFO; |
473 | s3c24xx_i2s_pcm_stereo_out.slave = pdata->dma_playback; | 473 | s3c24xx_i2s_pcm_stereo_out.filter_data = pdata->dma_playback; |
474 | s3c24xx_i2s_pcm_stereo_in.dma_addr = res->start + S3C2410_IISFIFO; | 474 | s3c24xx_i2s_pcm_stereo_in.addr = res->start + S3C2410_IISFIFO; |
475 | s3c24xx_i2s_pcm_stereo_in.slave = pdata->dma_capture; | 475 | s3c24xx_i2s_pcm_stereo_in.filter_data = pdata->dma_capture; |
476 | 476 | ||
477 | ret = devm_snd_soc_register_component(&pdev->dev, | 477 | ret = devm_snd_soc_register_component(&pdev->dev, |
478 | &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1); | 478 | &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1); |
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c index 92e88bca386e..7853fbe6ccc9 100644 --- a/sound/soc/samsung/s3c24xx_uda134x.c +++ b/sound/soc/samsung/s3c24xx_uda134x.c | |||
@@ -54,8 +54,6 @@ static struct snd_pcm_hw_constraint_list hw_constraints_rates = { | |||
54 | }; | 54 | }; |
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | static struct platform_device *s3c24xx_uda134x_snd_device; | ||
58 | |||
59 | static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) | 57 | static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) |
60 | { | 58 | { |
61 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 59 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
@@ -66,17 +64,17 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) | |||
66 | int ret = 0; | 64 | int ret = 0; |
67 | 65 | ||
68 | mutex_lock(&clk_lock); | 66 | mutex_lock(&clk_lock); |
69 | pr_debug("%s %d\n", __func__, clk_users); | 67 | |
70 | if (clk_users == 0) { | 68 | if (clk_users == 0) { |
71 | xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal"); | 69 | xtal = clk_get(rtd->dev, "xtal"); |
72 | if (IS_ERR(xtal)) { | 70 | if (IS_ERR(xtal)) { |
73 | printk(KERN_ERR "%s cannot get xtal\n", __func__); | 71 | dev_err(rtd->dev, "%s cannot get xtal\n", __func__); |
74 | ret = PTR_ERR(xtal); | 72 | ret = PTR_ERR(xtal); |
75 | } else { | 73 | } else { |
76 | pclk = clk_get(cpu_dai->dev, "iis"); | 74 | pclk = clk_get(cpu_dai->dev, "iis"); |
77 | if (IS_ERR(pclk)) { | 75 | if (IS_ERR(pclk)) { |
78 | printk(KERN_ERR "%s cannot get pclk\n", | 76 | dev_err(rtd->dev, "%s cannot get pclk\n", |
79 | __func__); | 77 | __func__); |
80 | clk_put(xtal); | 78 | clk_put(xtal); |
81 | ret = PTR_ERR(pclk); | 79 | ret = PTR_ERR(pclk); |
82 | } | 80 | } |
@@ -102,8 +100,8 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) | |||
102 | SNDRV_PCM_HW_PARAM_RATE, | 100 | SNDRV_PCM_HW_PARAM_RATE, |
103 | &hw_constraints_rates); | 101 | &hw_constraints_rates); |
104 | if (ret < 0) | 102 | if (ret < 0) |
105 | printk(KERN_ERR "%s cannot set constraints\n", | 103 | dev_err(rtd->dev, "%s cannot set constraints\n", |
106 | __func__); | 104 | __func__); |
107 | #endif | 105 | #endif |
108 | } | 106 | } |
109 | return ret; | 107 | return ret; |
@@ -112,7 +110,6 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) | |||
112 | static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream) | 110 | static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream) |
113 | { | 111 | { |
114 | mutex_lock(&clk_lock); | 112 | mutex_lock(&clk_lock); |
115 | pr_debug("%s %d\n", __func__, clk_users); | ||
116 | clk_users -= 1; | 113 | clk_users -= 1; |
117 | if (clk_users == 0) { | 114 | if (clk_users == 0) { |
118 | clk_put(xtal); | 115 | clk_put(xtal); |
@@ -159,18 +156,19 @@ static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream, | |||
159 | clk_source = S3C24XX_CLKSRC_PCLK; | 156 | clk_source = S3C24XX_CLKSRC_PCLK; |
160 | div = bi % 33; | 157 | div = bi % 33; |
161 | } | 158 | } |
162 | pr_debug("%s desired rate %lu, %d\n", __func__, rate, bi); | 159 | |
160 | dev_dbg(rtd->dev, "%s desired rate %lu, %d\n", __func__, rate, bi); | ||
163 | 161 | ||
164 | clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate; | 162 | clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate; |
165 | pr_debug("%s will use: %s %s %d sysclk %d err %ld\n", __func__, | 163 | |
166 | fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS", | 164 | dev_dbg(rtd->dev, "%s will use: %s %s %d sysclk %d err %ld\n", __func__, |
167 | clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK", | 165 | fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS", |
168 | div, clk, err); | 166 | clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK", |
167 | div, clk, err); | ||
169 | 168 | ||
170 | if ((err * 100 / rate) > 5) { | 169 | if ((err * 100 / rate) > 5) { |
171 | printk(KERN_ERR "S3C24XX_UDA134X: effective frequency " | 170 | dev_err(rtd->dev, "effective frequency too different " |
172 | "too different from desired (%ld%%)\n", | 171 | "from desired (%ld%%)\n", err * 100 / rate); |
173 | err * 100 / rate); | ||
174 | return -EINVAL; | 172 | return -EINVAL; |
175 | } | 173 | } |
176 | 174 | ||
@@ -227,115 +225,27 @@ static struct snd_soc_card snd_soc_s3c24xx_uda134x = { | |||
227 | .num_links = 1, | 225 | .num_links = 1, |
228 | }; | 226 | }; |
229 | 227 | ||
230 | static struct s3c24xx_uda134x_platform_data *s3c24xx_uda134x_l3_pins; | ||
231 | |||
232 | static void setdat(int v) | ||
233 | { | ||
234 | gpio_set_value(s3c24xx_uda134x_l3_pins->l3_data, v > 0); | ||
235 | } | ||
236 | |||
237 | static void setclk(int v) | ||
238 | { | ||
239 | gpio_set_value(s3c24xx_uda134x_l3_pins->l3_clk, v > 0); | ||
240 | } | ||
241 | |||
242 | static void setmode(int v) | ||
243 | { | ||
244 | gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0); | ||
245 | } | ||
246 | |||
247 | /* FIXME - This must be codec platform data but in which board file ?? */ | ||
248 | static struct uda134x_platform_data s3c24xx_uda134x = { | ||
249 | .l3 = { | ||
250 | .setdat = setdat, | ||
251 | .setclk = setclk, | ||
252 | .setmode = setmode, | ||
253 | .data_hold = 1, | ||
254 | .data_setup = 1, | ||
255 | .clock_high = 1, | ||
256 | .mode_hold = 1, | ||
257 | .mode = 1, | ||
258 | .mode_setup = 1, | ||
259 | }, | ||
260 | }; | ||
261 | |||
262 | static int s3c24xx_uda134x_setup_pin(int pin, char *fun) | ||
263 | { | ||
264 | if (gpio_request(pin, "s3c24xx_uda134x") < 0) { | ||
265 | printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: " | ||
266 | "l3 %s pin already in use", fun); | ||
267 | return -EBUSY; | ||
268 | } | ||
269 | gpio_direction_output(pin, 0); | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int s3c24xx_uda134x_probe(struct platform_device *pdev) | 228 | static int s3c24xx_uda134x_probe(struct platform_device *pdev) |
274 | { | 229 | { |
230 | struct snd_soc_card *card = &snd_soc_s3c24xx_uda134x; | ||
275 | int ret; | 231 | int ret; |
276 | 232 | ||
277 | printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n"); | 233 | platform_set_drvdata(pdev, card); |
234 | card->dev = &pdev->dev; | ||
278 | 235 | ||
279 | s3c24xx_uda134x_l3_pins = pdev->dev.platform_data; | 236 | ret = devm_snd_soc_register_card(&pdev->dev, card); |
280 | if (s3c24xx_uda134x_l3_pins == NULL) { | 237 | if (ret) |
281 | printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: " | 238 | dev_err(&pdev->dev, "failed to register card: %d\n", ret); |
282 | "unable to find platform data\n"); | ||
283 | return -ENODEV; | ||
284 | } | ||
285 | s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power; | ||
286 | s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model; | ||
287 | |||
288 | if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data, | ||
289 | "data") < 0) | ||
290 | return -EBUSY; | ||
291 | if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk, | ||
292 | "clk") < 0) { | ||
293 | gpio_free(s3c24xx_uda134x_l3_pins->l3_data); | ||
294 | return -EBUSY; | ||
295 | } | ||
296 | if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode, | ||
297 | "mode") < 0) { | ||
298 | gpio_free(s3c24xx_uda134x_l3_pins->l3_data); | ||
299 | gpio_free(s3c24xx_uda134x_l3_pins->l3_clk); | ||
300 | return -EBUSY; | ||
301 | } | ||
302 | |||
303 | s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1); | ||
304 | if (!s3c24xx_uda134x_snd_device) { | ||
305 | printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: " | ||
306 | "Unable to register\n"); | ||
307 | return -ENOMEM; | ||
308 | } | ||
309 | |||
310 | platform_set_drvdata(s3c24xx_uda134x_snd_device, | ||
311 | &snd_soc_s3c24xx_uda134x); | ||
312 | platform_device_add_data(s3c24xx_uda134x_snd_device, &s3c24xx_uda134x, sizeof(s3c24xx_uda134x)); | ||
313 | ret = platform_device_add(s3c24xx_uda134x_snd_device); | ||
314 | if (ret) { | ||
315 | printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n"); | ||
316 | platform_device_put(s3c24xx_uda134x_snd_device); | ||
317 | } | ||
318 | 239 | ||
319 | return ret; | 240 | return ret; |
320 | } | 241 | } |
321 | 242 | ||
322 | static int s3c24xx_uda134x_remove(struct platform_device *pdev) | ||
323 | { | ||
324 | platform_device_unregister(s3c24xx_uda134x_snd_device); | ||
325 | gpio_free(s3c24xx_uda134x_l3_pins->l3_data); | ||
326 | gpio_free(s3c24xx_uda134x_l3_pins->l3_clk); | ||
327 | gpio_free(s3c24xx_uda134x_l3_pins->l3_mode); | ||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | static struct platform_driver s3c24xx_uda134x_driver = { | 243 | static struct platform_driver s3c24xx_uda134x_driver = { |
332 | .probe = s3c24xx_uda134x_probe, | 244 | .probe = s3c24xx_uda134x_probe, |
333 | .remove = s3c24xx_uda134x_remove, | ||
334 | .driver = { | 245 | .driver = { |
335 | .name = "s3c24xx_uda134x", | 246 | .name = "s3c24xx_uda134x", |
336 | }, | 247 | }, |
337 | }; | 248 | }; |
338 | |||
339 | module_platform_driver(s3c24xx_uda134x_driver); | 249 | module_platform_driver(s3c24xx_uda134x_driver); |
340 | 250 | ||
341 | MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>"); | 251 | MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>"); |
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c index 6deec5234c92..a6d223310c67 100644 --- a/sound/soc/samsung/smdk_wm8580pcm.c +++ b/sound/soc/samsung/smdk_wm8580pcm.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <asm/mach-types.h> | 16 | #include <asm/mach-types.h> |
17 | 17 | ||
18 | #include "../codecs/wm8580.h" | 18 | #include "../codecs/wm8580.h" |
19 | #include "dma.h" | ||
20 | #include "pcm.h" | 19 | #include "pcm.h" |
21 | 20 | ||
22 | /* | 21 | /* |
diff --git a/sound/soc/samsung/smdk_wm8994pcm.c b/sound/soc/samsung/smdk_wm8994pcm.c index b1c89ec2d999..2e621496be8b 100644 --- a/sound/soc/samsung/smdk_wm8994pcm.c +++ b/sound/soc/samsung/smdk_wm8994pcm.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <sound/pcm_params.h> | 15 | #include <sound/pcm_params.h> |
16 | 16 | ||
17 | #include "../codecs/wm8994.h" | 17 | #include "../codecs/wm8994.h" |
18 | #include "dma.h" | ||
19 | #include "pcm.h" | 18 | #include "pcm.h" |
20 | 19 | ||
21 | /* | 20 | /* |
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index 0cb9c8567546..26c1fbed4d35 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c | |||
@@ -90,10 +90,10 @@ struct samsung_spdif_info { | |||
90 | u32 saved_clkcon; | 90 | u32 saved_clkcon; |
91 | u32 saved_con; | 91 | u32 saved_con; |
92 | u32 saved_cstas; | 92 | u32 saved_cstas; |
93 | struct s3c_dma_params *dma_playback; | 93 | struct snd_dmaengine_dai_dma_data *dma_playback; |
94 | }; | 94 | }; |
95 | 95 | ||
96 | static struct s3c_dma_params spdif_stereo_out; | 96 | static struct snd_dmaengine_dai_dma_data spdif_stereo_out; |
97 | static struct samsung_spdif_info spdif_info; | 97 | static struct samsung_spdif_info spdif_info; |
98 | 98 | ||
99 | static inline struct samsung_spdif_info *to_info(struct snd_soc_dai *cpu_dai) | 99 | static inline struct samsung_spdif_info *to_info(struct snd_soc_dai *cpu_dai) |
@@ -179,7 +179,7 @@ static int spdif_hw_params(struct snd_pcm_substream *substream, | |||
179 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 179 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
180 | struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai); | 180 | struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai); |
181 | void __iomem *regs = spdif->regs; | 181 | void __iomem *regs = spdif->regs; |
182 | struct s3c_dma_params *dma_data; | 182 | struct snd_dmaengine_dai_dma_data *dma_data; |
183 | u32 con, clkcon, cstas; | 183 | u32 con, clkcon, cstas; |
184 | unsigned long flags; | 184 | unsigned long flags; |
185 | int i, ratio; | 185 | int i, ratio; |
@@ -425,11 +425,11 @@ static int spdif_probe(struct platform_device *pdev) | |||
425 | goto err4; | 425 | goto err4; |
426 | } | 426 | } |
427 | 427 | ||
428 | spdif_stereo_out.dma_size = 2; | 428 | spdif_stereo_out.addr_width = 2; |
429 | spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF; | 429 | spdif_stereo_out.addr = mem_res->start + DATA_OUTBUF; |
430 | filter = NULL; | 430 | filter = NULL; |
431 | if (spdif_pdata) { | 431 | if (spdif_pdata) { |
432 | spdif_stereo_out.slave = spdif_pdata->dma_playback; | 432 | spdif_stereo_out.filter_data = spdif_pdata->dma_playback; |
433 | filter = spdif_pdata->dma_filter; | 433 | filter = spdif_pdata->dma_filter; |
434 | } | 434 | } |
435 | 435 | ||
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig index 9311f119feb5..6db6405d952f 100644 --- a/sound/soc/sh/Kconfig +++ b/sound/soc/sh/Kconfig | |||
@@ -42,12 +42,6 @@ config SND_SOC_RCAR | |||
42 | help | 42 | help |
43 | This option enables R-Car SRU/SCU/SSIU/SSI sound support | 43 | This option enables R-Car SRU/SCU/SSIU/SSI sound support |
44 | 44 | ||
45 | config SND_SOC_RSRC_CARD | ||
46 | tristate "Renesas Sampling Rate Convert Sound Card" | ||
47 | select SND_SIMPLE_CARD_UTILS | ||
48 | help | ||
49 | This option enables simple sound if you need sampling rate convert | ||
50 | |||
51 | ## | 45 | ## |
52 | ## Boards | 46 | ## Boards |
53 | ## | 47 | ## |
diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile index a89ddf758695..9c3d5aed99d1 100644 --- a/sound/soc/sh/rcar/Makefile +++ b/sound/soc/sh/rcar/Makefile | |||
@@ -1,5 +1,2 @@ | |||
1 | snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o ssiu.o src.o ctu.o mix.o dvc.o cmd.o | 1 | snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o ssiu.o src.o ctu.o mix.o dvc.o cmd.o |
2 | obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o | 2 | obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o |
3 | |||
4 | snd-soc-rsrc-card-objs := rsrc-card.o | ||
5 | obj-$(CONFIG_SND_SOC_RSRC_CARD) += snd-soc-rsrc-card.o | ||
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 3351a701c60e..f18141098b50 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
@@ -110,6 +110,7 @@ MODULE_DEVICE_TABLE(of, rsnd_of_match); | |||
110 | /* | 110 | /* |
111 | * rsnd_mod functions | 111 | * rsnd_mod functions |
112 | */ | 112 | */ |
113 | #ifdef DEBUG | ||
113 | void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type) | 114 | void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type) |
114 | { | 115 | { |
115 | if (mod->type != type) { | 116 | if (mod->type != type) { |
@@ -120,6 +121,7 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type) | |||
120 | rsnd_mod_name(mod), rsnd_mod_id(mod)); | 121 | rsnd_mod_name(mod), rsnd_mod_id(mod)); |
121 | } | 122 | } |
122 | } | 123 | } |
124 | #endif | ||
123 | 125 | ||
124 | char *rsnd_mod_name(struct rsnd_mod *mod) | 126 | char *rsnd_mod_name(struct rsnd_mod *mod) |
125 | { | 127 | { |
@@ -574,6 +576,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
574 | 576 | ||
575 | switch (cmd) { | 577 | switch (cmd) { |
576 | case SNDRV_PCM_TRIGGER_START: | 578 | case SNDRV_PCM_TRIGGER_START: |
579 | case SNDRV_PCM_TRIGGER_RESUME: | ||
577 | rsnd_dai_stream_init(io, substream); | 580 | rsnd_dai_stream_init(io, substream); |
578 | 581 | ||
579 | ret = rsnd_dai_call(init, io, priv); | 582 | ret = rsnd_dai_call(init, io, priv); |
@@ -590,6 +593,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
590 | 593 | ||
591 | break; | 594 | break; |
592 | case SNDRV_PCM_TRIGGER_STOP: | 595 | case SNDRV_PCM_TRIGGER_STOP: |
596 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
593 | ret = rsnd_dai_call(irq, io, priv, 0); | 597 | ret = rsnd_dai_call(irq, io, priv, 0); |
594 | 598 | ||
595 | ret |= rsnd_dai_call(stop, io, priv); | 599 | ret |= rsnd_dai_call(stop, io, priv); |
diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c deleted file mode 100644 index fa37f842b62f..000000000000 --- a/sound/soc/sh/rcar/rsrc-card.c +++ /dev/null | |||
@@ -1,486 +0,0 @@ | |||
1 | /* | ||
2 | * Renesas Sampling Rate Convert Sound Card for DPCM | ||
3 | * | ||
4 | * Copyright (C) 2015 Renesas Solutions Corp. | ||
5 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | ||
6 | * | ||
7 | * based on ${LINUX}/sound/soc/generic/simple-card.c | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | #include <linux/clk.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/of_device.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <sound/jack.h> | ||
21 | #include <sound/soc.h> | ||
22 | #include <sound/soc-dai.h> | ||
23 | #include <sound/simple_card_utils.h> | ||
24 | |||
25 | struct rsrc_card_of_data { | ||
26 | const char *prefix; | ||
27 | const struct snd_soc_dapm_route *routes; | ||
28 | int num_routes; | ||
29 | }; | ||
30 | |||
31 | static const struct snd_soc_dapm_route routes_ssi0_ak4642[] = { | ||
32 | {"ak4642 Playback", NULL, "DAI0 Playback"}, | ||
33 | {"DAI0 Capture", NULL, "ak4642 Capture"}, | ||
34 | }; | ||
35 | |||
36 | static const struct rsrc_card_of_data routes_of_ssi0_ak4642 = { | ||
37 | .prefix = "ak4642", | ||
38 | .routes = routes_ssi0_ak4642, | ||
39 | .num_routes = ARRAY_SIZE(routes_ssi0_ak4642), | ||
40 | }; | ||
41 | |||
42 | static const struct of_device_id rsrc_card_of_match[] = { | ||
43 | { .compatible = "renesas,rsrc-card,lager", .data = &routes_of_ssi0_ak4642 }, | ||
44 | { .compatible = "renesas,rsrc-card,koelsch", .data = &routes_of_ssi0_ak4642 }, | ||
45 | { .compatible = "renesas,rsrc-card", }, | ||
46 | {}, | ||
47 | }; | ||
48 | MODULE_DEVICE_TABLE(of, rsrc_card_of_match); | ||
49 | |||
50 | #define IDX_CPU 0 | ||
51 | #define IDX_CODEC 1 | ||
52 | struct rsrc_card_priv { | ||
53 | struct snd_soc_card snd_card; | ||
54 | struct snd_soc_codec_conf codec_conf; | ||
55 | struct asoc_simple_dai *dai_props; | ||
56 | struct snd_soc_dai_link *dai_link; | ||
57 | u32 convert_rate; | ||
58 | u32 convert_channels; | ||
59 | }; | ||
60 | |||
61 | #define rsrc_priv_to_dev(priv) ((priv)->snd_card.dev) | ||
62 | #define rsrc_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i)) | ||
63 | #define rsrc_priv_to_props(priv, i) ((priv)->dai_props + (i)) | ||
64 | |||
65 | static int rsrc_card_startup(struct snd_pcm_substream *substream) | ||
66 | { | ||
67 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
68 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
69 | struct asoc_simple_dai *dai_props = | ||
70 | rsrc_priv_to_props(priv, rtd->num); | ||
71 | |||
72 | return clk_prepare_enable(dai_props->clk); | ||
73 | } | ||
74 | |||
75 | static void rsrc_card_shutdown(struct snd_pcm_substream *substream) | ||
76 | { | ||
77 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
78 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
79 | struct asoc_simple_dai *dai_props = | ||
80 | rsrc_priv_to_props(priv, rtd->num); | ||
81 | |||
82 | clk_disable_unprepare(dai_props->clk); | ||
83 | } | ||
84 | |||
85 | static struct snd_soc_ops rsrc_card_ops = { | ||
86 | .startup = rsrc_card_startup, | ||
87 | .shutdown = rsrc_card_shutdown, | ||
88 | }; | ||
89 | |||
90 | static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd) | ||
91 | { | ||
92 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
93 | struct snd_soc_dai *dai; | ||
94 | struct snd_soc_dai_link *dai_link; | ||
95 | struct asoc_simple_dai *dai_props; | ||
96 | int num = rtd->num; | ||
97 | int ret; | ||
98 | |||
99 | dai_link = rsrc_priv_to_link(priv, num); | ||
100 | dai_props = rsrc_priv_to_props(priv, num); | ||
101 | dai = dai_link->dynamic ? | ||
102 | rtd->cpu_dai : | ||
103 | rtd->codec_dai; | ||
104 | |||
105 | if (dai_props->sysclk) { | ||
106 | ret = snd_soc_dai_set_sysclk(dai, 0, dai_props->sysclk, 0); | ||
107 | if (ret && ret != -ENOTSUPP) { | ||
108 | dev_err(dai->dev, "set_sysclk error\n"); | ||
109 | goto err; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | if (dai_props->slots) { | ||
114 | ret = snd_soc_dai_set_tdm_slot(dai, | ||
115 | dai_props->tx_slot_mask, | ||
116 | dai_props->rx_slot_mask, | ||
117 | dai_props->slots, | ||
118 | dai_props->slot_width); | ||
119 | if (ret && ret != -ENOTSUPP) { | ||
120 | dev_err(dai->dev, "set_tdm_slot error\n"); | ||
121 | goto err; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | ret = 0; | ||
126 | |||
127 | err: | ||
128 | return ret; | ||
129 | } | ||
130 | |||
131 | static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, | ||
132 | struct snd_pcm_hw_params *params) | ||
133 | { | ||
134 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
135 | struct snd_interval *rate = hw_param_interval(params, | ||
136 | SNDRV_PCM_HW_PARAM_RATE); | ||
137 | struct snd_interval *channels = hw_param_interval(params, | ||
138 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
139 | |||
140 | if (priv->convert_rate) | ||
141 | rate->min = | ||
142 | rate->max = priv->convert_rate; | ||
143 | |||
144 | if (priv->convert_channels) | ||
145 | channels->min = | ||
146 | channels->max = priv->convert_channels; | ||
147 | |||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static int rsrc_card_parse_links(struct device_node *np, | ||
152 | struct rsrc_card_priv *priv, | ||
153 | int idx, bool is_fe) | ||
154 | { | ||
155 | struct device *dev = rsrc_priv_to_dev(priv); | ||
156 | struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); | ||
157 | struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx); | ||
158 | struct of_phandle_args args; | ||
159 | int ret; | ||
160 | |||
161 | /* | ||
162 | * Get node via "sound-dai = <&phandle port>" | ||
163 | * it will be used as xxx_of_node on soc_bind_dai_link() | ||
164 | */ | ||
165 | ret = of_parse_phandle_with_args(np, "sound-dai", | ||
166 | "#sound-dai-cells", 0, &args); | ||
167 | if (ret) | ||
168 | return ret; | ||
169 | |||
170 | /* Parse TDM slot */ | ||
171 | ret = snd_soc_of_parse_tdm_slot(np, | ||
172 | &dai_props->tx_slot_mask, | ||
173 | &dai_props->rx_slot_mask, | ||
174 | &dai_props->slots, | ||
175 | &dai_props->slot_width); | ||
176 | if (ret) | ||
177 | return ret; | ||
178 | |||
179 | if (is_fe) { | ||
180 | /* BE is dummy */ | ||
181 | dai_link->codec_of_node = NULL; | ||
182 | dai_link->codec_dai_name = "snd-soc-dummy-dai"; | ||
183 | dai_link->codec_name = "snd-soc-dummy"; | ||
184 | |||
185 | /* FE settings */ | ||
186 | dai_link->dynamic = 1; | ||
187 | dai_link->dpcm_merged_format = 1; | ||
188 | dai_link->cpu_of_node = args.np; | ||
189 | ret = snd_soc_of_get_dai_name(np, &dai_link->cpu_dai_name); | ||
190 | if (ret < 0) | ||
191 | return ret; | ||
192 | |||
193 | ret = asoc_simple_card_set_dailink_name(dev, dai_link, | ||
194 | "fe.%s", | ||
195 | dai_link->cpu_dai_name); | ||
196 | if (ret < 0) | ||
197 | return ret; | ||
198 | |||
199 | /* | ||
200 | * In soc_bind_dai_link() will check cpu name after | ||
201 | * of_node matching if dai_link has cpu_dai_name. | ||
202 | * but, it will never match if name was created by | ||
203 | * fmt_single_name() remove cpu_dai_name if cpu_args | ||
204 | * was 0. See: | ||
205 | * fmt_single_name() | ||
206 | * fmt_multiple_name() | ||
207 | */ | ||
208 | if (!args.args_count) | ||
209 | dai_link->cpu_dai_name = NULL; | ||
210 | } else { | ||
211 | const struct rsrc_card_of_data *of_data; | ||
212 | |||
213 | of_data = of_device_get_match_data(dev); | ||
214 | |||
215 | /* FE is dummy */ | ||
216 | dai_link->cpu_of_node = NULL; | ||
217 | dai_link->cpu_dai_name = "snd-soc-dummy-dai"; | ||
218 | dai_link->cpu_name = "snd-soc-dummy"; | ||
219 | |||
220 | /* BE settings */ | ||
221 | dai_link->no_pcm = 1; | ||
222 | dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup; | ||
223 | dai_link->codec_of_node = args.np; | ||
224 | ret = snd_soc_of_get_dai_name(np, &dai_link->codec_dai_name); | ||
225 | if (ret < 0) | ||
226 | return ret; | ||
227 | |||
228 | ret = asoc_simple_card_set_dailink_name(dev, dai_link, | ||
229 | "be.%s", | ||
230 | dai_link->codec_dai_name); | ||
231 | if (ret < 0) | ||
232 | return ret; | ||
233 | |||
234 | /* additional name prefix */ | ||
235 | if (of_data) { | ||
236 | priv->codec_conf.of_node = dai_link->codec_of_node; | ||
237 | priv->codec_conf.name_prefix = of_data->prefix; | ||
238 | } else { | ||
239 | snd_soc_of_parse_audio_prefix(&priv->snd_card, | ||
240 | &priv->codec_conf, | ||
241 | dai_link->codec_of_node, | ||
242 | "audio-prefix"); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | /* Simple Card assumes platform == cpu */ | ||
247 | dai_link->platform_of_node = dai_link->cpu_of_node; | ||
248 | dai_link->dpcm_playback = 1; | ||
249 | dai_link->dpcm_capture = 1; | ||
250 | dai_link->ops = &rsrc_card_ops; | ||
251 | dai_link->init = rsrc_card_dai_init; | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static int rsrc_card_parse_clk(struct device_node *np, | ||
257 | struct rsrc_card_priv *priv, | ||
258 | int idx, bool is_fe) | ||
259 | { | ||
260 | struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); | ||
261 | struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx); | ||
262 | struct clk *clk; | ||
263 | struct device_node *of_np = is_fe ? dai_link->cpu_of_node : | ||
264 | dai_link->codec_of_node; | ||
265 | u32 val; | ||
266 | |||
267 | /* | ||
268 | * Parse dai->sysclk come from "clocks = <&xxx>" | ||
269 | * (if system has common clock) | ||
270 | * or "system-clock-frequency = <xxx>" | ||
271 | * or device's module clock. | ||
272 | */ | ||
273 | if (of_property_read_bool(np, "clocks")) { | ||
274 | clk = of_clk_get(np, 0); | ||
275 | if (IS_ERR(clk)) | ||
276 | return PTR_ERR(clk); | ||
277 | |||
278 | dai_props->sysclk = clk_get_rate(clk); | ||
279 | dai_props->clk = clk; | ||
280 | } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) { | ||
281 | dai_props->sysclk = val; | ||
282 | } else { | ||
283 | clk = of_clk_get(of_np, 0); | ||
284 | if (!IS_ERR(clk)) | ||
285 | dai_props->sysclk = clk_get_rate(clk); | ||
286 | } | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static int rsrc_card_dai_sub_link_of(struct device_node *node, | ||
292 | struct device_node *np, | ||
293 | struct rsrc_card_priv *priv, | ||
294 | int idx, bool is_fe) | ||
295 | { | ||
296 | struct device *dev = rsrc_priv_to_dev(priv); | ||
297 | struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); | ||
298 | struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx); | ||
299 | int ret; | ||
300 | |||
301 | ret = rsrc_card_parse_links(np, priv, idx, is_fe); | ||
302 | if (ret < 0) | ||
303 | return ret; | ||
304 | |||
305 | ret = rsrc_card_parse_clk(np, priv, idx, is_fe); | ||
306 | if (ret < 0) | ||
307 | return ret; | ||
308 | |||
309 | dev_dbg(dev, "\t%s / %04x / %d\n", | ||
310 | dai_link->name, | ||
311 | dai_link->dai_fmt, | ||
312 | dai_props->sysclk); | ||
313 | |||
314 | return ret; | ||
315 | } | ||
316 | |||
317 | static int rsrc_card_dai_link_of(struct device_node *node, | ||
318 | struct rsrc_card_priv *priv) | ||
319 | { | ||
320 | struct device *dev = rsrc_priv_to_dev(priv); | ||
321 | struct snd_soc_dai_link *dai_link; | ||
322 | struct device_node *np; | ||
323 | unsigned int daifmt = 0; | ||
324 | int ret, i; | ||
325 | bool is_fe; | ||
326 | |||
327 | /* find 1st codec */ | ||
328 | i = 0; | ||
329 | for_each_child_of_node(node, np) { | ||
330 | dai_link = rsrc_priv_to_link(priv, i); | ||
331 | |||
332 | if (strcmp(np->name, "codec") == 0) { | ||
333 | ret = asoc_simple_card_parse_daifmt(dev, node, np, | ||
334 | NULL, &daifmt); | ||
335 | if (ret < 0) | ||
336 | return ret; | ||
337 | break; | ||
338 | } | ||
339 | i++; | ||
340 | } | ||
341 | |||
342 | i = 0; | ||
343 | for_each_child_of_node(node, np) { | ||
344 | dai_link = rsrc_priv_to_link(priv, i); | ||
345 | dai_link->dai_fmt = daifmt; | ||
346 | |||
347 | is_fe = false; | ||
348 | if (strcmp(np->name, "cpu") == 0) | ||
349 | is_fe = true; | ||
350 | |||
351 | ret = rsrc_card_dai_sub_link_of(node, np, priv, i, is_fe); | ||
352 | if (ret < 0) | ||
353 | return ret; | ||
354 | i++; | ||
355 | } | ||
356 | |||
357 | return 0; | ||
358 | } | ||
359 | |||
360 | static int rsrc_card_parse_of(struct device_node *node, | ||
361 | struct rsrc_card_priv *priv, | ||
362 | struct device *dev) | ||
363 | { | ||
364 | const struct rsrc_card_of_data *of_data = of_device_get_match_data(dev); | ||
365 | struct asoc_simple_dai *props; | ||
366 | struct snd_soc_dai_link *links; | ||
367 | int ret; | ||
368 | int num; | ||
369 | |||
370 | if (!node) | ||
371 | return -EINVAL; | ||
372 | |||
373 | num = of_get_child_count(node); | ||
374 | props = devm_kzalloc(dev, sizeof(*props) * num, GFP_KERNEL); | ||
375 | links = devm_kzalloc(dev, sizeof(*links) * num, GFP_KERNEL); | ||
376 | if (!props || !links) | ||
377 | return -ENOMEM; | ||
378 | |||
379 | priv->dai_props = props; | ||
380 | priv->dai_link = links; | ||
381 | |||
382 | /* Init snd_soc_card */ | ||
383 | priv->snd_card.owner = THIS_MODULE; | ||
384 | priv->snd_card.dev = dev; | ||
385 | priv->snd_card.dai_link = priv->dai_link; | ||
386 | priv->snd_card.num_links = num; | ||
387 | priv->snd_card.codec_conf = &priv->codec_conf; | ||
388 | priv->snd_card.num_configs = 1; | ||
389 | |||
390 | if (of_data) { | ||
391 | priv->snd_card.of_dapm_routes = of_data->routes; | ||
392 | priv->snd_card.num_of_dapm_routes = of_data->num_routes; | ||
393 | } else { | ||
394 | snd_soc_of_parse_audio_routing(&priv->snd_card, | ||
395 | "audio-routing"); | ||
396 | } | ||
397 | |||
398 | /* sampling rate convert */ | ||
399 | of_property_read_u32(node, "convert-rate", &priv->convert_rate); | ||
400 | |||
401 | /* channels transfer */ | ||
402 | of_property_read_u32(node, "convert-channels", &priv->convert_channels); | ||
403 | |||
404 | dev_dbg(dev, "New rsrc-audio-card: %s\n", | ||
405 | priv->snd_card.name ? priv->snd_card.name : ""); | ||
406 | dev_dbg(dev, "SRC : convert_rate %d\n", priv->convert_rate); | ||
407 | dev_dbg(dev, "CTU : convert_channels %d\n", priv->convert_channels); | ||
408 | |||
409 | ret = rsrc_card_dai_link_of(node, priv); | ||
410 | if (ret < 0) | ||
411 | return ret; | ||
412 | |||
413 | ret = asoc_simple_card_parse_card_name(&priv->snd_card, "card-"); | ||
414 | if (ret < 0) | ||
415 | return ret; | ||
416 | |||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | /* Decrease the reference count of the device nodes */ | ||
421 | static int rsrc_card_unref(struct snd_soc_card *card) | ||
422 | { | ||
423 | struct snd_soc_dai_link *dai_link; | ||
424 | int num_links; | ||
425 | |||
426 | for (num_links = 0, dai_link = card->dai_link; | ||
427 | num_links < card->num_links; | ||
428 | num_links++, dai_link++) { | ||
429 | of_node_put(dai_link->cpu_of_node); | ||
430 | of_node_put(dai_link->codec_of_node); | ||
431 | } | ||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | static int rsrc_card_probe(struct platform_device *pdev) | ||
436 | { | ||
437 | struct rsrc_card_priv *priv; | ||
438 | struct device_node *np = pdev->dev.of_node; | ||
439 | struct device *dev = &pdev->dev; | ||
440 | int ret; | ||
441 | |||
442 | /* Allocate the private data */ | ||
443 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
444 | if (!priv) | ||
445 | return -ENOMEM; | ||
446 | |||
447 | ret = rsrc_card_parse_of(np, priv, dev); | ||
448 | if (ret < 0) { | ||
449 | if (ret != -EPROBE_DEFER) | ||
450 | dev_err(dev, "parse error %d\n", ret); | ||
451 | goto err; | ||
452 | } | ||
453 | |||
454 | snd_soc_card_set_drvdata(&priv->snd_card, priv); | ||
455 | |||
456 | ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); | ||
457 | if (ret >= 0) | ||
458 | return ret; | ||
459 | err: | ||
460 | rsrc_card_unref(&priv->snd_card); | ||
461 | |||
462 | return ret; | ||
463 | } | ||
464 | |||
465 | static int rsrc_card_remove(struct platform_device *pdev) | ||
466 | { | ||
467 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
468 | |||
469 | return rsrc_card_unref(card); | ||
470 | } | ||
471 | |||
472 | static struct platform_driver rsrc_card = { | ||
473 | .driver = { | ||
474 | .name = "renesas-src-audio-card", | ||
475 | .of_match_table = rsrc_card_of_match, | ||
476 | }, | ||
477 | .probe = rsrc_card_probe, | ||
478 | .remove = rsrc_card_remove, | ||
479 | }; | ||
480 | |||
481 | module_platform_driver(rsrc_card); | ||
482 | |||
483 | MODULE_ALIAS("platform:renesas-src-audio-card"); | ||
484 | MODULE_LICENSE("GPL"); | ||
485 | MODULE_DESCRIPTION("Renesas Sampling Rate Convert Sound Card"); | ||
486 | MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); | ||
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 5f848f054745..6cb6db005fc4 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c | |||
@@ -928,7 +928,7 @@ int rsnd_ssi_probe(struct rsnd_priv *priv) | |||
928 | } | 928 | } |
929 | 929 | ||
930 | ops = &rsnd_ssi_non_ops; | 930 | ops = &rsnd_ssi_non_ops; |
931 | if (of_get_property(np, "pio-transfer", NULL)) | 931 | if (of_property_read_bool(np, "pio-transfer")) |
932 | ops = &rsnd_ssi_pio_ops; | 932 | ops = &rsnd_ssi_pio_ops; |
933 | else | 933 | else |
934 | ops = &rsnd_ssi_dma_ops; | 934 | ops = &rsnd_ssi_dma_ops; |
diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c index bc4a55bb3fd9..6c8b0b0c56ec 100644 --- a/sound/soc/soc-ac97.c +++ b/sound/soc/soc-ac97.c | |||
@@ -116,7 +116,7 @@ static int snd_soc_ac97_gpio_direction_out(struct gpio_chip *chip, | |||
116 | return snd_soc_update_bits(codec, AC97_GPIO_CFG, 1 << offset, 0); | 116 | return snd_soc_update_bits(codec, AC97_GPIO_CFG, 1 << offset, 0); |
117 | } | 117 | } |
118 | 118 | ||
119 | static struct gpio_chip snd_soc_ac97_gpio_chip = { | 119 | static const struct gpio_chip snd_soc_ac97_gpio_chip = { |
120 | .label = "snd_soc_ac97", | 120 | .label = "snd_soc_ac97", |
121 | .owner = THIS_MODULE, | 121 | .owner = THIS_MODULE, |
122 | .request = snd_soc_ac97_gpio_request, | 122 | .request = snd_soc_ac97_gpio_request, |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4afa8dba5e98..c0bbcd903261 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -3332,19 +3332,6 @@ int snd_soc_register_codec(struct device *dev, | |||
3332 | if (ret) | 3332 | if (ret) |
3333 | goto err_free; | 3333 | goto err_free; |
3334 | 3334 | ||
3335 | if (codec_drv->controls) { | ||
3336 | codec->component.controls = codec_drv->controls; | ||
3337 | codec->component.num_controls = codec_drv->num_controls; | ||
3338 | } | ||
3339 | if (codec_drv->dapm_widgets) { | ||
3340 | codec->component.dapm_widgets = codec_drv->dapm_widgets; | ||
3341 | codec->component.num_dapm_widgets = codec_drv->num_dapm_widgets; | ||
3342 | } | ||
3343 | if (codec_drv->dapm_routes) { | ||
3344 | codec->component.dapm_routes = codec_drv->dapm_routes; | ||
3345 | codec->component.num_dapm_routes = codec_drv->num_dapm_routes; | ||
3346 | } | ||
3347 | |||
3348 | if (codec_drv->probe) | 3335 | if (codec_drv->probe) |
3349 | codec->component.probe = snd_soc_codec_drv_probe; | 3336 | codec->component.probe = snd_soc_codec_drv_probe; |
3350 | if (codec_drv->remove) | 3337 | if (codec_drv->remove) |
@@ -3732,7 +3719,7 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np, | |||
3732 | * SND_SOC_DAIFMT_CLOCK_MASK area | 3719 | * SND_SOC_DAIFMT_CLOCK_MASK area |
3733 | */ | 3720 | */ |
3734 | snprintf(prop, sizeof(prop), "%scontinuous-clock", prefix); | 3721 | snprintf(prop, sizeof(prop), "%scontinuous-clock", prefix); |
3735 | if (of_get_property(np, prop, NULL)) | 3722 | if (of_property_read_bool(np, prop)) |
3736 | format |= SND_SOC_DAIFMT_CONT; | 3723 | format |= SND_SOC_DAIFMT_CONT; |
3737 | else | 3724 | else |
3738 | format |= SND_SOC_DAIFMT_GATED; | 3725 | format |= SND_SOC_DAIFMT_GATED; |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d908ff8f9755..3bbe32ee4630 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -823,6 +823,7 @@ static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w, | |||
823 | case snd_soc_dapm_switch: | 823 | case snd_soc_dapm_switch: |
824 | case snd_soc_dapm_mixer: | 824 | case snd_soc_dapm_mixer: |
825 | case snd_soc_dapm_pga: | 825 | case snd_soc_dapm_pga: |
826 | case snd_soc_dapm_out_drv: | ||
826 | wname_in_long_name = true; | 827 | wname_in_long_name = true; |
827 | kcname_in_long_name = true; | 828 | kcname_in_long_name = true; |
828 | break; | 829 | break; |
@@ -1169,7 +1170,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, | |||
1169 | * @custom_stop_condition: (optional) a function meant to stop the widget graph | 1170 | * @custom_stop_condition: (optional) a function meant to stop the widget graph |
1170 | * walk based on custom logic. | 1171 | * walk based on custom logic. |
1171 | * | 1172 | * |
1172 | * Queries DAPM graph as to whether an valid audio stream path exists for | 1173 | * Queries DAPM graph as to whether a valid audio stream path exists for |
1173 | * the initial stream specified by name. This takes into account | 1174 | * the initial stream specified by name. This takes into account |
1174 | * current mixer and mux kcontrol settings. Creates list of valid widgets. | 1175 | * current mixer and mux kcontrol settings. Creates list of valid widgets. |
1175 | * | 1176 | * |
@@ -1294,8 +1295,7 @@ static int dapm_widget_power_check(struct snd_soc_dapm_widget *w) | |||
1294 | return w->new_power; | 1295 | return w->new_power; |
1295 | } | 1296 | } |
1296 | 1297 | ||
1297 | /* Generic check to see if a widget should be powered. | 1298 | /* Generic check to see if a widget should be powered. */ |
1298 | */ | ||
1299 | static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) | 1299 | static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) |
1300 | { | 1300 | { |
1301 | int in, out; | 1301 | int in, out; |
@@ -1646,7 +1646,7 @@ static void dapm_pre_sequence_async(void *data, async_cookie_t cookie) | |||
1646 | struct snd_soc_dapm_context *d = data; | 1646 | struct snd_soc_dapm_context *d = data; |
1647 | int ret; | 1647 | int ret; |
1648 | 1648 | ||
1649 | /* If we're off and we're not supposed to be go into STANDBY */ | 1649 | /* If we're off and we're not supposed to go into STANDBY */ |
1650 | if (d->bias_level == SND_SOC_BIAS_OFF && | 1650 | if (d->bias_level == SND_SOC_BIAS_OFF && |
1651 | d->target_bias_level != SND_SOC_BIAS_OFF) { | 1651 | d->target_bias_level != SND_SOC_BIAS_OFF) { |
1652 | if (d->dev) | 1652 | if (d->dev) |
@@ -1798,7 +1798,7 @@ static bool dapm_idle_bias_off(struct snd_soc_dapm_context *dapm) | |||
1798 | * A complete path is a route that has valid endpoints i.e.:- | 1798 | * A complete path is a route that has valid endpoints i.e.:- |
1799 | * | 1799 | * |
1800 | * o DAC to output pin. | 1800 | * o DAC to output pin. |
1801 | * o Input Pin to ADC. | 1801 | * o Input pin to ADC. |
1802 | * o Input pin to Output pin (bypass, sidetone) | 1802 | * o Input pin to Output pin (bypass, sidetone) |
1803 | * o DAC to ADC (loopback). | 1803 | * o DAC to ADC (loopback). |
1804 | */ | 1804 | */ |
@@ -2114,7 +2114,7 @@ static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm) | |||
2114 | * soc_dapm_connect_path() - Connects or disconnects a path | 2114 | * soc_dapm_connect_path() - Connects or disconnects a path |
2115 | * @path: The path to update | 2115 | * @path: The path to update |
2116 | * @connect: The new connect state of the path. True if the path is connected, | 2116 | * @connect: The new connect state of the path. True if the path is connected, |
2117 | * false if it is disconneted. | 2117 | * false if it is disconnected. |
2118 | * @reason: The reason why the path changed (for debugging only) | 2118 | * @reason: The reason why the path changed (for debugging only) |
2119 | */ | 2119 | */ |
2120 | static void soc_dapm_connect_path(struct snd_soc_dapm_path *path, | 2120 | static void soc_dapm_connect_path(struct snd_soc_dapm_path *path, |
@@ -2233,7 +2233,7 @@ static ssize_t dapm_widget_show_component(struct snd_soc_component *cmpnt, | |||
2233 | if (w->dapm != dapm) | 2233 | if (w->dapm != dapm) |
2234 | continue; | 2234 | continue; |
2235 | 2235 | ||
2236 | /* only display widgets that burnm power */ | 2236 | /* only display widgets that burn power */ |
2237 | switch (w->id) { | 2237 | switch (w->id) { |
2238 | case snd_soc_dapm_hp: | 2238 | case snd_soc_dapm_hp: |
2239 | case snd_soc_dapm_mic: | 2239 | case snd_soc_dapm_mic: |
@@ -2461,7 +2461,7 @@ static void dapm_update_widget_flags(struct snd_soc_dapm_widget *w) | |||
2461 | 2461 | ||
2462 | switch (w->id) { | 2462 | switch (w->id) { |
2463 | case snd_soc_dapm_input: | 2463 | case snd_soc_dapm_input: |
2464 | /* On a fully routed card a input is never a source */ | 2464 | /* On a fully routed card an input is never a source */ |
2465 | if (w->dapm->card->fully_routed) | 2465 | if (w->dapm->card->fully_routed) |
2466 | return; | 2466 | return; |
2467 | ep = SND_SOC_DAPM_EP_SOURCE; | 2467 | ep = SND_SOC_DAPM_EP_SOURCE; |
@@ -3049,6 +3049,9 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, | |||
3049 | } | 3049 | } |
3050 | mutex_unlock(&card->dapm_mutex); | 3050 | mutex_unlock(&card->dapm_mutex); |
3051 | 3051 | ||
3052 | if (ret) | ||
3053 | return ret; | ||
3054 | |||
3052 | if (invert) | 3055 | if (invert) |
3053 | ucontrol->value.integer.value[0] = max - val; | 3056 | ucontrol->value.integer.value[0] = max - val; |
3054 | else | 3057 | else |
@@ -3200,7 +3203,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, | |||
3200 | if (e->shift_l != e->shift_r) { | 3203 | if (e->shift_l != e->shift_r) { |
3201 | if (item[1] > e->items) | 3204 | if (item[1] > e->items) |
3202 | return -EINVAL; | 3205 | return -EINVAL; |
3203 | val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_l; | 3206 | val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r; |
3204 | mask |= e->mask << e->shift_r; | 3207 | mask |= e->mask << e->shift_r; |
3205 | } | 3208 | } |
3206 | 3209 | ||
@@ -3445,7 +3448,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, | |||
3445 | w->endpoints[dir] = -1; | 3448 | w->endpoints[dir] = -1; |
3446 | } | 3449 | } |
3447 | 3450 | ||
3448 | /* machine layer set ups unconnected pins and insertions */ | 3451 | /* machine layer sets up unconnected pins and insertions */ |
3449 | w->connected = 1; | 3452 | w->connected = 1; |
3450 | return w; | 3453 | return w; |
3451 | } | 3454 | } |
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index a513a34a51d2..9fc1a7bb8b95 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c | |||
@@ -77,7 +77,7 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol, | |||
77 | item = snd_soc_enum_val_to_item(e, val); | 77 | item = snd_soc_enum_val_to_item(e, val); |
78 | ucontrol->value.enumerated.item[0] = item; | 78 | ucontrol->value.enumerated.item[0] = item; |
79 | if (e->shift_l != e->shift_r) { | 79 | if (e->shift_l != e->shift_r) { |
80 | val = (reg_val >> e->shift_l) & e->mask; | 80 | val = (reg_val >> e->shift_r) & e->mask; |
81 | item = snd_soc_enum_val_to_item(e, val); | 81 | item = snd_soc_enum_val_to_item(e, val); |
82 | ucontrol->value.enumerated.item[1] = item; | 82 | ucontrol->value.enumerated.item[1] = item; |
83 | } | 83 | } |
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 60d702f8b9f0..d56a16a0f6fa 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
@@ -1694,6 +1694,9 @@ static int dpcm_apply_symmetry(struct snd_pcm_substream *fe_substream, | |||
1694 | struct snd_soc_pcm_runtime *rtd = be_substream->private_data; | 1694 | struct snd_soc_pcm_runtime *rtd = be_substream->private_data; |
1695 | int i; | 1695 | int i; |
1696 | 1696 | ||
1697 | if (rtd->dai_link->be_hw_params_fixup) | ||
1698 | continue; | ||
1699 | |||
1697 | if (soc_pcm_has_symmetry(be_substream)) | 1700 | if (soc_pcm_has_symmetry(be_substream)) |
1698 | be_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; | 1701 | be_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; |
1699 | 1702 | ||
@@ -1790,7 +1793,7 @@ int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream) | |||
1790 | continue; | 1793 | continue; |
1791 | 1794 | ||
1792 | dev_dbg(be->dev, "ASoC: close BE %s\n", | 1795 | dev_dbg(be->dev, "ASoC: close BE %s\n", |
1793 | dpcm->fe->dai_link->name); | 1796 | be->dai_link->name); |
1794 | 1797 | ||
1795 | soc_pcm_close(be_substream); | 1798 | soc_pcm_close(be_substream); |
1796 | be_substream->runtime = NULL; | 1799 | be_substream->runtime = NULL; |
@@ -1856,7 +1859,7 @@ int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) | |||
1856 | continue; | 1859 | continue; |
1857 | 1860 | ||
1858 | dev_dbg(be->dev, "ASoC: hw_free BE %s\n", | 1861 | dev_dbg(be->dev, "ASoC: hw_free BE %s\n", |
1859 | dpcm->fe->dai_link->name); | 1862 | be->dai_link->name); |
1860 | 1863 | ||
1861 | soc_pcm_hw_free(be_substream); | 1864 | soc_pcm_hw_free(be_substream); |
1862 | 1865 | ||
@@ -1934,7 +1937,7 @@ int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) | |||
1934 | continue; | 1937 | continue; |
1935 | 1938 | ||
1936 | dev_dbg(be->dev, "ASoC: hw_params BE %s\n", | 1939 | dev_dbg(be->dev, "ASoC: hw_params BE %s\n", |
1937 | dpcm->fe->dai_link->name); | 1940 | be->dai_link->name); |
1938 | 1941 | ||
1939 | ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params); | 1942 | ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params); |
1940 | if (ret < 0) { | 1943 | if (ret < 0) { |
@@ -2014,7 +2017,7 @@ static int dpcm_do_trigger(struct snd_soc_dpcm *dpcm, | |||
2014 | int ret; | 2017 | int ret; |
2015 | 2018 | ||
2016 | dev_dbg(dpcm->be->dev, "ASoC: trigger BE %s cmd %d\n", | 2019 | dev_dbg(dpcm->be->dev, "ASoC: trigger BE %s cmd %d\n", |
2017 | dpcm->fe->dai_link->name, cmd); | 2020 | dpcm->be->dai_link->name, cmd); |
2018 | 2021 | ||
2019 | ret = soc_pcm_trigger(substream, cmd); | 2022 | ret = soc_pcm_trigger(substream, cmd); |
2020 | if (ret < 0) | 2023 | if (ret < 0) |
@@ -2229,7 +2232,7 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) | |||
2229 | continue; | 2232 | continue; |
2230 | 2233 | ||
2231 | dev_dbg(be->dev, "ASoC: prepare BE %s\n", | 2234 | dev_dbg(be->dev, "ASoC: prepare BE %s\n", |
2232 | dpcm->fe->dai_link->name); | 2235 | be->dai_link->name); |
2233 | 2236 | ||
2234 | ret = soc_pcm_prepare(be_substream); | 2237 | ret = soc_pcm_prepare(be_substream); |
2235 | if (ret < 0) { | 2238 | if (ret < 0) { |
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index ee7f15aa46fc..6b05047a4134 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c | |||
@@ -48,9 +48,10 @@ | |||
48 | #define SOC_TPLG_PASS_PCM_DAI 4 | 48 | #define SOC_TPLG_PASS_PCM_DAI 4 |
49 | #define SOC_TPLG_PASS_GRAPH 5 | 49 | #define SOC_TPLG_PASS_GRAPH 5 |
50 | #define SOC_TPLG_PASS_PINS 6 | 50 | #define SOC_TPLG_PASS_PINS 6 |
51 | #define SOC_TPLG_PASS_BE_DAI 7 | ||
51 | 52 | ||
52 | #define SOC_TPLG_PASS_START SOC_TPLG_PASS_MANIFEST | 53 | #define SOC_TPLG_PASS_START SOC_TPLG_PASS_MANIFEST |
53 | #define SOC_TPLG_PASS_END SOC_TPLG_PASS_PINS | 54 | #define SOC_TPLG_PASS_END SOC_TPLG_PASS_BE_DAI |
54 | 55 | ||
55 | struct soc_tplg { | 56 | struct soc_tplg { |
56 | const struct firmware *fw; | 57 | const struct firmware *fw; |
@@ -1475,6 +1476,7 @@ widget: | |||
1475 | if (widget == NULL) { | 1476 | if (widget == NULL) { |
1476 | dev_err(tplg->dev, "ASoC: failed to create widget %s controls\n", | 1477 | dev_err(tplg->dev, "ASoC: failed to create widget %s controls\n", |
1477 | w->name); | 1478 | w->name); |
1479 | ret = -ENOMEM; | ||
1478 | goto hdr_err; | 1480 | goto hdr_err; |
1479 | } | 1481 | } |
1480 | 1482 | ||
@@ -1554,6 +1556,25 @@ static void set_stream_info(struct snd_soc_pcm_stream *stream, | |||
1554 | stream->rate_min = caps->rate_min; | 1556 | stream->rate_min = caps->rate_min; |
1555 | stream->rate_max = caps->rate_max; | 1557 | stream->rate_max = caps->rate_max; |
1556 | stream->formats = caps->formats; | 1558 | stream->formats = caps->formats; |
1559 | stream->sig_bits = caps->sig_bits; | ||
1560 | } | ||
1561 | |||
1562 | static void set_dai_flags(struct snd_soc_dai_driver *dai_drv, | ||
1563 | unsigned int flag_mask, unsigned int flags) | ||
1564 | { | ||
1565 | if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES) | ||
1566 | dai_drv->symmetric_rates = | ||
1567 | flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES ? 1 : 0; | ||
1568 | |||
1569 | if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS) | ||
1570 | dai_drv->symmetric_channels = | ||
1571 | flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS ? | ||
1572 | 1 : 0; | ||
1573 | |||
1574 | if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS) | ||
1575 | dai_drv->symmetric_samplebits = | ||
1576 | flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS ? | ||
1577 | 1 : 0; | ||
1557 | } | 1578 | } |
1558 | 1579 | ||
1559 | static int soc_tplg_dai_create(struct soc_tplg *tplg, | 1580 | static int soc_tplg_dai_create(struct soc_tplg *tplg, |
@@ -1690,8 +1711,96 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg, | |||
1690 | return 0; | 1711 | return 0; |
1691 | } | 1712 | } |
1692 | 1713 | ||
1714 | /* * | ||
1715 | * soc_tplg_be_dai_config - Find and configure an existing BE DAI. | ||
1716 | * @tplg: topology context | ||
1717 | * @be: topology BE DAI configs. | ||
1718 | * | ||
1719 | * The BE dai should already be registered by the platform driver. The | ||
1720 | * platform driver should specify the BE DAI name and ID for matching. | ||
1721 | */ | ||
1722 | static int soc_tplg_be_dai_config(struct soc_tplg *tplg, | ||
1723 | struct snd_soc_tplg_be_dai *be) | ||
1724 | { | ||
1725 | struct snd_soc_dai_link_component dai_component = {0}; | ||
1726 | struct snd_soc_dai *dai; | ||
1727 | struct snd_soc_dai_driver *dai_drv; | ||
1728 | struct snd_soc_pcm_stream *stream; | ||
1729 | struct snd_soc_tplg_stream_caps *caps; | ||
1730 | int ret; | ||
1731 | |||
1732 | dai_component.dai_name = be->dai_name; | ||
1733 | dai = snd_soc_find_dai(&dai_component); | ||
1734 | if (!dai) { | ||
1735 | dev_err(tplg->dev, "ASoC: BE DAI %s not registered\n", | ||
1736 | be->dai_name); | ||
1737 | return -EINVAL; | ||
1738 | } | ||
1739 | |||
1740 | if (be->dai_id != dai->id) { | ||
1741 | dev_err(tplg->dev, "ASoC: BE DAI %s id mismatch\n", | ||
1742 | be->dai_name); | ||
1743 | return -EINVAL; | ||
1744 | } | ||
1745 | |||
1746 | dai_drv = dai->driver; | ||
1747 | if (!dai_drv) | ||
1748 | return -EINVAL; | ||
1749 | |||
1750 | if (be->playback) { | ||
1751 | stream = &dai_drv->playback; | ||
1752 | caps = &be->caps[SND_SOC_TPLG_STREAM_PLAYBACK]; | ||
1753 | set_stream_info(stream, caps); | ||
1754 | } | ||
1755 | |||
1756 | if (be->capture) { | ||
1757 | stream = &dai_drv->capture; | ||
1758 | caps = &be->caps[SND_SOC_TPLG_STREAM_CAPTURE]; | ||
1759 | set_stream_info(stream, caps); | ||
1760 | } | ||
1761 | |||
1762 | if (be->flag_mask) | ||
1763 | set_dai_flags(dai_drv, be->flag_mask, be->flags); | ||
1764 | |||
1765 | /* pass control to component driver for optional further init */ | ||
1766 | ret = soc_tplg_dai_load(tplg, dai_drv); | ||
1767 | if (ret < 0) { | ||
1768 | dev_err(tplg->comp->dev, "ASoC: DAI loading failed\n"); | ||
1769 | return ret; | ||
1770 | } | ||
1771 | |||
1772 | return 0; | ||
1773 | } | ||
1774 | |||
1775 | static int soc_tplg_be_dai_elems_load(struct soc_tplg *tplg, | ||
1776 | struct snd_soc_tplg_hdr *hdr) | ||
1777 | { | ||
1778 | struct snd_soc_tplg_be_dai *be; | ||
1779 | int count = hdr->count; | ||
1780 | int i; | ||
1781 | |||
1782 | if (tplg->pass != SOC_TPLG_PASS_BE_DAI) | ||
1783 | return 0; | ||
1784 | |||
1785 | /* config the existing BE DAIs */ | ||
1786 | for (i = 0; i < count; i++) { | ||
1787 | be = (struct snd_soc_tplg_be_dai *)tplg->pos; | ||
1788 | if (be->size != sizeof(*be)) { | ||
1789 | dev_err(tplg->dev, "ASoC: invalid BE DAI size\n"); | ||
1790 | return -EINVAL; | ||
1791 | } | ||
1792 | |||
1793 | soc_tplg_be_dai_config(tplg, be); | ||
1794 | tplg->pos += (sizeof(*be) + be->priv.size); | ||
1795 | } | ||
1796 | |||
1797 | dev_dbg(tplg->dev, "ASoC: Configure %d BE DAIs\n", count); | ||
1798 | return 0; | ||
1799 | } | ||
1800 | |||
1801 | |||
1693 | static int soc_tplg_manifest_load(struct soc_tplg *tplg, | 1802 | static int soc_tplg_manifest_load(struct soc_tplg *tplg, |
1694 | struct snd_soc_tplg_hdr *hdr) | 1803 | struct snd_soc_tplg_hdr *hdr) |
1695 | { | 1804 | { |
1696 | struct snd_soc_tplg_manifest *manifest; | 1805 | struct snd_soc_tplg_manifest *manifest; |
1697 | 1806 | ||
@@ -1793,6 +1902,8 @@ static int soc_tplg_load_header(struct soc_tplg *tplg, | |||
1793 | return soc_tplg_dapm_widget_elems_load(tplg, hdr); | 1902 | return soc_tplg_dapm_widget_elems_load(tplg, hdr); |
1794 | case SND_SOC_TPLG_TYPE_PCM: | 1903 | case SND_SOC_TPLG_TYPE_PCM: |
1795 | return soc_tplg_pcm_elems_load(tplg, hdr); | 1904 | return soc_tplg_pcm_elems_load(tplg, hdr); |
1905 | case SND_SOC_TPLG_TYPE_BE_DAI: | ||
1906 | return soc_tplg_be_dai_elems_load(tplg, hdr); | ||
1796 | case SND_SOC_TPLG_TYPE_MANIFEST: | 1907 | case SND_SOC_TPLG_TYPE_MANIFEST: |
1797 | return soc_tplg_manifest_load(tplg, hdr); | 1908 | return soc_tplg_manifest_load(tplg, hdr); |
1798 | default: | 1909 | default: |
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 53dd085d3ee2..393e8f0fe2cc 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c | |||
@@ -80,7 +80,7 @@ static int dummy_dma_open(struct snd_pcm_substream *substream) | |||
80 | return 0; | 80 | return 0; |
81 | } | 81 | } |
82 | 82 | ||
83 | static struct snd_pcm_ops dummy_dma_ops = { | 83 | static const struct snd_pcm_ops dummy_dma_ops = { |
84 | .open = dummy_dma_open, | 84 | .open = dummy_dma_open, |
85 | .ioctl = snd_pcm_lib_ioctl, | 85 | .ioctl = snd_pcm_lib_ioctl, |
86 | }; | 86 | }; |
diff --git a/sound/soc/sti/sti_uniperif.c b/sound/soc/sti/sti_uniperif.c index 488ef4ed8fba..549fac349fa0 100644 --- a/sound/soc/sti/sti_uniperif.c +++ b/sound/soc/sti/sti_uniperif.c | |||
@@ -19,6 +19,84 @@ | |||
19 | #define UNIPERIF_MAX_FRAME_SZ 0x20 | 19 | #define UNIPERIF_MAX_FRAME_SZ 0x20 |
20 | #define UNIPERIF_ALLOWED_FRAME_SZ (0x08 | 0x10 | 0x18 | UNIPERIF_MAX_FRAME_SZ) | 20 | #define UNIPERIF_ALLOWED_FRAME_SZ (0x08 | 0x10 | 0x18 | UNIPERIF_MAX_FRAME_SZ) |
21 | 21 | ||
22 | struct sti_uniperiph_dev_data { | ||
23 | unsigned int id; /* Nb available player instances */ | ||
24 | unsigned int version; /* player IP version */ | ||
25 | unsigned int stream; | ||
26 | const char *dai_names; | ||
27 | enum uniperif_type type; | ||
28 | }; | ||
29 | |||
30 | static const struct sti_uniperiph_dev_data sti_uniplayer_hdmi = { | ||
31 | .id = 0, | ||
32 | .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0, | ||
33 | .stream = SNDRV_PCM_STREAM_PLAYBACK, | ||
34 | .dai_names = "Uni Player #0 (HDMI)", | ||
35 | .type = SND_ST_UNIPERIF_TYPE_HDMI | ||
36 | }; | ||
37 | |||
38 | static const struct sti_uniperiph_dev_data sti_uniplayer_pcm_out = { | ||
39 | .id = 1, | ||
40 | .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0, | ||
41 | .stream = SNDRV_PCM_STREAM_PLAYBACK, | ||
42 | .dai_names = "Uni Player #1 (PCM OUT)", | ||
43 | .type = SND_ST_UNIPERIF_TYPE_PCM | SND_ST_UNIPERIF_TYPE_TDM, | ||
44 | }; | ||
45 | |||
46 | static const struct sti_uniperiph_dev_data sti_uniplayer_dac = { | ||
47 | .id = 2, | ||
48 | .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0, | ||
49 | .stream = SNDRV_PCM_STREAM_PLAYBACK, | ||
50 | .dai_names = "Uni Player #2 (DAC)", | ||
51 | .type = SND_ST_UNIPERIF_TYPE_PCM, | ||
52 | }; | ||
53 | |||
54 | static const struct sti_uniperiph_dev_data sti_uniplayer_spdif = { | ||
55 | .id = 3, | ||
56 | .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0, | ||
57 | .stream = SNDRV_PCM_STREAM_PLAYBACK, | ||
58 | .dai_names = "Uni Player #3 (SPDIF)", | ||
59 | .type = SND_ST_UNIPERIF_TYPE_SPDIF | ||
60 | }; | ||
61 | |||
62 | static const struct sti_uniperiph_dev_data sti_unireader_pcm_in = { | ||
63 | .id = 0, | ||
64 | .version = SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0, | ||
65 | .stream = SNDRV_PCM_STREAM_CAPTURE, | ||
66 | .dai_names = "Uni Reader #0 (PCM IN)", | ||
67 | .type = SND_ST_UNIPERIF_TYPE_PCM | SND_ST_UNIPERIF_TYPE_TDM, | ||
68 | }; | ||
69 | |||
70 | static const struct sti_uniperiph_dev_data sti_unireader_hdmi_in = { | ||
71 | .id = 1, | ||
72 | .version = SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0, | ||
73 | .stream = SNDRV_PCM_STREAM_CAPTURE, | ||
74 | .dai_names = "Uni Reader #1 (HDMI IN)", | ||
75 | .type = SND_ST_UNIPERIF_TYPE_PCM, | ||
76 | }; | ||
77 | |||
78 | static const struct of_device_id snd_soc_sti_match[] = { | ||
79 | { .compatible = "st,stih407-uni-player-hdmi", | ||
80 | .data = &sti_uniplayer_hdmi | ||
81 | }, | ||
82 | { .compatible = "st,stih407-uni-player-pcm-out", | ||
83 | .data = &sti_uniplayer_pcm_out | ||
84 | }, | ||
85 | { .compatible = "st,stih407-uni-player-dac", | ||
86 | .data = &sti_uniplayer_dac | ||
87 | }, | ||
88 | { .compatible = "st,stih407-uni-player-spdif", | ||
89 | .data = &sti_uniplayer_spdif | ||
90 | }, | ||
91 | { .compatible = "st,stih407-uni-reader-pcm_in", | ||
92 | .data = &sti_unireader_pcm_in | ||
93 | }, | ||
94 | { .compatible = "st,stih407-uni-reader-hdmi", | ||
95 | .data = &sti_unireader_hdmi_in | ||
96 | }, | ||
97 | {}, | ||
98 | }; | ||
99 | |||
22 | int sti_uniperiph_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, | 100 | int sti_uniperiph_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, |
23 | unsigned int rx_mask, int slots, | 101 | unsigned int rx_mask, int slots, |
24 | int slot_width) | 102 | int slot_width) |
@@ -167,8 +245,8 @@ static int sti_uniperiph_dai_create_ctrl(struct snd_soc_dai *dai) | |||
167 | * Uniperipheral instance ID | 245 | * Uniperipheral instance ID |
168 | */ | 246 | */ |
169 | ctrl = &uni->snd_ctrls[i]; | 247 | ctrl = &uni->snd_ctrls[i]; |
170 | ctrl->index = uni->info->id; | 248 | ctrl->index = uni->id; |
171 | ctrl->device = uni->info->id; | 249 | ctrl->device = uni->id; |
172 | } | 250 | } |
173 | 251 | ||
174 | return snd_soc_add_dai_controls(dai, uni->snd_ctrls, uni->num_ctrls); | 252 | return snd_soc_add_dai_controls(dai, uni->snd_ctrls, uni->num_ctrls); |
@@ -186,7 +264,7 @@ int sti_uniperiph_dai_hw_params(struct snd_pcm_substream *substream, | |||
186 | struct snd_dmaengine_dai_dma_data *dma_data; | 264 | struct snd_dmaengine_dai_dma_data *dma_data; |
187 | int transfer_size; | 265 | int transfer_size; |
188 | 266 | ||
189 | if (uni->info->type == SND_ST_UNIPERIF_TYPE_TDM) | 267 | if (uni->type == SND_ST_UNIPERIF_TYPE_TDM) |
190 | /* transfer size = user frame size (in 32-bits FIFO cell) */ | 268 | /* transfer size = user frame size (in 32-bits FIFO cell) */ |
191 | transfer_size = snd_soc_params_to_frame_size(params) / 32; | 269 | transfer_size = snd_soc_params_to_frame_size(params) / 32; |
192 | else | 270 | else |
@@ -235,7 +313,7 @@ static int sti_uniperiph_dai_resume(struct snd_soc_dai *dai) | |||
235 | struct uniperif *uni = priv->dai_data.uni; | 313 | struct uniperif *uni = priv->dai_data.uni; |
236 | int ret; | 314 | int ret; |
237 | 315 | ||
238 | if (of_device_is_compatible(dai->dev->of_node, "st,sti-uni-player")) { | 316 | if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) { |
239 | ret = uni_player_resume(uni); | 317 | ret = uni_player_resume(uni); |
240 | if (ret) | 318 | if (ret) |
241 | return ret; | 319 | return ret; |
@@ -256,7 +334,7 @@ static int sti_uniperiph_dai_probe(struct snd_soc_dai *dai) | |||
256 | struct sti_uniperiph_dai *dai_data = &priv->dai_data; | 334 | struct sti_uniperiph_dai *dai_data = &priv->dai_data; |
257 | 335 | ||
258 | /* DMA settings*/ | 336 | /* DMA settings*/ |
259 | if (of_device_is_compatible(dai->dev->of_node, "st,sti-uni-player")) | 337 | if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) |
260 | snd_soc_dai_init_dma_data(dai, &dai_data->dma_data, NULL); | 338 | snd_soc_dai_init_dma_data(dai, &dai_data->dma_data, NULL); |
261 | else | 339 | else |
262 | snd_soc_dai_init_dma_data(dai, NULL, &dai_data->dma_data); | 340 | snd_soc_dai_init_dma_data(dai, NULL, &dai_data->dma_data); |
@@ -280,25 +358,32 @@ static const struct snd_soc_component_driver sti_uniperiph_dai_component = { | |||
280 | static int sti_uniperiph_cpu_dai_of(struct device_node *node, | 358 | static int sti_uniperiph_cpu_dai_of(struct device_node *node, |
281 | struct sti_uniperiph_data *priv) | 359 | struct sti_uniperiph_data *priv) |
282 | { | 360 | { |
283 | const char *str; | ||
284 | int ret; | ||
285 | struct device *dev = &priv->pdev->dev; | 361 | struct device *dev = &priv->pdev->dev; |
286 | struct sti_uniperiph_dai *dai_data = &priv->dai_data; | 362 | struct sti_uniperiph_dai *dai_data = &priv->dai_data; |
287 | struct snd_soc_dai_driver *dai = priv->dai; | 363 | struct snd_soc_dai_driver *dai = priv->dai; |
288 | struct snd_soc_pcm_stream *stream; | 364 | struct snd_soc_pcm_stream *stream; |
289 | struct uniperif *uni; | 365 | struct uniperif *uni; |
366 | const struct of_device_id *of_id; | ||
367 | const struct sti_uniperiph_dev_data *dev_data; | ||
368 | const char *mode; | ||
369 | |||
370 | /* Populate data structure depending on compatibility */ | ||
371 | of_id = of_match_node(snd_soc_sti_match, node); | ||
372 | if (!of_id->data) { | ||
373 | dev_err(dev, "data associated to device is missing"); | ||
374 | return -EINVAL; | ||
375 | } | ||
376 | dev_data = (struct sti_uniperiph_dev_data *)of_id->data; | ||
290 | 377 | ||
291 | uni = devm_kzalloc(dev, sizeof(*uni), GFP_KERNEL); | 378 | uni = devm_kzalloc(dev, sizeof(*uni), GFP_KERNEL); |
292 | if (!uni) | 379 | if (!uni) |
293 | return -ENOMEM; | 380 | return -ENOMEM; |
294 | 381 | ||
382 | uni->id = dev_data->id; | ||
383 | uni->ver = dev_data->version; | ||
384 | |||
295 | *dai = sti_uniperiph_dai_template; | 385 | *dai = sti_uniperiph_dai_template; |
296 | ret = of_property_read_string(node, "dai-name", &str); | 386 | dai->name = dev_data->dai_names; |
297 | if (ret < 0) { | ||
298 | dev_err(dev, "%s: dai name missing.\n", __func__); | ||
299 | return -EINVAL; | ||
300 | } | ||
301 | dai->name = str; | ||
302 | 387 | ||
303 | /* Get resources */ | 388 | /* Get resources */ |
304 | uni->mem_region = platform_get_resource(priv->pdev, IORESOURCE_MEM, 0); | 389 | uni->mem_region = platform_get_resource(priv->pdev, IORESOURCE_MEM, 0); |
@@ -322,9 +407,20 @@ static int sti_uniperiph_cpu_dai_of(struct device_node *node, | |||
322 | return -ENXIO; | 407 | return -ENXIO; |
323 | } | 408 | } |
324 | 409 | ||
410 | uni->type = dev_data->type; | ||
411 | |||
412 | /* check if player should be configured for tdm */ | ||
413 | if (dev_data->type & SND_ST_UNIPERIF_TYPE_TDM) { | ||
414 | if (!of_property_read_string(node, "st,tdm-mode", &mode)) | ||
415 | uni->type = SND_ST_UNIPERIF_TYPE_TDM; | ||
416 | else | ||
417 | uni->type = SND_ST_UNIPERIF_TYPE_PCM; | ||
418 | } | ||
419 | |||
325 | dai_data->uni = uni; | 420 | dai_data->uni = uni; |
421 | dai_data->stream = dev_data->stream; | ||
326 | 422 | ||
327 | if (of_device_is_compatible(node, "st,sti-uni-player")) { | 423 | if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) { |
328 | uni_player_init(priv->pdev, uni); | 424 | uni_player_init(priv->pdev, uni); |
329 | stream = &dai->playback; | 425 | stream = &dai->playback; |
330 | } else { | 426 | } else { |
@@ -376,12 +472,6 @@ static int sti_uniperiph_probe(struct platform_device *pdev) | |||
376 | &dmaengine_pcm_config, 0); | 472 | &dmaengine_pcm_config, 0); |
377 | } | 473 | } |
378 | 474 | ||
379 | static const struct of_device_id snd_soc_sti_match[] = { | ||
380 | { .compatible = "st,sti-uni-player", }, | ||
381 | { .compatible = "st,sti-uni-reader", }, | ||
382 | {}, | ||
383 | }; | ||
384 | |||
385 | static struct platform_driver sti_uniperiph_driver = { | 475 | static struct platform_driver sti_uniperiph_driver = { |
386 | .driver = { | 476 | .driver = { |
387 | .name = "sti-uniperiph-dai", | 477 | .name = "sti-uniperiph-dai", |
diff --git a/sound/soc/sti/uniperif.h b/sound/soc/sti/uniperif.h index eb9933c62ad6..1993c655fb79 100644 --- a/sound/soc/sti/uniperif.h +++ b/sound/soc/sti/uniperif.h | |||
@@ -1220,16 +1220,16 @@ | |||
1220 | #define UNIPERIF_FIFO_FRAMES 4 /* FDMA trigger limit in frames */ | 1220 | #define UNIPERIF_FIFO_FRAMES 4 /* FDMA trigger limit in frames */ |
1221 | 1221 | ||
1222 | #define UNIPERIF_TYPE_IS_HDMI(p) \ | 1222 | #define UNIPERIF_TYPE_IS_HDMI(p) \ |
1223 | ((p)->info->type == SND_ST_UNIPERIF_TYPE_HDMI) | 1223 | ((p)->type == SND_ST_UNIPERIF_TYPE_HDMI) |
1224 | #define UNIPERIF_TYPE_IS_PCM(p) \ | 1224 | #define UNIPERIF_TYPE_IS_PCM(p) \ |
1225 | ((p)->info->type == SND_ST_UNIPERIF_TYPE_PCM) | 1225 | ((p)->type == SND_ST_UNIPERIF_TYPE_PCM) |
1226 | #define UNIPERIF_TYPE_IS_SPDIF(p) \ | 1226 | #define UNIPERIF_TYPE_IS_SPDIF(p) \ |
1227 | ((p)->info->type == SND_ST_UNIPERIF_TYPE_SPDIF) | 1227 | ((p)->type == SND_ST_UNIPERIF_TYPE_SPDIF) |
1228 | #define UNIPERIF_TYPE_IS_IEC958(p) \ | 1228 | #define UNIPERIF_TYPE_IS_IEC958(p) \ |
1229 | (UNIPERIF_TYPE_IS_HDMI(p) || \ | 1229 | (UNIPERIF_TYPE_IS_HDMI(p) || \ |
1230 | UNIPERIF_TYPE_IS_SPDIF(p)) | 1230 | UNIPERIF_TYPE_IS_SPDIF(p)) |
1231 | #define UNIPERIF_TYPE_IS_TDM(p) \ | 1231 | #define UNIPERIF_TYPE_IS_TDM(p) \ |
1232 | ((p)->info->type == SND_ST_UNIPERIF_TYPE_TDM) | 1232 | ((p)->type == SND_ST_UNIPERIF_TYPE_TDM) |
1233 | 1233 | ||
1234 | /* | 1234 | /* |
1235 | * Uniperipheral IP revisions | 1235 | * Uniperipheral IP revisions |
@@ -1249,11 +1249,11 @@ enum uniperif_version { | |||
1249 | }; | 1249 | }; |
1250 | 1250 | ||
1251 | enum uniperif_type { | 1251 | enum uniperif_type { |
1252 | SND_ST_UNIPERIF_TYPE_NONE, | 1252 | SND_ST_UNIPERIF_TYPE_NONE = 0x00, |
1253 | SND_ST_UNIPERIF_TYPE_HDMI, | 1253 | SND_ST_UNIPERIF_TYPE_HDMI = 0x01, |
1254 | SND_ST_UNIPERIF_TYPE_PCM, | 1254 | SND_ST_UNIPERIF_TYPE_PCM = 0x02, |
1255 | SND_ST_UNIPERIF_TYPE_SPDIF, | 1255 | SND_ST_UNIPERIF_TYPE_SPDIF = 0x04, |
1256 | SND_ST_UNIPERIF_TYPE_TDM | 1256 | SND_ST_UNIPERIF_TYPE_TDM = 0x08 |
1257 | }; | 1257 | }; |
1258 | 1258 | ||
1259 | enum uniperif_state { | 1259 | enum uniperif_state { |
@@ -1278,12 +1278,6 @@ enum uniperif_word_pos { | |||
1278 | WORD_MAX | 1278 | WORD_MAX |
1279 | }; | 1279 | }; |
1280 | 1280 | ||
1281 | struct uniperif_info { | ||
1282 | int id; /* instance value of the uniperipheral IP */ | ||
1283 | enum uniperif_type type; | ||
1284 | int underflow_enabled; /* Underflow recovery mode */ | ||
1285 | }; | ||
1286 | |||
1287 | struct uniperif_iec958_settings { | 1281 | struct uniperif_iec958_settings { |
1288 | enum uniperif_iec958_encoding_mode encoding_mode; | 1282 | enum uniperif_iec958_encoding_mode encoding_mode; |
1289 | struct snd_aes_iec958 iec958; | 1283 | struct snd_aes_iec958 iec958; |
@@ -1298,8 +1292,10 @@ struct dai_tdm_slot { | |||
1298 | 1292 | ||
1299 | struct uniperif { | 1293 | struct uniperif { |
1300 | /* System information */ | 1294 | /* System information */ |
1301 | struct uniperif_info *info; | 1295 | enum uniperif_type type; |
1296 | int underflow_enabled; /* Underflow recovery mode */ | ||
1302 | struct device *dev; | 1297 | struct device *dev; |
1298 | int id; /* instance value of the uniperipheral IP */ | ||
1303 | int ver; /* IP version, used by register access macros */ | 1299 | int ver; /* IP version, used by register access macros */ |
1304 | struct regmap_field *clk_sel; | 1300 | struct regmap_field *clk_sel; |
1305 | struct regmap_field *valid_sel; | 1301 | struct regmap_field *valid_sel; |
diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c index 1ac2db205a0d..1bc8ebc2528e 100644 --- a/sound/soc/sti/uniperif_player.c +++ b/sound/soc/sti/uniperif_player.c | |||
@@ -100,7 +100,7 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id) | |||
100 | dev_err(player->dev, "FIFO underflow error detected"); | 100 | dev_err(player->dev, "FIFO underflow error detected"); |
101 | 101 | ||
102 | /* Interrupt is just for information when underflow recovery */ | 102 | /* Interrupt is just for information when underflow recovery */ |
103 | if (player->info->underflow_enabled) { | 103 | if (player->underflow_enabled) { |
104 | /* Update state to underflow */ | 104 | /* Update state to underflow */ |
105 | player->state = UNIPERIF_STATE_UNDERFLOW; | 105 | player->state = UNIPERIF_STATE_UNDERFLOW; |
106 | 106 | ||
@@ -134,7 +134,7 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id) | |||
134 | 134 | ||
135 | /* Check for underflow recovery done */ | 135 | /* Check for underflow recovery done */ |
136 | if (unlikely(status & UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(player))) { | 136 | if (unlikely(status & UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(player))) { |
137 | if (!player->info->underflow_enabled) { | 137 | if (!player->underflow_enabled) { |
138 | dev_err(player->dev, "unexpected Underflow recovering"); | 138 | dev_err(player->dev, "unexpected Underflow recovering"); |
139 | return -EPERM; | 139 | return -EPERM; |
140 | } | 140 | } |
@@ -764,7 +764,7 @@ static int uni_player_prepare(struct snd_pcm_substream *substream, | |||
764 | } | 764 | } |
765 | 765 | ||
766 | /* Calculate transfer size (in fifo cells and bytes) for frame count */ | 766 | /* Calculate transfer size (in fifo cells and bytes) for frame count */ |
767 | if (player->info->type == SND_ST_UNIPERIF_TYPE_TDM) { | 767 | if (player->type == SND_ST_UNIPERIF_TYPE_TDM) { |
768 | /* transfer size = user frame size (in 32 bits FIFO cell) */ | 768 | /* transfer size = user frame size (in 32 bits FIFO cell) */ |
769 | transfer_size = | 769 | transfer_size = |
770 | sti_uniperiph_get_user_frame_size(runtime) / 4; | 770 | sti_uniperiph_get_user_frame_size(runtime) / 4; |
@@ -794,7 +794,7 @@ static int uni_player_prepare(struct snd_pcm_substream *substream, | |||
794 | SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(player, trigger_limit); | 794 | SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(player, trigger_limit); |
795 | 795 | ||
796 | /* Uniperipheral setup depends on player type */ | 796 | /* Uniperipheral setup depends on player type */ |
797 | switch (player->info->type) { | 797 | switch (player->type) { |
798 | case SND_ST_UNIPERIF_TYPE_HDMI: | 798 | case SND_ST_UNIPERIF_TYPE_HDMI: |
799 | ret = uni_player_prepare_iec958(player, runtime); | 799 | ret = uni_player_prepare_iec958(player, runtime); |
800 | break; | 800 | break; |
@@ -884,7 +884,7 @@ static int uni_player_start(struct uniperif *player) | |||
884 | SET_UNIPERIF_ITM_BSET_FIFO_ERROR(player); | 884 | SET_UNIPERIF_ITM_BSET_FIFO_ERROR(player); |
885 | 885 | ||
886 | /* Enable underflow recovery interrupts */ | 886 | /* Enable underflow recovery interrupts */ |
887 | if (player->info->underflow_enabled) { | 887 | if (player->underflow_enabled) { |
888 | SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(player); | 888 | SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(player); |
889 | SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(player); | 889 | SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(player); |
890 | } | 890 | } |
@@ -893,8 +893,10 @@ static int uni_player_start(struct uniperif *player) | |||
893 | SET_UNIPERIF_SOFT_RST_SOFT_RST(player); | 893 | SET_UNIPERIF_SOFT_RST_SOFT_RST(player); |
894 | 894 | ||
895 | ret = reset_player(player); | 895 | ret = reset_player(player); |
896 | if (ret < 0) | 896 | if (ret < 0) { |
897 | clk_disable_unprepare(player->clk); | ||
897 | return ret; | 898 | return ret; |
899 | } | ||
898 | 900 | ||
899 | /* | 901 | /* |
900 | * Does not use IEC61937 features of the uniperipheral hardware. | 902 | * Does not use IEC61937 features of the uniperipheral hardware. |
@@ -1021,8 +1023,8 @@ static int uni_player_parse_dt_audio_glue(struct platform_device *pdev, | |||
1021 | struct reg_field regfield[2] = { | 1023 | struct reg_field regfield[2] = { |
1022 | /* PCM_CLK_SEL */ | 1024 | /* PCM_CLK_SEL */ |
1023 | REG_FIELD(SYS_CFG_AUDIO_GLUE, | 1025 | REG_FIELD(SYS_CFG_AUDIO_GLUE, |
1024 | 8 + player->info->id, | 1026 | 8 + player->id, |
1025 | 8 + player->info->id), | 1027 | 8 + player->id), |
1026 | /* PCMP_VALID_SEL */ | 1028 | /* PCMP_VALID_SEL */ |
1027 | REG_FIELD(SYS_CFG_AUDIO_GLUE, 0, 1) | 1029 | REG_FIELD(SYS_CFG_AUDIO_GLUE, 0, 1) |
1028 | }; | 1030 | }; |
@@ -1040,60 +1042,6 @@ static int uni_player_parse_dt_audio_glue(struct platform_device *pdev, | |||
1040 | return 0; | 1042 | return 0; |
1041 | } | 1043 | } |
1042 | 1044 | ||
1043 | static int uni_player_parse_dt(struct platform_device *pdev, | ||
1044 | struct uniperif *player) | ||
1045 | { | ||
1046 | struct uniperif_info *info; | ||
1047 | struct device *dev = &pdev->dev; | ||
1048 | struct device_node *pnode = pdev->dev.of_node; | ||
1049 | const char *mode; | ||
1050 | |||
1051 | /* Allocate memory for the info structure */ | ||
1052 | info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); | ||
1053 | if (!info) | ||
1054 | return -ENOMEM; | ||
1055 | |||
1056 | if (of_property_read_u32(pnode, "st,version", &player->ver) || | ||
1057 | player->ver == SND_ST_UNIPERIF_VERSION_UNKNOWN) { | ||
1058 | dev_err(dev, "Unknown uniperipheral version "); | ||
1059 | return -EINVAL; | ||
1060 | } | ||
1061 | /* Underflow recovery is only supported on later ip revisions */ | ||
1062 | if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) | ||
1063 | info->underflow_enabled = 1; | ||
1064 | |||
1065 | if (of_property_read_u32(pnode, "st,uniperiph-id", &info->id)) { | ||
1066 | dev_err(dev, "uniperipheral id not defined"); | ||
1067 | return -EINVAL; | ||
1068 | } | ||
1069 | |||
1070 | /* Read the device mode property */ | ||
1071 | if (of_property_read_string(pnode, "st,mode", &mode)) { | ||
1072 | dev_err(dev, "uniperipheral mode not defined"); | ||
1073 | return -EINVAL; | ||
1074 | } | ||
1075 | |||
1076 | if (strcasecmp(mode, "hdmi") == 0) | ||
1077 | info->type = SND_ST_UNIPERIF_TYPE_HDMI; | ||
1078 | else if (strcasecmp(mode, "pcm") == 0) | ||
1079 | info->type = SND_ST_UNIPERIF_TYPE_PCM; | ||
1080 | else if (strcasecmp(mode, "spdif") == 0) | ||
1081 | info->type = SND_ST_UNIPERIF_TYPE_SPDIF; | ||
1082 | else if (strcasecmp(mode, "tdm") == 0) | ||
1083 | info->type = SND_ST_UNIPERIF_TYPE_TDM; | ||
1084 | else | ||
1085 | info->type = SND_ST_UNIPERIF_TYPE_NONE; | ||
1086 | |||
1087 | /* Save the info structure */ | ||
1088 | player->info = info; | ||
1089 | |||
1090 | /* Get PCM_CLK_SEL & PCMP_VALID_SEL from audio-glue-ctrl SoC reg */ | ||
1091 | if (uni_player_parse_dt_audio_glue(pdev, player)) | ||
1092 | return -EINVAL; | ||
1093 | |||
1094 | return 0; | ||
1095 | } | ||
1096 | |||
1097 | static const struct snd_soc_dai_ops uni_player_dai_ops = { | 1045 | static const struct snd_soc_dai_ops uni_player_dai_ops = { |
1098 | .startup = uni_player_startup, | 1046 | .startup = uni_player_startup, |
1099 | .shutdown = uni_player_shutdown, | 1047 | .shutdown = uni_player_shutdown, |
@@ -1114,13 +1062,18 @@ int uni_player_init(struct platform_device *pdev, | |||
1114 | player->state = UNIPERIF_STATE_STOPPED; | 1062 | player->state = UNIPERIF_STATE_STOPPED; |
1115 | player->dai_ops = &uni_player_dai_ops; | 1063 | player->dai_ops = &uni_player_dai_ops; |
1116 | 1064 | ||
1117 | ret = uni_player_parse_dt(pdev, player); | 1065 | /* Get PCM_CLK_SEL & PCMP_VALID_SEL from audio-glue-ctrl SoC reg */ |
1066 | ret = uni_player_parse_dt_audio_glue(pdev, player); | ||
1118 | 1067 | ||
1119 | if (ret < 0) { | 1068 | if (ret < 0) { |
1120 | dev_err(player->dev, "Failed to parse DeviceTree"); | 1069 | dev_err(player->dev, "Failed to parse DeviceTree"); |
1121 | return ret; | 1070 | return ret; |
1122 | } | 1071 | } |
1123 | 1072 | ||
1073 | /* Underflow recovery is only supported on later ip revisions */ | ||
1074 | if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) | ||
1075 | player->underflow_enabled = 1; | ||
1076 | |||
1124 | if (UNIPERIF_TYPE_IS_TDM(player)) | 1077 | if (UNIPERIF_TYPE_IS_TDM(player)) |
1125 | player->hw = &uni_tdm_hw; | 1078 | player->hw = &uni_tdm_hw; |
1126 | else | 1079 | else |
@@ -1144,8 +1097,8 @@ int uni_player_init(struct platform_device *pdev, | |||
1144 | 1097 | ||
1145 | /* connect to I2S/TDM TX bus */ | 1098 | /* connect to I2S/TDM TX bus */ |
1146 | if (player->valid_sel && | 1099 | if (player->valid_sel && |
1147 | (player->info->id == UNIPERIF_PLAYER_I2S_OUT)) { | 1100 | (player->id == UNIPERIF_PLAYER_I2S_OUT)) { |
1148 | ret = regmap_field_write(player->valid_sel, player->info->id); | 1101 | ret = regmap_field_write(player->valid_sel, player->id); |
1149 | if (ret) { | 1102 | if (ret) { |
1150 | dev_err(player->dev, | 1103 | dev_err(player->dev, |
1151 | "%s: unable to connect to tdm bus", __func__); | 1104 | "%s: unable to connect to tdm bus", __func__); |
diff --git a/sound/soc/sti/uniperif_reader.c b/sound/soc/sti/uniperif_reader.c index eb74a328c928..0e1c3ee56675 100644 --- a/sound/soc/sti/uniperif_reader.c +++ b/sound/soc/sti/uniperif_reader.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include "uniperif.h" | 14 | #include "uniperif.h" |
15 | 15 | ||
16 | #define UNIPERIF_READER_I2S_IN 0 /* reader id connected to I2S/TDM TX bus */ | ||
16 | /* | 17 | /* |
17 | * Note: snd_pcm_hardware is linked to DMA controller but is declared here to | 18 | * Note: snd_pcm_hardware is linked to DMA controller but is declared here to |
18 | * integrate unireader capability in term of rate and supported channels | 19 | * integrate unireader capability in term of rate and supported channels |
@@ -195,7 +196,7 @@ static int uni_reader_prepare(struct snd_pcm_substream *substream, | |||
195 | } | 196 | } |
196 | 197 | ||
197 | /* Calculate transfer size (in fifo cells and bytes) for frame count */ | 198 | /* Calculate transfer size (in fifo cells and bytes) for frame count */ |
198 | if (reader->info->type == SND_ST_UNIPERIF_TYPE_TDM) { | 199 | if (reader->type == SND_ST_UNIPERIF_TYPE_TDM) { |
199 | /* transfer size = unip frame size (in 32 bits FIFO cell) */ | 200 | /* transfer size = unip frame size (in 32 bits FIFO cell) */ |
200 | transfer_size = | 201 | transfer_size = |
201 | sti_uniperiph_get_user_frame_size(runtime) / 4; | 202 | sti_uniperiph_get_user_frame_size(runtime) / 4; |
@@ -280,7 +281,7 @@ static int uni_reader_prepare(struct snd_pcm_substream *substream, | |||
280 | SET_UNIPERIF_ITM_BSET_MEM_BLK_READ(reader); | 281 | SET_UNIPERIF_ITM_BSET_MEM_BLK_READ(reader); |
281 | 282 | ||
282 | /* Enable underflow recovery interrupts */ | 283 | /* Enable underflow recovery interrupts */ |
283 | if (reader->info->underflow_enabled) { | 284 | if (reader->underflow_enabled) { |
284 | SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(reader); | 285 | SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(reader); |
285 | SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(reader); | 286 | SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(reader); |
286 | } | 287 | } |
@@ -394,41 +395,6 @@ static void uni_reader_shutdown(struct snd_pcm_substream *substream, | |||
394 | } | 395 | } |
395 | } | 396 | } |
396 | 397 | ||
397 | static int uni_reader_parse_dt(struct platform_device *pdev, | ||
398 | struct uniperif *reader) | ||
399 | { | ||
400 | struct uniperif_info *info; | ||
401 | struct device_node *node = pdev->dev.of_node; | ||
402 | const char *mode; | ||
403 | |||
404 | /* Allocate memory for the info structure */ | ||
405 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | ||
406 | if (!info) | ||
407 | return -ENOMEM; | ||
408 | |||
409 | if (of_property_read_u32(node, "st,version", &reader->ver) || | ||
410 | reader->ver == SND_ST_UNIPERIF_VERSION_UNKNOWN) { | ||
411 | dev_err(&pdev->dev, "Unknown uniperipheral version "); | ||
412 | return -EINVAL; | ||
413 | } | ||
414 | |||
415 | /* Read the device mode property */ | ||
416 | if (of_property_read_string(node, "st,mode", &mode)) { | ||
417 | dev_err(&pdev->dev, "uniperipheral mode not defined"); | ||
418 | return -EINVAL; | ||
419 | } | ||
420 | |||
421 | if (strcasecmp(mode, "tdm") == 0) | ||
422 | info->type = SND_ST_UNIPERIF_TYPE_TDM; | ||
423 | else | ||
424 | info->type = SND_ST_UNIPERIF_TYPE_PCM; | ||
425 | |||
426 | /* Save the info structure */ | ||
427 | reader->info = info; | ||
428 | |||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | static const struct snd_soc_dai_ops uni_reader_dai_ops = { | 398 | static const struct snd_soc_dai_ops uni_reader_dai_ops = { |
433 | .startup = uni_reader_startup, | 399 | .startup = uni_reader_startup, |
434 | .shutdown = uni_reader_shutdown, | 400 | .shutdown = uni_reader_shutdown, |
@@ -448,12 +414,6 @@ int uni_reader_init(struct platform_device *pdev, | |||
448 | reader->state = UNIPERIF_STATE_STOPPED; | 414 | reader->state = UNIPERIF_STATE_STOPPED; |
449 | reader->dai_ops = &uni_reader_dai_ops; | 415 | reader->dai_ops = &uni_reader_dai_ops; |
450 | 416 | ||
451 | ret = uni_reader_parse_dt(pdev, reader); | ||
452 | if (ret < 0) { | ||
453 | dev_err(reader->dev, "Failed to parse DeviceTree"); | ||
454 | return ret; | ||
455 | } | ||
456 | |||
457 | if (UNIPERIF_TYPE_IS_TDM(reader)) | 417 | if (UNIPERIF_TYPE_IS_TDM(reader)) |
458 | reader->hw = &uni_tdm_hw; | 418 | reader->hw = &uni_tdm_hw; |
459 | else | 419 | else |
diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig index 2a954bd01fd8..dd2368297fd3 100644 --- a/sound/soc/sunxi/Kconfig +++ b/sound/soc/sunxi/Kconfig | |||
@@ -1,4 +1,5 @@ | |||
1 | menu "Allwinner SoC Audio support" | 1 | menu "Allwinner SoC Audio support" |
2 | depends on ARCH_SUNXI || COMPILE_TEST | ||
2 | 3 | ||
3 | config SND_SUN4I_CODEC | 4 | config SND_SUN4I_CODEC |
4 | tristate "Allwinner A10 Codec Support" | 5 | tristate "Allwinner A10 Codec Support" |
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index 44f170c73b06..e047ec06d538 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c | |||
@@ -96,8 +96,8 @@ | |||
96 | /* Other various ADC registers */ | 96 | /* Other various ADC registers */ |
97 | #define SUN4I_CODEC_DAC_TXCNT (0x30) | 97 | #define SUN4I_CODEC_DAC_TXCNT (0x30) |
98 | #define SUN4I_CODEC_ADC_RXCNT (0x34) | 98 | #define SUN4I_CODEC_ADC_RXCNT (0x34) |
99 | #define SUN4I_CODEC_AC_SYS_VERI (0x38) | 99 | #define SUN7I_CODEC_AC_DAC_CAL (0x38) |
100 | #define SUN4I_CODEC_AC_MIC_PHONE_CAL (0x3c) | 100 | #define SUN7I_CODEC_AC_MIC_PHONE_CAL (0x3c) |
101 | 101 | ||
102 | struct sun4i_codec { | 102 | struct sun4i_codec { |
103 | struct device *dev; | 103 | struct device *dev; |
@@ -509,7 +509,7 @@ static const struct snd_kcontrol_new sun4i_codec_pa_mute = | |||
509 | 509 | ||
510 | static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1); | 510 | static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1); |
511 | 511 | ||
512 | static const struct snd_kcontrol_new sun4i_codec_widgets[] = { | 512 | static const struct snd_kcontrol_new sun4i_codec_controls[] = { |
513 | SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL, | 513 | SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL, |
514 | SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0, | 514 | SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0, |
515 | sun4i_codec_pa_volume_scale), | 515 | sun4i_codec_pa_volume_scale), |
@@ -628,12 +628,14 @@ static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = { | |||
628 | }; | 628 | }; |
629 | 629 | ||
630 | static struct snd_soc_codec_driver sun4i_codec_codec = { | 630 | static struct snd_soc_codec_driver sun4i_codec_codec = { |
631 | .controls = sun4i_codec_widgets, | 631 | .component_driver = { |
632 | .num_controls = ARRAY_SIZE(sun4i_codec_widgets), | 632 | .controls = sun4i_codec_controls, |
633 | .dapm_widgets = sun4i_codec_codec_dapm_widgets, | 633 | .num_controls = ARRAY_SIZE(sun4i_codec_controls), |
634 | .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets), | 634 | .dapm_widgets = sun4i_codec_codec_dapm_widgets, |
635 | .dapm_routes = sun4i_codec_codec_dapm_routes, | 635 | .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets), |
636 | .num_dapm_routes = ARRAY_SIZE(sun4i_codec_codec_dapm_routes), | 636 | .dapm_routes = sun4i_codec_codec_dapm_routes, |
637 | .num_dapm_routes = ARRAY_SIZE(sun4i_codec_codec_dapm_routes), | ||
638 | }, | ||
637 | }; | 639 | }; |
638 | 640 | ||
639 | static const struct snd_soc_component_driver sun4i_codec_component = { | 641 | static const struct snd_soc_component_driver sun4i_codec_component = { |
@@ -680,12 +682,37 @@ static const struct regmap_config sun4i_codec_regmap_config = { | |||
680 | .reg_bits = 32, | 682 | .reg_bits = 32, |
681 | .reg_stride = 4, | 683 | .reg_stride = 4, |
682 | .val_bits = 32, | 684 | .val_bits = 32, |
683 | .max_register = SUN4I_CODEC_AC_MIC_PHONE_CAL, | 685 | .max_register = SUN4I_CODEC_ADC_RXCNT, |
686 | }; | ||
687 | |||
688 | static const struct regmap_config sun7i_codec_regmap_config = { | ||
689 | .reg_bits = 32, | ||
690 | .reg_stride = 4, | ||
691 | .val_bits = 32, | ||
692 | .max_register = SUN7I_CODEC_AC_MIC_PHONE_CAL, | ||
693 | }; | ||
694 | |||
695 | struct sun4i_codec_quirks { | ||
696 | const struct regmap_config *regmap_config; | ||
697 | }; | ||
698 | |||
699 | static const struct sun4i_codec_quirks sun4i_codec_quirks = { | ||
700 | .regmap_config = &sun4i_codec_regmap_config, | ||
701 | }; | ||
702 | |||
703 | static const struct sun4i_codec_quirks sun7i_codec_quirks = { | ||
704 | .regmap_config = &sun7i_codec_regmap_config, | ||
684 | }; | 705 | }; |
685 | 706 | ||
686 | static const struct of_device_id sun4i_codec_of_match[] = { | 707 | static const struct of_device_id sun4i_codec_of_match[] = { |
687 | { .compatible = "allwinner,sun4i-a10-codec" }, | 708 | { |
688 | { .compatible = "allwinner,sun7i-a20-codec" }, | 709 | .compatible = "allwinner,sun4i-a10-codec", |
710 | .data = &sun4i_codec_quirks, | ||
711 | }, | ||
712 | { | ||
713 | .compatible = "allwinner,sun7i-a20-codec", | ||
714 | .data = &sun7i_codec_quirks, | ||
715 | }, | ||
689 | {} | 716 | {} |
690 | }; | 717 | }; |
691 | MODULE_DEVICE_TABLE(of, sun4i_codec_of_match); | 718 | MODULE_DEVICE_TABLE(of, sun4i_codec_of_match); |
@@ -758,6 +785,7 @@ static int sun4i_codec_probe(struct platform_device *pdev) | |||
758 | { | 785 | { |
759 | struct snd_soc_card *card; | 786 | struct snd_soc_card *card; |
760 | struct sun4i_codec *scodec; | 787 | struct sun4i_codec *scodec; |
788 | const struct sun4i_codec_quirks *quirks; | ||
761 | struct resource *res; | 789 | struct resource *res; |
762 | void __iomem *base; | 790 | void __iomem *base; |
763 | int ret; | 791 | int ret; |
@@ -775,8 +803,14 @@ static int sun4i_codec_probe(struct platform_device *pdev) | |||
775 | return PTR_ERR(base); | 803 | return PTR_ERR(base); |
776 | } | 804 | } |
777 | 805 | ||
806 | quirks = of_device_get_match_data(&pdev->dev); | ||
807 | if (quirks == NULL) { | ||
808 | dev_err(&pdev->dev, "Failed to determine the quirks to use\n"); | ||
809 | return -ENODEV; | ||
810 | } | ||
811 | |||
778 | scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base, | 812 | scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base, |
779 | &sun4i_codec_regmap_config); | 813 | quirks->regmap_config); |
780 | if (IS_ERR(scodec->regmap)) { | 814 | if (IS_ERR(scodec->regmap)) { |
781 | dev_err(&pdev->dev, "Failed to create our regmap\n"); | 815 | dev_err(&pdev->dev, "Failed to create our regmap\n"); |
782 | return PTR_ERR(scodec->regmap); | 816 | return PTR_ERR(scodec->regmap); |
diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c index 0b04fb02125c..88fbb3a1e660 100644 --- a/sound/soc/sunxi/sun4i-spdif.c +++ b/sound/soc/sunxi/sun4i-spdif.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/pm_runtime.h> | 31 | #include <linux/pm_runtime.h> |
32 | #include <linux/reset.h> | ||
32 | #include <sound/dmaengine_pcm.h> | 33 | #include <sound/dmaengine_pcm.h> |
33 | #include <sound/pcm_params.h> | 34 | #include <sound/pcm_params.h> |
34 | #include <sound/soc.h> | 35 | #include <sound/soc.h> |
@@ -162,6 +163,7 @@ struct sun4i_spdif_dev { | |||
162 | struct platform_device *pdev; | 163 | struct platform_device *pdev; |
163 | struct clk *spdif_clk; | 164 | struct clk *spdif_clk; |
164 | struct clk *apb_clk; | 165 | struct clk *apb_clk; |
166 | struct reset_control *rst; | ||
165 | struct snd_soc_dai_driver cpu_dai_drv; | 167 | struct snd_soc_dai_driver cpu_dai_drv; |
166 | struct regmap *regmap; | 168 | struct regmap *regmap; |
167 | struct snd_dmaengine_dai_dma_data dma_params_tx; | 169 | struct snd_dmaengine_dai_dma_data dma_params_tx; |
@@ -411,6 +413,7 @@ static const struct snd_soc_dapm_route dit_routes[] = { | |||
411 | 413 | ||
412 | static const struct of_device_id sun4i_spdif_of_match[] = { | 414 | static const struct of_device_id sun4i_spdif_of_match[] = { |
413 | { .compatible = "allwinner,sun4i-a10-spdif", }, | 415 | { .compatible = "allwinner,sun4i-a10-spdif", }, |
416 | { .compatible = "allwinner,sun6i-a31-spdif", }, | ||
414 | { /* sentinel */ } | 417 | { /* sentinel */ } |
415 | }; | 418 | }; |
416 | MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match); | 419 | MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match); |
@@ -482,11 +485,23 @@ static int sun4i_spdif_probe(struct platform_device *pdev) | |||
482 | } | 485 | } |
483 | 486 | ||
484 | host->dma_params_tx.addr = res->start + SUN4I_SPDIF_TXFIFO; | 487 | host->dma_params_tx.addr = res->start + SUN4I_SPDIF_TXFIFO; |
485 | host->dma_params_tx.maxburst = 4; | 488 | host->dma_params_tx.maxburst = 8; |
486 | host->dma_params_tx.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | 489 | host->dma_params_tx.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; |
487 | 490 | ||
488 | platform_set_drvdata(pdev, host); | 491 | platform_set_drvdata(pdev, host); |
489 | 492 | ||
493 | if (of_device_is_compatible(pdev->dev.of_node, | ||
494 | "allwinner,sun6i-a31-spdif")) { | ||
495 | host->rst = devm_reset_control_get_optional(&pdev->dev, NULL); | ||
496 | if (IS_ERR(host->rst) && PTR_ERR(host->rst) == -EPROBE_DEFER) { | ||
497 | ret = -EPROBE_DEFER; | ||
498 | dev_err(&pdev->dev, "Failed to get reset: %d\n", ret); | ||
499 | goto err_disable_apb_clk; | ||
500 | } | ||
501 | if (!IS_ERR(host->rst)) | ||
502 | reset_control_deassert(host->rst); | ||
503 | } | ||
504 | |||
490 | ret = devm_snd_soc_register_component(&pdev->dev, | 505 | ret = devm_snd_soc_register_component(&pdev->dev, |
491 | &sun4i_spdif_component, &sun4i_spdif_dai, 1); | 506 | &sun4i_spdif_component, &sun4i_spdif_dai, 1); |
492 | if (ret) | 507 | if (ret) |
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index a6768f832c6f..efbe8d4c019e 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig | |||
@@ -138,3 +138,14 @@ config SND_SOC_TEGRA_RT5677 | |||
138 | help | 138 | help |
139 | Say Y or M here if you want to add support for SoC audio on Tegra | 139 | Say Y or M here if you want to add support for SoC audio on Tegra |
140 | boards using the RT5677 codec, such as Ryu. | 140 | boards using the RT5677 codec, such as Ryu. |
141 | |||
142 | config SND_SOC_TEGRA_SGTL5000 | ||
143 | tristate "SoC Audio support for Tegra boards using a SGTL5000 codec" | ||
144 | depends on SND_SOC_TEGRA && I2C && GPIOLIB | ||
145 | select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC | ||
146 | select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC | ||
147 | select SND_SOC_SGTL5000 | ||
148 | help | ||
149 | Say Y or M here if you want to add support for SoC audio on Tegra | ||
150 | boards using the SGTL5000 codec, such as Apalis T30, Apalis TK1 or | ||
151 | Colibri T30. | ||
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile index 9171655ad843..f214a3fd0024 100644 --- a/sound/soc/tegra/Makefile +++ b/sound/soc/tegra/Makefile | |||
@@ -26,6 +26,7 @@ snd-soc-tegra-wm9712-objs := tegra_wm9712.o | |||
26 | snd-soc-tegra-trimslice-objs := trimslice.o | 26 | snd-soc-tegra-trimslice-objs := trimslice.o |
27 | snd-soc-tegra-alc5632-objs := tegra_alc5632.o | 27 | snd-soc-tegra-alc5632-objs := tegra_alc5632.o |
28 | snd-soc-tegra-max98090-objs := tegra_max98090.o | 28 | snd-soc-tegra-max98090-objs := tegra_max98090.o |
29 | snd-soc-tegra-sgtl5000-objs := tegra_sgtl5000.o | ||
29 | 30 | ||
30 | obj-$(CONFIG_SND_SOC_TEGRA_RT5640) += snd-soc-tegra-rt5640.o | 31 | obj-$(CONFIG_SND_SOC_TEGRA_RT5640) += snd-soc-tegra-rt5640.o |
31 | obj-$(CONFIG_SND_SOC_TEGRA_RT5677) += snd-soc-tegra-rt5677.o | 32 | obj-$(CONFIG_SND_SOC_TEGRA_RT5677) += snd-soc-tegra-rt5677.o |
@@ -35,3 +36,4 @@ obj-$(CONFIG_SND_SOC_TEGRA_WM9712) += snd-soc-tegra-wm9712.o | |||
35 | obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o | 36 | obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o |
36 | obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o | 37 | obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o |
37 | obj-$(CONFIG_SND_SOC_TEGRA_MAX98090) += snd-soc-tegra-max98090.o | 38 | obj-$(CONFIG_SND_SOC_TEGRA_MAX98090) += snd-soc-tegra-max98090.o |
39 | obj-$(CONFIG_SND_SOC_TEGRA_SGTL5000) += snd-soc-tegra-sgtl5000.o \ No newline at end of file | ||
diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c index 773daecaa5e8..e5ef4e9c4ac5 100644 --- a/sound/soc/tegra/tegra_rt5640.c +++ b/sound/soc/tegra/tegra_rt5640.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * tegra_rt5640.c - Tegra machine ASoC driver for boards using WM8903 codec. | 2 | * tegra_rt5640.c - Tegra machine ASoC driver for boards using RT5640 codec. |
3 | * | 3 | * |
4 | * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. | 4 | * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. |
5 | * | 5 | * |
diff --git a/sound/soc/tegra/tegra_sgtl5000.c b/sound/soc/tegra/tegra_sgtl5000.c new file mode 100644 index 000000000000..1e76869dd488 --- /dev/null +++ b/sound/soc/tegra/tegra_sgtl5000.c | |||
@@ -0,0 +1,212 @@ | |||
1 | /* | ||
2 | * tegra_sgtl5000.c - Tegra machine ASoC driver for boards using SGTL5000 codec | ||
3 | * | ||
4 | * Author: Marcel Ziswiler <marcel@ziswiler.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * Based on code copyright/by: | ||
19 | * | ||
20 | * Copyright (C) 2010-2012 - NVIDIA, Inc. | ||
21 | * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd. | ||
22 | * Copyright 2007 Wolfson Microelectronics PLC. | ||
23 | */ | ||
24 | |||
25 | #include <linux/module.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/gpio.h> | ||
29 | #include <linux/of_gpio.h> | ||
30 | |||
31 | #include <sound/core.h> | ||
32 | #include <sound/pcm.h> | ||
33 | #include <sound/pcm_params.h> | ||
34 | #include <sound/soc.h> | ||
35 | |||
36 | #include "../codecs/sgtl5000.h" | ||
37 | |||
38 | #include "tegra_asoc_utils.h" | ||
39 | |||
40 | #define DRV_NAME "tegra-snd-sgtl5000" | ||
41 | |||
42 | struct tegra_sgtl5000 { | ||
43 | struct tegra_asoc_utils_data util_data; | ||
44 | }; | ||
45 | |||
46 | static int tegra_sgtl5000_hw_params(struct snd_pcm_substream *substream, | ||
47 | struct snd_pcm_hw_params *params) | ||
48 | { | ||
49 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
50 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
51 | struct snd_soc_card *card = rtd->card; | ||
52 | struct tegra_sgtl5000 *machine = snd_soc_card_get_drvdata(card); | ||
53 | int srate, mclk; | ||
54 | int err; | ||
55 | |||
56 | srate = params_rate(params); | ||
57 | switch (srate) { | ||
58 | case 11025: | ||
59 | case 22050: | ||
60 | case 44100: | ||
61 | case 88200: | ||
62 | mclk = 11289600; | ||
63 | break; | ||
64 | default: | ||
65 | mclk = 12288000; | ||
66 | break; | ||
67 | } | ||
68 | |||
69 | err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); | ||
70 | if (err < 0) { | ||
71 | dev_err(card->dev, "Can't configure clocks\n"); | ||
72 | return err; | ||
73 | } | ||
74 | |||
75 | err = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, mclk, | ||
76 | SND_SOC_CLOCK_IN); | ||
77 | if (err < 0) { | ||
78 | dev_err(card->dev, "codec_dai clock not set\n"); | ||
79 | return err; | ||
80 | } | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static struct snd_soc_ops tegra_sgtl5000_ops = { | ||
86 | .hw_params = tegra_sgtl5000_hw_params, | ||
87 | }; | ||
88 | |||
89 | static const struct snd_soc_dapm_widget tegra_sgtl5000_dapm_widgets[] = { | ||
90 | SND_SOC_DAPM_HP("Headphone Jack", NULL), | ||
91 | SND_SOC_DAPM_LINE("Line In Jack", NULL), | ||
92 | SND_SOC_DAPM_MIC("Mic Jack", NULL), | ||
93 | }; | ||
94 | |||
95 | static struct snd_soc_dai_link tegra_sgtl5000_dai = { | ||
96 | .name = "sgtl5000", | ||
97 | .stream_name = "HiFi", | ||
98 | .codec_dai_name = "sgtl5000", | ||
99 | .ops = &tegra_sgtl5000_ops, | ||
100 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
101 | SND_SOC_DAIFMT_CBS_CFS, | ||
102 | }; | ||
103 | |||
104 | static struct snd_soc_card snd_soc_tegra_sgtl5000 = { | ||
105 | .name = "tegra-sgtl5000", | ||
106 | .owner = THIS_MODULE, | ||
107 | .dai_link = &tegra_sgtl5000_dai, | ||
108 | .num_links = 1, | ||
109 | .dapm_widgets = tegra_sgtl5000_dapm_widgets, | ||
110 | .num_dapm_widgets = ARRAY_SIZE(tegra_sgtl5000_dapm_widgets), | ||
111 | .fully_routed = true, | ||
112 | }; | ||
113 | |||
114 | static int tegra_sgtl5000_driver_probe(struct platform_device *pdev) | ||
115 | { | ||
116 | struct device_node *np = pdev->dev.of_node; | ||
117 | struct snd_soc_card *card = &snd_soc_tegra_sgtl5000; | ||
118 | struct tegra_sgtl5000 *machine; | ||
119 | int ret; | ||
120 | |||
121 | machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_sgtl5000), | ||
122 | GFP_KERNEL); | ||
123 | if (!machine) { | ||
124 | dev_err(&pdev->dev, "Can't allocate tegra_sgtl5000 struct\n"); | ||
125 | return -ENOMEM; | ||
126 | } | ||
127 | |||
128 | card->dev = &pdev->dev; | ||
129 | platform_set_drvdata(pdev, card); | ||
130 | snd_soc_card_set_drvdata(card, machine); | ||
131 | |||
132 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); | ||
133 | if (ret) | ||
134 | goto err; | ||
135 | |||
136 | ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing"); | ||
137 | if (ret) | ||
138 | goto err; | ||
139 | |||
140 | tegra_sgtl5000_dai.codec_of_node = of_parse_phandle(np, | ||
141 | "nvidia,audio-codec", 0); | ||
142 | if (!tegra_sgtl5000_dai.codec_of_node) { | ||
143 | dev_err(&pdev->dev, | ||
144 | "Property 'nvidia,audio-codec' missing or invalid\n"); | ||
145 | ret = -EINVAL; | ||
146 | goto err; | ||
147 | } | ||
148 | |||
149 | tegra_sgtl5000_dai.cpu_of_node = of_parse_phandle(np, | ||
150 | "nvidia,i2s-controller", 0); | ||
151 | if (!tegra_sgtl5000_dai.cpu_of_node) { | ||
152 | dev_err(&pdev->dev, | ||
153 | "Property 'nvidia,i2s-controller' missing/invalid\n"); | ||
154 | ret = -EINVAL; | ||
155 | goto err; | ||
156 | } | ||
157 | |||
158 | tegra_sgtl5000_dai.platform_of_node = tegra_sgtl5000_dai.cpu_of_node; | ||
159 | |||
160 | ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); | ||
161 | if (ret) | ||
162 | goto err; | ||
163 | |||
164 | ret = snd_soc_register_card(card); | ||
165 | if (ret) { | ||
166 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", | ||
167 | ret); | ||
168 | goto err_fini_utils; | ||
169 | } | ||
170 | |||
171 | return 0; | ||
172 | |||
173 | err_fini_utils: | ||
174 | tegra_asoc_utils_fini(&machine->util_data); | ||
175 | err: | ||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | static int tegra_sgtl5000_driver_remove(struct platform_device *pdev) | ||
180 | { | ||
181 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
182 | struct tegra_sgtl5000 *machine = snd_soc_card_get_drvdata(card); | ||
183 | int ret; | ||
184 | |||
185 | ret = snd_soc_unregister_card(card); | ||
186 | |||
187 | tegra_asoc_utils_fini(&machine->util_data); | ||
188 | |||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | static const struct of_device_id tegra_sgtl5000_of_match[] = { | ||
193 | { .compatible = "nvidia,tegra-audio-sgtl5000", }, | ||
194 | { /* sentinel */ }, | ||
195 | }; | ||
196 | |||
197 | static struct platform_driver tegra_sgtl5000_driver = { | ||
198 | .driver = { | ||
199 | .name = DRV_NAME, | ||
200 | .pm = &snd_soc_pm_ops, | ||
201 | .of_match_table = tegra_sgtl5000_of_match, | ||
202 | }, | ||
203 | .probe = tegra_sgtl5000_driver_probe, | ||
204 | .remove = tegra_sgtl5000_driver_remove, | ||
205 | }; | ||
206 | module_platform_driver(tegra_sgtl5000_driver); | ||
207 | |||
208 | MODULE_AUTHOR("Marcel Ziswiler <marcel@ziswiler.com>"); | ||
209 | MODULE_DESCRIPTION("Tegra SGTL5000 machine ASoC driver"); | ||
210 | MODULE_LICENSE("GPL v2"); | ||
211 | MODULE_ALIAS("platform:" DRV_NAME); | ||
212 | MODULE_DEVICE_TABLE(of, tegra_sgtl5000_of_match); | ||
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index 6d5698b25bd4..b343efd9be5b 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c | |||
@@ -187,7 +187,7 @@ static int setup_clocking(struct snd_soc_dai *dai, | |||
187 | 187 | ||
188 | default: | 188 | default: |
189 | dev_err(dai->dev, | 189 | dev_err(dai->dev, |
190 | "%s: Error: Unsopported inversion (fmt = 0x%x)!\n", | 190 | "%s: Error: Unsupported inversion (fmt = 0x%x)!\n", |
191 | __func__, fmt); | 191 | __func__, fmt); |
192 | 192 | ||
193 | return -EINVAL; | 193 | return -EINVAL; |
@@ -218,7 +218,7 @@ static int setup_clocking(struct snd_soc_dai *dai, | |||
218 | break; | 218 | break; |
219 | 219 | ||
220 | default: | 220 | default: |
221 | dev_err(dai->dev, "%s: Error: Unsopported master (fmt = 0x%x)!\n", | 221 | dev_err(dai->dev, "%s: Error: Unsupported master (fmt = 0x%x)!\n", |
222 | __func__, fmt); | 222 | __func__, fmt); |
223 | 223 | ||
224 | return -EINVAL; | 224 | return -EINVAL; |
@@ -374,7 +374,7 @@ static int setup_msp_config(struct snd_pcm_substream *substream, | |||
374 | break; | 374 | break; |
375 | 375 | ||
376 | default: | 376 | default: |
377 | dev_err(dai->dev, "%s: Error: Unsopported format (%d)!\n", | 377 | dev_err(dai->dev, "%s: Error: Unsupported format (%d)!\n", |
378 | __func__, fmt); | 378 | __func__, fmt); |
379 | return -EINVAL; | 379 | return -EINVAL; |
380 | } | 380 | } |
diff --git a/tools/gpio/gpio-event-mon.c b/tools/gpio/gpio-event-mon.c index 448ed96b3b4f..1c14c2595158 100644 --- a/tools/gpio/gpio-event-mon.c +++ b/tools/gpio/gpio-event-mon.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * gpio-hammer - example swiss army knife to shake GPIO lines on a system | 2 | * gpio-event-mon - monitor GPIO line events from userspace |
3 | * | 3 | * |
4 | * Copyright (C) 2016 Linus Walleij | 4 | * Copyright (C) 2016 Linus Walleij |
5 | * | 5 | * |
diff --git a/tools/iio/iio_generic_buffer.c b/tools/iio/iio_generic_buffer.c index 0e8a1f7a292d..f39c0e9c0d5c 100644 --- a/tools/iio/iio_generic_buffer.c +++ b/tools/iio/iio_generic_buffer.c | |||
@@ -348,7 +348,7 @@ int main(int argc, char **argv) | |||
348 | int notrigger = 0; | 348 | int notrigger = 0; |
349 | char *dummy; | 349 | char *dummy; |
350 | 350 | ||
351 | struct iio_channel_info *channels; | 351 | struct iio_channel_info *channels = NULL; |
352 | 352 | ||
353 | register_cleanup(); | 353 | register_cleanup(); |
354 | 354 | ||
@@ -456,7 +456,7 @@ int main(int argc, char **argv) | |||
456 | 456 | ||
457 | if (notrigger) { | 457 | if (notrigger) { |
458 | printf("trigger-less mode selected\n"); | 458 | printf("trigger-less mode selected\n"); |
459 | } if (trig_num >= 0) { | 459 | } else if (trig_num >= 0) { |
460 | char *trig_dev_name; | 460 | char *trig_dev_name; |
461 | ret = asprintf(&trig_dev_name, "%strigger%d", iio_dir, trig_num); | 461 | ret = asprintf(&trig_dev_name, "%strigger%d", iio_dir, trig_num); |
462 | if (ret < 0) { | 462 | if (ret < 0) { |
diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h index b96879477311..f436d2420a18 100644 --- a/tools/include/linux/string.h +++ b/tools/include/linux/string.h | |||
@@ -8,7 +8,11 @@ void *memdup(const void *src, size_t len); | |||
8 | 8 | ||
9 | int strtobool(const char *s, bool *res); | 9 | int strtobool(const char *s, bool *res); |
10 | 10 | ||
11 | #ifdef __GLIBC__ | 11 | /* |
12 | * glibc based builds needs the extern while uClibc doesn't. | ||
13 | * However uClibc headers also define __GLIBC__ hence the hack below | ||
14 | */ | ||
15 | #if defined(__GLIBC__) && !defined(__UCLIBC__) | ||
12 | extern size_t strlcpy(char *dest, const char *src, size_t size); | 16 | extern size_t strlcpy(char *dest, const char *src, size_t size); |
13 | #endif | 17 | #endif |
14 | 18 | ||
diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c index d9836c5eb694..11c8d9bc762e 100644 --- a/tools/lguest/lguest.c +++ b/tools/lguest/lguest.c | |||
@@ -3266,6 +3266,9 @@ int main(int argc, char *argv[]) | |||
3266 | } | 3266 | } |
3267 | } | 3267 | } |
3268 | 3268 | ||
3269 | /* If we exit via err(), this kills all the threads, restores tty. */ | ||
3270 | atexit(cleanup_devices); | ||
3271 | |||
3269 | /* We always have a console device, and it's always device 1. */ | 3272 | /* We always have a console device, and it's always device 1. */ |
3270 | setup_console(); | 3273 | setup_console(); |
3271 | 3274 | ||
@@ -3369,9 +3372,6 @@ int main(int argc, char *argv[]) | |||
3369 | /* Ensure that we terminate if a device-servicing child dies. */ | 3372 | /* Ensure that we terminate if a device-servicing child dies. */ |
3370 | signal(SIGCHLD, kill_launcher); | 3373 | signal(SIGCHLD, kill_launcher); |
3371 | 3374 | ||
3372 | /* If we exit via err(), this kills all the threads, restores tty. */ | ||
3373 | atexit(cleanup_devices); | ||
3374 | |||
3375 | /* If requested, chroot to a directory */ | 3375 | /* If requested, chroot to a directory */ |
3376 | if (chroot_path) { | 3376 | if (chroot_path) { |
3377 | if (chroot(chroot_path) != 0) | 3377 | if (chroot(chroot_path) != 0) |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index d9b80ef881cd..21fd573106ed 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -507,17 +507,17 @@ static int __perf_evsel__hw_cache_name(u64 config, char *bf, size_t size) | |||
507 | u8 op, result, type = (config >> 0) & 0xff; | 507 | u8 op, result, type = (config >> 0) & 0xff; |
508 | const char *err = "unknown-ext-hardware-cache-type"; | 508 | const char *err = "unknown-ext-hardware-cache-type"; |
509 | 509 | ||
510 | if (type > PERF_COUNT_HW_CACHE_MAX) | 510 | if (type >= PERF_COUNT_HW_CACHE_MAX) |
511 | goto out_err; | 511 | goto out_err; |
512 | 512 | ||
513 | op = (config >> 8) & 0xff; | 513 | op = (config >> 8) & 0xff; |
514 | err = "unknown-ext-hardware-cache-op"; | 514 | err = "unknown-ext-hardware-cache-op"; |
515 | if (op > PERF_COUNT_HW_CACHE_OP_MAX) | 515 | if (op >= PERF_COUNT_HW_CACHE_OP_MAX) |
516 | goto out_err; | 516 | goto out_err; |
517 | 517 | ||
518 | result = (config >> 16) & 0xff; | 518 | result = (config >> 16) & 0xff; |
519 | err = "unknown-ext-hardware-cache-result"; | 519 | err = "unknown-ext-hardware-cache-result"; |
520 | if (result > PERF_COUNT_HW_CACHE_RESULT_MAX) | 520 | if (result >= PERF_COUNT_HW_CACHE_RESULT_MAX) |
521 | goto out_err; | 521 | goto out_err; |
522 | 522 | ||
523 | err = "invalid-cache"; | 523 | err = "invalid-cache"; |
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index cf5e250bc78e..783a53fb7a4e 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c | |||
@@ -66,7 +66,7 @@ static int entry(u64 ip, struct unwind_info *ui) | |||
66 | if (__report_module(&al, ip, ui)) | 66 | if (__report_module(&al, ip, ui)) |
67 | return -1; | 67 | return -1; |
68 | 68 | ||
69 | e->ip = ip; | 69 | e->ip = al.addr; |
70 | e->map = al.map; | 70 | e->map = al.map; |
71 | e->sym = al.sym; | 71 | e->sym = al.sym; |
72 | 72 | ||
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index 97c0f8fc5561..20c2e5743903 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c | |||
@@ -542,7 +542,7 @@ static int entry(u64 ip, struct thread *thread, | |||
542 | thread__find_addr_location(thread, PERF_RECORD_MISC_USER, | 542 | thread__find_addr_location(thread, PERF_RECORD_MISC_USER, |
543 | MAP__FUNCTION, ip, &al); | 543 | MAP__FUNCTION, ip, &al); |
544 | 544 | ||
545 | e.ip = ip; | 545 | e.ip = al.addr; |
546 | e.map = al.map; | 546 | e.map = al.map; |
547 | e.sym = al.sym; | 547 | e.sym = al.sym; |
548 | 548 | ||
diff --git a/tools/testing/radix-tree/Makefile b/tools/testing/radix-tree/Makefile index 3b530467148e..9d0919ed52a4 100644 --- a/tools/testing/radix-tree/Makefile +++ b/tools/testing/radix-tree/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | CFLAGS += -I. -g -Wall -D_LGPL_SOURCE | 2 | CFLAGS += -I. -g -O2 -Wall -D_LGPL_SOURCE |
3 | LDFLAGS += -lpthread -lurcu | 3 | LDFLAGS += -lpthread -lurcu |
4 | TARGETS = main | 4 | TARGETS = main |
5 | OFILES = main.o radix-tree.o linux.o test.o tag_check.o find_next_bit.o \ | 5 | OFILES = main.o radix-tree.o linux.o test.o tag_check.o find_next_bit.o \ |
diff --git a/tools/testing/radix-tree/multiorder.c b/tools/testing/radix-tree/multiorder.c index 39d9b9568fe2..05d7bc488971 100644 --- a/tools/testing/radix-tree/multiorder.c +++ b/tools/testing/radix-tree/multiorder.c | |||
@@ -124,6 +124,8 @@ static void multiorder_check(unsigned long index, int order) | |||
124 | unsigned long i; | 124 | unsigned long i; |
125 | unsigned long min = index & ~((1UL << order) - 1); | 125 | unsigned long min = index & ~((1UL << order) - 1); |
126 | unsigned long max = min + (1UL << order); | 126 | unsigned long max = min + (1UL << order); |
127 | void **slot; | ||
128 | struct item *item2 = item_create(min); | ||
127 | RADIX_TREE(tree, GFP_KERNEL); | 129 | RADIX_TREE(tree, GFP_KERNEL); |
128 | 130 | ||
129 | printf("Multiorder index %ld, order %d\n", index, order); | 131 | printf("Multiorder index %ld, order %d\n", index, order); |
@@ -139,13 +141,19 @@ static void multiorder_check(unsigned long index, int order) | |||
139 | item_check_absent(&tree, i); | 141 | item_check_absent(&tree, i); |
140 | for (i = max; i < 2*max; i++) | 142 | for (i = max; i < 2*max; i++) |
141 | item_check_absent(&tree, i); | 143 | item_check_absent(&tree, i); |
144 | for (i = min; i < max; i++) | ||
145 | assert(radix_tree_insert(&tree, i, item2) == -EEXIST); | ||
146 | |||
147 | slot = radix_tree_lookup_slot(&tree, index); | ||
148 | free(*slot); | ||
149 | radix_tree_replace_slot(slot, item2); | ||
142 | for (i = min; i < max; i++) { | 150 | for (i = min; i < max; i++) { |
143 | static void *entry = (void *) | 151 | struct item *item = item_lookup(&tree, i); |
144 | (0xA0 | RADIX_TREE_EXCEPTIONAL_ENTRY); | 152 | assert(item != 0); |
145 | assert(radix_tree_insert(&tree, i, entry) == -EEXIST); | 153 | assert(item->index == min); |
146 | } | 154 | } |
147 | 155 | ||
148 | assert(item_delete(&tree, index) != 0); | 156 | assert(item_delete(&tree, min) != 0); |
149 | 157 | ||
150 | for (i = 0; i < 2*max; i++) | 158 | for (i = 0; i < 2*max; i++) |
151 | item_check_absent(&tree, i); | 159 | item_check_absent(&tree, i); |
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index 4fde8c7dfcfe..77e6ccf14901 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c | |||
@@ -33,6 +33,7 @@ | |||
33 | static struct timecounter *timecounter; | 33 | static struct timecounter *timecounter; |
34 | static struct workqueue_struct *wqueue; | 34 | static struct workqueue_struct *wqueue; |
35 | static unsigned int host_vtimer_irq; | 35 | static unsigned int host_vtimer_irq; |
36 | static u32 host_vtimer_irq_flags; | ||
36 | 37 | ||
37 | void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu) | 38 | void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu) |
38 | { | 39 | { |
@@ -365,7 +366,7 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) | |||
365 | 366 | ||
366 | static void kvm_timer_init_interrupt(void *info) | 367 | static void kvm_timer_init_interrupt(void *info) |
367 | { | 368 | { |
368 | enable_percpu_irq(host_vtimer_irq, 0); | 369 | enable_percpu_irq(host_vtimer_irq, host_vtimer_irq_flags); |
369 | } | 370 | } |
370 | 371 | ||
371 | int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value) | 372 | int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value) |
@@ -432,6 +433,14 @@ int kvm_timer_hyp_init(void) | |||
432 | } | 433 | } |
433 | host_vtimer_irq = info->virtual_irq; | 434 | host_vtimer_irq = info->virtual_irq; |
434 | 435 | ||
436 | host_vtimer_irq_flags = irq_get_trigger_type(host_vtimer_irq); | ||
437 | if (host_vtimer_irq_flags != IRQF_TRIGGER_HIGH && | ||
438 | host_vtimer_irq_flags != IRQF_TRIGGER_LOW) { | ||
439 | kvm_err("Invalid trigger for IRQ%d, assuming level low\n", | ||
440 | host_vtimer_irq); | ||
441 | host_vtimer_irq_flags = IRQF_TRIGGER_LOW; | ||
442 | } | ||
443 | |||
435 | err = request_percpu_irq(host_vtimer_irq, kvm_arch_timer_handler, | 444 | err = request_percpu_irq(host_vtimer_irq, kvm_arch_timer_handler, |
436 | "kvm guest timer", kvm_get_running_vcpus()); | 445 | "kvm guest timer", kvm_get_running_vcpus()); |
437 | if (err) { | 446 | if (err) { |
diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c index 07411cf967b9..4660a7d04eea 100644 --- a/virt/kvm/arm/vgic/vgic-its.c +++ b/virt/kvm/arm/vgic/vgic-its.c | |||
@@ -51,7 +51,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid) | |||
51 | 51 | ||
52 | irq = kzalloc(sizeof(struct vgic_irq), GFP_KERNEL); | 52 | irq = kzalloc(sizeof(struct vgic_irq), GFP_KERNEL); |
53 | if (!irq) | 53 | if (!irq) |
54 | return NULL; | 54 | return ERR_PTR(-ENOMEM); |
55 | 55 | ||
56 | INIT_LIST_HEAD(&irq->lpi_list); | 56 | INIT_LIST_HEAD(&irq->lpi_list); |
57 | INIT_LIST_HEAD(&irq->ap_list); | 57 | INIT_LIST_HEAD(&irq->ap_list); |
@@ -441,39 +441,63 @@ static unsigned long vgic_mmio_read_its_idregs(struct kvm *kvm, | |||
441 | * Find the target VCPU and the LPI number for a given devid/eventid pair | 441 | * Find the target VCPU and the LPI number for a given devid/eventid pair |
442 | * and make this IRQ pending, possibly injecting it. | 442 | * and make this IRQ pending, possibly injecting it. |
443 | * Must be called with the its_lock mutex held. | 443 | * Must be called with the its_lock mutex held. |
444 | * Returns 0 on success, a positive error value for any ITS mapping | ||
445 | * related errors and negative error values for generic errors. | ||
444 | */ | 446 | */ |
445 | static void vgic_its_trigger_msi(struct kvm *kvm, struct vgic_its *its, | 447 | static int vgic_its_trigger_msi(struct kvm *kvm, struct vgic_its *its, |
446 | u32 devid, u32 eventid) | 448 | u32 devid, u32 eventid) |
447 | { | 449 | { |
450 | struct kvm_vcpu *vcpu; | ||
448 | struct its_itte *itte; | 451 | struct its_itte *itte; |
449 | 452 | ||
450 | if (!its->enabled) | 453 | if (!its->enabled) |
451 | return; | 454 | return -EBUSY; |
452 | 455 | ||
453 | itte = find_itte(its, devid, eventid); | 456 | itte = find_itte(its, devid, eventid); |
454 | /* Triggering an unmapped IRQ gets silently dropped. */ | 457 | if (!itte || !its_is_collection_mapped(itte->collection)) |
455 | if (itte && its_is_collection_mapped(itte->collection)) { | 458 | return E_ITS_INT_UNMAPPED_INTERRUPT; |
456 | struct kvm_vcpu *vcpu; | 459 | |
457 | 460 | vcpu = kvm_get_vcpu(kvm, itte->collection->target_addr); | |
458 | vcpu = kvm_get_vcpu(kvm, itte->collection->target_addr); | 461 | if (!vcpu) |
459 | if (vcpu && vcpu->arch.vgic_cpu.lpis_enabled) { | 462 | return E_ITS_INT_UNMAPPED_INTERRUPT; |
460 | spin_lock(&itte->irq->irq_lock); | 463 | |
461 | itte->irq->pending = true; | 464 | if (!vcpu->arch.vgic_cpu.lpis_enabled) |
462 | vgic_queue_irq_unlock(kvm, itte->irq); | 465 | return -EBUSY; |
463 | } | 466 | |
464 | } | 467 | spin_lock(&itte->irq->irq_lock); |
468 | itte->irq->pending = true; | ||
469 | vgic_queue_irq_unlock(kvm, itte->irq); | ||
470 | |||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | static struct vgic_io_device *vgic_get_its_iodev(struct kvm_io_device *dev) | ||
475 | { | ||
476 | struct vgic_io_device *iodev; | ||
477 | |||
478 | if (dev->ops != &kvm_io_gic_ops) | ||
479 | return NULL; | ||
480 | |||
481 | iodev = container_of(dev, struct vgic_io_device, dev); | ||
482 | |||
483 | if (iodev->iodev_type != IODEV_ITS) | ||
484 | return NULL; | ||
485 | |||
486 | return iodev; | ||
465 | } | 487 | } |
466 | 488 | ||
467 | /* | 489 | /* |
468 | * Queries the KVM IO bus framework to get the ITS pointer from the given | 490 | * Queries the KVM IO bus framework to get the ITS pointer from the given |
469 | * doorbell address. | 491 | * doorbell address. |
470 | * We then call vgic_its_trigger_msi() with the decoded data. | 492 | * We then call vgic_its_trigger_msi() with the decoded data. |
493 | * According to the KVM_SIGNAL_MSI API description returns 1 on success. | ||
471 | */ | 494 | */ |
472 | int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi) | 495 | int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi) |
473 | { | 496 | { |
474 | u64 address; | 497 | u64 address; |
475 | struct kvm_io_device *kvm_io_dev; | 498 | struct kvm_io_device *kvm_io_dev; |
476 | struct vgic_io_device *iodev; | 499 | struct vgic_io_device *iodev; |
500 | int ret; | ||
477 | 501 | ||
478 | if (!vgic_has_its(kvm)) | 502 | if (!vgic_has_its(kvm)) |
479 | return -ENODEV; | 503 | return -ENODEV; |
@@ -485,15 +509,28 @@ int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi) | |||
485 | 509 | ||
486 | kvm_io_dev = kvm_io_bus_get_dev(kvm, KVM_MMIO_BUS, address); | 510 | kvm_io_dev = kvm_io_bus_get_dev(kvm, KVM_MMIO_BUS, address); |
487 | if (!kvm_io_dev) | 511 | if (!kvm_io_dev) |
488 | return -ENODEV; | 512 | return -EINVAL; |
489 | 513 | ||
490 | iodev = container_of(kvm_io_dev, struct vgic_io_device, dev); | 514 | iodev = vgic_get_its_iodev(kvm_io_dev); |
515 | if (!iodev) | ||
516 | return -EINVAL; | ||
491 | 517 | ||
492 | mutex_lock(&iodev->its->its_lock); | 518 | mutex_lock(&iodev->its->its_lock); |
493 | vgic_its_trigger_msi(kvm, iodev->its, msi->devid, msi->data); | 519 | ret = vgic_its_trigger_msi(kvm, iodev->its, msi->devid, msi->data); |
494 | mutex_unlock(&iodev->its->its_lock); | 520 | mutex_unlock(&iodev->its->its_lock); |
495 | 521 | ||
496 | return 0; | 522 | if (ret < 0) |
523 | return ret; | ||
524 | |||
525 | /* | ||
526 | * KVM_SIGNAL_MSI demands a return value > 0 for success and 0 | ||
527 | * if the guest has blocked the MSI. So we map any LPI mapping | ||
528 | * related error to that. | ||
529 | */ | ||
530 | if (ret) | ||
531 | return 0; | ||
532 | else | ||
533 | return 1; | ||
497 | } | 534 | } |
498 | 535 | ||
499 | /* Requires the its_lock to be held. */ | 536 | /* Requires the its_lock to be held. */ |
@@ -502,7 +539,8 @@ static void its_free_itte(struct kvm *kvm, struct its_itte *itte) | |||
502 | list_del(&itte->itte_list); | 539 | list_del(&itte->itte_list); |
503 | 540 | ||
504 | /* This put matches the get in vgic_add_lpi. */ | 541 | /* This put matches the get in vgic_add_lpi. */ |
505 | vgic_put_irq(kvm, itte->irq); | 542 | if (itte->irq) |
543 | vgic_put_irq(kvm, itte->irq); | ||
506 | 544 | ||
507 | kfree(itte); | 545 | kfree(itte); |
508 | } | 546 | } |
@@ -697,6 +735,7 @@ static int vgic_its_cmd_handle_mapi(struct kvm *kvm, struct vgic_its *its, | |||
697 | struct its_device *device; | 735 | struct its_device *device; |
698 | struct its_collection *collection, *new_coll = NULL; | 736 | struct its_collection *collection, *new_coll = NULL; |
699 | int lpi_nr; | 737 | int lpi_nr; |
738 | struct vgic_irq *irq; | ||
700 | 739 | ||
701 | device = find_its_device(its, device_id); | 740 | device = find_its_device(its, device_id); |
702 | if (!device) | 741 | if (!device) |
@@ -710,6 +749,10 @@ static int vgic_its_cmd_handle_mapi(struct kvm *kvm, struct vgic_its *its, | |||
710 | lpi_nr >= max_lpis_propbaser(kvm->arch.vgic.propbaser)) | 749 | lpi_nr >= max_lpis_propbaser(kvm->arch.vgic.propbaser)) |
711 | return E_ITS_MAPTI_PHYSICALID_OOR; | 750 | return E_ITS_MAPTI_PHYSICALID_OOR; |
712 | 751 | ||
752 | /* If there is an existing mapping, behavior is UNPREDICTABLE. */ | ||
753 | if (find_itte(its, device_id, event_id)) | ||
754 | return 0; | ||
755 | |||
713 | collection = find_collection(its, coll_id); | 756 | collection = find_collection(its, coll_id); |
714 | if (!collection) { | 757 | if (!collection) { |
715 | int ret = vgic_its_alloc_collection(its, &collection, coll_id); | 758 | int ret = vgic_its_alloc_collection(its, &collection, coll_id); |
@@ -718,22 +761,28 @@ static int vgic_its_cmd_handle_mapi(struct kvm *kvm, struct vgic_its *its, | |||
718 | new_coll = collection; | 761 | new_coll = collection; |
719 | } | 762 | } |
720 | 763 | ||
721 | itte = find_itte(its, device_id, event_id); | 764 | itte = kzalloc(sizeof(struct its_itte), GFP_KERNEL); |
722 | if (!itte) { | 765 | if (!itte) { |
723 | itte = kzalloc(sizeof(struct its_itte), GFP_KERNEL); | 766 | if (new_coll) |
724 | if (!itte) { | 767 | vgic_its_free_collection(its, coll_id); |
725 | if (new_coll) | 768 | return -ENOMEM; |
726 | vgic_its_free_collection(its, coll_id); | ||
727 | return -ENOMEM; | ||
728 | } | ||
729 | |||
730 | itte->event_id = event_id; | ||
731 | list_add_tail(&itte->itte_list, &device->itt_head); | ||
732 | } | 769 | } |
733 | 770 | ||
771 | itte->event_id = event_id; | ||
772 | list_add_tail(&itte->itte_list, &device->itt_head); | ||
773 | |||
734 | itte->collection = collection; | 774 | itte->collection = collection; |
735 | itte->lpi = lpi_nr; | 775 | itte->lpi = lpi_nr; |
736 | itte->irq = vgic_add_lpi(kvm, lpi_nr); | 776 | |
777 | irq = vgic_add_lpi(kvm, lpi_nr); | ||
778 | if (IS_ERR(irq)) { | ||
779 | if (new_coll) | ||
780 | vgic_its_free_collection(its, coll_id); | ||
781 | its_free_itte(kvm, itte); | ||
782 | return PTR_ERR(irq); | ||
783 | } | ||
784 | itte->irq = irq; | ||
785 | |||
737 | update_affinity_itte(kvm, itte); | 786 | update_affinity_itte(kvm, itte); |
738 | 787 | ||
739 | /* | 788 | /* |
@@ -981,9 +1030,7 @@ static int vgic_its_cmd_handle_int(struct kvm *kvm, struct vgic_its *its, | |||
981 | u32 msi_data = its_cmd_get_id(its_cmd); | 1030 | u32 msi_data = its_cmd_get_id(its_cmd); |
982 | u64 msi_devid = its_cmd_get_deviceid(its_cmd); | 1031 | u64 msi_devid = its_cmd_get_deviceid(its_cmd); |
983 | 1032 | ||
984 | vgic_its_trigger_msi(kvm, its, msi_devid, msi_data); | 1033 | return vgic_its_trigger_msi(kvm, its, msi_devid, msi_data); |
985 | |||
986 | return 0; | ||
987 | } | 1034 | } |
988 | 1035 | ||
989 | /* | 1036 | /* |
@@ -1288,13 +1335,13 @@ void vgic_enable_lpis(struct kvm_vcpu *vcpu) | |||
1288 | its_sync_lpi_pending_table(vcpu); | 1335 | its_sync_lpi_pending_table(vcpu); |
1289 | } | 1336 | } |
1290 | 1337 | ||
1291 | static int vgic_its_init_its(struct kvm *kvm, struct vgic_its *its) | 1338 | static int vgic_register_its_iodev(struct kvm *kvm, struct vgic_its *its) |
1292 | { | 1339 | { |
1293 | struct vgic_io_device *iodev = &its->iodev; | 1340 | struct vgic_io_device *iodev = &its->iodev; |
1294 | int ret; | 1341 | int ret; |
1295 | 1342 | ||
1296 | if (its->initialized) | 1343 | if (!its->initialized) |
1297 | return 0; | 1344 | return -EBUSY; |
1298 | 1345 | ||
1299 | if (IS_VGIC_ADDR_UNDEF(its->vgic_its_base)) | 1346 | if (IS_VGIC_ADDR_UNDEF(its->vgic_its_base)) |
1300 | return -ENXIO; | 1347 | return -ENXIO; |
@@ -1311,9 +1358,6 @@ static int vgic_its_init_its(struct kvm *kvm, struct vgic_its *its) | |||
1311 | KVM_VGIC_V3_ITS_SIZE, &iodev->dev); | 1358 | KVM_VGIC_V3_ITS_SIZE, &iodev->dev); |
1312 | mutex_unlock(&kvm->slots_lock); | 1359 | mutex_unlock(&kvm->slots_lock); |
1313 | 1360 | ||
1314 | if (!ret) | ||
1315 | its->initialized = true; | ||
1316 | |||
1317 | return ret; | 1361 | return ret; |
1318 | } | 1362 | } |
1319 | 1363 | ||
@@ -1435,9 +1479,6 @@ static int vgic_its_set_attr(struct kvm_device *dev, | |||
1435 | if (type != KVM_VGIC_ITS_ADDR_TYPE) | 1479 | if (type != KVM_VGIC_ITS_ADDR_TYPE) |
1436 | return -ENODEV; | 1480 | return -ENODEV; |
1437 | 1481 | ||
1438 | if (its->initialized) | ||
1439 | return -EBUSY; | ||
1440 | |||
1441 | if (copy_from_user(&addr, uaddr, sizeof(addr))) | 1482 | if (copy_from_user(&addr, uaddr, sizeof(addr))) |
1442 | return -EFAULT; | 1483 | return -EFAULT; |
1443 | 1484 | ||
@@ -1453,7 +1494,9 @@ static int vgic_its_set_attr(struct kvm_device *dev, | |||
1453 | case KVM_DEV_ARM_VGIC_GRP_CTRL: | 1494 | case KVM_DEV_ARM_VGIC_GRP_CTRL: |
1454 | switch (attr->attr) { | 1495 | switch (attr->attr) { |
1455 | case KVM_DEV_ARM_VGIC_CTRL_INIT: | 1496 | case KVM_DEV_ARM_VGIC_CTRL_INIT: |
1456 | return vgic_its_init_its(dev->kvm, its); | 1497 | its->initialized = true; |
1498 | |||
1499 | return 0; | ||
1457 | } | 1500 | } |
1458 | break; | 1501 | break; |
1459 | } | 1502 | } |
@@ -1498,3 +1541,30 @@ int kvm_vgic_register_its_device(void) | |||
1498 | return kvm_register_device_ops(&kvm_arm_vgic_its_ops, | 1541 | return kvm_register_device_ops(&kvm_arm_vgic_its_ops, |
1499 | KVM_DEV_TYPE_ARM_VGIC_ITS); | 1542 | KVM_DEV_TYPE_ARM_VGIC_ITS); |
1500 | } | 1543 | } |
1544 | |||
1545 | /* | ||
1546 | * Registers all ITSes with the kvm_io_bus framework. | ||
1547 | * To follow the existing VGIC initialization sequence, this has to be | ||
1548 | * done as late as possible, just before the first VCPU runs. | ||
1549 | */ | ||
1550 | int vgic_register_its_iodevs(struct kvm *kvm) | ||
1551 | { | ||
1552 | struct kvm_device *dev; | ||
1553 | int ret = 0; | ||
1554 | |||
1555 | list_for_each_entry(dev, &kvm->devices, vm_node) { | ||
1556 | if (dev->ops != &kvm_arm_vgic_its_ops) | ||
1557 | continue; | ||
1558 | |||
1559 | ret = vgic_register_its_iodev(kvm, dev->private); | ||
1560 | if (ret) | ||
1561 | return ret; | ||
1562 | /* | ||
1563 | * We don't need to care about tearing down previously | ||
1564 | * registered ITSes, as the kvm_io_bus framework removes | ||
1565 | * them for us if the VM gets destroyed. | ||
1566 | */ | ||
1567 | } | ||
1568 | |||
1569 | return ret; | ||
1570 | } | ||
diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c index ff668e0dd586..90d81811fdda 100644 --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c | |||
@@ -306,16 +306,19 @@ static void vgic_mmio_write_propbase(struct kvm_vcpu *vcpu, | |||
306 | { | 306 | { |
307 | struct vgic_dist *dist = &vcpu->kvm->arch.vgic; | 307 | struct vgic_dist *dist = &vcpu->kvm->arch.vgic; |
308 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | 308 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; |
309 | u64 propbaser = dist->propbaser; | 309 | u64 old_propbaser, propbaser; |
310 | 310 | ||
311 | /* Storing a value with LPIs already enabled is undefined */ | 311 | /* Storing a value with LPIs already enabled is undefined */ |
312 | if (vgic_cpu->lpis_enabled) | 312 | if (vgic_cpu->lpis_enabled) |
313 | return; | 313 | return; |
314 | 314 | ||
315 | propbaser = update_64bit_reg(propbaser, addr & 4, len, val); | 315 | do { |
316 | propbaser = vgic_sanitise_propbaser(propbaser); | 316 | old_propbaser = dist->propbaser; |
317 | 317 | propbaser = old_propbaser; | |
318 | dist->propbaser = propbaser; | 318 | propbaser = update_64bit_reg(propbaser, addr & 4, len, val); |
319 | propbaser = vgic_sanitise_propbaser(propbaser); | ||
320 | } while (cmpxchg64(&dist->propbaser, old_propbaser, | ||
321 | propbaser) != old_propbaser); | ||
319 | } | 322 | } |
320 | 323 | ||
321 | static unsigned long vgic_mmio_read_pendbase(struct kvm_vcpu *vcpu, | 324 | static unsigned long vgic_mmio_read_pendbase(struct kvm_vcpu *vcpu, |
@@ -331,16 +334,19 @@ static void vgic_mmio_write_pendbase(struct kvm_vcpu *vcpu, | |||
331 | unsigned long val) | 334 | unsigned long val) |
332 | { | 335 | { |
333 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | 336 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; |
334 | u64 pendbaser = vgic_cpu->pendbaser; | 337 | u64 old_pendbaser, pendbaser; |
335 | 338 | ||
336 | /* Storing a value with LPIs already enabled is undefined */ | 339 | /* Storing a value with LPIs already enabled is undefined */ |
337 | if (vgic_cpu->lpis_enabled) | 340 | if (vgic_cpu->lpis_enabled) |
338 | return; | 341 | return; |
339 | 342 | ||
340 | pendbaser = update_64bit_reg(pendbaser, addr & 4, len, val); | 343 | do { |
341 | pendbaser = vgic_sanitise_pendbaser(pendbaser); | 344 | old_pendbaser = vgic_cpu->pendbaser; |
342 | 345 | pendbaser = old_pendbaser; | |
343 | vgic_cpu->pendbaser = pendbaser; | 346 | pendbaser = update_64bit_reg(pendbaser, addr & 4, len, val); |
347 | pendbaser = vgic_sanitise_pendbaser(pendbaser); | ||
348 | } while (cmpxchg64(&vgic_cpu->pendbaser, old_pendbaser, | ||
349 | pendbaser) != old_pendbaser); | ||
344 | } | 350 | } |
345 | 351 | ||
346 | /* | 352 | /* |
diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c index 0506543df38a..9f0dae397d9c 100644 --- a/virt/kvm/arm/vgic/vgic-v3.c +++ b/virt/kvm/arm/vgic/vgic-v3.c | |||
@@ -289,6 +289,14 @@ int vgic_v3_map_resources(struct kvm *kvm) | |||
289 | goto out; | 289 | goto out; |
290 | } | 290 | } |
291 | 291 | ||
292 | if (vgic_has_its(kvm)) { | ||
293 | ret = vgic_register_its_iodevs(kvm); | ||
294 | if (ret) { | ||
295 | kvm_err("Unable to register VGIC ITS MMIO regions\n"); | ||
296 | goto out; | ||
297 | } | ||
298 | } | ||
299 | |||
292 | dist->ready = true; | 300 | dist->ready = true; |
293 | 301 | ||
294 | out: | 302 | out: |
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c index e7aeac719e09..e83b7fe4baae 100644 --- a/virt/kvm/arm/vgic/vgic.c +++ b/virt/kvm/arm/vgic/vgic.c | |||
@@ -117,17 +117,17 @@ static void vgic_irq_release(struct kref *ref) | |||
117 | 117 | ||
118 | void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq) | 118 | void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq) |
119 | { | 119 | { |
120 | struct vgic_dist *dist; | 120 | struct vgic_dist *dist = &kvm->arch.vgic; |
121 | 121 | ||
122 | if (irq->intid < VGIC_MIN_LPI) | 122 | if (irq->intid < VGIC_MIN_LPI) |
123 | return; | 123 | return; |
124 | 124 | ||
125 | if (!kref_put(&irq->refcount, vgic_irq_release)) | 125 | spin_lock(&dist->lpi_list_lock); |
126 | if (!kref_put(&irq->refcount, vgic_irq_release)) { | ||
127 | spin_unlock(&dist->lpi_list_lock); | ||
126 | return; | 128 | return; |
129 | }; | ||
127 | 130 | ||
128 | dist = &kvm->arch.vgic; | ||
129 | |||
130 | spin_lock(&dist->lpi_list_lock); | ||
131 | list_del(&irq->lpi_list); | 131 | list_del(&irq->lpi_list); |
132 | dist->lpi_list_count--; | 132 | dist->lpi_list_count--; |
133 | spin_unlock(&dist->lpi_list_lock); | 133 | spin_unlock(&dist->lpi_list_lock); |
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h index 1d8e21d5c13f..6c4625c46368 100644 --- a/virt/kvm/arm/vgic/vgic.h +++ b/virt/kvm/arm/vgic/vgic.h | |||
@@ -84,6 +84,7 @@ void vgic_v3_enable(struct kvm_vcpu *vcpu); | |||
84 | int vgic_v3_probe(const struct gic_kvm_info *info); | 84 | int vgic_v3_probe(const struct gic_kvm_info *info); |
85 | int vgic_v3_map_resources(struct kvm *kvm); | 85 | int vgic_v3_map_resources(struct kvm *kvm); |
86 | int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t dist_base_address); | 86 | int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t dist_base_address); |
87 | int vgic_register_its_iodevs(struct kvm *kvm); | ||
87 | bool vgic_has_its(struct kvm *kvm); | 88 | bool vgic_has_its(struct kvm *kvm); |
88 | int kvm_vgic_register_its_device(void); | 89 | int kvm_vgic_register_its_device(void); |
89 | void vgic_enable_lpis(struct kvm_vcpu *vcpu); | 90 | void vgic_enable_lpis(struct kvm_vcpu *vcpu); |
@@ -140,6 +141,11 @@ static inline int vgic_register_redist_iodevs(struct kvm *kvm, | |||
140 | return -ENODEV; | 141 | return -ENODEV; |
141 | } | 142 | } |
142 | 143 | ||
144 | static inline int vgic_register_its_iodevs(struct kvm *kvm) | ||
145 | { | ||
146 | return -ENODEV; | ||
147 | } | ||
148 | |||
143 | static inline bool vgic_has_its(struct kvm *kvm) | 149 | static inline bool vgic_has_its(struct kvm *kvm) |
144 | { | 150 | { |
145 | return false; | 151 | return false; |