Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'dmaengine-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine

Pull dmaengine updates from Vinod Koul:
"New support:

- Apple admac t8112 device support

- StarFive JH7110 DMA controller

Updates:

- Big pile of idxd updates to support IAA 2.0 device capabilities,
DSA 2.0 Event Log and completion record faulting features and
new DSA operations

- at_xdmac supend & resume updates and driver code cleanup

- k3-udma supend & resume support

- k3-psil thread support for J784s4"

* tag 'dmaengine-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine: (57 commits)
dmaengine: idxd: add per wq PRS disable
dmaengine: idxd: add pid to exported sysfs attribute for opened file
dmaengine: idxd: expose fault counters to sysfs
dmaengine: idxd: add a device to represent the file opened
dmaengine: idxd: add per file user counters for completion record faults
dmaengine: idxd: process batch descriptor completion record faults
dmaengine: idxd: add descs_completed field for completion record
dmaengine: idxd: process user page faults for completion record
dmaengine: idxd: add idxd_copy_cr() to copy user completion record during page fault handling
dmaengine: idxd: create kmem cache for event log fault items
dmaengine: idxd: add per DSA wq workqueue for processing cr faults
dmanegine: idxd: add debugfs for event log dump
dmaengine: idxd: add interrupt handling for event log
dmaengine: idxd: setup event log configuration
dmaengine: idxd: add event log size sysfs attribute
dmaengine: idxd: make misc interrupt one shot
dt-bindings: dma: snps,dw-axi-dmac: constrain the items of resets for JH7110 dma
dt-bindings: dma: Drop unneeded quotes
dmaengine: at_xdmac: align declaration of ret with the rest of variables
dmaengine: at_xdmac: add a warning message regarding for unpaused channels
...

