ASoC: Updates for v4.7 The updates this time around are almost all driver code: - Further slow progress on the topology code. - Substantial updates and improvements for the da7219, es8328, fsl-ssi Intel and rcar drivers.
Unified · Split
| @@ -48,6 +48,9 @@ Felix Kuhling <fxkuehl@gmx.de> · 47 unmodified lines | ||
| 48 | 48 | Felix Moeller <felix@derklecks.de> |
| 49 | 49 | Filipe Lautert <filipe@icewall.org> |
| 50 | 50 | Franck Bui-Huu <vagabon.xyz@gmail.com> |
| 51 | +Frank Rowand <frowand.list@gmail.com> <frowand@mvista.com> | |
| 52 | +Frank Rowand <frowand.list@gmail.com> <frank.rowand@am.sony.com> | |
| 53 | +Frank Rowand <frowand.list@gmail.com> <frank.rowand@sonymobile.com> | |
| 51 | 54 | Frank Zago <fzago@systemfabricworks.com> |
| 52 | 55 | Greg Kroah-Hartman <greg@echidna.(none)> |
| 53 | 56 | Greg Kroah-Hartman <gregkh@suse.de> |
| @@ -66,6 +69,7 @@ Jean Tourrilhes <jt@hpl.hp.com> · 12 unmodified lines | ||
| 66 | 69 | Jeff Garzik <jgarzik@pretzel.yyz.us> |
| 67 | 70 | Jens Axboe <axboe@suse.de> |
| 68 | 71 | Jens Osterkamp <Jens.Osterkamp@de.ibm.com> |
| 72 | +John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> | |
| 69 | 73 | John Stultz <johnstul@us.ibm.com> |
| 70 | 74 | <josh@joshtriplett.org> <josh@freedesktop.org> |
| 71 | 75 | <josh@joshtriplett.org> <josh@kernel.org> |
| @@ -79,6 +83,7 @@ Kay Sievers <kay.sievers@vrfy.org> · 7 unmodified lines | ||
| 79 | 83 | Kenneth W Chen <kenneth.w.chen@intel.com> |
| 80 | 84 | Konstantin Khlebnikov <koct9i@gmail.com> <k.khlebnikov@samsung.com> |
| 81 | 85 | Koushik <raghavendra.koushik@neterion.com> |
| 86 | +Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski.k@gmail.com> | |
| 82 | 87 | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| 83 | 88 | Leonid I Ananiev <leonid.i.ananiev@intel.com> |
| 84 | 89 | Linas Vepstas <linas@austin.ibm.com> |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | The ARC HS can be configured with a pipeline performance monitor for counting |
| 4 | 4 | CPU and cache events like cache misses and hits. Like conventional PCT there |
| 5 | −are 100+ hardware conditions dynamically mapped to upto 32 counters. | |
| 5 | +are 100+ hardware conditions dynamically mapped to up to 32 counters. | |
| 6 | 6 | It also supports overflow interrupts. |
| 7 | 7 | |
| 8 | 8 | Required properties: |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | The ARC700 can be configured with a pipeline performance monitor for counting |
| 4 | 4 | CPU and cache events like cache misses and hits. Like conventional PCT there |
| 5 | −are 100+ hardware conditions dynamically mapped to upto 32 counters | |
| 5 | +are 100+ hardware conditions dynamically mapped to up to 32 counters | |
| 6 | 6 | |
| 7 | 7 | Note that: |
| 8 | 8 | * The ARC 700 PCT does not support interrupts; although HW events may be |
| @@ -192,7 +192,6 @@ nodes to be present and contain the properties described below. · 191 unmodified lines | ||
| 192 | 192 | can be one of: |
| 193 | 193 | "allwinner,sun6i-a31" |
| 194 | 194 | "allwinner,sun8i-a23" |
| 195 | − "arm,psci" | |
| 196 | 195 | "arm,realview-smp" |
| 197 | 196 | "brcm,bcm-nsp-smp" |
| 198 | 197 | "brcm,brahma-b15" |
| @@ -32,6 +32,10 @@ Optional properties: · 31 unmodified lines | ||
| 32 | 32 | - target-supply : regulator for SATA target power |
| 33 | 33 | - phys : reference to the SATA PHY node |
| 34 | 34 | - phy-names : must be "sata-phy" |
| 35 | +- ports-implemented : Mask that indicates which ports that the HBA supports | |
| 36 | + are available for software to use. Useful if PORTS_IMPL | |
| 37 | + is not programmed by the BIOS, which is true with | |
| 38 | + some embedded SOC's. | |
| 35 | 39 | |
| 36 | 40 | Required properties when using sub-nodes: |
| 37 | 41 | - #address-cells : number of cells to encode an address |
| @@ -6,8 +6,8 @@ RK3xxx SoCs. · 5 unmodified lines | ||
| 6 | 6 | Required properties : |
| 7 | 7 | |
| 8 | 8 | - reg : Offset and length of the register set for the device |
| 9 | − - compatible : should be "rockchip,rk3066-i2c", "rockchip,rk3188-i2c" or | |
| 10 | − "rockchip,rk3288-i2c". | |
| 9 | + - compatible : should be "rockchip,rk3066-i2c", "rockchip,rk3188-i2c", | |
| 10 | + "rockchip,rk3228-i2c" or "rockchip,rk3288-i2c". | |
| 11 | 11 | - interrupts : interrupt number |
| 12 | 12 | - clocks : parent clock |
| 13 | 13 | |
| @@ -45,13 +45,13 @@ Required properties: · 44 unmodified lines | ||
| 45 | 45 | Optional properties: |
| 46 | 46 | - dual_emac_res_vlan : Specifies VID to be used to segregate the ports |
| 47 | 47 | - mac-address : See ethernet.txt file in the same directory |
| 48 | −- phy_id : Specifies slave phy id | |
| 48 | +- phy_id : Specifies slave phy id (deprecated, use phy-handle) | |
| 49 | 49 | - phy-handle : See ethernet.txt file in the same directory |
| 50 | 50 | |
| 51 | 51 | Slave sub-nodes: |
| 52 | 52 | - fixed-link : See fixed-link.txt file in the same directory |
| 53 | − Either the property phy_id, or the sub-node | |
| 54 | − fixed-link can be specified | |
| 53 | + | |
| 54 | +Note: Exactly one of phy_id, phy-handle, or fixed-link must be specified. | |
| 55 | 55 | |
| 56 | 56 | Note: "ti,hwmods" field is used to fetch the base address and irq |
| 57 | 57 | resources from TI, omap hwmod data base during device registration. |
| @@ -0,0 +1,51 @@ | ||
| 1 | +Texas Instruments DaVinci McBSP module | |
| 2 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 3 | + | |
| 4 | +This binding describes the "Multi-channel Buffered Serial Port" (McBSP) | |
| 5 | +audio interface found in some TI DaVinci processors like the OMAP-L138 or AM180x. | |
| 6 | + | |
| 7 | + | |
| 8 | +Required properties: | |
| 9 | +~~~~~~~~~~~~~~~~~~~~ | |
| 10 | +- compatible : | |
| 11 | + "ti,da850-mcbsp" : for DA850, AM180x and OPAM-L138 platforms | |
| 12 | + | |
| 13 | +- reg : physical base address and length of the controller memory mapped | |
| 14 | + region(s). | |
| 15 | +- reg-names : Should contain: | |
| 16 | + * "mpu" for the main registers (required). | |
| 17 | + * "dat" for the data FIFO (optional). | |
| 18 | + | |
| 19 | +- dmas: three element list of DMA controller phandles, DMA request line and | |
| 20 | + TC channel ordered triplets. | |
| 21 | +- dma-names: identifier string for each DMA request line in the dmas property. | |
| 22 | + These strings correspond 1:1 with the ordered pairs in dmas. The dma | |
| 23 | + identifiers must be "rx" and "tx". | |
| 24 | + | |
| 25 | +Optional properties: | |
| 26 | +~~~~~~~~~~~~~~~~~~~~ | |
| 27 | +- interrupts : Interrupt numbers for McBSP | |
| 28 | +- interrupt-names : Known interrupt names are "rx" and "tx" | |
| 29 | + | |
| 30 | +- pinctrl-0: Should specify pin control group used for this controller. | |
| 31 | +- pinctrl-names: Should contain only one value - "default", for more details | |
| 32 | + please refer to pinctrl-bindings.txt | |
| 33 | + | |
| 34 | +Example (AM1808): | |
| 35 | +~~~~~~~~~~~~~~~~~ | |
| 36 | + | |
| 37 | +mcbsp0: mcbsp@1d10000 { | |
| 38 | + compatible = "ti,da850-mcbsp"; | |
| 39 | + pinctrl-names = "default"; | |
| 40 | + pinctrl-0 = <&mcbsp0_pins>; | |
| 41 | + | |
| 42 | + reg = <0x00110000 0x1000>, | |
| 43 | + <0x00310000 0x1000>; | |
| 44 | + reg-names = "mpu", "dat"; | |
| 45 | + interrupts = <97 98>; | |
| 46 | + interrupts-names = "rx", "tx"; | |
| 47 | + dmas = <&edma0 3 1 | |
| 48 | + &edma0 2 1>; | |
| 49 | + dma-names = "tx", "rx"; | |
| 50 | + status = "okay"; | |
| 51 | +}; | |
| @@ -7,8 +7,8 @@ codec/DSP interfaces. · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | Required properties: |
| 9 | 9 | |
| 10 | − - compatible : Compatible list, contains "fsl,vf610-sai" or | |
| 11 | − "fsl,imx6sx-sai". | |
| 10 | + - compatible : Compatible list, contains "fsl,vf610-sai", | |
| 11 | + "fsl,imx6sx-sai" or "fsl,imx6ul-sai" | |
| 12 | 12 | |
| 13 | 13 | - reg : Offset and length of the register set for the device. |
| 14 | 14 | |
| @@ -48,6 +48,11 @@ Required properties: · 33 unmodified lines | ||
| 48 | 48 | receive data by following their own bit clocks and |
| 49 | 49 | frame sync clocks separately. |
| 50 | 50 | |
| 51 | +Optional properties (for mx6ul): | |
| 52 | + | |
| 53 | + - fsl,sai-mclk-direction-output: This is a boolean property. If present, | |
| 54 | + indicates that SAI will output the SAI MCLK clock. | |
| 55 | + | |
| 51 | 56 | Note: |
| 52 | 57 | - If both fsl,sai-asynchronous and fsl,sai-synchronous-rx are absent, the |
| 53 | 58 | default synchronous mode (sync Rx with Tx) will be used, which means both |
| @@ -0,0 +1,13 @@ | ||
| 1 | +PCM5102a audio CODECs | |
| 2 | + | |
| 3 | +These devices does not use I2C or SPI. | |
| 4 | + | |
| 5 | +Required properties: | |
| 6 | + | |
| 7 | + - compatible : set as "ti,pcm5102a" | |
| 8 | + | |
| 9 | +Examples: | |
| 10 | + | |
| 11 | + pcm5102a: pcm5102a { | |
| 12 | + compatible = "ti,pcm5102a"; | |
| 13 | + }; | |
| @@ -6,7 +6,7 @@ This is the driver for the Altera Triple-Speed Ethernet (TSE) controllers · 5 unmodified lines | ||
| 6 | 6 | using the SGDMA and MSGDMA soft DMA IP components. The driver uses the |
| 7 | 7 | platform bus to obtain component resources. The designs used to test this |
| 8 | 8 | driver were built for a Cyclone(R) V SOC FPGA board, a Cyclone(R) V FPGA board, |
| 9 | −and tested with ARM and NIOS processor hosts seperately. The anticipated use | |
| 9 | +and tested with ARM and NIOS processor hosts separately. The anticipated use | |
| 10 | 10 | cases are simple communications between an embedded system and an external peer |
| 11 | 11 | for status and simple configuration of the embedded system. |
| 12 | 12 | |
| @@ -65,14 +65,14 @@ Driver parameters can be also passed in command line by using: · 52 unmodified lines | ||
| 65 | 65 | 4.1) Transmit process |
| 66 | 66 | When the driver's transmit routine is called by the kernel, it sets up a |
| 67 | 67 | transmit descriptor by calling the underlying DMA transmit routine (SGDMA or |
| 68 | −MSGDMA), and initites a transmit operation. Once the transmit is complete, an | |
| 68 | +MSGDMA), and initiates a transmit operation. Once the transmit is complete, an | |
| 69 | 69 | interrupt is driven by the transmit DMA logic. The driver handles the transmit |
| 70 | 70 | completion in the context of the interrupt handling chain by recycling |
| 71 | 71 | resource required to send and track the requested transmit operation. |
| 72 | 72 | |
| 73 | 73 | 4.2) Receive process |
| 74 | 74 | The driver will post receive buffers to the receive DMA logic during driver |
| 75 | −intialization. Receive buffers may or may not be queued depending upon the | |
| 75 | +initialization. Receive buffers may or may not be queued depending upon the | |
| 76 | 76 | underlying DMA logic (MSGDMA is able queue receive buffers, SGDMA is not able |
| 77 | 77 | to queue receive buffers to the SGDMA receive logic). When a packet is |
| 78 | 78 | received, the DMA logic generates an interrupt. The driver handles a receive |
| @@ -8,7 +8,7 @@ Initial Release: · 7 unmodified lines | ||
| 8 | 8 | This is conceptually very similar to the macvlan driver with one major |
| 9 | 9 | exception of using L3 for mux-ing /demux-ing among slaves. This property makes |
| 10 | 10 | the master device share the L2 with it's slave devices. I have developed this |
| 11 | −driver in conjuntion with network namespaces and not sure if there is use case | |
| 11 | +driver in conjunction with network namespaces and not sure if there is use case | |
| 12 | 12 | outside of it. |
| 13 | 13 | |
| 14 | 14 | |
| @@ -42,7 +42,7 @@ out. In this mode the slaves will RX/TX multicast and broadcast (if applicable) · 27 unmodified lines | ||
| 42 | 42 | as well. |
| 43 | 43 | |
| 44 | 44 | 4.2 L3 mode: |
| 45 | − In this mode TX processing upto L3 happens on the stack instance attached | |
| 45 | + In this mode TX processing up to L3 happens on the stack instance attached | |
| 46 | 46 | to the slave device and packets are switched to the stack instance of the |
| 47 | 47 | master device for the L2 processing and routing from that instance will be |
| 48 | 48 | used before packets are queued on the outbound device. In this mode the slaves |
| @@ -56,7 +56,7 @@ situations defines your use case then you can choose to use ipvlan - · 7 unmodified lines | ||
| 56 | 56 | (a) The Linux host that is connected to the external switch / router has |
| 57 | 57 | policy configured that allows only one mac per port. |
| 58 | 58 | (b) No of virtual devices created on a master exceed the mac capacity and |
| 59 | −puts the NIC in promiscous mode and degraded performance is a concern. | |
| 59 | +puts the NIC in promiscuous mode and degraded performance is a concern. | |
| 60 | 60 | (c) If the slave device is to be put into the hostile / untrusted network |
| 61 | 61 | namespace where L2 on the slave could be changed / misused. |
| 62 | 62 | |
| @@ -67,12 +67,12 @@ The two basic thread commands are: · 66 unmodified lines | ||
| 67 | 67 | * add_device DEVICE@NAME -- adds a single device |
| 68 | 68 | * rem_device_all -- remove all associated devices |
| 69 | 69 | |
| 70 | −When adding a device to a thread, a corrosponding procfile is created | |
| 70 | +When adding a device to a thread, a corresponding procfile is created | |
| 71 | 71 | which is used for configuring this device. Thus, device names need to |
| 72 | 72 | be unique. |
| 73 | 73 | |
| 74 | 74 | To support adding the same device to multiple threads, which is useful |
| 75 | −with multi queue NICs, a the device naming scheme is extended with "@": | |
| 75 | +with multi queue NICs, the device naming scheme is extended with "@": | |
| 76 | 76 | device@something |
| 77 | 77 | |
| 78 | 78 | The part after "@" can be anything, but it is custom to use the thread |
| @@ -221,7 +221,7 @@ Sample scripts · 142 unmodified lines | ||
| 221 | 221 | |
| 222 | 222 | A collection of tutorial scripts and helpers for pktgen is in the |
| 223 | 223 | samples/pktgen directory. The helper parameters.sh file support easy |
| 224 | −and consistant parameter parsing across the sample scripts. | |
| 224 | +and consistent parameter parsing across the sample scripts. | |
| 225 | 225 | |
| 226 | 226 | Usage example and help: |
| 227 | 227 | ./pktgen_sample01_simple.sh -i eth4 -m 00:1B:21:3C:9D:F8 -d 192.168.8.2 |
| @@ -41,7 +41,7 @@ using an rx_handler which gives the impression that packets flow through · 40 unmodified lines | ||
| 41 | 41 | the VRF device. Similarly on egress routing rules are used to send packets |
| 42 | 42 | to the VRF device driver before getting sent out the actual interface. This |
| 43 | 43 | allows tcpdump on a VRF device to capture all packets into and out of the |
| 44 | −VRF as a whole.[1] Similiarly, netfilter [2] and tc rules can be applied | |
| 44 | +VRF as a whole.[1] Similarly, netfilter [2] and tc rules can be applied | |
| 45 | 45 | using the VRF device to specify rules that apply to the VRF domain as a whole. |
| 46 | 46 | |
| 47 | 47 | [1] Packets in the forwarded state do not flow through the device, so those |
| @@ -4,7 +4,7 @@ Krisztian <hidden@balabit.hu> and others and additional patches · 3 unmodified lines | ||
| 4 | 4 | from Jamal <hadi@cyberus.ca>. |
| 5 | 5 | |
| 6 | 6 | The end goal for syncing is to be able to insert attributes + generate |
| 7 | −events so that the an SA can be safely moved from one machine to another | |
| 7 | +events so that the SA can be safely moved from one machine to another | |
| 8 | 8 | for HA purposes. |
| 9 | 9 | The idea is to synchronize the SA so that the takeover machine can do |
| 10 | 10 | the processing of the SA as accurate as possible if it has access to it. |
| @@ -13,7 +13,7 @@ We already have the ability to generate SA add/del/upd events. · 2 unmodified lines | ||
| 13 | 13 | These patches add ability to sync and have accurate lifetime byte (to |
| 14 | 14 | ensure proper decay of SAs) and replay counters to avoid replay attacks |
| 15 | 15 | with as minimal loss at failover time. |
| 16 | −This way a backup stays as closely uptodate as an active member. | |
| 16 | +This way a backup stays as closely up-to-date as an active member. | |
| 17 | 17 | |
| 18 | 18 | Because the above items change for every packet the SA receives, |
| 19 | 19 | it is possible for a lot of the events to be generated. |
| @@ -163,7 +163,7 @@ If you have an SA that is getting hit by traffic in bursts such that · 143 unmodified lines | ||
| 163 | 163 | there is a period where the timer threshold expires with no packets |
| 164 | 164 | seen, then an odd behavior is seen as follows: |
| 165 | 165 | The first packet arrival after a timer expiry will trigger a timeout |
| 166 | −aevent; i.e we dont wait for a timeout period or a packet threshold | |
| 166 | +event; i.e we don't wait for a timeout period or a packet threshold | |
| 167 | 167 | to be reached. This is done for simplicity and efficiency reasons. |
| 168 | 168 | |
| 169 | 169 | -JHS |
| @@ -581,15 +581,16 @@ Specify "[Nn]ode" for node order · 580 unmodified lines | ||
| 581 | 581 | "Zone Order" orders the zonelists by zone type, then by node within each |
| 582 | 582 | zone. Specify "[Zz]one" for zone order. |
| 583 | 583 | |
| 584 | −Specify "[Dd]efault" to request automatic configuration. Autoconfiguration | |
| 585 | −will select "node" order in following case. | |
| 586 | −(1) if the DMA zone does not exist or | |
| 587 | −(2) if the DMA zone comprises greater than 50% of the available memory or | |
| 588 | −(3) if any node's DMA zone comprises greater than 70% of its local memory and | |
| 589 | − the amount of local memory is big enough. | |
| 590 | − | |
| 591 | −Otherwise, "zone" order will be selected. Default order is recommended unless | |
| 592 | −this is causing problems for your system/application. | |
| 584 | +Specify "[Dd]efault" to request automatic configuration. | |
| 585 | + | |
| 586 | +On 32-bit, the Normal zone needs to be preserved for allocations accessible | |
| 587 | +by the kernel, so "zone" order will be selected. | |
| 588 | + | |
| 589 | +On 64-bit, devices that require DMA32/DMA are relatively rare, so "node" | |
| 590 | +order will be selected. | |
| 591 | + | |
| 592 | +Default order is recommended unless this is causing problems for your | |
| 593 | +system/application. | |
| 593 | 594 | |
| 594 | 595 | ============================================================== |
| 595 | 596 | |
| @@ -872,9 +872,9 @@ F: drivers/perf/arm_pmu.c · 871 unmodified lines | ||
| 872 | 872 | F: include/linux/perf/arm_pmu.h |
| 873 | 873 | |
| 874 | 874 | ARM PORT |
| 875 | −M: Russell King <linux@arm.linux.org.uk> | |
| 875 | +M: Russell King <linux@armlinux.org.uk> | |
| 876 | 876 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 877 | −W: http://www.arm.linux.org.uk/ | |
| 877 | +W: http://www.armlinux.org.uk/ | |
| 878 | 878 | S: Maintained |
| 879 | 879 | F: arch/arm/ |
| 880 | 880 | |
| @@ -886,35 +886,35 @@ F: arch/arm/plat-*/ · 5 unmodified lines | ||
| 886 | 886 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git |
| 887 | 887 | |
| 888 | 888 | ARM PRIMECELL AACI PL041 DRIVER |
| 889 | −M: Russell King <linux@arm.linux.org.uk> | |
| 889 | +M: Russell King <linux@armlinux.org.uk> | |
| 890 | 890 | S: Maintained |
| 891 | 891 | F: sound/arm/aaci.* |
| 892 | 892 | |
| 893 | 893 | ARM PRIMECELL CLCD PL110 DRIVER |
| 894 | −M: Russell King <linux@arm.linux.org.uk> | |
| 894 | +M: Russell King <linux@armlinux.org.uk> | |
| 895 | 895 | S: Maintained |
| 896 | 896 | F: drivers/video/fbdev/amba-clcd.* |
| 897 | 897 | |
| 898 | 898 | ARM PRIMECELL KMI PL050 DRIVER |
| 899 | −M: Russell King <linux@arm.linux.org.uk> | |
| 899 | +M: Russell King <linux@armlinux.org.uk> | |
| 900 | 900 | S: Maintained |
| 901 | 901 | F: drivers/input/serio/ambakmi.* |
| 902 | 902 | F: include/linux/amba/kmi.h |
| 903 | 903 | |
| 904 | 904 | ARM PRIMECELL MMCI PL180/1 DRIVER |
| 905 | −M: Russell King <linux@arm.linux.org.uk> | |
| 905 | +M: Russell King <linux@armlinux.org.uk> | |
| 906 | 906 | S: Maintained |
| 907 | 907 | F: drivers/mmc/host/mmci.* |
| 908 | 908 | F: include/linux/amba/mmci.h |
| 909 | 909 | |
| 910 | 910 | ARM PRIMECELL UART PL010 AND PL011 DRIVERS |
| 911 | −M: Russell King <linux@arm.linux.org.uk> | |
| 911 | +M: Russell King <linux@armlinux.org.uk> | |
| 912 | 912 | S: Maintained |
| 913 | 913 | F: drivers/tty/serial/amba-pl01*.c |
| 914 | 914 | F: include/linux/amba/serial.h |
| 915 | 915 | |
| 916 | 916 | ARM PRIMECELL BUS SUPPORT |
| 917 | −M: Russell King <linux@arm.linux.org.uk> | |
| 917 | +M: Russell King <linux@armlinux.org.uk> | |
| 918 | 918 | S: Maintained |
| 919 | 919 | F: drivers/amba/ |
| 920 | 920 | F: include/linux/amba/bus.h |
| @@ -1036,7 +1036,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) · 115 unmodified lines | ||
| 1036 | 1036 | S: Maintained |
| 1037 | 1037 | |
| 1038 | 1038 | ARM/CLKDEV SUPPORT |
| 1039 | −M: Russell King <linux@arm.linux.org.uk> | |
| 1039 | +M: Russell King <linux@armlinux.org.uk> | |
| 1040 | 1040 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1041 | 1041 | S: Maintained |
| 1042 | 1042 | F: arch/arm/include/asm/clkdev.h |
| @@ -1093,9 +1093,9 @@ F: arch/arm/boot/dts/cx92755* · 50 unmodified lines | ||
| 1093 | 1093 | N: digicolor |
| 1094 | 1094 | |
| 1095 | 1095 | ARM/EBSA110 MACHINE SUPPORT |
| 1096 | −M: Russell King <linux@arm.linux.org.uk> | |
| 1096 | +M: Russell King <linux@armlinux.org.uk> | |
| 1097 | 1097 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1098 | −W: http://www.arm.linux.org.uk/ | |
| 1098 | +W: http://www.armlinux.org.uk/ | |
| 1099 | 1099 | S: Maintained |
| 1100 | 1100 | F: arch/arm/mach-ebsa110/ |
| 1101 | 1101 | F: drivers/net/ethernet/amd/am79c961a.* |
| @@ -1124,9 +1124,9 @@ T: git git://git.berlios.de/gemini-board · 22 unmodified lines | ||
| 1124 | 1124 | F: arch/arm/mm/*-fa* |
| 1125 | 1125 | |
| 1126 | 1126 | ARM/FOOTBRIDGE ARCHITECTURE |
| 1127 | −M: Russell King <linux@arm.linux.org.uk> | |
| 1127 | +M: Russell King <linux@armlinux.org.uk> | |
| 1128 | 1128 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1129 | −W: http://www.arm.linux.org.uk/ | |
| 1129 | +W: http://www.armlinux.org.uk/ | |
| 1130 | 1130 | S: Maintained |
| 1131 | 1131 | F: arch/arm/include/asm/hardware/dec21285.h |
| 1132 | 1132 | F: arch/arm/mach-footbridge/ |
| @@ -1457,7 +1457,7 @@ S: Maintained · 324 unmodified lines | ||
| 1457 | 1457 | ARM/PT DIGITAL BOARD PORT |
| 1458 | 1458 | M: Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de> |
| 1459 | 1459 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1460 | −W: http://www.arm.linux.org.uk/ | |
| 1460 | +W: http://www.armlinux.org.uk/ | |
| 1461 | 1461 | S: Maintained |
| 1462 | 1462 | |
| 1463 | 1463 | ARM/QUALCOMM SUPPORT |
| @@ -1493,9 +1493,9 @@ S: Supported · 29 unmodified lines | ||
| 1493 | 1493 | F: arch/arm64/boot/dts/renesas/ |
| 1494 | 1494 | |
| 1495 | 1495 | ARM/RISCPC ARCHITECTURE |
| 1496 | −M: Russell King <linux@arm.linux.org.uk> | |
| 1496 | +M: Russell King <linux@armlinux.org.uk> | |
| 1497 | 1497 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1498 | −W: http://www.arm.linux.org.uk/ | |
| 1498 | +W: http://www.armlinux.org.uk/ | |
| 1499 | 1499 | S: Maintained |
| 1500 | 1500 | F: arch/arm/include/asm/hardware/entry-macro-iomd.S |
| 1501 | 1501 | F: arch/arm/include/asm/hardware/ioc.h |
| @@ -1773,9 +1773,9 @@ F: drivers/clk/versatile/clk-vexpress-osc.c · 271 unmodified lines | ||
| 1773 | 1773 | F: drivers/clocksource/versatile.c |
| 1774 | 1774 | |
| 1775 | 1775 | ARM/VFP SUPPORT |
| 1776 | −M: Russell King <linux@arm.linux.org.uk> | |
| 1776 | +M: Russell King <linux@armlinux.org.uk> | |
| 1777 | 1777 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1778 | −W: http://www.arm.linux.org.uk/ | |
| 1778 | +W: http://www.armlinux.org.uk/ | |
| 1779 | 1779 | S: Maintained |
| 1780 | 1780 | F: arch/arm/vfp/ |
| 1781 | 1781 | |
| @@ -2921,7 +2921,7 @@ F: mm/cleancache.c · 1139 unmodified lines | ||
| 2921 | 2921 | F: include/linux/cleancache.h |
| 2922 | 2922 | |
| 2923 | 2923 | CLK API |
| 2924 | −M: Russell King <linux@arm.linux.org.uk> | |
| 2924 | +M: Russell King <linux@armlinux.org.uk> | |
| 2925 | 2925 | L: linux-clk@vger.kernel.org |
| 2926 | 2926 | S: Maintained |
| 2927 | 2927 | F: include/linux/clk.h |
| @@ -3354,9 +3354,9 @@ S: Supported · 426 unmodified lines | ||
| 3354 | 3354 | F: drivers/net/ethernet/stmicro/stmmac/ |
| 3355 | 3355 | |
| 3356 | 3356 | CYBERPRO FB DRIVER |
| 3357 | −M: Russell King <linux@arm.linux.org.uk> | |
| 3357 | +M: Russell King <linux@armlinux.org.uk> | |
| 3358 | 3358 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 3359 | −W: http://www.arm.linux.org.uk/ | |
| 3359 | +W: http://www.armlinux.org.uk/ | |
| 3360 | 3360 | S: Maintained |
| 3361 | 3361 | F: drivers/video/fbdev/cyber2000fb.* |
| 3362 | 3362 | |
| @@ -3881,7 +3881,7 @@ F: Documentation/devicetree/bindings/display/st,stih4xx.txt · 518 unmodified lines | ||
| 3881 | 3881 | |
| 3882 | 3882 | DRM DRIVERS FOR VIVANTE GPU IP |
| 3883 | 3883 | M: Lucas Stach <l.stach@pengutronix.de> |
| 3884 | −R: Russell King <linux+etnaviv@arm.linux.org.uk> | |
| 3884 | +R: Russell King <linux+etnaviv@armlinux.org.uk> | |
| 3885 | 3885 | R: Christian Gmeiner <christian.gmeiner@gmail.com> |
| 3886 | 3886 | L: dri-devel@lists.freedesktop.org |
| 3887 | 3887 | S: Maintained |
| @@ -4223,8 +4223,8 @@ F: Documentation/efi-stub.txt · 335 unmodified lines | ||
| 4223 | 4223 | F: arch/ia64/kernel/efi.c |
| 4224 | 4224 | F: arch/x86/boot/compressed/eboot.[ch] |
| 4225 | 4225 | F: arch/x86/include/asm/efi.h |
| 4226 | −F: arch/x86/platform/efi/* | |
| 4227 | −F: drivers/firmware/efi/* | |
| 4226 | +F: arch/x86/platform/efi/ | |
| 4227 | +F: drivers/firmware/efi/ | |
| 4228 | 4228 | F: include/linux/efi*.h |
| 4229 | 4229 | |
| 4230 | 4230 | EFI VARIABLE FILESYSTEM |
| @@ -4661,6 +4661,7 @@ FREESCALE SOC SOUND DRIVERS · 430 unmodified lines | ||
| 4661 | 4661 | M: Timur Tabi <timur@tabi.org> |
| 4662 | 4662 | M: Nicolin Chen <nicoleotsuka@gmail.com> |
| 4663 | 4663 | M: Xiubo Li <Xiubo.Lee@gmail.com> |
| 4664 | +R: Fabio Estevam <fabio.estevam@nxp.com> | |
| 4664 | 4665 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 4665 | 4666 | L: linuxppc-dev@lists.ozlabs.org |
| 4666 | 4667 | S: Maintained |
| @@ -4744,7 +4745,7 @@ F: drivers/platform/x86/fujitsu-tablet.c · 77 unmodified lines | ||
| 4744 | 4745 | |
| 4745 | 4746 | FUSE: FILESYSTEM IN USERSPACE |
| 4746 | 4747 | M: Miklos Szeredi <miklos@szeredi.hu> |
| 4747 | −L: fuse-devel@lists.sourceforge.net | |
| 4748 | +L: linux-fsdevel@vger.kernel.org | |
| 4748 | 4749 | W: http://fuse.sourceforge.net/ |
| 4749 | 4750 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git |
| 4750 | 4751 | S: Maintained |
| @@ -4903,7 +4904,7 @@ F: net/ipv4/gre_offload.c · 152 unmodified lines | ||
| 4903 | 4904 | F: include/net/gre.h |
| 4904 | 4905 | |
| 4905 | 4906 | GRETH 10/100/1G Ethernet MAC device driver |
| 4906 | −M: Kristoffer Glembo <kristoffer@gaisler.com> | |
| 4907 | +M: Andreas Larsson <andreas@gaisler.com> | |
| 4907 | 4908 | L: netdev@vger.kernel.org |
| 4908 | 4909 | S: Maintained |
| 4909 | 4910 | F: drivers/net/ethernet/aeroflex/ |
| @@ -6027,7 +6028,7 @@ F: include/scsi/*iscsi* · 1117 unmodified lines | ||
| 6027 | 6028 | |
| 6028 | 6029 | ISCSI EXTENSIONS FOR RDMA (ISER) INITIATOR |
| 6029 | 6030 | M: Or Gerlitz <ogerlitz@mellanox.com> |
| 6030 | −M: Sagi Grimberg <sagig@mellanox.com> | |
| 6031 | +M: Sagi Grimberg <sagi@grimberg.me> | |
| 6031 | 6032 | M: Roi Dayan <roid@mellanox.com> |
| 6032 | 6033 | L: linux-rdma@vger.kernel.org |
| 6033 | 6034 | S: Supported |
| @@ -6037,7 +6038,7 @@ Q: http://patchwork.kernel.org/project/linux-rdma/list/ · 3 unmodified lines | ||
| 6037 | 6038 | F: drivers/infiniband/ulp/iser/ |
| 6038 | 6039 | |
| 6039 | 6040 | ISCSI EXTENSIONS FOR RDMA (ISER) TARGET |
| 6040 | −M: Sagi Grimberg <sagig@mellanox.com> | |
| 6041 | +M: Sagi Grimberg <sagi@grimberg.me> | |
| 6041 | 6042 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master |
| 6042 | 6043 | L: linux-rdma@vger.kernel.org |
| 6043 | 6044 | L: target-devel@vger.kernel.org |
| @@ -6400,7 +6401,7 @@ F: mm/kmemleak.c · 356 unmodified lines | ||
| 6400 | 6401 | F: mm/kmemleak-test.c |
| 6401 | 6402 | |
| 6402 | 6403 | KPROBES |
| 6403 | −M: Ananth N Mavinakayanahalli <ananth@in.ibm.com> | |
| 6404 | +M: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com> | |
| 6404 | 6405 | M: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> |
| 6405 | 6406 | M: "David S. Miller" <davem@davemloft.net> |
| 6406 | 6407 | M: Masami Hiramatsu <mhiramat@kernel.org> |
| @@ -6905,7 +6906,7 @@ L: linux-man@vger.kernel.org · 498 unmodified lines | ||
| 6905 | 6906 | S: Maintained |
| 6906 | 6907 | |
| 6907 | 6908 | MARVELL ARMADA DRM SUPPORT |
| 6908 | −M: Russell King <rmk+kernel@arm.linux.org.uk> | |
| 6909 | +M: Russell King <rmk+kernel@armlinux.org.uk> | |
| 6909 | 6910 | S: Maintained |
| 6910 | 6911 | F: drivers/gpu/drm/armada/ |
| 6911 | 6912 | |
| @@ -7905,7 +7906,7 @@ S: Supported · 993 unmodified lines | ||
| 7905 | 7906 | F: drivers/nfc/nxp-nci |
| 7906 | 7907 | |
| 7907 | 7908 | NXP TDA998X DRM DRIVER |
| 7908 | −M: Russell King <rmk+kernel@arm.linux.org.uk> | |
| 7909 | +M: Russell King <rmk+kernel@armlinux.org.uk> | |
| 7909 | 7910 | S: Supported |
| 7910 | 7911 | F: drivers/gpu/drm/i2c/tda998x_drv.c |
| 7911 | 7912 | F: include/drm/i2c/tda998x.h |
| @@ -7978,7 +7979,7 @@ F: arch/arm/*omap*/*pm* · 66 unmodified lines | ||
| 7978 | 7979 | F: drivers/cpufreq/omap-cpufreq.c |
| 7979 | 7980 | |
| 7980 | 7981 | OMAP POWERDOMAIN SOC ADAPTATION LAYER SUPPORT |
| 7981 | −M: Rajendra Nayak <rnayak@ti.com> | |
| 7982 | +M: Rajendra Nayak <rnayak@codeaurora.org> | |
| 7982 | 7983 | M: Paul Walmsley <paul@pwsan.com> |
| 7983 | 7984 | L: linux-omap@vger.kernel.org |
| 7984 | 7985 | S: Maintained |
| @@ -10014,7 +10015,8 @@ F: drivers/infiniband/hw/ocrdma/ · 2029 unmodified lines | ||
| 10014 | 10015 | |
| 10015 | 10016 | SFC NETWORK DRIVER |
| 10016 | 10017 | M: Solarflare linux maintainers <linux-net-drivers@solarflare.com> |
| 10017 | −M: Shradha Shah <sshah@solarflare.com> | |
| 10018 | +M: Edward Cree <ecree@solarflare.com> | |
| 10019 | +M: Bert Kenward <bkenward@solarflare.com> | |
| 10018 | 10020 | L: netdev@vger.kernel.org |
| 10019 | 10021 | S: Supported |
| 10020 | 10022 | F: drivers/net/ethernet/sfc/ |
| @@ -11071,6 +11073,15 @@ S: Maintained · 1050 unmodified lines | ||
| 11071 | 11073 | F: drivers/clk/ti/ |
| 11072 | 11074 | F: include/linux/clk/ti.h |
| 11073 | 11075 | |
| 11076 | +TI ETHERNET SWITCH DRIVER (CPSW) | |
| 11077 | +M: Mugunthan V N <mugunthanvnm@ti.com> | |
| 11078 | +R: Grygorii Strashko <grygorii.strashko@ti.com> | |
| 11079 | +L: linux-omap@vger.kernel.org | |
| 11080 | +L: netdev@vger.kernel.org | |
| 11081 | +S: Maintained | |
| 11082 | +F: drivers/net/ethernet/ti/cpsw* | |
| 11083 | +F: drivers/net/ethernet/ti/davinci* | |
| 11084 | + | |
| 11074 | 11085 | TI FLASH MEDIA INTERFACE DRIVER |
| 11075 | 11086 | M: Alex Dubov <oakad@yahoo.com> |
| 11076 | 11087 | S: Maintained |
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | VERSION = 4 |
| 2 | 2 | PATCHLEVEL = 6 |
| 3 | 3 | SUBLEVEL = 0 |
| 4 | −EXTRAVERSION = -rc5 | |
| 5 | −NAME = Blurry Fish Butt | |
| 4 | +EXTRAVERSION = -rc7 | |
| 5 | +NAME = Charred Weasel | |
| 6 | 6 | |
| 7 | 7 | # *DOCUMENTATION* |
| 8 | 8 | # To see a list of typical targets execute "make help" |
| @@ -35,8 +35,10 @@ config ARC · 34 unmodified lines | ||
| 35 | 35 | select NO_BOOTMEM |
| 36 | 36 | select OF |
| 37 | 37 | select OF_EARLY_FLATTREE |
| 38 | + select OF_RESERVED_MEM | |
| 38 | 39 | select PERF_USE_VMALLOC |
| 39 | 40 | select HAVE_DEBUG_STACKOVERFLOW |
| 41 | + select HAVE_GENERIC_DMA_COHERENT | |
| 40 | 42 | |
| 41 | 43 | config MIGHT_HAVE_PCI |
| 42 | 44 | bool |
| @@ -56,6 +58,9 @@ config GENERIC_CSUM · 13 unmodified lines | ||
| 56 | 58 | config RWSEM_GENERIC_SPINLOCK |
| 57 | 59 | def_bool y |
| 58 | 60 | |
| 61 | +config ARCH_DISCONTIGMEM_ENABLE | |
| 62 | + def_bool y | |
| 63 | + | |
| 59 | 64 | config ARCH_FLATMEM_ENABLE |
| 60 | 65 | def_bool y |
| 61 | 66 | |
| @@ -345,6 +350,15 @@ config ARC_HUGEPAGE_16M · 283 unmodified lines | ||
| 345 | 350 | |
| 346 | 351 | endchoice |
| 347 | 352 | |
| 353 | +config NODES_SHIFT | |
| 354 | + int "Maximum NUMA Nodes (as a power of 2)" | |
| 355 | + default "1" if !DISCONTIGMEM | |
| 356 | + default "2" if DISCONTIGMEM | |
| 357 | + depends on NEED_MULTIPLE_NODES | |
| 358 | + ---help--- | |
| 359 | + Accessing memory beyond 1GB (with or w/o PAE) requires 2 memory | |
| 360 | + zones. | |
| 361 | + | |
| 348 | 362 | if ISA_ARCOMPACT |
| 349 | 363 | |
| 350 | 364 | config ARC_COMPACT_IRQ_LEVELS |
| @@ -453,6 +467,7 @@ config LINUX_LINK_BASE · 102 unmodified lines | ||
| 453 | 467 | |
| 454 | 468 | config HIGHMEM |
| 455 | 469 | bool "High Memory Support" |
| 470 | + select DISCONTIGMEM | |
| 456 | 471 | help |
| 457 | 472 | With ARC 2G:2G address split, only upper 2G is directly addressable by |
| 458 | 473 | kernel. Enable this to potentially allow access to rest of 2G and PAE |
| @@ -13,6 +13,15 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <asm/byteorder.h> |
| 14 | 14 | #include <asm/page.h> |
| 15 | 15 | |
| 16 | +#ifdef CONFIG_ISA_ARCV2 | |
| 17 | +#include <asm/barrier.h> | |
| 18 | +#define __iormb() rmb() | |
| 19 | +#define __iowmb() wmb() | |
| 20 | +#else | |
| 21 | +#define __iormb() do { } while (0) | |
| 22 | +#define __iowmb() do { } while (0) | |
| 23 | +#endif | |
| 24 | + | |
| 16 | 25 | extern void __iomem *ioremap(phys_addr_t paddr, unsigned long size); |
| 17 | 26 | extern void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size, |
| 18 | 27 | unsigned long flags); |
| @@ -31,6 +40,15 @@ extern void iounmap(const void __iomem *addr); · 12 unmodified lines | ||
| 31 | 40 | #define ioremap_wc(phy, sz) ioremap(phy, sz) |
| 32 | 41 | #define ioremap_wt(phy, sz) ioremap(phy, sz) |
| 33 | 42 | |
| 43 | +/* | |
| 44 | + * io{read,write}{16,32}be() macros | |
| 45 | + */ | |
| 46 | +#define ioread16be(p) ({ u16 __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; }) | |
| 47 | +#define ioread32be(p) ({ u32 __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; }) | |
| 48 | + | |
| 49 | +#define iowrite16be(v,p) ({ __iowmb(); __raw_writew((__force u16)cpu_to_be16(v), p); }) | |
| 50 | +#define iowrite32be(v,p) ({ __iowmb(); __raw_writel((__force u32)cpu_to_be32(v), p); }) | |
| 51 | + | |
| 34 | 52 | /* Change struct page to physical address */ |
| 35 | 53 | #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) |
| 36 | 54 | |
| @@ -108,15 +126,6 @@ static inline void __raw_writel(u32 w, volatile void __iomem *addr) · 71 unmodified lines | ||
| 108 | 126 | |
| 109 | 127 | } |
| 110 | 128 | |
| 111 | −#ifdef CONFIG_ISA_ARCV2 | |
| 112 | −#include <asm/barrier.h> | |
| 113 | −#define __iormb() rmb() | |
| 114 | −#define __iowmb() wmb() | |
| 115 | −#else | |
| 116 | −#define __iormb() do { } while (0) | |
| 117 | −#define __iowmb() do { } while (0) | |
| 118 | −#endif | |
| 119 | − | |
| 120 | 129 | /* |
| 121 | 130 | * MMIO can also get buffered/optimized in micro-arch, so barriers needed |
| 122 | 131 | * Based on ARM model for the typical use case |
| @@ -18,6 +18,12 @@ · 17 unmodified lines | ||
| 18 | 18 | #define STATUS_AD_MASK (1<<STATUS_AD_BIT) |
| 19 | 19 | #define STATUS_IE_MASK (1<<STATUS_IE_BIT) |
| 20 | 20 | |
| 21 | +/* status32 Bits as encoded/expected by CLRI/SETI */ | |
| 22 | +#define CLRI_STATUS_IE_BIT 4 | |
| 23 | + | |
| 24 | +#define CLRI_STATUS_E_MASK 0xF | |
| 25 | +#define CLRI_STATUS_IE_MASK (1 << CLRI_STATUS_IE_BIT) | |
| 26 | + | |
| 21 | 27 | #define AUX_USER_SP 0x00D |
| 22 | 28 | #define AUX_IRQ_CTRL 0x00E |
| 23 | 29 | #define AUX_IRQ_ACT 0x043 /* Active Intr across all levels */ |
| @@ -100,6 +106,13 @@ static inline long arch_local_save_flags(void) · 76 unmodified lines | ||
| 100 | 106 | : |
| 101 | 107 | : "memory"); |
| 102 | 108 | |
| 109 | + /* To be compatible with irq_save()/irq_restore() | |
| 110 | + * encode the irq bits as expected by CLRI/SETI | |
| 111 | + * (this was needed to make CONFIG_TRACE_IRQFLAGS work) | |
| 112 | + */ | |
| 113 | + temp = (1 << 5) | | |
| 114 | + ((!!(temp & STATUS_IE_MASK)) << CLRI_STATUS_IE_BIT) | | |
| 115 | + (temp & CLRI_STATUS_E_MASK); | |
| 103 | 116 | return temp; |
| 104 | 117 | } |
| 105 | 118 | |
| @@ -108,7 +121,7 @@ static inline long arch_local_save_flags(void) · 2 unmodified lines | ||
| 108 | 121 | */ |
| 109 | 122 | static inline int arch_irqs_disabled_flags(unsigned long flags) |
| 110 | 123 | { |
| 111 | − return !(flags & (STATUS_IE_MASK)); | |
| 124 | + return !(flags & CLRI_STATUS_IE_MASK); | |
| 112 | 125 | } |
| 113 | 126 | |
| 114 | 127 | static inline int arch_irqs_disabled(void) |
| @@ -128,11 +141,32 @@ static inline void arc_softirq_clear(int irq) · 13 unmodified lines | ||
| 128 | 141 | |
| 129 | 142 | #else |
| 130 | 143 | |
| 144 | +#ifdef CONFIG_TRACE_IRQFLAGS | |
| 145 | + | |
| 146 | +.macro TRACE_ASM_IRQ_DISABLE | |
| 147 | + bl trace_hardirqs_off | |
| 148 | +.endm | |
| 149 | + | |
| 150 | +.macro TRACE_ASM_IRQ_ENABLE | |
| 151 | + bl trace_hardirqs_on | |
| 152 | +.endm | |
| 153 | + | |
| 154 | +#else | |
| 155 | + | |
| 156 | +.macro TRACE_ASM_IRQ_DISABLE | |
| 157 | +.endm | |
| 158 | + | |
| 159 | +.macro TRACE_ASM_IRQ_ENABLE | |
| 160 | +.endm | |
| 161 | + | |
| 162 | +#endif | |
| 131 | 163 | .macro IRQ_DISABLE scratch |
| 132 | 164 | clri |
| 165 | + TRACE_ASM_IRQ_DISABLE | |
| 133 | 166 | .endm |
| 134 | 167 | |
| 135 | 168 | .macro IRQ_ENABLE scratch |
| 169 | + TRACE_ASM_IRQ_ENABLE | |
| 136 | 170 | seti |
| 137 | 171 | .endm |
| 138 | 172 | |
| @@ -0,0 +1,43 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2016 Synopsys, Inc. (www.synopsys.com) | |
| 3 | + * | |
| 4 | + * This program is free software; you can redistribute it and/or modify | |
| 5 | + * it under the terms of the GNU General Public License version 2 as | |
| 6 | + * published by the Free Software Foundation. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +#ifndef _ASM_ARC_MMZONE_H | |
| 10 | +#define _ASM_ARC_MMZONE_H | |
| 11 | + | |
| 12 | +#ifdef CONFIG_DISCONTIGMEM | |
| 13 | + | |
| 14 | +extern struct pglist_data node_data[]; | |
| 15 | +#define NODE_DATA(nid) (&node_data[nid]) | |
| 16 | + | |
| 17 | +static inline int pfn_to_nid(unsigned long pfn) | |
| 18 | +{ | |
| 19 | + int is_end_low = 1; | |
| 20 | + | |
| 21 | + if (IS_ENABLED(CONFIG_ARC_HAS_PAE40)) | |
| 22 | + is_end_low = pfn <= virt_to_pfn(0xFFFFFFFFUL); | |
| 23 | + | |
| 24 | + /* | |
| 25 | + * node 0: lowmem: 0x8000_0000 to 0xFFFF_FFFF | |
| 26 | + * node 1: HIGHMEM w/o PAE40: 0x0 to 0x7FFF_FFFF | |
| 27 | + * HIGHMEM with PAE40: 0x1_0000_0000 to ... | |
| 28 | + */ | |
| 29 | + if (pfn >= ARCH_PFN_OFFSET && is_end_low) | |
| 30 | + return 0; | |
| 31 | + | |
| 32 | + return 1; | |
| 33 | +} | |
| 34 | + | |
| 35 | +static inline int pfn_valid(unsigned long pfn) | |
| 36 | +{ | |
| 37 | + int nid = pfn_to_nid(pfn); | |
| 38 | + | |
| 39 | + return (pfn <= node_end_pfn(nid)); | |
| 40 | +} | |
| 41 | +#endif /* CONFIG_DISCONTIGMEM */ | |
| 42 | + | |
| 43 | +#endif | |
| @@ -72,11 +72,20 @@ typedef unsigned long pgprot_t; · 71 unmodified lines | ||
| 72 | 72 | |
| 73 | 73 | typedef pte_t * pgtable_t; |
| 74 | 74 | |
| 75 | +/* | |
| 76 | + * Use virt_to_pfn with caution: | |
| 77 | + * If used in pte or paddr related macros, it could cause truncation | |
| 78 | + * in PAE40 builds | |
| 79 | + * As a rule of thumb, only use it in helpers starting with virt_ | |
| 80 | + * You have been warned ! | |
| 81 | + */ | |
| 75 | 82 | #define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) |
| 76 | 83 | |
| 77 | 84 | #define ARCH_PFN_OFFSET virt_to_pfn(CONFIG_LINUX_LINK_BASE) |
| 78 | 85 | |
| 86 | +#ifdef CONFIG_FLATMEM | |
| 79 | 87 | #define pfn_valid(pfn) (((pfn) - ARCH_PFN_OFFSET) < max_mapnr) |
| 88 | +#endif | |
| 80 | 89 | |
| 81 | 90 | /* |
| 82 | 91 | * __pa, __va, virt_to_page (ALERT: deprecated, don't use them) |
| @@ -85,12 +94,10 @@ typedef pte_t * pgtable_t; · 2 unmodified lines | ||
| 85 | 94 | * virt here means link-address/program-address as embedded in object code. |
| 86 | 95 | * And for ARC, link-addr = physical address |
| 87 | 96 | */ |
| 88 | −#define __pa(vaddr) ((unsigned long)vaddr) | |
| 97 | +#define __pa(vaddr) ((unsigned long)(vaddr)) | |
| 89 | 98 | #define __va(paddr) ((void *)((unsigned long)(paddr))) |
| 90 | 99 | |
| 91 | −#define virt_to_page(kaddr) \ | |
| 92 | − (mem_map + virt_to_pfn((kaddr) - CONFIG_LINUX_LINK_BASE)) | |
| 93 | − | |
| 100 | +#define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr)) | |
| 94 | 101 | #define virt_addr_valid(kaddr) pfn_valid(virt_to_pfn(kaddr)) |
| 95 | 102 | |
| 96 | 103 | /* Default Permissions for stack/heaps pages (Non Executable) */ |
| @@ -278,14 +278,13 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep) · 277 unmodified lines | ||
| 278 | 278 | #define pmd_present(x) (pmd_val(x)) |
| 279 | 279 | #define pmd_clear(xp) do { pmd_val(*(xp)) = 0; } while (0) |
| 280 | 280 | |
| 281 | −#define pte_page(pte) \ | |
| 282 | − (mem_map + virt_to_pfn(pte_val(pte) - CONFIG_LINUX_LINK_BASE)) | |
| 283 | − | |
| 281 | +#define pte_page(pte) pfn_to_page(pte_pfn(pte)) | |
| 284 | 282 | #define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot) |
| 285 | −#define pte_pfn(pte) virt_to_pfn(pte_val(pte)) | |
| 286 | −#define pfn_pte(pfn, prot) (__pte(((pte_t)(pfn) << PAGE_SHIFT) | \ | |
| 287 | − pgprot_val(prot))) | |
| 288 | −#define __pte_index(addr) (virt_to_pfn(addr) & (PTRS_PER_PTE - 1)) | |
| 283 | +#define pfn_pte(pfn, prot) (__pte(((pte_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))) | |
| 284 | + | |
| 285 | +/* Don't use virt_to_pfn for macros below: could cause truncations for PAE40*/ | |
| 286 | +#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) | |
| 287 | +#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) | |
| 289 | 288 | |
| 290 | 289 | /* |
| 291 | 290 | * pte_offset gets a @ptr to PMD entry (PGD in our 2-tier paging system) |
| @@ -69,8 +69,11 @@ ENTRY(handle_interrupt) · 68 unmodified lines | ||
| 69 | 69 | |
| 70 | 70 | clri ; To make status32.IE agree with CPU internal state |
| 71 | 71 | |
| 72 | − lr r0, [ICAUSE] | |
| 72 | +#ifdef CONFIG_TRACE_IRQFLAGS | |
| 73 | + TRACE_ASM_IRQ_DISABLE | |
| 74 | +#endif | |
| 73 | 75 | |
| 76 | + lr r0, [ICAUSE] | |
| 74 | 77 | mov blink, ret_from_exception |
| 75 | 78 | |
| 76 | 79 | b.d arch_do_IRQ |
| @@ -169,6 +172,11 @@ END(EV_TLBProtV) · 92 unmodified lines | ||
| 169 | 172 | |
| 170 | 173 | .Lrestore_regs: |
| 171 | 174 | |
| 175 | + # Interrpts are actually disabled from this point on, but will get | |
| 176 | + # reenabled after we return from interrupt/exception. | |
| 177 | + # But irq tracer needs to be told now... | |
| 178 | + TRACE_ASM_IRQ_ENABLE | |
| 179 | + | |
| 172 | 180 | ld r0, [sp, PT_status32] ; U/K mode at time of entry |
| 173 | 181 | lr r10, [AUX_IRQ_ACT] |
| 174 | 182 | |
| @@ -341,6 +341,9 @@ END(call_do_page_fault) · 340 unmodified lines | ||
| 341 | 341 | |
| 342 | 342 | .Lrestore_regs: |
| 343 | 343 | |
| 344 | + # Interrpts are actually disabled from this point on, but will get | |
| 345 | + # reenabled after we return from interrupt/exception. | |
| 346 | + # But irq tracer needs to be told now... | |
| 344 | 347 | TRACE_ASM_IRQ_ENABLE |
| 345 | 348 | |
| 346 | 349 | lr r10, [status32] |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #ifdef CONFIG_BLK_DEV_INITRD |
| 14 | 14 | #include <linux/initrd.h> |
| 15 | 15 | #endif |
| 16 | +#include <linux/of_fdt.h> | |
| 16 | 17 | #include <linux/swap.h> |
| 17 | 18 | #include <linux/module.h> |
| 18 | 19 | #include <linux/highmem.h> |
| @@ -29,11 +30,16 @@ static const unsigned long low_mem_start = CONFIG_LINUX_LINK_BASE; · 10 unmodified lines | ||
| 29 | 30 | static unsigned long low_mem_sz; |
| 30 | 31 | |
| 31 | 32 | #ifdef CONFIG_HIGHMEM |
| 32 | −static unsigned long min_high_pfn; | |
| 33 | +static unsigned long min_high_pfn, max_high_pfn; | |
| 33 | 34 | static u64 high_mem_start; |
| 34 | 35 | static u64 high_mem_sz; |
| 35 | 36 | #endif |
| 36 | 37 | |
| 38 | +#ifdef CONFIG_DISCONTIGMEM | |
| 39 | +struct pglist_data node_data[MAX_NUMNODES] __read_mostly; | |
| 40 | +EXPORT_SYMBOL(node_data); | |
| 41 | +#endif | |
| 42 | + | |
| 37 | 43 | /* User can over-ride above with "mem=nnn[KkMm]" in cmdline */ |
| 38 | 44 | static int __init setup_mem_sz(char *str) |
| 39 | 45 | { |
| @@ -108,13 +114,11 @@ void __init setup_arch_memory(void) · 68 unmodified lines | ||
| 108 | 114 | /* Last usable page of low mem */ |
| 109 | 115 | max_low_pfn = max_pfn = PFN_DOWN(low_mem_start + low_mem_sz); |
| 110 | 116 | |
| 111 | −#ifdef CONFIG_HIGHMEM | |
| 112 | − min_high_pfn = PFN_DOWN(high_mem_start); | |
| 113 | − max_pfn = PFN_DOWN(high_mem_start + high_mem_sz); | |
| 117 | +#ifdef CONFIG_FLATMEM | |
| 118 | + /* pfn_valid() uses this */ | |
| 119 | + max_mapnr = max_low_pfn - min_low_pfn; | |
| 114 | 120 | #endif |
| 115 | 121 | |
| 116 | − max_mapnr = max_pfn - min_low_pfn; | |
| 117 | − | |
| 118 | 122 | /*------------- bootmem allocator setup -----------------------*/ |
| 119 | 123 | |
| 120 | 124 | /* |
| @@ -128,7 +132,7 @@ void __init setup_arch_memory(void) · 7 unmodified lines | ||
| 128 | 132 | * the crash |
| 129 | 133 | */ |
| 130 | 134 | |
| 131 | − memblock_add(low_mem_start, low_mem_sz); | |
| 135 | + memblock_add_node(low_mem_start, low_mem_sz, 0); | |
| 132 | 136 | memblock_reserve(low_mem_start, __pa(_end) - low_mem_start); |
| 133 | 137 | |
| 134 | 138 | #ifdef CONFIG_BLK_DEV_INITRD |
| @@ -136,6 +140,9 @@ void __init setup_arch_memory(void) · 1 unmodified line | ||
| 136 | 140 | memblock_reserve(__pa(initrd_start), initrd_end - initrd_start); |
| 137 | 141 | #endif |
| 138 | 142 | |
| 143 | + early_init_fdt_reserve_self(); | |
| 144 | + early_init_fdt_scan_reserved_mem(); | |
| 145 | + | |
| 139 | 146 | memblock_dump_all(); |
| 140 | 147 | |
| 141 | 148 | /*----------------- node/zones setup --------------------------*/ |
| @@ -145,13 +152,6 @@ void __init setup_arch_memory(void) · 3 unmodified lines | ||
| 145 | 152 | zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn; |
| 146 | 153 | zones_holes[ZONE_NORMAL] = 0; |
| 147 | 154 | |
| 148 | −#ifdef CONFIG_HIGHMEM | |
| 149 | − zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn; | |
| 150 | − | |
| 151 | − /* This handles the peripheral address space hole */ | |
| 152 | − zones_holes[ZONE_HIGHMEM] = min_high_pfn - max_low_pfn; | |
| 153 | −#endif | |
| 154 | − | |
| 155 | 155 | /* |
| 156 | 156 | * We can't use the helper free_area_init(zones[]) because it uses |
| 157 | 157 | * PAGE_OFFSET to compute the @min_low_pfn which would be wrong |
| @@ -164,6 +164,34 @@ void __init setup_arch_memory(void) · 6 unmodified lines | ||
| 164 | 164 | zones_holes); /* holes */ |
| 165 | 165 | |
| 166 | 166 | #ifdef CONFIG_HIGHMEM |
| 167 | + /* | |
| 168 | + * Populate a new node with highmem | |
| 169 | + * | |
| 170 | + * On ARC (w/o PAE) HIGHMEM addresses are actually smaller (0 based) | |
| 171 | + * than addresses in normal ala low memory (0x8000_0000 based). | |
| 172 | + * Even with PAE, the huge peripheral space hole would waste a lot of | |
| 173 | + * mem with single mem_map[]. This warrants a mem_map per region design. | |
| 174 | + * Thus HIGHMEM on ARC is imlemented with DISCONTIGMEM. | |
| 175 | + * | |
| 176 | + * DISCONTIGMEM in turns requires multiple nodes. node 0 above is | |
| 177 | + * populated with normal memory zone while node 1 only has highmem | |
| 178 | + */ | |
| 179 | + node_set_online(1); | |
| 180 | + | |
| 181 | + min_high_pfn = PFN_DOWN(high_mem_start); | |
| 182 | + max_high_pfn = PFN_DOWN(high_mem_start + high_mem_sz); | |
| 183 | + | |
| 184 | + zones_size[ZONE_NORMAL] = 0; | |
| 185 | + zones_holes[ZONE_NORMAL] = 0; | |
| 186 | + | |
| 187 | + zones_size[ZONE_HIGHMEM] = max_high_pfn - min_high_pfn; | |
| 188 | + zones_holes[ZONE_HIGHMEM] = 0; | |
| 189 | + | |
| 190 | + free_area_init_node(1, /* node-id */ | |
| 191 | + zones_size, /* num pages per zone */ | |
| 192 | + min_high_pfn, /* first pfn of node */ | |
| 193 | + zones_holes); /* holes */ | |
| 194 | + | |
| 167 | 195 | high_memory = (void *)(min_high_pfn << PAGE_SHIFT); |
| 168 | 196 | kmap_init(); |
| 169 | 197 | #endif |
| @@ -181,7 +209,7 @@ void __init mem_init(void) · 11 unmodified lines | ||
| 181 | 209 | unsigned long tmp; |
| 182 | 210 | |
| 183 | 211 | reset_all_zones_managed_pages(); |
| 184 | − for (tmp = min_high_pfn; tmp < max_pfn; tmp++) | |
| 212 | + for (tmp = min_high_pfn; tmp < max_high_pfn; tmp++) | |
| 185 | 213 | free_highmem_page(pfn_to_page(tmp)); |
| 186 | 214 | #endif |
| 187 | 215 | |
| @@ -860,7 +860,7 @@ · 859 unmodified lines | ||
| 860 | 860 | ti,no-idle-on-init; |
| 861 | 861 | reg = <0x50000000 0x2000>; |
| 862 | 862 | interrupts = <100>; |
| 863 | − dmas = <&edma 52>; | |
| 863 | + dmas = <&edma 52 0>; | |
| 864 | 864 | dma-names = "rxtx"; |
| 865 | 865 | gpmc,num-cs = <7>; |
| 866 | 866 | gpmc,num-waitpins = <2>; |
| @@ -884,7 +884,7 @@ · 883 unmodified lines | ||
| 884 | 884 | gpmc: gpmc@50000000 { |
| 885 | 885 | compatible = "ti,am3352-gpmc"; |
| 886 | 886 | ti,hwmods = "gpmc"; |
| 887 | − dmas = <&edma 52>; | |
| 887 | + dmas = <&edma 52 0>; | |
| 888 | 888 | dma-names = "rxtx"; |
| 889 | 889 | clocks = <&l3s_gclk>; |
| 890 | 890 | clock-names = "fck"; |
| @@ -99,13 +99,6 @@ · 98 unmodified lines | ||
| 99 | 99 | #cooling-cells = <2>; |
| 100 | 100 | }; |
| 101 | 101 | |
| 102 | − extcon_usb1: extcon_usb1 { | |
| 103 | − compatible = "linux,extcon-usb-gpio"; | |
| 104 | − id-gpio = <&gpio7 25 GPIO_ACTIVE_HIGH>; | |
| 105 | − pinctrl-names = "default"; | |
| 106 | − pinctrl-0 = <&extcon_usb1_pins>; | |
| 107 | − }; | |
| 108 | − | |
| 109 | 102 | hdmi0: connector { |
| 110 | 103 | compatible = "hdmi-connector"; |
| 111 | 104 | label = "hdmi"; |
| @@ -349,12 +342,6 @@ · 237 unmodified lines | ||
| 349 | 342 | >; |
| 350 | 343 | }; |
| 351 | 344 | |
| 352 | − extcon_usb1_pins: extcon_usb1_pins { | |
| 353 | − pinctrl-single,pins = < | |
| 354 | − DRA7XX_CORE_IOPAD(0x37ec, PIN_INPUT_PULLUP | MUX_MODE14) /* uart1_rtsn.gpio7_25 */ | |
| 355 | − >; | |
| 356 | − }; | |
| 357 | − | |
| 358 | 345 | tpd12s015_pins: pinmux_tpd12s015_pins { |
| 359 | 346 | pinctrl-single,pins = < |
| 360 | 347 | DRA7XX_CORE_IOPAD(0x37b0, PIN_OUTPUT | MUX_MODE14) /* gpio7_10 CT_CP_HPD */ |
| @@ -706,10 +693,6 @@ · 345 unmodified lines | ||
| 706 | 693 | pinctrl-0 = <&usb1_pins>; |
| 707 | 694 | }; |
| 708 | 695 | |
| 709 | −&omap_dwc3_1 { | |
| 710 | − extcon = <&extcon_usb1>; | |
| 711 | −}; | |
| 712 | − | |
| 713 | 696 | &omap_dwc3_2 { |
| 714 | 697 | extcon = <&extcon_usb2>; |
| 715 | 698 | }; |
| @@ -4,6 +4,157 @@ · 3 unmodified lines | ||
| 4 | 4 | * published by the Free Software Foundation. |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | +&pllss { | |
| 8 | + /* | |
| 9 | + * See TRM "2.6.10 Connected outputso DPLLS" and | |
| 10 | + * "2.6.11 Connected Outputs of DPLLJ". Only clkout is | |
| 11 | + * connected except for hdmi and usb. | |
| 12 | + */ | |
| 13 | + adpll_mpu_ck: adpll@40 { | |
| 14 | + #clock-cells = <1>; | |
| 15 | + compatible = "ti,dm814-adpll-s-clock"; | |
| 16 | + reg = <0x40 0x40>; | |
| 17 | + clocks = <&devosc_ck &devosc_ck &devosc_ck>; | |
| 18 | + clock-names = "clkinp", "clkinpulow", "clkinphif"; | |
| 19 | + clock-output-names = "481c5040.adpll.dcoclkldo", | |
| 20 | + "481c5040.adpll.clkout", | |
| 21 | + "481c5040.adpll.clkoutx2", | |
| 22 | + "481c5040.adpll.clkouthif"; | |
| 23 | + }; | |
| 24 | + | |
| 25 | + adpll_dsp_ck: adpll@80 { | |
| 26 | + #clock-cells = <1>; | |
| 27 | + compatible = "ti,dm814-adpll-lj-clock"; | |
| 28 | + reg = <0x80 0x30>; | |
| 29 | + clocks = <&devosc_ck &devosc_ck>; | |
| 30 | + clock-names = "clkinp", "clkinpulow"; | |
| 31 | + clock-output-names = "481c5080.adpll.dcoclkldo", | |
| 32 | + "481c5080.adpll.clkout", | |
| 33 | + "481c5080.adpll.clkoutldo"; | |
| 34 | + }; | |
| 35 | + | |
| 36 | + adpll_sgx_ck: adpll@b0 { | |
| 37 | + #clock-cells = <1>; | |
| 38 | + compatible = "ti,dm814-adpll-lj-clock"; | |
| 39 | + reg = <0xb0 0x30>; | |
| 40 | + clocks = <&devosc_ck &devosc_ck>; | |
| 41 | + clock-names = "clkinp", "clkinpulow"; | |
| 42 | + clock-output-names = "481c50b0.adpll.dcoclkldo", | |
| 43 | + "481c50b0.adpll.clkout", | |
| 44 | + "481c50b0.adpll.clkoutldo"; | |
| 45 | + }; | |
| 46 | + | |
| 47 | + adpll_hdvic_ck: adpll@e0 { | |
| 48 | + #clock-cells = <1>; | |
| 49 | + compatible = "ti,dm814-adpll-lj-clock"; | |
| 50 | + reg = <0xe0 0x30>; | |
| 51 | + clocks = <&devosc_ck &devosc_ck>; | |
| 52 | + clock-names = "clkinp", "clkinpulow"; | |
| 53 | + clock-output-names = "481c50e0.adpll.dcoclkldo", | |
| 54 | + "481c50e0.adpll.clkout", | |
| 55 | + "481c50e0.adpll.clkoutldo"; | |
| 56 | + }; | |
| 57 | + | |
| 58 | + adpll_l3_ck: adpll@110 { | |
| 59 | + #clock-cells = <1>; | |
| 60 | + compatible = "ti,dm814-adpll-lj-clock"; | |
| 61 | + reg = <0x110 0x30>; | |
| 62 | + clocks = <&devosc_ck &devosc_ck>; | |
| 63 | + clock-names = "clkinp", "clkinpulow"; | |
| 64 | + clock-output-names = "481c5110.adpll.dcoclkldo", | |
| 65 | + "481c5110.adpll.clkout", | |
| 66 | + "481c5110.adpll.clkoutldo"; | |
| 67 | + }; | |
| 68 | + | |
| 69 | + adpll_isp_ck: adpll@140 { | |
| 70 | + #clock-cells = <1>; | |
| 71 | + compatible = "ti,dm814-adpll-lj-clock"; | |
| 72 | + reg = <0x140 0x30>; | |
| 73 | + clocks = <&devosc_ck &devosc_ck>; | |
| 74 | + clock-names = "clkinp", "clkinpulow"; | |
| 75 | + clock-output-names = "481c5140.adpll.dcoclkldo", | |
| 76 | + "481c5140.adpll.clkout", | |
| 77 | + "481c5140.adpll.clkoutldo"; | |
| 78 | + }; | |
| 79 | + | |
| 80 | + adpll_dss_ck: adpll@170 { | |
| 81 | + #clock-cells = <1>; | |
| 82 | + compatible = "ti,dm814-adpll-lj-clock"; | |
| 83 | + reg = <0x170 0x30>; | |
| 84 | + clocks = <&devosc_ck &devosc_ck>; | |
| 85 | + clock-names = "clkinp", "clkinpulow"; | |
| 86 | + clock-output-names = "481c5170.adpll.dcoclkldo", | |
| 87 | + "481c5170.adpll.clkout", | |
| 88 | + "481c5170.adpll.clkoutldo"; | |
| 89 | + }; | |
| 90 | + | |
| 91 | + adpll_video0_ck: adpll@1a0 { | |
| 92 | + #clock-cells = <1>; | |
| 93 | + compatible = "ti,dm814-adpll-lj-clock"; | |
| 94 | + reg = <0x1a0 0x30>; | |
| 95 | + clocks = <&devosc_ck &devosc_ck>; | |
| 96 | + clock-names = "clkinp", "clkinpulow"; | |
| 97 | + clock-output-names = "481c51a0.adpll.dcoclkldo", | |
| 98 | + "481c51a0.adpll.clkout", | |
| 99 | + "481c51a0.adpll.clkoutldo"; | |
| 100 | + }; | |
| 101 | + | |
| 102 | + adpll_video1_ck: adpll@1d0 { | |
| 103 | + #clock-cells = <1>; | |
| 104 | + compatible = "ti,dm814-adpll-lj-clock"; | |
| 105 | + reg = <0x1d0 0x30>; | |
| 106 | + clocks = <&devosc_ck &devosc_ck>; | |
| 107 | + clock-names = "clkinp", "clkinpulow"; | |
| 108 | + clock-output-names = "481c51d0.adpll.dcoclkldo", | |
| 109 | + "481c51d0.adpll.clkout", | |
| 110 | + "481c51d0.adpll.clkoutldo"; | |
| 111 | + }; | |
| 112 | + | |
| 113 | + adpll_hdmi_ck: adpll@200 { | |
| 114 | + #clock-cells = <1>; | |
| 115 | + compatible = "ti,dm814-adpll-lj-clock"; | |
| 116 | + reg = <0x200 0x30>; | |
| 117 | + clocks = <&devosc_ck &devosc_ck>; | |
| 118 | + clock-names = "clkinp", "clkinpulow"; | |
| 119 | + clock-output-names = "481c5200.adpll.dcoclkldo", | |
| 120 | + "481c5200.adpll.clkout", | |
| 121 | + "481c5200.adpll.clkoutldo"; | |
| 122 | + }; | |
| 123 | + | |
| 124 | + adpll_audio_ck: adpll@230 { | |
| 125 | + #clock-cells = <1>; | |
| 126 | + compatible = "ti,dm814-adpll-lj-clock"; | |
| 127 | + reg = <0x230 0x30>; | |
| 128 | + clocks = <&devosc_ck &devosc_ck>; | |
| 129 | + clock-names = "clkinp", "clkinpulow"; | |
| 130 | + clock-output-names = "481c5230.adpll.dcoclkldo", | |
| 131 | + "481c5230.adpll.clkout", | |
| 132 | + "481c5230.adpll.clkoutldo"; | |
| 133 | + }; | |
| 134 | + | |
| 135 | + adpll_usb_ck: adpll@260 { | |
| 136 | + #clock-cells = <1>; | |
| 137 | + compatible = "ti,dm814-adpll-lj-clock"; | |
| 138 | + reg = <0x260 0x30>; | |
| 139 | + clocks = <&devosc_ck &devosc_ck>; | |
| 140 | + clock-names = "clkinp", "clkinpulow"; | |
| 141 | + clock-output-names = "481c5260.adpll.dcoclkldo", | |
| 142 | + "481c5260.adpll.clkout", | |
| 143 | + "481c5260.adpll.clkoutldo"; | |
| 144 | + }; | |
| 145 | + | |
| 146 | + adpll_ddr_ck: adpll@290 { | |
| 147 | + #clock-cells = <1>; | |
| 148 | + compatible = "ti,dm814-adpll-lj-clock"; | |
| 149 | + reg = <0x290 0x30>; | |
| 150 | + clocks = <&devosc_ck &devosc_ck>; | |
| 151 | + clock-names = "clkinp", "clkinpulow"; | |
| 152 | + clock-output-names = "481c5290.adpll.dcoclkldo", | |
| 153 | + "481c5290.adpll.clkout", | |
| 154 | + "481c5290.adpll.clkoutldo"; | |
| 155 | + }; | |
| 156 | +}; | |
| 157 | + | |
| 7 | 158 | &pllss_clocks { |
| 8 | 159 | timer1_fck: timer1_fck { |
| 9 | 160 | #clock-cells = <0>; |
| @@ -23,6 +174,24 @@ · 13 unmodified lines | ||
| 23 | 174 | reg = <0x2e0>; |
| 24 | 175 | }; |
| 25 | 176 | |
| 177 | + /* CPTS_RFT_CLK in RMII_REFCLK_SRC, usually sourced from auiod */ | |
| 178 | + cpsw_cpts_rft_clk: cpsw_cpts_rft_clk { | |
| 179 | + #clock-cells = <0>; | |
| 180 | + compatible = "ti,mux-clock"; | |
| 181 | + clocks = <&adpll_video0_ck 1 | |
| 182 | + &adpll_video1_ck 1 | |
| 183 | + &adpll_audio_ck 1>; | |
| 184 | + ti,bit-shift = <1>; | |
| 185 | + reg = <0x2e8>; | |
| 186 | + }; | |
| 187 | + | |
| 188 | + /* REVISIT: Set up with a proper mux using RMII_REFCLK_SRC */ | |
| 189 | + cpsw_125mhz_gclk: cpsw_125mhz_gclk { | |
| 190 | + #clock-cells = <0>; | |
| 191 | + compatible = "fixed-clock"; | |
| 192 | + clock-frequency = <125000000>; | |
| 193 | + }; | |
| 194 | + | |
| 26 | 195 | sysclk18_ck: sysclk18_ck { |
| 27 | 196 | #clock-cells = <0>; |
| 28 | 197 | compatible = "ti,mux-clock"; |
| @@ -79,37 +248,6 @@ · 50 unmodified lines | ||
| 79 | 248 | compatible = "fixed-clock"; |
| 80 | 249 | clock-frequency = <1000000000>; |
| 81 | 250 | }; |
| 82 | − | |
| 83 | − sysclk4_ck: sysclk4_ck { | |
| 84 | − #clock-cells = <0>; | |
| 85 | − compatible = "fixed-clock"; | |
| 86 | − clock-frequency = <222000000>; | |
| 87 | − }; | |
| 88 | − | |
| 89 | − sysclk6_ck: sysclk6_ck { | |
| 90 | − #clock-cells = <0>; | |
| 91 | − compatible = "fixed-clock"; | |
| 92 | − clock-frequency = <100000000>; | |
| 93 | − }; | |
| 94 | − | |
| 95 | − sysclk10_ck: sysclk10_ck { | |
| 96 | − #clock-cells = <0>; | |
| 97 | − compatible = "fixed-clock"; | |
| 98 | − clock-frequency = <48000000>; | |
| 99 | − }; | |
| 100 | − | |
| 101 | − cpsw_125mhz_gclk: cpsw_125mhz_gclk { | |
| 102 | − #clock-cells = <0>; | |
| 103 | − compatible = "fixed-clock"; | |
| 104 | − clock-frequency = <125000000>; | |
| 105 | − }; | |
| 106 | − | |
| 107 | − cpsw_cpts_rft_clk: cpsw_cpts_rft_clk { | |
| 108 | − #clock-cells = <0>; | |
| 109 | − compatible = "fixed-clock"; | |
| 110 | − clock-frequency = <250000000>; | |
| 111 | − }; | |
| 112 | − | |
| 113 | 251 | }; |
| 114 | 252 | |
| 115 | 253 | &prcm_clocks { |
| @@ -138,6 +276,49 @@ · 22 unmodified lines | ||
| 138 | 276 | clock-div = <78125>; |
| 139 | 277 | }; |
| 140 | 278 | |
| 279 | + /* L4_HS 220 MHz*/ | |
| 280 | + sysclk4_ck: sysclk4_ck { | |
| 281 | + #clock-cells = <0>; | |
| 282 | + compatible = "ti,fixed-factor-clock"; | |
| 283 | + clocks = <&adpll_l3_ck 1>; | |
| 284 | + ti,clock-mult = <1>; | |
| 285 | + ti,clock-div = <1>; | |
| 286 | + }; | |
| 287 | + | |
| 288 | + /* L4_FWCFG */ | |
| 289 | + sysclk5_ck: sysclk5_ck { | |
| 290 | + #clock-cells = <0>; | |
| 291 | + compatible = "ti,fixed-factor-clock"; | |
| 292 | + clocks = <&adpll_l3_ck 1>; | |
| 293 | + ti,clock-mult = <1>; | |
| 294 | + ti,clock-div = <2>; | |
| 295 | + }; | |
| 296 | + | |
| 297 | + /* L4_LS 110 MHz */ | |
| 298 | + sysclk6_ck: sysclk6_ck { | |
| 299 | + #clock-cells = <0>; | |
| 300 | + compatible = "ti,fixed-factor-clock"; | |
| 301 | + clocks = <&adpll_l3_ck 1>; | |
| 302 | + ti,clock-mult = <1>; | |
| 303 | + ti,clock-div = <2>; | |
| 304 | + }; | |
| 305 | + | |
| 306 | + sysclk8_ck: sysclk8_ck { | |
| 307 | + #clock-cells = <0>; | |
| 308 | + compatible = "ti,fixed-factor-clock"; | |
| 309 | + clocks = <&adpll_usb_ck 1>; | |
| 310 | + ti,clock-mult = <1>; | |
| 311 | + ti,clock-div = <1>; | |
| 312 | + }; | |
| 313 | + | |
| 314 | + sysclk10_ck: sysclk10_ck { | |
| 315 | + compatible = "ti,divider-clock"; | |
| 316 | + reg = <0x324>; | |
| 317 | + ti,max-div = <7>; | |
| 318 | + #clock-cells = <0>; | |
| 319 | + clocks = <&adpll_usb_ck 1>; | |
| 320 | + }; | |
| 321 | + | |
| 141 | 322 | aud_clkin0_ck: aud_clkin0_ck { |
| 142 | 323 | #clock-cells = <0>; |
| 143 | 324 | compatible = "fixed-clock"; |
| @@ -6,6 +6,32 @@ · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | #include "dm814x-clocks.dtsi" |
| 8 | 8 | |
| 9 | +/* Compared to dm814x, dra62x does not have hdic, l3 or dss PLLs */ | |
| 10 | +&adpll_hdvic_ck { | |
| 11 | + status = "disabled"; | |
| 12 | +}; | |
| 13 | + | |
| 14 | +&adpll_l3_ck { | |
| 15 | + status = "disabled"; | |
| 16 | +}; | |
| 17 | + | |
| 18 | +&adpll_dss_ck { | |
| 19 | + status = "disabled"; | |
| 20 | +}; | |
| 21 | + | |
| 22 | +/* Compared to dm814x, dra62x has interconnect clocks on isp PLL */ | |
| 23 | +&sysclk4_ck { | |
| 24 | + clocks = <&adpll_isp_ck 1>; | |
| 25 | +}; | |
| 26 | + | |
| 27 | +&sysclk5_ck { | |
| 28 | + clocks = <&adpll_isp_ck 1>; | |
| 29 | +}; | |
| 30 | + | |
| 31 | +&sysclk6_ck { | |
| 32 | + clocks = <&adpll_isp_ck 1>; | |
| 33 | +}; | |
| 34 | + | |
| 9 | 35 | /* |
| 10 | 36 | * Compared to dm814x, dra62x has different shifts and more mux options. |
| 11 | 37 | * Please add the extra options for ysclk_14 and 16 if really needed. |
| @@ -98,12 +98,20 @@ · 97 unmodified lines | ||
| 98 | 98 | clock-frequency = <32768>; |
| 99 | 99 | }; |
| 100 | 100 | |
| 101 | − sys_32k_ck: sys_32k_ck { | |
| 101 | + sys_clk32_crystal_ck: sys_clk32_crystal_ck { | |
| 102 | 102 | #clock-cells = <0>; |
| 103 | 103 | compatible = "fixed-clock"; |
| 104 | 104 | clock-frequency = <32768>; |
| 105 | 105 | }; |
| 106 | 106 | |
| 107 | + sys_clk32_pseudo_ck: sys_clk32_pseudo_ck { | |
| 108 | + #clock-cells = <0>; | |
| 109 | + compatible = "fixed-factor-clock"; | |
| 110 | + clocks = <&sys_clkin1>; | |
| 111 | + clock-mult = <1>; | |
| 112 | + clock-div = <610>; | |
| 113 | + }; | |
| 114 | + | |
| 107 | 115 | virt_12000000_ck: virt_12000000_ck { |
| 108 | 116 | #clock-cells = <0>; |
| 109 | 117 | compatible = "fixed-clock"; |
| @@ -2170,4 +2178,12 @@ · 2060 unmodified lines | ||
| 2170 | 2178 | ti,bit-shift = <22>; |
| 2171 | 2179 | reg = <0x0558>; |
| 2172 | 2180 | }; |
| 2181 | + | |
| 2182 | + sys_32k_ck: sys_32k_ck { | |
| 2183 | + #clock-cells = <0>; | |
| 2184 | + compatible = "ti,mux-clock"; | |
| 2185 | + clocks = <&sys_clk32_crystal_ck>, <&sys_clk32_pseudo_ck>, <&sys_clk32_pseudo_ck>, <&sys_clk32_pseudo_ck>; | |
| 2186 | + ti,bit-shift = <8>; | |
| 2187 | + reg = <0x6c4>; | |
| 2188 | + }; | |
| 2173 | 2189 | }; |
| @@ -329,6 +329,7 @@ · 328 unmodified lines | ||
| 329 | 329 | regulator-name = "V28"; |
| 330 | 330 | regulator-min-microvolt = <2800000>; |
| 331 | 331 | regulator-max-microvolt = <2800000>; |
| 332 | + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ | |
| 332 | 333 | regulator-always-on; /* due to battery cover sensor */ |
| 333 | 334 | }; |
| 334 | 335 | |
| @@ -336,30 +337,35 @@ · 1 unmodified line | ||
| 336 | 337 | regulator-name = "VCSI"; |
| 337 | 338 | regulator-min-microvolt = <1800000>; |
| 338 | 339 | regulator-max-microvolt = <1800000>; |
| 340 | + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ | |
| 339 | 341 | }; |
| 340 | 342 | |
| 341 | 343 | &vaux3 { |
| 342 | 344 | regulator-name = "VMMC2_30"; |
| 343 | 345 | regulator-min-microvolt = <2800000>; |
| 344 | 346 | regulator-max-microvolt = <3000000>; |
| 347 | + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ | |
| 345 | 348 | }; |
| 346 | 349 | |
| 347 | 350 | &vaux4 { |
| 348 | 351 | regulator-name = "VCAM_ANA_28"; |
| 349 | 352 | regulator-min-microvolt = <2800000>; |
| 350 | 353 | regulator-max-microvolt = <2800000>; |
| 354 | + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ | |
| 351 | 355 | }; |
| 352 | 356 | |
| 353 | 357 | &vmmc1 { |
| 354 | 358 | regulator-name = "VMMC1"; |
| 355 | 359 | regulator-min-microvolt = <1850000>; |
| 356 | 360 | regulator-max-microvolt = <3150000>; |
| 361 | + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ | |
| 357 | 362 | }; |
| 358 | 363 | |
| 359 | 364 | &vmmc2 { |
| 360 | 365 | regulator-name = "V28_A"; |
| 361 | 366 | regulator-min-microvolt = <2800000>; |
| 362 | 367 | regulator-max-microvolt = <3000000>; |
| 368 | + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ | |
| 363 | 369 | regulator-always-on; /* due VIO leak to AIC34 VDDs */ |
| 364 | 370 | }; |
| 365 | 371 | |
| @@ -367,6 +373,7 @@ · 1 unmodified line | ||
| 367 | 373 | regulator-name = "VPLL"; |
| 368 | 374 | regulator-min-microvolt = <1800000>; |
| 369 | 375 | regulator-max-microvolt = <1800000>; |
| 376 | + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ | |
| 370 | 377 | regulator-always-on; |
| 371 | 378 | }; |
| 372 | 379 | |
| @@ -374,6 +381,7 @@ · 1 unmodified line | ||
| 374 | 381 | regulator-name = "VSDI_CSI"; |
| 375 | 382 | regulator-min-microvolt = <1800000>; |
| 376 | 383 | regulator-max-microvolt = <1800000>; |
| 384 | + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ | |
| 377 | 385 | regulator-always-on; |
| 378 | 386 | }; |
| 379 | 387 | |
| @@ -381,6 +389,7 @@ · 1 unmodified line | ||
| 381 | 389 | regulator-name = "VMMC2_IO_18"; |
| 382 | 390 | regulator-min-microvolt = <1800000>; |
| 383 | 391 | regulator-max-microvolt = <1800000>; |
| 392 | + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ | |
| 384 | 393 | }; |
| 385 | 394 | |
| 386 | 395 | &vio { |
| @@ -46,7 +46,7 @@ · 45 unmodified lines | ||
| 46 | 46 | 0x480bd800 0x017c>; |
| 47 | 47 | interrupts = <24>; |
| 48 | 48 | iommus = <&mmu_isp>; |
| 49 | − syscon = <&scm_conf 0xdc>; | |
| 49 | + syscon = <&scm_conf 0x6c>; | |
| 50 | 50 | ti,phy-type = <OMAP3ISP_PHY_TYPE_COMPLEX_IO>; |
| 51 | 51 | #clock-cells = <1>; |
| 52 | 52 | ports { |
| @@ -472,7 +472,7 @@ · 471 unmodified lines | ||
| 472 | 472 | ldo1_reg: ldo1 { |
| 473 | 473 | /* VDDAPHY_CAM: vdda_csiport */ |
| 474 | 474 | regulator-name = "ldo1"; |
| 475 | − regulator-min-microvolt = <1500000>; | |
| 475 | + regulator-min-microvolt = <1800000>; | |
| 476 | 476 | regulator-max-microvolt = <1800000>; |
| 477 | 477 | }; |
| 478 | 478 | |
| @@ -498,7 +498,7 @@ · 19 unmodified lines | ||
| 498 | 498 | ldo4_reg: ldo4 { |
| 499 | 499 | /* VDDAPHY_DISP: vdda_dsiport/hdmi */ |
| 500 | 500 | regulator-name = "ldo4"; |
| 501 | − regulator-min-microvolt = <1500000>; | |
| 501 | + regulator-min-microvolt = <1800000>; | |
| 502 | 502 | regulator-max-microvolt = <1800000>; |
| 503 | 503 | }; |
| 504 | 504 | |
| @@ -513,7 +513,7 @@ · 512 unmodified lines | ||
| 513 | 513 | ldo1_reg: ldo1 { |
| 514 | 514 | /* VDDAPHY_CAM: vdda_csiport */ |
| 515 | 515 | regulator-name = "ldo1"; |
| 516 | − regulator-min-microvolt = <1500000>; | |
| 516 | + regulator-min-microvolt = <1800000>; | |
| 517 | 517 | regulator-max-microvolt = <1800000>; |
| 518 | 518 | }; |
| 519 | 519 | |
| @@ -537,7 +537,7 @@ · 17 unmodified lines | ||
| 537 | 537 | ldo4_reg: ldo4 { |
| 538 | 538 | /* VDDAPHY_DISP: vdda_dsiport/hdmi */ |
| 539 | 539 | regulator-name = "ldo4"; |
| 540 | − regulator-min-microvolt = <1500000>; | |
| 540 | + regulator-min-microvolt = <1800000>; | |
| 541 | 541 | regulator-max-microvolt = <1800000>; |
| 542 | 542 | }; |
| 543 | 543 | |
| @@ -269,7 +269,7 @@ · 268 unmodified lines | ||
| 269 | 269 | omap5_pmx_wkup: pinmux@c840 { |
| 270 | 270 | compatible = "ti,omap5-padconf", |
| 271 | 271 | "pinctrl-single"; |
| 272 | − reg = <0xc840 0x0038>; | |
| 272 | + reg = <0xc840 0x003c>; | |
| 273 | 273 | #address-cells = <1>; |
| 274 | 274 | #size-cells = <0>; |
| 275 | 275 | #interrupt-cells = <1>; |
| @@ -666,7 +666,7 @@ · 665 unmodified lines | ||
| 666 | 666 | }; |
| 667 | 667 | |
| 668 | 668 | sata0: sata@29000000 { |
| 669 | − compatible = "generic-ahci"; | |
| 669 | + compatible = "qcom,apq8064-ahci", "generic-ahci"; | |
| 670 | 670 | status = "disabled"; |
| 671 | 671 | reg = <0x29000000 0x180>; |
| 672 | 672 | interrupts = <GIC_SPI 209 IRQ_TYPE_NONE>; |
| @@ -688,6 +688,7 @@ · 15 unmodified lines | ||
| 688 | 688 | |
| 689 | 689 | phys = <&sata_phy0>; |
| 690 | 690 | phy-names = "sata-phy"; |
| 691 | + ports-implemented = <0x1>; | |
| 691 | 692 | }; |
| 692 | 693 | |
| 693 | 694 | /* Temporary fixed regulator */ |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | /dts-v1/; |
| 2 | 2 | |
| 3 | −#include <dt-bindings/interrupt-controller/arm-gic.h> | |
| 3 | +#include <dt-bindings/interrupt-controller/irq.h> | |
| 4 | 4 | #include <dt-bindings/clock/qcom,gcc-msm8974.h> |
| 5 | 5 | #include "skeleton.dtsi" |
| 6 | 6 | |
| @@ -460,8 +460,6 @@ · 453 unmodified lines | ||
| 460 | 460 | clock-names = "core", "iface"; |
| 461 | 461 | #address-cells = <1>; |
| 462 | 462 | #size-cells = <0>; |
| 463 | − dmas = <&blsp2_dma 20>, <&blsp2_dma 21>; | |
| 464 | − dma-names = "tx", "rx"; | |
| 465 | 463 | }; |
| 466 | 464 | |
| 467 | 465 | spmi_bus: spmi@fc4cf000 { |
| @@ -479,16 +477,6 @@ · 11 unmodified lines | ||
| 479 | 477 | interrupt-controller; |
| 480 | 478 | #interrupt-cells = <4>; |
| 481 | 479 | }; |
| 482 | − | |
| 483 | − blsp2_dma: dma-controller@f9944000 { | |
| 484 | − compatible = "qcom,bam-v1.4.0"; | |
| 485 | − reg = <0xf9944000 0x19000>; | |
| 486 | − interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>; | |
| 487 | − clocks = <&gcc GCC_BLSP2_AHB_CLK>; | |
| 488 | − clock-names = "bam_clk"; | |
| 489 | − #dma-cells = <1>; | |
| 490 | − qcom,ee = <0>; | |
| 491 | − }; | |
| 492 | 480 | }; |
| 493 | 481 | |
| 494 | 482 | smd { |
| @@ -661,6 +661,7 @@ · 660 unmodified lines | ||
| 661 | 661 | }; |
| 662 | 662 | |
| 663 | 663 | &pcie_bus_clk { |
| 664 | + clock-frequency = <100000000>; | |
| 664 | 665 | status = "okay"; |
| 665 | 666 | }; |
| 666 | 667 | |
| @@ -143,19 +143,11 @@ · 142 unmodified lines | ||
| 143 | 143 | }; |
| 144 | 144 | |
| 145 | 145 | &pfc { |
| 146 | − pinctrl-0 = <&scif_clk_pins>; | |
| 147 | − pinctrl-names = "default"; | |
| 148 | − | |
| 149 | 146 | scif0_pins: serial0 { |
| 150 | 147 | renesas,groups = "scif0_data_d"; |
| 151 | 148 | renesas,function = "scif0"; |
| 152 | 149 | }; |
| 153 | 150 | |
| 154 | − scif_clk_pins: scif_clk { | |
| 155 | − renesas,groups = "scif_clk"; | |
| 156 | − renesas,function = "scif_clk"; | |
| 157 | − }; | |
| 158 | − | |
| 159 | 151 | ether_pins: ether { |
| 160 | 152 | renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; |
| 161 | 153 | renesas,function = "eth"; |
| @@ -229,11 +221,6 @@ · 67 unmodified lines | ||
| 229 | 221 | status = "okay"; |
| 230 | 222 | }; |
| 231 | 223 | |
| 232 | −&scif_clk { | |
| 233 | − clock-frequency = <14745600>; | |
| 234 | − status = "okay"; | |
| 235 | −}; | |
| 236 | − | |
| 237 | 224 | ðer { |
| 238 | 225 | pinctrl-0 = <ðer_pins &phy1_pins>; |
| 239 | 226 | pinctrl-names = "default"; |
| @@ -414,6 +401,7 @@ · 174 unmodified lines | ||
| 414 | 401 | }; |
| 415 | 402 | |
| 416 | 403 | &pcie_bus_clk { |
| 404 | + clock-frequency = <100000000>; | |
| 417 | 405 | status = "okay"; |
| 418 | 406 | }; |
| 419 | 407 | |
| @@ -1083,9 +1083,8 @@ · 1082 unmodified lines | ||
| 1083 | 1083 | pcie_bus_clk: pcie_bus_clk { |
| 1084 | 1084 | compatible = "fixed-clock"; |
| 1085 | 1085 | #clock-cells = <0>; |
| 1086 | − clock-frequency = <100000000>; | |
| 1086 | + clock-frequency = <0>; | |
| 1087 | 1087 | clock-output-names = "pcie_bus"; |
| 1088 | − status = "disabled"; | |
| 1089 | 1088 | }; |
| 1090 | 1089 | |
| 1091 | 1090 | /* External SCIF clock */ |
| @@ -1094,7 +1093,6 @@ · 2 unmodified lines | ||
| 1094 | 1093 | #clock-cells = <0>; |
| 1095 | 1094 | /* This value must be overridden by the board. */ |
| 1096 | 1095 | clock-frequency = <0>; |
| 1097 | − status = "disabled"; | |
| 1098 | 1096 | }; |
| 1099 | 1097 | |
| 1100 | 1098 | /* External USB clock - can be overridden by the board */ |
| @@ -1112,7 +1110,6 @@ · 11 unmodified lines | ||
| 1112 | 1110 | /* This value must be overridden by the board. */ |
| 1113 | 1111 | clock-frequency = <0>; |
| 1114 | 1112 | clock-output-names = "can_clk"; |
| 1115 | − status = "disabled"; | |
| 1116 | 1113 | }; |
| 1117 | 1114 | |
| 1118 | 1115 | /* Special CPG clocks */ |
| @@ -125,8 +125,6 @@ · 124 unmodified lines | ||
| 125 | 125 | }; |
| 126 | 126 | |
| 127 | 127 | ®_dc1sw { |
| 128 | − regulator-min-microvolt = <3000000>; | |
| 129 | − regulator-max-microvolt = <3000000>; | |
| 130 | 128 | regulator-name = "vcc-lcd"; |
| 131 | 129 | }; |
| 132 | 130 | |
| @@ -84,6 +84,7 @@ · 83 unmodified lines | ||
| 84 | 84 | |
| 85 | 85 | #ifndef __ASSEMBLY__ |
| 86 | 86 | |
| 87 | +#ifdef CONFIG_CPU_CP15_MMU | |
| 87 | 88 | static inline unsigned int get_domain(void) |
| 88 | 89 | { |
| 89 | 90 | unsigned int domain; |
| @@ -103,6 +104,16 @@ static inline void set_domain(unsigned val) · 13 unmodified lines | ||
| 103 | 104 | : : "r" (val) : "memory"); |
| 104 | 105 | isb(); |
| 105 | 106 | } |
| 107 | +#else | |
| 108 | +static inline unsigned int get_domain(void) | |
| 109 | +{ | |
| 110 | + return 0; | |
| 111 | +} | |
| 112 | + | |
| 113 | +static inline void set_domain(unsigned val) | |
| 114 | +{ | |
| 115 | +} | |
| 116 | +#endif | |
| 106 | 117 | |
| 107 | 118 | #ifdef CONFIG_CPU_USE_DOMAINS |
| 108 | 119 | #define modify_domain(dom,type) \ |
| @@ -236,7 +236,7 @@ ENTRY(__setup_mpu) · 235 unmodified lines | ||
| 236 | 236 | mov r0, #CONFIG_VECTORS_BASE @ Cover from VECTORS_BASE |
| 237 | 237 | ldr r5,=(MPU_AP_PL1RW_PL0NA | MPU_RGN_NORMAL) |
| 238 | 238 | /* Writing N to bits 5:1 (RSR_SZ) --> region size 2^N+1 */ |
| 239 | − mov r6, #(((PAGE_SHIFT - 1) << MPU_RSR_SZ) | 1 << MPU_RSR_EN) | |
| 239 | + mov r6, #(((2 * PAGE_SHIFT - 1) << MPU_RSR_SZ) | 1 << MPU_RSR_EN) | |
| 240 | 240 | |
| 241 | 241 | setup_region r0, r5, r6, MPU_DATA_SIDE @ VECTORS_BASE, PL0 NA, enabled |
| 242 | 242 | beq 3f @ Memory-map not unified |
| @@ -1004,7 +1004,7 @@ static bool transparent_hugepage_adjust(kvm_pfn_t *pfnp, phys_addr_t *ipap) · 1003 unmodified lines | ||
| 1004 | 1004 | kvm_pfn_t pfn = *pfnp; |
| 1005 | 1005 | gfn_t gfn = *ipap >> PAGE_SHIFT; |
| 1006 | 1006 | |
| 1007 | − if (PageTransCompound(pfn_to_page(pfn))) { | |
| 1007 | + if (PageTransCompoundMap(pfn_to_page(pfn))) { | |
| 1008 | 1008 | unsigned long mask; |
| 1009 | 1009 | /* |
| 1010 | 1010 | * The address we faulted on is backed by a transparent huge |
| @@ -121,6 +121,11 @@ static void read_factory_config(struct nvmem_device *nvmem, void *context) · 120 unmodified lines | ||
| 121 | 121 | const char *partnum = NULL; |
| 122 | 122 | struct davinci_soc_info *soc_info = &davinci_soc_info; |
| 123 | 123 | |
| 124 | + if (!IS_BUILTIN(CONFIG_NVMEM)) { | |
| 125 | + pr_warn("Factory Config not available without CONFIG_NVMEM\n"); | |
| 126 | + goto bad_config; | |
| 127 | + } | |
| 128 | + | |
| 124 | 129 | ret = nvmem_device_read(nvmem, 0, sizeof(factory_config), |
| 125 | 130 | &factory_config); |
| 126 | 131 | if (ret != sizeof(struct factory_config)) { |
| @@ -33,6 +33,11 @@ void davinci_get_mac_addr(struct nvmem_device *nvmem, void *context) · 32 unmodified lines | ||
| 33 | 33 | char *mac_addr = davinci_soc_info.emac_pdata->mac_addr; |
| 34 | 34 | off_t offset = (off_t)context; |
| 35 | 35 | |
| 36 | + if (!IS_BUILTIN(CONFIG_NVMEM)) { | |
| 37 | + pr_warn("Cannot read MAC addr from EEPROM without CONFIG_NVMEM\n"); | |
| 38 | + return; | |
| 39 | + } | |
| 40 | + | |
| 36 | 41 | /* Read MAC addr from EEPROM */ |
| 37 | 42 | if (nvmem_device_read(nvmem, offset, ETH_ALEN, mac_addr) == ETH_ALEN) |
| 38 | 43 | pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr); |
| @@ -92,7 +92,7 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) · 91 unmodified lines | ||
| 92 | 92 | if (IS_ERR(pd->clk[i])) |
| 93 | 93 | break; |
| 94 | 94 | |
| 95 | − if (IS_ERR(pd->clk[i])) | |
| 95 | + if (IS_ERR(pd->pclk[i])) | |
| 96 | 96 | continue; /* Skip on first power up */ |
| 97 | 97 | if (clk_set_parent(pd->clk[i], pd->pclk[i])) |
| 98 | 98 | pr_err("%s: error setting parent to clock%d\n", |
| @@ -71,6 +71,7 @@ struct platform_device *__init imx_add_sdhci_esdhc_imx( · 70 unmodified lines | ||
| 71 | 71 | if (!pdata) |
| 72 | 72 | pdata = &default_esdhc_pdata; |
| 73 | 73 | |
| 74 | − return imx_add_platform_device(data->devid, data->id, res, | |
| 75 | − ARRAY_SIZE(res), pdata, sizeof(*pdata)); | |
| 74 | + return imx_add_platform_device_dmamask(data->devid, data->id, res, | |
| 75 | + ARRAY_SIZE(res), pdata, sizeof(*pdata), | |
| 76 | + DMA_BIT_MASK(32)); | |
| 76 | 77 | } |
| @@ -461,7 +461,7 @@ static struct clockdomain ipu_7xx_clkdm = { · 460 unmodified lines | ||
| 461 | 461 | .cm_inst = DRA7XX_CM_CORE_AON_IPU_INST, |
| 462 | 462 | .clkdm_offs = DRA7XX_CM_CORE_AON_IPU_IPU_CDOFFS, |
| 463 | 463 | .dep_bit = DRA7XX_IPU_STATDEP_SHIFT, |
| 464 | − .flags = CLKDM_CAN_HWSUP_SWSUP, | |
| 464 | + .flags = CLKDM_CAN_SWSUP, | |
| 465 | 465 | }; |
| 466 | 466 | |
| 467 | 467 | static struct clockdomain mpu1_7xx_clkdm = { |
| @@ -737,7 +737,8 @@ void __init omap5_init_late(void) · 736 unmodified lines | ||
| 737 | 737 | #ifdef CONFIG_SOC_DRA7XX |
| 738 | 738 | void __init dra7xx_init_early(void) |
| 739 | 739 | { |
| 740 | − omap2_set_globals_tap(-1, OMAP2_L4_IO_ADDRESS(DRA7XX_TAP_BASE)); | |
| 740 | + omap2_set_globals_tap(DRA7XX_CLASS, | |
| 741 | + OMAP2_L4_IO_ADDRESS(DRA7XX_TAP_BASE)); | |
| 741 | 742 | omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE)); |
| 742 | 743 | omap2_control_base_init(); |
| 743 | 744 | omap4_pm_init_early(); |
| @@ -274,6 +274,10 @@ static inline void omap5_irq_save_context(void) · 273 unmodified lines | ||
| 274 | 274 | */ |
| 275 | 275 | static void irq_save_context(void) |
| 276 | 276 | { |
| 277 | + /* DRA7 has no SAR to save */ | |
| 278 | + if (soc_is_dra7xx()) | |
| 279 | + return; | |
| 280 | + | |
| 277 | 281 | if (!sar_base) |
| 278 | 282 | sar_base = omap4_get_sar_ram_base(); |
| 279 | 283 | |
| @@ -290,6 +294,9 @@ static void irq_sar_clear(void) · 10 unmodified lines | ||
| 290 | 294 | { |
| 291 | 295 | u32 val; |
| 292 | 296 | u32 offset = SAR_BACKUP_STATUS_OFFSET; |
| 297 | + /* DRA7 has no SAR to save */ | |
| 298 | + if (soc_is_dra7xx()) | |
| 299 | + return; | |
| 293 | 300 | |
| 294 | 301 | if (soc_is_omap54xx()) |
| 295 | 302 | offset = OMAP5_SAR_BACKUP_STATUS_OFFSET; |
| @@ -198,7 +198,6 @@ void omap_sram_idle(void) · 197 unmodified lines | ||
| 198 | 198 | int per_next_state = PWRDM_POWER_ON; |
| 199 | 199 | int core_next_state = PWRDM_POWER_ON; |
| 200 | 200 | int per_going_off; |
| 201 | − int core_prev_state; | |
| 202 | 201 | u32 sdrc_pwr = 0; |
| 203 | 202 | |
| 204 | 203 | mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm); |
| @@ -278,16 +277,20 @@ void omap_sram_idle(void) · 73 unmodified lines | ||
| 278 | 277 | sdrc_write_reg(sdrc_pwr, SDRC_POWER); |
| 279 | 278 | |
| 280 | 279 | /* CORE */ |
| 281 | − if (core_next_state < PWRDM_POWER_ON) { | |
| 282 | − core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm); | |
| 283 | − if (core_prev_state == PWRDM_POWER_OFF) { | |
| 284 | − omap3_core_restore_context(); | |
| 285 | − omap3_cm_restore_context(); | |
| 286 | − omap3_sram_restore_context(); | |
| 287 | − omap2_sms_restore_context(); | |
| 288 | − } | |
| 280 | + if (core_next_state < PWRDM_POWER_ON && | |
| 281 | + pwrdm_read_prev_pwrst(core_pwrdm) == PWRDM_POWER_OFF) { | |
| 282 | + omap3_core_restore_context(); | |
| 283 | + omap3_cm_restore_context(); | |
| 284 | + omap3_sram_restore_context(); | |
| 285 | + omap2_sms_restore_context(); | |
| 286 | + } else { | |
| 287 | + /* | |
| 288 | + * In off-mode resume path above, omap3_core_restore_context | |
| 289 | + * also handles the INTC autoidle restore done here so limit | |
| 290 | + * this to non-off mode resume paths so we don't do it twice. | |
| 291 | + */ | |
| 292 | + omap3_intc_resume_idle(); | |
| 289 | 293 | } |
| 290 | − omap3_intc_resume_idle(); | |
| 291 | 294 | |
| 292 | 295 | pwrdm_post_transition(NULL); |
| 293 | 296 | |
| @@ -40,8 +40,7 @@ static void __init shmobile_setup_delay_hz(unsigned int max_cpu_core_hz, · 39 unmodified lines | ||
| 40 | 40 | void __init shmobile_init_delay(void) |
| 41 | 41 | { |
| 42 | 42 | struct device_node *np, *cpus; |
| 43 | − bool is_a7_a8_a9 = false; | |
| 44 | − bool is_a15 = false; | |
| 43 | + unsigned int div = 0; | |
| 45 | 44 | bool has_arch_timer = false; |
| 46 | 45 | u32 max_freq = 0; |
| 47 | 46 | |
| @@ -55,27 +54,22 @@ void __init shmobile_init_delay(void) · 7 unmodified lines | ||
| 55 | 54 | if (!of_property_read_u32(np, "clock-frequency", &freq)) |
| 56 | 55 | max_freq = max(max_freq, freq); |
| 57 | 56 | |
| 58 | − if (of_device_is_compatible(np, "arm,cortex-a8") || | |
| 59 | − of_device_is_compatible(np, "arm,cortex-a9")) { | |
| 60 | − is_a7_a8_a9 = true; | |
| 61 | − } else if (of_device_is_compatible(np, "arm,cortex-a7")) { | |
| 62 | − is_a7_a8_a9 = true; | |
| 63 | − has_arch_timer = true; | |
| 64 | − } else if (of_device_is_compatible(np, "arm,cortex-a15")) { | |
| 65 | − is_a15 = true; | |
| 57 | + if (of_device_is_compatible(np, "arm,cortex-a8")) { | |
| 58 | + div = 2; | |
| 59 | + } else if (of_device_is_compatible(np, "arm,cortex-a9")) { | |
| 60 | + div = 1; | |
| 61 | + } else if (of_device_is_compatible(np, "arm,cortex-a7") || | |
| 62 | + of_device_is_compatible(np, "arm,cortex-a15")) { | |
| 63 | + div = 1; | |
| 66 | 64 | has_arch_timer = true; |
| 67 | 65 | } |
| 68 | 66 | } |
| 69 | 67 | |
| 70 | 68 | of_node_put(cpus); |
| 71 | 69 | |
| 72 | − if (!max_freq) | |
| 70 | + if (!max_freq || !div) | |
| 73 | 71 | return; |
| 74 | 72 | |
| 75 | − if (!has_arch_timer || !IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) { | |
| 76 | − if (is_a7_a8_a9) | |
| 77 | − shmobile_setup_delay_hz(max_freq, 1, 3); | |
| 78 | − else if (is_a15) | |
| 79 | − shmobile_setup_delay_hz(max_freq, 2, 4); | |
| 80 | − } | |
| 73 | + if (!has_arch_timer || !IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) | |
| 74 | + shmobile_setup_delay_hz(max_freq, 1, div); | |
| 81 | 75 | } |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <asm/assembler.h> |
| 14 | 14 | |
| 15 | 15 | .arch armv7-a |
| 16 | + .arm | |
| 16 | 17 | |
| 17 | 18 | ENTRY(secondary_trampoline) |
| 18 | 19 | /* CPU1 will always fetch from 0x0 when it is brought out of reset. |
| @@ -87,7 +87,6 @@ static unsigned long irbar_read(void) · 86 unmodified lines | ||
| 87 | 87 | /* MPU initialisation functions */ |
| 88 | 88 | void __init sanity_check_meminfo_mpu(void) |
| 89 | 89 | { |
| 90 | − int i; | |
| 91 | 90 | phys_addr_t phys_offset = PHYS_OFFSET; |
| 92 | 91 | phys_addr_t aligned_region_size, specified_mem_size, rounded_mem_size; |
| 93 | 92 | struct memblock_region *reg; |
| @@ -110,11 +109,13 @@ void __init sanity_check_meminfo_mpu(void) · 16 unmodified lines | ||
| 110 | 109 | } else { |
| 111 | 110 | /* |
| 112 | 111 | * memblock auto merges contiguous blocks, remove |
| 113 | − * all blocks afterwards | |
| 112 | + * all blocks afterwards in one go (we can't remove | |
| 113 | + * blocks separately while iterating) | |
| 114 | 114 | */ |
| 115 | 115 | pr_notice("Ignoring RAM after %pa, memory at %pa ignored\n", |
| 116 | − &mem_start, ®->base); | |
| 117 | − memblock_remove(reg->base, reg->size); | |
| 116 | + &mem_end, ®->base); | |
| 117 | + memblock_remove(reg->base, 0 - reg->base); | |
| 118 | + break; | |
| 118 | 119 | } |
| 119 | 120 | } |
| 120 | 121 | |
| @@ -144,7 +145,7 @@ void __init sanity_check_meminfo_mpu(void) · 23 unmodified lines | ||
| 144 | 145 | pr_warn("Truncating memory from %pa to %pa (MPU region constraints)", |
| 145 | 146 | &specified_mem_size, &aligned_region_size); |
| 146 | 147 | memblock_remove(mem_start + aligned_region_size, |
| 147 | − specified_mem_size - aligned_round_size); | |
| 148 | + specified_mem_size - aligned_region_size); | |
| 148 | 149 | |
| 149 | 150 | mem_end = mem_start + aligned_region_size; |
| 150 | 151 | } |
| @@ -261,7 +262,7 @@ void __init mpu_setup(void) · 110 unmodified lines | ||
| 261 | 262 | return; |
| 262 | 263 | |
| 263 | 264 | region_err = mpu_setup_region(MPU_RAM_REGION, PHYS_OFFSET, |
| 264 | − ilog2(meminfo.bank[0].size), | |
| 265 | + ilog2(memblock.memory.regions[0].size), | |
| 265 | 266 | MPU_AP_PL1RW_PL0RW | MPU_RGN_NORMAL); |
| 266 | 267 | if (region_err) { |
| 267 | 268 | panic("MPU region initialization failure! %d", region_err); |
| @@ -285,7 +286,7 @@ void __init arm_mm_memblock_reserve(void) · 17 unmodified lines | ||
| 285 | 286 | * some architectures which the DRAM is the exception vector to trap, |
| 286 | 287 | * alloc_page breaks with error, although it is not NULL, but "0." |
| 287 | 288 | */ |
| 288 | − memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE); | |
| 289 | + memblock_reserve(CONFIG_VECTORS_BASE, 2 * PAGE_SIZE); | |
| 289 | 290 | #else /* ifndef CONFIG_CPU_V7M */ |
| 290 | 291 | /* |
| 291 | 292 | * There is no dedicated vector page on V7-M. So nothing needs to be |
| @@ -120,7 +120,6 @@ · 119 unmodified lines | ||
| 120 | 120 | compatible = "fixed-clock"; |
| 121 | 121 | #clock-cells = <0>; |
| 122 | 122 | clock-frequency = <0>; |
| 123 | − status = "disabled"; | |
| 124 | 123 | }; |
| 125 | 124 | |
| 126 | 125 | soc { |
| @@ -70,7 +70,6 @@ · 69 unmodified lines | ||
| 70 | 70 | i2c3 = &i2c3; |
| 71 | 71 | i2c4 = &i2c4; |
| 72 | 72 | i2c5 = &i2c5; |
| 73 | − i2c6 = &i2c6; | |
| 74 | 73 | }; |
| 75 | 74 | }; |
| 76 | 75 | |
| @@ -201,15 +201,12 @@ · 200 unmodified lines | ||
| 201 | 201 | |
| 202 | 202 | i2c2: i2c@58782000 { |
| 203 | 203 | compatible = "socionext,uniphier-fi2c"; |
| 204 | − status = "disabled"; | |
| 205 | 204 | reg = <0x58782000 0x80>; |
| 206 | 205 | #address-cells = <1>; |
| 207 | 206 | #size-cells = <0>; |
| 208 | 207 | interrupts = <0 43 4>; |
| 209 | − pinctrl-names = "default"; | |
| 210 | − pinctrl-0 = <&pinctrl_i2c2>; | |
| 211 | 208 | clocks = <&i2c_clk>; |
| 212 | − clock-frequency = <100000>; | |
| 209 | + clock-frequency = <400000>; | |
| 213 | 210 | }; |
| 214 | 211 | |
| 215 | 212 | i2c3: i2c@58783000 { |
| @@ -227,12 +224,15 @@ · 11 unmodified lines | ||
| 227 | 224 | |
| 228 | 225 | i2c4: i2c@58784000 { |
| 229 | 226 | compatible = "socionext,uniphier-fi2c"; |
| 227 | + status = "disabled"; | |
| 230 | 228 | reg = <0x58784000 0x80>; |
| 231 | 229 | #address-cells = <1>; |
| 232 | 230 | #size-cells = <0>; |
| 233 | 231 | interrupts = <0 45 4>; |
| 232 | + pinctrl-names = "default"; | |
| 233 | + pinctrl-0 = <&pinctrl_i2c4>; | |
| 234 | 234 | clocks = <&i2c_clk>; |
| 235 | − clock-frequency = <400000>; | |
| 235 | + clock-frequency = <100000>; | |
| 236 | 236 | }; |
| 237 | 237 | |
| 238 | 238 | i2c5: i2c@58785000 { |
| @@ -245,16 +245,6 @@ · 6 unmodified lines | ||
| 245 | 245 | clock-frequency = <400000>; |
| 246 | 246 | }; |
| 247 | 247 | |
| 248 | − i2c6: i2c@58786000 { | |
| 249 | − compatible = "socionext,uniphier-fi2c"; | |
| 250 | − reg = <0x58786000 0x80>; | |
| 251 | − #address-cells = <1>; | |
| 252 | − #size-cells = <0>; | |
| 253 | − interrupts = <0 26 4>; | |
| 254 | − clocks = <&i2c_clk>; | |
| 255 | − clock-frequency = <400000>; | |
| 256 | − }; | |
| 257 | − | |
| 258 | 248 | system_bus: system-bus@58c00000 { |
| 259 | 249 | compatible = "socionext,uniphier-system-bus"; |
| 260 | 250 | status = "disabled"; |
| @@ -68,7 +68,7 @@ void *memset(void *s, int c, size_t count) · 67 unmodified lines | ||
| 68 | 68 | "=r" (charcnt), /* %1 Output */ |
| 69 | 69 | "=r" (dwordcnt), /* %2 Output */ |
| 70 | 70 | "=r" (fill8reg), /* %3 Output */ |
| 71 | − "=r" (wrkrega) /* %4 Output */ | |
| 71 | + "=&r" (wrkrega) /* %4 Output only */ | |
| 72 | 72 | : "r" (c), /* %5 Input */ |
| 73 | 73 | "0" (s), /* %0 Input/Output */ |
| 74 | 74 | "1" (count) /* %1 Input/Output */ |
| @@ -344,7 +344,7 @@ tracesys_next: · 343 unmodified lines | ||
| 344 | 344 | #endif |
| 345 | 345 | |
| 346 | 346 | cmpib,COND(=),n -1,%r20,tracesys_exit /* seccomp may have returned -1 */ |
| 347 | − comiclr,>>= __NR_Linux_syscalls, %r20, %r0 | |
| 347 | + comiclr,>> __NR_Linux_syscalls, %r20, %r0 | |
| 348 | 348 | b,n .Ltracesys_nosys |
| 349 | 349 | |
| 350 | 350 | LDREGX %r20(%r19), %r19 |
| @@ -384,3 +384,5 @@ SYSCALL(ni_syscall) · 383 unmodified lines | ||
| 384 | 384 | SYSCALL(ni_syscall) |
| 385 | 385 | SYSCALL(mlock2) |
| 386 | 386 | SYSCALL(copy_file_range) |
| 387 | +COMPAT_SYS_SPU(preadv2) | |
| 388 | +COMPAT_SYS_SPU(pwritev2) | |
| @@ -12,7 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <uapi/asm/unistd.h> |
| 13 | 13 | |
| 14 | 14 | |
| 15 | −#define NR_syscalls 380 | |
| 15 | +#define NR_syscalls 382 | |
| 16 | 16 | |
| 17 | 17 | #define __NR__exit __NR_exit |
| 18 | 18 | |
| @@ -82,7 +82,7 @@ static inline unsigned long create_zero_mask(unsigned long bits) · 81 unmodified lines | ||
| 82 | 82 | "andc %1,%1,%2\n\t" |
| 83 | 83 | "popcntd %0,%1" |
| 84 | 84 | : "=r" (leading_zero_bits), "=&r" (trailing_zero_bit_mask) |
| 85 | − : "r" (bits)); | |
| 85 | + : "b" (bits)); | |
| 86 | 86 | |
| 87 | 87 | return leading_zero_bits; |
| 88 | 88 | } |
| @@ -390,5 +390,7 @@ · 389 unmodified lines | ||
| 390 | 390 | #define __NR_membarrier 365 |
| 391 | 391 | #define __NR_mlock2 378 |
| 392 | 392 | #define __NR_copy_file_range 379 |
| 393 | +#define __NR_preadv2 380 | |
| 394 | +#define __NR_pwritev2 381 | |
| 393 | 395 | |
| 394 | 396 | #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ |
| @@ -11,7 +11,7 @@ typedef struct { · 10 unmodified lines | ||
| 11 | 11 | spinlock_t list_lock; |
| 12 | 12 | struct list_head pgtable_list; |
| 13 | 13 | struct list_head gmap_list; |
| 14 | − unsigned long asce_bits; | |
| 14 | + unsigned long asce; | |
| 15 | 15 | unsigned long asce_limit; |
| 16 | 16 | unsigned long vdso_base; |
| 17 | 17 | /* The mmu context allocates 4K page tables. */ |
| @@ -26,12 +26,28 @@ static inline int init_new_context(struct task_struct *tsk, · 25 unmodified lines | ||
| 26 | 26 | mm->context.has_pgste = 0; |
| 27 | 27 | mm->context.use_skey = 0; |
| 28 | 28 | #endif |
| 29 | − if (mm->context.asce_limit == 0) { | |
| 29 | + switch (mm->context.asce_limit) { | |
| 30 | + case 1UL << 42: | |
| 31 | + /* | |
| 32 | + * forked 3-level task, fall through to set new asce with new | |
| 33 | + * mm->pgd | |
| 34 | + */ | |
| 35 | + case 0: | |
| 30 | 36 | /* context created by exec, set asce limit to 4TB */ |
| 31 | − mm->context.asce_bits = _ASCE_TABLE_LENGTH | | |
| 32 | − _ASCE_USER_BITS | _ASCE_TYPE_REGION3; | |
| 33 | 37 | mm->context.asce_limit = STACK_TOP_MAX; |
| 34 | − } else if (mm->context.asce_limit == (1UL << 31)) { | |
| 38 | + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | | |
| 39 | + _ASCE_USER_BITS | _ASCE_TYPE_REGION3; | |
| 40 | + break; | |
| 41 | + case 1UL << 53: | |
| 42 | + /* forked 4-level task, set new asce with new mm->pgd */ | |
| 43 | + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | | |
| 44 | + _ASCE_USER_BITS | _ASCE_TYPE_REGION2; | |
| 45 | + break; | |
| 46 | + case 1UL << 31: | |
| 47 | + /* forked 2-level compat task, set new asce with new mm->pgd */ | |
| 48 | + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | | |
| 49 | + _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT; | |
| 50 | + /* pgd_alloc() did not increase mm->nr_pmds */ | |
| 35 | 51 | mm_inc_nr_pmds(mm); |
| 36 | 52 | } |
| 37 | 53 | crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); |
| @@ -42,7 +58,7 @@ static inline int init_new_context(struct task_struct *tsk, · 4 unmodified lines | ||
| 42 | 58 | |
| 43 | 59 | static inline void set_user_asce(struct mm_struct *mm) |
| 44 | 60 | { |
| 45 | − S390_lowcore.user_asce = mm->context.asce_bits | __pa(mm->pgd); | |
| 61 | + S390_lowcore.user_asce = mm->context.asce; | |
| 46 | 62 | if (current->thread.mm_segment.ar4) |
| 47 | 63 | __ctl_load(S390_lowcore.user_asce, 7, 7); |
| 48 | 64 | set_cpu_flag(CIF_ASCE); |
| @@ -71,7 +87,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, · 22 unmodified lines | ||
| 71 | 87 | { |
| 72 | 88 | int cpu = smp_processor_id(); |
| 73 | 89 | |
| 74 | − S390_lowcore.user_asce = next->context.asce_bits | __pa(next->pgd); | |
| 90 | + S390_lowcore.user_asce = next->context.asce; | |
| 75 | 91 | if (prev == next) |
| 76 | 92 | return; |
| 77 | 93 | if (MACHINE_HAS_TLB_LC) |
| @@ -52,8 +52,8 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm) · 51 unmodified lines | ||
| 52 | 52 | return _REGION2_ENTRY_EMPTY; |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | −int crst_table_upgrade(struct mm_struct *, unsigned long limit); | |
| 56 | −void crst_table_downgrade(struct mm_struct *, unsigned long limit); | |
| 55 | +int crst_table_upgrade(struct mm_struct *); | |
| 56 | +void crst_table_downgrade(struct mm_struct *); | |
| 57 | 57 | |
| 58 | 58 | static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address) |
| 59 | 59 | { |
| @@ -175,7 +175,7 @@ extern __vector128 init_task_fpu_regs[__NUM_VXRS]; · 174 unmodified lines | ||
| 175 | 175 | regs->psw.mask = PSW_USER_BITS | PSW_MASK_BA; \ |
| 176 | 176 | regs->psw.addr = new_psw; \ |
| 177 | 177 | regs->gprs[15] = new_stackp; \ |
| 178 | − crst_table_downgrade(current->mm, 1UL << 31); \ | |
| 178 | + crst_table_downgrade(current->mm); \ | |
| 179 | 179 | execve_tail(); \ |
| 180 | 180 | } while (0) |
| 181 | 181 | |
| @@ -110,8 +110,7 @@ static inline void __tlb_flush_asce(struct mm_struct *mm, unsigned long asce) · 109 unmodified lines | ||
| 110 | 110 | static inline void __tlb_flush_kernel(void) |
| 111 | 111 | { |
| 112 | 112 | if (MACHINE_HAS_IDTE) |
| 113 | − __tlb_flush_idte((unsigned long) init_mm.pgd | | |
| 114 | − init_mm.context.asce_bits); | |
| 113 | + __tlb_flush_idte(init_mm.context.asce); | |
| 115 | 114 | else |
| 116 | 115 | __tlb_flush_global(); |
| 117 | 116 | } |
| @@ -133,8 +132,7 @@ static inline void __tlb_flush_asce(struct mm_struct *mm, unsigned long asce) · 15 unmodified lines | ||
| 133 | 132 | static inline void __tlb_flush_kernel(void) |
| 134 | 133 | { |
| 135 | 134 | if (MACHINE_HAS_TLB_LC) |
| 136 | − __tlb_flush_idte_local((unsigned long) init_mm.pgd | | |
| 137 | − init_mm.context.asce_bits); | |
| 135 | + __tlb_flush_idte_local(init_mm.context.asce); | |
| 138 | 136 | else |
| 139 | 137 | __tlb_flush_local(); |
| 140 | 138 | } |
| @@ -148,8 +146,7 @@ static inline void __tlb_flush_mm(struct mm_struct * mm) · 7 unmodified lines | ||
| 148 | 146 | * only ran on the local cpu. |
| 149 | 147 | */ |
| 150 | 148 | if (MACHINE_HAS_IDTE && list_empty(&mm->context.gmap_list)) |
| 151 | − __tlb_flush_asce(mm, (unsigned long) mm->pgd | | |
| 152 | − mm->context.asce_bits); | |
| 149 | + __tlb_flush_asce(mm, mm->context.asce); | |
| 153 | 150 | else |
| 154 | 151 | __tlb_flush_full(mm); |
| 155 | 152 | } |
| @@ -89,7 +89,8 @@ void __init paging_init(void) · 88 unmodified lines | ||
| 89 | 89 | asce_bits = _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH; |
| 90 | 90 | pgd_type = _REGION3_ENTRY_EMPTY; |
| 91 | 91 | } |
| 92 | − S390_lowcore.kernel_asce = (__pa(init_mm.pgd) & PAGE_MASK) | asce_bits; | |
| 92 | + init_mm.context.asce = (__pa(init_mm.pgd) & PAGE_MASK) | asce_bits; | |
| 93 | + S390_lowcore.kernel_asce = init_mm.context.asce; | |
| 93 | 94 | clear_table((unsigned long *) init_mm.pgd, pgd_type, |
| 94 | 95 | sizeof(unsigned long)*2048); |
| 95 | 96 | vmem_map_init(); |
| @@ -174,7 +174,7 @@ int s390_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) · 173 unmodified lines | ||
| 174 | 174 | if (!(flags & MAP_FIXED)) |
| 175 | 175 | addr = 0; |
| 176 | 176 | if ((addr + len) >= TASK_SIZE) |
| 177 | − return crst_table_upgrade(current->mm, TASK_MAX_SIZE); | |
| 177 | + return crst_table_upgrade(current->mm); | |
| 178 | 178 | return 0; |
| 179 | 179 | } |
| 180 | 180 | |
| @@ -191,7 +191,7 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr, · 10 unmodified lines | ||
| 191 | 191 | return area; |
| 192 | 192 | if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < TASK_MAX_SIZE) { |
| 193 | 193 | /* Upgrade the page table to 4 levels and retry. */ |
| 194 | − rc = crst_table_upgrade(mm, TASK_MAX_SIZE); | |
| 194 | + rc = crst_table_upgrade(mm); | |
| 195 | 195 | if (rc) |
| 196 | 196 | return (unsigned long) rc; |
| 197 | 197 | area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); |
| @@ -213,7 +213,7 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, · 15 unmodified lines | ||
| 213 | 213 | return area; |
| 214 | 214 | if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < TASK_MAX_SIZE) { |
| 215 | 215 | /* Upgrade the page table to 4 levels and retry. */ |
| 216 | − rc = crst_table_upgrade(mm, TASK_MAX_SIZE); | |
| 216 | + rc = crst_table_upgrade(mm); | |
| 217 | 217 | if (rc) |
| 218 | 218 | return (unsigned long) rc; |
| 219 | 219 | area = arch_get_unmapped_area_topdown(filp, addr, len, |
| @@ -76,81 +76,52 @@ static void __crst_table_upgrade(void *arg) · 75 unmodified lines | ||
| 76 | 76 | __tlb_flush_local(); |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | −int crst_table_upgrade(struct mm_struct *mm, unsigned long limit) | |
| 79 | +int crst_table_upgrade(struct mm_struct *mm) | |
| 80 | 80 | { |
| 81 | 81 | unsigned long *table, *pgd; |
| 82 | − unsigned long entry; | |
| 83 | − int flush; | |
| 84 | 82 | |
| 85 | − BUG_ON(limit > TASK_MAX_SIZE); | |
| 86 | − flush = 0; | |
| 87 | −repeat: | |
| 83 | + /* upgrade should only happen from 3 to 4 levels */ | |
| 84 | + BUG_ON(mm->context.asce_limit != (1UL << 42)); | |
| 85 | + | |
| 88 | 86 | table = crst_table_alloc(mm); |
| 89 | 87 | if (!table) |
| 90 | 88 | return -ENOMEM; |
| 89 | + | |
| 91 | 90 | spin_lock_bh(&mm->page_table_lock); |
| 92 | − if (mm->context.asce_limit < limit) { | |
| 93 | − pgd = (unsigned long *) mm->pgd; | |
| 94 | − if (mm->context.asce_limit <= (1UL << 31)) { | |
| 95 | − entry = _REGION3_ENTRY_EMPTY; | |
| 96 | − mm->context.asce_limit = 1UL << 42; | |
| 97 | − mm->context.asce_bits = _ASCE_TABLE_LENGTH | | |
| 98 | − _ASCE_USER_BITS | | |
| 99 | − _ASCE_TYPE_REGION3; | |
| 100 | − } else { | |
| 101 | − entry = _REGION2_ENTRY_EMPTY; | |
| 102 | − mm->context.asce_limit = 1UL << 53; | |
| 103 | − mm->context.asce_bits = _ASCE_TABLE_LENGTH | | |
| 104 | − _ASCE_USER_BITS | | |
| 105 | − _ASCE_TYPE_REGION2; | |
| 106 | − } | |
| 107 | − crst_table_init(table, entry); | |
| 108 | − pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd); | |
| 109 | − mm->pgd = (pgd_t *) table; | |
| 110 | − mm->task_size = mm->context.asce_limit; | |
| 111 | − table = NULL; | |
| 112 | − flush = 1; | |
| 113 | − } | |
| 91 | + pgd = (unsigned long *) mm->pgd; | |
| 92 | + crst_table_init(table, _REGION2_ENTRY_EMPTY); | |
| 93 | + pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd); | |
| 94 | + mm->pgd = (pgd_t *) table; | |
| 95 | + mm->context.asce_limit = 1UL << 53; | |
| 96 | + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | | |
| 97 | + _ASCE_USER_BITS | _ASCE_TYPE_REGION2; | |
| 98 | + mm->task_size = mm->context.asce_limit; | |
| 114 | 99 | spin_unlock_bh(&mm->page_table_lock); |
| 115 | − if (table) | |
| 116 | − crst_table_free(mm, table); | |
| 117 | − if (mm->context.asce_limit < limit) | |
| 118 | − goto repeat; | |
| 119 | − if (flush) | |
| 120 | − on_each_cpu(__crst_table_upgrade, mm, 0); | |
| 100 | + | |
| 101 | + on_each_cpu(__crst_table_upgrade, mm, 0); | |
| 121 | 102 | return 0; |
| 122 | 103 | } |
| 123 | 104 | |
| 124 | −void crst_table_downgrade(struct mm_struct *mm, unsigned long limit) | |
| 105 | +void crst_table_downgrade(struct mm_struct *mm) | |
| 125 | 106 | { |
| 126 | 107 | pgd_t *pgd; |
| 127 | 108 | |
| 109 | + /* downgrade should only happen from 3 to 2 levels (compat only) */ | |
| 110 | + BUG_ON(mm->context.asce_limit != (1UL << 42)); | |
| 111 | + | |
| 128 | 112 | if (current->active_mm == mm) { |
| 129 | 113 | clear_user_asce(); |
| 130 | 114 | __tlb_flush_mm(mm); |
| 131 | 115 | } |
| 132 | − while (mm->context.asce_limit > limit) { | |
| 133 | − pgd = mm->pgd; | |
| 134 | − switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) { | |
| 135 | − case _REGION_ENTRY_TYPE_R2: | |
| 136 | − mm->context.asce_limit = 1UL << 42; | |
| 137 | − mm->context.asce_bits = _ASCE_TABLE_LENGTH | | |
| 138 | − _ASCE_USER_BITS | | |
| 139 | − _ASCE_TYPE_REGION3; | |
| 140 | − break; | |
| 141 | − case _REGION_ENTRY_TYPE_R3: | |
| 142 | − mm->context.asce_limit = 1UL << 31; | |
| 143 | − mm->context.asce_bits = _ASCE_TABLE_LENGTH | | |
| 144 | − _ASCE_USER_BITS | | |
| 145 | − _ASCE_TYPE_SEGMENT; | |
| 146 | − break; | |
| 147 | − default: | |
| 148 | − BUG(); | |
| 149 | − } | |
| 150 | − mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN); | |
| 151 | − mm->task_size = mm->context.asce_limit; | |
| 152 | − crst_table_free(mm, (unsigned long *) pgd); | |
| 153 | − } | |
| 116 | + | |
| 117 | + pgd = mm->pgd; | |
| 118 | + mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN); | |
| 119 | + mm->context.asce_limit = 1UL << 31; | |
| 120 | + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | | |
| 121 | + _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT; | |
| 122 | + mm->task_size = mm->context.asce_limit; | |
| 123 | + crst_table_free(mm, (unsigned long *) pgd); | |
| 124 | + | |
| 154 | 125 | if (current->active_mm == mm) |
| 155 | 126 | set_user_asce(mm); |
| 156 | 127 | } |
| @@ -457,7 +457,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev) · 456 unmodified lines | ||
| 457 | 457 | zdev->dma_table = dma_alloc_cpu_table(); |
| 458 | 458 | if (!zdev->dma_table) { |
| 459 | 459 | rc = -ENOMEM; |
| 460 | − goto out_clean; | |
| 460 | + goto out; | |
| 461 | 461 | } |
| 462 | 462 | |
| 463 | 463 | /* |
| @@ -477,18 +477,22 @@ int zpci_dma_init_device(struct zpci_dev *zdev) · 13 unmodified lines | ||
| 477 | 477 | zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8); |
| 478 | 478 | if (!zdev->iommu_bitmap) { |
| 479 | 479 | rc = -ENOMEM; |
| 480 | − goto out_reg; | |
| 480 | + goto free_dma_table; | |
| 481 | 481 | } |
| 482 | 482 | |
| 483 | 483 | rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma, |
| 484 | 484 | (u64) zdev->dma_table); |
| 485 | 485 | if (rc) |
| 486 | − goto out_reg; | |
| 487 | − return 0; | |
| 486 | + goto free_bitmap; | |
| 488 | 487 | |
| 489 | −out_reg: | |
| 488 | + return 0; | |
| 489 | +free_bitmap: | |
| 490 | + vfree(zdev->iommu_bitmap); | |
| 491 | + zdev->iommu_bitmap = NULL; | |
| 492 | +free_dma_table: | |
| 490 | 493 | dma_free_cpu_table(zdev->dma_table); |
| 491 | −out_clean: | |
| 494 | + zdev->dma_table = NULL; | |
| 495 | +out: | |
| 492 | 496 | return rc; |
| 493 | 497 | } |
| 494 | 498 | |
| @@ -24,7 +24,6 @@ CONFIG_INET_AH=y · 23 unmodified lines | ||
| 24 | 24 | CONFIG_INET_ESP=y |
| 25 | 25 | CONFIG_INET_IPCOMP=y |
| 26 | 26 | # CONFIG_INET_LRO is not set |
| 27 | −CONFIG_IPV6_PRIVACY=y | |
| 28 | 27 | CONFIG_INET6_AH=m |
| 29 | 28 | CONFIG_INET6_ESP=m |
| 30 | 29 | CONFIG_INET6_IPCOMP=m |
| @@ -48,7 +48,6 @@ CONFIG_SYN_COOKIES=y · 47 unmodified lines | ||
| 48 | 48 | CONFIG_INET_AH=y |
| 49 | 49 | CONFIG_INET_ESP=y |
| 50 | 50 | CONFIG_INET_IPCOMP=y |
| 51 | −CONFIG_IPV6_PRIVACY=y | |
| 52 | 51 | CONFIG_IPV6_ROUTER_PREF=y |
| 53 | 52 | CONFIG_IPV6_ROUTE_INFO=y |
| 54 | 53 | CONFIG_IPV6_OPTIMISTIC_DAD=y |
| @@ -48,6 +48,7 @@ · 47 unmodified lines | ||
| 48 | 48 | #define SUN4V_CHIP_SPARC_M6 0x06 |
| 49 | 49 | #define SUN4V_CHIP_SPARC_M7 0x07 |
| 50 | 50 | #define SUN4V_CHIP_SPARC64X 0x8a |
| 51 | +#define SUN4V_CHIP_SPARC_SN 0x8b | |
| 51 | 52 | #define SUN4V_CHIP_UNKNOWN 0xff |
| 52 | 53 | |
| 53 | 54 | #ifndef __ASSEMBLY__ |
| @@ -423,8 +423,10 @@ · 422 unmodified lines | ||
| 423 | 423 | #define __NR_setsockopt 355 |
| 424 | 424 | #define __NR_mlock2 356 |
| 425 | 425 | #define __NR_copy_file_range 357 |
| 426 | +#define __NR_preadv2 358 | |
| 427 | +#define __NR_pwritev2 359 | |
| 426 | 428 | |
| 427 | −#define NR_syscalls 358 | |
| 429 | +#define NR_syscalls 360 | |
| 428 | 430 | |
| 429 | 431 | /* Bitmask values returned from kern_features system call. */ |
| 430 | 432 | #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 |
| @@ -214,8 +214,7 @@ do_dcpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */ · 213 unmodified lines | ||
| 214 | 214 | subcc %g1, %g2, %g1 ! Next cacheline |
| 215 | 215 | bge,pt %icc, 1b |
| 216 | 216 | nop |
| 217 | − ba,pt %xcc, dcpe_icpe_tl1_common | |
| 218 | − nop | |
| 217 | + ba,a,pt %xcc, dcpe_icpe_tl1_common | |
| 219 | 218 | |
| 220 | 219 | do_dcpe_tl1_fatal: |
| 221 | 220 | sethi %hi(1f), %g7 |
| @@ -224,8 +223,7 @@ do_dcpe_tl1_fatal: · 2 unmodified lines | ||
| 224 | 223 | mov 0x2, %o0 |
| 225 | 224 | call cheetah_plus_parity_error |
| 226 | 225 | add %sp, PTREGS_OFF, %o1 |
| 227 | − ba,pt %xcc, rtrap | |
| 228 | − nop | |
| 226 | + ba,a,pt %xcc, rtrap | |
| 229 | 227 | .size do_dcpe_tl1,.-do_dcpe_tl1 |
| 230 | 228 | |
| 231 | 229 | .globl do_icpe_tl1 |
| @@ -259,8 +257,7 @@ do_icpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */ · 27 unmodified lines | ||
| 259 | 257 | subcc %g1, %g2, %g1 |
| 260 | 258 | bge,pt %icc, 1b |
| 261 | 259 | nop |
| 262 | − ba,pt %xcc, dcpe_icpe_tl1_common | |
| 263 | − nop | |
| 260 | + ba,a,pt %xcc, dcpe_icpe_tl1_common | |
| 264 | 261 | |
| 265 | 262 | do_icpe_tl1_fatal: |
| 266 | 263 | sethi %hi(1f), %g7 |
| @@ -269,8 +266,7 @@ do_icpe_tl1_fatal: · 2 unmodified lines | ||
| 269 | 266 | mov 0x3, %o0 |
| 270 | 267 | call cheetah_plus_parity_error |
| 271 | 268 | add %sp, PTREGS_OFF, %o1 |
| 272 | − ba,pt %xcc, rtrap | |
| 273 | − nop | |
| 269 | + ba,a,pt %xcc, rtrap | |
| 274 | 270 | .size do_icpe_tl1,.-do_icpe_tl1 |
| 275 | 271 | |
| 276 | 272 | .type dcpe_icpe_tl1_common,#function |
| @@ -456,7 +452,7 @@ __cheetah_log_error: · 179 unmodified lines | ||
| 456 | 452 | cmp %g2, 0x63 |
| 457 | 453 | be c_cee |
| 458 | 454 | nop |
| 459 | − ba,pt %xcc, c_deferred | |
| 455 | + ba,a,pt %xcc, c_deferred | |
| 460 | 456 | .size __cheetah_log_error,.-__cheetah_log_error |
| 461 | 457 | |
| 462 | 458 | /* Cheetah FECC trap handling, we get here from tl{0,1}_fecc |
| @@ -506,6 +506,12 @@ static void __init sun4v_cpu_probe(void) · 505 unmodified lines | ||
| 506 | 506 | sparc_pmu_type = "sparc-m7"; |
| 507 | 507 | break; |
| 508 | 508 | |
| 509 | + case SUN4V_CHIP_SPARC_SN: | |
| 510 | + sparc_cpu_type = "SPARC-SN"; | |
| 511 | + sparc_fpu_type = "SPARC-SN integrated FPU"; | |
| 512 | + sparc_pmu_type = "sparc-sn"; | |
| 513 | + break; | |
| 514 | + | |
| 509 | 515 | case SUN4V_CHIP_SPARC64X: |
| 510 | 516 | sparc_cpu_type = "SPARC64-X"; |
| 511 | 517 | sparc_fpu_type = "SPARC64-X integrated FPU"; |
| @@ -328,6 +328,7 @@ static int iterate_cpu(struct cpuinfo_tree *t, unsigned int root_index) · 327 unmodified lines | ||
| 328 | 328 | case SUN4V_CHIP_NIAGARA5: |
| 329 | 329 | case SUN4V_CHIP_SPARC_M6: |
| 330 | 330 | case SUN4V_CHIP_SPARC_M7: |
| 331 | + case SUN4V_CHIP_SPARC_SN: | |
| 331 | 332 | case SUN4V_CHIP_SPARC64X: |
| 332 | 333 | rover_inc_table = niagara_iterate_method; |
| 333 | 334 | break; |
| @@ -100,8 +100,8 @@ do_fpdis: · 99 unmodified lines | ||
| 100 | 100 | fmuld %f0, %f2, %f26 |
| 101 | 101 | faddd %f0, %f2, %f28 |
| 102 | 102 | fmuld %f0, %f2, %f30 |
| 103 | − b,pt %xcc, fpdis_exit | |
| 104 | − nop | |
| 103 | + ba,a,pt %xcc, fpdis_exit | |
| 104 | + | |
| 105 | 105 | 2: andcc %g5, FPRS_DU, %g0 |
| 106 | 106 | bne,pt %icc, 3f |
| 107 | 107 | fzero %f32 |
| @@ -144,8 +144,8 @@ do_fpdis: · 36 unmodified lines | ||
| 144 | 144 | fmuld %f32, %f34, %f58 |
| 145 | 145 | faddd %f32, %f34, %f60 |
| 146 | 146 | fmuld %f32, %f34, %f62 |
| 147 | − ba,pt %xcc, fpdis_exit | |
| 148 | − nop | |
| 147 | + ba,a,pt %xcc, fpdis_exit | |
| 148 | + | |
| 149 | 149 | 3: mov SECONDARY_CONTEXT, %g3 |
| 150 | 150 | add %g6, TI_FPREGS, %g1 |
| 151 | 151 | |
| @@ -197,8 +197,7 @@ fpdis_exit2: · 45 unmodified lines | ||
| 197 | 197 | fp_other_bounce: |
| 198 | 198 | call do_fpother |
| 199 | 199 | add %sp, PTREGS_OFF, %o0 |
| 200 | − ba,pt %xcc, rtrap | |
| 201 | − nop | |
| 200 | + ba,a,pt %xcc, rtrap | |
| 202 | 201 | .size fp_other_bounce,.-fp_other_bounce |
| 203 | 202 | |
| 204 | 203 | .align 32 |
| @@ -414,6 +414,8 @@ sun4v_chip_type: · 413 unmodified lines | ||
| 414 | 414 | cmp %g2, 'T' |
| 415 | 415 | be,pt %xcc, 70f |
| 416 | 416 | cmp %g2, 'M' |
| 417 | + be,pt %xcc, 70f | |
| 418 | + cmp %g2, 'S' | |
| 417 | 419 | bne,pn %xcc, 49f |
| 418 | 420 | nop |
| 419 | 421 | |
| @@ -433,6 +435,9 @@ sun4v_chip_type: · 13 unmodified lines | ||
| 433 | 435 | cmp %g2, '7' |
| 434 | 436 | be,pt %xcc, 5f |
| 435 | 437 | mov SUN4V_CHIP_SPARC_M7, %g4 |
| 438 | + cmp %g2, 'N' | |
| 439 | + be,pt %xcc, 5f | |
| 440 | + mov SUN4V_CHIP_SPARC_SN, %g4 | |
| 436 | 441 | ba,pt %xcc, 49f |
| 437 | 442 | nop |
| 438 | 443 | |
| @@ -461,9 +466,8 @@ sun4v_chip_type: · 22 unmodified lines | ||
| 461 | 466 | subcc %g3, 1, %g3 |
| 462 | 467 | bne,pt %xcc, 41b |
| 463 | 468 | add %g1, 1, %g1 |
| 464 | − mov SUN4V_CHIP_SPARC64X, %g4 | |
| 465 | 469 | ba,pt %xcc, 5f |
| 466 | − nop | |
| 470 | + mov SUN4V_CHIP_SPARC64X, %g4 | |
| 467 | 471 | |
| 468 | 472 | 49: |
| 469 | 473 | mov SUN4V_CHIP_UNKNOWN, %g4 |
| @@ -548,8 +552,7 @@ sun4u_init: · 78 unmodified lines | ||
| 548 | 552 | stxa %g0, [%g7] ASI_DMMU |
| 549 | 553 | membar #Sync |
| 550 | 554 | |
| 551 | − ba,pt %xcc, sun4u_continue | |
| 552 | − nop | |
| 555 | + ba,a,pt %xcc, sun4u_continue | |
| 553 | 556 | |
| 554 | 557 | sun4v_init: |
| 555 | 558 | /* Set ctx 0 */ |
| @@ -560,14 +563,12 @@ sun4v_init: · 4 unmodified lines | ||
| 560 | 563 | mov SECONDARY_CONTEXT, %g7 |
| 561 | 564 | stxa %g0, [%g7] ASI_MMU |
| 562 | 565 | membar #Sync |
| 563 | − ba,pt %xcc, niagara_tlb_fixup | |
| 564 | − nop | |
| 566 | + ba,a,pt %xcc, niagara_tlb_fixup | |
| 565 | 567 | |
| 566 | 568 | sun4u_continue: |
| 567 | 569 | BRANCH_IF_ANY_CHEETAH(g1, g7, cheetah_tlb_fixup) |
| 568 | 570 | |
| 569 | − ba,pt %xcc, spitfire_tlb_fixup | |
| 570 | − nop | |
| 571 | + ba,a,pt %xcc, spitfire_tlb_fixup | |
| 571 | 572 | |
| 572 | 573 | niagara_tlb_fixup: |
| 573 | 574 | mov 3, %g2 /* Set TLB type to hypervisor. */ |
| @@ -595,6 +596,9 @@ niagara_tlb_fixup: · 21 unmodified lines | ||
| 595 | 596 | be,pt %xcc, niagara4_patch |
| 596 | 597 | nop |
| 597 | 598 | cmp %g1, SUN4V_CHIP_SPARC_M7 |
| 599 | + be,pt %xcc, niagara4_patch | |
| 600 | + nop | |
| 601 | + cmp %g1, SUN4V_CHIP_SPARC_SN | |
| 598 | 602 | be,pt %xcc, niagara4_patch |
| 599 | 603 | nop |
| 600 | 604 | |
| @@ -639,8 +643,7 @@ niagara_patch: · 38 unmodified lines | ||
| 639 | 643 | call hypervisor_patch_cachetlbops |
| 640 | 644 | nop |
| 641 | 645 | |
| 642 | − ba,pt %xcc, tlb_fixup_done | |
| 643 | − nop | |
| 646 | + ba,a,pt %xcc, tlb_fixup_done | |
| 644 | 647 | |
| 645 | 648 | cheetah_tlb_fixup: |
| 646 | 649 | mov 2, %g2 /* Set TLB type to cheetah+. */ |
| @@ -659,8 +662,7 @@ cheetah_tlb_fixup: · 12 unmodified lines | ||
| 659 | 662 | call cheetah_patch_cachetlbops |
| 660 | 663 | nop |
| 661 | 664 | |
| 662 | − ba,pt %xcc, tlb_fixup_done | |
| 663 | − nop | |
| 665 | + ba,a,pt %xcc, tlb_fixup_done | |
| 664 | 666 | |
| 665 | 667 | spitfire_tlb_fixup: |
| 666 | 668 | /* Set TLB type to spitfire. */ |
| @@ -774,8 +776,7 @@ setup_trap_table: · 107 unmodified lines | ||
| 774 | 776 | call %o1 |
| 775 | 777 | add %sp, (2047 + 128), %o0 |
| 776 | 778 | |
| 777 | − ba,pt %xcc, 2f | |
| 778 | − nop | |
| 779 | + ba,a,pt %xcc, 2f | |
| 779 | 780 | |
| 780 | 781 | 1: sethi %hi(sparc64_ttable_tl0), %o0 |
| 781 | 782 | set prom_set_trap_table_name, %g2 |
| @@ -814,8 +815,7 @@ setup_trap_table: · 32 unmodified lines | ||
| 814 | 815 | |
| 815 | 816 | BRANCH_IF_ANY_CHEETAH(o2, o3, 1f) |
| 816 | 817 | |
| 817 | − ba,pt %xcc, 2f | |
| 818 | − nop | |
| 818 | + ba,a,pt %xcc, 2f | |
| 819 | 819 | |
| 820 | 820 | /* Disable STICK_INT interrupts. */ |
| 821 | 821 | 1: |
| @@ -18,8 +18,7 @@ __do_privact: · 17 unmodified lines | ||
| 18 | 18 | 109: or %g7, %lo(109b), %g7 |
| 19 | 19 | call do_privact |
| 20 | 20 | add %sp, PTREGS_OFF, %o0 |
| 21 | − ba,pt %xcc, rtrap | |
| 22 | − nop | |
| 21 | + ba,a,pt %xcc, rtrap | |
| 23 | 22 | .size __do_privact,.-__do_privact |
| 24 | 23 | |
| 25 | 24 | .type do_mna,#function |
| @@ -46,8 +45,7 @@ do_mna: · 20 unmodified lines | ||
| 46 | 45 | mov %l5, %o2 |
| 47 | 46 | call mem_address_unaligned |
| 48 | 47 | add %sp, PTREGS_OFF, %o0 |
| 49 | − ba,pt %xcc, rtrap | |
| 50 | − nop | |
| 48 | + ba,a,pt %xcc, rtrap | |
| 51 | 49 | .size do_mna,.-do_mna |
| 52 | 50 | |
| 53 | 51 | .type do_lddfmna,#function |
| @@ -65,8 +63,7 @@ do_lddfmna: · 11 unmodified lines | ||
| 65 | 63 | mov %l5, %o2 |
| 66 | 64 | call handle_lddfmna |
| 67 | 65 | add %sp, PTREGS_OFF, %o0 |
| 68 | − ba,pt %xcc, rtrap | |
| 69 | − nop | |
| 66 | + ba,a,pt %xcc, rtrap | |
| 70 | 67 | .size do_lddfmna,.-do_lddfmna |
| 71 | 68 | |
| 72 | 69 | .type do_stdfmna,#function |
| @@ -84,8 +81,7 @@ do_stdfmna: · 11 unmodified lines | ||
| 84 | 81 | mov %l5, %o2 |
| 85 | 82 | call handle_stdfmna |
| 86 | 83 | add %sp, PTREGS_OFF, %o0 |
| 87 | − ba,pt %xcc, rtrap | |
| 88 | − nop | |
| 84 | + ba,a,pt %xcc, rtrap | |
| 89 | 85 | .size do_stdfmna,.-do_stdfmna |
| 90 | 86 | |
| 91 | 87 | .type breakpoint_trap,#function |
| @@ -245,6 +245,18 @@ static void pci_parse_of_addrs(struct platform_device *op, · 244 unmodified lines | ||
| 245 | 245 | } |
| 246 | 246 | } |
| 247 | 247 | |
| 248 | +static void pci_init_dev_archdata(struct dev_archdata *sd, void *iommu, | |
| 249 | + void *stc, void *host_controller, | |
| 250 | + struct platform_device *op, | |
| 251 | + int numa_node) | |
| 252 | +{ | |
| 253 | + sd->iommu = iommu; | |
| 254 | + sd->stc = stc; | |
| 255 | + sd->host_controller = host_controller; | |
| 256 | + sd->op = op; | |
| 257 | + sd->numa_node = numa_node; | |
| 258 | +} | |
| 259 | + | |
| 248 | 260 | static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, |
| 249 | 261 | struct device_node *node, |
| 250 | 262 | struct pci_bus *bus, int devfn) |
| @@ -259,13 +271,10 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, · 8 unmodified lines | ||
| 259 | 271 | if (!dev) |
| 260 | 272 | return NULL; |
| 261 | 273 | |
| 274 | + op = of_find_device_by_node(node); | |
| 262 | 275 | sd = &dev->dev.archdata; |
| 263 | − sd->iommu = pbm->iommu; | |
| 264 | − sd->stc = &pbm->stc; | |
| 265 | − sd->host_controller = pbm; | |
| 266 | − sd->op = op = of_find_device_by_node(node); | |
| 267 | − sd->numa_node = pbm->numa_node; | |
| 268 | − | |
| 276 | + pci_init_dev_archdata(sd, pbm->iommu, &pbm->stc, pbm, op, | |
| 277 | + pbm->numa_node); | |
| 269 | 278 | sd = &op->dev.archdata; |
| 270 | 279 | sd->iommu = pbm->iommu; |
| 271 | 280 | sd->stc = &pbm->stc; |
| @@ -994,6 +1003,27 @@ void pcibios_set_master(struct pci_dev *dev) · 722 unmodified lines | ||
| 994 | 1003 | /* No special bus mastering setup handling */ |
| 995 | 1004 | } |
| 996 | 1005 | |
| 1006 | +#ifdef CONFIG_PCI_IOV | |
| 1007 | +int pcibios_add_device(struct pci_dev *dev) | |
| 1008 | +{ | |
| 1009 | + struct pci_dev *pdev; | |
| 1010 | + | |
| 1011 | + /* Add sriov arch specific initialization here. | |
| 1012 | + * Copy dev_archdata from PF to VF | |
| 1013 | + */ | |
| 1014 | + if (dev->is_virtfn) { | |
| 1015 | + struct dev_archdata *psd; | |
| 1016 | + | |
| 1017 | + pdev = dev->physfn; | |
| 1018 | + psd = &pdev->dev.archdata; | |
| 1019 | + pci_init_dev_archdata(&dev->dev.archdata, psd->iommu, | |
| 1020 | + psd->stc, psd->host_controller, NULL, | |
| 1021 | + psd->numa_node); | |
| 1022 | + } | |
| 1023 | + return 0; | |
| 1024 | +} | |
| 1025 | +#endif /* CONFIG_PCI_IOV */ | |
| 1026 | + | |
| 997 | 1027 | static int __init pcibios_init(void) |
| 998 | 1028 | { |
| 999 | 1029 | pci_dfl_cache_line_size = 64 >> 2; |
| @@ -285,7 +285,8 @@ static void __init sun4v_patch(void) · 284 unmodified lines | ||
| 285 | 285 | |
| 286 | 286 | sun4v_patch_2insn_range(&__sun4v_2insn_patch, |
| 287 | 287 | &__sun4v_2insn_patch_end); |
| 288 | − if (sun4v_chip_type == SUN4V_CHIP_SPARC_M7) | |
| 288 | + if (sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || | |
| 289 | + sun4v_chip_type == SUN4V_CHIP_SPARC_SN) | |
| 289 | 290 | sun_m7_patch_2insn_range(&__sun_m7_2insn_patch, |
| 290 | 291 | &__sun_m7_2insn_patch_end); |
| 291 | 292 | |
| @@ -524,6 +525,7 @@ static void __init init_sparc64_elf_hwcap(void) · 232 unmodified lines | ||
| 524 | 525 | sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || |
| 525 | 526 | sun4v_chip_type == SUN4V_CHIP_SPARC_M6 || |
| 526 | 527 | sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || |
| 528 | + sun4v_chip_type == SUN4V_CHIP_SPARC_SN || | |
| 527 | 529 | sun4v_chip_type == SUN4V_CHIP_SPARC64X) |
| 528 | 530 | cap |= HWCAP_SPARC_BLKINIT; |
| 529 | 531 | if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || |
| @@ -532,6 +534,7 @@ static void __init init_sparc64_elf_hwcap(void) · 2 unmodified lines | ||
| 532 | 534 | sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || |
| 533 | 535 | sun4v_chip_type == SUN4V_CHIP_SPARC_M6 || |
| 534 | 536 | sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || |
| 537 | + sun4v_chip_type == SUN4V_CHIP_SPARC_SN || | |
| 535 | 538 | sun4v_chip_type == SUN4V_CHIP_SPARC64X) |
| 536 | 539 | cap |= HWCAP_SPARC_N2; |
| 537 | 540 | } |
| @@ -561,6 +564,7 @@ static void __init init_sparc64_elf_hwcap(void) · 23 unmodified lines | ||
| 561 | 564 | sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || |
| 562 | 565 | sun4v_chip_type == SUN4V_CHIP_SPARC_M6 || |
| 563 | 566 | sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || |
| 567 | + sun4v_chip_type == SUN4V_CHIP_SPARC_SN || | |
| 564 | 568 | sun4v_chip_type == SUN4V_CHIP_SPARC64X) |
| 565 | 569 | cap |= (AV_SPARC_VIS | AV_SPARC_VIS2 | |
| 566 | 570 | AV_SPARC_ASI_BLK_INIT | |
| @@ -570,6 +574,7 @@ static void __init init_sparc64_elf_hwcap(void) · 3 unmodified lines | ||
| 570 | 574 | sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || |
| 571 | 575 | sun4v_chip_type == SUN4V_CHIP_SPARC_M6 || |
| 572 | 576 | sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || |
| 577 | + sun4v_chip_type == SUN4V_CHIP_SPARC_SN || | |
| 573 | 578 | sun4v_chip_type == SUN4V_CHIP_SPARC64X) |
| 574 | 579 | cap |= (AV_SPARC_VIS3 | AV_SPARC_HPC | |
| 575 | 580 | AV_SPARC_FMAF); |
| @@ -85,8 +85,7 @@ __spitfire_cee_trap_continue: · 84 unmodified lines | ||
| 85 | 85 | ba,pt %xcc, etraptl1 |
| 86 | 86 | rd %pc, %g7 |
| 87 | 87 | |
| 88 | − ba,pt %xcc, 2f | |
| 89 | − nop | |
| 88 | + ba,a,pt %xcc, 2f | |
| 90 | 89 | |
| 91 | 90 | 1: ba,pt %xcc, etrap_irq |
| 92 | 91 | rd %pc, %g7 |
| @@ -100,8 +99,7 @@ __spitfire_cee_trap_continue: · 7 unmodified lines | ||
| 100 | 99 | mov %l5, %o2 |
| 101 | 100 | call spitfire_access_error |
| 102 | 101 | add %sp, PTREGS_OFF, %o0 |
| 103 | − ba,pt %xcc, rtrap | |
| 104 | − nop | |
| 102 | + ba,a,pt %xcc, rtrap | |
| 105 | 103 | .size __spitfire_access_error,.-__spitfire_access_error |
| 106 | 104 | |
| 107 | 105 | /* This is the trap handler entry point for ECC correctable |
| @@ -179,8 +177,7 @@ __spitfire_data_access_exception_tl1: · 71 unmodified lines | ||
| 179 | 177 | mov %l5, %o2 |
| 180 | 178 | call spitfire_data_access_exception_tl1 |
| 181 | 179 | add %sp, PTREGS_OFF, %o0 |
| 182 | − ba,pt %xcc, rtrap | |
| 183 | − nop | |
| 180 | + ba,a,pt %xcc, rtrap | |
| 184 | 181 | .size __spitfire_data_access_exception_tl1,.-__spitfire_data_access_exception_tl1 |
| 185 | 182 | |
| 186 | 183 | .type __spitfire_data_access_exception,#function |
| @@ -200,8 +197,7 @@ __spitfire_data_access_exception: · 13 unmodified lines | ||
| 200 | 197 | mov %l5, %o2 |
| 201 | 198 | call spitfire_data_access_exception |
| 202 | 199 | add %sp, PTREGS_OFF, %o0 |
| 203 | − ba,pt %xcc, rtrap | |
| 204 | − nop | |
| 200 | + ba,a,pt %xcc, rtrap | |
| 205 | 201 | .size __spitfire_data_access_exception,.-__spitfire_data_access_exception |
| 206 | 202 | |
| 207 | 203 | .type __spitfire_insn_access_exception_tl1,#function |
| @@ -220,8 +216,7 @@ __spitfire_insn_access_exception_tl1: · 12 unmodified lines | ||
| 220 | 216 | mov %l5, %o2 |
| 221 | 217 | call spitfire_insn_access_exception_tl1 |
| 222 | 218 | add %sp, PTREGS_OFF, %o0 |
| 223 | − ba,pt %xcc, rtrap | |
| 224 | − nop | |
| 219 | + ba,a,pt %xcc, rtrap | |
| 225 | 220 | .size __spitfire_insn_access_exception_tl1,.-__spitfire_insn_access_exception_tl1 |
| 226 | 221 | |
| 227 | 222 | .type __spitfire_insn_access_exception,#function |
| @@ -240,6 +235,5 @@ __spitfire_insn_access_exception: · 12 unmodified lines | ||
| 240 | 235 | mov %l5, %o2 |
| 241 | 236 | call spitfire_insn_access_exception |
| 242 | 237 | add %sp, PTREGS_OFF, %o0 |
| 243 | − ba,pt %xcc, rtrap | |
| 244 | − nop | |
| 238 | + ba,a,pt %xcc, rtrap | |
| 245 | 239 | .size __spitfire_insn_access_exception,.-__spitfire_insn_access_exception |
| @@ -88,4 +88,4 @@ sys_call_table: · 87 unmodified lines | ||
| 88 | 88 | /*340*/ .long sys_ni_syscall, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr |
| 89 | 89 | /*345*/ .long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf |
| 90 | 90 | /*350*/ .long sys_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen |
| 91 | −/*355*/ .long sys_setsockopt, sys_mlock2, sys_copy_file_range | |
| 91 | +/*355*/ .long sys_setsockopt, sys_mlock2, sys_copy_file_range, sys_preadv2, sys_pwritev2 | |
| @@ -89,7 +89,7 @@ sys_call_table32: · 88 unmodified lines | ||
| 89 | 89 | /*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr |
| 90 | 90 | .word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf |
| 91 | 91 | /*350*/ .word sys32_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen |
| 92 | − .word compat_sys_setsockopt, sys_mlock2, sys_copy_file_range | |
| 92 | + .word compat_sys_setsockopt, sys_mlock2, sys_copy_file_range, compat_sys_preadv2, compat_sys_pwritev2 | |
| 93 | 93 | |
| 94 | 94 | #endif /* CONFIG_COMPAT */ |
| 95 | 95 | |
| @@ -170,4 +170,4 @@ sys_call_table: · 74 unmodified lines | ||
| 170 | 170 | /*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr |
| 171 | 171 | .word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf |
| 172 | 172 | /*350*/ .word sys64_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen |
| 173 | − .word sys_setsockopt, sys_mlock2, sys_copy_file_range | |
| 173 | + .word sys_setsockopt, sys_mlock2, sys_copy_file_range, sys_preadv2, sys_pwritev2 | |
| @@ -11,8 +11,7 @@ utrap_trap: /* %g3=handler,%g4=level */ · 10 unmodified lines | ||
| 11 | 11 | mov %l4, %o1 |
| 12 | 12 | call bad_trap |
| 13 | 13 | add %sp, PTREGS_OFF, %o0 |
| 14 | − ba,pt %xcc, rtrap | |
| 15 | − nop | |
| 14 | + ba,a,pt %xcc, rtrap | |
| 16 | 15 | |
| 17 | 16 | invoke_utrap: |
| 18 | 17 | sllx %g3, 3, %g3 |
| @@ -45,6 +45,14 @@ static const struct vio_device_id *vio_match_device( · 44 unmodified lines | ||
| 45 | 45 | return NULL; |
| 46 | 46 | } |
| 47 | 47 | |
| 48 | +static int vio_hotplug(struct device *dev, struct kobj_uevent_env *env) | |
| 49 | +{ | |
| 50 | + const struct vio_dev *vio_dev = to_vio_dev(dev); | |
| 51 | + | |
| 52 | + add_uevent_var(env, "MODALIAS=vio:T%sS%s", vio_dev->type, vio_dev->compat); | |
| 53 | + return 0; | |
| 54 | +} | |
| 55 | + | |
| 48 | 56 | static int vio_bus_match(struct device *dev, struct device_driver *drv) |
| 49 | 57 | { |
| 50 | 58 | struct vio_dev *vio_dev = to_vio_dev(dev); |
| @@ -105,15 +113,25 @@ static ssize_t type_show(struct device *dev, · 54 unmodified lines | ||
| 105 | 113 | return sprintf(buf, "%s\n", vdev->type); |
| 106 | 114 | } |
| 107 | 115 | |
| 116 | +static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, | |
| 117 | + char *buf) | |
| 118 | +{ | |
| 119 | + const struct vio_dev *vdev = to_vio_dev(dev); | |
| 120 | + | |
| 121 | + return sprintf(buf, "vio:T%sS%s\n", vdev->type, vdev->compat); | |
| 122 | +} | |
| 123 | + | |
| 108 | 124 | static struct device_attribute vio_dev_attrs[] = { |
| 109 | 125 | __ATTR_RO(devspec), |
| 110 | 126 | __ATTR_RO(type), |
| 127 | + __ATTR_RO(modalias), | |
| 111 | 128 | __ATTR_NULL |
| 112 | 129 | }; |
| 113 | 130 | |
| 114 | 131 | static struct bus_type vio_bus_type = { |
| 115 | 132 | .name = "vio", |
| 116 | 133 | .dev_attrs = vio_dev_attrs, |
| 134 | + .uevent = vio_hotplug, | |
| 117 | 135 | .match = vio_bus_match, |
| 118 | 136 | .probe = vio_device_probe, |
| 119 | 137 | .remove = vio_device_remove, |
| @@ -33,6 +33,10 @@ ENTRY(_start) · 32 unmodified lines | ||
| 33 | 33 | jiffies = jiffies_64; |
| 34 | 34 | #endif |
| 35 | 35 | |
| 36 | +#ifdef CONFIG_SPARC64 | |
| 37 | +ASSERT((swapper_tsb == 0x0000000000408000), "Error: sparc64 early assembler too large") | |
| 38 | +#endif | |
| 39 | + | |
| 36 | 40 | SECTIONS |
| 37 | 41 | { |
| 38 | 42 | #ifdef CONFIG_SPARC64 |
| @@ -32,8 +32,7 @@ fill_fixup: · 31 unmodified lines | ||
| 32 | 32 | rd %pc, %g7 |
| 33 | 33 | call do_sparc64_fault |
| 34 | 34 | add %sp, PTREGS_OFF, %o0 |
| 35 | − ba,pt %xcc, rtrap | |
| 36 | − nop | |
| 35 | + ba,a,pt %xcc, rtrap | |
| 37 | 36 | |
| 38 | 37 | /* Be very careful about usage of the trap globals here. |
| 39 | 38 | * You cannot touch %g5 as that has the fault information. |
| @@ -1769,6 +1769,7 @@ static void __init setup_page_offset(void) · 1768 unmodified lines | ||
| 1769 | 1769 | max_phys_bits = 47; |
| 1770 | 1770 | break; |
| 1771 | 1771 | case SUN4V_CHIP_SPARC_M7: |
| 1772 | + case SUN4V_CHIP_SPARC_SN: | |
| 1772 | 1773 | default: |
| 1773 | 1774 | /* M7 and later support 52-bit virtual addresses. */ |
| 1774 | 1775 | sparc64_va_hole_top = 0xfff8000000000000UL; |
| @@ -1986,6 +1987,7 @@ static void __init sun4v_linear_pte_xor_finalize(void) · 211 unmodified lines | ||
| 1986 | 1987 | */ |
| 1987 | 1988 | switch (sun4v_chip_type) { |
| 1988 | 1989 | case SUN4V_CHIP_SPARC_M7: |
| 1990 | + case SUN4V_CHIP_SPARC_SN: | |
| 1989 | 1991 | pagecv_flag = 0x00; |
| 1990 | 1992 | break; |
| 1991 | 1993 | default: |
| @@ -2138,6 +2140,7 @@ void __init paging_init(void) · 146 unmodified lines | ||
| 2138 | 2140 | */ |
| 2139 | 2141 | switch (sun4v_chip_type) { |
| 2140 | 2142 | case SUN4V_CHIP_SPARC_M7: |
| 2143 | + case SUN4V_CHIP_SPARC_SN: | |
| 2141 | 2144 | page_cache4v_flag = _PAGE_CP_4V; |
| 2142 | 2145 | break; |
| 2143 | 2146 | default: |
| @@ -115,7 +115,7 @@ static __initconst const u64 amd_hw_cache_event_ids · 114 unmodified lines | ||
| 115 | 115 | /* |
| 116 | 116 | * AMD Performance Monitor K7 and later. |
| 117 | 117 | */ |
| 118 | −static const u64 amd_perfmon_event_map[] = | |
| 118 | +static const u64 amd_perfmon_event_map[PERF_COUNT_HW_MAX] = | |
| 119 | 119 | { |
| 120 | 120 | [PERF_COUNT_HW_CPU_CYCLES] = 0x0076, |
| 121 | 121 | [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, |
| @@ -474,6 +474,7 @@ static __init int _init_perf_amd_iommu( · 473 unmodified lines | ||
| 474 | 474 | |
| 475 | 475 | static struct perf_amd_iommu __perf_iommu = { |
| 476 | 476 | .pmu = { |
| 477 | + .task_ctx_nr = perf_invalid_context, | |
| 477 | 478 | .event_init = perf_iommu_event_init, |
| 478 | 479 | .add = perf_iommu_add, |
| 479 | 480 | .del = perf_iommu_del, |
| @@ -3637,8 +3637,11 @@ __init int intel_pmu_init(void) · 3636 unmodified lines | ||
| 3637 | 3637 | pr_cont("Knights Landing events, "); |
| 3638 | 3638 | break; |
| 3639 | 3639 | |
| 3640 | + case 142: /* 14nm Kabylake Mobile */ | |
| 3641 | + case 158: /* 14nm Kabylake Desktop */ | |
| 3640 | 3642 | case 78: /* 14nm Skylake Mobile */ |
| 3641 | 3643 | case 94: /* 14nm Skylake Desktop */ |
| 3644 | + case 85: /* 14nm Skylake Server */ | |
| 3642 | 3645 | x86_pmu.late_ack = true; |
| 3643 | 3646 | memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids)); |
| 3644 | 3647 | memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); |
| @@ -63,7 +63,7 @@ static enum { · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | #define LBR_PLM (LBR_KERNEL | LBR_USER) |
| 65 | 65 | |
| 66 | −#define LBR_SEL_MASK 0x1ff /* valid bits in LBR_SELECT */ | |
| 66 | +#define LBR_SEL_MASK 0x3ff /* valid bits in LBR_SELECT */ | |
| 67 | 67 | #define LBR_NOT_SUPP -1 /* LBR filter not supported */ |
| 68 | 68 | #define LBR_IGN 0 /* ignored */ |
| 69 | 69 | |
| @@ -610,8 +610,10 @@ static int intel_pmu_setup_hw_lbr_filter(struct perf_event *event) · 540 unmodified lines | ||
| 610 | 610 | * The first 9 bits (LBR_SEL_MASK) in LBR_SELECT operate |
| 611 | 611 | * in suppress mode. So LBR_SELECT should be set to |
| 612 | 612 | * (~mask & LBR_SEL_MASK) | (mask & ~LBR_SEL_MASK) |
| 613 | + * But the 10th bit LBR_CALL_STACK does not operate | |
| 614 | + * in suppress mode. | |
| 613 | 615 | */ |
| 614 | − reg->config = mask ^ x86_pmu.lbr_sel_mask; | |
| 616 | + reg->config = mask ^ (x86_pmu.lbr_sel_mask & ~LBR_CALL_STACK); | |
| 615 | 617 | |
| 616 | 618 | if ((br_type & PERF_SAMPLE_BRANCH_NO_CYCLES) && |
| 617 | 619 | (br_type & PERF_SAMPLE_BRANCH_NO_FLAGS) && |
| @@ -136,9 +136,21 @@ static int __init pt_pmu_hw_init(void) · 135 unmodified lines | ||
| 136 | 136 | struct dev_ext_attribute *de_attrs; |
| 137 | 137 | struct attribute **attrs; |
| 138 | 138 | size_t size; |
| 139 | + u64 reg; | |
| 139 | 140 | int ret; |
| 140 | 141 | long i; |
| 141 | 142 | |
| 143 | + if (boot_cpu_has(X86_FEATURE_VMX)) { | |
| 144 | + /* | |
| 145 | + * Intel SDM, 36.5 "Tracing post-VMXON" says that | |
| 146 | + * "IA32_VMX_MISC[bit 14]" being 1 means PT can trace | |
| 147 | + * post-VMXON. | |
| 148 | + */ | |
| 149 | + rdmsrl(MSR_IA32_VMX_MISC, reg); | |
| 150 | + if (reg & BIT(14)) | |
| 151 | + pt_pmu.vmx = true; | |
| 152 | + } | |
| 153 | + | |
| 142 | 154 | attrs = NULL; |
| 143 | 155 | |
| 144 | 156 | for (i = 0; i < PT_CPUID_LEAVES; i++) { |
| @@ -269,20 +281,23 @@ static void pt_config(struct perf_event *event) · 124 unmodified lines | ||
| 269 | 281 | |
| 270 | 282 | reg |= (event->attr.config & PT_CONFIG_MASK); |
| 271 | 283 | |
| 284 | + event->hw.config = reg; | |
| 272 | 285 | wrmsrl(MSR_IA32_RTIT_CTL, reg); |
| 273 | 286 | } |
| 274 | 287 | |
| 275 | −static void pt_config_start(bool start) | |
| 288 | +static void pt_config_stop(struct perf_event *event) | |
| 276 | 289 | { |
| 277 | − u64 ctl; | |
| 290 | + u64 ctl = READ_ONCE(event->hw.config); | |
| 291 | + | |
| 292 | + /* may be already stopped by a PMI */ | |
| 293 | + if (!(ctl & RTIT_CTL_TRACEEN)) | |
| 294 | + return; | |
| 278 | 295 | |
| 279 | − rdmsrl(MSR_IA32_RTIT_CTL, ctl); | |
| 280 | − if (start) | |
| 281 | − ctl |= RTIT_CTL_TRACEEN; | |
| 282 | − else | |
| 283 | − ctl &= ~RTIT_CTL_TRACEEN; | |
| 296 | + ctl &= ~RTIT_CTL_TRACEEN; | |
| 284 | 297 | wrmsrl(MSR_IA32_RTIT_CTL, ctl); |
| 285 | 298 | |
| 299 | + WRITE_ONCE(event->hw.config, ctl); | |
| 300 | + | |
| 286 | 301 | /* |
| 287 | 302 | * A wrmsr that disables trace generation serializes other PT |
| 288 | 303 | * registers and causes all data packets to be written to memory, |
| @@ -291,8 +306,7 @@ static void pt_config_start(bool start) · 2 unmodified lines | ||
| 291 | 306 | * The below WMB, separating data store and aux_head store matches |
| 292 | 307 | * the consumer's RMB that separates aux_head load and data load. |
| 293 | 308 | */ |
| 294 | − if (!start) | |
| 295 | − wmb(); | |
| 309 | + wmb(); | |
| 296 | 310 | } |
| 297 | 311 | |
| 298 | 312 | static void pt_config_buffer(void *buf, unsigned int topa_idx, |
| @@ -942,11 +956,17 @@ void intel_pt_interrupt(void) · 643 unmodified lines | ||
| 942 | 956 | if (!ACCESS_ONCE(pt->handle_nmi)) |
| 943 | 957 | return; |
| 944 | 958 | |
| 945 | − pt_config_start(false); | |
| 959 | + /* | |
| 960 | + * If VMX is on and PT does not support it, don't touch anything. | |
| 961 | + */ | |
| 962 | + if (READ_ONCE(pt->vmx_on)) | |
| 963 | + return; | |
| 946 | 964 | |
| 947 | 965 | if (!event) |
| 948 | 966 | return; |
| 949 | 967 | |
| 968 | + pt_config_stop(event); | |
| 969 | + | |
| 950 | 970 | buf = perf_get_aux(&pt->handle); |
| 951 | 971 | if (!buf) |
| 952 | 972 | return; |
| @@ -983,6 +1003,35 @@ void intel_pt_interrupt(void) · 30 unmodified lines | ||
| 983 | 1003 | } |
| 984 | 1004 | } |
| 985 | 1005 | |
| 1006 | +void intel_pt_handle_vmx(int on) | |
| 1007 | +{ | |
| 1008 | + struct pt *pt = this_cpu_ptr(&pt_ctx); | |
| 1009 | + struct perf_event *event; | |
| 1010 | + unsigned long flags; | |
| 1011 | + | |
| 1012 | + /* PT plays nice with VMX, do nothing */ | |
| 1013 | + if (pt_pmu.vmx) | |
| 1014 | + return; | |
| 1015 | + | |
| 1016 | + /* | |
| 1017 | + * VMXON will clear RTIT_CTL.TraceEn; we need to make | |
| 1018 | + * sure to not try to set it while VMX is on. Disable | |
| 1019 | + * interrupts to avoid racing with pmu callbacks; | |
| 1020 | + * concurrent PMI should be handled fine. | |
| 1021 | + */ | |
| 1022 | + local_irq_save(flags); | |
| 1023 | + WRITE_ONCE(pt->vmx_on, on); | |
| 1024 | + | |
| 1025 | + if (on) { | |
| 1026 | + /* prevent pt_config_stop() from writing RTIT_CTL */ | |
| 1027 | + event = pt->handle.event; | |
| 1028 | + if (event) | |
| 1029 | + event->hw.config = 0; | |
| 1030 | + } | |
| 1031 | + local_irq_restore(flags); | |
| 1032 | +} | |
| 1033 | +EXPORT_SYMBOL_GPL(intel_pt_handle_vmx); | |
| 1034 | + | |
| 986 | 1035 | /* |
| 987 | 1036 | * PMU callbacks |
| 988 | 1037 | */ |
| @@ -992,6 +1041,9 @@ static void pt_event_start(struct perf_event *event, int mode) · 3 unmodified lines | ||
| 992 | 1041 | struct pt *pt = this_cpu_ptr(&pt_ctx); |
| 993 | 1042 | struct pt_buffer *buf = perf_get_aux(&pt->handle); |
| 994 | 1043 | |
| 1044 | + if (READ_ONCE(pt->vmx_on)) | |
| 1045 | + return; | |
| 1046 | + | |
| 995 | 1047 | if (!buf || pt_buffer_is_full(buf, pt)) { |
| 996 | 1048 | event->hw.state = PERF_HES_STOPPED; |
| 997 | 1049 | return; |
| @@ -1014,7 +1066,8 @@ static void pt_event_stop(struct perf_event *event, int mode) · 16 unmodified lines | ||
| 1014 | 1066 | * see comment in intel_pt_interrupt(). |
| 1015 | 1067 | */ |
| 1016 | 1068 | ACCESS_ONCE(pt->handle_nmi) = 0; |
| 1017 | − pt_config_start(false); | |
| 1069 | + | |
| 1070 | + pt_config_stop(event); | |
| 1018 | 1071 | |
| 1019 | 1072 | if (event->hw.state == PERF_HES_STOPPED) |
| 1020 | 1073 | return; |
| @@ -65,6 +65,7 @@ enum pt_capabilities { · 64 unmodified lines | ||
| 65 | 65 | struct pt_pmu { |
| 66 | 66 | struct pmu pmu; |
| 67 | 67 | u32 caps[PT_CPUID_REGS_NUM * PT_CPUID_LEAVES]; |
| 68 | + bool vmx; | |
| 68 | 69 | }; |
| 69 | 70 | |
| 70 | 71 | /** |
| @@ -107,10 +108,12 @@ struct pt_buffer { · 36 unmodified lines | ||
| 107 | 108 | * struct pt - per-cpu pt context |
| 108 | 109 | * @handle: perf output handle |
| 109 | 110 | * @handle_nmi: do handle PT PMI on this cpu, there's an active event |
| 111 | + * @vmx_on: 1 if VMX is ON on this cpu | |
| 110 | 112 | */ |
| 111 | 113 | struct pt { |
| 112 | 114 | struct perf_output_handle handle; |
| 113 | 115 | int handle_nmi; |
| 116 | + int vmx_on; | |
| 114 | 117 | }; |
| 115 | 118 | |
| 116 | 119 | #endif /* __INTEL_PT_H__ */ |
| @@ -718,6 +718,7 @@ static int __init rapl_pmu_init(void) · 717 unmodified lines | ||
| 718 | 718 | break; |
| 719 | 719 | case 60: /* Haswell */ |
| 720 | 720 | case 69: /* Haswell-Celeron */ |
| 721 | + case 70: /* Haswell GT3e */ | |
| 721 | 722 | case 61: /* Broadwell */ |
| 722 | 723 | case 71: /* Broadwell-H */ |
| 723 | 724 | rapl_cntr_mask = RAPL_IDX_HSW; |
| @@ -285,6 +285,10 @@ static inline void perf_events_lapic_init(void) { } · 284 unmodified lines | ||
| 285 | 285 | static inline void perf_check_microcode(void) { } |
| 286 | 286 | #endif |
| 287 | 287 | |
| 288 | +#ifdef CONFIG_CPU_SUP_INTEL | |
| 289 | + extern void intel_pt_handle_vmx(int on); | |
| 290 | +#endif | |
| 291 | + | |
| 288 | 292 | #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) |
| 289 | 293 | extern void amd_pmu_enable_virt(void); |
| 290 | 294 | extern void amd_pmu_disable_virt(void); |
| @@ -256,7 +256,8 @@ static void clear_irq_vector(int irq, struct apic_chip_data *data) · 255 unmodified lines | ||
| 256 | 256 | struct irq_desc *desc; |
| 257 | 257 | int cpu, vector; |
| 258 | 258 | |
| 259 | − BUG_ON(!data->cfg.vector); | |
| 259 | + if (!data->cfg.vector) | |
| 260 | + return; | |
| 260 | 261 | |
| 261 | 262 | vector = data->cfg.vector; |
| 262 | 263 | for_each_cpu_and(cpu, data->domain, cpu_online_mask) |
| @@ -891,9 +891,7 @@ void __init uv_system_init(void) · 890 unmodified lines | ||
| 891 | 891 | } |
| 892 | 892 | pr_info("UV: Found %s hub\n", hub); |
| 893 | 893 | |
| 894 | − /* We now only need to map the MMRs on UV1 */ | |
| 895 | − if (is_uv1_hub()) | |
| 896 | − map_low_mmrs(); | |
| 894 | + map_low_mmrs(); | |
| 897 | 895 | |
| 898 | 896 | m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR ); |
| 899 | 897 | m_val = m_n_config.s.m_skt; |
| @@ -389,12 +389,6 @@ default_entry: · 388 unmodified lines | ||
| 389 | 389 | /* Make changes effective */ |
| 390 | 390 | wrmsr |
| 391 | 391 | |
| 392 | − /* | |
| 393 | − * And make sure that all the mappings we set up have NX set from | |
| 394 | − * the beginning. | |
| 395 | − */ | |
| 396 | − orl $(1 << (_PAGE_BIT_NX - 32)), pa(__supported_pte_mask + 4) | |
| 397 | − | |
| 398 | 392 | enable_paging: |
| 399 | 393 | |
| 400 | 394 | /* |
| @@ -106,14 +106,24 @@ static int __init efifb_set_system(const struct dmi_system_id *id) · 105 unmodified lines | ||
| 106 | 106 | continue; |
| 107 | 107 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
| 108 | 108 | resource_size_t start, end; |
| 109 | + unsigned long flags; | |
| 110 | + | |
| 111 | + flags = pci_resource_flags(dev, i); | |
| 112 | + if (!(flags & IORESOURCE_MEM)) | |
| 113 | + continue; | |
| 114 | + | |
| 115 | + if (flags & IORESOURCE_UNSET) | |
| 116 | + continue; | |
| 117 | + | |
| 118 | + if (pci_resource_len(dev, i) == 0) | |
| 119 | + continue; | |
| 109 | 120 | |
| 110 | 121 | start = pci_resource_start(dev, i); |
| 111 | − if (start == 0) | |
| 112 | − break; | |
| 113 | 122 | end = pci_resource_end(dev, i); |
| 114 | 123 | if (screen_info.lfb_base >= start && |
| 115 | 124 | screen_info.lfb_base < end) { |
| 116 | 125 | found_bar = 1; |
| 126 | + break; | |
| 117 | 127 | } |
| 118 | 128 | } |
| 119 | 129 | } |
| @@ -92,7 +92,7 @@ unsigned long try_msr_calibrate_tsc(void) · 91 unmodified lines | ||
| 92 | 92 | |
| 93 | 93 | if (freq_desc_tables[cpu_index].msr_plat) { |
| 94 | 94 | rdmsr(MSR_PLATFORM_INFO, lo, hi); |
| 95 | − ratio = (lo >> 8) & 0x1f; | |
| 95 | + ratio = (lo >> 8) & 0xff; | |
| 96 | 96 | } else { |
| 97 | 97 | rdmsr(MSR_IA32_PERF_STATUS, lo, hi); |
| 98 | 98 | ratio = (hi >> 8) & 0x1f; |
| @@ -2823,7 +2823,7 @@ static void transparent_hugepage_adjust(struct kvm_vcpu *vcpu, · 2822 unmodified lines | ||
| 2823 | 2823 | */ |
| 2824 | 2824 | if (!is_error_noslot_pfn(pfn) && !kvm_is_reserved_pfn(pfn) && |
| 2825 | 2825 | level == PT_PAGE_TABLE_LEVEL && |
| 2826 | − PageTransCompound(pfn_to_page(pfn)) && | |
| 2826 | + PageTransCompoundMap(pfn_to_page(pfn)) && | |
| 2827 | 2827 | !mmu_gfn_lpage_is_disallowed(vcpu, gfn, PT_DIRECTORY_LEVEL)) { |
| 2828 | 2828 | unsigned long mask; |
| 2829 | 2829 | /* |
| @@ -4785,7 +4785,7 @@ restart: · 1955 unmodified lines | ||
| 4785 | 4785 | */ |
| 4786 | 4786 | if (sp->role.direct && |
| 4787 | 4787 | !kvm_is_reserved_pfn(pfn) && |
| 4788 | − PageTransCompound(pfn_to_page(pfn))) { | |
| 4788 | + PageTransCompoundMap(pfn_to_page(pfn))) { | |
| 4789 | 4789 | drop_spte(kvm, sptep); |
| 4790 | 4790 | need_tlb_flush = 1; |
| 4791 | 4791 | goto restart; |
| @@ -3103,6 +3103,8 @@ static __init int vmx_disabled_by_bios(void) · 3102 unmodified lines | ||
| 3103 | 3103 | |
| 3104 | 3104 | static void kvm_cpu_vmxon(u64 addr) |
| 3105 | 3105 | { |
| 3106 | + intel_pt_handle_vmx(1); | |
| 3107 | + | |
| 3106 | 3108 | asm volatile (ASM_VMX_VMXON_RAX |
| 3107 | 3109 | : : "a"(&addr), "m"(addr) |
| 3108 | 3110 | : "memory", "cc"); |
| @@ -3172,6 +3174,8 @@ static void vmclear_local_loaded_vmcss(void) · 63 unmodified lines | ||
| 3172 | 3174 | static void kvm_cpu_vmxoff(void) |
| 3173 | 3175 | { |
| 3174 | 3176 | asm volatile (__ex(ASM_VMX_VMXOFF) : : : "cc"); |
| 3177 | + | |
| 3178 | + intel_pt_handle_vmx(0); | |
| 3175 | 3179 | } |
| 3176 | 3180 | |
| 3177 | 3181 | static void hardware_disable(void) |
| @@ -32,8 +32,9 @@ early_param("noexec", noexec_setup); · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | void x86_configure_nx(void) |
| 34 | 34 | { |
| 35 | − /* If disable_nx is set, clear NX on all new mappings going forward. */ | |
| 36 | − if (disable_nx) | |
| 35 | + if (boot_cpu_has(X86_FEATURE_NX) && !disable_nx) | |
| 36 | + __supported_pte_mask |= _PAGE_NX; | |
| 37 | + else | |
| 37 | 38 | __supported_pte_mask &= ~_PAGE_NX; |
| 38 | 39 | } |
| 39 | 40 | |
| @@ -43,40 +43,40 @@ void __init efi_bgrt_init(void) · 42 unmodified lines | ||
| 43 | 43 | return; |
| 44 | 44 | |
| 45 | 45 | if (bgrt_tab->header.length < sizeof(*bgrt_tab)) { |
| 46 | − pr_err("Ignoring BGRT: invalid length %u (expected %zu)\n", | |
| 46 | + pr_notice("Ignoring BGRT: invalid length %u (expected %zu)\n", | |
| 47 | 47 | bgrt_tab->header.length, sizeof(*bgrt_tab)); |
| 48 | 48 | return; |
| 49 | 49 | } |
| 50 | 50 | if (bgrt_tab->version != 1) { |
| 51 | − pr_err("Ignoring BGRT: invalid version %u (expected 1)\n", | |
| 51 | + pr_notice("Ignoring BGRT: invalid version %u (expected 1)\n", | |
| 52 | 52 | bgrt_tab->version); |
| 53 | 53 | return; |
| 54 | 54 | } |
| 55 | 55 | if (bgrt_tab->status & 0xfe) { |
| 56 | − pr_err("Ignoring BGRT: reserved status bits are non-zero %u\n", | |
| 56 | + pr_notice("Ignoring BGRT: reserved status bits are non-zero %u\n", | |
| 57 | 57 | bgrt_tab->status); |
| 58 | 58 | return; |
| 59 | 59 | } |
| 60 | 60 | if (bgrt_tab->image_type != 0) { |
| 61 | − pr_err("Ignoring BGRT: invalid image type %u (expected 0)\n", | |
| 61 | + pr_notice("Ignoring BGRT: invalid image type %u (expected 0)\n", | |
| 62 | 62 | bgrt_tab->image_type); |
| 63 | 63 | return; |
| 64 | 64 | } |
| 65 | 65 | if (!bgrt_tab->image_address) { |
| 66 | − pr_err("Ignoring BGRT: null image address\n"); | |
| 66 | + pr_notice("Ignoring BGRT: null image address\n"); | |
| 67 | 67 | return; |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | 70 | image = memremap(bgrt_tab->image_address, sizeof(bmp_header), MEMREMAP_WB); |
| 71 | 71 | if (!image) { |
| 72 | − pr_err("Ignoring BGRT: failed to map image header memory\n"); | |
| 72 | + pr_notice("Ignoring BGRT: failed to map image header memory\n"); | |
| 73 | 73 | return; |
| 74 | 74 | } |
| 75 | 75 | |
| 76 | 76 | memcpy(&bmp_header, image, sizeof(bmp_header)); |
| 77 | 77 | memunmap(image); |
| 78 | 78 | if (bmp_header.id != 0x4d42) { |
| 79 | − pr_err("Ignoring BGRT: Incorrect BMP magic number 0x%x (expected 0x4d42)\n", | |
| 79 | + pr_notice("Ignoring BGRT: Incorrect BMP magic number 0x%x (expected 0x4d42)\n", | |
| 80 | 80 | bmp_header.id); |
| 81 | 81 | return; |
| 82 | 82 | } |
| @@ -84,14 +84,14 @@ void __init efi_bgrt_init(void) · 1 unmodified line | ||
| 84 | 84 | |
| 85 | 85 | bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL | __GFP_NOWARN); |
| 86 | 86 | if (!bgrt_image) { |
| 87 | − pr_err("Ignoring BGRT: failed to allocate memory for image (wanted %zu bytes)\n", | |
| 87 | + pr_notice("Ignoring BGRT: failed to allocate memory for image (wanted %zu bytes)\n", | |
| 88 | 88 | bgrt_image_size); |
| 89 | 89 | return; |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | 92 | image = memremap(bgrt_tab->image_address, bmp_header.size, MEMREMAP_WB); |
| 93 | 93 | if (!image) { |
| 94 | − pr_err("Ignoring BGRT: failed to map image memory\n"); | |
| 94 | + pr_notice("Ignoring BGRT: failed to map image memory\n"); | |
| 95 | 95 | kfree(bgrt_image); |
| 96 | 96 | bgrt_image = NULL; |
| 97 | 97 | return; |
| @@ -27,6 +27,12 @@ static bool xen_pvspin = true; · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | static void xen_qlock_kick(int cpu) |
| 29 | 29 | { |
| 30 | + int irq = per_cpu(lock_kicker_irq, cpu); | |
| 31 | + | |
| 32 | + /* Don't kick if the target's kicker interrupt is not initialized. */ | |
| 33 | + if (irq == -1) | |
| 34 | + return; | |
| 35 | + | |
| 30 | 36 | xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR); |
| 31 | 37 | } |
| 32 | 38 | |
| @@ -428,6 +428,9 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, · 427 unmodified lines | ||
| 428 | 428 | obj_desc->method.mutex->mutex. |
| 429 | 429 | original_sync_level = |
| 430 | 430 | obj_desc->method.mutex->mutex.sync_level; |
| 431 | + | |
| 432 | + obj_desc->method.mutex->mutex.thread_id = | |
| 433 | + acpi_os_get_thread_id(); | |
| 431 | 434 | } |
| 432 | 435 | } |
| 433 | 436 | |
| @@ -287,8 +287,11 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, · 286 unmodified lines | ||
| 287 | 287 | offset); |
| 288 | 288 | rc = -ENXIO; |
| 289 | 289 | } |
| 290 | − } else | |
| 290 | + } else { | |
| 291 | 291 | rc = 0; |
| 292 | + if (cmd_rc) | |
| 293 | + *cmd_rc = xlat_status(buf, cmd); | |
| 294 | + } | |
| 292 | 295 | |
| 293 | 296 | out: |
| 294 | 297 | ACPI_FREE(out_obj); |
| @@ -202,6 +202,14 @@ config SATA_FSL · 201 unmodified lines | ||
| 202 | 202 | |
| 203 | 203 | If unsure, say N. |
| 204 | 204 | |
| 205 | +config SATA_AHCI_SEATTLE | |
| 206 | + tristate "AMD Seattle 6.0Gbps AHCI SATA host controller support" | |
| 207 | + depends on ARCH_SEATTLE | |
| 208 | + help | |
| 209 | + This option enables support for AMD Seattle SATA host controller. | |
| 210 | + | |
| 211 | + If unsure, say N | |
| 212 | + | |
| 205 | 213 | config SATA_INIC162X |
| 206 | 214 | tristate "Initio 162x SATA support (Very Experimental)" |
| 207 | 215 | depends on PCI |
| @@ -4,6 +4,7 @@ obj-$(CONFIG_ATA) += libata.o · 3 unmodified lines | ||
| 4 | 4 | # non-SFF interface |
| 5 | 5 | obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o |
| 6 | 6 | obj-$(CONFIG_SATA_ACARD_AHCI) += acard-ahci.o libahci.o |
| 7 | +obj-$(CONFIG_SATA_AHCI_SEATTLE) += ahci_seattle.o libahci.o libahci_platform.o | |
| 7 | 8 | obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o libahci_platform.o |
| 8 | 9 | obj-$(CONFIG_SATA_FSL) += sata_fsl.o |
| 9 | 10 | obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o |
| @@ -51,6 +51,9 @@ static int ahci_probe(struct platform_device *pdev) · 50 unmodified lines | ||
| 51 | 51 | if (rc) |
| 52 | 52 | return rc; |
| 53 | 53 | |
| 54 | + of_property_read_u32(dev->of_node, | |
| 55 | + "ports-implemented", &hpriv->force_port_map); | |
| 56 | + | |
| 54 | 57 | if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci")) |
| 55 | 58 | hpriv->flags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ; |
| 56 | 59 | |
| @@ -0,0 +1,210 @@ | ||
| 1 | +/* | |
| 2 | + * AMD Seattle AHCI SATA driver | |
| 3 | + * | |
| 4 | + * Copyright (c) 2015, Advanced Micro Devices | |
| 5 | + * Author: Brijesh Singh <brijesh.singh@amd.com> | |
| 6 | + * | |
| 7 | + * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov | |
| 8 | + * | |
| 9 | + * This program is free software; you can redistribute it and/or modify | |
| 10 | + * it under the terms of the GNU General Public License as published by | |
| 11 | + * the Free Software Foundation; either version 2 of the License. | |
| 12 | + * | |
| 13 | + * This program is distributed in the hope that it will be useful, | |
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 16 | + * GNU General Public License for more details. | |
| 17 | + */ | |
| 18 | + | |
| 19 | +#include <linux/kernel.h> | |
| 20 | +#include <linux/module.h> | |
| 21 | +#include <linux/pm.h> | |
| 22 | +#include <linux/device.h> | |
| 23 | +#include <linux/of_device.h> | |
| 24 | +#include <linux/platform_device.h> | |
| 25 | +#include <linux/libata.h> | |
| 26 | +#include <linux/ahci_platform.h> | |
| 27 | +#include <linux/acpi.h> | |
| 28 | +#include <linux/pci_ids.h> | |
| 29 | +#include "ahci.h" | |
| 30 | + | |
| 31 | +/* SGPIO Control Register definition | |
| 32 | + * | |
| 33 | + * Bit Type Description | |
| 34 | + * 31 RW OD7.2 (activity) | |
| 35 | + * 30 RW OD7.1 (locate) | |
| 36 | + * 29 RW OD7.0 (fault) | |
| 37 | + * 28...8 RW OD6.2...OD0.0 (3bits per port, 1 bit per LED) | |
| 38 | + * 7 RO SGPIO feature flag | |
| 39 | + * 6:4 RO Reserved | |
| 40 | + * 3:0 RO Number of ports (0 means no port supported) | |
| 41 | + */ | |
| 42 | +#define ACTIVITY_BIT_POS(x) (8 + (3 * x)) | |
| 43 | +#define LOCATE_BIT_POS(x) (ACTIVITY_BIT_POS(x) + 1) | |
| 44 | +#define FAULT_BIT_POS(x) (LOCATE_BIT_POS(x) + 1) | |
| 45 | + | |
| 46 | +#define ACTIVITY_MASK 0x00010000 | |
| 47 | +#define LOCATE_MASK 0x00080000 | |
| 48 | +#define FAULT_MASK 0x00400000 | |
| 49 | + | |
| 50 | +#define DRV_NAME "ahci-seattle" | |
| 51 | + | |
| 52 | +static ssize_t seattle_transmit_led_message(struct ata_port *ap, u32 state, | |
| 53 | + ssize_t size); | |
| 54 | + | |
| 55 | +struct seattle_plat_data { | |
| 56 | + void __iomem *sgpio_ctrl; | |
| 57 | +}; | |
| 58 | + | |
| 59 | +static struct ata_port_operations ahci_port_ops = { | |
| 60 | + .inherits = &ahci_ops, | |
| 61 | +}; | |
| 62 | + | |
| 63 | +static const struct ata_port_info ahci_port_info = { | |
| 64 | + .flags = AHCI_FLAG_COMMON, | |
| 65 | + .pio_mask = ATA_PIO4, | |
| 66 | + .udma_mask = ATA_UDMA6, | |
| 67 | + .port_ops = &ahci_port_ops, | |
| 68 | +}; | |
| 69 | + | |
| 70 | +static struct ata_port_operations ahci_seattle_ops = { | |
| 71 | + .inherits = &ahci_ops, | |
| 72 | + .transmit_led_message = seattle_transmit_led_message, | |
| 73 | +}; | |
| 74 | + | |
| 75 | +static const struct ata_port_info ahci_port_seattle_info = { | |
| 76 | + .flags = AHCI_FLAG_COMMON | ATA_FLAG_EM | ATA_FLAG_SW_ACTIVITY, | |
| 77 | + .link_flags = ATA_LFLAG_SW_ACTIVITY, | |
| 78 | + .pio_mask = ATA_PIO4, | |
| 79 | + .udma_mask = ATA_UDMA6, | |
| 80 | + .port_ops = &ahci_seattle_ops, | |
| 81 | +}; | |
| 82 | + | |
| 83 | +static struct scsi_host_template ahci_platform_sht = { | |
| 84 | + AHCI_SHT(DRV_NAME), | |
| 85 | +}; | |
| 86 | + | |
| 87 | +static ssize_t seattle_transmit_led_message(struct ata_port *ap, u32 state, | |
| 88 | + ssize_t size) | |
| 89 | +{ | |
| 90 | + struct ahci_host_priv *hpriv = ap->host->private_data; | |
| 91 | + struct ahci_port_priv *pp = ap->private_data; | |
| 92 | + struct seattle_plat_data *plat_data = hpriv->plat_data; | |
| 93 | + unsigned long flags; | |
| 94 | + int pmp; | |
| 95 | + struct ahci_em_priv *emp; | |
| 96 | + u32 val; | |
| 97 | + | |
| 98 | + /* get the slot number from the message */ | |
| 99 | + pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; | |
| 100 | + if (pmp >= EM_MAX_SLOTS) | |
| 101 | + return -EINVAL; | |
| 102 | + emp = &pp->em_priv[pmp]; | |
| 103 | + | |
| 104 | + val = ioread32(plat_data->sgpio_ctrl); | |
| 105 | + if (state & ACTIVITY_MASK) | |
| 106 | + val |= 1 << ACTIVITY_BIT_POS((ap->port_no)); | |
| 107 | + else | |
| 108 | + val &= ~(1 << ACTIVITY_BIT_POS((ap->port_no))); | |
| 109 | + | |
| 110 | + if (state & LOCATE_MASK) | |
| 111 | + val |= 1 << LOCATE_BIT_POS((ap->port_no)); | |
| 112 | + else | |
| 113 | + val &= ~(1 << LOCATE_BIT_POS((ap->port_no))); | |
| 114 | + | |
| 115 | + if (state & FAULT_MASK) | |
| 116 | + val |= 1 << FAULT_BIT_POS((ap->port_no)); | |
| 117 | + else | |
| 118 | + val &= ~(1 << FAULT_BIT_POS((ap->port_no))); | |
| 119 | + | |
| 120 | + iowrite32(val, plat_data->sgpio_ctrl); | |
| 121 | + | |
| 122 | + spin_lock_irqsave(ap->lock, flags); | |
| 123 | + | |
| 124 | + /* save off new led state for port/slot */ | |
| 125 | + emp->led_state = state; | |
| 126 | + | |
| 127 | + spin_unlock_irqrestore(ap->lock, flags); | |
| 128 | + | |
| 129 | + return size; | |
| 130 | +} | |
| 131 | + | |
| 132 | +static const struct ata_port_info *ahci_seattle_get_port_info( | |
| 133 | + struct platform_device *pdev, struct ahci_host_priv *hpriv) | |
| 134 | +{ | |
| 135 | + struct device *dev = &pdev->dev; | |
| 136 | + struct seattle_plat_data *plat_data; | |
| 137 | + u32 val; | |
| 138 | + | |
| 139 | + plat_data = devm_kzalloc(dev, sizeof(*plat_data), GFP_KERNEL); | |
| 140 | + if (IS_ERR(plat_data)) | |
| 141 | + return &ahci_port_info; | |
| 142 | + | |
| 143 | + plat_data->sgpio_ctrl = devm_ioremap_resource(dev, | |
| 144 | + platform_get_resource(pdev, IORESOURCE_MEM, 1)); | |
| 145 | + if (IS_ERR(plat_data->sgpio_ctrl)) | |
| 146 | + return &ahci_port_info; | |
| 147 | + | |
| 148 | + val = ioread32(plat_data->sgpio_ctrl); | |
| 149 | + | |
| 150 | + if (!(val & 0xf)) | |
| 151 | + return &ahci_port_info; | |
| 152 | + | |
| 153 | + hpriv->em_loc = 0; | |
| 154 | + hpriv->em_buf_sz = 4; | |
| 155 | + hpriv->em_msg_type = EM_MSG_TYPE_LED; | |
| 156 | + hpriv->plat_data = plat_data; | |
| 157 | + | |
| 158 | + dev_info(dev, "SGPIO LED control is enabled.\n"); | |
| 159 | + return &ahci_port_seattle_info; | |
| 160 | +} | |
| 161 | + | |
| 162 | +static int ahci_seattle_probe(struct platform_device *pdev) | |
| 163 | +{ | |
| 164 | + int rc; | |
| 165 | + struct ahci_host_priv *hpriv; | |
| 166 | + | |
| 167 | + hpriv = ahci_platform_get_resources(pdev); | |
| 168 | + if (IS_ERR(hpriv)) | |
| 169 | + return PTR_ERR(hpriv); | |
| 170 | + | |
| 171 | + rc = ahci_platform_enable_resources(hpriv); | |
| 172 | + if (rc) | |
| 173 | + return rc; | |
| 174 | + | |
| 175 | + rc = ahci_platform_init_host(pdev, hpriv, | |
| 176 | + ahci_seattle_get_port_info(pdev, hpriv), | |
| 177 | + &ahci_platform_sht); | |
| 178 | + if (rc) | |
| 179 | + goto disable_resources; | |
| 180 | + | |
| 181 | + return 0; | |
| 182 | +disable_resources: | |
| 183 | + ahci_platform_disable_resources(hpriv); | |
| 184 | + return rc; | |
| 185 | +} | |
| 186 | + | |
| 187 | +static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend, | |
| 188 | + ahci_platform_resume); | |
| 189 | + | |
| 190 | +static const struct acpi_device_id ahci_acpi_match[] = { | |
| 191 | + { "AMDI0600", 0 }, | |
| 192 | + {} | |
| 193 | +}; | |
| 194 | +MODULE_DEVICE_TABLE(acpi, ahci_acpi_match); | |
| 195 | + | |
| 196 | +static struct platform_driver ahci_seattle_driver = { | |
| 197 | + .probe = ahci_seattle_probe, | |
| 198 | + .remove = ata_platform_remove_one, | |
| 199 | + .driver = { | |
| 200 | + .name = DRV_NAME, | |
| 201 | + .acpi_match_table = ahci_acpi_match, | |
| 202 | + .pm = &ahci_pm_ops, | |
| 203 | + }, | |
| 204 | +}; | |
| 205 | +module_platform_driver(ahci_seattle_driver); | |
| 206 | + | |
| 207 | +MODULE_DESCRIPTION("Seattle AHCI SATA platform driver"); | |
| 208 | +MODULE_AUTHOR("Brijesh Singh <brijesh.singh@amd.com>"); | |
| 209 | +MODULE_LICENSE("GPL"); | |
| 210 | +MODULE_ALIAS("platform:" DRV_NAME); | |
| @@ -507,6 +507,7 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv) · 506 unmodified lines | ||
| 507 | 507 | dev_info(dev, "forcing port_map 0x%x -> 0x%x\n", |
| 508 | 508 | port_map, hpriv->force_port_map); |
| 509 | 509 | port_map = hpriv->force_port_map; |
| 510 | + hpriv->saved_port_map = port_map; | |
| 510 | 511 | } |
| 511 | 512 | |
| 512 | 513 | if (hpriv->mask_port_map) { |
| @@ -259,9 +259,6 @@ unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev) · 258 unmodified lines | ||
| 259 | 259 | reg = opp_table->regulator; |
| 260 | 260 | if (IS_ERR(reg)) { |
| 261 | 261 | /* Regulator may not be required for device */ |
| 262 | − if (reg) | |
| 263 | − dev_err(dev, "%s: Invalid regulator (%ld)\n", __func__, | |
| 264 | − PTR_ERR(reg)); | |
| 265 | 262 | rcu_read_unlock(); |
| 266 | 263 | return 0; |
| 267 | 264 | } |
| @@ -21,7 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | static inline bool is_pset_node(struct fwnode_handle *fwnode) |
| 23 | 23 | { |
| 24 | − return fwnode && fwnode->type == FWNODE_PDATA; | |
| 24 | + return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_PDATA; | |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | 27 | static inline struct property_set *to_pset_node(struct fwnode_handle *fwnode) |
| @@ -538,7 +538,6 @@ static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, · 537 unmodified lines | ||
| 538 | 538 | u8 *order, u64 *snap_size); |
| 539 | 539 | static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, |
| 540 | 540 | u64 *snap_features); |
| 541 | −static u64 rbd_snap_id_by_name(struct rbd_device *rbd_dev, const char *name); | |
| 542 | 541 | |
| 543 | 542 | static int rbd_open(struct block_device *bdev, fmode_t mode) |
| 544 | 543 | { |
| @@ -3127,9 +3126,6 @@ static void rbd_watch_cb(u64 ver, u64 notify_id, u8 opcode, void *data) · 2582 unmodified lines | ||
| 3127 | 3126 | struct rbd_device *rbd_dev = (struct rbd_device *)data; |
| 3128 | 3127 | int ret; |
| 3129 | 3128 | |
| 3130 | − if (!rbd_dev) | |
| 3131 | − return; | |
| 3132 | − | |
| 3133 | 3129 | dout("%s: \"%s\" notify_id %llu opcode %u\n", __func__, |
| 3134 | 3130 | rbd_dev->header_name, (unsigned long long)notify_id, |
| 3135 | 3131 | (unsigned int)opcode); |
| @@ -3263,6 +3259,9 @@ static void rbd_dev_header_unwatch_sync(struct rbd_device *rbd_dev) · 127 unmodified lines | ||
| 3263 | 3259 | |
| 3264 | 3260 | ceph_osdc_cancel_event(rbd_dev->watch_event); |
| 3265 | 3261 | rbd_dev->watch_event = NULL; |
| 3262 | + | |
| 3263 | + dout("%s flushing notifies\n", __func__); | |
| 3264 | + ceph_osdc_flush_notifies(&rbd_dev->rbd_client->client->osdc); | |
| 3266 | 3265 | } |
| 3267 | 3266 | |
| 3268 | 3267 | /* |
| @@ -3642,21 +3641,14 @@ static void rbd_exists_validate(struct rbd_device *rbd_dev) · 373 unmodified lines | ||
| 3642 | 3641 | static void rbd_dev_update_size(struct rbd_device *rbd_dev) |
| 3643 | 3642 | { |
| 3644 | 3643 | sector_t size; |
| 3645 | − bool removing; | |
| 3646 | 3644 | |
| 3647 | 3645 | /* |
| 3648 | − * Don't hold the lock while doing disk operations, | |
| 3649 | − * or lock ordering will conflict with the bdev mutex via: | |
| 3650 | − * rbd_add() -> blkdev_get() -> rbd_open() | |
| 3646 | + * If EXISTS is not set, rbd_dev->disk may be NULL, so don't | |
| 3647 | + * try to update its size. If REMOVING is set, updating size | |
| 3648 | + * is just useless work since the device can't be opened. | |
| 3651 | 3649 | */ |
| 3652 | − spin_lock_irq(&rbd_dev->lock); | |
| 3653 | − removing = test_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags); | |
| 3654 | − spin_unlock_irq(&rbd_dev->lock); | |
| 3655 | − /* | |
| 3656 | − * If the device is being removed, rbd_dev->disk has | |
| 3657 | − * been destroyed, so don't try to update its size | |
| 3658 | − */ | |
| 3659 | − if (!removing) { | |
| 3650 | + if (test_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags) && | |
| 3651 | + !test_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags)) { | |
| 3660 | 3652 | size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE; |
| 3661 | 3653 | dout("setting size to %llu sectors", (unsigned long long)size); |
| 3662 | 3654 | set_capacity(rbd_dev->disk, size); |
| @@ -4191,7 +4183,7 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, · 528 unmodified lines | ||
| 4191 | 4183 | __le64 features; |
| 4192 | 4184 | __le64 incompat; |
| 4193 | 4185 | } __attribute__ ((packed)) features_buf = { 0 }; |
| 4194 | − u64 incompat; | |
| 4186 | + u64 unsup; | |
| 4195 | 4187 | int ret; |
| 4196 | 4188 | |
| 4197 | 4189 | ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name, |
| @@ -4204,9 +4196,12 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, · 6 unmodified lines | ||
| 4204 | 4196 | if (ret < sizeof (features_buf)) |
| 4205 | 4197 | return -ERANGE; |
| 4206 | 4198 | |
| 4207 | − incompat = le64_to_cpu(features_buf.incompat); | |
| 4208 | − if (incompat & ~RBD_FEATURES_SUPPORTED) | |
| 4199 | + unsup = le64_to_cpu(features_buf.incompat) & ~RBD_FEATURES_SUPPORTED; | |
| 4200 | + if (unsup) { | |
| 4201 | + rbd_warn(rbd_dev, "image uses unsupported features: 0x%llx", | |
| 4202 | + unsup); | |
| 4209 | 4203 | return -ENXIO; |
| 4204 | + } | |
| 4210 | 4205 | |
| 4211 | 4206 | *snap_features = le64_to_cpu(features_buf.features); |
| 4212 | 4207 | |
| @@ -5187,6 +5182,10 @@ out_err: · 974 unmodified lines | ||
| 5187 | 5182 | return ret; |
| 5188 | 5183 | } |
| 5189 | 5184 | |
| 5185 | +/* | |
| 5186 | + * rbd_dev->header_rwsem must be locked for write and will be unlocked | |
| 5187 | + * upon return. | |
| 5188 | + */ | |
| 5190 | 5189 | static int rbd_dev_device_setup(struct rbd_device *rbd_dev) |
| 5191 | 5190 | { |
| 5192 | 5191 | int ret; |
| @@ -5195,7 +5194,7 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev) · 2 unmodified lines | ||
| 5195 | 5194 | |
| 5196 | 5195 | ret = rbd_dev_id_get(rbd_dev); |
| 5197 | 5196 | if (ret) |
| 5198 | − return ret; | |
| 5197 | + goto err_out_unlock; | |
| 5199 | 5198 | |
| 5200 | 5199 | BUILD_BUG_ON(DEV_NAME_LEN |
| 5201 | 5200 | < sizeof (RBD_DRV_NAME) + MAX_INT_FORMAT_WIDTH); |
| @@ -5236,8 +5235,9 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev) · 34 unmodified lines | ||
| 5236 | 5235 | /* Everything's ready. Announce the disk to the world. */ |
| 5237 | 5236 | |
| 5238 | 5237 | set_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); |
| 5239 | − add_disk(rbd_dev->disk); | |
| 5238 | + up_write(&rbd_dev->header_rwsem); | |
| 5240 | 5239 | |
| 5240 | + add_disk(rbd_dev->disk); | |
| 5241 | 5241 | pr_info("%s: added with size 0x%llx\n", rbd_dev->disk->disk_name, |
| 5242 | 5242 | (unsigned long long) rbd_dev->mapping.size); |
| 5243 | 5243 | |
| @@ -5252,6 +5252,8 @@ err_out_blkdev: · 8 unmodified lines | ||
| 5252 | 5252 | unregister_blkdev(rbd_dev->major, rbd_dev->name); |
| 5253 | 5253 | err_out_id: |
| 5254 | 5254 | rbd_dev_id_put(rbd_dev); |
| 5255 | +err_out_unlock: | |
| 5256 | + up_write(&rbd_dev->header_rwsem); | |
| 5255 | 5257 | return ret; |
| 5256 | 5258 | } |
| 5257 | 5259 | |
| @@ -5442,6 +5444,7 @@ static ssize_t do_rbd_add(struct bus_type *bus, · 184 unmodified lines | ||
| 5442 | 5444 | spec = NULL; /* rbd_dev now owns this */ |
| 5443 | 5445 | rbd_opts = NULL; /* rbd_dev now owns this */ |
| 5444 | 5446 | |
| 5447 | + down_write(&rbd_dev->header_rwsem); | |
| 5445 | 5448 | rc = rbd_dev_image_probe(rbd_dev, 0); |
| 5446 | 5449 | if (rc < 0) |
| 5447 | 5450 | goto err_out_rbd_dev; |
| @@ -5471,6 +5474,7 @@ out: · 23 unmodified lines | ||
| 5471 | 5474 | return rc; |
| 5472 | 5475 | |
| 5473 | 5476 | err_out_rbd_dev: |
| 5477 | + up_write(&rbd_dev->header_rwsem); | |
| 5474 | 5478 | rbd_dev_destroy(rbd_dev); |
| 5475 | 5479 | err_out_client: |
| 5476 | 5480 | rbd_put_client(rbdc); |
| @@ -5577,12 +5581,6 @@ static ssize_t do_rbd_remove(struct bus_type *bus, · 100 unmodified lines | ||
| 5577 | 5581 | return ret; |
| 5578 | 5582 | |
| 5579 | 5583 | rbd_dev_header_unwatch_sync(rbd_dev); |
| 5580 | − /* | |
| 5581 | − * flush remaining watch callbacks - these must be complete | |
| 5582 | − * before the osd_client is shutdown | |
| 5583 | − */ | |
| 5584 | − dout("%s: flushing notifies", __func__); | |
| 5585 | − ceph_osdc_flush_notifies(&rbd_dev->rbd_client->client->osdc); | |
| 5586 | 5584 | |
| 5587 | 5585 | /* |
| 5588 | 5586 | * Don't free anything from rbd_dev->disk until after all |
| @@ -394,7 +394,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) · 393 unmodified lines | ||
| 394 | 394 | clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1", 2, 7); |
| 395 | 395 | } else { |
| 396 | 396 | clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6); |
| 397 | − clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60", base + 0x20, 2, 6); | |
| 397 | + clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60m", base + 0x20, 2, 6); | |
| 398 | 398 | clk[IMX6QDL_CLK_IPG_PER] = imx_clk_fixup_divider("ipg_per", "ipg", base + 0x1c, 0, 6, imx_cscmr1_fixup); |
| 399 | 399 | clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6); |
| 400 | 400 | clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); |
| @@ -1557,21 +1557,25 @@ void cpufreq_suspend(void) · 1556 unmodified lines | ||
| 1557 | 1557 | if (!cpufreq_driver) |
| 1558 | 1558 | return; |
| 1559 | 1559 | |
| 1560 | − if (!has_target()) | |
| 1560 | + if (!has_target() && !cpufreq_driver->suspend) | |
| 1561 | 1561 | goto suspend; |
| 1562 | 1562 | |
| 1563 | 1563 | pr_debug("%s: Suspending Governors\n", __func__); |
| 1564 | 1564 | |
| 1565 | 1565 | for_each_active_policy(policy) { |
| 1566 | − down_write(&policy->rwsem); | |
| 1567 | − ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); | |
| 1568 | − up_write(&policy->rwsem); | |
| 1566 | + if (has_target()) { | |
| 1567 | + down_write(&policy->rwsem); | |
| 1568 | + ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); | |
| 1569 | + up_write(&policy->rwsem); | |
| 1569 | 1570 | |
| 1570 | − if (ret) | |
| 1571 | − pr_err("%s: Failed to stop governor for policy: %p\n", | |
| 1572 | − __func__, policy); | |
| 1573 | − else if (cpufreq_driver->suspend | |
| 1574 | − && cpufreq_driver->suspend(policy)) | |
| 1571 | + if (ret) { | |
| 1572 | + pr_err("%s: Failed to stop governor for policy: %p\n", | |
| 1573 | + __func__, policy); | |
| 1574 | + continue; | |
| 1575 | + } | |
| 1576 | + } | |
| 1577 | + | |
| 1578 | + if (cpufreq_driver->suspend && cpufreq_driver->suspend(policy)) | |
| 1575 | 1579 | pr_err("%s: Failed to suspend driver: %p\n", __func__, |
| 1576 | 1580 | policy); |
| 1577 | 1581 | } |
| @@ -1596,7 +1600,7 @@ void cpufreq_resume(void) · 18 unmodified lines | ||
| 1596 | 1600 | |
| 1597 | 1601 | cpufreq_suspended = false; |
| 1598 | 1602 | |
| 1599 | − if (!has_target()) | |
| 1603 | + if (!has_target() && !cpufreq_driver->resume) | |
| 1600 | 1604 | return; |
| 1601 | 1605 | |
| 1602 | 1606 | pr_debug("%s: Resuming Governors\n", __func__); |
| @@ -1605,7 +1609,7 @@ void cpufreq_resume(void) · 2 unmodified lines | ||
| 1605 | 1609 | if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) { |
| 1606 | 1610 | pr_err("%s: Failed to resume driver: %p\n", __func__, |
| 1607 | 1611 | policy); |
| 1608 | − } else { | |
| 1612 | + } else if (has_target()) { | |
| 1609 | 1613 | down_write(&policy->rwsem); |
| 1610 | 1614 | ret = cpufreq_start_governor(policy); |
| 1611 | 1615 | up_write(&policy->rwsem); |
| @@ -193,12 +193,8 @@ unsigned int dbs_update(struct cpufreq_policy *policy) · 192 unmodified lines | ||
| 193 | 193 | wall_time = cur_wall_time - j_cdbs->prev_cpu_wall; |
| 194 | 194 | j_cdbs->prev_cpu_wall = cur_wall_time; |
| 195 | 195 | |
| 196 | − if (cur_idle_time <= j_cdbs->prev_cpu_idle) { | |
| 197 | − idle_time = 0; | |
| 198 | − } else { | |
| 199 | − idle_time = cur_idle_time - j_cdbs->prev_cpu_idle; | |
| 200 | − j_cdbs->prev_cpu_idle = cur_idle_time; | |
| 201 | − } | |
| 196 | + idle_time = cur_idle_time - j_cdbs->prev_cpu_idle; | |
| 197 | + j_cdbs->prev_cpu_idle = cur_idle_time; | |
| 202 | 198 | |
| 203 | 199 | if (ignore_nice) { |
| 204 | 200 | u64 cur_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE]; |
| @@ -453,6 +453,14 @@ static void intel_pstate_hwp_set(const struct cpumask *cpumask) · 452 unmodified lines | ||
| 453 | 453 | } |
| 454 | 454 | } |
| 455 | 455 | |
| 456 | +static int intel_pstate_hwp_set_policy(struct cpufreq_policy *policy) | |
| 457 | +{ | |
| 458 | + if (hwp_active) | |
| 459 | + intel_pstate_hwp_set(policy->cpus); | |
| 460 | + | |
| 461 | + return 0; | |
| 462 | +} | |
| 463 | + | |
| 456 | 464 | static void intel_pstate_hwp_set_online_cpus(void) |
| 457 | 465 | { |
| 458 | 466 | get_online_cpus(); |
| @@ -813,6 +821,11 @@ static int core_get_max_pstate(void) · 354 unmodified lines | ||
| 813 | 821 | if (err) |
| 814 | 822 | goto skip_tar; |
| 815 | 823 | |
| 824 | + /* For level 1 and 2, bits[23:16] contain the ratio */ | |
| 825 | + if (tdp_ctrl) | |
| 826 | + tdp_ratio >>= 16; | |
| 827 | + | |
| 828 | + tdp_ratio &= 0xff; /* ratios are only 8 bits long */ | |
| 816 | 829 | if (tdp_ratio - 1 == tar) { |
| 817 | 830 | max_pstate = tar; |
| 818 | 831 | pr_debug("max_pstate=TAC %x\n", max_pstate); |
| @@ -1057,8 +1070,9 @@ static inline bool intel_pstate_sample(struct cpudata *cpu, u64 time) · 238 unmodified lines | ||
| 1057 | 1070 | |
| 1058 | 1071 | static inline int32_t get_avg_frequency(struct cpudata *cpu) |
| 1059 | 1072 | { |
| 1060 | − return div64_u64(cpu->pstate.max_pstate_physical * cpu->sample.aperf * | |
| 1061 | − cpu->pstate.scaling, cpu->sample.mperf); | |
| 1073 | + return fp_toint(mul_fp(cpu->sample.core_pct_busy, | |
| 1074 | + int_tofp(cpu->pstate.max_pstate_physical * | |
| 1075 | + cpu->pstate.scaling / 100))); | |
| 1062 | 1076 | } |
| 1063 | 1077 | |
| 1064 | 1078 | static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu) |
| @@ -1101,8 +1115,6 @@ static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu) · 36 unmodified lines | ||
| 1101 | 1115 | int32_t core_busy, max_pstate, current_pstate, sample_ratio; |
| 1102 | 1116 | u64 duration_ns; |
| 1103 | 1117 | |
| 1104 | − intel_pstate_calc_busy(cpu); | |
| 1105 | − | |
| 1106 | 1118 | /* |
| 1107 | 1119 | * core_busy is the ratio of actual performance to max |
| 1108 | 1120 | * max_pstate is the max non turbo pstate available |
| @@ -1186,8 +1198,11 @@ static void intel_pstate_update_util(struct update_util_data *data, u64 time, · 77 unmodified lines | ||
| 1186 | 1198 | if ((s64)delta_ns >= pid_params.sample_rate_ns) { |
| 1187 | 1199 | bool sample_taken = intel_pstate_sample(cpu, time); |
| 1188 | 1200 | |
| 1189 | − if (sample_taken && !hwp_active) | |
| 1190 | − intel_pstate_adjust_busy_pstate(cpu); | |
| 1201 | + if (sample_taken) { | |
| 1202 | + intel_pstate_calc_busy(cpu); | |
| 1203 | + if (!hwp_active) | |
| 1204 | + intel_pstate_adjust_busy_pstate(cpu); | |
| 1205 | + } | |
| 1191 | 1206 | } |
| 1192 | 1207 | } |
| 1193 | 1208 | |
| @@ -1341,8 +1356,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) · 147 unmodified lines | ||
| 1341 | 1356 | out: |
| 1342 | 1357 | intel_pstate_set_update_util_hook(policy->cpu); |
| 1343 | 1358 | |
| 1344 | − if (hwp_active) | |
| 1345 | − intel_pstate_hwp_set(policy->cpus); | |
| 1359 | + intel_pstate_hwp_set_policy(policy); | |
| 1346 | 1360 | |
| 1347 | 1361 | return 0; |
| 1348 | 1362 | } |
| @@ -1406,6 +1420,7 @@ static struct cpufreq_driver intel_pstate_driver = { · 57 unmodified lines | ||
| 1406 | 1420 | .flags = CPUFREQ_CONST_LOOPS, |
| 1407 | 1421 | .verify = intel_pstate_verify_policy, |
| 1408 | 1422 | .setpolicy = intel_pstate_set_policy, |
| 1423 | + .resume = intel_pstate_hwp_set_policy, | |
| 1409 | 1424 | .get = intel_pstate_get, |
| 1410 | 1425 | .init = intel_pstate_cpu_init, |
| 1411 | 1426 | .stop_cpu = intel_pstate_stop_cpu, |
| @@ -259,6 +259,10 @@ static int sti_cpufreq_init(void) · 258 unmodified lines | ||
| 259 | 259 | { |
| 260 | 260 | int ret; |
| 261 | 261 | |
| 262 | + if ((!of_machine_is_compatible("st,stih407")) && | |
| 263 | + (!of_machine_is_compatible("st,stih410"))) | |
| 264 | + return -ENODEV; | |
| 265 | + | |
| 262 | 266 | ddata.cpu = get_cpu_device(0); |
| 263 | 267 | if (!ddata.cpu) { |
| 264 | 268 | dev_err(ddata.cpu, "Failed to get device for CPU0\n"); |
| @@ -50,7 +50,7 @@ static int arm_enter_idle_state(struct cpuidle_device *dev, · 49 unmodified lines | ||
| 50 | 50 | * call the CPU ops suspend protocol with idle index as a |
| 51 | 51 | * parameter. |
| 52 | 52 | */ |
| 53 | − arm_cpuidle_suspend(idx); | |
| 53 | + ret = arm_cpuidle_suspend(idx); | |
| 54 | 54 | |
| 55 | 55 | cpu_pm_exit(); |
| 56 | 56 | } |
| @@ -63,6 +63,14 @@ static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr, · 62 unmodified lines | ||
| 63 | 63 | ptr->eptr = upper_32_bits(dma_addr); |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | +static void copy_talitos_ptr(struct talitos_ptr *dst_ptr, | |
| 67 | + struct talitos_ptr *src_ptr, bool is_sec1) | |
| 68 | +{ | |
| 69 | + dst_ptr->ptr = src_ptr->ptr; | |
| 70 | + if (!is_sec1) | |
| 71 | + dst_ptr->eptr = src_ptr->eptr; | |
| 72 | +} | |
| 73 | + | |
| 66 | 74 | static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned int len, |
| 67 | 75 | bool is_sec1) |
| 68 | 76 | { |
| @@ -1083,21 +1091,20 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, · 1014 unmodified lines | ||
| 1083 | 1091 | sg_count = dma_map_sg(dev, areq->src, edesc->src_nents ?: 1, |
| 1084 | 1092 | (areq->src == areq->dst) ? DMA_BIDIRECTIONAL |
| 1085 | 1093 | : DMA_TO_DEVICE); |
| 1086 | − | |
| 1087 | 1094 | /* hmac data */ |
| 1088 | 1095 | desc->ptr[1].len = cpu_to_be16(areq->assoclen); |
| 1089 | 1096 | if (sg_count > 1 && |
| 1090 | 1097 | (ret = sg_to_link_tbl_offset(areq->src, sg_count, 0, |
| 1091 | 1098 | areq->assoclen, |
| 1092 | 1099 | &edesc->link_tbl[tbl_off])) > 1) { |
| 1093 | − tbl_off += ret; | |
| 1094 | − | |
| 1095 | 1100 | to_talitos_ptr(&desc->ptr[1], edesc->dma_link_tbl + tbl_off * |
| 1096 | 1101 | sizeof(struct talitos_ptr), 0); |
| 1097 | 1102 | desc->ptr[1].j_extent = DESC_PTR_LNKTBL_JUMP; |
| 1098 | 1103 | |
| 1099 | 1104 | dma_sync_single_for_device(dev, edesc->dma_link_tbl, |
| 1100 | 1105 | edesc->dma_len, DMA_BIDIRECTIONAL); |
| 1106 | + | |
| 1107 | + tbl_off += ret; | |
| 1101 | 1108 | } else { |
| 1102 | 1109 | to_talitos_ptr(&desc->ptr[1], sg_dma_address(areq->src), 0); |
| 1103 | 1110 | desc->ptr[1].j_extent = 0; |
| @@ -1126,11 +1133,13 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, · 22 unmodified lines | ||
| 1126 | 1133 | if (edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV) |
| 1127 | 1134 | sg_link_tbl_len += authsize; |
| 1128 | 1135 | |
| 1129 | − if (sg_count > 1 && | |
| 1130 | − (ret = sg_to_link_tbl_offset(areq->src, sg_count, areq->assoclen, | |
| 1131 | − sg_link_tbl_len, | |
| 1132 | − &edesc->link_tbl[tbl_off])) > 1) { | |
| 1133 | − tbl_off += ret; | |
| 1136 | + if (sg_count == 1) { | |
| 1137 | + to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->src) + | |
| 1138 | + areq->assoclen, 0); | |
| 1139 | + } else if ((ret = sg_to_link_tbl_offset(areq->src, sg_count, | |
| 1140 | + areq->assoclen, sg_link_tbl_len, | |
| 1141 | + &edesc->link_tbl[tbl_off])) > | |
| 1142 | + 1) { | |
| 1134 | 1143 | desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP; |
| 1135 | 1144 | to_talitos_ptr(&desc->ptr[4], edesc->dma_link_tbl + |
| 1136 | 1145 | tbl_off * |
| @@ -1138,8 +1147,10 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, · 1 unmodified line | ||
| 1138 | 1147 | dma_sync_single_for_device(dev, edesc->dma_link_tbl, |
| 1139 | 1148 | edesc->dma_len, |
| 1140 | 1149 | DMA_BIDIRECTIONAL); |
| 1141 | − } else | |
| 1142 | − to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->src), 0); | |
| 1150 | + tbl_off += ret; | |
| 1151 | + } else { | |
| 1152 | + copy_talitos_ptr(&desc->ptr[4], &edesc->link_tbl[tbl_off], 0); | |
| 1153 | + } | |
| 1143 | 1154 | |
| 1144 | 1155 | /* cipher out */ |
| 1145 | 1156 | desc->ptr[5].len = cpu_to_be16(cryptlen); |
| @@ -1151,11 +1162,13 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, · 5 unmodified lines | ||
| 1151 | 1162 | |
| 1152 | 1163 | edesc->icv_ool = false; |
| 1153 | 1164 | |
| 1154 | − if (sg_count > 1 && | |
| 1155 | − (sg_count = sg_to_link_tbl_offset(areq->dst, sg_count, | |
| 1165 | + if (sg_count == 1) { | |
| 1166 | + to_talitos_ptr(&desc->ptr[5], sg_dma_address(areq->dst) + | |
| 1167 | + areq->assoclen, 0); | |
| 1168 | + } else if ((sg_count = | |
| 1169 | + sg_to_link_tbl_offset(areq->dst, sg_count, | |
| 1156 | 1170 | areq->assoclen, cryptlen, |
| 1157 | − &edesc->link_tbl[tbl_off])) > | |
| 1158 | − 1) { | |
| 1171 | + &edesc->link_tbl[tbl_off])) > 1) { | |
| 1159 | 1172 | struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off]; |
| 1160 | 1173 | |
| 1161 | 1174 | to_talitos_ptr(&desc->ptr[5], edesc->dma_link_tbl + |
| @@ -1178,8 +1191,9 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, · 16 unmodified lines | ||
| 1178 | 1191 | edesc->dma_len, DMA_BIDIRECTIONAL); |
| 1179 | 1192 | |
| 1180 | 1193 | edesc->icv_ool = true; |
| 1181 | − } else | |
| 1182 | − to_talitos_ptr(&desc->ptr[5], sg_dma_address(areq->dst), 0); | |
| 1194 | + } else { | |
| 1195 | + copy_talitos_ptr(&desc->ptr[5], &edesc->link_tbl[tbl_off], 0); | |
| 1196 | + } | |
| 1183 | 1197 | |
| 1184 | 1198 | /* iv out */ |
| 1185 | 1199 | map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv, |
| @@ -2629,21 +2643,11 @@ struct talitos_crypto_alg { · 1443 unmodified lines | ||
| 2629 | 2643 | struct talitos_alg_template algt; |
| 2630 | 2644 | }; |
| 2631 | 2645 | |
| 2632 | −static int talitos_cra_init(struct crypto_tfm *tfm) | |
| 2646 | +static int talitos_init_common(struct talitos_ctx *ctx, | |
| 2647 | + struct talitos_crypto_alg *talitos_alg) | |
| 2633 | 2648 | { |
| 2634 | − struct crypto_alg *alg = tfm->__crt_alg; | |
| 2635 | − struct talitos_crypto_alg *talitos_alg; | |
| 2636 | − struct talitos_ctx *ctx = crypto_tfm_ctx(tfm); | |
| 2637 | 2649 | struct talitos_private *priv; |
| 2638 | 2650 | |
| 2639 | − if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH) | |
| 2640 | − talitos_alg = container_of(__crypto_ahash_alg(alg), | |
| 2641 | − struct talitos_crypto_alg, | |
| 2642 | − algt.alg.hash); | |
| 2643 | − else | |
| 2644 | − talitos_alg = container_of(alg, struct talitos_crypto_alg, | |
| 2645 | − algt.alg.crypto); | |
| 2646 | − | |
| 2647 | 2651 | /* update context with ptr to dev */ |
| 2648 | 2652 | ctx->dev = talitos_alg->dev; |
| 2649 | 2653 | |
| @@ -2661,10 +2665,33 @@ static int talitos_cra_init(struct crypto_tfm *tfm) · 11 unmodified lines | ||
| 2661 | 2665 | return 0; |
| 2662 | 2666 | } |
| 2663 | 2667 | |
| 2668 | +static int talitos_cra_init(struct crypto_tfm *tfm) | |
| 2669 | +{ | |
| 2670 | + struct crypto_alg *alg = tfm->__crt_alg; | |
| 2671 | + struct talitos_crypto_alg *talitos_alg; | |
| 2672 | + struct talitos_ctx *ctx = crypto_tfm_ctx(tfm); | |
| 2673 | + | |
| 2674 | + if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH) | |
| 2675 | + talitos_alg = container_of(__crypto_ahash_alg(alg), | |
| 2676 | + struct talitos_crypto_alg, | |
| 2677 | + algt.alg.hash); | |
| 2678 | + else | |
| 2679 | + talitos_alg = container_of(alg, struct talitos_crypto_alg, | |
| 2680 | + algt.alg.crypto); | |
| 2681 | + | |
| 2682 | + return talitos_init_common(ctx, talitos_alg); | |
| 2683 | +} | |
| 2684 | + | |
| 2664 | 2685 | static int talitos_cra_init_aead(struct crypto_aead *tfm) |
| 2665 | 2686 | { |
| 2666 | − talitos_cra_init(crypto_aead_tfm(tfm)); | |
| 2667 | − return 0; | |
| 2687 | + struct aead_alg *alg = crypto_aead_alg(tfm); | |
| 2688 | + struct talitos_crypto_alg *talitos_alg; | |
| 2689 | + struct talitos_ctx *ctx = crypto_aead_ctx(tfm); | |
| 2690 | + | |
| 2691 | + talitos_alg = container_of(alg, struct talitos_crypto_alg, | |
| 2692 | + algt.alg.aead); | |
| 2693 | + | |
| 2694 | + return talitos_init_common(ctx, talitos_alg); | |
| 2668 | 2695 | } |
| 2669 | 2696 | |
| 2670 | 2697 | static int talitos_cra_init_ahash(struct crypto_tfm *tfm) |
| @@ -1866,7 +1866,7 @@ static int i7core_mce_check_error(struct notifier_block *nb, unsigned long val, · 1865 unmodified lines | ||
| 1866 | 1866 | |
| 1867 | 1867 | i7_dev = get_i7core_dev(mce->socketid); |
| 1868 | 1868 | if (!i7_dev) |
| 1869 | − return NOTIFY_BAD; | |
| 1869 | + return NOTIFY_DONE; | |
| 1870 | 1870 | |
| 1871 | 1871 | mci = i7_dev->mci; |
| 1872 | 1872 | pvt = mci->pvt_info; |
| @@ -3168,7 +3168,7 @@ static int sbridge_mce_check_error(struct notifier_block *nb, unsigned long val, · 3167 unmodified lines | ||
| 3168 | 3168 | |
| 3169 | 3169 | mci = get_mci_for_node_id(mce->socketid); |
| 3170 | 3170 | if (!mci) |
| 3171 | − return NOTIFY_BAD; | |
| 3171 | + return NOTIFY_DONE; | |
| 3172 | 3172 | pvt = mci->pvt_info; |
| 3173 | 3173 | |
| 3174 | 3174 | /* |
| @@ -202,29 +202,44 @@ static const struct variable_validate variable_validate[] = { · 201 unmodified lines | ||
| 202 | 202 | { NULL_GUID, "", NULL }, |
| 203 | 203 | }; |
| 204 | 204 | |
| 205 | +/* | |
| 206 | + * Check if @var_name matches the pattern given in @match_name. | |
| 207 | + * | |
| 208 | + * @var_name: an array of @len non-NUL characters. | |
| 209 | + * @match_name: a NUL-terminated pattern string, optionally ending in "*". A | |
| 210 | + * final "*" character matches any trailing characters @var_name, | |
| 211 | + * including the case when there are none left in @var_name. | |
| 212 | + * @match: on output, the number of non-wildcard characters in @match_name | |
| 213 | + * that @var_name matches, regardless of the return value. | |
| 214 | + * @return: whether @var_name fully matches @match_name. | |
| 215 | + */ | |
| 205 | 216 | static bool |
| 206 | 217 | variable_matches(const char *var_name, size_t len, const char *match_name, |
| 207 | 218 | int *match) |
| 208 | 219 | { |
| 209 | 220 | for (*match = 0; ; (*match)++) { |
| 210 | 221 | char c = match_name[*match]; |
| 211 | − char u = var_name[*match]; | |
| 212 | 222 | |
| 213 | − /* Wildcard in the matching name means we've matched */ | |
| 214 | − if (c == '*') | |
| 223 | + switch (c) { | |
| 224 | + case '*': | |
| 225 | + /* Wildcard in @match_name means we've matched. */ | |
| 215 | 226 | return true; |
| 216 | 227 | |
| 217 | − /* Case sensitive match */ | |
| 218 | − if (!c && *match == len) | |
| 219 | − return true; | |
| 228 | + case '\0': | |
| 229 | + /* @match_name has ended. Has @var_name too? */ | |
| 230 | + return (*match == len); | |
| 220 | 231 | |
| 221 | − if (c != u) | |
| 232 | + default: | |
| 233 | + /* | |
| 234 | + * We've reached a non-wildcard char in @match_name. | |
| 235 | + * Continue only if there's an identical character in | |
| 236 | + * @var_name. | |
| 237 | + */ | |
| 238 | + if (*match < len && c == var_name[*match]) | |
| 239 | + continue; | |
| 222 | 240 | return false; |
| 223 | − | |
| 224 | − if (!c) | |
| 225 | − return true; | |
| 241 | + } | |
| 226 | 242 | } |
| 227 | − return true; | |
| 228 | 243 | } |
| 229 | 244 | |
| 230 | 245 | bool |
| @@ -360,7 +360,7 @@ static struct cpuidle_ops psci_cpuidle_ops __initdata = { · 359 unmodified lines | ||
| 360 | 360 | .init = psci_dt_cpu_init_idle, |
| 361 | 361 | }; |
| 362 | 362 | |
| 363 | −CPUIDLE_METHOD_OF_DECLARE(psci, "arm,psci", &psci_cpuidle_ops); | |
| 363 | +CPUIDLE_METHOD_OF_DECLARE(psci, "psci", &psci_cpuidle_ops); | |
| 364 | 364 | #endif |
| 365 | 365 | #endif |
| 366 | 366 | |
| @@ -77,7 +77,7 @@ static inline u16 fw_cfg_sel_endianness(u16 key) · 76 unmodified lines | ||
| 77 | 77 | static inline void fw_cfg_read_blob(u16 key, |
| 78 | 78 | void *buf, loff_t pos, size_t count) |
| 79 | 79 | { |
| 80 | − u32 glk; | |
| 80 | + u32 glk = -1U; | |
| 81 | 81 | acpi_status status; |
| 82 | 82 | |
| 83 | 83 | /* If we have ACPI, ensure mutual exclusion against any potential |
| @@ -196,44 +196,6 @@ static int gpio_rcar_irq_set_wake(struct irq_data *d, unsigned int on) · 195 unmodified lines | ||
| 196 | 196 | return 0; |
| 197 | 197 | } |
| 198 | 198 | |
| 199 | −static void gpio_rcar_irq_bus_lock(struct irq_data *d) | |
| 200 | −{ | |
| 201 | − struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | |
| 202 | − struct gpio_rcar_priv *p = gpiochip_get_data(gc); | |
| 203 | − | |
| 204 | − pm_runtime_get_sync(&p->pdev->dev); | |
| 205 | −} | |
| 206 | − | |
| 207 | −static void gpio_rcar_irq_bus_sync_unlock(struct irq_data *d) | |
| 208 | −{ | |
| 209 | − struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | |
| 210 | − struct gpio_rcar_priv *p = gpiochip_get_data(gc); | |
| 211 | − | |
| 212 | − pm_runtime_put(&p->pdev->dev); | |
| 213 | −} | |
| 214 | − | |
| 215 | − | |
| 216 | −static int gpio_rcar_irq_request_resources(struct irq_data *d) | |
| 217 | −{ | |
| 218 | − struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | |
| 219 | − struct gpio_rcar_priv *p = gpiochip_get_data(gc); | |
| 220 | − int error; | |
| 221 | − | |
| 222 | − error = pm_runtime_get_sync(&p->pdev->dev); | |
| 223 | − if (error < 0) | |
| 224 | − return error; | |
| 225 | − | |
| 226 | − return 0; | |
| 227 | −} | |
| 228 | − | |
| 229 | −static void gpio_rcar_irq_release_resources(struct irq_data *d) | |
| 230 | −{ | |
| 231 | − struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | |
| 232 | − struct gpio_rcar_priv *p = gpiochip_get_data(gc); | |
| 233 | − | |
| 234 | − pm_runtime_put(&p->pdev->dev); | |
| 235 | −} | |
| 236 | − | |
| 237 | 199 | static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id) |
| 238 | 200 | { |
| 239 | 201 | struct gpio_rcar_priv *p = dev_id; |
| @@ -280,32 +242,18 @@ static void gpio_rcar_config_general_input_output_mode(struct gpio_chip *chip, · 40 unmodified lines | ||
| 280 | 242 | |
| 281 | 243 | static int gpio_rcar_request(struct gpio_chip *chip, unsigned offset) |
| 282 | 244 | { |
| 283 | − struct gpio_rcar_priv *p = gpiochip_get_data(chip); | |
| 284 | − int error; | |
| 285 | − | |
| 286 | − error = pm_runtime_get_sync(&p->pdev->dev); | |
| 287 | − if (error < 0) | |
| 288 | − return error; | |
| 289 | − | |
| 290 | − error = pinctrl_request_gpio(chip->base + offset); | |
| 291 | − if (error) | |
| 292 | − pm_runtime_put(&p->pdev->dev); | |
| 293 | − | |
| 294 | − return error; | |
| 245 | + return pinctrl_request_gpio(chip->base + offset); | |
| 295 | 246 | } |
| 296 | 247 | |
| 297 | 248 | static void gpio_rcar_free(struct gpio_chip *chip, unsigned offset) |
| 298 | 249 | { |
| 299 | − struct gpio_rcar_priv *p = gpiochip_get_data(chip); | |
| 300 | − | |
| 301 | 250 | pinctrl_free_gpio(chip->base + offset); |
| 302 | 251 | |
| 303 | − /* Set the GPIO as an input to ensure that the next GPIO request won't | |
| 252 | + /* | |
| 253 | + * Set the GPIO as an input to ensure that the next GPIO request won't | |
| 304 | 254 | * drive the GPIO pin as an output. |
| 305 | 255 | */ |
| 306 | 256 | gpio_rcar_config_general_input_output_mode(chip, offset, false); |
| 307 | − | |
| 308 | − pm_runtime_put(&p->pdev->dev); | |
| 309 | 257 | } |
| 310 | 258 | |
| 311 | 259 | static int gpio_rcar_direction_input(struct gpio_chip *chip, unsigned offset) |
| @@ -452,6 +400,7 @@ static int gpio_rcar_probe(struct platform_device *pdev) · 140 unmodified lines | ||
| 452 | 400 | } |
| 453 | 401 | |
| 454 | 402 | pm_runtime_enable(dev); |
| 403 | + pm_runtime_get_sync(dev); | |
| 455 | 404 | |
| 456 | 405 | io = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 457 | 406 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
| @@ -488,10 +437,6 @@ static int gpio_rcar_probe(struct platform_device *pdev) · 30 unmodified lines | ||
| 488 | 437 | irq_chip->irq_unmask = gpio_rcar_irq_enable; |
| 489 | 438 | irq_chip->irq_set_type = gpio_rcar_irq_set_type; |
| 490 | 439 | irq_chip->irq_set_wake = gpio_rcar_irq_set_wake; |
| 491 | − irq_chip->irq_bus_lock = gpio_rcar_irq_bus_lock; | |
| 492 | − irq_chip->irq_bus_sync_unlock = gpio_rcar_irq_bus_sync_unlock; | |
| 493 | − irq_chip->irq_request_resources = gpio_rcar_irq_request_resources; | |
| 494 | − irq_chip->irq_release_resources = gpio_rcar_irq_release_resources; | |
| 495 | 440 | irq_chip->flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND; |
| 496 | 441 | |
| 497 | 442 | ret = gpiochip_add_data(gpio_chip, p); |
| @@ -522,6 +467,7 @@ static int gpio_rcar_probe(struct platform_device *pdev) · 24 unmodified lines | ||
| 522 | 467 | err1: |
| 523 | 468 | gpiochip_remove(gpio_chip); |
| 524 | 469 | err0: |
| 470 | + pm_runtime_put(dev); | |
| 525 | 471 | pm_runtime_disable(dev); |
| 526 | 472 | return ret; |
| 527 | 473 | } |
| @@ -532,6 +478,7 @@ static int gpio_rcar_remove(struct platform_device *pdev) · 4 unmodified lines | ||
| 532 | 478 | |
| 533 | 479 | gpiochip_remove(&p->gpio_chip); |
| 534 | 480 | |
| 481 | + pm_runtime_put(&pdev->dev); | |
| 535 | 482 | pm_runtime_disable(&pdev->dev); |
| 536 | 483 | return 0; |
| 537 | 484 | } |
| @@ -977,7 +977,7 @@ bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id) · 976 unmodified lines | ||
| 977 | 977 | lookup = kmalloc(sizeof(*lookup), GFP_KERNEL); |
| 978 | 978 | if (lookup) { |
| 979 | 979 | lookup->adev = adev; |
| 980 | − lookup->con_id = con_id; | |
| 980 | + lookup->con_id = kstrdup(con_id, GFP_KERNEL); | |
| 981 | 981 | list_add_tail(&lookup->node, &acpi_crs_lookup_list); |
| 982 | 982 | } |
| 983 | 983 | } |
| @@ -63,10 +63,6 @@ bool amdgpu_has_atpx(void) { · 62 unmodified lines | ||
| 63 | 63 | return amdgpu_atpx_priv.atpx_detected; |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | −bool amdgpu_has_atpx_dgpu_power_cntl(void) { | |
| 67 | − return amdgpu_atpx_priv.atpx.functions.power_cntl; | |
| 68 | −} | |
| 69 | − | |
| 70 | 66 | /** |
| 71 | 67 | * amdgpu_atpx_call - call an ATPX method |
| 72 | 68 | * |
| @@ -146,6 +142,13 @@ static void amdgpu_atpx_parse_functions(struct amdgpu_atpx_functions *f, u32 mas · 73 unmodified lines | ||
| 146 | 142 | */ |
| 147 | 143 | static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) |
| 148 | 144 | { |
| 145 | + /* make sure required functions are enabled */ | |
| 146 | + /* dGPU power control is required */ | |
| 147 | + if (atpx->functions.power_cntl == false) { | |
| 148 | + printk("ATPX dGPU power cntl not present, forcing\n"); | |
| 149 | + atpx->functions.power_cntl = true; | |
| 150 | + } | |
| 151 | + | |
| 149 | 152 | if (atpx->functions.px_params) { |
| 150 | 153 | union acpi_object *info; |
| 151 | 154 | struct atpx_px_params output; |
| @@ -62,12 +62,6 @@ static const char *amdgpu_asic_name[] = { · 61 unmodified lines | ||
| 62 | 62 | "LAST", |
| 63 | 63 | }; |
| 64 | 64 | |
| 65 | −#if defined(CONFIG_VGA_SWITCHEROO) | |
| 66 | −bool amdgpu_has_atpx_dgpu_power_cntl(void); | |
| 67 | −#else | |
| 68 | −static inline bool amdgpu_has_atpx_dgpu_power_cntl(void) { return false; } | |
| 69 | −#endif | |
| 70 | − | |
| 71 | 65 | bool amdgpu_device_is_px(struct drm_device *dev) |
| 72 | 66 | { |
| 73 | 67 | struct amdgpu_device *adev = dev->dev_private; |
| @@ -1485,7 +1479,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, · 1411 unmodified lines | ||
| 1485 | 1479 | |
| 1486 | 1480 | if (amdgpu_runtime_pm == 1) |
| 1487 | 1481 | runtime = true; |
| 1488 | − if (amdgpu_device_is_px(ddev) && amdgpu_has_atpx_dgpu_power_cntl()) | |
| 1482 | + if (amdgpu_device_is_px(ddev)) | |
| 1489 | 1483 | runtime = true; |
| 1490 | 1484 | vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, runtime); |
| 1491 | 1485 | if (runtime) |
| @@ -541,6 +541,7 @@ int amdgpu_bo_set_metadata (struct amdgpu_bo *bo, void *metadata, · 540 unmodified lines | ||
| 541 | 541 | if (!metadata_size) { |
| 542 | 542 | if (bo->metadata_size) { |
| 543 | 543 | kfree(bo->metadata); |
| 544 | + bo->metadata = NULL; | |
| 544 | 545 | bo->metadata_size = 0; |
| 545 | 546 | } |
| 546 | 547 | return 0; |
| @@ -298,6 +298,10 @@ bool amdgpu_atombios_encoder_mode_fixup(struct drm_encoder *encoder, · 297 unmodified lines | ||
| 298 | 298 | && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) |
| 299 | 299 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; |
| 300 | 300 | |
| 301 | + /* vertical FP must be at least 1 */ | |
| 302 | + if (mode->crtc_vsync_start == mode->crtc_vdisplay) | |
| 303 | + adjusted_mode->crtc_vsync_start++; | |
| 304 | + | |
| 301 | 305 | /* get the native mode for scaling */ |
| 302 | 306 | if (amdgpu_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) |
| 303 | 307 | amdgpu_panel_mode_fixup(encoder, adjusted_mode); |
| @@ -910,7 +910,10 @@ static int gmc_v7_0_late_init(void *handle) · 909 unmodified lines | ||
| 910 | 910 | { |
| 911 | 911 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 912 | 912 | |
| 913 | − return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); | |
| 913 | + if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS) | |
| 914 | + return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); | |
| 915 | + else | |
| 916 | + return 0; | |
| 914 | 917 | } |
| 915 | 918 | |
| 916 | 919 | static int gmc_v7_0_sw_init(void *handle) |
| @@ -870,7 +870,10 @@ static int gmc_v8_0_late_init(void *handle) · 869 unmodified lines | ||
| 870 | 870 | { |
| 871 | 871 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 872 | 872 | |
| 873 | − return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); | |
| 873 | + if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS) | |
| 874 | + return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); | |
| 875 | + else | |
| 876 | + return 0; | |
| 874 | 877 | } |
| 875 | 878 | |
| 876 | 879 | #define mmMC_SEQ_MISC0_FIJI 0xA71 |
| @@ -1796,6 +1796,11 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) · 1795 unmodified lines | ||
| 1796 | 1796 | req_payload.start_slot = cur_slots; |
| 1797 | 1797 | if (mgr->proposed_vcpis[i]) { |
| 1798 | 1798 | port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi); |
| 1799 | + port = drm_dp_get_validated_port_ref(mgr, port); | |
| 1800 | + if (!port) { | |
| 1801 | + mutex_unlock(&mgr->payload_lock); | |
| 1802 | + return -EINVAL; | |
| 1803 | + } | |
| 1799 | 1804 | req_payload.num_slots = mgr->proposed_vcpis[i]->num_slots; |
| 1800 | 1805 | req_payload.vcpi = mgr->proposed_vcpis[i]->vcpi; |
| 1801 | 1806 | } else { |
| @@ -1823,6 +1828,9 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) · 21 unmodified lines | ||
| 1823 | 1828 | mgr->payloads[i].payload_state = req_payload.payload_state; |
| 1824 | 1829 | } |
| 1825 | 1830 | cur_slots += req_payload.num_slots; |
| 1831 | + | |
| 1832 | + if (port) | |
| 1833 | + drm_dp_put_port(port); | |
| 1826 | 1834 | } |
| 1827 | 1835 | |
| 1828 | 1836 | for (i = 0; i < mgr->max_payloads; i++) { |
| @@ -2128,6 +2136,8 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr) · 299 unmodified lines | ||
| 2128 | 2136 | |
| 2129 | 2137 | if (mgr->mst_primary) { |
| 2130 | 2138 | int sret; |
| 2139 | + u8 guid[16]; | |
| 2140 | + | |
| 2131 | 2141 | sret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE); |
| 2132 | 2142 | if (sret != DP_RECEIVER_CAP_SIZE) { |
| 2133 | 2143 | DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n"); |
| @@ -2142,6 +2152,16 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr) · 8 unmodified lines | ||
| 2142 | 2152 | ret = -1; |
| 2143 | 2153 | goto out_unlock; |
| 2144 | 2154 | } |
| 2155 | + | |
| 2156 | + /* Some hubs forget their guids after they resume */ | |
| 2157 | + sret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16); | |
| 2158 | + if (sret != 16) { | |
| 2159 | + DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n"); | |
| 2160 | + ret = -1; | |
| 2161 | + goto out_unlock; | |
| 2162 | + } | |
| 2163 | + drm_dp_check_mstb_guid(mgr->mst_primary, guid); | |
| 2164 | + | |
| 2145 | 2165 | ret = 0; |
| 2146 | 2166 | } else |
| 2147 | 2167 | ret = -1; |
| @@ -572,6 +572,24 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) · 571 unmodified lines | ||
| 572 | 572 | goto fail; |
| 573 | 573 | } |
| 574 | 574 | |
| 575 | + /* | |
| 576 | + * Set the GPU linear window to be at the end of the DMA window, where | |
| 577 | + * the CMA area is likely to reside. This ensures that we are able to | |
| 578 | + * map the command buffers while having the linear window overlap as | |
| 579 | + * much RAM as possible, so we can optimize mappings for other buffers. | |
| 580 | + * | |
| 581 | + * For 3D cores only do this if MC2.0 is present, as with MC1.0 it leads | |
| 582 | + * to different views of the memory on the individual engines. | |
| 583 | + */ | |
| 584 | + if (!(gpu->identity.features & chipFeatures_PIPE_3D) || | |
| 585 | + (gpu->identity.minor_features0 & chipMinorFeatures0_MC20)) { | |
| 586 | + u32 dma_mask = (u32)dma_get_required_mask(gpu->dev); | |
| 587 | + if (dma_mask < PHYS_OFFSET + SZ_2G) | |
| 588 | + gpu->memory_base = PHYS_OFFSET; | |
| 589 | + else | |
| 590 | + gpu->memory_base = dma_mask - SZ_2G + 1; | |
| 591 | + } | |
| 592 | + | |
| 575 | 593 | ret = etnaviv_hw_reset(gpu); |
| 576 | 594 | if (ret) |
| 577 | 595 | goto fail; |
| @@ -1566,7 +1584,6 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev) · 988 unmodified lines | ||
| 1566 | 1584 | { |
| 1567 | 1585 | struct device *dev = &pdev->dev; |
| 1568 | 1586 | struct etnaviv_gpu *gpu; |
| 1569 | − u32 dma_mask; | |
| 1570 | 1587 | int err = 0; |
| 1571 | 1588 | |
| 1572 | 1589 | gpu = devm_kzalloc(dev, sizeof(*gpu), GFP_KERNEL); |
| @@ -1576,18 +1593,6 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 1576 | 1593 | gpu->dev = &pdev->dev; |
| 1577 | 1594 | mutex_init(&gpu->lock); |
| 1578 | 1595 | |
| 1579 | − /* | |
| 1580 | − * Set the GPU linear window to be at the end of the DMA window, where | |
| 1581 | − * the CMA area is likely to reside. This ensures that we are able to | |
| 1582 | − * map the command buffers while having the linear window overlap as | |
| 1583 | − * much RAM as possible, so we can optimize mappings for other buffers. | |
| 1584 | − */ | |
| 1585 | − dma_mask = (u32)dma_get_required_mask(dev); | |
| 1586 | − if (dma_mask < PHYS_OFFSET + SZ_2G) | |
| 1587 | − gpu->memory_base = PHYS_OFFSET; | |
| 1588 | − else | |
| 1589 | − gpu->memory_base = dma_mask - SZ_2G + 1; | |
| 1590 | − | |
| 1591 | 1596 | /* Map registers: */ |
| 1592 | 1597 | gpu->mmio = etnaviv_ioremap(pdev, NULL, dev_name(gpu->dev)); |
| 1593 | 1598 | if (IS_ERR(gpu->mmio)) |
| @@ -792,7 +792,7 @@ static int i915_drm_resume(struct drm_device *dev) · 791 unmodified lines | ||
| 792 | 792 | static int i915_drm_resume_early(struct drm_device *dev) |
| 793 | 793 | { |
| 794 | 794 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 795 | − int ret = 0; | |
| 795 | + int ret; | |
| 796 | 796 | |
| 797 | 797 | /* |
| 798 | 798 | * We have a resume ordering issue with the snd-hda driver also |
| @@ -803,6 +803,36 @@ static int i915_drm_resume_early(struct drm_device *dev) · 4 unmodified lines | ||
| 803 | 803 | * FIXME: This should be solved with a special hdmi sink device or |
| 804 | 804 | * similar so that power domains can be employed. |
| 805 | 805 | */ |
| 806 | + | |
| 807 | + /* | |
| 808 | + * Note that we need to set the power state explicitly, since we | |
| 809 | + * powered off the device during freeze and the PCI core won't power | |
| 810 | + * it back up for us during thaw. Powering off the device during | |
| 811 | + * freeze is not a hard requirement though, and during the | |
| 812 | + * suspend/resume phases the PCI core makes sure we get here with the | |
| 813 | + * device powered on. So in case we change our freeze logic and keep | |
| 814 | + * the device powered we can also remove the following set power state | |
| 815 | + * call. | |
| 816 | + */ | |
| 817 | + ret = pci_set_power_state(dev->pdev, PCI_D0); | |
| 818 | + if (ret) { | |
| 819 | + DRM_ERROR("failed to set PCI D0 power state (%d)\n", ret); | |
| 820 | + goto out; | |
| 821 | + } | |
| 822 | + | |
| 823 | + /* | |
| 824 | + * Note that pci_enable_device() first enables any parent bridge | |
| 825 | + * device and only then sets the power state for this device. The | |
| 826 | + * bridge enabling is a nop though, since bridge devices are resumed | |
| 827 | + * first. The order of enabling power and enabling the device is | |
| 828 | + * imposed by the PCI core as described above, so here we preserve the | |
| 829 | + * same order for the freeze/thaw phases. | |
| 830 | + * | |
| 831 | + * TODO: eventually we should remove pci_disable_device() / | |
| 832 | + * pci_enable_enable_device() from suspend/resume. Due to how they | |
| 833 | + * depend on the device enable refcount we can't anyway depend on them | |
| 834 | + * disabling/enabling the device. | |
| 835 | + */ | |
| 806 | 836 | if (pci_enable_device(dev->pdev)) { |
| 807 | 837 | ret = -EIO; |
| 808 | 838 | goto out; |
| @@ -2907,7 +2907,14 @@ enum skl_disp_power_wells { · 2906 unmodified lines | ||
| 2907 | 2907 | #define GEN6_RP_STATE_CAP _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5998) |
| 2908 | 2908 | #define BXT_RP_STATE_CAP _MMIO(0x138170) |
| 2909 | 2909 | |
| 2910 | −#define INTERVAL_1_28_US(us) (((us) * 100) >> 7) | |
| 2910 | +/* | |
| 2911 | + * Make these a multiple of magic 25 to avoid SNB (eg. Dell XPS | |
| 2912 | + * 8300) freezing up around GPU hangs. Looks as if even | |
| 2913 | + * scheduling/timer interrupts start misbehaving if the RPS | |
| 2914 | + * EI/thresholds are "bad", leading to a very sluggish or even | |
| 2915 | + * frozen machine. | |
| 2916 | + */ | |
| 2917 | +#define INTERVAL_1_28_US(us) roundup(((us) * 100) >> 7, 25) | |
| 2911 | 2918 | #define INTERVAL_1_33_US(us) (((us) * 3) >> 2) |
| 2912 | 2919 | #define INTERVAL_0_833_US(us) (((us) * 6) / 5) |
| 2913 | 2920 | #define GT_INTERVAL_FROM_US(dev_priv, us) (IS_GEN9(dev_priv) ? \ |
| @@ -443,9 +443,17 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) · 442 unmodified lines | ||
| 443 | 443 | } else if (IS_BROADWELL(dev_priv)) { |
| 444 | 444 | ddi_translations_fdi = bdw_ddi_translations_fdi; |
| 445 | 445 | ddi_translations_dp = bdw_ddi_translations_dp; |
| 446 | − ddi_translations_edp = bdw_ddi_translations_edp; | |
| 446 | + | |
| 447 | + if (dev_priv->edp_low_vswing) { | |
| 448 | + ddi_translations_edp = bdw_ddi_translations_edp; | |
| 449 | + n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp); | |
| 450 | + } else { | |
| 451 | + ddi_translations_edp = bdw_ddi_translations_dp; | |
| 452 | + n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); | |
| 453 | + } | |
| 454 | + | |
| 447 | 455 | ddi_translations_hdmi = bdw_ddi_translations_hdmi; |
| 448 | − n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp); | |
| 456 | + | |
| 449 | 457 | n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); |
| 450 | 458 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); |
| 451 | 459 | hdmi_default_entry = 7; |
| @@ -3201,12 +3209,6 @@ void intel_ddi_get_config(struct intel_encoder *encoder, · 2749 unmodified lines | ||
| 3201 | 3209 | intel_ddi_clock_get(encoder, pipe_config); |
| 3202 | 3210 | } |
| 3203 | 3211 | |
| 3204 | −static void intel_ddi_destroy(struct drm_encoder *encoder) | |
| 3205 | −{ | |
| 3206 | − /* HDMI has nothing special to destroy, so we can go with this. */ | |
| 3207 | − intel_dp_encoder_destroy(encoder); | |
| 3208 | −} | |
| 3209 | − | |
| 3210 | 3212 | static bool intel_ddi_compute_config(struct intel_encoder *encoder, |
| 3211 | 3213 | struct intel_crtc_state *pipe_config) |
| 3212 | 3214 | { |
| @@ -3225,7 +3227,8 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder, · 12 unmodified lines | ||
| 3225 | 3227 | } |
| 3226 | 3228 | |
| 3227 | 3229 | static const struct drm_encoder_funcs intel_ddi_funcs = { |
| 3228 | − .destroy = intel_ddi_destroy, | |
| 3230 | + .reset = intel_dp_encoder_reset, | |
| 3231 | + .destroy = intel_dp_encoder_destroy, | |
| 3229 | 3232 | }; |
| 3230 | 3233 | |
| 3231 | 3234 | static struct intel_connector * |
| @@ -3324,6 +3327,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port) · 92 unmodified lines | ||
| 3324 | 3327 | intel_encoder->post_disable = intel_ddi_post_disable; |
| 3325 | 3328 | intel_encoder->get_hw_state = intel_ddi_get_hw_state; |
| 3326 | 3329 | intel_encoder->get_config = intel_ddi_get_config; |
| 3330 | + intel_encoder->suspend = intel_dp_encoder_suspend; | |
| 3327 | 3331 | |
| 3328 | 3332 | intel_dig_port->port = port; |
| 3329 | 3333 | intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & |
| @@ -13351,6 +13351,9 @@ static int intel_atomic_prepare_commit(struct drm_device *dev, · 13350 unmodified lines | ||
| 13351 | 13351 | } |
| 13352 | 13352 | |
| 13353 | 13353 | for_each_crtc_in_state(state, crtc, crtc_state, i) { |
| 13354 | + if (state->legacy_cursor_update) | |
| 13355 | + continue; | |
| 13356 | + | |
| 13354 | 13357 | ret = intel_crtc_wait_for_pending_flips(crtc); |
| 13355 | 13358 | if (ret) |
| 13356 | 13359 | return ret; |
| @@ -4898,7 +4898,7 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder) · 4897 unmodified lines | ||
| 4898 | 4898 | kfree(intel_dig_port); |
| 4899 | 4899 | } |
| 4900 | 4900 | |
| 4901 | −static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder) | |
| 4901 | +void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder) | |
| 4902 | 4902 | { |
| 4903 | 4903 | struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base); |
| 4904 | 4904 | |
| @@ -4940,7 +4940,7 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp) · 35 unmodified lines | ||
| 4940 | 4940 | edp_panel_vdd_schedule_off(intel_dp); |
| 4941 | 4941 | } |
| 4942 | 4942 | |
| 4943 | −static void intel_dp_encoder_reset(struct drm_encoder *encoder) | |
| 4943 | +void intel_dp_encoder_reset(struct drm_encoder *encoder) | |
| 4944 | 4944 | { |
| 4945 | 4945 | struct intel_dp *intel_dp; |
| 4946 | 4946 | |
| @@ -1238,6 +1238,8 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp, · 1237 unmodified lines | ||
| 1238 | 1238 | void intel_dp_start_link_train(struct intel_dp *intel_dp); |
| 1239 | 1239 | void intel_dp_stop_link_train(struct intel_dp *intel_dp); |
| 1240 | 1240 | void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode); |
| 1241 | +void intel_dp_encoder_reset(struct drm_encoder *encoder); | |
| 1242 | +void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder); | |
| 1241 | 1243 | void intel_dp_encoder_destroy(struct drm_encoder *encoder); |
| 1242 | 1244 | int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc); |
| 1243 | 1245 | bool intel_dp_compute_config(struct intel_encoder *encoder, |
| @@ -1415,8 +1415,16 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) · 1414 unmodified lines | ||
| 1415 | 1415 | hdmi_to_dig_port(intel_hdmi)); |
| 1416 | 1416 | } |
| 1417 | 1417 | |
| 1418 | − if (!live_status) | |
| 1419 | − DRM_DEBUG_KMS("Live status not up!"); | |
| 1418 | + if (!live_status) { | |
| 1419 | + DRM_DEBUG_KMS("HDMI live status down\n"); | |
| 1420 | + /* | |
| 1421 | + * Live status register is not reliable on all intel platforms. | |
| 1422 | + * So consider live_status only for certain platforms, for | |
| 1423 | + * others, read EDID to determine presence of sink. | |
| 1424 | + */ | |
| 1425 | + if (INTEL_INFO(dev_priv)->gen < 7 || IS_IVYBRIDGE(dev_priv)) | |
| 1426 | + live_status = true; | |
| 1427 | + } | |
| 1420 | 1428 | |
| 1421 | 1429 | intel_hdmi_unset_edid(connector); |
| 1422 | 1430 | |
| @@ -310,6 +310,10 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, · 309 unmodified lines | ||
| 310 | 310 | && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) |
| 311 | 311 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; |
| 312 | 312 | |
| 313 | + /* vertical FP must be at least 1 */ | |
| 314 | + if (mode->crtc_vsync_start == mode->crtc_vdisplay) | |
| 315 | + adjusted_mode->crtc_vsync_start++; | |
| 316 | + | |
| 313 | 317 | /* get the native mode for scaling */ |
| 314 | 318 | if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { |
| 315 | 319 | radeon_panel_mode_fixup(encoder, adjusted_mode); |
| @@ -2608,10 +2608,152 @@ static void evergreen_agp_enable(struct radeon_device *rdev) · 2607 unmodified lines | ||
| 2608 | 2608 | WREG32(VM_CONTEXT1_CNTL, 0); |
| 2609 | 2609 | } |
| 2610 | 2610 | |
| 2611 | +static const unsigned ni_dig_offsets[] = | |
| 2612 | +{ | |
| 2613 | + NI_DIG0_REGISTER_OFFSET, | |
| 2614 | + NI_DIG1_REGISTER_OFFSET, | |
| 2615 | + NI_DIG2_REGISTER_OFFSET, | |
| 2616 | + NI_DIG3_REGISTER_OFFSET, | |
| 2617 | + NI_DIG4_REGISTER_OFFSET, | |
| 2618 | + NI_DIG5_REGISTER_OFFSET | |
| 2619 | +}; | |
| 2620 | + | |
| 2621 | +static const unsigned ni_tx_offsets[] = | |
| 2622 | +{ | |
| 2623 | + NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1, | |
| 2624 | + NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1, | |
| 2625 | + NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1, | |
| 2626 | + NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1, | |
| 2627 | + NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1, | |
| 2628 | + NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1 | |
| 2629 | +}; | |
| 2630 | + | |
| 2631 | +static const unsigned evergreen_dp_offsets[] = | |
| 2632 | +{ | |
| 2633 | + EVERGREEN_DP0_REGISTER_OFFSET, | |
| 2634 | + EVERGREEN_DP1_REGISTER_OFFSET, | |
| 2635 | + EVERGREEN_DP2_REGISTER_OFFSET, | |
| 2636 | + EVERGREEN_DP3_REGISTER_OFFSET, | |
| 2637 | + EVERGREEN_DP4_REGISTER_OFFSET, | |
| 2638 | + EVERGREEN_DP5_REGISTER_OFFSET | |
| 2639 | +}; | |
| 2640 | + | |
| 2641 | + | |
| 2642 | +/* | |
| 2643 | + * Assumption is that EVERGREEN_CRTC_MASTER_EN enable for requested crtc | |
| 2644 | + * We go from crtc to connector and it is not relible since it | |
| 2645 | + * should be an opposite direction .If crtc is enable then | |
| 2646 | + * find the dig_fe which selects this crtc and insure that it enable. | |
| 2647 | + * if such dig_fe is found then find dig_be which selects found dig_be and | |
| 2648 | + * insure that it enable and in DP_SST mode. | |
| 2649 | + * if UNIPHY_PLL_CONTROL1.enable then we should disconnect timing | |
| 2650 | + * from dp symbols clocks . | |
| 2651 | + */ | |
| 2652 | +static bool evergreen_is_dp_sst_stream_enabled(struct radeon_device *rdev, | |
| 2653 | + unsigned crtc_id, unsigned *ret_dig_fe) | |
| 2654 | +{ | |
| 2655 | + unsigned i; | |
| 2656 | + unsigned dig_fe; | |
| 2657 | + unsigned dig_be; | |
| 2658 | + unsigned dig_en_be; | |
| 2659 | + unsigned uniphy_pll; | |
| 2660 | + unsigned digs_fe_selected; | |
| 2661 | + unsigned dig_be_mode; | |
| 2662 | + unsigned dig_fe_mask; | |
| 2663 | + bool is_enabled = false; | |
| 2664 | + bool found_crtc = false; | |
| 2665 | + | |
| 2666 | + /* loop through all running dig_fe to find selected crtc */ | |
| 2667 | + for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) { | |
| 2668 | + dig_fe = RREG32(NI_DIG_FE_CNTL + ni_dig_offsets[i]); | |
| 2669 | + if (dig_fe & NI_DIG_FE_CNTL_SYMCLK_FE_ON && | |
| 2670 | + crtc_id == NI_DIG_FE_CNTL_SOURCE_SELECT(dig_fe)) { | |
| 2671 | + /* found running pipe */ | |
| 2672 | + found_crtc = true; | |
| 2673 | + dig_fe_mask = 1 << i; | |
| 2674 | + dig_fe = i; | |
| 2675 | + break; | |
| 2676 | + } | |
| 2677 | + } | |
| 2678 | + | |
| 2679 | + if (found_crtc) { | |
| 2680 | + /* loop through all running dig_be to find selected dig_fe */ | |
| 2681 | + for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) { | |
| 2682 | + dig_be = RREG32(NI_DIG_BE_CNTL + ni_dig_offsets[i]); | |
| 2683 | + /* if dig_fe_selected by dig_be? */ | |
| 2684 | + digs_fe_selected = NI_DIG_BE_CNTL_FE_SOURCE_SELECT(dig_be); | |
| 2685 | + dig_be_mode = NI_DIG_FE_CNTL_MODE(dig_be); | |
| 2686 | + if (dig_fe_mask & digs_fe_selected && | |
| 2687 | + /* if dig_be in sst mode? */ | |
| 2688 | + dig_be_mode == NI_DIG_BE_DPSST) { | |
| 2689 | + dig_en_be = RREG32(NI_DIG_BE_EN_CNTL + | |
| 2690 | + ni_dig_offsets[i]); | |
| 2691 | + uniphy_pll = RREG32(NI_DCIO_UNIPHY0_PLL_CONTROL1 + | |
| 2692 | + ni_tx_offsets[i]); | |
| 2693 | + /* dig_be enable and tx is running */ | |
| 2694 | + if (dig_en_be & NI_DIG_BE_EN_CNTL_ENABLE && | |
| 2695 | + dig_en_be & NI_DIG_BE_EN_CNTL_SYMBCLK_ON && | |
| 2696 | + uniphy_pll & NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE) { | |
| 2697 | + is_enabled = true; | |
| 2698 | + *ret_dig_fe = dig_fe; | |
| 2699 | + break; | |
| 2700 | + } | |
| 2701 | + } | |
| 2702 | + } | |
| 2703 | + } | |
| 2704 | + | |
| 2705 | + return is_enabled; | |
| 2706 | +} | |
| 2707 | + | |
| 2708 | +/* | |
| 2709 | + * Blank dig when in dp sst mode | |
| 2710 | + * Dig ignores crtc timing | |
| 2711 | + */ | |
| 2712 | +static void evergreen_blank_dp_output(struct radeon_device *rdev, | |
| 2713 | + unsigned dig_fe) | |
| 2714 | +{ | |
| 2715 | + unsigned stream_ctrl; | |
| 2716 | + unsigned fifo_ctrl; | |
| 2717 | + unsigned counter = 0; | |
| 2718 | + | |
| 2719 | + if (dig_fe >= ARRAY_SIZE(evergreen_dp_offsets)) { | |
| 2720 | + DRM_ERROR("invalid dig_fe %d\n", dig_fe); | |
| 2721 | + return; | |
| 2722 | + } | |
| 2723 | + | |
| 2724 | + stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + | |
| 2725 | + evergreen_dp_offsets[dig_fe]); | |
| 2726 | + if (!(stream_ctrl & EVERGREEN_DP_VID_STREAM_CNTL_ENABLE)) { | |
| 2727 | + DRM_ERROR("dig %d , should be enable\n", dig_fe); | |
| 2728 | + return; | |
| 2729 | + } | |
| 2730 | + | |
| 2731 | + stream_ctrl &=~EVERGREEN_DP_VID_STREAM_CNTL_ENABLE; | |
| 2732 | + WREG32(EVERGREEN_DP_VID_STREAM_CNTL + | |
| 2733 | + evergreen_dp_offsets[dig_fe], stream_ctrl); | |
| 2734 | + | |
| 2735 | + stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + | |
| 2736 | + evergreen_dp_offsets[dig_fe]); | |
| 2737 | + while (counter < 32 && stream_ctrl & EVERGREEN_DP_VID_STREAM_STATUS) { | |
| 2738 | + msleep(1); | |
| 2739 | + counter++; | |
| 2740 | + stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + | |
| 2741 | + evergreen_dp_offsets[dig_fe]); | |
| 2742 | + } | |
| 2743 | + if (counter >= 32 ) | |
| 2744 | + DRM_ERROR("counter exceeds %d\n", counter); | |
| 2745 | + | |
| 2746 | + fifo_ctrl = RREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe]); | |
| 2747 | + fifo_ctrl |= EVERGREEN_DP_STEER_FIFO_RESET; | |
| 2748 | + WREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe], fifo_ctrl); | |
| 2749 | + | |
| 2750 | +} | |
| 2751 | + | |
| 2611 | 2752 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) |
| 2612 | 2753 | { |
| 2613 | 2754 | u32 crtc_enabled, tmp, frame_count, blackout; |
| 2614 | 2755 | int i, j; |
| 2756 | + unsigned dig_fe; | |
| 2615 | 2757 | |
| 2616 | 2758 | if (!ASIC_IS_NODCE(rdev)) { |
| 2617 | 2759 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); |
| @@ -2651,7 +2793,17 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav · 33 unmodified lines | ||
| 2651 | 2793 | break; |
| 2652 | 2794 | udelay(1); |
| 2653 | 2795 | } |
| 2654 | − | |
| 2796 | + /*we should disable dig if it drives dp sst*/ | |
| 2797 | + /*but we are in radeon_device_init and the topology is unknown*/ | |
| 2798 | + /*and it is available after radeon_modeset_init*/ | |
| 2799 | + /*the following method radeon_atom_encoder_dpms_dig*/ | |
| 2800 | + /*does the job if we initialize it properly*/ | |
| 2801 | + /*for now we do it this manually*/ | |
| 2802 | + /**/ | |
| 2803 | + if (ASIC_IS_DCE5(rdev) && | |
| 2804 | + evergreen_is_dp_sst_stream_enabled(rdev, i ,&dig_fe)) | |
| 2805 | + evergreen_blank_dp_output(rdev, dig_fe); | |
| 2806 | + /*we could remove 6 lines below*/ | |
| 2655 | 2807 | /* XXX this is a hack to avoid strange behavior with EFI on certain systems */ |
| 2656 | 2808 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); |
| 2657 | 2809 | tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); |
| @@ -250,8 +250,43 @@ · 249 unmodified lines | ||
| 250 | 250 | |
| 251 | 251 | /* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */ |
| 252 | 252 | #define EVERGREEN_HDMI_BASE 0x7030 |
| 253 | +/*DIG block*/ | |
| 254 | +#define NI_DIG0_REGISTER_OFFSET (0x7000 - 0x7000) | |
| 255 | +#define NI_DIG1_REGISTER_OFFSET (0x7C00 - 0x7000) | |
| 256 | +#define NI_DIG2_REGISTER_OFFSET (0x10800 - 0x7000) | |
| 257 | +#define NI_DIG3_REGISTER_OFFSET (0x11400 - 0x7000) | |
| 258 | +#define NI_DIG4_REGISTER_OFFSET (0x12000 - 0x7000) | |
| 259 | +#define NI_DIG5_REGISTER_OFFSET (0x12C00 - 0x7000) | |
| 260 | + | |
| 261 | + | |
| 262 | +#define NI_DIG_FE_CNTL 0x7000 | |
| 263 | +# define NI_DIG_FE_CNTL_SOURCE_SELECT(x) ((x) & 0x3) | |
| 264 | +# define NI_DIG_FE_CNTL_SYMCLK_FE_ON (1<<24) | |
| 265 | + | |
| 266 | + | |
| 267 | +#define NI_DIG_BE_CNTL 0x7140 | |
| 268 | +# define NI_DIG_BE_CNTL_FE_SOURCE_SELECT(x) (((x) >> 8 ) & 0x3F) | |
| 269 | +# define NI_DIG_FE_CNTL_MODE(x) (((x) >> 16) & 0x7 ) | |
| 270 | + | |
| 271 | +#define NI_DIG_BE_EN_CNTL 0x7144 | |
| 272 | +# define NI_DIG_BE_EN_CNTL_ENABLE (1 << 0) | |
| 273 | +# define NI_DIG_BE_EN_CNTL_SYMBCLK_ON (1 << 8) | |
| 274 | +# define NI_DIG_BE_DPSST 0 | |
| 253 | 275 | |
| 254 | 276 | /* Display Port block */ |
| 277 | +#define EVERGREEN_DP0_REGISTER_OFFSET (0x730C - 0x730C) | |
| 278 | +#define EVERGREEN_DP1_REGISTER_OFFSET (0x7F0C - 0x730C) | |
| 279 | +#define EVERGREEN_DP2_REGISTER_OFFSET (0x10B0C - 0x730C) | |
| 280 | +#define EVERGREEN_DP3_REGISTER_OFFSET (0x1170C - 0x730C) | |
| 281 | +#define EVERGREEN_DP4_REGISTER_OFFSET (0x1230C - 0x730C) | |
| 282 | +#define EVERGREEN_DP5_REGISTER_OFFSET (0x12F0C - 0x730C) | |
| 283 | + | |
| 284 | + | |
| 285 | +#define EVERGREEN_DP_VID_STREAM_CNTL 0x730C | |
| 286 | +# define EVERGREEN_DP_VID_STREAM_CNTL_ENABLE (1 << 0) | |
| 287 | +# define EVERGREEN_DP_VID_STREAM_STATUS (1 <<16) | |
| 288 | +#define EVERGREEN_DP_STEER_FIFO 0x7310 | |
| 289 | +# define EVERGREEN_DP_STEER_FIFO_RESET (1 << 0) | |
| 255 | 290 | #define EVERGREEN_DP_SEC_CNTL 0x7280 |
| 256 | 291 | # define EVERGREEN_DP_SEC_STREAM_ENABLE (1 << 0) |
| 257 | 292 | # define EVERGREEN_DP_SEC_ASP_ENABLE (1 << 4) |
| @@ -266,4 +301,15 @@ · 8 unmodified lines | ||
| 266 | 301 | # define EVERGREEN_DP_SEC_N_BASE_MULTIPLE(x) (((x) & 0xf) << 24) |
| 267 | 302 | # define EVERGREEN_DP_SEC_SS_EN (1 << 28) |
| 268 | 303 | |
| 304 | +/*DCIO_UNIPHY block*/ | |
| 305 | +#define NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1 (0x6600 -0x6600) | |
| 306 | +#define NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1 (0x6640 -0x6600) | |
| 307 | +#define NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1 (0x6680 - 0x6600) | |
| 308 | +#define NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1 (0x66C0 - 0x6600) | |
| 309 | +#define NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1 (0x6700 - 0x6600) | |
| 310 | +#define NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1 (0x6740 - 0x6600) | |
| 311 | + | |
| 312 | +#define NI_DCIO_UNIPHY0_PLL_CONTROL1 0x6618 | |
| 313 | +# define NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE (1 << 0) | |
| 314 | + | |
| 269 | 315 | #endif |
| @@ -230,22 +230,13 @@ EXPORT_SYMBOL(ttm_bo_del_sub_from_lru); · 229 unmodified lines | ||
| 230 | 230 | |
| 231 | 231 | void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo) |
| 232 | 232 | { |
| 233 | − struct ttm_bo_device *bdev = bo->bdev; | |
| 234 | − struct ttm_mem_type_manager *man; | |
| 233 | + int put_count = 0; | |
| 235 | 234 | |
| 236 | 235 | lockdep_assert_held(&bo->resv->lock.base); |
| 237 | 236 | |
| 238 | − if (bo->mem.placement & TTM_PL_FLAG_NO_EVICT) { | |
| 239 | − list_del_init(&bo->swap); | |
| 240 | − list_del_init(&bo->lru); | |
| 241 | − | |
| 242 | − } else { | |
| 243 | − if (bo->ttm && !(bo->ttm->page_flags & TTM_PAGE_FLAG_SG)) | |
| 244 | − list_move_tail(&bo->swap, &bo->glob->swap_lru); | |
| 245 | − | |
| 246 | − man = &bdev->man[bo->mem.mem_type]; | |
| 247 | − list_move_tail(&bo->lru, &man->lru); | |
| 248 | − } | |
| 237 | + put_count = ttm_bo_del_from_lru(bo); | |
| 238 | + ttm_bo_list_ref_sub(bo, put_count, true); | |
| 239 | + ttm_bo_add_to_lru(bo); | |
| 249 | 240 | } |
| 250 | 241 | EXPORT_SYMBOL(ttm_bo_move_to_lru_tail); |
| 251 | 242 | |
| @@ -267,11 +267,23 @@ static int virtio_gpu_crtc_atomic_check(struct drm_crtc *crtc, · 266 unmodified lines | ||
| 267 | 267 | return 0; |
| 268 | 268 | } |
| 269 | 269 | |
| 270 | +static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc, | |
| 271 | + struct drm_crtc_state *old_state) | |
| 272 | +{ | |
| 273 | + unsigned long flags; | |
| 274 | + | |
| 275 | + spin_lock_irqsave(&crtc->dev->event_lock, flags); | |
| 276 | + if (crtc->state->event) | |
| 277 | + drm_crtc_send_vblank_event(crtc, crtc->state->event); | |
| 278 | + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); | |
| 279 | +} | |
| 280 | + | |
| 270 | 281 | static const struct drm_crtc_helper_funcs virtio_gpu_crtc_helper_funcs = { |
| 271 | 282 | .enable = virtio_gpu_crtc_enable, |
| 272 | 283 | .disable = virtio_gpu_crtc_disable, |
| 273 | 284 | .mode_set_nofb = virtio_gpu_crtc_mode_set_nofb, |
| 274 | 285 | .atomic_check = virtio_gpu_crtc_atomic_check, |
| 286 | + .atomic_flush = virtio_gpu_crtc_atomic_flush, | |
| 275 | 287 | }; |
| 276 | 288 | |
| 277 | 289 | static void virtio_gpu_enc_mode_set(struct drm_encoder *encoder, |
| @@ -3293,19 +3293,19 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { · 3292 unmodified lines | ||
| 3293 | 3293 | &vmw_cmd_dx_cid_check, true, false, true), |
| 3294 | 3294 | VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_QUERY, &vmw_cmd_dx_define_query, |
| 3295 | 3295 | true, false, true), |
| 3296 | − VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_QUERY, &vmw_cmd_ok, | |
| 3296 | + VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_QUERY, &vmw_cmd_dx_cid_check, | |
| 3297 | 3297 | true, false, true), |
| 3298 | 3298 | VMW_CMD_DEF(SVGA_3D_CMD_DX_BIND_QUERY, &vmw_cmd_dx_bind_query, |
| 3299 | 3299 | true, false, true), |
| 3300 | 3300 | VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_QUERY_OFFSET, |
| 3301 | − &vmw_cmd_ok, true, false, true), | |
| 3302 | − VMW_CMD_DEF(SVGA_3D_CMD_DX_BEGIN_QUERY, &vmw_cmd_ok, | |
| 3301 | + &vmw_cmd_dx_cid_check, true, false, true), | |
| 3302 | + VMW_CMD_DEF(SVGA_3D_CMD_DX_BEGIN_QUERY, &vmw_cmd_dx_cid_check, | |
| 3303 | 3303 | true, false, true), |
| 3304 | − VMW_CMD_DEF(SVGA_3D_CMD_DX_END_QUERY, &vmw_cmd_ok, | |
| 3304 | + VMW_CMD_DEF(SVGA_3D_CMD_DX_END_QUERY, &vmw_cmd_dx_cid_check, | |
| 3305 | 3305 | true, false, true), |
| 3306 | 3306 | VMW_CMD_DEF(SVGA_3D_CMD_DX_READBACK_QUERY, &vmw_cmd_invalid, |
| 3307 | 3307 | true, false, true), |
| 3308 | − VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_PREDICATION, &vmw_cmd_invalid, | |
| 3308 | + VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_PREDICATION, &vmw_cmd_dx_cid_check, | |
| 3309 | 3309 | true, false, true), |
| 3310 | 3310 | VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_VIEWPORTS, &vmw_cmd_dx_cid_check, |
| 3311 | 3311 | true, false, true), |
| @@ -573,9 +573,9 @@ static int vmw_fb_set_par(struct fb_info *info) · 572 unmodified lines | ||
| 573 | 573 | mode = old_mode; |
| 574 | 574 | old_mode = NULL; |
| 575 | 575 | } else if (!vmw_kms_validate_mode_vram(vmw_priv, |
| 576 | − mode->hdisplay * | |
| 577 | − (var->bits_per_pixel + 7) / 8, | |
| 578 | − mode->vdisplay)) { | |
| 576 | + mode->hdisplay * | |
| 577 | + DIV_ROUND_UP(var->bits_per_pixel, 8), | |
| 578 | + mode->vdisplay)) { | |
| 579 | 579 | drm_mode_destroy(vmw_priv->dev, mode); |
| 580 | 580 | return -EINVAL; |
| 581 | 581 | } |
| @@ -1068,7 +1068,6 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base) · 1067 unmodified lines | ||
| 1068 | 1068 | goto err_register; |
| 1069 | 1069 | } |
| 1070 | 1070 | |
| 1071 | − pdev->dev.of_node = of_node; | |
| 1072 | 1071 | pdev->dev.parent = dev; |
| 1073 | 1072 | |
| 1074 | 1073 | ret = platform_device_add_data(pdev, ®->pdata, |
| @@ -1079,6 +1078,12 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base) · 4 unmodified lines | ||
| 1079 | 1078 | platform_device_put(pdev); |
| 1080 | 1079 | goto err_register; |
| 1081 | 1080 | } |
| 1081 | + | |
| 1082 | + /* | |
| 1083 | + * Set of_node only after calling platform_device_add. Otherwise | |
| 1084 | + * the platform:imx-ipuv3-crtc modalias won't be used. | |
| 1085 | + */ | |
| 1086 | + pdev->dev.of_node = of_node; | |
| 1082 | 1087 | } |
| 1083 | 1088 | |
| 1084 | 1089 | return 0; |
| @@ -259,6 +259,7 @@ · 258 unmodified lines | ||
| 259 | 259 | #define USB_DEVICE_ID_CORSAIR_K90 0x1b02 |
| 260 | 260 | |
| 261 | 261 | #define USB_VENDOR_ID_CREATIVELABS 0x041e |
| 262 | +#define USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51 0x322c | |
| 262 | 263 | #define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801 |
| 263 | 264 | |
| 264 | 265 | #define USB_VENDOR_ID_CVTOUCH 0x1ff7 |
| @@ -71,6 +71,7 @@ static const struct hid_blacklist { · 70 unmodified lines | ||
| 71 | 71 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET }, |
| 72 | 72 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, |
| 73 | 73 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, |
| 74 | + { USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51, HID_QUIRK_NOGET }, | |
| 74 | 75 | { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, |
| 75 | 76 | { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT }, |
| 76 | 77 | { USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL }, |
| @@ -684,6 +684,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) · 683 unmodified lines | ||
| 684 | 684 | |
| 685 | 685 | wacom->tool[idx] = wacom_intuos_get_tool_type(wacom->id[idx]); |
| 686 | 686 | |
| 687 | + wacom->shared->stylus_in_proximity = true; | |
| 687 | 688 | return 1; |
| 688 | 689 | } |
| 689 | 690 | |
| @@ -3395,6 +3396,10 @@ static const struct wacom_features wacom_features_0x33E = · 2705 unmodified lines | ||
| 3395 | 3396 | { "Wacom Intuos PT M 2", 21600, 13500, 2047, 63, |
| 3396 | 3397 | INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16, |
| 3397 | 3398 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
| 3399 | +static const struct wacom_features wacom_features_0x343 = | |
| 3400 | + { "Wacom DTK1651", 34616, 19559, 1023, 0, | |
| 3401 | + DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4, | |
| 3402 | + WACOM_DTU_OFFSET, WACOM_DTU_OFFSET }; | |
| 3398 | 3403 | |
| 3399 | 3404 | static const struct wacom_features wacom_features_HID_ANY_ID = |
| 3400 | 3405 | { "Wacom HID", .type = HID_GENERIC }; |
| @@ -3560,6 +3565,7 @@ const struct hid_device_id wacom_ids[] = { · 159 unmodified lines | ||
| 3560 | 3565 | { USB_DEVICE_WACOM(0x33C) }, |
| 3561 | 3566 | { USB_DEVICE_WACOM(0x33D) }, |
| 3562 | 3567 | { USB_DEVICE_WACOM(0x33E) }, |
| 3568 | + { USB_DEVICE_WACOM(0x343) }, | |
| 3563 | 3569 | { USB_DEVICE_WACOM(0x4001) }, |
| 3564 | 3570 | { USB_DEVICE_WACOM(0x4004) }, |
| 3565 | 3571 | { USB_DEVICE_WACOM(0x5000) }, |
| @@ -103,15 +103,29 @@ static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi) · 102 unmodified lines | ||
| 103 | 103 | * there is room for the producer to send the pending packet. |
| 104 | 104 | */ |
| 105 | 105 | |
| 106 | −static bool hv_need_to_signal_on_read(u32 prev_write_sz, | |
| 107 | − struct hv_ring_buffer_info *rbi) | |
| 106 | +static bool hv_need_to_signal_on_read(struct hv_ring_buffer_info *rbi) | |
| 108 | 107 | { |
| 109 | 108 | u32 cur_write_sz; |
| 110 | 109 | u32 r_size; |
| 111 | − u32 write_loc = rbi->ring_buffer->write_index; | |
| 110 | + u32 write_loc; | |
| 112 | 111 | u32 read_loc = rbi->ring_buffer->read_index; |
| 113 | − u32 pending_sz = rbi->ring_buffer->pending_send_sz; | |
| 112 | + u32 pending_sz; | |
| 114 | 113 | |
| 114 | + /* | |
| 115 | + * Issue a full memory barrier before making the signaling decision. | |
| 116 | + * Here is the reason for having this barrier: | |
| 117 | + * If the reading of the pend_sz (in this function) | |
| 118 | + * were to be reordered and read before we commit the new read | |
| 119 | + * index (in the calling function) we could | |
| 120 | + * have a problem. If the host were to set the pending_sz after we | |
| 121 | + * have sampled pending_sz and go to sleep before we commit the | |
| 122 | + * read index, we could miss sending the interrupt. Issue a full | |
| 123 | + * memory barrier to address this. | |
| 124 | + */ | |
| 125 | + mb(); | |
| 126 | + | |
| 127 | + pending_sz = rbi->ring_buffer->pending_send_sz; | |
| 128 | + write_loc = rbi->ring_buffer->write_index; | |
| 115 | 129 | /* If the other end is not blocked on write don't bother. */ |
| 116 | 130 | if (pending_sz == 0) |
| 117 | 131 | return false; |
| @@ -120,7 +134,7 @@ static bool hv_need_to_signal_on_read(u32 prev_write_sz, · 2 unmodified lines | ||
| 120 | 134 | cur_write_sz = write_loc >= read_loc ? r_size - (write_loc - read_loc) : |
| 121 | 135 | read_loc - write_loc; |
| 122 | 136 | |
| 123 | − if ((prev_write_sz < pending_sz) && (cur_write_sz >= pending_sz)) | |
| 137 | + if (cur_write_sz >= pending_sz) | |
| 124 | 138 | return true; |
| 125 | 139 | |
| 126 | 140 | return false; |
| @@ -455,7 +469,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, · 328 unmodified lines | ||
| 455 | 469 | /* Update the read index */ |
| 456 | 470 | hv_set_next_read_location(inring_info, next_read_location); |
| 457 | 471 | |
| 458 | − *signal = hv_need_to_signal_on_read(bytes_avail_towrite, inring_info); | |
| 472 | + *signal = hv_need_to_signal_on_read(inring_info); | |
| 459 | 473 | |
| 460 | 474 | return ret; |
| 461 | 475 | } |
| @@ -975,10 +975,10 @@ config I2C_XLR · 974 unmodified lines | ||
| 975 | 975 | |
| 976 | 976 | config I2C_XLP9XX |
| 977 | 977 | tristate "XLP9XX I2C support" |
| 978 | − depends on CPU_XLP || COMPILE_TEST | |
| 978 | + depends on CPU_XLP || ARCH_VULCAN || COMPILE_TEST | |
| 979 | 979 | help |
| 980 | 980 | This driver enables support for the on-chip I2C interface of |
| 981 | − the Broadcom XLP9xx/XLP5xx MIPS processors. | |
| 981 | + the Broadcom XLP9xx/XLP5xx MIPS and Vulcan ARM64 processors. | |
| 982 | 982 | |
| 983 | 983 | This driver can also be built as a module. If so, the module will |
| 984 | 984 | be called i2c-xlp9xx. |
| @@ -116,8 +116,8 @@ struct cpm_i2c { · 115 unmodified lines | ||
| 116 | 116 | cbd_t __iomem *rbase; |
| 117 | 117 | u_char *txbuf[CPM_MAXBD]; |
| 118 | 118 | u_char *rxbuf[CPM_MAXBD]; |
| 119 | − u32 txdma[CPM_MAXBD]; | |
| 120 | − u32 rxdma[CPM_MAXBD]; | |
| 119 | + dma_addr_t txdma[CPM_MAXBD]; | |
| 120 | + dma_addr_t rxdma[CPM_MAXBD]; | |
| 121 | 121 | }; |
| 122 | 122 | |
| 123 | 123 | static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id) |
| @@ -671,7 +671,9 @@ static int exynos5_i2c_xfer(struct i2c_adapter *adap, · 670 unmodified lines | ||
| 671 | 671 | return -EIO; |
| 672 | 672 | } |
| 673 | 673 | |
| 674 | − clk_prepare_enable(i2c->clk); | |
| 674 | + ret = clk_enable(i2c->clk); | |
| 675 | + if (ret) | |
| 676 | + return ret; | |
| 675 | 677 | |
| 676 | 678 | for (i = 0; i < num; i++, msgs++) { |
| 677 | 679 | stop = (i == num - 1); |
| @@ -695,7 +697,7 @@ static int exynos5_i2c_xfer(struct i2c_adapter *adap, · 17 unmodified lines | ||
| 695 | 697 | } |
| 696 | 698 | |
| 697 | 699 | out: |
| 698 | − clk_disable_unprepare(i2c->clk); | |
| 700 | + clk_disable(i2c->clk); | |
| 699 | 701 | return ret; |
| 700 | 702 | } |
| 701 | 703 | |
| @@ -747,7 +749,9 @@ static int exynos5_i2c_probe(struct platform_device *pdev) · 45 unmodified lines | ||
| 747 | 749 | return -ENOENT; |
| 748 | 750 | } |
| 749 | 751 | |
| 750 | − clk_prepare_enable(i2c->clk); | |
| 752 | + ret = clk_prepare_enable(i2c->clk); | |
| 753 | + if (ret) | |
| 754 | + return ret; | |
| 751 | 755 | |
| 752 | 756 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 753 | 757 | i2c->regs = devm_ioremap_resource(&pdev->dev, mem); |
| @@ -799,6 +803,10 @@ static int exynos5_i2c_probe(struct platform_device *pdev) · 45 unmodified lines | ||
| 799 | 803 | |
| 800 | 804 | platform_set_drvdata(pdev, i2c); |
| 801 | 805 | |
| 806 | + clk_disable(i2c->clk); | |
| 807 | + | |
| 808 | + return 0; | |
| 809 | + | |
| 802 | 810 | err_clk: |
| 803 | 811 | clk_disable_unprepare(i2c->clk); |
| 804 | 812 | return ret; |
| @@ -810,6 +818,8 @@ static int exynos5_i2c_remove(struct platform_device *pdev) · 5 unmodified lines | ||
| 810 | 818 | |
| 811 | 819 | i2c_del_adapter(&i2c->adap); |
| 812 | 820 | |
| 821 | + clk_unprepare(i2c->clk); | |
| 822 | + | |
| 813 | 823 | return 0; |
| 814 | 824 | } |
| 815 | 825 | |
| @@ -821,6 +831,8 @@ static int exynos5_i2c_suspend_noirq(struct device *dev) · 5 unmodified lines | ||
| 821 | 831 | |
| 822 | 832 | i2c->suspended = 1; |
| 823 | 833 | |
| 834 | + clk_unprepare(i2c->clk); | |
| 835 | + | |
| 824 | 836 | return 0; |
| 825 | 837 | } |
| 826 | 838 | |
| @@ -830,7 +842,9 @@ static int exynos5_i2c_resume_noirq(struct device *dev) · 3 unmodified lines | ||
| 830 | 842 | struct exynos5_i2c *i2c = platform_get_drvdata(pdev); |
| 831 | 843 | int ret = 0; |
| 832 | 844 | |
| 833 | − clk_prepare_enable(i2c->clk); | |
| 845 | + ret = clk_prepare_enable(i2c->clk); | |
| 846 | + if (ret) | |
| 847 | + return ret; | |
| 834 | 848 | |
| 835 | 849 | ret = exynos5_hsi2c_clock_setup(i2c); |
| 836 | 850 | if (ret) { |
| @@ -839,7 +853,7 @@ static int exynos5_i2c_resume_noirq(struct device *dev) · 2 unmodified lines | ||
| 839 | 853 | } |
| 840 | 854 | |
| 841 | 855 | exynos5_i2c_init(i2c); |
| 842 | − clk_disable_unprepare(i2c->clk); | |
| 856 | + clk_disable(i2c->clk); | |
| 843 | 857 | i2c->suspended = 0; |
| 844 | 858 | |
| 845 | 859 | return 0; |
| @@ -75,6 +75,7 @@ · 74 unmodified lines | ||
| 75 | 75 | /* PCI DIDs for the Intel SMBus Message Transport (SMT) Devices */ |
| 76 | 76 | #define PCI_DEVICE_ID_INTEL_S1200_SMT0 0x0c59 |
| 77 | 77 | #define PCI_DEVICE_ID_INTEL_S1200_SMT1 0x0c5a |
| 78 | +#define PCI_DEVICE_ID_INTEL_DNV_SMT 0x19ac | |
| 78 | 79 | #define PCI_DEVICE_ID_INTEL_AVOTON_SMT 0x1f15 |
| 79 | 80 | |
| 80 | 81 | #define ISMT_DESC_ENTRIES 2 /* number of descriptor entries */ |
| @@ -180,6 +181,7 @@ struct ismt_priv { · 99 unmodified lines | ||
| 180 | 181 | static const struct pci_device_id ismt_ids[] = { |
| 181 | 182 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT0) }, |
| 182 | 183 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT1) }, |
| 184 | + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DNV_SMT) }, | |
| 183 | 185 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMT) }, |
| 184 | 186 | { 0, } |
| 185 | 187 | }; |
| @@ -855,6 +855,7 @@ static struct rk3x_i2c_soc_data soc_data[3] = { · 854 unmodified lines | ||
| 855 | 855 | static const struct of_device_id rk3x_i2c_match[] = { |
| 856 | 856 | { .compatible = "rockchip,rk3066-i2c", .data = (void *)&soc_data[0] }, |
| 857 | 857 | { .compatible = "rockchip,rk3188-i2c", .data = (void *)&soc_data[1] }, |
| 858 | + { .compatible = "rockchip,rk3228-i2c", .data = (void *)&soc_data[2] }, | |
| 858 | 859 | { .compatible = "rockchip,rk3288-i2c", .data = (void *)&soc_data[2] }, |
| 859 | 860 | {}, |
| 860 | 861 | }; |
| @@ -451,6 +451,8 @@ static int at91_adc_probe(struct platform_device *pdev) · 450 unmodified lines | ||
| 451 | 451 | if (ret) |
| 452 | 452 | goto vref_disable; |
| 453 | 453 | |
| 454 | + platform_set_drvdata(pdev, indio_dev); | |
| 455 | + | |
| 454 | 456 | ret = iio_device_register(indio_dev); |
| 455 | 457 | if (ret < 0) |
| 456 | 458 | goto per_clk_disable_unprepare; |
| @@ -104,6 +104,19 @@ static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap, · 103 unmodified lines | ||
| 104 | 104 | return 0; |
| 105 | 105 | } |
| 106 | 106 | |
| 107 | +static const char *inv_mpu_match_acpi_device(struct device *dev, int *chip_id) | |
| 108 | +{ | |
| 109 | + const struct acpi_device_id *id; | |
| 110 | + | |
| 111 | + id = acpi_match_device(dev->driver->acpi_match_table, dev); | |
| 112 | + if (!id) | |
| 113 | + return NULL; | |
| 114 | + | |
| 115 | + *chip_id = (int)id->driver_data; | |
| 116 | + | |
| 117 | + return dev_name(dev); | |
| 118 | +} | |
| 119 | + | |
| 107 | 120 | /** |
| 108 | 121 | * inv_mpu_probe() - probe function. |
| 109 | 122 | * @client: i2c client. |
| @@ -115,14 +128,25 @@ static int inv_mpu_probe(struct i2c_client *client, · 5 unmodified lines | ||
| 115 | 128 | const struct i2c_device_id *id) |
| 116 | 129 | { |
| 117 | 130 | struct inv_mpu6050_state *st; |
| 118 | − int result; | |
| 119 | − const char *name = id ? id->name : NULL; | |
| 131 | + int result, chip_type; | |
| 120 | 132 | struct regmap *regmap; |
| 133 | + const char *name; | |
| 121 | 134 | |
| 122 | 135 | if (!i2c_check_functionality(client->adapter, |
| 123 | 136 | I2C_FUNC_SMBUS_I2C_BLOCK)) |
| 124 | 137 | return -EOPNOTSUPP; |
| 125 | 138 | |
| 139 | + if (id) { | |
| 140 | + chip_type = (int)id->driver_data; | |
| 141 | + name = id->name; | |
| 142 | + } else if (ACPI_HANDLE(&client->dev)) { | |
| 143 | + name = inv_mpu_match_acpi_device(&client->dev, &chip_type); | |
| 144 | + if (!name) | |
| 145 | + return -ENODEV; | |
| 146 | + } else { | |
| 147 | + return -ENOSYS; | |
| 148 | + } | |
| 149 | + | |
| 126 | 150 | regmap = devm_regmap_init_i2c(client, &inv_mpu_regmap_config); |
| 127 | 151 | if (IS_ERR(regmap)) { |
| 128 | 152 | dev_err(&client->dev, "Failed to register i2c regmap %d\n", |
| @@ -131,7 +155,7 @@ static int inv_mpu_probe(struct i2c_client *client, · 2 unmodified lines | ||
| 131 | 155 | } |
| 132 | 156 | |
| 133 | 157 | result = inv_mpu_core_probe(regmap, client->irq, name, |
| 134 | − NULL, id->driver_data); | |
| 158 | + NULL, chip_type); | |
| 135 | 159 | if (result < 0) |
| 136 | 160 | return result; |
| 137 | 161 | |
| @@ -46,6 +46,7 @@ static int inv_mpu_probe(struct spi_device *spi) · 45 unmodified lines | ||
| 46 | 46 | struct regmap *regmap; |
| 47 | 47 | const struct spi_device_id *id = spi_get_device_id(spi); |
| 48 | 48 | const char *name = id ? id->name : NULL; |
| 49 | + const int chip_type = id ? id->driver_data : 0; | |
| 49 | 50 | |
| 50 | 51 | regmap = devm_regmap_init_spi(spi, &inv_mpu_regmap_config); |
| 51 | 52 | if (IS_ERR(regmap)) { |
| @@ -55,7 +56,7 @@ static int inv_mpu_probe(struct spi_device *spi) · 3 unmodified lines | ||
| 55 | 56 | } |
| 56 | 57 | |
| 57 | 58 | return inv_mpu_core_probe(regmap, spi->irq, name, |
| 58 | − inv_mpu_i2c_disable, id->driver_data); | |
| 59 | + inv_mpu_i2c_disable, chip_type); | |
| 59 | 60 | } |
| 60 | 61 | |
| 61 | 62 | static int inv_mpu_remove(struct spi_device *spi) |
| @@ -462,6 +462,8 @@ static int ak8975_setup_irq(struct ak8975_data *data) · 461 unmodified lines | ||
| 462 | 462 | int rc; |
| 463 | 463 | int irq; |
| 464 | 464 | |
| 465 | + init_waitqueue_head(&data->data_ready_queue); | |
| 466 | + clear_bit(0, &data->flags); | |
| 465 | 467 | if (client->irq) |
| 466 | 468 | irq = client->irq; |
| 467 | 469 | else |
| @@ -477,8 +479,6 @@ static int ak8975_setup_irq(struct ak8975_data *data) · 9 unmodified lines | ||
| 477 | 479 | return rc; |
| 478 | 480 | } |
| 479 | 481 | |
| 480 | − init_waitqueue_head(&data->data_ready_queue); | |
| 481 | − clear_bit(0, &data->flags); | |
| 482 | 482 | data->eoc_irq = irq; |
| 483 | 483 | |
| 484 | 484 | return rc; |
| @@ -732,7 +732,7 @@ static int ak8975_probe(struct i2c_client *client, · 247 unmodified lines | ||
| 732 | 732 | int eoc_gpio; |
| 733 | 733 | int err; |
| 734 | 734 | const char *name = NULL; |
| 735 | − enum asahi_compass_chipset chipset; | |
| 735 | + enum asahi_compass_chipset chipset = AK_MAX_TYPE; | |
| 736 | 736 | |
| 737 | 737 | /* Grab and set up the supplied GPIO. */ |
| 738 | 738 | if (client->dev.platform_data) |
| @@ -691,7 +691,8 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port, · 690 unmodified lines | ||
| 691 | 691 | NULL); |
| 692 | 692 | |
| 693 | 693 | /* Coudn't find default GID location */ |
| 694 | − WARN_ON(ix < 0); | |
| 694 | + if (WARN_ON(ix < 0)) | |
| 695 | + goto release; | |
| 695 | 696 | |
| 696 | 697 | zattr_type.gid_type = gid_type; |
| 697 | 698 | |
| @@ -48,6 +48,7 @@ · 47 unmodified lines | ||
| 48 | 48 | |
| 49 | 49 | #include <asm/uaccess.h> |
| 50 | 50 | |
| 51 | +#include <rdma/ib.h> | |
| 51 | 52 | #include <rdma/ib_cm.h> |
| 52 | 53 | #include <rdma/ib_user_cm.h> |
| 53 | 54 | #include <rdma/ib_marshall.h> |
| @@ -1103,6 +1104,9 @@ static ssize_t ib_ucm_write(struct file *filp, const char __user *buf, · 1049 unmodified lines | ||
| 1103 | 1104 | struct ib_ucm_cmd_hdr hdr; |
| 1104 | 1105 | ssize_t result; |
| 1105 | 1106 | |
| 1107 | + if (WARN_ON_ONCE(!ib_safe_file_access(filp))) | |
| 1108 | + return -EACCES; | |
| 1109 | + | |
| 1106 | 1110 | if (len < sizeof(hdr)) |
| 1107 | 1111 | return -EINVAL; |
| 1108 | 1112 | |
| @@ -1574,6 +1574,9 @@ static ssize_t ucma_write(struct file *filp, const char __user *buf, · 1573 unmodified lines | ||
| 1574 | 1574 | struct rdma_ucm_cmd_hdr hdr; |
| 1575 | 1575 | ssize_t ret; |
| 1576 | 1576 | |
| 1577 | + if (WARN_ON_ONCE(!ib_safe_file_access(filp))) | |
| 1578 | + return -EACCES; | |
| 1579 | + | |
| 1577 | 1580 | if (len < sizeof(hdr)) |
| 1578 | 1581 | return -EINVAL; |
| 1579 | 1582 | |
| @@ -48,6 +48,8 @@ · 47 unmodified lines | ||
| 48 | 48 | |
| 49 | 49 | #include <asm/uaccess.h> |
| 50 | 50 | |
| 51 | +#include <rdma/ib.h> | |
| 52 | + | |
| 51 | 53 | #include "uverbs.h" |
| 52 | 54 | |
| 53 | 55 | MODULE_AUTHOR("Roland Dreier"); |
| @@ -709,6 +711,9 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, · 655 unmodified lines | ||
| 709 | 711 | int srcu_key; |
| 710 | 712 | ssize_t ret; |
| 711 | 713 | |
| 714 | + if (WARN_ON_ONCE(!ib_safe_file_access(filp))) | |
| 715 | + return -EACCES; | |
| 716 | + | |
| 712 | 717 | if (count < sizeof hdr) |
| 713 | 718 | return -EINVAL; |
| 714 | 719 | |
| @@ -1860,6 +1860,7 @@ EXPORT_SYMBOL(ib_drain_rq); · 1859 unmodified lines | ||
| 1860 | 1860 | void ib_drain_qp(struct ib_qp *qp) |
| 1861 | 1861 | { |
| 1862 | 1862 | ib_drain_sq(qp); |
| 1863 | − ib_drain_rq(qp); | |
| 1863 | + if (!qp->srq) | |
| 1864 | + ib_drain_rq(qp); | |
| 1864 | 1865 | } |
| 1865 | 1866 | EXPORT_SYMBOL(ib_drain_qp); |
| @@ -1390,6 +1390,8 @@ int iwch_register_device(struct iwch_dev *dev) · 1389 unmodified lines | ||
| 1390 | 1390 | dev->ibdev.iwcm->add_ref = iwch_qp_add_ref; |
| 1391 | 1391 | dev->ibdev.iwcm->rem_ref = iwch_qp_rem_ref; |
| 1392 | 1392 | dev->ibdev.iwcm->get_qp = iwch_get_qp; |
| 1393 | + memcpy(dev->ibdev.iwcm->ifname, dev->rdev.t3cdev_p->lldev->name, | |
| 1394 | + sizeof(dev->ibdev.iwcm->ifname)); | |
| 1393 | 1395 | |
| 1394 | 1396 | ret = ib_register_device(&dev->ibdev, NULL); |
| 1395 | 1397 | if (ret) |
| @@ -162,7 +162,7 @@ static int create_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, · 161 unmodified lines | ||
| 162 | 162 | cq->bar2_va = c4iw_bar2_addrs(rdev, cq->cqid, T4_BAR2_QTYPE_INGRESS, |
| 163 | 163 | &cq->bar2_qid, |
| 164 | 164 | user ? &cq->bar2_pa : NULL); |
| 165 | − if (user && !cq->bar2_va) { | |
| 165 | + if (user && !cq->bar2_pa) { | |
| 166 | 166 | pr_warn(MOD "%s: cqid %u not in BAR2 range.\n", |
| 167 | 167 | pci_name(rdev->lldi.pdev), cq->cqid); |
| 168 | 168 | ret = -EINVAL; |
| @@ -580,6 +580,8 @@ int c4iw_register_device(struct c4iw_dev *dev) · 579 unmodified lines | ||
| 580 | 580 | dev->ibdev.iwcm->add_ref = c4iw_qp_add_ref; |
| 581 | 581 | dev->ibdev.iwcm->rem_ref = c4iw_qp_rem_ref; |
| 582 | 582 | dev->ibdev.iwcm->get_qp = c4iw_get_qp; |
| 583 | + memcpy(dev->ibdev.iwcm->ifname, dev->rdev.lldi.ports[0]->name, | |
| 584 | + sizeof(dev->ibdev.iwcm->ifname)); | |
| 583 | 585 | |
| 584 | 586 | ret = ib_register_device(&dev->ibdev, NULL); |
| 585 | 587 | if (ret) |
| @@ -185,6 +185,10 @@ void __iomem *c4iw_bar2_addrs(struct c4iw_rdev *rdev, unsigned int qid, · 184 unmodified lines | ||
| 185 | 185 | |
| 186 | 186 | if (pbar2_pa) |
| 187 | 187 | *pbar2_pa = (rdev->bar2_pa + bar2_qoffset) & PAGE_MASK; |
| 188 | + | |
| 189 | + if (is_t4(rdev->lldi.adapter_type)) | |
| 190 | + return NULL; | |
| 191 | + | |
| 188 | 192 | return rdev->bar2_kva + bar2_qoffset; |
| 189 | 193 | } |
| 190 | 194 | |
| @@ -270,7 +274,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, · 79 unmodified lines | ||
| 270 | 274 | /* |
| 271 | 275 | * User mode must have bar2 access. |
| 272 | 276 | */ |
| 273 | − if (user && (!wq->sq.bar2_va || !wq->rq.bar2_va)) { | |
| 277 | + if (user && (!wq->sq.bar2_pa || !wq->rq.bar2_pa)) { | |
| 274 | 278 | pr_warn(MOD "%s: sqid %u or rqid %u not in BAR2 range.\n", |
| 275 | 279 | pci_name(rdev->lldi.pdev), wq->sq.qid, wq->rq.qid); |
| 276 | 280 | goto free_dma; |
| @@ -1895,13 +1899,27 @@ int c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, · 1618 unmodified lines | ||
| 1895 | 1899 | void c4iw_drain_sq(struct ib_qp *ibqp) |
| 1896 | 1900 | { |
| 1897 | 1901 | struct c4iw_qp *qp = to_c4iw_qp(ibqp); |
| 1902 | + unsigned long flag; | |
| 1903 | + bool need_to_wait; | |
| 1898 | 1904 | |
| 1899 | − wait_for_completion(&qp->sq_drained); | |
| 1905 | + spin_lock_irqsave(&qp->lock, flag); | |
| 1906 | + need_to_wait = !t4_sq_empty(&qp->wq); | |
| 1907 | + spin_unlock_irqrestore(&qp->lock, flag); | |
| 1908 | + | |
| 1909 | + if (need_to_wait) | |
| 1910 | + wait_for_completion(&qp->sq_drained); | |
| 1900 | 1911 | } |
| 1901 | 1912 | |
| 1902 | 1913 | void c4iw_drain_rq(struct ib_qp *ibqp) |
| 1903 | 1914 | { |
| 1904 | 1915 | struct c4iw_qp *qp = to_c4iw_qp(ibqp); |
| 1916 | + unsigned long flag; | |
| 1917 | + bool need_to_wait; | |
| 1918 | + | |
| 1919 | + spin_lock_irqsave(&qp->lock, flag); | |
| 1920 | + need_to_wait = !t4_rq_empty(&qp->wq); | |
| 1921 | + spin_unlock_irqrestore(&qp->lock, flag); | |
| 1905 | 1922 | |
| 1906 | − wait_for_completion(&qp->rq_drained); | |
| 1923 | + if (need_to_wait) | |
| 1924 | + wait_for_completion(&qp->rq_drained); | |
| 1907 | 1925 | } |
| @@ -530,7 +530,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev, · 529 unmodified lines | ||
| 530 | 530 | sizeof(struct mlx5_wqe_ctrl_seg)) / |
| 531 | 531 | sizeof(struct mlx5_wqe_data_seg); |
| 532 | 532 | props->max_sge = min(max_rq_sg, max_sq_sg); |
| 533 | − props->max_sge_rd = props->max_sge; | |
| 533 | + props->max_sge_rd = MLX5_MAX_SGE_RD; | |
| 534 | 534 | props->max_cq = 1 << MLX5_CAP_GEN(mdev, log_max_cq); |
| 535 | 535 | props->max_cqe = (1 << MLX5_CAP_GEN(mdev, log_max_cq_sz)) - 1; |
| 536 | 536 | props->max_mr = 1 << MLX5_CAP_GEN(mdev, log_max_mkey); |
| @@ -671,8 +671,8 @@ static int mlx5_query_hca_port(struct ib_device *ibdev, u8 port, · 134 unmodified lines | ||
| 671 | 671 | struct mlx5_ib_dev *dev = to_mdev(ibdev); |
| 672 | 672 | struct mlx5_core_dev *mdev = dev->mdev; |
| 673 | 673 | struct mlx5_hca_vport_context *rep; |
| 674 | − int max_mtu; | |
| 675 | − int oper_mtu; | |
| 674 | + u16 max_mtu; | |
| 675 | + u16 oper_mtu; | |
| 676 | 676 | int err; |
| 677 | 677 | u8 ib_link_width_oper; |
| 678 | 678 | u8 vl_hw_cap; |
| @@ -500,9 +500,6 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev) · 499 unmodified lines | ||
| 500 | 500 | * skb_shinfo(skb)->nr_frags, skb_is_gso(skb)); |
| 501 | 501 | */ |
| 502 | 502 | |
| 503 | − if (!netif_carrier_ok(netdev)) | |
| 504 | − return NETDEV_TX_OK; | |
| 505 | − | |
| 506 | 503 | if (netif_queue_stopped(netdev)) |
| 507 | 504 | return NETDEV_TX_BUSY; |
| 508 | 505 | |
| @@ -45,6 +45,8 @@ · 44 unmodified lines | ||
| 45 | 45 | #include <linux/export.h> |
| 46 | 46 | #include <linux/uio.h> |
| 47 | 47 | |
| 48 | +#include <rdma/ib.h> | |
| 49 | + | |
| 48 | 50 | #include "qib.h" |
| 49 | 51 | #include "qib_common.h" |
| 50 | 52 | #include "qib_user_sdma.h" |
| @@ -2067,6 +2069,9 @@ static ssize_t qib_write(struct file *fp, const char __user *data, · 2016 unmodified lines | ||
| 2067 | 2069 | ssize_t ret = 0; |
| 2068 | 2070 | void *dest; |
| 2069 | 2071 | |
| 2072 | + if (WARN_ON_ONCE(!ib_safe_file_access(fp))) | |
| 2073 | + return -EACCES; | |
| 2074 | + | |
| 2070 | 2075 | if (count < sizeof(cmd.type)) { |
| 2071 | 2076 | ret = -EINVAL; |
| 2072 | 2077 | goto bail; |
| @@ -1637,9 +1637,9 @@ bail: · 1636 unmodified lines | ||
| 1637 | 1637 | spin_unlock_irqrestore(&qp->s_hlock, flags); |
| 1638 | 1638 | if (nreq) { |
| 1639 | 1639 | if (call_send) |
| 1640 | − rdi->driver_f.schedule_send_no_lock(qp); | |
| 1641 | − else | |
| 1642 | 1640 | rdi->driver_f.do_send(qp); |
| 1641 | + else | |
| 1642 | + rdi->driver_f.schedule_send_no_lock(qp); | |
| 1643 | 1643 | } |
| 1644 | 1644 | return err; |
| 1645 | 1645 | } |
| @@ -612,6 +612,7 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep, · 611 unmodified lines | ||
| 612 | 612 | struct Scsi_Host *shost; |
| 613 | 613 | struct iser_conn *iser_conn = NULL; |
| 614 | 614 | struct ib_conn *ib_conn; |
| 615 | + u32 max_fr_sectors; | |
| 615 | 616 | u16 max_cmds; |
| 616 | 617 | |
| 617 | 618 | shost = iscsi_host_alloc(&iscsi_iser_sht, 0, 0); |
| @@ -632,7 +633,6 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep, · 14 unmodified lines | ||
| 632 | 633 | iser_conn = ep->dd_data; |
| 633 | 634 | max_cmds = iser_conn->max_cmds; |
| 634 | 635 | shost->sg_tablesize = iser_conn->scsi_sg_tablesize; |
| 635 | − shost->max_sectors = iser_conn->scsi_max_sectors; | |
| 636 | 636 | |
| 637 | 637 | mutex_lock(&iser_conn->state_mutex); |
| 638 | 638 | if (iser_conn->state != ISER_CONN_UP) { |
| @@ -657,8 +657,6 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep, · 18 unmodified lines | ||
| 657 | 657 | */ |
| 658 | 658 | shost->sg_tablesize = min_t(unsigned short, shost->sg_tablesize, |
| 659 | 659 | ib_conn->device->ib_device->attrs.max_fast_reg_page_list_len); |
| 660 | − shost->max_sectors = min_t(unsigned int, | |
| 661 | − 1024, (shost->sg_tablesize * PAGE_SIZE) >> 9); | |
| 662 | 660 | |
| 663 | 661 | if (iscsi_host_add(shost, |
| 664 | 662 | ib_conn->device->ib_device->dma_device)) { |
| @@ -672,6 +670,15 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep, · 7 unmodified lines | ||
| 672 | 670 | goto free_host; |
| 673 | 671 | } |
| 674 | 672 | |
| 673 | + /* | |
| 674 | + * FRs or FMRs can only map up to a (device) page per entry, but if the | |
| 675 | + * first entry is misaligned we'll end up using using two entries | |
| 676 | + * (head and tail) for a single page worth data, so we have to drop | |
| 677 | + * one segment from the calculation. | |
| 678 | + */ | |
| 679 | + max_fr_sectors = ((shost->sg_tablesize - 1) * PAGE_SIZE) >> 9; | |
| 680 | + shost->max_sectors = min(iser_max_sectors, max_fr_sectors); | |
| 681 | + | |
| 675 | 682 | if (cmds_max > max_cmds) { |
| 676 | 683 | iser_info("cmds_max changed from %u to %u\n", |
| 677 | 684 | cmds_max, max_cmds); |
| @@ -989,7 +996,6 @@ static struct scsi_host_template iscsi_iser_sht = { · 311 unmodified lines | ||
| 989 | 996 | .queuecommand = iscsi_queuecommand, |
| 990 | 997 | .change_queue_depth = scsi_change_queue_depth, |
| 991 | 998 | .sg_tablesize = ISCSI_ISER_DEF_SG_TABLESIZE, |
| 992 | − .max_sectors = ISER_DEF_MAX_SECTORS, | |
| 993 | 999 | .cmd_per_lun = ISER_DEF_CMD_PER_LUN, |
| 994 | 1000 | .eh_abort_handler = iscsi_eh_abort, |
| 995 | 1001 | .eh_device_reset_handler= iscsi_eh_device_reset, |
| @@ -181,6 +181,14 @@ static void vibra_play_work(struct work_struct *work) · 180 unmodified lines | ||
| 181 | 181 | { |
| 182 | 182 | struct vibra_info *info = container_of(work, |
| 183 | 183 | struct vibra_info, play_work); |
| 184 | + int ret; | |
| 185 | + | |
| 186 | + /* Do not allow effect, while the routing is set to use audio */ | |
| 187 | + ret = twl6040_get_vibralr_status(info->twl6040); | |
| 188 | + if (ret & TWL6040_VIBSEL) { | |
| 189 | + dev_info(info->dev, "Vibra is configured for audio\n"); | |
| 190 | + return; | |
| 191 | + } | |
| 184 | 192 | |
| 185 | 193 | mutex_lock(&info->mutex); |
| 186 | 194 | |
| @@ -199,14 +207,6 @@ static int vibra_play(struct input_dev *input, void *data, · 12 unmodified lines | ||
| 199 | 207 | struct ff_effect *effect) |
| 200 | 208 | { |
| 201 | 209 | struct vibra_info *info = input_get_drvdata(input); |
| 202 | − int ret; | |
| 203 | − | |
| 204 | − /* Do not allow effect, while the routing is set to use audio */ | |
| 205 | − ret = twl6040_get_vibralr_status(info->twl6040); | |
| 206 | − if (ret & TWL6040_VIBSEL) { | |
| 207 | − dev_info(&input->dev, "Vibra is configured for audio\n"); | |
| 208 | − return -EBUSY; | |
| 209 | − } | |
| 210 | 210 | |
| 211 | 211 | info->weak_speed = effect->u.rumble.weak_magnitude; |
| 212 | 212 | info->strong_speed = effect->u.rumble.strong_magnitude; |
| @@ -1093,6 +1093,19 @@ static int mxt_t6_command(struct mxt_data *data, u16 cmd_offset, · 1092 unmodified lines | ||
| 1093 | 1093 | return 0; |
| 1094 | 1094 | } |
| 1095 | 1095 | |
| 1096 | +static int mxt_acquire_irq(struct mxt_data *data) | |
| 1097 | +{ | |
| 1098 | + int error; | |
| 1099 | + | |
| 1100 | + enable_irq(data->irq); | |
| 1101 | + | |
| 1102 | + error = mxt_process_messages_until_invalid(data); | |
| 1103 | + if (error) | |
| 1104 | + return error; | |
| 1105 | + | |
| 1106 | + return 0; | |
| 1107 | +} | |
| 1108 | + | |
| 1096 | 1109 | static int mxt_soft_reset(struct mxt_data *data) |
| 1097 | 1110 | { |
| 1098 | 1111 | struct device *dev = &data->client->dev; |
| @@ -1111,7 +1124,7 @@ static int mxt_soft_reset(struct mxt_data *data) · 12 unmodified lines | ||
| 1111 | 1124 | /* Ignore CHG line for 100ms after reset */ |
| 1112 | 1125 | msleep(100); |
| 1113 | 1126 | |
| 1114 | − enable_irq(data->irq); | |
| 1127 | + mxt_acquire_irq(data); | |
| 1115 | 1128 | |
| 1116 | 1129 | ret = mxt_wait_for_completion(data, &data->reset_completion, |
| 1117 | 1130 | MXT_RESET_TIMEOUT); |
| @@ -1466,19 +1479,6 @@ release_mem: · 348 unmodified lines | ||
| 1466 | 1479 | return ret; |
| 1467 | 1480 | } |
| 1468 | 1481 | |
| 1469 | −static int mxt_acquire_irq(struct mxt_data *data) | |
| 1470 | −{ | |
| 1471 | − int error; | |
| 1472 | − | |
| 1473 | − enable_irq(data->irq); | |
| 1474 | − | |
| 1475 | − error = mxt_process_messages_until_invalid(data); | |
| 1476 | − if (error) | |
| 1477 | − return error; | |
| 1478 | − | |
| 1479 | − return 0; | |
| 1480 | −} | |
| 1481 | − | |
| 1482 | 1482 | static int mxt_get_info(struct mxt_data *data) |
| 1483 | 1483 | { |
| 1484 | 1484 | struct i2c_client *client = data->client; |
| @@ -370,8 +370,8 @@ static int zforce_touch_event(struct zforce_ts *ts, u8 *payload) · 369 unmodified lines | ||
| 370 | 370 | point.coord_x = point.coord_y = 0; |
| 371 | 371 | } |
| 372 | 372 | |
| 373 | − point.state = payload[9 * i + 5] & 0x03; | |
| 374 | − point.id = (payload[9 * i + 5] & 0xfc) >> 2; | |
| 373 | + point.state = payload[9 * i + 5] & 0x0f; | |
| 374 | + point.id = (payload[9 * i + 5] & 0xf0) >> 4; | |
| 375 | 375 | |
| 376 | 376 | /* determine touch major, minor and orientation */ |
| 377 | 377 | point.area_major = max(payload[9 * i + 6], |
| @@ -284,6 +284,8 @@ static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio) · 283 unmodified lines | ||
| 284 | 284 | * go away inside make_request |
| 285 | 285 | */ |
| 286 | 286 | sectors = bio_sectors(bio); |
| 287 | + /* bio could be mergeable after passing to underlayer */ | |
| 288 | + bio->bi_rw &= ~REQ_NOMERGE; | |
| 287 | 289 | mddev->pers->make_request(mddev, bio); |
| 288 | 290 | |
| 289 | 291 | cpu = part_stat_lock(); |
| @@ -70,7 +70,6 @@ static void dump_zones(struct mddev *mddev) · 69 unmodified lines | ||
| 70 | 70 | (unsigned long long)zone_size>>1); |
| 71 | 71 | zone_start = conf->strip_zone[j].zone_end; |
| 72 | 72 | } |
| 73 | − printk(KERN_INFO "\n"); | |
| 74 | 73 | } |
| 75 | 74 | |
| 76 | 75 | static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) |
| @@ -85,6 +84,7 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) · 8 unmodified lines | ||
| 85 | 84 | struct r0conf *conf = kzalloc(sizeof(*conf), GFP_KERNEL); |
| 86 | 85 | unsigned short blksize = 512; |
| 87 | 86 | |
| 87 | + *private_conf = ERR_PTR(-ENOMEM); | |
| 88 | 88 | if (!conf) |
| 89 | 89 | return -ENOMEM; |
| 90 | 90 | rdev_for_each(rdev1, mddev) { |
| @@ -3502,8 +3502,6 @@ returnbi: · 3501 unmodified lines | ||
| 3502 | 3502 | dev = &sh->dev[i]; |
| 3503 | 3503 | } else if (test_bit(R5_Discard, &dev->flags)) |
| 3504 | 3504 | discard_pending = 1; |
| 3505 | − WARN_ON(test_bit(R5_SkipCopy, &dev->flags)); | |
| 3506 | − WARN_ON(dev->page != dev->orig_page); | |
| 3507 | 3505 | } |
| 3508 | 3506 | |
| 3509 | 3507 | r5l_stripe_write_finished(sh); |
| @@ -846,11 +846,11 @@ struct media_device *media_device_find_devres(struct device *dev) · 845 unmodified lines | ||
| 846 | 846 | } |
| 847 | 847 | EXPORT_SYMBOL_GPL(media_device_find_devres); |
| 848 | 848 | |
| 849 | +#if IS_ENABLED(CONFIG_PCI) | |
| 849 | 850 | void media_device_pci_init(struct media_device *mdev, |
| 850 | 851 | struct pci_dev *pci_dev, |
| 851 | 852 | const char *name) |
| 852 | 853 | { |
| 853 | −#ifdef CONFIG_PCI | |
| 854 | 854 | mdev->dev = &pci_dev->dev; |
| 855 | 855 | |
| 856 | 856 | if (name) |
| @@ -866,16 +866,16 @@ void media_device_pci_init(struct media_device *mdev, · 9 unmodified lines | ||
| 866 | 866 | mdev->driver_version = LINUX_VERSION_CODE; |
| 867 | 867 | |
| 868 | 868 | media_device_init(mdev); |
| 869 | −#endif | |
| 870 | 869 | } |
| 871 | 870 | EXPORT_SYMBOL_GPL(media_device_pci_init); |
| 871 | +#endif | |
| 872 | 872 | |
| 873 | +#if IS_ENABLED(CONFIG_USB) | |
| 873 | 874 | void __media_device_usb_init(struct media_device *mdev, |
| 874 | 875 | struct usb_device *udev, |
| 875 | 876 | const char *board_name, |
| 876 | 877 | const char *driver_name) |
| 877 | 878 | { |
| 878 | −#ifdef CONFIG_USB | |
| 879 | 879 | mdev->dev = &udev->dev; |
| 880 | 880 | |
| 881 | 881 | if (driver_name) |
| @@ -895,9 +895,9 @@ void __media_device_usb_init(struct media_device *mdev, · 13 unmodified lines | ||
| 895 | 895 | mdev->driver_version = LINUX_VERSION_CODE; |
| 896 | 896 | |
| 897 | 897 | media_device_init(mdev); |
| 898 | −#endif | |
| 899 | 898 | } |
| 900 | 899 | EXPORT_SYMBOL_GPL(__media_device_usb_init); |
| 900 | +#endif | |
| 901 | 901 | |
| 902 | 902 | |
| 903 | 903 | #endif /* CONFIG_MEDIA_CONTROLLER */ |
| @@ -1446,22 +1446,13 @@ static int fimc_md_probe(struct platform_device *pdev) · 1445 unmodified lines | ||
| 1446 | 1446 | |
| 1447 | 1447 | platform_set_drvdata(pdev, fmd); |
| 1448 | 1448 | |
| 1449 | − /* Protect the media graph while we're registering entities */ | |
| 1450 | − mutex_lock(&fmd->media_dev.graph_mutex); | |
| 1451 | − | |
| 1452 | 1449 | ret = fimc_md_register_platform_entities(fmd, dev->of_node); |
| 1453 | − if (ret) { | |
| 1454 | − mutex_unlock(&fmd->media_dev.graph_mutex); | |
| 1450 | + if (ret) | |
| 1455 | 1451 | goto err_clk; |
| 1456 | − } | |
| 1457 | 1452 | |
| 1458 | 1453 | ret = fimc_md_register_sensor_entities(fmd); |
| 1459 | − if (ret) { | |
| 1460 | − mutex_unlock(&fmd->media_dev.graph_mutex); | |
| 1454 | + if (ret) | |
| 1461 | 1455 | goto err_m_ent; |
| 1462 | − } | |
| 1463 | − | |
| 1464 | − mutex_unlock(&fmd->media_dev.graph_mutex); | |
| 1465 | 1456 | |
| 1466 | 1457 | ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode); |
| 1467 | 1458 | if (ret) |
| @@ -493,21 +493,17 @@ static int s3c_camif_probe(struct platform_device *pdev) · 492 unmodified lines | ||
| 493 | 493 | if (ret < 0) |
| 494 | 494 | goto err_sens; |
| 495 | 495 | |
| 496 | − mutex_lock(&camif->media_dev.graph_mutex); | |
| 497 | − | |
| 498 | 496 | ret = v4l2_device_register_subdev_nodes(&camif->v4l2_dev); |
| 499 | 497 | if (ret < 0) |
| 500 | − goto err_unlock; | |
| 498 | + goto err_sens; | |
| 501 | 499 | |
| 502 | 500 | ret = camif_register_video_nodes(camif); |
| 503 | 501 | if (ret < 0) |
| 504 | − goto err_unlock; | |
| 502 | + goto err_sens; | |
| 505 | 503 | |
| 506 | 504 | ret = camif_create_media_links(camif); |
| 507 | 505 | if (ret < 0) |
| 508 | − goto err_unlock; | |
| 509 | − | |
| 510 | − mutex_unlock(&camif->media_dev.graph_mutex); | |
| 506 | + goto err_sens; | |
| 511 | 507 | |
| 512 | 508 | ret = media_device_register(&camif->media_dev); |
| 513 | 509 | if (ret < 0) |
| @@ -516,8 +512,6 @@ static int s3c_camif_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 516 | 512 | pm_runtime_put(dev); |
| 517 | 513 | return 0; |
| 518 | 514 | |
| 519 | −err_unlock: | |
| 520 | − mutex_unlock(&camif->media_dev.graph_mutex); | |
| 521 | 515 | err_sens: |
| 522 | 516 | v4l2_device_unregister(&camif->v4l2_dev); |
| 523 | 517 | media_device_unregister(&camif->media_dev); |
| @@ -1452,13 +1452,6 @@ static int usbvision_probe(struct usb_interface *intf, · 1451 unmodified lines | ||
| 1452 | 1452 | printk(KERN_INFO "%s: %s found\n", __func__, |
| 1453 | 1453 | usbvision_device_data[model].model_string); |
| 1454 | 1454 | |
| 1455 | − /* | |
| 1456 | − * this is a security check. | |
| 1457 | − * an exploit using an incorrect bInterfaceNumber is known | |
| 1458 | − */ | |
| 1459 | − if (ifnum >= USB_MAXINTERFACES || !dev->actconfig->interface[ifnum]) | |
| 1460 | − return -ENODEV; | |
| 1461 | − | |
| 1462 | 1455 | if (usbvision_device_data[model].interface >= 0) |
| 1463 | 1456 | interface = &dev->actconfig->interface[usbvision_device_data[model].interface]->altsetting[0]; |
| 1464 | 1457 | else if (ifnum < dev->actconfig->desc.bNumInterfaces) |
| @@ -1645,7 +1645,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) · 1644 unmodified lines | ||
| 1645 | 1645 | * Will sleep if required for nonblocking == false. |
| 1646 | 1646 | */ |
| 1647 | 1647 | static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb, |
| 1648 | − int nonblocking) | |
| 1648 | + void *pb, int nonblocking) | |
| 1649 | 1649 | { |
| 1650 | 1650 | unsigned long flags; |
| 1651 | 1651 | int ret; |
| @@ -1666,10 +1666,10 @@ static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb, · 14 unmodified lines | ||
| 1666 | 1666 | /* |
| 1667 | 1667 | * Only remove the buffer from done_list if v4l2_buffer can handle all |
| 1668 | 1668 | * the planes. |
| 1669 | − * Verifying planes is NOT necessary since it already has been checked | |
| 1670 | − * before the buffer is queued/prepared. So it can never fail. | |
| 1671 | 1669 | */ |
| 1672 | − list_del(&(*vb)->done_entry); | |
| 1670 | + ret = call_bufop(q, verify_planes_array, *vb, pb); | |
| 1671 | + if (!ret) | |
| 1672 | + list_del(&(*vb)->done_entry); | |
| 1673 | 1673 | spin_unlock_irqrestore(&q->done_lock, flags); |
| 1674 | 1674 | |
| 1675 | 1675 | return ret; |
| @@ -1748,7 +1748,7 @@ int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb, · 72 unmodified lines | ||
| 1748 | 1748 | struct vb2_buffer *vb = NULL; |
| 1749 | 1749 | int ret; |
| 1750 | 1750 | |
| 1751 | − ret = __vb2_get_done_vb(q, &vb, nonblocking); | |
| 1751 | + ret = __vb2_get_done_vb(q, &vb, pb, nonblocking); | |
| 1752 | 1752 | if (ret < 0) |
| 1753 | 1753 | return ret; |
| 1754 | 1754 | |
| @@ -2297,6 +2297,16 @@ unsigned int vb2_core_poll(struct vb2_queue *q, struct file *file, · 542 unmodified lines | ||
| 2297 | 2297 | if (!vb2_is_streaming(q) || q->error) |
| 2298 | 2298 | return POLLERR; |
| 2299 | 2299 | |
| 2300 | + /* | |
| 2301 | + * If this quirk is set and QBUF hasn't been called yet then | |
| 2302 | + * return POLLERR as well. This only affects capture queues, output | |
| 2303 | + * queues will always initialize waiting_for_buffers to false. | |
| 2304 | + * This quirk is set by V4L2 for backwards compatibility reasons. | |
| 2305 | + */ | |
| 2306 | + if (q->quirk_poll_must_check_waiting_for_buffers && | |
| 2307 | + q->waiting_for_buffers && (req_events & (POLLIN | POLLRDNORM))) | |
| 2308 | + return POLLERR; | |
| 2309 | + | |
| 2300 | 2310 | /* |
| 2301 | 2311 | * For output streams you can call write() as long as there are fewer |
| 2302 | 2312 | * buffers queued than there are buffers available. |
| @@ -49,7 +49,7 @@ struct frame_vector *vb2_create_framevec(unsigned long start, · 48 unmodified lines | ||
| 49 | 49 | vec = frame_vector_create(nr); |
| 50 | 50 | if (!vec) |
| 51 | 51 | return ERR_PTR(-ENOMEM); |
| 52 | − ret = get_vaddr_frames(start, nr, write, 1, vec); | |
| 52 | + ret = get_vaddr_frames(start & PAGE_MASK, nr, write, true, vec); | |
| 53 | 53 | if (ret < 0) |
| 54 | 54 | goto out_destroy; |
| 55 | 55 | /* We accept only complete set of PFNs */ |
| @@ -74,6 +74,11 @@ static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer · 73 unmodified lines | ||
| 74 | 74 | return 0; |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | +static int __verify_planes_array_core(struct vb2_buffer *vb, const void *pb) | |
| 78 | +{ | |
| 79 | + return __verify_planes_array(vb, pb); | |
| 80 | +} | |
| 81 | + | |
| 77 | 82 | /** |
| 78 | 83 | * __verify_length() - Verify that the bytesused value for each plane fits in |
| 79 | 84 | * the plane length and that the data offset doesn't exceed the bytesused value. |
| @@ -437,6 +442,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, · 357 unmodified lines | ||
| 437 | 442 | } |
| 438 | 443 | |
| 439 | 444 | static const struct vb2_buf_ops v4l2_buf_ops = { |
| 445 | + .verify_planes_array = __verify_planes_array_core, | |
| 440 | 446 | .fill_user_buffer = __fill_v4l2_buffer, |
| 441 | 447 | .fill_vb2_buffer = __fill_vb2_buffer, |
| 442 | 448 | .copy_timestamp = __copy_timestamp, |
| @@ -765,6 +771,12 @@ int vb2_queue_init(struct vb2_queue *q) · 322 unmodified lines | ||
| 765 | 771 | q->is_output = V4L2_TYPE_IS_OUTPUT(q->type); |
| 766 | 772 | q->copy_timestamp = (q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) |
| 767 | 773 | == V4L2_BUF_FLAG_TIMESTAMP_COPY; |
| 774 | + /* | |
| 775 | + * For compatibility with vb1: if QBUF hasn't been called yet, then | |
| 776 | + * return POLLERR as well. This only affects capture queues, output | |
| 777 | + * queues will always initialize waiting_for_buffers to false. | |
| 778 | + */ | |
| 779 | + q->quirk_poll_must_check_waiting_for_buffers = true; | |
| 768 | 780 | |
| 769 | 781 | return vb2_core_queue_init(q); |
| 770 | 782 | } |
| @@ -818,14 +830,6 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) · 47 unmodified lines | ||
| 818 | 830 | poll_wait(file, &fh->wait, wait); |
| 819 | 831 | } |
| 820 | 832 | |
| 821 | − /* | |
| 822 | − * For compatibility with vb1: if QBUF hasn't been called yet, then | |
| 823 | − * return POLLERR as well. This only affects capture queues, output | |
| 824 | − * queues will always initialize waiting_for_buffers to false. | |
| 825 | − */ | |
| 826 | − if (q->waiting_for_buffers && (req_events & (POLLIN | POLLRDNORM))) | |
| 827 | − return POLLERR; | |
| 828 | − | |
| 829 | 833 | return res | vb2_core_poll(q, file, wait); |
| 830 | 834 | } |
| 831 | 835 | EXPORT_SYMBOL_GPL(vb2_poll); |
| @@ -223,6 +223,13 @@ int __detach_context(struct cxl_context *ctx) · 222 unmodified lines | ||
| 223 | 223 | cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)); |
| 224 | 224 | flush_work(&ctx->fault_work); /* Only needed for dedicated process */ |
| 225 | 225 | |
| 226 | + /* | |
| 227 | + * Wait until no further interrupts are presented by the PSL | |
| 228 | + * for this context. | |
| 229 | + */ | |
| 230 | + if (cxl_ops->irq_wait) | |
| 231 | + cxl_ops->irq_wait(ctx); | |
| 232 | + | |
| 226 | 233 | /* release the reference to the group leader and mm handling pid */ |
| 227 | 234 | put_pid(ctx->pid); |
| 228 | 235 | put_pid(ctx->glpid); |
| @@ -274,6 +274,7 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0}; · 273 unmodified lines | ||
| 274 | 274 | #define CXL_PSL_DSISR_An_PE (1ull << (63-4)) /* PSL Error (implementation specific) */ |
| 275 | 275 | #define CXL_PSL_DSISR_An_AE (1ull << (63-5)) /* AFU Error */ |
| 276 | 276 | #define CXL_PSL_DSISR_An_OC (1ull << (63-6)) /* OS Context Warning */ |
| 277 | +#define CXL_PSL_DSISR_PENDING (CXL_PSL_DSISR_TRANS | CXL_PSL_DSISR_An_PE | CXL_PSL_DSISR_An_AE | CXL_PSL_DSISR_An_OC) | |
| 277 | 278 | /* NOTE: Bits 32:63 are undefined if DSISR[DS] = 1 */ |
| 278 | 279 | #define CXL_PSL_DSISR_An_M DSISR_NOHPTE /* PTE not found */ |
| 279 | 280 | #define CXL_PSL_DSISR_An_P DSISR_PROTFAULT /* Storage protection violation */ |
| @@ -855,6 +856,7 @@ struct cxl_backend_ops { · 575 unmodified lines | ||
| 855 | 856 | u64 dsisr, u64 errstat); |
| 856 | 857 | irqreturn_t (*psl_interrupt)(int irq, void *data); |
| 857 | 858 | int (*ack_irq)(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask); |
| 859 | + void (*irq_wait)(struct cxl_context *ctx); | |
| 858 | 860 | int (*attach_process)(struct cxl_context *ctx, bool kernel, |
| 859 | 861 | u64 wed, u64 amr); |
| 860 | 862 | int (*detach_process)(struct cxl_context *ctx); |
| @@ -203,7 +203,6 @@ unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq, · 202 unmodified lines | ||
| 203 | 203 | void cxl_unmap_irq(unsigned int virq, void *cookie) |
| 204 | 204 | { |
| 205 | 205 | free_irq(virq, cookie); |
| 206 | − irq_dispose_mapping(virq); | |
| 207 | 206 | } |
| 208 | 207 | |
| 209 | 208 | int cxl_register_one_irq(struct cxl *adapter, |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/mutex.h> |
| 15 | 15 | #include <linux/mm.h> |
| 16 | 16 | #include <linux/uaccess.h> |
| 17 | +#include <linux/delay.h> | |
| 17 | 18 | #include <asm/synch.h> |
| 18 | 19 | #include <misc/cxl-base.h> |
| 19 | 20 | |
| @@ -797,6 +798,35 @@ static irqreturn_t native_irq_multiplexed(int irq, void *data) · 777 unmodified lines | ||
| 797 | 798 | return fail_psl_irq(afu, &irq_info); |
| 798 | 799 | } |
| 799 | 800 | |
| 801 | +void native_irq_wait(struct cxl_context *ctx) | |
| 802 | +{ | |
| 803 | + u64 dsisr; | |
| 804 | + int timeout = 1000; | |
| 805 | + int ph; | |
| 806 | + | |
| 807 | + /* | |
| 808 | + * Wait until no further interrupts are presented by the PSL | |
| 809 | + * for this context. | |
| 810 | + */ | |
| 811 | + while (timeout--) { | |
| 812 | + ph = cxl_p2n_read(ctx->afu, CXL_PSL_PEHandle_An) & 0xffff; | |
| 813 | + if (ph != ctx->pe) | |
| 814 | + return; | |
| 815 | + dsisr = cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An); | |
| 816 | + if ((dsisr & CXL_PSL_DSISR_PENDING) == 0) | |
| 817 | + return; | |
| 818 | + /* | |
| 819 | + * We are waiting for the workqueue to process our | |
| 820 | + * irq, so need to let that run here. | |
| 821 | + */ | |
| 822 | + msleep(1); | |
| 823 | + } | |
| 824 | + | |
| 825 | + dev_warn(&ctx->afu->dev, "WARNING: waiting on DSI for PE %i" | |
| 826 | + " DSISR %016llx!\n", ph, dsisr); | |
| 827 | + return; | |
| 828 | +} | |
| 829 | + | |
| 800 | 830 | static irqreturn_t native_slice_irq_err(int irq, void *data) |
| 801 | 831 | { |
| 802 | 832 | struct cxl_afu *afu = data; |
| @@ -1076,6 +1106,7 @@ const struct cxl_backend_ops cxl_native_ops = { · 273 unmodified lines | ||
| 1076 | 1106 | .handle_psl_slice_error = native_handle_psl_slice_error, |
| 1077 | 1107 | .psl_interrupt = NULL, |
| 1078 | 1108 | .ack_irq = native_ack_irq, |
| 1109 | + .irq_wait = native_irq_wait, | |
| 1079 | 1110 | .attach_process = native_attach_process, |
| 1080 | 1111 | .detach_process = native_detach_process, |
| 1081 | 1112 | .support_attributes = native_support_attributes, |
| @@ -945,6 +945,11 @@ static long vop_ioctl(struct file *f, unsigned int cmd, unsigned long arg) · 944 unmodified lines | ||
| 945 | 945 | ret = -EFAULT; |
| 946 | 946 | goto free_ret; |
| 947 | 947 | } |
| 948 | + /* Ensure desc has not changed between the two reads */ | |
| 949 | + if (memcmp(&dd, dd_config, sizeof(dd))) { | |
| 950 | + ret = -EINVAL; | |
| 951 | + goto free_ret; | |
| 952 | + } | |
| 948 | 953 | mutex_lock(&vdev->vdev_mutex); |
| 949 | 954 | mutex_lock(&vi->vop_mutex); |
| 950 | 955 | ret = vop_virtio_add_device(vdev, dd_config); |
| @@ -97,6 +97,7 @@ config MMC_RICOH_MMC · 96 unmodified lines | ||
| 97 | 97 | config MMC_SDHCI_ACPI |
| 98 | 98 | tristate "SDHCI support for ACPI enumerated SDHCI controllers" |
| 99 | 99 | depends on MMC_SDHCI && ACPI |
| 100 | + select IOSF_MBI if X86 | |
| 100 | 101 | help |
| 101 | 102 | This selects support for ACPI enumerated SDHCI controllers, |
| 102 | 103 | identified by ACPI Compatibility ID PNP0D40 or specific |
| @@ -41,6 +41,11 @@ · 40 unmodified lines | ||
| 41 | 41 | #include <linux/mmc/pm.h> |
| 42 | 42 | #include <linux/mmc/slot-gpio.h> |
| 43 | 43 | |
| 44 | +#ifdef CONFIG_X86 | |
| 45 | +#include <asm/cpu_device_id.h> | |
| 46 | +#include <asm/iosf_mbi.h> | |
| 47 | +#endif | |
| 48 | + | |
| 44 | 49 | #include "sdhci.h" |
| 45 | 50 | |
| 46 | 51 | enum { |
| @@ -116,6 +121,75 @@ static const struct sdhci_acpi_chip sdhci_acpi_chip_int = { · 69 unmodified lines | ||
| 116 | 121 | .ops = &sdhci_acpi_ops_int, |
| 117 | 122 | }; |
| 118 | 123 | |
| 124 | +#ifdef CONFIG_X86 | |
| 125 | + | |
| 126 | +static bool sdhci_acpi_byt(void) | |
| 127 | +{ | |
| 128 | + static const struct x86_cpu_id byt[] = { | |
| 129 | + { X86_VENDOR_INTEL, 6, 0x37 }, | |
| 130 | + {} | |
| 131 | + }; | |
| 132 | + | |
| 133 | + return x86_match_cpu(byt); | |
| 134 | +} | |
| 135 | + | |
| 136 | +#define BYT_IOSF_SCCEP 0x63 | |
| 137 | +#define BYT_IOSF_OCP_NETCTRL0 0x1078 | |
| 138 | +#define BYT_IOSF_OCP_TIMEOUT_BASE GENMASK(10, 8) | |
| 139 | + | |
| 140 | +static void sdhci_acpi_byt_setting(struct device *dev) | |
| 141 | +{ | |
| 142 | + u32 val = 0; | |
| 143 | + | |
| 144 | + if (!sdhci_acpi_byt()) | |
| 145 | + return; | |
| 146 | + | |
| 147 | + if (iosf_mbi_read(BYT_IOSF_SCCEP, MBI_CR_READ, BYT_IOSF_OCP_NETCTRL0, | |
| 148 | + &val)) { | |
| 149 | + dev_err(dev, "%s read error\n", __func__); | |
| 150 | + return; | |
| 151 | + } | |
| 152 | + | |
| 153 | + if (!(val & BYT_IOSF_OCP_TIMEOUT_BASE)) | |
| 154 | + return; | |
| 155 | + | |
| 156 | + val &= ~BYT_IOSF_OCP_TIMEOUT_BASE; | |
| 157 | + | |
| 158 | + if (iosf_mbi_write(BYT_IOSF_SCCEP, MBI_CR_WRITE, BYT_IOSF_OCP_NETCTRL0, | |
| 159 | + val)) { | |
| 160 | + dev_err(dev, "%s write error\n", __func__); | |
| 161 | + return; | |
| 162 | + } | |
| 163 | + | |
| 164 | + dev_dbg(dev, "%s completed\n", __func__); | |
| 165 | +} | |
| 166 | + | |
| 167 | +static bool sdhci_acpi_byt_defer(struct device *dev) | |
| 168 | +{ | |
| 169 | + if (!sdhci_acpi_byt()) | |
| 170 | + return false; | |
| 171 | + | |
| 172 | + if (!iosf_mbi_available()) | |
| 173 | + return true; | |
| 174 | + | |
| 175 | + sdhci_acpi_byt_setting(dev); | |
| 176 | + | |
| 177 | + return false; | |
| 178 | +} | |
| 179 | + | |
| 180 | +#else | |
| 181 | + | |
| 182 | +static inline void sdhci_acpi_byt_setting(struct device *dev) | |
| 183 | +{ | |
| 184 | +} | |
| 185 | + | |
| 186 | +static inline bool sdhci_acpi_byt_defer(struct device *dev) | |
| 187 | +{ | |
| 188 | + return false; | |
| 189 | +} | |
| 190 | + | |
| 191 | +#endif | |
| 192 | + | |
| 119 | 193 | static int bxt_get_cd(struct mmc_host *mmc) |
| 120 | 194 | { |
| 121 | 195 | int gpio_cd = mmc_gpio_get_cd(mmc); |
| @@ -322,6 +396,9 @@ static int sdhci_acpi_probe(struct platform_device *pdev) · 200 unmodified lines | ||
| 322 | 396 | if (acpi_bus_get_status(device) || !device->status.present) |
| 323 | 397 | return -ENODEV; |
| 324 | 398 | |
| 399 | + if (sdhci_acpi_byt_defer(dev)) | |
| 400 | + return -EPROBE_DEFER; | |
| 401 | + | |
| 325 | 402 | hid = acpi_device_hid(device); |
| 326 | 403 | uid = device->pnp.unique_id; |
| 327 | 404 | |
| @@ -447,6 +524,8 @@ static int sdhci_acpi_resume(struct device *dev) · 119 unmodified lines | ||
| 447 | 524 | { |
| 448 | 525 | struct sdhci_acpi_host *c = dev_get_drvdata(dev); |
| 449 | 526 | |
| 527 | + sdhci_acpi_byt_setting(&c->pdev->dev); | |
| 528 | + | |
| 450 | 529 | return sdhci_resume_host(c->host); |
| 451 | 530 | } |
| 452 | 531 | |
| @@ -470,6 +549,8 @@ static int sdhci_acpi_runtime_resume(struct device *dev) · 17 unmodified lines | ||
| 470 | 549 | { |
| 471 | 550 | struct sdhci_acpi_host *c = dev_get_drvdata(dev); |
| 472 | 551 | |
| 552 | + sdhci_acpi_byt_setting(&c->pdev->dev); | |
| 553 | + | |
| 473 | 554 | return sdhci_runtime_resume_host(c->host); |
| 474 | 555 | } |
| 475 | 556 | |
| @@ -1129,6 +1129,11 @@ static int sunxi_mmc_probe(struct platform_device *pdev) · 1128 unmodified lines | ||
| 1129 | 1129 | MMC_CAP_1_8V_DDR | |
| 1130 | 1130 | MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ; |
| 1131 | 1131 | |
| 1132 | + /* TODO MMC DDR is not working on A80 */ | |
| 1133 | + if (of_device_is_compatible(pdev->dev.of_node, | |
| 1134 | + "allwinner,sun9i-a80-mmc")) | |
| 1135 | + mmc->caps &= ~MMC_CAP_1_8V_DDR; | |
| 1136 | + | |
| 1132 | 1137 | ret = mmc_of_parse(mmc); |
| 1133 | 1138 | if (ret) |
| 1134 | 1139 | goto error_free_dma; |
| @@ -62,9 +62,8 @@ config DUMMY · 61 unmodified lines | ||
| 62 | 62 | this device is consigned into oblivion) with a configurable IP |
| 63 | 63 | address. It is most commonly used in order to make your currently |
| 64 | 64 | inactive SLIP address seem like a real address for local programs. |
| 65 | − If you use SLIP or PPP, you might want to say Y here. Since this | |
| 66 | − thing often comes in handy, the default is Y. It won't enlarge your | |
| 67 | − kernel either. What a deal. Read about it in the Network | |
| 65 | + If you use SLIP or PPP, you might want to say Y here. It won't | |
| 66 | + enlarge your kernel. What a deal. Read about it in the Network | |
| 68 | 67 | Administrator's Guide, available from |
| 69 | 68 | <http://www.tldp.org/docs.html#guide>. |
| 70 | 69 | |
| @@ -2181,7 +2181,7 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, · 2180 unmodified lines | ||
| 2181 | 2181 | struct net_device *bridge) |
| 2182 | 2182 | { |
| 2183 | 2183 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
| 2184 | − int i, err; | |
| 2184 | + int i, err = 0; | |
| 2185 | 2185 | |
| 2186 | 2186 | mutex_lock(&ps->smi_mutex); |
| 2187 | 2187 | |
| @@ -581,12 +581,30 @@ static inline int bnxt_alloc_rx_page(struct bnxt *bp, · 580 unmodified lines | ||
| 581 | 581 | struct page *page; |
| 582 | 582 | dma_addr_t mapping; |
| 583 | 583 | u16 sw_prod = rxr->rx_sw_agg_prod; |
| 584 | + unsigned int offset = 0; | |
| 584 | 585 | |
| 585 | − page = alloc_page(gfp); | |
| 586 | − if (!page) | |
| 587 | − return -ENOMEM; | |
| 586 | + if (PAGE_SIZE > BNXT_RX_PAGE_SIZE) { | |
| 587 | + page = rxr->rx_page; | |
| 588 | + if (!page) { | |
| 589 | + page = alloc_page(gfp); | |
| 590 | + if (!page) | |
| 591 | + return -ENOMEM; | |
| 592 | + rxr->rx_page = page; | |
| 593 | + rxr->rx_page_offset = 0; | |
| 594 | + } | |
| 595 | + offset = rxr->rx_page_offset; | |
| 596 | + rxr->rx_page_offset += BNXT_RX_PAGE_SIZE; | |
| 597 | + if (rxr->rx_page_offset == PAGE_SIZE) | |
| 598 | + rxr->rx_page = NULL; | |
| 599 | + else | |
| 600 | + get_page(page); | |
| 601 | + } else { | |
| 602 | + page = alloc_page(gfp); | |
| 603 | + if (!page) | |
| 604 | + return -ENOMEM; | |
| 605 | + } | |
| 588 | 606 | |
| 589 | − mapping = dma_map_page(&pdev->dev, page, 0, PAGE_SIZE, | |
| 607 | + mapping = dma_map_page(&pdev->dev, page, offset, BNXT_RX_PAGE_SIZE, | |
| 590 | 608 | PCI_DMA_FROMDEVICE); |
| 591 | 609 | if (dma_mapping_error(&pdev->dev, mapping)) { |
| 592 | 610 | __free_page(page); |
| @@ -601,6 +619,7 @@ static inline int bnxt_alloc_rx_page(struct bnxt *bp, · 8 unmodified lines | ||
| 601 | 619 | rxr->rx_sw_agg_prod = NEXT_RX_AGG(sw_prod); |
| 602 | 620 | |
| 603 | 621 | rx_agg_buf->page = page; |
| 622 | + rx_agg_buf->offset = offset; | |
| 604 | 623 | rx_agg_buf->mapping = mapping; |
| 605 | 624 | rxbd->rx_bd_haddr = cpu_to_le64(mapping); |
| 606 | 625 | rxbd->rx_bd_opaque = sw_prod; |
| @@ -642,6 +661,7 @@ static void bnxt_reuse_rx_agg_bufs(struct bnxt_napi *bnapi, u16 cp_cons, · 35 unmodified lines | ||
| 642 | 661 | page = cons_rx_buf->page; |
| 643 | 662 | cons_rx_buf->page = NULL; |
| 644 | 663 | prod_rx_buf->page = page; |
| 664 | + prod_rx_buf->offset = cons_rx_buf->offset; | |
| 645 | 665 | |
| 646 | 666 | prod_rx_buf->mapping = cons_rx_buf->mapping; |
| 647 | 667 | |
| @@ -709,7 +729,8 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp, struct bnxt_napi *bnapi, · 61 unmodified lines | ||
| 709 | 729 | RX_AGG_CMP_LEN) >> RX_AGG_CMP_LEN_SHIFT; |
| 710 | 730 | |
| 711 | 731 | cons_rx_buf = &rxr->rx_agg_ring[cons]; |
| 712 | − skb_fill_page_desc(skb, i, cons_rx_buf->page, 0, frag_len); | |
| 732 | + skb_fill_page_desc(skb, i, cons_rx_buf->page, | |
| 733 | + cons_rx_buf->offset, frag_len); | |
| 713 | 734 | __clear_bit(cons, rxr->rx_agg_bmap); |
| 714 | 735 | |
| 715 | 736 | /* It is possible for bnxt_alloc_rx_page() to allocate |
| @@ -740,7 +761,7 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp, struct bnxt_napi *bnapi, · 24 unmodified lines | ||
| 740 | 761 | return NULL; |
| 741 | 762 | } |
| 742 | 763 | |
| 743 | − dma_unmap_page(&pdev->dev, mapping, PAGE_SIZE, | |
| 764 | + dma_unmap_page(&pdev->dev, mapping, BNXT_RX_PAGE_SIZE, | |
| 744 | 765 | PCI_DMA_FROMDEVICE); |
| 745 | 766 | |
| 746 | 767 | skb->data_len += frag_len; |
| @@ -1584,13 +1605,17 @@ static void bnxt_free_rx_skbs(struct bnxt *bp) · 837 unmodified lines | ||
| 1584 | 1605 | |
| 1585 | 1606 | dma_unmap_page(&pdev->dev, |
| 1586 | 1607 | dma_unmap_addr(rx_agg_buf, mapping), |
| 1587 | − PAGE_SIZE, PCI_DMA_FROMDEVICE); | |
| 1608 | + BNXT_RX_PAGE_SIZE, PCI_DMA_FROMDEVICE); | |
| 1588 | 1609 | |
| 1589 | 1610 | rx_agg_buf->page = NULL; |
| 1590 | 1611 | __clear_bit(j, rxr->rx_agg_bmap); |
| 1591 | 1612 | |
| 1592 | 1613 | __free_page(page); |
| 1593 | 1614 | } |
| 1615 | + if (rxr->rx_page) { | |
| 1616 | + __free_page(rxr->rx_page); | |
| 1617 | + rxr->rx_page = NULL; | |
| 1618 | + } | |
| 1594 | 1619 | } |
| 1595 | 1620 | } |
| 1596 | 1621 | |
| @@ -1973,7 +1998,7 @@ static int bnxt_init_one_rx_ring(struct bnxt *bp, int ring_nr) · 376 unmodified lines | ||
| 1973 | 1998 | if (!(bp->flags & BNXT_FLAG_AGG_RINGS)) |
| 1974 | 1999 | return 0; |
| 1975 | 2000 | |
| 1976 | − type = ((u32)PAGE_SIZE << RX_BD_LEN_SHIFT) | | |
| 2001 | + type = ((u32)BNXT_RX_PAGE_SIZE << RX_BD_LEN_SHIFT) | | |
| 1977 | 2002 | RX_BD_TYPE_RX_AGG_BD | RX_BD_FLAGS_SOP; |
| 1978 | 2003 | |
| 1979 | 2004 | bnxt_init_rxbd_pages(ring, type); |
| @@ -2164,7 +2189,7 @@ void bnxt_set_ring_params(struct bnxt *bp) · 184 unmodified lines | ||
| 2164 | 2189 | bp->rx_agg_nr_pages = 0; |
| 2165 | 2190 | |
| 2166 | 2191 | if (bp->flags & BNXT_FLAG_TPA) |
| 2167 | − agg_factor = 4; | |
| 2192 | + agg_factor = min_t(u32, 4, 65536 / BNXT_RX_PAGE_SIZE); | |
| 2168 | 2193 | |
| 2169 | 2194 | bp->flags &= ~BNXT_FLAG_JUMBO; |
| 2170 | 2195 | if (rx_space > PAGE_SIZE) { |
| @@ -3020,12 +3045,12 @@ static int bnxt_hwrm_vnic_set_tpa(struct bnxt *bp, u16 vnic_id, u32 tpa_flags) · 849 unmodified lines | ||
| 3020 | 3045 | /* Number of segs are log2 units, and first packet is not |
| 3021 | 3046 | * included as part of this units. |
| 3022 | 3047 | */ |
| 3023 | − if (mss <= PAGE_SIZE) { | |
| 3024 | − n = PAGE_SIZE / mss; | |
| 3048 | + if (mss <= BNXT_RX_PAGE_SIZE) { | |
| 3049 | + n = BNXT_RX_PAGE_SIZE / mss; | |
| 3025 | 3050 | nsegs = (MAX_SKB_FRAGS - 1) * n; |
| 3026 | 3051 | } else { |
| 3027 | − n = mss / PAGE_SIZE; | |
| 3028 | − if (mss & (PAGE_SIZE - 1)) | |
| 3052 | + n = mss / BNXT_RX_PAGE_SIZE; | |
| 3053 | + if (mss & (BNXT_RX_PAGE_SIZE - 1)) | |
| 3029 | 3054 | n++; |
| 3030 | 3055 | nsegs = (MAX_SKB_FRAGS - n) / n; |
| 3031 | 3056 | } |
| @@ -4309,7 +4334,7 @@ static int bnxt_setup_int_mode(struct bnxt *bp) · 1277 unmodified lines | ||
| 4309 | 4334 | if (bp->flags & BNXT_FLAG_MSIX_CAP) |
| 4310 | 4335 | rc = bnxt_setup_msix(bp); |
| 4311 | 4336 | |
| 4312 | − if (!(bp->flags & BNXT_FLAG_USING_MSIX)) { | |
| 4337 | + if (!(bp->flags & BNXT_FLAG_USING_MSIX) && BNXT_PF(bp)) { | |
| 4313 | 4338 | /* fallback to INTA */ |
| 4314 | 4339 | rc = bnxt_setup_inta(bp); |
| 4315 | 4340 | } |
| @@ -407,6 +407,15 @@ struct rx_tpa_end_cmp_ext { · 406 unmodified lines | ||
| 407 | 407 | |
| 408 | 408 | #define BNXT_PAGE_SIZE (1 << BNXT_PAGE_SHIFT) |
| 409 | 409 | |
| 410 | +/* The RXBD length is 16-bit so we can only support page sizes < 64K */ | |
| 411 | +#if (PAGE_SHIFT > 15) | |
| 412 | +#define BNXT_RX_PAGE_SHIFT 15 | |
| 413 | +#else | |
| 414 | +#define BNXT_RX_PAGE_SHIFT PAGE_SHIFT | |
| 415 | +#endif | |
| 416 | + | |
| 417 | +#define BNXT_RX_PAGE_SIZE (1 << BNXT_RX_PAGE_SHIFT) | |
| 418 | + | |
| 410 | 419 | #define BNXT_MIN_PKT_SIZE 45 |
| 411 | 420 | |
| 412 | 421 | #define BNXT_NUM_TESTS(bp) 0 |
| @@ -506,6 +515,7 @@ struct bnxt_sw_rx_bd { · 93 unmodified lines | ||
| 506 | 515 | |
| 507 | 516 | struct bnxt_sw_rx_agg_bd { |
| 508 | 517 | struct page *page; |
| 518 | + unsigned int offset; | |
| 509 | 519 | dma_addr_t mapping; |
| 510 | 520 | }; |
| 511 | 521 | |
| @@ -586,6 +596,9 @@ struct bnxt_rx_ring_info { · 74 unmodified lines | ||
| 586 | 596 | unsigned long *rx_agg_bmap; |
| 587 | 597 | u16 rx_agg_bmap_size; |
| 588 | 598 | |
| 599 | + struct page *rx_page; | |
| 600 | + unsigned int rx_page_offset; | |
| 601 | + | |
| 589 | 602 | dma_addr_t rx_desc_mapping[MAX_RX_PAGES]; |
| 590 | 603 | dma_addr_t rx_agg_desc_mapping[MAX_RX_AGG_PAGES]; |
| 591 | 604 | |
| @@ -441,7 +441,7 @@ static int macb_mii_init(struct macb *bp) · 440 unmodified lines | ||
| 441 | 441 | snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", |
| 442 | 442 | bp->pdev->name, bp->pdev->id); |
| 443 | 443 | bp->mii_bus->priv = bp; |
| 444 | − bp->mii_bus->parent = &bp->dev->dev; | |
| 444 | + bp->mii_bus->parent = &bp->pdev->dev; | |
| 445 | 445 | pdata = dev_get_platdata(&bp->pdev->dev); |
| 446 | 446 | |
| 447 | 447 | dev_set_drvdata(&bp->dev->dev, bp->mii_bus); |
| @@ -458,7 +458,8 @@ static int macb_mii_init(struct macb *bp) · 10 unmodified lines | ||
| 458 | 458 | struct phy_device *phydev; |
| 459 | 459 | |
| 460 | 460 | phydev = mdiobus_scan(bp->mii_bus, i); |
| 461 | − if (IS_ERR(phydev)) { | |
| 461 | + if (IS_ERR(phydev) && | |
| 462 | + PTR_ERR(phydev) != -ENODEV) { | |
| 462 | 463 | err = PTR_ERR(phydev); |
| 463 | 464 | break; |
| 464 | 465 | } |
| @@ -3019,29 +3020,36 @@ static int macb_probe(struct platform_device *pdev) · 2554 unmodified lines | ||
| 3019 | 3020 | if (err) |
| 3020 | 3021 | goto err_out_free_netdev; |
| 3021 | 3022 | |
| 3023 | + err = macb_mii_init(bp); | |
| 3024 | + if (err) | |
| 3025 | + goto err_out_free_netdev; | |
| 3026 | + | |
| 3027 | + phydev = bp->phy_dev; | |
| 3028 | + | |
| 3029 | + netif_carrier_off(dev); | |
| 3030 | + | |
| 3022 | 3031 | err = register_netdev(dev); |
| 3023 | 3032 | if (err) { |
| 3024 | 3033 | dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); |
| 3025 | − goto err_out_unregister_netdev; | |
| 3034 | + goto err_out_unregister_mdio; | |
| 3026 | 3035 | } |
| 3027 | 3036 | |
| 3028 | − err = macb_mii_init(bp); | |
| 3029 | − if (err) | |
| 3030 | − goto err_out_unregister_netdev; | |
| 3031 | − | |
| 3032 | − netif_carrier_off(dev); | |
| 3037 | + phy_attached_info(phydev); | |
| 3033 | 3038 | |
| 3034 | 3039 | netdev_info(dev, "Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\n", |
| 3035 | 3040 | macb_is_gem(bp) ? "GEM" : "MACB", macb_readl(bp, MID), |
| 3036 | 3041 | dev->base_addr, dev->irq, dev->dev_addr); |
| 3037 | 3042 | |
| 3038 | − phydev = bp->phy_dev; | |
| 3039 | − phy_attached_info(phydev); | |
| 3040 | − | |
| 3041 | 3043 | return 0; |
| 3042 | 3044 | |
| 3043 | −err_out_unregister_netdev: | |
| 3044 | − unregister_netdev(dev); | |
| 3045 | +err_out_unregister_mdio: | |
| 3046 | + phy_disconnect(bp->phy_dev); | |
| 3047 | + mdiobus_unregister(bp->mii_bus); | |
| 3048 | + mdiobus_free(bp->mii_bus); | |
| 3049 | + | |
| 3050 | + /* Shutdown the PHY if there is a GPIO reset */ | |
| 3051 | + if (bp->reset_gpio) | |
| 3052 | + gpiod_set_value(bp->reset_gpio, 0); | |
| 3045 | 3053 | |
| 3046 | 3054 | err_out_free_netdev: |
| 3047 | 3055 | free_netdev(dev); |
| @@ -576,7 +576,7 @@ static void setup_rss(struct adapter *adap) · 575 unmodified lines | ||
| 576 | 576 | unsigned int nq0 = adap2pinfo(adap, 0)->nqsets; |
| 577 | 577 | unsigned int nq1 = adap->port[1] ? adap2pinfo(adap, 1)->nqsets : 1; |
| 578 | 578 | u8 cpus[SGE_QSETS + 1]; |
| 579 | − u16 rspq_map[RSS_TABLE_SIZE]; | |
| 579 | + u16 rspq_map[RSS_TABLE_SIZE + 1]; | |
| 580 | 580 | |
| 581 | 581 | for (i = 0; i < SGE_QSETS; ++i) |
| 582 | 582 | cpus[i] = i; |
| @@ -586,6 +586,7 @@ static void setup_rss(struct adapter *adap) · 3 unmodified lines | ||
| 586 | 586 | rspq_map[i] = i % nq0; |
| 587 | 587 | rspq_map[i + RSS_TABLE_SIZE / 2] = (i % nq1) + nq0; |
| 588 | 588 | } |
| 589 | + rspq_map[RSS_TABLE_SIZE] = 0xffff; /* terminator */ | |
| 589 | 590 | |
| 590 | 591 | t3_config_rss(adap, F_RQFEEDBACKENABLE | F_TNLLKPEN | F_TNLMAPEN | |
| 591 | 592 | F_TNLPRTEN | F_TNL2TUPEN | F_TNL4TUPEN | |
| @@ -3354,8 +3354,7 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb, · 3353 unmodified lines | ||
| 3354 | 3354 | /* Enable per-CPU interrupts on the CPU that is |
| 3355 | 3355 | * brought up. |
| 3356 | 3356 | */ |
| 3357 | − smp_call_function_single(cpu, mvneta_percpu_enable, | |
| 3358 | − pp, true); | |
| 3357 | + mvneta_percpu_enable(pp); | |
| 3359 | 3358 | |
| 3360 | 3359 | /* Enable per-CPU interrupt on the one CPU we care |
| 3361 | 3360 | * about. |
| @@ -3387,8 +3386,7 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb, · 25 unmodified lines | ||
| 3387 | 3386 | /* Disable per-CPU interrupts on the CPU that is |
| 3388 | 3387 | * brought down. |
| 3389 | 3388 | */ |
| 3390 | − smp_call_function_single(cpu, mvneta_percpu_disable, | |
| 3391 | − pp, true); | |
| 3389 | + mvneta_percpu_disable(pp); | |
| 3392 | 3390 | |
| 3393 | 3391 | break; |
| 3394 | 3392 | case CPU_DEAD: |
| @@ -979,6 +979,8 @@ static int pxa168_init_phy(struct net_device *dev) · 978 unmodified lines | ||
| 979 | 979 | return 0; |
| 980 | 980 | |
| 981 | 981 | pep->phy = mdiobus_scan(pep->smi_bus, pep->phy_addr); |
| 982 | + if (IS_ERR(pep->phy)) | |
| 983 | + return PTR_ERR(pep->phy); | |
| 982 | 984 | if (!pep->phy) |
| 983 | 985 | return -ENODEV; |
| 984 | 986 | |
| @@ -405,7 +405,6 @@ static bool mlx4_en_process_tx_cq(struct net_device *dev, · 404 unmodified lines | ||
| 405 | 405 | u32 packets = 0; |
| 406 | 406 | u32 bytes = 0; |
| 407 | 407 | int factor = priv->cqe_factor; |
| 408 | − u64 timestamp = 0; | |
| 409 | 408 | int done = 0; |
| 410 | 409 | int budget = priv->tx_work_limit; |
| 411 | 410 | u32 last_nr_txbb; |
| @@ -445,9 +444,12 @@ static bool mlx4_en_process_tx_cq(struct net_device *dev, · 33 unmodified lines | ||
| 445 | 444 | new_index = be16_to_cpu(cqe->wqe_index) & size_mask; |
| 446 | 445 | |
| 447 | 446 | do { |
| 447 | + u64 timestamp = 0; | |
| 448 | + | |
| 448 | 449 | txbbs_skipped += last_nr_txbb; |
| 449 | 450 | ring_index = (ring_index + last_nr_txbb) & size_mask; |
| 450 | − if (ring->tx_info[ring_index].ts_requested) | |
| 451 | + | |
| 452 | + if (unlikely(ring->tx_info[ring_index].ts_requested)) | |
| 451 | 453 | timestamp = mlx4_en_get_cqe_ts(cqe); |
| 452 | 454 | |
| 453 | 455 | /* free next descriptor */ |
| @@ -14,6 +14,7 @@ config MLX5_CORE_EN · 13 unmodified lines | ||
| 14 | 14 | bool "Mellanox Technologies ConnectX-4 Ethernet support" |
| 15 | 15 | depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE |
| 16 | 16 | select PTP_1588_CLOCK |
| 17 | + select VXLAN if MLX5_CORE=y | |
| 17 | 18 | default n |
| 18 | 19 | ---help--- |
| 19 | 20 | Ethernet support in Mellanox Technologies ConnectX-4 NIC. |
| @@ -567,6 +567,7 @@ struct mlx5e_priv { · 566 unmodified lines | ||
| 567 | 567 | struct mlx5e_vxlan_db vxlan; |
| 568 | 568 | |
| 569 | 569 | struct mlx5e_params params; |
| 570 | + struct workqueue_struct *wq; | |
| 570 | 571 | struct work_struct update_carrier_work; |
| 571 | 572 | struct work_struct set_rx_mode_work; |
| 572 | 573 | struct delayed_work update_stats_work; |
| @@ -609,7 +610,7 @@ enum mlx5e_link_mode { · 36 unmodified lines | ||
| 609 | 610 | MLX5E_100GBASE_KR4 = 22, |
| 610 | 611 | MLX5E_100GBASE_LR4 = 23, |
| 611 | 612 | MLX5E_100BASE_TX = 24, |
| 612 | − MLX5E_100BASE_T = 25, | |
| 613 | + MLX5E_1000BASE_T = 25, | |
| 613 | 614 | MLX5E_10GBASE_T = 26, |
| 614 | 615 | MLX5E_25GBASE_CR = 27, |
| 615 | 616 | MLX5E_25GBASE_KR = 28, |
| @@ -138,10 +138,10 @@ static const struct { · 137 unmodified lines | ||
| 138 | 138 | [MLX5E_100BASE_TX] = { |
| 139 | 139 | .speed = 100, |
| 140 | 140 | }, |
| 141 | − [MLX5E_100BASE_T] = { | |
| 142 | − .supported = SUPPORTED_100baseT_Full, | |
| 143 | − .advertised = ADVERTISED_100baseT_Full, | |
| 144 | − .speed = 100, | |
| 141 | + [MLX5E_1000BASE_T] = { | |
| 142 | + .supported = SUPPORTED_1000baseT_Full, | |
| 143 | + .advertised = ADVERTISED_1000baseT_Full, | |
| 144 | + .speed = 1000, | |
| 145 | 145 | }, |
| 146 | 146 | [MLX5E_10GBASE_T] = { |
| 147 | 147 | .supported = SUPPORTED_10000baseT_Full, |
| @@ -262,9 +262,8 @@ static void mlx5e_update_stats_work(struct work_struct *work) · 261 unmodified lines | ||
| 262 | 262 | mutex_lock(&priv->state_lock); |
| 263 | 263 | if (test_bit(MLX5E_STATE_OPENED, &priv->state)) { |
| 264 | 264 | mlx5e_update_stats(priv); |
| 265 | − schedule_delayed_work(dwork, | |
| 266 | − msecs_to_jiffies( | |
| 267 | − MLX5E_UPDATE_STATS_INTERVAL)); | |
| 265 | + queue_delayed_work(priv->wq, dwork, | |
| 266 | + msecs_to_jiffies(MLX5E_UPDATE_STATS_INTERVAL)); | |
| 268 | 267 | } |
| 269 | 268 | mutex_unlock(&priv->state_lock); |
| 270 | 269 | } |
| @@ -280,7 +279,7 @@ static void mlx5e_async_event(struct mlx5_core_dev *mdev, void *vpriv, · 9 unmodified lines | ||
| 280 | 279 | switch (event) { |
| 281 | 280 | case MLX5_DEV_EVENT_PORT_UP: |
| 282 | 281 | case MLX5_DEV_EVENT_PORT_DOWN: |
| 283 | − schedule_work(&priv->update_carrier_work); | |
| 282 | + queue_work(priv->wq, &priv->update_carrier_work); | |
| 284 | 283 | break; |
| 285 | 284 | |
| 286 | 285 | default: |
| @@ -1404,24 +1403,50 @@ static int mlx5e_refresh_tirs_self_loopback_enable(struct mlx5e_priv *priv) · 1117 unmodified lines | ||
| 1404 | 1403 | return 0; |
| 1405 | 1404 | } |
| 1406 | 1405 | |
| 1407 | −static int mlx5e_set_dev_port_mtu(struct net_device *netdev) | |
| 1406 | +static int mlx5e_set_mtu(struct mlx5e_priv *priv, u16 mtu) | |
| 1408 | 1407 | { |
| 1409 | − struct mlx5e_priv *priv = netdev_priv(netdev); | |
| 1410 | 1408 | struct mlx5_core_dev *mdev = priv->mdev; |
| 1411 | − int hw_mtu; | |
| 1409 | + u16 hw_mtu = MLX5E_SW2HW_MTU(mtu); | |
| 1412 | 1410 | int err; |
| 1413 | 1411 | |
| 1414 | − err = mlx5_set_port_mtu(mdev, MLX5E_SW2HW_MTU(netdev->mtu), 1); | |
| 1412 | + err = mlx5_set_port_mtu(mdev, hw_mtu, 1); | |
| 1415 | 1413 | if (err) |
| 1416 | 1414 | return err; |
| 1417 | 1415 | |
| 1418 | − mlx5_query_port_oper_mtu(mdev, &hw_mtu, 1); | |
| 1416 | + /* Update vport context MTU */ | |
| 1417 | + mlx5_modify_nic_vport_mtu(mdev, hw_mtu); | |
| 1418 | + return 0; | |
| 1419 | +} | |
| 1420 | + | |
| 1421 | +static void mlx5e_query_mtu(struct mlx5e_priv *priv, u16 *mtu) | |
| 1422 | +{ | |
| 1423 | + struct mlx5_core_dev *mdev = priv->mdev; | |
| 1424 | + u16 hw_mtu = 0; | |
| 1425 | + int err; | |
| 1419 | 1426 | |
| 1420 | − if (MLX5E_HW2SW_MTU(hw_mtu) != netdev->mtu) | |
| 1421 | − netdev_warn(netdev, "%s: Port MTU %d is different than netdev mtu %d\n", | |
| 1422 | − __func__, MLX5E_HW2SW_MTU(hw_mtu), netdev->mtu); | |
| 1427 | + err = mlx5_query_nic_vport_mtu(mdev, &hw_mtu); | |
| 1428 | + if (err || !hw_mtu) /* fallback to port oper mtu */ | |
| 1429 | + mlx5_query_port_oper_mtu(mdev, &hw_mtu, 1); | |
| 1430 | + | |
| 1431 | + *mtu = MLX5E_HW2SW_MTU(hw_mtu); | |
| 1432 | +} | |
| 1433 | + | |
| 1434 | +static int mlx5e_set_dev_port_mtu(struct net_device *netdev) | |
| 1435 | +{ | |
| 1436 | + struct mlx5e_priv *priv = netdev_priv(netdev); | |
| 1437 | + u16 mtu; | |
| 1438 | + int err; | |
| 1423 | 1439 | |
| 1424 | − netdev->mtu = MLX5E_HW2SW_MTU(hw_mtu); | |
| 1440 | + err = mlx5e_set_mtu(priv, netdev->mtu); | |
| 1441 | + if (err) | |
| 1442 | + return err; | |
| 1443 | + | |
| 1444 | + mlx5e_query_mtu(priv, &mtu); | |
| 1445 | + if (mtu != netdev->mtu) | |
| 1446 | + netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n", | |
| 1447 | + __func__, mtu, netdev->mtu); | |
| 1448 | + | |
| 1449 | + netdev->mtu = mtu; | |
| 1425 | 1450 | return 0; |
| 1426 | 1451 | } |
| 1427 | 1452 | |
| @@ -1479,7 +1504,7 @@ int mlx5e_open_locked(struct net_device *netdev) · 51 unmodified lines | ||
| 1479 | 1504 | mlx5e_update_carrier(priv); |
| 1480 | 1505 | mlx5e_timestamp_init(priv); |
| 1481 | 1506 | |
| 1482 | − schedule_delayed_work(&priv->update_stats_work, 0); | |
| 1507 | + queue_delayed_work(priv->wq, &priv->update_stats_work, 0); | |
| 1483 | 1508 | |
| 1484 | 1509 | return 0; |
| 1485 | 1510 | |
| @@ -1935,7 +1960,7 @@ static void mlx5e_set_rx_mode(struct net_device *dev) · 449 unmodified lines | ||
| 1935 | 1960 | { |
| 1936 | 1961 | struct mlx5e_priv *priv = netdev_priv(dev); |
| 1937 | 1962 | |
| 1938 | − schedule_work(&priv->set_rx_mode_work); | |
| 1963 | + queue_work(priv->wq, &priv->set_rx_mode_work); | |
| 1939 | 1964 | } |
| 1940 | 1965 | |
| 1941 | 1966 | static int mlx5e_set_mac(struct net_device *netdev, void *addr) |
| @@ -1950,7 +1975,7 @@ static int mlx5e_set_mac(struct net_device *netdev, void *addr) · 8 unmodified lines | ||
| 1950 | 1975 | ether_addr_copy(netdev->dev_addr, saddr->sa_data); |
| 1951 | 1976 | netif_addr_unlock_bh(netdev); |
| 1952 | 1977 | |
| 1953 | − schedule_work(&priv->set_rx_mode_work); | |
| 1978 | + queue_work(priv->wq, &priv->set_rx_mode_work); | |
| 1954 | 1979 | |
| 1955 | 1980 | return 0; |
| 1956 | 1981 | } |
| @@ -1999,22 +2024,27 @@ static int mlx5e_set_features(struct net_device *netdev, · 42 unmodified lines | ||
| 1999 | 2024 | return err; |
| 2000 | 2025 | } |
| 2001 | 2026 | |
| 2027 | +#define MXL5_HW_MIN_MTU 64 | |
| 2028 | +#define MXL5E_MIN_MTU (MXL5_HW_MIN_MTU + ETH_FCS_LEN) | |
| 2029 | + | |
| 2002 | 2030 | static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu) |
| 2003 | 2031 | { |
| 2004 | 2032 | struct mlx5e_priv *priv = netdev_priv(netdev); |
| 2005 | 2033 | struct mlx5_core_dev *mdev = priv->mdev; |
| 2006 | 2034 | bool was_opened; |
| 2007 | − int max_mtu; | |
| 2035 | + u16 max_mtu; | |
| 2036 | + u16 min_mtu; | |
| 2008 | 2037 | int err = 0; |
| 2009 | 2038 | |
| 2010 | 2039 | mlx5_query_port_max_mtu(mdev, &max_mtu, 1); |
| 2011 | 2040 | |
| 2012 | 2041 | max_mtu = MLX5E_HW2SW_MTU(max_mtu); |
| 2042 | + min_mtu = MLX5E_HW2SW_MTU(MXL5E_MIN_MTU); | |
| 2013 | 2043 | |
| 2014 | − if (new_mtu > max_mtu) { | |
| 2044 | + if (new_mtu > max_mtu || new_mtu < min_mtu) { | |
| 2015 | 2045 | netdev_err(netdev, |
| 2016 | − "%s: Bad MTU (%d) > (%d) Max\n", | |
| 2017 | − __func__, new_mtu, max_mtu); | |
| 2046 | + "%s: Bad MTU (%d), valid range is: [%d..%d]\n", | |
| 2047 | + __func__, new_mtu, min_mtu, max_mtu); | |
| 2018 | 2048 | return -EINVAL; |
| 2019 | 2049 | } |
| 2020 | 2050 | |
| @@ -2127,7 +2157,7 @@ static void mlx5e_add_vxlan_port(struct net_device *netdev, · 106 unmodified lines | ||
| 2127 | 2157 | if (!mlx5e_vxlan_allowed(priv->mdev)) |
| 2128 | 2158 | return; |
| 2129 | 2159 | |
| 2130 | − mlx5e_vxlan_add_port(priv, be16_to_cpu(port)); | |
| 2160 | + mlx5e_vxlan_queue_work(priv, sa_family, be16_to_cpu(port), 1); | |
| 2131 | 2161 | } |
| 2132 | 2162 | |
| 2133 | 2163 | static void mlx5e_del_vxlan_port(struct net_device *netdev, |
| @@ -2138,7 +2168,7 @@ static void mlx5e_del_vxlan_port(struct net_device *netdev, · 4 unmodified lines | ||
| 2138 | 2168 | if (!mlx5e_vxlan_allowed(priv->mdev)) |
| 2139 | 2169 | return; |
| 2140 | 2170 | |
| 2141 | − mlx5e_vxlan_del_port(priv, be16_to_cpu(port)); | |
| 2171 | + mlx5e_vxlan_queue_work(priv, sa_family, be16_to_cpu(port), 0); | |
| 2142 | 2172 | } |
| 2143 | 2173 | |
| 2144 | 2174 | static netdev_features_t mlx5e_vxlan_features_check(struct mlx5e_priv *priv, |
| @@ -2467,10 +2497,14 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev) · 322 unmodified lines | ||
| 2467 | 2497 | |
| 2468 | 2498 | priv = netdev_priv(netdev); |
| 2469 | 2499 | |
| 2500 | + priv->wq = create_singlethread_workqueue("mlx5e"); | |
| 2501 | + if (!priv->wq) | |
| 2502 | + goto err_free_netdev; | |
| 2503 | + | |
| 2470 | 2504 | err = mlx5_alloc_map_uar(mdev, &priv->cq_uar, false); |
| 2471 | 2505 | if (err) { |
| 2472 | 2506 | mlx5_core_err(mdev, "alloc_map uar failed, %d\n", err); |
| 2473 | − goto err_free_netdev; | |
| 2507 | + goto err_destroy_wq; | |
| 2474 | 2508 | } |
| 2475 | 2509 | |
| 2476 | 2510 | err = mlx5_core_alloc_pd(mdev, &priv->pdn); |
| @@ -2549,7 +2583,7 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev) · 72 unmodified lines | ||
| 2549 | 2583 | vxlan_get_rx_port(netdev); |
| 2550 | 2584 | |
| 2551 | 2585 | mlx5e_enable_async_events(priv); |
| 2552 | − schedule_work(&priv->set_rx_mode_work); | |
| 2586 | + queue_work(priv->wq, &priv->set_rx_mode_work); | |
| 2553 | 2587 | |
| 2554 | 2588 | return priv; |
| 2555 | 2589 | |
| @@ -2586,6 +2620,9 @@ err_dealloc_pd: · 30 unmodified lines | ||
| 2586 | 2620 | err_unmap_free_uar: |
| 2587 | 2621 | mlx5_unmap_free_uar(mdev, &priv->cq_uar); |
| 2588 | 2622 | |
| 2623 | +err_destroy_wq: | |
| 2624 | + destroy_workqueue(priv->wq); | |
| 2625 | + | |
| 2589 | 2626 | err_free_netdev: |
| 2590 | 2627 | free_netdev(netdev); |
| 2591 | 2628 | |
| @@ -2599,10 +2636,19 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv) · 7 unmodified lines | ||
| 2599 | 2636 | |
| 2600 | 2637 | set_bit(MLX5E_STATE_DESTROYING, &priv->state); |
| 2601 | 2638 | |
| 2602 | − schedule_work(&priv->set_rx_mode_work); | |
| 2639 | + queue_work(priv->wq, &priv->set_rx_mode_work); | |
| 2603 | 2640 | mlx5e_disable_async_events(priv); |
| 2604 | − flush_scheduled_work(); | |
| 2605 | − unregister_netdev(netdev); | |
| 2641 | + flush_workqueue(priv->wq); | |
| 2642 | + if (test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) { | |
| 2643 | + netif_device_detach(netdev); | |
| 2644 | + mutex_lock(&priv->state_lock); | |
| 2645 | + if (test_bit(MLX5E_STATE_OPENED, &priv->state)) | |
| 2646 | + mlx5e_close_locked(netdev); | |
| 2647 | + mutex_unlock(&priv->state_lock); | |
| 2648 | + } else { | |
| 2649 | + unregister_netdev(netdev); | |
| 2650 | + } | |
| 2651 | + | |
| 2606 | 2652 | mlx5e_tc_cleanup(priv); |
| 2607 | 2653 | mlx5e_vxlan_cleanup(priv); |
| 2608 | 2654 | mlx5e_destroy_flow_tables(priv); |
| @@ -2615,7 +2661,11 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv) · 6 unmodified lines | ||
| 2615 | 2661 | mlx5_core_dealloc_transport_domain(priv->mdev, priv->tdn); |
| 2616 | 2662 | mlx5_core_dealloc_pd(priv->mdev, priv->pdn); |
| 2617 | 2663 | mlx5_unmap_free_uar(priv->mdev, &priv->cq_uar); |
| 2618 | − free_netdev(netdev); | |
| 2664 | + cancel_delayed_work_sync(&priv->update_stats_work); | |
| 2665 | + destroy_workqueue(priv->wq); | |
| 2666 | + | |
| 2667 | + if (!test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) | |
| 2668 | + free_netdev(netdev); | |
| 2619 | 2669 | } |
| 2620 | 2670 | |
| 2621 | 2671 | static void *mlx5e_get_netdev(void *vpriv) |
| @@ -1065,33 +1065,6 @@ unlock_fg: · 1064 unmodified lines | ||
| 1065 | 1065 | return rule; |
| 1066 | 1066 | } |
| 1067 | 1067 | |
| 1068 | −static struct mlx5_flow_rule *add_rule_to_auto_fg(struct mlx5_flow_table *ft, | |
| 1069 | − u8 match_criteria_enable, | |
| 1070 | − u32 *match_criteria, | |
| 1071 | − u32 *match_value, | |
| 1072 | − u8 action, | |
| 1073 | − u32 flow_tag, | |
| 1074 | − struct mlx5_flow_destination *dest) | |
| 1075 | −{ | |
| 1076 | − struct mlx5_flow_rule *rule; | |
| 1077 | − struct mlx5_flow_group *g; | |
| 1078 | − | |
| 1079 | − g = create_autogroup(ft, match_criteria_enable, match_criteria); | |
| 1080 | − if (IS_ERR(g)) | |
| 1081 | − return (void *)g; | |
| 1082 | − | |
| 1083 | − rule = add_rule_fg(g, match_value, | |
| 1084 | − action, flow_tag, dest); | |
| 1085 | − if (IS_ERR(rule)) { | |
| 1086 | − /* Remove assumes refcount > 0 and autogroup creates a group | |
| 1087 | − * with a refcount = 0. | |
| 1088 | − */ | |
| 1089 | − tree_get_node(&g->node); | |
| 1090 | − tree_remove_node(&g->node); | |
| 1091 | − } | |
| 1092 | − return rule; | |
| 1093 | −} | |
| 1094 | − | |
| 1095 | 1068 | static struct mlx5_flow_rule * |
| 1096 | 1069 | _mlx5_add_flow_rule(struct mlx5_flow_table *ft, |
| 1097 | 1070 | u8 match_criteria_enable, |
| @@ -1119,8 +1092,23 @@ _mlx5_add_flow_rule(struct mlx5_flow_table *ft, · 21 unmodified lines | ||
| 1119 | 1092 | goto unlock; |
| 1120 | 1093 | } |
| 1121 | 1094 | |
| 1122 | − rule = add_rule_to_auto_fg(ft, match_criteria_enable, match_criteria, | |
| 1123 | − match_value, action, flow_tag, dest); | |
| 1095 | + g = create_autogroup(ft, match_criteria_enable, match_criteria); | |
| 1096 | + if (IS_ERR(g)) { | |
| 1097 | + rule = (void *)g; | |
| 1098 | + goto unlock; | |
| 1099 | + } | |
| 1100 | + | |
| 1101 | + rule = add_rule_fg(g, match_value, | |
| 1102 | + action, flow_tag, dest); | |
| 1103 | + if (IS_ERR(rule)) { | |
| 1104 | + /* Remove assumes refcount > 0 and autogroup creates a group | |
| 1105 | + * with a refcount = 0. | |
| 1106 | + */ | |
| 1107 | + unlock_ref_node(&ft->node); | |
| 1108 | + tree_get_node(&g->node); | |
| 1109 | + tree_remove_node(&g->node); | |
| 1110 | + return rule; | |
| 1111 | + } | |
| 1124 | 1112 | unlock: |
| 1125 | 1113 | unlock_ref_node(&ft->node); |
| 1126 | 1114 | return rule; |
| @@ -1288,7 +1276,7 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev, · 161 unmodified lines | ||
| 1288 | 1276 | { |
| 1289 | 1277 | struct mlx5_flow_root_namespace *root_ns = dev->priv.root_ns; |
| 1290 | 1278 | int prio; |
| 1291 | − static struct fs_prio *fs_prio; | |
| 1279 | + struct fs_prio *fs_prio; | |
| 1292 | 1280 | struct mlx5_flow_namespace *ns; |
| 1293 | 1281 | |
| 1294 | 1282 | if (!root_ns) |
| @@ -966,7 +966,7 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv) · 965 unmodified lines | ||
| 966 | 966 | int err; |
| 967 | 967 | |
| 968 | 968 | mutex_lock(&dev->intf_state_mutex); |
| 969 | − if (dev->interface_state == MLX5_INTERFACE_STATE_UP) { | |
| 969 | + if (test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) { | |
| 970 | 970 | dev_warn(&dev->pdev->dev, "%s: interface is up, NOP\n", |
| 971 | 971 | __func__); |
| 972 | 972 | goto out; |
| @@ -1133,7 +1133,8 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv) · 160 unmodified lines | ||
| 1133 | 1133 | if (err) |
| 1134 | 1134 | pr_info("failed request module on %s\n", MLX5_IB_MOD); |
| 1135 | 1135 | |
| 1136 | − dev->interface_state = MLX5_INTERFACE_STATE_UP; | |
| 1136 | + clear_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state); | |
| 1137 | + set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); | |
| 1137 | 1138 | out: |
| 1138 | 1139 | mutex_unlock(&dev->intf_state_mutex); |
| 1139 | 1140 | |
| @@ -1207,7 +1208,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv) · 67 unmodified lines | ||
| 1207 | 1208 | } |
| 1208 | 1209 | |
| 1209 | 1210 | mutex_lock(&dev->intf_state_mutex); |
| 1210 | − if (dev->interface_state == MLX5_INTERFACE_STATE_DOWN) { | |
| 1211 | + if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) { | |
| 1211 | 1212 | dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n", |
| 1212 | 1213 | __func__); |
| 1213 | 1214 | goto out; |
| @@ -1241,7 +1242,8 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv) · 27 unmodified lines | ||
| 1241 | 1242 | mlx5_cmd_cleanup(dev); |
| 1242 | 1243 | |
| 1243 | 1244 | out: |
| 1244 | − dev->interface_state = MLX5_INTERFACE_STATE_DOWN; | |
| 1245 | + clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); | |
| 1246 | + set_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state); | |
| 1245 | 1247 | mutex_unlock(&dev->intf_state_mutex); |
| 1246 | 1248 | return err; |
| 1247 | 1249 | } |
| @@ -1452,6 +1454,18 @@ static const struct pci_error_handlers mlx5_err_handler = { · 204 unmodified lines | ||
| 1452 | 1454 | .resume = mlx5_pci_resume |
| 1453 | 1455 | }; |
| 1454 | 1456 | |
| 1457 | +static void shutdown(struct pci_dev *pdev) | |
| 1458 | +{ | |
| 1459 | + struct mlx5_core_dev *dev = pci_get_drvdata(pdev); | |
| 1460 | + struct mlx5_priv *priv = &dev->priv; | |
| 1461 | + | |
| 1462 | + dev_info(&pdev->dev, "Shutdown was called\n"); | |
| 1463 | + /* Notify mlx5 clients that the kernel is being shut down */ | |
| 1464 | + set_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &dev->intf_state); | |
| 1465 | + mlx5_unload_one(dev, priv); | |
| 1466 | + mlx5_pci_disable_device(dev); | |
| 1467 | +} | |
| 1468 | + | |
| 1455 | 1469 | static const struct pci_device_id mlx5_core_pci_table[] = { |
| 1456 | 1470 | { PCI_VDEVICE(MELLANOX, 0x1011) }, /* Connect-IB */ |
| 1457 | 1471 | { PCI_VDEVICE(MELLANOX, 0x1012), MLX5_PCI_DEV_IS_VF}, /* Connect-IB VF */ |
| @@ -1459,6 +1473,8 @@ static const struct pci_device_id mlx5_core_pci_table[] = { · 1 unmodified line | ||
| 1459 | 1473 | { PCI_VDEVICE(MELLANOX, 0x1014), MLX5_PCI_DEV_IS_VF}, /* ConnectX-4 VF */ |
| 1460 | 1474 | { PCI_VDEVICE(MELLANOX, 0x1015) }, /* ConnectX-4LX */ |
| 1461 | 1475 | { PCI_VDEVICE(MELLANOX, 0x1016), MLX5_PCI_DEV_IS_VF}, /* ConnectX-4LX VF */ |
| 1476 | + { PCI_VDEVICE(MELLANOX, 0x1017) }, /* ConnectX-5 */ | |
| 1477 | + { PCI_VDEVICE(MELLANOX, 0x1018), MLX5_PCI_DEV_IS_VF}, /* ConnectX-5 VF */ | |
| 1462 | 1478 | { 0, } |
| 1463 | 1479 | }; |
| 1464 | 1480 | |
| @@ -1469,6 +1485,7 @@ static struct pci_driver mlx5_core_driver = { · 4 unmodified lines | ||
| 1469 | 1485 | .id_table = mlx5_core_pci_table, |
| 1470 | 1486 | .probe = init_one, |
| 1471 | 1487 | .remove = remove_one, |
| 1488 | + .shutdown = shutdown, | |
| 1472 | 1489 | .err_handler = &mlx5_err_handler, |
| 1473 | 1490 | .sriov_configure = mlx5_core_sriov_configure, |
| 1474 | 1491 | }; |
| @@ -247,8 +247,8 @@ int mlx5_query_port_admin_status(struct mlx5_core_dev *dev, · 246 unmodified lines | ||
| 247 | 247 | } |
| 248 | 248 | EXPORT_SYMBOL_GPL(mlx5_query_port_admin_status); |
| 249 | 249 | |
| 250 | −static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, int *admin_mtu, | |
| 251 | − int *max_mtu, int *oper_mtu, u8 port) | |
| 250 | +static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, u16 *admin_mtu, | |
| 251 | + u16 *max_mtu, u16 *oper_mtu, u8 port) | |
| 252 | 252 | { |
| 253 | 253 | u32 in[MLX5_ST_SZ_DW(pmtu_reg)]; |
| 254 | 254 | u32 out[MLX5_ST_SZ_DW(pmtu_reg)]; |
| @@ -268,7 +268,7 @@ static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, int *admin_mtu, · 13 unmodified lines | ||
| 268 | 268 | *admin_mtu = MLX5_GET(pmtu_reg, out, admin_mtu); |
| 269 | 269 | } |
| 270 | 270 | |
| 271 | −int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port) | |
| 271 | +int mlx5_set_port_mtu(struct mlx5_core_dev *dev, u16 mtu, u8 port) | |
| 272 | 272 | { |
| 273 | 273 | u32 in[MLX5_ST_SZ_DW(pmtu_reg)]; |
| 274 | 274 | u32 out[MLX5_ST_SZ_DW(pmtu_reg)]; |
| @@ -283,14 +283,14 @@ int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port) · 8 unmodified lines | ||
| 283 | 283 | } |
| 284 | 284 | EXPORT_SYMBOL_GPL(mlx5_set_port_mtu); |
| 285 | 285 | |
| 286 | −void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu, | |
| 286 | +void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, u16 *max_mtu, | |
| 287 | 287 | u8 port) |
| 288 | 288 | { |
| 289 | 289 | mlx5_query_port_mtu(dev, NULL, max_mtu, NULL, port); |
| 290 | 290 | } |
| 291 | 291 | EXPORT_SYMBOL_GPL(mlx5_query_port_max_mtu); |
| 292 | 292 | |
| 293 | −void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu, | |
| 293 | +void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, u16 *oper_mtu, | |
| 294 | 294 | u8 port) |
| 295 | 295 | { |
| 296 | 296 | mlx5_query_port_mtu(dev, NULL, NULL, oper_mtu, port); |
| @@ -269,8 +269,10 @@ EXPORT_SYMBOL(mlx5_alloc_map_uar); · 268 unmodified lines | ||
| 269 | 269 | |
| 270 | 270 | void mlx5_unmap_free_uar(struct mlx5_core_dev *mdev, struct mlx5_uar *uar) |
| 271 | 271 | { |
| 272 | − iounmap(uar->map); | |
| 273 | − iounmap(uar->bf_map); | |
| 272 | + if (uar->map) | |
| 273 | + iounmap(uar->map); | |
| 274 | + else | |
| 275 | + iounmap(uar->bf_map); | |
| 274 | 276 | mlx5_cmd_free_uar(mdev, uar->index); |
| 275 | 277 | } |
| 276 | 278 | EXPORT_SYMBOL(mlx5_unmap_free_uar); |
| @@ -196,6 +196,46 @@ int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *mdev, · 195 unmodified lines | ||
| 196 | 196 | } |
| 197 | 197 | EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mac_address); |
| 198 | 198 | |
| 199 | +int mlx5_query_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 *mtu) | |
| 200 | +{ | |
| 201 | + int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out); | |
| 202 | + u32 *out; | |
| 203 | + int err; | |
| 204 | + | |
| 205 | + out = mlx5_vzalloc(outlen); | |
| 206 | + if (!out) | |
| 207 | + return -ENOMEM; | |
| 208 | + | |
| 209 | + err = mlx5_query_nic_vport_context(mdev, 0, out, outlen); | |
| 210 | + if (!err) | |
| 211 | + *mtu = MLX5_GET(query_nic_vport_context_out, out, | |
| 212 | + nic_vport_context.mtu); | |
| 213 | + | |
| 214 | + kvfree(out); | |
| 215 | + return err; | |
| 216 | +} | |
| 217 | +EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_mtu); | |
| 218 | + | |
| 219 | +int mlx5_modify_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 mtu) | |
| 220 | +{ | |
| 221 | + int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in); | |
| 222 | + void *in; | |
| 223 | + int err; | |
| 224 | + | |
| 225 | + in = mlx5_vzalloc(inlen); | |
| 226 | + if (!in) | |
| 227 | + return -ENOMEM; | |
| 228 | + | |
| 229 | + MLX5_SET(modify_nic_vport_context_in, in, field_select.mtu, 1); | |
| 230 | + MLX5_SET(modify_nic_vport_context_in, in, nic_vport_context.mtu, mtu); | |
| 231 | + | |
| 232 | + err = mlx5_modify_nic_vport_context(mdev, in, inlen); | |
| 233 | + | |
| 234 | + kvfree(in); | |
| 235 | + return err; | |
| 236 | +} | |
| 237 | +EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mtu); | |
| 238 | + | |
| 199 | 239 | int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev, |
| 200 | 240 | u32 vport, |
| 201 | 241 | enum mlx5_list_type list_type, |
| @@ -95,21 +95,22 @@ struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port) · 94 unmodified lines | ||
| 95 | 95 | return vxlan; |
| 96 | 96 | } |
| 97 | 97 | |
| 98 | −int mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port) | |
| 98 | +static void mlx5e_vxlan_add_port(struct work_struct *work) | |
| 99 | 99 | { |
| 100 | + struct mlx5e_vxlan_work *vxlan_work = | |
| 101 | + container_of(work, struct mlx5e_vxlan_work, work); | |
| 102 | + struct mlx5e_priv *priv = vxlan_work->priv; | |
| 100 | 103 | struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; |
| 104 | + u16 port = vxlan_work->port; | |
| 101 | 105 | struct mlx5e_vxlan *vxlan; |
| 102 | 106 | int err; |
| 103 | 107 | |
| 104 | − err = mlx5e_vxlan_core_add_port_cmd(priv->mdev, port); | |
| 105 | − if (err) | |
| 106 | − return err; | |
| 108 | + if (mlx5e_vxlan_core_add_port_cmd(priv->mdev, port)) | |
| 109 | + goto free_work; | |
| 107 | 110 | |
| 108 | 111 | vxlan = kzalloc(sizeof(*vxlan), GFP_KERNEL); |
| 109 | − if (!vxlan) { | |
| 110 | − err = -ENOMEM; | |
| 112 | + if (!vxlan) | |
| 111 | 113 | goto err_delete_port; |
| 112 | − } | |
| 113 | 114 | |
| 114 | 115 | vxlan->udp_port = port; |
| 115 | 116 | |
| @@ -119,13 +120,14 @@ int mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port) · 3 unmodified lines | ||
| 119 | 120 | if (err) |
| 120 | 121 | goto err_free; |
| 121 | 122 | |
| 122 | − return 0; | |
| 123 | + goto free_work; | |
| 123 | 124 | |
| 124 | 125 | err_free: |
| 125 | 126 | kfree(vxlan); |
| 126 | 127 | err_delete_port: |
| 127 | 128 | mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); |
| 128 | − return err; | |
| 129 | +free_work: | |
| 130 | + kfree(vxlan_work); | |
| 129 | 131 | } |
| 130 | 132 | |
| 131 | 133 | static void __mlx5e_vxlan_core_del_port(struct mlx5e_priv *priv, u16 port) |
| @@ -145,12 +147,36 @@ static void __mlx5e_vxlan_core_del_port(struct mlx5e_priv *priv, u16 port) · 13 unmodified lines | ||
| 145 | 147 | kfree(vxlan); |
| 146 | 148 | } |
| 147 | 149 | |
| 148 | −void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port) | |
| 150 | +static void mlx5e_vxlan_del_port(struct work_struct *work) | |
| 149 | 151 | { |
| 150 | − if (!mlx5e_vxlan_lookup_port(priv, port)) | |
| 151 | − return; | |
| 152 | + struct mlx5e_vxlan_work *vxlan_work = | |
| 153 | + container_of(work, struct mlx5e_vxlan_work, work); | |
| 154 | + struct mlx5e_priv *priv = vxlan_work->priv; | |
| 155 | + u16 port = vxlan_work->port; | |
| 152 | 156 | |
| 153 | 157 | __mlx5e_vxlan_core_del_port(priv, port); |
| 158 | + | |
| 159 | + kfree(vxlan_work); | |
| 160 | +} | |
| 161 | + | |
| 162 | +void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, sa_family_t sa_family, | |
| 163 | + u16 port, int add) | |
| 164 | +{ | |
| 165 | + struct mlx5e_vxlan_work *vxlan_work; | |
| 166 | + | |
| 167 | + vxlan_work = kmalloc(sizeof(*vxlan_work), GFP_ATOMIC); | |
| 168 | + if (!vxlan_work) | |
| 169 | + return; | |
| 170 | + | |
| 171 | + if (add) | |
| 172 | + INIT_WORK(&vxlan_work->work, mlx5e_vxlan_add_port); | |
| 173 | + else | |
| 174 | + INIT_WORK(&vxlan_work->work, mlx5e_vxlan_del_port); | |
| 175 | + | |
| 176 | + vxlan_work->priv = priv; | |
| 177 | + vxlan_work->port = port; | |
| 178 | + vxlan_work->sa_family = sa_family; | |
| 179 | + queue_work(priv->wq, &vxlan_work->work); | |
| 154 | 180 | } |
| 155 | 181 | |
| 156 | 182 | void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv) |
| @@ -39,6 +39,13 @@ struct mlx5e_vxlan { · 38 unmodified lines | ||
| 39 | 39 | u16 udp_port; |
| 40 | 40 | }; |
| 41 | 41 | |
| 42 | +struct mlx5e_vxlan_work { | |
| 43 | + struct work_struct work; | |
| 44 | + struct mlx5e_priv *priv; | |
| 45 | + sa_family_t sa_family; | |
| 46 | + u16 port; | |
| 47 | +}; | |
| 48 | + | |
| 42 | 49 | static inline bool mlx5e_vxlan_allowed(struct mlx5_core_dev *mdev) |
| 43 | 50 | { |
| 44 | 51 | return (MLX5_CAP_ETH(mdev, tunnel_stateless_vxlan) && |
| @@ -46,8 +53,8 @@ static inline bool mlx5e_vxlan_allowed(struct mlx5_core_dev *mdev) · 1 unmodified line | ||
| 46 | 53 | } |
| 47 | 54 | |
| 48 | 55 | void mlx5e_vxlan_init(struct mlx5e_priv *priv); |
| 49 | −int mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port); | |
| 50 | −void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port); | |
| 56 | +void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, sa_family_t sa_family, | |
| 57 | + u16 port, int add); | |
| 51 | 58 | struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port); |
| 52 | 59 | void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv); |
| 53 | 60 | |
| @@ -2668,9 +2668,9 @@ static int myri10ge_close(struct net_device *dev) · 2667 unmodified lines | ||
| 2668 | 2668 | |
| 2669 | 2669 | del_timer_sync(&mgp->watchdog_timer); |
| 2670 | 2670 | mgp->running = MYRI10GE_ETH_STOPPING; |
| 2671 | − local_bh_disable(); /* myri10ge_ss_lock_napi needs bh disabled */ | |
| 2672 | 2671 | for (i = 0; i < mgp->num_slices; i++) { |
| 2673 | 2672 | napi_disable(&mgp->ss[i].napi); |
| 2673 | + local_bh_disable(); /* myri10ge_ss_lock_napi needs this */ | |
| 2674 | 2674 | /* Lock the slice to prevent the busy_poll handler from |
| 2675 | 2675 | * accessing it. Later when we bring the NIC up, myri10ge_open |
| 2676 | 2676 | * resets the slice including this lock. |
| @@ -2679,8 +2679,8 @@ static int myri10ge_close(struct net_device *dev) · 2 unmodified lines | ||
| 2679 | 2679 | pr_info("Slice %d locked\n", i); |
| 2680 | 2680 | mdelay(1); |
| 2681 | 2681 | } |
| 2682 | + local_bh_enable(); | |
| 2682 | 2683 | } |
| 2683 | − local_bh_enable(); | |
| 2684 | 2684 | netif_carrier_off(dev); |
| 2685 | 2685 | |
| 2686 | 2686 | netif_tx_stop_all_queues(dev); |
| @@ -37,8 +37,8 @@ · 36 unmodified lines | ||
| 37 | 37 | |
| 38 | 38 | #define _QLCNIC_LINUX_MAJOR 5 |
| 39 | 39 | #define _QLCNIC_LINUX_MINOR 3 |
| 40 | −#define _QLCNIC_LINUX_SUBVERSION 63 | |
| 41 | −#define QLCNIC_LINUX_VERSIONID "5.3.63" | |
| 40 | +#define _QLCNIC_LINUX_SUBVERSION 64 | |
| 41 | +#define QLCNIC_LINUX_VERSIONID "5.3.64" | |
| 42 | 42 | #define QLCNIC_DRV_IDC_VER 0x01 |
| 43 | 43 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ |
| 44 | 44 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) |
| @@ -1920,6 +1920,10 @@ static int efx_ef10_alloc_rss_context(struct efx_nic *efx, u32 *context, · 1919 unmodified lines | ||
| 1920 | 1920 | return 0; |
| 1921 | 1921 | } |
| 1922 | 1922 | |
| 1923 | + if (nic_data->datapath_caps & | |
| 1924 | + 1 << MC_CMD_GET_CAPABILITIES_OUT_RX_RSS_LIMITED_LBN) | |
| 1925 | + return -EOPNOTSUPP; | |
| 1926 | + | |
| 1923 | 1927 | MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID, |
| 1924 | 1928 | nic_data->vport_id); |
| 1925 | 1929 | MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_TYPE, alloc_type); |
| @@ -2923,9 +2927,16 @@ static void efx_ef10_filter_push_prep(struct efx_nic *efx, · 997 unmodified lines | ||
| 2923 | 2927 | bool replacing) |
| 2924 | 2928 | { |
| 2925 | 2929 | struct efx_ef10_nic_data *nic_data = efx->nic_data; |
| 2930 | + u32 flags = spec->flags; | |
| 2926 | 2931 | |
| 2927 | 2932 | memset(inbuf, 0, MC_CMD_FILTER_OP_IN_LEN); |
| 2928 | 2933 | |
| 2934 | + /* Remove RSS flag if we don't have an RSS context. */ | |
| 2935 | + if (flags & EFX_FILTER_FLAG_RX_RSS && | |
| 2936 | + spec->rss_context == EFX_FILTER_RSS_CONTEXT_DEFAULT && | |
| 2937 | + nic_data->rx_rss_context == EFX_EF10_RSS_CONTEXT_INVALID) | |
| 2938 | + flags &= ~EFX_FILTER_FLAG_RX_RSS; | |
| 2939 | + | |
| 2929 | 2940 | if (replacing) { |
| 2930 | 2941 | MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP, |
| 2931 | 2942 | MC_CMD_FILTER_OP_IN_OP_REPLACE); |
| @@ -2985,10 +2996,10 @@ static void efx_ef10_filter_push_prep(struct efx_nic *efx, · 53 unmodified lines | ||
| 2985 | 2996 | spec->dmaq_id == EFX_FILTER_RX_DMAQ_ID_DROP ? |
| 2986 | 2997 | 0 : spec->dmaq_id); |
| 2987 | 2998 | MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_MODE, |
| 2988 | − (spec->flags & EFX_FILTER_FLAG_RX_RSS) ? | |
| 2999 | + (flags & EFX_FILTER_FLAG_RX_RSS) ? | |
| 2989 | 3000 | MC_CMD_FILTER_OP_IN_RX_MODE_RSS : |
| 2990 | 3001 | MC_CMD_FILTER_OP_IN_RX_MODE_SIMPLE); |
| 2991 | − if (spec->flags & EFX_FILTER_FLAG_RX_RSS) | |
| 3002 | + if (flags & EFX_FILTER_FLAG_RX_RSS) | |
| 2992 | 3003 | MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_CONTEXT, |
| 2993 | 3004 | spec->rss_context != |
| 2994 | 3005 | EFX_FILTER_RSS_CONTEXT_DEFAULT ? |
| @@ -49,7 +49,6 @@ struct socfpga_dwmac { · 48 unmodified lines | ||
| 49 | 49 | u32 reg_shift; |
| 50 | 50 | struct device *dev; |
| 51 | 51 | struct regmap *sys_mgr_base_addr; |
| 52 | − struct reset_control *stmmac_rst; | |
| 53 | 52 | void __iomem *splitter_base; |
| 54 | 53 | bool f2h_ptp_ref_clk; |
| 55 | 54 | }; |
| @@ -92,15 +91,6 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device * · 36 unmodified lines | ||
| 92 | 91 | struct device_node *np_splitter; |
| 93 | 92 | struct resource res_splitter; |
| 94 | 93 | |
| 95 | − dwmac->stmmac_rst = devm_reset_control_get(dev, | |
| 96 | − STMMAC_RESOURCE_NAME); | |
| 97 | − if (IS_ERR(dwmac->stmmac_rst)) { | |
| 98 | − dev_info(dev, "Could not get reset control!\n"); | |
| 99 | − if (PTR_ERR(dwmac->stmmac_rst) == -EPROBE_DEFER) | |
| 100 | − return -EPROBE_DEFER; | |
| 101 | − dwmac->stmmac_rst = NULL; | |
| 102 | − } | |
| 103 | − | |
| 104 | 94 | dwmac->interface = of_get_phy_mode(np); |
| 105 | 95 | |
| 106 | 96 | sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon"); |
| @@ -194,30 +184,23 @@ static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac) · 87 unmodified lines | ||
| 194 | 184 | return 0; |
| 195 | 185 | } |
| 196 | 186 | |
| 197 | −static void socfpga_dwmac_exit(struct platform_device *pdev, void *priv) | |
| 198 | −{ | |
| 199 | − struct socfpga_dwmac *dwmac = priv; | |
| 200 | − | |
| 201 | − /* On socfpga platform exit, assert and hold reset to the | |
| 202 | − * enet controller - the default state after a hard reset. | |
| 203 | − */ | |
| 204 | − if (dwmac->stmmac_rst) | |
| 205 | − reset_control_assert(dwmac->stmmac_rst); | |
| 206 | −} | |
| 207 | − | |
| 208 | 187 | static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) |
| 209 | 188 | { |
| 210 | − struct socfpga_dwmac *dwmac = priv; | |
| 189 | + struct socfpga_dwmac *dwmac = priv; | |
| 211 | 190 | struct net_device *ndev = platform_get_drvdata(pdev); |
| 212 | 191 | struct stmmac_priv *stpriv = NULL; |
| 213 | 192 | int ret = 0; |
| 214 | 193 | |
| 215 | − if (ndev) | |
| 216 | − stpriv = netdev_priv(ndev); | |
| 194 | + if (!ndev) | |
| 195 | + return -EINVAL; | |
| 196 | + | |
| 197 | + stpriv = netdev_priv(ndev); | |
| 198 | + if (!stpriv) | |
| 199 | + return -EINVAL; | |
| 217 | 200 | |
| 218 | 201 | /* Assert reset to the enet controller before changing the phy mode */ |
| 219 | − if (dwmac->stmmac_rst) | |
| 220 | − reset_control_assert(dwmac->stmmac_rst); | |
| 202 | + if (stpriv->stmmac_rst) | |
| 203 | + reset_control_assert(stpriv->stmmac_rst); | |
| 221 | 204 | |
| 222 | 205 | /* Setup the phy mode in the system manager registers according to |
| 223 | 206 | * devicetree configuration |
| @@ -227,8 +210,8 @@ static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) · 3 unmodified lines | ||
| 227 | 210 | /* Deassert reset for the phy configuration to be sampled by |
| 228 | 211 | * the enet controller, and operation to start in requested mode |
| 229 | 212 | */ |
| 230 | − if (dwmac->stmmac_rst) | |
| 231 | − reset_control_deassert(dwmac->stmmac_rst); | |
| 213 | + if (stpriv->stmmac_rst) | |
| 214 | + reset_control_deassert(stpriv->stmmac_rst); | |
| 232 | 215 | |
| 233 | 216 | /* Before the enet controller is suspended, the phy is suspended. |
| 234 | 217 | * This causes the phy clock to be gated. The enet controller is |
| @@ -245,7 +228,7 @@ static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) · 10 unmodified lines | ||
| 245 | 228 | * control register 0, and can be modified by the phy driver |
| 246 | 229 | * framework. |
| 247 | 230 | */ |
| 248 | − if (stpriv && stpriv->phydev) | |
| 231 | + if (stpriv->phydev) | |
| 249 | 232 | phy_resume(stpriv->phydev); |
| 250 | 233 | |
| 251 | 234 | return ret; |
| @@ -285,14 +268,13 @@ static int socfpga_dwmac_probe(struct platform_device *pdev) · 33 unmodified lines | ||
| 285 | 268 | |
| 286 | 269 | plat_dat->bsp_priv = dwmac; |
| 287 | 270 | plat_dat->init = socfpga_dwmac_init; |
| 288 | − plat_dat->exit = socfpga_dwmac_exit; | |
| 289 | 271 | plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed; |
| 290 | 272 | |
| 291 | − ret = socfpga_dwmac_init(pdev, plat_dat->bsp_priv); | |
| 292 | − if (ret) | |
| 293 | − return ret; | |
| 273 | + ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); | |
| 274 | + if (!ret) | |
| 275 | + ret = socfpga_dwmac_init(pdev, dwmac); | |
| 294 | 276 | |
| 295 | − return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); | |
| 277 | + return ret; | |
| 296 | 278 | } |
| 297 | 279 | |
| 298 | 280 | static const struct of_device_id socfpga_dwmac_match[] = { |
| @@ -367,7 +367,6 @@ struct cpsw_priv { · 366 unmodified lines | ||
| 367 | 367 | spinlock_t lock; |
| 368 | 368 | struct platform_device *pdev; |
| 369 | 369 | struct net_device *ndev; |
| 370 | − struct device_node *phy_node; | |
| 371 | 370 | struct napi_struct napi_rx; |
| 372 | 371 | struct napi_struct napi_tx; |
| 373 | 372 | struct device *dev; |
| @@ -1148,25 +1147,34 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) · 774 unmodified lines | ||
| 1148 | 1147 | cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, |
| 1149 | 1148 | 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); |
| 1150 | 1149 | |
| 1151 | − if (priv->phy_node) | |
| 1152 | − slave->phy = of_phy_connect(priv->ndev, priv->phy_node, | |
| 1150 | + if (slave->data->phy_node) { | |
| 1151 | + slave->phy = of_phy_connect(priv->ndev, slave->data->phy_node, | |
| 1153 | 1152 | &cpsw_adjust_link, 0, slave->data->phy_if); |
| 1154 | − else | |
| 1153 | + if (!slave->phy) { | |
| 1154 | + dev_err(priv->dev, "phy \"%s\" not found on slave %d\n", | |
| 1155 | + slave->data->phy_node->full_name, | |
| 1156 | + slave->slave_num); | |
| 1157 | + return; | |
| 1158 | + } | |
| 1159 | + } else { | |
| 1155 | 1160 | slave->phy = phy_connect(priv->ndev, slave->data->phy_id, |
| 1156 | 1161 | &cpsw_adjust_link, slave->data->phy_if); |
| 1157 | − if (IS_ERR(slave->phy)) { | |
| 1158 | − dev_err(priv->dev, "phy %s not found on slave %d\n", | |
| 1159 | − slave->data->phy_id, slave->slave_num); | |
| 1160 | − slave->phy = NULL; | |
| 1161 | − } else { | |
| 1162 | − phy_attached_info(slave->phy); | |
| 1162 | + if (IS_ERR(slave->phy)) { | |
| 1163 | + dev_err(priv->dev, | |
| 1164 | + "phy \"%s\" not found on slave %d, err %ld\n", | |
| 1165 | + slave->data->phy_id, slave->slave_num, | |
| 1166 | + PTR_ERR(slave->phy)); | |
| 1167 | + slave->phy = NULL; | |
| 1168 | + return; | |
| 1169 | + } | |
| 1170 | + } | |
| 1163 | 1171 | |
| 1164 | − phy_start(slave->phy); | |
| 1172 | + phy_attached_info(slave->phy); | |
| 1165 | 1173 | |
| 1166 | − /* Configure GMII_SEL register */ | |
| 1167 | − cpsw_phy_sel(&priv->pdev->dev, slave->phy->interface, | |
| 1168 | − slave->slave_num); | |
| 1169 | − } | |
| 1174 | + phy_start(slave->phy); | |
| 1175 | + | |
| 1176 | + /* Configure GMII_SEL register */ | |
| 1177 | + cpsw_phy_sel(&priv->pdev->dev, slave->phy->interface, slave->slave_num); | |
| 1170 | 1178 | } |
| 1171 | 1179 | |
| 1172 | 1180 | static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) |
| @@ -1940,12 +1948,11 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv, · 767 unmodified lines | ||
| 1940 | 1948 | slave->port_vlan = data->dual_emac_res_vlan; |
| 1941 | 1949 | } |
| 1942 | 1950 | |
| 1943 | −static int cpsw_probe_dt(struct cpsw_priv *priv, | |
| 1951 | +static int cpsw_probe_dt(struct cpsw_platform_data *data, | |
| 1944 | 1952 | struct platform_device *pdev) |
| 1945 | 1953 | { |
| 1946 | 1954 | struct device_node *node = pdev->dev.of_node; |
| 1947 | 1955 | struct device_node *slave_node; |
| 1948 | − struct cpsw_platform_data *data = &priv->data; | |
| 1949 | 1956 | int i = 0, ret; |
| 1950 | 1957 | u32 prop; |
| 1951 | 1958 | |
| @@ -2033,25 +2040,21 @@ static int cpsw_probe_dt(struct cpsw_priv *priv, · 81 unmodified lines | ||
| 2033 | 2040 | if (strcmp(slave_node->name, "slave")) |
| 2034 | 2041 | continue; |
| 2035 | 2042 | |
| 2036 | − priv->phy_node = of_parse_phandle(slave_node, "phy-handle", 0); | |
| 2043 | + slave_data->phy_node = of_parse_phandle(slave_node, | |
| 2044 | + "phy-handle", 0); | |
| 2037 | 2045 | parp = of_get_property(slave_node, "phy_id", &lenp); |
| 2038 | − if (of_phy_is_fixed_link(slave_node)) { | |
| 2039 | − struct device_node *phy_node; | |
| 2040 | − struct phy_device *phy_dev; | |
| 2041 | − | |
| 2046 | + if (slave_data->phy_node) { | |
| 2047 | + dev_dbg(&pdev->dev, | |
| 2048 | + "slave[%d] using phy-handle=\"%s\"\n", | |
| 2049 | + i, slave_data->phy_node->full_name); | |
| 2050 | + } else if (of_phy_is_fixed_link(slave_node)) { | |
| 2042 | 2051 | /* In the case of a fixed PHY, the DT node associated |
| 2043 | 2052 | * to the PHY is the Ethernet MAC DT node. |
| 2044 | 2053 | */ |
| 2045 | 2054 | ret = of_phy_register_fixed_link(slave_node); |
| 2046 | 2055 | if (ret) |
| 2047 | 2056 | return ret; |
| 2048 | − phy_node = of_node_get(slave_node); | |
| 2049 | − phy_dev = of_phy_find_device(phy_node); | |
| 2050 | − if (!phy_dev) | |
| 2051 | − return -ENODEV; | |
| 2052 | − snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), | |
| 2053 | − PHY_ID_FMT, phy_dev->mdio.bus->id, | |
| 2054 | − phy_dev->mdio.addr); | |
| 2057 | + slave_data->phy_node = of_node_get(slave_node); | |
| 2055 | 2058 | } else if (parp) { |
| 2056 | 2059 | u32 phyid; |
| 2057 | 2060 | struct device_node *mdio_node; |
| @@ -2072,7 +2075,9 @@ static int cpsw_probe_dt(struct cpsw_priv *priv, · 14 unmodified lines | ||
| 2072 | 2075 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), |
| 2073 | 2076 | PHY_ID_FMT, mdio->name, phyid); |
| 2074 | 2077 | } else { |
| 2075 | − dev_err(&pdev->dev, "No slave[%d] phy_id or fixed-link property\n", i); | |
| 2078 | + dev_err(&pdev->dev, | |
| 2079 | + "No slave[%d] phy_id, phy-handle, or fixed-link property\n", | |
| 2080 | + i); | |
| 2076 | 2081 | goto no_phy_slave; |
| 2077 | 2082 | } |
| 2078 | 2083 | slave_data->phy_if = of_get_phy_mode(slave_node); |
| @@ -2275,7 +2280,7 @@ static int cpsw_probe(struct platform_device *pdev) · 196 unmodified lines | ||
| 2275 | 2280 | /* Select default pin state */ |
| 2276 | 2281 | pinctrl_pm_select_default_state(&pdev->dev); |
| 2277 | 2282 | |
| 2278 | − if (cpsw_probe_dt(priv, pdev)) { | |
| 2283 | + if (cpsw_probe_dt(&priv->data, pdev)) { | |
| 2279 | 2284 | dev_err(&pdev->dev, "cpsw: platform data missing\n"); |
| 2280 | 2285 | ret = -ENODEV; |
| 2281 | 2286 | goto clean_runtime_disable_ret; |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/phy.h> |
| 19 | 19 | |
| 20 | 20 | struct cpsw_slave_data { |
| 21 | + struct device_node *phy_node; | |
| 21 | 22 | char phy_id[MII_BUS_ID_SIZE]; |
| 22 | 23 | int phy_if; |
| 23 | 24 | u8 mac_addr[ETH_ALEN]; |
| @@ -1512,7 +1512,10 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd) · 1511 unmodified lines | ||
| 1512 | 1512 | |
| 1513 | 1513 | /* TODO: Add phy read and write and private statistics get feature */ |
| 1514 | 1514 | |
| 1515 | − return phy_mii_ioctl(priv->phydev, ifrq, cmd); | |
| 1515 | + if (priv->phydev) | |
| 1516 | + return phy_mii_ioctl(priv->phydev, ifrq, cmd); | |
| 1517 | + else | |
| 1518 | + return -EOPNOTSUPP; | |
| 1516 | 1519 | } |
| 1517 | 1520 | |
| 1518 | 1521 | static int match_first_device(struct device *dev, void *data) |
| @@ -1622,7 +1622,7 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl) · 1621 unmodified lines | ||
| 1622 | 1622 | continue; |
| 1623 | 1623 | |
| 1624 | 1624 | /* copy hw scan info */ |
| 1625 | − memcpy(target->hwinfo, scan_info, scan_info->size); | |
| 1625 | + memcpy(target->hwinfo, scan_info, be16_to_cpu(scan_info->size)); | |
| 1626 | 1626 | target->essid_len = strnlen(scan_info->essid, |
| 1627 | 1627 | sizeof(scan_info->essid)); |
| 1628 | 1628 | target->rate_len = 0; |
| @@ -880,12 +880,12 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, · 879 unmodified lines | ||
| 880 | 880 | macsec_skb_cb(skb)->valid = false; |
| 881 | 881 | skb = skb_share_check(skb, GFP_ATOMIC); |
| 882 | 882 | if (!skb) |
| 883 | − return NULL; | |
| 883 | + return ERR_PTR(-ENOMEM); | |
| 884 | 884 | |
| 885 | 885 | req = aead_request_alloc(rx_sa->key.tfm, GFP_ATOMIC); |
| 886 | 886 | if (!req) { |
| 887 | 887 | kfree_skb(skb); |
| 888 | − return NULL; | |
| 888 | + return ERR_PTR(-ENOMEM); | |
| 889 | 889 | } |
| 890 | 890 | |
| 891 | 891 | hdr = (struct macsec_eth_header *)skb->data; |
| @@ -905,7 +905,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, · 13 unmodified lines | ||
| 905 | 905 | skb = skb_unshare(skb, GFP_ATOMIC); |
| 906 | 906 | if (!skb) { |
| 907 | 907 | aead_request_free(req); |
| 908 | − return NULL; | |
| 908 | + return ERR_PTR(-ENOMEM); | |
| 909 | 909 | } |
| 910 | 910 | } else { |
| 911 | 911 | /* integrity only: all headers + data authenticated */ |
| @@ -921,14 +921,14 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, · 9 unmodified lines | ||
| 921 | 921 | dev_hold(dev); |
| 922 | 922 | ret = crypto_aead_decrypt(req); |
| 923 | 923 | if (ret == -EINPROGRESS) { |
| 924 | − return NULL; | |
| 924 | + return ERR_PTR(ret); | |
| 925 | 925 | } else if (ret != 0) { |
| 926 | 926 | /* decryption/authentication failed |
| 927 | 927 | * 10.6 if validateFrames is disabled, deliver anyway |
| 928 | 928 | */ |
| 929 | 929 | if (ret != -EBADMSG) { |
| 930 | 930 | kfree_skb(skb); |
| 931 | − skb = NULL; | |
| 931 | + skb = ERR_PTR(ret); | |
| 932 | 932 | } |
| 933 | 933 | } else { |
| 934 | 934 | macsec_skb_cb(skb)->valid = true; |
| @@ -1146,8 +1146,10 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) · 211 unmodified lines | ||
| 1146 | 1146 | secy->validate_frames != MACSEC_VALIDATE_DISABLED) |
| 1147 | 1147 | skb = macsec_decrypt(skb, dev, rx_sa, sci, secy); |
| 1148 | 1148 | |
| 1149 | − if (!skb) { | |
| 1150 | − macsec_rxsa_put(rx_sa); | |
| 1149 | + if (IS_ERR(skb)) { | |
| 1150 | + /* the decrypt callback needs the reference */ | |
| 1151 | + if (PTR_ERR(skb) != -EINPROGRESS) | |
| 1152 | + macsec_rxsa_put(rx_sa); | |
| 1151 | 1153 | rcu_read_unlock(); |
| 1152 | 1154 | *pskb = NULL; |
| 1153 | 1155 | return RX_HANDLER_CONSUMED; |
| @@ -1161,7 +1163,8 @@ deliver: · 7 unmodified lines | ||
| 1161 | 1163 | macsec_extra_len(macsec_skb_cb(skb)->has_sci)); |
| 1162 | 1164 | macsec_reset_skb(skb, secy->netdev); |
| 1163 | 1165 | |
| 1164 | − macsec_rxsa_put(rx_sa); | |
| 1166 | + if (rx_sa) | |
| 1167 | + macsec_rxsa_put(rx_sa); | |
| 1165 | 1168 | count_rx(dev, skb->len); |
| 1166 | 1169 | |
| 1167 | 1170 | rcu_read_unlock(); |
| @@ -1622,8 +1625,9 @@ static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info) · 454 unmodified lines | ||
| 1622 | 1625 | } |
| 1623 | 1626 | |
| 1624 | 1627 | rx_sa = kmalloc(sizeof(*rx_sa), GFP_KERNEL); |
| 1625 | − if (init_rx_sa(rx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), secy->key_len, | |
| 1626 | − secy->icv_len)) { | |
| 1628 | + if (!rx_sa || init_rx_sa(rx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), | |
| 1629 | + secy->key_len, secy->icv_len)) { | |
| 1630 | + kfree(rx_sa); | |
| 1627 | 1631 | rtnl_unlock(); |
| 1628 | 1632 | return -ENOMEM; |
| 1629 | 1633 | } |
| @@ -1768,6 +1772,7 @@ static int macsec_add_txsa(struct sk_buff *skb, struct genl_info *info) · 138 unmodified lines | ||
| 1768 | 1772 | tx_sa = kmalloc(sizeof(*tx_sa), GFP_KERNEL); |
| 1769 | 1773 | if (!tx_sa || init_tx_sa(tx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), |
| 1770 | 1774 | secy->key_len, secy->icv_len)) { |
| 1775 | + kfree(tx_sa); | |
| 1771 | 1776 | rtnl_unlock(); |
| 1772 | 1777 | return -ENOMEM; |
| 1773 | 1778 | } |
| @@ -2227,7 +2232,8 @@ static int nla_put_secy(struct macsec_secy *secy, struct sk_buff *skb) · 453 unmodified lines | ||
| 2227 | 2232 | return 1; |
| 2228 | 2233 | |
| 2229 | 2234 | if (nla_put_sci(skb, MACSEC_SECY_ATTR_SCI, secy->sci) || |
| 2230 | − nla_put_u64(skb, MACSEC_SECY_ATTR_CIPHER_SUITE, DEFAULT_CIPHER_ID) || | |
| 2235 | + nla_put_u64(skb, MACSEC_SECY_ATTR_CIPHER_SUITE, | |
| 2236 | + MACSEC_DEFAULT_CIPHER_ID) || | |
| 2231 | 2237 | nla_put_u8(skb, MACSEC_SECY_ATTR_ICV_LEN, secy->icv_len) || |
| 2232 | 2238 | nla_put_u8(skb, MACSEC_SECY_ATTR_OPER, secy->operational) || |
| 2233 | 2239 | nla_put_u8(skb, MACSEC_SECY_ATTR_PROTECT, secy->protect_frames) || |
| @@ -2268,7 +2274,7 @@ static int dump_secy(struct macsec_secy *secy, struct net_device *dev, · 34 unmodified lines | ||
| 2268 | 2274 | if (!hdr) |
| 2269 | 2275 | return -EMSGSIZE; |
| 2270 | 2276 | |
| 2271 | − rtnl_lock(); | |
| 2277 | + genl_dump_check_consistent(cb, hdr, &macsec_fam); | |
| 2272 | 2278 | |
| 2273 | 2279 | if (nla_put_u32(skb, MACSEC_ATTR_IFINDEX, dev->ifindex)) |
| 2274 | 2280 | goto nla_put_failure; |
| @@ -2429,18 +2435,17 @@ static int dump_secy(struct macsec_secy *secy, struct net_device *dev, · 154 unmodified lines | ||
| 2429 | 2435 | |
| 2430 | 2436 | nla_nest_end(skb, rxsc_list); |
| 2431 | 2437 | |
| 2432 | − rtnl_unlock(); | |
| 2433 | − | |
| 2434 | 2438 | genlmsg_end(skb, hdr); |
| 2435 | 2439 | |
| 2436 | 2440 | return 0; |
| 2437 | 2441 | |
| 2438 | 2442 | nla_put_failure: |
| 2439 | − rtnl_unlock(); | |
| 2440 | 2443 | genlmsg_cancel(skb, hdr); |
| 2441 | 2444 | return -EMSGSIZE; |
| 2442 | 2445 | } |
| 2443 | 2446 | |
| 2447 | +static int macsec_generation = 1; /* protected by RTNL */ | |
| 2448 | + | |
| 2444 | 2449 | static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb) |
| 2445 | 2450 | { |
| 2446 | 2451 | struct net *net = sock_net(skb->sk); |
| @@ -2450,6 +2455,10 @@ static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb) · 3 unmodified lines | ||
| 2450 | 2455 | dev_idx = cb->args[0]; |
| 2451 | 2456 | |
| 2452 | 2457 | d = 0; |
| 2458 | + rtnl_lock(); | |
| 2459 | + | |
| 2460 | + cb->seq = macsec_generation; | |
| 2461 | + | |
| 2453 | 2462 | for_each_netdev(net, dev) { |
| 2454 | 2463 | struct macsec_secy *secy; |
| 2455 | 2464 | |
| @@ -2467,6 +2476,7 @@ next: · 11 unmodified lines | ||
| 2467 | 2476 | } |
| 2468 | 2477 | |
| 2469 | 2478 | done: |
| 2479 | + rtnl_unlock(); | |
| 2470 | 2480 | cb->args[0] = d; |
| 2471 | 2481 | return skb->len; |
| 2472 | 2482 | } |
| @@ -2920,10 +2930,14 @@ static void macsec_dellink(struct net_device *dev, struct list_head *head) · 447 unmodified lines | ||
| 2920 | 2930 | struct net_device *real_dev = macsec->real_dev; |
| 2921 | 2931 | struct macsec_rxh_data *rxd = macsec_data_rtnl(real_dev); |
| 2922 | 2932 | |
| 2933 | + macsec_generation++; | |
| 2934 | + | |
| 2923 | 2935 | unregister_netdevice_queue(dev, head); |
| 2924 | 2936 | list_del_rcu(&macsec->secys); |
| 2925 | − if (list_empty(&rxd->secys)) | |
| 2937 | + if (list_empty(&rxd->secys)) { | |
| 2926 | 2938 | netdev_rx_handler_unregister(real_dev); |
| 2939 | + kfree(rxd); | |
| 2940 | + } | |
| 2927 | 2941 | |
| 2928 | 2942 | macsec_del_dev(macsec); |
| 2929 | 2943 | } |
| @@ -2945,8 +2959,10 @@ static int register_macsec_dev(struct net_device *real_dev, · 15 unmodified lines | ||
| 2945 | 2959 | |
| 2946 | 2960 | err = netdev_rx_handler_register(real_dev, macsec_handle_frame, |
| 2947 | 2961 | rxd); |
| 2948 | − if (err < 0) | |
| 2962 | + if (err < 0) { | |
| 2963 | + kfree(rxd); | |
| 2949 | 2964 | return err; |
| 2965 | + } | |
| 2950 | 2966 | } |
| 2951 | 2967 | |
| 2952 | 2968 | list_add_tail_rcu(&macsec->secys, &rxd->secys); |
| @@ -3066,6 +3082,8 @@ static int macsec_newlink(struct net *net, struct net_device *dev, · 113 unmodified lines | ||
| 3066 | 3082 | if (err < 0) |
| 3067 | 3083 | goto del_dev; |
| 3068 | 3084 | |
| 3085 | + macsec_generation++; | |
| 3086 | + | |
| 3069 | 3087 | dev_hold(real_dev); |
| 3070 | 3088 | |
| 3071 | 3089 | return 0; |
| @@ -3079,7 +3097,7 @@ unregister: · 7 unmodified lines | ||
| 3079 | 3097 | |
| 3080 | 3098 | static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) |
| 3081 | 3099 | { |
| 3082 | − u64 csid = DEFAULT_CIPHER_ID; | |
| 3100 | + u64 csid = MACSEC_DEFAULT_CIPHER_ID; | |
| 3083 | 3101 | u8 icv_len = DEFAULT_ICV_LEN; |
| 3084 | 3102 | int flag; |
| 3085 | 3103 | bool es, scb, sci; |
| @@ -3094,8 +3112,8 @@ static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) · 8 unmodified lines | ||
| 3094 | 3112 | icv_len = nla_get_u8(data[IFLA_MACSEC_ICV_LEN]); |
| 3095 | 3113 | |
| 3096 | 3114 | switch (csid) { |
| 3097 | − case DEFAULT_CIPHER_ID: | |
| 3098 | − case DEFAULT_CIPHER_ALT: | |
| 3115 | + case MACSEC_DEFAULT_CIPHER_ID: | |
| 3116 | + case MACSEC_DEFAULT_CIPHER_ALT: | |
| 3099 | 3117 | if (icv_len < MACSEC_MIN_ICV_LEN || |
| 3100 | 3118 | icv_len > MACSEC_MAX_ICV_LEN) |
| 3101 | 3119 | return -EINVAL; |
| @@ -3129,8 +3147,8 @@ static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) · 27 unmodified lines | ||
| 3129 | 3147 | nla_get_u8(data[IFLA_MACSEC_VALIDATION]) > MACSEC_VALIDATE_MAX) |
| 3130 | 3148 | return -EINVAL; |
| 3131 | 3149 | |
| 3132 | − if ((data[IFLA_MACSEC_PROTECT] && | |
| 3133 | − nla_get_u8(data[IFLA_MACSEC_PROTECT])) && | |
| 3150 | + if ((data[IFLA_MACSEC_REPLAY_PROTECT] && | |
| 3151 | + nla_get_u8(data[IFLA_MACSEC_REPLAY_PROTECT])) && | |
| 3134 | 3152 | !data[IFLA_MACSEC_WINDOW]) |
| 3135 | 3153 | return -EINVAL; |
| 3136 | 3154 | |
| @@ -3168,7 +3186,8 @@ static int macsec_fill_info(struct sk_buff *skb, · 31 unmodified lines | ||
| 3168 | 3186 | |
| 3169 | 3187 | if (nla_put_sci(skb, IFLA_MACSEC_SCI, secy->sci) || |
| 3170 | 3188 | nla_put_u8(skb, IFLA_MACSEC_ICV_LEN, secy->icv_len) || |
| 3171 | − nla_put_u64(skb, IFLA_MACSEC_CIPHER_SUITE, DEFAULT_CIPHER_ID) || | |
| 3189 | + nla_put_u64(skb, IFLA_MACSEC_CIPHER_SUITE, | |
| 3190 | + MACSEC_DEFAULT_CIPHER_ID) || | |
| 3172 | 3191 | nla_put_u8(skb, IFLA_MACSEC_ENCODING_SA, tx_sc->encoding_sa) || |
| 3173 | 3192 | nla_put_u8(skb, IFLA_MACSEC_ENCRYPT, tx_sc->encrypt) || |
| 3174 | 3193 | nla_put_u8(skb, IFLA_MACSEC_PROTECT, secy->protect_frames) || |
| @@ -359,27 +359,25 @@ static void at803x_link_change_notify(struct phy_device *phydev) · 358 unmodified lines | ||
| 359 | 359 | * in the FIFO. In such cases, the FIFO enters an error mode it |
| 360 | 360 | * cannot recover from by software. |
| 361 | 361 | */ |
| 362 | − if (phydev->drv->phy_id == ATH8030_PHY_ID) { | |
| 363 | − if (phydev->state == PHY_NOLINK) { | |
| 364 | − if (priv->gpiod_reset && !priv->phy_reset) { | |
| 365 | − struct at803x_context context; | |
| 366 | − | |
| 367 | − at803x_context_save(phydev, &context); | |
| 368 | − | |
| 369 | − gpiod_set_value(priv->gpiod_reset, 1); | |
| 370 | − msleep(1); | |
| 371 | − gpiod_set_value(priv->gpiod_reset, 0); | |
| 372 | − msleep(1); | |
| 373 | − | |
| 374 | − at803x_context_restore(phydev, &context); | |
| 375 | − | |
| 376 | − phydev_dbg(phydev, "%s(): phy was reset\n", | |
| 377 | − __func__); | |
| 378 | − priv->phy_reset = true; | |
| 379 | − } | |
| 380 | − } else { | |
| 381 | − priv->phy_reset = false; | |
| 362 | + if (phydev->state == PHY_NOLINK) { | |
| 363 | + if (priv->gpiod_reset && !priv->phy_reset) { | |
| 364 | + struct at803x_context context; | |
| 365 | + | |
| 366 | + at803x_context_save(phydev, &context); | |
| 367 | + | |
| 368 | + gpiod_set_value(priv->gpiod_reset, 1); | |
| 369 | + msleep(1); | |
| 370 | + gpiod_set_value(priv->gpiod_reset, 0); | |
| 371 | + msleep(1); | |
| 372 | + | |
| 373 | + at803x_context_restore(phydev, &context); | |
| 374 | + | |
| 375 | + phydev_dbg(phydev, "%s(): phy was reset\n", | |
| 376 | + __func__); | |
| 377 | + priv->phy_reset = true; | |
| 382 | 378 | } |
| 379 | + } else { | |
| 380 | + priv->phy_reset = false; | |
| 383 | 381 | } |
| 384 | 382 | } |
| 385 | 383 | |
| @@ -391,7 +389,6 @@ static struct phy_driver at803x_driver[] = { · 5 unmodified lines | ||
| 391 | 389 | .phy_id_mask = 0xffffffef, |
| 392 | 390 | .probe = at803x_probe, |
| 393 | 391 | .config_init = at803x_config_init, |
| 394 | − .link_change_notify = at803x_link_change_notify, | |
| 395 | 392 | .set_wol = at803x_set_wol, |
| 396 | 393 | .get_wol = at803x_get_wol, |
| 397 | 394 | .suspend = at803x_suspend, |
| @@ -427,7 +424,6 @@ static struct phy_driver at803x_driver[] = { · 29 unmodified lines | ||
| 427 | 424 | .phy_id_mask = 0xffffffef, |
| 428 | 425 | .probe = at803x_probe, |
| 429 | 426 | .config_init = at803x_config_init, |
| 430 | − .link_change_notify = at803x_link_change_notify, | |
| 431 | 427 | .set_wol = at803x_set_wol, |
| 432 | 428 | .get_wol = at803x_get_wol, |
| 433 | 429 | .suspend = at803x_suspend, |
| @@ -269,6 +269,7 @@ struct skb_data { /* skb->cb is one of these */ · 268 unmodified lines | ||
| 269 | 269 | struct lan78xx_net *dev; |
| 270 | 270 | enum skb_state state; |
| 271 | 271 | size_t length; |
| 272 | + int num_of_packet; | |
| 272 | 273 | }; |
| 273 | 274 | |
| 274 | 275 | struct usb_context { |
| @@ -1803,7 +1804,34 @@ static void lan78xx_remove_mdio(struct lan78xx_net *dev) · 1528 unmodified lines | ||
| 1803 | 1804 | |
| 1804 | 1805 | static void lan78xx_link_status_change(struct net_device *net) |
| 1805 | 1806 | { |
| 1806 | − /* nothing to do */ | |
| 1807 | + struct phy_device *phydev = net->phydev; | |
| 1808 | + int ret, temp; | |
| 1809 | + | |
| 1810 | + /* At forced 100 F/H mode, chip may fail to set mode correctly | |
| 1811 | + * when cable is switched between long(~50+m) and short one. | |
| 1812 | + * As workaround, set to 10 before setting to 100 | |
| 1813 | + * at forced 100 F/H mode. | |
| 1814 | + */ | |
| 1815 | + if (!phydev->autoneg && (phydev->speed == 100)) { | |
| 1816 | + /* disable phy interrupt */ | |
| 1817 | + temp = phy_read(phydev, LAN88XX_INT_MASK); | |
| 1818 | + temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_; | |
| 1819 | + ret = phy_write(phydev, LAN88XX_INT_MASK, temp); | |
| 1820 | + | |
| 1821 | + temp = phy_read(phydev, MII_BMCR); | |
| 1822 | + temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000); | |
| 1823 | + phy_write(phydev, MII_BMCR, temp); /* set to 10 first */ | |
| 1824 | + temp |= BMCR_SPEED100; | |
| 1825 | + phy_write(phydev, MII_BMCR, temp); /* set to 100 later */ | |
| 1826 | + | |
| 1827 | + /* clear pending interrupt generated while workaround */ | |
| 1828 | + temp = phy_read(phydev, LAN88XX_INT_STS); | |
| 1829 | + | |
| 1830 | + /* enable phy interrupt back */ | |
| 1831 | + temp = phy_read(phydev, LAN88XX_INT_MASK); | |
| 1832 | + temp |= LAN88XX_INT_MASK_MDINTPIN_EN_; | |
| 1833 | + ret = phy_write(phydev, LAN88XX_INT_MASK, temp); | |
| 1834 | + } | |
| 1807 | 1835 | } |
| 1808 | 1836 | |
| 1809 | 1837 | static int lan78xx_phy_init(struct lan78xx_net *dev) |
| @@ -2464,7 +2492,7 @@ static void tx_complete(struct urb *urb) · 654 unmodified lines | ||
| 2464 | 2492 | struct lan78xx_net *dev = entry->dev; |
| 2465 | 2493 | |
| 2466 | 2494 | if (urb->status == 0) { |
| 2467 | − dev->net->stats.tx_packets++; | |
| 2495 | + dev->net->stats.tx_packets += entry->num_of_packet; | |
| 2468 | 2496 | dev->net->stats.tx_bytes += entry->length; |
| 2469 | 2497 | } else { |
| 2470 | 2498 | dev->net->stats.tx_errors++; |
| @@ -2681,10 +2709,11 @@ void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb) · 210 unmodified lines | ||
| 2681 | 2709 | return; |
| 2682 | 2710 | } |
| 2683 | 2711 | |
| 2684 | − skb->protocol = eth_type_trans(skb, dev->net); | |
| 2685 | 2712 | dev->net->stats.rx_packets++; |
| 2686 | 2713 | dev->net->stats.rx_bytes += skb->len; |
| 2687 | 2714 | |
| 2715 | + skb->protocol = eth_type_trans(skb, dev->net); | |
| 2716 | + | |
| 2688 | 2717 | netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n", |
| 2689 | 2718 | skb->len + sizeof(struct ethhdr), skb->protocol); |
| 2690 | 2719 | memset(skb->cb, 0, sizeof(struct skb_data)); |
| @@ -2934,13 +2963,16 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) · 243 unmodified lines | ||
| 2934 | 2963 | |
| 2935 | 2964 | skb_totallen = 0; |
| 2936 | 2965 | pkt_cnt = 0; |
| 2966 | + count = 0; | |
| 2967 | + length = 0; | |
| 2937 | 2968 | for (skb = tqp->next; pkt_cnt < tqp->qlen; skb = skb->next) { |
| 2938 | 2969 | if (skb_is_gso(skb)) { |
| 2939 | 2970 | if (pkt_cnt) { |
| 2940 | 2971 | /* handle previous packets first */ |
| 2941 | 2972 | break; |
| 2942 | 2973 | } |
| 2943 | − length = skb->len; | |
| 2974 | + count = 1; | |
| 2975 | + length = skb->len - TX_OVERHEAD; | |
| 2944 | 2976 | skb2 = skb_dequeue(tqp); |
| 2945 | 2977 | goto gso_skb; |
| 2946 | 2978 | } |
| @@ -2961,14 +2993,13 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) · 14 unmodified lines | ||
| 2961 | 2993 | for (count = pos = 0; count < pkt_cnt; count++) { |
| 2962 | 2994 | skb2 = skb_dequeue(tqp); |
| 2963 | 2995 | if (skb2) { |
| 2996 | + length += (skb2->len - TX_OVERHEAD); | |
| 2964 | 2997 | memcpy(skb->data + pos, skb2->data, skb2->len); |
| 2965 | 2998 | pos += roundup(skb2->len, sizeof(u32)); |
| 2966 | 2999 | dev_kfree_skb(skb2); |
| 2967 | 3000 | } |
| 2968 | 3001 | } |
| 2969 | 3002 | |
| 2970 | − length = skb_totallen; | |
| 2971 | − | |
| 2972 | 3003 | gso_skb: |
| 2973 | 3004 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
| 2974 | 3005 | if (!urb) { |
| @@ -2980,6 +3011,7 @@ gso_skb: · 5 unmodified lines | ||
| 2980 | 3011 | entry->urb = urb; |
| 2981 | 3012 | entry->dev = dev; |
| 2982 | 3013 | entry->length = length; |
| 3014 | + entry->num_of_packet = count; | |
| 2983 | 3015 | |
| 2984 | 3016 | spin_lock_irqsave(&dev->txq.lock, flags); |
| 2985 | 3017 | ret = usb_autopm_get_interface_async(dev->intf); |
| @@ -411,7 +411,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) · 410 unmodified lines | ||
| 411 | 411 | int ret; |
| 412 | 412 | |
| 413 | 413 | read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart); |
| 414 | − data[0] = 0xc9; | |
| 414 | + data[0] = 0xc8; /* TX & RX enable, append status, no CRC */ | |
| 415 | 415 | data[1] = 0; |
| 416 | 416 | if (linkpart & (ADVERTISE_100FULL | ADVERTISE_10FULL)) |
| 417 | 417 | data[1] |= 0x20; /* set full duplex */ |
| @@ -497,7 +497,7 @@ static void read_bulk_callback(struct urb *urb) · 79 unmodified lines | ||
| 497 | 497 | pkt_len = buf[count - 3] << 8; |
| 498 | 498 | pkt_len += buf[count - 4]; |
| 499 | 499 | pkt_len &= 0xfff; |
| 500 | − pkt_len -= 8; | |
| 500 | + pkt_len -= 4; | |
| 501 | 501 | } |
| 502 | 502 | |
| 503 | 503 | /* |
| @@ -528,7 +528,7 @@ static void read_bulk_callback(struct urb *urb) · 24 unmodified lines | ||
| 528 | 528 | goon: |
| 529 | 529 | usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, |
| 530 | 530 | usb_rcvbulkpipe(pegasus->usb, 1), |
| 531 | − pegasus->rx_skb->data, PEGASUS_MTU + 8, | |
| 531 | + pegasus->rx_skb->data, PEGASUS_MTU, | |
| 532 | 532 | read_bulk_callback, pegasus); |
| 533 | 533 | rx_status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); |
| 534 | 534 | if (rx_status == -ENODEV) |
| @@ -569,7 +569,7 @@ static void rx_fixup(unsigned long data) · 34 unmodified lines | ||
| 569 | 569 | } |
| 570 | 570 | usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, |
| 571 | 571 | usb_rcvbulkpipe(pegasus->usb, 1), |
| 572 | − pegasus->rx_skb->data, PEGASUS_MTU + 8, | |
| 572 | + pegasus->rx_skb->data, PEGASUS_MTU, | |
| 573 | 573 | read_bulk_callback, pegasus); |
| 574 | 574 | try_again: |
| 575 | 575 | status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); |
| @@ -823,7 +823,7 @@ static int pegasus_open(struct net_device *net) · 247 unmodified lines | ||
| 823 | 823 | |
| 824 | 824 | usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, |
| 825 | 825 | usb_rcvbulkpipe(pegasus->usb, 1), |
| 826 | − pegasus->rx_skb->data, PEGASUS_MTU + 8, | |
| 826 | + pegasus->rx_skb->data, PEGASUS_MTU, | |
| 827 | 827 | read_bulk_callback, pegasus); |
| 828 | 828 | if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) { |
| 829 | 829 | if (res == -ENODEV) |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/crc32.h> |
| 30 | 30 | #include <linux/usb/usbnet.h> |
| 31 | 31 | #include <linux/slab.h> |
| 32 | +#include <linux/of_net.h> | |
| 32 | 33 | #include "smsc75xx.h" |
| 33 | 34 | |
| 34 | 35 | #define SMSC_CHIPNAME "smsc75xx" |
| @@ -761,6 +762,15 @@ static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) · 726 unmodified lines | ||
| 761 | 762 | |
| 762 | 763 | static void smsc75xx_init_mac_address(struct usbnet *dev) |
| 763 | 764 | { |
| 765 | + const u8 *mac_addr; | |
| 766 | + | |
| 767 | + /* maybe the boot loader passed the MAC address in devicetree */ | |
| 768 | + mac_addr = of_get_mac_address(dev->udev->dev.of_node); | |
| 769 | + if (mac_addr) { | |
| 770 | + memcpy(dev->net->dev_addr, mac_addr, ETH_ALEN); | |
| 771 | + return; | |
| 772 | + } | |
| 773 | + | |
| 764 | 774 | /* try reading mac address from EEPROM */ |
| 765 | 775 | if (smsc75xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, |
| 766 | 776 | dev->net->dev_addr) == 0) { |
| @@ -772,7 +782,7 @@ static void smsc75xx_init_mac_address(struct usbnet *dev) · 5 unmodified lines | ||
| 772 | 782 | } |
| 773 | 783 | } |
| 774 | 784 | |
| 775 | − /* no eeprom, or eeprom values are invalid. generate random MAC */ | |
| 785 | + /* no useful static MAC address found. generate a random one */ | |
| 776 | 786 | eth_hw_addr_random(dev->net); |
| 777 | 787 | netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); |
| 778 | 788 | } |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/crc32.h> |
| 30 | 30 | #include <linux/usb/usbnet.h> |
| 31 | 31 | #include <linux/slab.h> |
| 32 | +#include <linux/of_net.h> | |
| 32 | 33 | #include "smsc95xx.h" |
| 33 | 34 | |
| 34 | 35 | #define SMSC_CHIPNAME "smsc95xx" |
| @@ -765,6 +766,15 @@ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) · 730 unmodified lines | ||
| 765 | 766 | |
| 766 | 767 | static void smsc95xx_init_mac_address(struct usbnet *dev) |
| 767 | 768 | { |
| 769 | + const u8 *mac_addr; | |
| 770 | + | |
| 771 | + /* maybe the boot loader passed the MAC address in devicetree */ | |
| 772 | + mac_addr = of_get_mac_address(dev->udev->dev.of_node); | |
| 773 | + if (mac_addr) { | |
| 774 | + memcpy(dev->net->dev_addr, mac_addr, ETH_ALEN); | |
| 775 | + return; | |
| 776 | + } | |
| 777 | + | |
| 768 | 778 | /* try reading mac address from EEPROM */ |
| 769 | 779 | if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, |
| 770 | 780 | dev->net->dev_addr) == 0) { |
| @@ -775,7 +785,7 @@ static void smsc95xx_init_mac_address(struct usbnet *dev) · 4 unmodified lines | ||
| 775 | 785 | } |
| 776 | 786 | } |
| 777 | 787 | |
| 778 | − /* no eeprom, or eeprom values are invalid. generate random MAC */ | |
| 788 | + /* no useful static MAC address found. generate a random one */ | |
| 779 | 789 | eth_hw_addr_random(dev->net); |
| 780 | 790 | netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); |
| 781 | 791 | } |
| @@ -274,6 +274,9 @@ void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah, · 273 unmodified lines | ||
| 274 | 274 | }; |
| 275 | 275 | static const int inc[4] = { 0, 100, 0, 0 }; |
| 276 | 276 | |
| 277 | + memset(&mask_m, 0, sizeof(int8_t) * 123); | |
| 278 | + memset(&mask_p, 0, sizeof(int8_t) * 123); | |
| 279 | + | |
| 277 | 280 | cur_bin = -6000; |
| 278 | 281 | upper = bin + 100; |
| 279 | 282 | lower = bin - 100; |
| @@ -424,14 +427,9 @@ static void ar5008_hw_spur_mitigate(struct ath_hw *ah, · 144 unmodified lines | ||
| 424 | 427 | int tmp, new; |
| 425 | 428 | int i; |
| 426 | 429 | |
| 427 | − int8_t mask_m[123]; | |
| 428 | − int8_t mask_p[123]; | |
| 429 | 430 | int cur_bb_spur; |
| 430 | 431 | bool is2GHz = IS_CHAN_2GHZ(chan); |
| 431 | 432 | |
| 432 | − memset(&mask_m, 0, sizeof(int8_t) * 123); | |
| 433 | − memset(&mask_p, 0, sizeof(int8_t) * 123); | |
| 434 | − | |
| 435 | 433 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { |
| 436 | 434 | cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); |
| 437 | 435 | if (AR_NO_SPUR == cur_bb_spur) |
| @@ -178,14 +178,9 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah, · 177 unmodified lines | ||
| 178 | 178 | int i; |
| 179 | 179 | struct chan_centers centers; |
| 180 | 180 | |
| 181 | − int8_t mask_m[123]; | |
| 182 | − int8_t mask_p[123]; | |
| 183 | 181 | int cur_bb_spur; |
| 184 | 182 | bool is2GHz = IS_CHAN_2GHZ(chan); |
| 185 | 183 | |
| 186 | − memset(&mask_m, 0, sizeof(int8_t) * 123); | |
| 187 | − memset(&mask_p, 0, sizeof(int8_t) * 123); | |
| 188 | − | |
| 189 | 184 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); |
| 190 | 185 | freq = centers.synth_center; |
| 191 | 186 | |
| @@ -93,7 +93,7 @@ · 92 unmodified lines | ||
| 93 | 93 | #define IWL8260_SMEM_OFFSET 0x400000 |
| 94 | 94 | #define IWL8260_SMEM_LEN 0x68000 |
| 95 | 95 | |
| 96 | −#define IWL8000_FW_PRE "iwlwifi-8000" | |
| 96 | +#define IWL8000_FW_PRE "iwlwifi-8000C-" | |
| 97 | 97 | #define IWL8000_MODULE_FIRMWARE(api) \ |
| 98 | 98 | IWL8000_FW_PRE "-" __stringify(api) ".ucode" |
| 99 | 99 | |
| @@ -238,19 +238,6 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) · 237 unmodified lines | ||
| 238 | 238 | snprintf(drv->firmware_name, sizeof(drv->firmware_name), "%s%s.ucode", |
| 239 | 239 | name_pre, tag); |
| 240 | 240 | |
| 241 | − /* | |
| 242 | − * Starting 8000B - FW name format has changed. This overwrites the | |
| 243 | − * previous name and uses the new format. | |
| 244 | − */ | |
| 245 | − if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) { | |
| 246 | − char rev_step = 'A' + CSR_HW_REV_STEP(drv->trans->hw_rev); | |
| 247 | − | |
| 248 | − if (rev_step != 'A') | |
| 249 | − snprintf(drv->firmware_name, | |
| 250 | − sizeof(drv->firmware_name), "%s%c-%s.ucode", | |
| 251 | − name_pre, rev_step, tag); | |
| 252 | − } | |
| 253 | − | |
| 254 | 241 | IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n", |
| 255 | 242 | (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) |
| 256 | 243 | ? "EXPERIMENTAL " : "", |
| @@ -1060,11 +1047,18 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, · 803 unmodified lines | ||
| 1060 | 1047 | return -EINVAL; |
| 1061 | 1048 | } |
| 1062 | 1049 | |
| 1063 | − if (WARN(fw_has_capa(capa, IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT) && | |
| 1064 | − !gscan_capa, | |
| 1065 | − "GSCAN is supported but capabilities TLV is unavailable\n")) | |
| 1050 | + /* | |
| 1051 | + * If ucode advertises that it supports GSCAN but GSCAN | |
| 1052 | + * capabilities TLV is not present, or if it has an old format, | |
| 1053 | + * warn and continue without GSCAN. | |
| 1054 | + */ | |
| 1055 | + if (fw_has_capa(capa, IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT) && | |
| 1056 | + !gscan_capa) { | |
| 1057 | + IWL_DEBUG_INFO(drv, | |
| 1058 | + "GSCAN is supported but capabilities TLV is unavailable\n"); | |
| 1066 | 1059 | __clear_bit((__force long)IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT, |
| 1067 | 1060 | capa->_capa); |
| 1061 | + } | |
| 1068 | 1062 | |
| 1069 | 1063 | return 0; |
| 1070 | 1064 | |
| @@ -526,7 +526,8 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) · 525 unmodified lines | ||
| 526 | 526 | file_len += sizeof(*dump_data) + sizeof(*dump_mem) + sram2_len; |
| 527 | 527 | |
| 528 | 528 | /* Make room for fw's virtual image pages, if it exists */ |
| 529 | − if (mvm->fw->img[mvm->cur_ucode].paging_mem_size) | |
| 529 | + if (mvm->fw->img[mvm->cur_ucode].paging_mem_size && | |
| 530 | + mvm->fw_paging_db[0].fw_paging_block) | |
| 530 | 531 | file_len += mvm->num_of_paging_blk * |
| 531 | 532 | (sizeof(*dump_data) + |
| 532 | 533 | sizeof(struct iwl_fw_error_dump_paging) + |
| @@ -643,7 +644,8 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) · 110 unmodified lines | ||
| 643 | 644 | } |
| 644 | 645 | |
| 645 | 646 | /* Dump fw's virtual image */ |
| 646 | − if (mvm->fw->img[mvm->cur_ucode].paging_mem_size) { | |
| 647 | + if (mvm->fw->img[mvm->cur_ucode].paging_mem_size && | |
| 648 | + mvm->fw_paging_db[0].fw_paging_block) { | |
| 647 | 649 | for (i = 1; i < mvm->num_of_paging_blk + 1; i++) { |
| 648 | 650 | struct iwl_fw_error_dump_paging *paging; |
| 649 | 651 | struct page *pages = |
| @@ -144,9 +144,11 @@ void iwl_free_fw_paging(struct iwl_mvm *mvm) · 143 unmodified lines | ||
| 144 | 144 | |
| 145 | 145 | __free_pages(mvm->fw_paging_db[i].fw_paging_block, |
| 146 | 146 | get_order(mvm->fw_paging_db[i].fw_paging_size)); |
| 147 | + mvm->fw_paging_db[i].fw_paging_block = NULL; | |
| 147 | 148 | } |
| 148 | 149 | kfree(mvm->trans->paging_download_buf); |
| 149 | 150 | mvm->trans->paging_download_buf = NULL; |
| 151 | + mvm->trans->paging_db = NULL; | |
| 150 | 152 | |
| 151 | 153 | memset(mvm->fw_paging_db, 0, sizeof(mvm->fw_paging_db)); |
| 152 | 154 | } |
| @@ -479,8 +479,18 @@ static const struct pci_device_id iwl_hw_card_ids[] = { · 478 unmodified lines | ||
| 479 | 479 | {IWL_PCI_DEVICE(0x24F3, 0x0930, iwl8260_2ac_cfg)}, |
| 480 | 480 | {IWL_PCI_DEVICE(0x24F3, 0x0000, iwl8265_2ac_cfg)}, |
| 481 | 481 | {IWL_PCI_DEVICE(0x24FD, 0x0010, iwl8265_2ac_cfg)}, |
| 482 | + {IWL_PCI_DEVICE(0x24FD, 0x0110, iwl8265_2ac_cfg)}, | |
| 483 | + {IWL_PCI_DEVICE(0x24FD, 0x1110, iwl8265_2ac_cfg)}, | |
| 484 | + {IWL_PCI_DEVICE(0x24FD, 0x1010, iwl8265_2ac_cfg)}, | |
| 485 | + {IWL_PCI_DEVICE(0x24FD, 0x0050, iwl8265_2ac_cfg)}, | |
| 486 | + {IWL_PCI_DEVICE(0x24FD, 0x0150, iwl8265_2ac_cfg)}, | |
| 487 | + {IWL_PCI_DEVICE(0x24FD, 0x9010, iwl8265_2ac_cfg)}, | |
| 488 | + {IWL_PCI_DEVICE(0x24FD, 0x8110, iwl8265_2ac_cfg)}, | |
| 489 | + {IWL_PCI_DEVICE(0x24FD, 0x8050, iwl8265_2ac_cfg)}, | |
| 482 | 490 | {IWL_PCI_DEVICE(0x24FD, 0x8010, iwl8265_2ac_cfg)}, |
| 483 | 491 | {IWL_PCI_DEVICE(0x24FD, 0x0810, iwl8265_2ac_cfg)}, |
| 492 | + {IWL_PCI_DEVICE(0x24FD, 0x9110, iwl8265_2ac_cfg)}, | |
| 493 | + {IWL_PCI_DEVICE(0x24FD, 0x8130, iwl8265_2ac_cfg)}, | |
| 484 | 494 | |
| 485 | 495 | /* 9000 Series */ |
| 486 | 496 | {IWL_PCI_DEVICE(0x9DF0, 0x2A10, iwl5165_2ac_cfg)}, |
| @@ -397,10 +397,17 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) · 396 unmodified lines | ||
| 397 | 397 | */ |
| 398 | 398 | start += start_pad; |
| 399 | 399 | npfns = (pmem->size - start_pad - end_trunc - SZ_8K) / SZ_4K; |
| 400 | − if (nd_pfn->mode == PFN_MODE_PMEM) | |
| 401 | − offset = ALIGN(start + SZ_8K + 64 * npfns, nd_pfn->align) | |
| 400 | + if (nd_pfn->mode == PFN_MODE_PMEM) { | |
| 401 | + unsigned long memmap_size; | |
| 402 | + | |
| 403 | + /* | |
| 404 | + * vmemmap_populate_hugepages() allocates the memmap array in | |
| 405 | + * HPAGE_SIZE chunks. | |
| 406 | + */ | |
| 407 | + memmap_size = ALIGN(64 * npfns, HPAGE_SIZE); | |
| 408 | + offset = ALIGN(start + SZ_8K + memmap_size, nd_pfn->align) | |
| 402 | 409 | - start; |
| 403 | − else if (nd_pfn->mode == PFN_MODE_RAM) | |
| 410 | + } else if (nd_pfn->mode == PFN_MODE_RAM) | |
| 404 | 411 | offset = ALIGN(start + SZ_8K, nd_pfn->align) - start; |
| 405 | 412 | else |
| 406 | 413 | goto err; |
| @@ -94,7 +94,7 @@ static int mxs_ocotp_read(void *context, const void *reg, size_t reg_size, · 93 unmodified lines | ||
| 94 | 94 | if (ret) |
| 95 | 95 | goto close_banks; |
| 96 | 96 | |
| 97 | − while (val_size) { | |
| 97 | + while (val_size >= reg_size) { | |
| 98 | 98 | if ((offset < OCOTP_DATA_OFFSET) || (offset % 16)) { |
| 99 | 99 | /* fill up non-data register */ |
| 100 | 100 | *buf = 0; |
| @@ -103,7 +103,7 @@ static int mxs_ocotp_read(void *context, const void *reg, size_t reg_size, · 2 unmodified lines | ||
| 103 | 103 | } |
| 104 | 104 | |
| 105 | 105 | buf++; |
| 106 | − val_size--; | |
| 106 | + val_size -= reg_size; | |
| 107 | 107 | offset += reg_size; |
| 108 | 108 | } |
| 109 | 109 | |
| @@ -135,7 +135,7 @@ MODULE_LICENSE("GPL"); · 134 unmodified lines | ||
| 135 | 135 | /* Field definitions */ |
| 136 | 136 | #define HCI_ACCEL_MASK 0x7fff |
| 137 | 137 | #define HCI_HOTKEY_DISABLE 0x0b |
| 138 | −#define HCI_HOTKEY_ENABLE 0x01 | |
| 138 | +#define HCI_HOTKEY_ENABLE 0x09 | |
| 139 | 139 | #define HCI_HOTKEY_SPECIAL_FUNCTIONS 0x10 |
| 140 | 140 | #define HCI_LCD_BRIGHTNESS_BITS 3 |
| 141 | 141 | #define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS) |
| @@ -126,7 +126,7 @@ struct rio_mport_mapping { · 125 unmodified lines | ||
| 126 | 126 | struct list_head node; |
| 127 | 127 | struct mport_dev *md; |
| 128 | 128 | enum rio_mport_map_dir dir; |
| 129 | − u32 rioid; | |
| 129 | + u16 rioid; | |
| 130 | 130 | u64 rio_addr; |
| 131 | 131 | dma_addr_t phys_addr; /* for mmap */ |
| 132 | 132 | void *virt_addr; /* kernel address, for dma_free_coherent */ |
| @@ -137,7 +137,7 @@ struct rio_mport_mapping { · 4 unmodified lines | ||
| 137 | 137 | |
| 138 | 138 | struct rio_mport_dma_map { |
| 139 | 139 | int valid; |
| 140 | − uint64_t length; | |
| 140 | + u64 length; | |
| 141 | 141 | void *vaddr; |
| 142 | 142 | dma_addr_t paddr; |
| 143 | 143 | }; |
| @@ -208,7 +208,7 @@ struct mport_cdev_priv { · 64 unmodified lines | ||
| 208 | 208 | struct kfifo event_fifo; |
| 209 | 209 | wait_queue_head_t event_rx_wait; |
| 210 | 210 | spinlock_t fifo_lock; |
| 211 | − unsigned int event_mask; /* RIO_DOORBELL, RIO_PORTWRITE */ | |
| 211 | + u32 event_mask; /* RIO_DOORBELL, RIO_PORTWRITE */ | |
| 212 | 212 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE |
| 213 | 213 | struct dma_chan *dmach; |
| 214 | 214 | struct list_head async_list; |
| @@ -276,7 +276,8 @@ static int rio_mport_maint_rd(struct mport_cdev_priv *priv, void __user *arg, · 61 unmodified lines | ||
| 276 | 276 | return -EFAULT; |
| 277 | 277 | |
| 278 | 278 | if ((maint_io.offset % 4) || |
| 279 | − (maint_io.length == 0) || (maint_io.length % 4)) | |
| 279 | + (maint_io.length == 0) || (maint_io.length % 4) || | |
| 280 | + (maint_io.length + maint_io.offset) > RIO_MAINT_SPACE_SZ) | |
| 280 | 281 | return -EINVAL; |
| 281 | 282 | |
| 282 | 283 | buffer = vmalloc(maint_io.length); |
| @@ -298,7 +299,8 @@ static int rio_mport_maint_rd(struct mport_cdev_priv *priv, void __user *arg, · 15 unmodified lines | ||
| 298 | 299 | offset += 4; |
| 299 | 300 | } |
| 300 | 301 | |
| 301 | − if (unlikely(copy_to_user(maint_io.buffer, buffer, maint_io.length))) | |
| 302 | + if (unlikely(copy_to_user((void __user *)(uintptr_t)maint_io.buffer, | |
| 303 | + buffer, maint_io.length))) | |
| 302 | 304 | ret = -EFAULT; |
| 303 | 305 | out: |
| 304 | 306 | vfree(buffer); |
| @@ -319,7 +321,8 @@ static int rio_mport_maint_wr(struct mport_cdev_priv *priv, void __user *arg, · 14 unmodified lines | ||
| 319 | 321 | return -EFAULT; |
| 320 | 322 | |
| 321 | 323 | if ((maint_io.offset % 4) || |
| 322 | − (maint_io.length == 0) || (maint_io.length % 4)) | |
| 324 | + (maint_io.length == 0) || (maint_io.length % 4) || | |
| 325 | + (maint_io.length + maint_io.offset) > RIO_MAINT_SPACE_SZ) | |
| 323 | 326 | return -EINVAL; |
| 324 | 327 | |
| 325 | 328 | buffer = vmalloc(maint_io.length); |
| @@ -327,7 +330,8 @@ static int rio_mport_maint_wr(struct mport_cdev_priv *priv, void __user *arg, · 1 unmodified line | ||
| 327 | 330 | return -ENOMEM; |
| 328 | 331 | length = maint_io.length; |
| 329 | 332 | |
| 330 | − if (unlikely(copy_from_user(buffer, maint_io.buffer, length))) { | |
| 333 | + if (unlikely(copy_from_user(buffer, | |
| 334 | + (void __user *)(uintptr_t)maint_io.buffer, length))) { | |
| 331 | 335 | ret = -EFAULT; |
| 332 | 336 | goto out; |
| 333 | 337 | } |
| @@ -360,7 +364,7 @@ out: · 26 unmodified lines | ||
| 360 | 364 | */ |
| 361 | 365 | static int |
| 362 | 366 | rio_mport_create_outbound_mapping(struct mport_dev *md, struct file *filp, |
| 363 | − u32 rioid, u64 raddr, u32 size, | |
| 367 | + u16 rioid, u64 raddr, u32 size, | |
| 364 | 368 | dma_addr_t *paddr) |
| 365 | 369 | { |
| 366 | 370 | struct rio_mport *mport = md->mport; |
| @@ -369,7 +373,7 @@ rio_mport_create_outbound_mapping(struct mport_dev *md, struct file *filp, · 2 unmodified lines | ||
| 369 | 373 | |
| 370 | 374 | rmcd_debug(OBW, "did=%d ra=0x%llx sz=0x%x", rioid, raddr, size); |
| 371 | 375 | |
| 372 | − map = kzalloc(sizeof(struct rio_mport_mapping), GFP_KERNEL); | |
| 376 | + map = kzalloc(sizeof(*map), GFP_KERNEL); | |
| 373 | 377 | if (map == NULL) |
| 374 | 378 | return -ENOMEM; |
| 375 | 379 | |
| @@ -394,7 +398,7 @@ err_map_outb: · 18 unmodified lines | ||
| 394 | 398 | |
| 395 | 399 | static int |
| 396 | 400 | rio_mport_get_outbound_mapping(struct mport_dev *md, struct file *filp, |
| 397 | − u32 rioid, u64 raddr, u32 size, | |
| 401 | + u16 rioid, u64 raddr, u32 size, | |
| 398 | 402 | dma_addr_t *paddr) |
| 399 | 403 | { |
| 400 | 404 | struct rio_mport_mapping *map; |
| @@ -433,7 +437,7 @@ static int rio_mport_obw_map(struct file *filp, void __user *arg) · 32 unmodified lines | ||
| 433 | 437 | dma_addr_t paddr; |
| 434 | 438 | int ret; |
| 435 | 439 | |
| 436 | − if (unlikely(copy_from_user(&map, arg, sizeof(struct rio_mmap)))) | |
| 440 | + if (unlikely(copy_from_user(&map, arg, sizeof(map)))) | |
| 437 | 441 | return -EFAULT; |
| 438 | 442 | |
| 439 | 443 | rmcd_debug(OBW, "did=%d ra=0x%llx sz=0x%llx", |
| @@ -448,7 +452,7 @@ static int rio_mport_obw_map(struct file *filp, void __user *arg) · 8 unmodified lines | ||
| 448 | 452 | |
| 449 | 453 | map.handle = paddr; |
| 450 | 454 | |
| 451 | − if (unlikely(copy_to_user(arg, &map, sizeof(struct rio_mmap)))) | |
| 455 | + if (unlikely(copy_to_user(arg, &map, sizeof(map)))) | |
| 452 | 456 | return -EFAULT; |
| 453 | 457 | return 0; |
| 454 | 458 | } |
| @@ -469,7 +473,7 @@ static int rio_mport_obw_free(struct file *filp, void __user *arg) · 14 unmodified lines | ||
| 469 | 473 | if (!md->mport->ops->unmap_outb) |
| 470 | 474 | return -EPROTONOSUPPORT; |
| 471 | 475 | |
| 472 | − if (copy_from_user(&handle, arg, sizeof(u64))) | |
| 476 | + if (copy_from_user(&handle, arg, sizeof(handle))) | |
| 473 | 477 | return -EFAULT; |
| 474 | 478 | |
| 475 | 479 | rmcd_debug(OBW, "h=0x%llx", handle); |
| @@ -498,9 +502,9 @@ static int rio_mport_obw_free(struct file *filp, void __user *arg) · 22 unmodified lines | ||
| 498 | 502 | static int maint_hdid_set(struct mport_cdev_priv *priv, void __user *arg) |
| 499 | 503 | { |
| 500 | 504 | struct mport_dev *md = priv->md; |
| 501 | − uint16_t hdid; | |
| 505 | + u16 hdid; | |
| 502 | 506 | |
| 503 | − if (copy_from_user(&hdid, arg, sizeof(uint16_t))) | |
| 507 | + if (copy_from_user(&hdid, arg, sizeof(hdid))) | |
| 504 | 508 | return -EFAULT; |
| 505 | 509 | |
| 506 | 510 | md->mport->host_deviceid = hdid; |
| @@ -520,9 +524,9 @@ static int maint_hdid_set(struct mport_cdev_priv *priv, void __user *arg) · 13 unmodified lines | ||
| 520 | 524 | static int maint_comptag_set(struct mport_cdev_priv *priv, void __user *arg) |
| 521 | 525 | { |
| 522 | 526 | struct mport_dev *md = priv->md; |
| 523 | − uint32_t comptag; | |
| 527 | + u32 comptag; | |
| 524 | 528 | |
| 525 | − if (copy_from_user(&comptag, arg, sizeof(uint32_t))) | |
| 529 | + if (copy_from_user(&comptag, arg, sizeof(comptag))) | |
| 526 | 530 | return -EFAULT; |
| 527 | 531 | |
| 528 | 532 | rio_local_write_config_32(md->mport, RIO_COMPONENT_TAG_CSR, comptag); |
| @@ -837,7 +841,7 @@ err_out: · 308 unmodified lines | ||
| 837 | 841 | * @xfer: data transfer descriptor structure |
| 838 | 842 | */ |
| 839 | 843 | static int |
| 840 | −rio_dma_transfer(struct file *filp, uint32_t transfer_mode, | |
| 844 | +rio_dma_transfer(struct file *filp, u32 transfer_mode, | |
| 841 | 845 | enum rio_transfer_sync sync, enum dma_data_direction dir, |
| 842 | 846 | struct rio_transfer_io *xfer) |
| 843 | 847 | { |
| @@ -875,7 +879,7 @@ rio_dma_transfer(struct file *filp, uint32_t transfer_mode, · 31 unmodified lines | ||
| 875 | 879 | unsigned long offset; |
| 876 | 880 | long pinned; |
| 877 | 881 | |
| 878 | − offset = (unsigned long)xfer->loc_addr & ~PAGE_MASK; | |
| 882 | + offset = (unsigned long)(uintptr_t)xfer->loc_addr & ~PAGE_MASK; | |
| 879 | 883 | nr_pages = PAGE_ALIGN(xfer->length + offset) >> PAGE_SHIFT; |
| 880 | 884 | |
| 881 | 885 | page_list = kmalloc_array(nr_pages, |
| @@ -1015,19 +1019,20 @@ static int rio_mport_transfer_ioctl(struct file *filp, void __user *arg) · 133 unmodified lines | ||
| 1015 | 1019 | if (unlikely(copy_from_user(&transaction, arg, sizeof(transaction)))) |
| 1016 | 1020 | return -EFAULT; |
| 1017 | 1021 | |
| 1018 | − if (transaction.count != 1) | |
| 1022 | + if (transaction.count != 1) /* only single transfer for now */ | |
| 1019 | 1023 | return -EINVAL; |
| 1020 | 1024 | |
| 1021 | 1025 | if ((transaction.transfer_mode & |
| 1022 | 1026 | priv->md->properties.transfer_mode) == 0) |
| 1023 | 1027 | return -ENODEV; |
| 1024 | 1028 | |
| 1025 | − transfer = vmalloc(transaction.count * sizeof(struct rio_transfer_io)); | |
| 1029 | + transfer = vmalloc(transaction.count * sizeof(*transfer)); | |
| 1026 | 1030 | if (!transfer) |
| 1027 | 1031 | return -ENOMEM; |
| 1028 | 1032 | |
| 1029 | − if (unlikely(copy_from_user(transfer, transaction.block, | |
| 1030 | − transaction.count * sizeof(struct rio_transfer_io)))) { | |
| 1033 | + if (unlikely(copy_from_user(transfer, | |
| 1034 | + (void __user *)(uintptr_t)transaction.block, | |
| 1035 | + transaction.count * sizeof(*transfer)))) { | |
| 1031 | 1036 | ret = -EFAULT; |
| 1032 | 1037 | goto out_free; |
| 1033 | 1038 | } |
| @@ -1038,8 +1043,9 @@ static int rio_mport_transfer_ioctl(struct file *filp, void __user *arg) · 4 unmodified lines | ||
| 1038 | 1043 | ret = rio_dma_transfer(filp, transaction.transfer_mode, |
| 1039 | 1044 | transaction.sync, dir, &transfer[i]); |
| 1040 | 1045 | |
| 1041 | − if (unlikely(copy_to_user(transaction.block, transfer, | |
| 1042 | − transaction.count * sizeof(struct rio_transfer_io)))) | |
| 1046 | + if (unlikely(copy_to_user((void __user *)(uintptr_t)transaction.block, | |
| 1047 | + transfer, | |
| 1048 | + transaction.count * sizeof(*transfer)))) | |
| 1043 | 1049 | ret = -EFAULT; |
| 1044 | 1050 | |
| 1045 | 1051 | out_free: |
| @@ -1129,11 +1135,11 @@ err_tmo: · 83 unmodified lines | ||
| 1129 | 1135 | } |
| 1130 | 1136 | |
| 1131 | 1137 | static int rio_mport_create_dma_mapping(struct mport_dev *md, struct file *filp, |
| 1132 | − uint64_t size, struct rio_mport_mapping **mapping) | |
| 1138 | + u64 size, struct rio_mport_mapping **mapping) | |
| 1133 | 1139 | { |
| 1134 | 1140 | struct rio_mport_mapping *map; |
| 1135 | 1141 | |
| 1136 | − map = kzalloc(sizeof(struct rio_mport_mapping), GFP_KERNEL); | |
| 1142 | + map = kzalloc(sizeof(*map), GFP_KERNEL); | |
| 1137 | 1143 | if (map == NULL) |
| 1138 | 1144 | return -ENOMEM; |
| 1139 | 1145 | |
| @@ -1165,7 +1171,7 @@ static int rio_mport_alloc_dma(struct file *filp, void __user *arg) · 25 unmodified lines | ||
| 1165 | 1171 | struct rio_mport_mapping *mapping = NULL; |
| 1166 | 1172 | int ret; |
| 1167 | 1173 | |
| 1168 | − if (unlikely(copy_from_user(&map, arg, sizeof(struct rio_dma_mem)))) | |
| 1174 | + if (unlikely(copy_from_user(&map, arg, sizeof(map)))) | |
| 1169 | 1175 | return -EFAULT; |
| 1170 | 1176 | |
| 1171 | 1177 | ret = rio_mport_create_dma_mapping(md, filp, map.length, &mapping); |
| @@ -1174,7 +1180,7 @@ static int rio_mport_alloc_dma(struct file *filp, void __user *arg) · 2 unmodified lines | ||
| 1174 | 1180 | |
| 1175 | 1181 | map.dma_handle = mapping->phys_addr; |
| 1176 | 1182 | |
| 1177 | − if (unlikely(copy_to_user(arg, &map, sizeof(struct rio_dma_mem)))) { | |
| 1183 | + if (unlikely(copy_to_user(arg, &map, sizeof(map)))) { | |
| 1178 | 1184 | mutex_lock(&md->buf_mutex); |
| 1179 | 1185 | kref_put(&mapping->ref, mport_release_mapping); |
| 1180 | 1186 | mutex_unlock(&md->buf_mutex); |
| @@ -1192,7 +1198,7 @@ static int rio_mport_free_dma(struct file *filp, void __user *arg) · 11 unmodified lines | ||
| 1192 | 1198 | int ret = -EFAULT; |
| 1193 | 1199 | struct rio_mport_mapping *map, *_map; |
| 1194 | 1200 | |
| 1195 | − if (copy_from_user(&handle, arg, sizeof(u64))) | |
| 1201 | + if (copy_from_user(&handle, arg, sizeof(handle))) | |
| 1196 | 1202 | return -EFAULT; |
| 1197 | 1203 | rmcd_debug(EXIT, "filp=%p", filp); |
| 1198 | 1204 | |
| @@ -1242,14 +1248,18 @@ static int rio_mport_free_dma(struct file *filp, void __user *arg) · 43 unmodified lines | ||
| 1242 | 1248 | |
| 1243 | 1249 | static int |
| 1244 | 1250 | rio_mport_create_inbound_mapping(struct mport_dev *md, struct file *filp, |
| 1245 | − u64 raddr, u32 size, | |
| 1251 | + u64 raddr, u64 size, | |
| 1246 | 1252 | struct rio_mport_mapping **mapping) |
| 1247 | 1253 | { |
| 1248 | 1254 | struct rio_mport *mport = md->mport; |
| 1249 | 1255 | struct rio_mport_mapping *map; |
| 1250 | 1256 | int ret; |
| 1251 | 1257 | |
| 1252 | − map = kzalloc(sizeof(struct rio_mport_mapping), GFP_KERNEL); | |
| 1258 | + /* rio_map_inb_region() accepts u32 size */ | |
| 1259 | + if (size > 0xffffffff) | |
| 1260 | + return -EINVAL; | |
| 1261 | + | |
| 1262 | + map = kzalloc(sizeof(*map), GFP_KERNEL); | |
| 1253 | 1263 | if (map == NULL) |
| 1254 | 1264 | return -ENOMEM; |
| 1255 | 1265 | |
| @@ -1262,7 +1272,7 @@ rio_mport_create_inbound_mapping(struct mport_dev *md, struct file *filp, · 6 unmodified lines | ||
| 1262 | 1272 | |
| 1263 | 1273 | if (raddr == RIO_MAP_ANY_ADDR) |
| 1264 | 1274 | raddr = map->phys_addr; |
| 1265 | − ret = rio_map_inb_region(mport, map->phys_addr, raddr, size, 0); | |
| 1275 | + ret = rio_map_inb_region(mport, map->phys_addr, raddr, (u32)size, 0); | |
| 1266 | 1276 | if (ret < 0) |
| 1267 | 1277 | goto err_map_inb; |
| 1268 | 1278 | |
| @@ -1288,7 +1298,7 @@ err_dma_alloc: · 19 unmodified lines | ||
| 1288 | 1298 | |
| 1289 | 1299 | static int |
| 1290 | 1300 | rio_mport_get_inbound_mapping(struct mport_dev *md, struct file *filp, |
| 1291 | − u64 raddr, u32 size, | |
| 1301 | + u64 raddr, u64 size, | |
| 1292 | 1302 | struct rio_mport_mapping **mapping) |
| 1293 | 1303 | { |
| 1294 | 1304 | struct rio_mport_mapping *map; |
| @@ -1331,7 +1341,7 @@ static int rio_mport_map_inbound(struct file *filp, void __user *arg) · 36 unmodified lines | ||
| 1331 | 1341 | |
| 1332 | 1342 | if (!md->mport->ops->map_inb) |
| 1333 | 1343 | return -EPROTONOSUPPORT; |
| 1334 | − if (unlikely(copy_from_user(&map, arg, sizeof(struct rio_mmap)))) | |
| 1344 | + if (unlikely(copy_from_user(&map, arg, sizeof(map)))) | |
| 1335 | 1345 | return -EFAULT; |
| 1336 | 1346 | |
| 1337 | 1347 | rmcd_debug(IBW, "%s filp=%p", dev_name(&priv->md->dev), filp); |
| @@ -1344,7 +1354,7 @@ static int rio_mport_map_inbound(struct file *filp, void __user *arg) · 6 unmodified lines | ||
| 1344 | 1354 | map.handle = mapping->phys_addr; |
| 1345 | 1355 | map.rio_addr = mapping->rio_addr; |
| 1346 | 1356 | |
| 1347 | − if (unlikely(copy_to_user(arg, &map, sizeof(struct rio_mmap)))) { | |
| 1357 | + if (unlikely(copy_to_user(arg, &map, sizeof(map)))) { | |
| 1348 | 1358 | /* Delete mapping if it was created by this request */ |
| 1349 | 1359 | if (ret == 0 && mapping->filp == filp) { |
| 1350 | 1360 | mutex_lock(&md->buf_mutex); |
| @@ -1375,7 +1385,7 @@ static int rio_mport_inbound_free(struct file *filp, void __user *arg) · 24 unmodified lines | ||
| 1375 | 1385 | if (!md->mport->ops->unmap_inb) |
| 1376 | 1386 | return -EPROTONOSUPPORT; |
| 1377 | 1387 | |
| 1378 | − if (copy_from_user(&handle, arg, sizeof(u64))) | |
| 1388 | + if (copy_from_user(&handle, arg, sizeof(handle))) | |
| 1379 | 1389 | return -EFAULT; |
| 1380 | 1390 | |
| 1381 | 1391 | mutex_lock(&md->buf_mutex); |
| @@ -1401,7 +1411,7 @@ static int rio_mport_inbound_free(struct file *filp, void __user *arg) · 19 unmodified lines | ||
| 1401 | 1411 | static int maint_port_idx_get(struct mport_cdev_priv *priv, void __user *arg) |
| 1402 | 1412 | { |
| 1403 | 1413 | struct mport_dev *md = priv->md; |
| 1404 | − uint32_t port_idx = md->mport->index; | |
| 1414 | + u32 port_idx = md->mport->index; | |
| 1405 | 1415 | |
| 1406 | 1416 | rmcd_debug(MPORT, "port_index=%d", port_idx); |
| 1407 | 1417 | |
| @@ -1451,7 +1461,7 @@ static void rio_mport_doorbell_handler(struct rio_mport *mport, void *dev_id, · 43 unmodified lines | ||
| 1451 | 1461 | handled = 0; |
| 1452 | 1462 | spin_lock(&data->db_lock); |
| 1453 | 1463 | list_for_each_entry(db_filter, &data->doorbells, data_node) { |
| 1454 | − if (((db_filter->filter.rioid == 0xffffffff || | |
| 1464 | + if (((db_filter->filter.rioid == RIO_INVALID_DESTID || | |
| 1455 | 1465 | db_filter->filter.rioid == src)) && |
| 1456 | 1466 | info >= db_filter->filter.low && |
| 1457 | 1467 | info <= db_filter->filter.high) { |
| @@ -1525,6 +1535,9 @@ static int rio_mport_remove_db_filter(struct mport_cdev_priv *priv, · 67 unmodified lines | ||
| 1525 | 1535 | if (copy_from_user(&filter, arg, sizeof(filter))) |
| 1526 | 1536 | return -EFAULT; |
| 1527 | 1537 | |
| 1538 | + if (filter.low > filter.high) | |
| 1539 | + return -EINVAL; | |
| 1540 | + | |
| 1528 | 1541 | spin_lock_irqsave(&priv->md->db_lock, flags); |
| 1529 | 1542 | list_for_each_entry(db_filter, &priv->db_filters, priv_node) { |
| 1530 | 1543 | if (db_filter->filter.rioid == filter.rioid && |
| @@ -1737,10 +1750,10 @@ static int rio_mport_add_riodev(struct mport_cdev_priv *priv, · 206 unmodified lines | ||
| 1737 | 1750 | return -EEXIST; |
| 1738 | 1751 | } |
| 1739 | 1752 | |
| 1740 | − size = sizeof(struct rio_dev); | |
| 1753 | + size = sizeof(*rdev); | |
| 1741 | 1754 | mport = md->mport; |
| 1742 | − destid = (u16)dev_info.destid; | |
| 1743 | − hopcount = (u8)dev_info.hopcount; | |
| 1755 | + destid = dev_info.destid; | |
| 1756 | + hopcount = dev_info.hopcount; | |
| 1744 | 1757 | |
| 1745 | 1758 | if (rio_mport_read_config_32(mport, destid, hopcount, |
| 1746 | 1759 | RIO_PEF_CAR, &rval)) |
| @@ -1872,8 +1885,8 @@ static int rio_mport_del_riodev(struct mport_cdev_priv *priv, void __user *arg) · 125 unmodified lines | ||
| 1872 | 1885 | do { |
| 1873 | 1886 | rdev = rio_get_comptag(dev_info.comptag, rdev); |
| 1874 | 1887 | if (rdev && rdev->dev.parent == &mport->net->dev && |
| 1875 | − rdev->destid == (u16)dev_info.destid && | |
| 1876 | − rdev->hopcount == (u8)dev_info.hopcount) | |
| 1888 | + rdev->destid == dev_info.destid && | |
| 1889 | + rdev->hopcount == dev_info.hopcount) | |
| 1877 | 1890 | break; |
| 1878 | 1891 | } while (rdev); |
| 1879 | 1892 | } |
| @@ -2146,8 +2159,8 @@ static long mport_cdev_ioctl(struct file *filp, · 266 unmodified lines | ||
| 2146 | 2159 | return maint_port_idx_get(data, (void __user *)arg); |
| 2147 | 2160 | case RIO_MPORT_GET_PROPERTIES: |
| 2148 | 2161 | md->properties.hdid = md->mport->host_deviceid; |
| 2149 | − if (copy_to_user((void __user *)arg, &(data->md->properties), | |
| 2150 | − sizeof(data->md->properties))) | |
| 2162 | + if (copy_to_user((void __user *)arg, &(md->properties), | |
| 2163 | + sizeof(md->properties))) | |
| 2151 | 2164 | return -EFAULT; |
| 2152 | 2165 | return 0; |
| 2153 | 2166 | case RIO_ENABLE_DOORBELL_RANGE: |
| @@ -2159,11 +2172,11 @@ static long mport_cdev_ioctl(struct file *filp, · 5 unmodified lines | ||
| 2159 | 2172 | case RIO_DISABLE_PORTWRITE_RANGE: |
| 2160 | 2173 | return rio_mport_remove_pw_filter(data, (void __user *)arg); |
| 2161 | 2174 | case RIO_SET_EVENT_MASK: |
| 2162 | − data->event_mask = arg; | |
| 2175 | + data->event_mask = (u32)arg; | |
| 2163 | 2176 | return 0; |
| 2164 | 2177 | case RIO_GET_EVENT_MASK: |
| 2165 | 2178 | if (copy_to_user((void __user *)arg, &data->event_mask, |
| 2166 | − sizeof(data->event_mask))) | |
| 2179 | + sizeof(u32))) | |
| 2167 | 2180 | return -EFAULT; |
| 2168 | 2181 | return 0; |
| 2169 | 2182 | case RIO_MAP_OUTBOUND: |
| @@ -2374,7 +2387,7 @@ static ssize_t mport_write(struct file *filp, const char __user *buf, · 204 unmodified lines | ||
| 2374 | 2387 | return -EINVAL; |
| 2375 | 2388 | |
| 2376 | 2389 | ret = rio_mport_send_doorbell(mport, |
| 2377 | − (u16)event.u.doorbell.rioid, | |
| 2390 | + event.u.doorbell.rioid, | |
| 2378 | 2391 | event.u.doorbell.payload); |
| 2379 | 2392 | if (ret < 0) |
| 2380 | 2393 | return ret; |
| @@ -2421,7 +2434,7 @@ static struct mport_dev *mport_cdev_add(struct rio_mport *mport) · 40 unmodified lines | ||
| 2421 | 2434 | struct mport_dev *md; |
| 2422 | 2435 | struct rio_mport_attr attr; |
| 2423 | 2436 | |
| 2424 | − md = kzalloc(sizeof(struct mport_dev), GFP_KERNEL); | |
| 2437 | + md = kzalloc(sizeof(*md), GFP_KERNEL); | |
| 2425 | 2438 | if (!md) { |
| 2426 | 2439 | rmcd_error("Unable allocate a device object"); |
| 2427 | 2440 | return NULL; |
| @@ -2470,7 +2483,7 @@ static struct mport_dev *mport_cdev_add(struct rio_mport *mport) · 42 unmodified lines | ||
| 2470 | 2483 | /* The transfer_mode property will be returned through mport query |
| 2471 | 2484 | * interface |
| 2472 | 2485 | */ |
| 2473 | −#ifdef CONFIG_PPC /* for now: only on Freescale's SoCs */ | |
| 2486 | +#ifdef CONFIG_FSL_RIO /* for now: only on Freescale's SoCs */ | |
| 2474 | 2487 | md->properties.transfer_mode |= RIO_TRANSFER_MODE_MAPPED; |
| 2475 | 2488 | #else |
| 2476 | 2489 | md->properties.transfer_mode |= RIO_TRANSFER_MODE_TRANSFER; |
| @@ -2669,9 +2682,9 @@ static int __init mport_init(void) · 192 unmodified lines | ||
| 2669 | 2682 | |
| 2670 | 2683 | /* Create device class needed by udev */ |
| 2671 | 2684 | dev_class = class_create(THIS_MODULE, DRV_NAME); |
| 2672 | − if (!dev_class) { | |
| 2685 | + if (IS_ERR(dev_class)) { | |
| 2673 | 2686 | rmcd_error("Unable to create " DRV_NAME " class"); |
| 2674 | − return -EINVAL; | |
| 2687 | + return PTR_ERR(dev_class); | |
| 2675 | 2688 | } |
| 2676 | 2689 | |
| 2677 | 2690 | ret = alloc_chrdev_region(&dev_number, 0, RIO_MAX_MPORTS, DRV_NAME); |
| @@ -56,6 +56,7 @@ static int sclp_ctl_ioctl_sccb(void __user *user_area) · 55 unmodified lines | ||
| 56 | 56 | { |
| 57 | 57 | struct sclp_ctl_sccb ctl_sccb; |
| 58 | 58 | struct sccb_header *sccb; |
| 59 | + unsigned long copied; | |
| 59 | 60 | int rc; |
| 60 | 61 | |
| 61 | 62 | if (copy_from_user(&ctl_sccb, user_area, sizeof(ctl_sccb))) |
| @@ -65,14 +66,15 @@ static int sclp_ctl_ioctl_sccb(void __user *user_area) · 3 unmodified lines | ||
| 65 | 66 | sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); |
| 66 | 67 | if (!sccb) |
| 67 | 68 | return -ENOMEM; |
| 68 | − if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sizeof(*sccb))) { | |
| 69 | + copied = PAGE_SIZE - | |
| 70 | + copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), PAGE_SIZE); | |
| 71 | + if (offsetof(struct sccb_header, length) + | |
| 72 | + sizeof(sccb->length) > copied || sccb->length > copied) { | |
| 69 | 73 | rc = -EFAULT; |
| 70 | 74 | goto out_free; |
| 71 | 75 | } |
| 72 | − if (sccb->length > PAGE_SIZE || sccb->length < 8) | |
| 73 | − return -EINVAL; | |
| 74 | − if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sccb->length)) { | |
| 75 | − rc = -EFAULT; | |
| 76 | + if (sccb->length < 8) { | |
| 77 | + rc = -EINVAL; | |
| 76 | 78 | goto out_free; |
| 77 | 79 | } |
| 78 | 80 | rc = sclp_sync_request(ctl_sccb.cmdw, sccb); |
| @@ -688,6 +688,7 @@ static struct rt6_info *find_route_ipv6(const struct in6_addr *saddr, · 687 unmodified lines | ||
| 688 | 688 | { |
| 689 | 689 | struct flowi6 fl; |
| 690 | 690 | |
| 691 | + memset(&fl, 0, sizeof(fl)); | |
| 691 | 692 | if (saddr) |
| 692 | 693 | memcpy(&fl.saddr, saddr, sizeof(struct in6_addr)); |
| 693 | 694 | if (daddr) |
| @@ -491,13 +491,14 @@ static int scpsys_probe(struct platform_device *pdev) · 490 unmodified lines | ||
| 491 | 491 | genpd->dev_ops.active_wakeup = scpsys_active_wakeup; |
| 492 | 492 | |
| 493 | 493 | /* |
| 494 | − * With CONFIG_PM disabled turn on all domains to make the | |
| 495 | − * hardware usable. | |
| 494 | + * Initially turn on all domains to make the domains usable | |
| 495 | + * with !CONFIG_PM and to get the hardware in sync with the | |
| 496 | + * software. The unused domains will be switched off during | |
| 497 | + * late_init time. | |
| 496 | 498 | */ |
| 497 | − if (!IS_ENABLED(CONFIG_PM)) | |
| 498 | − genpd->power_on(genpd); | |
| 499 | + genpd->power_on(genpd); | |
| 499 | 500 | |
| 500 | − pm_genpd_init(genpd, NULL, true); | |
| 501 | + pm_genpd_init(genpd, NULL, false); | |
| 501 | 502 | } |
| 502 | 503 | |
| 503 | 504 | /* |
| @@ -172,9 +172,11 @@ static int vpfe_prepare_pipeline(struct vpfe_video_device *video) · 171 unmodified lines | ||
| 172 | 172 | static int vpfe_update_pipe_state(struct vpfe_video_device *video) |
| 173 | 173 | { |
| 174 | 174 | struct vpfe_pipeline *pipe = &video->pipe; |
| 175 | + int ret; | |
| 175 | 176 | |
| 176 | − if (vpfe_prepare_pipeline(video)) | |
| 177 | − return vpfe_prepare_pipeline(video); | |
| 177 | + ret = vpfe_prepare_pipeline(video); | |
| 178 | + if (ret) | |
| 179 | + return ret; | |
| 178 | 180 | |
| 179 | 181 | /* |
| 180 | 182 | * Find out if there is any input video |
| @@ -182,9 +184,10 @@ static int vpfe_update_pipe_state(struct vpfe_video_device *video) · 1 unmodified line | ||
| 182 | 184 | */ |
| 183 | 185 | if (pipe->input_num == 0) { |
| 184 | 186 | pipe->state = VPFE_PIPELINE_STREAM_CONTINUOUS; |
| 185 | − if (vpfe_update_current_ext_subdev(video)) { | |
| 187 | + ret = vpfe_update_current_ext_subdev(video); | |
| 188 | + if (ret) { | |
| 186 | 189 | pr_err("Invalid external subdev\n"); |
| 187 | − return vpfe_update_current_ext_subdev(video); | |
| 190 | + return ret; | |
| 188 | 191 | } |
| 189 | 192 | } else { |
| 190 | 193 | pipe->state = VPFE_PIPELINE_STREAM_SINGLESHOT; |
| @@ -667,6 +670,7 @@ static int vpfe_enum_fmt(struct file *file, void *priv, · 476 unmodified lines | ||
| 667 | 670 | struct v4l2_subdev *subdev; |
| 668 | 671 | struct v4l2_format format; |
| 669 | 672 | struct media_pad *remote; |
| 673 | + int ret; | |
| 670 | 674 | |
| 671 | 675 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt\n"); |
| 672 | 676 | |
| @@ -695,10 +699,11 @@ static int vpfe_enum_fmt(struct file *file, void *priv, · 22 unmodified lines | ||
| 695 | 699 | sd_fmt.pad = remote->index; |
| 696 | 700 | sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; |
| 697 | 701 | /* get output format of remote subdev */ |
| 698 | − if (v4l2_subdev_call(subdev, pad, get_fmt, NULL, &sd_fmt)) { | |
| 702 | + ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &sd_fmt); | |
| 703 | + if (ret) { | |
| 699 | 704 | v4l2_err(&vpfe_dev->v4l2_dev, |
| 700 | 705 | "invalid remote subdev for video node\n"); |
| 701 | − return v4l2_subdev_call(subdev, pad, get_fmt, NULL, &sd_fmt); | |
| 706 | + return ret; | |
| 702 | 707 | } |
| 703 | 708 | /* convert to pix format */ |
| 704 | 709 | mbus.code = sd_fmt.format.code; |
| @@ -725,6 +730,7 @@ static int vpfe_s_fmt(struct file *file, void *priv, · 20 unmodified lines | ||
| 725 | 730 | struct vpfe_video_device *video = video_drvdata(file); |
| 726 | 731 | struct vpfe_device *vpfe_dev = video->vpfe_dev; |
| 727 | 732 | struct v4l2_format format; |
| 733 | + int ret; | |
| 728 | 734 | |
| 729 | 735 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_fmt\n"); |
| 730 | 736 | /* If streaming is started, return error */ |
| @@ -733,8 +739,9 @@ static int vpfe_s_fmt(struct file *file, void *priv, · 2 unmodified lines | ||
| 733 | 739 | return -EBUSY; |
| 734 | 740 | } |
| 735 | 741 | /* get adjacent subdev's output pad format */ |
| 736 | − if (__vpfe_video_get_format(video, &format)) | |
| 737 | − return __vpfe_video_get_format(video, &format); | |
| 742 | + ret = __vpfe_video_get_format(video, &format); | |
| 743 | + if (ret) | |
| 744 | + return ret; | |
| 738 | 745 | *fmt = format; |
| 739 | 746 | video->fmt = *fmt; |
| 740 | 747 | return 0; |
| @@ -757,11 +764,13 @@ static int vpfe_try_fmt(struct file *file, void *priv, · 16 unmodified lines | ||
| 757 | 764 | struct vpfe_video_device *video = video_drvdata(file); |
| 758 | 765 | struct vpfe_device *vpfe_dev = video->vpfe_dev; |
| 759 | 766 | struct v4l2_format format; |
| 767 | + int ret; | |
| 760 | 768 | |
| 761 | 769 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_try_fmt\n"); |
| 762 | 770 | /* get adjacent subdev's output pad format */ |
| 763 | − if (__vpfe_video_get_format(video, &format)) | |
| 764 | − return __vpfe_video_get_format(video, &format); | |
| 771 | + ret = __vpfe_video_get_format(video, &format); | |
| 772 | + if (ret) | |
| 773 | + return ret; | |
| 765 | 774 | |
| 766 | 775 | *fmt = format; |
| 767 | 776 | return 0; |
| @@ -838,8 +847,9 @@ static int vpfe_s_input(struct file *file, void *priv, unsigned int index) · 70 unmodified lines | ||
| 838 | 847 | |
| 839 | 848 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_input\n"); |
| 840 | 849 | |
| 841 | − if (mutex_lock_interruptible(&video->lock)) | |
| 842 | − return mutex_lock_interruptible(&video->lock); | |
| 850 | + ret = mutex_lock_interruptible(&video->lock); | |
| 851 | + if (ret) | |
| 852 | + return ret; | |
| 843 | 853 | /* |
| 844 | 854 | * If streaming is started return device busy |
| 845 | 855 | * error |
| @@ -940,8 +950,9 @@ static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id std_id) · 94 unmodified lines | ||
| 940 | 950 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_std\n"); |
| 941 | 951 | |
| 942 | 952 | /* Call decoder driver function to set the standard */ |
| 943 | − if (mutex_lock_interruptible(&video->lock)) | |
| 944 | − return mutex_lock_interruptible(&video->lock); | |
| 953 | + ret = mutex_lock_interruptible(&video->lock); | |
| 954 | + if (ret) | |
| 955 | + return ret; | |
| 945 | 956 | sdinfo = video->current_ext_subdev; |
| 946 | 957 | /* If streaming is started, return device busy error */ |
| 947 | 958 | if (video->started) { |
| @@ -1327,8 +1338,9 @@ static int vpfe_reqbufs(struct file *file, void *priv, · 379 unmodified lines | ||
| 1327 | 1338 | return -EINVAL; |
| 1328 | 1339 | } |
| 1329 | 1340 | |
| 1330 | − if (mutex_lock_interruptible(&video->lock)) | |
| 1331 | − return mutex_lock_interruptible(&video->lock); | |
| 1341 | + ret = mutex_lock_interruptible(&video->lock); | |
| 1342 | + if (ret) | |
| 1343 | + return ret; | |
| 1332 | 1344 | |
| 1333 | 1345 | if (video->io_usrs != 0) { |
| 1334 | 1346 | v4l2_err(&vpfe_dev->v4l2_dev, "Only one IO user allowed\n"); |
| @@ -1354,10 +1366,11 @@ static int vpfe_reqbufs(struct file *file, void *priv, · 19 unmodified lines | ||
| 1354 | 1366 | q->buf_struct_size = sizeof(struct vpfe_cap_buffer); |
| 1355 | 1367 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
| 1356 | 1368 | |
| 1357 | − if (vb2_queue_init(q)) { | |
| 1369 | + ret = vb2_queue_init(q); | |
| 1370 | + if (ret) { | |
| 1358 | 1371 | v4l2_err(&vpfe_dev->v4l2_dev, "vb2_queue_init() failed\n"); |
| 1359 | 1372 | vb2_dma_contig_cleanup_ctx(vpfe_dev->pdev); |
| 1360 | − return vb2_queue_init(q); | |
| 1373 | + return ret; | |
| 1361 | 1374 | } |
| 1362 | 1375 | |
| 1363 | 1376 | fh->io_allowed = 1; |
| @@ -1533,8 +1546,9 @@ static int vpfe_streamoff(struct file *file, void *priv, · 169 unmodified lines | ||
| 1533 | 1546 | return -EINVAL; |
| 1534 | 1547 | } |
| 1535 | 1548 | |
| 1536 | − if (mutex_lock_interruptible(&video->lock)) | |
| 1537 | − return mutex_lock_interruptible(&video->lock); | |
| 1549 | + ret = mutex_lock_interruptible(&video->lock); | |
| 1550 | + if (ret) | |
| 1551 | + return ret; | |
| 1538 | 1552 | |
| 1539 | 1553 | vpfe_stop_capture(video); |
| 1540 | 1554 | ret = vb2_streamoff(&video->buffer_queue, buf_type); |
| @@ -3,4 +3,4 @@ July, 2015 · 2 unmodified lines | ||
| 3 | 3 | - Remove unneeded file entries in sysfs |
| 4 | 4 | - Remove software processing of IB protocol and place in library for use |
| 5 | 5 | by qib, ipath (if still present), hfi1, and eventually soft-roce |
| 6 | − | |
| 6 | +- Replace incorrect uAPI | |
| @@ -49,6 +49,8 @@ · 48 unmodified lines | ||
| 49 | 49 | #include <linux/vmalloc.h> |
| 50 | 50 | #include <linux/io.h> |
| 51 | 51 | |
| 52 | +#include <rdma/ib.h> | |
| 53 | + | |
| 52 | 54 | #include "hfi.h" |
| 53 | 55 | #include "pio.h" |
| 54 | 56 | #include "device.h" |
| @@ -190,6 +192,10 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data, · 135 unmodified lines | ||
| 190 | 192 | int uctxt_required = 1; |
| 191 | 193 | int must_be_root = 0; |
| 192 | 194 | |
| 195 | + /* FIXME: This interface cannot continue out of staging */ | |
| 196 | + if (WARN_ON_ONCE(!ib_safe_file_access(fp))) | |
| 197 | + return -EACCES; | |
| 198 | + | |
| 193 | 199 | if (count < sizeof(cmd)) { |
| 194 | 200 | ret = -EINVAL; |
| 195 | 201 | goto bail; |
| @@ -791,15 +797,16 @@ static int hfi1_file_close(struct inode *inode, struct file *fp) · 595 unmodified lines | ||
| 791 | 797 | spin_unlock_irqrestore(&dd->uctxt_lock, flags); |
| 792 | 798 | |
| 793 | 799 | dd->rcd[uctxt->ctxt] = NULL; |
| 800 | + | |
| 801 | + hfi1_user_exp_rcv_free(fdata); | |
| 802 | + hfi1_clear_ctxt_pkey(dd, uctxt->ctxt); | |
| 803 | + | |
| 794 | 804 | uctxt->rcvwait_to = 0; |
| 795 | 805 | uctxt->piowait_to = 0; |
| 796 | 806 | uctxt->rcvnowait = 0; |
| 797 | 807 | uctxt->pionowait = 0; |
| 798 | 808 | uctxt->event_flags = 0; |
| 799 | 809 | |
| 800 | − hfi1_user_exp_rcv_free(fdata); | |
| 801 | − hfi1_clear_ctxt_pkey(dd, uctxt->ctxt); | |
| 802 | − | |
| 803 | 810 | hfi1_stats.sps_ctxts--; |
| 804 | 811 | if (++dd->freectxts == dd->num_user_contexts) |
| 805 | 812 | aspm_enable_all(dd); |
| @@ -1127,27 +1134,13 @@ bail: · 321 unmodified lines | ||
| 1127 | 1134 | |
| 1128 | 1135 | static int user_init(struct file *fp) |
| 1129 | 1136 | { |
| 1130 | − int ret; | |
| 1131 | 1137 | unsigned int rcvctrl_ops = 0; |
| 1132 | 1138 | struct hfi1_filedata *fd = fp->private_data; |
| 1133 | 1139 | struct hfi1_ctxtdata *uctxt = fd->uctxt; |
| 1134 | 1140 | |
| 1135 | 1141 | /* make sure that the context has already been setup */ |
| 1136 | − if (!test_bit(HFI1_CTXT_SETUP_DONE, &uctxt->event_flags)) { | |
| 1137 | − ret = -EFAULT; | |
| 1138 | − goto done; | |
| 1139 | − } | |
| 1140 | − | |
| 1141 | − /* | |
| 1142 | − * Subctxts don't need to initialize anything since master | |
| 1143 | − * has done it. | |
| 1144 | − */ | |
| 1145 | − if (fd->subctxt) { | |
| 1146 | − ret = wait_event_interruptible(uctxt->wait, !test_bit( | |
| 1147 | − HFI1_CTXT_MASTER_UNINIT, | |
| 1148 | − &uctxt->event_flags)); | |
| 1149 | − goto expected; | |
| 1150 | − } | |
| 1142 | + if (!test_bit(HFI1_CTXT_SETUP_DONE, &uctxt->event_flags)) | |
| 1143 | + return -EFAULT; | |
| 1151 | 1144 | |
| 1152 | 1145 | /* initialize poll variables... */ |
| 1153 | 1146 | uctxt->urgent = 0; |
| @@ -1202,19 +1195,7 @@ static int user_init(struct file *fp) · 48 unmodified lines | ||
| 1202 | 1195 | wake_up(&uctxt->wait); |
| 1203 | 1196 | } |
| 1204 | 1197 | |
| 1205 | −expected: | |
| 1206 | − /* | |
| 1207 | − * Expected receive has to be setup for all processes (including | |
| 1208 | − * shared contexts). However, it has to be done after the master | |
| 1209 | − * context has been fully configured as it depends on the | |
| 1210 | − * eager/expected split of the RcvArray entries. | |
| 1211 | − * Setting it up here ensures that the subcontexts will be waiting | |
| 1212 | − * (due to the above wait_event_interruptible() until the master | |
| 1213 | − * is setup. | |
| 1214 | − */ | |
| 1215 | − ret = hfi1_user_exp_rcv_init(fp); | |
| 1216 | −done: | |
| 1217 | − return ret; | |
| 1198 | + return 0; | |
| 1218 | 1199 | } |
| 1219 | 1200 | |
| 1220 | 1201 | static int get_ctxt_info(struct file *fp, void __user *ubase, __u32 len) |
| @@ -1261,7 +1242,7 @@ static int setup_ctxt(struct file *fp) · 40 unmodified lines | ||
| 1261 | 1242 | int ret = 0; |
| 1262 | 1243 | |
| 1263 | 1244 | /* |
| 1264 | − * Context should be set up only once (including allocation and | |
| 1245 | + * Context should be set up only once, including allocation and | |
| 1265 | 1246 | * programming of eager buffers. This is done if context sharing |
| 1266 | 1247 | * is not requested or by the master process. |
| 1267 | 1248 | */ |
| @@ -1282,8 +1263,27 @@ static int setup_ctxt(struct file *fp) · 14 unmodified lines | ||
| 1282 | 1263 | if (ret) |
| 1283 | 1264 | goto done; |
| 1284 | 1265 | } |
| 1266 | + } else { | |
| 1267 | + ret = wait_event_interruptible(uctxt->wait, !test_bit( | |
| 1268 | + HFI1_CTXT_MASTER_UNINIT, | |
| 1269 | + &uctxt->event_flags)); | |
| 1270 | + if (ret) | |
| 1271 | + goto done; | |
| 1285 | 1272 | } |
| 1273 | + | |
| 1286 | 1274 | ret = hfi1_user_sdma_alloc_queues(uctxt, fp); |
| 1275 | + if (ret) | |
| 1276 | + goto done; | |
| 1277 | + /* | |
| 1278 | + * Expected receive has to be setup for all processes (including | |
| 1279 | + * shared contexts). However, it has to be done after the master | |
| 1280 | + * context has been fully configured as it depends on the | |
| 1281 | + * eager/expected split of the RcvArray entries. | |
| 1282 | + * Setting it up here ensures that the subcontexts will be waiting | |
| 1283 | + * (due to the above wait_event_interruptible() until the master | |
| 1284 | + * is setup. | |
| 1285 | + */ | |
| 1286 | + ret = hfi1_user_exp_rcv_init(fp); | |
| 1287 | 1287 | if (ret) |
| 1288 | 1288 | goto done; |
| 1289 | 1289 | |
| @@ -1565,29 +1565,8 @@ static loff_t ui_lseek(struct file *filp, loff_t offset, int whence) · 275 unmodified lines | ||
| 1565 | 1565 | { |
| 1566 | 1566 | struct hfi1_devdata *dd = filp->private_data; |
| 1567 | 1567 | |
| 1568 | − switch (whence) { | |
| 1569 | − case SEEK_SET: | |
| 1570 | − break; | |
| 1571 | − case SEEK_CUR: | |
| 1572 | − offset += filp->f_pos; | |
| 1573 | − break; | |
| 1574 | − case SEEK_END: | |
| 1575 | − offset = ((dd->kregend - dd->kregbase) + DC8051_DATA_MEM_SIZE) - | |
| 1576 | − offset; | |
| 1577 | − break; | |
| 1578 | − default: | |
| 1579 | − return -EINVAL; | |
| 1580 | − } | |
| 1581 | − | |
| 1582 | − if (offset < 0) | |
| 1583 | − return -EINVAL; | |
| 1584 | − | |
| 1585 | − if (offset >= (dd->kregend - dd->kregbase) + DC8051_DATA_MEM_SIZE) | |
| 1586 | − return -EINVAL; | |
| 1587 | − | |
| 1588 | − filp->f_pos = offset; | |
| 1589 | − | |
| 1590 | − return filp->f_pos; | |
| 1568 | + return fixed_size_llseek(filp, offset, whence, | |
| 1569 | + (dd->kregend - dd->kregbase) + DC8051_DATA_MEM_SIZE); | |
| 1591 | 1570 | } |
| 1592 | 1571 | |
| 1593 | 1572 | /* NOTE: assumes unsigned long is 8 bytes */ |
| @@ -71,6 +71,7 @@ static inline void mmu_notifier_range_start(struct mmu_notifier *, · 70 unmodified lines | ||
| 71 | 71 | struct mm_struct *, |
| 72 | 72 | unsigned long, unsigned long); |
| 73 | 73 | static void mmu_notifier_mem_invalidate(struct mmu_notifier *, |
| 74 | + struct mm_struct *, | |
| 74 | 75 | unsigned long, unsigned long); |
| 75 | 76 | static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *, |
| 76 | 77 | unsigned long, unsigned long); |
| @@ -137,7 +138,7 @@ void hfi1_mmu_rb_unregister(struct rb_root *root) · 60 unmodified lines | ||
| 137 | 138 | rbnode = rb_entry(node, struct mmu_rb_node, node); |
| 138 | 139 | rb_erase(node, root); |
| 139 | 140 | if (handler->ops->remove) |
| 140 | − handler->ops->remove(root, rbnode, false); | |
| 141 | + handler->ops->remove(root, rbnode, NULL); | |
| 141 | 142 | } |
| 142 | 143 | } |
| 143 | 144 | |
| @@ -176,7 +177,7 @@ unlock: · 32 unmodified lines | ||
| 176 | 177 | return ret; |
| 177 | 178 | } |
| 178 | 179 | |
| 179 | −/* Caller must host handler lock */ | |
| 180 | +/* Caller must hold handler lock */ | |
| 180 | 181 | static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler, |
| 181 | 182 | unsigned long addr, |
| 182 | 183 | unsigned long len) |
| @@ -200,15 +201,21 @@ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler, · 17 unmodified lines | ||
| 200 | 201 | return node; |
| 201 | 202 | } |
| 202 | 203 | |
| 204 | +/* Caller must *not* hold handler lock. */ | |
| 203 | 205 | static void __mmu_rb_remove(struct mmu_rb_handler *handler, |
| 204 | − struct mmu_rb_node *node, bool arg) | |
| 206 | + struct mmu_rb_node *node, struct mm_struct *mm) | |
| 205 | 207 | { |
| 208 | + unsigned long flags; | |
| 209 | + | |
| 206 | 210 | /* Validity of handler and node pointers has been checked by caller. */ |
| 207 | 211 | hfi1_cdbg(MMU, "Removing node addr 0x%llx, len %u", node->addr, |
| 208 | 212 | node->len); |
| 213 | + spin_lock_irqsave(&handler->lock, flags); | |
| 209 | 214 | __mmu_int_rb_remove(node, handler->root); |
| 215 | + spin_unlock_irqrestore(&handler->lock, flags); | |
| 216 | + | |
| 210 | 217 | if (handler->ops->remove) |
| 211 | − handler->ops->remove(handler->root, node, arg); | |
| 218 | + handler->ops->remove(handler->root, node, mm); | |
| 212 | 219 | } |
| 213 | 220 | |
| 214 | 221 | struct mmu_rb_node *hfi1_mmu_rb_search(struct rb_root *root, unsigned long addr, |
| @@ -231,14 +238,11 @@ struct mmu_rb_node *hfi1_mmu_rb_search(struct rb_root *root, unsigned long addr, · 16 unmodified lines | ||
| 231 | 238 | void hfi1_mmu_rb_remove(struct rb_root *root, struct mmu_rb_node *node) |
| 232 | 239 | { |
| 233 | 240 | struct mmu_rb_handler *handler = find_mmu_handler(root); |
| 234 | − unsigned long flags; | |
| 235 | 241 | |
| 236 | 242 | if (!handler || !node) |
| 237 | 243 | return; |
| 238 | 244 | |
| 239 | − spin_lock_irqsave(&handler->lock, flags); | |
| 240 | − __mmu_rb_remove(handler, node, false); | |
| 241 | − spin_unlock_irqrestore(&handler->lock, flags); | |
| 245 | + __mmu_rb_remove(handler, node, NULL); | |
| 242 | 246 | } |
| 243 | 247 | |
| 244 | 248 | static struct mmu_rb_handler *find_mmu_handler(struct rb_root *root) |
| @@ -260,7 +264,7 @@ unlock: · 15 unmodified lines | ||
| 260 | 264 | static inline void mmu_notifier_page(struct mmu_notifier *mn, |
| 261 | 265 | struct mm_struct *mm, unsigned long addr) |
| 262 | 266 | { |
| 263 | − mmu_notifier_mem_invalidate(mn, addr, addr + PAGE_SIZE); | |
| 267 | + mmu_notifier_mem_invalidate(mn, mm, addr, addr + PAGE_SIZE); | |
| 264 | 268 | } |
| 265 | 269 | |
| 266 | 270 | static inline void mmu_notifier_range_start(struct mmu_notifier *mn, |
| @@ -268,25 +272,31 @@ static inline void mmu_notifier_range_start(struct mmu_notifier *mn, · 1 unmodified line | ||
| 268 | 272 | unsigned long start, |
| 269 | 273 | unsigned long end) |
| 270 | 274 | { |
| 271 | − mmu_notifier_mem_invalidate(mn, start, end); | |
| 275 | + mmu_notifier_mem_invalidate(mn, mm, start, end); | |
| 272 | 276 | } |
| 273 | 277 | |
| 274 | 278 | static void mmu_notifier_mem_invalidate(struct mmu_notifier *mn, |
| 279 | + struct mm_struct *mm, | |
| 275 | 280 | unsigned long start, unsigned long end) |
| 276 | 281 | { |
| 277 | 282 | struct mmu_rb_handler *handler = |
| 278 | 283 | container_of(mn, struct mmu_rb_handler, mn); |
| 279 | 284 | struct rb_root *root = handler->root; |
| 280 | − struct mmu_rb_node *node; | |
| 285 | + struct mmu_rb_node *node, *ptr = NULL; | |
| 281 | 286 | unsigned long flags; |
| 282 | 287 | |
| 283 | 288 | spin_lock_irqsave(&handler->lock, flags); |
| 284 | − for (node = __mmu_int_rb_iter_first(root, start, end - 1); node; | |
| 285 | − node = __mmu_int_rb_iter_next(node, start, end - 1)) { | |
| 289 | + for (node = __mmu_int_rb_iter_first(root, start, end - 1); | |
| 290 | + node; node = ptr) { | |
| 291 | + /* Guard against node removal. */ | |
| 292 | + ptr = __mmu_int_rb_iter_next(node, start, end - 1); | |
| 286 | 293 | hfi1_cdbg(MMU, "Invalidating node addr 0x%llx, len %u", |
| 287 | 294 | node->addr, node->len); |
| 288 | − if (handler->ops->invalidate(root, node)) | |
| 289 | − __mmu_rb_remove(handler, node, true); | |
| 295 | + if (handler->ops->invalidate(root, node)) { | |
| 296 | + spin_unlock_irqrestore(&handler->lock, flags); | |
| 297 | + __mmu_rb_remove(handler, node, mm); | |
| 298 | + spin_lock_irqsave(&handler->lock, flags); | |
| 299 | + } | |
| 290 | 300 | } |
| 291 | 301 | spin_unlock_irqrestore(&handler->lock, flags); |
| 292 | 302 | } |
| @@ -59,7 +59,8 @@ struct mmu_rb_node { · 58 unmodified lines | ||
| 59 | 59 | struct mmu_rb_ops { |
| 60 | 60 | bool (*filter)(struct mmu_rb_node *, unsigned long, unsigned long); |
| 61 | 61 | int (*insert)(struct rb_root *, struct mmu_rb_node *); |
| 62 | − void (*remove)(struct rb_root *, struct mmu_rb_node *, bool); | |
| 62 | + void (*remove)(struct rb_root *, struct mmu_rb_node *, | |
| 63 | + struct mm_struct *); | |
| 63 | 64 | int (*invalidate)(struct rb_root *, struct mmu_rb_node *); |
| 64 | 65 | }; |
| 65 | 66 | |
| @@ -519,10 +519,12 @@ static void iowait_sdma_drained(struct iowait *wait) · 518 unmodified lines | ||
| 519 | 519 | * do the flush work until that QP's |
| 520 | 520 | * sdma work has finished. |
| 521 | 521 | */ |
| 522 | + spin_lock(&qp->s_lock); | |
| 522 | 523 | if (qp->s_flags & RVT_S_WAIT_DMA) { |
| 523 | 524 | qp->s_flags &= ~RVT_S_WAIT_DMA; |
| 524 | 525 | hfi1_schedule_send(qp); |
| 525 | 526 | } |
| 527 | + spin_unlock(&qp->s_lock); | |
| 526 | 528 | } |
| 527 | 529 | |
| 528 | 530 | /** |
| @@ -87,7 +87,8 @@ static u32 find_phys_blocks(struct page **, unsigned, struct tid_pageset *); · 86 unmodified lines | ||
| 87 | 87 | static int set_rcvarray_entry(struct file *, unsigned long, u32, |
| 88 | 88 | struct tid_group *, struct page **, unsigned); |
| 89 | 89 | static int mmu_rb_insert(struct rb_root *, struct mmu_rb_node *); |
| 90 | −static void mmu_rb_remove(struct rb_root *, struct mmu_rb_node *, bool); | |
| 90 | +static void mmu_rb_remove(struct rb_root *, struct mmu_rb_node *, | |
| 91 | + struct mm_struct *); | |
| 91 | 92 | static int mmu_rb_invalidate(struct rb_root *, struct mmu_rb_node *); |
| 92 | 93 | static int program_rcvarray(struct file *, unsigned long, struct tid_group *, |
| 93 | 94 | struct tid_pageset *, unsigned, u16, struct page **, |
| @@ -254,6 +255,8 @@ int hfi1_user_exp_rcv_free(struct hfi1_filedata *fd) · 160 unmodified lines | ||
| 254 | 255 | struct hfi1_ctxtdata *uctxt = fd->uctxt; |
| 255 | 256 | struct tid_group *grp, *gptr; |
| 256 | 257 | |
| 258 | + if (!test_bit(HFI1_CTXT_SETUP_DONE, &uctxt->event_flags)) | |
| 259 | + return 0; | |
| 257 | 260 | /* |
| 258 | 261 | * The notifier would have been removed when the process'es mm |
| 259 | 262 | * was freed. |
| @@ -899,7 +902,7 @@ static int unprogram_rcvarray(struct file *fp, u32 tidinfo, · 639 unmodified lines | ||
| 899 | 902 | if (!node || node->rcventry != (uctxt->expected_base + rcventry)) |
| 900 | 903 | return -EBADF; |
| 901 | 904 | if (HFI1_CAP_IS_USET(TID_UNMAP)) |
| 902 | − mmu_rb_remove(&fd->tid_rb_root, &node->mmu, false); | |
| 905 | + mmu_rb_remove(&fd->tid_rb_root, &node->mmu, NULL); | |
| 903 | 906 | else |
| 904 | 907 | hfi1_mmu_rb_remove(&fd->tid_rb_root, &node->mmu); |
| 905 | 908 | |
| @@ -965,7 +968,7 @@ static void unlock_exp_tids(struct hfi1_ctxtdata *uctxt, · 59 unmodified lines | ||
| 965 | 968 | continue; |
| 966 | 969 | if (HFI1_CAP_IS_USET(TID_UNMAP)) |
| 967 | 970 | mmu_rb_remove(&fd->tid_rb_root, |
| 968 | − &node->mmu, false); | |
| 971 | + &node->mmu, NULL); | |
| 969 | 972 | else |
| 970 | 973 | hfi1_mmu_rb_remove(&fd->tid_rb_root, |
| 971 | 974 | &node->mmu); |
| @@ -1032,7 +1035,7 @@ static int mmu_rb_insert(struct rb_root *root, struct mmu_rb_node *node) · 60 unmodified lines | ||
| 1032 | 1035 | } |
| 1033 | 1036 | |
| 1034 | 1037 | static void mmu_rb_remove(struct rb_root *root, struct mmu_rb_node *node, |
| 1035 | − bool notifier) | |
| 1038 | + struct mm_struct *mm) | |
| 1036 | 1039 | { |
| 1037 | 1040 | struct hfi1_filedata *fdata = |
| 1038 | 1041 | container_of(root, struct hfi1_filedata, tid_rb_root); |
| @@ -278,7 +278,8 @@ static inline void pq_update(struct hfi1_user_sdma_pkt_q *); · 277 unmodified lines | ||
| 278 | 278 | static void user_sdma_free_request(struct user_sdma_request *, bool); |
| 279 | 279 | static int pin_vector_pages(struct user_sdma_request *, |
| 280 | 280 | struct user_sdma_iovec *); |
| 281 | −static void unpin_vector_pages(struct mm_struct *, struct page **, unsigned); | |
| 281 | +static void unpin_vector_pages(struct mm_struct *, struct page **, unsigned, | |
| 282 | + unsigned); | |
| 282 | 283 | static int check_header_template(struct user_sdma_request *, |
| 283 | 284 | struct hfi1_pkt_header *, u32, u32); |
| 284 | 285 | static int set_txreq_header(struct user_sdma_request *, |
| @@ -299,7 +300,8 @@ static int defer_packet_queue( · 14 unmodified lines | ||
| 299 | 300 | static void activate_packet_queue(struct iowait *, int); |
| 300 | 301 | static bool sdma_rb_filter(struct mmu_rb_node *, unsigned long, unsigned long); |
| 301 | 302 | static int sdma_rb_insert(struct rb_root *, struct mmu_rb_node *); |
| 302 | −static void sdma_rb_remove(struct rb_root *, struct mmu_rb_node *, bool); | |
| 303 | +static void sdma_rb_remove(struct rb_root *, struct mmu_rb_node *, | |
| 304 | + struct mm_struct *); | |
| 303 | 305 | static int sdma_rb_invalidate(struct rb_root *, struct mmu_rb_node *); |
| 304 | 306 | |
| 305 | 307 | static struct mmu_rb_ops sdma_rb_ops = { |
| @@ -1063,8 +1065,10 @@ static int pin_vector_pages(struct user_sdma_request *req, · 757 unmodified lines | ||
| 1063 | 1065 | rb_node = hfi1_mmu_rb_search(&pq->sdma_rb_root, |
| 1064 | 1066 | (unsigned long)iovec->iov.iov_base, |
| 1065 | 1067 | iovec->iov.iov_len); |
| 1066 | − if (rb_node) | |
| 1068 | + if (rb_node && !IS_ERR(rb_node)) | |
| 1067 | 1069 | node = container_of(rb_node, struct sdma_mmu_node, rb); |
| 1070 | + else | |
| 1071 | + rb_node = NULL; | |
| 1068 | 1072 | |
| 1069 | 1073 | if (!node) { |
| 1070 | 1074 | node = kzalloc(sizeof(*node), GFP_KERNEL); |
| @@ -1107,7 +1111,8 @@ retry: · 36 unmodified lines | ||
| 1107 | 1111 | goto bail; |
| 1108 | 1112 | } |
| 1109 | 1113 | if (pinned != npages) { |
| 1110 | − unpin_vector_pages(current->mm, pages, pinned); | |
| 1114 | + unpin_vector_pages(current->mm, pages, node->npages, | |
| 1115 | + pinned); | |
| 1111 | 1116 | ret = -EFAULT; |
| 1112 | 1117 | goto bail; |
| 1113 | 1118 | } |
| @@ -1147,9 +1152,9 @@ bail: · 33 unmodified lines | ||
| 1147 | 1152 | } |
| 1148 | 1153 | |
| 1149 | 1154 | static void unpin_vector_pages(struct mm_struct *mm, struct page **pages, |
| 1150 | − unsigned npages) | |
| 1155 | + unsigned start, unsigned npages) | |
| 1151 | 1156 | { |
| 1152 | − hfi1_release_user_pages(mm, pages, npages, 0); | |
| 1157 | + hfi1_release_user_pages(mm, pages + start, npages, 0); | |
| 1153 | 1158 | kfree(pages); |
| 1154 | 1159 | } |
| 1155 | 1160 | |
| @@ -1502,7 +1507,7 @@ static void user_sdma_free_request(struct user_sdma_request *req, bool unpin) · 346 unmodified lines | ||
| 1502 | 1507 | &req->pq->sdma_rb_root, |
| 1503 | 1508 | (unsigned long)req->iovs[i].iov.iov_base, |
| 1504 | 1509 | req->iovs[i].iov.iov_len); |
| 1505 | − if (!mnode) | |
| 1510 | + if (!mnode || IS_ERR(mnode)) | |
| 1506 | 1511 | continue; |
| 1507 | 1512 | |
| 1508 | 1513 | node = container_of(mnode, struct sdma_mmu_node, rb); |
| @@ -1547,7 +1552,7 @@ static int sdma_rb_insert(struct rb_root *root, struct mmu_rb_node *mnode) · 38 unmodified lines | ||
| 1547 | 1552 | } |
| 1548 | 1553 | |
| 1549 | 1554 | static void sdma_rb_remove(struct rb_root *root, struct mmu_rb_node *mnode, |
| 1550 | − bool notifier) | |
| 1555 | + struct mm_struct *mm) | |
| 1551 | 1556 | { |
| 1552 | 1557 | struct sdma_mmu_node *node = |
| 1553 | 1558 | container_of(mnode, struct sdma_mmu_node, rb); |
| @@ -1557,14 +1562,20 @@ static void sdma_rb_remove(struct rb_root *root, struct mmu_rb_node *mnode, · 3 unmodified lines | ||
| 1557 | 1562 | node->pq->n_locked -= node->npages; |
| 1558 | 1563 | spin_unlock(&node->pq->evict_lock); |
| 1559 | 1564 | |
| 1560 | − unpin_vector_pages(notifier ? NULL : current->mm, node->pages, | |
| 1565 | + /* | |
| 1566 | + * If mm is set, we are being called by the MMU notifier and we | |
| 1567 | + * should not pass a mm_struct to unpin_vector_page(). This is to | |
| 1568 | + * prevent a deadlock when hfi1_release_user_pages() attempts to | |
| 1569 | + * take the mmap_sem, which the MMU notifier has already taken. | |
| 1570 | + */ | |
| 1571 | + unpin_vector_pages(mm ? NULL : current->mm, node->pages, 0, | |
| 1561 | 1572 | node->npages); |
| 1562 | 1573 | /* |
| 1563 | 1574 | * If called by the MMU notifier, we have to adjust the pinned |
| 1564 | 1575 | * page count ourselves. |
| 1565 | 1576 | */ |
| 1566 | − if (notifier) | |
| 1567 | − current->mm->pinned_vm -= node->npages; | |
| 1577 | + if (mm) | |
| 1578 | + mm->pinned_vm -= node->npages; | |
| 1568 | 1579 | kfree(node); |
| 1569 | 1580 | } |
| 1570 | 1581 | |
| @@ -68,12 +68,12 @@ static inline int _step_to_temp(int step) · 67 unmodified lines | ||
| 68 | 68 | * Every step equals (1 * 200) / 255 celsius, and finally |
| 69 | 69 | * need convert to millicelsius. |
| 70 | 70 | */ |
| 71 | − return (HISI_TEMP_BASE + (step * 200 / 255)) * 1000; | |
| 71 | + return (HISI_TEMP_BASE * 1000 + (step * 200000 / 255)); | |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | 74 | static inline long _temp_to_step(long temp) |
| 75 | 75 | { |
| 76 | − return ((temp / 1000 - HISI_TEMP_BASE) * 255 / 200); | |
| 76 | + return ((temp - HISI_TEMP_BASE * 1000) * 255) / 200000; | |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | static long hisi_thermal_get_sensor_temp(struct hisi_thermal_data *data, |
| @@ -959,7 +959,7 @@ static DEVICE_ATTR(sustainable_power, S_IWUSR | S_IRUGO, sustainable_power_show, · 958 unmodified lines | ||
| 959 | 959 | struct thermal_zone_device *tz = to_thermal_zone(dev); \ |
| 960 | 960 | \ |
| 961 | 961 | if (tz->tzp) \ |
| 962 | − return sprintf(buf, "%u\n", tz->tzp->name); \ | |
| 962 | + return sprintf(buf, "%d\n", tz->tzp->name); \ | |
| 963 | 963 | else \ |
| 964 | 964 | return -EIO; \ |
| 965 | 965 | } \ |
| @@ -626,7 +626,7 @@ static int pty_unix98_ioctl(struct tty_struct *tty, · 625 unmodified lines | ||
| 626 | 626 | */ |
| 627 | 627 | |
| 628 | 628 | static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, |
| 629 | − struct inode *ptm_inode, int idx) | |
| 629 | + struct file *file, int idx) | |
| 630 | 630 | { |
| 631 | 631 | /* Master must be open via /dev/ptmx */ |
| 632 | 632 | return ERR_PTR(-EIO); |
| @@ -642,12 +642,12 @@ static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, · 9 unmodified lines | ||
| 642 | 642 | */ |
| 643 | 643 | |
| 644 | 644 | static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, |
| 645 | − struct inode *pts_inode, int idx) | |
| 645 | + struct file *file, int idx) | |
| 646 | 646 | { |
| 647 | 647 | struct tty_struct *tty; |
| 648 | 648 | |
| 649 | 649 | mutex_lock(&devpts_mutex); |
| 650 | − tty = devpts_get_priv(pts_inode); | |
| 650 | + tty = devpts_get_priv(file->f_path.dentry); | |
| 651 | 651 | mutex_unlock(&devpts_mutex); |
| 652 | 652 | /* Master must be open before slave */ |
| 653 | 653 | if (!tty) |
| @@ -722,7 +722,7 @@ static int ptmx_open(struct inode *inode, struct file *filp) · 68 unmodified lines | ||
| 722 | 722 | { |
| 723 | 723 | struct pts_fs_info *fsi; |
| 724 | 724 | struct tty_struct *tty; |
| 725 | − struct inode *slave_inode; | |
| 725 | + struct dentry *dentry; | |
| 726 | 726 | int retval; |
| 727 | 727 | int index; |
| 728 | 728 | |
| @@ -769,14 +769,12 @@ static int ptmx_open(struct inode *inode, struct file *filp) · 40 unmodified lines | ||
| 769 | 769 | |
| 770 | 770 | tty_add_file(tty, filp); |
| 771 | 771 | |
| 772 | − slave_inode = devpts_pty_new(fsi, | |
| 773 | − MKDEV(UNIX98_PTY_SLAVE_MAJOR, index), index, | |
| 774 | − tty->link); | |
| 775 | − if (IS_ERR(slave_inode)) { | |
| 776 | − retval = PTR_ERR(slave_inode); | |
| 772 | + dentry = devpts_pty_new(fsi, index, tty->link); | |
| 773 | + if (IS_ERR(dentry)) { | |
| 774 | + retval = PTR_ERR(dentry); | |
| 777 | 775 | goto err_release; |
| 778 | 776 | } |
| 779 | − tty->link->driver_data = slave_inode; | |
| 777 | + tty->link->driver_data = dentry; | |
| 780 | 778 | |
| 781 | 779 | retval = ptm_driver->ops->open(tty, filp); |
| 782 | 780 | if (retval) |
| @@ -1367,12 +1367,12 @@ static ssize_t tty_line_name(struct tty_driver *driver, int index, char *p) · 1366 unmodified lines | ||
| 1367 | 1367 | * Locking: tty_mutex must be held. If the tty is found, bump the tty kref. |
| 1368 | 1368 | */ |
| 1369 | 1369 | static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, |
| 1370 | − struct inode *inode, int idx) | |
| 1370 | + struct file *file, int idx) | |
| 1371 | 1371 | { |
| 1372 | 1372 | struct tty_struct *tty; |
| 1373 | 1373 | |
| 1374 | 1374 | if (driver->ops->lookup) |
| 1375 | − tty = driver->ops->lookup(driver, inode, idx); | |
| 1375 | + tty = driver->ops->lookup(driver, file, idx); | |
| 1376 | 1376 | else |
| 1377 | 1377 | tty = driver->ttys[idx]; |
| 1378 | 1378 | |
| @@ -2040,7 +2040,7 @@ static struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode, · 661 unmodified lines | ||
| 2040 | 2040 | } |
| 2041 | 2041 | |
| 2042 | 2042 | /* check whether we're reopening an existing tty */ |
| 2043 | − tty = tty_driver_lookup_tty(driver, inode, index); | |
| 2043 | + tty = tty_driver_lookup_tty(driver, filp, index); | |
| 2044 | 2044 | if (IS_ERR(tty)) { |
| 2045 | 2045 | mutex_unlock(&tty_mutex); |
| 2046 | 2046 | goto out; |
| @@ -249,18 +249,12 @@ static int usb_port_runtime_suspend(struct device *dev) · 248 unmodified lines | ||
| 249 | 249 | |
| 250 | 250 | return retval; |
| 251 | 251 | } |
| 252 | − | |
| 253 | −static int usb_port_prepare(struct device *dev) | |
| 254 | −{ | |
| 255 | − return 1; | |
| 256 | −} | |
| 257 | 252 | #endif |
| 258 | 253 | |
| 259 | 254 | static const struct dev_pm_ops usb_port_pm_ops = { |
| 260 | 255 | #ifdef CONFIG_PM |
| 261 | 256 | .runtime_suspend = usb_port_runtime_suspend, |
| 262 | 257 | .runtime_resume = usb_port_runtime_resume, |
| 263 | − .prepare = usb_port_prepare, | |
| 264 | 258 | #endif |
| 265 | 259 | }; |
| 266 | 260 | |
| @@ -312,13 +312,7 @@ static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env) · 311 unmodified lines | ||
| 312 | 312 | |
| 313 | 313 | static int usb_dev_prepare(struct device *dev) |
| 314 | 314 | { |
| 315 | − struct usb_device *udev = to_usb_device(dev); | |
| 316 | − | |
| 317 | − /* Return 0 if the current wakeup setting is wrong, otherwise 1 */ | |
| 318 | − if (udev->do_remote_wakeup != device_may_wakeup(dev)) | |
| 319 | − return 0; | |
| 320 | − | |
| 321 | − return 1; | |
| 315 | + return 0; /* Implement eventually? */ | |
| 322 | 316 | } |
| 323 | 317 | |
| 324 | 318 | static void usb_dev_complete(struct device *dev) |
| @@ -83,9 +83,9 @@ static int jz4740_musb_init(struct musb *musb) · 82 unmodified lines | ||
| 83 | 83 | { |
| 84 | 84 | usb_phy_generic_register(); |
| 85 | 85 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); |
| 86 | − if (!musb->xceiv) { | |
| 86 | + if (IS_ERR(musb->xceiv)) { | |
| 87 | 87 | pr_err("HS UDC: no transceiver configured\n"); |
| 88 | − return -ENODEV; | |
| 88 | + return PTR_ERR(musb->xceiv); | |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | 91 | /* Silicon does not implement ConfigData register. |
| @@ -1164,12 +1164,12 @@ static int musb_gadget_disable(struct usb_ep *ep) · 1163 unmodified lines | ||
| 1164 | 1164 | musb_writew(epio, MUSB_RXMAXP, 0); |
| 1165 | 1165 | } |
| 1166 | 1166 | |
| 1167 | − musb_ep->desc = NULL; | |
| 1168 | − musb_ep->end_point.desc = NULL; | |
| 1169 | − | |
| 1170 | 1167 | /* abort all pending DMA and requests */ |
| 1171 | 1168 | nuke(musb_ep, -ESHUTDOWN); |
| 1172 | 1169 | |
| 1170 | + musb_ep->desc = NULL; | |
| 1171 | + musb_ep->end_point.desc = NULL; | |
| 1172 | + | |
| 1173 | 1173 | schedule_work(&musb->irq_work); |
| 1174 | 1174 | |
| 1175 | 1175 | spin_unlock_irqrestore(&(musb->lock), flags); |
| @@ -2735,7 +2735,7 @@ static const struct hc_driver musb_hc_driver = { · 2734 unmodified lines | ||
| 2735 | 2735 | .description = "musb-hcd", |
| 2736 | 2736 | .product_desc = "MUSB HDRC host driver", |
| 2737 | 2737 | .hcd_priv_size = sizeof(struct musb *), |
| 2738 | − .flags = HCD_USB2 | HCD_MEMORY | HCD_BH, | |
| 2738 | + .flags = HCD_USB2 | HCD_MEMORY, | |
| 2739 | 2739 | |
| 2740 | 2740 | /* not using irq handler or reset hooks from usbcore, since |
| 2741 | 2741 | * those must be shared with peripheral code for OTG configs |
| @@ -109,6 +109,7 @@ static const struct usb_device_id id_table[] = { · 108 unmodified lines | ||
| 109 | 109 | { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */ |
| 110 | 110 | { USB_DEVICE(0x10C4, 0x8281) }, /* Nanotec Plug & Drive */ |
| 111 | 111 | { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */ |
| 112 | + { USB_DEVICE(0x10C4, 0x82F4) }, /* Starizona MicroTouch */ | |
| 112 | 113 | { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ |
| 113 | 114 | { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ |
| 114 | 115 | { USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */ |
| @@ -118,6 +119,7 @@ static const struct usb_device_id id_table[] = { · 3 unmodified lines | ||
| 118 | 119 | { USB_DEVICE(0x10C4, 0x8418) }, /* IRZ Automation Teleport SG-10 GSM/GPRS Modem */ |
| 119 | 120 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ |
| 120 | 121 | { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */ |
| 122 | + { USB_DEVICE(0x10C4, 0x84B6) }, /* Starizona Hyperion */ | |
| 121 | 123 | { USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */ |
| 122 | 124 | { USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */ |
| 123 | 125 | { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ |
| @@ -141,6 +143,8 @@ static const struct usb_device_id id_table[] = { · 17 unmodified lines | ||
| 141 | 143 | { USB_DEVICE(0x10C4, 0xF004) }, /* Elan Digital Systems USBcount50 */ |
| 142 | 144 | { USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */ |
| 143 | 145 | { USB_DEVICE(0x10CE, 0xEA6A) }, /* Silicon Labs MobiData GPRS USB Modem 100EU */ |
| 146 | + { USB_DEVICE(0x12B8, 0xEC60) }, /* Link G4 ECU */ | |
| 147 | + { USB_DEVICE(0x12B8, 0xEC62) }, /* Link G4+ ECU */ | |
| 144 | 148 | { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ |
| 145 | 149 | { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ |
| 146 | 150 | { USB_DEVICE(0x166A, 0x0201) }, /* Clipsal 5500PACA C-Bus Pascal Automation Controller */ |
| @@ -1006,7 +1006,7 @@ struct virtqueue *vring_create_virtqueue( · 1005 unmodified lines | ||
| 1006 | 1006 | const char *name) |
| 1007 | 1007 | { |
| 1008 | 1008 | struct virtqueue *vq; |
| 1009 | − void *queue; | |
| 1009 | + void *queue = NULL; | |
| 1010 | 1010 | dma_addr_t dma_addr; |
| 1011 | 1011 | size_t queue_size_in_bytes; |
| 1012 | 1012 | struct vring vring; |
| @@ -151,6 +151,8 @@ static DECLARE_WAIT_QUEUE_HEAD(balloon_wq); · 150 unmodified lines | ||
| 151 | 151 | static void balloon_process(struct work_struct *work); |
| 152 | 152 | static DECLARE_DELAYED_WORK(balloon_worker, balloon_process); |
| 153 | 153 | |
| 154 | +static void release_memory_resource(struct resource *resource); | |
| 155 | + | |
| 154 | 156 | /* When ballooning out (allocating memory to return to Xen) we don't really |
| 155 | 157 | want the kernel to try too hard since that can trigger the oom killer. */ |
| 156 | 158 | #define GFP_BALLOON \ |
| @@ -267,6 +269,20 @@ static struct resource *additional_memory_resource(phys_addr_t size) · 110 unmodified lines | ||
| 267 | 269 | return NULL; |
| 268 | 270 | } |
| 269 | 271 | |
| 272 | +#ifdef CONFIG_SPARSEMEM | |
| 273 | + { | |
| 274 | + unsigned long limit = 1UL << (MAX_PHYSMEM_BITS - PAGE_SHIFT); | |
| 275 | + unsigned long pfn = res->start >> PAGE_SHIFT; | |
| 276 | + | |
| 277 | + if (pfn > limit) { | |
| 278 | + pr_err("New System RAM resource outside addressable RAM (%lu > %lu)\n", | |
| 279 | + pfn, limit); | |
| 280 | + release_memory_resource(res); | |
| 281 | + return NULL; | |
| 282 | + } | |
| 283 | + } | |
| 284 | +#endif | |
| 285 | + | |
| 270 | 286 | return res; |
| 271 | 287 | } |
| 272 | 288 | |
| @@ -316,7 +316,6 @@ static int evtchn_resize_ring(struct per_user_data *u) · 315 unmodified lines | ||
| 316 | 316 | { |
| 317 | 317 | unsigned int new_size; |
| 318 | 318 | evtchn_port_t *new_ring, *old_ring; |
| 319 | − unsigned int p, c; | |
| 320 | 319 | |
| 321 | 320 | /* |
| 322 | 321 | * Ensure the ring is large enough to capture all possible |
| @@ -346,20 +345,17 @@ static int evtchn_resize_ring(struct per_user_data *u) · 23 unmodified lines | ||
| 346 | 345 | /* |
| 347 | 346 | * Copy the old ring contents to the new ring. |
| 348 | 347 | * |
| 349 | − * If the ring contents crosses the end of the current ring, | |
| 350 | − * it needs to be copied in two chunks. | |
| 348 | + * To take care of wrapping, a full ring, and the new index | |
| 349 | + * pointing into the second half, simply copy the old contents | |
| 350 | + * twice. | |
| 351 | 351 | * |
| 352 | 352 | * +---------+ +------------------+ |
| 353 | − * |34567 12| -> | 1234567 | | |
| 354 | − * +-----p-c-+ +------------------+ | |
| 353 | + * |34567 12| -> |34567 1234567 12| | |
| 354 | + * +-----p-c-+ +-------c------p---+ | |
| 355 | 355 | */ |
| 356 | − p = evtchn_ring_offset(u, u->ring_prod); | |
| 357 | − c = evtchn_ring_offset(u, u->ring_cons); | |
| 358 | − if (p < c) { | |
| 359 | − memcpy(new_ring + c, u->ring + c, (u->ring_size - c) * sizeof(*u->ring)); | |
| 360 | − memcpy(new_ring + u->ring_size, u->ring, p * sizeof(*u->ring)); | |
| 361 | − } else | |
| 362 | − memcpy(new_ring + c, u->ring + c, (p - c) * sizeof(*u->ring)); | |
| 356 | + memcpy(new_ring, old_ring, u->ring_size * sizeof(*u->ring)); | |
| 357 | + memcpy(new_ring + u->ring_size, old_ring, | |
| 358 | + u->ring_size * sizeof(*u->ring)); | |
| 363 | 359 | |
| 364 | 360 | u->ring = new_ring; |
| 365 | 361 | u->ring_size = new_size; |
| @@ -386,9 +386,7 @@ void ceph_put_mds_session(struct ceph_mds_session *s) · 385 unmodified lines | ||
| 386 | 386 | atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1); |
| 387 | 387 | if (atomic_dec_and_test(&s->s_ref)) { |
| 388 | 388 | if (s->s_auth.authorizer) |
| 389 | − ceph_auth_destroy_authorizer( | |
| 390 | − s->s_mdsc->fsc->client->monc.auth, | |
| 391 | − s->s_auth.authorizer); | |
| 389 | + ceph_auth_destroy_authorizer(s->s_auth.authorizer); | |
| 392 | 390 | kfree(s); |
| 393 | 391 | } |
| 394 | 392 | } |
| @@ -3900,7 +3898,7 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, · 3505 unmodified lines | ||
| 3900 | 3898 | struct ceph_auth_handshake *auth = &s->s_auth; |
| 3901 | 3899 | |
| 3902 | 3900 | if (force_new && auth->authorizer) { |
| 3903 | − ceph_auth_destroy_authorizer(ac, auth->authorizer); | |
| 3901 | + ceph_auth_destroy_authorizer(auth->authorizer); | |
| 3904 | 3902 | auth->authorizer = NULL; |
| 3905 | 3903 | } |
| 3906 | 3904 | if (!auth->authorizer) { |
| @@ -604,8 +604,7 @@ void devpts_put_ref(struct pts_fs_info *fsi) · 603 unmodified lines | ||
| 604 | 604 | * |
| 605 | 605 | * The created inode is returned. Remove it from /dev/pts/ by devpts_pty_kill. |
| 606 | 606 | */ |
| 607 | −struct inode *devpts_pty_new(struct pts_fs_info *fsi, dev_t device, int index, | |
| 608 | − void *priv) | |
| 607 | +struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv) | |
| 609 | 608 | { |
| 610 | 609 | struct dentry *dentry; |
| 611 | 610 | struct super_block *sb; |
| @@ -629,25 +628,21 @@ struct inode *devpts_pty_new(struct pts_fs_info *fsi, dev_t device, int index, · 17 unmodified lines | ||
| 629 | 628 | inode->i_uid = opts->setuid ? opts->uid : current_fsuid(); |
| 630 | 629 | inode->i_gid = opts->setgid ? opts->gid : current_fsgid(); |
| 631 | 630 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
| 632 | − init_special_inode(inode, S_IFCHR|opts->mode, device); | |
| 633 | − inode->i_private = priv; | |
| 631 | + init_special_inode(inode, S_IFCHR|opts->mode, MKDEV(UNIX98_PTY_SLAVE_MAJOR, index)); | |
| 634 | 632 | |
| 635 | 633 | sprintf(s, "%d", index); |
| 636 | 634 | |
| 637 | − inode_lock(d_inode(root)); | |
| 638 | − | |
| 639 | 635 | dentry = d_alloc_name(root, s); |
| 640 | 636 | if (dentry) { |
| 637 | + dentry->d_fsdata = priv; | |
| 641 | 638 | d_add(dentry, inode); |
| 642 | 639 | fsnotify_create(d_inode(root), dentry); |
| 643 | 640 | } else { |
| 644 | 641 | iput(inode); |
| 645 | − inode = ERR_PTR(-ENOMEM); | |
| 642 | + dentry = ERR_PTR(-ENOMEM); | |
| 646 | 643 | } |
| 647 | 644 | |
| 648 | − inode_unlock(d_inode(root)); | |
| 649 | − | |
| 650 | − return inode; | |
| 645 | + return dentry; | |
| 651 | 646 | } |
| 652 | 647 | |
| 653 | 648 | /** |
| @@ -656,24 +651,10 @@ struct inode *devpts_pty_new(struct pts_fs_info *fsi, dev_t device, int index, · 2 unmodified lines | ||
| 656 | 651 | * |
| 657 | 652 | * Returns whatever was passed as priv in devpts_pty_new for a given inode. |
| 658 | 653 | */ |
| 659 | −void *devpts_get_priv(struct inode *pts_inode) | |
| 654 | +void *devpts_get_priv(struct dentry *dentry) | |
| 660 | 655 | { |
| 661 | − struct dentry *dentry; | |
| 662 | − void *priv = NULL; | |
| 663 | − | |
| 664 | − BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR)); | |
| 665 | − | |
| 666 | − /* Ensure dentry has not been deleted by devpts_pty_kill() */ | |
| 667 | − dentry = d_find_alias(pts_inode); | |
| 668 | − if (!dentry) | |
| 669 | − return NULL; | |
| 670 | − | |
| 671 | − if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) | |
| 672 | − priv = pts_inode->i_private; | |
| 673 | − | |
| 674 | − dput(dentry); | |
| 675 | − | |
| 676 | − return priv; | |
| 656 | + WARN_ON_ONCE(dentry->d_sb->s_magic != DEVPTS_SUPER_MAGIC); | |
| 657 | + return dentry->d_fsdata; | |
| 677 | 658 | } |
| 678 | 659 | |
| 679 | 660 | /** |
| @@ -682,24 +663,14 @@ void *devpts_get_priv(struct inode *pts_inode) · 2 unmodified lines | ||
| 682 | 663 | * |
| 683 | 664 | * This is an inverse operation of devpts_pty_new. |
| 684 | 665 | */ |
| 685 | −void devpts_pty_kill(struct inode *inode) | |
| 666 | +void devpts_pty_kill(struct dentry *dentry) | |
| 686 | 667 | { |
| 687 | − struct super_block *sb = pts_sb_from_inode(inode); | |
| 688 | − struct dentry *root = sb->s_root; | |
| 689 | − struct dentry *dentry; | |
| 668 | + WARN_ON_ONCE(dentry->d_sb->s_magic != DEVPTS_SUPER_MAGIC); | |
| 690 | 669 | |
| 691 | − BUG_ON(inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR)); | |
| 692 | − | |
| 693 | − inode_lock(d_inode(root)); | |
| 694 | − | |
| 695 | − dentry = d_find_alias(inode); | |
| 696 | − | |
| 697 | − drop_nlink(inode); | |
| 670 | + dentry->d_fsdata = NULL; | |
| 671 | + drop_nlink(dentry->d_inode); | |
| 698 | 672 | d_delete(dentry); |
| 699 | 673 | dput(dentry); /* d_alloc_name() in devpts_pty_new() */ |
| 700 | − dput(dentry); /* d_find_alias above */ | |
| 701 | − | |
| 702 | − inode_unlock(d_inode(root)); | |
| 703 | 674 | } |
| 704 | 675 | |
| 705 | 676 | static int __init init_devpts_fs(void) |
| @@ -1295,7 +1295,7 @@ static int fuse_get_user_pages(struct fuse_req *req, struct iov_iter *ii, · 1294 unmodified lines | ||
| 1295 | 1295 | |
| 1296 | 1296 | *nbytesp = nbytes; |
| 1297 | 1297 | |
| 1298 | − return ret; | |
| 1298 | + return ret < 0 ? ret : 0; | |
| 1299 | 1299 | } |
| 1300 | 1300 | |
| 1301 | 1301 | static inline int fuse_iter_npages(const struct iov_iter *ii_p) |
| @@ -2455,6 +2455,8 @@ int dlm_deref_lockres_done_handler(struct o2net_msg *msg, u32 len, void *data, · 2454 unmodified lines | ||
| 2455 | 2455 | |
| 2456 | 2456 | spin_unlock(&dlm->spinlock); |
| 2457 | 2457 | |
| 2458 | + ret = 0; | |
| 2459 | + | |
| 2458 | 2460 | done: |
| 2459 | 2461 | dlm_put(dlm); |
| 2460 | 2462 | return ret; |
| @@ -198,7 +198,7 @@ static struct mount *next_group(struct mount *m, struct mount *origin) · 197 unmodified lines | ||
| 198 | 198 | |
| 199 | 199 | /* all accesses are serialized by namespace_sem */ |
| 200 | 200 | static struct user_namespace *user_ns; |
| 201 | −static struct mount *last_dest, *last_source, *dest_master; | |
| 201 | +static struct mount *last_dest, *first_source, *last_source, *dest_master; | |
| 202 | 202 | static struct mountpoint *mp; |
| 203 | 203 | static struct hlist_head *list; |
| 204 | 204 | |
| @@ -221,20 +221,22 @@ static int propagate_one(struct mount *m) · 16 unmodified lines | ||
| 221 | 221 | type = CL_MAKE_SHARED; |
| 222 | 222 | } else { |
| 223 | 223 | struct mount *n, *p; |
| 224 | + bool done; | |
| 224 | 225 | for (n = m; ; n = p) { |
| 225 | 226 | p = n->mnt_master; |
| 226 | − if (p == dest_master || IS_MNT_MARKED(p)) { | |
| 227 | − while (last_dest->mnt_master != p) { | |
| 228 | − last_source = last_source->mnt_master; | |
| 229 | − last_dest = last_source->mnt_parent; | |
| 230 | − } | |
| 231 | − if (!peers(n, last_dest)) { | |
| 232 | − last_source = last_source->mnt_master; | |
| 233 | − last_dest = last_source->mnt_parent; | |
| 234 | − } | |
| 227 | + if (p == dest_master || IS_MNT_MARKED(p)) | |
| 235 | 228 | break; |
| 236 | − } | |
| 237 | 229 | } |
| 230 | + do { | |
| 231 | + struct mount *parent = last_source->mnt_parent; | |
| 232 | + if (last_source == first_source) | |
| 233 | + break; | |
| 234 | + done = parent->mnt_master == p; | |
| 235 | + if (done && peers(n, parent)) | |
| 236 | + break; | |
| 237 | + last_source = last_source->mnt_master; | |
| 238 | + } while (!done); | |
| 239 | + | |
| 238 | 240 | type = CL_SLAVE; |
| 239 | 241 | /* beginning of peer group among the slaves? */ |
| 240 | 242 | if (IS_MNT_SHARED(m)) |
| @@ -286,6 +288,7 @@ int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp, · 45 unmodified lines | ||
| 286 | 288 | */ |
| 287 | 289 | user_ns = current->nsproxy->mnt_ns->user_ns; |
| 288 | 290 | last_dest = dest_mnt; |
| 291 | + first_source = source_mnt; | |
| 289 | 292 | last_source = source_mnt; |
| 290 | 293 | mp = dest_mp; |
| 291 | 294 | list = tree_list; |
| @@ -955,7 +955,8 @@ static ssize_t environ_read(struct file *file, char __user *buf, · 954 unmodified lines | ||
| 955 | 955 | struct mm_struct *mm = file->private_data; |
| 956 | 956 | unsigned long env_start, env_end; |
| 957 | 957 | |
| 958 | − if (!mm) | |
| 958 | + /* Ensure the process spawned far enough to have an environment. */ | |
| 959 | + if (!mm || !mm->env_end) | |
| 959 | 960 | return 0; |
| 960 | 961 | |
| 961 | 962 | page = (char *)__get_free_page(GFP_TEMPORARY); |
| @@ -1518,6 +1518,32 @@ static struct page *can_gather_numa_stats(pte_t pte, struct vm_area_struct *vma, · 1517 unmodified lines | ||
| 1518 | 1518 | return page; |
| 1519 | 1519 | } |
| 1520 | 1520 | |
| 1521 | +#ifdef CONFIG_TRANSPARENT_HUGEPAGE | |
| 1522 | +static struct page *can_gather_numa_stats_pmd(pmd_t pmd, | |
| 1523 | + struct vm_area_struct *vma, | |
| 1524 | + unsigned long addr) | |
| 1525 | +{ | |
| 1526 | + struct page *page; | |
| 1527 | + int nid; | |
| 1528 | + | |
| 1529 | + if (!pmd_present(pmd)) | |
| 1530 | + return NULL; | |
| 1531 | + | |
| 1532 | + page = vm_normal_page_pmd(vma, addr, pmd); | |
| 1533 | + if (!page) | |
| 1534 | + return NULL; | |
| 1535 | + | |
| 1536 | + if (PageReserved(page)) | |
| 1537 | + return NULL; | |
| 1538 | + | |
| 1539 | + nid = page_to_nid(page); | |
| 1540 | + if (!node_isset(nid, node_states[N_MEMORY])) | |
| 1541 | + return NULL; | |
| 1542 | + | |
| 1543 | + return page; | |
| 1544 | +} | |
| 1545 | +#endif | |
| 1546 | + | |
| 1521 | 1547 | static int gather_pte_stats(pmd_t *pmd, unsigned long addr, |
| 1522 | 1548 | unsigned long end, struct mm_walk *walk) |
| 1523 | 1549 | { |
| @@ -1527,14 +1553,14 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr, · 3 unmodified lines | ||
| 1527 | 1553 | pte_t *orig_pte; |
| 1528 | 1554 | pte_t *pte; |
| 1529 | 1555 | |
| 1556 | +#ifdef CONFIG_TRANSPARENT_HUGEPAGE | |
| 1530 | 1557 | ptl = pmd_trans_huge_lock(pmd, vma); |
| 1531 | 1558 | if (ptl) { |
| 1532 | − pte_t huge_pte = *(pte_t *)pmd; | |
| 1533 | 1559 | struct page *page; |
| 1534 | 1560 | |
| 1535 | − page = can_gather_numa_stats(huge_pte, vma, addr); | |
| 1561 | + page = can_gather_numa_stats_pmd(*pmd, vma, addr); | |
| 1536 | 1562 | if (page) |
| 1537 | − gather_stats(page, md, pte_dirty(huge_pte), | |
| 1563 | + gather_stats(page, md, pmd_dirty(*pmd), | |
| 1538 | 1564 | HPAGE_PMD_SIZE/PAGE_SIZE); |
| 1539 | 1565 | spin_unlock(ptl); |
| 1540 | 1566 | return 0; |
| @@ -1542,6 +1568,7 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr, · 1 unmodified line | ||
| 1542 | 1568 | |
| 1543 | 1569 | if (pmd_trans_unstable(pmd)) |
| 1544 | 1570 | return 0; |
| 1571 | +#endif | |
| 1545 | 1572 | orig_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl); |
| 1546 | 1573 | do { |
| 1547 | 1574 | struct page *page = can_gather_numa_stats(*pte, vma, addr); |
| @@ -919,14 +919,14 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) · 918 unmodified lines | ||
| 919 | 919 | #endif |
| 920 | 920 | } |
| 921 | 921 | |
| 922 | − ret = udf_CS0toUTF8(outstr, 31, pvoldesc->volIdent, 32); | |
| 922 | + ret = udf_dstrCS0toUTF8(outstr, 31, pvoldesc->volIdent, 32); | |
| 923 | 923 | if (ret < 0) |
| 924 | 924 | goto out_bh; |
| 925 | 925 | |
| 926 | 926 | strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret); |
| 927 | 927 | udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident); |
| 928 | 928 | |
| 929 | − ret = udf_CS0toUTF8(outstr, 127, pvoldesc->volSetIdent, 128); | |
| 929 | + ret = udf_dstrCS0toUTF8(outstr, 127, pvoldesc->volSetIdent, 128); | |
| 930 | 930 | if (ret < 0) |
| 931 | 931 | goto out_bh; |
| 932 | 932 | |
| @@ -212,7 +212,7 @@ extern int udf_get_filename(struct super_block *, const uint8_t *, int, · 211 unmodified lines | ||
| 212 | 212 | uint8_t *, int); |
| 213 | 213 | extern int udf_put_filename(struct super_block *, const uint8_t *, int, |
| 214 | 214 | uint8_t *, int); |
| 215 | −extern int udf_CS0toUTF8(uint8_t *, int, const uint8_t *, int); | |
| 215 | +extern int udf_dstrCS0toUTF8(uint8_t *, int, const uint8_t *, int); | |
| 216 | 216 | |
| 217 | 217 | /* ialloc.c */ |
| 218 | 218 | extern void udf_free_inode(struct inode *); |
| @@ -335,9 +335,21 @@ try_again: · 334 unmodified lines | ||
| 335 | 335 | return u_len; |
| 336 | 336 | } |
| 337 | 337 | |
| 338 | −int udf_CS0toUTF8(uint8_t *utf_o, int o_len, const uint8_t *ocu_i, int i_len) | |
| 338 | +int udf_dstrCS0toUTF8(uint8_t *utf_o, int o_len, | |
| 339 | + const uint8_t *ocu_i, int i_len) | |
| 339 | 340 | { |
| 340 | − return udf_name_from_CS0(utf_o, o_len, ocu_i, i_len, | |
| 341 | + int s_len = 0; | |
| 342 | + | |
| 343 | + if (i_len > 0) { | |
| 344 | + s_len = ocu_i[i_len - 1]; | |
| 345 | + if (s_len >= i_len) { | |
| 346 | + pr_err("incorrect dstring lengths (%d/%d)\n", | |
| 347 | + s_len, i_len); | |
| 348 | + return -EINVAL; | |
| 349 | + } | |
| 350 | + } | |
| 351 | + | |
| 352 | + return udf_name_from_CS0(utf_o, o_len, ocu_i, s_len, | |
| 341 | 353 | udf_uni2char_utf8, 0); |
| 342 | 354 | } |
| 343 | 355 | |
| @@ -394,13 +394,13 @@ struct acpi_data_node { · 393 unmodified lines | ||
| 394 | 394 | |
| 395 | 395 | static inline bool is_acpi_node(struct fwnode_handle *fwnode) |
| 396 | 396 | { |
| 397 | − return fwnode && (fwnode->type == FWNODE_ACPI | |
| 397 | + return !IS_ERR_OR_NULL(fwnode) && (fwnode->type == FWNODE_ACPI | |
| 398 | 398 | || fwnode->type == FWNODE_ACPI_DATA); |
| 399 | 399 | } |
| 400 | 400 | |
| 401 | 401 | static inline bool is_acpi_device_node(struct fwnode_handle *fwnode) |
| 402 | 402 | { |
| 403 | − return fwnode && fwnode->type == FWNODE_ACPI; | |
| 403 | + return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_ACPI; | |
| 404 | 404 | } |
| 405 | 405 | |
| 406 | 406 | static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode) |
| @@ -171,12 +171,13 @@ void bpf_register_prog_type(struct bpf_prog_type_list *tl); · 170 unmodified lines | ||
| 171 | 171 | void bpf_register_map_type(struct bpf_map_type_list *tl); |
| 172 | 172 | |
| 173 | 173 | struct bpf_prog *bpf_prog_get(u32 ufd); |
| 174 | +struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog); | |
| 174 | 175 | void bpf_prog_put(struct bpf_prog *prog); |
| 175 | 176 | void bpf_prog_put_rcu(struct bpf_prog *prog); |
| 176 | 177 | |
| 177 | 178 | struct bpf_map *bpf_map_get_with_uref(u32 ufd); |
| 178 | 179 | struct bpf_map *__bpf_map_get(struct fd f); |
| 179 | −void bpf_map_inc(struct bpf_map *map, bool uref); | |
| 180 | +struct bpf_map *bpf_map_inc(struct bpf_map *map, bool uref); | |
| 180 | 181 | void bpf_map_put_with_uref(struct bpf_map *map); |
| 181 | 182 | void bpf_map_put(struct bpf_map *map); |
| 182 | 183 | int bpf_map_precharge_memlock(u32 pages); |
| @@ -12,9 +12,12 @@ · 11 unmodified lines | ||
| 12 | 12 | */ |
| 13 | 13 | |
| 14 | 14 | struct ceph_auth_client; |
| 15 | −struct ceph_authorizer; | |
| 16 | 15 | struct ceph_msg; |
| 17 | 16 | |
| 17 | +struct ceph_authorizer { | |
| 18 | + void (*destroy)(struct ceph_authorizer *); | |
| 19 | +}; | |
| 20 | + | |
| 18 | 21 | struct ceph_auth_handshake { |
| 19 | 22 | struct ceph_authorizer *authorizer; |
| 20 | 23 | void *authorizer_buf; |
| @@ -62,8 +65,6 @@ struct ceph_auth_client_ops { · 41 unmodified lines | ||
| 62 | 65 | struct ceph_auth_handshake *auth); |
| 63 | 66 | int (*verify_authorizer_reply)(struct ceph_auth_client *ac, |
| 64 | 67 | struct ceph_authorizer *a, size_t len); |
| 65 | − void (*destroy_authorizer)(struct ceph_auth_client *ac, | |
| 66 | − struct ceph_authorizer *a); | |
| 67 | 68 | void (*invalidate_authorizer)(struct ceph_auth_client *ac, |
| 68 | 69 | int peer_type); |
| 69 | 70 | |
| @@ -112,8 +113,7 @@ extern int ceph_auth_is_authenticated(struct ceph_auth_client *ac); · 42 unmodified lines | ||
| 112 | 113 | extern int ceph_auth_create_authorizer(struct ceph_auth_client *ac, |
| 113 | 114 | int peer_type, |
| 114 | 115 | struct ceph_auth_handshake *auth); |
| 115 | −extern void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac, | |
| 116 | − struct ceph_authorizer *a); | |
| 116 | +void ceph_auth_destroy_authorizer(struct ceph_authorizer *a); | |
| 117 | 117 | extern int ceph_auth_update_authorizer(struct ceph_auth_client *ac, |
| 118 | 118 | int peer_type, |
| 119 | 119 | struct ceph_auth_handshake *a); |
| @@ -16,7 +16,6 @@ struct ceph_msg; · 15 unmodified lines | ||
| 16 | 16 | struct ceph_snap_context; |
| 17 | 17 | struct ceph_osd_request; |
| 18 | 18 | struct ceph_osd_client; |
| 19 | −struct ceph_authorizer; | |
| 20 | 19 | |
| 21 | 20 | /* |
| 22 | 21 | * completion callback for async writepages |
| @@ -444,6 +444,7 @@ struct cgroup_subsys { · 443 unmodified lines | ||
| 444 | 444 | int (*can_attach)(struct cgroup_taskset *tset); |
| 445 | 445 | void (*cancel_attach)(struct cgroup_taskset *tset); |
| 446 | 446 | void (*attach)(struct cgroup_taskset *tset); |
| 447 | + void (*post_attach)(void); | |
| 447 | 448 | int (*can_fork)(struct task_struct *task); |
| 448 | 449 | void (*cancel_fork)(struct task_struct *task); |
| 449 | 450 | void (*fork)(struct task_struct *task); |
| @@ -137,8 +137,6 @@ static inline void set_mems_allowed(nodemask_t nodemask) · 136 unmodified lines | ||
| 137 | 137 | task_unlock(current); |
| 138 | 138 | } |
| 139 | 139 | |
| 140 | −extern void cpuset_post_attach_flush(void); | |
| 141 | − | |
| 142 | 140 | #else /* !CONFIG_CPUSETS */ |
| 143 | 141 | |
| 144 | 142 | static inline bool cpusets_enabled(void) { return false; } |
| @@ -245,10 +243,6 @@ static inline bool read_mems_allowed_retry(unsigned int seq) · 100 unmodified lines | ||
| 245 | 243 | return false; |
| 246 | 244 | } |
| 247 | 245 | |
| 248 | −static inline void cpuset_post_attach_flush(void) | |
| 249 | −{ | |
| 250 | −} | |
| 251 | − | |
| 252 | 246 | #endif /* !CONFIG_CPUSETS */ |
| 253 | 247 | |
| 254 | 248 | #endif /* _LINUX_CPUSET_H */ |
| @@ -27,11 +27,11 @@ int devpts_new_index(struct pts_fs_info *); · 26 unmodified lines | ||
| 27 | 27 | void devpts_kill_index(struct pts_fs_info *, int); |
| 28 | 28 | |
| 29 | 29 | /* mknod in devpts */ |
| 30 | −struct inode *devpts_pty_new(struct pts_fs_info *, dev_t, int, void *); | |
| 30 | +struct dentry *devpts_pty_new(struct pts_fs_info *, int, void *); | |
| 31 | 31 | /* get private structure */ |
| 32 | −void *devpts_get_priv(struct inode *pts_inode); | |
| 32 | +void *devpts_get_priv(struct dentry *); | |
| 33 | 33 | /* unlink */ |
| 34 | −void devpts_pty_kill(struct inode *inode); | |
| 34 | +void devpts_pty_kill(struct dentry *); | |
| 35 | 35 | |
| 36 | 36 | #endif |
| 37 | 37 | |
| @@ -32,12 +32,28 @@ · 31 unmodified lines | ||
| 32 | 32 | #error Wordsize not 32 or 64 |
| 33 | 33 | #endif |
| 34 | 34 | |
| 35 | +/* | |
| 36 | + * The above primes are actively bad for hashing, since they are | |
| 37 | + * too sparse. The 32-bit one is mostly ok, the 64-bit one causes | |
| 38 | + * real problems. Besides, the "prime" part is pointless for the | |
| 39 | + * multiplicative hash. | |
| 40 | + * | |
| 41 | + * Although a random odd number will do, it turns out that the golden | |
| 42 | + * ratio phi = (sqrt(5)-1)/2, or its negative, has particularly nice | |
| 43 | + * properties. | |
| 44 | + * | |
| 45 | + * These are the negative, (1 - phi) = (phi^2) = (3 - sqrt(5))/2. | |
| 46 | + * (See Knuth vol 3, section 6.4, exercise 9.) | |
| 47 | + */ | |
| 48 | +#define GOLDEN_RATIO_32 0x61C88647 | |
| 49 | +#define GOLDEN_RATIO_64 0x61C8864680B583EBull | |
| 50 | + | |
| 35 | 51 | static __always_inline u64 hash_64(u64 val, unsigned int bits) |
| 36 | 52 | { |
| 37 | 53 | u64 hash = val; |
| 38 | 54 | |
| 39 | −#if defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64 | |
| 40 | − hash = hash * GOLDEN_RATIO_PRIME_64; | |
| 55 | +#if BITS_PER_LONG == 64 | |
| 56 | + hash = hash * GOLDEN_RATIO_64; | |
| 41 | 57 | #else |
| 42 | 58 | /* Sigh, gcc can't optimise this alone like it does for 32 bits. */ |
| 43 | 59 | u64 n = hash; |
| @@ -152,6 +152,7 @@ static inline bool is_huge_zero_pmd(pmd_t pmd) · 151 unmodified lines | ||
| 152 | 152 | } |
| 153 | 153 | |
| 154 | 154 | struct page *get_huge_zero_page(void); |
| 155 | +void put_huge_zero_page(void); | |
| 155 | 156 | |
| 156 | 157 | #else /* CONFIG_TRANSPARENT_HUGEPAGE */ |
| 157 | 158 | #define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; }) |
| @@ -208,6 +209,10 @@ static inline bool is_huge_zero_page(struct page *page) · 50 unmodified lines | ||
| 208 | 209 | return false; |
| 209 | 210 | } |
| 210 | 211 | |
| 212 | +static inline void put_huge_zero_page(void) | |
| 213 | +{ | |
| 214 | + BUILD_BUG(); | |
| 215 | +} | |
| 211 | 216 | |
| 212 | 217 | static inline struct page *follow_devmap_pmd(struct vm_area_struct *vma, |
| 213 | 218 | unsigned long addr, pmd_t *pmd, int flags) |
| @@ -28,6 +28,11 @@ static inline struct ethhdr *eth_hdr(const struct sk_buff *skb) · 27 unmodified lines | ||
| 28 | 28 | return (struct ethhdr *)skb_mac_header(skb); |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | +static inline struct ethhdr *inner_eth_hdr(const struct sk_buff *skb) | |
| 32 | +{ | |
| 33 | + return (struct ethhdr *)skb_inner_mac_header(skb); | |
| 34 | +} | |
| 35 | + | |
| 31 | 36 | int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr); |
| 32 | 37 | |
| 33 | 38 | extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len); |
| @@ -196,9 +196,11 @@ struct lock_list { · 195 unmodified lines | ||
| 196 | 196 | * We record lock dependency chains, so that we can cache them: |
| 197 | 197 | */ |
| 198 | 198 | struct lock_chain { |
| 199 | − u8 irq_context; | |
| 200 | − u8 depth; | |
| 201 | − u16 base; | |
| 199 | + /* see BUILD_BUG_ON()s in lookup_chain_cache() */ | |
| 200 | + unsigned int irq_context : 2, | |
| 201 | + depth : 6, | |
| 202 | + base : 24; | |
| 203 | + /* 4 byte hole */ | |
| 202 | 204 | struct hlist_node entry; |
| 203 | 205 | u64 chain_key; |
| 204 | 206 | }; |
| @@ -447,5 +447,11 @@ · 446 unmodified lines | ||
| 447 | 447 | #define IMX6UL_GPR1_ENET2_CLK_OUTPUT (0x1 << 18) |
| 448 | 448 | #define IMX6UL_GPR1_ENET_CLK_DIR (0x3 << 17) |
| 449 | 449 | #define IMX6UL_GPR1_ENET_CLK_OUTPUT (0x3 << 17) |
| 450 | +#define IMX6UL_GPR1_SAI1_MCLK_DIR (0x1 << 19) | |
| 451 | +#define IMX6UL_GPR1_SAI2_MCLK_DIR (0x1 << 20) | |
| 452 | +#define IMX6UL_GPR1_SAI3_MCLK_DIR (0x1 << 21) | |
| 453 | +#define IMX6UL_GPR1_SAI_MCLK_MASK (0x7 << 19) | |
| 454 | +#define MCLK_DIR(x) (x == 1 ? IMX6UL_GPR1_SAI1_MCLK_DIR : x == 2 ? \ | |
| 455 | + IMX6UL_GPR1_SAI2_MCLK_DIR : IMX6UL_GPR1_SAI3_MCLK_DIR) | |
| 450 | 456 | |
| 451 | 457 | #endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */ |
| @@ -392,6 +392,17 @@ enum { · 391 unmodified lines | ||
| 392 | 392 | MLX5_CAP_OFF_CMDIF_CSUM = 46, |
| 393 | 393 | }; |
| 394 | 394 | |
| 395 | +enum { | |
| 396 | + /* | |
| 397 | + * Max wqe size for rdma read is 512 bytes, so this | |
| 398 | + * limits our max_sge_rd as the wqe needs to fit: | |
| 399 | + * - ctrl segment (16 bytes) | |
| 400 | + * - rdma segment (16 bytes) | |
| 401 | + * - scatter elements (16 bytes each) | |
| 402 | + */ | |
| 403 | + MLX5_MAX_SGE_RD = (512 - 16 - 16) / 16 | |
| 404 | +}; | |
| 405 | + | |
| 395 | 406 | struct mlx5_inbox_hdr { |
| 396 | 407 | __be16 opcode; |
| 397 | 408 | u8 rsvd[4]; |
| @@ -519,8 +519,9 @@ enum mlx5_device_state { · 518 unmodified lines | ||
| 519 | 519 | }; |
| 520 | 520 | |
| 521 | 521 | enum mlx5_interface_state { |
| 522 | − MLX5_INTERFACE_STATE_DOWN, | |
| 523 | − MLX5_INTERFACE_STATE_UP, | |
| 522 | + MLX5_INTERFACE_STATE_DOWN = BIT(0), | |
| 523 | + MLX5_INTERFACE_STATE_UP = BIT(1), | |
| 524 | + MLX5_INTERFACE_STATE_SHUTDOWN = BIT(2), | |
| 524 | 525 | }; |
| 525 | 526 | |
| 526 | 527 | enum mlx5_pci_status { |
| @@ -544,7 +545,7 @@ struct mlx5_core_dev { · 17 unmodified lines | ||
| 544 | 545 | enum mlx5_device_state state; |
| 545 | 546 | /* sync interface state */ |
| 546 | 547 | struct mutex intf_state_mutex; |
| 547 | − enum mlx5_interface_state interface_state; | |
| 548 | + unsigned long intf_state; | |
| 548 | 549 | void (*event) (struct mlx5_core_dev *dev, |
| 549 | 550 | enum mlx5_dev_event event, |
| 550 | 551 | unsigned long param); |
| @@ -54,9 +54,9 @@ int mlx5_set_port_admin_status(struct mlx5_core_dev *dev, · 53 unmodified lines | ||
| 54 | 54 | int mlx5_query_port_admin_status(struct mlx5_core_dev *dev, |
| 55 | 55 | enum mlx5_port_status *status); |
| 56 | 56 | |
| 57 | −int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port); | |
| 58 | −void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu, u8 port); | |
| 59 | −void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu, | |
| 57 | +int mlx5_set_port_mtu(struct mlx5_core_dev *dev, u16 mtu, u8 port); | |
| 58 | +void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, u16 *max_mtu, u8 port); | |
| 59 | +void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, u16 *oper_mtu, | |
| 60 | 60 | u8 port); |
| 61 | 61 | |
| 62 | 62 | int mlx5_query_port_vl_hw_cap(struct mlx5_core_dev *dev, |
| @@ -45,6 +45,8 @@ int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev, · 44 unmodified lines | ||
| 45 | 45 | u16 vport, u8 *addr); |
| 46 | 46 | int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *dev, |
| 47 | 47 | u16 vport, u8 *addr); |
| 48 | +int mlx5_query_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 *mtu); | |
| 49 | +int mlx5_modify_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 mtu); | |
| 48 | 50 | int mlx5_query_nic_vport_system_image_guid(struct mlx5_core_dev *mdev, |
| 49 | 51 | u64 *system_image_guid); |
| 50 | 52 | int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid); |
| @@ -1031,6 +1031,8 @@ static inline bool page_mapped(struct page *page) · 1030 unmodified lines | ||
| 1031 | 1031 | page = compound_head(page); |
| 1032 | 1032 | if (atomic_read(compound_mapcount_ptr(page)) >= 0) |
| 1033 | 1033 | return true; |
| 1034 | + if (PageHuge(page)) | |
| 1035 | + return false; | |
| 1034 | 1036 | for (i = 0; i < hpage_nr_pages(page); i++) { |
| 1035 | 1037 | if (atomic_read(&page[i]._mapcount) >= 0) |
| 1036 | 1038 | return true; |
| @@ -1138,6 +1140,8 @@ struct zap_details { · 101 unmodified lines | ||
| 1138 | 1140 | |
| 1139 | 1141 | struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, |
| 1140 | 1142 | pte_t pte); |
| 1143 | +struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr, | |
| 1144 | + pmd_t pmd); | |
| 1141 | 1145 | |
| 1142 | 1146 | int zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, |
| 1143 | 1147 | unsigned long size); |
| @@ -246,7 +246,15 @@ do { \ · 245 unmodified lines | ||
| 246 | 246 | net_ratelimited_function(pr_warn, fmt, ##__VA_ARGS__) |
| 247 | 247 | #define net_info_ratelimited(fmt, ...) \ |
| 248 | 248 | net_ratelimited_function(pr_info, fmt, ##__VA_ARGS__) |
| 249 | −#if defined(DEBUG) | |
| 249 | +#if defined(CONFIG_DYNAMIC_DEBUG) | |
| 250 | +#define net_dbg_ratelimited(fmt, ...) \ | |
| 251 | +do { \ | |
| 252 | + DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ | |
| 253 | + if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \ | |
| 254 | + net_ratelimit()) \ | |
| 255 | + __dynamic_pr_debug(&descriptor, fmt, ##__VA_ARGS__); \ | |
| 256 | +} while (0) | |
| 257 | +#elif defined(DEBUG) | |
| 250 | 258 | #define net_dbg_ratelimited(fmt, ...) \ |
| 251 | 259 | net_ratelimited_function(pr_debug, fmt, ##__VA_ARGS__) |
| 252 | 260 | #else |
| @@ -4004,7 +4004,7 @@ netdev_features_t netif_skb_features(struct sk_buff *skb); · 4003 unmodified lines | ||
| 4004 | 4004 | |
| 4005 | 4005 | static inline bool net_gso_ok(netdev_features_t features, int gso_type) |
| 4006 | 4006 | { |
| 4007 | − netdev_features_t feature = gso_type << NETIF_F_GSO_SHIFT; | |
| 4007 | + netdev_features_t feature = (netdev_features_t)gso_type << NETIF_F_GSO_SHIFT; | |
| 4008 | 4008 | |
| 4009 | 4009 | /* check flags correspondence */ |
| 4010 | 4010 | BUILD_BUG_ON(SKB_GSO_TCPV4 != (NETIF_F_TSO >> NETIF_F_GSO_SHIFT)); |
| @@ -133,7 +133,7 @@ void of_core_init(void); · 132 unmodified lines | ||
| 133 | 133 | |
| 134 | 134 | static inline bool is_of_node(struct fwnode_handle *fwnode) |
| 135 | 135 | { |
| 136 | − return fwnode && fwnode->type == FWNODE_OF; | |
| 136 | + return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_OF; | |
| 137 | 137 | } |
| 138 | 138 | |
| 139 | 139 | static inline struct device_node *to_of_node(struct fwnode_handle *fwnode) |
| @@ -516,6 +516,27 @@ static inline int PageTransCompound(struct page *page) · 515 unmodified lines | ||
| 516 | 516 | return PageCompound(page); |
| 517 | 517 | } |
| 518 | 518 | |
| 519 | +/* | |
| 520 | + * PageTransCompoundMap is the same as PageTransCompound, but it also | |
| 521 | + * guarantees the primary MMU has the entire compound page mapped | |
| 522 | + * through pmd_trans_huge, which in turn guarantees the secondary MMUs | |
| 523 | + * can also map the entire compound page. This allows the secondary | |
| 524 | + * MMUs to call get_user_pages() only once for each compound page and | |
| 525 | + * to immediately map the entire compound page with a single secondary | |
| 526 | + * MMU fault. If there will be a pmd split later, the secondary MMUs | |
| 527 | + * will get an update through the MMU notifier invalidation through | |
| 528 | + * split_huge_pmd(). | |
| 529 | + * | |
| 530 | + * Unlike PageTransCompound, this is safe to be called only while | |
| 531 | + * split_huge_pmd() cannot run from under us, like if protected by the | |
| 532 | + * MMU notifier, otherwise it may result in page->_mapcount < 0 false | |
| 533 | + * positives. | |
| 534 | + */ | |
| 535 | +static inline int PageTransCompoundMap(struct page *page) | |
| 536 | +{ | |
| 537 | + return PageTransCompound(page) && atomic_read(&page->_mapcount) < 0; | |
| 538 | +} | |
| 539 | + | |
| 519 | 540 | /* |
| 520 | 541 | * PageTransTail returns true for both transparent huge pages |
| 521 | 542 | * and hugetlbfs pages, so it should only be called when it's known |
| @@ -559,6 +580,7 @@ static inline int TestClearPageDoubleMap(struct page *page) · 37 unmodified lines | ||
| 559 | 580 | #else |
| 560 | 581 | TESTPAGEFLAG_FALSE(TransHuge) |
| 561 | 582 | TESTPAGEFLAG_FALSE(TransCompound) |
| 583 | +TESTPAGEFLAG_FALSE(TransCompoundMap) | |
| 562 | 584 | TESTPAGEFLAG_FALSE(TransTail) |
| 563 | 585 | TESTPAGEFLAG_FALSE(DoubleMap) |
| 564 | 586 | TESTSETFLAG_FALSE(DoubleMap) |
| @@ -533,6 +533,10 @@ static inline swp_entry_t get_swap_page(void) · 532 unmodified lines | ||
| 533 | 533 | #ifdef CONFIG_MEMCG |
| 534 | 534 | static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg) |
| 535 | 535 | { |
| 536 | + /* Cgroup2 doesn't have per-cgroup swappiness */ | |
| 537 | + if (cgroup_subsys_on_dfl(memory_cgrp_subsys)) | |
| 538 | + return vm_swappiness; | |
| 539 | + | |
| 536 | 540 | /* root ? */ |
| 537 | 541 | if (mem_cgroup_disabled() || !memcg->css.parent) |
| 538 | 542 | return vm_swappiness; |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | * defined; unless noted otherwise, they are optional, and can be |
| 8 | 8 | * filled in with a null pointer. |
| 9 | 9 | * |
| 10 | − * struct tty_struct * (*lookup)(struct tty_driver *self, int idx) | |
| 10 | + * struct tty_struct * (*lookup)(struct tty_driver *self, struct file *, int idx) | |
| 11 | 11 | * |
| 12 | 12 | * Return the tty device corresponding to idx, NULL if there is not |
| 13 | 13 | * one currently in use and an ERR_PTR value on error. Called under |
| @@ -250,7 +250,7 @@ struct serial_icounter_struct; · 236 unmodified lines | ||
| 250 | 250 | |
| 251 | 251 | struct tty_operations { |
| 252 | 252 | struct tty_struct * (*lookup)(struct tty_driver *driver, |
| 253 | − struct inode *inode, int idx); | |
| 253 | + struct file *filp, int idx); | |
| 254 | 254 | int (*install)(struct tty_driver *driver, struct tty_struct *tty); |
| 255 | 255 | void (*remove)(struct tty_driver *driver, struct tty_struct *tty); |
| 256 | 256 | int (*open)(struct tty_struct * tty, struct file * filp); |
| @@ -375,6 +375,9 @@ struct vb2_ops { · 374 unmodified lines | ||
| 375 | 375 | /** |
| 376 | 376 | * struct vb2_ops - driver-specific callbacks |
| 377 | 377 | * |
| 378 | + * @verify_planes_array: Verify that a given user space structure contains | |
| 379 | + * enough planes for the buffer. This is called | |
| 380 | + * for each dequeued buffer. | |
| 378 | 381 | * @fill_user_buffer: given a vb2_buffer fill in the userspace structure. |
| 379 | 382 | * For V4L2 this is a struct v4l2_buffer. |
| 380 | 383 | * @fill_vb2_buffer: given a userspace structure, fill in the vb2_buffer. |
| @@ -384,6 +387,7 @@ struct vb2_ops { · 3 unmodified lines | ||
| 384 | 387 | * the vb2_buffer struct. |
| 385 | 388 | */ |
| 386 | 389 | struct vb2_buf_ops { |
| 390 | + int (*verify_planes_array)(struct vb2_buffer *vb, const void *pb); | |
| 387 | 391 | void (*fill_user_buffer)(struct vb2_buffer *vb, void *pb); |
| 388 | 392 | int (*fill_vb2_buffer)(struct vb2_buffer *vb, const void *pb, |
| 389 | 393 | struct vb2_plane *planes); |
| @@ -400,6 +404,9 @@ struct vb2_buf_ops { · 10 unmodified lines | ||
| 400 | 404 | * @fileio_read_once: report EOF after reading the first buffer |
| 401 | 405 | * @fileio_write_immediately: queue buffer after each write() call |
| 402 | 406 | * @allow_zero_bytesused: allow bytesused == 0 to be passed to the driver |
| 407 | + * @quirk_poll_must_check_waiting_for_buffers: Return POLLERR at poll when QBUF | |
| 408 | + * has not been called. This is a vb1 idiom that has been adopted | |
| 409 | + * also by vb2. | |
| 403 | 410 | * @lock: pointer to a mutex that protects the vb2_queue struct. The |
| 404 | 411 | * driver can set this to a mutex to let the v4l2 core serialize |
| 405 | 412 | * the queuing ioctls. If the driver wants to handle locking |
| @@ -463,6 +470,7 @@ struct vb2_queue { · 57 unmodified lines | ||
| 463 | 470 | unsigned fileio_read_once:1; |
| 464 | 471 | unsigned fileio_write_immediately:1; |
| 465 | 472 | unsigned allow_zero_bytesused:1; |
| 473 | + unsigned quirk_poll_must_check_waiting_for_buffers:1; | |
| 466 | 474 | |
| 467 | 475 | struct mutex *lock; |
| 468 | 476 | void *owner; |
| @@ -54,6 +54,8 @@ struct switchdev_attr { · 53 unmodified lines | ||
| 54 | 54 | struct net_device *orig_dev; |
| 55 | 55 | enum switchdev_attr_id id; |
| 56 | 56 | u32 flags; |
| 57 | + void *complete_priv; | |
| 58 | + void (*complete)(struct net_device *dev, int err, void *priv); | |
| 57 | 59 | union { |
| 58 | 60 | struct netdev_phys_item_id ppid; /* PORT_PARENT_ID */ |
| 59 | 61 | u8 stp_state; /* PORT_STP_STATE */ |
| @@ -75,6 +77,8 @@ struct switchdev_obj { · 15 unmodified lines | ||
| 75 | 77 | struct net_device *orig_dev; |
| 76 | 78 | enum switchdev_obj_id id; |
| 77 | 79 | u32 flags; |
| 80 | + void *complete_priv; | |
| 81 | + void (*complete)(struct net_device *dev, int err, void *priv); | |
| 78 | 82 | }; |
| 79 | 83 | |
| 80 | 84 | /* SWITCHDEV_OBJ_ID_PORT_VLAN */ |
| @@ -252,7 +252,9 @@ static inline netdev_features_t vxlan_features_check(struct sk_buff *skb, · 251 unmodified lines | ||
| 252 | 252 | (skb->inner_protocol_type != ENCAP_TYPE_ETHER || |
| 253 | 253 | skb->inner_protocol != htons(ETH_P_TEB) || |
| 254 | 254 | (skb_inner_mac_header(skb) - skb_transport_header(skb) != |
| 255 | − sizeof(struct udphdr) + sizeof(struct vxlanhdr)))) | |
| 255 | + sizeof(struct udphdr) + sizeof(struct vxlanhdr)) || | |
| 256 | + (skb->ip_summed != CHECKSUM_NONE && | |
| 257 | + !can_checksum_protocol(features, inner_eth_hdr(skb)->h_proto)))) | |
| 256 | 258 | return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); |
| 257 | 259 | |
| 258 | 260 | return features; |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | #define _RDMA_IB_H |
| 35 | 35 | |
| 36 | 36 | #include <linux/types.h> |
| 37 | +#include <linux/sched.h> | |
| 37 | 38 | |
| 38 | 39 | struct ib_addr { |
| 39 | 40 | union { |
| @@ -86,4 +87,19 @@ struct sockaddr_ib { · 46 unmodified lines | ||
| 86 | 87 | __u64 sib_scope_id; |
| 87 | 88 | }; |
| 88 | 89 | |
| 90 | +/* | |
| 91 | + * The IB interfaces that use write() as bi-directional ioctl() are | |
| 92 | + * fundamentally unsafe, since there are lots of ways to trigger "write()" | |
| 93 | + * calls from various contexts with elevated privileges. That includes the | |
| 94 | + * traditional suid executable error message writes, but also various kernel | |
| 95 | + * interfaces that can write to file descriptors. | |
| 96 | + * | |
| 97 | + * This function provides protection for the legacy API by restricting the | |
| 98 | + * calling context. | |
| 99 | + */ | |
| 100 | +static inline bool ib_safe_file_access(struct file *filp) | |
| 101 | +{ | |
| 102 | + return filp->f_cred == current_cred() && segment_eq(get_fs(), USER_DS); | |
| 103 | +} | |
| 104 | + | |
| 89 | 105 | #endif /* _RDMA_IB_H */ |
| @@ -51,6 +51,16 @@ struct dma_chan *snd_dmaengine_pcm_request_channel(dma_filter_fn filter_fn, · 50 unmodified lines | ||
| 51 | 51 | void *filter_data); |
| 52 | 52 | struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream); |
| 53 | 53 | |
| 54 | +/* | |
| 55 | + * The DAI supports packed transfers, eg 2 16-bit samples in a 32-bit word. | |
| 56 | + * If this flag is set the dmaengine driver won't put any restriction on | |
| 57 | + * the supported sample formats and set the DMA transfer size to undefined. | |
| 58 | + * The DAI driver is responsible to disable any unsupported formats in it's | |
| 59 | + * configuration and catch corner cases that are not already handled in | |
| 60 | + * the ALSA core. | |
| 61 | + */ | |
| 62 | +#define SND_DMAENGINE_PCM_DAI_FLAG_PACK BIT(0) | |
| 63 | + | |
| 54 | 64 | /** |
| 55 | 65 | * struct snd_dmaengine_dai_dma_data - DAI DMA configuration data |
| 56 | 66 | * @addr: Address of the DAI data source or destination register. |
| @@ -63,6 +73,7 @@ struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream) · 6 unmodified lines | ||
| 63 | 73 | * requesting the DMA channel. |
| 64 | 74 | * @chan_name: Custom channel name to use when requesting DMA channel. |
| 65 | 75 | * @fifo_size: FIFO size of the DAI controller in bytes |
| 76 | + * @flags: PCM_DAI flags, only SND_DMAENGINE_PCM_DAI_FLAG_PACK for now | |
| 66 | 77 | */ |
| 67 | 78 | struct snd_dmaengine_dai_dma_data { |
| 68 | 79 | dma_addr_t addr; |
| @@ -72,6 +83,7 @@ struct snd_dmaengine_dai_dma_data { · 3 unmodified lines | ||
| 72 | 83 | void *filter_data; |
| 73 | 84 | const char *chan_name; |
| 74 | 85 | unsigned int fifo_size; |
| 86 | + unsigned int flags; | |
| 75 | 87 | }; |
| 76 | 88 | |
| 77 | 89 | void snd_dmaengine_pcm_set_config_from_dai_data( |
| @@ -14,6 +14,8 @@ · 13 unmodified lines | ||
| 14 | 14 | * @gtscap: gts capabilities pointer |
| 15 | 15 | * @drsmcap: dma resume capabilities pointer |
| 16 | 16 | * @hlink_list: link list of HDA links |
| 17 | + * @lock: lock for link mgmt | |
| 18 | + * @cmd_dma_state: state of cmd DMAs: CORB and RIRB | |
| 17 | 19 | */ |
| 18 | 20 | struct hdac_ext_bus { |
| 19 | 21 | struct hdac_bus bus; |
| @@ -27,6 +29,9 @@ struct hdac_ext_bus { · 7 unmodified lines | ||
| 27 | 29 | void __iomem *drsmcap; |
| 28 | 30 | |
| 29 | 31 | struct list_head hlink_list; |
| 32 | + | |
| 33 | + struct mutex lock; | |
| 34 | + bool cmd_dma_state; | |
| 30 | 35 | }; |
| 31 | 36 | |
| 32 | 37 | int snd_hdac_ext_bus_init(struct hdac_ext_bus *sbus, struct device *dev, |
| @@ -142,6 +147,9 @@ struct hdac_ext_link { · 109 unmodified lines | ||
| 142 | 147 | void __iomem *ml_addr; /* link output stream reg pointer */ |
| 143 | 148 | u32 lcaps; /* link capablities */ |
| 144 | 149 | u16 lsdiid; /* link sdi identifier */ |
| 150 | + | |
| 151 | + int ref_count; | |
| 152 | + | |
| 145 | 153 | struct list_head list; |
| 146 | 154 | }; |
| 147 | 155 | |
| @@ -154,6 +162,11 @@ void snd_hdac_ext_link_set_stream_id(struct hdac_ext_link *link, · 6 unmodified lines | ||
| 154 | 162 | void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link, |
| 155 | 163 | int stream); |
| 156 | 164 | |
| 165 | +int snd_hdac_ext_bus_link_get(struct hdac_ext_bus *ebus, | |
| 166 | + struct hdac_ext_link *link); | |
| 167 | +int snd_hdac_ext_bus_link_put(struct hdac_ext_bus *ebus, | |
| 168 | + struct hdac_ext_link *link); | |
| 169 | + | |
| 157 | 170 | /* update register macro */ |
| 158 | 171 | #define snd_hdac_updatel(addr, reg, mask, val) \ |
| 159 | 172 | writel(((readl(addr + reg) & ~(mask)) | (val)), \ |
| @@ -0,0 +1,100 @@ | ||
| 1 | +/* | |
| 2 | + * hdmi-codec.h - HDMI Codec driver API | |
| 3 | + * | |
| 4 | + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com | |
| 5 | + * | |
| 6 | + * Author: Jyri Sarha <jsarha@ti.com> | |
| 7 | + * | |
| 8 | + * This program is free software; you can redistribute it and/or | |
| 9 | + * modify it under the terms of the GNU General Public License | |
| 10 | + * version 2 as published by the Free Software Foundation. | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, but | |
| 13 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 | + * General Public License for more details. | |
| 16 | + */ | |
| 17 | + | |
| 18 | +#ifndef __HDMI_CODEC_H__ | |
| 19 | +#define __HDMI_CODEC_H__ | |
| 20 | + | |
| 21 | +#include <linux/hdmi.h> | |
| 22 | +#include <drm/drm_edid.h> | |
| 23 | +#include <sound/asoundef.h> | |
| 24 | +#include <uapi/sound/asound.h> | |
| 25 | + | |
| 26 | +/* | |
| 27 | + * Protocol between ASoC cpu-dai and HDMI-encoder | |
| 28 | + */ | |
| 29 | +struct hdmi_codec_daifmt { | |
| 30 | + enum { | |
| 31 | + HDMI_I2S, | |
| 32 | + HDMI_RIGHT_J, | |
| 33 | + HDMI_LEFT_J, | |
| 34 | + HDMI_DSP_A, | |
| 35 | + HDMI_DSP_B, | |
| 36 | + HDMI_AC97, | |
| 37 | + HDMI_SPDIF, | |
| 38 | + } fmt; | |
| 39 | + int bit_clk_inv:1; | |
| 40 | + int frame_clk_inv:1; | |
| 41 | + int bit_clk_master:1; | |
| 42 | + int frame_clk_master:1; | |
| 43 | +}; | |
| 44 | + | |
| 45 | +/* | |
| 46 | + * HDMI audio parameters | |
| 47 | + */ | |
| 48 | +struct hdmi_codec_params { | |
| 49 | + struct hdmi_audio_infoframe cea; | |
| 50 | + struct snd_aes_iec958 iec; | |
| 51 | + int sample_rate; | |
| 52 | + int sample_width; | |
| 53 | + int channels; | |
| 54 | +}; | |
| 55 | + | |
| 56 | +struct hdmi_codec_ops { | |
| 57 | + /* | |
| 58 | + * Called when ASoC starts an audio stream setup. | |
| 59 | + * Optional | |
| 60 | + */ | |
| 61 | + int (*audio_startup)(struct device *dev); | |
| 62 | + | |
| 63 | + /* | |
| 64 | + * Configures HDMI-encoder for audio stream. | |
| 65 | + * Mandatory | |
| 66 | + */ | |
| 67 | + int (*hw_params)(struct device *dev, | |
| 68 | + struct hdmi_codec_daifmt *fmt, | |
| 69 | + struct hdmi_codec_params *hparms); | |
| 70 | + | |
| 71 | + /* | |
| 72 | + * Shuts down the audio stream. | |
| 73 | + * Mandatory | |
| 74 | + */ | |
| 75 | + void (*audio_shutdown)(struct device *dev); | |
| 76 | + | |
| 77 | + /* | |
| 78 | + * Mute/unmute HDMI audio stream. | |
| 79 | + * Optional | |
| 80 | + */ | |
| 81 | + int (*digital_mute)(struct device *dev, bool enable); | |
| 82 | + | |
| 83 | + /* | |
| 84 | + * Provides EDID-Like-Data from connected HDMI device. | |
| 85 | + * Optional | |
| 86 | + */ | |
| 87 | + int (*get_eld)(struct device *dev, uint8_t *buf, size_t len); | |
| 88 | +}; | |
| 89 | + | |
| 90 | +/* HDMI codec initalization data */ | |
| 91 | +struct hdmi_codec_pdata { | |
| 92 | + const struct hdmi_codec_ops *ops; | |
| 93 | + uint i2s:1; | |
| 94 | + uint spdif:1; | |
| 95 | + int max_i2s_channels; | |
| 96 | +}; | |
| 97 | + | |
| 98 | +#define HDMI_CODEC_DRV_NAME "hdmi-audio-codec" | |
| 99 | + | |
| 100 | +#endif /* __HDMI_CODEC_H__ */ | |
| @@ -6,4 +6,6 @@ · 5 unmodified lines | ||
| 6 | 6 | int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs, |
| 7 | 7 | size_t len); |
| 8 | 8 | |
| 9 | +int snd_pcm_create_iec958_consumer_hw_params(struct snd_pcm_hw_params *params, | |
| 10 | + u8 *cs, size_t len); | |
| 9 | 11 | #endif |
| @@ -100,6 +100,7 @@ struct device; · 99 unmodified lines | ||
| 100 | 100 | { .id = snd_soc_dapm_mixer_named_ctl, .name = wname, \ |
| 101 | 101 | SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \ |
| 102 | 102 | .kcontrol_news = wcontrols, .num_kcontrols = wncontrols} |
| 103 | +/* DEPRECATED: use SND_SOC_DAPM_SUPPLY */ | |
| 103 | 104 | #define SND_SOC_DAPM_MICBIAS(wname, wreg, wshift, winvert) \ |
| 104 | 105 | { .id = snd_soc_dapm_micbias, .name = wname, \ |
| 105 | 106 | SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \ |
| @@ -473,7 +474,7 @@ enum snd_soc_dapm_type { · 367 unmodified lines | ||
| 473 | 474 | snd_soc_dapm_out_drv, /* output driver */ |
| 474 | 475 | snd_soc_dapm_adc, /* analog to digital converter */ |
| 475 | 476 | snd_soc_dapm_dac, /* digital to analog converter */ |
| 476 | − snd_soc_dapm_micbias, /* microphone bias (power) */ | |
| 477 | + snd_soc_dapm_micbias, /* microphone bias (power) - DEPRECATED: use snd_soc_dapm_supply */ | |
| 477 | 478 | snd_soc_dapm_mic, /* microphone */ |
| 478 | 479 | snd_soc_dapm_hp, /* headphones */ |
| 479 | 480 | snd_soc_dapm_spk, /* speaker */ |
| @@ -1002,7 +1002,7 @@ struct snd_soc_dai_link { · 1001 unmodified lines | ||
| 1002 | 1002 | */ |
| 1003 | 1003 | const char *platform_name; |
| 1004 | 1004 | struct device_node *platform_of_node; |
| 1005 | − int be_id; /* optional ID for machine driver BE identification */ | |
| 1005 | + int id; /* optional ID for machine driver link identification */ | |
| 1006 | 1006 | |
| 1007 | 1007 | const struct snd_soc_pcm_stream *params; |
| 1008 | 1008 | unsigned int num_params; |
| @@ -1683,6 +1683,9 @@ void snd_soc_remove_dai_link(struct snd_soc_card *card, · 674 unmodified lines | ||
| 1683 | 1683 | int snd_soc_register_dai(struct snd_soc_component *component, |
| 1684 | 1684 | struct snd_soc_dai_driver *dai_drv); |
| 1685 | 1685 | |
| 1686 | +struct snd_soc_dai *snd_soc_find_dai( | |
| 1687 | + const struct snd_soc_dai_link_component *dlc); | |
| 1688 | + | |
| 1686 | 1689 | #include <sound/soc-dai.h> |
| 1687 | 1690 | |
| 1688 | 1691 | #ifdef CONFIG_DEBUG_FS |
| @@ -718,9 +718,9 @@ __SYSCALL(__NR_mlock2, sys_mlock2) · 717 unmodified lines | ||
| 718 | 718 | #define __NR_copy_file_range 285 |
| 719 | 719 | __SYSCALL(__NR_copy_file_range, sys_copy_file_range) |
| 720 | 720 | #define __NR_preadv2 286 |
| 721 | −__SYSCALL(__NR_preadv2, sys_preadv2) | |
| 721 | +__SC_COMP(__NR_preadv2, sys_preadv2, compat_sys_preadv2) | |
| 722 | 722 | #define __NR_pwritev2 287 |
| 723 | −__SYSCALL(__NR_pwritev2, sys_pwritev2) | |
| 723 | +__SC_COMP(__NR_pwritev2, sys_pwritev2, compat_sys_pwritev2) | |
| 724 | 724 | |
| 725 | 725 | #undef __NR_syscalls |
| 726 | 726 | #define __NR_syscalls 288 |
| @@ -19,8 +19,8 @@ · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | #define MACSEC_MAX_KEY_LEN 128 |
| 21 | 21 | |
| 22 | −#define DEFAULT_CIPHER_ID 0x0080020001000001ULL | |
| 23 | −#define DEFAULT_CIPHER_ALT 0x0080C20001000001ULL | |
| 22 | +#define MACSEC_DEFAULT_CIPHER_ID 0x0080020001000001ULL | |
| 23 | +#define MACSEC_DEFAULT_CIPHER_ALT 0x0080C20001000001ULL | |
| 24 | 24 | |
| 25 | 25 | #define MACSEC_MIN_ICV_LEN 8 |
| 26 | 26 | #define MACSEC_MAX_ICV_LEN 32 |
| @@ -39,16 +39,16 @@ · 38 unmodified lines | ||
| 39 | 39 | #ifndef _RIO_MPORT_CDEV_H_ |
| 40 | 40 | #define _RIO_MPORT_CDEV_H_ |
| 41 | 41 | |
| 42 | −#ifndef __user | |
| 43 | −#define __user | |
| 44 | −#endif | |
| 42 | +#include <linux/ioctl.h> | |
| 43 | +#include <linux/types.h> | |
| 45 | 44 | |
| 46 | 45 | struct rio_mport_maint_io { |
| 47 | − uint32_t rioid; /* destID of remote device */ | |
| 48 | − uint32_t hopcount; /* hopcount to remote device */ | |
| 49 | − uint32_t offset; /* offset in register space */ | |
| 50 | − size_t length; /* length in bytes */ | |
| 51 | − void __user *buffer; /* data buffer */ | |
| 46 | + __u16 rioid; /* destID of remote device */ | |
| 47 | + __u8 hopcount; /* hopcount to remote device */ | |
| 48 | + __u8 pad0[5]; | |
| 49 | + __u32 offset; /* offset in register space */ | |
| 50 | + __u32 length; /* length in bytes */ | |
| 51 | + __u64 buffer; /* pointer to data buffer */ | |
| 52 | 52 | }; |
| 53 | 53 | |
| 54 | 54 | /* |
| @@ -66,22 +66,23 @@ struct rio_mport_maint_io { · 11 unmodified lines | ||
| 66 | 66 | #define RIO_CAP_MAP_INB (1 << 7) |
| 67 | 67 | |
| 68 | 68 | struct rio_mport_properties { |
| 69 | − uint16_t hdid; | |
| 70 | − uint8_t id; /* Physical port ID */ | |
| 71 | − uint8_t index; | |
| 72 | − uint32_t flags; | |
| 73 | − uint32_t sys_size; /* Default addressing size */ | |
| 74 | − uint8_t port_ok; | |
| 75 | − uint8_t link_speed; | |
| 76 | − uint8_t link_width; | |
| 77 | − uint32_t dma_max_sge; | |
| 78 | − uint32_t dma_max_size; | |
| 79 | − uint32_t dma_align; | |
| 80 | − uint32_t transfer_mode; /* Default transfer mode */ | |
| 81 | − uint32_t cap_sys_size; /* Capable system sizes */ | |
| 82 | − uint32_t cap_addr_size; /* Capable addressing sizes */ | |
| 83 | − uint32_t cap_transfer_mode; /* Capable transfer modes */ | |
| 84 | − uint32_t cap_mport; /* Mport capabilities */ | |
| 69 | + __u16 hdid; | |
| 70 | + __u8 id; /* Physical port ID */ | |
| 71 | + __u8 index; | |
| 72 | + __u32 flags; | |
| 73 | + __u32 sys_size; /* Default addressing size */ | |
| 74 | + __u8 port_ok; | |
| 75 | + __u8 link_speed; | |
| 76 | + __u8 link_width; | |
| 77 | + __u8 pad0; | |
| 78 | + __u32 dma_max_sge; | |
| 79 | + __u32 dma_max_size; | |
| 80 | + __u32 dma_align; | |
| 81 | + __u32 transfer_mode; /* Default transfer mode */ | |
| 82 | + __u32 cap_sys_size; /* Capable system sizes */ | |
| 83 | + __u32 cap_addr_size; /* Capable addressing sizes */ | |
| 84 | + __u32 cap_transfer_mode; /* Capable transfer modes */ | |
| 85 | + __u32 cap_mport; /* Mport capabilities */ | |
| 85 | 86 | }; |
| 86 | 87 | |
| 87 | 88 | /* |
| @@ -93,54 +94,57 @@ struct rio_mport_properties { · 5 unmodified lines | ||
| 93 | 94 | #define RIO_PORTWRITE (1 << 1) |
| 94 | 95 | |
| 95 | 96 | struct rio_doorbell { |
| 96 | − uint32_t rioid; | |
| 97 | − uint16_t payload; | |
| 97 | + __u16 rioid; | |
| 98 | + __u16 payload; | |
| 98 | 99 | }; |
| 99 | 100 | |
| 100 | 101 | struct rio_doorbell_filter { |
| 101 | − uint32_t rioid; /* 0xffffffff to match all ids */ | |
| 102 | − uint16_t low; | |
| 103 | − uint16_t high; | |
| 102 | + __u16 rioid; /* Use RIO_INVALID_DESTID to match all ids */ | |
| 103 | + __u16 low; | |
| 104 | + __u16 high; | |
| 105 | + __u16 pad0; | |
| 104 | 106 | }; |
| 105 | 107 | |
| 106 | 108 | |
| 107 | 109 | struct rio_portwrite { |
| 108 | − uint32_t payload[16]; | |
| 110 | + __u32 payload[16]; | |
| 109 | 111 | }; |
| 110 | 112 | |
| 111 | 113 | struct rio_pw_filter { |
| 112 | − uint32_t mask; | |
| 113 | − uint32_t low; | |
| 114 | − uint32_t high; | |
| 114 | + __u32 mask; | |
| 115 | + __u32 low; | |
| 116 | + __u32 high; | |
| 117 | + __u32 pad0; | |
| 115 | 118 | }; |
| 116 | 119 | |
| 117 | 120 | /* RapidIO base address for inbound requests set to value defined below |
| 118 | 121 | * indicates that no specific RIO-to-local address translation is requested |
| 119 | 122 | * and driver should use direct (one-to-one) address mapping. |
| 120 | 123 | */ |
| 121 | −#define RIO_MAP_ANY_ADDR (uint64_t)(~((uint64_t) 0)) | |
| 124 | +#define RIO_MAP_ANY_ADDR (__u64)(~((__u64) 0)) | |
| 122 | 125 | |
| 123 | 126 | struct rio_mmap { |
| 124 | − uint32_t rioid; | |
| 125 | − uint64_t rio_addr; | |
| 126 | − uint64_t length; | |
| 127 | − uint64_t handle; | |
| 128 | − void *address; | |
| 127 | + __u16 rioid; | |
| 128 | + __u16 pad0[3]; | |
| 129 | + __u64 rio_addr; | |
| 130 | + __u64 length; | |
| 131 | + __u64 handle; | |
| 132 | + __u64 address; | |
| 129 | 133 | }; |
| 130 | 134 | |
| 131 | 135 | struct rio_dma_mem { |
| 132 | − uint64_t length; /* length of DMA memory */ | |
| 133 | − uint64_t dma_handle; /* handle associated with this memory */ | |
| 134 | − void *buffer; /* pointer to this memory */ | |
| 136 | + __u64 length; /* length of DMA memory */ | |
| 137 | + __u64 dma_handle; /* handle associated with this memory */ | |
| 138 | + __u64 address; | |
| 135 | 139 | }; |
| 136 | 140 | |
| 137 | − | |
| 138 | 141 | struct rio_event { |
| 139 | − unsigned int header; /* event type RIO_DOORBELL or RIO_PORTWRITE */ | |
| 142 | + __u32 header; /* event type RIO_DOORBELL or RIO_PORTWRITE */ | |
| 140 | 143 | union { |
| 141 | 144 | struct rio_doorbell doorbell; /* header for RIO_DOORBELL */ |
| 142 | 145 | struct rio_portwrite portwrite; /* header for RIO_PORTWRITE */ |
| 143 | 146 | } u; |
| 147 | + __u32 pad0; | |
| 144 | 148 | }; |
| 145 | 149 | |
| 146 | 150 | enum rio_transfer_sync { |
| @@ -184,35 +188,37 @@ enum rio_exchange { · 37 unmodified lines | ||
| 184 | 188 | }; |
| 185 | 189 | |
| 186 | 190 | struct rio_transfer_io { |
| 187 | − uint32_t rioid; /* Target destID */ | |
| 188 | − uint64_t rio_addr; /* Address in target's RIO mem space */ | |
| 189 | − enum rio_exchange method; /* Data exchange method */ | |
| 190 | − void __user *loc_addr; | |
| 191 | − uint64_t handle; | |
| 192 | − uint64_t offset; /* Offset in buffer */ | |
| 193 | − uint64_t length; /* Length in bytes */ | |
| 194 | − uint32_t completion_code; /* Completion code for this transfer */ | |
| 191 | + __u64 rio_addr; /* Address in target's RIO mem space */ | |
| 192 | + __u64 loc_addr; | |
| 193 | + __u64 handle; | |
| 194 | + __u64 offset; /* Offset in buffer */ | |
| 195 | + __u64 length; /* Length in bytes */ | |
| 196 | + __u16 rioid; /* Target destID */ | |
| 197 | + __u16 method; /* Data exchange method, one of rio_exchange enum */ | |
| 198 | + __u32 completion_code; /* Completion code for this transfer */ | |
| 195 | 199 | }; |
| 196 | 200 | |
| 197 | 201 | struct rio_transaction { |
| 198 | − uint32_t transfer_mode; /* Data transfer mode */ | |
| 199 | − enum rio_transfer_sync sync; /* Synchronization method */ | |
| 200 | − enum rio_transfer_dir dir; /* Transfer direction */ | |
| 201 | − size_t count; /* Number of transfers */ | |
| 202 | − struct rio_transfer_io __user *block; /* Array of <count> transfers */ | |
| 202 | + __u64 block; /* Pointer to array of <count> transfers */ | |
| 203 | + __u32 count; /* Number of transfers */ | |
| 204 | + __u32 transfer_mode; /* Data transfer mode */ | |
| 205 | + __u16 sync; /* Synch method, one of rio_transfer_sync enum */ | |
| 206 | + __u16 dir; /* Transfer direction, one of rio_transfer_dir enum */ | |
| 207 | + __u32 pad0; | |
| 203 | 208 | }; |
| 204 | 209 | |
| 205 | 210 | struct rio_async_tx_wait { |
| 206 | − uint32_t token; /* DMA transaction ID token */ | |
| 207 | − uint32_t timeout; /* Wait timeout in msec, if 0 use default TO */ | |
| 211 | + __u32 token; /* DMA transaction ID token */ | |
| 212 | + __u32 timeout; /* Wait timeout in msec, if 0 use default TO */ | |
| 208 | 213 | }; |
| 209 | 214 | |
| 210 | 215 | #define RIO_MAX_DEVNAME_SZ 20 |
| 211 | 216 | |
| 212 | 217 | struct rio_rdev_info { |
| 213 | − uint32_t destid; | |
| 214 | − uint8_t hopcount; | |
| 215 | − uint32_t comptag; | |
| 218 | + __u16 destid; | |
| 219 | + __u8 hopcount; | |
| 220 | + __u8 pad0; | |
| 221 | + __u32 comptag; | |
| 216 | 222 | char name[RIO_MAX_DEVNAME_SZ + 1]; |
| 217 | 223 | }; |
| 218 | 224 | |
| @@ -220,11 +226,11 @@ struct rio_rdev_info { · 1 unmodified line | ||
| 220 | 226 | #define RIO_MPORT_DRV_MAGIC 'm' |
| 221 | 227 | |
| 222 | 228 | #define RIO_MPORT_MAINT_HDID_SET \ |
| 223 | − _IOW(RIO_MPORT_DRV_MAGIC, 1, uint16_t) | |
| 229 | + _IOW(RIO_MPORT_DRV_MAGIC, 1, __u16) | |
| 224 | 230 | #define RIO_MPORT_MAINT_COMPTAG_SET \ |
| 225 | − _IOW(RIO_MPORT_DRV_MAGIC, 2, uint32_t) | |
| 231 | + _IOW(RIO_MPORT_DRV_MAGIC, 2, __u32) | |
| 226 | 232 | #define RIO_MPORT_MAINT_PORT_IDX_GET \ |
| 227 | − _IOR(RIO_MPORT_DRV_MAGIC, 3, uint32_t) | |
| 233 | + _IOR(RIO_MPORT_DRV_MAGIC, 3, __u32) | |
| 228 | 234 | #define RIO_MPORT_GET_PROPERTIES \ |
| 229 | 235 | _IOR(RIO_MPORT_DRV_MAGIC, 4, struct rio_mport_properties) |
| 230 | 236 | #define RIO_MPORT_MAINT_READ_LOCAL \ |
| @@ -244,9 +250,9 @@ struct rio_rdev_info { · 13 unmodified lines | ||
| 244 | 250 | #define RIO_DISABLE_PORTWRITE_RANGE \ |
| 245 | 251 | _IOW(RIO_MPORT_DRV_MAGIC, 12, struct rio_pw_filter) |
| 246 | 252 | #define RIO_SET_EVENT_MASK \ |
| 247 | − _IOW(RIO_MPORT_DRV_MAGIC, 13, unsigned int) | |
| 253 | + _IOW(RIO_MPORT_DRV_MAGIC, 13, __u32) | |
| 248 | 254 | #define RIO_GET_EVENT_MASK \ |
| 249 | − _IOR(RIO_MPORT_DRV_MAGIC, 14, unsigned int) | |
| 255 | + _IOR(RIO_MPORT_DRV_MAGIC, 14, __u32) | |
| 250 | 256 | #define RIO_MAP_OUTBOUND \ |
| 251 | 257 | _IOWR(RIO_MPORT_DRV_MAGIC, 15, struct rio_mmap) |
| 252 | 258 | #define RIO_UNMAP_OUTBOUND \ |
| @@ -254,11 +260,11 @@ struct rio_rdev_info { · 1 unmodified line | ||
| 254 | 260 | #define RIO_MAP_INBOUND \ |
| 255 | 261 | _IOWR(RIO_MPORT_DRV_MAGIC, 17, struct rio_mmap) |
| 256 | 262 | #define RIO_UNMAP_INBOUND \ |
| 257 | − _IOW(RIO_MPORT_DRV_MAGIC, 18, uint64_t) | |
| 263 | + _IOW(RIO_MPORT_DRV_MAGIC, 18, __u64) | |
| 258 | 264 | #define RIO_ALLOC_DMA \ |
| 259 | 265 | _IOWR(RIO_MPORT_DRV_MAGIC, 19, struct rio_dma_mem) |
| 260 | 266 | #define RIO_FREE_DMA \ |
| 261 | − _IOW(RIO_MPORT_DRV_MAGIC, 20, uint64_t) | |
| 267 | + _IOW(RIO_MPORT_DRV_MAGIC, 20, __u64) | |
| 262 | 268 | #define RIO_TRANSFER \ |
| 263 | 269 | _IOWR(RIO_MPORT_DRV_MAGIC, 21, struct rio_transaction) |
| 264 | 270 | #define RIO_WAIT_FOR_ASYNC \ |
| @@ -45,9 +45,7 @@ · 44 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | static inline __attribute_const__ __u16 __fswab16(__u16 val) |
| 47 | 47 | { |
| 48 | −#ifdef __HAVE_BUILTIN_BSWAP16__ | |
| 49 | − return __builtin_bswap16(val); | |
| 50 | −#elif defined (__arch_swab16) | |
| 48 | +#if defined (__arch_swab16) | |
| 51 | 49 | return __arch_swab16(val); |
| 52 | 50 | #else |
| 53 | 51 | return ___constant_swab16(val); |
| @@ -56,9 +54,7 @@ static inline __attribute_const__ __u16 __fswab16(__u16 val) · 2 unmodified lines | ||
| 56 | 54 | |
| 57 | 55 | static inline __attribute_const__ __u32 __fswab32(__u32 val) |
| 58 | 56 | { |
| 59 | −#ifdef __HAVE_BUILTIN_BSWAP32__ | |
| 60 | − return __builtin_bswap32(val); | |
| 61 | −#elif defined(__arch_swab32) | |
| 57 | +#if defined(__arch_swab32) | |
| 62 | 58 | return __arch_swab32(val); |
| 63 | 59 | #else |
| 64 | 60 | return ___constant_swab32(val); |
| @@ -67,9 +63,7 @@ static inline __attribute_const__ __u32 __fswab32(__u32 val) · 2 unmodified lines | ||
| 67 | 63 | |
| 68 | 64 | static inline __attribute_const__ __u64 __fswab64(__u64 val) |
| 69 | 65 | { |
| 70 | −#ifdef __HAVE_BUILTIN_BSWAP64__ | |
| 71 | − return __builtin_bswap64(val); | |
| 72 | −#elif defined (__arch_swab64) | |
| 66 | +#if defined (__arch_swab64) | |
| 73 | 67 | return __arch_swab64(val); |
| 74 | 68 | #elif defined(__SWAB_64_THRU_32__) |
| 75 | 69 | __u32 h = val >> 32; |
| @@ -102,28 +96,40 @@ static inline __attribute_const__ __u32 __fswahb32(__u32 val) · 26 unmodified lines | ||
| 102 | 96 | * __swab16 - return a byteswapped 16-bit value |
| 103 | 97 | * @x: value to byteswap |
| 104 | 98 | */ |
| 99 | +#ifdef __HAVE_BUILTIN_BSWAP16__ | |
| 100 | +#define __swab16(x) (__u16)__builtin_bswap16((__u16)(x)) | |
| 101 | +#else | |
| 105 | 102 | #define __swab16(x) \ |
| 106 | 103 | (__builtin_constant_p((__u16)(x)) ? \ |
| 107 | 104 | ___constant_swab16(x) : \ |
| 108 | 105 | __fswab16(x)) |
| 106 | +#endif | |
| 109 | 107 | |
| 110 | 108 | /** |
| 111 | 109 | * __swab32 - return a byteswapped 32-bit value |
| 112 | 110 | * @x: value to byteswap |
| 113 | 111 | */ |
| 112 | +#ifdef __HAVE_BUILTIN_BSWAP32__ | |
| 113 | +#define __swab32(x) (__u32)__builtin_bswap32((__u32)(x)) | |
| 114 | +#else | |
| 114 | 115 | #define __swab32(x) \ |
| 115 | 116 | (__builtin_constant_p((__u32)(x)) ? \ |
| 116 | 117 | ___constant_swab32(x) : \ |
| 117 | 118 | __fswab32(x)) |
| 119 | +#endif | |
| 118 | 120 | |
| 119 | 121 | /** |
| 120 | 122 | * __swab64 - return a byteswapped 64-bit value |
| 121 | 123 | * @x: value to byteswap |
| 122 | 124 | */ |
| 125 | +#ifdef __HAVE_BUILTIN_BSWAP64__ | |
| 126 | +#define __swab64(x) (__u64)__builtin_bswap64((__u64)(x)) | |
| 127 | +#else | |
| 123 | 128 | #define __swab64(x) \ |
| 124 | 129 | (__builtin_constant_p((__u64)(x)) ? \ |
| 125 | 130 | ___constant_swab64(x) : \ |
| 126 | 131 | __fswab64(x)) |
| 132 | +#endif | |
| 127 | 133 | |
| 128 | 134 | /** |
| 129 | 135 | * __swahw32 - return a word-swapped 32-bit value |
| @@ -183,7 +183,8 @@ · 182 unmodified lines | ||
| 183 | 183 | |
| 184 | 184 | #define V4L2_DV_BT_CEA_3840X2160P24 { \ |
| 185 | 185 | .type = V4L2_DV_BT_656_1120, \ |
| 186 | − V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 186 | + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ | |
| 187 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 187 | 188 | 297000000, 1276, 88, 296, 8, 10, 72, 0, 0, 0, \ |
| 188 | 189 | V4L2_DV_BT_STD_CEA861, \ |
| 189 | 190 | V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ |
| @@ -191,14 +192,16 @@ · 1 unmodified line | ||
| 191 | 192 | |
| 192 | 193 | #define V4L2_DV_BT_CEA_3840X2160P25 { \ |
| 193 | 194 | .type = V4L2_DV_BT_656_1120, \ |
| 194 | − V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 195 | + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ | |
| 196 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 195 | 197 | 297000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, \ |
| 196 | 198 | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ |
| 197 | 199 | } |
| 198 | 200 | |
| 199 | 201 | #define V4L2_DV_BT_CEA_3840X2160P30 { \ |
| 200 | 202 | .type = V4L2_DV_BT_656_1120, \ |
| 201 | − V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 203 | + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ | |
| 204 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 202 | 205 | 297000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, \ |
| 203 | 206 | V4L2_DV_BT_STD_CEA861, \ |
| 204 | 207 | V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ |
| @@ -206,14 +209,16 @@ · 1 unmodified line | ||
| 206 | 209 | |
| 207 | 210 | #define V4L2_DV_BT_CEA_3840X2160P50 { \ |
| 208 | 211 | .type = V4L2_DV_BT_656_1120, \ |
| 209 | − V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 212 | + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ | |
| 213 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 210 | 214 | 594000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, \ |
| 211 | 215 | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ |
| 212 | 216 | } |
| 213 | 217 | |
| 214 | 218 | #define V4L2_DV_BT_CEA_3840X2160P60 { \ |
| 215 | 219 | .type = V4L2_DV_BT_656_1120, \ |
| 216 | − V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 220 | + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ | |
| 221 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 217 | 222 | 594000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, \ |
| 218 | 223 | V4L2_DV_BT_STD_CEA861, \ |
| 219 | 224 | V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ |
| @@ -221,7 +226,8 @@ · 1 unmodified line | ||
| 221 | 226 | |
| 222 | 227 | #define V4L2_DV_BT_CEA_4096X2160P24 { \ |
| 223 | 228 | .type = V4L2_DV_BT_656_1120, \ |
| 224 | − V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 229 | + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ | |
| 230 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 225 | 231 | 297000000, 1020, 88, 296, 8, 10, 72, 0, 0, 0, \ |
| 226 | 232 | V4L2_DV_BT_STD_CEA861, \ |
| 227 | 233 | V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ |
| @@ -229,14 +235,16 @@ · 1 unmodified line | ||
| 229 | 235 | |
| 230 | 236 | #define V4L2_DV_BT_CEA_4096X2160P25 { \ |
| 231 | 237 | .type = V4L2_DV_BT_656_1120, \ |
| 232 | − V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 238 | + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ | |
| 239 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 233 | 240 | 297000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, \ |
| 234 | 241 | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ |
| 235 | 242 | } |
| 236 | 243 | |
| 237 | 244 | #define V4L2_DV_BT_CEA_4096X2160P30 { \ |
| 238 | 245 | .type = V4L2_DV_BT_656_1120, \ |
| 239 | − V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 246 | + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ | |
| 247 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 240 | 248 | 297000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, \ |
| 241 | 249 | V4L2_DV_BT_STD_CEA861, \ |
| 242 | 250 | V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ |
| @@ -244,14 +252,16 @@ · 1 unmodified line | ||
| 244 | 252 | |
| 245 | 253 | #define V4L2_DV_BT_CEA_4096X2160P50 { \ |
| 246 | 254 | .type = V4L2_DV_BT_656_1120, \ |
| 247 | − V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 255 | + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ | |
| 256 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 248 | 257 | 594000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, \ |
| 249 | 258 | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ |
| 250 | 259 | } |
| 251 | 260 | |
| 252 | 261 | #define V4L2_DV_BT_CEA_4096X2160P60 { \ |
| 253 | 262 | .type = V4L2_DV_BT_656_1120, \ |
| 254 | − V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 263 | + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ | |
| 264 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 255 | 265 | 594000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, \ |
| 256 | 266 | V4L2_DV_BT_STD_CEA861, \ |
| 257 | 267 | V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ |
| @@ -15,9 +15,9 @@ · 14 unmodified lines | ||
| 15 | 15 | */ |
| 16 | 16 | |
| 17 | 17 | #define xen_pfn_to_page(xen_pfn) \ |
| 18 | − ((pfn_to_page(((unsigned long)(xen_pfn) << XEN_PAGE_SHIFT) >> PAGE_SHIFT))) | |
| 18 | + (pfn_to_page((unsigned long)(xen_pfn) >> (PAGE_SHIFT - XEN_PAGE_SHIFT))) | |
| 19 | 19 | #define page_to_xen_pfn(page) \ |
| 20 | − (((page_to_pfn(page)) << PAGE_SHIFT) >> XEN_PAGE_SHIFT) | |
| 20 | + ((page_to_pfn(page)) << (PAGE_SHIFT - XEN_PAGE_SHIFT)) | |
| 21 | 21 | |
| 22 | 22 | #define XEN_PFN_PER_PAGE (PAGE_SIZE / XEN_PAGE_SIZE) |
| 23 | 23 | |
| @@ -31,10 +31,10 @@ static void *bpf_any_get(void *raw, enum bpf_type type) · 30 unmodified lines | ||
| 31 | 31 | { |
| 32 | 32 | switch (type) { |
| 33 | 33 | case BPF_TYPE_PROG: |
| 34 | − atomic_inc(&((struct bpf_prog *)raw)->aux->refcnt); | |
| 34 | + raw = bpf_prog_inc(raw); | |
| 35 | 35 | break; |
| 36 | 36 | case BPF_TYPE_MAP: |
| 37 | − bpf_map_inc(raw, true); | |
| 37 | + raw = bpf_map_inc(raw, true); | |
| 38 | 38 | break; |
| 39 | 39 | default: |
| 40 | 40 | WARN_ON_ONCE(1); |
| @@ -297,7 +297,8 @@ static void *bpf_obj_do_get(const struct filename *pathname, · 256 unmodified lines | ||
| 297 | 297 | goto out; |
| 298 | 298 | |
| 299 | 299 | raw = bpf_any_get(inode->i_private, *type); |
| 300 | − touch_atime(&path); | |
| 300 | + if (!IS_ERR(raw)) | |
| 301 | + touch_atime(&path); | |
| 301 | 302 | |
| 302 | 303 | path_put(&path); |
| 303 | 304 | return raw; |
| @@ -218,11 +218,18 @@ struct bpf_map *__bpf_map_get(struct fd f) · 217 unmodified lines | ||
| 218 | 218 | return f.file->private_data; |
| 219 | 219 | } |
| 220 | 220 | |
| 221 | −void bpf_map_inc(struct bpf_map *map, bool uref) | |
| 221 | +/* prog's and map's refcnt limit */ | |
| 222 | +#define BPF_MAX_REFCNT 32768 | |
| 223 | + | |
| 224 | +struct bpf_map *bpf_map_inc(struct bpf_map *map, bool uref) | |
| 222 | 225 | { |
| 223 | − atomic_inc(&map->refcnt); | |
| 226 | + if (atomic_inc_return(&map->refcnt) > BPF_MAX_REFCNT) { | |
| 227 | + atomic_dec(&map->refcnt); | |
| 228 | + return ERR_PTR(-EBUSY); | |
| 229 | + } | |
| 224 | 230 | if (uref) |
| 225 | 231 | atomic_inc(&map->usercnt); |
| 232 | + return map; | |
| 226 | 233 | } |
| 227 | 234 | |
| 228 | 235 | struct bpf_map *bpf_map_get_with_uref(u32 ufd) |
| @@ -234,7 +241,7 @@ struct bpf_map *bpf_map_get_with_uref(u32 ufd) · 5 unmodified lines | ||
| 234 | 241 | if (IS_ERR(map)) |
| 235 | 242 | return map; |
| 236 | 243 | |
| 237 | − bpf_map_inc(map, true); | |
| 244 | + map = bpf_map_inc(map, true); | |
| 238 | 245 | fdput(f); |
| 239 | 246 | |
| 240 | 247 | return map; |
| @@ -658,6 +665,15 @@ static struct bpf_prog *__bpf_prog_get(struct fd f) · 417 unmodified lines | ||
| 658 | 665 | return f.file->private_data; |
| 659 | 666 | } |
| 660 | 667 | |
| 668 | +struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog) | |
| 669 | +{ | |
| 670 | + if (atomic_inc_return(&prog->aux->refcnt) > BPF_MAX_REFCNT) { | |
| 671 | + atomic_dec(&prog->aux->refcnt); | |
| 672 | + return ERR_PTR(-EBUSY); | |
| 673 | + } | |
| 674 | + return prog; | |
| 675 | +} | |
| 676 | + | |
| 661 | 677 | /* called by sockets/tracing/seccomp before attaching program to an event |
| 662 | 678 | * pairs with bpf_prog_put() |
| 663 | 679 | */ |
| @@ -670,7 +686,7 @@ struct bpf_prog *bpf_prog_get(u32 ufd) · 6 unmodified lines | ||
| 670 | 686 | if (IS_ERR(prog)) |
| 671 | 687 | return prog; |
| 672 | 688 | |
| 673 | − atomic_inc(&prog->aux->refcnt); | |
| 689 | + prog = bpf_prog_inc(prog); | |
| 674 | 690 | fdput(f); |
| 675 | 691 | |
| 676 | 692 | return prog; |
| @@ -239,16 +239,6 @@ static const char * const reg_type_str[] = { · 238 unmodified lines | ||
| 239 | 239 | [CONST_IMM] = "imm", |
| 240 | 240 | }; |
| 241 | 241 | |
| 242 | −static const struct { | |
| 243 | − int map_type; | |
| 244 | − int func_id; | |
| 245 | −} func_limit[] = { | |
| 246 | − {BPF_MAP_TYPE_PROG_ARRAY, BPF_FUNC_tail_call}, | |
| 247 | − {BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_read}, | |
| 248 | − {BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_output}, | |
| 249 | − {BPF_MAP_TYPE_STACK_TRACE, BPF_FUNC_get_stackid}, | |
| 250 | −}; | |
| 251 | − | |
| 252 | 242 | static void print_verifier_state(struct verifier_env *env) |
| 253 | 243 | { |
| 254 | 244 | enum bpf_reg_type t; |
| @@ -921,27 +911,52 @@ static int check_func_arg(struct verifier_env *env, u32 regno, · 666 unmodified lines | ||
| 921 | 911 | |
| 922 | 912 | static int check_map_func_compatibility(struct bpf_map *map, int func_id) |
| 923 | 913 | { |
| 924 | − bool bool_map, bool_func; | |
| 925 | − int i; | |
| 926 | − | |
| 927 | 914 | if (!map) |
| 928 | 915 | return 0; |
| 929 | 916 | |
| 930 | − for (i = 0; i < ARRAY_SIZE(func_limit); i++) { | |
| 931 | − bool_map = (map->map_type == func_limit[i].map_type); | |
| 932 | − bool_func = (func_id == func_limit[i].func_id); | |
| 933 | − /* only when map & func pair match it can continue. | |
| 934 | − * don't allow any other map type to be passed into | |
| 935 | − * the special func; | |
| 936 | − */ | |
| 937 | − if (bool_func && bool_map != bool_func) { | |
| 938 | − verbose("cannot pass map_type %d into func %d\n", | |
| 939 | − map->map_type, func_id); | |
| 940 | − return -EINVAL; | |
| 941 | − } | |
| 917 | + /* We need a two way check, first is from map perspective ... */ | |
| 918 | + switch (map->map_type) { | |
| 919 | + case BPF_MAP_TYPE_PROG_ARRAY: | |
| 920 | + if (func_id != BPF_FUNC_tail_call) | |
| 921 | + goto error; | |
| 922 | + break; | |
| 923 | + case BPF_MAP_TYPE_PERF_EVENT_ARRAY: | |
| 924 | + if (func_id != BPF_FUNC_perf_event_read && | |
| 925 | + func_id != BPF_FUNC_perf_event_output) | |
| 926 | + goto error; | |
| 927 | + break; | |
| 928 | + case BPF_MAP_TYPE_STACK_TRACE: | |
| 929 | + if (func_id != BPF_FUNC_get_stackid) | |
| 930 | + goto error; | |
| 931 | + break; | |
| 932 | + default: | |
| 933 | + break; | |
| 934 | + } | |
| 935 | + | |
| 936 | + /* ... and second from the function itself. */ | |
| 937 | + switch (func_id) { | |
| 938 | + case BPF_FUNC_tail_call: | |
| 939 | + if (map->map_type != BPF_MAP_TYPE_PROG_ARRAY) | |
| 940 | + goto error; | |
| 941 | + break; | |
| 942 | + case BPF_FUNC_perf_event_read: | |
| 943 | + case BPF_FUNC_perf_event_output: | |
| 944 | + if (map->map_type != BPF_MAP_TYPE_PERF_EVENT_ARRAY) | |
| 945 | + goto error; | |
| 946 | + break; | |
| 947 | + case BPF_FUNC_get_stackid: | |
| 948 | + if (map->map_type != BPF_MAP_TYPE_STACK_TRACE) | |
| 949 | + goto error; | |
| 950 | + break; | |
| 951 | + default: | |
| 952 | + break; | |
| 942 | 953 | } |
| 943 | 954 | |
| 944 | 955 | return 0; |
| 956 | +error: | |
| 957 | + verbose("cannot pass map_type %d into func %d\n", | |
| 958 | + map->map_type, func_id); | |
| 959 | + return -EINVAL; | |
| 945 | 960 | } |
| 946 | 961 | |
| 947 | 962 | static int check_call(struct verifier_env *env, int func_id) |
| @@ -2030,7 +2045,6 @@ static int replace_map_fd_with_map_ptr(struct verifier_env *env) · 1082 unmodified lines | ||
| 2030 | 2045 | if (IS_ERR(map)) { |
| 2031 | 2046 | verbose("fd %d is not pointing to valid bpf_map\n", |
| 2032 | 2047 | insn->imm); |
| 2033 | − fdput(f); | |
| 2034 | 2048 | return PTR_ERR(map); |
| 2035 | 2049 | } |
| 2036 | 2050 | |
| @@ -2050,15 +2064,18 @@ static int replace_map_fd_with_map_ptr(struct verifier_env *env) · 13 unmodified lines | ||
| 2050 | 2064 | return -E2BIG; |
| 2051 | 2065 | } |
| 2052 | 2066 | |
| 2053 | − /* remember this map */ | |
| 2054 | − env->used_maps[env->used_map_cnt++] = map; | |
| 2055 | − | |
| 2056 | 2067 | /* hold the map. If the program is rejected by verifier, |
| 2057 | 2068 | * the map will be released by release_maps() or it |
| 2058 | 2069 | * will be used by the valid program until it's unloaded |
| 2059 | 2070 | * and all maps are released in free_bpf_prog_info() |
| 2060 | 2071 | */ |
| 2061 | − bpf_map_inc(map, false); | |
| 2072 | + map = bpf_map_inc(map, false); | |
| 2073 | + if (IS_ERR(map)) { | |
| 2074 | + fdput(f); | |
| 2075 | + return PTR_ERR(map); | |
| 2076 | + } | |
| 2077 | + env->used_maps[env->used_map_cnt++] = map; | |
| 2078 | + | |
| 2062 | 2079 | fdput(f); |
| 2063 | 2080 | next_insn: |
| 2064 | 2081 | insn++; |
| @@ -2825,9 +2825,10 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf, · 2824 unmodified lines | ||
| 2825 | 2825 | size_t nbytes, loff_t off, bool threadgroup) |
| 2826 | 2826 | { |
| 2827 | 2827 | struct task_struct *tsk; |
| 2828 | + struct cgroup_subsys *ss; | |
| 2828 | 2829 | struct cgroup *cgrp; |
| 2829 | 2830 | pid_t pid; |
| 2830 | − int ret; | |
| 2831 | + int ssid, ret; | |
| 2831 | 2832 | |
| 2832 | 2833 | if (kstrtoint(strstrip(buf), 0, &pid) || pid < 0) |
| 2833 | 2834 | return -EINVAL; |
| @@ -2875,8 +2876,10 @@ out_unlock_rcu: · 41 unmodified lines | ||
| 2875 | 2876 | rcu_read_unlock(); |
| 2876 | 2877 | out_unlock_threadgroup: |
| 2877 | 2878 | percpu_up_write(&cgroup_threadgroup_rwsem); |
| 2879 | + for_each_subsys(ss, ssid) | |
| 2880 | + if (ss->post_attach) | |
| 2881 | + ss->post_attach(); | |
| 2878 | 2882 | cgroup_kn_unlock(of->kn); |
| 2879 | − cpuset_post_attach_flush(); | |
| 2880 | 2883 | return ret ?: nbytes; |
| 2881 | 2884 | } |
| 2882 | 2885 | |
| @@ -58,7 +58,6 @@ · 57 unmodified lines | ||
| 58 | 58 | #include <asm/uaccess.h> |
| 59 | 59 | #include <linux/atomic.h> |
| 60 | 60 | #include <linux/mutex.h> |
| 61 | −#include <linux/workqueue.h> | |
| 62 | 61 | #include <linux/cgroup.h> |
| 63 | 62 | #include <linux/wait.h> |
| 64 | 63 | |
| @@ -1016,7 +1015,7 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from, · 951 unmodified lines | ||
| 1016 | 1015 | } |
| 1017 | 1016 | } |
| 1018 | 1017 | |
| 1019 | −void cpuset_post_attach_flush(void) | |
| 1018 | +static void cpuset_post_attach(void) | |
| 1020 | 1019 | { |
| 1021 | 1020 | flush_workqueue(cpuset_migrate_mm_wq); |
| 1022 | 1021 | } |
| @@ -2087,6 +2086,7 @@ struct cgroup_subsys cpuset_cgrp_subsys = { · 1064 unmodified lines | ||
| 2087 | 2086 | .can_attach = cpuset_can_attach, |
| 2088 | 2087 | .cancel_attach = cpuset_cancel_attach, |
| 2089 | 2088 | .attach = cpuset_attach, |
| 2089 | + .post_attach = cpuset_post_attach, | |
| 2090 | 2090 | .bind = cpuset_bind, |
| 2091 | 2091 | .legacy_cftypes = files, |
| 2092 | 2092 | .early_init = true, |
| @@ -412,7 +412,8 @@ int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write, · 411 unmodified lines | ||
| 412 | 412 | if (ret || !write) |
| 413 | 413 | return ret; |
| 414 | 414 | |
| 415 | − if (sysctl_perf_cpu_time_max_percent == 100) { | |
| 415 | + if (sysctl_perf_cpu_time_max_percent == 100 || | |
| 416 | + sysctl_perf_cpu_time_max_percent == 0) { | |
| 416 | 417 | printk(KERN_WARNING |
| 417 | 418 | "perf: Dynamic interrupt throttling disabled, can hang your system!\n"); |
| 418 | 419 | WRITE_ONCE(perf_sample_allowed_ns, 0); |
| @@ -1105,6 +1106,7 @@ static void put_ctx(struct perf_event_context *ctx) · 686 unmodified lines | ||
| 1105 | 1106 | * function. |
| 1106 | 1107 | * |
| 1107 | 1108 | * Lock order: |
| 1109 | + * cred_guard_mutex | |
| 1108 | 1110 | * task_struct::perf_event_mutex |
| 1109 | 1111 | * perf_event_context::mutex |
| 1110 | 1112 | * perf_event::child_mutex; |
| @@ -3420,7 +3422,6 @@ static struct task_struct * · 2309 unmodified lines | ||
| 3420 | 3422 | find_lively_task_by_vpid(pid_t vpid) |
| 3421 | 3423 | { |
| 3422 | 3424 | struct task_struct *task; |
| 3423 | − int err; | |
| 3424 | 3425 | |
| 3425 | 3426 | rcu_read_lock(); |
| 3426 | 3427 | if (!vpid) |
| @@ -3434,16 +3435,7 @@ find_lively_task_by_vpid(pid_t vpid) · 7 unmodified lines | ||
| 3434 | 3435 | if (!task) |
| 3435 | 3436 | return ERR_PTR(-ESRCH); |
| 3436 | 3437 | |
| 3437 | − /* Reuse ptrace permission checks for now. */ | |
| 3438 | − err = -EACCES; | |
| 3439 | − if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) | |
| 3440 | − goto errout; | |
| 3441 | − | |
| 3442 | 3438 | return task; |
| 3443 | −errout: | |
| 3444 | − put_task_struct(task); | |
| 3445 | − return ERR_PTR(err); | |
| 3446 | − | |
| 3447 | 3439 | } |
| 3448 | 3440 | |
| 3449 | 3441 | /* |
| @@ -8413,6 +8405,24 @@ SYSCALL_DEFINE5(perf_event_open, · 4963 unmodified lines | ||
| 8413 | 8405 | |
| 8414 | 8406 | get_online_cpus(); |
| 8415 | 8407 | |
| 8408 | + if (task) { | |
| 8409 | + err = mutex_lock_interruptible(&task->signal->cred_guard_mutex); | |
| 8410 | + if (err) | |
| 8411 | + goto err_cpus; | |
| 8412 | + | |
| 8413 | + /* | |
| 8414 | + * Reuse ptrace permission checks for now. | |
| 8415 | + * | |
| 8416 | + * We must hold cred_guard_mutex across this and any potential | |
| 8417 | + * perf_install_in_context() call for this new event to | |
| 8418 | + * serialize against exec() altering our credentials (and the | |
| 8419 | + * perf_event_exit_task() that could imply). | |
| 8420 | + */ | |
| 8421 | + err = -EACCES; | |
| 8422 | + if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) | |
| 8423 | + goto err_cred; | |
| 8424 | + } | |
| 8425 | + | |
| 8416 | 8426 | if (flags & PERF_FLAG_PID_CGROUP) |
| 8417 | 8427 | cgroup_fd = pid; |
| 8418 | 8428 | |
| @@ -8420,7 +8430,7 @@ SYSCALL_DEFINE5(perf_event_open, · 1 unmodified line | ||
| 8420 | 8430 | NULL, NULL, cgroup_fd); |
| 8421 | 8431 | if (IS_ERR(event)) { |
| 8422 | 8432 | err = PTR_ERR(event); |
| 8423 | − goto err_cpus; | |
| 8433 | + goto err_cred; | |
| 8424 | 8434 | } |
| 8425 | 8435 | |
| 8426 | 8436 | if (is_sampling_event(event)) { |
| @@ -8479,11 +8489,6 @@ SYSCALL_DEFINE5(perf_event_open, · 52 unmodified lines | ||
| 8479 | 8489 | goto err_context; |
| 8480 | 8490 | } |
| 8481 | 8491 | |
| 8482 | − if (task) { | |
| 8483 | − put_task_struct(task); | |
| 8484 | − task = NULL; | |
| 8485 | − } | |
| 8486 | − | |
| 8487 | 8492 | /* |
| 8488 | 8493 | * Look up the group leader (we will attach this event to it): |
| 8489 | 8494 | */ |
| @@ -8581,6 +8586,11 @@ SYSCALL_DEFINE5(perf_event_open, · 91 unmodified lines | ||
| 8581 | 8586 | |
| 8582 | 8587 | WARN_ON_ONCE(ctx->parent_ctx); |
| 8583 | 8588 | |
| 8589 | + /* | |
| 8590 | + * This is the point on no return; we cannot fail hereafter. This is | |
| 8591 | + * where we start modifying current state. | |
| 8592 | + */ | |
| 8593 | + | |
| 8584 | 8594 | if (move_group) { |
| 8585 | 8595 | /* |
| 8586 | 8596 | * See perf_event_ctx_lock() for comments on the details |
| @@ -8652,6 +8662,11 @@ SYSCALL_DEFINE5(perf_event_open, · 65 unmodified lines | ||
| 8652 | 8662 | mutex_unlock(&gctx->mutex); |
| 8653 | 8663 | mutex_unlock(&ctx->mutex); |
| 8654 | 8664 | |
| 8665 | + if (task) { | |
| 8666 | + mutex_unlock(&task->signal->cred_guard_mutex); | |
| 8667 | + put_task_struct(task); | |
| 8668 | + } | |
| 8669 | + | |
| 8655 | 8670 | put_online_cpus(); |
| 8656 | 8671 | |
| 8657 | 8672 | mutex_lock(¤t->perf_event_mutex); |
| @@ -8684,6 +8699,9 @@ err_alloc: · 26 unmodified lines | ||
| 8684 | 8699 | */ |
| 8685 | 8700 | if (!event_file) |
| 8686 | 8701 | free_event(event); |
| 8702 | +err_cred: | |
| 8703 | + if (task) | |
| 8704 | + mutex_unlock(&task->signal->cred_guard_mutex); | |
| 8687 | 8705 | err_cpus: |
| 8688 | 8706 | put_online_cpus(); |
| 8689 | 8707 | err_task: |
| @@ -8968,6 +8986,9 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn) · 278 unmodified lines | ||
| 8968 | 8986 | |
| 8969 | 8987 | /* |
| 8970 | 8988 | * When a child task exits, feed back event values to parent events. |
| 8989 | + * | |
| 8990 | + * Can be called with cred_guard_mutex held when called from | |
| 8991 | + * install_exec_creds(). | |
| 8971 | 8992 | */ |
| 8972 | 8993 | void perf_event_exit_task(struct task_struct *child) |
| 8973 | 8994 | { |
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | #define pr_fmt(fmt) "kcov: " fmt |
| 2 | 2 | |
| 3 | +#define DISABLE_BRANCH_PROFILING | |
| 3 | 4 | #include <linux/compiler.h> |
| 4 | 5 | #include <linux/types.h> |
| 5 | 6 | #include <linux/file.h> |
| @@ -43,7 +44,7 @@ struct kcov { · 37 unmodified lines | ||
| 43 | 44 | * Entry point from instrumented code. |
| 44 | 45 | * This is called once per basic-block/edge. |
| 45 | 46 | */ |
| 46 | −void __sanitizer_cov_trace_pc(void) | |
| 47 | +void notrace __sanitizer_cov_trace_pc(void) | |
| 47 | 48 | { |
| 48 | 49 | struct task_struct *t; |
| 49 | 50 | enum kcov_mode mode; |
| @@ -1415,6 +1415,9 @@ static int __init crash_save_vmcoreinfo_init(void) · 1414 unmodified lines | ||
| 1415 | 1415 | VMCOREINFO_OFFSET(page, lru); |
| 1416 | 1416 | VMCOREINFO_OFFSET(page, _mapcount); |
| 1417 | 1417 | VMCOREINFO_OFFSET(page, private); |
| 1418 | + VMCOREINFO_OFFSET(page, compound_dtor); | |
| 1419 | + VMCOREINFO_OFFSET(page, compound_order); | |
| 1420 | + VMCOREINFO_OFFSET(page, compound_head); | |
| 1418 | 1421 | VMCOREINFO_OFFSET(pglist_data, node_zones); |
| 1419 | 1422 | VMCOREINFO_OFFSET(pglist_data, nr_zones); |
| 1420 | 1423 | #ifdef CONFIG_FLAT_NODE_MEM_MAP |
| @@ -1447,8 +1450,8 @@ static int __init crash_save_vmcoreinfo_init(void) · 26 unmodified lines | ||
| 1447 | 1450 | #ifdef CONFIG_X86 |
| 1448 | 1451 | VMCOREINFO_NUMBER(KERNEL_IMAGE_SIZE); |
| 1449 | 1452 | #endif |
| 1450 | −#ifdef CONFIG_HUGETLBFS | |
| 1451 | − VMCOREINFO_SYMBOL(free_huge_page); | |
| 1453 | +#ifdef CONFIG_HUGETLB_PAGE | |
| 1454 | + VMCOREINFO_NUMBER(HUGETLB_PAGE_DTOR); | |
| 1452 | 1455 | #endif |
| 1453 | 1456 | |
| 1454 | 1457 | arch_crash_save_vmcoreinfo(); |
| @@ -2176,15 +2176,37 @@ cache_hit: · 2175 unmodified lines | ||
| 2176 | 2176 | chain->irq_context = hlock->irq_context; |
| 2177 | 2177 | i = get_first_held_lock(curr, hlock); |
| 2178 | 2178 | chain->depth = curr->lockdep_depth + 1 - i; |
| 2179 | + | |
| 2180 | + BUILD_BUG_ON((1UL << 24) <= ARRAY_SIZE(chain_hlocks)); | |
| 2181 | + BUILD_BUG_ON((1UL << 6) <= ARRAY_SIZE(curr->held_locks)); | |
| 2182 | + BUILD_BUG_ON((1UL << 8*sizeof(chain_hlocks[0])) <= ARRAY_SIZE(lock_classes)); | |
| 2183 | + | |
| 2179 | 2184 | if (likely(nr_chain_hlocks + chain->depth <= MAX_LOCKDEP_CHAIN_HLOCKS)) { |
| 2180 | 2185 | chain->base = nr_chain_hlocks; |
| 2181 | − nr_chain_hlocks += chain->depth; | |
| 2182 | 2186 | for (j = 0; j < chain->depth - 1; j++, i++) { |
| 2183 | 2187 | int lock_id = curr->held_locks[i].class_idx - 1; |
| 2184 | 2188 | chain_hlocks[chain->base + j] = lock_id; |
| 2185 | 2189 | } |
| 2186 | 2190 | chain_hlocks[chain->base + j] = class - lock_classes; |
| 2187 | 2191 | } |
| 2192 | + | |
| 2193 | + if (nr_chain_hlocks < MAX_LOCKDEP_CHAIN_HLOCKS) | |
| 2194 | + nr_chain_hlocks += chain->depth; | |
| 2195 | + | |
| 2196 | +#ifdef CONFIG_DEBUG_LOCKDEP | |
| 2197 | + /* | |
| 2198 | + * Important for check_no_collision(). | |
| 2199 | + */ | |
| 2200 | + if (unlikely(nr_chain_hlocks > MAX_LOCKDEP_CHAIN_HLOCKS)) { | |
| 2201 | + if (debug_locks_off_graph_unlock()) | |
| 2202 | + return 0; | |
| 2203 | + | |
| 2204 | + print_lockdep_off("BUG: MAX_LOCKDEP_CHAIN_HLOCKS too low!"); | |
| 2205 | + dump_stack(); | |
| 2206 | + return 0; | |
| 2207 | + } | |
| 2208 | +#endif | |
| 2209 | + | |
| 2188 | 2210 | hlist_add_head_rcu(&chain->entry, hash_head); |
| 2189 | 2211 | debug_atomic_inc(chain_lookup_misses); |
| 2190 | 2212 | inc_chains(); |
| @@ -2932,6 +2954,11 @@ static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) · 741 unmodified lines | ||
| 2932 | 2954 | return 1; |
| 2933 | 2955 | } |
| 2934 | 2956 | |
| 2957 | +static inline unsigned int task_irq_context(struct task_struct *task) | |
| 2958 | +{ | |
| 2959 | + return 2 * !!task->hardirq_context + !!task->softirq_context; | |
| 2960 | +} | |
| 2961 | + | |
| 2935 | 2962 | static int separate_irq_context(struct task_struct *curr, |
| 2936 | 2963 | struct held_lock *hlock) |
| 2937 | 2964 | { |
| @@ -2940,8 +2967,6 @@ static int separate_irq_context(struct task_struct *curr, · 2 unmodified lines | ||
| 2940 | 2967 | /* |
| 2941 | 2968 | * Keep track of points where we cross into an interrupt context: |
| 2942 | 2969 | */ |
| 2943 | − hlock->irq_context = 2*(curr->hardirq_context ? 1 : 0) + | |
| 2944 | − curr->softirq_context; | |
| 2945 | 2970 | if (depth) { |
| 2946 | 2971 | struct held_lock *prev_hlock; |
| 2947 | 2972 | |
| @@ -2973,6 +2998,11 @@ static inline int mark_irqflags(struct task_struct *curr, · 25 unmodified lines | ||
| 2973 | 2998 | return 1; |
| 2974 | 2999 | } |
| 2975 | 3000 | |
| 3001 | +static inline unsigned int task_irq_context(struct task_struct *task) | |
| 3002 | +{ | |
| 3003 | + return 0; | |
| 3004 | +} | |
| 3005 | + | |
| 2976 | 3006 | static inline int separate_irq_context(struct task_struct *curr, |
| 2977 | 3007 | struct held_lock *hlock) |
| 2978 | 3008 | { |
| @@ -3241,6 +3271,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, · 262 unmodified lines | ||
| 3241 | 3271 | hlock->acquire_ip = ip; |
| 3242 | 3272 | hlock->instance = lock; |
| 3243 | 3273 | hlock->nest_lock = nest_lock; |
| 3274 | + hlock->irq_context = task_irq_context(curr); | |
| 3244 | 3275 | hlock->trylock = trylock; |
| 3245 | 3276 | hlock->read = read; |
| 3246 | 3277 | hlock->check = check; |
| @@ -141,6 +141,8 @@ static int lc_show(struct seq_file *m, void *v) · 140 unmodified lines | ||
| 141 | 141 | int i; |
| 142 | 142 | |
| 143 | 143 | if (v == SEQ_START_TOKEN) { |
| 144 | + if (nr_chain_hlocks > MAX_LOCKDEP_CHAIN_HLOCKS) | |
| 145 | + seq_printf(m, "(buggered) "); | |
| 144 | 146 | seq_printf(m, "all lock chains:\n"); |
| 145 | 147 | return 0; |
| 146 | 148 | } |
| @@ -596,17 +596,8 @@ bool sched_can_stop_tick(struct rq *rq) · 595 unmodified lines | ||
| 596 | 596 | return false; |
| 597 | 597 | |
| 598 | 598 | /* |
| 599 | − * FIFO realtime policy runs the highest priority task (after DEADLINE). | |
| 600 | − * Other runnable tasks are of a lower priority. The scheduler tick | |
| 601 | − * isn't needed. | |
| 602 | − */ | |
| 603 | − fifo_nr_running = rq->rt.rt_nr_running - rq->rt.rr_nr_running; | |
| 604 | − if (fifo_nr_running) | |
| 605 | − return true; | |
| 606 | − | |
| 607 | − /* | |
| 608 | − * Round-robin realtime tasks time slice with other tasks at the same | |
| 609 | − * realtime priority. | |
| 599 | + * If there are more than one RR tasks, we need the tick to effect the | |
| 600 | + * actual RR behaviour. | |
| 610 | 601 | */ |
| 611 | 602 | if (rq->rt.rr_nr_running) { |
| 612 | 603 | if (rq->rt.rr_nr_running == 1) |
| @@ -615,8 +606,20 @@ bool sched_can_stop_tick(struct rq *rq) · 2 unmodified lines | ||
| 615 | 606 | return false; |
| 616 | 607 | } |
| 617 | 608 | |
| 618 | − /* Normal multitasking need periodic preemption checks */ | |
| 619 | − if (rq->cfs.nr_running > 1) | |
| 609 | + /* | |
| 610 | + * If there's no RR tasks, but FIFO tasks, we can skip the tick, no | |
| 611 | + * forced preemption between FIFO tasks. | |
| 612 | + */ | |
| 613 | + fifo_nr_running = rq->rt.rt_nr_running - rq->rt.rr_nr_running; | |
| 614 | + if (fifo_nr_running) | |
| 615 | + return true; | |
| 616 | + | |
| 617 | + /* | |
| 618 | + * If there are no DL,RR/FIFO tasks, there must only be CFS tasks left; | |
| 619 | + * if there's more than one we need the tick for involuntary | |
| 620 | + * preemption. | |
| 621 | + */ | |
| 622 | + if (rq->nr_running > 1) | |
| 620 | 623 | return false; |
| 621 | 624 | |
| 622 | 625 | return true; |
| @@ -2095,8 +2095,13 @@ event_create_dir(struct dentry *parent, struct trace_event_file *file) · 2094 unmodified lines | ||
| 2095 | 2095 | trace_create_file("filter", 0644, file->dir, file, |
| 2096 | 2096 | &ftrace_event_filter_fops); |
| 2097 | 2097 | |
| 2098 | − trace_create_file("trigger", 0644, file->dir, file, | |
| 2099 | − &event_trigger_fops); | |
| 2098 | + /* | |
| 2099 | + * Only event directories that can be enabled should have | |
| 2100 | + * triggers. | |
| 2101 | + */ | |
| 2102 | + if (!(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE)) | |
| 2103 | + trace_create_file("trigger", 0644, file->dir, file, | |
| 2104 | + &event_trigger_fops); | |
| 2100 | 2105 | |
| 2101 | 2106 | trace_create_file("format", 0444, file->dir, call, |
| 2102 | 2107 | &ftrace_event_format_fops); |
| @@ -666,6 +666,35 @@ static void set_work_pool_and_clear_pending(struct work_struct *work, · 665 unmodified lines | ||
| 666 | 666 | */ |
| 667 | 667 | smp_wmb(); |
| 668 | 668 | set_work_data(work, (unsigned long)pool_id << WORK_OFFQ_POOL_SHIFT, 0); |
| 669 | + /* | |
| 670 | + * The following mb guarantees that previous clear of a PENDING bit | |
| 671 | + * will not be reordered with any speculative LOADS or STORES from | |
| 672 | + * work->current_func, which is executed afterwards. This possible | |
| 673 | + * reordering can lead to a missed execution on attempt to qeueue | |
| 674 | + * the same @work. E.g. consider this case: | |
| 675 | + * | |
| 676 | + * CPU#0 CPU#1 | |
| 677 | + * ---------------------------- -------------------------------- | |
| 678 | + * | |
| 679 | + * 1 STORE event_indicated | |
| 680 | + * 2 queue_work_on() { | |
| 681 | + * 3 test_and_set_bit(PENDING) | |
| 682 | + * 4 } set_..._and_clear_pending() { | |
| 683 | + * 5 set_work_data() # clear bit | |
| 684 | + * 6 smp_mb() | |
| 685 | + * 7 work->current_func() { | |
| 686 | + * 8 LOAD event_indicated | |
| 687 | + * } | |
| 688 | + * | |
| 689 | + * Without an explicit full barrier speculative LOAD on line 8 can | |
| 690 | + * be executed before CPU#0 does STORE on line 1. If that happens, | |
| 691 | + * CPU#0 observes the PENDING bit is still set and new execution of | |
| 692 | + * a @work is not queued in a hope, that CPU#1 will eventually | |
| 693 | + * finish the queued @work. Meanwhile CPU#1 does not see | |
| 694 | + * event_indicated is set, because speculative LOAD was executed | |
| 695 | + * before actual STORE. | |
| 696 | + */ | |
| 697 | + smp_mb(); | |
| 669 | 698 | } |
| 670 | 699 | |
| 671 | 700 | static void clear_work_data(struct work_struct *work) |
| @@ -42,12 +42,14 @@ · 41 unmodified lines | ||
| 42 | 42 | |
| 43 | 43 | #define DEPOT_STACK_BITS (sizeof(depot_stack_handle_t) * 8) |
| 44 | 44 | |
| 45 | +#define STACK_ALLOC_NULL_PROTECTION_BITS 1 | |
| 45 | 46 | #define STACK_ALLOC_ORDER 2 /* 'Slab' size order for stack depot, 4 pages */ |
| 46 | 47 | #define STACK_ALLOC_SIZE (1LL << (PAGE_SHIFT + STACK_ALLOC_ORDER)) |
| 47 | 48 | #define STACK_ALLOC_ALIGN 4 |
| 48 | 49 | #define STACK_ALLOC_OFFSET_BITS (STACK_ALLOC_ORDER + PAGE_SHIFT - \ |
| 49 | 50 | STACK_ALLOC_ALIGN) |
| 50 | −#define STACK_ALLOC_INDEX_BITS (DEPOT_STACK_BITS - STACK_ALLOC_OFFSET_BITS) | |
| 51 | +#define STACK_ALLOC_INDEX_BITS (DEPOT_STACK_BITS - \ | |
| 52 | + STACK_ALLOC_NULL_PROTECTION_BITS - STACK_ALLOC_OFFSET_BITS) | |
| 51 | 53 | #define STACK_ALLOC_SLABS_CAP 1024 |
| 52 | 54 | #define STACK_ALLOC_MAX_SLABS \ |
| 53 | 55 | (((1LL << (STACK_ALLOC_INDEX_BITS)) < STACK_ALLOC_SLABS_CAP) ? \ |
| @@ -59,6 +61,7 @@ union handle_parts { · 5 unmodified lines | ||
| 59 | 61 | struct { |
| 60 | 62 | u32 slabindex : STACK_ALLOC_INDEX_BITS; |
| 61 | 63 | u32 offset : STACK_ALLOC_OFFSET_BITS; |
| 64 | + u32 valid : STACK_ALLOC_NULL_PROTECTION_BITS; | |
| 62 | 65 | }; |
| 63 | 66 | }; |
| 64 | 67 | |
| @@ -136,6 +139,7 @@ static struct stack_record *depot_alloc_stack(unsigned long *entries, int size, · 71 unmodified lines | ||
| 136 | 139 | stack->size = size; |
| 137 | 140 | stack->handle.slabindex = depot_index; |
| 138 | 141 | stack->handle.offset = depot_offset >> STACK_ALLOC_ALIGN; |
| 142 | + stack->handle.valid = 1; | |
| 139 | 143 | memcpy(stack->entries, entries, size * sizeof(unsigned long)); |
| 140 | 144 | depot_offset += required_size; |
| 141 | 145 | |
| @@ -210,10 +214,6 @@ depot_stack_handle_t depot_save_stack(struct stack_trace *trace, · 68 unmodified lines | ||
| 210 | 214 | goto fast_exit; |
| 211 | 215 | |
| 212 | 216 | hash = hash_stack(trace->entries, trace->nr_entries); |
| 213 | − /* Bad luck, we won't store this stack. */ | |
| 214 | − if (hash == 0) | |
| 215 | − goto exit; | |
| 216 | − | |
| 217 | 217 | bucket = &stack_table[hash & STACK_HASH_MASK]; |
| 218 | 218 | |
| 219 | 219 | /* |
| @@ -852,16 +852,8 @@ isolate_migratepages_range(struct compact_control *cc, unsigned long start_pfn, · 851 unmodified lines | ||
| 852 | 852 | pfn = isolate_migratepages_block(cc, pfn, block_end_pfn, |
| 853 | 853 | ISOLATE_UNEVICTABLE); |
| 854 | 854 | |
| 855 | − /* | |
| 856 | − * In case of fatal failure, release everything that might | |
| 857 | − * have been isolated in the previous iteration, and signal | |
| 858 | − * the failure back to caller. | |
| 859 | − */ | |
| 860 | − if (!pfn) { | |
| 861 | − putback_movable_pages(&cc->migratepages); | |
| 862 | − cc->nr_migratepages = 0; | |
| 855 | + if (!pfn) | |
| 863 | 856 | break; |
| 864 | − } | |
| 865 | 857 | |
| 866 | 858 | if (cc->nr_migratepages == COMPACT_CLUSTER_MAX) |
| 867 | 859 | break; |
| @@ -1741,7 +1733,7 @@ void compaction_unregister_node(struct node *node) · 873 unmodified lines | ||
| 1741 | 1733 | |
| 1742 | 1734 | static inline bool kcompactd_work_requested(pg_data_t *pgdat) |
| 1743 | 1735 | { |
| 1744 | − return pgdat->kcompactd_max_order > 0; | |
| 1736 | + return pgdat->kcompactd_max_order > 0 || kthread_should_stop(); | |
| 1745 | 1737 | } |
| 1746 | 1738 | |
| 1747 | 1739 | static bool kcompactd_node_suitable(pg_data_t *pgdat) |
| @@ -1805,6 +1797,8 @@ static void kcompactd_do_work(pg_data_t *pgdat) · 57 unmodified lines | ||
| 1805 | 1797 | INIT_LIST_HEAD(&cc.freepages); |
| 1806 | 1798 | INIT_LIST_HEAD(&cc.migratepages); |
| 1807 | 1799 | |
| 1800 | + if (kthread_should_stop()) | |
| 1801 | + return; | |
| 1808 | 1802 | status = compact_zone(zone, &cc); |
| 1809 | 1803 | |
| 1810 | 1804 | if (zone_watermark_ok(zone, cc.order, low_wmark_pages(zone), |
| @@ -232,7 +232,7 @@ retry: · 231 unmodified lines | ||
| 232 | 232 | return READ_ONCE(huge_zero_page); |
| 233 | 233 | } |
| 234 | 234 | |
| 235 | −static void put_huge_zero_page(void) | |
| 235 | +void put_huge_zero_page(void) | |
| 236 | 236 | { |
| 237 | 237 | /* |
| 238 | 238 | * Counter should never go to zero here. Only shrinker can put |
| @@ -1684,12 +1684,12 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, · 1445 unmodified lines | ||
| 1684 | 1684 | if (vma_is_dax(vma)) { |
| 1685 | 1685 | spin_unlock(ptl); |
| 1686 | 1686 | if (is_huge_zero_pmd(orig_pmd)) |
| 1687 | − put_huge_zero_page(); | |
| 1687 | + tlb_remove_page(tlb, pmd_page(orig_pmd)); | |
| 1688 | 1688 | } else if (is_huge_zero_pmd(orig_pmd)) { |
| 1689 | 1689 | pte_free(tlb->mm, pgtable_trans_huge_withdraw(tlb->mm, pmd)); |
| 1690 | 1690 | atomic_long_dec(&tlb->mm->nr_ptes); |
| 1691 | 1691 | spin_unlock(ptl); |
| 1692 | − put_huge_zero_page(); | |
| 1692 | + tlb_remove_page(tlb, pmd_page(orig_pmd)); | |
| 1693 | 1693 | } else { |
| 1694 | 1694 | struct page *page = pmd_page(orig_pmd); |
| 1695 | 1695 | page_remove_rmap(page, true); |
| @@ -1960,10 +1960,9 @@ int khugepaged_enter_vma_merge(struct vm_area_struct *vma, · 264 unmodified lines | ||
| 1960 | 1960 | * page fault if needed. |
| 1961 | 1961 | */ |
| 1962 | 1962 | return 0; |
| 1963 | − if (vma->vm_ops) | |
| 1963 | + if (vma->vm_ops || (vm_flags & VM_NO_THP)) | |
| 1964 | 1964 | /* khugepaged not yet working on file or special mappings */ |
| 1965 | 1965 | return 0; |
| 1966 | − VM_BUG_ON_VMA(vm_flags & VM_NO_THP, vma); | |
| 1967 | 1966 | hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; |
| 1968 | 1967 | hend = vma->vm_end & HPAGE_PMD_MASK; |
| 1969 | 1968 | if (hstart < hend) |
| @@ -2352,8 +2351,7 @@ static bool hugepage_vma_check(struct vm_area_struct *vma) · 382 unmodified lines | ||
| 2352 | 2351 | return false; |
| 2353 | 2352 | if (is_vma_temporary_stack(vma)) |
| 2354 | 2353 | return false; |
| 2355 | − VM_BUG_ON_VMA(vma->vm_flags & VM_NO_THP, vma); | |
| 2356 | − return true; | |
| 2354 | + return !(vma->vm_flags & VM_NO_THP); | |
| 2357 | 2355 | } |
| 2358 | 2356 | |
| 2359 | 2357 | static void collapse_huge_page(struct mm_struct *mm, |
| @@ -3454,7 +3452,7 @@ next: · 1094 unmodified lines | ||
| 3454 | 3452 | } |
| 3455 | 3453 | } |
| 3456 | 3454 | |
| 3457 | − pr_info("%lu of %lu THP split", split, total); | |
| 3455 | + pr_info("%lu of %lu THP split\n", split, total); | |
| 3458 | 3456 | |
| 3459 | 3457 | return 0; |
| 3460 | 3458 | } |
| @@ -3465,7 +3463,7 @@ static int __init split_huge_pages_debugfs(void) · 4 unmodified lines | ||
| 3465 | 3463 | { |
| 3466 | 3464 | void *ret; |
| 3467 | 3465 | |
| 3468 | − ret = debugfs_create_file("split_huge_pages", 0644, NULL, NULL, | |
| 3466 | + ret = debugfs_create_file("split_huge_pages", 0200, NULL, NULL, | |
| 3469 | 3467 | &split_huge_pages_fops); |
| 3470 | 3468 | if (!ret) |
| 3471 | 3469 | pr_warn("Failed to create split_huge_pages in debugfs"); |
| @@ -207,6 +207,7 @@ static void mem_cgroup_oom_notify(struct mem_cgroup *memcg); · 206 unmodified lines | ||
| 207 | 207 | /* "mc" and its members are protected by cgroup_mutex */ |
| 208 | 208 | static struct move_charge_struct { |
| 209 | 209 | spinlock_t lock; /* for from, to */ |
| 210 | + struct mm_struct *mm; | |
| 210 | 211 | struct mem_cgroup *from; |
| 211 | 212 | struct mem_cgroup *to; |
| 212 | 213 | unsigned long flags; |
| @@ -4667,6 +4668,8 @@ static void __mem_cgroup_clear_mc(void) · 4454 unmodified lines | ||
| 4667 | 4668 | |
| 4668 | 4669 | static void mem_cgroup_clear_mc(void) |
| 4669 | 4670 | { |
| 4671 | + struct mm_struct *mm = mc.mm; | |
| 4672 | + | |
| 4670 | 4673 | /* |
| 4671 | 4674 | * we must clear moving_task before waking up waiters at the end of |
| 4672 | 4675 | * task migration. |
| @@ -4676,7 +4679,10 @@ static void mem_cgroup_clear_mc(void) · 3 unmodified lines | ||
| 4676 | 4679 | spin_lock(&mc.lock); |
| 4677 | 4680 | mc.from = NULL; |
| 4678 | 4681 | mc.to = NULL; |
| 4682 | + mc.mm = NULL; | |
| 4679 | 4683 | spin_unlock(&mc.lock); |
| 4684 | + | |
| 4685 | + mmput(mm); | |
| 4680 | 4686 | } |
| 4681 | 4687 | |
| 4682 | 4688 | static int mem_cgroup_can_attach(struct cgroup_taskset *tset) |
| @@ -4733,6 +4739,7 @@ static int mem_cgroup_can_attach(struct cgroup_taskset *tset) · 50 unmodified lines | ||
| 4733 | 4739 | VM_BUG_ON(mc.moved_swap); |
| 4734 | 4740 | |
| 4735 | 4741 | spin_lock(&mc.lock); |
| 4742 | + mc.mm = mm; | |
| 4736 | 4743 | mc.from = from; |
| 4737 | 4744 | mc.to = memcg; |
| 4738 | 4745 | mc.flags = move_flags; |
| @@ -4742,8 +4749,9 @@ static int mem_cgroup_can_attach(struct cgroup_taskset *tset) · 3 unmodified lines | ||
| 4742 | 4749 | ret = mem_cgroup_precharge_mc(mm); |
| 4743 | 4750 | if (ret) |
| 4744 | 4751 | mem_cgroup_clear_mc(); |
| 4752 | + } else { | |
| 4753 | + mmput(mm); | |
| 4745 | 4754 | } |
| 4746 | − mmput(mm); | |
| 4747 | 4755 | return ret; |
| 4748 | 4756 | } |
| 4749 | 4757 | |
| @@ -4852,11 +4860,11 @@ put: /* get_mctgt_type() gets the page */ · 102 unmodified lines | ||
| 4852 | 4860 | return ret; |
| 4853 | 4861 | } |
| 4854 | 4862 | |
| 4855 | −static void mem_cgroup_move_charge(struct mm_struct *mm) | |
| 4863 | +static void mem_cgroup_move_charge(void) | |
| 4856 | 4864 | { |
| 4857 | 4865 | struct mm_walk mem_cgroup_move_charge_walk = { |
| 4858 | 4866 | .pmd_entry = mem_cgroup_move_charge_pte_range, |
| 4859 | − .mm = mm, | |
| 4867 | + .mm = mc.mm, | |
| 4860 | 4868 | }; |
| 4861 | 4869 | |
| 4862 | 4870 | lru_add_drain_all(); |
| @@ -4868,7 +4876,7 @@ static void mem_cgroup_move_charge(struct mm_struct *mm) · 5 unmodified lines | ||
| 4868 | 4876 | atomic_inc(&mc.from->moving_account); |
| 4869 | 4877 | synchronize_rcu(); |
| 4870 | 4878 | retry: |
| 4871 | − if (unlikely(!down_read_trylock(&mm->mmap_sem))) { | |
| 4879 | + if (unlikely(!down_read_trylock(&mc.mm->mmap_sem))) { | |
| 4872 | 4880 | /* |
| 4873 | 4881 | * Someone who are holding the mmap_sem might be waiting in |
| 4874 | 4882 | * waitq. So we cancel all extra charges, wake up all waiters, |
| @@ -4885,23 +4893,16 @@ retry: · 10 unmodified lines | ||
| 4885 | 4893 | * additional charge, the page walk just aborts. |
| 4886 | 4894 | */ |
| 4887 | 4895 | walk_page_range(0, ~0UL, &mem_cgroup_move_charge_walk); |
| 4888 | − up_read(&mm->mmap_sem); | |
| 4896 | + up_read(&mc.mm->mmap_sem); | |
| 4889 | 4897 | atomic_dec(&mc.from->moving_account); |
| 4890 | 4898 | } |
| 4891 | 4899 | |
| 4892 | −static void mem_cgroup_move_task(struct cgroup_taskset *tset) | |
| 4900 | +static void mem_cgroup_move_task(void) | |
| 4893 | 4901 | { |
| 4894 | − struct cgroup_subsys_state *css; | |
| 4895 | − struct task_struct *p = cgroup_taskset_first(tset, &css); | |
| 4896 | − struct mm_struct *mm = get_task_mm(p); | |
| 4897 | − | |
| 4898 | − if (mm) { | |
| 4899 | − if (mc.to) | |
| 4900 | − mem_cgroup_move_charge(mm); | |
| 4901 | − mmput(mm); | |
| 4902 | − } | |
| 4903 | − if (mc.to) | |
| 4902 | + if (mc.to) { | |
| 4903 | + mem_cgroup_move_charge(); | |
| 4904 | 4904 | mem_cgroup_clear_mc(); |
| 4905 | + } | |
| 4905 | 4906 | } |
| 4906 | 4907 | #else /* !CONFIG_MMU */ |
| 4907 | 4908 | static int mem_cgroup_can_attach(struct cgroup_taskset *tset) |
| @@ -4911,7 +4912,7 @@ static int mem_cgroup_can_attach(struct cgroup_taskset *tset) · 3 unmodified lines | ||
| 4911 | 4912 | static void mem_cgroup_cancel_attach(struct cgroup_taskset *tset) |
| 4912 | 4913 | { |
| 4913 | 4914 | } |
| 4914 | −static void mem_cgroup_move_task(struct cgroup_taskset *tset) | |
| 4915 | +static void mem_cgroup_move_task(void) | |
| 4915 | 4916 | { |
| 4916 | 4917 | } |
| 4917 | 4918 | #endif |
| @@ -5195,7 +5196,7 @@ struct cgroup_subsys memory_cgrp_subsys = { · 277 unmodified lines | ||
| 5195 | 5196 | .css_reset = mem_cgroup_css_reset, |
| 5196 | 5197 | .can_attach = mem_cgroup_can_attach, |
| 5197 | 5198 | .cancel_attach = mem_cgroup_cancel_attach, |
| 5198 | − .attach = mem_cgroup_move_task, | |
| 5199 | + .post_attach = mem_cgroup_move_task, | |
| 5199 | 5200 | .bind = mem_cgroup_bind, |
| 5200 | 5201 | .dfl_cftypes = memory_files, |
| 5201 | 5202 | .legacy_cftypes = mem_cgroup_legacy_files, |
| @@ -888,7 +888,15 @@ int get_hwpoison_page(struct page *page) · 887 unmodified lines | ||
| 888 | 888 | } |
| 889 | 889 | } |
| 890 | 890 | |
| 891 | − return get_page_unless_zero(head); | |
| 891 | + if (get_page_unless_zero(head)) { | |
| 892 | + if (head == compound_head(page)) | |
| 893 | + return 1; | |
| 894 | + | |
| 895 | + pr_info("MCE: %#lx cannot catch tail\n", page_to_pfn(page)); | |
| 896 | + put_page(head); | |
| 897 | + } | |
| 898 | + | |
| 899 | + return 0; | |
| 892 | 900 | } |
| 893 | 901 | EXPORT_SYMBOL_GPL(get_hwpoison_page); |
| 894 | 902 | |
| @@ -789,6 +789,46 @@ out: · 788 unmodified lines | ||
| 789 | 789 | return pfn_to_page(pfn); |
| 790 | 790 | } |
| 791 | 791 | |
| 792 | +#ifdef CONFIG_TRANSPARENT_HUGEPAGE | |
| 793 | +struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr, | |
| 794 | + pmd_t pmd) | |
| 795 | +{ | |
| 796 | + unsigned long pfn = pmd_pfn(pmd); | |
| 797 | + | |
| 798 | + /* | |
| 799 | + * There is no pmd_special() but there may be special pmds, e.g. | |
| 800 | + * in a direct-access (dax) mapping, so let's just replicate the | |
| 801 | + * !HAVE_PTE_SPECIAL case from vm_normal_page() here. | |
| 802 | + */ | |
| 803 | + if (unlikely(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP))) { | |
| 804 | + if (vma->vm_flags & VM_MIXEDMAP) { | |
| 805 | + if (!pfn_valid(pfn)) | |
| 806 | + return NULL; | |
| 807 | + goto out; | |
| 808 | + } else { | |
| 809 | + unsigned long off; | |
| 810 | + off = (addr - vma->vm_start) >> PAGE_SHIFT; | |
| 811 | + if (pfn == vma->vm_pgoff + off) | |
| 812 | + return NULL; | |
| 813 | + if (!is_cow_mapping(vma->vm_flags)) | |
| 814 | + return NULL; | |
| 815 | + } | |
| 816 | + } | |
| 817 | + | |
| 818 | + if (is_zero_pfn(pfn)) | |
| 819 | + return NULL; | |
| 820 | + if (unlikely(pfn > highest_memmap_pfn)) | |
| 821 | + return NULL; | |
| 822 | + | |
| 823 | + /* | |
| 824 | + * NOTE! We still have PageReserved() pages in the page tables. | |
| 825 | + * eg. VDSO mappings can cause them to exist. | |
| 826 | + */ | |
| 827 | +out: | |
| 828 | + return pfn_to_page(pfn); | |
| 829 | +} | |
| 830 | +#endif | |
| 831 | + | |
| 792 | 832 | /* |
| 793 | 833 | * copy one vm_area from one task to the other. Assumes the page tables |
| 794 | 834 | * already present in the new task to be cleared in the whole range |
| @@ -1182,15 +1222,8 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb, · 387 unmodified lines | ||
| 1182 | 1222 | next = pmd_addr_end(addr, end); |
| 1183 | 1223 | if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd)) { |
| 1184 | 1224 | if (next - addr != HPAGE_PMD_SIZE) { |
| 1185 | −#ifdef CONFIG_DEBUG_VM | |
| 1186 | − if (!rwsem_is_locked(&tlb->mm->mmap_sem)) { | |
| 1187 | − pr_err("%s: mmap_sem is unlocked! addr=0x%lx end=0x%lx vma->vm_start=0x%lx vma->vm_end=0x%lx\n", | |
| 1188 | − __func__, addr, end, | |
| 1189 | − vma->vm_start, | |
| 1190 | − vma->vm_end); | |
| 1191 | − BUG(); | |
| 1192 | − } | |
| 1193 | −#endif | |
| 1225 | + VM_BUG_ON_VMA(vma_is_anonymous(vma) && | |
| 1226 | + !rwsem_is_locked(&tlb->mm->mmap_sem), vma); | |
| 1194 | 1227 | split_huge_pmd(vma, pmd, addr); |
| 1195 | 1228 | } else if (zap_huge_pmd(tlb, vma, pmd, addr)) |
| 1196 | 1229 | goto next; |
| @@ -975,7 +975,13 @@ out: · 974 unmodified lines | ||
| 975 | 975 | dec_zone_page_state(page, NR_ISOLATED_ANON + |
| 976 | 976 | page_is_file_cache(page)); |
| 977 | 977 | /* Soft-offlined page shouldn't go through lru cache list */ |
| 978 | − if (reason == MR_MEMORY_FAILURE) { | |
| 978 | + if (reason == MR_MEMORY_FAILURE && rc == MIGRATEPAGE_SUCCESS) { | |
| 979 | + /* | |
| 980 | + * With this release, we free successfully migrated | |
| 981 | + * page and set PG_HWPoison on just freed page | |
| 982 | + * intentionally. Although it's rather weird, it's how | |
| 983 | + * HWPoison flag works at the moment. | |
| 984 | + */ | |
| 979 | 985 | put_page(page); |
| 980 | 986 | if (!test_set_page_hwpoison(page)) |
| 981 | 987 | num_poisoned_pages_inc(); |
| @@ -1910,7 +1910,8 @@ bool wb_over_bg_thresh(struct bdi_writeback *wb) · 1909 unmodified lines | ||
| 1910 | 1910 | if (gdtc->dirty > gdtc->bg_thresh) |
| 1911 | 1911 | return true; |
| 1912 | 1912 | |
| 1913 | − if (wb_stat(wb, WB_RECLAIMABLE) > __wb_calc_thresh(gdtc)) | |
| 1913 | + if (wb_stat(wb, WB_RECLAIMABLE) > | |
| 1914 | + wb_calc_thresh(gdtc->wb, gdtc->bg_thresh)) | |
| 1914 | 1915 | return true; |
| 1915 | 1916 | |
| 1916 | 1917 | if (mdtc) { |
| @@ -1924,7 +1925,8 @@ bool wb_over_bg_thresh(struct bdi_writeback *wb) · 7 unmodified lines | ||
| 1924 | 1925 | if (mdtc->dirty > mdtc->bg_thresh) |
| 1925 | 1926 | return true; |
| 1926 | 1927 | |
| 1927 | − if (wb_stat(wb, WB_RECLAIMABLE) > __wb_calc_thresh(mdtc)) | |
| 1928 | + if (wb_stat(wb, WB_RECLAIMABLE) > | |
| 1929 | + wb_calc_thresh(mdtc->wb, mdtc->bg_thresh)) | |
| 1928 | 1930 | return true; |
| 1929 | 1931 | } |
| 1930 | 1932 | |
| @@ -6485,7 +6485,7 @@ int __meminit init_per_zone_wmark_min(void) · 6484 unmodified lines | ||
| 6485 | 6485 | setup_per_zone_inactive_ratio(); |
| 6486 | 6486 | return 0; |
| 6487 | 6487 | } |
| 6488 | −module_init(init_per_zone_wmark_min) | |
| 6488 | +core_initcall(init_per_zone_wmark_min) | |
| 6489 | 6489 | |
| 6490 | 6490 | /* |
| 6491 | 6491 | * min_free_kbytes_sysctl_handler - just a wrapper around proc_dointvec() so |
| @@ -353,7 +353,11 @@ int swap_readpage(struct page *page) · 352 unmodified lines | ||
| 353 | 353 | |
| 354 | 354 | ret = bdev_read_page(sis->bdev, swap_page_sector(page), page); |
| 355 | 355 | if (!ret) { |
| 356 | − swap_slot_free_notify(page); | |
| 356 | + if (trylock_page(page)) { | |
| 357 | + swap_slot_free_notify(page); | |
| 358 | + unlock_page(page); | |
| 359 | + } | |
| 360 | + | |
| 357 | 361 | count_vm_event(PSWPIN); |
| 358 | 362 | return 0; |
| 359 | 363 | } |
| @@ -728,6 +728,11 @@ void release_pages(struct page **pages, int nr, bool cold) · 727 unmodified lines | ||
| 728 | 728 | zone = NULL; |
| 729 | 729 | } |
| 730 | 730 | |
| 731 | + if (is_huge_zero_page(page)) { | |
| 732 | + put_huge_zero_page(); | |
| 733 | + continue; | |
| 734 | + } | |
| 735 | + | |
| 731 | 736 | page = compound_head(page); |
| 732 | 737 | if (!put_page_testzero(page)) |
| 733 | 738 | continue; |
| @@ -2553,7 +2553,7 @@ static bool shrink_zones(struct zonelist *zonelist, struct scan_control *sc) · 2552 unmodified lines | ||
| 2553 | 2553 | sc->gfp_mask |= __GFP_HIGHMEM; |
| 2554 | 2554 | |
| 2555 | 2555 | for_each_zone_zonelist_nodemask(zone, z, zonelist, |
| 2556 | − requested_highidx, sc->nodemask) { | |
| 2556 | + gfp_zone(sc->gfp_mask), sc->nodemask) { | |
| 2557 | 2557 | enum zone_type classzone_idx; |
| 2558 | 2558 | |
| 2559 | 2559 | if (!populated_zone(zone)) |
| @@ -3318,6 +3318,20 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, · 758 unmodified lines | ||
| 3318 | 3318 | /* Try to sleep for a short interval */ |
| 3319 | 3319 | if (prepare_kswapd_sleep(pgdat, order, remaining, |
| 3320 | 3320 | balanced_classzone_idx)) { |
| 3321 | + /* | |
| 3322 | + * Compaction records what page blocks it recently failed to | |
| 3323 | + * isolate pages from and skips them in the future scanning. | |
| 3324 | + * When kswapd is going to sleep, it is reasonable to assume | |
| 3325 | + * that pages and compaction may succeed so reset the cache. | |
| 3326 | + */ | |
| 3327 | + reset_isolation_suitable(pgdat); | |
| 3328 | + | |
| 3329 | + /* | |
| 3330 | + * We have freed the memory, now we should compact it to make | |
| 3331 | + * allocation of the requested order possible. | |
| 3332 | + */ | |
| 3333 | + wakeup_kcompactd(pgdat, order, classzone_idx); | |
| 3334 | + | |
| 3321 | 3335 | remaining = schedule_timeout(HZ/10); |
| 3322 | 3336 | finish_wait(&pgdat->kswapd_wait, &wait); |
| 3323 | 3337 | prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE); |
| @@ -3341,20 +3355,6 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, · 17 unmodified lines | ||
| 3341 | 3355 | */ |
| 3342 | 3356 | set_pgdat_percpu_threshold(pgdat, calculate_normal_threshold); |
| 3343 | 3357 | |
| 3344 | − /* | |
| 3345 | − * Compaction records what page blocks it recently failed to | |
| 3346 | − * isolate pages from and skips them in the future scanning. | |
| 3347 | − * When kswapd is going to sleep, it is reasonable to assume | |
| 3348 | − * that pages and compaction may succeed so reset the cache. | |
| 3349 | − */ | |
| 3350 | − reset_isolation_suitable(pgdat); | |
| 3351 | − | |
| 3352 | − /* | |
| 3353 | − * We have freed the memory, now we should compact it to make | |
| 3354 | − * allocation of the requested order possible. | |
| 3355 | − */ | |
| 3356 | − wakeup_kcompactd(pgdat, order, classzone_idx); | |
| 3357 | − | |
| 3358 | 3358 | if (!kthread_should_stop()) |
| 3359 | 3359 | schedule(); |
| 3360 | 3360 | |
| @@ -170,6 +170,8 @@ static struct zswap_tree *zswap_trees[MAX_SWAPFILES]; · 169 unmodified lines | ||
| 170 | 170 | static LIST_HEAD(zswap_pools); |
| 171 | 171 | /* protects zswap_pools list modification */ |
| 172 | 172 | static DEFINE_SPINLOCK(zswap_pools_lock); |
| 173 | +/* pool counter to provide unique names to zpool */ | |
| 174 | +static atomic_t zswap_pools_count = ATOMIC_INIT(0); | |
| 173 | 175 | |
| 174 | 176 | /* used by param callback function */ |
| 175 | 177 | static bool zswap_init_started; |
| @@ -565,6 +567,7 @@ static struct zswap_pool *zswap_pool_find_get(char *type, char *compressor) · 389 unmodified lines | ||
| 565 | 567 | static struct zswap_pool *zswap_pool_create(char *type, char *compressor) |
| 566 | 568 | { |
| 567 | 569 | struct zswap_pool *pool; |
| 570 | + char name[38]; /* 'zswap' + 32 char (max) num + \0 */ | |
| 568 | 571 | gfp_t gfp = __GFP_NORETRY | __GFP_NOWARN | __GFP_KSWAPD_RECLAIM; |
| 569 | 572 | |
| 570 | 573 | pool = kzalloc(sizeof(*pool), GFP_KERNEL); |
| @@ -573,7 +576,10 @@ static struct zswap_pool *zswap_pool_create(char *type, char *compressor) · 2 unmodified lines | ||
| 573 | 576 | return NULL; |
| 574 | 577 | } |
| 575 | 578 | |
| 576 | − pool->zpool = zpool_create_pool(type, "zswap", gfp, &zswap_zpool_ops); | |
| 579 | + /* unique name for each pool specifically required by zsmalloc */ | |
| 580 | + snprintf(name, 38, "zswap%x", atomic_inc_return(&zswap_pools_count)); | |
| 581 | + | |
| 582 | + pool->zpool = zpool_create_pool(type, name, gfp, &zswap_zpool_ops); | |
| 577 | 583 | if (!pool->zpool) { |
| 578 | 584 | pr_err("%s zpool not available\n", type); |
| 579 | 585 | goto error; |
| @@ -32,10 +32,21 @@ · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | #include "bat_v_elp.h" |
| 34 | 34 | #include "bat_v_ogm.h" |
| 35 | +#include "hard-interface.h" | |
| 35 | 36 | #include "hash.h" |
| 36 | 37 | #include "originator.h" |
| 37 | 38 | #include "packet.h" |
| 38 | 39 | |
| 40 | +static void batadv_v_iface_activate(struct batadv_hard_iface *hard_iface) | |
| 41 | +{ | |
| 42 | + /* B.A.T.M.A.N. V does not use any queuing mechanism, therefore it can | |
| 43 | + * set the interface as ACTIVE right away, without any risk of race | |
| 44 | + * condition | |
| 45 | + */ | |
| 46 | + if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED) | |
| 47 | + hard_iface->if_status = BATADV_IF_ACTIVE; | |
| 48 | +} | |
| 49 | + | |
| 39 | 50 | static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface) |
| 40 | 51 | { |
| 41 | 52 | int ret; |
| @@ -274,6 +285,7 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, · 232 unmodified lines | ||
| 274 | 285 | |
| 275 | 286 | static struct batadv_algo_ops batadv_batman_v __read_mostly = { |
| 276 | 287 | .name = "BATMAN_V", |
| 288 | + .bat_iface_activate = batadv_v_iface_activate, | |
| 277 | 289 | .bat_iface_enable = batadv_v_iface_enable, |
| 278 | 290 | .bat_iface_disable = batadv_v_iface_disable, |
| 279 | 291 | .bat_iface_update_mac = batadv_v_iface_update_mac, |
| @@ -568,6 +568,7 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv, · 567 unmodified lines | ||
| 568 | 568 | * be sent to |
| 569 | 569 | * @bat_priv: the bat priv with all the soft interface information |
| 570 | 570 | * @ip_dst: ipv4 to look up in the DHT |
| 571 | + * @vid: VLAN identifier | |
| 571 | 572 | * |
| 572 | 573 | * An originator O is selected if and only if its DHT_ID value is one of three |
| 573 | 574 | * closest values (from the LEFT, with wrap around if needed) then the hash |
| @@ -576,7 +577,8 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv, · 2 unmodified lines | ||
| 576 | 577 | * Return: the candidate array of size BATADV_DAT_CANDIDATE_NUM. |
| 577 | 578 | */ |
| 578 | 579 | static struct batadv_dat_candidate * |
| 579 | −batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) | |
| 580 | +batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst, | |
| 581 | + unsigned short vid) | |
| 580 | 582 | { |
| 581 | 583 | int select; |
| 582 | 584 | batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key; |
| @@ -592,7 +594,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) · 9 unmodified lines | ||
| 592 | 594 | return NULL; |
| 593 | 595 | |
| 594 | 596 | dat.ip = ip_dst; |
| 595 | − dat.vid = 0; | |
| 597 | + dat.vid = vid; | |
| 596 | 598 | ip_key = (batadv_dat_addr_t)batadv_hash_dat(&dat, |
| 597 | 599 | BATADV_DAT_ADDR_MAX); |
| 598 | 600 | |
| @@ -612,6 +614,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) · 13 unmodified lines | ||
| 612 | 614 | * @bat_priv: the bat priv with all the soft interface information |
| 613 | 615 | * @skb: payload to send |
| 614 | 616 | * @ip: the DHT key |
| 617 | + * @vid: VLAN identifier | |
| 615 | 618 | * @packet_subtype: unicast4addr packet subtype to use |
| 616 | 619 | * |
| 617 | 620 | * This function copies the skb with pskb_copy() and is sent as unicast packet |
| @@ -622,7 +625,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) · 4 unmodified lines | ||
| 622 | 625 | */ |
| 623 | 626 | static bool batadv_dat_send_data(struct batadv_priv *bat_priv, |
| 624 | 627 | struct sk_buff *skb, __be32 ip, |
| 625 | − int packet_subtype) | |
| 628 | + unsigned short vid, int packet_subtype) | |
| 626 | 629 | { |
| 627 | 630 | int i; |
| 628 | 631 | bool ret = false; |
| @@ -631,7 +634,7 @@ static bool batadv_dat_send_data(struct batadv_priv *bat_priv, · 2 unmodified lines | ||
| 631 | 634 | struct sk_buff *tmp_skb; |
| 632 | 635 | struct batadv_dat_candidate *cand; |
| 633 | 636 | |
| 634 | − cand = batadv_dat_select_candidates(bat_priv, ip); | |
| 637 | + cand = batadv_dat_select_candidates(bat_priv, ip, vid); | |
| 635 | 638 | if (!cand) |
| 636 | 639 | goto out; |
| 637 | 640 | |
| @@ -1022,7 +1025,7 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, · 384 unmodified lines | ||
| 1022 | 1025 | ret = true; |
| 1023 | 1026 | } else { |
| 1024 | 1027 | /* Send the request to the DHT */ |
| 1025 | − ret = batadv_dat_send_data(bat_priv, skb, ip_dst, | |
| 1028 | + ret = batadv_dat_send_data(bat_priv, skb, ip_dst, vid, | |
| 1026 | 1029 | BATADV_P_DAT_DHT_GET); |
| 1027 | 1030 | } |
| 1028 | 1031 | out: |
| @@ -1150,8 +1153,8 @@ void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv, · 121 unmodified lines | ||
| 1150 | 1153 | /* Send the ARP reply to the candidates for both the IP addresses that |
| 1151 | 1154 | * the node obtained from the ARP reply |
| 1152 | 1155 | */ |
| 1153 | − batadv_dat_send_data(bat_priv, skb, ip_src, BATADV_P_DAT_DHT_PUT); | |
| 1154 | − batadv_dat_send_data(bat_priv, skb, ip_dst, BATADV_P_DAT_DHT_PUT); | |
| 1156 | + batadv_dat_send_data(bat_priv, skb, ip_src, vid, BATADV_P_DAT_DHT_PUT); | |
| 1157 | + batadv_dat_send_data(bat_priv, skb, ip_dst, vid, BATADV_P_DAT_DHT_PUT); | |
| 1155 | 1158 | } |
| 1156 | 1159 | |
| 1157 | 1160 | /** |
| @@ -407,6 +407,9 @@ batadv_hardif_activate_interface(struct batadv_hard_iface *hard_iface) · 406 unmodified lines | ||
| 407 | 407 | |
| 408 | 408 | batadv_update_min_mtu(hard_iface->soft_iface); |
| 409 | 409 | |
| 410 | + if (bat_priv->bat_algo_ops->bat_iface_activate) | |
| 411 | + bat_priv->bat_algo_ops->bat_iface_activate(hard_iface); | |
| 412 | + | |
| 410 | 413 | out: |
| 411 | 414 | if (primary_if) |
| 412 | 415 | batadv_hardif_put(primary_if); |
| @@ -572,8 +575,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface, · 159 unmodified lines | ||
| 572 | 575 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); |
| 573 | 576 | struct batadv_hard_iface *primary_if = NULL; |
| 574 | 577 | |
| 575 | − if (hard_iface->if_status == BATADV_IF_ACTIVE) | |
| 576 | − batadv_hardif_deactivate_interface(hard_iface); | |
| 578 | + batadv_hardif_deactivate_interface(hard_iface); | |
| 577 | 579 | |
| 578 | 580 | if (hard_iface->if_status != BATADV_IF_INACTIVE) |
| 579 | 581 | goto out; |
| @@ -250,7 +250,6 @@ static void batadv_neigh_node_release(struct kref *ref) · 249 unmodified lines | ||
| 250 | 250 | { |
| 251 | 251 | struct hlist_node *node_tmp; |
| 252 | 252 | struct batadv_neigh_node *neigh_node; |
| 253 | − struct batadv_hardif_neigh_node *hardif_neigh; | |
| 254 | 253 | struct batadv_neigh_ifinfo *neigh_ifinfo; |
| 255 | 254 | struct batadv_algo_ops *bao; |
| 256 | 255 | |
| @@ -262,13 +261,7 @@ static void batadv_neigh_node_release(struct kref *ref) · 5 unmodified lines | ||
| 262 | 261 | batadv_neigh_ifinfo_put(neigh_ifinfo); |
| 263 | 262 | } |
| 264 | 263 | |
| 265 | − hardif_neigh = batadv_hardif_neigh_get(neigh_node->if_incoming, | |
| 266 | − neigh_node->addr); | |
| 267 | − if (hardif_neigh) { | |
| 268 | − /* batadv_hardif_neigh_get() increases refcount too */ | |
| 269 | − batadv_hardif_neigh_put(hardif_neigh); | |
| 270 | − batadv_hardif_neigh_put(hardif_neigh); | |
| 271 | − } | |
| 264 | + batadv_hardif_neigh_put(neigh_node->hardif_neigh); | |
| 272 | 265 | |
| 273 | 266 | if (bao->bat_neigh_free) |
| 274 | 267 | bao->bat_neigh_free(neigh_node); |
| @@ -663,6 +656,11 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node, · 388 unmodified lines | ||
| 663 | 656 | ether_addr_copy(neigh_node->addr, neigh_addr); |
| 664 | 657 | neigh_node->if_incoming = hard_iface; |
| 665 | 658 | neigh_node->orig_node = orig_node; |
| 659 | + neigh_node->last_seen = jiffies; | |
| 660 | + | |
| 661 | + /* increment unique neighbor refcount */ | |
| 662 | + kref_get(&hardif_neigh->refcount); | |
| 663 | + neigh_node->hardif_neigh = hardif_neigh; | |
| 666 | 664 | |
| 667 | 665 | /* extra reference for return */ |
| 668 | 666 | kref_init(&neigh_node->refcount); |
| @@ -672,9 +670,6 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node, · 3 unmodified lines | ||
| 672 | 670 | hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); |
| 673 | 671 | spin_unlock_bh(&orig_node->neigh_list_lock); |
| 674 | 672 | |
| 675 | − /* increment unique neighbor refcount */ | |
| 676 | − kref_get(&hardif_neigh->refcount); | |
| 677 | − | |
| 678 | 673 | batadv_dbg(BATADV_DBG_BATMAN, orig_node->bat_priv, |
| 679 | 674 | "Creating new neighbor %pM for orig_node %pM on interface %s\n", |
| 680 | 675 | neigh_addr, orig_node->orig, hard_iface->net_dev->name); |
| @@ -105,6 +105,15 @@ static void _batadv_update_route(struct batadv_priv *bat_priv, · 104 unmodified lines | ||
| 105 | 105 | neigh_node = NULL; |
| 106 | 106 | |
| 107 | 107 | spin_lock_bh(&orig_node->neigh_list_lock); |
| 108 | + /* curr_router used earlier may not be the current orig_ifinfo->router | |
| 109 | + * anymore because it was dereferenced outside of the neigh_list_lock | |
| 110 | + * protected region. After the new best neighbor has replace the current | |
| 111 | + * best neighbor the reference counter needs to decrease. Consequently, | |
| 112 | + * the code needs to ensure the curr_router variable contains a pointer | |
| 113 | + * to the replaced best neighbor. | |
| 114 | + */ | |
| 115 | + curr_router = rcu_dereference_protected(orig_ifinfo->router, true); | |
| 116 | + | |
| 108 | 117 | rcu_assign_pointer(orig_ifinfo->router, neigh_node); |
| 109 | 118 | spin_unlock_bh(&orig_node->neigh_list_lock); |
| 110 | 119 | batadv_orig_ifinfo_put(orig_ifinfo); |
| @@ -675,6 +675,9 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv, · 674 unmodified lines | ||
| 675 | 675 | |
| 676 | 676 | if (pending) { |
| 677 | 677 | hlist_del(&forw_packet->list); |
| 678 | + if (!forw_packet->own) | |
| 679 | + atomic_inc(&bat_priv->bcast_queue_left); | |
| 680 | + | |
| 678 | 681 | batadv_forw_packet_free(forw_packet); |
| 679 | 682 | } |
| 680 | 683 | } |
| @@ -702,6 +705,9 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv, · 21 unmodified lines | ||
| 702 | 705 | |
| 703 | 706 | if (pending) { |
| 704 | 707 | hlist_del(&forw_packet->list); |
| 708 | + if (!forw_packet->own) | |
| 709 | + atomic_inc(&bat_priv->batman_queue_left); | |
| 710 | + | |
| 705 | 711 | batadv_forw_packet_free(forw_packet); |
| 706 | 712 | } |
| 707 | 713 | } |
| @@ -408,11 +408,17 @@ void batadv_interface_rx(struct net_device *soft_iface, · 407 unmodified lines | ||
| 408 | 408 | */ |
| 409 | 409 | nf_reset(skb); |
| 410 | 410 | |
| 411 | + if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) | |
| 412 | + goto dropped; | |
| 413 | + | |
| 411 | 414 | vid = batadv_get_vid(skb, 0); |
| 412 | 415 | ethhdr = eth_hdr(skb); |
| 413 | 416 | |
| 414 | 417 | switch (ntohs(ethhdr->h_proto)) { |
| 415 | 418 | case ETH_P_8021Q: |
| 419 | + if (!pskb_may_pull(skb, VLAN_ETH_HLEN)) | |
| 420 | + goto dropped; | |
| 421 | + | |
| 416 | 422 | vhdr = (struct vlan_ethhdr *)skb->data; |
| 417 | 423 | |
| 418 | 424 | if (vhdr->h_vlan_encapsulated_proto != ethertype) |
| @@ -424,8 +430,6 @@ void batadv_interface_rx(struct net_device *soft_iface, · 5 unmodified lines | ||
| 424 | 430 | } |
| 425 | 431 | |
| 426 | 432 | /* skb->dev & skb->pkt_type are set here */ |
| 427 | − if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) | |
| 428 | − goto dropped; | |
| 429 | 433 | skb->protocol = eth_type_trans(skb, soft_iface); |
| 430 | 434 | |
| 431 | 435 | /* should not be necessary anymore as we use skb_pull_rcsum() |
| @@ -215,6 +215,8 @@ static void batadv_tt_local_entry_release(struct kref *ref) · 214 unmodified lines | ||
| 215 | 215 | tt_local_entry = container_of(ref, struct batadv_tt_local_entry, |
| 216 | 216 | common.refcount); |
| 217 | 217 | |
| 218 | + batadv_softif_vlan_put(tt_local_entry->vlan); | |
| 219 | + | |
| 218 | 220 | kfree_rcu(tt_local_entry, common.rcu); |
| 219 | 221 | } |
| 220 | 222 | |
| @@ -673,6 +675,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr, · 452 unmodified lines | ||
| 673 | 675 | kref_get(&tt_local->common.refcount); |
| 674 | 676 | tt_local->last_seen = jiffies; |
| 675 | 677 | tt_local->common.added_at = tt_local->last_seen; |
| 678 | + tt_local->vlan = vlan; | |
| 676 | 679 | |
| 677 | 680 | /* the batman interface mac and multicast addresses should never be |
| 678 | 681 | * purged |
| @@ -991,7 +994,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) · 312 unmodified lines | ||
| 991 | 994 | struct batadv_tt_common_entry *tt_common_entry; |
| 992 | 995 | struct batadv_tt_local_entry *tt_local; |
| 993 | 996 | struct batadv_hard_iface *primary_if; |
| 994 | − struct batadv_softif_vlan *vlan; | |
| 995 | 997 | struct hlist_head *head; |
| 996 | 998 | unsigned short vid; |
| 997 | 999 | u32 i; |
| @@ -1027,14 +1029,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) · 29 unmodified lines | ||
| 1027 | 1029 | last_seen_msecs = last_seen_msecs % 1000; |
| 1028 | 1030 | |
| 1029 | 1031 | no_purge = tt_common_entry->flags & np_flag; |
| 1030 | − | |
| 1031 | − vlan = batadv_softif_vlan_get(bat_priv, vid); | |
| 1032 | − if (!vlan) { | |
| 1033 | − seq_printf(seq, "Cannot retrieve VLAN %d\n", | |
| 1034 | − BATADV_PRINT_VID(vid)); | |
| 1035 | − continue; | |
| 1036 | − } | |
| 1037 | − | |
| 1038 | 1032 | seq_printf(seq, |
| 1039 | 1033 | " * %pM %4i [%c%c%c%c%c%c] %3u.%03u (%#.8x)\n", |
| 1040 | 1034 | tt_common_entry->addr, |
| @@ -1052,9 +1046,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) · 11 unmodified lines | ||
| 1052 | 1046 | BATADV_TT_CLIENT_ISOLA) ? 'I' : '.'), |
| 1053 | 1047 | no_purge ? 0 : last_seen_secs, |
| 1054 | 1048 | no_purge ? 0 : last_seen_msecs, |
| 1055 | − vlan->tt.crc); | |
| 1056 | − | |
| 1057 | − batadv_softif_vlan_put(vlan); | |
| 1049 | + tt_local->vlan->tt.crc); | |
| 1058 | 1050 | } |
| 1059 | 1051 | rcu_read_unlock(); |
| 1060 | 1052 | } |
| @@ -1099,7 +1091,6 @@ u16 batadv_tt_local_remove(struct batadv_priv *bat_priv, const u8 *addr, · 38 unmodified lines | ||
| 1099 | 1091 | { |
| 1100 | 1092 | struct batadv_tt_local_entry *tt_local_entry; |
| 1101 | 1093 | u16 flags, curr_flags = BATADV_NO_FLAGS; |
| 1102 | − struct batadv_softif_vlan *vlan; | |
| 1103 | 1094 | void *tt_entry_exists; |
| 1104 | 1095 | |
| 1105 | 1096 | tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid); |
| @@ -1139,14 +1130,6 @@ u16 batadv_tt_local_remove(struct batadv_priv *bat_priv, const u8 *addr, · 33 unmodified lines | ||
| 1139 | 1130 | /* extra call to free the local tt entry */ |
| 1140 | 1131 | batadv_tt_local_entry_put(tt_local_entry); |
| 1141 | 1132 | |
| 1142 | − /* decrease the reference held for this vlan */ | |
| 1143 | − vlan = batadv_softif_vlan_get(bat_priv, vid); | |
| 1144 | − if (!vlan) | |
| 1145 | − goto out; | |
| 1146 | − | |
| 1147 | − batadv_softif_vlan_put(vlan); | |
| 1148 | − batadv_softif_vlan_put(vlan); | |
| 1149 | − | |
| 1150 | 1133 | out: |
| 1151 | 1134 | if (tt_local_entry) |
| 1152 | 1135 | batadv_tt_local_entry_put(tt_local_entry); |
| @@ -1219,7 +1202,6 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) · 66 unmodified lines | ||
| 1219 | 1202 | spinlock_t *list_lock; /* protects write access to the hash lists */ |
| 1220 | 1203 | struct batadv_tt_common_entry *tt_common_entry; |
| 1221 | 1204 | struct batadv_tt_local_entry *tt_local; |
| 1222 | − struct batadv_softif_vlan *vlan; | |
| 1223 | 1205 | struct hlist_node *node_tmp; |
| 1224 | 1206 | struct hlist_head *head; |
| 1225 | 1207 | u32 i; |
| @@ -1241,14 +1223,6 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) · 15 unmodified lines | ||
| 1241 | 1223 | struct batadv_tt_local_entry, |
| 1242 | 1224 | common); |
| 1243 | 1225 | |
| 1244 | − /* decrease the reference held for this vlan */ | |
| 1245 | − vlan = batadv_softif_vlan_get(bat_priv, | |
| 1246 | − tt_common_entry->vid); | |
| 1247 | − if (vlan) { | |
| 1248 | − batadv_softif_vlan_put(vlan); | |
| 1249 | − batadv_softif_vlan_put(vlan); | |
| 1250 | − } | |
| 1251 | − | |
| 1252 | 1226 | batadv_tt_local_entry_put(tt_local); |
| 1253 | 1227 | } |
| 1254 | 1228 | spin_unlock_bh(list_lock); |
| @@ -3309,7 +3283,6 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) · 2054 unmodified lines | ||
| 3309 | 3283 | struct batadv_hashtable *hash = bat_priv->tt.local_hash; |
| 3310 | 3284 | struct batadv_tt_common_entry *tt_common; |
| 3311 | 3285 | struct batadv_tt_local_entry *tt_local; |
| 3312 | − struct batadv_softif_vlan *vlan; | |
| 3313 | 3286 | struct hlist_node *node_tmp; |
| 3314 | 3287 | struct hlist_head *head; |
| 3315 | 3288 | spinlock_t *list_lock; /* protects write access to the hash lists */ |
| @@ -3339,13 +3312,6 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) · 23 unmodified lines | ||
| 3339 | 3312 | struct batadv_tt_local_entry, |
| 3340 | 3313 | common); |
| 3341 | 3314 | |
| 3342 | − /* decrease the reference held for this vlan */ | |
| 3343 | − vlan = batadv_softif_vlan_get(bat_priv, tt_common->vid); | |
| 3344 | − if (vlan) { | |
| 3345 | − batadv_softif_vlan_put(vlan); | |
| 3346 | − batadv_softif_vlan_put(vlan); | |
| 3347 | − } | |
| 3348 | − | |
| 3349 | 3315 | batadv_tt_local_entry_put(tt_local); |
| 3350 | 3316 | } |
| 3351 | 3317 | spin_unlock_bh(list_lock); |
| @@ -433,6 +433,7 @@ struct batadv_hardif_neigh_node { · 432 unmodified lines | ||
| 433 | 433 | * @ifinfo_lock: lock protecting private ifinfo members and list |
| 434 | 434 | * @if_incoming: pointer to incoming hard-interface |
| 435 | 435 | * @last_seen: when last packet via this neighbor was received |
| 436 | + * @hardif_neigh: hardif_neigh of this neighbor | |
| 436 | 437 | * @refcount: number of contexts the object is used |
| 437 | 438 | * @rcu: struct used for freeing in an RCU-safe manner |
| 438 | 439 | */ |
| @@ -444,6 +445,7 @@ struct batadv_neigh_node { · 5 unmodified lines | ||
| 444 | 445 | spinlock_t ifinfo_lock; /* protects ifinfo_list and its members */ |
| 445 | 446 | struct batadv_hard_iface *if_incoming; |
| 446 | 447 | unsigned long last_seen; |
| 448 | + struct batadv_hardif_neigh_node *hardif_neigh; | |
| 447 | 449 | struct kref refcount; |
| 448 | 450 | struct rcu_head rcu; |
| 449 | 451 | }; |
| @@ -1073,10 +1075,12 @@ struct batadv_tt_common_entry { · 623 unmodified lines | ||
| 1073 | 1075 | * struct batadv_tt_local_entry - translation table local entry data |
| 1074 | 1076 | * @common: general translation table data |
| 1075 | 1077 | * @last_seen: timestamp used for purging stale tt local entries |
| 1078 | + * @vlan: soft-interface vlan of the entry | |
| 1076 | 1079 | */ |
| 1077 | 1080 | struct batadv_tt_local_entry { |
| 1078 | 1081 | struct batadv_tt_common_entry common; |
| 1079 | 1082 | unsigned long last_seen; |
| 1083 | + struct batadv_softif_vlan *vlan; | |
| 1080 | 1084 | }; |
| 1081 | 1085 | |
| 1082 | 1086 | /** |
| @@ -1250,6 +1254,8 @@ struct batadv_forw_packet { · 167 unmodified lines | ||
| 1250 | 1254 | * struct batadv_algo_ops - mesh algorithm callbacks |
| 1251 | 1255 | * @list: list node for the batadv_algo_list |
| 1252 | 1256 | * @name: name of the algorithm |
| 1257 | + * @bat_iface_activate: start routing mechanisms when hard-interface is brought | |
| 1258 | + * up | |
| 1253 | 1259 | * @bat_iface_enable: init routing info when hard-interface is enabled |
| 1254 | 1260 | * @bat_iface_disable: de-init routing info when hard-interface is disabled |
| 1255 | 1261 | * @bat_iface_update_mac: (re-)init mac addresses of the protocol information |
| @@ -1277,6 +1283,7 @@ struct batadv_forw_packet { · 21 unmodified lines | ||
| 1277 | 1283 | struct batadv_algo_ops { |
| 1278 | 1284 | struct hlist_node list; |
| 1279 | 1285 | char *name; |
| 1286 | + void (*bat_iface_activate)(struct batadv_hard_iface *hard_iface); | |
| 1280 | 1287 | int (*bat_iface_enable)(struct batadv_hard_iface *hard_iface); |
| 1281 | 1288 | void (*bat_iface_disable)(struct batadv_hard_iface *hard_iface); |
| 1282 | 1289 | void (*bat_iface_update_mac)(struct batadv_hard_iface *hard_iface); |
| @@ -61,6 +61,19 @@ static void __mdb_entry_fill_flags(struct br_mdb_entry *e, unsigned char flags) · 60 unmodified lines | ||
| 61 | 61 | e->flags |= MDB_FLAGS_OFFLOAD; |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | +static void __mdb_entry_to_br_ip(struct br_mdb_entry *entry, struct br_ip *ip) | |
| 65 | +{ | |
| 66 | + memset(ip, 0, sizeof(struct br_ip)); | |
| 67 | + ip->vid = entry->vid; | |
| 68 | + ip->proto = entry->addr.proto; | |
| 69 | + if (ip->proto == htons(ETH_P_IP)) | |
| 70 | + ip->u.ip4 = entry->addr.u.ip4; | |
| 71 | +#if IS_ENABLED(CONFIG_IPV6) | |
| 72 | + else | |
| 73 | + ip->u.ip6 = entry->addr.u.ip6; | |
| 74 | +#endif | |
| 75 | +} | |
| 76 | + | |
| 64 | 77 | static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, |
| 65 | 78 | struct net_device *dev) |
| 66 | 79 | { |
| @@ -243,9 +256,45 @@ static inline size_t rtnl_mdb_nlmsg_size(void) · 176 unmodified lines | ||
| 243 | 256 | + nla_total_size(sizeof(struct br_mdb_entry)); |
| 244 | 257 | } |
| 245 | 258 | |
| 246 | −static void __br_mdb_notify(struct net_device *dev, struct br_mdb_entry *entry, | |
| 247 | − int type, struct net_bridge_port_group *pg) | |
| 259 | +struct br_mdb_complete_info { | |
| 260 | + struct net_bridge_port *port; | |
| 261 | + struct br_ip ip; | |
| 262 | +}; | |
| 263 | + | |
| 264 | +static void br_mdb_complete(struct net_device *dev, int err, void *priv) | |
| 248 | 265 | { |
| 266 | + struct br_mdb_complete_info *data = priv; | |
| 267 | + struct net_bridge_port_group __rcu **pp; | |
| 268 | + struct net_bridge_port_group *p; | |
| 269 | + struct net_bridge_mdb_htable *mdb; | |
| 270 | + struct net_bridge_mdb_entry *mp; | |
| 271 | + struct net_bridge_port *port = data->port; | |
| 272 | + struct net_bridge *br = port->br; | |
| 273 | + | |
| 274 | + if (err) | |
| 275 | + goto err; | |
| 276 | + | |
| 277 | + spin_lock_bh(&br->multicast_lock); | |
| 278 | + mdb = mlock_dereference(br->mdb, br); | |
| 279 | + mp = br_mdb_ip_get(mdb, &data->ip); | |
| 280 | + if (!mp) | |
| 281 | + goto out; | |
| 282 | + for (pp = &mp->ports; (p = mlock_dereference(*pp, br)) != NULL; | |
| 283 | + pp = &p->next) { | |
| 284 | + if (p->port != port) | |
| 285 | + continue; | |
| 286 | + p->flags |= MDB_PG_FLAGS_OFFLOAD; | |
| 287 | + } | |
| 288 | +out: | |
| 289 | + spin_unlock_bh(&br->multicast_lock); | |
| 290 | +err: | |
| 291 | + kfree(priv); | |
| 292 | +} | |
| 293 | + | |
| 294 | +static void __br_mdb_notify(struct net_device *dev, struct net_bridge_port *p, | |
| 295 | + struct br_mdb_entry *entry, int type) | |
| 296 | +{ | |
| 297 | + struct br_mdb_complete_info *complete_info; | |
| 249 | 298 | struct switchdev_obj_port_mdb mdb = { |
| 250 | 299 | .obj = { |
| 251 | 300 | .id = SWITCHDEV_OBJ_ID_PORT_MDB, |
| @@ -268,9 +317,14 @@ static void __br_mdb_notify(struct net_device *dev, struct br_mdb_entry *entry, · 16 unmodified lines | ||
| 268 | 317 | |
| 269 | 318 | mdb.obj.orig_dev = port_dev; |
| 270 | 319 | if (port_dev && type == RTM_NEWMDB) { |
| 271 | − err = switchdev_port_obj_add(port_dev, &mdb.obj); | |
| 272 | − if (!err && pg) | |
| 273 | − pg->flags |= MDB_PG_FLAGS_OFFLOAD; | |
| 320 | + complete_info = kmalloc(sizeof(*complete_info), GFP_ATOMIC); | |
| 321 | + if (complete_info) { | |
| 322 | + complete_info->port = p; | |
| 323 | + __mdb_entry_to_br_ip(entry, &complete_info->ip); | |
| 324 | + mdb.obj.complete_priv = complete_info; | |
| 325 | + mdb.obj.complete = br_mdb_complete; | |
| 326 | + switchdev_port_obj_add(port_dev, &mdb.obj); | |
| 327 | + } | |
| 274 | 328 | } else if (port_dev && type == RTM_DELMDB) { |
| 275 | 329 | switchdev_port_obj_del(port_dev, &mdb.obj); |
| 276 | 330 | } |
| @@ -291,21 +345,21 @@ errout: · 14 unmodified lines | ||
| 291 | 345 | rtnl_set_sk_err(net, RTNLGRP_MDB, err); |
| 292 | 346 | } |
| 293 | 347 | |
| 294 | −void br_mdb_notify(struct net_device *dev, struct net_bridge_port_group *pg, | |
| 295 | − int type) | |
| 348 | +void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, | |
| 349 | + struct br_ip *group, int type, u8 flags) | |
| 296 | 350 | { |
| 297 | 351 | struct br_mdb_entry entry; |
| 298 | 352 | |
| 299 | 353 | memset(&entry, 0, sizeof(entry)); |
| 300 | − entry.ifindex = pg->port->dev->ifindex; | |
| 301 | − entry.addr.proto = pg->addr.proto; | |
| 302 | − entry.addr.u.ip4 = pg->addr.u.ip4; | |
| 354 | + entry.ifindex = port->dev->ifindex; | |
| 355 | + entry.addr.proto = group->proto; | |
| 356 | + entry.addr.u.ip4 = group->u.ip4; | |
| 303 | 357 | #if IS_ENABLED(CONFIG_IPV6) |
| 304 | − entry.addr.u.ip6 = pg->addr.u.ip6; | |
| 358 | + entry.addr.u.ip6 = group->u.ip6; | |
| 305 | 359 | #endif |
| 306 | − entry.vid = pg->addr.vid; | |
| 307 | − __mdb_entry_fill_flags(&entry, pg->flags); | |
| 308 | − __br_mdb_notify(dev, &entry, type, pg); | |
| 360 | + entry.vid = group->vid; | |
| 361 | + __mdb_entry_fill_flags(&entry, flags); | |
| 362 | + __br_mdb_notify(dev, port, &entry, type); | |
| 309 | 363 | } |
| 310 | 364 | |
| 311 | 365 | static int nlmsg_populate_rtr_fill(struct sk_buff *skb, |
| @@ -450,8 +504,7 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh, · 138 unmodified lines | ||
| 450 | 504 | } |
| 451 | 505 | |
| 452 | 506 | static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, |
| 453 | − struct br_ip *group, unsigned char state, | |
| 454 | − struct net_bridge_port_group **pg) | |
| 507 | + struct br_ip *group, unsigned char state) | |
| 455 | 508 | { |
| 456 | 509 | struct net_bridge_mdb_entry *mp; |
| 457 | 510 | struct net_bridge_port_group *p; |
| @@ -482,7 +535,6 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, · 24 unmodified lines | ||
| 482 | 535 | if (unlikely(!p)) |
| 483 | 536 | return -ENOMEM; |
| 484 | 537 | rcu_assign_pointer(*pp, p); |
| 485 | − *pg = p; | |
| 486 | 538 | if (state == MDB_TEMPORARY) |
| 487 | 539 | mod_timer(&p->timer, now + br->multicast_membership_interval); |
| 488 | 540 | |
| @@ -490,8 +542,7 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, · 1 unmodified line | ||
| 490 | 542 | } |
| 491 | 543 | |
| 492 | 544 | static int __br_mdb_add(struct net *net, struct net_bridge *br, |
| 493 | − struct br_mdb_entry *entry, | |
| 494 | − struct net_bridge_port_group **pg) | |
| 545 | + struct br_mdb_entry *entry) | |
| 495 | 546 | { |
| 496 | 547 | struct br_ip ip; |
| 497 | 548 | struct net_device *dev; |
| @@ -509,18 +560,10 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br, · 11 unmodified lines | ||
| 509 | 560 | if (!p || p->br != br || p->state == BR_STATE_DISABLED) |
| 510 | 561 | return -EINVAL; |
| 511 | 562 | |
| 512 | − memset(&ip, 0, sizeof(ip)); | |
| 513 | − ip.vid = entry->vid; | |
| 514 | − ip.proto = entry->addr.proto; | |
| 515 | − if (ip.proto == htons(ETH_P_IP)) | |
| 516 | − ip.u.ip4 = entry->addr.u.ip4; | |
| 517 | −#if IS_ENABLED(CONFIG_IPV6) | |
| 518 | − else | |
| 519 | − ip.u.ip6 = entry->addr.u.ip6; | |
| 520 | −#endif | |
| 563 | + __mdb_entry_to_br_ip(entry, &ip); | |
| 521 | 564 | |
| 522 | 565 | spin_lock_bh(&br->multicast_lock); |
| 523 | − ret = br_mdb_add_group(br, p, &ip, entry->state, pg); | |
| 566 | + ret = br_mdb_add_group(br, p, &ip, entry->state); | |
| 524 | 567 | spin_unlock_bh(&br->multicast_lock); |
| 525 | 568 | return ret; |
| 526 | 569 | } |
| @@ -528,7 +571,6 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br, · 1 unmodified line | ||
| 528 | 571 | static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh) |
| 529 | 572 | { |
| 530 | 573 | struct net *net = sock_net(skb->sk); |
| 531 | − struct net_bridge_port_group *pg; | |
| 532 | 574 | struct net_bridge_vlan_group *vg; |
| 533 | 575 | struct net_device *dev, *pdev; |
| 534 | 576 | struct br_mdb_entry *entry; |
| @@ -558,15 +600,15 @@ static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh) · 23 unmodified lines | ||
| 558 | 600 | if (br_vlan_enabled(br) && vg && entry->vid == 0) { |
| 559 | 601 | list_for_each_entry(v, &vg->vlan_list, vlist) { |
| 560 | 602 | entry->vid = v->vid; |
| 561 | − err = __br_mdb_add(net, br, entry, &pg); | |
| 603 | + err = __br_mdb_add(net, br, entry); | |
| 562 | 604 | if (err) |
| 563 | 605 | break; |
| 564 | − __br_mdb_notify(dev, entry, RTM_NEWMDB, pg); | |
| 606 | + __br_mdb_notify(dev, p, entry, RTM_NEWMDB); | |
| 565 | 607 | } |
| 566 | 608 | } else { |
| 567 | − err = __br_mdb_add(net, br, entry, &pg); | |
| 609 | + err = __br_mdb_add(net, br, entry); | |
| 568 | 610 | if (!err) |
| 569 | − __br_mdb_notify(dev, entry, RTM_NEWMDB, pg); | |
| 611 | + __br_mdb_notify(dev, p, entry, RTM_NEWMDB); | |
| 570 | 612 | } |
| 571 | 613 | |
| 572 | 614 | return err; |
| @@ -584,15 +626,7 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry) · 11 unmodified lines | ||
| 584 | 626 | if (!netif_running(br->dev) || br->multicast_disabled) |
| 585 | 627 | return -EINVAL; |
| 586 | 628 | |
| 587 | − memset(&ip, 0, sizeof(ip)); | |
| 588 | − ip.vid = entry->vid; | |
| 589 | − ip.proto = entry->addr.proto; | |
| 590 | − if (ip.proto == htons(ETH_P_IP)) | |
| 591 | − ip.u.ip4 = entry->addr.u.ip4; | |
| 592 | −#if IS_ENABLED(CONFIG_IPV6) | |
| 593 | − else | |
| 594 | − ip.u.ip6 = entry->addr.u.ip6; | |
| 595 | −#endif | |
| 629 | + __mdb_entry_to_br_ip(entry, &ip); | |
| 596 | 630 | |
| 597 | 631 | spin_lock_bh(&br->multicast_lock); |
| 598 | 632 | mdb = mlock_dereference(br->mdb, br); |
| @@ -662,12 +696,12 @@ static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh) · 63 unmodified lines | ||
| 662 | 696 | entry->vid = v->vid; |
| 663 | 697 | err = __br_mdb_del(br, entry); |
| 664 | 698 | if (!err) |
| 665 | − __br_mdb_notify(dev, entry, RTM_DELMDB, NULL); | |
| 699 | + __br_mdb_notify(dev, p, entry, RTM_DELMDB); | |
| 666 | 700 | } |
| 667 | 701 | } else { |
| 668 | 702 | err = __br_mdb_del(br, entry); |
| 669 | 703 | if (!err) |
| 670 | − __br_mdb_notify(dev, entry, RTM_DELMDB, NULL); | |
| 704 | + __br_mdb_notify(dev, p, entry, RTM_DELMDB); | |
| 671 | 705 | } |
| 672 | 706 | |
| 673 | 707 | return err; |
| @@ -283,7 +283,8 @@ static void br_multicast_del_pg(struct net_bridge *br, · 282 unmodified lines | ||
| 283 | 283 | rcu_assign_pointer(*pp, p->next); |
| 284 | 284 | hlist_del_init(&p->mglist); |
| 285 | 285 | del_timer(&p->timer); |
| 286 | − br_mdb_notify(br->dev, p, RTM_DELMDB); | |
| 286 | + br_mdb_notify(br->dev, p->port, &pg->addr, RTM_DELMDB, | |
| 287 | + p->flags); | |
| 287 | 288 | call_rcu_bh(&p->rcu, br_multicast_free_pg); |
| 288 | 289 | |
| 289 | 290 | if (!mp->ports && !mp->mglist && |
| @@ -705,7 +706,7 @@ static int br_multicast_add_group(struct net_bridge *br, · 415 unmodified lines | ||
| 705 | 706 | if (unlikely(!p)) |
| 706 | 707 | goto err; |
| 707 | 708 | rcu_assign_pointer(*pp, p); |
| 708 | − br_mdb_notify(br->dev, p, RTM_NEWMDB); | |
| 709 | + br_mdb_notify(br->dev, port, group, RTM_NEWMDB, 0); | |
| 709 | 710 | |
| 710 | 711 | found: |
| 711 | 712 | mod_timer(&p->timer, now + br->multicast_membership_interval); |
| @@ -1461,7 +1462,8 @@ br_multicast_leave_group(struct net_bridge *br, · 749 unmodified lines | ||
| 1461 | 1462 | hlist_del_init(&p->mglist); |
| 1462 | 1463 | del_timer(&p->timer); |
| 1463 | 1464 | call_rcu_bh(&p->rcu, br_multicast_free_pg); |
| 1464 | − br_mdb_notify(br->dev, p, RTM_DELMDB); | |
| 1465 | + br_mdb_notify(br->dev, port, group, RTM_DELMDB, | |
| 1466 | + p->flags); | |
| 1465 | 1467 | |
| 1466 | 1468 | if (!mp->ports && !mp->mglist && |
| 1467 | 1469 | netif_running(br->dev)) |
| @@ -560,8 +560,8 @@ br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group, · 559 unmodified lines | ||
| 560 | 560 | unsigned char flags); |
| 561 | 561 | void br_mdb_init(void); |
| 562 | 562 | void br_mdb_uninit(void); |
| 563 | −void br_mdb_notify(struct net_device *dev, struct net_bridge_port_group *pg, | |
| 564 | − int type); | |
| 563 | +void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, | |
| 564 | + struct br_ip *group, int type, u8 flags); | |
| 565 | 565 | void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, |
| 566 | 566 | int type); |
| 567 | 567 | |
| @@ -293,13 +293,9 @@ int ceph_auth_create_authorizer(struct ceph_auth_client *ac, · 292 unmodified lines | ||
| 293 | 293 | } |
| 294 | 294 | EXPORT_SYMBOL(ceph_auth_create_authorizer); |
| 295 | 295 | |
| 296 | −void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac, | |
| 297 | − struct ceph_authorizer *a) | |
| 296 | +void ceph_auth_destroy_authorizer(struct ceph_authorizer *a) | |
| 298 | 297 | { |
| 299 | − mutex_lock(&ac->mutex); | |
| 300 | − if (ac->ops && ac->ops->destroy_authorizer) | |
| 301 | − ac->ops->destroy_authorizer(ac, a); | |
| 302 | − mutex_unlock(&ac->mutex); | |
| 298 | + a->destroy(a); | |
| 303 | 299 | } |
| 304 | 300 | EXPORT_SYMBOL(ceph_auth_destroy_authorizer); |
| 305 | 301 | |
| @@ -16,7 +16,6 @@ static void reset(struct ceph_auth_client *ac) · 15 unmodified lines | ||
| 16 | 16 | struct ceph_auth_none_info *xi = ac->private; |
| 17 | 17 | |
| 18 | 18 | xi->starting = true; |
| 19 | − xi->built_authorizer = false; | |
| 20 | 19 | } |
| 21 | 20 | |
| 22 | 21 | static void destroy(struct ceph_auth_client *ac) |
| @@ -39,6 +38,27 @@ static int should_authenticate(struct ceph_auth_client *ac) · 16 unmodified lines | ||
| 39 | 38 | return xi->starting; |
| 40 | 39 | } |
| 41 | 40 | |
| 41 | +static int ceph_auth_none_build_authorizer(struct ceph_auth_client *ac, | |
| 42 | + struct ceph_none_authorizer *au) | |
| 43 | +{ | |
| 44 | + void *p = au->buf; | |
| 45 | + void *const end = p + sizeof(au->buf); | |
| 46 | + int ret; | |
| 47 | + | |
| 48 | + ceph_encode_8_safe(&p, end, 1, e_range); | |
| 49 | + ret = ceph_entity_name_encode(ac->name, &p, end); | |
| 50 | + if (ret < 0) | |
| 51 | + return ret; | |
| 52 | + | |
| 53 | + ceph_encode_64_safe(&p, end, ac->global_id, e_range); | |
| 54 | + au->buf_len = p - (void *)au->buf; | |
| 55 | + dout("%s built authorizer len %d\n", __func__, au->buf_len); | |
| 56 | + return 0; | |
| 57 | + | |
| 58 | +e_range: | |
| 59 | + return -ERANGE; | |
| 60 | +} | |
| 61 | + | |
| 42 | 62 | static int build_request(struct ceph_auth_client *ac, void *buf, void *end) |
| 43 | 63 | { |
| 44 | 64 | return 0; |
| @@ -57,32 +77,32 @@ static int handle_reply(struct ceph_auth_client *ac, int result, · 12 unmodified lines | ||
| 57 | 77 | return result; |
| 58 | 78 | } |
| 59 | 79 | |
| 80 | +static void ceph_auth_none_destroy_authorizer(struct ceph_authorizer *a) | |
| 81 | +{ | |
| 82 | + kfree(a); | |
| 83 | +} | |
| 84 | + | |
| 60 | 85 | /* |
| 61 | − * build an 'authorizer' with our entity_name and global_id. we can | |
| 62 | − * reuse a single static copy since it is identical for all services | |
| 63 | − * we connect to. | |
| 86 | + * build an 'authorizer' with our entity_name and global_id. it is | |
| 87 | + * identical for all services we connect to. | |
| 64 | 88 | */ |
| 65 | 89 | static int ceph_auth_none_create_authorizer( |
| 66 | 90 | struct ceph_auth_client *ac, int peer_type, |
| 67 | 91 | struct ceph_auth_handshake *auth) |
| 68 | 92 | { |
| 69 | − struct ceph_auth_none_info *ai = ac->private; | |
| 70 | − struct ceph_none_authorizer *au = &ai->au; | |
| 71 | − void *p, *end; | |
| 93 | + struct ceph_none_authorizer *au; | |
| 72 | 94 | int ret; |
| 73 | 95 | |
| 74 | − if (!ai->built_authorizer) { | |
| 75 | − p = au->buf; | |
| 76 | − end = p + sizeof(au->buf); | |
| 77 | − ceph_encode_8(&p, 1); | |
| 78 | − ret = ceph_entity_name_encode(ac->name, &p, end - 8); | |
| 79 | − if (ret < 0) | |
| 80 | − goto bad; | |
| 81 | − ceph_decode_need(&p, end, sizeof(u64), bad2); | |
| 82 | − ceph_encode_64(&p, ac->global_id); | |
| 83 | − au->buf_len = p - (void *)au->buf; | |
| 84 | − ai->built_authorizer = true; | |
| 85 | − dout("built authorizer len %d\n", au->buf_len); | |
| 96 | + au = kmalloc(sizeof(*au), GFP_NOFS); | |
| 97 | + if (!au) | |
| 98 | + return -ENOMEM; | |
| 99 | + | |
| 100 | + au->base.destroy = ceph_auth_none_destroy_authorizer; | |
| 101 | + | |
| 102 | + ret = ceph_auth_none_build_authorizer(ac, au); | |
| 103 | + if (ret) { | |
| 104 | + kfree(au); | |
| 105 | + return ret; | |
| 86 | 106 | } |
| 87 | 107 | |
| 88 | 108 | auth->authorizer = (struct ceph_authorizer *) au; |
| @@ -92,17 +112,6 @@ static int ceph_auth_none_create_authorizer( · 3 unmodified lines | ||
| 92 | 112 | auth->authorizer_reply_buf_len = sizeof (au->reply_buf); |
| 93 | 113 | |
| 94 | 114 | return 0; |
| 95 | − | |
| 96 | −bad2: | |
| 97 | − ret = -ERANGE; | |
| 98 | −bad: | |
| 99 | − return ret; | |
| 100 | −} | |
| 101 | − | |
| 102 | −static void ceph_auth_none_destroy_authorizer(struct ceph_auth_client *ac, | |
| 103 | − struct ceph_authorizer *a) | |
| 104 | −{ | |
| 105 | − /* nothing to do */ | |
| 106 | 115 | } |
| 107 | 116 | |
| 108 | 117 | static const struct ceph_auth_client_ops ceph_auth_none_ops = { |
| @@ -114,7 +123,6 @@ static const struct ceph_auth_client_ops ceph_auth_none_ops = { · 5 unmodified lines | ||
| 114 | 123 | .build_request = build_request, |
| 115 | 124 | .handle_reply = handle_reply, |
| 116 | 125 | .create_authorizer = ceph_auth_none_create_authorizer, |
| 117 | − .destroy_authorizer = ceph_auth_none_destroy_authorizer, | |
| 118 | 126 | }; |
| 119 | 127 | |
| 120 | 128 | int ceph_auth_none_init(struct ceph_auth_client *ac) |
| @@ -127,7 +135,6 @@ int ceph_auth_none_init(struct ceph_auth_client *ac) · 6 unmodified lines | ||
| 127 | 135 | return -ENOMEM; |
| 128 | 136 | |
| 129 | 137 | xi->starting = true; |
| 130 | − xi->built_authorizer = false; | |
| 131 | 138 | |
| 132 | 139 | ac->protocol = CEPH_AUTH_NONE; |
| 133 | 140 | ac->private = xi; |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | */ |
| 13 | 13 | |
| 14 | 14 | struct ceph_none_authorizer { |
| 15 | + struct ceph_authorizer base; | |
| 15 | 16 | char buf[128]; |
| 16 | 17 | int buf_len; |
| 17 | 18 | char reply_buf[0]; |
| @@ -19,8 +20,6 @@ struct ceph_none_authorizer { · 1 unmodified line | ||
| 19 | 20 | |
| 20 | 21 | struct ceph_auth_none_info { |
| 21 | 22 | bool starting; |
| 22 | − bool built_authorizer; | |
| 23 | − struct ceph_none_authorizer au; /* we only need one; it's static */ | |
| 24 | 23 | }; |
| 25 | 24 | |
| 26 | 25 | int ceph_auth_none_init(struct ceph_auth_client *ac); |
| @@ -565,6 +565,14 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result, · 564 unmodified lines | ||
| 565 | 565 | return -EAGAIN; |
| 566 | 566 | } |
| 567 | 567 | |
| 568 | +static void ceph_x_destroy_authorizer(struct ceph_authorizer *a) | |
| 569 | +{ | |
| 570 | + struct ceph_x_authorizer *au = (void *)a; | |
| 571 | + | |
| 572 | + ceph_x_authorizer_cleanup(au); | |
| 573 | + kfree(au); | |
| 574 | +} | |
| 575 | + | |
| 568 | 576 | static int ceph_x_create_authorizer( |
| 569 | 577 | struct ceph_auth_client *ac, int peer_type, |
| 570 | 578 | struct ceph_auth_handshake *auth) |
| @@ -581,6 +589,8 @@ static int ceph_x_create_authorizer( · 10 unmodified lines | ||
| 581 | 589 | if (!au) |
| 582 | 590 | return -ENOMEM; |
| 583 | 591 | |
| 592 | + au->base.destroy = ceph_x_destroy_authorizer; | |
| 593 | + | |
| 584 | 594 | ret = ceph_x_build_authorizer(ac, th, au); |
| 585 | 595 | if (ret) { |
| 586 | 596 | kfree(au); |
| @@ -643,16 +653,6 @@ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac, · 56 unmodified lines | ||
| 643 | 653 | return ret; |
| 644 | 654 | } |
| 645 | 655 | |
| 646 | −static void ceph_x_destroy_authorizer(struct ceph_auth_client *ac, | |
| 647 | − struct ceph_authorizer *a) | |
| 648 | −{ | |
| 649 | − struct ceph_x_authorizer *au = (void *)a; | |
| 650 | − | |
| 651 | − ceph_x_authorizer_cleanup(au); | |
| 652 | − kfree(au); | |
| 653 | −} | |
| 654 | − | |
| 655 | − | |
| 656 | 656 | static void ceph_x_reset(struct ceph_auth_client *ac) |
| 657 | 657 | { |
| 658 | 658 | struct ceph_x_info *xi = ac->private; |
| @@ -770,7 +770,6 @@ static const struct ceph_auth_client_ops ceph_x_ops = { · 111 unmodified lines | ||
| 770 | 770 | .create_authorizer = ceph_x_create_authorizer, |
| 771 | 771 | .update_authorizer = ceph_x_update_authorizer, |
| 772 | 772 | .verify_authorizer_reply = ceph_x_verify_authorizer_reply, |
| 773 | − .destroy_authorizer = ceph_x_destroy_authorizer, | |
| 774 | 773 | .invalidate_authorizer = ceph_x_invalidate_authorizer, |
| 775 | 774 | .reset = ceph_x_reset, |
| 776 | 775 | .destroy = ceph_x_destroy, |
| @@ -26,6 +26,7 @@ struct ceph_x_ticket_handler { · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | |
| 28 | 28 | struct ceph_x_authorizer { |
| 29 | + struct ceph_authorizer base; | |
| 29 | 30 | struct ceph_crypto_key session_key; |
| 30 | 31 | struct ceph_buffer *buf; |
| 31 | 32 | unsigned int service; |
| @@ -1087,10 +1087,8 @@ static void put_osd(struct ceph_osd *osd) · 1086 unmodified lines | ||
| 1087 | 1087 | dout("put_osd %p %d -> %d\n", osd, atomic_read(&osd->o_ref), |
| 1088 | 1088 | atomic_read(&osd->o_ref) - 1); |
| 1089 | 1089 | if (atomic_dec_and_test(&osd->o_ref)) { |
| 1090 | − struct ceph_auth_client *ac = osd->o_osdc->client->monc.auth; | |
| 1091 | − | |
| 1092 | 1090 | if (osd->o_auth.authorizer) |
| 1093 | − ceph_auth_destroy_authorizer(ac, osd->o_auth.authorizer); | |
| 1091 | + ceph_auth_destroy_authorizer(osd->o_auth.authorizer); | |
| 1094 | 1092 | kfree(osd); |
| 1095 | 1093 | } |
| 1096 | 1094 | } |
| @@ -2984,7 +2982,7 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, · 1887 unmodified lines | ||
| 2984 | 2982 | struct ceph_auth_handshake *auth = &o->o_auth; |
| 2985 | 2983 | |
| 2986 | 2984 | if (force_new && auth->authorizer) { |
| 2987 | − ceph_auth_destroy_authorizer(ac, auth->authorizer); | |
| 2985 | + ceph_auth_destroy_authorizer(auth->authorizer); | |
| 2988 | 2986 | auth->authorizer = NULL; |
| 2989 | 2987 | } |
| 2990 | 2988 | if (!auth->authorizer) { |
| @@ -2802,7 +2802,7 @@ static netdev_features_t harmonize_features(struct sk_buff *skb, · 2801 unmodified lines | ||
| 2802 | 2802 | |
| 2803 | 2803 | if (skb->ip_summed != CHECKSUM_NONE && |
| 2804 | 2804 | !can_checksum_protocol(features, type)) { |
| 2805 | − features &= ~NETIF_F_CSUM_MASK; | |
| 2805 | + features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); | |
| 2806 | 2806 | } else if (illegal_highdma(skb->dev, skb)) { |
| 2807 | 2807 | features &= ~NETIF_F_SG; |
| 2808 | 2808 | } |
| @@ -904,7 +904,11 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim) · 903 unmodified lines | ||
| 904 | 904 | if (ifa->ifa_flags & IFA_F_SECONDARY) { |
| 905 | 905 | prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask); |
| 906 | 906 | if (!prim) { |
| 907 | − pr_warn("%s: bug: prim == NULL\n", __func__); | |
| 907 | + /* if the device has been deleted, we don't perform | |
| 908 | + * address promotion | |
| 909 | + */ | |
| 910 | + if (!in_dev->dead) | |
| 911 | + pr_warn("%s: bug: prim == NULL\n", __func__); | |
| 908 | 912 | return; |
| 909 | 913 | } |
| 910 | 914 | if (iprim && iprim != prim) { |
| @@ -470,6 +470,7 @@ static int inet_reuseport_add_sock(struct sock *sk, · 469 unmodified lines | ||
| 470 | 470 | const struct sock *sk2, |
| 471 | 471 | bool match_wildcard)) |
| 472 | 472 | { |
| 473 | + struct inet_bind_bucket *tb = inet_csk(sk)->icsk_bind_hash; | |
| 473 | 474 | struct sock *sk2; |
| 474 | 475 | struct hlist_nulls_node *node; |
| 475 | 476 | kuid_t uid = sock_i_uid(sk); |
| @@ -479,6 +480,7 @@ static int inet_reuseport_add_sock(struct sock *sk, · 3 unmodified lines | ||
| 479 | 480 | sk2->sk_family == sk->sk_family && |
| 480 | 481 | ipv6_only_sock(sk2) == ipv6_only_sock(sk) && |
| 481 | 482 | sk2->sk_bound_dev_if == sk->sk_bound_dev_if && |
| 483 | + inet_csk(sk2)->icsk_bind_hash == tb && | |
| 482 | 484 | sk2->sk_reuseport && uid_eq(uid, sock_i_uid(sk2)) && |
| 483 | 485 | saddr_same(sk, sk2, false)) |
| 484 | 486 | return reuseport_add_sock(sk, sk2); |
| @@ -179,6 +179,7 @@ static __be16 tnl_flags_to_gre_flags(__be16 tflags) · 178 unmodified lines | ||
| 179 | 179 | return flags; |
| 180 | 180 | } |
| 181 | 181 | |
| 182 | +/* Fills in tpi and returns header length to be pulled. */ | |
| 182 | 183 | static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, |
| 183 | 184 | bool *csum_err) |
| 184 | 185 | { |
| @@ -238,7 +239,7 @@ static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, · 53 unmodified lines | ||
| 238 | 239 | return -EINVAL; |
| 239 | 240 | } |
| 240 | 241 | } |
| 241 | − return iptunnel_pull_header(skb, hdr_len, tpi->proto, false); | |
| 242 | + return hdr_len; | |
| 242 | 243 | } |
| 243 | 244 | |
| 244 | 245 | static void ipgre_err(struct sk_buff *skb, u32 info, |
| @@ -341,7 +342,7 @@ static void gre_err(struct sk_buff *skb, u32 info) · 96 unmodified lines | ||
| 341 | 342 | struct tnl_ptk_info tpi; |
| 342 | 343 | bool csum_err = false; |
| 343 | 344 | |
| 344 | − if (parse_gre_header(skb, &tpi, &csum_err)) { | |
| 345 | + if (parse_gre_header(skb, &tpi, &csum_err) < 0) { | |
| 345 | 346 | if (!csum_err) /* ignore csum errors. */ |
| 346 | 347 | return; |
| 347 | 348 | } |
| @@ -419,6 +420,7 @@ static int gre_rcv(struct sk_buff *skb) · 71 unmodified lines | ||
| 419 | 420 | { |
| 420 | 421 | struct tnl_ptk_info tpi; |
| 421 | 422 | bool csum_err = false; |
| 423 | + int hdr_len; | |
| 422 | 424 | |
| 423 | 425 | #ifdef CONFIG_NET_IPGRE_BROADCAST |
| 424 | 426 | if (ipv4_is_multicast(ip_hdr(skb)->daddr)) { |
| @@ -428,7 +430,10 @@ static int gre_rcv(struct sk_buff *skb) · 3 unmodified lines | ||
| 428 | 430 | } |
| 429 | 431 | #endif |
| 430 | 432 | |
| 431 | − if (parse_gre_header(skb, &tpi, &csum_err) < 0) | |
| 433 | + hdr_len = parse_gre_header(skb, &tpi, &csum_err); | |
| 434 | + if (hdr_len < 0) | |
| 435 | + goto drop; | |
| 436 | + if (iptunnel_pull_header(skb, hdr_len, tpi.proto, false) < 0) | |
| 432 | 437 | goto drop; |
| 433 | 438 | |
| 434 | 439 | if (ipgre_rcv(skb, &tpi) == PACKET_RCVD) |
| @@ -523,7 +528,8 @@ static struct rtable *gre_get_rt(struct sk_buff *skb, · 88 unmodified lines | ||
| 523 | 528 | return ip_route_output_key(net, fl); |
| 524 | 529 | } |
| 525 | 530 | |
| 526 | −static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev) | |
| 531 | +static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev, | |
| 532 | + __be16 proto) | |
| 527 | 533 | { |
| 528 | 534 | struct ip_tunnel_info *tun_info; |
| 529 | 535 | const struct ip_tunnel_key *key; |
| @@ -575,7 +581,7 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev) · 45 unmodified lines | ||
| 575 | 581 | } |
| 576 | 582 | |
| 577 | 583 | flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY); |
| 578 | − build_header(skb, tunnel_hlen, flags, htons(ETH_P_TEB), | |
| 584 | + build_header(skb, tunnel_hlen, flags, proto, | |
| 579 | 585 | tunnel_id_to_key(tun_info->key.tun_id), 0); |
| 580 | 586 | |
| 581 | 587 | df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; |
| @@ -616,7 +622,7 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, · 34 unmodified lines | ||
| 616 | 622 | const struct iphdr *tnl_params; |
| 617 | 623 | |
| 618 | 624 | if (tunnel->collect_md) { |
| 619 | − gre_fb_xmit(skb, dev); | |
| 625 | + gre_fb_xmit(skb, dev, skb->protocol); | |
| 620 | 626 | return NETDEV_TX_OK; |
| 621 | 627 | } |
| 622 | 628 | |
| @@ -660,7 +666,7 @@ static netdev_tx_t gre_tap_xmit(struct sk_buff *skb, · 37 unmodified lines | ||
| 660 | 666 | struct ip_tunnel *tunnel = netdev_priv(dev); |
| 661 | 667 | |
| 662 | 668 | if (tunnel->collect_md) { |
| 663 | − gre_fb_xmit(skb, dev); | |
| 669 | + gre_fb_xmit(skb, dev, htons(ETH_P_TEB)); | |
| 664 | 670 | return NETDEV_TX_OK; |
| 665 | 671 | } |
| 666 | 672 | |
| @@ -893,7 +899,7 @@ static int ipgre_tunnel_init(struct net_device *dev) · 226 unmodified lines | ||
| 893 | 899 | netif_keep_dst(dev); |
| 894 | 900 | dev->addr_len = 4; |
| 895 | 901 | |
| 896 | − if (iph->daddr) { | |
| 902 | + if (iph->daddr && !tunnel->collect_md) { | |
| 897 | 903 | #ifdef CONFIG_NET_IPGRE_BROADCAST |
| 898 | 904 | if (ipv4_is_multicast(iph->daddr)) { |
| 899 | 905 | if (!iph->saddr) |
| @@ -902,8 +908,9 @@ static int ipgre_tunnel_init(struct net_device *dev) · 2 unmodified lines | ||
| 902 | 908 | dev->header_ops = &ipgre_header_ops; |
| 903 | 909 | } |
| 904 | 910 | #endif |
| 905 | − } else | |
| 911 | + } else if (!tunnel->collect_md) { | |
| 906 | 912 | dev->header_ops = &ipgre_header_ops; |
| 913 | + } | |
| 907 | 914 | |
| 908 | 915 | return ip_tunnel_init(dev); |
| 909 | 916 | } |
| @@ -946,6 +953,11 @@ static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[]) · 36 unmodified lines | ||
| 946 | 953 | if (flags & (GRE_VERSION|GRE_ROUTING)) |
| 947 | 954 | return -EINVAL; |
| 948 | 955 | |
| 956 | + if (data[IFLA_GRE_COLLECT_METADATA] && | |
| 957 | + data[IFLA_GRE_ENCAP_TYPE] && | |
| 958 | + nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE) | |
| 959 | + return -EINVAL; | |
| 960 | + | |
| 949 | 961 | return 0; |
| 950 | 962 | } |
| 951 | 963 | |
| @@ -326,12 +326,12 @@ static int ip_tunnel_bind_dev(struct net_device *dev) · 325 unmodified lines | ||
| 326 | 326 | |
| 327 | 327 | if (!IS_ERR(rt)) { |
| 328 | 328 | tdev = rt->dst.dev; |
| 329 | − dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst, | |
| 330 | − fl4.saddr); | |
| 331 | 329 | ip_rt_put(rt); |
| 332 | 330 | } |
| 333 | 331 | if (dev->type != ARPHRD_ETHER) |
| 334 | 332 | dev->flags |= IFF_POINTOPOINT; |
| 333 | + | |
| 334 | + dst_cache_reset(&tunnel->dst_cache); | |
| 335 | 335 | } |
| 336 | 336 | |
| 337 | 337 | if (!tdev && tunnel->parms.link) |
| @@ -3176,35 +3176,9 @@ static void addrconf_gre_config(struct net_device *dev) · 3175 unmodified lines | ||
| 3176 | 3176 | } |
| 3177 | 3177 | #endif |
| 3178 | 3178 | |
| 3179 | −#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) | |
| 3180 | −/* If the host route is cached on the addr struct make sure it is associated | |
| 3181 | − * with the proper table. e.g., enslavement can change and if so the cached | |
| 3182 | − * host route needs to move to the new table. | |
| 3183 | − */ | |
| 3184 | −static void l3mdev_check_host_rt(struct inet6_dev *idev, | |
| 3185 | − struct inet6_ifaddr *ifp) | |
| 3186 | −{ | |
| 3187 | − if (ifp->rt) { | |
| 3188 | − u32 tb_id = l3mdev_fib_table(idev->dev) ? : RT6_TABLE_LOCAL; | |
| 3189 | − | |
| 3190 | − if (tb_id != ifp->rt->rt6i_table->tb6_id) { | |
| 3191 | − ip6_del_rt(ifp->rt); | |
| 3192 | − ifp->rt = NULL; | |
| 3193 | − } | |
| 3194 | − } | |
| 3195 | −} | |
| 3196 | −#else | |
| 3197 | −static void l3mdev_check_host_rt(struct inet6_dev *idev, | |
| 3198 | − struct inet6_ifaddr *ifp) | |
| 3199 | −{ | |
| 3200 | −} | |
| 3201 | −#endif | |
| 3202 | − | |
| 3203 | 3179 | static int fixup_permanent_addr(struct inet6_dev *idev, |
| 3204 | 3180 | struct inet6_ifaddr *ifp) |
| 3205 | 3181 | { |
| 3206 | − l3mdev_check_host_rt(idev, ifp); | |
| 3207 | − | |
| 3208 | 3182 | if (!ifp->rt) { |
| 3209 | 3183 | struct rt6_info *rt; |
| 3210 | 3184 | |
| @@ -3304,6 +3278,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, · 93 unmodified lines | ||
| 3304 | 3278 | break; |
| 3305 | 3279 | |
| 3306 | 3280 | if (event == NETDEV_UP) { |
| 3281 | + /* restore routes for permanent addresses */ | |
| 3282 | + addrconf_permanent_addr(dev); | |
| 3283 | + | |
| 3307 | 3284 | if (!addrconf_qdisc_ok(dev)) { |
| 3308 | 3285 | /* device is not ready yet. */ |
| 3309 | 3286 | pr_info("ADDRCONF(NETDEV_UP): %s: link is not ready\n", |
| @@ -3337,9 +3314,6 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, · 27 unmodified lines | ||
| 3337 | 3314 | run_pending = 1; |
| 3338 | 3315 | } |
| 3339 | 3316 | |
| 3340 | − /* restore routes for permanent addresses */ | |
| 3341 | − addrconf_permanent_addr(dev); | |
| 3342 | − | |
| 3343 | 3317 | switch (dev->type) { |
| 3344 | 3318 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
| 3345 | 3319 | case ARPHRD_SIT: |
| @@ -3556,6 +3530,8 @@ restart: · 210 unmodified lines | ||
| 3556 | 3530 | |
| 3557 | 3531 | INIT_LIST_HEAD(&del_list); |
| 3558 | 3532 | list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) { |
| 3533 | + struct rt6_info *rt = NULL; | |
| 3534 | + | |
| 3559 | 3535 | addrconf_del_dad_work(ifa); |
| 3560 | 3536 | |
| 3561 | 3537 | write_unlock_bh(&idev->lock); |
| @@ -3568,6 +3544,9 @@ restart: · 6 unmodified lines | ||
| 3568 | 3544 | ifa->state = 0; |
| 3569 | 3545 | if (!(ifa->flags & IFA_F_NODAD)) |
| 3570 | 3546 | ifa->flags |= IFA_F_TENTATIVE; |
| 3547 | + | |
| 3548 | + rt = ifa->rt; | |
| 3549 | + ifa->rt = NULL; | |
| 3571 | 3550 | } else { |
| 3572 | 3551 | state = ifa->state; |
| 3573 | 3552 | ifa->state = INET6_IFADDR_STATE_DEAD; |
| @@ -3578,6 +3557,9 @@ restart: · 4 unmodified lines | ||
| 3578 | 3557 | |
| 3579 | 3558 | spin_unlock_bh(&ifa->lock); |
| 3580 | 3559 | |
| 3560 | + if (rt) | |
| 3561 | + ip6_del_rt(rt); | |
| 3562 | + | |
| 3581 | 3563 | if (state != INET6_IFADDR_STATE_DEAD) { |
| 3582 | 3564 | __ipv6_ifa_notify(RTM_DELADDR, ifa); |
| 3583 | 3565 | inet6addr_notifier_call_chain(NETDEV_DOWN, ifa); |
| @@ -5343,10 +5325,10 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) · 1759 unmodified lines | ||
| 5343 | 5325 | if (rt) |
| 5344 | 5326 | ip6_del_rt(rt); |
| 5345 | 5327 | } |
| 5346 | − dst_hold(&ifp->rt->dst); | |
| 5347 | − | |
| 5348 | − ip6_del_rt(ifp->rt); | |
| 5349 | − | |
| 5328 | + if (ifp->rt) { | |
| 5329 | + dst_hold(&ifp->rt->dst); | |
| 5330 | + ip6_del_rt(ifp->rt); | |
| 5331 | + } | |
| 5350 | 5332 | rt_genid_bump_ipv6(net); |
| 5351 | 5333 | break; |
| 5352 | 5334 | } |
| @@ -120,8 +120,7 @@ nla_put_failure: · 119 unmodified lines | ||
| 120 | 120 | |
| 121 | 121 | static int ila_encap_nlsize(struct lwtunnel_state *lwtstate) |
| 122 | 122 | { |
| 123 | − /* No encapsulation overhead */ | |
| 124 | − return 0; | |
| 123 | + return nla_total_size(sizeof(u64)); /* ILA_ATTR_LOCATOR */ | |
| 125 | 124 | } |
| 126 | 125 | |
| 127 | 126 | static int ila_encap_cmp(struct lwtunnel_state *a, struct lwtunnel_state *b) |
| @@ -1376,9 +1376,9 @@ static int l2tp_tunnel_sock_create(struct net *net, · 1375 unmodified lines | ||
| 1376 | 1376 | memcpy(&udp_conf.peer_ip6, cfg->peer_ip6, |
| 1377 | 1377 | sizeof(udp_conf.peer_ip6)); |
| 1378 | 1378 | udp_conf.use_udp6_tx_checksums = |
| 1379 | − cfg->udp6_zero_tx_checksums; | |
| 1379 | + ! cfg->udp6_zero_tx_checksums; | |
| 1380 | 1380 | udp_conf.use_udp6_rx_checksums = |
| 1381 | − cfg->udp6_zero_rx_checksums; | |
| 1381 | + ! cfg->udp6_zero_rx_checksums; | |
| 1382 | 1382 | } else |
| 1383 | 1383 | #endif |
| 1384 | 1384 | { |
| @@ -1761,7 +1761,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, · 1760 unmodified lines | ||
| 1761 | 1761 | |
| 1762 | 1762 | ret = dev_alloc_name(ndev, ndev->name); |
| 1763 | 1763 | if (ret < 0) { |
| 1764 | − free_netdev(ndev); | |
| 1764 | + ieee80211_if_free(ndev); | |
| 1765 | 1765 | return ret; |
| 1766 | 1766 | } |
| 1767 | 1767 | |
| @@ -1847,7 +1847,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, · 79 unmodified lines | ||
| 1847 | 1847 | |
| 1848 | 1848 | ret = register_netdevice(ndev); |
| 1849 | 1849 | if (ret) { |
| 1850 | − free_netdev(ndev); | |
| 1850 | + ieee80211_if_free(ndev); | |
| 1851 | 1851 | return ret; |
| 1852 | 1852 | } |
| 1853 | 1853 | } |
| @@ -127,7 +127,7 @@ void rds_tcp_restore_callbacks(struct socket *sock, · 126 unmodified lines | ||
| 127 | 127 | |
| 128 | 128 | /* |
| 129 | 129 | * This is the only path that sets tc->t_sock. Send and receive trust that |
| 130 | − * it is set. The RDS_CONN_CONNECTED bit protects those paths from being | |
| 130 | + * it is set. The RDS_CONN_UP bit protects those paths from being | |
| 131 | 131 | * called while it isn't set. |
| 132 | 132 | */ |
| 133 | 133 | void rds_tcp_set_callbacks(struct socket *sock, struct rds_connection *conn) |
| @@ -216,6 +216,7 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp) · 82 unmodified lines | ||
| 216 | 216 | if (!tc) |
| 217 | 217 | return -ENOMEM; |
| 218 | 218 | |
| 219 | + mutex_init(&tc->t_conn_lock); | |
| 219 | 220 | tc->t_sock = NULL; |
| 220 | 221 | tc->t_tinc = NULL; |
| 221 | 222 | tc->t_tinc_hdr_rem = sizeof(struct rds_header); |
| @@ -12,6 +12,10 @@ struct rds_tcp_connection { · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | struct list_head t_tcp_node; |
| 14 | 14 | struct rds_connection *conn; |
| 15 | + /* t_conn_lock synchronizes the connection establishment between | |
| 16 | + * rds_tcp_accept_one and rds_tcp_conn_connect | |
| 17 | + */ | |
| 18 | + struct mutex t_conn_lock; | |
| 15 | 19 | struct socket *t_sock; |
| 16 | 20 | void *t_orig_write_space; |
| 17 | 21 | void *t_orig_data_ready; |
| @@ -78,7 +78,14 @@ int rds_tcp_conn_connect(struct rds_connection *conn) · 77 unmodified lines | ||
| 78 | 78 | struct socket *sock = NULL; |
| 79 | 79 | struct sockaddr_in src, dest; |
| 80 | 80 | int ret; |
| 81 | + struct rds_tcp_connection *tc = conn->c_transport_data; | |
| 82 | + | |
| 83 | + mutex_lock(&tc->t_conn_lock); | |
| 81 | 84 | |
| 85 | + if (rds_conn_up(conn)) { | |
| 86 | + mutex_unlock(&tc->t_conn_lock); | |
| 87 | + return 0; | |
| 88 | + } | |
| 82 | 89 | ret = sock_create_kern(rds_conn_net(conn), PF_INET, |
| 83 | 90 | SOCK_STREAM, IPPROTO_TCP, &sock); |
| 84 | 91 | if (ret < 0) |
| @@ -120,6 +127,7 @@ int rds_tcp_conn_connect(struct rds_connection *conn) · 35 unmodified lines | ||
| 120 | 127 | } |
| 121 | 128 | |
| 122 | 129 | out: |
| 130 | + mutex_unlock(&tc->t_conn_lock); | |
| 123 | 131 | if (sock) |
| 124 | 132 | sock_release(sock); |
| 125 | 133 | return ret; |
| @@ -76,7 +76,9 @@ int rds_tcp_accept_one(struct socket *sock) · 75 unmodified lines | ||
| 76 | 76 | struct rds_connection *conn; |
| 77 | 77 | int ret; |
| 78 | 78 | struct inet_sock *inet; |
| 79 | − struct rds_tcp_connection *rs_tcp; | |
| 79 | + struct rds_tcp_connection *rs_tcp = NULL; | |
| 80 | + int conn_state; | |
| 81 | + struct sock *nsk; | |
| 80 | 82 | |
| 81 | 83 | ret = sock_create_kern(sock_net(sock->sk), sock->sk->sk_family, |
| 82 | 84 | sock->sk->sk_type, sock->sk->sk_protocol, |
| @@ -115,28 +117,44 @@ int rds_tcp_accept_one(struct socket *sock) · 32 unmodified lines | ||
| 115 | 117 | * rds_tcp_state_change() will do that cleanup |
| 116 | 118 | */ |
| 117 | 119 | rs_tcp = (struct rds_tcp_connection *)conn->c_transport_data; |
| 118 | − if (rs_tcp->t_sock && | |
| 119 | − ntohl(inet->inet_saddr) < ntohl(inet->inet_daddr)) { | |
| 120 | − struct sock *nsk = new_sock->sk; | |
| 121 | − | |
| 122 | − nsk->sk_user_data = NULL; | |
| 123 | − nsk->sk_prot->disconnect(nsk, 0); | |
| 124 | − tcp_done(nsk); | |
| 125 | − new_sock = NULL; | |
| 126 | − ret = 0; | |
| 127 | − goto out; | |
| 128 | − } else if (rs_tcp->t_sock) { | |
| 129 | − rds_tcp_restore_callbacks(rs_tcp->t_sock, rs_tcp); | |
| 130 | − conn->c_outgoing = 0; | |
| 131 | − } | |
| 132 | − | |
| 133 | 120 | rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_CONNECTING); |
| 121 | + mutex_lock(&rs_tcp->t_conn_lock); | |
| 122 | + conn_state = rds_conn_state(conn); | |
| 123 | + if (conn_state != RDS_CONN_CONNECTING && conn_state != RDS_CONN_UP) | |
| 124 | + goto rst_nsk; | |
| 125 | + if (rs_tcp->t_sock) { | |
| 126 | + /* Need to resolve a duelling SYN between peers. | |
| 127 | + * We have an outstanding SYN to this peer, which may | |
| 128 | + * potentially have transitioned to the RDS_CONN_UP state, | |
| 129 | + * so we must quiesce any send threads before resetting | |
| 130 | + * c_transport_data. | |
| 131 | + */ | |
| 132 | + wait_event(conn->c_waitq, | |
| 133 | + !test_bit(RDS_IN_XMIT, &conn->c_flags)); | |
| 134 | + if (ntohl(inet->inet_saddr) < ntohl(inet->inet_daddr)) { | |
| 135 | + goto rst_nsk; | |
| 136 | + } else if (rs_tcp->t_sock) { | |
| 137 | + rds_tcp_restore_callbacks(rs_tcp->t_sock, rs_tcp); | |
| 138 | + conn->c_outgoing = 0; | |
| 139 | + } | |
| 140 | + } | |
| 134 | 141 | rds_tcp_set_callbacks(new_sock, conn); |
| 135 | − rds_connect_complete(conn); | |
| 142 | + rds_connect_complete(conn); /* marks RDS_CONN_UP */ | |
| 143 | + new_sock = NULL; | |
| 144 | + ret = 0; | |
| 145 | + goto out; | |
| 146 | +rst_nsk: | |
| 147 | + /* reset the newly returned accept sock and bail */ | |
| 148 | + nsk = new_sock->sk; | |
| 149 | + rds_tcp_stats_inc(s_tcp_listen_closed_stale); | |
| 150 | + nsk->sk_user_data = NULL; | |
| 151 | + nsk->sk_prot->disconnect(nsk, 0); | |
| 152 | + tcp_done(nsk); | |
| 136 | 153 | new_sock = NULL; |
| 137 | 154 | ret = 0; |
| 138 | − | |
| 139 | 155 | out: |
| 156 | + if (rs_tcp) | |
| 157 | + mutex_unlock(&rs_tcp->t_conn_lock); | |
| 140 | 158 | if (new_sock) |
| 141 | 159 | sock_release(new_sock); |
| 142 | 160 | return ret; |
| @@ -395,6 +395,25 @@ static void tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) · 394 unmodified lines | ||
| 395 | 395 | sch->q.qlen++; |
| 396 | 396 | } |
| 397 | 397 | |
| 398 | +/* netem can't properly corrupt a megapacket (like we get from GSO), so instead | |
| 399 | + * when we statistically choose to corrupt one, we instead segment it, returning | |
| 400 | + * the first packet to be corrupted, and re-enqueue the remaining frames | |
| 401 | + */ | |
| 402 | +static struct sk_buff *netem_segment(struct sk_buff *skb, struct Qdisc *sch) | |
| 403 | +{ | |
| 404 | + struct sk_buff *segs; | |
| 405 | + netdev_features_t features = netif_skb_features(skb); | |
| 406 | + | |
| 407 | + segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK); | |
| 408 | + | |
| 409 | + if (IS_ERR_OR_NULL(segs)) { | |
| 410 | + qdisc_reshape_fail(skb, sch); | |
| 411 | + return NULL; | |
| 412 | + } | |
| 413 | + consume_skb(skb); | |
| 414 | + return segs; | |
| 415 | +} | |
| 416 | + | |
| 398 | 417 | /* |
| 399 | 418 | * Insert one skb into qdisc. |
| 400 | 419 | * Note: parent depends on return value to account for queue length. |
| @@ -407,7 +426,11 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) · 6 unmodified lines | ||
| 407 | 426 | /* We don't fill cb now as skb_unshare() may invalidate it */ |
| 408 | 427 | struct netem_skb_cb *cb; |
| 409 | 428 | struct sk_buff *skb2; |
| 429 | + struct sk_buff *segs = NULL; | |
| 430 | + unsigned int len = 0, last_len, prev_len = qdisc_pkt_len(skb); | |
| 431 | + int nb = 0; | |
| 410 | 432 | int count = 1; |
| 433 | + int rc = NET_XMIT_SUCCESS; | |
| 411 | 434 | |
| 412 | 435 | /* Random duplication */ |
| 413 | 436 | if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor)) |
| @@ -453,10 +476,23 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) · 39 unmodified lines | ||
| 453 | 476 | * do it now in software before we mangle it. |
| 454 | 477 | */ |
| 455 | 478 | if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) { |
| 479 | + if (skb_is_gso(skb)) { | |
| 480 | + segs = netem_segment(skb, sch); | |
| 481 | + if (!segs) | |
| 482 | + return NET_XMIT_DROP; | |
| 483 | + } else { | |
| 484 | + segs = skb; | |
| 485 | + } | |
| 486 | + | |
| 487 | + skb = segs; | |
| 488 | + segs = segs->next; | |
| 489 | + | |
| 456 | 490 | if (!(skb = skb_unshare(skb, GFP_ATOMIC)) || |
| 457 | 491 | (skb->ip_summed == CHECKSUM_PARTIAL && |
| 458 | − skb_checksum_help(skb))) | |
| 459 | − return qdisc_drop(skb, sch); | |
| 492 | + skb_checksum_help(skb))) { | |
| 493 | + rc = qdisc_drop(skb, sch); | |
| 494 | + goto finish_segs; | |
| 495 | + } | |
| 460 | 496 | |
| 461 | 497 | skb->data[prandom_u32() % skb_headlen(skb)] ^= |
| 462 | 498 | 1<<(prandom_u32() % 8); |
| @@ -516,6 +552,27 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) · 53 unmodified lines | ||
| 516 | 552 | sch->qstats.requeues++; |
| 517 | 553 | } |
| 518 | 554 | |
| 555 | +finish_segs: | |
| 556 | + if (segs) { | |
| 557 | + while (segs) { | |
| 558 | + skb2 = segs->next; | |
| 559 | + segs->next = NULL; | |
| 560 | + qdisc_skb_cb(segs)->pkt_len = segs->len; | |
| 561 | + last_len = segs->len; | |
| 562 | + rc = qdisc_enqueue(segs, sch); | |
| 563 | + if (rc != NET_XMIT_SUCCESS) { | |
| 564 | + if (net_xmit_drop_count(rc)) | |
| 565 | + qdisc_qstats_drop(sch); | |
| 566 | + } else { | |
| 567 | + nb++; | |
| 568 | + len += last_len; | |
| 569 | + } | |
| 570 | + segs = skb2; | |
| 571 | + } | |
| 572 | + sch->q.qlen += nb; | |
| 573 | + if (nb > 1) | |
| 574 | + qdisc_tree_reduce_backlog(sch, 1 - nb, prev_len - len); | |
| 575 | + } | |
| 519 | 576 | return NET_XMIT_SUCCESS; |
| 520 | 577 | } |
| 521 | 578 | |
| @@ -305,6 +305,8 @@ static void switchdev_port_attr_set_deferred(struct net_device *dev, · 304 unmodified lines | ||
| 305 | 305 | if (err && err != -EOPNOTSUPP) |
| 306 | 306 | netdev_err(dev, "failed (err=%d) to set attribute (id=%d)\n", |
| 307 | 307 | err, attr->id); |
| 308 | + if (attr->complete) | |
| 309 | + attr->complete(dev, err, attr->complete_priv); | |
| 308 | 310 | } |
| 309 | 311 | |
| 310 | 312 | static int switchdev_port_attr_set_defer(struct net_device *dev, |
| @@ -434,6 +436,8 @@ static void switchdev_port_obj_add_deferred(struct net_device *dev, · 123 unmodified lines | ||
| 434 | 436 | if (err && err != -EOPNOTSUPP) |
| 435 | 437 | netdev_err(dev, "failed (err=%d) to add object (id=%d)\n", |
| 436 | 438 | err, obj->id); |
| 439 | + if (obj->complete) | |
| 440 | + obj->complete(dev, err, obj->complete_priv); | |
| 437 | 441 | } |
| 438 | 442 | |
| 439 | 443 | static int switchdev_port_obj_add_defer(struct net_device *dev, |
| @@ -502,6 +506,8 @@ static void switchdev_port_obj_del_deferred(struct net_device *dev, · 62 unmodified lines | ||
| 502 | 506 | if (err && err != -EOPNOTSUPP) |
| 503 | 507 | netdev_err(dev, "failed (err=%d) to del object (id=%d)\n", |
| 504 | 508 | err, obj->id); |
| 509 | + if (obj->complete) | |
| 510 | + obj->complete(dev, err, obj->complete_priv); | |
| 505 | 511 | } |
| 506 | 512 | |
| 507 | 513 | static int switchdev_port_obj_del_defer(struct net_device *dev, |
| @@ -1444,6 +1444,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) · 1443 unmodified lines | ||
| 1444 | 1444 | int bearer_id = b->identity; |
| 1445 | 1445 | struct tipc_link_entry *le; |
| 1446 | 1446 | u16 bc_ack = msg_bcast_ack(hdr); |
| 1447 | + u32 self = tipc_own_addr(net); | |
| 1447 | 1448 | int rc = 0; |
| 1448 | 1449 | |
| 1449 | 1450 | __skb_queue_head_init(&xmitq); |
| @@ -1460,6 +1461,10 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) · 10 unmodified lines | ||
| 1460 | 1461 | return tipc_node_bc_rcv(net, skb, bearer_id); |
| 1461 | 1462 | } |
| 1462 | 1463 | |
| 1464 | + /* Discard unicast link messages destined for another node */ | |
| 1465 | + if (unlikely(!msg_short(hdr) && (msg_destnode(hdr) != self))) | |
| 1466 | + goto discard; | |
| 1467 | + | |
| 1463 | 1468 | /* Locate neighboring node that sent packet */ |
| 1464 | 1469 | n = tipc_node_find(net, msg_prevnode(hdr)); |
| 1465 | 1470 | if (unlikely(!n)) |
| @@ -18,7 +18,6 @@ int bpf_prog1(struct pt_regs *ctx) · 17 unmodified lines | ||
| 18 | 18 | u64 cookie; |
| 19 | 19 | } data; |
| 20 | 20 | |
| 21 | − memset(&data, 0, sizeof(data)); | |
| 22 | 21 | data.pid = bpf_get_current_pid_tgid(); |
| 23 | 22 | data.cookie = 0x12345678; |
| 24 | 23 | |
| @@ -371,6 +371,49 @@ static void do_usb_table(void *symval, unsigned long size, · 370 unmodified lines | ||
| 371 | 371 | do_usb_entry_multi(symval + i, mod); |
| 372 | 372 | } |
| 373 | 373 | |
| 374 | +static void do_of_entry_multi(void *symval, struct module *mod) | |
| 375 | +{ | |
| 376 | + char alias[500]; | |
| 377 | + int len; | |
| 378 | + char *tmp; | |
| 379 | + | |
| 380 | + DEF_FIELD_ADDR(symval, of_device_id, name); | |
| 381 | + DEF_FIELD_ADDR(symval, of_device_id, type); | |
| 382 | + DEF_FIELD_ADDR(symval, of_device_id, compatible); | |
| 383 | + | |
| 384 | + len = sprintf(alias, "of:N%sT%s", (*name)[0] ? *name : "*", | |
| 385 | + (*type)[0] ? *type : "*"); | |
| 386 | + | |
| 387 | + if (compatible[0]) | |
| 388 | + sprintf(&alias[len], "%sC%s", (*type)[0] ? "*" : "", | |
| 389 | + *compatible); | |
| 390 | + | |
| 391 | + /* Replace all whitespace with underscores */ | |
| 392 | + for (tmp = alias; tmp && *tmp; tmp++) | |
| 393 | + if (isspace(*tmp)) | |
| 394 | + *tmp = '_'; | |
| 395 | + | |
| 396 | + buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias); | |
| 397 | + strcat(alias, "C"); | |
| 398 | + add_wildcard(alias); | |
| 399 | + buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias); | |
| 400 | +} | |
| 401 | + | |
| 402 | +static void do_of_table(void *symval, unsigned long size, | |
| 403 | + struct module *mod) | |
| 404 | +{ | |
| 405 | + unsigned int i; | |
| 406 | + const unsigned long id_size = SIZE_of_device_id; | |
| 407 | + | |
| 408 | + device_id_check(mod->name, "of", size, id_size, symval); | |
| 409 | + | |
| 410 | + /* Leave last one: it's the terminator. */ | |
| 411 | + size -= id_size; | |
| 412 | + | |
| 413 | + for (i = 0; i < size; i += id_size) | |
| 414 | + do_of_entry_multi(symval + i, mod); | |
| 415 | +} | |
| 416 | + | |
| 374 | 417 | /* Looks like: hid:bNvNpN */ |
| 375 | 418 | static int do_hid_entry(const char *filename, |
| 376 | 419 | void *symval, char *alias) |
| @@ -684,30 +727,6 @@ static int do_pcmcia_entry(const char *filename, · 307 unmodified lines | ||
| 684 | 727 | } |
| 685 | 728 | ADD_TO_DEVTABLE("pcmcia", pcmcia_device_id, do_pcmcia_entry); |
| 686 | 729 | |
| 687 | −static int do_of_entry (const char *filename, void *symval, char *alias) | |
| 688 | −{ | |
| 689 | − int len; | |
| 690 | − char *tmp; | |
| 691 | − DEF_FIELD_ADDR(symval, of_device_id, name); | |
| 692 | − DEF_FIELD_ADDR(symval, of_device_id, type); | |
| 693 | − DEF_FIELD_ADDR(symval, of_device_id, compatible); | |
| 694 | − | |
| 695 | − len = sprintf(alias, "of:N%sT%s", (*name)[0] ? *name : "*", | |
| 696 | − (*type)[0] ? *type : "*"); | |
| 697 | − | |
| 698 | − if (compatible[0]) | |
| 699 | − sprintf(&alias[len], "%sC%s", (*type)[0] ? "*" : "", | |
| 700 | − *compatible); | |
| 701 | − | |
| 702 | − /* Replace all whitespace with underscores */ | |
| 703 | − for (tmp = alias; tmp && *tmp; tmp++) | |
| 704 | − if (isspace (*tmp)) | |
| 705 | − *tmp = '_'; | |
| 706 | − | |
| 707 | − return 1; | |
| 708 | −} | |
| 709 | −ADD_TO_DEVTABLE("of", of_device_id, do_of_entry); | |
| 710 | − | |
| 711 | 730 | static int do_vio_entry(const char *filename, void *symval, |
| 712 | 731 | char *alias) |
| 713 | 732 | { |
| @@ -1348,6 +1367,8 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, · 634 unmodified lines | ||
| 1348 | 1367 | /* First handle the "special" cases */ |
| 1349 | 1368 | if (sym_is(name, namelen, "usb")) |
| 1350 | 1369 | do_usb_table(symval, sym->st_size, mod); |
| 1370 | + if (sym_is(name, namelen, "of")) | |
| 1371 | + do_of_table(symval, sym->st_size, mod); | |
| 1351 | 1372 | else if (sym_is(name, namelen, "pnp")) |
| 1352 | 1373 | do_pnp_device_entry(symval, sym->st_size, mod); |
| 1353 | 1374 | else if (sym_is(name, namelen, "pnp_card")) |
| @@ -884,10 +884,10 @@ static char *func_tokens[] = { · 883 unmodified lines | ||
| 884 | 884 | "BPRM_CHECK", |
| 885 | 885 | "MODULE_CHECK", |
| 886 | 886 | "FIRMWARE_CHECK", |
| 887 | + "POST_SETATTR", | |
| 887 | 888 | "KEXEC_KERNEL_CHECK", |
| 888 | 889 | "KEXEC_INITRAMFS_CHECK", |
| 889 | − "POLICY_CHECK", | |
| 890 | − "POST_SETATTR" | |
| 890 | + "POLICY_CHECK" | |
| 891 | 891 | }; |
| 892 | 892 | |
| 893 | 893 | void *ima_policy_start(struct seq_file *m, loff_t *pos) |
| @@ -106,8 +106,9 @@ EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config); · 105 unmodified lines | ||
| 106 | 106 | * direction of the substream. If the substream is a playback stream the dst |
| 107 | 107 | * fields will be initialized, if it is a capture stream the src fields will be |
| 108 | 108 | * initialized. The {dst,src}_addr_width field will only be initialized if the |
| 109 | − * addr_width field of the DAI DMA data struct is not equal to | |
| 110 | − * DMA_SLAVE_BUSWIDTH_UNDEFINED. | |
| 109 | + * SND_DMAENGINE_PCM_DAI_FLAG_PACK flag is set or if the addr_width field of | |
| 110 | + * the DAI DMA data struct is not equal to DMA_SLAVE_BUSWIDTH_UNDEFINED. If | |
| 111 | + * both conditions are met the latter takes priority. | |
| 111 | 112 | */ |
| 112 | 113 | void snd_dmaengine_pcm_set_config_from_dai_data( |
| 113 | 114 | const struct snd_pcm_substream *substream, |
| @@ -117,11 +118,17 @@ void snd_dmaengine_pcm_set_config_from_dai_data( · 3 unmodified lines | ||
| 117 | 118 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 118 | 119 | slave_config->dst_addr = dma_data->addr; |
| 119 | 120 | slave_config->dst_maxburst = dma_data->maxburst; |
| 121 | + if (dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK) | |
| 122 | + slave_config->dst_addr_width = | |
| 123 | + DMA_SLAVE_BUSWIDTH_UNDEFINED; | |
| 120 | 124 | if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED) |
| 121 | 125 | slave_config->dst_addr_width = dma_data->addr_width; |
| 122 | 126 | } else { |
| 123 | 127 | slave_config->src_addr = dma_data->addr; |
| 124 | 128 | slave_config->src_maxburst = dma_data->maxburst; |
| 129 | + if (dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK) | |
| 130 | + slave_config->src_addr_width = | |
| 131 | + DMA_SLAVE_BUSWIDTH_UNDEFINED; | |
| 125 | 132 | if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED) |
| 126 | 133 | slave_config->src_addr_width = dma_data->addr_width; |
| 127 | 134 | } |
| @@ -9,30 +9,18 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/types.h> |
| 10 | 10 | #include <sound/asoundef.h> |
| 11 | 11 | #include <sound/pcm.h> |
| 12 | +#include <sound/pcm_params.h> | |
| 12 | 13 | #include <sound/pcm_iec958.h> |
| 13 | 14 | |
| 14 | −/** | |
| 15 | − * snd_pcm_create_iec958_consumer - create consumer format IEC958 channel status | |
| 16 | − * @runtime: pcm runtime structure with ->rate filled in | |
| 17 | − * @cs: channel status buffer, at least four bytes | |
| 18 | − * @len: length of channel status buffer | |
| 19 | − * | |
| 20 | − * Create the consumer format channel status data in @cs of maximum size | |
| 21 | − * @len corresponding to the parameters of the PCM runtime @runtime. | |
| 22 | − * | |
| 23 | − * Drivers may wish to tweak the contents of the buffer after creation. | |
| 24 | − * | |
| 25 | − * Returns: length of buffer, or negative error code if something failed. | |
| 26 | − */ | |
| 27 | −int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs, | |
| 28 | − size_t len) | |
| 15 | +static int create_iec958_consumer(uint rate, uint sample_width, | |
| 16 | + u8 *cs, size_t len) | |
| 29 | 17 | { |
| 30 | 18 | unsigned int fs, ws; |
| 31 | 19 | |
| 32 | 20 | if (len < 4) |
| 33 | 21 | return -EINVAL; |
| 34 | 22 | |
| 35 | − switch (runtime->rate) { | |
| 23 | + switch (rate) { | |
| 36 | 24 | case 32000: |
| 37 | 25 | fs = IEC958_AES3_CON_FS_32000; |
| 38 | 26 | break; |
| @@ -59,7 +47,7 @@ int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs, · 20 unmodified lines | ||
| 59 | 47 | } |
| 60 | 48 | |
| 61 | 49 | if (len > 4) { |
| 62 | − switch (snd_pcm_format_width(runtime->format)) { | |
| 50 | + switch (sample_width) { | |
| 63 | 51 | case 16: |
| 64 | 52 | ws = IEC958_AES4_CON_WORDLEN_20_16; |
| 65 | 53 | break; |
| @@ -71,6 +59,7 @@ int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs, · 5 unmodified lines | ||
| 71 | 59 | IEC958_AES4_CON_MAX_WORDLEN_24; |
| 72 | 60 | break; |
| 73 | 61 | case 24: |
| 62 | + case 32: /* Assume 24-bit width for 32-bit samples. */ | |
| 74 | 63 | ws = IEC958_AES4_CON_WORDLEN_24_20 | |
| 75 | 64 | IEC958_AES4_CON_MAX_WORDLEN_24; |
| 76 | 65 | break; |
| @@ -92,4 +81,46 @@ int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs, · 15 unmodified lines | ||
| 92 | 81 | |
| 93 | 82 | return len; |
| 94 | 83 | } |
| 84 | + | |
| 85 | +/** | |
| 86 | + * snd_pcm_create_iec958_consumer - create consumer format IEC958 channel status | |
| 87 | + * @runtime: pcm runtime structure with ->rate filled in | |
| 88 | + * @cs: channel status buffer, at least four bytes | |
| 89 | + * @len: length of channel status buffer | |
| 90 | + * | |
| 91 | + * Create the consumer format channel status data in @cs of maximum size | |
| 92 | + * @len corresponding to the parameters of the PCM runtime @runtime. | |
| 93 | + * | |
| 94 | + * Drivers may wish to tweak the contents of the buffer after creation. | |
| 95 | + * | |
| 96 | + * Returns: length of buffer, or negative error code if something failed. | |
| 97 | + */ | |
| 98 | +int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs, | |
| 99 | + size_t len) | |
| 100 | +{ | |
| 101 | + return create_iec958_consumer(runtime->rate, | |
| 102 | + snd_pcm_format_width(runtime->format), | |
| 103 | + cs, len); | |
| 104 | +} | |
| 95 | 105 | EXPORT_SYMBOL(snd_pcm_create_iec958_consumer); |
| 106 | + | |
| 107 | +/** | |
| 108 | + * snd_pcm_create_iec958_consumer_hw_params - create IEC958 channel status | |
| 109 | + * @hw_params: the hw_params instance for extracting rate and sample format | |
| 110 | + * @cs: channel status buffer, at least four bytes | |
| 111 | + * @len: length of channel status buffer | |
| 112 | + * | |
| 113 | + * Create the consumer format channel status data in @cs of maximum size | |
| 114 | + * @len corresponding to the parameters of the PCM runtime @runtime. | |
| 115 | + * | |
| 116 | + * Drivers may wish to tweak the contents of the buffer after creation. | |
| 117 | + * | |
| 118 | + * Returns: length of buffer, or negative error code if something failed. | |
| 119 | + */ | |
| 120 | +int snd_pcm_create_iec958_consumer_hw_params(struct snd_pcm_hw_params *params, | |
| 121 | + u8 *cs, size_t len) | |
| 122 | +{ | |
| 123 | + return create_iec958_consumer(params_rate(params), params_width(params), | |
| 124 | + cs, len); | |
| 125 | +} | |
| 126 | +EXPORT_SYMBOL(snd_pcm_create_iec958_consumer_hw_params); | |
| @@ -105,6 +105,9 @@ int snd_hdac_ext_bus_init(struct hdac_ext_bus *ebus, struct device *dev, · 104 unmodified lines | ||
| 105 | 105 | INIT_LIST_HEAD(&ebus->hlink_list); |
| 106 | 106 | ebus->idx = idx++; |
| 107 | 107 | |
| 108 | + mutex_init(&ebus->lock); | |
| 109 | + ebus->cmd_dma_state = true; | |
| 110 | + | |
| 108 | 111 | return 0; |
| 109 | 112 | } |
| 110 | 113 | EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_init); |
| @@ -186,6 +186,9 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *ebus) · 185 unmodified lines | ||
| 186 | 186 | hlink->lcaps = readl(hlink->ml_addr + AZX_REG_ML_LCAP); |
| 187 | 187 | hlink->lsdiid = readw(hlink->ml_addr + AZX_REG_ML_LSDIID); |
| 188 | 188 | |
| 189 | + /* since link in On, update the ref */ | |
| 190 | + hlink->ref_count = 1; | |
| 191 | + | |
| 189 | 192 | list_add_tail(&hlink->list, &ebus->hlink_list); |
| 190 | 193 | } |
| 191 | 194 | |
| @@ -327,3 +330,66 @@ int snd_hdac_ext_bus_link_power_down_all(struct hdac_ext_bus *ebus) · 135 unmodified lines | ||
| 327 | 330 | return 0; |
| 328 | 331 | } |
| 329 | 332 | EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down_all); |
| 333 | + | |
| 334 | +int snd_hdac_ext_bus_link_get(struct hdac_ext_bus *ebus, | |
| 335 | + struct hdac_ext_link *link) | |
| 336 | +{ | |
| 337 | + int ret = 0; | |
| 338 | + | |
| 339 | + mutex_lock(&ebus->lock); | |
| 340 | + | |
| 341 | + /* | |
| 342 | + * if we move from 0 to 1, count will be 1 so power up this link | |
| 343 | + * as well, also check the dma status and trigger that | |
| 344 | + */ | |
| 345 | + if (++link->ref_count == 1) { | |
| 346 | + if (!ebus->cmd_dma_state) { | |
| 347 | + snd_hdac_bus_init_cmd_io(&ebus->bus); | |
| 348 | + ebus->cmd_dma_state = true; | |
| 349 | + } | |
| 350 | + | |
| 351 | + ret = snd_hdac_ext_bus_link_power_up(link); | |
| 352 | + } | |
| 353 | + | |
| 354 | + mutex_unlock(&ebus->lock); | |
| 355 | + return ret; | |
| 356 | +} | |
| 357 | +EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_get); | |
| 358 | + | |
| 359 | +int snd_hdac_ext_bus_link_put(struct hdac_ext_bus *ebus, | |
| 360 | + struct hdac_ext_link *link) | |
| 361 | +{ | |
| 362 | + int ret = 0; | |
| 363 | + struct hdac_ext_link *hlink; | |
| 364 | + bool link_up = false; | |
| 365 | + | |
| 366 | + mutex_lock(&ebus->lock); | |
| 367 | + | |
| 368 | + /* | |
| 369 | + * if we move from 1 to 0, count will be 0 | |
| 370 | + * so power down this link as well | |
| 371 | + */ | |
| 372 | + if (--link->ref_count == 0) { | |
| 373 | + ret = snd_hdac_ext_bus_link_power_down(link); | |
| 374 | + | |
| 375 | + /* | |
| 376 | + * now check if all links are off, if so turn off | |
| 377 | + * cmd dma as well | |
| 378 | + */ | |
| 379 | + list_for_each_entry(hlink, &ebus->hlink_list, list) { | |
| 380 | + if (hlink->ref_count) { | |
| 381 | + link_up = true; | |
| 382 | + break; | |
| 383 | + } | |
| 384 | + } | |
| 385 | + | |
| 386 | + if (!link_up) { | |
| 387 | + snd_hdac_bus_stop_cmd_io(&ebus->bus); | |
| 388 | + ebus->cmd_dma_state = false; | |
| 389 | + } | |
| 390 | + } | |
| 391 | + | |
| 392 | + mutex_unlock(&ebus->lock); | |
| 393 | + return ret; | |
| 394 | +} | |
| 395 | +EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_put); | |
| @@ -16,6 +16,16 @@ static inline int get_wcaps_type(unsigned int wcaps) · 15 unmodified lines | ||
| 16 | 16 | return (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; |
| 17 | 17 | } |
| 18 | 18 | |
| 19 | +static inline unsigned int get_wcaps_channels(u32 wcaps) | |
| 20 | +{ | |
| 21 | + unsigned int chans; | |
| 22 | + | |
| 23 | + chans = (wcaps & AC_WCAP_CHAN_CNT_EXT) >> 13; | |
| 24 | + chans = (chans + 1) * 2; | |
| 25 | + | |
| 26 | + return chans; | |
| 27 | +} | |
| 28 | + | |
| 19 | 29 | extern const struct attribute_group *hdac_dev_attr_groups[]; |
| 20 | 30 | int hda_widget_sysfs_init(struct hdac_device *codec); |
| 21 | 31 | void hda_widget_sysfs_exit(struct hdac_device *codec); |
| @@ -652,7 +652,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, · 651 unmodified lines | ||
| 652 | 652 | rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) |
| 653 | 653 | | SSC_BF(RCMR_STTDLY, 1) |
| 654 | 654 | | SSC_BF(RCMR_START, SSC_START_RISING_RF) |
| 655 | − | SSC_BF(RCMR_CKI, SSC_CKI_FALLING) | |
| 655 | + | SSC_BF(RCMR_CKI, SSC_CKI_RISING) | |
| 656 | 656 | | SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
| 657 | 657 | | SSC_BF(RCMR_CKS, SSC_CKS_DIV); |
| 658 | 658 | |
| @@ -692,7 +692,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, · 33 unmodified lines | ||
| 692 | 692 | rcmr = SSC_BF(RCMR_PERIOD, 0) |
| 693 | 693 | | SSC_BF(RCMR_STTDLY, START_DELAY) |
| 694 | 694 | | SSC_BF(RCMR_START, SSC_START_RISING_RF) |
| 695 | − | SSC_BF(RCMR_CKI, SSC_CKI_FALLING) | |
| 695 | + | SSC_BF(RCMR_CKI, SSC_CKI_RISING) | |
| 696 | 696 | | SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
| 697 | 697 | | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? |
| 698 | 698 | SSC_CKS_PIN : SSC_CKS_CLOCK); |
| @@ -206,8 +206,8 @@ static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream, · 205 unmodified lines | ||
| 206 | 206 | stype = substream->stream; |
| 207 | 207 | pcd = to_dmadata(substream); |
| 208 | 208 | |
| 209 | − DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d " | |
| 210 | − "runtime->min_align %d\n", | |
| 209 | + DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %zu " | |
| 210 | + "runtime->min_align %lu\n", | |
| 211 | 211 | (unsigned long)runtime->dma_area, |
| 212 | 212 | (unsigned long)runtime->dma_addr, runtime->dma_bytes, |
| 213 | 213 | runtime->min_align); |
| @@ -259,6 +259,9 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, · 258 unmodified lines | ||
| 259 | 259 | case SNDRV_PCM_FORMAT_S16_LE: |
| 260 | 260 | data_length = 16; |
| 261 | 261 | break; |
| 262 | + case SNDRV_PCM_FORMAT_S24_LE: | |
| 263 | + data_length = 24; | |
| 264 | + break; | |
| 262 | 265 | case SNDRV_PCM_FORMAT_S32_LE: |
| 263 | 266 | data_length = 32; |
| 264 | 267 | break; |
| @@ -273,13 +276,20 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, · 8 unmodified lines | ||
| 273 | 276 | /* otherwise calculate a fitting block ratio */ |
| 274 | 277 | bclk_ratio = 2 * data_length; |
| 275 | 278 | |
| 276 | − /* set target clock rate*/ | |
| 277 | − clk_set_rate(dev->clk, sampling_rate * bclk_ratio); | |
| 279 | + /* Clock should only be set up here if CPU is clock master */ | |
| 280 | + switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { | |
| 281 | + case SND_SOC_DAIFMT_CBS_CFS: | |
| 282 | + case SND_SOC_DAIFMT_CBS_CFM: | |
| 283 | + clk_set_rate(dev->clk, sampling_rate * bclk_ratio); | |
| 284 | + break; | |
| 285 | + default: | |
| 286 | + break; | |
| 287 | + } | |
| 278 | 288 | |
| 279 | 289 | /* Setup the frame format */ |
| 280 | 290 | format = BCM2835_I2S_CHEN; |
| 281 | 291 | |
| 282 | − if (data_length > 24) | |
| 292 | + if (data_length >= 24) | |
| 283 | 293 | format |= BCM2835_I2S_CHWEX; |
| 284 | 294 | |
| 285 | 295 | format |= BCM2835_I2S_CHWID((data_length-8)&0xf); |
| @@ -570,6 +580,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { · 284 unmodified lines | ||
| 570 | 580 | .channels_max = 2, |
| 571 | 581 | .rates = SNDRV_PCM_RATE_8000_192000, |
| 572 | 582 | .formats = SNDRV_PCM_FMTBIT_S16_LE |
| 583 | + | SNDRV_PCM_FMTBIT_S24_LE | |
| 573 | 584 | | SNDRV_PCM_FMTBIT_S32_LE |
| 574 | 585 | }, |
| 575 | 586 | .capture = { |
| @@ -577,6 +588,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { · 1 unmodified line | ||
| 577 | 588 | .channels_max = 2, |
| 578 | 589 | .rates = SNDRV_PCM_RATE_8000_192000, |
| 579 | 590 | .formats = SNDRV_PCM_FMTBIT_S16_LE |
| 591 | + | SNDRV_PCM_FMTBIT_S24_LE | |
| 580 | 592 | | SNDRV_PCM_FMTBIT_S32_LE |
| 581 | 593 | }, |
| 582 | 594 | .ops = &bcm2835_i2s_dai_ops, |
| @@ -678,6 +690,15 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) · 95 unmodified lines | ||
| 678 | 690 | dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].maxburst = 2; |
| 679 | 691 | dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].maxburst = 2; |
| 680 | 692 | |
| 693 | + /* | |
| 694 | + * Set the PACK flag to enable S16_LE support (2 S16_LE values | |
| 695 | + * packed into 32-bit transfers). | |
| 696 | + */ | |
| 697 | + dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].flags = | |
| 698 | + SND_DMAENGINE_PCM_DAI_FLAG_PACK; | |
| 699 | + dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].flags = | |
| 700 | + SND_DMAENGINE_PCM_DAI_FLAG_PACK; | |
| 701 | + | |
| 681 | 702 | /* BCLK ratio - use default */ |
| 682 | 703 | dev->bclk_ratio = 0; |
| 683 | 704 | |
| @@ -88,12 +88,14 @@ config SND_SOC_ALL_CODECS · 87 unmodified lines | ||
| 88 | 88 | select SND_SOC_MC13783 if MFD_MC13XXX |
| 89 | 89 | select SND_SOC_ML26124 if I2C |
| 90 | 90 | select SND_SOC_NAU8825 if I2C |
| 91 | + select SND_SOC_HDMI_CODEC | |
| 91 | 92 | select SND_SOC_PCM1681 if I2C |
| 92 | 93 | select SND_SOC_PCM179X_I2C if I2C |
| 93 | 94 | select SND_SOC_PCM179X_SPI if SPI_MASTER |
| 94 | 95 | select SND_SOC_PCM3008 |
| 95 | 96 | select SND_SOC_PCM3168A_I2C if I2C |
| 96 | 97 | select SND_SOC_PCM3168A_SPI if SPI_MASTER |
| 98 | + select SND_SOC_PCM5102A | |
| 97 | 99 | select SND_SOC_PCM512x_I2C if I2C |
| 98 | 100 | select SND_SOC_PCM512x_SPI if SPI_MASTER |
| 99 | 101 | select SND_SOC_RT286 if I2C |
| @@ -477,6 +479,11 @@ config SND_SOC_BT_SCO · 377 unmodified lines | ||
| 477 | 479 | config SND_SOC_DMIC |
| 478 | 480 | tristate |
| 479 | 481 | |
| 482 | +config SND_SOC_HDMI_CODEC | |
| 483 | + tristate | |
| 484 | + select SND_PCM_ELD | |
| 485 | + select SND_PCM_IEC958 | |
| 486 | + | |
| 480 | 487 | config SND_SOC_ES8328 |
| 481 | 488 | tristate "Everest Semi ES8328 CODEC" |
| 482 | 489 | |
| @@ -575,6 +582,9 @@ config SND_SOC_PCM3168A_SPI · 92 unmodified lines | ||
| 575 | 582 | select SND_SOC_PCM3168A |
| 576 | 583 | select REGMAP_SPI |
| 577 | 584 | |
| 585 | +config SND_SOC_PCM5102A | |
| 586 | + tristate | |
| 587 | + | |
| 578 | 588 | config SND_SOC_PCM512x |
| 579 | 589 | tristate |
| 580 | 590 | |
| @@ -81,6 +81,7 @@ snd-soc-max9850-objs := max9850.o · 80 unmodified lines | ||
| 81 | 81 | snd-soc-mc13783-objs := mc13783.o |
| 82 | 82 | snd-soc-ml26124-objs := ml26124.o |
| 83 | 83 | snd-soc-nau8825-objs := nau8825.o |
| 84 | +snd-soc-hdmi-codec-objs := hdmi-codec.o | |
| 84 | 85 | snd-soc-pcm1681-objs := pcm1681.o |
| 85 | 86 | snd-soc-pcm179x-codec-objs := pcm179x.o |
| 86 | 87 | snd-soc-pcm179x-i2c-objs := pcm179x-i2c.o |
| @@ -89,6 +90,7 @@ snd-soc-pcm3008-objs := pcm3008.o · 2 unmodified lines | ||
| 89 | 90 | snd-soc-pcm3168a-objs := pcm3168a.o |
| 90 | 91 | snd-soc-pcm3168a-i2c-objs := pcm3168a-i2c.o |
| 91 | 92 | snd-soc-pcm3168a-spi-objs := pcm3168a-spi.o |
| 93 | +snd-soc-pcm5102a-objs := pcm5102a.o | |
| 92 | 94 | snd-soc-pcm512x-objs := pcm512x.o |
| 93 | 95 | snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o |
| 94 | 96 | snd-soc-pcm512x-spi-objs := pcm512x-spi.o |
| @@ -290,6 +292,7 @@ obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o · 195 unmodified lines | ||
| 290 | 292 | obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o |
| 291 | 293 | obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o |
| 292 | 294 | obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o |
| 295 | +obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o | |
| 293 | 296 | obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o |
| 294 | 297 | obj-$(CONFIG_SND_SOC_PCM179X) += snd-soc-pcm179x-codec.o |
| 295 | 298 | obj-$(CONFIG_SND_SOC_PCM179X_I2C) += snd-soc-pcm179x-i2c.o |
| @@ -298,6 +301,7 @@ obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o · 2 unmodified lines | ||
| 298 | 301 | obj-$(CONFIG_SND_SOC_PCM3168A) += snd-soc-pcm3168a.o |
| 299 | 302 | obj-$(CONFIG_SND_SOC_PCM3168A_I2C) += snd-soc-pcm3168a-i2c.o |
| 300 | 303 | obj-$(CONFIG_SND_SOC_PCM3168A_SPI) += snd-soc-pcm3168a-spi.o |
| 304 | +obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o | |
| 301 | 305 | obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o |
| 302 | 306 | obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o |
| 303 | 307 | obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o |
| @@ -608,9 +608,7 @@ static struct clk *ak4642_of_parse_mcko(struct device *dev) · 607 unmodified lines | ||
| 608 | 608 | |
| 609 | 609 | of_property_read_string(np, "clock-output-names", &clk_name); |
| 610 | 610 | |
| 611 | − clk = clk_register_fixed_rate(dev, clk_name, parent_clk_name, | |
| 612 | − (parent_clk_name) ? 0 : CLK_IS_ROOT, | |
| 613 | − rate); | |
| 611 | + clk = clk_register_fixed_rate(dev, clk_name, parent_clk_name, 0, rate); | |
| 614 | 612 | if (!IS_ERR(clk)) |
| 615 | 613 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
| 616 | 614 | |
| @@ -221,6 +221,8 @@ int arizona_init_spk(struct snd_soc_codec *codec) · 220 unmodified lines | ||
| 221 | 221 | |
| 222 | 222 | switch (arizona->type) { |
| 223 | 223 | case WM8997: |
| 224 | + case CS47L24: | |
| 225 | + case WM1831: | |
| 224 | 226 | break; |
| 225 | 227 | default: |
| 226 | 228 | ret = snd_soc_dapm_new_controls(dapm, &arizona_spkr, 1); |
| @@ -1134,7 +1136,6 @@ int arizona_anc_ev(struct snd_soc_dapm_widget *w, · 907 unmodified lines | ||
| 1134 | 1136 | int event) |
| 1135 | 1137 | { |
| 1136 | 1138 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
| 1137 | − unsigned int mask = 0x3 << w->shift; | |
| 1138 | 1139 | unsigned int val; |
| 1139 | 1140 | |
| 1140 | 1141 | switch (event) { |
| @@ -1148,7 +1149,7 @@ int arizona_anc_ev(struct snd_soc_dapm_widget *w, · 7 unmodified lines | ||
| 1148 | 1149 | return 0; |
| 1149 | 1150 | } |
| 1150 | 1151 | |
| 1151 | − snd_soc_update_bits(codec, ARIZONA_CLOCK_CONTROL, mask, val); | |
| 1152 | + snd_soc_write(codec, ARIZONA_CLOCK_CONTROL, val); | |
| 1152 | 1153 | |
| 1153 | 1154 | return 0; |
| 1154 | 1155 | } |
| @@ -2047,7 +2048,21 @@ static int arizona_calc_fratio(struct arizona_fll *fll, · 892 unmodified lines | ||
| 2047 | 2048 | init_ratio, Fref, refdiv); |
| 2048 | 2049 | |
| 2049 | 2050 | while (div <= ARIZONA_FLL_MAX_REFDIV) { |
| 2050 | − for (ratio = init_ratio; ratio <= ARIZONA_FLL_MAX_FRATIO; | |
| 2051 | + /* start from init_ratio because this may already give a | |
| 2052 | + * fractional N.K | |
| 2053 | + */ | |
| 2054 | + for (ratio = init_ratio; ratio > 0; ratio--) { | |
| 2055 | + if (target % (ratio * Fref)) { | |
| 2056 | + cfg->refdiv = refdiv; | |
| 2057 | + cfg->fratio = ratio - 1; | |
| 2058 | + arizona_fll_dbg(fll, | |
| 2059 | + "pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n", | |
| 2060 | + Fref, refdiv, div, ratio); | |
| 2061 | + return ratio; | |
| 2062 | + } | |
| 2063 | + } | |
| 2064 | + | |
| 2065 | + for (ratio = init_ratio + 1; ratio <= ARIZONA_FLL_MAX_FRATIO; | |
| 2051 | 2066 | ratio++) { |
| 2052 | 2067 | if ((ARIZONA_FLL_VCO_CORNER / 2) / |
| 2053 | 2068 | (fll->vco_mult * ratio) < Fref) { |
| @@ -2073,17 +2088,6 @@ static int arizona_calc_fratio(struct arizona_fll *fll, · 19 unmodified lines | ||
| 2073 | 2088 | } |
| 2074 | 2089 | } |
| 2075 | 2090 | |
| 2076 | − for (ratio = init_ratio - 1; ratio > 0; ratio--) { | |
| 2077 | − if (target % (ratio * Fref)) { | |
| 2078 | − cfg->refdiv = refdiv; | |
| 2079 | − cfg->fratio = ratio - 1; | |
| 2080 | − arizona_fll_dbg(fll, | |
| 2081 | − "pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n", | |
| 2082 | − Fref, refdiv, div, ratio); | |
| 2083 | − return ratio; | |
| 2084 | − } | |
| 2085 | − } | |
| 2086 | − | |
| 2087 | 2091 | div *= 2; |
| 2088 | 2092 | Fref /= 2; |
| 2089 | 2093 | refdiv++; |
| @@ -56,7 +56,7 @@ struct cs42l56_private { · 55 unmodified lines | ||
| 56 | 56 | u8 iface; |
| 57 | 57 | u8 iface_fmt; |
| 58 | 58 | u8 iface_inv; |
| 59 | −#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | |
| 59 | +#if IS_ENABLED(CONFIG_INPUT) | |
| 60 | 60 | struct input_dev *beep; |
| 61 | 61 | struct work_struct beep_work; |
| 62 | 62 | int beep_rate; |
| @@ -807,6 +807,9 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = { · 806 unmodified lines | ||
| 807 | 807 | { "IN2L PGA", NULL, "IN2L" }, |
| 808 | 808 | { "IN2R PGA", NULL, "IN2R" }, |
| 809 | 809 | |
| 810 | + { "Audio Trace DSP", NULL, "DSP2" }, | |
| 811 | + { "Audio Trace DSP", NULL, "SYSCLK" }, | |
| 812 | + | |
| 810 | 813 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), |
| 811 | 814 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), |
| 812 | 815 | |
| @@ -1016,6 +1019,27 @@ static struct snd_soc_dai_driver cs47l24_dai[] = { · 203 unmodified lines | ||
| 1016 | 1019 | .formats = CS47L24_FORMATS, |
| 1017 | 1020 | }, |
| 1018 | 1021 | }, |
| 1022 | + { | |
| 1023 | + .name = "cs47l24-cpu-trace", | |
| 1024 | + .capture = { | |
| 1025 | + .stream_name = "Audio Trace CPU", | |
| 1026 | + .channels_min = 1, | |
| 1027 | + .channels_max = 6, | |
| 1028 | + .rates = CS47L24_RATES, | |
| 1029 | + .formats = CS47L24_FORMATS, | |
| 1030 | + }, | |
| 1031 | + .compress_new = snd_soc_new_compress, | |
| 1032 | + }, | |
| 1033 | + { | |
| 1034 | + .name = "cs47l24-dsp-trace", | |
| 1035 | + .capture = { | |
| 1036 | + .stream_name = "Audio Trace DSP", | |
| 1037 | + .channels_min = 1, | |
| 1038 | + .channels_max = 6, | |
| 1039 | + .rates = CS47L24_RATES, | |
| 1040 | + .formats = CS47L24_FORMATS, | |
| 1041 | + }, | |
| 1042 | + }, | |
| 1019 | 1043 | }; |
| 1020 | 1044 | |
| 1021 | 1045 | static int cs47l24_open(struct snd_compr_stream *stream) |
| @@ -1027,6 +1051,8 @@ static int cs47l24_open(struct snd_compr_stream *stream) · 5 unmodified lines | ||
| 1027 | 1051 | |
| 1028 | 1052 | if (strcmp(rtd->codec_dai->name, "cs47l24-dsp-voicectrl") == 0) { |
| 1029 | 1053 | n_adsp = 2; |
| 1054 | + } else if (strcmp(rtd->codec_dai->name, "cs47l24-dsp-trace") == 0) { | |
| 1055 | + n_adsp = 1; | |
| 1030 | 1056 | } else { |
| 1031 | 1057 | dev_err(arizona->dev, |
| 1032 | 1058 | "No suitable compressed stream for DAI '%s'\n", |
| @@ -1041,10 +1067,16 @@ static irqreturn_t cs47l24_adsp2_irq(int irq, void *data) · 8 unmodified lines | ||
| 1041 | 1067 | { |
| 1042 | 1068 | struct cs47l24_priv *priv = data; |
| 1043 | 1069 | struct arizona *arizona = priv->core.arizona; |
| 1044 | − int ret; | |
| 1070 | + int serviced = 0; | |
| 1071 | + int i, ret; | |
| 1045 | 1072 | |
| 1046 | − ret = wm_adsp_compr_handle_irq(&priv->core.adsp[2]); | |
| 1047 | − if (ret == -ENODEV) { | |
| 1073 | + for (i = 1; i <= 2; ++i) { | |
| 1074 | + ret = wm_adsp_compr_handle_irq(&priv->core.adsp[i]); | |
| 1075 | + if (ret != -ENODEV) | |
| 1076 | + serviced++; | |
| 1077 | + } | |
| 1078 | + | |
| 1079 | + if (!serviced) { | |
| 1048 | 1080 | dev_err(arizona->dev, "Spurious compressed data IRQ\n"); |
| 1049 | 1081 | return IRQ_NONE; |
| 1050 | 1082 | } |
| @@ -1160,6 +1192,7 @@ static struct snd_compr_ops cs47l24_compr_ops = { · 109 unmodified lines | ||
| 1160 | 1192 | static struct snd_soc_platform_driver cs47l24_compr_platform = { |
| 1161 | 1193 | .compr_ops = &cs47l24_compr_ops, |
| 1162 | 1194 | }; |
| 1195 | + | |
| 1163 | 1196 | static int cs47l24_probe(struct platform_device *pdev) |
| 1164 | 1197 | { |
| 1165 | 1198 | struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); |
| @@ -1228,9 +1261,9 @@ static int cs47l24_probe(struct platform_device *pdev) · 62 unmodified lines | ||
| 1228 | 1261 | dev_err(&pdev->dev, "Failed to register platform: %d\n", ret); |
| 1229 | 1262 | return ret; |
| 1230 | 1263 | } |
| 1264 | + | |
| 1231 | 1265 | ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_cs47l24, |
| 1232 | 1266 | cs47l24_dai, ARRAY_SIZE(cs47l24_dai)); |
| 1233 | − | |
| 1234 | 1267 | if (ret < 0) { |
| 1235 | 1268 | dev_err(&pdev->dev, "Failed to register codec: %d\n", ret); |
| 1236 | 1269 | snd_soc_unregister_platform(&pdev->dev); |
| @@ -1241,10 +1274,15 @@ static int cs47l24_probe(struct platform_device *pdev) · 4 unmodified lines | ||
| 1241 | 1274 | |
| 1242 | 1275 | static int cs47l24_remove(struct platform_device *pdev) |
| 1243 | 1276 | { |
| 1277 | + struct cs47l24_priv *cs47l24 = platform_get_drvdata(pdev); | |
| 1278 | + | |
| 1244 | 1279 | snd_soc_unregister_platform(&pdev->dev); |
| 1245 | 1280 | snd_soc_unregister_codec(&pdev->dev); |
| 1246 | 1281 | pm_runtime_disable(&pdev->dev); |
| 1247 | 1282 | |
| 1283 | + wm_adsp2_remove(&cs47l24->core.adsp[1]); | |
| 1284 | + wm_adsp2_remove(&cs47l24->core.adsp[2]); | |
| 1285 | + | |
| 1248 | 1286 | return 0; |
| 1249 | 1287 | } |
| 1250 | 1288 | |
| @@ -725,6 +725,68 @@ static const struct snd_kcontrol_new da7213_dapm_mixoutr_controls[] = { · 724 unmodified lines | ||
| 725 | 725 | }; |
| 726 | 726 | |
| 727 | 727 | |
| 728 | +/* | |
| 729 | + * DAPM Events | |
| 730 | + */ | |
| 731 | + | |
| 732 | +static int da7213_dai_event(struct snd_soc_dapm_widget *w, | |
| 733 | + struct snd_kcontrol *kcontrol, int event) | |
| 734 | +{ | |
| 735 | + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | |
| 736 | + struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); | |
| 737 | + u8 pll_ctrl, pll_status; | |
| 738 | + int i = 0; | |
| 739 | + bool srm_lock = false; | |
| 740 | + | |
| 741 | + switch (event) { | |
| 742 | + case SND_SOC_DAPM_PRE_PMU: | |
| 743 | + /* Enable DAI clks for master mode */ | |
| 744 | + if (da7213->master) | |
| 745 | + snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE, | |
| 746 | + DA7213_DAI_CLK_EN_MASK, | |
| 747 | + DA7213_DAI_CLK_EN_MASK); | |
| 748 | + | |
| 749 | + /* PC synchronised to DAI */ | |
| 750 | + snd_soc_update_bits(codec, DA7213_PC_COUNT, | |
| 751 | + DA7213_PC_FREERUN_MASK, 0); | |
| 752 | + | |
| 753 | + /* Slave mode, if SRM not enabled no need for status checks */ | |
| 754 | + pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL); | |
| 755 | + if (!(pll_ctrl & DA7213_PLL_SRM_EN)) | |
| 756 | + return 0; | |
| 757 | + | |
| 758 | + /* Check SRM has locked */ | |
| 759 | + do { | |
| 760 | + pll_status = snd_soc_read(codec, DA7213_PLL_STATUS); | |
| 761 | + if (pll_status & DA7219_PLL_SRM_LOCK) { | |
| 762 | + srm_lock = true; | |
| 763 | + } else { | |
| 764 | + ++i; | |
| 765 | + msleep(50); | |
| 766 | + } | |
| 767 | + } while ((i < DA7213_SRM_CHECK_RETRIES) & (!srm_lock)); | |
| 768 | + | |
| 769 | + if (!srm_lock) | |
| 770 | + dev_warn(codec->dev, "SRM failed to lock\n"); | |
| 771 | + | |
| 772 | + return 0; | |
| 773 | + case SND_SOC_DAPM_POST_PMD: | |
| 774 | + /* PC free-running */ | |
| 775 | + snd_soc_update_bits(codec, DA7213_PC_COUNT, | |
| 776 | + DA7213_PC_FREERUN_MASK, | |
| 777 | + DA7213_PC_FREERUN_MASK); | |
| 778 | + | |
| 779 | + /* Disable DAI clks if in master mode */ | |
| 780 | + if (da7213->master) | |
| 781 | + snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE, | |
| 782 | + DA7213_DAI_CLK_EN_MASK, 0); | |
| 783 | + return 0; | |
| 784 | + default: | |
| 785 | + return -EINVAL; | |
| 786 | + } | |
| 787 | +} | |
| 788 | + | |
| 789 | + | |
| 728 | 790 | /* |
| 729 | 791 | * DAPM widgets |
| 730 | 792 | */ |
| @@ -736,7 +798,8 @@ static const struct snd_soc_dapm_widget da7213_dapm_widgets[] = { · 5 unmodified lines | ||
| 736 | 798 | |
| 737 | 799 | /* Use a supply here as this controls both input & output DAIs */ |
| 738 | 800 | SND_SOC_DAPM_SUPPLY("DAI", DA7213_DAI_CTRL, DA7213_DAI_EN_SHIFT, |
| 739 | − DA7213_NO_INVERT, NULL, 0), | |
| 801 | + DA7213_NO_INVERT, da7213_dai_event, | |
| 802 | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
| 740 | 803 | |
| 741 | 804 | /* |
| 742 | 805 | * Input |
| @@ -1143,11 +1206,9 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) · 400 unmodified lines | ||
| 1143 | 1206 | /* Set master/slave mode */ |
| 1144 | 1207 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
| 1145 | 1208 | case SND_SOC_DAIFMT_CBM_CFM: |
| 1146 | − dai_clk_mode |= DA7213_DAI_CLK_EN_MASTER_MODE; | |
| 1147 | 1209 | da7213->master = true; |
| 1148 | 1210 | break; |
| 1149 | 1211 | case SND_SOC_DAIFMT_CBS_CFS: |
| 1150 | − dai_clk_mode |= DA7213_DAI_CLK_EN_SLAVE_MODE; | |
| 1151 | 1212 | da7213->master = false; |
| 1152 | 1213 | break; |
| 1153 | 1214 | default: |
| @@ -1281,28 +1342,28 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, · 127 unmodified lines | ||
| 1281 | 1342 | pll_ctrl = 0; |
| 1282 | 1343 | |
| 1283 | 1344 | /* Workout input divider based on MCLK rate */ |
| 1284 | − if ((da7213->mclk_rate == 32768) && (source == DA7213_SYSCLK_PLL)) { | |
| 1345 | + if (da7213->mclk_rate == 32768) { | |
| 1285 | 1346 | /* 32KHz PLL Mode */ |
| 1286 | − indiv_bits = DA7213_PLL_INDIV_10_20_MHZ; | |
| 1287 | − indiv = DA7213_PLL_INDIV_10_20_MHZ_VAL; | |
| 1347 | + indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ; | |
| 1348 | + indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL; | |
| 1288 | 1349 | freq_ref = 3750000; |
| 1289 | 1350 | pll_ctrl |= DA7213_PLL_32K_MODE; |
| 1290 | 1351 | } else { |
| 1291 | 1352 | /* 5 - 54MHz MCLK */ |
| 1292 | 1353 | if (da7213->mclk_rate < 5000000) { |
| 1293 | 1354 | goto pll_err; |
| 1294 | − } else if (da7213->mclk_rate <= 10000000) { | |
| 1295 | − indiv_bits = DA7213_PLL_INDIV_5_10_MHZ; | |
| 1296 | − indiv = DA7213_PLL_INDIV_5_10_MHZ_VAL; | |
| 1297 | − } else if (da7213->mclk_rate <= 20000000) { | |
| 1298 | − indiv_bits = DA7213_PLL_INDIV_10_20_MHZ; | |
| 1299 | − indiv = DA7213_PLL_INDIV_10_20_MHZ_VAL; | |
| 1300 | − } else if (da7213->mclk_rate <= 40000000) { | |
| 1301 | − indiv_bits = DA7213_PLL_INDIV_20_40_MHZ; | |
| 1302 | − indiv = DA7213_PLL_INDIV_20_40_MHZ_VAL; | |
| 1355 | + } else if (da7213->mclk_rate <= 9000000) { | |
| 1356 | + indiv_bits = DA7213_PLL_INDIV_5_TO_9_MHZ; | |
| 1357 | + indiv = DA7213_PLL_INDIV_5_TO_9_MHZ_VAL; | |
| 1358 | + } else if (da7213->mclk_rate <= 18000000) { | |
| 1359 | + indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ; | |
| 1360 | + indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL; | |
| 1361 | + } else if (da7213->mclk_rate <= 36000000) { | |
| 1362 | + indiv_bits = DA7213_PLL_INDIV_18_TO_36_MHZ; | |
| 1363 | + indiv = DA7213_PLL_INDIV_18_TO_36_MHZ_VAL; | |
| 1303 | 1364 | } else if (da7213->mclk_rate <= 54000000) { |
| 1304 | − indiv_bits = DA7213_PLL_INDIV_40_54_MHZ; | |
| 1305 | − indiv = DA7213_PLL_INDIV_40_54_MHZ_VAL; | |
| 1365 | + indiv_bits = DA7213_PLL_INDIV_36_TO_54_MHZ; | |
| 1366 | + indiv = DA7213_PLL_INDIV_36_TO_54_MHZ_VAL; | |
| 1306 | 1367 | } else { |
| 1307 | 1368 | goto pll_err; |
| 1308 | 1369 | } |
| @@ -1547,6 +1608,10 @@ static int da7213_probe(struct snd_soc_codec *codec) · 238 unmodified lines | ||
| 1547 | 1608 | /* Default to using SRM for slave mode */ |
| 1548 | 1609 | da7213->srm_en = true; |
| 1549 | 1610 | |
| 1611 | + /* Default PC counter to free-running */ | |
| 1612 | + snd_soc_update_bits(codec, DA7213_PC_COUNT, DA7213_PC_FREERUN_MASK, | |
| 1613 | + DA7213_PC_FREERUN_MASK); | |
| 1614 | + | |
| 1550 | 1615 | /* Enable all Gain Ramps */ |
| 1551 | 1616 | snd_soc_update_bits(codec, DA7213_AUX_L_CTRL, |
| 1552 | 1617 | DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN); |
| @@ -142,6 +142,9 @@ · 141 unmodified lines | ||
| 142 | 142 | * Bit fields |
| 143 | 143 | */ |
| 144 | 144 | |
| 145 | +/* DA7213_PLL_STATUS = 0x03 */ | |
| 146 | +#define DA7219_PLL_SRM_LOCK (0x1 << 1) | |
| 147 | + | |
| 145 | 148 | /* DA7213_SR = 0x22 */ |
| 146 | 149 | #define DA7213_SR_8000 (0x1 << 0) |
| 147 | 150 | #define DA7213_SR_11025 (0x2 << 0) |
| @@ -160,10 +163,10 @@ · 12 unmodified lines | ||
| 160 | 163 | #define DA7213_VMID_EN (0x1 << 7) |
| 161 | 164 | |
| 162 | 165 | /* DA7213_PLL_CTRL = 0x27 */ |
| 163 | −#define DA7213_PLL_INDIV_5_10_MHZ (0x0 << 2) | |
| 164 | −#define DA7213_PLL_INDIV_10_20_MHZ (0x1 << 2) | |
| 165 | −#define DA7213_PLL_INDIV_20_40_MHZ (0x2 << 2) | |
| 166 | −#define DA7213_PLL_INDIV_40_54_MHZ (0x3 << 2) | |
| 166 | +#define DA7213_PLL_INDIV_5_TO_9_MHZ (0x0 << 2) | |
| 167 | +#define DA7213_PLL_INDIV_9_TO_18_MHZ (0x1 << 2) | |
| 168 | +#define DA7213_PLL_INDIV_18_TO_36_MHZ (0x2 << 2) | |
| 169 | +#define DA7213_PLL_INDIV_36_TO_54_MHZ (0x3 << 2) | |
| 167 | 170 | #define DA7213_PLL_INDIV_MASK (0x3 << 2) |
| 168 | 171 | #define DA7213_PLL_MCLK_SQR_EN (0x1 << 4) |
| 169 | 172 | #define DA7213_PLL_32K_MODE (0x1 << 5) |
| @@ -178,8 +181,6 @@ · 8 unmodified lines | ||
| 178 | 181 | #define DA7213_DAI_BCLKS_PER_WCLK_MASK (0x3 << 0) |
| 179 | 182 | #define DA7213_DAI_CLK_POL_INV (0x1 << 2) |
| 180 | 183 | #define DA7213_DAI_WCLK_POL_INV (0x1 << 3) |
| 181 | −#define DA7213_DAI_CLK_EN_SLAVE_MODE (0x0 << 7) | |
| 182 | −#define DA7213_DAI_CLK_EN_MASTER_MODE (0x1 << 7) | |
| 183 | 184 | #define DA7213_DAI_CLK_EN_MASK (0x1 << 7) |
| 184 | 185 | |
| 185 | 186 | /* DA7213_DAI_CTRL = 0x29 */ |
| @@ -412,6 +413,9 @@ · 226 unmodified lines | ||
| 412 | 413 | #define DA7213_DMIC_CLK_RATE_SHIFT 2 |
| 413 | 414 | #define DA7213_DMIC_CLK_RATE_MASK (0x1 << 2) |
| 414 | 415 | |
| 416 | +/* DA7213_PC_COUNT = 0x94 */ | |
| 417 | +#define DA7213_PC_FREERUN_MASK (0x1 << 0) | |
| 418 | + | |
| 415 | 419 | /* DA7213_DIG_CTRL = 0x99 */ |
| 416 | 420 | #define DA7213_DAC_L_INV_SHIFT 3 |
| 417 | 421 | #define DA7213_DAC_R_INV_SHIFT 7 |
| @@ -495,15 +499,16 @@ · 77 unmodified lines | ||
| 495 | 499 | #define DA7213_ALC_AVG_ITERATIONS 5 |
| 496 | 500 | |
| 497 | 501 | /* PLL related */ |
| 498 | −#define DA7213_SYSCLK_MCLK 0 | |
| 499 | −#define DA7213_SYSCLK_PLL 1 | |
| 500 | −#define DA7213_PLL_FREQ_OUT_90316800 90316800 | |
| 501 | −#define DA7213_PLL_FREQ_OUT_98304000 98304000 | |
| 502 | −#define DA7213_PLL_FREQ_OUT_94310400 94310400 | |
| 503 | −#define DA7213_PLL_INDIV_5_10_MHZ_VAL 2 | |
| 504 | −#define DA7213_PLL_INDIV_10_20_MHZ_VAL 4 | |
| 505 | −#define DA7213_PLL_INDIV_20_40_MHZ_VAL 8 | |
| 506 | −#define DA7213_PLL_INDIV_40_54_MHZ_VAL 16 | |
| 502 | +#define DA7213_SYSCLK_MCLK 0 | |
| 503 | +#define DA7213_SYSCLK_PLL 1 | |
| 504 | +#define DA7213_PLL_FREQ_OUT_90316800 90316800 | |
| 505 | +#define DA7213_PLL_FREQ_OUT_98304000 98304000 | |
| 506 | +#define DA7213_PLL_FREQ_OUT_94310400 94310400 | |
| 507 | +#define DA7213_PLL_INDIV_5_TO_9_MHZ_VAL 2 | |
| 508 | +#define DA7213_PLL_INDIV_9_TO_18_MHZ_VAL 4 | |
| 509 | +#define DA7213_PLL_INDIV_18_TO_36_MHZ_VAL 8 | |
| 510 | +#define DA7213_PLL_INDIV_36_TO_54_MHZ_VAL 16 | |
| 511 | +#define DA7213_SRM_CHECK_RETRIES 8 | |
| 507 | 512 | |
| 508 | 513 | enum da7213_clk_src { |
| 509 | 514 | DA7213_CLKSRC_MCLK = 0, |
| @@ -1868,27 +1868,27 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, · 1867 unmodified lines | ||
| 1868 | 1868 | |
| 1869 | 1869 | /* Verify 32KHz, 2MHz - 54MHz MCLK provided, and set input divider */ |
| 1870 | 1870 | if (da7218->mclk_rate == 32768) { |
| 1871 | − indiv_bits = DA7218_PLL_INDIV_2_5_MHZ; | |
| 1872 | − indiv = DA7218_PLL_INDIV_2_10_MHZ_VAL; | |
| 1871 | + indiv_bits = DA7218_PLL_INDIV_9_TO_18_MHZ; | |
| 1872 | + indiv = DA7218_PLL_INDIV_9_TO_18_MHZ_VAL; | |
| 1873 | 1873 | } else if (da7218->mclk_rate < 2000000) { |
| 1874 | 1874 | dev_err(codec->dev, "PLL input clock %d below valid range\n", |
| 1875 | 1875 | da7218->mclk_rate); |
| 1876 | 1876 | return -EINVAL; |
| 1877 | − } else if (da7218->mclk_rate <= 5000000) { | |
| 1878 | − indiv_bits = DA7218_PLL_INDIV_2_5_MHZ; | |
| 1879 | − indiv = DA7218_PLL_INDIV_2_10_MHZ_VAL; | |
| 1880 | − } else if (da7218->mclk_rate <= 10000000) { | |
| 1881 | − indiv_bits = DA7218_PLL_INDIV_5_10_MHZ; | |
| 1882 | − indiv = DA7218_PLL_INDIV_2_10_MHZ_VAL; | |
| 1883 | − } else if (da7218->mclk_rate <= 20000000) { | |
| 1884 | − indiv_bits = DA7218_PLL_INDIV_10_20_MHZ; | |
| 1885 | − indiv = DA7218_PLL_INDIV_10_20_MHZ_VAL; | |
| 1886 | − } else if (da7218->mclk_rate <= 40000000) { | |
| 1887 | − indiv_bits = DA7218_PLL_INDIV_20_40_MHZ; | |
| 1888 | − indiv = DA7218_PLL_INDIV_20_40_MHZ_VAL; | |
| 1877 | + } else if (da7218->mclk_rate <= 4500000) { | |
| 1878 | + indiv_bits = DA7218_PLL_INDIV_2_TO_4_5_MHZ; | |
| 1879 | + indiv = DA7218_PLL_INDIV_2_TO_4_5_MHZ_VAL; | |
| 1880 | + } else if (da7218->mclk_rate <= 9000000) { | |
| 1881 | + indiv_bits = DA7218_PLL_INDIV_4_5_TO_9_MHZ; | |
| 1882 | + indiv = DA7218_PLL_INDIV_4_5_TO_9_MHZ_VAL; | |
| 1883 | + } else if (da7218->mclk_rate <= 18000000) { | |
| 1884 | + indiv_bits = DA7218_PLL_INDIV_9_TO_18_MHZ; | |
| 1885 | + indiv = DA7218_PLL_INDIV_9_TO_18_MHZ_VAL; | |
| 1886 | + } else if (da7218->mclk_rate <= 36000000) { | |
| 1887 | + indiv_bits = DA7218_PLL_INDIV_18_TO_36_MHZ; | |
| 1888 | + indiv = DA7218_PLL_INDIV_18_TO_36_MHZ_VAL; | |
| 1889 | 1889 | } else if (da7218->mclk_rate <= 54000000) { |
| 1890 | − indiv_bits = DA7218_PLL_INDIV_40_54_MHZ; | |
| 1891 | − indiv = DA7218_PLL_INDIV_40_54_MHZ_VAL; | |
| 1890 | + indiv_bits = DA7218_PLL_INDIV_36_TO_54_MHZ; | |
| 1891 | + indiv = DA7218_PLL_INDIV_36_TO_54_MHZ_VAL; | |
| 1892 | 1892 | } else { |
| 1893 | 1893 | dev_err(codec->dev, "PLL input clock %d above valid range\n", |
| 1894 | 1894 | da7218->mclk_rate); |
| @@ -876,15 +876,11 @@ · 875 unmodified lines | ||
| 876 | 876 | /* DA7218_PLL_CTRL = 0x91 */ |
| 877 | 877 | #define DA7218_PLL_INDIV_SHIFT 0 |
| 878 | 878 | #define DA7218_PLL_INDIV_MASK (0x7 << 0) |
| 879 | −#define DA7218_PLL_INDIV_2_5_MHZ (0x0 << 0) | |
| 880 | −#define DA7218_PLL_INDIV_5_10_MHZ (0x1 << 0) | |
| 881 | −#define DA7218_PLL_INDIV_10_20_MHZ (0x2 << 0) | |
| 882 | −#define DA7218_PLL_INDIV_20_40_MHZ (0x3 << 0) | |
| 883 | −#define DA7218_PLL_INDIV_40_54_MHZ (0x4 << 0) | |
| 884 | −#define DA7218_PLL_INDIV_2_10_MHZ_VAL 2 | |
| 885 | −#define DA7218_PLL_INDIV_10_20_MHZ_VAL 4 | |
| 886 | −#define DA7218_PLL_INDIV_20_40_MHZ_VAL 8 | |
| 887 | −#define DA7218_PLL_INDIV_40_54_MHZ_VAL 16 | |
| 879 | +#define DA7218_PLL_INDIV_2_TO_4_5_MHZ (0x0 << 0) | |
| 880 | +#define DA7218_PLL_INDIV_4_5_TO_9_MHZ (0x1 << 0) | |
| 881 | +#define DA7218_PLL_INDIV_9_TO_18_MHZ (0x2 << 0) | |
| 882 | +#define DA7218_PLL_INDIV_18_TO_36_MHZ (0x3 << 0) | |
| 883 | +#define DA7218_PLL_INDIV_36_TO_54_MHZ (0x4 << 0) | |
| 888 | 884 | #define DA7218_PLL_MCLK_SQR_EN_SHIFT 4 |
| 889 | 885 | #define DA7218_PLL_MCLK_SQR_EN_MASK (0x1 << 4) |
| 890 | 886 | #define DA7218_PLL_MODE_SHIFT 6 |
| @@ -1336,6 +1332,13 @@ · 445 unmodified lines | ||
| 1336 | 1332 | #define DA7218_PLL_FREQ_OUT_90316 90316800 |
| 1337 | 1333 | #define DA7218_PLL_FREQ_OUT_98304 98304000 |
| 1338 | 1334 | |
| 1335 | +/* PLL Frequency Dividers */ | |
| 1336 | +#define DA7218_PLL_INDIV_2_TO_4_5_MHZ_VAL 1 | |
| 1337 | +#define DA7218_PLL_INDIV_4_5_TO_9_MHZ_VAL 2 | |
| 1338 | +#define DA7218_PLL_INDIV_9_TO_18_MHZ_VAL 4 | |
| 1339 | +#define DA7218_PLL_INDIV_18_TO_36_MHZ_VAL 8 | |
| 1340 | +#define DA7218_PLL_INDIV_36_TO_54_MHZ_VAL 16 | |
| 1341 | + | |
| 1339 | 1342 | /* ALC Calibration */ |
| 1340 | 1343 | #define DA7218_ALC_CALIB_DELAY_MIN 2500 |
| 1341 | 1344 | #define DA7218_ALC_CALIB_DELAY_MAX 5000 |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | * option) any later version. |
| 12 | 12 | */ |
| 13 | 13 | |
| 14 | +#include <linux/acpi.h> | |
| 14 | 15 | #include <linux/clk.h> |
| 15 | 16 | #include <linux/i2c.h> |
| 16 | 17 | #include <linux/of_device.h> |
| @@ -1025,7 +1026,7 @@ static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai, · 1008 unmodified lines | ||
| 1025 | 1026 | if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq)) |
| 1026 | 1027 | return 0; |
| 1027 | 1028 | |
| 1028 | − if (((freq < 2000000) && (freq != 32768)) || (freq > 54000000)) { | |
| 1029 | + if ((freq < 2000000) || (freq > 54000000)) { | |
| 1029 | 1030 | dev_err(codec_dai->dev, "Unsupported MCLK value %d\n", |
| 1030 | 1031 | freq); |
| 1031 | 1032 | return -EINVAL; |
| @@ -1079,21 +1080,21 @@ static int da7219_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, · 47 unmodified lines | ||
| 1079 | 1080 | dev_err(codec->dev, "PLL input clock %d below valid range\n", |
| 1080 | 1081 | da7219->mclk_rate); |
| 1081 | 1082 | return -EINVAL; |
| 1082 | − } else if (da7219->mclk_rate <= 5000000) { | |
| 1083 | − indiv_bits = DA7219_PLL_INDIV_2_5_MHZ; | |
| 1084 | − indiv = DA7219_PLL_INDIV_2_5_MHZ_VAL; | |
| 1085 | − } else if (da7219->mclk_rate <= 10000000) { | |
| 1086 | − indiv_bits = DA7219_PLL_INDIV_5_10_MHZ; | |
| 1087 | − indiv = DA7219_PLL_INDIV_5_10_MHZ_VAL; | |
| 1088 | − } else if (da7219->mclk_rate <= 20000000) { | |
| 1089 | − indiv_bits = DA7219_PLL_INDIV_10_20_MHZ; | |
| 1090 | − indiv = DA7219_PLL_INDIV_10_20_MHZ_VAL; | |
| 1091 | − } else if (da7219->mclk_rate <= 40000000) { | |
| 1092 | − indiv_bits = DA7219_PLL_INDIV_20_40_MHZ; | |
| 1093 | − indiv = DA7219_PLL_INDIV_20_40_MHZ_VAL; | |
| 1083 | + } else if (da7219->mclk_rate <= 4500000) { | |
| 1084 | + indiv_bits = DA7219_PLL_INDIV_2_TO_4_5_MHZ; | |
| 1085 | + indiv = DA7219_PLL_INDIV_2_TO_4_5_MHZ_VAL; | |
| 1086 | + } else if (da7219->mclk_rate <= 9000000) { | |
| 1087 | + indiv_bits = DA7219_PLL_INDIV_4_5_TO_9_MHZ; | |
| 1088 | + indiv = DA7219_PLL_INDIV_4_5_TO_9_MHZ_VAL; | |
| 1089 | + } else if (da7219->mclk_rate <= 18000000) { | |
| 1090 | + indiv_bits = DA7219_PLL_INDIV_9_TO_18_MHZ; | |
| 1091 | + indiv = DA7219_PLL_INDIV_9_TO_18_MHZ_VAL; | |
| 1092 | + } else if (da7219->mclk_rate <= 36000000) { | |
| 1093 | + indiv_bits = DA7219_PLL_INDIV_18_TO_36_MHZ; | |
| 1094 | + indiv = DA7219_PLL_INDIV_18_TO_36_MHZ_VAL; | |
| 1094 | 1095 | } else if (da7219->mclk_rate <= 54000000) { |
| 1095 | − indiv_bits = DA7219_PLL_INDIV_40_54_MHZ; | |
| 1096 | − indiv = DA7219_PLL_INDIV_40_54_MHZ_VAL; | |
| 1096 | + indiv_bits = DA7219_PLL_INDIV_36_TO_54_MHZ; | |
| 1097 | + indiv = DA7219_PLL_INDIV_36_TO_54_MHZ_VAL; | |
| 1097 | 1098 | } else { |
| 1098 | 1099 | dev_err(codec->dev, "PLL input clock %d above valid range\n", |
| 1099 | 1100 | da7219->mclk_rate); |
| @@ -1426,6 +1427,12 @@ static const struct of_device_id da7219_of_match[] = { · 326 unmodified lines | ||
| 1426 | 1427 | }; |
| 1427 | 1428 | MODULE_DEVICE_TABLE(of, da7219_of_match); |
| 1428 | 1429 | |
| 1430 | +static const struct acpi_device_id da7219_acpi_match[] = { | |
| 1431 | + { .id = "DLGS7219", }, | |
| 1432 | + { } | |
| 1433 | +}; | |
| 1434 | +MODULE_DEVICE_TABLE(acpi, da7219_acpi_match); | |
| 1435 | + | |
| 1429 | 1436 | static enum da7219_micbias_voltage |
| 1430 | 1437 | da7219_of_micbias_lvl(struct snd_soc_codec *codec, u32 val) |
| 1431 | 1438 | { |
| @@ -1955,6 +1962,7 @@ static struct i2c_driver da7219_i2c_driver = { · 523 unmodified lines | ||
| 1955 | 1962 | .driver = { |
| 1956 | 1963 | .name = "da7219", |
| 1957 | 1964 | .of_match_table = of_match_ptr(da7219_of_match), |
| 1965 | + .acpi_match_table = ACPI_PTR(da7219_acpi_match), | |
| 1958 | 1966 | }, |
| 1959 | 1967 | .probe = da7219_i2c_probe, |
| 1960 | 1968 | .remove = da7219_i2c_remove, |
| @@ -194,11 +194,11 @@ · 193 unmodified lines | ||
| 194 | 194 | /* DA7219_PLL_CTRL = 0x20 */ |
| 195 | 195 | #define DA7219_PLL_INDIV_SHIFT 2 |
| 196 | 196 | #define DA7219_PLL_INDIV_MASK (0x7 << 2) |
| 197 | −#define DA7219_PLL_INDIV_2_5_MHZ (0x0 << 2) | |
| 198 | −#define DA7219_PLL_INDIV_5_10_MHZ (0x1 << 2) | |
| 199 | −#define DA7219_PLL_INDIV_10_20_MHZ (0x2 << 2) | |
| 200 | −#define DA7219_PLL_INDIV_20_40_MHZ (0x3 << 2) | |
| 201 | −#define DA7219_PLL_INDIV_40_54_MHZ (0x4 << 2) | |
| 197 | +#define DA7219_PLL_INDIV_2_TO_4_5_MHZ (0x0 << 2) | |
| 198 | +#define DA7219_PLL_INDIV_4_5_TO_9_MHZ (0x1 << 2) | |
| 199 | +#define DA7219_PLL_INDIV_9_TO_18_MHZ (0x2 << 2) | |
| 200 | +#define DA7219_PLL_INDIV_18_TO_36_MHZ (0x3 << 2) | |
| 201 | +#define DA7219_PLL_INDIV_36_TO_54_MHZ (0x4 << 2) | |
| 202 | 202 | #define DA7219_PLL_MCLK_SQR_EN_SHIFT 5 |
| 203 | 203 | #define DA7219_PLL_MCLK_SQR_EN_MASK (0x1 << 5) |
| 204 | 204 | #define DA7219_PLL_MODE_SHIFT 6 |
| @@ -761,11 +761,11 @@ · 556 unmodified lines | ||
| 761 | 761 | #define DA7219_PLL_FREQ_OUT_98304 98304000 |
| 762 | 762 | |
| 763 | 763 | /* PLL Frequency Dividers */ |
| 764 | −#define DA7219_PLL_INDIV_2_5_MHZ_VAL 1 | |
| 765 | −#define DA7219_PLL_INDIV_5_10_MHZ_VAL 2 | |
| 766 | −#define DA7219_PLL_INDIV_10_20_MHZ_VAL 4 | |
| 767 | −#define DA7219_PLL_INDIV_20_40_MHZ_VAL 8 | |
| 768 | −#define DA7219_PLL_INDIV_40_54_MHZ_VAL 16 | |
| 764 | +#define DA7219_PLL_INDIV_2_TO_4_5_MHZ_VAL 1 | |
| 765 | +#define DA7219_PLL_INDIV_4_5_TO_9_MHZ_VAL 2 | |
| 766 | +#define DA7219_PLL_INDIV_9_TO_18_MHZ_VAL 4 | |
| 767 | +#define DA7219_PLL_INDIV_18_TO_36_MHZ_VAL 8 | |
| 768 | +#define DA7219_PLL_INDIV_36_TO_54_MHZ_VAL 16 | |
| 769 | 769 | |
| 770 | 770 | /* SRM */ |
| 771 | 771 | #define DA7219_SRM_CHECK_RETRIES 8 |
| @@ -26,18 +26,30 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <sound/tlv.h> |
| 27 | 27 | #include "es8328.h" |
| 28 | 28 | |
| 29 | −#define ES8328_SYSCLK_RATE_1X 11289600 | |
| 30 | −#define ES8328_SYSCLK_RATE_2X 22579200 | |
| 29 | +static const unsigned int rates_12288[] = { | |
| 30 | + 8000, 12000, 16000, 24000, 32000, 48000, 96000, | |
| 31 | +}; | |
| 31 | 32 | |
| 32 | −/* Run the codec at 22.5792 or 11.2896 MHz to support these rates */ | |
| 33 | −static struct { | |
| 34 | − int rate; | |
| 35 | − u8 ratio; | |
| 36 | −} mclk_ratios[] = { | |
| 37 | − { 8000, 9 }, | |
| 38 | − {11025, 7 }, | |
| 39 | − {22050, 4 }, | |
| 40 | − {44100, 2 }, | |
| 33 | +static const int ratios_12288[] = { | |
| 34 | + 10, 7, 6, 4, 3, 2, 0, | |
| 35 | +}; | |
| 36 | + | |
| 37 | +static const struct snd_pcm_hw_constraint_list constraints_12288 = { | |
| 38 | + .count = ARRAY_SIZE(rates_12288), | |
| 39 | + .list = rates_12288, | |
| 40 | +}; | |
| 41 | + | |
| 42 | +static const unsigned int rates_11289[] = { | |
| 43 | + 8018, 11025, 22050, 44100, 88200, | |
| 44 | +}; | |
| 45 | + | |
| 46 | +static const int ratios_11289[] = { | |
| 47 | + 9, 7, 4, 2, 0, | |
| 48 | +}; | |
| 49 | + | |
| 50 | +static const struct snd_pcm_hw_constraint_list constraints_11289 = { | |
| 51 | + .count = ARRAY_SIZE(rates_11289), | |
| 52 | + .list = rates_11289, | |
| 41 | 53 | }; |
| 42 | 54 | |
| 43 | 55 | /* regulator supplies for sgtl5000, VDDD is an optional external supply */ |
| @@ -57,16 +69,28 @@ static const char * const supply_names[ES8328_SUPPLY_NUM] = { · 13 unmodified lines | ||
| 57 | 69 | "HPVDD", |
| 58 | 70 | }; |
| 59 | 71 | |
| 60 | −#define ES8328_RATES (SNDRV_PCM_RATE_44100 | \ | |
| 72 | +#define ES8328_RATES (SNDRV_PCM_RATE_96000 | \ | |
| 73 | + SNDRV_PCM_RATE_48000 | \ | |
| 74 | + SNDRV_PCM_RATE_44100 | \ | |
| 75 | + SNDRV_PCM_RATE_32000 | \ | |
| 61 | 76 | SNDRV_PCM_RATE_22050 | \ |
| 62 | − SNDRV_PCM_RATE_11025) | |
| 63 | −#define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) | |
| 77 | + SNDRV_PCM_RATE_16000 | \ | |
| 78 | + SNDRV_PCM_RATE_11025 | \ | |
| 79 | + SNDRV_PCM_RATE_8000) | |
| 80 | +#define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ | |
| 81 | + SNDRV_PCM_FMTBIT_S18_3LE | \ | |
| 82 | + SNDRV_PCM_FMTBIT_S20_3LE | \ | |
| 83 | + SNDRV_PCM_FMTBIT_S24_LE | \ | |
| 84 | + SNDRV_PCM_FMTBIT_S32_LE) | |
| 64 | 85 | |
| 65 | 86 | struct es8328_priv { |
| 66 | 87 | struct regmap *regmap; |
| 67 | 88 | struct clk *clk; |
| 68 | 89 | int playback_fs; |
| 69 | 90 | bool deemph; |
| 91 | + int mclkdiv2; | |
| 92 | + const struct snd_pcm_hw_constraint_list *sysclk_constraints; | |
| 93 | + const int *mclk_ratios; | |
| 70 | 94 | struct regulator_bulk_data supplies[ES8328_SUPPLY_NUM]; |
| 71 | 95 | }; |
| 72 | 96 | |
| @@ -439,54 +463,131 @@ static int es8328_mute(struct snd_soc_dai *dai, int mute) · 366 unmodified lines | ||
| 439 | 463 | mute ? ES8328_DACCONTROL3_DACMUTE : 0); |
| 440 | 464 | } |
| 441 | 465 | |
| 466 | +static int es8328_startup(struct snd_pcm_substream *substream, | |
| 467 | + struct snd_soc_dai *dai) | |
| 468 | +{ | |
| 469 | + struct snd_soc_codec *codec = dai->codec; | |
| 470 | + struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); | |
| 471 | + | |
| 472 | + if (es8328->sysclk_constraints) | |
| 473 | + snd_pcm_hw_constraint_list(substream->runtime, 0, | |
| 474 | + SNDRV_PCM_HW_PARAM_RATE, | |
| 475 | + es8328->sysclk_constraints); | |
| 476 | + | |
| 477 | + return 0; | |
| 478 | +} | |
| 479 | + | |
| 442 | 480 | static int es8328_hw_params(struct snd_pcm_substream *substream, |
| 443 | 481 | struct snd_pcm_hw_params *params, |
| 444 | 482 | struct snd_soc_dai *dai) |
| 445 | 483 | { |
| 446 | 484 | struct snd_soc_codec *codec = dai->codec; |
| 447 | 485 | struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); |
| 448 | − int clk_rate; | |
| 449 | 486 | int i; |
| 450 | 487 | int reg; |
| 451 | − u8 ratio; | |
| 488 | + int wl; | |
| 489 | + int ratio; | |
| 490 | + | |
| 491 | + if (!es8328->sysclk_constraints) { | |
| 492 | + dev_err(codec->dev, "No MCLK configured\n"); | |
| 493 | + return -EINVAL; | |
| 494 | + } | |
| 452 | 495 | |
| 453 | 496 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
| 454 | 497 | reg = ES8328_DACCONTROL2; |
| 455 | 498 | else |
| 456 | 499 | reg = ES8328_ADCCONTROL5; |
| 457 | 500 | |
| 458 | − clk_rate = clk_get_rate(es8328->clk); | |
| 501 | + for (i = 0; i < es8328->sysclk_constraints->count; i++) | |
| 502 | + if (es8328->sysclk_constraints->list[i] == params_rate(params)) | |
| 503 | + break; | |
| 459 | 504 | |
| 460 | − if ((clk_rate != ES8328_SYSCLK_RATE_1X) && | |
| 461 | − (clk_rate != ES8328_SYSCLK_RATE_2X)) { | |
| 462 | − dev_err(codec->dev, | |
| 463 | − "%s: clock is running at %d Hz, not %d or %d Hz\n", | |
| 464 | − __func__, clk_rate, | |
| 465 | − ES8328_SYSCLK_RATE_1X, ES8328_SYSCLK_RATE_2X); | |
| 505 | + if (i == es8328->sysclk_constraints->count) { | |
| 506 | + dev_err(codec->dev, "LRCLK %d unsupported with current clock\n", | |
| 507 | + params_rate(params)); | |
| 466 | 508 | return -EINVAL; |
| 467 | 509 | } |
| 468 | 510 | |
| 469 | − /* find master mode MCLK to sampling frequency ratio */ | |
| 470 | − ratio = mclk_ratios[0].rate; | |
| 471 | − for (i = 1; i < ARRAY_SIZE(mclk_ratios); i++) | |
| 472 | − if (params_rate(params) <= mclk_ratios[i].rate) | |
| 473 | − ratio = mclk_ratios[i].ratio; | |
| 511 | + ratio = es8328->mclk_ratios[i]; | |
| 512 | + snd_soc_update_bits(codec, ES8328_MASTERMODE, | |
| 513 | + ES8328_MASTERMODE_MCLKDIV2, | |
| 514 | + es8328->mclkdiv2 ? ES8328_MASTERMODE_MCLKDIV2 : 0); | |
| 515 | + | |
| 516 | + switch (params_width(params)) { | |
| 517 | + case 16: | |
| 518 | + wl = 3; | |
| 519 | + break; | |
| 520 | + case 18: | |
| 521 | + wl = 2; | |
| 522 | + break; | |
| 523 | + case 20: | |
| 524 | + wl = 1; | |
| 525 | + break; | |
| 526 | + case 24: | |
| 527 | + wl = 0; | |
| 528 | + break; | |
| 529 | + case 32: | |
| 530 | + wl = 4; | |
| 531 | + break; | |
| 532 | + default: | |
| 533 | + return -EINVAL; | |
| 534 | + } | |
| 474 | 535 | |
| 475 | 536 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 537 | + snd_soc_update_bits(codec, ES8328_DACCONTROL1, | |
| 538 | + ES8328_DACCONTROL1_DACWL_MASK, | |
| 539 | + wl << ES8328_DACCONTROL1_DACWL_SHIFT); | |
| 540 | + | |
| 476 | 541 | es8328->playback_fs = params_rate(params); |
| 477 | 542 | es8328_set_deemph(codec); |
| 478 | − } | |
| 543 | + } else | |
| 544 | + snd_soc_update_bits(codec, ES8328_ADCCONTROL4, | |
| 545 | + ES8328_ADCCONTROL4_ADCWL_MASK, | |
| 546 | + wl << ES8328_ADCCONTROL4_ADCWL_SHIFT); | |
| 479 | 547 | |
| 480 | 548 | return snd_soc_update_bits(codec, reg, ES8328_RATEMASK, ratio); |
| 481 | 549 | } |
| 482 | 550 | |
| 551 | +static int es8328_set_sysclk(struct snd_soc_dai *codec_dai, | |
| 552 | + int clk_id, unsigned int freq, int dir) | |
| 553 | +{ | |
| 554 | + struct snd_soc_codec *codec = codec_dai->codec; | |
| 555 | + struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); | |
| 556 | + int mclkdiv2 = 0; | |
| 557 | + | |
| 558 | + switch (freq) { | |
| 559 | + case 0: | |
| 560 | + es8328->sysclk_constraints = NULL; | |
| 561 | + es8328->mclk_ratios = NULL; | |
| 562 | + break; | |
| 563 | + case 22579200: | |
| 564 | + mclkdiv2 = 1; | |
| 565 | + /* fallthru */ | |
| 566 | + case 11289600: | |
| 567 | + es8328->sysclk_constraints = &constraints_11289; | |
| 568 | + es8328->mclk_ratios = ratios_11289; | |
| 569 | + break; | |
| 570 | + case 24576000: | |
| 571 | + mclkdiv2 = 1; | |
| 572 | + /* fallthru */ | |
| 573 | + case 12288000: | |
| 574 | + es8328->sysclk_constraints = &constraints_12288; | |
| 575 | + es8328->mclk_ratios = ratios_12288; | |
| 576 | + break; | |
| 577 | + default: | |
| 578 | + return -EINVAL; | |
| 579 | + } | |
| 580 | + | |
| 581 | + es8328->mclkdiv2 = mclkdiv2; | |
| 582 | + return 0; | |
| 583 | +} | |
| 584 | + | |
| 483 | 585 | static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai, |
| 484 | 586 | unsigned int fmt) |
| 485 | 587 | { |
| 486 | 588 | struct snd_soc_codec *codec = codec_dai->codec; |
| 487 | − struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); | |
| 488 | − int clk_rate; | |
| 489 | − u8 mode = ES8328_DACCONTROL1_DACWL_16; | |
| 589 | + u8 dac_mode = 0; | |
| 590 | + u8 adc_mode = 0; | |
| 490 | 591 | |
| 491 | 592 | /* set master/slave audio interface */ |
| 492 | 593 | if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBM_CFM) |
| @@ -495,13 +596,16 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai, · 2 unmodified lines | ||
| 495 | 596 | /* interface format */ |
| 496 | 597 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
| 497 | 598 | case SND_SOC_DAIFMT_I2S: |
| 498 | − mode |= ES8328_DACCONTROL1_DACFORMAT_I2S; | |
| 599 | + dac_mode |= ES8328_DACCONTROL1_DACFORMAT_I2S; | |
| 600 | + adc_mode |= ES8328_ADCCONTROL4_ADCFORMAT_I2S; | |
| 499 | 601 | break; |
| 500 | 602 | case SND_SOC_DAIFMT_RIGHT_J: |
| 501 | − mode |= ES8328_DACCONTROL1_DACFORMAT_RJUST; | |
| 603 | + dac_mode |= ES8328_DACCONTROL1_DACFORMAT_RJUST; | |
| 604 | + adc_mode |= ES8328_ADCCONTROL4_ADCFORMAT_RJUST; | |
| 502 | 605 | break; |
| 503 | 606 | case SND_SOC_DAIFMT_LEFT_J: |
| 504 | − mode |= ES8328_DACCONTROL1_DACFORMAT_LJUST; | |
| 607 | + dac_mode |= ES8328_DACCONTROL1_DACFORMAT_LJUST; | |
| 608 | + adc_mode |= ES8328_ADCCONTROL4_ADCFORMAT_LJUST; | |
| 505 | 609 | break; |
| 506 | 610 | default: |
| 507 | 611 | return -EINVAL; |
| @@ -511,18 +615,14 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai, · 3 unmodified lines | ||
| 511 | 615 | if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) |
| 512 | 616 | return -EINVAL; |
| 513 | 617 | |
| 514 | − snd_soc_write(codec, ES8328_DACCONTROL1, mode); | |
| 515 | − snd_soc_write(codec, ES8328_ADCCONTROL4, mode); | |
| 618 | + snd_soc_update_bits(codec, ES8328_DACCONTROL1, | |
| 619 | + ES8328_DACCONTROL1_DACFORMAT_MASK, dac_mode); | |
| 620 | + snd_soc_update_bits(codec, ES8328_ADCCONTROL4, | |
| 621 | + ES8328_ADCCONTROL4_ADCFORMAT_MASK, adc_mode); | |
| 516 | 622 | |
| 517 | 623 | /* Master serial port mode, with BCLK generated automatically */ |
| 518 | − clk_rate = clk_get_rate(es8328->clk); | |
| 519 | − if (clk_rate == ES8328_SYSCLK_RATE_1X) | |
| 520 | − snd_soc_write(codec, ES8328_MASTERMODE, | |
| 521 | − ES8328_MASTERMODE_MSC); | |
| 522 | − else | |
| 523 | − snd_soc_write(codec, ES8328_MASTERMODE, | |
| 524 | − ES8328_MASTERMODE_MCLKDIV2 | | |
| 525 | − ES8328_MASTERMODE_MSC); | |
| 624 | + snd_soc_update_bits(codec, ES8328_MASTERMODE, | |
| 625 | + ES8328_MASTERMODE_MSC, ES8328_MASTERMODE_MSC); | |
| 526 | 626 | |
| 527 | 627 | return 0; |
| 528 | 628 | } |
| @@ -579,8 +679,10 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec, · 50 unmodified lines | ||
| 579 | 679 | } |
| 580 | 680 | |
| 581 | 681 | static const struct snd_soc_dai_ops es8328_dai_ops = { |
| 682 | + .startup = es8328_startup, | |
| 582 | 683 | .hw_params = es8328_hw_params, |
| 583 | 684 | .digital_mute = es8328_mute, |
| 685 | + .set_sysclk = es8328_set_sysclk, | |
| 584 | 686 | .set_fmt = es8328_set_dai_fmt, |
| 585 | 687 | }; |
| 586 | 688 | |
| @@ -601,6 +703,7 @@ static struct snd_soc_dai_driver es8328_dai = { · 14 unmodified lines | ||
| 601 | 703 | .formats = ES8328_FORMATS, |
| 602 | 704 | }, |
| 603 | 705 | .ops = &es8328_dai_ops, |
| 706 | + .symmetric_rates = 1, | |
| 604 | 707 | }; |
| 605 | 708 | |
| 606 | 709 | static int es8328_suspend(struct snd_soc_codec *codec) |
| @@ -708,6 +811,7 @@ const struct regmap_config es8328_regmap_config = { · 101 unmodified lines | ||
| 708 | 811 | .val_bits = 8, |
| 709 | 812 | .max_register = ES8328_REG_MAX, |
| 710 | 813 | .cache_type = REGCACHE_RBTREE, |
| 814 | + .use_single_rw = true, | |
| 711 | 815 | }; |
| 712 | 816 | EXPORT_SYMBOL_GPL(es8328_regmap_config); |
| 713 | 817 | |
| @@ -22,7 +22,7 @@ int es8328_probe(struct device *dev, struct regmap *regmap); · 21 unmodified lines | ||
| 22 | 22 | #define ES8328_CONTROL1_VMIDSEL_50k (1 << 0) |
| 23 | 23 | #define ES8328_CONTROL1_VMIDSEL_500k (2 << 0) |
| 24 | 24 | #define ES8328_CONTROL1_VMIDSEL_5k (3 << 0) |
| 25 | −#define ES8328_CONTROL1_VMIDSEL_MASK (7 << 0) | |
| 25 | +#define ES8328_CONTROL1_VMIDSEL_MASK (3 << 0) | |
| 26 | 26 | #define ES8328_CONTROL1_ENREF (1 << 2) |
| 27 | 27 | #define ES8328_CONTROL1_SEQEN (1 << 3) |
| 28 | 28 | #define ES8328_CONTROL1_SAMEFS (1 << 4) |
| @@ -84,7 +84,20 @@ int es8328_probe(struct device *dev, struct regmap *regmap); · 55 unmodified lines | ||
| 84 | 84 | #define ES8328_ADCCONTROL1 0x09 |
| 85 | 85 | #define ES8328_ADCCONTROL2 0x0a |
| 86 | 86 | #define ES8328_ADCCONTROL3 0x0b |
| 87 | + | |
| 87 | 88 | #define ES8328_ADCCONTROL4 0x0c |
| 89 | +#define ES8328_ADCCONTROL4_ADCFORMAT_MASK (3 << 0) | |
| 90 | +#define ES8328_ADCCONTROL4_ADCFORMAT_I2S (0 << 0) | |
| 91 | +#define ES8328_ADCCONTROL4_ADCFORMAT_LJUST (1 << 0) | |
| 92 | +#define ES8328_ADCCONTROL4_ADCFORMAT_RJUST (2 << 0) | |
| 93 | +#define ES8328_ADCCONTROL4_ADCFORMAT_PCM (3 << 0) | |
| 94 | +#define ES8328_ADCCONTROL4_ADCWL_SHIFT 2 | |
| 95 | +#define ES8328_ADCCONTROL4_ADCWL_MASK (7 << 2) | |
| 96 | +#define ES8328_ADCCONTROL4_ADCLRP_I2S_POL_NORMAL (0 << 5) | |
| 97 | +#define ES8328_ADCCONTROL4_ADCLRP_I2S_POL_INV (1 << 5) | |
| 98 | +#define ES8328_ADCCONTROL4_ADCLRP_PCM_MSB_CLK2 (0 << 5) | |
| 99 | +#define ES8328_ADCCONTROL4_ADCLRP_PCM_MSB_CLK1 (1 << 5) | |
| 100 | + | |
| 88 | 101 | #define ES8328_ADCCONTROL5 0x0d |
| 89 | 102 | #define ES8328_ADCCONTROL5_RATEMASK (0x1f << 0) |
| 90 | 103 | |
| @@ -109,15 +122,13 @@ int es8328_probe(struct device *dev, struct regmap *regmap); · 18 unmodified lines | ||
| 109 | 122 | #define ES8328_ADCCONTROL14 0x16 |
| 110 | 123 | |
| 111 | 124 | #define ES8328_DACCONTROL1 0x17 |
| 125 | +#define ES8328_DACCONTROL1_DACFORMAT_MASK (3 << 1) | |
| 112 | 126 | #define ES8328_DACCONTROL1_DACFORMAT_I2S (0 << 1) |
| 113 | 127 | #define ES8328_DACCONTROL1_DACFORMAT_LJUST (1 << 1) |
| 114 | 128 | #define ES8328_DACCONTROL1_DACFORMAT_RJUST (2 << 1) |
| 115 | 129 | #define ES8328_DACCONTROL1_DACFORMAT_PCM (3 << 1) |
| 116 | −#define ES8328_DACCONTROL1_DACWL_24 (0 << 3) | |
| 117 | −#define ES8328_DACCONTROL1_DACWL_20 (1 << 3) | |
| 118 | −#define ES8328_DACCONTROL1_DACWL_18 (2 << 3) | |
| 119 | −#define ES8328_DACCONTROL1_DACWL_16 (3 << 3) | |
| 120 | −#define ES8328_DACCONTROL1_DACWL_32 (4 << 3) | |
| 130 | +#define ES8328_DACCONTROL1_DACWL_SHIFT 3 | |
| 131 | +#define ES8328_DACCONTROL1_DACWL_MASK (7 << 3) | |
| 121 | 132 | #define ES8328_DACCONTROL1_DACLRP_I2S_POL_NORMAL (0 << 6) |
| 122 | 133 | #define ES8328_DACCONTROL1_DACLRP_I2S_POL_INV (1 << 6) |
| 123 | 134 | #define ES8328_DACCONTROL1_DACLRP_PCM_MSB_CLK2 (0 << 6) |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <sound/hdaudio_ext.h> |
| 30 | 30 | #include <sound/hda_i915.h> |
| 31 | 31 | #include <sound/pcm_drm_eld.h> |
| 32 | +#include <sound/hda_chmap.h> | |
| 32 | 33 | #include "../../hda/local.h" |
| 33 | 34 | #include "hdac_hdmi.h" |
| 34 | 35 | |
| @@ -60,11 +61,17 @@ struct hdac_hdmi_cvt { · 25 unmodified lines | ||
| 60 | 61 | struct hdac_hdmi_cvt_params params; |
| 61 | 62 | }; |
| 62 | 63 | |
| 64 | +/* Currently only spk_alloc, more to be added */ | |
| 65 | +struct hdac_hdmi_parsed_eld { | |
| 66 | + u8 spk_alloc; | |
| 67 | +}; | |
| 68 | + | |
| 63 | 69 | struct hdac_hdmi_eld { |
| 64 | 70 | bool monitor_present; |
| 65 | 71 | bool eld_valid; |
| 66 | 72 | int eld_size; |
| 67 | 73 | char eld_buffer[ELD_MAX_SIZE]; |
| 74 | + struct hdac_hdmi_parsed_eld info; | |
| 68 | 75 | }; |
| 69 | 76 | |
| 70 | 77 | struct hdac_hdmi_pin { |
| @@ -76,6 +83,10 @@ struct hdac_hdmi_pin { · 5 unmodified lines | ||
| 76 | 83 | struct hdac_ext_device *edev; |
| 77 | 84 | int repoll_count; |
| 78 | 85 | struct delayed_work work; |
| 86 | + struct mutex lock; | |
| 87 | + bool chmap_set; | |
| 88 | + unsigned char chmap[8]; /* ALSA API channel-map */ | |
| 89 | + int channels; /* current number of channels */ | |
| 79 | 90 | }; |
| 80 | 91 | |
| 81 | 92 | struct hdac_hdmi_pcm { |
| @@ -100,8 +111,22 @@ struct hdac_hdmi_priv { · 18 unmodified lines | ||
| 100 | 111 | int num_pin; |
| 101 | 112 | int num_cvt; |
| 102 | 113 | struct mutex pin_mutex; |
| 114 | + struct hdac_chmap chmap; | |
| 103 | 115 | }; |
| 104 | 116 | |
| 117 | +static struct hdac_hdmi_pcm *get_hdmi_pcm_from_id(struct hdac_hdmi_priv *hdmi, | |
| 118 | + int pcm_idx) | |
| 119 | +{ | |
| 120 | + struct hdac_hdmi_pcm *pcm; | |
| 121 | + | |
| 122 | + list_for_each_entry(pcm, &hdmi->pcm_list, head) { | |
| 123 | + if (pcm->pcm_id == pcm_idx) | |
| 124 | + return pcm; | |
| 125 | + } | |
| 126 | + | |
| 127 | + return NULL; | |
| 128 | +} | |
| 129 | + | |
| 105 | 130 | static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev) |
| 106 | 131 | { |
| 107 | 132 | struct hdac_device *hdac = dev_to_hdac_dev(dev); |
| @@ -278,26 +303,31 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac, · 170 unmodified lines | ||
| 278 | 303 | int i; |
| 279 | 304 | const u8 *eld_buf; |
| 280 | 305 | u8 conn_type; |
| 281 | − int channels = 2; | |
| 306 | + int channels, ca; | |
| 282 | 307 | |
| 283 | 308 | list_for_each_entry(pin, &hdmi->pin_list, head) { |
| 284 | 309 | if (pin->nid == pin_nid) |
| 285 | 310 | break; |
| 286 | 311 | } |
| 287 | 312 | |
| 313 | + ca = snd_hdac_channel_allocation(&hdac->hdac, pin->eld.info.spk_alloc, | |
| 314 | + pin->channels, pin->chmap_set, true, pin->chmap); | |
| 315 | + | |
| 316 | + channels = snd_hdac_get_active_channels(ca); | |
| 317 | + hdmi->chmap.ops.set_channel_count(&hdac->hdac, cvt_nid, channels); | |
| 318 | + | |
| 319 | + snd_hdac_setup_channel_mapping(&hdmi->chmap, pin->nid, false, ca, | |
| 320 | + pin->channels, pin->chmap, pin->chmap_set); | |
| 321 | + | |
| 288 | 322 | eld_buf = pin->eld.eld_buffer; |
| 289 | 323 | conn_type = drm_eld_get_conn_type(eld_buf); |
| 290 | 324 | |
| 291 | − /* setup channel count */ | |
| 292 | − snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0, | |
| 293 | − AC_VERB_SET_CVT_CHAN_COUNT, channels - 1); | |
| 294 | − | |
| 295 | 325 | switch (conn_type) { |
| 296 | 326 | case DRM_ELD_CONN_TYPE_HDMI: |
| 297 | 327 | hdmi_audio_infoframe_init(&frame); |
| 298 | 328 | |
| 299 | − /* Default stereo for now */ | |
| 300 | 329 | frame.channels = channels; |
| 330 | + frame.channel_allocation = ca; | |
| 301 | 331 | |
| 302 | 332 | ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer)); |
| 303 | 333 | if (ret < 0) |
| @@ -311,7 +341,7 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac, · 7 unmodified lines | ||
| 311 | 341 | dp_ai.len = 0x1b; |
| 312 | 342 | dp_ai.ver = 0x11 << 2; |
| 313 | 343 | dp_ai.CC02_CT47 = channels - 1; |
| 314 | − dp_ai.CA = 0; | |
| 344 | + dp_ai.CA = ca; | |
| 315 | 345 | |
| 316 | 346 | dip = (u8 *)&dp_ai; |
| 317 | 347 | break; |
| @@ -370,17 +400,23 @@ static int hdac_hdmi_playback_prepare(struct snd_pcm_substream *substream, · 52 unmodified lines | ||
| 370 | 400 | struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai); |
| 371 | 401 | struct hdac_hdmi_priv *hdmi = hdac->private_data; |
| 372 | 402 | struct hdac_hdmi_dai_pin_map *dai_map; |
| 403 | + struct hdac_hdmi_pin *pin; | |
| 373 | 404 | struct hdac_ext_dma_params *dd; |
| 374 | 405 | int ret; |
| 375 | 406 | |
| 376 | 407 | dai_map = &hdmi->dai_map[dai->id]; |
| 408 | + pin = dai_map->pin; | |
| 377 | 409 | |
| 378 | 410 | dd = (struct hdac_ext_dma_params *)snd_soc_dai_get_dma_data(dai, substream); |
| 379 | 411 | dev_dbg(&hdac->hdac.dev, "stream tag from cpu dai %d format in cvt 0x%x\n", |
| 380 | 412 | dd->stream_tag, dd->format); |
| 381 | 413 | |
| 414 | + mutex_lock(&pin->lock); | |
| 415 | + pin->channels = substream->runtime->channels; | |
| 416 | + | |
| 382 | 417 | ret = hdac_hdmi_setup_audio_infoframe(hdac, dai_map->cvt->nid, |
| 383 | 418 | dai_map->pin->nid); |
| 419 | + mutex_unlock(&pin->lock); | |
| 384 | 420 | if (ret < 0) |
| 385 | 421 | return ret; |
| 386 | 422 | |
| @@ -640,6 +676,12 @@ static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream, · 253 unmodified lines | ||
| 640 | 676 | snd_hdac_codec_write(&hdac->hdac, dai_map->pin->nid, 0, |
| 641 | 677 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
| 642 | 678 | |
| 679 | + mutex_lock(&dai_map->pin->lock); | |
| 680 | + dai_map->pin->chmap_set = false; | |
| 681 | + memset(dai_map->pin->chmap, 0, sizeof(dai_map->pin->chmap)); | |
| 682 | + dai_map->pin->channels = 0; | |
| 683 | + mutex_unlock(&dai_map->pin->lock); | |
| 684 | + | |
| 643 | 685 | dai_map->pin = NULL; |
| 644 | 686 | } |
| 645 | 687 | } |
| @@ -647,10 +689,19 @@ static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream, · 1 unmodified line | ||
| 647 | 689 | static int |
| 648 | 690 | hdac_hdmi_query_cvt_params(struct hdac_device *hdac, struct hdac_hdmi_cvt *cvt) |
| 649 | 691 | { |
| 692 | + unsigned int chans; | |
| 693 | + struct hdac_ext_device *edev = to_ehdac_device(hdac); | |
| 694 | + struct hdac_hdmi_priv *hdmi = edev->private_data; | |
| 650 | 695 | int err; |
| 651 | 696 | |
| 652 | − /* Only stereo supported as of now */ | |
| 653 | − cvt->params.channels_min = cvt->params.channels_max = 2; | |
| 697 | + chans = get_wcaps(hdac, cvt->nid); | |
| 698 | + chans = get_wcaps_channels(chans); | |
| 699 | + | |
| 700 | + cvt->params.channels_min = 2; | |
| 701 | + | |
| 702 | + cvt->params.channels_max = chans; | |
| 703 | + if (chans > hdmi->chmap.channels_max) | |
| 704 | + hdmi->chmap.channels_max = chans; | |
| 654 | 705 | |
| 655 | 706 | err = snd_hdac_query_supported_pcm(hdac, cvt->nid, |
| 656 | 707 | &cvt->params.rates, |
| @@ -1008,6 +1059,12 @@ static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid) · 351 unmodified lines | ||
| 1008 | 1059 | return hdac_hdmi_query_cvt_params(&edev->hdac, cvt); |
| 1009 | 1060 | } |
| 1010 | 1061 | |
| 1062 | +static void hdac_hdmi_parse_eld(struct hdac_ext_device *edev, | |
| 1063 | + struct hdac_hdmi_pin *pin) | |
| 1064 | +{ | |
| 1065 | + pin->eld.info.spk_alloc = pin->eld.eld_buffer[DRM_ELD_SPEAKER]; | |
| 1066 | +} | |
| 1067 | + | |
| 1011 | 1068 | static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, int repoll) |
| 1012 | 1069 | { |
| 1013 | 1070 | struct hdac_ext_device *edev = pin->edev; |
| @@ -1065,6 +1122,7 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, int repoll) · 51 unmodified lines | ||
| 1065 | 1122 | |
| 1066 | 1123 | snd_jack_report(pcm->jack, SND_JACK_AVOUT); |
| 1067 | 1124 | } |
| 1125 | + hdac_hdmi_parse_eld(edev, pin); | |
| 1068 | 1126 | |
| 1069 | 1127 | print_hex_dump_bytes("ELD: ", DUMP_PREFIX_OFFSET, |
| 1070 | 1128 | pin->eld.eld_buffer, pin->eld.eld_size); |
| @@ -1123,6 +1181,7 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid) · 52 unmodified lines | ||
| 1123 | 1181 | hdmi->num_pin++; |
| 1124 | 1182 | |
| 1125 | 1183 | pin->edev = edev; |
| 1184 | + mutex_init(&pin->lock); | |
| 1126 | 1185 | INIT_DELAYED_WORK(&pin->work, hdac_hdmi_repoll_eld); |
| 1127 | 1186 | |
| 1128 | 1187 | return 0; |
| @@ -1342,6 +1401,19 @@ static struct i915_audio_component_audio_ops aops = { · 213 unmodified lines | ||
| 1342 | 1401 | .pin_eld_notify = hdac_hdmi_eld_notify_cb, |
| 1343 | 1402 | }; |
| 1344 | 1403 | |
| 1404 | +static struct snd_pcm *hdac_hdmi_get_pcm_from_id(struct snd_soc_card *card, | |
| 1405 | + int device) | |
| 1406 | +{ | |
| 1407 | + struct snd_soc_pcm_runtime *rtd; | |
| 1408 | + | |
| 1409 | + list_for_each_entry(rtd, &card->rtd_list, list) { | |
| 1410 | + if (rtd->pcm && (rtd->pcm->device == device)) | |
| 1411 | + return rtd->pcm; | |
| 1412 | + } | |
| 1413 | + | |
| 1414 | + return NULL; | |
| 1415 | +} | |
| 1416 | + | |
| 1345 | 1417 | int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device) |
| 1346 | 1418 | { |
| 1347 | 1419 | char jack_name[NAME_SIZE]; |
| @@ -1351,6 +1423,8 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device) · 3 unmodified lines | ||
| 1351 | 1423 | snd_soc_component_get_dapm(&codec->component); |
| 1352 | 1424 | struct hdac_hdmi_priv *hdmi = edev->private_data; |
| 1353 | 1425 | struct hdac_hdmi_pcm *pcm; |
| 1426 | + struct snd_pcm *snd_pcm; | |
| 1427 | + int err; | |
| 1354 | 1428 | |
| 1355 | 1429 | /* |
| 1356 | 1430 | * this is a new PCM device, create new pcm and |
| @@ -1362,6 +1436,18 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device) · 5 unmodified lines | ||
| 1362 | 1436 | pcm->pcm_id = device; |
| 1363 | 1437 | pcm->cvt = hdmi->dai_map[dai->id].cvt; |
| 1364 | 1438 | |
| 1439 | + snd_pcm = hdac_hdmi_get_pcm_from_id(dai->component->card, device); | |
| 1440 | + if (snd_pcm) { | |
| 1441 | + err = snd_hdac_add_chmap_ctls(snd_pcm, device, &hdmi->chmap); | |
| 1442 | + if (err < 0) { | |
| 1443 | + dev_err(&edev->hdac.dev, | |
| 1444 | + "chmap control add failed with err: %d for pcm: %d\n", | |
| 1445 | + err, device); | |
| 1446 | + kfree(pcm); | |
| 1447 | + return err; | |
| 1448 | + } | |
| 1449 | + } | |
| 1450 | + | |
| 1365 | 1451 | list_add_tail(&pcm->head, &hdmi->pcm_list); |
| 1366 | 1452 | |
| 1367 | 1453 | sprintf(jack_name, "HDMI/DP, pcm=%d Jack", device); |
| @@ -1378,10 +1464,18 @@ static int hdmi_codec_probe(struct snd_soc_codec *codec) · 10 unmodified lines | ||
| 1378 | 1464 | struct snd_soc_dapm_context *dapm = |
| 1379 | 1465 | snd_soc_component_get_dapm(&codec->component); |
| 1380 | 1466 | struct hdac_hdmi_pin *pin; |
| 1467 | + struct hdac_ext_link *hlink = NULL; | |
| 1381 | 1468 | int ret; |
| 1382 | 1469 | |
| 1383 | 1470 | edev->scodec = codec; |
| 1384 | 1471 | |
| 1472 | + /* | |
| 1473 | + * hold the ref while we probe, also no need to drop the ref on | |
| 1474 | + * exit, we call pm_runtime_suspend() so that will do for us | |
| 1475 | + */ | |
| 1476 | + hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdac.dev)); | |
| 1477 | + snd_hdac_ext_bus_link_get(edev->ebus, hlink); | |
| 1478 | + | |
| 1385 | 1479 | ret = create_fill_widget_route_map(dapm); |
| 1386 | 1480 | if (ret < 0) |
| 1387 | 1481 | return ret; |
| @@ -1475,19 +1569,83 @@ static struct snd_soc_codec_driver hdmi_hda_codec = { · 87 unmodified lines | ||
| 1475 | 1569 | .idle_bias_off = true, |
| 1476 | 1570 | }; |
| 1477 | 1571 | |
| 1572 | +static void hdac_hdmi_get_chmap(struct hdac_device *hdac, int pcm_idx, | |
| 1573 | + unsigned char *chmap) | |
| 1574 | +{ | |
| 1575 | + struct hdac_ext_device *edev = to_ehdac_device(hdac); | |
| 1576 | + struct hdac_hdmi_priv *hdmi = edev->private_data; | |
| 1577 | + struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx); | |
| 1578 | + struct hdac_hdmi_pin *pin = pcm->pin; | |
| 1579 | + | |
| 1580 | + /* chmap is already set to 0 in caller */ | |
| 1581 | + if (!pin) | |
| 1582 | + return; | |
| 1583 | + | |
| 1584 | + memcpy(chmap, pin->chmap, ARRAY_SIZE(pin->chmap)); | |
| 1585 | +} | |
| 1586 | + | |
| 1587 | +static void hdac_hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx, | |
| 1588 | + unsigned char *chmap, int prepared) | |
| 1589 | +{ | |
| 1590 | + struct hdac_ext_device *edev = to_ehdac_device(hdac); | |
| 1591 | + struct hdac_hdmi_priv *hdmi = edev->private_data; | |
| 1592 | + struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx); | |
| 1593 | + struct hdac_hdmi_pin *pin = pcm->pin; | |
| 1594 | + | |
| 1595 | + mutex_lock(&pin->lock); | |
| 1596 | + pin->chmap_set = true; | |
| 1597 | + memcpy(pin->chmap, chmap, ARRAY_SIZE(pin->chmap)); | |
| 1598 | + if (prepared) | |
| 1599 | + hdac_hdmi_setup_audio_infoframe(edev, pcm->cvt->nid, pin->nid); | |
| 1600 | + mutex_unlock(&pin->lock); | |
| 1601 | +} | |
| 1602 | + | |
| 1603 | +static bool is_hdac_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx) | |
| 1604 | +{ | |
| 1605 | + struct hdac_ext_device *edev = to_ehdac_device(hdac); | |
| 1606 | + struct hdac_hdmi_priv *hdmi = edev->private_data; | |
| 1607 | + struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx); | |
| 1608 | + struct hdac_hdmi_pin *pin = pcm->pin; | |
| 1609 | + | |
| 1610 | + return pin ? true:false; | |
| 1611 | +} | |
| 1612 | + | |
| 1613 | +static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx) | |
| 1614 | +{ | |
| 1615 | + struct hdac_ext_device *edev = to_ehdac_device(hdac); | |
| 1616 | + struct hdac_hdmi_priv *hdmi = edev->private_data; | |
| 1617 | + struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx); | |
| 1618 | + struct hdac_hdmi_pin *pin = pcm->pin; | |
| 1619 | + | |
| 1620 | + if (!pin || !pin->eld.eld_valid) | |
| 1621 | + return 0; | |
| 1622 | + | |
| 1623 | + return pin->eld.info.spk_alloc; | |
| 1624 | +} | |
| 1625 | + | |
| 1478 | 1626 | static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) |
| 1479 | 1627 | { |
| 1480 | 1628 | struct hdac_device *codec = &edev->hdac; |
| 1481 | 1629 | struct hdac_hdmi_priv *hdmi_priv; |
| 1482 | 1630 | struct snd_soc_dai_driver *hdmi_dais = NULL; |
| 1631 | + struct hdac_ext_link *hlink = NULL; | |
| 1483 | 1632 | int num_dais = 0; |
| 1484 | 1633 | int ret = 0; |
| 1485 | 1634 | |
| 1635 | + /* hold the ref while we probe */ | |
| 1636 | + hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdac.dev)); | |
| 1637 | + snd_hdac_ext_bus_link_get(edev->ebus, hlink); | |
| 1638 | + | |
| 1486 | 1639 | hdmi_priv = devm_kzalloc(&codec->dev, sizeof(*hdmi_priv), GFP_KERNEL); |
| 1487 | 1640 | if (hdmi_priv == NULL) |
| 1488 | 1641 | return -ENOMEM; |
| 1489 | 1642 | |
| 1490 | 1643 | edev->private_data = hdmi_priv; |
| 1644 | + snd_hdac_register_chmap_ops(codec, &hdmi_priv->chmap); | |
| 1645 | + hdmi_priv->chmap.ops.get_chmap = hdac_hdmi_get_chmap; | |
| 1646 | + hdmi_priv->chmap.ops.set_chmap = hdac_hdmi_set_chmap; | |
| 1647 | + hdmi_priv->chmap.ops.is_pcm_attached = is_hdac_hdmi_pcm_attached; | |
| 1648 | + hdmi_priv->chmap.ops.get_spk_alloc = hdac_hdmi_get_spk_alloc; | |
| 1491 | 1649 | |
| 1492 | 1650 | dev_set_drvdata(&codec->dev, edev); |
| 1493 | 1651 | |
| @@ -1516,8 +1674,12 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) · 22 unmodified lines | ||
| 1516 | 1674 | } |
| 1517 | 1675 | |
| 1518 | 1676 | /* ASoC specific initialization */ |
| 1519 | − return snd_soc_register_codec(&codec->dev, &hdmi_hda_codec, | |
| 1520 | − hdmi_dais, num_dais); | |
| 1677 | + ret = snd_soc_register_codec(&codec->dev, &hdmi_hda_codec, | |
| 1678 | + hdmi_dais, num_dais); | |
| 1679 | + | |
| 1680 | + snd_hdac_ext_bus_link_put(edev->ebus, hlink); | |
| 1681 | + | |
| 1682 | + return ret; | |
| 1521 | 1683 | } |
| 1522 | 1684 | |
| 1523 | 1685 | static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev) |
| @@ -1556,6 +1718,9 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) · 32 unmodified lines | ||
| 1556 | 1718 | struct hdac_ext_device *edev = to_hda_ext_device(dev); |
| 1557 | 1719 | struct hdac_device *hdac = &edev->hdac; |
| 1558 | 1720 | struct hdac_bus *bus = hdac->bus; |
| 1721 | + unsigned long timeout; | |
| 1722 | + struct hdac_ext_bus *ebus = hbus_to_ebus(bus); | |
| 1723 | + struct hdac_ext_link *hlink = NULL; | |
| 1559 | 1724 | int err; |
| 1560 | 1725 | |
| 1561 | 1726 | dev_dbg(dev, "Enter: %s\n", __func__); |
| @@ -1579,6 +1744,9 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) · 17 unmodified lines | ||
| 1579 | 1744 | return err; |
| 1580 | 1745 | } |
| 1581 | 1746 | |
| 1747 | + hlink = snd_hdac_ext_bus_get_link(ebus, dev_name(dev)); | |
| 1748 | + snd_hdac_ext_bus_link_put(ebus, hlink); | |
| 1749 | + | |
| 1582 | 1750 | return 0; |
| 1583 | 1751 | } |
| 1584 | 1752 | |
| @@ -1587,6 +1755,8 @@ static int hdac_hdmi_runtime_resume(struct device *dev) · 2 unmodified lines | ||
| 1587 | 1755 | struct hdac_ext_device *edev = to_hda_ext_device(dev); |
| 1588 | 1756 | struct hdac_device *hdac = &edev->hdac; |
| 1589 | 1757 | struct hdac_bus *bus = hdac->bus; |
| 1758 | + struct hdac_ext_bus *ebus = hbus_to_ebus(bus); | |
| 1759 | + struct hdac_ext_link *hlink = NULL; | |
| 1590 | 1760 | int err; |
| 1591 | 1761 | |
| 1592 | 1762 | dev_dbg(dev, "Enter: %s\n", __func__); |
| @@ -1595,6 +1765,9 @@ static int hdac_hdmi_runtime_resume(struct device *dev) · 2 unmodified lines | ||
| 1595 | 1765 | if (!bus) |
| 1596 | 1766 | return 0; |
| 1597 | 1767 | |
| 1768 | + hlink = snd_hdac_ext_bus_get_link(ebus, dev_name(dev)); | |
| 1769 | + snd_hdac_ext_bus_link_get(ebus, hlink); | |
| 1770 | + | |
| 1598 | 1771 | err = snd_hdac_display_power(bus, true); |
| 1599 | 1772 | if (err < 0) { |
| 1600 | 1773 | dev_err(bus->dev, "Cannot turn on display power on i915\n"); |
| @@ -0,0 +1,432 @@ | ||
| 1 | +/* | |
| 2 | + * ALSA SoC codec for HDMI encoder drivers | |
| 3 | + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ | |
| 4 | + * Author: Jyri Sarha <jsarha@ti.com> | |
| 5 | + * | |
| 6 | + * This program is free software; you can redistribute it and/or | |
| 7 | + * modify it under the terms of the GNU General Public License | |
| 8 | + * version 2 as published by the Free Software Foundation. | |
| 9 | + * | |
| 10 | + * This program is distributed in the hope that it will be useful, but | |
| 11 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 | + * General Public License for more details. | |
| 14 | + */ | |
| 15 | +#include <linux/module.h> | |
| 16 | +#include <linux/string.h> | |
| 17 | +#include <sound/core.h> | |
| 18 | +#include <sound/pcm.h> | |
| 19 | +#include <sound/pcm_params.h> | |
| 20 | +#include <sound/soc.h> | |
| 21 | +#include <sound/pcm_drm_eld.h> | |
| 22 | +#include <sound/hdmi-codec.h> | |
| 23 | +#include <sound/pcm_iec958.h> | |
| 24 | + | |
| 25 | +#include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */ | |
| 26 | + | |
| 27 | +struct hdmi_codec_priv { | |
| 28 | + struct hdmi_codec_pdata hcd; | |
| 29 | + struct snd_soc_dai_driver *daidrv; | |
| 30 | + struct hdmi_codec_daifmt daifmt[2]; | |
| 31 | + struct mutex current_stream_lock; | |
| 32 | + struct snd_pcm_substream *current_stream; | |
| 33 | + struct snd_pcm_hw_constraint_list ratec; | |
| 34 | + uint8_t eld[MAX_ELD_BYTES]; | |
| 35 | +}; | |
| 36 | + | |
| 37 | +static const struct snd_soc_dapm_widget hdmi_widgets[] = { | |
| 38 | + SND_SOC_DAPM_OUTPUT("TX"), | |
| 39 | +}; | |
| 40 | + | |
| 41 | +static const struct snd_soc_dapm_route hdmi_routes[] = { | |
| 42 | + { "TX", NULL, "Playback" }, | |
| 43 | +}; | |
| 44 | + | |
| 45 | +enum { | |
| 46 | + DAI_ID_I2S = 0, | |
| 47 | + DAI_ID_SPDIF, | |
| 48 | +}; | |
| 49 | + | |
| 50 | +static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol, | |
| 51 | + struct snd_ctl_elem_info *uinfo) | |
| 52 | +{ | |
| 53 | + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | |
| 54 | + struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component); | |
| 55 | + | |
| 56 | + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; | |
| 57 | + uinfo->count = sizeof(hcp->eld); | |
| 58 | + | |
| 59 | + return 0; | |
| 60 | +} | |
| 61 | + | |
| 62 | +static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, | |
| 63 | + struct snd_ctl_elem_value *ucontrol) | |
| 64 | +{ | |
| 65 | + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | |
| 66 | + struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component); | |
| 67 | + | |
| 68 | + memcpy(ucontrol->value.bytes.data, hcp->eld, sizeof(hcp->eld)); | |
| 69 | + | |
| 70 | + return 0; | |
| 71 | +} | |
| 72 | + | |
| 73 | +static const struct snd_kcontrol_new hdmi_controls[] = { | |
| 74 | + { | |
| 75 | + .access = SNDRV_CTL_ELEM_ACCESS_READ | | |
| 76 | + SNDRV_CTL_ELEM_ACCESS_VOLATILE, | |
| 77 | + .iface = SNDRV_CTL_ELEM_IFACE_PCM, | |
| 78 | + .name = "ELD", | |
| 79 | + .info = hdmi_eld_ctl_info, | |
| 80 | + .get = hdmi_eld_ctl_get, | |
| 81 | + }, | |
| 82 | +}; | |
| 83 | + | |
| 84 | +static int hdmi_codec_new_stream(struct snd_pcm_substream *substream, | |
| 85 | + struct snd_soc_dai *dai) | |
| 86 | +{ | |
| 87 | + struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); | |
| 88 | + int ret = 0; | |
| 89 | + | |
| 90 | + mutex_lock(&hcp->current_stream_lock); | |
| 91 | + if (!hcp->current_stream) { | |
| 92 | + hcp->current_stream = substream; | |
| 93 | + } else if (hcp->current_stream != substream) { | |
| 94 | + dev_err(dai->dev, "Only one simultaneous stream supported!\n"); | |
| 95 | + ret = -EINVAL; | |
| 96 | + } | |
| 97 | + mutex_unlock(&hcp->current_stream_lock); | |
| 98 | + | |
| 99 | + return ret; | |
| 100 | +} | |
| 101 | + | |
| 102 | +static int hdmi_codec_startup(struct snd_pcm_substream *substream, | |
| 103 | + struct snd_soc_dai *dai) | |
| 104 | +{ | |
| 105 | + struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); | |
| 106 | + int ret = 0; | |
| 107 | + | |
| 108 | + dev_dbg(dai->dev, "%s()\n", __func__); | |
| 109 | + | |
| 110 | + ret = hdmi_codec_new_stream(substream, dai); | |
| 111 | + if (ret) | |
| 112 | + return ret; | |
| 113 | + | |
| 114 | + if (hcp->hcd.ops->audio_startup) { | |
| 115 | + ret = hcp->hcd.ops->audio_startup(dai->dev->parent); | |
| 116 | + if (ret) { | |
| 117 | + mutex_lock(&hcp->current_stream_lock); | |
| 118 | + hcp->current_stream = NULL; | |
| 119 | + mutex_unlock(&hcp->current_stream_lock); | |
| 120 | + return ret; | |
| 121 | + } | |
| 122 | + } | |
| 123 | + | |
| 124 | + if (hcp->hcd.ops->get_eld) { | |
| 125 | + ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->eld, | |
| 126 | + sizeof(hcp->eld)); | |
| 127 | + | |
| 128 | + if (!ret) { | |
| 129 | + ret = snd_pcm_hw_constraint_eld(substream->runtime, | |
| 130 | + hcp->eld); | |
| 131 | + if (ret) | |
| 132 | + return ret; | |
| 133 | + } | |
| 134 | + } | |
| 135 | + return 0; | |
| 136 | +} | |
| 137 | + | |
| 138 | +static void hdmi_codec_shutdown(struct snd_pcm_substream *substream, | |
| 139 | + struct snd_soc_dai *dai) | |
| 140 | +{ | |
| 141 | + struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); | |
| 142 | + | |
| 143 | + dev_dbg(dai->dev, "%s()\n", __func__); | |
| 144 | + | |
| 145 | + WARN_ON(hcp->current_stream != substream); | |
| 146 | + | |
| 147 | + hcp->hcd.ops->audio_shutdown(dai->dev->parent); | |
| 148 | + | |
| 149 | + mutex_lock(&hcp->current_stream_lock); | |
| 150 | + hcp->current_stream = NULL; | |
| 151 | + mutex_unlock(&hcp->current_stream_lock); | |
| 152 | +} | |
| 153 | + | |
| 154 | +static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, | |
| 155 | + struct snd_pcm_hw_params *params, | |
| 156 | + struct snd_soc_dai *dai) | |
| 157 | +{ | |
| 158 | + struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); | |
| 159 | + struct hdmi_codec_params hp = { | |
| 160 | + .iec = { | |
| 161 | + .status = { 0 }, | |
| 162 | + .subcode = { 0 }, | |
| 163 | + .pad = 0, | |
| 164 | + .dig_subframe = { 0 }, | |
| 165 | + } | |
| 166 | + }; | |
| 167 | + int ret; | |
| 168 | + | |
| 169 | + dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__, | |
| 170 | + params_width(params), params_rate(params), | |
| 171 | + params_channels(params)); | |
| 172 | + | |
| 173 | + if (params_width(params) > 24) | |
| 174 | + params->msbits = 24; | |
| 175 | + | |
| 176 | + ret = snd_pcm_create_iec958_consumer_hw_params(params, hp.iec.status, | |
| 177 | + sizeof(hp.iec.status)); | |
| 178 | + if (ret < 0) { | |
| 179 | + dev_err(dai->dev, "Creating IEC958 channel status failed %d\n", | |
| 180 | + ret); | |
| 181 | + return ret; | |
| 182 | + } | |
| 183 | + | |
| 184 | + ret = hdmi_codec_new_stream(substream, dai); | |
| 185 | + if (ret) | |
| 186 | + return ret; | |
| 187 | + | |
| 188 | + hdmi_audio_infoframe_init(&hp.cea); | |
| 189 | + hp.cea.channels = params_channels(params); | |
| 190 | + hp.cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; | |
| 191 | + hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; | |
| 192 | + hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; | |
| 193 | + | |
| 194 | + hp.sample_width = params_width(params); | |
| 195 | + hp.sample_rate = params_rate(params); | |
| 196 | + hp.channels = params_channels(params); | |
| 197 | + | |
| 198 | + return hcp->hcd.ops->hw_params(dai->dev->parent, &hcp->daifmt[dai->id], | |
| 199 | + &hp); | |
| 200 | +} | |
| 201 | + | |
| 202 | +static int hdmi_codec_set_fmt(struct snd_soc_dai *dai, | |
| 203 | + unsigned int fmt) | |
| 204 | +{ | |
| 205 | + struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); | |
| 206 | + struct hdmi_codec_daifmt cf = { 0 }; | |
| 207 | + int ret = 0; | |
| 208 | + | |
| 209 | + dev_dbg(dai->dev, "%s()\n", __func__); | |
| 210 | + | |
| 211 | + if (dai->id == DAI_ID_SPDIF) { | |
| 212 | + cf.fmt = HDMI_SPDIF; | |
| 213 | + } else { | |
| 214 | + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | |
| 215 | + case SND_SOC_DAIFMT_CBM_CFM: | |
| 216 | + cf.bit_clk_master = 1; | |
| 217 | + cf.frame_clk_master = 1; | |
| 218 | + break; | |
| 219 | + case SND_SOC_DAIFMT_CBS_CFM: | |
| 220 | + cf.frame_clk_master = 1; | |
| 221 | + break; | |
| 222 | + case SND_SOC_DAIFMT_CBM_CFS: | |
| 223 | + cf.bit_clk_master = 1; | |
| 224 | + break; | |
| 225 | + case SND_SOC_DAIFMT_CBS_CFS: | |
| 226 | + break; | |
| 227 | + default: | |
| 228 | + return -EINVAL; | |
| 229 | + } | |
| 230 | + | |
| 231 | + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | |
| 232 | + case SND_SOC_DAIFMT_NB_NF: | |
| 233 | + break; | |
| 234 | + case SND_SOC_DAIFMT_NB_IF: | |
| 235 | + cf.frame_clk_inv = 1; | |
| 236 | + break; | |
| 237 | + case SND_SOC_DAIFMT_IB_NF: | |
| 238 | + cf.bit_clk_inv = 1; | |
| 239 | + break; | |
| 240 | + case SND_SOC_DAIFMT_IB_IF: | |
| 241 | + cf.frame_clk_inv = 1; | |
| 242 | + cf.bit_clk_inv = 1; | |
| 243 | + break; | |
| 244 | + } | |
| 245 | + | |
| 246 | + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | |
| 247 | + case SND_SOC_DAIFMT_I2S: | |
| 248 | + cf.fmt = HDMI_I2S; | |
| 249 | + break; | |
| 250 | + case SND_SOC_DAIFMT_DSP_A: | |
| 251 | + cf.fmt = HDMI_DSP_A; | |
| 252 | + break; | |
| 253 | + case SND_SOC_DAIFMT_DSP_B: | |
| 254 | + cf.fmt = HDMI_DSP_B; | |
| 255 | + break; | |
| 256 | + case SND_SOC_DAIFMT_RIGHT_J: | |
| 257 | + cf.fmt = HDMI_RIGHT_J; | |
| 258 | + break; | |
| 259 | + case SND_SOC_DAIFMT_LEFT_J: | |
| 260 | + cf.fmt = HDMI_LEFT_J; | |
| 261 | + break; | |
| 262 | + case SND_SOC_DAIFMT_AC97: | |
| 263 | + cf.fmt = HDMI_AC97; | |
| 264 | + break; | |
| 265 | + default: | |
| 266 | + dev_err(dai->dev, "Invalid DAI interface format\n"); | |
| 267 | + return -EINVAL; | |
| 268 | + } | |
| 269 | + } | |
| 270 | + | |
| 271 | + hcp->daifmt[dai->id] = cf; | |
| 272 | + | |
| 273 | + return ret; | |
| 274 | +} | |
| 275 | + | |
| 276 | +static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute) | |
| 277 | +{ | |
| 278 | + struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); | |
| 279 | + | |
| 280 | + dev_dbg(dai->dev, "%s()\n", __func__); | |
| 281 | + | |
| 282 | + if (hcp->hcd.ops->digital_mute) | |
| 283 | + return hcp->hcd.ops->digital_mute(dai->dev->parent, mute); | |
| 284 | + | |
| 285 | + return 0; | |
| 286 | +} | |
| 287 | + | |
| 288 | +static const struct snd_soc_dai_ops hdmi_dai_ops = { | |
| 289 | + .startup = hdmi_codec_startup, | |
| 290 | + .shutdown = hdmi_codec_shutdown, | |
| 291 | + .hw_params = hdmi_codec_hw_params, | |
| 292 | + .set_fmt = hdmi_codec_set_fmt, | |
| 293 | + .digital_mute = hdmi_codec_digital_mute, | |
| 294 | +}; | |
| 295 | + | |
| 296 | + | |
| 297 | +#define HDMI_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ | |
| 298 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ | |
| 299 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\ | |
| 300 | + SNDRV_PCM_RATE_192000) | |
| 301 | + | |
| 302 | +#define SPDIF_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\ | |
| 303 | + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\ | |
| 304 | + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\ | |
| 305 | + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) | |
| 306 | + | |
| 307 | +/* | |
| 308 | + * This list is only for formats allowed on the I2S bus. So there is | |
| 309 | + * some formats listed that are not supported by HDMI interface. For | |
| 310 | + * instance allowing the 32-bit formats enables 24-precision with CPU | |
| 311 | + * DAIs that do not support 24-bit formats. If the extra formats cause | |
| 312 | + * problems, we should add the video side driver an option to disable | |
| 313 | + * them. | |
| 314 | + */ | |
| 315 | +#define I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\ | |
| 316 | + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\ | |
| 317 | + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\ | |
| 318 | + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\ | |
| 319 | + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) | |
| 320 | + | |
| 321 | +static struct snd_soc_dai_driver hdmi_i2s_dai = { | |
| 322 | + .name = "i2s-hifi", | |
| 323 | + .id = DAI_ID_I2S, | |
| 324 | + .playback = { | |
| 325 | + .stream_name = "Playback", | |
| 326 | + .channels_min = 2, | |
| 327 | + .channels_max = 8, | |
| 328 | + .rates = HDMI_RATES, | |
| 329 | + .formats = I2S_FORMATS, | |
| 330 | + .sig_bits = 24, | |
| 331 | + }, | |
| 332 | + .ops = &hdmi_dai_ops, | |
| 333 | +}; | |
| 334 | + | |
| 335 | +static const struct snd_soc_dai_driver hdmi_spdif_dai = { | |
| 336 | + .name = "spdif-hifi", | |
| 337 | + .id = DAI_ID_SPDIF, | |
| 338 | + .playback = { | |
| 339 | + .stream_name = "Playback", | |
| 340 | + .channels_min = 2, | |
| 341 | + .channels_max = 2, | |
| 342 | + .rates = HDMI_RATES, | |
| 343 | + .formats = SPDIF_FORMATS, | |
| 344 | + }, | |
| 345 | + .ops = &hdmi_dai_ops, | |
| 346 | +}; | |
| 347 | + | |
| 348 | +static struct snd_soc_codec_driver hdmi_codec = { | |
| 349 | + .controls = hdmi_controls, | |
| 350 | + .num_controls = ARRAY_SIZE(hdmi_controls), | |
| 351 | + .dapm_widgets = hdmi_widgets, | |
| 352 | + .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets), | |
| 353 | + .dapm_routes = hdmi_routes, | |
| 354 | + .num_dapm_routes = ARRAY_SIZE(hdmi_routes), | |
| 355 | +}; | |
| 356 | + | |
| 357 | +static int hdmi_codec_probe(struct platform_device *pdev) | |
| 358 | +{ | |
| 359 | + struct hdmi_codec_pdata *hcd = pdev->dev.platform_data; | |
| 360 | + struct device *dev = &pdev->dev; | |
| 361 | + struct hdmi_codec_priv *hcp; | |
| 362 | + int dai_count, i = 0; | |
| 363 | + int ret; | |
| 364 | + | |
| 365 | + dev_dbg(dev, "%s()\n", __func__); | |
| 366 | + | |
| 367 | + if (!hcd) { | |
| 368 | + dev_err(dev, "%s: No plalform data\n", __func__); | |
| 369 | + return -EINVAL; | |
| 370 | + } | |
| 371 | + | |
| 372 | + dai_count = hcd->i2s + hcd->spdif; | |
| 373 | + if (dai_count < 1 || !hcd->ops || !hcd->ops->hw_params || | |
| 374 | + !hcd->ops->audio_shutdown) { | |
| 375 | + dev_err(dev, "%s: Invalid parameters\n", __func__); | |
| 376 | + return -EINVAL; | |
| 377 | + } | |
| 378 | + | |
| 379 | + hcp = devm_kzalloc(dev, sizeof(*hcp), GFP_KERNEL); | |
| 380 | + if (!hcp) | |
| 381 | + return -ENOMEM; | |
| 382 | + | |
| 383 | + hcp->hcd = *hcd; | |
| 384 | + mutex_init(&hcp->current_stream_lock); | |
| 385 | + | |
| 386 | + hcp->daidrv = devm_kzalloc(dev, dai_count * sizeof(*hcp->daidrv), | |
| 387 | + GFP_KERNEL); | |
| 388 | + if (!hcp->daidrv) | |
| 389 | + return -ENOMEM; | |
| 390 | + | |
| 391 | + if (hcd->i2s) { | |
| 392 | + hcp->daidrv[i] = hdmi_i2s_dai; | |
| 393 | + hcp->daidrv[i].playback.channels_max = | |
| 394 | + hcd->max_i2s_channels; | |
| 395 | + i++; | |
| 396 | + } | |
| 397 | + | |
| 398 | + if (hcd->spdif) | |
| 399 | + hcp->daidrv[i] = hdmi_spdif_dai; | |
| 400 | + | |
| 401 | + ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv, | |
| 402 | + dai_count); | |
| 403 | + if (ret) { | |
| 404 | + dev_err(dev, "%s: snd_soc_register_codec() failed (%d)\n", | |
| 405 | + __func__, ret); | |
| 406 | + return ret; | |
| 407 | + } | |
| 408 | + | |
| 409 | + dev_set_drvdata(dev, hcp); | |
| 410 | + return 0; | |
| 411 | +} | |
| 412 | + | |
| 413 | +static int hdmi_codec_remove(struct platform_device *pdev) | |
| 414 | +{ | |
| 415 | + snd_soc_unregister_codec(&pdev->dev); | |
| 416 | + return 0; | |
| 417 | +} | |
| 418 | + | |
| 419 | +static struct platform_driver hdmi_codec_driver = { | |
| 420 | + .driver = { | |
| 421 | + .name = HDMI_CODEC_DRV_NAME, | |
| 422 | + }, | |
| 423 | + .probe = hdmi_codec_probe, | |
| 424 | + .remove = hdmi_codec_remove, | |
| 425 | +}; | |
| 426 | + | |
| 427 | +module_platform_driver(hdmi_codec_driver); | |
| 428 | + | |
| 429 | +MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>"); | |
| 430 | +MODULE_DESCRIPTION("HDMI Audio Codec Driver"); | |
| 431 | +MODULE_LICENSE("GPL"); | |
| 432 | +MODULE_ALIAS("platform:" HDMI_CODEC_DRV_NAME); | |
| @@ -0,0 +1,69 @@ | ||
| 1 | +/* | |
| 2 | + * Driver for the PCM5102A codec | |
| 3 | + * | |
| 4 | + * Author: Florian Meier <florian.meier@koalo.de> | |
| 5 | + * Copyright 2013 | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or | |
| 8 | + * modify it under the terms of the GNU General Public License | |
| 9 | + * version 2 as published by the Free Software Foundation. | |
| 10 | + * | |
| 11 | + * This program is distributed in the hope that it will be useful, but | |
| 12 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 14 | + * General Public License for more details. | |
| 15 | + */ | |
| 16 | + | |
| 17 | +#include <linux/init.h> | |
| 18 | +#include <linux/module.h> | |
| 19 | +#include <linux/platform_device.h> | |
| 20 | + | |
| 21 | +#include <sound/soc.h> | |
| 22 | + | |
| 23 | +static struct snd_soc_dai_driver pcm5102a_dai = { | |
| 24 | + .name = "pcm5102a-hifi", | |
| 25 | + .playback = { | |
| 26 | + .channels_min = 2, | |
| 27 | + .channels_max = 2, | |
| 28 | + .rates = SNDRV_PCM_RATE_8000_192000, | |
| 29 | + .formats = SNDRV_PCM_FMTBIT_S16_LE | | |
| 30 | + SNDRV_PCM_FMTBIT_S24_LE | | |
| 31 | + SNDRV_PCM_FMTBIT_S32_LE | |
| 32 | + }, | |
| 33 | +}; | |
| 34 | + | |
| 35 | +static struct snd_soc_codec_driver soc_codec_dev_pcm5102a; | |
| 36 | + | |
| 37 | +static int pcm5102a_probe(struct platform_device *pdev) | |
| 38 | +{ | |
| 39 | + return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm5102a, | |
| 40 | + &pcm5102a_dai, 1); | |
| 41 | +} | |
| 42 | + | |
| 43 | +static int pcm5102a_remove(struct platform_device *pdev) | |
| 44 | +{ | |
| 45 | + snd_soc_unregister_codec(&pdev->dev); | |
| 46 | + return 0; | |
| 47 | +} | |
| 48 | + | |
| 49 | +static const struct of_device_id pcm5102a_of_match[] = { | |
| 50 | + { .compatible = "ti,pcm5102a", }, | |
| 51 | + { } | |
| 52 | +}; | |
| 53 | +MODULE_DEVICE_TABLE(of, pcm5102a_of_match); | |
| 54 | + | |
| 55 | +static struct platform_driver pcm5102a_codec_driver = { | |
| 56 | + .probe = pcm5102a_probe, | |
| 57 | + .remove = pcm5102a_remove, | |
| 58 | + .driver = { | |
| 59 | + .name = "pcm5102a-codec", | |
| 60 | + .owner = THIS_MODULE, | |
| 61 | + .of_match_table = pcm5102a_of_match, | |
| 62 | + }, | |
| 63 | +}; | |
| 64 | + | |
| 65 | +module_platform_driver(pcm5102a_codec_driver); | |
| 66 | + | |
| 67 | +MODULE_DESCRIPTION("ASoC PCM5102A codec driver"); | |
| 68 | +MODULE_AUTHOR("Florian Meier <florian.meier@koalo.de>"); | |
| 69 | +MODULE_LICENSE("GPL v2"); | |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/i2c.h> |
| 18 | 18 | #include <linux/platform_device.h> |
| 19 | 19 | #include <linux/spi/spi.h> |
| 20 | +#include <linux/dmi.h> | |
| 20 | 21 | #include <linux/acpi.h> |
| 21 | 22 | #include <sound/core.h> |
| 22 | 23 | #include <sound/pcm.h> |
| @@ -1132,6 +1133,17 @@ static const struct acpi_device_id rt298_acpi_match[] = { · 1109 unmodified lines | ||
| 1132 | 1133 | }; |
| 1133 | 1134 | MODULE_DEVICE_TABLE(acpi, rt298_acpi_match); |
| 1134 | 1135 | |
| 1136 | +static const struct dmi_system_id force_combo_jack_table[] = { | |
| 1137 | + { | |
| 1138 | + .ident = "Intel Broxton P", | |
| 1139 | + .matches = { | |
| 1140 | + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp"), | |
| 1141 | + DMI_MATCH(DMI_PRODUCT_NAME, "Broxton P") | |
| 1142 | + } | |
| 1143 | + }, | |
| 1144 | + { } | |
| 1145 | +}; | |
| 1146 | + | |
| 1135 | 1147 | static int rt298_i2c_probe(struct i2c_client *i2c, |
| 1136 | 1148 | const struct i2c_device_id *id) |
| 1137 | 1149 | { |
| @@ -1184,11 +1196,16 @@ static int rt298_i2c_probe(struct i2c_client *i2c, · 46 unmodified lines | ||
| 1184 | 1196 | |
| 1185 | 1197 | /* enable jack combo mode on supported devices */ |
| 1186 | 1198 | acpiid = acpi_match_device(dev->driver->acpi_match_table, dev); |
| 1187 | − if (acpiid) { | |
| 1199 | + if (acpiid && acpiid->driver_data) { | |
| 1188 | 1200 | rt298->pdata = *(struct rt298_platform_data *) |
| 1189 | 1201 | acpiid->driver_data; |
| 1190 | 1202 | } |
| 1191 | 1203 | |
| 1204 | + if (dmi_check_system(force_combo_jack_table)) { | |
| 1205 | + rt298->pdata.cbj_en = true; | |
| 1206 | + rt298->pdata.gpio2_en = false; | |
| 1207 | + } | |
| 1208 | + | |
| 1192 | 1209 | /* VREF Charging */ |
| 1193 | 1210 | regmap_update_bits(rt298->regmap, 0x04, 0x80, 0x80); |
| 1194 | 1211 | regmap_update_bits(rt298->regmap, 0x1b, 0x860, 0x860); |
| @@ -3286,10 +3286,8 @@ static void rt5645_jack_detect_work(struct work_struct *work) · 3285 unmodified lines | ||
| 3286 | 3286 | if (btn_type == 0)/* button release */ |
| 3287 | 3287 | report = rt5645->jack_type; |
| 3288 | 3288 | else { |
| 3289 | − if (rt5645->pdata.jd_invert) { | |
| 3290 | − mod_timer(&rt5645->btn_check_timer, | |
| 3291 | − msecs_to_jiffies(100)); | |
| 3292 | − } | |
| 3289 | + mod_timer(&rt5645->btn_check_timer, | |
| 3290 | + msecs_to_jiffies(100)); | |
| 3293 | 3291 | } |
| 3294 | 3292 | |
| 3295 | 3293 | break; |
| @@ -3557,6 +3555,12 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = { · 261 unmodified lines | ||
| 3557 | 3555 | DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), |
| 3558 | 3556 | }, |
| 3559 | 3557 | }, |
| 3558 | + { | |
| 3559 | + .ident = "Google Setzer", | |
| 3560 | + .matches = { | |
| 3561 | + DMI_MATCH(DMI_PRODUCT_NAME, "Setzer"), | |
| 3562 | + }, | |
| 3563 | + }, | |
| 3560 | 3564 | { } |
| 3561 | 3565 | }; |
| 3562 | 3566 | |
| @@ -3810,9 +3814,9 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, · 247 unmodified lines | ||
| 3810 | 3814 | if (rt5645->pdata.jd_invert) { |
| 3811 | 3815 | regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2, |
| 3812 | 3816 | RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV); |
| 3813 | − setup_timer(&rt5645->btn_check_timer, | |
| 3814 | − rt5645_btn_check_callback, (unsigned long)rt5645); | |
| 3815 | 3817 | } |
| 3818 | + setup_timer(&rt5645->btn_check_timer, | |
| 3819 | + rt5645_btn_check_callback, (unsigned long)rt5645); | |
| 3816 | 3820 | |
| 3817 | 3821 | INIT_DELAYED_WORK(&rt5645->jack_detect_work, rt5645_jack_detect_work); |
| 3818 | 3822 | INIT_DELAYED_WORK(&rt5645->rcclock_work, rt5645_rcclock_work); |
| @@ -2098,10 +2098,14 @@ static int wm5102_probe(struct platform_device *pdev) · 2097 unmodified lines | ||
| 2098 | 2098 | |
| 2099 | 2099 | static int wm5102_remove(struct platform_device *pdev) |
| 2100 | 2100 | { |
| 2101 | + struct wm5102_priv *wm5102 = platform_get_drvdata(pdev); | |
| 2102 | + | |
| 2101 | 2103 | snd_soc_unregister_platform(&pdev->dev); |
| 2102 | 2104 | snd_soc_unregister_codec(&pdev->dev); |
| 2103 | 2105 | pm_runtime_disable(&pdev->dev); |
| 2104 | 2106 | |
| 2107 | + wm_adsp2_remove(&wm5102->core.adsp[0]); | |
| 2108 | + | |
| 2105 | 2109 | return 0; |
| 2106 | 2110 | } |
| 2107 | 2111 | |
| @@ -2437,10 +2437,16 @@ static int wm5110_probe(struct platform_device *pdev) · 2436 unmodified lines | ||
| 2437 | 2437 | |
| 2438 | 2438 | static int wm5110_remove(struct platform_device *pdev) |
| 2439 | 2439 | { |
| 2440 | + struct wm5110_priv *wm5110 = platform_get_drvdata(pdev); | |
| 2441 | + int i; | |
| 2442 | + | |
| 2440 | 2443 | snd_soc_unregister_platform(&pdev->dev); |
| 2441 | 2444 | snd_soc_unregister_codec(&pdev->dev); |
| 2442 | 2445 | pm_runtime_disable(&pdev->dev); |
| 2443 | 2446 | |
| 2447 | + for (i = 0; i < WM5110_NUM_ADSP; i++) | |
| 2448 | + wm_adsp2_remove(&wm5110->core.adsp[i]); | |
| 2449 | + | |
| 2444 | 2450 | return 0; |
| 2445 | 2451 | } |
| 2446 | 2452 | |
| @@ -160,6 +160,8 @@ · 159 unmodified lines | ||
| 160 | 160 | #define ADSP2_RAM_RDY_SHIFT 0 |
| 161 | 161 | #define ADSP2_RAM_RDY_WIDTH 1 |
| 162 | 162 | |
| 163 | +#define ADSP_MAX_STD_CTRL_SIZE 512 | |
| 164 | + | |
| 163 | 165 | struct wm_adsp_buf { |
| 164 | 166 | struct list_head list; |
| 165 | 167 | void *buf; |
| @@ -271,8 +273,11 @@ struct wm_adsp_buffer { · 105 unmodified lines | ||
| 271 | 273 | __be32 words_written[2]; /* total words written (64 bit) */ |
| 272 | 274 | }; |
| 273 | 275 | |
| 276 | +struct wm_adsp_compr; | |
| 277 | + | |
| 274 | 278 | struct wm_adsp_compr_buf { |
| 275 | 279 | struct wm_adsp *dsp; |
| 280 | + struct wm_adsp_compr *compr; | |
| 276 | 281 | |
| 277 | 282 | struct wm_adsp_buffer_region *regions; |
| 278 | 283 | u32 host_buf_ptr; |
| @@ -435,6 +440,7 @@ struct wm_coeff_ctl { · 156 unmodified lines | ||
| 435 | 440 | size_t len; |
| 436 | 441 | unsigned int set:1; |
| 437 | 442 | struct snd_kcontrol *kcontrol; |
| 443 | + struct soc_bytes_ext bytes_ext; | |
| 438 | 444 | unsigned int flags; |
| 439 | 445 | }; |
| 440 | 446 | |
| @@ -711,10 +717,17 @@ static void wm_adsp2_show_fw_status(struct wm_adsp *dsp) · 270 unmodified lines | ||
| 711 | 717 | be16_to_cpu(scratch[3])); |
| 712 | 718 | } |
| 713 | 719 | |
| 720 | +static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext) | |
| 721 | +{ | |
| 722 | + return container_of(ext, struct wm_coeff_ctl, bytes_ext); | |
| 723 | +} | |
| 724 | + | |
| 714 | 725 | static int wm_coeff_info(struct snd_kcontrol *kctl, |
| 715 | 726 | struct snd_ctl_elem_info *uinfo) |
| 716 | 727 | { |
| 717 | − struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kctl->private_value; | |
| 728 | + struct soc_bytes_ext *bytes_ext = | |
| 729 | + (struct soc_bytes_ext *)kctl->private_value; | |
| 730 | + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); | |
| 718 | 731 | |
| 719 | 732 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; |
| 720 | 733 | uinfo->count = ctl->len; |
| @@ -763,7 +776,9 @@ static int wm_coeff_write_control(struct wm_coeff_ctl *ctl, · 42 unmodified lines | ||
| 763 | 776 | static int wm_coeff_put(struct snd_kcontrol *kctl, |
| 764 | 777 | struct snd_ctl_elem_value *ucontrol) |
| 765 | 778 | { |
| 766 | − struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kctl->private_value; | |
| 779 | + struct soc_bytes_ext *bytes_ext = | |
| 780 | + (struct soc_bytes_ext *)kctl->private_value; | |
| 781 | + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); | |
| 767 | 782 | char *p = ucontrol->value.bytes.data; |
| 768 | 783 | int ret = 0; |
| 769 | 784 | |
| @@ -780,6 +795,29 @@ static int wm_coeff_put(struct snd_kcontrol *kctl, · 10 unmodified lines | ||
| 780 | 795 | return ret; |
| 781 | 796 | } |
| 782 | 797 | |
| 798 | +static int wm_coeff_tlv_put(struct snd_kcontrol *kctl, | |
| 799 | + const unsigned int __user *bytes, unsigned int size) | |
| 800 | +{ | |
| 801 | + struct soc_bytes_ext *bytes_ext = | |
| 802 | + (struct soc_bytes_ext *)kctl->private_value; | |
| 803 | + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); | |
| 804 | + int ret = 0; | |
| 805 | + | |
| 806 | + mutex_lock(&ctl->dsp->pwr_lock); | |
| 807 | + | |
| 808 | + if (copy_from_user(ctl->cache, bytes, size)) { | |
| 809 | + ret = -EFAULT; | |
| 810 | + } else { | |
| 811 | + ctl->set = 1; | |
| 812 | + if (ctl->enabled) | |
| 813 | + ret = wm_coeff_write_control(ctl, ctl->cache, size); | |
| 814 | + } | |
| 815 | + | |
| 816 | + mutex_unlock(&ctl->dsp->pwr_lock); | |
| 817 | + | |
| 818 | + return ret; | |
| 819 | +} | |
| 820 | + | |
| 783 | 821 | static int wm_coeff_read_control(struct wm_coeff_ctl *ctl, |
| 784 | 822 | void *buf, size_t len) |
| 785 | 823 | { |
| @@ -822,7 +860,9 @@ static int wm_coeff_read_control(struct wm_coeff_ctl *ctl, · 36 unmodified lines | ||
| 822 | 860 | static int wm_coeff_get(struct snd_kcontrol *kctl, |
| 823 | 861 | struct snd_ctl_elem_value *ucontrol) |
| 824 | 862 | { |
| 825 | − struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kctl->private_value; | |
| 863 | + struct soc_bytes_ext *bytes_ext = | |
| 864 | + (struct soc_bytes_ext *)kctl->private_value; | |
| 865 | + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); | |
| 826 | 866 | char *p = ucontrol->value.bytes.data; |
| 827 | 867 | int ret = 0; |
| 828 | 868 | |
| @@ -845,12 +885,72 @@ static int wm_coeff_get(struct snd_kcontrol *kctl, · 16 unmodified lines | ||
| 845 | 885 | return ret; |
| 846 | 886 | } |
| 847 | 887 | |
| 888 | +static int wm_coeff_tlv_get(struct snd_kcontrol *kctl, | |
| 889 | + unsigned int __user *bytes, unsigned int size) | |
| 890 | +{ | |
| 891 | + struct soc_bytes_ext *bytes_ext = | |
| 892 | + (struct soc_bytes_ext *)kctl->private_value; | |
| 893 | + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); | |
| 894 | + int ret = 0; | |
| 895 | + | |
| 896 | + mutex_lock(&ctl->dsp->pwr_lock); | |
| 897 | + | |
| 898 | + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { | |
| 899 | + if (ctl->enabled) | |
| 900 | + ret = wm_coeff_read_control(ctl, ctl->cache, size); | |
| 901 | + else | |
| 902 | + ret = -EPERM; | |
| 903 | + } else { | |
| 904 | + if (!ctl->flags && ctl->enabled) | |
| 905 | + ret = wm_coeff_read_control(ctl, ctl->cache, size); | |
| 906 | + } | |
| 907 | + | |
| 908 | + if (!ret && copy_to_user(bytes, ctl->cache, size)) | |
| 909 | + ret = -EFAULT; | |
| 910 | + | |
| 911 | + mutex_unlock(&ctl->dsp->pwr_lock); | |
| 912 | + | |
| 913 | + return ret; | |
| 914 | +} | |
| 915 | + | |
| 848 | 916 | struct wmfw_ctl_work { |
| 849 | 917 | struct wm_adsp *dsp; |
| 850 | 918 | struct wm_coeff_ctl *ctl; |
| 851 | 919 | struct work_struct work; |
| 852 | 920 | }; |
| 853 | 921 | |
| 922 | +static unsigned int wmfw_convert_flags(unsigned int in, unsigned int len) | |
| 923 | +{ | |
| 924 | + unsigned int out, rd, wr, vol; | |
| 925 | + | |
| 926 | + if (len > ADSP_MAX_STD_CTRL_SIZE) { | |
| 927 | + rd = SNDRV_CTL_ELEM_ACCESS_TLV_READ; | |
| 928 | + wr = SNDRV_CTL_ELEM_ACCESS_TLV_WRITE; | |
| 929 | + vol = SNDRV_CTL_ELEM_ACCESS_VOLATILE; | |
| 930 | + | |
| 931 | + out = SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; | |
| 932 | + } else { | |
| 933 | + rd = SNDRV_CTL_ELEM_ACCESS_READ; | |
| 934 | + wr = SNDRV_CTL_ELEM_ACCESS_WRITE; | |
| 935 | + vol = SNDRV_CTL_ELEM_ACCESS_VOLATILE; | |
| 936 | + | |
| 937 | + out = 0; | |
| 938 | + } | |
| 939 | + | |
| 940 | + if (in) { | |
| 941 | + if (in & WMFW_CTL_FLAG_READABLE) | |
| 942 | + out |= rd; | |
| 943 | + if (in & WMFW_CTL_FLAG_WRITEABLE) | |
| 944 | + out |= wr; | |
| 945 | + if (in & WMFW_CTL_FLAG_VOLATILE) | |
| 946 | + out |= vol; | |
| 947 | + } else { | |
| 948 | + out |= rd | wr | vol; | |
| 949 | + } | |
| 950 | + | |
| 951 | + return out; | |
| 952 | +} | |
| 953 | + | |
| 854 | 954 | static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) |
| 855 | 955 | { |
| 856 | 956 | struct snd_kcontrol_new *kcontrol; |
| @@ -868,19 +968,15 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) · 11 unmodified lines | ||
| 868 | 968 | kcontrol->info = wm_coeff_info; |
| 869 | 969 | kcontrol->get = wm_coeff_get; |
| 870 | 970 | kcontrol->put = wm_coeff_put; |
| 871 | − kcontrol->private_value = (unsigned long)ctl; | |
| 971 | + kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER; | |
| 972 | + kcontrol->tlv.c = snd_soc_bytes_tlv_callback; | |
| 973 | + kcontrol->private_value = (unsigned long)&ctl->bytes_ext; | |
| 872 | 974 | |
| 873 | − if (ctl->flags) { | |
| 874 | − if (ctl->flags & WMFW_CTL_FLAG_WRITEABLE) | |
| 875 | − kcontrol->access |= SNDRV_CTL_ELEM_ACCESS_WRITE; | |
| 876 | − if (ctl->flags & WMFW_CTL_FLAG_READABLE) | |
| 877 | − kcontrol->access |= SNDRV_CTL_ELEM_ACCESS_READ; | |
| 878 | − if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) | |
| 879 | − kcontrol->access |= SNDRV_CTL_ELEM_ACCESS_VOLATILE; | |
| 880 | − } else { | |
| 881 | − kcontrol->access = SNDRV_CTL_ELEM_ACCESS_READWRITE; | |
| 882 | − kcontrol->access |= SNDRV_CTL_ELEM_ACCESS_VOLATILE; | |
| 883 | − } | |
| 975 | + ctl->bytes_ext.max = ctl->len; | |
| 976 | + ctl->bytes_ext.get = wm_coeff_tlv_get; | |
| 977 | + ctl->bytes_ext.put = wm_coeff_tlv_put; | |
| 978 | + | |
| 979 | + kcontrol->access = wmfw_convert_flags(ctl->flags, ctl->len); | |
| 884 | 980 | |
| 885 | 981 | ret = snd_soc_add_card_controls(dsp->card, kcontrol, 1); |
| 886 | 982 | if (ret < 0) |
| @@ -944,6 +1040,13 @@ static void wm_adsp_ctl_work(struct work_struct *work) · 57 unmodified lines | ||
| 944 | 1040 | kfree(ctl_work); |
| 945 | 1041 | } |
| 946 | 1042 | |
| 1043 | +static void wm_adsp_free_ctl_blk(struct wm_coeff_ctl *ctl) | |
| 1044 | +{ | |
| 1045 | + kfree(ctl->cache); | |
| 1046 | + kfree(ctl->name); | |
| 1047 | + kfree(ctl); | |
| 1048 | +} | |
| 1049 | + | |
| 947 | 1050 | static int wm_adsp_create_control(struct wm_adsp *dsp, |
| 948 | 1051 | const struct wm_adsp_alg_region *alg_region, |
| 949 | 1052 | unsigned int offset, unsigned int len, |
| @@ -1032,11 +1135,6 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, · 82 unmodified lines | ||
| 1032 | 1135 | |
| 1033 | 1136 | ctl->flags = flags; |
| 1034 | 1137 | ctl->offset = offset; |
| 1035 | − if (len > 512) { | |
| 1036 | − adsp_warn(dsp, "Truncating control %s from %d\n", | |
| 1037 | − ctl->name, len); | |
| 1038 | − len = 512; | |
| 1039 | − } | |
| 1040 | 1138 | ctl->len = len; |
| 1041 | 1139 | ctl->cache = kzalloc(ctl->len, GFP_KERNEL); |
| 1042 | 1140 | if (!ctl->cache) { |
| @@ -1564,6 +1662,19 @@ static struct wm_adsp_alg_region *wm_adsp_create_region(struct wm_adsp *dsp, · 521 unmodified lines | ||
| 1564 | 1662 | return alg_region; |
| 1565 | 1663 | } |
| 1566 | 1664 | |
| 1665 | +static void wm_adsp_free_alg_regions(struct wm_adsp *dsp) | |
| 1666 | +{ | |
| 1667 | + struct wm_adsp_alg_region *alg_region; | |
| 1668 | + | |
| 1669 | + while (!list_empty(&dsp->alg_regions)) { | |
| 1670 | + alg_region = list_first_entry(&dsp->alg_regions, | |
| 1671 | + struct wm_adsp_alg_region, | |
| 1672 | + list); | |
| 1673 | + list_del(&alg_region->list); | |
| 1674 | + kfree(alg_region); | |
| 1675 | + } | |
| 1676 | +} | |
| 1677 | + | |
| 1567 | 1678 | static int wm_adsp1_setup_algs(struct wm_adsp *dsp) |
| 1568 | 1679 | { |
| 1569 | 1680 | struct wmfw_adsp1_id_hdr adsp1_id; |
| @@ -1994,7 +2105,6 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, · 424 unmodified lines | ||
| 1994 | 2105 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
| 1995 | 2106 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); |
| 1996 | 2107 | struct wm_adsp *dsp = &dsps[w->shift]; |
| 1997 | − struct wm_adsp_alg_region *alg_region; | |
| 1998 | 2108 | struct wm_coeff_ctl *ctl; |
| 1999 | 2109 | int ret; |
| 2000 | 2110 | unsigned int val; |
| @@ -2074,13 +2184,8 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, · 73 unmodified lines | ||
| 2074 | 2184 | list_for_each_entry(ctl, &dsp->ctl_list, list) |
| 2075 | 2185 | ctl->enabled = 0; |
| 2076 | 2186 | |
| 2077 | − while (!list_empty(&dsp->alg_regions)) { | |
| 2078 | − alg_region = list_first_entry(&dsp->alg_regions, | |
| 2079 | − struct wm_adsp_alg_region, | |
| 2080 | − list); | |
| 2081 | − list_del(&alg_region->list); | |
| 2082 | − kfree(alg_region); | |
| 2083 | − } | |
| 2187 | + | |
| 2188 | + wm_adsp_free_alg_regions(dsp); | |
| 2084 | 2189 | break; |
| 2085 | 2190 | |
| 2086 | 2191 | default: |
| @@ -2222,7 +2327,6 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, · 135 unmodified lines | ||
| 2222 | 2327 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
| 2223 | 2328 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); |
| 2224 | 2329 | struct wm_adsp *dsp = &dsps[w->shift]; |
| 2225 | − struct wm_adsp_alg_region *alg_region; | |
| 2226 | 2330 | struct wm_coeff_ctl *ctl; |
| 2227 | 2331 | int ret; |
| 2228 | 2332 | |
| @@ -2240,9 +2344,13 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, · 11 unmodified lines | ||
| 2240 | 2344 | if (ret != 0) |
| 2241 | 2345 | goto err; |
| 2242 | 2346 | |
| 2347 | + mutex_lock(&dsp->pwr_lock); | |
| 2348 | + | |
| 2243 | 2349 | if (wm_adsp_fw[dsp->fw].num_caps != 0) |
| 2244 | 2350 | ret = wm_adsp_buffer_init(dsp); |
| 2245 | 2351 | |
| 2352 | + mutex_unlock(&dsp->pwr_lock); | |
| 2353 | + | |
| 2246 | 2354 | break; |
| 2247 | 2355 | |
| 2248 | 2356 | case SND_SOC_DAPM_PRE_PMD: |
| @@ -2269,13 +2377,7 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, · 20 unmodified lines | ||
| 2269 | 2377 | list_for_each_entry(ctl, &dsp->ctl_list, list) |
| 2270 | 2378 | ctl->enabled = 0; |
| 2271 | 2379 | |
| 2272 | − while (!list_empty(&dsp->alg_regions)) { | |
| 2273 | − alg_region = list_first_entry(&dsp->alg_regions, | |
| 2274 | − struct wm_adsp_alg_region, | |
| 2275 | − list); | |
| 2276 | − list_del(&alg_region->list); | |
| 2277 | − kfree(alg_region); | |
| 2278 | − } | |
| 2380 | + wm_adsp_free_alg_regions(dsp); | |
| 2279 | 2381 | |
| 2280 | 2382 | if (wm_adsp_fw[dsp->fw].num_caps != 0) |
| 2281 | 2383 | wm_adsp_buffer_free(dsp); |
| @@ -2340,6 +2442,54 @@ int wm_adsp2_init(struct wm_adsp *dsp) · 58 unmodified lines | ||
| 2340 | 2442 | } |
| 2341 | 2443 | EXPORT_SYMBOL_GPL(wm_adsp2_init); |
| 2342 | 2444 | |
| 2445 | +void wm_adsp2_remove(struct wm_adsp *dsp) | |
| 2446 | +{ | |
| 2447 | + struct wm_coeff_ctl *ctl; | |
| 2448 | + | |
| 2449 | + while (!list_empty(&dsp->ctl_list)) { | |
| 2450 | + ctl = list_first_entry(&dsp->ctl_list, struct wm_coeff_ctl, | |
| 2451 | + list); | |
| 2452 | + list_del(&ctl->list); | |
| 2453 | + wm_adsp_free_ctl_blk(ctl); | |
| 2454 | + } | |
| 2455 | +} | |
| 2456 | +EXPORT_SYMBOL_GPL(wm_adsp2_remove); | |
| 2457 | + | |
| 2458 | +static inline int wm_adsp_compr_attached(struct wm_adsp_compr *compr) | |
| 2459 | +{ | |
| 2460 | + return compr->buf != NULL; | |
| 2461 | +} | |
| 2462 | + | |
| 2463 | +static int wm_adsp_compr_attach(struct wm_adsp_compr *compr) | |
| 2464 | +{ | |
| 2465 | + /* | |
| 2466 | + * Note this will be more complex once each DSP can support multiple | |
| 2467 | + * streams | |
| 2468 | + */ | |
| 2469 | + if (!compr->dsp->buffer) | |
| 2470 | + return -EINVAL; | |
| 2471 | + | |
| 2472 | + compr->buf = compr->dsp->buffer; | |
| 2473 | + compr->buf->compr = compr; | |
| 2474 | + | |
| 2475 | + return 0; | |
| 2476 | +} | |
| 2477 | + | |
| 2478 | +static void wm_adsp_compr_detach(struct wm_adsp_compr *compr) | |
| 2479 | +{ | |
| 2480 | + if (!compr) | |
| 2481 | + return; | |
| 2482 | + | |
| 2483 | + /* Wake the poll so it can see buffer is no longer attached */ | |
| 2484 | + if (compr->stream) | |
| 2485 | + snd_compr_fragment_elapsed(compr->stream); | |
| 2486 | + | |
| 2487 | + if (wm_adsp_compr_attached(compr)) { | |
| 2488 | + compr->buf->compr = NULL; | |
| 2489 | + compr->buf = NULL; | |
| 2490 | + } | |
| 2491 | +} | |
| 2492 | + | |
| 2343 | 2493 | int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) |
| 2344 | 2494 | { |
| 2345 | 2495 | struct wm_adsp_compr *compr; |
| @@ -2393,6 +2543,7 @@ int wm_adsp_compr_free(struct snd_compr_stream *stream) · 47 unmodified lines | ||
| 2393 | 2543 | |
| 2394 | 2544 | mutex_lock(&dsp->pwr_lock); |
| 2395 | 2545 | |
| 2546 | + wm_adsp_compr_detach(compr); | |
| 2396 | 2547 | dsp->compr = NULL; |
| 2397 | 2548 | |
| 2398 | 2549 | kfree(compr->raw_buf); |
| @@ -2689,6 +2840,8 @@ err_buffer: · 290 unmodified lines | ||
| 2689 | 2840 | static int wm_adsp_buffer_free(struct wm_adsp *dsp) |
| 2690 | 2841 | { |
| 2691 | 2842 | if (dsp->buffer) { |
| 2843 | + wm_adsp_compr_detach(dsp->buffer->compr); | |
| 2844 | + | |
| 2692 | 2845 | kfree(dsp->buffer->regions); |
| 2693 | 2846 | kfree(dsp->buffer); |
| 2694 | 2847 | |
| @@ -2698,25 +2851,6 @@ static int wm_adsp_buffer_free(struct wm_adsp *dsp) · 3 unmodified lines | ||
| 2698 | 2851 | return 0; |
| 2699 | 2852 | } |
| 2700 | 2853 | |
| 2701 | −static inline int wm_adsp_compr_attached(struct wm_adsp_compr *compr) | |
| 2702 | −{ | |
| 2703 | − return compr->buf != NULL; | |
| 2704 | −} | |
| 2705 | − | |
| 2706 | −static int wm_adsp_compr_attach(struct wm_adsp_compr *compr) | |
| 2707 | −{ | |
| 2708 | − /* | |
| 2709 | − * Note this will be more complex once each DSP can support multiple | |
| 2710 | − * streams | |
| 2711 | − */ | |
| 2712 | − if (!compr->dsp->buffer) | |
| 2713 | − return -EINVAL; | |
| 2714 | − | |
| 2715 | − compr->buf = compr->dsp->buffer; | |
| 2716 | − | |
| 2717 | − return 0; | |
| 2718 | −} | |
| 2719 | − | |
| 2720 | 2854 | int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd) |
| 2721 | 2855 | { |
| 2722 | 2856 | struct wm_adsp_compr *compr = stream->runtime->private_data; |
| @@ -2805,21 +2939,41 @@ static int wm_adsp_buffer_update_avail(struct wm_adsp_compr_buf *buf) · 82 unmodified lines | ||
| 2805 | 2939 | avail += wm_adsp_buffer_size(buf); |
| 2806 | 2940 | |
| 2807 | 2941 | adsp_dbg(buf->dsp, "readindex=0x%x, writeindex=0x%x, avail=%d\n", |
| 2808 | − buf->read_index, write_index, avail); | |
| 2942 | + buf->read_index, write_index, avail * WM_ADSP_DATA_WORD_SIZE); | |
| 2809 | 2943 | |
| 2810 | 2944 | buf->avail = avail; |
| 2811 | 2945 | |
| 2812 | 2946 | return 0; |
| 2813 | 2947 | } |
| 2814 | 2948 | |
| 2949 | +static int wm_adsp_buffer_get_error(struct wm_adsp_compr_buf *buf) | |
| 2950 | +{ | |
| 2951 | + int ret; | |
| 2952 | + | |
| 2953 | + ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error); | |
| 2954 | + if (ret < 0) { | |
| 2955 | + adsp_err(buf->dsp, "Failed to check buffer error: %d\n", ret); | |
| 2956 | + return ret; | |
| 2957 | + } | |
| 2958 | + if (buf->error != 0) { | |
| 2959 | + adsp_err(buf->dsp, "Buffer error occurred: %d\n", buf->error); | |
| 2960 | + return -EIO; | |
| 2961 | + } | |
| 2962 | + | |
| 2963 | + return 0; | |
| 2964 | +} | |
| 2965 | + | |
| 2815 | 2966 | int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) |
| 2816 | 2967 | { |
| 2817 | − struct wm_adsp_compr_buf *buf = dsp->buffer; | |
| 2818 | − struct wm_adsp_compr *compr = dsp->compr; | |
| 2968 | + struct wm_adsp_compr_buf *buf; | |
| 2969 | + struct wm_adsp_compr *compr; | |
| 2819 | 2970 | int ret = 0; |
| 2820 | 2971 | |
| 2821 | 2972 | mutex_lock(&dsp->pwr_lock); |
| 2822 | 2973 | |
| 2974 | + buf = dsp->buffer; | |
| 2975 | + compr = dsp->compr; | |
| 2976 | + | |
| 2823 | 2977 | if (!buf) { |
| 2824 | 2978 | ret = -ENODEV; |
| 2825 | 2979 | goto out; |
| @@ -2827,16 +2981,9 @@ int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) · 1 unmodified line | ||
| 2827 | 2981 | |
| 2828 | 2982 | adsp_dbg(dsp, "Handling buffer IRQ\n"); |
| 2829 | 2983 | |
| 2830 | − ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error); | |
| 2831 | − if (ret < 0) { | |
| 2832 | − adsp_err(dsp, "Failed to check buffer error: %d\n", ret); | |
| 2833 | − goto out; | |
| 2834 | − } | |
| 2835 | − if (buf->error != 0) { | |
| 2836 | − adsp_err(dsp, "Buffer error occurred: %d\n", buf->error); | |
| 2837 | − ret = -EIO; | |
| 2838 | − goto out; | |
| 2839 | − } | |
| 2984 | + ret = wm_adsp_buffer_get_error(buf); | |
| 2985 | + if (ret < 0) | |
| 2986 | + goto out_notify; /* Wake poll to report error */ | |
| 2840 | 2987 | |
| 2841 | 2988 | ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(irq_count), |
| 2842 | 2989 | &buf->irq_count); |
| @@ -2851,6 +2998,7 @@ int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) · 8 unmodified lines | ||
| 2851 | 2998 | goto out; |
| 2852 | 2999 | } |
| 2853 | 3000 | |
| 3001 | +out_notify: | |
| 2854 | 3002 | if (compr && compr->stream) |
| 2855 | 3003 | snd_compr_fragment_elapsed(compr->stream); |
| 2856 | 3004 | |
| @@ -2879,14 +3027,16 @@ int wm_adsp_compr_pointer(struct snd_compr_stream *stream, · 22 unmodified lines | ||
| 2879 | 3027 | struct snd_compr_tstamp *tstamp) |
| 2880 | 3028 | { |
| 2881 | 3029 | struct wm_adsp_compr *compr = stream->runtime->private_data; |
| 2882 | − struct wm_adsp_compr_buf *buf = compr->buf; | |
| 2883 | 3030 | struct wm_adsp *dsp = compr->dsp; |
| 3031 | + struct wm_adsp_compr_buf *buf; | |
| 2884 | 3032 | int ret = 0; |
| 2885 | 3033 | |
| 2886 | 3034 | adsp_dbg(dsp, "Pointer request\n"); |
| 2887 | 3035 | |
| 2888 | 3036 | mutex_lock(&dsp->pwr_lock); |
| 2889 | 3037 | |
| 3038 | + buf = compr->buf; | |
| 3039 | + | |
| 2890 | 3040 | if (!compr->buf) { |
| 2891 | 3041 | ret = -ENXIO; |
| 2892 | 3042 | goto out; |
| @@ -2909,6 +3059,10 @@ int wm_adsp_compr_pointer(struct snd_compr_stream *stream, · 16 unmodified lines | ||
| 2909 | 3059 | * DSP to inform us once a whole fragment is available. |
| 2910 | 3060 | */ |
| 2911 | 3061 | if (buf->avail < wm_adsp_compr_frag_words(compr)) { |
| 3062 | + ret = wm_adsp_buffer_get_error(buf); | |
| 3063 | + if (ret < 0) | |
| 3064 | + goto out; | |
| 3065 | + | |
| 2912 | 3066 | ret = wm_adsp_buffer_reenable_irq(buf); |
| 2913 | 3067 | if (ret < 0) { |
| 2914 | 3068 | adsp_err(dsp, |
| @@ -92,6 +92,7 @@ extern const struct snd_kcontrol_new wm_adsp_fw_controls[]; · 91 unmodified lines | ||
| 92 | 92 | |
| 93 | 93 | int wm_adsp1_init(struct wm_adsp *dsp); |
| 94 | 94 | int wm_adsp2_init(struct wm_adsp *dsp); |
| 95 | +void wm_adsp2_remove(struct wm_adsp *dsp); | |
| 95 | 96 | int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec); |
| 96 | 97 | int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec); |
| 97 | 98 | int wm_adsp1_event(struct snd_soc_dapm_widget *w, |
| @@ -16,7 +16,11 @@ config SND_EDMA_SOC · 15 unmodified lines | ||
| 16 | 16 | - DRA7xx family |
| 17 | 17 | |
| 18 | 18 | config SND_DAVINCI_SOC_I2S |
| 19 | − tristate | |
| 19 | + tristate "DaVinci Multichannel Buffered Serial Port (McBSP) support" | |
| 20 | + depends on SND_EDMA_SOC | |
| 21 | + help | |
| 22 | + Say Y or M here if you want to have support for McBSP IP found in | |
| 23 | + Texas Instruments DaVinci DA850 SoCs. | |
| 20 | 24 | |
| 21 | 25 | config SND_DAVINCI_SOC_MCASP |
| 22 | 26 | tristate "Multichannel Audio Serial Port (McASP) support" |
| @@ -4,9 +4,15 @@ · 3 unmodified lines | ||
| 4 | 4 | * Author: Vladimir Barinov, <vbarinov@embeddedalley.com> |
| 5 | 5 | * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> |
| 6 | 6 | * |
| 7 | + * DT support (c) 2016 Petr Kulhavy, Barix AG <petr@barix.com> | |
| 8 | + * based on davinci-mcasp.c DT support | |
| 9 | + * | |
| 7 | 10 | * This program is free software; you can redistribute it and/or modify |
| 8 | 11 | * it under the terms of the GNU General Public License version 2 as |
| 9 | 12 | * published by the Free Software Foundation. |
| 13 | + * | |
| 14 | + * TODO: | |
| 15 | + * on DA850 implement HW FIFOs instead of DMA into DXR and DRR registers | |
| 10 | 16 | */ |
| 11 | 17 | |
| 12 | 18 | #include <linux/init.h> |
| @@ -650,13 +656,24 @@ static const struct snd_soc_component_driver davinci_i2s_component = { · 637 unmodified lines | ||
| 650 | 656 | |
| 651 | 657 | static int davinci_i2s_probe(struct platform_device *pdev) |
| 652 | 658 | { |
| 659 | + struct snd_dmaengine_dai_dma_data *dma_data; | |
| 653 | 660 | struct davinci_mcbsp_dev *dev; |
| 654 | 661 | struct resource *mem, *res; |
| 655 | 662 | void __iomem *io_base; |
| 656 | 663 | int *dma; |
| 657 | 664 | int ret; |
| 658 | 665 | |
| 659 | − mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 666 | + mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); | |
| 667 | + if (!mem) { | |
| 668 | + dev_warn(&pdev->dev, | |
| 669 | + "\"mpu\" mem resource not found, using index 0\n"); | |
| 670 | + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 671 | + if (!mem) { | |
| 672 | + dev_err(&pdev->dev, "no mem resource?\n"); | |
| 673 | + return -ENODEV; | |
| 674 | + } | |
| 675 | + } | |
| 676 | + | |
| 660 | 677 | io_base = devm_ioremap_resource(&pdev->dev, mem); |
| 661 | 678 | if (IS_ERR(io_base)) |
| 662 | 679 | return PTR_ERR(io_base); |
| @@ -666,39 +683,43 @@ static int davinci_i2s_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 666 | 683 | if (!dev) |
| 667 | 684 | return -ENOMEM; |
| 668 | 685 | |
| 669 | − dev->clk = clk_get(&pdev->dev, NULL); | |
| 670 | − if (IS_ERR(dev->clk)) | |
| 671 | − return -ENODEV; | |
| 672 | − clk_enable(dev->clk); | |
| 673 | − | |
| 674 | 686 | dev->base = io_base; |
| 675 | 687 | |
| 676 | − dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = | |
| 677 | − (dma_addr_t)(mem->start + DAVINCI_MCBSP_DXR_REG); | |
| 688 | + /* setup DMA, first TX, then RX */ | |
| 689 | + dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; | |
| 690 | + dma_data->addr = (dma_addr_t)(mem->start + DAVINCI_MCBSP_DXR_REG); | |
| 678 | 691 | |
| 679 | − dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = | |
| 680 | − (dma_addr_t)(mem->start + DAVINCI_MCBSP_DRR_REG); | |
| 681 | − | |
| 682 | − /* first TX, then RX */ | |
| 683 | 692 | res = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
| 684 | − if (!res) { | |
| 685 | − dev_err(&pdev->dev, "no DMA resource\n"); | |
| 686 | − ret = -ENXIO; | |
| 687 | − goto err_release_clk; | |
| 693 | + if (res) { | |
| 694 | + dma = &dev->dma_request[SNDRV_PCM_STREAM_PLAYBACK]; | |
| 695 | + *dma = res->start; | |
| 696 | + dma_data->filter_data = dma; | |
| 697 | + } else if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { | |
| 698 | + dma_data->filter_data = "tx"; | |
| 699 | + } else { | |
| 700 | + dev_err(&pdev->dev, "Missing DMA tx resource\n"); | |
| 701 | + return -ENODEV; | |
| 688 | 702 | } |
| 689 | − dma = &dev->dma_request[SNDRV_PCM_STREAM_PLAYBACK]; | |
| 690 | − *dma = res->start; | |
| 691 | − dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = dma; | |
| 703 | + | |
| 704 | + dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]; | |
| 705 | + dma_data->addr = (dma_addr_t)(mem->start + DAVINCI_MCBSP_DRR_REG); | |
| 692 | 706 | |
| 693 | 707 | res = platform_get_resource(pdev, IORESOURCE_DMA, 1); |
| 694 | − if (!res) { | |
| 695 | − dev_err(&pdev->dev, "no DMA resource\n"); | |
| 696 | − ret = -ENXIO; | |
| 697 | − goto err_release_clk; | |
| 708 | + if (res) { | |
| 709 | + dma = &dev->dma_request[SNDRV_PCM_STREAM_CAPTURE]; | |
| 710 | + *dma = res->start; | |
| 711 | + dma_data->filter_data = dma; | |
| 712 | + } else if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { | |
| 713 | + dma_data->filter_data = "rx"; | |
| 714 | + } else { | |
| 715 | + dev_err(&pdev->dev, "Missing DMA rx resource\n"); | |
| 716 | + return -ENODEV; | |
| 698 | 717 | } |
| 699 | − dma = &dev->dma_request[SNDRV_PCM_STREAM_CAPTURE]; | |
| 700 | − *dma = res->start; | |
| 701 | − dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data = dma; | |
| 718 | + | |
| 719 | + dev->clk = clk_get(&pdev->dev, NULL); | |
| 720 | + if (IS_ERR(dev->clk)) | |
| 721 | + return -ENODEV; | |
| 722 | + clk_enable(dev->clk); | |
| 702 | 723 | |
| 703 | 724 | dev->dev = &pdev->dev; |
| 704 | 725 | dev_set_drvdata(&pdev->dev, dev); |
| @@ -737,11 +758,18 @@ static int davinci_i2s_remove(struct platform_device *pdev) · 32 unmodified lines | ||
| 737 | 758 | return 0; |
| 738 | 759 | } |
| 739 | 760 | |
| 761 | +static const struct of_device_id davinci_i2s_match[] = { | |
| 762 | + { .compatible = "ti,da850-mcbsp" }, | |
| 763 | + {}, | |
| 764 | +}; | |
| 765 | +MODULE_DEVICE_TABLE(of, davinci_i2s_match); | |
| 766 | + | |
| 740 | 767 | static struct platform_driver davinci_mcbsp_driver = { |
| 741 | 768 | .probe = davinci_i2s_probe, |
| 742 | 769 | .remove = davinci_i2s_remove, |
| 743 | 770 | .driver = { |
| 744 | 771 | .name = "davinci-mcbsp", |
| 772 | + .of_match_table = of_match_ptr(davinci_i2s_match), | |
| 745 | 773 | }, |
| 746 | 774 | }; |
| 747 | 775 | |
| @@ -489,7 +489,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, · 488 unmodified lines | ||
| 489 | 489 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE); |
| 490 | 490 | |
| 491 | 491 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, |
| 492 | − ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR); | |
| 492 | + ACLKX | AFSX | ACLKR | AHCLKR | AFSR); | |
| 493 | 493 | mcasp->bclk_master = 0; |
| 494 | 494 | break; |
| 495 | 495 | default: |
| @@ -540,21 +540,19 @@ out: · 44 unmodified lines | ||
| 540 | 540 | return ret; |
| 541 | 541 | } |
| 542 | 542 | |
| 543 | −static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, | |
| 543 | +static int __davinci_mcasp_set_clkdiv(struct davinci_mcasp *mcasp, int div_id, | |
| 544 | 544 | int div, bool explicit) |
| 545 | 545 | { |
| 546 | − struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); | |
| 547 | − | |
| 548 | 546 | pm_runtime_get_sync(mcasp->dev); |
| 549 | 547 | switch (div_id) { |
| 550 | − case 0: /* MCLK divider */ | |
| 548 | + case MCASP_CLKDIV_AUXCLK: /* MCLK divider */ | |
| 551 | 549 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, |
| 552 | 550 | AHCLKXDIV(div - 1), AHCLKXDIV_MASK); |
| 553 | 551 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, |
| 554 | 552 | AHCLKRDIV(div - 1), AHCLKRDIV_MASK); |
| 555 | 553 | break; |
| 556 | 554 | |
| 557 | − case 1: /* BCLK divider */ | |
| 555 | + case MCASP_CLKDIV_BCLK: /* BCLK divider */ | |
| 558 | 556 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, |
| 559 | 557 | ACLKXDIV(div - 1), ACLKXDIV_MASK); |
| 560 | 558 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, |
| @@ -563,7 +561,8 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, · 2 unmodified lines | ||
| 563 | 561 | mcasp->bclk_div = div; |
| 564 | 562 | break; |
| 565 | 563 | |
| 566 | − case 2: /* | |
| 564 | + case MCASP_CLKDIV_BCLK_FS_RATIO: | |
| 565 | + /* | |
| 567 | 566 | * BCLK/LRCLK ratio descries how many bit-clock cycles |
| 568 | 567 | * fit into one frame. The clock ratio is given for a |
| 569 | 568 | * full period of data (for I2S format both left and |
| @@ -591,7 +590,9 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, · 21 unmodified lines | ||
| 591 | 590 | static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, |
| 592 | 591 | int div) |
| 593 | 592 | { |
| 594 | − return __davinci_mcasp_set_clkdiv(dai, div_id, div, 1); | |
| 593 | + struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); | |
| 594 | + | |
| 595 | + return __davinci_mcasp_set_clkdiv(mcasp, div_id, div, 1); | |
| 595 | 596 | } |
| 596 | 597 | |
| 597 | 598 | static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, |
| @@ -999,27 +1000,53 @@ static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp, · 401 unmodified lines | ||
| 999 | 1000 | } |
| 1000 | 1001 | |
| 1001 | 1002 | static int davinci_mcasp_calc_clk_div(struct davinci_mcasp *mcasp, |
| 1002 | − unsigned int bclk_freq, | |
| 1003 | − int *error_ppm) | |
| 1003 | + unsigned int bclk_freq, bool set) | |
| 1004 | 1004 | { |
| 1005 | − int div = mcasp->sysclk_freq / bclk_freq; | |
| 1006 | − int rem = mcasp->sysclk_freq % bclk_freq; | |
| 1005 | + int error_ppm; | |
| 1006 | + unsigned int sysclk_freq = mcasp->sysclk_freq; | |
| 1007 | + u32 reg = mcasp_get_reg(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG); | |
| 1008 | + int div = sysclk_freq / bclk_freq; | |
| 1009 | + int rem = sysclk_freq % bclk_freq; | |
| 1010 | + int aux_div = 1; | |
| 1011 | + | |
| 1012 | + if (div > (ACLKXDIV_MASK + 1)) { | |
| 1013 | + if (reg & AHCLKXE) { | |
| 1014 | + aux_div = div / (ACLKXDIV_MASK + 1); | |
| 1015 | + if (div % (ACLKXDIV_MASK + 1)) | |
| 1016 | + aux_div++; | |
| 1017 | + | |
| 1018 | + sysclk_freq /= aux_div; | |
| 1019 | + div = sysclk_freq / bclk_freq; | |
| 1020 | + rem = sysclk_freq % bclk_freq; | |
| 1021 | + } else if (set) { | |
| 1022 | + dev_warn(mcasp->dev, "Too fast reference clock (%u)\n", | |
| 1023 | + sysclk_freq); | |
| 1024 | + } | |
| 1025 | + } | |
| 1007 | 1026 | |
| 1008 | 1027 | if (rem != 0) { |
| 1009 | 1028 | if (div == 0 || |
| 1010 | − ((mcasp->sysclk_freq / div) - bclk_freq) > | |
| 1011 | − (bclk_freq - (mcasp->sysclk_freq / (div+1)))) { | |
| 1029 | + ((sysclk_freq / div) - bclk_freq) > | |
| 1030 | + (bclk_freq - (sysclk_freq / (div+1)))) { | |
| 1012 | 1031 | div++; |
| 1013 | 1032 | rem = rem - bclk_freq; |
| 1014 | 1033 | } |
| 1015 | 1034 | } |
| 1016 | − if (error_ppm) | |
| 1017 | − *error_ppm = | |
| 1018 | − (div*1000000 + (int)div64_long(1000000LL*rem, | |
| 1019 | − (int)bclk_freq)) | |
| 1020 | − /div - 1000000; | |
| 1035 | + error_ppm = (div*1000000 + (int)div64_long(1000000LL*rem, | |
| 1036 | + (int)bclk_freq)) / div - 1000000; | |
| 1037 | + | |
| 1038 | + if (set) { | |
| 1039 | + if (error_ppm) | |
| 1040 | + dev_info(mcasp->dev, "Sample-rate is off by %d PPM\n", | |
| 1041 | + error_ppm); | |
| 1042 | + | |
| 1043 | + __davinci_mcasp_set_clkdiv(mcasp, MCASP_CLKDIV_BCLK, div, 0); | |
| 1044 | + if (reg & AHCLKXE) | |
| 1045 | + __davinci_mcasp_set_clkdiv(mcasp, MCASP_CLKDIV_AUXCLK, | |
| 1046 | + aux_div, 0); | |
| 1047 | + } | |
| 1021 | 1048 | |
| 1022 | − return div; | |
| 1049 | + return error_ppm; | |
| 1023 | 1050 | } |
| 1024 | 1051 | |
| 1025 | 1052 | static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, |
| @@ -1044,18 +1071,11 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, · 18 unmodified lines | ||
| 1044 | 1071 | int slots = mcasp->tdm_slots; |
| 1045 | 1072 | int rate = params_rate(params); |
| 1046 | 1073 | int sbits = params_width(params); |
| 1047 | − int ppm, div; | |
| 1048 | 1074 | |
| 1049 | 1075 | if (mcasp->slot_width) |
| 1050 | 1076 | sbits = mcasp->slot_width; |
| 1051 | 1077 | |
| 1052 | − div = davinci_mcasp_calc_clk_div(mcasp, rate*sbits*slots, | |
| 1053 | − &ppm); | |
| 1054 | − if (ppm) | |
| 1055 | − dev_info(mcasp->dev, "Sample-rate is off by %d PPM\n", | |
| 1056 | − ppm); | |
| 1057 | − | |
| 1058 | − __davinci_mcasp_set_clkdiv(cpu_dai, 1, div, 0); | |
| 1078 | + davinci_mcasp_calc_clk_div(mcasp, rate * sbits * slots, true); | |
| 1059 | 1079 | } |
| 1060 | 1080 | |
| 1061 | 1081 | ret = mcasp_common_hw_param(mcasp, substream->stream, |
| @@ -1166,7 +1186,8 @@ static int davinci_mcasp_hw_rule_rate(struct snd_pcm_hw_params *params, · 104 unmodified lines | ||
| 1166 | 1186 | davinci_mcasp_dai_rates[i]; |
| 1167 | 1187 | int ppm; |
| 1168 | 1188 | |
| 1169 | − davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm); | |
| 1189 | + ppm = davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, | |
| 1190 | + false); | |
| 1170 | 1191 | if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) { |
| 1171 | 1192 | if (range.empty) { |
| 1172 | 1193 | range.min = davinci_mcasp_dai_rates[i]; |
| @@ -1205,8 +1226,9 @@ static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params, · 32 unmodified lines | ||
| 1205 | 1226 | if (rd->mcasp->slot_width) |
| 1206 | 1227 | sbits = rd->mcasp->slot_width; |
| 1207 | 1228 | |
| 1208 | − davinci_mcasp_calc_clk_div(rd->mcasp, sbits*slots*rate, | |
| 1209 | − &ppm); | |
| 1229 | + ppm = davinci_mcasp_calc_clk_div(rd->mcasp, | |
| 1230 | + sbits * slots * rate, | |
| 1231 | + false); | |
| 1210 | 1232 | if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) { |
| 1211 | 1233 | snd_mask_set(&nfmt, i); |
| 1212 | 1234 | count++; |
| @@ -1230,11 +1252,15 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, · 17 unmodified lines | ||
| 1230 | 1252 | int i, dir; |
| 1231 | 1253 | int tdm_slots = mcasp->tdm_slots; |
| 1232 | 1254 | |
| 1233 | − if (mcasp->tdm_mask[substream->stream]) | |
| 1234 | − tdm_slots = hweight32(mcasp->tdm_mask[substream->stream]); | |
| 1255 | + /* Do not allow more then one stream per direction */ | |
| 1256 | + if (mcasp->substreams[substream->stream]) | |
| 1257 | + return -EBUSY; | |
| 1235 | 1258 | |
| 1236 | 1259 | mcasp->substreams[substream->stream] = substream; |
| 1237 | 1260 | |
| 1261 | + if (mcasp->tdm_mask[substream->stream]) | |
| 1262 | + tdm_slots = hweight32(mcasp->tdm_mask[substream->stream]); | |
| 1263 | + | |
| 1238 | 1264 | if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) |
| 1239 | 1265 | return 0; |
| 1240 | 1266 | |
| @@ -306,4 +306,9 @@ · 305 unmodified lines | ||
| 306 | 306 | #define NUMEVT(x) (((x) & 0xFF) << 8) |
| 307 | 307 | #define NUMDMA_MASK (0xFF) |
| 308 | 308 | |
| 309 | +/* clock divider IDs */ | |
| 310 | +#define MCASP_CLKDIV_AUXCLK 0 /* HCLK divider from AUXCLK */ | |
| 311 | +#define MCASP_CLKDIV_BCLK 1 /* BCLK divider from HCLK */ | |
| 312 | +#define MCASP_CLKDIV_BCLK_FS_RATIO 2 /* to set BCLK FS ration */ | |
| 313 | + | |
| 309 | 314 | #endif /* DAVINCI_MCASP_H */ |
| @@ -100,6 +100,7 @@ struct dw_i2s_dev { · 99 unmodified lines | ||
| 100 | 100 | struct device *dev; |
| 101 | 101 | u32 ccr; |
| 102 | 102 | u32 xfer_resolution; |
| 103 | + u32 fifo_th; | |
| 103 | 104 | |
| 104 | 105 | /* data related to DMA transfers b/w i2s and DMAC */ |
| 105 | 106 | union dw_i2s_snd_dma_data play_dma_data; |
| @@ -147,17 +148,18 @@ static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream) · 41 unmodified lines | ||
| 147 | 148 | static void i2s_start(struct dw_i2s_dev *dev, |
| 148 | 149 | struct snd_pcm_substream *substream) |
| 149 | 150 | { |
| 151 | + struct i2s_clk_config_data *config = &dev->config; | |
| 150 | 152 | u32 i, irq; |
| 151 | 153 | i2s_write_reg(dev->i2s_base, IER, 1); |
| 152 | 154 | |
| 153 | 155 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 154 | − for (i = 0; i < 4; i++) { | |
| 156 | + for (i = 0; i < (config->chan_nr / 2); i++) { | |
| 155 | 157 | irq = i2s_read_reg(dev->i2s_base, IMR(i)); |
| 156 | 158 | i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x30); |
| 157 | 159 | } |
| 158 | 160 | i2s_write_reg(dev->i2s_base, ITER, 1); |
| 159 | 161 | } else { |
| 160 | − for (i = 0; i < 4; i++) { | |
| 162 | + for (i = 0; i < (config->chan_nr / 2); i++) { | |
| 161 | 163 | irq = i2s_read_reg(dev->i2s_base, IMR(i)); |
| 162 | 164 | i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x03); |
| 163 | 165 | } |
| @@ -231,14 +233,16 @@ static void dw_i2s_config(struct dw_i2s_dev *dev, int stream) · 67 unmodified lines | ||
| 231 | 233 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 232 | 234 | i2s_write_reg(dev->i2s_base, TCR(ch_reg), |
| 233 | 235 | dev->xfer_resolution); |
| 234 | − i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02); | |
| 236 | + i2s_write_reg(dev->i2s_base, TFCR(ch_reg), | |
| 237 | + dev->fifo_th - 1); | |
| 235 | 238 | irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg)); |
| 236 | 239 | i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30); |
| 237 | 240 | i2s_write_reg(dev->i2s_base, TER(ch_reg), 1); |
| 238 | 241 | } else { |
| 239 | 242 | i2s_write_reg(dev->i2s_base, RCR(ch_reg), |
| 240 | 243 | dev->xfer_resolution); |
| 241 | − i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07); | |
| 244 | + i2s_write_reg(dev->i2s_base, RFCR(ch_reg), | |
| 245 | + dev->fifo_th - 1); | |
| 242 | 246 | irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg)); |
| 243 | 247 | i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03); |
| 244 | 248 | i2s_write_reg(dev->i2s_base, RER(ch_reg), 1); |
| @@ -498,6 +502,7 @@ static int dw_configure_dai(struct dw_i2s_dev *dev, · 253 unmodified lines | ||
| 498 | 502 | */ |
| 499 | 503 | u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1); |
| 500 | 504 | u32 comp2 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp2); |
| 505 | + u32 fifo_depth = 1 << (1 + COMP1_FIFO_DEPTH_GLOBAL(comp1)); | |
| 501 | 506 | u32 idx; |
| 502 | 507 | |
| 503 | 508 | if (dev->capability & DWC_I2S_RECORD && |
| @@ -536,6 +541,7 @@ static int dw_configure_dai(struct dw_i2s_dev *dev, · 32 unmodified lines | ||
| 536 | 541 | dev->capability |= DW_I2S_SLAVE; |
| 537 | 542 | } |
| 538 | 543 | |
| 544 | + dev->fifo_th = fifo_depth / 2; | |
| 539 | 545 | return 0; |
| 540 | 546 | } |
| 541 | 547 | |
| @@ -21,6 +21,8 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <sound/core.h> |
| 22 | 22 | #include <sound/dmaengine_pcm.h> |
| 23 | 23 | #include <sound/pcm_params.h> |
| 24 | +#include <linux/mfd/syscon.h> | |
| 25 | +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> | |
| 24 | 26 | |
| 25 | 27 | #include "fsl_sai.h" |
| 26 | 28 | #include "imx-pcm.h" |
| @@ -786,10 +788,12 @@ static int fsl_sai_probe(struct platform_device *pdev) · 759 unmodified lines | ||
| 786 | 788 | { |
| 787 | 789 | struct device_node *np = pdev->dev.of_node; |
| 788 | 790 | struct fsl_sai *sai; |
| 791 | + struct regmap *gpr; | |
| 789 | 792 | struct resource *res; |
| 790 | 793 | void __iomem *base; |
| 791 | 794 | char tmp[8]; |
| 792 | 795 | int irq, ret, i; |
| 796 | + int index; | |
| 793 | 797 | |
| 794 | 798 | sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); |
| 795 | 799 | if (!sai) |
| @@ -797,7 +801,8 @@ static int fsl_sai_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 797 | 801 | |
| 798 | 802 | sai->pdev = pdev; |
| 799 | 803 | |
| 800 | − if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx6sx-sai")) | |
| 804 | + if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx6sx-sai") || | |
| 805 | + of_device_is_compatible(pdev->dev.of_node, "fsl,imx6ul-sai")) | |
| 801 | 806 | sai->sai_on_imx = true; |
| 802 | 807 | |
| 803 | 808 | sai->is_lsb_first = of_property_read_bool(np, "lsb-first"); |
| @@ -877,6 +882,22 @@ static int fsl_sai_probe(struct platform_device *pdev) · 73 unmodified lines | ||
| 877 | 882 | fsl_sai_dai.symmetric_samplebits = 0; |
| 878 | 883 | } |
| 879 | 884 | |
| 885 | + if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) && | |
| 886 | + of_device_is_compatible(pdev->dev.of_node, "fsl,imx6ul-sai")) { | |
| 887 | + gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr"); | |
| 888 | + if (IS_ERR(gpr)) { | |
| 889 | + dev_err(&pdev->dev, "cannot find iomuxc registers\n"); | |
| 890 | + return PTR_ERR(gpr); | |
| 891 | + } | |
| 892 | + | |
| 893 | + index = of_alias_get_id(np, "sai"); | |
| 894 | + if (index < 0) | |
| 895 | + return index; | |
| 896 | + | |
| 897 | + regmap_update_bits(gpr, IOMUXC_GPR1, MCLK_DIR(index), | |
| 898 | + MCLK_DIR(index)); | |
| 899 | + } | |
| 900 | + | |
| 880 | 901 | sai->dma_params_rx.addr = res->start + FSL_SAI_RDR; |
| 881 | 902 | sai->dma_params_tx.addr = res->start + FSL_SAI_TDR; |
| 882 | 903 | sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; |
| @@ -898,6 +919,7 @@ static int fsl_sai_probe(struct platform_device *pdev) · 15 unmodified lines | ||
| 898 | 919 | static const struct of_device_id fsl_sai_ids[] = { |
| 899 | 920 | { .compatible = "fsl,vf610-sai", }, |
| 900 | 921 | { .compatible = "fsl,imx6sx-sai", }, |
| 922 | + { .compatible = "fsl,imx6ul-sai", }, | |
| 901 | 923 | { /* sentinel */ } |
| 902 | 924 | }; |
| 903 | 925 | MODULE_DEVICE_TABLE(of, fsl_sai_ids); |
| @@ -137,6 +137,7 @@ static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg) · 136 unmodified lines | ||
| 137 | 137 | case CCSR_SSI_SACDAT: |
| 138 | 138 | case CCSR_SSI_SATAG: |
| 139 | 139 | case CCSR_SSI_SACCST: |
| 140 | + case CCSR_SSI_SOR: | |
| 140 | 141 | return true; |
| 141 | 142 | default: |
| 142 | 143 | return false; |
| @@ -261,6 +262,7 @@ struct fsl_ssi_private { · 118 unmodified lines | ||
| 261 | 262 | struct fsl_ssi_dbg dbg_stats; |
| 262 | 263 | |
| 263 | 264 | const struct fsl_ssi_soc_data *soc; |
| 265 | + struct device *dev; | |
| 264 | 266 | }; |
| 265 | 267 | |
| 266 | 268 | /* |
| @@ -399,6 +401,26 @@ static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private, · 132 unmodified lines | ||
| 399 | 401 | } |
| 400 | 402 | } |
| 401 | 403 | |
| 404 | +/* | |
| 405 | + * Clear RX or TX FIFO to remove samples from the previous | |
| 406 | + * stream session which may be still present in the FIFO and | |
| 407 | + * may introduce bad samples and/or channel slipping. | |
| 408 | + * | |
| 409 | + * Note: The SOR is not documented in recent IMX datasheet, but | |
| 410 | + * is described in IMX51 reference manual at section 56.3.3.15. | |
| 411 | + */ | |
| 412 | +static void fsl_ssi_fifo_clear(struct fsl_ssi_private *ssi_private, | |
| 413 | + bool is_rx) | |
| 414 | +{ | |
| 415 | + if (is_rx) { | |
| 416 | + regmap_update_bits(ssi_private->regs, CCSR_SSI_SOR, | |
| 417 | + CCSR_SSI_SOR_RX_CLR, CCSR_SSI_SOR_RX_CLR); | |
| 418 | + } else { | |
| 419 | + regmap_update_bits(ssi_private->regs, CCSR_SSI_SOR, | |
| 420 | + CCSR_SSI_SOR_TX_CLR, CCSR_SSI_SOR_TX_CLR); | |
| 421 | + } | |
| 422 | +} | |
| 423 | + | |
| 402 | 424 | /* |
| 403 | 425 | * Calculate the bits that have to be disabled for the current stream that is |
| 404 | 426 | * getting disabled. This keeps the bits enabled that are necessary for the |
| @@ -474,9 +496,11 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, · 69 unmodified lines | ||
| 474 | 496 | * (online configuration) |
| 475 | 497 | */ |
| 476 | 498 | if (enable) { |
| 477 | − regmap_update_bits(regs, CCSR_SSI_SIER, vals->sier, vals->sier); | |
| 499 | + fsl_ssi_fifo_clear(ssi_private, vals->scr & CCSR_SSI_SCR_RE); | |
| 500 | + | |
| 478 | 501 | regmap_update_bits(regs, CCSR_SSI_SRCR, vals->srcr, vals->srcr); |
| 479 | 502 | regmap_update_bits(regs, CCSR_SSI_STCR, vals->stcr, vals->stcr); |
| 503 | + regmap_update_bits(regs, CCSR_SSI_SIER, vals->sier, vals->sier); | |
| 480 | 504 | } else { |
| 481 | 505 | u32 sier; |
| 482 | 506 | u32 srcr; |
| @@ -506,8 +530,40 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, · 23 unmodified lines | ||
| 506 | 530 | |
| 507 | 531 | config_done: |
| 508 | 532 | /* Enabling of subunits is done after configuration */ |
| 509 | − if (enable) | |
| 533 | + if (enable) { | |
| 534 | + if (ssi_private->use_dma && (vals->scr & CCSR_SSI_SCR_TE)) { | |
| 535 | + /* | |
| 536 | + * Be sure the Tx FIFO is filled when TE is set. | |
| 537 | + * Otherwise, there are some chances to start the | |
| 538 | + * playback with some void samples inserted first, | |
| 539 | + * generating a channel slip. | |
| 540 | + * | |
| 541 | + * First, SSIEN must be set, to let the FIFO be filled. | |
| 542 | + * | |
| 543 | + * Notes: | |
| 544 | + * - Limit this fix to the DMA case until FIQ cases can | |
| 545 | + * be tested. | |
| 546 | + * - Limit the length of the busy loop to not lock the | |
| 547 | + * system too long, even if 1-2 loops are sufficient | |
| 548 | + * in general. | |
| 549 | + */ | |
| 550 | + int i; | |
| 551 | + int max_loop = 100; | |
| 552 | + regmap_update_bits(regs, CCSR_SSI_SCR, | |
| 553 | + CCSR_SSI_SCR_SSIEN, CCSR_SSI_SCR_SSIEN); | |
| 554 | + for (i = 0; i < max_loop; i++) { | |
| 555 | + u32 sfcsr; | |
| 556 | + regmap_read(regs, CCSR_SSI_SFCSR, &sfcsr); | |
| 557 | + if (CCSR_SSI_SFCSR_TFCNT0(sfcsr)) | |
| 558 | + break; | |
| 559 | + } | |
| 560 | + if (i == max_loop) { | |
| 561 | + dev_err(ssi_private->dev, | |
| 562 | + "Timeout waiting TX FIFO filling\n"); | |
| 563 | + } | |
| 564 | + } | |
| 510 | 565 | regmap_update_bits(regs, CCSR_SSI_SCR, vals->scr, vals->scr); |
| 566 | + } | |
| 511 | 567 | } |
| 512 | 568 | |
| 513 | 569 | |
| @@ -670,6 +726,15 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, · 156 unmodified lines | ||
| 670 | 726 | if (IS_ERR(ssi_private->baudclk)) |
| 671 | 727 | return -EINVAL; |
| 672 | 728 | |
| 729 | + /* | |
| 730 | + * Hardware limitation: The bclk rate must be | |
| 731 | + * never greater than 1/5 IPG clock rate | |
| 732 | + */ | |
| 733 | + if (freq * 5 > clk_get_rate(ssi_private->clk)) { | |
| 734 | + dev_err(cpu_dai->dev, "bitclk > ipgclk/5\n"); | |
| 735 | + return -EINVAL; | |
| 736 | + } | |
| 737 | + | |
| 673 | 738 | baudclk_is_used = ssi_private->baudclk_streams & ~(BIT(substream->stream)); |
| 674 | 739 | |
| 675 | 740 | /* It should be already enough to divide clock by setting pm alone */ |
| @@ -686,13 +751,6 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, · 10 unmodified lines | ||
| 686 | 751 | else |
| 687 | 752 | clkrate = clk_round_rate(ssi_private->baudclk, tmprate); |
| 688 | 753 | |
| 689 | − /* | |
| 690 | − * Hardware limitation: The bclk rate must be | |
| 691 | − * never greater than 1/5 IPG clock rate | |
| 692 | − */ | |
| 693 | − if (clkrate * 5 > clk_get_rate(ssi_private->clk)) | |
| 694 | − continue; | |
| 695 | − | |
| 696 | 754 | clkrate /= factor; |
| 697 | 755 | afreq = clkrate / (i + 1); |
| 698 | 756 | |
| @@ -1158,14 +1216,14 @@ static struct snd_soc_dai_driver fsl_ssi_dai_template = { · 459 unmodified lines | ||
| 1158 | 1216 | .playback = { |
| 1159 | 1217 | .stream_name = "CPU-Playback", |
| 1160 | 1218 | .channels_min = 1, |
| 1161 | − .channels_max = 2, | |
| 1219 | + .channels_max = 32, | |
| 1162 | 1220 | .rates = FSLSSI_I2S_RATES, |
| 1163 | 1221 | .formats = FSLSSI_I2S_FORMATS, |
| 1164 | 1222 | }, |
| 1165 | 1223 | .capture = { |
| 1166 | 1224 | .stream_name = "CPU-Capture", |
| 1167 | 1225 | .channels_min = 1, |
| 1168 | − .channels_max = 2, | |
| 1226 | + .channels_max = 32, | |
| 1169 | 1227 | .rates = FSLSSI_I2S_RATES, |
| 1170 | 1228 | .formats = FSLSSI_I2S_FORMATS, |
| 1171 | 1229 | }, |
| @@ -1402,6 +1460,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) · 230 unmodified lines | ||
| 1402 | 1460 | } |
| 1403 | 1461 | |
| 1404 | 1462 | ssi_private->soc = of_id->data; |
| 1463 | + ssi_private->dev = &pdev->dev; | |
| 1405 | 1464 | |
| 1406 | 1465 | sprop = of_get_property(np, "fsl,mode", NULL); |
| 1407 | 1466 | if (sprop) { |
| @@ -220,7 +220,7 @@ static int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, · 219 unmodified lines | ||
| 220 | 220 | ret = dma_mmap_wc(substream->pcm->card->dev, vma, runtime->dma_area, |
| 221 | 221 | runtime->dma_addr, runtime->dma_bytes); |
| 222 | 222 | |
| 223 | − pr_debug("%s: ret: %d %p %pad 0x%08x\n", __func__, ret, | |
| 223 | + pr_debug("%s: ret: %d %p %pad 0x%08zx\n", __func__, ret, | |
| 224 | 224 | runtime->dma_area, |
| 225 | 225 | &runtime->dma_addr, |
| 226 | 226 | runtime->dma_bytes); |
| @@ -58,6 +58,21 @@ config SND_SOC_INTEL_HASWELL_MACH · 57 unmodified lines | ||
| 58 | 58 | Say Y if you have such a device |
| 59 | 59 | If unsure select "N". |
| 60 | 60 | |
| 61 | +config SND_SOC_INTEL_BXT_RT298_MACH | |
| 62 | + tristate "ASoC Audio driver for Broxton with RT298 I2S mode" | |
| 63 | + depends on X86 && ACPI && I2C | |
| 64 | + select SND_SOC_INTEL_SST | |
| 65 | + select SND_SOC_INTEL_SKYLAKE | |
| 66 | + select SND_SOC_RT298 | |
| 67 | + select SND_SOC_DMIC | |
| 68 | + select SND_SOC_HDAC_HDMI | |
| 69 | + select SND_HDA_DSP_LOADER | |
| 70 | + help | |
| 71 | + This adds support for ASoC machine driver for Broxton platforms | |
| 72 | + with RT286 I2S audio codec. | |
| 73 | + Say Y if you have such a device | |
| 74 | + If unsure select "N". | |
| 75 | + | |
| 61 | 76 | config SND_SOC_INTEL_BYT_RT5640_MACH |
| 62 | 77 | tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec" |
| 63 | 78 | depends on X86_INTEL_LPSS && I2C |
| @@ -162,6 +177,7 @@ config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH · 98 unmodified lines | ||
| 162 | 177 | config SND_SOC_INTEL_SKYLAKE |
| 163 | 178 | tristate |
| 164 | 179 | select SND_HDA_EXT_CORE |
| 180 | + select SND_HDA_DSP_LOADER | |
| 165 | 181 | select SND_SOC_TOPOLOGY |
| 166 | 182 | select SND_SOC_INTEL_SST |
| 167 | 183 | |
| @@ -195,7 +195,7 @@ static int sst_check_and_send_slot_map(struct sst_data *drv, struct snd_kcontrol · 194 unmodified lines | ||
| 195 | 195 | |
| 196 | 196 | if (e->w && e->w->power) |
| 197 | 197 | ret = sst_send_slot_map(drv); |
| 198 | − else | |
| 198 | + else if (!e->w) | |
| 199 | 199 | dev_err(&drv->pdev->dev, "Slot control: %s doesn't have DAPM widget!!!\n", |
| 200 | 200 | kcontrol->id.name); |
| 201 | 201 | return ret; |
| @@ -2,6 +2,7 @@ snd-soc-sst-haswell-objs := haswell.o · 1 unmodified line | ||
| 2 | 2 | snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o |
| 3 | 3 | snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o |
| 4 | 4 | snd-soc-sst-broadwell-objs := broadwell.o |
| 5 | +snd-soc-sst-bxt-rt298-objs := bxt_rt298.o | |
| 5 | 6 | snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o |
| 6 | 7 | snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o |
| 7 | 8 | snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o |
| @@ -14,6 +15,7 @@ snd-soc-skl_nau88l25_ssm4567-objs := skl_nau88l25_ssm4567.o · 6 unmodified lines | ||
| 14 | 15 | obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o |
| 15 | 16 | obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o |
| 16 | 17 | obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o |
| 18 | +obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o | |
| 17 | 19 | obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o |
| 18 | 20 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o |
| 19 | 21 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o |
| @@ -201,7 +201,7 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = { · 200 unmodified lines | ||
| 201 | 201 | { |
| 202 | 202 | /* SSP0 - Codec */ |
| 203 | 203 | .name = "Codec", |
| 204 | − .be_id = 0, | |
| 204 | + .id = 0, | |
| 205 | 205 | .cpu_dai_name = "snd-soc-dummy-dai", |
| 206 | 206 | .platform_name = "snd-soc-dummy", |
| 207 | 207 | .no_pcm = 1, |
| @@ -0,0 +1,353 @@ | ||
| 1 | +/* | |
| 2 | + * Intel Broxton-P I2S Machine Driver | |
| 3 | + * | |
| 4 | + * Copyright (C) 2014-2016, Intel Corporation. All rights reserved. | |
| 5 | + * | |
| 6 | + * Modified from: | |
| 7 | + * Intel Skylake I2S Machine driver | |
| 8 | + * | |
| 9 | + * This program is free software; you can redistribute it and/or | |
| 10 | + * modify it under the terms of the GNU General Public License version | |
| 11 | + * 2 as published by the Free Software Foundation. | |
| 12 | + * | |
| 13 | + * This program is distributed in the hope that it will be useful, | |
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 16 | + * GNU General Public License for more details. | |
| 17 | + */ | |
| 18 | + | |
| 19 | +#include <linux/module.h> | |
| 20 | +#include <linux/platform_device.h> | |
| 21 | +#include <sound/core.h> | |
| 22 | +#include <sound/pcm.h> | |
| 23 | +#include <sound/soc.h> | |
| 24 | +#include <sound/jack.h> | |
| 25 | +#include <sound/pcm_params.h> | |
| 26 | +#include "../../codecs/hdac_hdmi.h" | |
| 27 | +#include "../../codecs/rt298.h" | |
| 28 | + | |
| 29 | +static struct snd_soc_jack broxton_headset; | |
| 30 | +/* Headset jack detection DAPM pins */ | |
| 31 | + | |
| 32 | +enum { | |
| 33 | + BXT_DPCM_AUDIO_PB = 0, | |
| 34 | + BXT_DPCM_AUDIO_CP, | |
| 35 | + BXT_DPCM_AUDIO_REF_CP, | |
| 36 | + BXT_DPCM_AUDIO_HDMI1_PB, | |
| 37 | + BXT_DPCM_AUDIO_HDMI2_PB, | |
| 38 | + BXT_DPCM_AUDIO_HDMI3_PB, | |
| 39 | +}; | |
| 40 | + | |
| 41 | +static struct snd_soc_jack_pin broxton_headset_pins[] = { | |
| 42 | + { | |
| 43 | + .pin = "Mic Jack", | |
| 44 | + .mask = SND_JACK_MICROPHONE, | |
| 45 | + }, | |
| 46 | + { | |
| 47 | + .pin = "Headphone Jack", | |
| 48 | + .mask = SND_JACK_HEADPHONE, | |
| 49 | + }, | |
| 50 | +}; | |
| 51 | + | |
| 52 | +static const struct snd_kcontrol_new broxton_controls[] = { | |
| 53 | + SOC_DAPM_PIN_SWITCH("Speaker"), | |
| 54 | + SOC_DAPM_PIN_SWITCH("Headphone Jack"), | |
| 55 | + SOC_DAPM_PIN_SWITCH("Mic Jack"), | |
| 56 | +}; | |
| 57 | + | |
| 58 | +static const struct snd_soc_dapm_widget broxton_widgets[] = { | |
| 59 | + SND_SOC_DAPM_HP("Headphone Jack", NULL), | |
| 60 | + SND_SOC_DAPM_SPK("Speaker", NULL), | |
| 61 | + SND_SOC_DAPM_MIC("Mic Jack", NULL), | |
| 62 | + SND_SOC_DAPM_MIC("DMIC2", NULL), | |
| 63 | + SND_SOC_DAPM_MIC("SoC DMIC", NULL), | |
| 64 | + SND_SOC_DAPM_SPK("HDMI1", NULL), | |
| 65 | + SND_SOC_DAPM_SPK("HDMI2", NULL), | |
| 66 | + SND_SOC_DAPM_SPK("HDMI3", NULL), | |
| 67 | +}; | |
| 68 | + | |
| 69 | +static const struct snd_soc_dapm_route broxton_rt298_map[] = { | |
| 70 | + /* speaker */ | |
| 71 | + {"Speaker", NULL, "SPOR"}, | |
| 72 | + {"Speaker", NULL, "SPOL"}, | |
| 73 | + | |
| 74 | + /* HP jack connectors - unknown if we have jack detect */ | |
| 75 | + {"Headphone Jack", NULL, "HPO Pin"}, | |
| 76 | + | |
| 77 | + /* other jacks */ | |
| 78 | + {"MIC1", NULL, "Mic Jack"}, | |
| 79 | + | |
| 80 | + /* digital mics */ | |
| 81 | + {"DMIC1 Pin", NULL, "DMIC2"}, | |
| 82 | + {"DMic", NULL, "SoC DMIC"}, | |
| 83 | + | |
| 84 | + {"HDMI1", NULL, "hif5 Output"}, | |
| 85 | + {"HDMI2", NULL, "hif6 Output"}, | |
| 86 | + {"HDMI3", NULL, "hif7 Output"}, | |
| 87 | + | |
| 88 | + /* CODEC BE connections */ | |
| 89 | + { "AIF1 Playback", NULL, "ssp5 Tx"}, | |
| 90 | + { "ssp5 Tx", NULL, "codec0_out"}, | |
| 91 | + | |
| 92 | + { "codec0_in", NULL, "ssp5 Rx" }, | |
| 93 | + { "ssp5 Rx", NULL, "AIF1 Capture" }, | |
| 94 | + | |
| 95 | + { "dmic01_hifi", NULL, "DMIC01 Rx" }, | |
| 96 | + { "DMIC01 Rx", NULL, "Capture" }, | |
| 97 | + | |
| 98 | + { "hifi3", NULL, "iDisp3 Tx"}, | |
| 99 | + { "iDisp3 Tx", NULL, "iDisp3_out"}, | |
| 100 | + { "hifi2", NULL, "iDisp2 Tx"}, | |
| 101 | + { "iDisp2 Tx", NULL, "iDisp2_out"}, | |
| 102 | + { "hifi1", NULL, "iDisp1 Tx"}, | |
| 103 | + { "iDisp1 Tx", NULL, "iDisp1_out"}, | |
| 104 | + | |
| 105 | +}; | |
| 106 | + | |
| 107 | +static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd) | |
| 108 | +{ | |
| 109 | + struct snd_soc_codec *codec = rtd->codec; | |
| 110 | + int ret = 0; | |
| 111 | + | |
| 112 | + ret = snd_soc_card_jack_new(rtd->card, "Headset", | |
| 113 | + SND_JACK_HEADSET | SND_JACK_BTN_0, | |
| 114 | + &broxton_headset, | |
| 115 | + broxton_headset_pins, ARRAY_SIZE(broxton_headset_pins)); | |
| 116 | + | |
| 117 | + if (ret) | |
| 118 | + return ret; | |
| 119 | + | |
| 120 | + rt298_mic_detect(codec, &broxton_headset); | |
| 121 | + return 0; | |
| 122 | +} | |
| 123 | + | |
| 124 | +static int broxton_hdmi_init(struct snd_soc_pcm_runtime *rtd) | |
| 125 | +{ | |
| 126 | + struct snd_soc_dai *dai = rtd->codec_dai; | |
| 127 | + | |
| 128 | + return hdac_hdmi_jack_init(dai, BXT_DPCM_AUDIO_HDMI1_PB + dai->id); | |
| 129 | +} | |
| 130 | + | |
| 131 | +static int broxton_ssp5_fixup(struct snd_soc_pcm_runtime *rtd, | |
| 132 | + struct snd_pcm_hw_params *params) | |
| 133 | +{ | |
| 134 | + struct snd_interval *rate = hw_param_interval(params, | |
| 135 | + SNDRV_PCM_HW_PARAM_RATE); | |
| 136 | + struct snd_interval *channels = hw_param_interval(params, | |
| 137 | + SNDRV_PCM_HW_PARAM_CHANNELS); | |
| 138 | + struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | |
| 139 | + | |
| 140 | + /* The ADSP will covert the FE rate to 48k, stereo */ | |
| 141 | + rate->min = rate->max = 48000; | |
| 142 | + channels->min = channels->max = 2; | |
| 143 | + | |
| 144 | + /* set SSP5 to 24 bit */ | |
| 145 | + snd_mask_none(fmt); | |
| 146 | + snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE); | |
| 147 | + | |
| 148 | + return 0; | |
| 149 | +} | |
| 150 | + | |
| 151 | +static int broxton_rt298_hw_params(struct snd_pcm_substream *substream, | |
| 152 | + struct snd_pcm_hw_params *params) | |
| 153 | +{ | |
| 154 | + struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
| 155 | + struct snd_soc_dai *codec_dai = rtd->codec_dai; | |
| 156 | + int ret; | |
| 157 | + | |
| 158 | + ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, | |
| 159 | + 19200000, SND_SOC_CLOCK_IN); | |
| 160 | + if (ret < 0) { | |
| 161 | + dev_err(rtd->dev, "can't set codec sysclk configuration\n"); | |
| 162 | + return ret; | |
| 163 | + } | |
| 164 | + | |
| 165 | + return ret; | |
| 166 | +} | |
| 167 | + | |
| 168 | +static struct snd_soc_ops broxton_rt298_ops = { | |
| 169 | + .hw_params = broxton_rt298_hw_params, | |
| 170 | +}; | |
| 171 | + | |
| 172 | +/* broxton digital audio interface glue - connects codec <--> CPU */ | |
| 173 | +static struct snd_soc_dai_link broxton_rt298_dais[] = { | |
| 174 | + /* Front End DAI links */ | |
| 175 | + [BXT_DPCM_AUDIO_PB] | |
| 176 | + { | |
| 177 | + .name = "Bxt Audio Port", | |
| 178 | + .stream_name = "Audio", | |
| 179 | + .cpu_dai_name = "System Pin", | |
| 180 | + .platform_name = "0000:00:0e.0", | |
| 181 | + .nonatomic = 1, | |
| 182 | + .dynamic = 1, | |
| 183 | + .codec_name = "snd-soc-dummy", | |
| 184 | + .codec_dai_name = "snd-soc-dummy-dai", | |
| 185 | + .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
| 186 | + .dpcm_playback = 1, | |
| 187 | + }, | |
| 188 | + [BXT_DPCM_AUDIO_CP] | |
| 189 | + { | |
| 190 | + .name = "Bxt Audio Capture Port", | |
| 191 | + .stream_name = "Audio Record", | |
| 192 | + .cpu_dai_name = "System Pin", | |
| 193 | + .platform_name = "0000:00:0e.0", | |
| 194 | + .nonatomic = 1, | |
| 195 | + .dynamic = 1, | |
| 196 | + .codec_name = "snd-soc-dummy", | |
| 197 | + .codec_dai_name = "snd-soc-dummy-dai", | |
| 198 | + .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
| 199 | + .dpcm_capture = 1, | |
| 200 | + }, | |
| 201 | + [BXT_DPCM_AUDIO_REF_CP] | |
| 202 | + { | |
| 203 | + .name = "Bxt Audio Reference cap", | |
| 204 | + .stream_name = "refcap", | |
| 205 | + .cpu_dai_name = "Reference Pin", | |
| 206 | + .codec_name = "snd-soc-dummy", | |
| 207 | + .codec_dai_name = "snd-soc-dummy-dai", | |
| 208 | + .platform_name = "0000:00:0e.0", | |
| 209 | + .init = NULL, | |
| 210 | + .dpcm_capture = 1, | |
| 211 | + .nonatomic = 1, | |
| 212 | + .dynamic = 1, | |
| 213 | + }, | |
| 214 | + [BXT_DPCM_AUDIO_HDMI1_PB] | |
| 215 | + { | |
| 216 | + .name = "Bxt HDMI Port1", | |
| 217 | + .stream_name = "Hdmi1", | |
| 218 | + .cpu_dai_name = "HDMI1 Pin", | |
| 219 | + .codec_name = "snd-soc-dummy", | |
| 220 | + .codec_dai_name = "snd-soc-dummy-dai", | |
| 221 | + .platform_name = "0000:00:0e.0", | |
| 222 | + .dpcm_playback = 1, | |
| 223 | + .init = NULL, | |
| 224 | + .nonatomic = 1, | |
| 225 | + .dynamic = 1, | |
| 226 | + }, | |
| 227 | + [BXT_DPCM_AUDIO_HDMI2_PB] | |
| 228 | + { | |
| 229 | + .name = "Bxt HDMI Port2", | |
| 230 | + .stream_name = "Hdmi2", | |
| 231 | + .cpu_dai_name = "HDMI2 Pin", | |
| 232 | + .codec_name = "snd-soc-dummy", | |
| 233 | + .codec_dai_name = "snd-soc-dummy-dai", | |
| 234 | + .platform_name = "0000:00:0e.0", | |
| 235 | + .dpcm_playback = 1, | |
| 236 | + .init = NULL, | |
| 237 | + .nonatomic = 1, | |
| 238 | + .dynamic = 1, | |
| 239 | + }, | |
| 240 | + [BXT_DPCM_AUDIO_HDMI3_PB] | |
| 241 | + { | |
| 242 | + .name = "Bxt HDMI Port3", | |
| 243 | + .stream_name = "Hdmi3", | |
| 244 | + .cpu_dai_name = "HDMI3 Pin", | |
| 245 | + .codec_name = "snd-soc-dummy", | |
| 246 | + .codec_dai_name = "snd-soc-dummy-dai", | |
| 247 | + .platform_name = "0000:00:0e.0", | |
| 248 | + .dpcm_playback = 1, | |
| 249 | + .init = NULL, | |
| 250 | + .nonatomic = 1, | |
| 251 | + .dynamic = 1, | |
| 252 | + }, | |
| 253 | + /* Back End DAI links */ | |
| 254 | + { | |
| 255 | + /* SSP5 - Codec */ | |
| 256 | + .name = "SSP5-Codec", | |
| 257 | + .id = 0, | |
| 258 | + .cpu_dai_name = "SSP5 Pin", | |
| 259 | + .platform_name = "0000:00:0e.0", | |
| 260 | + .no_pcm = 1, | |
| 261 | + .codec_name = "i2c-INT343A:00", | |
| 262 | + .codec_dai_name = "rt298-aif1", | |
| 263 | + .init = broxton_rt298_codec_init, | |
| 264 | + .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | | |
| 265 | + SND_SOC_DAIFMT_CBS_CFS, | |
| 266 | + .ignore_pmdown_time = 1, | |
| 267 | + .be_hw_params_fixup = broxton_ssp5_fixup, | |
| 268 | + .ops = &broxton_rt298_ops, | |
| 269 | + .dpcm_playback = 1, | |
| 270 | + .dpcm_capture = 1, | |
| 271 | + }, | |
| 272 | + { | |
| 273 | + .name = "dmic01", | |
| 274 | + .id = 1, | |
| 275 | + .cpu_dai_name = "DMIC01 Pin", | |
| 276 | + .codec_name = "dmic-codec", | |
| 277 | + .codec_dai_name = "dmic-hifi", | |
| 278 | + .platform_name = "0000:00:0e.0", | |
| 279 | + .ignore_suspend = 1, | |
| 280 | + .dpcm_capture = 1, | |
| 281 | + .no_pcm = 1, | |
| 282 | + }, | |
| 283 | + { | |
| 284 | + .name = "iDisp1", | |
| 285 | + .id = 3, | |
| 286 | + .cpu_dai_name = "iDisp1 Pin", | |
| 287 | + .codec_name = "ehdaudio0D2", | |
| 288 | + .codec_dai_name = "intel-hdmi-hifi1", | |
| 289 | + .platform_name = "0000:00:0e.0", | |
| 290 | + .init = broxton_hdmi_init, | |
| 291 | + .dpcm_playback = 1, | |
| 292 | + .no_pcm = 1, | |
| 293 | + }, | |
| 294 | + { | |
| 295 | + .name = "iDisp2", | |
| 296 | + .id = 4, | |
| 297 | + .cpu_dai_name = "iDisp2 Pin", | |
| 298 | + .codec_name = "ehdaudio0D2", | |
| 299 | + .codec_dai_name = "intel-hdmi-hifi2", | |
| 300 | + .platform_name = "0000:00:0e.0", | |
| 301 | + .init = broxton_hdmi_init, | |
| 302 | + .dpcm_playback = 1, | |
| 303 | + .no_pcm = 1, | |
| 304 | + }, | |
| 305 | + { | |
| 306 | + .name = "iDisp3", | |
| 307 | + .id = 5, | |
| 308 | + .cpu_dai_name = "iDisp3 Pin", | |
| 309 | + .codec_name = "ehdaudio0D2", | |
| 310 | + .codec_dai_name = "intel-hdmi-hifi3", | |
| 311 | + .platform_name = "0000:00:0e.0", | |
| 312 | + .init = broxton_hdmi_init, | |
| 313 | + .dpcm_playback = 1, | |
| 314 | + .no_pcm = 1, | |
| 315 | + }, | |
| 316 | +}; | |
| 317 | + | |
| 318 | +/* broxton audio machine driver for SPT + RT298S */ | |
| 319 | +static struct snd_soc_card broxton_rt298 = { | |
| 320 | + .name = "broxton-rt298", | |
| 321 | + .owner = THIS_MODULE, | |
| 322 | + .dai_link = broxton_rt298_dais, | |
| 323 | + .num_links = ARRAY_SIZE(broxton_rt298_dais), | |
| 324 | + .controls = broxton_controls, | |
| 325 | + .num_controls = ARRAY_SIZE(broxton_controls), | |
| 326 | + .dapm_widgets = broxton_widgets, | |
| 327 | + .num_dapm_widgets = ARRAY_SIZE(broxton_widgets), | |
| 328 | + .dapm_routes = broxton_rt298_map, | |
| 329 | + .num_dapm_routes = ARRAY_SIZE(broxton_rt298_map), | |
| 330 | + .fully_routed = true, | |
| 331 | +}; | |
| 332 | + | |
| 333 | +static int broxton_audio_probe(struct platform_device *pdev) | |
| 334 | +{ | |
| 335 | + broxton_rt298.dev = &pdev->dev; | |
| 336 | + | |
| 337 | + return devm_snd_soc_register_card(&pdev->dev, &broxton_rt298); | |
| 338 | +} | |
| 339 | + | |
| 340 | +static struct platform_driver broxton_audio = { | |
| 341 | + .probe = broxton_audio_probe, | |
| 342 | + .driver = { | |
| 343 | + .name = "bxt_alc298s_i2s", | |
| 344 | + }, | |
| 345 | +}; | |
| 346 | +module_platform_driver(broxton_audio) | |
| 347 | + | |
| 348 | +/* Module information */ | |
| 349 | +MODULE_AUTHOR("Ramesh Babu <Ramesh.Babu@intel.com>"); | |
| 350 | +MODULE_AUTHOR("Senthilnathan Veppur <senthilnathanx.veppur@intel.com>"); | |
| 351 | +MODULE_DESCRIPTION("Intel SST Audio for Broxton"); | |
| 352 | +MODULE_LICENSE("GPL v2"); | |
| 353 | +MODULE_ALIAS("platform:bxt_alc298s_i2s"); | |
| @@ -304,7 +304,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = { · 303 unmodified lines | ||
| 304 | 304 | /* back ends */ |
| 305 | 305 | { |
| 306 | 306 | .name = "SSP2-Codec", |
| 307 | − .be_id = 1, | |
| 307 | + .id = 1, | |
| 308 | 308 | .cpu_dai_name = "ssp2-port", |
| 309 | 309 | .platform_name = "sst-mfld-platform", |
| 310 | 310 | .no_pcm = 1, |
| @@ -267,7 +267,7 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = { · 266 unmodified lines | ||
| 267 | 267 | /* back ends */ |
| 268 | 268 | { |
| 269 | 269 | .name = "SSP2-Codec", |
| 270 | − .be_id = 1, | |
| 270 | + .id = 1, | |
| 271 | 271 | .cpu_dai_name = "ssp2-port", |
| 272 | 272 | .platform_name = "sst-mfld-platform", |
| 273 | 273 | .no_pcm = 1, |
| @@ -255,7 +255,7 @@ static struct snd_soc_dai_link cht_dailink[] = { · 254 unmodified lines | ||
| 255 | 255 | /* back ends */ |
| 256 | 256 | { |
| 257 | 257 | .name = "SSP2-Codec", |
| 258 | − .be_id = 1, | |
| 258 | + .id = 1, | |
| 259 | 259 | .cpu_dai_name = "ssp2-port", |
| 260 | 260 | .platform_name = "sst-mfld-platform", |
| 261 | 261 | .no_pcm = 1, |
| @@ -295,7 +295,7 @@ static struct snd_soc_dai_link cht_dailink[] = { · 294 unmodified lines | ||
| 295 | 295 | /* back ends */ |
| 296 | 296 | { |
| 297 | 297 | .name = "SSP2-Codec", |
| 298 | − .be_id = 1, | |
| 298 | + .id = 1, | |
| 299 | 299 | .cpu_dai_name = "ssp2-port", |
| 300 | 300 | .platform_name = "sst-mfld-platform", |
| 301 | 301 | .no_pcm = 1, |
| @@ -273,7 +273,7 @@ static struct snd_soc_dai_link cht_dailink[] = { · 272 unmodified lines | ||
| 273 | 273 | { |
| 274 | 274 | /* SSP2 - Codec */ |
| 275 | 275 | .name = "SSP2-Codec", |
| 276 | − .be_id = 1, | |
| 276 | + .id = 1, | |
| 277 | 277 | .cpu_dai_name = "ssp2-port", |
| 278 | 278 | .platform_name = "sst-mfld-platform", |
| 279 | 279 | .no_pcm = 1, |
| @@ -156,7 +156,7 @@ static struct snd_soc_dai_link haswell_rt5640_dais[] = { · 155 unmodified lines | ||
| 156 | 156 | { |
| 157 | 157 | /* SSP0 - Codec */ |
| 158 | 158 | .name = "Codec", |
| 159 | − .be_id = 0, | |
| 159 | + .id = 0, | |
| 160 | 160 | .cpu_dai_name = "snd-soc-dummy-dai", |
| 161 | 161 | .platform_name = "snd-soc-dummy", |
| 162 | 162 | .no_pcm = 1, |
| @@ -30,6 +30,16 @@ · 29 unmodified lines | ||
| 30 | 30 | static struct snd_soc_jack skylake_headset; |
| 31 | 31 | static struct snd_soc_card skylake_audio_card; |
| 32 | 32 | |
| 33 | +struct skl_hdmi_pcm { | |
| 34 | + struct list_head head; | |
| 35 | + struct snd_soc_dai *codec_dai; | |
| 36 | + int device; | |
| 37 | +}; | |
| 38 | + | |
| 39 | +struct skl_nau8825_private { | |
| 40 | + struct list_head hdmi_pcm_list; | |
| 41 | +}; | |
| 42 | + | |
| 33 | 43 | enum { |
| 34 | 44 | SKL_DPCM_AUDIO_PB = 0, |
| 35 | 45 | SKL_DPCM_AUDIO_CP, |
| @@ -192,23 +202,56 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) · 156 unmodified lines | ||
| 192 | 202 | |
| 193 | 203 | static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) |
| 194 | 204 | { |
| 205 | + struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card); | |
| 195 | 206 | struct snd_soc_dai *dai = rtd->codec_dai; |
| 207 | + struct skl_hdmi_pcm *pcm; | |
| 208 | + | |
| 209 | + pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); | |
| 210 | + if (!pcm) | |
| 211 | + return -ENOMEM; | |
| 212 | + | |
| 213 | + pcm->device = SKL_DPCM_AUDIO_HDMI1_PB; | |
| 214 | + pcm->codec_dai = dai; | |
| 196 | 215 | |
| 197 | − return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI1_PB); | |
| 216 | + list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); | |
| 217 | + | |
| 218 | + return 0; | |
| 198 | 219 | } |
| 199 | 220 | |
| 200 | 221 | static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) |
| 201 | 222 | { |
| 223 | + struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card); | |
| 202 | 224 | struct snd_soc_dai *dai = rtd->codec_dai; |
| 225 | + struct skl_hdmi_pcm *pcm; | |
| 226 | + | |
| 227 | + pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); | |
| 228 | + if (!pcm) | |
| 229 | + return -ENOMEM; | |
| 230 | + | |
| 231 | + pcm->device = SKL_DPCM_AUDIO_HDMI2_PB; | |
| 232 | + pcm->codec_dai = dai; | |
| 203 | 233 | |
| 204 | − return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI2_PB); | |
| 234 | + list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); | |
| 235 | + | |
| 236 | + return 0; | |
| 205 | 237 | } |
| 206 | 238 | |
| 207 | 239 | static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) |
| 208 | 240 | { |
| 241 | + struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card); | |
| 209 | 242 | struct snd_soc_dai *dai = rtd->codec_dai; |
| 243 | + struct skl_hdmi_pcm *pcm; | |
| 244 | + | |
| 245 | + pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); | |
| 246 | + if (!pcm) | |
| 247 | + return -ENOMEM; | |
| 210 | 248 | |
| 211 | − return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI3_PB); | |
| 249 | + pcm->device = SKL_DPCM_AUDIO_HDMI3_PB; | |
| 250 | + pcm->codec_dai = dai; | |
| 251 | + | |
| 252 | + list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); | |
| 253 | + | |
| 254 | + return 0; | |
| 212 | 255 | } |
| 213 | 256 | |
| 214 | 257 | static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd) |
| @@ -391,7 +434,6 @@ static struct snd_soc_dai_link skylake_dais[] = { · 176 unmodified lines | ||
| 391 | 434 | .platform_name = "0000:00:1f.3", |
| 392 | 435 | .init = NULL, |
| 393 | 436 | .dpcm_capture = 1, |
| 394 | − .ignore_suspend = 1, | |
| 395 | 437 | .nonatomic = 1, |
| 396 | 438 | .dynamic = 1, |
| 397 | 439 | .ops = &skylaye_refcap_ops, |
| @@ -456,7 +498,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 58 unmodified lines | ||
| 456 | 498 | { |
| 457 | 499 | /* SSP0 - Codec */ |
| 458 | 500 | .name = "SSP0-Codec", |
| 459 | − .be_id = 0, | |
| 501 | + .id = 0, | |
| 460 | 502 | .cpu_dai_name = "SSP0 Pin", |
| 461 | 503 | .platform_name = "0000:00:1f.3", |
| 462 | 504 | .no_pcm = 1, |
| @@ -472,7 +514,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 9 unmodified lines | ||
| 472 | 514 | { |
| 473 | 515 | /* SSP1 - Codec */ |
| 474 | 516 | .name = "SSP1-Codec", |
| 475 | − .be_id = 1, | |
| 517 | + .id = 1, | |
| 476 | 518 | .cpu_dai_name = "SSP1 Pin", |
| 477 | 519 | .platform_name = "0000:00:1f.3", |
| 478 | 520 | .no_pcm = 1, |
| @@ -489,7 +531,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 10 unmodified lines | ||
| 489 | 531 | }, |
| 490 | 532 | { |
| 491 | 533 | .name = "dmic01", |
| 492 | − .be_id = 2, | |
| 534 | + .id = 2, | |
| 493 | 535 | .cpu_dai_name = "DMIC01 Pin", |
| 494 | 536 | .codec_name = "dmic-codec", |
| 495 | 537 | .codec_dai_name = "dmic-hifi", |
| @@ -501,7 +543,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 5 unmodified lines | ||
| 501 | 543 | }, |
| 502 | 544 | { |
| 503 | 545 | .name = "iDisp1", |
| 504 | − .be_id = 3, | |
| 546 | + .id = 3, | |
| 505 | 547 | .cpu_dai_name = "iDisp1 Pin", |
| 506 | 548 | .codec_name = "ehdaudio0D2", |
| 507 | 549 | .codec_dai_name = "intel-hdmi-hifi1", |
| @@ -512,7 +554,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 4 unmodified lines | ||
| 512 | 554 | }, |
| 513 | 555 | { |
| 514 | 556 | .name = "iDisp2", |
| 515 | − .be_id = 4, | |
| 557 | + .id = 4, | |
| 516 | 558 | .cpu_dai_name = "iDisp2 Pin", |
| 517 | 559 | .codec_name = "ehdaudio0D2", |
| 518 | 560 | .codec_dai_name = "intel-hdmi-hifi2", |
| @@ -523,7 +565,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 4 unmodified lines | ||
| 523 | 565 | }, |
| 524 | 566 | { |
| 525 | 567 | .name = "iDisp3", |
| 526 | − .be_id = 5, | |
| 568 | + .id = 5, | |
| 527 | 569 | .cpu_dai_name = "iDisp3 Pin", |
| 528 | 570 | .codec_name = "ehdaudio0D2", |
| 529 | 571 | .codec_dai_name = "intel-hdmi-hifi3", |
| @@ -534,6 +576,21 @@ static struct snd_soc_dai_link skylake_dais[] = { · 4 unmodified lines | ||
| 534 | 576 | }, |
| 535 | 577 | }; |
| 536 | 578 | |
| 579 | +static int skylake_card_late_probe(struct snd_soc_card *card) | |
| 580 | +{ | |
| 581 | + struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(card); | |
| 582 | + struct skl_hdmi_pcm *pcm; | |
| 583 | + int err; | |
| 584 | + | |
| 585 | + list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { | |
| 586 | + err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device); | |
| 587 | + if (err < 0) | |
| 588 | + return err; | |
| 589 | + } | |
| 590 | + | |
| 591 | + return 0; | |
| 592 | +} | |
| 593 | + | |
| 537 | 594 | /* skylake audio machine driver for SPT + NAU88L25 */ |
| 538 | 595 | static struct snd_soc_card skylake_audio_card = { |
| 539 | 596 | .name = "sklnau8825max", |
| @@ -547,11 +604,21 @@ static struct snd_soc_card skylake_audio_card = { · 7 unmodified lines | ||
| 547 | 604 | .dapm_routes = skylake_map, |
| 548 | 605 | .num_dapm_routes = ARRAY_SIZE(skylake_map), |
| 549 | 606 | .fully_routed = true, |
| 607 | + .late_probe = skylake_card_late_probe, | |
| 550 | 608 | }; |
| 551 | 609 | |
| 552 | 610 | static int skylake_audio_probe(struct platform_device *pdev) |
| 553 | 611 | { |
| 612 | + struct skl_nau8825_private *ctx; | |
| 613 | + | |
| 614 | + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); | |
| 615 | + if (!ctx) | |
| 616 | + return -ENOMEM; | |
| 617 | + | |
| 618 | + INIT_LIST_HEAD(&ctx->hdmi_pcm_list); | |
| 619 | + | |
| 554 | 620 | skylake_audio_card.dev = &pdev->dev; |
| 621 | + snd_soc_card_set_drvdata(&skylake_audio_card, ctx); | |
| 555 | 622 | |
| 556 | 623 | return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card); |
| 557 | 624 | } |
| @@ -34,6 +34,15 @@ · 33 unmodified lines | ||
| 34 | 34 | static struct snd_soc_jack skylake_headset; |
| 35 | 35 | static struct snd_soc_card skylake_audio_card; |
| 36 | 36 | |
| 37 | +struct skl_hdmi_pcm { | |
| 38 | + struct list_head head; | |
| 39 | + struct snd_soc_dai *codec_dai; | |
| 40 | + int device; | |
| 41 | +}; | |
| 42 | + | |
| 43 | +struct skl_nau88125_private { | |
| 44 | + struct list_head hdmi_pcm_list; | |
| 45 | +}; | |
| 37 | 46 | enum { |
| 38 | 47 | SKL_DPCM_AUDIO_PB = 0, |
| 39 | 48 | SKL_DPCM_AUDIO_CP, |
| @@ -222,24 +231,57 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) · 182 unmodified lines | ||
| 222 | 231 | |
| 223 | 232 | static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) |
| 224 | 233 | { |
| 234 | + struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); | |
| 225 | 235 | struct snd_soc_dai *dai = rtd->codec_dai; |
| 236 | + struct skl_hdmi_pcm *pcm; | |
| 237 | + | |
| 238 | + pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); | |
| 239 | + if (!pcm) | |
| 240 | + return -ENOMEM; | |
| 241 | + | |
| 242 | + pcm->device = SKL_DPCM_AUDIO_HDMI1_PB; | |
| 243 | + pcm->codec_dai = dai; | |
| 244 | + | |
| 245 | + list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); | |
| 226 | 246 | |
| 227 | − return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI1_PB); | |
| 247 | + return 0; | |
| 228 | 248 | } |
| 229 | 249 | |
| 230 | 250 | static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) |
| 231 | 251 | { |
| 252 | + struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); | |
| 232 | 253 | struct snd_soc_dai *dai = rtd->codec_dai; |
| 254 | + struct skl_hdmi_pcm *pcm; | |
| 255 | + | |
| 256 | + pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); | |
| 257 | + if (!pcm) | |
| 258 | + return -ENOMEM; | |
| 259 | + | |
| 260 | + pcm->device = SKL_DPCM_AUDIO_HDMI2_PB; | |
| 261 | + pcm->codec_dai = dai; | |
| 233 | 262 | |
| 234 | − return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI2_PB); | |
| 263 | + list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); | |
| 264 | + | |
| 265 | + return 0; | |
| 235 | 266 | } |
| 236 | 267 | |
| 237 | 268 | |
| 238 | 269 | static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) |
| 239 | 270 | { |
| 271 | + struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); | |
| 240 | 272 | struct snd_soc_dai *dai = rtd->codec_dai; |
| 273 | + struct skl_hdmi_pcm *pcm; | |
| 274 | + | |
| 275 | + pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); | |
| 276 | + if (!pcm) | |
| 277 | + return -ENOMEM; | |
| 241 | 278 | |
| 242 | − return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI3_PB); | |
| 279 | + pcm->device = SKL_DPCM_AUDIO_HDMI3_PB; | |
| 280 | + pcm->codec_dai = dai; | |
| 281 | + | |
| 282 | + list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); | |
| 283 | + | |
| 284 | + return 0; | |
| 243 | 285 | } |
| 244 | 286 | |
| 245 | 287 | static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd) |
| @@ -440,7 +482,6 @@ static struct snd_soc_dai_link skylake_dais[] = { · 194 unmodified lines | ||
| 440 | 482 | .platform_name = "0000:00:1f.3", |
| 441 | 483 | .init = NULL, |
| 442 | 484 | .dpcm_capture = 1, |
| 443 | − .ignore_suspend = 1, | |
| 444 | 485 | .nonatomic = 1, |
| 445 | 486 | .dynamic = 1, |
| 446 | 487 | .ops = &skylaye_refcap_ops, |
| @@ -505,7 +546,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 58 unmodified lines | ||
| 505 | 546 | { |
| 506 | 547 | /* SSP0 - Codec */ |
| 507 | 548 | .name = "SSP0-Codec", |
| 508 | − .be_id = 0, | |
| 549 | + .id = 0, | |
| 509 | 550 | .cpu_dai_name = "SSP0 Pin", |
| 510 | 551 | .platform_name = "0000:00:1f.3", |
| 511 | 552 | .no_pcm = 1, |
| @@ -523,7 +564,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 11 unmodified lines | ||
| 523 | 564 | { |
| 524 | 565 | /* SSP1 - Codec */ |
| 525 | 566 | .name = "SSP1-Codec", |
| 526 | − .be_id = 1, | |
| 567 | + .id = 1, | |
| 527 | 568 | .cpu_dai_name = "SSP1 Pin", |
| 528 | 569 | .platform_name = "0000:00:1f.3", |
| 529 | 570 | .no_pcm = 1, |
| @@ -540,7 +581,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 10 unmodified lines | ||
| 540 | 581 | }, |
| 541 | 582 | { |
| 542 | 583 | .name = "dmic01", |
| 543 | − .be_id = 2, | |
| 584 | + .id = 2, | |
| 544 | 585 | .cpu_dai_name = "DMIC01 Pin", |
| 545 | 586 | .codec_name = "dmic-codec", |
| 546 | 587 | .codec_dai_name = "dmic-hifi", |
| @@ -552,7 +593,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 5 unmodified lines | ||
| 552 | 593 | }, |
| 553 | 594 | { |
| 554 | 595 | .name = "iDisp1", |
| 555 | − .be_id = 3, | |
| 596 | + .id = 3, | |
| 556 | 597 | .cpu_dai_name = "iDisp1 Pin", |
| 557 | 598 | .codec_name = "ehdaudio0D2", |
| 558 | 599 | .codec_dai_name = "intel-hdmi-hifi1", |
| @@ -563,7 +604,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 4 unmodified lines | ||
| 563 | 604 | }, |
| 564 | 605 | { |
| 565 | 606 | .name = "iDisp2", |
| 566 | − .be_id = 4, | |
| 607 | + .id = 4, | |
| 567 | 608 | .cpu_dai_name = "iDisp2 Pin", |
| 568 | 609 | .codec_name = "ehdaudio0D2", |
| 569 | 610 | .codec_dai_name = "intel-hdmi-hifi2", |
| @@ -574,7 +615,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 4 unmodified lines | ||
| 574 | 615 | }, |
| 575 | 616 | { |
| 576 | 617 | .name = "iDisp3", |
| 577 | − .be_id = 5, | |
| 618 | + .id = 5, | |
| 578 | 619 | .cpu_dai_name = "iDisp3 Pin", |
| 579 | 620 | .codec_name = "ehdaudio0D2", |
| 580 | 621 | .codec_dai_name = "intel-hdmi-hifi3", |
| @@ -585,6 +626,21 @@ static struct snd_soc_dai_link skylake_dais[] = { · 4 unmodified lines | ||
| 585 | 626 | }, |
| 586 | 627 | }; |
| 587 | 628 | |
| 629 | +static int skylake_card_late_probe(struct snd_soc_card *card) | |
| 630 | +{ | |
| 631 | + struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(card); | |
| 632 | + struct skl_hdmi_pcm *pcm; | |
| 633 | + int err; | |
| 634 | + | |
| 635 | + list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { | |
| 636 | + err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device); | |
| 637 | + if (err < 0) | |
| 638 | + return err; | |
| 639 | + } | |
| 640 | + | |
| 641 | + return 0; | |
| 642 | +} | |
| 643 | + | |
| 588 | 644 | /* skylake audio machine driver for SPT + NAU88L25 */ |
| 589 | 645 | static struct snd_soc_card skylake_audio_card = { |
| 590 | 646 | .name = "sklnau8825adi", |
| @@ -600,11 +656,21 @@ static struct snd_soc_card skylake_audio_card = { · 9 unmodified lines | ||
| 600 | 656 | .codec_conf = ssm4567_codec_conf, |
| 601 | 657 | .num_configs = ARRAY_SIZE(ssm4567_codec_conf), |
| 602 | 658 | .fully_routed = true, |
| 659 | + .late_probe = skylake_card_late_probe, | |
| 603 | 660 | }; |
| 604 | 661 | |
| 605 | 662 | static int skylake_audio_probe(struct platform_device *pdev) |
| 606 | 663 | { |
| 664 | + struct skl_nau88125_private *ctx; | |
| 665 | + | |
| 666 | + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); | |
| 667 | + if (!ctx) | |
| 668 | + return -ENOMEM; | |
| 669 | + | |
| 670 | + INIT_LIST_HEAD(&ctx->hdmi_pcm_list); | |
| 671 | + | |
| 607 | 672 | skylake_audio_card.dev = &pdev->dev; |
| 673 | + snd_soc_card_set_drvdata(&skylake_audio_card, ctx); | |
| 608 | 674 | |
| 609 | 675 | return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card); |
| 610 | 676 | } |
| @@ -30,6 +30,16 @@ · 29 unmodified lines | ||
| 30 | 30 | |
| 31 | 31 | static struct snd_soc_jack skylake_headset; |
| 32 | 32 | |
| 33 | +struct skl_hdmi_pcm { | |
| 34 | + struct list_head head; | |
| 35 | + struct snd_soc_dai *codec_dai; | |
| 36 | + int device; | |
| 37 | +}; | |
| 38 | + | |
| 39 | +struct skl_rt286_private { | |
| 40 | + struct list_head hdmi_pcm_list; | |
| 41 | +}; | |
| 42 | + | |
| 33 | 43 | enum { |
| 34 | 44 | SKL_DPCM_AUDIO_PB = 0, |
| 35 | 45 | SKL_DPCM_AUDIO_CP, |
| @@ -142,9 +152,20 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) · 106 unmodified lines | ||
| 142 | 152 | |
| 143 | 153 | static int skylake_hdmi_init(struct snd_soc_pcm_runtime *rtd) |
| 144 | 154 | { |
| 155 | + struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(rtd->card); | |
| 145 | 156 | struct snd_soc_dai *dai = rtd->codec_dai; |
| 157 | + struct skl_hdmi_pcm *pcm; | |
| 158 | + | |
| 159 | + pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); | |
| 160 | + if (!pcm) | |
| 161 | + return -ENOMEM; | |
| 146 | 162 | |
| 147 | − return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI1_PB + dai->id); | |
| 163 | + pcm->device = SKL_DPCM_AUDIO_HDMI1_PB + dai->id; | |
| 164 | + pcm->codec_dai = dai; | |
| 165 | + | |
| 166 | + list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); | |
| 167 | + | |
| 168 | + return 0; | |
| 148 | 169 | } |
| 149 | 170 | |
| 150 | 171 | static unsigned int rates[] = { |
| @@ -317,7 +338,6 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = { · 166 unmodified lines | ||
| 317 | 338 | .platform_name = "0000:00:1f.3", |
| 318 | 339 | .init = NULL, |
| 319 | 340 | .dpcm_capture = 1, |
| 320 | − .ignore_suspend = 1, | |
| 321 | 341 | .nonatomic = 1, |
| 322 | 342 | .dynamic = 1, |
| 323 | 343 | }, |
| @@ -375,7 +395,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = { · 51 unmodified lines | ||
| 375 | 395 | { |
| 376 | 396 | /* SSP0 - Codec */ |
| 377 | 397 | .name = "SSP0-Codec", |
| 378 | − .be_id = 0, | |
| 398 | + .id = 0, | |
| 379 | 399 | .cpu_dai_name = "SSP0 Pin", |
| 380 | 400 | .platform_name = "0000:00:1f.3", |
| 381 | 401 | .no_pcm = 1, |
| @@ -393,7 +413,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = { · 11 unmodified lines | ||
| 393 | 413 | }, |
| 394 | 414 | { |
| 395 | 415 | .name = "dmic01", |
| 396 | − .be_id = 1, | |
| 416 | + .id = 1, | |
| 397 | 417 | .cpu_dai_name = "DMIC01 Pin", |
| 398 | 418 | .codec_name = "dmic-codec", |
| 399 | 419 | .codec_dai_name = "dmic-hifi", |
| @@ -405,7 +425,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = { · 5 unmodified lines | ||
| 405 | 425 | }, |
| 406 | 426 | { |
| 407 | 427 | .name = "iDisp1", |
| 408 | − .be_id = 2, | |
| 428 | + .id = 2, | |
| 409 | 429 | .cpu_dai_name = "iDisp1 Pin", |
| 410 | 430 | .codec_name = "ehdaudio0D2", |
| 411 | 431 | .codec_dai_name = "intel-hdmi-hifi1", |
| @@ -416,7 +436,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = { · 4 unmodified lines | ||
| 416 | 436 | }, |
| 417 | 437 | { |
| 418 | 438 | .name = "iDisp2", |
| 419 | − .be_id = 3, | |
| 439 | + .id = 3, | |
| 420 | 440 | .cpu_dai_name = "iDisp2 Pin", |
| 421 | 441 | .codec_name = "ehdaudio0D2", |
| 422 | 442 | .codec_dai_name = "intel-hdmi-hifi2", |
| @@ -427,7 +447,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = { · 4 unmodified lines | ||
| 427 | 447 | }, |
| 428 | 448 | { |
| 429 | 449 | .name = "iDisp3", |
| 430 | − .be_id = 4, | |
| 450 | + .id = 4, | |
| 431 | 451 | .cpu_dai_name = "iDisp3 Pin", |
| 432 | 452 | .codec_name = "ehdaudio0D2", |
| 433 | 453 | .codec_dai_name = "intel-hdmi-hifi3", |
| @@ -438,6 +458,21 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = { · 4 unmodified lines | ||
| 438 | 458 | }, |
| 439 | 459 | }; |
| 440 | 460 | |
| 461 | +static int skylake_card_late_probe(struct snd_soc_card *card) | |
| 462 | +{ | |
| 463 | + struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(card); | |
| 464 | + struct skl_hdmi_pcm *pcm; | |
| 465 | + int err; | |
| 466 | + | |
| 467 | + list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { | |
| 468 | + err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device); | |
| 469 | + if (err < 0) | |
| 470 | + return err; | |
| 471 | + } | |
| 472 | + | |
| 473 | + return 0; | |
| 474 | +} | |
| 475 | + | |
| 441 | 476 | /* skylake audio machine driver for SPT + RT286S */ |
| 442 | 477 | static struct snd_soc_card skylake_rt286 = { |
| 443 | 478 | .name = "skylake-rt286", |
| @@ -451,11 +486,21 @@ static struct snd_soc_card skylake_rt286 = { · 7 unmodified lines | ||
| 451 | 486 | .dapm_routes = skylake_rt286_map, |
| 452 | 487 | .num_dapm_routes = ARRAY_SIZE(skylake_rt286_map), |
| 453 | 488 | .fully_routed = true, |
| 489 | + .late_probe = skylake_card_late_probe, | |
| 454 | 490 | }; |
| 455 | 491 | |
| 456 | 492 | static int skylake_audio_probe(struct platform_device *pdev) |
| 457 | 493 | { |
| 494 | + struct skl_rt286_private *ctx; | |
| 495 | + | |
| 496 | + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); | |
| 497 | + if (!ctx) | |
| 498 | + return -ENOMEM; | |
| 499 | + | |
| 500 | + INIT_LIST_HEAD(&ctx->hdmi_pcm_list); | |
| 501 | + | |
| 458 | 502 | skylake_rt286.dev = &pdev->dev; |
| 503 | + snd_soc_card_set_drvdata(&skylake_rt286, ctx); | |
| 459 | 504 | |
| 460 | 505 | return devm_snd_soc_register_card(&pdev->dev, &skylake_rt286); |
| 461 | 506 | } |
| @@ -12,10 +12,19 @@ · 11 unmodified lines | ||
| 12 | 12 | * |
| 13 | 13 | */ |
| 14 | 14 | |
| 15 | +#include <linux/kconfig.h> | |
| 16 | +#include <linux/stddef.h> | |
| 15 | 17 | #include <linux/acpi.h> |
| 16 | 18 | |
| 17 | 19 | /* translation fron HID to I2C name, needed for DAI codec_name */ |
| 20 | +#if IS_ENABLED(CONFIG_ACPI) | |
| 18 | 21 | const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]); |
| 22 | +#else | |
| 23 | +inline const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]) | |
| 24 | +{ | |
| 25 | + return NULL; | |
| 26 | +} | |
| 27 | +#endif | |
| 19 | 28 | |
| 20 | 29 | /* acpi match */ |
| 21 | 30 | struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines); |
| @@ -445,7 +445,7 @@ static int create_adsp_page_table(struct snd_pcm_substream *substream, · 444 unmodified lines | ||
| 445 | 445 | |
| 446 | 446 | pages = snd_sgbuf_aligned_pages(size); |
| 447 | 447 | |
| 448 | − dev_dbg(rtd->dev, "generating page table for %p size 0x%zu pages %d\n", | |
| 448 | + dev_dbg(rtd->dev, "generating page table for %p size 0x%zx pages %d\n", | |
| 449 | 449 | dma_area, size, pages); |
| 450 | 450 | |
| 451 | 451 | for (i = 0; i < pages; i++) { |
| @@ -5,6 +5,6 @@ obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | # Skylake IPC Support |
| 7 | 7 | snd-soc-skl-ipc-objs := skl-sst-ipc.o skl-sst-dsp.o skl-sst-cldma.o \ |
| 8 | − skl-sst.o | |
| 8 | + skl-sst.o bxt-sst.o | |
| 9 | 9 | |
| 10 | 10 | obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl-ipc.o |
| @@ -0,0 +1,328 @@ | ||
| 1 | +/* | |
| 2 | + * bxt-sst.c - DSP library functions for BXT platform | |
| 3 | + * | |
| 4 | + * Copyright (C) 2015-16 Intel Corp | |
| 5 | + * Author:Rafal Redzimski <rafal.f.redzimski@intel.com> | |
| 6 | + * Jeeja KP <jeeja.kp@intel.com> | |
| 7 | + * | |
| 8 | + * This program is free software; you can redistribute it and/or modify | |
| 9 | + * it under the terms of the GNU General Public License as published by | |
| 10 | + * the Free Software Foundation; version 2 of the License. | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, but | |
| 13 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 | + * General Public License for more details. | |
| 16 | + */ | |
| 17 | + | |
| 18 | +#include <linux/module.h> | |
| 19 | +#include <linux/delay.h> | |
| 20 | +#include <linux/firmware.h> | |
| 21 | +#include <linux/device.h> | |
| 22 | + | |
| 23 | +#include "../common/sst-dsp.h" | |
| 24 | +#include "../common/sst-dsp-priv.h" | |
| 25 | +#include "skl-sst-ipc.h" | |
| 26 | + | |
| 27 | +#define BXT_BASEFW_TIMEOUT 3000 | |
| 28 | +#define BXT_INIT_TIMEOUT 500 | |
| 29 | +#define BXT_IPC_PURGE_FW 0x01004000 | |
| 30 | + | |
| 31 | +#define BXT_ROM_INIT 0x5 | |
| 32 | +#define BXT_ADSP_SRAM0_BASE 0x80000 | |
| 33 | + | |
| 34 | +/* Firmware status window */ | |
| 35 | +#define BXT_ADSP_FW_STATUS BXT_ADSP_SRAM0_BASE | |
| 36 | +#define BXT_ADSP_ERROR_CODE (BXT_ADSP_FW_STATUS + 0x4) | |
| 37 | + | |
| 38 | +#define BXT_ADSP_SRAM1_BASE 0xA0000 | |
| 39 | + | |
| 40 | +static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) | |
| 41 | +{ | |
| 42 | + return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE); | |
| 43 | +} | |
| 44 | + | |
| 45 | +static int sst_bxt_prepare_fw(struct sst_dsp *ctx, | |
| 46 | + const void *fwdata, u32 fwsize) | |
| 47 | +{ | |
| 48 | + int stream_tag, ret, i; | |
| 49 | + u32 reg; | |
| 50 | + | |
| 51 | + stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, fwsize, &ctx->dmab); | |
| 52 | + if (stream_tag < 0) { | |
| 53 | + dev_err(ctx->dev, "Failed to prepare DMA FW loading err: %x\n", | |
| 54 | + stream_tag); | |
| 55 | + return stream_tag; | |
| 56 | + } | |
| 57 | + | |
| 58 | + ctx->dsp_ops.stream_tag = stream_tag; | |
| 59 | + memcpy(ctx->dmab.area, fwdata, fwsize); | |
| 60 | + | |
| 61 | + /* Purge FW request */ | |
| 62 | + sst_dsp_shim_write(ctx, SKL_ADSP_REG_HIPCI, SKL_ADSP_REG_HIPCI_BUSY | | |
| 63 | + BXT_IPC_PURGE_FW | (stream_tag - 1)); | |
| 64 | + | |
| 65 | + ret = skl_dsp_enable_core(ctx); | |
| 66 | + if (ret < 0) { | |
| 67 | + dev_err(ctx->dev, "Boot dsp core failed ret: %d\n", ret); | |
| 68 | + ret = -EIO; | |
| 69 | + goto base_fw_load_failed; | |
| 70 | + } | |
| 71 | + | |
| 72 | + for (i = BXT_INIT_TIMEOUT; i > 0; --i) { | |
| 73 | + reg = sst_dsp_shim_read(ctx, SKL_ADSP_REG_HIPCIE); | |
| 74 | + | |
| 75 | + if (reg & SKL_ADSP_REG_HIPCIE_DONE) { | |
| 76 | + sst_dsp_shim_update_bits_forced(ctx, | |
| 77 | + SKL_ADSP_REG_HIPCIE, | |
| 78 | + SKL_ADSP_REG_HIPCIE_DONE, | |
| 79 | + SKL_ADSP_REG_HIPCIE_DONE); | |
| 80 | + break; | |
| 81 | + } | |
| 82 | + mdelay(1); | |
| 83 | + } | |
| 84 | + if (!i) { | |
| 85 | + dev_info(ctx->dev, "Waiting for HIPCIE done, reg: 0x%x\n", reg); | |
| 86 | + sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_HIPCIE, | |
| 87 | + SKL_ADSP_REG_HIPCIE_DONE, | |
| 88 | + SKL_ADSP_REG_HIPCIE_DONE); | |
| 89 | + } | |
| 90 | + | |
| 91 | + /* enable Interrupt */ | |
| 92 | + skl_ipc_int_enable(ctx); | |
| 93 | + skl_ipc_op_int_enable(ctx); | |
| 94 | + | |
| 95 | + for (i = BXT_INIT_TIMEOUT; i > 0; --i) { | |
| 96 | + if (SKL_FW_INIT == | |
| 97 | + (sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS) & | |
| 98 | + SKL_FW_STS_MASK)) { | |
| 99 | + | |
| 100 | + dev_info(ctx->dev, "ROM loaded, continue FW loading\n"); | |
| 101 | + break; | |
| 102 | + } | |
| 103 | + mdelay(1); | |
| 104 | + } | |
| 105 | + if (!i) { | |
| 106 | + dev_err(ctx->dev, "Timeout for ROM init, HIPCIE: 0x%x\n", reg); | |
| 107 | + ret = -EIO; | |
| 108 | + goto base_fw_load_failed; | |
| 109 | + } | |
| 110 | + | |
| 111 | + return ret; | |
| 112 | + | |
| 113 | +base_fw_load_failed: | |
| 114 | + ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, stream_tag); | |
| 115 | + skl_dsp_disable_core(ctx); | |
| 116 | + return ret; | |
| 117 | +} | |
| 118 | + | |
| 119 | +static int sst_transfer_fw_host_dma(struct sst_dsp *ctx) | |
| 120 | +{ | |
| 121 | + int ret; | |
| 122 | + | |
| 123 | + ctx->dsp_ops.trigger(ctx->dev, true, ctx->dsp_ops.stream_tag); | |
| 124 | + ret = sst_dsp_register_poll(ctx, BXT_ADSP_FW_STATUS, SKL_FW_STS_MASK, | |
| 125 | + BXT_ROM_INIT, BXT_BASEFW_TIMEOUT, "Firmware boot"); | |
| 126 | + | |
| 127 | + ctx->dsp_ops.trigger(ctx->dev, false, ctx->dsp_ops.stream_tag); | |
| 128 | + ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, ctx->dsp_ops.stream_tag); | |
| 129 | + | |
| 130 | + return ret; | |
| 131 | +} | |
| 132 | + | |
| 133 | +static int bxt_load_base_firmware(struct sst_dsp *ctx) | |
| 134 | +{ | |
| 135 | + const struct firmware *fw = NULL; | |
| 136 | + struct skl_sst *skl = ctx->thread_context; | |
| 137 | + int ret; | |
| 138 | + | |
| 139 | + ret = request_firmware(&fw, ctx->fw_name, ctx->dev); | |
| 140 | + if (ret < 0) { | |
| 141 | + dev_err(ctx->dev, "Request firmware failed %d\n", ret); | |
| 142 | + goto sst_load_base_firmware_failed; | |
| 143 | + } | |
| 144 | + | |
| 145 | + ret = sst_bxt_prepare_fw(ctx, fw->data, fw->size); | |
| 146 | + /* Retry Enabling core and ROM load. Retry seemed to help */ | |
| 147 | + if (ret < 0) { | |
| 148 | + ret = sst_bxt_prepare_fw(ctx, fw->data, fw->size); | |
| 149 | + if (ret < 0) { | |
| 150 | + dev_err(ctx->dev, "Core En/ROM load fail:%d\n", ret); | |
| 151 | + goto sst_load_base_firmware_failed; | |
| 152 | + } | |
| 153 | + } | |
| 154 | + | |
| 155 | + ret = sst_transfer_fw_host_dma(ctx); | |
| 156 | + if (ret < 0) { | |
| 157 | + dev_err(ctx->dev, "Transfer firmware failed %d\n", ret); | |
| 158 | + dev_info(ctx->dev, "Error code=0x%x: FW status=0x%x\n", | |
| 159 | + sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE), | |
| 160 | + sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS)); | |
| 161 | + | |
| 162 | + skl_dsp_disable_core(ctx); | |
| 163 | + } else { | |
| 164 | + dev_dbg(ctx->dev, "Firmware download successful\n"); | |
| 165 | + ret = wait_event_timeout(skl->boot_wait, skl->boot_complete, | |
| 166 | + msecs_to_jiffies(SKL_IPC_BOOT_MSECS)); | |
| 167 | + if (ret == 0) { | |
| 168 | + dev_err(ctx->dev, "DSP boot fail, FW Ready timeout\n"); | |
| 169 | + skl_dsp_disable_core(ctx); | |
| 170 | + ret = -EIO; | |
| 171 | + } else { | |
| 172 | + skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING); | |
| 173 | + ret = 0; | |
| 174 | + } | |
| 175 | + } | |
| 176 | + | |
| 177 | +sst_load_base_firmware_failed: | |
| 178 | + release_firmware(fw); | |
| 179 | + return ret; | |
| 180 | +} | |
| 181 | + | |
| 182 | +static int bxt_set_dsp_D0(struct sst_dsp *ctx) | |
| 183 | +{ | |
| 184 | + struct skl_sst *skl = ctx->thread_context; | |
| 185 | + int ret; | |
| 186 | + | |
| 187 | + skl->boot_complete = false; | |
| 188 | + | |
| 189 | + ret = skl_dsp_enable_core(ctx); | |
| 190 | + if (ret < 0) { | |
| 191 | + dev_err(ctx->dev, "enable dsp core failed ret: %d\n", ret); | |
| 192 | + return ret; | |
| 193 | + } | |
| 194 | + | |
| 195 | + /* enable interrupt */ | |
| 196 | + skl_ipc_int_enable(ctx); | |
| 197 | + skl_ipc_op_int_enable(ctx); | |
| 198 | + | |
| 199 | + ret = wait_event_timeout(skl->boot_wait, skl->boot_complete, | |
| 200 | + msecs_to_jiffies(SKL_IPC_BOOT_MSECS)); | |
| 201 | + if (ret == 0) { | |
| 202 | + dev_err(ctx->dev, "ipc: error DSP boot timeout\n"); | |
| 203 | + dev_err(ctx->dev, "Error code=0x%x: FW status=0x%x\n", | |
| 204 | + sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE), | |
| 205 | + sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS)); | |
| 206 | + return -EIO; | |
| 207 | + } | |
| 208 | + | |
| 209 | + skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING); | |
| 210 | + return 0; | |
| 211 | +} | |
| 212 | + | |
| 213 | +static int bxt_set_dsp_D3(struct sst_dsp *ctx) | |
| 214 | +{ | |
| 215 | + struct skl_ipc_dxstate_info dx; | |
| 216 | + struct skl_sst *skl = ctx->thread_context; | |
| 217 | + int ret = 0; | |
| 218 | + | |
| 219 | + if (!is_skl_dsp_running(ctx)) | |
| 220 | + return ret; | |
| 221 | + | |
| 222 | + dx.core_mask = SKL_DSP_CORE0_MASK; | |
| 223 | + dx.dx_mask = SKL_IPC_D3_MASK; | |
| 224 | + | |
| 225 | + ret = skl_ipc_set_dx(&skl->ipc, SKL_INSTANCE_ID, | |
| 226 | + SKL_BASE_FW_MODULE_ID, &dx); | |
| 227 | + if (ret < 0) { | |
| 228 | + dev_err(ctx->dev, "Failed to set DSP to D3 state: %d\n", ret); | |
| 229 | + return ret; | |
| 230 | + } | |
| 231 | + | |
| 232 | + ret = skl_dsp_disable_core(ctx); | |
| 233 | + if (ret < 0) { | |
| 234 | + dev_err(ctx->dev, "disbale dsp core failed: %d\n", ret); | |
| 235 | + ret = -EIO; | |
| 236 | + } | |
| 237 | + | |
| 238 | + skl_dsp_set_state_locked(ctx, SKL_DSP_RESET); | |
| 239 | + return 0; | |
| 240 | +} | |
| 241 | + | |
| 242 | +static struct skl_dsp_fw_ops bxt_fw_ops = { | |
| 243 | + .set_state_D0 = bxt_set_dsp_D0, | |
| 244 | + .set_state_D3 = bxt_set_dsp_D3, | |
| 245 | + .load_fw = bxt_load_base_firmware, | |
| 246 | + .get_fw_errcode = bxt_get_errorcode, | |
| 247 | +}; | |
| 248 | + | |
| 249 | +static struct sst_ops skl_ops = { | |
| 250 | + .irq_handler = skl_dsp_sst_interrupt, | |
| 251 | + .write = sst_shim32_write, | |
| 252 | + .read = sst_shim32_read, | |
| 253 | + .ram_read = sst_memcpy_fromio_32, | |
| 254 | + .ram_write = sst_memcpy_toio_32, | |
| 255 | + .free = skl_dsp_free, | |
| 256 | +}; | |
| 257 | + | |
| 258 | +static struct sst_dsp_device skl_dev = { | |
| 259 | + .thread = skl_dsp_irq_thread_handler, | |
| 260 | + .ops = &skl_ops, | |
| 261 | +}; | |
| 262 | + | |
| 263 | +int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | |
| 264 | + const char *fw_name, struct skl_dsp_loader_ops dsp_ops, | |
| 265 | + struct skl_sst **dsp) | |
| 266 | +{ | |
| 267 | + struct skl_sst *skl; | |
| 268 | + struct sst_dsp *sst; | |
| 269 | + int ret; | |
| 270 | + | |
| 271 | + skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL); | |
| 272 | + if (skl == NULL) | |
| 273 | + return -ENOMEM; | |
| 274 | + | |
| 275 | + skl->dev = dev; | |
| 276 | + skl_dev.thread_context = skl; | |
| 277 | + | |
| 278 | + skl->dsp = skl_dsp_ctx_init(dev, &skl_dev, irq); | |
| 279 | + if (!skl->dsp) { | |
| 280 | + dev_err(skl->dev, "skl_dsp_ctx_init failed\n"); | |
| 281 | + return -ENODEV; | |
| 282 | + } | |
| 283 | + | |
| 284 | + sst = skl->dsp; | |
| 285 | + sst->fw_name = fw_name; | |
| 286 | + sst->dsp_ops = dsp_ops; | |
| 287 | + sst->fw_ops = bxt_fw_ops; | |
| 288 | + sst->addr.lpe = mmio_base; | |
| 289 | + sst->addr.shim = mmio_base; | |
| 290 | + | |
| 291 | + sst_dsp_mailbox_init(sst, (BXT_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), | |
| 292 | + SKL_ADSP_W0_UP_SZ, BXT_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ); | |
| 293 | + | |
| 294 | + ret = skl_ipc_init(dev, skl); | |
| 295 | + if (ret) | |
| 296 | + return ret; | |
| 297 | + | |
| 298 | + skl->boot_complete = false; | |
| 299 | + init_waitqueue_head(&skl->boot_wait); | |
| 300 | + | |
| 301 | + ret = sst->fw_ops.load_fw(sst); | |
| 302 | + if (ret < 0) { | |
| 303 | + dev_err(dev, "Load base fw failed: %x", ret); | |
| 304 | + return ret; | |
| 305 | + } | |
| 306 | + | |
| 307 | + if (dsp) | |
| 308 | + *dsp = skl; | |
| 309 | + | |
| 310 | + return 0; | |
| 311 | +} | |
| 312 | +EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); | |
| 313 | + | |
| 314 | + | |
| 315 | +void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) | |
| 316 | +{ | |
| 317 | + skl_ipc_free(&ctx->ipc); | |
| 318 | + ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp); | |
| 319 | + | |
| 320 | + if (ctx->dsp->addr.lpe) | |
| 321 | + iounmap(ctx->dsp->addr.lpe); | |
| 322 | + | |
| 323 | + ctx->dsp->ops->free(ctx->dsp); | |
| 324 | +} | |
| 325 | +EXPORT_SYMBOL_GPL(bxt_sst_dsp_cleanup); | |
| 326 | + | |
| 327 | +MODULE_LICENSE("GPL v2"); | |
| 328 | +MODULE_DESCRIPTION("Intel Broxton IPC driver"); | |
| @@ -72,6 +72,105 @@ static void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable) · 71 unmodified lines | ||
| 72 | 72 | skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)&mask); |
| 73 | 73 | } |
| 74 | 74 | |
| 75 | +static int skl_dsp_setup_spib(struct device *dev, unsigned int size, | |
| 76 | + int stream_tag, int enable) | |
| 77 | +{ | |
| 78 | + struct hdac_ext_bus *ebus = dev_get_drvdata(dev); | |
| 79 | + struct hdac_bus *bus = ebus_to_hbus(ebus); | |
| 80 | + struct hdac_stream *stream = snd_hdac_get_stream(bus, | |
| 81 | + SNDRV_PCM_STREAM_PLAYBACK, stream_tag); | |
| 82 | + struct hdac_ext_stream *estream; | |
| 83 | + | |
| 84 | + if (!stream) | |
| 85 | + return -EINVAL; | |
| 86 | + | |
| 87 | + estream = stream_to_hdac_ext_stream(stream); | |
| 88 | + /* enable/disable SPIB for this hdac stream */ | |
| 89 | + snd_hdac_ext_stream_spbcap_enable(ebus, enable, stream->index); | |
| 90 | + | |
| 91 | + /* set the spib value */ | |
| 92 | + snd_hdac_ext_stream_set_spib(ebus, estream, size); | |
| 93 | + | |
| 94 | + return 0; | |
| 95 | +} | |
| 96 | + | |
| 97 | +static int skl_dsp_prepare(struct device *dev, unsigned int format, | |
| 98 | + unsigned int size, struct snd_dma_buffer *dmab) | |
| 99 | +{ | |
| 100 | + struct hdac_ext_bus *ebus = dev_get_drvdata(dev); | |
| 101 | + struct hdac_bus *bus = ebus_to_hbus(ebus); | |
| 102 | + struct hdac_ext_stream *estream; | |
| 103 | + struct hdac_stream *stream; | |
| 104 | + struct snd_pcm_substream substream; | |
| 105 | + int ret; | |
| 106 | + | |
| 107 | + if (!bus) | |
| 108 | + return -ENODEV; | |
| 109 | + | |
| 110 | + memset(&substream, 0, sizeof(substream)); | |
| 111 | + substream.stream = SNDRV_PCM_STREAM_PLAYBACK; | |
| 112 | + | |
| 113 | + estream = snd_hdac_ext_stream_assign(ebus, &substream, | |
| 114 | + HDAC_EXT_STREAM_TYPE_HOST); | |
| 115 | + if (!estream) | |
| 116 | + return -ENODEV; | |
| 117 | + | |
| 118 | + stream = hdac_stream(estream); | |
| 119 | + | |
| 120 | + /* assign decouple host dma channel */ | |
| 121 | + ret = snd_hdac_dsp_prepare(stream, format, size, dmab); | |
| 122 | + if (ret < 0) | |
| 123 | + return ret; | |
| 124 | + | |
| 125 | + skl_dsp_setup_spib(dev, size, stream->stream_tag, true); | |
| 126 | + | |
| 127 | + return stream->stream_tag; | |
| 128 | +} | |
| 129 | + | |
| 130 | +static int skl_dsp_trigger(struct device *dev, bool start, int stream_tag) | |
| 131 | +{ | |
| 132 | + struct hdac_ext_bus *ebus = dev_get_drvdata(dev); | |
| 133 | + struct hdac_stream *stream; | |
| 134 | + struct hdac_bus *bus = ebus_to_hbus(ebus); | |
| 135 | + | |
| 136 | + if (!bus) | |
| 137 | + return -ENODEV; | |
| 138 | + | |
| 139 | + stream = snd_hdac_get_stream(bus, | |
| 140 | + SNDRV_PCM_STREAM_PLAYBACK, stream_tag); | |
| 141 | + if (!stream) | |
| 142 | + return -EINVAL; | |
| 143 | + | |
| 144 | + snd_hdac_dsp_trigger(stream, start); | |
| 145 | + | |
| 146 | + return 0; | |
| 147 | +} | |
| 148 | + | |
| 149 | +static int skl_dsp_cleanup(struct device *dev, | |
| 150 | + struct snd_dma_buffer *dmab, int stream_tag) | |
| 151 | +{ | |
| 152 | + struct hdac_ext_bus *ebus = dev_get_drvdata(dev); | |
| 153 | + struct hdac_stream *stream; | |
| 154 | + struct hdac_ext_stream *estream; | |
| 155 | + struct hdac_bus *bus = ebus_to_hbus(ebus); | |
| 156 | + | |
| 157 | + if (!bus) | |
| 158 | + return -ENODEV; | |
| 159 | + | |
| 160 | + stream = snd_hdac_get_stream(bus, | |
| 161 | + SNDRV_PCM_STREAM_PLAYBACK, stream_tag); | |
| 162 | + if (!stream) | |
| 163 | + return -EINVAL; | |
| 164 | + | |
| 165 | + estream = stream_to_hdac_ext_stream(stream); | |
| 166 | + skl_dsp_setup_spib(dev, 0, stream_tag, false); | |
| 167 | + snd_hdac_ext_stream_release(estream, HDAC_EXT_STREAM_TYPE_HOST); | |
| 168 | + | |
| 169 | + snd_hdac_dsp_cleanup(stream, dmab); | |
| 170 | + | |
| 171 | + return 0; | |
| 172 | +} | |
| 173 | + | |
| 75 | 174 | static struct skl_dsp_loader_ops skl_get_loader_ops(void) |
| 76 | 175 | { |
| 77 | 176 | struct skl_dsp_loader_ops loader_ops; |
| @@ -84,6 +183,21 @@ static struct skl_dsp_loader_ops skl_get_loader_ops(void) · 6 unmodified lines | ||
| 84 | 183 | return loader_ops; |
| 85 | 184 | }; |
| 86 | 185 | |
| 186 | +static struct skl_dsp_loader_ops bxt_get_loader_ops(void) | |
| 187 | +{ | |
| 188 | + struct skl_dsp_loader_ops loader_ops; | |
| 189 | + | |
| 190 | + memset(&loader_ops, 0, sizeof(loader_ops)); | |
| 191 | + | |
| 192 | + loader_ops.alloc_dma_buf = skl_alloc_dma_buf; | |
| 193 | + loader_ops.free_dma_buf = skl_free_dma_buf; | |
| 194 | + loader_ops.prepare = skl_dsp_prepare; | |
| 195 | + loader_ops.trigger = skl_dsp_trigger; | |
| 196 | + loader_ops.cleanup = skl_dsp_cleanup; | |
| 197 | + | |
| 198 | + return loader_ops; | |
| 199 | +}; | |
| 200 | + | |
| 87 | 201 | static const struct skl_dsp_ops dsp_ops[] = { |
| 88 | 202 | { |
| 89 | 203 | .id = 0x9d70, |
| @@ -91,6 +205,12 @@ static const struct skl_dsp_ops dsp_ops[] = { · 1 unmodified line | ||
| 91 | 205 | .init = skl_sst_dsp_init, |
| 92 | 206 | .cleanup = skl_sst_dsp_cleanup |
| 93 | 207 | }, |
| 208 | + { | |
| 209 | + .id = 0x5a98, | |
| 210 | + .loader_ops = bxt_get_loader_ops, | |
| 211 | + .init = bxt_sst_dsp_init, | |
| 212 | + .cleanup = bxt_sst_dsp_cleanup | |
| 213 | + }, | |
| 94 | 214 | }; |
| 95 | 215 | |
| 96 | 216 | static int skl_get_dsp_ops(int pci_id) |
| @@ -744,7 +864,7 @@ int skl_init_module(struct skl_sst *ctx, · 647 unmodified lines | ||
| 744 | 864 | return ret; |
| 745 | 865 | } |
| 746 | 866 | mconfig->m_state = SKL_MODULE_INIT_DONE; |
| 747 | − | |
| 867 | + kfree(param_data); | |
| 748 | 868 | return ret; |
| 749 | 869 | } |
| 750 | 870 | |
| @@ -25,11 +25,12 @@ static u8 OSC_UUID[16] = {0x6E, 0x88, 0x9F, 0xA6, 0xEB, 0x6C, 0x94, 0x45, · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | #define DSDT_NHLT_PATH "\\_SB.PCI0.HDAS" |
| 27 | 27 | |
| 28 | −void *skl_nhlt_init(struct device *dev) | |
| 28 | +struct nhlt_acpi_table *skl_nhlt_init(struct device *dev) | |
| 29 | 29 | { |
| 30 | 30 | acpi_handle handle; |
| 31 | 31 | union acpi_object *obj; |
| 32 | 32 | struct nhlt_resource_desc *nhlt_ptr = NULL; |
| 33 | + struct nhlt_acpi_table *nhlt_table = NULL; | |
| 33 | 34 | |
| 34 | 35 | if (ACPI_FAILURE(acpi_get_handle(NULL, DSDT_NHLT_PATH, &handle))) { |
| 35 | 36 | dev_err(dev, "Requested NHLT device not found\n"); |
| @@ -39,18 +40,20 @@ void *skl_nhlt_init(struct device *dev) · 3 unmodified lines | ||
| 39 | 40 | obj = acpi_evaluate_dsm(handle, OSC_UUID, 1, 1, NULL); |
| 40 | 41 | if (obj && obj->type == ACPI_TYPE_BUFFER) { |
| 41 | 42 | nhlt_ptr = (struct nhlt_resource_desc *)obj->buffer.pointer; |
| 42 | − | |
| 43 | − return memremap(nhlt_ptr->min_addr, nhlt_ptr->length, | |
| 43 | + nhlt_table = (struct nhlt_acpi_table *) | |
| 44 | + memremap(nhlt_ptr->min_addr, nhlt_ptr->length, | |
| 44 | 45 | MEMREMAP_WB); |
| 46 | + ACPI_FREE(obj); | |
| 47 | + return nhlt_table; | |
| 45 | 48 | } |
| 46 | 49 | |
| 47 | 50 | dev_err(dev, "device specific method to extract NHLT blob failed\n"); |
| 48 | 51 | return NULL; |
| 49 | 52 | } |
| 50 | 53 | |
| 51 | −void skl_nhlt_free(void *addr) | |
| 54 | +void skl_nhlt_free(struct nhlt_acpi_table *nhlt) | |
| 52 | 55 | { |
| 53 | − memunmap(addr); | |
| 56 | + memunmap((void *) nhlt); | |
| 54 | 57 | } |
| 55 | 58 | |
| 56 | 59 | static struct nhlt_specific_cfg *skl_get_specific_cfg( |
| @@ -120,7 +123,7 @@ struct nhlt_specific_cfg · 63 unmodified lines | ||
| 120 | 123 | struct hdac_bus *bus = ebus_to_hbus(&skl->ebus); |
| 121 | 124 | struct device *dev = bus->dev; |
| 122 | 125 | struct nhlt_specific_cfg *sp_config; |
| 123 | − struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; | |
| 126 | + struct nhlt_acpi_table *nhlt = skl->nhlt; | |
| 124 | 127 | u16 bps = (s_fmt == 16) ? 16 : 32; |
| 125 | 128 | u8 j; |
| 126 | 129 | |
| @@ -51,7 +51,7 @@ static struct snd_pcm_hardware azx_pcm_hw = { · 50 unmodified lines | ||
| 51 | 51 | .rate_min = 8000, |
| 52 | 52 | .rate_max = 48000, |
| 53 | 53 | .channels_min = 1, |
| 54 | − .channels_max = HDA_QUAD, | |
| 54 | + .channels_max = 8, | |
| 55 | 55 | .buffer_bytes_max = AZX_MAX_BUF_SIZE, |
| 56 | 56 | .period_bytes_min = 128, |
| 57 | 57 | .period_bytes_max = AZX_MAX_BUF_SIZE / 2, |
| @@ -213,7 +213,7 @@ static int skl_be_prepare(struct snd_pcm_substream *substream, · 155 unmodified lines | ||
| 213 | 213 | struct skl_sst *ctx = skl->skl_sst; |
| 214 | 214 | struct skl_module_cfg *mconfig; |
| 215 | 215 | |
| 216 | − if ((dai->playback_active > 1) || (dai->capture_active > 1)) | |
| 216 | + if (dai->playback_widget->power || dai->capture_widget->power) | |
| 217 | 217 | return 0; |
| 218 | 218 | |
| 219 | 219 | mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream); |
| @@ -402,23 +402,33 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, · 182 unmodified lines | ||
| 402 | 402 | struct skl_module_cfg *mconfig; |
| 403 | 403 | struct hdac_ext_bus *ebus = get_bus_ctx(substream); |
| 404 | 404 | struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); |
| 405 | + struct snd_soc_dapm_widget *w; | |
| 405 | 406 | int ret; |
| 406 | 407 | |
| 407 | 408 | mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); |
| 408 | 409 | if (!mconfig) |
| 409 | 410 | return -EIO; |
| 410 | 411 | |
| 412 | + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | |
| 413 | + w = dai->playback_widget; | |
| 414 | + else | |
| 415 | + w = dai->capture_widget; | |
| 416 | + | |
| 411 | 417 | switch (cmd) { |
| 412 | 418 | case SNDRV_PCM_TRIGGER_RESUME: |
| 413 | − skl_pcm_prepare(substream, dai); | |
| 414 | − /* | |
| 415 | − * enable DMA Resume enable bit for the stream, set the dpib | |
| 416 | − * & lpib position to resune before starting the DMA | |
| 417 | − */ | |
| 418 | − snd_hdac_ext_stream_drsm_enable(ebus, true, | |
| 419 | − hdac_stream(stream)->index); | |
| 420 | − snd_hdac_ext_stream_set_dpibr(ebus, stream, stream->dpib); | |
| 421 | − snd_hdac_ext_stream_set_lpib(stream, stream->lpib); | |
| 419 | + if (!w->ignore_suspend) { | |
| 420 | + skl_pcm_prepare(substream, dai); | |
| 421 | + /* | |
| 422 | + * enable DMA Resume enable bit for the stream, set the | |
| 423 | + * dpib & lpib position to resume before starting the | |
| 424 | + * DMA | |
| 425 | + */ | |
| 426 | + snd_hdac_ext_stream_drsm_enable(ebus, true, | |
| 427 | + hdac_stream(stream)->index); | |
| 428 | + snd_hdac_ext_stream_set_dpibr(ebus, stream, | |
| 429 | + stream->dpib); | |
| 430 | + snd_hdac_ext_stream_set_lpib(stream, stream->lpib); | |
| 431 | + } | |
| 422 | 432 | |
| 423 | 433 | case SNDRV_PCM_TRIGGER_START: |
| 424 | 434 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
| @@ -448,7 +458,7 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, · 23 unmodified lines | ||
| 448 | 458 | return ret; |
| 449 | 459 | |
| 450 | 460 | ret = skl_decoupled_trigger(substream, cmd); |
| 451 | − if (cmd == SNDRV_PCM_TRIGGER_SUSPEND) { | |
| 461 | + if ((cmd == SNDRV_PCM_TRIGGER_SUSPEND) && !w->ignore_suspend) { | |
| 452 | 462 | /* save the dpib and lpib positions */ |
| 453 | 463 | stream->dpib = readl(ebus->bus.remap_addr + |
| 454 | 464 | AZX_REG_VS_SDXDPIB_XBASE + |
| @@ -523,7 +533,6 @@ static int skl_link_pcm_prepare(struct snd_pcm_substream *substream, · 68 unmodified lines | ||
| 523 | 533 | if (!link) |
| 524 | 534 | return -EINVAL; |
| 525 | 535 | |
| 526 | − snd_hdac_ext_bus_link_power_up(link); | |
| 527 | 536 | snd_hdac_ext_link_stream_reset(link_dev); |
| 528 | 537 | |
| 529 | 538 | snd_hdac_ext_link_stream_setup(link_dev, format_val); |
| @@ -682,7 +691,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { · 152 unmodified lines | ||
| 682 | 691 | .playback = { |
| 683 | 692 | .stream_name = "HDMI1 Playback", |
| 684 | 693 | .channels_min = HDA_STEREO, |
| 685 | − .channels_max = HDA_STEREO, | |
| 694 | + .channels_max = 8, | |
| 686 | 695 | .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | |
| 687 | 696 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | |
| 688 | 697 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | |
| @@ -697,7 +706,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { · 8 unmodified lines | ||
| 697 | 706 | .playback = { |
| 698 | 707 | .stream_name = "HDMI2 Playback", |
| 699 | 708 | .channels_min = HDA_STEREO, |
| 700 | − .channels_max = HDA_STEREO, | |
| 709 | + .channels_max = 8, | |
| 701 | 710 | .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | |
| 702 | 711 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | |
| 703 | 712 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | |
| @@ -712,7 +721,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { · 8 unmodified lines | ||
| 712 | 721 | .playback = { |
| 713 | 722 | .stream_name = "HDMI3 Playback", |
| 714 | 723 | .channels_min = HDA_STEREO, |
| 715 | − .channels_max = HDA_STEREO, | |
| 724 | + .channels_max = 8, | |
| 716 | 725 | .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | |
| 717 | 726 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | |
| 718 | 727 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | |
| @@ -759,13 +768,85 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { · 40 unmodified lines | ||
| 759 | 768 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
| 760 | 769 | }, |
| 761 | 770 | }, |
| 771 | +{ | |
| 772 | + .name = "SSP2 Pin", | |
| 773 | + .ops = &skl_be_ssp_dai_ops, | |
| 774 | + .playback = { | |
| 775 | + .stream_name = "ssp2 Tx", | |
| 776 | + .channels_min = HDA_STEREO, | |
| 777 | + .channels_max = HDA_STEREO, | |
| 778 | + .rates = SNDRV_PCM_RATE_48000, | |
| 779 | + .formats = SNDRV_PCM_FMTBIT_S16_LE, | |
| 780 | + }, | |
| 781 | + .capture = { | |
| 782 | + .stream_name = "ssp2 Rx", | |
| 783 | + .channels_min = HDA_STEREO, | |
| 784 | + .channels_max = HDA_STEREO, | |
| 785 | + .rates = SNDRV_PCM_RATE_48000, | |
| 786 | + .formats = SNDRV_PCM_FMTBIT_S16_LE, | |
| 787 | + }, | |
| 788 | +}, | |
| 789 | +{ | |
| 790 | + .name = "SSP3 Pin", | |
| 791 | + .ops = &skl_be_ssp_dai_ops, | |
| 792 | + .playback = { | |
| 793 | + .stream_name = "ssp3 Tx", | |
| 794 | + .channels_min = HDA_STEREO, | |
| 795 | + .channels_max = HDA_STEREO, | |
| 796 | + .rates = SNDRV_PCM_RATE_48000, | |
| 797 | + .formats = SNDRV_PCM_FMTBIT_S16_LE, | |
| 798 | + }, | |
| 799 | + .capture = { | |
| 800 | + .stream_name = "ssp3 Rx", | |
| 801 | + .channels_min = HDA_STEREO, | |
| 802 | + .channels_max = HDA_STEREO, | |
| 803 | + .rates = SNDRV_PCM_RATE_48000, | |
| 804 | + .formats = SNDRV_PCM_FMTBIT_S16_LE, | |
| 805 | + }, | |
| 806 | +}, | |
| 807 | +{ | |
| 808 | + .name = "SSP4 Pin", | |
| 809 | + .ops = &skl_be_ssp_dai_ops, | |
| 810 | + .playback = { | |
| 811 | + .stream_name = "ssp4 Tx", | |
| 812 | + .channels_min = HDA_STEREO, | |
| 813 | + .channels_max = HDA_STEREO, | |
| 814 | + .rates = SNDRV_PCM_RATE_48000, | |
| 815 | + .formats = SNDRV_PCM_FMTBIT_S16_LE, | |
| 816 | + }, | |
| 817 | + .capture = { | |
| 818 | + .stream_name = "ssp4 Rx", | |
| 819 | + .channels_min = HDA_STEREO, | |
| 820 | + .channels_max = HDA_STEREO, | |
| 821 | + .rates = SNDRV_PCM_RATE_48000, | |
| 822 | + .formats = SNDRV_PCM_FMTBIT_S16_LE, | |
| 823 | + }, | |
| 824 | +}, | |
| 825 | +{ | |
| 826 | + .name = "SSP5 Pin", | |
| 827 | + .ops = &skl_be_ssp_dai_ops, | |
| 828 | + .playback = { | |
| 829 | + .stream_name = "ssp5 Tx", | |
| 830 | + .channels_min = HDA_STEREO, | |
| 831 | + .channels_max = HDA_STEREO, | |
| 832 | + .rates = SNDRV_PCM_RATE_48000, | |
| 833 | + .formats = SNDRV_PCM_FMTBIT_S16_LE, | |
| 834 | + }, | |
| 835 | + .capture = { | |
| 836 | + .stream_name = "ssp5 Rx", | |
| 837 | + .channels_min = HDA_STEREO, | |
| 838 | + .channels_max = HDA_STEREO, | |
| 839 | + .rates = SNDRV_PCM_RATE_48000, | |
| 840 | + .formats = SNDRV_PCM_FMTBIT_S16_LE, | |
| 841 | + }, | |
| 842 | +}, | |
| 762 | 843 | { |
| 763 | 844 | .name = "iDisp1 Pin", |
| 764 | 845 | .ops = &skl_link_dai_ops, |
| 765 | 846 | .playback = { |
| 766 | 847 | .stream_name = "iDisp1 Tx", |
| 767 | 848 | .channels_min = HDA_STEREO, |
| 768 | − .channels_max = HDA_STEREO, | |
| 849 | + .channels_max = 8, | |
| 769 | 850 | .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_48000, |
| 770 | 851 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE | |
| 771 | 852 | SNDRV_PCM_FMTBIT_S24_LE, |
| @@ -777,7 +858,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { · 5 unmodified lines | ||
| 777 | 858 | .playback = { |
| 778 | 859 | .stream_name = "iDisp2 Tx", |
| 779 | 860 | .channels_min = HDA_STEREO, |
| 780 | − .channels_max = HDA_STEREO, | |
| 861 | + .channels_max = 8, | |
| 781 | 862 | .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000| |
| 782 | 863 | SNDRV_PCM_RATE_48000, |
| 783 | 864 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE | |
| @@ -790,7 +871,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { · 6 unmodified lines | ||
| 790 | 871 | .playback = { |
| 791 | 872 | .stream_name = "iDisp3 Tx", |
| 792 | 873 | .channels_min = HDA_STEREO, |
| 793 | − .channels_max = HDA_STEREO, | |
| 874 | + .channels_max = 8, | |
| 794 | 875 | .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000| |
| 795 | 876 | SNDRV_PCM_RATE_48000, |
| 796 | 877 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE | |
| @@ -336,8 +336,6 @@ void skl_dsp_free(struct sst_dsp *dsp) · 335 unmodified lines | ||
| 336 | 336 | skl_ipc_int_disable(dsp); |
| 337 | 337 | |
| 338 | 338 | free_irq(dsp->irq, dsp); |
| 339 | − dsp->cl_dev.ops.cl_cleanup_controller(dsp); | |
| 340 | − skl_cldma_int_disable(dsp); | |
| 341 | 339 | skl_ipc_op_int_disable(dsp); |
| 342 | 340 | skl_ipc_int_disable(dsp); |
| 343 | 341 | |
| @@ -118,16 +118,25 @@ struct skl_dsp_fw_ops { · 117 unmodified lines | ||
| 118 | 118 | int (*set_state_D0)(struct sst_dsp *ctx); |
| 119 | 119 | int (*set_state_D3)(struct sst_dsp *ctx); |
| 120 | 120 | unsigned int (*get_fw_errcode)(struct sst_dsp *ctx); |
| 121 | − int (*load_mod)(struct sst_dsp *ctx, u16 mod_id, char *mod_name); | |
| 121 | + int (*load_mod)(struct sst_dsp *ctx, u16 mod_id, u8 *mod_name); | |
| 122 | 122 | int (*unload_mod)(struct sst_dsp *ctx, u16 mod_id); |
| 123 | 123 | |
| 124 | 124 | }; |
| 125 | 125 | |
| 126 | 126 | struct skl_dsp_loader_ops { |
| 127 | + int stream_tag; | |
| 128 | + | |
| 127 | 129 | int (*alloc_dma_buf)(struct device *dev, |
| 128 | 130 | struct snd_dma_buffer *dmab, size_t size); |
| 129 | 131 | int (*free_dma_buf)(struct device *dev, |
| 130 | 132 | struct snd_dma_buffer *dmab); |
| 133 | + int (*prepare)(struct device *dev, unsigned int format, | |
| 134 | + unsigned int byte_size, | |
| 135 | + struct snd_dma_buffer *bufp); | |
| 136 | + int (*trigger)(struct device *dev, bool start, int stream_tag); | |
| 137 | + | |
| 138 | + int (*cleanup)(struct device *dev, struct snd_dma_buffer *dmab, | |
| 139 | + int stream_tag); | |
| 131 | 140 | }; |
| 132 | 141 | |
| 133 | 142 | struct skl_load_module_info { |
| @@ -160,6 +169,10 @@ int skl_dsp_boot(struct sst_dsp *ctx); · 26 unmodified lines | ||
| 160 | 169 | int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, |
| 161 | 170 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, |
| 162 | 171 | struct skl_sst **dsp); |
| 172 | +int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | |
| 173 | + const char *fw_name, struct skl_dsp_loader_ops dsp_ops, | |
| 174 | + struct skl_sst **dsp); | |
| 163 | 175 | void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); |
| 176 | +void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); | |
| 164 | 177 | |
| 165 | 178 | #endif /*__SKL_SST_DSP_H__*/ |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <linux/delay.h> |
| 21 | 21 | #include <linux/device.h> |
| 22 | 22 | #include <linux/err.h> |
| 23 | +#include <linux/uuid.h> | |
| 23 | 24 | #include "../common/sst-dsp.h" |
| 24 | 25 | #include "../common/sst-dsp-priv.h" |
| 25 | 26 | #include "../common/sst-ipc.h" |
| @@ -304,14 +305,16 @@ static int skl_transfer_module(struct sst_dsp *ctx, · 278 unmodified lines | ||
| 304 | 305 | return ret; |
| 305 | 306 | } |
| 306 | 307 | |
| 307 | −static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, char *guid) | |
| 308 | +static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid) | |
| 308 | 309 | { |
| 309 | 310 | struct skl_module_table *module_entry = NULL; |
| 310 | 311 | int ret = 0; |
| 311 | 312 | char mod_name[64]; /* guid str = 32 chars + 4 hyphens */ |
| 313 | + uuid_le *uuid_mod; | |
| 312 | 314 | |
| 313 | − snprintf(mod_name, sizeof(mod_name), "%s%s%s", | |
| 314 | − "intel/dsp_fw_", guid, ".bin"); | |
| 315 | + uuid_mod = (uuid_le *)guid; | |
| 316 | + snprintf(mod_name, sizeof(mod_name), "%s%pUL%s", | |
| 317 | + "intel/dsp_fw_", uuid_mod, ".bin"); | |
| 315 | 318 | |
| 316 | 319 | module_entry = skl_module_get_from_id(ctx, mod_id); |
| 317 | 320 | if (module_entry == NULL) { |
| @@ -451,6 +454,10 @@ void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) · 133 unmodified lines | ||
| 451 | 454 | skl_clear_module_table(ctx->dsp); |
| 452 | 455 | skl_ipc_free(&ctx->ipc); |
| 453 | 456 | ctx->dsp->ops->free(ctx->dsp); |
| 457 | + if (ctx->boot_complete) { | |
| 458 | + ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp); | |
| 459 | + skl_cldma_int_disable(ctx->dsp); | |
| 460 | + } | |
| 454 | 461 | } |
| 455 | 462 | EXPORT_SYMBOL_GPL(skl_sst_dsp_cleanup); |
| 456 | 463 | |
| @@ -154,13 +154,32 @@ static void skl_dump_mconfig(struct skl_sst *ctx, · 153 unmodified lines | ||
| 154 | 154 | dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->out_fmt[0].ch_cfg); |
| 155 | 155 | } |
| 156 | 156 | |
| 157 | +static void skl_tplg_update_chmap(struct skl_module_fmt *fmt, int chs) | |
| 158 | +{ | |
| 159 | + int slot_map = 0xFFFFFFFF; | |
| 160 | + int start_slot = 0; | |
| 161 | + int i; | |
| 162 | + | |
| 163 | + for (i = 0; i < chs; i++) { | |
| 164 | + /* | |
| 165 | + * For 2 channels with starting slot as 0, slot map will | |
| 166 | + * look like 0xFFFFFF10. | |
| 167 | + */ | |
| 168 | + slot_map &= (~(0xF << (4 * i)) | (start_slot << (4 * i))); | |
| 169 | + start_slot++; | |
| 170 | + } | |
| 171 | + fmt->ch_map = slot_map; | |
| 172 | +} | |
| 173 | + | |
| 157 | 174 | static void skl_tplg_update_params(struct skl_module_fmt *fmt, |
| 158 | 175 | struct skl_pipe_params *params, int fixup) |
| 159 | 176 | { |
| 160 | 177 | if (fixup & SKL_RATE_FIXUP_MASK) |
| 161 | 178 | fmt->s_freq = params->s_freq; |
| 162 | − if (fixup & SKL_CH_FIXUP_MASK) | |
| 179 | + if (fixup & SKL_CH_FIXUP_MASK) { | |
| 163 | 180 | fmt->channels = params->ch; |
| 181 | + skl_tplg_update_chmap(fmt, fmt->channels); | |
| 182 | + } | |
| 164 | 183 | if (fixup & SKL_FMT_FIXUP_MASK) { |
| 165 | 184 | fmt->valid_bit_depth = skl_get_bit_depth(params->s_fmt); |
| 166 | 185 | |
| @@ -1564,6 +1583,8 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, · 1397 unmodified lines | ||
| 1564 | 1583 | return -ENOMEM; |
| 1565 | 1584 | |
| 1566 | 1585 | w->priv = mconfig; |
| 1586 | + memcpy(&mconfig->guid, &dfw_config->uuid, 16); | |
| 1587 | + | |
| 1567 | 1588 | mconfig->id.module_id = dfw_config->module_id; |
| 1568 | 1589 | mconfig->id.instance_id = dfw_config->instance_id; |
| 1569 | 1590 | mconfig->mcps = dfw_config->max_mcps; |
| @@ -1593,10 +1614,6 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, · 23 unmodified lines | ||
| 1593 | 1614 | mconfig->time_slot = dfw_config->time_slot; |
| 1594 | 1615 | mconfig->formats_config.caps_size = dfw_config->caps.caps_size; |
| 1595 | 1616 | |
| 1596 | − if (dfw_config->is_loadable) | |
| 1597 | − memcpy(mconfig->guid, dfw_config->uuid, | |
| 1598 | − ARRAY_SIZE(dfw_config->uuid)); | |
| 1599 | − | |
| 1600 | 1617 | mconfig->m_in_pin = devm_kzalloc(bus->dev, (mconfig->max_in_queue) * |
| 1601 | 1618 | sizeof(*mconfig->m_in_pin), |
| 1602 | 1619 | GFP_KERNEL); |
| @@ -281,7 +281,7 @@ enum skl_module_state { · 280 unmodified lines | ||
| 281 | 281 | }; |
| 282 | 282 | |
| 283 | 283 | struct skl_module_cfg { |
| 284 | − char guid[SKL_UUID_STR_SZ]; | |
| 284 | + u8 guid[16]; | |
| 285 | 285 | struct skl_module_inst_id id; |
| 286 | 286 | u8 domain; |
| 287 | 287 | bool homogenous_inputs; |
| @@ -181,7 +181,7 @@ struct skl_dfw_pipe { · 180 unmodified lines | ||
| 181 | 181 | } __packed; |
| 182 | 182 | |
| 183 | 183 | struct skl_dfw_module { |
| 184 | − char uuid[SKL_UUID_STR_SZ]; | |
| 184 | + u8 uuid[16]; | |
| 185 | 185 | |
| 186 | 186 | u16 module_id; |
| 187 | 187 | u16 instance_id; |
| @@ -229,7 +229,12 @@ static int skl_suspend(struct device *dev) · 228 unmodified lines | ||
| 229 | 229 | * running, we need to save the state for these and continue |
| 230 | 230 | */ |
| 231 | 231 | if (skl->supend_active) { |
| 232 | + /* turn off the links and stop the CORB/RIRB DMA if it is On */ | |
| 232 | 233 | snd_hdac_ext_bus_link_power_down_all(ebus); |
| 234 | + | |
| 235 | + if (ebus->cmd_dma_state) | |
| 236 | + snd_hdac_bus_stop_cmd_io(&ebus->bus); | |
| 237 | + | |
| 233 | 238 | enable_irq_wake(bus->irq); |
| 234 | 239 | pci_save_state(pci); |
| 235 | 240 | pci_disable_device(pci); |
| @@ -255,6 +260,7 @@ static int skl_resume(struct device *dev) · 19 unmodified lines | ||
| 255 | 260 | struct hdac_ext_bus *ebus = pci_get_drvdata(pci); |
| 256 | 261 | struct skl *skl = ebus_to_skl(ebus); |
| 257 | 262 | struct hdac_bus *bus = ebus_to_hbus(ebus); |
| 263 | + struct hdac_ext_link *hlink = NULL; | |
| 258 | 264 | int ret; |
| 259 | 265 | |
| 260 | 266 | /* Turned OFF in HDMI codec driver after codec reconfiguration */ |
| @@ -276,8 +282,29 @@ static int skl_resume(struct device *dev) · 15 unmodified lines | ||
| 276 | 282 | ret = pci_enable_device(pci); |
| 277 | 283 | snd_hdac_ext_bus_link_power_up_all(ebus); |
| 278 | 284 | disable_irq_wake(bus->irq); |
| 285 | + /* | |
| 286 | + * turn On the links which are On before active suspend | |
| 287 | + * and start the CORB/RIRB DMA if On before | |
| 288 | + * active suspend. | |
| 289 | + */ | |
| 290 | + list_for_each_entry(hlink, &ebus->hlink_list, list) { | |
| 291 | + if (hlink->ref_count) | |
| 292 | + snd_hdac_ext_bus_link_power_up(hlink); | |
| 293 | + } | |
| 294 | + | |
| 295 | + if (ebus->cmd_dma_state) | |
| 296 | + snd_hdac_bus_init_cmd_io(&ebus->bus); | |
| 279 | 297 | } else { |
| 280 | 298 | ret = _skl_resume(ebus); |
| 299 | + | |
| 300 | + /* turn off the links which are off before suspend */ | |
| 301 | + list_for_each_entry(hlink, &ebus->hlink_list, list) { | |
| 302 | + if (!hlink->ref_count) | |
| 303 | + snd_hdac_ext_bus_link_power_down(hlink); | |
| 304 | + } | |
| 305 | + | |
| 306 | + if (!ebus->cmd_dma_state) | |
| 307 | + snd_hdac_bus_stop_cmd_io(&ebus->bus); | |
| 281 | 308 | } |
| 282 | 309 | |
| 283 | 310 | return ret; |
| @@ -613,6 +640,7 @@ static int skl_probe(struct pci_dev *pci, · 329 unmodified lines | ||
| 613 | 640 | struct skl *skl; |
| 614 | 641 | struct hdac_ext_bus *ebus = NULL; |
| 615 | 642 | struct hdac_bus *bus = NULL; |
| 643 | + struct hdac_ext_link *hlink = NULL; | |
| 616 | 644 | int err; |
| 617 | 645 | |
| 618 | 646 | /* we use ext core ops, so provide NULL for ops here */ |
| @@ -643,7 +671,7 @@ static int skl_probe(struct pci_dev *pci, · 24 unmodified lines | ||
| 643 | 671 | err = skl_machine_device_register(skl, |
| 644 | 672 | (void *)pci_id->driver_data); |
| 645 | 673 | if (err < 0) |
| 646 | − goto out_free; | |
| 674 | + goto out_nhlt_free; | |
| 647 | 675 | |
| 648 | 676 | err = skl_init_dsp(skl); |
| 649 | 677 | if (err < 0) { |
| @@ -679,6 +707,12 @@ static int skl_probe(struct pci_dev *pci, · 29 unmodified lines | ||
| 679 | 707 | } |
| 680 | 708 | } |
| 681 | 709 | |
| 710 | + /* | |
| 711 | + * we are done probling so decrement link counts | |
| 712 | + */ | |
| 713 | + list_for_each_entry(hlink, &ebus->hlink_list, list) | |
| 714 | + snd_hdac_ext_bus_link_put(ebus, hlink); | |
| 715 | + | |
| 682 | 716 | /*configure PM */ |
| 683 | 717 | pm_runtime_put_noidle(bus->dev); |
| 684 | 718 | pm_runtime_allow(bus->dev); |
| @@ -693,6 +727,8 @@ out_dsp_free: · 8 unmodified lines | ||
| 693 | 727 | skl_free_dsp(skl); |
| 694 | 728 | out_mach_free: |
| 695 | 729 | skl_machine_device_unregister(skl); |
| 730 | +out_nhlt_free: | |
| 731 | + skl_nhlt_free(skl->nhlt); | |
| 696 | 732 | out_free: |
| 697 | 733 | skl->init_failed = 1; |
| 698 | 734 | skl_free(ebus); |
| @@ -743,6 +779,7 @@ static void skl_remove(struct pci_dev *pci) · 44 unmodified lines | ||
| 743 | 779 | skl_free_dsp(skl); |
| 744 | 780 | skl_machine_device_unregister(skl); |
| 745 | 781 | skl_dmic_device_unregister(skl); |
| 782 | + skl_nhlt_free(skl->nhlt); | |
| 746 | 783 | skl_free(ebus); |
| 747 | 784 | dev_set_drvdata(&pci->dev, NULL); |
| 748 | 785 | } |
| @@ -66,7 +66,7 @@ struct skl { · 65 unmodified lines | ||
| 66 | 66 | struct platform_device *dmic_dev; |
| 67 | 67 | struct platform_device *i2s_dev; |
| 68 | 68 | |
| 69 | − void *nhlt; /* nhlt ptr */ | |
| 69 | + struct nhlt_acpi_table *nhlt; /* nhlt ptr */ | |
| 70 | 70 | struct skl_sst *skl_sst; /* sst skl ctx */ |
| 71 | 71 | |
| 72 | 72 | struct skl_dsp_resource resource; |
| @@ -103,8 +103,8 @@ struct skl_dsp_ops { · 30 unmodified lines | ||
| 103 | 103 | int skl_platform_unregister(struct device *dev); |
| 104 | 104 | int skl_platform_register(struct device *dev); |
| 105 | 105 | |
| 106 | −void *skl_nhlt_init(struct device *dev); | |
| 107 | −void skl_nhlt_free(void *addr); | |
| 106 | +struct nhlt_acpi_table *skl_nhlt_init(struct device *dev); | |
| 107 | +void skl_nhlt_free(struct nhlt_acpi_table *addr); | |
| 108 | 108 | struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance, |
| 109 | 109 | u8 link_type, u8 s_fmt, u8 no_ch, u32 s_rate, u8 dirn); |
| 110 | 110 | |
| @@ -34,6 +34,13 @@ struct rk_i2s_dev { · 33 unmodified lines | ||
| 34 | 34 | |
| 35 | 35 | struct regmap *regmap; |
| 36 | 36 | |
| 37 | +/* | |
| 38 | + * Used to indicate the tx/rx status. | |
| 39 | + * I2S controller hopes to start the tx and rx together, | |
| 40 | + * also to stop them when they are both try to stop. | |
| 41 | +*/ | |
| 42 | + bool tx_start; | |
| 43 | + bool rx_start; | |
| 37 | 44 | bool is_master_mode; |
| 38 | 45 | }; |
| 39 | 46 | |
| @@ -75,29 +82,37 @@ static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) · 35 unmodified lines | ||
| 75 | 82 | I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE); |
| 76 | 83 | |
| 77 | 84 | regmap_update_bits(i2s->regmap, I2S_XFER, |
| 78 | − I2S_XFER_TXS_START, | |
| 79 | − I2S_XFER_TXS_START); | |
| 85 | + I2S_XFER_TXS_START | I2S_XFER_RXS_START, | |
| 86 | + I2S_XFER_TXS_START | I2S_XFER_RXS_START); | |
| 87 | + | |
| 88 | + i2s->tx_start = true; | |
| 80 | 89 | } else { |
| 90 | + i2s->tx_start = false; | |
| 91 | + | |
| 81 | 92 | regmap_update_bits(i2s->regmap, I2S_DMACR, |
| 82 | 93 | I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE); |
| 83 | 94 | |
| 84 | − regmap_update_bits(i2s->regmap, I2S_XFER, | |
| 85 | − I2S_XFER_TXS_START, | |
| 86 | − I2S_XFER_TXS_STOP); | |
| 95 | + if (!i2s->rx_start) { | |
| 96 | + regmap_update_bits(i2s->regmap, I2S_XFER, | |
| 97 | + I2S_XFER_TXS_START | | |
| 98 | + I2S_XFER_RXS_START, | |
| 99 | + I2S_XFER_TXS_STOP | | |
| 100 | + I2S_XFER_RXS_STOP); | |
| 87 | 101 | |
| 88 | − regmap_update_bits(i2s->regmap, I2S_CLR, | |
| 89 | − I2S_CLR_TXC, | |
| 90 | − I2S_CLR_TXC); | |
| 102 | + regmap_update_bits(i2s->regmap, I2S_CLR, | |
| 103 | + I2S_CLR_TXC | I2S_CLR_RXC, | |
| 104 | + I2S_CLR_TXC | I2S_CLR_RXC); | |
| 91 | 105 | |
| 92 | − regmap_read(i2s->regmap, I2S_CLR, &val); | |
| 93 | − | |
| 94 | − /* Should wait for clear operation to finish */ | |
| 95 | − while (val & I2S_CLR_TXC) { | |
| 96 | 106 | regmap_read(i2s->regmap, I2S_CLR, &val); |
| 97 | − retry--; | |
| 98 | − if (!retry) { | |
| 99 | − dev_warn(i2s->dev, "fail to clear\n"); | |
| 100 | − break; | |
| 107 | + | |
| 108 | + /* Should wait for clear operation to finish */ | |
| 109 | + while (val) { | |
| 110 | + regmap_read(i2s->regmap, I2S_CLR, &val); | |
| 111 | + retry--; | |
| 112 | + if (!retry) { | |
| 113 | + dev_warn(i2s->dev, "fail to clear\n"); | |
| 114 | + break; | |
| 115 | + } | |
| 101 | 116 | } |
| 102 | 117 | } |
| 103 | 118 | } |
| @@ -113,29 +128,37 @@ static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) · 9 unmodified lines | ||
| 113 | 128 | I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE); |
| 114 | 129 | |
| 115 | 130 | regmap_update_bits(i2s->regmap, I2S_XFER, |
| 116 | − I2S_XFER_RXS_START, | |
| 117 | − I2S_XFER_RXS_START); | |
| 131 | + I2S_XFER_TXS_START | I2S_XFER_RXS_START, | |
| 132 | + I2S_XFER_TXS_START | I2S_XFER_RXS_START); | |
| 133 | + | |
| 134 | + i2s->rx_start = true; | |
| 118 | 135 | } else { |
| 136 | + i2s->rx_start = false; | |
| 137 | + | |
| 119 | 138 | regmap_update_bits(i2s->regmap, I2S_DMACR, |
| 120 | 139 | I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE); |
| 121 | 140 | |
| 122 | − regmap_update_bits(i2s->regmap, I2S_XFER, | |
| 123 | − I2S_XFER_RXS_START, | |
| 124 | − I2S_XFER_RXS_STOP); | |
| 141 | + if (!i2s->tx_start) { | |
| 142 | + regmap_update_bits(i2s->regmap, I2S_XFER, | |
| 143 | + I2S_XFER_TXS_START | | |
| 144 | + I2S_XFER_RXS_START, | |
| 145 | + I2S_XFER_TXS_STOP | | |
| 146 | + I2S_XFER_RXS_STOP); | |
| 125 | 147 | |
| 126 | − regmap_update_bits(i2s->regmap, I2S_CLR, | |
| 127 | − I2S_CLR_RXC, | |
| 128 | − I2S_CLR_RXC); | |
| 148 | + regmap_update_bits(i2s->regmap, I2S_CLR, | |
| 149 | + I2S_CLR_TXC | I2S_CLR_RXC, | |
| 150 | + I2S_CLR_TXC | I2S_CLR_RXC); | |
| 129 | 151 | |
| 130 | − regmap_read(i2s->regmap, I2S_CLR, &val); | |
| 131 | − | |
| 132 | − /* Should wait for clear operation to finish */ | |
| 133 | − while (val & I2S_CLR_RXC) { | |
| 134 | 152 | regmap_read(i2s->regmap, I2S_CLR, &val); |
| 135 | − retry--; | |
| 136 | − if (!retry) { | |
| 137 | − dev_warn(i2s->dev, "fail to clear\n"); | |
| 138 | − break; | |
| 153 | + | |
| 154 | + /* Should wait for clear operation to finish */ | |
| 155 | + while (val) { | |
| 156 | + regmap_read(i2s->regmap, I2S_CLR, &val); | |
| 157 | + retry--; | |
| 158 | + if (!retry) { | |
| 159 | + dev_warn(i2s->dev, "fail to clear\n"); | |
| 160 | + break; | |
| 161 | + } | |
| 139 | 162 | } |
| 140 | 163 | } |
| 141 | 164 | } |
| @@ -930,7 +930,18 @@ static struct snd_soc_component *soc_find_component( · 929 unmodified lines | ||
| 930 | 930 | return NULL; |
| 931 | 931 | } |
| 932 | 932 | |
| 933 | −static struct snd_soc_dai *snd_soc_find_dai( | |
| 933 | +/** | |
| 934 | + * snd_soc_find_dai - Find a registered DAI | |
| 935 | + * | |
| 936 | + * @dlc: name of the DAI and optional component info to match | |
| 937 | + * | |
| 938 | + * This function will search all regsitered components and their DAIs to | |
| 939 | + * find the DAI of the same name. The component's of_node and name | |
| 940 | + * should also match if being specified. | |
| 941 | + * | |
| 942 | + * Return: pointer of DAI, or NULL if not found. | |
| 943 | + */ | |
| 944 | +struct snd_soc_dai *snd_soc_find_dai( | |
| 934 | 945 | const struct snd_soc_dai_link_component *dlc) |
| 935 | 946 | { |
| 936 | 947 | struct snd_soc_component *component; |
| @@ -959,6 +970,7 @@ static struct snd_soc_dai *snd_soc_find_dai( · 22 unmodified lines | ||
| 959 | 970 | |
| 960 | 971 | return NULL; |
| 961 | 972 | } |
| 973 | +EXPORT_SYMBOL_GPL(snd_soc_find_dai); | |
| 962 | 974 | |
| 963 | 975 | static bool soc_is_dai_link_bound(struct snd_soc_card *card, |
| 964 | 976 | struct snd_soc_dai_link *dai_link) |
| @@ -163,31 +163,42 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea · 162 unmodified lines | ||
| 163 | 163 | } |
| 164 | 164 | |
| 165 | 165 | /* |
| 166 | − * Prepare formats mask for valid/allowed sample types. If the dma does | |
| 167 | − * not have support for the given physical word size, it needs to be | |
| 168 | − * masked out so user space can not use the format which produces | |
| 169 | − * corrupted audio. | |
| 170 | − * In case the dma driver does not implement the slave_caps the default | |
| 171 | − * assumption is that it supports 1, 2 and 4 bytes widths. | |
| 166 | + * If SND_DMAENGINE_PCM_DAI_FLAG_PACK is set keep | |
| 167 | + * hw.formats set to 0, meaning no restrictions are in place. | |
| 168 | + * In this case it's the responsibility of the DAI driver to | |
| 169 | + * provide the supported format information. | |
| 172 | 170 | */ |
| 173 | − for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) { | |
| 174 | − int bits = snd_pcm_format_physical_width(i); | |
| 175 | − | |
| 176 | − /* Enable only samples with DMA supported physical widths */ | |
| 177 | − switch (bits) { | |
| 178 | − case 8: | |
| 179 | − case 16: | |
| 180 | − case 24: | |
| 181 | − case 32: | |
| 182 | − case 64: | |
| 183 | − if (addr_widths & (1 << (bits / 8))) | |
| 184 | − hw.formats |= (1LL << i); | |
| 185 | − break; | |
| 186 | − default: | |
| 187 | − /* Unsupported types */ | |
| 188 | − break; | |
| 171 | + if (!(dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK)) | |
| 172 | + /* | |
| 173 | + * Prepare formats mask for valid/allowed sample types. If the | |
| 174 | + * dma does not have support for the given physical word size, | |
| 175 | + * it needs to be masked out so user space can not use the | |
| 176 | + * format which produces corrupted audio. | |
| 177 | + * In case the dma driver does not implement the slave_caps the | |
| 178 | + * default assumption is that it supports 1, 2 and 4 bytes | |
| 179 | + * widths. | |
| 180 | + */ | |
| 181 | + for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) { | |
| 182 | + int bits = snd_pcm_format_physical_width(i); | |
| 183 | + | |
| 184 | + /* | |
| 185 | + * Enable only samples with DMA supported physical | |
| 186 | + * widths | |
| 187 | + */ | |
| 188 | + switch (bits) { | |
| 189 | + case 8: | |
| 190 | + case 16: | |
| 191 | + case 24: | |
| 192 | + case 32: | |
| 193 | + case 64: | |
| 194 | + if (addr_widths & (1 << (bits / 8))) | |
| 195 | + hw.formats |= (1LL << i); | |
| 196 | + break; | |
| 197 | + default: | |
| 198 | + /* Unsupported types */ | |
| 199 | + break; | |
| 200 | + } | |
| 189 | 201 | } |
| 190 | − } | |
| 191 | 202 | |
| 192 | 203 | return snd_soc_set_runtime_hwparams(substream, &hw); |
| 193 | 204 | } |