diff options
278 files changed, 10913 insertions, 1899 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci index a3c5a6685036..ab8d76dfaa80 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci | |||
@@ -117,7 +117,7 @@ Description: | |||
117 | 117 | ||
118 | What: /sys/bus/pci/devices/.../vpd | 118 | What: /sys/bus/pci/devices/.../vpd |
119 | Date: February 2008 | 119 | Date: February 2008 |
120 | Contact: Ben Hutchings <bhutchings@solarflare.com> | 120 | Contact: Ben Hutchings <bwh@kernel.org> |
121 | Description: | 121 | Description: |
122 | A file named vpd in a device directory will be a | 122 | A file named vpd in a device directory will be a |
123 | binary file containing the Vital Product Data for the | 123 | binary file containing the Vital Product Data for the |
diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt index cd5e23912888..6794cdc96d8f 100644 --- a/Documentation/devicetree/bindings/clock/at91-clock.txt +++ b/Documentation/devicetree/bindings/clock/at91-clock.txt | |||
@@ -62,7 +62,7 @@ Required properties for PMC node: | |||
62 | - interrupt-controller : tell that the PMC is an interrupt controller. | 62 | - interrupt-controller : tell that the PMC is an interrupt controller. |
63 | - #interrupt-cells : must be set to 1. The first cell encodes the interrupt id, | 63 | - #interrupt-cells : must be set to 1. The first cell encodes the interrupt id, |
64 | and reflect the bit position in the PMC_ER/DR/SR registers. | 64 | and reflect the bit position in the PMC_ER/DR/SR registers. |
65 | You can use the dt macros defined in dt-bindings/clk/at91.h. | 65 | You can use the dt macros defined in dt-bindings/clock/at91.h. |
66 | 0 (AT91_PMC_MOSCS) -> main oscillator ready | 66 | 0 (AT91_PMC_MOSCS) -> main oscillator ready |
67 | 1 (AT91_PMC_LOCKA) -> PLL A ready | 67 | 1 (AT91_PMC_LOCKA) -> PLL A ready |
68 | 2 (AT91_PMC_LOCKB) -> PLL B ready | 68 | 2 (AT91_PMC_LOCKB) -> PLL B ready |
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt index 5992dceec7af..02a25d99ca61 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt | |||
@@ -43,7 +43,7 @@ Example | |||
43 | clock-output-names = | 43 | clock-output-names = |
44 | "tpu0", "mmcif1", "sdhi3", "sdhi2", | 44 | "tpu0", "mmcif1", "sdhi3", "sdhi2", |
45 | "sdhi1", "sdhi0", "mmcif0"; | 45 | "sdhi1", "sdhi0", "mmcif0"; |
46 | renesas,clock-indices = < | 46 | clock-indices = < |
47 | R8A7790_CLK_TPU0 R8A7790_CLK_MMCIF1 R8A7790_CLK_SDHI3 | 47 | R8A7790_CLK_TPU0 R8A7790_CLK_MMCIF1 R8A7790_CLK_SDHI3 |
48 | R8A7790_CLK_SDHI2 R8A7790_CLK_SDHI1 R8A7790_CLK_SDHI0 | 48 | R8A7790_CLK_SDHI2 R8A7790_CLK_SDHI1 R8A7790_CLK_SDHI0 |
49 | R8A7790_CLK_MMCIF0 | 49 | R8A7790_CLK_MMCIF0 |
diff --git a/Documentation/devicetree/bindings/dma/ti-edma.txt b/Documentation/devicetree/bindings/dma/ti-edma.txt index 9fbbdb783a72..68ff2137bae7 100644 --- a/Documentation/devicetree/bindings/dma/ti-edma.txt +++ b/Documentation/devicetree/bindings/dma/ti-edma.txt | |||
@@ -29,6 +29,6 @@ edma: edma@49000000 { | |||
29 | dma-channels = <64>; | 29 | dma-channels = <64>; |
30 | ti,edma-regions = <4>; | 30 | ti,edma-regions = <4>; |
31 | ti,edma-slots = <256>; | 31 | ti,edma-slots = <256>; |
32 | ti,edma-xbar-event-map = <1 12 | 32 | ti,edma-xbar-event-map = /bits/ 16 <1 12 |
33 | 2 13>; | 33 | 2 13>; |
34 | }; | 34 | }; |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 43842177b771..30a8ad0dae53 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -2218,10 +2218,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
2218 | noreplace-smp [X86-32,SMP] Don't replace SMP instructions | 2218 | noreplace-smp [X86-32,SMP] Don't replace SMP instructions |
2219 | with UP alternatives | 2219 | with UP alternatives |
2220 | 2220 | ||
2221 | nordrand [X86] Disable the direct use of the RDRAND | 2221 | nordrand [X86] Disable kernel use of the RDRAND and |
2222 | instruction even if it is supported by the | 2222 | RDSEED instructions even if they are supported |
2223 | processor. RDRAND is still available to user | 2223 | by the processor. RDRAND and RDSEED are still |
2224 | space applications. | 2224 | available to user space applications. |
2225 | 2225 | ||
2226 | noresume [SWSUSP] Disables resume and restores original swap | 2226 | noresume [SWSUSP] Disables resume and restores original swap |
2227 | space. | 2227 | space. |
diff --git a/MAINTAINERS b/MAINTAINERS index 2c4cc2251693..8779dae65f63 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1893,14 +1893,15 @@ L: netdev@vger.kernel.org | |||
1893 | S: Supported | 1893 | S: Supported |
1894 | F: drivers/net/ethernet/broadcom/bnx2x/ | 1894 | F: drivers/net/ethernet/broadcom/bnx2x/ |
1895 | 1895 | ||
1896 | BROADCOM BCM281XX/BCM11XXX ARM ARCHITECTURE | 1896 | BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITECTURE |
1897 | M: Christian Daudt <bcm@fixthebug.org> | 1897 | M: Christian Daudt <bcm@fixthebug.org> |
1898 | M: Matt Porter <mporter@linaro.org> | 1898 | M: Matt Porter <mporter@linaro.org> |
1899 | L: bcm-kernel-feedback-list@broadcom.com | 1899 | L: bcm-kernel-feedback-list@broadcom.com |
1900 | T: git git://git.github.com/broadcom/bcm11351 | 1900 | T: git git://github.com/broadcom/mach-bcm |
1901 | S: Maintained | 1901 | S: Maintained |
1902 | F: arch/arm/mach-bcm/ | 1902 | F: arch/arm/mach-bcm/ |
1903 | F: arch/arm/boot/dts/bcm113* | 1903 | F: arch/arm/boot/dts/bcm113* |
1904 | F: arch/arm/boot/dts/bcm216* | ||
1904 | F: arch/arm/boot/dts/bcm281* | 1905 | F: arch/arm/boot/dts/bcm281* |
1905 | F: arch/arm/configs/bcm_defconfig | 1906 | F: arch/arm/configs/bcm_defconfig |
1906 | F: drivers/mmc/host/sdhci_bcm_kona.c | 1907 | F: drivers/mmc/host/sdhci_bcm_kona.c |
@@ -4812,6 +4813,14 @@ L: linux-kernel@vger.kernel.org | |||
4812 | S: Maintained | 4813 | S: Maintained |
4813 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core | 4814 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core |
4814 | F: kernel/irq/ | 4815 | F: kernel/irq/ |
4816 | |||
4817 | IRQCHIP DRIVERS | ||
4818 | M: Thomas Gleixner <tglx@linutronix.de> | ||
4819 | M: Jason Cooper <jason@lakedaemon.net> | ||
4820 | L: linux-kernel@vger.kernel.org | ||
4821 | S: Maintained | ||
4822 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core | ||
4823 | T: git git://git.infradead.org/users/jcooper/linux.git irqchip/core | ||
4815 | F: drivers/irqchip/ | 4824 | F: drivers/irqchip/ |
4816 | 4825 | ||
4817 | IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY) | 4826 | IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY) |
@@ -5484,15 +5493,15 @@ F: Documentation/hwmon/ltc4261 | |||
5484 | F: drivers/hwmon/ltc4261.c | 5493 | F: drivers/hwmon/ltc4261.c |
5485 | 5494 | ||
5486 | LTP (Linux Test Project) | 5495 | LTP (Linux Test Project) |
5487 | M: Shubham Goyal <shubham@linux.vnet.ibm.com> | ||
5488 | M: Mike Frysinger <vapier@gentoo.org> | 5496 | M: Mike Frysinger <vapier@gentoo.org> |
5489 | M: Cyril Hrubis <chrubis@suse.cz> | 5497 | M: Cyril Hrubis <chrubis@suse.cz> |
5490 | M: Caspar Zhang <caspar@casparzhang.com> | ||
5491 | M: Wanlong Gao <gaowanlong@cn.fujitsu.com> | 5498 | M: Wanlong Gao <gaowanlong@cn.fujitsu.com> |
5499 | M: Jan Stancek <jstancek@redhat.com> | ||
5500 | M: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com> | ||
5501 | M: Alexey Kodanev <alexey.kodanev@oracle.com> | ||
5492 | L: ltp-list@lists.sourceforge.net (subscribers-only) | 5502 | L: ltp-list@lists.sourceforge.net (subscribers-only) |
5493 | W: http://ltp.sourceforge.net/ | 5503 | W: http://linux-test-project.github.io/ |
5494 | T: git git://github.com/linux-test-project/ltp.git | 5504 | T: git git://github.com/linux-test-project/ltp.git |
5495 | T: git git://ltp.git.sourceforge.net/gitroot/ltp/ltp-dev | ||
5496 | S: Maintained | 5505 | S: Maintained |
5497 | 5506 | ||
5498 | M32R ARCHITECTURE | 5507 | M32R ARCHITECTURE |
@@ -9102,6 +9111,9 @@ F: arch/um/os-Linux/drivers/ | |||
9102 | 9111 | ||
9103 | TURBOCHANNEL SUBSYSTEM | 9112 | TURBOCHANNEL SUBSYSTEM |
9104 | M: "Maciej W. Rozycki" <macro@linux-mips.org> | 9113 | M: "Maciej W. Rozycki" <macro@linux-mips.org> |
9114 | M: Ralf Baechle <ralf@linux-mips.org> | ||
9115 | L: linux-mips@linux-mips.org | ||
9116 | Q: http://patchwork.linux-mips.org/project/linux-mips/list/ | ||
9105 | S: Maintained | 9117 | S: Maintained |
9106 | F: drivers/tc/ | 9118 | F: drivers/tc/ |
9107 | F: include/linux/tc.h | 9119 | F: include/linux/tc.h |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 3 | 1 | VERSION = 3 |
2 | PATCHLEVEL = 15 | 2 | PATCHLEVEL = 15 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = -rc5 | 4 | EXTRAVERSION = -rc6 |
5 | NAME = Shuffling Zombie Juror | 5 | NAME = Shuffling Zombie Juror |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index cb6811e5ae5a..7ad75b4e0663 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi | |||
@@ -144,7 +144,7 @@ | |||
144 | compatible = "ti,edma3"; | 144 | compatible = "ti,edma3"; |
145 | ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2"; | 145 | ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2"; |
146 | reg = <0x49000000 0x10000>, | 146 | reg = <0x49000000 0x10000>, |
147 | <0x44e10f90 0x10>; | 147 | <0x44e10f90 0x40>; |
148 | interrupts = <12 13 14>; | 148 | interrupts = <12 13 14>; |
149 | #dma-cells = <1>; | 149 | #dma-cells = <1>; |
150 | dma-channels = <64>; | 150 | dma-channels = <64>; |
diff --git a/arch/arm/boot/dts/am3517.dtsi b/arch/arm/boot/dts/am3517.dtsi index 788391f91684..5a452fdd7c5d 100644 --- a/arch/arm/boot/dts/am3517.dtsi +++ b/arch/arm/boot/dts/am3517.dtsi | |||
@@ -62,5 +62,21 @@ | |||
62 | }; | 62 | }; |
63 | }; | 63 | }; |
64 | 64 | ||
65 | &iva { | ||
66 | status = "disabled"; | ||
67 | }; | ||
68 | |||
69 | &mailbox { | ||
70 | status = "disabled"; | ||
71 | }; | ||
72 | |||
73 | &mmu_isp { | ||
74 | status = "disabled"; | ||
75 | }; | ||
76 | |||
77 | &smartreflex_mpu_iva { | ||
78 | status = "disabled"; | ||
79 | }; | ||
80 | |||
65 | /include/ "am35xx-clocks.dtsi" | 81 | /include/ "am35xx-clocks.dtsi" |
66 | /include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi" | 82 | /include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi" |
diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts index df8798e8bd25..a055f7f0f14a 100644 --- a/arch/arm/boot/dts/am437x-gp-evm.dts +++ b/arch/arm/boot/dts/am437x-gp-evm.dts | |||
@@ -117,6 +117,11 @@ | |||
117 | status = "okay"; | 117 | status = "okay"; |
118 | }; | 118 | }; |
119 | 119 | ||
120 | &gpio5 { | ||
121 | status = "okay"; | ||
122 | ti,no-reset-on-init; | ||
123 | }; | ||
124 | |||
120 | &mmc1 { | 125 | &mmc1 { |
121 | status = "okay"; | 126 | status = "okay"; |
122 | vmmc-supply = <&vmmcsd_fixed>; | 127 | vmmc-supply = <&vmmcsd_fixed>; |
diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts index 82f238a9063f..3383c4b66803 100644 --- a/arch/arm/boot/dts/armada-370-db.dts +++ b/arch/arm/boot/dts/armada-370-db.dts | |||
@@ -67,6 +67,7 @@ | |||
67 | i2c@11000 { | 67 | i2c@11000 { |
68 | pinctrl-0 = <&i2c0_pins>; | 68 | pinctrl-0 = <&i2c0_pins>; |
69 | pinctrl-names = "default"; | 69 | pinctrl-names = "default"; |
70 | clock-frequency = <100000>; | ||
70 | status = "okay"; | 71 | status = "okay"; |
71 | audio_codec: audio-codec@4a { | 72 | audio_codec: audio-codec@4a { |
72 | compatible = "cirrus,cs42l51"; | 73 | compatible = "cirrus,cs42l51"; |
diff --git a/arch/arm/boot/dts/armada-375-db.dts b/arch/arm/boot/dts/armada-375-db.dts index 9378d3136b41..0451124e8ebf 100644 --- a/arch/arm/boot/dts/armada-375-db.dts +++ b/arch/arm/boot/dts/armada-375-db.dts | |||
@@ -79,6 +79,11 @@ | |||
79 | }; | 79 | }; |
80 | }; | 80 | }; |
81 | 81 | ||
82 | sata@a0000 { | ||
83 | status = "okay"; | ||
84 | nr-ports = <2>; | ||
85 | }; | ||
86 | |||
82 | nand: nand@d0000 { | 87 | nand: nand@d0000 { |
83 | pinctrl-0 = <&nand_pins>; | 88 | pinctrl-0 = <&nand_pins>; |
84 | pinctrl-names = "default"; | 89 | pinctrl-names = "default"; |
diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts index 448373c4b0e5..90f0bf6f9271 100644 --- a/arch/arm/boot/dts/armada-xp-db.dts +++ b/arch/arm/boot/dts/armada-xp-db.dts | |||
@@ -49,7 +49,7 @@ | |||
49 | /* Device Bus parameters are required */ | 49 | /* Device Bus parameters are required */ |
50 | 50 | ||
51 | /* Read parameters */ | 51 | /* Read parameters */ |
52 | devbus,bus-width = <8>; | 52 | devbus,bus-width = <16>; |
53 | devbus,turn-off-ps = <60000>; | 53 | devbus,turn-off-ps = <60000>; |
54 | devbus,badr-skew-ps = <0>; | 54 | devbus,badr-skew-ps = <0>; |
55 | devbus,acc-first-ps = <124000>; | 55 | devbus,acc-first-ps = <124000>; |
diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts index 61bda687f782..0c756421ae6a 100644 --- a/arch/arm/boot/dts/armada-xp-gp.dts +++ b/arch/arm/boot/dts/armada-xp-gp.dts | |||
@@ -59,7 +59,7 @@ | |||
59 | /* Device Bus parameters are required */ | 59 | /* Device Bus parameters are required */ |
60 | 60 | ||
61 | /* Read parameters */ | 61 | /* Read parameters */ |
62 | devbus,bus-width = <8>; | 62 | devbus,bus-width = <16>; |
63 | devbus,turn-off-ps = <60000>; | 63 | devbus,turn-off-ps = <60000>; |
64 | devbus,badr-skew-ps = <0>; | 64 | devbus,badr-skew-ps = <0>; |
65 | devbus,acc-first-ps = <124000>; | 65 | devbus,acc-first-ps = <124000>; |
@@ -146,22 +146,22 @@ | |||
146 | ethernet@70000 { | 146 | ethernet@70000 { |
147 | status = "okay"; | 147 | status = "okay"; |
148 | phy = <&phy0>; | 148 | phy = <&phy0>; |
149 | phy-mode = "rgmii-id"; | 149 | phy-mode = "qsgmii"; |
150 | }; | 150 | }; |
151 | ethernet@74000 { | 151 | ethernet@74000 { |
152 | status = "okay"; | 152 | status = "okay"; |
153 | phy = <&phy1>; | 153 | phy = <&phy1>; |
154 | phy-mode = "rgmii-id"; | 154 | phy-mode = "qsgmii"; |
155 | }; | 155 | }; |
156 | ethernet@30000 { | 156 | ethernet@30000 { |
157 | status = "okay"; | 157 | status = "okay"; |
158 | phy = <&phy2>; | 158 | phy = <&phy2>; |
159 | phy-mode = "rgmii-id"; | 159 | phy-mode = "qsgmii"; |
160 | }; | 160 | }; |
161 | ethernet@34000 { | 161 | ethernet@34000 { |
162 | status = "okay"; | 162 | status = "okay"; |
163 | phy = <&phy3>; | 163 | phy = <&phy3>; |
164 | phy-mode = "rgmii-id"; | 164 | phy-mode = "qsgmii"; |
165 | }; | 165 | }; |
166 | 166 | ||
167 | /* Front-side USB slot */ | 167 | /* Front-side USB slot */ |
diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts index 985948ce67b3..5d42feb31049 100644 --- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts +++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts | |||
@@ -39,7 +39,7 @@ | |||
39 | /* Device Bus parameters are required */ | 39 | /* Device Bus parameters are required */ |
40 | 40 | ||
41 | /* Read parameters */ | 41 | /* Read parameters */ |
42 | devbus,bus-width = <8>; | 42 | devbus,bus-width = <16>; |
43 | devbus,turn-off-ps = <60000>; | 43 | devbus,turn-off-ps = <60000>; |
44 | devbus,badr-skew-ps = <0>; | 44 | devbus,badr-skew-ps = <0>; |
45 | devbus,acc-first-ps = <124000>; | 45 | devbus,acc-first-ps = <124000>; |
diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts index ce1375595e5f..4537259ce529 100644 --- a/arch/arm/boot/dts/at91-sama5d3_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts | |||
@@ -34,7 +34,7 @@ | |||
34 | }; | 34 | }; |
35 | 35 | ||
36 | spi0: spi@f0004000 { | 36 | spi0: spi@f0004000 { |
37 | cs-gpios = <&pioD 13 0>; | 37 | cs-gpios = <&pioD 13 0>, <0>, <0>, <&pioD 16 0>; |
38 | status = "okay"; | 38 | status = "okay"; |
39 | }; | 39 | }; |
40 | 40 | ||
@@ -79,7 +79,7 @@ | |||
79 | }; | 79 | }; |
80 | 80 | ||
81 | spi1: spi@f8008000 { | 81 | spi1: spi@f8008000 { |
82 | cs-gpios = <&pioC 25 0>, <0>, <0>, <&pioD 16 0>; | 82 | cs-gpios = <&pioC 25 0>; |
83 | status = "okay"; | 83 | status = "okay"; |
84 | }; | 84 | }; |
85 | 85 | ||
diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi index e21dda0e8986..3be973e9889a 100644 --- a/arch/arm/boot/dts/at91sam9261.dtsi +++ b/arch/arm/boot/dts/at91sam9261.dtsi | |||
@@ -10,7 +10,7 @@ | |||
10 | #include <dt-bindings/pinctrl/at91.h> | 10 | #include <dt-bindings/pinctrl/at91.h> |
11 | #include <dt-bindings/interrupt-controller/irq.h> | 11 | #include <dt-bindings/interrupt-controller/irq.h> |
12 | #include <dt-bindings/gpio/gpio.h> | 12 | #include <dt-bindings/gpio/gpio.h> |
13 | #include <dt-bindings/clk/at91.h> | 13 | #include <dt-bindings/clock/at91.h> |
14 | 14 | ||
15 | / { | 15 | / { |
16 | model = "Atmel AT91SAM9261 family SoC"; | 16 | model = "Atmel AT91SAM9261 family SoC"; |
diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi index 63e1784d272c..92a52faebef7 100644 --- a/arch/arm/boot/dts/at91sam9rl.dtsi +++ b/arch/arm/boot/dts/at91sam9rl.dtsi | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | #include "skeleton.dtsi" | 9 | #include "skeleton.dtsi" |
10 | #include <dt-bindings/pinctrl/at91.h> | 10 | #include <dt-bindings/pinctrl/at91.h> |
11 | #include <dt-bindings/clk/at91.h> | 11 | #include <dt-bindings/clock/at91.h> |
12 | #include <dt-bindings/interrupt-controller/irq.h> | 12 | #include <dt-bindings/interrupt-controller/irq.h> |
13 | #include <dt-bindings/gpio/gpio.h> | 13 | #include <dt-bindings/gpio/gpio.h> |
14 | 14 | ||
diff --git a/arch/arm/boot/dts/imx53-mba53.dts b/arch/arm/boot/dts/imx53-mba53.dts index 7c8c12969892..a3431d784870 100644 --- a/arch/arm/boot/dts/imx53-mba53.dts +++ b/arch/arm/boot/dts/imx53-mba53.dts | |||
@@ -244,7 +244,7 @@ | |||
244 | &tve { | 244 | &tve { |
245 | pinctrl-names = "default"; | 245 | pinctrl-names = "default"; |
246 | pinctrl-0 = <&pinctrl_vga_sync_1>; | 246 | pinctrl-0 = <&pinctrl_vga_sync_1>; |
247 | i2c-ddc-bus = <&i2c3>; | 247 | ddc-i2c-bus = <&i2c3>; |
248 | fsl,tve-mode = "vga"; | 248 | fsl,tve-mode = "vga"; |
249 | fsl,hsync-pin = <4>; | 249 | fsl,hsync-pin = <4>; |
250 | fsl,vsync-pin = <6>; | 250 | fsl,vsync-pin = <6>; |
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index 9c2bff2252d0..6a1bf4ff83d5 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi | |||
@@ -115,7 +115,7 @@ | |||
115 | #address-cells = <1>; | 115 | #address-cells = <1>; |
116 | #size-cells = <0>; | 116 | #size-cells = <0>; |
117 | compatible = "fsl,imx53-ipu"; | 117 | compatible = "fsl,imx53-ipu"; |
118 | reg = <0x18000000 0x080000000>; | 118 | reg = <0x18000000 0x08000000>; |
119 | interrupts = <11 10>; | 119 | interrupts = <11 10>; |
120 | clocks = <&clks IMX5_CLK_IPU_GATE>, | 120 | clocks = <&clks IMX5_CLK_IPU_GATE>, |
121 | <&clks IMX5_CLK_IPU_DI0_GATE>, | 121 | <&clks IMX5_CLK_IPU_DI0_GATE>, |
diff --git a/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts b/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts index 32c6fb4a1162..b939f4f52d16 100644 --- a/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts +++ b/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts | |||
@@ -30,6 +30,16 @@ | |||
30 | bootargs = "console=ttyS0,115200n8 earlyprintk"; | 30 | bootargs = "console=ttyS0,115200n8 earlyprintk"; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | mbus { | ||
34 | pcie-controller { | ||
35 | status = "okay"; | ||
36 | |||
37 | pcie@1,0 { | ||
38 | status = "okay"; | ||
39 | }; | ||
40 | }; | ||
41 | }; | ||
42 | |||
33 | ocp@f1000000 { | 43 | ocp@f1000000 { |
34 | pinctrl@10000 { | 44 | pinctrl@10000 { |
35 | pmx_usb_led: pmx-usb-led { | 45 | pmx_usb_led: pmx-usb-led { |
@@ -73,14 +83,6 @@ | |||
73 | ehci@50000 { | 83 | ehci@50000 { |
74 | status = "okay"; | 84 | status = "okay"; |
75 | }; | 85 | }; |
76 | |||
77 | pcie-controller { | ||
78 | status = "okay"; | ||
79 | |||
80 | pcie@1,0 { | ||
81 | status = "okay"; | ||
82 | }; | ||
83 | }; | ||
84 | }; | 86 | }; |
85 | 87 | ||
86 | gpio-leds { | 88 | gpio-leds { |
diff --git a/arch/arm/boot/dts/kirkwood-nsa310-common.dtsi b/arch/arm/boot/dts/kirkwood-nsa310-common.dtsi index aa78c2d11fe7..e2cc85cc3b87 100644 --- a/arch/arm/boot/dts/kirkwood-nsa310-common.dtsi +++ b/arch/arm/boot/dts/kirkwood-nsa310-common.dtsi | |||
@@ -4,6 +4,16 @@ | |||
4 | / { | 4 | / { |
5 | model = "ZyXEL NSA310"; | 5 | model = "ZyXEL NSA310"; |
6 | 6 | ||
7 | mbus { | ||
8 | pcie-controller { | ||
9 | status = "okay"; | ||
10 | |||
11 | pcie@1,0 { | ||
12 | status = "okay"; | ||
13 | }; | ||
14 | }; | ||
15 | }; | ||
16 | |||
7 | ocp@f1000000 { | 17 | ocp@f1000000 { |
8 | pinctrl: pinctrl@10000 { | 18 | pinctrl: pinctrl@10000 { |
9 | 19 | ||
@@ -26,14 +36,6 @@ | |||
26 | status = "okay"; | 36 | status = "okay"; |
27 | nr-ports = <2>; | 37 | nr-ports = <2>; |
28 | }; | 38 | }; |
29 | |||
30 | pcie-controller { | ||
31 | status = "okay"; | ||
32 | |||
33 | pcie@1,0 { | ||
34 | status = "okay"; | ||
35 | }; | ||
36 | }; | ||
37 | }; | 39 | }; |
38 | 40 | ||
39 | gpio_poweroff { | 41 | gpio_poweroff { |
diff --git a/arch/arm/boot/dts/kirkwood-t5325.dts b/arch/arm/boot/dts/kirkwood-t5325.dts index 7d1c7677a18f..0bd70d928c69 100644 --- a/arch/arm/boot/dts/kirkwood-t5325.dts +++ b/arch/arm/boot/dts/kirkwood-t5325.dts | |||
@@ -127,11 +127,6 @@ | |||
127 | 127 | ||
128 | i2c@11000 { | 128 | i2c@11000 { |
129 | status = "okay"; | 129 | status = "okay"; |
130 | |||
131 | alc5621: alc5621@1a { | ||
132 | compatible = "realtek,alc5621"; | ||
133 | reg = <0x1a>; | ||
134 | }; | ||
135 | }; | 130 | }; |
136 | 131 | ||
137 | serial@12000 { | 132 | serial@12000 { |
diff --git a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi index f577b7df9a29..521c587acaee 100644 --- a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi +++ b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi | |||
@@ -24,11 +24,10 @@ | |||
24 | compatible = "smsc,lan9221", "smsc,lan9115"; | 24 | compatible = "smsc,lan9221", "smsc,lan9115"; |
25 | bank-width = <2>; | 25 | bank-width = <2>; |
26 | gpmc,mux-add-data; | 26 | gpmc,mux-add-data; |
27 | gpmc,cs-on-ns = <0>; | 27 | gpmc,cs-on-ns = <1>; |
28 | gpmc,cs-rd-off-ns = <186>; | 28 | gpmc,cs-rd-off-ns = <180>; |
29 | gpmc,cs-wr-off-ns = <186>; | 29 | gpmc,cs-wr-off-ns = <180>; |
30 | gpmc,adv-on-ns = <12>; | 30 | gpmc,adv-rd-off-ns = <18>; |
31 | gpmc,adv-rd-off-ns = <48>; | ||
32 | gpmc,adv-wr-off-ns = <48>; | 31 | gpmc,adv-wr-off-ns = <48>; |
33 | gpmc,oe-on-ns = <54>; | 32 | gpmc,oe-on-ns = <54>; |
34 | gpmc,oe-off-ns = <168>; | 33 | gpmc,oe-off-ns = <168>; |
@@ -36,12 +35,10 @@ | |||
36 | gpmc,we-off-ns = <168>; | 35 | gpmc,we-off-ns = <168>; |
37 | gpmc,rd-cycle-ns = <186>; | 36 | gpmc,rd-cycle-ns = <186>; |
38 | gpmc,wr-cycle-ns = <186>; | 37 | gpmc,wr-cycle-ns = <186>; |
39 | gpmc,access-ns = <114>; | 38 | gpmc,access-ns = <144>; |
40 | gpmc,page-burst-access-ns = <6>; | 39 | gpmc,page-burst-access-ns = <24>; |
41 | gpmc,bus-turnaround-ns = <12>; | 40 | gpmc,bus-turnaround-ns = <90>; |
42 | gpmc,cycle2cycle-delay-ns = <18>; | 41 | gpmc,cycle2cycle-delay-ns = <90>; |
43 | gpmc,wr-data-mux-bus-ns = <90>; | ||
44 | gpmc,wr-access-ns = <186>; | ||
45 | gpmc,cycle2cycle-samecsen; | 42 | gpmc,cycle2cycle-samecsen; |
46 | gpmc,cycle2cycle-diffcsen; | 43 | gpmc,cycle2cycle-diffcsen; |
47 | vddvario-supply = <&vddvario>; | 44 | vddvario-supply = <&vddvario>; |
diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi index 22f35ea142c1..8f8c07da4ac1 100644 --- a/arch/arm/boot/dts/omap2.dtsi +++ b/arch/arm/boot/dts/omap2.dtsi | |||
@@ -71,13 +71,6 @@ | |||
71 | interrupts = <58>; | 71 | interrupts = <58>; |
72 | }; | 72 | }; |
73 | 73 | ||
74 | mailbox: mailbox@48094000 { | ||
75 | compatible = "ti,omap2-mailbox"; | ||
76 | ti,hwmods = "mailbox"; | ||
77 | reg = <0x48094000 0x200>; | ||
78 | interrupts = <26>; | ||
79 | }; | ||
80 | |||
81 | intc: interrupt-controller@1 { | 74 | intc: interrupt-controller@1 { |
82 | compatible = "ti,omap2-intc"; | 75 | compatible = "ti,omap2-intc"; |
83 | interrupt-controller; | 76 | interrupt-controller; |
diff --git a/arch/arm/boot/dts/omap2420.dtsi b/arch/arm/boot/dts/omap2420.dtsi index 85b1fb014c43..2d9979835f24 100644 --- a/arch/arm/boot/dts/omap2420.dtsi +++ b/arch/arm/boot/dts/omap2420.dtsi | |||
@@ -125,6 +125,14 @@ | |||
125 | dma-names = "tx", "rx"; | 125 | dma-names = "tx", "rx"; |
126 | }; | 126 | }; |
127 | 127 | ||
128 | mailbox: mailbox@48094000 { | ||
129 | compatible = "ti,omap2-mailbox"; | ||
130 | reg = <0x48094000 0x200>; | ||
131 | interrupts = <26>, <34>; | ||
132 | interrupt-names = "dsp", "iva"; | ||
133 | ti,hwmods = "mailbox"; | ||
134 | }; | ||
135 | |||
128 | timer1: timer@48028000 { | 136 | timer1: timer@48028000 { |
129 | compatible = "ti,omap2420-timer"; | 137 | compatible = "ti,omap2420-timer"; |
130 | reg = <0x48028000 0x400>; | 138 | reg = <0x48028000 0x400>; |
diff --git a/arch/arm/boot/dts/omap2430.dtsi b/arch/arm/boot/dts/omap2430.dtsi index d09697dab55e..42d2c61c9e2d 100644 --- a/arch/arm/boot/dts/omap2430.dtsi +++ b/arch/arm/boot/dts/omap2430.dtsi | |||
@@ -216,6 +216,13 @@ | |||
216 | dma-names = "tx", "rx"; | 216 | dma-names = "tx", "rx"; |
217 | }; | 217 | }; |
218 | 218 | ||
219 | mailbox: mailbox@48094000 { | ||
220 | compatible = "ti,omap2-mailbox"; | ||
221 | reg = <0x48094000 0x200>; | ||
222 | interrupts = <26>; | ||
223 | ti,hwmods = "mailbox"; | ||
224 | }; | ||
225 | |||
219 | timer1: timer@49018000 { | 226 | timer1: timer@49018000 { |
220 | compatible = "ti,omap2420-timer"; | 227 | compatible = "ti,omap2420-timer"; |
221 | reg = <0x49018000 0x400>; | 228 | reg = <0x49018000 0x400>; |
diff --git a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi index d00055809e31..25ba08331d88 100644 --- a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi +++ b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi | |||
@@ -10,18 +10,6 @@ | |||
10 | cpu0-supply = <&vcc>; | 10 | cpu0-supply = <&vcc>; |
11 | }; | 11 | }; |
12 | }; | 12 | }; |
13 | |||
14 | vddvario: regulator-vddvario { | ||
15 | compatible = "regulator-fixed"; | ||
16 | regulator-name = "vddvario"; | ||
17 | regulator-always-on; | ||
18 | }; | ||
19 | |||
20 | vdd33a: regulator-vdd33a { | ||
21 | compatible = "regulator-fixed"; | ||
22 | regulator-name = "vdd33a"; | ||
23 | regulator-always-on; | ||
24 | }; | ||
25 | }; | 13 | }; |
26 | 14 | ||
27 | &omap3_pmx_core { | 15 | &omap3_pmx_core { |
@@ -35,58 +23,34 @@ | |||
35 | 23 | ||
36 | hsusb0_pins: pinmux_hsusb0_pins { | 24 | hsusb0_pins: pinmux_hsusb0_pins { |
37 | pinctrl-single,pins = < | 25 | pinctrl-single,pins = < |
38 | OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0) /* hsusb0_clk.hsusb0_clk */ | 26 | OMAP3_CORE1_IOPAD(0x21a2, PIN_OUTPUT | MUX_MODE0) /* hsusb0_clk.hsusb0_clk */ |
39 | OMAP3_CORE1_IOPAD(0x21a2, PIN_OUTPUT | MUX_MODE0) /* hsusb0_stp.hsusb0_stp */ | 27 | OMAP3_CORE1_IOPAD(0x21a4, PIN_OUTPUT | MUX_MODE0) /* hsusb0_stp.hsusb0_stp */ |
40 | OMAP3_CORE1_IOPAD(0x21a4, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_dir.hsusb0_dir */ | 28 | OMAP3_CORE1_IOPAD(0x21a6, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_dir.hsusb0_dir */ |
41 | OMAP3_CORE1_IOPAD(0x21a6, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_nxt.hsusb0_nxt */ | 29 | OMAP3_CORE1_IOPAD(0x21a8, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_nxt.hsusb0_nxt */ |
42 | OMAP3_CORE1_IOPAD(0x21a8, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data0.hsusb2_data0 */ | 30 | OMAP3_CORE1_IOPAD(0x21aa, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data0.hsusb2_data0 */ |
43 | OMAP3_CORE1_IOPAD(0x21aa, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data1.hsusb0_data1 */ | 31 | OMAP3_CORE1_IOPAD(0x21ac, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data1.hsusb0_data1 */ |
44 | OMAP3_CORE1_IOPAD(0x21ac, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data2.hsusb0_data2 */ | 32 | OMAP3_CORE1_IOPAD(0x21ae, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data2.hsusb0_data2 */ |
45 | OMAP3_CORE1_IOPAD(0x21ae, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data7.hsusb0_data3 */ | 33 | OMAP3_CORE1_IOPAD(0x21b0, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data7.hsusb0_data3 */ |
46 | OMAP3_CORE1_IOPAD(0x21b0, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data7.hsusb0_data4 */ | 34 | OMAP3_CORE1_IOPAD(0x21b2, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data7.hsusb0_data4 */ |
47 | OMAP3_CORE1_IOPAD(0x21b2, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data7.hsusb0_data5 */ | 35 | OMAP3_CORE1_IOPAD(0x21b4, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data7.hsusb0_data5 */ |
48 | OMAP3_CORE1_IOPAD(0x21b4, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data7.hsusb0_data6 */ | 36 | OMAP3_CORE1_IOPAD(0x21b6, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data7.hsusb0_data6 */ |
49 | OMAP3_CORE1_IOPAD(0x21b6, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data7.hsusb0_data7 */ | 37 | OMAP3_CORE1_IOPAD(0x21b8, PIN_INPUT_PULLDOWN | MUX_MODE0) /* hsusb0_data7.hsusb0_data7 */ |
50 | >; | 38 | >; |
51 | }; | 39 | }; |
52 | }; | 40 | }; |
53 | 41 | ||
42 | #include "omap-gpmc-smsc911x.dtsi" | ||
43 | |||
54 | &gpmc { | 44 | &gpmc { |
55 | ranges = <5 0 0x2c000000 0x01000000>; | 45 | ranges = <5 0 0x2c000000 0x01000000>; |
56 | 46 | ||
57 | smsc1: ethernet@5,0 { | 47 | smsc1: ethernet@gpmc { |
58 | compatible = "smsc,lan9221", "smsc,lan9115"; | 48 | compatible = "smsc,lan9221", "smsc,lan9115"; |
59 | pinctrl-names = "default"; | 49 | pinctrl-names = "default"; |
60 | pinctrl-0 = <&smsc1_pins>; | 50 | pinctrl-0 = <&smsc1_pins>; |
61 | interrupt-parent = <&gpio6>; | 51 | interrupt-parent = <&gpio6>; |
62 | interrupts = <3 IRQ_TYPE_LEVEL_LOW>; | 52 | interrupts = <3 IRQ_TYPE_LEVEL_LOW>; |
63 | reg = <5 0 0xff>; | 53 | reg = <5 0 0xff>; |
64 | bank-width = <2>; | ||
65 | gpmc,mux-add-data; | ||
66 | gpmc,cs-on-ns = <0>; | ||
67 | gpmc,cs-rd-off-ns = <186>; | ||
68 | gpmc,cs-wr-off-ns = <186>; | ||
69 | gpmc,adv-on-ns = <12>; | ||
70 | gpmc,adv-rd-off-ns = <48>; | ||
71 | gpmc,adv-wr-off-ns = <48>; | ||
72 | gpmc,oe-on-ns = <54>; | ||
73 | gpmc,oe-off-ns = <168>; | ||
74 | gpmc,we-on-ns = <54>; | ||
75 | gpmc,we-off-ns = <168>; | ||
76 | gpmc,rd-cycle-ns = <186>; | ||
77 | gpmc,wr-cycle-ns = <186>; | ||
78 | gpmc,access-ns = <114>; | ||
79 | gpmc,page-burst-access-ns = <6>; | ||
80 | gpmc,bus-turnaround-ns = <12>; | ||
81 | gpmc,cycle2cycle-delay-ns = <18>; | ||
82 | gpmc,wr-data-mux-bus-ns = <90>; | ||
83 | gpmc,wr-access-ns = <186>; | ||
84 | gpmc,cycle2cycle-samecsen; | ||
85 | gpmc,cycle2cycle-diffcsen; | ||
86 | vddvario-supply = <&vddvario>; | ||
87 | vdd33a-supply = <&vdd33a>; | ||
88 | reg-io-width = <4>; | ||
89 | smsc,save-mac-address; | ||
90 | }; | 54 | }; |
91 | }; | 55 | }; |
92 | 56 | ||
diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi index b97736d98a64..e2d163bf0619 100644 --- a/arch/arm/boot/dts/omap3-igep.dtsi +++ b/arch/arm/boot/dts/omap3-igep.dtsi | |||
@@ -107,7 +107,7 @@ | |||
107 | >; | 107 | >; |
108 | }; | 108 | }; |
109 | 109 | ||
110 | smsc911x_pins: pinmux_smsc911x_pins { | 110 | smsc9221_pins: pinmux_smsc9221_pins { |
111 | pinctrl-single,pins = < | 111 | pinctrl-single,pins = < |
112 | 0x1a2 (PIN_INPUT | MUX_MODE4) /* mcspi1_cs2.gpio_176 */ | 112 | 0x1a2 (PIN_INPUT | MUX_MODE4) /* mcspi1_cs2.gpio_176 */ |
113 | >; | 113 | >; |
diff --git a/arch/arm/boot/dts/omap3-igep0020.dts b/arch/arm/boot/dts/omap3-igep0020.dts index 7abd64f6ae21..b22caaaf774b 100644 --- a/arch/arm/boot/dts/omap3-igep0020.dts +++ b/arch/arm/boot/dts/omap3-igep0020.dts | |||
@@ -10,7 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include "omap3-igep.dtsi" | 12 | #include "omap3-igep.dtsi" |
13 | #include "omap-gpmc-smsc911x.dtsi" | 13 | #include "omap-gpmc-smsc9221.dtsi" |
14 | 14 | ||
15 | / { | 15 | / { |
16 | model = "IGEPv2 (TI OMAP AM/DM37x)"; | 16 | model = "IGEPv2 (TI OMAP AM/DM37x)"; |
@@ -248,7 +248,7 @@ | |||
248 | 248 | ||
249 | ethernet@gpmc { | 249 | ethernet@gpmc { |
250 | pinctrl-names = "default"; | 250 | pinctrl-names = "default"; |
251 | pinctrl-0 = <&smsc911x_pins>; | 251 | pinctrl-0 = <&smsc9221_pins>; |
252 | reg = <5 0 0xff>; | 252 | reg = <5 0 0xff>; |
253 | interrupt-parent = <&gpio6>; | 253 | interrupt-parent = <&gpio6>; |
254 | interrupts = <16 IRQ_TYPE_LEVEL_LOW>; | 254 | interrupts = <16 IRQ_TYPE_LEVEL_LOW>; |
diff --git a/arch/arm/boot/dts/omap3-sb-t35.dtsi b/arch/arm/boot/dts/omap3-sb-t35.dtsi index 7909c51b05a5..d59e3de1441e 100644 --- a/arch/arm/boot/dts/omap3-sb-t35.dtsi +++ b/arch/arm/boot/dts/omap3-sb-t35.dtsi | |||
@@ -2,20 +2,6 @@ | |||
2 | * Common support for CompuLab SB-T35 used on SBC-T3530, SBC-T3517 and SBC-T3730 | 2 | * Common support for CompuLab SB-T35 used on SBC-T3530, SBC-T3517 and SBC-T3730 |
3 | */ | 3 | */ |
4 | 4 | ||
5 | / { | ||
6 | vddvario_sb_t35: regulator-vddvario-sb-t35 { | ||
7 | compatible = "regulator-fixed"; | ||
8 | regulator-name = "vddvario"; | ||
9 | regulator-always-on; | ||
10 | }; | ||
11 | |||
12 | vdd33a_sb_t35: regulator-vdd33a-sb-t35 { | ||
13 | compatible = "regulator-fixed"; | ||
14 | regulator-name = "vdd33a"; | ||
15 | regulator-always-on; | ||
16 | }; | ||
17 | }; | ||
18 | |||
19 | &omap3_pmx_core { | 5 | &omap3_pmx_core { |
20 | smsc2_pins: pinmux_smsc2_pins { | 6 | smsc2_pins: pinmux_smsc2_pins { |
21 | pinctrl-single,pins = < | 7 | pinctrl-single,pins = < |
@@ -37,11 +23,10 @@ | |||
37 | reg = <4 0 0xff>; | 23 | reg = <4 0 0xff>; |
38 | bank-width = <2>; | 24 | bank-width = <2>; |
39 | gpmc,mux-add-data; | 25 | gpmc,mux-add-data; |
40 | gpmc,cs-on-ns = <0>; | 26 | gpmc,cs-on-ns = <1>; |
41 | gpmc,cs-rd-off-ns = <186>; | 27 | gpmc,cs-rd-off-ns = <180>; |
42 | gpmc,cs-wr-off-ns = <186>; | 28 | gpmc,cs-wr-off-ns = <180>; |
43 | gpmc,adv-on-ns = <12>; | 29 | gpmc,adv-rd-off-ns = <18>; |
44 | gpmc,adv-rd-off-ns = <48>; | ||
45 | gpmc,adv-wr-off-ns = <48>; | 30 | gpmc,adv-wr-off-ns = <48>; |
46 | gpmc,oe-on-ns = <54>; | 31 | gpmc,oe-on-ns = <54>; |
47 | gpmc,oe-off-ns = <168>; | 32 | gpmc,oe-off-ns = <168>; |
@@ -49,16 +34,14 @@ | |||
49 | gpmc,we-off-ns = <168>; | 34 | gpmc,we-off-ns = <168>; |
50 | gpmc,rd-cycle-ns = <186>; | 35 | gpmc,rd-cycle-ns = <186>; |
51 | gpmc,wr-cycle-ns = <186>; | 36 | gpmc,wr-cycle-ns = <186>; |
52 | gpmc,access-ns = <114>; | 37 | gpmc,access-ns = <144>; |
53 | gpmc,page-burst-access-ns = <6>; | 38 | gpmc,page-burst-access-ns = <24>; |
54 | gpmc,bus-turnaround-ns = <12>; | 39 | gpmc,bus-turnaround-ns = <90>; |
55 | gpmc,cycle2cycle-delay-ns = <18>; | 40 | gpmc,cycle2cycle-delay-ns = <90>; |
56 | gpmc,wr-data-mux-bus-ns = <90>; | ||
57 | gpmc,wr-access-ns = <186>; | ||
58 | gpmc,cycle2cycle-samecsen; | 41 | gpmc,cycle2cycle-samecsen; |
59 | gpmc,cycle2cycle-diffcsen; | 42 | gpmc,cycle2cycle-diffcsen; |
60 | vddvario-supply = <&vddvario_sb_t35>; | 43 | vddvario-supply = <&vddvario>; |
61 | vdd33a-supply = <&vdd33a_sb_t35>; | 44 | vdd33a-supply = <&vdd33a>; |
62 | reg-io-width = <4>; | 45 | reg-io-width = <4>; |
63 | smsc,save-mac-address; | 46 | smsc,save-mac-address; |
64 | }; | 47 | }; |
diff --git a/arch/arm/boot/dts/omap3-sbc-t3517.dts b/arch/arm/boot/dts/omap3-sbc-t3517.dts index 024c9c6c682d..42189b65d393 100644 --- a/arch/arm/boot/dts/omap3-sbc-t3517.dts +++ b/arch/arm/boot/dts/omap3-sbc-t3517.dts | |||
@@ -8,6 +8,19 @@ | |||
8 | / { | 8 | / { |
9 | model = "CompuLab SBC-T3517 with CM-T3517"; | 9 | model = "CompuLab SBC-T3517 with CM-T3517"; |
10 | compatible = "compulab,omap3-sbc-t3517", "compulab,omap3-cm-t3517", "ti,am3517", "ti,omap3"; | 10 | compatible = "compulab,omap3-sbc-t3517", "compulab,omap3-cm-t3517", "ti,am3517", "ti,omap3"; |
11 | |||
12 | /* Only one GPMC smsc9220 on SBC-T3517, CM-T3517 uses am35x Ethernet */ | ||
13 | vddvario: regulator-vddvario-sb-t35 { | ||
14 | compatible = "regulator-fixed"; | ||
15 | regulator-name = "vddvario"; | ||
16 | regulator-always-on; | ||
17 | }; | ||
18 | |||
19 | vdd33a: regulator-vdd33a-sb-t35 { | ||
20 | compatible = "regulator-fixed"; | ||
21 | regulator-name = "vdd33a"; | ||
22 | regulator-always-on; | ||
23 | }; | ||
11 | }; | 24 | }; |
12 | 25 | ||
13 | &omap3_pmx_core { | 26 | &omap3_pmx_core { |
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index acb9019dc437..4231191ade06 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi | |||
@@ -61,7 +61,7 @@ | |||
61 | ti,hwmods = "mpu"; | 61 | ti,hwmods = "mpu"; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | iva { | 64 | iva: iva { |
65 | compatible = "ti,iva2.2"; | 65 | compatible = "ti,iva2.2"; |
66 | ti,hwmods = "iva"; | 66 | ti,hwmods = "iva"; |
67 | 67 | ||
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index f8c9855ce587..36b4312a5e0d 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi | |||
@@ -630,6 +630,13 @@ | |||
630 | status = "disabled"; | 630 | status = "disabled"; |
631 | }; | 631 | }; |
632 | 632 | ||
633 | mailbox: mailbox@4a0f4000 { | ||
634 | compatible = "ti,omap4-mailbox"; | ||
635 | reg = <0x4a0f4000 0x200>; | ||
636 | interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; | ||
637 | ti,hwmods = "mailbox"; | ||
638 | }; | ||
639 | |||
633 | timer1: timer@4ae18000 { | 640 | timer1: timer@4ae18000 { |
634 | compatible = "ti,omap5430-timer"; | 641 | compatible = "ti,omap5430-timer"; |
635 | reg = <0x4ae18000 0x80>; | 642 | reg = <0x4ae18000 0x80>; |
diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi index eabcfdbb403a..a106b0872910 100644 --- a/arch/arm/boot/dts/sama5d3.dtsi +++ b/arch/arm/boot/dts/sama5d3.dtsi | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <dt-bindings/pinctrl/at91.h> | 13 | #include <dt-bindings/pinctrl/at91.h> |
14 | #include <dt-bindings/interrupt-controller/irq.h> | 14 | #include <dt-bindings/interrupt-controller/irq.h> |
15 | #include <dt-bindings/gpio/gpio.h> | 15 | #include <dt-bindings/gpio/gpio.h> |
16 | #include <dt-bindings/clk/at91.h> | 16 | #include <dt-bindings/clock/at91.h> |
17 | 17 | ||
18 | / { | 18 | / { |
19 | model = "Atmel SAMA5D3 family SoC"; | 19 | model = "Atmel SAMA5D3 family SoC"; |
diff --git a/arch/arm/boot/dts/sama5d3_mci2.dtsi b/arch/arm/boot/dts/sama5d3_mci2.dtsi index b029fe7ef17a..1b02208ea6ff 100644 --- a/arch/arm/boot/dts/sama5d3_mci2.dtsi +++ b/arch/arm/boot/dts/sama5d3_mci2.dtsi | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | #include <dt-bindings/pinctrl/at91.h> | 10 | #include <dt-bindings/pinctrl/at91.h> |
11 | #include <dt-bindings/interrupt-controller/irq.h> | 11 | #include <dt-bindings/interrupt-controller/irq.h> |
12 | #include <dt-bindings/clk/at91.h> | 12 | #include <dt-bindings/clock/at91.h> |
13 | 13 | ||
14 | / { | 14 | / { |
15 | ahb { | 15 | ahb { |
diff --git a/arch/arm/boot/dts/sama5d3_tcb1.dtsi b/arch/arm/boot/dts/sama5d3_tcb1.dtsi index 382b04431f66..02848453ca0c 100644 --- a/arch/arm/boot/dts/sama5d3_tcb1.dtsi +++ b/arch/arm/boot/dts/sama5d3_tcb1.dtsi | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | #include <dt-bindings/pinctrl/at91.h> | 10 | #include <dt-bindings/pinctrl/at91.h> |
11 | #include <dt-bindings/interrupt-controller/irq.h> | 11 | #include <dt-bindings/interrupt-controller/irq.h> |
12 | #include <dt-bindings/clk/at91.h> | 12 | #include <dt-bindings/clock/at91.h> |
13 | 13 | ||
14 | / { | 14 | / { |
15 | aliases { | 15 | aliases { |
diff --git a/arch/arm/boot/dts/sama5d3_uart.dtsi b/arch/arm/boot/dts/sama5d3_uart.dtsi index a9fa75e41652..7a8d4c6115f7 100644 --- a/arch/arm/boot/dts/sama5d3_uart.dtsi +++ b/arch/arm/boot/dts/sama5d3_uart.dtsi | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | #include <dt-bindings/pinctrl/at91.h> | 10 | #include <dt-bindings/pinctrl/at91.h> |
11 | #include <dt-bindings/interrupt-controller/irq.h> | 11 | #include <dt-bindings/interrupt-controller/irq.h> |
12 | #include <dt-bindings/clk/at91.h> | 12 | #include <dt-bindings/clock/at91.h> |
13 | 13 | ||
14 | / { | 14 | / { |
15 | aliases { | 15 | aliases { |
diff --git a/arch/arm/boot/dts/ste-ccu8540.dts b/arch/arm/boot/dts/ste-ccu8540.dts index 7f3baf51a3a9..32dd55e5f4e6 100644 --- a/arch/arm/boot/dts/ste-ccu8540.dts +++ b/arch/arm/boot/dts/ste-ccu8540.dts | |||
@@ -18,6 +18,7 @@ | |||
18 | compatible = "st-ericsson,ccu8540", "st-ericsson,u8540"; | 18 | compatible = "st-ericsson,ccu8540", "st-ericsson,u8540"; |
19 | 19 | ||
20 | memory@0 { | 20 | memory@0 { |
21 | device_type = "memory"; | ||
21 | reg = <0x20000000 0x1f000000>, <0xc0000000 0x3f000000>; | 22 | reg = <0x20000000 0x1f000000>, <0xc0000000 0x3f000000>; |
22 | }; | 23 | }; |
23 | 24 | ||
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 32efc105df83..aba1c8a3f388 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi | |||
@@ -87,7 +87,7 @@ | |||
87 | 87 | ||
88 | pll4: clk@01c20018 { | 88 | pll4: clk@01c20018 { |
89 | #clock-cells = <0>; | 89 | #clock-cells = <0>; |
90 | compatible = "allwinner,sun4i-a10-pll1-clk"; | 90 | compatible = "allwinner,sun7i-a20-pll4-clk"; |
91 | reg = <0x01c20018 0x4>; | 91 | reg = <0x01c20018 0x4>; |
92 | clocks = <&osc24M>; | 92 | clocks = <&osc24M>; |
93 | clock-output-names = "pll4"; | 93 | clock-output-names = "pll4"; |
@@ -109,6 +109,14 @@ | |||
109 | clock-output-names = "pll6_sata", "pll6_other", "pll6"; | 109 | clock-output-names = "pll6_sata", "pll6_other", "pll6"; |
110 | }; | 110 | }; |
111 | 111 | ||
112 | pll8: clk@01c20040 { | ||
113 | #clock-cells = <0>; | ||
114 | compatible = "allwinner,sun7i-a20-pll4-clk"; | ||
115 | reg = <0x01c20040 0x4>; | ||
116 | clocks = <&osc24M>; | ||
117 | clock-output-names = "pll8"; | ||
118 | }; | ||
119 | |||
112 | cpu: cpu@01c20054 { | 120 | cpu: cpu@01c20054 { |
113 | #clock-cells = <0>; | 121 | #clock-cells = <0>; |
114 | compatible = "allwinner,sun4i-a10-cpu-clk"; | 122 | compatible = "allwinner,sun4i-a10-cpu-clk"; |
@@ -805,9 +813,9 @@ | |||
805 | status = "disabled"; | 813 | status = "disabled"; |
806 | }; | 814 | }; |
807 | 815 | ||
808 | i2c4: i2c@01c2bc00 { | 816 | i2c4: i2c@01c2c000 { |
809 | compatible = "allwinner,sun4i-i2c"; | 817 | compatible = "allwinner,sun4i-i2c"; |
810 | reg = <0x01c2bc00 0x400>; | 818 | reg = <0x01c2c000 0x400>; |
811 | interrupts = <0 89 4>; | 819 | interrupts = <0 89 4>; |
812 | clocks = <&apb1_gates 15>; | 820 | clocks = <&apb1_gates 15>; |
813 | clock-frequency = <100000>; | 821 | clock-frequency = <100000>; |
diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index 41bca32409fc..5339009b3c0c 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c | |||
@@ -1423,55 +1423,38 @@ EXPORT_SYMBOL(edma_clear_event); | |||
1423 | 1423 | ||
1424 | #if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DMADEVICES) | 1424 | #if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DMADEVICES) |
1425 | 1425 | ||
1426 | static int edma_of_read_u32_to_s16_array(const struct device_node *np, | 1426 | static int edma_xbar_event_map(struct device *dev, struct device_node *node, |
1427 | const char *propname, s16 *out_values, | 1427 | struct edma_soc_info *pdata, size_t sz) |
1428 | size_t sz) | ||
1429 | { | 1428 | { |
1430 | int ret; | 1429 | const char pname[] = "ti,edma-xbar-event-map"; |
1431 | |||
1432 | ret = of_property_read_u16_array(np, propname, out_values, sz); | ||
1433 | if (ret) | ||
1434 | return ret; | ||
1435 | |||
1436 | /* Terminate it */ | ||
1437 | *out_values++ = -1; | ||
1438 | *out_values++ = -1; | ||
1439 | |||
1440 | return 0; | ||
1441 | } | ||
1442 | |||
1443 | static int edma_xbar_event_map(struct device *dev, | ||
1444 | struct device_node *node, | ||
1445 | struct edma_soc_info *pdata, int len) | ||
1446 | { | ||
1447 | int ret, i; | ||
1448 | struct resource res; | 1430 | struct resource res; |
1449 | void __iomem *xbar; | 1431 | void __iomem *xbar; |
1450 | const s16 (*xbar_chans)[2]; | 1432 | s16 (*xbar_chans)[2]; |
1433 | size_t nelm = sz / sizeof(s16); | ||
1451 | u32 shift, offset, mux; | 1434 | u32 shift, offset, mux; |
1435 | int ret, i; | ||
1452 | 1436 | ||
1453 | xbar_chans = devm_kzalloc(dev, | 1437 | xbar_chans = devm_kzalloc(dev, (nelm + 2) * sizeof(s16), GFP_KERNEL); |
1454 | len/sizeof(s16) + 2*sizeof(s16), | ||
1455 | GFP_KERNEL); | ||
1456 | if (!xbar_chans) | 1438 | if (!xbar_chans) |
1457 | return -ENOMEM; | 1439 | return -ENOMEM; |
1458 | 1440 | ||
1459 | ret = of_address_to_resource(node, 1, &res); | 1441 | ret = of_address_to_resource(node, 1, &res); |
1460 | if (ret) | 1442 | if (ret) |
1461 | return -EIO; | 1443 | return -ENOMEM; |
1462 | 1444 | ||
1463 | xbar = devm_ioremap(dev, res.start, resource_size(&res)); | 1445 | xbar = devm_ioremap(dev, res.start, resource_size(&res)); |
1464 | if (!xbar) | 1446 | if (!xbar) |
1465 | return -ENOMEM; | 1447 | return -ENOMEM; |
1466 | 1448 | ||
1467 | ret = edma_of_read_u32_to_s16_array(node, | 1449 | ret = of_property_read_u16_array(node, pname, (u16 *)xbar_chans, nelm); |
1468 | "ti,edma-xbar-event-map", | ||
1469 | (s16 *)xbar_chans, | ||
1470 | len/sizeof(u32)); | ||
1471 | if (ret) | 1450 | if (ret) |
1472 | return -EIO; | 1451 | return -EIO; |
1473 | 1452 | ||
1474 | for (i = 0; xbar_chans[i][0] != -1; i++) { | 1453 | /* Invalidate last entry for the other user of this mess */ |
1454 | nelm >>= 1; | ||
1455 | xbar_chans[nelm][0] = xbar_chans[nelm][1] = -1; | ||
1456 | |||
1457 | for (i = 0; i < nelm; i++) { | ||
1475 | shift = (xbar_chans[i][1] & 0x03) << 3; | 1458 | shift = (xbar_chans[i][1] & 0x03) << 3; |
1476 | offset = xbar_chans[i][1] & 0xfffffffc; | 1459 | offset = xbar_chans[i][1] & 0xfffffffc; |
1477 | mux = readl(xbar + offset); | 1460 | mux = readl(xbar + offset); |
@@ -1480,8 +1463,7 @@ static int edma_xbar_event_map(struct device *dev, | |||
1480 | writel(mux, (xbar + offset)); | 1463 | writel(mux, (xbar + offset)); |
1481 | } | 1464 | } |
1482 | 1465 | ||
1483 | pdata->xbar_chans = xbar_chans; | 1466 | pdata->xbar_chans = (const s16 (*)[2]) xbar_chans; |
1484 | |||
1485 | return 0; | 1467 | return 0; |
1486 | } | 1468 | } |
1487 | 1469 | ||
diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig index b5df4a511b0a..81ba78eaf54a 100644 --- a/arch/arm/configs/sunxi_defconfig +++ b/arch/arm/configs/sunxi_defconfig | |||
@@ -37,7 +37,7 @@ CONFIG_SUN4I_EMAC=y | |||
37 | # CONFIG_NET_VENDOR_NATSEMI is not set | 37 | # CONFIG_NET_VENDOR_NATSEMI is not set |
38 | # CONFIG_NET_VENDOR_SEEQ is not set | 38 | # CONFIG_NET_VENDOR_SEEQ is not set |
39 | # CONFIG_NET_VENDOR_SMSC is not set | 39 | # CONFIG_NET_VENDOR_SMSC is not set |
40 | # CONFIG_NET_VENDOR_STMICRO is not set | 40 | CONFIG_STMMAC_ETH=y |
41 | # CONFIG_NET_VENDOR_WIZNET is not set | 41 | # CONFIG_NET_VENDOR_WIZNET is not set |
42 | # CONFIG_WLAN is not set | 42 | # CONFIG_WLAN is not set |
43 | CONFIG_SERIAL_8250=y | 43 | CONFIG_SERIAL_8250=y |
diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h index cf4f3e867395..ded062f9b358 100644 --- a/arch/arm/include/asm/xen/page.h +++ b/arch/arm/include/asm/xen/page.h | |||
@@ -77,7 +77,6 @@ static inline xpaddr_t machine_to_phys(xmaddr_t machine) | |||
77 | } | 77 | } |
78 | /* VIRT <-> MACHINE conversion */ | 78 | /* VIRT <-> MACHINE conversion */ |
79 | #define virt_to_machine(v) (phys_to_machine(XPADDR(__pa(v)))) | 79 | #define virt_to_machine(v) (phys_to_machine(XPADDR(__pa(v)))) |
80 | #define virt_to_pfn(v) (PFN_DOWN(__pa(v))) | ||
81 | #define virt_to_mfn(v) (pfn_to_mfn(virt_to_pfn(v))) | 80 | #define virt_to_mfn(v) (pfn_to_mfn(virt_to_pfn(v))) |
82 | #define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT)) | 81 | #define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT)) |
83 | 82 | ||
diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 75e92952c18e..40c5d5f1451c 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Secondary CPU startup routine source file. | 2 | * Secondary CPU startup routine source file. |
3 | * | 3 | * |
4 | * Copyright (C) 2009 Texas Instruments, Inc. | 4 | * Copyright (C) 2009-2014 Texas Instruments, Inc. |
5 | * | 5 | * |
6 | * Author: | 6 | * Author: |
7 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | 7 | * Santosh Shilimkar <santosh.shilimkar@ti.com> |
@@ -28,9 +28,13 @@ | |||
28 | * code. This routine also provides a holding flag into which | 28 | * code. This routine also provides a holding flag into which |
29 | * secondary core is held until we're ready for it to initialise. | 29 | * secondary core is held until we're ready for it to initialise. |
30 | * The primary core will update this flag using a hardware | 30 | * The primary core will update this flag using a hardware |
31 | + * register AuxCoreBoot0. | 31 | * register AuxCoreBoot0. |
32 | */ | 32 | */ |
33 | ENTRY(omap5_secondary_startup) | 33 | ENTRY(omap5_secondary_startup) |
34 | .arm | ||
35 | THUMB( adr r9, BSYM(wait) ) @ CPU may be entered in ARM mode. | ||
36 | THUMB( bx r9 ) @ If this is a Thumb-2 kernel, | ||
37 | THUMB( .thumb ) @ switch to Thumb now. | ||
34 | wait: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0 | 38 | wait: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0 |
35 | ldr r0, [r2] | 39 | ldr r0, [r2] |
36 | mov r0, r0, lsr #5 | 40 | mov r0, r0, lsr #5 |
diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h index f565f9944af2..7548db2bfb8a 100644 --- a/arch/arm/mach-orion5x/common.h +++ b/arch/arm/mach-orion5x/common.h | |||
@@ -21,7 +21,7 @@ struct mv_sata_platform_data; | |||
21 | #define ORION_MBUS_DEVBUS_BOOT_ATTR 0x0f | 21 | #define ORION_MBUS_DEVBUS_BOOT_ATTR 0x0f |
22 | #define ORION_MBUS_DEVBUS_TARGET(cs) 0x01 | 22 | #define ORION_MBUS_DEVBUS_TARGET(cs) 0x01 |
23 | #define ORION_MBUS_DEVBUS_ATTR(cs) (~(1 << cs)) | 23 | #define ORION_MBUS_DEVBUS_ATTR(cs) (~(1 << cs)) |
24 | #define ORION_MBUS_SRAM_TARGET 0x00 | 24 | #define ORION_MBUS_SRAM_TARGET 0x09 |
25 | #define ORION_MBUS_SRAM_ATTR 0x00 | 25 | #define ORION_MBUS_SRAM_ATTR 0x00 |
26 | 26 | ||
27 | /* | 27 | /* |
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index e94f9458aa6f..993bce527b85 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h | |||
@@ -138,6 +138,7 @@ static inline void *phys_to_virt(phys_addr_t x) | |||
138 | #define __pa(x) __virt_to_phys((unsigned long)(x)) | 138 | #define __pa(x) __virt_to_phys((unsigned long)(x)) |
139 | #define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x))) | 139 | #define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x))) |
140 | #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) | 140 | #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) |
141 | #define virt_to_pfn(x) __phys_to_pfn(__virt_to_phys(x)) | ||
141 | 142 | ||
142 | /* | 143 | /* |
143 | * virt_to_page(k) convert a _valid_ virtual address to struct page * | 144 | * virt_to_page(k) convert a _valid_ virtual address to struct page * |
diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c index 473e5dbf8f39..0f08dfd69ebc 100644 --- a/arch/arm64/kernel/irq.c +++ b/arch/arm64/kernel/irq.c | |||
@@ -97,11 +97,15 @@ static bool migrate_one_irq(struct irq_desc *desc) | |||
97 | if (irqd_is_per_cpu(d) || !cpumask_test_cpu(smp_processor_id(), affinity)) | 97 | if (irqd_is_per_cpu(d) || !cpumask_test_cpu(smp_processor_id(), affinity)) |
98 | return false; | 98 | return false; |
99 | 99 | ||
100 | if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) { | 100 | if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) |
101 | affinity = cpu_online_mask; | ||
102 | ret = true; | 101 | ret = true; |
103 | } | ||
104 | 102 | ||
103 | /* | ||
104 | * when using forced irq_set_affinity we must ensure that the cpu | ||
105 | * being offlined is not present in the affinity mask, it may be | ||
106 | * selected as the target CPU otherwise | ||
107 | */ | ||
108 | affinity = cpu_online_mask; | ||
105 | c = irq_data_get_irq_chip(d); | 109 | c = irq_data_get_irq_chip(d); |
106 | if (!c->irq_set_affinity) | 110 | if (!c->irq_set_affinity) |
107 | pr_debug("IRQ%u: unable to set affinity\n", d->irq); | 111 | pr_debug("IRQ%u: unable to set affinity\n", d->irq); |
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 5e9aec358306..31eb959e9aa8 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c | |||
@@ -51,7 +51,11 @@ int pmd_huge(pmd_t pmd) | |||
51 | 51 | ||
52 | int pud_huge(pud_t pud) | 52 | int pud_huge(pud_t pud) |
53 | { | 53 | { |
54 | #ifndef __PAGETABLE_PMD_FOLDED | ||
54 | return !(pud_val(pud) & PUD_TABLE_BIT); | 55 | return !(pud_val(pud) & PUD_TABLE_BIT); |
56 | #else | ||
57 | return 0; | ||
58 | #endif | ||
55 | } | 59 | } |
56 | 60 | ||
57 | int pmd_huge_support(void) | 61 | int pmd_huge_support(void) |
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h index ae763d8bf55a..fb13dc5e8f8c 100644 --- a/arch/ia64/include/asm/unistd.h +++ b/arch/ia64/include/asm/unistd.h | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | 12 | ||
13 | 13 | ||
14 | #define NR_syscalls 314 /* length of syscall table */ | 14 | #define NR_syscalls 315 /* length of syscall table */ |
15 | 15 | ||
16 | /* | 16 | /* |
17 | * The following defines stop scripts/checksyscalls.sh from complaining about | 17 | * The following defines stop scripts/checksyscalls.sh from complaining about |
diff --git a/arch/ia64/include/uapi/asm/unistd.h b/arch/ia64/include/uapi/asm/unistd.h index 715e85f858de..7de0a2d65da4 100644 --- a/arch/ia64/include/uapi/asm/unistd.h +++ b/arch/ia64/include/uapi/asm/unistd.h | |||
@@ -327,5 +327,6 @@ | |||
327 | #define __NR_finit_module 1335 | 327 | #define __NR_finit_module 1335 |
328 | #define __NR_sched_setattr 1336 | 328 | #define __NR_sched_setattr 1336 |
329 | #define __NR_sched_getattr 1337 | 329 | #define __NR_sched_getattr 1337 |
330 | #define __NR_renameat2 1338 | ||
330 | 331 | ||
331 | #endif /* _UAPI_ASM_IA64_UNISTD_H */ | 332 | #endif /* _UAPI_ASM_IA64_UNISTD_H */ |
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index fa8d61a312a7..ba3d03503e84 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -1775,6 +1775,7 @@ sys_call_table: | |||
1775 | data8 sys_finit_module // 1335 | 1775 | data8 sys_finit_module // 1335 |
1776 | data8 sys_sched_setattr | 1776 | data8 sys_sched_setattr |
1777 | data8 sys_sched_getattr | 1777 | data8 sys_sched_getattr |
1778 | data8 sys_renameat2 | ||
1778 | 1779 | ||
1779 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls | 1780 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls |
1780 | #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */ | 1781 | #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */ |
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index 9d38b73989eb..33afa56ad47a 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #include <uapi/asm/unistd.h> | 4 | #include <uapi/asm/unistd.h> |
5 | 5 | ||
6 | 6 | ||
7 | #define NR_syscalls 351 | 7 | #define NR_syscalls 352 |
8 | 8 | ||
9 | #define __ARCH_WANT_OLD_READDIR | 9 | #define __ARCH_WANT_OLD_READDIR |
10 | #define __ARCH_WANT_OLD_STAT | 10 | #define __ARCH_WANT_OLD_STAT |
diff --git a/arch/m68k/include/uapi/asm/unistd.h b/arch/m68k/include/uapi/asm/unistd.h index b932dd470041..9cd82fbc7817 100644 --- a/arch/m68k/include/uapi/asm/unistd.h +++ b/arch/m68k/include/uapi/asm/unistd.h | |||
@@ -356,5 +356,6 @@ | |||
356 | #define __NR_finit_module 348 | 356 | #define __NR_finit_module 348 |
357 | #define __NR_sched_setattr 349 | 357 | #define __NR_sched_setattr 349 |
358 | #define __NR_sched_getattr 350 | 358 | #define __NR_sched_getattr 350 |
359 | #define __NR_renameat2 351 | ||
359 | 360 | ||
360 | #endif /* _UAPI_ASM_M68K_UNISTD_H_ */ | 361 | #endif /* _UAPI_ASM_M68K_UNISTD_H_ */ |
diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S index b6223dc41d82..501e10212789 100644 --- a/arch/m68k/kernel/syscalltable.S +++ b/arch/m68k/kernel/syscalltable.S | |||
@@ -371,4 +371,5 @@ ENTRY(sys_call_table) | |||
371 | .long sys_finit_module | 371 | .long sys_finit_module |
372 | .long sys_sched_setattr | 372 | .long sys_sched_setattr |
373 | .long sys_sched_getattr /* 350 */ | 373 | .long sys_sched_getattr /* 350 */ |
374 | .long sys_renameat2 | ||
374 | 375 | ||
diff --git a/arch/metag/include/asm/barrier.h b/arch/metag/include/asm/barrier.h index 5d6b4b407dda..2d6f0de77325 100644 --- a/arch/metag/include/asm/barrier.h +++ b/arch/metag/include/asm/barrier.h | |||
@@ -15,6 +15,7 @@ static inline void wr_fence(void) | |||
15 | volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_FENCE; | 15 | volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_FENCE; |
16 | barrier(); | 16 | barrier(); |
17 | *flushptr = 0; | 17 | *flushptr = 0; |
18 | barrier(); | ||
18 | } | 19 | } |
19 | 20 | ||
20 | #else /* CONFIG_METAG_META21 */ | 21 | #else /* CONFIG_METAG_META21 */ |
@@ -35,6 +36,7 @@ static inline void wr_fence(void) | |||
35 | *flushptr = 0; | 36 | *flushptr = 0; |
36 | *flushptr = 0; | 37 | *flushptr = 0; |
37 | *flushptr = 0; | 38 | *flushptr = 0; |
39 | barrier(); | ||
38 | } | 40 | } |
39 | 41 | ||
40 | #endif /* !CONFIG_METAG_META21 */ | 42 | #endif /* !CONFIG_METAG_META21 */ |
@@ -68,6 +70,7 @@ static inline void fence(void) | |||
68 | volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_ATOMIC_UNLOCK; | 70 | volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_ATOMIC_UNLOCK; |
69 | barrier(); | 71 | barrier(); |
70 | *flushptr = 0; | 72 | *flushptr = 0; |
73 | barrier(); | ||
71 | } | 74 | } |
72 | #define smp_mb() fence() | 75 | #define smp_mb() fence() |
73 | #define smp_rmb() fence() | 76 | #define smp_rmb() fence() |
diff --git a/arch/metag/include/asm/processor.h b/arch/metag/include/asm/processor.h index f16477d1f571..a8a37477c66e 100644 --- a/arch/metag/include/asm/processor.h +++ b/arch/metag/include/asm/processor.h | |||
@@ -22,6 +22,8 @@ | |||
22 | /* Add an extra page of padding at the top of the stack for the guard page. */ | 22 | /* Add an extra page of padding at the top of the stack for the guard page. */ |
23 | #define STACK_TOP (TASK_SIZE - PAGE_SIZE) | 23 | #define STACK_TOP (TASK_SIZE - PAGE_SIZE) |
24 | #define STACK_TOP_MAX STACK_TOP | 24 | #define STACK_TOP_MAX STACK_TOP |
25 | /* Maximum virtual space for stack */ | ||
26 | #define STACK_SIZE_MAX (CONFIG_MAX_STACK_SIZE_MB*1024*1024) | ||
25 | 27 | ||
26 | /* This decides where the kernel will search for a free chunk of vm | 28 | /* This decides where the kernel will search for a free chunk of vm |
27 | * space during mmap's. | 29 | * space during mmap's. |
diff --git a/arch/metag/include/uapi/asm/Kbuild b/arch/metag/include/uapi/asm/Kbuild index 84e09feb4d54..ab78be2b6eb0 100644 --- a/arch/metag/include/uapi/asm/Kbuild +++ b/arch/metag/include/uapi/asm/Kbuild | |||
@@ -4,11 +4,11 @@ include include/uapi/asm-generic/Kbuild.asm | |||
4 | header-y += byteorder.h | 4 | header-y += byteorder.h |
5 | header-y += ech.h | 5 | header-y += ech.h |
6 | header-y += ptrace.h | 6 | header-y += ptrace.h |
7 | header-y += resource.h | ||
8 | header-y += sigcontext.h | 7 | header-y += sigcontext.h |
9 | header-y += siginfo.h | 8 | header-y += siginfo.h |
10 | header-y += swab.h | 9 | header-y += swab.h |
11 | header-y += unistd.h | 10 | header-y += unistd.h |
12 | 11 | ||
13 | generic-y += mman.h | 12 | generic-y += mman.h |
13 | generic-y += resource.h | ||
14 | generic-y += setup.h | 14 | generic-y += setup.h |
diff --git a/arch/metag/include/uapi/asm/resource.h b/arch/metag/include/uapi/asm/resource.h deleted file mode 100644 index 526d23cc3054..000000000000 --- a/arch/metag/include/uapi/asm/resource.h +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | #ifndef _UAPI_METAG_RESOURCE_H | ||
2 | #define _UAPI_METAG_RESOURCE_H | ||
3 | |||
4 | #define _STK_LIM_MAX (1 << 28) | ||
5 | #include <asm-generic/resource.h> | ||
6 | |||
7 | #endif /* _UAPI_METAG_RESOURCE_H */ | ||
diff --git a/arch/mips/dec/ecc-berr.c b/arch/mips/dec/ecc-berr.c index 5abf4e894216..2a66e908f6a9 100644 --- a/arch/mips/dec/ecc-berr.c +++ b/arch/mips/dec/ecc-berr.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/addrspace.h> | 21 | #include <asm/addrspace.h> |
22 | #include <asm/bootinfo.h> | 22 | #include <asm/bootinfo.h> |
23 | #include <asm/cpu.h> | 23 | #include <asm/cpu.h> |
24 | #include <asm/cpu-type.h> | ||
24 | #include <asm/irq_regs.h> | 25 | #include <asm/irq_regs.h> |
25 | #include <asm/processor.h> | 26 | #include <asm/processor.h> |
26 | #include <asm/ptrace.h> | 27 | #include <asm/ptrace.h> |
diff --git a/arch/mips/dec/kn02xa-berr.c b/arch/mips/dec/kn02xa-berr.c index f434b759e3b9..ec606363b806 100644 --- a/arch/mips/dec/kn02xa-berr.c +++ b/arch/mips/dec/kn02xa-berr.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/types.h> | 19 | #include <linux/types.h> |
20 | 20 | ||
21 | #include <asm/addrspace.h> | 21 | #include <asm/addrspace.h> |
22 | #include <asm/cpu-type.h> | ||
22 | #include <asm/irq_regs.h> | 23 | #include <asm/irq_regs.h> |
23 | #include <asm/ptrace.h> | 24 | #include <asm/ptrace.h> |
24 | #include <asm/traps.h> | 25 | #include <asm/traps.h> |
diff --git a/arch/mips/dec/prom/Makefile b/arch/mips/dec/prom/Makefile index 064ae7a76bdc..ae73e42ac20b 100644 --- a/arch/mips/dec/prom/Makefile +++ b/arch/mips/dec/prom/Makefile | |||
@@ -6,4 +6,3 @@ | |||
6 | lib-y += init.o memory.o cmdline.o identify.o console.o | 6 | lib-y += init.o memory.o cmdline.o identify.o console.o |
7 | 7 | ||
8 | lib-$(CONFIG_32BIT) += locore.o | 8 | lib-$(CONFIG_32BIT) += locore.o |
9 | lib-$(CONFIG_64BIT) += call_o32.o | ||
diff --git a/arch/mips/dec/prom/call_o32.S b/arch/mips/dec/prom/call_o32.S deleted file mode 100644 index 8c8498159e43..000000000000 --- a/arch/mips/dec/prom/call_o32.S +++ /dev/null | |||
@@ -1,89 +0,0 @@ | |||
1 | /* | ||
2 | * O32 interface for the 64 (or N32) ABI. | ||
3 | * | ||
4 | * Copyright (C) 2002 Maciej W. Rozycki | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <asm/asm.h> | ||
13 | #include <asm/regdef.h> | ||
14 | |||
15 | /* Maximum number of arguments supported. Must be even! */ | ||
16 | #define O32_ARGC 32 | ||
17 | /* Number of static registers we save. */ | ||
18 | #define O32_STATC 11 | ||
19 | /* Frame size for both of the above. */ | ||
20 | #define O32_FRAMESZ (4 * O32_ARGC + SZREG * O32_STATC) | ||
21 | |||
22 | .text | ||
23 | |||
24 | /* | ||
25 | * O32 function call dispatcher, for interfacing 32-bit ROM routines. | ||
26 | * | ||
27 | * The standard 64 (N32) calling sequence is supported, with a0 | ||
28 | * holding a function pointer, a1-a7 -- its first seven arguments | ||
29 | * and the stack -- remaining ones (up to O32_ARGC, including a1-a7). | ||
30 | * Static registers, gp and fp are preserved, v0 holds a result. | ||
31 | * This code relies on the called o32 function for sp and ra | ||
32 | * restoration and thus both this dispatcher and the current stack | ||
33 | * have to be placed in a KSEGx (or KUSEG) address space. Any | ||
34 | * pointers passed have to point to addresses within one of these | ||
35 | * spaces as well. | ||
36 | */ | ||
37 | NESTED(call_o32, O32_FRAMESZ, ra) | ||
38 | REG_SUBU sp,O32_FRAMESZ | ||
39 | |||
40 | REG_S ra,O32_FRAMESZ-1*SZREG(sp) | ||
41 | REG_S fp,O32_FRAMESZ-2*SZREG(sp) | ||
42 | REG_S gp,O32_FRAMESZ-3*SZREG(sp) | ||
43 | REG_S s7,O32_FRAMESZ-4*SZREG(sp) | ||
44 | REG_S s6,O32_FRAMESZ-5*SZREG(sp) | ||
45 | REG_S s5,O32_FRAMESZ-6*SZREG(sp) | ||
46 | REG_S s4,O32_FRAMESZ-7*SZREG(sp) | ||
47 | REG_S s3,O32_FRAMESZ-8*SZREG(sp) | ||
48 | REG_S s2,O32_FRAMESZ-9*SZREG(sp) | ||
49 | REG_S s1,O32_FRAMESZ-10*SZREG(sp) | ||
50 | REG_S s0,O32_FRAMESZ-11*SZREG(sp) | ||
51 | |||
52 | move jp,a0 | ||
53 | |||
54 | sll a0,a1,zero | ||
55 | sll a1,a2,zero | ||
56 | sll a2,a3,zero | ||
57 | sll a3,a4,zero | ||
58 | sw a5,0x10(sp) | ||
59 | sw a6,0x14(sp) | ||
60 | sw a7,0x18(sp) | ||
61 | |||
62 | PTR_LA t0,O32_FRAMESZ(sp) | ||
63 | PTR_LA t1,0x1c(sp) | ||
64 | li t2,O32_ARGC-7 | ||
65 | 1: | ||
66 | lw t3,(t0) | ||
67 | REG_ADDU t0,SZREG | ||
68 | sw t3,(t1) | ||
69 | REG_SUBU t2,1 | ||
70 | REG_ADDU t1,4 | ||
71 | bnez t2,1b | ||
72 | |||
73 | jalr jp | ||
74 | |||
75 | REG_L s0,O32_FRAMESZ-11*SZREG(sp) | ||
76 | REG_L s1,O32_FRAMESZ-10*SZREG(sp) | ||
77 | REG_L s2,O32_FRAMESZ-9*SZREG(sp) | ||
78 | REG_L s3,O32_FRAMESZ-8*SZREG(sp) | ||
79 | REG_L s4,O32_FRAMESZ-7*SZREG(sp) | ||
80 | REG_L s5,O32_FRAMESZ-6*SZREG(sp) | ||
81 | REG_L s6,O32_FRAMESZ-5*SZREG(sp) | ||
82 | REG_L s7,O32_FRAMESZ-4*SZREG(sp) | ||
83 | REG_L gp,O32_FRAMESZ-3*SZREG(sp) | ||
84 | REG_L fp,O32_FRAMESZ-2*SZREG(sp) | ||
85 | REG_L ra,O32_FRAMESZ-1*SZREG(sp) | ||
86 | |||
87 | REG_ADDU sp,O32_FRAMESZ | ||
88 | jr ra | ||
89 | END(call_o32) | ||
diff --git a/arch/mips/fw/lib/call_o32.S b/arch/mips/fw/lib/call_o32.S index b308b2a0613e..4703fe4dbd9a 100644 --- a/arch/mips/fw/lib/call_o32.S +++ b/arch/mips/fw/lib/call_o32.S | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * O32 interface for the 64 (or N32) ABI. | 2 | * O32 interface for the 64 (or N32) ABI. |
3 | * | 3 | * |
4 | * Copyright (C) 2002 Maciej W. Rozycki | 4 | * Copyright (C) 2002, 2014 Maciej W. Rozycki |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
@@ -12,28 +12,37 @@ | |||
12 | #include <asm/asm.h> | 12 | #include <asm/asm.h> |
13 | #include <asm/regdef.h> | 13 | #include <asm/regdef.h> |
14 | 14 | ||
15 | /* O32 register size. */ | ||
16 | #define O32_SZREG 4 | ||
15 | /* Maximum number of arguments supported. Must be even! */ | 17 | /* Maximum number of arguments supported. Must be even! */ |
16 | #define O32_ARGC 32 | 18 | #define O32_ARGC 32 |
17 | /* Number of static registers we save. */ | 19 | /* Number of static registers we save. */ |
18 | #define O32_STATC 11 | 20 | #define O32_STATC 11 |
19 | /* Frame size for static register */ | 21 | /* Argument area frame size. */ |
20 | #define O32_FRAMESZ (SZREG * O32_STATC) | 22 | #define O32_ARGSZ (O32_SZREG * O32_ARGC) |
21 | /* Frame size on new stack */ | 23 | /* Static register save area frame size. */ |
22 | #define O32_FRAMESZ_NEW (SZREG + 4 * O32_ARGC) | 24 | #define O32_STATSZ (SZREG * O32_STATC) |
25 | /* Stack pointer register save area frame size. */ | ||
26 | #define O32_SPSZ SZREG | ||
27 | /* Combined area frame size. */ | ||
28 | #define O32_FRAMESZ (O32_ARGSZ + O32_SPSZ + O32_STATSZ) | ||
29 | /* Switched stack frame size. */ | ||
30 | #define O32_NFRAMESZ (O32_ARGSZ + O32_SPSZ) | ||
23 | 31 | ||
24 | .text | 32 | .text |
25 | 33 | ||
26 | /* | 34 | /* |
27 | * O32 function call dispatcher, for interfacing 32-bit ROM routines. | 35 | * O32 function call dispatcher, for interfacing 32-bit ROM routines. |
28 | * | 36 | * |
29 | * The standard 64 (N32) calling sequence is supported, with a0 | 37 | * The standard 64 (N32) calling sequence is supported, with a0 holding |
30 | * holding a function pointer, a1 a new stack pointer, a2-a7 -- its | 38 | * a function pointer, a1 a pointer to the new stack to call the |
31 | * first six arguments and the stack -- remaining ones (up to O32_ARGC, | 39 | * function with or 0 if no stack switching is requested, a2-a7 -- the |
32 | * including a2-a7). Static registers, gp and fp are preserved, v0 holds | 40 | * function call's first six arguments, and the stack -- the remaining |
33 | * a result. This code relies on the called o32 function for sp and ra | 41 | * arguments (up to O32_ARGC, including a2-a7). Static registers, gp |
34 | * restoration and this dispatcher has to be placed in a KSEGx (or KUSEG) | 42 | * and fp are preserved, v0 holds the result. This code relies on the |
35 | * address space. Any pointers passed have to point to addresses within | 43 | * called o32 function for sp and ra restoration and this dispatcher has |
36 | * one of these spaces as well. | 44 | * to be placed in a KSEGx (or KUSEG) address space. Any pointers |
45 | * passed have to point to addresses within one of these spaces as well. | ||
37 | */ | 46 | */ |
38 | NESTED(call_o32, O32_FRAMESZ, ra) | 47 | NESTED(call_o32, O32_FRAMESZ, ra) |
39 | REG_SUBU sp,O32_FRAMESZ | 48 | REG_SUBU sp,O32_FRAMESZ |
@@ -51,32 +60,36 @@ NESTED(call_o32, O32_FRAMESZ, ra) | |||
51 | REG_S s0,O32_FRAMESZ-11*SZREG(sp) | 60 | REG_S s0,O32_FRAMESZ-11*SZREG(sp) |
52 | 61 | ||
53 | move jp,a0 | 62 | move jp,a0 |
54 | REG_SUBU s0,a1,O32_FRAMESZ_NEW | 63 | |
55 | REG_S sp,O32_FRAMESZ_NEW-1*SZREG(s0) | 64 | move fp,sp |
65 | beqz a1,0f | ||
66 | REG_SUBU fp,a1,O32_NFRAMESZ | ||
67 | 0: | ||
68 | REG_S sp,O32_NFRAMESZ-1*SZREG(fp) | ||
56 | 69 | ||
57 | sll a0,a2,zero | 70 | sll a0,a2,zero |
58 | sll a1,a3,zero | 71 | sll a1,a3,zero |
59 | sll a2,a4,zero | 72 | sll a2,a4,zero |
60 | sll a3,a5,zero | 73 | sll a3,a5,zero |
61 | sw a6,0x10(s0) | 74 | sw a6,4*O32_SZREG(fp) |
62 | sw a7,0x14(s0) | 75 | sw a7,5*O32_SZREG(fp) |
63 | 76 | ||
64 | PTR_LA t0,O32_FRAMESZ(sp) | 77 | PTR_LA t0,O32_FRAMESZ(sp) |
65 | PTR_LA t1,0x18(s0) | 78 | PTR_LA t1,6*O32_SZREG(fp) |
66 | li t2,O32_ARGC-6 | 79 | li t2,O32_ARGC-6 |
67 | 1: | 80 | 1: |
68 | lw t3,(t0) | 81 | lw t3,(t0) |
69 | REG_ADDU t0,SZREG | 82 | REG_ADDU t0,SZREG |
70 | sw t3,(t1) | 83 | sw t3,(t1) |
71 | REG_SUBU t2,1 | 84 | REG_SUBU t2,1 |
72 | REG_ADDU t1,4 | 85 | REG_ADDU t1,O32_SZREG |
73 | bnez t2,1b | 86 | bnez t2,1b |
74 | 87 | ||
75 | move sp,s0 | 88 | move sp,fp |
76 | 89 | ||
77 | jalr jp | 90 | jalr jp |
78 | 91 | ||
79 | REG_L sp,O32_FRAMESZ_NEW-1*SZREG(sp) | 92 | REG_L sp,O32_NFRAMESZ-1*SZREG(sp) |
80 | 93 | ||
81 | REG_L s0,O32_FRAMESZ-11*SZREG(sp) | 94 | REG_L s0,O32_FRAMESZ-11*SZREG(sp) |
82 | REG_L s1,O32_FRAMESZ-10*SZREG(sp) | 95 | REG_L s1,O32_FRAMESZ-10*SZREG(sp) |
diff --git a/arch/mips/fw/sni/sniprom.c b/arch/mips/fw/sni/sniprom.c index 2c2cb182af4e..6aa264b9856a 100644 --- a/arch/mips/fw/sni/sniprom.c +++ b/arch/mips/fw/sni/sniprom.c | |||
@@ -40,7 +40,8 @@ | |||
40 | 40 | ||
41 | #ifdef CONFIG_64BIT | 41 | #ifdef CONFIG_64BIT |
42 | 42 | ||
43 | static u8 o32_stk[16384]; | 43 | /* O32 stack has to be 8-byte aligned. */ |
44 | static u64 o32_stk[4096]; | ||
44 | #define O32_STK &o32_stk[sizeof(o32_stk)] | 45 | #define O32_STK &o32_stk[sizeof(o32_stk)] |
45 | 46 | ||
46 | #define __PROM_O32(fun, arg) fun arg __asm__(#fun); \ | 47 | #define __PROM_O32(fun, arg) fun arg __asm__(#fun); \ |
diff --git a/arch/mips/include/asm/dec/prom.h b/arch/mips/include/asm/dec/prom.h index c0ead6313845..b59a2103b61a 100644 --- a/arch/mips/include/asm/dec/prom.h +++ b/arch/mips/include/asm/dec/prom.h | |||
@@ -113,31 +113,31 @@ extern int (*__pmax_close)(int); | |||
113 | #define __DEC_PROM_O32(fun, arg) fun arg __asm__(#fun); \ | 113 | #define __DEC_PROM_O32(fun, arg) fun arg __asm__(#fun); \ |
114 | __asm__(#fun " = call_o32") | 114 | __asm__(#fun " = call_o32") |
115 | 115 | ||
116 | int __DEC_PROM_O32(_rex_bootinit, (int (*)(void))); | 116 | int __DEC_PROM_O32(_rex_bootinit, (int (*)(void), void *)); |
117 | int __DEC_PROM_O32(_rex_bootread, (int (*)(void))); | 117 | int __DEC_PROM_O32(_rex_bootread, (int (*)(void), void *)); |
118 | int __DEC_PROM_O32(_rex_getbitmap, (int (*)(memmap *), memmap *)); | 118 | int __DEC_PROM_O32(_rex_getbitmap, (int (*)(memmap *), void *, memmap *)); |
119 | unsigned long *__DEC_PROM_O32(_rex_slot_address, | 119 | unsigned long *__DEC_PROM_O32(_rex_slot_address, |
120 | (unsigned long *(*)(int), int)); | 120 | (unsigned long *(*)(int), void *, int)); |
121 | void *__DEC_PROM_O32(_rex_gettcinfo, (void *(*)(void))); | 121 | void *__DEC_PROM_O32(_rex_gettcinfo, (void *(*)(void), void *)); |
122 | int __DEC_PROM_O32(_rex_getsysid, (int (*)(void))); | 122 | int __DEC_PROM_O32(_rex_getsysid, (int (*)(void), void *)); |
123 | void __DEC_PROM_O32(_rex_clear_cache, (void (*)(void))); | 123 | void __DEC_PROM_O32(_rex_clear_cache, (void (*)(void), void *)); |
124 | 124 | ||
125 | int __DEC_PROM_O32(_prom_getchar, (int (*)(void))); | 125 | int __DEC_PROM_O32(_prom_getchar, (int (*)(void), void *)); |
126 | char *__DEC_PROM_O32(_prom_getenv, (char *(*)(char *), char *)); | 126 | char *__DEC_PROM_O32(_prom_getenv, (char *(*)(char *), void *, char *)); |
127 | int __DEC_PROM_O32(_prom_printf, (int (*)(char *, ...), char *, ...)); | 127 | int __DEC_PROM_O32(_prom_printf, (int (*)(char *, ...), void *, char *, ...)); |
128 | 128 | ||
129 | 129 | ||
130 | #define rex_bootinit() _rex_bootinit(__rex_bootinit) | 130 | #define rex_bootinit() _rex_bootinit(__rex_bootinit, NULL) |
131 | #define rex_bootread() _rex_bootread(__rex_bootread) | 131 | #define rex_bootread() _rex_bootread(__rex_bootread, NULL) |
132 | #define rex_getbitmap(x) _rex_getbitmap(__rex_getbitmap, x) | 132 | #define rex_getbitmap(x) _rex_getbitmap(__rex_getbitmap, NULL, x) |
133 | #define rex_slot_address(x) _rex_slot_address(__rex_slot_address, x) | 133 | #define rex_slot_address(x) _rex_slot_address(__rex_slot_address, NULL, x) |
134 | #define rex_gettcinfo() _rex_gettcinfo(__rex_gettcinfo) | 134 | #define rex_gettcinfo() _rex_gettcinfo(__rex_gettcinfo, NULL) |
135 | #define rex_getsysid() _rex_getsysid(__rex_getsysid) | 135 | #define rex_getsysid() _rex_getsysid(__rex_getsysid, NULL) |
136 | #define rex_clear_cache() _rex_clear_cache(__rex_clear_cache) | 136 | #define rex_clear_cache() _rex_clear_cache(__rex_clear_cache, NULL) |
137 | 137 | ||
138 | #define prom_getchar() _prom_getchar(__prom_getchar) | 138 | #define prom_getchar() _prom_getchar(__prom_getchar, NULL) |
139 | #define prom_getenv(x) _prom_getenv(__prom_getenv, x) | 139 | #define prom_getenv(x) _prom_getenv(__prom_getenv, NULL, x) |
140 | #define prom_printf(x...) _prom_printf(__prom_printf, x) | 140 | #define prom_printf(x...) _prom_printf(__prom_printf, NULL, x) |
141 | 141 | ||
142 | #else /* !CONFIG_64BIT */ | 142 | #else /* !CONFIG_64BIT */ |
143 | 143 | ||
diff --git a/arch/mips/include/asm/rm9k-ocd.h b/arch/mips/include/asm/rm9k-ocd.h deleted file mode 100644 index b0b80d9ecf96..000000000000 --- a/arch/mips/include/asm/rm9k-ocd.h +++ /dev/null | |||
@@ -1,56 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 by Basler Vision Technologies AG | ||
3 | * Author: Thomas Koeller <thomas.koeller@baslerweb.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #if !defined(_ASM_RM9K_OCD_H) | ||
21 | #define _ASM_RM9K_OCD_H | ||
22 | |||
23 | #include <linux/types.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <asm/io.h> | ||
26 | |||
27 | extern volatile void __iomem * const ocd_base; | ||
28 | extern volatile void __iomem * const titan_base; | ||
29 | |||
30 | #define ocd_addr(__x__) (ocd_base + (__x__)) | ||
31 | #define titan_addr(__x__) (titan_base + (__x__)) | ||
32 | #define scram_addr(__x__) (scram_base + (__x__)) | ||
33 | |||
34 | /* OCD register access */ | ||
35 | #define ocd_readl(__offs__) __raw_readl(ocd_addr(__offs__)) | ||
36 | #define ocd_readw(__offs__) __raw_readw(ocd_addr(__offs__)) | ||
37 | #define ocd_readb(__offs__) __raw_readb(ocd_addr(__offs__)) | ||
38 | #define ocd_writel(__val__, __offs__) \ | ||
39 | __raw_writel((__val__), ocd_addr(__offs__)) | ||
40 | #define ocd_writew(__val__, __offs__) \ | ||
41 | __raw_writew((__val__), ocd_addr(__offs__)) | ||
42 | #define ocd_writeb(__val__, __offs__) \ | ||
43 | __raw_writeb((__val__), ocd_addr(__offs__)) | ||
44 | |||
45 | /* TITAN register access - 32 bit-wide only */ | ||
46 | #define titan_readl(__offs__) __raw_readl(titan_addr(__offs__)) | ||
47 | #define titan_writel(__val__, __offs__) \ | ||
48 | __raw_writel((__val__), titan_addr(__offs__)) | ||
49 | |||
50 | /* Protect access to shared TITAN registers */ | ||
51 | extern spinlock_t titan_lock; | ||
52 | extern int titan_irqflags; | ||
53 | #define lock_titan_regs() spin_lock_irqsave(&titan_lock, titan_irqflags) | ||
54 | #define unlock_titan_regs() spin_unlock_irqrestore(&titan_lock, titan_irqflags) | ||
55 | |||
56 | #endif /* !defined(_ASM_RM9K_OCD_H) */ | ||
diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h index c6e9cd2bca8d..17960fe7a8ce 100644 --- a/arch/mips/include/asm/syscall.h +++ b/arch/mips/include/asm/syscall.h | |||
@@ -133,6 +133,8 @@ static inline int syscall_get_arch(void) | |||
133 | #ifdef CONFIG_64BIT | 133 | #ifdef CONFIG_64BIT |
134 | if (!test_thread_flag(TIF_32BIT_REGS)) | 134 | if (!test_thread_flag(TIF_32BIT_REGS)) |
135 | arch |= __AUDIT_ARCH_64BIT; | 135 | arch |= __AUDIT_ARCH_64BIT; |
136 | if (test_thread_flag(TIF_32BIT_ADDR)) | ||
137 | arch |= __AUDIT_ARCH_CONVENTION_MIPS64_N32; | ||
136 | #endif | 138 | #endif |
137 | #if defined(__LITTLE_ENDIAN) | 139 | #if defined(__LITTLE_ENDIAN) |
138 | arch |= __AUDIT_ARCH_LE; | 140 | arch |= __AUDIT_ARCH_LE; |
diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h index df6e775f3fef..3125797f2a88 100644 --- a/arch/mips/include/uapi/asm/inst.h +++ b/arch/mips/include/uapi/asm/inst.h | |||
@@ -484,13 +484,13 @@ enum MIPS6e_i8_func { | |||
484 | * Damn ... bitfields depend from byteorder :-( | 484 | * Damn ... bitfields depend from byteorder :-( |
485 | */ | 485 | */ |
486 | #ifdef __MIPSEB__ | 486 | #ifdef __MIPSEB__ |
487 | #define BITFIELD_FIELD(field, more) \ | 487 | #define __BITFIELD_FIELD(field, more) \ |
488 | field; \ | 488 | field; \ |
489 | more | 489 | more |
490 | 490 | ||
491 | #elif defined(__MIPSEL__) | 491 | #elif defined(__MIPSEL__) |
492 | 492 | ||
493 | #define BITFIELD_FIELD(field, more) \ | 493 | #define __BITFIELD_FIELD(field, more) \ |
494 | more \ | 494 | more \ |
495 | field; | 495 | field; |
496 | 496 | ||
@@ -499,112 +499,112 @@ enum MIPS6e_i8_func { | |||
499 | #endif | 499 | #endif |
500 | 500 | ||
501 | struct j_format { | 501 | struct j_format { |
502 | BITFIELD_FIELD(unsigned int opcode : 6, /* Jump format */ | 502 | __BITFIELD_FIELD(unsigned int opcode : 6, /* Jump format */ |
503 | BITFIELD_FIELD(unsigned int target : 26, | 503 | __BITFIELD_FIELD(unsigned int target : 26, |
504 | ;)) | 504 | ;)) |
505 | }; | 505 | }; |
506 | 506 | ||
507 | struct i_format { /* signed immediate format */ | 507 | struct i_format { /* signed immediate format */ |
508 | BITFIELD_FIELD(unsigned int opcode : 6, | 508 | __BITFIELD_FIELD(unsigned int opcode : 6, |
509 | BITFIELD_FIELD(unsigned int rs : 5, | 509 | __BITFIELD_FIELD(unsigned int rs : 5, |
510 | BITFIELD_FIELD(unsigned int rt : 5, | 510 | __BITFIELD_FIELD(unsigned int rt : 5, |
511 | BITFIELD_FIELD(signed int simmediate : 16, | 511 | __BITFIELD_FIELD(signed int simmediate : 16, |
512 | ;)))) | 512 | ;)))) |
513 | }; | 513 | }; |
514 | 514 | ||
515 | struct u_format { /* unsigned immediate format */ | 515 | struct u_format { /* unsigned immediate format */ |
516 | BITFIELD_FIELD(unsigned int opcode : 6, | 516 | __BITFIELD_FIELD(unsigned int opcode : 6, |
517 | BITFIELD_FIELD(unsigned int rs : 5, | 517 | __BITFIELD_FIELD(unsigned int rs : 5, |
518 | BITFIELD_FIELD(unsigned int rt : 5, | 518 | __BITFIELD_FIELD(unsigned int rt : 5, |
519 | BITFIELD_FIELD(unsigned int uimmediate : 16, | 519 | __BITFIELD_FIELD(unsigned int uimmediate : 16, |
520 | ;)))) | 520 | ;)))) |
521 | }; | 521 | }; |
522 | 522 | ||
523 | struct c_format { /* Cache (>= R6000) format */ | 523 | struct c_format { /* Cache (>= R6000) format */ |
524 | BITFIELD_FIELD(unsigned int opcode : 6, | 524 | __BITFIELD_FIELD(unsigned int opcode : 6, |
525 | BITFIELD_FIELD(unsigned int rs : 5, | 525 | __BITFIELD_FIELD(unsigned int rs : 5, |
526 | BITFIELD_FIELD(unsigned int c_op : 3, | 526 | __BITFIELD_FIELD(unsigned int c_op : 3, |
527 | BITFIELD_FIELD(unsigned int cache : 2, | 527 | __BITFIELD_FIELD(unsigned int cache : 2, |
528 | BITFIELD_FIELD(unsigned int simmediate : 16, | 528 | __BITFIELD_FIELD(unsigned int simmediate : 16, |
529 | ;))))) | 529 | ;))))) |
530 | }; | 530 | }; |
531 | 531 | ||
532 | struct r_format { /* Register format */ | 532 | struct r_format { /* Register format */ |
533 | BITFIELD_FIELD(unsigned int opcode : 6, | 533 | __BITFIELD_FIELD(unsigned int opcode : 6, |
534 | BITFIELD_FIELD(unsigned int rs : 5, | 534 | __BITFIELD_FIELD(unsigned int rs : 5, |
535 | BITFIELD_FIELD(unsigned int rt : 5, | 535 | __BITFIELD_FIELD(unsigned int rt : 5, |
536 | BITFIELD_FIELD(unsigned int rd : 5, | 536 | __BITFIELD_FIELD(unsigned int rd : 5, |
537 | BITFIELD_FIELD(unsigned int re : 5, | 537 | __BITFIELD_FIELD(unsigned int re : 5, |
538 | BITFIELD_FIELD(unsigned int func : 6, | 538 | __BITFIELD_FIELD(unsigned int func : 6, |
539 | ;)))))) | 539 | ;)))))) |
540 | }; | 540 | }; |
541 | 541 | ||
542 | struct p_format { /* Performance counter format (R10000) */ | 542 | struct p_format { /* Performance counter format (R10000) */ |
543 | BITFIELD_FIELD(unsigned int opcode : 6, | 543 | __BITFIELD_FIELD(unsigned int opcode : 6, |
544 | BITFIELD_FIELD(unsigned int rs : 5, | 544 | __BITFIELD_FIELD(unsigned int rs : 5, |
545 | BITFIELD_FIELD(unsigned int rt : 5, | 545 | __BITFIELD_FIELD(unsigned int rt : 5, |
546 | BITFIELD_FIELD(unsigned int rd : 5, | 546 | __BITFIELD_FIELD(unsigned int rd : 5, |
547 | BITFIELD_FIELD(unsigned int re : 5, | 547 | __BITFIELD_FIELD(unsigned int re : 5, |
548 | BITFIELD_FIELD(unsigned int func : 6, | 548 | __BITFIELD_FIELD(unsigned int func : 6, |
549 | ;)))))) | 549 | ;)))))) |
550 | }; | 550 | }; |
551 | 551 | ||
552 | struct f_format { /* FPU register format */ | 552 | struct f_format { /* FPU register format */ |
553 | BITFIELD_FIELD(unsigned int opcode : 6, | 553 | __BITFIELD_FIELD(unsigned int opcode : 6, |
554 | BITFIELD_FIELD(unsigned int : 1, | 554 | __BITFIELD_FIELD(unsigned int : 1, |
555 | BITFIELD_FIELD(unsigned int fmt : 4, | 555 | __BITFIELD_FIELD(unsigned int fmt : 4, |
556 | BITFIELD_FIELD(unsigned int rt : 5, | 556 | __BITFIELD_FIELD(unsigned int rt : 5, |
557 | BITFIELD_FIELD(unsigned int rd : 5, | 557 | __BITFIELD_FIELD(unsigned int rd : 5, |
558 | BITFIELD_FIELD(unsigned int re : 5, | 558 | __BITFIELD_FIELD(unsigned int re : 5, |
559 | BITFIELD_FIELD(unsigned int func : 6, | 559 | __BITFIELD_FIELD(unsigned int func : 6, |
560 | ;))))))) | 560 | ;))))))) |
561 | }; | 561 | }; |
562 | 562 | ||
563 | struct ma_format { /* FPU multiply and add format (MIPS IV) */ | 563 | struct ma_format { /* FPU multiply and add format (MIPS IV) */ |
564 | BITFIELD_FIELD(unsigned int opcode : 6, | 564 | __BITFIELD_FIELD(unsigned int opcode : 6, |
565 | BITFIELD_FIELD(unsigned int fr : 5, | 565 | __BITFIELD_FIELD(unsigned int fr : 5, |
566 | BITFIELD_FIELD(unsigned int ft : 5, | 566 | __BITFIELD_FIELD(unsigned int ft : 5, |
567 | BITFIELD_FIELD(unsigned int fs : 5, | 567 | __BITFIELD_FIELD(unsigned int fs : 5, |
568 | BITFIELD_FIELD(unsigned int fd : 5, | 568 | __BITFIELD_FIELD(unsigned int fd : 5, |
569 | BITFIELD_FIELD(unsigned int func : 4, | 569 | __BITFIELD_FIELD(unsigned int func : 4, |
570 | BITFIELD_FIELD(unsigned int fmt : 2, | 570 | __BITFIELD_FIELD(unsigned int fmt : 2, |
571 | ;))))))) | 571 | ;))))))) |
572 | }; | 572 | }; |
573 | 573 | ||
574 | struct b_format { /* BREAK and SYSCALL */ | 574 | struct b_format { /* BREAK and SYSCALL */ |
575 | BITFIELD_FIELD(unsigned int opcode : 6, | 575 | __BITFIELD_FIELD(unsigned int opcode : 6, |
576 | BITFIELD_FIELD(unsigned int code : 20, | 576 | __BITFIELD_FIELD(unsigned int code : 20, |
577 | BITFIELD_FIELD(unsigned int func : 6, | 577 | __BITFIELD_FIELD(unsigned int func : 6, |
578 | ;))) | 578 | ;))) |
579 | }; | 579 | }; |
580 | 580 | ||
581 | struct ps_format { /* MIPS-3D / paired single format */ | 581 | struct ps_format { /* MIPS-3D / paired single format */ |
582 | BITFIELD_FIELD(unsigned int opcode : 6, | 582 | __BITFIELD_FIELD(unsigned int opcode : 6, |
583 | BITFIELD_FIELD(unsigned int rs : 5, | 583 | __BITFIELD_FIELD(unsigned int rs : 5, |
584 | BITFIELD_FIELD(unsigned int ft : 5, | 584 | __BITFIELD_FIELD(unsigned int ft : 5, |
585 | BITFIELD_FIELD(unsigned int fs : 5, | 585 | __BITFIELD_FIELD(unsigned int fs : 5, |
586 | BITFIELD_FIELD(unsigned int fd : 5, | 586 | __BITFIELD_FIELD(unsigned int fd : 5, |
587 | BITFIELD_FIELD(unsigned int func : 6, | 587 | __BITFIELD_FIELD(unsigned int func : 6, |
588 | ;)))))) | 588 | ;)))))) |
589 | }; | 589 | }; |
590 | 590 | ||
591 | struct v_format { /* MDMX vector format */ | 591 | struct v_format { /* MDMX vector format */ |
592 | BITFIELD_FIELD(unsigned int opcode : 6, | 592 | __BITFIELD_FIELD(unsigned int opcode : 6, |
593 | BITFIELD_FIELD(unsigned int sel : 4, | 593 | __BITFIELD_FIELD(unsigned int sel : 4, |
594 | BITFIELD_FIELD(unsigned int fmt : 1, | 594 | __BITFIELD_FIELD(unsigned int fmt : 1, |
595 | BITFIELD_FIELD(unsigned int vt : 5, | 595 | __BITFIELD_FIELD(unsigned int vt : 5, |
596 | BITFIELD_FIELD(unsigned int vs : 5, | 596 | __BITFIELD_FIELD(unsigned int vs : 5, |
597 | BITFIELD_FIELD(unsigned int vd : 5, | 597 | __BITFIELD_FIELD(unsigned int vd : 5, |
598 | BITFIELD_FIELD(unsigned int func : 6, | 598 | __BITFIELD_FIELD(unsigned int func : 6, |
599 | ;))))))) | 599 | ;))))))) |
600 | }; | 600 | }; |
601 | 601 | ||
602 | struct spec3_format { /* SPEC3 */ | 602 | struct spec3_format { /* SPEC3 */ |
603 | BITFIELD_FIELD(unsigned int opcode:6, | 603 | __BITFIELD_FIELD(unsigned int opcode:6, |
604 | BITFIELD_FIELD(unsigned int rs:5, | 604 | __BITFIELD_FIELD(unsigned int rs:5, |
605 | BITFIELD_FIELD(unsigned int rt:5, | 605 | __BITFIELD_FIELD(unsigned int rt:5, |
606 | BITFIELD_FIELD(signed int simmediate:9, | 606 | __BITFIELD_FIELD(signed int simmediate:9, |
607 | BITFIELD_FIELD(unsigned int func:7, | 607 | __BITFIELD_FIELD(unsigned int func:7, |
608 | ;))))) | 608 | ;))))) |
609 | }; | 609 | }; |
610 | 610 | ||
@@ -616,141 +616,141 @@ struct spec3_format { /* SPEC3 */ | |||
616 | * if it is MIPS32 instruction re-encoded for use in the microMIPS ASE. | 616 | * if it is MIPS32 instruction re-encoded for use in the microMIPS ASE. |
617 | */ | 617 | */ |
618 | struct fb_format { /* FPU branch format (MIPS32) */ | 618 | struct fb_format { /* FPU branch format (MIPS32) */ |
619 | BITFIELD_FIELD(unsigned int opcode : 6, | 619 | __BITFIELD_FIELD(unsigned int opcode : 6, |
620 | BITFIELD_FIELD(unsigned int bc : 5, | 620 | __BITFIELD_FIELD(unsigned int bc : 5, |
621 | BITFIELD_FIELD(unsigned int cc : 3, | 621 | __BITFIELD_FIELD(unsigned int cc : 3, |
622 | BITFIELD_FIELD(unsigned int flag : 2, | 622 | __BITFIELD_FIELD(unsigned int flag : 2, |
623 | BITFIELD_FIELD(signed int simmediate : 16, | 623 | __BITFIELD_FIELD(signed int simmediate : 16, |
624 | ;))))) | 624 | ;))))) |
625 | }; | 625 | }; |
626 | 626 | ||
627 | struct fp0_format { /* FPU multiply and add format (MIPS32) */ | 627 | struct fp0_format { /* FPU multiply and add format (MIPS32) */ |
628 | BITFIELD_FIELD(unsigned int opcode : 6, | 628 | __BITFIELD_FIELD(unsigned int opcode : 6, |
629 | BITFIELD_FIELD(unsigned int fmt : 5, | 629 | __BITFIELD_FIELD(unsigned int fmt : 5, |
630 | BITFIELD_FIELD(unsigned int ft : 5, | 630 | __BITFIELD_FIELD(unsigned int ft : 5, |
631 | BITFIELD_FIELD(unsigned int fs : 5, | 631 | __BITFIELD_FIELD(unsigned int fs : 5, |
632 | BITFIELD_FIELD(unsigned int fd : 5, | 632 | __BITFIELD_FIELD(unsigned int fd : 5, |
633 | BITFIELD_FIELD(unsigned int func : 6, | 633 | __BITFIELD_FIELD(unsigned int func : 6, |
634 | ;)))))) | 634 | ;)))))) |
635 | }; | 635 | }; |
636 | 636 | ||
637 | struct mm_fp0_format { /* FPU multipy and add format (microMIPS) */ | 637 | struct mm_fp0_format { /* FPU multipy and add format (microMIPS) */ |
638 | BITFIELD_FIELD(unsigned int opcode : 6, | 638 | __BITFIELD_FIELD(unsigned int opcode : 6, |
639 | BITFIELD_FIELD(unsigned int ft : 5, | 639 | __BITFIELD_FIELD(unsigned int ft : 5, |
640 | BITFIELD_FIELD(unsigned int fs : 5, | 640 | __BITFIELD_FIELD(unsigned int fs : 5, |
641 | BITFIELD_FIELD(unsigned int fd : 5, | 641 | __BITFIELD_FIELD(unsigned int fd : 5, |
642 | BITFIELD_FIELD(unsigned int fmt : 3, | 642 | __BITFIELD_FIELD(unsigned int fmt : 3, |
643 | BITFIELD_FIELD(unsigned int op : 2, | 643 | __BITFIELD_FIELD(unsigned int op : 2, |
644 | BITFIELD_FIELD(unsigned int func : 6, | 644 | __BITFIELD_FIELD(unsigned int func : 6, |
645 | ;))))))) | 645 | ;))))))) |
646 | }; | 646 | }; |
647 | 647 | ||
648 | struct fp1_format { /* FPU mfc1 and cfc1 format (MIPS32) */ | 648 | struct fp1_format { /* FPU mfc1 and cfc1 format (MIPS32) */ |
649 | BITFIELD_FIELD(unsigned int opcode : 6, | 649 | __BITFIELD_FIELD(unsigned int opcode : 6, |
650 | BITFIELD_FIELD(unsigned int op : 5, | 650 | __BITFIELD_FIELD(unsigned int op : 5, |
651 | BITFIELD_FIELD(unsigned int rt : 5, | 651 | __BITFIELD_FIELD(unsigned int rt : 5, |
652 | BITFIELD_FIELD(unsigned int fs : 5, | 652 | __BITFIELD_FIELD(unsigned int fs : 5, |
653 | BITFIELD_FIELD(unsigned int fd : 5, | 653 | __BITFIELD_FIELD(unsigned int fd : 5, |
654 | BITFIELD_FIELD(unsigned int func : 6, | 654 | __BITFIELD_FIELD(unsigned int func : 6, |
655 | ;)))))) | 655 | ;)))))) |
656 | }; | 656 | }; |
657 | 657 | ||
658 | struct mm_fp1_format { /* FPU mfc1 and cfc1 format (microMIPS) */ | 658 | struct mm_fp1_format { /* FPU mfc1 and cfc1 format (microMIPS) */ |
659 | BITFIELD_FIELD(unsigned int opcode : 6, | 659 | __BITFIELD_FIELD(unsigned int opcode : 6, |
660 | BITFIELD_FIELD(unsigned int rt : 5, | 660 | __BITFIELD_FIELD(unsigned int rt : 5, |
661 | BITFIELD_FIELD(unsigned int fs : 5, | 661 | __BITFIELD_FIELD(unsigned int fs : 5, |
662 | BITFIELD_FIELD(unsigned int fmt : 2, | 662 | __BITFIELD_FIELD(unsigned int fmt : 2, |
663 | BITFIELD_FIELD(unsigned int op : 8, | 663 | __BITFIELD_FIELD(unsigned int op : 8, |
664 | BITFIELD_FIELD(unsigned int func : 6, | 664 | __BITFIELD_FIELD(unsigned int func : 6, |
665 | ;)))))) | 665 | ;)))))) |
666 | }; | 666 | }; |
667 | 667 | ||
668 | struct mm_fp2_format { /* FPU movt and movf format (microMIPS) */ | 668 | struct mm_fp2_format { /* FPU movt and movf format (microMIPS) */ |
669 | BITFIELD_FIELD(unsigned int opcode : 6, | 669 | __BITFIELD_FIELD(unsigned int opcode : 6, |
670 | BITFIELD_FIELD(unsigned int fd : 5, | 670 | __BITFIELD_FIELD(unsigned int fd : 5, |
671 | BITFIELD_FIELD(unsigned int fs : 5, | 671 | __BITFIELD_FIELD(unsigned int fs : 5, |
672 | BITFIELD_FIELD(unsigned int cc : 3, | 672 | __BITFIELD_FIELD(unsigned int cc : 3, |
673 | BITFIELD_FIELD(unsigned int zero : 2, | 673 | __BITFIELD_FIELD(unsigned int zero : 2, |
674 | BITFIELD_FIELD(unsigned int fmt : 2, | 674 | __BITFIELD_FIELD(unsigned int fmt : 2, |
675 | BITFIELD_FIELD(unsigned int op : 3, | 675 | __BITFIELD_FIELD(unsigned int op : 3, |
676 | BITFIELD_FIELD(unsigned int func : 6, | 676 | __BITFIELD_FIELD(unsigned int func : 6, |
677 | ;)))))))) | 677 | ;)))))))) |
678 | }; | 678 | }; |
679 | 679 | ||
680 | struct mm_fp3_format { /* FPU abs and neg format (microMIPS) */ | 680 | struct mm_fp3_format { /* FPU abs and neg format (microMIPS) */ |
681 | BITFIELD_FIELD(unsigned int opcode : 6, | 681 | __BITFIELD_FIELD(unsigned int opcode : 6, |
682 | BITFIELD_FIELD(unsigned int rt : 5, | 682 | __BITFIELD_FIELD(unsigned int rt : 5, |
683 | BITFIELD_FIELD(unsigned int fs : 5, | 683 | __BITFIELD_FIELD(unsigned int fs : 5, |
684 | BITFIELD_FIELD(unsigned int fmt : 3, | 684 | __BITFIELD_FIELD(unsigned int fmt : 3, |
685 | BITFIELD_FIELD(unsigned int op : 7, | 685 | __BITFIELD_FIELD(unsigned int op : 7, |
686 | BITFIELD_FIELD(unsigned int func : 6, | 686 | __BITFIELD_FIELD(unsigned int func : 6, |
687 | ;)))))) | 687 | ;)))))) |
688 | }; | 688 | }; |
689 | 689 | ||
690 | struct mm_fp4_format { /* FPU c.cond format (microMIPS) */ | 690 | struct mm_fp4_format { /* FPU c.cond format (microMIPS) */ |
691 | BITFIELD_FIELD(unsigned int opcode : 6, | 691 | __BITFIELD_FIELD(unsigned int opcode : 6, |
692 | BITFIELD_FIELD(unsigned int rt : 5, | 692 | __BITFIELD_FIELD(unsigned int rt : 5, |
693 | BITFIELD_FIELD(unsigned int fs : 5, | 693 | __BITFIELD_FIELD(unsigned int fs : 5, |
694 | BITFIELD_FIELD(unsigned int cc : 3, | 694 | __BITFIELD_FIELD(unsigned int cc : 3, |
695 | BITFIELD_FIELD(unsigned int fmt : 3, | 695 | __BITFIELD_FIELD(unsigned int fmt : 3, |
696 | BITFIELD_FIELD(unsigned int cond : 4, | 696 | __BITFIELD_FIELD(unsigned int cond : 4, |
697 | BITFIELD_FIELD(unsigned int func : 6, | 697 | __BITFIELD_FIELD(unsigned int func : 6, |
698 | ;))))))) | 698 | ;))))))) |
699 | }; | 699 | }; |
700 | 700 | ||
701 | struct mm_fp5_format { /* FPU lwxc1 and swxc1 format (microMIPS) */ | 701 | struct mm_fp5_format { /* FPU lwxc1 and swxc1 format (microMIPS) */ |
702 | BITFIELD_FIELD(unsigned int opcode : 6, | 702 | __BITFIELD_FIELD(unsigned int opcode : 6, |
703 | BITFIELD_FIELD(unsigned int index : 5, | 703 | __BITFIELD_FIELD(unsigned int index : 5, |
704 | BITFIELD_FIELD(unsigned int base : 5, | 704 | __BITFIELD_FIELD(unsigned int base : 5, |
705 | BITFIELD_FIELD(unsigned int fd : 5, | 705 | __BITFIELD_FIELD(unsigned int fd : 5, |
706 | BITFIELD_FIELD(unsigned int op : 5, | 706 | __BITFIELD_FIELD(unsigned int op : 5, |
707 | BITFIELD_FIELD(unsigned int func : 6, | 707 | __BITFIELD_FIELD(unsigned int func : 6, |
708 | ;)))))) | 708 | ;)))))) |
709 | }; | 709 | }; |
710 | 710 | ||
711 | struct fp6_format { /* FPU madd and msub format (MIPS IV) */ | 711 | struct fp6_format { /* FPU madd and msub format (MIPS IV) */ |
712 | BITFIELD_FIELD(unsigned int opcode : 6, | 712 | __BITFIELD_FIELD(unsigned int opcode : 6, |
713 | BITFIELD_FIELD(unsigned int fr : 5, | 713 | __BITFIELD_FIELD(unsigned int fr : 5, |
714 | BITFIELD_FIELD(unsigned int ft : 5, | 714 | __BITFIELD_FIELD(unsigned int ft : 5, |
715 | BITFIELD_FIELD(unsigned int fs : 5, | 715 | __BITFIELD_FIELD(unsigned int fs : 5, |
716 | BITFIELD_FIELD(unsigned int fd : 5, | 716 | __BITFIELD_FIELD(unsigned int fd : 5, |
717 | BITFIELD_FIELD(unsigned int func : 6, | 717 | __BITFIELD_FIELD(unsigned int func : 6, |
718 | ;)))))) | 718 | ;)))))) |
719 | }; | 719 | }; |
720 | 720 | ||
721 | struct mm_fp6_format { /* FPU madd and msub format (microMIPS) */ | 721 | struct mm_fp6_format { /* FPU madd and msub format (microMIPS) */ |
722 | BITFIELD_FIELD(unsigned int opcode : 6, | 722 | __BITFIELD_FIELD(unsigned int opcode : 6, |
723 | BITFIELD_FIELD(unsigned int ft : 5, | 723 | __BITFIELD_FIELD(unsigned int ft : 5, |
724 | BITFIELD_FIELD(unsigned int fs : 5, | 724 | __BITFIELD_FIELD(unsigned int fs : 5, |
725 | BITFIELD_FIELD(unsigned int fd : 5, | 725 | __BITFIELD_FIELD(unsigned int fd : 5, |
726 | BITFIELD_FIELD(unsigned int fr : 5, | 726 | __BITFIELD_FIELD(unsigned int fr : 5, |
727 | BITFIELD_FIELD(unsigned int func : 6, | 727 | __BITFIELD_FIELD(unsigned int func : 6, |
728 | ;)))))) | 728 | ;)))))) |
729 | }; | 729 | }; |
730 | 730 | ||
731 | struct mm_i_format { /* Immediate format (microMIPS) */ | 731 | struct mm_i_format { /* Immediate format (microMIPS) */ |
732 | BITFIELD_FIELD(unsigned int opcode : 6, | 732 | __BITFIELD_FIELD(unsigned int opcode : 6, |
733 | BITFIELD_FIELD(unsigned int rt : 5, | 733 | __BITFIELD_FIELD(unsigned int rt : 5, |
734 | BITFIELD_FIELD(unsigned int rs : 5, | 734 | __BITFIELD_FIELD(unsigned int rs : 5, |
735 | BITFIELD_FIELD(signed int simmediate : 16, | 735 | __BITFIELD_FIELD(signed int simmediate : 16, |
736 | ;)))) | 736 | ;)))) |
737 | }; | 737 | }; |
738 | 738 | ||
739 | struct mm_m_format { /* Multi-word load/store format (microMIPS) */ | 739 | struct mm_m_format { /* Multi-word load/store format (microMIPS) */ |
740 | BITFIELD_FIELD(unsigned int opcode : 6, | 740 | __BITFIELD_FIELD(unsigned int opcode : 6, |
741 | BITFIELD_FIELD(unsigned int rd : 5, | 741 | __BITFIELD_FIELD(unsigned int rd : 5, |
742 | BITFIELD_FIELD(unsigned int base : 5, | 742 | __BITFIELD_FIELD(unsigned int base : 5, |
743 | BITFIELD_FIELD(unsigned int func : 4, | 743 | __BITFIELD_FIELD(unsigned int func : 4, |
744 | BITFIELD_FIELD(signed int simmediate : 12, | 744 | __BITFIELD_FIELD(signed int simmediate : 12, |
745 | ;))))) | 745 | ;))))) |
746 | }; | 746 | }; |
747 | 747 | ||
748 | struct mm_x_format { /* Scaled indexed load format (microMIPS) */ | 748 | struct mm_x_format { /* Scaled indexed load format (microMIPS) */ |
749 | BITFIELD_FIELD(unsigned int opcode : 6, | 749 | __BITFIELD_FIELD(unsigned int opcode : 6, |
750 | BITFIELD_FIELD(unsigned int index : 5, | 750 | __BITFIELD_FIELD(unsigned int index : 5, |
751 | BITFIELD_FIELD(unsigned int base : 5, | 751 | __BITFIELD_FIELD(unsigned int base : 5, |
752 | BITFIELD_FIELD(unsigned int rd : 5, | 752 | __BITFIELD_FIELD(unsigned int rd : 5, |
753 | BITFIELD_FIELD(unsigned int func : 11, | 753 | __BITFIELD_FIELD(unsigned int func : 11, |
754 | ;))))) | 754 | ;))))) |
755 | }; | 755 | }; |
756 | 756 | ||
@@ -758,51 +758,51 @@ struct mm_x_format { /* Scaled indexed load format (microMIPS) */ | |||
758 | * microMIPS instruction formats (16-bit length) | 758 | * microMIPS instruction formats (16-bit length) |
759 | */ | 759 | */ |
760 | struct mm_b0_format { /* Unconditional branch format (microMIPS) */ | 760 | struct mm_b0_format { /* Unconditional branch format (microMIPS) */ |
761 | BITFIELD_FIELD(unsigned int opcode : 6, | 761 | __BITFIELD_FIELD(unsigned int opcode : 6, |
762 | BITFIELD_FIELD(signed int simmediate : 10, | 762 | __BITFIELD_FIELD(signed int simmediate : 10, |
763 | BITFIELD_FIELD(unsigned int : 16, /* Ignored */ | 763 | __BITFIELD_FIELD(unsigned int : 16, /* Ignored */ |
764 | ;))) | 764 | ;))) |
765 | }; | 765 | }; |
766 | 766 | ||
767 | struct mm_b1_format { /* Conditional branch format (microMIPS) */ | 767 | struct mm_b1_format { /* Conditional branch format (microMIPS) */ |
768 | BITFIELD_FIELD(unsigned int opcode : 6, | 768 | __BITFIELD_FIELD(unsigned int opcode : 6, |
769 | BITFIELD_FIELD(unsigned int rs : 3, | 769 | __BITFIELD_FIELD(unsigned int rs : 3, |
770 | BITFIELD_FIELD(signed int simmediate : 7, | 770 | __BITFIELD_FIELD(signed int simmediate : 7, |
771 | BITFIELD_FIELD(unsigned int : 16, /* Ignored */ | 771 | __BITFIELD_FIELD(unsigned int : 16, /* Ignored */ |
772 | ;)))) | 772 | ;)))) |
773 | }; | 773 | }; |
774 | 774 | ||
775 | struct mm16_m_format { /* Multi-word load/store format */ | 775 | struct mm16_m_format { /* Multi-word load/store format */ |
776 | BITFIELD_FIELD(unsigned int opcode : 6, | 776 | __BITFIELD_FIELD(unsigned int opcode : 6, |
777 | BITFIELD_FIELD(unsigned int func : 4, | 777 | __BITFIELD_FIELD(unsigned int func : 4, |
778 | BITFIELD_FIELD(unsigned int rlist : 2, | 778 | __BITFIELD_FIELD(unsigned int rlist : 2, |
779 | BITFIELD_FIELD(unsigned int imm : 4, | 779 | __BITFIELD_FIELD(unsigned int imm : 4, |
780 | BITFIELD_FIELD(unsigned int : 16, /* Ignored */ | 780 | __BITFIELD_FIELD(unsigned int : 16, /* Ignored */ |
781 | ;))))) | 781 | ;))))) |
782 | }; | 782 | }; |
783 | 783 | ||
784 | struct mm16_rb_format { /* Signed immediate format */ | 784 | struct mm16_rb_format { /* Signed immediate format */ |
785 | BITFIELD_FIELD(unsigned int opcode : 6, | 785 | __BITFIELD_FIELD(unsigned int opcode : 6, |
786 | BITFIELD_FIELD(unsigned int rt : 3, | 786 | __BITFIELD_FIELD(unsigned int rt : 3, |
787 | BITFIELD_FIELD(unsigned int base : 3, | 787 | __BITFIELD_FIELD(unsigned int base : 3, |
788 | BITFIELD_FIELD(signed int simmediate : 4, | 788 | __BITFIELD_FIELD(signed int simmediate : 4, |
789 | BITFIELD_FIELD(unsigned int : 16, /* Ignored */ | 789 | __BITFIELD_FIELD(unsigned int : 16, /* Ignored */ |
790 | ;))))) | 790 | ;))))) |
791 | }; | 791 | }; |
792 | 792 | ||
793 | struct mm16_r3_format { /* Load from global pointer format */ | 793 | struct mm16_r3_format { /* Load from global pointer format */ |
794 | BITFIELD_FIELD(unsigned int opcode : 6, | 794 | __BITFIELD_FIELD(unsigned int opcode : 6, |
795 | BITFIELD_FIELD(unsigned int rt : 3, | 795 | __BITFIELD_FIELD(unsigned int rt : 3, |
796 | BITFIELD_FIELD(signed int simmediate : 7, | 796 | __BITFIELD_FIELD(signed int simmediate : 7, |
797 | BITFIELD_FIELD(unsigned int : 16, /* Ignored */ | 797 | __BITFIELD_FIELD(unsigned int : 16, /* Ignored */ |
798 | ;)))) | 798 | ;)))) |
799 | }; | 799 | }; |
800 | 800 | ||
801 | struct mm16_r5_format { /* Load/store from stack pointer format */ | 801 | struct mm16_r5_format { /* Load/store from stack pointer format */ |
802 | BITFIELD_FIELD(unsigned int opcode : 6, | 802 | __BITFIELD_FIELD(unsigned int opcode : 6, |
803 | BITFIELD_FIELD(unsigned int rt : 5, | 803 | __BITFIELD_FIELD(unsigned int rt : 5, |
804 | BITFIELD_FIELD(signed int simmediate : 5, | 804 | __BITFIELD_FIELD(signed int simmediate : 5, |
805 | BITFIELD_FIELD(unsigned int : 16, /* Ignored */ | 805 | __BITFIELD_FIELD(unsigned int : 16, /* Ignored */ |
806 | ;)))) | 806 | ;)))) |
807 | }; | 807 | }; |
808 | 808 | ||
@@ -810,57 +810,57 @@ struct mm16_r5_format { /* Load/store from stack pointer format */ | |||
810 | * MIPS16e instruction formats (16-bit length) | 810 | * MIPS16e instruction formats (16-bit length) |
811 | */ | 811 | */ |
812 | struct m16e_rr { | 812 | struct m16e_rr { |
813 | BITFIELD_FIELD(unsigned int opcode : 5, | 813 | __BITFIELD_FIELD(unsigned int opcode : 5, |
814 | BITFIELD_FIELD(unsigned int rx : 3, | 814 | __BITFIELD_FIELD(unsigned int rx : 3, |
815 | BITFIELD_FIELD(unsigned int nd : 1, | 815 | __BITFIELD_FIELD(unsigned int nd : 1, |
816 | BITFIELD_FIELD(unsigned int l : 1, | 816 | __BITFIELD_FIELD(unsigned int l : 1, |
817 | BITFIELD_FIELD(unsigned int ra : 1, | 817 | __BITFIELD_FIELD(unsigned int ra : 1, |
818 | BITFIELD_FIELD(unsigned int func : 5, | 818 | __BITFIELD_FIELD(unsigned int func : 5, |
819 | ;)))))) | 819 | ;)))))) |
820 | }; | 820 | }; |
821 | 821 | ||
822 | struct m16e_jal { | 822 | struct m16e_jal { |
823 | BITFIELD_FIELD(unsigned int opcode : 5, | 823 | __BITFIELD_FIELD(unsigned int opcode : 5, |
824 | BITFIELD_FIELD(unsigned int x : 1, | 824 | __BITFIELD_FIELD(unsigned int x : 1, |
825 | BITFIELD_FIELD(unsigned int imm20_16 : 5, | 825 | __BITFIELD_FIELD(unsigned int imm20_16 : 5, |
826 | BITFIELD_FIELD(signed int imm25_21 : 5, | 826 | __BITFIELD_FIELD(signed int imm25_21 : 5, |
827 | ;)))) | 827 | ;)))) |
828 | }; | 828 | }; |
829 | 829 | ||
830 | struct m16e_i64 { | 830 | struct m16e_i64 { |
831 | BITFIELD_FIELD(unsigned int opcode : 5, | 831 | __BITFIELD_FIELD(unsigned int opcode : 5, |
832 | BITFIELD_FIELD(unsigned int func : 3, | 832 | __BITFIELD_FIELD(unsigned int func : 3, |
833 | BITFIELD_FIELD(unsigned int imm : 8, | 833 | __BITFIELD_FIELD(unsigned int imm : 8, |
834 | ;))) | 834 | ;))) |
835 | }; | 835 | }; |
836 | 836 | ||
837 | struct m16e_ri64 { | 837 | struct m16e_ri64 { |
838 | BITFIELD_FIELD(unsigned int opcode : 5, | 838 | __BITFIELD_FIELD(unsigned int opcode : 5, |
839 | BITFIELD_FIELD(unsigned int func : 3, | 839 | __BITFIELD_FIELD(unsigned int func : 3, |
840 | BITFIELD_FIELD(unsigned int ry : 3, | 840 | __BITFIELD_FIELD(unsigned int ry : 3, |
841 | BITFIELD_FIELD(unsigned int imm : 5, | 841 | __BITFIELD_FIELD(unsigned int imm : 5, |
842 | ;)))) | 842 | ;)))) |
843 | }; | 843 | }; |
844 | 844 | ||
845 | struct m16e_ri { | 845 | struct m16e_ri { |
846 | BITFIELD_FIELD(unsigned int opcode : 5, | 846 | __BITFIELD_FIELD(unsigned int opcode : 5, |
847 | BITFIELD_FIELD(unsigned int rx : 3, | 847 | __BITFIELD_FIELD(unsigned int rx : 3, |
848 | BITFIELD_FIELD(unsigned int imm : 8, | 848 | __BITFIELD_FIELD(unsigned int imm : 8, |
849 | ;))) | 849 | ;))) |
850 | }; | 850 | }; |
851 | 851 | ||
852 | struct m16e_rri { | 852 | struct m16e_rri { |
853 | BITFIELD_FIELD(unsigned int opcode : 5, | 853 | __BITFIELD_FIELD(unsigned int opcode : 5, |
854 | BITFIELD_FIELD(unsigned int rx : 3, | 854 | __BITFIELD_FIELD(unsigned int rx : 3, |
855 | BITFIELD_FIELD(unsigned int ry : 3, | 855 | __BITFIELD_FIELD(unsigned int ry : 3, |
856 | BITFIELD_FIELD(unsigned int imm : 5, | 856 | __BITFIELD_FIELD(unsigned int imm : 5, |
857 | ;)))) | 857 | ;)))) |
858 | }; | 858 | }; |
859 | 859 | ||
860 | struct m16e_i8 { | 860 | struct m16e_i8 { |
861 | BITFIELD_FIELD(unsigned int opcode : 5, | 861 | __BITFIELD_FIELD(unsigned int opcode : 5, |
862 | BITFIELD_FIELD(unsigned int func : 3, | 862 | __BITFIELD_FIELD(unsigned int func : 3, |
863 | BITFIELD_FIELD(unsigned int imm : 8, | 863 | __BITFIELD_FIELD(unsigned int imm : 8, |
864 | ;))) | 864 | ;))) |
865 | }; | 865 | }; |
866 | 866 | ||
diff --git a/arch/mips/include/uapi/asm/unistd.h b/arch/mips/include/uapi/asm/unistd.h index d6e154a9e6a5..2692abb28e36 100644 --- a/arch/mips/include/uapi/asm/unistd.h +++ b/arch/mips/include/uapi/asm/unistd.h | |||
@@ -371,11 +371,12 @@ | |||
371 | #define __NR_finit_module (__NR_Linux + 348) | 371 | #define __NR_finit_module (__NR_Linux + 348) |
372 | #define __NR_sched_setattr (__NR_Linux + 349) | 372 | #define __NR_sched_setattr (__NR_Linux + 349) |
373 | #define __NR_sched_getattr (__NR_Linux + 350) | 373 | #define __NR_sched_getattr (__NR_Linux + 350) |
374 | #define __NR_renameat2 (__NR_Linux + 351) | ||
374 | 375 | ||
375 | /* | 376 | /* |
376 | * Offset of the last Linux o32 flavoured syscall | 377 | * Offset of the last Linux o32 flavoured syscall |
377 | */ | 378 | */ |
378 | #define __NR_Linux_syscalls 350 | 379 | #define __NR_Linux_syscalls 351 |
379 | 380 | ||
380 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ | 381 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ |
381 | 382 | ||
@@ -699,11 +700,12 @@ | |||
699 | #define __NR_getdents64 (__NR_Linux + 308) | 700 | #define __NR_getdents64 (__NR_Linux + 308) |
700 | #define __NR_sched_setattr (__NR_Linux + 309) | 701 | #define __NR_sched_setattr (__NR_Linux + 309) |
701 | #define __NR_sched_getattr (__NR_Linux + 310) | 702 | #define __NR_sched_getattr (__NR_Linux + 310) |
703 | #define __NR_renameat2 (__NR_Linux + 311) | ||
702 | 704 | ||
703 | /* | 705 | /* |
704 | * Offset of the last Linux 64-bit flavoured syscall | 706 | * Offset of the last Linux 64-bit flavoured syscall |
705 | */ | 707 | */ |
706 | #define __NR_Linux_syscalls 310 | 708 | #define __NR_Linux_syscalls 311 |
707 | 709 | ||
708 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ | 710 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ |
709 | 711 | ||
@@ -1031,11 +1033,12 @@ | |||
1031 | #define __NR_finit_module (__NR_Linux + 312) | 1033 | #define __NR_finit_module (__NR_Linux + 312) |
1032 | #define __NR_sched_setattr (__NR_Linux + 313) | 1034 | #define __NR_sched_setattr (__NR_Linux + 313) |
1033 | #define __NR_sched_getattr (__NR_Linux + 314) | 1035 | #define __NR_sched_getattr (__NR_Linux + 314) |
1036 | #define __NR_renameat2 (__NR_Linux + 315) | ||
1034 | 1037 | ||
1035 | /* | 1038 | /* |
1036 | * Offset of the last N32 flavoured syscall | 1039 | * Offset of the last N32 flavoured syscall |
1037 | */ | 1040 | */ |
1038 | #define __NR_Linux_syscalls 314 | 1041 | #define __NR_Linux_syscalls 315 |
1039 | 1042 | ||
1040 | #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ | 1043 | #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ |
1041 | 1044 | ||
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index e40971b51d2f..037a44d962f3 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c | |||
@@ -124,14 +124,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
124 | seq_printf(m, "kscratch registers\t: %d\n", | 124 | seq_printf(m, "kscratch registers\t: %d\n", |
125 | hweight8(cpu_data[n].kscratch_mask)); | 125 | hweight8(cpu_data[n].kscratch_mask)); |
126 | seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core); | 126 | seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core); |
127 | #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC) | 127 | |
128 | if (cpu_has_mipsmt) { | ||
129 | seq_printf(m, "VPE\t\t\t: %d\n", cpu_data[n].vpe_id); | ||
130 | #if defined(CONFIG_MIPS_MT_SMTC) | ||
131 | seq_printf(m, "TC\t\t\t: %d\n", cpu_data[n].tc_id); | ||
132 | #endif | ||
133 | } | ||
134 | #endif | ||
135 | sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", | 128 | sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", |
136 | cpu_has_vce ? "%u" : "not available"); | 129 | cpu_has_vce ? "%u" : "not available"); |
137 | seq_printf(m, fmt, 'D', vced_count); | 130 | seq_printf(m, fmt, 'D', vced_count); |
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index fdc70b400442..3245474f19d5 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -577,3 +577,4 @@ EXPORT(sys_call_table) | |||
577 | PTR sys_finit_module | 577 | PTR sys_finit_module |
578 | PTR sys_sched_setattr | 578 | PTR sys_sched_setattr |
579 | PTR sys_sched_getattr /* 4350 */ | 579 | PTR sys_sched_getattr /* 4350 */ |
580 | PTR sys_renameat2 | ||
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index dd99c3285aea..be2fedd4ae33 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
@@ -430,4 +430,5 @@ EXPORT(sys_call_table) | |||
430 | PTR sys_getdents64 | 430 | PTR sys_getdents64 |
431 | PTR sys_sched_setattr | 431 | PTR sys_sched_setattr |
432 | PTR sys_sched_getattr /* 5310 */ | 432 | PTR sys_sched_getattr /* 5310 */ |
433 | PTR sys_renameat2 | ||
433 | .size sys_call_table,.-sys_call_table | 434 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index f68d2f4f0090..c1dbcda4b816 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
@@ -423,4 +423,5 @@ EXPORT(sysn32_call_table) | |||
423 | PTR sys_finit_module | 423 | PTR sys_finit_module |
424 | PTR sys_sched_setattr | 424 | PTR sys_sched_setattr |
425 | PTR sys_sched_getattr | 425 | PTR sys_sched_getattr |
426 | PTR sys_renameat2 /* 6315 */ | ||
426 | .size sysn32_call_table,.-sysn32_call_table | 427 | .size sysn32_call_table,.-sysn32_call_table |
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 70f6acecd928..f1343ccd7ed7 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
@@ -556,4 +556,5 @@ EXPORT(sys32_call_table) | |||
556 | PTR sys_finit_module | 556 | PTR sys_finit_module |
557 | PTR sys_sched_setattr | 557 | PTR sys_sched_setattr |
558 | PTR sys_sched_getattr /* 4350 */ | 558 | PTR sys_sched_getattr /* 4350 */ |
559 | PTR sys_renameat2 | ||
559 | .size sys32_call_table,.-sys32_call_table | 560 | .size sys32_call_table,.-sys32_call_table |
diff --git a/arch/mips/lantiq/dts/easy50712.dts b/arch/mips/lantiq/dts/easy50712.dts index fac1f5b178eb..143b8a37b5e4 100644 --- a/arch/mips/lantiq/dts/easy50712.dts +++ b/arch/mips/lantiq/dts/easy50712.dts | |||
@@ -8,6 +8,7 @@ | |||
8 | }; | 8 | }; |
9 | 9 | ||
10 | memory@0 { | 10 | memory@0 { |
11 | device_type = "memory"; | ||
11 | reg = <0x0 0x2000000>; | 12 | reg = <0x0 0x2000000>; |
12 | }; | 13 | }; |
13 | 14 | ||
diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S index 2e4825e48388..9901237563c5 100644 --- a/arch/mips/lib/csum_partial.S +++ b/arch/mips/lib/csum_partial.S | |||
@@ -56,14 +56,20 @@ | |||
56 | #define UNIT(unit) ((unit)*NBYTES) | 56 | #define UNIT(unit) ((unit)*NBYTES) |
57 | 57 | ||
58 | #define ADDC(sum,reg) \ | 58 | #define ADDC(sum,reg) \ |
59 | .set push; \ | ||
60 | .set noat; \ | ||
59 | ADD sum, reg; \ | 61 | ADD sum, reg; \ |
60 | sltu v1, sum, reg; \ | 62 | sltu v1, sum, reg; \ |
61 | ADD sum, v1; \ | 63 | ADD sum, v1; \ |
64 | .set pop | ||
62 | 65 | ||
63 | #define ADDC32(sum,reg) \ | 66 | #define ADDC32(sum,reg) \ |
67 | .set push; \ | ||
68 | .set noat; \ | ||
64 | addu sum, reg; \ | 69 | addu sum, reg; \ |
65 | sltu v1, sum, reg; \ | 70 | sltu v1, sum, reg; \ |
66 | addu sum, v1; \ | 71 | addu sum, v1; \ |
72 | .set pop | ||
67 | 73 | ||
68 | #define CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3) \ | 74 | #define CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3) \ |
69 | LOAD _t0, (offset + UNIT(0))(src); \ | 75 | LOAD _t0, (offset + UNIT(0))(src); \ |
@@ -710,6 +716,8 @@ LEAF(csum_partial) | |||
710 | ADDC(sum, t2) | 716 | ADDC(sum, t2) |
711 | .Ldone\@: | 717 | .Ldone\@: |
712 | /* fold checksum */ | 718 | /* fold checksum */ |
719 | .set push | ||
720 | .set noat | ||
713 | #ifdef USE_DOUBLE | 721 | #ifdef USE_DOUBLE |
714 | dsll32 v1, sum, 0 | 722 | dsll32 v1, sum, 0 |
715 | daddu sum, v1 | 723 | daddu sum, v1 |
@@ -732,6 +740,7 @@ LEAF(csum_partial) | |||
732 | or sum, sum, t0 | 740 | or sum, sum, t0 |
733 | 1: | 741 | 1: |
734 | #endif | 742 | #endif |
743 | .set pop | ||
735 | .set reorder | 744 | .set reorder |
736 | ADDC32(sum, psum) | 745 | ADDC32(sum, psum) |
737 | jr ra | 746 | jr ra |
diff --git a/arch/mips/lib/delay.c b/arch/mips/lib/delay.c index 44713af15a62..705cfb7c1a74 100644 --- a/arch/mips/lib/delay.c +++ b/arch/mips/lib/delay.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Copyright (C) 1994 by Waldorf Electronics | 6 | * Copyright (C) 1994 by Waldorf Electronics |
7 | * Copyright (C) 1995 - 2000, 01, 03 by Ralf Baechle | 7 | * Copyright (C) 1995 - 2000, 01, 03 by Ralf Baechle |
8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | 8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
9 | * Copyright (C) 2007 Maciej W. Rozycki | 9 | * Copyright (C) 2007, 2014 Maciej W. Rozycki |
10 | */ | 10 | */ |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/param.h> | 12 | #include <linux/param.h> |
@@ -15,6 +15,12 @@ | |||
15 | #include <asm/compiler.h> | 15 | #include <asm/compiler.h> |
16 | #include <asm/war.h> | 16 | #include <asm/war.h> |
17 | 17 | ||
18 | #ifndef CONFIG_CPU_DADDI_WORKAROUNDS | ||
19 | #define GCC_DADDI_IMM_ASM() "I" | ||
20 | #else | ||
21 | #define GCC_DADDI_IMM_ASM() "r" | ||
22 | #endif | ||
23 | |||
18 | void __delay(unsigned long loops) | 24 | void __delay(unsigned long loops) |
19 | { | 25 | { |
20 | __asm__ __volatile__ ( | 26 | __asm__ __volatile__ ( |
@@ -22,13 +28,13 @@ void __delay(unsigned long loops) | |||
22 | " .align 3 \n" | 28 | " .align 3 \n" |
23 | "1: bnez %0, 1b \n" | 29 | "1: bnez %0, 1b \n" |
24 | #if BITS_PER_LONG == 32 | 30 | #if BITS_PER_LONG == 32 |
25 | " subu %0, 1 \n" | 31 | " subu %0, %1 \n" |
26 | #else | 32 | #else |
27 | " dsubu %0, 1 \n" | 33 | " dsubu %0, %1 \n" |
28 | #endif | 34 | #endif |
29 | " .set reorder \n" | 35 | " .set reorder \n" |
30 | : "=r" (loops) | 36 | : "=r" (loops) |
31 | : "0" (loops)); | 37 | : GCC_DADDI_IMM_ASM() (1), "0" (loops)); |
32 | } | 38 | } |
33 | EXPORT_SYMBOL(__delay); | 39 | EXPORT_SYMBOL(__delay); |
34 | 40 | ||
diff --git a/arch/mips/lib/strncpy_user.S b/arch/mips/lib/strncpy_user.S index d3301cd1e9a5..3c32baf8b494 100644 --- a/arch/mips/lib/strncpy_user.S +++ b/arch/mips/lib/strncpy_user.S | |||
@@ -35,7 +35,6 @@ LEAF(__strncpy_from_\func\()_asm) | |||
35 | bnez v0, .Lfault\@ | 35 | bnez v0, .Lfault\@ |
36 | 36 | ||
37 | FEXPORT(__strncpy_from_\func\()_nocheck_asm) | 37 | FEXPORT(__strncpy_from_\func\()_nocheck_asm) |
38 | .set noreorder | ||
39 | move t0, zero | 38 | move t0, zero |
40 | move v1, a1 | 39 | move v1, a1 |
41 | .ifeqs "\func","kernel" | 40 | .ifeqs "\func","kernel" |
@@ -45,21 +44,21 @@ FEXPORT(__strncpy_from_\func\()_nocheck_asm) | |||
45 | .endif | 44 | .endif |
46 | PTR_ADDIU v1, 1 | 45 | PTR_ADDIU v1, 1 |
47 | R10KCBARRIER(0(ra)) | 46 | R10KCBARRIER(0(ra)) |
47 | sb v0, (a0) | ||
48 | beqz v0, 2f | 48 | beqz v0, 2f |
49 | sb v0, (a0) | ||
50 | PTR_ADDIU t0, 1 | 49 | PTR_ADDIU t0, 1 |
50 | PTR_ADDIU a0, 1 | ||
51 | bne t0, a2, 1b | 51 | bne t0, a2, 1b |
52 | PTR_ADDIU a0, 1 | ||
53 | 2: PTR_ADDU v0, a1, t0 | 52 | 2: PTR_ADDU v0, a1, t0 |
54 | xor v0, a1 | 53 | xor v0, a1 |
55 | bltz v0, .Lfault\@ | 54 | bltz v0, .Lfault\@ |
56 | nop | 55 | move v0, t0 |
57 | jr ra # return n | 56 | jr ra # return n |
58 | move v0, t0 | ||
59 | END(__strncpy_from_\func\()_asm) | 57 | END(__strncpy_from_\func\()_asm) |
60 | 58 | ||
61 | .Lfault\@: jr ra | 59 | .Lfault\@: |
62 | li v0, -EFAULT | 60 | li v0, -EFAULT |
61 | jr ra | ||
63 | 62 | ||
64 | .section __ex_table,"a" | 63 | .section __ex_table,"a" |
65 | PTR 1b, .Lfault\@ | 64 | PTR 1b, .Lfault\@ |
diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index 7397be226a06..603d79a95f47 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig | |||
@@ -64,7 +64,6 @@ config LEMOTE_MACH3A | |||
64 | bool "Lemote Loongson 3A family machines" | 64 | bool "Lemote Loongson 3A family machines" |
65 | select ARCH_SPARSEMEM_ENABLE | 65 | select ARCH_SPARSEMEM_ENABLE |
66 | select GENERIC_ISA_DMA_SUPPORT_BROKEN | 66 | select GENERIC_ISA_DMA_SUPPORT_BROKEN |
67 | select GENERIC_HARDIRQS_NO__DO_IRQ | ||
68 | select BOOT_ELF32 | 67 | select BOOT_ELF32 |
69 | select BOARD_SCACHE | 68 | select BOARD_SCACHE |
70 | select CSRC_R4K | 69 | select CSRC_R4K |
diff --git a/arch/mips/loongson/lemote-2f/clock.c b/arch/mips/loongson/lemote-2f/clock.c index e1f427f4f5f3..67dd94ef28e6 100644 --- a/arch/mips/loongson/lemote-2f/clock.c +++ b/arch/mips/loongson/lemote-2f/clock.c | |||
@@ -91,6 +91,7 @@ EXPORT_SYMBOL(clk_put); | |||
91 | 91 | ||
92 | int clk_set_rate(struct clk *clk, unsigned long rate) | 92 | int clk_set_rate(struct clk *clk, unsigned long rate) |
93 | { | 93 | { |
94 | unsigned int rate_khz = rate / 1000; | ||
94 | int ret = 0; | 95 | int ret = 0; |
95 | int regval; | 96 | int regval; |
96 | int i; | 97 | int i; |
@@ -111,10 +112,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate) | |||
111 | if (loongson2_clockmod_table[i].frequency == | 112 | if (loongson2_clockmod_table[i].frequency == |
112 | CPUFREQ_ENTRY_INVALID) | 113 | CPUFREQ_ENTRY_INVALID) |
113 | continue; | 114 | continue; |
114 | if (rate == loongson2_clockmod_table[i].frequency) | 115 | if (rate_khz == loongson2_clockmod_table[i].frequency) |
115 | break; | 116 | break; |
116 | } | 117 | } |
117 | if (rate != loongson2_clockmod_table[i].frequency) | 118 | if (rate_khz != loongson2_clockmod_table[i].frequency) |
118 | return -ENOTSUPP; | 119 | return -ENOTSUPP; |
119 | 120 | ||
120 | clk->rate = rate; | 121 | clk->rate = rate; |
diff --git a/arch/mips/mm/tlb-funcs.S b/arch/mips/mm/tlb-funcs.S index 30a494db99c2..a5427c6e9757 100644 --- a/arch/mips/mm/tlb-funcs.S +++ b/arch/mips/mm/tlb-funcs.S | |||
@@ -16,8 +16,10 @@ | |||
16 | 16 | ||
17 | #define FASTPATH_SIZE 128 | 17 | #define FASTPATH_SIZE 128 |
18 | 18 | ||
19 | EXPORT(tlbmiss_handler_setup_pgd_start) | ||
19 | LEAF(tlbmiss_handler_setup_pgd) | 20 | LEAF(tlbmiss_handler_setup_pgd) |
20 | .space 16 * 4 | 21 | 1: j 1b /* Dummy, will be replaced. */ |
22 | .space 64 | ||
21 | END(tlbmiss_handler_setup_pgd) | 23 | END(tlbmiss_handler_setup_pgd) |
22 | EXPORT(tlbmiss_handler_setup_pgd_end) | 24 | EXPORT(tlbmiss_handler_setup_pgd_end) |
23 | 25 | ||
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index ee88367ab3ad..f99ec587b151 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -1422,16 +1422,17 @@ static void build_r4000_tlb_refill_handler(void) | |||
1422 | extern u32 handle_tlbl[], handle_tlbl_end[]; | 1422 | extern u32 handle_tlbl[], handle_tlbl_end[]; |
1423 | extern u32 handle_tlbs[], handle_tlbs_end[]; | 1423 | extern u32 handle_tlbs[], handle_tlbs_end[]; |
1424 | extern u32 handle_tlbm[], handle_tlbm_end[]; | 1424 | extern u32 handle_tlbm[], handle_tlbm_end[]; |
1425 | extern u32 tlbmiss_handler_setup_pgd[], tlbmiss_handler_setup_pgd_end[]; | 1425 | extern u32 tlbmiss_handler_setup_pgd_start[], tlbmiss_handler_setup_pgd[]; |
1426 | extern u32 tlbmiss_handler_setup_pgd_end[]; | ||
1426 | 1427 | ||
1427 | static void build_setup_pgd(void) | 1428 | static void build_setup_pgd(void) |
1428 | { | 1429 | { |
1429 | const int a0 = 4; | 1430 | const int a0 = 4; |
1430 | const int __maybe_unused a1 = 5; | 1431 | const int __maybe_unused a1 = 5; |
1431 | const int __maybe_unused a2 = 6; | 1432 | const int __maybe_unused a2 = 6; |
1432 | u32 *p = tlbmiss_handler_setup_pgd; | 1433 | u32 *p = tlbmiss_handler_setup_pgd_start; |
1433 | const int tlbmiss_handler_setup_pgd_size = | 1434 | const int tlbmiss_handler_setup_pgd_size = |
1434 | tlbmiss_handler_setup_pgd_end - tlbmiss_handler_setup_pgd; | 1435 | tlbmiss_handler_setup_pgd_end - tlbmiss_handler_setup_pgd_start; |
1435 | #ifndef CONFIG_MIPS_PGD_C0_CONTEXT | 1436 | #ifndef CONFIG_MIPS_PGD_C0_CONTEXT |
1436 | long pgdc = (long)pgd_current; | 1437 | long pgdc = (long)pgd_current; |
1437 | #endif | 1438 | #endif |
diff --git a/arch/mips/ralink/dts/mt7620a_eval.dts b/arch/mips/ralink/dts/mt7620a_eval.dts index 35eb874ab7f1..709f58132f5c 100644 --- a/arch/mips/ralink/dts/mt7620a_eval.dts +++ b/arch/mips/ralink/dts/mt7620a_eval.dts | |||
@@ -7,6 +7,7 @@ | |||
7 | model = "Ralink MT7620A evaluation board"; | 7 | model = "Ralink MT7620A evaluation board"; |
8 | 8 | ||
9 | memory@0 { | 9 | memory@0 { |
10 | device_type = "memory"; | ||
10 | reg = <0x0 0x2000000>; | 11 | reg = <0x0 0x2000000>; |
11 | }; | 12 | }; |
12 | 13 | ||
diff --git a/arch/mips/ralink/dts/rt2880_eval.dts b/arch/mips/ralink/dts/rt2880_eval.dts index 322d7002595b..0a685db093d4 100644 --- a/arch/mips/ralink/dts/rt2880_eval.dts +++ b/arch/mips/ralink/dts/rt2880_eval.dts | |||
@@ -7,6 +7,7 @@ | |||
7 | model = "Ralink RT2880 evaluation board"; | 7 | model = "Ralink RT2880 evaluation board"; |
8 | 8 | ||
9 | memory@0 { | 9 | memory@0 { |
10 | device_type = "memory"; | ||
10 | reg = <0x8000000 0x2000000>; | 11 | reg = <0x8000000 0x2000000>; |
11 | }; | 12 | }; |
12 | 13 | ||
diff --git a/arch/mips/ralink/dts/rt3052_eval.dts b/arch/mips/ralink/dts/rt3052_eval.dts index 0ac73ea28198..ec9e9a035541 100644 --- a/arch/mips/ralink/dts/rt3052_eval.dts +++ b/arch/mips/ralink/dts/rt3052_eval.dts | |||
@@ -7,6 +7,7 @@ | |||
7 | model = "Ralink RT3052 evaluation board"; | 7 | model = "Ralink RT3052 evaluation board"; |
8 | 8 | ||
9 | memory@0 { | 9 | memory@0 { |
10 | device_type = "memory"; | ||
10 | reg = <0x0 0x2000000>; | 11 | reg = <0x0 0x2000000>; |
11 | }; | 12 | }; |
12 | 13 | ||
diff --git a/arch/mips/ralink/dts/rt3883_eval.dts b/arch/mips/ralink/dts/rt3883_eval.dts index 2fa6b330bf4f..e8df21a5d10d 100644 --- a/arch/mips/ralink/dts/rt3883_eval.dts +++ b/arch/mips/ralink/dts/rt3883_eval.dts | |||
@@ -7,6 +7,7 @@ | |||
7 | model = "Ralink RT3883 evaluation board"; | 7 | model = "Ralink RT3883 evaluation board"; |
8 | 8 | ||
9 | memory@0 { | 9 | memory@0 { |
10 | device_type = "memory"; | ||
10 | reg = <0x0 0x2000000>; | 11 | reg = <0x0 0x2000000>; |
11 | }; | 12 | }; |
12 | 13 | ||
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 1faefed32749..108d48e652af 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig | |||
@@ -22,6 +22,7 @@ config PARISC | |||
22 | select GENERIC_SMP_IDLE_THREAD | 22 | select GENERIC_SMP_IDLE_THREAD |
23 | select GENERIC_STRNCPY_FROM_USER | 23 | select GENERIC_STRNCPY_FROM_USER |
24 | select SYSCTL_ARCH_UNALIGN_ALLOW | 24 | select SYSCTL_ARCH_UNALIGN_ALLOW |
25 | select SYSCTL_EXCEPTION_TRACE | ||
25 | select HAVE_MOD_ARCH_SPECIFIC | 26 | select HAVE_MOD_ARCH_SPECIFIC |
26 | select VIRT_TO_BUS | 27 | select VIRT_TO_BUS |
27 | select MODULES_USE_ELF_RELA | 28 | select MODULES_USE_ELF_RELA |
diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h index 198a86feb574..d951c9681ab3 100644 --- a/arch/parisc/include/asm/processor.h +++ b/arch/parisc/include/asm/processor.h | |||
@@ -55,6 +55,11 @@ | |||
55 | #define STACK_TOP TASK_SIZE | 55 | #define STACK_TOP TASK_SIZE |
56 | #define STACK_TOP_MAX DEFAULT_TASK_SIZE | 56 | #define STACK_TOP_MAX DEFAULT_TASK_SIZE |
57 | 57 | ||
58 | /* Allow bigger stacks for 64-bit processes */ | ||
59 | #define STACK_SIZE_MAX (USER_WIDE_MODE \ | ||
60 | ? (1 << 30) /* 1 GB */ \ | ||
61 | : (CONFIG_MAX_STACK_SIZE_MB*1024*1024)) | ||
62 | |||
58 | #endif | 63 | #endif |
59 | 64 | ||
60 | #ifndef __ASSEMBLY__ | 65 | #ifndef __ASSEMBLY__ |
diff --git a/arch/parisc/include/uapi/asm/unistd.h b/arch/parisc/include/uapi/asm/unistd.h index 265ae5190b0a..47e0e21d2272 100644 --- a/arch/parisc/include/uapi/asm/unistd.h +++ b/arch/parisc/include/uapi/asm/unistd.h | |||
@@ -829,8 +829,9 @@ | |||
829 | #define __NR_sched_setattr (__NR_Linux + 334) | 829 | #define __NR_sched_setattr (__NR_Linux + 334) |
830 | #define __NR_sched_getattr (__NR_Linux + 335) | 830 | #define __NR_sched_getattr (__NR_Linux + 335) |
831 | #define __NR_utimes (__NR_Linux + 336) | 831 | #define __NR_utimes (__NR_Linux + 336) |
832 | #define __NR_renameat2 (__NR_Linux + 337) | ||
832 | 833 | ||
833 | #define __NR_Linux_syscalls (__NR_utimes + 1) | 834 | #define __NR_Linux_syscalls (__NR_renameat2 + 1) |
834 | 835 | ||
835 | 836 | ||
836 | #define __IGNORE_select /* newselect */ | 837 | #define __IGNORE_select /* newselect */ |
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 31ffa9b55322..e1ffea2f9a0b 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c | |||
@@ -72,10 +72,10 @@ static unsigned long mmap_upper_limit(void) | |||
72 | { | 72 | { |
73 | unsigned long stack_base; | 73 | unsigned long stack_base; |
74 | 74 | ||
75 | /* Limit stack size to 1GB - see setup_arg_pages() in fs/exec.c */ | 75 | /* Limit stack size - see setup_arg_pages() in fs/exec.c */ |
76 | stack_base = rlimit_max(RLIMIT_STACK); | 76 | stack_base = rlimit_max(RLIMIT_STACK); |
77 | if (stack_base > (1 << 30)) | 77 | if (stack_base > STACK_SIZE_MAX) |
78 | stack_base = 1 << 30; | 78 | stack_base = STACK_SIZE_MAX; |
79 | 79 | ||
80 | return PAGE_ALIGN(STACK_TOP - stack_base); | 80 | return PAGE_ALIGN(STACK_TOP - stack_base); |
81 | } | 81 | } |
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index a63bb179f79a..838786011037 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S | |||
@@ -589,10 +589,13 @@ cas_nocontend: | |||
589 | # endif | 589 | # endif |
590 | /* ENABLE_LWS_DEBUG */ | 590 | /* ENABLE_LWS_DEBUG */ |
591 | 591 | ||
592 | rsm PSW_SM_I, %r0 /* Disable interrupts */ | ||
593 | /* COW breaks can cause contention on UP systems */ | ||
592 | LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */ | 594 | LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */ |
593 | cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */ | 595 | cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */ |
594 | cas_wouldblock: | 596 | cas_wouldblock: |
595 | ldo 2(%r0), %r28 /* 2nd case */ | 597 | ldo 2(%r0), %r28 /* 2nd case */ |
598 | ssm PSW_SM_I, %r0 | ||
596 | b lws_exit /* Contended... */ | 599 | b lws_exit /* Contended... */ |
597 | ldo -EAGAIN(%r0), %r21 /* Spin in userspace */ | 600 | ldo -EAGAIN(%r0), %r21 /* Spin in userspace */ |
598 | 601 | ||
@@ -619,15 +622,17 @@ cas_action: | |||
619 | stw %r1, 4(%sr2,%r20) | 622 | stw %r1, 4(%sr2,%r20) |
620 | #endif | 623 | #endif |
621 | /* The load and store could fail */ | 624 | /* The load and store could fail */ |
622 | 1: ldw 0(%sr3,%r26), %r28 | 625 | 1: ldw,ma 0(%sr3,%r26), %r28 |
623 | sub,<> %r28, %r25, %r0 | 626 | sub,<> %r28, %r25, %r0 |
624 | 2: stw %r24, 0(%sr3,%r26) | 627 | 2: stw,ma %r24, 0(%sr3,%r26) |
625 | /* Free lock */ | 628 | /* Free lock */ |
626 | stw %r20, 0(%sr2,%r20) | 629 | stw,ma %r20, 0(%sr2,%r20) |
627 | #if ENABLE_LWS_DEBUG | 630 | #if ENABLE_LWS_DEBUG |
628 | /* Clear thread register indicator */ | 631 | /* Clear thread register indicator */ |
629 | stw %r0, 4(%sr2,%r20) | 632 | stw %r0, 4(%sr2,%r20) |
630 | #endif | 633 | #endif |
634 | /* Enable interrupts */ | ||
635 | ssm PSW_SM_I, %r0 | ||
631 | /* Return to userspace, set no error */ | 636 | /* Return to userspace, set no error */ |
632 | b lws_exit | 637 | b lws_exit |
633 | copy %r0, %r21 | 638 | copy %r0, %r21 |
@@ -639,6 +644,7 @@ cas_action: | |||
639 | #if ENABLE_LWS_DEBUG | 644 | #if ENABLE_LWS_DEBUG |
640 | stw %r0, 4(%sr2,%r20) | 645 | stw %r0, 4(%sr2,%r20) |
641 | #endif | 646 | #endif |
647 | ssm PSW_SM_I, %r0 | ||
642 | b lws_exit | 648 | b lws_exit |
643 | ldo -EFAULT(%r0),%r21 /* set errno */ | 649 | ldo -EFAULT(%r0),%r21 /* set errno */ |
644 | nop | 650 | nop |
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 83ead0ea127d..f1432da7b4c0 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S | |||
@@ -432,6 +432,7 @@ | |||
432 | ENTRY_SAME(sched_setattr) | 432 | ENTRY_SAME(sched_setattr) |
433 | ENTRY_SAME(sched_getattr) /* 335 */ | 433 | ENTRY_SAME(sched_getattr) /* 335 */ |
434 | ENTRY_COMP(utimes) | 434 | ENTRY_COMP(utimes) |
435 | ENTRY_COMP(renameat2) | ||
435 | 436 | ||
436 | /* Nothing yet */ | 437 | /* Nothing yet */ |
437 | 438 | ||
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 1cd1d0c83b6d..47ee620d15d2 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/console.h> | 26 | #include <linux/console.h> |
27 | #include <linux/bug.h> | 27 | #include <linux/bug.h> |
28 | #include <linux/ratelimit.h> | ||
28 | 29 | ||
29 | #include <asm/assembly.h> | 30 | #include <asm/assembly.h> |
30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
@@ -42,9 +43,6 @@ | |||
42 | 43 | ||
43 | #include "../math-emu/math-emu.h" /* for handle_fpe() */ | 44 | #include "../math-emu/math-emu.h" /* for handle_fpe() */ |
44 | 45 | ||
45 | #define PRINT_USER_FAULTS /* (turn this on if you want user faults to be */ | ||
46 | /* dumped to the console via printk) */ | ||
47 | |||
48 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) | 46 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) |
49 | DEFINE_SPINLOCK(pa_dbit_lock); | 47 | DEFINE_SPINLOCK(pa_dbit_lock); |
50 | #endif | 48 | #endif |
@@ -160,6 +158,17 @@ void show_regs(struct pt_regs *regs) | |||
160 | } | 158 | } |
161 | } | 159 | } |
162 | 160 | ||
161 | static DEFINE_RATELIMIT_STATE(_hppa_rs, | ||
162 | DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); | ||
163 | |||
164 | #define parisc_printk_ratelimited(critical, regs, fmt, ...) { \ | ||
165 | if ((critical || show_unhandled_signals) && __ratelimit(&_hppa_rs)) { \ | ||
166 | printk(fmt, ##__VA_ARGS__); \ | ||
167 | show_regs(regs); \ | ||
168 | } \ | ||
169 | } | ||
170 | |||
171 | |||
163 | static void do_show_stack(struct unwind_frame_info *info) | 172 | static void do_show_stack(struct unwind_frame_info *info) |
164 | { | 173 | { |
165 | int i = 1; | 174 | int i = 1; |
@@ -229,12 +238,10 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err) | |||
229 | if (err == 0) | 238 | if (err == 0) |
230 | return; /* STFU */ | 239 | return; /* STFU */ |
231 | 240 | ||
232 | printk(KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n", | 241 | parisc_printk_ratelimited(1, regs, |
242 | KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n", | ||
233 | current->comm, task_pid_nr(current), str, err, regs->iaoq[0]); | 243 | current->comm, task_pid_nr(current), str, err, regs->iaoq[0]); |
234 | #ifdef PRINT_USER_FAULTS | 244 | |
235 | /* XXX for debugging only */ | ||
236 | show_regs(regs); | ||
237 | #endif | ||
238 | return; | 245 | return; |
239 | } | 246 | } |
240 | 247 | ||
@@ -321,14 +328,11 @@ static void handle_break(struct pt_regs *regs) | |||
321 | (tt == BUG_TRAP_TYPE_NONE) ? 9 : 0); | 328 | (tt == BUG_TRAP_TYPE_NONE) ? 9 : 0); |
322 | } | 329 | } |
323 | 330 | ||
324 | #ifdef PRINT_USER_FAULTS | 331 | if (unlikely(iir != GDB_BREAK_INSN)) |
325 | if (unlikely(iir != GDB_BREAK_INSN)) { | 332 | parisc_printk_ratelimited(0, regs, |
326 | printk(KERN_DEBUG "break %d,%d: pid=%d command='%s'\n", | 333 | KERN_DEBUG "break %d,%d: pid=%d command='%s'\n", |
327 | iir & 31, (iir>>13) & ((1<<13)-1), | 334 | iir & 31, (iir>>13) & ((1<<13)-1), |
328 | task_pid_nr(current), current->comm); | 335 | task_pid_nr(current), current->comm); |
329 | show_regs(regs); | ||
330 | } | ||
331 | #endif | ||
332 | 336 | ||
333 | /* send standard GDB signal */ | 337 | /* send standard GDB signal */ |
334 | handle_gdb_break(regs, TRAP_BRKPT); | 338 | handle_gdb_break(regs, TRAP_BRKPT); |
@@ -758,11 +762,9 @@ void notrace handle_interruption(int code, struct pt_regs *regs) | |||
758 | 762 | ||
759 | default: | 763 | default: |
760 | if (user_mode(regs)) { | 764 | if (user_mode(regs)) { |
761 | #ifdef PRINT_USER_FAULTS | 765 | parisc_printk_ratelimited(0, regs, KERN_DEBUG |
762 | printk(KERN_DEBUG "\nhandle_interruption() pid=%d command='%s'\n", | 766 | "handle_interruption() pid=%d command='%s'\n", |
763 | task_pid_nr(current), current->comm); | 767 | task_pid_nr(current), current->comm); |
764 | show_regs(regs); | ||
765 | #endif | ||
766 | /* SIGBUS, for lack of a better one. */ | 768 | /* SIGBUS, for lack of a better one. */ |
767 | si.si_signo = SIGBUS; | 769 | si.si_signo = SIGBUS; |
768 | si.si_code = BUS_OBJERR; | 770 | si.si_code = BUS_OBJERR; |
@@ -779,16 +781,10 @@ void notrace handle_interruption(int code, struct pt_regs *regs) | |||
779 | 781 | ||
780 | if (user_mode(regs)) { | 782 | if (user_mode(regs)) { |
781 | if ((fault_space >> SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) { | 783 | if ((fault_space >> SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) { |
782 | #ifdef PRINT_USER_FAULTS | 784 | parisc_printk_ratelimited(0, regs, KERN_DEBUG |
783 | if (fault_space == 0) | 785 | "User fault %d on space 0x%08lx, pid=%d command='%s'\n", |
784 | printk(KERN_DEBUG "User Fault on Kernel Space "); | 786 | code, fault_space, |
785 | else | 787 | task_pid_nr(current), current->comm); |
786 | printk(KERN_DEBUG "User Fault (long pointer) (fault %d) ", | ||
787 | code); | ||
788 | printk(KERN_CONT "pid=%d command='%s'\n", | ||
789 | task_pid_nr(current), current->comm); | ||
790 | show_regs(regs); | ||
791 | #endif | ||
792 | si.si_signo = SIGSEGV; | 788 | si.si_signo = SIGSEGV; |
793 | si.si_errno = 0; | 789 | si.si_errno = 0; |
794 | si.si_code = SEGV_MAPERR; | 790 | si.si_code = SEGV_MAPERR; |
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 747550762f3c..3ca9c1131cfe 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c | |||
@@ -19,10 +19,6 @@ | |||
19 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
20 | #include <asm/traps.h> | 20 | #include <asm/traps.h> |
21 | 21 | ||
22 | #define PRINT_USER_FAULTS /* (turn this on if you want user faults to be */ | ||
23 | /* dumped to the console via printk) */ | ||
24 | |||
25 | |||
26 | /* Various important other fields */ | 22 | /* Various important other fields */ |
27 | #define bit22set(x) (x & 0x00000200) | 23 | #define bit22set(x) (x & 0x00000200) |
28 | #define bits23_25set(x) (x & 0x000001c0) | 24 | #define bits23_25set(x) (x & 0x000001c0) |
@@ -34,6 +30,8 @@ | |||
34 | 30 | ||
35 | DEFINE_PER_CPU(struct exception_data, exception_data); | 31 | DEFINE_PER_CPU(struct exception_data, exception_data); |
36 | 32 | ||
33 | int show_unhandled_signals = 1; | ||
34 | |||
37 | /* | 35 | /* |
38 | * parisc_acctyp(unsigned int inst) -- | 36 | * parisc_acctyp(unsigned int inst) -- |
39 | * Given a PA-RISC memory access instruction, determine if the | 37 | * Given a PA-RISC memory access instruction, determine if the |
@@ -173,6 +171,32 @@ int fixup_exception(struct pt_regs *regs) | |||
173 | return 0; | 171 | return 0; |
174 | } | 172 | } |
175 | 173 | ||
174 | /* | ||
175 | * Print out info about fatal segfaults, if the show_unhandled_signals | ||
176 | * sysctl is set: | ||
177 | */ | ||
178 | static inline void | ||
179 | show_signal_msg(struct pt_regs *regs, unsigned long code, | ||
180 | unsigned long address, struct task_struct *tsk, | ||
181 | struct vm_area_struct *vma) | ||
182 | { | ||
183 | if (!unhandled_signal(tsk, SIGSEGV)) | ||
184 | return; | ||
185 | |||
186 | if (!printk_ratelimit()) | ||
187 | return; | ||
188 | |||
189 | pr_warn("\n"); | ||
190 | pr_warn("do_page_fault() command='%s' type=%lu address=0x%08lx", | ||
191 | tsk->comm, code, address); | ||
192 | print_vma_addr(KERN_CONT " in ", regs->iaoq[0]); | ||
193 | if (vma) | ||
194 | pr_warn(" vm_start = 0x%08lx, vm_end = 0x%08lx\n", | ||
195 | vma->vm_start, vma->vm_end); | ||
196 | |||
197 | show_regs(regs); | ||
198 | } | ||
199 | |||
176 | void do_page_fault(struct pt_regs *regs, unsigned long code, | 200 | void do_page_fault(struct pt_regs *regs, unsigned long code, |
177 | unsigned long address) | 201 | unsigned long address) |
178 | { | 202 | { |
@@ -270,16 +294,8 @@ bad_area: | |||
270 | if (user_mode(regs)) { | 294 | if (user_mode(regs)) { |
271 | struct siginfo si; | 295 | struct siginfo si; |
272 | 296 | ||
273 | #ifdef PRINT_USER_FAULTS | 297 | show_signal_msg(regs, code, address, tsk, vma); |
274 | printk(KERN_DEBUG "\n"); | 298 | |
275 | printk(KERN_DEBUG "do_page_fault() pid=%d command='%s' type=%lu address=0x%08lx\n", | ||
276 | task_pid_nr(tsk), tsk->comm, code, address); | ||
277 | if (vma) { | ||
278 | printk(KERN_DEBUG "vm_start = 0x%08lx, vm_end = 0x%08lx\n", | ||
279 | vma->vm_start, vma->vm_end); | ||
280 | } | ||
281 | show_regs(regs); | ||
282 | #endif | ||
283 | switch (code) { | 299 | switch (code) { |
284 | case 15: /* Data TLB miss fault/Data page fault */ | 300 | case 15: /* Data TLB miss fault/Data page fault */ |
285 | /* send SIGSEGV when outside of vma */ | 301 | /* send SIGSEGV when outside of vma */ |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 122a580f7322..7e711bdcc6da 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -813,9 +813,6 @@ static void __init clocksource_init(void) | |||
813 | static int decrementer_set_next_event(unsigned long evt, | 813 | static int decrementer_set_next_event(unsigned long evt, |
814 | struct clock_event_device *dev) | 814 | struct clock_event_device *dev) |
815 | { | 815 | { |
816 | /* Don't adjust the decrementer if some irq work is pending */ | ||
817 | if (test_irq_work_pending()) | ||
818 | return 0; | ||
819 | __get_cpu_var(decrementers_next_tb) = get_tb_or_rtc() + evt; | 816 | __get_cpu_var(decrementers_next_tb) = get_tb_or_rtc() + evt; |
820 | set_dec(evt); | 817 | set_dec(evt); |
821 | 818 | ||
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index 253fefe3d1a0..5b51079f3e3b 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c | |||
@@ -549,7 +549,8 @@ static int ioda_eeh_reset(struct eeh_pe *pe, int option) | |||
549 | ret = ioda_eeh_phb_reset(hose, option); | 549 | ret = ioda_eeh_phb_reset(hose, option); |
550 | } else { | 550 | } else { |
551 | bus = eeh_pe_bus_get(pe); | 551 | bus = eeh_pe_bus_get(pe); |
552 | if (pci_is_root_bus(bus)) | 552 | if (pci_is_root_bus(bus) || |
553 | pci_is_root_bus(bus->parent)) | ||
553 | ret = ioda_eeh_root_reset(hose, option); | 554 | ret = ioda_eeh_root_reset(hose, option); |
554 | else | 555 | else |
555 | ret = ioda_eeh_bridge_reset(hose, bus->self, option); | 556 | ret = ioda_eeh_bridge_reset(hose, bus->self, option); |
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index cf3c0089bef2..23223cd63e54 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c | |||
@@ -820,6 +820,9 @@ static int ctr_aes_crypt(struct blkcipher_desc *desc, long func, | |||
820 | else | 820 | else |
821 | memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE); | 821 | memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE); |
822 | spin_unlock(&ctrblk_lock); | 822 | spin_unlock(&ctrblk_lock); |
823 | } else { | ||
824 | if (!nbytes) | ||
825 | memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE); | ||
823 | } | 826 | } |
824 | /* | 827 | /* |
825 | * final block may be < AES_BLOCK_SIZE, copy only nbytes | 828 | * final block may be < AES_BLOCK_SIZE, copy only nbytes |
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c index 0a5aac8a9412..7acb77f7ef1a 100644 --- a/arch/s390/crypto/des_s390.c +++ b/arch/s390/crypto/des_s390.c | |||
@@ -429,6 +429,9 @@ static int ctr_desall_crypt(struct blkcipher_desc *desc, long func, | |||
429 | else | 429 | else |
430 | memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE); | 430 | memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE); |
431 | spin_unlock(&ctrblk_lock); | 431 | spin_unlock(&ctrblk_lock); |
432 | } else { | ||
433 | if (!nbytes) | ||
434 | memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE); | ||
432 | } | 435 | } |
433 | /* final block may be < DES_BLOCK_SIZE, copy only nbytes */ | 436 | /* final block may be < DES_BLOCK_SIZE, copy only nbytes */ |
434 | if (nbytes) { | 437 | if (nbytes) { |
diff --git a/arch/x86/include/asm/hugetlb.h b/arch/x86/include/asm/hugetlb.h index a8091216963b..68c05398bba9 100644 --- a/arch/x86/include/asm/hugetlb.h +++ b/arch/x86/include/asm/hugetlb.h | |||
@@ -52,6 +52,7 @@ static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | |||
52 | static inline void huge_ptep_clear_flush(struct vm_area_struct *vma, | 52 | static inline void huge_ptep_clear_flush(struct vm_area_struct *vma, |
53 | unsigned long addr, pte_t *ptep) | 53 | unsigned long addr, pte_t *ptep) |
54 | { | 54 | { |
55 | ptep_clear_flush(vma, addr, ptep); | ||
55 | } | 56 | } |
56 | 57 | ||
57 | static inline int huge_pte_none(pte_t pte) | 58 | static inline int huge_pte_none(pte_t pte) |
diff --git a/arch/x86/kernel/cpu/rdrand.c b/arch/x86/kernel/cpu/rdrand.c index 384df5105fbc..136ac74dee82 100644 --- a/arch/x86/kernel/cpu/rdrand.c +++ b/arch/x86/kernel/cpu/rdrand.c | |||
@@ -27,6 +27,7 @@ | |||
27 | static int __init x86_rdrand_setup(char *s) | 27 | static int __init x86_rdrand_setup(char *s) |
28 | { | 28 | { |
29 | setup_clear_cpu_cap(X86_FEATURE_RDRAND); | 29 | setup_clear_cpu_cap(X86_FEATURE_RDRAND); |
30 | setup_clear_cpu_cap(X86_FEATURE_RDSEED); | ||
30 | return 1; | 31 | return 1; |
31 | } | 32 | } |
32 | __setup("nordrand", x86_rdrand_setup); | 33 | __setup("nordrand", x86_rdrand_setup); |
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index af1d14a9ebda..dcbbaa165bde 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <asm/mmu_context.h> | 20 | #include <asm/mmu_context.h> |
21 | #include <asm/syscalls.h> | 21 | #include <asm/syscalls.h> |
22 | 22 | ||
23 | int sysctl_ldt16 = 0; | ||
24 | |||
23 | #ifdef CONFIG_SMP | 25 | #ifdef CONFIG_SMP |
24 | static void flush_ldt(void *current_mm) | 26 | static void flush_ldt(void *current_mm) |
25 | { | 27 | { |
@@ -234,7 +236,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) | |||
234 | * IRET leaking the high bits of the kernel stack address. | 236 | * IRET leaking the high bits of the kernel stack address. |
235 | */ | 237 | */ |
236 | #ifdef CONFIG_X86_64 | 238 | #ifdef CONFIG_X86_64 |
237 | if (!ldt_info.seg_32bit) { | 239 | if (!ldt_info.seg_32bit && !sysctl_ldt16) { |
238 | error = -EINVAL; | 240 | error = -EINVAL; |
239 | goto out_unlock; | 241 | goto out_unlock; |
240 | } | 242 | } |
diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c index 00348980a3a6..e1f220e3ca68 100644 --- a/arch/x86/vdso/vdso32-setup.c +++ b/arch/x86/vdso/vdso32-setup.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #ifdef CONFIG_X86_64 | 39 | #ifdef CONFIG_X86_64 |
40 | #define vdso_enabled sysctl_vsyscall32 | 40 | #define vdso_enabled sysctl_vsyscall32 |
41 | #define arch_setup_additional_pages syscall32_setup_pages | 41 | #define arch_setup_additional_pages syscall32_setup_pages |
42 | extern int sysctl_ldt16; | ||
42 | #endif | 43 | #endif |
43 | 44 | ||
44 | /* | 45 | /* |
@@ -249,6 +250,13 @@ static struct ctl_table abi_table2[] = { | |||
249 | .mode = 0644, | 250 | .mode = 0644, |
250 | .proc_handler = proc_dointvec | 251 | .proc_handler = proc_dointvec |
251 | }, | 252 | }, |
253 | { | ||
254 | .procname = "ldt16", | ||
255 | .data = &sysctl_ldt16, | ||
256 | .maxlen = sizeof(int), | ||
257 | .mode = 0644, | ||
258 | .proc_handler = proc_dointvec | ||
259 | }, | ||
252 | {} | 260 | {} |
253 | }; | 261 | }; |
254 | 262 | ||
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index e4a4145926f6..1039fb9ff5f5 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
@@ -451,7 +451,20 @@ static int blkcg_reset_stats(struct cgroup_subsys_state *css, | |||
451 | struct blkcg_gq *blkg; | 451 | struct blkcg_gq *blkg; |
452 | int i; | 452 | int i; |
453 | 453 | ||
454 | mutex_lock(&blkcg_pol_mutex); | 454 | /* |
455 | * XXX: We invoke cgroup_add/rm_cftypes() under blkcg_pol_mutex | ||
456 | * which ends up putting cgroup's internal cgroup_tree_mutex under | ||
457 | * it; however, cgroup_tree_mutex is nested above cgroup file | ||
458 | * active protection and grabbing blkcg_pol_mutex from a cgroup | ||
459 | * file operation creates a possible circular dependency. cgroup | ||
460 | * internal locking is planned to go through further simplification | ||
461 | * and this issue should go away soon. For now, let's trylock | ||
462 | * blkcg_pol_mutex and restart the write on failure. | ||
463 | * | ||
464 | * http://lkml.kernel.org/g/5363C04B.4010400@oracle.com | ||
465 | */ | ||
466 | if (!mutex_trylock(&blkcg_pol_mutex)) | ||
467 | return restart_syscall(); | ||
455 | spin_lock_irq(&blkcg->lock); | 468 | spin_lock_irq(&blkcg->lock); |
456 | 469 | ||
457 | /* | 470 | /* |
diff --git a/drivers/Makefile b/drivers/Makefile index d05d81b19b50..7183b6af5dac 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -119,7 +119,7 @@ obj-$(CONFIG_SGI_SN) += sn/ | |||
119 | obj-y += firmware/ | 119 | obj-y += firmware/ |
120 | obj-$(CONFIG_CRYPTO) += crypto/ | 120 | obj-$(CONFIG_CRYPTO) += crypto/ |
121 | obj-$(CONFIG_SUPERH) += sh/ | 121 | obj-$(CONFIG_SUPERH) += sh/ |
122 | obj-$(CONFIG_ARCH_SHMOBILE_LEGACY) += sh/ | 122 | obj-$(CONFIG_ARCH_SHMOBILE) += sh/ |
123 | ifndef CONFIG_ARCH_USES_GETTIMEOFFSET | 123 | ifndef CONFIG_ARCH_USES_GETTIMEOFFSET |
124 | obj-y += clocksource/ | 124 | obj-y += clocksource/ |
125 | endif | 125 | endif |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index ab686b310100..a34a22841002 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -47,6 +47,23 @@ config ACPI_SLEEP | |||
47 | depends on SUSPEND || HIBERNATION | 47 | depends on SUSPEND || HIBERNATION |
48 | default y | 48 | default y |
49 | 49 | ||
50 | config ACPI_PROCFS_POWER | ||
51 | bool "Deprecated power /proc/acpi directories" | ||
52 | depends on PROC_FS | ||
53 | help | ||
54 | For backwards compatibility, this option allows | ||
55 | deprecated power /proc/acpi/ directories to exist, even when | ||
56 | they have been replaced by functions in /sys. | ||
57 | The deprecated directories (and their replacements) include: | ||
58 | /proc/acpi/battery/* (/sys/class/power_supply/*) | ||
59 | /proc/acpi/ac_adapter/* (sys/class/power_supply/*) | ||
60 | This option has no effect on /proc/acpi/ directories | ||
61 | and functions, which do not yet exist in /sys | ||
62 | This option, together with the proc directories, will be | ||
63 | deleted in the future. | ||
64 | |||
65 | Say N to delete power /proc/acpi/ directories that have moved to /sys/ | ||
66 | |||
50 | config ACPI_EC_DEBUGFS | 67 | config ACPI_EC_DEBUGFS |
51 | tristate "EC read/write access through /sys/kernel/debug/ec" | 68 | tristate "EC read/write access through /sys/kernel/debug/ec" |
52 | default n | 69 | default n |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 0331f91d56e6..bce34afadcd0 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -47,6 +47,7 @@ acpi-y += sysfs.o | |||
47 | acpi-$(CONFIG_X86) += acpi_cmos_rtc.o | 47 | acpi-$(CONFIG_X86) += acpi_cmos_rtc.o |
48 | acpi-$(CONFIG_DEBUG_FS) += debugfs.o | 48 | acpi-$(CONFIG_DEBUG_FS) += debugfs.o |
49 | acpi-$(CONFIG_ACPI_NUMA) += numa.o | 49 | acpi-$(CONFIG_ACPI_NUMA) += numa.o |
50 | acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o | ||
50 | ifdef CONFIG_ACPI_VIDEO | 51 | ifdef CONFIG_ACPI_VIDEO |
51 | acpi-y += video_detect.o | 52 | acpi-y += video_detect.o |
52 | endif | 53 | endif |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 2c01c1da29ce..c67f6f5ad611 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -52,11 +52,39 @@ MODULE_AUTHOR("Paul Diefenbaugh"); | |||
52 | MODULE_DESCRIPTION("ACPI AC Adapter Driver"); | 52 | MODULE_DESCRIPTION("ACPI AC Adapter Driver"); |
53 | MODULE_LICENSE("GPL"); | 53 | MODULE_LICENSE("GPL"); |
54 | 54 | ||
55 | static int acpi_ac_add(struct acpi_device *device); | ||
56 | static int acpi_ac_remove(struct acpi_device *device); | ||
57 | static void acpi_ac_notify(struct acpi_device *device, u32 event); | ||
58 | |||
59 | static const struct acpi_device_id ac_device_ids[] = { | ||
60 | {"ACPI0003", 0}, | ||
61 | {"", 0}, | ||
62 | }; | ||
63 | MODULE_DEVICE_TABLE(acpi, ac_device_ids); | ||
64 | |||
65 | #ifdef CONFIG_PM_SLEEP | ||
66 | static int acpi_ac_resume(struct device *dev); | ||
67 | #endif | ||
68 | static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); | ||
69 | |||
55 | static int ac_sleep_before_get_state_ms; | 70 | static int ac_sleep_before_get_state_ms; |
56 | 71 | ||
72 | static struct acpi_driver acpi_ac_driver = { | ||
73 | .name = "ac", | ||
74 | .class = ACPI_AC_CLASS, | ||
75 | .ids = ac_device_ids, | ||
76 | .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, | ||
77 | .ops = { | ||
78 | .add = acpi_ac_add, | ||
79 | .remove = acpi_ac_remove, | ||
80 | .notify = acpi_ac_notify, | ||
81 | }, | ||
82 | .drv.pm = &acpi_ac_pm, | ||
83 | }; | ||
84 | |||
57 | struct acpi_ac { | 85 | struct acpi_ac { |
58 | struct power_supply charger; | 86 | struct power_supply charger; |
59 | struct platform_device *pdev; | 87 | struct acpi_device * device; |
60 | unsigned long long state; | 88 | unsigned long long state; |
61 | struct notifier_block battery_nb; | 89 | struct notifier_block battery_nb; |
62 | }; | 90 | }; |
@@ -69,10 +97,12 @@ struct acpi_ac { | |||
69 | 97 | ||
70 | static int acpi_ac_get_state(struct acpi_ac *ac) | 98 | static int acpi_ac_get_state(struct acpi_ac *ac) |
71 | { | 99 | { |
72 | acpi_status status; | 100 | acpi_status status = AE_OK; |
73 | acpi_handle handle = ACPI_HANDLE(&ac->pdev->dev); | 101 | |
102 | if (!ac) | ||
103 | return -EINVAL; | ||
74 | 104 | ||
75 | status = acpi_evaluate_integer(handle, "_PSR", NULL, | 105 | status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL, |
76 | &ac->state); | 106 | &ac->state); |
77 | if (ACPI_FAILURE(status)) { | 107 | if (ACPI_FAILURE(status)) { |
78 | ACPI_EXCEPTION((AE_INFO, status, | 108 | ACPI_EXCEPTION((AE_INFO, status, |
@@ -117,10 +147,9 @@ static enum power_supply_property ac_props[] = { | |||
117 | Driver Model | 147 | Driver Model |
118 | -------------------------------------------------------------------------- */ | 148 | -------------------------------------------------------------------------- */ |
119 | 149 | ||
120 | static void acpi_ac_notify_handler(acpi_handle handle, u32 event, void *data) | 150 | static void acpi_ac_notify(struct acpi_device *device, u32 event) |
121 | { | 151 | { |
122 | struct acpi_ac *ac = data; | 152 | struct acpi_ac *ac = acpi_driver_data(device); |
123 | struct acpi_device *adev; | ||
124 | 153 | ||
125 | if (!ac) | 154 | if (!ac) |
126 | return; | 155 | return; |
@@ -143,11 +172,10 @@ static void acpi_ac_notify_handler(acpi_handle handle, u32 event, void *data) | |||
143 | msleep(ac_sleep_before_get_state_ms); | 172 | msleep(ac_sleep_before_get_state_ms); |
144 | 173 | ||
145 | acpi_ac_get_state(ac); | 174 | acpi_ac_get_state(ac); |
146 | adev = ACPI_COMPANION(&ac->pdev->dev); | 175 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
147 | acpi_bus_generate_netlink_event(adev->pnp.device_class, | 176 | dev_name(&device->dev), event, |
148 | dev_name(&ac->pdev->dev), | 177 | (u32) ac->state); |
149 | event, (u32) ac->state); | 178 | acpi_notifier_call_chain(device, event, (u32) ac->state); |
150 | acpi_notifier_call_chain(adev, event, (u32) ac->state); | ||
151 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); | 179 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); |
152 | } | 180 | } |
153 | 181 | ||
@@ -192,49 +220,39 @@ static struct dmi_system_id ac_dmi_table[] = { | |||
192 | {}, | 220 | {}, |
193 | }; | 221 | }; |
194 | 222 | ||
195 | static int acpi_ac_probe(struct platform_device *pdev) | 223 | static int acpi_ac_add(struct acpi_device *device) |
196 | { | 224 | { |
197 | int result = 0; | 225 | int result = 0; |
198 | struct acpi_ac *ac = NULL; | 226 | struct acpi_ac *ac = NULL; |
199 | struct acpi_device *adev; | ||
200 | 227 | ||
201 | if (!pdev) | ||
202 | return -EINVAL; | ||
203 | 228 | ||
204 | adev = ACPI_COMPANION(&pdev->dev); | 229 | if (!device) |
205 | if (!adev) | 230 | return -EINVAL; |
206 | return -ENODEV; | ||
207 | 231 | ||
208 | ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL); | 232 | ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL); |
209 | if (!ac) | 233 | if (!ac) |
210 | return -ENOMEM; | 234 | return -ENOMEM; |
211 | 235 | ||
212 | strcpy(acpi_device_name(adev), ACPI_AC_DEVICE_NAME); | 236 | ac->device = device; |
213 | strcpy(acpi_device_class(adev), ACPI_AC_CLASS); | 237 | strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); |
214 | ac->pdev = pdev; | 238 | strcpy(acpi_device_class(device), ACPI_AC_CLASS); |
215 | platform_set_drvdata(pdev, ac); | 239 | device->driver_data = ac; |
216 | 240 | ||
217 | result = acpi_ac_get_state(ac); | 241 | result = acpi_ac_get_state(ac); |
218 | if (result) | 242 | if (result) |
219 | goto end; | 243 | goto end; |
220 | 244 | ||
221 | ac->charger.name = acpi_device_bid(adev); | 245 | ac->charger.name = acpi_device_bid(device); |
222 | ac->charger.type = POWER_SUPPLY_TYPE_MAINS; | 246 | ac->charger.type = POWER_SUPPLY_TYPE_MAINS; |
223 | ac->charger.properties = ac_props; | 247 | ac->charger.properties = ac_props; |
224 | ac->charger.num_properties = ARRAY_SIZE(ac_props); | 248 | ac->charger.num_properties = ARRAY_SIZE(ac_props); |
225 | ac->charger.get_property = get_ac_property; | 249 | ac->charger.get_property = get_ac_property; |
226 | result = power_supply_register(&pdev->dev, &ac->charger); | 250 | result = power_supply_register(&ac->device->dev, &ac->charger); |
227 | if (result) | 251 | if (result) |
228 | goto end; | 252 | goto end; |
229 | 253 | ||
230 | result = acpi_install_notify_handler(ACPI_HANDLE(&pdev->dev), | ||
231 | ACPI_ALL_NOTIFY, acpi_ac_notify_handler, ac); | ||
232 | if (result) { | ||
233 | power_supply_unregister(&ac->charger); | ||
234 | goto end; | ||
235 | } | ||
236 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", | 254 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", |
237 | acpi_device_name(adev), acpi_device_bid(adev), | 255 | acpi_device_name(device), acpi_device_bid(device), |
238 | ac->state ? "on-line" : "off-line"); | 256 | ac->state ? "on-line" : "off-line"); |
239 | 257 | ||
240 | ac->battery_nb.notifier_call = acpi_ac_battery_notify; | 258 | ac->battery_nb.notifier_call = acpi_ac_battery_notify; |
@@ -256,7 +274,7 @@ static int acpi_ac_resume(struct device *dev) | |||
256 | if (!dev) | 274 | if (!dev) |
257 | return -EINVAL; | 275 | return -EINVAL; |
258 | 276 | ||
259 | ac = platform_get_drvdata(to_platform_device(dev)); | 277 | ac = acpi_driver_data(to_acpi_device(dev)); |
260 | if (!ac) | 278 | if (!ac) |
261 | return -EINVAL; | 279 | return -EINVAL; |
262 | 280 | ||
@@ -270,19 +288,17 @@ static int acpi_ac_resume(struct device *dev) | |||
270 | #else | 288 | #else |
271 | #define acpi_ac_resume NULL | 289 | #define acpi_ac_resume NULL |
272 | #endif | 290 | #endif |
273 | static SIMPLE_DEV_PM_OPS(acpi_ac_pm_ops, NULL, acpi_ac_resume); | ||
274 | 291 | ||
275 | static int acpi_ac_remove(struct platform_device *pdev) | 292 | static int acpi_ac_remove(struct acpi_device *device) |
276 | { | 293 | { |
277 | struct acpi_ac *ac; | 294 | struct acpi_ac *ac = NULL; |
295 | |||
278 | 296 | ||
279 | if (!pdev) | 297 | if (!device || !acpi_driver_data(device)) |
280 | return -EINVAL; | 298 | return -EINVAL; |
281 | 299 | ||
282 | acpi_remove_notify_handler(ACPI_HANDLE(&pdev->dev), | 300 | ac = acpi_driver_data(device); |
283 | ACPI_ALL_NOTIFY, acpi_ac_notify_handler); | ||
284 | 301 | ||
285 | ac = platform_get_drvdata(pdev); | ||
286 | if (ac->charger.dev) | 302 | if (ac->charger.dev) |
287 | power_supply_unregister(&ac->charger); | 303 | power_supply_unregister(&ac->charger); |
288 | unregister_acpi_notifier(&ac->battery_nb); | 304 | unregister_acpi_notifier(&ac->battery_nb); |
@@ -292,23 +308,6 @@ static int acpi_ac_remove(struct platform_device *pdev) | |||
292 | return 0; | 308 | return 0; |
293 | } | 309 | } |
294 | 310 | ||
295 | static const struct acpi_device_id acpi_ac_match[] = { | ||
296 | { "ACPI0003", 0 }, | ||
297 | { } | ||
298 | }; | ||
299 | MODULE_DEVICE_TABLE(acpi, acpi_ac_match); | ||
300 | |||
301 | static struct platform_driver acpi_ac_driver = { | ||
302 | .probe = acpi_ac_probe, | ||
303 | .remove = acpi_ac_remove, | ||
304 | .driver = { | ||
305 | .name = "acpi-ac", | ||
306 | .owner = THIS_MODULE, | ||
307 | .pm = &acpi_ac_pm_ops, | ||
308 | .acpi_match_table = ACPI_PTR(acpi_ac_match), | ||
309 | }, | ||
310 | }; | ||
311 | |||
312 | static int __init acpi_ac_init(void) | 311 | static int __init acpi_ac_init(void) |
313 | { | 312 | { |
314 | int result; | 313 | int result; |
@@ -316,7 +315,7 @@ static int __init acpi_ac_init(void) | |||
316 | if (acpi_disabled) | 315 | if (acpi_disabled) |
317 | return -ENODEV; | 316 | return -ENODEV; |
318 | 317 | ||
319 | result = platform_driver_register(&acpi_ac_driver); | 318 | result = acpi_bus_register_driver(&acpi_ac_driver); |
320 | if (result < 0) | 319 | if (result < 0) |
321 | return -ENODEV; | 320 | return -ENODEV; |
322 | 321 | ||
@@ -325,7 +324,7 @@ static int __init acpi_ac_init(void) | |||
325 | 324 | ||
326 | static void __exit acpi_ac_exit(void) | 325 | static void __exit acpi_ac_exit(void) |
327 | { | 326 | { |
328 | platform_driver_unregister(&acpi_ac_driver); | 327 | acpi_bus_unregister_driver(&acpi_ac_driver); |
329 | } | 328 | } |
330 | module_init(acpi_ac_init); | 329 | module_init(acpi_ac_init); |
331 | module_exit(acpi_ac_exit); | 330 | module_exit(acpi_ac_exit); |
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index dbfe49e5fd63..1d4950388fa1 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c | |||
@@ -29,7 +29,6 @@ ACPI_MODULE_NAME("platform"); | |||
29 | static const struct acpi_device_id acpi_platform_device_ids[] = { | 29 | static const struct acpi_device_id acpi_platform_device_ids[] = { |
30 | 30 | ||
31 | { "PNP0D40" }, | 31 | { "PNP0D40" }, |
32 | { "ACPI0003" }, | ||
33 | { "VPC2004" }, | 32 | { "VPC2004" }, |
34 | { "BCM4752" }, | 33 | { "BCM4752" }, |
35 | 34 | ||
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index b06f5f55ada9..52c81c49cc7d 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c | |||
@@ -405,7 +405,6 @@ static int acpi_processor_add(struct acpi_device *device, | |||
405 | goto err; | 405 | goto err; |
406 | 406 | ||
407 | pr->dev = dev; | 407 | pr->dev = dev; |
408 | dev->offline = pr->flags.need_hotplug_init; | ||
409 | 408 | ||
410 | /* Trigger the processor driver's .probe() if present. */ | 409 | /* Trigger the processor driver's .probe() if present. */ |
411 | if (device_attach(dev) >= 0) | 410 | if (device_attach(dev) >= 0) |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 49bbc71fad54..a08a448068dd 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -141,9 +141,9 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_do_not_use_xsdt, FALSE); | |||
141 | * address. Although ACPICA adheres to the ACPI specification which | 141 | * address. Although ACPICA adheres to the ACPI specification which |
142 | * requires the use of the corresponding 64-bit address if it is non-zero, | 142 | * requires the use of the corresponding 64-bit address if it is non-zero, |
143 | * some machines have been found to have a corrupted non-zero 64-bit | 143 | * some machines have been found to have a corrupted non-zero 64-bit |
144 | * address. Default is FALSE, do not favor the 32-bit addresses. | 144 | * address. Default is TRUE, favor the 32-bit addresses. |
145 | */ | 145 | */ |
146 | ACPI_INIT_GLOBAL(u8, acpi_gbl_use32_bit_fadt_addresses, FALSE); | 146 | ACPI_INIT_GLOBAL(u8, acpi_gbl_use32_bit_fadt_addresses, TRUE); |
147 | 147 | ||
148 | /* | 148 | /* |
149 | * Optionally truncate I/O addresses to 16 bits. Provides compatibility | 149 | * Optionally truncate I/O addresses to 16 bits. Provides compatibility |
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index a4702eee91a8..9fb85f38de90 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c | |||
@@ -461,6 +461,7 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
461 | u32 table_count; | 461 | u32 table_count; |
462 | struct acpi_table_header *table; | 462 | struct acpi_table_header *table; |
463 | acpi_physical_address address; | 463 | acpi_physical_address address; |
464 | acpi_physical_address rsdt_address; | ||
464 | u32 length; | 465 | u32 length; |
465 | u8 *table_entry; | 466 | u8 *table_entry; |
466 | acpi_status status; | 467 | acpi_status status; |
@@ -488,11 +489,14 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
488 | * as per the ACPI specification. | 489 | * as per the ACPI specification. |
489 | */ | 490 | */ |
490 | address = (acpi_physical_address) rsdp->xsdt_physical_address; | 491 | address = (acpi_physical_address) rsdp->xsdt_physical_address; |
492 | rsdt_address = | ||
493 | (acpi_physical_address) rsdp->rsdt_physical_address; | ||
491 | table_entry_size = ACPI_XSDT_ENTRY_SIZE; | 494 | table_entry_size = ACPI_XSDT_ENTRY_SIZE; |
492 | } else { | 495 | } else { |
493 | /* Root table is an RSDT (32-bit physical addresses) */ | 496 | /* Root table is an RSDT (32-bit physical addresses) */ |
494 | 497 | ||
495 | address = (acpi_physical_address) rsdp->rsdt_physical_address; | 498 | address = (acpi_physical_address) rsdp->rsdt_physical_address; |
499 | rsdt_address = address; | ||
496 | table_entry_size = ACPI_RSDT_ENTRY_SIZE; | 500 | table_entry_size = ACPI_RSDT_ENTRY_SIZE; |
497 | } | 501 | } |
498 | 502 | ||
@@ -515,8 +519,7 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
515 | 519 | ||
516 | /* Fall back to the RSDT */ | 520 | /* Fall back to the RSDT */ |
517 | 521 | ||
518 | address = | 522 | address = rsdt_address; |
519 | (acpi_physical_address) rsdp->rsdt_physical_address; | ||
520 | table_entry_size = ACPI_RSDT_ENTRY_SIZE; | 523 | table_entry_size = ACPI_RSDT_ENTRY_SIZE; |
521 | } | 524 | } |
522 | } | 525 | } |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 9a2c63b20050..6e7b2a12860d 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -36,6 +36,12 @@ | |||
36 | #include <linux/suspend.h> | 36 | #include <linux/suspend.h> |
37 | #include <asm/unaligned.h> | 37 | #include <asm/unaligned.h> |
38 | 38 | ||
39 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
40 | #include <linux/proc_fs.h> | ||
41 | #include <linux/seq_file.h> | ||
42 | #include <asm/uaccess.h> | ||
43 | #endif | ||
44 | |||
39 | #include <linux/acpi.h> | 45 | #include <linux/acpi.h> |
40 | #include <linux/power_supply.h> | 46 | #include <linux/power_supply.h> |
41 | 47 | ||
@@ -64,6 +70,19 @@ static unsigned int cache_time = 1000; | |||
64 | module_param(cache_time, uint, 0644); | 70 | module_param(cache_time, uint, 0644); |
65 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); | 71 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); |
66 | 72 | ||
73 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
74 | extern struct proc_dir_entry *acpi_lock_battery_dir(void); | ||
75 | extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); | ||
76 | |||
77 | enum acpi_battery_files { | ||
78 | info_tag = 0, | ||
79 | state_tag, | ||
80 | alarm_tag, | ||
81 | ACPI_BATTERY_NUMFILES, | ||
82 | }; | ||
83 | |||
84 | #endif | ||
85 | |||
67 | static const struct acpi_device_id battery_device_ids[] = { | 86 | static const struct acpi_device_id battery_device_ids[] = { |
68 | {"PNP0C0A", 0}, | 87 | {"PNP0C0A", 0}, |
69 | {"", 0}, | 88 | {"", 0}, |
@@ -299,6 +318,14 @@ static enum power_supply_property energy_battery_props[] = { | |||
299 | POWER_SUPPLY_PROP_SERIAL_NUMBER, | 318 | POWER_SUPPLY_PROP_SERIAL_NUMBER, |
300 | }; | 319 | }; |
301 | 320 | ||
321 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
322 | inline char *acpi_battery_units(struct acpi_battery *battery) | ||
323 | { | ||
324 | return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ? | ||
325 | "mA" : "mW"; | ||
326 | } | ||
327 | #endif | ||
328 | |||
302 | /* -------------------------------------------------------------------------- | 329 | /* -------------------------------------------------------------------------- |
303 | Battery Management | 330 | Battery Management |
304 | -------------------------------------------------------------------------- */ | 331 | -------------------------------------------------------------------------- */ |
@@ -717,6 +744,279 @@ static void acpi_battery_refresh(struct acpi_battery *battery) | |||
717 | } | 744 | } |
718 | 745 | ||
719 | /* -------------------------------------------------------------------------- | 746 | /* -------------------------------------------------------------------------- |
747 | FS Interface (/proc) | ||
748 | -------------------------------------------------------------------------- */ | ||
749 | |||
750 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
751 | static struct proc_dir_entry *acpi_battery_dir; | ||
752 | |||
753 | static int acpi_battery_print_info(struct seq_file *seq, int result) | ||
754 | { | ||
755 | struct acpi_battery *battery = seq->private; | ||
756 | |||
757 | if (result) | ||
758 | goto end; | ||
759 | |||
760 | seq_printf(seq, "present: %s\n", | ||
761 | acpi_battery_present(battery) ? "yes" : "no"); | ||
762 | if (!acpi_battery_present(battery)) | ||
763 | goto end; | ||
764 | if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) | ||
765 | seq_printf(seq, "design capacity: unknown\n"); | ||
766 | else | ||
767 | seq_printf(seq, "design capacity: %d %sh\n", | ||
768 | battery->design_capacity, | ||
769 | acpi_battery_units(battery)); | ||
770 | |||
771 | if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN) | ||
772 | seq_printf(seq, "last full capacity: unknown\n"); | ||
773 | else | ||
774 | seq_printf(seq, "last full capacity: %d %sh\n", | ||
775 | battery->full_charge_capacity, | ||
776 | acpi_battery_units(battery)); | ||
777 | |||
778 | seq_printf(seq, "battery technology: %srechargeable\n", | ||
779 | (!battery->technology)?"non-":""); | ||
780 | |||
781 | if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) | ||
782 | seq_printf(seq, "design voltage: unknown\n"); | ||
783 | else | ||
784 | seq_printf(seq, "design voltage: %d mV\n", | ||
785 | battery->design_voltage); | ||
786 | seq_printf(seq, "design capacity warning: %d %sh\n", | ||
787 | battery->design_capacity_warning, | ||
788 | acpi_battery_units(battery)); | ||
789 | seq_printf(seq, "design capacity low: %d %sh\n", | ||
790 | battery->design_capacity_low, | ||
791 | acpi_battery_units(battery)); | ||
792 | seq_printf(seq, "cycle count: %i\n", battery->cycle_count); | ||
793 | seq_printf(seq, "capacity granularity 1: %d %sh\n", | ||
794 | battery->capacity_granularity_1, | ||
795 | acpi_battery_units(battery)); | ||
796 | seq_printf(seq, "capacity granularity 2: %d %sh\n", | ||
797 | battery->capacity_granularity_2, | ||
798 | acpi_battery_units(battery)); | ||
799 | seq_printf(seq, "model number: %s\n", battery->model_number); | ||
800 | seq_printf(seq, "serial number: %s\n", battery->serial_number); | ||
801 | seq_printf(seq, "battery type: %s\n", battery->type); | ||
802 | seq_printf(seq, "OEM info: %s\n", battery->oem_info); | ||
803 | end: | ||
804 | if (result) | ||
805 | seq_printf(seq, "ERROR: Unable to read battery info\n"); | ||
806 | return result; | ||
807 | } | ||
808 | |||
809 | static int acpi_battery_print_state(struct seq_file *seq, int result) | ||
810 | { | ||
811 | struct acpi_battery *battery = seq->private; | ||
812 | |||
813 | if (result) | ||
814 | goto end; | ||
815 | |||
816 | seq_printf(seq, "present: %s\n", | ||
817 | acpi_battery_present(battery) ? "yes" : "no"); | ||
818 | if (!acpi_battery_present(battery)) | ||
819 | goto end; | ||
820 | |||
821 | seq_printf(seq, "capacity state: %s\n", | ||
822 | (battery->state & 0x04) ? "critical" : "ok"); | ||
823 | if ((battery->state & 0x01) && (battery->state & 0x02)) | ||
824 | seq_printf(seq, | ||
825 | "charging state: charging/discharging\n"); | ||
826 | else if (battery->state & 0x01) | ||
827 | seq_printf(seq, "charging state: discharging\n"); | ||
828 | else if (battery->state & 0x02) | ||
829 | seq_printf(seq, "charging state: charging\n"); | ||
830 | else | ||
831 | seq_printf(seq, "charging state: charged\n"); | ||
832 | |||
833 | if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) | ||
834 | seq_printf(seq, "present rate: unknown\n"); | ||
835 | else | ||
836 | seq_printf(seq, "present rate: %d %s\n", | ||
837 | battery->rate_now, acpi_battery_units(battery)); | ||
838 | |||
839 | if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN) | ||
840 | seq_printf(seq, "remaining capacity: unknown\n"); | ||
841 | else | ||
842 | seq_printf(seq, "remaining capacity: %d %sh\n", | ||
843 | battery->capacity_now, acpi_battery_units(battery)); | ||
844 | if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN) | ||
845 | seq_printf(seq, "present voltage: unknown\n"); | ||
846 | else | ||
847 | seq_printf(seq, "present voltage: %d mV\n", | ||
848 | battery->voltage_now); | ||
849 | end: | ||
850 | if (result) | ||
851 | seq_printf(seq, "ERROR: Unable to read battery state\n"); | ||
852 | |||
853 | return result; | ||
854 | } | ||
855 | |||
856 | static int acpi_battery_print_alarm(struct seq_file *seq, int result) | ||
857 | { | ||
858 | struct acpi_battery *battery = seq->private; | ||
859 | |||
860 | if (result) | ||
861 | goto end; | ||
862 | |||
863 | if (!acpi_battery_present(battery)) { | ||
864 | seq_printf(seq, "present: no\n"); | ||
865 | goto end; | ||
866 | } | ||
867 | seq_printf(seq, "alarm: "); | ||
868 | if (!battery->alarm) | ||
869 | seq_printf(seq, "unsupported\n"); | ||
870 | else | ||
871 | seq_printf(seq, "%u %sh\n", battery->alarm, | ||
872 | acpi_battery_units(battery)); | ||
873 | end: | ||
874 | if (result) | ||
875 | seq_printf(seq, "ERROR: Unable to read battery alarm\n"); | ||
876 | return result; | ||
877 | } | ||
878 | |||
879 | static ssize_t acpi_battery_write_alarm(struct file *file, | ||
880 | const char __user * buffer, | ||
881 | size_t count, loff_t * ppos) | ||
882 | { | ||
883 | int result = 0; | ||
884 | char alarm_string[12] = { '\0' }; | ||
885 | struct seq_file *m = file->private_data; | ||
886 | struct acpi_battery *battery = m->private; | ||
887 | |||
888 | if (!battery || (count > sizeof(alarm_string) - 1)) | ||
889 | return -EINVAL; | ||
890 | if (!acpi_battery_present(battery)) { | ||
891 | result = -ENODEV; | ||
892 | goto end; | ||
893 | } | ||
894 | if (copy_from_user(alarm_string, buffer, count)) { | ||
895 | result = -EFAULT; | ||
896 | goto end; | ||
897 | } | ||
898 | alarm_string[count] = '\0'; | ||
899 | battery->alarm = simple_strtol(alarm_string, NULL, 0); | ||
900 | result = acpi_battery_set_alarm(battery); | ||
901 | end: | ||
902 | if (!result) | ||
903 | return count; | ||
904 | return result; | ||
905 | } | ||
906 | |||
907 | typedef int(*print_func)(struct seq_file *seq, int result); | ||
908 | |||
909 | static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = { | ||
910 | acpi_battery_print_info, | ||
911 | acpi_battery_print_state, | ||
912 | acpi_battery_print_alarm, | ||
913 | }; | ||
914 | |||
915 | static int acpi_battery_read(int fid, struct seq_file *seq) | ||
916 | { | ||
917 | struct acpi_battery *battery = seq->private; | ||
918 | int result = acpi_battery_update(battery); | ||
919 | return acpi_print_funcs[fid](seq, result); | ||
920 | } | ||
921 | |||
922 | #define DECLARE_FILE_FUNCTIONS(_name) \ | ||
923 | static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \ | ||
924 | { \ | ||
925 | return acpi_battery_read(_name##_tag, seq); \ | ||
926 | } \ | ||
927 | static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \ | ||
928 | { \ | ||
929 | return single_open(file, acpi_battery_read_##_name, PDE_DATA(inode)); \ | ||
930 | } | ||
931 | |||
932 | DECLARE_FILE_FUNCTIONS(info); | ||
933 | DECLARE_FILE_FUNCTIONS(state); | ||
934 | DECLARE_FILE_FUNCTIONS(alarm); | ||
935 | |||
936 | #undef DECLARE_FILE_FUNCTIONS | ||
937 | |||
938 | #define FILE_DESCRIPTION_RO(_name) \ | ||
939 | { \ | ||
940 | .name = __stringify(_name), \ | ||
941 | .mode = S_IRUGO, \ | ||
942 | .ops = { \ | ||
943 | .open = acpi_battery_##_name##_open_fs, \ | ||
944 | .read = seq_read, \ | ||
945 | .llseek = seq_lseek, \ | ||
946 | .release = single_release, \ | ||
947 | .owner = THIS_MODULE, \ | ||
948 | }, \ | ||
949 | } | ||
950 | |||
951 | #define FILE_DESCRIPTION_RW(_name) \ | ||
952 | { \ | ||
953 | .name = __stringify(_name), \ | ||
954 | .mode = S_IFREG | S_IRUGO | S_IWUSR, \ | ||
955 | .ops = { \ | ||
956 | .open = acpi_battery_##_name##_open_fs, \ | ||
957 | .read = seq_read, \ | ||
958 | .llseek = seq_lseek, \ | ||
959 | .write = acpi_battery_write_##_name, \ | ||
960 | .release = single_release, \ | ||
961 | .owner = THIS_MODULE, \ | ||
962 | }, \ | ||
963 | } | ||
964 | |||
965 | static const struct battery_file { | ||
966 | struct file_operations ops; | ||
967 | umode_t mode; | ||
968 | const char *name; | ||
969 | } acpi_battery_file[] = { | ||
970 | FILE_DESCRIPTION_RO(info), | ||
971 | FILE_DESCRIPTION_RO(state), | ||
972 | FILE_DESCRIPTION_RW(alarm), | ||
973 | }; | ||
974 | |||
975 | #undef FILE_DESCRIPTION_RO | ||
976 | #undef FILE_DESCRIPTION_RW | ||
977 | |||
978 | static int acpi_battery_add_fs(struct acpi_device *device) | ||
979 | { | ||
980 | struct proc_dir_entry *entry = NULL; | ||
981 | int i; | ||
982 | |||
983 | printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded," | ||
984 | " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); | ||
985 | if (!acpi_device_dir(device)) { | ||
986 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
987 | acpi_battery_dir); | ||
988 | if (!acpi_device_dir(device)) | ||
989 | return -ENODEV; | ||
990 | } | ||
991 | |||
992 | for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { | ||
993 | entry = proc_create_data(acpi_battery_file[i].name, | ||
994 | acpi_battery_file[i].mode, | ||
995 | acpi_device_dir(device), | ||
996 | &acpi_battery_file[i].ops, | ||
997 | acpi_driver_data(device)); | ||
998 | if (!entry) | ||
999 | return -ENODEV; | ||
1000 | } | ||
1001 | return 0; | ||
1002 | } | ||
1003 | |||
1004 | static void acpi_battery_remove_fs(struct acpi_device *device) | ||
1005 | { | ||
1006 | int i; | ||
1007 | if (!acpi_device_dir(device)) | ||
1008 | return; | ||
1009 | for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) | ||
1010 | remove_proc_entry(acpi_battery_file[i].name, | ||
1011 | acpi_device_dir(device)); | ||
1012 | |||
1013 | remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); | ||
1014 | acpi_device_dir(device) = NULL; | ||
1015 | } | ||
1016 | |||
1017 | #endif | ||
1018 | |||
1019 | /* -------------------------------------------------------------------------- | ||
720 | Driver Interface | 1020 | Driver Interface |
721 | -------------------------------------------------------------------------- */ | 1021 | -------------------------------------------------------------------------- */ |
722 | 1022 | ||
@@ -790,6 +1090,15 @@ static int acpi_battery_add(struct acpi_device *device) | |||
790 | result = acpi_battery_update(battery); | 1090 | result = acpi_battery_update(battery); |
791 | if (result) | 1091 | if (result) |
792 | goto fail; | 1092 | goto fail; |
1093 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1094 | result = acpi_battery_add_fs(device); | ||
1095 | #endif | ||
1096 | if (result) { | ||
1097 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1098 | acpi_battery_remove_fs(device); | ||
1099 | #endif | ||
1100 | goto fail; | ||
1101 | } | ||
793 | 1102 | ||
794 | printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", | 1103 | printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", |
795 | ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), | 1104 | ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), |
@@ -816,6 +1125,9 @@ static int acpi_battery_remove(struct acpi_device *device) | |||
816 | return -EINVAL; | 1125 | return -EINVAL; |
817 | battery = acpi_driver_data(device); | 1126 | battery = acpi_driver_data(device); |
818 | unregister_pm_notifier(&battery->pm_nb); | 1127 | unregister_pm_notifier(&battery->pm_nb); |
1128 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1129 | acpi_battery_remove_fs(device); | ||
1130 | #endif | ||
819 | sysfs_remove_battery(battery); | 1131 | sysfs_remove_battery(battery); |
820 | mutex_destroy(&battery->lock); | 1132 | mutex_destroy(&battery->lock); |
821 | mutex_destroy(&battery->sysfs_lock); | 1133 | mutex_destroy(&battery->sysfs_lock); |
@@ -866,7 +1178,19 @@ static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) | |||
866 | 1178 | ||
867 | if (dmi_check_system(bat_dmi_table)) | 1179 | if (dmi_check_system(bat_dmi_table)) |
868 | battery_bix_broken_package = 1; | 1180 | battery_bix_broken_package = 1; |
869 | acpi_bus_register_driver(&acpi_battery_driver); | 1181 | |
1182 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1183 | acpi_battery_dir = acpi_lock_battery_dir(); | ||
1184 | if (!acpi_battery_dir) | ||
1185 | return; | ||
1186 | #endif | ||
1187 | if (acpi_bus_register_driver(&acpi_battery_driver) < 0) { | ||
1188 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1189 | acpi_unlock_battery_dir(acpi_battery_dir); | ||
1190 | #endif | ||
1191 | return; | ||
1192 | } | ||
1193 | return; | ||
870 | } | 1194 | } |
871 | 1195 | ||
872 | static int __init acpi_battery_init(void) | 1196 | static int __init acpi_battery_init(void) |
@@ -878,6 +1202,9 @@ static int __init acpi_battery_init(void) | |||
878 | static void __exit acpi_battery_exit(void) | 1202 | static void __exit acpi_battery_exit(void) |
879 | { | 1203 | { |
880 | acpi_bus_unregister_driver(&acpi_battery_driver); | 1204 | acpi_bus_unregister_driver(&acpi_battery_driver); |
1205 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1206 | acpi_unlock_battery_dir(acpi_battery_dir); | ||
1207 | #endif | ||
881 | } | 1208 | } |
882 | 1209 | ||
883 | module_init(acpi_battery_init); | 1210 | module_init(acpi_battery_init); |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index afec4526c48a..3d8413d02a97 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -314,6 +314,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
314 | DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"), | 314 | DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"), |
315 | }, | 315 | }, |
316 | }, | 316 | }, |
317 | { | ||
318 | .callback = dmi_disable_osi_win8, | ||
319 | .ident = "Dell Inspiron 7737", | ||
320 | .matches = { | ||
321 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
322 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7737"), | ||
323 | }, | ||
324 | }, | ||
317 | 325 | ||
318 | /* | 326 | /* |
319 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. | 327 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. |
@@ -374,6 +382,19 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
374 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T500"), | 382 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T500"), |
375 | }, | 383 | }, |
376 | }, | 384 | }, |
385 | /* | ||
386 | * Without this this EEEpc exports a non working WMI interface, with | ||
387 | * this it exports a working "good old" eeepc_laptop interface, fixing | ||
388 | * both brightness control, and rfkill not working. | ||
389 | */ | ||
390 | { | ||
391 | .callback = dmi_enable_osi_linux, | ||
392 | .ident = "Asus EEE PC 1015PX", | ||
393 | .matches = { | ||
394 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."), | ||
395 | DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"), | ||
396 | }, | ||
397 | }, | ||
377 | {} | 398 | {} |
378 | }; | 399 | }; |
379 | 400 | ||
diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c new file mode 100644 index 000000000000..6c9ee68e46fb --- /dev/null +++ b/drivers/acpi/cm_sbs.c | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or (at | ||
7 | * your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but | ||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
17 | * | ||
18 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/acpi.h> | ||
25 | #include <linux/types.h> | ||
26 | #include <linux/proc_fs.h> | ||
27 | #include <linux/seq_file.h> | ||
28 | #include <acpi/acpi_bus.h> | ||
29 | #include <acpi/acpi_drivers.h> | ||
30 | |||
31 | #define PREFIX "ACPI: " | ||
32 | |||
33 | ACPI_MODULE_NAME("cm_sbs"); | ||
34 | #define ACPI_AC_CLASS "ac_adapter" | ||
35 | #define ACPI_BATTERY_CLASS "battery" | ||
36 | #define _COMPONENT ACPI_SBS_COMPONENT | ||
37 | static struct proc_dir_entry *acpi_ac_dir; | ||
38 | static struct proc_dir_entry *acpi_battery_dir; | ||
39 | |||
40 | static DEFINE_MUTEX(cm_sbs_mutex); | ||
41 | |||
42 | static int lock_ac_dir_cnt; | ||
43 | static int lock_battery_dir_cnt; | ||
44 | |||
45 | struct proc_dir_entry *acpi_lock_ac_dir(void) | ||
46 | { | ||
47 | mutex_lock(&cm_sbs_mutex); | ||
48 | if (!acpi_ac_dir) | ||
49 | acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir); | ||
50 | if (acpi_ac_dir) { | ||
51 | lock_ac_dir_cnt++; | ||
52 | } else { | ||
53 | printk(KERN_ERR PREFIX | ||
54 | "Cannot create %s\n", ACPI_AC_CLASS); | ||
55 | } | ||
56 | mutex_unlock(&cm_sbs_mutex); | ||
57 | return acpi_ac_dir; | ||
58 | } | ||
59 | EXPORT_SYMBOL(acpi_lock_ac_dir); | ||
60 | |||
61 | void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir_param) | ||
62 | { | ||
63 | mutex_lock(&cm_sbs_mutex); | ||
64 | if (acpi_ac_dir_param) | ||
65 | lock_ac_dir_cnt--; | ||
66 | if (lock_ac_dir_cnt == 0 && acpi_ac_dir_param && acpi_ac_dir) { | ||
67 | remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir); | ||
68 | acpi_ac_dir = NULL; | ||
69 | } | ||
70 | mutex_unlock(&cm_sbs_mutex); | ||
71 | } | ||
72 | EXPORT_SYMBOL(acpi_unlock_ac_dir); | ||
73 | |||
74 | struct proc_dir_entry *acpi_lock_battery_dir(void) | ||
75 | { | ||
76 | mutex_lock(&cm_sbs_mutex); | ||
77 | if (!acpi_battery_dir) { | ||
78 | acpi_battery_dir = | ||
79 | proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir); | ||
80 | } | ||
81 | if (acpi_battery_dir) { | ||
82 | lock_battery_dir_cnt++; | ||
83 | } else { | ||
84 | printk(KERN_ERR PREFIX | ||
85 | "Cannot create %s\n", ACPI_BATTERY_CLASS); | ||
86 | } | ||
87 | mutex_unlock(&cm_sbs_mutex); | ||
88 | return acpi_battery_dir; | ||
89 | } | ||
90 | EXPORT_SYMBOL(acpi_lock_battery_dir); | ||
91 | |||
92 | void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param) | ||
93 | { | ||
94 | mutex_lock(&cm_sbs_mutex); | ||
95 | if (acpi_battery_dir_param) | ||
96 | lock_battery_dir_cnt--; | ||
97 | if (lock_battery_dir_cnt == 0 && acpi_battery_dir_param | ||
98 | && acpi_battery_dir) { | ||
99 | remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); | ||
100 | acpi_battery_dir = NULL; | ||
101 | } | ||
102 | mutex_unlock(&cm_sbs_mutex); | ||
103 | return; | ||
104 | } | ||
105 | EXPORT_SYMBOL(acpi_unlock_battery_dir); | ||
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 8b6990e417ec..f8bc5a755dda 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -457,10 +457,10 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
457 | }, | 457 | }, |
458 | { | 458 | { |
459 | .callback = video_set_use_native_backlight, | 459 | .callback = video_set_use_native_backlight, |
460 | .ident = "ThinkPad T430s", | 460 | .ident = "ThinkPad T430 and T430s", |
461 | .matches = { | 461 | .matches = { |
462 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 462 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
463 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430s"), | 463 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430"), |
464 | }, | 464 | }, |
465 | }, | 465 | }, |
466 | { | 466 | { |
@@ -472,7 +472,7 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
472 | }, | 472 | }, |
473 | }, | 473 | }, |
474 | { | 474 | { |
475 | .callback = video_set_use_native_backlight, | 475 | .callback = video_set_use_native_backlight, |
476 | .ident = "ThinkPad X1 Carbon", | 476 | .ident = "ThinkPad X1 Carbon", |
477 | .matches = { | 477 | .matches = { |
478 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 478 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
@@ -500,7 +500,7 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
500 | .ident = "Dell Inspiron 7520", | 500 | .ident = "Dell Inspiron 7520", |
501 | .matches = { | 501 | .matches = { |
502 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 502 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
503 | DMI_MATCH(DMI_PRODUCT_VERSION, "Inspiron 7520"), | 503 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7520"), |
504 | }, | 504 | }, |
505 | }, | 505 | }, |
506 | { | 506 | { |
@@ -513,6 +513,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
513 | }, | 513 | }, |
514 | { | 514 | { |
515 | .callback = video_set_use_native_backlight, | 515 | .callback = video_set_use_native_backlight, |
516 | .ident = "Acer Aspire 5742G", | ||
517 | .matches = { | ||
518 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
519 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5742G"), | ||
520 | }, | ||
521 | }, | ||
522 | { | ||
523 | .callback = video_set_use_native_backlight, | ||
516 | .ident = "Acer Aspire V5-431", | 524 | .ident = "Acer Aspire V5-431", |
517 | .matches = { | 525 | .matches = { |
518 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 526 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index c2706047337f..0033fafc470b 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -815,7 +815,7 @@ config PATA_AT32 | |||
815 | 815 | ||
816 | config PATA_AT91 | 816 | config PATA_AT91 |
817 | tristate "PATA support for AT91SAM9260" | 817 | tristate "PATA support for AT91SAM9260" |
818 | depends on ARM && ARCH_AT91 | 818 | depends on ARM && SOC_AT91SAM9 |
819 | help | 819 | help |
820 | This option enables support for IDE devices on the Atmel AT91SAM9260 SoC. | 820 | This option enables support for IDE devices on the Atmel AT91SAM9260 SoC. |
821 | 821 | ||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 71e15b73513d..60707814a84b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -1115,6 +1115,17 @@ static bool ahci_broken_online(struct pci_dev *pdev) | |||
1115 | return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff); | 1115 | return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff); |
1116 | } | 1116 | } |
1117 | 1117 | ||
1118 | static bool ahci_broken_devslp(struct pci_dev *pdev) | ||
1119 | { | ||
1120 | /* device with broken DEVSLP but still showing SDS capability */ | ||
1121 | static const struct pci_device_id ids[] = { | ||
1122 | { PCI_VDEVICE(INTEL, 0x0f23)}, /* Valleyview SoC */ | ||
1123 | {} | ||
1124 | }; | ||
1125 | |||
1126 | return pci_match_id(ids, pdev); | ||
1127 | } | ||
1128 | |||
1118 | #ifdef CONFIG_ATA_ACPI | 1129 | #ifdef CONFIG_ATA_ACPI |
1119 | static void ahci_gtf_filter_workaround(struct ata_host *host) | 1130 | static void ahci_gtf_filter_workaround(struct ata_host *host) |
1120 | { | 1131 | { |
@@ -1364,6 +1375,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1364 | 1375 | ||
1365 | hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar]; | 1376 | hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar]; |
1366 | 1377 | ||
1378 | /* must set flag prior to save config in order to take effect */ | ||
1379 | if (ahci_broken_devslp(pdev)) | ||
1380 | hpriv->flags |= AHCI_HFLAG_NO_DEVSLP; | ||
1381 | |||
1367 | /* save initial config */ | 1382 | /* save initial config */ |
1368 | ahci_pci_save_initial_config(pdev, hpriv); | 1383 | ahci_pci_save_initial_config(pdev, hpriv); |
1369 | 1384 | ||
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index b5eb886da226..af63c75c2001 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
@@ -236,6 +236,7 @@ enum { | |||
236 | port start (wait until | 236 | port start (wait until |
237 | error-handling stage) */ | 237 | error-handling stage) */ |
238 | AHCI_HFLAG_MULTI_MSI = (1 << 16), /* multiple PCI MSIs */ | 238 | AHCI_HFLAG_MULTI_MSI = (1 << 16), /* multiple PCI MSIs */ |
239 | AHCI_HFLAG_NO_DEVSLP = (1 << 17), /* no device sleep */ | ||
239 | 240 | ||
240 | /* ap->flags bits */ | 241 | /* ap->flags bits */ |
241 | 242 | ||
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index 497c7abe1c7d..8befeb69eeb1 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c | |||
@@ -29,9 +29,25 @@ | |||
29 | #include "ahci.h" | 29 | #include "ahci.h" |
30 | 30 | ||
31 | enum { | 31 | enum { |
32 | PORT_PHY_CTL = 0x178, /* Port0 PHY Control */ | 32 | /* Timer 1-ms Register */ |
33 | PORT_PHY_CTL_PDDQ_LOC = 0x100000, /* PORT_PHY_CTL bits */ | 33 | IMX_TIMER1MS = 0x00e0, |
34 | HOST_TIMER1MS = 0xe0, /* Timer 1-ms */ | 34 | /* Port0 PHY Control Register */ |
35 | IMX_P0PHYCR = 0x0178, | ||
36 | IMX_P0PHYCR_TEST_PDDQ = 1 << 20, | ||
37 | IMX_P0PHYCR_CR_READ = 1 << 19, | ||
38 | IMX_P0PHYCR_CR_WRITE = 1 << 18, | ||
39 | IMX_P0PHYCR_CR_CAP_DATA = 1 << 17, | ||
40 | IMX_P0PHYCR_CR_CAP_ADDR = 1 << 16, | ||
41 | /* Port0 PHY Status Register */ | ||
42 | IMX_P0PHYSR = 0x017c, | ||
43 | IMX_P0PHYSR_CR_ACK = 1 << 18, | ||
44 | IMX_P0PHYSR_CR_DATA_OUT = 0xffff << 0, | ||
45 | /* Lane0 Output Status Register */ | ||
46 | IMX_LANE0_OUT_STAT = 0x2003, | ||
47 | IMX_LANE0_OUT_STAT_RX_PLL_STATE = 1 << 1, | ||
48 | /* Clock Reset Register */ | ||
49 | IMX_CLOCK_RESET = 0x7f3f, | ||
50 | IMX_CLOCK_RESET_RESET = 1 << 0, | ||
35 | }; | 51 | }; |
36 | 52 | ||
37 | enum ahci_imx_type { | 53 | enum ahci_imx_type { |
@@ -54,9 +70,149 @@ MODULE_PARM_DESC(hotplug, "AHCI IMX hot-plug support (0=Don't support, 1=support | |||
54 | 70 | ||
55 | static void ahci_imx_host_stop(struct ata_host *host); | 71 | static void ahci_imx_host_stop(struct ata_host *host); |
56 | 72 | ||
73 | static int imx_phy_crbit_assert(void __iomem *mmio, u32 bit, bool assert) | ||
74 | { | ||
75 | int timeout = 10; | ||
76 | u32 crval; | ||
77 | u32 srval; | ||
78 | |||
79 | /* Assert or deassert the bit */ | ||
80 | crval = readl(mmio + IMX_P0PHYCR); | ||
81 | if (assert) | ||
82 | crval |= bit; | ||
83 | else | ||
84 | crval &= ~bit; | ||
85 | writel(crval, mmio + IMX_P0PHYCR); | ||
86 | |||
87 | /* Wait for the cr_ack signal */ | ||
88 | do { | ||
89 | srval = readl(mmio + IMX_P0PHYSR); | ||
90 | if ((assert ? srval : ~srval) & IMX_P0PHYSR_CR_ACK) | ||
91 | break; | ||
92 | usleep_range(100, 200); | ||
93 | } while (--timeout); | ||
94 | |||
95 | return timeout ? 0 : -ETIMEDOUT; | ||
96 | } | ||
97 | |||
98 | static int imx_phy_reg_addressing(u16 addr, void __iomem *mmio) | ||
99 | { | ||
100 | u32 crval = addr; | ||
101 | int ret; | ||
102 | |||
103 | /* Supply the address on cr_data_in */ | ||
104 | writel(crval, mmio + IMX_P0PHYCR); | ||
105 | |||
106 | /* Assert the cr_cap_addr signal */ | ||
107 | ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_ADDR, true); | ||
108 | if (ret) | ||
109 | return ret; | ||
110 | |||
111 | /* Deassert cr_cap_addr */ | ||
112 | ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_ADDR, false); | ||
113 | if (ret) | ||
114 | return ret; | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static int imx_phy_reg_write(u16 val, void __iomem *mmio) | ||
120 | { | ||
121 | u32 crval = val; | ||
122 | int ret; | ||
123 | |||
124 | /* Supply the data on cr_data_in */ | ||
125 | writel(crval, mmio + IMX_P0PHYCR); | ||
126 | |||
127 | /* Assert the cr_cap_data signal */ | ||
128 | ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_DATA, true); | ||
129 | if (ret) | ||
130 | return ret; | ||
131 | |||
132 | /* Deassert cr_cap_data */ | ||
133 | ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_DATA, false); | ||
134 | if (ret) | ||
135 | return ret; | ||
136 | |||
137 | if (val & IMX_CLOCK_RESET_RESET) { | ||
138 | /* | ||
139 | * In case we're resetting the phy, it's unable to acknowledge, | ||
140 | * so we return immediately here. | ||
141 | */ | ||
142 | crval |= IMX_P0PHYCR_CR_WRITE; | ||
143 | writel(crval, mmio + IMX_P0PHYCR); | ||
144 | goto out; | ||
145 | } | ||
146 | |||
147 | /* Assert the cr_write signal */ | ||
148 | ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_WRITE, true); | ||
149 | if (ret) | ||
150 | return ret; | ||
151 | |||
152 | /* Deassert cr_write */ | ||
153 | ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_WRITE, false); | ||
154 | if (ret) | ||
155 | return ret; | ||
156 | |||
157 | out: | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static int imx_phy_reg_read(u16 *val, void __iomem *mmio) | ||
162 | { | ||
163 | int ret; | ||
164 | |||
165 | /* Assert the cr_read signal */ | ||
166 | ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_READ, true); | ||
167 | if (ret) | ||
168 | return ret; | ||
169 | |||
170 | /* Capture the data from cr_data_out[] */ | ||
171 | *val = readl(mmio + IMX_P0PHYSR) & IMX_P0PHYSR_CR_DATA_OUT; | ||
172 | |||
173 | /* Deassert cr_read */ | ||
174 | ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_READ, false); | ||
175 | if (ret) | ||
176 | return ret; | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static int imx_sata_phy_reset(struct ahci_host_priv *hpriv) | ||
182 | { | ||
183 | void __iomem *mmio = hpriv->mmio; | ||
184 | int timeout = 10; | ||
185 | u16 val; | ||
186 | int ret; | ||
187 | |||
188 | /* Reset SATA PHY by setting RESET bit of PHY register CLOCK_RESET */ | ||
189 | ret = imx_phy_reg_addressing(IMX_CLOCK_RESET, mmio); | ||
190 | if (ret) | ||
191 | return ret; | ||
192 | ret = imx_phy_reg_write(IMX_CLOCK_RESET_RESET, mmio); | ||
193 | if (ret) | ||
194 | return ret; | ||
195 | |||
196 | /* Wait for PHY RX_PLL to be stable */ | ||
197 | do { | ||
198 | usleep_range(100, 200); | ||
199 | ret = imx_phy_reg_addressing(IMX_LANE0_OUT_STAT, mmio); | ||
200 | if (ret) | ||
201 | return ret; | ||
202 | ret = imx_phy_reg_read(&val, mmio); | ||
203 | if (ret) | ||
204 | return ret; | ||
205 | if (val & IMX_LANE0_OUT_STAT_RX_PLL_STATE) | ||
206 | break; | ||
207 | } while (--timeout); | ||
208 | |||
209 | return timeout ? 0 : -ETIMEDOUT; | ||
210 | } | ||
211 | |||
57 | static int imx_sata_enable(struct ahci_host_priv *hpriv) | 212 | static int imx_sata_enable(struct ahci_host_priv *hpriv) |
58 | { | 213 | { |
59 | struct imx_ahci_priv *imxpriv = hpriv->plat_data; | 214 | struct imx_ahci_priv *imxpriv = hpriv->plat_data; |
215 | struct device *dev = &imxpriv->ahci_pdev->dev; | ||
60 | int ret; | 216 | int ret; |
61 | 217 | ||
62 | if (imxpriv->no_device) | 218 | if (imxpriv->no_device) |
@@ -101,6 +257,14 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv) | |||
101 | regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, | 257 | regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, |
102 | IMX6Q_GPR13_SATA_MPLL_CLK_EN, | 258 | IMX6Q_GPR13_SATA_MPLL_CLK_EN, |
103 | IMX6Q_GPR13_SATA_MPLL_CLK_EN); | 259 | IMX6Q_GPR13_SATA_MPLL_CLK_EN); |
260 | |||
261 | usleep_range(100, 200); | ||
262 | |||
263 | ret = imx_sata_phy_reset(hpriv); | ||
264 | if (ret) { | ||
265 | dev_err(dev, "failed to reset phy: %d\n", ret); | ||
266 | goto disable_regulator; | ||
267 | } | ||
104 | } | 268 | } |
105 | 269 | ||
106 | usleep_range(1000, 2000); | 270 | usleep_range(1000, 2000); |
@@ -156,8 +320,8 @@ static void ahci_imx_error_handler(struct ata_port *ap) | |||
156 | * without full reset once the pddq mode is enabled making it | 320 | * without full reset once the pddq mode is enabled making it |
157 | * impossible to use as part of libata LPM. | 321 | * impossible to use as part of libata LPM. |
158 | */ | 322 | */ |
159 | reg_val = readl(mmio + PORT_PHY_CTL); | 323 | reg_val = readl(mmio + IMX_P0PHYCR); |
160 | writel(reg_val | PORT_PHY_CTL_PDDQ_LOC, mmio + PORT_PHY_CTL); | 324 | writel(reg_val | IMX_P0PHYCR_TEST_PDDQ, mmio + IMX_P0PHYCR); |
161 | imx_sata_disable(hpriv); | 325 | imx_sata_disable(hpriv); |
162 | imxpriv->no_device = true; | 326 | imxpriv->no_device = true; |
163 | } | 327 | } |
@@ -217,6 +381,7 @@ static int imx_ahci_probe(struct platform_device *pdev) | |||
217 | if (!imxpriv) | 381 | if (!imxpriv) |
218 | return -ENOMEM; | 382 | return -ENOMEM; |
219 | 383 | ||
384 | imxpriv->ahci_pdev = pdev; | ||
220 | imxpriv->no_device = false; | 385 | imxpriv->no_device = false; |
221 | imxpriv->first_time = true; | 386 | imxpriv->first_time = true; |
222 | imxpriv->type = (enum ahci_imx_type)of_id->data; | 387 | imxpriv->type = (enum ahci_imx_type)of_id->data; |
@@ -248,7 +413,7 @@ static int imx_ahci_probe(struct platform_device *pdev) | |||
248 | 413 | ||
249 | /* | 414 | /* |
250 | * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL, | 415 | * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL, |
251 | * and IP vendor specific register HOST_TIMER1MS. | 416 | * and IP vendor specific register IMX_TIMER1MS. |
252 | * Configure CAP_SSS (support stagered spin up). | 417 | * Configure CAP_SSS (support stagered spin up). |
253 | * Implement the port0. | 418 | * Implement the port0. |
254 | * Get the ahb clock rate, and configure the TIMER1MS register. | 419 | * Get the ahb clock rate, and configure the TIMER1MS register. |
@@ -265,7 +430,7 @@ static int imx_ahci_probe(struct platform_device *pdev) | |||
265 | } | 430 | } |
266 | 431 | ||
267 | reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000; | 432 | reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000; |
268 | writel(reg_val, hpriv->mmio + HOST_TIMER1MS); | 433 | writel(reg_val, hpriv->mmio + IMX_TIMER1MS); |
269 | 434 | ||
270 | ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, 0, 0); | 435 | ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, 0, 0); |
271 | if (ret) | 436 | if (ret) |
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 6bd4f660b4e1..b9861453fc81 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -452,6 +452,13 @@ void ahci_save_initial_config(struct device *dev, | |||
452 | cap &= ~HOST_CAP_SNTF; | 452 | cap &= ~HOST_CAP_SNTF; |
453 | } | 453 | } |
454 | 454 | ||
455 | if ((cap2 & HOST_CAP2_SDS) && (hpriv->flags & AHCI_HFLAG_NO_DEVSLP)) { | ||
456 | dev_info(dev, | ||
457 | "controller can't do DEVSLP, turning off\n"); | ||
458 | cap2 &= ~HOST_CAP2_SDS; | ||
459 | cap2 &= ~HOST_CAP2_SADM; | ||
460 | } | ||
461 | |||
455 | if (!(cap & HOST_CAP_FBS) && (hpriv->flags & AHCI_HFLAG_YES_FBS)) { | 462 | if (!(cap & HOST_CAP_FBS) && (hpriv->flags & AHCI_HFLAG_YES_FBS)) { |
456 | dev_info(dev, "controller can do FBS, turning on CAP_FBS\n"); | 463 | dev_info(dev, "controller can do FBS, turning on CAP_FBS\n"); |
457 | cap |= HOST_CAP_FBS; | 464 | cap |= HOST_CAP_FBS; |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 943cc8b83e59..ea83828bfea9 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -6314,6 +6314,8 @@ int ata_host_activate(struct ata_host *host, int irq, | |||
6314 | static void ata_port_detach(struct ata_port *ap) | 6314 | static void ata_port_detach(struct ata_port *ap) |
6315 | { | 6315 | { |
6316 | unsigned long flags; | 6316 | unsigned long flags; |
6317 | struct ata_link *link; | ||
6318 | struct ata_device *dev; | ||
6317 | 6319 | ||
6318 | if (!ap->ops->error_handler) | 6320 | if (!ap->ops->error_handler) |
6319 | goto skip_eh; | 6321 | goto skip_eh; |
@@ -6333,6 +6335,13 @@ static void ata_port_detach(struct ata_port *ap) | |||
6333 | cancel_delayed_work_sync(&ap->hotplug_task); | 6335 | cancel_delayed_work_sync(&ap->hotplug_task); |
6334 | 6336 | ||
6335 | skip_eh: | 6337 | skip_eh: |
6338 | /* clean up zpodd on port removal */ | ||
6339 | ata_for_each_link(link, ap, HOST_FIRST) { | ||
6340 | ata_for_each_dev(dev, link, ALL) { | ||
6341 | if (zpodd_dev_enabled(dev)) | ||
6342 | zpodd_exit(dev); | ||
6343 | } | ||
6344 | } | ||
6336 | if (ap->pmp_link) { | 6345 | if (ap->pmp_link) { |
6337 | int i; | 6346 | int i; |
6338 | for (i = 0; i < SATA_PMP_MAX_PORTS; i++) | 6347 | for (i = 0; i < SATA_PMP_MAX_PORTS; i++) |
diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index 293e2e0a0a87..00b73448b22e 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/of.h> | 56 | #include <linux/of.h> |
57 | #include <linux/of_address.h> | 57 | #include <linux/of_address.h> |
58 | #include <linux/debugfs.h> | 58 | #include <linux/debugfs.h> |
59 | #include <linux/log2.h> | ||
59 | 60 | ||
60 | /* | 61 | /* |
61 | * DDR target is the same on all platforms. | 62 | * DDR target is the same on all platforms. |
@@ -222,12 +223,6 @@ static int mvebu_mbus_window_conflicts(struct mvebu_mbus_state *mbus, | |||
222 | */ | 223 | */ |
223 | if ((u64)base < wend && end > wbase) | 224 | if ((u64)base < wend && end > wbase) |
224 | return 0; | 225 | return 0; |
225 | |||
226 | /* | ||
227 | * Check if target/attribute conflicts | ||
228 | */ | ||
229 | if (target == wtarget && attr == wattr) | ||
230 | return 0; | ||
231 | } | 226 | } |
232 | 227 | ||
233 | return 1; | 228 | return 1; |
@@ -266,6 +261,17 @@ static int mvebu_mbus_setup_window(struct mvebu_mbus_state *mbus, | |||
266 | mbus->soc->win_cfg_offset(win); | 261 | mbus->soc->win_cfg_offset(win); |
267 | u32 ctrl, remap_addr; | 262 | u32 ctrl, remap_addr; |
268 | 263 | ||
264 | if (!is_power_of_2(size)) { | ||
265 | WARN(true, "Invalid MBus window size: 0x%zx\n", size); | ||
266 | return -EINVAL; | ||
267 | } | ||
268 | |||
269 | if ((base & (phys_addr_t)(size - 1)) != 0) { | ||
270 | WARN(true, "Invalid MBus base/size: %pa len 0x%zx\n", &base, | ||
271 | size); | ||
272 | return -EINVAL; | ||
273 | } | ||
274 | |||
269 | ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) | | 275 | ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) | |
270 | (attr << WIN_CTRL_ATTR_SHIFT) | | 276 | (attr << WIN_CTRL_ATTR_SHIFT) | |
271 | (target << WIN_CTRL_TGT_SHIFT) | | 277 | (target << WIN_CTRL_TGT_SHIFT) | |
@@ -413,6 +419,10 @@ static int mvebu_devs_debug_show(struct seq_file *seq, void *v) | |||
413 | win, (unsigned long long)wbase, | 419 | win, (unsigned long long)wbase, |
414 | (unsigned long long)(wbase + wsize), wtarget, wattr); | 420 | (unsigned long long)(wbase + wsize), wtarget, wattr); |
415 | 421 | ||
422 | if (!is_power_of_2(wsize) || | ||
423 | ((wbase & (u64)(wsize - 1)) != 0)) | ||
424 | seq_puts(seq, " (Invalid base/size!!)"); | ||
425 | |||
416 | if (win < mbus->soc->num_remappable_wins) { | 426 | if (win < mbus->soc->num_remappable_wins) { |
417 | seq_printf(seq, " (remap %016llx)\n", | 427 | seq_printf(seq, " (remap %016llx)\n", |
418 | (unsigned long long)wremap); | 428 | (unsigned long long)wremap); |
diff --git a/drivers/char/random.c b/drivers/char/random.c index 6b75713d953a..102c50d38902 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -995,8 +995,11 @@ retry: | |||
995 | ibytes = min_t(size_t, ibytes, have_bytes - reserved); | 995 | ibytes = min_t(size_t, ibytes, have_bytes - reserved); |
996 | if (ibytes < min) | 996 | if (ibytes < min) |
997 | ibytes = 0; | 997 | ibytes = 0; |
998 | entropy_count = max_t(int, 0, | 998 | if (have_bytes >= ibytes + reserved) |
999 | entropy_count - (ibytes << (ENTROPY_SHIFT + 3))); | 999 | entropy_count -= ibytes << (ENTROPY_SHIFT + 3); |
1000 | else | ||
1001 | entropy_count = reserved << (ENTROPY_SHIFT + 3); | ||
1002 | |||
1000 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) | 1003 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) |
1001 | goto retry; | 1004 | goto retry; |
1002 | 1005 | ||
diff --git a/drivers/char/tpm/tpm_ppi.c b/drivers/char/tpm/tpm_ppi.c index b3ea223585bd..61dcc8011ec7 100644 --- a/drivers/char/tpm/tpm_ppi.c +++ b/drivers/char/tpm/tpm_ppi.c | |||
@@ -328,13 +328,11 @@ int tpm_add_ppi(struct kobject *parent) | |||
328 | /* Cache TPM ACPI handle and version string */ | 328 | /* Cache TPM ACPI handle and version string */ |
329 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, | 329 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, |
330 | ppi_callback, NULL, NULL, &tpm_ppi_handle); | 330 | ppi_callback, NULL, NULL, &tpm_ppi_handle); |
331 | if (tpm_ppi_handle == NULL) | 331 | return tpm_ppi_handle ? sysfs_create_group(parent, &ppi_attr_grp) : 0; |
332 | return -ENODEV; | ||
333 | |||
334 | return sysfs_create_group(parent, &ppi_attr_grp); | ||
335 | } | 332 | } |
336 | 333 | ||
337 | void tpm_remove_ppi(struct kobject *parent) | 334 | void tpm_remove_ppi(struct kobject *parent) |
338 | { | 335 | { |
339 | sysfs_remove_group(parent, &ppi_attr_grp); | 336 | if (tpm_ppi_handle) |
337 | sysfs_remove_group(parent, &ppi_attr_grp); | ||
340 | } | 338 | } |
diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c index c7607feb18dd..54a06526f64f 100644 --- a/drivers/clk/bcm/clk-kona-setup.c +++ b/drivers/clk/bcm/clk-kona-setup.c | |||
@@ -27,7 +27,7 @@ LIST_HEAD(ccu_list); /* The list of set up CCUs */ | |||
27 | 27 | ||
28 | static bool clk_requires_trigger(struct kona_clk *bcm_clk) | 28 | static bool clk_requires_trigger(struct kona_clk *bcm_clk) |
29 | { | 29 | { |
30 | struct peri_clk_data *peri = bcm_clk->peri; | 30 | struct peri_clk_data *peri = bcm_clk->u.peri; |
31 | struct bcm_clk_sel *sel; | 31 | struct bcm_clk_sel *sel; |
32 | struct bcm_clk_div *div; | 32 | struct bcm_clk_div *div; |
33 | 33 | ||
@@ -63,7 +63,7 @@ static bool peri_clk_data_offsets_valid(struct kona_clk *bcm_clk) | |||
63 | u32 limit; | 63 | u32 limit; |
64 | 64 | ||
65 | BUG_ON(bcm_clk->type != bcm_clk_peri); | 65 | BUG_ON(bcm_clk->type != bcm_clk_peri); |
66 | peri = bcm_clk->peri; | 66 | peri = bcm_clk->u.peri; |
67 | name = bcm_clk->name; | 67 | name = bcm_clk->name; |
68 | range = bcm_clk->ccu->range; | 68 | range = bcm_clk->ccu->range; |
69 | 69 | ||
@@ -81,19 +81,19 @@ static bool peri_clk_data_offsets_valid(struct kona_clk *bcm_clk) | |||
81 | 81 | ||
82 | div = &peri->div; | 82 | div = &peri->div; |
83 | if (divider_exists(div)) { | 83 | if (divider_exists(div)) { |
84 | if (div->offset > limit) { | 84 | if (div->u.s.offset > limit) { |
85 | pr_err("%s: bad divider offset for %s (%u > %u)\n", | 85 | pr_err("%s: bad divider offset for %s (%u > %u)\n", |
86 | __func__, name, div->offset, limit); | 86 | __func__, name, div->u.s.offset, limit); |
87 | return false; | 87 | return false; |
88 | } | 88 | } |
89 | } | 89 | } |
90 | 90 | ||
91 | div = &peri->pre_div; | 91 | div = &peri->pre_div; |
92 | if (divider_exists(div)) { | 92 | if (divider_exists(div)) { |
93 | if (div->offset > limit) { | 93 | if (div->u.s.offset > limit) { |
94 | pr_err("%s: bad pre-divider offset for %s " | 94 | pr_err("%s: bad pre-divider offset for %s " |
95 | "(%u > %u)\n", | 95 | "(%u > %u)\n", |
96 | __func__, name, div->offset, limit); | 96 | __func__, name, div->u.s.offset, limit); |
97 | return false; | 97 | return false; |
98 | } | 98 | } |
99 | } | 99 | } |
@@ -249,21 +249,22 @@ static bool div_valid(struct bcm_clk_div *div, const char *field_name, | |||
249 | { | 249 | { |
250 | if (divider_is_fixed(div)) { | 250 | if (divider_is_fixed(div)) { |
251 | /* Any fixed divider value but 0 is OK */ | 251 | /* Any fixed divider value but 0 is OK */ |
252 | if (div->fixed == 0) { | 252 | if (div->u.fixed == 0) { |
253 | pr_err("%s: bad %s fixed value 0 for %s\n", __func__, | 253 | pr_err("%s: bad %s fixed value 0 for %s\n", __func__, |
254 | field_name, clock_name); | 254 | field_name, clock_name); |
255 | return false; | 255 | return false; |
256 | } | 256 | } |
257 | return true; | 257 | return true; |
258 | } | 258 | } |
259 | if (!bitfield_valid(div->shift, div->width, field_name, clock_name)) | 259 | if (!bitfield_valid(div->u.s.shift, div->u.s.width, |
260 | field_name, clock_name)) | ||
260 | return false; | 261 | return false; |
261 | 262 | ||
262 | if (divider_has_fraction(div)) | 263 | if (divider_has_fraction(div)) |
263 | if (div->frac_width > div->width) { | 264 | if (div->u.s.frac_width > div->u.s.width) { |
264 | pr_warn("%s: bad %s fraction width for %s (%u > %u)\n", | 265 | pr_warn("%s: bad %s fraction width for %s (%u > %u)\n", |
265 | __func__, field_name, clock_name, | 266 | __func__, field_name, clock_name, |
266 | div->frac_width, div->width); | 267 | div->u.s.frac_width, div->u.s.width); |
267 | return false; | 268 | return false; |
268 | } | 269 | } |
269 | 270 | ||
@@ -278,7 +279,7 @@ static bool div_valid(struct bcm_clk_div *div, const char *field_name, | |||
278 | */ | 279 | */ |
279 | static bool kona_dividers_valid(struct kona_clk *bcm_clk) | 280 | static bool kona_dividers_valid(struct kona_clk *bcm_clk) |
280 | { | 281 | { |
281 | struct peri_clk_data *peri = bcm_clk->peri; | 282 | struct peri_clk_data *peri = bcm_clk->u.peri; |
282 | struct bcm_clk_div *div; | 283 | struct bcm_clk_div *div; |
283 | struct bcm_clk_div *pre_div; | 284 | struct bcm_clk_div *pre_div; |
284 | u32 limit; | 285 | u32 limit; |
@@ -295,7 +296,7 @@ static bool kona_dividers_valid(struct kona_clk *bcm_clk) | |||
295 | 296 | ||
296 | limit = BITS_PER_BYTE * sizeof(u32); | 297 | limit = BITS_PER_BYTE * sizeof(u32); |
297 | 298 | ||
298 | return div->frac_width + pre_div->frac_width <= limit; | 299 | return div->u.s.frac_width + pre_div->u.s.frac_width <= limit; |
299 | } | 300 | } |
300 | 301 | ||
301 | 302 | ||
@@ -328,7 +329,7 @@ peri_clk_data_valid(struct kona_clk *bcm_clk) | |||
328 | if (!peri_clk_data_offsets_valid(bcm_clk)) | 329 | if (!peri_clk_data_offsets_valid(bcm_clk)) |
329 | return false; | 330 | return false; |
330 | 331 | ||
331 | peri = bcm_clk->peri; | 332 | peri = bcm_clk->u.peri; |
332 | name = bcm_clk->name; | 333 | name = bcm_clk->name; |
333 | gate = &peri->gate; | 334 | gate = &peri->gate; |
334 | if (gate_exists(gate) && !gate_valid(gate, "gate", name)) | 335 | if (gate_exists(gate) && !gate_valid(gate, "gate", name)) |
@@ -588,12 +589,12 @@ static void bcm_clk_teardown(struct kona_clk *bcm_clk) | |||
588 | { | 589 | { |
589 | switch (bcm_clk->type) { | 590 | switch (bcm_clk->type) { |
590 | case bcm_clk_peri: | 591 | case bcm_clk_peri: |
591 | peri_clk_teardown(bcm_clk->data, &bcm_clk->init_data); | 592 | peri_clk_teardown(bcm_clk->u.data, &bcm_clk->init_data); |
592 | break; | 593 | break; |
593 | default: | 594 | default: |
594 | break; | 595 | break; |
595 | } | 596 | } |
596 | bcm_clk->data = NULL; | 597 | bcm_clk->u.data = NULL; |
597 | bcm_clk->type = bcm_clk_none; | 598 | bcm_clk->type = bcm_clk_none; |
598 | } | 599 | } |
599 | 600 | ||
@@ -644,7 +645,7 @@ struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name, | |||
644 | break; | 645 | break; |
645 | } | 646 | } |
646 | bcm_clk->type = type; | 647 | bcm_clk->type = type; |
647 | bcm_clk->data = data; | 648 | bcm_clk->u.data = data; |
648 | 649 | ||
649 | /* Make sure everything makes sense before we set it up */ | 650 | /* Make sure everything makes sense before we set it up */ |
650 | if (!kona_clk_valid(bcm_clk)) { | 651 | if (!kona_clk_valid(bcm_clk)) { |
diff --git a/drivers/clk/bcm/clk-kona.c b/drivers/clk/bcm/clk-kona.c index e3d339e08309..db11a87449f2 100644 --- a/drivers/clk/bcm/clk-kona.c +++ b/drivers/clk/bcm/clk-kona.c | |||
@@ -61,7 +61,7 @@ u64 do_div_round_closest(u64 dividend, unsigned long divisor) | |||
61 | /* Convert a divider into the scaled divisor value it represents. */ | 61 | /* Convert a divider into the scaled divisor value it represents. */ |
62 | static inline u64 scaled_div_value(struct bcm_clk_div *div, u32 reg_div) | 62 | static inline u64 scaled_div_value(struct bcm_clk_div *div, u32 reg_div) |
63 | { | 63 | { |
64 | return (u64)reg_div + ((u64)1 << div->frac_width); | 64 | return (u64)reg_div + ((u64)1 << div->u.s.frac_width); |
65 | } | 65 | } |
66 | 66 | ||
67 | /* | 67 | /* |
@@ -77,7 +77,7 @@ u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, u32 billionths) | |||
77 | BUG_ON(billionths >= BILLION); | 77 | BUG_ON(billionths >= BILLION); |
78 | 78 | ||
79 | combined = (u64)div_value * BILLION + billionths; | 79 | combined = (u64)div_value * BILLION + billionths; |
80 | combined <<= div->frac_width; | 80 | combined <<= div->u.s.frac_width; |
81 | 81 | ||
82 | return do_div_round_closest(combined, BILLION); | 82 | return do_div_round_closest(combined, BILLION); |
83 | } | 83 | } |
@@ -87,7 +87,7 @@ static inline u64 | |||
87 | scaled_div_min(struct bcm_clk_div *div) | 87 | scaled_div_min(struct bcm_clk_div *div) |
88 | { | 88 | { |
89 | if (divider_is_fixed(div)) | 89 | if (divider_is_fixed(div)) |
90 | return (u64)div->fixed; | 90 | return (u64)div->u.fixed; |
91 | 91 | ||
92 | return scaled_div_value(div, 0); | 92 | return scaled_div_value(div, 0); |
93 | } | 93 | } |
@@ -98,9 +98,9 @@ u64 scaled_div_max(struct bcm_clk_div *div) | |||
98 | u32 reg_div; | 98 | u32 reg_div; |
99 | 99 | ||
100 | if (divider_is_fixed(div)) | 100 | if (divider_is_fixed(div)) |
101 | return (u64)div->fixed; | 101 | return (u64)div->u.fixed; |
102 | 102 | ||
103 | reg_div = ((u32)1 << div->width) - 1; | 103 | reg_div = ((u32)1 << div->u.s.width) - 1; |
104 | 104 | ||
105 | return scaled_div_value(div, reg_div); | 105 | return scaled_div_value(div, reg_div); |
106 | } | 106 | } |
@@ -115,7 +115,7 @@ divider(struct bcm_clk_div *div, u64 scaled_div) | |||
115 | BUG_ON(scaled_div < scaled_div_min(div)); | 115 | BUG_ON(scaled_div < scaled_div_min(div)); |
116 | BUG_ON(scaled_div > scaled_div_max(div)); | 116 | BUG_ON(scaled_div > scaled_div_max(div)); |
117 | 117 | ||
118 | return (u32)(scaled_div - ((u64)1 << div->frac_width)); | 118 | return (u32)(scaled_div - ((u64)1 << div->u.s.frac_width)); |
119 | } | 119 | } |
120 | 120 | ||
121 | /* Return a rate scaled for use when dividing by a scaled divisor. */ | 121 | /* Return a rate scaled for use when dividing by a scaled divisor. */ |
@@ -125,7 +125,7 @@ scale_rate(struct bcm_clk_div *div, u32 rate) | |||
125 | if (divider_is_fixed(div)) | 125 | if (divider_is_fixed(div)) |
126 | return (u64)rate; | 126 | return (u64)rate; |
127 | 127 | ||
128 | return (u64)rate << div->frac_width; | 128 | return (u64)rate << div->u.s.frac_width; |
129 | } | 129 | } |
130 | 130 | ||
131 | /* CCU access */ | 131 | /* CCU access */ |
@@ -398,14 +398,14 @@ static u64 divider_read_scaled(struct ccu_data *ccu, struct bcm_clk_div *div) | |||
398 | u32 reg_div; | 398 | u32 reg_div; |
399 | 399 | ||
400 | if (divider_is_fixed(div)) | 400 | if (divider_is_fixed(div)) |
401 | return (u64)div->fixed; | 401 | return (u64)div->u.fixed; |
402 | 402 | ||
403 | flags = ccu_lock(ccu); | 403 | flags = ccu_lock(ccu); |
404 | reg_val = __ccu_read(ccu, div->offset); | 404 | reg_val = __ccu_read(ccu, div->u.s.offset); |
405 | ccu_unlock(ccu, flags); | 405 | ccu_unlock(ccu, flags); |
406 | 406 | ||
407 | /* Extract the full divider field from the register value */ | 407 | /* Extract the full divider field from the register value */ |
408 | reg_div = bitfield_extract(reg_val, div->shift, div->width); | 408 | reg_div = bitfield_extract(reg_val, div->u.s.shift, div->u.s.width); |
409 | 409 | ||
410 | /* Return the scaled divisor value it represents */ | 410 | /* Return the scaled divisor value it represents */ |
411 | return scaled_div_value(div, reg_div); | 411 | return scaled_div_value(div, reg_div); |
@@ -433,16 +433,17 @@ static int __div_commit(struct ccu_data *ccu, struct bcm_clk_gate *gate, | |||
433 | * state was defined in the device tree, we just find out | 433 | * state was defined in the device tree, we just find out |
434 | * what its current value is rather than updating it. | 434 | * what its current value is rather than updating it. |
435 | */ | 435 | */ |
436 | if (div->scaled_div == BAD_SCALED_DIV_VALUE) { | 436 | if (div->u.s.scaled_div == BAD_SCALED_DIV_VALUE) { |
437 | reg_val = __ccu_read(ccu, div->offset); | 437 | reg_val = __ccu_read(ccu, div->u.s.offset); |
438 | reg_div = bitfield_extract(reg_val, div->shift, div->width); | 438 | reg_div = bitfield_extract(reg_val, div->u.s.shift, |
439 | div->scaled_div = scaled_div_value(div, reg_div); | 439 | div->u.s.width); |
440 | div->u.s.scaled_div = scaled_div_value(div, reg_div); | ||
440 | 441 | ||
441 | return 0; | 442 | return 0; |
442 | } | 443 | } |
443 | 444 | ||
444 | /* Convert the scaled divisor to the value we need to record */ | 445 | /* Convert the scaled divisor to the value we need to record */ |
445 | reg_div = divider(div, div->scaled_div); | 446 | reg_div = divider(div, div->u.s.scaled_div); |
446 | 447 | ||
447 | /* Clock needs to be enabled before changing the rate */ | 448 | /* Clock needs to be enabled before changing the rate */ |
448 | enabled = __is_clk_gate_enabled(ccu, gate); | 449 | enabled = __is_clk_gate_enabled(ccu, gate); |
@@ -452,9 +453,10 @@ static int __div_commit(struct ccu_data *ccu, struct bcm_clk_gate *gate, | |||
452 | } | 453 | } |
453 | 454 | ||
454 | /* Replace the divider value and record the result */ | 455 | /* Replace the divider value and record the result */ |
455 | reg_val = __ccu_read(ccu, div->offset); | 456 | reg_val = __ccu_read(ccu, div->u.s.offset); |
456 | reg_val = bitfield_replace(reg_val, div->shift, div->width, reg_div); | 457 | reg_val = bitfield_replace(reg_val, div->u.s.shift, div->u.s.width, |
457 | __ccu_write(ccu, div->offset, reg_val); | 458 | reg_div); |
459 | __ccu_write(ccu, div->u.s.offset, reg_val); | ||
458 | 460 | ||
459 | /* If the trigger fails we still want to disable the gate */ | 461 | /* If the trigger fails we still want to disable the gate */ |
460 | if (!__clk_trigger(ccu, trig)) | 462 | if (!__clk_trigger(ccu, trig)) |
@@ -490,11 +492,11 @@ static int divider_write(struct ccu_data *ccu, struct bcm_clk_gate *gate, | |||
490 | 492 | ||
491 | BUG_ON(divider_is_fixed(div)); | 493 | BUG_ON(divider_is_fixed(div)); |
492 | 494 | ||
493 | previous = div->scaled_div; | 495 | previous = div->u.s.scaled_div; |
494 | if (previous == scaled_div) | 496 | if (previous == scaled_div) |
495 | return 0; /* No change */ | 497 | return 0; /* No change */ |
496 | 498 | ||
497 | div->scaled_div = scaled_div; | 499 | div->u.s.scaled_div = scaled_div; |
498 | 500 | ||
499 | flags = ccu_lock(ccu); | 501 | flags = ccu_lock(ccu); |
500 | __ccu_write_enable(ccu); | 502 | __ccu_write_enable(ccu); |
@@ -505,7 +507,7 @@ static int divider_write(struct ccu_data *ccu, struct bcm_clk_gate *gate, | |||
505 | ccu_unlock(ccu, flags); | 507 | ccu_unlock(ccu, flags); |
506 | 508 | ||
507 | if (ret) | 509 | if (ret) |
508 | div->scaled_div = previous; /* Revert the change */ | 510 | div->u.s.scaled_div = previous; /* Revert the change */ |
509 | 511 | ||
510 | return ret; | 512 | return ret; |
511 | 513 | ||
@@ -802,7 +804,7 @@ static int selector_write(struct ccu_data *ccu, struct bcm_clk_gate *gate, | |||
802 | static int kona_peri_clk_enable(struct clk_hw *hw) | 804 | static int kona_peri_clk_enable(struct clk_hw *hw) |
803 | { | 805 | { |
804 | struct kona_clk *bcm_clk = to_kona_clk(hw); | 806 | struct kona_clk *bcm_clk = to_kona_clk(hw); |
805 | struct bcm_clk_gate *gate = &bcm_clk->peri->gate; | 807 | struct bcm_clk_gate *gate = &bcm_clk->u.peri->gate; |
806 | 808 | ||
807 | return clk_gate(bcm_clk->ccu, bcm_clk->name, gate, true); | 809 | return clk_gate(bcm_clk->ccu, bcm_clk->name, gate, true); |
808 | } | 810 | } |
@@ -810,7 +812,7 @@ static int kona_peri_clk_enable(struct clk_hw *hw) | |||
810 | static void kona_peri_clk_disable(struct clk_hw *hw) | 812 | static void kona_peri_clk_disable(struct clk_hw *hw) |
811 | { | 813 | { |
812 | struct kona_clk *bcm_clk = to_kona_clk(hw); | 814 | struct kona_clk *bcm_clk = to_kona_clk(hw); |
813 | struct bcm_clk_gate *gate = &bcm_clk->peri->gate; | 815 | struct bcm_clk_gate *gate = &bcm_clk->u.peri->gate; |
814 | 816 | ||
815 | (void)clk_gate(bcm_clk->ccu, bcm_clk->name, gate, false); | 817 | (void)clk_gate(bcm_clk->ccu, bcm_clk->name, gate, false); |
816 | } | 818 | } |
@@ -818,7 +820,7 @@ static void kona_peri_clk_disable(struct clk_hw *hw) | |||
818 | static int kona_peri_clk_is_enabled(struct clk_hw *hw) | 820 | static int kona_peri_clk_is_enabled(struct clk_hw *hw) |
819 | { | 821 | { |
820 | struct kona_clk *bcm_clk = to_kona_clk(hw); | 822 | struct kona_clk *bcm_clk = to_kona_clk(hw); |
821 | struct bcm_clk_gate *gate = &bcm_clk->peri->gate; | 823 | struct bcm_clk_gate *gate = &bcm_clk->u.peri->gate; |
822 | 824 | ||
823 | return is_clk_gate_enabled(bcm_clk->ccu, gate) ? 1 : 0; | 825 | return is_clk_gate_enabled(bcm_clk->ccu, gate) ? 1 : 0; |
824 | } | 826 | } |
@@ -827,7 +829,7 @@ static unsigned long kona_peri_clk_recalc_rate(struct clk_hw *hw, | |||
827 | unsigned long parent_rate) | 829 | unsigned long parent_rate) |
828 | { | 830 | { |
829 | struct kona_clk *bcm_clk = to_kona_clk(hw); | 831 | struct kona_clk *bcm_clk = to_kona_clk(hw); |
830 | struct peri_clk_data *data = bcm_clk->peri; | 832 | struct peri_clk_data *data = bcm_clk->u.peri; |
831 | 833 | ||
832 | return clk_recalc_rate(bcm_clk->ccu, &data->div, &data->pre_div, | 834 | return clk_recalc_rate(bcm_clk->ccu, &data->div, &data->pre_div, |
833 | parent_rate); | 835 | parent_rate); |
@@ -837,20 +839,20 @@ static long kona_peri_clk_round_rate(struct clk_hw *hw, unsigned long rate, | |||
837 | unsigned long *parent_rate) | 839 | unsigned long *parent_rate) |
838 | { | 840 | { |
839 | struct kona_clk *bcm_clk = to_kona_clk(hw); | 841 | struct kona_clk *bcm_clk = to_kona_clk(hw); |
840 | struct bcm_clk_div *div = &bcm_clk->peri->div; | 842 | struct bcm_clk_div *div = &bcm_clk->u.peri->div; |
841 | 843 | ||
842 | if (!divider_exists(div)) | 844 | if (!divider_exists(div)) |
843 | return __clk_get_rate(hw->clk); | 845 | return __clk_get_rate(hw->clk); |
844 | 846 | ||
845 | /* Quietly avoid a zero rate */ | 847 | /* Quietly avoid a zero rate */ |
846 | return round_rate(bcm_clk->ccu, div, &bcm_clk->peri->pre_div, | 848 | return round_rate(bcm_clk->ccu, div, &bcm_clk->u.peri->pre_div, |
847 | rate ? rate : 1, *parent_rate, NULL); | 849 | rate ? rate : 1, *parent_rate, NULL); |
848 | } | 850 | } |
849 | 851 | ||
850 | static int kona_peri_clk_set_parent(struct clk_hw *hw, u8 index) | 852 | static int kona_peri_clk_set_parent(struct clk_hw *hw, u8 index) |
851 | { | 853 | { |
852 | struct kona_clk *bcm_clk = to_kona_clk(hw); | 854 | struct kona_clk *bcm_clk = to_kona_clk(hw); |
853 | struct peri_clk_data *data = bcm_clk->peri; | 855 | struct peri_clk_data *data = bcm_clk->u.peri; |
854 | struct bcm_clk_sel *sel = &data->sel; | 856 | struct bcm_clk_sel *sel = &data->sel; |
855 | struct bcm_clk_trig *trig; | 857 | struct bcm_clk_trig *trig; |
856 | int ret; | 858 | int ret; |
@@ -884,7 +886,7 @@ static int kona_peri_clk_set_parent(struct clk_hw *hw, u8 index) | |||
884 | static u8 kona_peri_clk_get_parent(struct clk_hw *hw) | 886 | static u8 kona_peri_clk_get_parent(struct clk_hw *hw) |
885 | { | 887 | { |
886 | struct kona_clk *bcm_clk = to_kona_clk(hw); | 888 | struct kona_clk *bcm_clk = to_kona_clk(hw); |
887 | struct peri_clk_data *data = bcm_clk->peri; | 889 | struct peri_clk_data *data = bcm_clk->u.peri; |
888 | u8 index; | 890 | u8 index; |
889 | 891 | ||
890 | index = selector_read_index(bcm_clk->ccu, &data->sel); | 892 | index = selector_read_index(bcm_clk->ccu, &data->sel); |
@@ -897,7 +899,7 @@ static int kona_peri_clk_set_rate(struct clk_hw *hw, unsigned long rate, | |||
897 | unsigned long parent_rate) | 899 | unsigned long parent_rate) |
898 | { | 900 | { |
899 | struct kona_clk *bcm_clk = to_kona_clk(hw); | 901 | struct kona_clk *bcm_clk = to_kona_clk(hw); |
900 | struct peri_clk_data *data = bcm_clk->peri; | 902 | struct peri_clk_data *data = bcm_clk->u.peri; |
901 | struct bcm_clk_div *div = &data->div; | 903 | struct bcm_clk_div *div = &data->div; |
902 | u64 scaled_div = 0; | 904 | u64 scaled_div = 0; |
903 | int ret; | 905 | int ret; |
@@ -958,7 +960,7 @@ struct clk_ops kona_peri_clk_ops = { | |||
958 | static bool __peri_clk_init(struct kona_clk *bcm_clk) | 960 | static bool __peri_clk_init(struct kona_clk *bcm_clk) |
959 | { | 961 | { |
960 | struct ccu_data *ccu = bcm_clk->ccu; | 962 | struct ccu_data *ccu = bcm_clk->ccu; |
961 | struct peri_clk_data *peri = bcm_clk->peri; | 963 | struct peri_clk_data *peri = bcm_clk->u.peri; |
962 | const char *name = bcm_clk->name; | 964 | const char *name = bcm_clk->name; |
963 | struct bcm_clk_trig *trig; | 965 | struct bcm_clk_trig *trig; |
964 | 966 | ||
diff --git a/drivers/clk/bcm/clk-kona.h b/drivers/clk/bcm/clk-kona.h index 5e139adc3dc5..dee690951bb6 100644 --- a/drivers/clk/bcm/clk-kona.h +++ b/drivers/clk/bcm/clk-kona.h | |||
@@ -57,7 +57,7 @@ | |||
57 | #define divider_exists(div) FLAG_TEST(div, DIV, EXISTS) | 57 | #define divider_exists(div) FLAG_TEST(div, DIV, EXISTS) |
58 | #define divider_is_fixed(div) FLAG_TEST(div, DIV, FIXED) | 58 | #define divider_is_fixed(div) FLAG_TEST(div, DIV, FIXED) |
59 | #define divider_has_fraction(div) (!divider_is_fixed(div) && \ | 59 | #define divider_has_fraction(div) (!divider_is_fixed(div) && \ |
60 | (div)->frac_width > 0) | 60 | (div)->u.s.frac_width > 0) |
61 | 61 | ||
62 | #define selector_exists(sel) ((sel)->width != 0) | 62 | #define selector_exists(sel) ((sel)->width != 0) |
63 | #define trigger_exists(trig) FLAG_TEST(trig, TRIG, EXISTS) | 63 | #define trigger_exists(trig) FLAG_TEST(trig, TRIG, EXISTS) |
@@ -244,9 +244,9 @@ struct bcm_clk_div { | |||
244 | u32 frac_width; /* field fraction width */ | 244 | u32 frac_width; /* field fraction width */ |
245 | 245 | ||
246 | u64 scaled_div; /* scaled divider value */ | 246 | u64 scaled_div; /* scaled divider value */ |
247 | }; | 247 | } s; |
248 | u32 fixed; /* non-zero fixed divider value */ | 248 | u32 fixed; /* non-zero fixed divider value */ |
249 | }; | 249 | } u; |
250 | u32 flags; /* BCM_CLK_DIV_FLAGS_* below */ | 250 | u32 flags; /* BCM_CLK_DIV_FLAGS_* below */ |
251 | }; | 251 | }; |
252 | 252 | ||
@@ -263,28 +263,28 @@ struct bcm_clk_div { | |||
263 | /* A fixed (non-zero) divider */ | 263 | /* A fixed (non-zero) divider */ |
264 | #define FIXED_DIVIDER(_value) \ | 264 | #define FIXED_DIVIDER(_value) \ |
265 | { \ | 265 | { \ |
266 | .fixed = (_value), \ | 266 | .u.fixed = (_value), \ |
267 | .flags = FLAG(DIV, EXISTS)|FLAG(DIV, FIXED), \ | 267 | .flags = FLAG(DIV, EXISTS)|FLAG(DIV, FIXED), \ |
268 | } | 268 | } |
269 | 269 | ||
270 | /* A divider with an integral divisor */ | 270 | /* A divider with an integral divisor */ |
271 | #define DIVIDER(_offset, _shift, _width) \ | 271 | #define DIVIDER(_offset, _shift, _width) \ |
272 | { \ | 272 | { \ |
273 | .offset = (_offset), \ | 273 | .u.s.offset = (_offset), \ |
274 | .shift = (_shift), \ | 274 | .u.s.shift = (_shift), \ |
275 | .width = (_width), \ | 275 | .u.s.width = (_width), \ |
276 | .scaled_div = BAD_SCALED_DIV_VALUE, \ | 276 | .u.s.scaled_div = BAD_SCALED_DIV_VALUE, \ |
277 | .flags = FLAG(DIV, EXISTS), \ | 277 | .flags = FLAG(DIV, EXISTS), \ |
278 | } | 278 | } |
279 | 279 | ||
280 | /* A divider whose divisor has an integer and fractional part */ | 280 | /* A divider whose divisor has an integer and fractional part */ |
281 | #define FRAC_DIVIDER(_offset, _shift, _width, _frac_width) \ | 281 | #define FRAC_DIVIDER(_offset, _shift, _width, _frac_width) \ |
282 | { \ | 282 | { \ |
283 | .offset = (_offset), \ | 283 | .u.s.offset = (_offset), \ |
284 | .shift = (_shift), \ | 284 | .u.s.shift = (_shift), \ |
285 | .width = (_width), \ | 285 | .u.s.width = (_width), \ |
286 | .frac_width = (_frac_width), \ | 286 | .u.s.frac_width = (_frac_width), \ |
287 | .scaled_div = BAD_SCALED_DIV_VALUE, \ | 287 | .u.s.scaled_div = BAD_SCALED_DIV_VALUE, \ |
288 | .flags = FLAG(DIV, EXISTS), \ | 288 | .flags = FLAG(DIV, EXISTS), \ |
289 | } | 289 | } |
290 | 290 | ||
@@ -380,7 +380,7 @@ struct kona_clk { | |||
380 | union { | 380 | union { |
381 | void *data; | 381 | void *data; |
382 | struct peri_clk_data *peri; | 382 | struct peri_clk_data *peri; |
383 | }; | 383 | } u; |
384 | }; | 384 | }; |
385 | #define to_kona_clk(_hw) \ | 385 | #define to_kona_clk(_hw) \ |
386 | container_of(_hw, struct kona_clk, hw) | 386 | container_of(_hw, struct kona_clk, hw) |
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index ec22112e569f..4637697c139f 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c | |||
@@ -144,6 +144,37 @@ static bool _is_valid_div(struct clk_divider *divider, unsigned int div) | |||
144 | return true; | 144 | return true; |
145 | } | 145 | } |
146 | 146 | ||
147 | static int _round_up_table(const struct clk_div_table *table, int div) | ||
148 | { | ||
149 | const struct clk_div_table *clkt; | ||
150 | int up = _get_table_maxdiv(table); | ||
151 | |||
152 | for (clkt = table; clkt->div; clkt++) { | ||
153 | if (clkt->div == div) | ||
154 | return clkt->div; | ||
155 | else if (clkt->div < div) | ||
156 | continue; | ||
157 | |||
158 | if ((clkt->div - div) < (up - div)) | ||
159 | up = clkt->div; | ||
160 | } | ||
161 | |||
162 | return up; | ||
163 | } | ||
164 | |||
165 | static int _div_round_up(struct clk_divider *divider, | ||
166 | unsigned long parent_rate, unsigned long rate) | ||
167 | { | ||
168 | int div = DIV_ROUND_UP(parent_rate, rate); | ||
169 | |||
170 | if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) | ||
171 | div = __roundup_pow_of_two(div); | ||
172 | if (divider->table) | ||
173 | div = _round_up_table(divider->table, div); | ||
174 | |||
175 | return div; | ||
176 | } | ||
177 | |||
147 | static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, | 178 | static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, |
148 | unsigned long *best_parent_rate) | 179 | unsigned long *best_parent_rate) |
149 | { | 180 | { |
@@ -159,7 +190,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, | |||
159 | 190 | ||
160 | if (!(__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT)) { | 191 | if (!(__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT)) { |
161 | parent_rate = *best_parent_rate; | 192 | parent_rate = *best_parent_rate; |
162 | bestdiv = DIV_ROUND_UP(parent_rate, rate); | 193 | bestdiv = _div_round_up(divider, parent_rate, rate); |
163 | bestdiv = bestdiv == 0 ? 1 : bestdiv; | 194 | bestdiv = bestdiv == 0 ? 1 : bestdiv; |
164 | bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv; | 195 | bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv; |
165 | return bestdiv; | 196 | return bestdiv; |
@@ -219,6 +250,10 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, | |||
219 | u32 val; | 250 | u32 val; |
220 | 251 | ||
221 | div = DIV_ROUND_UP(parent_rate, rate); | 252 | div = DIV_ROUND_UP(parent_rate, rate); |
253 | |||
254 | if (!_is_valid_div(divider, div)) | ||
255 | return -EINVAL; | ||
256 | |||
222 | value = _get_val(divider, div); | 257 | value = _get_val(divider, div); |
223 | 258 | ||
224 | if (value > div_mask(divider)) | 259 | if (value > div_mask(divider)) |
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index dff0373f53c1..7cf2c093cc54 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -1984,9 +1984,28 @@ struct clk *__clk_register(struct device *dev, struct clk_hw *hw) | |||
1984 | } | 1984 | } |
1985 | EXPORT_SYMBOL_GPL(__clk_register); | 1985 | EXPORT_SYMBOL_GPL(__clk_register); |
1986 | 1986 | ||
1987 | static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) | 1987 | /** |
1988 | * clk_register - allocate a new clock, register it and return an opaque cookie | ||
1989 | * @dev: device that is registering this clock | ||
1990 | * @hw: link to hardware-specific clock data | ||
1991 | * | ||
1992 | * clk_register is the primary interface for populating the clock tree with new | ||
1993 | * clock nodes. It returns a pointer to the newly allocated struct clk which | ||
1994 | * cannot be dereferenced by driver code but may be used in conjuction with the | ||
1995 | * rest of the clock API. In the event of an error clk_register will return an | ||
1996 | * error code; drivers must test for an error code after calling clk_register. | ||
1997 | */ | ||
1998 | struct clk *clk_register(struct device *dev, struct clk_hw *hw) | ||
1988 | { | 1999 | { |
1989 | int i, ret; | 2000 | int i, ret; |
2001 | struct clk *clk; | ||
2002 | |||
2003 | clk = kzalloc(sizeof(*clk), GFP_KERNEL); | ||
2004 | if (!clk) { | ||
2005 | pr_err("%s: could not allocate clk\n", __func__); | ||
2006 | ret = -ENOMEM; | ||
2007 | goto fail_out; | ||
2008 | } | ||
1990 | 2009 | ||
1991 | clk->name = kstrdup(hw->init->name, GFP_KERNEL); | 2010 | clk->name = kstrdup(hw->init->name, GFP_KERNEL); |
1992 | if (!clk->name) { | 2011 | if (!clk->name) { |
@@ -2026,7 +2045,7 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) | |||
2026 | 2045 | ||
2027 | ret = __clk_init(dev, clk); | 2046 | ret = __clk_init(dev, clk); |
2028 | if (!ret) | 2047 | if (!ret) |
2029 | return 0; | 2048 | return clk; |
2030 | 2049 | ||
2031 | fail_parent_names_copy: | 2050 | fail_parent_names_copy: |
2032 | while (--i >= 0) | 2051 | while (--i >= 0) |
@@ -2035,36 +2054,6 @@ fail_parent_names_copy: | |||
2035 | fail_parent_names: | 2054 | fail_parent_names: |
2036 | kfree(clk->name); | 2055 | kfree(clk->name); |
2037 | fail_name: | 2056 | fail_name: |
2038 | return ret; | ||
2039 | } | ||
2040 | |||
2041 | /** | ||
2042 | * clk_register - allocate a new clock, register it and return an opaque cookie | ||
2043 | * @dev: device that is registering this clock | ||
2044 | * @hw: link to hardware-specific clock data | ||
2045 | * | ||
2046 | * clk_register is the primary interface for populating the clock tree with new | ||
2047 | * clock nodes. It returns a pointer to the newly allocated struct clk which | ||
2048 | * cannot be dereferenced by driver code but may be used in conjuction with the | ||
2049 | * rest of the clock API. In the event of an error clk_register will return an | ||
2050 | * error code; drivers must test for an error code after calling clk_register. | ||
2051 | */ | ||
2052 | struct clk *clk_register(struct device *dev, struct clk_hw *hw) | ||
2053 | { | ||
2054 | int ret; | ||
2055 | struct clk *clk; | ||
2056 | |||
2057 | clk = kzalloc(sizeof(*clk), GFP_KERNEL); | ||
2058 | if (!clk) { | ||
2059 | pr_err("%s: could not allocate clk\n", __func__); | ||
2060 | ret = -ENOMEM; | ||
2061 | goto fail_out; | ||
2062 | } | ||
2063 | |||
2064 | ret = _clk_register(dev, hw, clk); | ||
2065 | if (!ret) | ||
2066 | return clk; | ||
2067 | |||
2068 | kfree(clk); | 2057 | kfree(clk); |
2069 | fail_out: | 2058 | fail_out: |
2070 | return ERR_PTR(ret); | 2059 | return ERR_PTR(ret); |
@@ -2151,9 +2140,10 @@ void clk_unregister(struct clk *clk) | |||
2151 | 2140 | ||
2152 | if (!hlist_empty(&clk->children)) { | 2141 | if (!hlist_empty(&clk->children)) { |
2153 | struct clk *child; | 2142 | struct clk *child; |
2143 | struct hlist_node *t; | ||
2154 | 2144 | ||
2155 | /* Reparent all children to the orphan list. */ | 2145 | /* Reparent all children to the orphan list. */ |
2156 | hlist_for_each_entry(child, &clk->children, child_node) | 2146 | hlist_for_each_entry_safe(child, t, &clk->children, child_node) |
2157 | clk_set_parent(child, NULL); | 2147 | clk_set_parent(child, NULL); |
2158 | } | 2148 | } |
2159 | 2149 | ||
@@ -2173,7 +2163,7 @@ EXPORT_SYMBOL_GPL(clk_unregister); | |||
2173 | 2163 | ||
2174 | static void devm_clk_release(struct device *dev, void *res) | 2164 | static void devm_clk_release(struct device *dev, void *res) |
2175 | { | 2165 | { |
2176 | clk_unregister(res); | 2166 | clk_unregister(*(struct clk **)res); |
2177 | } | 2167 | } |
2178 | 2168 | ||
2179 | /** | 2169 | /** |
@@ -2188,18 +2178,18 @@ static void devm_clk_release(struct device *dev, void *res) | |||
2188 | struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw) | 2178 | struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw) |
2189 | { | 2179 | { |
2190 | struct clk *clk; | 2180 | struct clk *clk; |
2191 | int ret; | 2181 | struct clk **clkp; |
2192 | 2182 | ||
2193 | clk = devres_alloc(devm_clk_release, sizeof(*clk), GFP_KERNEL); | 2183 | clkp = devres_alloc(devm_clk_release, sizeof(*clkp), GFP_KERNEL); |
2194 | if (!clk) | 2184 | if (!clkp) |
2195 | return ERR_PTR(-ENOMEM); | 2185 | return ERR_PTR(-ENOMEM); |
2196 | 2186 | ||
2197 | ret = _clk_register(dev, hw, clk); | 2187 | clk = clk_register(dev, hw); |
2198 | if (!ret) { | 2188 | if (!IS_ERR(clk)) { |
2199 | devres_add(dev, clk); | 2189 | *clkp = clk; |
2190 | devres_add(dev, clkp); | ||
2200 | } else { | 2191 | } else { |
2201 | devres_free(clk); | 2192 | devres_free(clkp); |
2202 | clk = ERR_PTR(ret); | ||
2203 | } | 2193 | } |
2204 | 2194 | ||
2205 | return clk; | 2195 | return clk; |
diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/shmobile/clk-mstp.c index 2e5810c88d11..1f6324e29a80 100644 --- a/drivers/clk/shmobile/clk-mstp.c +++ b/drivers/clk/shmobile/clk-mstp.c | |||
@@ -156,6 +156,7 @@ cpg_mstp_clock_register(const char *name, const char *parent_name, | |||
156 | static void __init cpg_mstp_clocks_init(struct device_node *np) | 156 | static void __init cpg_mstp_clocks_init(struct device_node *np) |
157 | { | 157 | { |
158 | struct mstp_clock_group *group; | 158 | struct mstp_clock_group *group; |
159 | const char *idxname; | ||
159 | struct clk **clks; | 160 | struct clk **clks; |
160 | unsigned int i; | 161 | unsigned int i; |
161 | 162 | ||
@@ -184,6 +185,11 @@ static void __init cpg_mstp_clocks_init(struct device_node *np) | |||
184 | for (i = 0; i < MSTP_MAX_CLOCKS; ++i) | 185 | for (i = 0; i < MSTP_MAX_CLOCKS; ++i) |
185 | clks[i] = ERR_PTR(-ENOENT); | 186 | clks[i] = ERR_PTR(-ENOENT); |
186 | 187 | ||
188 | if (of_find_property(np, "clock-indices", &i)) | ||
189 | idxname = "clock-indices"; | ||
190 | else | ||
191 | idxname = "renesas,clock-indices"; | ||
192 | |||
187 | for (i = 0; i < MSTP_MAX_CLOCKS; ++i) { | 193 | for (i = 0; i < MSTP_MAX_CLOCKS; ++i) { |
188 | const char *parent_name; | 194 | const char *parent_name; |
189 | const char *name; | 195 | const char *name; |
@@ -197,8 +203,7 @@ static void __init cpg_mstp_clocks_init(struct device_node *np) | |||
197 | continue; | 203 | continue; |
198 | 204 | ||
199 | parent_name = of_clk_get_parent_name(np, i); | 205 | parent_name = of_clk_get_parent_name(np, i); |
200 | ret = of_property_read_u32_index(np, "renesas,clock-indices", i, | 206 | ret = of_property_read_u32_index(np, idxname, i, &clkidx); |
201 | &clkidx); | ||
202 | if (parent_name == NULL || ret < 0) | 207 | if (parent_name == NULL || ret < 0) |
203 | break; | 208 | break; |
204 | 209 | ||
diff --git a/drivers/clk/socfpga/clk-pll.c b/drivers/clk/socfpga/clk-pll.c index 88dafb5e9627..de6da957a09d 100644 --- a/drivers/clk/socfpga/clk-pll.c +++ b/drivers/clk/socfpga/clk-pll.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/clk-provider.h> | 20 | #include <linux/clk-provider.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/of.h> | 22 | #include <linux/of.h> |
23 | #include <linux/of_address.h> | ||
23 | 24 | ||
24 | #include "clk.h" | 25 | #include "clk.h" |
25 | 26 | ||
@@ -43,6 +44,8 @@ | |||
43 | 44 | ||
44 | #define to_socfpga_clk(p) container_of(p, struct socfpga_pll, hw.hw) | 45 | #define to_socfpga_clk(p) container_of(p, struct socfpga_pll, hw.hw) |
45 | 46 | ||
47 | void __iomem *clk_mgr_base_addr; | ||
48 | |||
46 | static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk, | 49 | static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk, |
47 | unsigned long parent_rate) | 50 | unsigned long parent_rate) |
48 | { | 51 | { |
@@ -87,6 +90,7 @@ static __init struct clk *__socfpga_pll_init(struct device_node *node, | |||
87 | const char *clk_name = node->name; | 90 | const char *clk_name = node->name; |
88 | const char *parent_name[SOCFPGA_MAX_PARENTS]; | 91 | const char *parent_name[SOCFPGA_MAX_PARENTS]; |
89 | struct clk_init_data init; | 92 | struct clk_init_data init; |
93 | struct device_node *clkmgr_np; | ||
90 | int rc; | 94 | int rc; |
91 | int i = 0; | 95 | int i = 0; |
92 | 96 | ||
@@ -96,6 +100,9 @@ static __init struct clk *__socfpga_pll_init(struct device_node *node, | |||
96 | if (WARN_ON(!pll_clk)) | 100 | if (WARN_ON(!pll_clk)) |
97 | return NULL; | 101 | return NULL; |
98 | 102 | ||
103 | clkmgr_np = of_find_compatible_node(NULL, NULL, "altr,clk-mgr"); | ||
104 | clk_mgr_base_addr = of_iomap(clkmgr_np, 0); | ||
105 | BUG_ON(!clk_mgr_base_addr); | ||
99 | pll_clk->hw.reg = clk_mgr_base_addr + reg; | 106 | pll_clk->hw.reg = clk_mgr_base_addr + reg; |
100 | 107 | ||
101 | of_property_read_string(node, "clock-output-names", &clk_name); | 108 | of_property_read_string(node, "clock-output-names", &clk_name); |
diff --git a/drivers/clk/socfpga/clk.c b/drivers/clk/socfpga/clk.c index 35a960a993f9..43db947e5f0e 100644 --- a/drivers/clk/socfpga/clk.c +++ b/drivers/clk/socfpga/clk.c | |||
@@ -17,28 +17,11 @@ | |||
17 | * You should have received a copy of the GNU General Public License | 17 | * You should have received a copy of the GNU General Public License |
18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | */ | 19 | */ |
20 | #include <linux/clk.h> | ||
21 | #include <linux/clkdev.h> | ||
22 | #include <linux/clk-provider.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/of.h> | 20 | #include <linux/of.h> |
25 | #include <linux/of_address.h> | ||
26 | 21 | ||
27 | #include "clk.h" | 22 | #include "clk.h" |
28 | 23 | ||
29 | void __iomem *clk_mgr_base_addr; | 24 | CLK_OF_DECLARE(socfpga_pll_clk, "altr,socfpga-pll-clock", socfpga_pll_init); |
30 | 25 | CLK_OF_DECLARE(socfpga_perip_clk, "altr,socfpga-perip-clk", socfpga_periph_init); | |
31 | static const struct of_device_id socfpga_child_clocks[] __initconst = { | 26 | CLK_OF_DECLARE(socfpga_gate_clk, "altr,socfpga-gate-clk", socfpga_gate_init); |
32 | { .compatible = "altr,socfpga-pll-clock", socfpga_pll_init, }, | ||
33 | { .compatible = "altr,socfpga-perip-clk", socfpga_periph_init, }, | ||
34 | { .compatible = "altr,socfpga-gate-clk", socfpga_gate_init, }, | ||
35 | {}, | ||
36 | }; | ||
37 | |||
38 | static void __init socfpga_clkmgr_init(struct device_node *node) | ||
39 | { | ||
40 | clk_mgr_base_addr = of_iomap(node, 0); | ||
41 | of_clk_init(socfpga_child_clocks); | ||
42 | } | ||
43 | CLK_OF_DECLARE(socfpga_mgr, "altr,clk-mgr", socfpga_clkmgr_init); | ||
44 | 27 | ||
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 0d20241e0770..e1769addf435 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c | |||
@@ -1718,7 +1718,7 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, | |||
1718 | "pll_re_vco"); | 1718 | "pll_re_vco"); |
1719 | } else { | 1719 | } else { |
1720 | val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL); | 1720 | val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL); |
1721 | pll_writel(val, pll_params->aux_reg, pll); | 1721 | pll_writel(val_aux, pll_params->aux_reg, pll); |
1722 | } | 1722 | } |
1723 | 1723 | ||
1724 | clk = _tegra_clk_register_pll(pll, name, parent_name, flags, | 1724 | clk = _tegra_clk_register_pll(pll, name, parent_name, flags, |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 099967302bf2..eab8ccfe6beb 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #define BYT_RATIOS 0x66a | 37 | #define BYT_RATIOS 0x66a |
38 | #define BYT_VIDS 0x66b | 38 | #define BYT_VIDS 0x66b |
39 | #define BYT_TURBO_RATIOS 0x66c | 39 | #define BYT_TURBO_RATIOS 0x66c |
40 | #define BYT_TURBO_VIDS 0x66d | ||
40 | 41 | ||
41 | 42 | ||
42 | #define FRAC_BITS 6 | 43 | #define FRAC_BITS 6 |
@@ -70,8 +71,9 @@ struct pstate_data { | |||
70 | }; | 71 | }; |
71 | 72 | ||
72 | struct vid_data { | 73 | struct vid_data { |
73 | int32_t min; | 74 | int min; |
74 | int32_t max; | 75 | int max; |
76 | int turbo; | ||
75 | int32_t ratio; | 77 | int32_t ratio; |
76 | }; | 78 | }; |
77 | 79 | ||
@@ -359,14 +361,14 @@ static int byt_get_min_pstate(void) | |||
359 | { | 361 | { |
360 | u64 value; | 362 | u64 value; |
361 | rdmsrl(BYT_RATIOS, value); | 363 | rdmsrl(BYT_RATIOS, value); |
362 | return (value >> 8) & 0xFF; | 364 | return (value >> 8) & 0x3F; |
363 | } | 365 | } |
364 | 366 | ||
365 | static int byt_get_max_pstate(void) | 367 | static int byt_get_max_pstate(void) |
366 | { | 368 | { |
367 | u64 value; | 369 | u64 value; |
368 | rdmsrl(BYT_RATIOS, value); | 370 | rdmsrl(BYT_RATIOS, value); |
369 | return (value >> 16) & 0xFF; | 371 | return (value >> 16) & 0x3F; |
370 | } | 372 | } |
371 | 373 | ||
372 | static int byt_get_turbo_pstate(void) | 374 | static int byt_get_turbo_pstate(void) |
@@ -393,6 +395,9 @@ static void byt_set_pstate(struct cpudata *cpudata, int pstate) | |||
393 | vid_fp = clamp_t(int32_t, vid_fp, cpudata->vid.min, cpudata->vid.max); | 395 | vid_fp = clamp_t(int32_t, vid_fp, cpudata->vid.min, cpudata->vid.max); |
394 | vid = fp_toint(vid_fp); | 396 | vid = fp_toint(vid_fp); |
395 | 397 | ||
398 | if (pstate > cpudata->pstate.max_pstate) | ||
399 | vid = cpudata->vid.turbo; | ||
400 | |||
396 | val |= vid; | 401 | val |= vid; |
397 | 402 | ||
398 | wrmsrl(MSR_IA32_PERF_CTL, val); | 403 | wrmsrl(MSR_IA32_PERF_CTL, val); |
@@ -402,13 +407,17 @@ static void byt_get_vid(struct cpudata *cpudata) | |||
402 | { | 407 | { |
403 | u64 value; | 408 | u64 value; |
404 | 409 | ||
410 | |||
405 | rdmsrl(BYT_VIDS, value); | 411 | rdmsrl(BYT_VIDS, value); |
406 | cpudata->vid.min = int_tofp((value >> 8) & 0x7f); | 412 | cpudata->vid.min = int_tofp((value >> 8) & 0x3f); |
407 | cpudata->vid.max = int_tofp((value >> 16) & 0x7f); | 413 | cpudata->vid.max = int_tofp((value >> 16) & 0x3f); |
408 | cpudata->vid.ratio = div_fp( | 414 | cpudata->vid.ratio = div_fp( |
409 | cpudata->vid.max - cpudata->vid.min, | 415 | cpudata->vid.max - cpudata->vid.min, |
410 | int_tofp(cpudata->pstate.max_pstate - | 416 | int_tofp(cpudata->pstate.max_pstate - |
411 | cpudata->pstate.min_pstate)); | 417 | cpudata->pstate.min_pstate)); |
418 | |||
419 | rdmsrl(BYT_TURBO_VIDS, value); | ||
420 | cpudata->vid.turbo = value & 0x7f; | ||
412 | } | 421 | } |
413 | 422 | ||
414 | 423 | ||
@@ -545,12 +554,7 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) | |||
545 | 554 | ||
546 | if (pstate_funcs.get_vid) | 555 | if (pstate_funcs.get_vid) |
547 | pstate_funcs.get_vid(cpu); | 556 | pstate_funcs.get_vid(cpu); |
548 | 557 | intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate); | |
549 | /* | ||
550 | * goto max pstate so we don't slow up boot if we are built-in if we are | ||
551 | * a module we will take care of it during normal operation | ||
552 | */ | ||
553 | intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate); | ||
554 | } | 558 | } |
555 | 559 | ||
556 | static inline void intel_pstate_calc_busy(struct cpudata *cpu, | 560 | static inline void intel_pstate_calc_busy(struct cpudata *cpu, |
@@ -695,11 +699,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum) | |||
695 | cpu = all_cpu_data[cpunum]; | 699 | cpu = all_cpu_data[cpunum]; |
696 | 700 | ||
697 | intel_pstate_get_cpu_pstates(cpu); | 701 | intel_pstate_get_cpu_pstates(cpu); |
698 | if (!cpu->pstate.current_pstate) { | ||
699 | all_cpu_data[cpunum] = NULL; | ||
700 | kfree(cpu); | ||
701 | return -ENODATA; | ||
702 | } | ||
703 | 702 | ||
704 | cpu->cpu = cpunum; | 703 | cpu->cpu = cpunum; |
705 | 704 | ||
@@ -710,7 +709,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum) | |||
710 | cpu->timer.expires = jiffies + HZ/100; | 709 | cpu->timer.expires = jiffies + HZ/100; |
711 | intel_pstate_busy_pid_reset(cpu); | 710 | intel_pstate_busy_pid_reset(cpu); |
712 | intel_pstate_sample(cpu); | 711 | intel_pstate_sample(cpu); |
713 | intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate); | ||
714 | 712 | ||
715 | add_timer_on(&cpu->timer, cpunum); | 713 | add_timer_on(&cpu->timer, cpunum); |
716 | 714 | ||
diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c index f0bc31f5db27..d4add8621944 100644 --- a/drivers/cpufreq/loongson2_cpufreq.c +++ b/drivers/cpufreq/loongson2_cpufreq.c | |||
@@ -62,7 +62,7 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy, | |||
62 | set_cpus_allowed_ptr(current, &cpus_allowed); | 62 | set_cpus_allowed_ptr(current, &cpus_allowed); |
63 | 63 | ||
64 | /* setting the cpu frequency */ | 64 | /* setting the cpu frequency */ |
65 | clk_set_rate(policy->clk, freq); | 65 | clk_set_rate(policy->clk, freq * 1000); |
66 | 66 | ||
67 | return 0; | 67 | return 0; |
68 | } | 68 | } |
@@ -92,7 +92,7 @@ static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
92 | i++) | 92 | i++) |
93 | loongson2_clockmod_table[i].frequency = (rate * i) / 8; | 93 | loongson2_clockmod_table[i].frequency = (rate * i) / 8; |
94 | 94 | ||
95 | ret = clk_set_rate(cpuclk, rate); | 95 | ret = clk_set_rate(cpuclk, rate * 1000); |
96 | if (ret) { | 96 | if (ret) { |
97 | clk_put(cpuclk); | 97 | clk_put(cpuclk); |
98 | return ret; | 98 | return ret; |
diff --git a/drivers/crypto/caam/error.c b/drivers/crypto/caam/error.c index 9f25f5296029..0eabd81e1a90 100644 --- a/drivers/crypto/caam/error.c +++ b/drivers/crypto/caam/error.c | |||
@@ -16,9 +16,13 @@ | |||
16 | char *tmp; \ | 16 | char *tmp; \ |
17 | \ | 17 | \ |
18 | tmp = kmalloc(sizeof(format) + max_alloc, GFP_ATOMIC); \ | 18 | tmp = kmalloc(sizeof(format) + max_alloc, GFP_ATOMIC); \ |
19 | sprintf(tmp, format, param); \ | 19 | if (likely(tmp)) { \ |
20 | strcat(str, tmp); \ | 20 | sprintf(tmp, format, param); \ |
21 | kfree(tmp); \ | 21 | strcat(str, tmp); \ |
22 | kfree(tmp); \ | ||
23 | } else { \ | ||
24 | strcat(str, "kmalloc failure in SPRINTFCAT"); \ | ||
25 | } \ | ||
22 | } | 26 | } |
23 | 27 | ||
24 | static void report_jump_idx(u32 status, char *outstr) | 28 | static void report_jump_idx(u32 status, char *outstr) |
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index c98764aeeec6..870044e82316 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h | |||
@@ -118,7 +118,6 @@ int fw_card_add(struct fw_card *card, | |||
118 | u32 max_receive, u32 link_speed, u64 guid); | 118 | u32 max_receive, u32 link_speed, u64 guid); |
119 | void fw_core_remove_card(struct fw_card *card); | 119 | void fw_core_remove_card(struct fw_card *card); |
120 | int fw_compute_block_crc(__be32 *block); | 120 | int fw_compute_block_crc(__be32 *block); |
121 | void fw_schedule_bus_reset(struct fw_card *card, bool delayed, bool short_reset); | ||
122 | void fw_schedule_bm_work(struct fw_card *card, unsigned long delay); | 121 | void fw_schedule_bm_work(struct fw_card *card, unsigned long delay); |
123 | 122 | ||
124 | /* -cdev */ | 123 | /* -cdev */ |
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c index 3ee852c9925b..071c2c969eec 100644 --- a/drivers/firmware/iscsi_ibft.c +++ b/drivers/firmware/iscsi_ibft.c | |||
@@ -756,6 +756,7 @@ static const struct { | |||
756 | */ | 756 | */ |
757 | { ACPI_SIG_IBFT }, | 757 | { ACPI_SIG_IBFT }, |
758 | { "iBFT" }, | 758 | { "iBFT" }, |
759 | { "BIFT" }, /* Broadcom iSCSI Offload */ | ||
759 | }; | 760 | }; |
760 | 761 | ||
761 | static void __init acpi_find_ibft_region(void) | 762 | static void __init acpi_find_ibft_region(void) |
diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c index e73c6755a5eb..70304220a479 100644 --- a/drivers/gpio/gpio-ich.c +++ b/drivers/gpio/gpio-ich.c | |||
@@ -305,6 +305,8 @@ static struct ichx_desc ich6_desc = { | |||
305 | 305 | ||
306 | .ngpio = 50, | 306 | .ngpio = 50, |
307 | .have_blink = true, | 307 | .have_blink = true, |
308 | .regs = ichx_regs, | ||
309 | .reglen = ichx_reglen, | ||
308 | }; | 310 | }; |
309 | 311 | ||
310 | /* Intel 3100 */ | 312 | /* Intel 3100 */ |
@@ -324,6 +326,8 @@ static struct ichx_desc i3100_desc = { | |||
324 | .uses_gpe0 = true, | 326 | .uses_gpe0 = true, |
325 | 327 | ||
326 | .ngpio = 50, | 328 | .ngpio = 50, |
329 | .regs = ichx_regs, | ||
330 | .reglen = ichx_reglen, | ||
327 | }; | 331 | }; |
328 | 332 | ||
329 | /* ICH7 and ICH8-based */ | 333 | /* ICH7 and ICH8-based */ |
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 99a68310e7c0..3d53fd6880d1 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c | |||
@@ -894,9 +894,11 @@ static int mcp23s08_probe(struct spi_device *spi) | |||
894 | dev_err(&spi->dev, "invalid spi-present-mask\n"); | 894 | dev_err(&spi->dev, "invalid spi-present-mask\n"); |
895 | return -ENODEV; | 895 | return -ENODEV; |
896 | } | 896 | } |
897 | 897 | for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) { | |
898 | for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) | 898 | if ((spi_present_mask & (1 << addr))) |
899 | chips++; | ||
899 | pullups[addr] = 0; | 900 | pullups[addr] = 0; |
901 | } | ||
900 | } else { | 902 | } else { |
901 | type = spi_get_device_id(spi)->driver_data; | 903 | type = spi_get_device_id(spi)->driver_data; |
902 | pdata = dev_get_platdata(&spi->dev); | 904 | pdata = dev_get_platdata(&spi->dev); |
@@ -919,12 +921,12 @@ static int mcp23s08_probe(struct spi_device *spi) | |||
919 | pullups[addr] = pdata->chip[addr].pullups; | 921 | pullups[addr] = pdata->chip[addr].pullups; |
920 | } | 922 | } |
921 | 923 | ||
922 | if (!chips) | ||
923 | return -ENODEV; | ||
924 | |||
925 | base = pdata->base; | 924 | base = pdata->base; |
926 | } | 925 | } |
927 | 926 | ||
927 | if (!chips) | ||
928 | return -ENODEV; | ||
929 | |||
928 | data = kzalloc(sizeof(*data) + chips * sizeof(struct mcp23s08), | 930 | data = kzalloc(sizeof(*data) + chips * sizeof(struct mcp23s08), |
929 | GFP_KERNEL); | 931 | GFP_KERNEL); |
930 | if (!data) | 932 | if (!data) |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index fa486c5fbb02..aff4a113cda3 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -560,47 +560,71 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb) | |||
560 | 560 | ||
561 | dev_priv->vbt.edp_pps = *edp_pps; | 561 | dev_priv->vbt.edp_pps = *edp_pps; |
562 | 562 | ||
563 | dev_priv->vbt.edp_rate = edp_link_params->rate ? DP_LINK_BW_2_7 : | 563 | switch (edp_link_params->rate) { |
564 | DP_LINK_BW_1_62; | 564 | case EDP_RATE_1_62: |
565 | dev_priv->vbt.edp_rate = DP_LINK_BW_1_62; | ||
566 | break; | ||
567 | case EDP_RATE_2_7: | ||
568 | dev_priv->vbt.edp_rate = DP_LINK_BW_2_7; | ||
569 | break; | ||
570 | default: | ||
571 | DRM_DEBUG_KMS("VBT has unknown eDP link rate value %u\n", | ||
572 | edp_link_params->rate); | ||
573 | break; | ||
574 | } | ||
575 | |||
565 | switch (edp_link_params->lanes) { | 576 | switch (edp_link_params->lanes) { |
566 | case 0: | 577 | case EDP_LANE_1: |
567 | dev_priv->vbt.edp_lanes = 1; | 578 | dev_priv->vbt.edp_lanes = 1; |
568 | break; | 579 | break; |
569 | case 1: | 580 | case EDP_LANE_2: |
570 | dev_priv->vbt.edp_lanes = 2; | 581 | dev_priv->vbt.edp_lanes = 2; |
571 | break; | 582 | break; |
572 | case 3: | 583 | case EDP_LANE_4: |
573 | default: | ||
574 | dev_priv->vbt.edp_lanes = 4; | 584 | dev_priv->vbt.edp_lanes = 4; |
575 | break; | 585 | break; |
586 | default: | ||
587 | DRM_DEBUG_KMS("VBT has unknown eDP lane count value %u\n", | ||
588 | edp_link_params->lanes); | ||
589 | break; | ||
576 | } | 590 | } |
591 | |||
577 | switch (edp_link_params->preemphasis) { | 592 | switch (edp_link_params->preemphasis) { |
578 | case 0: | 593 | case EDP_PREEMPHASIS_NONE: |
579 | dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_0; | 594 | dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_0; |
580 | break; | 595 | break; |
581 | case 1: | 596 | case EDP_PREEMPHASIS_3_5dB: |
582 | dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_3_5; | 597 | dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_3_5; |
583 | break; | 598 | break; |
584 | case 2: | 599 | case EDP_PREEMPHASIS_6dB: |
585 | dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_6; | 600 | dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_6; |
586 | break; | 601 | break; |
587 | case 3: | 602 | case EDP_PREEMPHASIS_9_5dB: |
588 | dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_9_5; | 603 | dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_9_5; |
589 | break; | 604 | break; |
605 | default: | ||
606 | DRM_DEBUG_KMS("VBT has unknown eDP pre-emphasis value %u\n", | ||
607 | edp_link_params->preemphasis); | ||
608 | break; | ||
590 | } | 609 | } |
610 | |||
591 | switch (edp_link_params->vswing) { | 611 | switch (edp_link_params->vswing) { |
592 | case 0: | 612 | case EDP_VSWING_0_4V: |
593 | dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_400; | 613 | dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_400; |
594 | break; | 614 | break; |
595 | case 1: | 615 | case EDP_VSWING_0_6V: |
596 | dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_600; | 616 | dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_600; |
597 | break; | 617 | break; |
598 | case 2: | 618 | case EDP_VSWING_0_8V: |
599 | dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_800; | 619 | dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_800; |
600 | break; | 620 | break; |
601 | case 3: | 621 | case EDP_VSWING_1_2V: |
602 | dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_1200; | 622 | dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_1200; |
603 | break; | 623 | break; |
624 | default: | ||
625 | DRM_DEBUG_KMS("VBT has unknown eDP voltage swing value %u\n", | ||
626 | edp_link_params->vswing); | ||
627 | break; | ||
604 | } | 628 | } |
605 | } | 629 | } |
606 | 630 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5ca68aa9f237..2a00cb828d20 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -121,6 +121,22 @@ intel_dp_max_link_bw(struct intel_dp *intel_dp) | |||
121 | return max_link_bw; | 121 | return max_link_bw; |
122 | } | 122 | } |
123 | 123 | ||
124 | static u8 intel_dp_max_lane_count(struct intel_dp *intel_dp) | ||
125 | { | ||
126 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | ||
127 | struct drm_device *dev = intel_dig_port->base.base.dev; | ||
128 | u8 source_max, sink_max; | ||
129 | |||
130 | source_max = 4; | ||
131 | if (HAS_DDI(dev) && intel_dig_port->port == PORT_A && | ||
132 | (intel_dig_port->saved_port_bits & DDI_A_4_LANES) == 0) | ||
133 | source_max = 2; | ||
134 | |||
135 | sink_max = drm_dp_max_lane_count(intel_dp->dpcd); | ||
136 | |||
137 | return min(source_max, sink_max); | ||
138 | } | ||
139 | |||
124 | /* | 140 | /* |
125 | * The units on the numbers in the next two are... bizarre. Examples will | 141 | * The units on the numbers in the next two are... bizarre. Examples will |
126 | * make it clearer; this one parallels an example in the eDP spec. | 142 | * make it clearer; this one parallels an example in the eDP spec. |
@@ -171,7 +187,7 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
171 | } | 187 | } |
172 | 188 | ||
173 | max_link_clock = drm_dp_bw_code_to_link_rate(intel_dp_max_link_bw(intel_dp)); | 189 | max_link_clock = drm_dp_bw_code_to_link_rate(intel_dp_max_link_bw(intel_dp)); |
174 | max_lanes = drm_dp_max_lane_count(intel_dp->dpcd); | 190 | max_lanes = intel_dp_max_lane_count(intel_dp); |
175 | 191 | ||
176 | max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); | 192 | max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); |
177 | mode_rate = intel_dp_link_required(target_clock, 18); | 193 | mode_rate = intel_dp_link_required(target_clock, 18); |
@@ -751,8 +767,10 @@ intel_dp_compute_config(struct intel_encoder *encoder, | |||
751 | struct intel_crtc *intel_crtc = encoder->new_crtc; | 767 | struct intel_crtc *intel_crtc = encoder->new_crtc; |
752 | struct intel_connector *intel_connector = intel_dp->attached_connector; | 768 | struct intel_connector *intel_connector = intel_dp->attached_connector; |
753 | int lane_count, clock; | 769 | int lane_count, clock; |
754 | int max_lane_count = drm_dp_max_lane_count(intel_dp->dpcd); | 770 | int min_lane_count = 1; |
771 | int max_lane_count = intel_dp_max_lane_count(intel_dp); | ||
755 | /* Conveniently, the link BW constants become indices with a shift...*/ | 772 | /* Conveniently, the link BW constants become indices with a shift...*/ |
773 | int min_clock = 0; | ||
756 | int max_clock = intel_dp_max_link_bw(intel_dp) >> 3; | 774 | int max_clock = intel_dp_max_link_bw(intel_dp) >> 3; |
757 | int bpp, mode_rate; | 775 | int bpp, mode_rate; |
758 | static int bws[] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7, DP_LINK_BW_5_4 }; | 776 | static int bws[] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7, DP_LINK_BW_5_4 }; |
@@ -785,19 +803,38 @@ intel_dp_compute_config(struct intel_encoder *encoder, | |||
785 | /* Walk through all bpp values. Luckily they're all nicely spaced with 2 | 803 | /* Walk through all bpp values. Luckily they're all nicely spaced with 2 |
786 | * bpc in between. */ | 804 | * bpc in between. */ |
787 | bpp = pipe_config->pipe_bpp; | 805 | bpp = pipe_config->pipe_bpp; |
788 | if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp && | 806 | if (is_edp(intel_dp)) { |
789 | dev_priv->vbt.edp_bpp < bpp) { | 807 | if (dev_priv->vbt.edp_bpp && dev_priv->vbt.edp_bpp < bpp) { |
790 | DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n", | 808 | DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n", |
791 | dev_priv->vbt.edp_bpp); | 809 | dev_priv->vbt.edp_bpp); |
792 | bpp = dev_priv->vbt.edp_bpp; | 810 | bpp = dev_priv->vbt.edp_bpp; |
811 | } | ||
812 | |||
813 | if (IS_BROADWELL(dev)) { | ||
814 | /* Yes, it's an ugly hack. */ | ||
815 | min_lane_count = max_lane_count; | ||
816 | DRM_DEBUG_KMS("forcing lane count to max (%u) on BDW\n", | ||
817 | min_lane_count); | ||
818 | } else if (dev_priv->vbt.edp_lanes) { | ||
819 | min_lane_count = min(dev_priv->vbt.edp_lanes, | ||
820 | max_lane_count); | ||
821 | DRM_DEBUG_KMS("using min %u lanes per VBT\n", | ||
822 | min_lane_count); | ||
823 | } | ||
824 | |||
825 | if (dev_priv->vbt.edp_rate) { | ||
826 | min_clock = min(dev_priv->vbt.edp_rate >> 3, max_clock); | ||
827 | DRM_DEBUG_KMS("using min %02x link bw per VBT\n", | ||
828 | bws[min_clock]); | ||
829 | } | ||
793 | } | 830 | } |
794 | 831 | ||
795 | for (; bpp >= 6*3; bpp -= 2*3) { | 832 | for (; bpp >= 6*3; bpp -= 2*3) { |
796 | mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, | 833 | mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, |
797 | bpp); | 834 | bpp); |
798 | 835 | ||
799 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { | 836 | for (lane_count = min_lane_count; lane_count <= max_lane_count; lane_count <<= 1) { |
800 | for (clock = 0; clock <= max_clock; clock++) { | 837 | for (clock = min_clock; clock <= max_clock; clock++) { |
801 | link_clock = drm_dp_bw_code_to_link_rate(bws[clock]); | 838 | link_clock = drm_dp_bw_code_to_link_rate(bws[clock]); |
802 | link_avail = intel_dp_max_data_rate(link_clock, | 839 | link_avail = intel_dp_max_data_rate(link_clock, |
803 | lane_count); | 840 | lane_count); |
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index fce4a0d93c0b..f73ba5e6b7a8 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c | |||
@@ -387,6 +387,15 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, | |||
387 | height); | 387 | height); |
388 | } | 388 | } |
389 | 389 | ||
390 | /* No preferred mode marked by the EDID? Are there any modes? */ | ||
391 | if (!modes[i] && !list_empty(&connector->modes)) { | ||
392 | DRM_DEBUG_KMS("using first mode listed on connector %s\n", | ||
393 | drm_get_connector_name(connector)); | ||
394 | modes[i] = list_first_entry(&connector->modes, | ||
395 | struct drm_display_mode, | ||
396 | head); | ||
397 | } | ||
398 | |||
390 | /* last resort: use current mode */ | 399 | /* last resort: use current mode */ |
391 | if (!modes[i]) { | 400 | if (!modes[i]) { |
392 | /* | 401 | /* |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 0eead16aeda7..cb8cfb7e0974 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -492,6 +492,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level, | |||
492 | enum pipe pipe = intel_get_pipe_from_connector(connector); | 492 | enum pipe pipe = intel_get_pipe_from_connector(connector); |
493 | u32 freq; | 493 | u32 freq; |
494 | unsigned long flags; | 494 | unsigned long flags; |
495 | u64 n; | ||
495 | 496 | ||
496 | if (!panel->backlight.present || pipe == INVALID_PIPE) | 497 | if (!panel->backlight.present || pipe == INVALID_PIPE) |
497 | return; | 498 | return; |
@@ -502,10 +503,9 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level, | |||
502 | 503 | ||
503 | /* scale to hardware max, but be careful to not overflow */ | 504 | /* scale to hardware max, but be careful to not overflow */ |
504 | freq = panel->backlight.max; | 505 | freq = panel->backlight.max; |
505 | if (freq < max) | 506 | n = (u64)level * freq; |
506 | level = level * freq / max; | 507 | do_div(n, max); |
507 | else | 508 | level = n; |
508 | level = freq / max * level; | ||
509 | 509 | ||
510 | panel->backlight.level = level; | 510 | panel->backlight.level = level; |
511 | if (panel->backlight.device) | 511 | if (panel->backlight.device) |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 19e94c3edc19..d93dcf683e8c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -2095,6 +2095,43 @@ static void intel_print_wm_latency(struct drm_device *dev, | |||
2095 | } | 2095 | } |
2096 | } | 2096 | } |
2097 | 2097 | ||
2098 | static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv, | ||
2099 | uint16_t wm[5], uint16_t min) | ||
2100 | { | ||
2101 | int level, max_level = ilk_wm_max_level(dev_priv->dev); | ||
2102 | |||
2103 | if (wm[0] >= min) | ||
2104 | return false; | ||
2105 | |||
2106 | wm[0] = max(wm[0], min); | ||
2107 | for (level = 1; level <= max_level; level++) | ||
2108 | wm[level] = max_t(uint16_t, wm[level], DIV_ROUND_UP(min, 5)); | ||
2109 | |||
2110 | return true; | ||
2111 | } | ||
2112 | |||
2113 | static void snb_wm_latency_quirk(struct drm_device *dev) | ||
2114 | { | ||
2115 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2116 | bool changed; | ||
2117 | |||
2118 | /* | ||
2119 | * The BIOS provided WM memory latency values are often | ||
2120 | * inadequate for high resolution displays. Adjust them. | ||
2121 | */ | ||
2122 | changed = ilk_increase_wm_latency(dev_priv, dev_priv->wm.pri_latency, 12) | | ||
2123 | ilk_increase_wm_latency(dev_priv, dev_priv->wm.spr_latency, 12) | | ||
2124 | ilk_increase_wm_latency(dev_priv, dev_priv->wm.cur_latency, 12); | ||
2125 | |||
2126 | if (!changed) | ||
2127 | return; | ||
2128 | |||
2129 | DRM_DEBUG_KMS("WM latency values increased to avoid potential underruns\n"); | ||
2130 | intel_print_wm_latency(dev, "Primary", dev_priv->wm.pri_latency); | ||
2131 | intel_print_wm_latency(dev, "Sprite", dev_priv->wm.spr_latency); | ||
2132 | intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency); | ||
2133 | } | ||
2134 | |||
2098 | static void ilk_setup_wm_latency(struct drm_device *dev) | 2135 | static void ilk_setup_wm_latency(struct drm_device *dev) |
2099 | { | 2136 | { |
2100 | struct drm_i915_private *dev_priv = dev->dev_private; | 2137 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -2112,6 +2149,9 @@ static void ilk_setup_wm_latency(struct drm_device *dev) | |||
2112 | intel_print_wm_latency(dev, "Primary", dev_priv->wm.pri_latency); | 2149 | intel_print_wm_latency(dev, "Primary", dev_priv->wm.pri_latency); |
2113 | intel_print_wm_latency(dev, "Sprite", dev_priv->wm.spr_latency); | 2150 | intel_print_wm_latency(dev, "Sprite", dev_priv->wm.spr_latency); |
2114 | intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency); | 2151 | intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency); |
2152 | |||
2153 | if (IS_GEN6(dev)) | ||
2154 | snb_wm_latency_quirk(dev); | ||
2115 | } | 2155 | } |
2116 | 2156 | ||
2117 | static void ilk_compute_wm_parameters(struct drm_crtc *crtc, | 2157 | static void ilk_compute_wm_parameters(struct drm_crtc *crtc, |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d27155adf5db..46be00d66df3 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -2424,8 +2424,8 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector, | |||
2424 | if (ret < 0) | 2424 | if (ret < 0) |
2425 | goto err1; | 2425 | goto err1; |
2426 | 2426 | ||
2427 | ret = sysfs_create_link(&encoder->ddc.dev.kobj, | 2427 | ret = sysfs_create_link(&drm_connector->kdev->kobj, |
2428 | &drm_connector->kdev->kobj, | 2428 | &encoder->ddc.dev.kobj, |
2429 | encoder->ddc.dev.kobj.name); | 2429 | encoder->ddc.dev.kobj.name); |
2430 | if (ret < 0) | 2430 | if (ret < 0) |
2431 | goto err2; | 2431 | goto err2; |
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index f729dc71d5be..d0c75779d3f6 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c | |||
@@ -185,6 +185,8 @@ static void vlv_force_wake_reset(struct drm_i915_private *dev_priv) | |||
185 | { | 185 | { |
186 | __raw_i915_write32(dev_priv, FORCEWAKE_VLV, | 186 | __raw_i915_write32(dev_priv, FORCEWAKE_VLV, |
187 | _MASKED_BIT_DISABLE(0xffff)); | 187 | _MASKED_BIT_DISABLE(0xffff)); |
188 | __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV, | ||
189 | _MASKED_BIT_DISABLE(0xffff)); | ||
188 | /* something from same cacheline, but !FORCEWAKE_VLV */ | 190 | /* something from same cacheline, but !FORCEWAKE_VLV */ |
189 | __raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV); | 191 | __raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV); |
190 | } | 192 | } |
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c index 90ec1173b8a1..01723f04fe45 100644 --- a/drivers/hwmon/emc1403.c +++ b/drivers/hwmon/emc1403.c | |||
@@ -163,7 +163,7 @@ static ssize_t store_hyst(struct device *dev, | |||
163 | if (retval < 0) | 163 | if (retval < 0) |
164 | goto fail; | 164 | goto fail; |
165 | 165 | ||
166 | hyst = val - retval * 1000; | 166 | hyst = retval * 1000 - val; |
167 | hyst = DIV_ROUND_CLOSEST(hyst, 1000); | 167 | hyst = DIV_ROUND_CLOSEST(hyst, 1000); |
168 | if (hyst < 0 || hyst > 255) { | 168 | if (hyst < 0 || hyst > 255) { |
169 | retval = -ERANGE; | 169 | retval = -ERANGE; |
@@ -330,7 +330,7 @@ static int emc1403_detect(struct i2c_client *client, | |||
330 | } | 330 | } |
331 | 331 | ||
332 | id = i2c_smbus_read_byte_data(client, THERMAL_REVISION_REG); | 332 | id = i2c_smbus_read_byte_data(client, THERMAL_REVISION_REG); |
333 | if (id != 0x01) | 333 | if (id < 0x01 || id > 0x04) |
334 | return -ENODEV; | 334 | return -ENODEV; |
335 | 335 | ||
336 | return 0; | 336 | return 0; |
@@ -355,9 +355,9 @@ static int emc1403_probe(struct i2c_client *client, | |||
355 | if (id->driver_data) | 355 | if (id->driver_data) |
356 | data->groups[1] = &emc1404_group; | 356 | data->groups[1] = &emc1404_group; |
357 | 357 | ||
358 | hwmon_dev = hwmon_device_register_with_groups(&client->dev, | 358 | hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, |
359 | client->name, data, | 359 | client->name, data, |
360 | data->groups); | 360 | data->groups); |
361 | if (IS_ERR(hwmon_dev)) | 361 | if (IS_ERR(hwmon_dev)) |
362 | return PTR_ERR(hwmon_dev); | 362 | return PTR_ERR(hwmon_dev); |
363 | 363 | ||
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 22e92c3d3d07..3c20e4bd6dd1 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c | |||
@@ -422,6 +422,9 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) | |||
422 | */ | 422 | */ |
423 | dw_writel(dev, msgs[dev->msg_write_idx].addr | ic_tar, DW_IC_TAR); | 423 | dw_writel(dev, msgs[dev->msg_write_idx].addr | ic_tar, DW_IC_TAR); |
424 | 424 | ||
425 | /* enforce disabled interrupts (due to HW issues) */ | ||
426 | i2c_dw_disable_int(dev); | ||
427 | |||
425 | /* Enable the adapter */ | 428 | /* Enable the adapter */ |
426 | __i2c_dw_enable(dev, true); | 429 | __i2c_dw_enable(dev, true); |
427 | 430 | ||
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index 28cbe1b2a2ec..32c85e9ecdae 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c | |||
@@ -999,7 +999,7 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) | |||
999 | 999 | ||
1000 | dev->virtbase = devm_ioremap(&adev->dev, adev->res.start, | 1000 | dev->virtbase = devm_ioremap(&adev->dev, adev->res.start, |
1001 | resource_size(&adev->res)); | 1001 | resource_size(&adev->res)); |
1002 | if (IS_ERR(dev->virtbase)) { | 1002 | if (!dev->virtbase) { |
1003 | ret = -ENOMEM; | 1003 | ret = -ENOMEM; |
1004 | goto err_no_mem; | 1004 | goto err_no_mem; |
1005 | } | 1005 | } |
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c index 1b4cf14f1106..2a5efb5b487c 100644 --- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c | |||
@@ -479,7 +479,7 @@ static int qup_i2c_xfer(struct i2c_adapter *adap, | |||
479 | int ret, idx; | 479 | int ret, idx; |
480 | 480 | ||
481 | ret = pm_runtime_get_sync(qup->dev); | 481 | ret = pm_runtime_get_sync(qup->dev); |
482 | if (ret) | 482 | if (ret < 0) |
483 | goto out; | 483 | goto out; |
484 | 484 | ||
485 | writel(1, qup->base + QUP_SW_RESET); | 485 | writel(1, qup->base + QUP_SW_RESET); |
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index d4fa8eba6e9d..06d47aafbb79 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c | |||
@@ -561,6 +561,12 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, | |||
561 | 561 | ||
562 | ret = -EINVAL; | 562 | ret = -EINVAL; |
563 | for (i = 0; i < num; i++) { | 563 | for (i = 0; i < num; i++) { |
564 | /* This HW can't send STOP after address phase */ | ||
565 | if (msgs[i].len == 0) { | ||
566 | ret = -EOPNOTSUPP; | ||
567 | break; | ||
568 | } | ||
569 | |||
564 | /*-------------- spin lock -----------------*/ | 570 | /*-------------- spin lock -----------------*/ |
565 | spin_lock_irqsave(&priv->lock, flags); | 571 | spin_lock_irqsave(&priv->lock, flags); |
566 | 572 | ||
@@ -625,7 +631,8 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, | |||
625 | 631 | ||
626 | static u32 rcar_i2c_func(struct i2c_adapter *adap) | 632 | static u32 rcar_i2c_func(struct i2c_adapter *adap) |
627 | { | 633 | { |
628 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | 634 | /* This HW can't do SMBUS_QUICK and NOSTART */ |
635 | return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); | ||
629 | } | 636 | } |
630 | 637 | ||
631 | static const struct i2c_algorithm rcar_i2c_algo = { | 638 | static const struct i2c_algorithm rcar_i2c_algo = { |
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index ae4491062e41..bb3a9964f7e0 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c | |||
@@ -1276,10 +1276,10 @@ static int s3c24xx_i2c_resume(struct device *dev) | |||
1276 | struct platform_device *pdev = to_platform_device(dev); | 1276 | struct platform_device *pdev = to_platform_device(dev); |
1277 | struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); | 1277 | struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); |
1278 | 1278 | ||
1279 | i2c->suspended = 0; | ||
1280 | clk_prepare_enable(i2c->clk); | 1279 | clk_prepare_enable(i2c->clk); |
1281 | s3c24xx_i2c_init(i2c); | 1280 | s3c24xx_i2c_init(i2c); |
1282 | clk_disable_unprepare(i2c->clk); | 1281 | clk_disable_unprepare(i2c->clk); |
1282 | i2c->suspended = 0; | ||
1283 | 1283 | ||
1284 | return 0; | 1284 | return 0; |
1285 | } | 1285 | } |
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index c98fdb185931..a1710465faaf 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <target/target_core_base.h> | 28 | #include <target/target_core_base.h> |
29 | #include <target/target_core_fabric.h> | 29 | #include <target/target_core_fabric.h> |
30 | #include <target/iscsi/iscsi_transport.h> | 30 | #include <target/iscsi/iscsi_transport.h> |
31 | #include <linux/semaphore.h> | ||
31 | 32 | ||
32 | #include "isert_proto.h" | 33 | #include "isert_proto.h" |
33 | #include "ib_isert.h" | 34 | #include "ib_isert.h" |
@@ -561,7 +562,15 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | |||
561 | struct isert_device *device; | 562 | struct isert_device *device; |
562 | struct ib_device *ib_dev = cma_id->device; | 563 | struct ib_device *ib_dev = cma_id->device; |
563 | int ret = 0; | 564 | int ret = 0; |
564 | u8 pi_support = np->tpg_np->tpg->tpg_attrib.t10_pi; | 565 | u8 pi_support; |
566 | |||
567 | spin_lock_bh(&np->np_thread_lock); | ||
568 | if (!np->enabled) { | ||
569 | spin_unlock_bh(&np->np_thread_lock); | ||
570 | pr_debug("iscsi_np is not enabled, reject connect request\n"); | ||
571 | return rdma_reject(cma_id, NULL, 0); | ||
572 | } | ||
573 | spin_unlock_bh(&np->np_thread_lock); | ||
565 | 574 | ||
566 | pr_debug("Entering isert_connect_request cma_id: %p, context: %p\n", | 575 | pr_debug("Entering isert_connect_request cma_id: %p, context: %p\n", |
567 | cma_id, cma_id->context); | 576 | cma_id, cma_id->context); |
@@ -652,6 +661,7 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | |||
652 | goto out_mr; | 661 | goto out_mr; |
653 | } | 662 | } |
654 | 663 | ||
664 | pi_support = np->tpg_np->tpg->tpg_attrib.t10_pi; | ||
655 | if (pi_support && !device->pi_capable) { | 665 | if (pi_support && !device->pi_capable) { |
656 | pr_err("Protection information requested but not supported\n"); | 666 | pr_err("Protection information requested but not supported\n"); |
657 | ret = -EINVAL; | 667 | ret = -EINVAL; |
@@ -663,11 +673,11 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | |||
663 | goto out_conn_dev; | 673 | goto out_conn_dev; |
664 | 674 | ||
665 | mutex_lock(&isert_np->np_accept_mutex); | 675 | mutex_lock(&isert_np->np_accept_mutex); |
666 | list_add_tail(&isert_np->np_accept_list, &isert_conn->conn_accept_node); | 676 | list_add_tail(&isert_conn->conn_accept_node, &isert_np->np_accept_list); |
667 | mutex_unlock(&isert_np->np_accept_mutex); | 677 | mutex_unlock(&isert_np->np_accept_mutex); |
668 | 678 | ||
669 | pr_debug("isert_connect_request() waking up np_accept_wq: %p\n", np); | 679 | pr_debug("isert_connect_request() up np_sem np: %p\n", np); |
670 | wake_up(&isert_np->np_accept_wq); | 680 | up(&isert_np->np_sem); |
671 | return 0; | 681 | return 0; |
672 | 682 | ||
673 | out_conn_dev: | 683 | out_conn_dev: |
@@ -2999,7 +3009,7 @@ isert_setup_np(struct iscsi_np *np, | |||
2999 | pr_err("Unable to allocate struct isert_np\n"); | 3009 | pr_err("Unable to allocate struct isert_np\n"); |
3000 | return -ENOMEM; | 3010 | return -ENOMEM; |
3001 | } | 3011 | } |
3002 | init_waitqueue_head(&isert_np->np_accept_wq); | 3012 | sema_init(&isert_np->np_sem, 0); |
3003 | mutex_init(&isert_np->np_accept_mutex); | 3013 | mutex_init(&isert_np->np_accept_mutex); |
3004 | INIT_LIST_HEAD(&isert_np->np_accept_list); | 3014 | INIT_LIST_HEAD(&isert_np->np_accept_list); |
3005 | init_completion(&isert_np->np_login_comp); | 3015 | init_completion(&isert_np->np_login_comp); |
@@ -3048,18 +3058,6 @@ out: | |||
3048 | } | 3058 | } |
3049 | 3059 | ||
3050 | static int | 3060 | static int |
3051 | isert_check_accept_queue(struct isert_np *isert_np) | ||
3052 | { | ||
3053 | int empty; | ||
3054 | |||
3055 | mutex_lock(&isert_np->np_accept_mutex); | ||
3056 | empty = list_empty(&isert_np->np_accept_list); | ||
3057 | mutex_unlock(&isert_np->np_accept_mutex); | ||
3058 | |||
3059 | return empty; | ||
3060 | } | ||
3061 | |||
3062 | static int | ||
3063 | isert_rdma_accept(struct isert_conn *isert_conn) | 3061 | isert_rdma_accept(struct isert_conn *isert_conn) |
3064 | { | 3062 | { |
3065 | struct rdma_cm_id *cm_id = isert_conn->conn_cm_id; | 3063 | struct rdma_cm_id *cm_id = isert_conn->conn_cm_id; |
@@ -3151,16 +3149,14 @@ isert_accept_np(struct iscsi_np *np, struct iscsi_conn *conn) | |||
3151 | int max_accept = 0, ret; | 3149 | int max_accept = 0, ret; |
3152 | 3150 | ||
3153 | accept_wait: | 3151 | accept_wait: |
3154 | ret = wait_event_interruptible(isert_np->np_accept_wq, | 3152 | ret = down_interruptible(&isert_np->np_sem); |
3155 | !isert_check_accept_queue(isert_np) || | ||
3156 | np->np_thread_state == ISCSI_NP_THREAD_RESET); | ||
3157 | if (max_accept > 5) | 3153 | if (max_accept > 5) |
3158 | return -ENODEV; | 3154 | return -ENODEV; |
3159 | 3155 | ||
3160 | spin_lock_bh(&np->np_thread_lock); | 3156 | spin_lock_bh(&np->np_thread_lock); |
3161 | if (np->np_thread_state == ISCSI_NP_THREAD_RESET) { | 3157 | if (np->np_thread_state == ISCSI_NP_THREAD_RESET) { |
3162 | spin_unlock_bh(&np->np_thread_lock); | 3158 | spin_unlock_bh(&np->np_thread_lock); |
3163 | pr_err("ISCSI_NP_THREAD_RESET for isert_accept_np\n"); | 3159 | pr_debug("ISCSI_NP_THREAD_RESET for isert_accept_np\n"); |
3164 | return -ENODEV; | 3160 | return -ENODEV; |
3165 | } | 3161 | } |
3166 | spin_unlock_bh(&np->np_thread_lock); | 3162 | spin_unlock_bh(&np->np_thread_lock); |
diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h index 4c072ae34c01..da6612e68000 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.h +++ b/drivers/infiniband/ulp/isert/ib_isert.h | |||
@@ -182,7 +182,7 @@ struct isert_device { | |||
182 | }; | 182 | }; |
183 | 183 | ||
184 | struct isert_np { | 184 | struct isert_np { |
185 | wait_queue_head_t np_accept_wq; | 185 | struct semaphore np_sem; |
186 | struct rdma_cm_id *np_cm_id; | 186 | struct rdma_cm_id *np_cm_id; |
187 | struct mutex np_accept_mutex; | 187 | struct mutex np_accept_mutex; |
188 | struct list_head np_accept_list; | 188 | struct list_head np_accept_list; |
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index c949520bd196..57068e8035b5 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -3999,7 +3999,7 @@ static struct irq_remap_table *get_irq_table(u16 devid, bool ioapic) | |||
3999 | iommu_flush_dte(iommu, devid); | 3999 | iommu_flush_dte(iommu, devid); |
4000 | if (devid != alias) { | 4000 | if (devid != alias) { |
4001 | irq_lookup_table[alias] = table; | 4001 | irq_lookup_table[alias] = table; |
4002 | set_dte_irq_entry(devid, table); | 4002 | set_dte_irq_entry(alias, table); |
4003 | iommu_flush_dte(iommu, alias); | 4003 | iommu_flush_dte(iommu, alias); |
4004 | } | 4004 | } |
4005 | 4005 | ||
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index b76c58dbe30c..0e08545d7298 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c | |||
@@ -788,7 +788,7 @@ static void __init set_device_exclusion_range(u16 devid, struct ivmd_header *m) | |||
788 | * per device. But we can enable the exclusion range per | 788 | * per device. But we can enable the exclusion range per |
789 | * device. This is done here | 789 | * device. This is done here |
790 | */ | 790 | */ |
791 | set_dev_entry_bit(m->devid, DEV_ENTRY_EX); | 791 | set_dev_entry_bit(devid, DEV_ENTRY_EX); |
792 | iommu->exclusion_start = m->range_start; | 792 | iommu->exclusion_start = m->range_start; |
793 | iommu->exclusion_length = m->range_length; | 793 | iommu->exclusion_length = m->range_length; |
794 | } | 794 | } |
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c index 5208828792e6..203b2e6a91cf 100644 --- a/drivers/iommu/amd_iommu_v2.c +++ b/drivers/iommu/amd_iommu_v2.c | |||
@@ -504,8 +504,10 @@ static void do_fault(struct work_struct *work) | |||
504 | 504 | ||
505 | write = !!(fault->flags & PPR_FAULT_WRITE); | 505 | write = !!(fault->flags & PPR_FAULT_WRITE); |
506 | 506 | ||
507 | down_read(&fault->state->mm->mmap_sem); | ||
507 | npages = get_user_pages(fault->state->task, fault->state->mm, | 508 | npages = get_user_pages(fault->state->task, fault->state->mm, |
508 | fault->address, 1, write, 0, &page, NULL); | 509 | fault->address, 1, write, 0, &page, NULL); |
510 | up_read(&fault->state->mm->mmap_sem); | ||
509 | 511 | ||
510 | if (npages == 1) { | 512 | if (npages == 1) { |
511 | put_page(page); | 513 | put_page(page); |
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 784695d22fde..53b213226c01 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/crypto.h> | 19 | #include <linux/crypto.h> |
20 | #include <linux/workqueue.h> | 20 | #include <linux/workqueue.h> |
21 | #include <linux/backing-dev.h> | 21 | #include <linux/backing-dev.h> |
22 | #include <linux/percpu.h> | ||
23 | #include <linux/atomic.h> | 22 | #include <linux/atomic.h> |
24 | #include <linux/scatterlist.h> | 23 | #include <linux/scatterlist.h> |
25 | #include <asm/page.h> | 24 | #include <asm/page.h> |
@@ -43,6 +42,7 @@ struct convert_context { | |||
43 | struct bvec_iter iter_out; | 42 | struct bvec_iter iter_out; |
44 | sector_t cc_sector; | 43 | sector_t cc_sector; |
45 | atomic_t cc_pending; | 44 | atomic_t cc_pending; |
45 | struct ablkcipher_request *req; | ||
46 | }; | 46 | }; |
47 | 47 | ||
48 | /* | 48 | /* |
@@ -111,15 +111,7 @@ struct iv_tcw_private { | |||
111 | enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID }; | 111 | enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID }; |
112 | 112 | ||
113 | /* | 113 | /* |
114 | * Duplicated per-CPU state for cipher. | 114 | * The fields in here must be read only after initialization. |
115 | */ | ||
116 | struct crypt_cpu { | ||
117 | struct ablkcipher_request *req; | ||
118 | }; | ||
119 | |||
120 | /* | ||
121 | * The fields in here must be read only after initialization, | ||
122 | * changing state should be in crypt_cpu. | ||
123 | */ | 115 | */ |
124 | struct crypt_config { | 116 | struct crypt_config { |
125 | struct dm_dev *dev; | 117 | struct dm_dev *dev; |
@@ -150,12 +142,6 @@ struct crypt_config { | |||
150 | sector_t iv_offset; | 142 | sector_t iv_offset; |
151 | unsigned int iv_size; | 143 | unsigned int iv_size; |
152 | 144 | ||
153 | /* | ||
154 | * Duplicated per cpu state. Access through | ||
155 | * per_cpu_ptr() only. | ||
156 | */ | ||
157 | struct crypt_cpu __percpu *cpu; | ||
158 | |||
159 | /* ESSIV: struct crypto_cipher *essiv_tfm */ | 145 | /* ESSIV: struct crypto_cipher *essiv_tfm */ |
160 | void *iv_private; | 146 | void *iv_private; |
161 | struct crypto_ablkcipher **tfms; | 147 | struct crypto_ablkcipher **tfms; |
@@ -192,11 +178,6 @@ static void clone_init(struct dm_crypt_io *, struct bio *); | |||
192 | static void kcryptd_queue_crypt(struct dm_crypt_io *io); | 178 | static void kcryptd_queue_crypt(struct dm_crypt_io *io); |
193 | static u8 *iv_of_dmreq(struct crypt_config *cc, struct dm_crypt_request *dmreq); | 179 | static u8 *iv_of_dmreq(struct crypt_config *cc, struct dm_crypt_request *dmreq); |
194 | 180 | ||
195 | static struct crypt_cpu *this_crypt_config(struct crypt_config *cc) | ||
196 | { | ||
197 | return this_cpu_ptr(cc->cpu); | ||
198 | } | ||
199 | |||
200 | /* | 181 | /* |
201 | * Use this to access cipher attributes that are the same for each CPU. | 182 | * Use this to access cipher attributes that are the same for each CPU. |
202 | */ | 183 | */ |
@@ -903,16 +884,15 @@ static void kcryptd_async_done(struct crypto_async_request *async_req, | |||
903 | static void crypt_alloc_req(struct crypt_config *cc, | 884 | static void crypt_alloc_req(struct crypt_config *cc, |
904 | struct convert_context *ctx) | 885 | struct convert_context *ctx) |
905 | { | 886 | { |
906 | struct crypt_cpu *this_cc = this_crypt_config(cc); | ||
907 | unsigned key_index = ctx->cc_sector & (cc->tfms_count - 1); | 887 | unsigned key_index = ctx->cc_sector & (cc->tfms_count - 1); |
908 | 888 | ||
909 | if (!this_cc->req) | 889 | if (!ctx->req) |
910 | this_cc->req = mempool_alloc(cc->req_pool, GFP_NOIO); | 890 | ctx->req = mempool_alloc(cc->req_pool, GFP_NOIO); |
911 | 891 | ||
912 | ablkcipher_request_set_tfm(this_cc->req, cc->tfms[key_index]); | 892 | ablkcipher_request_set_tfm(ctx->req, cc->tfms[key_index]); |
913 | ablkcipher_request_set_callback(this_cc->req, | 893 | ablkcipher_request_set_callback(ctx->req, |
914 | CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, | 894 | CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, |
915 | kcryptd_async_done, dmreq_of_req(cc, this_cc->req)); | 895 | kcryptd_async_done, dmreq_of_req(cc, ctx->req)); |
916 | } | 896 | } |
917 | 897 | ||
918 | /* | 898 | /* |
@@ -921,7 +901,6 @@ static void crypt_alloc_req(struct crypt_config *cc, | |||
921 | static int crypt_convert(struct crypt_config *cc, | 901 | static int crypt_convert(struct crypt_config *cc, |
922 | struct convert_context *ctx) | 902 | struct convert_context *ctx) |
923 | { | 903 | { |
924 | struct crypt_cpu *this_cc = this_crypt_config(cc); | ||
925 | int r; | 904 | int r; |
926 | 905 | ||
927 | atomic_set(&ctx->cc_pending, 1); | 906 | atomic_set(&ctx->cc_pending, 1); |
@@ -932,7 +911,7 @@ static int crypt_convert(struct crypt_config *cc, | |||
932 | 911 | ||
933 | atomic_inc(&ctx->cc_pending); | 912 | atomic_inc(&ctx->cc_pending); |
934 | 913 | ||
935 | r = crypt_convert_block(cc, ctx, this_cc->req); | 914 | r = crypt_convert_block(cc, ctx, ctx->req); |
936 | 915 | ||
937 | switch (r) { | 916 | switch (r) { |
938 | /* async */ | 917 | /* async */ |
@@ -941,7 +920,7 @@ static int crypt_convert(struct crypt_config *cc, | |||
941 | reinit_completion(&ctx->restart); | 920 | reinit_completion(&ctx->restart); |
942 | /* fall through*/ | 921 | /* fall through*/ |
943 | case -EINPROGRESS: | 922 | case -EINPROGRESS: |
944 | this_cc->req = NULL; | 923 | ctx->req = NULL; |
945 | ctx->cc_sector++; | 924 | ctx->cc_sector++; |
946 | continue; | 925 | continue; |
947 | 926 | ||
@@ -1040,6 +1019,7 @@ static struct dm_crypt_io *crypt_io_alloc(struct crypt_config *cc, | |||
1040 | io->sector = sector; | 1019 | io->sector = sector; |
1041 | io->error = 0; | 1020 | io->error = 0; |
1042 | io->base_io = NULL; | 1021 | io->base_io = NULL; |
1022 | io->ctx.req = NULL; | ||
1043 | atomic_set(&io->io_pending, 0); | 1023 | atomic_set(&io->io_pending, 0); |
1044 | 1024 | ||
1045 | return io; | 1025 | return io; |
@@ -1065,6 +1045,8 @@ static void crypt_dec_pending(struct dm_crypt_io *io) | |||
1065 | if (!atomic_dec_and_test(&io->io_pending)) | 1045 | if (!atomic_dec_and_test(&io->io_pending)) |
1066 | return; | 1046 | return; |
1067 | 1047 | ||
1048 | if (io->ctx.req) | ||
1049 | mempool_free(io->ctx.req, cc->req_pool); | ||
1068 | mempool_free(io, cc->io_pool); | 1050 | mempool_free(io, cc->io_pool); |
1069 | 1051 | ||
1070 | if (likely(!base_io)) | 1052 | if (likely(!base_io)) |
@@ -1492,8 +1474,6 @@ static int crypt_wipe_key(struct crypt_config *cc) | |||
1492 | static void crypt_dtr(struct dm_target *ti) | 1474 | static void crypt_dtr(struct dm_target *ti) |
1493 | { | 1475 | { |
1494 | struct crypt_config *cc = ti->private; | 1476 | struct crypt_config *cc = ti->private; |
1495 | struct crypt_cpu *cpu_cc; | ||
1496 | int cpu; | ||
1497 | 1477 | ||
1498 | ti->private = NULL; | 1478 | ti->private = NULL; |
1499 | 1479 | ||
@@ -1505,13 +1485,6 @@ static void crypt_dtr(struct dm_target *ti) | |||
1505 | if (cc->crypt_queue) | 1485 | if (cc->crypt_queue) |
1506 | destroy_workqueue(cc->crypt_queue); | 1486 | destroy_workqueue(cc->crypt_queue); |
1507 | 1487 | ||
1508 | if (cc->cpu) | ||
1509 | for_each_possible_cpu(cpu) { | ||
1510 | cpu_cc = per_cpu_ptr(cc->cpu, cpu); | ||
1511 | if (cpu_cc->req) | ||
1512 | mempool_free(cpu_cc->req, cc->req_pool); | ||
1513 | } | ||
1514 | |||
1515 | crypt_free_tfms(cc); | 1488 | crypt_free_tfms(cc); |
1516 | 1489 | ||
1517 | if (cc->bs) | 1490 | if (cc->bs) |
@@ -1530,9 +1503,6 @@ static void crypt_dtr(struct dm_target *ti) | |||
1530 | if (cc->dev) | 1503 | if (cc->dev) |
1531 | dm_put_device(ti, cc->dev); | 1504 | dm_put_device(ti, cc->dev); |
1532 | 1505 | ||
1533 | if (cc->cpu) | ||
1534 | free_percpu(cc->cpu); | ||
1535 | |||
1536 | kzfree(cc->cipher); | 1506 | kzfree(cc->cipher); |
1537 | kzfree(cc->cipher_string); | 1507 | kzfree(cc->cipher_string); |
1538 | 1508 | ||
@@ -1588,13 +1558,6 @@ static int crypt_ctr_cipher(struct dm_target *ti, | |||
1588 | if (tmp) | 1558 | if (tmp) |
1589 | DMWARN("Ignoring unexpected additional cipher options"); | 1559 | DMWARN("Ignoring unexpected additional cipher options"); |
1590 | 1560 | ||
1591 | cc->cpu = __alloc_percpu(sizeof(*(cc->cpu)), | ||
1592 | __alignof__(struct crypt_cpu)); | ||
1593 | if (!cc->cpu) { | ||
1594 | ti->error = "Cannot allocate per cpu state"; | ||
1595 | goto bad_mem; | ||
1596 | } | ||
1597 | |||
1598 | /* | 1561 | /* |
1599 | * For compatibility with the original dm-crypt mapping format, if | 1562 | * For compatibility with the original dm-crypt mapping format, if |
1600 | * only the cipher name is supplied, use cbc-plain. | 1563 | * only the cipher name is supplied, use cbc-plain. |
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index aa009e865871..fa0f6cbd6a41 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -1566,8 +1566,8 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, | |||
1566 | } | 1566 | } |
1567 | if (m->pg_init_required) | 1567 | if (m->pg_init_required) |
1568 | __pg_init_all_paths(m); | 1568 | __pg_init_all_paths(m); |
1569 | spin_unlock_irqrestore(&m->lock, flags); | ||
1570 | dm_table_run_md_queue_async(m->ti->table); | 1569 | dm_table_run_md_queue_async(m->ti->table); |
1570 | spin_unlock_irqrestore(&m->lock, flags); | ||
1571 | } | 1571 | } |
1572 | 1572 | ||
1573 | return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg); | 1573 | return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg); |
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 13abade76ad9..2e71de8e0048 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #define MAPPING_POOL_SIZE 1024 | 27 | #define MAPPING_POOL_SIZE 1024 |
28 | #define PRISON_CELLS 1024 | 28 | #define PRISON_CELLS 1024 |
29 | #define COMMIT_PERIOD HZ | 29 | #define COMMIT_PERIOD HZ |
30 | #define NO_SPACE_TIMEOUT (HZ * 60) | ||
30 | 31 | ||
31 | DECLARE_DM_KCOPYD_THROTTLE_WITH_MODULE_PARM(snapshot_copy_throttle, | 32 | DECLARE_DM_KCOPYD_THROTTLE_WITH_MODULE_PARM(snapshot_copy_throttle, |
32 | "A percentage of time allocated for copy on write"); | 33 | "A percentage of time allocated for copy on write"); |
@@ -175,6 +176,7 @@ struct pool { | |||
175 | struct workqueue_struct *wq; | 176 | struct workqueue_struct *wq; |
176 | struct work_struct worker; | 177 | struct work_struct worker; |
177 | struct delayed_work waker; | 178 | struct delayed_work waker; |
179 | struct delayed_work no_space_timeout; | ||
178 | 180 | ||
179 | unsigned long last_commit_jiffies; | 181 | unsigned long last_commit_jiffies; |
180 | unsigned ref_count; | 182 | unsigned ref_count; |
@@ -935,7 +937,7 @@ static int commit(struct pool *pool) | |||
935 | { | 937 | { |
936 | int r; | 938 | int r; |
937 | 939 | ||
938 | if (get_pool_mode(pool) != PM_WRITE) | 940 | if (get_pool_mode(pool) >= PM_READ_ONLY) |
939 | return -EINVAL; | 941 | return -EINVAL; |
940 | 942 | ||
941 | r = dm_pool_commit_metadata(pool->pmd); | 943 | r = dm_pool_commit_metadata(pool->pmd); |
@@ -1590,6 +1592,20 @@ static void do_waker(struct work_struct *ws) | |||
1590 | queue_delayed_work(pool->wq, &pool->waker, COMMIT_PERIOD); | 1592 | queue_delayed_work(pool->wq, &pool->waker, COMMIT_PERIOD); |
1591 | } | 1593 | } |
1592 | 1594 | ||
1595 | /* | ||
1596 | * We're holding onto IO to allow userland time to react. After the | ||
1597 | * timeout either the pool will have been resized (and thus back in | ||
1598 | * PM_WRITE mode), or we degrade to PM_READ_ONLY and start erroring IO. | ||
1599 | */ | ||
1600 | static void do_no_space_timeout(struct work_struct *ws) | ||
1601 | { | ||
1602 | struct pool *pool = container_of(to_delayed_work(ws), struct pool, | ||
1603 | no_space_timeout); | ||
1604 | |||
1605 | if (get_pool_mode(pool) == PM_OUT_OF_DATA_SPACE && !pool->pf.error_if_no_space) | ||
1606 | set_pool_mode(pool, PM_READ_ONLY); | ||
1607 | } | ||
1608 | |||
1593 | /*----------------------------------------------------------------*/ | 1609 | /*----------------------------------------------------------------*/ |
1594 | 1610 | ||
1595 | struct noflush_work { | 1611 | struct noflush_work { |
@@ -1715,6 +1731,9 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode) | |||
1715 | pool->process_discard = process_discard; | 1731 | pool->process_discard = process_discard; |
1716 | pool->process_prepared_mapping = process_prepared_mapping; | 1732 | pool->process_prepared_mapping = process_prepared_mapping; |
1717 | pool->process_prepared_discard = process_prepared_discard_passdown; | 1733 | pool->process_prepared_discard = process_prepared_discard_passdown; |
1734 | |||
1735 | if (!pool->pf.error_if_no_space) | ||
1736 | queue_delayed_work(pool->wq, &pool->no_space_timeout, NO_SPACE_TIMEOUT); | ||
1718 | break; | 1737 | break; |
1719 | 1738 | ||
1720 | case PM_WRITE: | 1739 | case PM_WRITE: |
@@ -2100,6 +2119,7 @@ static struct pool *pool_create(struct mapped_device *pool_md, | |||
2100 | 2119 | ||
2101 | INIT_WORK(&pool->worker, do_worker); | 2120 | INIT_WORK(&pool->worker, do_worker); |
2102 | INIT_DELAYED_WORK(&pool->waker, do_waker); | 2121 | INIT_DELAYED_WORK(&pool->waker, do_waker); |
2122 | INIT_DELAYED_WORK(&pool->no_space_timeout, do_no_space_timeout); | ||
2103 | spin_lock_init(&pool->lock); | 2123 | spin_lock_init(&pool->lock); |
2104 | bio_list_init(&pool->deferred_flush_bios); | 2124 | bio_list_init(&pool->deferred_flush_bios); |
2105 | INIT_LIST_HEAD(&pool->prepared_mappings); | 2125 | INIT_LIST_HEAD(&pool->prepared_mappings); |
@@ -2662,6 +2682,7 @@ static void pool_postsuspend(struct dm_target *ti) | |||
2662 | struct pool *pool = pt->pool; | 2682 | struct pool *pool = pt->pool; |
2663 | 2683 | ||
2664 | cancel_delayed_work(&pool->waker); | 2684 | cancel_delayed_work(&pool->waker); |
2685 | cancel_delayed_work(&pool->no_space_timeout); | ||
2665 | flush_workqueue(pool->wq); | 2686 | flush_workqueue(pool->wq); |
2666 | (void) commit(pool); | 2687 | (void) commit(pool); |
2667 | } | 2688 | } |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 8fda38d23e38..237b7e0ddc7a 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -8516,7 +8516,8 @@ static int md_notify_reboot(struct notifier_block *this, | |||
8516 | if (mddev_trylock(mddev)) { | 8516 | if (mddev_trylock(mddev)) { |
8517 | if (mddev->pers) | 8517 | if (mddev->pers) |
8518 | __md_stop_writes(mddev); | 8518 | __md_stop_writes(mddev); |
8519 | mddev->safemode = 2; | 8519 | if (mddev->persistent) |
8520 | mddev->safemode = 2; | ||
8520 | mddev_unlock(mddev); | 8521 | mddev_unlock(mddev); |
8521 | } | 8522 | } |
8522 | need_delay = 1; | 8523 | need_delay = 1; |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 33fc408e5eac..cb882aae9e20 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1172,6 +1172,13 @@ static void __make_request(struct mddev *mddev, struct bio *bio) | |||
1172 | int max_sectors; | 1172 | int max_sectors; |
1173 | int sectors; | 1173 | int sectors; |
1174 | 1174 | ||
1175 | /* | ||
1176 | * Register the new request and wait if the reconstruction | ||
1177 | * thread has put up a bar for new requests. | ||
1178 | * Continue immediately if no resync is active currently. | ||
1179 | */ | ||
1180 | wait_barrier(conf); | ||
1181 | |||
1175 | sectors = bio_sectors(bio); | 1182 | sectors = bio_sectors(bio); |
1176 | while (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && | 1183 | while (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && |
1177 | bio->bi_iter.bi_sector < conf->reshape_progress && | 1184 | bio->bi_iter.bi_sector < conf->reshape_progress && |
@@ -1552,12 +1559,6 @@ static void make_request(struct mddev *mddev, struct bio *bio) | |||
1552 | 1559 | ||
1553 | md_write_start(mddev, bio); | 1560 | md_write_start(mddev, bio); |
1554 | 1561 | ||
1555 | /* | ||
1556 | * Register the new request and wait if the reconstruction | ||
1557 | * thread has put up a bar for new requests. | ||
1558 | * Continue immediately if no resync is active currently. | ||
1559 | */ | ||
1560 | wait_barrier(conf); | ||
1561 | 1562 | ||
1562 | do { | 1563 | do { |
1563 | 1564 | ||
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index e8a1ce204036..cdd7c1b7259b 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c | |||
@@ -1109,7 +1109,7 @@ static int ov7670_enum_framesizes(struct v4l2_subdev *sd, | |||
1109 | * windows that fall outside that. | 1109 | * windows that fall outside that. |
1110 | */ | 1110 | */ |
1111 | for (i = 0; i < n_win_sizes; i++) { | 1111 | for (i = 0; i < n_win_sizes; i++) { |
1112 | struct ov7670_win_size *win = &info->devtype->win_sizes[index]; | 1112 | struct ov7670_win_size *win = &info->devtype->win_sizes[i]; |
1113 | if (info->min_width && win->width < info->min_width) | 1113 | if (info->min_width && win->width < info->min_width) |
1114 | continue; | 1114 | continue; |
1115 | if (info->min_height && win->height < info->min_height) | 1115 | if (info->min_height && win->height < info->min_height) |
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index a4459301b5f8..ee0f57e01b56 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c | |||
@@ -1616,7 +1616,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state) | |||
1616 | if (ret < 0) | 1616 | if (ret < 0) |
1617 | return -EINVAL; | 1617 | return -EINVAL; |
1618 | 1618 | ||
1619 | node_ep = v4l2_of_get_next_endpoint(node, NULL); | 1619 | node_ep = of_graph_get_next_endpoint(node, NULL); |
1620 | if (!node_ep) { | 1620 | if (!node_ep) { |
1621 | dev_warn(dev, "no endpoint defined for node: %s\n", | 1621 | dev_warn(dev, "no endpoint defined for node: %s\n", |
1622 | node->full_name); | 1622 | node->full_name); |
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index d5a7a135f75d..703560fa5e73 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c | |||
@@ -93,6 +93,7 @@ static long media_device_enum_entities(struct media_device *mdev, | |||
93 | struct media_entity *ent; | 93 | struct media_entity *ent; |
94 | struct media_entity_desc u_ent; | 94 | struct media_entity_desc u_ent; |
95 | 95 | ||
96 | memset(&u_ent, 0, sizeof(u_ent)); | ||
96 | if (copy_from_user(&u_ent.id, &uent->id, sizeof(u_ent.id))) | 97 | if (copy_from_user(&u_ent.id, &uent->id, sizeof(u_ent.id))) |
97 | return -EFAULT; | 98 | return -EFAULT; |
98 | 99 | ||
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index b4f12d00be05..656708252962 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c | |||
@@ -372,18 +372,32 @@ static int vpbe_stop_streaming(struct vb2_queue *vq) | |||
372 | { | 372 | { |
373 | struct vpbe_fh *fh = vb2_get_drv_priv(vq); | 373 | struct vpbe_fh *fh = vb2_get_drv_priv(vq); |
374 | struct vpbe_layer *layer = fh->layer; | 374 | struct vpbe_layer *layer = fh->layer; |
375 | struct vpbe_display *disp = fh->disp_dev; | ||
376 | unsigned long flags; | ||
375 | 377 | ||
376 | if (!vb2_is_streaming(vq)) | 378 | if (!vb2_is_streaming(vq)) |
377 | return 0; | 379 | return 0; |
378 | 380 | ||
379 | /* release all active buffers */ | 381 | /* release all active buffers */ |
382 | spin_lock_irqsave(&disp->dma_queue_lock, flags); | ||
383 | if (layer->cur_frm == layer->next_frm) { | ||
384 | vb2_buffer_done(&layer->cur_frm->vb, VB2_BUF_STATE_ERROR); | ||
385 | } else { | ||
386 | if (layer->cur_frm != NULL) | ||
387 | vb2_buffer_done(&layer->cur_frm->vb, | ||
388 | VB2_BUF_STATE_ERROR); | ||
389 | if (layer->next_frm != NULL) | ||
390 | vb2_buffer_done(&layer->next_frm->vb, | ||
391 | VB2_BUF_STATE_ERROR); | ||
392 | } | ||
393 | |||
380 | while (!list_empty(&layer->dma_queue)) { | 394 | while (!list_empty(&layer->dma_queue)) { |
381 | layer->next_frm = list_entry(layer->dma_queue.next, | 395 | layer->next_frm = list_entry(layer->dma_queue.next, |
382 | struct vpbe_disp_buffer, list); | 396 | struct vpbe_disp_buffer, list); |
383 | list_del(&layer->next_frm->list); | 397 | list_del(&layer->next_frm->list); |
384 | vb2_buffer_done(&layer->next_frm->vb, VB2_BUF_STATE_ERROR); | 398 | vb2_buffer_done(&layer->next_frm->vb, VB2_BUF_STATE_ERROR); |
385 | } | 399 | } |
386 | 400 | spin_unlock_irqrestore(&disp->dma_queue_lock, flags); | |
387 | return 0; | 401 | return 0; |
388 | } | 402 | } |
389 | 403 | ||
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index d762246eabf5..0379cb9f9a9c 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c | |||
@@ -734,6 +734,8 @@ static int vpfe_release(struct file *file) | |||
734 | } | 734 | } |
735 | vpfe_dev->io_usrs = 0; | 735 | vpfe_dev->io_usrs = 0; |
736 | vpfe_dev->numbuffers = config_params.numbuffers; | 736 | vpfe_dev->numbuffers = config_params.numbuffers; |
737 | videobuf_stop(&vpfe_dev->buffer_queue); | ||
738 | videobuf_mmap_free(&vpfe_dev->buffer_queue); | ||
737 | } | 739 | } |
738 | 740 | ||
739 | /* Decrement device usrs counter */ | 741 | /* Decrement device usrs counter */ |
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 756da78bac23..8dea0b84a3ad 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c | |||
@@ -358,8 +358,31 @@ static int vpif_stop_streaming(struct vb2_queue *vq) | |||
358 | 358 | ||
359 | common = &ch->common[VPIF_VIDEO_INDEX]; | 359 | common = &ch->common[VPIF_VIDEO_INDEX]; |
360 | 360 | ||
361 | /* Disable channel as per its device type and channel id */ | ||
362 | if (VPIF_CHANNEL0_VIDEO == ch->channel_id) { | ||
363 | enable_channel0(0); | ||
364 | channel0_intr_enable(0); | ||
365 | } | ||
366 | if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) || | ||
367 | (2 == common->started)) { | ||
368 | enable_channel1(0); | ||
369 | channel1_intr_enable(0); | ||
370 | } | ||
371 | common->started = 0; | ||
372 | |||
361 | /* release all active buffers */ | 373 | /* release all active buffers */ |
362 | spin_lock_irqsave(&common->irqlock, flags); | 374 | spin_lock_irqsave(&common->irqlock, flags); |
375 | if (common->cur_frm == common->next_frm) { | ||
376 | vb2_buffer_done(&common->cur_frm->vb, VB2_BUF_STATE_ERROR); | ||
377 | } else { | ||
378 | if (common->cur_frm != NULL) | ||
379 | vb2_buffer_done(&common->cur_frm->vb, | ||
380 | VB2_BUF_STATE_ERROR); | ||
381 | if (common->next_frm != NULL) | ||
382 | vb2_buffer_done(&common->next_frm->vb, | ||
383 | VB2_BUF_STATE_ERROR); | ||
384 | } | ||
385 | |||
363 | while (!list_empty(&common->dma_queue)) { | 386 | while (!list_empty(&common->dma_queue)) { |
364 | common->next_frm = list_entry(common->dma_queue.next, | 387 | common->next_frm = list_entry(common->dma_queue.next, |
365 | struct vpif_cap_buffer, list); | 388 | struct vpif_cap_buffer, list); |
@@ -933,17 +956,6 @@ static int vpif_release(struct file *filep) | |||
933 | if (fh->io_allowed[VPIF_VIDEO_INDEX]) { | 956 | if (fh->io_allowed[VPIF_VIDEO_INDEX]) { |
934 | /* Reset io_usrs member of channel object */ | 957 | /* Reset io_usrs member of channel object */ |
935 | common->io_usrs = 0; | 958 | common->io_usrs = 0; |
936 | /* Disable channel as per its device type and channel id */ | ||
937 | if (VPIF_CHANNEL0_VIDEO == ch->channel_id) { | ||
938 | enable_channel0(0); | ||
939 | channel0_intr_enable(0); | ||
940 | } | ||
941 | if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) || | ||
942 | (2 == common->started)) { | ||
943 | enable_channel1(0); | ||
944 | channel1_intr_enable(0); | ||
945 | } | ||
946 | common->started = 0; | ||
947 | /* Free buffers allocated */ | 959 | /* Free buffers allocated */ |
948 | vb2_queue_release(&common->buffer_queue); | 960 | vb2_queue_release(&common->buffer_queue); |
949 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); | 961 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); |
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index 0ac841e35aa4..aed41edd0501 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c | |||
@@ -320,8 +320,31 @@ static int vpif_stop_streaming(struct vb2_queue *vq) | |||
320 | 320 | ||
321 | common = &ch->common[VPIF_VIDEO_INDEX]; | 321 | common = &ch->common[VPIF_VIDEO_INDEX]; |
322 | 322 | ||
323 | /* Disable channel */ | ||
324 | if (VPIF_CHANNEL2_VIDEO == ch->channel_id) { | ||
325 | enable_channel2(0); | ||
326 | channel2_intr_enable(0); | ||
327 | } | ||
328 | if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) || | ||
329 | (2 == common->started)) { | ||
330 | enable_channel3(0); | ||
331 | channel3_intr_enable(0); | ||
332 | } | ||
333 | common->started = 0; | ||
334 | |||
323 | /* release all active buffers */ | 335 | /* release all active buffers */ |
324 | spin_lock_irqsave(&common->irqlock, flags); | 336 | spin_lock_irqsave(&common->irqlock, flags); |
337 | if (common->cur_frm == common->next_frm) { | ||
338 | vb2_buffer_done(&common->cur_frm->vb, VB2_BUF_STATE_ERROR); | ||
339 | } else { | ||
340 | if (common->cur_frm != NULL) | ||
341 | vb2_buffer_done(&common->cur_frm->vb, | ||
342 | VB2_BUF_STATE_ERROR); | ||
343 | if (common->next_frm != NULL) | ||
344 | vb2_buffer_done(&common->next_frm->vb, | ||
345 | VB2_BUF_STATE_ERROR); | ||
346 | } | ||
347 | |||
325 | while (!list_empty(&common->dma_queue)) { | 348 | while (!list_empty(&common->dma_queue)) { |
326 | common->next_frm = list_entry(common->dma_queue.next, | 349 | common->next_frm = list_entry(common->dma_queue.next, |
327 | struct vpif_disp_buffer, list); | 350 | struct vpif_disp_buffer, list); |
@@ -773,18 +796,6 @@ static int vpif_release(struct file *filep) | |||
773 | if (fh->io_allowed[VPIF_VIDEO_INDEX]) { | 796 | if (fh->io_allowed[VPIF_VIDEO_INDEX]) { |
774 | /* Reset io_usrs member of channel object */ | 797 | /* Reset io_usrs member of channel object */ |
775 | common->io_usrs = 0; | 798 | common->io_usrs = 0; |
776 | /* Disable channel */ | ||
777 | if (VPIF_CHANNEL2_VIDEO == ch->channel_id) { | ||
778 | enable_channel2(0); | ||
779 | channel2_intr_enable(0); | ||
780 | } | ||
781 | if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) || | ||
782 | (2 == common->started)) { | ||
783 | enable_channel3(0); | ||
784 | channel3_intr_enable(0); | ||
785 | } | ||
786 | common->started = 0; | ||
787 | |||
788 | /* Free buffers allocated */ | 799 | /* Free buffers allocated */ |
789 | vb2_queue_release(&common->buffer_queue); | 800 | vb2_queue_release(&common->buffer_queue); |
790 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); | 801 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); |
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c index da2fc86cc524..25dbf5b05a96 100644 --- a/drivers/media/platform/exynos4-is/fimc-core.c +++ b/drivers/media/platform/exynos4-is/fimc-core.c | |||
@@ -122,7 +122,7 @@ static struct fimc_fmt fimc_formats[] = { | |||
122 | }, { | 122 | }, { |
123 | .name = "YUV 4:2:2 planar, Y/Cb/Cr", | 123 | .name = "YUV 4:2:2 planar, Y/Cb/Cr", |
124 | .fourcc = V4L2_PIX_FMT_YUV422P, | 124 | .fourcc = V4L2_PIX_FMT_YUV422P, |
125 | .depth = { 12 }, | 125 | .depth = { 16 }, |
126 | .color = FIMC_FMT_YCBYCR422, | 126 | .color = FIMC_FMT_YCBYCR422, |
127 | .memplanes = 1, | 127 | .memplanes = 1, |
128 | .colplanes = 3, | 128 | .colplanes = 3, |
diff --git a/drivers/media/tuners/fc2580.c b/drivers/media/tuners/fc2580.c index 3aecaf465094..f0c9c42867de 100644 --- a/drivers/media/tuners/fc2580.c +++ b/drivers/media/tuners/fc2580.c | |||
@@ -195,7 +195,7 @@ static int fc2580_set_params(struct dvb_frontend *fe) | |||
195 | 195 | ||
196 | f_ref = 2UL * priv->cfg->clock / r_val; | 196 | f_ref = 2UL * priv->cfg->clock / r_val; |
197 | n_val = div_u64_rem(f_vco, f_ref, &k_val); | 197 | n_val = div_u64_rem(f_vco, f_ref, &k_val); |
198 | k_val_reg = 1UL * k_val * (1 << 20) / f_ref; | 198 | k_val_reg = div_u64(1ULL * k_val * (1 << 20), f_ref); |
199 | 199 | ||
200 | ret = fc2580_wr_reg(priv, 0x18, r18_val | ((k_val_reg >> 16) & 0xff)); | 200 | ret = fc2580_wr_reg(priv, 0x18, r18_val | ((k_val_reg >> 16) & 0xff)); |
201 | if (ret < 0) | 201 | if (ret < 0) |
@@ -348,8 +348,8 @@ static int fc2580_set_params(struct dvb_frontend *fe) | |||
348 | if (ret < 0) | 348 | if (ret < 0) |
349 | goto err; | 349 | goto err; |
350 | 350 | ||
351 | ret = fc2580_wr_reg(priv, 0x37, 1UL * priv->cfg->clock * \ | 351 | ret = fc2580_wr_reg(priv, 0x37, div_u64(1ULL * priv->cfg->clock * |
352 | fc2580_if_filter_lut[i].mul / 1000000000); | 352 | fc2580_if_filter_lut[i].mul, 1000000000)); |
353 | if (ret < 0) | 353 | if (ret < 0) |
354 | goto err; | 354 | goto err; |
355 | 355 | ||
diff --git a/drivers/media/tuners/fc2580_priv.h b/drivers/media/tuners/fc2580_priv.h index be38a9e637e0..646c99452136 100644 --- a/drivers/media/tuners/fc2580_priv.h +++ b/drivers/media/tuners/fc2580_priv.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #define FC2580_PRIV_H | 22 | #define FC2580_PRIV_H |
23 | 23 | ||
24 | #include "fc2580.h" | 24 | #include "fc2580.h" |
25 | #include <linux/math64.h> | ||
25 | 26 | ||
26 | struct fc2580_reg_val { | 27 | struct fc2580_reg_val { |
27 | u8 reg; | 28 | u8 reg; |
diff --git a/drivers/media/usb/dvb-usb-v2/Makefile b/drivers/media/usb/dvb-usb-v2/Makefile index 7407b8338ccf..bc38f03394cd 100644 --- a/drivers/media/usb/dvb-usb-v2/Makefile +++ b/drivers/media/usb/dvb-usb-v2/Makefile | |||
@@ -41,4 +41,3 @@ ccflags-y += -I$(srctree)/drivers/media/dvb-core | |||
41 | ccflags-y += -I$(srctree)/drivers/media/dvb-frontends | 41 | ccflags-y += -I$(srctree)/drivers/media/dvb-frontends |
42 | ccflags-y += -I$(srctree)/drivers/media/tuners | 42 | ccflags-y += -I$(srctree)/drivers/media/tuners |
43 | ccflags-y += -I$(srctree)/drivers/media/common | 43 | ccflags-y += -I$(srctree)/drivers/media/common |
44 | ccflags-y += -I$(srctree)/drivers/staging/media/rtl2832u_sdr | ||
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 61d196e8b3ab..dcbd392e6efc 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | #include "rtl2830.h" | 25 | #include "rtl2830.h" |
26 | #include "rtl2832.h" | 26 | #include "rtl2832.h" |
27 | #include "rtl2832_sdr.h" | ||
28 | 27 | ||
29 | #include "qt1010.h" | 28 | #include "qt1010.h" |
30 | #include "mt2060.h" | 29 | #include "mt2060.h" |
@@ -36,6 +35,45 @@ | |||
36 | #include "tua9001.h" | 35 | #include "tua9001.h" |
37 | #include "r820t.h" | 36 | #include "r820t.h" |
38 | 37 | ||
38 | /* | ||
39 | * RTL2832_SDR module is in staging. That logic is added in order to avoid any | ||
40 | * hard dependency to drivers/staging/ directory as we want compile mainline | ||
41 | * driver even whole staging directory is missing. | ||
42 | */ | ||
43 | #include <media/v4l2-subdev.h> | ||
44 | |||
45 | #if IS_ENABLED(CONFIG_DVB_RTL2832_SDR) | ||
46 | struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe, | ||
47 | struct i2c_adapter *i2c, const struct rtl2832_config *cfg, | ||
48 | struct v4l2_subdev *sd); | ||
49 | #else | ||
50 | static inline struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe, | ||
51 | struct i2c_adapter *i2c, const struct rtl2832_config *cfg, | ||
52 | struct v4l2_subdev *sd) | ||
53 | { | ||
54 | return NULL; | ||
55 | } | ||
56 | #endif | ||
57 | |||
58 | #ifdef CONFIG_MEDIA_ATTACH | ||
59 | #define dvb_attach_sdr(FUNCTION, ARGS...) ({ \ | ||
60 | void *__r = NULL; \ | ||
61 | typeof(&FUNCTION) __a = symbol_request(FUNCTION); \ | ||
62 | if (__a) { \ | ||
63 | __r = (void *) __a(ARGS); \ | ||
64 | if (__r == NULL) \ | ||
65 | symbol_put(FUNCTION); \ | ||
66 | } \ | ||
67 | __r; \ | ||
68 | }) | ||
69 | |||
70 | #else | ||
71 | #define dvb_attach_sdr(FUNCTION, ARGS...) ({ \ | ||
72 | FUNCTION(ARGS); \ | ||
73 | }) | ||
74 | |||
75 | #endif | ||
76 | |||
39 | static int rtl28xxu_disable_rc; | 77 | static int rtl28xxu_disable_rc; |
40 | module_param_named(disable_rc, rtl28xxu_disable_rc, int, 0644); | 78 | module_param_named(disable_rc, rtl28xxu_disable_rc, int, 0644); |
41 | MODULE_PARM_DESC(disable_rc, "disable RTL2832U remote controller"); | 79 | MODULE_PARM_DESC(disable_rc, "disable RTL2832U remote controller"); |
@@ -908,7 +946,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) | |||
908 | adap->fe[0]->ops.tuner_ops.get_rf_strength; | 946 | adap->fe[0]->ops.tuner_ops.get_rf_strength; |
909 | 947 | ||
910 | /* attach SDR */ | 948 | /* attach SDR */ |
911 | dvb_attach(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap, | 949 | dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap, |
912 | &rtl28xxu_rtl2832_fc0012_config, NULL); | 950 | &rtl28xxu_rtl2832_fc0012_config, NULL); |
913 | break; | 951 | break; |
914 | case TUNER_RTL2832_FC0013: | 952 | case TUNER_RTL2832_FC0013: |
@@ -920,7 +958,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) | |||
920 | adap->fe[0]->ops.tuner_ops.get_rf_strength; | 958 | adap->fe[0]->ops.tuner_ops.get_rf_strength; |
921 | 959 | ||
922 | /* attach SDR */ | 960 | /* attach SDR */ |
923 | dvb_attach(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap, | 961 | dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap, |
924 | &rtl28xxu_rtl2832_fc0013_config, NULL); | 962 | &rtl28xxu_rtl2832_fc0013_config, NULL); |
925 | break; | 963 | break; |
926 | case TUNER_RTL2832_E4000: { | 964 | case TUNER_RTL2832_E4000: { |
@@ -951,7 +989,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) | |||
951 | i2c_set_adapdata(i2c_adap_internal, d); | 989 | i2c_set_adapdata(i2c_adap_internal, d); |
952 | 990 | ||
953 | /* attach SDR */ | 991 | /* attach SDR */ |
954 | dvb_attach(rtl2832_sdr_attach, adap->fe[0], | 992 | dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], |
955 | i2c_adap_internal, | 993 | i2c_adap_internal, |
956 | &rtl28xxu_rtl2832_e4000_config, sd); | 994 | &rtl28xxu_rtl2832_e4000_config, sd); |
957 | } | 995 | } |
@@ -982,7 +1020,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) | |||
982 | adap->fe[0]->ops.tuner_ops.get_rf_strength; | 1020 | adap->fe[0]->ops.tuner_ops.get_rf_strength; |
983 | 1021 | ||
984 | /* attach SDR */ | 1022 | /* attach SDR */ |
985 | dvb_attach(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap, | 1023 | dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap, |
986 | &rtl28xxu_rtl2832_r820t_config, NULL); | 1024 | &rtl28xxu_rtl2832_r820t_config, NULL); |
987 | break; | 1025 | break; |
988 | case TUNER_RTL2832_R828D: | 1026 | case TUNER_RTL2832_R828D: |
diff --git a/drivers/media/usb/gspca/sonixb.c b/drivers/media/usb/gspca/sonixb.c index 7277dbd2afcd..ecbcb39feb71 100644 --- a/drivers/media/usb/gspca/sonixb.c +++ b/drivers/media/usb/gspca/sonixb.c | |||
@@ -1430,10 +1430,8 @@ static const struct usb_device_id device_table[] = { | |||
1430 | {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)}, | 1430 | {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)}, |
1431 | {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)}, | 1431 | {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)}, |
1432 | {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)}, | 1432 | {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)}, |
1433 | #if !IS_ENABLED(CONFIG_USB_SN9C102) | ||
1434 | {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)}, | 1433 | {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)}, |
1435 | {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)}, | 1434 | {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)}, |
1436 | #endif | ||
1437 | {USB_DEVICE(0x0c45, 0x6027), SB(OV7630, 101)}, /* Genius Eye 310 */ | 1435 | {USB_DEVICE(0x0c45, 0x6027), SB(OV7630, 101)}, /* Genius Eye 310 */ |
1438 | {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)}, | 1436 | {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)}, |
1439 | {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)}, | 1437 | {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)}, |
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index 04b2daf567be..7e2411c36419 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c | |||
@@ -178,6 +178,9 @@ struct v4l2_create_buffers32 { | |||
178 | 178 | ||
179 | static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) | 179 | static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) |
180 | { | 180 | { |
181 | if (get_user(kp->type, &up->type)) | ||
182 | return -EFAULT; | ||
183 | |||
181 | switch (kp->type) { | 184 | switch (kp->type) { |
182 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 185 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
183 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 186 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
@@ -204,17 +207,16 @@ static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __us | |||
204 | 207 | ||
205 | static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) | 208 | static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) |
206 | { | 209 | { |
207 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) || | 210 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32))) |
208 | get_user(kp->type, &up->type)) | 211 | return -EFAULT; |
209 | return -EFAULT; | ||
210 | return __get_v4l2_format32(kp, up); | 212 | return __get_v4l2_format32(kp, up); |
211 | } | 213 | } |
212 | 214 | ||
213 | static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up) | 215 | static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up) |
214 | { | 216 | { |
215 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) || | 217 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) || |
216 | copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt))) | 218 | copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format))) |
217 | return -EFAULT; | 219 | return -EFAULT; |
218 | return __get_v4l2_format32(&kp->format, &up->format); | 220 | return __get_v4l2_format32(&kp->format, &up->format); |
219 | } | 221 | } |
220 | 222 | ||
diff --git a/drivers/memory/mvebu-devbus.c b/drivers/memory/mvebu-devbus.c index 110c03627051..b59a17fb7c3e 100644 --- a/drivers/memory/mvebu-devbus.c +++ b/drivers/memory/mvebu-devbus.c | |||
@@ -108,8 +108,19 @@ static int devbus_set_timing_params(struct devbus *devbus, | |||
108 | node->full_name); | 108 | node->full_name); |
109 | return err; | 109 | return err; |
110 | } | 110 | } |
111 | /* Convert bit width to byte width */ | 111 | |
112 | r.bus_width /= 8; | 112 | /* |
113 | * The bus width is encoded into the register as 0 for 8 bits, | ||
114 | * and 1 for 16 bits, so we do the necessary conversion here. | ||
115 | */ | ||
116 | if (r.bus_width == 8) | ||
117 | r.bus_width = 0; | ||
118 | else if (r.bus_width == 16) | ||
119 | r.bus_width = 1; | ||
120 | else { | ||
121 | dev_err(devbus->dev, "invalid bus width %d\n", r.bus_width); | ||
122 | return -EINVAL; | ||
123 | } | ||
113 | 124 | ||
114 | err = get_timing_param_ps(devbus, node, "devbus,badr-skew-ps", | 125 | err = get_timing_param_ps(devbus, node, "devbus,badr-skew-ps", |
115 | &r.badr_skew); | 126 | &r.badr_skew); |
diff --git a/drivers/of/base.c b/drivers/of/base.c index 6d4ee22708c9..32e969d95319 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -1831,6 +1831,10 @@ int of_update_property(struct device_node *np, struct property *newprop) | |||
1831 | if (!found) | 1831 | if (!found) |
1832 | return -ENODEV; | 1832 | return -ENODEV; |
1833 | 1833 | ||
1834 | /* At early boot, bail out and defer setup to of_init() */ | ||
1835 | if (!of_kset) | ||
1836 | return found ? 0 : -ENODEV; | ||
1837 | |||
1834 | /* Update the sysfs attribute */ | 1838 | /* Update the sysfs attribute */ |
1835 | sysfs_remove_bin_file(&np->kobj, &oldprop->attr); | 1839 | sysfs_remove_bin_file(&np->kobj, &oldprop->attr); |
1836 | __of_add_property_sysfs(np, newprop); | 1840 | __of_add_property_sysfs(np, newprop); |
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index d3d1cfd51e09..e384e2534594 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
@@ -293,6 +293,58 @@ static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port, | |||
293 | return PCIBIOS_SUCCESSFUL; | 293 | return PCIBIOS_SUCCESSFUL; |
294 | } | 294 | } |
295 | 295 | ||
296 | /* | ||
297 | * Remove windows, starting from the largest ones to the smallest | ||
298 | * ones. | ||
299 | */ | ||
300 | static void mvebu_pcie_del_windows(struct mvebu_pcie_port *port, | ||
301 | phys_addr_t base, size_t size) | ||
302 | { | ||
303 | while (size) { | ||
304 | size_t sz = 1 << (fls(size) - 1); | ||
305 | |||
306 | mvebu_mbus_del_window(base, sz); | ||
307 | base += sz; | ||
308 | size -= sz; | ||
309 | } | ||
310 | } | ||
311 | |||
312 | /* | ||
313 | * MBus windows can only have a power of two size, but PCI BARs do not | ||
314 | * have this constraint. Therefore, we have to split the PCI BAR into | ||
315 | * areas each having a power of two size. We start from the largest | ||
316 | * one (i.e highest order bit set in the size). | ||
317 | */ | ||
318 | static void mvebu_pcie_add_windows(struct mvebu_pcie_port *port, | ||
319 | unsigned int target, unsigned int attribute, | ||
320 | phys_addr_t base, size_t size, | ||
321 | phys_addr_t remap) | ||
322 | { | ||
323 | size_t size_mapped = 0; | ||
324 | |||
325 | while (size) { | ||
326 | size_t sz = 1 << (fls(size) - 1); | ||
327 | int ret; | ||
328 | |||
329 | ret = mvebu_mbus_add_window_remap_by_id(target, attribute, base, | ||
330 | sz, remap); | ||
331 | if (ret) { | ||
332 | dev_err(&port->pcie->pdev->dev, | ||
333 | "Could not create MBus window at 0x%x, size 0x%x: %d\n", | ||
334 | base, sz, ret); | ||
335 | mvebu_pcie_del_windows(port, base - size_mapped, | ||
336 | size_mapped); | ||
337 | return; | ||
338 | } | ||
339 | |||
340 | size -= sz; | ||
341 | size_mapped += sz; | ||
342 | base += sz; | ||
343 | if (remap != MVEBU_MBUS_NO_REMAP) | ||
344 | remap += sz; | ||
345 | } | ||
346 | } | ||
347 | |||
296 | static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) | 348 | static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) |
297 | { | 349 | { |
298 | phys_addr_t iobase; | 350 | phys_addr_t iobase; |
@@ -304,8 +356,8 @@ static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) | |||
304 | 356 | ||
305 | /* If a window was configured, remove it */ | 357 | /* If a window was configured, remove it */ |
306 | if (port->iowin_base) { | 358 | if (port->iowin_base) { |
307 | mvebu_mbus_del_window(port->iowin_base, | 359 | mvebu_pcie_del_windows(port, port->iowin_base, |
308 | port->iowin_size); | 360 | port->iowin_size); |
309 | port->iowin_base = 0; | 361 | port->iowin_base = 0; |
310 | port->iowin_size = 0; | 362 | port->iowin_size = 0; |
311 | } | 363 | } |
@@ -331,11 +383,11 @@ static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) | |||
331 | port->iowin_base = port->pcie->io.start + iobase; | 383 | port->iowin_base = port->pcie->io.start + iobase; |
332 | port->iowin_size = ((0xFFF | ((port->bridge.iolimit & 0xF0) << 8) | | 384 | port->iowin_size = ((0xFFF | ((port->bridge.iolimit & 0xF0) << 8) | |
333 | (port->bridge.iolimitupper << 16)) - | 385 | (port->bridge.iolimitupper << 16)) - |
334 | iobase); | 386 | iobase) + 1; |
335 | 387 | ||
336 | mvebu_mbus_add_window_remap_by_id(port->io_target, port->io_attr, | 388 | mvebu_pcie_add_windows(port, port->io_target, port->io_attr, |
337 | port->iowin_base, port->iowin_size, | 389 | port->iowin_base, port->iowin_size, |
338 | iobase); | 390 | iobase); |
339 | } | 391 | } |
340 | 392 | ||
341 | static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port) | 393 | static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port) |
@@ -346,8 +398,8 @@ static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port) | |||
346 | 398 | ||
347 | /* If a window was configured, remove it */ | 399 | /* If a window was configured, remove it */ |
348 | if (port->memwin_base) { | 400 | if (port->memwin_base) { |
349 | mvebu_mbus_del_window(port->memwin_base, | 401 | mvebu_pcie_del_windows(port, port->memwin_base, |
350 | port->memwin_size); | 402 | port->memwin_size); |
351 | port->memwin_base = 0; | 403 | port->memwin_base = 0; |
352 | port->memwin_size = 0; | 404 | port->memwin_size = 0; |
353 | } | 405 | } |
@@ -364,10 +416,11 @@ static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port) | |||
364 | port->memwin_base = ((port->bridge.membase & 0xFFF0) << 16); | 416 | port->memwin_base = ((port->bridge.membase & 0xFFF0) << 16); |
365 | port->memwin_size = | 417 | port->memwin_size = |
366 | (((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) - | 418 | (((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) - |
367 | port->memwin_base; | 419 | port->memwin_base + 1; |
368 | 420 | ||
369 | mvebu_mbus_add_window_by_id(port->mem_target, port->mem_attr, | 421 | mvebu_pcie_add_windows(port, port->mem_target, port->mem_attr, |
370 | port->memwin_base, port->memwin_size); | 422 | port->memwin_base, port->memwin_size, |
423 | MVEBU_MBUS_NO_REMAP); | ||
371 | } | 424 | } |
372 | 425 | ||
373 | /* | 426 | /* |
@@ -743,14 +796,21 @@ static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev, | |||
743 | 796 | ||
744 | /* | 797 | /* |
745 | * On the PCI-to-PCI bridge side, the I/O windows must have at | 798 | * On the PCI-to-PCI bridge side, the I/O windows must have at |
746 | * least a 64 KB size and be aligned on their size, and the | 799 | * least a 64 KB size and the memory windows must have at |
747 | * memory windows must have at least a 1 MB size and be | 800 | * least a 1 MB size. Moreover, MBus windows need to have a |
748 | * aligned on their size | 801 | * base address aligned on their size, and their size must be |
802 | * a power of two. This means that if the BAR doesn't have a | ||
803 | * power of two size, several MBus windows will actually be | ||
804 | * created. We need to ensure that the biggest MBus window | ||
805 | * (which will be the first one) is aligned on its size, which | ||
806 | * explains the rounddown_pow_of_two() being done here. | ||
749 | */ | 807 | */ |
750 | if (res->flags & IORESOURCE_IO) | 808 | if (res->flags & IORESOURCE_IO) |
751 | return round_up(start, max_t(resource_size_t, SZ_64K, size)); | 809 | return round_up(start, max_t(resource_size_t, SZ_64K, |
810 | rounddown_pow_of_two(size))); | ||
752 | else if (res->flags & IORESOURCE_MEM) | 811 | else if (res->flags & IORESOURCE_MEM) |
753 | return round_up(start, max_t(resource_size_t, SZ_1M, size)); | 812 | return round_up(start, max_t(resource_size_t, SZ_1M, |
813 | rounddown_pow_of_two(size))); | ||
754 | else | 814 | else |
755 | return start; | 815 | return start; |
756 | } | 816 | } |
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 58499277903a..6efc2ec5e4db 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c | |||
@@ -282,8 +282,8 @@ static int board_added(struct slot *p_slot) | |||
282 | return WRONG_BUS_FREQUENCY; | 282 | return WRONG_BUS_FREQUENCY; |
283 | } | 283 | } |
284 | 284 | ||
285 | bsp = ctrl->pci_dev->bus->cur_bus_speed; | 285 | bsp = ctrl->pci_dev->subordinate->cur_bus_speed; |
286 | msp = ctrl->pci_dev->bus->max_bus_speed; | 286 | msp = ctrl->pci_dev->subordinate->max_bus_speed; |
287 | 287 | ||
288 | /* Check if there are other slots or devices on the same bus */ | 288 | /* Check if there are other slots or devices on the same bus */ |
289 | if (!list_empty(&ctrl->pci_dev->subordinate->devices)) | 289 | if (!list_empty(&ctrl->pci_dev->subordinate->devices)) |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 7325d43bf030..759475ef6ff3 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -3067,7 +3067,8 @@ int pci_wait_for_pending_transaction(struct pci_dev *dev) | |||
3067 | if (!pci_is_pcie(dev)) | 3067 | if (!pci_is_pcie(dev)) |
3068 | return 1; | 3068 | return 1; |
3069 | 3069 | ||
3070 | return pci_wait_for_pending(dev, PCI_EXP_DEVSTA, PCI_EXP_DEVSTA_TRPND); | 3070 | return pci_wait_for_pending(dev, pci_pcie_cap(dev) + PCI_EXP_DEVSTA, |
3071 | PCI_EXP_DEVSTA_TRPND); | ||
3071 | } | 3072 | } |
3072 | EXPORT_SYMBOL(pci_wait_for_pending_transaction); | 3073 | EXPORT_SYMBOL(pci_wait_for_pending_transaction); |
3073 | 3074 | ||
@@ -3109,7 +3110,7 @@ static int pci_af_flr(struct pci_dev *dev, int probe) | |||
3109 | return 0; | 3110 | return 0; |
3110 | 3111 | ||
3111 | /* Wait for Transaction Pending bit clean */ | 3112 | /* Wait for Transaction Pending bit clean */ |
3112 | if (pci_wait_for_pending(dev, PCI_AF_STATUS, PCI_AF_STATUS_TP)) | 3113 | if (pci_wait_for_pending(dev, pos + PCI_AF_STATUS, PCI_AF_STATUS_TP)) |
3113 | goto clear; | 3114 | goto clear; |
3114 | 3115 | ||
3115 | dev_err(&dev->dev, "transaction is not cleared; " | 3116 | dev_err(&dev->dev, "transaction is not cleared; " |
diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index bd628a6f981d..e5f13c4310fe 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c | |||
@@ -569,6 +569,9 @@ static int hym8563_probe(struct i2c_client *client, | |||
569 | if (IS_ERR(hym8563->rtc)) | 569 | if (IS_ERR(hym8563->rtc)) |
570 | return PTR_ERR(hym8563->rtc); | 570 | return PTR_ERR(hym8563->rtc); |
571 | 571 | ||
572 | /* the hym8563 alarm only supports a minute accuracy */ | ||
573 | hym8563->rtc->uie_unsupported = 1; | ||
574 | |||
572 | #ifdef CONFIG_COMMON_CLK | 575 | #ifdef CONFIG_COMMON_CLK |
573 | hym8563_clkout_register_clk(hym8563); | 576 | hym8563_clkout_register_clk(hym8563); |
574 | #endif | 577 | #endif |
diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile index fc67f564f02c..788ed9b59b4e 100644 --- a/drivers/sh/Makefile +++ b/drivers/sh/Makefile | |||
@@ -1,10 +1,12 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the SuperH specific drivers. | 2 | # Makefile for the SuperH specific drivers. |
3 | # | 3 | # |
4 | obj-y := intc/ | 4 | obj-$(CONFIG_SUPERH) += intc/ |
5 | obj-$(CONFIG_ARCH_SHMOBILE_LEGACY) += intc/ | ||
6 | ifneq ($(CONFIG_COMMON_CLK),y) | ||
7 | obj-$(CONFIG_HAVE_CLK) += clk/ | ||
8 | endif | ||
9 | obj-$(CONFIG_MAPLE) += maple/ | ||
10 | obj-$(CONFIG_SUPERHYWAY) += superhyway/ | ||
5 | 11 | ||
6 | obj-$(CONFIG_HAVE_CLK) += clk/ | 12 | obj-y += pm_runtime.o |
7 | obj-$(CONFIG_MAPLE) += maple/ | ||
8 | obj-$(CONFIG_SUPERHYWAY) += superhyway/ | ||
9 | |||
10 | obj-y += pm_runtime.o | ||
diff --git a/drivers/sh/pm_runtime.c b/drivers/sh/pm_runtime.c index 8afa5a4589f2..10c65eb51f85 100644 --- a/drivers/sh/pm_runtime.c +++ b/drivers/sh/pm_runtime.c | |||
@@ -50,8 +50,25 @@ static struct pm_clk_notifier_block platform_bus_notifier = { | |||
50 | .con_ids = { NULL, }, | 50 | .con_ids = { NULL, }, |
51 | }; | 51 | }; |
52 | 52 | ||
53 | static bool default_pm_on; | ||
54 | |||
53 | static int __init sh_pm_runtime_init(void) | 55 | static int __init sh_pm_runtime_init(void) |
54 | { | 56 | { |
57 | if (IS_ENABLED(CONFIG_ARCH_SHMOBILE_MULTI)) { | ||
58 | if (!of_machine_is_compatible("renesas,emev2") && | ||
59 | !of_machine_is_compatible("renesas,r7s72100") && | ||
60 | !of_machine_is_compatible("renesas,r8a73a4") && | ||
61 | !of_machine_is_compatible("renesas,r8a7740") && | ||
62 | !of_machine_is_compatible("renesas,r8a7778") && | ||
63 | !of_machine_is_compatible("renesas,r8a7779") && | ||
64 | !of_machine_is_compatible("renesas,r8a7790") && | ||
65 | !of_machine_is_compatible("renesas,r8a7791") && | ||
66 | !of_machine_is_compatible("renesas,sh7372") && | ||
67 | !of_machine_is_compatible("renesas,sh73a0")) | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | default_pm_on = true; | ||
55 | pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier); | 72 | pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier); |
56 | return 0; | 73 | return 0; |
57 | } | 74 | } |
@@ -59,7 +76,8 @@ core_initcall(sh_pm_runtime_init); | |||
59 | 76 | ||
60 | static int __init sh_pm_runtime_late_init(void) | 77 | static int __init sh_pm_runtime_late_init(void) |
61 | { | 78 | { |
62 | pm_genpd_poweroff_unused(); | 79 | if (default_pm_on) |
80 | pm_genpd_poweroff_unused(); | ||
63 | return 0; | 81 | return 0; |
64 | } | 82 | } |
65 | late_initcall(sh_pm_runtime_late_init); | 83 | late_initcall(sh_pm_runtime_late_init); |
diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c index 713af4806f26..f6759dc0153b 100644 --- a/drivers/spi/spi-pxa2xx-dma.c +++ b/drivers/spi/spi-pxa2xx-dma.c | |||
@@ -29,18 +29,6 @@ static int pxa2xx_spi_map_dma_buffer(struct driver_data *drv_data, | |||
29 | struct sg_table *sgt; | 29 | struct sg_table *sgt; |
30 | void *buf, *pbuf; | 30 | void *buf, *pbuf; |
31 | 31 | ||
32 | /* | ||
33 | * Some DMA controllers have problems transferring buffers that are | ||
34 | * not multiple of 4 bytes. So we truncate the transfer so that it | ||
35 | * is suitable for such controllers, and handle the trailing bytes | ||
36 | * manually after the DMA completes. | ||
37 | * | ||
38 | * REVISIT: It would be better if this information could be | ||
39 | * retrieved directly from the DMA device in a similar way than | ||
40 | * ->copy_align etc. is done. | ||
41 | */ | ||
42 | len = ALIGN(drv_data->len, 4); | ||
43 | |||
44 | if (dir == DMA_TO_DEVICE) { | 32 | if (dir == DMA_TO_DEVICE) { |
45 | dmadev = drv_data->tx_chan->device->dev; | 33 | dmadev = drv_data->tx_chan->device->dev; |
46 | sgt = &drv_data->tx_sgt; | 34 | sgt = &drv_data->tx_sgt; |
@@ -144,12 +132,8 @@ static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data, | |||
144 | if (!error) { | 132 | if (!error) { |
145 | pxa2xx_spi_unmap_dma_buffers(drv_data); | 133 | pxa2xx_spi_unmap_dma_buffers(drv_data); |
146 | 134 | ||
147 | /* Handle the last bytes of unaligned transfer */ | ||
148 | drv_data->tx += drv_data->tx_map_len; | 135 | drv_data->tx += drv_data->tx_map_len; |
149 | drv_data->write(drv_data); | ||
150 | |||
151 | drv_data->rx += drv_data->rx_map_len; | 136 | drv_data->rx += drv_data->rx_map_len; |
152 | drv_data->read(drv_data); | ||
153 | 137 | ||
154 | msg->actual_length += drv_data->len; | 138 | msg->actual_length += drv_data->len; |
155 | msg->state = pxa2xx_spi_next_transfer(drv_data); | 139 | msg->state = pxa2xx_spi_next_transfer(drv_data); |
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index b032e8885e24..78c66e3c53ed 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c | |||
@@ -734,7 +734,7 @@ static int spi_qup_remove(struct platform_device *pdev) | |||
734 | int ret; | 734 | int ret; |
735 | 735 | ||
736 | ret = pm_runtime_get_sync(&pdev->dev); | 736 | ret = pm_runtime_get_sync(&pdev->dev); |
737 | if (ret) | 737 | if (ret < 0) |
738 | return ret; | 738 | return ret; |
739 | 739 | ||
740 | ret = spi_qup_set_state(controller, QUP_STATE_RESET); | 740 | ret = spi_qup_set_state(controller, QUP_STATE_RESET); |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 4eb9bf02996c..939edf473235 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -580,6 +580,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable) | |||
580 | spi->master->set_cs(spi, !enable); | 580 | spi->master->set_cs(spi, !enable); |
581 | } | 581 | } |
582 | 582 | ||
583 | #ifdef CONFIG_HAS_DMA | ||
583 | static int spi_map_buf(struct spi_master *master, struct device *dev, | 584 | static int spi_map_buf(struct spi_master *master, struct device *dev, |
584 | struct sg_table *sgt, void *buf, size_t len, | 585 | struct sg_table *sgt, void *buf, size_t len, |
585 | enum dma_data_direction dir) | 586 | enum dma_data_direction dir) |
@@ -637,55 +638,12 @@ static void spi_unmap_buf(struct spi_master *master, struct device *dev, | |||
637 | } | 638 | } |
638 | } | 639 | } |
639 | 640 | ||
640 | static int spi_map_msg(struct spi_master *master, struct spi_message *msg) | 641 | static int __spi_map_msg(struct spi_master *master, struct spi_message *msg) |
641 | { | 642 | { |
642 | struct device *tx_dev, *rx_dev; | 643 | struct device *tx_dev, *rx_dev; |
643 | struct spi_transfer *xfer; | 644 | struct spi_transfer *xfer; |
644 | void *tmp; | ||
645 | unsigned int max_tx, max_rx; | ||
646 | int ret; | 645 | int ret; |
647 | 646 | ||
648 | if (master->flags & (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX)) { | ||
649 | max_tx = 0; | ||
650 | max_rx = 0; | ||
651 | |||
652 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | ||
653 | if ((master->flags & SPI_MASTER_MUST_TX) && | ||
654 | !xfer->tx_buf) | ||
655 | max_tx = max(xfer->len, max_tx); | ||
656 | if ((master->flags & SPI_MASTER_MUST_RX) && | ||
657 | !xfer->rx_buf) | ||
658 | max_rx = max(xfer->len, max_rx); | ||
659 | } | ||
660 | |||
661 | if (max_tx) { | ||
662 | tmp = krealloc(master->dummy_tx, max_tx, | ||
663 | GFP_KERNEL | GFP_DMA); | ||
664 | if (!tmp) | ||
665 | return -ENOMEM; | ||
666 | master->dummy_tx = tmp; | ||
667 | memset(tmp, 0, max_tx); | ||
668 | } | ||
669 | |||
670 | if (max_rx) { | ||
671 | tmp = krealloc(master->dummy_rx, max_rx, | ||
672 | GFP_KERNEL | GFP_DMA); | ||
673 | if (!tmp) | ||
674 | return -ENOMEM; | ||
675 | master->dummy_rx = tmp; | ||
676 | } | ||
677 | |||
678 | if (max_tx || max_rx) { | ||
679 | list_for_each_entry(xfer, &msg->transfers, | ||
680 | transfer_list) { | ||
681 | if (!xfer->tx_buf) | ||
682 | xfer->tx_buf = master->dummy_tx; | ||
683 | if (!xfer->rx_buf) | ||
684 | xfer->rx_buf = master->dummy_rx; | ||
685 | } | ||
686 | } | ||
687 | } | ||
688 | |||
689 | if (!master->can_dma) | 647 | if (!master->can_dma) |
690 | return 0; | 648 | return 0; |
691 | 649 | ||
@@ -742,6 +700,69 @@ static int spi_unmap_msg(struct spi_master *master, struct spi_message *msg) | |||
742 | 700 | ||
743 | return 0; | 701 | return 0; |
744 | } | 702 | } |
703 | #else /* !CONFIG_HAS_DMA */ | ||
704 | static inline int __spi_map_msg(struct spi_master *master, | ||
705 | struct spi_message *msg) | ||
706 | { | ||
707 | return 0; | ||
708 | } | ||
709 | |||
710 | static inline int spi_unmap_msg(struct spi_master *master, | ||
711 | struct spi_message *msg) | ||
712 | { | ||
713 | return 0; | ||
714 | } | ||
715 | #endif /* !CONFIG_HAS_DMA */ | ||
716 | |||
717 | static int spi_map_msg(struct spi_master *master, struct spi_message *msg) | ||
718 | { | ||
719 | struct spi_transfer *xfer; | ||
720 | void *tmp; | ||
721 | unsigned int max_tx, max_rx; | ||
722 | |||
723 | if (master->flags & (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX)) { | ||
724 | max_tx = 0; | ||
725 | max_rx = 0; | ||
726 | |||
727 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | ||
728 | if ((master->flags & SPI_MASTER_MUST_TX) && | ||
729 | !xfer->tx_buf) | ||
730 | max_tx = max(xfer->len, max_tx); | ||
731 | if ((master->flags & SPI_MASTER_MUST_RX) && | ||
732 | !xfer->rx_buf) | ||
733 | max_rx = max(xfer->len, max_rx); | ||
734 | } | ||
735 | |||
736 | if (max_tx) { | ||
737 | tmp = krealloc(master->dummy_tx, max_tx, | ||
738 | GFP_KERNEL | GFP_DMA); | ||
739 | if (!tmp) | ||
740 | return -ENOMEM; | ||
741 | master->dummy_tx = tmp; | ||
742 | memset(tmp, 0, max_tx); | ||
743 | } | ||
744 | |||
745 | if (max_rx) { | ||
746 | tmp = krealloc(master->dummy_rx, max_rx, | ||
747 | GFP_KERNEL | GFP_DMA); | ||
748 | if (!tmp) | ||
749 | return -ENOMEM; | ||
750 | master->dummy_rx = tmp; | ||
751 | } | ||
752 | |||
753 | if (max_tx || max_rx) { | ||
754 | list_for_each_entry(xfer, &msg->transfers, | ||
755 | transfer_list) { | ||
756 | if (!xfer->tx_buf) | ||
757 | xfer->tx_buf = master->dummy_tx; | ||
758 | if (!xfer->rx_buf) | ||
759 | xfer->rx_buf = master->dummy_rx; | ||
760 | } | ||
761 | } | ||
762 | } | ||
763 | |||
764 | return __spi_map_msg(master, msg); | ||
765 | } | ||
745 | 766 | ||
746 | /* | 767 | /* |
747 | * spi_transfer_one_message - Default implementation of transfer_one_message() | 768 | * spi_transfer_one_message - Default implementation of transfer_one_message() |
@@ -1151,7 +1172,6 @@ static int spi_master_initialize_queue(struct spi_master *master) | |||
1151 | { | 1172 | { |
1152 | int ret; | 1173 | int ret; |
1153 | 1174 | ||
1154 | master->queued = true; | ||
1155 | master->transfer = spi_queued_transfer; | 1175 | master->transfer = spi_queued_transfer; |
1156 | if (!master->transfer_one_message) | 1176 | if (!master->transfer_one_message) |
1157 | master->transfer_one_message = spi_transfer_one_message; | 1177 | master->transfer_one_message = spi_transfer_one_message; |
@@ -1162,6 +1182,7 @@ static int spi_master_initialize_queue(struct spi_master *master) | |||
1162 | dev_err(&master->dev, "problem initializing queue\n"); | 1182 | dev_err(&master->dev, "problem initializing queue\n"); |
1163 | goto err_init_queue; | 1183 | goto err_init_queue; |
1164 | } | 1184 | } |
1185 | master->queued = true; | ||
1165 | ret = spi_start_queue(master); | 1186 | ret = spi_start_queue(master); |
1166 | if (ret) { | 1187 | if (ret) { |
1167 | dev_err(&master->dev, "problem starting queue\n"); | 1188 | dev_err(&master->dev, "problem starting queue\n"); |
@@ -1171,8 +1192,8 @@ static int spi_master_initialize_queue(struct spi_master *master) | |||
1171 | return 0; | 1192 | return 0; |
1172 | 1193 | ||
1173 | err_start_queue: | 1194 | err_start_queue: |
1174 | err_init_queue: | ||
1175 | spi_destroy_queue(master); | 1195 | spi_destroy_queue(master); |
1196 | err_init_queue: | ||
1176 | return ret; | 1197 | return ret; |
1177 | } | 1198 | } |
1178 | 1199 | ||
@@ -1756,7 +1777,7 @@ EXPORT_SYMBOL_GPL(spi_busnum_to_master); | |||
1756 | */ | 1777 | */ |
1757 | int spi_setup(struct spi_device *spi) | 1778 | int spi_setup(struct spi_device *spi) |
1758 | { | 1779 | { |
1759 | unsigned bad_bits; | 1780 | unsigned bad_bits, ugly_bits; |
1760 | int status = 0; | 1781 | int status = 0; |
1761 | 1782 | ||
1762 | /* check mode to prevent that DUAL and QUAD set at the same time | 1783 | /* check mode to prevent that DUAL and QUAD set at the same time |
@@ -1776,6 +1797,15 @@ int spi_setup(struct spi_device *spi) | |||
1776 | * that aren't supported with their current master | 1797 | * that aren't supported with their current master |
1777 | */ | 1798 | */ |
1778 | bad_bits = spi->mode & ~spi->master->mode_bits; | 1799 | bad_bits = spi->mode & ~spi->master->mode_bits; |
1800 | ugly_bits = bad_bits & | ||
1801 | (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD); | ||
1802 | if (ugly_bits) { | ||
1803 | dev_warn(&spi->dev, | ||
1804 | "setup: ignoring unsupported mode bits %x\n", | ||
1805 | ugly_bits); | ||
1806 | spi->mode &= ~ugly_bits; | ||
1807 | bad_bits &= ~ugly_bits; | ||
1808 | } | ||
1779 | if (bad_bits) { | 1809 | if (bad_bits) { |
1780 | dev_err(&spi->dev, "setup: unsupported mode bits %x\n", | 1810 | dev_err(&spi->dev, "setup: unsupported mode bits %x\n", |
1781 | bad_bits); | 1811 | bad_bits); |
diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 4144a75e5f71..c270c9ae6d27 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c | |||
@@ -517,7 +517,7 @@ int imx_drm_encoder_get_mux_id(struct device_node *node, | |||
517 | of_node_put(port); | 517 | of_node_put(port); |
518 | if (port == imx_crtc->port) { | 518 | if (port == imx_crtc->port) { |
519 | ret = of_graph_parse_endpoint(ep, &endpoint); | 519 | ret = of_graph_parse_endpoint(ep, &endpoint); |
520 | return ret ? ret : endpoint.id; | 520 | return ret ? ret : endpoint.port; |
521 | } | 521 | } |
522 | } while (ep); | 522 | } while (ep); |
523 | 523 | ||
@@ -675,6 +675,11 @@ static int imx_drm_platform_probe(struct platform_device *pdev) | |||
675 | if (!remote || !of_device_is_available(remote)) { | 675 | if (!remote || !of_device_is_available(remote)) { |
676 | of_node_put(remote); | 676 | of_node_put(remote); |
677 | continue; | 677 | continue; |
678 | } else if (!of_device_is_available(remote->parent)) { | ||
679 | dev_warn(&pdev->dev, "parent device of %s is not available\n", | ||
680 | remote->full_name); | ||
681 | of_node_put(remote); | ||
682 | continue; | ||
678 | } | 683 | } |
679 | 684 | ||
680 | ret = imx_drm_add_component(&pdev->dev, remote); | 685 | ret = imx_drm_add_component(&pdev->dev, remote); |
diff --git a/drivers/staging/imx-drm/imx-tve.c b/drivers/staging/imx-drm/imx-tve.c index 575533f4fd64..a23f4f773146 100644 --- a/drivers/staging/imx-drm/imx-tve.c +++ b/drivers/staging/imx-drm/imx-tve.c | |||
@@ -582,7 +582,7 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data) | |||
582 | tve->dev = dev; | 582 | tve->dev = dev; |
583 | spin_lock_init(&tve->lock); | 583 | spin_lock_init(&tve->lock); |
584 | 584 | ||
585 | ddc_node = of_parse_phandle(np, "i2c-ddc-bus", 0); | 585 | ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); |
586 | if (ddc_node) { | 586 | if (ddc_node) { |
587 | tve->ddc = of_find_i2c_adapter_by_node(ddc_node); | 587 | tve->ddc = of_find_i2c_adapter_by_node(ddc_node); |
588 | of_node_put(ddc_node); | 588 | of_node_put(ddc_node); |
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 8c101cbbee97..acc8184c46cd 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c | |||
@@ -1247,9 +1247,18 @@ static int vpfe_stop_streaming(struct vb2_queue *vq) | |||
1247 | struct vpfe_fh *fh = vb2_get_drv_priv(vq); | 1247 | struct vpfe_fh *fh = vb2_get_drv_priv(vq); |
1248 | struct vpfe_video_device *video = fh->video; | 1248 | struct vpfe_video_device *video = fh->video; |
1249 | 1249 | ||
1250 | if (!vb2_is_streaming(vq)) | ||
1251 | return 0; | ||
1252 | /* release all active buffers */ | 1250 | /* release all active buffers */ |
1251 | if (video->cur_frm == video->next_frm) { | ||
1252 | vb2_buffer_done(&video->cur_frm->vb, VB2_BUF_STATE_ERROR); | ||
1253 | } else { | ||
1254 | if (video->cur_frm != NULL) | ||
1255 | vb2_buffer_done(&video->cur_frm->vb, | ||
1256 | VB2_BUF_STATE_ERROR); | ||
1257 | if (video->next_frm != NULL) | ||
1258 | vb2_buffer_done(&video->next_frm->vb, | ||
1259 | VB2_BUF_STATE_ERROR); | ||
1260 | } | ||
1261 | |||
1253 | while (!list_empty(&video->dma_queue)) { | 1262 | while (!list_empty(&video->dma_queue)) { |
1254 | video->next_frm = list_entry(video->dma_queue.next, | 1263 | video->next_frm = list_entry(video->dma_queue.next, |
1255 | struct vpfe_cap_buffer, list); | 1264 | struct vpfe_cap_buffer, list); |
diff --git a/drivers/staging/media/sn9c102/sn9c102_devtable.h b/drivers/staging/media/sn9c102/sn9c102_devtable.h index b3d2cc729657..4ba569258498 100644 --- a/drivers/staging/media/sn9c102/sn9c102_devtable.h +++ b/drivers/staging/media/sn9c102/sn9c102_devtable.h | |||
@@ -48,10 +48,8 @@ static const struct usb_device_id sn9c102_id_table[] = { | |||
48 | { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), }, | 48 | { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), }, |
49 | /* { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */ | 49 | /* { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */ |
50 | { SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), }, | 50 | { SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), }, |
51 | #endif | ||
52 | { SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), }, | 51 | { SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), }, |
53 | { SN9C102_USB_DEVICE(0x0c45, 0x6025, BRIDGE_SN9C102), }, | 52 | { SN9C102_USB_DEVICE(0x0c45, 0x6025, BRIDGE_SN9C102), }, |
54 | #if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE | ||
55 | { SN9C102_USB_DEVICE(0x0c45, 0x6028, BRIDGE_SN9C102), }, | 53 | { SN9C102_USB_DEVICE(0x0c45, 0x6028, BRIDGE_SN9C102), }, |
56 | { SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), }, | 54 | { SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), }, |
57 | { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), }, | 55 | { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), }, |
diff --git a/drivers/staging/rtl8723au/os_dep/os_intfs.c b/drivers/staging/rtl8723au/os_dep/os_intfs.c index 57eca7a45672..4fe751f7c2bf 100644 --- a/drivers/staging/rtl8723au/os_dep/os_intfs.c +++ b/drivers/staging/rtl8723au/os_dep/os_intfs.c | |||
@@ -953,8 +953,6 @@ static int netdev_close(struct net_device *pnetdev) | |||
953 | #endif /* CONFIG_8723AU_P2P */ | 953 | #endif /* CONFIG_8723AU_P2P */ |
954 | 954 | ||
955 | rtw_scan_abort23a(padapter); | 955 | rtw_scan_abort23a(padapter); |
956 | /* set this at the end */ | ||
957 | padapter->rtw_wdev->iftype = NL80211_IFTYPE_MONITOR; | ||
958 | 956 | ||
959 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-871x_drv - drv_close\n")); | 957 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-871x_drv - drv_close\n")); |
960 | DBG_8723A("-871x_drv - drv_close, bup =%d\n", padapter->bup); | 958 | DBG_8723A("-871x_drv - drv_close, bup =%d\n", padapter->bup); |
diff --git a/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c b/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c index c49160e477d8..07e542e5d156 100644 --- a/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c +++ b/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c | |||
@@ -26,7 +26,7 @@ unsigned int ffaddr2pipehdl23a(struct dvobj_priv *pdvobj, u32 addr) | |||
26 | if (addr == RECV_BULK_IN_ADDR) { | 26 | if (addr == RECV_BULK_IN_ADDR) { |
27 | pipe = usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[0]); | 27 | pipe = usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[0]); |
28 | } else if (addr == RECV_INT_IN_ADDR) { | 28 | } else if (addr == RECV_INT_IN_ADDR) { |
29 | pipe = usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[1]); | 29 | pipe = usb_rcvintpipe(pusbd, pdvobj->RtInPipe[1]); |
30 | } else if (addr < HW_QUEUE_ENTRY) { | 30 | } else if (addr < HW_QUEUE_ENTRY) { |
31 | ep_num = pdvobj->Queue2Pipe[addr]; | 31 | ep_num = pdvobj->Queue2Pipe[addr]; |
32 | pipe = usb_sndbulkpipe(pusbd, ep_num); | 32 | pipe = usb_sndbulkpipe(pusbd, ep_num); |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 78cab13bbb1b..46588c85d39b 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -1593,7 +1593,9 @@ int iscsit_process_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1593 | * Initiator is expecting a NopIN ping reply.. | 1593 | * Initiator is expecting a NopIN ping reply.. |
1594 | */ | 1594 | */ |
1595 | if (hdr->itt != RESERVED_ITT) { | 1595 | if (hdr->itt != RESERVED_ITT) { |
1596 | BUG_ON(!cmd); | 1596 | if (!cmd) |
1597 | return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, | ||
1598 | (unsigned char *)hdr); | ||
1597 | 1599 | ||
1598 | spin_lock_bh(&conn->cmd_lock); | 1600 | spin_lock_bh(&conn->cmd_lock); |
1599 | list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); | 1601 | list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); |
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 6960f22909ae..302eb3b78715 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h | |||
@@ -775,6 +775,7 @@ struct iscsi_np { | |||
775 | int np_ip_proto; | 775 | int np_ip_proto; |
776 | int np_sock_type; | 776 | int np_sock_type; |
777 | enum np_thread_state_table np_thread_state; | 777 | enum np_thread_state_table np_thread_state; |
778 | bool enabled; | ||
778 | enum iscsi_timer_flags_table np_login_timer_flags; | 779 | enum iscsi_timer_flags_table np_login_timer_flags; |
779 | u32 np_exports; | 780 | u32 np_exports; |
780 | enum np_flags_table np_flags; | 781 | enum np_flags_table np_flags; |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 8739b98f6f93..ca31fa1b8a4b 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
@@ -436,7 +436,7 @@ static int iscsi_login_zero_tsih_s2( | |||
436 | } | 436 | } |
437 | off = mrdsl % PAGE_SIZE; | 437 | off = mrdsl % PAGE_SIZE; |
438 | if (!off) | 438 | if (!off) |
439 | return 0; | 439 | goto check_prot; |
440 | 440 | ||
441 | if (mrdsl < PAGE_SIZE) | 441 | if (mrdsl < PAGE_SIZE) |
442 | mrdsl = PAGE_SIZE; | 442 | mrdsl = PAGE_SIZE; |
@@ -452,6 +452,31 @@ static int iscsi_login_zero_tsih_s2( | |||
452 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | 452 | ISCSI_LOGIN_STATUS_NO_RESOURCES); |
453 | return -1; | 453 | return -1; |
454 | } | 454 | } |
455 | /* | ||
456 | * ISER currently requires that ImmediateData + Unsolicited | ||
457 | * Data be disabled when protection / signature MRs are enabled. | ||
458 | */ | ||
459 | check_prot: | ||
460 | if (sess->se_sess->sup_prot_ops & | ||
461 | (TARGET_PROT_DOUT_STRIP | TARGET_PROT_DOUT_PASS | | ||
462 | TARGET_PROT_DOUT_INSERT)) { | ||
463 | |||
464 | sprintf(buf, "ImmediateData=No"); | ||
465 | if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) { | ||
466 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
467 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
468 | return -1; | ||
469 | } | ||
470 | |||
471 | sprintf(buf, "InitialR2T=Yes"); | ||
472 | if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) { | ||
473 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
474 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
475 | return -1; | ||
476 | } | ||
477 | pr_debug("Forcing ImmediateData=No + InitialR2T=Yes for" | ||
478 | " T10-PI enabled ISER session\n"); | ||
479 | } | ||
455 | } | 480 | } |
456 | 481 | ||
457 | return 0; | 482 | return 0; |
@@ -984,6 +1009,7 @@ int iscsi_target_setup_login_socket( | |||
984 | } | 1009 | } |
985 | 1010 | ||
986 | np->np_transport = t; | 1011 | np->np_transport = t; |
1012 | np->enabled = true; | ||
987 | return 0; | 1013 | return 0; |
988 | } | 1014 | } |
989 | 1015 | ||
diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c index eb96b20dc09e..ca1811858afd 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c | |||
@@ -184,6 +184,7 @@ static void iscsit_clear_tpg_np_login_thread( | |||
184 | return; | 184 | return; |
185 | } | 185 | } |
186 | 186 | ||
187 | tpg_np->tpg_np->enabled = false; | ||
187 | iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg, shutdown); | 188 | iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg, shutdown); |
188 | } | 189 | } |
189 | 190 | ||
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 65001e133670..26416c15d65c 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -798,10 +798,10 @@ int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) | |||
798 | pr_err("emulate_write_cache not supported for pSCSI\n"); | 798 | pr_err("emulate_write_cache not supported for pSCSI\n"); |
799 | return -EINVAL; | 799 | return -EINVAL; |
800 | } | 800 | } |
801 | if (dev->transport->get_write_cache) { | 801 | if (flag && |
802 | pr_warn("emulate_write_cache cannot be changed when underlying" | 802 | dev->transport->get_write_cache) { |
803 | " HW reports WriteCacheEnabled, ignoring request\n"); | 803 | pr_err("emulate_write_cache not supported for this device\n"); |
804 | return 0; | 804 | return -EINVAL; |
805 | } | 805 | } |
806 | 806 | ||
807 | dev->dev_attrib.emulate_write_cache = flag; | 807 | dev->dev_attrib.emulate_write_cache = flag; |
@@ -936,6 +936,10 @@ int se_dev_set_pi_prot_type(struct se_device *dev, int flag) | |||
936 | return 0; | 936 | return 0; |
937 | } | 937 | } |
938 | if (!dev->transport->init_prot || !dev->transport->free_prot) { | 938 | if (!dev->transport->init_prot || !dev->transport->free_prot) { |
939 | /* 0 is only allowed value for non-supporting backends */ | ||
940 | if (flag == 0) | ||
941 | return 0; | ||
942 | |||
939 | pr_err("DIF protection not supported by backend: %s\n", | 943 | pr_err("DIF protection not supported by backend: %s\n", |
940 | dev->transport->name); | 944 | dev->transport->name); |
941 | return -ENOSYS; | 945 | return -ENOSYS; |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index d4b98690a736..789aa9eb0a1e 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -1113,6 +1113,7 @@ void transport_init_se_cmd( | |||
1113 | init_completion(&cmd->cmd_wait_comp); | 1113 | init_completion(&cmd->cmd_wait_comp); |
1114 | init_completion(&cmd->task_stop_comp); | 1114 | init_completion(&cmd->task_stop_comp); |
1115 | spin_lock_init(&cmd->t_state_lock); | 1115 | spin_lock_init(&cmd->t_state_lock); |
1116 | kref_init(&cmd->cmd_kref); | ||
1116 | cmd->transport_state = CMD_T_DEV_ACTIVE; | 1117 | cmd->transport_state = CMD_T_DEV_ACTIVE; |
1117 | 1118 | ||
1118 | cmd->se_tfo = tfo; | 1119 | cmd->se_tfo = tfo; |
@@ -2357,7 +2358,6 @@ int target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd, | |||
2357 | unsigned long flags; | 2358 | unsigned long flags; |
2358 | int ret = 0; | 2359 | int ret = 0; |
2359 | 2360 | ||
2360 | kref_init(&se_cmd->cmd_kref); | ||
2361 | /* | 2361 | /* |
2362 | * Add a second kref if the fabric caller is expecting to handle | 2362 | * Add a second kref if the fabric caller is expecting to handle |
2363 | * fabric acknowledgement that requires two target_put_sess_cmd() | 2363 | * fabric acknowledgement that requires two target_put_sess_cmd() |
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index 01cf37f212c3..f5fd515b2bee 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c | |||
@@ -90,18 +90,18 @@ static void ft_free_cmd(struct ft_cmd *cmd) | |||
90 | { | 90 | { |
91 | struct fc_frame *fp; | 91 | struct fc_frame *fp; |
92 | struct fc_lport *lport; | 92 | struct fc_lport *lport; |
93 | struct se_session *se_sess; | 93 | struct ft_sess *sess; |
94 | 94 | ||
95 | if (!cmd) | 95 | if (!cmd) |
96 | return; | 96 | return; |
97 | se_sess = cmd->sess->se_sess; | 97 | sess = cmd->sess; |
98 | fp = cmd->req_frame; | 98 | fp = cmd->req_frame; |
99 | lport = fr_dev(fp); | 99 | lport = fr_dev(fp); |
100 | if (fr_seq(fp)) | 100 | if (fr_seq(fp)) |
101 | lport->tt.seq_release(fr_seq(fp)); | 101 | lport->tt.seq_release(fr_seq(fp)); |
102 | fc_frame_free(fp); | 102 | fc_frame_free(fp); |
103 | percpu_ida_free(&se_sess->sess_tag_pool, cmd->se_cmd.map_tag); | 103 | percpu_ida_free(&sess->se_sess->sess_tag_pool, cmd->se_cmd.map_tag); |
104 | ft_sess_put(cmd->sess); /* undo get from lookup at recv */ | 104 | ft_sess_put(sess); /* undo get from lookup at recv */ |
105 | } | 105 | } |
106 | 106 | ||
107 | void ft_release_cmd(struct se_cmd *se_cmd) | 107 | void ft_release_cmd(struct se_cmd *se_cmd) |
diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c index 96109a9972b6..84b4bfb84344 100644 --- a/drivers/xen/events/events_fifo.c +++ b/drivers/xen/events/events_fifo.c | |||
@@ -66,7 +66,22 @@ static DEFINE_PER_CPU(struct evtchn_fifo_queue, cpu_queue); | |||
66 | static event_word_t *event_array[MAX_EVENT_ARRAY_PAGES] __read_mostly; | 66 | static event_word_t *event_array[MAX_EVENT_ARRAY_PAGES] __read_mostly; |
67 | static unsigned event_array_pages __read_mostly; | 67 | static unsigned event_array_pages __read_mostly; |
68 | 68 | ||
69 | /* | ||
70 | * sync_set_bit() and friends must be unsigned long aligned on non-x86 | ||
71 | * platforms. | ||
72 | */ | ||
73 | #if !defined(CONFIG_X86) && BITS_PER_LONG > 32 | ||
74 | |||
75 | #define BM(w) (unsigned long *)((unsigned long)w & ~0x7UL) | ||
76 | #define EVTCHN_FIFO_BIT(b, w) \ | ||
77 | (((unsigned long)w & 0x4UL) ? (EVTCHN_FIFO_ ##b + 32) : EVTCHN_FIFO_ ##b) | ||
78 | |||
79 | #else | ||
80 | |||
69 | #define BM(w) ((unsigned long *)(w)) | 81 | #define BM(w) ((unsigned long *)(w)) |
82 | #define EVTCHN_FIFO_BIT(b, w) EVTCHN_FIFO_ ##b | ||
83 | |||
84 | #endif | ||
70 | 85 | ||
71 | static inline event_word_t *event_word_from_port(unsigned port) | 86 | static inline event_word_t *event_word_from_port(unsigned port) |
72 | { | 87 | { |
@@ -161,33 +176,38 @@ static void evtchn_fifo_bind_to_cpu(struct irq_info *info, unsigned cpu) | |||
161 | static void evtchn_fifo_clear_pending(unsigned port) | 176 | static void evtchn_fifo_clear_pending(unsigned port) |
162 | { | 177 | { |
163 | event_word_t *word = event_word_from_port(port); | 178 | event_word_t *word = event_word_from_port(port); |
164 | sync_clear_bit(EVTCHN_FIFO_PENDING, BM(word)); | 179 | sync_clear_bit(EVTCHN_FIFO_BIT(PENDING, word), BM(word)); |
165 | } | 180 | } |
166 | 181 | ||
167 | static void evtchn_fifo_set_pending(unsigned port) | 182 | static void evtchn_fifo_set_pending(unsigned port) |
168 | { | 183 | { |
169 | event_word_t *word = event_word_from_port(port); | 184 | event_word_t *word = event_word_from_port(port); |
170 | sync_set_bit(EVTCHN_FIFO_PENDING, BM(word)); | 185 | sync_set_bit(EVTCHN_FIFO_BIT(PENDING, word), BM(word)); |
171 | } | 186 | } |
172 | 187 | ||
173 | static bool evtchn_fifo_is_pending(unsigned port) | 188 | static bool evtchn_fifo_is_pending(unsigned port) |
174 | { | 189 | { |
175 | event_word_t *word = event_word_from_port(port); | 190 | event_word_t *word = event_word_from_port(port); |
176 | return sync_test_bit(EVTCHN_FIFO_PENDING, BM(word)); | 191 | return sync_test_bit(EVTCHN_FIFO_BIT(PENDING, word), BM(word)); |
177 | } | 192 | } |
178 | 193 | ||
179 | static bool evtchn_fifo_test_and_set_mask(unsigned port) | 194 | static bool evtchn_fifo_test_and_set_mask(unsigned port) |
180 | { | 195 | { |
181 | event_word_t *word = event_word_from_port(port); | 196 | event_word_t *word = event_word_from_port(port); |
182 | return sync_test_and_set_bit(EVTCHN_FIFO_MASKED, BM(word)); | 197 | return sync_test_and_set_bit(EVTCHN_FIFO_BIT(MASKED, word), BM(word)); |
183 | } | 198 | } |
184 | 199 | ||
185 | static void evtchn_fifo_mask(unsigned port) | 200 | static void evtchn_fifo_mask(unsigned port) |
186 | { | 201 | { |
187 | event_word_t *word = event_word_from_port(port); | 202 | event_word_t *word = event_word_from_port(port); |
188 | sync_set_bit(EVTCHN_FIFO_MASKED, BM(word)); | 203 | sync_set_bit(EVTCHN_FIFO_BIT(MASKED, word), BM(word)); |
189 | } | 204 | } |
190 | 205 | ||
206 | static bool evtchn_fifo_is_masked(unsigned port) | ||
207 | { | ||
208 | event_word_t *word = event_word_from_port(port); | ||
209 | return sync_test_bit(EVTCHN_FIFO_BIT(MASKED, word), BM(word)); | ||
210 | } | ||
191 | /* | 211 | /* |
192 | * Clear MASKED, spinning if BUSY is set. | 212 | * Clear MASKED, spinning if BUSY is set. |
193 | */ | 213 | */ |
@@ -211,7 +231,7 @@ static void evtchn_fifo_unmask(unsigned port) | |||
211 | BUG_ON(!irqs_disabled()); | 231 | BUG_ON(!irqs_disabled()); |
212 | 232 | ||
213 | clear_masked(word); | 233 | clear_masked(word); |
214 | if (sync_test_bit(EVTCHN_FIFO_PENDING, BM(word))) { | 234 | if (evtchn_fifo_is_pending(port)) { |
215 | struct evtchn_unmask unmask = { .port = port }; | 235 | struct evtchn_unmask unmask = { .port = port }; |
216 | (void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask); | 236 | (void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask); |
217 | } | 237 | } |
@@ -243,7 +263,7 @@ static void handle_irq_for_port(unsigned port) | |||
243 | 263 | ||
244 | static void consume_one_event(unsigned cpu, | 264 | static void consume_one_event(unsigned cpu, |
245 | struct evtchn_fifo_control_block *control_block, | 265 | struct evtchn_fifo_control_block *control_block, |
246 | unsigned priority, uint32_t *ready) | 266 | unsigned priority, unsigned long *ready) |
247 | { | 267 | { |
248 | struct evtchn_fifo_queue *q = &per_cpu(cpu_queue, cpu); | 268 | struct evtchn_fifo_queue *q = &per_cpu(cpu_queue, cpu); |
249 | uint32_t head; | 269 | uint32_t head; |
@@ -273,10 +293,9 @@ static void consume_one_event(unsigned cpu, | |||
273 | * copy of the ready word. | 293 | * copy of the ready word. |
274 | */ | 294 | */ |
275 | if (head == 0) | 295 | if (head == 0) |
276 | clear_bit(priority, BM(ready)); | 296 | clear_bit(priority, ready); |
277 | 297 | ||
278 | if (sync_test_bit(EVTCHN_FIFO_PENDING, BM(word)) | 298 | if (evtchn_fifo_is_pending(port) && !evtchn_fifo_is_masked(port)) |
279 | && !sync_test_bit(EVTCHN_FIFO_MASKED, BM(word))) | ||
280 | handle_irq_for_port(port); | 299 | handle_irq_for_port(port); |
281 | 300 | ||
282 | q->head[priority] = head; | 301 | q->head[priority] = head; |
@@ -285,7 +304,7 @@ static void consume_one_event(unsigned cpu, | |||
285 | static void evtchn_fifo_handle_events(unsigned cpu) | 304 | static void evtchn_fifo_handle_events(unsigned cpu) |
286 | { | 305 | { |
287 | struct evtchn_fifo_control_block *control_block; | 306 | struct evtchn_fifo_control_block *control_block; |
288 | uint32_t ready; | 307 | unsigned long ready; |
289 | unsigned q; | 308 | unsigned q; |
290 | 309 | ||
291 | control_block = per_cpu(cpu_control_block, cpu); | 310 | control_block = per_cpu(cpu_control_block, cpu); |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 2ad7de94efef..2f6d7b13b5bd 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -3120,6 +3120,8 @@ process_slot: | |||
3120 | } else if (type == BTRFS_FILE_EXTENT_INLINE) { | 3120 | } else if (type == BTRFS_FILE_EXTENT_INLINE) { |
3121 | u64 skip = 0; | 3121 | u64 skip = 0; |
3122 | u64 trim = 0; | 3122 | u64 trim = 0; |
3123 | u64 aligned_end = 0; | ||
3124 | |||
3123 | if (off > key.offset) { | 3125 | if (off > key.offset) { |
3124 | skip = off - key.offset; | 3126 | skip = off - key.offset; |
3125 | new_key.offset += skip; | 3127 | new_key.offset += skip; |
@@ -3136,9 +3138,11 @@ process_slot: | |||
3136 | size -= skip + trim; | 3138 | size -= skip + trim; |
3137 | datal -= skip + trim; | 3139 | datal -= skip + trim; |
3138 | 3140 | ||
3141 | aligned_end = ALIGN(new_key.offset + datal, | ||
3142 | root->sectorsize); | ||
3139 | ret = btrfs_drop_extents(trans, root, inode, | 3143 | ret = btrfs_drop_extents(trans, root, inode, |
3140 | new_key.offset, | 3144 | new_key.offset, |
3141 | new_key.offset + datal, | 3145 | aligned_end, |
3142 | 1); | 3146 | 1); |
3143 | if (ret) { | 3147 | if (ret) { |
3144 | if (ret != -EOPNOTSUPP) | 3148 | if (ret != -EOPNOTSUPP) |
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index eb6537a08c1b..fd38b5053479 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
@@ -1668,7 +1668,7 @@ static int get_first_ref(struct btrfs_root *root, u64 ino, | |||
1668 | goto out; | 1668 | goto out; |
1669 | } | 1669 | } |
1670 | 1670 | ||
1671 | if (key.type == BTRFS_INODE_REF_KEY) { | 1671 | if (found_key.type == BTRFS_INODE_REF_KEY) { |
1672 | struct btrfs_inode_ref *iref; | 1672 | struct btrfs_inode_ref *iref; |
1673 | iref = btrfs_item_ptr(path->nodes[0], path->slots[0], | 1673 | iref = btrfs_item_ptr(path->nodes[0], path->slots[0], |
1674 | struct btrfs_inode_ref); | 1674 | struct btrfs_inode_ref); |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index aadc2b68678b..a22d667f1069 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1737,6 +1737,9 @@ cifs_inode_needs_reval(struct inode *inode) | |||
1737 | if (cifs_i->time == 0) | 1737 | if (cifs_i->time == 0) |
1738 | return true; | 1738 | return true; |
1739 | 1739 | ||
1740 | if (!cifs_sb->actimeo) | ||
1741 | return true; | ||
1742 | |||
1740 | if (!time_in_range(jiffies, cifs_i->time, | 1743 | if (!time_in_range(jiffies, cifs_i->time, |
1741 | cifs_i->time + cifs_sb->actimeo)) | 1744 | cifs_i->time + cifs_sb->actimeo)) |
1742 | return true; | 1745 | return true; |
@@ -657,10 +657,10 @@ int setup_arg_pages(struct linux_binprm *bprm, | |||
657 | unsigned long rlim_stack; | 657 | unsigned long rlim_stack; |
658 | 658 | ||
659 | #ifdef CONFIG_STACK_GROWSUP | 659 | #ifdef CONFIG_STACK_GROWSUP |
660 | /* Limit stack size to 1GB */ | 660 | /* Limit stack size */ |
661 | stack_base = rlimit_max(RLIMIT_STACK); | 661 | stack_base = rlimit_max(RLIMIT_STACK); |
662 | if (stack_base > (1 << 30)) | 662 | if (stack_base > STACK_SIZE_MAX) |
663 | stack_base = 1 << 30; | 663 | stack_base = STACK_SIZE_MAX; |
664 | 664 | ||
665 | /* Make sure we didn't let the argument array grow too large. */ | 665 | /* Make sure we didn't let the argument array grow too large. */ |
666 | if (vma->vm_end - vma->vm_start > stack_base) | 666 | if (vma->vm_end - vma->vm_start > stack_base) |
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index e01ea4a14a01..5e9a80cfc3d8 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c | |||
@@ -610,6 +610,7 @@ static void kernfs_put_open_node(struct kernfs_node *kn, | |||
610 | static int kernfs_fop_open(struct inode *inode, struct file *file) | 610 | static int kernfs_fop_open(struct inode *inode, struct file *file) |
611 | { | 611 | { |
612 | struct kernfs_node *kn = file->f_path.dentry->d_fsdata; | 612 | struct kernfs_node *kn = file->f_path.dentry->d_fsdata; |
613 | struct kernfs_root *root = kernfs_root(kn); | ||
613 | const struct kernfs_ops *ops; | 614 | const struct kernfs_ops *ops; |
614 | struct kernfs_open_file *of; | 615 | struct kernfs_open_file *of; |
615 | bool has_read, has_write, has_mmap; | 616 | bool has_read, has_write, has_mmap; |
@@ -624,14 +625,16 @@ static int kernfs_fop_open(struct inode *inode, struct file *file) | |||
624 | has_write = ops->write || ops->mmap; | 625 | has_write = ops->write || ops->mmap; |
625 | has_mmap = ops->mmap; | 626 | has_mmap = ops->mmap; |
626 | 627 | ||
627 | /* check perms and supported operations */ | 628 | /* see the flag definition for details */ |
628 | if ((file->f_mode & FMODE_WRITE) && | 629 | if (root->flags & KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK) { |
629 | (!(inode->i_mode & S_IWUGO) || !has_write)) | 630 | if ((file->f_mode & FMODE_WRITE) && |
630 | goto err_out; | 631 | (!(inode->i_mode & S_IWUGO) || !has_write)) |
632 | goto err_out; | ||
631 | 633 | ||
632 | if ((file->f_mode & FMODE_READ) && | 634 | if ((file->f_mode & FMODE_READ) && |
633 | (!(inode->i_mode & S_IRUGO) || !has_read)) | 635 | (!(inode->i_mode & S_IRUGO) || !has_read)) |
634 | goto err_out; | 636 | goto err_out; |
637 | } | ||
635 | 638 | ||
636 | /* allocate a kernfs_open_file for the file */ | 639 | /* allocate a kernfs_open_file for the file */ |
637 | error = -ENOMEM; | 640 | error = -ENOMEM; |
diff --git a/fs/locks.c b/fs/locks.c index e663aeac579e..e390bd9ae068 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -389,18 +389,6 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl, | |||
389 | fl->fl_ops = NULL; | 389 | fl->fl_ops = NULL; |
390 | fl->fl_lmops = NULL; | 390 | fl->fl_lmops = NULL; |
391 | 391 | ||
392 | /* Ensure that fl->fl_filp has compatible f_mode */ | ||
393 | switch (l->l_type) { | ||
394 | case F_RDLCK: | ||
395 | if (!(filp->f_mode & FMODE_READ)) | ||
396 | return -EBADF; | ||
397 | break; | ||
398 | case F_WRLCK: | ||
399 | if (!(filp->f_mode & FMODE_WRITE)) | ||
400 | return -EBADF; | ||
401 | break; | ||
402 | } | ||
403 | |||
404 | return assign_type(fl, l->l_type); | 392 | return assign_type(fl, l->l_type); |
405 | } | 393 | } |
406 | 394 | ||
@@ -2034,6 +2022,22 @@ static int do_lock_file_wait(struct file *filp, unsigned int cmd, | |||
2034 | return error; | 2022 | return error; |
2035 | } | 2023 | } |
2036 | 2024 | ||
2025 | /* Ensure that fl->fl_filp has compatible f_mode for F_SETLK calls */ | ||
2026 | static int | ||
2027 | check_fmode_for_setlk(struct file_lock *fl) | ||
2028 | { | ||
2029 | switch (fl->fl_type) { | ||
2030 | case F_RDLCK: | ||
2031 | if (!(fl->fl_file->f_mode & FMODE_READ)) | ||
2032 | return -EBADF; | ||
2033 | break; | ||
2034 | case F_WRLCK: | ||
2035 | if (!(fl->fl_file->f_mode & FMODE_WRITE)) | ||
2036 | return -EBADF; | ||
2037 | } | ||
2038 | return 0; | ||
2039 | } | ||
2040 | |||
2037 | /* Apply the lock described by l to an open file descriptor. | 2041 | /* Apply the lock described by l to an open file descriptor. |
2038 | * This implements both the F_SETLK and F_SETLKW commands of fcntl(). | 2042 | * This implements both the F_SETLK and F_SETLKW commands of fcntl(). |
2039 | */ | 2043 | */ |
@@ -2071,6 +2075,10 @@ again: | |||
2071 | if (error) | 2075 | if (error) |
2072 | goto out; | 2076 | goto out; |
2073 | 2077 | ||
2078 | error = check_fmode_for_setlk(file_lock); | ||
2079 | if (error) | ||
2080 | goto out; | ||
2081 | |||
2074 | /* | 2082 | /* |
2075 | * If the cmd is requesting file-private locks, then set the | 2083 | * If the cmd is requesting file-private locks, then set the |
2076 | * FL_OFDLCK flag and override the owner. | 2084 | * FL_OFDLCK flag and override the owner. |
@@ -2206,6 +2214,10 @@ again: | |||
2206 | if (error) | 2214 | if (error) |
2207 | goto out; | 2215 | goto out; |
2208 | 2216 | ||
2217 | error = check_fmode_for_setlk(file_lock); | ||
2218 | if (error) | ||
2219 | goto out; | ||
2220 | |||
2209 | /* | 2221 | /* |
2210 | * If the cmd is requesting file-private locks, then set the | 2222 | * If the cmd is requesting file-private locks, then set the |
2211 | * FL_OFDLCK flag and override the owner. | 2223 | * FL_OFDLCK flag and override the owner. |
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 6f3f392d48af..b6f46013dddf 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c | |||
@@ -402,8 +402,10 @@ sort_pacl(struct posix_acl *pacl) | |||
402 | * by uid/gid. */ | 402 | * by uid/gid. */ |
403 | int i, j; | 403 | int i, j; |
404 | 404 | ||
405 | if (pacl->a_count <= 4) | 405 | /* no users or groups */ |
406 | return; /* no users or groups */ | 406 | if (!pacl || pacl->a_count <= 4) |
407 | return; | ||
408 | |||
407 | i = 1; | 409 | i = 1; |
408 | while (pacl->a_entries[i].e_tag == ACL_USER) | 410 | while (pacl->a_entries[i].e_tag == ACL_USER) |
409 | i++; | 411 | i++; |
@@ -530,13 +532,12 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) | |||
530 | 532 | ||
531 | /* | 533 | /* |
532 | * ACLs with no ACEs are treated differently in the inheritable | 534 | * ACLs with no ACEs are treated differently in the inheritable |
533 | * and effective cases: when there are no inheritable ACEs, we | 535 | * and effective cases: when there are no inheritable ACEs, |
534 | * set a zero-length default posix acl: | 536 | * calls ->set_acl with a NULL ACL structure. |
535 | */ | 537 | */ |
536 | if (state->empty && (flags & NFS4_ACL_TYPE_DEFAULT)) { | 538 | if (state->empty && (flags & NFS4_ACL_TYPE_DEFAULT)) |
537 | pacl = posix_acl_alloc(0, GFP_KERNEL); | 539 | return NULL; |
538 | return pacl ? pacl : ERR_PTR(-ENOMEM); | 540 | |
539 | } | ||
540 | /* | 541 | /* |
541 | * When there are no effective ACEs, the following will end | 542 | * When there are no effective ACEs, the following will end |
542 | * up setting a 3-element effective posix ACL with all | 543 | * up setting a 3-element effective posix ACL with all |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 3ba65979a3cd..32b699bebb9c 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -1078,6 +1078,18 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name) | |||
1078 | return NULL; | 1078 | return NULL; |
1079 | } | 1079 | } |
1080 | clp->cl_name.len = name.len; | 1080 | clp->cl_name.len = name.len; |
1081 | INIT_LIST_HEAD(&clp->cl_sessions); | ||
1082 | idr_init(&clp->cl_stateids); | ||
1083 | atomic_set(&clp->cl_refcount, 0); | ||
1084 | clp->cl_cb_state = NFSD4_CB_UNKNOWN; | ||
1085 | INIT_LIST_HEAD(&clp->cl_idhash); | ||
1086 | INIT_LIST_HEAD(&clp->cl_openowners); | ||
1087 | INIT_LIST_HEAD(&clp->cl_delegations); | ||
1088 | INIT_LIST_HEAD(&clp->cl_lru); | ||
1089 | INIT_LIST_HEAD(&clp->cl_callbacks); | ||
1090 | INIT_LIST_HEAD(&clp->cl_revoked); | ||
1091 | spin_lock_init(&clp->cl_lock); | ||
1092 | rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table"); | ||
1081 | return clp; | 1093 | return clp; |
1082 | } | 1094 | } |
1083 | 1095 | ||
@@ -1095,6 +1107,7 @@ free_client(struct nfs4_client *clp) | |||
1095 | WARN_ON_ONCE(atomic_read(&ses->se_ref)); | 1107 | WARN_ON_ONCE(atomic_read(&ses->se_ref)); |
1096 | free_session(ses); | 1108 | free_session(ses); |
1097 | } | 1109 | } |
1110 | rpc_destroy_wait_queue(&clp->cl_cb_waitq); | ||
1098 | free_svc_cred(&clp->cl_cred); | 1111 | free_svc_cred(&clp->cl_cred); |
1099 | kfree(clp->cl_name.data); | 1112 | kfree(clp->cl_name.data); |
1100 | idr_destroy(&clp->cl_stateids); | 1113 | idr_destroy(&clp->cl_stateids); |
@@ -1347,7 +1360,6 @@ static struct nfs4_client *create_client(struct xdr_netobj name, | |||
1347 | if (clp == NULL) | 1360 | if (clp == NULL) |
1348 | return NULL; | 1361 | return NULL; |
1349 | 1362 | ||
1350 | INIT_LIST_HEAD(&clp->cl_sessions); | ||
1351 | ret = copy_cred(&clp->cl_cred, &rqstp->rq_cred); | 1363 | ret = copy_cred(&clp->cl_cred, &rqstp->rq_cred); |
1352 | if (ret) { | 1364 | if (ret) { |
1353 | spin_lock(&nn->client_lock); | 1365 | spin_lock(&nn->client_lock); |
@@ -1355,20 +1367,9 @@ static struct nfs4_client *create_client(struct xdr_netobj name, | |||
1355 | spin_unlock(&nn->client_lock); | 1367 | spin_unlock(&nn->client_lock); |
1356 | return NULL; | 1368 | return NULL; |
1357 | } | 1369 | } |
1358 | idr_init(&clp->cl_stateids); | ||
1359 | atomic_set(&clp->cl_refcount, 0); | ||
1360 | clp->cl_cb_state = NFSD4_CB_UNKNOWN; | ||
1361 | INIT_LIST_HEAD(&clp->cl_idhash); | ||
1362 | INIT_LIST_HEAD(&clp->cl_openowners); | ||
1363 | INIT_LIST_HEAD(&clp->cl_delegations); | ||
1364 | INIT_LIST_HEAD(&clp->cl_lru); | ||
1365 | INIT_LIST_HEAD(&clp->cl_callbacks); | ||
1366 | INIT_LIST_HEAD(&clp->cl_revoked); | ||
1367 | spin_lock_init(&clp->cl_lock); | ||
1368 | nfsd4_init_callback(&clp->cl_cb_null); | 1370 | nfsd4_init_callback(&clp->cl_cb_null); |
1369 | clp->cl_time = get_seconds(); | 1371 | clp->cl_time = get_seconds(); |
1370 | clear_bit(0, &clp->cl_cb_slot_busy); | 1372 | clear_bit(0, &clp->cl_cb_slot_busy); |
1371 | rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table"); | ||
1372 | copy_verf(clp, verf); | 1373 | copy_verf(clp, verf); |
1373 | rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa); | 1374 | rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa); |
1374 | gen_confirm(clp); | 1375 | gen_confirm(clp); |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 28cc1acd5439..e9ef59b3abb1 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -47,12 +47,13 @@ static int sysfs_kf_seq_show(struct seq_file *sf, void *v) | |||
47 | ssize_t count; | 47 | ssize_t count; |
48 | char *buf; | 48 | char *buf; |
49 | 49 | ||
50 | /* acquire buffer and ensure that it's >= PAGE_SIZE */ | 50 | /* acquire buffer and ensure that it's >= PAGE_SIZE and clear */ |
51 | count = seq_get_buf(sf, &buf); | 51 | count = seq_get_buf(sf, &buf); |
52 | if (count < PAGE_SIZE) { | 52 | if (count < PAGE_SIZE) { |
53 | seq_commit(sf, -1); | 53 | seq_commit(sf, -1); |
54 | return 0; | 54 | return 0; |
55 | } | 55 | } |
56 | memset(buf, 0, PAGE_SIZE); | ||
56 | 57 | ||
57 | /* | 58 | /* |
58 | * Invoke show(). Control may reach here via seq file lseek even | 59 | * Invoke show(). Control may reach here via seq file lseek even |
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index a66ad6196f59..8794423f7efb 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
@@ -63,7 +63,8 @@ int __init sysfs_init(void) | |||
63 | { | 63 | { |
64 | int err; | 64 | int err; |
65 | 65 | ||
66 | sysfs_root = kernfs_create_root(NULL, 0, NULL); | 66 | sysfs_root = kernfs_create_root(NULL, KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK, |
67 | NULL); | ||
67 | if (IS_ERR(sysfs_root)) | 68 | if (IS_ERR(sysfs_root)) |
68 | return PTR_ERR(sysfs_root); | 69 | return PTR_ERR(sysfs_root); |
69 | 70 | ||
diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c index 1399e187d425..753e467aa1a5 100644 --- a/fs/xfs/xfs_export.c +++ b/fs/xfs/xfs_export.c | |||
@@ -237,7 +237,7 @@ xfs_fs_nfs_commit_metadata( | |||
237 | 237 | ||
238 | if (!lsn) | 238 | if (!lsn) |
239 | return 0; | 239 | return 0; |
240 | return _xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, NULL); | 240 | return -_xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, NULL); |
241 | } | 241 | } |
242 | 242 | ||
243 | const struct export_operations xfs_export_operations = { | 243 | const struct export_operations xfs_export_operations = { |
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 951a2321ee01..830c1c937b88 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -155,7 +155,7 @@ xfs_dir_fsync( | |||
155 | 155 | ||
156 | if (!lsn) | 156 | if (!lsn) |
157 | return 0; | 157 | return 0; |
158 | return _xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, NULL); | 158 | return -_xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, NULL); |
159 | } | 159 | } |
160 | 160 | ||
161 | STATIC int | 161 | STATIC int |
@@ -295,7 +295,7 @@ xfs_file_aio_read( | |||
295 | xfs_rw_ilock(ip, XFS_IOLOCK_EXCL); | 295 | xfs_rw_ilock(ip, XFS_IOLOCK_EXCL); |
296 | 296 | ||
297 | if (inode->i_mapping->nrpages) { | 297 | if (inode->i_mapping->nrpages) { |
298 | ret = -filemap_write_and_wait_range( | 298 | ret = filemap_write_and_wait_range( |
299 | VFS_I(ip)->i_mapping, | 299 | VFS_I(ip)->i_mapping, |
300 | pos, -1); | 300 | pos, -1); |
301 | if (ret) { | 301 | if (ret) { |
@@ -837,7 +837,7 @@ xfs_file_fallocate( | |||
837 | unsigned blksize_mask = (1 << inode->i_blkbits) - 1; | 837 | unsigned blksize_mask = (1 << inode->i_blkbits) - 1; |
838 | 838 | ||
839 | if (offset & blksize_mask || len & blksize_mask) { | 839 | if (offset & blksize_mask || len & blksize_mask) { |
840 | error = -EINVAL; | 840 | error = EINVAL; |
841 | goto out_unlock; | 841 | goto out_unlock; |
842 | } | 842 | } |
843 | 843 | ||
@@ -846,7 +846,7 @@ xfs_file_fallocate( | |||
846 | * in which case it is effectively a truncate operation | 846 | * in which case it is effectively a truncate operation |
847 | */ | 847 | */ |
848 | if (offset + len >= i_size_read(inode)) { | 848 | if (offset + len >= i_size_read(inode)) { |
849 | error = -EINVAL; | 849 | error = EINVAL; |
850 | goto out_unlock; | 850 | goto out_unlock; |
851 | } | 851 | } |
852 | 852 | ||
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 301ecbfcc0be..36d630319a27 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -72,8 +72,8 @@ xfs_initxattrs( | |||
72 | int error = 0; | 72 | int error = 0; |
73 | 73 | ||
74 | for (xattr = xattr_array; xattr->name != NULL; xattr++) { | 74 | for (xattr = xattr_array; xattr->name != NULL; xattr++) { |
75 | error = xfs_attr_set(ip, xattr->name, xattr->value, | 75 | error = -xfs_attr_set(ip, xattr->name, xattr->value, |
76 | xattr->value_len, ATTR_SECURE); | 76 | xattr->value_len, ATTR_SECURE); |
77 | if (error < 0) | 77 | if (error < 0) |
78 | break; | 78 | break; |
79 | } | 79 | } |
@@ -93,8 +93,8 @@ xfs_init_security( | |||
93 | struct inode *dir, | 93 | struct inode *dir, |
94 | const struct qstr *qstr) | 94 | const struct qstr *qstr) |
95 | { | 95 | { |
96 | return security_inode_init_security(inode, dir, qstr, | 96 | return -security_inode_init_security(inode, dir, qstr, |
97 | &xfs_initxattrs, NULL); | 97 | &xfs_initxattrs, NULL); |
98 | } | 98 | } |
99 | 99 | ||
100 | static void | 100 | static void |
@@ -173,12 +173,12 @@ xfs_generic_create( | |||
173 | 173 | ||
174 | #ifdef CONFIG_XFS_POSIX_ACL | 174 | #ifdef CONFIG_XFS_POSIX_ACL |
175 | if (default_acl) { | 175 | if (default_acl) { |
176 | error = xfs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); | 176 | error = -xfs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); |
177 | if (error) | 177 | if (error) |
178 | goto out_cleanup_inode; | 178 | goto out_cleanup_inode; |
179 | } | 179 | } |
180 | if (acl) { | 180 | if (acl) { |
181 | error = xfs_set_acl(inode, acl, ACL_TYPE_ACCESS); | 181 | error = -xfs_set_acl(inode, acl, ACL_TYPE_ACCESS); |
182 | if (error) | 182 | if (error) |
183 | goto out_cleanup_inode; | 183 | goto out_cleanup_inode; |
184 | } | 184 | } |
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 348e4d2ed6e6..dc977b6e6a36 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c | |||
@@ -843,22 +843,17 @@ xfs_qm_init_quotainfo( | |||
843 | 843 | ||
844 | qinf = mp->m_quotainfo = kmem_zalloc(sizeof(xfs_quotainfo_t), KM_SLEEP); | 844 | qinf = mp->m_quotainfo = kmem_zalloc(sizeof(xfs_quotainfo_t), KM_SLEEP); |
845 | 845 | ||
846 | if ((error = list_lru_init(&qinf->qi_lru))) { | 846 | error = -list_lru_init(&qinf->qi_lru); |
847 | kmem_free(qinf); | 847 | if (error) |
848 | mp->m_quotainfo = NULL; | 848 | goto out_free_qinf; |
849 | return error; | ||
850 | } | ||
851 | 849 | ||
852 | /* | 850 | /* |
853 | * See if quotainodes are setup, and if not, allocate them, | 851 | * See if quotainodes are setup, and if not, allocate them, |
854 | * and change the superblock accordingly. | 852 | * and change the superblock accordingly. |
855 | */ | 853 | */ |
856 | if ((error = xfs_qm_init_quotainos(mp))) { | 854 | error = xfs_qm_init_quotainos(mp); |
857 | list_lru_destroy(&qinf->qi_lru); | 855 | if (error) |
858 | kmem_free(qinf); | 856 | goto out_free_lru; |
859 | mp->m_quotainfo = NULL; | ||
860 | return error; | ||
861 | } | ||
862 | 857 | ||
863 | INIT_RADIX_TREE(&qinf->qi_uquota_tree, GFP_NOFS); | 858 | INIT_RADIX_TREE(&qinf->qi_uquota_tree, GFP_NOFS); |
864 | INIT_RADIX_TREE(&qinf->qi_gquota_tree, GFP_NOFS); | 859 | INIT_RADIX_TREE(&qinf->qi_gquota_tree, GFP_NOFS); |
@@ -918,7 +913,7 @@ xfs_qm_init_quotainfo( | |||
918 | qinf->qi_isoftlimit = be64_to_cpu(ddqp->d_ino_softlimit); | 913 | qinf->qi_isoftlimit = be64_to_cpu(ddqp->d_ino_softlimit); |
919 | qinf->qi_rtbhardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit); | 914 | qinf->qi_rtbhardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit); |
920 | qinf->qi_rtbsoftlimit = be64_to_cpu(ddqp->d_rtb_softlimit); | 915 | qinf->qi_rtbsoftlimit = be64_to_cpu(ddqp->d_rtb_softlimit); |
921 | 916 | ||
922 | xfs_qm_dqdestroy(dqp); | 917 | xfs_qm_dqdestroy(dqp); |
923 | } else { | 918 | } else { |
924 | qinf->qi_btimelimit = XFS_QM_BTIMELIMIT; | 919 | qinf->qi_btimelimit = XFS_QM_BTIMELIMIT; |
@@ -935,6 +930,13 @@ xfs_qm_init_quotainfo( | |||
935 | qinf->qi_shrinker.flags = SHRINKER_NUMA_AWARE; | 930 | qinf->qi_shrinker.flags = SHRINKER_NUMA_AWARE; |
936 | register_shrinker(&qinf->qi_shrinker); | 931 | register_shrinker(&qinf->qi_shrinker); |
937 | return 0; | 932 | return 0; |
933 | |||
934 | out_free_lru: | ||
935 | list_lru_destroy(&qinf->qi_lru); | ||
936 | out_free_qinf: | ||
937 | kmem_free(qinf); | ||
938 | mp->m_quotainfo = NULL; | ||
939 | return error; | ||
938 | } | 940 | } |
939 | 941 | ||
940 | 942 | ||
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 205376776377..3494eff8e4eb 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -1433,11 +1433,11 @@ xfs_fs_fill_super( | |||
1433 | if (error) | 1433 | if (error) |
1434 | goto out_free_fsname; | 1434 | goto out_free_fsname; |
1435 | 1435 | ||
1436 | error = xfs_init_mount_workqueues(mp); | 1436 | error = -xfs_init_mount_workqueues(mp); |
1437 | if (error) | 1437 | if (error) |
1438 | goto out_close_devices; | 1438 | goto out_close_devices; |
1439 | 1439 | ||
1440 | error = xfs_icsb_init_counters(mp); | 1440 | error = -xfs_icsb_init_counters(mp); |
1441 | if (error) | 1441 | if (error) |
1442 | goto out_destroy_workqueues; | 1442 | goto out_destroy_workqueues; |
1443 | 1443 | ||
diff --git a/include/asm-generic/resource.h b/include/asm-generic/resource.h index b4ea8f50fc65..5e752b959054 100644 --- a/include/asm-generic/resource.h +++ b/include/asm-generic/resource.h | |||
@@ -12,7 +12,7 @@ | |||
12 | [RLIMIT_CPU] = { RLIM_INFINITY, RLIM_INFINITY }, \ | 12 | [RLIMIT_CPU] = { RLIM_INFINITY, RLIM_INFINITY }, \ |
13 | [RLIMIT_FSIZE] = { RLIM_INFINITY, RLIM_INFINITY }, \ | 13 | [RLIMIT_FSIZE] = { RLIM_INFINITY, RLIM_INFINITY }, \ |
14 | [RLIMIT_DATA] = { RLIM_INFINITY, RLIM_INFINITY }, \ | 14 | [RLIMIT_DATA] = { RLIM_INFINITY, RLIM_INFINITY }, \ |
15 | [RLIMIT_STACK] = { _STK_LIM, _STK_LIM_MAX }, \ | 15 | [RLIMIT_STACK] = { _STK_LIM, RLIM_INFINITY }, \ |
16 | [RLIMIT_CORE] = { 0, RLIM_INFINITY }, \ | 16 | [RLIMIT_CORE] = { 0, RLIM_INFINITY }, \ |
17 | [RLIMIT_RSS] = { RLIM_INFINITY, RLIM_INFINITY }, \ | 17 | [RLIMIT_RSS] = { RLIM_INFINITY, RLIM_INFINITY }, \ |
18 | [RLIMIT_NPROC] = { 0, 0 }, \ | 18 | [RLIMIT_NPROC] = { 0, 0 }, \ |
diff --git a/include/dt-bindings/clk/at91.h b/include/dt-bindings/clock/at91.h index 0b4cb999a3f7..0b4cb999a3f7 100644 --- a/include/dt-bindings/clk/at91.h +++ b/include/dt-bindings/clock/at91.h | |||
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index c2515851c1aa..d60904b9e505 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
@@ -473,6 +473,7 @@ struct cftype { | |||
473 | }; | 473 | }; |
474 | 474 | ||
475 | extern struct cgroup_root cgrp_dfl_root; | 475 | extern struct cgroup_root cgrp_dfl_root; |
476 | extern struct css_set init_css_set; | ||
476 | 477 | ||
477 | static inline bool cgroup_on_dfl(const struct cgroup *cgrp) | 478 | static inline bool cgroup_on_dfl(const struct cgroup *cgrp) |
478 | { | 479 | { |
@@ -700,6 +701,20 @@ static inline struct cgroup_subsys_state *task_css(struct task_struct *task, | |||
700 | return task_css_check(task, subsys_id, false); | 701 | return task_css_check(task, subsys_id, false); |
701 | } | 702 | } |
702 | 703 | ||
704 | /** | ||
705 | * task_css_is_root - test whether a task belongs to the root css | ||
706 | * @task: the target task | ||
707 | * @subsys_id: the target subsystem ID | ||
708 | * | ||
709 | * Test whether @task belongs to the root css on the specified subsystem. | ||
710 | * May be invoked in any context. | ||
711 | */ | ||
712 | static inline bool task_css_is_root(struct task_struct *task, int subsys_id) | ||
713 | { | ||
714 | return task_css_check(task, subsys_id, true) == | ||
715 | init_css_set.subsys[subsys_id]; | ||
716 | } | ||
717 | |||
703 | static inline struct cgroup *task_cgroup(struct task_struct *task, | 718 | static inline struct cgroup *task_cgroup(struct task_struct *task, |
704 | int subsys_id) | 719 | int subsys_id) |
705 | { | 720 | { |
diff --git a/include/linux/firewire.h b/include/linux/firewire.h index c3683bdf28fe..d4b7683c722d 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h | |||
@@ -367,6 +367,9 @@ static inline int fw_stream_packet_destination_id(int tag, int channel, int sy) | |||
367 | return tag << 14 | channel << 8 | sy; | 367 | return tag << 14 | channel << 8 | sy; |
368 | } | 368 | } |
369 | 369 | ||
370 | void fw_schedule_bus_reset(struct fw_card *card, bool delayed, | ||
371 | bool short_reset); | ||
372 | |||
370 | struct fw_descriptor { | 373 | struct fw_descriptor { |
371 | struct list_head link; | 374 | struct list_head link; |
372 | size_t length; | 375 | size_t length; |
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 97ac926c78a7..051c85032f48 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -272,6 +272,11 @@ static inline int irq_set_affinity(unsigned int irq, const struct cpumask *m) | |||
272 | return -EINVAL; | 272 | return -EINVAL; |
273 | } | 273 | } |
274 | 274 | ||
275 | static inline int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask) | ||
276 | { | ||
277 | return 0; | ||
278 | } | ||
279 | |||
275 | static inline int irq_can_set_affinity(unsigned int irq) | 280 | static inline int irq_can_set_affinity(unsigned int irq) |
276 | { | 281 | { |
277 | return 0; | 282 | return 0; |
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index b0122dc6f96a..ca1be5c9136c 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h | |||
@@ -50,7 +50,24 @@ enum kernfs_node_flag { | |||
50 | 50 | ||
51 | /* @flags for kernfs_create_root() */ | 51 | /* @flags for kernfs_create_root() */ |
52 | enum kernfs_root_flag { | 52 | enum kernfs_root_flag { |
53 | KERNFS_ROOT_CREATE_DEACTIVATED = 0x0001, | 53 | /* |
54 | * kernfs_nodes are created in the deactivated state and invisible. | ||
55 | * They require explicit kernfs_activate() to become visible. This | ||
56 | * can be used to make related nodes become visible atomically | ||
57 | * after all nodes are created successfully. | ||
58 | */ | ||
59 | KERNFS_ROOT_CREATE_DEACTIVATED = 0x0001, | ||
60 | |||
61 | /* | ||
62 | * For regular flies, if the opener has CAP_DAC_OVERRIDE, open(2) | ||
63 | * succeeds regardless of the RW permissions. sysfs had an extra | ||
64 | * layer of enforcement where open(2) fails with -EACCES regardless | ||
65 | * of CAP_DAC_OVERRIDE if the permission doesn't have the | ||
66 | * respective read or write access at all (none of S_IRUGO or | ||
67 | * S_IWUGO) or the respective operation isn't implemented. The | ||
68 | * following flag enables that behavior. | ||
69 | */ | ||
70 | KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK = 0x0002, | ||
54 | }; | 71 | }; |
55 | 72 | ||
56 | /* type-specific structures for kernfs_node union members */ | 73 | /* type-specific structures for kernfs_node union members */ |
diff --git a/include/linux/of.h b/include/linux/of.h index 3bad8d106e0e..e6f0988c1c68 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
@@ -349,7 +349,7 @@ int of_device_is_stdout_path(struct device_node *dn); | |||
349 | 349 | ||
350 | #else /* CONFIG_OF */ | 350 | #else /* CONFIG_OF */ |
351 | 351 | ||
352 | static inline const char* of_node_full_name(struct device_node *np) | 352 | static inline const char* of_node_full_name(const struct device_node *np) |
353 | { | 353 | { |
354 | return "<no-node>"; | 354 | return "<no-node>"; |
355 | } | 355 | } |
diff --git a/include/uapi/asm-generic/resource.h b/include/uapi/asm-generic/resource.h index f863428796d5..c6d10af50123 100644 --- a/include/uapi/asm-generic/resource.h +++ b/include/uapi/asm-generic/resource.h | |||
@@ -57,12 +57,5 @@ | |||
57 | # define RLIM_INFINITY (~0UL) | 57 | # define RLIM_INFINITY (~0UL) |
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | /* | ||
61 | * RLIMIT_STACK default maximum - some architectures override it: | ||
62 | */ | ||
63 | #ifndef _STK_LIM_MAX | ||
64 | # define _STK_LIM_MAX RLIM_INFINITY | ||
65 | #endif | ||
66 | |||
67 | 60 | ||
68 | #endif /* _UAPI_ASM_GENERIC_RESOURCE_H */ | 61 | #endif /* _UAPI_ASM_GENERIC_RESOURCE_H */ |
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index 6db66783d268..333640608087 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h | |||
@@ -697,9 +697,11 @@ __SYSCALL(__NR_finit_module, sys_finit_module) | |||
697 | __SYSCALL(__NR_sched_setattr, sys_sched_setattr) | 697 | __SYSCALL(__NR_sched_setattr, sys_sched_setattr) |
698 | #define __NR_sched_getattr 275 | 698 | #define __NR_sched_getattr 275 |
699 | __SYSCALL(__NR_sched_getattr, sys_sched_getattr) | 699 | __SYSCALL(__NR_sched_getattr, sys_sched_getattr) |
700 | #define __NR_renameat2 276 | ||
701 | __SYSCALL(__NR_renameat2, sys_renameat2) | ||
700 | 702 | ||
701 | #undef __NR_syscalls | 703 | #undef __NR_syscalls |
702 | #define __NR_syscalls 276 | 704 | #define __NR_syscalls 277 |
703 | 705 | ||
704 | /* | 706 | /* |
705 | * All syscalls below here should go away really, | 707 | * All syscalls below here should go away really, |
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h index 11917f747cb4..1b1efddb91cd 100644 --- a/include/uapi/linux/audit.h +++ b/include/uapi/linux/audit.h | |||
@@ -331,9 +331,17 @@ enum { | |||
331 | #define AUDIT_FAIL_PRINTK 1 | 331 | #define AUDIT_FAIL_PRINTK 1 |
332 | #define AUDIT_FAIL_PANIC 2 | 332 | #define AUDIT_FAIL_PANIC 2 |
333 | 333 | ||
334 | /* | ||
335 | * These bits disambiguate different calling conventions that share an | ||
336 | * ELF machine type, bitness, and endianness | ||
337 | */ | ||
338 | #define __AUDIT_ARCH_CONVENTION_MASK 0x30000000 | ||
339 | #define __AUDIT_ARCH_CONVENTION_MIPS64_N32 0x20000000 | ||
340 | |||
334 | /* distinguish syscall tables */ | 341 | /* distinguish syscall tables */ |
335 | #define __AUDIT_ARCH_64BIT 0x80000000 | 342 | #define __AUDIT_ARCH_64BIT 0x80000000 |
336 | #define __AUDIT_ARCH_LE 0x40000000 | 343 | #define __AUDIT_ARCH_LE 0x40000000 |
344 | |||
337 | #define AUDIT_ARCH_ALPHA (EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) | 345 | #define AUDIT_ARCH_ALPHA (EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) |
338 | #define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE) | 346 | #define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE) |
339 | #define AUDIT_ARCH_ARMEB (EM_ARM) | 347 | #define AUDIT_ARCH_ARMEB (EM_ARM) |
@@ -346,7 +354,11 @@ enum { | |||
346 | #define AUDIT_ARCH_MIPS (EM_MIPS) | 354 | #define AUDIT_ARCH_MIPS (EM_MIPS) |
347 | #define AUDIT_ARCH_MIPSEL (EM_MIPS|__AUDIT_ARCH_LE) | 355 | #define AUDIT_ARCH_MIPSEL (EM_MIPS|__AUDIT_ARCH_LE) |
348 | #define AUDIT_ARCH_MIPS64 (EM_MIPS|__AUDIT_ARCH_64BIT) | 356 | #define AUDIT_ARCH_MIPS64 (EM_MIPS|__AUDIT_ARCH_64BIT) |
357 | #define AUDIT_ARCH_MIPS64N32 (EM_MIPS|__AUDIT_ARCH_64BIT|\ | ||
358 | __AUDIT_ARCH_CONVENTION_MIPS64_N32) | ||
349 | #define AUDIT_ARCH_MIPSEL64 (EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) | 359 | #define AUDIT_ARCH_MIPSEL64 (EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) |
360 | #define AUDIT_ARCH_MIPSEL64N32 (EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE\ | ||
361 | __AUDIT_ARCH_CONVENTION_MIPS64_N32) | ||
350 | #define AUDIT_ARCH_OPENRISC (EM_OPENRISC) | 362 | #define AUDIT_ARCH_OPENRISC (EM_OPENRISC) |
351 | #define AUDIT_ARCH_PARISC (EM_PARISC) | 363 | #define AUDIT_ARCH_PARISC (EM_PARISC) |
352 | #define AUDIT_ARCH_PARISC64 (EM_PARISC|__AUDIT_ARCH_64BIT) | 364 | #define AUDIT_ARCH_PARISC64 (EM_PARISC|__AUDIT_ARCH_64BIT) |
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index 9fc6219d3848..224948342f14 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h | |||
@@ -94,9 +94,11 @@ enum { | |||
94 | SNDRV_HWDEP_IFACE_HDA, /* HD-audio */ | 94 | SNDRV_HWDEP_IFACE_HDA, /* HD-audio */ |
95 | SNDRV_HWDEP_IFACE_USB_STREAM, /* direct access to usb stream */ | 95 | SNDRV_HWDEP_IFACE_USB_STREAM, /* direct access to usb stream */ |
96 | SNDRV_HWDEP_IFACE_FW_DICE, /* TC DICE FireWire device */ | 96 | SNDRV_HWDEP_IFACE_FW_DICE, /* TC DICE FireWire device */ |
97 | SNDRV_HWDEP_IFACE_FW_FIREWORKS, /* Echo Audio Fireworks based device */ | ||
98 | SNDRV_HWDEP_IFACE_FW_BEBOB, /* BridgeCo BeBoB based device */ | ||
97 | 99 | ||
98 | /* Don't forget to change the following: */ | 100 | /* Don't forget to change the following: */ |
99 | SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_DICE | 101 | SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_BEBOB |
100 | }; | 102 | }; |
101 | 103 | ||
102 | struct snd_hwdep_info { | 104 | struct snd_hwdep_info { |
diff --git a/include/uapi/sound/firewire.h b/include/uapi/sound/firewire.h index 59f5961302bf..af4bd136c75d 100644 --- a/include/uapi/sound/firewire.h +++ b/include/uapi/sound/firewire.h | |||
@@ -2,11 +2,13 @@ | |||
2 | #define _UAPI_SOUND_FIREWIRE_H_INCLUDED | 2 | #define _UAPI_SOUND_FIREWIRE_H_INCLUDED |
3 | 3 | ||
4 | #include <linux/ioctl.h> | 4 | #include <linux/ioctl.h> |
5 | #include <linux/types.h> | ||
5 | 6 | ||
6 | /* events can be read() from the hwdep device */ | 7 | /* events can be read() from the hwdep device */ |
7 | 8 | ||
8 | #define SNDRV_FIREWIRE_EVENT_LOCK_STATUS 0x000010cc | 9 | #define SNDRV_FIREWIRE_EVENT_LOCK_STATUS 0x000010cc |
9 | #define SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION 0xd1ce004e | 10 | #define SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION 0xd1ce004e |
11 | #define SNDRV_FIREWIRE_EVENT_EFW_RESPONSE 0x4e617475 | ||
10 | 12 | ||
11 | struct snd_firewire_event_common { | 13 | struct snd_firewire_event_common { |
12 | unsigned int type; /* SNDRV_FIREWIRE_EVENT_xxx */ | 14 | unsigned int type; /* SNDRV_FIREWIRE_EVENT_xxx */ |
@@ -22,10 +24,27 @@ struct snd_firewire_event_dice_notification { | |||
22 | unsigned int notification; /* DICE-specific bits */ | 24 | unsigned int notification; /* DICE-specific bits */ |
23 | }; | 25 | }; |
24 | 26 | ||
27 | #define SND_EFW_TRANSACTION_USER_SEQNUM_MAX ((__u32)((__u16)~0) - 1) | ||
28 | /* each field should be in big endian */ | ||
29 | struct snd_efw_transaction { | ||
30 | __be32 length; | ||
31 | __be32 version; | ||
32 | __be32 seqnum; | ||
33 | __be32 category; | ||
34 | __be32 command; | ||
35 | __be32 status; | ||
36 | __be32 params[0]; | ||
37 | }; | ||
38 | struct snd_firewire_event_efw_response { | ||
39 | unsigned int type; | ||
40 | __be32 response[0]; /* some responses */ | ||
41 | }; | ||
42 | |||
25 | union snd_firewire_event { | 43 | union snd_firewire_event { |
26 | struct snd_firewire_event_common common; | 44 | struct snd_firewire_event_common common; |
27 | struct snd_firewire_event_lock_status lock_status; | 45 | struct snd_firewire_event_lock_status lock_status; |
28 | struct snd_firewire_event_dice_notification dice_notification; | 46 | struct snd_firewire_event_dice_notification dice_notification; |
47 | struct snd_firewire_event_efw_response efw_response; | ||
29 | }; | 48 | }; |
30 | 49 | ||
31 | 50 | ||
@@ -34,7 +53,9 @@ union snd_firewire_event { | |||
34 | #define SNDRV_FIREWIRE_IOCTL_UNLOCK _IO('H', 0xfa) | 53 | #define SNDRV_FIREWIRE_IOCTL_UNLOCK _IO('H', 0xfa) |
35 | 54 | ||
36 | #define SNDRV_FIREWIRE_TYPE_DICE 1 | 55 | #define SNDRV_FIREWIRE_TYPE_DICE 1 |
37 | /* Fireworks, AV/C, RME, MOTU, ... */ | 56 | #define SNDRV_FIREWIRE_TYPE_FIREWORKS 2 |
57 | #define SNDRV_FIREWIRE_TYPE_BEBOB 3 | ||
58 | /* AV/C, RME, MOTU, ... */ | ||
38 | 59 | ||
39 | struct snd_firewire_get_info { | 60 | struct snd_firewire_get_info { |
40 | unsigned int type; /* SNDRV_FIREWIRE_TYPE_xxx */ | 61 | unsigned int type; /* SNDRV_FIREWIRE_TYPE_xxx */ |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 9fcdaa705b6c..3f1ca934a237 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -348,7 +348,7 @@ struct cgrp_cset_link { | |||
348 | * reference-counted, to improve performance when child cgroups | 348 | * reference-counted, to improve performance when child cgroups |
349 | * haven't been created. | 349 | * haven't been created. |
350 | */ | 350 | */ |
351 | static struct css_set init_css_set = { | 351 | struct css_set init_css_set = { |
352 | .refcount = ATOMIC_INIT(1), | 352 | .refcount = ATOMIC_INIT(1), |
353 | .cgrp_links = LIST_HEAD_INIT(init_css_set.cgrp_links), | 353 | .cgrp_links = LIST_HEAD_INIT(init_css_set.cgrp_links), |
354 | .tasks = LIST_HEAD_INIT(init_css_set.tasks), | 354 | .tasks = LIST_HEAD_INIT(init_css_set.tasks), |
@@ -1495,7 +1495,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type, | |||
1495 | */ | 1495 | */ |
1496 | if (!use_task_css_set_links) | 1496 | if (!use_task_css_set_links) |
1497 | cgroup_enable_task_cg_lists(); | 1497 | cgroup_enable_task_cg_lists(); |
1498 | retry: | 1498 | |
1499 | mutex_lock(&cgroup_tree_mutex); | 1499 | mutex_lock(&cgroup_tree_mutex); |
1500 | mutex_lock(&cgroup_mutex); | 1500 | mutex_lock(&cgroup_mutex); |
1501 | 1501 | ||
@@ -1503,7 +1503,7 @@ retry: | |||
1503 | ret = parse_cgroupfs_options(data, &opts); | 1503 | ret = parse_cgroupfs_options(data, &opts); |
1504 | if (ret) | 1504 | if (ret) |
1505 | goto out_unlock; | 1505 | goto out_unlock; |
1506 | 1506 | retry: | |
1507 | /* look for a matching existing root */ | 1507 | /* look for a matching existing root */ |
1508 | if (!opts.subsys_mask && !opts.none && !opts.name) { | 1508 | if (!opts.subsys_mask && !opts.none && !opts.name) { |
1509 | cgrp_dfl_root_visible = true; | 1509 | cgrp_dfl_root_visible = true; |
@@ -1562,9 +1562,9 @@ retry: | |||
1562 | if (!atomic_inc_not_zero(&root->cgrp.refcnt)) { | 1562 | if (!atomic_inc_not_zero(&root->cgrp.refcnt)) { |
1563 | mutex_unlock(&cgroup_mutex); | 1563 | mutex_unlock(&cgroup_mutex); |
1564 | mutex_unlock(&cgroup_tree_mutex); | 1564 | mutex_unlock(&cgroup_tree_mutex); |
1565 | kfree(opts.release_agent); | ||
1566 | kfree(opts.name); | ||
1567 | msleep(10); | 1565 | msleep(10); |
1566 | mutex_lock(&cgroup_tree_mutex); | ||
1567 | mutex_lock(&cgroup_mutex); | ||
1568 | goto retry; | 1568 | goto retry; |
1569 | } | 1569 | } |
1570 | 1570 | ||
diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c index 2bc4a2256444..345628c78b5b 100644 --- a/kernel/cgroup_freezer.c +++ b/kernel/cgroup_freezer.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
22 | #include <linux/freezer.h> | 22 | #include <linux/freezer.h> |
23 | #include <linux/seq_file.h> | 23 | #include <linux/seq_file.h> |
24 | #include <linux/mutex.h> | ||
24 | 25 | ||
25 | /* | 26 | /* |
26 | * A cgroup is freezing if any FREEZING flags are set. FREEZING_SELF is | 27 | * A cgroup is freezing if any FREEZING flags are set. FREEZING_SELF is |
@@ -42,9 +43,10 @@ enum freezer_state_flags { | |||
42 | struct freezer { | 43 | struct freezer { |
43 | struct cgroup_subsys_state css; | 44 | struct cgroup_subsys_state css; |
44 | unsigned int state; | 45 | unsigned int state; |
45 | spinlock_t lock; | ||
46 | }; | 46 | }; |
47 | 47 | ||
48 | static DEFINE_MUTEX(freezer_mutex); | ||
49 | |||
48 | static inline struct freezer *css_freezer(struct cgroup_subsys_state *css) | 50 | static inline struct freezer *css_freezer(struct cgroup_subsys_state *css) |
49 | { | 51 | { |
50 | return css ? container_of(css, struct freezer, css) : NULL; | 52 | return css ? container_of(css, struct freezer, css) : NULL; |
@@ -93,7 +95,6 @@ freezer_css_alloc(struct cgroup_subsys_state *parent_css) | |||
93 | if (!freezer) | 95 | if (!freezer) |
94 | return ERR_PTR(-ENOMEM); | 96 | return ERR_PTR(-ENOMEM); |
95 | 97 | ||
96 | spin_lock_init(&freezer->lock); | ||
97 | return &freezer->css; | 98 | return &freezer->css; |
98 | } | 99 | } |
99 | 100 | ||
@@ -110,14 +111,7 @@ static int freezer_css_online(struct cgroup_subsys_state *css) | |||
110 | struct freezer *freezer = css_freezer(css); | 111 | struct freezer *freezer = css_freezer(css); |
111 | struct freezer *parent = parent_freezer(freezer); | 112 | struct freezer *parent = parent_freezer(freezer); |
112 | 113 | ||
113 | /* | 114 | mutex_lock(&freezer_mutex); |
114 | * The following double locking and freezing state inheritance | ||
115 | * guarantee that @cgroup can never escape ancestors' freezing | ||
116 | * states. See css_for_each_descendant_pre() for details. | ||
117 | */ | ||
118 | if (parent) | ||
119 | spin_lock_irq(&parent->lock); | ||
120 | spin_lock_nested(&freezer->lock, SINGLE_DEPTH_NESTING); | ||
121 | 115 | ||
122 | freezer->state |= CGROUP_FREEZER_ONLINE; | 116 | freezer->state |= CGROUP_FREEZER_ONLINE; |
123 | 117 | ||
@@ -126,10 +120,7 @@ static int freezer_css_online(struct cgroup_subsys_state *css) | |||
126 | atomic_inc(&system_freezing_cnt); | 120 | atomic_inc(&system_freezing_cnt); |
127 | } | 121 | } |
128 | 122 | ||
129 | spin_unlock(&freezer->lock); | 123 | mutex_unlock(&freezer_mutex); |
130 | if (parent) | ||
131 | spin_unlock_irq(&parent->lock); | ||
132 | |||
133 | return 0; | 124 | return 0; |
134 | } | 125 | } |
135 | 126 | ||
@@ -144,14 +135,14 @@ static void freezer_css_offline(struct cgroup_subsys_state *css) | |||
144 | { | 135 | { |
145 | struct freezer *freezer = css_freezer(css); | 136 | struct freezer *freezer = css_freezer(css); |
146 | 137 | ||
147 | spin_lock_irq(&freezer->lock); | 138 | mutex_lock(&freezer_mutex); |
148 | 139 | ||
149 | if (freezer->state & CGROUP_FREEZING) | 140 | if (freezer->state & CGROUP_FREEZING) |
150 | atomic_dec(&system_freezing_cnt); | 141 | atomic_dec(&system_freezing_cnt); |
151 | 142 | ||
152 | freezer->state = 0; | 143 | freezer->state = 0; |
153 | 144 | ||
154 | spin_unlock_irq(&freezer->lock); | 145 | mutex_unlock(&freezer_mutex); |
155 | } | 146 | } |
156 | 147 | ||
157 | static void freezer_css_free(struct cgroup_subsys_state *css) | 148 | static void freezer_css_free(struct cgroup_subsys_state *css) |
@@ -175,7 +166,7 @@ static void freezer_attach(struct cgroup_subsys_state *new_css, | |||
175 | struct task_struct *task; | 166 | struct task_struct *task; |
176 | bool clear_frozen = false; | 167 | bool clear_frozen = false; |
177 | 168 | ||
178 | spin_lock_irq(&freezer->lock); | 169 | mutex_lock(&freezer_mutex); |
179 | 170 | ||
180 | /* | 171 | /* |
181 | * Make the new tasks conform to the current state of @new_css. | 172 | * Make the new tasks conform to the current state of @new_css. |
@@ -197,21 +188,13 @@ static void freezer_attach(struct cgroup_subsys_state *new_css, | |||
197 | } | 188 | } |
198 | } | 189 | } |
199 | 190 | ||
200 | spin_unlock_irq(&freezer->lock); | 191 | /* propagate FROZEN clearing upwards */ |
201 | |||
202 | /* | ||
203 | * Propagate FROZEN clearing upwards. We may race with | ||
204 | * update_if_frozen(), but as long as both work bottom-up, either | ||
205 | * update_if_frozen() sees child's FROZEN cleared or we clear the | ||
206 | * parent's FROZEN later. No parent w/ !FROZEN children can be | ||
207 | * left FROZEN. | ||
208 | */ | ||
209 | while (clear_frozen && (freezer = parent_freezer(freezer))) { | 192 | while (clear_frozen && (freezer = parent_freezer(freezer))) { |
210 | spin_lock_irq(&freezer->lock); | ||
211 | freezer->state &= ~CGROUP_FROZEN; | 193 | freezer->state &= ~CGROUP_FROZEN; |
212 | clear_frozen = freezer->state & CGROUP_FREEZING; | 194 | clear_frozen = freezer->state & CGROUP_FREEZING; |
213 | spin_unlock_irq(&freezer->lock); | ||
214 | } | 195 | } |
196 | |||
197 | mutex_unlock(&freezer_mutex); | ||
215 | } | 198 | } |
216 | 199 | ||
217 | /** | 200 | /** |
@@ -228,9 +211,6 @@ static void freezer_fork(struct task_struct *task) | |||
228 | { | 211 | { |
229 | struct freezer *freezer; | 212 | struct freezer *freezer; |
230 | 213 | ||
231 | rcu_read_lock(); | ||
232 | freezer = task_freezer(task); | ||
233 | |||
234 | /* | 214 | /* |
235 | * The root cgroup is non-freezable, so we can skip locking the | 215 | * The root cgroup is non-freezable, so we can skip locking the |
236 | * freezer. This is safe regardless of race with task migration. | 216 | * freezer. This is safe regardless of race with task migration. |
@@ -238,24 +218,18 @@ static void freezer_fork(struct task_struct *task) | |||
238 | * to do. If we lost and root is the new cgroup, noop is still the | 218 | * to do. If we lost and root is the new cgroup, noop is still the |
239 | * right thing to do. | 219 | * right thing to do. |
240 | */ | 220 | */ |
241 | if (!parent_freezer(freezer)) | 221 | if (task_css_is_root(task, freezer_cgrp_id)) |
242 | goto out; | 222 | return; |
243 | 223 | ||
244 | /* | 224 | mutex_lock(&freezer_mutex); |
245 | * Grab @freezer->lock and freeze @task after verifying @task still | 225 | rcu_read_lock(); |
246 | * belongs to @freezer and it's freezing. The former is for the | 226 | |
247 | * case where we have raced against task migration and lost and | 227 | freezer = task_freezer(task); |
248 | * @task is already in a different cgroup which may not be frozen. | 228 | if (freezer->state & CGROUP_FREEZING) |
249 | * This isn't strictly necessary as freeze_task() is allowed to be | ||
250 | * called spuriously but let's do it anyway for, if nothing else, | ||
251 | * documentation. | ||
252 | */ | ||
253 | spin_lock_irq(&freezer->lock); | ||
254 | if (freezer == task_freezer(task) && (freezer->state & CGROUP_FREEZING)) | ||
255 | freeze_task(task); | 229 | freeze_task(task); |
256 | spin_unlock_irq(&freezer->lock); | 230 | |
257 | out: | ||
258 | rcu_read_unlock(); | 231 | rcu_read_unlock(); |
232 | mutex_unlock(&freezer_mutex); | ||
259 | } | 233 | } |
260 | 234 | ||
261 | /** | 235 | /** |
@@ -281,22 +255,24 @@ static void update_if_frozen(struct cgroup_subsys_state *css) | |||
281 | struct css_task_iter it; | 255 | struct css_task_iter it; |
282 | struct task_struct *task; | 256 | struct task_struct *task; |
283 | 257 | ||
284 | WARN_ON_ONCE(!rcu_read_lock_held()); | 258 | lockdep_assert_held(&freezer_mutex); |
285 | |||
286 | spin_lock_irq(&freezer->lock); | ||
287 | 259 | ||
288 | if (!(freezer->state & CGROUP_FREEZING) || | 260 | if (!(freezer->state & CGROUP_FREEZING) || |
289 | (freezer->state & CGROUP_FROZEN)) | 261 | (freezer->state & CGROUP_FROZEN)) |
290 | goto out_unlock; | 262 | return; |
291 | 263 | ||
292 | /* are all (live) children frozen? */ | 264 | /* are all (live) children frozen? */ |
265 | rcu_read_lock(); | ||
293 | css_for_each_child(pos, css) { | 266 | css_for_each_child(pos, css) { |
294 | struct freezer *child = css_freezer(pos); | 267 | struct freezer *child = css_freezer(pos); |
295 | 268 | ||
296 | if ((child->state & CGROUP_FREEZER_ONLINE) && | 269 | if ((child->state & CGROUP_FREEZER_ONLINE) && |
297 | !(child->state & CGROUP_FROZEN)) | 270 | !(child->state & CGROUP_FROZEN)) { |
298 | goto out_unlock; | 271 | rcu_read_unlock(); |
272 | return; | ||
273 | } | ||
299 | } | 274 | } |
275 | rcu_read_unlock(); | ||
300 | 276 | ||
301 | /* are all tasks frozen? */ | 277 | /* are all tasks frozen? */ |
302 | css_task_iter_start(css, &it); | 278 | css_task_iter_start(css, &it); |
@@ -317,21 +293,29 @@ static void update_if_frozen(struct cgroup_subsys_state *css) | |||
317 | freezer->state |= CGROUP_FROZEN; | 293 | freezer->state |= CGROUP_FROZEN; |
318 | out_iter_end: | 294 | out_iter_end: |
319 | css_task_iter_end(&it); | 295 | css_task_iter_end(&it); |
320 | out_unlock: | ||
321 | spin_unlock_irq(&freezer->lock); | ||
322 | } | 296 | } |
323 | 297 | ||
324 | static int freezer_read(struct seq_file *m, void *v) | 298 | static int freezer_read(struct seq_file *m, void *v) |
325 | { | 299 | { |
326 | struct cgroup_subsys_state *css = seq_css(m), *pos; | 300 | struct cgroup_subsys_state *css = seq_css(m), *pos; |
327 | 301 | ||
302 | mutex_lock(&freezer_mutex); | ||
328 | rcu_read_lock(); | 303 | rcu_read_lock(); |
329 | 304 | ||
330 | /* update states bottom-up */ | 305 | /* update states bottom-up */ |
331 | css_for_each_descendant_post(pos, css) | 306 | css_for_each_descendant_post(pos, css) { |
307 | if (!css_tryget(pos)) | ||
308 | continue; | ||
309 | rcu_read_unlock(); | ||
310 | |||
332 | update_if_frozen(pos); | 311 | update_if_frozen(pos); |
333 | 312 | ||
313 | rcu_read_lock(); | ||
314 | css_put(pos); | ||
315 | } | ||
316 | |||
334 | rcu_read_unlock(); | 317 | rcu_read_unlock(); |
318 | mutex_unlock(&freezer_mutex); | ||
335 | 319 | ||
336 | seq_puts(m, freezer_state_strs(css_freezer(css)->state)); | 320 | seq_puts(m, freezer_state_strs(css_freezer(css)->state)); |
337 | seq_putc(m, '\n'); | 321 | seq_putc(m, '\n'); |
@@ -373,7 +357,7 @@ static void freezer_apply_state(struct freezer *freezer, bool freeze, | |||
373 | unsigned int state) | 357 | unsigned int state) |
374 | { | 358 | { |
375 | /* also synchronizes against task migration, see freezer_attach() */ | 359 | /* also synchronizes against task migration, see freezer_attach() */ |
376 | lockdep_assert_held(&freezer->lock); | 360 | lockdep_assert_held(&freezer_mutex); |
377 | 361 | ||
378 | if (!(freezer->state & CGROUP_FREEZER_ONLINE)) | 362 | if (!(freezer->state & CGROUP_FREEZER_ONLINE)) |
379 | return; | 363 | return; |
@@ -414,31 +398,29 @@ static void freezer_change_state(struct freezer *freezer, bool freeze) | |||
414 | * descendant will try to inherit its parent's FREEZING state as | 398 | * descendant will try to inherit its parent's FREEZING state as |
415 | * CGROUP_FREEZING_PARENT. | 399 | * CGROUP_FREEZING_PARENT. |
416 | */ | 400 | */ |
401 | mutex_lock(&freezer_mutex); | ||
417 | rcu_read_lock(); | 402 | rcu_read_lock(); |
418 | css_for_each_descendant_pre(pos, &freezer->css) { | 403 | css_for_each_descendant_pre(pos, &freezer->css) { |
419 | struct freezer *pos_f = css_freezer(pos); | 404 | struct freezer *pos_f = css_freezer(pos); |
420 | struct freezer *parent = parent_freezer(pos_f); | 405 | struct freezer *parent = parent_freezer(pos_f); |
421 | 406 | ||
422 | spin_lock_irq(&pos_f->lock); | 407 | if (!css_tryget(pos)) |
408 | continue; | ||
409 | rcu_read_unlock(); | ||
423 | 410 | ||
424 | if (pos_f == freezer) { | 411 | if (pos_f == freezer) |
425 | freezer_apply_state(pos_f, freeze, | 412 | freezer_apply_state(pos_f, freeze, |
426 | CGROUP_FREEZING_SELF); | 413 | CGROUP_FREEZING_SELF); |
427 | } else { | 414 | else |
428 | /* | ||
429 | * Our update to @parent->state is already visible | ||
430 | * which is all we need. No need to lock @parent. | ||
431 | * For more info on synchronization, see | ||
432 | * freezer_post_create(). | ||
433 | */ | ||
434 | freezer_apply_state(pos_f, | 415 | freezer_apply_state(pos_f, |
435 | parent->state & CGROUP_FREEZING, | 416 | parent->state & CGROUP_FREEZING, |
436 | CGROUP_FREEZING_PARENT); | 417 | CGROUP_FREEZING_PARENT); |
437 | } | ||
438 | 418 | ||
439 | spin_unlock_irq(&pos_f->lock); | 419 | rcu_read_lock(); |
420 | css_put(pos); | ||
440 | } | 421 | } |
441 | rcu_read_unlock(); | 422 | rcu_read_unlock(); |
423 | mutex_unlock(&freezer_mutex); | ||
442 | } | 424 | } |
443 | 425 | ||
444 | static int freezer_write(struct cgroup_subsys_state *css, struct cftype *cft, | 426 | static int freezer_write(struct cgroup_subsys_state *css, struct cftype *cft, |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 6b715c0af1b1..e0501fe7140d 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -990,11 +990,8 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, | |||
990 | /* Remove an active timer from the queue: */ | 990 | /* Remove an active timer from the queue: */ |
991 | ret = remove_hrtimer(timer, base); | 991 | ret = remove_hrtimer(timer, base); |
992 | 992 | ||
993 | /* Switch the timer base, if necessary: */ | ||
994 | new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED); | ||
995 | |||
996 | if (mode & HRTIMER_MODE_REL) { | 993 | if (mode & HRTIMER_MODE_REL) { |
997 | tim = ktime_add_safe(tim, new_base->get_time()); | 994 | tim = ktime_add_safe(tim, base->get_time()); |
998 | /* | 995 | /* |
999 | * CONFIG_TIME_LOW_RES is a temporary way for architectures | 996 | * CONFIG_TIME_LOW_RES is a temporary way for architectures |
1000 | * to signal that they simply return xtime in | 997 | * to signal that they simply return xtime in |
@@ -1009,6 +1006,9 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, | |||
1009 | 1006 | ||
1010 | hrtimer_set_expires_range_ns(timer, tim, delta_ns); | 1007 | hrtimer_set_expires_range_ns(timer, tim, delta_ns); |
1011 | 1008 | ||
1009 | /* Switch the timer base, if necessary: */ | ||
1010 | new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED); | ||
1011 | |||
1012 | timer_stats_hrtimer_set_start_info(timer); | 1012 | timer_stats_hrtimer_set_start_info(timer); |
1013 | 1013 | ||
1014 | leftmost = enqueue_hrtimer(timer, new_base); | 1014 | leftmost = enqueue_hrtimer(timer, new_base); |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 0ee63af30bd1..8edc87185427 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -1916,6 +1916,12 @@ static void send_mayday(struct work_struct *work) | |||
1916 | 1916 | ||
1917 | /* mayday mayday mayday */ | 1917 | /* mayday mayday mayday */ |
1918 | if (list_empty(&pwq->mayday_node)) { | 1918 | if (list_empty(&pwq->mayday_node)) { |
1919 | /* | ||
1920 | * If @pwq is for an unbound wq, its base ref may be put at | ||
1921 | * any time due to an attribute change. Pin @pwq until the | ||
1922 | * rescuer is done with it. | ||
1923 | */ | ||
1924 | get_pwq(pwq); | ||
1919 | list_add_tail(&pwq->mayday_node, &wq->maydays); | 1925 | list_add_tail(&pwq->mayday_node, &wq->maydays); |
1920 | wake_up_process(wq->rescuer->task); | 1926 | wake_up_process(wq->rescuer->task); |
1921 | } | 1927 | } |
@@ -2398,6 +2404,7 @@ static int rescuer_thread(void *__rescuer) | |||
2398 | struct worker *rescuer = __rescuer; | 2404 | struct worker *rescuer = __rescuer; |
2399 | struct workqueue_struct *wq = rescuer->rescue_wq; | 2405 | struct workqueue_struct *wq = rescuer->rescue_wq; |
2400 | struct list_head *scheduled = &rescuer->scheduled; | 2406 | struct list_head *scheduled = &rescuer->scheduled; |
2407 | bool should_stop; | ||
2401 | 2408 | ||
2402 | set_user_nice(current, RESCUER_NICE_LEVEL); | 2409 | set_user_nice(current, RESCUER_NICE_LEVEL); |
2403 | 2410 | ||
@@ -2409,11 +2416,15 @@ static int rescuer_thread(void *__rescuer) | |||
2409 | repeat: | 2416 | repeat: |
2410 | set_current_state(TASK_INTERRUPTIBLE); | 2417 | set_current_state(TASK_INTERRUPTIBLE); |
2411 | 2418 | ||
2412 | if (kthread_should_stop()) { | 2419 | /* |
2413 | __set_current_state(TASK_RUNNING); | 2420 | * By the time the rescuer is requested to stop, the workqueue |
2414 | rescuer->task->flags &= ~PF_WQ_WORKER; | 2421 | * shouldn't have any work pending, but @wq->maydays may still have |
2415 | return 0; | 2422 | * pwq(s) queued. This can happen by non-rescuer workers consuming |
2416 | } | 2423 | * all the work items before the rescuer got to them. Go through |
2424 | * @wq->maydays processing before acting on should_stop so that the | ||
2425 | * list is always empty on exit. | ||
2426 | */ | ||
2427 | should_stop = kthread_should_stop(); | ||
2417 | 2428 | ||
2418 | /* see whether any pwq is asking for help */ | 2429 | /* see whether any pwq is asking for help */ |
2419 | spin_lock_irq(&wq_mayday_lock); | 2430 | spin_lock_irq(&wq_mayday_lock); |
@@ -2445,6 +2456,12 @@ repeat: | |||
2445 | process_scheduled_works(rescuer); | 2456 | process_scheduled_works(rescuer); |
2446 | 2457 | ||
2447 | /* | 2458 | /* |
2459 | * Put the reference grabbed by send_mayday(). @pool won't | ||
2460 | * go away while we're holding its lock. | ||
2461 | */ | ||
2462 | put_pwq(pwq); | ||
2463 | |||
2464 | /* | ||
2448 | * Leave this pool. If keep_working() is %true, notify a | 2465 | * Leave this pool. If keep_working() is %true, notify a |
2449 | * regular worker; otherwise, we end up with 0 concurrency | 2466 | * regular worker; otherwise, we end up with 0 concurrency |
2450 | * and stalling the execution. | 2467 | * and stalling the execution. |
@@ -2459,6 +2476,12 @@ repeat: | |||
2459 | 2476 | ||
2460 | spin_unlock_irq(&wq_mayday_lock); | 2477 | spin_unlock_irq(&wq_mayday_lock); |
2461 | 2478 | ||
2479 | if (should_stop) { | ||
2480 | __set_current_state(TASK_RUNNING); | ||
2481 | rescuer->task->flags &= ~PF_WQ_WORKER; | ||
2482 | return 0; | ||
2483 | } | ||
2484 | |||
2462 | /* rescuers should never participate in concurrency management */ | 2485 | /* rescuers should never participate in concurrency management */ |
2463 | WARN_ON_ONCE(!(rescuer->flags & WORKER_NOT_RUNNING)); | 2486 | WARN_ON_ONCE(!(rescuer->flags & WORKER_NOT_RUNNING)); |
2464 | schedule(); | 2487 | schedule(); |
@@ -4100,7 +4123,8 @@ static void wq_update_unbound_numa(struct workqueue_struct *wq, int cpu, | |||
4100 | if (!pwq) { | 4123 | if (!pwq) { |
4101 | pr_warning("workqueue: allocation failed while updating NUMA affinity of \"%s\"\n", | 4124 | pr_warning("workqueue: allocation failed while updating NUMA affinity of \"%s\"\n", |
4102 | wq->name); | 4125 | wq->name); |
4103 | goto out_unlock; | 4126 | mutex_lock(&wq->mutex); |
4127 | goto use_dfl_pwq; | ||
4104 | } | 4128 | } |
4105 | 4129 | ||
4106 | /* | 4130 | /* |
diff --git a/mm/Kconfig b/mm/Kconfig index ebe5880c29d6..1b5a95f0fa01 100644 --- a/mm/Kconfig +++ b/mm/Kconfig | |||
@@ -581,3 +581,18 @@ config PGTABLE_MAPPING | |||
581 | 581 | ||
582 | config GENERIC_EARLY_IOREMAP | 582 | config GENERIC_EARLY_IOREMAP |
583 | bool | 583 | bool |
584 | |||
585 | config MAX_STACK_SIZE_MB | ||
586 | int "Maximum user stack size for 32-bit processes (MB)" | ||
587 | default 80 | ||
588 | range 8 256 if METAG | ||
589 | range 8 2048 | ||
590 | depends on STACK_GROWSUP && (!64BIT || COMPAT) | ||
591 | help | ||
592 | This is the maximum stack size in Megabytes in the VM layout of 32-bit | ||
593 | user processes when the stack grows upwards (currently only on parisc | ||
594 | and metag arch). The stack will be located at the highest memory | ||
595 | address minus the given value, unless the RLIMIT_STACK hard limit is | ||
596 | changed to a smaller value in which case that is used. | ||
597 | |||
598 | A sane initial value is 80 MB. | ||
diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 91d67eaee050..8d2fcdfeff7f 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c | |||
@@ -1775,10 +1775,9 @@ void __init kmemleak_init(void) | |||
1775 | int i; | 1775 | int i; |
1776 | unsigned long flags; | 1776 | unsigned long flags; |
1777 | 1777 | ||
1778 | kmemleak_early_log = 0; | ||
1779 | |||
1780 | #ifdef CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF | 1778 | #ifdef CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF |
1781 | if (!kmemleak_skip_disable) { | 1779 | if (!kmemleak_skip_disable) { |
1780 | kmemleak_early_log = 0; | ||
1782 | kmemleak_disable(); | 1781 | kmemleak_disable(); |
1783 | return; | 1782 | return; |
1784 | } | 1783 | } |
@@ -1796,6 +1795,7 @@ void __init kmemleak_init(void) | |||
1796 | 1795 | ||
1797 | /* the kernel is still in UP mode, so disabling the IRQs is enough */ | 1796 | /* the kernel is still in UP mode, so disabling the IRQs is enough */ |
1798 | local_irq_save(flags); | 1797 | local_irq_save(flags); |
1798 | kmemleak_early_log = 0; | ||
1799 | if (kmemleak_error) { | 1799 | if (kmemleak_error) { |
1800 | local_irq_restore(flags); | 1800 | local_irq_restore(flags); |
1801 | return; | 1801 | return; |
diff --git a/mm/mremap.c b/mm/mremap.c index 0843feb66f3d..05f1180e9f21 100644 --- a/mm/mremap.c +++ b/mm/mremap.c | |||
@@ -194,10 +194,17 @@ unsigned long move_page_tables(struct vm_area_struct *vma, | |||
194 | break; | 194 | break; |
195 | if (pmd_trans_huge(*old_pmd)) { | 195 | if (pmd_trans_huge(*old_pmd)) { |
196 | int err = 0; | 196 | int err = 0; |
197 | if (extent == HPAGE_PMD_SIZE) | 197 | if (extent == HPAGE_PMD_SIZE) { |
198 | VM_BUG_ON(vma->vm_file || !vma->anon_vma); | ||
199 | /* See comment in move_ptes() */ | ||
200 | if (need_rmap_locks) | ||
201 | anon_vma_lock_write(vma->anon_vma); | ||
198 | err = move_huge_pmd(vma, new_vma, old_addr, | 202 | err = move_huge_pmd(vma, new_vma, old_addr, |
199 | new_addr, old_end, | 203 | new_addr, old_end, |
200 | old_pmd, new_pmd); | 204 | old_pmd, new_pmd); |
205 | if (need_rmap_locks) | ||
206 | anon_vma_unlock_write(vma->anon_vma); | ||
207 | } | ||
201 | if (err > 0) { | 208 | if (err > 0) { |
202 | need_flush = true; | 209 | need_flush = true; |
203 | continue; | 210 | continue; |
diff --git a/mm/percpu.c b/mm/percpu.c index 63e24fb4387b..2ddf9a990dbd 100644 --- a/mm/percpu.c +++ b/mm/percpu.c | |||
@@ -610,7 +610,7 @@ static struct pcpu_chunk *pcpu_alloc_chunk(void) | |||
610 | chunk->map = pcpu_mem_zalloc(PCPU_DFL_MAP_ALLOC * | 610 | chunk->map = pcpu_mem_zalloc(PCPU_DFL_MAP_ALLOC * |
611 | sizeof(chunk->map[0])); | 611 | sizeof(chunk->map[0])); |
612 | if (!chunk->map) { | 612 | if (!chunk->map) { |
613 | kfree(chunk); | 613 | pcpu_mem_free(chunk, pcpu_chunk_struct_size); |
614 | return NULL; | 614 | return NULL; |
615 | } | 615 | } |
616 | 616 | ||
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index dac7f9b98687..1948d592aa54 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -557,7 +557,7 @@ static int ceph_tcp_sendmsg(struct socket *sock, struct kvec *iov, | |||
557 | return r; | 557 | return r; |
558 | } | 558 | } |
559 | 559 | ||
560 | static int ceph_tcp_sendpage(struct socket *sock, struct page *page, | 560 | static int __ceph_tcp_sendpage(struct socket *sock, struct page *page, |
561 | int offset, size_t size, bool more) | 561 | int offset, size_t size, bool more) |
562 | { | 562 | { |
563 | int flags = MSG_DONTWAIT | MSG_NOSIGNAL | (more ? MSG_MORE : MSG_EOR); | 563 | int flags = MSG_DONTWAIT | MSG_NOSIGNAL | (more ? MSG_MORE : MSG_EOR); |
@@ -570,6 +570,24 @@ static int ceph_tcp_sendpage(struct socket *sock, struct page *page, | |||
570 | return ret; | 570 | return ret; |
571 | } | 571 | } |
572 | 572 | ||
573 | static int ceph_tcp_sendpage(struct socket *sock, struct page *page, | ||
574 | int offset, size_t size, bool more) | ||
575 | { | ||
576 | int ret; | ||
577 | struct kvec iov; | ||
578 | |||
579 | /* sendpage cannot properly handle pages with page_count == 0, | ||
580 | * we need to fallback to sendmsg if that's the case */ | ||
581 | if (page_count(page) >= 1) | ||
582 | return __ceph_tcp_sendpage(sock, page, offset, size, more); | ||
583 | |||
584 | iov.iov_base = kmap(page) + offset; | ||
585 | iov.iov_len = size; | ||
586 | ret = ceph_tcp_sendmsg(sock, &iov, 1, size, more); | ||
587 | kunmap(page); | ||
588 | |||
589 | return ret; | ||
590 | } | ||
573 | 591 | ||
574 | /* | 592 | /* |
575 | * Shutdown/close the socket for the given connection. | 593 | * Shutdown/close the socket for the given connection. |
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index 8b8a5a24b223..c547e46084d3 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c | |||
@@ -329,6 +329,11 @@ static struct crush_map *crush_decode(void *pbyval, void *end) | |||
329 | dout("crush decode tunable chooseleaf_descend_once = %d", | 329 | dout("crush decode tunable chooseleaf_descend_once = %d", |
330 | c->chooseleaf_descend_once); | 330 | c->chooseleaf_descend_once); |
331 | 331 | ||
332 | ceph_decode_need(p, end, sizeof(u8), done); | ||
333 | c->chooseleaf_vary_r = ceph_decode_8(p); | ||
334 | dout("crush decode tunable chooseleaf_vary_r = %d", | ||
335 | c->chooseleaf_vary_r); | ||
336 | |||
332 | done: | 337 | done: |
333 | dout("crush_decode success\n"); | 338 | dout("crush_decode success\n"); |
334 | return c; | 339 | return c; |
diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh index fd8fa9aa7c4e..5b3add31f9f1 100755 --- a/scripts/checksyscalls.sh +++ b/scripts/checksyscalls.sh | |||
@@ -25,7 +25,7 @@ cat << EOF | |||
25 | #define __IGNORE_rmdir /* unlinkat */ | 25 | #define __IGNORE_rmdir /* unlinkat */ |
26 | #define __IGNORE_lchown /* fchownat */ | 26 | #define __IGNORE_lchown /* fchownat */ |
27 | #define __IGNORE_access /* faccessat */ | 27 | #define __IGNORE_access /* faccessat */ |
28 | #define __IGNORE_rename /* renameat */ | 28 | #define __IGNORE_rename /* renameat2 */ |
29 | #define __IGNORE_readlink /* readlinkat */ | 29 | #define __IGNORE_readlink /* readlinkat */ |
30 | #define __IGNORE_symlink /* symlinkat */ | 30 | #define __IGNORE_symlink /* symlinkat */ |
31 | #define __IGNORE_utimes /* futimesat */ | 31 | #define __IGNORE_utimes /* futimesat */ |
@@ -37,6 +37,9 @@ cat << EOF | |||
37 | #define __IGNORE_lstat64 /* fstatat64 */ | 37 | #define __IGNORE_lstat64 /* fstatat64 */ |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | /* Missing flags argument */ | ||
41 | #define __IGNORE_renameat /* renameat2 */ | ||
42 | |||
40 | /* CLOEXEC flag */ | 43 | /* CLOEXEC flag */ |
41 | #define __IGNORE_pipe /* pipe2 */ | 44 | #define __IGNORE_pipe /* pipe2 */ |
42 | #define __IGNORE_dup2 /* dup3 */ | 45 | #define __IGNORE_dup2 /* dup3 */ |
diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 8365909f5f8c..9134dbf70d3e 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c | |||
@@ -306,57 +306,138 @@ static int devcgroup_seq_show(struct seq_file *m, void *v) | |||
306 | } | 306 | } |
307 | 307 | ||
308 | /** | 308 | /** |
309 | * may_access - verifies if a new exception is part of what is allowed | 309 | * match_exception - iterates the exception list trying to find a complete match |
310 | * by a dev cgroup based on the default policy + | 310 | * @exceptions: list of exceptions |
311 | * exceptions. This is used to make sure a child cgroup | 311 | * @type: device type (DEV_BLOCK or DEV_CHAR) |
312 | * won't have more privileges than its parent or to | 312 | * @major: device file major number, ~0 to match all |
313 | * verify if a certain access is allowed. | 313 | * @minor: device file minor number, ~0 to match all |
314 | * @dev_cgroup: dev cgroup to be tested against | 314 | * @access: permission mask (ACC_READ, ACC_WRITE, ACC_MKNOD) |
315 | * @refex: new exception | 315 | * |
316 | * @behavior: behavior of the exception | 316 | * It is considered a complete match if an exception is found that will |
317 | * contain the entire range of provided parameters. | ||
318 | * | ||
319 | * Return: true in case it matches an exception completely | ||
317 | */ | 320 | */ |
318 | static bool may_access(struct dev_cgroup *dev_cgroup, | 321 | static bool match_exception(struct list_head *exceptions, short type, |
319 | struct dev_exception_item *refex, | 322 | u32 major, u32 minor, short access) |
320 | enum devcg_behavior behavior) | ||
321 | { | 323 | { |
322 | struct dev_exception_item *ex; | 324 | struct dev_exception_item *ex; |
323 | bool match = false; | ||
324 | 325 | ||
325 | rcu_lockdep_assert(rcu_read_lock_held() || | 326 | list_for_each_entry_rcu(ex, exceptions, list) { |
326 | lockdep_is_held(&devcgroup_mutex), | 327 | if ((type & DEV_BLOCK) && !(ex->type & DEV_BLOCK)) |
327 | "device_cgroup::may_access() called without proper synchronization"); | 328 | continue; |
329 | if ((type & DEV_CHAR) && !(ex->type & DEV_CHAR)) | ||
330 | continue; | ||
331 | if (ex->major != ~0 && ex->major != major) | ||
332 | continue; | ||
333 | if (ex->minor != ~0 && ex->minor != minor) | ||
334 | continue; | ||
335 | /* provided access cannot have more than the exception rule */ | ||
336 | if (access & (~ex->access)) | ||
337 | continue; | ||
338 | return true; | ||
339 | } | ||
340 | return false; | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * match_exception_partial - iterates the exception list trying to find a partial match | ||
345 | * @exceptions: list of exceptions | ||
346 | * @type: device type (DEV_BLOCK or DEV_CHAR) | ||
347 | * @major: device file major number, ~0 to match all | ||
348 | * @minor: device file minor number, ~0 to match all | ||
349 | * @access: permission mask (ACC_READ, ACC_WRITE, ACC_MKNOD) | ||
350 | * | ||
351 | * It is considered a partial match if an exception's range is found to | ||
352 | * contain *any* of the devices specified by provided parameters. This is | ||
353 | * used to make sure no extra access is being granted that is forbidden by | ||
354 | * any of the exception list. | ||
355 | * | ||
356 | * Return: true in case the provided range mat matches an exception completely | ||
357 | */ | ||
358 | static bool match_exception_partial(struct list_head *exceptions, short type, | ||
359 | u32 major, u32 minor, short access) | ||
360 | { | ||
361 | struct dev_exception_item *ex; | ||
328 | 362 | ||
329 | list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) { | 363 | list_for_each_entry_rcu(ex, exceptions, list) { |
330 | if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK)) | 364 | if ((type & DEV_BLOCK) && !(ex->type & DEV_BLOCK)) |
331 | continue; | 365 | continue; |
332 | if ((refex->type & DEV_CHAR) && !(ex->type & DEV_CHAR)) | 366 | if ((type & DEV_CHAR) && !(ex->type & DEV_CHAR)) |
333 | continue; | 367 | continue; |
334 | if (ex->major != ~0 && ex->major != refex->major) | 368 | /* |
369 | * We must be sure that both the exception and the provided | ||
370 | * range aren't masking all devices | ||
371 | */ | ||
372 | if (ex->major != ~0 && major != ~0 && ex->major != major) | ||
335 | continue; | 373 | continue; |
336 | if (ex->minor != ~0 && ex->minor != refex->minor) | 374 | if (ex->minor != ~0 && minor != ~0 && ex->minor != minor) |
337 | continue; | 375 | continue; |
338 | if (refex->access & (~ex->access)) | 376 | /* |
377 | * In order to make sure the provided range isn't matching | ||
378 | * an exception, all its access bits shouldn't match the | ||
379 | * exception's access bits | ||
380 | */ | ||
381 | if (!(access & ex->access)) | ||
339 | continue; | 382 | continue; |
340 | match = true; | 383 | return true; |
341 | break; | ||
342 | } | 384 | } |
385 | return false; | ||
386 | } | ||
387 | |||
388 | /** | ||
389 | * verify_new_ex - verifies if a new exception is allowed by parent cgroup's permissions | ||
390 | * @dev_cgroup: dev cgroup to be tested against | ||
391 | * @refex: new exception | ||
392 | * @behavior: behavior of the exception's dev_cgroup | ||
393 | * | ||
394 | * This is used to make sure a child cgroup won't have more privileges | ||
395 | * than its parent | ||
396 | */ | ||
397 | static bool verify_new_ex(struct dev_cgroup *dev_cgroup, | ||
398 | struct dev_exception_item *refex, | ||
399 | enum devcg_behavior behavior) | ||
400 | { | ||
401 | bool match = false; | ||
402 | |||
403 | rcu_lockdep_assert(rcu_read_lock_held() || | ||
404 | lockdep_is_held(&devcgroup_mutex), | ||
405 | "device_cgroup:verify_new_ex called without proper synchronization"); | ||
343 | 406 | ||
344 | if (dev_cgroup->behavior == DEVCG_DEFAULT_ALLOW) { | 407 | if (dev_cgroup->behavior == DEVCG_DEFAULT_ALLOW) { |
345 | if (behavior == DEVCG_DEFAULT_ALLOW) { | 408 | if (behavior == DEVCG_DEFAULT_ALLOW) { |
346 | /* the exception will deny access to certain devices */ | 409 | /* |
410 | * new exception in the child doesn't matter, only | ||
411 | * adding extra restrictions | ||
412 | */ | ||
347 | return true; | 413 | return true; |
348 | } else { | 414 | } else { |
349 | /* the exception will allow access to certain devices */ | 415 | /* |
416 | * new exception in the child will add more devices | ||
417 | * that can be acessed, so it can't match any of | ||
418 | * parent's exceptions, even slightly | ||
419 | */ | ||
420 | match = match_exception_partial(&dev_cgroup->exceptions, | ||
421 | refex->type, | ||
422 | refex->major, | ||
423 | refex->minor, | ||
424 | refex->access); | ||
425 | |||
350 | if (match) | 426 | if (match) |
351 | /* | ||
352 | * a new exception allowing access shouldn't | ||
353 | * match an parent's exception | ||
354 | */ | ||
355 | return false; | 427 | return false; |
356 | return true; | 428 | return true; |
357 | } | 429 | } |
358 | } else { | 430 | } else { |
359 | /* only behavior == DEVCG_DEFAULT_DENY allowed here */ | 431 | /* |
432 | * Only behavior == DEVCG_DEFAULT_DENY allowed here, therefore | ||
433 | * the new exception will add access to more devices and must | ||
434 | * be contained completely in an parent's exception to be | ||
435 | * allowed | ||
436 | */ | ||
437 | match = match_exception(&dev_cgroup->exceptions, refex->type, | ||
438 | refex->major, refex->minor, | ||
439 | refex->access); | ||
440 | |||
360 | if (match) | 441 | if (match) |
361 | /* parent has an exception that matches the proposed */ | 442 | /* parent has an exception that matches the proposed */ |
362 | return true; | 443 | return true; |
@@ -378,7 +459,38 @@ static int parent_has_perm(struct dev_cgroup *childcg, | |||
378 | 459 | ||
379 | if (!parent) | 460 | if (!parent) |
380 | return 1; | 461 | return 1; |
381 | return may_access(parent, ex, childcg->behavior); | 462 | return verify_new_ex(parent, ex, childcg->behavior); |
463 | } | ||
464 | |||
465 | /** | ||
466 | * parent_allows_removal - verify if it's ok to remove an exception | ||
467 | * @childcg: child cgroup from where the exception will be removed | ||
468 | * @ex: exception being removed | ||
469 | * | ||
470 | * When removing an exception in cgroups with default ALLOW policy, it must | ||
471 | * be checked if removing it will give the child cgroup more access than the | ||
472 | * parent. | ||
473 | * | ||
474 | * Return: true if it's ok to remove exception, false otherwise | ||
475 | */ | ||
476 | static bool parent_allows_removal(struct dev_cgroup *childcg, | ||
477 | struct dev_exception_item *ex) | ||
478 | { | ||
479 | struct dev_cgroup *parent = css_to_devcgroup(css_parent(&childcg->css)); | ||
480 | |||
481 | if (!parent) | ||
482 | return true; | ||
483 | |||
484 | /* It's always allowed to remove access to devices */ | ||
485 | if (childcg->behavior == DEVCG_DEFAULT_DENY) | ||
486 | return true; | ||
487 | |||
488 | /* | ||
489 | * Make sure you're not removing part or a whole exception existing in | ||
490 | * the parent cgroup | ||
491 | */ | ||
492 | return !match_exception_partial(&parent->exceptions, ex->type, | ||
493 | ex->major, ex->minor, ex->access); | ||
382 | } | 494 | } |
383 | 495 | ||
384 | /** | 496 | /** |
@@ -616,17 +728,21 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, | |||
616 | 728 | ||
617 | switch (filetype) { | 729 | switch (filetype) { |
618 | case DEVCG_ALLOW: | 730 | case DEVCG_ALLOW: |
619 | if (!parent_has_perm(devcgroup, &ex)) | ||
620 | return -EPERM; | ||
621 | /* | 731 | /* |
622 | * If the default policy is to allow by default, try to remove | 732 | * If the default policy is to allow by default, try to remove |
623 | * an matching exception instead. And be silent about it: we | 733 | * an matching exception instead. And be silent about it: we |
624 | * don't want to break compatibility | 734 | * don't want to break compatibility |
625 | */ | 735 | */ |
626 | if (devcgroup->behavior == DEVCG_DEFAULT_ALLOW) { | 736 | if (devcgroup->behavior == DEVCG_DEFAULT_ALLOW) { |
737 | /* Check if the parent allows removing it first */ | ||
738 | if (!parent_allows_removal(devcgroup, &ex)) | ||
739 | return -EPERM; | ||
627 | dev_exception_rm(devcgroup, &ex); | 740 | dev_exception_rm(devcgroup, &ex); |
628 | return 0; | 741 | break; |
629 | } | 742 | } |
743 | |||
744 | if (!parent_has_perm(devcgroup, &ex)) | ||
745 | return -EPERM; | ||
630 | rc = dev_exception_add(devcgroup, &ex); | 746 | rc = dev_exception_add(devcgroup, &ex); |
631 | break; | 747 | break; |
632 | case DEVCG_DENY: | 748 | case DEVCG_DENY: |
@@ -704,18 +820,18 @@ static int __devcgroup_check_permission(short type, u32 major, u32 minor, | |||
704 | short access) | 820 | short access) |
705 | { | 821 | { |
706 | struct dev_cgroup *dev_cgroup; | 822 | struct dev_cgroup *dev_cgroup; |
707 | struct dev_exception_item ex; | 823 | bool rc; |
708 | int rc; | ||
709 | |||
710 | memset(&ex, 0, sizeof(ex)); | ||
711 | ex.type = type; | ||
712 | ex.major = major; | ||
713 | ex.minor = minor; | ||
714 | ex.access = access; | ||
715 | 824 | ||
716 | rcu_read_lock(); | 825 | rcu_read_lock(); |
717 | dev_cgroup = task_devcgroup(current); | 826 | dev_cgroup = task_devcgroup(current); |
718 | rc = may_access(dev_cgroup, &ex, dev_cgroup->behavior); | 827 | if (dev_cgroup->behavior == DEVCG_DEFAULT_ALLOW) |
828 | /* Can't match any of the exceptions, even partially */ | ||
829 | rc = !match_exception_partial(&dev_cgroup->exceptions, | ||
830 | type, major, minor, access); | ||
831 | else | ||
832 | /* Need to match completely one exception to be allowed */ | ||
833 | rc = match_exception(&dev_cgroup->exceptions, type, major, | ||
834 | minor, access); | ||
719 | rcu_read_unlock(); | 835 | rcu_read_unlock(); |
720 | 836 | ||
721 | if (!rc) | 837 | if (!rc) |
diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig index b3e274fe4a77..9f363fac7688 100644 --- a/sound/firewire/Kconfig +++ b/sound/firewire/Kconfig | |||
@@ -61,4 +61,63 @@ config SND_SCS1X | |||
61 | To compile this driver as a module, choose M here: the module | 61 | To compile this driver as a module, choose M here: the module |
62 | will be called snd-scs1x. | 62 | will be called snd-scs1x. |
63 | 63 | ||
64 | config SND_FIREWORKS | ||
65 | tristate "Echo Fireworks board module support" | ||
66 | select SND_FIREWIRE_LIB | ||
67 | select SND_RAWMIDI | ||
68 | select SND_PCM | ||
69 | select SND_HWDEP | ||
70 | help | ||
71 | Say Y here to include support for FireWire devices based | ||
72 | on Echo Digital Audio Fireworks board: | ||
73 | * Mackie Onyx 400F/1200F | ||
74 | * Echo AudioFire12/8(until 2009 July) | ||
75 | * Echo AudioFire2/4/Pre8/8(since 2009 July) | ||
76 | * Echo Fireworks 8/HDMI | ||
77 | * Gibson Robot Interface Pack/GoldTop | ||
78 | |||
79 | To compile this driver as a module, choose M here: the module | ||
80 | will be called snd-fireworks. | ||
81 | |||
82 | config SND_BEBOB | ||
83 | tristate "BridgeCo DM1000/DM1100/DM1500 with BeBoB firmware" | ||
84 | select SND_FIREWIRE_LIB | ||
85 | select SND_RAWMIDI | ||
86 | select SND_PCM | ||
87 | select SND_HWDEP | ||
88 | help | ||
89 | Say Y here to include support for FireWire devices based | ||
90 | on BridgeCo DM1000/DM1100/DM1500 with BeBoB firmware: | ||
91 | * Edirol FA-66/FA-101 | ||
92 | * PreSonus FIREBOX/FIREPOD/FP10/Inspire1394 | ||
93 | * BridgeCo RDAudio1/Audio5 | ||
94 | * Mackie Onyx 1220/1620/1640 (Firewire I/O Card) | ||
95 | * Mackie d.2 (Firewire Option) | ||
96 | * Stanton FinalScratch 2 (ScratchAmp) | ||
97 | * Tascam IF-FW/DM | ||
98 | * Behringer XENIX UFX 1204/1604 | ||
99 | * Behringer Digital Mixer X32 series (X-UF Card) | ||
100 | * Apogee Rosetta 200/400 (X-FireWire card) | ||
101 | * Apogee DA/AD/DD-16X (X-FireWire card) | ||
102 | * Apogee Ensemble | ||
103 | * ESI Quotafire610 | ||
104 | * AcousticReality eARMasterOne | ||
105 | * CME MatrixKFW | ||
106 | * Phonic Helix Board 12 MkII/18 MkII/24 MkII | ||
107 | * Phonic Helix Board 12 Universal/18 Universal/24 Universal | ||
108 | * Lynx Aurora 8/16 (LT-FW) | ||
109 | * ICON FireXon | ||
110 | * PrismSound Orpheus/ADA-8XR | ||
111 | * TerraTec PHASE 24 FW/PHASE X24 FW/PHASE 88 Rack FW | ||
112 | * Terratec EWS MIC2/EWS MIC4 | ||
113 | * Terratec Aureon 7.1 Firewire | ||
114 | * Yamaha GO44/GO46 | ||
115 | * Focusrite Saffire/Saffire LE/SaffirePro10 IO/SaffirePro26 IO | ||
116 | * M-Audio Firewire410/AudioPhile/Solo | ||
117 | * M-Audio Ozonic/NRV10/ProfireLightBridge | ||
118 | * M-Audio Firewire 1814/ProjectMix IO | ||
119 | |||
120 | To compile this driver as a module, choose M here: the module | ||
121 | will be called snd-bebob. | ||
122 | |||
64 | endif # SND_FIREWIRE | 123 | endif # SND_FIREWIRE |
diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile index 509955061d30..fad8d49306ab 100644 --- a/sound/firewire/Makefile +++ b/sound/firewire/Makefile | |||
@@ -10,3 +10,5 @@ obj-$(CONFIG_SND_DICE) += snd-dice.o | |||
10 | obj-$(CONFIG_SND_FIREWIRE_SPEAKERS) += snd-firewire-speakers.o | 10 | obj-$(CONFIG_SND_FIREWIRE_SPEAKERS) += snd-firewire-speakers.o |
11 | obj-$(CONFIG_SND_ISIGHT) += snd-isight.o | 11 | obj-$(CONFIG_SND_ISIGHT) += snd-isight.o |
12 | obj-$(CONFIG_SND_SCS1X) += snd-scs1x.o | 12 | obj-$(CONFIG_SND_SCS1X) += snd-scs1x.o |
13 | obj-$(CONFIG_SND_FIREWORKS) += fireworks/ | ||
14 | obj-$(CONFIG_SND_BEBOB) += bebob/ | ||
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index 9048777228e2..31dd1cfc79b3 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c | |||
@@ -11,7 +11,10 @@ | |||
11 | #include <linux/firewire.h> | 11 | #include <linux/firewire.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/sched.h> | ||
14 | #include <sound/pcm.h> | 15 | #include <sound/pcm.h> |
16 | #include <sound/pcm_params.h> | ||
17 | #include <sound/rawmidi.h> | ||
15 | #include "amdtp.h" | 18 | #include "amdtp.h" |
16 | 19 | ||
17 | #define TICKS_PER_CYCLE 3072 | 20 | #define TICKS_PER_CYCLE 3072 |
@@ -20,50 +23,78 @@ | |||
20 | 23 | ||
21 | #define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */ | 24 | #define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */ |
22 | 25 | ||
26 | /* isochronous header parameters */ | ||
27 | #define ISO_DATA_LENGTH_SHIFT 16 | ||
23 | #define TAG_CIP 1 | 28 | #define TAG_CIP 1 |
24 | 29 | ||
30 | /* common isochronous packet header parameters */ | ||
25 | #define CIP_EOH (1u << 31) | 31 | #define CIP_EOH (1u << 31) |
32 | #define CIP_EOH_MASK 0x80000000 | ||
26 | #define CIP_FMT_AM (0x10 << 24) | 33 | #define CIP_FMT_AM (0x10 << 24) |
27 | #define AMDTP_FDF_AM824 (0 << 19) | 34 | #define CIP_FMT_MASK 0x3f000000 |
28 | #define AMDTP_FDF_SFC_SHIFT 16 | 35 | #define CIP_SYT_MASK 0x0000ffff |
36 | #define CIP_SYT_NO_INFO 0xffff | ||
37 | #define CIP_FDF_MASK 0x00ff0000 | ||
38 | #define CIP_FDF_SFC_SHIFT 16 | ||
39 | |||
40 | /* | ||
41 | * Audio and Music transfer protocol specific parameters | ||
42 | * only "Clock-based rate control mode" is supported | ||
43 | */ | ||
44 | #define AMDTP_FDF_AM824 (0 << (CIP_FDF_SFC_SHIFT + 3)) | ||
45 | #define AMDTP_FDF_NO_DATA 0xff | ||
46 | #define AMDTP_DBS_MASK 0x00ff0000 | ||
47 | #define AMDTP_DBS_SHIFT 16 | ||
48 | #define AMDTP_DBC_MASK 0x000000ff | ||
29 | 49 | ||
30 | /* TODO: make these configurable */ | 50 | /* TODO: make these configurable */ |
31 | #define INTERRUPT_INTERVAL 16 | 51 | #define INTERRUPT_INTERVAL 16 |
32 | #define QUEUE_LENGTH 48 | 52 | #define QUEUE_LENGTH 48 |
33 | 53 | ||
54 | #define IN_PACKET_HEADER_SIZE 4 | ||
55 | #define OUT_PACKET_HEADER_SIZE 0 | ||
56 | |||
34 | static void pcm_period_tasklet(unsigned long data); | 57 | static void pcm_period_tasklet(unsigned long data); |
35 | 58 | ||
36 | /** | 59 | /** |
37 | * amdtp_out_stream_init - initialize an AMDTP output stream structure | 60 | * amdtp_stream_init - initialize an AMDTP stream structure |
38 | * @s: the AMDTP output stream to initialize | 61 | * @s: the AMDTP stream to initialize |
39 | * @unit: the target of the stream | 62 | * @unit: the target of the stream |
63 | * @dir: the direction of stream | ||
40 | * @flags: the packet transmission method to use | 64 | * @flags: the packet transmission method to use |
41 | */ | 65 | */ |
42 | int amdtp_out_stream_init(struct amdtp_out_stream *s, struct fw_unit *unit, | 66 | int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, |
43 | enum cip_out_flags flags) | 67 | enum amdtp_stream_direction dir, enum cip_flags flags) |
44 | { | 68 | { |
45 | s->unit = fw_unit_get(unit); | 69 | s->unit = fw_unit_get(unit); |
70 | s->direction = dir; | ||
46 | s->flags = flags; | 71 | s->flags = flags; |
47 | s->context = ERR_PTR(-1); | 72 | s->context = ERR_PTR(-1); |
48 | mutex_init(&s->mutex); | 73 | mutex_init(&s->mutex); |
49 | tasklet_init(&s->period_tasklet, pcm_period_tasklet, (unsigned long)s); | 74 | tasklet_init(&s->period_tasklet, pcm_period_tasklet, (unsigned long)s); |
50 | s->packet_index = 0; | 75 | s->packet_index = 0; |
51 | 76 | ||
77 | init_waitqueue_head(&s->callback_wait); | ||
78 | s->callbacked = false; | ||
79 | s->sync_slave = NULL; | ||
80 | |||
81 | s->rx_blocks_for_midi = UINT_MAX; | ||
82 | |||
52 | return 0; | 83 | return 0; |
53 | } | 84 | } |
54 | EXPORT_SYMBOL(amdtp_out_stream_init); | 85 | EXPORT_SYMBOL(amdtp_stream_init); |
55 | 86 | ||
56 | /** | 87 | /** |
57 | * amdtp_out_stream_destroy - free stream resources | 88 | * amdtp_stream_destroy - free stream resources |
58 | * @s: the AMDTP output stream to destroy | 89 | * @s: the AMDTP stream to destroy |
59 | */ | 90 | */ |
60 | void amdtp_out_stream_destroy(struct amdtp_out_stream *s) | 91 | void amdtp_stream_destroy(struct amdtp_stream *s) |
61 | { | 92 | { |
62 | WARN_ON(amdtp_out_stream_running(s)); | 93 | WARN_ON(amdtp_stream_running(s)); |
63 | mutex_destroy(&s->mutex); | 94 | mutex_destroy(&s->mutex); |
64 | fw_unit_put(s->unit); | 95 | fw_unit_put(s->unit); |
65 | } | 96 | } |
66 | EXPORT_SYMBOL(amdtp_out_stream_destroy); | 97 | EXPORT_SYMBOL(amdtp_stream_destroy); |
67 | 98 | ||
68 | const unsigned int amdtp_syt_intervals[CIP_SFC_COUNT] = { | 99 | const unsigned int amdtp_syt_intervals[CIP_SFC_COUNT] = { |
69 | [CIP_SFC_32000] = 8, | 100 | [CIP_SFC_32000] = 8, |
@@ -76,9 +107,75 @@ const unsigned int amdtp_syt_intervals[CIP_SFC_COUNT] = { | |||
76 | }; | 107 | }; |
77 | EXPORT_SYMBOL(amdtp_syt_intervals); | 108 | EXPORT_SYMBOL(amdtp_syt_intervals); |
78 | 109 | ||
110 | const unsigned int amdtp_rate_table[CIP_SFC_COUNT] = { | ||
111 | [CIP_SFC_32000] = 32000, | ||
112 | [CIP_SFC_44100] = 44100, | ||
113 | [CIP_SFC_48000] = 48000, | ||
114 | [CIP_SFC_88200] = 88200, | ||
115 | [CIP_SFC_96000] = 96000, | ||
116 | [CIP_SFC_176400] = 176400, | ||
117 | [CIP_SFC_192000] = 192000, | ||
118 | }; | ||
119 | EXPORT_SYMBOL(amdtp_rate_table); | ||
120 | |||
121 | /** | ||
122 | * amdtp_stream_add_pcm_hw_constraints - add hw constraints for PCM substream | ||
123 | * @s: the AMDTP stream, which must be initialized. | ||
124 | * @runtime: the PCM substream runtime | ||
125 | */ | ||
126 | int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s, | ||
127 | struct snd_pcm_runtime *runtime) | ||
128 | { | ||
129 | int err; | ||
130 | |||
131 | /* AM824 in IEC 61883-6 can deliver 24bit data */ | ||
132 | err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); | ||
133 | if (err < 0) | ||
134 | goto end; | ||
135 | |||
136 | /* | ||
137 | * Currently firewire-lib processes 16 packets in one software | ||
138 | * interrupt callback. This equals to 2msec but actually the | ||
139 | * interval of the interrupts has a jitter. | ||
140 | * Additionally, even if adding a constraint to fit period size to | ||
141 | * 2msec, actual calculated frames per period doesn't equal to 2msec, | ||
142 | * depending on sampling rate. | ||
143 | * Anyway, the interval to call snd_pcm_period_elapsed() cannot 2msec. | ||
144 | * Here let us use 5msec for safe period interrupt. | ||
145 | */ | ||
146 | err = snd_pcm_hw_constraint_minmax(runtime, | ||
147 | SNDRV_PCM_HW_PARAM_PERIOD_TIME, | ||
148 | 5000, UINT_MAX); | ||
149 | if (err < 0) | ||
150 | goto end; | ||
151 | |||
152 | /* Non-Blocking stream has no more constraints */ | ||
153 | if (!(s->flags & CIP_BLOCKING)) | ||
154 | goto end; | ||
155 | |||
156 | /* | ||
157 | * One AMDTP packet can include some frames. In blocking mode, the | ||
158 | * number equals to SYT_INTERVAL. So the number is 8, 16 or 32, | ||
159 | * depending on its sampling rate. For accurate period interrupt, it's | ||
160 | * preferrable to aligh period/buffer sizes to current SYT_INTERVAL. | ||
161 | * | ||
162 | * TODO: These constraints can be improved with propper rules. | ||
163 | * Currently apply LCM of SYT_INTEVALs. | ||
164 | */ | ||
165 | err = snd_pcm_hw_constraint_step(runtime, 0, | ||
166 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 32); | ||
167 | if (err < 0) | ||
168 | goto end; | ||
169 | err = snd_pcm_hw_constraint_step(runtime, 0, | ||
170 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 32); | ||
171 | end: | ||
172 | return err; | ||
173 | } | ||
174 | EXPORT_SYMBOL(amdtp_stream_add_pcm_hw_constraints); | ||
175 | |||
79 | /** | 176 | /** |
80 | * amdtp_out_stream_set_parameters - set stream parameters | 177 | * amdtp_stream_set_parameters - set stream parameters |
81 | * @s: the AMDTP output stream to configure | 178 | * @s: the AMDTP stream to configure |
82 | * @rate: the sample rate | 179 | * @rate: the sample rate |
83 | * @pcm_channels: the number of PCM samples in each data block, to be encoded | 180 | * @pcm_channels: the number of PCM samples in each data block, to be encoded |
84 | * as AM824 multi-bit linear audio | 181 | * as AM824 multi-bit linear audio |
@@ -87,41 +184,30 @@ EXPORT_SYMBOL(amdtp_syt_intervals); | |||
87 | * The parameters must be set before the stream is started, and must not be | 184 | * The parameters must be set before the stream is started, and must not be |
88 | * changed while the stream is running. | 185 | * changed while the stream is running. |
89 | */ | 186 | */ |
90 | void amdtp_out_stream_set_parameters(struct amdtp_out_stream *s, | 187 | void amdtp_stream_set_parameters(struct amdtp_stream *s, |
91 | unsigned int rate, | 188 | unsigned int rate, |
92 | unsigned int pcm_channels, | 189 | unsigned int pcm_channels, |
93 | unsigned int midi_ports) | 190 | unsigned int midi_ports) |
94 | { | 191 | { |
95 | static const unsigned int rates[] = { | 192 | unsigned int i, sfc, midi_channels; |
96 | [CIP_SFC_32000] = 32000, | 193 | |
97 | [CIP_SFC_44100] = 44100, | 194 | midi_channels = DIV_ROUND_UP(midi_ports, 8); |
98 | [CIP_SFC_48000] = 48000, | ||
99 | [CIP_SFC_88200] = 88200, | ||
100 | [CIP_SFC_96000] = 96000, | ||
101 | [CIP_SFC_176400] = 176400, | ||
102 | [CIP_SFC_192000] = 192000, | ||
103 | }; | ||
104 | unsigned int sfc; | ||
105 | 195 | ||
106 | if (WARN_ON(amdtp_out_stream_running(s))) | 196 | if (WARN_ON(amdtp_stream_running(s)) | |
197 | WARN_ON(pcm_channels > AMDTP_MAX_CHANNELS_FOR_PCM) | | ||
198 | WARN_ON(midi_channels > AMDTP_MAX_CHANNELS_FOR_MIDI)) | ||
107 | return; | 199 | return; |
108 | 200 | ||
109 | for (sfc = 0; sfc < CIP_SFC_COUNT; ++sfc) | 201 | for (sfc = 0; sfc < ARRAY_SIZE(amdtp_rate_table); ++sfc) |
110 | if (rates[sfc] == rate) | 202 | if (amdtp_rate_table[sfc] == rate) |
111 | goto sfc_found; | 203 | goto sfc_found; |
112 | WARN_ON(1); | 204 | WARN_ON(1); |
113 | return; | 205 | return; |
114 | 206 | ||
115 | sfc_found: | 207 | sfc_found: |
116 | s->dual_wire = (s->flags & CIP_HI_DUALWIRE) && sfc > CIP_SFC_96000; | ||
117 | if (s->dual_wire) { | ||
118 | sfc -= 2; | ||
119 | rate /= 2; | ||
120 | pcm_channels *= 2; | ||
121 | } | ||
122 | s->sfc = sfc; | ||
123 | s->data_block_quadlets = pcm_channels + DIV_ROUND_UP(midi_ports, 8); | ||
124 | s->pcm_channels = pcm_channels; | 208 | s->pcm_channels = pcm_channels; |
209 | s->sfc = sfc; | ||
210 | s->data_block_quadlets = s->pcm_channels + midi_channels; | ||
125 | s->midi_ports = midi_ports; | 211 | s->midi_ports = midi_ports; |
126 | 212 | ||
127 | s->syt_interval = amdtp_syt_intervals[sfc]; | 213 | s->syt_interval = amdtp_syt_intervals[sfc]; |
@@ -131,48 +217,50 @@ sfc_found: | |||
131 | if (s->flags & CIP_BLOCKING) | 217 | if (s->flags & CIP_BLOCKING) |
132 | /* additional buffering needed to adjust for no-data packets */ | 218 | /* additional buffering needed to adjust for no-data packets */ |
133 | s->transfer_delay += TICKS_PER_SECOND * s->syt_interval / rate; | 219 | s->transfer_delay += TICKS_PER_SECOND * s->syt_interval / rate; |
220 | |||
221 | /* init the position map for PCM and MIDI channels */ | ||
222 | for (i = 0; i < pcm_channels; i++) | ||
223 | s->pcm_positions[i] = i; | ||
224 | s->midi_position = s->pcm_channels; | ||
134 | } | 225 | } |
135 | EXPORT_SYMBOL(amdtp_out_stream_set_parameters); | 226 | EXPORT_SYMBOL(amdtp_stream_set_parameters); |
136 | 227 | ||
137 | /** | 228 | /** |
138 | * amdtp_out_stream_get_max_payload - get the stream's packet size | 229 | * amdtp_stream_get_max_payload - get the stream's packet size |
139 | * @s: the AMDTP output stream | 230 | * @s: the AMDTP stream |
140 | * | 231 | * |
141 | * This function must not be called before the stream has been configured | 232 | * This function must not be called before the stream has been configured |
142 | * with amdtp_out_stream_set_parameters(). | 233 | * with amdtp_stream_set_parameters(). |
143 | */ | 234 | */ |
144 | unsigned int amdtp_out_stream_get_max_payload(struct amdtp_out_stream *s) | 235 | unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s) |
145 | { | 236 | { |
146 | return 8 + s->syt_interval * s->data_block_quadlets * 4; | 237 | return 8 + s->syt_interval * s->data_block_quadlets * 4; |
147 | } | 238 | } |
148 | EXPORT_SYMBOL(amdtp_out_stream_get_max_payload); | 239 | EXPORT_SYMBOL(amdtp_stream_get_max_payload); |
149 | 240 | ||
150 | static void amdtp_write_s16(struct amdtp_out_stream *s, | 241 | static void amdtp_write_s16(struct amdtp_stream *s, |
151 | struct snd_pcm_substream *pcm, | 242 | struct snd_pcm_substream *pcm, |
152 | __be32 *buffer, unsigned int frames); | 243 | __be32 *buffer, unsigned int frames); |
153 | static void amdtp_write_s32(struct amdtp_out_stream *s, | 244 | static void amdtp_write_s32(struct amdtp_stream *s, |
154 | struct snd_pcm_substream *pcm, | 245 | struct snd_pcm_substream *pcm, |
155 | __be32 *buffer, unsigned int frames); | 246 | __be32 *buffer, unsigned int frames); |
156 | static void amdtp_write_s16_dualwire(struct amdtp_out_stream *s, | 247 | static void amdtp_read_s32(struct amdtp_stream *s, |
157 | struct snd_pcm_substream *pcm, | 248 | struct snd_pcm_substream *pcm, |
158 | __be32 *buffer, unsigned int frames); | 249 | __be32 *buffer, unsigned int frames); |
159 | static void amdtp_write_s32_dualwire(struct amdtp_out_stream *s, | ||
160 | struct snd_pcm_substream *pcm, | ||
161 | __be32 *buffer, unsigned int frames); | ||
162 | 250 | ||
163 | /** | 251 | /** |
164 | * amdtp_out_stream_set_pcm_format - set the PCM format | 252 | * amdtp_stream_set_pcm_format - set the PCM format |
165 | * @s: the AMDTP output stream to configure | 253 | * @s: the AMDTP stream to configure |
166 | * @format: the format of the ALSA PCM device | 254 | * @format: the format of the ALSA PCM device |
167 | * | 255 | * |
168 | * The sample format must be set after the other paramters (rate/PCM channels/ | 256 | * The sample format must be set after the other paramters (rate/PCM channels/ |
169 | * MIDI) and before the stream is started, and must not be changed while the | 257 | * MIDI) and before the stream is started, and must not be changed while the |
170 | * stream is running. | 258 | * stream is running. |
171 | */ | 259 | */ |
172 | void amdtp_out_stream_set_pcm_format(struct amdtp_out_stream *s, | 260 | void amdtp_stream_set_pcm_format(struct amdtp_stream *s, |
173 | snd_pcm_format_t format) | 261 | snd_pcm_format_t format) |
174 | { | 262 | { |
175 | if (WARN_ON(amdtp_out_stream_running(s))) | 263 | if (WARN_ON(amdtp_stream_pcm_running(s))) |
176 | return; | 264 | return; |
177 | 265 | ||
178 | switch (format) { | 266 | switch (format) { |
@@ -180,41 +268,44 @@ void amdtp_out_stream_set_pcm_format(struct amdtp_out_stream *s, | |||
180 | WARN_ON(1); | 268 | WARN_ON(1); |
181 | /* fall through */ | 269 | /* fall through */ |
182 | case SNDRV_PCM_FORMAT_S16: | 270 | case SNDRV_PCM_FORMAT_S16: |
183 | if (s->dual_wire) | 271 | if (s->direction == AMDTP_OUT_STREAM) { |
184 | s->transfer_samples = amdtp_write_s16_dualwire; | ||
185 | else | ||
186 | s->transfer_samples = amdtp_write_s16; | 272 | s->transfer_samples = amdtp_write_s16; |
187 | break; | 273 | break; |
274 | } | ||
275 | WARN_ON(1); | ||
276 | /* fall through */ | ||
188 | case SNDRV_PCM_FORMAT_S32: | 277 | case SNDRV_PCM_FORMAT_S32: |
189 | if (s->dual_wire) | 278 | if (s->direction == AMDTP_OUT_STREAM) |
190 | s->transfer_samples = amdtp_write_s32_dualwire; | ||
191 | else | ||
192 | s->transfer_samples = amdtp_write_s32; | 279 | s->transfer_samples = amdtp_write_s32; |
280 | else | ||
281 | s->transfer_samples = amdtp_read_s32; | ||
193 | break; | 282 | break; |
194 | } | 283 | } |
195 | } | 284 | } |
196 | EXPORT_SYMBOL(amdtp_out_stream_set_pcm_format); | 285 | EXPORT_SYMBOL(amdtp_stream_set_pcm_format); |
197 | 286 | ||
198 | /** | 287 | /** |
199 | * amdtp_out_stream_pcm_prepare - prepare PCM device for running | 288 | * amdtp_stream_pcm_prepare - prepare PCM device for running |
200 | * @s: the AMDTP output stream | 289 | * @s: the AMDTP stream |
201 | * | 290 | * |
202 | * This function should be called from the PCM device's .prepare callback. | 291 | * This function should be called from the PCM device's .prepare callback. |
203 | */ | 292 | */ |
204 | void amdtp_out_stream_pcm_prepare(struct amdtp_out_stream *s) | 293 | void amdtp_stream_pcm_prepare(struct amdtp_stream *s) |
205 | { | 294 | { |
206 | tasklet_kill(&s->period_tasklet); | 295 | tasklet_kill(&s->period_tasklet); |
207 | s->pcm_buffer_pointer = 0; | 296 | s->pcm_buffer_pointer = 0; |
208 | s->pcm_period_pointer = 0; | 297 | s->pcm_period_pointer = 0; |
209 | s->pointer_flush = true; | 298 | s->pointer_flush = true; |
210 | } | 299 | } |
211 | EXPORT_SYMBOL(amdtp_out_stream_pcm_prepare); | 300 | EXPORT_SYMBOL(amdtp_stream_pcm_prepare); |
212 | 301 | ||
213 | static unsigned int calculate_data_blocks(struct amdtp_out_stream *s) | 302 | static unsigned int calculate_data_blocks(struct amdtp_stream *s) |
214 | { | 303 | { |
215 | unsigned int phase, data_blocks; | 304 | unsigned int phase, data_blocks; |
216 | 305 | ||
217 | if (!cip_sfc_is_base_44100(s->sfc)) { | 306 | if (s->flags & CIP_BLOCKING) |
307 | data_blocks = s->syt_interval; | ||
308 | else if (!cip_sfc_is_base_44100(s->sfc)) { | ||
218 | /* Sample_rate / 8000 is an integer, and precomputed. */ | 309 | /* Sample_rate / 8000 is an integer, and precomputed. */ |
219 | data_blocks = s->data_block_state; | 310 | data_blocks = s->data_block_state; |
220 | } else { | 311 | } else { |
@@ -243,7 +334,7 @@ static unsigned int calculate_data_blocks(struct amdtp_out_stream *s) | |||
243 | return data_blocks; | 334 | return data_blocks; |
244 | } | 335 | } |
245 | 336 | ||
246 | static unsigned int calculate_syt(struct amdtp_out_stream *s, | 337 | static unsigned int calculate_syt(struct amdtp_stream *s, |
247 | unsigned int cycle) | 338 | unsigned int cycle) |
248 | { | 339 | { |
249 | unsigned int syt_offset, phase, index, syt; | 340 | unsigned int syt_offset, phase, index, syt; |
@@ -280,175 +371,228 @@ static unsigned int calculate_syt(struct amdtp_out_stream *s, | |||
280 | syt = (cycle + syt_offset / TICKS_PER_CYCLE) << 12; | 371 | syt = (cycle + syt_offset / TICKS_PER_CYCLE) << 12; |
281 | syt += syt_offset % TICKS_PER_CYCLE; | 372 | syt += syt_offset % TICKS_PER_CYCLE; |
282 | 373 | ||
283 | return syt & 0xffff; | 374 | return syt & CIP_SYT_MASK; |
284 | } else { | 375 | } else { |
285 | return 0xffff; /* no info */ | 376 | return CIP_SYT_NO_INFO; |
286 | } | 377 | } |
287 | } | 378 | } |
288 | 379 | ||
289 | static void amdtp_write_s32(struct amdtp_out_stream *s, | 380 | static void amdtp_write_s32(struct amdtp_stream *s, |
290 | struct snd_pcm_substream *pcm, | 381 | struct snd_pcm_substream *pcm, |
291 | __be32 *buffer, unsigned int frames) | 382 | __be32 *buffer, unsigned int frames) |
292 | { | 383 | { |
293 | struct snd_pcm_runtime *runtime = pcm->runtime; | 384 | struct snd_pcm_runtime *runtime = pcm->runtime; |
294 | unsigned int channels, remaining_frames, frame_step, i, c; | 385 | unsigned int channels, remaining_frames, i, c; |
295 | const u32 *src; | 386 | const u32 *src; |
296 | 387 | ||
297 | channels = s->pcm_channels; | 388 | channels = s->pcm_channels; |
298 | src = (void *)runtime->dma_area + | 389 | src = (void *)runtime->dma_area + |
299 | frames_to_bytes(runtime, s->pcm_buffer_pointer); | 390 | frames_to_bytes(runtime, s->pcm_buffer_pointer); |
300 | remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; | 391 | remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; |
301 | frame_step = s->data_block_quadlets - channels; | ||
302 | 392 | ||
303 | for (i = 0; i < frames; ++i) { | 393 | for (i = 0; i < frames; ++i) { |
304 | for (c = 0; c < channels; ++c) { | 394 | for (c = 0; c < channels; ++c) { |
305 | *buffer = cpu_to_be32((*src >> 8) | 0x40000000); | 395 | buffer[s->pcm_positions[c]] = |
396 | cpu_to_be32((*src >> 8) | 0x40000000); | ||
306 | src++; | 397 | src++; |
307 | buffer++; | ||
308 | } | 398 | } |
309 | buffer += frame_step; | 399 | buffer += s->data_block_quadlets; |
310 | if (--remaining_frames == 0) | 400 | if (--remaining_frames == 0) |
311 | src = (void *)runtime->dma_area; | 401 | src = (void *)runtime->dma_area; |
312 | } | 402 | } |
313 | } | 403 | } |
314 | 404 | ||
315 | static void amdtp_write_s16(struct amdtp_out_stream *s, | 405 | static void amdtp_write_s16(struct amdtp_stream *s, |
316 | struct snd_pcm_substream *pcm, | 406 | struct snd_pcm_substream *pcm, |
317 | __be32 *buffer, unsigned int frames) | 407 | __be32 *buffer, unsigned int frames) |
318 | { | 408 | { |
319 | struct snd_pcm_runtime *runtime = pcm->runtime; | 409 | struct snd_pcm_runtime *runtime = pcm->runtime; |
320 | unsigned int channels, remaining_frames, frame_step, i, c; | 410 | unsigned int channels, remaining_frames, i, c; |
321 | const u16 *src; | 411 | const u16 *src; |
322 | 412 | ||
323 | channels = s->pcm_channels; | 413 | channels = s->pcm_channels; |
324 | src = (void *)runtime->dma_area + | 414 | src = (void *)runtime->dma_area + |
325 | frames_to_bytes(runtime, s->pcm_buffer_pointer); | 415 | frames_to_bytes(runtime, s->pcm_buffer_pointer); |
326 | remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; | 416 | remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; |
327 | frame_step = s->data_block_quadlets - channels; | ||
328 | 417 | ||
329 | for (i = 0; i < frames; ++i) { | 418 | for (i = 0; i < frames; ++i) { |
330 | for (c = 0; c < channels; ++c) { | 419 | for (c = 0; c < channels; ++c) { |
331 | *buffer = cpu_to_be32((*src << 8) | 0x40000000); | 420 | buffer[s->pcm_positions[c]] = |
421 | cpu_to_be32((*src << 8) | 0x40000000); | ||
332 | src++; | 422 | src++; |
333 | buffer++; | ||
334 | } | 423 | } |
335 | buffer += frame_step; | 424 | buffer += s->data_block_quadlets; |
336 | if (--remaining_frames == 0) | 425 | if (--remaining_frames == 0) |
337 | src = (void *)runtime->dma_area; | 426 | src = (void *)runtime->dma_area; |
338 | } | 427 | } |
339 | } | 428 | } |
340 | 429 | ||
341 | static void amdtp_write_s32_dualwire(struct amdtp_out_stream *s, | 430 | static void amdtp_read_s32(struct amdtp_stream *s, |
342 | struct snd_pcm_substream *pcm, | 431 | struct snd_pcm_substream *pcm, |
343 | __be32 *buffer, unsigned int frames) | 432 | __be32 *buffer, unsigned int frames) |
344 | { | 433 | { |
345 | struct snd_pcm_runtime *runtime = pcm->runtime; | 434 | struct snd_pcm_runtime *runtime = pcm->runtime; |
346 | unsigned int channels, frame_adjust_1, frame_adjust_2, i, c; | 435 | unsigned int channels, remaining_frames, i, c; |
347 | const u32 *src; | 436 | u32 *dst; |
348 | 437 | ||
349 | channels = s->pcm_channels; | 438 | channels = s->pcm_channels; |
350 | src = (void *)runtime->dma_area + | 439 | dst = (void *)runtime->dma_area + |
351 | s->pcm_buffer_pointer * (runtime->frame_bits / 8); | 440 | frames_to_bytes(runtime, s->pcm_buffer_pointer); |
352 | frame_adjust_1 = channels - 1; | 441 | remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; |
353 | frame_adjust_2 = 1 - (s->data_block_quadlets - channels); | ||
354 | 442 | ||
355 | channels /= 2; | ||
356 | for (i = 0; i < frames; ++i) { | 443 | for (i = 0; i < frames; ++i) { |
357 | for (c = 0; c < channels; ++c) { | 444 | for (c = 0; c < channels; ++c) { |
358 | *buffer = cpu_to_be32((*src >> 8) | 0x40000000); | 445 | *dst = be32_to_cpu(buffer[s->pcm_positions[c]]) << 8; |
359 | src++; | 446 | dst++; |
360 | buffer += 2; | ||
361 | } | ||
362 | buffer -= frame_adjust_1; | ||
363 | for (c = 0; c < channels; ++c) { | ||
364 | *buffer = cpu_to_be32((*src >> 8) | 0x40000000); | ||
365 | src++; | ||
366 | buffer += 2; | ||
367 | } | 447 | } |
368 | buffer -= frame_adjust_2; | 448 | buffer += s->data_block_quadlets; |
449 | if (--remaining_frames == 0) | ||
450 | dst = (void *)runtime->dma_area; | ||
369 | } | 451 | } |
370 | } | 452 | } |
371 | 453 | ||
372 | static void amdtp_write_s16_dualwire(struct amdtp_out_stream *s, | 454 | static void amdtp_fill_pcm_silence(struct amdtp_stream *s, |
373 | struct snd_pcm_substream *pcm, | 455 | __be32 *buffer, unsigned int frames) |
374 | __be32 *buffer, unsigned int frames) | ||
375 | { | 456 | { |
376 | struct snd_pcm_runtime *runtime = pcm->runtime; | 457 | unsigned int i, c; |
377 | unsigned int channels, frame_adjust_1, frame_adjust_2, i, c; | ||
378 | const u16 *src; | ||
379 | |||
380 | channels = s->pcm_channels; | ||
381 | src = (void *)runtime->dma_area + | ||
382 | s->pcm_buffer_pointer * (runtime->frame_bits / 8); | ||
383 | frame_adjust_1 = channels - 1; | ||
384 | frame_adjust_2 = 1 - (s->data_block_quadlets - channels); | ||
385 | 458 | ||
386 | channels /= 2; | ||
387 | for (i = 0; i < frames; ++i) { | 459 | for (i = 0; i < frames; ++i) { |
388 | for (c = 0; c < channels; ++c) { | 460 | for (c = 0; c < s->pcm_channels; ++c) |
389 | *buffer = cpu_to_be32((*src << 8) | 0x40000000); | 461 | buffer[s->pcm_positions[c]] = cpu_to_be32(0x40000000); |
390 | src++; | 462 | buffer += s->data_block_quadlets; |
391 | buffer += 2; | ||
392 | } | ||
393 | buffer -= frame_adjust_1; | ||
394 | for (c = 0; c < channels; ++c) { | ||
395 | *buffer = cpu_to_be32((*src << 8) | 0x40000000); | ||
396 | src++; | ||
397 | buffer += 2; | ||
398 | } | ||
399 | buffer -= frame_adjust_2; | ||
400 | } | 463 | } |
401 | } | 464 | } |
402 | 465 | ||
403 | static void amdtp_fill_pcm_silence(struct amdtp_out_stream *s, | 466 | static void amdtp_fill_midi(struct amdtp_stream *s, |
404 | __be32 *buffer, unsigned int frames) | 467 | __be32 *buffer, unsigned int frames) |
405 | { | 468 | { |
406 | unsigned int i, c; | 469 | unsigned int f, port; |
470 | u8 *b; | ||
471 | |||
472 | for (f = 0; f < frames; f++) { | ||
473 | buffer[s->midi_position] = 0; | ||
474 | b = (u8 *)&buffer[s->midi_position]; | ||
475 | |||
476 | port = (s->data_block_counter + f) % 8; | ||
477 | if ((f >= s->rx_blocks_for_midi) || | ||
478 | (s->midi[port] == NULL) || | ||
479 | (snd_rawmidi_transmit(s->midi[port], b + 1, 1) <= 0)) | ||
480 | b[0] = 0x80; | ||
481 | else | ||
482 | b[0] = 0x81; | ||
407 | 483 | ||
408 | for (i = 0; i < frames; ++i) { | ||
409 | for (c = 0; c < s->pcm_channels; ++c) | ||
410 | buffer[c] = cpu_to_be32(0x40000000); | ||
411 | buffer += s->data_block_quadlets; | 484 | buffer += s->data_block_quadlets; |
412 | } | 485 | } |
413 | } | 486 | } |
414 | 487 | ||
415 | static void amdtp_fill_midi(struct amdtp_out_stream *s, | 488 | static void amdtp_pull_midi(struct amdtp_stream *s, |
416 | __be32 *buffer, unsigned int frames) | 489 | __be32 *buffer, unsigned int frames) |
417 | { | 490 | { |
418 | unsigned int i; | 491 | unsigned int f, port; |
492 | int len; | ||
493 | u8 *b; | ||
494 | |||
495 | for (f = 0; f < frames; f++) { | ||
496 | port = (s->data_block_counter + f) % 8; | ||
497 | b = (u8 *)&buffer[s->midi_position]; | ||
498 | |||
499 | len = b[0] - 0x80; | ||
500 | if ((1 <= len) && (len <= 3) && (s->midi[port])) | ||
501 | snd_rawmidi_receive(s->midi[port], b + 1, len); | ||
502 | |||
503 | buffer += s->data_block_quadlets; | ||
504 | } | ||
505 | } | ||
506 | |||
507 | static void update_pcm_pointers(struct amdtp_stream *s, | ||
508 | struct snd_pcm_substream *pcm, | ||
509 | unsigned int frames) | ||
510 | { unsigned int ptr; | ||
511 | |||
512 | ptr = s->pcm_buffer_pointer + frames; | ||
513 | if (ptr >= pcm->runtime->buffer_size) | ||
514 | ptr -= pcm->runtime->buffer_size; | ||
515 | ACCESS_ONCE(s->pcm_buffer_pointer) = ptr; | ||
516 | |||
517 | s->pcm_period_pointer += frames; | ||
518 | if (s->pcm_period_pointer >= pcm->runtime->period_size) { | ||
519 | s->pcm_period_pointer -= pcm->runtime->period_size; | ||
520 | s->pointer_flush = false; | ||
521 | tasklet_hi_schedule(&s->period_tasklet); | ||
522 | } | ||
523 | } | ||
524 | |||
525 | static void pcm_period_tasklet(unsigned long data) | ||
526 | { | ||
527 | struct amdtp_stream *s = (void *)data; | ||
528 | struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm); | ||
419 | 529 | ||
420 | for (i = 0; i < frames; ++i) | 530 | if (pcm) |
421 | buffer[s->pcm_channels + i * s->data_block_quadlets] = | 531 | snd_pcm_period_elapsed(pcm); |
422 | cpu_to_be32(0x80000000); | ||
423 | } | 532 | } |
424 | 533 | ||
425 | static void queue_out_packet(struct amdtp_out_stream *s, unsigned int cycle) | 534 | static int queue_packet(struct amdtp_stream *s, |
535 | unsigned int header_length, | ||
536 | unsigned int payload_length, bool skip) | ||
537 | { | ||
538 | struct fw_iso_packet p = {0}; | ||
539 | int err = 0; | ||
540 | |||
541 | if (IS_ERR(s->context)) | ||
542 | goto end; | ||
543 | |||
544 | p.interrupt = IS_ALIGNED(s->packet_index + 1, INTERRUPT_INTERVAL); | ||
545 | p.tag = TAG_CIP; | ||
546 | p.header_length = header_length; | ||
547 | p.payload_length = (!skip) ? payload_length : 0; | ||
548 | p.skip = skip; | ||
549 | err = fw_iso_context_queue(s->context, &p, &s->buffer.iso_buffer, | ||
550 | s->buffer.packets[s->packet_index].offset); | ||
551 | if (err < 0) { | ||
552 | dev_err(&s->unit->device, "queueing error: %d\n", err); | ||
553 | goto end; | ||
554 | } | ||
555 | |||
556 | if (++s->packet_index >= QUEUE_LENGTH) | ||
557 | s->packet_index = 0; | ||
558 | end: | ||
559 | return err; | ||
560 | } | ||
561 | |||
562 | static inline int queue_out_packet(struct amdtp_stream *s, | ||
563 | unsigned int payload_length, bool skip) | ||
564 | { | ||
565 | return queue_packet(s, OUT_PACKET_HEADER_SIZE, | ||
566 | payload_length, skip); | ||
567 | } | ||
568 | |||
569 | static inline int queue_in_packet(struct amdtp_stream *s) | ||
570 | { | ||
571 | return queue_packet(s, IN_PACKET_HEADER_SIZE, | ||
572 | amdtp_stream_get_max_payload(s), false); | ||
573 | } | ||
574 | |||
575 | static void handle_out_packet(struct amdtp_stream *s, unsigned int syt) | ||
426 | { | 576 | { |
427 | __be32 *buffer; | 577 | __be32 *buffer; |
428 | unsigned int index, data_blocks, syt, ptr; | 578 | unsigned int data_blocks, payload_length; |
429 | struct snd_pcm_substream *pcm; | 579 | struct snd_pcm_substream *pcm; |
430 | struct fw_iso_packet packet; | ||
431 | int err; | ||
432 | 580 | ||
433 | if (s->packet_index < 0) | 581 | if (s->packet_index < 0) |
434 | return; | 582 | return; |
435 | index = s->packet_index; | ||
436 | 583 | ||
437 | /* this module generate empty packet for 'no data' */ | 584 | /* this module generate empty packet for 'no data' */ |
438 | syt = calculate_syt(s, cycle); | 585 | if (!(s->flags & CIP_BLOCKING) || (syt != CIP_SYT_NO_INFO)) |
439 | if (!(s->flags & CIP_BLOCKING)) | ||
440 | data_blocks = calculate_data_blocks(s); | 586 | data_blocks = calculate_data_blocks(s); |
441 | else if (syt != 0xffff) | ||
442 | data_blocks = s->syt_interval; | ||
443 | else | 587 | else |
444 | data_blocks = 0; | 588 | data_blocks = 0; |
445 | 589 | ||
446 | buffer = s->buffer.packets[index].buffer; | 590 | buffer = s->buffer.packets[s->packet_index].buffer; |
447 | buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) | | 591 | buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) | |
448 | (s->data_block_quadlets << 16) | | 592 | (s->data_block_quadlets << AMDTP_DBS_SHIFT) | |
449 | s->data_block_counter); | 593 | s->data_block_counter); |
450 | buffer[1] = cpu_to_be32(CIP_EOH | CIP_FMT_AM | AMDTP_FDF_AM824 | | 594 | buffer[1] = cpu_to_be32(CIP_EOH | CIP_FMT_AM | AMDTP_FDF_AM824 | |
451 | (s->sfc << AMDTP_FDF_SFC_SHIFT) | syt); | 595 | (s->sfc << CIP_FDF_SFC_SHIFT) | syt); |
452 | buffer += 2; | 596 | buffer += 2; |
453 | 597 | ||
454 | pcm = ACCESS_ONCE(s->pcm); | 598 | pcm = ACCESS_ONCE(s->pcm); |
@@ -461,58 +605,127 @@ static void queue_out_packet(struct amdtp_out_stream *s, unsigned int cycle) | |||
461 | 605 | ||
462 | s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff; | 606 | s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff; |
463 | 607 | ||
464 | packet.payload_length = 8 + data_blocks * 4 * s->data_block_quadlets; | 608 | payload_length = 8 + data_blocks * 4 * s->data_block_quadlets; |
465 | packet.interrupt = IS_ALIGNED(index + 1, INTERRUPT_INTERVAL); | 609 | if (queue_out_packet(s, payload_length, false) < 0) { |
466 | packet.skip = 0; | ||
467 | packet.tag = TAG_CIP; | ||
468 | packet.sy = 0; | ||
469 | packet.header_length = 0; | ||
470 | |||
471 | err = fw_iso_context_queue(s->context, &packet, &s->buffer.iso_buffer, | ||
472 | s->buffer.packets[index].offset); | ||
473 | if (err < 0) { | ||
474 | dev_err(&s->unit->device, "queueing error: %d\n", err); | ||
475 | s->packet_index = -1; | 610 | s->packet_index = -1; |
476 | amdtp_out_stream_pcm_abort(s); | 611 | amdtp_stream_pcm_abort(s); |
477 | return; | 612 | return; |
478 | } | 613 | } |
479 | 614 | ||
480 | if (++index >= QUEUE_LENGTH) | 615 | if (pcm) |
481 | index = 0; | 616 | update_pcm_pointers(s, pcm, data_blocks); |
482 | s->packet_index = index; | 617 | } |
483 | 618 | ||
484 | if (pcm) { | 619 | static void handle_in_packet(struct amdtp_stream *s, |
485 | if (s->dual_wire) | 620 | unsigned int payload_quadlets, |
486 | data_blocks *= 2; | 621 | __be32 *buffer) |
487 | 622 | { | |
488 | ptr = s->pcm_buffer_pointer + data_blocks; | 623 | u32 cip_header[2]; |
489 | if (ptr >= pcm->runtime->buffer_size) | 624 | unsigned int data_blocks, data_block_quadlets, data_block_counter, |
490 | ptr -= pcm->runtime->buffer_size; | 625 | dbc_interval; |
491 | ACCESS_ONCE(s->pcm_buffer_pointer) = ptr; | 626 | struct snd_pcm_substream *pcm = NULL; |
492 | 627 | bool lost; | |
493 | s->pcm_period_pointer += data_blocks; | 628 | |
494 | if (s->pcm_period_pointer >= pcm->runtime->period_size) { | 629 | cip_header[0] = be32_to_cpu(buffer[0]); |
495 | s->pcm_period_pointer -= pcm->runtime->period_size; | 630 | cip_header[1] = be32_to_cpu(buffer[1]); |
496 | s->pointer_flush = false; | 631 | |
497 | tasklet_hi_schedule(&s->period_tasklet); | 632 | /* |
633 | * This module supports 'Two-quadlet CIP header with SYT field'. | ||
634 | * For convenience, also check FMT field is AM824 or not. | ||
635 | */ | ||
636 | if (((cip_header[0] & CIP_EOH_MASK) == CIP_EOH) || | ||
637 | ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH) || | ||
638 | ((cip_header[1] & CIP_FMT_MASK) != CIP_FMT_AM)) { | ||
639 | dev_info_ratelimited(&s->unit->device, | ||
640 | "Invalid CIP header for AMDTP: %08X:%08X\n", | ||
641 | cip_header[0], cip_header[1]); | ||
642 | goto end; | ||
643 | } | ||
644 | |||
645 | /* Calculate data blocks */ | ||
646 | if (payload_quadlets < 3 || | ||
647 | ((cip_header[1] & CIP_FDF_MASK) == | ||
648 | (AMDTP_FDF_NO_DATA << CIP_FDF_SFC_SHIFT))) { | ||
649 | data_blocks = 0; | ||
650 | } else { | ||
651 | data_block_quadlets = | ||
652 | (cip_header[0] & AMDTP_DBS_MASK) >> AMDTP_DBS_SHIFT; | ||
653 | /* avoid division by zero */ | ||
654 | if (data_block_quadlets == 0) { | ||
655 | dev_info_ratelimited(&s->unit->device, | ||
656 | "Detect invalid value in dbs field: %08X\n", | ||
657 | cip_header[0]); | ||
658 | goto err; | ||
498 | } | 659 | } |
660 | if (s->flags & CIP_WRONG_DBS) | ||
661 | data_block_quadlets = s->data_block_quadlets; | ||
662 | |||
663 | data_blocks = (payload_quadlets - 2) / data_block_quadlets; | ||
499 | } | 664 | } |
500 | } | ||
501 | 665 | ||
502 | static void pcm_period_tasklet(unsigned long data) | 666 | /* Check data block counter continuity */ |
503 | { | 667 | data_block_counter = cip_header[0] & AMDTP_DBC_MASK; |
504 | struct amdtp_out_stream *s = (void *)data; | 668 | if (data_blocks == 0 && (s->flags & CIP_EMPTY_HAS_WRONG_DBC) && |
505 | struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm); | 669 | s->data_block_counter != UINT_MAX) |
670 | data_block_counter = s->data_block_counter; | ||
671 | |||
672 | if (((s->flags & CIP_SKIP_DBC_ZERO_CHECK) && data_block_counter == 0) || | ||
673 | (s->data_block_counter == UINT_MAX)) { | ||
674 | lost = false; | ||
675 | } else if (!(s->flags & CIP_DBC_IS_END_EVENT)) { | ||
676 | lost = data_block_counter != s->data_block_counter; | ||
677 | } else { | ||
678 | if ((data_blocks > 0) && (s->tx_dbc_interval > 0)) | ||
679 | dbc_interval = s->tx_dbc_interval; | ||
680 | else | ||
681 | dbc_interval = data_blocks; | ||
682 | |||
683 | lost = data_block_counter != | ||
684 | ((s->data_block_counter + dbc_interval) & 0xff); | ||
685 | } | ||
686 | |||
687 | if (lost) { | ||
688 | dev_info(&s->unit->device, | ||
689 | "Detect discontinuity of CIP: %02X %02X\n", | ||
690 | s->data_block_counter, data_block_counter); | ||
691 | goto err; | ||
692 | } | ||
693 | |||
694 | if (data_blocks > 0) { | ||
695 | buffer += 2; | ||
696 | |||
697 | pcm = ACCESS_ONCE(s->pcm); | ||
698 | if (pcm) | ||
699 | s->transfer_samples(s, pcm, buffer, data_blocks); | ||
700 | |||
701 | if (s->midi_ports) | ||
702 | amdtp_pull_midi(s, buffer, data_blocks); | ||
703 | } | ||
704 | |||
705 | if (s->flags & CIP_DBC_IS_END_EVENT) | ||
706 | s->data_block_counter = data_block_counter; | ||
707 | else | ||
708 | s->data_block_counter = | ||
709 | (data_block_counter + data_blocks) & 0xff; | ||
710 | end: | ||
711 | if (queue_in_packet(s) < 0) | ||
712 | goto err; | ||
506 | 713 | ||
507 | if (pcm) | 714 | if (pcm) |
508 | snd_pcm_period_elapsed(pcm); | 715 | update_pcm_pointers(s, pcm, data_blocks); |
716 | |||
717 | return; | ||
718 | err: | ||
719 | s->packet_index = -1; | ||
720 | amdtp_stream_pcm_abort(s); | ||
509 | } | 721 | } |
510 | 722 | ||
511 | static void out_packet_callback(struct fw_iso_context *context, u32 cycle, | 723 | static void out_stream_callback(struct fw_iso_context *context, u32 cycle, |
512 | size_t header_length, void *header, void *data) | 724 | size_t header_length, void *header, |
725 | void *private_data) | ||
513 | { | 726 | { |
514 | struct amdtp_out_stream *s = data; | 727 | struct amdtp_stream *s = private_data; |
515 | unsigned int i, packets = header_length / 4; | 728 | unsigned int i, syt, packets = header_length / 4; |
516 | 729 | ||
517 | /* | 730 | /* |
518 | * Compute the cycle of the last queued packet. | 731 | * Compute the cycle of the last queued packet. |
@@ -521,43 +734,102 @@ static void out_packet_callback(struct fw_iso_context *context, u32 cycle, | |||
521 | */ | 734 | */ |
522 | cycle += QUEUE_LENGTH - packets; | 735 | cycle += QUEUE_LENGTH - packets; |
523 | 736 | ||
524 | for (i = 0; i < packets; ++i) | 737 | for (i = 0; i < packets; ++i) { |
525 | queue_out_packet(s, ++cycle); | 738 | syt = calculate_syt(s, ++cycle); |
739 | handle_out_packet(s, syt); | ||
740 | } | ||
526 | fw_iso_context_queue_flush(s->context); | 741 | fw_iso_context_queue_flush(s->context); |
527 | } | 742 | } |
528 | 743 | ||
529 | static int queue_initial_skip_packets(struct amdtp_out_stream *s) | 744 | static void in_stream_callback(struct fw_iso_context *context, u32 cycle, |
745 | size_t header_length, void *header, | ||
746 | void *private_data) | ||
530 | { | 747 | { |
531 | struct fw_iso_packet skip_packet = { | 748 | struct amdtp_stream *s = private_data; |
532 | .skip = 1, | 749 | unsigned int p, syt, packets, payload_quadlets; |
533 | }; | 750 | __be32 *buffer, *headers = header; |
534 | unsigned int i; | ||
535 | int err; | ||
536 | 751 | ||
537 | for (i = 0; i < QUEUE_LENGTH; ++i) { | 752 | /* The number of packets in buffer */ |
538 | skip_packet.interrupt = IS_ALIGNED(s->packet_index + 1, | 753 | packets = header_length / IN_PACKET_HEADER_SIZE; |
539 | INTERRUPT_INTERVAL); | 754 | |
540 | err = fw_iso_context_queue(s->context, &skip_packet, NULL, 0); | 755 | for (p = 0; p < packets; p++) { |
541 | if (err < 0) | 756 | if (s->packet_index < 0) |
542 | return err; | 757 | break; |
543 | if (++s->packet_index >= QUEUE_LENGTH) | 758 | |
544 | s->packet_index = 0; | 759 | buffer = s->buffer.packets[s->packet_index].buffer; |
760 | |||
761 | /* Process sync slave stream */ | ||
762 | if (s->sync_slave && s->sync_slave->callbacked) { | ||
763 | syt = be32_to_cpu(buffer[1]) & CIP_SYT_MASK; | ||
764 | handle_out_packet(s->sync_slave, syt); | ||
765 | } | ||
766 | |||
767 | /* The number of quadlets in this packet */ | ||
768 | payload_quadlets = | ||
769 | (be32_to_cpu(headers[p]) >> ISO_DATA_LENGTH_SHIFT) / 4; | ||
770 | handle_in_packet(s, payload_quadlets, buffer); | ||
545 | } | 771 | } |
546 | 772 | ||
547 | return 0; | 773 | /* Queueing error or detecting discontinuity */ |
774 | if (s->packet_index < 0) { | ||
775 | /* Abort sync slave. */ | ||
776 | if (s->sync_slave) { | ||
777 | s->sync_slave->packet_index = -1; | ||
778 | amdtp_stream_pcm_abort(s->sync_slave); | ||
779 | } | ||
780 | return; | ||
781 | } | ||
782 | |||
783 | /* when sync to device, flush the packets for slave stream */ | ||
784 | if (s->sync_slave && s->sync_slave->callbacked) | ||
785 | fw_iso_context_queue_flush(s->sync_slave->context); | ||
786 | |||
787 | fw_iso_context_queue_flush(s->context); | ||
788 | } | ||
789 | |||
790 | /* processing is done by master callback */ | ||
791 | static void slave_stream_callback(struct fw_iso_context *context, u32 cycle, | ||
792 | size_t header_length, void *header, | ||
793 | void *private_data) | ||
794 | { | ||
795 | return; | ||
796 | } | ||
797 | |||
798 | /* this is executed one time */ | ||
799 | static void amdtp_stream_first_callback(struct fw_iso_context *context, | ||
800 | u32 cycle, size_t header_length, | ||
801 | void *header, void *private_data) | ||
802 | { | ||
803 | struct amdtp_stream *s = private_data; | ||
804 | |||
805 | /* | ||
806 | * For in-stream, first packet has come. | ||
807 | * For out-stream, prepared to transmit first packet | ||
808 | */ | ||
809 | s->callbacked = true; | ||
810 | wake_up(&s->callback_wait); | ||
811 | |||
812 | if (s->direction == AMDTP_IN_STREAM) | ||
813 | context->callback.sc = in_stream_callback; | ||
814 | else if ((s->flags & CIP_BLOCKING) && (s->flags & CIP_SYNC_TO_DEVICE)) | ||
815 | context->callback.sc = slave_stream_callback; | ||
816 | else | ||
817 | context->callback.sc = out_stream_callback; | ||
818 | |||
819 | context->callback.sc(context, cycle, header_length, header, s); | ||
548 | } | 820 | } |
549 | 821 | ||
550 | /** | 822 | /** |
551 | * amdtp_out_stream_start - start sending packets | 823 | * amdtp_stream_start - start transferring packets |
552 | * @s: the AMDTP output stream to start | 824 | * @s: the AMDTP stream to start |
553 | * @channel: the isochronous channel on the bus | 825 | * @channel: the isochronous channel on the bus |
554 | * @speed: firewire speed code | 826 | * @speed: firewire speed code |
555 | * | 827 | * |
556 | * The stream cannot be started until it has been configured with | 828 | * The stream cannot be started until it has been configured with |
557 | * amdtp_out_stream_set_parameters() and amdtp_out_stream_set_pcm_format(), | 829 | * amdtp_stream_set_parameters() and it must be started before any PCM or MIDI |
558 | * and it must be started before any PCM or MIDI device can be started. | 830 | * device can be started. |
559 | */ | 831 | */ |
560 | int amdtp_out_stream_start(struct amdtp_out_stream *s, int channel, int speed) | 832 | int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed) |
561 | { | 833 | { |
562 | static const struct { | 834 | static const struct { |
563 | unsigned int data_block; | 835 | unsigned int data_block; |
@@ -571,47 +843,72 @@ int amdtp_out_stream_start(struct amdtp_out_stream *s, int channel, int speed) | |||
571 | [CIP_SFC_88200] = { 0, 67 }, | 843 | [CIP_SFC_88200] = { 0, 67 }, |
572 | [CIP_SFC_176400] = { 0, 67 }, | 844 | [CIP_SFC_176400] = { 0, 67 }, |
573 | }; | 845 | }; |
574 | int err; | 846 | unsigned int header_size; |
847 | enum dma_data_direction dir; | ||
848 | int type, tag, err; | ||
575 | 849 | ||
576 | mutex_lock(&s->mutex); | 850 | mutex_lock(&s->mutex); |
577 | 851 | ||
578 | if (WARN_ON(amdtp_out_stream_running(s) || | 852 | if (WARN_ON(amdtp_stream_running(s) || |
579 | (!s->pcm_channels && !s->midi_ports))) { | 853 | (s->data_block_quadlets < 1))) { |
580 | err = -EBADFD; | 854 | err = -EBADFD; |
581 | goto err_unlock; | 855 | goto err_unlock; |
582 | } | 856 | } |
583 | 857 | ||
858 | if (s->direction == AMDTP_IN_STREAM && | ||
859 | s->flags & CIP_SKIP_INIT_DBC_CHECK) | ||
860 | s->data_block_counter = UINT_MAX; | ||
861 | else | ||
862 | s->data_block_counter = 0; | ||
584 | s->data_block_state = initial_state[s->sfc].data_block; | 863 | s->data_block_state = initial_state[s->sfc].data_block; |
585 | s->syt_offset_state = initial_state[s->sfc].syt_offset; | 864 | s->syt_offset_state = initial_state[s->sfc].syt_offset; |
586 | s->last_syt_offset = TICKS_PER_CYCLE; | 865 | s->last_syt_offset = TICKS_PER_CYCLE; |
587 | 866 | ||
867 | /* initialize packet buffer */ | ||
868 | if (s->direction == AMDTP_IN_STREAM) { | ||
869 | dir = DMA_FROM_DEVICE; | ||
870 | type = FW_ISO_CONTEXT_RECEIVE; | ||
871 | header_size = IN_PACKET_HEADER_SIZE; | ||
872 | } else { | ||
873 | dir = DMA_TO_DEVICE; | ||
874 | type = FW_ISO_CONTEXT_TRANSMIT; | ||
875 | header_size = OUT_PACKET_HEADER_SIZE; | ||
876 | } | ||
588 | err = iso_packets_buffer_init(&s->buffer, s->unit, QUEUE_LENGTH, | 877 | err = iso_packets_buffer_init(&s->buffer, s->unit, QUEUE_LENGTH, |
589 | amdtp_out_stream_get_max_payload(s), | 878 | amdtp_stream_get_max_payload(s), dir); |
590 | DMA_TO_DEVICE); | ||
591 | if (err < 0) | 879 | if (err < 0) |
592 | goto err_unlock; | 880 | goto err_unlock; |
593 | 881 | ||
594 | s->context = fw_iso_context_create(fw_parent_device(s->unit)->card, | 882 | s->context = fw_iso_context_create(fw_parent_device(s->unit)->card, |
595 | FW_ISO_CONTEXT_TRANSMIT, | 883 | type, channel, speed, header_size, |
596 | channel, speed, 0, | 884 | amdtp_stream_first_callback, s); |
597 | out_packet_callback, s); | ||
598 | if (IS_ERR(s->context)) { | 885 | if (IS_ERR(s->context)) { |
599 | err = PTR_ERR(s->context); | 886 | err = PTR_ERR(s->context); |
600 | if (err == -EBUSY) | 887 | if (err == -EBUSY) |
601 | dev_err(&s->unit->device, | 888 | dev_err(&s->unit->device, |
602 | "no free output stream on this controller\n"); | 889 | "no free stream on this controller\n"); |
603 | goto err_buffer; | 890 | goto err_buffer; |
604 | } | 891 | } |
605 | 892 | ||
606 | amdtp_out_stream_update(s); | 893 | amdtp_stream_update(s); |
607 | 894 | ||
608 | s->packet_index = 0; | 895 | s->packet_index = 0; |
609 | s->data_block_counter = 0; | 896 | do { |
610 | err = queue_initial_skip_packets(s); | 897 | if (s->direction == AMDTP_IN_STREAM) |
611 | if (err < 0) | 898 | err = queue_in_packet(s); |
612 | goto err_context; | 899 | else |
900 | err = queue_out_packet(s, 0, true); | ||
901 | if (err < 0) | ||
902 | goto err_context; | ||
903 | } while (s->packet_index > 0); | ||
613 | 904 | ||
614 | err = fw_iso_context_start(s->context, -1, 0, 0); | 905 | /* NOTE: TAG1 matches CIP. This just affects in stream. */ |
906 | tag = FW_ISO_CONTEXT_MATCH_TAG1; | ||
907 | if (s->flags & CIP_EMPTY_WITH_TAG0) | ||
908 | tag |= FW_ISO_CONTEXT_MATCH_TAG0; | ||
909 | |||
910 | s->callbacked = false; | ||
911 | err = fw_iso_context_start(s->context, -1, 0, tag); | ||
615 | if (err < 0) | 912 | if (err < 0) |
616 | goto err_context; | 913 | goto err_context; |
617 | 914 | ||
@@ -629,49 +926,49 @@ err_unlock: | |||
629 | 926 | ||
630 | return err; | 927 | return err; |
631 | } | 928 | } |
632 | EXPORT_SYMBOL(amdtp_out_stream_start); | 929 | EXPORT_SYMBOL(amdtp_stream_start); |
633 | 930 | ||
634 | /** | 931 | /** |
635 | * amdtp_out_stream_pcm_pointer - get the PCM buffer position | 932 | * amdtp_stream_pcm_pointer - get the PCM buffer position |
636 | * @s: the AMDTP output stream that transports the PCM data | 933 | * @s: the AMDTP stream that transports the PCM data |
637 | * | 934 | * |
638 | * Returns the current buffer position, in frames. | 935 | * Returns the current buffer position, in frames. |
639 | */ | 936 | */ |
640 | unsigned long amdtp_out_stream_pcm_pointer(struct amdtp_out_stream *s) | 937 | unsigned long amdtp_stream_pcm_pointer(struct amdtp_stream *s) |
641 | { | 938 | { |
642 | /* this optimization is allowed to be racy */ | 939 | /* this optimization is allowed to be racy */ |
643 | if (s->pointer_flush) | 940 | if (s->pointer_flush && amdtp_stream_running(s)) |
644 | fw_iso_context_flush_completions(s->context); | 941 | fw_iso_context_flush_completions(s->context); |
645 | else | 942 | else |
646 | s->pointer_flush = true; | 943 | s->pointer_flush = true; |
647 | 944 | ||
648 | return ACCESS_ONCE(s->pcm_buffer_pointer); | 945 | return ACCESS_ONCE(s->pcm_buffer_pointer); |
649 | } | 946 | } |
650 | EXPORT_SYMBOL(amdtp_out_stream_pcm_pointer); | 947 | EXPORT_SYMBOL(amdtp_stream_pcm_pointer); |
651 | 948 | ||
652 | /** | 949 | /** |
653 | * amdtp_out_stream_update - update the stream after a bus reset | 950 | * amdtp_stream_update - update the stream after a bus reset |
654 | * @s: the AMDTP output stream | 951 | * @s: the AMDTP stream |
655 | */ | 952 | */ |
656 | void amdtp_out_stream_update(struct amdtp_out_stream *s) | 953 | void amdtp_stream_update(struct amdtp_stream *s) |
657 | { | 954 | { |
658 | ACCESS_ONCE(s->source_node_id_field) = | 955 | ACCESS_ONCE(s->source_node_id_field) = |
659 | (fw_parent_device(s->unit)->card->node_id & 0x3f) << 24; | 956 | (fw_parent_device(s->unit)->card->node_id & 0x3f) << 24; |
660 | } | 957 | } |
661 | EXPORT_SYMBOL(amdtp_out_stream_update); | 958 | EXPORT_SYMBOL(amdtp_stream_update); |
662 | 959 | ||
663 | /** | 960 | /** |
664 | * amdtp_out_stream_stop - stop sending packets | 961 | * amdtp_stream_stop - stop sending packets |
665 | * @s: the AMDTP output stream to stop | 962 | * @s: the AMDTP stream to stop |
666 | * | 963 | * |
667 | * All PCM and MIDI devices of the stream must be stopped before the stream | 964 | * All PCM and MIDI devices of the stream must be stopped before the stream |
668 | * itself can be stopped. | 965 | * itself can be stopped. |
669 | */ | 966 | */ |
670 | void amdtp_out_stream_stop(struct amdtp_out_stream *s) | 967 | void amdtp_stream_stop(struct amdtp_stream *s) |
671 | { | 968 | { |
672 | mutex_lock(&s->mutex); | 969 | mutex_lock(&s->mutex); |
673 | 970 | ||
674 | if (!amdtp_out_stream_running(s)) { | 971 | if (!amdtp_stream_running(s)) { |
675 | mutex_unlock(&s->mutex); | 972 | mutex_unlock(&s->mutex); |
676 | return; | 973 | return; |
677 | } | 974 | } |
@@ -682,18 +979,20 @@ void amdtp_out_stream_stop(struct amdtp_out_stream *s) | |||
682 | s->context = ERR_PTR(-1); | 979 | s->context = ERR_PTR(-1); |
683 | iso_packets_buffer_destroy(&s->buffer, s->unit); | 980 | iso_packets_buffer_destroy(&s->buffer, s->unit); |
684 | 981 | ||
982 | s->callbacked = false; | ||
983 | |||
685 | mutex_unlock(&s->mutex); | 984 | mutex_unlock(&s->mutex); |
686 | } | 985 | } |
687 | EXPORT_SYMBOL(amdtp_out_stream_stop); | 986 | EXPORT_SYMBOL(amdtp_stream_stop); |
688 | 987 | ||
689 | /** | 988 | /** |
690 | * amdtp_out_stream_pcm_abort - abort the running PCM device | 989 | * amdtp_stream_pcm_abort - abort the running PCM device |
691 | * @s: the AMDTP stream about to be stopped | 990 | * @s: the AMDTP stream about to be stopped |
692 | * | 991 | * |
693 | * If the isochronous stream needs to be stopped asynchronously, call this | 992 | * If the isochronous stream needs to be stopped asynchronously, call this |
694 | * function first to stop the PCM device. | 993 | * function first to stop the PCM device. |
695 | */ | 994 | */ |
696 | void amdtp_out_stream_pcm_abort(struct amdtp_out_stream *s) | 995 | void amdtp_stream_pcm_abort(struct amdtp_stream *s) |
697 | { | 996 | { |
698 | struct snd_pcm_substream *pcm; | 997 | struct snd_pcm_substream *pcm; |
699 | 998 | ||
@@ -705,4 +1004,4 @@ void amdtp_out_stream_pcm_abort(struct amdtp_out_stream *s) | |||
705 | snd_pcm_stream_unlock_irq(pcm); | 1004 | snd_pcm_stream_unlock_irq(pcm); |
706 | } | 1005 | } |
707 | } | 1006 | } |
708 | EXPORT_SYMBOL(amdtp_out_stream_pcm_abort); | 1007 | EXPORT_SYMBOL(amdtp_stream_pcm_abort); |
diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index 2746ecd291af..d8ee7b0e9386 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h | |||
@@ -8,7 +8,7 @@ | |||
8 | #include "packets-buffer.h" | 8 | #include "packets-buffer.h" |
9 | 9 | ||
10 | /** | 10 | /** |
11 | * enum cip_out_flags - describes details of the streaming protocol | 11 | * enum cip_flags - describes details of the streaming protocol |
12 | * @CIP_NONBLOCKING: In non-blocking mode, each packet contains | 12 | * @CIP_NONBLOCKING: In non-blocking mode, each packet contains |
13 | * sample_rate/8000 samples, with rounding up or down to adjust | 13 | * sample_rate/8000 samples, with rounding up or down to adjust |
14 | * for clock skew and left-over fractional samples. This should | 14 | * for clock skew and left-over fractional samples. This should |
@@ -16,15 +16,30 @@ | |||
16 | * @CIP_BLOCKING: In blocking mode, each packet contains either zero or | 16 | * @CIP_BLOCKING: In blocking mode, each packet contains either zero or |
17 | * SYT_INTERVAL samples, with these two types alternating so that | 17 | * SYT_INTERVAL samples, with these two types alternating so that |
18 | * the overall sample rate comes out right. | 18 | * the overall sample rate comes out right. |
19 | * @CIP_HI_DUALWIRE: At rates above 96 kHz, pretend that the stream runs | 19 | * @CIP_SYNC_TO_DEVICE: In sync to device mode, time stamp in out packets is |
20 | * at half the actual sample rate with twice the number of channels; | 20 | * generated by in packets. Defaultly this driver generates timestamp. |
21 | * two samples of a channel are stored consecutively in the packet. | 21 | * @CIP_EMPTY_WITH_TAG0: Only for in-stream. Empty in-packets have TAG0. |
22 | * Requires blocking mode and SYT_INTERVAL-aligned PCM buffer size. | 22 | * @CIP_DBC_IS_END_EVENT: Only for in-stream. The value of dbc in an in-packet |
23 | * corresponds to the end of event in the packet. Out of IEC 61883. | ||
24 | * @CIP_WRONG_DBS: Only for in-stream. The value of dbs is wrong in in-packets. | ||
25 | * The value of data_block_quadlets is used instead of reported value. | ||
26 | * @SKIP_DBC_ZERO_CHECK: Only for in-stream. Packets with zero in dbc is | ||
27 | * skipped for detecting discontinuity. | ||
28 | * @CIP_SKIP_INIT_DBC_CHECK: Only for in-stream. The value of dbc in first | ||
29 | * packet is not continuous from an initial value. | ||
30 | * @CIP_EMPTY_HAS_WRONG_DBC: Only for in-stream. The value of dbc in empty | ||
31 | * packet is wrong but the others are correct. | ||
23 | */ | 32 | */ |
24 | enum cip_out_flags { | 33 | enum cip_flags { |
25 | CIP_NONBLOCKING = 0x00, | 34 | CIP_NONBLOCKING = 0x00, |
26 | CIP_BLOCKING = 0x01, | 35 | CIP_BLOCKING = 0x01, |
27 | CIP_HI_DUALWIRE = 0x02, | 36 | CIP_SYNC_TO_DEVICE = 0x02, |
37 | CIP_EMPTY_WITH_TAG0 = 0x04, | ||
38 | CIP_DBC_IS_END_EVENT = 0x08, | ||
39 | CIP_WRONG_DBS = 0x10, | ||
40 | CIP_SKIP_DBC_ZERO_CHECK = 0x20, | ||
41 | CIP_SKIP_INIT_DBC_CHECK = 0x40, | ||
42 | CIP_EMPTY_HAS_WRONG_DBC = 0x80, | ||
28 | }; | 43 | }; |
29 | 44 | ||
30 | /** | 45 | /** |
@@ -41,27 +56,55 @@ enum cip_sfc { | |||
41 | CIP_SFC_COUNT | 56 | CIP_SFC_COUNT |
42 | }; | 57 | }; |
43 | 58 | ||
59 | #define AMDTP_IN_PCM_FORMAT_BITS SNDRV_PCM_FMTBIT_S32 | ||
60 | |||
44 | #define AMDTP_OUT_PCM_FORMAT_BITS (SNDRV_PCM_FMTBIT_S16 | \ | 61 | #define AMDTP_OUT_PCM_FORMAT_BITS (SNDRV_PCM_FMTBIT_S16 | \ |
45 | SNDRV_PCM_FMTBIT_S32) | 62 | SNDRV_PCM_FMTBIT_S32) |
46 | 63 | ||
64 | |||
65 | /* | ||
66 | * This module supports maximum 64 PCM channels for one PCM stream | ||
67 | * This is for our convenience. | ||
68 | */ | ||
69 | #define AMDTP_MAX_CHANNELS_FOR_PCM 64 | ||
70 | |||
71 | /* | ||
72 | * AMDTP packet can include channels for MIDI conformant data. | ||
73 | * Each MIDI conformant data channel includes 8 MPX-MIDI data stream. | ||
74 | * Each MPX-MIDI data stream includes one data stream from/to MIDI ports. | ||
75 | * | ||
76 | * This module supports maximum 1 MIDI conformant data channels. | ||
77 | * Then this AMDTP packets can transfer maximum 8 MIDI data streams. | ||
78 | */ | ||
79 | #define AMDTP_MAX_CHANNELS_FOR_MIDI 1 | ||
80 | |||
47 | struct fw_unit; | 81 | struct fw_unit; |
48 | struct fw_iso_context; | 82 | struct fw_iso_context; |
49 | struct snd_pcm_substream; | 83 | struct snd_pcm_substream; |
84 | struct snd_pcm_runtime; | ||
85 | struct snd_rawmidi_substream; | ||
50 | 86 | ||
51 | struct amdtp_out_stream { | 87 | enum amdtp_stream_direction { |
88 | AMDTP_OUT_STREAM = 0, | ||
89 | AMDTP_IN_STREAM | ||
90 | }; | ||
91 | |||
92 | struct amdtp_stream { | ||
52 | struct fw_unit *unit; | 93 | struct fw_unit *unit; |
53 | enum cip_out_flags flags; | 94 | enum cip_flags flags; |
95 | enum amdtp_stream_direction direction; | ||
54 | struct fw_iso_context *context; | 96 | struct fw_iso_context *context; |
55 | struct mutex mutex; | 97 | struct mutex mutex; |
56 | 98 | ||
57 | enum cip_sfc sfc; | 99 | enum cip_sfc sfc; |
58 | bool dual_wire; | ||
59 | unsigned int data_block_quadlets; | 100 | unsigned int data_block_quadlets; |
60 | unsigned int pcm_channels; | 101 | unsigned int pcm_channels; |
61 | unsigned int midi_ports; | 102 | unsigned int midi_ports; |
62 | void (*transfer_samples)(struct amdtp_out_stream *s, | 103 | void (*transfer_samples)(struct amdtp_stream *s, |
63 | struct snd_pcm_substream *pcm, | 104 | struct snd_pcm_substream *pcm, |
64 | __be32 *buffer, unsigned int frames); | 105 | __be32 *buffer, unsigned int frames); |
106 | u8 pcm_positions[AMDTP_MAX_CHANNELS_FOR_PCM]; | ||
107 | u8 midi_position; | ||
65 | 108 | ||
66 | unsigned int syt_interval; | 109 | unsigned int syt_interval; |
67 | unsigned int transfer_delay; | 110 | unsigned int transfer_delay; |
@@ -82,65 +125,148 @@ struct amdtp_out_stream { | |||
82 | unsigned int pcm_buffer_pointer; | 125 | unsigned int pcm_buffer_pointer; |
83 | unsigned int pcm_period_pointer; | 126 | unsigned int pcm_period_pointer; |
84 | bool pointer_flush; | 127 | bool pointer_flush; |
128 | |||
129 | struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8]; | ||
130 | |||
131 | /* quirk: fixed interval of dbc between previos/current packets. */ | ||
132 | unsigned int tx_dbc_interval; | ||
133 | |||
134 | /* quirk: the first count of data blocks in an rx packet for MIDI */ | ||
135 | unsigned int rx_blocks_for_midi; | ||
136 | |||
137 | bool callbacked; | ||
138 | wait_queue_head_t callback_wait; | ||
139 | struct amdtp_stream *sync_slave; | ||
85 | }; | 140 | }; |
86 | 141 | ||
87 | int amdtp_out_stream_init(struct amdtp_out_stream *s, struct fw_unit *unit, | 142 | int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, |
88 | enum cip_out_flags flags); | 143 | enum amdtp_stream_direction dir, |
89 | void amdtp_out_stream_destroy(struct amdtp_out_stream *s); | 144 | enum cip_flags flags); |
145 | void amdtp_stream_destroy(struct amdtp_stream *s); | ||
90 | 146 | ||
91 | void amdtp_out_stream_set_parameters(struct amdtp_out_stream *s, | 147 | void amdtp_stream_set_parameters(struct amdtp_stream *s, |
92 | unsigned int rate, | 148 | unsigned int rate, |
93 | unsigned int pcm_channels, | 149 | unsigned int pcm_channels, |
94 | unsigned int midi_ports); | 150 | unsigned int midi_ports); |
95 | unsigned int amdtp_out_stream_get_max_payload(struct amdtp_out_stream *s); | 151 | unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s); |
96 | 152 | ||
97 | int amdtp_out_stream_start(struct amdtp_out_stream *s, int channel, int speed); | 153 | int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed); |
98 | void amdtp_out_stream_update(struct amdtp_out_stream *s); | 154 | void amdtp_stream_update(struct amdtp_stream *s); |
99 | void amdtp_out_stream_stop(struct amdtp_out_stream *s); | 155 | void amdtp_stream_stop(struct amdtp_stream *s); |
100 | 156 | ||
101 | void amdtp_out_stream_set_pcm_format(struct amdtp_out_stream *s, | 157 | int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s, |
102 | snd_pcm_format_t format); | 158 | struct snd_pcm_runtime *runtime); |
103 | void amdtp_out_stream_pcm_prepare(struct amdtp_out_stream *s); | 159 | void amdtp_stream_set_pcm_format(struct amdtp_stream *s, |
104 | unsigned long amdtp_out_stream_pcm_pointer(struct amdtp_out_stream *s); | 160 | snd_pcm_format_t format); |
105 | void amdtp_out_stream_pcm_abort(struct amdtp_out_stream *s); | 161 | void amdtp_stream_pcm_prepare(struct amdtp_stream *s); |
162 | unsigned long amdtp_stream_pcm_pointer(struct amdtp_stream *s); | ||
163 | void amdtp_stream_pcm_abort(struct amdtp_stream *s); | ||
106 | 164 | ||
107 | extern const unsigned int amdtp_syt_intervals[CIP_SFC_COUNT]; | 165 | extern const unsigned int amdtp_syt_intervals[CIP_SFC_COUNT]; |
166 | extern const unsigned int amdtp_rate_table[CIP_SFC_COUNT]; | ||
108 | 167 | ||
109 | static inline bool amdtp_out_stream_running(struct amdtp_out_stream *s) | 168 | /** |
169 | * amdtp_stream_running - check stream is running or not | ||
170 | * @s: the AMDTP stream | ||
171 | * | ||
172 | * If this function returns true, the stream is running. | ||
173 | */ | ||
174 | static inline bool amdtp_stream_running(struct amdtp_stream *s) | ||
110 | { | 175 | { |
111 | return !IS_ERR(s->context); | 176 | return !IS_ERR(s->context); |
112 | } | 177 | } |
113 | 178 | ||
114 | /** | 179 | /** |
115 | * amdtp_out_streaming_error - check for streaming error | 180 | * amdtp_streaming_error - check for streaming error |
116 | * @s: the AMDTP output stream | 181 | * @s: the AMDTP stream |
117 | * | 182 | * |
118 | * If this function returns true, the stream's packet queue has stopped due to | 183 | * If this function returns true, the stream's packet queue has stopped due to |
119 | * an asynchronous error. | 184 | * an asynchronous error. |
120 | */ | 185 | */ |
121 | static inline bool amdtp_out_streaming_error(struct amdtp_out_stream *s) | 186 | static inline bool amdtp_streaming_error(struct amdtp_stream *s) |
122 | { | 187 | { |
123 | return s->packet_index < 0; | 188 | return s->packet_index < 0; |
124 | } | 189 | } |
125 | 190 | ||
126 | /** | 191 | /** |
127 | * amdtp_out_stream_pcm_trigger - start/stop playback from a PCM device | 192 | * amdtp_stream_pcm_running - check PCM substream is running or not |
128 | * @s: the AMDTP output stream | 193 | * @s: the AMDTP stream |
194 | * | ||
195 | * If this function returns true, PCM substream in the AMDTP stream is running. | ||
196 | */ | ||
197 | static inline bool amdtp_stream_pcm_running(struct amdtp_stream *s) | ||
198 | { | ||
199 | return !!s->pcm; | ||
200 | } | ||
201 | |||
202 | /** | ||
203 | * amdtp_stream_pcm_trigger - start/stop playback from a PCM device | ||
204 | * @s: the AMDTP stream | ||
129 | * @pcm: the PCM device to be started, or %NULL to stop the current device | 205 | * @pcm: the PCM device to be started, or %NULL to stop the current device |
130 | * | 206 | * |
131 | * Call this function on a running isochronous stream to enable the actual | 207 | * Call this function on a running isochronous stream to enable the actual |
132 | * transmission of PCM data. This function should be called from the PCM | 208 | * transmission of PCM data. This function should be called from the PCM |
133 | * device's .trigger callback. | 209 | * device's .trigger callback. |
134 | */ | 210 | */ |
135 | static inline void amdtp_out_stream_pcm_trigger(struct amdtp_out_stream *s, | 211 | static inline void amdtp_stream_pcm_trigger(struct amdtp_stream *s, |
136 | struct snd_pcm_substream *pcm) | 212 | struct snd_pcm_substream *pcm) |
137 | { | 213 | { |
138 | ACCESS_ONCE(s->pcm) = pcm; | 214 | ACCESS_ONCE(s->pcm) = pcm; |
139 | } | 215 | } |
140 | 216 | ||
217 | /** | ||
218 | * amdtp_stream_midi_trigger - start/stop playback/capture with a MIDI device | ||
219 | * @s: the AMDTP stream | ||
220 | * @port: index of MIDI port | ||
221 | * @midi: the MIDI device to be started, or %NULL to stop the current device | ||
222 | * | ||
223 | * Call this function on a running isochronous stream to enable the actual | ||
224 | * transmission of MIDI data. This function should be called from the MIDI | ||
225 | * device's .trigger callback. | ||
226 | */ | ||
227 | static inline void amdtp_stream_midi_trigger(struct amdtp_stream *s, | ||
228 | unsigned int port, | ||
229 | struct snd_rawmidi_substream *midi) | ||
230 | { | ||
231 | if (port < s->midi_ports) | ||
232 | ACCESS_ONCE(s->midi[port]) = midi; | ||
233 | } | ||
234 | |||
141 | static inline bool cip_sfc_is_base_44100(enum cip_sfc sfc) | 235 | static inline bool cip_sfc_is_base_44100(enum cip_sfc sfc) |
142 | { | 236 | { |
143 | return sfc & 1; | 237 | return sfc & 1; |
144 | } | 238 | } |
145 | 239 | ||
240 | static inline void amdtp_stream_set_sync(enum cip_flags sync_mode, | ||
241 | struct amdtp_stream *master, | ||
242 | struct amdtp_stream *slave) | ||
243 | { | ||
244 | if (sync_mode == CIP_SYNC_TO_DEVICE) { | ||
245 | master->flags |= CIP_SYNC_TO_DEVICE; | ||
246 | slave->flags |= CIP_SYNC_TO_DEVICE; | ||
247 | master->sync_slave = slave; | ||
248 | } else { | ||
249 | master->flags &= ~CIP_SYNC_TO_DEVICE; | ||
250 | slave->flags &= ~CIP_SYNC_TO_DEVICE; | ||
251 | master->sync_slave = NULL; | ||
252 | } | ||
253 | |||
254 | slave->sync_slave = NULL; | ||
255 | } | ||
256 | |||
257 | /** | ||
258 | * amdtp_stream_wait_callback - sleep till callbacked or timeout | ||
259 | * @s: the AMDTP stream | ||
260 | * @timeout: msec till timeout | ||
261 | * | ||
262 | * If this function return false, the AMDTP stream should be stopped. | ||
263 | */ | ||
264 | static inline bool amdtp_stream_wait_callback(struct amdtp_stream *s, | ||
265 | unsigned int timeout) | ||
266 | { | ||
267 | return wait_event_timeout(s->callback_wait, | ||
268 | s->callbacked == true, | ||
269 | msecs_to_jiffies(timeout)) > 0; | ||
270 | } | ||
271 | |||
146 | #endif | 272 | #endif |
diff --git a/sound/firewire/bebob/Makefile b/sound/firewire/bebob/Makefile new file mode 100644 index 000000000000..6cf470c80d1f --- /dev/null +++ b/sound/firewire/bebob/Makefile | |||
@@ -0,0 +1,4 @@ | |||
1 | snd-bebob-objs := bebob_command.o bebob_stream.o bebob_proc.o bebob_midi.o \ | ||
2 | bebob_pcm.o bebob_hwdep.o bebob_terratec.o bebob_yamaha.o \ | ||
3 | bebob_focusrite.o bebob_maudio.o bebob.o | ||
4 | obj-m += snd-bebob.o | ||
diff --git a/sound/firewire/bebob/bebob.c b/sound/firewire/bebob/bebob.c new file mode 100644 index 000000000000..fc19c99654aa --- /dev/null +++ b/sound/firewire/bebob/bebob.c | |||
@@ -0,0 +1,471 @@ | |||
1 | /* | ||
2 | * bebob.c - a part of driver for BeBoB based devices | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | /* | ||
10 | * BeBoB is 'BridgeCo enhanced Breakout Box'. This is installed to firewire | ||
11 | * devices with DM1000/DM1100/DM1500 chipset. It gives common way for host | ||
12 | * system to handle BeBoB based devices. | ||
13 | */ | ||
14 | |||
15 | #include "bebob.h" | ||
16 | |||
17 | MODULE_DESCRIPTION("BridgeCo BeBoB driver"); | ||
18 | MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>"); | ||
19 | MODULE_LICENSE("GPL v2"); | ||
20 | |||
21 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | ||
22 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | ||
23 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | ||
24 | |||
25 | module_param_array(index, int, NULL, 0444); | ||
26 | MODULE_PARM_DESC(index, "card index"); | ||
27 | module_param_array(id, charp, NULL, 0444); | ||
28 | MODULE_PARM_DESC(id, "ID string"); | ||
29 | module_param_array(enable, bool, NULL, 0444); | ||
30 | MODULE_PARM_DESC(enable, "enable BeBoB sound card"); | ||
31 | |||
32 | static DEFINE_MUTEX(devices_mutex); | ||
33 | static DECLARE_BITMAP(devices_used, SNDRV_CARDS); | ||
34 | |||
35 | /* Offsets from information register. */ | ||
36 | #define INFO_OFFSET_GUID 0x10 | ||
37 | #define INFO_OFFSET_HW_MODEL_ID 0x18 | ||
38 | #define INFO_OFFSET_HW_MODEL_REVISION 0x1c | ||
39 | |||
40 | #define VEN_EDIROL 0x000040ab | ||
41 | #define VEN_PRESONUS 0x00000a92 | ||
42 | #define VEN_BRIDGECO 0x000007f5 | ||
43 | #define VEN_MACKIE 0x0000000f | ||
44 | #define VEN_STANTON 0x00001260 | ||
45 | #define VEN_TASCAM 0x0000022e | ||
46 | #define VEN_BEHRINGER 0x00001564 | ||
47 | #define VEN_APOGEE 0x000003db | ||
48 | #define VEN_ESI 0x00000f1b | ||
49 | #define VEN_ACOUSTIC 0x00000002 | ||
50 | #define VEN_CME 0x0000000a | ||
51 | #define VEN_PHONIC 0x00001496 | ||
52 | #define VEN_LYNX 0x000019e5 | ||
53 | #define VEN_ICON 0x00001a9e | ||
54 | #define VEN_PRISMSOUND 0x00001198 | ||
55 | #define VEN_TERRATEC 0x00000aac | ||
56 | #define VEN_YAMAHA 0x0000a0de | ||
57 | #define VEN_FOCUSRITE 0x0000130e | ||
58 | #define VEN_MAUDIO1 0x00000d6c | ||
59 | #define VEN_MAUDIO2 0x000007f5 | ||
60 | |||
61 | #define MODEL_FOCUSRITE_SAFFIRE_BOTH 0x00000000 | ||
62 | #define MODEL_MAUDIO_AUDIOPHILE_BOTH 0x00010060 | ||
63 | #define MODEL_MAUDIO_FW1814 0x00010071 | ||
64 | #define MODEL_MAUDIO_PROJECTMIX 0x00010091 | ||
65 | |||
66 | static int | ||
67 | name_device(struct snd_bebob *bebob, unsigned int vendor_id) | ||
68 | { | ||
69 | struct fw_device *fw_dev = fw_parent_device(bebob->unit); | ||
70 | char vendor[24] = {0}; | ||
71 | char model[32] = {0}; | ||
72 | u32 hw_id; | ||
73 | u32 data[2] = {0}; | ||
74 | u32 revision; | ||
75 | int err; | ||
76 | |||
77 | /* get vendor name from root directory */ | ||
78 | err = fw_csr_string(fw_dev->config_rom + 5, CSR_VENDOR, | ||
79 | vendor, sizeof(vendor)); | ||
80 | if (err < 0) | ||
81 | goto end; | ||
82 | |||
83 | /* get model name from unit directory */ | ||
84 | err = fw_csr_string(bebob->unit->directory, CSR_MODEL, | ||
85 | model, sizeof(model)); | ||
86 | if (err < 0) | ||
87 | goto end; | ||
88 | |||
89 | /* get hardware id */ | ||
90 | err = snd_bebob_read_quad(bebob->unit, INFO_OFFSET_HW_MODEL_ID, | ||
91 | &hw_id); | ||
92 | if (err < 0) | ||
93 | goto end; | ||
94 | |||
95 | /* get hardware revision */ | ||
96 | err = snd_bebob_read_quad(bebob->unit, INFO_OFFSET_HW_MODEL_REVISION, | ||
97 | &revision); | ||
98 | if (err < 0) | ||
99 | goto end; | ||
100 | |||
101 | /* get GUID */ | ||
102 | err = snd_bebob_read_block(bebob->unit, INFO_OFFSET_GUID, | ||
103 | data, sizeof(data)); | ||
104 | if (err < 0) | ||
105 | goto end; | ||
106 | |||
107 | strcpy(bebob->card->driver, "BeBoB"); | ||
108 | strcpy(bebob->card->shortname, model); | ||
109 | strcpy(bebob->card->mixername, model); | ||
110 | snprintf(bebob->card->longname, sizeof(bebob->card->longname), | ||
111 | "%s %s (id:%d, rev:%d), GUID %08x%08x at %s, S%d", | ||
112 | vendor, model, hw_id, revision, | ||
113 | data[0], data[1], dev_name(&bebob->unit->device), | ||
114 | 100 << fw_dev->max_speed); | ||
115 | end: | ||
116 | return err; | ||
117 | } | ||
118 | |||
119 | static void | ||
120 | bebob_card_free(struct snd_card *card) | ||
121 | { | ||
122 | struct snd_bebob *bebob = card->private_data; | ||
123 | |||
124 | if (bebob->card_index >= 0) { | ||
125 | mutex_lock(&devices_mutex); | ||
126 | clear_bit(bebob->card_index, devices_used); | ||
127 | mutex_unlock(&devices_mutex); | ||
128 | } | ||
129 | |||
130 | mutex_destroy(&bebob->mutex); | ||
131 | } | ||
132 | |||
133 | static const struct snd_bebob_spec * | ||
134 | get_saffire_spec(struct fw_unit *unit) | ||
135 | { | ||
136 | char name[24] = {0}; | ||
137 | |||
138 | if (fw_csr_string(unit->directory, CSR_MODEL, name, sizeof(name)) < 0) | ||
139 | return NULL; | ||
140 | |||
141 | if (strcmp(name, "SaffireLE") == 0) | ||
142 | return &saffire_le_spec; | ||
143 | else | ||
144 | return &saffire_spec; | ||
145 | } | ||
146 | |||
147 | static bool | ||
148 | check_audiophile_booted(struct fw_unit *unit) | ||
149 | { | ||
150 | char name[24] = {0}; | ||
151 | |||
152 | if (fw_csr_string(unit->directory, CSR_MODEL, name, sizeof(name)) < 0) | ||
153 | return false; | ||
154 | |||
155 | return strncmp(name, "FW Audiophile Bootloader", 15) != 0; | ||
156 | } | ||
157 | |||
158 | static int | ||
159 | bebob_probe(struct fw_unit *unit, | ||
160 | const struct ieee1394_device_id *entry) | ||
161 | { | ||
162 | struct snd_card *card; | ||
163 | struct snd_bebob *bebob; | ||
164 | const struct snd_bebob_spec *spec; | ||
165 | unsigned int card_index; | ||
166 | int err; | ||
167 | |||
168 | mutex_lock(&devices_mutex); | ||
169 | |||
170 | for (card_index = 0; card_index < SNDRV_CARDS; card_index++) { | ||
171 | if (!test_bit(card_index, devices_used) && enable[card_index]) | ||
172 | break; | ||
173 | } | ||
174 | if (card_index >= SNDRV_CARDS) { | ||
175 | err = -ENOENT; | ||
176 | goto end; | ||
177 | } | ||
178 | |||
179 | if ((entry->vendor_id == VEN_FOCUSRITE) && | ||
180 | (entry->model_id == MODEL_FOCUSRITE_SAFFIRE_BOTH)) | ||
181 | spec = get_saffire_spec(unit); | ||
182 | else if ((entry->vendor_id == VEN_MAUDIO1) && | ||
183 | (entry->model_id == MODEL_MAUDIO_AUDIOPHILE_BOTH) && | ||
184 | !check_audiophile_booted(unit)) | ||
185 | spec = NULL; | ||
186 | else | ||
187 | spec = (const struct snd_bebob_spec *)entry->driver_data; | ||
188 | |||
189 | if (spec == NULL) { | ||
190 | if ((entry->vendor_id == VEN_MAUDIO1) || | ||
191 | (entry->vendor_id == VEN_MAUDIO2)) | ||
192 | err = snd_bebob_maudio_load_firmware(unit); | ||
193 | else | ||
194 | err = -ENOSYS; | ||
195 | goto end; | ||
196 | } | ||
197 | |||
198 | err = snd_card_new(&unit->device, index[card_index], id[card_index], | ||
199 | THIS_MODULE, sizeof(struct snd_bebob), &card); | ||
200 | if (err < 0) | ||
201 | goto end; | ||
202 | bebob = card->private_data; | ||
203 | bebob->card_index = card_index; | ||
204 | set_bit(card_index, devices_used); | ||
205 | card->private_free = bebob_card_free; | ||
206 | |||
207 | bebob->card = card; | ||
208 | bebob->unit = unit; | ||
209 | bebob->spec = spec; | ||
210 | mutex_init(&bebob->mutex); | ||
211 | spin_lock_init(&bebob->lock); | ||
212 | init_waitqueue_head(&bebob->hwdep_wait); | ||
213 | |||
214 | err = name_device(bebob, entry->vendor_id); | ||
215 | if (err < 0) | ||
216 | goto error; | ||
217 | |||
218 | if ((entry->vendor_id == VEN_MAUDIO1) && | ||
219 | (entry->model_id == MODEL_MAUDIO_FW1814)) | ||
220 | err = snd_bebob_maudio_special_discover(bebob, true); | ||
221 | else if ((entry->vendor_id == VEN_MAUDIO1) && | ||
222 | (entry->model_id == MODEL_MAUDIO_PROJECTMIX)) | ||
223 | err = snd_bebob_maudio_special_discover(bebob, false); | ||
224 | else | ||
225 | err = snd_bebob_stream_discover(bebob); | ||
226 | if (err < 0) | ||
227 | goto error; | ||
228 | |||
229 | snd_bebob_proc_init(bebob); | ||
230 | |||
231 | if ((bebob->midi_input_ports > 0) || | ||
232 | (bebob->midi_output_ports > 0)) { | ||
233 | err = snd_bebob_create_midi_devices(bebob); | ||
234 | if (err < 0) | ||
235 | goto error; | ||
236 | } | ||
237 | |||
238 | err = snd_bebob_create_pcm_devices(bebob); | ||
239 | if (err < 0) | ||
240 | goto error; | ||
241 | |||
242 | err = snd_bebob_create_hwdep_device(bebob); | ||
243 | if (err < 0) | ||
244 | goto error; | ||
245 | |||
246 | err = snd_bebob_stream_init_duplex(bebob); | ||
247 | if (err < 0) | ||
248 | goto error; | ||
249 | |||
250 | if (!bebob->maudio_special_quirk) { | ||
251 | err = snd_card_register(card); | ||
252 | if (err < 0) { | ||
253 | snd_bebob_stream_destroy_duplex(bebob); | ||
254 | goto error; | ||
255 | } | ||
256 | } else { | ||
257 | /* | ||
258 | * This is a workaround. This bus reset seems to have an effect | ||
259 | * to make devices correctly handling transactions. Without | ||
260 | * this, the devices have gap_count mismatch. This causes much | ||
261 | * failure of transaction. | ||
262 | * | ||
263 | * Just after registration, user-land application receive | ||
264 | * signals from dbus and starts I/Os. To avoid I/Os till the | ||
265 | * future bus reset, registration is done in next update(). | ||
266 | */ | ||
267 | bebob->deferred_registration = true; | ||
268 | fw_schedule_bus_reset(fw_parent_device(bebob->unit)->card, | ||
269 | false, true); | ||
270 | } | ||
271 | |||
272 | dev_set_drvdata(&unit->device, bebob); | ||
273 | end: | ||
274 | mutex_unlock(&devices_mutex); | ||
275 | return err; | ||
276 | error: | ||
277 | mutex_unlock(&devices_mutex); | ||
278 | snd_card_free(card); | ||
279 | return err; | ||
280 | } | ||
281 | |||
282 | static void | ||
283 | bebob_update(struct fw_unit *unit) | ||
284 | { | ||
285 | struct snd_bebob *bebob = dev_get_drvdata(&unit->device); | ||
286 | |||
287 | if (bebob == NULL) | ||
288 | return; | ||
289 | |||
290 | fcp_bus_reset(bebob->unit); | ||
291 | snd_bebob_stream_update_duplex(bebob); | ||
292 | |||
293 | if (bebob->deferred_registration) { | ||
294 | if (snd_card_register(bebob->card) < 0) { | ||
295 | snd_bebob_stream_destroy_duplex(bebob); | ||
296 | snd_card_free(bebob->card); | ||
297 | } | ||
298 | bebob->deferred_registration = false; | ||
299 | } | ||
300 | } | ||
301 | |||
302 | static void bebob_remove(struct fw_unit *unit) | ||
303 | { | ||
304 | struct snd_bebob *bebob = dev_get_drvdata(&unit->device); | ||
305 | |||
306 | if (bebob == NULL) | ||
307 | return; | ||
308 | |||
309 | kfree(bebob->maudio_special_quirk); | ||
310 | |||
311 | snd_bebob_stream_destroy_duplex(bebob); | ||
312 | snd_card_disconnect(bebob->card); | ||
313 | snd_card_free_when_closed(bebob->card); | ||
314 | } | ||
315 | |||
316 | static struct snd_bebob_rate_spec normal_rate_spec = { | ||
317 | .get = &snd_bebob_stream_get_rate, | ||
318 | .set = &snd_bebob_stream_set_rate | ||
319 | }; | ||
320 | static const struct snd_bebob_spec spec_normal = { | ||
321 | .clock = NULL, | ||
322 | .rate = &normal_rate_spec, | ||
323 | .meter = NULL | ||
324 | }; | ||
325 | |||
326 | static const struct ieee1394_device_id bebob_id_table[] = { | ||
327 | /* Edirol, FA-66 */ | ||
328 | SND_BEBOB_DEV_ENTRY(VEN_EDIROL, 0x00010049, &spec_normal), | ||
329 | /* Edirol, FA-101 */ | ||
330 | SND_BEBOB_DEV_ENTRY(VEN_EDIROL, 0x00010048, &spec_normal), | ||
331 | /* Presonus, FIREBOX */ | ||
332 | SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010000, &spec_normal), | ||
333 | /* PreSonus, FIREPOD/FP10 */ | ||
334 | SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010066, &spec_normal), | ||
335 | /* PreSonus, Inspire1394 */ | ||
336 | SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010001, &spec_normal), | ||
337 | /* BridgeCo, RDAudio1 */ | ||
338 | SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010048, &spec_normal), | ||
339 | /* BridgeCo, Audio5 */ | ||
340 | SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010049, &spec_normal), | ||
341 | /* Mackie, Onyx 1220/1620/1640 (Firewire I/O Card) */ | ||
342 | SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010065, &spec_normal), | ||
343 | /* Mackie, d.2 (Firewire Option) */ | ||
344 | SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010067, &spec_normal), | ||
345 | /* Stanton, ScratchAmp */ | ||
346 | SND_BEBOB_DEV_ENTRY(VEN_STANTON, 0x00000001, &spec_normal), | ||
347 | /* Tascam, IF-FW DM */ | ||
348 | SND_BEBOB_DEV_ENTRY(VEN_TASCAM, 0x00010067, &spec_normal), | ||
349 | /* Behringer, XENIX UFX 1204 */ | ||
350 | SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00001204, &spec_normal), | ||
351 | /* Behringer, XENIX UFX 1604 */ | ||
352 | SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00001604, &spec_normal), | ||
353 | /* Behringer, Digital Mixer X32 series (X-UF Card) */ | ||
354 | SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00000006, &spec_normal), | ||
355 | /* Apogee Electronics, Rosetta 200/400 (X-FireWire card) */ | ||
356 | /* Apogee Electronics, DA/AD/DD-16X (X-FireWire card) */ | ||
357 | SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x00010048, &spec_normal), | ||
358 | /* Apogee Electronics, Ensemble */ | ||
359 | SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x00001eee, &spec_normal), | ||
360 | /* ESI, Quatafire610 */ | ||
361 | SND_BEBOB_DEV_ENTRY(VEN_ESI, 0x00010064, &spec_normal), | ||
362 | /* AcousticReality, eARMasterOne */ | ||
363 | SND_BEBOB_DEV_ENTRY(VEN_ACOUSTIC, 0x00000002, &spec_normal), | ||
364 | /* CME, MatrixKFW */ | ||
365 | SND_BEBOB_DEV_ENTRY(VEN_CME, 0x00030000, &spec_normal), | ||
366 | /* Phonic, Helix Board 12 MkII */ | ||
367 | SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00050000, &spec_normal), | ||
368 | /* Phonic, Helix Board 18 MkII */ | ||
369 | SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00060000, &spec_normal), | ||
370 | /* Phonic, Helix Board 24 MkII */ | ||
371 | SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00070000, &spec_normal), | ||
372 | /* Phonic, Helix Board 12 Universal/18 Universal/24 Universal */ | ||
373 | SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00000000, &spec_normal), | ||
374 | /* Lynx, Aurora 8/16 (LT-FW) */ | ||
375 | SND_BEBOB_DEV_ENTRY(VEN_LYNX, 0x00000001, &spec_normal), | ||
376 | /* ICON, FireXon */ | ||
377 | SND_BEBOB_DEV_ENTRY(VEN_ICON, 0x00000001, &spec_normal), | ||
378 | /* PrismSound, Orpheus */ | ||
379 | SND_BEBOB_DEV_ENTRY(VEN_PRISMSOUND, 0x00010048, &spec_normal), | ||
380 | /* PrismSound, ADA-8XR */ | ||
381 | SND_BEBOB_DEV_ENTRY(VEN_PRISMSOUND, 0x0000ada8, &spec_normal), | ||
382 | /* TerraTec Electronic GmbH, PHASE 88 Rack FW */ | ||
383 | SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000003, &phase88_rack_spec), | ||
384 | /* TerraTec Electronic GmbH, PHASE 24 FW */ | ||
385 | SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000004, &phase24_series_spec), | ||
386 | /* TerraTec Electronic GmbH, Phase X24 FW */ | ||
387 | SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000007, &phase24_series_spec), | ||
388 | /* TerraTec Electronic GmbH, EWS MIC2/MIC8 */ | ||
389 | SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000005, &spec_normal), | ||
390 | /* Terratec Electronic GmbH, Aureon 7.1 Firewire */ | ||
391 | SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000002, &spec_normal), | ||
392 | /* Yamaha, GO44 */ | ||
393 | SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000b, &yamaha_go_spec), | ||
394 | /* YAMAHA, GO46 */ | ||
395 | SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000c, &yamaha_go_spec), | ||
396 | /* Focusrite, SaffirePro 26 I/O */ | ||
397 | SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, 0x00000003, &saffirepro_26_spec), | ||
398 | /* Focusrite, SaffirePro 10 I/O */ | ||
399 | SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, 0x00000006, &saffirepro_10_spec), | ||
400 | /* Focusrite, Saffire(no label and LE) */ | ||
401 | SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, MODEL_FOCUSRITE_SAFFIRE_BOTH, | ||
402 | &saffire_spec), | ||
403 | /* M-Audio, Firewire 410 */ | ||
404 | SND_BEBOB_DEV_ENTRY(VEN_MAUDIO2, 0x00010058, NULL), /* bootloader */ | ||
405 | SND_BEBOB_DEV_ENTRY(VEN_MAUDIO2, 0x00010046, &maudio_fw410_spec), | ||
406 | /* M-Audio, Firewire Audiophile */ | ||
407 | SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, MODEL_MAUDIO_AUDIOPHILE_BOTH, | ||
408 | &maudio_audiophile_spec), | ||
409 | /* M-Audio, Firewire Solo */ | ||
410 | SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, 0x00010062, &maudio_solo_spec), | ||
411 | /* M-Audio, Ozonic */ | ||
412 | SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, 0x0000000a, &maudio_ozonic_spec), | ||
413 | /* M-Audio NRV10 */ | ||
414 | SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, 0x00010081, &maudio_nrv10_spec), | ||
415 | /* M-Audio, ProFireLightbridge */ | ||
416 | SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, 0x000100a1, &spec_normal), | ||
417 | /* Firewire 1814 */ | ||
418 | SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, 0x00010070, NULL), /* bootloader */ | ||
419 | SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, MODEL_MAUDIO_FW1814, | ||
420 | &maudio_special_spec), | ||
421 | /* M-Audio ProjectMix */ | ||
422 | SND_BEBOB_DEV_ENTRY(VEN_MAUDIO1, MODEL_MAUDIO_PROJECTMIX, | ||
423 | &maudio_special_spec), | ||
424 | /* IDs are unknown but able to be supported */ | ||
425 | /* Apogee, Mini-ME Firewire */ | ||
426 | /* Apogee, Mini-DAC Firewire */ | ||
427 | /* Behringer, F-Control Audio 1616 */ | ||
428 | /* Behringer, F-Control Audio 610 */ | ||
429 | /* Cakawalk, Sonar Power Studio 66 */ | ||
430 | /* CME, UF400e */ | ||
431 | /* ESI, Quotafire XL */ | ||
432 | /* Infrasonic, DewX */ | ||
433 | /* Infrasonic, Windy6 */ | ||
434 | /* Mackie, Digital X Bus x.200 */ | ||
435 | /* Mackie, Digital X Bus x.400 */ | ||
436 | /* Phonic, HB 12 */ | ||
437 | /* Phonic, HB 24 */ | ||
438 | /* Phonic, HB 18 */ | ||
439 | /* Phonic, FireFly 202 */ | ||
440 | /* Phonic, FireFly 302 */ | ||
441 | /* Rolf Spuler, Firewire Guitar */ | ||
442 | {} | ||
443 | }; | ||
444 | MODULE_DEVICE_TABLE(ieee1394, bebob_id_table); | ||
445 | |||
446 | static struct fw_driver bebob_driver = { | ||
447 | .driver = { | ||
448 | .owner = THIS_MODULE, | ||
449 | .name = "snd-bebob", | ||
450 | .bus = &fw_bus_type, | ||
451 | }, | ||
452 | .probe = bebob_probe, | ||
453 | .update = bebob_update, | ||
454 | .remove = bebob_remove, | ||
455 | .id_table = bebob_id_table, | ||
456 | }; | ||
457 | |||
458 | static int __init | ||
459 | snd_bebob_init(void) | ||
460 | { | ||
461 | return driver_register(&bebob_driver.driver); | ||
462 | } | ||
463 | |||
464 | static void __exit | ||
465 | snd_bebob_exit(void) | ||
466 | { | ||
467 | driver_unregister(&bebob_driver.driver); | ||
468 | } | ||
469 | |||
470 | module_init(snd_bebob_init); | ||
471 | module_exit(snd_bebob_exit); | ||
diff --git a/sound/firewire/bebob/bebob.h b/sound/firewire/bebob/bebob.h new file mode 100644 index 000000000000..d1c93a1e0978 --- /dev/null +++ b/sound/firewire/bebob/bebob.h | |||
@@ -0,0 +1,257 @@ | |||
1 | /* | ||
2 | * bebob.h - a part of driver for BeBoB based devices | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | #ifndef SOUND_BEBOB_H_INCLUDED | ||
10 | #define SOUND_BEBOB_H_INCLUDED | ||
11 | |||
12 | #include <linux/compat.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/firewire.h> | ||
15 | #include <linux/firewire-constants.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/mod_devicetable.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | #include <sound/core.h> | ||
22 | #include <sound/initval.h> | ||
23 | #include <sound/info.h> | ||
24 | #include <sound/rawmidi.h> | ||
25 | #include <sound/pcm.h> | ||
26 | #include <sound/pcm_params.h> | ||
27 | #include <sound/firewire.h> | ||
28 | #include <sound/hwdep.h> | ||
29 | |||
30 | #include "../lib.h" | ||
31 | #include "../fcp.h" | ||
32 | #include "../packets-buffer.h" | ||
33 | #include "../iso-resources.h" | ||
34 | #include "../amdtp.h" | ||
35 | #include "../cmp.h" | ||
36 | |||
37 | /* basic register addresses on DM1000/DM1100/DM1500 */ | ||
38 | #define BEBOB_ADDR_REG_INFO 0xffffc8020000ULL | ||
39 | #define BEBOB_ADDR_REG_REQ 0xffffc8021000ULL | ||
40 | |||
41 | struct snd_bebob; | ||
42 | |||
43 | #define SND_BEBOB_STRM_FMT_ENTRIES 7 | ||
44 | struct snd_bebob_stream_formation { | ||
45 | unsigned int pcm; | ||
46 | unsigned int midi; | ||
47 | }; | ||
48 | /* this is a lookup table for index of stream formations */ | ||
49 | extern const unsigned int snd_bebob_rate_table[SND_BEBOB_STRM_FMT_ENTRIES]; | ||
50 | |||
51 | /* device specific operations */ | ||
52 | #define SND_BEBOB_CLOCK_INTERNAL "Internal" | ||
53 | struct snd_bebob_clock_spec { | ||
54 | unsigned int num; | ||
55 | char *const *labels; | ||
56 | int (*get)(struct snd_bebob *bebob, unsigned int *id); | ||
57 | }; | ||
58 | struct snd_bebob_rate_spec { | ||
59 | int (*get)(struct snd_bebob *bebob, unsigned int *rate); | ||
60 | int (*set)(struct snd_bebob *bebob, unsigned int rate); | ||
61 | }; | ||
62 | struct snd_bebob_meter_spec { | ||
63 | unsigned int num; | ||
64 | char *const *labels; | ||
65 | int (*get)(struct snd_bebob *bebob, u32 *target, unsigned int size); | ||
66 | }; | ||
67 | struct snd_bebob_spec { | ||
68 | struct snd_bebob_clock_spec *clock; | ||
69 | struct snd_bebob_rate_spec *rate; | ||
70 | struct snd_bebob_meter_spec *meter; | ||
71 | }; | ||
72 | |||
73 | struct snd_bebob { | ||
74 | struct snd_card *card; | ||
75 | struct fw_unit *unit; | ||
76 | int card_index; | ||
77 | |||
78 | struct mutex mutex; | ||
79 | spinlock_t lock; | ||
80 | |||
81 | const struct snd_bebob_spec *spec; | ||
82 | |||
83 | unsigned int midi_input_ports; | ||
84 | unsigned int midi_output_ports; | ||
85 | |||
86 | /* for bus reset quirk */ | ||
87 | struct completion bus_reset; | ||
88 | bool connected; | ||
89 | |||
90 | struct amdtp_stream *master; | ||
91 | struct amdtp_stream tx_stream; | ||
92 | struct amdtp_stream rx_stream; | ||
93 | struct cmp_connection out_conn; | ||
94 | struct cmp_connection in_conn; | ||
95 | atomic_t capture_substreams; | ||
96 | atomic_t playback_substreams; | ||
97 | |||
98 | struct snd_bebob_stream_formation | ||
99 | tx_stream_formations[SND_BEBOB_STRM_FMT_ENTRIES]; | ||
100 | struct snd_bebob_stream_formation | ||
101 | rx_stream_formations[SND_BEBOB_STRM_FMT_ENTRIES]; | ||
102 | |||
103 | int sync_input_plug; | ||
104 | |||
105 | /* for uapi */ | ||
106 | int dev_lock_count; | ||
107 | bool dev_lock_changed; | ||
108 | wait_queue_head_t hwdep_wait; | ||
109 | |||
110 | /* for M-Audio special devices */ | ||
111 | void *maudio_special_quirk; | ||
112 | bool deferred_registration; | ||
113 | }; | ||
114 | |||
115 | static inline int | ||
116 | snd_bebob_read_block(struct fw_unit *unit, u64 addr, void *buf, int size) | ||
117 | { | ||
118 | return snd_fw_transaction(unit, TCODE_READ_BLOCK_REQUEST, | ||
119 | BEBOB_ADDR_REG_INFO + addr, | ||
120 | buf, size, 0); | ||
121 | } | ||
122 | |||
123 | static inline int | ||
124 | snd_bebob_read_quad(struct fw_unit *unit, u64 addr, u32 *buf) | ||
125 | { | ||
126 | return snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST, | ||
127 | BEBOB_ADDR_REG_INFO + addr, | ||
128 | (void *)buf, sizeof(u32), 0); | ||
129 | } | ||
130 | |||
131 | /* AV/C Audio Subunit Specification 1.0 (Oct 2000, 1394TA) */ | ||
132 | int avc_audio_set_selector(struct fw_unit *unit, unsigned int subunit_id, | ||
133 | unsigned int fb_id, unsigned int num); | ||
134 | int avc_audio_get_selector(struct fw_unit *unit, unsigned int subunit_id, | ||
135 | unsigned int fb_id, unsigned int *num); | ||
136 | |||
137 | /* | ||
138 | * AVC command extensions, AV/C Unit and Subunit, Revision 17 | ||
139 | * (Nov 2003, BridgeCo) | ||
140 | */ | ||
141 | #define AVC_BRIDGECO_ADDR_BYTES 6 | ||
142 | enum avc_bridgeco_plug_dir { | ||
143 | AVC_BRIDGECO_PLUG_DIR_IN = 0x00, | ||
144 | AVC_BRIDGECO_PLUG_DIR_OUT = 0x01 | ||
145 | }; | ||
146 | enum avc_bridgeco_plug_mode { | ||
147 | AVC_BRIDGECO_PLUG_MODE_UNIT = 0x00, | ||
148 | AVC_BRIDGECO_PLUG_MODE_SUBUNIT = 0x01, | ||
149 | AVC_BRIDGECO_PLUG_MODE_FUNCTION_BLOCK = 0x02 | ||
150 | }; | ||
151 | enum avc_bridgeco_plug_unit { | ||
152 | AVC_BRIDGECO_PLUG_UNIT_ISOC = 0x00, | ||
153 | AVC_BRIDGECO_PLUG_UNIT_EXT = 0x01, | ||
154 | AVC_BRIDGECO_PLUG_UNIT_ASYNC = 0x02 | ||
155 | }; | ||
156 | enum avc_bridgeco_plug_type { | ||
157 | AVC_BRIDGECO_PLUG_TYPE_ISOC = 0x00, | ||
158 | AVC_BRIDGECO_PLUG_TYPE_ASYNC = 0x01, | ||
159 | AVC_BRIDGECO_PLUG_TYPE_MIDI = 0x02, | ||
160 | AVC_BRIDGECO_PLUG_TYPE_SYNC = 0x03, | ||
161 | AVC_BRIDGECO_PLUG_TYPE_ANA = 0x04, | ||
162 | AVC_BRIDGECO_PLUG_TYPE_DIG = 0x05 | ||
163 | }; | ||
164 | static inline void | ||
165 | avc_bridgeco_fill_unit_addr(u8 buf[AVC_BRIDGECO_ADDR_BYTES], | ||
166 | enum avc_bridgeco_plug_dir dir, | ||
167 | enum avc_bridgeco_plug_unit unit, | ||
168 | unsigned int pid) | ||
169 | { | ||
170 | buf[0] = 0xff; /* Unit */ | ||
171 | buf[1] = dir; | ||
172 | buf[2] = AVC_BRIDGECO_PLUG_MODE_UNIT; | ||
173 | buf[3] = unit; | ||
174 | buf[4] = 0xff & pid; | ||
175 | buf[5] = 0xff; /* reserved */ | ||
176 | } | ||
177 | static inline void | ||
178 | avc_bridgeco_fill_msu_addr(u8 buf[AVC_BRIDGECO_ADDR_BYTES], | ||
179 | enum avc_bridgeco_plug_dir dir, | ||
180 | unsigned int pid) | ||
181 | { | ||
182 | buf[0] = 0x60; /* Music subunit */ | ||
183 | buf[1] = dir; | ||
184 | buf[2] = AVC_BRIDGECO_PLUG_MODE_SUBUNIT; | ||
185 | buf[3] = 0xff & pid; | ||
186 | buf[4] = 0xff; /* reserved */ | ||
187 | buf[5] = 0xff; /* reserved */ | ||
188 | } | ||
189 | int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit, | ||
190 | u8 addr[AVC_BRIDGECO_ADDR_BYTES], | ||
191 | u8 *buf, unsigned int len); | ||
192 | int avc_bridgeco_get_plug_type(struct fw_unit *unit, | ||
193 | u8 addr[AVC_BRIDGECO_ADDR_BYTES], | ||
194 | enum avc_bridgeco_plug_type *type); | ||
195 | int avc_bridgeco_get_plug_section_type(struct fw_unit *unit, | ||
196 | u8 addr[AVC_BRIDGECO_ADDR_BYTES], | ||
197 | unsigned int id, u8 *type); | ||
198 | int avc_bridgeco_get_plug_input(struct fw_unit *unit, | ||
199 | u8 addr[AVC_BRIDGECO_ADDR_BYTES], | ||
200 | u8 input[7]); | ||
201 | int avc_bridgeco_get_plug_strm_fmt(struct fw_unit *unit, | ||
202 | u8 addr[AVC_BRIDGECO_ADDR_BYTES], u8 *buf, | ||
203 | unsigned int *len, unsigned int eid); | ||
204 | |||
205 | /* for AMDTP streaming */ | ||
206 | int snd_bebob_stream_get_rate(struct snd_bebob *bebob, unsigned int *rate); | ||
207 | int snd_bebob_stream_set_rate(struct snd_bebob *bebob, unsigned int rate); | ||
208 | int snd_bebob_stream_check_internal_clock(struct snd_bebob *bebob, | ||
209 | bool *internal); | ||
210 | int snd_bebob_stream_discover(struct snd_bebob *bebob); | ||
211 | int snd_bebob_stream_map(struct snd_bebob *bebob, | ||
212 | struct amdtp_stream *stream); | ||
213 | int snd_bebob_stream_init_duplex(struct snd_bebob *bebob); | ||
214 | int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate); | ||
215 | void snd_bebob_stream_stop_duplex(struct snd_bebob *bebob); | ||
216 | void snd_bebob_stream_update_duplex(struct snd_bebob *bebob); | ||
217 | void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob); | ||
218 | |||
219 | void snd_bebob_stream_lock_changed(struct snd_bebob *bebob); | ||
220 | int snd_bebob_stream_lock_try(struct snd_bebob *bebob); | ||
221 | void snd_bebob_stream_lock_release(struct snd_bebob *bebob); | ||
222 | |||
223 | void snd_bebob_proc_init(struct snd_bebob *bebob); | ||
224 | |||
225 | int snd_bebob_create_midi_devices(struct snd_bebob *bebob); | ||
226 | |||
227 | int snd_bebob_create_pcm_devices(struct snd_bebob *bebob); | ||
228 | |||
229 | int snd_bebob_create_hwdep_device(struct snd_bebob *bebob); | ||
230 | |||
231 | /* model specific operations */ | ||
232 | extern struct snd_bebob_spec phase88_rack_spec; | ||
233 | extern struct snd_bebob_spec phase24_series_spec; | ||
234 | extern struct snd_bebob_spec yamaha_go_spec; | ||
235 | extern struct snd_bebob_spec saffirepro_26_spec; | ||
236 | extern struct snd_bebob_spec saffirepro_10_spec; | ||
237 | extern struct snd_bebob_spec saffire_le_spec; | ||
238 | extern struct snd_bebob_spec saffire_spec; | ||
239 | extern struct snd_bebob_spec maudio_fw410_spec; | ||
240 | extern struct snd_bebob_spec maudio_audiophile_spec; | ||
241 | extern struct snd_bebob_spec maudio_solo_spec; | ||
242 | extern struct snd_bebob_spec maudio_ozonic_spec; | ||
243 | extern struct snd_bebob_spec maudio_nrv10_spec; | ||
244 | extern struct snd_bebob_spec maudio_special_spec; | ||
245 | int snd_bebob_maudio_special_discover(struct snd_bebob *bebob, bool is1814); | ||
246 | int snd_bebob_maudio_load_firmware(struct fw_unit *unit); | ||
247 | |||
248 | #define SND_BEBOB_DEV_ENTRY(vendor, model, data) \ | ||
249 | { \ | ||
250 | .match_flags = IEEE1394_MATCH_VENDOR_ID | \ | ||
251 | IEEE1394_MATCH_MODEL_ID, \ | ||
252 | .vendor_id = vendor, \ | ||
253 | .model_id = model, \ | ||
254 | .driver_data = (kernel_ulong_t)data \ | ||
255 | } | ||
256 | |||
257 | #endif | ||
diff --git a/sound/firewire/bebob/bebob_command.c b/sound/firewire/bebob/bebob_command.c new file mode 100644 index 000000000000..9402cc15dbc1 --- /dev/null +++ b/sound/firewire/bebob/bebob_command.c | |||
@@ -0,0 +1,282 @@ | |||
1 | /* | ||
2 | * bebob_command.c - driver for BeBoB based devices | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | #include "./bebob.h" | ||
10 | |||
11 | int avc_audio_set_selector(struct fw_unit *unit, unsigned int subunit_id, | ||
12 | unsigned int fb_id, unsigned int num) | ||
13 | { | ||
14 | u8 *buf; | ||
15 | int err; | ||
16 | |||
17 | buf = kzalloc(12, GFP_KERNEL); | ||
18 | if (buf == NULL) | ||
19 | return -ENOMEM; | ||
20 | |||
21 | buf[0] = 0x00; /* AV/C CONTROL */ | ||
22 | buf[1] = 0x08 | (0x07 & subunit_id); /* AUDIO SUBUNIT ID */ | ||
23 | buf[2] = 0xb8; /* FUNCTION BLOCK */ | ||
24 | buf[3] = 0x80; /* type is 'selector'*/ | ||
25 | buf[4] = 0xff & fb_id; /* function block id */ | ||
26 | buf[5] = 0x10; /* control attribute is CURRENT */ | ||
27 | buf[6] = 0x02; /* selector length is 2 */ | ||
28 | buf[7] = 0xff & num; /* input function block plug number */ | ||
29 | buf[8] = 0x01; /* control selector is SELECTOR_CONTROL */ | ||
30 | |||
31 | err = fcp_avc_transaction(unit, buf, 12, buf, 12, | ||
32 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | ||
33 | BIT(6) | BIT(7) | BIT(8)); | ||
34 | if (err > 0 && err < 9) | ||
35 | err = -EIO; | ||
36 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | ||
37 | err = -ENOSYS; | ||
38 | else if (buf[0] == 0x0a) /* REJECTED */ | ||
39 | err = -EINVAL; | ||
40 | else if (err > 0) | ||
41 | err = 0; | ||
42 | |||
43 | kfree(buf); | ||
44 | return err; | ||
45 | } | ||
46 | |||
47 | int avc_audio_get_selector(struct fw_unit *unit, unsigned int subunit_id, | ||
48 | unsigned int fb_id, unsigned int *num) | ||
49 | { | ||
50 | u8 *buf; | ||
51 | int err; | ||
52 | |||
53 | buf = kzalloc(12, GFP_KERNEL); | ||
54 | if (buf == NULL) | ||
55 | return -ENOMEM; | ||
56 | |||
57 | buf[0] = 0x01; /* AV/C STATUS */ | ||
58 | buf[1] = 0x08 | (0x07 & subunit_id); /* AUDIO SUBUNIT ID */ | ||
59 | buf[2] = 0xb8; /* FUNCTION BLOCK */ | ||
60 | buf[3] = 0x80; /* type is 'selector'*/ | ||
61 | buf[4] = 0xff & fb_id; /* function block id */ | ||
62 | buf[5] = 0x10; /* control attribute is CURRENT */ | ||
63 | buf[6] = 0x02; /* selector length is 2 */ | ||
64 | buf[7] = 0xff; /* input function block plug number */ | ||
65 | buf[8] = 0x01; /* control selector is SELECTOR_CONTROL */ | ||
66 | |||
67 | err = fcp_avc_transaction(unit, buf, 12, buf, 12, | ||
68 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | ||
69 | BIT(6) | BIT(8)); | ||
70 | if (err > 0 && err < 9) | ||
71 | err = -EIO; | ||
72 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | ||
73 | err = -ENOSYS; | ||
74 | else if (buf[0] == 0x0a) /* REJECTED */ | ||
75 | err = -EINVAL; | ||
76 | else if (buf[0] == 0x0b) /* IN TRANSITION */ | ||
77 | err = -EAGAIN; | ||
78 | if (err < 0) | ||
79 | goto end; | ||
80 | |||
81 | *num = buf[7]; | ||
82 | err = 0; | ||
83 | end: | ||
84 | kfree(buf); | ||
85 | return err; | ||
86 | } | ||
87 | |||
88 | static inline void | ||
89 | avc_bridgeco_fill_extension_addr(u8 *buf, u8 *addr) | ||
90 | { | ||
91 | buf[1] = addr[0]; | ||
92 | memcpy(buf + 4, addr + 1, 5); | ||
93 | } | ||
94 | |||
95 | static inline void | ||
96 | avc_bridgeco_fill_plug_info_extension_command(u8 *buf, u8 *addr, | ||
97 | unsigned int itype) | ||
98 | { | ||
99 | buf[0] = 0x01; /* AV/C STATUS */ | ||
100 | buf[2] = 0x02; /* AV/C GENERAL PLUG INFO */ | ||
101 | buf[3] = 0xc0; /* BridgeCo extension */ | ||
102 | avc_bridgeco_fill_extension_addr(buf, addr); | ||
103 | buf[9] = itype; /* info type */ | ||
104 | } | ||
105 | |||
106 | int avc_bridgeco_get_plug_type(struct fw_unit *unit, | ||
107 | u8 addr[AVC_BRIDGECO_ADDR_BYTES], | ||
108 | enum avc_bridgeco_plug_type *type) | ||
109 | { | ||
110 | u8 *buf; | ||
111 | int err; | ||
112 | |||
113 | buf = kzalloc(12, GFP_KERNEL); | ||
114 | if (buf == NULL) | ||
115 | return -ENOMEM; | ||
116 | |||
117 | /* Info type is 'plug type'. */ | ||
118 | avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x00); | ||
119 | |||
120 | err = fcp_avc_transaction(unit, buf, 12, buf, 12, | ||
121 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | ||
122 | BIT(6) | BIT(7) | BIT(9)); | ||
123 | if ((err >= 0) && (err < 8)) | ||
124 | err = -EIO; | ||
125 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | ||
126 | err = -ENOSYS; | ||
127 | else if (buf[0] == 0x0a) /* REJECTED */ | ||
128 | err = -EINVAL; | ||
129 | else if (buf[0] == 0x0b) /* IN TRANSITION */ | ||
130 | err = -EAGAIN; | ||
131 | if (err < 0) | ||
132 | goto end; | ||
133 | |||
134 | *type = buf[10]; | ||
135 | err = 0; | ||
136 | end: | ||
137 | kfree(buf); | ||
138 | return err; | ||
139 | } | ||
140 | |||
141 | int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit, | ||
142 | u8 addr[AVC_BRIDGECO_ADDR_BYTES], | ||
143 | u8 *buf, unsigned int len) | ||
144 | { | ||
145 | int err; | ||
146 | |||
147 | /* Info type is 'channel position'. */ | ||
148 | avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x03); | ||
149 | |||
150 | err = fcp_avc_transaction(unit, buf, 12, buf, 256, | ||
151 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | | ||
152 | BIT(5) | BIT(6) | BIT(7) | BIT(9)); | ||
153 | if ((err >= 0) && (err < 8)) | ||
154 | err = -EIO; | ||
155 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | ||
156 | err = -ENOSYS; | ||
157 | else if (buf[0] == 0x0a) /* REJECTED */ | ||
158 | err = -EINVAL; | ||
159 | else if (buf[0] == 0x0b) /* IN TRANSITION */ | ||
160 | err = -EAGAIN; | ||
161 | if (err < 0) | ||
162 | goto end; | ||
163 | |||
164 | /* Pick up specific data. */ | ||
165 | memmove(buf, buf + 10, err - 10); | ||
166 | err = 0; | ||
167 | end: | ||
168 | return err; | ||
169 | } | ||
170 | |||
171 | int avc_bridgeco_get_plug_section_type(struct fw_unit *unit, | ||
172 | u8 addr[AVC_BRIDGECO_ADDR_BYTES], | ||
173 | unsigned int id, u8 *type) | ||
174 | { | ||
175 | u8 *buf; | ||
176 | int err; | ||
177 | |||
178 | /* section info includes charactors but this module don't need it */ | ||
179 | buf = kzalloc(12, GFP_KERNEL); | ||
180 | if (buf == NULL) | ||
181 | return -ENOMEM; | ||
182 | |||
183 | /* Info type is 'section info'. */ | ||
184 | avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x07); | ||
185 | buf[10] = 0xff & ++id; /* section id */ | ||
186 | |||
187 | err = fcp_avc_transaction(unit, buf, 12, buf, 12, | ||
188 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | ||
189 | BIT(6) | BIT(7) | BIT(9) | BIT(10)); | ||
190 | if ((err >= 0) && (err < 8)) | ||
191 | err = -EIO; | ||
192 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | ||
193 | err = -ENOSYS; | ||
194 | else if (buf[0] == 0x0a) /* REJECTED */ | ||
195 | err = -EINVAL; | ||
196 | else if (buf[0] == 0x0b) /* IN TRANSITION */ | ||
197 | err = -EAGAIN; | ||
198 | if (err < 0) | ||
199 | goto end; | ||
200 | |||
201 | *type = buf[11]; | ||
202 | err = 0; | ||
203 | end: | ||
204 | kfree(buf); | ||
205 | return err; | ||
206 | } | ||
207 | |||
208 | int avc_bridgeco_get_plug_input(struct fw_unit *unit, | ||
209 | u8 addr[AVC_BRIDGECO_ADDR_BYTES], u8 input[7]) | ||
210 | { | ||
211 | int err; | ||
212 | u8 *buf; | ||
213 | |||
214 | buf = kzalloc(18, GFP_KERNEL); | ||
215 | if (buf == NULL) | ||
216 | return -ENOMEM; | ||
217 | |||
218 | /* Info type is 'plug input'. */ | ||
219 | avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x05); | ||
220 | |||
221 | err = fcp_avc_transaction(unit, buf, 16, buf, 16, | ||
222 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | ||
223 | BIT(6) | BIT(7)); | ||
224 | if ((err >= 0) && (err < 8)) | ||
225 | err = -EIO; | ||
226 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | ||
227 | err = -ENOSYS; | ||
228 | else if (buf[0] == 0x0a) /* REJECTED */ | ||
229 | err = -EINVAL; | ||
230 | else if (buf[0] == 0x0b) /* IN TRANSITION */ | ||
231 | err = -EAGAIN; | ||
232 | if (err < 0) | ||
233 | goto end; | ||
234 | |||
235 | memcpy(input, buf + 10, 5); | ||
236 | err = 0; | ||
237 | end: | ||
238 | kfree(buf); | ||
239 | return err; | ||
240 | } | ||
241 | |||
242 | int avc_bridgeco_get_plug_strm_fmt(struct fw_unit *unit, | ||
243 | u8 addr[AVC_BRIDGECO_ADDR_BYTES], u8 *buf, | ||
244 | unsigned int *len, unsigned int eid) | ||
245 | { | ||
246 | int err; | ||
247 | |||
248 | /* check given buffer */ | ||
249 | if ((buf == NULL) || (*len < 12)) { | ||
250 | err = -EINVAL; | ||
251 | goto end; | ||
252 | } | ||
253 | |||
254 | buf[0] = 0x01; /* AV/C STATUS */ | ||
255 | buf[2] = 0x2f; /* AV/C STREAM FORMAT SUPPORT */ | ||
256 | buf[3] = 0xc1; /* Bridgeco extension - List Request */ | ||
257 | avc_bridgeco_fill_extension_addr(buf, addr); | ||
258 | buf[10] = 0xff & eid; /* Entry ID */ | ||
259 | |||
260 | err = fcp_avc_transaction(unit, buf, 12, buf, *len, | ||
261 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | ||
262 | BIT(6) | BIT(7) | BIT(10)); | ||
263 | if ((err >= 0) && (err < 12)) | ||
264 | err = -EIO; | ||
265 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | ||
266 | err = -ENOSYS; | ||
267 | else if (buf[0] == 0x0a) /* REJECTED */ | ||
268 | err = -EINVAL; | ||
269 | else if (buf[0] == 0x0b) /* IN TRANSITION */ | ||
270 | err = -EAGAIN; | ||
271 | else if (buf[10] != eid) | ||
272 | err = -EIO; | ||
273 | if (err < 0) | ||
274 | goto end; | ||
275 | |||
276 | /* Pick up 'stream format info'. */ | ||
277 | memmove(buf, buf + 11, err - 11); | ||
278 | *len = err - 11; | ||
279 | err = 0; | ||
280 | end: | ||
281 | return err; | ||
282 | } | ||
diff --git a/sound/firewire/bebob/bebob_focusrite.c b/sound/firewire/bebob/bebob_focusrite.c new file mode 100644 index 000000000000..45a0eed6d5b1 --- /dev/null +++ b/sound/firewire/bebob/bebob_focusrite.c | |||
@@ -0,0 +1,279 @@ | |||
1 | /* | ||
2 | * bebob_focusrite.c - a part of driver for BeBoB based devices | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | #include "./bebob.h" | ||
10 | |||
11 | #define ANA_IN "Analog In" | ||
12 | #define DIG_IN "Digital In" | ||
13 | #define ANA_OUT "Analog Out" | ||
14 | #define DIG_OUT "Digital Out" | ||
15 | #define STM_IN "Stream In" | ||
16 | |||
17 | #define SAFFIRE_ADDRESS_BASE 0x000100000000ULL | ||
18 | |||
19 | #define SAFFIRE_OFFSET_CLOCK_SOURCE 0x00f8 | ||
20 | #define SAFFIREPRO_OFFSET_CLOCK_SOURCE 0x0174 | ||
21 | |||
22 | /* whether sync to external device or not */ | ||
23 | #define SAFFIRE_OFFSET_CLOCK_SYNC_EXT 0x013c | ||
24 | #define SAFFIRE_LE_OFFSET_CLOCK_SYNC_EXT 0x0432 | ||
25 | #define SAFFIREPRO_OFFSET_CLOCK_SYNC_EXT 0x0164 | ||
26 | |||
27 | #define SAFFIRE_CLOCK_SOURCE_INTERNAL 0 | ||
28 | #define SAFFIRE_CLOCK_SOURCE_SPDIF 1 | ||
29 | |||
30 | /* '1' is absent, why... */ | ||
31 | #define SAFFIREPRO_CLOCK_SOURCE_INTERNAL 0 | ||
32 | #define SAFFIREPRO_CLOCK_SOURCE_SPDIF 2 | ||
33 | #define SAFFIREPRO_CLOCK_SOURCE_ADAT1 3 | ||
34 | #define SAFFIREPRO_CLOCK_SOURCE_ADAT2 4 | ||
35 | #define SAFFIREPRO_CLOCK_SOURCE_WORDCLOCK 5 | ||
36 | |||
37 | /* S/PDIF, ADAT1, ADAT2 is enabled or not. three quadlets */ | ||
38 | #define SAFFIREPRO_ENABLE_DIG_IFACES 0x01a4 | ||
39 | |||
40 | /* saffirepro has its own parameter for sampling frequency */ | ||
41 | #define SAFFIREPRO_RATE_NOREBOOT 0x01cc | ||
42 | /* index is the value for this register */ | ||
43 | static const unsigned int rates[] = { | ||
44 | [0] = 0, | ||
45 | [1] = 44100, | ||
46 | [2] = 48000, | ||
47 | [3] = 88200, | ||
48 | [4] = 96000, | ||
49 | [5] = 176400, | ||
50 | [6] = 192000 | ||
51 | }; | ||
52 | |||
53 | /* saffire(no label)/saffire LE has metering */ | ||
54 | #define SAFFIRE_OFFSET_METER 0x0100 | ||
55 | #define SAFFIRE_LE_OFFSET_METER 0x0168 | ||
56 | |||
57 | static inline int | ||
58 | saffire_read_block(struct snd_bebob *bebob, u64 offset, | ||
59 | u32 *buf, unsigned int size) | ||
60 | { | ||
61 | unsigned int i; | ||
62 | int err; | ||
63 | __be32 *tmp = (__be32 *)buf; | ||
64 | |||
65 | err = snd_fw_transaction(bebob->unit, TCODE_READ_BLOCK_REQUEST, | ||
66 | SAFFIRE_ADDRESS_BASE + offset, | ||
67 | tmp, size, 0); | ||
68 | if (err < 0) | ||
69 | goto end; | ||
70 | |||
71 | for (i = 0; i < size / sizeof(u32); i++) | ||
72 | buf[i] = be32_to_cpu(tmp[i]); | ||
73 | end: | ||
74 | return err; | ||
75 | } | ||
76 | |||
77 | static inline int | ||
78 | saffire_read_quad(struct snd_bebob *bebob, u64 offset, u32 *value) | ||
79 | { | ||
80 | int err; | ||
81 | __be32 tmp; | ||
82 | |||
83 | err = snd_fw_transaction(bebob->unit, TCODE_READ_QUADLET_REQUEST, | ||
84 | SAFFIRE_ADDRESS_BASE + offset, | ||
85 | &tmp, sizeof(__be32), 0); | ||
86 | if (err < 0) | ||
87 | goto end; | ||
88 | |||
89 | *value = be32_to_cpu(tmp); | ||
90 | end: | ||
91 | return err; | ||
92 | } | ||
93 | |||
94 | static inline int | ||
95 | saffire_write_quad(struct snd_bebob *bebob, u64 offset, u32 value) | ||
96 | { | ||
97 | __be32 data = cpu_to_be32(value); | ||
98 | |||
99 | return snd_fw_transaction(bebob->unit, TCODE_WRITE_QUADLET_REQUEST, | ||
100 | SAFFIRE_ADDRESS_BASE + offset, | ||
101 | &data, sizeof(__be32), 0); | ||
102 | } | ||
103 | |||
104 | static char *const saffirepro_26_clk_src_labels[] = { | ||
105 | SND_BEBOB_CLOCK_INTERNAL, "S/PDIF", "ADAT1", "ADAT2", "Word Clock" | ||
106 | }; | ||
107 | |||
108 | static char *const saffirepro_10_clk_src_labels[] = { | ||
109 | SND_BEBOB_CLOCK_INTERNAL, "S/PDIF", "Word Clock" | ||
110 | }; | ||
111 | static int | ||
112 | saffirepro_both_clk_freq_get(struct snd_bebob *bebob, unsigned int *rate) | ||
113 | { | ||
114 | u32 id; | ||
115 | int err; | ||
116 | |||
117 | err = saffire_read_quad(bebob, SAFFIREPRO_RATE_NOREBOOT, &id); | ||
118 | if (err < 0) | ||
119 | goto end; | ||
120 | if (id >= ARRAY_SIZE(rates)) | ||
121 | err = -EIO; | ||
122 | else | ||
123 | *rate = rates[id]; | ||
124 | end: | ||
125 | return err; | ||
126 | } | ||
127 | static int | ||
128 | saffirepro_both_clk_freq_set(struct snd_bebob *bebob, unsigned int rate) | ||
129 | { | ||
130 | u32 id; | ||
131 | |||
132 | for (id = 0; id < ARRAY_SIZE(rates); id++) { | ||
133 | if (rates[id] == rate) | ||
134 | break; | ||
135 | } | ||
136 | if (id == ARRAY_SIZE(rates)) | ||
137 | return -EINVAL; | ||
138 | |||
139 | return saffire_write_quad(bebob, SAFFIREPRO_RATE_NOREBOOT, id); | ||
140 | } | ||
141 | static int | ||
142 | saffirepro_both_clk_src_get(struct snd_bebob *bebob, unsigned int *id) | ||
143 | { | ||
144 | int err; | ||
145 | u32 value; | ||
146 | |||
147 | err = saffire_read_quad(bebob, SAFFIREPRO_OFFSET_CLOCK_SOURCE, &value); | ||
148 | if (err < 0) | ||
149 | goto end; | ||
150 | |||
151 | if (bebob->spec->clock->labels == saffirepro_10_clk_src_labels) { | ||
152 | if (value == SAFFIREPRO_CLOCK_SOURCE_WORDCLOCK) | ||
153 | *id = 2; | ||
154 | else if (value == SAFFIREPRO_CLOCK_SOURCE_SPDIF) | ||
155 | *id = 1; | ||
156 | } else if (value > 1) { | ||
157 | *id = value - 1; | ||
158 | } | ||
159 | end: | ||
160 | return err; | ||
161 | } | ||
162 | |||
163 | struct snd_bebob_spec saffire_le_spec; | ||
164 | static char *const saffire_both_clk_src_labels[] = { | ||
165 | SND_BEBOB_CLOCK_INTERNAL, "S/PDIF" | ||
166 | }; | ||
167 | static int | ||
168 | saffire_both_clk_src_get(struct snd_bebob *bebob, unsigned int *id) | ||
169 | { | ||
170 | int err; | ||
171 | u32 value; | ||
172 | |||
173 | err = saffire_read_quad(bebob, SAFFIRE_OFFSET_CLOCK_SOURCE, &value); | ||
174 | if (err >= 0) | ||
175 | *id = 0xff & value; | ||
176 | |||
177 | return err; | ||
178 | }; | ||
179 | static char *const saffire_le_meter_labels[] = { | ||
180 | ANA_IN, ANA_IN, DIG_IN, | ||
181 | ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT, | ||
182 | STM_IN, STM_IN | ||
183 | }; | ||
184 | static char *const saffire_meter_labels[] = { | ||
185 | ANA_IN, ANA_IN, | ||
186 | STM_IN, STM_IN, STM_IN, STM_IN, STM_IN, | ||
187 | }; | ||
188 | static int | ||
189 | saffire_meter_get(struct snd_bebob *bebob, u32 *buf, unsigned int size) | ||
190 | { | ||
191 | struct snd_bebob_meter_spec *spec = bebob->spec->meter; | ||
192 | unsigned int channels; | ||
193 | u64 offset; | ||
194 | int err; | ||
195 | |||
196 | if (spec->labels == saffire_le_meter_labels) | ||
197 | offset = SAFFIRE_LE_OFFSET_METER; | ||
198 | else | ||
199 | offset = SAFFIRE_OFFSET_METER; | ||
200 | |||
201 | channels = spec->num * 2; | ||
202 | if (size < channels * sizeof(u32)) | ||
203 | return -EIO; | ||
204 | |||
205 | err = saffire_read_block(bebob, offset, buf, size); | ||
206 | if (err >= 0 && spec->labels == saffire_le_meter_labels) { | ||
207 | swap(buf[1], buf[3]); | ||
208 | swap(buf[2], buf[3]); | ||
209 | swap(buf[3], buf[4]); | ||
210 | |||
211 | swap(buf[7], buf[10]); | ||
212 | swap(buf[8], buf[10]); | ||
213 | swap(buf[9], buf[11]); | ||
214 | swap(buf[11], buf[12]); | ||
215 | |||
216 | swap(buf[15], buf[16]); | ||
217 | } | ||
218 | |||
219 | return err; | ||
220 | } | ||
221 | |||
222 | static struct snd_bebob_rate_spec saffirepro_both_rate_spec = { | ||
223 | .get = &saffirepro_both_clk_freq_get, | ||
224 | .set = &saffirepro_both_clk_freq_set, | ||
225 | }; | ||
226 | /* Saffire Pro 26 I/O */ | ||
227 | static struct snd_bebob_clock_spec saffirepro_26_clk_spec = { | ||
228 | .num = ARRAY_SIZE(saffirepro_26_clk_src_labels), | ||
229 | .labels = saffirepro_26_clk_src_labels, | ||
230 | .get = &saffirepro_both_clk_src_get, | ||
231 | }; | ||
232 | struct snd_bebob_spec saffirepro_26_spec = { | ||
233 | .clock = &saffirepro_26_clk_spec, | ||
234 | .rate = &saffirepro_both_rate_spec, | ||
235 | .meter = NULL | ||
236 | }; | ||
237 | /* Saffire Pro 10 I/O */ | ||
238 | static struct snd_bebob_clock_spec saffirepro_10_clk_spec = { | ||
239 | .num = ARRAY_SIZE(saffirepro_10_clk_src_labels), | ||
240 | .labels = saffirepro_10_clk_src_labels, | ||
241 | .get = &saffirepro_both_clk_src_get, | ||
242 | }; | ||
243 | struct snd_bebob_spec saffirepro_10_spec = { | ||
244 | .clock = &saffirepro_10_clk_spec, | ||
245 | .rate = &saffirepro_both_rate_spec, | ||
246 | .meter = NULL | ||
247 | }; | ||
248 | |||
249 | static struct snd_bebob_rate_spec saffire_both_rate_spec = { | ||
250 | .get = &snd_bebob_stream_get_rate, | ||
251 | .set = &snd_bebob_stream_set_rate, | ||
252 | }; | ||
253 | static struct snd_bebob_clock_spec saffire_both_clk_spec = { | ||
254 | .num = ARRAY_SIZE(saffire_both_clk_src_labels), | ||
255 | .labels = saffire_both_clk_src_labels, | ||
256 | .get = &saffire_both_clk_src_get, | ||
257 | }; | ||
258 | /* Saffire LE */ | ||
259 | static struct snd_bebob_meter_spec saffire_le_meter_spec = { | ||
260 | .num = ARRAY_SIZE(saffire_le_meter_labels), | ||
261 | .labels = saffire_le_meter_labels, | ||
262 | .get = &saffire_meter_get, | ||
263 | }; | ||
264 | struct snd_bebob_spec saffire_le_spec = { | ||
265 | .clock = &saffire_both_clk_spec, | ||
266 | .rate = &saffire_both_rate_spec, | ||
267 | .meter = &saffire_le_meter_spec | ||
268 | }; | ||
269 | /* Saffire */ | ||
270 | static struct snd_bebob_meter_spec saffire_meter_spec = { | ||
271 | .num = ARRAY_SIZE(saffire_meter_labels), | ||
272 | .labels = saffire_meter_labels, | ||
273 | .get = &saffire_meter_get, | ||
274 | }; | ||
275 | struct snd_bebob_spec saffire_spec = { | ||
276 | .clock = &saffire_both_clk_spec, | ||
277 | .rate = &saffire_both_rate_spec, | ||
278 | .meter = &saffire_meter_spec | ||
279 | }; | ||
diff --git a/sound/firewire/bebob/bebob_hwdep.c b/sound/firewire/bebob/bebob_hwdep.c new file mode 100644 index 000000000000..ce731f4d8b4f --- /dev/null +++ b/sound/firewire/bebob/bebob_hwdep.c | |||
@@ -0,0 +1,199 @@ | |||
1 | /* | ||
2 | * bebob_hwdep.c - a part of driver for BeBoB based devices | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | /* | ||
10 | * This codes give three functionality. | ||
11 | * | ||
12 | * 1.get firewire node infomation | ||
13 | * 2.get notification about starting/stopping stream | ||
14 | * 3.lock/unlock stream | ||
15 | */ | ||
16 | |||
17 | #include "bebob.h" | ||
18 | |||
19 | static long | ||
20 | hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, | ||
21 | loff_t *offset) | ||
22 | { | ||
23 | struct snd_bebob *bebob = hwdep->private_data; | ||
24 | DEFINE_WAIT(wait); | ||
25 | union snd_firewire_event event; | ||
26 | |||
27 | spin_lock_irq(&bebob->lock); | ||
28 | |||
29 | while (!bebob->dev_lock_changed) { | ||
30 | prepare_to_wait(&bebob->hwdep_wait, &wait, TASK_INTERRUPTIBLE); | ||
31 | spin_unlock_irq(&bebob->lock); | ||
32 | schedule(); | ||
33 | finish_wait(&bebob->hwdep_wait, &wait); | ||
34 | if (signal_pending(current)) | ||
35 | return -ERESTARTSYS; | ||
36 | spin_lock_irq(&bebob->lock); | ||
37 | } | ||
38 | |||
39 | memset(&event, 0, sizeof(event)); | ||
40 | if (bebob->dev_lock_changed) { | ||
41 | event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; | ||
42 | event.lock_status.status = (bebob->dev_lock_count > 0); | ||
43 | bebob->dev_lock_changed = false; | ||
44 | |||
45 | count = min_t(long, count, sizeof(event.lock_status)); | ||
46 | } | ||
47 | |||
48 | spin_unlock_irq(&bebob->lock); | ||
49 | |||
50 | if (copy_to_user(buf, &event, count)) | ||
51 | return -EFAULT; | ||
52 | |||
53 | return count; | ||
54 | } | ||
55 | |||
56 | static unsigned int | ||
57 | hwdep_poll(struct snd_hwdep *hwdep, struct file *file, poll_table *wait) | ||
58 | { | ||
59 | struct snd_bebob *bebob = hwdep->private_data; | ||
60 | unsigned int events; | ||
61 | |||
62 | poll_wait(file, &bebob->hwdep_wait, wait); | ||
63 | |||
64 | spin_lock_irq(&bebob->lock); | ||
65 | if (bebob->dev_lock_changed) | ||
66 | events = POLLIN | POLLRDNORM; | ||
67 | else | ||
68 | events = 0; | ||
69 | spin_unlock_irq(&bebob->lock); | ||
70 | |||
71 | return events; | ||
72 | } | ||
73 | |||
74 | static int | ||
75 | hwdep_get_info(struct snd_bebob *bebob, void __user *arg) | ||
76 | { | ||
77 | struct fw_device *dev = fw_parent_device(bebob->unit); | ||
78 | struct snd_firewire_get_info info; | ||
79 | |||
80 | memset(&info, 0, sizeof(info)); | ||
81 | info.type = SNDRV_FIREWIRE_TYPE_BEBOB; | ||
82 | info.card = dev->card->index; | ||
83 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); | ||
84 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); | ||
85 | strlcpy(info.device_name, dev_name(&dev->device), | ||
86 | sizeof(info.device_name)); | ||
87 | |||
88 | if (copy_to_user(arg, &info, sizeof(info))) | ||
89 | return -EFAULT; | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static int | ||
95 | hwdep_lock(struct snd_bebob *bebob) | ||
96 | { | ||
97 | int err; | ||
98 | |||
99 | spin_lock_irq(&bebob->lock); | ||
100 | |||
101 | if (bebob->dev_lock_count == 0) { | ||
102 | bebob->dev_lock_count = -1; | ||
103 | err = 0; | ||
104 | } else { | ||
105 | err = -EBUSY; | ||
106 | } | ||
107 | |||
108 | spin_unlock_irq(&bebob->lock); | ||
109 | |||
110 | return err; | ||
111 | } | ||
112 | |||
113 | static int | ||
114 | hwdep_unlock(struct snd_bebob *bebob) | ||
115 | { | ||
116 | int err; | ||
117 | |||
118 | spin_lock_irq(&bebob->lock); | ||
119 | |||
120 | if (bebob->dev_lock_count == -1) { | ||
121 | bebob->dev_lock_count = 0; | ||
122 | err = 0; | ||
123 | } else { | ||
124 | err = -EBADFD; | ||
125 | } | ||
126 | |||
127 | spin_unlock_irq(&bebob->lock); | ||
128 | |||
129 | return err; | ||
130 | } | ||
131 | |||
132 | static int | ||
133 | hwdep_release(struct snd_hwdep *hwdep, struct file *file) | ||
134 | { | ||
135 | struct snd_bebob *bebob = hwdep->private_data; | ||
136 | |||
137 | spin_lock_irq(&bebob->lock); | ||
138 | if (bebob->dev_lock_count == -1) | ||
139 | bebob->dev_lock_count = 0; | ||
140 | spin_unlock_irq(&bebob->lock); | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int | ||
146 | hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file, | ||
147 | unsigned int cmd, unsigned long arg) | ||
148 | { | ||
149 | struct snd_bebob *bebob = hwdep->private_data; | ||
150 | |||
151 | switch (cmd) { | ||
152 | case SNDRV_FIREWIRE_IOCTL_GET_INFO: | ||
153 | return hwdep_get_info(bebob, (void __user *)arg); | ||
154 | case SNDRV_FIREWIRE_IOCTL_LOCK: | ||
155 | return hwdep_lock(bebob); | ||
156 | case SNDRV_FIREWIRE_IOCTL_UNLOCK: | ||
157 | return hwdep_unlock(bebob); | ||
158 | default: | ||
159 | return -ENOIOCTLCMD; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | #ifdef CONFIG_COMPAT | ||
164 | static int | ||
165 | hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file, | ||
166 | unsigned int cmd, unsigned long arg) | ||
167 | { | ||
168 | return hwdep_ioctl(hwdep, file, cmd, | ||
169 | (unsigned long)compat_ptr(arg)); | ||
170 | } | ||
171 | #else | ||
172 | #define hwdep_compat_ioctl NULL | ||
173 | #endif | ||
174 | |||
175 | static const struct snd_hwdep_ops hwdep_ops = { | ||
176 | .read = hwdep_read, | ||
177 | .release = hwdep_release, | ||
178 | .poll = hwdep_poll, | ||
179 | .ioctl = hwdep_ioctl, | ||
180 | .ioctl_compat = hwdep_compat_ioctl, | ||
181 | }; | ||
182 | |||
183 | int snd_bebob_create_hwdep_device(struct snd_bebob *bebob) | ||
184 | { | ||
185 | struct snd_hwdep *hwdep; | ||
186 | int err; | ||
187 | |||
188 | err = snd_hwdep_new(bebob->card, "BeBoB", 0, &hwdep); | ||
189 | if (err < 0) | ||
190 | goto end; | ||
191 | strcpy(hwdep->name, "BeBoB"); | ||
192 | hwdep->iface = SNDRV_HWDEP_IFACE_FW_BEBOB; | ||
193 | hwdep->ops = hwdep_ops; | ||
194 | hwdep->private_data = bebob; | ||
195 | hwdep->exclusive = true; | ||
196 | end: | ||
197 | return err; | ||
198 | } | ||
199 | |||
diff --git a/sound/firewire/bebob/bebob_maudio.c b/sound/firewire/bebob/bebob_maudio.c new file mode 100644 index 000000000000..6af50eb80ea7 --- /dev/null +++ b/sound/firewire/bebob/bebob_maudio.c | |||
@@ -0,0 +1,792 @@ | |||
1 | /* | ||
2 | * bebob_maudio.c - a part of driver for BeBoB based devices | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | #include "./bebob.h" | ||
10 | #include <sound/control.h> | ||
11 | |||
12 | /* | ||
13 | * Just powering on, Firewire 410/Audiophile/1814 and ProjectMix I/O wait to | ||
14 | * download firmware blob. To enable these devices, drivers should upload | ||
15 | * firmware blob and send a command to initialize configuration to factory | ||
16 | * settings when completing uploading. Then these devices generate bus reset | ||
17 | * and are recognized as new devices with the firmware. | ||
18 | * | ||
19 | * But with firmware version 5058 or later, the firmware is stored to flash | ||
20 | * memory in the device and drivers can tell bootloader to load the firmware | ||
21 | * by sending a cue. This cue must be sent one time. | ||
22 | * | ||
23 | * For streaming, both of output and input streams are needed for Firewire 410 | ||
24 | * and Ozonic. The single stream is OK for the other devices even if the clock | ||
25 | * source is not SYT-Match (I note no devices use SYT-Match). | ||
26 | * | ||
27 | * Without streaming, the devices except for Firewire Audiophile can mix any | ||
28 | * input and output. For this reason, Audiophile cannot be used as standalone | ||
29 | * mixer. | ||
30 | * | ||
31 | * Firewire 1814 and ProjectMix I/O uses special firmware. It will be freezed | ||
32 | * when receiving any commands which the firmware can't understand. These | ||
33 | * devices utilize completely different system to control. It is some | ||
34 | * write-transaction directly into a certain address. All of addresses for mixer | ||
35 | * functionality is between 0xffc700700000 to 0xffc70070009c. | ||
36 | */ | ||
37 | |||
38 | /* Offset from information register */ | ||
39 | #define INFO_OFFSET_SW_DATE 0x20 | ||
40 | |||
41 | /* Bootloader Protocol Version 1 */ | ||
42 | #define MAUDIO_BOOTLOADER_CUE1 0x00000001 | ||
43 | /* | ||
44 | * Initializing configuration to factory settings (= 0x1101), (swapped in line), | ||
45 | * Command code is zero (= 0x00), | ||
46 | * the number of operands is zero (= 0x00)(at least significant byte) | ||
47 | */ | ||
48 | #define MAUDIO_BOOTLOADER_CUE2 0x01110000 | ||
49 | /* padding */ | ||
50 | #define MAUDIO_BOOTLOADER_CUE3 0x00000000 | ||
51 | |||
52 | #define MAUDIO_SPECIFIC_ADDRESS 0xffc700000000ULL | ||
53 | |||
54 | #define METER_OFFSET 0x00600000 | ||
55 | |||
56 | /* some device has sync info after metering data */ | ||
57 | #define METER_SIZE_SPECIAL 84 /* with sync info */ | ||
58 | #define METER_SIZE_FW410 76 /* with sync info */ | ||
59 | #define METER_SIZE_AUDIOPHILE 60 /* with sync info */ | ||
60 | #define METER_SIZE_SOLO 52 /* with sync info */ | ||
61 | #define METER_SIZE_OZONIC 48 | ||
62 | #define METER_SIZE_NRV10 80 | ||
63 | |||
64 | /* labels for metering */ | ||
65 | #define ANA_IN "Analog In" | ||
66 | #define ANA_OUT "Analog Out" | ||
67 | #define DIG_IN "Digital In" | ||
68 | #define SPDIF_IN "S/PDIF In" | ||
69 | #define ADAT_IN "ADAT In" | ||
70 | #define DIG_OUT "Digital Out" | ||
71 | #define SPDIF_OUT "S/PDIF Out" | ||
72 | #define ADAT_OUT "ADAT Out" | ||
73 | #define STRM_IN "Stream In" | ||
74 | #define AUX_OUT "Aux Out" | ||
75 | #define HP_OUT "HP Out" | ||
76 | /* for NRV */ | ||
77 | #define UNKNOWN_METER "Unknown" | ||
78 | |||
79 | struct special_params { | ||
80 | bool is1814; | ||
81 | unsigned int clk_src; | ||
82 | unsigned int dig_in_fmt; | ||
83 | unsigned int dig_out_fmt; | ||
84 | unsigned int clk_lock; | ||
85 | struct snd_ctl_elem_id *ctl_id_sync; | ||
86 | }; | ||
87 | |||
88 | /* | ||
89 | * For some M-Audio devices, this module just send cue to load firmware. After | ||
90 | * loading, the device generates bus reset and newly detected. | ||
91 | * | ||
92 | * If we make any transactions to load firmware, the operation may failed. | ||
93 | */ | ||
94 | int snd_bebob_maudio_load_firmware(struct fw_unit *unit) | ||
95 | { | ||
96 | struct fw_device *device = fw_parent_device(unit); | ||
97 | int err, rcode; | ||
98 | u64 date; | ||
99 | __be32 cues[3] = { | ||
100 | MAUDIO_BOOTLOADER_CUE1, | ||
101 | MAUDIO_BOOTLOADER_CUE2, | ||
102 | MAUDIO_BOOTLOADER_CUE3 | ||
103 | }; | ||
104 | |||
105 | /* check date of software used to build */ | ||
106 | err = snd_bebob_read_block(unit, INFO_OFFSET_SW_DATE, | ||
107 | &date, sizeof(u64)); | ||
108 | if (err < 0) | ||
109 | goto end; | ||
110 | /* | ||
111 | * firmware version 5058 or later has date later than "20070401", but | ||
112 | * 'date' is not null-terminated. | ||
113 | */ | ||
114 | if (date < 0x3230303730343031LL) { | ||
115 | dev_err(&unit->device, | ||
116 | "Use firmware version 5058 or later\n"); | ||
117 | err = -ENOSYS; | ||
118 | goto end; | ||
119 | } | ||
120 | |||
121 | rcode = fw_run_transaction(device->card, TCODE_WRITE_BLOCK_REQUEST, | ||
122 | device->node_id, device->generation, | ||
123 | device->max_speed, BEBOB_ADDR_REG_REQ, | ||
124 | cues, sizeof(cues)); | ||
125 | if (rcode != RCODE_COMPLETE) { | ||
126 | dev_err(&unit->device, | ||
127 | "Failed to send a cue to load firmware\n"); | ||
128 | err = -EIO; | ||
129 | } | ||
130 | end: | ||
131 | return err; | ||
132 | } | ||
133 | |||
134 | static inline int | ||
135 | get_meter(struct snd_bebob *bebob, void *buf, unsigned int size) | ||
136 | { | ||
137 | return snd_fw_transaction(bebob->unit, TCODE_READ_BLOCK_REQUEST, | ||
138 | MAUDIO_SPECIFIC_ADDRESS + METER_OFFSET, | ||
139 | buf, size, 0); | ||
140 | } | ||
141 | |||
142 | static int | ||
143 | check_clk_sync(struct snd_bebob *bebob, unsigned int size, bool *sync) | ||
144 | { | ||
145 | int err; | ||
146 | u8 *buf; | ||
147 | |||
148 | buf = kmalloc(size, GFP_KERNEL); | ||
149 | if (buf == NULL) | ||
150 | return -ENOMEM; | ||
151 | |||
152 | err = get_meter(bebob, buf, size); | ||
153 | if (err < 0) | ||
154 | goto end; | ||
155 | |||
156 | /* if synced, this value is the same as SFC of FDF in CIP header */ | ||
157 | *sync = (buf[size - 2] != 0xff); | ||
158 | end: | ||
159 | kfree(buf); | ||
160 | return err; | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * dig_fmt: 0x00:S/PDIF, 0x01:ADAT | ||
165 | * clk_lock: 0x00:unlock, 0x01:lock | ||
166 | */ | ||
167 | static int | ||
168 | avc_maudio_set_special_clk(struct snd_bebob *bebob, unsigned int clk_src, | ||
169 | unsigned int dig_in_fmt, unsigned int dig_out_fmt, | ||
170 | unsigned int clk_lock) | ||
171 | { | ||
172 | struct special_params *params = bebob->maudio_special_quirk; | ||
173 | int err; | ||
174 | u8 *buf; | ||
175 | |||
176 | if (amdtp_stream_running(&bebob->rx_stream) || | ||
177 | amdtp_stream_running(&bebob->tx_stream)) | ||
178 | return -EBUSY; | ||
179 | |||
180 | buf = kmalloc(12, GFP_KERNEL); | ||
181 | if (buf == NULL) | ||
182 | return -ENOMEM; | ||
183 | |||
184 | buf[0] = 0x00; /* CONTROL */ | ||
185 | buf[1] = 0xff; /* UNIT */ | ||
186 | buf[2] = 0x00; /* vendor dependent */ | ||
187 | buf[3] = 0x04; /* company ID high */ | ||
188 | buf[4] = 0x00; /* company ID middle */ | ||
189 | buf[5] = 0x04; /* company ID low */ | ||
190 | buf[6] = 0xff & clk_src; /* clock source */ | ||
191 | buf[7] = 0xff & dig_in_fmt; /* input digital format */ | ||
192 | buf[8] = 0xff & dig_out_fmt; /* output digital format */ | ||
193 | buf[9] = 0xff & clk_lock; /* lock these settings */ | ||
194 | buf[10] = 0x00; /* padding */ | ||
195 | buf[11] = 0x00; /* padding */ | ||
196 | |||
197 | err = fcp_avc_transaction(bebob->unit, buf, 12, buf, 12, | ||
198 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | | ||
199 | BIT(5) | BIT(6) | BIT(7) | BIT(8) | | ||
200 | BIT(9)); | ||
201 | if ((err > 0) && (err < 10)) | ||
202 | err = -EIO; | ||
203 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | ||
204 | err = -ENOSYS; | ||
205 | else if (buf[0] == 0x0a) /* REJECTED */ | ||
206 | err = -EINVAL; | ||
207 | if (err < 0) | ||
208 | goto end; | ||
209 | |||
210 | params->clk_src = buf[6]; | ||
211 | params->dig_in_fmt = buf[7]; | ||
212 | params->dig_out_fmt = buf[8]; | ||
213 | params->clk_lock = buf[9]; | ||
214 | |||
215 | if (params->ctl_id_sync) | ||
216 | snd_ctl_notify(bebob->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
217 | params->ctl_id_sync); | ||
218 | |||
219 | err = 0; | ||
220 | end: | ||
221 | kfree(buf); | ||
222 | return err; | ||
223 | } | ||
224 | static void | ||
225 | special_stream_formation_set(struct snd_bebob *bebob) | ||
226 | { | ||
227 | static const unsigned int ch_table[2][2][3] = { | ||
228 | /* AMDTP_OUT_STREAM */ | ||
229 | { { 6, 6, 4 }, /* SPDIF */ | ||
230 | { 12, 8, 4 } }, /* ADAT */ | ||
231 | /* AMDTP_IN_STREAM */ | ||
232 | { { 10, 10, 2 }, /* SPDIF */ | ||
233 | { 16, 12, 2 } } /* ADAT */ | ||
234 | }; | ||
235 | struct special_params *params = bebob->maudio_special_quirk; | ||
236 | unsigned int i, max; | ||
237 | |||
238 | max = SND_BEBOB_STRM_FMT_ENTRIES - 1; | ||
239 | if (!params->is1814) | ||
240 | max -= 2; | ||
241 | |||
242 | for (i = 0; i < max; i++) { | ||
243 | bebob->tx_stream_formations[i + 1].pcm = | ||
244 | ch_table[AMDTP_IN_STREAM][params->dig_in_fmt][i / 2]; | ||
245 | bebob->tx_stream_formations[i + 1].midi = 1; | ||
246 | |||
247 | bebob->rx_stream_formations[i + 1].pcm = | ||
248 | ch_table[AMDTP_OUT_STREAM][params->dig_out_fmt][i / 2]; | ||
249 | bebob->rx_stream_formations[i + 1].midi = 1; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | static int add_special_controls(struct snd_bebob *bebob); | ||
254 | int | ||
255 | snd_bebob_maudio_special_discover(struct snd_bebob *bebob, bool is1814) | ||
256 | { | ||
257 | struct special_params *params; | ||
258 | int err; | ||
259 | |||
260 | params = kzalloc(sizeof(struct special_params), GFP_KERNEL); | ||
261 | if (params == NULL) | ||
262 | return -ENOMEM; | ||
263 | |||
264 | mutex_lock(&bebob->mutex); | ||
265 | |||
266 | bebob->maudio_special_quirk = (void *)params; | ||
267 | params->is1814 = is1814; | ||
268 | |||
269 | /* initialize these parameters because driver is not allowed to ask */ | ||
270 | bebob->rx_stream.context = ERR_PTR(-1); | ||
271 | bebob->tx_stream.context = ERR_PTR(-1); | ||
272 | err = avc_maudio_set_special_clk(bebob, 0x03, 0x00, 0x00, 0x00); | ||
273 | if (err < 0) { | ||
274 | dev_err(&bebob->unit->device, | ||
275 | "fail to initialize clock params: %d\n", err); | ||
276 | goto end; | ||
277 | } | ||
278 | |||
279 | err = add_special_controls(bebob); | ||
280 | if (err < 0) | ||
281 | goto end; | ||
282 | |||
283 | special_stream_formation_set(bebob); | ||
284 | |||
285 | if (params->is1814) { | ||
286 | bebob->midi_input_ports = 1; | ||
287 | bebob->midi_output_ports = 1; | ||
288 | } else { | ||
289 | bebob->midi_input_ports = 2; | ||
290 | bebob->midi_output_ports = 2; | ||
291 | } | ||
292 | end: | ||
293 | if (err < 0) { | ||
294 | kfree(params); | ||
295 | bebob->maudio_special_quirk = NULL; | ||
296 | } | ||
297 | mutex_unlock(&bebob->mutex); | ||
298 | return err; | ||
299 | } | ||
300 | |||
301 | /* Input plug shows actual rate. Output plug is needless for this purpose. */ | ||
302 | static int special_get_rate(struct snd_bebob *bebob, unsigned int *rate) | ||
303 | { | ||
304 | int err, trials; | ||
305 | |||
306 | trials = 0; | ||
307 | do { | ||
308 | err = avc_general_get_sig_fmt(bebob->unit, rate, | ||
309 | AVC_GENERAL_PLUG_DIR_IN, 0); | ||
310 | } while (err == -EAGAIN && ++trials < 3); | ||
311 | |||
312 | return err; | ||
313 | } | ||
314 | static int special_set_rate(struct snd_bebob *bebob, unsigned int rate) | ||
315 | { | ||
316 | struct special_params *params = bebob->maudio_special_quirk; | ||
317 | int err; | ||
318 | |||
319 | err = avc_general_set_sig_fmt(bebob->unit, rate, | ||
320 | AVC_GENERAL_PLUG_DIR_OUT, 0); | ||
321 | if (err < 0) | ||
322 | goto end; | ||
323 | |||
324 | /* | ||
325 | * Just after changing sampling rate for output, a followed command | ||
326 | * for input is easy to fail. This is a workaround fot this issue. | ||
327 | */ | ||
328 | msleep(100); | ||
329 | |||
330 | err = avc_general_set_sig_fmt(bebob->unit, rate, | ||
331 | AVC_GENERAL_PLUG_DIR_IN, 0); | ||
332 | if (err < 0) | ||
333 | goto end; | ||
334 | |||
335 | if (params->ctl_id_sync) | ||
336 | snd_ctl_notify(bebob->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
337 | params->ctl_id_sync); | ||
338 | end: | ||
339 | return err; | ||
340 | } | ||
341 | |||
342 | /* Clock source control for special firmware */ | ||
343 | static char *const special_clk_labels[] = { | ||
344 | SND_BEBOB_CLOCK_INTERNAL " with Digital Mute", "Digital", | ||
345 | "Word Clock", SND_BEBOB_CLOCK_INTERNAL}; | ||
346 | static int special_clk_get(struct snd_bebob *bebob, unsigned int *id) | ||
347 | { | ||
348 | struct special_params *params = bebob->maudio_special_quirk; | ||
349 | *id = params->clk_src; | ||
350 | return 0; | ||
351 | } | ||
352 | static int special_clk_ctl_info(struct snd_kcontrol *kctl, | ||
353 | struct snd_ctl_elem_info *einf) | ||
354 | { | ||
355 | einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
356 | einf->count = 1; | ||
357 | einf->value.enumerated.items = ARRAY_SIZE(special_clk_labels); | ||
358 | |||
359 | if (einf->value.enumerated.item >= einf->value.enumerated.items) | ||
360 | einf->value.enumerated.item = einf->value.enumerated.items - 1; | ||
361 | |||
362 | strcpy(einf->value.enumerated.name, | ||
363 | special_clk_labels[einf->value.enumerated.item]); | ||
364 | |||
365 | return 0; | ||
366 | } | ||
367 | static int special_clk_ctl_get(struct snd_kcontrol *kctl, | ||
368 | struct snd_ctl_elem_value *uval) | ||
369 | { | ||
370 | struct snd_bebob *bebob = snd_kcontrol_chip(kctl); | ||
371 | struct special_params *params = bebob->maudio_special_quirk; | ||
372 | uval->value.enumerated.item[0] = params->clk_src; | ||
373 | return 0; | ||
374 | } | ||
375 | static int special_clk_ctl_put(struct snd_kcontrol *kctl, | ||
376 | struct snd_ctl_elem_value *uval) | ||
377 | { | ||
378 | struct snd_bebob *bebob = snd_kcontrol_chip(kctl); | ||
379 | struct special_params *params = bebob->maudio_special_quirk; | ||
380 | int err, id; | ||
381 | |||
382 | mutex_lock(&bebob->mutex); | ||
383 | |||
384 | id = uval->value.enumerated.item[0]; | ||
385 | if (id >= ARRAY_SIZE(special_clk_labels)) | ||
386 | return 0; | ||
387 | |||
388 | err = avc_maudio_set_special_clk(bebob, id, | ||
389 | params->dig_in_fmt, | ||
390 | params->dig_out_fmt, | ||
391 | params->clk_lock); | ||
392 | mutex_unlock(&bebob->mutex); | ||
393 | |||
394 | return err >= 0; | ||
395 | } | ||
396 | static struct snd_kcontrol_new special_clk_ctl = { | ||
397 | .name = "Clock Source", | ||
398 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
399 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
400 | .info = special_clk_ctl_info, | ||
401 | .get = special_clk_ctl_get, | ||
402 | .put = special_clk_ctl_put | ||
403 | }; | ||
404 | |||
405 | /* Clock synchronization control for special firmware */ | ||
406 | static int special_sync_ctl_info(struct snd_kcontrol *kctl, | ||
407 | struct snd_ctl_elem_info *einf) | ||
408 | { | ||
409 | einf->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
410 | einf->count = 1; | ||
411 | einf->value.integer.min = 0; | ||
412 | einf->value.integer.max = 1; | ||
413 | |||
414 | return 0; | ||
415 | } | ||
416 | static int special_sync_ctl_get(struct snd_kcontrol *kctl, | ||
417 | struct snd_ctl_elem_value *uval) | ||
418 | { | ||
419 | struct snd_bebob *bebob = snd_kcontrol_chip(kctl); | ||
420 | int err; | ||
421 | bool synced = 0; | ||
422 | |||
423 | err = check_clk_sync(bebob, METER_SIZE_SPECIAL, &synced); | ||
424 | if (err >= 0) | ||
425 | uval->value.integer.value[0] = synced; | ||
426 | |||
427 | return 0; | ||
428 | } | ||
429 | static struct snd_kcontrol_new special_sync_ctl = { | ||
430 | .name = "Sync Status", | ||
431 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
432 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | ||
433 | .info = special_sync_ctl_info, | ||
434 | .get = special_sync_ctl_get, | ||
435 | }; | ||
436 | |||
437 | /* Digital interface control for special firmware */ | ||
438 | static char *const special_dig_iface_labels[] = { | ||
439 | "S/PDIF Optical", "S/PDIF Coaxial", "ADAT Optical" | ||
440 | }; | ||
441 | static int special_dig_in_iface_ctl_info(struct snd_kcontrol *kctl, | ||
442 | struct snd_ctl_elem_info *einf) | ||
443 | { | ||
444 | einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
445 | einf->count = 1; | ||
446 | einf->value.enumerated.items = ARRAY_SIZE(special_dig_iface_labels); | ||
447 | |||
448 | if (einf->value.enumerated.item >= einf->value.enumerated.items) | ||
449 | einf->value.enumerated.item = einf->value.enumerated.items - 1; | ||
450 | |||
451 | strcpy(einf->value.enumerated.name, | ||
452 | special_dig_iface_labels[einf->value.enumerated.item]); | ||
453 | |||
454 | return 0; | ||
455 | } | ||
456 | static int special_dig_in_iface_ctl_get(struct snd_kcontrol *kctl, | ||
457 | struct snd_ctl_elem_value *uval) | ||
458 | { | ||
459 | struct snd_bebob *bebob = snd_kcontrol_chip(kctl); | ||
460 | struct special_params *params = bebob->maudio_special_quirk; | ||
461 | unsigned int dig_in_iface; | ||
462 | int err, val; | ||
463 | |||
464 | mutex_lock(&bebob->mutex); | ||
465 | |||
466 | err = avc_audio_get_selector(bebob->unit, 0x00, 0x04, | ||
467 | &dig_in_iface); | ||
468 | if (err < 0) { | ||
469 | dev_err(&bebob->unit->device, | ||
470 | "fail to get digital input interface: %d\n", err); | ||
471 | goto end; | ||
472 | } | ||
473 | |||
474 | /* encoded id for user value */ | ||
475 | val = (params->dig_in_fmt << 1) | (dig_in_iface & 0x01); | ||
476 | |||
477 | /* for ADAT Optical */ | ||
478 | if (val > 2) | ||
479 | val = 2; | ||
480 | |||
481 | uval->value.enumerated.item[0] = val; | ||
482 | end: | ||
483 | mutex_unlock(&bebob->mutex); | ||
484 | return err; | ||
485 | } | ||
486 | static int special_dig_in_iface_ctl_set(struct snd_kcontrol *kctl, | ||
487 | struct snd_ctl_elem_value *uval) | ||
488 | { | ||
489 | struct snd_bebob *bebob = snd_kcontrol_chip(kctl); | ||
490 | struct special_params *params = bebob->maudio_special_quirk; | ||
491 | unsigned int id, dig_in_fmt, dig_in_iface; | ||
492 | int err; | ||
493 | |||
494 | mutex_lock(&bebob->mutex); | ||
495 | |||
496 | id = uval->value.enumerated.item[0]; | ||
497 | |||
498 | /* decode user value */ | ||
499 | dig_in_fmt = (id >> 1) & 0x01; | ||
500 | dig_in_iface = id & 0x01; | ||
501 | |||
502 | err = avc_maudio_set_special_clk(bebob, | ||
503 | params->clk_src, | ||
504 | dig_in_fmt, | ||
505 | params->dig_out_fmt, | ||
506 | params->clk_lock); | ||
507 | if ((err < 0) || (params->dig_in_fmt > 0)) /* ADAT */ | ||
508 | goto end; | ||
509 | |||
510 | err = avc_audio_set_selector(bebob->unit, 0x00, 0x04, dig_in_iface); | ||
511 | if (err < 0) | ||
512 | dev_err(&bebob->unit->device, | ||
513 | "fail to set digital input interface: %d\n", err); | ||
514 | end: | ||
515 | special_stream_formation_set(bebob); | ||
516 | mutex_unlock(&bebob->mutex); | ||
517 | return err; | ||
518 | } | ||
519 | static struct snd_kcontrol_new special_dig_in_iface_ctl = { | ||
520 | .name = "Digital Input Interface", | ||
521 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
522 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
523 | .info = special_dig_in_iface_ctl_info, | ||
524 | .get = special_dig_in_iface_ctl_get, | ||
525 | .put = special_dig_in_iface_ctl_set | ||
526 | }; | ||
527 | |||
528 | static int special_dig_out_iface_ctl_info(struct snd_kcontrol *kctl, | ||
529 | struct snd_ctl_elem_info *einf) | ||
530 | { | ||
531 | einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
532 | einf->count = 1; | ||
533 | einf->value.enumerated.items = ARRAY_SIZE(special_dig_iface_labels) - 1; | ||
534 | |||
535 | if (einf->value.enumerated.item >= einf->value.enumerated.items) | ||
536 | einf->value.enumerated.item = einf->value.enumerated.items - 1; | ||
537 | |||
538 | strcpy(einf->value.enumerated.name, | ||
539 | special_dig_iface_labels[einf->value.enumerated.item + 1]); | ||
540 | |||
541 | return 0; | ||
542 | } | ||
543 | static int special_dig_out_iface_ctl_get(struct snd_kcontrol *kctl, | ||
544 | struct snd_ctl_elem_value *uval) | ||
545 | { | ||
546 | struct snd_bebob *bebob = snd_kcontrol_chip(kctl); | ||
547 | struct special_params *params = bebob->maudio_special_quirk; | ||
548 | mutex_lock(&bebob->mutex); | ||
549 | uval->value.enumerated.item[0] = params->dig_out_fmt; | ||
550 | mutex_unlock(&bebob->mutex); | ||
551 | return 0; | ||
552 | } | ||
553 | static int special_dig_out_iface_ctl_set(struct snd_kcontrol *kctl, | ||
554 | struct snd_ctl_elem_value *uval) | ||
555 | { | ||
556 | struct snd_bebob *bebob = snd_kcontrol_chip(kctl); | ||
557 | struct special_params *params = bebob->maudio_special_quirk; | ||
558 | unsigned int id; | ||
559 | int err; | ||
560 | |||
561 | mutex_lock(&bebob->mutex); | ||
562 | |||
563 | id = uval->value.enumerated.item[0]; | ||
564 | |||
565 | err = avc_maudio_set_special_clk(bebob, | ||
566 | params->clk_src, | ||
567 | params->dig_in_fmt, | ||
568 | id, params->clk_lock); | ||
569 | if (err >= 0) | ||
570 | special_stream_formation_set(bebob); | ||
571 | |||
572 | mutex_unlock(&bebob->mutex); | ||
573 | return err; | ||
574 | } | ||
575 | static struct snd_kcontrol_new special_dig_out_iface_ctl = { | ||
576 | .name = "Digital Output Interface", | ||
577 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
578 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
579 | .info = special_dig_out_iface_ctl_info, | ||
580 | .get = special_dig_out_iface_ctl_get, | ||
581 | .put = special_dig_out_iface_ctl_set | ||
582 | }; | ||
583 | |||
584 | static int add_special_controls(struct snd_bebob *bebob) | ||
585 | { | ||
586 | struct snd_kcontrol *kctl; | ||
587 | struct special_params *params = bebob->maudio_special_quirk; | ||
588 | int err; | ||
589 | |||
590 | kctl = snd_ctl_new1(&special_clk_ctl, bebob); | ||
591 | err = snd_ctl_add(bebob->card, kctl); | ||
592 | if (err < 0) | ||
593 | goto end; | ||
594 | |||
595 | kctl = snd_ctl_new1(&special_sync_ctl, bebob); | ||
596 | err = snd_ctl_add(bebob->card, kctl); | ||
597 | if (err < 0) | ||
598 | goto end; | ||
599 | params->ctl_id_sync = &kctl->id; | ||
600 | |||
601 | kctl = snd_ctl_new1(&special_dig_in_iface_ctl, bebob); | ||
602 | err = snd_ctl_add(bebob->card, kctl); | ||
603 | if (err < 0) | ||
604 | goto end; | ||
605 | |||
606 | kctl = snd_ctl_new1(&special_dig_out_iface_ctl, bebob); | ||
607 | err = snd_ctl_add(bebob->card, kctl); | ||
608 | end: | ||
609 | return err; | ||
610 | } | ||
611 | |||
612 | /* Hardware metering for special firmware */ | ||
613 | static char *const special_meter_labels[] = { | ||
614 | ANA_IN, ANA_IN, ANA_IN, ANA_IN, | ||
615 | SPDIF_IN, | ||
616 | ADAT_IN, ADAT_IN, ADAT_IN, ADAT_IN, | ||
617 | ANA_OUT, ANA_OUT, | ||
618 | SPDIF_OUT, | ||
619 | ADAT_OUT, ADAT_OUT, ADAT_OUT, ADAT_OUT, | ||
620 | HP_OUT, HP_OUT, | ||
621 | AUX_OUT | ||
622 | }; | ||
623 | static int | ||
624 | special_meter_get(struct snd_bebob *bebob, u32 *target, unsigned int size) | ||
625 | { | ||
626 | u16 *buf; | ||
627 | unsigned int i, c, channels; | ||
628 | int err; | ||
629 | |||
630 | channels = ARRAY_SIZE(special_meter_labels) * 2; | ||
631 | if (size < channels * sizeof(u32)) | ||
632 | return -EINVAL; | ||
633 | |||
634 | /* omit last 4 bytes because it's clock info. */ | ||
635 | buf = kmalloc(METER_SIZE_SPECIAL - 4, GFP_KERNEL); | ||
636 | if (buf == NULL) | ||
637 | return -ENOMEM; | ||
638 | |||
639 | err = get_meter(bebob, (void *)buf, METER_SIZE_SPECIAL - 4); | ||
640 | if (err < 0) | ||
641 | goto end; | ||
642 | |||
643 | /* Its format is u16 and some channels are unknown. */ | ||
644 | i = 0; | ||
645 | for (c = 2; c < channels + 2; c++) | ||
646 | target[i++] = be16_to_cpu(buf[c]) << 16; | ||
647 | end: | ||
648 | kfree(buf); | ||
649 | return err; | ||
650 | } | ||
651 | |||
652 | /* last 4 bytes are omitted because it's clock info. */ | ||
653 | static char *const fw410_meter_labels[] = { | ||
654 | ANA_IN, DIG_IN, | ||
655 | ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT, DIG_OUT, | ||
656 | HP_OUT | ||
657 | }; | ||
658 | static char *const audiophile_meter_labels[] = { | ||
659 | ANA_IN, DIG_IN, | ||
660 | ANA_OUT, ANA_OUT, DIG_OUT, | ||
661 | HP_OUT, AUX_OUT, | ||
662 | }; | ||
663 | static char *const solo_meter_labels[] = { | ||
664 | ANA_IN, DIG_IN, | ||
665 | STRM_IN, STRM_IN, | ||
666 | ANA_OUT, DIG_OUT | ||
667 | }; | ||
668 | |||
669 | /* no clock info */ | ||
670 | static char *const ozonic_meter_labels[] = { | ||
671 | ANA_IN, ANA_IN, | ||
672 | STRM_IN, STRM_IN, | ||
673 | ANA_OUT, ANA_OUT | ||
674 | }; | ||
675 | /* TODO: need testers. these positions are based on authour's assumption */ | ||
676 | static char *const nrv10_meter_labels[] = { | ||
677 | ANA_IN, ANA_IN, ANA_IN, ANA_IN, | ||
678 | DIG_IN, | ||
679 | ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT, | ||
680 | DIG_IN | ||
681 | }; | ||
682 | static int | ||
683 | normal_meter_get(struct snd_bebob *bebob, u32 *buf, unsigned int size) | ||
684 | { | ||
685 | struct snd_bebob_meter_spec *spec = bebob->spec->meter; | ||
686 | unsigned int c, channels; | ||
687 | int err; | ||
688 | |||
689 | channels = spec->num * 2; | ||
690 | if (size < channels * sizeof(u32)) | ||
691 | return -EINVAL; | ||
692 | |||
693 | err = get_meter(bebob, (void *)buf, size); | ||
694 | if (err < 0) | ||
695 | goto end; | ||
696 | |||
697 | for (c = 0; c < channels; c++) | ||
698 | be32_to_cpus(&buf[c]); | ||
699 | |||
700 | /* swap stream channels because inverted */ | ||
701 | if (spec->labels == solo_meter_labels) { | ||
702 | swap(buf[4], buf[6]); | ||
703 | swap(buf[5], buf[7]); | ||
704 | } | ||
705 | end: | ||
706 | return err; | ||
707 | } | ||
708 | |||
709 | /* for special customized devices */ | ||
710 | static struct snd_bebob_rate_spec special_rate_spec = { | ||
711 | .get = &special_get_rate, | ||
712 | .set = &special_set_rate, | ||
713 | }; | ||
714 | static struct snd_bebob_clock_spec special_clk_spec = { | ||
715 | .num = ARRAY_SIZE(special_clk_labels), | ||
716 | .labels = special_clk_labels, | ||
717 | .get = &special_clk_get, | ||
718 | }; | ||
719 | static struct snd_bebob_meter_spec special_meter_spec = { | ||
720 | .num = ARRAY_SIZE(special_meter_labels), | ||
721 | .labels = special_meter_labels, | ||
722 | .get = &special_meter_get | ||
723 | }; | ||
724 | struct snd_bebob_spec maudio_special_spec = { | ||
725 | .clock = &special_clk_spec, | ||
726 | .rate = &special_rate_spec, | ||
727 | .meter = &special_meter_spec | ||
728 | }; | ||
729 | |||
730 | /* Firewire 410 specification */ | ||
731 | static struct snd_bebob_rate_spec usual_rate_spec = { | ||
732 | .get = &snd_bebob_stream_get_rate, | ||
733 | .set = &snd_bebob_stream_set_rate, | ||
734 | }; | ||
735 | static struct snd_bebob_meter_spec fw410_meter_spec = { | ||
736 | .num = ARRAY_SIZE(fw410_meter_labels), | ||
737 | .labels = fw410_meter_labels, | ||
738 | .get = &normal_meter_get | ||
739 | }; | ||
740 | struct snd_bebob_spec maudio_fw410_spec = { | ||
741 | .clock = NULL, | ||
742 | .rate = &usual_rate_spec, | ||
743 | .meter = &fw410_meter_spec | ||
744 | }; | ||
745 | |||
746 | /* Firewire Audiophile specification */ | ||
747 | static struct snd_bebob_meter_spec audiophile_meter_spec = { | ||
748 | .num = ARRAY_SIZE(audiophile_meter_labels), | ||
749 | .labels = audiophile_meter_labels, | ||
750 | .get = &normal_meter_get | ||
751 | }; | ||
752 | struct snd_bebob_spec maudio_audiophile_spec = { | ||
753 | .clock = NULL, | ||
754 | .rate = &usual_rate_spec, | ||
755 | .meter = &audiophile_meter_spec | ||
756 | }; | ||
757 | |||
758 | /* Firewire Solo specification */ | ||
759 | static struct snd_bebob_meter_spec solo_meter_spec = { | ||
760 | .num = ARRAY_SIZE(solo_meter_labels), | ||
761 | .labels = solo_meter_labels, | ||
762 | .get = &normal_meter_get | ||
763 | }; | ||
764 | struct snd_bebob_spec maudio_solo_spec = { | ||
765 | .clock = NULL, | ||
766 | .rate = &usual_rate_spec, | ||
767 | .meter = &solo_meter_spec | ||
768 | }; | ||
769 | |||
770 | /* Ozonic specification */ | ||
771 | static struct snd_bebob_meter_spec ozonic_meter_spec = { | ||
772 | .num = ARRAY_SIZE(ozonic_meter_labels), | ||
773 | .labels = ozonic_meter_labels, | ||
774 | .get = &normal_meter_get | ||
775 | }; | ||
776 | struct snd_bebob_spec maudio_ozonic_spec = { | ||
777 | .clock = NULL, | ||
778 | .rate = &usual_rate_spec, | ||
779 | .meter = &ozonic_meter_spec | ||
780 | }; | ||
781 | |||
782 | /* NRV10 specification */ | ||
783 | static struct snd_bebob_meter_spec nrv10_meter_spec = { | ||
784 | .num = ARRAY_SIZE(nrv10_meter_labels), | ||
785 | .labels = nrv10_meter_labels, | ||
786 | .get = &normal_meter_get | ||
787 | }; | ||
788 | struct snd_bebob_spec maudio_nrv10_spec = { | ||
789 | .clock = NULL, | ||
790 | .rate = &usual_rate_spec, | ||
791 | .meter = &nrv10_meter_spec | ||
792 | }; | ||
diff --git a/sound/firewire/bebob/bebob_midi.c b/sound/firewire/bebob/bebob_midi.c new file mode 100644 index 000000000000..63343d578df3 --- /dev/null +++ b/sound/firewire/bebob/bebob_midi.c | |||
@@ -0,0 +1,168 @@ | |||
1 | /* | ||
2 | * bebob_midi.c - a part of driver for BeBoB based devices | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | #include "bebob.h" | ||
10 | |||
11 | static int midi_capture_open(struct snd_rawmidi_substream *substream) | ||
12 | { | ||
13 | struct snd_bebob *bebob = substream->rmidi->private_data; | ||
14 | int err; | ||
15 | |||
16 | err = snd_bebob_stream_lock_try(bebob); | ||
17 | if (err < 0) | ||
18 | goto end; | ||
19 | |||
20 | atomic_inc(&bebob->capture_substreams); | ||
21 | err = snd_bebob_stream_start_duplex(bebob, 0); | ||
22 | if (err < 0) | ||
23 | snd_bebob_stream_lock_release(bebob); | ||
24 | end: | ||
25 | return err; | ||
26 | } | ||
27 | |||
28 | static int midi_playback_open(struct snd_rawmidi_substream *substream) | ||
29 | { | ||
30 | struct snd_bebob *bebob = substream->rmidi->private_data; | ||
31 | int err; | ||
32 | |||
33 | err = snd_bebob_stream_lock_try(bebob); | ||
34 | if (err < 0) | ||
35 | goto end; | ||
36 | |||
37 | atomic_inc(&bebob->playback_substreams); | ||
38 | err = snd_bebob_stream_start_duplex(bebob, 0); | ||
39 | if (err < 0) | ||
40 | snd_bebob_stream_lock_release(bebob); | ||
41 | end: | ||
42 | return err; | ||
43 | } | ||
44 | |||
45 | static int midi_capture_close(struct snd_rawmidi_substream *substream) | ||
46 | { | ||
47 | struct snd_bebob *bebob = substream->rmidi->private_data; | ||
48 | |||
49 | atomic_dec(&bebob->capture_substreams); | ||
50 | snd_bebob_stream_stop_duplex(bebob); | ||
51 | |||
52 | snd_bebob_stream_lock_release(bebob); | ||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | static int midi_playback_close(struct snd_rawmidi_substream *substream) | ||
57 | { | ||
58 | struct snd_bebob *bebob = substream->rmidi->private_data; | ||
59 | |||
60 | atomic_dec(&bebob->playback_substreams); | ||
61 | snd_bebob_stream_stop_duplex(bebob); | ||
62 | |||
63 | snd_bebob_stream_lock_release(bebob); | ||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up) | ||
68 | { | ||
69 | struct snd_bebob *bebob = substrm->rmidi->private_data; | ||
70 | unsigned long flags; | ||
71 | |||
72 | spin_lock_irqsave(&bebob->lock, flags); | ||
73 | |||
74 | if (up) | ||
75 | amdtp_stream_midi_trigger(&bebob->tx_stream, | ||
76 | substrm->number, substrm); | ||
77 | else | ||
78 | amdtp_stream_midi_trigger(&bebob->tx_stream, | ||
79 | substrm->number, NULL); | ||
80 | |||
81 | spin_unlock_irqrestore(&bebob->lock, flags); | ||
82 | } | ||
83 | |||
84 | static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up) | ||
85 | { | ||
86 | struct snd_bebob *bebob = substrm->rmidi->private_data; | ||
87 | unsigned long flags; | ||
88 | |||
89 | spin_lock_irqsave(&bebob->lock, flags); | ||
90 | |||
91 | if (up) | ||
92 | amdtp_stream_midi_trigger(&bebob->rx_stream, | ||
93 | substrm->number, substrm); | ||
94 | else | ||
95 | amdtp_stream_midi_trigger(&bebob->rx_stream, | ||
96 | substrm->number, NULL); | ||
97 | |||
98 | spin_unlock_irqrestore(&bebob->lock, flags); | ||
99 | } | ||
100 | |||
101 | static struct snd_rawmidi_ops midi_capture_ops = { | ||
102 | .open = midi_capture_open, | ||
103 | .close = midi_capture_close, | ||
104 | .trigger = midi_capture_trigger, | ||
105 | }; | ||
106 | |||
107 | static struct snd_rawmidi_ops midi_playback_ops = { | ||
108 | .open = midi_playback_open, | ||
109 | .close = midi_playback_close, | ||
110 | .trigger = midi_playback_trigger, | ||
111 | }; | ||
112 | |||
113 | static void set_midi_substream_names(struct snd_bebob *bebob, | ||
114 | struct snd_rawmidi_str *str) | ||
115 | { | ||
116 | struct snd_rawmidi_substream *subs; | ||
117 | |||
118 | list_for_each_entry(subs, &str->substreams, list) { | ||
119 | snprintf(subs->name, sizeof(subs->name), | ||
120 | "%s MIDI %d", | ||
121 | bebob->card->shortname, subs->number + 1); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | int snd_bebob_create_midi_devices(struct snd_bebob *bebob) | ||
126 | { | ||
127 | struct snd_rawmidi *rmidi; | ||
128 | struct snd_rawmidi_str *str; | ||
129 | int err; | ||
130 | |||
131 | /* create midi ports */ | ||
132 | err = snd_rawmidi_new(bebob->card, bebob->card->driver, 0, | ||
133 | bebob->midi_output_ports, bebob->midi_input_ports, | ||
134 | &rmidi); | ||
135 | if (err < 0) | ||
136 | return err; | ||
137 | |||
138 | snprintf(rmidi->name, sizeof(rmidi->name), | ||
139 | "%s MIDI", bebob->card->shortname); | ||
140 | rmidi->private_data = bebob; | ||
141 | |||
142 | if (bebob->midi_input_ports > 0) { | ||
143 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; | ||
144 | |||
145 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, | ||
146 | &midi_capture_ops); | ||
147 | |||
148 | str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]; | ||
149 | |||
150 | set_midi_substream_names(bebob, str); | ||
151 | } | ||
152 | |||
153 | if (bebob->midi_output_ports > 0) { | ||
154 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; | ||
155 | |||
156 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, | ||
157 | &midi_playback_ops); | ||
158 | |||
159 | str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]; | ||
160 | |||
161 | set_midi_substream_names(bebob, str); | ||
162 | } | ||
163 | |||
164 | if ((bebob->midi_output_ports > 0) && (bebob->midi_input_ports > 0)) | ||
165 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX; | ||
166 | |||
167 | return 0; | ||
168 | } | ||
diff --git a/sound/firewire/bebob/bebob_pcm.c b/sound/firewire/bebob/bebob_pcm.c new file mode 100644 index 000000000000..4a55561ed4ec --- /dev/null +++ b/sound/firewire/bebob/bebob_pcm.c | |||
@@ -0,0 +1,378 @@ | |||
1 | /* | ||
2 | * bebob_pcm.c - a part of driver for BeBoB based devices | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | #include "./bebob.h" | ||
10 | |||
11 | static int | ||
12 | hw_rule_rate(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) | ||
13 | { | ||
14 | struct snd_bebob_stream_formation *formations = rule->private; | ||
15 | struct snd_interval *r = | ||
16 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | ||
17 | const struct snd_interval *c = | ||
18 | hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
19 | struct snd_interval t = { | ||
20 | .min = UINT_MAX, .max = 0, .integer = 1 | ||
21 | }; | ||
22 | unsigned int i; | ||
23 | |||
24 | for (i = 0; i < SND_BEBOB_STRM_FMT_ENTRIES; i++) { | ||
25 | /* entry is invalid */ | ||
26 | if (formations[i].pcm == 0) | ||
27 | continue; | ||
28 | |||
29 | if (!snd_interval_test(c, formations[i].pcm)) | ||
30 | continue; | ||
31 | |||
32 | t.min = min(t.min, snd_bebob_rate_table[i]); | ||
33 | t.max = max(t.max, snd_bebob_rate_table[i]); | ||
34 | |||
35 | } | ||
36 | return snd_interval_refine(r, &t); | ||
37 | } | ||
38 | |||
39 | static int | ||
40 | hw_rule_channels(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) | ||
41 | { | ||
42 | struct snd_bebob_stream_formation *formations = rule->private; | ||
43 | struct snd_interval *c = | ||
44 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
45 | const struct snd_interval *r = | ||
46 | hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE); | ||
47 | struct snd_interval t = { | ||
48 | .min = UINT_MAX, .max = 0, .integer = 1 | ||
49 | }; | ||
50 | |||
51 | unsigned int i; | ||
52 | |||
53 | for (i = 0; i < SND_BEBOB_STRM_FMT_ENTRIES; i++) { | ||
54 | /* entry is invalid */ | ||
55 | if (formations[i].pcm == 0) | ||
56 | continue; | ||
57 | |||
58 | if (!snd_interval_test(r, snd_bebob_rate_table[i])) | ||
59 | continue; | ||
60 | |||
61 | t.min = min(t.min, formations[i].pcm); | ||
62 | t.max = max(t.max, formations[i].pcm); | ||
63 | } | ||
64 | |||
65 | return snd_interval_refine(c, &t); | ||
66 | } | ||
67 | |||
68 | static void | ||
69 | limit_channels_and_rates(struct snd_pcm_hardware *hw, | ||
70 | struct snd_bebob_stream_formation *formations) | ||
71 | { | ||
72 | unsigned int i; | ||
73 | |||
74 | hw->channels_min = UINT_MAX; | ||
75 | hw->channels_max = 0; | ||
76 | |||
77 | hw->rate_min = UINT_MAX; | ||
78 | hw->rate_max = 0; | ||
79 | hw->rates = 0; | ||
80 | |||
81 | for (i = 0; i < SND_BEBOB_STRM_FMT_ENTRIES; i++) { | ||
82 | /* entry has no PCM channels */ | ||
83 | if (formations[i].pcm == 0) | ||
84 | continue; | ||
85 | |||
86 | hw->channels_min = min(hw->channels_min, formations[i].pcm); | ||
87 | hw->channels_max = max(hw->channels_max, formations[i].pcm); | ||
88 | |||
89 | hw->rate_min = min(hw->rate_min, snd_bebob_rate_table[i]); | ||
90 | hw->rate_max = max(hw->rate_max, snd_bebob_rate_table[i]); | ||
91 | hw->rates |= snd_pcm_rate_to_rate_bit(snd_bebob_rate_table[i]); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | static void | ||
96 | limit_period_and_buffer(struct snd_pcm_hardware *hw) | ||
97 | { | ||
98 | hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */ | ||
99 | hw->periods_max = UINT_MAX; | ||
100 | |||
101 | hw->period_bytes_min = 4 * hw->channels_max; /* bytes for a frame */ | ||
102 | |||
103 | /* Just to prevent from allocating much pages. */ | ||
104 | hw->period_bytes_max = hw->period_bytes_min * 2048; | ||
105 | hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; | ||
106 | } | ||
107 | |||
108 | static int | ||
109 | pcm_init_hw_params(struct snd_bebob *bebob, | ||
110 | struct snd_pcm_substream *substream) | ||
111 | { | ||
112 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
113 | struct amdtp_stream *s; | ||
114 | struct snd_bebob_stream_formation *formations; | ||
115 | int err; | ||
116 | |||
117 | runtime->hw.info = SNDRV_PCM_INFO_BATCH | | ||
118 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
119 | SNDRV_PCM_INFO_INTERLEAVED | | ||
120 | SNDRV_PCM_INFO_JOINT_DUPLEX | | ||
121 | SNDRV_PCM_INFO_MMAP | | ||
122 | SNDRV_PCM_INFO_MMAP_VALID; | ||
123 | |||
124 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | ||
125 | runtime->hw.formats = AMDTP_IN_PCM_FORMAT_BITS; | ||
126 | s = &bebob->tx_stream; | ||
127 | formations = bebob->tx_stream_formations; | ||
128 | } else { | ||
129 | runtime->hw.formats = AMDTP_OUT_PCM_FORMAT_BITS; | ||
130 | s = &bebob->rx_stream; | ||
131 | formations = bebob->rx_stream_formations; | ||
132 | } | ||
133 | |||
134 | limit_channels_and_rates(&runtime->hw, formations); | ||
135 | limit_period_and_buffer(&runtime->hw); | ||
136 | |||
137 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
138 | hw_rule_channels, formations, | ||
139 | SNDRV_PCM_HW_PARAM_RATE, -1); | ||
140 | if (err < 0) | ||
141 | goto end; | ||
142 | |||
143 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | ||
144 | hw_rule_rate, formations, | ||
145 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
146 | if (err < 0) | ||
147 | goto end; | ||
148 | |||
149 | err = amdtp_stream_add_pcm_hw_constraints(s, runtime); | ||
150 | end: | ||
151 | return err; | ||
152 | } | ||
153 | |||
154 | static int | ||
155 | pcm_open(struct snd_pcm_substream *substream) | ||
156 | { | ||
157 | struct snd_bebob *bebob = substream->private_data; | ||
158 | struct snd_bebob_rate_spec *spec = bebob->spec->rate; | ||
159 | unsigned int sampling_rate; | ||
160 | bool internal; | ||
161 | int err; | ||
162 | |||
163 | err = snd_bebob_stream_lock_try(bebob); | ||
164 | if (err < 0) | ||
165 | goto end; | ||
166 | |||
167 | err = pcm_init_hw_params(bebob, substream); | ||
168 | if (err < 0) | ||
169 | goto err_locked; | ||
170 | |||
171 | err = snd_bebob_stream_check_internal_clock(bebob, &internal); | ||
172 | if (err < 0) | ||
173 | goto err_locked; | ||
174 | |||
175 | /* | ||
176 | * When source of clock is internal or any PCM stream are running, | ||
177 | * the available sampling rate is limited at current sampling rate. | ||
178 | */ | ||
179 | if (!internal || | ||
180 | amdtp_stream_pcm_running(&bebob->tx_stream) || | ||
181 | amdtp_stream_pcm_running(&bebob->rx_stream)) { | ||
182 | err = spec->get(bebob, &sampling_rate); | ||
183 | if (err < 0) { | ||
184 | dev_err(&bebob->unit->device, | ||
185 | "fail to get sampling rate: %d\n", err); | ||
186 | goto err_locked; | ||
187 | } | ||
188 | |||
189 | substream->runtime->hw.rate_min = sampling_rate; | ||
190 | substream->runtime->hw.rate_max = sampling_rate; | ||
191 | } | ||
192 | |||
193 | snd_pcm_set_sync(substream); | ||
194 | end: | ||
195 | return err; | ||
196 | err_locked: | ||
197 | snd_bebob_stream_lock_release(bebob); | ||
198 | return err; | ||
199 | } | ||
200 | |||
201 | static int | ||
202 | pcm_close(struct snd_pcm_substream *substream) | ||
203 | { | ||
204 | struct snd_bebob *bebob = substream->private_data; | ||
205 | snd_bebob_stream_lock_release(bebob); | ||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static int | ||
210 | pcm_capture_hw_params(struct snd_pcm_substream *substream, | ||
211 | struct snd_pcm_hw_params *hw_params) | ||
212 | { | ||
213 | struct snd_bebob *bebob = substream->private_data; | ||
214 | |||
215 | if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) | ||
216 | atomic_inc(&bebob->capture_substreams); | ||
217 | amdtp_stream_set_pcm_format(&bebob->tx_stream, | ||
218 | params_format(hw_params)); | ||
219 | return snd_pcm_lib_alloc_vmalloc_buffer(substream, | ||
220 | params_buffer_bytes(hw_params)); | ||
221 | } | ||
222 | static int | ||
223 | pcm_playback_hw_params(struct snd_pcm_substream *substream, | ||
224 | struct snd_pcm_hw_params *hw_params) | ||
225 | { | ||
226 | struct snd_bebob *bebob = substream->private_data; | ||
227 | |||
228 | if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) | ||
229 | atomic_inc(&bebob->playback_substreams); | ||
230 | amdtp_stream_set_pcm_format(&bebob->rx_stream, | ||
231 | params_format(hw_params)); | ||
232 | return snd_pcm_lib_alloc_vmalloc_buffer(substream, | ||
233 | params_buffer_bytes(hw_params)); | ||
234 | } | ||
235 | |||
236 | static int | ||
237 | pcm_capture_hw_free(struct snd_pcm_substream *substream) | ||
238 | { | ||
239 | struct snd_bebob *bebob = substream->private_data; | ||
240 | |||
241 | if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) | ||
242 | atomic_dec(&bebob->capture_substreams); | ||
243 | |||
244 | snd_bebob_stream_stop_duplex(bebob); | ||
245 | |||
246 | return snd_pcm_lib_free_vmalloc_buffer(substream); | ||
247 | } | ||
248 | static int | ||
249 | pcm_playback_hw_free(struct snd_pcm_substream *substream) | ||
250 | { | ||
251 | struct snd_bebob *bebob = substream->private_data; | ||
252 | |||
253 | if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) | ||
254 | atomic_dec(&bebob->playback_substreams); | ||
255 | |||
256 | snd_bebob_stream_stop_duplex(bebob); | ||
257 | |||
258 | return snd_pcm_lib_free_vmalloc_buffer(substream); | ||
259 | } | ||
260 | |||
261 | static int | ||
262 | pcm_capture_prepare(struct snd_pcm_substream *substream) | ||
263 | { | ||
264 | struct snd_bebob *bebob = substream->private_data; | ||
265 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
266 | int err; | ||
267 | |||
268 | err = snd_bebob_stream_start_duplex(bebob, runtime->rate); | ||
269 | if (err >= 0) | ||
270 | amdtp_stream_pcm_prepare(&bebob->tx_stream); | ||
271 | |||
272 | return err; | ||
273 | } | ||
274 | static int | ||
275 | pcm_playback_prepare(struct snd_pcm_substream *substream) | ||
276 | { | ||
277 | struct snd_bebob *bebob = substream->private_data; | ||
278 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
279 | int err; | ||
280 | |||
281 | err = snd_bebob_stream_start_duplex(bebob, runtime->rate); | ||
282 | if (err >= 0) | ||
283 | amdtp_stream_pcm_prepare(&bebob->rx_stream); | ||
284 | |||
285 | return err; | ||
286 | } | ||
287 | |||
288 | static int | ||
289 | pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) | ||
290 | { | ||
291 | struct snd_bebob *bebob = substream->private_data; | ||
292 | |||
293 | switch (cmd) { | ||
294 | case SNDRV_PCM_TRIGGER_START: | ||
295 | amdtp_stream_pcm_trigger(&bebob->tx_stream, substream); | ||
296 | break; | ||
297 | case SNDRV_PCM_TRIGGER_STOP: | ||
298 | amdtp_stream_pcm_trigger(&bebob->tx_stream, NULL); | ||
299 | break; | ||
300 | default: | ||
301 | return -EINVAL; | ||
302 | } | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | static int | ||
307 | pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) | ||
308 | { | ||
309 | struct snd_bebob *bebob = substream->private_data; | ||
310 | |||
311 | switch (cmd) { | ||
312 | case SNDRV_PCM_TRIGGER_START: | ||
313 | amdtp_stream_pcm_trigger(&bebob->rx_stream, substream); | ||
314 | break; | ||
315 | case SNDRV_PCM_TRIGGER_STOP: | ||
316 | amdtp_stream_pcm_trigger(&bebob->rx_stream, NULL); | ||
317 | break; | ||
318 | default: | ||
319 | return -EINVAL; | ||
320 | } | ||
321 | |||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static snd_pcm_uframes_t | ||
326 | pcm_capture_pointer(struct snd_pcm_substream *sbstrm) | ||
327 | { | ||
328 | struct snd_bebob *bebob = sbstrm->private_data; | ||
329 | return amdtp_stream_pcm_pointer(&bebob->tx_stream); | ||
330 | } | ||
331 | static snd_pcm_uframes_t | ||
332 | pcm_playback_pointer(struct snd_pcm_substream *sbstrm) | ||
333 | { | ||
334 | struct snd_bebob *bebob = sbstrm->private_data; | ||
335 | return amdtp_stream_pcm_pointer(&bebob->rx_stream); | ||
336 | } | ||
337 | |||
338 | static const struct snd_pcm_ops pcm_capture_ops = { | ||
339 | .open = pcm_open, | ||
340 | .close = pcm_close, | ||
341 | .ioctl = snd_pcm_lib_ioctl, | ||
342 | .hw_params = pcm_capture_hw_params, | ||
343 | .hw_free = pcm_capture_hw_free, | ||
344 | .prepare = pcm_capture_prepare, | ||
345 | .trigger = pcm_capture_trigger, | ||
346 | .pointer = pcm_capture_pointer, | ||
347 | .page = snd_pcm_lib_get_vmalloc_page, | ||
348 | }; | ||
349 | static const struct snd_pcm_ops pcm_playback_ops = { | ||
350 | .open = pcm_open, | ||
351 | .close = pcm_close, | ||
352 | .ioctl = snd_pcm_lib_ioctl, | ||
353 | .hw_params = pcm_playback_hw_params, | ||
354 | .hw_free = pcm_playback_hw_free, | ||
355 | .prepare = pcm_playback_prepare, | ||
356 | .trigger = pcm_playback_trigger, | ||
357 | .pointer = pcm_playback_pointer, | ||
358 | .page = snd_pcm_lib_get_vmalloc_page, | ||
359 | .mmap = snd_pcm_lib_mmap_vmalloc, | ||
360 | }; | ||
361 | |||
362 | int snd_bebob_create_pcm_devices(struct snd_bebob *bebob) | ||
363 | { | ||
364 | struct snd_pcm *pcm; | ||
365 | int err; | ||
366 | |||
367 | err = snd_pcm_new(bebob->card, bebob->card->driver, 0, 1, 1, &pcm); | ||
368 | if (err < 0) | ||
369 | goto end; | ||
370 | |||
371 | pcm->private_data = bebob; | ||
372 | snprintf(pcm->name, sizeof(pcm->name), | ||
373 | "%s PCM", bebob->card->shortname); | ||
374 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops); | ||
375 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops); | ||
376 | end: | ||
377 | return err; | ||
378 | } | ||
diff --git a/sound/firewire/bebob/bebob_proc.c b/sound/firewire/bebob/bebob_proc.c new file mode 100644 index 000000000000..335da64506e0 --- /dev/null +++ b/sound/firewire/bebob/bebob_proc.c | |||
@@ -0,0 +1,196 @@ | |||
1 | /* | ||
2 | * bebob_proc.c - a part of driver for BeBoB based devices | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | #include "./bebob.h" | ||
10 | |||
11 | /* contents of information register */ | ||
12 | struct hw_info { | ||
13 | u64 manufacturer; | ||
14 | u32 protocol_ver; | ||
15 | u32 bld_ver; | ||
16 | u32 guid[2]; | ||
17 | u32 model_id; | ||
18 | u32 model_rev; | ||
19 | u64 fw_date; | ||
20 | u64 fw_time; | ||
21 | u32 fw_id; | ||
22 | u32 fw_ver; | ||
23 | u32 base_addr; | ||
24 | u32 max_size; | ||
25 | u64 bld_date; | ||
26 | u64 bld_time; | ||
27 | /* may not used in product | ||
28 | u64 dbg_date; | ||
29 | u64 dbg_time; | ||
30 | u32 dbg_id; | ||
31 | u32 dbg_version; | ||
32 | */ | ||
33 | } __packed; | ||
34 | |||
35 | static void | ||
36 | proc_read_hw_info(struct snd_info_entry *entry, | ||
37 | struct snd_info_buffer *buffer) | ||
38 | { | ||
39 | struct snd_bebob *bebob = entry->private_data; | ||
40 | struct hw_info *info; | ||
41 | |||
42 | info = kzalloc(sizeof(struct hw_info), GFP_KERNEL); | ||
43 | if (info == NULL) | ||
44 | return; | ||
45 | |||
46 | if (snd_bebob_read_block(bebob->unit, 0, | ||
47 | info, sizeof(struct hw_info)) < 0) | ||
48 | goto end; | ||
49 | |||
50 | snd_iprintf(buffer, "Manufacturer:\t%.8s\n", | ||
51 | (char *)&info->manufacturer); | ||
52 | snd_iprintf(buffer, "Protocol Ver:\t%d\n", info->protocol_ver); | ||
53 | snd_iprintf(buffer, "Build Ver:\t%d\n", info->bld_ver); | ||
54 | snd_iprintf(buffer, "GUID:\t\t0x%.8X%.8X\n", | ||
55 | info->guid[0], info->guid[1]); | ||
56 | snd_iprintf(buffer, "Model ID:\t0x%02X\n", info->model_id); | ||
57 | snd_iprintf(buffer, "Model Rev:\t%d\n", info->model_rev); | ||
58 | snd_iprintf(buffer, "Firmware Date:\t%.8s\n", (char *)&info->fw_date); | ||
59 | snd_iprintf(buffer, "Firmware Time:\t%.8s\n", (char *)&info->fw_time); | ||
60 | snd_iprintf(buffer, "Firmware ID:\t0x%X\n", info->fw_id); | ||
61 | snd_iprintf(buffer, "Firmware Ver:\t%d\n", info->fw_ver); | ||
62 | snd_iprintf(buffer, "Base Addr:\t0x%X\n", info->base_addr); | ||
63 | snd_iprintf(buffer, "Max Size:\t%d\n", info->max_size); | ||
64 | snd_iprintf(buffer, "Loader Date:\t%.8s\n", (char *)&info->bld_date); | ||
65 | snd_iprintf(buffer, "Loader Time:\t%.8s\n", (char *)&info->bld_time); | ||
66 | |||
67 | end: | ||
68 | kfree(info); | ||
69 | } | ||
70 | |||
71 | static void | ||
72 | proc_read_meters(struct snd_info_entry *entry, | ||
73 | struct snd_info_buffer *buffer) | ||
74 | { | ||
75 | struct snd_bebob *bebob = entry->private_data; | ||
76 | struct snd_bebob_meter_spec *spec = bebob->spec->meter; | ||
77 | u32 *buf; | ||
78 | unsigned int i, c, channels, size; | ||
79 | |||
80 | if (spec == NULL) | ||
81 | return; | ||
82 | |||
83 | channels = spec->num * 2; | ||
84 | size = channels * sizeof(u32); | ||
85 | buf = kmalloc(size, GFP_KERNEL); | ||
86 | if (buf == NULL) | ||
87 | return; | ||
88 | |||
89 | if (spec->get(bebob, buf, size) < 0) | ||
90 | goto end; | ||
91 | |||
92 | for (i = 0, c = 1; i < channels; i++) { | ||
93 | snd_iprintf(buffer, "%s %d:\t%d\n", | ||
94 | spec->labels[i / 2], c++, buf[i]); | ||
95 | if ((i + 1 < channels - 1) && | ||
96 | (strcmp(spec->labels[i / 2], | ||
97 | spec->labels[(i + 1) / 2]) != 0)) | ||
98 | c = 1; | ||
99 | } | ||
100 | end: | ||
101 | kfree(buf); | ||
102 | } | ||
103 | |||
104 | static void | ||
105 | proc_read_formation(struct snd_info_entry *entry, | ||
106 | struct snd_info_buffer *buffer) | ||
107 | { | ||
108 | struct snd_bebob *bebob = entry->private_data; | ||
109 | struct snd_bebob_stream_formation *formation; | ||
110 | unsigned int i; | ||
111 | |||
112 | snd_iprintf(buffer, "Output Stream from device:\n"); | ||
113 | snd_iprintf(buffer, "\tRate\tPCM\tMIDI\n"); | ||
114 | formation = bebob->tx_stream_formations; | ||
115 | for (i = 0; i < SND_BEBOB_STRM_FMT_ENTRIES; i++) { | ||
116 | snd_iprintf(buffer, | ||
117 | "\t%d\t%d\t%d\n", snd_bebob_rate_table[i], | ||
118 | formation[i].pcm, formation[i].midi); | ||
119 | } | ||
120 | |||
121 | snd_iprintf(buffer, "Input Stream to device:\n"); | ||
122 | snd_iprintf(buffer, "\tRate\tPCM\tMIDI\n"); | ||
123 | formation = bebob->rx_stream_formations; | ||
124 | for (i = 0; i < SND_BEBOB_STRM_FMT_ENTRIES; i++) { | ||
125 | snd_iprintf(buffer, | ||
126 | "\t%d\t%d\t%d\n", snd_bebob_rate_table[i], | ||
127 | formation[i].pcm, formation[i].midi); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | static void | ||
132 | proc_read_clock(struct snd_info_entry *entry, | ||
133 | struct snd_info_buffer *buffer) | ||
134 | { | ||
135 | struct snd_bebob *bebob = entry->private_data; | ||
136 | struct snd_bebob_rate_spec *rate_spec = bebob->spec->rate; | ||
137 | struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock; | ||
138 | unsigned int rate, id; | ||
139 | bool internal; | ||
140 | |||
141 | if (rate_spec->get(bebob, &rate) >= 0) | ||
142 | snd_iprintf(buffer, "Sampling rate: %d\n", rate); | ||
143 | |||
144 | if (clk_spec) { | ||
145 | if (clk_spec->get(bebob, &id) >= 0) | ||
146 | snd_iprintf(buffer, "Clock Source: %s\n", | ||
147 | clk_spec->labels[id]); | ||
148 | } else { | ||
149 | if (snd_bebob_stream_check_internal_clock(bebob, | ||
150 | &internal) >= 0) | ||
151 | snd_iprintf(buffer, "Clock Source: %s (MSU-dest: %d)\n", | ||
152 | (internal) ? "Internal" : "External", | ||
153 | bebob->sync_input_plug); | ||
154 | } | ||
155 | } | ||
156 | |||
157 | static void | ||
158 | add_node(struct snd_bebob *bebob, struct snd_info_entry *root, const char *name, | ||
159 | void (*op)(struct snd_info_entry *e, struct snd_info_buffer *b)) | ||
160 | { | ||
161 | struct snd_info_entry *entry; | ||
162 | |||
163 | entry = snd_info_create_card_entry(bebob->card, name, root); | ||
164 | if (entry == NULL) | ||
165 | return; | ||
166 | |||
167 | snd_info_set_text_ops(entry, bebob, op); | ||
168 | if (snd_info_register(entry) < 0) | ||
169 | snd_info_free_entry(entry); | ||
170 | } | ||
171 | |||
172 | void snd_bebob_proc_init(struct snd_bebob *bebob) | ||
173 | { | ||
174 | struct snd_info_entry *root; | ||
175 | |||
176 | /* | ||
177 | * All nodes are automatically removed at snd_card_disconnect(), | ||
178 | * by following to link list. | ||
179 | */ | ||
180 | root = snd_info_create_card_entry(bebob->card, "firewire", | ||
181 | bebob->card->proc_root); | ||
182 | if (root == NULL) | ||
183 | return; | ||
184 | root->mode = S_IFDIR | S_IRUGO | S_IXUGO; | ||
185 | if (snd_info_register(root) < 0) { | ||
186 | snd_info_free_entry(root); | ||
187 | return; | ||
188 | } | ||
189 | |||
190 | add_node(bebob, root, "clock", proc_read_clock); | ||
191 | add_node(bebob, root, "firmware", proc_read_hw_info); | ||
192 | add_node(bebob, root, "formation", proc_read_formation); | ||
193 | |||
194 | if (bebob->spec->meter != NULL) | ||
195 | add_node(bebob, root, "meter", proc_read_meters); | ||
196 | } | ||
diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c new file mode 100644 index 000000000000..514c7c9fa1cd --- /dev/null +++ b/sound/firewire/bebob/bebob_stream.c | |||
@@ -0,0 +1,1021 @@ | |||
1 | /* | ||
2 | * bebob_stream.c - a part of driver for BeBoB based devices | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | #include "./bebob.h" | ||
10 | |||
11 | #define CALLBACK_TIMEOUT 1000 | ||
12 | #define FW_ISO_RESOURCE_DELAY 1000 | ||
13 | |||
14 | /* | ||
15 | * NOTE; | ||
16 | * For BeBoB streams, Both of input and output CMP connection are important. | ||
17 | * | ||
18 | * For most devices, each CMP connection starts to transmit/receive a | ||
19 | * corresponding stream. But for a few devices, both of CMP connection needs | ||
20 | * to start transmitting stream. An example is 'M-Audio Firewire 410'. | ||
21 | */ | ||
22 | |||
23 | /* 128 is an arbitrary length but it seems to be enough */ | ||
24 | #define FORMAT_MAXIMUM_LENGTH 128 | ||
25 | |||
26 | const unsigned int snd_bebob_rate_table[SND_BEBOB_STRM_FMT_ENTRIES] = { | ||
27 | [0] = 32000, | ||
28 | [1] = 44100, | ||
29 | [2] = 48000, | ||
30 | [3] = 88200, | ||
31 | [4] = 96000, | ||
32 | [5] = 176400, | ||
33 | [6] = 192000, | ||
34 | }; | ||
35 | |||
36 | /* | ||
37 | * See: Table 51: Extended Stream Format Info ‘Sampling Frequency’ | ||
38 | * in Additional AVC commands (Nov 2003, BridgeCo) | ||
39 | */ | ||
40 | static const unsigned int bridgeco_freq_table[] = { | ||
41 | [0] = 0x02, | ||
42 | [1] = 0x03, | ||
43 | [2] = 0x04, | ||
44 | [3] = 0x0a, | ||
45 | [4] = 0x05, | ||
46 | [5] = 0x06, | ||
47 | [6] = 0x07, | ||
48 | }; | ||
49 | |||
50 | static unsigned int | ||
51 | get_formation_index(unsigned int rate) | ||
52 | { | ||
53 | unsigned int i; | ||
54 | |||
55 | for (i = 0; i < ARRAY_SIZE(snd_bebob_rate_table); i++) { | ||
56 | if (snd_bebob_rate_table[i] == rate) | ||
57 | return i; | ||
58 | } | ||
59 | return -EINVAL; | ||
60 | } | ||
61 | |||
62 | int | ||
63 | snd_bebob_stream_get_rate(struct snd_bebob *bebob, unsigned int *curr_rate) | ||
64 | { | ||
65 | unsigned int tx_rate, rx_rate, trials; | ||
66 | int err; | ||
67 | |||
68 | trials = 0; | ||
69 | do { | ||
70 | err = avc_general_get_sig_fmt(bebob->unit, &tx_rate, | ||
71 | AVC_GENERAL_PLUG_DIR_OUT, 0); | ||
72 | } while (err == -EAGAIN && ++trials < 3); | ||
73 | if (err < 0) | ||
74 | goto end; | ||
75 | |||
76 | trials = 0; | ||
77 | do { | ||
78 | err = avc_general_get_sig_fmt(bebob->unit, &rx_rate, | ||
79 | AVC_GENERAL_PLUG_DIR_IN, 0); | ||
80 | } while (err == -EAGAIN && ++trials < 3); | ||
81 | if (err < 0) | ||
82 | goto end; | ||
83 | |||
84 | *curr_rate = rx_rate; | ||
85 | if (rx_rate == tx_rate) | ||
86 | goto end; | ||
87 | |||
88 | /* synchronize receive stream rate to transmit stream rate */ | ||
89 | err = avc_general_set_sig_fmt(bebob->unit, rx_rate, | ||
90 | AVC_GENERAL_PLUG_DIR_IN, 0); | ||
91 | end: | ||
92 | return err; | ||
93 | } | ||
94 | |||
95 | int | ||
96 | snd_bebob_stream_set_rate(struct snd_bebob *bebob, unsigned int rate) | ||
97 | { | ||
98 | int err; | ||
99 | |||
100 | err = avc_general_set_sig_fmt(bebob->unit, rate, | ||
101 | AVC_GENERAL_PLUG_DIR_OUT, 0); | ||
102 | if (err < 0) | ||
103 | goto end; | ||
104 | |||
105 | err = avc_general_set_sig_fmt(bebob->unit, rate, | ||
106 | AVC_GENERAL_PLUG_DIR_IN, 0); | ||
107 | if (err < 0) | ||
108 | goto end; | ||
109 | |||
110 | /* | ||
111 | * Some devices need a bit time for transition. | ||
112 | * 300msec is got by some experiments. | ||
113 | */ | ||
114 | msleep(300); | ||
115 | end: | ||
116 | return err; | ||
117 | } | ||
118 | |||
119 | int | ||
120 | snd_bebob_stream_check_internal_clock(struct snd_bebob *bebob, bool *internal) | ||
121 | { | ||
122 | struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock; | ||
123 | u8 addr[AVC_BRIDGECO_ADDR_BYTES], input[7]; | ||
124 | unsigned int id; | ||
125 | int err = 0; | ||
126 | |||
127 | *internal = false; | ||
128 | |||
129 | /* 1.The device has its own operation to switch source of clock */ | ||
130 | if (clk_spec) { | ||
131 | err = clk_spec->get(bebob, &id); | ||
132 | if (err < 0) | ||
133 | dev_err(&bebob->unit->device, | ||
134 | "fail to get clock source: %d\n", err); | ||
135 | else if (strncmp(clk_spec->labels[id], SND_BEBOB_CLOCK_INTERNAL, | ||
136 | strlen(SND_BEBOB_CLOCK_INTERNAL)) == 0) | ||
137 | *internal = true; | ||
138 | goto end; | ||
139 | } | ||
140 | |||
141 | /* | ||
142 | * 2.The device don't support to switch source of clock then assumed | ||
143 | * to use internal clock always | ||
144 | */ | ||
145 | if (bebob->sync_input_plug < 0) { | ||
146 | *internal = true; | ||
147 | goto end; | ||
148 | } | ||
149 | |||
150 | /* | ||
151 | * 3.The device supports to switch source of clock by an usual way. | ||
152 | * Let's check input for 'Music Sub Unit Sync Input' plug. | ||
153 | */ | ||
154 | avc_bridgeco_fill_msu_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN, | ||
155 | bebob->sync_input_plug); | ||
156 | err = avc_bridgeco_get_plug_input(bebob->unit, addr, input); | ||
157 | if (err < 0) { | ||
158 | dev_err(&bebob->unit->device, | ||
159 | "fail to get an input for MSU in plug %d: %d\n", | ||
160 | bebob->sync_input_plug, err); | ||
161 | goto end; | ||
162 | } | ||
163 | |||
164 | /* | ||
165 | * If there are no input plugs, all of fields are 0xff. | ||
166 | * Here check the first field. This field is used for direction. | ||
167 | */ | ||
168 | if (input[0] == 0xff) { | ||
169 | *internal = true; | ||
170 | goto end; | ||
171 | } | ||
172 | |||
173 | /* | ||
174 | * If source of clock is internal CSR, Music Sub Unit Sync Input is | ||
175 | * a destination of Music Sub Unit Sync Output. | ||
176 | */ | ||
177 | *internal = ((input[0] == AVC_BRIDGECO_PLUG_DIR_OUT) && | ||
178 | (input[1] == AVC_BRIDGECO_PLUG_MODE_SUBUNIT) && | ||
179 | (input[2] == 0x0c) && | ||
180 | (input[3] == 0x00)); | ||
181 | end: | ||
182 | return err; | ||
183 | } | ||
184 | |||
185 | static unsigned int | ||
186 | map_data_channels(struct snd_bebob *bebob, struct amdtp_stream *s) | ||
187 | { | ||
188 | unsigned int sec, sections, ch, channels; | ||
189 | unsigned int pcm, midi, location; | ||
190 | unsigned int stm_pos, sec_loc, pos; | ||
191 | u8 *buf, addr[AVC_BRIDGECO_ADDR_BYTES], type; | ||
192 | enum avc_bridgeco_plug_dir dir; | ||
193 | int err; | ||
194 | |||
195 | /* | ||
196 | * The length of return value of this command cannot be expected. Here | ||
197 | * use the maximum length of FCP. | ||
198 | */ | ||
199 | buf = kzalloc(256, GFP_KERNEL); | ||
200 | if (buf == NULL) | ||
201 | return -ENOMEM; | ||
202 | |||
203 | if (s == &bebob->tx_stream) | ||
204 | dir = AVC_BRIDGECO_PLUG_DIR_OUT; | ||
205 | else | ||
206 | dir = AVC_BRIDGECO_PLUG_DIR_IN; | ||
207 | |||
208 | avc_bridgeco_fill_unit_addr(addr, dir, AVC_BRIDGECO_PLUG_UNIT_ISOC, 0); | ||
209 | err = avc_bridgeco_get_plug_ch_pos(bebob->unit, addr, buf, 256); | ||
210 | if (err < 0) { | ||
211 | dev_err(&bebob->unit->device, | ||
212 | "fail to get channel position for isoc %s plug 0: %d\n", | ||
213 | (dir == AVC_BRIDGECO_PLUG_DIR_IN) ? "in" : "out", | ||
214 | err); | ||
215 | goto end; | ||
216 | } | ||
217 | pos = 0; | ||
218 | |||
219 | /* positions in I/O buffer */ | ||
220 | pcm = 0; | ||
221 | midi = 0; | ||
222 | |||
223 | /* the number of sections in AMDTP packet */ | ||
224 | sections = buf[pos++]; | ||
225 | |||
226 | for (sec = 0; sec < sections; sec++) { | ||
227 | /* type of this section */ | ||
228 | avc_bridgeco_fill_unit_addr(addr, dir, | ||
229 | AVC_BRIDGECO_PLUG_UNIT_ISOC, 0); | ||
230 | err = avc_bridgeco_get_plug_section_type(bebob->unit, addr, | ||
231 | sec, &type); | ||
232 | if (err < 0) { | ||
233 | dev_err(&bebob->unit->device, | ||
234 | "fail to get section type for isoc %s plug 0: %d\n", | ||
235 | (dir == AVC_BRIDGECO_PLUG_DIR_IN) ? "in" : | ||
236 | "out", | ||
237 | err); | ||
238 | goto end; | ||
239 | } | ||
240 | /* NoType */ | ||
241 | if (type == 0xff) { | ||
242 | err = -ENOSYS; | ||
243 | goto end; | ||
244 | } | ||
245 | |||
246 | /* the number of channels in this section */ | ||
247 | channels = buf[pos++]; | ||
248 | |||
249 | for (ch = 0; ch < channels; ch++) { | ||
250 | /* position of this channel in AMDTP packet */ | ||
251 | stm_pos = buf[pos++] - 1; | ||
252 | /* location of this channel in this section */ | ||
253 | sec_loc = buf[pos++] - 1; | ||
254 | |||
255 | /* | ||
256 | * Basically the number of location is within the | ||
257 | * number of channels in this section. But some models | ||
258 | * of M-Audio don't follow this. Its location for MIDI | ||
259 | * is the position of MIDI channels in AMDTP packet. | ||
260 | */ | ||
261 | if (sec_loc >= channels) | ||
262 | sec_loc = ch; | ||
263 | |||
264 | switch (type) { | ||
265 | /* for MIDI conformant data channel */ | ||
266 | case 0x0a: | ||
267 | /* AMDTP_MAX_CHANNELS_FOR_MIDI is 1. */ | ||
268 | if ((midi > 0) && (stm_pos != midi)) { | ||
269 | err = -ENOSYS; | ||
270 | goto end; | ||
271 | } | ||
272 | s->midi_position = stm_pos; | ||
273 | midi = stm_pos; | ||
274 | break; | ||
275 | /* for PCM data channel */ | ||
276 | case 0x01: /* Headphone */ | ||
277 | case 0x02: /* Microphone */ | ||
278 | case 0x03: /* Line */ | ||
279 | case 0x04: /* SPDIF */ | ||
280 | case 0x05: /* ADAT */ | ||
281 | case 0x06: /* TDIF */ | ||
282 | case 0x07: /* MADI */ | ||
283 | /* for undefined/changeable signal */ | ||
284 | case 0x08: /* Analog */ | ||
285 | case 0x09: /* Digital */ | ||
286 | default: | ||
287 | location = pcm + sec_loc; | ||
288 | if (location >= AMDTP_MAX_CHANNELS_FOR_PCM) { | ||
289 | err = -ENOSYS; | ||
290 | goto end; | ||
291 | } | ||
292 | s->pcm_positions[location] = stm_pos; | ||
293 | break; | ||
294 | } | ||
295 | } | ||
296 | |||
297 | if (type != 0x0a) | ||
298 | pcm += channels; | ||
299 | else | ||
300 | midi += channels; | ||
301 | } | ||
302 | end: | ||
303 | kfree(buf); | ||
304 | return err; | ||
305 | } | ||
306 | |||
307 | static int | ||
308 | init_both_connections(struct snd_bebob *bebob) | ||
309 | { | ||
310 | int err; | ||
311 | |||
312 | err = cmp_connection_init(&bebob->in_conn, | ||
313 | bebob->unit, CMP_INPUT, 0); | ||
314 | if (err < 0) | ||
315 | goto end; | ||
316 | |||
317 | err = cmp_connection_init(&bebob->out_conn, | ||
318 | bebob->unit, CMP_OUTPUT, 0); | ||
319 | if (err < 0) | ||
320 | cmp_connection_destroy(&bebob->in_conn); | ||
321 | end: | ||
322 | return err; | ||
323 | } | ||
324 | |||
325 | static int | ||
326 | check_connection_used_by_others(struct snd_bebob *bebob, struct amdtp_stream *s) | ||
327 | { | ||
328 | struct cmp_connection *conn; | ||
329 | bool used; | ||
330 | int err; | ||
331 | |||
332 | if (s == &bebob->tx_stream) | ||
333 | conn = &bebob->out_conn; | ||
334 | else | ||
335 | conn = &bebob->in_conn; | ||
336 | |||
337 | err = cmp_connection_check_used(conn, &used); | ||
338 | if ((err >= 0) && used && !amdtp_stream_running(s)) { | ||
339 | dev_err(&bebob->unit->device, | ||
340 | "Connection established by others: %cPCR[%d]\n", | ||
341 | (conn->direction == CMP_OUTPUT) ? 'o' : 'i', | ||
342 | conn->pcr_index); | ||
343 | err = -EBUSY; | ||
344 | } | ||
345 | |||
346 | return err; | ||
347 | } | ||
348 | |||
349 | static int | ||
350 | make_both_connections(struct snd_bebob *bebob, unsigned int rate) | ||
351 | { | ||
352 | int index, pcm_channels, midi_channels, err = 0; | ||
353 | |||
354 | if (bebob->connected) | ||
355 | goto end; | ||
356 | |||
357 | /* confirm params for both streams */ | ||
358 | index = get_formation_index(rate); | ||
359 | pcm_channels = bebob->tx_stream_formations[index].pcm; | ||
360 | midi_channels = bebob->tx_stream_formations[index].midi; | ||
361 | amdtp_stream_set_parameters(&bebob->tx_stream, | ||
362 | rate, pcm_channels, midi_channels * 8); | ||
363 | pcm_channels = bebob->rx_stream_formations[index].pcm; | ||
364 | midi_channels = bebob->rx_stream_formations[index].midi; | ||
365 | amdtp_stream_set_parameters(&bebob->rx_stream, | ||
366 | rate, pcm_channels, midi_channels * 8); | ||
367 | |||
368 | /* establish connections for both streams */ | ||
369 | err = cmp_connection_establish(&bebob->out_conn, | ||
370 | amdtp_stream_get_max_payload(&bebob->tx_stream)); | ||
371 | if (err < 0) | ||
372 | goto end; | ||
373 | err = cmp_connection_establish(&bebob->in_conn, | ||
374 | amdtp_stream_get_max_payload(&bebob->rx_stream)); | ||
375 | if (err < 0) { | ||
376 | cmp_connection_break(&bebob->out_conn); | ||
377 | goto end; | ||
378 | } | ||
379 | |||
380 | bebob->connected = true; | ||
381 | end: | ||
382 | return err; | ||
383 | } | ||
384 | |||
385 | static void | ||
386 | break_both_connections(struct snd_bebob *bebob) | ||
387 | { | ||
388 | cmp_connection_break(&bebob->in_conn); | ||
389 | cmp_connection_break(&bebob->out_conn); | ||
390 | |||
391 | bebob->connected = false; | ||
392 | |||
393 | /* These models seems to be in transition state for a longer time. */ | ||
394 | if (bebob->maudio_special_quirk != NULL) | ||
395 | msleep(200); | ||
396 | } | ||
397 | |||
398 | static void | ||
399 | destroy_both_connections(struct snd_bebob *bebob) | ||
400 | { | ||
401 | break_both_connections(bebob); | ||
402 | |||
403 | cmp_connection_destroy(&bebob->in_conn); | ||
404 | cmp_connection_destroy(&bebob->out_conn); | ||
405 | } | ||
406 | |||
407 | static int | ||
408 | get_sync_mode(struct snd_bebob *bebob, enum cip_flags *sync_mode) | ||
409 | { | ||
410 | /* currently this module doesn't support SYT-Match mode */ | ||
411 | *sync_mode = CIP_SYNC_TO_DEVICE; | ||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | static int | ||
416 | start_stream(struct snd_bebob *bebob, struct amdtp_stream *stream, | ||
417 | unsigned int rate) | ||
418 | { | ||
419 | struct cmp_connection *conn; | ||
420 | int err = 0; | ||
421 | |||
422 | if (stream == &bebob->rx_stream) | ||
423 | conn = &bebob->in_conn; | ||
424 | else | ||
425 | conn = &bebob->out_conn; | ||
426 | |||
427 | /* channel mapping */ | ||
428 | if (bebob->maudio_special_quirk == NULL) { | ||
429 | err = map_data_channels(bebob, stream); | ||
430 | if (err < 0) | ||
431 | goto end; | ||
432 | } | ||
433 | |||
434 | /* start amdtp stream */ | ||
435 | err = amdtp_stream_start(stream, | ||
436 | conn->resources.channel, | ||
437 | conn->speed); | ||
438 | end: | ||
439 | return err; | ||
440 | } | ||
441 | |||
442 | int snd_bebob_stream_init_duplex(struct snd_bebob *bebob) | ||
443 | { | ||
444 | int err; | ||
445 | |||
446 | err = init_both_connections(bebob); | ||
447 | if (err < 0) | ||
448 | goto end; | ||
449 | |||
450 | err = amdtp_stream_init(&bebob->tx_stream, bebob->unit, | ||
451 | AMDTP_IN_STREAM, CIP_BLOCKING); | ||
452 | if (err < 0) { | ||
453 | amdtp_stream_destroy(&bebob->tx_stream); | ||
454 | destroy_both_connections(bebob); | ||
455 | goto end; | ||
456 | } | ||
457 | /* See comments in next function */ | ||
458 | init_completion(&bebob->bus_reset); | ||
459 | bebob->tx_stream.flags |= CIP_SKIP_INIT_DBC_CHECK; | ||
460 | /* | ||
461 | * At high sampling rate, M-Audio special firmware transmits empty | ||
462 | * packet with the value of dbc incremented by 8 but the others are | ||
463 | * valid to IEC 61883-1. | ||
464 | */ | ||
465 | if (bebob->maudio_special_quirk) | ||
466 | bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC; | ||
467 | |||
468 | err = amdtp_stream_init(&bebob->rx_stream, bebob->unit, | ||
469 | AMDTP_OUT_STREAM, CIP_BLOCKING); | ||
470 | if (err < 0) { | ||
471 | amdtp_stream_destroy(&bebob->tx_stream); | ||
472 | amdtp_stream_destroy(&bebob->rx_stream); | ||
473 | destroy_both_connections(bebob); | ||
474 | } | ||
475 | /* | ||
476 | * The firmware for these devices ignore MIDI messages in more than | ||
477 | * first 8 data blocks of an received AMDTP packet. | ||
478 | */ | ||
479 | if (bebob->spec == &maudio_fw410_spec || | ||
480 | bebob->spec == &maudio_special_spec) | ||
481 | bebob->rx_stream.rx_blocks_for_midi = 8; | ||
482 | end: | ||
483 | return err; | ||
484 | } | ||
485 | |||
486 | int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate) | ||
487 | { | ||
488 | struct snd_bebob_rate_spec *rate_spec = bebob->spec->rate; | ||
489 | struct amdtp_stream *master, *slave; | ||
490 | atomic_t *slave_substreams; | ||
491 | enum cip_flags sync_mode; | ||
492 | unsigned int curr_rate; | ||
493 | bool updated = false; | ||
494 | int err = 0; | ||
495 | |||
496 | /* | ||
497 | * Normal BeBoB firmware has a quirk at bus reset to transmits packets | ||
498 | * with discontinuous value in dbc field. | ||
499 | * | ||
500 | * This 'struct completion' is used to call .update() at first to update | ||
501 | * connections/streams. Next following codes handle streaming error. | ||
502 | */ | ||
503 | if (amdtp_streaming_error(&bebob->tx_stream)) { | ||
504 | if (completion_done(&bebob->bus_reset)) | ||
505 | reinit_completion(&bebob->bus_reset); | ||
506 | |||
507 | updated = (wait_for_completion_interruptible_timeout( | ||
508 | &bebob->bus_reset, | ||
509 | msecs_to_jiffies(FW_ISO_RESOURCE_DELAY)) > 0); | ||
510 | } | ||
511 | |||
512 | mutex_lock(&bebob->mutex); | ||
513 | |||
514 | /* Need no substreams */ | ||
515 | if (atomic_read(&bebob->playback_substreams) == 0 && | ||
516 | atomic_read(&bebob->capture_substreams) == 0) | ||
517 | goto end; | ||
518 | |||
519 | err = get_sync_mode(bebob, &sync_mode); | ||
520 | if (err < 0) | ||
521 | goto end; | ||
522 | if (sync_mode == CIP_SYNC_TO_DEVICE) { | ||
523 | master = &bebob->tx_stream; | ||
524 | slave = &bebob->rx_stream; | ||
525 | slave_substreams = &bebob->playback_substreams; | ||
526 | } else { | ||
527 | master = &bebob->rx_stream; | ||
528 | slave = &bebob->tx_stream; | ||
529 | slave_substreams = &bebob->capture_substreams; | ||
530 | } | ||
531 | |||
532 | /* | ||
533 | * Considering JACK/FFADO streaming: | ||
534 | * TODO: This can be removed hwdep functionality becomes popular. | ||
535 | */ | ||
536 | err = check_connection_used_by_others(bebob, master); | ||
537 | if (err < 0) | ||
538 | goto end; | ||
539 | |||
540 | /* | ||
541 | * packet queueing error or detecting discontinuity | ||
542 | * | ||
543 | * At bus reset, connections should not be broken here. So streams need | ||
544 | * to be re-started. This is a reason to use SKIP_INIT_DBC_CHECK flag. | ||
545 | */ | ||
546 | if (amdtp_streaming_error(master)) | ||
547 | amdtp_stream_stop(master); | ||
548 | if (amdtp_streaming_error(slave)) | ||
549 | amdtp_stream_stop(slave); | ||
550 | if (!updated && | ||
551 | !amdtp_stream_running(master) && !amdtp_stream_running(slave)) | ||
552 | break_both_connections(bebob); | ||
553 | |||
554 | /* stop streams if rate is different */ | ||
555 | err = rate_spec->get(bebob, &curr_rate); | ||
556 | if (err < 0) { | ||
557 | dev_err(&bebob->unit->device, | ||
558 | "fail to get sampling rate: %d\n", err); | ||
559 | goto end; | ||
560 | } | ||
561 | if (rate == 0) | ||
562 | rate = curr_rate; | ||
563 | if (rate != curr_rate) { | ||
564 | amdtp_stream_stop(master); | ||
565 | amdtp_stream_stop(slave); | ||
566 | break_both_connections(bebob); | ||
567 | } | ||
568 | |||
569 | /* master should be always running */ | ||
570 | if (!amdtp_stream_running(master)) { | ||
571 | amdtp_stream_set_sync(sync_mode, master, slave); | ||
572 | bebob->master = master; | ||
573 | |||
574 | /* | ||
575 | * NOTE: | ||
576 | * If establishing connections at first, Yamaha GO46 | ||
577 | * (and maybe Terratec X24) don't generate sound. | ||
578 | * | ||
579 | * For firmware customized by M-Audio, refer to next NOTE. | ||
580 | */ | ||
581 | if (bebob->maudio_special_quirk == NULL) { | ||
582 | err = rate_spec->set(bebob, rate); | ||
583 | if (err < 0) { | ||
584 | dev_err(&bebob->unit->device, | ||
585 | "fail to set sampling rate: %d\n", | ||
586 | err); | ||
587 | goto end; | ||
588 | } | ||
589 | } | ||
590 | |||
591 | err = make_both_connections(bebob, rate); | ||
592 | if (err < 0) | ||
593 | goto end; | ||
594 | |||
595 | err = start_stream(bebob, master, rate); | ||
596 | if (err < 0) { | ||
597 | dev_err(&bebob->unit->device, | ||
598 | "fail to run AMDTP master stream:%d\n", err); | ||
599 | break_both_connections(bebob); | ||
600 | goto end; | ||
601 | } | ||
602 | |||
603 | /* | ||
604 | * NOTE: | ||
605 | * The firmware customized by M-Audio uses these commands to | ||
606 | * start transmitting stream. This is not usual way. | ||
607 | */ | ||
608 | if (bebob->maudio_special_quirk != NULL) { | ||
609 | err = rate_spec->set(bebob, rate); | ||
610 | if (err < 0) { | ||
611 | dev_err(&bebob->unit->device, | ||
612 | "fail to ensure sampling rate: %d\n", | ||
613 | err); | ||
614 | amdtp_stream_stop(master); | ||
615 | break_both_connections(bebob); | ||
616 | goto end; | ||
617 | } | ||
618 | } | ||
619 | |||
620 | /* wait first callback */ | ||
621 | if (!amdtp_stream_wait_callback(master, CALLBACK_TIMEOUT)) { | ||
622 | amdtp_stream_stop(master); | ||
623 | break_both_connections(bebob); | ||
624 | err = -ETIMEDOUT; | ||
625 | goto end; | ||
626 | } | ||
627 | } | ||
628 | |||
629 | /* start slave if needed */ | ||
630 | if (atomic_read(slave_substreams) > 0 && !amdtp_stream_running(slave)) { | ||
631 | err = start_stream(bebob, slave, rate); | ||
632 | if (err < 0) { | ||
633 | dev_err(&bebob->unit->device, | ||
634 | "fail to run AMDTP slave stream:%d\n", err); | ||
635 | amdtp_stream_stop(master); | ||
636 | break_both_connections(bebob); | ||
637 | goto end; | ||
638 | } | ||
639 | |||
640 | /* wait first callback */ | ||
641 | if (!amdtp_stream_wait_callback(slave, CALLBACK_TIMEOUT)) { | ||
642 | amdtp_stream_stop(slave); | ||
643 | amdtp_stream_stop(master); | ||
644 | break_both_connections(bebob); | ||
645 | err = -ETIMEDOUT; | ||
646 | } | ||
647 | } | ||
648 | end: | ||
649 | mutex_unlock(&bebob->mutex); | ||
650 | return err; | ||
651 | } | ||
652 | |||
653 | void snd_bebob_stream_stop_duplex(struct snd_bebob *bebob) | ||
654 | { | ||
655 | struct amdtp_stream *master, *slave; | ||
656 | atomic_t *master_substreams, *slave_substreams; | ||
657 | |||
658 | mutex_lock(&bebob->mutex); | ||
659 | |||
660 | if (bebob->master == &bebob->rx_stream) { | ||
661 | slave = &bebob->tx_stream; | ||
662 | master = &bebob->rx_stream; | ||
663 | slave_substreams = &bebob->capture_substreams; | ||
664 | master_substreams = &bebob->playback_substreams; | ||
665 | } else { | ||
666 | slave = &bebob->rx_stream; | ||
667 | master = &bebob->tx_stream; | ||
668 | slave_substreams = &bebob->playback_substreams; | ||
669 | master_substreams = &bebob->capture_substreams; | ||
670 | } | ||
671 | |||
672 | if (atomic_read(slave_substreams) == 0) { | ||
673 | amdtp_stream_pcm_abort(slave); | ||
674 | amdtp_stream_stop(slave); | ||
675 | |||
676 | if (atomic_read(master_substreams) == 0) { | ||
677 | amdtp_stream_pcm_abort(master); | ||
678 | amdtp_stream_stop(master); | ||
679 | break_both_connections(bebob); | ||
680 | } | ||
681 | } | ||
682 | |||
683 | mutex_unlock(&bebob->mutex); | ||
684 | } | ||
685 | |||
686 | void snd_bebob_stream_update_duplex(struct snd_bebob *bebob) | ||
687 | { | ||
688 | /* vs. XRUN recovery due to discontinuity at bus reset */ | ||
689 | mutex_lock(&bebob->mutex); | ||
690 | |||
691 | if ((cmp_connection_update(&bebob->in_conn) < 0) || | ||
692 | (cmp_connection_update(&bebob->out_conn) < 0)) { | ||
693 | amdtp_stream_pcm_abort(&bebob->rx_stream); | ||
694 | amdtp_stream_pcm_abort(&bebob->tx_stream); | ||
695 | amdtp_stream_stop(&bebob->rx_stream); | ||
696 | amdtp_stream_stop(&bebob->tx_stream); | ||
697 | break_both_connections(bebob); | ||
698 | } else { | ||
699 | amdtp_stream_update(&bebob->rx_stream); | ||
700 | amdtp_stream_update(&bebob->tx_stream); | ||
701 | } | ||
702 | |||
703 | /* wake up stream_start_duplex() */ | ||
704 | if (!completion_done(&bebob->bus_reset)) | ||
705 | complete_all(&bebob->bus_reset); | ||
706 | |||
707 | mutex_unlock(&bebob->mutex); | ||
708 | } | ||
709 | |||
710 | void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob) | ||
711 | { | ||
712 | mutex_lock(&bebob->mutex); | ||
713 | |||
714 | amdtp_stream_pcm_abort(&bebob->rx_stream); | ||
715 | amdtp_stream_pcm_abort(&bebob->tx_stream); | ||
716 | |||
717 | amdtp_stream_stop(&bebob->rx_stream); | ||
718 | amdtp_stream_stop(&bebob->tx_stream); | ||
719 | |||
720 | amdtp_stream_destroy(&bebob->rx_stream); | ||
721 | amdtp_stream_destroy(&bebob->tx_stream); | ||
722 | |||
723 | destroy_both_connections(bebob); | ||
724 | |||
725 | mutex_unlock(&bebob->mutex); | ||
726 | } | ||
727 | |||
728 | /* | ||
729 | * See: Table 50: Extended Stream Format Info Format Hierarchy Level 2’ | ||
730 | * in Additional AVC commands (Nov 2003, BridgeCo) | ||
731 | * Also 'Clause 12 AM824 sequence adaption layers' in IEC 61883-6:2005 | ||
732 | */ | ||
733 | static int | ||
734 | parse_stream_formation(u8 *buf, unsigned int len, | ||
735 | struct snd_bebob_stream_formation *formation) | ||
736 | { | ||
737 | unsigned int i, e, channels, format; | ||
738 | |||
739 | /* | ||
740 | * this module can support a hierarchy combination that: | ||
741 | * Root: Audio and Music (0x90) | ||
742 | * Level 1: AM824 Compound (0x40) | ||
743 | */ | ||
744 | if ((buf[0] != 0x90) || (buf[1] != 0x40)) | ||
745 | return -ENOSYS; | ||
746 | |||
747 | /* check sampling rate */ | ||
748 | for (i = 0; i < ARRAY_SIZE(bridgeco_freq_table); i++) { | ||
749 | if (buf[2] == bridgeco_freq_table[i]) | ||
750 | break; | ||
751 | } | ||
752 | if (i == sizeof(bridgeco_freq_table)) | ||
753 | return -ENOSYS; | ||
754 | |||
755 | /* Avoid double count by different entries for the same rate. */ | ||
756 | memset(&formation[i], 0, sizeof(struct snd_bebob_stream_formation)); | ||
757 | |||
758 | for (e = 0; e < buf[4]; e++) { | ||
759 | channels = buf[5 + e * 2]; | ||
760 | format = buf[6 + e * 2]; | ||
761 | |||
762 | switch (format) { | ||
763 | /* IEC 60958 Conformant, currently handled as MBLA */ | ||
764 | case 0x00: | ||
765 | /* Multi bit linear audio */ | ||
766 | case 0x06: /* Raw */ | ||
767 | formation[i].pcm += channels; | ||
768 | break; | ||
769 | /* MIDI Conformant */ | ||
770 | case 0x0d: | ||
771 | formation[i].midi += channels; | ||
772 | break; | ||
773 | /* IEC 61937-3 to 7 */ | ||
774 | case 0x01: | ||
775 | case 0x02: | ||
776 | case 0x03: | ||
777 | case 0x04: | ||
778 | case 0x05: | ||
779 | /* Multi bit linear audio */ | ||
780 | case 0x07: /* DVD-Audio */ | ||
781 | case 0x0c: /* High Precision */ | ||
782 | /* One Bit Audio */ | ||
783 | case 0x08: /* (Plain) Raw */ | ||
784 | case 0x09: /* (Plain) SACD */ | ||
785 | case 0x0a: /* (Encoded) Raw */ | ||
786 | case 0x0b: /* (Encoded) SACD */ | ||
787 | /* Synchronization Stream (Stereo Raw audio) */ | ||
788 | case 0x40: | ||
789 | /* Don't care */ | ||
790 | case 0xff: | ||
791 | default: | ||
792 | return -ENOSYS; /* not supported */ | ||
793 | } | ||
794 | } | ||
795 | |||
796 | if (formation[i].pcm > AMDTP_MAX_CHANNELS_FOR_PCM || | ||
797 | formation[i].midi > AMDTP_MAX_CHANNELS_FOR_MIDI) | ||
798 | return -ENOSYS; | ||
799 | |||
800 | return 0; | ||
801 | } | ||
802 | |||
803 | static int | ||
804 | fill_stream_formations(struct snd_bebob *bebob, enum avc_bridgeco_plug_dir dir, | ||
805 | unsigned short pid) | ||
806 | { | ||
807 | u8 *buf; | ||
808 | struct snd_bebob_stream_formation *formations; | ||
809 | unsigned int len, eid; | ||
810 | u8 addr[AVC_BRIDGECO_ADDR_BYTES]; | ||
811 | int err; | ||
812 | |||
813 | buf = kmalloc(FORMAT_MAXIMUM_LENGTH, GFP_KERNEL); | ||
814 | if (buf == NULL) | ||
815 | return -ENOMEM; | ||
816 | |||
817 | if (dir == AVC_BRIDGECO_PLUG_DIR_IN) | ||
818 | formations = bebob->rx_stream_formations; | ||
819 | else | ||
820 | formations = bebob->tx_stream_formations; | ||
821 | |||
822 | for (eid = 0; eid < SND_BEBOB_STRM_FMT_ENTRIES; eid++) { | ||
823 | len = FORMAT_MAXIMUM_LENGTH; | ||
824 | avc_bridgeco_fill_unit_addr(addr, dir, | ||
825 | AVC_BRIDGECO_PLUG_UNIT_ISOC, pid); | ||
826 | err = avc_bridgeco_get_plug_strm_fmt(bebob->unit, addr, buf, | ||
827 | &len, eid); | ||
828 | /* No entries remained. */ | ||
829 | if (err == -EINVAL && eid > 0) { | ||
830 | err = 0; | ||
831 | break; | ||
832 | } else if (err < 0) { | ||
833 | dev_err(&bebob->unit->device, | ||
834 | "fail to get stream format %d for isoc %s plug %d:%d\n", | ||
835 | eid, | ||
836 | (dir == AVC_BRIDGECO_PLUG_DIR_IN) ? "in" : | ||
837 | "out", | ||
838 | pid, err); | ||
839 | break; | ||
840 | } | ||
841 | |||
842 | err = parse_stream_formation(buf, len, formations); | ||
843 | if (err < 0) | ||
844 | break; | ||
845 | } | ||
846 | |||
847 | kfree(buf); | ||
848 | return err; | ||
849 | } | ||
850 | |||
851 | static int | ||
852 | seek_msu_sync_input_plug(struct snd_bebob *bebob) | ||
853 | { | ||
854 | u8 plugs[AVC_PLUG_INFO_BUF_BYTES], addr[AVC_BRIDGECO_ADDR_BYTES]; | ||
855 | unsigned int i; | ||
856 | enum avc_bridgeco_plug_type type; | ||
857 | int err; | ||
858 | |||
859 | /* Get the number of Music Sub Unit for both direction. */ | ||
860 | err = avc_general_get_plug_info(bebob->unit, 0x0c, 0x00, 0x00, plugs); | ||
861 | if (err < 0) { | ||
862 | dev_err(&bebob->unit->device, | ||
863 | "fail to get info for MSU in/out plugs: %d\n", | ||
864 | err); | ||
865 | goto end; | ||
866 | } | ||
867 | |||
868 | /* seek destination plugs for 'MSU sync input' */ | ||
869 | bebob->sync_input_plug = -1; | ||
870 | for (i = 0; i < plugs[0]; i++) { | ||
871 | avc_bridgeco_fill_msu_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN, i); | ||
872 | err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type); | ||
873 | if (err < 0) { | ||
874 | dev_err(&bebob->unit->device, | ||
875 | "fail to get type for MSU in plug %d: %d\n", | ||
876 | i, err); | ||
877 | goto end; | ||
878 | } | ||
879 | |||
880 | if (type == AVC_BRIDGECO_PLUG_TYPE_SYNC) { | ||
881 | bebob->sync_input_plug = i; | ||
882 | break; | ||
883 | } | ||
884 | } | ||
885 | end: | ||
886 | return err; | ||
887 | } | ||
888 | |||
889 | int snd_bebob_stream_discover(struct snd_bebob *bebob) | ||
890 | { | ||
891 | struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock; | ||
892 | u8 plugs[AVC_PLUG_INFO_BUF_BYTES], addr[AVC_BRIDGECO_ADDR_BYTES]; | ||
893 | enum avc_bridgeco_plug_type type; | ||
894 | unsigned int i; | ||
895 | int err; | ||
896 | |||
897 | /* the number of plugs for isoc in/out, ext in/out */ | ||
898 | err = avc_general_get_plug_info(bebob->unit, 0x1f, 0x07, 0x00, plugs); | ||
899 | if (err < 0) { | ||
900 | dev_err(&bebob->unit->device, | ||
901 | "fail to get info for isoc/external in/out plugs: %d\n", | ||
902 | err); | ||
903 | goto end; | ||
904 | } | ||
905 | |||
906 | /* | ||
907 | * This module supports at least one isoc input plug and one isoc | ||
908 | * output plug. | ||
909 | */ | ||
910 | if ((plugs[0] == 0) || (plugs[1] == 0)) { | ||
911 | err = -ENOSYS; | ||
912 | goto end; | ||
913 | } | ||
914 | |||
915 | avc_bridgeco_fill_unit_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN, | ||
916 | AVC_BRIDGECO_PLUG_UNIT_ISOC, 0); | ||
917 | err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type); | ||
918 | if (err < 0) { | ||
919 | dev_err(&bebob->unit->device, | ||
920 | "fail to get type for isoc in plug 0: %d\n", err); | ||
921 | goto end; | ||
922 | } else if (type != AVC_BRIDGECO_PLUG_TYPE_ISOC) { | ||
923 | err = -ENOSYS; | ||
924 | goto end; | ||
925 | } | ||
926 | err = fill_stream_formations(bebob, AVC_BRIDGECO_PLUG_DIR_IN, 0); | ||
927 | if (err < 0) | ||
928 | goto end; | ||
929 | |||
930 | avc_bridgeco_fill_unit_addr(addr, AVC_BRIDGECO_PLUG_DIR_OUT, | ||
931 | AVC_BRIDGECO_PLUG_UNIT_ISOC, 0); | ||
932 | err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type); | ||
933 | if (err < 0) { | ||
934 | dev_err(&bebob->unit->device, | ||
935 | "fail to get type for isoc out plug 0: %d\n", err); | ||
936 | goto end; | ||
937 | } else if (type != AVC_BRIDGECO_PLUG_TYPE_ISOC) { | ||
938 | err = -ENOSYS; | ||
939 | goto end; | ||
940 | } | ||
941 | err = fill_stream_formations(bebob, AVC_BRIDGECO_PLUG_DIR_OUT, 0); | ||
942 | if (err < 0) | ||
943 | goto end; | ||
944 | |||
945 | /* count external input plugs for MIDI */ | ||
946 | bebob->midi_input_ports = 0; | ||
947 | for (i = 0; i < plugs[2]; i++) { | ||
948 | avc_bridgeco_fill_unit_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN, | ||
949 | AVC_BRIDGECO_PLUG_UNIT_EXT, i); | ||
950 | err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type); | ||
951 | if (err < 0) { | ||
952 | dev_err(&bebob->unit->device, | ||
953 | "fail to get type for external in plug %d: %d\n", | ||
954 | i, err); | ||
955 | goto end; | ||
956 | } else if (type == AVC_BRIDGECO_PLUG_TYPE_MIDI) { | ||
957 | bebob->midi_input_ports++; | ||
958 | } | ||
959 | } | ||
960 | |||
961 | /* count external output plugs for MIDI */ | ||
962 | bebob->midi_output_ports = 0; | ||
963 | for (i = 0; i < plugs[3]; i++) { | ||
964 | avc_bridgeco_fill_unit_addr(addr, AVC_BRIDGECO_PLUG_DIR_OUT, | ||
965 | AVC_BRIDGECO_PLUG_UNIT_EXT, i); | ||
966 | err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type); | ||
967 | if (err < 0) { | ||
968 | dev_err(&bebob->unit->device, | ||
969 | "fail to get type for external out plug %d: %d\n", | ||
970 | i, err); | ||
971 | goto end; | ||
972 | } else if (type == AVC_BRIDGECO_PLUG_TYPE_MIDI) { | ||
973 | bebob->midi_output_ports++; | ||
974 | } | ||
975 | } | ||
976 | |||
977 | /* for check source of clock later */ | ||
978 | if (!clk_spec) | ||
979 | err = seek_msu_sync_input_plug(bebob); | ||
980 | end: | ||
981 | return err; | ||
982 | } | ||
983 | |||
984 | void snd_bebob_stream_lock_changed(struct snd_bebob *bebob) | ||
985 | { | ||
986 | bebob->dev_lock_changed = true; | ||
987 | wake_up(&bebob->hwdep_wait); | ||
988 | } | ||
989 | |||
990 | int snd_bebob_stream_lock_try(struct snd_bebob *bebob) | ||
991 | { | ||
992 | int err; | ||
993 | |||
994 | spin_lock_irq(&bebob->lock); | ||
995 | |||
996 | /* user land lock this */ | ||
997 | if (bebob->dev_lock_count < 0) { | ||
998 | err = -EBUSY; | ||
999 | goto end; | ||
1000 | } | ||
1001 | |||
1002 | /* this is the first time */ | ||
1003 | if (bebob->dev_lock_count++ == 0) | ||
1004 | snd_bebob_stream_lock_changed(bebob); | ||
1005 | err = 0; | ||
1006 | end: | ||
1007 | spin_unlock_irq(&bebob->lock); | ||
1008 | return err; | ||
1009 | } | ||
1010 | |||
1011 | void snd_bebob_stream_lock_release(struct snd_bebob *bebob) | ||
1012 | { | ||
1013 | spin_lock_irq(&bebob->lock); | ||
1014 | |||
1015 | if (WARN_ON(bebob->dev_lock_count <= 0)) | ||
1016 | goto end; | ||
1017 | if (--bebob->dev_lock_count == 0) | ||
1018 | snd_bebob_stream_lock_changed(bebob); | ||
1019 | end: | ||
1020 | spin_unlock_irq(&bebob->lock); | ||
1021 | } | ||
diff --git a/sound/firewire/bebob/bebob_terratec.c b/sound/firewire/bebob/bebob_terratec.c new file mode 100644 index 000000000000..eef8ea7d9b97 --- /dev/null +++ b/sound/firewire/bebob/bebob_terratec.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * bebob_terratec.c - a part of driver for BeBoB based devices | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | #include "./bebob.h" | ||
10 | |||
11 | static char *const phase88_rack_clk_src_labels[] = { | ||
12 | SND_BEBOB_CLOCK_INTERNAL, "Digital In", "Word Clock" | ||
13 | }; | ||
14 | static int | ||
15 | phase88_rack_clk_src_get(struct snd_bebob *bebob, unsigned int *id) | ||
16 | { | ||
17 | unsigned int enable_ext, enable_word; | ||
18 | int err; | ||
19 | |||
20 | err = avc_audio_get_selector(bebob->unit, 0, 0, &enable_ext); | ||
21 | if (err < 0) | ||
22 | goto end; | ||
23 | err = avc_audio_get_selector(bebob->unit, 0, 0, &enable_word); | ||
24 | if (err < 0) | ||
25 | goto end; | ||
26 | |||
27 | *id = (enable_ext & 0x01) | ((enable_word & 0x01) << 1); | ||
28 | end: | ||
29 | return err; | ||
30 | } | ||
31 | |||
32 | static char *const phase24_series_clk_src_labels[] = { | ||
33 | SND_BEBOB_CLOCK_INTERNAL, "Digital In" | ||
34 | }; | ||
35 | static int | ||
36 | phase24_series_clk_src_get(struct snd_bebob *bebob, unsigned int *id) | ||
37 | { | ||
38 | return avc_audio_get_selector(bebob->unit, 0, 4, id); | ||
39 | } | ||
40 | |||
41 | static struct snd_bebob_rate_spec phase_series_rate_spec = { | ||
42 | .get = &snd_bebob_stream_get_rate, | ||
43 | .set = &snd_bebob_stream_set_rate, | ||
44 | }; | ||
45 | |||
46 | /* PHASE 88 Rack FW */ | ||
47 | static struct snd_bebob_clock_spec phase88_rack_clk = { | ||
48 | .num = ARRAY_SIZE(phase88_rack_clk_src_labels), | ||
49 | .labels = phase88_rack_clk_src_labels, | ||
50 | .get = &phase88_rack_clk_src_get, | ||
51 | }; | ||
52 | struct snd_bebob_spec phase88_rack_spec = { | ||
53 | .clock = &phase88_rack_clk, | ||
54 | .rate = &phase_series_rate_spec, | ||
55 | .meter = NULL | ||
56 | }; | ||
57 | |||
58 | /* 'PHASE 24 FW' and 'PHASE X24 FW' */ | ||
59 | static struct snd_bebob_clock_spec phase24_series_clk = { | ||
60 | .num = ARRAY_SIZE(phase24_series_clk_src_labels), | ||
61 | .labels = phase24_series_clk_src_labels, | ||
62 | .get = &phase24_series_clk_src_get, | ||
63 | }; | ||
64 | struct snd_bebob_spec phase24_series_spec = { | ||
65 | .clock = &phase24_series_clk, | ||
66 | .rate = &phase_series_rate_spec, | ||
67 | .meter = NULL | ||
68 | }; | ||
diff --git a/sound/firewire/bebob/bebob_yamaha.c b/sound/firewire/bebob/bebob_yamaha.c new file mode 100644 index 000000000000..9b7e798180ff --- /dev/null +++ b/sound/firewire/bebob/bebob_yamaha.c | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * bebob_yamaha.c - a part of driver for BeBoB based devices | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | #include "./bebob.h" | ||
10 | |||
11 | /* | ||
12 | * NOTE: | ||
13 | * Yamaha GO44 is not designed to be used as stand-alone mixer. So any streams | ||
14 | * must be accompanied. If changing the state, a LED on the device starts to | ||
15 | * blink and its sync status is false. In this state, the device sounds nothing | ||
16 | * even if streaming. To start streaming at the current sampling rate is only | ||
17 | * way to revocer this state. GO46 is better for stand-alone mixer. | ||
18 | * | ||
19 | * Both of them have a capability to change its sampling rate up to 192.0kHz. | ||
20 | * At 192.0kHz, the device reports 4 PCM-in, 1 MIDI-in, 6 PCM-out, 1 MIDI-out. | ||
21 | * But Yamaha's driver reduce 2 PCM-in, 1 MIDI-in, 2 PCM-out, 1 MIDI-out to use | ||
22 | * 'Extended Stream Format Information Command - Single Request' in 'Additional | ||
23 | * AVC commands' defined by BridgeCo. | ||
24 | * This ALSA driver don't do this because a bit tiresome. Then isochronous | ||
25 | * streaming with many asynchronous transactions brings sounds with noises. | ||
26 | * Unfortunately current 'ffado-mixer' generated many asynchronous transaction | ||
27 | * to observe device's state, mainly check cmp connection and signal format. I | ||
28 | * reccomend users to close ffado-mixer at 192.0kHz if mixer is needless. | ||
29 | */ | ||
30 | |||
31 | static char *const clk_src_labels[] = {SND_BEBOB_CLOCK_INTERNAL, "SPDIF"}; | ||
32 | static int | ||
33 | clk_src_get(struct snd_bebob *bebob, unsigned int *id) | ||
34 | { | ||
35 | return avc_audio_get_selector(bebob->unit, 0, 4, id); | ||
36 | } | ||
37 | static struct snd_bebob_clock_spec clock_spec = { | ||
38 | .num = ARRAY_SIZE(clk_src_labels), | ||
39 | .labels = clk_src_labels, | ||
40 | .get = &clk_src_get, | ||
41 | }; | ||
42 | static struct snd_bebob_rate_spec rate_spec = { | ||
43 | .get = &snd_bebob_stream_get_rate, | ||
44 | .set = &snd_bebob_stream_set_rate, | ||
45 | }; | ||
46 | struct snd_bebob_spec yamaha_go_spec = { | ||
47 | .clock = &clock_spec, | ||
48 | .rate = &rate_spec, | ||
49 | .meter = NULL | ||
50 | }; | ||
diff --git a/sound/firewire/cmp.c b/sound/firewire/cmp.c index efdbf585e404..ba8df5a1be39 100644 --- a/sound/firewire/cmp.c +++ b/sound/firewire/cmp.c | |||
@@ -14,18 +14,28 @@ | |||
14 | #include "iso-resources.h" | 14 | #include "iso-resources.h" |
15 | #include "cmp.h" | 15 | #include "cmp.h" |
16 | 16 | ||
17 | #define IMPR_SPEED_MASK 0xc0000000 | 17 | /* MPR common fields */ |
18 | #define IMPR_SPEED_SHIFT 30 | 18 | #define MPR_SPEED_MASK 0xc0000000 |
19 | #define IMPR_XSPEED_MASK 0x00000060 | 19 | #define MPR_SPEED_SHIFT 30 |
20 | #define IMPR_XSPEED_SHIFT 5 | 20 | #define MPR_XSPEED_MASK 0x00000060 |
21 | #define IMPR_PLUGS_MASK 0x0000001f | 21 | #define MPR_XSPEED_SHIFT 5 |
22 | 22 | #define MPR_PLUGS_MASK 0x0000001f | |
23 | #define IPCR_ONLINE 0x80000000 | 23 | |
24 | #define IPCR_BCAST_CONN 0x40000000 | 24 | /* PCR common fields */ |
25 | #define IPCR_P2P_CONN_MASK 0x3f000000 | 25 | #define PCR_ONLINE 0x80000000 |
26 | #define IPCR_P2P_CONN_SHIFT 24 | 26 | #define PCR_BCAST_CONN 0x40000000 |
27 | #define IPCR_CHANNEL_MASK 0x003f0000 | 27 | #define PCR_P2P_CONN_MASK 0x3f000000 |
28 | #define IPCR_CHANNEL_SHIFT 16 | 28 | #define PCR_P2P_CONN_SHIFT 24 |
29 | #define PCR_CHANNEL_MASK 0x003f0000 | ||
30 | #define PCR_CHANNEL_SHIFT 16 | ||
31 | |||
32 | /* oPCR specific fields */ | ||
33 | #define OPCR_XSPEED_MASK 0x00C00000 | ||
34 | #define OPCR_XSPEED_SHIFT 22 | ||
35 | #define OPCR_SPEED_MASK 0x0000C000 | ||
36 | #define OPCR_SPEED_SHIFT 14 | ||
37 | #define OPCR_OVERHEAD_ID_MASK 0x00003C00 | ||
38 | #define OPCR_OVERHEAD_ID_SHIFT 10 | ||
29 | 39 | ||
30 | enum bus_reset_handling { | 40 | enum bus_reset_handling { |
31 | ABORT_ON_BUS_RESET, | 41 | ABORT_ON_BUS_RESET, |
@@ -39,10 +49,27 @@ void cmp_error(struct cmp_connection *c, const char *fmt, ...) | |||
39 | 49 | ||
40 | va_start(va, fmt); | 50 | va_start(va, fmt); |
41 | dev_err(&c->resources.unit->device, "%cPCR%u: %pV", | 51 | dev_err(&c->resources.unit->device, "%cPCR%u: %pV", |
42 | 'i', c->pcr_index, &(struct va_format){ fmt, &va }); | 52 | (c->direction == CMP_INPUT) ? 'i' : 'o', |
53 | c->pcr_index, &(struct va_format){ fmt, &va }); | ||
43 | va_end(va); | 54 | va_end(va); |
44 | } | 55 | } |
45 | 56 | ||
57 | static u64 mpr_address(struct cmp_connection *c) | ||
58 | { | ||
59 | if (c->direction == CMP_INPUT) | ||
60 | return CSR_REGISTER_BASE + CSR_IMPR; | ||
61 | else | ||
62 | return CSR_REGISTER_BASE + CSR_OMPR; | ||
63 | } | ||
64 | |||
65 | static u64 pcr_address(struct cmp_connection *c) | ||
66 | { | ||
67 | if (c->direction == CMP_INPUT) | ||
68 | return CSR_REGISTER_BASE + CSR_IPCR(c->pcr_index); | ||
69 | else | ||
70 | return CSR_REGISTER_BASE + CSR_OPCR(c->pcr_index); | ||
71 | } | ||
72 | |||
46 | static int pcr_modify(struct cmp_connection *c, | 73 | static int pcr_modify(struct cmp_connection *c, |
47 | __be32 (*modify)(struct cmp_connection *c, __be32 old), | 74 | __be32 (*modify)(struct cmp_connection *c, __be32 old), |
48 | int (*check)(struct cmp_connection *c, __be32 pcr), | 75 | int (*check)(struct cmp_connection *c, __be32 pcr), |
@@ -58,8 +85,7 @@ static int pcr_modify(struct cmp_connection *c, | |||
58 | 85 | ||
59 | err = snd_fw_transaction( | 86 | err = snd_fw_transaction( |
60 | c->resources.unit, TCODE_LOCK_COMPARE_SWAP, | 87 | c->resources.unit, TCODE_LOCK_COMPARE_SWAP, |
61 | CSR_REGISTER_BASE + CSR_IPCR(c->pcr_index), | 88 | pcr_address(c), buffer, 8, |
62 | buffer, 8, | ||
63 | FW_FIXED_GENERATION | c->resources.generation); | 89 | FW_FIXED_GENERATION | c->resources.generation); |
64 | 90 | ||
65 | if (err < 0) { | 91 | if (err < 0) { |
@@ -88,24 +114,25 @@ static int pcr_modify(struct cmp_connection *c, | |||
88 | * cmp_connection_init - initializes a connection manager | 114 | * cmp_connection_init - initializes a connection manager |
89 | * @c: the connection manager to initialize | 115 | * @c: the connection manager to initialize |
90 | * @unit: a unit of the target device | 116 | * @unit: a unit of the target device |
91 | * @ipcr_index: the index of the iPCR on the target device | 117 | * @pcr_index: the index of the iPCR/oPCR on the target device |
92 | */ | 118 | */ |
93 | int cmp_connection_init(struct cmp_connection *c, | 119 | int cmp_connection_init(struct cmp_connection *c, |
94 | struct fw_unit *unit, | 120 | struct fw_unit *unit, |
95 | unsigned int ipcr_index) | 121 | enum cmp_direction direction, |
122 | unsigned int pcr_index) | ||
96 | { | 123 | { |
97 | __be32 impr_be; | 124 | __be32 mpr_be; |
98 | u32 impr; | 125 | u32 mpr; |
99 | int err; | 126 | int err; |
100 | 127 | ||
128 | c->direction = direction; | ||
101 | err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST, | 129 | err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST, |
102 | CSR_REGISTER_BASE + CSR_IMPR, | 130 | mpr_address(c), &mpr_be, 4, 0); |
103 | &impr_be, 4, 0); | ||
104 | if (err < 0) | 131 | if (err < 0) |
105 | return err; | 132 | return err; |
106 | impr = be32_to_cpu(impr_be); | 133 | mpr = be32_to_cpu(mpr_be); |
107 | 134 | ||
108 | if (ipcr_index >= (impr & IMPR_PLUGS_MASK)) | 135 | if (pcr_index >= (mpr & MPR_PLUGS_MASK)) |
109 | return -EINVAL; | 136 | return -EINVAL; |
110 | 137 | ||
111 | err = fw_iso_resources_init(&c->resources, unit); | 138 | err = fw_iso_resources_init(&c->resources, unit); |
@@ -115,16 +142,36 @@ int cmp_connection_init(struct cmp_connection *c, | |||
115 | c->connected = false; | 142 | c->connected = false; |
116 | mutex_init(&c->mutex); | 143 | mutex_init(&c->mutex); |
117 | c->last_pcr_value = cpu_to_be32(0x80000000); | 144 | c->last_pcr_value = cpu_to_be32(0x80000000); |
118 | c->pcr_index = ipcr_index; | 145 | c->pcr_index = pcr_index; |
119 | c->max_speed = (impr & IMPR_SPEED_MASK) >> IMPR_SPEED_SHIFT; | 146 | c->max_speed = (mpr & MPR_SPEED_MASK) >> MPR_SPEED_SHIFT; |
120 | if (c->max_speed == SCODE_BETA) | 147 | if (c->max_speed == SCODE_BETA) |
121 | c->max_speed += (impr & IMPR_XSPEED_MASK) >> IMPR_XSPEED_SHIFT; | 148 | c->max_speed += (mpr & MPR_XSPEED_MASK) >> MPR_XSPEED_SHIFT; |
122 | 149 | ||
123 | return 0; | 150 | return 0; |
124 | } | 151 | } |
125 | EXPORT_SYMBOL(cmp_connection_init); | 152 | EXPORT_SYMBOL(cmp_connection_init); |
126 | 153 | ||
127 | /** | 154 | /** |
155 | * cmp_connection_check_used - check connection is already esablished or not | ||
156 | * @c: the connection manager to be checked | ||
157 | */ | ||
158 | int cmp_connection_check_used(struct cmp_connection *c, bool *used) | ||
159 | { | ||
160 | __be32 pcr; | ||
161 | int err; | ||
162 | |||
163 | err = snd_fw_transaction( | ||
164 | c->resources.unit, TCODE_READ_QUADLET_REQUEST, | ||
165 | pcr_address(c), &pcr, 4, 0); | ||
166 | if (err >= 0) | ||
167 | *used = !!(pcr & cpu_to_be32(PCR_BCAST_CONN | | ||
168 | PCR_P2P_CONN_MASK)); | ||
169 | |||
170 | return err; | ||
171 | } | ||
172 | EXPORT_SYMBOL(cmp_connection_check_used); | ||
173 | |||
174 | /** | ||
128 | * cmp_connection_destroy - free connection manager resources | 175 | * cmp_connection_destroy - free connection manager resources |
129 | * @c: the connection manager | 176 | * @c: the connection manager |
130 | */ | 177 | */ |
@@ -139,23 +186,70 @@ EXPORT_SYMBOL(cmp_connection_destroy); | |||
139 | 186 | ||
140 | static __be32 ipcr_set_modify(struct cmp_connection *c, __be32 ipcr) | 187 | static __be32 ipcr_set_modify(struct cmp_connection *c, __be32 ipcr) |
141 | { | 188 | { |
142 | ipcr &= ~cpu_to_be32(IPCR_BCAST_CONN | | 189 | ipcr &= ~cpu_to_be32(PCR_BCAST_CONN | |
143 | IPCR_P2P_CONN_MASK | | 190 | PCR_P2P_CONN_MASK | |
144 | IPCR_CHANNEL_MASK); | 191 | PCR_CHANNEL_MASK); |
145 | ipcr |= cpu_to_be32(1 << IPCR_P2P_CONN_SHIFT); | 192 | ipcr |= cpu_to_be32(1 << PCR_P2P_CONN_SHIFT); |
146 | ipcr |= cpu_to_be32(c->resources.channel << IPCR_CHANNEL_SHIFT); | 193 | ipcr |= cpu_to_be32(c->resources.channel << PCR_CHANNEL_SHIFT); |
147 | 194 | ||
148 | return ipcr; | 195 | return ipcr; |
149 | } | 196 | } |
150 | 197 | ||
151 | static int ipcr_set_check(struct cmp_connection *c, __be32 ipcr) | 198 | static int get_overhead_id(struct cmp_connection *c) |
152 | { | 199 | { |
153 | if (ipcr & cpu_to_be32(IPCR_BCAST_CONN | | 200 | int id; |
154 | IPCR_P2P_CONN_MASK)) { | 201 | |
202 | /* | ||
203 | * apply "oPCR overhead ID encoding" | ||
204 | * the encoding table can convert up to 512. | ||
205 | * here the value over 512 is converted as the same way as 512. | ||
206 | */ | ||
207 | for (id = 1; id < 16; id++) { | ||
208 | if (c->resources.bandwidth_overhead < (id << 5)) | ||
209 | break; | ||
210 | } | ||
211 | if (id == 16) | ||
212 | id = 0; | ||
213 | |||
214 | return id; | ||
215 | } | ||
216 | |||
217 | static __be32 opcr_set_modify(struct cmp_connection *c, __be32 opcr) | ||
218 | { | ||
219 | unsigned int spd, xspd; | ||
220 | |||
221 | /* generate speed and extended speed field value */ | ||
222 | if (c->speed > SCODE_400) { | ||
223 | spd = SCODE_800; | ||
224 | xspd = c->speed - SCODE_800; | ||
225 | } else { | ||
226 | spd = c->speed; | ||
227 | xspd = 0; | ||
228 | } | ||
229 | |||
230 | opcr &= ~cpu_to_be32(PCR_BCAST_CONN | | ||
231 | PCR_P2P_CONN_MASK | | ||
232 | OPCR_XSPEED_MASK | | ||
233 | PCR_CHANNEL_MASK | | ||
234 | OPCR_SPEED_MASK | | ||
235 | OPCR_OVERHEAD_ID_MASK); | ||
236 | opcr |= cpu_to_be32(1 << PCR_P2P_CONN_SHIFT); | ||
237 | opcr |= cpu_to_be32(xspd << OPCR_XSPEED_SHIFT); | ||
238 | opcr |= cpu_to_be32(c->resources.channel << PCR_CHANNEL_SHIFT); | ||
239 | opcr |= cpu_to_be32(spd << OPCR_SPEED_SHIFT); | ||
240 | opcr |= cpu_to_be32(get_overhead_id(c) << OPCR_OVERHEAD_ID_SHIFT); | ||
241 | |||
242 | return opcr; | ||
243 | } | ||
244 | |||
245 | static int pcr_set_check(struct cmp_connection *c, __be32 pcr) | ||
246 | { | ||
247 | if (pcr & cpu_to_be32(PCR_BCAST_CONN | | ||
248 | PCR_P2P_CONN_MASK)) { | ||
155 | cmp_error(c, "plug is already in use\n"); | 249 | cmp_error(c, "plug is already in use\n"); |
156 | return -EBUSY; | 250 | return -EBUSY; |
157 | } | 251 | } |
158 | if (!(ipcr & cpu_to_be32(IPCR_ONLINE))) { | 252 | if (!(pcr & cpu_to_be32(PCR_ONLINE))) { |
159 | cmp_error(c, "plug is not on-line\n"); | 253 | cmp_error(c, "plug is not on-line\n"); |
160 | return -ECONNREFUSED; | 254 | return -ECONNREFUSED; |
161 | } | 255 | } |
@@ -170,9 +264,9 @@ static int ipcr_set_check(struct cmp_connection *c, __be32 ipcr) | |||
170 | * | 264 | * |
171 | * This function establishes a point-to-point connection from the local | 265 | * This function establishes a point-to-point connection from the local |
172 | * computer to the target by allocating isochronous resources (channel and | 266 | * computer to the target by allocating isochronous resources (channel and |
173 | * bandwidth) and setting the target's input plug control register. When this | 267 | * bandwidth) and setting the target's input/output plug control register. |
174 | * function succeeds, the caller is responsible for starting transmitting | 268 | * When this function succeeds, the caller is responsible for starting |
175 | * packets. | 269 | * transmitting packets. |
176 | */ | 270 | */ |
177 | int cmp_connection_establish(struct cmp_connection *c, | 271 | int cmp_connection_establish(struct cmp_connection *c, |
178 | unsigned int max_payload_bytes) | 272 | unsigned int max_payload_bytes) |
@@ -193,8 +287,13 @@ retry_after_bus_reset: | |||
193 | if (err < 0) | 287 | if (err < 0) |
194 | goto err_mutex; | 288 | goto err_mutex; |
195 | 289 | ||
196 | err = pcr_modify(c, ipcr_set_modify, ipcr_set_check, | 290 | if (c->direction == CMP_OUTPUT) |
197 | ABORT_ON_BUS_RESET); | 291 | err = pcr_modify(c, opcr_set_modify, pcr_set_check, |
292 | ABORT_ON_BUS_RESET); | ||
293 | else | ||
294 | err = pcr_modify(c, ipcr_set_modify, pcr_set_check, | ||
295 | ABORT_ON_BUS_RESET); | ||
296 | |||
198 | if (err == -EAGAIN) { | 297 | if (err == -EAGAIN) { |
199 | fw_iso_resources_free(&c->resources); | 298 | fw_iso_resources_free(&c->resources); |
200 | goto retry_after_bus_reset; | 299 | goto retry_after_bus_reset; |
@@ -221,8 +320,8 @@ EXPORT_SYMBOL(cmp_connection_establish); | |||
221 | * cmp_connection_update - update the connection after a bus reset | 320 | * cmp_connection_update - update the connection after a bus reset |
222 | * @c: the connection manager | 321 | * @c: the connection manager |
223 | * | 322 | * |
224 | * This function must be called from the driver's .update handler to reestablish | 323 | * This function must be called from the driver's .update handler to |
225 | * any connection that might have been active. | 324 | * reestablish any connection that might have been active. |
226 | * | 325 | * |
227 | * Returns zero on success, or a negative error code. On an error, the | 326 | * Returns zero on success, or a negative error code. On an error, the |
228 | * connection is broken and the caller must stop transmitting iso packets. | 327 | * connection is broken and the caller must stop transmitting iso packets. |
@@ -242,8 +341,13 @@ int cmp_connection_update(struct cmp_connection *c) | |||
242 | if (err < 0) | 341 | if (err < 0) |
243 | goto err_unconnect; | 342 | goto err_unconnect; |
244 | 343 | ||
245 | err = pcr_modify(c, ipcr_set_modify, ipcr_set_check, | 344 | if (c->direction == CMP_OUTPUT) |
246 | SUCCEED_ON_BUS_RESET); | 345 | err = pcr_modify(c, opcr_set_modify, pcr_set_check, |
346 | SUCCEED_ON_BUS_RESET); | ||
347 | else | ||
348 | err = pcr_modify(c, ipcr_set_modify, pcr_set_check, | ||
349 | SUCCEED_ON_BUS_RESET); | ||
350 | |||
247 | if (err < 0) | 351 | if (err < 0) |
248 | goto err_resources; | 352 | goto err_resources; |
249 | 353 | ||
@@ -261,19 +365,18 @@ err_unconnect: | |||
261 | } | 365 | } |
262 | EXPORT_SYMBOL(cmp_connection_update); | 366 | EXPORT_SYMBOL(cmp_connection_update); |
263 | 367 | ||
264 | 368 | static __be32 pcr_break_modify(struct cmp_connection *c, __be32 pcr) | |
265 | static __be32 ipcr_break_modify(struct cmp_connection *c, __be32 ipcr) | ||
266 | { | 369 | { |
267 | return ipcr & ~cpu_to_be32(IPCR_BCAST_CONN | IPCR_P2P_CONN_MASK); | 370 | return pcr & ~cpu_to_be32(PCR_BCAST_CONN | PCR_P2P_CONN_MASK); |
268 | } | 371 | } |
269 | 372 | ||
270 | /** | 373 | /** |
271 | * cmp_connection_break - break the connection to the target | 374 | * cmp_connection_break - break the connection to the target |
272 | * @c: the connection manager | 375 | * @c: the connection manager |
273 | * | 376 | * |
274 | * This function deactives the connection in the target's input plug control | 377 | * This function deactives the connection in the target's input/output plug |
275 | * register, and frees the isochronous resources of the connection. Before | 378 | * control register, and frees the isochronous resources of the connection. |
276 | * calling this function, the caller should cease transmitting packets. | 379 | * Before calling this function, the caller should cease transmitting packets. |
277 | */ | 380 | */ |
278 | void cmp_connection_break(struct cmp_connection *c) | 381 | void cmp_connection_break(struct cmp_connection *c) |
279 | { | 382 | { |
@@ -286,7 +389,7 @@ void cmp_connection_break(struct cmp_connection *c) | |||
286 | return; | 389 | return; |
287 | } | 390 | } |
288 | 391 | ||
289 | err = pcr_modify(c, ipcr_break_modify, NULL, SUCCEED_ON_BUS_RESET); | 392 | err = pcr_modify(c, pcr_break_modify, NULL, SUCCEED_ON_BUS_RESET); |
290 | if (err < 0) | 393 | if (err < 0) |
291 | cmp_error(c, "plug is still connected\n"); | 394 | cmp_error(c, "plug is still connected\n"); |
292 | 395 | ||
diff --git a/sound/firewire/cmp.h b/sound/firewire/cmp.h index f47de08feb12..ebcb48484fca 100644 --- a/sound/firewire/cmp.h +++ b/sound/firewire/cmp.h | |||
@@ -7,12 +7,17 @@ | |||
7 | 7 | ||
8 | struct fw_unit; | 8 | struct fw_unit; |
9 | 9 | ||
10 | enum cmp_direction { | ||
11 | CMP_INPUT = 0, | ||
12 | CMP_OUTPUT, | ||
13 | }; | ||
14 | |||
10 | /** | 15 | /** |
11 | * struct cmp_connection - manages an isochronous connection to a device | 16 | * struct cmp_connection - manages an isochronous connection to a device |
12 | * @speed: the connection's actual speed | 17 | * @speed: the connection's actual speed |
13 | * | 18 | * |
14 | * This structure manages (using CMP) an isochronous stream from the local | 19 | * This structure manages (using CMP) an isochronous stream between the local |
15 | * computer to a device's input plug (iPCR). | 20 | * computer and a device's input plug (iPCR) and output plug (oPCR). |
16 | * | 21 | * |
17 | * There is no corresponding oPCR created on the local computer, so it is not | 22 | * There is no corresponding oPCR created on the local computer, so it is not |
18 | * possible to overlay connections on top of this one. | 23 | * possible to overlay connections on top of this one. |
@@ -26,11 +31,14 @@ struct cmp_connection { | |||
26 | __be32 last_pcr_value; | 31 | __be32 last_pcr_value; |
27 | unsigned int pcr_index; | 32 | unsigned int pcr_index; |
28 | unsigned int max_speed; | 33 | unsigned int max_speed; |
34 | enum cmp_direction direction; | ||
29 | }; | 35 | }; |
30 | 36 | ||
31 | int cmp_connection_init(struct cmp_connection *connection, | 37 | int cmp_connection_init(struct cmp_connection *connection, |
32 | struct fw_unit *unit, | 38 | struct fw_unit *unit, |
33 | unsigned int ipcr_index); | 39 | enum cmp_direction direction, |
40 | unsigned int pcr_index); | ||
41 | int cmp_connection_check_used(struct cmp_connection *connection, bool *used); | ||
34 | void cmp_connection_destroy(struct cmp_connection *connection); | 42 | void cmp_connection_destroy(struct cmp_connection *connection); |
35 | 43 | ||
36 | int cmp_connection_establish(struct cmp_connection *connection, | 44 | int cmp_connection_establish(struct cmp_connection *connection, |
diff --git a/sound/firewire/dice.c b/sound/firewire/dice.c index 0c3948630cf7..a9a30c0161f1 100644 --- a/sound/firewire/dice.c +++ b/sound/firewire/dice.c | |||
@@ -51,7 +51,7 @@ struct dice { | |||
51 | wait_queue_head_t hwdep_wait; | 51 | wait_queue_head_t hwdep_wait; |
52 | u32 notification_bits; | 52 | u32 notification_bits; |
53 | struct fw_iso_resources resources; | 53 | struct fw_iso_resources resources; |
54 | struct amdtp_out_stream stream; | 54 | struct amdtp_stream stream; |
55 | }; | 55 | }; |
56 | 56 | ||
57 | MODULE_DESCRIPTION("DICE driver"); | 57 | MODULE_DESCRIPTION("DICE driver"); |
@@ -420,22 +420,7 @@ static int dice_open(struct snd_pcm_substream *substream) | |||
420 | if (err < 0) | 420 | if (err < 0) |
421 | goto err_lock; | 421 | goto err_lock; |
422 | 422 | ||
423 | err = snd_pcm_hw_constraint_step(runtime, 0, | 423 | err = amdtp_stream_add_pcm_hw_constraints(&dice->stream, runtime); |
424 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 32); | ||
425 | if (err < 0) | ||
426 | goto err_lock; | ||
427 | err = snd_pcm_hw_constraint_step(runtime, 0, | ||
428 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 32); | ||
429 | if (err < 0) | ||
430 | goto err_lock; | ||
431 | |||
432 | err = snd_pcm_hw_constraint_minmax(runtime, | ||
433 | SNDRV_PCM_HW_PARAM_PERIOD_TIME, | ||
434 | 5000, UINT_MAX); | ||
435 | if (err < 0) | ||
436 | goto err_lock; | ||
437 | |||
438 | err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); | ||
439 | if (err < 0) | 424 | if (err < 0) |
440 | goto err_lock; | 425 | goto err_lock; |
441 | 426 | ||
@@ -460,17 +445,17 @@ static int dice_stream_start_packets(struct dice *dice) | |||
460 | { | 445 | { |
461 | int err; | 446 | int err; |
462 | 447 | ||
463 | if (amdtp_out_stream_running(&dice->stream)) | 448 | if (amdtp_stream_running(&dice->stream)) |
464 | return 0; | 449 | return 0; |
465 | 450 | ||
466 | err = amdtp_out_stream_start(&dice->stream, dice->resources.channel, | 451 | err = amdtp_stream_start(&dice->stream, dice->resources.channel, |
467 | fw_parent_device(dice->unit)->max_speed); | 452 | fw_parent_device(dice->unit)->max_speed); |
468 | if (err < 0) | 453 | if (err < 0) |
469 | return err; | 454 | return err; |
470 | 455 | ||
471 | err = dice_enable_set(dice); | 456 | err = dice_enable_set(dice); |
472 | if (err < 0) { | 457 | if (err < 0) { |
473 | amdtp_out_stream_stop(&dice->stream); | 458 | amdtp_stream_stop(&dice->stream); |
474 | return err; | 459 | return err; |
475 | } | 460 | } |
476 | 461 | ||
@@ -484,7 +469,7 @@ static int dice_stream_start(struct dice *dice) | |||
484 | 469 | ||
485 | if (!dice->resources.allocated) { | 470 | if (!dice->resources.allocated) { |
486 | err = fw_iso_resources_allocate(&dice->resources, | 471 | err = fw_iso_resources_allocate(&dice->resources, |
487 | amdtp_out_stream_get_max_payload(&dice->stream), | 472 | amdtp_stream_get_max_payload(&dice->stream), |
488 | fw_parent_device(dice->unit)->max_speed); | 473 | fw_parent_device(dice->unit)->max_speed); |
489 | if (err < 0) | 474 | if (err < 0) |
490 | goto error; | 475 | goto error; |
@@ -516,9 +501,9 @@ error: | |||
516 | 501 | ||
517 | static void dice_stream_stop_packets(struct dice *dice) | 502 | static void dice_stream_stop_packets(struct dice *dice) |
518 | { | 503 | { |
519 | if (amdtp_out_stream_running(&dice->stream)) { | 504 | if (amdtp_stream_running(&dice->stream)) { |
520 | dice_enable_clear(dice); | 505 | dice_enable_clear(dice); |
521 | amdtp_out_stream_stop(&dice->stream); | 506 | amdtp_stream_stop(&dice->stream); |
522 | } | 507 | } |
523 | } | 508 | } |
524 | 509 | ||
@@ -563,7 +548,7 @@ static int dice_hw_params(struct snd_pcm_substream *substream, | |||
563 | struct snd_pcm_hw_params *hw_params) | 548 | struct snd_pcm_hw_params *hw_params) |
564 | { | 549 | { |
565 | struct dice *dice = substream->private_data; | 550 | struct dice *dice = substream->private_data; |
566 | unsigned int rate_index, mode; | 551 | unsigned int rate_index, mode, rate, channels, i; |
567 | int err; | 552 | int err; |
568 | 553 | ||
569 | mutex_lock(&dice->mutex); | 554 | mutex_lock(&dice->mutex); |
@@ -575,18 +560,39 @@ static int dice_hw_params(struct snd_pcm_substream *substream, | |||
575 | if (err < 0) | 560 | if (err < 0) |
576 | return err; | 561 | return err; |
577 | 562 | ||
578 | rate_index = rate_to_index(params_rate(hw_params)); | 563 | rate = params_rate(hw_params); |
564 | rate_index = rate_to_index(rate); | ||
579 | err = dice_change_rate(dice, rate_index << CLOCK_RATE_SHIFT); | 565 | err = dice_change_rate(dice, rate_index << CLOCK_RATE_SHIFT); |
580 | if (err < 0) | 566 | if (err < 0) |
581 | return err; | 567 | return err; |
582 | 568 | ||
569 | /* | ||
570 | * At rates above 96 kHz, pretend that the stream runs at half the | ||
571 | * actual sample rate with twice the number of channels; two samples | ||
572 | * of a channel are stored consecutively in the packet. Requires | ||
573 | * blocking mode and PCM buffer size should be aligned to SYT_INTERVAL. | ||
574 | */ | ||
575 | channels = params_channels(hw_params); | ||
576 | if (rate_index > 4) { | ||
577 | if (channels > AMDTP_MAX_CHANNELS_FOR_PCM / 2) { | ||
578 | err = -ENOSYS; | ||
579 | return err; | ||
580 | } | ||
581 | |||
582 | for (i = 0; i < channels; i++) { | ||
583 | dice->stream.pcm_positions[i * 2] = i; | ||
584 | dice->stream.pcm_positions[i * 2 + 1] = i + channels; | ||
585 | } | ||
586 | |||
587 | rate /= 2; | ||
588 | channels *= 2; | ||
589 | } | ||
590 | |||
583 | mode = rate_index_to_mode(rate_index); | 591 | mode = rate_index_to_mode(rate_index); |
584 | amdtp_out_stream_set_parameters(&dice->stream, | 592 | amdtp_stream_set_parameters(&dice->stream, rate, channels, |
585 | params_rate(hw_params), | 593 | dice->rx_midi_ports[mode]); |
586 | params_channels(hw_params), | 594 | amdtp_stream_set_pcm_format(&dice->stream, |
587 | dice->rx_midi_ports[mode]); | 595 | params_format(hw_params)); |
588 | amdtp_out_stream_set_pcm_format(&dice->stream, | ||
589 | params_format(hw_params)); | ||
590 | 596 | ||
591 | return 0; | 597 | return 0; |
592 | } | 598 | } |
@@ -609,7 +615,7 @@ static int dice_prepare(struct snd_pcm_substream *substream) | |||
609 | 615 | ||
610 | mutex_lock(&dice->mutex); | 616 | mutex_lock(&dice->mutex); |
611 | 617 | ||
612 | if (amdtp_out_streaming_error(&dice->stream)) | 618 | if (amdtp_streaming_error(&dice->stream)) |
613 | dice_stream_stop_packets(dice); | 619 | dice_stream_stop_packets(dice); |
614 | 620 | ||
615 | err = dice_stream_start(dice); | 621 | err = dice_stream_start(dice); |
@@ -620,7 +626,7 @@ static int dice_prepare(struct snd_pcm_substream *substream) | |||
620 | 626 | ||
621 | mutex_unlock(&dice->mutex); | 627 | mutex_unlock(&dice->mutex); |
622 | 628 | ||
623 | amdtp_out_stream_pcm_prepare(&dice->stream); | 629 | amdtp_stream_pcm_prepare(&dice->stream); |
624 | 630 | ||
625 | return 0; | 631 | return 0; |
626 | } | 632 | } |
@@ -640,7 +646,7 @@ static int dice_trigger(struct snd_pcm_substream *substream, int cmd) | |||
640 | default: | 646 | default: |
641 | return -EINVAL; | 647 | return -EINVAL; |
642 | } | 648 | } |
643 | amdtp_out_stream_pcm_trigger(&dice->stream, pcm); | 649 | amdtp_stream_pcm_trigger(&dice->stream, pcm); |
644 | 650 | ||
645 | return 0; | 651 | return 0; |
646 | } | 652 | } |
@@ -649,7 +655,7 @@ static snd_pcm_uframes_t dice_pointer(struct snd_pcm_substream *substream) | |||
649 | { | 655 | { |
650 | struct dice *dice = substream->private_data; | 656 | struct dice *dice = substream->private_data; |
651 | 657 | ||
652 | return amdtp_out_stream_pcm_pointer(&dice->stream); | 658 | return amdtp_stream_pcm_pointer(&dice->stream); |
653 | } | 659 | } |
654 | 660 | ||
655 | static int dice_create_pcm(struct dice *dice) | 661 | static int dice_create_pcm(struct dice *dice) |
@@ -1104,7 +1110,7 @@ static void dice_card_free(struct snd_card *card) | |||
1104 | { | 1110 | { |
1105 | struct dice *dice = card->private_data; | 1111 | struct dice *dice = card->private_data; |
1106 | 1112 | ||
1107 | amdtp_out_stream_destroy(&dice->stream); | 1113 | amdtp_stream_destroy(&dice->stream); |
1108 | fw_core_remove_address_handler(&dice->notification_handler); | 1114 | fw_core_remove_address_handler(&dice->notification_handler); |
1109 | mutex_destroy(&dice->mutex); | 1115 | mutex_destroy(&dice->mutex); |
1110 | } | 1116 | } |
@@ -1360,8 +1366,8 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) | |||
1360 | goto err_owner; | 1366 | goto err_owner; |
1361 | dice->resources.channels_mask = 0x00000000ffffffffuLL; | 1367 | dice->resources.channels_mask = 0x00000000ffffffffuLL; |
1362 | 1368 | ||
1363 | err = amdtp_out_stream_init(&dice->stream, unit, | 1369 | err = amdtp_stream_init(&dice->stream, unit, AMDTP_OUT_STREAM, |
1364 | CIP_BLOCKING | CIP_HI_DUALWIRE); | 1370 | CIP_BLOCKING); |
1365 | if (err < 0) | 1371 | if (err < 0) |
1366 | goto err_resources; | 1372 | goto err_resources; |
1367 | 1373 | ||
@@ -1417,7 +1423,7 @@ static void dice_remove(struct fw_unit *unit) | |||
1417 | { | 1423 | { |
1418 | struct dice *dice = dev_get_drvdata(&unit->device); | 1424 | struct dice *dice = dev_get_drvdata(&unit->device); |
1419 | 1425 | ||
1420 | amdtp_out_stream_pcm_abort(&dice->stream); | 1426 | amdtp_stream_pcm_abort(&dice->stream); |
1421 | 1427 | ||
1422 | snd_card_disconnect(dice->card); | 1428 | snd_card_disconnect(dice->card); |
1423 | 1429 | ||
@@ -1443,7 +1449,7 @@ static void dice_bus_reset(struct fw_unit *unit) | |||
1443 | * to stop so that the application can restart them in an orderly | 1449 | * to stop so that the application can restart them in an orderly |
1444 | * manner. | 1450 | * manner. |
1445 | */ | 1451 | */ |
1446 | amdtp_out_stream_pcm_abort(&dice->stream); | 1452 | amdtp_stream_pcm_abort(&dice->stream); |
1447 | 1453 | ||
1448 | mutex_lock(&dice->mutex); | 1454 | mutex_lock(&dice->mutex); |
1449 | 1455 | ||
diff --git a/sound/firewire/fcp.c b/sound/firewire/fcp.c index 860c08073c59..d48e326567c8 100644 --- a/sound/firewire/fcp.c +++ b/sound/firewire/fcp.c | |||
@@ -10,12 +10,14 @@ | |||
10 | #include <linux/firewire-constants.h> | 10 | #include <linux/firewire-constants.h> |
11 | #include <linux/list.h> | 11 | #include <linux/list.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/slab.h> | ||
13 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
14 | #include <linux/spinlock.h> | 15 | #include <linux/spinlock.h> |
15 | #include <linux/wait.h> | 16 | #include <linux/wait.h> |
16 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
17 | #include "fcp.h" | 18 | #include "fcp.h" |
18 | #include "lib.h" | 19 | #include "lib.h" |
20 | #include "amdtp.h" | ||
19 | 21 | ||
20 | #define CTS_AVC 0x00 | 22 | #define CTS_AVC 0x00 |
21 | 23 | ||
@@ -23,6 +25,158 @@ | |||
23 | #define ERROR_DELAY_MS 5 | 25 | #define ERROR_DELAY_MS 5 |
24 | #define FCP_TIMEOUT_MS 125 | 26 | #define FCP_TIMEOUT_MS 125 |
25 | 27 | ||
28 | int avc_general_set_sig_fmt(struct fw_unit *unit, unsigned int rate, | ||
29 | enum avc_general_plug_dir dir, | ||
30 | unsigned short pid) | ||
31 | { | ||
32 | unsigned int sfc; | ||
33 | u8 *buf; | ||
34 | bool flag; | ||
35 | int err; | ||
36 | |||
37 | flag = false; | ||
38 | for (sfc = 0; sfc < CIP_SFC_COUNT; sfc++) { | ||
39 | if (amdtp_rate_table[sfc] == rate) { | ||
40 | flag = true; | ||
41 | break; | ||
42 | } | ||
43 | } | ||
44 | if (!flag) | ||
45 | return -EINVAL; | ||
46 | |||
47 | buf = kzalloc(8, GFP_KERNEL); | ||
48 | if (buf == NULL) | ||
49 | return -ENOMEM; | ||
50 | |||
51 | buf[0] = 0x00; /* AV/C CONTROL */ | ||
52 | buf[1] = 0xff; /* UNIT */ | ||
53 | if (dir == AVC_GENERAL_PLUG_DIR_IN) | ||
54 | buf[2] = 0x19; /* INPUT PLUG SIGNAL FORMAT */ | ||
55 | else | ||
56 | buf[2] = 0x18; /* OUTPUT PLUG SIGNAL FORMAT */ | ||
57 | buf[3] = 0xff & pid; /* plug id */ | ||
58 | buf[4] = 0x90; /* EOH_1, Form_1, FMT. AM824 */ | ||
59 | buf[5] = 0x07 & sfc; /* FDF-hi. AM824, frequency */ | ||
60 | buf[6] = 0xff; /* FDF-mid. AM824, SYT hi (not used)*/ | ||
61 | buf[7] = 0xff; /* FDF-low. AM824, SYT lo (not used) */ | ||
62 | |||
63 | /* do transaction and check buf[1-5] are the same against command */ | ||
64 | err = fcp_avc_transaction(unit, buf, 8, buf, 8, | ||
65 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5)); | ||
66 | if (err >= 0 && err < 8) | ||
67 | err = -EIO; | ||
68 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | ||
69 | err = -ENOSYS; | ||
70 | else if (buf[0] == 0x0a) /* REJECTED */ | ||
71 | err = -EINVAL; | ||
72 | if (err < 0) | ||
73 | goto end; | ||
74 | |||
75 | err = 0; | ||
76 | end: | ||
77 | kfree(buf); | ||
78 | return err; | ||
79 | } | ||
80 | EXPORT_SYMBOL(avc_general_set_sig_fmt); | ||
81 | |||
82 | int avc_general_get_sig_fmt(struct fw_unit *unit, unsigned int *rate, | ||
83 | enum avc_general_plug_dir dir, | ||
84 | unsigned short pid) | ||
85 | { | ||
86 | unsigned int sfc; | ||
87 | u8 *buf; | ||
88 | int err; | ||
89 | |||
90 | buf = kzalloc(8, GFP_KERNEL); | ||
91 | if (buf == NULL) | ||
92 | return -ENOMEM; | ||
93 | |||
94 | buf[0] = 0x01; /* AV/C STATUS */ | ||
95 | buf[1] = 0xff; /* Unit */ | ||
96 | if (dir == AVC_GENERAL_PLUG_DIR_IN) | ||
97 | buf[2] = 0x19; /* INPUT PLUG SIGNAL FORMAT */ | ||
98 | else | ||
99 | buf[2] = 0x18; /* OUTPUT PLUG SIGNAL FORMAT */ | ||
100 | buf[3] = 0xff & pid; /* plug id */ | ||
101 | buf[4] = 0x90; /* EOH_1, Form_1, FMT. AM824 */ | ||
102 | buf[5] = 0xff; /* FDF-hi. AM824, frequency */ | ||
103 | buf[6] = 0xff; /* FDF-mid. AM824, SYT hi (not used) */ | ||
104 | buf[7] = 0xff; /* FDF-low. AM824, SYT lo (not used) */ | ||
105 | |||
106 | /* do transaction and check buf[1-4] are the same against command */ | ||
107 | err = fcp_avc_transaction(unit, buf, 8, buf, 8, | ||
108 | BIT(1) | BIT(2) | BIT(3) | BIT(4)); | ||
109 | if (err >= 0 && err < 8) | ||
110 | err = -EIO; | ||
111 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | ||
112 | err = -ENOSYS; | ||
113 | else if (buf[0] == 0x0a) /* REJECTED */ | ||
114 | err = -EINVAL; | ||
115 | else if (buf[0] == 0x0b) /* IN TRANSITION */ | ||
116 | err = -EAGAIN; | ||
117 | if (err < 0) | ||
118 | goto end; | ||
119 | |||
120 | /* check sfc field and pick up rate */ | ||
121 | sfc = 0x07 & buf[5]; | ||
122 | if (sfc >= CIP_SFC_COUNT) { | ||
123 | err = -EAGAIN; /* also in transition */ | ||
124 | goto end; | ||
125 | } | ||
126 | |||
127 | *rate = amdtp_rate_table[sfc]; | ||
128 | err = 0; | ||
129 | end: | ||
130 | kfree(buf); | ||
131 | return err; | ||
132 | } | ||
133 | EXPORT_SYMBOL(avc_general_get_sig_fmt); | ||
134 | |||
135 | int avc_general_get_plug_info(struct fw_unit *unit, unsigned int subunit_type, | ||
136 | unsigned int subunit_id, unsigned int subfunction, | ||
137 | u8 info[AVC_PLUG_INFO_BUF_BYTES]) | ||
138 | { | ||
139 | u8 *buf; | ||
140 | int err; | ||
141 | |||
142 | /* extended subunit in spec.4.2 is not supported */ | ||
143 | if ((subunit_type == 0x1E) || (subunit_id == 5)) | ||
144 | return -EINVAL; | ||
145 | |||
146 | buf = kzalloc(8, GFP_KERNEL); | ||
147 | if (buf == NULL) | ||
148 | return -ENOMEM; | ||
149 | |||
150 | buf[0] = 0x01; /* AV/C STATUS */ | ||
151 | /* UNIT or Subunit, Functionblock */ | ||
152 | buf[1] = ((subunit_type & 0x1f) << 3) | (subunit_id & 0x7); | ||
153 | buf[2] = 0x02; /* PLUG INFO */ | ||
154 | buf[3] = 0xff & subfunction; | ||
155 | |||
156 | err = fcp_avc_transaction(unit, buf, 8, buf, 8, BIT(1) | BIT(2)); | ||
157 | if (err >= 0 && err < 8) | ||
158 | err = -EIO; | ||
159 | else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | ||
160 | err = -ENOSYS; | ||
161 | else if (buf[0] == 0x0a) /* REJECTED */ | ||
162 | err = -EINVAL; | ||
163 | else if (buf[0] == 0x0b) /* IN TRANSITION */ | ||
164 | err = -EAGAIN; | ||
165 | if (err < 0) | ||
166 | goto end; | ||
167 | |||
168 | info[0] = buf[4]; | ||
169 | info[1] = buf[5]; | ||
170 | info[2] = buf[6]; | ||
171 | info[3] = buf[7]; | ||
172 | |||
173 | err = 0; | ||
174 | end: | ||
175 | kfree(buf); | ||
176 | return err; | ||
177 | } | ||
178 | EXPORT_SYMBOL(avc_general_get_plug_info); | ||
179 | |||
26 | static DEFINE_SPINLOCK(transactions_lock); | 180 | static DEFINE_SPINLOCK(transactions_lock); |
27 | static LIST_HEAD(transactions); | 181 | static LIST_HEAD(transactions); |
28 | 182 | ||
@@ -30,6 +184,7 @@ enum fcp_state { | |||
30 | STATE_PENDING, | 184 | STATE_PENDING, |
31 | STATE_BUS_RESET, | 185 | STATE_BUS_RESET, |
32 | STATE_COMPLETE, | 186 | STATE_COMPLETE, |
187 | STATE_DEFERRED, | ||
33 | }; | 188 | }; |
34 | 189 | ||
35 | struct fcp_transaction { | 190 | struct fcp_transaction { |
@@ -40,6 +195,7 @@ struct fcp_transaction { | |||
40 | unsigned int response_match_bytes; | 195 | unsigned int response_match_bytes; |
41 | enum fcp_state state; | 196 | enum fcp_state state; |
42 | wait_queue_head_t wait; | 197 | wait_queue_head_t wait; |
198 | bool deferrable; | ||
43 | }; | 199 | }; |
44 | 200 | ||
45 | /** | 201 | /** |
@@ -81,6 +237,9 @@ int fcp_avc_transaction(struct fw_unit *unit, | |||
81 | t.state = STATE_PENDING; | 237 | t.state = STATE_PENDING; |
82 | init_waitqueue_head(&t.wait); | 238 | init_waitqueue_head(&t.wait); |
83 | 239 | ||
240 | if (*(const u8 *)command == 0x00 || *(const u8 *)command == 0x03) | ||
241 | t.deferrable = true; | ||
242 | |||
84 | spin_lock_irq(&transactions_lock); | 243 | spin_lock_irq(&transactions_lock); |
85 | list_add_tail(&t.list, &transactions); | 244 | list_add_tail(&t.list, &transactions); |
86 | spin_unlock_irq(&transactions_lock); | 245 | spin_unlock_irq(&transactions_lock); |
@@ -93,11 +252,21 @@ int fcp_avc_transaction(struct fw_unit *unit, | |||
93 | (void *)command, command_size, 0); | 252 | (void *)command, command_size, 0); |
94 | if (ret < 0) | 253 | if (ret < 0) |
95 | break; | 254 | break; |
96 | 255 | deferred: | |
97 | wait_event_timeout(t.wait, t.state != STATE_PENDING, | 256 | wait_event_timeout(t.wait, t.state != STATE_PENDING, |
98 | msecs_to_jiffies(FCP_TIMEOUT_MS)); | 257 | msecs_to_jiffies(FCP_TIMEOUT_MS)); |
99 | 258 | ||
100 | if (t.state == STATE_COMPLETE) { | 259 | if (t.state == STATE_DEFERRED) { |
260 | /* | ||
261 | * 'AV/C General Specification' define no time limit | ||
262 | * on command completion once an INTERIM response has | ||
263 | * been sent. but we promise to finish this function | ||
264 | * for a caller. Here we use FCP_TIMEOUT_MS for next | ||
265 | * interval. This is not in the specification. | ||
266 | */ | ||
267 | t.state = STATE_PENDING; | ||
268 | goto deferred; | ||
269 | } else if (t.state == STATE_COMPLETE) { | ||
101 | ret = t.response_size; | 270 | ret = t.response_size; |
102 | break; | 271 | break; |
103 | } else if (t.state == STATE_BUS_RESET) { | 272 | } else if (t.state == STATE_BUS_RESET) { |
@@ -132,7 +301,8 @@ void fcp_bus_reset(struct fw_unit *unit) | |||
132 | spin_lock_irq(&transactions_lock); | 301 | spin_lock_irq(&transactions_lock); |
133 | list_for_each_entry(t, &transactions, list) { | 302 | list_for_each_entry(t, &transactions, list) { |
134 | if (t->unit == unit && | 303 | if (t->unit == unit && |
135 | t->state == STATE_PENDING) { | 304 | (t->state == STATE_PENDING || |
305 | t->state == STATE_DEFERRED)) { | ||
136 | t->state = STATE_BUS_RESET; | 306 | t->state = STATE_BUS_RESET; |
137 | wake_up(&t->wait); | 307 | wake_up(&t->wait); |
138 | } | 308 | } |
@@ -186,10 +356,15 @@ static void fcp_response(struct fw_card *card, struct fw_request *request, | |||
186 | 356 | ||
187 | if (t->state == STATE_PENDING && | 357 | if (t->state == STATE_PENDING && |
188 | is_matching_response(t, data, length)) { | 358 | is_matching_response(t, data, length)) { |
189 | t->state = STATE_COMPLETE; | 359 | if (t->deferrable && *(const u8 *)data == 0x0f) { |
190 | t->response_size = min((unsigned int)length, | 360 | t->state = STATE_DEFERRED; |
191 | t->response_size); | 361 | } else { |
192 | memcpy(t->response_buffer, data, t->response_size); | 362 | t->state = STATE_COMPLETE; |
363 | t->response_size = min_t(unsigned int, length, | ||
364 | t->response_size); | ||
365 | memcpy(t->response_buffer, data, | ||
366 | t->response_size); | ||
367 | } | ||
193 | wake_up(&t->wait); | 368 | wake_up(&t->wait); |
194 | } | 369 | } |
195 | } | 370 | } |
diff --git a/sound/firewire/fcp.h b/sound/firewire/fcp.h index 86595688bd91..63ae4f7ce3af 100644 --- a/sound/firewire/fcp.h +++ b/sound/firewire/fcp.h | |||
@@ -1,8 +1,29 @@ | |||
1 | #ifndef SOUND_FIREWIRE_FCP_H_INCLUDED | 1 | #ifndef SOUND_FIREWIRE_FCP_H_INCLUDED |
2 | #define SOUND_FIREWIRE_FCP_H_INCLUDED | 2 | #define SOUND_FIREWIRE_FCP_H_INCLUDED |
3 | 3 | ||
4 | #define AVC_PLUG_INFO_BUF_BYTES 4 | ||
5 | |||
4 | struct fw_unit; | 6 | struct fw_unit; |
5 | 7 | ||
8 | /* | ||
9 | * AV/C Digital Interface Command Set General Specification 4.2 | ||
10 | * (Sep 2004, 1394TA) | ||
11 | */ | ||
12 | enum avc_general_plug_dir { | ||
13 | AVC_GENERAL_PLUG_DIR_IN = 0, | ||
14 | AVC_GENERAL_PLUG_DIR_OUT = 1, | ||
15 | AVC_GENERAL_PLUG_DIR_COUNT | ||
16 | }; | ||
17 | int avc_general_set_sig_fmt(struct fw_unit *unit, unsigned int rate, | ||
18 | enum avc_general_plug_dir dir, | ||
19 | unsigned short plug); | ||
20 | int avc_general_get_sig_fmt(struct fw_unit *unit, unsigned int *rate, | ||
21 | enum avc_general_plug_dir dir, | ||
22 | unsigned short plug); | ||
23 | int avc_general_get_plug_info(struct fw_unit *unit, unsigned int subunit_type, | ||
24 | unsigned int subunit_id, unsigned int subfunction, | ||
25 | u8 info[AVC_PLUG_INFO_BUF_BYTES]); | ||
26 | |||
6 | int fcp_avc_transaction(struct fw_unit *unit, | 27 | int fcp_avc_transaction(struct fw_unit *unit, |
7 | const void *command, unsigned int command_size, | 28 | const void *command, unsigned int command_size, |
8 | void *response, unsigned int response_size, | 29 | void *response, unsigned int response_size, |
diff --git a/sound/firewire/fireworks/Makefile b/sound/firewire/fireworks/Makefile new file mode 100644 index 000000000000..0c7440826db8 --- /dev/null +++ b/sound/firewire/fireworks/Makefile | |||
@@ -0,0 +1,4 @@ | |||
1 | snd-fireworks-objs := fireworks_transaction.o fireworks_command.o \ | ||
2 | fireworks_stream.o fireworks_proc.o fireworks_midi.o \ | ||
3 | fireworks_pcm.o fireworks_hwdep.o fireworks.o | ||
4 | obj-m += snd-fireworks.o | ||
diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c new file mode 100644 index 000000000000..a354d26afe9e --- /dev/null +++ b/sound/firewire/fireworks/fireworks.c | |||
@@ -0,0 +1,357 @@ | |||
1 | /* | ||
2 | * fireworks.c - a part of driver for Fireworks based devices | ||
3 | * | ||
4 | * Copyright (c) 2009-2010 Clemens Ladisch | ||
5 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
6 | * | ||
7 | * Licensed under the terms of the GNU General Public License, version 2. | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * Fireworks is a board module which Echo Audio produced. This module consists | ||
12 | * of three chipsets: | ||
13 | * - Communication chipset for IEEE1394 PHY/Link and IEC 61883-1/6 | ||
14 | * - DSP or/and FPGA for signal processing | ||
15 | * - Flash Memory to store firmwares | ||
16 | */ | ||
17 | |||
18 | #include "fireworks.h" | ||
19 | |||
20 | MODULE_DESCRIPTION("Echo Fireworks driver"); | ||
21 | MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>"); | ||
22 | MODULE_LICENSE("GPL v2"); | ||
23 | |||
24 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | ||
25 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | ||
26 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | ||
27 | unsigned int snd_efw_resp_buf_size = 1024; | ||
28 | bool snd_efw_resp_buf_debug = false; | ||
29 | |||
30 | module_param_array(index, int, NULL, 0444); | ||
31 | MODULE_PARM_DESC(index, "card index"); | ||
32 | module_param_array(id, charp, NULL, 0444); | ||
33 | MODULE_PARM_DESC(id, "ID string"); | ||
34 | module_param_array(enable, bool, NULL, 0444); | ||
35 | MODULE_PARM_DESC(enable, "enable Fireworks sound card"); | ||
36 | module_param_named(resp_buf_size, snd_efw_resp_buf_size, uint, 0444); | ||
37 | MODULE_PARM_DESC(resp_buf_size, | ||
38 | "response buffer size (max 4096, default 1024)"); | ||
39 | module_param_named(resp_buf_debug, snd_efw_resp_buf_debug, bool, 0444); | ||
40 | MODULE_PARM_DESC(resp_buf_debug, "store all responses to buffer"); | ||
41 | |||
42 | static DEFINE_MUTEX(devices_mutex); | ||
43 | static DECLARE_BITMAP(devices_used, SNDRV_CARDS); | ||
44 | |||
45 | #define VENDOR_LOUD 0x000ff2 | ||
46 | #define MODEL_MACKIE_400F 0x00400f | ||
47 | #define MODEL_MACKIE_1200F 0x01200f | ||
48 | |||
49 | #define VENDOR_ECHO 0x001486 | ||
50 | #define MODEL_ECHO_AUDIOFIRE_12 0x00af12 | ||
51 | #define MODEL_ECHO_AUDIOFIRE_12HD 0x0af12d | ||
52 | #define MODEL_ECHO_AUDIOFIRE_12_APPLE 0x0af12a | ||
53 | /* This is applied for AudioFire8 (until 2009 July) */ | ||
54 | #define MODEL_ECHO_AUDIOFIRE_8 0x000af8 | ||
55 | #define MODEL_ECHO_AUDIOFIRE_2 0x000af2 | ||
56 | #define MODEL_ECHO_AUDIOFIRE_4 0x000af4 | ||
57 | /* AudioFire9 is applied for AudioFire8(since 2009 July) and AudioFirePre8 */ | ||
58 | #define MODEL_ECHO_AUDIOFIRE_9 0x000af9 | ||
59 | /* unknown as product */ | ||
60 | #define MODEL_ECHO_FIREWORKS_8 0x0000f8 | ||
61 | #define MODEL_ECHO_FIREWORKS_HDMI 0x00afd1 | ||
62 | |||
63 | #define VENDOR_GIBSON 0x00075b | ||
64 | /* for Robot Interface Pack of Dark Fire, Dusk Tiger, Les Paul Standard 2010 */ | ||
65 | #define MODEL_GIBSON_RIP 0x00afb2 | ||
66 | /* unknown as product */ | ||
67 | #define MODEL_GIBSON_GOLDTOP 0x00afb9 | ||
68 | |||
69 | /* part of hardware capability flags */ | ||
70 | #define FLAG_RESP_ADDR_CHANGABLE 0 | ||
71 | |||
72 | static int | ||
73 | get_hardware_info(struct snd_efw *efw) | ||
74 | { | ||
75 | struct fw_device *fw_dev = fw_parent_device(efw->unit); | ||
76 | struct snd_efw_hwinfo *hwinfo; | ||
77 | char version[12] = {0}; | ||
78 | int err; | ||
79 | |||
80 | hwinfo = kzalloc(sizeof(struct snd_efw_hwinfo), GFP_KERNEL); | ||
81 | if (hwinfo == NULL) | ||
82 | return -ENOMEM; | ||
83 | |||
84 | err = snd_efw_command_get_hwinfo(efw, hwinfo); | ||
85 | if (err < 0) | ||
86 | goto end; | ||
87 | |||
88 | /* firmware version for communication chipset */ | ||
89 | snprintf(version, sizeof(version), "%u.%u", | ||
90 | (hwinfo->arm_version >> 24) & 0xff, | ||
91 | (hwinfo->arm_version >> 16) & 0xff); | ||
92 | if (err < 0) | ||
93 | goto end; | ||
94 | efw->firmware_version = hwinfo->arm_version; | ||
95 | |||
96 | strcpy(efw->card->driver, "Fireworks"); | ||
97 | strcpy(efw->card->shortname, hwinfo->model_name); | ||
98 | strcpy(efw->card->mixername, hwinfo->model_name); | ||
99 | snprintf(efw->card->longname, sizeof(efw->card->longname), | ||
100 | "%s %s v%s, GUID %08x%08x at %s, S%d", | ||
101 | hwinfo->vendor_name, hwinfo->model_name, version, | ||
102 | hwinfo->guid_hi, hwinfo->guid_lo, | ||
103 | dev_name(&efw->unit->device), 100 << fw_dev->max_speed); | ||
104 | if (err < 0) | ||
105 | goto end; | ||
106 | |||
107 | if (hwinfo->flags & BIT(FLAG_RESP_ADDR_CHANGABLE)) | ||
108 | efw->resp_addr_changable = true; | ||
109 | |||
110 | efw->supported_sampling_rate = 0; | ||
111 | if ((hwinfo->min_sample_rate <= 22050) | ||
112 | && (22050 <= hwinfo->max_sample_rate)) | ||
113 | efw->supported_sampling_rate |= SNDRV_PCM_RATE_22050; | ||
114 | if ((hwinfo->min_sample_rate <= 32000) | ||
115 | && (32000 <= hwinfo->max_sample_rate)) | ||
116 | efw->supported_sampling_rate |= SNDRV_PCM_RATE_32000; | ||
117 | if ((hwinfo->min_sample_rate <= 44100) | ||
118 | && (44100 <= hwinfo->max_sample_rate)) | ||
119 | efw->supported_sampling_rate |= SNDRV_PCM_RATE_44100; | ||
120 | if ((hwinfo->min_sample_rate <= 48000) | ||
121 | && (48000 <= hwinfo->max_sample_rate)) | ||
122 | efw->supported_sampling_rate |= SNDRV_PCM_RATE_48000; | ||
123 | if ((hwinfo->min_sample_rate <= 88200) | ||
124 | && (88200 <= hwinfo->max_sample_rate)) | ||
125 | efw->supported_sampling_rate |= SNDRV_PCM_RATE_88200; | ||
126 | if ((hwinfo->min_sample_rate <= 96000) | ||
127 | && (96000 <= hwinfo->max_sample_rate)) | ||
128 | efw->supported_sampling_rate |= SNDRV_PCM_RATE_96000; | ||
129 | if ((hwinfo->min_sample_rate <= 176400) | ||
130 | && (176400 <= hwinfo->max_sample_rate)) | ||
131 | efw->supported_sampling_rate |= SNDRV_PCM_RATE_176400; | ||
132 | if ((hwinfo->min_sample_rate <= 192000) | ||
133 | && (192000 <= hwinfo->max_sample_rate)) | ||
134 | efw->supported_sampling_rate |= SNDRV_PCM_RATE_192000; | ||
135 | |||
136 | /* the number of MIDI ports, not of MIDI conformant data channels */ | ||
137 | if (hwinfo->midi_out_ports > SND_EFW_MAX_MIDI_OUT_PORTS || | ||
138 | hwinfo->midi_in_ports > SND_EFW_MAX_MIDI_IN_PORTS) { | ||
139 | err = -EIO; | ||
140 | goto end; | ||
141 | } | ||
142 | efw->midi_out_ports = hwinfo->midi_out_ports; | ||
143 | efw->midi_in_ports = hwinfo->midi_in_ports; | ||
144 | |||
145 | if (hwinfo->amdtp_tx_pcm_channels > AMDTP_MAX_CHANNELS_FOR_PCM || | ||
146 | hwinfo->amdtp_tx_pcm_channels_2x > AMDTP_MAX_CHANNELS_FOR_PCM || | ||
147 | hwinfo->amdtp_tx_pcm_channels_4x > AMDTP_MAX_CHANNELS_FOR_PCM || | ||
148 | hwinfo->amdtp_rx_pcm_channels > AMDTP_MAX_CHANNELS_FOR_PCM || | ||
149 | hwinfo->amdtp_rx_pcm_channels_2x > AMDTP_MAX_CHANNELS_FOR_PCM || | ||
150 | hwinfo->amdtp_rx_pcm_channels_4x > AMDTP_MAX_CHANNELS_FOR_PCM) { | ||
151 | err = -ENOSYS; | ||
152 | goto end; | ||
153 | } | ||
154 | efw->pcm_capture_channels[0] = hwinfo->amdtp_tx_pcm_channels; | ||
155 | efw->pcm_capture_channels[1] = hwinfo->amdtp_tx_pcm_channels_2x; | ||
156 | efw->pcm_capture_channels[2] = hwinfo->amdtp_tx_pcm_channels_4x; | ||
157 | efw->pcm_playback_channels[0] = hwinfo->amdtp_rx_pcm_channels; | ||
158 | efw->pcm_playback_channels[1] = hwinfo->amdtp_rx_pcm_channels_2x; | ||
159 | efw->pcm_playback_channels[2] = hwinfo->amdtp_rx_pcm_channels_4x; | ||
160 | |||
161 | /* Hardware metering. */ | ||
162 | if (hwinfo->phys_in_grp_count > HWINFO_MAX_CAPS_GROUPS || | ||
163 | hwinfo->phys_out_grp_count > HWINFO_MAX_CAPS_GROUPS) { | ||
164 | return -EIO; | ||
165 | goto end; | ||
166 | } | ||
167 | efw->phys_in = hwinfo->phys_in; | ||
168 | efw->phys_out = hwinfo->phys_out; | ||
169 | efw->phys_in_grp_count = hwinfo->phys_in_grp_count; | ||
170 | efw->phys_out_grp_count = hwinfo->phys_out_grp_count; | ||
171 | memcpy(&efw->phys_in_grps, hwinfo->phys_in_grps, | ||
172 | sizeof(struct snd_efw_phys_grp) * hwinfo->phys_in_grp_count); | ||
173 | memcpy(&efw->phys_out_grps, hwinfo->phys_out_grps, | ||
174 | sizeof(struct snd_efw_phys_grp) * hwinfo->phys_out_grp_count); | ||
175 | end: | ||
176 | kfree(hwinfo); | ||
177 | return err; | ||
178 | } | ||
179 | |||
180 | static void | ||
181 | efw_card_free(struct snd_card *card) | ||
182 | { | ||
183 | struct snd_efw *efw = card->private_data; | ||
184 | |||
185 | if (efw->card_index >= 0) { | ||
186 | mutex_lock(&devices_mutex); | ||
187 | clear_bit(efw->card_index, devices_used); | ||
188 | mutex_unlock(&devices_mutex); | ||
189 | } | ||
190 | |||
191 | mutex_destroy(&efw->mutex); | ||
192 | kfree(efw->resp_buf); | ||
193 | } | ||
194 | |||
195 | static int | ||
196 | efw_probe(struct fw_unit *unit, | ||
197 | const struct ieee1394_device_id *entry) | ||
198 | { | ||
199 | struct snd_card *card; | ||
200 | struct snd_efw *efw; | ||
201 | int card_index, err; | ||
202 | |||
203 | mutex_lock(&devices_mutex); | ||
204 | |||
205 | /* check registered cards */ | ||
206 | for (card_index = 0; card_index < SNDRV_CARDS; ++card_index) { | ||
207 | if (!test_bit(card_index, devices_used) && enable[card_index]) | ||
208 | break; | ||
209 | } | ||
210 | if (card_index >= SNDRV_CARDS) { | ||
211 | err = -ENOENT; | ||
212 | goto end; | ||
213 | } | ||
214 | |||
215 | err = snd_card_new(&unit->device, index[card_index], id[card_index], | ||
216 | THIS_MODULE, sizeof(struct snd_efw), &card); | ||
217 | if (err < 0) | ||
218 | goto end; | ||
219 | efw = card->private_data; | ||
220 | efw->card_index = card_index; | ||
221 | set_bit(card_index, devices_used); | ||
222 | card->private_free = efw_card_free; | ||
223 | |||
224 | efw->card = card; | ||
225 | efw->unit = unit; | ||
226 | mutex_init(&efw->mutex); | ||
227 | spin_lock_init(&efw->lock); | ||
228 | init_waitqueue_head(&efw->hwdep_wait); | ||
229 | |||
230 | /* prepare response buffer */ | ||
231 | snd_efw_resp_buf_size = clamp(snd_efw_resp_buf_size, | ||
232 | SND_EFW_RESPONSE_MAXIMUM_BYTES, 4096U); | ||
233 | efw->resp_buf = kzalloc(snd_efw_resp_buf_size, GFP_KERNEL); | ||
234 | if (efw->resp_buf == NULL) { | ||
235 | err = -ENOMEM; | ||
236 | goto error; | ||
237 | } | ||
238 | efw->pull_ptr = efw->push_ptr = efw->resp_buf; | ||
239 | snd_efw_transaction_add_instance(efw); | ||
240 | |||
241 | err = get_hardware_info(efw); | ||
242 | if (err < 0) | ||
243 | goto error; | ||
244 | if (entry->model_id == MODEL_ECHO_AUDIOFIRE_9) | ||
245 | efw->is_af9 = true; | ||
246 | |||
247 | snd_efw_proc_init(efw); | ||
248 | |||
249 | if (efw->midi_out_ports || efw->midi_in_ports) { | ||
250 | err = snd_efw_create_midi_devices(efw); | ||
251 | if (err < 0) | ||
252 | goto error; | ||
253 | } | ||
254 | |||
255 | err = snd_efw_create_pcm_devices(efw); | ||
256 | if (err < 0) | ||
257 | goto error; | ||
258 | |||
259 | err = snd_efw_create_hwdep_device(efw); | ||
260 | if (err < 0) | ||
261 | goto error; | ||
262 | |||
263 | err = snd_efw_stream_init_duplex(efw); | ||
264 | if (err < 0) | ||
265 | goto error; | ||
266 | |||
267 | err = snd_card_register(card); | ||
268 | if (err < 0) { | ||
269 | snd_efw_stream_destroy_duplex(efw); | ||
270 | goto error; | ||
271 | } | ||
272 | |||
273 | dev_set_drvdata(&unit->device, efw); | ||
274 | end: | ||
275 | mutex_unlock(&devices_mutex); | ||
276 | return err; | ||
277 | error: | ||
278 | snd_efw_transaction_remove_instance(efw); | ||
279 | mutex_unlock(&devices_mutex); | ||
280 | snd_card_free(card); | ||
281 | return err; | ||
282 | } | ||
283 | |||
284 | static void efw_update(struct fw_unit *unit) | ||
285 | { | ||
286 | struct snd_efw *efw = dev_get_drvdata(&unit->device); | ||
287 | |||
288 | snd_efw_transaction_bus_reset(efw->unit); | ||
289 | snd_efw_stream_update_duplex(efw); | ||
290 | } | ||
291 | |||
292 | static void efw_remove(struct fw_unit *unit) | ||
293 | { | ||
294 | struct snd_efw *efw = dev_get_drvdata(&unit->device); | ||
295 | |||
296 | snd_efw_stream_destroy_duplex(efw); | ||
297 | snd_efw_transaction_remove_instance(efw); | ||
298 | |||
299 | snd_card_disconnect(efw->card); | ||
300 | snd_card_free_when_closed(efw->card); | ||
301 | } | ||
302 | |||
303 | static const struct ieee1394_device_id efw_id_table[] = { | ||
304 | SND_EFW_DEV_ENTRY(VENDOR_LOUD, MODEL_MACKIE_400F), | ||
305 | SND_EFW_DEV_ENTRY(VENDOR_LOUD, MODEL_MACKIE_1200F), | ||
306 | SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_AUDIOFIRE_8), | ||
307 | SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_AUDIOFIRE_12), | ||
308 | SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_AUDIOFIRE_12HD), | ||
309 | SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_AUDIOFIRE_12_APPLE), | ||
310 | SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_AUDIOFIRE_2), | ||
311 | SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_AUDIOFIRE_4), | ||
312 | SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_AUDIOFIRE_9), | ||
313 | SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_FIREWORKS_8), | ||
314 | SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_FIREWORKS_HDMI), | ||
315 | SND_EFW_DEV_ENTRY(VENDOR_GIBSON, MODEL_GIBSON_RIP), | ||
316 | SND_EFW_DEV_ENTRY(VENDOR_GIBSON, MODEL_GIBSON_GOLDTOP), | ||
317 | {} | ||
318 | }; | ||
319 | MODULE_DEVICE_TABLE(ieee1394, efw_id_table); | ||
320 | |||
321 | static struct fw_driver efw_driver = { | ||
322 | .driver = { | ||
323 | .owner = THIS_MODULE, | ||
324 | .name = "snd-fireworks", | ||
325 | .bus = &fw_bus_type, | ||
326 | }, | ||
327 | .probe = efw_probe, | ||
328 | .update = efw_update, | ||
329 | .remove = efw_remove, | ||
330 | .id_table = efw_id_table, | ||
331 | }; | ||
332 | |||
333 | static int __init snd_efw_init(void) | ||
334 | { | ||
335 | int err; | ||
336 | |||
337 | err = snd_efw_transaction_register(); | ||
338 | if (err < 0) | ||
339 | goto end; | ||
340 | |||
341 | err = driver_register(&efw_driver.driver); | ||
342 | if (err < 0) | ||
343 | snd_efw_transaction_unregister(); | ||
344 | |||
345 | end: | ||
346 | return err; | ||
347 | } | ||
348 | |||
349 | static void __exit snd_efw_exit(void) | ||
350 | { | ||
351 | snd_efw_transaction_unregister(); | ||
352 | driver_unregister(&efw_driver.driver); | ||
353 | mutex_destroy(&devices_mutex); | ||
354 | } | ||
355 | |||
356 | module_init(snd_efw_init); | ||
357 | module_exit(snd_efw_exit); | ||
diff --git a/sound/firewire/fireworks/fireworks.h b/sound/firewire/fireworks/fireworks.h new file mode 100644 index 000000000000..d2b36be4d2f8 --- /dev/null +++ b/sound/firewire/fireworks/fireworks.h | |||
@@ -0,0 +1,233 @@ | |||
1 | /* | ||
2 | * fireworks.h - a part of driver for Fireworks based devices | ||
3 | * | ||
4 | * Copyright (c) 2009-2010 Clemens Ladisch | ||
5 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
6 | * | ||
7 | * Licensed under the terms of the GNU General Public License, version 2. | ||
8 | */ | ||
9 | #ifndef SOUND_FIREWORKS_H_INCLUDED | ||
10 | #define SOUND_FIREWORKS_H_INCLUDED | ||
11 | |||
12 | #include <linux/compat.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/firewire.h> | ||
15 | #include <linux/firewire-constants.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/mod_devicetable.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | #include <sound/core.h> | ||
22 | #include <sound/initval.h> | ||
23 | #include <sound/pcm.h> | ||
24 | #include <sound/info.h> | ||
25 | #include <sound/rawmidi.h> | ||
26 | #include <sound/pcm_params.h> | ||
27 | #include <sound/firewire.h> | ||
28 | #include <sound/hwdep.h> | ||
29 | |||
30 | #include "../packets-buffer.h" | ||
31 | #include "../iso-resources.h" | ||
32 | #include "../amdtp.h" | ||
33 | #include "../cmp.h" | ||
34 | #include "../lib.h" | ||
35 | |||
36 | #define SND_EFW_MAX_MIDI_OUT_PORTS 2 | ||
37 | #define SND_EFW_MAX_MIDI_IN_PORTS 2 | ||
38 | |||
39 | #define SND_EFW_MULTIPLIER_MODES 3 | ||
40 | #define HWINFO_NAME_SIZE_BYTES 32 | ||
41 | #define HWINFO_MAX_CAPS_GROUPS 8 | ||
42 | |||
43 | /* | ||
44 | * This should be greater than maximum bytes for EFW response content. | ||
45 | * Currently response against command for isochronous channel mapping is | ||
46 | * confirmed to be the maximum one. But for flexibility, use maximum data | ||
47 | * payload for asynchronous primary packets at S100 (Cable base rate) in | ||
48 | * IEEE Std 1394-1995. | ||
49 | */ | ||
50 | #define SND_EFW_RESPONSE_MAXIMUM_BYTES 0x200U | ||
51 | |||
52 | extern unsigned int snd_efw_resp_buf_size; | ||
53 | extern bool snd_efw_resp_buf_debug; | ||
54 | |||
55 | struct snd_efw_phys_grp { | ||
56 | u8 type; /* see enum snd_efw_grp_type */ | ||
57 | u8 count; | ||
58 | } __packed; | ||
59 | |||
60 | struct snd_efw { | ||
61 | struct snd_card *card; | ||
62 | struct fw_unit *unit; | ||
63 | int card_index; | ||
64 | |||
65 | struct mutex mutex; | ||
66 | spinlock_t lock; | ||
67 | |||
68 | /* for transaction */ | ||
69 | u32 seqnum; | ||
70 | bool resp_addr_changable; | ||
71 | |||
72 | /* for quirks */ | ||
73 | bool is_af9; | ||
74 | u32 firmware_version; | ||
75 | |||
76 | unsigned int midi_in_ports; | ||
77 | unsigned int midi_out_ports; | ||
78 | |||
79 | unsigned int supported_sampling_rate; | ||
80 | unsigned int pcm_capture_channels[SND_EFW_MULTIPLIER_MODES]; | ||
81 | unsigned int pcm_playback_channels[SND_EFW_MULTIPLIER_MODES]; | ||
82 | |||
83 | struct amdtp_stream *master; | ||
84 | struct amdtp_stream tx_stream; | ||
85 | struct amdtp_stream rx_stream; | ||
86 | struct cmp_connection out_conn; | ||
87 | struct cmp_connection in_conn; | ||
88 | atomic_t capture_substreams; | ||
89 | atomic_t playback_substreams; | ||
90 | |||
91 | /* hardware metering parameters */ | ||
92 | unsigned int phys_out; | ||
93 | unsigned int phys_in; | ||
94 | unsigned int phys_out_grp_count; | ||
95 | unsigned int phys_in_grp_count; | ||
96 | struct snd_efw_phys_grp phys_out_grps[HWINFO_MAX_CAPS_GROUPS]; | ||
97 | struct snd_efw_phys_grp phys_in_grps[HWINFO_MAX_CAPS_GROUPS]; | ||
98 | |||
99 | /* for uapi */ | ||
100 | int dev_lock_count; | ||
101 | bool dev_lock_changed; | ||
102 | wait_queue_head_t hwdep_wait; | ||
103 | |||
104 | /* response queue */ | ||
105 | u8 *resp_buf; | ||
106 | u8 *pull_ptr; | ||
107 | u8 *push_ptr; | ||
108 | unsigned int resp_queues; | ||
109 | }; | ||
110 | |||
111 | int snd_efw_transaction_cmd(struct fw_unit *unit, | ||
112 | const void *cmd, unsigned int size); | ||
113 | int snd_efw_transaction_run(struct fw_unit *unit, | ||
114 | const void *cmd, unsigned int cmd_size, | ||
115 | void *resp, unsigned int resp_size); | ||
116 | int snd_efw_transaction_register(void); | ||
117 | void snd_efw_transaction_unregister(void); | ||
118 | void snd_efw_transaction_bus_reset(struct fw_unit *unit); | ||
119 | void snd_efw_transaction_add_instance(struct snd_efw *efw); | ||
120 | void snd_efw_transaction_remove_instance(struct snd_efw *efw); | ||
121 | |||
122 | struct snd_efw_hwinfo { | ||
123 | u32 flags; | ||
124 | u32 guid_hi; | ||
125 | u32 guid_lo; | ||
126 | u32 type; | ||
127 | u32 version; | ||
128 | char vendor_name[HWINFO_NAME_SIZE_BYTES]; | ||
129 | char model_name[HWINFO_NAME_SIZE_BYTES]; | ||
130 | u32 supported_clocks; | ||
131 | u32 amdtp_rx_pcm_channels; | ||
132 | u32 amdtp_tx_pcm_channels; | ||
133 | u32 phys_out; | ||
134 | u32 phys_in; | ||
135 | u32 phys_out_grp_count; | ||
136 | struct snd_efw_phys_grp phys_out_grps[HWINFO_MAX_CAPS_GROUPS]; | ||
137 | u32 phys_in_grp_count; | ||
138 | struct snd_efw_phys_grp phys_in_grps[HWINFO_MAX_CAPS_GROUPS]; | ||
139 | u32 midi_out_ports; | ||
140 | u32 midi_in_ports; | ||
141 | u32 max_sample_rate; | ||
142 | u32 min_sample_rate; | ||
143 | u32 dsp_version; | ||
144 | u32 arm_version; | ||
145 | u32 mixer_playback_channels; | ||
146 | u32 mixer_capture_channels; | ||
147 | u32 fpga_version; | ||
148 | u32 amdtp_rx_pcm_channels_2x; | ||
149 | u32 amdtp_tx_pcm_channels_2x; | ||
150 | u32 amdtp_rx_pcm_channels_4x; | ||
151 | u32 amdtp_tx_pcm_channels_4x; | ||
152 | u32 reserved[16]; | ||
153 | } __packed; | ||
154 | enum snd_efw_grp_type { | ||
155 | SND_EFW_CH_TYPE_ANALOG = 0, | ||
156 | SND_EFW_CH_TYPE_SPDIF = 1, | ||
157 | SND_EFW_CH_TYPE_ADAT = 2, | ||
158 | SND_EFW_CH_TYPE_SPDIF_OR_ADAT = 3, | ||
159 | SND_EFW_CH_TYPE_ANALOG_MIRRORING = 4, | ||
160 | SND_EFW_CH_TYPE_HEADPHONES = 5, | ||
161 | SND_EFW_CH_TYPE_I2S = 6, | ||
162 | SND_EFW_CH_TYPE_GUITAR = 7, | ||
163 | SND_EFW_CH_TYPE_PIEZO_GUITAR = 8, | ||
164 | SND_EFW_CH_TYPE_GUITAR_STRING = 9, | ||
165 | SND_EFW_CH_TYPE_VIRTUAL = 0x10000, | ||
166 | SND_EFW_CH_TYPE_DUMMY | ||
167 | }; | ||
168 | struct snd_efw_phys_meters { | ||
169 | u32 status; /* guitar state/midi signal/clock input detect */ | ||
170 | u32 reserved0; | ||
171 | u32 reserved1; | ||
172 | u32 reserved2; | ||
173 | u32 reserved3; | ||
174 | u32 out_meters; | ||
175 | u32 in_meters; | ||
176 | u32 reserved4; | ||
177 | u32 reserved5; | ||
178 | u32 values[0]; | ||
179 | } __packed; | ||
180 | enum snd_efw_clock_source { | ||
181 | SND_EFW_CLOCK_SOURCE_INTERNAL = 0, | ||
182 | SND_EFW_CLOCK_SOURCE_SYTMATCH = 1, | ||
183 | SND_EFW_CLOCK_SOURCE_WORDCLOCK = 2, | ||
184 | SND_EFW_CLOCK_SOURCE_SPDIF = 3, | ||
185 | SND_EFW_CLOCK_SOURCE_ADAT_1 = 4, | ||
186 | SND_EFW_CLOCK_SOURCE_ADAT_2 = 5, | ||
187 | SND_EFW_CLOCK_SOURCE_CONTINUOUS = 6 /* internal variable clock */ | ||
188 | }; | ||
189 | enum snd_efw_transport_mode { | ||
190 | SND_EFW_TRANSPORT_MODE_WINDOWS = 0, | ||
191 | SND_EFW_TRANSPORT_MODE_IEC61883 = 1, | ||
192 | }; | ||
193 | int snd_efw_command_set_resp_addr(struct snd_efw *efw, | ||
194 | u16 addr_high, u32 addr_low); | ||
195 | int snd_efw_command_set_tx_mode(struct snd_efw *efw, | ||
196 | enum snd_efw_transport_mode mode); | ||
197 | int snd_efw_command_get_hwinfo(struct snd_efw *efw, | ||
198 | struct snd_efw_hwinfo *hwinfo); | ||
199 | int snd_efw_command_get_phys_meters(struct snd_efw *efw, | ||
200 | struct snd_efw_phys_meters *meters, | ||
201 | unsigned int len); | ||
202 | int snd_efw_command_get_clock_source(struct snd_efw *efw, | ||
203 | enum snd_efw_clock_source *source); | ||
204 | int snd_efw_command_get_sampling_rate(struct snd_efw *efw, unsigned int *rate); | ||
205 | int snd_efw_command_set_sampling_rate(struct snd_efw *efw, unsigned int rate); | ||
206 | |||
207 | int snd_efw_stream_init_duplex(struct snd_efw *efw); | ||
208 | int snd_efw_stream_start_duplex(struct snd_efw *efw, unsigned int rate); | ||
209 | void snd_efw_stream_stop_duplex(struct snd_efw *efw); | ||
210 | void snd_efw_stream_update_duplex(struct snd_efw *efw); | ||
211 | void snd_efw_stream_destroy_duplex(struct snd_efw *efw); | ||
212 | void snd_efw_stream_lock_changed(struct snd_efw *efw); | ||
213 | int snd_efw_stream_lock_try(struct snd_efw *efw); | ||
214 | void snd_efw_stream_lock_release(struct snd_efw *efw); | ||
215 | |||
216 | void snd_efw_proc_init(struct snd_efw *efw); | ||
217 | |||
218 | int snd_efw_create_midi_devices(struct snd_efw *efw); | ||
219 | |||
220 | int snd_efw_create_pcm_devices(struct snd_efw *efw); | ||
221 | int snd_efw_get_multiplier_mode(unsigned int sampling_rate, unsigned int *mode); | ||
222 | |||
223 | int snd_efw_create_hwdep_device(struct snd_efw *efw); | ||
224 | |||
225 | #define SND_EFW_DEV_ENTRY(vendor, model) \ | ||
226 | { \ | ||
227 | .match_flags = IEEE1394_MATCH_VENDOR_ID | \ | ||
228 | IEEE1394_MATCH_MODEL_ID, \ | ||
229 | .vendor_id = vendor,\ | ||
230 | .model_id = model \ | ||
231 | } | ||
232 | |||
233 | #endif | ||
diff --git a/sound/firewire/fireworks/fireworks_command.c b/sound/firewire/fireworks/fireworks_command.c new file mode 100644 index 000000000000..166f80584c2a --- /dev/null +++ b/sound/firewire/fireworks/fireworks_command.c | |||
@@ -0,0 +1,372 @@ | |||
1 | /* | ||
2 | * fireworks_command.c - a part of driver for Fireworks based devices | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | #include "./fireworks.h" | ||
10 | |||
11 | /* | ||
12 | * This driver uses transaction version 1 or later to use extended hardware | ||
13 | * information. Then too old devices are not available. | ||
14 | * | ||
15 | * Each commands are not required to have continuous sequence numbers. This | ||
16 | * number is just used to match command and response. | ||
17 | * | ||
18 | * This module support a part of commands. Please see FFADO if you want to see | ||
19 | * whole commands. But there are some commands which FFADO don't implement. | ||
20 | * | ||
21 | * Fireworks also supports AV/C general commands and AV/C Stream Format | ||
22 | * Information commands. But this module don't use them. | ||
23 | */ | ||
24 | |||
25 | #define KERNEL_SEQNUM_MIN (SND_EFW_TRANSACTION_USER_SEQNUM_MAX + 2) | ||
26 | #define KERNEL_SEQNUM_MAX ((u32)~0) | ||
27 | |||
28 | /* for clock source and sampling rate */ | ||
29 | struct efc_clock { | ||
30 | u32 source; | ||
31 | u32 sampling_rate; | ||
32 | u32 index; | ||
33 | }; | ||
34 | |||
35 | /* command categories */ | ||
36 | enum efc_category { | ||
37 | EFC_CAT_HWINFO = 0, | ||
38 | EFC_CAT_TRANSPORT = 2, | ||
39 | EFC_CAT_HWCTL = 3, | ||
40 | }; | ||
41 | |||
42 | /* hardware info category commands */ | ||
43 | enum efc_cmd_hwinfo { | ||
44 | EFC_CMD_HWINFO_GET_CAPS = 0, | ||
45 | EFC_CMD_HWINFO_GET_POLLED = 1, | ||
46 | EFC_CMD_HWINFO_SET_RESP_ADDR = 2 | ||
47 | }; | ||
48 | |||
49 | enum efc_cmd_transport { | ||
50 | EFC_CMD_TRANSPORT_SET_TX_MODE = 0 | ||
51 | }; | ||
52 | |||
53 | /* hardware control category commands */ | ||
54 | enum efc_cmd_hwctl { | ||
55 | EFC_CMD_HWCTL_SET_CLOCK = 0, | ||
56 | EFC_CMD_HWCTL_GET_CLOCK = 1, | ||
57 | EFC_CMD_HWCTL_IDENTIFY = 5 | ||
58 | }; | ||
59 | |||
60 | /* return values in response */ | ||
61 | enum efr_status { | ||
62 | EFR_STATUS_OK = 0, | ||
63 | EFR_STATUS_BAD = 1, | ||
64 | EFR_STATUS_BAD_COMMAND = 2, | ||
65 | EFR_STATUS_COMM_ERR = 3, | ||
66 | EFR_STATUS_BAD_QUAD_COUNT = 4, | ||
67 | EFR_STATUS_UNSUPPORTED = 5, | ||
68 | EFR_STATUS_1394_TIMEOUT = 6, | ||
69 | EFR_STATUS_DSP_TIMEOUT = 7, | ||
70 | EFR_STATUS_BAD_RATE = 8, | ||
71 | EFR_STATUS_BAD_CLOCK = 9, | ||
72 | EFR_STATUS_BAD_CHANNEL = 10, | ||
73 | EFR_STATUS_BAD_PAN = 11, | ||
74 | EFR_STATUS_FLASH_BUSY = 12, | ||
75 | EFR_STATUS_BAD_MIRROR = 13, | ||
76 | EFR_STATUS_BAD_LED = 14, | ||
77 | EFR_STATUS_BAD_PARAMETER = 15, | ||
78 | EFR_STATUS_INCOMPLETE = 0x80000000 | ||
79 | }; | ||
80 | |||
81 | static const char *const efr_status_names[] = { | ||
82 | [EFR_STATUS_OK] = "OK", | ||
83 | [EFR_STATUS_BAD] = "bad", | ||
84 | [EFR_STATUS_BAD_COMMAND] = "bad command", | ||
85 | [EFR_STATUS_COMM_ERR] = "comm err", | ||
86 | [EFR_STATUS_BAD_QUAD_COUNT] = "bad quad count", | ||
87 | [EFR_STATUS_UNSUPPORTED] = "unsupported", | ||
88 | [EFR_STATUS_1394_TIMEOUT] = "1394 timeout", | ||
89 | [EFR_STATUS_DSP_TIMEOUT] = "DSP timeout", | ||
90 | [EFR_STATUS_BAD_RATE] = "bad rate", | ||
91 | [EFR_STATUS_BAD_CLOCK] = "bad clock", | ||
92 | [EFR_STATUS_BAD_CHANNEL] = "bad channel", | ||
93 | [EFR_STATUS_BAD_PAN] = "bad pan", | ||
94 | [EFR_STATUS_FLASH_BUSY] = "flash busy", | ||
95 | [EFR_STATUS_BAD_MIRROR] = "bad mirror", | ||
96 | [EFR_STATUS_BAD_LED] = "bad LED", | ||
97 | [EFR_STATUS_BAD_PARAMETER] = "bad parameter", | ||
98 | [EFR_STATUS_BAD_PARAMETER + 1] = "incomplete" | ||
99 | }; | ||
100 | |||
101 | static int | ||
102 | efw_transaction(struct snd_efw *efw, unsigned int category, | ||
103 | unsigned int command, | ||
104 | const __be32 *params, unsigned int param_bytes, | ||
105 | const __be32 *resp, unsigned int resp_bytes) | ||
106 | { | ||
107 | struct snd_efw_transaction *header; | ||
108 | __be32 *buf; | ||
109 | u32 seqnum; | ||
110 | unsigned int buf_bytes, cmd_bytes; | ||
111 | int err; | ||
112 | |||
113 | /* calculate buffer size*/ | ||
114 | buf_bytes = sizeof(struct snd_efw_transaction) + | ||
115 | max(param_bytes, resp_bytes); | ||
116 | |||
117 | /* keep buffer */ | ||
118 | buf = kzalloc(buf_bytes, GFP_KERNEL); | ||
119 | if (buf == NULL) | ||
120 | return -ENOMEM; | ||
121 | |||
122 | /* to keep consistency of sequence number */ | ||
123 | spin_lock(&efw->lock); | ||
124 | if ((efw->seqnum < KERNEL_SEQNUM_MIN) || | ||
125 | (efw->seqnum >= KERNEL_SEQNUM_MAX - 2)) | ||
126 | efw->seqnum = KERNEL_SEQNUM_MIN; | ||
127 | else | ||
128 | efw->seqnum += 2; | ||
129 | seqnum = efw->seqnum; | ||
130 | spin_unlock(&efw->lock); | ||
131 | |||
132 | /* fill transaction header fields */ | ||
133 | cmd_bytes = sizeof(struct snd_efw_transaction) + param_bytes; | ||
134 | header = (struct snd_efw_transaction *)buf; | ||
135 | header->length = cpu_to_be32(cmd_bytes / sizeof(__be32)); | ||
136 | header->version = cpu_to_be32(1); | ||
137 | header->seqnum = cpu_to_be32(seqnum); | ||
138 | header->category = cpu_to_be32(category); | ||
139 | header->command = cpu_to_be32(command); | ||
140 | header->status = 0; | ||
141 | |||
142 | /* fill transaction command parameters */ | ||
143 | memcpy(header->params, params, param_bytes); | ||
144 | |||
145 | err = snd_efw_transaction_run(efw->unit, buf, cmd_bytes, | ||
146 | buf, buf_bytes); | ||
147 | if (err < 0) | ||
148 | goto end; | ||
149 | |||
150 | /* check transaction header fields */ | ||
151 | if ((be32_to_cpu(header->version) < 1) || | ||
152 | (be32_to_cpu(header->category) != category) || | ||
153 | (be32_to_cpu(header->command) != command) || | ||
154 | (be32_to_cpu(header->status) != EFR_STATUS_OK)) { | ||
155 | dev_err(&efw->unit->device, "EFW command failed [%u/%u]: %s\n", | ||
156 | be32_to_cpu(header->category), | ||
157 | be32_to_cpu(header->command), | ||
158 | efr_status_names[be32_to_cpu(header->status)]); | ||
159 | err = -EIO; | ||
160 | goto end; | ||
161 | } | ||
162 | |||
163 | if (resp == NULL) | ||
164 | goto end; | ||
165 | |||
166 | /* fill transaction response parameters */ | ||
167 | memset((void *)resp, 0, resp_bytes); | ||
168 | resp_bytes = min_t(unsigned int, resp_bytes, | ||
169 | be32_to_cpu(header->length) * sizeof(__be32) - | ||
170 | sizeof(struct snd_efw_transaction)); | ||
171 | memcpy((void *)resp, &buf[6], resp_bytes); | ||
172 | end: | ||
173 | kfree(buf); | ||
174 | return err; | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * The address in host system for transaction response is changable when the | ||
179 | * device supports. struct hwinfo.flags includes its flag. The default is | ||
180 | * MEMORY_SPACE_EFW_RESPONSE. | ||
181 | */ | ||
182 | int snd_efw_command_set_resp_addr(struct snd_efw *efw, | ||
183 | u16 addr_high, u32 addr_low) | ||
184 | { | ||
185 | __be32 addr[2]; | ||
186 | |||
187 | addr[0] = cpu_to_be32(addr_high); | ||
188 | addr[1] = cpu_to_be32(addr_low); | ||
189 | |||
190 | if (!efw->resp_addr_changable) | ||
191 | return -ENOSYS; | ||
192 | |||
193 | return efw_transaction(efw, EFC_CAT_HWCTL, | ||
194 | EFC_CMD_HWINFO_SET_RESP_ADDR, | ||
195 | addr, sizeof(addr), NULL, 0); | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * This is for timestamp processing. In Windows mode, all 32bit fields of second | ||
200 | * CIP header in AMDTP transmit packet is used for 'presentation timestamp'. In | ||
201 | * 'no data' packet the value of this field is 0x90ffffff. | ||
202 | */ | ||
203 | int snd_efw_command_set_tx_mode(struct snd_efw *efw, | ||
204 | enum snd_efw_transport_mode mode) | ||
205 | { | ||
206 | __be32 param = cpu_to_be32(mode); | ||
207 | return efw_transaction(efw, EFC_CAT_TRANSPORT, | ||
208 | EFC_CMD_TRANSPORT_SET_TX_MODE, | ||
209 | ¶m, sizeof(param), NULL, 0); | ||
210 | } | ||
211 | |||
212 | int snd_efw_command_get_hwinfo(struct snd_efw *efw, | ||
213 | struct snd_efw_hwinfo *hwinfo) | ||
214 | { | ||
215 | int err; | ||
216 | |||
217 | err = efw_transaction(efw, EFC_CAT_HWINFO, | ||
218 | EFC_CMD_HWINFO_GET_CAPS, | ||
219 | NULL, 0, (__be32 *)hwinfo, sizeof(*hwinfo)); | ||
220 | if (err < 0) | ||
221 | goto end; | ||
222 | |||
223 | be32_to_cpus(&hwinfo->flags); | ||
224 | be32_to_cpus(&hwinfo->guid_hi); | ||
225 | be32_to_cpus(&hwinfo->guid_lo); | ||
226 | be32_to_cpus(&hwinfo->type); | ||
227 | be32_to_cpus(&hwinfo->version); | ||
228 | be32_to_cpus(&hwinfo->supported_clocks); | ||
229 | be32_to_cpus(&hwinfo->amdtp_rx_pcm_channels); | ||
230 | be32_to_cpus(&hwinfo->amdtp_tx_pcm_channels); | ||
231 | be32_to_cpus(&hwinfo->phys_out); | ||
232 | be32_to_cpus(&hwinfo->phys_in); | ||
233 | be32_to_cpus(&hwinfo->phys_out_grp_count); | ||
234 | be32_to_cpus(&hwinfo->phys_in_grp_count); | ||
235 | be32_to_cpus(&hwinfo->midi_out_ports); | ||
236 | be32_to_cpus(&hwinfo->midi_in_ports); | ||
237 | be32_to_cpus(&hwinfo->max_sample_rate); | ||
238 | be32_to_cpus(&hwinfo->min_sample_rate); | ||
239 | be32_to_cpus(&hwinfo->dsp_version); | ||
240 | be32_to_cpus(&hwinfo->arm_version); | ||
241 | be32_to_cpus(&hwinfo->mixer_playback_channels); | ||
242 | be32_to_cpus(&hwinfo->mixer_capture_channels); | ||
243 | be32_to_cpus(&hwinfo->fpga_version); | ||
244 | be32_to_cpus(&hwinfo->amdtp_rx_pcm_channels_2x); | ||
245 | be32_to_cpus(&hwinfo->amdtp_tx_pcm_channels_2x); | ||
246 | be32_to_cpus(&hwinfo->amdtp_rx_pcm_channels_4x); | ||
247 | be32_to_cpus(&hwinfo->amdtp_tx_pcm_channels_4x); | ||
248 | |||
249 | /* ensure terminated */ | ||
250 | hwinfo->vendor_name[HWINFO_NAME_SIZE_BYTES - 1] = '\0'; | ||
251 | hwinfo->model_name[HWINFO_NAME_SIZE_BYTES - 1] = '\0'; | ||
252 | end: | ||
253 | return err; | ||
254 | } | ||
255 | |||
256 | int snd_efw_command_get_phys_meters(struct snd_efw *efw, | ||
257 | struct snd_efw_phys_meters *meters, | ||
258 | unsigned int len) | ||
259 | { | ||
260 | __be32 *buf = (__be32 *)meters; | ||
261 | unsigned int i; | ||
262 | int err; | ||
263 | |||
264 | err = efw_transaction(efw, EFC_CAT_HWINFO, | ||
265 | EFC_CMD_HWINFO_GET_POLLED, | ||
266 | NULL, 0, (__be32 *)meters, len); | ||
267 | if (err >= 0) | ||
268 | for (i = 0; i < len / sizeof(u32); i++) | ||
269 | be32_to_cpus(&buf[i]); | ||
270 | |||
271 | return err; | ||
272 | } | ||
273 | |||
274 | static int | ||
275 | command_get_clock(struct snd_efw *efw, struct efc_clock *clock) | ||
276 | { | ||
277 | int err; | ||
278 | |||
279 | err = efw_transaction(efw, EFC_CAT_HWCTL, | ||
280 | EFC_CMD_HWCTL_GET_CLOCK, | ||
281 | NULL, 0, | ||
282 | (__be32 *)clock, sizeof(struct efc_clock)); | ||
283 | if (err >= 0) { | ||
284 | be32_to_cpus(&clock->source); | ||
285 | be32_to_cpus(&clock->sampling_rate); | ||
286 | be32_to_cpus(&clock->index); | ||
287 | } | ||
288 | |||
289 | return err; | ||
290 | } | ||
291 | |||
292 | /* give UINT_MAX if set nothing */ | ||
293 | static int | ||
294 | command_set_clock(struct snd_efw *efw, | ||
295 | unsigned int source, unsigned int rate) | ||
296 | { | ||
297 | struct efc_clock clock = {0}; | ||
298 | int err; | ||
299 | |||
300 | /* check arguments */ | ||
301 | if ((source == UINT_MAX) && (rate == UINT_MAX)) { | ||
302 | err = -EINVAL; | ||
303 | goto end; | ||
304 | } | ||
305 | |||
306 | /* get current status */ | ||
307 | err = command_get_clock(efw, &clock); | ||
308 | if (err < 0) | ||
309 | goto end; | ||
310 | |||
311 | /* no need */ | ||
312 | if ((clock.source == source) && (clock.sampling_rate == rate)) | ||
313 | goto end; | ||
314 | |||
315 | /* set params */ | ||
316 | if ((source != UINT_MAX) && (clock.source != source)) | ||
317 | clock.source = source; | ||
318 | if ((rate != UINT_MAX) && (clock.sampling_rate != rate)) | ||
319 | clock.sampling_rate = rate; | ||
320 | clock.index = 0; | ||
321 | |||
322 | cpu_to_be32s(&clock.source); | ||
323 | cpu_to_be32s(&clock.sampling_rate); | ||
324 | cpu_to_be32s(&clock.index); | ||
325 | |||
326 | err = efw_transaction(efw, EFC_CAT_HWCTL, | ||
327 | EFC_CMD_HWCTL_SET_CLOCK, | ||
328 | (__be32 *)&clock, sizeof(struct efc_clock), | ||
329 | NULL, 0); | ||
330 | if (err < 0) | ||
331 | goto end; | ||
332 | |||
333 | /* | ||
334 | * With firmware version 5.8, just after changing clock state, these | ||
335 | * parameters are not immediately retrieved by get command. In my | ||
336 | * trial, there needs to be 100msec to get changed parameters. | ||
337 | */ | ||
338 | msleep(150); | ||
339 | end: | ||
340 | return err; | ||
341 | } | ||
342 | |||
343 | int snd_efw_command_get_clock_source(struct snd_efw *efw, | ||
344 | enum snd_efw_clock_source *source) | ||
345 | { | ||
346 | int err; | ||
347 | struct efc_clock clock = {0}; | ||
348 | |||
349 | err = command_get_clock(efw, &clock); | ||
350 | if (err >= 0) | ||
351 | *source = clock.source; | ||
352 | |||
353 | return err; | ||
354 | } | ||
355 | |||
356 | int snd_efw_command_get_sampling_rate(struct snd_efw *efw, unsigned int *rate) | ||
357 | { | ||
358 | int err; | ||
359 | struct efc_clock clock = {0}; | ||
360 | |||
361 | err = command_get_clock(efw, &clock); | ||
362 | if (err >= 0) | ||
363 | *rate = clock.sampling_rate; | ||
364 | |||
365 | return err; | ||
366 | } | ||
367 | |||
368 | int snd_efw_command_set_sampling_rate(struct snd_efw *efw, unsigned int rate) | ||
369 | { | ||
370 | return command_set_clock(efw, UINT_MAX, rate); | ||
371 | } | ||
372 | |||
diff --git a/sound/firewire/fireworks/fireworks_hwdep.c b/sound/firewire/fireworks/fireworks_hwdep.c new file mode 100644 index 000000000000..4f8216fb6b62 --- /dev/null +++ b/sound/firewire/fireworks/fireworks_hwdep.c | |||
@@ -0,0 +1,298 @@ | |||
1 | /* | ||
2 | * fireworks_hwdep.c - a part of driver for Fireworks based devices | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | /* | ||
10 | * This codes have five functionalities. | ||
11 | * | ||
12 | * 1.get information about firewire node | ||
13 | * 2.get notification about starting/stopping stream | ||
14 | * 3.lock/unlock streaming | ||
15 | * 4.transmit command of EFW transaction | ||
16 | * 5.receive response of EFW transaction | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include "fireworks.h" | ||
21 | |||
22 | static long | ||
23 | hwdep_read_resp_buf(struct snd_efw *efw, char __user *buf, long remained, | ||
24 | loff_t *offset) | ||
25 | { | ||
26 | unsigned int length, till_end, type; | ||
27 | struct snd_efw_transaction *t; | ||
28 | long count = 0; | ||
29 | |||
30 | if (remained < sizeof(type) + sizeof(struct snd_efw_transaction)) | ||
31 | return -ENOSPC; | ||
32 | |||
33 | /* data type is SNDRV_FIREWIRE_EVENT_EFW_RESPONSE */ | ||
34 | type = SNDRV_FIREWIRE_EVENT_EFW_RESPONSE; | ||
35 | if (copy_to_user(buf, &type, sizeof(type))) | ||
36 | return -EFAULT; | ||
37 | remained -= sizeof(type); | ||
38 | buf += sizeof(type); | ||
39 | |||
40 | /* write into buffer as many responses as possible */ | ||
41 | while (efw->resp_queues > 0) { | ||
42 | t = (struct snd_efw_transaction *)(efw->pull_ptr); | ||
43 | length = be32_to_cpu(t->length) * sizeof(__be32); | ||
44 | |||
45 | /* confirm enough space for this response */ | ||
46 | if (remained < length) | ||
47 | break; | ||
48 | |||
49 | /* copy from ring buffer to user buffer */ | ||
50 | while (length > 0) { | ||
51 | till_end = snd_efw_resp_buf_size - | ||
52 | (unsigned int)(efw->pull_ptr - efw->resp_buf); | ||
53 | till_end = min_t(unsigned int, length, till_end); | ||
54 | |||
55 | if (copy_to_user(buf, efw->pull_ptr, till_end)) | ||
56 | return -EFAULT; | ||
57 | |||
58 | efw->pull_ptr += till_end; | ||
59 | if (efw->pull_ptr >= efw->resp_buf + | ||
60 | snd_efw_resp_buf_size) | ||
61 | efw->pull_ptr = efw->resp_buf; | ||
62 | |||
63 | length -= till_end; | ||
64 | buf += till_end; | ||
65 | count += till_end; | ||
66 | remained -= till_end; | ||
67 | } | ||
68 | |||
69 | efw->resp_queues--; | ||
70 | } | ||
71 | |||
72 | return count; | ||
73 | } | ||
74 | |||
75 | static long | ||
76 | hwdep_read_locked(struct snd_efw *efw, char __user *buf, long count, | ||
77 | loff_t *offset) | ||
78 | { | ||
79 | union snd_firewire_event event; | ||
80 | |||
81 | memset(&event, 0, sizeof(event)); | ||
82 | |||
83 | event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; | ||
84 | event.lock_status.status = (efw->dev_lock_count > 0); | ||
85 | efw->dev_lock_changed = false; | ||
86 | |||
87 | count = min_t(long, count, sizeof(event.lock_status)); | ||
88 | |||
89 | if (copy_to_user(buf, &event, count)) | ||
90 | return -EFAULT; | ||
91 | |||
92 | return count; | ||
93 | } | ||
94 | |||
95 | static long | ||
96 | hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, | ||
97 | loff_t *offset) | ||
98 | { | ||
99 | struct snd_efw *efw = hwdep->private_data; | ||
100 | DEFINE_WAIT(wait); | ||
101 | |||
102 | spin_lock_irq(&efw->lock); | ||
103 | |||
104 | while ((!efw->dev_lock_changed) && (efw->resp_queues == 0)) { | ||
105 | prepare_to_wait(&efw->hwdep_wait, &wait, TASK_INTERRUPTIBLE); | ||
106 | spin_unlock_irq(&efw->lock); | ||
107 | schedule(); | ||
108 | finish_wait(&efw->hwdep_wait, &wait); | ||
109 | if (signal_pending(current)) | ||
110 | return -ERESTARTSYS; | ||
111 | spin_lock_irq(&efw->lock); | ||
112 | } | ||
113 | |||
114 | if (efw->dev_lock_changed) | ||
115 | count = hwdep_read_locked(efw, buf, count, offset); | ||
116 | else if (efw->resp_queues > 0) | ||
117 | count = hwdep_read_resp_buf(efw, buf, count, offset); | ||
118 | |||
119 | spin_unlock_irq(&efw->lock); | ||
120 | |||
121 | return count; | ||
122 | } | ||
123 | |||
124 | static long | ||
125 | hwdep_write(struct snd_hwdep *hwdep, const char __user *data, long count, | ||
126 | loff_t *offset) | ||
127 | { | ||
128 | struct snd_efw *efw = hwdep->private_data; | ||
129 | u32 seqnum; | ||
130 | u8 *buf; | ||
131 | |||
132 | if (count < sizeof(struct snd_efw_transaction) || | ||
133 | SND_EFW_RESPONSE_MAXIMUM_BYTES < count) | ||
134 | return -EINVAL; | ||
135 | |||
136 | buf = memdup_user(data, count); | ||
137 | if (IS_ERR(buf)) | ||
138 | return PTR_ERR(buf); | ||
139 | |||
140 | /* check seqnum is not for kernel-land */ | ||
141 | seqnum = be32_to_cpu(((struct snd_efw_transaction *)buf)->seqnum); | ||
142 | if (seqnum > SND_EFW_TRANSACTION_USER_SEQNUM_MAX) { | ||
143 | count = -EINVAL; | ||
144 | goto end; | ||
145 | } | ||
146 | |||
147 | if (snd_efw_transaction_cmd(efw->unit, buf, count) < 0) | ||
148 | count = -EIO; | ||
149 | end: | ||
150 | kfree(buf); | ||
151 | return count; | ||
152 | } | ||
153 | |||
154 | static unsigned int | ||
155 | hwdep_poll(struct snd_hwdep *hwdep, struct file *file, poll_table *wait) | ||
156 | { | ||
157 | struct snd_efw *efw = hwdep->private_data; | ||
158 | unsigned int events; | ||
159 | |||
160 | poll_wait(file, &efw->hwdep_wait, wait); | ||
161 | |||
162 | spin_lock_irq(&efw->lock); | ||
163 | if (efw->dev_lock_changed || (efw->resp_queues > 0)) | ||
164 | events = POLLIN | POLLRDNORM; | ||
165 | else | ||
166 | events = 0; | ||
167 | spin_unlock_irq(&efw->lock); | ||
168 | |||
169 | return events | POLLOUT; | ||
170 | } | ||
171 | |||
172 | static int | ||
173 | hwdep_get_info(struct snd_efw *efw, void __user *arg) | ||
174 | { | ||
175 | struct fw_device *dev = fw_parent_device(efw->unit); | ||
176 | struct snd_firewire_get_info info; | ||
177 | |||
178 | memset(&info, 0, sizeof(info)); | ||
179 | info.type = SNDRV_FIREWIRE_TYPE_FIREWORKS; | ||
180 | info.card = dev->card->index; | ||
181 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); | ||
182 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); | ||
183 | strlcpy(info.device_name, dev_name(&dev->device), | ||
184 | sizeof(info.device_name)); | ||
185 | |||
186 | if (copy_to_user(arg, &info, sizeof(info))) | ||
187 | return -EFAULT; | ||
188 | |||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static int | ||
193 | hwdep_lock(struct snd_efw *efw) | ||
194 | { | ||
195 | int err; | ||
196 | |||
197 | spin_lock_irq(&efw->lock); | ||
198 | |||
199 | if (efw->dev_lock_count == 0) { | ||
200 | efw->dev_lock_count = -1; | ||
201 | err = 0; | ||
202 | } else { | ||
203 | err = -EBUSY; | ||
204 | } | ||
205 | |||
206 | spin_unlock_irq(&efw->lock); | ||
207 | |||
208 | return err; | ||
209 | } | ||
210 | |||
211 | static int | ||
212 | hwdep_unlock(struct snd_efw *efw) | ||
213 | { | ||
214 | int err; | ||
215 | |||
216 | spin_lock_irq(&efw->lock); | ||
217 | |||
218 | if (efw->dev_lock_count == -1) { | ||
219 | efw->dev_lock_count = 0; | ||
220 | err = 0; | ||
221 | } else { | ||
222 | err = -EBADFD; | ||
223 | } | ||
224 | |||
225 | spin_unlock_irq(&efw->lock); | ||
226 | |||
227 | return err; | ||
228 | } | ||
229 | |||
230 | static int | ||
231 | hwdep_release(struct snd_hwdep *hwdep, struct file *file) | ||
232 | { | ||
233 | struct snd_efw *efw = hwdep->private_data; | ||
234 | |||
235 | spin_lock_irq(&efw->lock); | ||
236 | if (efw->dev_lock_count == -1) | ||
237 | efw->dev_lock_count = 0; | ||
238 | spin_unlock_irq(&efw->lock); | ||
239 | |||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | static int | ||
244 | hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file, | ||
245 | unsigned int cmd, unsigned long arg) | ||
246 | { | ||
247 | struct snd_efw *efw = hwdep->private_data; | ||
248 | |||
249 | switch (cmd) { | ||
250 | case SNDRV_FIREWIRE_IOCTL_GET_INFO: | ||
251 | return hwdep_get_info(efw, (void __user *)arg); | ||
252 | case SNDRV_FIREWIRE_IOCTL_LOCK: | ||
253 | return hwdep_lock(efw); | ||
254 | case SNDRV_FIREWIRE_IOCTL_UNLOCK: | ||
255 | return hwdep_unlock(efw); | ||
256 | default: | ||
257 | return -ENOIOCTLCMD; | ||
258 | } | ||
259 | } | ||
260 | |||
261 | #ifdef CONFIG_COMPAT | ||
262 | static int | ||
263 | hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file, | ||
264 | unsigned int cmd, unsigned long arg) | ||
265 | { | ||
266 | return hwdep_ioctl(hwdep, file, cmd, | ||
267 | (unsigned long)compat_ptr(arg)); | ||
268 | } | ||
269 | #else | ||
270 | #define hwdep_compat_ioctl NULL | ||
271 | #endif | ||
272 | |||
273 | static const struct snd_hwdep_ops hwdep_ops = { | ||
274 | .read = hwdep_read, | ||
275 | .write = hwdep_write, | ||
276 | .release = hwdep_release, | ||
277 | .poll = hwdep_poll, | ||
278 | .ioctl = hwdep_ioctl, | ||
279 | .ioctl_compat = hwdep_compat_ioctl, | ||
280 | }; | ||
281 | |||
282 | int snd_efw_create_hwdep_device(struct snd_efw *efw) | ||
283 | { | ||
284 | struct snd_hwdep *hwdep; | ||
285 | int err; | ||
286 | |||
287 | err = snd_hwdep_new(efw->card, "Fireworks", 0, &hwdep); | ||
288 | if (err < 0) | ||
289 | goto end; | ||
290 | strcpy(hwdep->name, "Fireworks"); | ||
291 | hwdep->iface = SNDRV_HWDEP_IFACE_FW_FIREWORKS; | ||
292 | hwdep->ops = hwdep_ops; | ||
293 | hwdep->private_data = efw; | ||
294 | hwdep->exclusive = true; | ||
295 | end: | ||
296 | return err; | ||
297 | } | ||
298 | |||
diff --git a/sound/firewire/fireworks/fireworks_midi.c b/sound/firewire/fireworks/fireworks_midi.c new file mode 100644 index 000000000000..cf9c65260439 --- /dev/null +++ b/sound/firewire/fireworks/fireworks_midi.c | |||
@@ -0,0 +1,168 @@ | |||
1 | /* | ||
2 | * fireworks_midi.c - a part of driver for Fireworks based devices | ||
3 | * | ||
4 | * Copyright (c) 2009-2010 Clemens Ladisch | ||
5 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
6 | * | ||
7 | * Licensed under the terms of the GNU General Public License, version 2. | ||
8 | */ | ||
9 | #include "fireworks.h" | ||
10 | |||
11 | static int midi_capture_open(struct snd_rawmidi_substream *substream) | ||
12 | { | ||
13 | struct snd_efw *efw = substream->rmidi->private_data; | ||
14 | int err; | ||
15 | |||
16 | err = snd_efw_stream_lock_try(efw); | ||
17 | if (err < 0) | ||
18 | goto end; | ||
19 | |||
20 | atomic_inc(&efw->capture_substreams); | ||
21 | err = snd_efw_stream_start_duplex(efw, 0); | ||
22 | if (err < 0) | ||
23 | snd_efw_stream_lock_release(efw); | ||
24 | |||
25 | end: | ||
26 | return err; | ||
27 | } | ||
28 | |||
29 | static int midi_playback_open(struct snd_rawmidi_substream *substream) | ||
30 | { | ||
31 | struct snd_efw *efw = substream->rmidi->private_data; | ||
32 | int err; | ||
33 | |||
34 | err = snd_efw_stream_lock_try(efw); | ||
35 | if (err < 0) | ||
36 | goto end; | ||
37 | |||
38 | atomic_inc(&efw->playback_substreams); | ||
39 | err = snd_efw_stream_start_duplex(efw, 0); | ||
40 | if (err < 0) | ||
41 | snd_efw_stream_lock_release(efw); | ||
42 | end: | ||
43 | return err; | ||
44 | } | ||
45 | |||
46 | static int midi_capture_close(struct snd_rawmidi_substream *substream) | ||
47 | { | ||
48 | struct snd_efw *efw = substream->rmidi->private_data; | ||
49 | |||
50 | atomic_dec(&efw->capture_substreams); | ||
51 | snd_efw_stream_stop_duplex(efw); | ||
52 | |||
53 | snd_efw_stream_lock_release(efw); | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static int midi_playback_close(struct snd_rawmidi_substream *substream) | ||
58 | { | ||
59 | struct snd_efw *efw = substream->rmidi->private_data; | ||
60 | |||
61 | atomic_dec(&efw->playback_substreams); | ||
62 | snd_efw_stream_stop_duplex(efw); | ||
63 | |||
64 | snd_efw_stream_lock_release(efw); | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up) | ||
69 | { | ||
70 | struct snd_efw *efw = substrm->rmidi->private_data; | ||
71 | unsigned long flags; | ||
72 | |||
73 | spin_lock_irqsave(&efw->lock, flags); | ||
74 | |||
75 | if (up) | ||
76 | amdtp_stream_midi_trigger(&efw->tx_stream, | ||
77 | substrm->number, substrm); | ||
78 | else | ||
79 | amdtp_stream_midi_trigger(&efw->tx_stream, | ||
80 | substrm->number, NULL); | ||
81 | |||
82 | spin_unlock_irqrestore(&efw->lock, flags); | ||
83 | } | ||
84 | |||
85 | static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up) | ||
86 | { | ||
87 | struct snd_efw *efw = substrm->rmidi->private_data; | ||
88 | unsigned long flags; | ||
89 | |||
90 | spin_lock_irqsave(&efw->lock, flags); | ||
91 | |||
92 | if (up) | ||
93 | amdtp_stream_midi_trigger(&efw->rx_stream, | ||
94 | substrm->number, substrm); | ||
95 | else | ||
96 | amdtp_stream_midi_trigger(&efw->rx_stream, | ||
97 | substrm->number, NULL); | ||
98 | |||
99 | spin_unlock_irqrestore(&efw->lock, flags); | ||
100 | } | ||
101 | |||
102 | static struct snd_rawmidi_ops midi_capture_ops = { | ||
103 | .open = midi_capture_open, | ||
104 | .close = midi_capture_close, | ||
105 | .trigger = midi_capture_trigger, | ||
106 | }; | ||
107 | |||
108 | static struct snd_rawmidi_ops midi_playback_ops = { | ||
109 | .open = midi_playback_open, | ||
110 | .close = midi_playback_close, | ||
111 | .trigger = midi_playback_trigger, | ||
112 | }; | ||
113 | |||
114 | static void set_midi_substream_names(struct snd_efw *efw, | ||
115 | struct snd_rawmidi_str *str) | ||
116 | { | ||
117 | struct snd_rawmidi_substream *subs; | ||
118 | |||
119 | list_for_each_entry(subs, &str->substreams, list) { | ||
120 | snprintf(subs->name, sizeof(subs->name), | ||
121 | "%s MIDI %d", efw->card->shortname, subs->number + 1); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | int snd_efw_create_midi_devices(struct snd_efw *efw) | ||
126 | { | ||
127 | struct snd_rawmidi *rmidi; | ||
128 | struct snd_rawmidi_str *str; | ||
129 | int err; | ||
130 | |||
131 | /* create midi ports */ | ||
132 | err = snd_rawmidi_new(efw->card, efw->card->driver, 0, | ||
133 | efw->midi_out_ports, efw->midi_in_ports, | ||
134 | &rmidi); | ||
135 | if (err < 0) | ||
136 | return err; | ||
137 | |||
138 | snprintf(rmidi->name, sizeof(rmidi->name), | ||
139 | "%s MIDI", efw->card->shortname); | ||
140 | rmidi->private_data = efw; | ||
141 | |||
142 | if (efw->midi_in_ports > 0) { | ||
143 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; | ||
144 | |||
145 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, | ||
146 | &midi_capture_ops); | ||
147 | |||
148 | str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]; | ||
149 | |||
150 | set_midi_substream_names(efw, str); | ||
151 | } | ||
152 | |||
153 | if (efw->midi_out_ports > 0) { | ||
154 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; | ||
155 | |||
156 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, | ||
157 | &midi_playback_ops); | ||
158 | |||
159 | str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]; | ||
160 | |||
161 | set_midi_substream_names(efw, str); | ||
162 | } | ||
163 | |||
164 | if ((efw->midi_out_ports > 0) && (efw->midi_in_ports > 0)) | ||
165 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX; | ||
166 | |||
167 | return 0; | ||
168 | } | ||
diff --git a/sound/firewire/fireworks/fireworks_pcm.c b/sound/firewire/fireworks/fireworks_pcm.c new file mode 100644 index 000000000000..8a34753de210 --- /dev/null +++ b/sound/firewire/fireworks/fireworks_pcm.c | |||
@@ -0,0 +1,403 @@ | |||
1 | /* | ||
2 | * fireworks_pcm.c - a part of driver for Fireworks based devices | ||
3 | * | ||
4 | * Copyright (c) 2009-2010 Clemens Ladisch | ||
5 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
6 | * | ||
7 | * Licensed under the terms of the GNU General Public License, version 2. | ||
8 | */ | ||
9 | #include "./fireworks.h" | ||
10 | |||
11 | /* | ||
12 | * NOTE: | ||
13 | * Fireworks changes its AMDTP channels for PCM data according to its sampling | ||
14 | * rate. There are three modes. Here _XX is either _rx or _tx. | ||
15 | * 0: 32.0- 48.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels applied | ||
16 | * 1: 88.2- 96.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels_2x applied | ||
17 | * 2: 176.4-192.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels_4x applied | ||
18 | * | ||
19 | * The number of PCM channels for analog input and output are always fixed but | ||
20 | * the number of PCM channels for digital input and output are differed. | ||
21 | * | ||
22 | * Additionally, according to "AudioFire Owner's Manual Version 2.2", in some | ||
23 | * model, the number of PCM channels for digital input has more restriction | ||
24 | * depending on which digital interface is selected. | ||
25 | * - S/PDIF coaxial and optical : use input 1-2 | ||
26 | * - ADAT optical at 32.0-48.0 kHz : use input 1-8 | ||
27 | * - ADAT optical at 88.2-96.0 kHz : use input 1-4 (S/MUX format) | ||
28 | * | ||
29 | * The data in AMDTP channels for blank PCM channels are zero. | ||
30 | */ | ||
31 | static const unsigned int freq_table[] = { | ||
32 | /* multiplier mode 0 */ | ||
33 | [0] = 32000, | ||
34 | [1] = 44100, | ||
35 | [2] = 48000, | ||
36 | /* multiplier mode 1 */ | ||
37 | [3] = 88200, | ||
38 | [4] = 96000, | ||
39 | /* multiplier mode 2 */ | ||
40 | [5] = 176400, | ||
41 | [6] = 192000, | ||
42 | }; | ||
43 | |||
44 | static inline unsigned int | ||
45 | get_multiplier_mode_with_index(unsigned int index) | ||
46 | { | ||
47 | return ((int)index - 1) / 2; | ||
48 | } | ||
49 | |||
50 | int snd_efw_get_multiplier_mode(unsigned int sampling_rate, unsigned int *mode) | ||
51 | { | ||
52 | unsigned int i; | ||
53 | |||
54 | for (i = 0; i < ARRAY_SIZE(freq_table); i++) { | ||
55 | if (freq_table[i] == sampling_rate) { | ||
56 | *mode = get_multiplier_mode_with_index(i); | ||
57 | return 0; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | return -EINVAL; | ||
62 | } | ||
63 | |||
64 | static int | ||
65 | hw_rule_rate(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) | ||
66 | { | ||
67 | unsigned int *pcm_channels = rule->private; | ||
68 | struct snd_interval *r = | ||
69 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | ||
70 | const struct snd_interval *c = | ||
71 | hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
72 | struct snd_interval t = { | ||
73 | .min = UINT_MAX, .max = 0, .integer = 1 | ||
74 | }; | ||
75 | unsigned int i, mode; | ||
76 | |||
77 | for (i = 0; i < ARRAY_SIZE(freq_table); i++) { | ||
78 | mode = get_multiplier_mode_with_index(i); | ||
79 | if (!snd_interval_test(c, pcm_channels[mode])) | ||
80 | continue; | ||
81 | |||
82 | t.min = min(t.min, freq_table[i]); | ||
83 | t.max = max(t.max, freq_table[i]); | ||
84 | } | ||
85 | |||
86 | return snd_interval_refine(r, &t); | ||
87 | } | ||
88 | |||
89 | static int | ||
90 | hw_rule_channels(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) | ||
91 | { | ||
92 | unsigned int *pcm_channels = rule->private; | ||
93 | struct snd_interval *c = | ||
94 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
95 | const struct snd_interval *r = | ||
96 | hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE); | ||
97 | struct snd_interval t = { | ||
98 | .min = UINT_MAX, .max = 0, .integer = 1 | ||
99 | }; | ||
100 | unsigned int i, mode; | ||
101 | |||
102 | for (i = 0; i < ARRAY_SIZE(freq_table); i++) { | ||
103 | mode = get_multiplier_mode_with_index(i); | ||
104 | if (!snd_interval_test(r, freq_table[i])) | ||
105 | continue; | ||
106 | |||
107 | t.min = min(t.min, pcm_channels[mode]); | ||
108 | t.max = max(t.max, pcm_channels[mode]); | ||
109 | } | ||
110 | |||
111 | return snd_interval_refine(c, &t); | ||
112 | } | ||
113 | |||
114 | static void | ||
115 | limit_channels(struct snd_pcm_hardware *hw, unsigned int *pcm_channels) | ||
116 | { | ||
117 | unsigned int i, mode; | ||
118 | |||
119 | hw->channels_min = UINT_MAX; | ||
120 | hw->channels_max = 0; | ||
121 | |||
122 | for (i = 0; i < ARRAY_SIZE(freq_table); i++) { | ||
123 | mode = get_multiplier_mode_with_index(i); | ||
124 | if (pcm_channels[mode] == 0) | ||
125 | continue; | ||
126 | |||
127 | hw->channels_min = min(hw->channels_min, pcm_channels[mode]); | ||
128 | hw->channels_max = max(hw->channels_max, pcm_channels[mode]); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | static void | ||
133 | limit_period_and_buffer(struct snd_pcm_hardware *hw) | ||
134 | { | ||
135 | hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */ | ||
136 | hw->periods_max = UINT_MAX; | ||
137 | |||
138 | hw->period_bytes_min = 4 * hw->channels_max; /* bytes for a frame */ | ||
139 | |||
140 | /* Just to prevent from allocating much pages. */ | ||
141 | hw->period_bytes_max = hw->period_bytes_min * 2048; | ||
142 | hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; | ||
143 | } | ||
144 | |||
145 | static int | ||
146 | pcm_init_hw_params(struct snd_efw *efw, | ||
147 | struct snd_pcm_substream *substream) | ||
148 | { | ||
149 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
150 | struct amdtp_stream *s; | ||
151 | unsigned int *pcm_channels; | ||
152 | int err; | ||
153 | |||
154 | runtime->hw.info = SNDRV_PCM_INFO_BATCH | | ||
155 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
156 | SNDRV_PCM_INFO_INTERLEAVED | | ||
157 | SNDRV_PCM_INFO_JOINT_DUPLEX | | ||
158 | SNDRV_PCM_INFO_MMAP | | ||
159 | SNDRV_PCM_INFO_MMAP_VALID; | ||
160 | |||
161 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | ||
162 | runtime->hw.formats = AMDTP_IN_PCM_FORMAT_BITS; | ||
163 | s = &efw->tx_stream; | ||
164 | pcm_channels = efw->pcm_capture_channels; | ||
165 | } else { | ||
166 | runtime->hw.formats = AMDTP_OUT_PCM_FORMAT_BITS; | ||
167 | s = &efw->rx_stream; | ||
168 | pcm_channels = efw->pcm_playback_channels; | ||
169 | } | ||
170 | |||
171 | /* limit rates */ | ||
172 | runtime->hw.rates = efw->supported_sampling_rate, | ||
173 | snd_pcm_limit_hw_rates(runtime); | ||
174 | |||
175 | limit_channels(&runtime->hw, pcm_channels); | ||
176 | limit_period_and_buffer(&runtime->hw); | ||
177 | |||
178 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
179 | hw_rule_channels, pcm_channels, | ||
180 | SNDRV_PCM_HW_PARAM_RATE, -1); | ||
181 | if (err < 0) | ||
182 | goto end; | ||
183 | |||
184 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | ||
185 | hw_rule_rate, pcm_channels, | ||
186 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
187 | if (err < 0) | ||
188 | goto end; | ||
189 | |||
190 | err = amdtp_stream_add_pcm_hw_constraints(s, runtime); | ||
191 | end: | ||
192 | return err; | ||
193 | } | ||
194 | |||
195 | static int pcm_open(struct snd_pcm_substream *substream) | ||
196 | { | ||
197 | struct snd_efw *efw = substream->private_data; | ||
198 | unsigned int sampling_rate; | ||
199 | enum snd_efw_clock_source clock_source; | ||
200 | int err; | ||
201 | |||
202 | err = snd_efw_stream_lock_try(efw); | ||
203 | if (err < 0) | ||
204 | goto end; | ||
205 | |||
206 | err = pcm_init_hw_params(efw, substream); | ||
207 | if (err < 0) | ||
208 | goto err_locked; | ||
209 | |||
210 | err = snd_efw_command_get_clock_source(efw, &clock_source); | ||
211 | if (err < 0) | ||
212 | goto err_locked; | ||
213 | |||
214 | /* | ||
215 | * When source of clock is not internal or any PCM streams are running, | ||
216 | * available sampling rate is limited at current sampling rate. | ||
217 | */ | ||
218 | if ((clock_source != SND_EFW_CLOCK_SOURCE_INTERNAL) || | ||
219 | amdtp_stream_pcm_running(&efw->tx_stream) || | ||
220 | amdtp_stream_pcm_running(&efw->rx_stream)) { | ||
221 | err = snd_efw_command_get_sampling_rate(efw, &sampling_rate); | ||
222 | if (err < 0) | ||
223 | goto err_locked; | ||
224 | substream->runtime->hw.rate_min = sampling_rate; | ||
225 | substream->runtime->hw.rate_max = sampling_rate; | ||
226 | } | ||
227 | |||
228 | snd_pcm_set_sync(substream); | ||
229 | end: | ||
230 | return err; | ||
231 | err_locked: | ||
232 | snd_efw_stream_lock_release(efw); | ||
233 | return err; | ||
234 | } | ||
235 | |||
236 | static int pcm_close(struct snd_pcm_substream *substream) | ||
237 | { | ||
238 | struct snd_efw *efw = substream->private_data; | ||
239 | snd_efw_stream_lock_release(efw); | ||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | static int pcm_capture_hw_params(struct snd_pcm_substream *substream, | ||
244 | struct snd_pcm_hw_params *hw_params) | ||
245 | { | ||
246 | struct snd_efw *efw = substream->private_data; | ||
247 | |||
248 | if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) | ||
249 | atomic_inc(&efw->capture_substreams); | ||
250 | amdtp_stream_set_pcm_format(&efw->tx_stream, params_format(hw_params)); | ||
251 | |||
252 | return snd_pcm_lib_alloc_vmalloc_buffer(substream, | ||
253 | params_buffer_bytes(hw_params)); | ||
254 | } | ||
255 | static int pcm_playback_hw_params(struct snd_pcm_substream *substream, | ||
256 | struct snd_pcm_hw_params *hw_params) | ||
257 | { | ||
258 | struct snd_efw *efw = substream->private_data; | ||
259 | |||
260 | if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) | ||
261 | atomic_inc(&efw->playback_substreams); | ||
262 | amdtp_stream_set_pcm_format(&efw->rx_stream, params_format(hw_params)); | ||
263 | |||
264 | return snd_pcm_lib_alloc_vmalloc_buffer(substream, | ||
265 | params_buffer_bytes(hw_params)); | ||
266 | } | ||
267 | |||
268 | static int pcm_capture_hw_free(struct snd_pcm_substream *substream) | ||
269 | { | ||
270 | struct snd_efw *efw = substream->private_data; | ||
271 | |||
272 | if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) | ||
273 | atomic_dec(&efw->capture_substreams); | ||
274 | |||
275 | snd_efw_stream_stop_duplex(efw); | ||
276 | |||
277 | return snd_pcm_lib_free_vmalloc_buffer(substream); | ||
278 | } | ||
279 | static int pcm_playback_hw_free(struct snd_pcm_substream *substream) | ||
280 | { | ||
281 | struct snd_efw *efw = substream->private_data; | ||
282 | |||
283 | if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) | ||
284 | atomic_dec(&efw->playback_substreams); | ||
285 | |||
286 | snd_efw_stream_stop_duplex(efw); | ||
287 | |||
288 | return snd_pcm_lib_free_vmalloc_buffer(substream); | ||
289 | } | ||
290 | |||
291 | static int pcm_capture_prepare(struct snd_pcm_substream *substream) | ||
292 | { | ||
293 | struct snd_efw *efw = substream->private_data; | ||
294 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
295 | int err; | ||
296 | |||
297 | err = snd_efw_stream_start_duplex(efw, runtime->rate); | ||
298 | if (err >= 0) | ||
299 | amdtp_stream_pcm_prepare(&efw->tx_stream); | ||
300 | |||
301 | return err; | ||
302 | } | ||
303 | static int pcm_playback_prepare(struct snd_pcm_substream *substream) | ||
304 | { | ||
305 | struct snd_efw *efw = substream->private_data; | ||
306 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
307 | int err; | ||
308 | |||
309 | err = snd_efw_stream_start_duplex(efw, runtime->rate); | ||
310 | if (err >= 0) | ||
311 | amdtp_stream_pcm_prepare(&efw->rx_stream); | ||
312 | |||
313 | return err; | ||
314 | } | ||
315 | |||
316 | static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) | ||
317 | { | ||
318 | struct snd_efw *efw = substream->private_data; | ||
319 | |||
320 | switch (cmd) { | ||
321 | case SNDRV_PCM_TRIGGER_START: | ||
322 | amdtp_stream_pcm_trigger(&efw->tx_stream, substream); | ||
323 | break; | ||
324 | case SNDRV_PCM_TRIGGER_STOP: | ||
325 | amdtp_stream_pcm_trigger(&efw->tx_stream, NULL); | ||
326 | break; | ||
327 | default: | ||
328 | return -EINVAL; | ||
329 | } | ||
330 | |||
331 | return 0; | ||
332 | } | ||
333 | static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) | ||
334 | { | ||
335 | struct snd_efw *efw = substream->private_data; | ||
336 | |||
337 | switch (cmd) { | ||
338 | case SNDRV_PCM_TRIGGER_START: | ||
339 | amdtp_stream_pcm_trigger(&efw->rx_stream, substream); | ||
340 | break; | ||
341 | case SNDRV_PCM_TRIGGER_STOP: | ||
342 | amdtp_stream_pcm_trigger(&efw->rx_stream, NULL); | ||
343 | break; | ||
344 | default: | ||
345 | return -EINVAL; | ||
346 | } | ||
347 | |||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm) | ||
352 | { | ||
353 | struct snd_efw *efw = sbstrm->private_data; | ||
354 | return amdtp_stream_pcm_pointer(&efw->tx_stream); | ||
355 | } | ||
356 | static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm) | ||
357 | { | ||
358 | struct snd_efw *efw = sbstrm->private_data; | ||
359 | return amdtp_stream_pcm_pointer(&efw->rx_stream); | ||
360 | } | ||
361 | |||
362 | static const struct snd_pcm_ops pcm_capture_ops = { | ||
363 | .open = pcm_open, | ||
364 | .close = pcm_close, | ||
365 | .ioctl = snd_pcm_lib_ioctl, | ||
366 | .hw_params = pcm_capture_hw_params, | ||
367 | .hw_free = pcm_capture_hw_free, | ||
368 | .prepare = pcm_capture_prepare, | ||
369 | .trigger = pcm_capture_trigger, | ||
370 | .pointer = pcm_capture_pointer, | ||
371 | .page = snd_pcm_lib_get_vmalloc_page, | ||
372 | }; | ||
373 | |||
374 | static const struct snd_pcm_ops pcm_playback_ops = { | ||
375 | .open = pcm_open, | ||
376 | .close = pcm_close, | ||
377 | .ioctl = snd_pcm_lib_ioctl, | ||
378 | .hw_params = pcm_playback_hw_params, | ||
379 | .hw_free = pcm_playback_hw_free, | ||
380 | .prepare = pcm_playback_prepare, | ||
381 | .trigger = pcm_playback_trigger, | ||
382 | .pointer = pcm_playback_pointer, | ||
383 | .page = snd_pcm_lib_get_vmalloc_page, | ||
384 | .mmap = snd_pcm_lib_mmap_vmalloc, | ||
385 | }; | ||
386 | |||
387 | int snd_efw_create_pcm_devices(struct snd_efw *efw) | ||
388 | { | ||
389 | struct snd_pcm *pcm; | ||
390 | int err; | ||
391 | |||
392 | err = snd_pcm_new(efw->card, efw->card->driver, 0, 1, 1, &pcm); | ||
393 | if (err < 0) | ||
394 | goto end; | ||
395 | |||
396 | pcm->private_data = efw; | ||
397 | snprintf(pcm->name, sizeof(pcm->name), "%s PCM", efw->card->shortname); | ||
398 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops); | ||
399 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops); | ||
400 | end: | ||
401 | return err; | ||
402 | } | ||
403 | |||
diff --git a/sound/firewire/fireworks/fireworks_proc.c b/sound/firewire/fireworks/fireworks_proc.c new file mode 100644 index 000000000000..f29d4aaf56a1 --- /dev/null +++ b/sound/firewire/fireworks/fireworks_proc.c | |||
@@ -0,0 +1,232 @@ | |||
1 | /* | ||
2 | * fireworks_proc.c - a part of driver for Fireworks based devices | ||
3 | * | ||
4 | * Copyright (c) 2009-2010 Clemens Ladisch | ||
5 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
6 | * | ||
7 | * Licensed under the terms of the GNU General Public License, version 2. | ||
8 | */ | ||
9 | |||
10 | #include "./fireworks.h" | ||
11 | |||
12 | static inline const char* | ||
13 | get_phys_name(struct snd_efw_phys_grp *grp, bool input) | ||
14 | { | ||
15 | const char *const ch_type[] = { | ||
16 | "Analog", "S/PDIF", "ADAT", "S/PDIF or ADAT", "Mirroring", | ||
17 | "Headphones", "I2S", "Guitar", "Pirzo Guitar", "Guitar String", | ||
18 | }; | ||
19 | |||
20 | if (grp->type < ARRAY_SIZE(ch_type)) | ||
21 | return ch_type[grp->type]; | ||
22 | else if (input) | ||
23 | return "Input"; | ||
24 | else | ||
25 | return "Output"; | ||
26 | } | ||
27 | |||
28 | static void | ||
29 | proc_read_hwinfo(struct snd_info_entry *entry, struct snd_info_buffer *buffer) | ||
30 | { | ||
31 | struct snd_efw *efw = entry->private_data; | ||
32 | unsigned short i; | ||
33 | struct snd_efw_hwinfo *hwinfo; | ||
34 | |||
35 | hwinfo = kmalloc(sizeof(struct snd_efw_hwinfo), GFP_KERNEL); | ||
36 | if (hwinfo == NULL) | ||
37 | return; | ||
38 | |||
39 | if (snd_efw_command_get_hwinfo(efw, hwinfo) < 0) | ||
40 | goto end; | ||
41 | |||
42 | snd_iprintf(buffer, "guid_hi: 0x%X\n", hwinfo->guid_hi); | ||
43 | snd_iprintf(buffer, "guid_lo: 0x%X\n", hwinfo->guid_lo); | ||
44 | snd_iprintf(buffer, "type: 0x%X\n", hwinfo->type); | ||
45 | snd_iprintf(buffer, "version: 0x%X\n", hwinfo->version); | ||
46 | snd_iprintf(buffer, "vendor_name: %s\n", hwinfo->vendor_name); | ||
47 | snd_iprintf(buffer, "model_name: %s\n", hwinfo->model_name); | ||
48 | |||
49 | snd_iprintf(buffer, "dsp_version: 0x%X\n", hwinfo->dsp_version); | ||
50 | snd_iprintf(buffer, "arm_version: 0x%X\n", hwinfo->arm_version); | ||
51 | snd_iprintf(buffer, "fpga_version: 0x%X\n", hwinfo->fpga_version); | ||
52 | |||
53 | snd_iprintf(buffer, "flags: 0x%X\n", hwinfo->flags); | ||
54 | |||
55 | snd_iprintf(buffer, "max_sample_rate: 0x%X\n", hwinfo->max_sample_rate); | ||
56 | snd_iprintf(buffer, "min_sample_rate: 0x%X\n", hwinfo->min_sample_rate); | ||
57 | snd_iprintf(buffer, "supported_clock: 0x%X\n", | ||
58 | hwinfo->supported_clocks); | ||
59 | |||
60 | snd_iprintf(buffer, "phys out: 0x%X\n", hwinfo->phys_out); | ||
61 | snd_iprintf(buffer, "phys in: 0x%X\n", hwinfo->phys_in); | ||
62 | |||
63 | snd_iprintf(buffer, "phys in grps: 0x%X\n", | ||
64 | hwinfo->phys_in_grp_count); | ||
65 | for (i = 0; i < hwinfo->phys_in_grp_count; i++) { | ||
66 | snd_iprintf(buffer, | ||
67 | "phys in grp[0x%d]: type 0x%d, count 0x%d\n", | ||
68 | i, hwinfo->phys_out_grps[i].type, | ||
69 | hwinfo->phys_out_grps[i].count); | ||
70 | } | ||
71 | |||
72 | snd_iprintf(buffer, "phys out grps: 0x%X\n", | ||
73 | hwinfo->phys_out_grp_count); | ||
74 | for (i = 0; i < hwinfo->phys_out_grp_count; i++) { | ||
75 | snd_iprintf(buffer, | ||
76 | "phys out grps[0x%d]: type 0x%d, count 0x%d\n", | ||
77 | i, hwinfo->phys_out_grps[i].type, | ||
78 | hwinfo->phys_out_grps[i].count); | ||
79 | } | ||
80 | |||
81 | snd_iprintf(buffer, "amdtp rx pcm channels 1x: 0x%X\n", | ||
82 | hwinfo->amdtp_rx_pcm_channels); | ||
83 | snd_iprintf(buffer, "amdtp tx pcm channels 1x: 0x%X\n", | ||
84 | hwinfo->amdtp_tx_pcm_channels); | ||
85 | snd_iprintf(buffer, "amdtp rx pcm channels 2x: 0x%X\n", | ||
86 | hwinfo->amdtp_rx_pcm_channels_2x); | ||
87 | snd_iprintf(buffer, "amdtp tx pcm channels 2x: 0x%X\n", | ||
88 | hwinfo->amdtp_tx_pcm_channels_2x); | ||
89 | snd_iprintf(buffer, "amdtp rx pcm channels 4x: 0x%X\n", | ||
90 | hwinfo->amdtp_rx_pcm_channels_4x); | ||
91 | snd_iprintf(buffer, "amdtp tx pcm channels 4x: 0x%X\n", | ||
92 | hwinfo->amdtp_tx_pcm_channels_4x); | ||
93 | |||
94 | snd_iprintf(buffer, "midi out ports: 0x%X\n", hwinfo->midi_out_ports); | ||
95 | snd_iprintf(buffer, "midi in ports: 0x%X\n", hwinfo->midi_in_ports); | ||
96 | |||
97 | snd_iprintf(buffer, "mixer playback channels: 0x%X\n", | ||
98 | hwinfo->mixer_playback_channels); | ||
99 | snd_iprintf(buffer, "mixer capture channels: 0x%X\n", | ||
100 | hwinfo->mixer_capture_channels); | ||
101 | end: | ||
102 | kfree(hwinfo); | ||
103 | } | ||
104 | |||
105 | static void | ||
106 | proc_read_clock(struct snd_info_entry *entry, struct snd_info_buffer *buffer) | ||
107 | { | ||
108 | struct snd_efw *efw = entry->private_data; | ||
109 | enum snd_efw_clock_source clock_source; | ||
110 | unsigned int sampling_rate; | ||
111 | |||
112 | if (snd_efw_command_get_clock_source(efw, &clock_source) < 0) | ||
113 | return; | ||
114 | |||
115 | if (snd_efw_command_get_sampling_rate(efw, &sampling_rate) < 0) | ||
116 | return; | ||
117 | |||
118 | snd_iprintf(buffer, "Clock Source: %d\n", clock_source); | ||
119 | snd_iprintf(buffer, "Sampling Rate: %d\n", sampling_rate); | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * NOTE: | ||
124 | * dB = 20 * log10(linear / 0x01000000) | ||
125 | * -144.0 dB when linear is 0 | ||
126 | */ | ||
127 | static void | ||
128 | proc_read_phys_meters(struct snd_info_entry *entry, | ||
129 | struct snd_info_buffer *buffer) | ||
130 | { | ||
131 | struct snd_efw *efw = entry->private_data; | ||
132 | struct snd_efw_phys_meters *meters; | ||
133 | unsigned int g, c, m, max, size; | ||
134 | const char *name; | ||
135 | u32 *linear; | ||
136 | int err; | ||
137 | |||
138 | size = sizeof(struct snd_efw_phys_meters) + | ||
139 | (efw->phys_in + efw->phys_out) * sizeof(u32); | ||
140 | meters = kzalloc(size, GFP_KERNEL); | ||
141 | if (meters == NULL) | ||
142 | return; | ||
143 | |||
144 | err = snd_efw_command_get_phys_meters(efw, meters, size); | ||
145 | if (err < 0) | ||
146 | goto end; | ||
147 | |||
148 | snd_iprintf(buffer, "Physical Meters:\n"); | ||
149 | |||
150 | m = 0; | ||
151 | max = min(efw->phys_out, meters->out_meters); | ||
152 | linear = meters->values; | ||
153 | snd_iprintf(buffer, " %d Outputs:\n", max); | ||
154 | for (g = 0; g < efw->phys_out_grp_count; g++) { | ||
155 | name = get_phys_name(&efw->phys_out_grps[g], false); | ||
156 | for (c = 0; c < efw->phys_out_grps[g].count; c++) { | ||
157 | if (m < max) | ||
158 | snd_iprintf(buffer, "\t%s [%d]: %d\n", | ||
159 | name, c, linear[m++]); | ||
160 | } | ||
161 | } | ||
162 | |||
163 | m = 0; | ||
164 | max = min(efw->phys_in, meters->in_meters); | ||
165 | linear = meters->values + meters->out_meters; | ||
166 | snd_iprintf(buffer, " %d Inputs:\n", max); | ||
167 | for (g = 0; g < efw->phys_in_grp_count; g++) { | ||
168 | name = get_phys_name(&efw->phys_in_grps[g], true); | ||
169 | for (c = 0; c < efw->phys_in_grps[g].count; c++) | ||
170 | if (m < max) | ||
171 | snd_iprintf(buffer, "\t%s [%d]: %d\n", | ||
172 | name, c, linear[m++]); | ||
173 | } | ||
174 | end: | ||
175 | kfree(meters); | ||
176 | } | ||
177 | |||
178 | static void | ||
179 | proc_read_queues_state(struct snd_info_entry *entry, | ||
180 | struct snd_info_buffer *buffer) | ||
181 | { | ||
182 | struct snd_efw *efw = entry->private_data; | ||
183 | unsigned int consumed; | ||
184 | |||
185 | if (efw->pull_ptr > efw->push_ptr) | ||
186 | consumed = snd_efw_resp_buf_size - | ||
187 | (unsigned int)(efw->pull_ptr - efw->push_ptr); | ||
188 | else | ||
189 | consumed = (unsigned int)(efw->push_ptr - efw->pull_ptr); | ||
190 | |||
191 | snd_iprintf(buffer, "%d %d/%d\n", | ||
192 | efw->resp_queues, consumed, snd_efw_resp_buf_size); | ||
193 | } | ||
194 | |||
195 | static void | ||
196 | add_node(struct snd_efw *efw, struct snd_info_entry *root, const char *name, | ||
197 | void (*op)(struct snd_info_entry *e, struct snd_info_buffer *b)) | ||
198 | { | ||
199 | struct snd_info_entry *entry; | ||
200 | |||
201 | entry = snd_info_create_card_entry(efw->card, name, root); | ||
202 | if (entry == NULL) | ||
203 | return; | ||
204 | |||
205 | snd_info_set_text_ops(entry, efw, op); | ||
206 | if (snd_info_register(entry) < 0) | ||
207 | snd_info_free_entry(entry); | ||
208 | } | ||
209 | |||
210 | void snd_efw_proc_init(struct snd_efw *efw) | ||
211 | { | ||
212 | struct snd_info_entry *root; | ||
213 | |||
214 | /* | ||
215 | * All nodes are automatically removed at snd_card_disconnect(), | ||
216 | * by following to link list. | ||
217 | */ | ||
218 | root = snd_info_create_card_entry(efw->card, "firewire", | ||
219 | efw->card->proc_root); | ||
220 | if (root == NULL) | ||
221 | return; | ||
222 | root->mode = S_IFDIR | S_IRUGO | S_IXUGO; | ||
223 | if (snd_info_register(root) < 0) { | ||
224 | snd_info_free_entry(root); | ||
225 | return; | ||
226 | } | ||
227 | |||
228 | add_node(efw, root, "clock", proc_read_clock); | ||
229 | add_node(efw, root, "firmware", proc_read_hwinfo); | ||
230 | add_node(efw, root, "meters", proc_read_phys_meters); | ||
231 | add_node(efw, root, "queues", proc_read_queues_state); | ||
232 | } | ||
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c new file mode 100644 index 000000000000..541569022a7c --- /dev/null +++ b/sound/firewire/fireworks/fireworks_stream.c | |||
@@ -0,0 +1,372 @@ | |||
1 | /* | ||
2 | * fireworks_stream.c - a part of driver for Fireworks based devices | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | #include "./fireworks.h" | ||
9 | |||
10 | #define CALLBACK_TIMEOUT 100 | ||
11 | |||
12 | static int | ||
13 | init_stream(struct snd_efw *efw, struct amdtp_stream *stream) | ||
14 | { | ||
15 | struct cmp_connection *conn; | ||
16 | enum cmp_direction c_dir; | ||
17 | enum amdtp_stream_direction s_dir; | ||
18 | int err; | ||
19 | |||
20 | if (stream == &efw->tx_stream) { | ||
21 | conn = &efw->out_conn; | ||
22 | c_dir = CMP_OUTPUT; | ||
23 | s_dir = AMDTP_IN_STREAM; | ||
24 | } else { | ||
25 | conn = &efw->in_conn; | ||
26 | c_dir = CMP_INPUT; | ||
27 | s_dir = AMDTP_OUT_STREAM; | ||
28 | } | ||
29 | |||
30 | err = cmp_connection_init(conn, efw->unit, c_dir, 0); | ||
31 | if (err < 0) | ||
32 | goto end; | ||
33 | |||
34 | err = amdtp_stream_init(stream, efw->unit, s_dir, CIP_BLOCKING); | ||
35 | if (err < 0) { | ||
36 | amdtp_stream_destroy(stream); | ||
37 | cmp_connection_destroy(conn); | ||
38 | } | ||
39 | end: | ||
40 | return err; | ||
41 | } | ||
42 | |||
43 | static void | ||
44 | stop_stream(struct snd_efw *efw, struct amdtp_stream *stream) | ||
45 | { | ||
46 | amdtp_stream_pcm_abort(stream); | ||
47 | amdtp_stream_stop(stream); | ||
48 | |||
49 | if (stream == &efw->tx_stream) | ||
50 | cmp_connection_break(&efw->out_conn); | ||
51 | else | ||
52 | cmp_connection_break(&efw->in_conn); | ||
53 | } | ||
54 | |||
55 | static int | ||
56 | start_stream(struct snd_efw *efw, struct amdtp_stream *stream, | ||
57 | unsigned int sampling_rate) | ||
58 | { | ||
59 | struct cmp_connection *conn; | ||
60 | unsigned int mode, pcm_channels, midi_ports; | ||
61 | int err; | ||
62 | |||
63 | err = snd_efw_get_multiplier_mode(sampling_rate, &mode); | ||
64 | if (err < 0) | ||
65 | goto end; | ||
66 | if (stream == &efw->tx_stream) { | ||
67 | conn = &efw->out_conn; | ||
68 | pcm_channels = efw->pcm_capture_channels[mode]; | ||
69 | midi_ports = efw->midi_out_ports; | ||
70 | } else { | ||
71 | conn = &efw->in_conn; | ||
72 | pcm_channels = efw->pcm_playback_channels[mode]; | ||
73 | midi_ports = efw->midi_in_ports; | ||
74 | } | ||
75 | |||
76 | amdtp_stream_set_parameters(stream, sampling_rate, | ||
77 | pcm_channels, midi_ports); | ||
78 | |||
79 | /* establish connection via CMP */ | ||
80 | err = cmp_connection_establish(conn, | ||
81 | amdtp_stream_get_max_payload(stream)); | ||
82 | if (err < 0) | ||
83 | goto end; | ||
84 | |||
85 | /* start amdtp stream */ | ||
86 | err = amdtp_stream_start(stream, | ||
87 | conn->resources.channel, | ||
88 | conn->speed); | ||
89 | if (err < 0) { | ||
90 | stop_stream(efw, stream); | ||
91 | goto end; | ||
92 | } | ||
93 | |||
94 | /* wait first callback */ | ||
95 | if (!amdtp_stream_wait_callback(stream, CALLBACK_TIMEOUT)) { | ||
96 | stop_stream(efw, stream); | ||
97 | err = -ETIMEDOUT; | ||
98 | } | ||
99 | end: | ||
100 | return err; | ||
101 | } | ||
102 | |||
103 | static void | ||
104 | destroy_stream(struct snd_efw *efw, struct amdtp_stream *stream) | ||
105 | { | ||
106 | stop_stream(efw, stream); | ||
107 | |||
108 | amdtp_stream_destroy(stream); | ||
109 | |||
110 | if (stream == &efw->tx_stream) | ||
111 | cmp_connection_destroy(&efw->out_conn); | ||
112 | else | ||
113 | cmp_connection_destroy(&efw->in_conn); | ||
114 | } | ||
115 | |||
116 | static int | ||
117 | get_sync_mode(struct snd_efw *efw, enum cip_flags *sync_mode) | ||
118 | { | ||
119 | enum snd_efw_clock_source clock_source; | ||
120 | int err; | ||
121 | |||
122 | err = snd_efw_command_get_clock_source(efw, &clock_source); | ||
123 | if (err < 0) | ||
124 | return err; | ||
125 | |||
126 | if (clock_source == SND_EFW_CLOCK_SOURCE_SYTMATCH) | ||
127 | return -ENOSYS; | ||
128 | |||
129 | *sync_mode = CIP_SYNC_TO_DEVICE; | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static int | ||
134 | check_connection_used_by_others(struct snd_efw *efw, struct amdtp_stream *s) | ||
135 | { | ||
136 | struct cmp_connection *conn; | ||
137 | bool used; | ||
138 | int err; | ||
139 | |||
140 | if (s == &efw->tx_stream) | ||
141 | conn = &efw->out_conn; | ||
142 | else | ||
143 | conn = &efw->in_conn; | ||
144 | |||
145 | err = cmp_connection_check_used(conn, &used); | ||
146 | if ((err >= 0) && used && !amdtp_stream_running(s)) { | ||
147 | dev_err(&efw->unit->device, | ||
148 | "Connection established by others: %cPCR[%d]\n", | ||
149 | (conn->direction == CMP_OUTPUT) ? 'o' : 'i', | ||
150 | conn->pcr_index); | ||
151 | err = -EBUSY; | ||
152 | } | ||
153 | |||
154 | return err; | ||
155 | } | ||
156 | |||
157 | int snd_efw_stream_init_duplex(struct snd_efw *efw) | ||
158 | { | ||
159 | int err; | ||
160 | |||
161 | err = init_stream(efw, &efw->tx_stream); | ||
162 | if (err < 0) | ||
163 | goto end; | ||
164 | /* Fireworks transmits NODATA packets with TAG0. */ | ||
165 | efw->tx_stream.flags |= CIP_EMPTY_WITH_TAG0; | ||
166 | /* Fireworks has its own meaning for dbc. */ | ||
167 | efw->tx_stream.flags |= CIP_DBC_IS_END_EVENT; | ||
168 | /* Fireworks reset dbc at bus reset. */ | ||
169 | efw->tx_stream.flags |= CIP_SKIP_DBC_ZERO_CHECK; | ||
170 | /* AudioFire9 always reports wrong dbs. */ | ||
171 | if (efw->is_af9) | ||
172 | efw->tx_stream.flags |= CIP_WRONG_DBS; | ||
173 | /* Firmware version 5.5 reports fixed interval for dbc. */ | ||
174 | if (efw->firmware_version == 0x5050000) | ||
175 | efw->tx_stream.tx_dbc_interval = 8; | ||
176 | |||
177 | err = init_stream(efw, &efw->rx_stream); | ||
178 | if (err < 0) { | ||
179 | destroy_stream(efw, &efw->tx_stream); | ||
180 | goto end; | ||
181 | } | ||
182 | /* | ||
183 | * Fireworks ignores MIDI messages in more than first 8 data | ||
184 | * blocks of an received AMDTP packet. | ||
185 | */ | ||
186 | efw->rx_stream.rx_blocks_for_midi = 8; | ||
187 | |||
188 | /* set IEC61883 compliant mode (actually not fully compliant...) */ | ||
189 | err = snd_efw_command_set_tx_mode(efw, SND_EFW_TRANSPORT_MODE_IEC61883); | ||
190 | if (err < 0) { | ||
191 | destroy_stream(efw, &efw->tx_stream); | ||
192 | destroy_stream(efw, &efw->rx_stream); | ||
193 | } | ||
194 | end: | ||
195 | return err; | ||
196 | } | ||
197 | |||
198 | int snd_efw_stream_start_duplex(struct snd_efw *efw, unsigned int rate) | ||
199 | { | ||
200 | struct amdtp_stream *master, *slave; | ||
201 | atomic_t *slave_substreams; | ||
202 | enum cip_flags sync_mode; | ||
203 | unsigned int curr_rate; | ||
204 | int err = 0; | ||
205 | |||
206 | mutex_lock(&efw->mutex); | ||
207 | |||
208 | /* Need no substreams */ | ||
209 | if ((atomic_read(&efw->playback_substreams) == 0) && | ||
210 | (atomic_read(&efw->capture_substreams) == 0)) | ||
211 | goto end; | ||
212 | |||
213 | err = get_sync_mode(efw, &sync_mode); | ||
214 | if (err < 0) | ||
215 | goto end; | ||
216 | if (sync_mode == CIP_SYNC_TO_DEVICE) { | ||
217 | master = &efw->tx_stream; | ||
218 | slave = &efw->rx_stream; | ||
219 | slave_substreams = &efw->playback_substreams; | ||
220 | } else { | ||
221 | master = &efw->rx_stream; | ||
222 | slave = &efw->tx_stream; | ||
223 | slave_substreams = &efw->capture_substreams; | ||
224 | } | ||
225 | |||
226 | /* | ||
227 | * Considering JACK/FFADO streaming: | ||
228 | * TODO: This can be removed hwdep functionality becomes popular. | ||
229 | */ | ||
230 | err = check_connection_used_by_others(efw, master); | ||
231 | if (err < 0) | ||
232 | goto end; | ||
233 | |||
234 | /* packet queueing error */ | ||
235 | if (amdtp_streaming_error(slave)) | ||
236 | stop_stream(efw, slave); | ||
237 | if (amdtp_streaming_error(master)) | ||
238 | stop_stream(efw, master); | ||
239 | |||
240 | /* stop streams if rate is different */ | ||
241 | err = snd_efw_command_get_sampling_rate(efw, &curr_rate); | ||
242 | if (err < 0) | ||
243 | goto end; | ||
244 | if (rate == 0) | ||
245 | rate = curr_rate; | ||
246 | if (rate != curr_rate) { | ||
247 | stop_stream(efw, slave); | ||
248 | stop_stream(efw, master); | ||
249 | } | ||
250 | |||
251 | /* master should be always running */ | ||
252 | if (!amdtp_stream_running(master)) { | ||
253 | amdtp_stream_set_sync(sync_mode, master, slave); | ||
254 | efw->master = master; | ||
255 | |||
256 | err = snd_efw_command_set_sampling_rate(efw, rate); | ||
257 | if (err < 0) | ||
258 | goto end; | ||
259 | |||
260 | err = start_stream(efw, master, rate); | ||
261 | if (err < 0) { | ||
262 | dev_err(&efw->unit->device, | ||
263 | "fail to start AMDTP master stream:%d\n", err); | ||
264 | goto end; | ||
265 | } | ||
266 | } | ||
267 | |||
268 | /* start slave if needed */ | ||
269 | if (atomic_read(slave_substreams) > 0 && !amdtp_stream_running(slave)) { | ||
270 | err = start_stream(efw, slave, rate); | ||
271 | if (err < 0) { | ||
272 | dev_err(&efw->unit->device, | ||
273 | "fail to start AMDTP slave stream:%d\n", err); | ||
274 | stop_stream(efw, master); | ||
275 | } | ||
276 | } | ||
277 | end: | ||
278 | mutex_unlock(&efw->mutex); | ||
279 | return err; | ||
280 | } | ||
281 | |||
282 | void snd_efw_stream_stop_duplex(struct snd_efw *efw) | ||
283 | { | ||
284 | struct amdtp_stream *master, *slave; | ||
285 | atomic_t *master_substreams, *slave_substreams; | ||
286 | |||
287 | mutex_lock(&efw->mutex); | ||
288 | |||
289 | if (efw->master == &efw->rx_stream) { | ||
290 | slave = &efw->tx_stream; | ||
291 | master = &efw->rx_stream; | ||
292 | slave_substreams = &efw->capture_substreams; | ||
293 | master_substreams = &efw->playback_substreams; | ||
294 | } else { | ||
295 | slave = &efw->rx_stream; | ||
296 | master = &efw->tx_stream; | ||
297 | slave_substreams = &efw->playback_substreams; | ||
298 | master_substreams = &efw->capture_substreams; | ||
299 | } | ||
300 | |||
301 | if (atomic_read(slave_substreams) == 0) { | ||
302 | stop_stream(efw, slave); | ||
303 | |||
304 | if (atomic_read(master_substreams) == 0) | ||
305 | stop_stream(efw, master); | ||
306 | } | ||
307 | |||
308 | mutex_unlock(&efw->mutex); | ||
309 | } | ||
310 | |||
311 | void snd_efw_stream_update_duplex(struct snd_efw *efw) | ||
312 | { | ||
313 | if ((cmp_connection_update(&efw->out_conn) < 0) || | ||
314 | (cmp_connection_update(&efw->in_conn) < 0)) { | ||
315 | mutex_lock(&efw->mutex); | ||
316 | stop_stream(efw, &efw->rx_stream); | ||
317 | stop_stream(efw, &efw->tx_stream); | ||
318 | mutex_unlock(&efw->mutex); | ||
319 | } else { | ||
320 | amdtp_stream_update(&efw->rx_stream); | ||
321 | amdtp_stream_update(&efw->tx_stream); | ||
322 | } | ||
323 | } | ||
324 | |||
325 | void snd_efw_stream_destroy_duplex(struct snd_efw *efw) | ||
326 | { | ||
327 | mutex_lock(&efw->mutex); | ||
328 | |||
329 | destroy_stream(efw, &efw->rx_stream); | ||
330 | destroy_stream(efw, &efw->tx_stream); | ||
331 | |||
332 | mutex_unlock(&efw->mutex); | ||
333 | } | ||
334 | |||
335 | void snd_efw_stream_lock_changed(struct snd_efw *efw) | ||
336 | { | ||
337 | efw->dev_lock_changed = true; | ||
338 | wake_up(&efw->hwdep_wait); | ||
339 | } | ||
340 | |||
341 | int snd_efw_stream_lock_try(struct snd_efw *efw) | ||
342 | { | ||
343 | int err; | ||
344 | |||
345 | spin_lock_irq(&efw->lock); | ||
346 | |||
347 | /* user land lock this */ | ||
348 | if (efw->dev_lock_count < 0) { | ||
349 | err = -EBUSY; | ||
350 | goto end; | ||
351 | } | ||
352 | |||
353 | /* this is the first time */ | ||
354 | if (efw->dev_lock_count++ == 0) | ||
355 | snd_efw_stream_lock_changed(efw); | ||
356 | err = 0; | ||
357 | end: | ||
358 | spin_unlock_irq(&efw->lock); | ||
359 | return err; | ||
360 | } | ||
361 | |||
362 | void snd_efw_stream_lock_release(struct snd_efw *efw) | ||
363 | { | ||
364 | spin_lock_irq(&efw->lock); | ||
365 | |||
366 | if (WARN_ON(efw->dev_lock_count <= 0)) | ||
367 | goto end; | ||
368 | if (--efw->dev_lock_count == 0) | ||
369 | snd_efw_stream_lock_changed(efw); | ||
370 | end: | ||
371 | spin_unlock_irq(&efw->lock); | ||
372 | } | ||
diff --git a/sound/firewire/fireworks/fireworks_transaction.c b/sound/firewire/fireworks/fireworks_transaction.c new file mode 100644 index 000000000000..aa56b8ac537c --- /dev/null +++ b/sound/firewire/fireworks/fireworks_transaction.c | |||
@@ -0,0 +1,326 @@ | |||
1 | /* | ||
2 | * fireworks_transaction.c - a part of driver for Fireworks based devices | ||
3 | * | ||
4 | * Copyright (c) 2013-2014 Takashi Sakamoto | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | /* | ||
10 | * Fireworks have its own transaction. The transaction can be delivered by AV/C | ||
11 | * Vendor Specific command. But at least Windows driver and firmware version 5.5 | ||
12 | * or later don't use it. | ||
13 | * | ||
14 | * Transaction substance: | ||
15 | * At first, 6 data exist. Following to the 6 data, parameters for each | ||
16 | * commands exists. All of parameters are 32 bit alighed to big endian. | ||
17 | * data[0]: Length of transaction substance | ||
18 | * data[1]: Transaction version | ||
19 | * data[2]: Sequence number. This is incremented by the device | ||
20 | * data[3]: transaction category | ||
21 | * data[4]: transaction command | ||
22 | * data[5]: return value in response. | ||
23 | * data[6-]: parameters | ||
24 | * | ||
25 | * Transaction address: | ||
26 | * command: 0xecc000000000 | ||
27 | * response: 0xecc080000000 (default) | ||
28 | * | ||
29 | * I note that the address for response can be changed by command. But this | ||
30 | * module uses the default address. | ||
31 | */ | ||
32 | #include "./fireworks.h" | ||
33 | |||
34 | #define MEMORY_SPACE_EFW_COMMAND 0xecc000000000ULL | ||
35 | #define MEMORY_SPACE_EFW_RESPONSE 0xecc080000000ULL | ||
36 | |||
37 | #define ERROR_RETRIES 3 | ||
38 | #define ERROR_DELAY_MS 5 | ||
39 | #define EFC_TIMEOUT_MS 125 | ||
40 | |||
41 | static DEFINE_SPINLOCK(instances_lock); | ||
42 | static struct snd_efw *instances[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; | ||
43 | |||
44 | static DEFINE_SPINLOCK(transaction_queues_lock); | ||
45 | static LIST_HEAD(transaction_queues); | ||
46 | |||
47 | enum transaction_queue_state { | ||
48 | STATE_PENDING, | ||
49 | STATE_BUS_RESET, | ||
50 | STATE_COMPLETE | ||
51 | }; | ||
52 | |||
53 | struct transaction_queue { | ||
54 | struct list_head list; | ||
55 | struct fw_unit *unit; | ||
56 | void *buf; | ||
57 | unsigned int size; | ||
58 | u32 seqnum; | ||
59 | enum transaction_queue_state state; | ||
60 | wait_queue_head_t wait; | ||
61 | }; | ||
62 | |||
63 | int snd_efw_transaction_cmd(struct fw_unit *unit, | ||
64 | const void *cmd, unsigned int size) | ||
65 | { | ||
66 | return snd_fw_transaction(unit, TCODE_WRITE_BLOCK_REQUEST, | ||
67 | MEMORY_SPACE_EFW_COMMAND, | ||
68 | (void *)cmd, size, 0); | ||
69 | } | ||
70 | |||
71 | int snd_efw_transaction_run(struct fw_unit *unit, | ||
72 | const void *cmd, unsigned int cmd_size, | ||
73 | void *resp, unsigned int resp_size) | ||
74 | { | ||
75 | struct transaction_queue t; | ||
76 | unsigned int tries; | ||
77 | int ret; | ||
78 | |||
79 | t.unit = unit; | ||
80 | t.buf = resp; | ||
81 | t.size = resp_size; | ||
82 | t.seqnum = be32_to_cpu(((struct snd_efw_transaction *)cmd)->seqnum) + 1; | ||
83 | t.state = STATE_PENDING; | ||
84 | init_waitqueue_head(&t.wait); | ||
85 | |||
86 | spin_lock_irq(&transaction_queues_lock); | ||
87 | list_add_tail(&t.list, &transaction_queues); | ||
88 | spin_unlock_irq(&transaction_queues_lock); | ||
89 | |||
90 | tries = 0; | ||
91 | do { | ||
92 | ret = snd_efw_transaction_cmd(t.unit, (void *)cmd, cmd_size); | ||
93 | if (ret < 0) | ||
94 | break; | ||
95 | |||
96 | wait_event_timeout(t.wait, t.state != STATE_PENDING, | ||
97 | msecs_to_jiffies(EFC_TIMEOUT_MS)); | ||
98 | |||
99 | if (t.state == STATE_COMPLETE) { | ||
100 | ret = t.size; | ||
101 | break; | ||
102 | } else if (t.state == STATE_BUS_RESET) { | ||
103 | msleep(ERROR_DELAY_MS); | ||
104 | } else if (++tries >= ERROR_RETRIES) { | ||
105 | dev_err(&t.unit->device, "EFW transaction timed out\n"); | ||
106 | ret = -EIO; | ||
107 | break; | ||
108 | } | ||
109 | } while (1); | ||
110 | |||
111 | spin_lock_irq(&transaction_queues_lock); | ||
112 | list_del(&t.list); | ||
113 | spin_unlock_irq(&transaction_queues_lock); | ||
114 | |||
115 | return ret; | ||
116 | } | ||
117 | |||
118 | static void | ||
119 | copy_resp_to_buf(struct snd_efw *efw, void *data, size_t length, int *rcode) | ||
120 | { | ||
121 | size_t capacity, till_end; | ||
122 | struct snd_efw_transaction *t; | ||
123 | |||
124 | spin_lock_irq(&efw->lock); | ||
125 | |||
126 | t = (struct snd_efw_transaction *)data; | ||
127 | length = min_t(size_t, t->length * sizeof(t->length), length); | ||
128 | |||
129 | if (efw->push_ptr < efw->pull_ptr) | ||
130 | capacity = (unsigned int)(efw->pull_ptr - efw->push_ptr); | ||
131 | else | ||
132 | capacity = snd_efw_resp_buf_size - | ||
133 | (unsigned int)(efw->push_ptr - efw->pull_ptr); | ||
134 | |||
135 | /* confirm enough space for this response */ | ||
136 | if (capacity < length) { | ||
137 | *rcode = RCODE_CONFLICT_ERROR; | ||
138 | goto end; | ||
139 | } | ||
140 | |||
141 | /* copy to ring buffer */ | ||
142 | while (length > 0) { | ||
143 | till_end = snd_efw_resp_buf_size - | ||
144 | (unsigned int)(efw->push_ptr - efw->resp_buf); | ||
145 | till_end = min_t(unsigned int, length, till_end); | ||
146 | |||
147 | memcpy(efw->push_ptr, data, till_end); | ||
148 | |||
149 | efw->push_ptr += till_end; | ||
150 | if (efw->push_ptr >= efw->resp_buf + snd_efw_resp_buf_size) | ||
151 | efw->push_ptr = efw->resp_buf; | ||
152 | |||
153 | length -= till_end; | ||
154 | data += till_end; | ||
155 | } | ||
156 | |||
157 | /* for hwdep */ | ||
158 | efw->resp_queues++; | ||
159 | wake_up(&efw->hwdep_wait); | ||
160 | |||
161 | *rcode = RCODE_COMPLETE; | ||
162 | end: | ||
163 | spin_unlock_irq(&efw->lock); | ||
164 | } | ||
165 | |||
166 | static void | ||
167 | handle_resp_for_user(struct fw_card *card, int generation, int source, | ||
168 | void *data, size_t length, int *rcode) | ||
169 | { | ||
170 | struct fw_device *device; | ||
171 | struct snd_efw *efw; | ||
172 | unsigned int i; | ||
173 | |||
174 | spin_lock_irq(&instances_lock); | ||
175 | |||
176 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
177 | efw = instances[i]; | ||
178 | if (efw == NULL) | ||
179 | continue; | ||
180 | device = fw_parent_device(efw->unit); | ||
181 | if ((device->card != card) || | ||
182 | (device->generation != generation)) | ||
183 | continue; | ||
184 | smp_rmb(); /* node id vs. generation */ | ||
185 | if (device->node_id != source) | ||
186 | continue; | ||
187 | |||
188 | break; | ||
189 | } | ||
190 | if (i == SNDRV_CARDS) | ||
191 | goto end; | ||
192 | |||
193 | copy_resp_to_buf(efw, data, length, rcode); | ||
194 | end: | ||
195 | spin_unlock_irq(&instances_lock); | ||
196 | } | ||
197 | |||
198 | static void | ||
199 | handle_resp_for_kernel(struct fw_card *card, int generation, int source, | ||
200 | void *data, size_t length, int *rcode, u32 seqnum) | ||
201 | { | ||
202 | struct fw_device *device; | ||
203 | struct transaction_queue *t; | ||
204 | unsigned long flags; | ||
205 | |||
206 | spin_lock_irqsave(&transaction_queues_lock, flags); | ||
207 | list_for_each_entry(t, &transaction_queues, list) { | ||
208 | device = fw_parent_device(t->unit); | ||
209 | if ((device->card != card) || | ||
210 | (device->generation != generation)) | ||
211 | continue; | ||
212 | smp_rmb(); /* node_id vs. generation */ | ||
213 | if (device->node_id != source) | ||
214 | continue; | ||
215 | |||
216 | if ((t->state == STATE_PENDING) && (t->seqnum == seqnum)) { | ||
217 | t->state = STATE_COMPLETE; | ||
218 | t->size = min_t(unsigned int, length, t->size); | ||
219 | memcpy(t->buf, data, t->size); | ||
220 | wake_up(&t->wait); | ||
221 | *rcode = RCODE_COMPLETE; | ||
222 | } | ||
223 | } | ||
224 | spin_unlock_irqrestore(&transaction_queues_lock, flags); | ||
225 | } | ||
226 | |||
227 | static void | ||
228 | efw_response(struct fw_card *card, struct fw_request *request, | ||
229 | int tcode, int destination, int source, | ||
230 | int generation, unsigned long long offset, | ||
231 | void *data, size_t length, void *callback_data) | ||
232 | { | ||
233 | int rcode, dummy; | ||
234 | u32 seqnum; | ||
235 | |||
236 | rcode = RCODE_TYPE_ERROR; | ||
237 | if (length < sizeof(struct snd_efw_transaction)) { | ||
238 | rcode = RCODE_DATA_ERROR; | ||
239 | goto end; | ||
240 | } else if (offset != MEMORY_SPACE_EFW_RESPONSE) { | ||
241 | rcode = RCODE_ADDRESS_ERROR; | ||
242 | goto end; | ||
243 | } | ||
244 | |||
245 | seqnum = be32_to_cpu(((struct snd_efw_transaction *)data)->seqnum); | ||
246 | if (seqnum > SND_EFW_TRANSACTION_USER_SEQNUM_MAX + 1) { | ||
247 | handle_resp_for_kernel(card, generation, source, | ||
248 | data, length, &rcode, seqnum); | ||
249 | if (snd_efw_resp_buf_debug) | ||
250 | handle_resp_for_user(card, generation, source, | ||
251 | data, length, &dummy); | ||
252 | } else { | ||
253 | handle_resp_for_user(card, generation, source, | ||
254 | data, length, &rcode); | ||
255 | } | ||
256 | end: | ||
257 | fw_send_response(card, request, rcode); | ||
258 | } | ||
259 | |||
260 | void snd_efw_transaction_add_instance(struct snd_efw *efw) | ||
261 | { | ||
262 | unsigned int i; | ||
263 | |||
264 | spin_lock_irq(&instances_lock); | ||
265 | |||
266 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
267 | if (instances[i] != NULL) | ||
268 | continue; | ||
269 | instances[i] = efw; | ||
270 | break; | ||
271 | } | ||
272 | |||
273 | spin_unlock_irq(&instances_lock); | ||
274 | } | ||
275 | |||
276 | void snd_efw_transaction_remove_instance(struct snd_efw *efw) | ||
277 | { | ||
278 | unsigned int i; | ||
279 | |||
280 | spin_lock_irq(&instances_lock); | ||
281 | |||
282 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
283 | if (instances[i] != efw) | ||
284 | continue; | ||
285 | instances[i] = NULL; | ||
286 | } | ||
287 | |||
288 | spin_unlock_irq(&instances_lock); | ||
289 | } | ||
290 | |||
291 | void snd_efw_transaction_bus_reset(struct fw_unit *unit) | ||
292 | { | ||
293 | struct transaction_queue *t; | ||
294 | |||
295 | spin_lock_irq(&transaction_queues_lock); | ||
296 | list_for_each_entry(t, &transaction_queues, list) { | ||
297 | if ((t->unit == unit) && | ||
298 | (t->state == STATE_PENDING)) { | ||
299 | t->state = STATE_BUS_RESET; | ||
300 | wake_up(&t->wait); | ||
301 | } | ||
302 | } | ||
303 | spin_unlock_irq(&transaction_queues_lock); | ||
304 | } | ||
305 | |||
306 | static struct fw_address_handler resp_register_handler = { | ||
307 | .length = SND_EFW_RESPONSE_MAXIMUM_BYTES, | ||
308 | .address_callback = efw_response | ||
309 | }; | ||
310 | |||
311 | int snd_efw_transaction_register(void) | ||
312 | { | ||
313 | static const struct fw_address_region resp_register_region = { | ||
314 | .start = MEMORY_SPACE_EFW_RESPONSE, | ||
315 | .end = MEMORY_SPACE_EFW_RESPONSE + | ||
316 | SND_EFW_RESPONSE_MAXIMUM_BYTES | ||
317 | }; | ||
318 | return fw_core_add_address_handler(&resp_register_handler, | ||
319 | &resp_register_region); | ||
320 | } | ||
321 | |||
322 | void snd_efw_transaction_unregister(void) | ||
323 | { | ||
324 | WARN_ON(!list_empty(&transaction_queues)); | ||
325 | fw_core_remove_address_handler(&resp_register_handler); | ||
326 | } | ||
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c index 9f7ef219b109..768d40ddfebb 100644 --- a/sound/firewire/speakers.c +++ b/sound/firewire/speakers.c | |||
@@ -51,7 +51,7 @@ struct fwspk { | |||
51 | const struct device_info *device_info; | 51 | const struct device_info *device_info; |
52 | struct mutex mutex; | 52 | struct mutex mutex; |
53 | struct cmp_connection connection; | 53 | struct cmp_connection connection; |
54 | struct amdtp_out_stream stream; | 54 | struct amdtp_stream stream; |
55 | bool mute; | 55 | bool mute; |
56 | s16 volume[6]; | 56 | s16 volume[6]; |
57 | s16 volume_min; | 57 | s16 volume_min; |
@@ -167,13 +167,7 @@ static int fwspk_open(struct snd_pcm_substream *substream) | |||
167 | if (err < 0) | 167 | if (err < 0) |
168 | return err; | 168 | return err; |
169 | 169 | ||
170 | err = snd_pcm_hw_constraint_minmax(runtime, | 170 | err = amdtp_stream_add_pcm_hw_constraints(&fwspk->stream, runtime); |
171 | SNDRV_PCM_HW_PARAM_PERIOD_TIME, | ||
172 | 5000, UINT_MAX); | ||
173 | if (err < 0) | ||
174 | return err; | ||
175 | |||
176 | err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); | ||
177 | if (err < 0) | 171 | if (err < 0) |
178 | return err; | 172 | return err; |
179 | 173 | ||
@@ -187,48 +181,12 @@ static int fwspk_close(struct snd_pcm_substream *substream) | |||
187 | 181 | ||
188 | static void fwspk_stop_stream(struct fwspk *fwspk) | 182 | static void fwspk_stop_stream(struct fwspk *fwspk) |
189 | { | 183 | { |
190 | if (amdtp_out_stream_running(&fwspk->stream)) { | 184 | if (amdtp_stream_running(&fwspk->stream)) { |
191 | amdtp_out_stream_stop(&fwspk->stream); | 185 | amdtp_stream_stop(&fwspk->stream); |
192 | cmp_connection_break(&fwspk->connection); | 186 | cmp_connection_break(&fwspk->connection); |
193 | } | 187 | } |
194 | } | 188 | } |
195 | 189 | ||
196 | static int fwspk_set_rate(struct fwspk *fwspk, unsigned int sfc) | ||
197 | { | ||
198 | u8 *buf; | ||
199 | int err; | ||
200 | |||
201 | buf = kmalloc(8, GFP_KERNEL); | ||
202 | if (!buf) | ||
203 | return -ENOMEM; | ||
204 | |||
205 | buf[0] = 0x00; /* AV/C, CONTROL */ | ||
206 | buf[1] = 0xff; /* unit */ | ||
207 | buf[2] = 0x19; /* INPUT PLUG SIGNAL FORMAT */ | ||
208 | buf[3] = 0x00; /* plug 0 */ | ||
209 | buf[4] = 0x90; /* format: audio */ | ||
210 | buf[5] = 0x00 | sfc; /* AM824, frequency */ | ||
211 | buf[6] = 0xff; /* SYT (not used) */ | ||
212 | buf[7] = 0xff; | ||
213 | |||
214 | err = fcp_avc_transaction(fwspk->unit, buf, 8, buf, 8, | ||
215 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5)); | ||
216 | if (err < 0) | ||
217 | goto error; | ||
218 | if (err < 6 || buf[0] != 0x09 /* ACCEPTED */) { | ||
219 | dev_err(&fwspk->unit->device, "failed to set sample rate\n"); | ||
220 | err = -EIO; | ||
221 | goto error; | ||
222 | } | ||
223 | |||
224 | err = 0; | ||
225 | |||
226 | error: | ||
227 | kfree(buf); | ||
228 | |||
229 | return err; | ||
230 | } | ||
231 | |||
232 | static int fwspk_hw_params(struct snd_pcm_substream *substream, | 190 | static int fwspk_hw_params(struct snd_pcm_substream *substream, |
233 | struct snd_pcm_hw_params *hw_params) | 191 | struct snd_pcm_hw_params *hw_params) |
234 | { | 192 | { |
@@ -244,17 +202,20 @@ static int fwspk_hw_params(struct snd_pcm_substream *substream, | |||
244 | if (err < 0) | 202 | if (err < 0) |
245 | goto error; | 203 | goto error; |
246 | 204 | ||
247 | amdtp_out_stream_set_parameters(&fwspk->stream, | 205 | amdtp_stream_set_parameters(&fwspk->stream, |
248 | params_rate(hw_params), | 206 | params_rate(hw_params), |
249 | params_channels(hw_params), | 207 | params_channels(hw_params), |
250 | 0); | 208 | 0); |
251 | 209 | ||
252 | amdtp_out_stream_set_pcm_format(&fwspk->stream, | 210 | amdtp_stream_set_pcm_format(&fwspk->stream, |
253 | params_format(hw_params)); | 211 | params_format(hw_params)); |
254 | 212 | ||
255 | err = fwspk_set_rate(fwspk, fwspk->stream.sfc); | 213 | err = avc_general_set_sig_fmt(fwspk->unit, params_rate(hw_params), |
256 | if (err < 0) | 214 | AVC_GENERAL_PLUG_DIR_IN, 0); |
215 | if (err < 0) { | ||
216 | dev_err(&fwspk->unit->device, "failed to set sample rate\n"); | ||
257 | goto err_buffer; | 217 | goto err_buffer; |
218 | } | ||
258 | 219 | ||
259 | return 0; | 220 | return 0; |
260 | 221 | ||
@@ -282,25 +243,25 @@ static int fwspk_prepare(struct snd_pcm_substream *substream) | |||
282 | 243 | ||
283 | mutex_lock(&fwspk->mutex); | 244 | mutex_lock(&fwspk->mutex); |
284 | 245 | ||
285 | if (amdtp_out_streaming_error(&fwspk->stream)) | 246 | if (amdtp_streaming_error(&fwspk->stream)) |
286 | fwspk_stop_stream(fwspk); | 247 | fwspk_stop_stream(fwspk); |
287 | 248 | ||
288 | if (!amdtp_out_stream_running(&fwspk->stream)) { | 249 | if (!amdtp_stream_running(&fwspk->stream)) { |
289 | err = cmp_connection_establish(&fwspk->connection, | 250 | err = cmp_connection_establish(&fwspk->connection, |
290 | amdtp_out_stream_get_max_payload(&fwspk->stream)); | 251 | amdtp_stream_get_max_payload(&fwspk->stream)); |
291 | if (err < 0) | 252 | if (err < 0) |
292 | goto err_mutex; | 253 | goto err_mutex; |
293 | 254 | ||
294 | err = amdtp_out_stream_start(&fwspk->stream, | 255 | err = amdtp_stream_start(&fwspk->stream, |
295 | fwspk->connection.resources.channel, | 256 | fwspk->connection.resources.channel, |
296 | fwspk->connection.speed); | 257 | fwspk->connection.speed); |
297 | if (err < 0) | 258 | if (err < 0) |
298 | goto err_connection; | 259 | goto err_connection; |
299 | } | 260 | } |
300 | 261 | ||
301 | mutex_unlock(&fwspk->mutex); | 262 | mutex_unlock(&fwspk->mutex); |
302 | 263 | ||
303 | amdtp_out_stream_pcm_prepare(&fwspk->stream); | 264 | amdtp_stream_pcm_prepare(&fwspk->stream); |
304 | 265 | ||
305 | return 0; | 266 | return 0; |
306 | 267 | ||
@@ -327,7 +288,7 @@ static int fwspk_trigger(struct snd_pcm_substream *substream, int cmd) | |||
327 | default: | 288 | default: |
328 | return -EINVAL; | 289 | return -EINVAL; |
329 | } | 290 | } |
330 | amdtp_out_stream_pcm_trigger(&fwspk->stream, pcm); | 291 | amdtp_stream_pcm_trigger(&fwspk->stream, pcm); |
331 | return 0; | 292 | return 0; |
332 | } | 293 | } |
333 | 294 | ||
@@ -335,7 +296,7 @@ static snd_pcm_uframes_t fwspk_pointer(struct snd_pcm_substream *substream) | |||
335 | { | 296 | { |
336 | struct fwspk *fwspk = substream->private_data; | 297 | struct fwspk *fwspk = substream->private_data; |
337 | 298 | ||
338 | return amdtp_out_stream_pcm_pointer(&fwspk->stream); | 299 | return amdtp_stream_pcm_pointer(&fwspk->stream); |
339 | } | 300 | } |
340 | 301 | ||
341 | static int fwspk_create_pcm(struct fwspk *fwspk) | 302 | static int fwspk_create_pcm(struct fwspk *fwspk) |
@@ -653,7 +614,7 @@ static void fwspk_card_free(struct snd_card *card) | |||
653 | { | 614 | { |
654 | struct fwspk *fwspk = card->private_data; | 615 | struct fwspk *fwspk = card->private_data; |
655 | 616 | ||
656 | amdtp_out_stream_destroy(&fwspk->stream); | 617 | amdtp_stream_destroy(&fwspk->stream); |
657 | cmp_connection_destroy(&fwspk->connection); | 618 | cmp_connection_destroy(&fwspk->connection); |
658 | fw_unit_put(fwspk->unit); | 619 | fw_unit_put(fwspk->unit); |
659 | mutex_destroy(&fwspk->mutex); | 620 | mutex_destroy(&fwspk->mutex); |
@@ -679,11 +640,12 @@ static int fwspk_probe(struct fw_unit *unit, | |||
679 | fwspk->unit = fw_unit_get(unit); | 640 | fwspk->unit = fw_unit_get(unit); |
680 | fwspk->device_info = (const struct device_info *)id->driver_data; | 641 | fwspk->device_info = (const struct device_info *)id->driver_data; |
681 | 642 | ||
682 | err = cmp_connection_init(&fwspk->connection, unit, 0); | 643 | err = cmp_connection_init(&fwspk->connection, unit, CMP_INPUT, 0); |
683 | if (err < 0) | 644 | if (err < 0) |
684 | goto err_unit; | 645 | goto err_unit; |
685 | 646 | ||
686 | err = amdtp_out_stream_init(&fwspk->stream, unit, CIP_NONBLOCKING); | 647 | err = amdtp_stream_init(&fwspk->stream, unit, AMDTP_OUT_STREAM, |
648 | CIP_NONBLOCKING); | ||
687 | if (err < 0) | 649 | if (err < 0) |
688 | goto err_connection; | 650 | goto err_connection; |
689 | 651 | ||
@@ -733,21 +695,21 @@ static void fwspk_bus_reset(struct fw_unit *unit) | |||
733 | fcp_bus_reset(fwspk->unit); | 695 | fcp_bus_reset(fwspk->unit); |
734 | 696 | ||
735 | if (cmp_connection_update(&fwspk->connection) < 0) { | 697 | if (cmp_connection_update(&fwspk->connection) < 0) { |
736 | amdtp_out_stream_pcm_abort(&fwspk->stream); | 698 | amdtp_stream_pcm_abort(&fwspk->stream); |
737 | mutex_lock(&fwspk->mutex); | 699 | mutex_lock(&fwspk->mutex); |
738 | fwspk_stop_stream(fwspk); | 700 | fwspk_stop_stream(fwspk); |
739 | mutex_unlock(&fwspk->mutex); | 701 | mutex_unlock(&fwspk->mutex); |
740 | return; | 702 | return; |
741 | } | 703 | } |
742 | 704 | ||
743 | amdtp_out_stream_update(&fwspk->stream); | 705 | amdtp_stream_update(&fwspk->stream); |
744 | } | 706 | } |
745 | 707 | ||
746 | static void fwspk_remove(struct fw_unit *unit) | 708 | static void fwspk_remove(struct fw_unit *unit) |
747 | { | 709 | { |
748 | struct fwspk *fwspk = dev_get_drvdata(&unit->device); | 710 | struct fwspk *fwspk = dev_get_drvdata(&unit->device); |
749 | 711 | ||
750 | amdtp_out_stream_pcm_abort(&fwspk->stream); | 712 | amdtp_stream_pcm_abort(&fwspk->stream); |
751 | snd_card_disconnect(fwspk->card); | 713 | snd_card_disconnect(fwspk->card); |
752 | 714 | ||
753 | mutex_lock(&fwspk->mutex); | 715 | mutex_lock(&fwspk->mutex); |
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c index 6496822c1808..1ff78ec9f0ac 100644 --- a/sound/isa/sb/sb_mixer.c +++ b/sound/isa/sb/sb_mixer.c | |||
@@ -818,12 +818,14 @@ int snd_sbmixer_new(struct snd_sb *chip) | |||
818 | return err; | 818 | return err; |
819 | break; | 819 | break; |
820 | case SB_HW_DT019X: | 820 | case SB_HW_DT019X: |
821 | if ((err = snd_sbmixer_init(chip, | 821 | err = snd_sbmixer_init(chip, |
822 | snd_dt019x_controls, | 822 | snd_dt019x_controls, |
823 | ARRAY_SIZE(snd_dt019x_controls), | 823 | ARRAY_SIZE(snd_dt019x_controls), |
824 | snd_dt019x_init_values, | 824 | snd_dt019x_init_values, |
825 | ARRAY_SIZE(snd_dt019x_init_values), | 825 | ARRAY_SIZE(snd_dt019x_init_values), |
826 | "DT019X")) < 0) | 826 | "DT019X"); |
827 | if (err < 0) | ||
828 | return err; | ||
827 | break; | 829 | break; |
828 | default: | 830 | default: |
829 | strcpy(card->mixername, "???"); | 831 | strcpy(card->mixername, "???"); |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index d3eaac020a38..ab0fd6d4961b 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -1367,6 +1367,12 @@ static int azx_first_init(struct azx *chip) | |||
1367 | /* initialize streams */ | 1367 | /* initialize streams */ |
1368 | azx_init_stream(chip); | 1368 | azx_init_stream(chip); |
1369 | 1369 | ||
1370 | /* workaround for Broadwell HDMI: the first stream is broken, | ||
1371 | * so mask it by keeping it as if opened | ||
1372 | */ | ||
1373 | if (pci->vendor == 0x8086 && pci->device == 0x160c) | ||
1374 | chip->azx_dev[0].opened = 1; | ||
1375 | |||
1370 | /* initialize chip */ | 1376 | /* initialize chip */ |
1371 | azx_init_pci(chip); | 1377 | azx_init_pci(chip); |
1372 | azx_init_chip(chip, (probe_only[dev] & 2) == 0); | 1378 | azx_init_chip(chip, (probe_only[dev] & 2) == 0); |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 11d1c5d303f8..be0a9ee0b804 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -3329,6 +3329,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = { | |||
3329 | { .id = 0x10de0051, .name = "GPU 51 HDMI/DP", .patch = patch_nvhdmi }, | 3329 | { .id = 0x10de0051, .name = "GPU 51 HDMI/DP", .patch = patch_nvhdmi }, |
3330 | { .id = 0x10de0060, .name = "GPU 60 HDMI/DP", .patch = patch_nvhdmi }, | 3330 | { .id = 0x10de0060, .name = "GPU 60 HDMI/DP", .patch = patch_nvhdmi }, |
3331 | { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, | 3331 | { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, |
3332 | { .id = 0x10de0071, .name = "GPU 71 HDMI/DP", .patch = patch_nvhdmi }, | ||
3332 | { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, | 3333 | { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, |
3333 | { .id = 0x11069f80, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, | 3334 | { .id = 0x11069f80, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, |
3334 | { .id = 0x11069f81, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, | 3335 | { .id = 0x11069f81, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, |
@@ -3385,6 +3386,7 @@ MODULE_ALIAS("snd-hda-codec-id:10de0044"); | |||
3385 | MODULE_ALIAS("snd-hda-codec-id:10de0051"); | 3386 | MODULE_ALIAS("snd-hda-codec-id:10de0051"); |
3386 | MODULE_ALIAS("snd-hda-codec-id:10de0060"); | 3387 | MODULE_ALIAS("snd-hda-codec-id:10de0060"); |
3387 | MODULE_ALIAS("snd-hda-codec-id:10de0067"); | 3388 | MODULE_ALIAS("snd-hda-codec-id:10de0067"); |
3389 | MODULE_ALIAS("snd-hda-codec-id:10de0071"); | ||
3388 | MODULE_ALIAS("snd-hda-codec-id:10de8001"); | 3390 | MODULE_ALIAS("snd-hda-codec-id:10de8001"); |
3389 | MODULE_ALIAS("snd-hda-codec-id:11069f80"); | 3391 | MODULE_ALIAS("snd-hda-codec-id:11069f80"); |
3390 | MODULE_ALIAS("snd-hda-codec-id:11069f81"); | 3392 | MODULE_ALIAS("snd-hda-codec-id:11069f81"); |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 7a800a8ee215..08bb06969a57 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -4760,6 +4760,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4760 | SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4760 | SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4761 | SND_PCI_QUIRK(0x1028, 0x0657, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4761 | SND_PCI_QUIRK(0x1028, 0x0657, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4762 | SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4762 | SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4763 | SND_PCI_QUIRK(0x1028, 0x065c, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4763 | SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4764 | SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4764 | SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4765 | SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4765 | SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4766 | SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
@@ -4768,6 +4769,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4768 | SND_PCI_QUIRK(0x1028, 0x0674, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4769 | SND_PCI_QUIRK(0x1028, 0x0674, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4769 | SND_PCI_QUIRK(0x1028, 0x067e, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4770 | SND_PCI_QUIRK(0x1028, 0x067e, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4770 | SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4771 | SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4772 | SND_PCI_QUIRK(0x1028, 0x0680, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4773 | SND_PCI_QUIRK(0x1028, 0x0684, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | ||
4771 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4774 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4772 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4775 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4773 | SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), | 4776 | SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), |