+1863 -260
+51
Documentation/ABI/stable/sysfs-driver-dma-idxd
··· 136 136 Also last configuration error overloaded. 137 137 Writing to it will clear the status. 138 138 139 + What: /sys/bus/dsa/devices/dsa<m>/iaa_cap 140 + Date: Sept 14, 2022 141 + KernelVersion: 6.0.0 142 + Contact: dmaengine@vger.kernel.org 143 + Description: IAA (IAX) capability mask. Exported to user space for application 144 + consumption. This attribute should only be visible on IAA devices 145 + that are version 2 or later. 146 + 147 + What: /sys/bus/dsa/devices/dsa<m>/event_log_size 148 + Date: Sept 14, 2022 149 + KernelVersion: 6.4.0 150 + Contact: dmaengine@vger.kernel.org 151 + Description: The event log size to be configured. Default is 64 entries and 152 + occupies 4k size if the evl entry is 64 bytes. It's visible 153 + only on platforms that support the capability. 154 + 139 155 What: /sys/bus/dsa/devices/wq<m>.<n>/block_on_fault 140 156 Date: Oct 27, 2020 141 157 KernelVersion: 5.11.0 ··· 234 218 Contact: dmaengine@vger.kernel.org 235 219 Description: Indicate whether ATS disable is turned on for the workqueue. 236 220 0 indicates ATS is on, and 1 indicates ATS is off for the workqueue. 221 + 222 + What: /sys/bus/dsa/devices/wq<m>.<n>/prs_disable 223 + Date: Sept 14, 2022 224 + KernelVersion: 6.4.0 225 + Contact: dmaengine@vger.kernel.org 226 + Description: Controls whether PRS disable is turned on for the workqueue. 227 + 0 indicates PRS is on, and 1 indicates PRS is off for the 228 + workqueue. This option overrides block_on_fault attribute 229 + if set. It's visible only on platforms that support the 230 + capability. 237 231 238 232 What: /sys/bus/dsa/devices/wq<m>.<n>/occupancy 239 233 Date May 25, 2021 ··· 328 302 1 (1/2 of max value), 2 (1/4 of the max value), and 3 (1/8 of 329 303 the max value). It's visible only on platforms that support 330 304 the capability. 305 + 306 + What: /sys/bus/dsa/devices/wq<m>.<n>/dsa<x>\!wq<m>.<n>/file<y>/cr_faults 307 + Date: Sept 14, 2022 308 + KernelVersion: 6.4.0 309 + Contact: dmaengine@vger.kernel.org 310 + Description: Show the number of Completion Record (CR) faults this application 311 + has caused. 312 + 313 + What: /sys/bus/dsa/devices/wq<m>.<n>/dsa<x>\!wq<m>.<n>/file<y>/cr_fault_failures 314 + Date: Sept 14, 2022 315 + KernelVersion: 6.4.0 316 + Contact: dmaengine@vger.kernel.org 317 + Description: Show the number of Completion Record (CR) faults failures that this 318 + application has caused. The failure counter is incremented when the 319 + driver cannot fault in the address for the CR. Typically this is caused 320 + by a bad address programmed in the submitted descriptor or a malicious 321 + submitter is using bad CR address on purpose. 322 + 323 + What: /sys/bus/dsa/devices/wq<m>.<n>/dsa<x>\!wq<m>.<n>/file<y>/pid 324 + Date: Sept 14, 2022 325 + KernelVersion: 6.4.0 326 + Contact: dmaengine@vger.kernel.org 327 + Description: Show the process id of the application that opened the file. This is 328 + helpful information for a monitor daemon that wants to kill the 329 + application that opened the file.
+1
Documentation/devicetree/bindings/dma/apple,admac.yaml
··· 26 26 - enum: 27 27 - apple,t6000-admac 28 28 - apple,t8103-admac 29 + - apple,t8112-admac 29 30 - const: apple,admac 30 31 31 32 reg:
+1
Documentation/devicetree/bindings/dma/qcom,gpi.yaml
··· 24 24 - qcom,sm6350-gpi-dma 25 25 - items: 26 26 - enum: 27 + - qcom,qcm2290-gpi-dma 27 28 - qcom,qdu1000-gpi-dma 28 29 - qcom,sc7280-gpi-dma 29 30 - qcom,sm6115-gpi-dma
+14
Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml
··· 54 54 - description: DMA main clock 55 55 - description: DMA register access clock 56 56 57 + clock-names: 58 + items: 59 + - const: main 60 + - const: register 61 + 57 62 '#dma-cells': 58 63 const: 1 59 64 description: ··· 82 77 - description: Reset for DMA ARESETN reset terminal 83 78 - description: Reset for DMA RST_ASYNC reset terminal 84 79 80 + reset-names: 81 + items: 82 + - const: arst 83 + - const: rst_async 84 + 85 85 required: 86 86 - compatible 87 87 - reg 88 88 - interrupts 89 89 - interrupt-names 90 90 - clocks 91 + - clock-names 91 92 - '#dma-cells' 92 93 - dma-channels 93 94 - power-domains 94 95 - resets 96 + - reset-names 95 97 96 98 additionalProperties: false 97 99 ··· 136 124 "ch12", "ch13", "ch14", "ch15"; 137 125 clocks = <&cpg CPG_MOD R9A07G044_DMAC_ACLK>, 138 126 <&cpg CPG_MOD R9A07G044_DMAC_PCLK>; 127 + clock-names = "main", "register"; 139 128 power-domains = <&cpg>; 140 129 resets = <&cpg R9A07G044_DMAC_ARESETN>, 141 130 <&cpg R9A07G044_DMAC_RST_ASYNC>; 131 + reset-names = "arst", "rst_async"; 142 132 #dma-cells = <1>; 143 133 dma-channels = <16>; 144 134 };
+22 -1
Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml
··· 20 20 enum: 21 21 - snps,axi-dma-1.01a 22 22 - intel,kmb-axi-dma 23 + - starfive,jh7110-axi-dma 23 24 24 25 reg: 25 26 minItems: 1 ··· 59 58 maximum: 8 60 59 61 60 resets: 62 - maxItems: 1 61 + minItems: 1 62 + maxItems: 2 63 63 64 64 snps,dma-masters: 65 65 description: | ··· 110 108 - snps,data-width 111 109 - snps,priority 112 110 - snps,block-size 111 + 112 + if: 113 + properties: 114 + compatible: 115 + contains: 116 + enum: 117 + - starfive,jh7110-axi-dma 118 + then: 119 + properties: 120 + resets: 121 + minItems: 2 122 + items: 123 + - description: AXI reset line 124 + - description: AHB reset line 125 + - description: module reset 126 + else: 127 + properties: 128 + resets: 129 + maxItems: 1 113 130 114 131 additionalProperties: false 115 132
+1 -1
Documentation/devicetree/bindings/dma/ti/k3-udma.yaml
··· 43 43 configuration of the legacy peripheral. 44 44 45 45 allOf: 46 - - $ref: "../dma-controller.yaml#" 46 + - $ref: ../dma-controller.yaml# 47 47 - $ref: /schemas/arm/keystone/ti,k3-sci-common.yaml# 48 48 49 49 properties:
+1 -1
Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml
··· 15 15 - Michael Tretter <m.tretter@pengutronix.de> 16 16 17 17 allOf: 18 - - $ref: "../dma-controller.yaml#" 18 + - $ref: ../dma-controller.yaml# 19 19 20 20 properties: 21 21 "#dma-cells":
+1 -1
Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dpdma.yaml
··· 16 16 - Laurent Pinchart <laurent.pinchart@ideasonboard.com> 17 17 18 18 allOf: 19 - - $ref: "../dma-controller.yaml#" 19 + - $ref: ../dma-controller.yaml# 20 20 21 21 properties: 22 22 "#dma-cells":
+1
drivers/dma/Kconfig
··· 623 623 depends on (ARCH_TEGRA || COMPILE_TEST) && ARCH_DMA_ADDR_T_64BIT 624 624 depends on IOMMU_API 625 625 select DMA_ENGINE 626 + select DMA_VIRTUAL_CHANNELS 626 627 help 627 628 Support for the NVIDIA Tegra General Purpose Central DMA controller. 628 629 The DMA controller has multiple DMA channels which can be configured
+82 -25
drivers/dma/at_xdmac.c
··· 187 187 enum atc_status { 188 188 AT_XDMAC_CHAN_IS_CYCLIC = 0, 189 189 AT_XDMAC_CHAN_IS_PAUSED, 190 + AT_XDMAC_CHAN_IS_PAUSED_INTERNAL, 190 191 }; 191 192 192 193 struct at_xdmac_layout { ··· 246 245 int irq; 247 246 struct clk *clk; 248 247 u32 save_gim; 248 + u32 save_gs; 249 249 struct dma_pool *at_xdmac_desc_pool; 250 250 const struct at_xdmac_layout *layout; 251 251 struct at_xdmac_chan chan[]; ··· 349 347 return test_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status); 350 348 } 351 349 350 + static inline int at_xdmac_chan_is_paused_internal(struct at_xdmac_chan *atchan) 351 + { 352 + return test_bit(AT_XDMAC_CHAN_IS_PAUSED_INTERNAL, &atchan->status); 353 + } 354 + 352 355 static inline bool at_xdmac_chan_is_peripheral_xfer(u32 cfg) 353 356 { 354 357 return cfg & AT_XDMAC_CC_TYPE_PER_TRAN; ··· 419 412 return ret; 420 413 } 421 414 422 - static void at_xdmac_off(struct at_xdmac *atxdmac) 415 + static void at_xdmac_off(struct at_xdmac *atxdmac, bool suspend_descriptors) 423 416 { 424 417 struct dma_chan *chan, *_chan; 425 418 struct at_xdmac_chan *atchan; ··· 438 431 at_xdmac_write(atxdmac, AT_XDMAC_GID, -1L); 439 432 440 433 /* Decrement runtime PM ref counter for each active descriptor. */ 441 - if (!list_empty(&atxdmac->dma.channels)) { 434 + if (!list_empty(&atxdmac->dma.channels) && suspend_descriptors) { 442 435 list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, 443 436 device_node) { 444 437 atchan = to_at_xdmac_chan(chan); ··· 1905 1898 return ret; 1906 1899 } 1907 1900 1901 + static void at_xdmac_device_pause_set(struct at_xdmac *atxdmac, 1902 + struct at_xdmac_chan *atchan) 1903 + { 1904 + at_xdmac_write(atxdmac, atxdmac->layout->grws, atchan->mask); 1905 + while (at_xdmac_chan_read(atchan, AT_XDMAC_CC) & 1906 + (AT_XDMAC_CC_WRIP | AT_XDMAC_CC_RDIP)) 1907 + cpu_relax(); 1908 + } 1909 + 1910 + static void at_xdmac_device_pause_internal(struct at_xdmac_chan *atchan) 1911 + { 1912 + struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); 1913 + unsigned long flags; 1914 + 1915 + spin_lock_irqsave(&atchan->lock, flags); 1916 + set_bit(AT_XDMAC_CHAN_IS_PAUSED_INTERNAL, &atchan->status); 1917 + at_xdmac_device_pause_set(atxdmac, atchan); 1918 + spin_unlock_irqrestore(&atchan->lock, flags); 1919 + } 1920 + 1908 1921 static int at_xdmac_device_pause(struct dma_chan *chan) 1909 1922 { 1910 1923 struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); ··· 1942 1915 return ret; 1943 1916 1944 1917 spin_lock_irqsave(&atchan->lock, flags); 1945 - at_xdmac_write(atxdmac, atxdmac->layout->grws, atchan->mask); 1946 - while (at_xdmac_chan_read(atchan, AT_XDMAC_CC) 1947 - & (AT_XDMAC_CC_WRIP | AT_XDMAC_CC_RDIP)) 1948 - cpu_relax(); 1949 1918 1919 + at_xdmac_device_pause_set(atxdmac, atchan); 1950 1920 /* Decrement runtime PM ref counter for each active descriptor. */ 1951 1921 at_xdmac_runtime_suspend_descriptors(atchan); 1952 1922 ··· 1953 1929 pm_runtime_put_autosuspend(atxdmac->dev); 1954 1930 1955 1931 return 0; 1932 + } 1933 + 1934 + static void at_xdmac_device_resume_internal(struct at_xdmac_chan *atchan) 1935 + { 1936 + struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); 1937 + unsigned long flags; 1938 + 1939 + spin_lock_irqsave(&atchan->lock, flags); 1940 + at_xdmac_write(atxdmac, atxdmac->layout->grwr, atchan->mask); 1941 + clear_bit(AT_XDMAC_CHAN_IS_PAUSED_INTERNAL, &atchan->status); 1942 + spin_unlock_irqrestore(&atchan->lock, flags); 1956 1943 } 1957 1944 1958 1945 static int at_xdmac_device_resume(struct dma_chan *chan) ··· 2153 2118 2154 2119 atchan->save_cc = at_xdmac_chan_read(atchan, AT_XDMAC_CC); 2155 2120 if (at_xdmac_chan_is_cyclic(atchan)) { 2156 - if (!at_xdmac_chan_is_paused(atchan)) 2157 - at_xdmac_device_pause(chan); 2121 + if (!at_xdmac_chan_is_paused(atchan)) { 2122 + dev_warn(chan2dev(chan), "%s: channel %d not paused\n", 2123 + __func__, chan->chan_id); 2124 + at_xdmac_device_pause_internal(atchan); 2125 + at_xdmac_runtime_suspend_descriptors(atchan); 2126 + } 2158 2127 atchan->save_cim = at_xdmac_chan_read(atchan, AT_XDMAC_CIM); 2159 2128 atchan->save_cnda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA); 2160 2129 atchan->save_cndc = at_xdmac_chan_read(atchan, AT_XDMAC_CNDC); 2161 2130 } 2162 - 2163 - at_xdmac_runtime_suspend_descriptors(atchan); 2164 2131 } 2165 2132 atxdmac->save_gim = at_xdmac_read(atxdmac, AT_XDMAC_GIM); 2133 + atxdmac->save_gs = at_xdmac_read(atxdmac, AT_XDMAC_GS); 2166 2134 2167 - at_xdmac_off(atxdmac); 2168 - return pm_runtime_force_suspend(atxdmac->dev); 2135 + at_xdmac_off(atxdmac, false); 2136 + pm_runtime_mark_last_busy(atxdmac->dev); 2137 + pm_runtime_put_noidle(atxdmac->dev); 2138 + clk_disable_unprepare(atxdmac->clk); 2139 + 2140 + return 0; 2169 2141 } 2170 2142 2171 2143 static int __maybe_unused atmel_xdmac_resume(struct device *dev) ··· 2181 2139 struct at_xdmac_chan *atchan; 2182 2140 struct dma_chan *chan, *_chan; 2183 2141 struct platform_device *pdev = container_of(dev, struct platform_device, dev); 2184 - int i; 2185 - int ret; 2142 + int i, ret; 2186 2143 2187 - ret = pm_runtime_force_resume(atxdmac->dev); 2188 - if (ret < 0) 2144 + ret = clk_prepare_enable(atxdmac->clk); 2145 + if (ret) 2189 2146 return ret; 2147 + 2148 + pm_runtime_get_noresume(atxdmac->dev); 2190 2149 2191 2150 at_xdmac_axi_config(pdev); 2192 2151 ··· 2202 2159 list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, device_node) { 2203 2160 atchan = to_at_xdmac_chan(chan); 2204 2161 2205 - ret = at_xdmac_runtime_resume_descriptors(atchan); 2206 - if (ret < 0) 2207 - return ret; 2208 - 2209 2162 at_xdmac_chan_write(atchan, AT_XDMAC_CC, atchan->save_cc); 2210 2163 if (at_xdmac_chan_is_cyclic(atchan)) { 2211 - if (at_xdmac_chan_is_paused(atchan)) 2212 - at_xdmac_device_resume(chan); 2164 + /* 2165 + * Resume only channels not explicitly paused by 2166 + * consumers. 2167 + */ 2168 + if (at_xdmac_chan_is_paused_internal(atchan)) { 2169 + ret = at_xdmac_runtime_resume_descriptors(atchan); 2170 + if (ret < 0) 2171 + return ret; 2172 + at_xdmac_device_resume_internal(atchan); 2173 + } 2174 + 2175 + /* 2176 + * We may resume from a deep sleep state where power 2177 + * to DMA controller is cut-off. Thus, restore the 2178 + * suspend state of channels set though dmaengine API. 2179 + */ 2180 + else if (at_xdmac_chan_is_paused(atchan)) 2181 + at_xdmac_device_pause_set(atxdmac, atchan); 2182 + 2213 2183 at_xdmac_chan_write(atchan, AT_XDMAC_CNDA, atchan->save_cnda); 2214 2184 at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc); 2215 2185 at_xdmac_chan_write(atchan, AT_XDMAC_CIE, atchan->save_cim); 2216 2186 wmb(); 2217 - at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask); 2187 + if (atxdmac->save_gs & atchan->mask) 2188 + at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask); 2218 2189 } 2219 2190 } 2220 2191 ··· 2369 2312 INIT_LIST_HEAD(&atxdmac->dma.channels); 2370 2313 2371 2314 /* Disable all chans and interrupts. */ 2372 - at_xdmac_off(atxdmac); 2315 + at_xdmac_off(atxdmac, true); 2373 2316 2374 2317 for (i = 0; i < nr_channels; i++) { 2375 2318 struct at_xdmac_chan *atchan = &atxdmac->chan[i]; ··· 2433 2376 struct at_xdmac *atxdmac = (struct at_xdmac *)platform_get_drvdata(pdev); 2434 2377 int i; 2435 2378 2436 - at_xdmac_off(atxdmac); 2379 + at_xdmac_off(atxdmac, true); 2437 2380 of_dma_controller_free(pdev->dev.of_node); 2438 2381 dma_async_device_unregister(&atxdmac->dma); 2439 2382 pm_runtime_disable(atxdmac->dev);
+8 -11
drivers/dma/bestcomm/sram.c
··· 38 38 { 39 39 int rv; 40 40 const u32 *regaddr_p; 41 - u64 regaddr64, size64; 41 + struct resource res; 42 42 unsigned int psize; 43 43 44 44 /* Create our state struct */ ··· 56 56 } 57 57 58 58 /* Get address and size of the sram */ 59 - regaddr_p = of_get_address(sram_node, 0, &size64, NULL); 60 - if (!regaddr_p) { 59 + rv = of_address_to_resource(sram_node, 0, &res); 60 + if (rv) { 61 61 printk(KERN_ERR "%s: bcom_sram_init: " 62 62 "Invalid device node !\n", owner); 63 - rv = -EINVAL; 64 63 goto error_free; 65 64 } 66 65 67 - regaddr64 = of_translate_address(sram_node, regaddr_p); 68 - 69 - bcom_sram->base_phys = (phys_addr_t) regaddr64; 70 - bcom_sram->size = (unsigned int) size64; 66 + bcom_sram->base_phys = res.start; 67 + bcom_sram->size = resource_size(&res); 71 68 72 69 /* Request region */ 73 - if (!request_mem_region(bcom_sram->base_phys, bcom_sram->size, owner)) { 70 + if (!request_mem_region(res.start, resource_size(&res), owner)) { 74 71 printk(KERN_ERR "%s: bcom_sram_init: " 75 72 "Couldn't request region !\n", owner); 76 73 rv = -EBUSY; ··· 76 79 77 80 /* Map SRAM */ 78 81 /* sram is not really __iomem */ 79 - bcom_sram->base_virt = (void*) ioremap(bcom_sram->base_phys, bcom_sram->size); 82 + bcom_sram->base_virt = (void *)ioremap(res.start, resource_size(&res)); 80 83 81 84 if (!bcom_sram->base_virt) { 82 85 printk(KERN_ERR "%s: bcom_sram_init: " ··· 117 120 return 0; 118 121 119 122 error_release: 120 - release_mem_region(bcom_sram->base_phys, bcom_sram->size); 123 + release_mem_region(res.start, resource_size(&res)); 121 124 error_free: 122 125 kfree(bcom_sram); 123 126 bcom_sram = NULL;
+34 -6
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
··· 21 21 #include <linux/kernel.h> 22 22 #include <linux/module.h> 23 23 #include <linux/of.h> 24 + #include <linux/of_device.h> 24 25 #include <linux/of_dma.h> 25 26 #include <linux/platform_device.h> 26 27 #include <linux/pm_runtime.h> 27 28 #include <linux/property.h> 29 + #include <linux/reset.h> 28 30 #include <linux/slab.h> 29 31 #include <linux/types.h> 30 32 ··· 47 45 DMA_SLAVE_BUSWIDTH_16_BYTES | \ 48 46 DMA_SLAVE_BUSWIDTH_32_BYTES | \ 49 47 DMA_SLAVE_BUSWIDTH_64_BYTES) 48 + 49 + #define AXI_DMA_FLAG_HAS_APB_REGS BIT(0) 50 + #define AXI_DMA_FLAG_HAS_RESETS BIT(1) 51 + #define AXI_DMA_FLAG_USE_CFG2 BIT(2) 50 52 51 53 static inline void 52 54 axi_dma_iowrite32(struct axi_dma_chip *chip, u32 reg, u32 val) ··· 92 86 93 87 cfg_lo = (config->dst_multblk_type << CH_CFG_L_DST_MULTBLK_TYPE_POS | 94 88 config->src_multblk_type << CH_CFG_L_SRC_MULTBLK_TYPE_POS); 95 - if (chan->chip->dw->hdata->reg_map_8_channels) { 89 + if (chan->chip->dw->hdata->reg_map_8_channels && 90 + !chan->chip->dw->hdata->use_cfg2) { 96 91 cfg_hi = config->tt_fc << CH_CFG_H_TT_FC_POS | 97 92 config->hs_sel_src << CH_CFG_H_HS_SEL_SRC_POS | 98 93 config->hs_sel_dst << CH_CFG_H_HS_SEL_DST_POS | ··· 1147 1140 axi_chan_disable(chan); 1148 1141 1149 1142 ret = readl_poll_timeout_atomic(chan->chip->regs + DMAC_CHEN, val, 1150 - !(val & chan_active), 1000, 10000); 1143 + !(val & chan_active), 1000, 50000); 1151 1144 if (ret == -ETIMEDOUT) 1152 1145 dev_warn(dchan2dev(dchan), 1153 1146 "%s failed to stop\n", axi_chan_name(chan)); ··· 1374 1367 1375 1368 static int dw_probe(struct platform_device *pdev) 1376 1369 { 1377 - struct device_node *node = pdev->dev.of_node; 1378 1370 struct axi_dma_chip *chip; 1379 1371 struct dw_axi_dma *dw; 1380 1372 struct dw_axi_dma_hcfg *hdata; 1373 + struct reset_control *resets; 1374 + unsigned int flags; 1381 1375 u32 i; 1382 1376 int ret; 1383 1377 ··· 1406 1398 if (IS_ERR(chip->regs)) 1407 1399 return PTR_ERR(chip->regs); 1408 1400 1409 - if (of_device_is_compatible(node, "intel,kmb-axi-dma")) { 1401 + flags = (uintptr_t)of_device_get_match_data(&pdev->dev); 1402 + if (flags & AXI_DMA_FLAG_HAS_APB_REGS) { 1410 1403 chip->apb_regs = devm_platform_ioremap_resource(pdev, 1); 1411 1404 if (IS_ERR(chip->apb_regs)) 1412 1405 return PTR_ERR(chip->apb_regs); 1413 1406 } 1407 + 1408 + if (flags & AXI_DMA_FLAG_HAS_RESETS) { 1409 + resets = devm_reset_control_array_get_exclusive(&pdev->dev); 1410 + if (IS_ERR(resets)) 1411 + return PTR_ERR(resets); 1412 + 1413 + ret = reset_control_deassert(resets); 1414 + if (ret) 1415 + return ret; 1416 + } 1417 + 1418 + chip->dw->hdata->use_cfg2 = !!(flags & AXI_DMA_FLAG_USE_CFG2); 1414 1419 1415 1420 chip->core_clk = devm_clk_get(chip->dev, "core-clk"); 1416 1421 if (IS_ERR(chip->core_clk)) ··· 1575 1554 }; 1576 1555 1577 1556 static const struct of_device_id dw_dma_of_id_table[] = { 1578 - { .compatible = "snps,axi-dma-1.01a" }, 1579 - { .compatible = "intel,kmb-axi-dma" }, 1557 + { 1558 + .compatible = "snps,axi-dma-1.01a" 1559 + }, { 1560 + .compatible = "intel,kmb-axi-dma", 1561 + .data = (void *)AXI_DMA_FLAG_HAS_APB_REGS, 1562 + }, { 1563 + .compatible = "starfive,jh7110-axi-dma", 1564 + .data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2), 1565 + }, 1580 1566 {} 1581 1567 }; 1582 1568 MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
+1
drivers/dma/dw-axi-dmac/dw-axi-dmac.h
··· 33 33 /* Register map for DMAX_NUM_CHANNELS <= 8 */ 34 34 bool reg_map_8_channels; 35 35 bool restrict_axi_burst_len; 36 + bool use_cfg2; 36 37 }; 37 38 38 39 struct axi_dma_chan {
+16 -11
drivers/dma/dw-edma/dw-edma-core.c
··· 181 181 dw_edma_free_desc(vd2dw_edma_desc(vdesc)); 182 182 } 183 183 184 - static void dw_edma_start_transfer(struct dw_edma_chan *chan) 184 + static int dw_edma_start_transfer(struct dw_edma_chan *chan) 185 185 { 186 186 struct dw_edma_chunk *child; 187 187 struct dw_edma_desc *desc; ··· 189 189 190 190 vd = vchan_next_desc(&chan->vc); 191 191 if (!vd) 192 - return; 192 + return 0; 193 193 194 194 desc = vd2dw_edma_desc(vd); 195 195 if (!desc) 196 - return; 196 + return 0; 197 197 198 198 child = list_first_entry_or_null(&desc->chunk->list, 199 199 struct dw_edma_chunk, list); 200 200 if (!child) 201 - return; 201 + return 0; 202 202 203 203 dw_edma_v0_core_start(child, !desc->xfer_sz); 204 204 desc->xfer_sz += child->ll_region.sz; ··· 206 206 list_del(&child->list); 207 207 kfree(child); 208 208 desc->chunks_alloc--; 209 + 210 + return 1; 209 211 } 210 212 211 213 static void dw_edma_device_caps(struct dma_chan *dchan, ··· 308 306 struct dw_edma_chan *chan = dchan2dw_edma_chan(dchan); 309 307 unsigned long flags; 310 308 309 + if (!chan->configured) 310 + return; 311 + 311 312 spin_lock_irqsave(&chan->vc.lock, flags); 312 - if (chan->configured && chan->request == EDMA_REQ_NONE && 313 - chan->status == EDMA_ST_IDLE && vchan_issue_pending(&chan->vc)) { 313 + if (vchan_issue_pending(&chan->vc) && chan->request == EDMA_REQ_NONE && 314 + chan->status == EDMA_ST_IDLE) { 314 315 chan->status = EDMA_ST_BUSY; 315 316 dw_edma_start_transfer(chan); 316 317 } ··· 607 602 switch (chan->request) { 608 603 case EDMA_REQ_NONE: 609 604 desc = vd2dw_edma_desc(vd); 610 - if (desc->chunks_alloc) { 611 - chan->status = EDMA_ST_BUSY; 612 - dw_edma_start_transfer(chan); 613 - } else { 605 + if (!desc->chunks_alloc) { 614 606 list_del(&vd->node); 615 607 vchan_cookie_complete(vd); 616 - chan->status = EDMA_ST_IDLE; 617 608 } 609 + 610 + /* Continue transferring if there are remaining chunks or issued requests. 611 + */ 612 + chan->status = dw_edma_start_transfer(chan) ? EDMA_ST_BUSY : EDMA_ST_IDLE; 618 613 break; 619 614 620 615 case EDMA_REQ_STOP:
-56
drivers/dma/dw-edma/dw-edma-v0-core.c
··· 159 159 #define GET_CH_32(dw, dir, ch, name) \ 160 160 readl_ch(dw, dir, ch, &(__dw_ch_regs(dw, dir, ch)->name)) 161 161 162 - static inline void writeq_ch(struct dw_edma *dw, enum dw_edma_dir dir, u16 ch, 163 - u64 value, void __iomem *addr) 164 - { 165 - if (dw->chip->mf == EDMA_MF_EDMA_LEGACY) { 166 - u32 viewport_sel; 167 - unsigned long flags; 168 - 169 - raw_spin_lock_irqsave(&dw->lock, flags); 170 - 171 - viewport_sel = FIELD_PREP(EDMA_V0_VIEWPORT_MASK, ch); 172 - if (dir == EDMA_DIR_READ) 173 - viewport_sel |= BIT(31); 174 - 175 - writel(viewport_sel, 176 - &(__dw_regs(dw)->type.legacy.viewport_sel)); 177 - writeq(value, addr); 178 - 179 - raw_spin_unlock_irqrestore(&dw->lock, flags); 180 - } else { 181 - writeq(value, addr); 182 - } 183 - } 184 - 185 - static inline u64 readq_ch(struct dw_edma *dw, enum dw_edma_dir dir, u16 ch, 186 - const void __iomem *addr) 187 - { 188 - u64 value; 189 - 190 - if (dw->chip->mf == EDMA_MF_EDMA_LEGACY) { 191 - u32 viewport_sel; 192 - unsigned long flags; 193 - 194 - raw_spin_lock_irqsave(&dw->lock, flags); 195 - 196 - viewport_sel = FIELD_PREP(EDMA_V0_VIEWPORT_MASK, ch); 197 - if (dir == EDMA_DIR_READ) 198 - viewport_sel |= BIT(31); 199 - 200 - writel(viewport_sel, 201 - &(__dw_regs(dw)->type.legacy.viewport_sel)); 202 - value = readq(addr); 203 - 204 - raw_spin_unlock_irqrestore(&dw->lock, flags); 205 - } else { 206 - value = readq(addr); 207 - } 208 - 209 - return value; 210 - } 211 - 212 - #define SET_CH_64(dw, dir, ch, name, value) \ 213 - writeq_ch(dw, dir, ch, value, &(__dw_ch_regs(dw, dir, ch)->name)) 214 - 215 - #define GET_CH_64(dw, dir, ch, name) \ 216 - readq_ch(dw, dir, ch, &(__dw_ch_regs(dw, dir, ch)->name)) 217 - 218 162 /* eDMA management callbacks */ 219 163 void dw_edma_v0_core_off(struct dw_edma *dw) 220 164 {
+1 -1
drivers/dma/idxd/Makefile
··· 1 1 ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=IDXD 2 2 3 3 obj-$(CONFIG_INTEL_IDXD) += idxd.o 4 - idxd-y := init.o irq.o device.o sysfs.o submit.o dma.o cdev.o 4 + idxd-y := init.o irq.o device.o sysfs.o submit.o dma.o cdev.o debugfs.o 5 5 6 6 idxd-$(CONFIG_INTEL_IDXD_PERFMON) += perfmon.o 7 7
+309 -25
drivers/dma/idxd/cdev.c
··· 11 11 #include <linux/fs.h> 12 12 #include <linux/poll.h> 13 13 #include <linux/iommu.h> 14 + #include <linux/highmem.h> 14 15 #include <uapi/linux/idxd.h> 16 + #include <linux/xarray.h> 15 17 #include "registers.h" 16 18 #include "idxd.h" 17 19 ··· 22 20 dev_t devt; 23 21 struct ida minor_ida; 24 22 }; 23 + 24 + /* 25 + * Since user file names are global in DSA devices, define their ida's as 26 + * global to avoid conflict file names. 27 + */ 28 + static DEFINE_IDA(file_ida); 29 + static DEFINE_MUTEX(ida_lock); 25 30 26 31 /* 27 32 * ictx is an array based off of accelerator types. enum idxd_type ··· 43 34 struct idxd_wq *wq; 44 35 struct task_struct *task; 45 36 unsigned int pasid; 37 + struct mm_struct *mm; 46 38 unsigned int flags; 47 39 struct iommu_sva *sva; 40 + struct idxd_dev idxd_dev; 41 + u64 counters[COUNTER_MAX]; 42 + int id; 43 + pid_t pid; 44 + }; 45 + 46 + static void idxd_cdev_evl_drain_pasid(struct idxd_wq *wq, u32 pasid); 47 + static void idxd_xa_pasid_remove(struct idxd_user_context *ctx); 48 + 49 + static inline struct idxd_user_context *dev_to_uctx(struct device *dev) 50 + { 51 + struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); 52 + 53 + return container_of(idxd_dev, struct idxd_user_context, idxd_dev); 54 + } 55 + 56 + static ssize_t cr_faults_show(struct device *dev, struct device_attribute *attr, char *buf) 57 + { 58 + struct idxd_user_context *ctx = dev_to_uctx(dev); 59 + 60 + return sysfs_emit(buf, "%llu\n", ctx->counters[COUNTER_FAULTS]); 61 + } 62 + static DEVICE_ATTR_RO(cr_faults); 63 + 64 + static ssize_t cr_fault_failures_show(struct device *dev, 65 + struct device_attribute *attr, char *buf) 66 + { 67 + struct idxd_user_context *ctx = dev_to_uctx(dev); 68 + 69 + return sysfs_emit(buf, "%llu\n", ctx->counters[COUNTER_FAULT_FAILS]); 70 + } 71 + static DEVICE_ATTR_RO(cr_fault_failures); 72 + 73 + static ssize_t pid_show(struct device *dev, struct device_attribute *attr, char *buf) 74 + { 75 + struct idxd_user_context *ctx = dev_to_uctx(dev); 76 + 77 + return sysfs_emit(buf, "%u\n", ctx->pid); 78 + } 79 + static DEVICE_ATTR_RO(pid); 80 + 81 + static struct attribute *cdev_file_attributes[] = { 82 + &dev_attr_cr_faults.attr, 83 + &dev_attr_cr_fault_failures.attr, 84 + &dev_attr_pid.attr, 85 + NULL 86 + }; 87 + 88 + static umode_t cdev_file_attr_visible(struct kobject *kobj, struct attribute *a, int n) 89 + { 90 + struct device *dev = container_of(kobj, typeof(*dev), kobj); 91 + struct idxd_user_context *ctx = dev_to_uctx(dev); 92 + struct idxd_wq *wq = ctx->wq; 93 + 94 + if (!wq_pasid_enabled(wq)) 95 + return 0; 96 + 97 + return a->mode; 98 + } 99 + 100 + static const struct attribute_group cdev_file_attribute_group = { 101 + .attrs = cdev_file_attributes, 102 + .is_visible = cdev_file_attr_visible, 103 + }; 104 + 105 + static const struct attribute_group *cdev_file_attribute_groups[] = { 106 + &cdev_file_attribute_group, 107 + NULL 108 + }; 109 + 110 + static void idxd_file_dev_release(struct device *dev) 111 + { 112 + struct idxd_user_context *ctx = dev_to_uctx(dev); 113 + struct idxd_wq *wq = ctx->wq; 114 + struct idxd_device *idxd = wq->idxd; 115 + int rc; 116 + 117 + mutex_lock(&ida_lock); 118 + ida_free(&file_ida, ctx->id); 119 + mutex_unlock(&ida_lock); 120 + 121 + /* Wait for in-flight operations to complete. */ 122 + if (wq_shared(wq)) { 123 + idxd_device_drain_pasid(idxd, ctx->pasid); 124 + } else { 125 + if (device_user_pasid_enabled(idxd)) { 126 + /* The wq disable in the disable pasid function will drain the wq */ 127 + rc = idxd_wq_disable_pasid(wq); 128 + if (rc < 0) 129 + dev_err(dev, "wq disable pasid failed.\n"); 130 + } else { 131 + idxd_wq_drain(wq); 132 + } 133 + } 134 + 135 + if (ctx->sva) { 136 + idxd_cdev_evl_drain_pasid(wq, ctx->pasid); 137 + iommu_sva_unbind_device(ctx->sva); 138 + idxd_xa_pasid_remove(ctx); 139 + } 140 + kfree(ctx); 141 + mutex_lock(&wq->wq_lock); 142 + idxd_wq_put(wq); 143 + mutex_unlock(&wq->wq_lock); 144 + } 145 + 146 + static struct device_type idxd_cdev_file_type = { 147 + .name = "idxd_file", 148 + .release = idxd_file_dev_release, 149 + .groups = cdev_file_attribute_groups, 48 150 }; 49 151 50 152 static void idxd_cdev_dev_release(struct device *dev) ··· 188 68 return idxd_cdev->wq; 189 69 } 190 70 71 + static void idxd_xa_pasid_remove(struct idxd_user_context *ctx) 72 + { 73 + struct idxd_wq *wq = ctx->wq; 74 + void *ptr; 75 + 76 + mutex_lock(&wq->uc_lock); 77 + ptr = xa_cmpxchg(&wq->upasid_xa, ctx->pasid, ctx, NULL, GFP_KERNEL); 78 + if (ptr != (void *)ctx) 79 + dev_warn(&wq->idxd->pdev->dev, "xarray cmpxchg failed for pasid %u\n", 80 + ctx->pasid); 81 + mutex_unlock(&wq->uc_lock); 82 + } 83 + 84 + void idxd_user_counter_increment(struct idxd_wq *wq, u32 pasid, int index) 85 + { 86 + struct idxd_user_context *ctx; 87 + 88 + if (index >= COUNTER_MAX) 89 + return; 90 + 91 + mutex_lock(&wq->uc_lock); 92 + ctx = xa_load(&wq->upasid_xa, pasid); 93 + if (!ctx) { 94 + mutex_unlock(&wq->uc_lock); 95 + return; 96 + } 97 + ctx->counters[index]++; 98 + mutex_unlock(&wq->uc_lock); 99 + } 100 + 191 101 static int idxd_cdev_open(struct inode *inode, struct file *filp) 192 102 { 193 103 struct idxd_user_context *ctx; 194 104 struct idxd_device *idxd; 195 105 struct idxd_wq *wq; 196 - struct device *dev; 106 + struct device *dev, *fdev; 197 107 int rc = 0; 198 108 struct iommu_sva *sva; 199 109 unsigned int pasid; 110 + struct idxd_cdev *idxd_cdev; 200 111 201 112 wq = inode_wq(inode); 202 113 idxd = wq->idxd; ··· 248 97 249 98 ctx->wq = wq; 250 99 filp->private_data = ctx; 100 + ctx->pid = current->pid; 251 101 252 102 if (device_user_pasid_enabled(idxd)) { 253 103 sva = iommu_sva_bind_device(dev, current->mm); ··· 260 108 261 109 pasid = iommu_sva_get_pasid(sva); 262 110 if (pasid == IOMMU_PASID_INVALID) { 263 - iommu_sva_unbind_device(sva); 264 111 rc = -EINVAL; 265 - goto failed; 112 + goto failed_get_pasid; 266 113 } 267 114 268 115 ctx->sva = sva; 269 116 ctx->pasid = pasid; 117 + ctx->mm = current->mm; 118 + 119 + mutex_lock(&wq->uc_lock); 120 + rc = xa_insert(&wq->upasid_xa, pasid, ctx, GFP_KERNEL); 121 + mutex_unlock(&wq->uc_lock); 122 + if (rc < 0) 123 + dev_warn(dev, "PASID entry already exist in xarray.\n"); 270 124 271 125 if (wq_dedicated(wq)) { 272 126 rc = idxd_wq_set_pasid(wq, pasid); 273 127 if (rc < 0) { 274 128 iommu_sva_unbind_device(sva); 275 129 dev_err(dev, "wq set pasid failed: %d\n", rc); 276 - goto failed; 130 + goto failed_set_pasid; 277 131 } 278 132 } 133 + } 134 + 135 + idxd_cdev = wq->idxd_cdev; 136 + mutex_lock(&ida_lock); 137 + ctx->id = ida_alloc(&file_ida, GFP_KERNEL); 138 + mutex_unlock(&ida_lock); 139 + if (ctx->id < 0) { 140 + dev_warn(dev, "ida alloc failure\n"); 141 + goto failed_ida; 142 + } 143 + ctx->idxd_dev.type = IDXD_DEV_CDEV_FILE; 144 + fdev = user_ctx_dev(ctx); 145 + device_initialize(fdev); 146 + fdev->parent = cdev_dev(idxd_cdev); 147 + fdev->bus = &dsa_bus_type; 148 + fdev->type = &idxd_cdev_file_type; 149 + 150 + rc = dev_set_name(fdev, "file%d", ctx->id); 151 + if (rc < 0) { 152 + dev_warn(dev, "set name failure\n"); 153 + goto failed_dev_name; 154 + } 155 + 156 + rc = device_add(fdev); 157 + if (rc < 0) { 158 + dev_warn(dev, "file device add failure\n"); 159 + goto failed_dev_add; 279 160 } 280 161 281 162 idxd_wq_get(wq); 282 163 mutex_unlock(&wq->wq_lock); 283 164 return 0; 284 165 285 - failed: 166 + failed_dev_add: 167 + failed_dev_name: 168 + put_device(fdev); 169 + failed_ida: 170 + failed_set_pasid: 171 + if (device_user_pasid_enabled(idxd)) 172 + idxd_xa_pasid_remove(ctx); 173 + failed_get_pasid: 174 + if (device_user_pasid_enabled(idxd)) 175 + iommu_sva_unbind_device(sva); 176 + failed: 286 177 mutex_unlock(&wq->wq_lock); 287 178 kfree(ctx); 288 179 return rc; 180 + } 181 + 182 + static void idxd_cdev_evl_drain_pasid(struct idxd_wq *wq, u32 pasid) 183 + { 184 + struct idxd_device *idxd = wq->idxd; 185 + struct idxd_evl *evl = idxd->evl; 186 + union evl_status_reg status; 187 + u16 h, t, size; 188 + int ent_size = evl_ent_size(idxd); 189 + struct __evl_entry *entry_head; 190 + 191 + if (!evl) 192 + return; 193 + 194 + spin_lock(&evl->lock); 195 + status.bits = ioread64(idxd->reg_base + IDXD_EVLSTATUS_OFFSET); 196 + t = status.tail; 197 + h = evl->head; 198 + size = evl->size; 199 + 200 + while (h != t) { 201 + entry_head = (struct __evl_entry *)(evl->log + (h * ent_size)); 202 + if (entry_head->pasid == pasid && entry_head->wq_idx == wq->id) 203 + set_bit(h, evl->bmap); 204 + h = (h + 1) % size; 205 + } 206 + spin_unlock(&evl->lock); 207 + 208 + drain_workqueue(wq->wq); 289 209 } 290 210 291 211 static int idxd_cdev_release(struct inode *node, struct file *filep) ··· 366 142 struct idxd_wq *wq = ctx->wq; 367 143 struct idxd_device *idxd = wq->idxd; 368 144 struct device *dev = &idxd->pdev->dev; 369 - int rc; 370 145 371 146 dev_dbg(dev, "%s called\n", __func__); 372 147 filep->private_data = NULL; 373 148 374 - /* Wait for in-flight operations to complete. */ 375 - if (wq_shared(wq)) { 376 - idxd_device_drain_pasid(idxd, ctx->pasid); 377 - } else { 378 - if (device_user_pasid_enabled(idxd)) { 379 - /* The wq disable in the disable pasid function will drain the wq */ 380 - rc = idxd_wq_disable_pasid(wq); 381 - if (rc < 0) 382 - dev_err(dev, "wq disable pasid failed.\n"); 383 - } else { 384 - idxd_wq_drain(wq); 385 - } 386 - } 149 + device_unregister(user_ctx_dev(ctx)); 387 150 388 - if (ctx->sva) 389 - iommu_sva_unbind_device(ctx->sva); 390 - kfree(ctx); 391 - mutex_lock(&wq->wq_lock); 392 - idxd_wq_put(wq); 393 - mutex_unlock(&wq->wq_lock); 394 151 return 0; 395 152 } 396 153 ··· 502 297 struct idxd_cdev *idxd_cdev; 503 298 504 299 idxd_cdev = wq->idxd_cdev; 300 + ida_destroy(&file_ida); 505 301 wq->idxd_cdev = NULL; 506 302 cdev_device_del(&idxd_cdev->cdev, cdev_dev(idxd_cdev)); 507 303 put_device(cdev_dev(idxd_cdev)); ··· 536 330 } 537 331 538 332 mutex_lock(&wq->wq_lock); 333 + 334 + wq->wq = create_workqueue(dev_name(wq_confdev(wq))); 335 + if (!wq->wq) { 336 + rc = -ENOMEM; 337 + goto wq_err; 338 + } 339 + 539 340 wq->type = IDXD_WQT_USER; 540 341 rc = drv_enable_wq(wq); 541 342 if (rc < 0) ··· 561 348 err_cdev: 562 349 drv_disable_wq(wq); 563 350 err: 351 + destroy_workqueue(wq->wq); 564 352 wq->type = IDXD_WQT_NONE; 353 + wq_err: 565 354 mutex_unlock(&wq->wq_lock); 566 355 return rc; 567 356 } ··· 576 361 idxd_wq_del_cdev(wq); 577 362 drv_disable_wq(wq); 578 363 wq->type = IDXD_WQT_NONE; 364 + destroy_workqueue(wq->wq); 365 + wq->wq = NULL; 579 366 mutex_unlock(&wq->wq_lock); 580 367 } 581 368 ··· 623 406 unregister_chrdev_region(ictx[i].devt, MINORMASK); 624 407 ida_destroy(&ictx[i].minor_ida); 625 408 } 409 + } 410 + 411 + /** 412 + * idxd_copy_cr - copy completion record to user address space found by wq and 413 + * PASID 414 + * @wq: work queue 415 + * @pasid: PASID 416 + * @addr: user fault address to write 417 + * @cr: completion record 418 + * @len: number of bytes to copy 419 + * 420 + * This is called by a work that handles completion record fault. 421 + * 422 + * Return: number of bytes copied. 423 + */ 424 + int idxd_copy_cr(struct idxd_wq *wq, ioasid_t pasid, unsigned long addr, 425 + void *cr, int len) 426 + { 427 + struct device *dev = &wq->idxd->pdev->dev; 428 + int left = len, status_size = 1; 429 + struct idxd_user_context *ctx; 430 + struct mm_struct *mm; 431 + 432 + mutex_lock(&wq->uc_lock); 433 + 434 + ctx = xa_load(&wq->upasid_xa, pasid); 435 + if (!ctx) { 436 + dev_warn(dev, "No user context\n"); 437 + goto out; 438 + } 439 + 440 + mm = ctx->mm; 441 + /* 442 + * The completion record fault handling work is running in kernel 443 + * thread context. It temporarily switches to the mm to copy cr 444 + * to addr in the mm. 445 + */ 446 + kthread_use_mm(mm); 447 + left = copy_to_user((void __user *)addr + status_size, cr + status_size, 448 + len - status_size); 449 + /* 450 + * Copy status only after the rest of completion record is copied 451 + * successfully so that the user gets the complete completion record 452 + * when a non-zero status is polled. 453 + */ 454 + if (!left) { 455 + u8 status; 456 + 457 + /* 458 + * Ensure that the completion record's status field is written 459 + * after the rest of the completion record has been written. 460 + * This ensures that the user receives the correct completion 461 + * record information once polling for a non-zero status. 462 + */ 463 + wmb(); 464 + status = *(u8 *)cr; 465 + if (put_user(status, (u8 __user *)addr)) 466 + left += status_size; 467 + } else { 468 + left += status_size; 469 + } 470 + kthread_unuse_mm(mm); 471 + 472 + out: 473 + mutex_unlock(&wq->uc_lock); 474 + 475 + return len - left; 626 476 }
+138
drivers/dma/idxd/debugfs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright(c) 2021 Intel Corporation. All rights rsvd. */ 3 + #include <linux/init.h> 4 + #include <linux/kernel.h> 5 + #include <linux/module.h> 6 + #include <linux/pci.h> 7 + #include <linux/debugfs.h> 8 + #include <linux/io-64-nonatomic-lo-hi.h> 9 + #include <uapi/linux/idxd.h> 10 + #include "idxd.h" 11 + #include "registers.h" 12 + 13 + static struct dentry *idxd_debugfs_dir; 14 + 15 + static void dump_event_entry(struct idxd_device *idxd, struct seq_file *s, 16 + u16 index, int *count, bool processed) 17 + { 18 + struct idxd_evl *evl = idxd->evl; 19 + struct dsa_evl_entry *entry; 20 + struct dsa_completion_record *cr; 21 + u64 *raw; 22 + int i; 23 + int evl_strides = evl_ent_size(idxd) / sizeof(u64); 24 + 25 + entry = (struct dsa_evl_entry *)evl->log + index; 26 + 27 + if (!entry->e.desc_valid) 28 + return; 29 + 30 + seq_printf(s, "Event Log entry %d (real index %u) processed: %u\n", 31 + *count, index, processed); 32 + 33 + seq_printf(s, "desc valid %u wq idx valid %u\n" 34 + "batch %u fault rw %u priv %u error 0x%x\n" 35 + "wq idx %u op %#x pasid %u batch idx %u\n" 36 + "fault addr %#llx\n", 37 + entry->e.desc_valid, entry->e.wq_idx_valid, 38 + entry->e.batch, entry->e.fault_rw, entry->e.priv, 39 + entry->e.error, entry->e.wq_idx, entry->e.operation, 40 + entry->e.pasid, entry->e.batch_idx, entry->e.fault_addr); 41 + 42 + cr = &entry->cr; 43 + seq_printf(s, "status %#x result %#x fault_info %#x bytes_completed %u\n" 44 + "fault addr %#llx inv flags %#x\n\n", 45 + cr->status, cr->result, cr->fault_info, cr->bytes_completed, 46 + cr->fault_addr, cr->invalid_flags); 47 + 48 + raw = (u64 *)entry; 49 + 50 + for (i = 0; i < evl_strides; i++) 51 + seq_printf(s, "entry[%d] = %#llx\n", i, raw[i]); 52 + 53 + seq_puts(s, "\n"); 54 + *count += 1; 55 + } 56 + 57 + static int debugfs_evl_show(struct seq_file *s, void *d) 58 + { 59 + struct idxd_device *idxd = s->private; 60 + struct idxd_evl *evl = idxd->evl; 61 + union evl_status_reg evl_status; 62 + u16 h, t, evl_size, i; 63 + int count = 0; 64 + bool processed = true; 65 + 66 + if (!evl || !evl->log) 67 + return 0; 68 + 69 + spin_lock(&evl->lock); 70 + 71 + h = evl->head; 72 + evl_status.bits = ioread64(idxd->reg_base + IDXD_EVLSTATUS_OFFSET); 73 + t = evl_status.tail; 74 + evl_size = evl->size; 75 + 76 + seq_printf(s, "Event Log head %u tail %u interrupt pending %u\n\n", 77 + evl_status.head, evl_status.tail, evl_status.int_pending); 78 + 79 + i = t; 80 + while (1) { 81 + i = (i + 1) % evl_size; 82 + if (i == t) 83 + break; 84 + 85 + if (processed && i == h) 86 + processed = false; 87 + dump_event_entry(idxd, s, i, &count, processed); 88 + } 89 + 90 + spin_unlock(&evl->lock); 91 + return 0; 92 + } 93 + 94 + DEFINE_SHOW_ATTRIBUTE(debugfs_evl); 95 + 96 + int idxd_device_init_debugfs(struct idxd_device *idxd) 97 + { 98 + if (IS_ERR_OR_NULL(idxd_debugfs_dir)) 99 + return 0; 100 + 101 + idxd->dbgfs_dir = debugfs_create_dir(dev_name(idxd_confdev(idxd)), idxd_debugfs_dir); 102 + if (IS_ERR(idxd->dbgfs_dir)) 103 + return PTR_ERR(idxd->dbgfs_dir); 104 + 105 + if (idxd->evl) { 106 + idxd->dbgfs_evl_file = debugfs_create_file("event_log", 0400, 107 + idxd->dbgfs_dir, idxd, 108 + &debugfs_evl_fops); 109 + if (IS_ERR(idxd->dbgfs_evl_file)) { 110 + debugfs_remove_recursive(idxd->dbgfs_dir); 111 + idxd->dbgfs_dir = NULL; 112 + return PTR_ERR(idxd->dbgfs_evl_file); 113 + } 114 + } 115 + 116 + return 0; 117 + } 118 + 119 + void idxd_device_remove_debugfs(struct idxd_device *idxd) 120 + { 121 + debugfs_remove_recursive(idxd->dbgfs_dir); 122 + } 123 + 124 + int idxd_init_debugfs(void) 125 + { 126 + if (!debugfs_initialized()) 127 + return 0; 128 + 129 + idxd_debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL); 130 + if (IS_ERR(idxd_debugfs_dir)) 131 + return PTR_ERR(idxd_debugfs_dir); 132 + return 0; 133 + } 134 + 135 + void idxd_remove_debugfs(void) 136 + { 137 + debugfs_remove_recursive(idxd_debugfs_dir); 138 + }
+111 -2
drivers/dma/idxd/device.c
··· 752 752 spin_unlock(&idxd->dev_lock); 753 753 } 754 754 755 + static int idxd_device_evl_setup(struct idxd_device *idxd) 756 + { 757 + union gencfg_reg gencfg; 758 + union evlcfg_reg evlcfg; 759 + union genctrl_reg genctrl; 760 + struct device *dev = &idxd->pdev->dev; 761 + void *addr; 762 + dma_addr_t dma_addr; 763 + int size; 764 + struct idxd_evl *evl = idxd->evl; 765 + unsigned long *bmap; 766 + int rc; 767 + 768 + if (!evl) 769 + return 0; 770 + 771 + size = evl_size(idxd); 772 + 773 + bmap = bitmap_zalloc(size, GFP_KERNEL); 774 + if (!bmap) { 775 + rc = -ENOMEM; 776 + goto err_bmap; 777 + } 778 + 779 + /* 780 + * Address needs to be page aligned. However, dma_alloc_coherent() provides 781 + * at minimal page size aligned address. No manual alignment required. 782 + */ 783 + addr = dma_alloc_coherent(dev, size, &dma_addr, GFP_KERNEL); 784 + if (!addr) { 785 + rc = -ENOMEM; 786 + goto err_alloc; 787 + } 788 + 789 + memset(addr, 0, size); 790 + 791 + spin_lock(&evl->lock); 792 + evl->log = addr; 793 + evl->dma = dma_addr; 794 + evl->log_size = size; 795 + evl->bmap = bmap; 796 + 797 + memset(&evlcfg, 0, sizeof(evlcfg)); 798 + evlcfg.bits[0] = dma_addr & GENMASK(63, 12); 799 + evlcfg.size = evl->size; 800 + 801 + iowrite64(evlcfg.bits[0], idxd->reg_base + IDXD_EVLCFG_OFFSET); 802 + iowrite64(evlcfg.bits[1], idxd->reg_base + IDXD_EVLCFG_OFFSET + 8); 803 + 804 + genctrl.bits = ioread32(idxd->reg_base + IDXD_GENCTRL_OFFSET); 805 + genctrl.evl_int_en = 1; 806 + iowrite32(genctrl.bits, idxd->reg_base + IDXD_GENCTRL_OFFSET); 807 + 808 + gencfg.bits = ioread32(idxd->reg_base + IDXD_GENCFG_OFFSET); 809 + gencfg.evl_en = 1; 810 + iowrite32(gencfg.bits, idxd->reg_base + IDXD_GENCFG_OFFSET); 811 + 812 + spin_unlock(&evl->lock); 813 + return 0; 814 + 815 + err_alloc: 816 + bitmap_free(bmap); 817 + err_bmap: 818 + return rc; 819 + } 820 + 821 + static void idxd_device_evl_free(struct idxd_device *idxd) 822 + { 823 + union gencfg_reg gencfg; 824 + union genctrl_reg genctrl; 825 + struct device *dev = &idxd->pdev->dev; 826 + struct idxd_evl *evl = idxd->evl; 827 + 828 + gencfg.bits = ioread32(idxd->reg_base + IDXD_GENCFG_OFFSET); 829 + if (!gencfg.evl_en) 830 + return; 831 + 832 + spin_lock(&evl->lock); 833 + gencfg.evl_en = 0; 834 + iowrite32(gencfg.bits, idxd->reg_base + IDXD_GENCFG_OFFSET); 835 + 836 + genctrl.bits = ioread32(idxd->reg_base + IDXD_GENCTRL_OFFSET); 837 + genctrl.evl_int_en = 0; 838 + iowrite32(genctrl.bits, idxd->reg_base + IDXD_GENCTRL_OFFSET); 839 + 840 + iowrite64(0, idxd->reg_base + IDXD_EVLCFG_OFFSET); 841 + iowrite64(0, idxd->reg_base + IDXD_EVLCFG_OFFSET + 8); 842 + 843 + dma_free_coherent(dev, evl->log_size, evl->log, evl->dma); 844 + bitmap_free(evl->bmap); 845 + evl->log = NULL; 846 + evl->size = IDXD_EVL_SIZE_MIN; 847 + spin_unlock(&evl->lock); 848 + } 849 + 755 850 static void idxd_group_config_write(struct idxd_group *group) 756 851 { 757 852 struct idxd_device *idxd = group->idxd; ··· 967 872 wq->wqcfg->priority = wq->priority; 968 873 969 874 if (idxd->hw.gen_cap.block_on_fault && 970 - test_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags)) 875 + test_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags) && 876 + !test_bit(WQ_FLAG_PRS_DISABLE, &wq->flags)) 971 877 wq->wqcfg->bof = 1; 972 878 973 879 if (idxd->hw.wq_cap.wq_ats_support) 974 880 wq->wqcfg->wq_ats_disable = test_bit(WQ_FLAG_ATS_DISABLE, &wq->flags); 881 + 882 + if (idxd->hw.wq_cap.wq_prs_support) 883 + wq->wqcfg->wq_prs_disable = test_bit(WQ_FLAG_PRS_DISABLE, &wq->flags); 975 884 976 885 /* bytes 12-15 */ 977 886 wq->wqcfg->max_xfer_shift = ilog2(wq->max_xfer_bytes); ··· 1550 1451 if (rc < 0) 1551 1452 return -ENXIO; 1552 1453 1454 + rc = idxd_device_evl_setup(idxd); 1455 + if (rc < 0) { 1456 + idxd->cmd_status = IDXD_SCMD_DEV_EVL_ERR; 1457 + return rc; 1458 + } 1459 + 1553 1460 /* Start device */ 1554 1461 rc = idxd_device_enable(idxd); 1555 - if (rc < 0) 1462 + if (rc < 0) { 1463 + idxd_device_evl_free(idxd); 1556 1464 return rc; 1465 + } 1557 1466 1558 1467 /* Setup DMA device without channels */ 1559 1468 rc = idxd_register_dma_device(idxd); 1560 1469 if (rc < 0) { 1561 1470 idxd_device_disable(idxd); 1471 + idxd_device_evl_free(idxd); 1562 1472 idxd->cmd_status = IDXD_SCMD_DEV_DMA_ERR; 1563 1473 return rc; 1564 1474 } ··· 1596 1488 idxd_device_disable(idxd); 1597 1489 if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) 1598 1490 idxd_device_reset(idxd); 1491 + idxd_device_evl_free(idxd); 1599 1492 } 1600 1493 1601 1494 static enum idxd_dev_type dev_types[] = {
+67
drivers/dma/idxd/idxd.h
··· 32 32 IDXD_DEV_GROUP, 33 33 IDXD_DEV_ENGINE, 34 34 IDXD_DEV_CDEV, 35 + IDXD_DEV_CDEV_FILE, 35 36 IDXD_DEV_MAX_TYPE, 36 37 }; 37 38 ··· 128 127 129 128 #define IDXD_MAX_PRIORITY 0xf 130 129 130 + enum { 131 + COUNTER_FAULTS = 0, 132 + COUNTER_FAULT_FAILS, 133 + COUNTER_MAX 134 + }; 135 + 131 136 enum idxd_wq_state { 132 137 IDXD_WQ_DISABLED = 0, 133 138 IDXD_WQ_ENABLED, ··· 143 136 WQ_FLAG_DEDICATED = 0, 144 137 WQ_FLAG_BLOCK_ON_FAULT, 145 138 WQ_FLAG_ATS_DISABLE, 139 + WQ_FLAG_PRS_DISABLE, 146 140 }; 147 141 148 142 enum idxd_wq_type { ··· 193 185 struct idxd_dev idxd_dev; 194 186 struct idxd_cdev *idxd_cdev; 195 187 struct wait_queue_head err_queue; 188 + struct workqueue_struct *wq; 196 189 struct idxd_device *idxd; 197 190 int id; 198 191 struct idxd_irq_entry ie; ··· 223 214 char name[WQ_NAME_SIZE + 1]; 224 215 u64 max_xfer_bytes; 225 216 u32 max_batch_size; 217 + 218 + /* Lock to protect upasid_xa access. */ 219 + struct mutex uc_lock; 220 + struct xarray upasid_xa; 226 221 }; 227 222 228 223 struct idxd_engine { ··· 245 232 union engine_cap_reg engine_cap; 246 233 struct opcap opcap; 247 234 u32 cmd_cap; 235 + union iaa_cap_reg iaa_cap; 248 236 }; 249 237 250 238 enum idxd_device_state { ··· 272 258 struct device_type *dev_type; 273 259 int compl_size; 274 260 int align; 261 + int evl_cr_off; 262 + int cr_status_off; 263 + int cr_result_off; 264 + }; 265 + 266 + struct idxd_evl { 267 + /* Lock to protect event log access. */ 268 + spinlock_t lock; 269 + void *log; 270 + dma_addr_t dma; 271 + /* Total size of event log = number of entries * entry size. */ 272 + unsigned int log_size; 273 + /* The number of entries in the event log. */ 274 + u16 size; 275 + u16 head; 276 + unsigned long *bmap; 277 + bool batch_fail[IDXD_MAX_BATCH_IDENT]; 278 + }; 279 + 280 + struct idxd_evl_fault { 281 + struct work_struct work; 282 + struct idxd_wq *wq; 283 + u8 status; 284 + 285 + /* make this last member always */ 286 + struct __evl_entry entry[]; 275 287 }; 276 288 277 289 struct idxd_device { ··· 356 316 struct idxd_pmu *idxd_pmu; 357 317 358 318 unsigned long *opcap_bmap; 319 + struct idxd_evl *evl; 320 + struct kmem_cache *evl_cache; 321 + 322 + struct dentry *dbgfs_dir; 323 + struct dentry *dbgfs_evl_file; 359 324 }; 325 + 326 + static inline unsigned int evl_ent_size(struct idxd_device *idxd) 327 + { 328 + return idxd->hw.gen_cap.evl_support ? 329 + (32 * (1 << idxd->hw.gen_cap.evl_support)) : 0; 330 + } 331 + 332 + static inline unsigned int evl_size(struct idxd_device *idxd) 333 + { 334 + return idxd->evl->size * evl_ent_size(idxd); 335 + } 360 336 361 337 /* IDXD software descriptor */ 362 338 struct idxd_desc { ··· 407 351 #define engine_confdev(engine) &engine->idxd_dev.conf_dev 408 352 #define group_confdev(group) &group->idxd_dev.conf_dev 409 353 #define cdev_dev(cdev) &cdev->idxd_dev.conf_dev 354 + #define user_ctx_dev(ctx) (&(ctx)->idxd_dev.conf_dev) 410 355 411 356 #define confdev_to_idxd_dev(dev) container_of(dev, struct idxd_dev, conf_dev) 412 357 #define idxd_dev_to_idxd(idxd_dev) container_of(idxd_dev, struct idxd_device, idxd_dev) ··· 655 598 void idxd_unregister_driver(void); 656 599 void idxd_wqs_quiesce(struct idxd_device *idxd); 657 600 bool idxd_queue_int_handle_resubmit(struct idxd_desc *desc); 601 + void multi_u64_to_bmap(unsigned long *bmap, u64 *val, int count); 658 602 659 603 /* device interrupt control */ 660 604 irqreturn_t idxd_misc_thread(int vec, void *data); ··· 720 662 int idxd_cdev_get_major(struct idxd_device *idxd); 721 663 int idxd_wq_add_cdev(struct idxd_wq *wq); 722 664 void idxd_wq_del_cdev(struct idxd_wq *wq); 665 + int idxd_copy_cr(struct idxd_wq *wq, ioasid_t pasid, unsigned long addr, 666 + void *buf, int len); 667 + void idxd_user_counter_increment(struct idxd_wq *wq, u32 pasid, int index); 723 668 724 669 /* perfmon */ 725 670 #if IS_ENABLED(CONFIG_INTEL_IDXD_PERFMON) ··· 738 677 static inline void perfmon_init(void) {} 739 678 static inline void perfmon_exit(void) {} 740 679 #endif 680 + 681 + /* debugfs */ 682 + int idxd_device_init_debugfs(struct idxd_device *idxd); 683 + void idxd_device_remove_debugfs(struct idxd_device *idxd); 684 + int idxd_init_debugfs(void); 685 + void idxd_remove_debugfs(void); 741 686 742 687 #endif
+58 -2
drivers/dma/idxd/init.c
··· 9 9 #include <linux/delay.h> 10 10 #include <linux/dma-mapping.h> 11 11 #include <linux/workqueue.h> 12 - #include <linux/aer.h> 13 12 #include <linux/fs.h> 14 13 #include <linux/io-64-nonatomic-lo-hi.h> 15 14 #include <linux/device.h> ··· 46 47 .compl_size = sizeof(struct dsa_completion_record), 47 48 .align = 32, 48 49 .dev_type = &dsa_device_type, 50 + .evl_cr_off = offsetof(struct dsa_evl_entry, cr), 51 + .cr_status_off = offsetof(struct dsa_completion_record, status), 52 + .cr_result_off = offsetof(struct dsa_completion_record, result), 49 53 }, 50 54 [IDXD_TYPE_IAX] = { 51 55 .name_prefix = "iax", ··· 56 54 .compl_size = sizeof(struct iax_completion_record), 57 55 .align = 64, 58 56 .dev_type = &iax_device_type, 57 + .evl_cr_off = offsetof(struct iax_evl_entry, cr), 58 + .cr_status_off = offsetof(struct iax_completion_record, status), 59 + .cr_result_off = offsetof(struct iax_completion_record, error_code), 59 60 }, 60 61 }; 61 62 ··· 205 200 } 206 201 bitmap_copy(wq->opcap_bmap, idxd->opcap_bmap, IDXD_MAX_OPCAP_BITS); 207 202 } 203 + mutex_init(&wq->uc_lock); 204 + xa_init(&wq->upasid_xa); 208 205 idxd->wqs[i] = wq; 209 206 } 210 207 ··· 339 332 destroy_workqueue(idxd->wq); 340 333 } 341 334 335 + static int idxd_init_evl(struct idxd_device *idxd) 336 + { 337 + struct device *dev = &idxd->pdev->dev; 338 + struct idxd_evl *evl; 339 + 340 + if (idxd->hw.gen_cap.evl_support == 0) 341 + return 0; 342 + 343 + evl = kzalloc_node(sizeof(*evl), GFP_KERNEL, dev_to_node(dev)); 344 + if (!evl) 345 + return -ENOMEM; 346 + 347 + spin_lock_init(&evl->lock); 348 + evl->size = IDXD_EVL_SIZE_MIN; 349 + 350 + idxd->evl_cache = kmem_cache_create(dev_name(idxd_confdev(idxd)), 351 + sizeof(struct idxd_evl_fault) + evl_ent_size(idxd), 352 + 0, 0, NULL); 353 + if (!idxd->evl_cache) { 354 + kfree(evl); 355 + return -ENOMEM; 356 + } 357 + 358 + idxd->evl = evl; 359 + return 0; 360 + } 361 + 342 362 static int idxd_setup_internals(struct idxd_device *idxd) 343 363 { 344 364 struct device *dev = &idxd->pdev->dev; ··· 391 357 goto err_wkq_create; 392 358 } 393 359 360 + rc = idxd_init_evl(idxd); 361 + if (rc < 0) 362 + goto err_evl; 363 + 394 364 return 0; 395 365 366 + err_evl: 367 + destroy_workqueue(idxd->wq); 396 368 err_wkq_create: 397 369 for (i = 0; i < idxd->max_groups; i++) 398 370 put_device(group_confdev(idxd->groups[i])); ··· 429 389 dev_dbg(dev, "IDXD Perfmon Offset: %#x\n", idxd->perfmon_offset); 430 390 } 431 391 432 - static void multi_u64_to_bmap(unsigned long *bmap, u64 *val, int count) 392 + void multi_u64_to_bmap(unsigned long *bmap, u64 *val, int count) 433 393 { 434 394 int i, j, nr; 435 395 ··· 501 461 dev_dbg(dev, "opcap[%d]: %#llx\n", i, idxd->hw.opcap.bits[i]); 502 462 } 503 463 multi_u64_to_bmap(idxd->opcap_bmap, &idxd->hw.opcap.bits[0], 4); 464 + 465 + /* read iaa cap */ 466 + if (idxd->data->type == IDXD_TYPE_IAX && idxd->hw.version >= DEVICE_VERSION_2) 467 + idxd->hw.iaa_cap.bits = ioread64(idxd->reg_base + IDXD_IAACAP_OFFSET); 504 468 } 505 469 506 470 static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_data *data) ··· 705 661 goto err_dev_register; 706 662 } 707 663 664 + rc = idxd_device_init_debugfs(idxd); 665 + if (rc) 666 + dev_warn(dev, "IDXD debugfs failed to setup\n"); 667 + 708 668 dev_info(&pdev->dev, "Intel(R) Accelerator Device (v%x)\n", 709 669 idxd->hw.version); 710 670 ··· 771 723 idxd_shutdown(pdev); 772 724 if (device_pasid_enabled(idxd)) 773 725 idxd_disable_system_pasid(idxd); 726 + idxd_device_remove_debugfs(idxd); 774 727 775 728 irq_entry = idxd_get_ie(idxd, 0); 776 729 free_irq(irq_entry->vector, irq_entry); ··· 829 780 if (err) 830 781 goto err_cdev_register; 831 782 783 + err = idxd_init_debugfs(); 784 + if (err) 785 + goto err_debugfs; 786 + 832 787 err = pci_register_driver(&idxd_pci_driver); 833 788 if (err) 834 789 goto err_pci_register; ··· 840 787 return 0; 841 788 842 789 err_pci_register: 790 + idxd_remove_debugfs(); 791 + err_debugfs: 843 792 idxd_cdev_remove(); 844 793 err_cdev_register: 845 794 idxd_driver_unregister(&idxd_user_drv); ··· 862 807 pci_unregister_driver(&idxd_pci_driver); 863 808 idxd_cdev_remove(); 864 809 perfmon_exit(); 810 + idxd_remove_debugfs(); 865 811 } 866 812 module_exit(idxd_exit_module);
+184 -26
drivers/dma/idxd/irq.c
··· 7 7 #include <linux/io-64-nonatomic-lo-hi.h> 8 8 #include <linux/dmaengine.h> 9 9 #include <linux/delay.h> 10 + #include <linux/iommu.h> 11 + #include <linux/sched/mm.h> 10 12 #include <uapi/linux/idxd.h> 11 13 #include "../dmaengine.h" 12 14 #include "idxd.h" ··· 219 217 kfree(revoke); 220 218 } 221 219 222 - static int process_misc_interrupts(struct idxd_device *idxd, u32 cause) 220 + static void idxd_evl_fault_work(struct work_struct *work) 223 221 { 222 + struct idxd_evl_fault *fault = container_of(work, struct idxd_evl_fault, work); 223 + struct idxd_wq *wq = fault->wq; 224 + struct idxd_device *idxd = wq->idxd; 225 + struct device *dev = &idxd->pdev->dev; 226 + struct idxd_evl *evl = idxd->evl; 227 + struct __evl_entry *entry_head = fault->entry; 228 + void *cr = (void *)entry_head + idxd->data->evl_cr_off; 229 + int cr_size = idxd->data->compl_size; 230 + u8 *status = (u8 *)cr + idxd->data->cr_status_off; 231 + u8 *result = (u8 *)cr + idxd->data->cr_result_off; 232 + int copied, copy_size; 233 + bool *bf; 234 + 235 + switch (fault->status) { 236 + case DSA_COMP_CRA_XLAT: 237 + if (entry_head->batch && entry_head->first_err_in_batch) 238 + evl->batch_fail[entry_head->batch_id] = false; 239 + 240 + copy_size = cr_size; 241 + idxd_user_counter_increment(wq, entry_head->pasid, COUNTER_FAULTS); 242 + break; 243 + case DSA_COMP_BATCH_EVL_ERR: 244 + bf = &evl->batch_fail[entry_head->batch_id]; 245 + 246 + copy_size = entry_head->rcr || *bf ? cr_size : 0; 247 + if (*bf) { 248 + if (*status == DSA_COMP_SUCCESS) 249 + *status = DSA_COMP_BATCH_FAIL; 250 + *result = 1; 251 + *bf = false; 252 + } 253 + idxd_user_counter_increment(wq, entry_head->pasid, COUNTER_FAULTS); 254 + break; 255 + case DSA_COMP_DRAIN_EVL: 256 + copy_size = cr_size; 257 + break; 258 + default: 259 + copy_size = 0; 260 + dev_dbg_ratelimited(dev, "Unrecognized error code: %#x\n", fault->status); 261 + break; 262 + } 263 + 264 + if (copy_size == 0) 265 + return; 266 + 267 + /* 268 + * Copy completion record to fault_addr in user address space 269 + * that is found by wq and PASID. 270 + */ 271 + copied = idxd_copy_cr(wq, entry_head->pasid, entry_head->fault_addr, 272 + cr, copy_size); 273 + /* 274 + * The task that triggered the page fault is unknown currently 275 + * because multiple threads may share the user address 276 + * space or the task exits already before this fault. 277 + * So if the copy fails, SIGSEGV can not be sent to the task. 278 + * Just print an error for the failure. The user application 279 + * waiting for the completion record will time out on this 280 + * failure. 281 + */ 282 + switch (fault->status) { 283 + case DSA_COMP_CRA_XLAT: 284 + if (copied != copy_size) { 285 + idxd_user_counter_increment(wq, entry_head->pasid, COUNTER_FAULT_FAILS); 286 + dev_dbg_ratelimited(dev, "Failed to write to completion record: (%d:%d)\n", 287 + copy_size, copied); 288 + if (entry_head->batch) 289 + evl->batch_fail[entry_head->batch_id] = true; 290 + } 291 + break; 292 + case DSA_COMP_BATCH_EVL_ERR: 293 + if (copied != copy_size) { 294 + idxd_user_counter_increment(wq, entry_head->pasid, COUNTER_FAULT_FAILS); 295 + dev_dbg_ratelimited(dev, "Failed to write to batch completion record: (%d:%d)\n", 296 + copy_size, copied); 297 + } 298 + break; 299 + case DSA_COMP_DRAIN_EVL: 300 + if (copied != copy_size) 301 + dev_dbg_ratelimited(dev, "Failed to write to drain completion record: (%d:%d)\n", 302 + copy_size, copied); 303 + break; 304 + } 305 + 306 + kmem_cache_free(idxd->evl_cache, fault); 307 + } 308 + 309 + static void process_evl_entry(struct idxd_device *idxd, 310 + struct __evl_entry *entry_head, unsigned int index) 311 + { 312 + struct device *dev = &idxd->pdev->dev; 313 + struct idxd_evl *evl = idxd->evl; 314 + u8 status; 315 + 316 + if (test_bit(index, evl->bmap)) { 317 + clear_bit(index, evl->bmap); 318 + } else { 319 + status = DSA_COMP_STATUS(entry_head->error); 320 + 321 + if (status == DSA_COMP_CRA_XLAT || status == DSA_COMP_DRAIN_EVL || 322 + status == DSA_COMP_BATCH_EVL_ERR) { 323 + struct idxd_evl_fault *fault; 324 + int ent_size = evl_ent_size(idxd); 325 + 326 + if (entry_head->rci) 327 + dev_dbg(dev, "Completion Int Req set, ignoring!\n"); 328 + 329 + if (!entry_head->rcr && status == DSA_COMP_DRAIN_EVL) 330 + return; 331 + 332 + fault = kmem_cache_alloc(idxd->evl_cache, GFP_ATOMIC); 333 + if (fault) { 334 + struct idxd_wq *wq = idxd->wqs[entry_head->wq_idx]; 335 + 336 + fault->wq = wq; 337 + fault->status = status; 338 + memcpy(&fault->entry, entry_head, ent_size); 339 + INIT_WORK(&fault->work, idxd_evl_fault_work); 340 + queue_work(wq->wq, &fault->work); 341 + } else { 342 + dev_warn(dev, "Failed to service fault work.\n"); 343 + } 344 + } else { 345 + dev_warn_ratelimited(dev, "Device error %#x operation: %#x fault addr: %#llx\n", 346 + status, entry_head->operation, 347 + entry_head->fault_addr); 348 + } 349 + } 350 + } 351 + 352 + static void process_evl_entries(struct idxd_device *idxd) 353 + { 354 + union evl_status_reg evl_status; 355 + unsigned int h, t; 356 + struct idxd_evl *evl = idxd->evl; 357 + struct __evl_entry *entry_head; 358 + unsigned int ent_size = evl_ent_size(idxd); 359 + u32 size; 360 + 361 + evl_status.bits = 0; 362 + evl_status.int_pending = 1; 363 + 364 + spin_lock(&evl->lock); 365 + /* Clear interrupt pending bit */ 366 + iowrite32(evl_status.bits_upper32, 367 + idxd->reg_base + IDXD_EVLSTATUS_OFFSET + sizeof(u32)); 368 + h = evl->head; 369 + evl_status.bits = ioread64(idxd->reg_base + IDXD_EVLSTATUS_OFFSET); 370 + t = evl_status.tail; 371 + size = idxd->evl->size; 372 + 373 + while (h != t) { 374 + entry_head = (struct __evl_entry *)(evl->log + (h * ent_size)); 375 + process_evl_entry(idxd, entry_head, h); 376 + h = (h + 1) % size; 377 + } 378 + 379 + evl->head = h; 380 + evl_status.head = h; 381 + iowrite32(evl_status.bits_lower32, idxd->reg_base + IDXD_EVLSTATUS_OFFSET); 382 + spin_unlock(&evl->lock); 383 + } 384 + 385 + irqreturn_t idxd_misc_thread(int vec, void *data) 386 + { 387 + struct idxd_irq_entry *irq_entry = data; 388 + struct idxd_device *idxd = ie_to_idxd(irq_entry); 224 389 struct device *dev = &idxd->pdev->dev; 225 390 union gensts_reg gensts; 226 391 u32 val = 0; 227 392 int i; 228 393 bool err = false; 394 + u32 cause; 395 + 396 + cause = ioread32(idxd->reg_base + IDXD_INTCAUSE_OFFSET); 397 + if (!cause) 398 + return IRQ_NONE; 399 + 400 + iowrite32(cause, idxd->reg_base + IDXD_INTCAUSE_OFFSET); 229 401 230 402 if (cause & IDXD_INTC_HALT_STATE) 231 403 goto halt; ··· 471 295 perfmon_counter_overflow(idxd); 472 296 } 473 297 298 + if (cause & IDXD_INTC_EVL) { 299 + val |= IDXD_INTC_EVL; 300 + process_evl_entries(idxd); 301 + } 302 + 474 303 val ^= cause; 475 304 if (val) 476 305 dev_warn_once(dev, "Unexpected interrupt cause bits set: %#x\n", 477 306 val); 478 307 479 308 if (!err) 480 - return 0; 309 + goto out; 481 310 482 311 halt: 483 312 gensts.bits = ioread32(idxd->reg_base + IDXD_GENSTATS_OFFSET); ··· 505 324 "idxd halted, need %s.\n", 506 325 gensts.reset_type == IDXD_DEVICE_RESET_FLR ? 507 326 "FLR" : "system reset"); 508 - return -ENXIO; 509 327 } 510 328 } 511 329 512 - return 0; 513 - } 514 - 515 - irqreturn_t idxd_misc_thread(int vec, void *data) 516 - { 517 - struct idxd_irq_entry *irq_entry = data; 518 - struct idxd_device *idxd = ie_to_idxd(irq_entry); 519 - int rc; 520 - u32 cause; 521 - 522 - cause = ioread32(idxd->reg_base + IDXD_INTCAUSE_OFFSET); 523 - if (cause) 524 - iowrite32(cause, idxd->reg_base + IDXD_INTCAUSE_OFFSET); 525 - 526 - while (cause) { 527 - rc = process_misc_interrupts(idxd, cause); 528 - if (rc < 0) 529 - break; 530 - cause = ioread32(idxd->reg_base + IDXD_INTCAUSE_OFFSET); 531 - if (cause) 532 - iowrite32(cause, idxd->reg_base + IDXD_INTCAUSE_OFFSET); 533 - } 534 - 330 + out: 535 331 return IRQ_HANDLED; 536 332 } 537 333
+121 -5
drivers/dma/idxd/registers.h
··· 3 3 #ifndef _IDXD_REGISTERS_H_ 4 4 #define _IDXD_REGISTERS_H_ 5 5 6 + #include <uapi/linux/idxd.h> 7 + 6 8 /* PCI Config */ 7 9 #define PCI_DEVICE_ID_INTEL_DSA_SPR0 0x0b25 8 10 #define PCI_DEVICE_ID_INTEL_IAX_SPR0 0x0cfe ··· 33 31 u64 rsvd:3; 34 32 u64 dest_readback:1; 35 33 u64 drain_readback:1; 36 - u64 rsvd2:6; 34 + u64 rsvd2:3; 35 + u64 evl_support:2; 36 + u64 batch_continuation:1; 37 37 u64 max_xfer_shift:5; 38 38 u64 max_batch_shift:4; 39 39 u64 max_ims_mult:6; ··· 59 55 u64 occupancy:1; 60 56 u64 occupancy_int:1; 61 57 u64 op_config:1; 62 - u64 rsvd3:9; 58 + u64 wq_prs_support:1; 59 + u64 rsvd4:8; 63 60 }; 64 61 u64 bits; 65 62 } __packed; ··· 122 117 u32 rdbuf_limit:8; 123 118 u32 rsvd:4; 124 119 u32 user_int_en:1; 125 - u32 rsvd2:19; 120 + u32 evl_en:1; 121 + u32 rsvd2:18; 126 122 }; 127 123 u32 bits; 128 124 } __packed; ··· 133 127 struct { 134 128 u32 softerr_int_en:1; 135 129 u32 halt_int_en:1; 136 - u32 rsvd:30; 130 + u32 evl_int_en:1; 131 + u32 rsvd:29; 137 132 }; 138 133 u32 bits; 139 134 } __packed; ··· 169 162 #define IDXD_INTC_OCCUPY 0x04 170 163 #define IDXD_INTC_PERFMON_OVFL 0x08 171 164 #define IDXD_INTC_HALT_STATE 0x10 165 + #define IDXD_INTC_EVL 0x20 172 166 #define IDXD_INTC_INT_HANDLE_REVOKED 0x80000000 173 167 174 168 #define IDXD_CMD_OFFSET 0xa0 ··· 284 276 u64 bits[4]; 285 277 } __packed; 286 278 279 + union iaa_cap_reg { 280 + struct { 281 + u64 dec_aecs_format_ver:1; 282 + u64 drop_init_bits:1; 283 + u64 chaining:1; 284 + u64 force_array_output_mod:1; 285 + u64 load_part_aecs:1; 286 + u64 comp_early_abort:1; 287 + u64 nested_comp:1; 288 + u64 diction_comp:1; 289 + u64 header_gen:1; 290 + u64 crypto_gcm:1; 291 + u64 crypto_cfb:1; 292 + u64 crypto_xts:1; 293 + u64 rsvd:52; 294 + }; 295 + u64 bits; 296 + } __packed; 297 + 298 + #define IDXD_IAACAP_OFFSET 0x180 299 + 300 + #define IDXD_EVLCFG_OFFSET 0xe0 301 + union evlcfg_reg { 302 + struct { 303 + u64 pasid_en:1; 304 + u64 priv:1; 305 + u64 rsvd:10; 306 + u64 base_addr:52; 307 + 308 + u64 size:16; 309 + u64 pasid:20; 310 + u64 rsvd2:28; 311 + }; 312 + u64 bits[2]; 313 + } __packed; 314 + 315 + #define IDXD_EVL_SIZE_MIN 0x0040 316 + #define IDXD_EVL_SIZE_MAX 0xffff 317 + 287 318 union msix_perm { 288 319 struct { 289 320 u32 rsvd:2; ··· 372 325 u32 mode:1; /* shared or dedicated */ 373 326 u32 bof:1; /* block on fault */ 374 327 u32 wq_ats_disable:1; 375 - u32 rsvd2:1; 328 + u32 wq_prs_disable:1; 376 329 u32 priority:4; 377 330 u32 pasid:20; 378 331 u32 pasid_en:1; ··· 558 511 u64 eng:8; 559 512 }; 560 513 u64 val; 514 + } __packed; 515 + 516 + #define IDXD_EVLSTATUS_OFFSET 0xf0 517 + 518 + union evl_status_reg { 519 + struct { 520 + u32 head:16; 521 + u32 rsvd:16; 522 + u32 tail:16; 523 + u32 rsvd2:14; 524 + u32 int_pending:1; 525 + u32 rsvd3:1; 526 + }; 527 + struct { 528 + u32 bits_lower32; 529 + u32 bits_upper32; 530 + }; 531 + u64 bits; 532 + } __packed; 533 + 534 + #define IDXD_MAX_BATCH_IDENT 256 535 + 536 + struct __evl_entry { 537 + u64 rsvd:2; 538 + u64 desc_valid:1; 539 + u64 wq_idx_valid:1; 540 + u64 batch:1; 541 + u64 fault_rw:1; 542 + u64 priv:1; 543 + u64 err_info_valid:1; 544 + u64 error:8; 545 + u64 wq_idx:8; 546 + u64 batch_id:8; 547 + u64 operation:8; 548 + u64 pasid:20; 549 + u64 rsvd2:4; 550 + 551 + u16 batch_idx; 552 + u16 rsvd3; 553 + union { 554 + /* Invalid Flags 0x11 */ 555 + u32 invalid_flags; 556 + /* Invalid Int Handle 0x19 */ 557 + /* Page fault 0x1a */ 558 + /* Page fault 0x06, 0x1f, only operand_id */ 559 + /* Page fault before drain or in batch, 0x26, 0x27 */ 560 + struct { 561 + u16 int_handle; 562 + u16 rci:1; 563 + u16 ims:1; 564 + u16 rcr:1; 565 + u16 first_err_in_batch:1; 566 + u16 rsvd4_2:9; 567 + u16 operand_id:3; 568 + }; 569 + }; 570 + u64 fault_addr; 571 + u64 rsvd5; 572 + } __packed; 573 + 574 + struct dsa_evl_entry { 575 + struct __evl_entry e; 576 + struct dsa_completion_record cr; 577 + } __packed; 578 + 579 + struct iax_evl_entry { 580 + struct __evl_entry e; 581 + u64 rsvd[4]; 582 + struct iax_completion_record cr; 561 583 } __packed; 562 584 563 585 #endif
+138 -8
drivers/dma/idxd/sysfs.c
··· 822 822 if (rc < 0) 823 823 return rc; 824 824 825 - if (bof) 825 + if (bof) { 826 + if (test_bit(WQ_FLAG_PRS_DISABLE, &wq->flags)) 827 + return -EOPNOTSUPP; 828 + 826 829 set_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags); 827 - else 830 + } else { 828 831 clear_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags); 832 + } 829 833 830 834 return count; 831 835 } ··· 1113 1109 static struct device_attribute dev_attr_wq_ats_disable = 1114 1110 __ATTR(ats_disable, 0644, wq_ats_disable_show, wq_ats_disable_store); 1115 1111 1112 + static ssize_t wq_prs_disable_show(struct device *dev, struct device_attribute *attr, char *buf) 1113 + { 1114 + struct idxd_wq *wq = confdev_to_wq(dev); 1115 + 1116 + return sysfs_emit(buf, "%u\n", test_bit(WQ_FLAG_PRS_DISABLE, &wq->flags)); 1117 + } 1118 + 1119 + static ssize_t wq_prs_disable_store(struct device *dev, struct device_attribute *attr, 1120 + const char *buf, size_t count) 1121 + { 1122 + struct idxd_wq *wq = confdev_to_wq(dev); 1123 + struct idxd_device *idxd = wq->idxd; 1124 + bool prs_dis; 1125 + int rc; 1126 + 1127 + if (wq->state != IDXD_WQ_DISABLED) 1128 + return -EPERM; 1129 + 1130 + if (!idxd->hw.wq_cap.wq_prs_support) 1131 + return -EOPNOTSUPP; 1132 + 1133 + rc = kstrtobool(buf, &prs_dis); 1134 + if (rc < 0) 1135 + return rc; 1136 + 1137 + if (prs_dis) { 1138 + set_bit(WQ_FLAG_PRS_DISABLE, &wq->flags); 1139 + /* when PRS is disabled, BOF needs to be off as well */ 1140 + clear_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags); 1141 + } else { 1142 + clear_bit(WQ_FLAG_PRS_DISABLE, &wq->flags); 1143 + } 1144 + return count; 1145 + } 1146 + 1147 + static struct device_attribute dev_attr_wq_prs_disable = 1148 + __ATTR(prs_disable, 0644, wq_prs_disable_show, wq_prs_disable_store); 1149 + 1116 1150 static ssize_t wq_occupancy_show(struct device *dev, struct device_attribute *attr, char *buf) 1117 1151 { 1118 1152 struct idxd_wq *wq = confdev_to_wq(dev); ··· 1281 1239 &dev_attr_wq_max_transfer_size.attr, 1282 1240 &dev_attr_wq_max_batch_size.attr, 1283 1241 &dev_attr_wq_ats_disable.attr, 1242 + &dev_attr_wq_prs_disable.attr, 1284 1243 &dev_attr_wq_occupancy.attr, 1285 1244 &dev_attr_wq_enqcmds_retries.attr, 1286 1245 &dev_attr_wq_op_config.attr, ··· 1303 1260 idxd->data->type == IDXD_TYPE_IAX; 1304 1261 } 1305 1262 1263 + static bool idxd_wq_attr_wq_prs_disable_invisible(struct attribute *attr, 1264 + struct idxd_device *idxd) 1265 + { 1266 + return attr == &dev_attr_wq_prs_disable.attr && 1267 + !idxd->hw.wq_cap.wq_prs_support; 1268 + } 1269 + 1306 1270 static umode_t idxd_wq_attr_visible(struct kobject *kobj, 1307 1271 struct attribute *attr, int n) 1308 1272 { ··· 1321 1271 return 0; 1322 1272 1323 1273 if (idxd_wq_attr_max_batch_size_invisible(attr, idxd)) 1274 + return 0; 1275 + 1276 + if (idxd_wq_attr_wq_prs_disable_invisible(attr, idxd)) 1324 1277 return 0; 1325 1278 1326 1279 return attr->mode; ··· 1345 1292 1346 1293 bitmap_free(wq->opcap_bmap); 1347 1294 kfree(wq->wqcfg); 1295 + xa_destroy(&wq->upasid_xa); 1348 1296 kfree(wq); 1349 1297 } 1350 1298 ··· 1506 1452 struct device_attribute *attr, char *buf) 1507 1453 { 1508 1454 struct idxd_device *idxd = confdev_to_idxd(dev); 1509 - int i, out = 0; 1455 + DECLARE_BITMAP(swerr_bmap, 256); 1510 1456 1457 + bitmap_zero(swerr_bmap, 256); 1511 1458 spin_lock(&idxd->dev_lock); 1512 - for (i = 0; i < 4; i++) 1513 - out += sysfs_emit_at(buf, out, "%#018llx ", idxd->sw_err.bits[i]); 1459 + multi_u64_to_bmap(swerr_bmap, &idxd->sw_err.bits[0], 4); 1514 1460 spin_unlock(&idxd->dev_lock); 1515 - out--; 1516 - out += sysfs_emit_at(buf, out, "\n"); 1517 - return out; 1461 + return sysfs_emit(buf, "%*pb\n", 256, swerr_bmap); 1518 1462 } 1519 1463 static DEVICE_ATTR_RO(errors); 1520 1464 ··· 1615 1563 } 1616 1564 static DEVICE_ATTR_RW(cmd_status); 1617 1565 1566 + static ssize_t iaa_cap_show(struct device *dev, 1567 + struct device_attribute *attr, char *buf) 1568 + { 1569 + struct idxd_device *idxd = confdev_to_idxd(dev); 1570 + 1571 + if (idxd->hw.version < DEVICE_VERSION_2) 1572 + return -EOPNOTSUPP; 1573 + 1574 + return sysfs_emit(buf, "%#llx\n", idxd->hw.iaa_cap.bits); 1575 + } 1576 + static DEVICE_ATTR_RO(iaa_cap); 1577 + 1578 + static ssize_t event_log_size_show(struct device *dev, 1579 + struct device_attribute *attr, char *buf) 1580 + { 1581 + struct idxd_device *idxd = confdev_to_idxd(dev); 1582 + 1583 + if (!idxd->evl) 1584 + return -EOPNOTSUPP; 1585 + 1586 + return sysfs_emit(buf, "%u\n", idxd->evl->size); 1587 + } 1588 + 1589 + static ssize_t event_log_size_store(struct device *dev, 1590 + struct device_attribute *attr, 1591 + const char *buf, size_t count) 1592 + { 1593 + struct idxd_device *idxd = confdev_to_idxd(dev); 1594 + unsigned long val; 1595 + int rc; 1596 + 1597 + if (!idxd->evl) 1598 + return -EOPNOTSUPP; 1599 + 1600 + rc = kstrtoul(buf, 10, &val); 1601 + if (rc < 0) 1602 + return -EINVAL; 1603 + 1604 + if (idxd->state == IDXD_DEV_ENABLED) 1605 + return -EPERM; 1606 + 1607 + if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) 1608 + return -EPERM; 1609 + 1610 + if (val < IDXD_EVL_SIZE_MIN || val > IDXD_EVL_SIZE_MAX || 1611 + (val * evl_ent_size(idxd) > ULONG_MAX - idxd->evl->dma)) 1612 + return -EINVAL; 1613 + 1614 + idxd->evl->size = val; 1615 + return count; 1616 + } 1617 + static DEVICE_ATTR_RW(event_log_size); 1618 + 1618 1619 static bool idxd_device_attr_max_batch_size_invisible(struct attribute *attr, 1619 1620 struct idxd_device *idxd) 1620 1621 { ··· 1690 1585 idxd->data->type == IDXD_TYPE_IAX; 1691 1586 } 1692 1587 1588 + static bool idxd_device_attr_iaa_cap_invisible(struct attribute *attr, 1589 + struct idxd_device *idxd) 1590 + { 1591 + return attr == &dev_attr_iaa_cap.attr && 1592 + (idxd->data->type != IDXD_TYPE_IAX || 1593 + idxd->hw.version < DEVICE_VERSION_2); 1594 + } 1595 + 1596 + static bool idxd_device_attr_event_log_size_invisible(struct attribute *attr, 1597 + struct idxd_device *idxd) 1598 + { 1599 + return (attr == &dev_attr_event_log_size.attr && 1600 + !idxd->hw.gen_cap.evl_support); 1601 + } 1602 + 1693 1603 static umode_t idxd_device_attr_visible(struct kobject *kobj, 1694 1604 struct attribute *attr, int n) 1695 1605 { ··· 1715 1595 return 0; 1716 1596 1717 1597 if (idxd_device_attr_read_buffers_invisible(attr, idxd)) 1598 + return 0; 1599 + 1600 + if (idxd_device_attr_iaa_cap_invisible(attr, idxd)) 1601 + return 0; 1602 + 1603 + if (idxd_device_attr_event_log_size_invisible(attr, idxd)) 1718 1604 return 0; 1719 1605 1720 1606 return attr->mode; ··· 1748 1622 &dev_attr_read_buffer_limit.attr, 1749 1623 &dev_attr_cdev_major.attr, 1750 1624 &dev_attr_cmd_status.attr, 1625 + &dev_attr_iaa_cap.attr, 1626 + &dev_attr_event_log_size.attr, 1751 1627 NULL, 1752 1628 }; 1753 1629 ··· 1771 1643 bitmap_free(idxd->wq_enable_map); 1772 1644 kfree(idxd->wqs); 1773 1645 kfree(idxd->engines); 1646 + kfree(idxd->evl); 1647 + kmem_cache_destroy(idxd->evl_cache); 1774 1648 ida_free(&idxd_ida, idxd->id); 1775 1649 bitmap_free(idxd->opcap_bmap); 1776 1650 kfree(idxd);
-1
drivers/dma/imx-dma.c
··· 750 750 desc = kzalloc(sizeof(*desc), GFP_KERNEL); 751 751 if (!desc) 752 752 break; 753 - memset(&desc->desc, 0, sizeof(struct dma_async_tx_descriptor)); 754 753 dma_async_tx_descriptor_init(&desc->desc, chan); 755 754 desc->desc.tx_submit = imxdma_tx_submit; 756 755 /* txd.flags will be overwritten in prep funcs */
+3 -9
drivers/dma/ioat/init.c
··· 15 15 #include <linux/workqueue.h> 16 16 #include <linux/prefetch.h> 17 17 #include <linux/dca.h> 18 - #include <linux/aer.h> 19 18 #include <linux/sizes.h> 20 19 #include "dma.h" 21 20 #include "registers.h" ··· 1190 1191 ioat_dma->dca = ioat_dca_init(pdev, ioat_dma->reg_base); 1191 1192 1192 1193 /* disable relaxed ordering */ 1193 - err = pcie_capability_read_word(pdev, IOAT_DEVCTRL_OFFSET, &val16); 1194 + err = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &val16); 1194 1195 if (err) 1195 1196 return pcibios_err_to_errno(err); 1196 1197 1197 1198 /* clear relaxed ordering enable */ 1198 - val16 &= ~IOAT_DEVCTRL_ROE; 1199 - err = pcie_capability_write_word(pdev, IOAT_DEVCTRL_OFFSET, val16); 1199 + val16 &= ~PCI_EXP_DEVCTL_RELAX_EN; 1200 + err = pcie_capability_write_word(pdev, PCI_EXP_DEVCTL, val16); 1200 1201 if (err) 1201 1202 return pcibios_err_to_errno(err); 1202 1203 ··· 1379 1380 if (is_skx_ioat(pdev)) 1380 1381 device->version = IOAT_VER_3_2; 1381 1382 err = ioat3_dma_probe(device, ioat_dca_enabled); 1382 - 1383 - if (device->version >= IOAT_VER_3_3) 1384 - pci_enable_pcie_error_reporting(pdev); 1385 1383 } else 1386 1384 return -ENODEV; 1387 1385 1388 1386 if (err) { 1389 1387 dev_err(dev, "Intel(R) I/OAT DMA Engine init failed\n"); 1390 - pci_disable_pcie_error_reporting(pdev); 1391 1388 return -ENODEV; 1392 1389 } 1393 1390 ··· 1406 1411 device->dca = NULL; 1407 1412 } 1408 1413 1409 - pci_disable_pcie_error_reporting(pdev); 1410 1414 ioat_dma_remove(device); 1411 1415 } 1412 1416
-7
drivers/dma/ioat/registers.h
··· 14 14 #define IOAT_PCI_CHANERR_INT_OFFSET 0x180 15 15 #define IOAT_PCI_CHANERRMASK_INT_OFFSET 0x184 16 16 17 - /* PCIe config registers */ 18 - 19 - /* EXPCAPID + N */ 20 - #define IOAT_DEVCTRL_OFFSET 0x8 21 - /* relaxed ordering enable */ 22 - #define IOAT_DEVCTRL_ROE 0x10 23 - 24 17 /* MMIO Device Registers */ 25 18 #define IOAT_CHANCNT_OFFSET 0x00 /* 8-bit */ 26 19
+7 -28
drivers/dma/mv_xor_v2.c
··· 739 739 if (ret) 740 740 return ret; 741 741 742 - xor_dev->reg_clk = devm_clk_get(&pdev->dev, "reg"); 743 - if (PTR_ERR(xor_dev->reg_clk) != -ENOENT) { 744 - if (!IS_ERR(xor_dev->reg_clk)) { 745 - ret = clk_prepare_enable(xor_dev->reg_clk); 746 - if (ret) 747 - return ret; 748 - } else { 749 - return PTR_ERR(xor_dev->reg_clk); 750 - } 751 - } 742 + xor_dev->reg_clk = devm_clk_get_optional_enabled(&pdev->dev, "reg"); 743 + if (IS_ERR(xor_dev->reg_clk)) 744 + return PTR_ERR(xor_dev->reg_clk); 752 745 753 - xor_dev->clk = devm_clk_get(&pdev->dev, NULL); 754 - if (PTR_ERR(xor_dev->clk) == -EPROBE_DEFER) { 755 - ret = EPROBE_DEFER; 756 - goto disable_reg_clk; 757 - } 758 - if (!IS_ERR(xor_dev->clk)) { 759 - ret = clk_prepare_enable(xor_dev->clk); 760 - if (ret) 761 - goto disable_reg_clk; 762 - } 746 + xor_dev->clk = devm_clk_get_enabled(&pdev->dev, NULL); 747 + if (IS_ERR(xor_dev->clk)) 748 + return PTR_ERR(xor_dev->clk); 763 749 764 750 ret = platform_msi_domain_alloc_irqs(&pdev->dev, 1, 765 751 mv_xor_v2_set_msi_msg); 766 752 if (ret) 767 - goto disable_clk; 753 + return ret; 768 754 769 755 xor_dev->irq = msi_get_virq(&pdev->dev, 0); 770 756 ··· 852 866 xor_dev->hw_desq_virt, xor_dev->hw_desq); 853 867 free_msi_irqs: 854 868 platform_msi_domain_free_irqs(&pdev->dev); 855 - disable_clk: 856 - clk_disable_unprepare(xor_dev->clk); 857 - disable_reg_clk: 858 - clk_disable_unprepare(xor_dev->reg_clk); 859 869 return ret; 860 870 } 861 871 ··· 870 888 platform_msi_domain_free_irqs(&pdev->dev); 871 889 872 890 tasklet_kill(&xor_dev->irq_tasklet); 873 - 874 - clk_disable_unprepare(xor_dev->clk); 875 - clk_disable_unprepare(xor_dev->reg_clk); 876 891 877 892 return 0; 878 893 }
+1 -1
drivers/dma/of-dma.c
··· 264 264 } 265 265 266 266 /* Silently fail if there is not even the "dmas" property */ 267 - if (!of_find_property(np, "dmas", NULL)) 267 + if (!of_property_present(np, "dmas")) 268 268 return ERR_PTR(-ENODEV); 269 269 270 270 count = of_property_count_strings(np, "dma-names");
-1
drivers/dma/qcom/gpi.c
··· 1966 1966 error_config_int: 1967 1967 gpi_free_ring(&gpii->ev_ring, gpii); 1968 1968 exit_gpi_init: 1969 - mutex_unlock(&gpii->ctrl_lock); 1970 1969 return ret; 1971 1970 } 1972 1971
+2
drivers/dma/qcom/hidma_mgmt.c
··· 12 12 #include <linux/of_address.h> 13 13 #include <linux/of_irq.h> 14 14 #include <linux/of_platform.h> 15 + #include <linux/of_device.h> 16 + #include <linux/platform_device.h> 15 17 #include <linux/module.h> 16 18 #include <linux/uaccess.h> 17 19 #include <linux/slab.h>
+14 -4
drivers/dma/sh/rz-dmac.c
··· 20 20 #include <linux/of_platform.h> 21 21 #include <linux/platform_device.h> 22 22 #include <linux/pm_runtime.h> 23 + #include <linux/reset.h> 23 24 #include <linux/slab.h> 24 25 #include <linux/spinlock.h> 25 26 ··· 67 66 struct rz_dmac_desc *desc; 68 67 int descs_allocated; 69 68 70 - enum dma_slave_buswidth src_word_size; 71 - enum dma_slave_buswidth dst_word_size; 72 69 dma_addr_t src_per_address; 73 70 dma_addr_t dst_per_address; 74 71 ··· 91 92 struct rz_dmac { 92 93 struct dma_device engine; 93 94 struct device *dev; 95 + struct reset_control *rstc; 94 96 void __iomem *base; 95 97 void __iomem *ext_base; 96 98 ··· 601 601 u32 val; 602 602 603 603 channel->src_per_address = config->src_addr; 604 - channel->src_word_size = config->src_addr_width; 605 604 channel->dst_per_address = config->dst_addr; 606 - channel->dst_word_size = config->dst_addr_width; 607 605 608 606 val = rz_dmac_ds_to_val_mapping(config->dst_addr_width); 609 607 if (val == CHCFG_DS_INVALID) ··· 887 889 /* Initialize the channels. */ 888 890 INIT_LIST_HEAD(&dmac->engine.channels); 889 891 892 + dmac->rstc = devm_reset_control_array_get_exclusive(&pdev->dev); 893 + if (IS_ERR(dmac->rstc)) 894 + return dev_err_probe(&pdev->dev, PTR_ERR(dmac->rstc), 895 + "failed to get resets\n"); 896 + 890 897 pm_runtime_enable(&pdev->dev); 891 898 ret = pm_runtime_resume_and_get(&pdev->dev); 892 899 if (ret < 0) { 893 900 dev_err(&pdev->dev, "pm_runtime_resume_and_get failed\n"); 894 901 goto err_pm_disable; 895 902 } 903 + 904 + ret = reset_control_deassert(dmac->rstc); 905 + if (ret) 906 + goto err_pm_runtime_put; 896 907 897 908 for (i = 0; i < dmac->n_channels; i++) { 898 909 ret = rz_dmac_chan_probe(dmac, &dmac->channels[i], i); ··· 947 940 dma_register_err: 948 941 of_dma_controller_free(pdev->dev.of_node); 949 942 err: 943 + reset_control_assert(dmac->rstc); 950 944 channel_num = i ? i - 1 : 0; 951 945 for (i = 0; i < channel_num; i++) { 952 946 struct rz_dmac_chan *channel = &dmac->channels[i]; ··· 958 950 channel->lmdesc.base_dma); 959 951 } 960 952 953 + err_pm_runtime_put: 961 954 pm_runtime_put(&pdev->dev); 962 955 err_pm_disable: 963 956 pm_runtime_disable(&pdev->dev); ··· 981 972 } 982 973 of_dma_controller_free(pdev->dev.of_node); 983 974 dma_async_device_unregister(&dmac->engine); 975 + reset_control_assert(dmac->rstc); 984 976 pm_runtime_put(&pdev->dev); 985 977 pm_runtime_disable(&pdev->dev); 986 978
-5
drivers/dma/tegra20-apb-dma.c
··· 233 233 writel(val, tdma->base_addr + reg); 234 234 } 235 235 236 - static inline u32 tdma_read(struct tegra_dma *tdma, u32 reg) 237 - { 238 - return readl(tdma->base_addr + reg); 239 - } 240 - 241 236 static inline void tdc_write(struct tegra_dma_channel *tdc, 242 237 u32 reg, u32 val) 243 238 {
+2 -1
drivers/dma/ti/Makefile
··· 11 11 k3-psil-am64.o \ 12 12 k3-psil-j721s2.o \ 13 13 k3-psil-am62.o \ 14 - k3-psil-am62a.o 14 + k3-psil-am62a.o \ 15 + k3-psil-j784s4.o 15 16 obj-$(CONFIG_TI_K3_PSIL) += k3-psil-lib.o 16 17 obj-$(CONFIG_TI_DMA_CROSSBAR) += dma-crossbar.o
-8
drivers/dma/ti/edma.c
··· 318 318 edma_write(ecc, offset, val); 319 319 } 320 320 321 - static inline void edma_and(struct edma_cc *ecc, int offset, unsigned and) 322 - { 323 - unsigned val = edma_read(ecc, offset); 324 - 325 - val &= and; 326 - edma_write(ecc, offset, val); 327 - } 328 - 329 321 static inline void edma_or(struct edma_cc *ecc, int offset, unsigned or) 330 322 { 331 323 unsigned val = edma_read(ecc, offset);
+354
drivers/dma/ti/k3-psil-j784s4.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com 4 + */ 5 + 6 + #include <linux/kernel.h> 7 + 8 + #include "k3-psil-priv.h" 9 + 10 + #define PSIL_PDMA_XY_TR(x) \ 11 + { \ 12 + .thread_id = x, \ 13 + .ep_config = { \ 14 + .ep_type = PSIL_EP_PDMA_XY, \ 15 + }, \ 16 + } 17 + 18 + #define PSIL_PDMA_XY_PKT(x) \ 19 + { \ 20 + .thread_id = x, \ 21 + .ep_config = { \ 22 + .ep_type = PSIL_EP_PDMA_XY, \ 23 + .pkt_mode = 1, \ 24 + }, \ 25 + } 26 + 27 + #define PSIL_PDMA_MCASP(x) \ 28 + { \ 29 + .thread_id = x, \ 30 + .ep_config = { \ 31 + .ep_type = PSIL_EP_PDMA_XY, \ 32 + .pdma_acc32 = 1, \ 33 + .pdma_burst = 1, \ 34 + }, \ 35 + } 36 + 37 + #define PSIL_ETHERNET(x) \ 38 + { \ 39 + .thread_id = x, \ 40 + .ep_config = { \ 41 + .ep_type = PSIL_EP_NATIVE, \ 42 + .pkt_mode = 1, \ 43 + .needs_epib = 1, \ 44 + .psd_size = 16, \ 45 + }, \ 46 + } 47 + 48 + #define PSIL_SA2UL(x, tx) \ 49 + { \ 50 + .thread_id = x, \ 51 + .ep_config = { \ 52 + .ep_type = PSIL_EP_NATIVE, \ 53 + .pkt_mode = 1, \ 54 + .needs_epib = 1, \ 55 + .psd_size = 64, \ 56 + .notdpkt = tx, \ 57 + }, \ 58 + } 59 + 60 + #define PSIL_CSI2RX(x) \ 61 + { \ 62 + .thread_id = x, \ 63 + .ep_config = { \ 64 + .ep_type = PSIL_EP_NATIVE, \ 65 + }, \ 66 + } 67 + 68 + /* PSI-L source thread IDs, used for RX (DMA_DEV_TO_MEM) */ 69 + static struct psil_ep j784s4_src_ep_map[] = { 70 + /* PDMA_MCASP - McASP0-4 */ 71 + PSIL_PDMA_MCASP(0x4400), 72 + PSIL_PDMA_MCASP(0x4401), 73 + PSIL_PDMA_MCASP(0x4402), 74 + PSIL_PDMA_MCASP(0x4403), 75 + PSIL_PDMA_MCASP(0x4404), 76 + /* PDMA_SPI_G0 - SPI0-3 */ 77 + PSIL_PDMA_XY_PKT(0x4600), 78 + PSIL_PDMA_XY_PKT(0x4601), 79 + PSIL_PDMA_XY_PKT(0x4602), 80 + PSIL_PDMA_XY_PKT(0x4603), 81 + PSIL_PDMA_XY_PKT(0x4604), 82 + PSIL_PDMA_XY_PKT(0x4605), 83 + PSIL_PDMA_XY_PKT(0x4606), 84 + PSIL_PDMA_XY_PKT(0x4607), 85 + PSIL_PDMA_XY_PKT(0x4608), 86 + PSIL_PDMA_XY_PKT(0x4609), 87 + PSIL_PDMA_XY_PKT(0x460a), 88 + PSIL_PDMA_XY_PKT(0x460b), 89 + PSIL_PDMA_XY_PKT(0x460c), 90 + PSIL_PDMA_XY_PKT(0x460d), 91 + PSIL_PDMA_XY_PKT(0x460e), 92 + PSIL_PDMA_XY_PKT(0x460f), 93 + /* PDMA_SPI_G1 - SPI4-7 */ 94 + PSIL_PDMA_XY_PKT(0x4620), 95 + PSIL_PDMA_XY_PKT(0x4621), 96 + PSIL_PDMA_XY_PKT(0x4622), 97 + PSIL_PDMA_XY_PKT(0x4623), 98 + PSIL_PDMA_XY_PKT(0x4624), 99 + PSIL_PDMA_XY_PKT(0x4625), 100 + PSIL_PDMA_XY_PKT(0x4626), 101 + PSIL_PDMA_XY_PKT(0x4627), 102 + PSIL_PDMA_XY_PKT(0x4628), 103 + PSIL_PDMA_XY_PKT(0x4629), 104 + PSIL_PDMA_XY_PKT(0x462a), 105 + PSIL_PDMA_XY_PKT(0x462b), 106 + PSIL_PDMA_XY_PKT(0x462c), 107 + PSIL_PDMA_XY_PKT(0x462d), 108 + PSIL_PDMA_XY_PKT(0x462e), 109 + PSIL_PDMA_XY_PKT(0x462f), 110 + /* MAIN_CPSW2G */ 111 + PSIL_ETHERNET(0x4640), 112 + /* PDMA_USART_G0 - UART0-1 */ 113 + PSIL_PDMA_XY_PKT(0x4700), 114 + PSIL_PDMA_XY_PKT(0x4701), 115 + /* PDMA_USART_G1 - UART2-3 */ 116 + PSIL_PDMA_XY_PKT(0x4702), 117 + PSIL_PDMA_XY_PKT(0x4703), 118 + /* PDMA_USART_G2 - UART4-9 */ 119 + PSIL_PDMA_XY_PKT(0x4704), 120 + PSIL_PDMA_XY_PKT(0x4705), 121 + PSIL_PDMA_XY_PKT(0x4706), 122 + PSIL_PDMA_XY_PKT(0x4707), 123 + PSIL_PDMA_XY_PKT(0x4708), 124 + PSIL_PDMA_XY_PKT(0x4709), 125 + /* CSI2RX */ 126 + PSIL_CSI2RX(0x4900), 127 + PSIL_CSI2RX(0x4901), 128 + PSIL_CSI2RX(0x4902), 129 + PSIL_CSI2RX(0x4903), 130 + PSIL_CSI2RX(0x4940), 131 + PSIL_CSI2RX(0x4941), 132 + PSIL_CSI2RX(0x4942), 133 + PSIL_CSI2RX(0x4943), 134 + PSIL_CSI2RX(0x4944), 135 + PSIL_CSI2RX(0x4945), 136 + PSIL_CSI2RX(0x4946), 137 + PSIL_CSI2RX(0x4947), 138 + PSIL_CSI2RX(0x4948), 139 + PSIL_CSI2RX(0x4949), 140 + PSIL_CSI2RX(0x494a), 141 + PSIL_CSI2RX(0x494b), 142 + PSIL_CSI2RX(0x494c), 143 + PSIL_CSI2RX(0x494d), 144 + PSIL_CSI2RX(0x494e), 145 + PSIL_CSI2RX(0x494f), 146 + PSIL_CSI2RX(0x4950), 147 + PSIL_CSI2RX(0x4951), 148 + PSIL_CSI2RX(0x4952), 149 + PSIL_CSI2RX(0x4953), 150 + PSIL_CSI2RX(0x4954), 151 + PSIL_CSI2RX(0x4955), 152 + PSIL_CSI2RX(0x4956), 153 + PSIL_CSI2RX(0x4957), 154 + PSIL_CSI2RX(0x4958), 155 + PSIL_CSI2RX(0x4959), 156 + PSIL_CSI2RX(0x495a), 157 + PSIL_CSI2RX(0x495b), 158 + PSIL_CSI2RX(0x495c), 159 + PSIL_CSI2RX(0x495d), 160 + PSIL_CSI2RX(0x495e), 161 + PSIL_CSI2RX(0x495f), 162 + PSIL_CSI2RX(0x4960), 163 + PSIL_CSI2RX(0x4961), 164 + PSIL_CSI2RX(0x4962), 165 + PSIL_CSI2RX(0x4963), 166 + PSIL_CSI2RX(0x4964), 167 + PSIL_CSI2RX(0x4965), 168 + PSIL_CSI2RX(0x4966), 169 + PSIL_CSI2RX(0x4967), 170 + PSIL_CSI2RX(0x4968), 171 + PSIL_CSI2RX(0x4969), 172 + PSIL_CSI2RX(0x496a), 173 + PSIL_CSI2RX(0x496b), 174 + PSIL_CSI2RX(0x496c), 175 + PSIL_CSI2RX(0x496d), 176 + PSIL_CSI2RX(0x496e), 177 + PSIL_CSI2RX(0x496f), 178 + PSIL_CSI2RX(0x4970), 179 + PSIL_CSI2RX(0x4971), 180 + PSIL_CSI2RX(0x4972), 181 + PSIL_CSI2RX(0x4973), 182 + PSIL_CSI2RX(0x4974), 183 + PSIL_CSI2RX(0x4975), 184 + PSIL_CSI2RX(0x4976), 185 + PSIL_CSI2RX(0x4977), 186 + PSIL_CSI2RX(0x4978), 187 + PSIL_CSI2RX(0x4979), 188 + PSIL_CSI2RX(0x497a), 189 + PSIL_CSI2RX(0x497b), 190 + PSIL_CSI2RX(0x497c), 191 + PSIL_CSI2RX(0x497d), 192 + PSIL_CSI2RX(0x497e), 193 + PSIL_CSI2RX(0x497f), 194 + PSIL_CSI2RX(0x4980), 195 + PSIL_CSI2RX(0x4981), 196 + PSIL_CSI2RX(0x4982), 197 + PSIL_CSI2RX(0x4983), 198 + PSIL_CSI2RX(0x4984), 199 + PSIL_CSI2RX(0x4985), 200 + PSIL_CSI2RX(0x4986), 201 + PSIL_CSI2RX(0x4987), 202 + PSIL_CSI2RX(0x4988), 203 + PSIL_CSI2RX(0x4989), 204 + PSIL_CSI2RX(0x498a), 205 + PSIL_CSI2RX(0x498b), 206 + PSIL_CSI2RX(0x498c), 207 + PSIL_CSI2RX(0x498d), 208 + PSIL_CSI2RX(0x498e), 209 + PSIL_CSI2RX(0x498f), 210 + PSIL_CSI2RX(0x4990), 211 + PSIL_CSI2RX(0x4991), 212 + PSIL_CSI2RX(0x4992), 213 + PSIL_CSI2RX(0x4993), 214 + PSIL_CSI2RX(0x4994), 215 + PSIL_CSI2RX(0x4995), 216 + PSIL_CSI2RX(0x4996), 217 + PSIL_CSI2RX(0x4997), 218 + PSIL_CSI2RX(0x4998), 219 + PSIL_CSI2RX(0x4999), 220 + PSIL_CSI2RX(0x499a), 221 + PSIL_CSI2RX(0x499b), 222 + PSIL_CSI2RX(0x499c), 223 + PSIL_CSI2RX(0x499d), 224 + PSIL_CSI2RX(0x499e), 225 + PSIL_CSI2RX(0x499f), 226 + /* MAIN_CPSW9G */ 227 + PSIL_ETHERNET(0x4a00), 228 + /* MAIN-SA2UL */ 229 + PSIL_SA2UL(0x4a40, 0), 230 + PSIL_SA2UL(0x4a41, 0), 231 + PSIL_SA2UL(0x4a42, 0), 232 + PSIL_SA2UL(0x4a43, 0), 233 + /* MCU_CPSW0 */ 234 + PSIL_ETHERNET(0x7000), 235 + /* MCU_PDMA0 (MCU_PDMA_MISC_G0) - SPI0 */ 236 + PSIL_PDMA_XY_PKT(0x7100), 237 + PSIL_PDMA_XY_PKT(0x7101), 238 + PSIL_PDMA_XY_PKT(0x7102), 239 + PSIL_PDMA_XY_PKT(0x7103), 240 + /* MCU_PDMA1 (MCU_PDMA_MISC_G1) - SPI1-2 */ 241 + PSIL_PDMA_XY_PKT(0x7200), 242 + PSIL_PDMA_XY_PKT(0x7201), 243 + PSIL_PDMA_XY_PKT(0x7202), 244 + PSIL_PDMA_XY_PKT(0x7203), 245 + PSIL_PDMA_XY_PKT(0x7204), 246 + PSIL_PDMA_XY_PKT(0x7205), 247 + PSIL_PDMA_XY_PKT(0x7206), 248 + PSIL_PDMA_XY_PKT(0x7207), 249 + /* MCU_PDMA2 (MCU_PDMA_MISC_G2) - UART0 */ 250 + PSIL_PDMA_XY_PKT(0x7300), 251 + /* MCU_PDMA_ADC - ADC0-1 */ 252 + PSIL_PDMA_XY_TR(0x7400), 253 + PSIL_PDMA_XY_TR(0x7401), 254 + PSIL_PDMA_XY_TR(0x7402), 255 + PSIL_PDMA_XY_TR(0x7403), 256 + /* MCU_SA2UL */ 257 + PSIL_SA2UL(0x7500, 0), 258 + PSIL_SA2UL(0x7501, 0), 259 + PSIL_SA2UL(0x7502, 0), 260 + PSIL_SA2UL(0x7503, 0), 261 + }; 262 + 263 + /* PSI-L destination thread IDs, used for TX (DMA_MEM_TO_DEV) */ 264 + static struct psil_ep j784s4_dst_ep_map[] = { 265 + /* MAIN_CPSW2G */ 266 + PSIL_ETHERNET(0xc640), 267 + PSIL_ETHERNET(0xc641), 268 + PSIL_ETHERNET(0xc642), 269 + PSIL_ETHERNET(0xc643), 270 + PSIL_ETHERNET(0xc644), 271 + PSIL_ETHERNET(0xc645), 272 + PSIL_ETHERNET(0xc646), 273 + PSIL_ETHERNET(0xc647), 274 + /* MAIN_CPSW9G */ 275 + PSIL_ETHERNET(0xca00), 276 + PSIL_ETHERNET(0xca01), 277 + PSIL_ETHERNET(0xca02), 278 + PSIL_ETHERNET(0xca03), 279 + PSIL_ETHERNET(0xca04), 280 + PSIL_ETHERNET(0xca05), 281 + PSIL_ETHERNET(0xca06), 282 + PSIL_ETHERNET(0xca07), 283 + /* MAIN-SA2UL */ 284 + PSIL_SA2UL(0xca40, 1), 285 + PSIL_SA2UL(0xca41, 1), 286 + /* PDMA_SPI_G0 - SPI0-3 */ 287 + PSIL_PDMA_XY_PKT(0xc600), 288 + PSIL_PDMA_XY_PKT(0xc601), 289 + PSIL_PDMA_XY_PKT(0xc602), 290 + PSIL_PDMA_XY_PKT(0xc603), 291 + PSIL_PDMA_XY_PKT(0xc604), 292 + PSIL_PDMA_XY_PKT(0xc605), 293 + PSIL_PDMA_XY_PKT(0xc606), 294 + PSIL_PDMA_XY_PKT(0xc607), 295 + PSIL_PDMA_XY_PKT(0xc608), 296 + PSIL_PDMA_XY_PKT(0xc609), 297 + PSIL_PDMA_XY_PKT(0xc60a), 298 + PSIL_PDMA_XY_PKT(0xc60b), 299 + PSIL_PDMA_XY_PKT(0xc60c), 300 + PSIL_PDMA_XY_PKT(0xc60d), 301 + PSIL_PDMA_XY_PKT(0xc60e), 302 + PSIL_PDMA_XY_PKT(0xc60f), 303 + /* PDMA_SPI_G1 - SPI4-7 */ 304 + PSIL_PDMA_XY_PKT(0xc620), 305 + PSIL_PDMA_XY_PKT(0xc621), 306 + PSIL_PDMA_XY_PKT(0xc622), 307 + PSIL_PDMA_XY_PKT(0xc623), 308 + PSIL_PDMA_XY_PKT(0xc624), 309 + PSIL_PDMA_XY_PKT(0xc625), 310 + PSIL_PDMA_XY_PKT(0xc626), 311 + PSIL_PDMA_XY_PKT(0xc627), 312 + PSIL_PDMA_XY_PKT(0xc628), 313 + PSIL_PDMA_XY_PKT(0xc629), 314 + PSIL_PDMA_XY_PKT(0xc62a), 315 + PSIL_PDMA_XY_PKT(0xc62b), 316 + PSIL_PDMA_XY_PKT(0xc62c), 317 + PSIL_PDMA_XY_PKT(0xc62d), 318 + PSIL_PDMA_XY_PKT(0xc62e), 319 + PSIL_PDMA_XY_PKT(0xc62f), 320 + /* MCU_CPSW0 */ 321 + PSIL_ETHERNET(0xf000), 322 + PSIL_ETHERNET(0xf001), 323 + PSIL_ETHERNET(0xf002), 324 + PSIL_ETHERNET(0xf003), 325 + PSIL_ETHERNET(0xf004), 326 + PSIL_ETHERNET(0xf005), 327 + PSIL_ETHERNET(0xf006), 328 + PSIL_ETHERNET(0xf007), 329 + /* MCU_PDMA_MISC_G0 - SPI0 */ 330 + PSIL_PDMA_XY_PKT(0xf100), 331 + PSIL_PDMA_XY_PKT(0xf101), 332 + PSIL_PDMA_XY_PKT(0xf102), 333 + PSIL_PDMA_XY_PKT(0xf103), 334 + /* MCU_PDMA_MISC_G1 - SPI1-2 */ 335 + PSIL_PDMA_XY_PKT(0xf200), 336 + PSIL_PDMA_XY_PKT(0xf201), 337 + PSIL_PDMA_XY_PKT(0xf202), 338 + PSIL_PDMA_XY_PKT(0xf203), 339 + PSIL_PDMA_XY_PKT(0xf204), 340 + PSIL_PDMA_XY_PKT(0xf205), 341 + PSIL_PDMA_XY_PKT(0xf206), 342 + PSIL_PDMA_XY_PKT(0xf207), 343 + /* MCU_SA2UL */ 344 + PSIL_SA2UL(0xf500, 1), 345 + PSIL_SA2UL(0xf501, 1), 346 + }; 347 + 348 + struct psil_ep_map j784s4_ep_map = { 349 + .name = "j784s4", 350 + .src = j784s4_src_ep_map, 351 + .src_count = ARRAY_SIZE(j784s4_src_ep_map), 352 + .dst = j784s4_dst_ep_map, 353 + .dst_count = ARRAY_SIZE(j784s4_dst_ep_map), 354 + };
+1
drivers/dma/ti/k3-psil-priv.h
··· 44 44 extern struct psil_ep_map j721s2_ep_map; 45 45 extern struct psil_ep_map am62_ep_map; 46 46 extern struct psil_ep_map am62a_ep_map; 47 + extern struct psil_ep_map j784s4_ep_map; 47 48 48 49 #endif /* K3_PSIL_PRIV_H_ */
+1
drivers/dma/ti/k3-psil.c
··· 25 25 { .family = "J721S2", .data = &j721s2_ep_map }, 26 26 { .family = "AM62X", .data = &am62_ep_map }, 27 27 { .family = "AM62AX", .data = &am62a_ep_map }, 28 + { .family = "J784S4", .data = &j784s4_ep_map }, 28 29 { /* sentinel */ } 29 30 }; 30 31
+66 -9
drivers/dma/ti/k3-udma.c
··· 305 305 306 306 /* Channel configuration parameters */ 307 307 struct udma_chan_config config; 308 + /* Channel configuration parameters (backup) */ 309 + struct udma_chan_config backup_config; 308 310 309 311 /* dmapool for packet mode descriptors */ 310 312 bool use_dma_pool; ··· 2966 2964 struct scatterlist *sgent; 2967 2965 struct cppi5_tr_type15_t *tr_req = NULL; 2968 2966 enum dma_slave_buswidth dev_width; 2967 + u32 csf = CPPI5_TR_CSF_SUPR_EVT; 2969 2968 u16 tr_cnt0, tr_cnt1; 2970 2969 dma_addr_t dev_addr; 2971 2970 struct udma_desc *d; ··· 3037 3034 3038 3035 if (uc->ud->match_data->type == DMA_TYPE_UDMA) { 3039 3036 asel = 0; 3037 + csf |= CPPI5_TR_CSF_EOL_ICNT0; 3040 3038 } else { 3041 3039 asel = (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT; 3042 3040 dev_addr |= asel; ··· 3061 3057 3062 3058 cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE15, false, 3063 3059 true, CPPI5_TR_EVENT_SIZE_COMPLETION, 0); 3064 - cppi5_tr_csf_set(&tr_req[tr_idx].flags, CPPI5_TR_CSF_SUPR_EVT); 3060 + cppi5_tr_csf_set(&tr_req[tr_idx].flags, csf); 3065 3061 cppi5_tr_set_trigger(&tr_req[tr_idx].flags, 3066 3062 uc->config.tr_trigger_type, 3067 3063 CPPI5_TR_TRIGGER_TYPE_ICNT2_DEC, 0, 0); ··· 3107 3103 cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE15, 3108 3104 false, true, 3109 3105 CPPI5_TR_EVENT_SIZE_COMPLETION, 0); 3110 - cppi5_tr_csf_set(&tr_req[tr_idx].flags, 3111 - CPPI5_TR_CSF_SUPR_EVT); 3106 + cppi5_tr_csf_set(&tr_req[tr_idx].flags, csf); 3112 3107 cppi5_tr_set_trigger(&tr_req[tr_idx].flags, 3113 3108 uc->config.tr_trigger_type, 3114 3109 CPPI5_TR_TRIGGER_TYPE_ICNT2_DEC, ··· 3151 3148 d->residue += sg_len; 3152 3149 } 3153 3150 3154 - cppi5_tr_csf_set(&tr_req[tr_idx - 1].flags, 3155 - CPPI5_TR_CSF_SUPR_EVT | CPPI5_TR_CSF_EOP); 3151 + cppi5_tr_csf_set(&tr_req[tr_idx - 1].flags, csf | CPPI5_TR_CSF_EOP); 3156 3152 3157 3153 return d; 3158 3154 } ··· 3680 3678 int num_tr; 3681 3679 size_t tr_size = sizeof(struct cppi5_tr_type15_t); 3682 3680 u16 tr0_cnt0, tr0_cnt1, tr1_cnt0; 3681 + u32 csf = CPPI5_TR_CSF_SUPR_EVT; 3683 3682 3684 3683 if (uc->config.dir != DMA_MEM_TO_MEM) { 3685 3684 dev_err(chan->device->dev, ··· 3711 3708 if (uc->ud->match_data->type != DMA_TYPE_UDMA) { 3712 3709 src |= (u64)uc->ud->asel << K3_ADDRESS_ASEL_SHIFT; 3713 3710 dest |= (u64)uc->ud->asel << K3_ADDRESS_ASEL_SHIFT; 3711 + } else { 3712 + csf |= CPPI5_TR_CSF_EOL_ICNT0; 3714 3713 } 3715 3714 3716 3715 tr_req = d->hwdesc[0].tr_req_base; 3717 3716 3718 3717 cppi5_tr_init(&tr_req[0].flags, CPPI5_TR_TYPE15, false, true, 3719 3718 CPPI5_TR_EVENT_SIZE_COMPLETION, 0); 3720 - cppi5_tr_csf_set(&tr_req[0].flags, CPPI5_TR_CSF_SUPR_EVT); 3719 + cppi5_tr_csf_set(&tr_req[0].flags, csf); 3721 3720 3722 3721 tr_req[0].addr = src; 3723 3722 tr_req[0].icnt0 = tr0_cnt0; ··· 3738 3733 if (num_tr == 2) { 3739 3734 cppi5_tr_init(&tr_req[1].flags, CPPI5_TR_TYPE15, false, true, 3740 3735 CPPI5_TR_EVENT_SIZE_COMPLETION, 0); 3741 - cppi5_tr_csf_set(&tr_req[1].flags, CPPI5_TR_CSF_SUPR_EVT); 3736 + cppi5_tr_csf_set(&tr_req[1].flags, csf); 3742 3737 3743 3738 tr_req[1].addr = src + tr0_cnt1 * tr0_cnt0; 3744 3739 tr_req[1].icnt0 = tr1_cnt0; ··· 3753 3748 tr_req[1].dicnt3 = 1; 3754 3749 } 3755 3750 3756 - cppi5_tr_csf_set(&tr_req[num_tr - 1].flags, 3757 - CPPI5_TR_CSF_SUPR_EVT | CPPI5_TR_CSF_EOP); 3751 + cppi5_tr_csf_set(&tr_req[num_tr - 1].flags, csf | CPPI5_TR_CSF_EOP); 3758 3752 3759 3753 if (uc->config.metadata_size) 3760 3754 d->vd.tx.metadata_ops = &metadata_ops; ··· 4416 4412 { .family = "J721S2", .data = &j721e_soc_data}, 4417 4413 { .family = "AM62X", .data = &am64_soc_data }, 4418 4414 { .family = "AM62AX", .data = &am64_soc_data }, 4415 + { .family = "J784S4", .data = &j721e_soc_data }, 4419 4416 { /* sentinel */ } 4420 4417 }; 4421 4418 ··· 5527 5522 return ret; 5528 5523 } 5529 5524 5525 + static int udma_pm_suspend(struct device *dev) 5526 + { 5527 + struct udma_dev *ud = dev_get_drvdata(dev); 5528 + struct dma_device *dma_dev = &ud->ddev; 5529 + struct dma_chan *chan; 5530 + struct udma_chan *uc; 5531 + 5532 + list_for_each_entry(chan, &dma_dev->channels, device_node) { 5533 + if (chan->client_count) { 5534 + uc = to_udma_chan(chan); 5535 + /* backup the channel configuration */ 5536 + memcpy(&uc->backup_config, &uc->config, 5537 + sizeof(struct udma_chan_config)); 5538 + dev_dbg(dev, "Suspending channel %s\n", 5539 + dma_chan_name(chan)); 5540 + ud->ddev.device_free_chan_resources(chan); 5541 + } 5542 + } 5543 + 5544 + return 0; 5545 + } 5546 + 5547 + static int udma_pm_resume(struct device *dev) 5548 + { 5549 + struct udma_dev *ud = dev_get_drvdata(dev); 5550 + struct dma_device *dma_dev = &ud->ddev; 5551 + struct dma_chan *chan; 5552 + struct udma_chan *uc; 5553 + int ret; 5554 + 5555 + list_for_each_entry(chan, &dma_dev->channels, device_node) { 5556 + if (chan->client_count) { 5557 + uc = to_udma_chan(chan); 5558 + /* restore the channel configuration */ 5559 + memcpy(&uc->config, &uc->backup_config, 5560 + sizeof(struct udma_chan_config)); 5561 + dev_dbg(dev, "Resuming channel %s\n", 5562 + dma_chan_name(chan)); 5563 + ret = ud->ddev.device_alloc_chan_resources(chan); 5564 + if (ret) 5565 + return ret; 5566 + } 5567 + } 5568 + 5569 + return 0; 5570 + } 5571 + 5572 + static const struct dev_pm_ops udma_pm_ops = { 5573 + SET_LATE_SYSTEM_SLEEP_PM_OPS(udma_pm_suspend, udma_pm_resume) 5574 + }; 5575 + 5530 5576 static struct platform_driver udma_driver = { 5531 5577 .driver = { 5532 5578 .name = "ti-udma", 5533 5579 .of_match_table = udma_of_match, 5534 5580 .suppress_bind_attrs = true, 5581 + .pm = &udma_pm_ops, 5535 5582 }, 5536 5583 .probe = udma_probe, 5537 5584 };
+5 -1
drivers/dma/xilinx/zynqmp_dma.c
··· 1060 1060 zdev->dev = &pdev->dev; 1061 1061 INIT_LIST_HEAD(&zdev->common.channels); 1062 1062 1063 - dma_set_mask(&pdev->dev, DMA_BIT_MASK(44)); 1063 + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(44)); 1064 + if (ret) { 1065 + dev_err(&pdev->dev, "DMA not available for address range\n"); 1066 + return ret; 1067 + } 1064 1068 dma_cap_set(DMA_MEMCPY, zdev->common.cap_mask); 1065 1069 1066 1070 p = &zdev->common;
+1
include/linux/dma/ti-cppi5.h
··· 616 616 #define CPPI5_TR_CSF_SUPR_EVT BIT(2) 617 617 #define CPPI5_TR_CSF_EOL_ADV_SHIFT (4U) 618 618 #define CPPI5_TR_CSF_EOL_ADV_MASK GENMASK(6, 4) 619 + #define CPPI5_TR_CSF_EOL_ICNT0 BIT(4) 619 620 #define CPPI5_TR_CSF_EOP BIT(7) 620 621 621 622 /**
+45 -3
include/uapi/linux/idxd.h
··· 30 30 IDXD_SCMD_WQ_NO_PRIV = 0x800f0000, 31 31 IDXD_SCMD_WQ_IRQ_ERR = 0x80100000, 32 32 IDXD_SCMD_WQ_USER_NO_IOMMU = 0x80110000, 33 + IDXD_SCMD_DEV_EVL_ERR = 0x80120000, 33 34 }; 34 35 35 36 #define IDXD_SCMD_SOFTERR_MASK 0x80000000 ··· 73 72 DSA_OPCODE_CR_DELTA, 74 73 DSA_OPCODE_AP_DELTA, 75 74 DSA_OPCODE_DUALCAST, 75 + DSA_OPCODE_TRANSL_FETCH, 76 76 DSA_OPCODE_CRCGEN = 0x10, 77 77 DSA_OPCODE_COPY_CRC, 78 78 DSA_OPCODE_DIF_CHECK, 79 79 DSA_OPCODE_DIF_INS, 80 80 DSA_OPCODE_DIF_STRP, 81 81 DSA_OPCODE_DIF_UPDT, 82 + DSA_OPCODE_DIX_GEN = 0x17, 82 83 DSA_OPCODE_CFLUSH = 0x20, 83 84 }; 84 85 ··· 135 132 DSA_COMP_HW_ERR1, 136 133 DSA_COMP_HW_ERR_DRB, 137 134 DSA_COMP_TRANSLATION_FAIL, 135 + DSA_COMP_DRAIN_EVL = 0x26, 136 + DSA_COMP_BATCH_EVL_ERR, 138 137 }; 139 138 140 139 enum iax_completion_status { ··· 172 167 173 168 #define DSA_COMP_STATUS_MASK 0x7f 174 169 #define DSA_COMP_STATUS_WRITE 0x80 170 + #define DSA_COMP_STATUS(status) ((status) & DSA_COMP_STATUS_MASK) 175 171 176 172 struct dsa_hw_desc { 177 173 uint32_t pasid:20; ··· 186 180 uint64_t rdback_addr; 187 181 uint64_t pattern; 188 182 uint64_t desc_list_addr; 183 + uint64_t pattern_lower; 184 + uint64_t transl_fetch_addr; 189 185 }; 190 186 union { 191 187 uint64_t dst_addr; ··· 198 190 union { 199 191 uint32_t xfer_size; 200 192 uint32_t desc_count; 193 + uint32_t region_size; 201 194 }; 202 195 uint16_t int_handle; 203 196 uint16_t rsvd1; ··· 253 244 uint16_t dest_app_tag_seed; 254 245 }; 255 246 247 + /* Fill */ 248 + uint64_t pattern_upper; 249 + 250 + /* Translation fetch */ 251 + struct { 252 + uint64_t transl_fetch_res; 253 + uint32_t region_stride; 254 + }; 255 + 256 + /* DIX generate */ 257 + struct { 258 + uint8_t dix_gen_res; 259 + uint8_t dest_dif_flags; 260 + uint8_t dif_flags; 261 + uint8_t dix_gen_res2[13]; 262 + uint32_t ref_tag_seed; 263 + uint16_t app_tag_mask; 264 + uint16_t app_tag_seed; 265 + }; 266 + 256 267 uint8_t op_specific[24]; 257 268 }; 258 269 } __attribute__((packed)); ··· 313 284 uint8_t result; 314 285 uint8_t dif_status; 315 286 }; 316 - uint16_t rsvd; 317 - uint32_t bytes_completed; 287 + uint8_t fault_info; 288 + uint8_t rsvd; 289 + union { 290 + uint32_t bytes_completed; 291 + uint32_t descs_completed; 292 + }; 318 293 uint64_t fault_addr; 319 294 union { 320 295 /* common record */ ··· 355 322 uint16_t dif_upd_dest_app_tag; 356 323 }; 357 324 325 + /* DIX generate */ 326 + struct { 327 + uint64_t dix_gen_res; 328 + uint32_t dix_ref_tag; 329 + uint16_t dix_app_tag_mask; 330 + uint16_t dix_app_tag; 331 + }; 332 + 358 333 uint8_t op_specific[16]; 359 334 }; 360 335 } __attribute__((packed)); ··· 374 333 struct iax_completion_record { 375 334 volatile uint8_t status; 376 335 uint8_t error_code; 377 - uint16_t rsvd; 336 + uint8_t fault_info; 337 + uint8_t rsvd; 378 338 uint32_t bytes_completed; 379 339 uint64_t fault_addr; 380 340 uint32_t invalid_flags;