To pick up fixes.
Unified · Split
| @@ -710,6 +710,10 @@ S: Las Cuevas 2385 - Bo Guemes · 709 unmodified lines | ||
| 710 | 710 | S: Las Heras, Mendoza CP 5539 |
| 711 | 711 | S: Argentina |
| 712 | 712 | |
| 713 | +N: Jay Cliburn | |
| 714 | +E: jcliburn@gmail.com | |
| 715 | +D: ATLX Ethernet drivers | |
| 716 | + | |
| 713 | 717 | N: Steven P. Cole |
| 714 | 718 | E: scole@lanl.gov |
| 715 | 719 | E: elenstev@mesatop.com |
| @@ -1284,6 +1288,10 @@ D: Major kbuild rework during the 2.5 cycle · 568 unmodified lines | ||
| 1284 | 1288 | D: ISDN Maintainer |
| 1285 | 1289 | S: USA |
| 1286 | 1290 | |
| 1291 | +N: Gerrit Renker | |
| 1292 | +E: gerrit@erg.abdn.ac.uk | |
| 1293 | +D: DCCP protocol support. | |
| 1294 | + | |
| 1287 | 1295 | N: Philip Gladstone |
| 1288 | 1296 | E: philip@gladstonefamily.net |
| 1289 | 1297 | D: Kernel / timekeeping stuff |
| @@ -2138,6 +2146,10 @@ E: seasons@falcon.sch.bme.hu · 848 unmodified lines | ||
| 2138 | 2146 | E: seasons@makosteszta.sote.hu |
| 2139 | 2147 | D: Original author of software suspend |
| 2140 | 2148 | |
| 2149 | +N: Alexey Kuznetsov | |
| 2150 | +E: kuznet@ms2.inr.ac.ru | |
| 2151 | +D: Author and maintainer of large parts of the networking stack | |
| 2152 | + | |
| 2141 | 2153 | N: Jaroslav Kysela |
| 2142 | 2154 | E: perex@perex.cz |
| 2143 | 2155 | W: https://www.perex.cz |
| @@ -2696,6 +2708,10 @@ N: Wolfgang Muees · 552 unmodified lines | ||
| 2696 | 2708 | E: wolfgang@iksw-muees.de |
| 2697 | 2709 | D: Auerswald USB driver |
| 2698 | 2710 | |
| 2711 | +N: Shrijeet Mukherjee | |
| 2712 | +E: shrijeet@gmail.com | |
| 2713 | +D: Network routing domains (VRF). | |
| 2714 | + | |
| 2699 | 2715 | N: Paul Mundt |
| 2700 | 2716 | E: paul.mundt@gmail.com |
| 2701 | 2717 | D: SuperH maintainer |
| @@ -4110,6 +4126,10 @@ S: B-1206 Jingmao Guojigongyu · 1408 unmodified lines | ||
| 4110 | 4126 | S: 16 Baliqiao Nanjie, Beijing 101100 |
| 4111 | 4127 | S: People's Repulic of China |
| 4112 | 4128 | |
| 4129 | +N: Aviad Yehezkel | |
| 4130 | +E: aviadye@nvidia.com | |
| 4131 | +D: Kernel TLS implementation and offload support. | |
| 4132 | + | |
| 4113 | 4133 | N: Victor Yodaiken |
| 4114 | 4134 | E: yodaiken@fsmlabs.com |
| 4115 | 4135 | D: RTLinux (RealTime Linux) |
| @@ -4167,6 +4187,10 @@ S: 1507 145th Place SE #B5 · 51 unmodified lines | ||
| 4167 | 4187 | S: Bellevue, Washington 98007 |
| 4168 | 4188 | S: USA |
| 4169 | 4189 | |
| 4190 | +N: Wensong Zhang | |
| 4191 | +E: wensong@linux-vs.org | |
| 4192 | +D: IP virtual server (IPVS). | |
| 4193 | + | |
| 4170 | 4194 | N: Haojian Zhuang |
| 4171 | 4195 | E: haojian.zhuang@gmail.com |
| 4172 | 4196 | D: MMP support |
| @@ -473,7 +473,7 @@ read-side critical sections that follow the idle period (the oval near · 472 unmodified lines | ||
| 473 | 473 | the bottom of the diagram above). |
| 474 | 474 | |
| 475 | 475 | Plumbing this into the full grace-period execution is described |
| 476 | −`below <#Forcing%20Quiescent%20States>`__. | |
| 476 | +`below <Forcing Quiescent States_>`__. | |
| 477 | 477 | |
| 478 | 478 | CPU-Hotplug Interface |
| 479 | 479 | ^^^^^^^^^^^^^^^^^^^^^ |
| @@ -494,7 +494,7 @@ mask to detect CPUs having gone offline since the beginning of this · 14 unmodified lines | ||
| 494 | 494 | grace period. |
| 495 | 495 | |
| 496 | 496 | Plumbing this into the full grace-period execution is described |
| 497 | −`below <#Forcing%20Quiescent%20States>`__. | |
| 497 | +`below <Forcing Quiescent States_>`__. | |
| 498 | 498 | |
| 499 | 499 | Forcing Quiescent States |
| 500 | 500 | ^^^^^^^^^^^^^^^^^^^^^^^^ |
| @@ -532,7 +532,7 @@ from other CPUs. · 31 unmodified lines | ||
| 532 | 532 | | RCU. But this diagram is complex enough as it is, so simplicity | |
| 533 | 533 | | overrode accuracy. You can think of it as poetic license, or you can | |
| 534 | 534 | | think of it as misdirection that is resolved in the | |
| 535 | −| `stitched-together diagram <#Putting%20It%20All%20Together>`__. | | |
| 535 | +| `stitched-together diagram <Putting It All Together_>`__. | | |
| 536 | 536 | +-----------------------------------------------------------------------+ |
| 537 | 537 | |
| 538 | 538 | Grace-Period Cleanup |
| @@ -596,7 +596,7 @@ maintain ordering. For example, if the callback function wakes up a task · 57 unmodified lines | ||
| 596 | 596 | that runs on some other CPU, proper ordering must in place in both the |
| 597 | 597 | callback function and the task being awakened. To see why this is |
| 598 | 598 | important, consider the top half of the `grace-period |
| 599 | −cleanup <#Grace-Period%20Cleanup>`__ diagram. The callback might be | |
| 599 | +cleanup`_ diagram. The callback might be | |
| 600 | 600 | running on a CPU corresponding to the leftmost leaf ``rcu_node`` |
| 601 | 601 | structure, and awaken a task that is to run on a CPU corresponding to |
| 602 | 602 | the rightmost leaf ``rcu_node`` structure, and the grace-period kernel |
| @@ -45,7 +45,7 @@ requirements: · 44 unmodified lines | ||
| 45 | 45 | #. `Other RCU Flavors`_ |
| 46 | 46 | #. `Possible Future Changes`_ |
| 47 | 47 | |
| 48 | −This is followed by a `summary <#Summary>`__, however, the answers to | |
| 48 | +This is followed by a summary_, however, the answers to | |
| 49 | 49 | each quick quiz immediately follows the quiz. Select the big white space |
| 50 | 50 | with your mouse to see the answer. |
| 51 | 51 | |
| @@ -1096,7 +1096,7 @@ memory barriers. · 1044 unmodified lines | ||
| 1096 | 1096 | | case, voluntary context switch) within an RCU read-side critical | |
| 1097 | 1097 | | section. However, sleeping locks may be used within userspace RCU | |
| 1098 | 1098 | | read-side critical sections, and also within Linux-kernel sleepable | |
| 1099 | −| RCU `(SRCU) <#Sleepable%20RCU>`__ read-side critical sections. In | | |
| 1099 | +| RCU `(SRCU) <Sleepable RCU_>`__ read-side critical sections. In | | |
| 1100 | 1100 | | addition, the -rt patchset turns spinlocks into a sleeping locks so | |
| 1101 | 1101 | | that the corresponding critical sections can be preempted, which also | |
| 1102 | 1102 | | means that these sleeplockified spinlocks (but not other sleeping | |
| @@ -1186,7 +1186,7 @@ non-preemptible (``CONFIG_PREEMPT=n``) kernels, and thus `tiny · 83 unmodified lines | ||
| 1186 | 1186 | RCU <https://lkml.kernel.org/g/20090113221724.GA15307@linux.vnet.ibm.com>`__ |
| 1187 | 1187 | was born. Josh Triplett has since taken over the small-memory banner |
| 1188 | 1188 | with his `Linux kernel tinification <https://tiny.wiki.kernel.org/>`__ |
| 1189 | −project, which resulted in `SRCU <#Sleepable%20RCU>`__ becoming optional | |
| 1189 | +project, which resulted in `SRCU <Sleepable RCU_>`__ becoming optional | |
| 1190 | 1190 | for those kernels not needing it. |
| 1191 | 1191 | |
| 1192 | 1192 | The remaining performance requirements are, for the most part, |
| @@ -1457,8 +1457,8 @@ will vary as the value of ``HZ`` varies, and can also be changed using · 264 unmodified lines | ||
| 1457 | 1457 | the relevant Kconfig options and kernel boot parameters. RCU currently |
| 1458 | 1458 | does not do much sanity checking of these parameters, so please use |
| 1459 | 1459 | caution when changing them. Note that these forward-progress measures |
| 1460 | −are provided only for RCU, not for `SRCU <#Sleepable%20RCU>`__ or `Tasks | |
| 1461 | −RCU <#Tasks%20RCU>`__. | |
| 1460 | +are provided only for RCU, not for `SRCU <Sleepable RCU_>`__ or `Tasks | |
| 1461 | +RCU`_. | |
| 1462 | 1462 | |
| 1463 | 1463 | RCU takes the following steps in ``call_rcu()`` to encourage timely |
| 1464 | 1464 | invocation of callbacks when any given non-\ ``rcu_nocbs`` CPU has |
| @@ -1477,8 +1477,8 @@ encouragement was provided: · 12 unmodified lines | ||
| 1477 | 1477 | |
| 1478 | 1478 | Again, these are default values when running at ``HZ=1000``, and can be |
| 1479 | 1479 | overridden. Again, these forward-progress measures are provided only for |
| 1480 | −RCU, not for `SRCU <#Sleepable%20RCU>`__ or `Tasks | |
| 1481 | −RCU <#Tasks%20RCU>`__. Even for RCU, callback-invocation forward | |
| 1480 | +RCU, not for `SRCU <Sleepable RCU_>`__ or `Tasks | |
| 1481 | +RCU`_. Even for RCU, callback-invocation forward | |
| 1482 | 1482 | progress for ``rcu_nocbs`` CPUs is much less well-developed, in part |
| 1483 | 1483 | because workloads benefiting from ``rcu_nocbs`` CPUs tend to invoke |
| 1484 | 1484 | ``call_rcu()`` relatively infrequently. If workloads emerge that need |
| @@ -1920,7 +1920,7 @@ Hotplug CPU · 435 unmodified lines | ||
| 1920 | 1920 | |
| 1921 | 1921 | The Linux kernel supports CPU hotplug, which means that CPUs can come |
| 1922 | 1922 | and go. It is of course illegal to use any RCU API member from an |
| 1923 | −offline CPU, with the exception of `SRCU <#Sleepable%20RCU>`__ read-side | |
| 1923 | +offline CPU, with the exception of `SRCU <Sleepable RCU_>`__ read-side | |
| 1924 | 1924 | critical sections. This requirement was present from day one in |
| 1925 | 1925 | DYNIX/ptx, but on the other hand, the Linux kernel's CPU-hotplug |
| 1926 | 1926 | implementation is “interesting.” |
| @@ -2177,7 +2177,7 @@ handles these states differently: · 250 unmodified lines | ||
| 2177 | 2177 | However, RCU must be reliably informed as to whether any given CPU is |
| 2178 | 2178 | currently in the idle loop, and, for ``NO_HZ_FULL``, also whether that |
| 2179 | 2179 | CPU is executing in usermode, as discussed |
| 2180 | −`earlier <#Energy%20Efficiency>`__. It also requires that the | |
| 2180 | +`earlier <Energy Efficiency_>`__. It also requires that the | |
| 2181 | 2181 | scheduling-clock interrupt be enabled when RCU needs it to be: |
| 2182 | 2182 | |
| 2183 | 2183 | #. If a CPU is either idle or executing in usermode, and RCU believes it |
| @@ -2294,7 +2294,7 @@ Performance, Scalability, Response Time, and Reliability · 110 unmodified lines | ||
| 2294 | 2294 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 2295 | 2295 | |
| 2296 | 2296 | Expanding on the `earlier |
| 2297 | −discussion <#Performance%20and%20Scalability>`__, RCU is used heavily by | |
| 2297 | +discussion <Performance and Scalability_>`__, RCU is used heavily by | |
| 2298 | 2298 | hot code paths in performance-critical portions of the Linux kernel's |
| 2299 | 2299 | networking, security, virtualization, and scheduling code paths. RCU |
| 2300 | 2300 | must therefore use efficient implementations, especially in its |
| @@ -23,7 +23,7 @@ Here is what the fields mean: · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | - ``name`` |
| 25 | 25 | is an identifier string. A new /proc file will be created with this |
| 26 | − ``name below /proc/sys/fs/binfmt_misc``; cannot contain slashes ``/`` for | |
| 26 | + name below ``/proc/sys/fs/binfmt_misc``; cannot contain slashes ``/`` for | |
| 27 | 27 | obvious reasons. |
| 28 | 28 | - ``type`` |
| 29 | 29 | is the type of recognition. Give ``M`` for magic and ``E`` for extension. |
| @@ -83,7 +83,7 @@ Here is what the fields mean: · 53 unmodified lines | ||
| 83 | 83 | ``F`` - fix binary |
| 84 | 84 | The usual behaviour of binfmt_misc is to spawn the |
| 85 | 85 | binary lazily when the misc format file is invoked. However, |
| 86 | − this doesn``t work very well in the face of mount namespaces and | |
| 86 | + this doesn't work very well in the face of mount namespaces and | |
| 87 | 87 | changeroots, so the ``F`` mode opens the binary as soon as the |
| 88 | 88 | emulation is installed and uses the opened image to spawn the |
| 89 | 89 | emulator, meaning it is always available once installed, |
| @@ -154,7 +154,7 @@ get the boot configuration data. · 153 unmodified lines | ||
| 154 | 154 | Because of this "piggyback" method, there is no need to change or |
| 155 | 155 | update the boot loader and the kernel image itself as long as the boot |
| 156 | 156 | loader passes the correct initrd file size. If by any chance, the boot |
| 157 | −loader passes a longer size, the kernel feils to find the bootconfig data. | |
| 157 | +loader passes a longer size, the kernel fails to find the bootconfig data. | |
| 158 | 158 | |
| 159 | 159 | To do this operation, Linux kernel provides "bootconfig" command under |
| 160 | 160 | tools/bootconfig, which allows admin to apply or delete the config file |
| @@ -3,8 +3,8 @@ · 2 unmodified lines | ||
| 3 | 3 | The kernel's command-line parameters |
| 4 | 4 | ==================================== |
| 5 | 5 | |
| 6 | −The following is a consolidated list of the kernel parameters as | |
| 7 | −implemented by the __setup(), core_param() and module_param() macros | |
| 6 | +The following is a consolidated list of the kernel parameters as implemented | |
| 7 | +by the __setup(), early_param(), core_param() and module_param() macros | |
| 8 | 8 | and sorted into English Dictionary order (defined as ignoring all |
| 9 | 9 | punctuation and sorting digits before letters in a case insensitive |
| 10 | 10 | manner), and with descriptions where known. |
| @@ -1385,7 +1385,7 @@ · 1384 unmodified lines | ||
| 1385 | 1385 | |
| 1386 | 1386 | ftrace_filter=[function-list] |
| 1387 | 1387 | [FTRACE] Limit the functions traced by the function |
| 1388 | − tracer at boot up. function-list is a comma separated | |
| 1388 | + tracer at boot up. function-list is a comma-separated | |
| 1389 | 1389 | list of functions. This list can be changed at run |
| 1390 | 1390 | time by the set_ftrace_filter file in the debugfs |
| 1391 | 1391 | tracing directory. |
| @@ -1399,13 +1399,13 @@ · 7 unmodified lines | ||
| 1399 | 1399 | ftrace_graph_filter=[function-list] |
| 1400 | 1400 | [FTRACE] Limit the top level callers functions traced |
| 1401 | 1401 | by the function graph tracer at boot up. |
| 1402 | − function-list is a comma separated list of functions | |
| 1402 | + function-list is a comma-separated list of functions | |
| 1403 | 1403 | that can be changed at run time by the |
| 1404 | 1404 | set_graph_function file in the debugfs tracing directory. |
| 1405 | 1405 | |
| 1406 | 1406 | ftrace_graph_notrace=[function-list] |
| 1407 | 1407 | [FTRACE] Do not trace from the functions specified in |
| 1408 | − function-list. This list is a comma separated list of | |
| 1408 | + function-list. This list is a comma-separated list of | |
| 1409 | 1409 | functions that can be changed at run time by the |
| 1410 | 1410 | set_graph_notrace file in the debugfs tracing directory. |
| 1411 | 1411 | |
| @@ -2421,7 +2421,7 @@ · 1009 unmodified lines | ||
| 2421 | 2421 | when set. |
| 2422 | 2422 | Format: <int> |
| 2423 | 2423 | |
| 2424 | − libata.force= [LIBATA] Force configurations. The format is comma | |
| 2424 | + libata.force= [LIBATA] Force configurations. The format is comma- | |
| 2425 | 2425 | separated list of "[ID:]VAL" where ID is |
| 2426 | 2426 | PORT[.DEVICE]. PORT and DEVICE are decimal numbers |
| 2427 | 2427 | matching port, link or device. Basically, it matches |
| @@ -5145,7 +5145,7 @@ · 2717 unmodified lines | ||
| 5145 | 5145 | |
| 5146 | 5146 | stacktrace_filter=[function-list] |
| 5147 | 5147 | [FTRACE] Limit the functions that the stack tracer |
| 5148 | − will trace at boot up. function-list is a comma separated | |
| 5148 | + will trace at boot up. function-list is a comma-separated | |
| 5149 | 5149 | list of functions. This list can be changed at run |
| 5150 | 5150 | time by the stack_trace_filter file in the debugfs |
| 5151 | 5151 | tracing directory. Note, this enables stack tracing |
| @@ -5348,7 +5348,7 @@ · 196 unmodified lines | ||
| 5348 | 5348 | trace_event=[event-list] |
| 5349 | 5349 | [FTRACE] Set and start specified trace events in order |
| 5350 | 5350 | to facilitate early boot debugging. The event-list is a |
| 5351 | − comma separated list of trace events to enable. See | |
| 5351 | + comma-separated list of trace events to enable. See | |
| 5352 | 5352 | also Documentation/trace/events.rst |
| 5353 | 5353 | |
| 5354 | 5354 | trace_options=[option-list] |
| @@ -5972,6 +5972,10 @@ · 617 unmodified lines | ||
| 5972 | 5972 | This option is obsoleted by the "nopv" option, which |
| 5973 | 5973 | has equivalent effect for XEN platform. |
| 5974 | 5974 | |
| 5975 | + xen_no_vector_callback | |
| 5976 | + [KNL,X86,XEN] Disable the vector callback for Xen | |
| 5977 | + event channel interrupts. | |
| 5978 | + | |
| 5975 | 5979 | xen_scrub_pages= [XEN] |
| 5976 | 5980 | Boolean option to control scrubbing pages before giving them back |
| 5977 | 5981 | to Xen, for use by other domains. Can be also changed at runtime |
| @@ -184,7 +184,7 @@ pages either asynchronously or synchronously, depending on the state · 183 unmodified lines | ||
| 184 | 184 | of the system. When the system is not loaded, most of the memory is free |
| 185 | 185 | and allocation requests will be satisfied immediately from the free |
| 186 | 186 | pages supply. As the load increases, the amount of the free pages goes |
| 187 | −down and when it reaches a certain threshold (high watermark), an | |
| 187 | +down and when it reaches a certain threshold (low watermark), an | |
| 188 | 188 | allocation request will awaken the ``kswapd`` daemon. It will |
| 189 | 189 | asynchronously scan memory pages and either just free them if the data |
| 190 | 190 | they contain is available elsewhere, or evict to the backing storage |
| @@ -53,7 +53,6 @@ How Linux keeps everything from happening at the same time. See · 52 unmodified lines | ||
| 53 | 53 | .. toctree:: |
| 54 | 54 | :maxdepth: 1 |
| 55 | 55 | |
| 56 | − atomic_ops | |
| 57 | 56 | refcount-vs-atomic |
| 58 | 57 | irq/index |
| 59 | 58 | local_ops |
| @@ -1,4 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | +# Copyright (C) 2020 Texas Instruments Incorporated | |
| 3 | +# Author: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 2 | 4 | %YAML 1.2 |
| 3 | 5 | --- |
| 4 | 6 | $id: http://devicetree.org/schemas/dma/ti/k3-bcdma.yaml# |
| @@ -7,7 +9,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 2 unmodified lines | ||
| 7 | 9 | title: Texas Instruments K3 DMSS BCDMA Device Tree Bindings |
| 8 | 10 | |
| 9 | 11 | maintainers: |
| 10 | − - Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 12 | + - Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 11 | 13 | |
| 12 | 14 | description: | |
| 13 | 15 | The Block Copy DMA (BCDMA) is intended to perform similar functions as the TR |
| @@ -1,4 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | +# Copyright (C) 2020 Texas Instruments Incorporated | |
| 3 | +# Author: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 2 | 4 | %YAML 1.2 |
| 3 | 5 | --- |
| 4 | 6 | $id: http://devicetree.org/schemas/dma/ti/k3-pktdma.yaml# |
| @@ -7,7 +9,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 2 unmodified lines | ||
| 7 | 9 | title: Texas Instruments K3 DMSS PKTDMA Device Tree Bindings |
| 8 | 10 | |
| 9 | 11 | maintainers: |
| 10 | − - Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 12 | + - Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 11 | 13 | |
| 12 | 14 | description: | |
| 13 | 15 | The Packet DMA (PKTDMA) is intended to perform similar functions as the packet |
| @@ -1,4 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | +# Copyright (C) 2019 Texas Instruments Incorporated | |
| 3 | +# Author: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 2 | 4 | %YAML 1.2 |
| 3 | 5 | --- |
| 4 | 6 | $id: http://devicetree.org/schemas/dma/ti/k3-udma.yaml# |
| @@ -7,7 +9,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 2 unmodified lines | ||
| 7 | 9 | title: Texas Instruments K3 NAVSS Unified DMA Device Tree Bindings |
| 8 | 10 | |
| 9 | 11 | maintainers: |
| 10 | − - Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 12 | + - Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 11 | 13 | |
| 12 | 14 | description: | |
| 13 | 15 | The UDMA-P is intended to perform similar (but significantly upgraded) |
| @@ -163,6 +163,7 @@ allOf: · 162 unmodified lines | ||
| 163 | 163 | enum: |
| 164 | 164 | - renesas,etheravb-r8a774a1 |
| 165 | 165 | - renesas,etheravb-r8a774b1 |
| 166 | + - renesas,etheravb-r8a774e1 | |
| 166 | 167 | - renesas,etheravb-r8a7795 |
| 167 | 168 | - renesas,etheravb-r8a7796 |
| 168 | 169 | - renesas,etheravb-r8a77961 |
| @@ -161,7 +161,8 @@ properties: · 160 unmodified lines | ||
| 161 | 161 | * snps,route-dcbcp, DCB Control Packets |
| 162 | 162 | * snps,route-up, Untagged Packets |
| 163 | 163 | * snps,route-multi-broad, Multicast & Broadcast Packets |
| 164 | − * snps,priority, RX queue priority (Range 0x0 to 0xF) | |
| 164 | + * snps,priority, bitmask of the tagged frames priorities assigned to | |
| 165 | + the queue | |
| 165 | 166 | |
| 166 | 167 | snps,mtl-tx-config: |
| 167 | 168 | $ref: /schemas/types.yaml#/definitions/phandle |
| @@ -188,7 +189,10 @@ properties: · 20 unmodified lines | ||
| 188 | 189 | * snps,idle_slope, unlock on WoL |
| 189 | 190 | * snps,high_credit, max write outstanding req. limit |
| 190 | 191 | * snps,low_credit, max read outstanding req. limit |
| 191 | − * snps,priority, TX queue priority (Range 0x0 to 0xF) | |
| 192 | + * snps,priority, bitmask of the priorities assigned to the queue. | |
| 193 | + When a PFC frame is received with priorities matching the bitmask, | |
| 194 | + the queue is blocked from transmitting for the pause time specified | |
| 195 | + in the PFC frame. | |
| 192 | 196 | |
| 193 | 197 | snps,reset-gpio: |
| 194 | 198 | deprecated: true |
| @@ -19,7 +19,9 @@ description: | · 18 unmodified lines | ||
| 19 | 19 | properties: |
| 20 | 20 | compatible: |
| 21 | 21 | enum: |
| 22 | − - nxp,pf8x00 | |
| 22 | + - nxp,pf8100 | |
| 23 | + - nxp,pf8121a | |
| 24 | + - nxp,pf8200 | |
| 23 | 25 | |
| 24 | 26 | reg: |
| 25 | 27 | maxItems: 1 |
| @@ -118,7 +120,7 @@ examples: · 92 unmodified lines | ||
| 118 | 120 | #size-cells = <0>; |
| 119 | 121 | |
| 120 | 122 | pmic@8 { |
| 121 | − compatible = "nxp,pf8x00"; | |
| 123 | + compatible = "nxp,pf8100"; | |
| 122 | 124 | reg = <0x08>; |
| 123 | 125 | |
| 124 | 126 | regulators { |
| @@ -44,6 +44,7 @@ First Level Nodes - PMIC · 43 unmodified lines | ||
| 44 | 44 | Definition: Must be one of below: |
| 45 | 45 | "qcom,pm8005-rpmh-regulators" |
| 46 | 46 | "qcom,pm8009-rpmh-regulators" |
| 47 | + "qcom,pm8009-1-rpmh-regulators" | |
| 47 | 48 | "qcom,pm8150-rpmh-regulators" |
| 48 | 49 | "qcom,pm8150l-rpmh-regulators" |
| 49 | 50 | "qcom,pm8350-rpmh-regulators" |
| @@ -1,4 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | +# Copyright (C) 2020 Texas Instruments Incorporated | |
| 3 | +# Author: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 2 | 4 | %YAML 1.2 |
| 3 | 5 | --- |
| 4 | 6 | $id: http://devicetree.org/schemas/sound/ti,j721e-cpb-audio.yaml# |
| @@ -7,7 +9,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 2 unmodified lines | ||
| 7 | 9 | title: Texas Instruments J721e Common Processor Board Audio Support |
| 8 | 10 | |
| 9 | 11 | maintainers: |
| 10 | − - Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 12 | + - Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 11 | 13 | |
| 12 | 14 | description: | |
| 13 | 15 | The audio support on the board is using pcm3168a codec connected to McASP10 |
| @@ -1,4 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | +# Copyright (C) 2020 Texas Instruments Incorporated | |
| 3 | +# Author: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 2 | 4 | %YAML 1.2 |
| 3 | 5 | --- |
| 4 | 6 | $id: http://devicetree.org/schemas/sound/ti,j721e-cpb-ivi-audio.yaml# |
| @@ -7,7 +9,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 2 unmodified lines | ||
| 7 | 9 | title: Texas Instruments J721e Common Processor Board Audio Support |
| 8 | 10 | |
| 9 | 11 | maintainers: |
| 10 | − - Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 12 | + - Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 11 | 13 | |
| 12 | 14 | description: | |
| 13 | 15 | The Infotainment board plugs into the Common Processor Board, the support of the |
| @@ -11,8 +11,12 @@ maintainers: · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | properties: |
| 13 | 13 | compatible: |
| 14 | − items: | |
| 14 | + oneOf: | |
| 15 | 15 | - const: ti,j721e-usb |
| 16 | + - const: ti,am64-usb | |
| 17 | + - items: | |
| 18 | + - const: ti,j721e-usb | |
| 19 | + - const: ti,am64-usb | |
| 16 | 20 | |
| 17 | 21 | reg: |
| 18 | 22 | description: module registers |
| @@ -48,12 +48,12 @@ or ``virtualenv``, depending on how your distribution packaged Python 3. · 47 unmodified lines | ||
| 48 | 48 | those versions, you should run ``pip install 'docutils==0.12'``. |
| 49 | 49 | |
| 50 | 50 | #) It is recommended to use the RTD theme for html output. Depending |
| 51 | − on the Sphinx version, it should be installed in separate, | |
| 51 | + on the Sphinx version, it should be installed separately, | |
| 52 | 52 | with ``pip install sphinx_rtd_theme``. |
| 53 | 53 | |
| 54 | − #) Some ReST pages contain math expressions. Due to the way Sphinx work, | |
| 54 | + #) Some ReST pages contain math expressions. Due to the way Sphinx works, | |
| 55 | 55 | those expressions are written using LaTeX notation. It needs texlive |
| 56 | − installed with amdfonts and amsmath in order to evaluate them. | |
| 56 | + installed with amsfonts and amsmath in order to evaluate them. | |
| 57 | 57 | |
| 58 | 58 | In summary, if you want to install Sphinx version 1.7.9, you should do:: |
| 59 | 59 | |
| @@ -128,7 +128,7 @@ Sphinx Build · 68 unmodified lines | ||
| 128 | 128 | ============ |
| 129 | 129 | |
| 130 | 130 | The usual way to generate the documentation is to run ``make htmldocs`` or |
| 131 | −``make pdfdocs``. There are also other formats available, see the documentation | |
| 131 | +``make pdfdocs``. There are also other formats available: see the documentation | |
| 132 | 132 | section of ``make help``. The generated documentation is placed in |
| 133 | 133 | format-specific subdirectories under ``Documentation/output``. |
| 134 | 134 | |
| @@ -303,17 +303,17 @@ and *targets* (e.g. a ref to ``:ref:`last row <last row>``` / :ref:`last row · 168 unmodified lines | ||
| 303 | 303 | - head col 3 |
| 304 | 304 | - head col 4 |
| 305 | 305 | |
| 306 | − * - column 1 | |
| 306 | + * - row 1 | |
| 307 | 307 | - field 1.1 |
| 308 | 308 | - field 1.2 with autospan |
| 309 | 309 | |
| 310 | − * - column 2 | |
| 310 | + * - row 2 | |
| 311 | 311 | - field 2.1 |
| 312 | 312 | - :rspan:`1` :cspan:`1` field 2.2 - 3.3 |
| 313 | 313 | |
| 314 | 314 | * .. _`last row`: |
| 315 | 315 | |
| 316 | − - column 3 | |
| 316 | + - row 3 | |
| 317 | 317 | |
| 318 | 318 | Rendered as: |
| 319 | 319 | |
| @@ -325,17 +325,17 @@ Rendered as: · 5 unmodified lines | ||
| 325 | 325 | - head col 3 |
| 326 | 326 | - head col 4 |
| 327 | 327 | |
| 328 | − * - column 1 | |
| 328 | + * - row 1 | |
| 329 | 329 | - field 1.1 |
| 330 | 330 | - field 1.2 with autospan |
| 331 | 331 | |
| 332 | − * - column 2 | |
| 332 | + * - row 2 | |
| 333 | 333 | - field 2.1 |
| 334 | 334 | - :rspan:`1` :cspan:`1` field 2.2 - 3.3 |
| 335 | 335 | |
| 336 | 336 | * .. _`last row`: |
| 337 | 337 | |
| 338 | − - column 3 | |
| 338 | + - row 3 | |
| 339 | 339 | |
| 340 | 340 | Cross-referencing |
| 341 | 341 | ----------------- |
| @@ -361,7 +361,7 @@ Figures & Images · 19 unmodified lines | ||
| 361 | 361 | |
| 362 | 362 | If you want to add an image, you should use the ``kernel-figure`` and |
| 363 | 363 | ``kernel-image`` directives. E.g. to insert a figure with a scalable |
| 364 | −image format use SVG (:ref:`svg_image_example`):: | |
| 364 | +image format, use SVG (:ref:`svg_image_example`):: | |
| 365 | 365 | |
| 366 | 366 | .. kernel-figure:: svg_image.svg |
| 367 | 367 | :alt: simple SVG image |
| @@ -375,7 +375,7 @@ image format use SVG (:ref:`svg_image_example`):: · 7 unmodified lines | ||
| 375 | 375 | |
| 376 | 376 | SVG image example |
| 377 | 377 | |
| 378 | −The kernel figure (and image) directive support **DOT** formatted files, see | |
| 378 | +The kernel figure (and image) directive supports **DOT** formatted files, see | |
| 379 | 379 | |
| 380 | 380 | * DOT: http://graphviz.org/pdf/dotguide.pdf |
| 381 | 381 | * Graphviz: http://www.graphviz.org/content/dot-language |
| @@ -394,7 +394,7 @@ A simple example (:ref:`hello_dot_file`):: · 12 unmodified lines | ||
| 394 | 394 | |
| 395 | 395 | DOT's hello world example |
| 396 | 396 | |
| 397 | −Embed *render* markups (or languages) like Graphviz's **DOT** is provided by the | |
| 397 | +Embedded *render* markups (or languages) like Graphviz's **DOT** are provided by the | |
| 398 | 398 | ``kernel-render`` directives.:: |
| 399 | 399 | |
| 400 | 400 | .. kernel-render:: DOT |
| @@ -406,7 +406,7 @@ Embed *render* markups (or languages) like Graphviz's **DOT** is provided by the · 5 unmodified lines | ||
| 406 | 406 | } |
| 407 | 407 | |
| 408 | 408 | How this will be rendered depends on the installed tools. If Graphviz is |
| 409 | −installed, you will see an vector image. If not the raw markup is inserted as | |
| 409 | +installed, you will see a vector image. If not, the raw markup is inserted as | |
| 410 | 410 | *literal-block* (:ref:`hello_dot_render`). |
| 411 | 411 | |
| 412 | 412 | .. _hello_dot_render: |
| @@ -421,8 +421,8 @@ installed, you will see an vector image. If not the raw markup is inserted as · 8 unmodified lines | ||
| 421 | 421 | |
| 422 | 422 | The *render* directive has all the options known from the *figure* directive, |
| 423 | 423 | plus option ``caption``. If ``caption`` has a value, a *figure* node is |
| 424 | −inserted. If not, a *image* node is inserted. A ``caption`` is also needed, if | |
| 425 | −you want to refer it (:ref:`hello_svg_render`). | |
| 424 | +inserted. If not, an *image* node is inserted. A ``caption`` is also needed, if | |
| 425 | +you want to refer to it (:ref:`hello_svg_render`). | |
| 426 | 426 | |
| 427 | 427 | Embedded **SVG**:: |
| 428 | 428 | |
| @@ -50,8 +50,8 @@ The following files belong to it: · 49 unmodified lines | ||
| 50 | 50 | 0x00000010 Memory Uncorrectable non-fatal |
| 51 | 51 | 0x00000020 Memory Uncorrectable fatal |
| 52 | 52 | 0x00000040 PCI Express Correctable |
| 53 | − 0x00000080 PCI Express Uncorrectable fatal | |
| 54 | − 0x00000100 PCI Express Uncorrectable non-fatal | |
| 53 | + 0x00000080 PCI Express Uncorrectable non-fatal | |
| 54 | + 0x00000100 PCI Express Uncorrectable fatal | |
| 55 | 55 | 0x00000200 Platform Correctable |
| 56 | 56 | 0x00000400 Platform Uncorrectable non-fatal |
| 57 | 57 | 0x00000800 Platform Uncorrectable fatal |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | .. SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | 2 | |
| 3 | 3 | Kernel driver sbtsi_temp |
| 4 | −================== | |
| 4 | +======================== | |
| 5 | 5 | |
| 6 | 6 | Supported hardware: |
| 7 | 7 | |
| @@ -598,7 +598,7 @@ more details, with real examples. · 597 unmodified lines | ||
| 598 | 598 | explicitly added to $(targets). |
| 599 | 599 | |
| 600 | 600 | Assignments to $(targets) are without $(obj)/ prefix. if_changed may be |
| 601 | − used in conjunction with custom rules as defined in "3.9 Custom Rules". | |
| 601 | + used in conjunction with custom rules as defined in "3.11 Custom Rules". | |
| 602 | 602 | |
| 603 | 603 | Note: It is a typical mistake to forget the FORCE prerequisite. |
| 604 | 604 | Another common pitfall is that whitespace is sometimes significant; for |
| @@ -118,11 +118,11 @@ spinlock, but you may block holding a mutex. If you can't lock a mutex, · 117 unmodified lines | ||
| 118 | 118 | your task will suspend itself, and be woken up when the mutex is |
| 119 | 119 | released. This means the CPU can do something else while you are |
| 120 | 120 | waiting. There are many cases when you simply can't sleep (see |
| 121 | −`What Functions Are Safe To Call From Interrupts? <#sleeping-things>`__), | |
| 121 | +`What Functions Are Safe To Call From Interrupts?`_), | |
| 122 | 122 | and so have to use a spinlock instead. |
| 123 | 123 | |
| 124 | 124 | Neither type of lock is recursive: see |
| 125 | −`Deadlock: Simple and Advanced <#deadlock>`__. | |
| 125 | +`Deadlock: Simple and Advanced`_. | |
| 126 | 126 | |
| 127 | 127 | Locks and Uniprocessor Kernels |
| 128 | 128 | ------------------------------ |
| @@ -179,7 +179,7 @@ perfect world). · 50 unmodified lines | ||
| 179 | 179 | |
| 180 | 180 | Note that you can also use spin_lock_irq() or |
| 181 | 181 | spin_lock_irqsave() here, which stop hardware interrupts |
| 182 | −as well: see `Hard IRQ Context <#hard-irq-context>`__. | |
| 182 | +as well: see `Hard IRQ Context`_. | |
| 183 | 183 | |
| 184 | 184 | This works perfectly for UP as well: the spin lock vanishes, and this |
| 185 | 185 | macro simply becomes local_bh_disable() |
| @@ -230,7 +230,7 @@ The Same Softirq · 44 unmodified lines | ||
| 230 | 230 | ~~~~~~~~~~~~~~~~ |
| 231 | 231 | |
| 232 | 232 | The same softirq can run on the other CPUs: you can use a per-CPU array |
| 233 | −(see `Per-CPU Data <#per-cpu-data>`__) for better performance. If you're | |
| 233 | +(see `Per-CPU Data`_) for better performance. If you're | |
| 234 | 234 | going so far as to use a softirq, you probably care about scalable |
| 235 | 235 | performance enough to justify the extra complexity. |
| 236 | 236 | |
| @@ -164,46 +164,56 @@ Devlink health reporters · 163 unmodified lines | ||
| 164 | 164 | |
| 165 | 165 | NPA Reporters |
| 166 | 166 | ------------- |
| 167 | −The NPA reporters are responsible for reporting and recovering the following group of errors | |
| 167 | +The NPA reporters are responsible for reporting and recovering the following group of errors: | |
| 168 | + | |
| 168 | 169 | 1. GENERAL events |
| 170 | + | |
| 169 | 171 | - Error due to operation of unmapped PF. |
| 170 | 172 | - Error due to disabled alloc/free for other HW blocks (NIX, SSO, TIM, DPI and AURA). |
| 173 | + | |
| 171 | 174 | 2. ERROR events |
| 175 | + | |
| 172 | 176 | - Fault due to NPA_AQ_INST_S read or NPA_AQ_RES_S write. |
| 173 | 177 | - AQ Doorbell Error. |
| 178 | + | |
| 174 | 179 | 3. RAS events |
| 180 | + | |
| 175 | 181 | - RAS Error Reporting for NPA_AQ_INST_S/NPA_AQ_RES_S. |
| 182 | + | |
| 176 | 183 | 4. RVU events |
| 184 | + | |
| 177 | 185 | - Error due to unmapped slot. |
| 178 | 186 | |
| 179 | −Sample Output | |
| 180 | −------------- | |
| 181 | −~# devlink health | |
| 182 | −pci/0002:01:00.0: | |
| 183 | − reporter hw_npa_intr | |
| 184 | − state healthy error 2872 recover 2872 last_dump_date 2020-12-10 last_dump_time 09:39:09 grace_period 0 auto_recover true auto_dump true | |
| 185 | − reporter hw_npa_gen | |
| 186 | − state healthy error 2872 recover 2872 last_dump_date 2020-12-11 last_dump_time 04:43:04 grace_period 0 auto_recover true auto_dump true | |
| 187 | − reporter hw_npa_err | |
| 188 | − state healthy error 2871 recover 2871 last_dump_date 2020-12-10 last_dump_time 09:39:17 grace_period 0 auto_recover true auto_dump true | |
| 189 | − reporter hw_npa_ras | |
| 190 | − state healthy error 0 recover 0 last_dump_date 2020-12-10 last_dump_time 09:32:40 grace_period 0 auto_recover true auto_dump true | |
| 187 | +Sample Output:: | |
| 188 | + | |
| 189 | + ~# devlink health | |
| 190 | + pci/0002:01:00.0: | |
| 191 | + reporter hw_npa_intr | |
| 192 | + state healthy error 2872 recover 2872 last_dump_date 2020-12-10 last_dump_time 09:39:09 grace_period 0 auto_recover true auto_dump true | |
| 193 | + reporter hw_npa_gen | |
| 194 | + state healthy error 2872 recover 2872 last_dump_date 2020-12-11 last_dump_time 04:43:04 grace_period 0 auto_recover true auto_dump true | |
| 195 | + reporter hw_npa_err | |
| 196 | + state healthy error 2871 recover 2871 last_dump_date 2020-12-10 last_dump_time 09:39:17 grace_period 0 auto_recover true auto_dump true | |
| 197 | + reporter hw_npa_ras | |
| 198 | + state healthy error 0 recover 0 last_dump_date 2020-12-10 last_dump_time 09:32:40 grace_period 0 auto_recover true auto_dump true | |
| 191 | 199 | |
| 192 | 200 | Each reporter dumps the |
| 201 | + | |
| 193 | 202 | - Error Type |
| 194 | 203 | - Error Register value |
| 195 | 204 | - Reason in words |
| 196 | 205 | |
| 197 | −For eg: | |
| 198 | −~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_gen | |
| 199 | − NPA_AF_GENERAL: | |
| 200 | − NPA General Interrupt Reg : 1 | |
| 201 | − NIX0: free disabled RX | |
| 202 | −~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_intr | |
| 203 | − NPA_AF_RVU: | |
| 204 | − NPA RVU Interrupt Reg : 1 | |
| 205 | − Unmap Slot Error | |
| 206 | −~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_err | |
| 207 | − NPA_AF_ERR: | |
| 208 | − NPA Error Interrupt Reg : 4096 | |
| 209 | − AQ Doorbell Error | |
| 206 | +For example:: | |
| 207 | + | |
| 208 | + ~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_gen | |
| 209 | + NPA_AF_GENERAL: | |
| 210 | + NPA General Interrupt Reg : 1 | |
| 211 | + NIX0: free disabled RX | |
| 212 | + ~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_intr | |
| 213 | + NPA_AF_RVU: | |
| 214 | + NPA RVU Interrupt Reg : 1 | |
| 215 | + Unmap Slot Error | |
| 216 | + ~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_err | |
| 217 | + NPA_AF_ERR: | |
| 218 | + NPA Error Interrupt Reg : 4096 | |
| 219 | + AQ Doorbell Error | |
| @@ -6,9 +6,9 @@ · 5 unmodified lines | ||
| 6 | 6 | netdev FAQ |
| 7 | 7 | ========== |
| 8 | 8 | |
| 9 | −Q: What is netdev? | |
| 10 | −------------------ | |
| 11 | −A: It is a mailing list for all network-related Linux stuff. This | |
| 9 | +What is netdev? | |
| 10 | +--------------- | |
| 11 | +It is a mailing list for all network-related Linux stuff. This | |
| 12 | 12 | includes anything found under net/ (i.e. core code like IPv6) and |
| 13 | 13 | drivers/net (i.e. hardware specific drivers) in the Linux source tree. |
| 14 | 14 | |
| @@ -25,9 +25,9 @@ Aside from subsystems like that mentioned above, all network-related · 10 unmodified lines | ||
| 25 | 25 | Linux development (i.e. RFC, review, comments, etc.) takes place on |
| 26 | 26 | netdev. |
| 27 | 27 | |
| 28 | −Q: How do the changes posted to netdev make their way into Linux? | |
| 29 | −----------------------------------------------------------------- | |
| 30 | −A: There are always two trees (git repositories) in play. Both are | |
| 28 | +How do the changes posted to netdev make their way into Linux? | |
| 29 | +-------------------------------------------------------------- | |
| 30 | +There are always two trees (git repositories) in play. Both are | |
| 31 | 31 | driven by David Miller, the main network maintainer. There is the |
| 32 | 32 | ``net`` tree, and the ``net-next`` tree. As you can probably guess from |
| 33 | 33 | the names, the ``net`` tree is for fixes to existing code already in the |
| @@ -37,9 +37,9 @@ for the future release. You can find the trees here: · 3 unmodified lines | ||
| 37 | 37 | - https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git |
| 38 | 38 | - https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git |
| 39 | 39 | |
| 40 | −Q: How often do changes from these trees make it to the mainline Linus tree? | |
| 41 | −---------------------------------------------------------------------------- | |
| 42 | −A: To understand this, you need to know a bit of background information on | |
| 40 | +How often do changes from these trees make it to the mainline Linus tree? | |
| 41 | +------------------------------------------------------------------------- | |
| 42 | +To understand this, you need to know a bit of background information on | |
| 43 | 43 | the cadence of Linux development. Each new release starts off with a |
| 44 | 44 | two week "merge window" where the main maintainers feed their new stuff |
| 45 | 45 | to Linus for merging into the mainline tree. After the two weeks, the |
| @@ -81,7 +81,8 @@ focus for ``net`` is on stabilization and bug fixes. · 35 unmodified lines | ||
| 81 | 81 | |
| 82 | 82 | Finally, the vX.Y gets released, and the whole cycle starts over. |
| 83 | 83 | |
| 84 | −Q: So where are we now in this cycle? | |
| 84 | +So where are we now in this cycle? | |
| 85 | +---------------------------------- | |
| 85 | 86 | |
| 86 | 87 | Load the mainline (Linus) page here: |
| 87 | 88 | |
| @@ -91,9 +92,9 @@ and note the top of the "tags" section. If it is rc1, it is early in · 3 unmodified lines | ||
| 91 | 92 | the dev cycle. If it was tagged rc7 a week ago, then a release is |
| 92 | 93 | probably imminent. |
| 93 | 94 | |
| 94 | −Q: How do I indicate which tree (net vs. net-next) my patch should be in? | |
| 95 | −------------------------------------------------------------------------- | |
| 96 | −A: Firstly, think whether you have a bug fix or new "next-like" content. | |
| 95 | +How do I indicate which tree (net vs. net-next) my patch should be in? | |
| 96 | +---------------------------------------------------------------------- | |
| 97 | +Firstly, think whether you have a bug fix or new "next-like" content. | |
| 97 | 98 | Then once decided, assuming that you use git, use the prefix flag, i.e. |
| 98 | 99 | :: |
| 99 | 100 | |
| @@ -105,48 +106,45 @@ in the above is just the subject text of the outgoing e-mail, and you · 5 unmodified lines | ||
| 105 | 106 | can manually change it yourself with whatever MUA you are comfortable |
| 106 | 107 | with. |
| 107 | 108 | |
| 108 | −Q: I sent a patch and I'm wondering what happened to it? | |
| 109 | −-------------------------------------------------------- | |
| 110 | −Q: How can I tell whether it got merged? | |
| 111 | −A: Start by looking at the main patchworks queue for netdev: | |
| 109 | +I sent a patch and I'm wondering what happened to it - how can I tell whether it got merged? | |
| 110 | +-------------------------------------------------------------------------------------------- | |
| 111 | +Start by looking at the main patchworks queue for netdev: | |
| 112 | 112 | |
| 113 | 113 | https://patchwork.kernel.org/project/netdevbpf/list/ |
| 114 | 114 | |
| 115 | 115 | The "State" field will tell you exactly where things are at with your |
| 116 | 116 | patch. |
| 117 | 117 | |
| 118 | −Q: The above only says "Under Review". How can I find out more? | |
| 119 | −---------------------------------------------------------------- | |
| 120 | −A: Generally speaking, the patches get triaged quickly (in less than | |
| 118 | +The above only says "Under Review". How can I find out more? | |
| 119 | +------------------------------------------------------------- | |
| 120 | +Generally speaking, the patches get triaged quickly (in less than | |
| 121 | 121 | 48h). So be patient. Asking the maintainer for status updates on your |
| 122 | 122 | patch is a good way to ensure your patch is ignored or pushed to the |
| 123 | 123 | bottom of the priority list. |
| 124 | 124 | |
| 125 | −Q: I submitted multiple versions of the patch series | |
| 126 | −---------------------------------------------------- | |
| 127 | −Q: should I directly update patchwork for the previous versions of these | |
| 128 | −patch series? | |
| 129 | −A: No, please don't interfere with the patch status on patchwork, leave | |
| 125 | +I submitted multiple versions of the patch series. Should I directly update patchwork for the previous versions of these patch series? | |
| 126 | +-------------------------------------------------------------------------------------------------------------------------------------- | |
| 127 | +No, please don't interfere with the patch status on patchwork, leave | |
| 130 | 128 | it to the maintainer to figure out what is the most recent and current |
| 131 | 129 | version that should be applied. If there is any doubt, the maintainer |
| 132 | 130 | will reply and ask what should be done. |
| 133 | 131 | |
| 134 | −Q: I made changes to only a few patches in a patch series should I resend only those changed? | |
| 135 | −--------------------------------------------------------------------------------------------- | |
| 136 | −A: No, please resend the entire patch series and make sure you do number your | |
| 132 | +I made changes to only a few patches in a patch series should I resend only those changed? | |
| 133 | +------------------------------------------------------------------------------------------ | |
| 134 | +No, please resend the entire patch series and make sure you do number your | |
| 137 | 135 | patches such that it is clear this is the latest and greatest set of patches |
| 138 | 136 | that can be applied. |
| 139 | 137 | |
| 140 | −Q: I submitted multiple versions of a patch series and it looks like a version other than the last one has been accepted, what should I do? | |
| 141 | −------------------------------------------------------------------------------------------------------------------------------------------- | |
| 142 | −A: There is no revert possible, once it is pushed out, it stays like that. | |
| 138 | +I submitted multiple versions of a patch series and it looks like a version other than the last one has been accepted, what should I do? | |
| 139 | +---------------------------------------------------------------------------------------------------------------------------------------- | |
| 140 | +There is no revert possible, once it is pushed out, it stays like that. | |
| 143 | 141 | Please send incremental versions on top of what has been merged in order to fix |
| 144 | 142 | the patches the way they would look like if your latest patch series was to be |
| 145 | 143 | merged. |
| 146 | 144 | |
| 147 | −Q: How can I tell what patches are queued up for backporting to the various stable releases? | |
| 148 | −-------------------------------------------------------------------------------------------- | |
| 149 | −A: Normally Greg Kroah-Hartman collects stable commits himself, but for | |
| 145 | +How can I tell what patches are queued up for backporting to the various stable releases? | |
| 146 | +----------------------------------------------------------------------------------------- | |
| 147 | +Normally Greg Kroah-Hartman collects stable commits himself, but for | |
| 150 | 148 | networking, Dave collects up patches he deems critical for the |
| 151 | 149 | networking subsystem, and then hands them off to Greg. |
| 152 | 150 | |
| @@ -169,11 +167,9 @@ simply clone the repo, and then git grep the mainline commit ID, e.g. · 16 unmodified lines | ||
| 169 | 167 | releases/3.9.8/ipv6-fix-possible-crashes-in-ip6_cork_release.patch |
| 170 | 168 | stable/stable-queue$ |
| 171 | 169 | |
| 172 | −Q: I see a network patch and I think it should be backported to stable. | |
| 173 | −----------------------------------------------------------------------- | |
| 174 | −Q: Should I request it via stable@vger.kernel.org like the references in | |
| 175 | −the kernel's Documentation/process/stable-kernel-rules.rst file say? | |
| 176 | −A: No, not for networking. Check the stable queues as per above first | |
| 170 | +I see a network patch and I think it should be backported to stable. Should I request it via stable@vger.kernel.org like the references in the kernel's Documentation/process/stable-kernel-rules.rst file say? | |
| 171 | +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| 172 | +No, not for networking. Check the stable queues as per above first | |
| 177 | 173 | to see if it is already queued. If not, then send a mail to netdev, |
| 178 | 174 | listing the upstream commit ID and why you think it should be a stable |
| 179 | 175 | candidate. |
| @@ -190,11 +186,9 @@ mainline, the better the odds that it is an OK candidate for stable. So · 10 unmodified lines | ||
| 190 | 186 | scrambling to request a commit be added the day after it appears should |
| 191 | 187 | be avoided. |
| 192 | 188 | |
| 193 | −Q: I have created a network patch and I think it should be backported to stable. | |
| 194 | −-------------------------------------------------------------------------------- | |
| 195 | −Q: Should I add a Cc: stable@vger.kernel.org like the references in the | |
| 196 | −kernel's Documentation/ directory say? | |
| 197 | −A: No. See above answer. In short, if you think it really belongs in | |
| 189 | +I have created a network patch and I think it should be backported to stable. Should I add a Cc: stable@vger.kernel.org like the references in the kernel's Documentation/ directory say? | |
| 190 | +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| 191 | +No. See above answer. In short, if you think it really belongs in | |
| 198 | 192 | stable, then ensure you write a decent commit log that describes who |
| 199 | 193 | gets impacted by the bug fix and how it manifests itself, and when the |
| 200 | 194 | bug was introduced. If you do that properly, then the commit will get |
| @@ -207,18 +201,18 @@ marker line as described in · 6 unmodified lines | ||
| 207 | 201 | :ref:`Documentation/process/submitting-patches.rst <the_canonical_patch_format>` |
| 208 | 202 | to temporarily embed that information into the patch that you send. |
| 209 | 203 | |
| 210 | −Q: Are all networking bug fixes backported to all stable releases? | |
| 211 | −------------------------------------------------------------------ | |
| 212 | −A: Due to capacity, Dave could only take care of the backports for the | |
| 204 | +Are all networking bug fixes backported to all stable releases? | |
| 205 | +--------------------------------------------------------------- | |
| 206 | +Due to capacity, Dave could only take care of the backports for the | |
| 213 | 207 | last two stable releases. For earlier stable releases, each stable |
| 214 | 208 | branch maintainer is supposed to take care of them. If you find any |
| 215 | 209 | patch is missing from an earlier stable branch, please notify |
| 216 | 210 | stable@vger.kernel.org with either a commit ID or a formal patch |
| 217 | 211 | backported, and CC Dave and other relevant networking developers. |
| 218 | 212 | |
| 219 | −Q: Is the comment style convention different for the networking content? | |
| 220 | −------------------------------------------------------------------------ | |
| 221 | −A: Yes, in a largely trivial way. Instead of this:: | |
| 213 | +Is the comment style convention different for the networking content? | |
| 214 | +--------------------------------------------------------------------- | |
| 215 | +Yes, in a largely trivial way. Instead of this:: | |
| 222 | 216 | |
| 223 | 217 | /* |
| 224 | 218 | * foobar blah blah blah |
| @@ -231,32 +225,30 @@ it is requested that you make it look like this:: · 6 unmodified lines | ||
| 231 | 225 | * another line of text |
| 232 | 226 | */ |
| 233 | 227 | |
| 234 | −Q: I am working in existing code that has the former comment style and not the latter. | |
| 235 | −-------------------------------------------------------------------------------------- | |
| 236 | −Q: Should I submit new code in the former style or the latter? | |
| 237 | −A: Make it the latter style, so that eventually all code in the domain | |
| 228 | +I am working in existing code that has the former comment style and not the latter. Should I submit new code in the former style or the latter? | |
| 229 | +----------------------------------------------------------------------------------------------------------------------------------------------- | |
| 230 | +Make it the latter style, so that eventually all code in the domain | |
| 238 | 231 | of netdev is of this format. |
| 239 | 232 | |
| 240 | −Q: I found a bug that might have possible security implications or similar. | |
| 241 | −--------------------------------------------------------------------------- | |
| 242 | −Q: Should I mail the main netdev maintainer off-list?** | |
| 243 | −A: No. The current netdev maintainer has consistently requested that | |
| 233 | +I found a bug that might have possible security implications or similar. Should I mail the main netdev maintainer off-list? | |
| 234 | +--------------------------------------------------------------------------------------------------------------------------- | |
| 235 | +No. The current netdev maintainer has consistently requested that | |
| 244 | 236 | people use the mailing lists and not reach out directly. If you aren't |
| 245 | 237 | OK with that, then perhaps consider mailing security@kernel.org or |
| 246 | 238 | reading about http://oss-security.openwall.org/wiki/mailing-lists/distros |
| 247 | 239 | as possible alternative mechanisms. |
| 248 | 240 | |
| 249 | −Q: What level of testing is expected before I submit my change? | |
| 250 | −--------------------------------------------------------------- | |
| 251 | −A: If your changes are against ``net-next``, the expectation is that you | |
| 241 | +What level of testing is expected before I submit my change? | |
| 242 | +------------------------------------------------------------ | |
| 243 | +If your changes are against ``net-next``, the expectation is that you | |
| 252 | 244 | have tested by layering your changes on top of ``net-next``. Ideally |
| 253 | 245 | you will have done run-time testing specific to your change, but at a |
| 254 | 246 | minimum, your changes should survive an ``allyesconfig`` and an |
| 255 | 247 | ``allmodconfig`` build without new warnings or failures. |
| 256 | 248 | |
| 257 | −Q: How do I post corresponding changes to user space components? | |
| 258 | −---------------------------------------------------------------- | |
| 259 | −A: User space code exercising kernel features should be posted | |
| 249 | +How do I post corresponding changes to user space components? | |
| 250 | +------------------------------------------------------------- | |
| 251 | +User space code exercising kernel features should be posted | |
| 260 | 252 | alongside kernel patches. This gives reviewers a chance to see |
| 261 | 253 | how any new interface is used and how well it works. |
| 262 | 254 | |
| @@ -280,9 +272,9 @@ to the mailing list, e.g.:: · 17 unmodified lines | ||
| 280 | 272 | Posting as one thread is discouraged because it confuses patchwork |
| 281 | 273 | (as of patchwork 2.2.2). |
| 282 | 274 | |
| 283 | −Q: Any other tips to help ensure my net/net-next patch gets OK'd? | |
| 284 | −----------------------------------------------------------------- | |
| 285 | −A: Attention to detail. Re-read your own work as if you were the | |
| 275 | +Any other tips to help ensure my net/net-next patch gets OK'd? | |
| 276 | +-------------------------------------------------------------- | |
| 277 | +Attention to detail. Re-read your own work as if you were the | |
| 286 | 278 | reviewer. You can start with using ``checkpatch.pl``, perhaps even with |
| 287 | 279 | the ``--strict`` flag. But do not be mindlessly robotic in doing so. |
| 288 | 280 | If your change is a bug fix, make sure your commit log indicates the |
| @@ -10,18 +10,177 @@ Introduction · 9 unmodified lines | ||
| 10 | 10 | The following is a random collection of documentation regarding |
| 11 | 11 | network devices. |
| 12 | 12 | |
| 13 | −struct net_device allocation rules | |
| 14 | −================================== | |
| 13 | +struct net_device lifetime rules | |
| 14 | +================================ | |
| 15 | 15 | Network device structures need to persist even after module is unloaded and |
| 16 | 16 | must be allocated with alloc_netdev_mqs() and friends. |
| 17 | 17 | If device has registered successfully, it will be freed on last use |
| 18 | −by free_netdev(). This is required to handle the pathologic case cleanly | |
| 19 | −(example: rmmod mydriver </sys/class/net/myeth/mtu ) | |
| 18 | +by free_netdev(). This is required to handle the pathological case cleanly | |
| 19 | +(example: ``rmmod mydriver </sys/class/net/myeth/mtu``) | |
| 20 | 20 | |
| 21 | −alloc_netdev_mqs()/alloc_netdev() reserve extra space for driver | |
| 21 | +alloc_netdev_mqs() / alloc_netdev() reserve extra space for driver | |
| 22 | 22 | private data which gets freed when the network device is freed. If |
| 23 | 23 | separately allocated data is attached to the network device |
| 24 | −(netdev_priv(dev)) then it is up to the module exit handler to free that. | |
| 24 | +(netdev_priv()) then it is up to the module exit handler to free that. | |
| 25 | + | |
| 26 | +There are two groups of APIs for registering struct net_device. | |
| 27 | +First group can be used in normal contexts where ``rtnl_lock`` is not already | |
| 28 | +held: register_netdev(), unregister_netdev(). | |
| 29 | +Second group can be used when ``rtnl_lock`` is already held: | |
| 30 | +register_netdevice(), unregister_netdevice(), free_netdevice(). | |
| 31 | + | |
| 32 | +Simple drivers | |
| 33 | +-------------- | |
| 34 | + | |
| 35 | +Most drivers (especially device drivers) handle lifetime of struct net_device | |
| 36 | +in context where ``rtnl_lock`` is not held (e.g. driver probe and remove paths). | |
| 37 | + | |
| 38 | +In that case the struct net_device registration is done using | |
| 39 | +the register_netdev(), and unregister_netdev() functions: | |
| 40 | + | |
| 41 | +.. code-block:: c | |
| 42 | + | |
| 43 | + int probe() | |
| 44 | + { | |
| 45 | + struct my_device_priv *priv; | |
| 46 | + int err; | |
| 47 | + | |
| 48 | + dev = alloc_netdev_mqs(...); | |
| 49 | + if (!dev) | |
| 50 | + return -ENOMEM; | |
| 51 | + priv = netdev_priv(dev); | |
| 52 | + | |
| 53 | + /* ... do all device setup before calling register_netdev() ... | |
| 54 | + */ | |
| 55 | + | |
| 56 | + err = register_netdev(dev); | |
| 57 | + if (err) | |
| 58 | + goto err_undo; | |
| 59 | + | |
| 60 | + /* net_device is visible to the user! */ | |
| 61 | + | |
| 62 | + err_undo: | |
| 63 | + /* ... undo the device setup ... */ | |
| 64 | + free_netdev(dev); | |
| 65 | + return err; | |
| 66 | + } | |
| 67 | + | |
| 68 | + void remove() | |
| 69 | + { | |
| 70 | + unregister_netdev(dev); | |
| 71 | + free_netdev(dev); | |
| 72 | + } | |
| 73 | + | |
| 74 | +Note that after calling register_netdev() the device is visible in the system. | |
| 75 | +Users can open it and start sending / receiving traffic immediately, | |
| 76 | +or run any other callback, so all initialization must be done prior to | |
| 77 | +registration. | |
| 78 | + | |
| 79 | +unregister_netdev() closes the device and waits for all users to be done | |
| 80 | +with it. The memory of struct net_device itself may still be referenced | |
| 81 | +by sysfs but all operations on that device will fail. | |
| 82 | + | |
| 83 | +free_netdev() can be called after unregister_netdev() returns on when | |
| 84 | +register_netdev() failed. | |
| 85 | + | |
| 86 | +Device management under RTNL | |
| 87 | +---------------------------- | |
| 88 | + | |
| 89 | +Registering struct net_device while in context which already holds | |
| 90 | +the ``rtnl_lock`` requires extra care. In those scenarios most drivers | |
| 91 | +will want to make use of struct net_device's ``needs_free_netdev`` | |
| 92 | +and ``priv_destructor`` members for freeing of state. | |
| 93 | + | |
| 94 | +Example flow of netdev handling under ``rtnl_lock``: | |
| 95 | + | |
| 96 | +.. code-block:: c | |
| 97 | + | |
| 98 | + static void my_setup(struct net_device *dev) | |
| 99 | + { | |
| 100 | + dev->needs_free_netdev = true; | |
| 101 | + } | |
| 102 | + | |
| 103 | + static void my_destructor(struct net_device *dev) | |
| 104 | + { | |
| 105 | + some_obj_destroy(priv->obj); | |
| 106 | + some_uninit(priv); | |
| 107 | + } | |
| 108 | + | |
| 109 | + int create_link() | |
| 110 | + { | |
| 111 | + struct my_device_priv *priv; | |
| 112 | + int err; | |
| 113 | + | |
| 114 | + ASSERT_RTNL(); | |
| 115 | + | |
| 116 | + dev = alloc_netdev(sizeof(*priv), "net%d", NET_NAME_UNKNOWN, my_setup); | |
| 117 | + if (!dev) | |
| 118 | + return -ENOMEM; | |
| 119 | + priv = netdev_priv(dev); | |
| 120 | + | |
| 121 | + /* Implicit constructor */ | |
| 122 | + err = some_init(priv); | |
| 123 | + if (err) | |
| 124 | + goto err_free_dev; | |
| 125 | + | |
| 126 | + priv->obj = some_obj_create(); | |
| 127 | + if (!priv->obj) { | |
| 128 | + err = -ENOMEM; | |
| 129 | + goto err_some_uninit; | |
| 130 | + } | |
| 131 | + /* End of constructor, set the destructor: */ | |
| 132 | + dev->priv_destructor = my_destructor; | |
| 133 | + | |
| 134 | + err = register_netdevice(dev); | |
| 135 | + if (err) | |
| 136 | + /* register_netdevice() calls destructor on failure */ | |
| 137 | + goto err_free_dev; | |
| 138 | + | |
| 139 | + /* If anything fails now unregister_netdevice() (or unregister_netdev()) | |
| 140 | + * will take care of calling my_destructor and free_netdev(). | |
| 141 | + */ | |
| 142 | + | |
| 143 | + return 0; | |
| 144 | + | |
| 145 | + err_some_uninit: | |
| 146 | + some_uninit(priv); | |
| 147 | + err_free_dev: | |
| 148 | + free_netdev(dev); | |
| 149 | + return err; | |
| 150 | + } | |
| 151 | + | |
| 152 | +If struct net_device.priv_destructor is set it will be called by the core | |
| 153 | +some time after unregister_netdevice(), it will also be called if | |
| 154 | +register_netdevice() fails. The callback may be invoked with or without | |
| 155 | +``rtnl_lock`` held. | |
| 156 | + | |
| 157 | +There is no explicit constructor callback, driver "constructs" the private | |
| 158 | +netdev state after allocating it and before registration. | |
| 159 | + | |
| 160 | +Setting struct net_device.needs_free_netdev makes core call free_netdevice() | |
| 161 | +automatically after unregister_netdevice() when all references to the device | |
| 162 | +are gone. It only takes effect after a successful call to register_netdevice() | |
| 163 | +so if register_netdevice() fails driver is responsible for calling | |
| 164 | +free_netdev(). | |
| 165 | + | |
| 166 | +free_netdev() is safe to call on error paths right after unregister_netdevice() | |
| 167 | +or when register_netdevice() fails. Parts of netdev (de)registration process | |
| 168 | +happen after ``rtnl_lock`` is released, therefore in those cases free_netdev() | |
| 169 | +will defer some of the processing until ``rtnl_lock`` is released. | |
| 170 | + | |
| 171 | +Devices spawned from struct rtnl_link_ops should never free the | |
| 172 | +struct net_device directly. | |
| 173 | + | |
| 174 | +.ndo_init and .ndo_uninit | |
| 175 | +~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 176 | + | |
| 177 | +``.ndo_init`` and ``.ndo_uninit`` callbacks are called during net_device | |
| 178 | +registration and de-registration, under ``rtnl_lock``. Drivers can use | |
| 179 | +those e.g. when parts of their init process need to run under ``rtnl_lock``. | |
| 180 | + | |
| 181 | +``.ndo_init`` runs before device is visible in the system, ``.ndo_uninit`` | |
| 182 | +runs during de-registering after device is closed but other subsystems | |
| 183 | +may still have outstanding references to the netdevice. | |
| 25 | 184 | |
| 26 | 185 | MTU |
| 27 | 186 | === |
| @@ -64,8 +223,8 @@ ndo_do_ioctl: · 36 unmodified lines | ||
| 64 | 223 | Context: process |
| 65 | 224 | |
| 66 | 225 | ndo_get_stats: |
| 67 | − Synchronization: dev_base_lock rwlock. | |
| 68 | − Context: nominally process, but don't sleep inside an rwlock | |
| 226 | + Synchronization: rtnl_lock() semaphore, dev_base_lock rwlock, or RCU. | |
| 227 | + Context: atomic (can't sleep under rwlock or RCU) | |
| 69 | 228 | |
| 70 | 229 | ndo_start_xmit: |
| 71 | 230 | Synchronization: __netif_tx_lock spinlock. |
| @@ -8,7 +8,7 @@ Abstract · 7 unmodified lines | ||
| 8 | 8 | ======== |
| 9 | 9 | |
| 10 | 10 | This file documents the mmap() facility available with the PACKET |
| 11 | −socket interface on 2.4/2.6/3.x kernels. This type of sockets is used for | |
| 11 | +socket interface. This type of sockets is used for | |
| 12 | 12 | |
| 13 | 13 | i) capture network traffic with utilities like tcpdump, |
| 14 | 14 | ii) transmit network traffic, or any other that needs raw |
| @@ -25,12 +25,12 @@ Please send your comments to · 10 unmodified lines | ||
| 25 | 25 | Why use PACKET_MMAP |
| 26 | 26 | =================== |
| 27 | 27 | |
| 28 | −In Linux 2.4/2.6/3.x if PACKET_MMAP is not enabled, the capture process is very | |
| 28 | +Non PACKET_MMAP capture process (plain AF_PACKET) is very | |
| 29 | 29 | inefficient. It uses very limited buffers and requires one system call to |
| 30 | 30 | capture each packet, it requires two if you want to get packet's timestamp |
| 31 | 31 | (like libpcap always does). |
| 32 | 32 | |
| 33 | −In the other hand PACKET_MMAP is very efficient. PACKET_MMAP provides a size | |
| 33 | +On the other hand PACKET_MMAP is very efficient. PACKET_MMAP provides a size | |
| 34 | 34 | configurable circular buffer mapped in user space that can be used to either |
| 35 | 35 | send or receive packets. This way reading packets just needs to wait for them, |
| 36 | 36 | most of the time there is no need to issue a single system call. Concerning |
| @@ -252,8 +252,7 @@ PACKET_MMAP setting constraints · 215 unmodified lines | ||
| 252 | 252 | |
| 253 | 253 | In kernel versions prior to 2.4.26 (for the 2.4 branch) and 2.6.5 (2.6 branch), |
| 254 | 254 | the PACKET_MMAP buffer could hold only 32768 frames in a 32 bit architecture or |
| 255 | −16384 in a 64 bit architecture. For information on these kernel versions | |
| 256 | −see http://pusa.uv.es/~ulisses/packet_mmap/packet_mmap.pre-2.4.26_2.6.5.txt | |
| 255 | +16384 in a 64 bit architecture. | |
| 257 | 256 | |
| 258 | 257 | Block size limit |
| 259 | 258 | ---------------- |
| @@ -437,7 +436,7 @@ and the following flags apply: · 177 unmodified lines | ||
| 437 | 436 | Capture process |
| 438 | 437 | ^^^^^^^^^^^^^^^ |
| 439 | 438 | |
| 440 | − from include/linux/if_packet.h | |
| 439 | +From include/linux/if_packet.h:: | |
| 441 | 440 | |
| 442 | 441 | #define TP_STATUS_COPY (1 << 1) |
| 443 | 442 | #define TP_STATUS_LOSING (1 << 2) |
| @@ -530,7 +530,7 @@ TLS device feature flags only control adding of new TLS connection · 529 unmodified lines | ||
| 530 | 530 | offloads, old connections will remain active after flags are cleared. |
| 531 | 531 | |
| 532 | 532 | TLS encryption cannot be offloaded to devices without checksum calculation |
| 533 | −offload. Hence, TLS TX device feature flag requires NETIF_F_HW_CSUM being set. | |
| 533 | +offload. Hence, TLS TX device feature flag requires TX csum offload being set. | |
| 534 | 534 | Disabling the latter implies clearing the former. Disabling TX checksum offload |
| 535 | 535 | should not affect old connections, and drivers should make sure checksum |
| 536 | 536 | calculation does not break for them. |
| @@ -249,10 +249,8 @@ features; most of these are found in the "kernel hacking" submenu. Several · 248 unmodified lines | ||
| 249 | 249 | of these options should be turned on for any kernel used for development or |
| 250 | 250 | testing purposes. In particular, you should turn on: |
| 251 | 251 | |
| 252 | − - ENABLE_MUST_CHECK and FRAME_WARN to get an | |
| 253 | − extra set of warnings for problems like the use of deprecated interfaces | |
| 254 | − or ignoring an important return value from a function. The output | |
| 255 | − generated by these warnings can be verbose, but one need not worry about | |
| 252 | + - FRAME_WARN to get warnings for stack frames larger than a given amount. | |
| 253 | + The output generated can be verbose, but one need not worry about | |
| 256 | 254 | warnings from other parts of the kernel. |
| 257 | 255 | |
| 258 | 256 | - DEBUG_OBJECTS will add code to track the lifetime of various objects |
| @@ -1501,7 +1501,7 @@ Module for Digigram miXart8 sound cards. · 1500 unmodified lines | ||
| 1501 | 1501 | |
| 1502 | 1502 | This module supports multiple cards. |
| 1503 | 1503 | Note: One miXart8 board will be represented as 4 alsa cards. |
| 1504 | −See MIXART.txt for details. | |
| 1504 | +See Documentation/sound/cards/mixart.rst for details. | |
| 1505 | 1505 | |
| 1506 | 1506 | When the driver is compiled as a module and the hotplug firmware |
| 1507 | 1507 | is supported, the firmware data is loaded via hotplug automatically. |
| @@ -71,7 +71,7 @@ core/oss · 70 unmodified lines | ||
| 71 | 71 | The codes for PCM and mixer OSS emulation modules are stored in this |
| 72 | 72 | directory. The rawmidi OSS emulation is included in the ALSA rawmidi |
| 73 | 73 | code since it's quite small. The sequencer code is stored in |
| 74 | −``core/seq/oss`` directory (see `below <#core-seq-oss>`__). | |
| 74 | +``core/seq/oss`` directory (see `below <core/seq/oss_>`__). | |
| 75 | 75 | |
| 76 | 76 | core/seq |
| 77 | 77 | ~~~~~~~~ |
| @@ -382,7 +382,7 @@ where ``enable[dev]`` is the module option. · 304 unmodified lines | ||
| 382 | 382 | Each time the ``probe`` callback is called, check the availability of |
| 383 | 383 | the device. If not available, simply increment the device index and |
| 384 | 384 | returns. dev will be incremented also later (`step 7 |
| 385 | −<#set-the-pci-driver-data-and-return-zero>`__). | |
| 385 | +<7) Set the PCI driver data and return zero._>`__). | |
| 386 | 386 | |
| 387 | 387 | 2) Create a card instance |
| 388 | 388 | ~~~~~~~~~~~~~~~~~~~~~~~~~ |
| @@ -450,10 +450,10 @@ field contains the information shown in ``/proc/asound/cards``. · 61 unmodified lines | ||
| 450 | 450 | 5) Create other components, such as mixer, MIDI, etc. |
| 451 | 451 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 452 | 452 | |
| 453 | −Here you define the basic components such as `PCM <#PCM-Interface>`__, | |
| 454 | −mixer (e.g. `AC97 <#API-for-AC97-Codec>`__), MIDI (e.g. | |
| 455 | −`MPU-401 <#MIDI-MPU401-UART-Interface>`__), and other interfaces. | |
| 456 | −Also, if you want a `proc file <#Proc-Interface>`__, define it here, | |
| 453 | +Here you define the basic components such as `PCM <PCM Interface_>`__, | |
| 454 | +mixer (e.g. `AC97 <API for AC97 Codec_>`__), MIDI (e.g. | |
| 455 | +`MPU-401 <MIDI (MPU401-UART) Interface_>`__), and other interfaces. | |
| 456 | +Also, if you want a `proc file <Proc Interface_>`__, define it here, | |
| 457 | 457 | too. |
| 458 | 458 | |
| 459 | 459 | 6) Register the card instance. |
| @@ -941,7 +941,7 @@ The allocation of an interrupt source is done like this: · 481 unmodified lines | ||
| 941 | 941 | chip->irq = pci->irq; |
| 942 | 942 | |
| 943 | 943 | where :c:func:`snd_mychip_interrupt()` is the interrupt handler |
| 944 | −defined `later <#pcm-interface-interrupt-handler>`__. Note that | |
| 944 | +defined `later <PCM Interrupt Handler_>`__. Note that | |
| 945 | 945 | ``chip->irq`` should be defined only when :c:func:`request_irq()` |
| 946 | 946 | succeeded. |
| 947 | 947 | |
| @@ -3104,7 +3104,7 @@ processing the output stream in the irq handler. · 2156 unmodified lines | ||
| 3104 | 3104 | |
| 3105 | 3105 | If the MPU-401 interface shares its interrupt with the other logical |
| 3106 | 3106 | devices on the card, set ``MPU401_INFO_IRQ_HOOK`` (see |
| 3107 | −`below <#MIDI-Interrupt-Handler>`__). | |
| 3107 | +`below <MIDI Interrupt Handler_>`__). | |
| 3108 | 3108 | |
| 3109 | 3109 | Usually, the port address corresponds to the command port and port + 1 |
| 3110 | 3110 | corresponds to the data port. If not, you may change the ``cport`` |
| @@ -392,9 +392,14 @@ This ioctl is obsolete and has been removed. · 391 unmodified lines | ||
| 392 | 392 | |
| 393 | 393 | Errors: |
| 394 | 394 | |
| 395 | − ===== ============================= | |
| 395 | + ======= ============================================================== | |
| 396 | 396 | EINTR an unmasked signal is pending |
| 397 | − ===== ============================= | |
| 397 | + ENOEXEC the vcpu hasn't been initialized or the guest tried to execute | |
| 398 | + instructions from device memory (arm64) | |
| 399 | + ENOSYS data abort outside memslots with no syndrome info and | |
| 400 | + KVM_CAP_ARM_NISV_TO_USER not enabled (arm64) | |
| 401 | + EPERM SVE feature set but not finalized (arm64) | |
| 402 | + ======= ============================================================== | |
| 398 | 403 | |
| 399 | 404 | This ioctl is used to run a guest virtual cpu. While there are no |
| 400 | 405 | explicit parameters, there is an implicit parameter block that can be |
| @@ -203,8 +203,8 @@ F: include/uapi/linux/nl80211.h · 202 unmodified lines | ||
| 203 | 203 | F: net/wireless/ |
| 204 | 204 | |
| 205 | 205 | 8169 10/100/1000 GIGABIT ETHERNET DRIVER |
| 206 | −M: Realtek linux nic maintainers <nic_swsd@realtek.com> | |
| 207 | 206 | M: Heiner Kallweit <hkallweit1@gmail.com> |
| 207 | +M: nic_swsd@realtek.com | |
| 208 | 208 | L: netdev@vger.kernel.org |
| 209 | 209 | S: Maintained |
| 210 | 210 | F: drivers/net/ethernet/realtek/r8169* |
| @@ -820,7 +820,6 @@ M: Netanel Belgazal <netanel@amazon.com> · 609 unmodified lines | ||
| 820 | 820 | M: Arthur Kiyanovski <akiyano@amazon.com> |
| 821 | 821 | R: Guy Tzalik <gtzalik@amazon.com> |
| 822 | 822 | R: Saeed Bishara <saeedb@amazon.com> |
| 823 | −R: Zorik Machulsky <zorik@amazon.com> | |
| 824 | 823 | L: netdev@vger.kernel.org |
| 825 | 824 | S: Supported |
| 826 | 825 | F: Documentation/networking/device_drivers/ethernet/amazon/ena.rst |
| @@ -907,7 +906,7 @@ AMD KFD · 80 unmodified lines | ||
| 907 | 906 | M: Felix Kuehling <Felix.Kuehling@amd.com> |
| 908 | 907 | L: amd-gfx@lists.freedesktop.org |
| 909 | 908 | S: Supported |
| 910 | −T: git git://people.freedesktop.org/~agd5f/linux | |
| 909 | +T: git https://gitlab.freedesktop.org/agd5f/linux.git | |
| 911 | 910 | F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd*.[ch] |
| 912 | 911 | F: drivers/gpu/drm/amd/amdkfd/ |
| 913 | 912 | F: drivers/gpu/drm/amd/include/cik_structs.h |
| @@ -2119,7 +2118,7 @@ N: atmel · 1205 unmodified lines | ||
| 2119 | 2118 | ARM/Microchip Sparx5 SoC support |
| 2120 | 2119 | M: Lars Povlsen <lars.povlsen@microchip.com> |
| 2121 | 2120 | M: Steen Hegelund <Steen.Hegelund@microchip.com> |
| 2122 | −M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | |
| 2121 | +M: UNGLinuxDriver@microchip.com | |
| 2123 | 2122 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 2124 | 2123 | S: Supported |
| 2125 | 2124 | T: git git://github.com/microchip-ung/linux-upstream.git |
| @@ -2942,7 +2941,6 @@ S: Maintained · 816 unmodified lines | ||
| 2942 | 2941 | F: drivers/hwmon/asus_atk0110.c |
| 2943 | 2942 | |
| 2944 | 2943 | ATLX ETHERNET DRIVERS |
| 2945 | −M: Jay Cliburn <jcliburn@gmail.com> | |
| 2946 | 2944 | M: Chris Snook <chris.snook@gmail.com> |
| 2947 | 2945 | L: netdev@vger.kernel.org |
| 2948 | 2946 | S: Maintained |
| @@ -3556,7 +3554,7 @@ S: Supported · 607 unmodified lines | ||
| 3556 | 3554 | F: drivers/net/ethernet/broadcom/bnxt/ |
| 3557 | 3555 | |
| 3558 | 3556 | BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER |
| 3559 | −M: Arend van Spriel <arend.vanspriel@broadcom.com> | |
| 3557 | +M: Arend van Spriel <aspriel@gmail.com> | |
| 3560 | 3558 | M: Franky Lin <franky.lin@broadcom.com> |
| 3561 | 3559 | M: Hante Meuleman <hante.meuleman@broadcom.com> |
| 3562 | 3560 | M: Chi-hsien Lin <chi-hsien.lin@infineon.com> |
| @@ -3883,7 +3881,7 @@ F: drivers/mtd/nand/raw/cadence-nand-controller.c · 320 unmodified lines | ||
| 3883 | 3881 | CADENCE USB3 DRD IP DRIVER |
| 3884 | 3882 | M: Peter Chen <peter.chen@nxp.com> |
| 3885 | 3883 | M: Pawel Laszczak <pawell@cadence.com> |
| 3886 | −M: Roger Quadros <rogerq@ti.com> | |
| 3884 | +R: Roger Quadros <rogerq@kernel.org> | |
| 3887 | 3885 | R: Aswath Govindraju <a-govindraju@ti.com> |
| 3888 | 3886 | L: linux-usb@vger.kernel.org |
| 3889 | 3887 | S: Maintained |
| @@ -3961,7 +3959,7 @@ F: net/can/ · 71 unmodified lines | ||
| 3961 | 3959 | CAN-J1939 NETWORK LAYER |
| 3962 | 3960 | M: Robin van der Gracht <robin@protonic.nl> |
| 3963 | 3961 | M: Oleksij Rempel <o.rempel@pengutronix.de> |
| 3964 | −R: Pengutronix Kernel Team <kernel@pengutronix.de> | |
| 3962 | +R: kernel@pengutronix.de | |
| 3965 | 3963 | L: linux-can@vger.kernel.org |
| 3966 | 3964 | S: Maintained |
| 3967 | 3965 | F: Documentation/networking/j1939.rst |
| @@ -4588,7 +4586,7 @@ B: https://bugzilla.kernel.org · 620 unmodified lines | ||
| 4588 | 4586 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git |
| 4589 | 4587 | F: Documentation/admin-guide/pm/cpuidle.rst |
| 4590 | 4588 | F: Documentation/driver-api/pm/cpuidle.rst |
| 4591 | −F: drivers/cpuidle/* | |
| 4589 | +F: drivers/cpuidle/ | |
| 4592 | 4590 | F: include/linux/cpuidle.h |
| 4593 | 4591 | |
| 4594 | 4592 | CPU POWER MONITORING SUBSYSTEM |
| @@ -4922,9 +4920,8 @@ F: Documentation/scsi/dc395x.rst · 327 unmodified lines | ||
| 4922 | 4920 | F: drivers/scsi/dc395x.* |
| 4923 | 4921 | |
| 4924 | 4922 | DCCP PROTOCOL |
| 4925 | −M: Gerrit Renker <gerrit@erg.abdn.ac.uk> | |
| 4926 | 4923 | L: dccp@vger.kernel.org |
| 4927 | −S: Maintained | |
| 4924 | +S: Orphan | |
| 4928 | 4925 | W: http://www.linuxfoundation.org/collaborate/workgroups/networking/dccp |
| 4929 | 4926 | F: include/linux/dccp.h |
| 4930 | 4927 | F: include/linux/tfrc.h |
| @@ -7363,7 +7360,6 @@ L: linux-hardening@vger.kernel.org · 2432 unmodified lines | ||
| 7363 | 7360 | S: Maintained |
| 7364 | 7361 | F: Documentation/kbuild/gcc-plugins.rst |
| 7365 | 7362 | F: scripts/Makefile.gcc-plugins |
| 7366 | −F: scripts/gcc-plugin.sh | |
| 7367 | 7363 | F: scripts/gcc-plugins/ |
| 7368 | 7364 | |
| 7369 | 7365 | GCOV BASED KERNEL PROFILING |
| @@ -9240,7 +9236,7 @@ F: tools/testing/selftests/sgx/* · 1870 unmodified lines | ||
| 9240 | 9236 | K: \bSGX_ |
| 9241 | 9237 | |
| 9242 | 9238 | INTERCONNECT API |
| 9243 | −M: Georgi Djakov <georgi.djakov@linaro.org> | |
| 9239 | +M: Georgi Djakov <djakov@kernel.org> | |
| 9244 | 9240 | L: linux-pm@vger.kernel.org |
| 9245 | 9241 | S: Maintained |
| 9246 | 9242 | F: Documentation/devicetree/bindings/interconnect/ |
| @@ -9273,7 +9269,7 @@ F: drivers/net/ethernet/sgi/ioc3-eth.c · 26 unmodified lines | ||
| 9273 | 9269 | |
| 9274 | 9270 | IOMAP FILESYSTEM LIBRARY |
| 9275 | 9271 | M: Christoph Hellwig <hch@infradead.org> |
| 9276 | −M: Darrick J. Wong <darrick.wong@oracle.com> | |
| 9272 | +M: Darrick J. Wong <djwong@kernel.org> | |
| 9277 | 9273 | M: linux-xfs@vger.kernel.org |
| 9278 | 9274 | M: linux-fsdevel@vger.kernel.org |
| 9279 | 9275 | L: linux-xfs@vger.kernel.org |
| @@ -9327,7 +9323,6 @@ W: http://www.adaptec.com/ · 47 unmodified lines | ||
| 9327 | 9323 | F: drivers/scsi/ips* |
| 9328 | 9324 | |
| 9329 | 9325 | IPVS |
| 9330 | −M: Wensong Zhang <wensong@linux-vs.org> | |
| 9331 | 9326 | M: Simon Horman <horms@verge.net.au> |
| 9332 | 9327 | M: Julian Anastasov <ja@ssi.bg> |
| 9333 | 9328 | L: netdev@vger.kernel.org |
| @@ -9776,7 +9771,7 @@ F: tools/testing/selftests/kvm/s390x/ · 442 unmodified lines | ||
| 9776 | 9771 | |
| 9777 | 9772 | KERNEL VIRTUAL MACHINE FOR X86 (KVM/x86) |
| 9778 | 9773 | M: Paolo Bonzini <pbonzini@redhat.com> |
| 9779 | −R: Sean Christopherson <sean.j.christopherson@intel.com> | |
| 9774 | +R: Sean Christopherson <seanjc@google.com> | |
| 9780 | 9775 | R: Vitaly Kuznetsov <vkuznets@redhat.com> |
| 9781 | 9776 | R: Wanpeng Li <wanpengli@tencent.com> |
| 9782 | 9777 | R: Jim Mattson <jmattson@google.com> |
| @@ -10260,7 +10255,6 @@ S: Supported · 477 unmodified lines | ||
| 10260 | 10255 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev |
| 10261 | 10256 | F: Documentation/atomic_bitops.txt |
| 10262 | 10257 | F: Documentation/atomic_t.txt |
| 10263 | −F: Documentation/core-api/atomic_ops.rst | |
| 10264 | 10258 | F: Documentation/core-api/refcount-vs-atomic.rst |
| 10265 | 10259 | F: Documentation/litmus-tests/ |
| 10266 | 10260 | F: Documentation/memory-barriers.txt |
| @@ -10847,7 +10841,7 @@ F: drivers/media/radio/radio-maxiradio* · 580 unmodified lines | ||
| 10847 | 10841 | |
| 10848 | 10842 | MCAN MMIO DEVICE DRIVER |
| 10849 | 10843 | M: Dan Murphy <dmurphy@ti.com> |
| 10850 | −M: Sriram Dash <sriram.dash@samsung.com> | |
| 10844 | +M: Pankaj Sharma <pankj.sharma@samsung.com> | |
| 10851 | 10845 | L: linux-can@vger.kernel.org |
| 10852 | 10846 | S: Maintained |
| 10853 | 10847 | F: Documentation/devicetree/bindings/net/can/bosch,m_can.yaml |
| @@ -11667,7 +11661,7 @@ F: drivers/media/platform/atmel/atmel-isi.h · 813 unmodified lines | ||
| 11667 | 11661 | |
| 11668 | 11662 | MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER |
| 11669 | 11663 | M: Woojung Huh <woojung.huh@microchip.com> |
| 11670 | −M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | |
| 11664 | +M: UNGLinuxDriver@microchip.com | |
| 11671 | 11665 | L: netdev@vger.kernel.org |
| 11672 | 11666 | S: Maintained |
| 11673 | 11667 | F: Documentation/devicetree/bindings/net/dsa/microchip,ksz.yaml |
| @@ -11677,7 +11671,7 @@ F: net/dsa/tag_ksz.c · 3 unmodified lines | ||
| 11677 | 11671 | |
| 11678 | 11672 | MICROCHIP LAN743X ETHERNET DRIVER |
| 11679 | 11673 | M: Bryan Whitehead <bryan.whitehead@microchip.com> |
| 11680 | −M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | |
| 11674 | +M: UNGLinuxDriver@microchip.com | |
| 11681 | 11675 | L: netdev@vger.kernel.org |
| 11682 | 11676 | S: Maintained |
| 11683 | 11677 | F: drivers/net/ethernet/microchip/lan743x_* |
| @@ -11771,7 +11765,7 @@ F: drivers/net/wireless/microchip/wilc1000/ · 87 unmodified lines | ||
| 11771 | 11765 | |
| 11772 | 11766 | MICROSEMI MIPS SOCS |
| 11773 | 11767 | M: Alexandre Belloni <alexandre.belloni@bootlin.com> |
| 11774 | −M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | |
| 11768 | +M: UNGLinuxDriver@microchip.com | |
| 11775 | 11769 | L: linux-mips@vger.kernel.org |
| 11776 | 11770 | S: Supported |
| 11777 | 11771 | F: Documentation/devicetree/bindings/mips/mscc.txt |
| @@ -12418,7 +12412,6 @@ F: tools/testing/selftests/net/ipsec.c · 640 unmodified lines | ||
| 12418 | 12412 | |
| 12419 | 12413 | NETWORKING [IPv4/IPv6] |
| 12420 | 12414 | M: "David S. Miller" <davem@davemloft.net> |
| 12421 | −M: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> | |
| 12422 | 12415 | M: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> |
| 12423 | 12416 | L: netdev@vger.kernel.org |
| 12424 | 12417 | S: Maintained |
| @@ -12475,7 +12468,6 @@ F: net/ipv6/tcp*.c · 50 unmodified lines | ||
| 12475 | 12468 | |
| 12476 | 12469 | NETWORKING [TLS] |
| 12477 | 12470 | M: Boris Pismenny <borisp@nvidia.com> |
| 12478 | −M: Aviad Yehezkel <aviadye@nvidia.com> | |
| 12479 | 12471 | M: John Fastabend <john.fastabend@gmail.com> |
| 12480 | 12472 | M: Daniel Borkmann <daniel@iogearbox.net> |
| 12481 | 12473 | M: Jakub Kicinski <kuba@kernel.org> |
| @@ -12825,10 +12817,10 @@ F: tools/objtool/ · 343 unmodified lines | ||
| 12825 | 12817 | F: include/linux/objtool.h |
| 12826 | 12818 | |
| 12827 | 12819 | OCELOT ETHERNET SWITCH DRIVER |
| 12828 | −M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | |
| 12829 | 12820 | M: Vladimir Oltean <vladimir.oltean@nxp.com> |
| 12830 | 12821 | M: Claudiu Manoil <claudiu.manoil@nxp.com> |
| 12831 | 12822 | M: Alexandre Belloni <alexandre.belloni@bootlin.com> |
| 12823 | +M: UNGLinuxDriver@microchip.com | |
| 12832 | 12824 | L: netdev@vger.kernel.org |
| 12833 | 12825 | S: Supported |
| 12834 | 12826 | F: drivers/net/dsa/ocelot/* |
| @@ -12850,7 +12842,7 @@ F: include/misc/ocxl* · 15 unmodified lines | ||
| 12850 | 12842 | F: include/uapi/misc/ocxl.h |
| 12851 | 12843 | |
| 12852 | 12844 | OMAP AUDIO SUPPORT |
| 12853 | −M: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 12845 | +M: Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 12854 | 12846 | M: Jarkko Nikula <jarkko.nikula@bitmer.com> |
| 12855 | 12847 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 12856 | 12848 | L: linux-omap@vger.kernel.org |
| @@ -13890,7 +13882,7 @@ F: drivers/platform/x86/peaq-wmi.c · 1033 unmodified lines | ||
| 13890 | 13882 | |
| 13891 | 13883 | PENSANDO ETHERNET DRIVERS |
| 13892 | 13884 | M: Shannon Nelson <snelson@pensando.io> |
| 13893 | −M: Pensando Drivers <drivers@pensando.io> | |
| 13885 | +M: drivers@pensando.io | |
| 13894 | 13886 | L: netdev@vger.kernel.org |
| 13895 | 13887 | S: Supported |
| 13896 | 13888 | F: Documentation/networking/device_drivers/ethernet/pensando/ionic.rst |
| @@ -14669,7 +14661,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git · 772 unmodified lines | ||
| 14669 | 14661 | F: drivers/net/wireless/ath/ath11k/ |
| 14670 | 14662 | |
| 14671 | 14663 | QUALCOMM ATHEROS ATH9K WIRELESS DRIVER |
| 14672 | −M: QCA ath9k Development <ath9k-devel@qca.qualcomm.com> | |
| 14664 | +M: ath9k-devel@qca.qualcomm.com | |
| 14673 | 14665 | L: linux-wireless@vger.kernel.org |
| 14674 | 14666 | S: Supported |
| 14675 | 14667 | W: https://wireless.wiki.kernel.org/en/users/Drivers/ath9k |
| @@ -14820,7 +14812,7 @@ M: Alex Deucher <alexander.deucher@amd.com> · 144 unmodified lines | ||
| 14820 | 14812 | M: Christian König <christian.koenig@amd.com> |
| 14821 | 14813 | L: amd-gfx@lists.freedesktop.org |
| 14822 | 14814 | S: Supported |
| 14823 | −T: git git://people.freedesktop.org/~agd5f/linux | |
| 14815 | +T: git https://gitlab.freedesktop.org/agd5f/linux.git | |
| 14824 | 14816 | F: drivers/gpu/drm/amd/ |
| 14825 | 14817 | F: drivers/gpu/drm/radeon/ |
| 14826 | 14818 | F: include/uapi/drm/amdgpu_drm.h |
| @@ -16321,6 +16313,7 @@ M: Pekka Enberg <penberg@kernel.org> · 1494 unmodified lines | ||
| 16321 | 16313 | M: David Rientjes <rientjes@google.com> |
| 16322 | 16314 | M: Joonsoo Kim <iamjoonsoo.kim@lge.com> |
| 16323 | 16315 | M: Andrew Morton <akpm@linux-foundation.org> |
| 16316 | +M: Vlastimil Babka <vbabka@suse.cz> | |
| 16324 | 16317 | L: linux-mm@kvack.org |
| 16325 | 16318 | S: Maintained |
| 16326 | 16319 | F: include/linux/sl?b*.h |
| @@ -16710,6 +16703,8 @@ M: Samuel Thibault <samuel.thibault@ens-lyon.org> · 383 unmodified lines | ||
| 16710 | 16703 | L: speakup@linux-speakup.org |
| 16711 | 16704 | S: Odd Fixes |
| 16712 | 16705 | W: http://www.linux-speakup.org/ |
| 16706 | +W: https://github.com/linux-speakup/speakup | |
| 16707 | +B: https://github.com/linux-speakup/speakup/issues | |
| 16713 | 16708 | F: drivers/accessibility/speakup/ |
| 16714 | 16709 | |
| 16715 | 16710 | SPEAR CLOCK FRAMEWORK SUPPORT |
| @@ -17541,7 +17536,7 @@ F: arch/xtensa/ · 825 unmodified lines | ||
| 17541 | 17536 | F: drivers/irqchip/irq-xtensa-* |
| 17542 | 17537 | |
| 17543 | 17538 | TEXAS INSTRUMENTS ASoC DRIVERS |
| 17544 | −M: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 17539 | +M: Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 17545 | 17540 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 17546 | 17541 | S: Maintained |
| 17547 | 17542 | F: sound/soc/ti/ |
| @@ -17553,6 +17548,19 @@ S: Supported · 5 unmodified lines | ||
| 17553 | 17548 | F: Documentation/devicetree/bindings/iio/dac/ti,dac7612.txt |
| 17554 | 17549 | F: drivers/iio/dac/ti-dac7612.c |
| 17555 | 17550 | |
| 17551 | +TEXAS INSTRUMENTS DMA DRIVERS | |
| 17552 | +M: Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 17553 | +L: dmaengine@vger.kernel.org | |
| 17554 | +S: Maintained | |
| 17555 | +F: Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt | |
| 17556 | +F: Documentation/devicetree/bindings/dma/ti-edma.txt | |
| 17557 | +F: Documentation/devicetree/bindings/dma/ti/ | |
| 17558 | +F: drivers/dma/ti/ | |
| 17559 | +X: drivers/dma/ti/cppi41.c | |
| 17560 | +F: include/linux/dma/k3-udma-glue.h | |
| 17561 | +F: include/linux/dma/ti-cppi5.h | |
| 17562 | +F: include/linux/dma/k3-psil.h | |
| 17563 | + | |
| 17556 | 17564 | TEXAS INSTRUMENTS' SYSTEM CONTROL INTERFACE (TISCI) PROTOCOL DRIVER |
| 17557 | 17565 | M: Nishanth Menon <nm@ti.com> |
| 17558 | 17566 | M: Tero Kristo <t-kristo@ti.com> |
| @@ -17838,7 +17846,7 @@ F: Documentation/devicetree/bindings/net/nfc/trf7970a.txt · 279 unmodified lines | ||
| 17838 | 17846 | F: drivers/nfc/trf7970a.c |
| 17839 | 17847 | |
| 17840 | 17848 | TI TWL4030 SERIES SOC CODEC DRIVER |
| 17841 | −M: Peter Ujfalusi <peter.ujfalusi@ti.com> | |
| 17849 | +M: Peter Ujfalusi <peter.ujfalusi@gmail.com> | |
| 17842 | 17850 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 17843 | 17851 | S: Maintained |
| 17844 | 17852 | F: sound/soc/codecs/twl4030* |
| @@ -18370,7 +18378,7 @@ F: include/linux/usb/isp116x.h · 525 unmodified lines | ||
| 18370 | 18378 | |
| 18371 | 18379 | USB LAN78XX ETHERNET DRIVER |
| 18372 | 18380 | M: Woojung Huh <woojung.huh@microchip.com> |
| 18373 | −M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | |
| 18381 | +M: UNGLinuxDriver@microchip.com | |
| 18374 | 18382 | L: netdev@vger.kernel.org |
| 18375 | 18383 | S: Maintained |
| 18376 | 18384 | F: Documentation/devicetree/bindings/net/microchip,lan78xx.txt |
| @@ -18484,7 +18492,7 @@ F: drivers/net/usb/smsc75xx.* · 107 unmodified lines | ||
| 18484 | 18492 | |
| 18485 | 18493 | USB SMSC95XX ETHERNET DRIVER |
| 18486 | 18494 | M: Steve Glendinning <steve.glendinning@shawell.net> |
| 18487 | −M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | |
| 18495 | +M: UNGLinuxDriver@microchip.com | |
| 18488 | 18496 | L: netdev@vger.kernel.org |
| 18489 | 18497 | S: Maintained |
| 18490 | 18498 | F: drivers/net/usb/smsc95xx.* |
| @@ -19031,7 +19039,7 @@ F: drivers/input/mouse/vmmouse.h · 540 unmodified lines | ||
| 19031 | 19039 | |
| 19032 | 19040 | VMWARE VMXNET3 ETHERNET DRIVER |
| 19033 | 19041 | M: Ronak Doshi <doshir@vmware.com> |
| 19034 | −M: "VMware, Inc." <pv-drivers@vmware.com> | |
| 19042 | +M: pv-drivers@vmware.com | |
| 19035 | 19043 | L: netdev@vger.kernel.org |
| 19036 | 19044 | S: Maintained |
| 19037 | 19045 | F: drivers/net/vmxnet3/ |
| @@ -19058,7 +19066,6 @@ K: regulator_get_optional · 20 unmodified lines | ||
| 19058 | 19066 | |
| 19059 | 19067 | VRF |
| 19060 | 19068 | M: David Ahern <dsahern@kernel.org> |
| 19061 | −M: Shrijeet Mukherjee <shrijeet@gmail.com> | |
| 19062 | 19069 | L: netdev@vger.kernel.org |
| 19063 | 19070 | S: Maintained |
| 19064 | 19071 | F: Documentation/networking/vrf.rst |
| @@ -19505,7 +19512,7 @@ F: arch/x86/xen/*swiotlb* · 440 unmodified lines | ||
| 19505 | 19512 | F: drivers/xen/*swiotlb* |
| 19506 | 19513 | |
| 19507 | 19514 | XFS FILESYSTEM |
| 19508 | −M: Darrick J. Wong <darrick.wong@oracle.com> | |
| 19515 | +M: Darrick J. Wong <djwong@kernel.org> | |
| 19509 | 19516 | M: linux-xfs@vger.kernel.org |
| 19510 | 19517 | L: linux-xfs@vger.kernel.org |
| 19511 | 19518 | S: Supported |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 11 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc1 | |
| 5 | +EXTRAVERSION = -rc4 | |
| 6 | 6 | NAME = Kleptomaniac Octopus |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -1105,6 +1105,12 @@ config HAVE_ARCH_PFN_VALID · 1104 unmodified lines | ||
| 1105 | 1105 | config ARCH_SUPPORTS_DEBUG_PAGEALLOC |
| 1106 | 1106 | bool |
| 1107 | 1107 | |
| 1108 | +config ARCH_SPLIT_ARG64 | |
| 1109 | + bool | |
| 1110 | + help | |
| 1111 | + If a 32-bit architecture requires 64-bit arguments to be split into | |
| 1112 | + pairs of 32-bit arguments, select this option. | |
| 1113 | + | |
| 1108 | 1114 | source "kernel/gcov/Kconfig" |
| 1109 | 1115 | |
| 1110 | 1116 | source "scripts/gcc-plugins/Kconfig" |
| @@ -1 +0,0 @@ | ||
| 1 | −#include <asm-generic/local64.h> | |
| @@ -102,16 +102,22 @@ libs-y += arch/arc/lib/ $(LIBGCC) · 101 unmodified lines | ||
| 102 | 102 | |
| 103 | 103 | boot := arch/arc/boot |
| 104 | 104 | |
| 105 | −#default target for make without any arguments. | |
| 106 | −KBUILD_IMAGE := $(boot)/bootpImage | |
| 107 | − | |
| 108 | −all: bootpImage | |
| 109 | −bootpImage: vmlinux | |
| 110 | − | |
| 111 | −boot_targets += uImage uImage.bin uImage.gz | |
| 105 | +boot_targets := uImage.bin uImage.gz uImage.lzma | |
| 112 | 106 | |
| 107 | +PHONY += $(boot_targets) | |
| 113 | 108 | $(boot_targets): vmlinux |
| 114 | 109 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ |
| 115 | 110 | |
| 111 | +uimage-default-y := uImage.bin | |
| 112 | +uimage-default-$(CONFIG_KERNEL_GZIP) := uImage.gz | |
| 113 | +uimage-default-$(CONFIG_KERNEL_LZMA) := uImage.lzma | |
| 114 | + | |
| 115 | +PHONY += uImage | |
| 116 | +uImage: $(uimage-default-y) | |
| 117 | + @ln -sf $< $(boot)/uImage | |
| 118 | + @$(kecho) ' Image $(boot)/uImage is ready' | |
| 119 | + | |
| 120 | +CLEAN_FILES += $(boot)/uImage | |
| 121 | + | |
| 116 | 122 | archclean: |
| 117 | 123 | $(Q)$(MAKE) $(clean)=$(boot) |
| @@ -1,5 +1,4 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | −targets := vmlinux.bin vmlinux.bin.gz uImage | |
| 3 | 2 | |
| 4 | 3 | # uImage build relies on mkimage being availble on your host for ARC target |
| 5 | 4 | # You will need to build u-boot for ARC, rename mkimage to arc-elf32-mkimage |
| @@ -7,23 +6,18 @@ targets := vmlinux.bin vmlinux.bin.gz uImage · 1 unmodified line | ||
| 7 | 6 | |
| 8 | 7 | OBJCOPYFLAGS= -O binary -R .note -R .note.gnu.build-id -R .comment -S |
| 9 | 8 | |
| 10 | −LINUX_START_TEXT = $$(readelf -h vmlinux | \ | |
| 9 | +LINUX_START_TEXT = $$($(READELF) -h vmlinux | \ | |
| 11 | 10 | grep "Entry point address" | grep -o 0x.*) |
| 12 | 11 | |
| 13 | 12 | UIMAGE_LOADADDR = $(CONFIG_LINUX_LINK_BASE) |
| 14 | 13 | UIMAGE_ENTRYADDR = $(LINUX_START_TEXT) |
| 15 | 14 | |
| 16 | −suffix-y := bin | |
| 17 | −suffix-$(CONFIG_KERNEL_GZIP) := gz | |
| 18 | −suffix-$(CONFIG_KERNEL_LZMA) := lzma | |
| 19 | − | |
| 20 | −targets += uImage | |
| 15 | +targets += vmlinux.bin | |
| 16 | +targets += vmlinux.bin.gz | |
| 17 | +targets += vmlinux.bin.lzma | |
| 21 | 18 | targets += uImage.bin |
| 22 | 19 | targets += uImage.gz |
| 23 | 20 | targets += uImage.lzma |
| 24 | −extra-y += vmlinux.bin | |
| 25 | −extra-y += vmlinux.bin.gz | |
| 26 | −extra-y += vmlinux.bin.lzma | |
| 27 | 21 | |
| 28 | 22 | $(obj)/vmlinux.bin: vmlinux FORCE |
| 29 | 23 | $(call if_changed,objcopy) |
| @@ -42,7 +36,3 @@ $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz FORCE · 12 unmodified lines | ||
| 42 | 36 | |
| 43 | 37 | $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma FORCE |
| 44 | 38 | $(call if_changed,uimage,lzma) |
| 45 | − | |
| 46 | −$(obj)/uImage: $(obj)/uImage.$(suffix-y) | |
| 47 | − @ln -sf $(notdir $<) $@ | |
| 48 | − @echo ' Image $@ is ready' | |
| @@ -1,7 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | generic-y += extable.h |
| 3 | 3 | generic-y += kvm_para.h |
| 4 | −generic-y += local64.h | |
| 5 | 4 | generic-y += mcs_spinlock.h |
| 6 | 5 | generic-y += parport.h |
| 7 | 6 | generic-y += user.h |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #ifndef __ASSEMBLY__ |
| 11 | 11 | |
| 12 | 12 | #define clear_page(paddr) memset((paddr), 0, PAGE_SIZE) |
| 13 | +#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) | |
| 13 | 14 | #define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) |
| 14 | 15 | |
| 15 | 16 | struct vm_area_struct; |
| @@ -307,7 +307,7 @@ resume_user_mode_begin: · 306 unmodified lines | ||
| 307 | 307 | mov r0, sp ; pt_regs for arg to do_signal()/do_notify_resume() |
| 308 | 308 | |
| 309 | 309 | GET_CURR_THR_INFO_FLAGS r9 |
| 310 | − and.f 0, r9, TIF_SIGPENDING|TIF_NOTIFY_SIGNAL | |
| 310 | + and.f 0, r9, _TIF_SIGPENDING|_TIF_NOTIFY_SIGNAL | |
| 311 | 311 | bz .Lchk_notify_resume |
| 312 | 312 | |
| 313 | 313 | ; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs |
| @@ -7,6 +7,7 @@ menuconfig ARC_SOC_HSDK · 6 unmodified lines | ||
| 7 | 7 | depends on ISA_ARCV2 |
| 8 | 8 | select ARC_HAS_ACCL_REGS |
| 9 | 9 | select ARC_IRQ_NO_AUTOSAVE |
| 10 | + select ARC_FPU_SAVE_RESTORE | |
| 10 | 11 | select CLK_HSDK |
| 11 | 12 | select RESET_CONTROLLER |
| 12 | 13 | select RESET_HSDK |
| @@ -494,3 +494,11 @@ · 493 unmodified lines | ||
| 494 | 494 | clock-names = "sysclk"; |
| 495 | 495 | }; |
| 496 | 496 | }; |
| 497 | + | |
| 498 | +&aes1_target { | |
| 499 | + status = "disabled"; | |
| 500 | +}; | |
| 501 | + | |
| 502 | +&aes2_target { | |
| 503 | + status = "disabled"; | |
| 504 | +}; | |
| @@ -45,18 +45,21 @@ · 44 unmodified lines | ||
| 45 | 45 | emac: gem@30000 { |
| 46 | 46 | compatible = "cadence,gem"; |
| 47 | 47 | reg = <0x30000 0x10000>; |
| 48 | + interrupt-parent = <&vic0>; | |
| 48 | 49 | interrupts = <31>; |
| 49 | 50 | }; |
| 50 | 51 | |
| 51 | 52 | dmac1: dmac@40000 { |
| 52 | 53 | compatible = "snps,dw-dmac"; |
| 53 | 54 | reg = <0x40000 0x10000>; |
| 55 | + interrupt-parent = <&vic0>; | |
| 54 | 56 | interrupts = <25>; |
| 55 | 57 | }; |
| 56 | 58 | |
| 57 | 59 | dmac2: dmac@50000 { |
| 58 | 60 | compatible = "snps,dw-dmac"; |
| 59 | 61 | reg = <0x50000 0x10000>; |
| 62 | + interrupt-parent = <&vic0>; | |
| 60 | 63 | interrupts = <26>; |
| 61 | 64 | }; |
| 62 | 65 | |
| @@ -233,6 +236,7 @@ · 170 unmodified lines | ||
| 233 | 236 | axi2pico@c0000000 { |
| 234 | 237 | compatible = "picochip,axi2pico-pc3x2"; |
| 235 | 238 | reg = <0xc0000000 0x10000>; |
| 239 | + interrupt-parent = <&vic0>; | |
| 236 | 240 | interrupts = <13 14 15 16 17 18 19 20 21>; |
| 237 | 241 | }; |
| 238 | 242 | }; |
| @@ -329,6 +329,7 @@ · 328 unmodified lines | ||
| 329 | 329 | panel@0 { |
| 330 | 330 | compatible = "samsung,s6e63m0"; |
| 331 | 331 | reg = <0>; |
| 332 | + max-brightness = <15>; | |
| 332 | 333 | vdd3-supply = <&panel_reg_3v0>; |
| 333 | 334 | vci-supply = <&panel_reg_1v8>; |
| 334 | 335 | reset-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; |
| @@ -279,6 +279,7 @@ CONFIG_SERIAL_OMAP_CONSOLE=y · 278 unmodified lines | ||
| 279 | 279 | CONFIG_SERIAL_DEV_BUS=y |
| 280 | 280 | CONFIG_I2C_CHARDEV=y |
| 281 | 281 | CONFIG_SPI=y |
| 282 | +CONFIG_SPI_GPIO=m | |
| 282 | 283 | CONFIG_SPI_OMAP24XX=y |
| 283 | 284 | CONFIG_SPI_TI_QSPI=m |
| 284 | 285 | CONFIG_HSI=m |
| @@ -296,7 +297,6 @@ CONFIG_GPIO_TWL4030=y · 11 unmodified lines | ||
| 296 | 297 | CONFIG_W1=m |
| 297 | 298 | CONFIG_HDQ_MASTER_OMAP=m |
| 298 | 299 | CONFIG_W1_SLAVE_DS250X=m |
| 299 | −CONFIG_POWER_AVS=y | |
| 300 | 300 | CONFIG_POWER_RESET=y |
| 301 | 301 | CONFIG_POWER_RESET_GPIO=y |
| 302 | 302 | CONFIG_BATTERY_BQ27XXX=m |
| @@ -60,6 +60,7 @@ static void chacha_doneon(u32 *state, u8 *dst, const u8 *src, · 59 unmodified lines | ||
| 60 | 60 | chacha_block_xor_neon(state, d, s, nrounds); |
| 61 | 61 | if (d != dst) |
| 62 | 62 | memcpy(dst, buf, bytes); |
| 63 | + state[12]++; | |
| 63 | 64 | } |
| 64 | 65 | } |
| 65 | 66 | |
| @@ -2,7 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | generic-y += early_ioremap.h |
| 3 | 3 | generic-y += extable.h |
| 4 | 4 | generic-y += flat.h |
| 5 | −generic-y += local64.h | |
| 6 | 5 | generic-y += parport.h |
| 7 | 6 | |
| 8 | 7 | generated-y += mach-types.h |
| @@ -230,10 +230,12 @@ static int _omap_device_notifier_call(struct notifier_block *nb, · 229 unmodified lines | ||
| 230 | 230 | break; |
| 231 | 231 | case BUS_NOTIFY_BIND_DRIVER: |
| 232 | 232 | od = to_omap_device(pdev); |
| 233 | − if (od && (od->_state == OMAP_DEVICE_STATE_ENABLED) && | |
| 234 | − pm_runtime_status_suspended(dev)) { | |
| 233 | + if (od) { | |
| 235 | 234 | od->_driver_status = BUS_NOTIFY_BIND_DRIVER; |
| 236 | − pm_runtime_set_active(dev); | |
| 235 | + if (od->_state == OMAP_DEVICE_STATE_ENABLED && | |
| 236 | + pm_runtime_status_suspended(dev)) { | |
| 237 | + pm_runtime_set_active(dev); | |
| 238 | + } | |
| 237 | 239 | } |
| 238 | 240 | break; |
| 239 | 241 | case BUS_NOTIFY_ADD_DEVICE: |
| @@ -71,7 +71,7 @@ static struct omap_voltdm_pmic omap_cpcap_iva = { · 70 unmodified lines | ||
| 71 | 71 | .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN, |
| 72 | 72 | .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX, |
| 73 | 73 | .vddmin = 900000, |
| 74 | − .vddmax = 1350000, | |
| 74 | + .vddmax = 1375000, | |
| 75 | 75 | .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US, |
| 76 | 76 | .i2c_slave_addr = 0x44, |
| 77 | 77 | .volt_reg_addr = 0x0, |
| @@ -371,7 +371,7 @@ static int __init xen_guest_init(void) · 370 unmodified lines | ||
| 371 | 371 | } |
| 372 | 372 | gnttab_init(); |
| 373 | 373 | if (!xen_initial_domain()) |
| 374 | − xenbus_probe(NULL); | |
| 374 | + xenbus_probe(); | |
| 375 | 375 | |
| 376 | 376 | /* |
| 377 | 377 | * Making sure board specific code will not set up ops for |
| @@ -174,8 +174,6 @@ config ARM64 · 173 unmodified lines | ||
| 174 | 174 | select HAVE_NMI |
| 175 | 175 | select HAVE_PATA_PLATFORM |
| 176 | 176 | select HAVE_PERF_EVENTS |
| 177 | − select HAVE_PERF_EVENTS_NMI if ARM64_PSEUDO_NMI && HW_PERF_EVENTS | |
| 178 | − select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && HAVE_PERF_EVENTS_NMI | |
| 179 | 177 | select HAVE_PERF_REGS |
| 180 | 178 | select HAVE_PERF_USER_STACK_DUMP |
| 181 | 179 | select HAVE_REGS_AND_STACK_ACCESS_API |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | # |
| 11 | 11 | # Copyright (C) 1995-2001 by Russell King |
| 12 | 12 | |
| 13 | −LDFLAGS_vmlinux :=--no-undefined -X -z norelro | |
| 13 | +LDFLAGS_vmlinux :=--no-undefined -X | |
| 14 | 14 | |
| 15 | 15 | ifeq ($(CONFIG_RELOCATABLE), y) |
| 16 | 16 | # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour |
| @@ -115,16 +115,20 @@ KBUILD_CPPFLAGS += -mbig-endian · 98 unmodified lines | ||
| 115 | 115 | CHECKFLAGS += -D__AARCH64EB__ |
| 116 | 116 | # Prefer the baremetal ELF build target, but not all toolchains include |
| 117 | 117 | # it so fall back to the standard linux version if needed. |
| 118 | −KBUILD_LDFLAGS += -EB $(call ld-option, -maarch64elfb, -maarch64linuxb) | |
| 118 | +KBUILD_LDFLAGS += -EB $(call ld-option, -maarch64elfb, -maarch64linuxb -z norelro) | |
| 119 | 119 | UTS_MACHINE := aarch64_be |
| 120 | 120 | else |
| 121 | 121 | KBUILD_CPPFLAGS += -mlittle-endian |
| 122 | 122 | CHECKFLAGS += -D__AARCH64EL__ |
| 123 | 123 | # Same as above, prefer ELF but fall back to linux target if needed. |
| 124 | −KBUILD_LDFLAGS += -EL $(call ld-option, -maarch64elf, -maarch64linux) | |
| 124 | +KBUILD_LDFLAGS += -EL $(call ld-option, -maarch64elf, -maarch64linux -z norelro) | |
| 125 | 125 | UTS_MACHINE := aarch64 |
| 126 | 126 | endif |
| 127 | 127 | |
| 128 | +ifeq ($(CONFIG_LD_IS_LLD), y) | |
| 129 | +KBUILD_LDFLAGS += -z norelro | |
| 130 | +endif | |
| 131 | + | |
| 128 | 132 | CHECKFLAGS += -D__aarch64__ |
| 129 | 133 | |
| 130 | 134 | ifeq ($(CONFIG_DYNAMIC_FTRACE_WITH_REGS),y) |
| @@ -127,7 +127,7 @@ · 126 unmodified lines | ||
| 127 | 127 | compatible = "snps,dw-apb-gpio-port"; |
| 128 | 128 | gpio-controller; |
| 129 | 129 | #gpio-cells = <2>; |
| 130 | − snps,nr-gpios = <32>; | |
| 130 | + ngpios = <32>; | |
| 131 | 131 | reg = <0>; |
| 132 | 132 | interrupt-controller; |
| 133 | 133 | #interrupt-cells = <2>; |
| @@ -145,7 +145,7 @@ · 11 unmodified lines | ||
| 145 | 145 | compatible = "snps,dw-apb-gpio-port"; |
| 146 | 146 | gpio-controller; |
| 147 | 147 | #gpio-cells = <2>; |
| 148 | − snps,nr-gpios = <32>; | |
| 148 | + ngpios = <32>; | |
| 149 | 149 | reg = <0>; |
| 150 | 150 | interrupt-controller; |
| 151 | 151 | #interrupt-cells = <2>; |
| @@ -163,7 +163,7 @@ · 11 unmodified lines | ||
| 163 | 163 | compatible = "snps,dw-apb-gpio-port"; |
| 164 | 164 | gpio-controller; |
| 165 | 165 | #gpio-cells = <2>; |
| 166 | − snps,nr-gpios = <8>; | |
| 166 | + ngpios = <8>; | |
| 167 | 167 | reg = <0>; |
| 168 | 168 | interrupt-controller; |
| 169 | 169 | #interrupt-cells = <2>; |
| @@ -1,6 +1,5 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | generic-y += early_ioremap.h |
| 3 | −generic-y += local64.h | |
| 4 | 3 | generic-y += mcs_spinlock.h |
| 5 | 4 | generic-y += qrwlock.h |
| 6 | 5 | generic-y += qspinlock.h |
| @@ -17,7 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <asm/lse.h> |
| 18 | 18 | |
| 19 | 19 | #define ATOMIC_OP(op) \ |
| 20 | −static inline void arch_##op(int i, atomic_t *v) \ | |
| 20 | +static __always_inline void arch_##op(int i, atomic_t *v) \ | |
| 21 | 21 | { \ |
| 22 | 22 | __lse_ll_sc_body(op, i, v); \ |
| 23 | 23 | } |
| @@ -32,7 +32,7 @@ ATOMIC_OP(atomic_sub) · 8 unmodified lines | ||
| 32 | 32 | #undef ATOMIC_OP |
| 33 | 33 | |
| 34 | 34 | #define ATOMIC_FETCH_OP(name, op) \ |
| 35 | −static inline int arch_##op##name(int i, atomic_t *v) \ | |
| 35 | +static __always_inline int arch_##op##name(int i, atomic_t *v) \ | |
| 36 | 36 | { \ |
| 37 | 37 | return __lse_ll_sc_body(op##name, i, v); \ |
| 38 | 38 | } |
| @@ -56,7 +56,7 @@ ATOMIC_FETCH_OPS(atomic_sub_return) · 17 unmodified lines | ||
| 56 | 56 | #undef ATOMIC_FETCH_OPS |
| 57 | 57 | |
| 58 | 58 | #define ATOMIC64_OP(op) \ |
| 59 | −static inline void arch_##op(long i, atomic64_t *v) \ | |
| 59 | +static __always_inline void arch_##op(long i, atomic64_t *v) \ | |
| 60 | 60 | { \ |
| 61 | 61 | __lse_ll_sc_body(op, i, v); \ |
| 62 | 62 | } |
| @@ -71,7 +71,7 @@ ATOMIC64_OP(atomic64_sub) · 8 unmodified lines | ||
| 71 | 71 | #undef ATOMIC64_OP |
| 72 | 72 | |
| 73 | 73 | #define ATOMIC64_FETCH_OP(name, op) \ |
| 74 | −static inline long arch_##op##name(long i, atomic64_t *v) \ | |
| 74 | +static __always_inline long arch_##op##name(long i, atomic64_t *v) \ | |
| 75 | 75 | { \ |
| 76 | 76 | return __lse_ll_sc_body(op##name, i, v); \ |
| 77 | 77 | } |
| @@ -94,7 +94,7 @@ ATOMIC64_FETCH_OPS(atomic64_sub_return) · 16 unmodified lines | ||
| 94 | 94 | #undef ATOMIC64_FETCH_OP |
| 95 | 95 | #undef ATOMIC64_FETCH_OPS |
| 96 | 96 | |
| 97 | −static inline long arch_atomic64_dec_if_positive(atomic64_t *v) | |
| 97 | +static __always_inline long arch_atomic64_dec_if_positive(atomic64_t *v) | |
| 98 | 98 | { |
| 99 | 99 | return __lse_ll_sc_body(atomic64_dec_if_positive, v); |
| 100 | 100 | } |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/jump_label.h> |
| 18 | 18 | #include <linux/kvm_types.h> |
| 19 | 19 | #include <linux/percpu.h> |
| 20 | +#include <linux/psci.h> | |
| 20 | 21 | #include <asm/arch_gicv3.h> |
| 21 | 22 | #include <asm/barrier.h> |
| 22 | 23 | #include <asm/cpufeature.h> |
| @@ -240,6 +241,28 @@ struct kvm_host_data { · 217 unmodified lines | ||
| 240 | 241 | struct kvm_pmu_events pmu_events; |
| 241 | 242 | }; |
| 242 | 243 | |
| 244 | +struct kvm_host_psci_config { | |
| 245 | + /* PSCI version used by host. */ | |
| 246 | + u32 version; | |
| 247 | + | |
| 248 | + /* Function IDs used by host if version is v0.1. */ | |
| 249 | + struct psci_0_1_function_ids function_ids_0_1; | |
| 250 | + | |
| 251 | + bool psci_0_1_cpu_suspend_implemented; | |
| 252 | + bool psci_0_1_cpu_on_implemented; | |
| 253 | + bool psci_0_1_cpu_off_implemented; | |
| 254 | + bool psci_0_1_migrate_implemented; | |
| 255 | +}; | |
| 256 | + | |
| 257 | +extern struct kvm_host_psci_config kvm_nvhe_sym(kvm_host_psci_config); | |
| 258 | +#define kvm_host_psci_config CHOOSE_NVHE_SYM(kvm_host_psci_config) | |
| 259 | + | |
| 260 | +extern s64 kvm_nvhe_sym(hyp_physvirt_offset); | |
| 261 | +#define hyp_physvirt_offset CHOOSE_NVHE_SYM(hyp_physvirt_offset) | |
| 262 | + | |
| 263 | +extern u64 kvm_nvhe_sym(hyp_cpu_logical_map)[NR_CPUS]; | |
| 264 | +#define hyp_cpu_logical_map CHOOSE_NVHE_SYM(hyp_cpu_logical_map) | |
| 265 | + | |
| 243 | 266 | struct vcpu_reset_state { |
| 244 | 267 | unsigned long pc; |
| 245 | 268 | unsigned long r0; |
| @@ -176,10 +176,21 @@ static inline void __uaccess_enable_hw_pan(void) · 175 unmodified lines | ||
| 176 | 176 | * The Tag check override (TCO) bit disables temporarily the tag checking |
| 177 | 177 | * preventing the issue. |
| 178 | 178 | */ |
| 179 | −static inline void uaccess_disable_privileged(void) | |
| 179 | +static inline void __uaccess_disable_tco(void) | |
| 180 | 180 | { |
| 181 | 181 | asm volatile(ALTERNATIVE("nop", SET_PSTATE_TCO(0), |
| 182 | 182 | ARM64_MTE, CONFIG_KASAN_HW_TAGS)); |
| 183 | +} | |
| 184 | + | |
| 185 | +static inline void __uaccess_enable_tco(void) | |
| 186 | +{ | |
| 187 | + asm volatile(ALTERNATIVE("nop", SET_PSTATE_TCO(1), | |
| 188 | + ARM64_MTE, CONFIG_KASAN_HW_TAGS)); | |
| 189 | +} | |
| 190 | + | |
| 191 | +static inline void uaccess_disable_privileged(void) | |
| 192 | +{ | |
| 193 | + __uaccess_disable_tco(); | |
| 183 | 194 | |
| 184 | 195 | if (uaccess_ttbr0_disable()) |
| 185 | 196 | return; |
| @@ -189,8 +200,7 @@ static inline void uaccess_disable_privileged(void) · 3 unmodified lines | ||
| 189 | 200 | |
| 190 | 201 | static inline void uaccess_enable_privileged(void) |
| 191 | 202 | { |
| 192 | − asm volatile(ALTERNATIVE("nop", SET_PSTATE_TCO(1), | |
| 193 | − ARM64_MTE, CONFIG_KASAN_HW_TAGS)); | |
| 203 | + __uaccess_enable_tco(); | |
| 194 | 204 | |
| 195 | 205 | if (uaccess_ttbr0_enable()) |
| 196 | 206 | return; |
| @@ -75,7 +75,7 @@ int main(void) · 74 unmodified lines | ||
| 75 | 75 | DEFINE(S_SDEI_TTBR1, offsetof(struct pt_regs, sdei_ttbr1)); |
| 76 | 76 | DEFINE(S_PMR_SAVE, offsetof(struct pt_regs, pmr_save)); |
| 77 | 77 | DEFINE(S_STACKFRAME, offsetof(struct pt_regs, stackframe)); |
| 78 | − DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs)); | |
| 78 | + DEFINE(PT_REGS_SIZE, sizeof(struct pt_regs)); | |
| 79 | 79 | BLANK(); |
| 80 | 80 | #ifdef CONFIG_COMPAT |
| 81 | 81 | DEFINE(COMPAT_SIGFRAME_REGS_OFFSET, offsetof(struct compat_sigframe, uc.uc_mcontext.arm_r0)); |
| @@ -2568,7 +2568,7 @@ static void verify_hyp_capabilities(void) · 2567 unmodified lines | ||
| 2568 | 2568 | int parange, ipa_max; |
| 2569 | 2569 | unsigned int safe_vmid_bits, vmid_bits; |
| 2570 | 2570 | |
| 2571 | − if (!IS_ENABLED(CONFIG_KVM) || !IS_ENABLED(CONFIG_KVM_ARM_HOST)) | |
| 2571 | + if (!IS_ENABLED(CONFIG_KVM)) | |
| 2572 | 2572 | return; |
| 2573 | 2573 | |
| 2574 | 2574 | safe_mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1); |
| @@ -35,7 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | */ |
| 36 | 36 | .macro ftrace_regs_entry, allregs=0 |
| 37 | 37 | /* Make room for pt_regs, plus a callee frame */ |
| 38 | − sub sp, sp, #(S_FRAME_SIZE + 16) | |
| 38 | + sub sp, sp, #(PT_REGS_SIZE + 16) | |
| 39 | 39 | |
| 40 | 40 | /* Save function arguments (and x9 for simplicity) */ |
| 41 | 41 | stp x0, x1, [sp, #S_X0] |
| @@ -61,15 +61,15 @@ · 19 unmodified lines | ||
| 61 | 61 | .endif |
| 62 | 62 | |
| 63 | 63 | /* Save the callsite's SP and LR */ |
| 64 | − add x10, sp, #(S_FRAME_SIZE + 16) | |
| 64 | + add x10, sp, #(PT_REGS_SIZE + 16) | |
| 65 | 65 | stp x9, x10, [sp, #S_LR] |
| 66 | 66 | |
| 67 | 67 | /* Save the PC after the ftrace callsite */ |
| 68 | 68 | str x30, [sp, #S_PC] |
| 69 | 69 | |
| 70 | 70 | /* Create a frame record for the callsite above pt_regs */ |
| 71 | − stp x29, x9, [sp, #S_FRAME_SIZE] | |
| 72 | − add x29, sp, #S_FRAME_SIZE | |
| 71 | + stp x29, x9, [sp, #PT_REGS_SIZE] | |
| 72 | + add x29, sp, #PT_REGS_SIZE | |
| 73 | 73 | |
| 74 | 74 | /* Create our frame record within pt_regs. */ |
| 75 | 75 | stp x29, x30, [sp, #S_STACKFRAME] |
| @@ -120,7 +120,7 @@ ftrace_common_return: · 44 unmodified lines | ||
| 120 | 120 | ldr x9, [sp, #S_PC] |
| 121 | 121 | |
| 122 | 122 | /* Restore the callsite's SP */ |
| 123 | − add sp, sp, #S_FRAME_SIZE + 16 | |
| 123 | + add sp, sp, #PT_REGS_SIZE + 16 | |
| 124 | 124 | |
| 125 | 125 | ret x9 |
| 126 | 126 | SYM_CODE_END(ftrace_common) |
| @@ -130,7 +130,7 @@ SYM_CODE_START(ftrace_graph_caller) · 3 unmodified lines | ||
| 130 | 130 | ldr x0, [sp, #S_PC] |
| 131 | 131 | sub x0, x0, #AARCH64_INSN_SIZE // ip (callsite's BL insn) |
| 132 | 132 | add x1, sp, #S_LR // parent_ip (callsite's LR) |
| 133 | − ldr x2, [sp, #S_FRAME_SIZE] // parent fp (callsite's FP) | |
| 133 | + ldr x2, [sp, #PT_REGS_SIZE] // parent fp (callsite's FP) | |
| 134 | 134 | bl prepare_ftrace_return |
| 135 | 135 | b ftrace_common_return |
| 136 | 136 | SYM_CODE_END(ftrace_graph_caller) |
| @@ -75,7 +75,7 @@ alternative_else_nop_endif · 74 unmodified lines | ||
| 75 | 75 | .endif |
| 76 | 76 | #endif |
| 77 | 77 | |
| 78 | − sub sp, sp, #S_FRAME_SIZE | |
| 78 | + sub sp, sp, #PT_REGS_SIZE | |
| 79 | 79 | #ifdef CONFIG_VMAP_STACK |
| 80 | 80 | /* |
| 81 | 81 | * Test whether the SP has overflowed, without corrupting a GPR. |
| @@ -96,7 +96,7 @@ alternative_else_nop_endif · 14 unmodified lines | ||
| 96 | 96 | * userspace, and can clobber EL0 registers to free up GPRs. |
| 97 | 97 | */ |
| 98 | 98 | |
| 99 | − /* Stash the original SP (minus S_FRAME_SIZE) in tpidr_el0. */ | |
| 99 | + /* Stash the original SP (minus PT_REGS_SIZE) in tpidr_el0. */ | |
| 100 | 100 | msr tpidr_el0, x0 |
| 101 | 101 | |
| 102 | 102 | /* Recover the original x0 value and stash it in tpidrro_el0 */ |
| @@ -182,7 +182,6 @@ alternative_else_nop_endif · 79 unmodified lines | ||
| 182 | 182 | mrs_s \tmp2, SYS_GCR_EL1 |
| 183 | 183 | bfi \tmp2, \tmp, #0, #16 |
| 184 | 184 | msr_s SYS_GCR_EL1, \tmp2 |
| 185 | − isb | |
| 186 | 185 | #endif |
| 187 | 186 | .endm |
| 188 | 187 | |
| @@ -194,6 +193,7 @@ alternative_else_nop_endif · 5 unmodified lines | ||
| 194 | 193 | ldr_l \tmp, gcr_kernel_excl |
| 195 | 194 | |
| 196 | 195 | mte_set_gcr \tmp, \tmp2 |
| 196 | + isb | |
| 197 | 197 | 1: |
| 198 | 198 | #endif |
| 199 | 199 | .endm |
| @@ -253,7 +253,7 @@ alternative_else_nop_endif · 53 unmodified lines | ||
| 253 | 253 | |
| 254 | 254 | scs_load tsk, x20 |
| 255 | 255 | .else |
| 256 | − add x21, sp, #S_FRAME_SIZE | |
| 256 | + add x21, sp, #PT_REGS_SIZE | |
| 257 | 257 | get_current_task tsk |
| 258 | 258 | .endif /* \el == 0 */ |
| 259 | 259 | mrs x22, elr_el1 |
| @@ -377,7 +377,7 @@ alternative_else_nop_endif · 117 unmodified lines | ||
| 377 | 377 | ldp x26, x27, [sp, #16 * 13] |
| 378 | 378 | ldp x28, x29, [sp, #16 * 14] |
| 379 | 379 | ldr lr, [sp, #S_LR] |
| 380 | − add sp, sp, #S_FRAME_SIZE // restore sp | |
| 380 | + add sp, sp, #PT_REGS_SIZE // restore sp | |
| 381 | 381 | |
| 382 | 382 | .if \el == 0 |
| 383 | 383 | alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0 |
| @@ -580,12 +580,12 @@ __bad_stack: · 196 unmodified lines | ||
| 580 | 580 | |
| 581 | 581 | /* |
| 582 | 582 | * Store the original GPRs to the new stack. The orginal SP (minus |
| 583 | − * S_FRAME_SIZE) was stashed in tpidr_el0 by kernel_ventry. | |
| 583 | + * PT_REGS_SIZE) was stashed in tpidr_el0 by kernel_ventry. | |
| 584 | 584 | */ |
| 585 | − sub sp, sp, #S_FRAME_SIZE | |
| 585 | + sub sp, sp, #PT_REGS_SIZE | |
| 586 | 586 | kernel_entry 1 |
| 587 | 587 | mrs x0, tpidr_el0 |
| 588 | − add x0, x0, #S_FRAME_SIZE | |
| 588 | + add x0, x0, #PT_REGS_SIZE | |
| 589 | 589 | str x0, [sp, #S_SP] |
| 590 | 590 | |
| 591 | 591 | /* Stash the regs for handle_bad_stack */ |
| @@ -23,8 +23,6 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <linux/platform_device.h> |
| 24 | 24 | #include <linux/sched_clock.h> |
| 25 | 25 | #include <linux/smp.h> |
| 26 | −#include <linux/nmi.h> | |
| 27 | −#include <linux/cpufreq.h> | |
| 28 | 26 | |
| 29 | 27 | /* ARMv8 Cortex-A53 specific event types. */ |
| 30 | 28 | #define ARMV8_A53_PERFCTR_PREF_LINEFILL 0xC2 |
| @@ -1250,21 +1248,10 @@ static struct platform_driver armv8_pmu_driver = { · 1219 unmodified lines | ||
| 1250 | 1248 | |
| 1251 | 1249 | static int __init armv8_pmu_driver_init(void) |
| 1252 | 1250 | { |
| 1253 | − int ret; | |
| 1254 | − | |
| 1255 | 1251 | if (acpi_disabled) |
| 1256 | − ret = platform_driver_register(&armv8_pmu_driver); | |
| 1252 | + return platform_driver_register(&armv8_pmu_driver); | |
| 1257 | 1253 | else |
| 1258 | − ret = arm_pmu_acpi_probe(armv8_pmuv3_init); | |
| 1259 | − | |
| 1260 | − /* | |
| 1261 | − * Try to re-initialize lockup detector after PMU init in | |
| 1262 | − * case PMU events are triggered via NMIs. | |
| 1263 | − */ | |
| 1264 | − if (ret == 0 && arm_pmu_irq_is_nmi()) | |
| 1265 | − lockup_detector_init(); | |
| 1266 | − | |
| 1267 | − return ret; | |
| 1254 | + return arm_pmu_acpi_probe(armv8_pmuv3_init); | |
| 1268 | 1255 | } |
| 1269 | 1256 | device_initcall(armv8_pmu_driver_init) |
| 1270 | 1257 | |
| @@ -1322,27 +1309,3 @@ void arch_perf_update_userpage(struct perf_event *event, · 51 unmodified lines | ||
| 1322 | 1309 | userpg->cap_user_time_zero = 1; |
| 1323 | 1310 | userpg->cap_user_time_short = 1; |
| 1324 | 1311 | } |
| 1325 | − | |
| 1326 | −#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF | |
| 1327 | −/* | |
| 1328 | − * Safe maximum CPU frequency in case a particular platform doesn't implement | |
| 1329 | − * cpufreq driver. Although, architecture doesn't put any restrictions on | |
| 1330 | − * maximum frequency but 5 GHz seems to be safe maximum given the available | |
| 1331 | − * Arm CPUs in the market which are clocked much less than 5 GHz. On the other | |
| 1332 | − * hand, we can't make it much higher as it would lead to a large hard-lockup | |
| 1333 | − * detection timeout on parts which are running slower (eg. 1GHz on | |
| 1334 | − * Developerbox) and doesn't possess a cpufreq driver. | |
| 1335 | − */ | |
| 1336 | −#define SAFE_MAX_CPU_FREQ 5000000000UL // 5 GHz | |
| 1337 | −u64 hw_nmi_get_sample_period(int watchdog_thresh) | |
| 1338 | −{ | |
| 1339 | − unsigned int cpu = smp_processor_id(); | |
| 1340 | − unsigned long max_cpu_freq; | |
| 1341 | − | |
| 1342 | − max_cpu_freq = cpufreq_get_hw_max_freq(cpu) * 1000UL; | |
| 1343 | − if (!max_cpu_freq) | |
| 1344 | − max_cpu_freq = SAFE_MAX_CPU_FREQ; | |
| 1345 | − | |
| 1346 | − return (u64)max_cpu_freq * watchdog_thresh; | |
| 1347 | −} | |
| 1348 | −#endif | |
| @@ -25,7 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | stp x24, x25, [sp, #S_X24] |
| 26 | 26 | stp x26, x27, [sp, #S_X26] |
| 27 | 27 | stp x28, x29, [sp, #S_X28] |
| 28 | − add x0, sp, #S_FRAME_SIZE | |
| 28 | + add x0, sp, #PT_REGS_SIZE | |
| 29 | 29 | stp lr, x0, [sp, #S_LR] |
| 30 | 30 | /* |
| 31 | 31 | * Construct a useful saved PSTATE |
| @@ -62,7 +62,7 @@ · 30 unmodified lines | ||
| 62 | 62 | .endm |
| 63 | 63 | |
| 64 | 64 | SYM_CODE_START(kretprobe_trampoline) |
| 65 | − sub sp, sp, #S_FRAME_SIZE | |
| 65 | + sub sp, sp, #PT_REGS_SIZE | |
| 66 | 66 | |
| 67 | 67 | save_all_base_regs |
| 68 | 68 | |
| @@ -76,7 +76,7 @@ SYM_CODE_START(kretprobe_trampoline) · 7 unmodified lines | ||
| 76 | 76 | |
| 77 | 77 | restore_all_base_regs |
| 78 | 78 | |
| 79 | − add sp, sp, #S_FRAME_SIZE | |
| 79 | + add sp, sp, #PT_REGS_SIZE | |
| 80 | 80 | ret |
| 81 | 81 | |
| 82 | 82 | SYM_CODE_END(kretprobe_trampoline) |
| @@ -914,13 +914,6 @@ static void do_signal(struct pt_regs *regs) · 913 unmodified lines | ||
| 914 | 914 | asmlinkage void do_notify_resume(struct pt_regs *regs, |
| 915 | 915 | unsigned long thread_flags) |
| 916 | 916 | { |
| 917 | − /* | |
| 918 | − * The assembly code enters us with IRQs off, but it hasn't | |
| 919 | − * informed the tracing code of that for efficiency reasons. | |
| 920 | − * Update the trace code with the current status. | |
| 921 | − */ | |
| 922 | − trace_hardirqs_off(); | |
| 923 | − | |
| 924 | 917 | do { |
| 925 | 918 | if (thread_flags & _TIF_NEED_RESCHED) { |
| 926 | 919 | /* Unmask Debug and SError for the next task */ |
| @@ -434,7 +434,7 @@ static void __init hyp_mode_check(void) · 433 unmodified lines | ||
| 434 | 434 | "CPU: CPUs started in inconsistent modes"); |
| 435 | 435 | else |
| 436 | 436 | pr_info("CPU: All CPU(s) started at EL1\n"); |
| 437 | − if (IS_ENABLED(CONFIG_KVM)) | |
| 437 | + if (IS_ENABLED(CONFIG_KVM) && !is_kernel_in_hyp_mode()) | |
| 438 | 438 | kvm_compute_layout(); |
| 439 | 439 | } |
| 440 | 440 | |
| @@ -807,7 +807,6 @@ int arch_show_interrupts(struct seq_file *p, int prec) · 366 unmodified lines | ||
| 807 | 807 | unsigned int cpu, i; |
| 808 | 808 | |
| 809 | 809 | for (i = 0; i < NR_IPI; i++) { |
| 810 | − unsigned int irq = irq_desc_get_irq(ipi_desc[i]); | |
| 811 | 810 | seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i, |
| 812 | 811 | prec >= 4 ? " " : ""); |
| 813 | 812 | for_each_online_cpu(cpu) |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | #include <asm/daifflags.h> |
| 11 | 11 | #include <asm/debug-monitors.h> |
| 12 | +#include <asm/exception.h> | |
| 12 | 13 | #include <asm/fpsimd.h> |
| 13 | 14 | #include <asm/syscall.h> |
| 14 | 15 | #include <asm/thread_info.h> |
| @@ -165,15 +166,8 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, · 150 unmodified lines | ||
| 165 | 166 | if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) { |
| 166 | 167 | local_daif_mask(); |
| 167 | 168 | flags = current_thread_info()->flags; |
| 168 | − if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) { | |
| 169 | − /* | |
| 170 | − * We're off to userspace, where interrupts are | |
| 171 | − * always enabled after we restore the flags from | |
| 172 | − * the SPSR. | |
| 173 | − */ | |
| 174 | − trace_hardirqs_on(); | |
| 169 | + if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) | |
| 175 | 170 | return; |
| 176 | − } | |
| 177 | 171 | local_daif_restore(DAIF_PROCCTX); |
| 178 | 172 | } |
| 179 | 173 | |
| @@ -42,7 +42,6 @@ · 41 unmodified lines | ||
| 42 | 42 | #include <asm/smp.h> |
| 43 | 43 | #include <asm/stack_pointer.h> |
| 44 | 44 | #include <asm/stacktrace.h> |
| 45 | −#include <asm/exception.h> | |
| 46 | 45 | #include <asm/system_misc.h> |
| 47 | 46 | #include <asm/sysreg.h> |
| 48 | 47 | |
| @@ -24,8 +24,7 @@ btildflags-$(CONFIG_ARM64_BTI_KERNEL) += -z force-bti · 23 unmodified lines | ||
| 24 | 24 | # routines, as x86 does (see 6f121e548f83 ("x86, vdso: Reimplement vdso.so |
| 25 | 25 | # preparation in build-time C")). |
| 26 | 26 | ldflags-y := -shared -nostdlib -soname=linux-vdso.so.1 --hash-style=sysv \ |
| 27 | − -Bsymbolic $(call ld-option, --no-eh-frame-hdr) --build-id=sha1 -n \ | |
| 28 | − $(btildflags-y) -T | |
| 27 | + -Bsymbolic --build-id=sha1 -n $(btildflags-y) -T | |
| 29 | 28 | |
| 30 | 29 | ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18 |
| 31 | 30 | ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO |
| @@ -40,9 +40,6 @@ SECTIONS · 39 unmodified lines | ||
| 40 | 40 | PROVIDE (_etext = .); |
| 41 | 41 | PROVIDE (etext = .); |
| 42 | 42 | |
| 43 | − .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr | |
| 44 | − .eh_frame : { KEEP (*(.eh_frame)) } :text | |
| 45 | − | |
| 46 | 43 | .dynamic : { *(.dynamic) } :text :dynamic |
| 47 | 44 | |
| 48 | 45 | .rodata : { *(.rodata*) } :text |
| @@ -54,6 +51,7 @@ SECTIONS · 5 unmodified lines | ||
| 54 | 51 | *(.note.GNU-stack) |
| 55 | 52 | *(.data .data.* .gnu.linkonce.d.* .sdata*) |
| 56 | 53 | *(.bss .sbss .dynbss .dynsbss) |
| 54 | + *(.eh_frame .eh_frame_hdr) | |
| 57 | 55 | } |
| 58 | 56 | } |
| 59 | 57 | |
| @@ -66,7 +64,6 @@ PHDRS · 6 unmodified lines | ||
| 66 | 64 | text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ |
| 67 | 65 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ |
| 68 | 66 | note PT_NOTE FLAGS(4); /* PF_R */ |
| 69 | − eh_frame_hdr PT_GNU_EH_FRAME; | |
| 70 | 67 | } |
| 71 | 68 | |
| 72 | 69 | /* |
| @@ -49,14 +49,6 @@ if KVM · 48 unmodified lines | ||
| 49 | 49 | |
| 50 | 50 | source "virt/kvm/Kconfig" |
| 51 | 51 | |
| 52 | −config KVM_ARM_PMU | |
| 53 | − bool "Virtual Performance Monitoring Unit (PMU) support" | |
| 54 | − depends on HW_PERF_EVENTS | |
| 55 | − default y | |
| 56 | − help | |
| 57 | − Adds support for a virtual Performance Monitoring Unit (PMU) in | |
| 58 | − virtual machines. | |
| 59 | − | |
| 60 | 52 | endif # KVM |
| 61 | 53 | |
| 62 | 54 | endif # VIRTUALIZATION |
| @@ -24,4 +24,4 @@ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \ · 23 unmodified lines | ||
| 24 | 24 | vgic/vgic-mmio-v3.o vgic/vgic-kvm-device.o \ |
| 25 | 25 | vgic/vgic-its.o vgic/vgic-debug.o |
| 26 | 26 | |
| 27 | −kvm-$(CONFIG_KVM_ARM_PMU) += pmu-emul.o | |
| 27 | +kvm-$(CONFIG_HW_PERF_EVENTS) += pmu-emul.o | |
| @@ -1129,9 +1129,10 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) · 1128 unmodified lines | ||
| 1129 | 1129 | if (!irqchip_in_kernel(vcpu->kvm)) |
| 1130 | 1130 | goto no_vgic; |
| 1131 | 1131 | |
| 1132 | − if (!vgic_initialized(vcpu->kvm)) | |
| 1133 | − return -ENODEV; | |
| 1134 | − | |
| 1132 | + /* | |
| 1133 | + * At this stage, we have the guarantee that the vgic is both | |
| 1134 | + * available and initialized. | |
| 1135 | + */ | |
| 1135 | 1136 | if (!timer_irqs_are_valid(vcpu)) { |
| 1136 | 1137 | kvm_debug("incorrectly configured timer irqs\n"); |
| 1137 | 1138 | return -EINVAL; |
| @@ -65,10 +65,6 @@ static bool vgic_present; · 64 unmodified lines | ||
| 65 | 65 | static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled); |
| 66 | 66 | DEFINE_STATIC_KEY_FALSE(userspace_irqchip_in_use); |
| 67 | 67 | |
| 68 | −extern u64 kvm_nvhe_sym(__cpu_logical_map)[NR_CPUS]; | |
| 69 | −extern u32 kvm_nvhe_sym(kvm_host_psci_version); | |
| 70 | −extern struct psci_0_1_function_ids kvm_nvhe_sym(kvm_host_psci_0_1_function_ids); | |
| 71 | − | |
| 72 | 68 | int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) |
| 73 | 69 | { |
| 74 | 70 | return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE; |
| @@ -584,11 +580,9 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) · 509 unmodified lines | ||
| 584 | 580 | * Map the VGIC hardware resources before running a vcpu the |
| 585 | 581 | * first time on this VM. |
| 586 | 582 | */ |
| 587 | − if (unlikely(!vgic_ready(kvm))) { | |
| 588 | − ret = kvm_vgic_map_resources(kvm); | |
| 589 | − if (ret) | |
| 590 | − return ret; | |
| 591 | − } | |
| 583 | + ret = kvm_vgic_map_resources(kvm); | |
| 584 | + if (ret) | |
| 585 | + return ret; | |
| 592 | 586 | } else { |
| 593 | 587 | /* |
| 594 | 588 | * Tell the rest of the code that there are userspace irqchip |
| @@ -1574,12 +1568,12 @@ static struct notifier_block hyp_init_cpu_pm_nb = { · 979 unmodified lines | ||
| 1574 | 1568 | .notifier_call = hyp_init_cpu_pm_notifier, |
| 1575 | 1569 | }; |
| 1576 | 1570 | |
| 1577 | −static void __init hyp_cpu_pm_init(void) | |
| 1571 | +static void hyp_cpu_pm_init(void) | |
| 1578 | 1572 | { |
| 1579 | 1573 | if (!is_protected_kvm_enabled()) |
| 1580 | 1574 | cpu_pm_register_notifier(&hyp_init_cpu_pm_nb); |
| 1581 | 1575 | } |
| 1582 | −static void __init hyp_cpu_pm_exit(void) | |
| 1576 | +static void hyp_cpu_pm_exit(void) | |
| 1583 | 1577 | { |
| 1584 | 1578 | if (!is_protected_kvm_enabled()) |
| 1585 | 1579 | cpu_pm_unregister_notifier(&hyp_init_cpu_pm_nb); |
| @@ -1604,9 +1598,12 @@ static void init_cpu_logical_map(void) · 18 unmodified lines | ||
| 1604 | 1598 | * allow any other CPUs from the `possible` set to boot. |
| 1605 | 1599 | */ |
| 1606 | 1600 | for_each_online_cpu(cpu) |
| 1607 | − kvm_nvhe_sym(__cpu_logical_map)[cpu] = cpu_logical_map(cpu); | |
| 1601 | + hyp_cpu_logical_map[cpu] = cpu_logical_map(cpu); | |
| 1608 | 1602 | } |
| 1609 | 1603 | |
| 1604 | +#define init_psci_0_1_impl_state(config, what) \ | |
| 1605 | + config.psci_0_1_ ## what ## _implemented = psci_ops.what | |
| 1606 | + | |
| 1610 | 1607 | static bool init_psci_relay(void) |
| 1611 | 1608 | { |
| 1612 | 1609 | /* |
| @@ -1618,8 +1615,15 @@ static bool init_psci_relay(void) · 5 unmodified lines | ||
| 1618 | 1615 | return false; |
| 1619 | 1616 | } |
| 1620 | 1617 | |
| 1621 | − kvm_nvhe_sym(kvm_host_psci_version) = psci_ops.get_version(); | |
| 1622 | − kvm_nvhe_sym(kvm_host_psci_0_1_function_ids) = get_psci_0_1_function_ids(); | |
| 1618 | + kvm_host_psci_config.version = psci_ops.get_version(); | |
| 1619 | + | |
| 1620 | + if (kvm_host_psci_config.version == PSCI_VERSION(0, 1)) { | |
| 1621 | + kvm_host_psci_config.function_ids_0_1 = get_psci_0_1_function_ids(); | |
| 1622 | + init_psci_0_1_impl_state(kvm_host_psci_config, cpu_suspend); | |
| 1623 | + init_psci_0_1_impl_state(kvm_host_psci_config, cpu_on); | |
| 1624 | + init_psci_0_1_impl_state(kvm_host_psci_config, cpu_off); | |
| 1625 | + init_psci_0_1_impl_state(kvm_host_psci_config, migrate); | |
| 1626 | + } | |
| 1623 | 1627 | return true; |
| 1624 | 1628 | } |
| 1625 | 1629 | |
| @@ -59,4 +59,13 @@ static inline void __adjust_pc(struct kvm_vcpu *vcpu) · 58 unmodified lines | ||
| 59 | 59 | } |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | +/* | |
| 63 | + * Skip an instruction while host sysregs are live. | |
| 64 | + * Assumes host is always 64-bit. | |
| 65 | + */ | |
| 66 | +static inline void kvm_skip_host_instr(void) | |
| 67 | +{ | |
| 68 | + write_sysreg_el2(read_sysreg_el2(SYS_ELR) + 4, SYS_ELR); | |
| 69 | +} | |
| 70 | + | |
| 62 | 71 | #endif |
| @@ -157,11 +157,6 @@ static void default_host_smc_handler(struct kvm_cpu_context *host_ctxt) · 156 unmodified lines | ||
| 157 | 157 | __kvm_hyp_host_forward_smc(host_ctxt); |
| 158 | 158 | } |
| 159 | 159 | |
| 160 | −static void skip_host_instruction(void) | |
| 161 | −{ | |
| 162 | − write_sysreg_el2(read_sysreg_el2(SYS_ELR) + 4, SYS_ELR); | |
| 163 | −} | |
| 164 | − | |
| 165 | 160 | static void handle_host_smc(struct kvm_cpu_context *host_ctxt) |
| 166 | 161 | { |
| 167 | 162 | bool handled; |
| @@ -170,11 +165,8 @@ static void handle_host_smc(struct kvm_cpu_context *host_ctxt) · 2 unmodified lines | ||
| 170 | 165 | if (!handled) |
| 171 | 166 | default_host_smc_handler(host_ctxt); |
| 172 | 167 | |
| 173 | − /* | |
| 174 | − * Unlike HVC, the return address of an SMC is the instruction's PC. | |
| 175 | − * Move the return address past the instruction. | |
| 176 | − */ | |
| 177 | − skip_host_instruction(); | |
| 168 | + /* SMC was trapped, move ELR past the current PC. */ | |
| 169 | + kvm_skip_host_instr(); | |
| 178 | 170 | } |
| 179 | 171 | |
| 180 | 172 | void handle_trap(struct kvm_cpu_context *host_ctxt) |
| @@ -14,14 +14,14 @@ · 13 unmodified lines | ||
| 14 | 14 | * Other CPUs should not be allowed to boot because their features were |
| 15 | 15 | * not checked against the finalized system capabilities. |
| 16 | 16 | */ |
| 17 | −u64 __ro_after_init __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID }; | |
| 17 | +u64 __ro_after_init hyp_cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID }; | |
| 18 | 18 | |
| 19 | 19 | u64 cpu_logical_map(unsigned int cpu) |
| 20 | 20 | { |
| 21 | − if (cpu >= ARRAY_SIZE(__cpu_logical_map)) | |
| 21 | + if (cpu >= ARRAY_SIZE(hyp_cpu_logical_map)) | |
| 22 | 22 | hyp_panic(); |
| 23 | 23 | |
| 24 | − return __cpu_logical_map[cpu]; | |
| 24 | + return hyp_cpu_logical_map[cpu]; | |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | 27 | unsigned long __hyp_per_cpu_offset(unsigned int cpu) |
| @@ -7,11 +7,8 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <asm/kvm_asm.h> |
| 8 | 8 | #include <asm/kvm_hyp.h> |
| 9 | 9 | #include <asm/kvm_mmu.h> |
| 10 | −#include <kvm/arm_hypercalls.h> | |
| 11 | 10 | #include <linux/arm-smccc.h> |
| 12 | 11 | #include <linux/kvm_host.h> |
| 13 | −#include <linux/psci.h> | |
| 14 | −#include <kvm/arm_psci.h> | |
| 15 | 12 | #include <uapi/linux/psci.h> |
| 16 | 13 | |
| 17 | 14 | #include <nvhe/trap_handler.h> |
| @@ -22,9 +19,8 @@ void kvm_hyp_cpu_resume(unsigned long r0); · 4 unmodified lines | ||
| 22 | 19 | void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt); |
| 23 | 20 | |
| 24 | 21 | /* Config options set by the host. */ |
| 25 | −__ro_after_init u32 kvm_host_psci_version; | |
| 26 | −__ro_after_init struct psci_0_1_function_ids kvm_host_psci_0_1_function_ids; | |
| 27 | −__ro_after_init s64 hyp_physvirt_offset; | |
| 22 | +struct kvm_host_psci_config __ro_after_init kvm_host_psci_config; | |
| 23 | +s64 __ro_after_init hyp_physvirt_offset; | |
| 28 | 24 | |
| 29 | 25 | #define __hyp_pa(x) ((phys_addr_t)((x)) + hyp_physvirt_offset) |
| 30 | 26 | |
| @@ -47,19 +43,16 @@ struct psci_boot_args { · 16 unmodified lines | ||
| 47 | 43 | static DEFINE_PER_CPU(struct psci_boot_args, cpu_on_args) = PSCI_BOOT_ARGS_INIT; |
| 48 | 44 | static DEFINE_PER_CPU(struct psci_boot_args, suspend_args) = PSCI_BOOT_ARGS_INIT; |
| 49 | 45 | |
| 50 | −static u64 get_psci_func_id(struct kvm_cpu_context *host_ctxt) | |
| 51 | −{ | |
| 52 | − DECLARE_REG(u64, func_id, host_ctxt, 0); | |
| 53 | − | |
| 54 | − return func_id; | |
| 55 | −} | |
| 46 | +#define is_psci_0_1(what, func_id) \ | |
| 47 | + (kvm_host_psci_config.psci_0_1_ ## what ## _implemented && \ | |
| 48 | + (func_id) == kvm_host_psci_config.function_ids_0_1.what) | |
| 56 | 49 | |
| 57 | 50 | static bool is_psci_0_1_call(u64 func_id) |
| 58 | 51 | { |
| 59 | − return (func_id == kvm_host_psci_0_1_function_ids.cpu_suspend) || | |
| 60 | − (func_id == kvm_host_psci_0_1_function_ids.cpu_on) || | |
| 61 | − (func_id == kvm_host_psci_0_1_function_ids.cpu_off) || | |
| 62 | − (func_id == kvm_host_psci_0_1_function_ids.migrate); | |
| 52 | + return (is_psci_0_1(cpu_suspend, func_id) || | |
| 53 | + is_psci_0_1(cpu_on, func_id) || | |
| 54 | + is_psci_0_1(cpu_off, func_id) || | |
| 55 | + is_psci_0_1(migrate, func_id)); | |
| 63 | 56 | } |
| 64 | 57 | |
| 65 | 58 | static bool is_psci_0_2_call(u64 func_id) |
| @@ -69,16 +62,6 @@ static bool is_psci_0_2_call(u64 func_id) · 3 unmodified lines | ||
| 69 | 62 | (PSCI_0_2_FN64(0) <= func_id && func_id <= PSCI_0_2_FN64(31)); |
| 70 | 63 | } |
| 71 | 64 | |
| 72 | −static bool is_psci_call(u64 func_id) | |
| 73 | −{ | |
| 74 | − switch (kvm_host_psci_version) { | |
| 75 | − case PSCI_VERSION(0, 1): | |
| 76 | − return is_psci_0_1_call(func_id); | |
| 77 | − default: | |
| 78 | − return is_psci_0_2_call(func_id); | |
| 79 | − } | |
| 80 | −} | |
| 81 | − | |
| 82 | 65 | static unsigned long psci_call(unsigned long fn, unsigned long arg0, |
| 83 | 66 | unsigned long arg1, unsigned long arg2) |
| 84 | 67 | { |
| @@ -248,15 +231,14 @@ asmlinkage void __noreturn kvm_host_psci_cpu_entry(bool is_cpu_on) · 163 unmodified lines | ||
| 248 | 231 | |
| 249 | 232 | static unsigned long psci_0_1_handler(u64 func_id, struct kvm_cpu_context *host_ctxt) |
| 250 | 233 | { |
| 251 | − if ((func_id == kvm_host_psci_0_1_function_ids.cpu_off) || | |
| 252 | − (func_id == kvm_host_psci_0_1_function_ids.migrate)) | |
| 234 | + if (is_psci_0_1(cpu_off, func_id) || is_psci_0_1(migrate, func_id)) | |
| 253 | 235 | return psci_forward(host_ctxt); |
| 254 | − else if (func_id == kvm_host_psci_0_1_function_ids.cpu_on) | |
| 236 | + if (is_psci_0_1(cpu_on, func_id)) | |
| 255 | 237 | return psci_cpu_on(func_id, host_ctxt); |
| 256 | − else if (func_id == kvm_host_psci_0_1_function_ids.cpu_suspend) | |
| 238 | + if (is_psci_0_1(cpu_suspend, func_id)) | |
| 257 | 239 | return psci_cpu_suspend(func_id, host_ctxt); |
| 258 | − else | |
| 259 | − return PSCI_RET_NOT_SUPPORTED; | |
| 240 | + | |
| 241 | + return PSCI_RET_NOT_SUPPORTED; | |
| 260 | 242 | } |
| 261 | 243 | |
| 262 | 244 | static unsigned long psci_0_2_handler(u64 func_id, struct kvm_cpu_context *host_ctxt) |
| @@ -298,20 +280,23 @@ static unsigned long psci_1_0_handler(u64 func_id, struct kvm_cpu_context *host_ · 35 unmodified lines | ||
| 298 | 280 | |
| 299 | 281 | bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt) |
| 300 | 282 | { |
| 301 | − u64 func_id = get_psci_func_id(host_ctxt); | |
| 283 | + DECLARE_REG(u64, func_id, host_ctxt, 0); | |
| 302 | 284 | unsigned long ret; |
| 303 | 285 | |
| 304 | − if (!is_psci_call(func_id)) | |
| 305 | − return false; | |
| 306 | − | |
| 307 | − switch (kvm_host_psci_version) { | |
| 286 | + switch (kvm_host_psci_config.version) { | |
| 308 | 287 | case PSCI_VERSION(0, 1): |
| 288 | + if (!is_psci_0_1_call(func_id)) | |
| 289 | + return false; | |
| 309 | 290 | ret = psci_0_1_handler(func_id, host_ctxt); |
| 310 | 291 | break; |
| 311 | 292 | case PSCI_VERSION(0, 2): |
| 293 | + if (!is_psci_0_2_call(func_id)) | |
| 294 | + return false; | |
| 312 | 295 | ret = psci_0_2_handler(func_id, host_ctxt); |
| 313 | 296 | break; |
| 314 | 297 | default: |
| 298 | + if (!is_psci_0_2_call(func_id)) | |
| 299 | + return false; | |
| 315 | 300 | ret = psci_1_0_handler(func_id, host_ctxt); |
| 316 | 301 | break; |
| 317 | 302 | } |
| @@ -850,8 +850,6 @@ int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu) · 849 unmodified lines | ||
| 850 | 850 | return -EINVAL; |
| 851 | 851 | } |
| 852 | 852 | |
| 853 | − kvm_pmu_vcpu_reset(vcpu); | |
| 854 | − | |
| 855 | 853 | return 0; |
| 856 | 854 | } |
| 857 | 855 | |
| @@ -594,6 +594,10 @@ static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) · 593 unmodified lines | ||
| 594 | 594 | { |
| 595 | 595 | u64 pmcr, val; |
| 596 | 596 | |
| 597 | + /* No PMU available, PMCR_EL0 may UNDEF... */ | |
| 598 | + if (!kvm_arm_support_pmu_v3()) | |
| 599 | + return; | |
| 600 | + | |
| 597 | 601 | pmcr = read_sysreg(pmcr_el0); |
| 598 | 602 | /* |
| 599 | 603 | * Writable bits of PMCR_EL0 (ARMV8_PMU_PMCR_MASK) are reset to UNKNOWN |
| @@ -919,7 +923,7 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, · 319 unmodified lines | ||
| 919 | 923 | |
| 920 | 924 | #define reg_to_encoding(x) \ |
| 921 | 925 | sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \ |
| 922 | − (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2); | |
| 926 | + (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2) | |
| 923 | 927 | |
| 924 | 928 | /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */ |
| 925 | 929 | #define DBG_BCR_BVR_WCR_WVR_EL1(n) \ |
| @@ -34,17 +34,16 @@ static u64 __early_kern_hyp_va(u64 addr) · 33 unmodified lines | ||
| 34 | 34 | } |
| 35 | 35 | |
| 36 | 36 | /* |
| 37 | − * Store a hyp VA <-> PA offset into a hyp-owned variable. | |
| 37 | + * Store a hyp VA <-> PA offset into a EL2-owned variable. | |
| 38 | 38 | */ |
| 39 | 39 | static void init_hyp_physvirt_offset(void) |
| 40 | 40 | { |
| 41 | − extern s64 kvm_nvhe_sym(hyp_physvirt_offset); | |
| 42 | 41 | u64 kern_va, hyp_va; |
| 43 | 42 | |
| 44 | 43 | /* Compute the offset from the hyp VA and PA of a random symbol. */ |
| 45 | − kern_va = (u64)kvm_ksym_ref(__hyp_text_start); | |
| 44 | + kern_va = (u64)lm_alias(__hyp_text_start); | |
| 46 | 45 | hyp_va = __early_kern_hyp_va(kern_va); |
| 47 | − CHOOSE_NVHE_SYM(hyp_physvirt_offset) = (s64)__pa(kern_va) - (s64)hyp_va; | |
| 46 | + hyp_physvirt_offset = (s64)__pa(kern_va) - (s64)hyp_va; | |
| 48 | 47 | } |
| 49 | 48 | |
| 50 | 49 | /* |
| @@ -419,7 +419,8 @@ int vgic_lazy_init(struct kvm *kvm) · 418 unmodified lines | ||
| 419 | 419 | * Map the MMIO regions depending on the VGIC model exposed to the guest |
| 420 | 420 | * called on the first VCPU run. |
| 421 | 421 | * Also map the virtual CPU interface into the VM. |
| 422 | − * v2/v3 derivatives call vgic_init if not already done. | |
| 422 | + * v2 calls vgic_init() if not already done. | |
| 423 | + * v3 and derivatives return an error if the VGIC is not initialized. | |
| 423 | 424 | * vgic_ready() returns true if this function has succeeded. |
| 424 | 425 | * @kvm: kvm struct pointer |
| 425 | 426 | */ |
| @@ -428,7 +429,13 @@ int kvm_vgic_map_resources(struct kvm *kvm) · 2 unmodified lines | ||
| 428 | 429 | struct vgic_dist *dist = &kvm->arch.vgic; |
| 429 | 430 | int ret = 0; |
| 430 | 431 | |
| 432 | + if (likely(vgic_ready(kvm))) | |
| 433 | + return 0; | |
| 434 | + | |
| 431 | 435 | mutex_lock(&kvm->lock); |
| 436 | + if (vgic_ready(kvm)) | |
| 437 | + goto out; | |
| 438 | + | |
| 432 | 439 | if (!irqchip_in_kernel(kvm)) |
| 433 | 440 | goto out; |
| 434 | 441 | |
| @@ -439,6 +446,8 @@ int kvm_vgic_map_resources(struct kvm *kvm) · 4 unmodified lines | ||
| 439 | 446 | |
| 440 | 447 | if (ret) |
| 441 | 448 | __kvm_vgic_destroy(kvm); |
| 449 | + else | |
| 450 | + dist->ready = true; | |
| 442 | 451 | |
| 443 | 452 | out: |
| 444 | 453 | mutex_unlock(&kvm->lock); |
| @@ -306,20 +306,15 @@ int vgic_v2_map_resources(struct kvm *kvm) · 305 unmodified lines | ||
| 306 | 306 | struct vgic_dist *dist = &kvm->arch.vgic; |
| 307 | 307 | int ret = 0; |
| 308 | 308 | |
| 309 | − if (vgic_ready(kvm)) | |
| 310 | − goto out; | |
| 311 | − | |
| 312 | 309 | if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base) || |
| 313 | 310 | IS_VGIC_ADDR_UNDEF(dist->vgic_cpu_base)) { |
| 314 | 311 | kvm_err("Need to set vgic cpu and dist addresses first\n"); |
| 315 | − ret = -ENXIO; | |
| 316 | − goto out; | |
| 312 | + return -ENXIO; | |
| 317 | 313 | } |
| 318 | 314 | |
| 319 | 315 | if (!vgic_v2_check_base(dist->vgic_dist_base, dist->vgic_cpu_base)) { |
| 320 | 316 | kvm_err("VGIC CPU and dist frames overlap\n"); |
| 321 | − ret = -EINVAL; | |
| 322 | − goto out; | |
| 317 | + return -EINVAL; | |
| 323 | 318 | } |
| 324 | 319 | |
| 325 | 320 | /* |
| @@ -329,13 +324,13 @@ int vgic_v2_map_resources(struct kvm *kvm) · 3 unmodified lines | ||
| 329 | 324 | ret = vgic_init(kvm); |
| 330 | 325 | if (ret) { |
| 331 | 326 | kvm_err("Unable to initialize VGIC dynamic data structures\n"); |
| 332 | − goto out; | |
| 327 | + return ret; | |
| 333 | 328 | } |
| 334 | 329 | |
| 335 | 330 | ret = vgic_register_dist_iodev(kvm, dist->vgic_dist_base, VGIC_V2); |
| 336 | 331 | if (ret) { |
| 337 | 332 | kvm_err("Unable to register VGIC MMIO regions\n"); |
| 338 | − goto out; | |
| 333 | + return ret; | |
| 339 | 334 | } |
| 340 | 335 | |
| 341 | 336 | if (!static_branch_unlikely(&vgic_v2_cpuif_trap)) { |
| @@ -344,14 +339,11 @@ int vgic_v2_map_resources(struct kvm *kvm) · 2 unmodified lines | ||
| 344 | 339 | KVM_VGIC_V2_CPU_SIZE, true); |
| 345 | 340 | if (ret) { |
| 346 | 341 | kvm_err("Unable to remap VGIC CPU to VCPU\n"); |
| 347 | − goto out; | |
| 342 | + return ret; | |
| 348 | 343 | } |
| 349 | 344 | } |
| 350 | 345 | |
| 351 | − dist->ready = true; | |
| 352 | − | |
| 353 | −out: | |
| 354 | − return ret; | |
| 346 | + return 0; | |
| 355 | 347 | } |
| 356 | 348 | |
| 357 | 349 | DEFINE_STATIC_KEY_FALSE(vgic_v2_cpuif_trap); |
| @@ -500,29 +500,23 @@ int vgic_v3_map_resources(struct kvm *kvm) · 499 unmodified lines | ||
| 500 | 500 | int ret = 0; |
| 501 | 501 | int c; |
| 502 | 502 | |
| 503 | − if (vgic_ready(kvm)) | |
| 504 | − goto out; | |
| 505 | − | |
| 506 | 503 | kvm_for_each_vcpu(c, vcpu, kvm) { |
| 507 | 504 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; |
| 508 | 505 | |
| 509 | 506 | if (IS_VGIC_ADDR_UNDEF(vgic_cpu->rd_iodev.base_addr)) { |
| 510 | 507 | kvm_debug("vcpu %d redistributor base not set\n", c); |
| 511 | − ret = -ENXIO; | |
| 512 | − goto out; | |
| 508 | + return -ENXIO; | |
| 513 | 509 | } |
| 514 | 510 | } |
| 515 | 511 | |
| 516 | 512 | if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base)) { |
| 517 | 513 | kvm_err("Need to set vgic distributor addresses first\n"); |
| 518 | − ret = -ENXIO; | |
| 519 | − goto out; | |
| 514 | + return -ENXIO; | |
| 520 | 515 | } |
| 521 | 516 | |
| 522 | 517 | if (!vgic_v3_check_base(kvm)) { |
| 523 | 518 | kvm_err("VGIC redist and dist frames overlap\n"); |
| 524 | − ret = -EINVAL; | |
| 525 | − goto out; | |
| 519 | + return -EINVAL; | |
| 526 | 520 | } |
| 527 | 521 | |
| 528 | 522 | /* |
| @@ -530,22 +524,19 @@ int vgic_v3_map_resources(struct kvm *kvm) · 1 unmodified line | ||
| 530 | 524 | * the VGIC before we need to use it. |
| 531 | 525 | */ |
| 532 | 526 | if (!vgic_initialized(kvm)) { |
| 533 | − ret = -EBUSY; | |
| 534 | − goto out; | |
| 527 | + return -EBUSY; | |
| 535 | 528 | } |
| 536 | 529 | |
| 537 | 530 | ret = vgic_register_dist_iodev(kvm, dist->vgic_dist_base, VGIC_V3); |
| 538 | 531 | if (ret) { |
| 539 | 532 | kvm_err("Unable to register VGICv3 dist MMIO regions\n"); |
| 540 | − goto out; | |
| 533 | + return ret; | |
| 541 | 534 | } |
| 542 | 535 | |
| 543 | 536 | if (kvm_vgic_global_state.has_gicv4_1) |
| 544 | 537 | vgic_v4_configure_vsgis(kvm); |
| 545 | − dist->ready = true; | |
| 546 | 538 | |
| 547 | −out: | |
| 548 | − return ret; | |
| 539 | + return 0; | |
| 549 | 540 | } |
| 550 | 541 | |
| 551 | 542 | DEFINE_STATIC_KEY_FALSE(vgic_v3_cpuif_trap); |
| @@ -53,13 +53,13 @@ s64 memstart_addr __ro_after_init = -1; · 52 unmodified lines | ||
| 53 | 53 | EXPORT_SYMBOL(memstart_addr); |
| 54 | 54 | |
| 55 | 55 | /* |
| 56 | − * We create both ZONE_DMA and ZONE_DMA32. ZONE_DMA covers the first 1G of | |
| 57 | − * memory as some devices, namely the Raspberry Pi 4, have peripherals with | |
| 58 | − * this limited view of the memory. ZONE_DMA32 will cover the rest of the 32 | |
| 59 | − * bit addressable memory area. | |
| 56 | + * If the corresponding config options are enabled, we create both ZONE_DMA | |
| 57 | + * and ZONE_DMA32. By default ZONE_DMA covers the 32-bit addressable memory | |
| 58 | + * unless restricted on specific platforms (e.g. 30-bit on Raspberry Pi 4). | |
| 59 | + * In such case, ZONE_DMA32 covers the rest of the 32-bit addressable memory, | |
| 60 | + * otherwise it is empty. | |
| 60 | 61 | */ |
| 61 | 62 | phys_addr_t arm64_dma_phys_limit __ro_after_init; |
| 62 | −static phys_addr_t arm64_dma32_phys_limit __ro_after_init; | |
| 63 | 63 | |
| 64 | 64 | #ifdef CONFIG_KEXEC_CORE |
| 65 | 65 | /* |
| @@ -84,7 +84,7 @@ static void __init reserve_crashkernel(void) · 18 unmodified lines | ||
| 84 | 84 | |
| 85 | 85 | if (crash_base == 0) { |
| 86 | 86 | /* Current arm64 boot protocol requires 2MB alignment */ |
| 87 | − crash_base = memblock_find_in_range(0, arm64_dma32_phys_limit, | |
| 87 | + crash_base = memblock_find_in_range(0, arm64_dma_phys_limit, | |
| 88 | 88 | crash_size, SZ_2M); |
| 89 | 89 | if (crash_base == 0) { |
| 90 | 90 | pr_warn("cannot allocate crashkernel (size:0x%llx)\n", |
| @@ -196,6 +196,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) · 105 unmodified lines | ||
| 196 | 196 | unsigned long max_zone_pfns[MAX_NR_ZONES] = {0}; |
| 197 | 197 | unsigned int __maybe_unused acpi_zone_dma_bits; |
| 198 | 198 | unsigned int __maybe_unused dt_zone_dma_bits; |
| 199 | + phys_addr_t __maybe_unused dma32_phys_limit = max_zone_phys(32); | |
| 199 | 200 | |
| 200 | 201 | #ifdef CONFIG_ZONE_DMA |
| 201 | 202 | acpi_zone_dma_bits = fls64(acpi_iort_dma_get_max_cpu_address()); |
| @@ -205,8 +206,12 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) · 3 unmodified lines | ||
| 205 | 206 | max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit); |
| 206 | 207 | #endif |
| 207 | 208 | #ifdef CONFIG_ZONE_DMA32 |
| 208 | − max_zone_pfns[ZONE_DMA32] = PFN_DOWN(arm64_dma32_phys_limit); | |
| 209 | + max_zone_pfns[ZONE_DMA32] = PFN_DOWN(dma32_phys_limit); | |
| 210 | + if (!arm64_dma_phys_limit) | |
| 211 | + arm64_dma_phys_limit = dma32_phys_limit; | |
| 209 | 212 | #endif |
| 213 | + if (!arm64_dma_phys_limit) | |
| 214 | + arm64_dma_phys_limit = PHYS_MASK + 1; | |
| 210 | 215 | max_zone_pfns[ZONE_NORMAL] = max; |
| 211 | 216 | |
| 212 | 217 | free_area_init(max_zone_pfns); |
| @@ -394,16 +399,9 @@ void __init arm64_memblock_init(void) · 181 unmodified lines | ||
| 394 | 399 | |
| 395 | 400 | early_init_fdt_scan_reserved_mem(); |
| 396 | 401 | |
| 397 | − if (IS_ENABLED(CONFIG_ZONE_DMA32)) | |
| 398 | − arm64_dma32_phys_limit = max_zone_phys(32); | |
| 399 | − else | |
| 400 | − arm64_dma32_phys_limit = PHYS_MASK + 1; | |
| 401 | − | |
| 402 | 402 | reserve_elfcorehdr(); |
| 403 | 403 | |
| 404 | 404 | high_memory = __va(memblock_end_of_DRAM() - 1) + 1; |
| 405 | − | |
| 406 | − dma_contiguous_reserve(arm64_dma32_phys_limit); | |
| 407 | 405 | } |
| 408 | 406 | |
| 409 | 407 | void __init bootmem_init(void) |
| @@ -438,6 +436,11 @@ void __init bootmem_init(void) · 28 unmodified lines | ||
| 438 | 436 | sparse_init(); |
| 439 | 437 | zone_sizes_init(min, max); |
| 440 | 438 | |
| 439 | + /* | |
| 440 | + * Reserve the CMA area after arm64_dma_phys_limit was initialised. | |
| 441 | + */ | |
| 442 | + dma_contiguous_reserve(arm64_dma_phys_limit); | |
| 443 | + | |
| 441 | 444 | /* |
| 442 | 445 | * request_standard_resources() depends on crashkernel's memory being |
| 443 | 446 | * reserved, so do it here. |
| @@ -455,7 +458,7 @@ void __init bootmem_init(void) · 11 unmodified lines | ||
| 455 | 458 | void __init mem_init(void) |
| 456 | 459 | { |
| 457 | 460 | if (swiotlb_force == SWIOTLB_FORCE || |
| 458 | − max_pfn > PFN_DOWN(arm64_dma_phys_limit ? : arm64_dma32_phys_limit)) | |
| 461 | + max_pfn > PFN_DOWN(arm64_dma_phys_limit)) | |
| 459 | 462 | swiotlb_init(1); |
| 460 | 463 | else |
| 461 | 464 | swiotlb_force = SWIOTLB_NO_FORCE; |
| @@ -46,7 +46,7 @@ · 45 unmodified lines | ||
| 46 | 46 | #endif |
| 47 | 47 | |
| 48 | 48 | #ifdef CONFIG_KASAN_HW_TAGS |
| 49 | −#define TCR_KASAN_HW_FLAGS SYS_TCR_EL1_TCMA1 | TCR_TBI1 | |
| 49 | +#define TCR_KASAN_HW_FLAGS SYS_TCR_EL1_TCMA1 | TCR_TBI1 | TCR_TBID1 | |
| 50 | 50 | #else |
| 51 | 51 | #define TCR_KASAN_HW_FLAGS 0 |
| 52 | 52 | #endif |
| @@ -2,7 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | generic-y += asm-offsets.h |
| 3 | 3 | generic-y += gpio.h |
| 4 | 4 | generic-y += kvm_para.h |
| 5 | −generic-y += local64.h | |
| 6 | 5 | generic-y += qrwlock.h |
| 7 | 6 | generic-y += user.h |
| 8 | 7 | generic-y += vmlinux.lds.h |
| @@ -2,7 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | generic-y += asm-offsets.h |
| 3 | 3 | generic-y += extable.h |
| 4 | 4 | generic-y += kvm_para.h |
| 5 | −generic-y += local64.h | |
| 6 | 5 | generic-y += mcs_spinlock.h |
| 7 | 6 | generic-y += parport.h |
| 8 | 7 | generic-y += spinlock.h |
| @@ -2,5 +2,4 @@ · 1 unmodified line | ||
| 2 | 2 | generic-y += extable.h |
| 3 | 3 | generic-y += iomap.h |
| 4 | 4 | generic-y += kvm_para.h |
| 5 | −generic-y += local64.h | |
| 6 | 5 | generic-y += mcs_spinlock.h |
| @@ -1 +0,0 @@ | ||
| 1 | −#include <asm-generic/local64.h> | |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | #define _ASM_IA64_SPARSEMEM_H |
| 4 | 4 | |
| 5 | 5 | #ifdef CONFIG_SPARSEMEM |
| 6 | +#include <asm/page.h> | |
| 6 | 7 | /* |
| 7 | 8 | * SECTION_SIZE_BITS 2^N: how big each section will be |
| 8 | 9 | * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space |
| @@ -536,7 +536,7 @@ virtual_memmap_init(u64 start, u64 end, void *arg) · 535 unmodified lines | ||
| 536 | 536 | |
| 537 | 537 | if (map_start < map_end) |
| 538 | 538 | memmap_init_zone((unsigned long)(map_end - map_start), |
| 539 | − args->nid, args->zone, page_to_pfn(map_start), | |
| 539 | + args->nid, args->zone, page_to_pfn(map_start), page_to_pfn(map_end), | |
| 540 | 540 | MEMINIT_EARLY, NULL, MIGRATE_MOVABLE); |
| 541 | 541 | return 0; |
| 542 | 542 | } |
| @@ -546,7 +546,7 @@ memmap_init (unsigned long size, int nid, unsigned long zone, · 3 unmodified lines | ||
| 546 | 546 | unsigned long start_pfn) |
| 547 | 547 | { |
| 548 | 548 | if (!vmem_map) { |
| 549 | − memmap_init_zone(size, nid, zone, start_pfn, | |
| 549 | + memmap_init_zone(size, nid, zone, start_pfn, start_pfn + size, | |
| 550 | 550 | MEMINIT_EARLY, NULL, MIGRATE_MOVABLE); |
| 551 | 551 | } else { |
| 552 | 552 | struct page *start; |
| @@ -2,6 +2,5 @@ · 1 unmodified line | ||
| 2 | 2 | generated-y += syscall_table.h |
| 3 | 3 | generic-y += extable.h |
| 4 | 4 | generic-y += kvm_para.h |
| 5 | −generic-y += local64.h | |
| 6 | 5 | generic-y += mcs_spinlock.h |
| 7 | 6 | generic-y += spinlock.h |
| @@ -2,7 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | generated-y += syscall_table.h |
| 3 | 3 | generic-y += extable.h |
| 4 | 4 | generic-y += kvm_para.h |
| 5 | −generic-y += local64.h | |
| 6 | 5 | generic-y += mcs_spinlock.h |
| 7 | 6 | generic-y += parport.h |
| 8 | 7 | generic-y += syscalls.h |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/libfdt.h> |
| 14 | 14 | |
| 15 | 15 | #include <asm/addrspace.h> |
| 16 | +#include <asm/unaligned.h> | |
| 16 | 17 | |
| 17 | 18 | /* |
| 18 | 19 | * These two variables specify the free mem region |
| @@ -117,7 +118,7 @@ void decompress_kernel(unsigned long boot_heap_start) · 98 unmodified lines | ||
| 117 | 118 | dtb_size = fdt_totalsize((void *)&__appended_dtb); |
| 118 | 119 | |
| 119 | 120 | /* last four bytes is always image size in little endian */ |
| 120 | − image_size = le32_to_cpup((void *)&__image_end - 4); | |
| 121 | + image_size = get_unaligned_le32((void *)&__image_end - 4); | |
| 121 | 122 | |
| 122 | 123 | /* copy dtb to where the booted kernel will expect it */ |
| 123 | 124 | memcpy((void *)VMLINUX_LOAD_ADDRESS_ULL + image_size, |
| @@ -1444,7 +1444,7 @@ static void octeon_irq_setup_secondary_ciu2(void) · 1443 unmodified lines | ||
| 1444 | 1444 | static int __init octeon_irq_init_ciu( |
| 1445 | 1445 | struct device_node *ciu_node, struct device_node *parent) |
| 1446 | 1446 | { |
| 1447 | − unsigned int i, r; | |
| 1447 | + int i, r; | |
| 1448 | 1448 | struct irq_chip *chip; |
| 1449 | 1449 | struct irq_chip *chip_edge; |
| 1450 | 1450 | struct irq_chip *chip_mbox; |
| @@ -6,7 +6,6 @@ generated-y += syscall_table_64_n64.h · 5 unmodified lines | ||
| 6 | 6 | generated-y += syscall_table_64_o32.h |
| 7 | 7 | generic-y += export.h |
| 8 | 8 | generic-y += kvm_para.h |
| 9 | −generic-y += local64.h | |
| 10 | 9 | generic-y += mcs_spinlock.h |
| 11 | 10 | generic-y += parport.h |
| 12 | 11 | generic-y += qrwlock.h |
| @@ -103,4 +103,11 @@ jiffies_to_old_timeval32(unsigned long jiffies, struct old_timeval32 *value) · 102 unmodified lines | ||
| 103 | 103 | #undef ns_to_kernel_old_timeval |
| 104 | 104 | #define ns_to_kernel_old_timeval ns_to_old_timeval32 |
| 105 | 105 | |
| 106 | +/* | |
| 107 | + * Some data types as stored in coredump. | |
| 108 | + */ | |
| 109 | +#define user_long_t compat_long_t | |
| 110 | +#define user_siginfo_t compat_siginfo_t | |
| 111 | +#define copy_siginfo_to_external copy_siginfo_to_external32 | |
| 112 | + | |
| 106 | 113 | #include "../../../fs/binfmt_elf.c" |
| @@ -106,4 +106,11 @@ jiffies_to_old_timeval32(unsigned long jiffies, struct old_timeval32 *value) · 105 unmodified lines | ||
| 106 | 106 | #undef ns_to_kernel_old_timeval |
| 107 | 107 | #define ns_to_kernel_old_timeval ns_to_old_timeval32 |
| 108 | 108 | |
| 109 | +/* | |
| 110 | + * Some data types as stored in coredump. | |
| 111 | + */ | |
| 112 | +#define user_long_t compat_long_t | |
| 113 | +#define user_siginfo_t compat_siginfo_t | |
| 114 | +#define copy_siginfo_to_external copy_siginfo_to_external32 | |
| 115 | + | |
| 109 | 116 | #include "../../../fs/binfmt_elf.c" |
| @@ -187,8 +187,14 @@ static int __init relocate_exception_table(long offset) · 186 unmodified lines | ||
| 187 | 187 | static inline __init unsigned long rotate_xor(unsigned long hash, |
| 188 | 188 | const void *area, size_t size) |
| 189 | 189 | { |
| 190 | − size_t i; | |
| 191 | − unsigned long *ptr = (unsigned long *)area; | |
| 190 | + const typeof(hash) *ptr = PTR_ALIGN(area, sizeof(hash)); | |
| 191 | + size_t diff, i; | |
| 192 | + | |
| 193 | + diff = (void *)ptr - area; | |
| 194 | + if (unlikely(size < diff + sizeof(hash))) | |
| 195 | + return hash; | |
| 196 | + | |
| 197 | + size = ALIGN_DOWN(size - diff, sizeof(hash)); | |
| 192 | 198 | |
| 193 | 199 | for (i = 0; i < size / sizeof(hash); i++) { |
| 194 | 200 | /* Rotate by odd number of bits and XOR. */ |
| @@ -4,6 +4,5 @@ generic-y += cmpxchg.h · 3 unmodified lines | ||
| 4 | 4 | generic-y += export.h |
| 5 | 5 | generic-y += gpio.h |
| 6 | 6 | generic-y += kvm_para.h |
| 7 | −generic-y += local64.h | |
| 8 | 7 | generic-y += parport.h |
| 9 | 8 | generic-y += user.h |
| @@ -1,7 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | generic-y += extable.h |
| 3 | 3 | generic-y += kvm_para.h |
| 4 | −generic-y += local64.h | |
| 5 | 4 | generic-y += mcs_spinlock.h |
| 6 | 5 | generic-y += qspinlock_types.h |
| 7 | 6 | generic-y += qspinlock.h |
| @@ -3,6 +3,5 @@ generated-y += syscall_table_32.h · 2 unmodified lines | ||
| 3 | 3 | generated-y += syscall_table_64.h |
| 4 | 4 | generated-y += syscall_table_c32.h |
| 5 | 5 | generic-y += kvm_para.h |
| 6 | −generic-y += local64.h | |
| 7 | 6 | generic-y += mcs_spinlock.h |
| 8 | 7 | generic-y += user.h |
| @@ -5,7 +5,6 @@ generated-y += syscall_table_c32.h · 4 unmodified lines | ||
| 5 | 5 | generated-y += syscall_table_spu.h |
| 6 | 6 | generic-y += export.h |
| 7 | 7 | generic-y += kvm_types.h |
| 8 | −generic-y += local64.h | |
| 9 | 8 | generic-y += mcs_spinlock.h |
| 10 | 9 | generic-y += qrwlock.h |
| 11 | 10 | generic-y += vtime.h |
| @@ -103,6 +103,8 @@ int gettimeofday_fallback(struct __kernel_old_timeval *_tv, struct timezone *_tz · 102 unmodified lines | ||
| 103 | 103 | return do_syscall_2(__NR_gettimeofday, (unsigned long)_tv, (unsigned long)_tz); |
| 104 | 104 | } |
| 105 | 105 | |
| 106 | +#ifdef __powerpc64__ | |
| 107 | + | |
| 106 | 108 | static __always_inline |
| 107 | 109 | int clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) |
| 108 | 110 | { |
| @@ -115,10 +117,22 @@ int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) · 6 unmodified lines | ||
| 115 | 117 | return do_syscall_2(__NR_clock_getres, _clkid, (unsigned long)_ts); |
| 116 | 118 | } |
| 117 | 119 | |
| 118 | −#ifdef CONFIG_VDSO32 | |
| 120 | +#else | |
| 119 | 121 | |
| 120 | 122 | #define BUILD_VDSO32 1 |
| 121 | 123 | |
| 124 | +static __always_inline | |
| 125 | +int clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) | |
| 126 | +{ | |
| 127 | + return do_syscall_2(__NR_clock_gettime64, _clkid, (unsigned long)_ts); | |
| 128 | +} | |
| 129 | + | |
| 130 | +static __always_inline | |
| 131 | +int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) | |
| 132 | +{ | |
| 133 | + return do_syscall_2(__NR_clock_getres_time64, _clkid, (unsigned long)_ts); | |
| 134 | +} | |
| 135 | + | |
| 122 | 136 | static __always_inline |
| 123 | 137 | int clock_gettime32_fallback(clockid_t _clkid, struct old_timespec32 *_ts) |
| 124 | 138 | { |
| @@ -260,10 +260,19 @@ __secondary_hold_acknowledge: · 259 unmodified lines | ||
| 260 | 260 | MachineCheck: |
| 261 | 261 | EXCEPTION_PROLOG_0 |
| 262 | 262 | #ifdef CONFIG_PPC_CHRP |
| 263 | +#ifdef CONFIG_VMAP_STACK | |
| 264 | + mtspr SPRN_SPRG_SCRATCH2,r1 | |
| 265 | + mfspr r1, SPRN_SPRG_THREAD | |
| 266 | + lwz r1, RTAS_SP(r1) | |
| 267 | + cmpwi cr1, r1, 0 | |
| 268 | + bne cr1, 7f | |
| 269 | + mfspr r1, SPRN_SPRG_SCRATCH2 | |
| 270 | +#else | |
| 263 | 271 | mfspr r11, SPRN_SPRG_THREAD |
| 264 | 272 | lwz r11, RTAS_SP(r11) |
| 265 | 273 | cmpwi cr1, r11, 0 |
| 266 | 274 | bne cr1, 7f |
| 275 | +#endif | |
| 267 | 276 | #endif /* CONFIG_PPC_CHRP */ |
| 268 | 277 | EXCEPTION_PROLOG_1 for_rtas=1 |
| 269 | 278 | 7: EXCEPTION_PROLOG_2 |
| @@ -85,7 +85,7 @@ SECTIONS · 84 unmodified lines | ||
| 85 | 85 | ALIGN_FUNCTION(); |
| 86 | 86 | #endif |
| 87 | 87 | /* careful! __ftr_alt_* sections need to be close to .text */ |
| 88 | − *(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text); | |
| 88 | + *(.text.hot .text.hot.* TEXT_MAIN .text.fixup .text.unlikely .text.unlikely.* .fixup __ftr_alt_* .ref.text); | |
| 89 | 89 | #ifdef CONFIG_PPC64 |
| 90 | 90 | *(.tramp.ftrace.text); |
| 91 | 91 | #endif |
| @@ -187,6 +187,12 @@ SECTIONS · 95 unmodified lines | ||
| 187 | 187 | .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { |
| 188 | 188 | _sinittext = .; |
| 189 | 189 | INIT_TEXT |
| 190 | + | |
| 191 | + /* | |
| 192 | + *.init.text might be RO so we must ensure this section ends on | |
| 193 | + * a page boundary. | |
| 194 | + */ | |
| 195 | + . = ALIGN(PAGE_SIZE); | |
| 190 | 196 | _einittext = .; |
| 191 | 197 | #ifdef CONFIG_PPC64 |
| 192 | 198 | *(.tramp.ftrace.init); |
| @@ -200,6 +206,8 @@ SECTIONS · 7 unmodified lines | ||
| 200 | 206 | EXIT_TEXT |
| 201 | 207 | } |
| 202 | 208 | |
| 209 | + . = ALIGN(PAGE_SIZE); | |
| 210 | + | |
| 203 | 211 | INIT_DATA_SECTION(16) |
| 204 | 212 | |
| 205 | 213 | . = ALIGN(8); |
| @@ -137,7 +137,7 @@ config PA_BITS · 136 unmodified lines | ||
| 137 | 137 | |
| 138 | 138 | config PAGE_OFFSET |
| 139 | 139 | hex |
| 140 | − default 0xC0000000 if 32BIT && MAXPHYSMEM_2GB | |
| 140 | + default 0xC0000000 if 32BIT && MAXPHYSMEM_1GB | |
| 141 | 141 | default 0x80000000 if 64BIT && !MMU |
| 142 | 142 | default 0xffffffff80000000 if 64BIT && MAXPHYSMEM_2GB |
| 143 | 143 | default 0xffffffe000000000 if 64BIT && MAXPHYSMEM_128GB |
| @@ -247,10 +247,12 @@ config MODULE_SECTIONS · 103 unmodified lines | ||
| 247 | 247 | |
| 248 | 248 | choice |
| 249 | 249 | prompt "Maximum Physical Memory" |
| 250 | − default MAXPHYSMEM_2GB if 32BIT | |
| 250 | + default MAXPHYSMEM_1GB if 32BIT | |
| 251 | 251 | default MAXPHYSMEM_2GB if 64BIT && CMODEL_MEDLOW |
| 252 | 252 | default MAXPHYSMEM_128GB if 64BIT && CMODEL_MEDANY |
| 253 | 253 | |
| 254 | + config MAXPHYSMEM_1GB | |
| 255 | + bool "1GiB" | |
| 254 | 256 | config MAXPHYSMEM_2GB |
| 255 | 257 | bool "2GiB" |
| 256 | 258 | config MAXPHYSMEM_128GB |
| @@ -88,7 +88,9 @@ · 87 unmodified lines | ||
| 88 | 88 | phy-mode = "gmii"; |
| 89 | 89 | phy-handle = <&phy0>; |
| 90 | 90 | phy0: ethernet-phy@0 { |
| 91 | + compatible = "ethernet-phy-id0007.0771"; | |
| 91 | 92 | reg = <0>; |
| 93 | + reset-gpios = <&gpio 12 GPIO_ACTIVE_LOW>; | |
| 92 | 94 | }; |
| 93 | 95 | }; |
| 94 | 96 | |
| @@ -64,6 +64,8 @@ CONFIG_HW_RANDOM=y · 63 unmodified lines | ||
| 64 | 64 | CONFIG_HW_RANDOM_VIRTIO=y |
| 65 | 65 | CONFIG_SPI=y |
| 66 | 66 | CONFIG_SPI_SIFIVE=y |
| 67 | +CONFIG_GPIOLIB=y | |
| 68 | +CONFIG_GPIO_SIFIVE=y | |
| 67 | 69 | # CONFIG_PTP_1588_CLOCK is not set |
| 68 | 70 | CONFIG_POWER_RESET=y |
| 69 | 71 | CONFIG_DRM=y |
| @@ -3,6 +3,5 @@ generic-y += early_ioremap.h · 2 unmodified lines | ||
| 3 | 3 | generic-y += extable.h |
| 4 | 4 | generic-y += flat.h |
| 5 | 5 | generic-y += kvm_para.h |
| 6 | −generic-y += local64.h | |
| 7 | 6 | generic-y += user.h |
| 8 | 7 | generic-y += vmlinux.lds.h |
| @@ -99,7 +99,6 @@ · 98 unmodified lines | ||
| 99 | 99 | | _PAGE_DIRTY) |
| 100 | 100 | |
| 101 | 101 | #define PAGE_KERNEL __pgprot(_PAGE_KERNEL) |
| 102 | −#define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL | _PAGE_EXEC) | |
| 103 | 102 | #define PAGE_KERNEL_READ __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE) |
| 104 | 103 | #define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL | _PAGE_EXEC) |
| 105 | 104 | #define PAGE_KERNEL_READ_EXEC __pgprot((_PAGE_KERNEL & ~_PAGE_WRITE) \ |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | |
| 11 | 11 | #include <linux/types.h> |
| 12 | 12 | |
| 13 | −#ifndef GENERIC_TIME_VSYSCALL | |
| 13 | +#ifndef CONFIG_GENERIC_TIME_VSYSCALL | |
| 14 | 14 | struct vdso_data { |
| 15 | 15 | }; |
| 16 | 16 | #endif |
| @@ -26,7 +26,16 @@ cache_get_priv_group(struct cacheinfo *this_leaf) · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | static struct cacheinfo *get_cacheinfo(u32 level, enum cache_type type) |
| 28 | 28 | { |
| 29 | − struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(smp_processor_id()); | |
| 29 | + /* | |
| 30 | + * Using raw_smp_processor_id() elides a preemptability check, but this | |
| 31 | + * is really indicative of a larger problem: the cacheinfo UABI assumes | |
| 32 | + * that cores have a homonogenous view of the cache hierarchy. That | |
| 33 | + * happens to be the case for the current set of RISC-V systems, but | |
| 34 | + * likely won't be true in general. Since there's no way to provide | |
| 35 | + * correct information for these systems via the current UABI we're | |
| 36 | + * just eliding the check for now. | |
| 37 | + */ | |
| 38 | + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(raw_smp_processor_id()); | |
| 30 | 39 | struct cacheinfo *this_leaf; |
| 31 | 40 | int index; |
| 32 | 41 | |
| @@ -124,15 +124,15 @@ skip_context_tracking: · 123 unmodified lines | ||
| 124 | 124 | REG_L a1, (a1) |
| 125 | 125 | jr a1 |
| 126 | 126 | 1: |
| 127 | −#ifdef CONFIG_TRACE_IRQFLAGS | |
| 128 | − call trace_hardirqs_on | |
| 129 | −#endif | |
| 130 | 127 | /* |
| 131 | 128 | * Exceptions run with interrupts enabled or disabled depending on the |
| 132 | 129 | * state of SR_PIE in m/sstatus. |
| 133 | 130 | */ |
| 134 | 131 | andi t0, s1, SR_PIE |
| 135 | 132 | beqz t0, 1f |
| 133 | +#ifdef CONFIG_TRACE_IRQFLAGS | |
| 134 | + call trace_hardirqs_on | |
| 135 | +#endif | |
| 136 | 136 | csrs CSR_STATUS, SR_IE |
| 137 | 137 | |
| 138 | 138 | 1: |
| @@ -155,6 +155,15 @@ skip_context_tracking: · 16 unmodified lines | ||
| 155 | 155 | tail do_trap_unknown |
| 156 | 156 | |
| 157 | 157 | handle_syscall: |
| 158 | +#ifdef CONFIG_RISCV_M_MODE | |
| 159 | + /* | |
| 160 | + * When running is M-Mode (no MMU config), MPIE does not get set. | |
| 161 | + * As a result, we need to force enable interrupts here because | |
| 162 | + * handle_exception did not do set SR_IE as it always sees SR_PIE | |
| 163 | + * being cleared. | |
| 164 | + */ | |
| 165 | + csrs CSR_STATUS, SR_IE | |
| 166 | +#endif | |
| 158 | 167 | #if defined(CONFIG_TRACE_IRQFLAGS) || defined(CONFIG_CONTEXT_TRACKING) |
| 159 | 168 | /* Recover a0 - a7 for system calls */ |
| 160 | 169 | REG_L a0, PT_A0(sp) |
| @@ -186,14 +195,7 @@ check_syscall_nr: · 25 unmodified lines | ||
| 186 | 195 | * Syscall number held in a7. |
| 187 | 196 | * If syscall number is above allowed value, redirect to ni_syscall. |
| 188 | 197 | */ |
| 189 | − bge a7, t0, 1f | |
| 190 | − /* | |
| 191 | − * Check if syscall is rejected by tracer, i.e., a7 == -1. | |
| 192 | − * If yes, we pretend it was executed. | |
| 193 | − */ | |
| 194 | − li t1, -1 | |
| 195 | − beq a7, t1, ret_from_syscall_rejected | |
| 196 | − blt a7, t1, 1f | |
| 198 | + bgeu a7, t0, 1f | |
| 197 | 199 | /* Call syscall */ |
| 198 | 200 | la s0, sys_call_table |
| 199 | 201 | slli t0, a7, RISCV_LGPTR |
| @@ -127,7 +127,9 @@ static void __init init_resources(void) · 126 unmodified lines | ||
| 127 | 127 | { |
| 128 | 128 | struct memblock_region *region = NULL; |
| 129 | 129 | struct resource *res = NULL; |
| 130 | − int ret = 0; | |
| 130 | + struct resource *mem_res = NULL; | |
| 131 | + size_t mem_res_sz = 0; | |
| 132 | + int ret = 0, i = 0; | |
| 131 | 133 | |
| 132 | 134 | code_res.start = __pa_symbol(_text); |
| 133 | 135 | code_res.end = __pa_symbol(_etext) - 1; |
| @@ -145,16 +147,17 @@ static void __init init_resources(void) · 11 unmodified lines | ||
| 145 | 147 | bss_res.end = __pa_symbol(__bss_stop) - 1; |
| 146 | 148 | bss_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; |
| 147 | 149 | |
| 150 | + mem_res_sz = (memblock.memory.cnt + memblock.reserved.cnt) * sizeof(*mem_res); | |
| 151 | + mem_res = memblock_alloc(mem_res_sz, SMP_CACHE_BYTES); | |
| 152 | + if (!mem_res) | |
| 153 | + panic("%s: Failed to allocate %zu bytes\n", __func__, mem_res_sz); | |
| 148 | 154 | /* |
| 149 | 155 | * Start by adding the reserved regions, if they overlap |
| 150 | 156 | * with /memory regions, insert_resource later on will take |
| 151 | 157 | * care of it. |
| 152 | 158 | */ |
| 153 | 159 | for_each_reserved_mem_region(region) { |
| 154 | − res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES); | |
| 155 | − if (!res) | |
| 156 | − panic("%s: Failed to allocate %zu bytes\n", __func__, | |
| 157 | − sizeof(struct resource)); | |
| 160 | + res = &mem_res[i++]; | |
| 158 | 161 | |
| 159 | 162 | res->name = "Reserved"; |
| 160 | 163 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; |
| @@ -171,8 +174,10 @@ static void __init init_resources(void) · 10 unmodified lines | ||
| 171 | 174 | * Ignore any other reserved regions within |
| 172 | 175 | * system memory. |
| 173 | 176 | */ |
| 174 | − if (memblock_is_memory(res->start)) | |
| 177 | + if (memblock_is_memory(res->start)) { | |
| 178 | + memblock_free((phys_addr_t) res, sizeof(struct resource)); | |
| 175 | 179 | continue; |
| 180 | + } | |
| 176 | 181 | |
| 177 | 182 | ret = add_resource(&iomem_resource, res); |
| 178 | 183 | if (ret < 0) |
| @@ -181,10 +186,7 @@ static void __init init_resources(void) · 2 unmodified lines | ||
| 181 | 186 | |
| 182 | 187 | /* Add /memory regions to the resource tree */ |
| 183 | 188 | for_each_mem_region(region) { |
| 184 | − res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES); | |
| 185 | − if (!res) | |
| 186 | − panic("%s: Failed to allocate %zu bytes\n", __func__, | |
| 187 | − sizeof(struct resource)); | |
| 189 | + res = &mem_res[i++]; | |
| 188 | 190 | |
| 189 | 191 | if (unlikely(memblock_is_nomap(region))) { |
| 190 | 192 | res->name = "Reserved"; |
| @@ -205,9 +207,9 @@ static void __init init_resources(void) · 14 unmodified lines | ||
| 205 | 207 | return; |
| 206 | 208 | |
| 207 | 209 | error: |
| 208 | − memblock_free((phys_addr_t) res, sizeof(struct resource)); | |
| 209 | 210 | /* Better an empty resource tree than an inconsistent one */ |
| 210 | 211 | release_child_resources(&iomem_resource); |
| 212 | + memblock_free((phys_addr_t) mem_res, mem_res_sz); | |
| 211 | 213 | } |
| 212 | 214 | |
| 213 | 215 | |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | #include <asm/stacktrace.h> |
| 16 | 16 | |
| 17 | −register unsigned long sp_in_global __asm__("sp"); | |
| 17 | +register const unsigned long sp_in_global __asm__("sp"); | |
| 18 | 18 | |
| 19 | 19 | #ifdef CONFIG_FRAME_POINTER |
| 20 | 20 | |
| @@ -28,9 +28,8 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, · 7 unmodified lines | ||
| 28 | 28 | sp = user_stack_pointer(regs); |
| 29 | 29 | pc = instruction_pointer(regs); |
| 30 | 30 | } else if (task == NULL || task == current) { |
| 31 | − const register unsigned long current_sp = sp_in_global; | |
| 32 | 31 | fp = (unsigned long)__builtin_frame_address(0); |
| 33 | − sp = current_sp; | |
| 32 | + sp = sp_in_global; | |
| 34 | 33 | pc = (unsigned long)walk_stackframe; |
| 35 | 34 | } else { |
| 36 | 35 | /* task blocked in __switch_to */ |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Copyright (C) 2017 SiFive |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | +#include <linux/of_clk.h> | |
| 7 | 8 | #include <linux/clocksource.h> |
| 8 | 9 | #include <linux/delay.h> |
| 9 | 10 | #include <asm/sbi.h> |
| @@ -24,6 +25,8 @@ void __init time_init(void) · 14 unmodified lines | ||
| 24 | 25 | riscv_timebase = prop; |
| 25 | 26 | |
| 26 | 27 | lpj_fine = riscv_timebase / HZ; |
| 28 | + | |
| 29 | + of_clk_init(NULL); | |
| 27 | 30 | timer_probe(); |
| 28 | 31 | } |
| 29 | 32 | |
| @@ -12,7 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/binfmts.h> |
| 13 | 13 | #include <linux/err.h> |
| 14 | 14 | #include <asm/page.h> |
| 15 | −#ifdef GENERIC_TIME_VSYSCALL | |
| 15 | +#ifdef CONFIG_GENERIC_TIME_VSYSCALL | |
| 16 | 16 | #include <vdso/datapage.h> |
| 17 | 17 | #else |
| 18 | 18 | #include <asm/vdso.h> |
| @@ -157,9 +157,10 @@ disable: · 156 unmodified lines | ||
| 157 | 157 | void __init setup_bootmem(void) |
| 158 | 158 | { |
| 159 | 159 | phys_addr_t mem_start = 0; |
| 160 | − phys_addr_t start, end = 0; | |
| 160 | + phys_addr_t start, dram_end, end = 0; | |
| 161 | 161 | phys_addr_t vmlinux_end = __pa_symbol(&_end); |
| 162 | 162 | phys_addr_t vmlinux_start = __pa_symbol(&_start); |
| 163 | + phys_addr_t max_mapped_addr = __pa(~(ulong)0); | |
| 163 | 164 | u64 i; |
| 164 | 165 | |
| 165 | 166 | /* Find the memory region containing the kernel */ |
| @@ -181,7 +182,18 @@ void __init setup_bootmem(void) · 15 unmodified lines | ||
| 181 | 182 | /* Reserve from the start of the kernel to the end of the kernel */ |
| 182 | 183 | memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); |
| 183 | 184 | |
| 184 | − max_pfn = PFN_DOWN(memblock_end_of_DRAM()); | |
| 185 | + dram_end = memblock_end_of_DRAM(); | |
| 186 | + | |
| 187 | + /* | |
| 188 | + * memblock allocator is not aware of the fact that last 4K bytes of | |
| 189 | + * the addressable memory can not be mapped because of IS_ERR_VALUE | |
| 190 | + * macro. Make sure that last 4k bytes are not usable by memblock | |
| 191 | + * if end of dram is equal to maximum addressable memory. | |
| 192 | + */ | |
| 193 | + if (max_mapped_addr == (dram_end - 1)) | |
| 194 | + memblock_set_current_limit(max_mapped_addr - 4096); | |
| 195 | + | |
| 196 | + max_pfn = PFN_DOWN(dram_end); | |
| 185 | 197 | max_low_pfn = max_pfn; |
| 186 | 198 | dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn)); |
| 187 | 199 | set_max_mapnr(max_low_pfn); |
| @@ -93,8 +93,8 @@ void __init kasan_init(void) · 92 unmodified lines | ||
| 93 | 93 | VMALLOC_END)); |
| 94 | 94 | |
| 95 | 95 | for_each_mem_range(i, &_start, &_end) { |
| 96 | − void *start = (void *)_start; | |
| 97 | − void *end = (void *)_end; | |
| 96 | + void *start = (void *)__va(_start); | |
| 97 | + void *end = (void *)__va(_end); | |
| 98 | 98 | |
| 99 | 99 | if (start >= end) |
| 100 | 100 | break; |
| @@ -54,17 +54,23 @@ config KASAN_SHADOW_OFFSET · 53 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | config S390 |
| 56 | 56 | def_bool y |
| 57 | + # | |
| 58 | + # Note: keep this list sorted alphabetically | |
| 59 | + # | |
| 60 | + imply IMA_SECURE_AND_OR_TRUSTED_BOOT | |
| 57 | 61 | select ARCH_BINFMT_ELF_STATE |
| 58 | 62 | select ARCH_HAS_DEBUG_VM_PGTABLE |
| 59 | 63 | select ARCH_HAS_DEBUG_WX |
| 60 | 64 | select ARCH_HAS_DEVMEM_IS_ALLOWED |
| 61 | 65 | select ARCH_HAS_ELF_RANDOMIZE |
| 66 | + select ARCH_HAS_FORCE_DMA_UNENCRYPTED | |
| 62 | 67 | select ARCH_HAS_FORTIFY_SOURCE |
| 63 | 68 | select ARCH_HAS_GCOV_PROFILE_ALL |
| 64 | 69 | select ARCH_HAS_GIGANTIC_PAGE |
| 65 | 70 | select ARCH_HAS_KCOV |
| 66 | 71 | select ARCH_HAS_MEM_ENCRYPT |
| 67 | 72 | select ARCH_HAS_PTE_SPECIAL |
| 73 | + select ARCH_HAS_SCALED_CPUTIME | |
| 68 | 74 | select ARCH_HAS_SET_MEMORY |
| 69 | 75 | select ARCH_HAS_STRICT_KERNEL_RWX |
| 70 | 76 | select ARCH_HAS_STRICT_MODULE_RWX |
| @@ -111,8 +117,10 @@ config S390 · 40 unmodified lines | ||
| 111 | 117 | select ARCH_WANT_IPC_PARSE_VERSION |
| 112 | 118 | select BUILDTIME_TABLE_SORT |
| 113 | 119 | select CLONE_BACKWARDS2 |
| 120 | + select CPU_NO_EFFICIENT_FFS if !HAVE_MARCH_Z9_109_FEATURES | |
| 114 | 121 | select DMA_OPS if PCI |
| 115 | 122 | select DYNAMIC_FTRACE if FUNCTION_TRACER |
| 123 | + select GENERIC_ALLOCATOR | |
| 116 | 124 | select GENERIC_CPU_AUTOPROBE |
| 117 | 125 | select GENERIC_CPU_VULNERABILITIES |
| 118 | 126 | select GENERIC_FIND_FIRST_BIT |
| @@ -126,22 +134,21 @@ config S390 · 7 unmodified lines | ||
| 126 | 134 | select HAVE_ARCH_JUMP_LABEL_RELATIVE |
| 127 | 135 | select HAVE_ARCH_KASAN |
| 128 | 136 | select HAVE_ARCH_KASAN_VMALLOC |
| 129 | − select CPU_NO_EFFICIENT_FFS if !HAVE_MARCH_Z9_109_FEATURES | |
| 130 | 137 | select HAVE_ARCH_SECCOMP_FILTER |
| 131 | 138 | select HAVE_ARCH_SOFT_DIRTY |
| 132 | 139 | select HAVE_ARCH_TRACEHOOK |
| 133 | 140 | select HAVE_ARCH_TRANSPARENT_HUGEPAGE |
| 134 | 141 | select HAVE_ARCH_VMAP_STACK |
| 135 | 142 | select HAVE_ASM_MODVERSIONS |
| 136 | − select HAVE_EBPF_JIT if PACK_STACK && HAVE_MARCH_Z196_FEATURES | |
| 137 | 143 | select HAVE_CMPXCHG_DOUBLE |
| 138 | 144 | select HAVE_CMPXCHG_LOCAL |
| 139 | 145 | select HAVE_DEBUG_KMEMLEAK |
| 140 | 146 | select HAVE_DMA_CONTIGUOUS |
| 141 | 147 | select HAVE_DYNAMIC_FTRACE |
| 142 | 148 | select HAVE_DYNAMIC_FTRACE_WITH_REGS |
| 143 | − select HAVE_FAST_GUP | |
| 149 | + select HAVE_EBPF_JIT if PACK_STACK && HAVE_MARCH_Z196_FEATURES | |
| 144 | 150 | select HAVE_EFFICIENT_UNALIGNED_ACCESS |
| 151 | + select HAVE_FAST_GUP | |
| 145 | 152 | select HAVE_FENTRY |
| 146 | 153 | select HAVE_FTRACE_MCOUNT_RECORD |
| 147 | 154 | select HAVE_FUNCTION_ERROR_INJECTION |
| @@ -163,16 +170,15 @@ config S390 · 15 unmodified lines | ||
| 163 | 170 | select HAVE_KRETPROBES |
| 164 | 171 | select HAVE_KVM |
| 165 | 172 | select HAVE_LIVEPATCH |
| 166 | − select HAVE_PERF_REGS | |
| 167 | − select HAVE_PERF_USER_STACK_DUMP | |
| 168 | 173 | select HAVE_MEMBLOCK_PHYS_MAP |
| 169 | − select MMU_GATHER_NO_GATHER | |
| 170 | 174 | select HAVE_MOD_ARCH_SPECIFIC |
| 175 | + select HAVE_NMI | |
| 171 | 176 | select HAVE_NOP_MCOUNT |
| 172 | 177 | select HAVE_OPROFILE |
| 173 | 178 | select HAVE_PCI |
| 174 | 179 | select HAVE_PERF_EVENTS |
| 175 | − select MMU_GATHER_RCU_TABLE_FREE | |
| 180 | + select HAVE_PERF_REGS | |
| 181 | + select HAVE_PERF_USER_STACK_DUMP | |
| 176 | 182 | select HAVE_REGS_AND_STACK_ACCESS_API |
| 177 | 183 | select HAVE_RELIABLE_STACKTRACE |
| 178 | 184 | select HAVE_RSEQ |
| @@ -181,6 +187,8 @@ config S390 · 2 unmodified lines | ||
| 181 | 187 | select HAVE_VIRT_CPU_ACCOUNTING_IDLE |
| 182 | 188 | select IOMMU_HELPER if PCI |
| 183 | 189 | select IOMMU_SUPPORT if PCI |
| 190 | + select MMU_GATHER_NO_GATHER | |
| 191 | + select MMU_GATHER_RCU_TABLE_FREE | |
| 184 | 192 | select MODULES_USE_ELF_RELA |
| 185 | 193 | select NEED_DMA_MAP_STATE if PCI |
| 186 | 194 | select NEED_SG_DMA_LENGTH if PCI |
| @@ -190,17 +198,12 @@ config S390 · 3 unmodified lines | ||
| 190 | 198 | select PCI_MSI if PCI |
| 191 | 199 | select PCI_MSI_ARCH_FALLBACKS if PCI_MSI |
| 192 | 200 | select SPARSE_IRQ |
| 201 | + select SWIOTLB | |
| 193 | 202 | select SYSCTL_EXCEPTION_TRACE |
| 194 | 203 | select THREAD_INFO_IN_TASK |
| 195 | 204 | select TTY |
| 196 | 205 | select VIRT_CPU_ACCOUNTING |
| 197 | − select ARCH_HAS_SCALED_CPUTIME | |
| 198 | − select HAVE_NMI | |
| 199 | − select ARCH_HAS_FORCE_DMA_UNENCRYPTED | |
| 200 | − select SWIOTLB | |
| 201 | − select GENERIC_ALLOCATOR | |
| 202 | − imply IMA_SECURE_AND_OR_TRUSTED_BOOT | |
| 203 | − | |
| 206 | + # Note: keep the above list sorted alphabetically | |
| 204 | 207 | |
| 205 | 208 | config SCHED_OMIT_FRAME_POINTER |
| 206 | 209 | def_bool y |
| @@ -61,7 +61,9 @@ CONFIG_OPROFILE=m · 60 unmodified lines | ||
| 61 | 61 | CONFIG_KPROBES=y |
| 62 | 62 | CONFIG_JUMP_LABEL=y |
| 63 | 63 | CONFIG_STATIC_KEYS_SELFTEST=y |
| 64 | +CONFIG_SECCOMP_CACHE_DEBUG=y | |
| 64 | 65 | CONFIG_LOCK_EVENT_COUNTS=y |
| 66 | +# CONFIG_GCC_PLUGINS is not set | |
| 65 | 67 | CONFIG_MODULES=y |
| 66 | 68 | CONFIG_MODULE_FORCE_LOAD=y |
| 67 | 69 | CONFIG_MODULE_UNLOAD=y |
| @@ -410,12 +412,12 @@ CONFIG_SCSI_ENCLOSURE=m · 342 unmodified lines | ||
| 410 | 412 | CONFIG_SCSI_CONSTANTS=y |
| 411 | 413 | CONFIG_SCSI_LOGGING=y |
| 412 | 414 | CONFIG_SCSI_SPI_ATTRS=m |
| 413 | −CONFIG_SCSI_FC_ATTRS=y | |
| 415 | +CONFIG_SCSI_FC_ATTRS=m | |
| 414 | 416 | CONFIG_SCSI_SAS_LIBSAS=m |
| 415 | 417 | CONFIG_SCSI_SRP_ATTRS=m |
| 416 | 418 | CONFIG_ISCSI_TCP=m |
| 417 | 419 | CONFIG_SCSI_DEBUG=m |
| 418 | −CONFIG_ZFCP=y | |
| 420 | +CONFIG_ZFCP=m | |
| 419 | 421 | CONFIG_SCSI_VIRTIO=m |
| 420 | 422 | CONFIG_SCSI_DH=y |
| 421 | 423 | CONFIG_SCSI_DH_RDAC=m |
| @@ -444,6 +446,7 @@ CONFIG_DM_MULTIPATH=m · 22 unmodified lines | ||
| 444 | 446 | CONFIG_DM_MULTIPATH_QL=m |
| 445 | 447 | CONFIG_DM_MULTIPATH_ST=m |
| 446 | 448 | CONFIG_DM_MULTIPATH_HST=m |
| 449 | +CONFIG_DM_MULTIPATH_IOA=m | |
| 447 | 450 | CONFIG_DM_DELAY=m |
| 448 | 451 | CONFIG_DM_UEVENT=y |
| 449 | 452 | CONFIG_DM_FLAKEY=m |
| @@ -542,7 +545,6 @@ CONFIG_INPUT_EVDEV=y · 92 unmodified lines | ||
| 542 | 545 | # CONFIG_INPUT_MOUSE is not set |
| 543 | 546 | # CONFIG_SERIO is not set |
| 544 | 547 | CONFIG_LEGACY_PTY_COUNT=0 |
| 545 | −CONFIG_NULL_TTY=m | |
| 546 | 548 | CONFIG_VIRTIO_CONSOLE=y |
| 547 | 549 | CONFIG_HW_RANDOM_VIRTIO=m |
| 548 | 550 | CONFIG_RAW_DRIVER=m |
| @@ -574,6 +576,7 @@ CONFIG_VIRTIO_BALLOON=m · 25 unmodified lines | ||
| 574 | 576 | CONFIG_VIRTIO_INPUT=y |
| 575 | 577 | CONFIG_VHOST_NET=m |
| 576 | 578 | CONFIG_VHOST_VSOCK=m |
| 579 | +# CONFIG_SURFACE_PLATFORMS is not set | |
| 577 | 580 | CONFIG_S390_CCW_IOMMU=y |
| 578 | 581 | CONFIG_S390_AP_IOMMU=y |
| 579 | 582 | CONFIG_EXT4_FS=y |
| @@ -655,6 +658,7 @@ CONFIG_CIFS_XATTR=y · 75 unmodified lines | ||
| 655 | 658 | CONFIG_CIFS_POSIX=y |
| 656 | 659 | # CONFIG_CIFS_DEBUG is not set |
| 657 | 660 | CONFIG_CIFS_DFS_UPCALL=y |
| 661 | +CONFIG_CIFS_SWN_UPCALL=y | |
| 658 | 662 | CONFIG_NLS_DEFAULT="utf8" |
| 659 | 663 | CONFIG_NLS_CODEPAGE_437=m |
| 660 | 664 | CONFIG_NLS_CODEPAGE_850=m |
| @@ -826,6 +830,8 @@ CONFIG_FTRACE_SYSCALLS=y · 165 unmodified lines | ||
| 826 | 830 | CONFIG_BLK_DEV_IO_TRACE=y |
| 827 | 831 | CONFIG_BPF_KPROBE_OVERRIDE=y |
| 828 | 832 | CONFIG_HIST_TRIGGERS=y |
| 833 | +CONFIG_FTRACE_STARTUP_TEST=y | |
| 834 | +# CONFIG_EVENT_TRACE_STARTUP_TEST is not set | |
| 829 | 835 | CONFIG_DEBUG_USER_ASCE=y |
| 830 | 836 | CONFIG_NOTIFIER_ERROR_INJECTION=m |
| 831 | 837 | CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m |
| @@ -58,6 +58,7 @@ CONFIG_S390_UNWIND_SELFTEST=m · 57 unmodified lines | ||
| 58 | 58 | CONFIG_OPROFILE=m |
| 59 | 59 | CONFIG_KPROBES=y |
| 60 | 60 | CONFIG_JUMP_LABEL=y |
| 61 | +# CONFIG_GCC_PLUGINS is not set | |
| 61 | 62 | CONFIG_MODULES=y |
| 62 | 63 | CONFIG_MODULE_FORCE_LOAD=y |
| 63 | 64 | CONFIG_MODULE_UNLOAD=y |
| @@ -95,7 +96,6 @@ CONFIG_ZSMALLOC_STAT=y · 31 unmodified lines | ||
| 95 | 96 | CONFIG_DEFERRED_STRUCT_PAGE_INIT=y |
| 96 | 97 | CONFIG_IDLE_PAGE_TRACKING=y |
| 97 | 98 | CONFIG_PERCPU_STATS=y |
| 98 | −CONFIG_GUP_TEST=y | |
| 99 | 99 | CONFIG_NET=y |
| 100 | 100 | CONFIG_PACKET=y |
| 101 | 101 | CONFIG_PACKET_DIAG=m |
| @@ -403,12 +403,12 @@ CONFIG_SCSI_ENCLOSURE=m · 301 unmodified lines | ||
| 403 | 403 | CONFIG_SCSI_CONSTANTS=y |
| 404 | 404 | CONFIG_SCSI_LOGGING=y |
| 405 | 405 | CONFIG_SCSI_SPI_ATTRS=m |
| 406 | −CONFIG_SCSI_FC_ATTRS=y | |
| 406 | +CONFIG_SCSI_FC_ATTRS=m | |
| 407 | 407 | CONFIG_SCSI_SAS_LIBSAS=m |
| 408 | 408 | CONFIG_SCSI_SRP_ATTRS=m |
| 409 | 409 | CONFIG_ISCSI_TCP=m |
| 410 | 410 | CONFIG_SCSI_DEBUG=m |
| 411 | −CONFIG_ZFCP=y | |
| 411 | +CONFIG_ZFCP=m | |
| 412 | 412 | CONFIG_SCSI_VIRTIO=m |
| 413 | 413 | CONFIG_SCSI_DH=y |
| 414 | 414 | CONFIG_SCSI_DH_RDAC=m |
| @@ -437,6 +437,7 @@ CONFIG_DM_MULTIPATH=m · 22 unmodified lines | ||
| 437 | 437 | CONFIG_DM_MULTIPATH_QL=m |
| 438 | 438 | CONFIG_DM_MULTIPATH_ST=m |
| 439 | 439 | CONFIG_DM_MULTIPATH_HST=m |
| 440 | +CONFIG_DM_MULTIPATH_IOA=m | |
| 440 | 441 | CONFIG_DM_DELAY=m |
| 441 | 442 | CONFIG_DM_UEVENT=y |
| 442 | 443 | CONFIG_DM_FLAKEY=m |
| @@ -536,7 +537,6 @@ CONFIG_INPUT_EVDEV=y · 93 unmodified lines | ||
| 536 | 537 | # CONFIG_INPUT_MOUSE is not set |
| 537 | 538 | # CONFIG_SERIO is not set |
| 538 | 539 | CONFIG_LEGACY_PTY_COUNT=0 |
| 539 | −CONFIG_NULL_TTY=m | |
| 540 | 540 | CONFIG_VIRTIO_CONSOLE=y |
| 541 | 541 | CONFIG_HW_RANDOM_VIRTIO=m |
| 542 | 542 | CONFIG_RAW_DRIVER=m |
| @@ -568,6 +568,7 @@ CONFIG_VIRTIO_BALLOON=m · 25 unmodified lines | ||
| 568 | 568 | CONFIG_VIRTIO_INPUT=y |
| 569 | 569 | CONFIG_VHOST_NET=m |
| 570 | 570 | CONFIG_VHOST_VSOCK=m |
| 571 | +# CONFIG_SURFACE_PLATFORMS is not set | |
| 571 | 572 | CONFIG_S390_CCW_IOMMU=y |
| 572 | 573 | CONFIG_S390_AP_IOMMU=y |
| 573 | 574 | CONFIG_EXT4_FS=y |
| @@ -645,6 +646,7 @@ CONFIG_CIFS_XATTR=y · 71 unmodified lines | ||
| 645 | 646 | CONFIG_CIFS_POSIX=y |
| 646 | 647 | # CONFIG_CIFS_DEBUG is not set |
| 647 | 648 | CONFIG_CIFS_DFS_UPCALL=y |
| 649 | +CONFIG_CIFS_SWN_UPCALL=y | |
| 648 | 650 | CONFIG_NLS_DEFAULT="utf8" |
| 649 | 651 | CONFIG_NLS_CODEPAGE_437=m |
| 650 | 652 | CONFIG_NLS_CODEPAGE_850=m |
| @@ -778,6 +780,7 @@ CONFIG_FTRACE_SYSCALLS=y · 127 unmodified lines | ||
| 778 | 780 | CONFIG_BLK_DEV_IO_TRACE=y |
| 779 | 781 | CONFIG_BPF_KPROBE_OVERRIDE=y |
| 780 | 782 | CONFIG_HIST_TRIGGERS=y |
| 783 | +CONFIG_DEBUG_USER_ASCE=y | |
| 781 | 784 | CONFIG_LKDTM=m |
| 782 | 785 | CONFIG_PERCPU_TEST=m |
| 783 | 786 | CONFIG_ATOMIC64_SELFTEST=y |
| @@ -22,6 +22,7 @@ CONFIG_CRASH_DUMP=y · 21 unmodified lines | ||
| 22 | 22 | # CONFIG_VIRTUALIZATION is not set |
| 23 | 23 | # CONFIG_S390_GUEST is not set |
| 24 | 24 | # CONFIG_SECCOMP is not set |
| 25 | +# CONFIG_GCC_PLUGINS is not set | |
| 25 | 26 | CONFIG_PARTITION_ADVANCED=y |
| 26 | 27 | CONFIG_IBM_PARTITION=y |
| 27 | 28 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set |
| @@ -58,6 +59,7 @@ CONFIG_RAW_DRIVER=y · 30 unmodified lines | ||
| 58 | 59 | # CONFIG_HID is not set |
| 59 | 60 | # CONFIG_VIRTIO_MENU is not set |
| 60 | 61 | # CONFIG_VHOST_MENU is not set |
| 62 | +# CONFIG_SURFACE_PLATFORMS is not set | |
| 61 | 63 | # CONFIG_IOMMU_SUPPORT is not set |
| 62 | 64 | # CONFIG_DNOTIFY is not set |
| 63 | 65 | # CONFIG_INOTIFY_USER is not set |
| @@ -7,5 +7,4 @@ generated-y += unistd_nr.h · 6 unmodified lines | ||
| 7 | 7 | generic-y += asm-offsets.h |
| 8 | 8 | generic-y += export.h |
| 9 | 9 | generic-y += kvm_types.h |
| 10 | −generic-y += local64.h | |
| 11 | 10 | generic-y += mcs_spinlock.h |
| @@ -1,6 +1,5 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | generated-y += syscall_table.h |
| 3 | 3 | generic-y += kvm_para.h |
| 4 | −generic-y += local64.h | |
| 5 | 4 | generic-y += mcs_spinlock.h |
| 6 | 5 | generic-y += parport.h |
| @@ -6,5 +6,4 @@ generated-y += syscall_table_64.h · 5 unmodified lines | ||
| 6 | 6 | generated-y += syscall_table_c32.h |
| 7 | 7 | generic-y += export.h |
| 8 | 8 | generic-y += kvm_para.h |
| 9 | −generic-y += local64.h | |
| 10 | 9 | generic-y += mcs_spinlock.h |
| @@ -19,6 +19,7 @@ config X86_32 · 18 unmodified lines | ||
| 19 | 19 | select KMAP_LOCAL |
| 20 | 20 | select MODULES_USE_ELF_REL |
| 21 | 21 | select OLD_SIGACTION |
| 22 | + select ARCH_SPLIT_ARG64 | |
| 22 | 23 | |
| 23 | 24 | config X86_64 |
| 24 | 25 | def_bool y |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <asm/hyperv-tlfs.h> |
| 17 | 17 | #include <asm/mshyperv.h> |
| 18 | 18 | #include <asm/idtentry.h> |
| 19 | +#include <linux/kexec.h> | |
| 19 | 20 | #include <linux/version.h> |
| 20 | 21 | #include <linux/vmalloc.h> |
| 21 | 22 | #include <linux/mm.h> |
| @@ -26,6 +27,8 @@ · 4 unmodified lines | ||
| 26 | 27 | #include <linux/syscore_ops.h> |
| 27 | 28 | #include <clocksource/hyperv_timer.h> |
| 28 | 29 | |
| 30 | +int hyperv_init_cpuhp; | |
| 31 | + | |
| 29 | 32 | void *hv_hypercall_pg; |
| 30 | 33 | EXPORT_SYMBOL_GPL(hv_hypercall_pg); |
| 31 | 34 | |
| @@ -312,6 +315,25 @@ static struct syscore_ops hv_syscore_ops = { · 280 unmodified lines | ||
| 312 | 315 | .resume = hv_resume, |
| 313 | 316 | }; |
| 314 | 317 | |
| 318 | +static void (* __initdata old_setup_percpu_clockev)(void); | |
| 319 | + | |
| 320 | +static void __init hv_stimer_setup_percpu_clockev(void) | |
| 321 | +{ | |
| 322 | + /* | |
| 323 | + * Ignore any errors in setting up stimer clockevents | |
| 324 | + * as we can run with the LAPIC timer as a fallback. | |
| 325 | + */ | |
| 326 | + (void)hv_stimer_alloc(); | |
| 327 | + | |
| 328 | + /* | |
| 329 | + * Still register the LAPIC timer, because the direct-mode STIMER is | |
| 330 | + * not supported by old versions of Hyper-V. This also allows users | |
| 331 | + * to switch to LAPIC timer via /sys, if they want to. | |
| 332 | + */ | |
| 333 | + if (old_setup_percpu_clockev) | |
| 334 | + old_setup_percpu_clockev(); | |
| 335 | +} | |
| 336 | + | |
| 315 | 337 | /* |
| 316 | 338 | * This function is to be invoked early in the boot sequence after the |
| 317 | 339 | * hypervisor has been detected. |
| @@ -390,10 +412,14 @@ void __init hyperv_init(void) · 72 unmodified lines | ||
| 390 | 412 | wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); |
| 391 | 413 | |
| 392 | 414 | /* |
| 393 | − * Ignore any errors in setting up stimer clockevents | |
| 394 | − * as we can run with the LAPIC timer as a fallback. | |
| 415 | + * hyperv_init() is called before LAPIC is initialized: see | |
| 416 | + * apic_intr_mode_init() -> x86_platform.apic_post_init() and | |
| 417 | + * apic_bsp_setup() -> setup_local_APIC(). The direct-mode STIMER | |
| 418 | + * depends on LAPIC, so hv_stimer_alloc() should be called from | |
| 419 | + * x86_init.timers.setup_percpu_clockev. | |
| 395 | 420 | */ |
| 396 | − (void)hv_stimer_alloc(); | |
| 421 | + old_setup_percpu_clockev = x86_init.timers.setup_percpu_clockev; | |
| 422 | + x86_init.timers.setup_percpu_clockev = hv_stimer_setup_percpu_clockev; | |
| 397 | 423 | |
| 398 | 424 | hv_apic_init(); |
| 399 | 425 | |
| @@ -401,6 +427,7 @@ void __init hyperv_init(void) · 1 unmodified line | ||
| 401 | 427 | |
| 402 | 428 | register_syscore_ops(&hv_syscore_ops); |
| 403 | 429 | |
| 430 | + hyperv_init_cpuhp = cpuhp; | |
| 404 | 431 | return; |
| 405 | 432 | |
| 406 | 433 | remove_cpuhp_state: |
| @@ -66,11 +66,17 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus, · 65 unmodified lines | ||
| 66 | 66 | if (!hv_hypercall_pg) |
| 67 | 67 | goto do_native; |
| 68 | 68 | |
| 69 | − if (cpumask_empty(cpus)) | |
| 70 | − return; | |
| 71 | − | |
| 72 | 69 | local_irq_save(flags); |
| 73 | 70 | |
| 71 | + /* | |
| 72 | + * Only check the mask _after_ interrupt has been disabled to avoid the | |
| 73 | + * mask changing under our feet. | |
| 74 | + */ | |
| 75 | + if (cpumask_empty(cpus)) { | |
| 76 | + local_irq_restore(flags); | |
| 77 | + return; | |
| 78 | + } | |
| 79 | + | |
| 74 | 80 | flush_pcpu = (struct hv_tlb_flush **) |
| 75 | 81 | this_cpu_ptr(hyperv_pcpu_input_arg); |
| 76 | 82 | |
| @@ -1010,9 +1010,21 @@ struct kvm_arch { · 1009 unmodified lines | ||
| 1010 | 1010 | */ |
| 1011 | 1011 | bool tdp_mmu_enabled; |
| 1012 | 1012 | |
| 1013 | − /* List of struct tdp_mmu_pages being used as roots */ | |
| 1013 | + /* | |
| 1014 | + * List of struct kvmp_mmu_pages being used as roots. | |
| 1015 | + * All struct kvm_mmu_pages in the list should have | |
| 1016 | + * tdp_mmu_page set. | |
| 1017 | + * All struct kvm_mmu_pages in the list should have a positive | |
| 1018 | + * root_count except when a thread holds the MMU lock and is removing | |
| 1019 | + * an entry from the list. | |
| 1020 | + */ | |
| 1014 | 1021 | struct list_head tdp_mmu_roots; |
| 1015 | − /* List of struct tdp_mmu_pages not being used as roots */ | |
| 1022 | + | |
| 1023 | + /* | |
| 1024 | + * List of struct kvmp_mmu_pages not being used as roots. | |
| 1025 | + * All struct kvm_mmu_pages in the list should have | |
| 1026 | + * tdp_mmu_page set and a root_count of 0. | |
| 1027 | + */ | |
| 1016 | 1028 | struct list_head tdp_mmu_pages; |
| 1017 | 1029 | }; |
| 1018 | 1030 | |
| @@ -1287,6 +1299,8 @@ struct kvm_x86_ops { · 268 unmodified lines | ||
| 1287 | 1299 | void (*migrate_timers)(struct kvm_vcpu *vcpu); |
| 1288 | 1300 | void (*msr_filter_changed)(struct kvm_vcpu *vcpu); |
| 1289 | 1301 | int (*complete_emulated_msr)(struct kvm_vcpu *vcpu, int err); |
| 1302 | + | |
| 1303 | + void (*vcpu_deliver_sipi_vector)(struct kvm_vcpu *vcpu, u8 vector); | |
| 1290 | 1304 | }; |
| 1291 | 1305 | |
| 1292 | 1306 | struct kvm_x86_nested_ops { |
| @@ -1468,6 +1482,7 @@ int kvm_fast_pio(struct kvm_vcpu *vcpu, int size, unsigned short port, int in); · 175 unmodified lines | ||
| 1468 | 1482 | int kvm_emulate_cpuid(struct kvm_vcpu *vcpu); |
| 1469 | 1483 | int kvm_emulate_halt(struct kvm_vcpu *vcpu); |
| 1470 | 1484 | int kvm_vcpu_halt(struct kvm_vcpu *vcpu); |
| 1485 | +int kvm_emulate_ap_reset_hold(struct kvm_vcpu *vcpu); | |
| 1471 | 1486 | int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu); |
| 1472 | 1487 | |
| 1473 | 1488 | void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); |
| @@ -1 +0,0 @@ | ||
| 1 | −#include <asm-generic/local64.h> | |
| @@ -74,6 +74,8 @@ static inline void hv_disable_stimer0_percpu_irq(int irq) {} · 73 unmodified lines | ||
| 74 | 74 | |
| 75 | 75 | |
| 76 | 76 | #if IS_ENABLED(CONFIG_HYPERV) |
| 77 | +extern int hyperv_init_cpuhp; | |
| 78 | + | |
| 77 | 79 | extern void *hv_hypercall_pg; |
| 78 | 80 | extern void __percpu **hyperv_pcpu_input_arg; |
| 79 | 81 | |
| @@ -135,14 +135,32 @@ static void hv_machine_shutdown(void) · 134 unmodified lines | ||
| 135 | 135 | { |
| 136 | 136 | if (kexec_in_progress && hv_kexec_handler) |
| 137 | 137 | hv_kexec_handler(); |
| 138 | + | |
| 139 | + /* | |
| 140 | + * Call hv_cpu_die() on all the CPUs, otherwise later the hypervisor | |
| 141 | + * corrupts the old VP Assist Pages and can crash the kexec kernel. | |
| 142 | + */ | |
| 143 | + if (kexec_in_progress && hyperv_init_cpuhp > 0) | |
| 144 | + cpuhp_remove_state(hyperv_init_cpuhp); | |
| 145 | + | |
| 146 | + /* The function calls stop_other_cpus(). */ | |
| 138 | 147 | native_machine_shutdown(); |
| 148 | + | |
| 149 | + /* Disable the hypercall page when there is only 1 active CPU. */ | |
| 150 | + if (kexec_in_progress) | |
| 151 | + hyperv_cleanup(); | |
| 139 | 152 | } |
| 140 | 153 | |
| 141 | 154 | static void hv_machine_crash_shutdown(struct pt_regs *regs) |
| 142 | 155 | { |
| 143 | 156 | if (hv_crash_handler) |
| 144 | 157 | hv_crash_handler(regs); |
| 158 | + | |
| 159 | + /* The function calls crash_smp_send_stop(). */ | |
| 145 | 160 | native_machine_crash_shutdown(regs); |
| 161 | + | |
| 162 | + /* Disable the hypercall page when there is only 1 active CPU. */ | |
| 163 | + hyperv_cleanup(); | |
| 146 | 164 | } |
| 147 | 165 | #endif /* CONFIG_KEXEC_CORE */ |
| 148 | 166 | #endif /* CONFIG_HYPERV */ |
| @@ -167,9 +167,6 @@ static u8 mtrr_type_lookup_variable(u64 start, u64 end, u64 *partial_end, · 166 unmodified lines | ||
| 167 | 167 | *repeat = 0; |
| 168 | 168 | *uniform = 1; |
| 169 | 169 | |
| 170 | − /* Make end inclusive instead of exclusive */ | |
| 171 | − end--; | |
| 172 | − | |
| 173 | 170 | prev_match = MTRR_TYPE_INVALID; |
| 174 | 171 | for (i = 0; i < num_var_ranges; ++i) { |
| 175 | 172 | unsigned short start_state, end_state, inclusive; |
| @@ -261,6 +258,9 @@ u8 mtrr_type_lookup(u64 start, u64 end, u8 *uniform) · 85 unmodified lines | ||
| 261 | 258 | int repeat; |
| 262 | 259 | u64 partial_end; |
| 263 | 260 | |
| 261 | + /* Make end inclusive instead of exclusive */ | |
| 262 | + end--; | |
| 263 | + | |
| 264 | 264 | if (!mtrr_state_set) |
| 265 | 265 | return MTRR_TYPE_INVALID; |
| 266 | 266 | |
| @@ -525,89 +525,70 @@ static void rdtgroup_remove(struct rdtgroup *rdtgrp) · 524 unmodified lines | ||
| 525 | 525 | kfree(rdtgrp); |
| 526 | 526 | } |
| 527 | 527 | |
| 528 | −struct task_move_callback { | |
| 529 | − struct callback_head work; | |
| 530 | − struct rdtgroup *rdtgrp; | |
| 531 | −}; | |
| 532 | − | |
| 533 | −static void move_myself(struct callback_head *head) | |
| 528 | +static void _update_task_closid_rmid(void *task) | |
| 534 | 529 | { |
| 535 | − struct task_move_callback *callback; | |
| 536 | − struct rdtgroup *rdtgrp; | |
| 537 | − | |
| 538 | − callback = container_of(head, struct task_move_callback, work); | |
| 539 | − rdtgrp = callback->rdtgrp; | |
| 540 | − | |
| 541 | 530 | /* |
| 542 | − * If resource group was deleted before this task work callback | |
| 543 | − * was invoked, then assign the task to root group and free the | |
| 544 | − * resource group. | |
| 531 | + * If the task is still current on this CPU, update PQR_ASSOC MSR. | |
| 532 | + * Otherwise, the MSR is updated when the task is scheduled in. | |
| 545 | 533 | */ |
| 546 | − if (atomic_dec_and_test(&rdtgrp->waitcount) && | |
| 547 | − (rdtgrp->flags & RDT_DELETED)) { | |
| 548 | − current->closid = 0; | |
| 549 | − current->rmid = 0; | |
| 550 | − rdtgroup_remove(rdtgrp); | |
| 551 | − } | |
| 552 | − | |
| 553 | − if (unlikely(current->flags & PF_EXITING)) | |
| 554 | − goto out; | |
| 555 | − | |
| 556 | − preempt_disable(); | |
| 557 | − /* update PQR_ASSOC MSR to make resource group go into effect */ | |
| 558 | − resctrl_sched_in(); | |
| 559 | − preempt_enable(); | |
| 534 | + if (task == current) | |
| 535 | + resctrl_sched_in(); | |
| 536 | +} | |
| 560 | 537 | |
| 561 | −out: | |
| 562 | − kfree(callback); | |
| 538 | +static void update_task_closid_rmid(struct task_struct *t) | |
| 539 | +{ | |
| 540 | + if (IS_ENABLED(CONFIG_SMP) && task_curr(t)) | |
| 541 | + smp_call_function_single(task_cpu(t), _update_task_closid_rmid, t, 1); | |
| 542 | + else | |
| 543 | + _update_task_closid_rmid(t); | |
| 563 | 544 | } |
| 564 | 545 | |
| 565 | 546 | static int __rdtgroup_move_task(struct task_struct *tsk, |
| 566 | 547 | struct rdtgroup *rdtgrp) |
| 567 | 548 | { |
| 568 | − struct task_move_callback *callback; | |
| 569 | − int ret; | |
| 570 | − | |
| 571 | − callback = kzalloc(sizeof(*callback), GFP_KERNEL); | |
| 572 | − if (!callback) | |
| 573 | − return -ENOMEM; | |
| 574 | − callback->work.func = move_myself; | |
| 575 | − callback->rdtgrp = rdtgrp; | |
| 549 | + /* If the task is already in rdtgrp, no need to move the task. */ | |
| 550 | + if ((rdtgrp->type == RDTCTRL_GROUP && tsk->closid == rdtgrp->closid && | |
| 551 | + tsk->rmid == rdtgrp->mon.rmid) || | |
| 552 | + (rdtgrp->type == RDTMON_GROUP && tsk->rmid == rdtgrp->mon.rmid && | |
| 553 | + tsk->closid == rdtgrp->mon.parent->closid)) | |
| 554 | + return 0; | |
| 576 | 555 | |
| 577 | 556 | /* |
| 578 | − * Take a refcount, so rdtgrp cannot be freed before the | |
| 579 | − * callback has been invoked. | |
| 557 | + * Set the task's closid/rmid before the PQR_ASSOC MSR can be | |
| 558 | + * updated by them. | |
| 559 | + * | |
| 560 | + * For ctrl_mon groups, move both closid and rmid. | |
| 561 | + * For monitor groups, can move the tasks only from | |
| 562 | + * their parent CTRL group. | |
| 580 | 563 | */ |
| 581 | − atomic_inc(&rdtgrp->waitcount); | |
| 582 | − ret = task_work_add(tsk, &callback->work, TWA_RESUME); | |
| 583 | − if (ret) { | |
| 584 | − /* | |
| 585 | − * Task is exiting. Drop the refcount and free the callback. | |
| 586 | − * No need to check the refcount as the group cannot be | |
| 587 | − * deleted before the write function unlocks rdtgroup_mutex. | |
| 588 | − */ | |
| 589 | − atomic_dec(&rdtgrp->waitcount); | |
| 590 | − kfree(callback); | |
| 591 | − rdt_last_cmd_puts("Task exited\n"); | |
| 592 | − } else { | |
| 593 | − /* | |
| 594 | − * For ctrl_mon groups move both closid and rmid. | |
| 595 | − * For monitor groups, can move the tasks only from | |
| 596 | − * their parent CTRL group. | |
| 597 | − */ | |
| 598 | − if (rdtgrp->type == RDTCTRL_GROUP) { | |
| 599 | − tsk->closid = rdtgrp->closid; | |
| 564 | + | |
| 565 | + if (rdtgrp->type == RDTCTRL_GROUP) { | |
| 566 | + tsk->closid = rdtgrp->closid; | |
| 567 | + tsk->rmid = rdtgrp->mon.rmid; | |
| 568 | + } else if (rdtgrp->type == RDTMON_GROUP) { | |
| 569 | + if (rdtgrp->mon.parent->closid == tsk->closid) { | |
| 600 | 570 | tsk->rmid = rdtgrp->mon.rmid; |
| 601 | − } else if (rdtgrp->type == RDTMON_GROUP) { | |
| 602 | − if (rdtgrp->mon.parent->closid == tsk->closid) { | |
| 603 | − tsk->rmid = rdtgrp->mon.rmid; | |
| 604 | − } else { | |
| 605 | − rdt_last_cmd_puts("Can't move task to different control group\n"); | |
| 606 | − ret = -EINVAL; | |
| 607 | − } | |
| 571 | + } else { | |
| 572 | + rdt_last_cmd_puts("Can't move task to different control group\n"); | |
| 573 | + return -EINVAL; | |
| 608 | 574 | } |
| 609 | 575 | } |
| 610 | − return ret; | |
| 576 | + | |
| 577 | + /* | |
| 578 | + * Ensure the task's closid and rmid are written before determining if | |
| 579 | + * the task is current that will decide if it will be interrupted. | |
| 580 | + */ | |
| 581 | + barrier(); | |
| 582 | + | |
| 583 | + /* | |
| 584 | + * By now, the task's closid and rmid are set. If the task is current | |
| 585 | + * on a CPU, the PQR_ASSOC MSR needs to be updated to make the resource | |
| 586 | + * group go into effect. If the task is not current, the MSR will be | |
| 587 | + * updated when the task is scheduled in. | |
| 588 | + */ | |
| 589 | + update_task_closid_rmid(tsk); | |
| 590 | + | |
| 591 | + return 0; | |
| 611 | 592 | } |
| 612 | 593 | |
| 613 | 594 | static bool is_closid_match(struct task_struct *t, struct rdtgroup *r) |
| @@ -305,14 +305,14 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) · 304 unmodified lines | ||
| 305 | 305 | case 0xe4: |
| 306 | 306 | case 0xe5: |
| 307 | 307 | *exitinfo |= IOIO_TYPE_IN; |
| 308 | − *exitinfo |= (u64)insn->immediate.value << 16; | |
| 308 | + *exitinfo |= (u8)insn->immediate.value << 16; | |
| 309 | 309 | break; |
| 310 | 310 | |
| 311 | 311 | /* OUT immediate opcodes */ |
| 312 | 312 | case 0xe6: |
| 313 | 313 | case 0xe7: |
| 314 | 314 | *exitinfo |= IOIO_TYPE_OUT; |
| 315 | − *exitinfo |= (u64)insn->immediate.value << 16; | |
| 315 | + *exitinfo |= (u8)insn->immediate.value << 16; | |
| 316 | 316 | break; |
| 317 | 317 | |
| 318 | 318 | /* IN register opcodes */ |
| @@ -674,7 +674,7 @@ static bool pv_eoi_get_pending(struct kvm_vcpu *vcpu) · 673 unmodified lines | ||
| 674 | 674 | (unsigned long long)vcpu->arch.pv_eoi.msr_val); |
| 675 | 675 | return false; |
| 676 | 676 | } |
| 677 | − return val & 0x1; | |
| 677 | + return val & KVM_PV_EOI_ENABLED; | |
| 678 | 678 | } |
| 679 | 679 | |
| 680 | 680 | static void pv_eoi_set_pending(struct kvm_vcpu *vcpu) |
| @@ -2898,7 +2898,7 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu) · 2217 unmodified lines | ||
| 2898 | 2898 | /* evaluate pending_events before reading the vector */ |
| 2899 | 2899 | smp_rmb(); |
| 2900 | 2900 | sipi_vector = apic->sipi_vector; |
| 2901 | − kvm_vcpu_deliver_sipi_vector(vcpu, sipi_vector); | |
| 2901 | + kvm_x86_ops.vcpu_deliver_sipi_vector(vcpu, sipi_vector); | |
| 2902 | 2902 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; |
| 2903 | 2903 | } |
| 2904 | 2904 | } |
| @@ -49,7 +49,7 @@ static inline u64 rsvd_bits(int s, int e) · 48 unmodified lines | ||
| 49 | 49 | if (e < s) |
| 50 | 50 | return 0; |
| 51 | 51 | |
| 52 | − return ((1ULL << (e - s + 1)) - 1) << s; | |
| 52 | + return ((2ULL << (e - s)) - 1) << s; | |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | 55 | void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 access_mask); |
| @@ -3493,26 +3493,25 @@ static bool mmio_info_in_cache(struct kvm_vcpu *vcpu, u64 addr, bool direct) · 3492 unmodified lines | ||
| 3493 | 3493 | * Return the level of the lowest level SPTE added to sptes. |
| 3494 | 3494 | * That SPTE may be non-present. |
| 3495 | 3495 | */ |
| 3496 | −static int get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes) | |
| 3496 | +static int get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, int *root_level) | |
| 3497 | 3497 | { |
| 3498 | 3498 | struct kvm_shadow_walk_iterator iterator; |
| 3499 | − int leaf = vcpu->arch.mmu->root_level; | |
| 3499 | + int leaf = -1; | |
| 3500 | 3500 | u64 spte; |
| 3501 | 3501 | |
| 3502 | − | |
| 3503 | 3502 | walk_shadow_page_lockless_begin(vcpu); |
| 3504 | 3503 | |
| 3505 | − for (shadow_walk_init(&iterator, vcpu, addr); | |
| 3504 | + for (shadow_walk_init(&iterator, vcpu, addr), | |
| 3505 | + *root_level = iterator.level; | |
| 3506 | 3506 | shadow_walk_okay(&iterator); |
| 3507 | 3507 | __shadow_walk_next(&iterator, spte)) { |
| 3508 | 3508 | leaf = iterator.level; |
| 3509 | 3509 | spte = mmu_spte_get_lockless(iterator.sptep); |
| 3510 | 3510 | |
| 3511 | − sptes[leaf - 1] = spte; | |
| 3511 | + sptes[leaf] = spte; | |
| 3512 | 3512 | |
| 3513 | 3513 | if (!is_shadow_present_pte(spte)) |
| 3514 | 3514 | break; |
| 3515 | − | |
| 3516 | 3515 | } |
| 3517 | 3516 | |
| 3518 | 3517 | walk_shadow_page_lockless_end(vcpu); |
| @@ -3520,14 +3519,12 @@ static int get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes) · 1 unmodified line | ||
| 3520 | 3519 | return leaf; |
| 3521 | 3520 | } |
| 3522 | 3521 | |
| 3523 | −/* return true if reserved bit is detected on spte. */ | |
| 3522 | +/* return true if reserved bit(s) are detected on a valid, non-MMIO SPTE. */ | |
| 3524 | 3523 | static bool get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr, u64 *sptep) |
| 3525 | 3524 | { |
| 3526 | − u64 sptes[PT64_ROOT_MAX_LEVEL]; | |
| 3525 | + u64 sptes[PT64_ROOT_MAX_LEVEL + 1]; | |
| 3527 | 3526 | struct rsvd_bits_validate *rsvd_check; |
| 3528 | − int root = vcpu->arch.mmu->shadow_root_level; | |
| 3529 | − int leaf; | |
| 3530 | − int level; | |
| 3527 | + int root, leaf, level; | |
| 3531 | 3528 | bool reserved = false; |
| 3532 | 3529 | |
| 3533 | 3530 | if (!VALID_PAGE(vcpu->arch.mmu->root_hpa)) { |
| @@ -3536,35 +3533,45 @@ static bool get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr, u64 *sptep) · 2 unmodified lines | ||
| 3536 | 3533 | } |
| 3537 | 3534 | |
| 3538 | 3535 | if (is_tdp_mmu_root(vcpu->kvm, vcpu->arch.mmu->root_hpa)) |
| 3539 | − leaf = kvm_tdp_mmu_get_walk(vcpu, addr, sptes); | |
| 3536 | + leaf = kvm_tdp_mmu_get_walk(vcpu, addr, sptes, &root); | |
| 3540 | 3537 | else |
| 3541 | − leaf = get_walk(vcpu, addr, sptes); | |
| 3538 | + leaf = get_walk(vcpu, addr, sptes, &root); | |
| 3539 | + | |
| 3540 | + if (unlikely(leaf < 0)) { | |
| 3541 | + *sptep = 0ull; | |
| 3542 | + return reserved; | |
| 3543 | + } | |
| 3544 | + | |
| 3545 | + *sptep = sptes[leaf]; | |
| 3546 | + | |
| 3547 | + /* | |
| 3548 | + * Skip reserved bits checks on the terminal leaf if it's not a valid | |
| 3549 | + * SPTE. Note, this also (intentionally) skips MMIO SPTEs, which, by | |
| 3550 | + * design, always have reserved bits set. The purpose of the checks is | |
| 3551 | + * to detect reserved bits on non-MMIO SPTEs. i.e. buggy SPTEs. | |
| 3552 | + */ | |
| 3553 | + if (!is_shadow_present_pte(sptes[leaf])) | |
| 3554 | + leaf++; | |
| 3542 | 3555 | |
| 3543 | 3556 | rsvd_check = &vcpu->arch.mmu->shadow_zero_check; |
| 3544 | 3557 | |
| 3545 | − for (level = root; level >= leaf; level--) { | |
| 3546 | − if (!is_shadow_present_pte(sptes[level - 1])) | |
| 3547 | − break; | |
| 3558 | + for (level = root; level >= leaf; level--) | |
| 3548 | 3559 | /* |
| 3549 | 3560 | * Use a bitwise-OR instead of a logical-OR to aggregate the |
| 3550 | 3561 | * reserved bit and EPT's invalid memtype/XWR checks to avoid |
| 3551 | 3562 | * adding a Jcc in the loop. |
| 3552 | 3563 | */ |
| 3553 | − reserved |= __is_bad_mt_xwr(rsvd_check, sptes[level - 1]) | | |
| 3554 | − __is_rsvd_bits_set(rsvd_check, sptes[level - 1], | |
| 3555 | − level); | |
| 3556 | − } | |
| 3564 | + reserved |= __is_bad_mt_xwr(rsvd_check, sptes[level]) | | |
| 3565 | + __is_rsvd_bits_set(rsvd_check, sptes[level], level); | |
| 3557 | 3566 | |
| 3558 | 3567 | if (reserved) { |
| 3559 | 3568 | pr_err("%s: detect reserved bits on spte, addr 0x%llx, dump hierarchy:\n", |
| 3560 | 3569 | __func__, addr); |
| 3561 | 3570 | for (level = root; level >= leaf; level--) |
| 3562 | 3571 | pr_err("------ spte 0x%llx level %d.\n", |
| 3563 | − sptes[level - 1], level); | |
| 3572 | + sptes[level], level); | |
| 3564 | 3573 | } |
| 3565 | 3574 | |
| 3566 | − *sptep = sptes[leaf - 1]; | |
| 3567 | − | |
| 3568 | 3575 | return reserved; |
| 3569 | 3576 | } |
| 3570 | 3577 | |
| @@ -44,7 +44,48 @@ void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm) · 43 unmodified lines | ||
| 44 | 44 | WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots)); |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | −#define for_each_tdp_mmu_root(_kvm, _root) \ | |
| 47 | +static void tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root) | |
| 48 | +{ | |
| 49 | + if (kvm_mmu_put_root(kvm, root)) | |
| 50 | + kvm_tdp_mmu_free_root(kvm, root); | |
| 51 | +} | |
| 52 | + | |
| 53 | +static inline bool tdp_mmu_next_root_valid(struct kvm *kvm, | |
| 54 | + struct kvm_mmu_page *root) | |
| 55 | +{ | |
| 56 | + lockdep_assert_held(&kvm->mmu_lock); | |
| 57 | + | |
| 58 | + if (list_entry_is_head(root, &kvm->arch.tdp_mmu_roots, link)) | |
| 59 | + return false; | |
| 60 | + | |
| 61 | + kvm_mmu_get_root(kvm, root); | |
| 62 | + return true; | |
| 63 | + | |
| 64 | +} | |
| 65 | + | |
| 66 | +static inline struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm, | |
| 67 | + struct kvm_mmu_page *root) | |
| 68 | +{ | |
| 69 | + struct kvm_mmu_page *next_root; | |
| 70 | + | |
| 71 | + next_root = list_next_entry(root, link); | |
| 72 | + tdp_mmu_put_root(kvm, root); | |
| 73 | + return next_root; | |
| 74 | +} | |
| 75 | + | |
| 76 | +/* | |
| 77 | + * Note: this iterator gets and puts references to the roots it iterates over. | |
| 78 | + * This makes it safe to release the MMU lock and yield within the loop, but | |
| 79 | + * if exiting the loop early, the caller must drop the reference to the most | |
| 80 | + * recent root. (Unless keeping a live reference is desirable.) | |
| 81 | + */ | |
| 82 | +#define for_each_tdp_mmu_root_yield_safe(_kvm, _root) \ | |
| 83 | + for (_root = list_first_entry(&_kvm->arch.tdp_mmu_roots, \ | |
| 84 | + typeof(*_root), link); \ | |
| 85 | + tdp_mmu_next_root_valid(_kvm, _root); \ | |
| 86 | + _root = tdp_mmu_next_root(_kvm, _root)) | |
| 87 | + | |
| 88 | +#define for_each_tdp_mmu_root(_kvm, _root) \ | |
| 48 | 89 | list_for_each_entry(_root, &_kvm->arch.tdp_mmu_roots, link) |
| 49 | 90 | |
| 50 | 91 | bool is_tdp_mmu_root(struct kvm *kvm, hpa_t hpa) |
| @@ -447,18 +488,9 @@ bool kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t start, gfn_t end) · 396 unmodified lines | ||
| 447 | 488 | struct kvm_mmu_page *root; |
| 448 | 489 | bool flush = false; |
| 449 | 490 | |
| 450 | − for_each_tdp_mmu_root(kvm, root) { | |
| 451 | − /* | |
| 452 | − * Take a reference on the root so that it cannot be freed if | |
| 453 | − * this thread releases the MMU lock and yields in this loop. | |
| 454 | − */ | |
| 455 | − kvm_mmu_get_root(kvm, root); | |
| 456 | − | |
| 491 | + for_each_tdp_mmu_root_yield_safe(kvm, root) | |
| 457 | 492 | flush |= zap_gfn_range(kvm, root, start, end, true); |
| 458 | 493 | |
| 459 | − kvm_mmu_put_root(kvm, root); | |
| 460 | − } | |
| 461 | − | |
| 462 | 494 | return flush; |
| 463 | 495 | } |
| 464 | 496 | |
| @@ -619,13 +651,7 @@ static int kvm_tdp_mmu_handle_hva_range(struct kvm *kvm, unsigned long start, · 154 unmodified lines | ||
| 619 | 651 | int ret = 0; |
| 620 | 652 | int as_id; |
| 621 | 653 | |
| 622 | − for_each_tdp_mmu_root(kvm, root) { | |
| 623 | − /* | |
| 624 | − * Take a reference on the root so that it cannot be freed if | |
| 625 | − * this thread releases the MMU lock and yields in this loop. | |
| 626 | − */ | |
| 627 | − kvm_mmu_get_root(kvm, root); | |
| 628 | − | |
| 654 | + for_each_tdp_mmu_root_yield_safe(kvm, root) { | |
| 629 | 655 | as_id = kvm_mmu_page_as_id(root); |
| 630 | 656 | slots = __kvm_memslots(kvm, as_id); |
| 631 | 657 | kvm_for_each_memslot(memslot, slots) { |
| @@ -647,8 +673,6 @@ static int kvm_tdp_mmu_handle_hva_range(struct kvm *kvm, unsigned long start, · 15 unmodified lines | ||
| 647 | 673 | ret |= handler(kvm, memslot, root, gfn_start, |
| 648 | 674 | gfn_end, data); |
| 649 | 675 | } |
| 650 | − | |
| 651 | − kvm_mmu_put_root(kvm, root); | |
| 652 | 676 | } |
| 653 | 677 | |
| 654 | 678 | return ret; |
| @@ -838,21 +862,13 @@ bool kvm_tdp_mmu_wrprot_slot(struct kvm *kvm, struct kvm_memory_slot *slot, · 183 unmodified lines | ||
| 838 | 862 | int root_as_id; |
| 839 | 863 | bool spte_set = false; |
| 840 | 864 | |
| 841 | − for_each_tdp_mmu_root(kvm, root) { | |
| 865 | + for_each_tdp_mmu_root_yield_safe(kvm, root) { | |
| 842 | 866 | root_as_id = kvm_mmu_page_as_id(root); |
| 843 | 867 | if (root_as_id != slot->as_id) |
| 844 | 868 | continue; |
| 845 | 869 | |
| 846 | − /* | |
| 847 | − * Take a reference on the root so that it cannot be freed if | |
| 848 | − * this thread releases the MMU lock and yields in this loop. | |
| 849 | − */ | |
| 850 | − kvm_mmu_get_root(kvm, root); | |
| 851 | − | |
| 852 | 870 | spte_set |= wrprot_gfn_range(kvm, root, slot->base_gfn, |
| 853 | 871 | slot->base_gfn + slot->npages, min_level); |
| 854 | − | |
| 855 | − kvm_mmu_put_root(kvm, root); | |
| 856 | 872 | } |
| 857 | 873 | |
| 858 | 874 | return spte_set; |
| @@ -906,21 +922,13 @@ bool kvm_tdp_mmu_clear_dirty_slot(struct kvm *kvm, struct kvm_memory_slot *slot) · 47 unmodified lines | ||
| 906 | 922 | int root_as_id; |
| 907 | 923 | bool spte_set = false; |
| 908 | 924 | |
| 909 | − for_each_tdp_mmu_root(kvm, root) { | |
| 925 | + for_each_tdp_mmu_root_yield_safe(kvm, root) { | |
| 910 | 926 | root_as_id = kvm_mmu_page_as_id(root); |
| 911 | 927 | if (root_as_id != slot->as_id) |
| 912 | 928 | continue; |
| 913 | 929 | |
| 914 | − /* | |
| 915 | − * Take a reference on the root so that it cannot be freed if | |
| 916 | − * this thread releases the MMU lock and yields in this loop. | |
| 917 | − */ | |
| 918 | − kvm_mmu_get_root(kvm, root); | |
| 919 | − | |
| 920 | 930 | spte_set |= clear_dirty_gfn_range(kvm, root, slot->base_gfn, |
| 921 | 931 | slot->base_gfn + slot->npages); |
| 922 | − | |
| 923 | − kvm_mmu_put_root(kvm, root); | |
| 924 | 932 | } |
| 925 | 933 | |
| 926 | 934 | return spte_set; |
| @@ -1029,21 +1037,13 @@ bool kvm_tdp_mmu_slot_set_dirty(struct kvm *kvm, struct kvm_memory_slot *slot) · 102 unmodified lines | ||
| 1029 | 1037 | int root_as_id; |
| 1030 | 1038 | bool spte_set = false; |
| 1031 | 1039 | |
| 1032 | − for_each_tdp_mmu_root(kvm, root) { | |
| 1040 | + for_each_tdp_mmu_root_yield_safe(kvm, root) { | |
| 1033 | 1041 | root_as_id = kvm_mmu_page_as_id(root); |
| 1034 | 1042 | if (root_as_id != slot->as_id) |
| 1035 | 1043 | continue; |
| 1036 | 1044 | |
| 1037 | − /* | |
| 1038 | − * Take a reference on the root so that it cannot be freed if | |
| 1039 | − * this thread releases the MMU lock and yields in this loop. | |
| 1040 | − */ | |
| 1041 | − kvm_mmu_get_root(kvm, root); | |
| 1042 | − | |
| 1043 | 1045 | spte_set |= set_dirty_gfn_range(kvm, root, slot->base_gfn, |
| 1044 | 1046 | slot->base_gfn + slot->npages); |
| 1045 | − | |
| 1046 | − kvm_mmu_put_root(kvm, root); | |
| 1047 | 1047 | } |
| 1048 | 1048 | return spte_set; |
| 1049 | 1049 | } |
| @@ -1089,21 +1089,13 @@ void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, · 39 unmodified lines | ||
| 1089 | 1089 | struct kvm_mmu_page *root; |
| 1090 | 1090 | int root_as_id; |
| 1091 | 1091 | |
| 1092 | − for_each_tdp_mmu_root(kvm, root) { | |
| 1092 | + for_each_tdp_mmu_root_yield_safe(kvm, root) { | |
| 1093 | 1093 | root_as_id = kvm_mmu_page_as_id(root); |
| 1094 | 1094 | if (root_as_id != slot->as_id) |
| 1095 | 1095 | continue; |
| 1096 | 1096 | |
| 1097 | − /* | |
| 1098 | − * Take a reference on the root so that it cannot be freed if | |
| 1099 | − * this thread releases the MMU lock and yields in this loop. | |
| 1100 | − */ | |
| 1101 | − kvm_mmu_get_root(kvm, root); | |
| 1102 | − | |
| 1103 | 1097 | zap_collapsible_spte_range(kvm, root, slot->base_gfn, |
| 1104 | 1098 | slot->base_gfn + slot->npages); |
| 1105 | − | |
| 1106 | − kvm_mmu_put_root(kvm, root); | |
| 1107 | 1099 | } |
| 1108 | 1100 | } |
| 1109 | 1101 | |
| @@ -1160,16 +1152,19 @@ bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, · 50 unmodified lines | ||
| 1160 | 1152 | * Return the level of the lowest level SPTE added to sptes. |
| 1161 | 1153 | * That SPTE may be non-present. |
| 1162 | 1154 | */ |
| 1163 | −int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes) | |
| 1155 | +int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, | |
| 1156 | + int *root_level) | |
| 1164 | 1157 | { |
| 1165 | 1158 | struct tdp_iter iter; |
| 1166 | 1159 | struct kvm_mmu *mmu = vcpu->arch.mmu; |
| 1167 | − int leaf = vcpu->arch.mmu->shadow_root_level; | |
| 1168 | 1160 | gfn_t gfn = addr >> PAGE_SHIFT; |
| 1161 | + int leaf = -1; | |
| 1162 | + | |
| 1163 | + *root_level = vcpu->arch.mmu->shadow_root_level; | |
| 1169 | 1164 | |
| 1170 | 1165 | tdp_mmu_for_each_pte(iter, mmu, gfn, gfn + 1) { |
| 1171 | 1166 | leaf = iter.level; |
| 1172 | − sptes[leaf - 1] = iter.old_spte; | |
| 1167 | + sptes[leaf] = iter.old_spte; | |
| 1173 | 1168 | } |
| 1174 | 1169 | |
| 1175 | 1170 | return leaf; |
| @@ -44,5 +44,7 @@ void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, · 43 unmodified lines | ||
| 44 | 44 | bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, |
| 45 | 45 | struct kvm_memory_slot *slot, gfn_t gfn); |
| 46 | 46 | |
| 47 | −int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes); | |
| 47 | +int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, | |
| 48 | + int *root_level); | |
| 49 | + | |
| 48 | 50 | #endif /* __KVM_X86_MMU_TDP_MMU_H */ |
| @@ -199,6 +199,7 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) · 198 unmodified lines | ||
| 199 | 199 | static bool svm_get_nested_state_pages(struct kvm_vcpu *vcpu) |
| 200 | 200 | { |
| 201 | 201 | struct vcpu_svm *svm = to_svm(vcpu); |
| 202 | + | |
| 202 | 203 | if (!nested_svm_vmrun_msrpm(svm)) { |
| 203 | 204 | vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; |
| 204 | 205 | vcpu->run->internal.suberror = |
| @@ -595,6 +596,8 @@ int nested_svm_vmexit(struct vcpu_svm *svm) · 390 unmodified lines | ||
| 595 | 596 | svm->nested.vmcb12_gpa = 0; |
| 596 | 597 | WARN_ON_ONCE(svm->nested.nested_run_pending); |
| 597 | 598 | |
| 599 | + kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, &svm->vcpu); | |
| 600 | + | |
| 598 | 601 | /* in case we halted in L2 */ |
| 599 | 602 | svm->vcpu.arch.mp_state = KVM_MP_STATE_RUNNABLE; |
| 600 | 603 | |
| @@ -754,6 +757,7 @@ void svm_leave_nested(struct vcpu_svm *svm) · 153 unmodified lines | ||
| 754 | 757 | leave_guest_mode(&svm->vcpu); |
| 755 | 758 | copy_vmcb_control_area(&vmcb->control, &hsave->control); |
| 756 | 759 | nested_svm_uninit_mmu_context(&svm->vcpu); |
| 760 | + vmcb_mark_all_dirty(svm->vmcb); | |
| 757 | 761 | } |
| 758 | 762 | |
| 759 | 763 | kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, &svm->vcpu); |
| @@ -1194,6 +1198,10 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, · 434 unmodified lines | ||
| 1194 | 1198 | * in the registers, the save area of the nested state instead |
| 1195 | 1199 | * contains saved L1 state. |
| 1196 | 1200 | */ |
| 1201 | + | |
| 1202 | + svm->nested.nested_run_pending = | |
| 1203 | + !!(kvm_state->flags & KVM_STATE_NESTED_RUN_PENDING); | |
| 1204 | + | |
| 1197 | 1205 | copy_vmcb_control_area(&hsave->control, &svm->vmcb->control); |
| 1198 | 1206 | hsave->save = *save; |
| 1199 | 1207 | |
| @@ -1563,6 +1563,7 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) · 1562 unmodified lines | ||
| 1563 | 1563 | goto vmgexit_err; |
| 1564 | 1564 | break; |
| 1565 | 1565 | case SVM_VMGEXIT_NMI_COMPLETE: |
| 1566 | + case SVM_VMGEXIT_AP_HLT_LOOP: | |
| 1566 | 1567 | case SVM_VMGEXIT_AP_JUMP_TABLE: |
| 1567 | 1568 | case SVM_VMGEXIT_UNSUPPORTED_EVENT: |
| 1568 | 1569 | break; |
| @@ -1888,6 +1889,9 @@ int sev_handle_vmgexit(struct vcpu_svm *svm) · 319 unmodified lines | ||
| 1888 | 1889 | case SVM_VMGEXIT_NMI_COMPLETE: |
| 1889 | 1890 | ret = svm_invoke_exit_handler(svm, SVM_EXIT_IRET); |
| 1890 | 1891 | break; |
| 1892 | + case SVM_VMGEXIT_AP_HLT_LOOP: | |
| 1893 | + ret = kvm_emulate_ap_reset_hold(&svm->vcpu); | |
| 1894 | + break; | |
| 1891 | 1895 | case SVM_VMGEXIT_AP_JUMP_TABLE: { |
| 1892 | 1896 | struct kvm_sev_info *sev = &to_kvm_svm(svm->vcpu.kvm)->sev_info; |
| 1893 | 1897 | |
| @@ -2001,7 +2005,7 @@ void sev_es_vcpu_load(struct vcpu_svm *svm, int cpu) · 107 unmodified lines | ||
| 2001 | 2005 | * of which one step is to perform a VMLOAD. Since hardware does not |
| 2002 | 2006 | * perform a VMSAVE on VMRUN, the host savearea must be updated. |
| 2003 | 2007 | */ |
| 2004 | − asm volatile(__ex("vmsave") : : "a" (__sme_page_pa(sd->save_area)) : "memory"); | |
| 2008 | + asm volatile(__ex("vmsave %0") : : "a" (__sme_page_pa(sd->save_area)) : "memory"); | |
| 2005 | 2009 | |
| 2006 | 2010 | /* |
| 2007 | 2011 | * Certain MSRs are restored on VMEXIT, only save ones that aren't |
| @@ -2040,3 +2044,21 @@ void sev_es_vcpu_put(struct vcpu_svm *svm) · 32 unmodified lines | ||
| 2040 | 2044 | wrmsrl(host_save_user_msrs[i].index, svm->host_user_msrs[i]); |
| 2041 | 2045 | } |
| 2042 | 2046 | } |
| 2047 | + | |
| 2048 | +void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector) | |
| 2049 | +{ | |
| 2050 | + struct vcpu_svm *svm = to_svm(vcpu); | |
| 2051 | + | |
| 2052 | + /* First SIPI: Use the values as initially set by the VMM */ | |
| 2053 | + if (!svm->received_first_sipi) { | |
| 2054 | + svm->received_first_sipi = true; | |
| 2055 | + return; | |
| 2056 | + } | |
| 2057 | + | |
| 2058 | + /* | |
| 2059 | + * Subsequent SIPI: Return from an AP Reset Hold VMGEXIT, where | |
| 2060 | + * the guest will set the CS and RIP. Set SW_EXIT_INFO_2 to a | |
| 2061 | + * non-zero value. | |
| 2062 | + */ | |
| 2063 | + ghcb_set_sw_exit_info_2(svm->ghcb, 1); | |
| 2064 | +} | |
| @@ -3677,8 +3677,6 @@ static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu) · 3676 unmodified lines | ||
| 3677 | 3677 | return EXIT_FASTPATH_NONE; |
| 3678 | 3678 | } |
| 3679 | 3679 | |
| 3680 | −void __svm_vcpu_run(unsigned long vmcb_pa, unsigned long *regs); | |
| 3681 | − | |
| 3682 | 3680 | static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu, |
| 3683 | 3681 | struct vcpu_svm *svm) |
| 3684 | 3682 | { |
| @@ -4384,6 +4382,14 @@ static bool svm_apic_init_signal_blocked(struct kvm_vcpu *vcpu) · 699 unmodified lines | ||
| 4384 | 4382 | (vmcb_is_intercept(&svm->vmcb->control, INTERCEPT_INIT)); |
| 4385 | 4383 | } |
| 4386 | 4384 | |
| 4385 | +static void svm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector) | |
| 4386 | +{ | |
| 4387 | + if (!sev_es_guest(vcpu->kvm)) | |
| 4388 | + return kvm_vcpu_deliver_sipi_vector(vcpu, vector); | |
| 4389 | + | |
| 4390 | + sev_vcpu_deliver_sipi_vector(vcpu, vector); | |
| 4391 | +} | |
| 4392 | + | |
| 4387 | 4393 | static void svm_vm_destroy(struct kvm *kvm) |
| 4388 | 4394 | { |
| 4389 | 4395 | avic_vm_destroy(kvm); |
| @@ -4526,6 +4532,8 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { · 136 unmodified lines | ||
| 4526 | 4532 | |
| 4527 | 4533 | .msr_filter_changed = svm_msr_filter_changed, |
| 4528 | 4534 | .complete_emulated_msr = svm_complete_emulated_msr, |
| 4535 | + | |
| 4536 | + .vcpu_deliver_sipi_vector = svm_vcpu_deliver_sipi_vector, | |
| 4529 | 4537 | }; |
| 4530 | 4538 | |
| 4531 | 4539 | static struct kvm_x86_init_ops svm_init_ops __initdata = { |
| @@ -185,6 +185,7 @@ struct vcpu_svm { · 184 unmodified lines | ||
| 185 | 185 | struct vmcb_save_area *vmsa; |
| 186 | 186 | struct ghcb *ghcb; |
| 187 | 187 | struct kvm_host_map ghcb_map; |
| 188 | + bool received_first_sipi; | |
| 188 | 189 | |
| 189 | 190 | /* SEV-ES scratch area support */ |
| 190 | 191 | void *ghcb_sa; |
| @@ -591,6 +592,7 @@ void sev_es_init_vmcb(struct vcpu_svm *svm); · 400 unmodified lines | ||
| 591 | 592 | void sev_es_create_vcpu(struct vcpu_svm *svm); |
| 592 | 593 | void sev_es_vcpu_load(struct vcpu_svm *svm, int cpu); |
| 593 | 594 | void sev_es_vcpu_put(struct vcpu_svm *svm); |
| 595 | +void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector); | |
| 594 | 596 | |
| 595 | 597 | /* vmenter.S */ |
| 596 | 598 | |
| @@ -4442,6 +4442,8 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason, · 4441 unmodified lines | ||
| 4442 | 4442 | /* trying to cancel vmlaunch/vmresume is a bug */ |
| 4443 | 4443 | WARN_ON_ONCE(vmx->nested.nested_run_pending); |
| 4444 | 4444 | |
| 4445 | + kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu); | |
| 4446 | + | |
| 4445 | 4447 | /* Service the TLB flush request for L2 before switching to L1. */ |
| 4446 | 4448 | if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) |
| 4447 | 4449 | kvm_vcpu_flush_tlb_current(vcpu); |
| @@ -7707,6 +7707,8 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { · 7706 unmodified lines | ||
| 7707 | 7707 | .msr_filter_changed = vmx_msr_filter_changed, |
| 7708 | 7708 | .complete_emulated_msr = kvm_complete_insn_gp, |
| 7709 | 7709 | .cpu_dirty_log_size = vmx_cpu_dirty_log_size, |
| 7710 | + | |
| 7711 | + .vcpu_deliver_sipi_vector = kvm_vcpu_deliver_sipi_vector, | |
| 7710 | 7712 | }; |
| 7711 | 7713 | |
| 7712 | 7714 | static __init int hardware_setup(void) |
| @@ -7976,17 +7976,22 @@ void kvm_arch_exit(void) · 7975 unmodified lines | ||
| 7976 | 7976 | kmem_cache_destroy(x86_fpu_cache); |
| 7977 | 7977 | } |
| 7978 | 7978 | |
| 7979 | −int kvm_vcpu_halt(struct kvm_vcpu *vcpu) | |
| 7979 | +static int __kvm_vcpu_halt(struct kvm_vcpu *vcpu, int state, int reason) | |
| 7980 | 7980 | { |
| 7981 | 7981 | ++vcpu->stat.halt_exits; |
| 7982 | 7982 | if (lapic_in_kernel(vcpu)) { |
| 7983 | − vcpu->arch.mp_state = KVM_MP_STATE_HALTED; | |
| 7983 | + vcpu->arch.mp_state = state; | |
| 7984 | 7984 | return 1; |
| 7985 | 7985 | } else { |
| 7986 | − vcpu->run->exit_reason = KVM_EXIT_HLT; | |
| 7986 | + vcpu->run->exit_reason = reason; | |
| 7987 | 7987 | return 0; |
| 7988 | 7988 | } |
| 7989 | 7989 | } |
| 7990 | + | |
| 7991 | +int kvm_vcpu_halt(struct kvm_vcpu *vcpu) | |
| 7992 | +{ | |
| 7993 | + return __kvm_vcpu_halt(vcpu, KVM_MP_STATE_HALTED, KVM_EXIT_HLT); | |
| 7994 | +} | |
| 7990 | 7995 | EXPORT_SYMBOL_GPL(kvm_vcpu_halt); |
| 7991 | 7996 | |
| 7992 | 7997 | int kvm_emulate_halt(struct kvm_vcpu *vcpu) |
| @@ -8000,6 +8005,14 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu) · 7 unmodified lines | ||
| 8000 | 8005 | } |
| 8001 | 8006 | EXPORT_SYMBOL_GPL(kvm_emulate_halt); |
| 8002 | 8007 | |
| 8008 | +int kvm_emulate_ap_reset_hold(struct kvm_vcpu *vcpu) | |
| 8009 | +{ | |
| 8010 | + int ret = kvm_skip_emulated_instruction(vcpu); | |
| 8011 | + | |
| 8012 | + return __kvm_vcpu_halt(vcpu, KVM_MP_STATE_AP_RESET_HOLD, KVM_EXIT_AP_RESET_HOLD) && ret; | |
| 8013 | +} | |
| 8014 | +EXPORT_SYMBOL_GPL(kvm_emulate_ap_reset_hold); | |
| 8015 | + | |
| 8003 | 8016 | #ifdef CONFIG_X86_64 |
| 8004 | 8017 | static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr, |
| 8005 | 8018 | unsigned long clock_type) |
| @@ -8789,7 +8802,9 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) · 783 unmodified lines | ||
| 8789 | 8802 | |
| 8790 | 8803 | if (kvm_request_pending(vcpu)) { |
| 8791 | 8804 | if (kvm_check_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu)) { |
| 8792 | − if (unlikely(!kvm_x86_ops.nested_ops->get_nested_state_pages(vcpu))) { | |
| 8805 | + if (WARN_ON_ONCE(!is_guest_mode(vcpu))) | |
| 8806 | + ; | |
| 8807 | + else if (unlikely(!kvm_x86_ops.nested_ops->get_nested_state_pages(vcpu))) { | |
| 8793 | 8808 | r = 0; |
| 8794 | 8809 | goto out; |
| 8795 | 8810 | } |
| @@ -9094,6 +9109,7 @@ static inline int vcpu_block(struct kvm *kvm, struct kvm_vcpu *vcpu) · 298 unmodified lines | ||
| 9094 | 9109 | kvm_apic_accept_events(vcpu); |
| 9095 | 9110 | switch(vcpu->arch.mp_state) { |
| 9096 | 9111 | case KVM_MP_STATE_HALTED: |
| 9112 | + case KVM_MP_STATE_AP_RESET_HOLD: | |
| 9097 | 9113 | vcpu->arch.pv.pv_unhalted = false; |
| 9098 | 9114 | vcpu->arch.mp_state = |
| 9099 | 9115 | KVM_MP_STATE_RUNNABLE; |
| @@ -9520,8 +9536,9 @@ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, · 420 unmodified lines | ||
| 9520 | 9536 | kvm_load_guest_fpu(vcpu); |
| 9521 | 9537 | |
| 9522 | 9538 | kvm_apic_accept_events(vcpu); |
| 9523 | − if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED && | |
| 9524 | − vcpu->arch.pv.pv_unhalted) | |
| 9539 | + if ((vcpu->arch.mp_state == KVM_MP_STATE_HALTED || | |
| 9540 | + vcpu->arch.mp_state == KVM_MP_STATE_AP_RESET_HOLD) && | |
| 9541 | + vcpu->arch.pv.pv_unhalted) | |
| 9525 | 9542 | mp_state->mp_state = KVM_MP_STATE_RUNNABLE; |
| 9526 | 9543 | else |
| 9527 | 9544 | mp_state->mp_state = vcpu->arch.mp_state; |
| @@ -10152,6 +10169,7 @@ void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector) · 624 unmodified lines | ||
| 10152 | 10169 | kvm_set_segment(vcpu, &cs, VCPU_SREG_CS); |
| 10153 | 10170 | kvm_rip_write(vcpu, 0); |
| 10154 | 10171 | } |
| 10172 | +EXPORT_SYMBOL_GPL(kvm_vcpu_deliver_sipi_vector); | |
| 10155 | 10173 | |
| 10156 | 10174 | int kvm_arch_hardware_enable(void) |
| 10157 | 10175 | { |
| @@ -829,6 +829,8 @@ int pud_free_pmd_page(pud_t *pud, unsigned long addr) · 828 unmodified lines | ||
| 829 | 829 | } |
| 830 | 830 | |
| 831 | 831 | free_page((unsigned long)pmd_sv); |
| 832 | + | |
| 833 | + pgtable_pmd_page_dtor(virt_to_page(pmd)); | |
| 832 | 834 | free_page((unsigned long)pmd); |
| 833 | 835 | |
| 834 | 836 | return 1; |
| @@ -164,10 +164,10 @@ static int xen_cpu_up_prepare_hvm(unsigned int cpu) · 163 unmodified lines | ||
| 164 | 164 | else |
| 165 | 165 | per_cpu(xen_vcpu_id, cpu) = cpu; |
| 166 | 166 | rc = xen_vcpu_setup(cpu); |
| 167 | − if (rc) | |
| 167 | + if (rc || !xen_have_vector_callback) | |
| 168 | 168 | return rc; |
| 169 | 169 | |
| 170 | − if (xen_have_vector_callback && xen_feature(XENFEAT_hvm_safe_pvclock)) | |
| 170 | + if (xen_feature(XENFEAT_hvm_safe_pvclock)) | |
| 171 | 171 | xen_setup_timer(cpu); |
| 172 | 172 | |
| 173 | 173 | rc = xen_smp_intr_init(cpu); |
| @@ -188,6 +188,8 @@ static int xen_cpu_dead_hvm(unsigned int cpu) · 14 unmodified lines | ||
| 188 | 188 | return 0; |
| 189 | 189 | } |
| 190 | 190 | |
| 191 | +static bool no_vector_callback __initdata; | |
| 192 | + | |
| 191 | 193 | static void __init xen_hvm_guest_init(void) |
| 192 | 194 | { |
| 193 | 195 | if (xen_pv_domain()) |
| @@ -207,7 +209,7 @@ static void __init xen_hvm_guest_init(void) · 13 unmodified lines | ||
| 207 | 209 | |
| 208 | 210 | xen_panic_handler_init(); |
| 209 | 211 | |
| 210 | − if (xen_feature(XENFEAT_hvm_callback_vector)) | |
| 212 | + if (!no_vector_callback && xen_feature(XENFEAT_hvm_callback_vector)) | |
| 211 | 213 | xen_have_vector_callback = 1; |
| 212 | 214 | |
| 213 | 215 | xen_hvm_smp_init(); |
| @@ -233,6 +235,13 @@ static __init int xen_parse_nopv(char *arg) · 19 unmodified lines | ||
| 233 | 235 | } |
| 234 | 236 | early_param("xen_nopv", xen_parse_nopv); |
| 235 | 237 | |
| 238 | +static __init int xen_parse_no_vector_callback(char *arg) | |
| 239 | +{ | |
| 240 | + no_vector_callback = true; | |
| 241 | + return 0; | |
| 242 | +} | |
| 243 | +early_param("xen_no_vector_callback", xen_parse_no_vector_callback); | |
| 244 | + | |
| 236 | 245 | bool __init xen_hvm_need_lapic(void) |
| 237 | 246 | { |
| 238 | 247 | if (xen_pv_domain()) |
| @@ -33,9 +33,11 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) · 32 unmodified lines | ||
| 33 | 33 | int cpu; |
| 34 | 34 | |
| 35 | 35 | native_smp_prepare_cpus(max_cpus); |
| 36 | − WARN_ON(xen_smp_intr_init(0)); | |
| 37 | 36 | |
| 38 | − xen_init_lock_cpu(0); | |
| 37 | + if (xen_have_vector_callback) { | |
| 38 | + WARN_ON(xen_smp_intr_init(0)); | |
| 39 | + xen_init_lock_cpu(0); | |
| 40 | + } | |
| 39 | 41 | |
| 40 | 42 | for_each_possible_cpu(cpu) { |
| 41 | 43 | if (cpu == 0) |
| @@ -50,9 +52,11 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) · 8 unmodified lines | ||
| 50 | 52 | static void xen_hvm_cpu_die(unsigned int cpu) |
| 51 | 53 | { |
| 52 | 54 | if (common_cpu_die(cpu) == 0) { |
| 53 | − xen_smp_intr_free(cpu); | |
| 54 | − xen_uninit_lock_cpu(cpu); | |
| 55 | − xen_teardown_timer(cpu); | |
| 55 | + if (xen_have_vector_callback) { | |
| 56 | + xen_smp_intr_free(cpu); | |
| 57 | + xen_uninit_lock_cpu(cpu); | |
| 58 | + xen_teardown_timer(cpu); | |
| 59 | + } | |
| 56 | 60 | } |
| 57 | 61 | } |
| 58 | 62 | #else |
| @@ -64,14 +68,17 @@ static void xen_hvm_cpu_die(unsigned int cpu) · 5 unmodified lines | ||
| 64 | 68 | |
| 65 | 69 | void __init xen_hvm_smp_init(void) |
| 66 | 70 | { |
| 67 | − if (!xen_have_vector_callback) | |
| 71 | + smp_ops.smp_prepare_boot_cpu = xen_hvm_smp_prepare_boot_cpu; | |
| 72 | + smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus; | |
| 73 | + smp_ops.smp_cpus_done = xen_smp_cpus_done; | |
| 74 | + smp_ops.cpu_die = xen_hvm_cpu_die; | |
| 75 | + | |
| 76 | + if (!xen_have_vector_callback) { | |
| 77 | + nopvspin = true; | |
| 68 | 78 | return; |
| 79 | + } | |
| 69 | 80 | |
| 70 | − smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus; | |
| 71 | 81 | smp_ops.smp_send_reschedule = xen_smp_send_reschedule; |
| 72 | − smp_ops.cpu_die = xen_hvm_cpu_die; | |
| 73 | 82 | smp_ops.send_call_func_ipi = xen_smp_send_call_function_ipi; |
| 74 | 83 | smp_ops.send_call_func_single_ipi = xen_smp_send_call_function_single_ipi; |
| 75 | − smp_ops.smp_prepare_boot_cpu = xen_hvm_smp_prepare_boot_cpu; | |
| 76 | − smp_ops.smp_cpus_done = xen_smp_cpus_done; | |
| 77 | 84 | } |
| @@ -2,7 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | generated-y += syscall_table.h |
| 3 | 3 | generic-y += extable.h |
| 4 | 4 | generic-y += kvm_para.h |
| 5 | −generic-y += local64.h | |
| 6 | 5 | generic-y += mcs_spinlock.h |
| 7 | 6 | generic-y += param.h |
| 8 | 7 | generic-y += qrwlock.h |
| @@ -6332,13 +6332,13 @@ static unsigned int bfq_update_depths(struct bfq_data *bfqd, · 6331 unmodified lines | ||
| 6332 | 6332 | * limit 'something'. |
| 6333 | 6333 | */ |
| 6334 | 6334 | /* no more than 50% of tags for async I/O */ |
| 6335 | − bfqd->word_depths[0][0] = max((1U << bt->sb.shift) >> 1, 1U); | |
| 6335 | + bfqd->word_depths[0][0] = max(bt->sb.depth >> 1, 1U); | |
| 6336 | 6336 | /* |
| 6337 | 6337 | * no more than 75% of tags for sync writes (25% extra tags |
| 6338 | 6338 | * w.r.t. async I/O, to prevent async I/O from starving sync |
| 6339 | 6339 | * writes) |
| 6340 | 6340 | */ |
| 6341 | − bfqd->word_depths[0][1] = max(((1U << bt->sb.shift) * 3) >> 2, 1U); | |
| 6341 | + bfqd->word_depths[0][1] = max((bt->sb.depth * 3) >> 2, 1U); | |
| 6342 | 6342 | |
| 6343 | 6343 | /* |
| 6344 | 6344 | * In-word depths in case some bfq_queue is being weight- |
| @@ -6348,9 +6348,9 @@ static unsigned int bfq_update_depths(struct bfq_data *bfqd, · 3 unmodified lines | ||
| 6348 | 6348 | * shortage. |
| 6349 | 6349 | */ |
| 6350 | 6350 | /* no more than ~18% of tags for async I/O */ |
| 6351 | − bfqd->word_depths[1][0] = max(((1U << bt->sb.shift) * 3) >> 4, 1U); | |
| 6351 | + bfqd->word_depths[1][0] = max((bt->sb.depth * 3) >> 4, 1U); | |
| 6352 | 6352 | /* no more than ~37% of tags for sync writes (~20% extra tags) */ |
| 6353 | − bfqd->word_depths[1][1] = max(((1U << bt->sb.shift) * 6) >> 4, 1U); | |
| 6353 | + bfqd->word_depths[1][1] = max((bt->sb.depth * 6) >> 4, 1U); | |
| 6354 | 6354 | |
| 6355 | 6355 | for (i = 0; i < 2; i++) |
| 6356 | 6356 | for (j = 0; j < 2; j++) |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/bio.h> |
| 19 | 19 | #include <linux/blkdev.h> |
| 20 | 20 | #include <linux/blk-mq.h> |
| 21 | +#include <linux/blk-pm.h> | |
| 21 | 22 | #include <linux/highmem.h> |
| 22 | 23 | #include <linux/mm.h> |
| 23 | 24 | #include <linux/pagemap.h> |
| @@ -424,11 +425,11 @@ EXPORT_SYMBOL(blk_cleanup_queue); · 400 unmodified lines | ||
| 424 | 425 | /** |
| 425 | 426 | * blk_queue_enter() - try to increase q->q_usage_counter |
| 426 | 427 | * @q: request queue pointer |
| 427 | − * @flags: BLK_MQ_REQ_NOWAIT and/or BLK_MQ_REQ_PREEMPT | |
| 428 | + * @flags: BLK_MQ_REQ_NOWAIT and/or BLK_MQ_REQ_PM | |
| 428 | 429 | */ |
| 429 | 430 | int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags) |
| 430 | 431 | { |
| 431 | − const bool pm = flags & BLK_MQ_REQ_PREEMPT; | |
| 432 | + const bool pm = flags & BLK_MQ_REQ_PM; | |
| 432 | 433 | |
| 433 | 434 | while (true) { |
| 434 | 435 | bool success = false; |
| @@ -440,7 +441,8 @@ int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags) · 5 unmodified lines | ||
| 440 | 441 | * responsible for ensuring that that counter is |
| 441 | 442 | * globally visible before the queue is unfrozen. |
| 442 | 443 | */ |
| 443 | − if (pm || !blk_queue_pm_only(q)) { | |
| 444 | + if ((pm && queue_rpm_status(q) != RPM_SUSPENDED) || | |
| 445 | + !blk_queue_pm_only(q)) { | |
| 444 | 446 | success = true; |
| 445 | 447 | } else { |
| 446 | 448 | percpu_ref_put(&q->q_usage_counter); |
| @@ -465,8 +467,7 @@ int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags) · 18 unmodified lines | ||
| 465 | 467 | |
| 466 | 468 | wait_event(q->mq_freeze_wq, |
| 467 | 469 | (!q->mq_freeze_depth && |
| 468 | − (pm || (blk_pm_request_resume(q), | |
| 469 | − !blk_queue_pm_only(q)))) || | |
| 470 | + blk_pm_resume_queue(pm, q)) || | |
| 470 | 471 | blk_queue_dying(q)); |
| 471 | 472 | if (blk_queue_dying(q)) |
| 472 | 473 | return -ENODEV; |
| @@ -630,7 +631,7 @@ struct request *blk_get_request(struct request_queue *q, unsigned int op, · 157 unmodified lines | ||
| 630 | 631 | struct request *req; |
| 631 | 632 | |
| 632 | 633 | WARN_ON_ONCE(op & REQ_NOWAIT); |
| 633 | − WARN_ON_ONCE(flags & ~(BLK_MQ_REQ_NOWAIT | BLK_MQ_REQ_PREEMPT)); | |
| 634 | + WARN_ON_ONCE(flags & ~(BLK_MQ_REQ_NOWAIT | BLK_MQ_REQ_PM)); | |
| 634 | 635 | |
| 635 | 636 | req = blk_mq_alloc_request(q, op, flags); |
| 636 | 637 | if (!IS_ERR(req) && q->mq_ops->initialize_rq_fn) |
| @@ -2551,8 +2551,8 @@ static void ioc_rqos_throttle(struct rq_qos *rqos, struct bio *bio) · 2550 unmodified lines | ||
| 2551 | 2551 | bool use_debt, ioc_locked; |
| 2552 | 2552 | unsigned long flags; |
| 2553 | 2553 | |
| 2554 | − /* bypass IOs if disabled or for root cgroup */ | |
| 2555 | − if (!ioc->enabled || !iocg->level) | |
| 2554 | + /* bypass IOs if disabled, still initializing, or for root cgroup */ | |
| 2555 | + if (!ioc->enabled || !iocg || !iocg->level) | |
| 2556 | 2556 | return; |
| 2557 | 2557 | |
| 2558 | 2558 | /* calculate the absolute vtime cost */ |
| @@ -2679,14 +2679,14 @@ static void ioc_rqos_merge(struct rq_qos *rqos, struct request *rq, · 120 unmodified lines | ||
| 2679 | 2679 | struct bio *bio) |
| 2680 | 2680 | { |
| 2681 | 2681 | struct ioc_gq *iocg = blkg_to_iocg(bio->bi_blkg); |
| 2682 | − struct ioc *ioc = iocg->ioc; | |
| 2682 | + struct ioc *ioc = rqos_to_ioc(rqos); | |
| 2683 | 2683 | sector_t bio_end = bio_end_sector(bio); |
| 2684 | 2684 | struct ioc_now now; |
| 2685 | 2685 | u64 vtime, abs_cost, cost; |
| 2686 | 2686 | unsigned long flags; |
| 2687 | 2687 | |
| 2688 | − /* bypass if disabled or for root cgroup */ | |
| 2689 | − if (!ioc->enabled || !iocg->level) | |
| 2688 | + /* bypass if disabled, still initializing, or for root cgroup */ | |
| 2689 | + if (!ioc->enabled || !iocg || !iocg->level) | |
| 2690 | 2690 | return; |
| 2691 | 2691 | |
| 2692 | 2692 | abs_cost = calc_vtime_cost(bio, iocg, true); |
| @@ -2863,6 +2863,12 @@ static int blk_iocost_init(struct request_queue *q) · 170 unmodified lines | ||
| 2863 | 2863 | ioc_refresh_params(ioc, true); |
| 2864 | 2864 | spin_unlock_irq(&ioc->lock); |
| 2865 | 2865 | |
| 2866 | + /* | |
| 2867 | + * rqos must be added before activation to allow iocg_pd_init() to | |
| 2868 | + * lookup the ioc from q. This means that the rqos methods may get | |
| 2869 | + * called before policy activation completion, can't assume that the | |
| 2870 | + * target bio has an iocg associated and need to test for NULL iocg. | |
| 2871 | + */ | |
| 2866 | 2872 | rq_qos_add(q, rqos); |
| 2867 | 2873 | ret = blkcg_activate_policy(q, &blkcg_policy_iocost); |
| 2868 | 2874 | if (ret) { |
| @@ -129,6 +129,7 @@ static const char *const blk_queue_flag_name[] = { · 128 unmodified lines | ||
| 129 | 129 | QUEUE_FLAG_NAME(PCI_P2PDMA), |
| 130 | 130 | QUEUE_FLAG_NAME(ZONE_RESETALL), |
| 131 | 131 | QUEUE_FLAG_NAME(RQ_ALLOC_TIME), |
| 132 | + QUEUE_FLAG_NAME(NOWAIT), | |
| 132 | 133 | }; |
| 133 | 134 | #undef QUEUE_FLAG_NAME |
| 134 | 135 | |
| @@ -245,6 +246,7 @@ static const char *const hctx_flag_name[] = { · 110 unmodified lines | ||
| 245 | 246 | HCTX_FLAG_NAME(BLOCKING), |
| 246 | 247 | HCTX_FLAG_NAME(NO_SCHED), |
| 247 | 248 | HCTX_FLAG_NAME(STACKING), |
| 249 | + HCTX_FLAG_NAME(TAG_HCTX_SHARED), | |
| 248 | 250 | }; |
| 249 | 251 | #undef HCTX_FLAG_NAME |
| 250 | 252 | |
| @@ -297,7 +299,6 @@ static const char *const rqf_name[] = { · 46 unmodified lines | ||
| 297 | 299 | RQF_NAME(MIXED_MERGE), |
| 298 | 300 | RQF_NAME(MQ_INFLIGHT), |
| 299 | 301 | RQF_NAME(DONTPREP), |
| 300 | − RQF_NAME(PREEMPT), | |
| 301 | 302 | RQF_NAME(FAILED), |
| 302 | 303 | RQF_NAME(QUIET), |
| 303 | 304 | RQF_NAME(ELVPRIV), |
| @@ -294,8 +294,8 @@ static struct request *blk_mq_rq_ctx_init(struct blk_mq_alloc_data *data, · 293 unmodified lines | ||
| 294 | 294 | rq->mq_hctx = data->hctx; |
| 295 | 295 | rq->rq_flags = 0; |
| 296 | 296 | rq->cmd_flags = data->cmd_flags; |
| 297 | − if (data->flags & BLK_MQ_REQ_PREEMPT) | |
| 298 | − rq->rq_flags |= RQF_PREEMPT; | |
| 297 | + if (data->flags & BLK_MQ_REQ_PM) | |
| 298 | + rq->rq_flags |= RQF_PM; | |
| 299 | 299 | if (blk_queue_io_stat(data->q)) |
| 300 | 300 | rq->rq_flags |= RQF_IO_STAT; |
| 301 | 301 | INIT_LIST_HEAD(&rq->queuelist); |
| @@ -67,6 +67,10 @@ int blk_pre_runtime_suspend(struct request_queue *q) · 66 unmodified lines | ||
| 67 | 67 | |
| 68 | 68 | WARN_ON_ONCE(q->rpm_status != RPM_ACTIVE); |
| 69 | 69 | |
| 70 | + spin_lock_irq(&q->queue_lock); | |
| 71 | + q->rpm_status = RPM_SUSPENDING; | |
| 72 | + spin_unlock_irq(&q->queue_lock); | |
| 73 | + | |
| 70 | 74 | /* |
| 71 | 75 | * Increase the pm_only counter before checking whether any |
| 72 | 76 | * non-PM blk_queue_enter() calls are in progress to avoid that any |
| @@ -89,15 +93,14 @@ int blk_pre_runtime_suspend(struct request_queue *q) · 16 unmodified lines | ||
| 89 | 93 | /* Switch q_usage_counter back to per-cpu mode. */ |
| 90 | 94 | blk_mq_unfreeze_queue(q); |
| 91 | 95 | |
| 92 | − spin_lock_irq(&q->queue_lock); | |
| 93 | − if (ret < 0) | |
| 96 | + if (ret < 0) { | |
| 97 | + spin_lock_irq(&q->queue_lock); | |
| 98 | + q->rpm_status = RPM_ACTIVE; | |
| 94 | 99 | pm_runtime_mark_last_busy(q->dev); |
| 95 | − else | |
| 96 | − q->rpm_status = RPM_SUSPENDING; | |
| 97 | − spin_unlock_irq(&q->queue_lock); | |
| 100 | + spin_unlock_irq(&q->queue_lock); | |
| 98 | 101 | |
| 99 | − if (ret) | |
| 100 | 102 | blk_clear_pm_only(q); |
| 103 | + } | |
| 101 | 104 | |
| 102 | 105 | return ret; |
| 103 | 106 | } |
| @@ -6,11 +6,14 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/pm_runtime.h> |
| 7 | 7 | |
| 8 | 8 | #ifdef CONFIG_PM |
| 9 | −static inline void blk_pm_request_resume(struct request_queue *q) | |
| 9 | +static inline int blk_pm_resume_queue(const bool pm, struct request_queue *q) | |
| 10 | 10 | { |
| 11 | − if (q->dev && (q->rpm_status == RPM_SUSPENDED || | |
| 12 | − q->rpm_status == RPM_SUSPENDING)) | |
| 13 | − pm_request_resume(q->dev); | |
| 11 | + if (!q->dev || !blk_queue_pm_only(q)) | |
| 12 | + return 1; /* Nothing to do */ | |
| 13 | + if (pm && q->rpm_status != RPM_SUSPENDED) | |
| 14 | + return 1; /* Request allowed */ | |
| 15 | + pm_request_resume(q->dev); | |
| 16 | + return 0; | |
| 14 | 17 | } |
| 15 | 18 | |
| 16 | 19 | static inline void blk_pm_mark_last_busy(struct request *rq) |
| @@ -44,8 +47,9 @@ static inline void blk_pm_put_request(struct request *rq) · 27 unmodified lines | ||
| 44 | 47 | --rq->q->nr_pending; |
| 45 | 48 | } |
| 46 | 49 | #else |
| 47 | −static inline void blk_pm_request_resume(struct request_queue *q) | |
| 50 | +static inline int blk_pm_resume_queue(const bool pm, struct request_queue *q) | |
| 48 | 51 | { |
| 52 | + return 1; | |
| 49 | 53 | } |
| 50 | 54 | |
| 51 | 55 | static inline void blk_pm_mark_last_busy(struct request *rq) |
| @@ -246,15 +246,18 @@ struct block_device *disk_part_iter_next(struct disk_part_iter *piter) · 245 unmodified lines | ||
| 246 | 246 | part = rcu_dereference(ptbl->part[piter->idx]); |
| 247 | 247 | if (!part) |
| 248 | 248 | continue; |
| 249 | + piter->part = bdgrab(part); | |
| 250 | + if (!piter->part) | |
| 251 | + continue; | |
| 249 | 252 | if (!bdev_nr_sectors(part) && |
| 250 | 253 | !(piter->flags & DISK_PITER_INCL_EMPTY) && |
| 251 | 254 | !(piter->flags & DISK_PITER_INCL_EMPTY_PART0 && |
| 252 | − piter->idx == 0)) | |
| 255 | + piter->idx == 0)) { | |
| 256 | + bdput(piter->part); | |
| 257 | + piter->part = NULL; | |
| 253 | 258 | continue; |
| 259 | + } | |
| 254 | 260 | |
| 255 | − piter->part = bdgrab(part); | |
| 256 | − if (!piter->part) | |
| 257 | − continue; | |
| 258 | 261 | piter->idx += inc; |
| 259 | 262 | break; |
| 260 | 263 | } |
| @@ -354,7 +354,7 @@ static uint32_t derive_pub_key(const void *pub_key, uint32_t len, uint8_t *buf) · 353 unmodified lines | ||
| 354 | 354 | memcpy(cur, e, sizeof(e)); |
| 355 | 355 | cur += sizeof(e); |
| 356 | 356 | /* Zero parameters to satisfy set_pub_key ABI. */ |
| 357 | − memset(cur, 0, SETKEY_PARAMS_SIZE); | |
| 357 | + memzero_explicit(cur, SETKEY_PARAMS_SIZE); | |
| 358 | 358 | |
| 359 | 359 | return cur - buf; |
| 360 | 360 | } |
| @@ -39,7 +39,8 @@ static int ecdh_set_secret(struct crypto_kpp *tfm, const void *buf, · 38 unmodified lines | ||
| 39 | 39 | struct ecdh params; |
| 40 | 40 | unsigned int ndigits; |
| 41 | 41 | |
| 42 | − if (crypto_ecdh_decode_key(buf, len, ¶ms) < 0) | |
| 42 | + if (crypto_ecdh_decode_key(buf, len, ¶ms) < 0 || | |
| 43 | + params.key_size > sizeof(ctx->private_key)) | |
| 43 | 44 | return -EINVAL; |
| 44 | 45 | |
| 45 | 46 | ndigits = ecdh_supported_curve(params.curve_id); |
| @@ -107,6 +107,8 @@ do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2) · 106 unmodified lines | ||
| 107 | 107 | preempt_enable(); |
| 108 | 108 | |
| 109 | 109 | // bytes/ns == GB/s, multiply by 1000 to get MB/s [not MiB/s] |
| 110 | + if (!min) | |
| 111 | + min = 1; | |
| 110 | 112 | speed = (1000 * REPS * BENCH_SIZE) / (unsigned int)ktime_to_ns(min); |
| 111 | 113 | tmpl->speed = speed; |
| 112 | 114 | |
| @@ -395,9 +395,6 @@ config ACPI_CONTAINER · 394 unmodified lines | ||
| 395 | 395 | |
| 396 | 396 | This helps support hotplug of nodes, CPUs, and memory. |
| 397 | 397 | |
| 398 | − To compile this driver as a module, choose M here: | |
| 399 | − the module will be called container. | |
| 400 | − | |
| 401 | 398 | config ACPI_HOTPLUG_MEMORY |
| 402 | 399 | bool "Memory Hotplug" |
| 403 | 400 | depends on MEMORY_HOTPLUG |
| @@ -411,9 +408,6 @@ config ACPI_HOTPLUG_MEMORY · 7 unmodified lines | ||
| 411 | 408 | removing memory devices at runtime, you need not enable |
| 412 | 409 | this driver. |
| 413 | 410 | |
| 414 | − To compile this driver as a module, choose M here: | |
| 415 | − the module will be called acpi_memhotplug. | |
| 416 | − | |
| 417 | 411 | config ACPI_HOTPLUG_IOAPIC |
| 418 | 412 | bool |
| 419 | 413 | depends on PCI |
| @@ -97,7 +97,7 @@ void acpi_scan_table_handler(u32 event, void *table, void *context); · 96 unmodified lines | ||
| 97 | 97 | extern struct list_head acpi_bus_id_list; |
| 98 | 98 | |
| 99 | 99 | struct acpi_device_bus_id { |
| 100 | − char bus_id[15]; | |
| 100 | + const char *bus_id; | |
| 101 | 101 | unsigned int instance_no; |
| 102 | 102 | struct list_head node; |
| 103 | 103 | }; |
| @@ -486,6 +486,7 @@ static void acpi_device_del(struct acpi_device *device) · 485 unmodified lines | ||
| 486 | 486 | acpi_device_bus_id->instance_no--; |
| 487 | 487 | else { |
| 488 | 488 | list_del(&acpi_device_bus_id->node); |
| 489 | + kfree_const(acpi_device_bus_id->bus_id); | |
| 489 | 490 | kfree(acpi_device_bus_id); |
| 490 | 491 | } |
| 491 | 492 | break; |
| @@ -674,7 +675,14 @@ int acpi_device_add(struct acpi_device *device, · 182 unmodified lines | ||
| 674 | 675 | } |
| 675 | 676 | if (!found) { |
| 676 | 677 | acpi_device_bus_id = new_bus_id; |
| 677 | − strcpy(acpi_device_bus_id->bus_id, acpi_device_hid(device)); | |
| 678 | + acpi_device_bus_id->bus_id = | |
| 679 | + kstrdup_const(acpi_device_hid(device), GFP_KERNEL); | |
| 680 | + if (!acpi_device_bus_id->bus_id) { | |
| 681 | + pr_err(PREFIX "Memory allocation error for bus id\n"); | |
| 682 | + result = -ENOMEM; | |
| 683 | + goto err_free_new_bus_id; | |
| 684 | + } | |
| 685 | + | |
| 678 | 686 | acpi_device_bus_id->instance_no = 0; |
| 679 | 687 | list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); |
| 680 | 688 | } |
| @@ -709,6 +717,11 @@ int acpi_device_add(struct acpi_device *device, · 28 unmodified lines | ||
| 709 | 717 | if (device->parent) |
| 710 | 718 | list_del(&device->node); |
| 711 | 719 | list_del(&device->wakeup_list); |
| 720 | + | |
| 721 | + err_free_new_bus_id: | |
| 722 | + if (!found) | |
| 723 | + kfree(new_bus_id); | |
| 724 | + | |
| 712 | 725 | mutex_unlock(&acpi_device_lock); |
| 713 | 726 | |
| 714 | 727 | err_detach: |
| @@ -105,18 +105,8 @@ static void lpi_device_get_constraints_amd(void) · 104 unmodified lines | ||
| 105 | 105 | |
| 106 | 106 | for (i = 0; i < out_obj->package.count; i++) { |
| 107 | 107 | union acpi_object *package = &out_obj->package.elements[i]; |
| 108 | − struct lpi_device_info_amd info = { }; | |
| 109 | 108 | |
| 110 | − if (package->type == ACPI_TYPE_INTEGER) { | |
| 111 | − switch (i) { | |
| 112 | − case 0: | |
| 113 | − info.revision = package->integer.value; | |
| 114 | − break; | |
| 115 | − case 1: | |
| 116 | − info.count = package->integer.value; | |
| 117 | − break; | |
| 118 | − } | |
| 119 | − } else if (package->type == ACPI_TYPE_PACKAGE) { | |
| 109 | + if (package->type == ACPI_TYPE_PACKAGE) { | |
| 120 | 110 | lpi_constraints_table = kcalloc(package->package.count, |
| 121 | 111 | sizeof(*lpi_constraints_table), |
| 122 | 112 | GFP_KERNEL); |
| @@ -135,12 +125,10 @@ static void lpi_device_get_constraints_amd(void) · 12 unmodified lines | ||
| 135 | 125 | |
| 136 | 126 | for (k = 0; k < info_obj->package.count; ++k) { |
| 137 | 127 | union acpi_object *obj = &info_obj->package.elements[k]; |
| 138 | − union acpi_object *obj_new; | |
| 139 | 128 | |
| 140 | 129 | list = &lpi_constraints_table[lpi_constraints_table_size]; |
| 141 | 130 | list->min_dstate = -1; |
| 142 | 131 | |
| 143 | − obj_new = &obj[k]; | |
| 144 | 132 | switch (k) { |
| 145 | 133 | case 0: |
| 146 | 134 | dev_info.enabled = obj->integer.value; |
| @@ -3607,7 +3607,7 @@ static int idt77252_init_one(struct pci_dev *pcidev, · 3606 unmodified lines | ||
| 3607 | 3607 | |
| 3608 | 3608 | if ((err = dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32)))) { |
| 3609 | 3609 | printk("idt77252: can't enable DMA for PCI device at %s\n", pci_name(pcidev)); |
| 3610 | − return err; | |
| 3610 | + goto err_out_disable_pdev; | |
| 3611 | 3611 | } |
| 3612 | 3612 | |
| 3613 | 3613 | card = kzalloc(sizeof(struct idt77252_dev), GFP_KERNEL); |
| @@ -4414,6 +4414,12 @@ static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) · 4413 unmodified lines | ||
| 4414 | 4414 | * |
| 4415 | 4415 | * Set the device's firmware node pointer to @fwnode, but if a secondary |
| 4416 | 4416 | * firmware node of the device is present, preserve it. |
| 4417 | + * | |
| 4418 | + * Valid fwnode cases are: | |
| 4419 | + * - primary --> secondary --> -ENODEV | |
| 4420 | + * - primary --> NULL | |
| 4421 | + * - secondary --> -ENODEV | |
| 4422 | + * - NULL | |
| 4417 | 4423 | */ |
| 4418 | 4424 | void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) |
| 4419 | 4425 | { |
| @@ -4432,8 +4438,9 @@ void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) · 12 unmodified lines | ||
| 4432 | 4438 | } else { |
| 4433 | 4439 | if (fwnode_is_primary(fn)) { |
| 4434 | 4440 | dev->fwnode = fn->secondary; |
| 4441 | + /* Set fn->secondary = NULL, so fn remains the primary fwnode */ | |
| 4435 | 4442 | if (!(parent && fn == parent->fwnode)) |
| 4436 | − fn->secondary = ERR_PTR(-ENODEV); | |
| 4443 | + fn->secondary = NULL; | |
| 4437 | 4444 | } else { |
| 4438 | 4445 | dev->fwnode = NULL; |
| 4439 | 4446 | } |
| @@ -582,8 +582,12 @@ void regmap_debugfs_init(struct regmap *map) · 581 unmodified lines | ||
| 582 | 582 | devname = dev_name(map->dev); |
| 583 | 583 | |
| 584 | 584 | if (name) { |
| 585 | − map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s", | |
| 585 | + if (!map->debugfs_name) { | |
| 586 | + map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s", | |
| 586 | 587 | devname, name); |
| 588 | + if (!map->debugfs_name) | |
| 589 | + return; | |
| 590 | + } | |
| 587 | 591 | name = map->debugfs_name; |
| 588 | 592 | } else { |
| 589 | 593 | name = devname; |
| @@ -591,9 +595,10 @@ void regmap_debugfs_init(struct regmap *map) · 1 unmodified line | ||
| 591 | 595 | |
| 592 | 596 | if (!strcmp(name, "dummy")) { |
| 593 | 597 | kfree(map->debugfs_name); |
| 594 | − | |
| 595 | 598 | map->debugfs_name = kasprintf(GFP_KERNEL, "dummy%d", |
| 596 | 599 | dummy_index); |
| 600 | + if (!map->debugfs_name) | |
| 601 | + return; | |
| 597 | 602 | name = map->debugfs_name; |
| 598 | 603 | dummy_index++; |
| 599 | 604 | } |
| @@ -445,6 +445,7 @@ config BLK_DEV_RBD · 444 unmodified lines | ||
| 445 | 445 | config BLK_DEV_RSXX |
| 446 | 446 | tristate "IBM Flash Adapter 900GB Full Height PCIe Device Driver" |
| 447 | 447 | depends on PCI |
| 448 | + select CRC32 | |
| 448 | 449 | help |
| 449 | 450 | Device driver for IBM's high speed PCIe SSD |
| 450 | 451 | storage device: Flash Adapter 900GB Full Height. |
| @@ -7,6 +7,7 @@ config BLK_DEV_RNBD_CLIENT · 6 unmodified lines | ||
| 7 | 7 | tristate "RDMA Network Block Device driver client" |
| 8 | 8 | depends on INFINIBAND_RTRS_CLIENT |
| 9 | 9 | select BLK_DEV_RNBD |
| 10 | + select SG_POOL | |
| 10 | 11 | help |
| 11 | 12 | RNBD client is a network block device driver using rdma transport. |
| 12 | 13 | |
| @@ -90,3 +90,4 @@ Kleber Souza <kleber.souza@profitbricks.com> · 89 unmodified lines | ||
| 90 | 90 | Lutz Pogrell <lutz.pogrell@cloud.ionos.com> |
| 91 | 91 | Milind Dumbare <Milind.dumbare@gmail.com> |
| 92 | 92 | Roman Penyaev <roman.penyaev@profitbricks.com> |
| 93 | +Swapnil Ingle <ingleswapnil@gmail.com> | |
| @@ -375,12 +375,19 @@ static struct rnbd_iu *rnbd_get_iu(struct rnbd_clt_session *sess, · 374 unmodified lines | ||
| 375 | 375 | init_waitqueue_head(&iu->comp.wait); |
| 376 | 376 | iu->comp.errno = INT_MAX; |
| 377 | 377 | |
| 378 | + if (sg_alloc_table(&iu->sgt, 1, GFP_KERNEL)) { | |
| 379 | + rnbd_put_permit(sess, permit); | |
| 380 | + kfree(iu); | |
| 381 | + return NULL; | |
| 382 | + } | |
| 383 | + | |
| 378 | 384 | return iu; |
| 379 | 385 | } |
| 380 | 386 | |
| 381 | 387 | static void rnbd_put_iu(struct rnbd_clt_session *sess, struct rnbd_iu *iu) |
| 382 | 388 | { |
| 383 | 389 | if (atomic_dec_and_test(&iu->refcount)) { |
| 390 | + sg_free_table(&iu->sgt); | |
| 384 | 391 | rnbd_put_permit(sess, iu->permit); |
| 385 | 392 | kfree(iu); |
| 386 | 393 | } |
| @@ -487,8 +494,6 @@ static int send_msg_close(struct rnbd_clt_dev *dev, u32 device_id, bool wait) · 100 unmodified lines | ||
| 487 | 494 | iu->buf = NULL; |
| 488 | 495 | iu->dev = dev; |
| 489 | 496 | |
| 490 | − sg_alloc_table(&iu->sgt, 1, GFP_KERNEL); | |
| 491 | − | |
| 492 | 497 | msg.hdr.type = cpu_to_le16(RNBD_MSG_CLOSE); |
| 493 | 498 | msg.device_id = cpu_to_le32(device_id); |
| 494 | 499 | |
| @@ -502,7 +507,6 @@ static int send_msg_close(struct rnbd_clt_dev *dev, u32 device_id, bool wait) · 7 unmodified lines | ||
| 502 | 507 | err = errno; |
| 503 | 508 | } |
| 504 | 509 | |
| 505 | − sg_free_table(&iu->sgt); | |
| 506 | 510 | rnbd_put_iu(sess, iu); |
| 507 | 511 | return err; |
| 508 | 512 | } |
| @@ -575,7 +579,6 @@ static int send_msg_open(struct rnbd_clt_dev *dev, bool wait) · 66 unmodified lines | ||
| 575 | 579 | iu->buf = rsp; |
| 576 | 580 | iu->dev = dev; |
| 577 | 581 | |
| 578 | − sg_alloc_table(&iu->sgt, 1, GFP_KERNEL); | |
| 579 | 582 | sg_init_one(iu->sgt.sgl, rsp, sizeof(*rsp)); |
| 580 | 583 | |
| 581 | 584 | msg.hdr.type = cpu_to_le16(RNBD_MSG_OPEN); |
| @@ -594,7 +597,6 @@ static int send_msg_open(struct rnbd_clt_dev *dev, bool wait) · 12 unmodified lines | ||
| 594 | 597 | err = errno; |
| 595 | 598 | } |
| 596 | 599 | |
| 597 | − sg_free_table(&iu->sgt); | |
| 598 | 600 | rnbd_put_iu(sess, iu); |
| 599 | 601 | return err; |
| 600 | 602 | } |
| @@ -622,8 +624,6 @@ static int send_msg_sess_info(struct rnbd_clt_session *sess, bool wait) · 21 unmodified lines | ||
| 622 | 624 | |
| 623 | 625 | iu->buf = rsp; |
| 624 | 626 | iu->sess = sess; |
| 625 | − | |
| 626 | − sg_alloc_table(&iu->sgt, 1, GFP_KERNEL); | |
| 627 | 627 | sg_init_one(iu->sgt.sgl, rsp, sizeof(*rsp)); |
| 628 | 628 | |
| 629 | 629 | msg.hdr.type = cpu_to_le16(RNBD_MSG_SESS_INFO); |
| @@ -650,7 +650,6 @@ put_iu: · 20 unmodified lines | ||
| 650 | 650 | } else { |
| 651 | 651 | err = errno; |
| 652 | 652 | } |
| 653 | − sg_free_table(&iu->sgt); | |
| 654 | 653 | rnbd_put_iu(sess, iu); |
| 655 | 654 | return err; |
| 656 | 655 | } |
| @@ -1698,7 +1697,8 @@ static void rnbd_destroy_sessions(void) · 1041 unmodified lines | ||
| 1698 | 1697 | */ |
| 1699 | 1698 | |
| 1700 | 1699 | list_for_each_entry_safe(sess, sn, &sess_list, list) { |
| 1701 | − WARN_ON(!rnbd_clt_get_sess(sess)); | |
| 1700 | + if (!rnbd_clt_get_sess(sess)) | |
| 1701 | + continue; | |
| 1702 | 1702 | close_rtrs(sess); |
| 1703 | 1703 | list_for_each_entry_safe(dev, tn, &sess->devs_list, list) { |
| 1704 | 1704 | /* |
| @@ -338,10 +338,12 @@ static int rnbd_srv_link_ev(struct rtrs_srv *rtrs, · 337 unmodified lines | ||
| 338 | 338 | |
| 339 | 339 | void rnbd_srv_sess_dev_force_close(struct rnbd_srv_sess_dev *sess_dev) |
| 340 | 340 | { |
| 341 | − mutex_lock(&sess_dev->sess->lock); | |
| 342 | − rnbd_srv_destroy_dev_session_sysfs(sess_dev); | |
| 343 | − mutex_unlock(&sess_dev->sess->lock); | |
| 341 | + struct rnbd_srv_session *sess = sess_dev->sess; | |
| 342 | + | |
| 344 | 343 | sess_dev->keep_id = true; |
| 344 | + mutex_lock(&sess->lock); | |
| 345 | + rnbd_srv_destroy_dev_session_sysfs(sess_dev); | |
| 346 | + mutex_unlock(&sess->lock); | |
| 345 | 347 | } |
| 346 | 348 | |
| 347 | 349 | static int process_msg_close(struct rtrs_srv *rtrs, |
| @@ -1256,6 +1256,8 @@ static struct tegra_clk_init_table init_table[] __initdata = { · 1255 unmodified lines | ||
| 1256 | 1256 | { TEGRA30_CLK_I2S3_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, |
| 1257 | 1257 | { TEGRA30_CLK_I2S4_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, |
| 1258 | 1258 | { TEGRA30_CLK_VIMCLK_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, |
| 1259 | + { TEGRA30_CLK_HDA, TEGRA30_CLK_PLL_P, 102000000, 0 }, | |
| 1260 | + { TEGRA30_CLK_HDA2CODEC_2X, TEGRA30_CLK_PLL_P, 48000000, 0 }, | |
| 1259 | 1261 | /* must be the last entry */ |
| 1260 | 1262 | { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 }, |
| 1261 | 1263 | }; |
| @@ -76,11 +76,6 @@ static inline int ceiling_fp(int32_t x) · 75 unmodified lines | ||
| 76 | 76 | return ret; |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | −static inline int32_t percent_fp(int percent) | |
| 80 | −{ | |
| 81 | − return div_fp(percent, 100); | |
| 82 | −} | |
| 83 | − | |
| 84 | 79 | static inline u64 mul_ext_fp(u64 x, u64 y) |
| 85 | 80 | { |
| 86 | 81 | return (x * y) >> EXT_FRAC_BITS; |
| @@ -91,11 +86,6 @@ static inline u64 div_ext_fp(u64 x, u64 y) · 4 unmodified lines | ||
| 91 | 86 | return div64_u64(x << EXT_FRAC_BITS, y); |
| 92 | 87 | } |
| 93 | 88 | |
| 94 | −static inline int32_t percent_ext_fp(int percent) | |
| 95 | −{ | |
| 96 | − return div_ext_fp(percent, 100); | |
| 97 | −} | |
| 98 | − | |
| 99 | 89 | /** |
| 100 | 90 | * struct sample - Store performance sample |
| 101 | 91 | * @core_avg_perf: Ratio of APERF/MPERF which is the actual average |
| @@ -2653,12 +2643,13 @@ static void intel_cpufreq_adjust_perf(unsigned int cpunum, · 2551 unmodified lines | ||
| 2653 | 2643 | unsigned long capacity) |
| 2654 | 2644 | { |
| 2655 | 2645 | struct cpudata *cpu = all_cpu_data[cpunum]; |
| 2646 | + u64 hwp_cap = READ_ONCE(cpu->hwp_cap_cached); | |
| 2656 | 2647 | int old_pstate = cpu->pstate.current_pstate; |
| 2657 | 2648 | int cap_pstate, min_pstate, max_pstate, target_pstate; |
| 2658 | 2649 | |
| 2659 | 2650 | update_turbo_state(); |
| 2660 | − cap_pstate = global.turbo_disabled ? cpu->pstate.max_pstate : | |
| 2661 | − cpu->pstate.turbo_pstate; | |
| 2651 | + cap_pstate = global.turbo_disabled ? HWP_GUARANTEED_PERF(hwp_cap) : | |
| 2652 | + HWP_HIGHEST_PERF(hwp_cap); | |
| 2662 | 2653 | |
| 2663 | 2654 | /* Optimization: Avoid unnecessary divisions. */ |
| 2664 | 2655 | |
| @@ -3086,7 +3077,6 @@ static int __init intel_pstate_init(void) · 421 unmodified lines | ||
| 3086 | 3077 | intel_pstate.attr = hwp_cpufreq_attrs; |
| 3087 | 3078 | intel_cpufreq.attr = hwp_cpufreq_attrs; |
| 3088 | 3079 | intel_cpufreq.flags |= CPUFREQ_NEED_UPDATE_LIMITS; |
| 3089 | − intel_cpufreq.fast_switch = NULL; | |
| 3090 | 3080 | intel_cpufreq.adjust_perf = intel_cpufreq_adjust_perf; |
| 3091 | 3081 | if (!default_driver) |
| 3092 | 3082 | default_driver = &intel_pstate; |
| @@ -878,9 +878,9 @@ static int get_transition_latency(struct powernow_k8_data *data) · 877 unmodified lines | ||
| 878 | 878 | |
| 879 | 879 | /* Take a frequency, and issue the fid/vid transition command */ |
| 880 | 880 | static int transition_frequency_fidvid(struct powernow_k8_data *data, |
| 881 | − unsigned int index) | |
| 881 | + unsigned int index, | |
| 882 | + struct cpufreq_policy *policy) | |
| 882 | 883 | { |
| 883 | − struct cpufreq_policy *policy; | |
| 884 | 884 | u32 fid = 0; |
| 885 | 885 | u32 vid = 0; |
| 886 | 886 | int res; |
| @@ -912,9 +912,6 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, · 25 unmodified lines | ||
| 912 | 912 | freqs.old = find_khz_freq_from_fid(data->currfid); |
| 913 | 913 | freqs.new = find_khz_freq_from_fid(fid); |
| 914 | 914 | |
| 915 | − policy = cpufreq_cpu_get(smp_processor_id()); | |
| 916 | − cpufreq_cpu_put(policy); | |
| 917 | − | |
| 918 | 915 | cpufreq_freq_transition_begin(policy, &freqs); |
| 919 | 916 | res = transition_fid_vid(data, fid, vid); |
| 920 | 917 | cpufreq_freq_transition_end(policy, &freqs, res); |
| @@ -969,7 +966,7 @@ static long powernowk8_target_fn(void *arg) · 48 unmodified lines | ||
| 969 | 966 | |
| 970 | 967 | powernow_k8_acpi_pst_values(data, newstate); |
| 971 | 968 | |
| 972 | − ret = transition_frequency_fidvid(data, newstate); | |
| 969 | + ret = transition_frequency_fidvid(data, newstate, pol); | |
| 973 | 970 | |
| 974 | 971 | if (ret) { |
| 975 | 972 | pr_err("transition frequency failed\n"); |
| @@ -366,6 +366,7 @@ if CRYPTO_DEV_OMAP · 365 unmodified lines | ||
| 366 | 366 | config CRYPTO_DEV_OMAP_SHAM |
| 367 | 367 | tristate "Support for OMAP MD5/SHA1/SHA2 hw accelerator" |
| 368 | 368 | depends on ARCH_OMAP2PLUS |
| 369 | + select CRYPTO_ENGINE | |
| 369 | 370 | select CRYPTO_SHA1 |
| 370 | 371 | select CRYPTO_MD5 |
| 371 | 372 | select CRYPTO_SHA256 |
| @@ -76,10 +76,6 @@ static void dma_buf_release(struct dentry *dentry) · 75 unmodified lines | ||
| 76 | 76 | |
| 77 | 77 | dmabuf->ops->release(dmabuf); |
| 78 | 78 | |
| 79 | − mutex_lock(&db_list.lock); | |
| 80 | − list_del(&dmabuf->list_node); | |
| 81 | − mutex_unlock(&db_list.lock); | |
| 82 | − | |
| 83 | 79 | if (dmabuf->resv == (struct dma_resv *)&dmabuf[1]) |
| 84 | 80 | dma_resv_fini(dmabuf->resv); |
| 85 | 81 | |
| @@ -88,6 +84,22 @@ static void dma_buf_release(struct dentry *dentry) · 2 unmodified lines | ||
| 88 | 84 | kfree(dmabuf); |
| 89 | 85 | } |
| 90 | 86 | |
| 87 | +static int dma_buf_file_release(struct inode *inode, struct file *file) | |
| 88 | +{ | |
| 89 | + struct dma_buf *dmabuf; | |
| 90 | + | |
| 91 | + if (!is_dma_buf_file(file)) | |
| 92 | + return -EINVAL; | |
| 93 | + | |
| 94 | + dmabuf = file->private_data; | |
| 95 | + | |
| 96 | + mutex_lock(&db_list.lock); | |
| 97 | + list_del(&dmabuf->list_node); | |
| 98 | + mutex_unlock(&db_list.lock); | |
| 99 | + | |
| 100 | + return 0; | |
| 101 | +} | |
| 102 | + | |
| 91 | 103 | static const struct dentry_operations dma_buf_dentry_ops = { |
| 92 | 104 | .d_dname = dmabuffs_dname, |
| 93 | 105 | .d_release = dma_buf_release, |
| @@ -413,6 +425,7 @@ static void dma_buf_show_fdinfo(struct seq_file *m, struct file *file) · 319 unmodified lines | ||
| 413 | 425 | } |
| 414 | 426 | |
| 415 | 427 | static const struct file_operations dma_buf_fops = { |
| 428 | + .release = dma_buf_file_release, | |
| 416 | 429 | .mmap = dma_buf_mmap_internal, |
| 417 | 430 | .llseek = dma_buf_llseek, |
| 418 | 431 | .poll = dma_buf_poll, |
| @@ -251,6 +251,9 @@ static void cma_heap_dma_buf_release(struct dma_buf *dmabuf) · 250 unmodified lines | ||
| 251 | 251 | buffer->vaddr = NULL; |
| 252 | 252 | } |
| 253 | 253 | |
| 254 | + /* free page list */ | |
| 255 | + kfree(buffer->pages); | |
| 256 | + /* release memory */ | |
| 254 | 257 | cma_release(cma_heap->cma, buffer->cma_pages, buffer->pagecount); |
| 255 | 258 | kfree(buffer); |
| 256 | 259 | } |
| @@ -86,12 +86,12 @@ static struct dw_edma_chunk *dw_edma_alloc_chunk(struct dw_edma_desc *desc) · 85 unmodified lines | ||
| 86 | 86 | |
| 87 | 87 | if (desc->chunk) { |
| 88 | 88 | /* Create and add new element into the linked list */ |
| 89 | − desc->chunks_alloc++; | |
| 90 | − list_add_tail(&chunk->list, &desc->chunk->list); | |
| 91 | 89 | if (!dw_edma_alloc_burst(chunk)) { |
| 92 | 90 | kfree(chunk); |
| 93 | 91 | return NULL; |
| 94 | 92 | } |
| 93 | + desc->chunks_alloc++; | |
| 94 | + list_add_tail(&chunk->list, &desc->chunk->list); | |
| 95 | 95 | } else { |
| 96 | 96 | /* List head */ |
| 97 | 97 | chunk->burst = NULL; |
| @@ -434,7 +434,7 @@ int idxd_register_driver(void) · 433 unmodified lines | ||
| 434 | 434 | return 0; |
| 435 | 435 | |
| 436 | 436 | drv_fail: |
| 437 | − for (; i > 0; i--) | |
| 437 | + while (--i >= 0) | |
| 438 | 438 | driver_unregister(&idxd_drvs[i]->drv); |
| 439 | 439 | return rc; |
| 440 | 440 | } |
| @@ -1840,7 +1840,7 @@ int idxd_register_bus_type(void) · 1399 unmodified lines | ||
| 1840 | 1840 | return 0; |
| 1841 | 1841 | |
| 1842 | 1842 | bus_err: |
| 1843 | − for (; i > 0; i--) | |
| 1843 | + while (--i >= 0) | |
| 1844 | 1844 | bus_unregister(idxd_bus_types[i]); |
| 1845 | 1845 | return rc; |
| 1846 | 1846 | } |
| @@ -1007,6 +1007,7 @@ static int mtk_hsdma_probe(struct platform_device *pdev) · 1006 unmodified lines | ||
| 1007 | 1007 | return 0; |
| 1008 | 1008 | |
| 1009 | 1009 | err_free: |
| 1010 | + mtk_hsdma_hw_deinit(hsdma); | |
| 1010 | 1011 | of_dma_controller_free(pdev->dev.of_node); |
| 1011 | 1012 | err_unregister: |
| 1012 | 1013 | dma_async_device_unregister(dd); |
| @@ -350,7 +350,7 @@ static int milbeaut_xdmac_probe(struct platform_device *pdev) · 349 unmodified lines | ||
| 350 | 350 | |
| 351 | 351 | ret = dma_async_device_register(ddev); |
| 352 | 352 | if (ret) |
| 353 | − return ret; | |
| 353 | + goto disable_xdmac; | |
| 354 | 354 | |
| 355 | 355 | ret = of_dma_controller_register(dev->of_node, |
| 356 | 356 | of_dma_simple_xlate, mdev); |
| @@ -363,6 +363,8 @@ static int milbeaut_xdmac_probe(struct platform_device *pdev) · 6 unmodified lines | ||
| 363 | 363 | |
| 364 | 364 | unregister_dmac: |
| 365 | 365 | dma_async_device_unregister(ddev); |
| 366 | +disable_xdmac: | |
| 367 | + disable_xdmac(mdev); | |
| 366 | 368 | return ret; |
| 367 | 369 | } |
| 368 | 370 | |
| @@ -630,7 +630,7 @@ static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan, · 629 unmodified lines | ||
| 630 | 630 | GFP_NOWAIT); |
| 631 | 631 | |
| 632 | 632 | if (!async_desc) |
| 633 | − goto err_out; | |
| 633 | + return NULL; | |
| 634 | 634 | |
| 635 | 635 | if (flags & DMA_PREP_FENCE) |
| 636 | 636 | async_desc->flags |= DESC_FLAG_NWD; |
| @@ -670,10 +670,6 @@ static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan, · 33 unmodified lines | ||
| 670 | 670 | } |
| 671 | 671 | |
| 672 | 672 | return vchan_tx_prep(&bchan->vc, &async_desc->vd, flags); |
| 673 | − | |
| 674 | −err_out: | |
| 675 | − kfree(async_desc); | |
| 676 | − return NULL; | |
| 677 | 673 | } |
| 678 | 674 | |
| 679 | 675 | /** |
| @@ -1416,7 +1416,7 @@ static int gpi_alloc_ring(struct gpi_ring *ring, u32 elements, · 1415 unmodified lines | ||
| 1416 | 1416 | len = 1 << bit; |
| 1417 | 1417 | ring->alloc_size = (len + (len - 1)); |
| 1418 | 1418 | dev_dbg(gpii->gpi_dev->dev, |
| 1419 | − "#el:%u el_size:%u len:%u actual_len:%llu alloc_size:%lu\n", | |
| 1419 | + "#el:%u el_size:%u len:%u actual_len:%llu alloc_size:%zu\n", | |
| 1420 | 1420 | elements, el_size, (elements * el_size), len, |
| 1421 | 1421 | ring->alloc_size); |
| 1422 | 1422 | |
| @@ -1424,7 +1424,7 @@ static int gpi_alloc_ring(struct gpi_ring *ring, u32 elements, · 1 unmodified line | ||
| 1424 | 1424 | ring->alloc_size, |
| 1425 | 1425 | &ring->dma_handle, GFP_KERNEL); |
| 1426 | 1426 | if (!ring->pre_aligned) { |
| 1427 | − dev_err(gpii->gpi_dev->dev, "could not alloc size:%lu mem for ring\n", | |
| 1427 | + dev_err(gpii->gpi_dev->dev, "could not alloc size:%zu mem for ring\n", | |
| 1428 | 1428 | ring->alloc_size); |
| 1429 | 1429 | return -ENOMEM; |
| 1430 | 1430 | } |
| @@ -1444,8 +1444,8 @@ static int gpi_alloc_ring(struct gpi_ring *ring, u32 elements, · 13 unmodified lines | ||
| 1444 | 1444 | smp_wmb(); |
| 1445 | 1445 | |
| 1446 | 1446 | dev_dbg(gpii->gpi_dev->dev, |
| 1447 | − "phy_pre:0x%0llx phy_alig:0x%0llx len:%u el_size:%u elements:%u\n", | |
| 1448 | − ring->dma_handle, ring->phys_addr, ring->len, | |
| 1447 | + "phy_pre:%pad phy_alig:%pa len:%u el_size:%u elements:%u\n", | |
| 1448 | + &ring->dma_handle, &ring->phys_addr, ring->len, | |
| 1449 | 1449 | ring->el_size, ring->elements); |
| 1450 | 1450 | |
| 1451 | 1451 | return 0; |
| @@ -1948,7 +1948,7 @@ static int gpi_ch_init(struct gchan *gchan) · 496 unmodified lines | ||
| 1948 | 1948 | return ret; |
| 1949 | 1949 | |
| 1950 | 1950 | error_start_chan: |
| 1951 | − for (i = i - 1; i >= 0; i++) { | |
| 1951 | + for (i = i - 1; i >= 0; i--) { | |
| 1952 | 1952 | gpi_stop_chan(&gpii->gchan[i]); |
| 1953 | 1953 | gpi_send_cmd(gpii, gchan, GPI_CH_CMD_RESET); |
| 1954 | 1954 | } |
| @@ -199,7 +199,7 @@ · 198 unmodified lines | ||
| 199 | 199 | #define STM32_MDMA_MAX_CHANNELS 63 |
| 200 | 200 | #define STM32_MDMA_MAX_REQUESTS 256 |
| 201 | 201 | #define STM32_MDMA_MAX_BURST 128 |
| 202 | −#define STM32_MDMA_VERY_HIGH_PRIORITY 0x11 | |
| 202 | +#define STM32_MDMA_VERY_HIGH_PRIORITY 0x3 | |
| 203 | 203 | |
| 204 | 204 | enum stm32_mdma_trigger_mode { |
| 205 | 205 | STM32_MDMA_BUFFER, |
| @@ -4698,9 +4698,9 @@ static int pktdma_setup_resources(struct udma_dev *ud) · 4697 unmodified lines | ||
| 4698 | 4698 | ud->tchan_tpl.levels = 1; |
| 4699 | 4699 | } |
| 4700 | 4700 | |
| 4701 | − ud->tchan_tpl.levels = ud->tchan_tpl.levels; | |
| 4702 | − ud->tchan_tpl.start_idx[0] = ud->tchan_tpl.start_idx[0]; | |
| 4703 | − ud->tchan_tpl.start_idx[1] = ud->tchan_tpl.start_idx[1]; | |
| 4701 | + ud->rchan_tpl.levels = ud->tchan_tpl.levels; | |
| 4702 | + ud->rchan_tpl.start_idx[0] = ud->tchan_tpl.start_idx[0]; | |
| 4703 | + ud->rchan_tpl.start_idx[1] = ud->tchan_tpl.start_idx[1]; | |
| 4704 | 4704 | |
| 4705 | 4705 | ud->tchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tchan_cnt), |
| 4706 | 4706 | sizeof(unsigned long), GFP_KERNEL); |
| @@ -2781,7 +2781,7 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, · 2780 unmodified lines | ||
| 2781 | 2781 | has_dre = false; |
| 2782 | 2782 | |
| 2783 | 2783 | if (!has_dre) |
| 2784 | − xdev->common.copy_align = fls(width - 1); | |
| 2784 | + xdev->common.copy_align = (enum dmaengine_alignment)fls(width - 1); | |
| 2785 | 2785 | |
| 2786 | 2786 | if (of_device_is_compatible(node, "xlnx,axi-vdma-mm2s-channel") || |
| 2787 | 2787 | of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel") || |
| @@ -2900,7 +2900,8 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, · 112 unmodified lines | ||
| 2900 | 2900 | static int xilinx_dma_child_probe(struct xilinx_dma_device *xdev, |
| 2901 | 2901 | struct device_node *node) |
| 2902 | 2902 | { |
| 2903 | − int ret, i, nr_channels = 1; | |
| 2903 | + int ret, i; | |
| 2904 | + u32 nr_channels = 1; | |
| 2904 | 2905 | |
| 2905 | 2906 | ret = of_property_read_u32(node, "dma-channels", &nr_channels); |
| 2906 | 2907 | if (xdev->dma_config->dmatype == XDMA_TYPE_AXIMCDMA && ret < 0) |
| @@ -3112,7 +3113,11 @@ static int xilinx_dma_probe(struct platform_device *pdev) · 205 unmodified lines | ||
| 3112 | 3113 | } |
| 3113 | 3114 | |
| 3114 | 3115 | /* Register the DMA engine with the core */ |
| 3115 | − dma_async_device_register(&xdev->common); | |
| 3116 | + err = dma_async_device_register(&xdev->common); | |
| 3117 | + if (err) { | |
| 3118 | + dev_err(xdev->dev, "failed to register the dma device\n"); | |
| 3119 | + goto error; | |
| 3120 | + } | |
| 3116 | 3121 | |
| 3117 | 3122 | err = of_dma_controller_register(node, of_dma_xilinx_xlate, |
| 3118 | 3123 | xdev); |
| @@ -112,6 +112,7 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev) · 111 unmodified lines | ||
| 112 | 112 | union igp_info { |
| 113 | 113 | struct atom_integrated_system_info_v1_11 v11; |
| 114 | 114 | struct atom_integrated_system_info_v1_12 v12; |
| 115 | + struct atom_integrated_system_info_v2_1 v21; | |
| 115 | 116 | }; |
| 116 | 117 | |
| 117 | 118 | union umc_info { |
| @@ -209,24 +210,42 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev, · 91 unmodified lines | ||
| 209 | 210 | if (adev->flags & AMD_IS_APU) { |
| 210 | 211 | igp_info = (union igp_info *) |
| 211 | 212 | (mode_info->atom_context->bios + data_offset); |
| 212 | − switch (crev) { | |
| 213 | − case 11: | |
| 214 | − mem_channel_number = igp_info->v11.umachannelnumber; | |
| 215 | − /* channel width is 64 */ | |
| 216 | − if (vram_width) | |
| 217 | − *vram_width = mem_channel_number * 64; | |
| 218 | − mem_type = igp_info->v11.memorytype; | |
| 219 | − if (vram_type) | |
| 220 | − *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); | |
| 213 | + switch (frev) { | |
| 214 | + case 1: | |
| 215 | + switch (crev) { | |
| 216 | + case 11: | |
| 217 | + case 12: | |
| 218 | + mem_channel_number = igp_info->v11.umachannelnumber; | |
| 219 | + if (!mem_channel_number) | |
| 220 | + mem_channel_number = 1; | |
| 221 | + /* channel width is 64 */ | |
| 222 | + if (vram_width) | |
| 223 | + *vram_width = mem_channel_number * 64; | |
| 224 | + mem_type = igp_info->v11.memorytype; | |
| 225 | + if (vram_type) | |
| 226 | + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); | |
| 227 | + break; | |
| 228 | + default: | |
| 229 | + return -EINVAL; | |
| 230 | + } | |
| 221 | 231 | break; |
| 222 | − case 12: | |
| 223 | − mem_channel_number = igp_info->v12.umachannelnumber; | |
| 224 | − /* channel width is 64 */ | |
| 225 | − if (vram_width) | |
| 226 | − *vram_width = mem_channel_number * 64; | |
| 227 | − mem_type = igp_info->v12.memorytype; | |
| 228 | − if (vram_type) | |
| 229 | − *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); | |
| 232 | + case 2: | |
| 233 | + switch (crev) { | |
| 234 | + case 1: | |
| 235 | + case 2: | |
| 236 | + mem_channel_number = igp_info->v21.umachannelnumber; | |
| 237 | + if (!mem_channel_number) | |
| 238 | + mem_channel_number = 1; | |
| 239 | + /* channel width is 64 */ | |
| 240 | + if (vram_width) | |
| 241 | + *vram_width = mem_channel_number * 64; | |
| 242 | + mem_type = igp_info->v21.memorytype; | |
| 243 | + if (vram_type) | |
| 244 | + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); | |
| 245 | + break; | |
| 246 | + default: | |
| 247 | + return -EINVAL; | |
| 248 | + } | |
| 230 | 249 | break; |
| 231 | 250 | default: |
| 232 | 251 | return -EINVAL; |
| @@ -2548,11 +2548,11 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) · 2547 unmodified lines | ||
| 2548 | 2548 | if (adev->gmc.xgmi.num_physical_nodes > 1) |
| 2549 | 2549 | amdgpu_xgmi_remove_device(adev); |
| 2550 | 2550 | |
| 2551 | − amdgpu_amdkfd_device_fini(adev); | |
| 2552 | − | |
| 2553 | 2551 | amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE); |
| 2554 | 2552 | amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE); |
| 2555 | 2553 | |
| 2554 | + amdgpu_amdkfd_device_fini(adev); | |
| 2555 | + | |
| 2556 | 2556 | /* need to disable SMC first */ |
| 2557 | 2557 | for (i = 0; i < adev->num_ip_blocks; i++) { |
| 2558 | 2558 | if (!adev->ip_blocks[i].status.hw) |
| @@ -3034,7 +3034,7 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) · 475 unmodified lines | ||
| 3034 | 3034 | #endif |
| 3035 | 3035 | default: |
| 3036 | 3036 | if (amdgpu_dc > 0) |
| 3037 | − DRM_INFO("Display Core has been requested via kernel parameter " | |
| 3037 | + DRM_INFO_ONCE("Display Core has been requested via kernel parameter " | |
| 3038 | 3038 | "but isn't supported by ASIC, ignoring\n"); |
| 3039 | 3039 | return false; |
| 3040 | 3040 | } |
| @@ -1085,6 +1085,8 @@ static const struct pci_device_id pciidlist[] = { · 1084 unmodified lines | ||
| 1085 | 1085 | |
| 1086 | 1086 | /* Renoir */ |
| 1087 | 1087 | {0x1002, 0x1636, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU}, |
| 1088 | + {0x1002, 0x1638, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU}, | |
| 1089 | + {0x1002, 0x164C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU}, | |
| 1088 | 1090 | |
| 1089 | 1091 | /* Navi12 */ |
| 1090 | 1092 | {0x1002, 0x7360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI12}, |
| @@ -563,7 +563,7 @@ static int psp_asd_load(struct psp_context *psp) · 562 unmodified lines | ||
| 563 | 563 | * add workaround to bypass it for sriov now. |
| 564 | 564 | * TODO: add version check to make it common |
| 565 | 565 | */ |
| 566 | − if (amdgpu_sriov_vf(psp->adev) || !psp->asd_fw) | |
| 566 | + if (amdgpu_sriov_vf(psp->adev) || !psp->asd_ucode_size) | |
| 567 | 567 | return 0; |
| 568 | 568 | |
| 569 | 569 | cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); |
| @@ -1315,8 +1315,12 @@ static int psp_hdcp_terminate(struct psp_context *psp) · 745 unmodified lines | ||
| 1315 | 1315 | if (amdgpu_sriov_vf(psp->adev)) |
| 1316 | 1316 | return 0; |
| 1317 | 1317 | |
| 1318 | − if (!psp->hdcp_context.hdcp_initialized) | |
| 1319 | − return 0; | |
| 1318 | + if (!psp->hdcp_context.hdcp_initialized) { | |
| 1319 | + if (psp->hdcp_context.hdcp_shared_buf) | |
| 1320 | + goto out; | |
| 1321 | + else | |
| 1322 | + return 0; | |
| 1323 | + } | |
| 1320 | 1324 | |
| 1321 | 1325 | ret = psp_hdcp_unload(psp); |
| 1322 | 1326 | if (ret) |
| @@ -1324,6 +1328,7 @@ static int psp_hdcp_terminate(struct psp_context *psp) · 1 unmodified line | ||
| 1324 | 1328 | |
| 1325 | 1329 | psp->hdcp_context.hdcp_initialized = false; |
| 1326 | 1330 | |
| 1331 | +out: | |
| 1327 | 1332 | /* free hdcp shared memory */ |
| 1328 | 1333 | amdgpu_bo_free_kernel(&psp->hdcp_context.hdcp_shared_bo, |
| 1329 | 1334 | &psp->hdcp_context.hdcp_shared_mc_addr, |
| @@ -1462,8 +1467,12 @@ static int psp_dtm_terminate(struct psp_context *psp) · 132 unmodified lines | ||
| 1462 | 1467 | if (amdgpu_sriov_vf(psp->adev)) |
| 1463 | 1468 | return 0; |
| 1464 | 1469 | |
| 1465 | − if (!psp->dtm_context.dtm_initialized) | |
| 1466 | − return 0; | |
| 1470 | + if (!psp->dtm_context.dtm_initialized) { | |
| 1471 | + if (psp->dtm_context.dtm_shared_buf) | |
| 1472 | + goto out; | |
| 1473 | + else | |
| 1474 | + return 0; | |
| 1475 | + } | |
| 1467 | 1476 | |
| 1468 | 1477 | ret = psp_dtm_unload(psp); |
| 1469 | 1478 | if (ret) |
| @@ -1471,6 +1480,7 @@ static int psp_dtm_terminate(struct psp_context *psp) · 1 unmodified line | ||
| 1471 | 1480 | |
| 1472 | 1481 | psp->dtm_context.dtm_initialized = false; |
| 1473 | 1482 | |
| 1483 | +out: | |
| 1474 | 1484 | /* free hdcp shared memory */ |
| 1475 | 1485 | amdgpu_bo_free_kernel(&psp->dtm_context.dtm_shared_bo, |
| 1476 | 1486 | &psp->dtm_context.dtm_shared_mc_addr, |
| @@ -2589,11 +2599,10 @@ static int parse_ta_bin_descriptor(struct psp_context *psp, · 1112 unmodified lines | ||
| 2589 | 2599 | |
| 2590 | 2600 | switch (desc->fw_type) { |
| 2591 | 2601 | case TA_FW_TYPE_PSP_ASD: |
| 2592 | − psp->asd_fw_version = le32_to_cpu(desc->fw_version); | |
| 2602 | + psp->asd_fw_version = le32_to_cpu(desc->fw_version); | |
| 2593 | 2603 | psp->asd_feature_version = le32_to_cpu(desc->fw_version); |
| 2594 | − psp->asd_ucode_size = le32_to_cpu(desc->size_bytes); | |
| 2604 | + psp->asd_ucode_size = le32_to_cpu(desc->size_bytes); | |
| 2595 | 2605 | psp->asd_start_addr = ucode_start_addr; |
| 2596 | − psp->asd_fw = psp->ta_fw; | |
| 2597 | 2606 | break; |
| 2598 | 2607 | case TA_FW_TYPE_PSP_XGMI: |
| 2599 | 2608 | psp->ta_xgmi_ucode_version = le32_to_cpu(desc->fw_version); |
| @@ -1518,7 +1518,7 @@ static int amdgpu_ras_badpages_read(struct amdgpu_device *adev, · 1517 unmodified lines | ||
| 1518 | 1518 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
| 1519 | 1519 | struct ras_err_handler_data *data; |
| 1520 | 1520 | int i = 0; |
| 1521 | − int ret = 0; | |
| 1521 | + int ret = 0, status; | |
| 1522 | 1522 | |
| 1523 | 1523 | if (!con || !con->eh_data || !bps || !count) |
| 1524 | 1524 | return -EINVAL; |
| @@ -1543,12 +1543,12 @@ static int amdgpu_ras_badpages_read(struct amdgpu_device *adev, · 18 unmodified lines | ||
| 1543 | 1543 | .size = AMDGPU_GPU_PAGE_SIZE, |
| 1544 | 1544 | .flags = AMDGPU_RAS_RETIRE_PAGE_RESERVED, |
| 1545 | 1545 | }; |
| 1546 | − ret = amdgpu_vram_mgr_query_page_status( | |
| 1546 | + status = amdgpu_vram_mgr_query_page_status( | |
| 1547 | 1547 | ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM), |
| 1548 | 1548 | data->bps[i].retired_page); |
| 1549 | − if (ret == -EBUSY) | |
| 1549 | + if (status == -EBUSY) | |
| 1550 | 1550 | (*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_PENDING; |
| 1551 | − else if (ret == -ENOENT) | |
| 1551 | + else if (status == -ENOENT) | |
| 1552 | 1552 | (*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_FAULT; |
| 1553 | 1553 | } |
| 1554 | 1554 | |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #define EEPROM_I2C_TARGET_ADDR_VEGA20 0xA0 |
| 31 | 31 | #define EEPROM_I2C_TARGET_ADDR_ARCTURUS 0xA8 |
| 32 | 32 | #define EEPROM_I2C_TARGET_ADDR_ARCTURUS_D342 0xA0 |
| 33 | +#define EEPROM_I2C_TARGET_ADDR_SIENNA_CICHLID 0xA0 | |
| 33 | 34 | |
| 34 | 35 | /* |
| 35 | 36 | * The 2 macros bellow represent the actual size in bytes that |
| @@ -62,7 +63,8 @@ · 26 unmodified lines | ||
| 62 | 63 | static bool __is_ras_eeprom_supported(struct amdgpu_device *adev) |
| 63 | 64 | { |
| 64 | 65 | if ((adev->asic_type == CHIP_VEGA20) || |
| 65 | − (adev->asic_type == CHIP_ARCTURUS)) | |
| 66 | + (adev->asic_type == CHIP_ARCTURUS) || | |
| 67 | + (adev->asic_type == CHIP_SIENNA_CICHLID)) | |
| 66 | 68 | return true; |
| 67 | 69 | |
| 68 | 70 | return false; |
| @@ -100,6 +102,10 @@ static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev, · 31 unmodified lines | ||
| 100 | 102 | case CHIP_ARCTURUS: |
| 101 | 103 | return __get_eeprom_i2c_addr_arct(adev, i2c_addr); |
| 102 | 104 | |
| 105 | + case CHIP_SIENNA_CICHLID: | |
| 106 | + *i2c_addr = EEPROM_I2C_TARGET_ADDR_SIENNA_CICHLID; | |
| 107 | + break; | |
| 108 | + | |
| 103 | 109 | default: |
| 104 | 110 | return false; |
| 105 | 111 | } |
| @@ -99,6 +99,10 @@ · 98 unmodified lines | ||
| 99 | 99 | #define mmGCR_GENERAL_CNTL_Sienna_Cichlid 0x1580 |
| 100 | 100 | #define mmGCR_GENERAL_CNTL_Sienna_Cichlid_BASE_IDX 0 |
| 101 | 101 | |
| 102 | +#define mmGOLDEN_TSC_COUNT_UPPER_Vangogh 0x0025 | |
| 103 | +#define mmGOLDEN_TSC_COUNT_UPPER_Vangogh_BASE_IDX 1 | |
| 104 | +#define mmGOLDEN_TSC_COUNT_LOWER_Vangogh 0x0026 | |
| 105 | +#define mmGOLDEN_TSC_COUNT_LOWER_Vangogh_BASE_IDX 1 | |
| 102 | 106 | #define mmSPI_CONFIG_CNTL_1_Vangogh 0x2441 |
| 103 | 107 | #define mmSPI_CONFIG_CNTL_1_Vangogh_BASE_IDX 1 |
| 104 | 108 | #define mmVGT_TF_MEMORY_BASE_HI_Vangogh 0x2261 |
| @@ -160,6 +164,9 @@ · 55 unmodified lines | ||
| 160 | 164 | #define mmGCVM_L2_CGTT_CLK_CTRL_Sienna_Cichlid 0x15db |
| 161 | 165 | #define mmGCVM_L2_CGTT_CLK_CTRL_Sienna_Cichlid_BASE_IDX 0 |
| 162 | 166 | |
| 167 | +#define mmGC_THROTTLE_CTRL_Sienna_Cichlid 0x2030 | |
| 168 | +#define mmGC_THROTTLE_CTRL_Sienna_Cichlid_BASE_IDX 0 | |
| 169 | + | |
| 163 | 170 | MODULE_FIRMWARE("amdgpu/navi10_ce.bin"); |
| 164 | 171 | MODULE_FIRMWARE("amdgpu/navi10_pfp.bin"); |
| 165 | 172 | MODULE_FIRMWARE("amdgpu/navi10_me.bin"); |
| @@ -3324,6 +3331,7 @@ static void gfx_v10_0_ring_emit_de_meta(struct amdgpu_ring *ring, bool resume); · 3158 unmodified lines | ||
| 3324 | 3331 | static void gfx_v10_0_ring_emit_frame_cntl(struct amdgpu_ring *ring, bool start, bool secure); |
| 3325 | 3332 | static u32 gfx_v10_3_get_disabled_sa(struct amdgpu_device *adev); |
| 3326 | 3333 | static void gfx_v10_3_program_pbb_mode(struct amdgpu_device *adev); |
| 3334 | +static void gfx_v10_3_set_power_brake_sequence(struct amdgpu_device *adev); | |
| 3327 | 3335 | |
| 3328 | 3336 | static void gfx10_kiq_set_resources(struct amdgpu_ring *kiq_ring, uint64_t queue_mask) |
| 3329 | 3337 | { |
| @@ -7192,6 +7200,9 @@ static int gfx_v10_0_hw_init(void *handle) · 3862 unmodified lines | ||
| 7192 | 7200 | if (adev->asic_type == CHIP_SIENNA_CICHLID) |
| 7193 | 7201 | gfx_v10_3_program_pbb_mode(adev); |
| 7194 | 7202 | |
| 7203 | + if (adev->asic_type >= CHIP_SIENNA_CICHLID) | |
| 7204 | + gfx_v10_3_set_power_brake_sequence(adev); | |
| 7205 | + | |
| 7195 | 7206 | return r; |
| 7196 | 7207 | } |
| 7197 | 7208 | |
| @@ -7377,8 +7388,16 @@ static uint64_t gfx_v10_0_get_gpu_clock_counter(struct amdgpu_device *adev) · 179 unmodified lines | ||
| 7377 | 7388 | |
| 7378 | 7389 | amdgpu_gfx_off_ctrl(adev, false); |
| 7379 | 7390 | mutex_lock(&adev->gfx.gpu_clock_mutex); |
| 7380 | − clock = (uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER) | | |
| 7381 | − ((uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER) << 32ULL); | |
| 7391 | + switch (adev->asic_type) { | |
| 7392 | + case CHIP_VANGOGH: | |
| 7393 | + clock = (uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh) | | |
| 7394 | + ((uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh) << 32ULL); | |
| 7395 | + break; | |
| 7396 | + default: | |
| 7397 | + clock = (uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER) | | |
| 7398 | + ((uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER) << 32ULL); | |
| 7399 | + break; | |
| 7400 | + } | |
| 7382 | 7401 | mutex_unlock(&adev->gfx.gpu_clock_mutex); |
| 7383 | 7402 | amdgpu_gfx_off_ctrl(adev, true); |
| 7384 | 7403 | return clock; |
| @@ -9169,6 +9188,31 @@ static void gfx_v10_3_program_pbb_mode(struct amdgpu_device *adev) · 1784 unmodified lines | ||
| 9169 | 9188 | } |
| 9170 | 9189 | } |
| 9171 | 9190 | |
| 9191 | +static void gfx_v10_3_set_power_brake_sequence(struct amdgpu_device *adev) | |
| 9192 | +{ | |
| 9193 | + WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, | |
| 9194 | + (0x1 << GRBM_GFX_INDEX__SA_BROADCAST_WRITES__SHIFT) | | |
| 9195 | + (0x1 << GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES__SHIFT) | | |
| 9196 | + (0x1 << GRBM_GFX_INDEX__SE_BROADCAST_WRITES__SHIFT)); | |
| 9197 | + | |
| 9198 | + WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, ixPWRBRK_STALL_PATTERN_CTRL); | |
| 9199 | + WREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA, | |
| 9200 | + (0x1 << PWRBRK_STALL_PATTERN_CTRL__PWRBRK_STEP_INTERVAL__SHIFT) | | |
| 9201 | + (0x12 << PWRBRK_STALL_PATTERN_CTRL__PWRBRK_BEGIN_STEP__SHIFT) | | |
| 9202 | + (0x13 << PWRBRK_STALL_PATTERN_CTRL__PWRBRK_END_STEP__SHIFT) | | |
| 9203 | + (0xf << PWRBRK_STALL_PATTERN_CTRL__PWRBRK_THROTTLE_PATTERN_BIT_NUMS__SHIFT)); | |
| 9204 | + | |
| 9205 | + WREG32_SOC15(GC, 0, mmGC_THROTTLE_CTRL_Sienna_Cichlid, | |
| 9206 | + (0x1 << GC_THROTTLE_CTRL__PWRBRK_STALL_EN__SHIFT) | | |
| 9207 | + (0x1 << GC_THROTTLE_CTRL__PATTERN_MODE__SHIFT) | | |
| 9208 | + (0x5 << GC_THROTTLE_CTRL__RELEASE_STEP_INTERVAL__SHIFT)); | |
| 9209 | + | |
| 9210 | + WREG32_SOC15(GC, 0, mmDIDT_IND_INDEX, ixDIDT_SQ_THROTTLE_CTRL); | |
| 9211 | + | |
| 9212 | + WREG32_SOC15(GC, 0, mmDIDT_IND_DATA, | |
| 9213 | + (0x1 << DIDT_SQ_THROTTLE_CTRL__PWRBRK_STALL_EN__SHIFT)); | |
| 9214 | +} | |
| 9215 | + | |
| 9172 | 9216 | const struct amdgpu_ip_block_version gfx_v10_0_ip_block = |
| 9173 | 9217 | { |
| 9174 | 9218 | .type = AMD_IP_BLOCK_TYPE_GFX, |
| @@ -310,7 +310,7 @@ static void mmhub_v2_3_setup_vmid_config(struct amdgpu_device *adev) · 309 unmodified lines | ||
| 310 | 310 | /* Send no-retry XNACK on fault to suppress VM fault storm. */ |
| 311 | 311 | tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, |
| 312 | 312 | RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, |
| 313 | − !amdgpu_noretry); | |
| 313 | + !adev->gmc.noretry); | |
| 314 | 314 | WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_CNTL, |
| 315 | 315 | i * hub->ctx_distance, tmp); |
| 316 | 316 | WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32, |
| @@ -47,7 +47,7 @@ enum psp_gfx_crtl_cmd_id · 46 unmodified lines | ||
| 47 | 47 | GFX_CTRL_CMD_ID_DISABLE_INT = 0x00060000, /* disable PSP-to-Gfx interrupt */ |
| 48 | 48 | GFX_CTRL_CMD_ID_MODE1_RST = 0x00070000, /* trigger the Mode 1 reset */ |
| 49 | 49 | GFX_CTRL_CMD_ID_GBR_IH_SET = 0x00080000, /* set Gbr IH_RB_CNTL registers */ |
| 50 | − GFX_CTRL_CMD_ID_CONSUME_CMD = 0x000A0000, /* send interrupt to psp for updating write pointer of vf */ | |
| 50 | + GFX_CTRL_CMD_ID_CONSUME_CMD = 0x00090000, /* send interrupt to psp for updating write pointer of vf */ | |
| 51 | 51 | GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING = 0x000C0000, /* destroy GPCOM ring */ |
| 52 | 52 | |
| 53 | 53 | GFX_CTRL_CMD_ID_MAX = 0x000F0000, /* max command ID */ |
| @@ -1239,7 +1239,8 @@ static int soc15_common_early_init(void *handle) · 1238 unmodified lines | ||
| 1239 | 1239 | break; |
| 1240 | 1240 | case CHIP_RENOIR: |
| 1241 | 1241 | adev->asic_funcs = &soc15_asic_funcs; |
| 1242 | − if (adev->pdev->device == 0x1636) | |
| 1242 | + if ((adev->pdev->device == 0x1636) || | |
| 1243 | + (adev->pdev->device == 0x164c)) | |
| 1243 | 1244 | adev->apu_flags |= AMD_APU_IS_RENOIR; |
| 1244 | 1245 | else |
| 1245 | 1246 | adev->apu_flags |= AMD_APU_IS_GREEN_SARDINE; |
| @@ -1040,11 +1040,14 @@ static int kfd_create_vcrat_image_cpu(void *pcrat_image, size_t *size) · 1039 unmodified lines | ||
| 1040 | 1040 | (struct crat_subtype_iolink *)sub_type_hdr); |
| 1041 | 1041 | if (ret < 0) |
| 1042 | 1042 | return ret; |
| 1043 | − crat_table->length += (sub_type_hdr->length * entries); | |
| 1044 | − crat_table->total_entries += entries; | |
| 1045 | 1043 | |
| 1046 | − sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr + | |
| 1047 | − sub_type_hdr->length * entries); | |
| 1044 | + if (entries) { | |
| 1045 | + crat_table->length += (sub_type_hdr->length * entries); | |
| 1046 | + crat_table->total_entries += entries; | |
| 1047 | + | |
| 1048 | + sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr + | |
| 1049 | + sub_type_hdr->length * entries); | |
| 1050 | + } | |
| 1048 | 1051 | #else |
| 1049 | 1052 | pr_info("IO link not available for non x86 platforms\n"); |
| 1050 | 1053 | #endif |
| @@ -6,7 +6,7 @@ config DRM_AMD_DC · 5 unmodified lines | ||
| 6 | 6 | bool "AMD DC - Enable new display engine" |
| 7 | 7 | default y |
| 8 | 8 | select SND_HDA_COMPONENT if SND_HDA_CORE |
| 9 | − select DRM_AMD_DC_DCN if (X86 || PPC64 || (ARM64 && KERNEL_MODE_NEON)) && !(KCOV_INSTRUMENT_ALL && KCOV_ENABLE_COMPARISONS) | |
| 9 | + select DRM_AMD_DC_DCN if (X86 || PPC64) && !(KCOV_INSTRUMENT_ALL && KCOV_ENABLE_COMPARISONS) | |
| 10 | 10 | help |
| 11 | 11 | Choose this option if you want to use the new display engine |
| 12 | 12 | support for AMDGPU. This adds required support for Vega and |
| @@ -939,41 +939,6 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_ · 938 unmodified lines | ||
| 939 | 939 | } |
| 940 | 940 | #endif |
| 941 | 941 | |
| 942 | −#ifdef CONFIG_DEBUG_FS | |
| 943 | −static int create_crtc_crc_properties(struct amdgpu_display_manager *dm) | |
| 944 | −{ | |
| 945 | − dm->crc_win_x_start_property = | |
| 946 | − drm_property_create_range(adev_to_drm(dm->adev), | |
| 947 | − DRM_MODE_PROP_ATOMIC, | |
| 948 | − "AMD_CRC_WIN_X_START", 0, U16_MAX); | |
| 949 | − if (!dm->crc_win_x_start_property) | |
| 950 | − return -ENOMEM; | |
| 951 | − | |
| 952 | − dm->crc_win_y_start_property = | |
| 953 | − drm_property_create_range(adev_to_drm(dm->adev), | |
| 954 | − DRM_MODE_PROP_ATOMIC, | |
| 955 | − "AMD_CRC_WIN_Y_START", 0, U16_MAX); | |
| 956 | − if (!dm->crc_win_y_start_property) | |
| 957 | − return -ENOMEM; | |
| 958 | − | |
| 959 | − dm->crc_win_x_end_property = | |
| 960 | − drm_property_create_range(adev_to_drm(dm->adev), | |
| 961 | − DRM_MODE_PROP_ATOMIC, | |
| 962 | − "AMD_CRC_WIN_X_END", 0, U16_MAX); | |
| 963 | − if (!dm->crc_win_x_end_property) | |
| 964 | − return -ENOMEM; | |
| 965 | − | |
| 966 | − dm->crc_win_y_end_property = | |
| 967 | − drm_property_create_range(adev_to_drm(dm->adev), | |
| 968 | − DRM_MODE_PROP_ATOMIC, | |
| 969 | − "AMD_CRC_WIN_Y_END", 0, U16_MAX); | |
| 970 | − if (!dm->crc_win_y_end_property) | |
| 971 | − return -ENOMEM; | |
| 972 | − | |
| 973 | − return 0; | |
| 974 | −} | |
| 975 | −#endif | |
| 976 | − | |
| 977 | 942 | static int amdgpu_dm_init(struct amdgpu_device *adev) |
| 978 | 943 | { |
| 979 | 944 | struct dc_init_data init_data; |
| @@ -1120,10 +1085,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 140 unmodified lines | ||
| 1120 | 1085 | |
| 1121 | 1086 | dc_init_callbacks(adev->dm.dc, &init_params); |
| 1122 | 1087 | } |
| 1123 | −#endif | |
| 1124 | −#ifdef CONFIG_DEBUG_FS | |
| 1125 | − if (create_crtc_crc_properties(&adev->dm)) | |
| 1126 | − DRM_ERROR("amdgpu: failed to create crc property.\n"); | |
| 1127 | 1088 | #endif |
| 1128 | 1089 | if (amdgpu_dm_initialize_drm_device(adev)) { |
| 1129 | 1090 | DRM_ERROR( |
| @@ -2386,8 +2347,7 @@ void amdgpu_dm_update_connector_after_detect( · 1256 unmodified lines | ||
| 2386 | 2347 | |
| 2387 | 2348 | drm_connector_update_edid_property(connector, |
| 2388 | 2349 | aconnector->edid); |
| 2389 | − aconnector->num_modes = drm_add_edid_modes(connector, aconnector->edid); | |
| 2390 | − drm_connector_list_update(connector); | |
| 2350 | + drm_add_edid_modes(connector, aconnector->edid); | |
| 2391 | 2351 | |
| 2392 | 2352 | if (aconnector->dc_link->aux_mode) |
| 2393 | 2353 | drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux, |
| @@ -5334,64 +5294,12 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc) · 2940 unmodified lines | ||
| 5334 | 5294 | state->crc_src = cur->crc_src; |
| 5335 | 5295 | state->cm_has_degamma = cur->cm_has_degamma; |
| 5336 | 5296 | state->cm_is_degamma_srgb = cur->cm_is_degamma_srgb; |
| 5337 | −#ifdef CONFIG_DEBUG_FS | |
| 5338 | − state->crc_window = cur->crc_window; | |
| 5339 | −#endif | |
| 5297 | + | |
| 5340 | 5298 | /* TODO Duplicate dc_stream after objects are stream object is flattened */ |
| 5341 | 5299 | |
| 5342 | 5300 | return &state->base; |
| 5343 | 5301 | } |
| 5344 | 5302 | |
| 5345 | −#ifdef CONFIG_DEBUG_FS | |
| 5346 | −static int amdgpu_dm_crtc_atomic_set_property(struct drm_crtc *crtc, | |
| 5347 | − struct drm_crtc_state *crtc_state, | |
| 5348 | − struct drm_property *property, | |
| 5349 | − uint64_t val) | |
| 5350 | −{ | |
| 5351 | − struct drm_device *dev = crtc->dev; | |
| 5352 | − struct amdgpu_device *adev = drm_to_adev(dev); | |
| 5353 | − struct dm_crtc_state *dm_new_state = | |
| 5354 | − to_dm_crtc_state(crtc_state); | |
| 5355 | − | |
| 5356 | − if (property == adev->dm.crc_win_x_start_property) | |
| 5357 | − dm_new_state->crc_window.x_start = val; | |
| 5358 | − else if (property == adev->dm.crc_win_y_start_property) | |
| 5359 | − dm_new_state->crc_window.y_start = val; | |
| 5360 | − else if (property == adev->dm.crc_win_x_end_property) | |
| 5361 | − dm_new_state->crc_window.x_end = val; | |
| 5362 | − else if (property == adev->dm.crc_win_y_end_property) | |
| 5363 | − dm_new_state->crc_window.y_end = val; | |
| 5364 | − else | |
| 5365 | − return -EINVAL; | |
| 5366 | − | |
| 5367 | − return 0; | |
| 5368 | −} | |
| 5369 | − | |
| 5370 | −static int amdgpu_dm_crtc_atomic_get_property(struct drm_crtc *crtc, | |
| 5371 | − const struct drm_crtc_state *state, | |
| 5372 | − struct drm_property *property, | |
| 5373 | − uint64_t *val) | |
| 5374 | −{ | |
| 5375 | − struct drm_device *dev = crtc->dev; | |
| 5376 | − struct amdgpu_device *adev = drm_to_adev(dev); | |
| 5377 | − struct dm_crtc_state *dm_state = | |
| 5378 | − to_dm_crtc_state(state); | |
| 5379 | − | |
| 5380 | − if (property == adev->dm.crc_win_x_start_property) | |
| 5381 | − *val = dm_state->crc_window.x_start; | |
| 5382 | − else if (property == adev->dm.crc_win_y_start_property) | |
| 5383 | − *val = dm_state->crc_window.y_start; | |
| 5384 | − else if (property == adev->dm.crc_win_x_end_property) | |
| 5385 | − *val = dm_state->crc_window.x_end; | |
| 5386 | − else if (property == adev->dm.crc_win_y_end_property) | |
| 5387 | − *val = dm_state->crc_window.y_end; | |
| 5388 | − else | |
| 5389 | − return -EINVAL; | |
| 5390 | − | |
| 5391 | − return 0; | |
| 5392 | −} | |
| 5393 | −#endif | |
| 5394 | − | |
| 5395 | 5303 | static inline int dm_set_vupdate_irq(struct drm_crtc *crtc, bool enable) |
| 5396 | 5304 | { |
| 5397 | 5305 | enum dc_irq_source irq_source; |
| @@ -5458,10 +5366,6 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { · 60 unmodified lines | ||
| 5458 | 5366 | .enable_vblank = dm_enable_vblank, |
| 5459 | 5367 | .disable_vblank = dm_disable_vblank, |
| 5460 | 5368 | .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp, |
| 5461 | −#ifdef CONFIG_DEBUG_FS | |
| 5462 | − .atomic_set_property = amdgpu_dm_crtc_atomic_set_property, | |
| 5463 | − .atomic_get_property = amdgpu_dm_crtc_atomic_get_property, | |
| 5464 | −#endif | |
| 5465 | 5369 | }; |
| 5466 | 5370 | |
| 5467 | 5371 | static enum drm_connector_status |
| @@ -6663,25 +6567,6 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, · 1195 unmodified lines | ||
| 6663 | 6567 | return 0; |
| 6664 | 6568 | } |
| 6665 | 6569 | |
| 6666 | −#ifdef CONFIG_DEBUG_FS | |
| 6667 | −static void attach_crtc_crc_properties(struct amdgpu_display_manager *dm, | |
| 6668 | − struct amdgpu_crtc *acrtc) | |
| 6669 | −{ | |
| 6670 | − drm_object_attach_property(&acrtc->base.base, | |
| 6671 | − dm->crc_win_x_start_property, | |
| 6672 | − 0); | |
| 6673 | − drm_object_attach_property(&acrtc->base.base, | |
| 6674 | − dm->crc_win_y_start_property, | |
| 6675 | − 0); | |
| 6676 | − drm_object_attach_property(&acrtc->base.base, | |
| 6677 | − dm->crc_win_x_end_property, | |
| 6678 | − 0); | |
| 6679 | − drm_object_attach_property(&acrtc->base.base, | |
| 6680 | − dm->crc_win_y_end_property, | |
| 6681 | − 0); | |
| 6682 | −} | |
| 6683 | −#endif | |
| 6684 | − | |
| 6685 | 6570 | static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, |
| 6686 | 6571 | struct drm_plane *plane, |
| 6687 | 6572 | uint32_t crtc_index) |
| @@ -6729,9 +6614,7 @@ static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, · 41 unmodified lines | ||
| 6729 | 6614 | drm_crtc_enable_color_mgmt(&acrtc->base, MAX_COLOR_LUT_ENTRIES, |
| 6730 | 6615 | true, MAX_COLOR_LUT_ENTRIES); |
| 6731 | 6616 | drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES); |
| 6732 | −#ifdef CONFIG_DEBUG_FS | |
| 6733 | − attach_crtc_crc_properties(dm, acrtc); | |
| 6734 | −#endif | |
| 6617 | + | |
| 6735 | 6618 | return 0; |
| 6736 | 6619 | |
| 6737 | 6620 | fail: |
| @@ -8368,7 +8251,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 1630 unmodified lines | ||
| 8368 | 8251 | */ |
| 8369 | 8252 | for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { |
| 8370 | 8253 | struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); |
| 8371 | − bool configure_crc = false; | |
| 8372 | 8254 | |
| 8373 | 8255 | dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); |
| 8374 | 8256 | |
| @@ -8378,30 +8260,21 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 3 unmodified lines | ||
| 8378 | 8260 | dc_stream_retain(dm_new_crtc_state->stream); |
| 8379 | 8261 | acrtc->dm_irq_params.stream = dm_new_crtc_state->stream; |
| 8380 | 8262 | manage_dm_interrupts(adev, acrtc, true); |
| 8381 | − } | |
| 8263 | + | |
| 8382 | 8264 | #ifdef CONFIG_DEBUG_FS |
| 8383 | − if (new_crtc_state->active && | |
| 8384 | − amdgpu_dm_is_valid_crc_source(dm_new_crtc_state->crc_src)) { | |
| 8385 | 8265 | /** |
| 8386 | 8266 | * Frontend may have changed so reapply the CRC capture |
| 8387 | 8267 | * settings for the stream. |
| 8388 | 8268 | */ |
| 8389 | 8269 | dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); |
| 8390 | − dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); | |
| 8391 | − | |
| 8392 | − if (amdgpu_dm_crc_window_is_default(dm_new_crtc_state)) { | |
| 8393 | − if (!old_crtc_state->active || drm_atomic_crtc_needs_modeset(new_crtc_state)) | |
| 8394 | − configure_crc = true; | |
| 8395 | − } else { | |
| 8396 | − if (amdgpu_dm_crc_window_changed(dm_new_crtc_state, dm_old_crtc_state)) | |
| 8397 | − configure_crc = true; | |
| 8398 | − } | |
| 8399 | 8270 | |
| 8400 | − if (configure_crc) | |
| 8271 | + if (amdgpu_dm_is_valid_crc_source(dm_new_crtc_state->crc_src)) { | |
| 8401 | 8272 | amdgpu_dm_crtc_configure_crc_source( |
| 8402 | − crtc, dm_new_crtc_state, dm_new_crtc_state->crc_src); | |
| 8403 | − } | |
| 8273 | + crtc, dm_new_crtc_state, | |
| 8274 | + dm_new_crtc_state->crc_src); | |
| 8275 | + } | |
| 8404 | 8276 | #endif |
| 8277 | + } | |
| 8405 | 8278 | } |
| 8406 | 8279 | |
| 8407 | 8280 | for_each_new_crtc_in_state(state, crtc, new_crtc_state, j) |
| @@ -336,32 +336,6 @@ struct amdgpu_display_manager { · 335 unmodified lines | ||
| 336 | 336 | */ |
| 337 | 337 | const struct gpu_info_soc_bounding_box_v1_0 *soc_bounding_box; |
| 338 | 338 | |
| 339 | −#ifdef CONFIG_DEBUG_FS | |
| 340 | − /** | |
| 341 | − * @crc_win_x_start_property: | |
| 342 | − * | |
| 343 | − * X start of the crc calculation window | |
| 344 | − */ | |
| 345 | − struct drm_property *crc_win_x_start_property; | |
| 346 | − /** | |
| 347 | − * @crc_win_y_start_property: | |
| 348 | − * | |
| 349 | − * Y start of the crc calculation window | |
| 350 | − */ | |
| 351 | − struct drm_property *crc_win_y_start_property; | |
| 352 | − /** | |
| 353 | − * @crc_win_x_end_property: | |
| 354 | − * | |
| 355 | − * X end of the crc calculation window | |
| 356 | − */ | |
| 357 | − struct drm_property *crc_win_x_end_property; | |
| 358 | − /** | |
| 359 | − * @crc_win_y_end_property: | |
| 360 | − * | |
| 361 | − * Y end of the crc calculation window | |
| 362 | − */ | |
| 363 | − struct drm_property *crc_win_y_end_property; | |
| 364 | −#endif | |
| 365 | 339 | /** |
| 366 | 340 | * @mst_encoders: |
| 367 | 341 | * |
| @@ -448,15 +422,6 @@ struct dm_plane_state { · 80 unmodified lines | ||
| 448 | 422 | struct dc_plane_state *dc_state; |
| 449 | 423 | }; |
| 450 | 424 | |
| 451 | −#ifdef CONFIG_DEBUG_FS | |
| 452 | −struct crc_rec { | |
| 453 | − uint16_t x_start; | |
| 454 | − uint16_t y_start; | |
| 455 | − uint16_t x_end; | |
| 456 | − uint16_t y_end; | |
| 457 | − }; | |
| 458 | −#endif | |
| 459 | − | |
| 460 | 425 | struct dm_crtc_state { |
| 461 | 426 | struct drm_crtc_state base; |
| 462 | 427 | struct dc_stream_state *stream; |
| @@ -479,9 +444,6 @@ struct dm_crtc_state { · 16 unmodified lines | ||
| 479 | 444 | struct dc_info_packet vrr_infopacket; |
| 480 | 445 | |
| 481 | 446 | int abm_level; |
| 482 | −#ifdef CONFIG_DEBUG_FS | |
| 483 | − struct crc_rec crc_window; | |
| 484 | −#endif | |
| 485 | 447 | }; |
| 486 | 448 | |
| 487 | 449 | #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base) |
| @@ -81,41 +81,6 @@ const char *const *amdgpu_dm_crtc_get_crc_sources(struct drm_crtc *crtc, · 80 unmodified lines | ||
| 81 | 81 | return pipe_crc_sources; |
| 82 | 82 | } |
| 83 | 83 | |
| 84 | −static void amdgpu_dm_set_crc_window_default(struct dm_crtc_state *dm_crtc_state) | |
| 85 | −{ | |
| 86 | − dm_crtc_state->crc_window.x_start = 0; | |
| 87 | − dm_crtc_state->crc_window.y_start = 0; | |
| 88 | − dm_crtc_state->crc_window.x_end = 0; | |
| 89 | − dm_crtc_state->crc_window.y_end = 0; | |
| 90 | −} | |
| 91 | − | |
| 92 | −bool amdgpu_dm_crc_window_is_default(struct dm_crtc_state *dm_crtc_state) | |
| 93 | −{ | |
| 94 | − bool ret = true; | |
| 95 | − | |
| 96 | − if ((dm_crtc_state->crc_window.x_start != 0) || | |
| 97 | − (dm_crtc_state->crc_window.y_start != 0) || | |
| 98 | − (dm_crtc_state->crc_window.x_end != 0) || | |
| 99 | − (dm_crtc_state->crc_window.y_end != 0)) | |
| 100 | − ret = false; | |
| 101 | − | |
| 102 | − return ret; | |
| 103 | −} | |
| 104 | − | |
| 105 | −bool amdgpu_dm_crc_window_changed(struct dm_crtc_state *dm_new_crtc_state, | |
| 106 | − struct dm_crtc_state *dm_old_crtc_state) | |
| 107 | −{ | |
| 108 | − bool ret = false; | |
| 109 | − | |
| 110 | − if ((dm_new_crtc_state->crc_window.x_start != dm_old_crtc_state->crc_window.x_start) || | |
| 111 | − (dm_new_crtc_state->crc_window.y_start != dm_old_crtc_state->crc_window.y_start) || | |
| 112 | − (dm_new_crtc_state->crc_window.x_end != dm_old_crtc_state->crc_window.x_end) || | |
| 113 | − (dm_new_crtc_state->crc_window.y_end != dm_old_crtc_state->crc_window.y_end)) | |
| 114 | − ret = true; | |
| 115 | − | |
| 116 | − return ret; | |
| 117 | −} | |
| 118 | − | |
| 119 | 84 | int |
| 120 | 85 | amdgpu_dm_crtc_verify_crc_source(struct drm_crtc *crtc, const char *src_name, |
| 121 | 86 | size_t *values_cnt) |
| @@ -140,7 +105,6 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, · 18 unmodified lines | ||
| 140 | 105 | struct dc_stream_state *stream_state = dm_crtc_state->stream; |
| 141 | 106 | bool enable = amdgpu_dm_is_valid_crc_source(source); |
| 142 | 107 | int ret = 0; |
| 143 | − struct crc_params *crc_window = NULL, tmp_window; | |
| 144 | 108 | |
| 145 | 109 | /* Configuration will be deferred to stream enable. */ |
| 146 | 110 | if (!stream_state) |
| @@ -150,24 +114,8 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, · 3 unmodified lines | ||
| 150 | 114 | |
| 151 | 115 | /* Enable CRTC CRC generation if necessary. */ |
| 152 | 116 | if (dm_is_crc_source_crtc(source) || source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE) { |
| 153 | − if (!enable) | |
| 154 | − amdgpu_dm_set_crc_window_default(dm_crtc_state); | |
| 155 | − | |
| 156 | − if (!amdgpu_dm_crc_window_is_default(dm_crtc_state)) { | |
| 157 | − crc_window = &tmp_window; | |
| 158 | − | |
| 159 | − tmp_window.windowa_x_start = dm_crtc_state->crc_window.x_start; | |
| 160 | − tmp_window.windowa_y_start = dm_crtc_state->crc_window.y_start; | |
| 161 | − tmp_window.windowa_x_end = dm_crtc_state->crc_window.x_end; | |
| 162 | − tmp_window.windowa_y_end = dm_crtc_state->crc_window.y_end; | |
| 163 | − tmp_window.windowb_x_start = dm_crtc_state->crc_window.x_start; | |
| 164 | − tmp_window.windowb_y_start = dm_crtc_state->crc_window.y_start; | |
| 165 | − tmp_window.windowb_x_end = dm_crtc_state->crc_window.x_end; | |
| 166 | − tmp_window.windowb_y_end = dm_crtc_state->crc_window.y_end; | |
| 167 | − } | |
| 168 | − | |
| 169 | 117 | if (!dc_stream_configure_crc(stream_state->ctx->dc, |
| 170 | − stream_state, crc_window, enable, enable)) { | |
| 118 | + stream_state, NULL, enable, enable)) { | |
| 171 | 119 | ret = -EINVAL; |
| 172 | 120 | goto unlock; |
| 173 | 121 | } |
| @@ -47,9 +47,6 @@ static inline bool amdgpu_dm_is_valid_crc_source(enum amdgpu_dm_pipe_crc_source · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | /* amdgpu_dm_crc.c */ |
| 49 | 49 | #ifdef CONFIG_DEBUG_FS |
| 50 | −bool amdgpu_dm_crc_window_is_default(struct dm_crtc_state *dm_crtc_state); | |
| 51 | −bool amdgpu_dm_crc_window_changed(struct dm_crtc_state *dm_new_crtc_state, | |
| 52 | − struct dm_crtc_state *dm_old_crtc_state); | |
| 53 | 50 | int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, |
| 54 | 51 | struct dm_crtc_state *dm_crtc_state, |
| 55 | 52 | enum amdgpu_dm_pipe_crc_source source); |
| @@ -33,10 +33,6 @@ ifdef CONFIG_PPC64 · 32 unmodified lines | ||
| 33 | 33 | calcs_ccflags := -mhard-float -maltivec |
| 34 | 34 | endif |
| 35 | 35 | |
| 36 | −ifdef CONFIG_ARM64 | |
| 37 | −calcs_rcflags := -mgeneral-regs-only | |
| 38 | −endif | |
| 39 | − | |
| 40 | 36 | ifdef CONFIG_CC_IS_GCC |
| 41 | 37 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 42 | 38 | IS_OLD_GCC = 1 |
| @@ -104,13 +104,6 @@ ifdef CONFIG_PPC64 · 103 unmodified lines | ||
| 104 | 104 | CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn21/rn_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) |
| 105 | 105 | endif |
| 106 | 106 | |
| 107 | −# prevent build errors: | |
| 108 | −# ...: '-mgeneral-regs-only' is incompatible with the use of floating-point types | |
| 109 | −# this file is unused on arm64, just like on ppc64 | |
| 110 | −ifdef CONFIG_ARM64 | |
| 111 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/clk_mgr/dcn21/rn_clk_mgr.o := -mgeneral-regs-only | |
| 112 | −endif | |
| 113 | − | |
| 114 | 107 | AMD_DAL_CLK_MGR_DCN21 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn21/,$(CLK_MGR_DCN21)) |
| 115 | 108 | |
| 116 | 109 | AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21) |
| @@ -125,13 +118,6 @@ ifdef CONFIG_PPC64 · 8 unmodified lines | ||
| 125 | 118 | CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn30/dcn30_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) |
| 126 | 119 | endif |
| 127 | 120 | |
| 128 | −# prevent build errors: | |
| 129 | −# ...: '-mgeneral-regs-only' is incompatible with the use of floating-point types | |
| 130 | −# this file is unused on arm64, just like on ppc64 | |
| 131 | −ifdef CONFIG_ARM64 | |
| 132 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/clk_mgr/dcn30/dcn30_clk_mgr.o := -mgeneral-regs-only | |
| 133 | −endif | |
| 134 | − | |
| 135 | 121 | AMD_DAL_CLK_MGR_DCN30 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn30/,$(CLK_MGR_DCN30)) |
| 136 | 122 | |
| 137 | 123 | AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN30) |
| @@ -146,13 +132,6 @@ ifdef CONFIG_PPC64 · 8 unmodified lines | ||
| 146 | 132 | CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn301/vg_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) |
| 147 | 133 | endif |
| 148 | 134 | |
| 149 | −# prevent build errors: | |
| 150 | −# ...: '-mgeneral-regs-only' is incompatible with the use of floating-point types | |
| 151 | −# this file is unused on arm64, just like on ppc64 | |
| 152 | −ifdef CONFIG_ARM64 | |
| 153 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/clk_mgr/dcn301/vg_clk_mgr.o := -mgeneral-regs-only | |
| 154 | −endif | |
| 155 | − | |
| 156 | 135 | AMD_DAL_CLK_MGR_DCN301 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn301/,$(CLK_MGR_DCN301)) |
| 157 | 136 | |
| 158 | 137 | AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN301) |
| @@ -2487,9 +2487,14 @@ enum dc_status dc_link_validate_mode_timing( · 2486 unmodified lines | ||
| 2487 | 2487 | static struct abm *get_abm_from_stream_res(const struct dc_link *link) |
| 2488 | 2488 | { |
| 2489 | 2489 | int i; |
| 2490 | − struct dc *dc = link->ctx->dc; | |
| 2490 | + struct dc *dc = NULL; | |
| 2491 | 2491 | struct abm *abm = NULL; |
| 2492 | 2492 | |
| 2493 | + if (!link || !link->ctx) | |
| 2494 | + return NULL; | |
| 2495 | + | |
| 2496 | + dc = link->ctx->dc; | |
| 2497 | + | |
| 2493 | 2498 | for (i = 0; i < MAX_PIPES; i++) { |
| 2494 | 2499 | struct pipe_ctx pipe_ctx = dc->current_state->res_ctx.pipe_ctx[i]; |
| 2495 | 2500 | struct dc_stream_state *stream = pipe_ctx.stream; |
| @@ -3992,7 +3992,7 @@ bool dc_link_dp_set_test_pattern( · 3991 unmodified lines | ||
| 3992 | 3992 | unsigned int cust_pattern_size) |
| 3993 | 3993 | { |
| 3994 | 3994 | struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx; |
| 3995 | − struct pipe_ctx *pipe_ctx = &pipes[0]; | |
| 3995 | + struct pipe_ctx *pipe_ctx = NULL; | |
| 3996 | 3996 | unsigned int lane; |
| 3997 | 3997 | unsigned int i; |
| 3998 | 3998 | unsigned char link_qual_pattern[LANE_COUNT_DP_MAX] = {0}; |
| @@ -4002,12 +4002,18 @@ bool dc_link_dp_set_test_pattern( · 3 unmodified lines | ||
| 4002 | 4002 | memset(&training_pattern, 0, sizeof(training_pattern)); |
| 4003 | 4003 | |
| 4004 | 4004 | for (i = 0; i < MAX_PIPES; i++) { |
| 4005 | + if (pipes[i].stream == NULL) | |
| 4006 | + continue; | |
| 4007 | + | |
| 4005 | 4008 | if (pipes[i].stream->link == link && !pipes[i].top_pipe && !pipes[i].prev_odm_pipe) { |
| 4006 | 4009 | pipe_ctx = &pipes[i]; |
| 4007 | 4010 | break; |
| 4008 | 4011 | } |
| 4009 | 4012 | } |
| 4010 | 4013 | |
| 4014 | + if (pipe_ctx == NULL) | |
| 4015 | + return false; | |
| 4016 | + | |
| 4011 | 4017 | /* Reset CRTC Test Pattern if it is currently running and request is VideoMode */ |
| 4012 | 4018 | if (link->test_pattern_enabled && test_pattern == |
| 4013 | 4019 | DP_TEST_PATTERN_VIDEO_MODE) { |
| @@ -31,11 +31,4 @@ DCN10 = dcn10_init.o dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o \ · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10)) |
| 33 | 33 | |
| 34 | −# fix: | |
| 35 | −# ...: '-mgeneral-regs-only' is incompatible with the use of floating-point types | |
| 36 | −# aarch64 does not support soft-float, so use hard-float and handle this in code | |
| 37 | −ifdef CONFIG_ARM64 | |
| 38 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn10/dcn10_resource.o := -mgeneral-regs-only | |
| 39 | −endif | |
| 40 | − | |
| 41 | 34 | AMD_DISPLAY_FILES += $(AMD_DAL_DCN10) |
| @@ -470,7 +470,7 @@ void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock) · 469 unmodified lines | ||
| 470 | 470 | unsigned int mpc1_get_mpc_out_mux(struct mpc *mpc, int opp_id) |
| 471 | 471 | { |
| 472 | 472 | struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); |
| 473 | − uint32_t val = 0; | |
| 473 | + uint32_t val = 0xf; | |
| 474 | 474 | |
| 475 | 475 | if (opp_id < MAX_OPP && REG(MUX[opp_id])) |
| 476 | 476 | REG_GET(MUX[opp_id], MPC_OUT_MUX, &val); |
| @@ -608,8 +608,8 @@ static const struct dc_debug_options debug_defaults_drv = { · 607 unmodified lines | ||
| 608 | 608 | .disable_pplib_clock_request = false, |
| 609 | 609 | .disable_pplib_wm_range = false, |
| 610 | 610 | .pplib_wm_report_mode = WM_REPORT_DEFAULT, |
| 611 | − .pipe_split_policy = MPC_SPLIT_DYNAMIC, | |
| 612 | − .force_single_disp_pipe_split = true, | |
| 611 | + .pipe_split_policy = MPC_SPLIT_AVOID, | |
| 612 | + .force_single_disp_pipe_split = false, | |
| 613 | 613 | .disable_dcc = DCC_ENABLE, |
| 614 | 614 | .voltage_align_fclk = true, |
| 615 | 615 | .disable_stereo_support = true, |
| @@ -1534,15 +1534,8 @@ static bool dcn10_resource_construct( · 918 unmodified lines | ||
| 1534 | 1534 | memcpy(dc->dcn_ip, &dcn10_ip_defaults, sizeof(dcn10_ip_defaults)); |
| 1535 | 1535 | memcpy(dc->dcn_soc, &dcn10_soc_defaults, sizeof(dcn10_soc_defaults)); |
| 1536 | 1536 | |
| 1537 | −#if defined(CONFIG_ARM64) | |
| 1538 | − /* Aarch64 does not support -msoft-float/-mfloat-abi=soft */ | |
| 1539 | − DC_FP_START(); | |
| 1540 | − dcn10_resource_construct_fp(dc); | |
| 1541 | − DC_FP_END(); | |
| 1542 | −#else | |
| 1543 | 1537 | /* Other architectures we build for build this with soft-float */ |
| 1544 | 1538 | dcn10_resource_construct_fp(dc); |
| 1545 | −#endif | |
| 1546 | 1539 | |
| 1547 | 1540 | pool->base.pp_smu = dcn10_pp_smu_create(ctx); |
| 1548 | 1541 | |
| @@ -17,10 +17,6 @@ ifdef CONFIG_PPC64 · 16 unmodified lines | ||
| 17 | 17 | CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -mhard-float -maltivec |
| 18 | 18 | endif |
| 19 | 19 | |
| 20 | −ifdef CONFIG_ARM64 | |
| 21 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -mgeneral-regs-only | |
| 22 | −endif | |
| 23 | − | |
| 24 | 20 | ifdef CONFIG_CC_IS_GCC |
| 25 | 21 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 26 | 22 | IS_OLD_GCC = 1 |
| @@ -13,10 +13,6 @@ ifdef CONFIG_PPC64 · 12 unmodified lines | ||
| 13 | 13 | CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mhard-float -maltivec |
| 14 | 14 | endif |
| 15 | 15 | |
| 16 | −ifdef CONFIG_ARM64 | |
| 17 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mgeneral-regs-only | |
| 18 | −endif | |
| 19 | − | |
| 20 | 16 | ifdef CONFIG_CC_IS_GCC |
| 21 | 17 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 22 | 18 | IS_OLD_GCC = 1 |
| @@ -41,11 +41,6 @@ CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -mhard-float -maltivec · 40 unmodified lines | ||
| 41 | 41 | CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -mhard-float -maltivec |
| 42 | 42 | endif |
| 43 | 43 | |
| 44 | −ifdef CONFIG_ARM64 | |
| 45 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -mgeneral-regs-only | |
| 46 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -mgeneral-regs-only | |
| 47 | −endif | |
| 48 | − | |
| 49 | 44 | ifdef CONFIG_CC_IS_GCC |
| 50 | 45 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 51 | 46 | IS_OLD_GCC = 1 |
| @@ -21,10 +21,6 @@ ifdef CONFIG_PPC64 · 20 unmodified lines | ||
| 21 | 21 | CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mhard-float -maltivec |
| 22 | 22 | endif |
| 23 | 23 | |
| 24 | −ifdef CONFIG_ARM64 | |
| 25 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mgeneral-regs-only | |
| 26 | −endif | |
| 27 | − | |
| 28 | 24 | ifdef CONFIG_CC_IS_GCC |
| 29 | 25 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 30 | 26 | IS_OLD_GCC = 1 |
| @@ -1731,6 +1731,7 @@ static struct resource_funcs dcn301_res_pool_funcs = { · 1730 unmodified lines | ||
| 1731 | 1731 | .populate_dml_pipes = dcn30_populate_dml_pipes_from_context, |
| 1732 | 1732 | .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer, |
| 1733 | 1733 | .add_stream_to_ctx = dcn30_add_stream_to_ctx, |
| 1734 | + .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource, | |
| 1734 | 1735 | .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, |
| 1735 | 1736 | .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context, |
| 1736 | 1737 | .set_mcif_arb_params = dcn30_set_mcif_arb_params, |
| @@ -20,10 +20,6 @@ ifdef CONFIG_PPC64 · 19 unmodified lines | ||
| 20 | 20 | CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -mhard-float -maltivec |
| 21 | 21 | endif |
| 22 | 22 | |
| 23 | −ifdef CONFIG_ARM64 | |
| 24 | −CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -mgeneral-regs-only | |
| 25 | −endif | |
| 26 | − | |
| 27 | 23 | ifdef CONFIG_CC_IS_GCC |
| 28 | 24 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 29 | 25 | IS_OLD_GCC = 1 |
| @@ -33,10 +33,6 @@ ifdef CONFIG_PPC64 · 32 unmodified lines | ||
| 33 | 33 | dml_ccflags := -mhard-float -maltivec |
| 34 | 34 | endif |
| 35 | 35 | |
| 36 | −ifdef CONFIG_ARM64 | |
| 37 | −dml_rcflags := -mgeneral-regs-only | |
| 38 | −endif | |
| 39 | − | |
| 40 | 36 | ifdef CONFIG_CC_IS_GCC |
| 41 | 37 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 42 | 38 | IS_OLD_GCC = 1 |
| @@ -2635,14 +2635,15 @@ static void dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndP · 2634 unmodified lines | ||
| 2635 | 2635 | } |
| 2636 | 2636 | |
| 2637 | 2637 | if (mode_lib->vba.DRAMClockChangeSupportsVActive && |
| 2638 | − mode_lib->vba.MinActiveDRAMClockChangeMargin > 60 && | |
| 2639 | − mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 0) { | |
| 2638 | + mode_lib->vba.MinActiveDRAMClockChangeMargin > 60) { | |
| 2640 | 2639 | mode_lib->vba.DRAMClockChangeWatermark += 25; |
| 2641 | 2640 | |
| 2642 | 2641 | for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { |
| 2643 | − if (mode_lib->vba.DRAMClockChangeWatermark > | |
| 2644 | − dml_max(mode_lib->vba.StutterEnterPlusExitWatermark, mode_lib->vba.UrgentWatermark)) | |
| 2645 | − mode_lib->vba.MinTTUVBlank[k] += 25; | |
| 2642 | + if (mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 0) { | |
| 2643 | + if (mode_lib->vba.DRAMClockChangeWatermark > | |
| 2644 | + dml_max(mode_lib->vba.StutterEnterPlusExitWatermark, mode_lib->vba.UrgentWatermark)) | |
| 2645 | + mode_lib->vba.MinTTUVBlank[k] += 25; | |
| 2646 | + } | |
| 2646 | 2647 | } |
| 2647 | 2648 | |
| 2648 | 2649 | mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive; |
| @@ -10,10 +10,6 @@ ifdef CONFIG_PPC64 · 9 unmodified lines | ||
| 10 | 10 | dsc_ccflags := -mhard-float -maltivec |
| 11 | 11 | endif |
| 12 | 12 | |
| 13 | −ifdef CONFIG_ARM64 | |
| 14 | −dsc_rcflags := -mgeneral-regs-only | |
| 15 | −endif | |
| 16 | − | |
| 17 | 13 | ifdef CONFIG_CC_IS_GCC |
| 18 | 14 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 19 | 15 | IS_OLD_GCC = 1 |
| @@ -55,10 +55,6 @@ · 54 unmodified lines | ||
| 55 | 55 | #include <asm/fpu/api.h> |
| 56 | 56 | #define DC_FP_START() kernel_fpu_begin() |
| 57 | 57 | #define DC_FP_END() kernel_fpu_end() |
| 58 | −#elif defined(CONFIG_ARM64) | |
| 59 | −#include <asm/neon.h> | |
| 60 | −#define DC_FP_START() kernel_neon_begin() | |
| 61 | −#define DC_FP_END() kernel_neon_end() | |
| 62 | 58 | #elif defined(CONFIG_PPC64) |
| 63 | 59 | #include <asm/switch_to.h> |
| 64 | 60 | #include <asm/cputable.h> |
| @@ -251,7 +251,7 @@ static int smu10_set_hard_min_gfxclk_by_freq(struct pp_hwmgr *hwmgr, uint32_t cl · 250 unmodified lines | ||
| 251 | 251 | smu10_data->gfx_actual_soft_min_freq = clock; |
| 252 | 252 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 253 | 253 | PPSMC_MSG_SetHardMinGfxClk, |
| 254 | − smu10_data->gfx_actual_soft_min_freq, | |
| 254 | + clock, | |
| 255 | 255 | NULL); |
| 256 | 256 | } |
| 257 | 257 | return 0; |
| @@ -558,7 +558,8 @@ static int smu10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) · 300 unmodified lines | ||
| 558 | 558 | |
| 559 | 559 | /* enable the pp_od_clk_voltage sysfs file */ |
| 560 | 560 | hwmgr->od_enabled = 1; |
| 561 | − | |
| 561 | + /* disabled fine grain tuning function by default */ | |
| 562 | + data->fine_grain_enabled = 0; | |
| 562 | 563 | return result; |
| 563 | 564 | } |
| 564 | 565 | |
| @@ -597,6 +598,7 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 32 unmodified lines | ||
| 597 | 598 | uint32_t min_mclk = hwmgr->display_config->min_mem_set_clock/100; |
| 598 | 599 | uint32_t index_fclk = data->clock_vol_info.vdd_dep_on_fclk->count - 1; |
| 599 | 600 | uint32_t index_socclk = data->clock_vol_info.vdd_dep_on_socclk->count - 1; |
| 601 | + uint32_t fine_grain_min_freq = 0, fine_grain_max_freq = 0; | |
| 600 | 602 | |
| 601 | 603 | if (hwmgr->smu_version < 0x1E3700) { |
| 602 | 604 | pr_info("smu firmware version too old, can not set dpm level\n"); |
| @@ -613,6 +615,14 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 10 unmodified lines | ||
| 613 | 615 | switch (level) { |
| 614 | 616 | case AMD_DPM_FORCED_LEVEL_HIGH: |
| 615 | 617 | case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: |
| 618 | + data->fine_grain_enabled = 0; | |
| 619 | + | |
| 620 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &fine_grain_min_freq); | |
| 621 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &fine_grain_max_freq); | |
| 622 | + | |
| 623 | + data->gfx_actual_soft_min_freq = fine_grain_min_freq; | |
| 624 | + data->gfx_actual_soft_max_freq = fine_grain_max_freq; | |
| 625 | + | |
| 616 | 626 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 617 | 627 | PPSMC_MSG_SetHardMinGfxClk, |
| 618 | 628 | data->gfx_max_freq_limit/100, |
| @@ -648,6 +658,14 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 29 unmodified lines | ||
| 648 | 658 | NULL); |
| 649 | 659 | break; |
| 650 | 660 | case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: |
| 661 | + data->fine_grain_enabled = 0; | |
| 662 | + | |
| 663 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &fine_grain_min_freq); | |
| 664 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &fine_grain_max_freq); | |
| 665 | + | |
| 666 | + data->gfx_actual_soft_min_freq = fine_grain_min_freq; | |
| 667 | + data->gfx_actual_soft_max_freq = fine_grain_max_freq; | |
| 668 | + | |
| 651 | 669 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 652 | 670 | PPSMC_MSG_SetHardMinGfxClk, |
| 653 | 671 | min_sclk, |
| @@ -658,6 +676,14 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 4 unmodified lines | ||
| 658 | 676 | NULL); |
| 659 | 677 | break; |
| 660 | 678 | case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: |
| 679 | + data->fine_grain_enabled = 0; | |
| 680 | + | |
| 681 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &fine_grain_min_freq); | |
| 682 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &fine_grain_max_freq); | |
| 683 | + | |
| 684 | + data->gfx_actual_soft_min_freq = fine_grain_min_freq; | |
| 685 | + data->gfx_actual_soft_max_freq = fine_grain_max_freq; | |
| 686 | + | |
| 661 | 687 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 662 | 688 | PPSMC_MSG_SetHardMinFclkByFreq, |
| 663 | 689 | min_mclk, |
| @@ -668,6 +694,14 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 4 unmodified lines | ||
| 668 | 694 | NULL); |
| 669 | 695 | break; |
| 670 | 696 | case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: |
| 697 | + data->fine_grain_enabled = 0; | |
| 698 | + | |
| 699 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &fine_grain_min_freq); | |
| 700 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &fine_grain_max_freq); | |
| 701 | + | |
| 702 | + data->gfx_actual_soft_min_freq = fine_grain_min_freq; | |
| 703 | + data->gfx_actual_soft_max_freq = fine_grain_max_freq; | |
| 704 | + | |
| 671 | 705 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 672 | 706 | PPSMC_MSG_SetHardMinGfxClk, |
| 673 | 707 | SMU10_UMD_PSTATE_GFXCLK, |
| @@ -703,6 +737,14 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 29 unmodified lines | ||
| 703 | 737 | NULL); |
| 704 | 738 | break; |
| 705 | 739 | case AMD_DPM_FORCED_LEVEL_AUTO: |
| 740 | + data->fine_grain_enabled = 0; | |
| 741 | + | |
| 742 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &fine_grain_min_freq); | |
| 743 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &fine_grain_max_freq); | |
| 744 | + | |
| 745 | + data->gfx_actual_soft_min_freq = fine_grain_min_freq; | |
| 746 | + data->gfx_actual_soft_max_freq = fine_grain_max_freq; | |
| 747 | + | |
| 706 | 748 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 707 | 749 | PPSMC_MSG_SetHardMinGfxClk, |
| 708 | 750 | min_sclk, |
| @@ -741,6 +783,14 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 32 unmodified lines | ||
| 741 | 783 | NULL); |
| 742 | 784 | break; |
| 743 | 785 | case AMD_DPM_FORCED_LEVEL_LOW: |
| 786 | + data->fine_grain_enabled = 0; | |
| 787 | + | |
| 788 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &fine_grain_min_freq); | |
| 789 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &fine_grain_max_freq); | |
| 790 | + | |
| 791 | + data->gfx_actual_soft_min_freq = fine_grain_min_freq; | |
| 792 | + data->gfx_actual_soft_max_freq = fine_grain_max_freq; | |
| 793 | + | |
| 744 | 794 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 745 | 795 | PPSMC_MSG_SetHardMinGfxClk, |
| 746 | 796 | data->gfx_min_freq_limit/100, |
| @@ -759,6 +809,7 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 12 unmodified lines | ||
| 759 | 809 | NULL); |
| 760 | 810 | break; |
| 761 | 811 | case AMD_DPM_FORCED_LEVEL_MANUAL: |
| 812 | + data->fine_grain_enabled = 1; | |
| 762 | 813 | case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT: |
| 763 | 814 | default: |
| 764 | 815 | break; |
| @@ -948,6 +999,8 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, · 183 unmodified lines | ||
| 948 | 999 | struct smu10_voltage_dependency_table *mclk_table = |
| 949 | 1000 | data->clock_vol_info.vdd_dep_on_fclk; |
| 950 | 1001 | uint32_t i, now, size = 0; |
| 1002 | + uint32_t min_freq, max_freq = 0; | |
| 1003 | + uint32_t ret = 0; | |
| 951 | 1004 | |
| 952 | 1005 | switch (type) { |
| 953 | 1006 | case PP_SCLK: |
| @@ -983,18 +1036,28 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, · 29 unmodified lines | ||
| 983 | 1036 | break; |
| 984 | 1037 | case OD_SCLK: |
| 985 | 1038 | if (hwmgr->od_enabled) { |
| 986 | − size = sprintf(buf, "%s:\n", "OD_SCLK"); | |
| 1039 | + ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); | |
| 1040 | + if (ret) | |
| 1041 | + return ret; | |
| 1042 | + ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); | |
| 1043 | + if (ret) | |
| 1044 | + return ret; | |
| 987 | 1045 | |
| 1046 | + size = sprintf(buf, "%s:\n", "OD_SCLK"); | |
| 988 | 1047 | size += sprintf(buf + size, "0: %10uMhz\n", |
| 989 | − (data->gfx_actual_soft_min_freq > 0) ? data->gfx_actual_soft_min_freq : data->gfx_min_freq_limit/100); | |
| 990 | − size += sprintf(buf + size, "1: %10uMhz\n", data->gfx_max_freq_limit/100); | |
| 1048 | + (data->gfx_actual_soft_min_freq > 0) ? data->gfx_actual_soft_min_freq : min_freq); | |
| 1049 | + size += sprintf(buf + size, "1: %10uMhz\n", | |
| 1050 | + (data->gfx_actual_soft_max_freq > 0) ? data->gfx_actual_soft_max_freq : max_freq); | |
| 991 | 1051 | } |
| 992 | 1052 | break; |
| 993 | 1053 | case OD_RANGE: |
| 994 | 1054 | if (hwmgr->od_enabled) { |
| 995 | − uint32_t min_freq, max_freq = 0; | |
| 996 | − smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); | |
| 997 | − smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); | |
| 1055 | + ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); | |
| 1056 | + if (ret) | |
| 1057 | + return ret; | |
| 1058 | + ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); | |
| 1059 | + if (ret) | |
| 1060 | + return ret; | |
| 998 | 1061 | |
| 999 | 1062 | size = sprintf(buf, "%s:\n", "OD_RANGE"); |
| 1000 | 1063 | size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n", |
| @@ -1414,23 +1477,96 @@ static int smu10_set_fine_grain_clk_vol(struct pp_hwmgr *hwmgr, · 413 unmodified lines | ||
| 1414 | 1477 | enum PP_OD_DPM_TABLE_COMMAND type, |
| 1415 | 1478 | long *input, uint32_t size) |
| 1416 | 1479 | { |
| 1480 | + uint32_t min_freq, max_freq = 0; | |
| 1481 | + struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); | |
| 1482 | + int ret = 0; | |
| 1483 | + | |
| 1417 | 1484 | if (!hwmgr->od_enabled) { |
| 1418 | 1485 | pr_err("Fine grain not support\n"); |
| 1419 | 1486 | return -EINVAL; |
| 1420 | 1487 | } |
| 1421 | 1488 | |
| 1422 | − if (size != 2) { | |
| 1423 | − pr_err("Input parameter number not correct\n"); | |
| 1489 | + if (!smu10_data->fine_grain_enabled) { | |
| 1490 | + pr_err("Fine grain not started\n"); | |
| 1424 | 1491 | return -EINVAL; |
| 1425 | 1492 | } |
| 1426 | 1493 | |
| 1427 | 1494 | if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) { |
| 1428 | − if (input[0] == 0) | |
| 1429 | − smu10_set_hard_min_gfxclk_by_freq(hwmgr, input[1]); | |
| 1430 | − else if (input[0] == 1) | |
| 1431 | − smu10_set_soft_max_gfxclk_by_freq(hwmgr, input[1]); | |
| 1432 | − else | |
| 1495 | + if (size != 2) { | |
| 1496 | + pr_err("Input parameter number not correct\n"); | |
| 1433 | 1497 | return -EINVAL; |
| 1498 | + } | |
| 1499 | + | |
| 1500 | + if (input[0] == 0) { | |
| 1501 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); | |
| 1502 | + if (input[1] < min_freq) { | |
| 1503 | + pr_err("Fine grain setting minimum sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n", | |
| 1504 | + input[1], min_freq); | |
| 1505 | + return -EINVAL; | |
| 1506 | + } | |
| 1507 | + smu10_data->gfx_actual_soft_min_freq = input[1]; | |
| 1508 | + } else if (input[0] == 1) { | |
| 1509 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); | |
| 1510 | + if (input[1] > max_freq) { | |
| 1511 | + pr_err("Fine grain setting maximum sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n", | |
| 1512 | + input[1], max_freq); | |
| 1513 | + return -EINVAL; | |
| 1514 | + } | |
| 1515 | + smu10_data->gfx_actual_soft_max_freq = input[1]; | |
| 1516 | + } else { | |
| 1517 | + return -EINVAL; | |
| 1518 | + } | |
| 1519 | + } else if (type == PP_OD_RESTORE_DEFAULT_TABLE) { | |
| 1520 | + if (size != 0) { | |
| 1521 | + pr_err("Input parameter number not correct\n"); | |
| 1522 | + return -EINVAL; | |
| 1523 | + } | |
| 1524 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); | |
| 1525 | + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); | |
| 1526 | + | |
| 1527 | + smu10_data->gfx_actual_soft_min_freq = min_freq; | |
| 1528 | + smu10_data->gfx_actual_soft_max_freq = max_freq; | |
| 1529 | + | |
| 1530 | + ret = smum_send_msg_to_smc_with_parameter(hwmgr, | |
| 1531 | + PPSMC_MSG_SetHardMinGfxClk, | |
| 1532 | + min_freq, | |
| 1533 | + NULL); | |
| 1534 | + if (ret) | |
| 1535 | + return ret; | |
| 1536 | + | |
| 1537 | + ret = smum_send_msg_to_smc_with_parameter(hwmgr, | |
| 1538 | + PPSMC_MSG_SetSoftMaxGfxClk, | |
| 1539 | + max_freq, | |
| 1540 | + NULL); | |
| 1541 | + if (ret) | |
| 1542 | + return ret; | |
| 1543 | + } else if (type == PP_OD_COMMIT_DPM_TABLE) { | |
| 1544 | + if (size != 0) { | |
| 1545 | + pr_err("Input parameter number not correct\n"); | |
| 1546 | + return -EINVAL; | |
| 1547 | + } | |
| 1548 | + | |
| 1549 | + if (smu10_data->gfx_actual_soft_min_freq > smu10_data->gfx_actual_soft_max_freq) { | |
| 1550 | + pr_err("The setting minimun sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n", | |
| 1551 | + smu10_data->gfx_actual_soft_min_freq, smu10_data->gfx_actual_soft_max_freq); | |
| 1552 | + return -EINVAL; | |
| 1553 | + } | |
| 1554 | + | |
| 1555 | + ret = smum_send_msg_to_smc_with_parameter(hwmgr, | |
| 1556 | + PPSMC_MSG_SetHardMinGfxClk, | |
| 1557 | + smu10_data->gfx_actual_soft_min_freq, | |
| 1558 | + NULL); | |
| 1559 | + if (ret) | |
| 1560 | + return ret; | |
| 1561 | + | |
| 1562 | + ret = smum_send_msg_to_smc_with_parameter(hwmgr, | |
| 1563 | + PPSMC_MSG_SetSoftMaxGfxClk, | |
| 1564 | + smu10_data->gfx_actual_soft_max_freq, | |
| 1565 | + NULL); | |
| 1566 | + if (ret) | |
| 1567 | + return ret; | |
| 1568 | + } else { | |
| 1569 | + return -EINVAL; | |
| 1434 | 1570 | } |
| 1435 | 1571 | |
| 1436 | 1572 | return 0; |
| @@ -283,6 +283,7 @@ struct smu10_hwmgr { · 282 unmodified lines | ||
| 283 | 283 | uint32_t vclk_soft_min; |
| 284 | 284 | uint32_t dclk_soft_min; |
| 285 | 285 | uint32_t gfx_actual_soft_min_freq; |
| 286 | + uint32_t gfx_actual_soft_max_freq; | |
| 286 | 287 | uint32_t gfx_min_freq_limit; |
| 287 | 288 | uint32_t gfx_max_freq_limit; /* in 10Khz*/ |
| 288 | 289 | |
| @@ -299,6 +300,8 @@ struct smu10_hwmgr { · 10 unmodified lines | ||
| 299 | 300 | bool need_min_deep_sleep_dcefclk; |
| 300 | 301 | uint32_t deep_sleep_dcefclk; |
| 301 | 302 | uint32_t num_active_display; |
| 303 | + | |
| 304 | + bool fine_grain_enabled; | |
| 302 | 305 | }; |
| 303 | 306 | |
| 304 | 307 | struct pp_hwmgr; |
| @@ -2372,7 +2372,7 @@ static void sienna_cichlid_fill_i2c_req(SwI2cRequest_t *req, bool write, · 2371 unmodified lines | ||
| 2372 | 2372 | { |
| 2373 | 2373 | int i; |
| 2374 | 2374 | |
| 2375 | − req->I2CcontrollerPort = 0; | |
| 2375 | + req->I2CcontrollerPort = 1; | |
| 2376 | 2376 | req->I2CSpeed = 2; |
| 2377 | 2377 | req->SlaveAddress = address; |
| 2378 | 2378 | req->NumCmds = numbytes; |
| @@ -252,7 +252,8 @@ static int vangogh_get_smu_metrics_data(struct smu_context *smu, · 251 unmodified lines | ||
| 252 | 252 | *value = metrics->UvdActivity; |
| 253 | 253 | break; |
| 254 | 254 | case METRICS_AVERAGE_SOCKETPOWER: |
| 255 | − *value = metrics->CurrentSocketPower; | |
| 255 | + *value = (metrics->CurrentSocketPower << 8) / | |
| 256 | + 1000 ; | |
| 256 | 257 | break; |
| 257 | 258 | case METRICS_TEMPERATURE_EDGE: |
| 258 | 259 | *value = metrics->GfxTemperature / 100 * |
| @@ -188,6 +188,7 @@ static int renoir_get_dpm_clk_limited(struct smu_context *smu, enum smu_clk_type · 187 unmodified lines | ||
| 188 | 188 | return -EINVAL; |
| 189 | 189 | *freq = clk_table->SocClocks[dpm_level].Freq; |
| 190 | 190 | break; |
| 191 | + case SMU_UCLK: | |
| 191 | 192 | case SMU_MCLK: |
| 192 | 193 | if (dpm_level >= NUM_FCLK_DPM_LEVELS) |
| 193 | 194 | return -EINVAL; |
| @@ -225,6 +225,7 @@ int smu_v12_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_ · 224 unmodified lines | ||
| 225 | 225 | break; |
| 226 | 226 | case SMU_FCLK: |
| 227 | 227 | case SMU_MCLK: |
| 228 | + case SMU_UCLK: | |
| 228 | 229 | ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinFclkByFreq, min, NULL); |
| 229 | 230 | if (ret) |
| 230 | 231 | return ret; |
| @@ -1163,7 +1163,14 @@ retry: · 1162 unmodified lines | ||
| 1163 | 1163 | if (ret) |
| 1164 | 1164 | goto out; |
| 1165 | 1165 | |
| 1166 | − if (old_fb->format != fb->format) { | |
| 1166 | + /* | |
| 1167 | + * Only check the FOURCC format code, excluding modifiers. This is | |
| 1168 | + * enough for all legacy drivers. Atomic drivers have their own | |
| 1169 | + * checks in their ->atomic_check implementation, which will | |
| 1170 | + * return -EINVAL if any hw or driver constraint is violated due | |
| 1171 | + * to modifier changes. | |
| 1172 | + */ | |
| 1173 | + if (old_fb->format->format != fb->format->format) { | |
| 1167 | 1174 | DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n"); |
| 1168 | 1175 | ret = -EINVAL; |
| 1169 | 1176 | goto out; |
| @@ -38,6 +38,7 @@ i915-y += i915_drv.o \ · 37 unmodified lines | ||
| 38 | 38 | i915_config.o \ |
| 39 | 39 | i915_irq.o \ |
| 40 | 40 | i915_getparam.o \ |
| 41 | + i915_mitigations.o \ | |
| 41 | 42 | i915_params.o \ |
| 42 | 43 | i915_pci.o \ |
| 43 | 44 | i915_scatterlist.o \ |
| @@ -1616,10 +1616,6 @@ static void gen11_dsi_get_power_domains(struct intel_encoder *encoder, · 1615 unmodified lines | ||
| 1616 | 1616 | |
| 1617 | 1617 | get_dsi_io_power_domains(i915, |
| 1618 | 1618 | enc_to_intel_dsi(encoder)); |
| 1619 | − | |
| 1620 | − if (crtc_state->dsc.compression_enable) | |
| 1621 | − intel_display_power_get(i915, | |
| 1622 | − intel_dsc_power_domain(crtc_state)); | |
| 1623 | 1619 | } |
| 1624 | 1620 | |
| 1625 | 1621 | static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, |
| @@ -1436,6 +1436,9 @@ struct intel_dp { · 1435 unmodified lines | ||
| 1436 | 1436 | bool ycbcr_444_to_420; |
| 1437 | 1437 | } dfp; |
| 1438 | 1438 | |
| 1439 | + /* To control wakeup latency, e.g. for irq-driven dp aux transfers. */ | |
| 1440 | + struct pm_qos_request pm_qos; | |
| 1441 | + | |
| 1439 | 1442 | /* Display stream compression testing */ |
| 1440 | 1443 | bool force_dsc_en; |
| 1441 | 1444 | |
| @@ -1489,7 +1489,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp, · 1488 unmodified lines | ||
| 1489 | 1489 | * lowest possible wakeup latency and so prevent the cpu from going into |
| 1490 | 1490 | * deep sleep states. |
| 1491 | 1491 | */ |
| 1492 | − cpu_latency_qos_update_request(&i915->pm_qos, 0); | |
| 1492 | + cpu_latency_qos_update_request(&intel_dp->pm_qos, 0); | |
| 1493 | 1493 | |
| 1494 | 1494 | intel_dp_check_edp(intel_dp); |
| 1495 | 1495 | |
| @@ -1622,7 +1622,7 @@ done: · 126 unmodified lines | ||
| 1622 | 1622 | |
| 1623 | 1623 | ret = recv_bytes; |
| 1624 | 1624 | out: |
| 1625 | − cpu_latency_qos_update_request(&i915->pm_qos, PM_QOS_DEFAULT_VALUE); | |
| 1625 | + cpu_latency_qos_update_request(&intel_dp->pm_qos, PM_QOS_DEFAULT_VALUE); | |
| 1626 | 1626 | |
| 1627 | 1627 | if (vdd) |
| 1628 | 1628 | edp_panel_vdd_off(intel_dp, false); |
| @@ -1898,6 +1898,9 @@ static i915_reg_t tgl_aux_data_reg(struct intel_dp *intel_dp, int index) · 269 unmodified lines | ||
| 1898 | 1898 | static void |
| 1899 | 1899 | intel_dp_aux_fini(struct intel_dp *intel_dp) |
| 1900 | 1900 | { |
| 1901 | + if (cpu_latency_qos_request_active(&intel_dp->pm_qos)) | |
| 1902 | + cpu_latency_qos_remove_request(&intel_dp->pm_qos); | |
| 1903 | + | |
| 1901 | 1904 | kfree(intel_dp->aux.name); |
| 1902 | 1905 | } |
| 1903 | 1906 | |
| @@ -1950,6 +1953,7 @@ intel_dp_aux_init(struct intel_dp *intel_dp) · 46 unmodified lines | ||
| 1950 | 1953 | encoder->base.name); |
| 1951 | 1954 | |
| 1952 | 1955 | intel_dp->aux.transfer = intel_dp_aux_transfer; |
| 1956 | + cpu_latency_qos_add_request(&intel_dp->pm_qos, PM_QOS_DEFAULT_VALUE); | |
| 1953 | 1957 | } |
| 1954 | 1958 | |
| 1955 | 1959 | bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp) |
| @@ -1650,16 +1650,13 @@ static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unus · 1649 unmodified lines | ||
| 1650 | 1650 | val = pch_get_backlight(connector); |
| 1651 | 1651 | else |
| 1652 | 1652 | val = lpt_get_backlight(connector); |
| 1653 | − val = intel_panel_compute_brightness(connector, val); | |
| 1654 | − panel->backlight.level = clamp(val, panel->backlight.min, | |
| 1655 | − panel->backlight.max); | |
| 1656 | 1653 | |
| 1657 | 1654 | if (cpu_mode) { |
| 1658 | 1655 | drm_dbg_kms(&dev_priv->drm, |
| 1659 | 1656 | "CPU backlight register was enabled, switching to PCH override\n"); |
| 1660 | 1657 | |
| 1661 | 1658 | /* Write converted CPU PWM value to PCH override register */ |
| 1662 | − lpt_set_backlight(connector->base.state, panel->backlight.level); | |
| 1659 | + lpt_set_backlight(connector->base.state, val); | |
| 1663 | 1660 | intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, |
| 1664 | 1661 | pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE); |
| 1665 | 1662 | |
| @@ -1667,6 +1664,10 @@ static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unus · 1 unmodified line | ||
| 1667 | 1664 | cpu_ctl2 & ~BLM_PWM_ENABLE); |
| 1668 | 1665 | } |
| 1669 | 1666 | |
| 1667 | + val = intel_panel_compute_brightness(connector, val); | |
| 1668 | + panel->backlight.level = clamp(val, panel->backlight.min, | |
| 1669 | + panel->backlight.max); | |
| 1670 | + | |
| 1670 | 1671 | return 0; |
| 1671 | 1672 | } |
| 1672 | 1673 | |
| @@ -812,10 +812,20 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, · 811 unmodified lines | ||
| 812 | 812 | intel_dsi_prepare(encoder, pipe_config); |
| 813 | 813 | |
| 814 | 814 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_ON); |
| 815 | − intel_dsi_msleep(intel_dsi, intel_dsi->panel_on_delay); | |
| 816 | 815 | |
| 817 | − /* Deassert reset */ | |
| 818 | − intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); | |
| 816 | + /* | |
| 817 | + * Give the panel time to power-on and then deassert its reset. | |
| 818 | + * Depending on the VBT MIPI sequences version the deassert-seq | |
| 819 | + * may contain the necessary delay, intel_dsi_msleep() will skip | |
| 820 | + * the delay in that case. If there is no deassert-seq, then an | |
| 821 | + * unconditional msleep is used to give the panel time to power-on. | |
| 822 | + */ | |
| 823 | + if (dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET]) { | |
| 824 | + intel_dsi_msleep(intel_dsi, intel_dsi->panel_on_delay); | |
| 825 | + intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); | |
| 826 | + } else { | |
| 827 | + msleep(intel_dsi->panel_on_delay); | |
| 828 | + } | |
| 819 | 829 | |
| 820 | 830 | if (IS_GEMINILAKE(dev_priv)) { |
| 821 | 831 | glk_cold_boot = glk_dsi_enable_io(encoder); |
| @@ -1046,7 +1046,7 @@ static void reloc_gpu_flush(struct i915_execbuffer *eb, struct reloc_cache *cach · 1045 unmodified lines | ||
| 1046 | 1046 | GEM_BUG_ON(cache->rq_size >= obj->base.size / sizeof(u32)); |
| 1047 | 1047 | cache->rq_cmd[cache->rq_size] = MI_BATCH_BUFFER_END; |
| 1048 | 1048 | |
| 1049 | − __i915_gem_object_flush_map(obj, 0, sizeof(u32) * (cache->rq_size + 1)); | |
| 1049 | + i915_gem_object_flush_map(obj); | |
| 1050 | 1050 | i915_gem_object_unpin_map(obj); |
| 1051 | 1051 | |
| 1052 | 1052 | intel_gt_chipset_flush(cache->rq->engine->gt); |
| @@ -1296,6 +1296,8 @@ static int __reloc_gpu_alloc(struct i915_execbuffer *eb, · 243 unmodified lines | ||
| 1296 | 1296 | goto err_pool; |
| 1297 | 1297 | } |
| 1298 | 1298 | |
| 1299 | + memset32(cmd, 0, pool->obj->base.size / sizeof(u32)); | |
| 1300 | + | |
| 1299 | 1301 | batch = i915_vma_instance(pool->obj, vma->vm, NULL); |
| 1300 | 1302 | if (IS_ERR(batch)) { |
| 1301 | 1303 | err = PTR_ERR(batch); |
| @@ -7,8 +7,6 @@ · 6 unmodified lines | ||
| 7 | 7 | #include "i915_drv.h" |
| 8 | 8 | #include "intel_gpu_commands.h" |
| 9 | 9 | |
| 10 | −#define MAX_URB_ENTRIES 64 | |
| 11 | −#define STATE_SIZE (4 * 1024) | |
| 12 | 10 | #define GT3_INLINE_DATA_DELAYS 0x1E00 |
| 13 | 11 | #define batch_advance(Y, CS) GEM_BUG_ON((Y)->end != (CS)) |
| 14 | 12 | |
| @@ -34,38 +32,59 @@ struct batch_chunk { · 19 unmodified lines | ||
| 34 | 32 | }; |
| 35 | 33 | |
| 36 | 34 | struct batch_vals { |
| 37 | − u32 max_primitives; | |
| 38 | − u32 max_urb_entries; | |
| 39 | − u32 cmd_size; | |
| 40 | − u32 state_size; | |
| 35 | + u32 max_threads; | |
| 41 | 36 | u32 state_start; |
| 42 | − u32 batch_size; | |
| 37 | + u32 surface_start; | |
| 43 | 38 | u32 surface_height; |
| 44 | 39 | u32 surface_width; |
| 45 | − u32 scratch_size; | |
| 46 | − u32 max_size; | |
| 40 | + u32 size; | |
| 47 | 41 | }; |
| 48 | 42 | |
| 43 | +static inline int num_primitives(const struct batch_vals *bv) | |
| 44 | +{ | |
| 45 | + /* | |
| 46 | + * We need to saturate the GPU with work in order to dispatch | |
| 47 | + * a shader on every HW thread, and clear the thread-local registers. | |
| 48 | + * In short, we have to dispatch work faster than the shaders can | |
| 49 | + * run in order to fill the EU and occupy each HW thread. | |
| 50 | + */ | |
| 51 | + return bv->max_threads; | |
| 52 | +} | |
| 53 | + | |
| 49 | 54 | static void |
| 50 | 55 | batch_get_defaults(struct drm_i915_private *i915, struct batch_vals *bv) |
| 51 | 56 | { |
| 52 | 57 | if (IS_HASWELL(i915)) { |
| 53 | − bv->max_primitives = 280; | |
| 54 | − bv->max_urb_entries = MAX_URB_ENTRIES; | |
| 58 | + switch (INTEL_INFO(i915)->gt) { | |
| 59 | + default: | |
| 60 | + case 1: | |
| 61 | + bv->max_threads = 70; | |
| 62 | + break; | |
| 63 | + case 2: | |
| 64 | + bv->max_threads = 140; | |
| 65 | + break; | |
| 66 | + case 3: | |
| 67 | + bv->max_threads = 280; | |
| 68 | + break; | |
| 69 | + } | |
| 55 | 70 | bv->surface_height = 16 * 16; |
| 56 | 71 | bv->surface_width = 32 * 2 * 16; |
| 57 | 72 | } else { |
| 58 | − bv->max_primitives = 128; | |
| 59 | − bv->max_urb_entries = MAX_URB_ENTRIES / 2; | |
| 73 | + switch (INTEL_INFO(i915)->gt) { | |
| 74 | + default: | |
| 75 | + case 1: /* including vlv */ | |
| 76 | + bv->max_threads = 36; | |
| 77 | + break; | |
| 78 | + case 2: | |
| 79 | + bv->max_threads = 128; | |
| 80 | + break; | |
| 81 | + } | |
| 60 | 82 | bv->surface_height = 16 * 8; |
| 61 | 83 | bv->surface_width = 32 * 16; |
| 62 | 84 | } |
| 63 | − bv->cmd_size = bv->max_primitives * 4096; | |
| 64 | − bv->state_size = STATE_SIZE; | |
| 65 | − bv->state_start = bv->cmd_size; | |
| 66 | − bv->batch_size = bv->cmd_size + bv->state_size; | |
| 67 | − bv->scratch_size = bv->surface_height * bv->surface_width; | |
| 68 | − bv->max_size = bv->batch_size + bv->scratch_size; | |
| 85 | + bv->state_start = round_up(SZ_1K + num_primitives(bv) * 64, SZ_4K); | |
| 86 | + bv->surface_start = bv->state_start + SZ_4K; | |
| 87 | + bv->size = bv->surface_start + bv->surface_height * bv->surface_width; | |
| 69 | 88 | } |
| 70 | 89 | |
| 71 | 90 | static void batch_init(struct batch_chunk *bc, |
| @@ -155,7 +174,8 @@ static u32 · 83 unmodified lines | ||
| 155 | 174 | gen7_fill_binding_table(struct batch_chunk *state, |
| 156 | 175 | const struct batch_vals *bv) |
| 157 | 176 | { |
| 158 | − u32 surface_start = gen7_fill_surface_state(state, bv->batch_size, bv); | |
| 177 | + u32 surface_start = | |
| 178 | + gen7_fill_surface_state(state, bv->surface_start, bv); | |
| 159 | 179 | u32 *cs = batch_alloc_items(state, 32, 8); |
| 160 | 180 | u32 offset = batch_offset(state, cs); |
| 161 | 181 | |
| @@ -214,9 +234,9 @@ static void · 52 unmodified lines | ||
| 214 | 234 | gen7_emit_state_base_address(struct batch_chunk *batch, |
| 215 | 235 | u32 surface_state_base) |
| 216 | 236 | { |
| 217 | − u32 *cs = batch_alloc_items(batch, 0, 12); | |
| 237 | + u32 *cs = batch_alloc_items(batch, 0, 10); | |
| 218 | 238 | |
| 219 | − *cs++ = STATE_BASE_ADDRESS | (12 - 2); | |
| 239 | + *cs++ = STATE_BASE_ADDRESS | (10 - 2); | |
| 220 | 240 | /* general */ |
| 221 | 241 | *cs++ = batch_addr(batch) | BASE_ADDRESS_MODIFY; |
| 222 | 242 | /* surface */ |
| @@ -233,8 +253,6 @@ gen7_emit_state_base_address(struct batch_chunk *batch, · 10 unmodified lines | ||
| 233 | 253 | *cs++ = BASE_ADDRESS_MODIFY; |
| 234 | 254 | *cs++ = 0; |
| 235 | 255 | *cs++ = BASE_ADDRESS_MODIFY; |
| 236 | − *cs++ = 0; | |
| 237 | − *cs++ = 0; | |
| 238 | 256 | batch_advance(batch, cs); |
| 239 | 257 | } |
| 240 | 258 | |
| @@ -244,8 +262,7 @@ gen7_emit_vfe_state(struct batch_chunk *batch, · 3 unmodified lines | ||
| 244 | 262 | u32 urb_size, u32 curbe_size, |
| 245 | 263 | u32 mode) |
| 246 | 264 | { |
| 247 | − u32 urb_entries = bv->max_urb_entries; | |
| 248 | − u32 threads = bv->max_primitives - 1; | |
| 265 | + u32 threads = bv->max_threads - 1; | |
| 249 | 266 | u32 *cs = batch_alloc_items(batch, 32, 8); |
| 250 | 267 | |
| 251 | 268 | *cs++ = MEDIA_VFE_STATE | (8 - 2); |
| @@ -254,7 +271,7 @@ gen7_emit_vfe_state(struct batch_chunk *batch, · 2 unmodified lines | ||
| 254 | 271 | *cs++ = 0; |
| 255 | 272 | |
| 256 | 273 | /* number of threads & urb entries for GPGPU vs Media Mode */ |
| 257 | − *cs++ = threads << 16 | urb_entries << 8 | mode << 2; | |
| 274 | + *cs++ = threads << 16 | 1 << 8 | mode << 2; | |
| 258 | 275 | |
| 259 | 276 | *cs++ = 0; |
| 260 | 277 | |
| @@ -293,17 +310,12 @@ gen7_emit_media_object(struct batch_chunk *batch, · 32 unmodified lines | ||
| 293 | 310 | { |
| 294 | 311 | unsigned int x_offset = (media_object_index % 16) * 64; |
| 295 | 312 | unsigned int y_offset = (media_object_index / 16) * 16; |
| 296 | − unsigned int inline_data_size; | |
| 297 | − unsigned int media_batch_size; | |
| 298 | − unsigned int i; | |
| 313 | + unsigned int pkt = 6 + 3; | |
| 299 | 314 | u32 *cs; |
| 300 | 315 | |
| 301 | − inline_data_size = 112 * 8; | |
| 302 | − media_batch_size = inline_data_size + 6; | |
| 303 | − | |
| 304 | − cs = batch_alloc_items(batch, 8, media_batch_size); | |
| 316 | + cs = batch_alloc_items(batch, 8, pkt); | |
| 305 | 317 | |
| 306 | − *cs++ = MEDIA_OBJECT | (media_batch_size - 2); | |
| 318 | + *cs++ = MEDIA_OBJECT | (pkt - 2); | |
| 307 | 319 | |
| 308 | 320 | /* interface descriptor offset */ |
| 309 | 321 | *cs++ = 0; |
| @@ -317,25 +329,44 @@ gen7_emit_media_object(struct batch_chunk *batch, · 7 unmodified lines | ||
| 317 | 329 | *cs++ = 0; |
| 318 | 330 | |
| 319 | 331 | /* inline */ |
| 320 | − *cs++ = (y_offset << 16) | (x_offset); | |
| 332 | + *cs++ = y_offset << 16 | x_offset; | |
| 321 | 333 | *cs++ = 0; |
| 322 | 334 | *cs++ = GT3_INLINE_DATA_DELAYS; |
| 323 | − for (i = 3; i < inline_data_size; i++) | |
| 324 | − *cs++ = 0; | |
| 325 | 335 | |
| 326 | 336 | batch_advance(batch, cs); |
| 327 | 337 | } |
| 328 | 338 | |
| 329 | 339 | static void gen7_emit_pipeline_flush(struct batch_chunk *batch) |
| 330 | 340 | { |
| 331 | − u32 *cs = batch_alloc_items(batch, 0, 5); | |
| 341 | + u32 *cs = batch_alloc_items(batch, 0, 4); | |
| 332 | 342 | |
| 333 | − *cs++ = GFX_OP_PIPE_CONTROL(5); | |
| 334 | − *cs++ = PIPE_CONTROL_STATE_CACHE_INVALIDATE | | |
| 335 | − PIPE_CONTROL_GLOBAL_GTT_IVB; | |
| 343 | + *cs++ = GFX_OP_PIPE_CONTROL(4); | |
| 344 | + *cs++ = PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH | | |
| 345 | + PIPE_CONTROL_DEPTH_CACHE_FLUSH | | |
| 346 | + PIPE_CONTROL_DC_FLUSH_ENABLE | | |
| 347 | + PIPE_CONTROL_CS_STALL; | |
| 336 | 348 | *cs++ = 0; |
| 337 | 349 | *cs++ = 0; |
| 350 | + | |
| 351 | + batch_advance(batch, cs); | |
| 352 | +} | |
| 353 | + | |
| 354 | +static void gen7_emit_pipeline_invalidate(struct batch_chunk *batch) | |
| 355 | +{ | |
| 356 | + u32 *cs = batch_alloc_items(batch, 0, 8); | |
| 357 | + | |
| 358 | + /* ivb: Stall before STATE_CACHE_INVALIDATE */ | |
| 359 | + *cs++ = GFX_OP_PIPE_CONTROL(4); | |
| 360 | + *cs++ = PIPE_CONTROL_STALL_AT_SCOREBOARD | | |
| 361 | + PIPE_CONTROL_CS_STALL; | |
| 362 | + *cs++ = 0; | |
| 363 | + *cs++ = 0; | |
| 364 | + | |
| 365 | + *cs++ = GFX_OP_PIPE_CONTROL(4); | |
| 366 | + *cs++ = PIPE_CONTROL_STATE_CACHE_INVALIDATE; | |
| 338 | 367 | *cs++ = 0; |
| 368 | + *cs++ = 0; | |
| 369 | + | |
| 339 | 370 | batch_advance(batch, cs); |
| 340 | 371 | } |
| 341 | 372 | |
| @@ -344,34 +375,34 @@ static void emit_batch(struct i915_vma * const vma, · 2 unmodified lines | ||
| 344 | 375 | const struct batch_vals *bv) |
| 345 | 376 | { |
| 346 | 377 | struct drm_i915_private *i915 = vma->vm->i915; |
| 347 | − unsigned int desc_count = 64; | |
| 348 | − const u32 urb_size = 112; | |
| 378 | + const unsigned int desc_count = 1; | |
| 379 | + const unsigned int urb_size = 1; | |
| 349 | 380 | struct batch_chunk cmds, state; |
| 350 | − u32 interface_descriptor; | |
| 381 | + u32 descriptors; | |
| 351 | 382 | unsigned int i; |
| 352 | 383 | |
| 353 | − batch_init(&cmds, vma, start, 0, bv->cmd_size); | |
| 354 | − batch_init(&state, vma, start, bv->state_start, bv->state_size); | |
| 384 | + batch_init(&cmds, vma, start, 0, bv->state_start); | |
| 385 | + batch_init(&state, vma, start, bv->state_start, SZ_4K); | |
| 355 | 386 | |
| 356 | − interface_descriptor = | |
| 357 | − gen7_fill_interface_descriptor(&state, bv, | |
| 358 | − IS_HASWELL(i915) ? | |
| 359 | − &cb_kernel_hsw : | |
| 360 | − &cb_kernel_ivb, | |
| 361 | − desc_count); | |
| 362 | − gen7_emit_pipeline_flush(&cmds); | |
| 387 | + descriptors = gen7_fill_interface_descriptor(&state, bv, | |
| 388 | + IS_HASWELL(i915) ? | |
| 389 | + &cb_kernel_hsw : | |
| 390 | + &cb_kernel_ivb, | |
| 391 | + desc_count); | |
| 392 | + | |
| 393 | + gen7_emit_pipeline_invalidate(&cmds); | |
| 363 | 394 | batch_add(&cmds, PIPELINE_SELECT | PIPELINE_SELECT_MEDIA); |
| 364 | 395 | batch_add(&cmds, MI_NOOP); |
| 365 | − gen7_emit_state_base_address(&cmds, interface_descriptor); | |
| 396 | + gen7_emit_pipeline_invalidate(&cmds); | |
| 397 | + | |
| 366 | 398 | gen7_emit_pipeline_flush(&cmds); |
| 399 | + gen7_emit_state_base_address(&cmds, descriptors); | |
| 400 | + gen7_emit_pipeline_invalidate(&cmds); | |
| 367 | 401 | |
| 368 | 402 | gen7_emit_vfe_state(&cmds, bv, urb_size - 1, 0, 0); |
| 403 | + gen7_emit_interface_descriptor_load(&cmds, descriptors, desc_count); | |
| 369 | 404 | |
| 370 | − gen7_emit_interface_descriptor_load(&cmds, | |
| 371 | − interface_descriptor, | |
| 372 | − desc_count); | |
| 373 | − | |
| 374 | − for (i = 0; i < bv->max_primitives; i++) | |
| 405 | + for (i = 0; i < num_primitives(bv); i++) | |
| 375 | 406 | gen7_emit_media_object(&cmds, i); |
| 376 | 407 | |
| 377 | 408 | batch_add(&cmds, MI_BATCH_BUFFER_END); |
| @@ -385,15 +416,15 @@ int gen7_setup_clear_gpr_bb(struct intel_engine_cs * const engine, · 7 unmodified lines | ||
| 385 | 416 | |
| 386 | 417 | batch_get_defaults(engine->i915, &bv); |
| 387 | 418 | if (!vma) |
| 388 | − return bv.max_size; | |
| 419 | + return bv.size; | |
| 389 | 420 | |
| 390 | − GEM_BUG_ON(vma->obj->base.size < bv.max_size); | |
| 421 | + GEM_BUG_ON(vma->obj->base.size < bv.size); | |
| 391 | 422 | |
| 392 | 423 | batch = i915_gem_object_pin_map(vma->obj, I915_MAP_WC); |
| 393 | 424 | if (IS_ERR(batch)) |
| 394 | 425 | return PTR_ERR(batch); |
| 395 | 426 | |
| 396 | − emit_batch(vma, memset(batch, 0, bv.max_size), &bv); | |
| 427 | + emit_batch(vma, memset(batch, 0, bv.size), &bv); | |
| 397 | 428 | |
| 398 | 429 | i915_gem_object_flush_map(vma->obj); |
| 399 | 430 | __i915_gem_object_release_map(vma->obj); |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | #include "gen6_ppgtt.h" |
| 33 | 33 | #include "gen7_renderclear.h" |
| 34 | 34 | #include "i915_drv.h" |
| 35 | +#include "i915_mitigations.h" | |
| 35 | 36 | #include "intel_breadcrumbs.h" |
| 36 | 37 | #include "intel_context.h" |
| 37 | 38 | #include "intel_gt.h" |
| @@ -886,7 +887,8 @@ static int switch_context(struct i915_request *rq) · 848 unmodified lines | ||
| 886 | 887 | GEM_BUG_ON(HAS_EXECLISTS(engine->i915)); |
| 887 | 888 | |
| 888 | 889 | if (engine->wa_ctx.vma && ce != engine->kernel_context) { |
| 889 | − if (engine->wa_ctx.vma->private != ce) { | |
| 890 | + if (engine->wa_ctx.vma->private != ce && | |
| 891 | + i915_mitigate_clear_residuals()) { | |
| 890 | 892 | ret = clear_residuals(rq); |
| 891 | 893 | if (ret) |
| 892 | 894 | return ret; |
| @@ -1290,7 +1292,7 @@ int intel_ring_submission_setup(struct intel_engine_cs *engine) · 397 unmodified lines | ||
| 1290 | 1292 | |
| 1291 | 1293 | GEM_BUG_ON(timeline->hwsp_ggtt != engine->status_page.vma); |
| 1292 | 1294 | |
| 1293 | − if (IS_HASWELL(engine->i915) && engine->class == RENDER_CLASS) { | |
| 1295 | + if (IS_GEN(engine->i915, 7) && engine->class == RENDER_CLASS) { | |
| 1294 | 1296 | err = gen7_ctx_switch_bb_init(engine); |
| 1295 | 1297 | if (err) |
| 1296 | 1298 | goto err_ring_unpin; |
| @@ -53,6 +53,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw, · 52 unmodified lines | ||
| 53 | 53 | fw_def(ELKHARTLAKE, 0, guc_def(ehl, 49, 0, 1), huc_def(ehl, 9, 0, 0)) \ |
| 54 | 54 | fw_def(ICELAKE, 0, guc_def(icl, 49, 0, 1), huc_def(icl, 9, 0, 0)) \ |
| 55 | 55 | fw_def(COMETLAKE, 5, guc_def(cml, 49, 0, 1), huc_def(cml, 4, 0, 0)) \ |
| 56 | + fw_def(COMETLAKE, 0, guc_def(kbl, 49, 0, 1), huc_def(kbl, 4, 0, 0)) \ | |
| 56 | 57 | fw_def(COFFEELAKE, 0, guc_def(kbl, 49, 0, 1), huc_def(kbl, 4, 0, 0)) \ |
| 57 | 58 | fw_def(GEMINILAKE, 0, guc_def(glk, 49, 0, 1), huc_def(glk, 4, 0, 0)) \ |
| 58 | 59 | fw_def(KABYLAKE, 0, guc_def(kbl, 49, 0, 1), huc_def(kbl, 4, 0, 0)) \ |
| @@ -217,6 +217,15 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) · 216 unmodified lines | ||
| 217 | 217 | DDI_BUF_CTL_ENABLE); |
| 218 | 218 | vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) |= DDI_BUF_IS_IDLE; |
| 219 | 219 | } |
| 220 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= | |
| 221 | + ~(PORTA_HOTPLUG_ENABLE | PORTA_HOTPLUG_STATUS_MASK); | |
| 222 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= | |
| 223 | + ~(PORTB_HOTPLUG_ENABLE | PORTB_HOTPLUG_STATUS_MASK); | |
| 224 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= | |
| 225 | + ~(PORTC_HOTPLUG_ENABLE | PORTC_HOTPLUG_STATUS_MASK); | |
| 226 | + /* No hpd_invert set in vgpu vbt, need to clear invert mask */ | |
| 227 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= ~BXT_DDI_HPD_INVERT_MASK; | |
| 228 | + vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~BXT_DE_PORT_HOTPLUG_MASK; | |
| 220 | 229 | |
| 221 | 230 | vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) &= ~(BIT(0) | BIT(1)); |
| 222 | 231 | vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) &= |
| @@ -273,6 +282,8 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) · 50 unmodified lines | ||
| 273 | 282 | vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)) |= |
| 274 | 283 | (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST | |
| 275 | 284 | TRANS_DDI_FUNC_ENABLE); |
| 285 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | |
| 286 | + PORTA_HOTPLUG_ENABLE; | |
| 276 | 287 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= |
| 277 | 288 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_A); |
| 278 | 289 | } |
| @@ -301,6 +312,8 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) · 22 unmodified lines | ||
| 301 | 312 | (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST | |
| 302 | 313 | (PORT_B << TRANS_DDI_PORT_SHIFT) | |
| 303 | 314 | TRANS_DDI_FUNC_ENABLE); |
| 315 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | |
| 316 | + PORTB_HOTPLUG_ENABLE; | |
| 304 | 317 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= |
| 305 | 318 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_B); |
| 306 | 319 | } |
| @@ -329,6 +342,8 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) · 22 unmodified lines | ||
| 329 | 342 | (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST | |
| 330 | 343 | (PORT_B << TRANS_DDI_PORT_SHIFT) | |
| 331 | 344 | TRANS_DDI_FUNC_ENABLE); |
| 345 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | |
| 346 | + PORTC_HOTPLUG_ENABLE; | |
| 332 | 347 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= |
| 333 | 348 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_C); |
| 334 | 349 | } |
| @@ -661,44 +676,62 @@ void intel_vgpu_emulate_hotplug(struct intel_vgpu *vgpu, bool connected) · 326 unmodified lines | ||
| 661 | 676 | PORTD_HOTPLUG_STATUS_MASK; |
| 662 | 677 | intel_vgpu_trigger_virtual_event(vgpu, DP_D_HOTPLUG); |
| 663 | 678 | } else if (IS_BROXTON(i915)) { |
| 664 | − if (connected) { | |
| 665 | − if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) { | |
| 679 | + if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) { | |
| 680 | + if (connected) { | |
| 666 | 681 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= |
| 667 | 682 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_A); |
| 683 | + } else { | |
| 684 | + vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= | |
| 685 | + ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_A); | |
| 668 | 686 | } |
| 669 | − if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) { | |
| 670 | − vgpu_vreg_t(vgpu, SFUSE_STRAP) |= | |
| 671 | − SFUSE_STRAP_DDIB_DETECTED; | |
| 687 | + vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |= | |
| 688 | + GEN8_DE_PORT_HOTPLUG(HPD_PORT_A); | |
| 689 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= | |
| 690 | + ~PORTA_HOTPLUG_STATUS_MASK; | |
| 691 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | |
| 692 | + PORTA_HOTPLUG_LONG_DETECT; | |
| 693 | + intel_vgpu_trigger_virtual_event(vgpu, DP_A_HOTPLUG); | |
| 694 | + } | |
| 695 | + if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) { | |
| 696 | + if (connected) { | |
| 672 | 697 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= |
| 673 | 698 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_B); |
| 674 | − } | |
| 675 | − if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) { | |
| 676 | 699 | vgpu_vreg_t(vgpu, SFUSE_STRAP) |= |
| 677 | − SFUSE_STRAP_DDIC_DETECTED; | |
| 678 | − vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= | |
| 679 | − GEN8_DE_PORT_HOTPLUG(HPD_PORT_C); | |
| 680 | − } | |
| 681 | − } else { | |
| 682 | − if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) { | |
| 700 | + SFUSE_STRAP_DDIB_DETECTED; | |
| 701 | + } else { | |
| 683 | 702 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= |
| 684 | − ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_A); | |
| 685 | − } | |
| 686 | − if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) { | |
| 703 | + ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_B); | |
| 687 | 704 | vgpu_vreg_t(vgpu, SFUSE_STRAP) &= |
| 688 | 705 | ~SFUSE_STRAP_DDIB_DETECTED; |
| 689 | − vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= | |
| 690 | − ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_B); | |
| 691 | 706 | } |
| 692 | − if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) { | |
| 693 | − vgpu_vreg_t(vgpu, SFUSE_STRAP) &= | |
| 694 | − ~SFUSE_STRAP_DDIC_DETECTED; | |
| 707 | + vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |= | |
| 708 | + GEN8_DE_PORT_HOTPLUG(HPD_PORT_B); | |
| 709 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= | |
| 710 | + ~PORTB_HOTPLUG_STATUS_MASK; | |
| 711 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | |
| 712 | + PORTB_HOTPLUG_LONG_DETECT; | |
| 713 | + intel_vgpu_trigger_virtual_event(vgpu, DP_B_HOTPLUG); | |
| 714 | + } | |
| 715 | + if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) { | |
| 716 | + if (connected) { | |
| 717 | + vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= | |
| 718 | + GEN8_DE_PORT_HOTPLUG(HPD_PORT_C); | |
| 719 | + vgpu_vreg_t(vgpu, SFUSE_STRAP) |= | |
| 720 | + SFUSE_STRAP_DDIC_DETECTED; | |
| 721 | + } else { | |
| 695 | 722 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= |
| 696 | 723 | ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_C); |
| 724 | + vgpu_vreg_t(vgpu, SFUSE_STRAP) &= | |
| 725 | + ~SFUSE_STRAP_DDIC_DETECTED; | |
| 697 | 726 | } |
| 727 | + vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |= | |
| 728 | + GEN8_DE_PORT_HOTPLUG(HPD_PORT_C); | |
| 729 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= | |
| 730 | + ~PORTC_HOTPLUG_STATUS_MASK; | |
| 731 | + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | |
| 732 | + PORTC_HOTPLUG_LONG_DETECT; | |
| 733 | + intel_vgpu_trigger_virtual_event(vgpu, DP_C_HOTPLUG); | |
| 698 | 734 | } |
| 699 | − vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | |
| 700 | − PORTB_HOTPLUG_STATUS_MASK; | |
| 701 | − intel_vgpu_trigger_virtual_event(vgpu, DP_B_HOTPLUG); | |
| 702 | 735 | } |
| 703 | 736 | } |
| 704 | 737 | |
| @@ -437,10 +437,9 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt, · 436 unmodified lines | ||
| 437 | 437 | if (ret) |
| 438 | 438 | goto out_clean_sched_policy; |
| 439 | 439 | |
| 440 | − if (IS_BROADWELL(dev_priv)) | |
| 440 | + if (IS_BROADWELL(dev_priv) || IS_BROXTON(dev_priv)) | |
| 441 | 441 | ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_B); |
| 442 | − /* FixMe: Re-enable APL/BXT once vfio_edid enabled */ | |
| 443 | − else if (!IS_BROXTON(dev_priv)) | |
| 442 | + else | |
| 444 | 443 | ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_D); |
| 445 | 444 | if (ret) |
| 446 | 445 | goto out_clean_sched_policy; |
| @@ -1166,7 +1166,7 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, · 1165 unmodified lines | ||
| 1166 | 1166 | } |
| 1167 | 1167 | } |
| 1168 | 1168 | if (IS_ERR(src)) { |
| 1169 | − unsigned long x, n; | |
| 1169 | + unsigned long x, n, remain; | |
| 1170 | 1170 | void *ptr; |
| 1171 | 1171 | |
| 1172 | 1172 | /* |
| @@ -1177,14 +1177,15 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, · 4 unmodified lines | ||
| 1177 | 1177 | * We don't care about copying too much here as we only |
| 1178 | 1178 | * validate up to the end of the batch. |
| 1179 | 1179 | */ |
| 1180 | + remain = length; | |
| 1180 | 1181 | if (!(dst_obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)) |
| 1181 | − length = round_up(length, | |
| 1182 | + remain = round_up(remain, | |
| 1182 | 1183 | boot_cpu_data.x86_clflush_size); |
| 1183 | 1184 | |
| 1184 | 1185 | ptr = dst; |
| 1185 | 1186 | x = offset_in_page(offset); |
| 1186 | − for (n = offset >> PAGE_SHIFT; length; n++) { | |
| 1187 | − int len = min(length, PAGE_SIZE - x); | |
| 1187 | + for (n = offset >> PAGE_SHIFT; remain; n++) { | |
| 1188 | + int len = min(remain, PAGE_SIZE - x); | |
| 1188 | 1189 | |
| 1189 | 1190 | src = kmap_atomic(i915_gem_object_get_page(src_obj, n)); |
| 1190 | 1191 | if (needs_clflush) |
| @@ -1193,13 +1194,15 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, · 2 unmodified lines | ||
| 1193 | 1194 | kunmap_atomic(src); |
| 1194 | 1195 | |
| 1195 | 1196 | ptr += len; |
| 1196 | − length -= len; | |
| 1197 | + remain -= len; | |
| 1197 | 1198 | x = 0; |
| 1198 | 1199 | } |
| 1199 | 1200 | } |
| 1200 | 1201 | |
| 1201 | 1202 | i915_gem_object_unpin_pages(src_obj); |
| 1202 | 1203 | |
| 1204 | + memset32(dst + length, 0, (dst_obj->base.size - length) / sizeof(u32)); | |
| 1205 | + | |
| 1203 | 1206 | /* dst_obj is returned with vmap pinned */ |
| 1204 | 1207 | return dst; |
| 1205 | 1208 | } |
| @@ -1392,11 +1395,6 @@ static unsigned long *alloc_whitelist(u32 batch_length) · 186 unmodified lines | ||
| 1392 | 1395 | |
| 1393 | 1396 | #define LENGTH_BIAS 2 |
| 1394 | 1397 | |
| 1395 | −static bool shadow_needs_clflush(struct drm_i915_gem_object *obj) | |
| 1396 | −{ | |
| 1397 | − return !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE); | |
| 1398 | −} | |
| 1399 | − | |
| 1400 | 1398 | /** |
| 1401 | 1399 | * intel_engine_cmd_parser() - parse a batch buffer for privilege violations |
| 1402 | 1400 | * @engine: the engine on which the batch is to execute |
| @@ -1538,16 +1536,9 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine, · 135 unmodified lines | ||
| 1538 | 1536 | ret = 0; /* allow execution */ |
| 1539 | 1537 | } |
| 1540 | 1538 | } |
| 1541 | − | |
| 1542 | − if (shadow_needs_clflush(shadow->obj)) | |
| 1543 | − drm_clflush_virt_range(batch_end, 8); | |
| 1544 | 1539 | } |
| 1545 | 1540 | |
| 1546 | − if (shadow_needs_clflush(shadow->obj)) { | |
| 1547 | − void *ptr = page_mask_bits(shadow->obj->mm.mapping); | |
| 1548 | − | |
| 1549 | − drm_clflush_virt_range(ptr, (void *)(cmd + 1) - ptr); | |
| 1550 | − } | |
| 1541 | + i915_gem_object_flush_map(shadow->obj); | |
| 1551 | 1542 | |
| 1552 | 1543 | if (!IS_ERR_OR_NULL(jump_whitelist)) |
| 1553 | 1544 | kfree(jump_whitelist); |
| @@ -578,8 +578,6 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv) · 577 unmodified lines | ||
| 578 | 578 | |
| 579 | 579 | pci_set_master(pdev); |
| 580 | 580 | |
| 581 | − cpu_latency_qos_add_request(&dev_priv->pm_qos, PM_QOS_DEFAULT_VALUE); | |
| 582 | − | |
| 583 | 581 | intel_gt_init_workarounds(dev_priv); |
| 584 | 582 | |
| 585 | 583 | /* On the 945G/GM, the chipset reports the MSI capability on the |
| @@ -626,7 +624,6 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv) · 40 unmodified lines | ||
| 626 | 624 | err_msi: |
| 627 | 625 | if (pdev->msi_enabled) |
| 628 | 626 | pci_disable_msi(pdev); |
| 629 | − cpu_latency_qos_remove_request(&dev_priv->pm_qos); | |
| 630 | 627 | err_mem_regions: |
| 631 | 628 | intel_memory_regions_driver_release(dev_priv); |
| 632 | 629 | err_ggtt: |
| @@ -648,8 +645,6 @@ static void i915_driver_hw_remove(struct drm_i915_private *dev_priv) · 15 unmodified lines | ||
| 648 | 645 | |
| 649 | 646 | if (pdev->msi_enabled) |
| 650 | 647 | pci_disable_msi(pdev); |
| 651 | − | |
| 652 | − cpu_latency_qos_remove_request(&dev_priv->pm_qos); | |
| 653 | 648 | } |
| 654 | 649 | |
| 655 | 650 | /** |
| @@ -1052,6 +1047,8 @@ static void intel_shutdown_encoders(struct drm_i915_private *dev_priv) · 396 unmodified lines | ||
| 1052 | 1047 | |
| 1053 | 1048 | void i915_driver_shutdown(struct drm_i915_private *i915) |
| 1054 | 1049 | { |
| 1050 | + disable_rpm_wakeref_asserts(&i915->runtime_pm); | |
| 1051 | + | |
| 1055 | 1052 | i915_gem_suspend(i915); |
| 1056 | 1053 | |
| 1057 | 1054 | drm_kms_helper_poll_disable(&i915->drm); |
| @@ -1065,6 +1062,8 @@ void i915_driver_shutdown(struct drm_i915_private *i915) · 7 unmodified lines | ||
| 1065 | 1062 | |
| 1066 | 1063 | intel_suspend_encoders(i915); |
| 1067 | 1064 | intel_shutdown_encoders(i915); |
| 1065 | + | |
| 1066 | + enable_rpm_wakeref_asserts(&i915->runtime_pm); | |
| 1068 | 1067 | } |
| 1069 | 1068 | |
| 1070 | 1069 | static bool suspend_to_idle(struct drm_i915_private *dev_priv) |
| @@ -891,9 +891,6 @@ struct drm_i915_private { · 890 unmodified lines | ||
| 891 | 891 | |
| 892 | 892 | bool display_irqs_enabled; |
| 893 | 893 | |
| 894 | − /* To control wakeup latency, e.g. for irq-driven dp aux transfers. */ | |
| 895 | − struct pm_qos_request pm_qos; | |
| 896 | − | |
| 897 | 894 | /* Sideband mailbox protection */ |
| 898 | 895 | struct mutex sb_lock; |
| 899 | 896 | struct pm_qos_request sb_qos; |
| @@ -0,0 +1,146 @@ | ||
| 1 | +// SPDX-License-Identifier: MIT | |
| 2 | +/* | |
| 3 | + * Copyright © 2021 Intel Corporation | |
| 4 | + */ | |
| 5 | + | |
| 6 | +#include <linux/kernel.h> | |
| 7 | +#include <linux/moduleparam.h> | |
| 8 | +#include <linux/slab.h> | |
| 9 | +#include <linux/string.h> | |
| 10 | + | |
| 11 | +#include "i915_drv.h" | |
| 12 | +#include "i915_mitigations.h" | |
| 13 | + | |
| 14 | +static unsigned long mitigations __read_mostly = ~0UL; | |
| 15 | + | |
| 16 | +enum { | |
| 17 | + CLEAR_RESIDUALS = 0, | |
| 18 | +}; | |
| 19 | + | |
| 20 | +static const char * const names[] = { | |
| 21 | + [CLEAR_RESIDUALS] = "residuals", | |
| 22 | +}; | |
| 23 | + | |
| 24 | +bool i915_mitigate_clear_residuals(void) | |
| 25 | +{ | |
| 26 | + return READ_ONCE(mitigations) & BIT(CLEAR_RESIDUALS); | |
| 27 | +} | |
| 28 | + | |
| 29 | +static int mitigations_set(const char *val, const struct kernel_param *kp) | |
| 30 | +{ | |
| 31 | + unsigned long new = ~0UL; | |
| 32 | + char *str, *sep, *tok; | |
| 33 | + bool first = true; | |
| 34 | + int err = 0; | |
| 35 | + | |
| 36 | + BUILD_BUG_ON(ARRAY_SIZE(names) >= BITS_PER_TYPE(mitigations)); | |
| 37 | + | |
| 38 | + str = kstrdup(val, GFP_KERNEL); | |
| 39 | + if (!str) | |
| 40 | + return -ENOMEM; | |
| 41 | + | |
| 42 | + for (sep = str; (tok = strsep(&sep, ","));) { | |
| 43 | + bool enable = true; | |
| 44 | + int i; | |
| 45 | + | |
| 46 | + /* Be tolerant of leading/trailing whitespace */ | |
| 47 | + tok = strim(tok); | |
| 48 | + | |
| 49 | + if (first) { | |
| 50 | + first = false; | |
| 51 | + | |
| 52 | + if (!strcmp(tok, "auto")) | |
| 53 | + continue; | |
| 54 | + | |
| 55 | + new = 0; | |
| 56 | + if (!strcmp(tok, "off")) | |
| 57 | + continue; | |
| 58 | + } | |
| 59 | + | |
| 60 | + if (*tok == '!') { | |
| 61 | + enable = !enable; | |
| 62 | + tok++; | |
| 63 | + } | |
| 64 | + | |
| 65 | + if (!strncmp(tok, "no", 2)) { | |
| 66 | + enable = !enable; | |
| 67 | + tok += 2; | |
| 68 | + } | |
| 69 | + | |
| 70 | + if (*tok == '\0') | |
| 71 | + continue; | |
| 72 | + | |
| 73 | + for (i = 0; i < ARRAY_SIZE(names); i++) { | |
| 74 | + if (!strcmp(tok, names[i])) { | |
| 75 | + if (enable) | |
| 76 | + new |= BIT(i); | |
| 77 | + else | |
| 78 | + new &= ~BIT(i); | |
| 79 | + break; | |
| 80 | + } | |
| 81 | + } | |
| 82 | + if (i == ARRAY_SIZE(names)) { | |
| 83 | + pr_err("Bad \"%s.mitigations=%s\", '%s' is unknown\n", | |
| 84 | + DRIVER_NAME, val, tok); | |
| 85 | + err = -EINVAL; | |
| 86 | + break; | |
| 87 | + } | |
| 88 | + } | |
| 89 | + kfree(str); | |
| 90 | + if (err) | |
| 91 | + return err; | |
| 92 | + | |
| 93 | + WRITE_ONCE(mitigations, new); | |
| 94 | + return 0; | |
| 95 | +} | |
| 96 | + | |
| 97 | +static int mitigations_get(char *buffer, const struct kernel_param *kp) | |
| 98 | +{ | |
| 99 | + unsigned long local = READ_ONCE(mitigations); | |
| 100 | + int count, i; | |
| 101 | + bool enable; | |
| 102 | + | |
| 103 | + if (!local) | |
| 104 | + return scnprintf(buffer, PAGE_SIZE, "%s\n", "off"); | |
| 105 | + | |
| 106 | + if (local & BIT(BITS_PER_LONG - 1)) { | |
| 107 | + count = scnprintf(buffer, PAGE_SIZE, "%s,", "auto"); | |
| 108 | + enable = false; | |
| 109 | + } else { | |
| 110 | + enable = true; | |
| 111 | + count = 0; | |
| 112 | + } | |
| 113 | + | |
| 114 | + for (i = 0; i < ARRAY_SIZE(names); i++) { | |
| 115 | + if ((local & BIT(i)) != enable) | |
| 116 | + continue; | |
| 117 | + | |
| 118 | + count += scnprintf(buffer + count, PAGE_SIZE - count, | |
| 119 | + "%s%s,", enable ? "" : "!", names[i]); | |
| 120 | + } | |
| 121 | + | |
| 122 | + buffer[count - 1] = '\n'; | |
| 123 | + return count; | |
| 124 | +} | |
| 125 | + | |
| 126 | +static const struct kernel_param_ops ops = { | |
| 127 | + .set = mitigations_set, | |
| 128 | + .get = mitigations_get, | |
| 129 | +}; | |
| 130 | + | |
| 131 | +module_param_cb_unsafe(mitigations, &ops, NULL, 0600); | |
| 132 | +MODULE_PARM_DESC(mitigations, | |
| 133 | +"Selectively enable security mitigations for all Intel® GPUs in the system.\n" | |
| 134 | +"\n" | |
| 135 | +" auto -- enables all mitigations required for the platform [default]\n" | |
| 136 | +" off -- disables all mitigations\n" | |
| 137 | +"\n" | |
| 138 | +"Individual mitigations can be enabled by passing a comma-separated string,\n" | |
| 139 | +"e.g. mitigations=residuals to enable only clearing residuals or\n" | |
| 140 | +"mitigations=auto,noresiduals to disable only the clear residual mitigation.\n" | |
| 141 | +"Either '!' or 'no' may be used to switch from enabling the mitigation to\n" | |
| 142 | +"disabling it.\n" | |
| 143 | +"\n" | |
| 144 | +"Active mitigations for Ivybridge, Baytrail, Haswell:\n" | |
| 145 | +" residuals -- clear all thread-local registers between contexts" | |
| 146 | +); | |
| @@ -0,0 +1,13 @@ | ||
| 1 | +/* SPDX-License-Identifier: MIT */ | |
| 2 | +/* | |
| 3 | + * Copyright © 2021 Intel Corporation | |
| 4 | + */ | |
| 5 | + | |
| 6 | +#ifndef __I915_MITIGATIONS_H__ | |
| 7 | +#define __I915_MITIGATIONS_H__ | |
| 8 | + | |
| 9 | +#include <linux/types.h> | |
| 10 | + | |
| 11 | +bool i915_mitigate_clear_residuals(void); | |
| 12 | + | |
| 13 | +#endif /* __I915_MITIGATIONS_H__ */ | |
| @@ -534,8 +534,10 @@ struct msm_gpu *a2xx_gpu_init(struct drm_device *dev) · 533 unmodified lines | ||
| 534 | 534 | |
| 535 | 535 | if (!gpu->aspace) { |
| 536 | 536 | dev_err(dev->dev, "No memory protection without MMU\n"); |
| 537 | − ret = -ENXIO; | |
| 538 | − goto fail; | |
| 537 | + if (!allow_vram_carveout) { | |
| 538 | + ret = -ENXIO; | |
| 539 | + goto fail; | |
| 540 | + } | |
| 539 | 541 | } |
| 540 | 542 | |
| 541 | 543 | return gpu; |
| @@ -564,8 +564,10 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) · 563 unmodified lines | ||
| 564 | 564 | * implement a cmdstream validator. |
| 565 | 565 | */ |
| 566 | 566 | DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n"); |
| 567 | − ret = -ENXIO; | |
| 568 | − goto fail; | |
| 567 | + if (!allow_vram_carveout) { | |
| 568 | + ret = -ENXIO; | |
| 569 | + goto fail; | |
| 570 | + } | |
| 569 | 571 | } |
| 570 | 572 | |
| 571 | 573 | icc_path = devm_of_icc_get(&pdev->dev, "gfx-mem"); |
| @@ -692,8 +692,10 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) · 691 unmodified lines | ||
| 692 | 692 | * implement a cmdstream validator. |
| 693 | 693 | */ |
| 694 | 694 | DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n"); |
| 695 | − ret = -ENXIO; | |
| 696 | − goto fail; | |
| 695 | + if (!allow_vram_carveout) { | |
| 696 | + ret = -ENXIO; | |
| 697 | + goto fail; | |
| 698 | + } | |
| 697 | 699 | } |
| 698 | 700 | |
| 699 | 701 | icc_path = devm_of_icc_get(&pdev->dev, "gfx-mem"); |
| @@ -18,6 +18,10 @@ bool snapshot_debugbus = false; · 17 unmodified lines | ||
| 18 | 18 | MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)"); |
| 19 | 19 | module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600); |
| 20 | 20 | |
| 21 | +bool allow_vram_carveout = false; | |
| 22 | +MODULE_PARM_DESC(allow_vram_carveout, "Allow using VRAM Carveout, in place of IOMMU"); | |
| 23 | +module_param_named(allow_vram_carveout, allow_vram_carveout, bool, 0600); | |
| 24 | + | |
| 21 | 25 | static const struct adreno_info gpulist[] = { |
| 22 | 26 | { |
| 23 | 27 | .rev = ADRENO_REV(2, 0, 0, 0), |
| @@ -191,8 +191,6 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu, · 190 unmodified lines | ||
| 191 | 191 | struct platform_device *pdev) |
| 192 | 192 | { |
| 193 | 193 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); |
| 194 | − struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); | |
| 195 | − struct io_pgtable_domain_attr pgtbl_cfg; | |
| 196 | 194 | struct iommu_domain *iommu; |
| 197 | 195 | struct msm_mmu *mmu; |
| 198 | 196 | struct msm_gem_address_space *aspace; |
| @@ -202,13 +200,18 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu, · 3 unmodified lines | ||
| 202 | 200 | if (!iommu) |
| 203 | 201 | return NULL; |
| 204 | 202 | |
| 205 | − /* | |
| 206 | − * This allows GPU to set the bus attributes required to use system | |
| 207 | − * cache on behalf of the iommu page table walker. | |
| 208 | − */ | |
| 209 | − if (!IS_ERR(a6xx_gpu->htw_llc_slice)) { | |
| 210 | − pgtbl_cfg.quirks = IO_PGTABLE_QUIRK_ARM_OUTER_WBWA; | |
| 211 | − iommu_domain_set_attr(iommu, DOMAIN_ATTR_IO_PGTABLE_CFG, &pgtbl_cfg); | |
| 203 | + | |
| 204 | + if (adreno_is_a6xx(adreno_gpu)) { | |
| 205 | + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); | |
| 206 | + struct io_pgtable_domain_attr pgtbl_cfg; | |
| 207 | + /* | |
| 208 | + * This allows GPU to set the bus attributes required to use system | |
| 209 | + * cache on behalf of the iommu page table walker. | |
| 210 | + */ | |
| 211 | + if (!IS_ERR(a6xx_gpu->htw_llc_slice)) { | |
| 212 | + pgtbl_cfg.quirks = IO_PGTABLE_QUIRK_ARM_OUTER_WBWA; | |
| 213 | + iommu_domain_set_attr(iommu, DOMAIN_ATTR_IO_PGTABLE_CFG, &pgtbl_cfg); | |
| 214 | + } | |
| 212 | 215 | } |
| 213 | 216 | |
| 214 | 217 | mmu = msm_iommu_new(&pdev->dev, iommu); |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include "adreno_pm4.xml.h" |
| 19 | 19 | |
| 20 | 20 | extern bool snapshot_debugbus; |
| 21 | +extern bool allow_vram_carveout; | |
| 21 | 22 | |
| 22 | 23 | enum { |
| 23 | 24 | ADRENO_FW_PM4 = 0, |
| @@ -211,6 +212,11 @@ static inline int adreno_is_a540(struct adreno_gpu *gpu) · 187 unmodified lines | ||
| 211 | 212 | return gpu->revn == 540; |
| 212 | 213 | } |
| 213 | 214 | |
| 215 | +static inline bool adreno_is_a6xx(struct adreno_gpu *gpu) | |
| 216 | +{ | |
| 217 | + return ((gpu->revn < 700 && gpu->revn > 599)); | |
| 218 | +} | |
| 219 | + | |
| 214 | 220 | static inline int adreno_is_a618(struct adreno_gpu *gpu) |
| 215 | 221 | { |
| 216 | 222 | return gpu->revn == 618; |
| @@ -693,6 +693,13 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data) · 692 unmodified lines | ||
| 693 | 693 | return 0; |
| 694 | 694 | } |
| 695 | 695 | |
| 696 | + if (state == ST_CONNECT_PENDING) { | |
| 697 | + /* wait until ST_CONNECTED */ | |
| 698 | + dp_add_event(dp, EV_IRQ_HPD_INT, 0, 1); /* delay = 1 */ | |
| 699 | + mutex_unlock(&dp->event_mutex); | |
| 700 | + return 0; | |
| 701 | + } | |
| 702 | + | |
| 696 | 703 | ret = dp_display_usbpd_attention_cb(&dp->pdev->dev); |
| 697 | 704 | if (ret == -ECONNRESET) { /* cable unplugged */ |
| 698 | 705 | dp->core_initialized = false; |
| @@ -167,12 +167,18 @@ int dp_panel_read_sink_caps(struct dp_panel *dp_panel, · 166 unmodified lines | ||
| 167 | 167 | panel = container_of(dp_panel, struct dp_panel_private, dp_panel); |
| 168 | 168 | |
| 169 | 169 | rc = dp_panel_read_dpcd(dp_panel); |
| 170 | + if (rc) { | |
| 171 | + DRM_ERROR("read dpcd failed %d\n", rc); | |
| 172 | + return rc; | |
| 173 | + } | |
| 174 | + | |
| 170 | 175 | bw_code = drm_dp_link_rate_to_bw_code(dp_panel->link_info.rate); |
| 171 | − if (rc || !is_link_rate_valid(bw_code) || | |
| 176 | + if (!is_link_rate_valid(bw_code) || | |
| 172 | 177 | !is_lane_count_valid(dp_panel->link_info.num_lanes) || |
| 173 | 178 | (bw_code > dp_panel->max_bw_code)) { |
| 174 | − DRM_ERROR("read dpcd failed %d\n", rc); | |
| 175 | − return rc; | |
| 179 | + DRM_ERROR("Illegal link rate=%d lane=%d\n", dp_panel->link_info.rate, | |
| 180 | + dp_panel->link_info.num_lanes); | |
| 181 | + return -EINVAL; | |
| 176 | 182 | } |
| 177 | 183 | |
| 178 | 184 | if (dp_panel->dfp_present) { |
| @@ -457,14 +457,14 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv) · 456 unmodified lines | ||
| 457 | 457 | |
| 458 | 458 | drm_mode_config_init(ddev); |
| 459 | 459 | |
| 460 | − /* Bind all our sub-components: */ | |
| 461 | − ret = component_bind_all(dev, ddev); | |
| 460 | + ret = msm_init_vram(ddev); | |
| 462 | 461 | if (ret) |
| 463 | 462 | goto err_destroy_mdss; |
| 464 | 463 | |
| 465 | − ret = msm_init_vram(ddev); | |
| 464 | + /* Bind all our sub-components: */ | |
| 465 | + ret = component_bind_all(dev, ddev); | |
| 466 | 466 | if (ret) |
| 467 | − goto err_msm_uninit; | |
| 467 | + goto err_destroy_mdss; | |
| 468 | 468 | |
| 469 | 469 | dma_set_max_seg_size(dev, UINT_MAX); |
| 470 | 470 | |
| @@ -96,6 +96,8 @@ static struct page **get_pages(struct drm_gem_object *obj) · 95 unmodified lines | ||
| 96 | 96 | { |
| 97 | 97 | struct msm_gem_object *msm_obj = to_msm_bo(obj); |
| 98 | 98 | |
| 99 | + WARN_ON(!msm_gem_is_locked(obj)); | |
| 100 | + | |
| 99 | 101 | if (!msm_obj->pages) { |
| 100 | 102 | struct drm_device *dev = obj->dev; |
| 101 | 103 | struct page **p; |
| @@ -988,6 +990,8 @@ void msm_gem_free_object(struct drm_gem_object *obj) · 886 unmodified lines | ||
| 988 | 990 | if (msm_obj->pages) |
| 989 | 991 | kvfree(msm_obj->pages); |
| 990 | 992 | |
| 993 | + put_iova_vmas(obj); | |
| 994 | + | |
| 991 | 995 | /* dma_buf_detach() grabs resv lock, so we need to unlock |
| 992 | 996 | * prior to drm_prime_gem_destroy |
| 993 | 997 | */ |
| @@ -997,11 +1001,10 @@ void msm_gem_free_object(struct drm_gem_object *obj) · 3 unmodified lines | ||
| 997 | 1001 | } else { |
| 998 | 1002 | msm_gem_vunmap(obj); |
| 999 | 1003 | put_pages(obj); |
| 1004 | + put_iova_vmas(obj); | |
| 1000 | 1005 | msm_gem_unlock(obj); |
| 1001 | 1006 | } |
| 1002 | 1007 | |
| 1003 | − put_iova_vmas(obj); | |
| 1004 | − | |
| 1005 | 1008 | drm_gem_object_release(obj); |
| 1006 | 1009 | |
| 1007 | 1010 | kfree(msm_obj); |
| @@ -1115,6 +1118,8 @@ static struct drm_gem_object *_msm_gem_new(struct drm_device *dev, · 107 unmodified lines | ||
| 1115 | 1118 | struct msm_gem_vma *vma; |
| 1116 | 1119 | struct page **pages; |
| 1117 | 1120 | |
| 1121 | + drm_gem_private_object_init(dev, obj, size); | |
| 1122 | + | |
| 1118 | 1123 | msm_gem_lock(obj); |
| 1119 | 1124 | |
| 1120 | 1125 | vma = add_vma(obj, NULL); |
| @@ -1126,9 +1131,9 @@ static struct drm_gem_object *_msm_gem_new(struct drm_device *dev, · 5 unmodified lines | ||
| 1126 | 1131 | |
| 1127 | 1132 | to_msm_bo(obj)->vram_node = &vma->node; |
| 1128 | 1133 | |
| 1129 | − drm_gem_private_object_init(dev, obj, size); | |
| 1130 | − | |
| 1134 | + msm_gem_lock(obj); | |
| 1131 | 1135 | pages = get_pages(obj); |
| 1136 | + msm_gem_unlock(obj); | |
| 1132 | 1137 | if (IS_ERR(pages)) { |
| 1133 | 1138 | ret = PTR_ERR(pages); |
| 1134 | 1139 | goto fail; |
| @@ -37,6 +37,7 @@ nouveau-y += dispnv50/wimmc37b.o · 36 unmodified lines | ||
| 37 | 37 | nouveau-y += dispnv50/wndw.o |
| 38 | 38 | nouveau-y += dispnv50/wndwc37e.o |
| 39 | 39 | nouveau-y += dispnv50/wndwc57e.o |
| 40 | +nouveau-y += dispnv50/wndwc67e.o | |
| 40 | 41 | |
| 41 | 42 | nouveau-y += dispnv50/base.o |
| 42 | 43 | nouveau-y += dispnv50/base507c.o |
| @@ -42,6 +42,7 @@ nv50_core_new(struct nouveau_drm *drm, struct nv50_core **pcore) · 41 unmodified lines | ||
| 42 | 42 | int version; |
| 43 | 43 | int (*new)(struct nouveau_drm *, s32, struct nv50_core **); |
| 44 | 44 | } cores[] = { |
| 45 | + { GA102_DISP_CORE_CHANNEL_DMA, 0, corec57d_new }, | |
| 45 | 46 | { TU102_DISP_CORE_CHANNEL_DMA, 0, corec57d_new }, |
| 46 | 47 | { GV100_DISP_CORE_CHANNEL_DMA, 0, corec37d_new }, |
| 47 | 48 | { GP102_DISP_CORE_CHANNEL_DMA, 0, core917d_new }, |
| @@ -31,6 +31,7 @@ nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) · 30 unmodified lines | ||
| 31 | 31 | int version; |
| 32 | 32 | int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); |
| 33 | 33 | } curses[] = { |
| 34 | + { GA102_DISP_CURSOR, 0, cursc37a_new }, | |
| 34 | 35 | { TU102_DISP_CURSOR, 0, cursc37a_new }, |
| 35 | 36 | { GV100_DISP_CURSOR, 0, cursc37a_new }, |
| 36 | 37 | { GK104_DISP_CURSOR, 0, curs907a_new }, |
| @@ -222,7 +222,7 @@ nv50_dmac_wait(struct nvif_push *push, u32 size) · 221 unmodified lines | ||
| 222 | 222 | |
| 223 | 223 | int |
| 224 | 224 | nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, |
| 225 | − const s32 *oclass, u8 head, void *data, u32 size, u64 syncbuf, | |
| 225 | + const s32 *oclass, u8 head, void *data, u32 size, s64 syncbuf, | |
| 226 | 226 | struct nv50_dmac *dmac) |
| 227 | 227 | { |
| 228 | 228 | struct nouveau_cli *cli = (void *)device->object.client; |
| @@ -271,7 +271,7 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, · 42 unmodified lines | ||
| 271 | 271 | if (ret) |
| 272 | 272 | return ret; |
| 273 | 273 | |
| 274 | − if (!syncbuf) | |
| 274 | + if (syncbuf < 0) | |
| 275 | 275 | return 0; |
| 276 | 276 | |
| 277 | 277 | ret = nvif_object_ctor(&dmac->base.user, "kmsSyncCtxDma", NV50_DISP_HANDLE_SYNCBUF, |
| @@ -95,7 +95,7 @@ struct nv50_outp_atom { · 94 unmodified lines | ||
| 95 | 95 | |
| 96 | 96 | int nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, |
| 97 | 97 | const s32 *oclass, u8 head, void *data, u32 size, |
| 98 | − u64 syncbuf, struct nv50_dmac *dmac); | |
| 98 | + s64 syncbuf, struct nv50_dmac *dmac); | |
| 99 | 99 | void nv50_dmac_destroy(struct nv50_dmac *); |
| 100 | 100 | |
| 101 | 101 | /* |
| @@ -31,6 +31,7 @@ nv50_wimm_init(struct nouveau_drm *drm, struct nv50_wndw *wndw) · 30 unmodified lines | ||
| 31 | 31 | int version; |
| 32 | 32 | int (*init)(struct nouveau_drm *, s32, struct nv50_wndw *); |
| 33 | 33 | } wimms[] = { |
| 34 | + { GA102_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, | |
| 34 | 35 | { TU102_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, |
| 35 | 36 | { GV100_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, |
| 36 | 37 | {} |
| @@ -76,7 +76,7 @@ wimmc37b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, · 75 unmodified lines | ||
| 76 | 76 | int ret; |
| 77 | 77 | |
| 78 | 78 | ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, |
| 79 | − &oclass, 0, &args, sizeof(args), 0, | |
| 79 | + &oclass, 0, &args, sizeof(args), -1, | |
| 80 | 80 | &wndw->wimm); |
| 81 | 81 | if (ret) { |
| 82 | 82 | NV_ERROR(drm, "wimm%04x allocation failed: %d\n", oclass, ret); |
| @@ -784,6 +784,7 @@ nv50_wndw_new(struct nouveau_drm *drm, enum drm_plane_type type, int index, · 783 unmodified lines | ||
| 784 | 784 | int (*new)(struct nouveau_drm *, enum drm_plane_type, |
| 785 | 785 | int, s32, struct nv50_wndw **); |
| 786 | 786 | } wndws[] = { |
| 787 | + { GA102_DISP_WINDOW_CHANNEL_DMA, 0, wndwc67e_new }, | |
| 787 | 788 | { TU102_DISP_WINDOW_CHANNEL_DMA, 0, wndwc57e_new }, |
| 788 | 789 | { GV100_DISP_WINDOW_CHANNEL_DMA, 0, wndwc37e_new }, |
| 789 | 790 | {} |
| @@ -129,6 +129,14 @@ int wndwc37e_update(struct nv50_wndw *, u32 *); · 128 unmodified lines | ||
| 129 | 129 | |
| 130 | 130 | int wndwc57e_new(struct nouveau_drm *, enum drm_plane_type, int, s32, |
| 131 | 131 | struct nv50_wndw **); |
| 132 | +bool wndwc57e_ilut(struct nv50_wndw *, struct nv50_wndw_atom *, int); | |
| 133 | +int wndwc57e_ilut_set(struct nv50_wndw *, struct nv50_wndw_atom *); | |
| 134 | +int wndwc57e_ilut_clr(struct nv50_wndw *); | |
| 135 | +int wndwc57e_csc_set(struct nv50_wndw *, struct nv50_wndw_atom *); | |
| 136 | +int wndwc57e_csc_clr(struct nv50_wndw *); | |
| 137 | + | |
| 138 | +int wndwc67e_new(struct nouveau_drm *, enum drm_plane_type, int, s32, | |
| 139 | + struct nv50_wndw **); | |
| 132 | 140 | |
| 133 | 141 | int nv50_wndw_new(struct nouveau_drm *, enum drm_plane_type, int index, |
| 134 | 142 | struct nv50_wndw **); |
| @@ -80,7 +80,7 @@ wndwc57e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) · 79 unmodified lines | ||
| 80 | 80 | return 0; |
| 81 | 81 | } |
| 82 | 82 | |
| 83 | −static int | |
| 83 | +int | |
| 84 | 84 | wndwc57e_csc_clr(struct nv50_wndw *wndw) |
| 85 | 85 | { |
| 86 | 86 | struct nvif_push *push = wndw->wndw.push; |
| @@ -98,7 +98,7 @@ wndwc57e_csc_clr(struct nv50_wndw *wndw) · 11 unmodified lines | ||
| 98 | 98 | return 0; |
| 99 | 99 | } |
| 100 | 100 | |
| 101 | −static int | |
| 101 | +int | |
| 102 | 102 | wndwc57e_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) |
| 103 | 103 | { |
| 104 | 104 | struct nvif_push *push = wndw->wndw.push; |
| @@ -111,7 +111,7 @@ wndwc57e_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) · 6 unmodified lines | ||
| 111 | 111 | return 0; |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | −static int | |
| 114 | +int | |
| 115 | 115 | wndwc57e_ilut_clr(struct nv50_wndw *wndw) |
| 116 | 116 | { |
| 117 | 117 | struct nvif_push *push = wndw->wndw.push; |
| @@ -124,7 +124,7 @@ wndwc57e_ilut_clr(struct nv50_wndw *wndw) · 6 unmodified lines | ||
| 124 | 124 | return 0; |
| 125 | 125 | } |
| 126 | 126 | |
| 127 | −static int | |
| 127 | +int | |
| 128 | 128 | wndwc57e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) |
| 129 | 129 | { |
| 130 | 130 | struct nvif_push *push = wndw->wndw.push; |
| @@ -179,7 +179,7 @@ wndwc57e_ilut_load(struct drm_color_lut *in, int size, void __iomem *mem) · 48 unmodified lines | ||
| 179 | 179 | writew(readw(mem - 4), mem + 4); |
| 180 | 180 | } |
| 181 | 181 | |
| 182 | −static bool | |
| 182 | +bool | |
| 183 | 183 | wndwc57e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size) |
| 184 | 184 | { |
| 185 | 185 | if (size = size ? size : 1024, size != 256 && size != 1024) |
| @@ -0,0 +1,106 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "wndw.h" | |
| 23 | +#include "atom.h" | |
| 24 | + | |
| 25 | +#include <nvif/pushc37b.h> | |
| 26 | + | |
| 27 | +#include <nvhw/class/clc57e.h> | |
| 28 | + | |
| 29 | +static int | |
| 30 | +wndwc67e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) | |
| 31 | +{ | |
| 32 | + struct nvif_push *push = wndw->wndw.push; | |
| 33 | + int ret; | |
| 34 | + | |
| 35 | + if ((ret = PUSH_WAIT(push, 17))) | |
| 36 | + return ret; | |
| 37 | + | |
| 38 | + PUSH_MTHD(push, NVC57E, SET_PRESENT_CONTROL, | |
| 39 | + NVVAL(NVC57E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval) | | |
| 40 | + NVVAL(NVC57E, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) | | |
| 41 | + NVDEF(NVC57E, SET_PRESENT_CONTROL, TIMESTAMP_MODE, DISABLE)); | |
| 42 | + | |
| 43 | + PUSH_MTHD(push, NVC57E, SET_SIZE, | |
| 44 | + NVVAL(NVC57E, SET_SIZE, WIDTH, asyw->image.w) | | |
| 45 | + NVVAL(NVC57E, SET_SIZE, HEIGHT, asyw->image.h), | |
| 46 | + | |
| 47 | + SET_STORAGE, | |
| 48 | + NVVAL(NVC57E, SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh), | |
| 49 | + | |
| 50 | + SET_PARAMS, | |
| 51 | + NVVAL(NVC57E, SET_PARAMS, FORMAT, asyw->image.format) | | |
| 52 | + NVDEF(NVC57E, SET_PARAMS, CLAMP_BEFORE_BLEND, DISABLE) | | |
| 53 | + NVDEF(NVC57E, SET_PARAMS, SWAP_UV, DISABLE) | | |
| 54 | + NVDEF(NVC57E, SET_PARAMS, FMT_ROUNDING_MODE, ROUND_TO_NEAREST), | |
| 55 | + | |
| 56 | + SET_PLANAR_STORAGE(0), | |
| 57 | + NVVAL(NVC57E, SET_PLANAR_STORAGE, PITCH, asyw->image.blocks[0]) | | |
| 58 | + NVVAL(NVC57E, SET_PLANAR_STORAGE, PITCH, asyw->image.pitch[0] >> 6)); | |
| 59 | + | |
| 60 | + PUSH_MTHD(push, NVC57E, SET_CONTEXT_DMA_ISO(0), asyw->image.handle, 1); | |
| 61 | + PUSH_MTHD(push, NVC57E, SET_OFFSET(0), asyw->image.offset[0] >> 8); | |
| 62 | + | |
| 63 | + PUSH_MTHD(push, NVC57E, SET_POINT_IN(0), | |
| 64 | + NVVAL(NVC57E, SET_POINT_IN, X, asyw->state.src_x >> 16) | | |
| 65 | + NVVAL(NVC57E, SET_POINT_IN, Y, asyw->state.src_y >> 16)); | |
| 66 | + | |
| 67 | + PUSH_MTHD(push, NVC57E, SET_SIZE_IN, | |
| 68 | + NVVAL(NVC57E, SET_SIZE_IN, WIDTH, asyw->state.src_w >> 16) | | |
| 69 | + NVVAL(NVC57E, SET_SIZE_IN, HEIGHT, asyw->state.src_h >> 16)); | |
| 70 | + | |
| 71 | + PUSH_MTHD(push, NVC57E, SET_SIZE_OUT, | |
| 72 | + NVVAL(NVC57E, SET_SIZE_OUT, WIDTH, asyw->state.crtc_w) | | |
| 73 | + NVVAL(NVC57E, SET_SIZE_OUT, HEIGHT, asyw->state.crtc_h)); | |
| 74 | + return 0; | |
| 75 | +} | |
| 76 | + | |
| 77 | +static const struct nv50_wndw_func | |
| 78 | +wndwc67e = { | |
| 79 | + .acquire = wndwc37e_acquire, | |
| 80 | + .release = wndwc37e_release, | |
| 81 | + .sema_set = wndwc37e_sema_set, | |
| 82 | + .sema_clr = wndwc37e_sema_clr, | |
| 83 | + .ntfy_set = wndwc37e_ntfy_set, | |
| 84 | + .ntfy_clr = wndwc37e_ntfy_clr, | |
| 85 | + .ntfy_reset = corec37d_ntfy_init, | |
| 86 | + .ntfy_wait_begun = base507c_ntfy_wait_begun, | |
| 87 | + .ilut = wndwc57e_ilut, | |
| 88 | + .ilut_identity = true, | |
| 89 | + .ilut_size = 1024, | |
| 90 | + .xlut_set = wndwc57e_ilut_set, | |
| 91 | + .xlut_clr = wndwc57e_ilut_clr, | |
| 92 | + .csc = base907c_csc, | |
| 93 | + .csc_set = wndwc57e_csc_set, | |
| 94 | + .csc_clr = wndwc57e_csc_clr, | |
| 95 | + .image_set = wndwc67e_image_set, | |
| 96 | + .image_clr = wndwc37e_image_clr, | |
| 97 | + .blend_set = wndwc37e_blend_set, | |
| 98 | + .update = wndwc37e_update, | |
| 99 | +}; | |
| 100 | + | |
| 101 | +int | |
| 102 | +wndwc67e_new(struct nouveau_drm *drm, enum drm_plane_type type, int index, | |
| 103 | + s32 oclass, struct nv50_wndw **pwndw) | |
| 104 | +{ | |
| 105 | + return wndwc37e_new_(&wndwc67e, drm, type, index, oclass, BIT(index >> 1), pwndw); | |
| 106 | +} | |
| @@ -33,6 +33,7 @@ struct nv_device_info_v0 { · 32 unmodified lines | ||
| 33 | 33 | #define NV_DEVICE_INFO_V0_PASCAL 0x0a |
| 34 | 34 | #define NV_DEVICE_INFO_V0_VOLTA 0x0b |
| 35 | 35 | #define NV_DEVICE_INFO_V0_TURING 0x0c |
| 36 | +#define NV_DEVICE_INFO_V0_AMPERE 0x0d | |
| 36 | 37 | __u8 family; |
| 37 | 38 | __u8 pad06[2]; |
| 38 | 39 | __u64 ram_size; |
| @@ -88,6 +88,7 @@ · 87 unmodified lines | ||
| 88 | 88 | #define GP102_DISP /* cl5070.h */ 0x00009870 |
| 89 | 89 | #define GV100_DISP /* cl5070.h */ 0x0000c370 |
| 90 | 90 | #define TU102_DISP /* cl5070.h */ 0x0000c570 |
| 91 | +#define GA102_DISP /* cl5070.h */ 0x0000c670 | |
| 91 | 92 | |
| 92 | 93 | #define GV100_DISP_CAPS 0x0000c373 |
| 93 | 94 | |
| @@ -103,6 +104,7 @@ · 9 unmodified lines | ||
| 103 | 104 | #define GK104_DISP_CURSOR /* cl507a.h */ 0x0000917a |
| 104 | 105 | #define GV100_DISP_CURSOR /* cl507a.h */ 0x0000c37a |
| 105 | 106 | #define TU102_DISP_CURSOR /* cl507a.h */ 0x0000c57a |
| 107 | +#define GA102_DISP_CURSOR /* cl507a.h */ 0x0000c67a | |
| 106 | 108 | |
| 107 | 109 | #define NV50_DISP_OVERLAY /* cl507b.h */ 0x0000507b |
| 108 | 110 | #define G82_DISP_OVERLAY /* cl507b.h */ 0x0000827b |
| @@ -112,6 +114,7 @@ · 3 unmodified lines | ||
| 112 | 114 | |
| 113 | 115 | #define GV100_DISP_WINDOW_IMM_CHANNEL_DMA /* clc37b.h */ 0x0000c37b |
| 114 | 116 | #define TU102_DISP_WINDOW_IMM_CHANNEL_DMA /* clc37b.h */ 0x0000c57b |
| 117 | +#define GA102_DISP_WINDOW_IMM_CHANNEL_DMA /* clc37b.h */ 0x0000c67b | |
| 115 | 118 | |
| 116 | 119 | #define NV50_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000507c |
| 117 | 120 | #define G82_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000827c |
| @@ -135,6 +138,7 @@ · 17 unmodified lines | ||
| 135 | 138 | #define GP102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000987d |
| 136 | 139 | #define GV100_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c37d |
| 137 | 140 | #define TU102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c57d |
| 141 | +#define GA102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c67d | |
| 138 | 142 | |
| 139 | 143 | #define NV50_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000507e |
| 140 | 144 | #define G82_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000827e |
| @@ -145,6 +149,7 @@ · 4 unmodified lines | ||
| 145 | 149 | |
| 146 | 150 | #define GV100_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c37e |
| 147 | 151 | #define TU102_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c57e |
| 152 | +#define GA102_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c67e | |
| 148 | 153 | |
| 149 | 154 | #define NV50_TESLA 0x00005097 |
| 150 | 155 | #define G82_TESLA 0x00008297 |
| @@ -120,6 +120,7 @@ struct nvkm_device { · 119 unmodified lines | ||
| 120 | 120 | GP100 = 0x130, |
| 121 | 121 | GV100 = 0x140, |
| 122 | 122 | TU100 = 0x160, |
| 123 | + GA100 = 0x170, | |
| 123 | 124 | } card_type; |
| 124 | 125 | u32 chipset; |
| 125 | 126 | u8 chiprev; |
| @@ -37,4 +37,5 @@ int gp100_disp_new(struct nvkm_device *, int, struct nvkm_disp **); · 36 unmodified lines | ||
| 37 | 37 | int gp102_disp_new(struct nvkm_device *, int, struct nvkm_disp **); |
| 38 | 38 | int gv100_disp_new(struct nvkm_device *, int, struct nvkm_disp **); |
| 39 | 39 | int tu102_disp_new(struct nvkm_device *, int, struct nvkm_disp **); |
| 40 | +int ga102_disp_new(struct nvkm_device *, int, struct nvkm_disp **); | |
| 40 | 41 | #endif |
| @@ -32,4 +32,5 @@ int gm107_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); · 31 unmodified lines | ||
| 32 | 32 | int gm200_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); |
| 33 | 33 | int gv100_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); |
| 34 | 34 | int tu102_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); |
| 35 | +int ga100_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); | |
| 35 | 36 | #endif |
| @@ -86,6 +86,8 @@ int gp100_fb_new(struct nvkm_device *, int, struct nvkm_fb **); · 85 unmodified lines | ||
| 86 | 86 | int gp102_fb_new(struct nvkm_device *, int, struct nvkm_fb **); |
| 87 | 87 | int gp10b_fb_new(struct nvkm_device *, int, struct nvkm_fb **); |
| 88 | 88 | int gv100_fb_new(struct nvkm_device *, int, struct nvkm_fb **); |
| 89 | +int ga100_fb_new(struct nvkm_device *, int, struct nvkm_fb **); | |
| 90 | +int ga102_fb_new(struct nvkm_device *, int, struct nvkm_fb **); | |
| 89 | 91 | |
| 90 | 92 | #include <subdev/bios.h> |
| 91 | 93 | #include <subdev/bios/ramcfg.h> |
| @@ -37,4 +37,5 @@ int nv50_gpio_new(struct nvkm_device *, int, struct nvkm_gpio **); · 36 unmodified lines | ||
| 37 | 37 | int g94_gpio_new(struct nvkm_device *, int, struct nvkm_gpio **); |
| 38 | 38 | int gf119_gpio_new(struct nvkm_device *, int, struct nvkm_gpio **); |
| 39 | 39 | int gk104_gpio_new(struct nvkm_device *, int, struct nvkm_gpio **); |
| 40 | +int ga102_gpio_new(struct nvkm_device *, int, struct nvkm_gpio **); | |
| 40 | 41 | #endif |
| @@ -92,6 +92,7 @@ int g94_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); · 91 unmodified lines | ||
| 92 | 92 | int gf117_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); |
| 93 | 93 | int gf119_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); |
| 94 | 94 | int gk104_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); |
| 95 | +int gk110_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); | |
| 95 | 96 | int gm200_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); |
| 96 | 97 | |
| 97 | 98 | static inline int |
| @@ -32,4 +32,5 @@ int gk20a_mc_new(struct nvkm_device *, int, struct nvkm_mc **); · 31 unmodified lines | ||
| 32 | 32 | int gp100_mc_new(struct nvkm_device *, int, struct nvkm_mc **); |
| 33 | 33 | int gp10b_mc_new(struct nvkm_device *, int, struct nvkm_mc **); |
| 34 | 34 | int tu102_mc_new(struct nvkm_device *, int, struct nvkm_mc **); |
| 35 | +int ga100_mc_new(struct nvkm_device *, int, struct nvkm_mc **); | |
| 35 | 36 | #endif |
| @@ -256,6 +256,7 @@ nouveau_backlight_init(struct drm_connector *connector) · 255 unmodified lines | ||
| 256 | 256 | case NV_DEVICE_INFO_V0_PASCAL: |
| 257 | 257 | case NV_DEVICE_INFO_V0_VOLTA: |
| 258 | 258 | case NV_DEVICE_INFO_V0_TURING: |
| 259 | + case NV_DEVICE_INFO_V0_AMPERE: //XXX: not confirmed | |
| 259 | 260 | ret = nv50_backlight_init(nv_encoder, &props, &ops); |
| 260 | 261 | break; |
| 261 | 262 | default: |
| @@ -35,6 +35,7 @@ nvif_disp_ctor(struct nvif_device *device, const char *name, s32 oclass, · 34 unmodified lines | ||
| 35 | 35 | struct nvif_disp *disp) |
| 36 | 36 | { |
| 37 | 37 | static const struct nvif_mclass disps[] = { |
| 38 | + { GA102_DISP, -1 }, | |
| 38 | 39 | { TU102_DISP, -1 }, |
| 39 | 40 | { GV100_DISP, -1 }, |
| 40 | 41 | { GP102_DISP, -1 }, |
| @@ -1815,7 +1815,7 @@ nvf0_chipset = { · 1814 unmodified lines | ||
| 1815 | 1815 | .fb = gk110_fb_new, |
| 1816 | 1816 | .fuse = gf100_fuse_new, |
| 1817 | 1817 | .gpio = gk104_gpio_new, |
| 1818 | − .i2c = gk104_i2c_new, | |
| 1818 | + .i2c = gk110_i2c_new, | |
| 1819 | 1819 | .ibus = gk104_ibus_new, |
| 1820 | 1820 | .iccsense = gf100_iccsense_new, |
| 1821 | 1821 | .imem = nv50_instmem_new, |
| @@ -1853,7 +1853,7 @@ nvf1_chipset = { · 31 unmodified lines | ||
| 1853 | 1853 | .fb = gk110_fb_new, |
| 1854 | 1854 | .fuse = gf100_fuse_new, |
| 1855 | 1855 | .gpio = gk104_gpio_new, |
| 1856 | − .i2c = gk104_i2c_new, | |
| 1856 | + .i2c = gk110_i2c_new, | |
| 1857 | 1857 | .ibus = gk104_ibus_new, |
| 1858 | 1858 | .iccsense = gf100_iccsense_new, |
| 1859 | 1859 | .imem = nv50_instmem_new, |
| @@ -1891,7 +1891,7 @@ nv106_chipset = { · 31 unmodified lines | ||
| 1891 | 1891 | .fb = gk110_fb_new, |
| 1892 | 1892 | .fuse = gf100_fuse_new, |
| 1893 | 1893 | .gpio = gk104_gpio_new, |
| 1894 | − .i2c = gk104_i2c_new, | |
| 1894 | + .i2c = gk110_i2c_new, | |
| 1895 | 1895 | .ibus = gk104_ibus_new, |
| 1896 | 1896 | .iccsense = gf100_iccsense_new, |
| 1897 | 1897 | .imem = nv50_instmem_new, |
| @@ -1929,7 +1929,7 @@ nv108_chipset = { · 31 unmodified lines | ||
| 1929 | 1929 | .fb = gk110_fb_new, |
| 1930 | 1930 | .fuse = gf100_fuse_new, |
| 1931 | 1931 | .gpio = gk104_gpio_new, |
| 1932 | − .i2c = gk104_i2c_new, | |
| 1932 | + .i2c = gk110_i2c_new, | |
| 1933 | 1933 | .ibus = gk104_ibus_new, |
| 1934 | 1934 | .iccsense = gf100_iccsense_new, |
| 1935 | 1935 | .imem = nv50_instmem_new, |
| @@ -1967,7 +1967,7 @@ nv117_chipset = { · 31 unmodified lines | ||
| 1967 | 1967 | .fb = gm107_fb_new, |
| 1968 | 1968 | .fuse = gm107_fuse_new, |
| 1969 | 1969 | .gpio = gk104_gpio_new, |
| 1970 | − .i2c = gk104_i2c_new, | |
| 1970 | + .i2c = gk110_i2c_new, | |
| 1971 | 1971 | .ibus = gk104_ibus_new, |
| 1972 | 1972 | .iccsense = gf100_iccsense_new, |
| 1973 | 1973 | .imem = nv50_instmem_new, |
| @@ -2003,7 +2003,7 @@ nv118_chipset = { · 29 unmodified lines | ||
| 2003 | 2003 | .fb = gm107_fb_new, |
| 2004 | 2004 | .fuse = gm107_fuse_new, |
| 2005 | 2005 | .gpio = gk104_gpio_new, |
| 2006 | − .i2c = gk104_i2c_new, | |
| 2006 | + .i2c = gk110_i2c_new, | |
| 2007 | 2007 | .ibus = gk104_ibus_new, |
| 2008 | 2008 | .iccsense = gf100_iccsense_new, |
| 2009 | 2009 | .imem = nv50_instmem_new, |
| @@ -2652,6 +2652,61 @@ nv168_chipset = { · 642 unmodified lines | ||
| 2652 | 2652 | .sec2 = tu102_sec2_new, |
| 2653 | 2653 | }; |
| 2654 | 2654 | |
| 2655 | +static const struct nvkm_device_chip | |
| 2656 | +nv170_chipset = { | |
| 2657 | + .name = "GA100", | |
| 2658 | + .bar = tu102_bar_new, | |
| 2659 | + .bios = nvkm_bios_new, | |
| 2660 | + .devinit = ga100_devinit_new, | |
| 2661 | + .fb = ga100_fb_new, | |
| 2662 | + .gpio = gk104_gpio_new, | |
| 2663 | + .i2c = gm200_i2c_new, | |
| 2664 | + .ibus = gm200_ibus_new, | |
| 2665 | + .imem = nv50_instmem_new, | |
| 2666 | + .mc = ga100_mc_new, | |
| 2667 | + .mmu = tu102_mmu_new, | |
| 2668 | + .pci = gp100_pci_new, | |
| 2669 | + .timer = gk20a_timer_new, | |
| 2670 | +}; | |
| 2671 | + | |
| 2672 | +static const struct nvkm_device_chip | |
| 2673 | +nv172_chipset = { | |
| 2674 | + .name = "GA102", | |
| 2675 | + .bar = tu102_bar_new, | |
| 2676 | + .bios = nvkm_bios_new, | |
| 2677 | + .devinit = ga100_devinit_new, | |
| 2678 | + .fb = ga102_fb_new, | |
| 2679 | + .gpio = ga102_gpio_new, | |
| 2680 | + .i2c = gm200_i2c_new, | |
| 2681 | + .ibus = gm200_ibus_new, | |
| 2682 | + .imem = nv50_instmem_new, | |
| 2683 | + .mc = ga100_mc_new, | |
| 2684 | + .mmu = tu102_mmu_new, | |
| 2685 | + .pci = gp100_pci_new, | |
| 2686 | + .timer = gk20a_timer_new, | |
| 2687 | + .disp = ga102_disp_new, | |
| 2688 | + .dma = gv100_dma_new, | |
| 2689 | +}; | |
| 2690 | + | |
| 2691 | +static const struct nvkm_device_chip | |
| 2692 | +nv174_chipset = { | |
| 2693 | + .name = "GA104", | |
| 2694 | + .bar = tu102_bar_new, | |
| 2695 | + .bios = nvkm_bios_new, | |
| 2696 | + .devinit = ga100_devinit_new, | |
| 2697 | + .fb = ga102_fb_new, | |
| 2698 | + .gpio = ga102_gpio_new, | |
| 2699 | + .i2c = gm200_i2c_new, | |
| 2700 | + .ibus = gm200_ibus_new, | |
| 2701 | + .imem = nv50_instmem_new, | |
| 2702 | + .mc = ga100_mc_new, | |
| 2703 | + .mmu = tu102_mmu_new, | |
| 2704 | + .pci = gp100_pci_new, | |
| 2705 | + .timer = gk20a_timer_new, | |
| 2706 | + .disp = ga102_disp_new, | |
| 2707 | + .dma = gv100_dma_new, | |
| 2708 | +}; | |
| 2709 | + | |
| 2655 | 2710 | static int |
| 2656 | 2711 | nvkm_device_event_ctor(struct nvkm_object *object, void *data, u32 size, |
| 2657 | 2712 | struct nvkm_notify *notify) |
| @@ -3063,6 +3118,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, · 405 unmodified lines | ||
| 3063 | 3118 | case 0x130: device->card_type = GP100; break; |
| 3064 | 3119 | case 0x140: device->card_type = GV100; break; |
| 3065 | 3120 | case 0x160: device->card_type = TU100; break; |
| 3121 | + case 0x170: device->card_type = GA100; break; | |
| 3066 | 3122 | default: |
| 3067 | 3123 | break; |
| 3068 | 3124 | } |
| @@ -3160,10 +3216,23 @@ nvkm_device_ctor(const struct nvkm_device_func *func, · 91 unmodified lines | ||
| 3160 | 3216 | case 0x166: device->chip = &nv166_chipset; break; |
| 3161 | 3217 | case 0x167: device->chip = &nv167_chipset; break; |
| 3162 | 3218 | case 0x168: device->chip = &nv168_chipset; break; |
| 3219 | + case 0x172: device->chip = &nv172_chipset; break; | |
| 3220 | + case 0x174: device->chip = &nv174_chipset; break; | |
| 3163 | 3221 | default: |
| 3164 | − nvdev_error(device, "unknown chipset (%08x)\n", boot0); | |
| 3165 | − ret = -ENODEV; | |
| 3166 | − goto done; | |
| 3222 | + if (nvkm_boolopt(device->cfgopt, "NvEnableUnsupportedChipsets", false)) { | |
| 3223 | + switch (device->chipset) { | |
| 3224 | + case 0x170: device->chip = &nv170_chipset; break; | |
| 3225 | + default: | |
| 3226 | + break; | |
| 3227 | + } | |
| 3228 | + } | |
| 3229 | + | |
| 3230 | + if (!device->chip) { | |
| 3231 | + nvdev_error(device, "unknown chipset (%08x)\n", boot0); | |
| 3232 | + ret = -ENODEV; | |
| 3233 | + goto done; | |
| 3234 | + } | |
| 3235 | + break; | |
| 3167 | 3236 | } |
| 3168 | 3237 | |
| 3169 | 3238 | nvdev_info(device, "NVIDIA %s (%08x)\n", |
| @@ -176,6 +176,7 @@ nvkm_udevice_info(struct nvkm_udevice *udev, void *data, u32 size) · 175 unmodified lines | ||
| 176 | 176 | case GP100: args->v0.family = NV_DEVICE_INFO_V0_PASCAL; break; |
| 177 | 177 | case GV100: args->v0.family = NV_DEVICE_INFO_V0_VOLTA; break; |
| 178 | 178 | case TU100: args->v0.family = NV_DEVICE_INFO_V0_TURING; break; |
| 179 | + case GA100: args->v0.family = NV_DEVICE_INFO_V0_AMPERE; break; | |
| 179 | 180 | default: |
| 180 | 181 | args->v0.family = 0; |
| 181 | 182 | break; |
| @@ -17,6 +17,7 @@ nvkm-y += nvkm/engine/disp/gp100.o · 16 unmodified lines | ||
| 17 | 17 | nvkm-y += nvkm/engine/disp/gp102.o |
| 18 | 18 | nvkm-y += nvkm/engine/disp/gv100.o |
| 19 | 19 | nvkm-y += nvkm/engine/disp/tu102.o |
| 20 | +nvkm-y += nvkm/engine/disp/ga102.o | |
| 20 | 21 | nvkm-y += nvkm/engine/disp/vga.o |
| 21 | 22 | |
| 22 | 23 | nvkm-y += nvkm/engine/disp/head.o |
| @@ -42,6 +43,7 @@ nvkm-y += nvkm/engine/disp/sorgm200.o · 19 unmodified lines | ||
| 42 | 43 | nvkm-y += nvkm/engine/disp/sorgp100.o |
| 43 | 44 | nvkm-y += nvkm/engine/disp/sorgv100.o |
| 44 | 45 | nvkm-y += nvkm/engine/disp/sortu102.o |
| 46 | +nvkm-y += nvkm/engine/disp/sorga102.o | |
| 45 | 47 | |
| 46 | 48 | nvkm-y += nvkm/engine/disp/outp.o |
| 47 | 49 | nvkm-y += nvkm/engine/disp/dp.o |
| @@ -75,6 +77,7 @@ nvkm-y += nvkm/engine/disp/rootgp100.o · 27 unmodified lines | ||
| 75 | 77 | nvkm-y += nvkm/engine/disp/rootgp102.o |
| 76 | 78 | nvkm-y += nvkm/engine/disp/rootgv100.o |
| 77 | 79 | nvkm-y += nvkm/engine/disp/roottu102.o |
| 80 | +nvkm-y += nvkm/engine/disp/rootga102.o | |
| 78 | 81 | |
| 79 | 82 | nvkm-y += nvkm/engine/disp/capsgv100.o |
| 80 | 83 | |
| @@ -33,6 +33,12 @@ · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | #include <nvif/event.h> |
| 35 | 35 | |
| 36 | +/* IED scripts are no longer used by UEFI/RM from Ampere, but have been updated for | |
| 37 | + * the x86 option ROM. However, the relevant VBIOS table versions weren't modified, | |
| 38 | + * so we're unable to detect this in a nice way. | |
| 39 | + */ | |
| 40 | +#define AMPERE_IED_HACK(disp) ((disp)->engine.subdev.device->card_type >= GA100) | |
| 41 | + | |
| 36 | 42 | struct lt_state { |
| 37 | 43 | struct nvkm_dp *dp; |
| 38 | 44 | u8 stat[6]; |
| @@ -238,6 +244,19 @@ nvkm_dp_train_links(struct nvkm_dp *dp) · 199 unmodified lines | ||
| 238 | 244 | dp->dpcd[DPCD_RC02] &= ~DPCD_RC02_TPS3_SUPPORTED; |
| 239 | 245 | lt.pc2 = dp->dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED; |
| 240 | 246 | |
| 247 | + if (AMPERE_IED_HACK(disp) && (lnkcmp = lt.dp->info.script[0])) { | |
| 248 | + /* Execute BeforeLinkTraining script from DP Info table. */ | |
| 249 | + while (ior->dp.bw < nvbios_rd08(bios, lnkcmp)) | |
| 250 | + lnkcmp += 3; | |
| 251 | + lnkcmp = nvbios_rd16(bios, lnkcmp + 1); | |
| 252 | + | |
| 253 | + nvbios_init(&dp->outp.disp->engine.subdev, lnkcmp, | |
| 254 | + init.outp = &dp->outp.info; | |
| 255 | + init.or = ior->id; | |
| 256 | + init.link = ior->asy.link; | |
| 257 | + ); | |
| 258 | + } | |
| 259 | + | |
| 241 | 260 | /* Set desired link configuration on the source. */ |
| 242 | 261 | if ((lnkcmp = lt.dp->info.lnkcmp)) { |
| 243 | 262 | if (dp->version < 0x30) { |
| @@ -316,12 +335,14 @@ nvkm_dp_train_init(struct nvkm_dp *dp) · 72 unmodified lines | ||
| 316 | 335 | ); |
| 317 | 336 | } |
| 318 | 337 | |
| 319 | − /* Execute BeforeLinkTraining script from DP Info table. */ | |
| 320 | − nvbios_init(&dp->outp.disp->engine.subdev, dp->info.script[0], | |
| 321 | − init.outp = &dp->outp.info; | |
| 322 | − init.or = dp->outp.ior->id; | |
| 323 | − init.link = dp->outp.ior->asy.link; | |
| 324 | − ); | |
| 338 | + if (!AMPERE_IED_HACK(dp->outp.disp)) { | |
| 339 | + /* Execute BeforeLinkTraining script from DP Info table. */ | |
| 340 | + nvbios_init(&dp->outp.disp->engine.subdev, dp->info.script[0], | |
| 341 | + init.outp = &dp->outp.info; | |
| 342 | + init.or = dp->outp.ior->id; | |
| 343 | + init.link = dp->outp.ior->asy.link; | |
| 344 | + ); | |
| 345 | + } | |
| 325 | 346 | } |
| 326 | 347 | |
| 327 | 348 | static const struct dp_rates { |
| @@ -0,0 +1,46 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "nv50.h" | |
| 23 | +#include "head.h" | |
| 24 | +#include "ior.h" | |
| 25 | +#include "channv50.h" | |
| 26 | +#include "rootnv50.h" | |
| 27 | + | |
| 28 | +static const struct nv50_disp_func | |
| 29 | +ga102_disp = { | |
| 30 | + .init = tu102_disp_init, | |
| 31 | + .fini = gv100_disp_fini, | |
| 32 | + .intr = gv100_disp_intr, | |
| 33 | + .uevent = &gv100_disp_chan_uevent, | |
| 34 | + .super = gv100_disp_super, | |
| 35 | + .root = &ga102_disp_root_oclass, | |
| 36 | + .wndw = { .cnt = gv100_disp_wndw_cnt }, | |
| 37 | + .head = { .cnt = gv100_head_cnt, .new = gv100_head_new }, | |
| 38 | + .sor = { .cnt = gv100_sor_cnt, .new = ga102_sor_new }, | |
| 39 | + .ramht_size = 0x2000, | |
| 40 | +}; | |
| 41 | + | |
| 42 | +int | |
| 43 | +ga102_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) | |
| 44 | +{ | |
| 45 | + return nv50_disp_new_(&ga102_disp, device, index, pdisp); | |
| 46 | +} | |
| @@ -150,6 +150,8 @@ void gv100_sor_dp_audio(struct nvkm_ior *, int, bool); · 149 unmodified lines | ||
| 150 | 150 | void gv100_sor_dp_audio_sym(struct nvkm_ior *, int, u16, u32); |
| 151 | 151 | void gv100_sor_dp_watermark(struct nvkm_ior *, int, u8); |
| 152 | 152 | |
| 153 | +void tu102_sor_dp_vcpi(struct nvkm_ior *, int, u8, u8, u16, u16); | |
| 154 | + | |
| 153 | 155 | void g84_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); |
| 154 | 156 | void gt215_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); |
| 155 | 157 | void gf119_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); |
| @@ -207,4 +209,6 @@ int gv100_sor_cnt(struct nvkm_disp *, unsigned long *); · 51 unmodified lines | ||
| 207 | 209 | int gv100_sor_new(struct nvkm_disp *, int); |
| 208 | 210 | |
| 209 | 211 | int tu102_sor_new(struct nvkm_disp *, int); |
| 212 | + | |
| 213 | +int ga102_sor_new(struct nvkm_disp *, int); | |
| 210 | 214 | #endif |
| @@ -86,6 +86,8 @@ void gv100_disp_intr(struct nv50_disp *); · 85 unmodified lines | ||
| 86 | 86 | void gv100_disp_super(struct work_struct *); |
| 87 | 87 | int gv100_disp_wndw_cnt(struct nvkm_disp *, unsigned long *); |
| 88 | 88 | |
| 89 | +int tu102_disp_init(struct nv50_disp *); | |
| 90 | + | |
| 89 | 91 | void nv50_disp_dptmds_war_2(struct nv50_disp *, struct dcb_output *); |
| 90 | 92 | void nv50_disp_dptmds_war_3(struct nv50_disp *, struct dcb_output *); |
| 91 | 93 | void nv50_disp_update_sppll1(struct nv50_disp *); |
| @@ -0,0 +1,52 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "rootnv50.h" | |
| 23 | +#include "channv50.h" | |
| 24 | + | |
| 25 | +#include <nvif/class.h> | |
| 26 | + | |
| 27 | +static const struct nv50_disp_root_func | |
| 28 | +ga102_disp_root = { | |
| 29 | + .user = { | |
| 30 | + {{-1,-1,GV100_DISP_CAPS }, gv100_disp_caps_new }, | |
| 31 | + {{0,0,GA102_DISP_CURSOR }, gv100_disp_curs_new }, | |
| 32 | + {{0,0,GA102_DISP_WINDOW_IMM_CHANNEL_DMA}, gv100_disp_wimm_new }, | |
| 33 | + {{0,0,GA102_DISP_CORE_CHANNEL_DMA }, gv100_disp_core_new }, | |
| 34 | + {{0,0,GA102_DISP_WINDOW_CHANNEL_DMA }, gv100_disp_wndw_new }, | |
| 35 | + {} | |
| 36 | + }, | |
| 37 | +}; | |
| 38 | + | |
| 39 | +static int | |
| 40 | +ga102_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass, | |
| 41 | + void *data, u32 size, struct nvkm_object **pobject) | |
| 42 | +{ | |
| 43 | + return nv50_disp_root_new_(&ga102_disp_root, disp, oclass, data, size, pobject); | |
| 44 | +} | |
| 45 | + | |
| 46 | +const struct nvkm_disp_oclass | |
| 47 | +ga102_disp_root_oclass = { | |
| 48 | + .base.oclass = GA102_DISP, | |
| 49 | + .base.minver = -1, | |
| 50 | + .base.maxver = -1, | |
| 51 | + .ctor = ga102_disp_root_new, | |
| 52 | +}; | |
| @@ -41,4 +41,5 @@ extern const struct nvkm_disp_oclass gp100_disp_root_oclass; · 40 unmodified lines | ||
| 41 | 41 | extern const struct nvkm_disp_oclass gp102_disp_root_oclass; |
| 42 | 42 | extern const struct nvkm_disp_oclass gv100_disp_root_oclass; |
| 43 | 43 | extern const struct nvkm_disp_oclass tu102_disp_root_oclass; |
| 44 | +extern const struct nvkm_disp_oclass ga102_disp_root_oclass; | |
| 44 | 45 | #endif |
| @@ -0,0 +1,140 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "ior.h" | |
| 23 | + | |
| 24 | +#include <subdev/timer.h> | |
| 25 | + | |
| 26 | +static int | |
| 27 | +ga102_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux) | |
| 28 | +{ | |
| 29 | + struct nvkm_device *device = sor->disp->engine.subdev.device; | |
| 30 | + const u32 soff = nv50_ior_base(sor); | |
| 31 | + const u32 loff = nv50_sor_link(sor); | |
| 32 | + u32 dpctrl = 0x00000000; | |
| 33 | + u32 clksor = 0x00000000; | |
| 34 | + | |
| 35 | + switch (sor->dp.bw) { | |
| 36 | + case 0x06: clksor |= 0x00000000; break; | |
| 37 | + case 0x0a: clksor |= 0x00040000; break; | |
| 38 | + case 0x14: clksor |= 0x00080000; break; | |
| 39 | + case 0x1e: clksor |= 0x000c0000; break; | |
| 40 | + default: | |
| 41 | + WARN_ON(1); | |
| 42 | + return -EINVAL; | |
| 43 | + } | |
| 44 | + | |
| 45 | + dpctrl |= ((1 << sor->dp.nr) - 1) << 16; | |
| 46 | + if (sor->dp.mst) | |
| 47 | + dpctrl |= 0x40000000; | |
| 48 | + if (sor->dp.ef) | |
| 49 | + dpctrl |= 0x00004000; | |
| 50 | + | |
| 51 | + nvkm_mask(device, 0x612300 + soff, 0x007c0000, clksor); | |
| 52 | + | |
| 53 | + /*XXX*/ | |
| 54 | + nvkm_msec(device, 40, NVKM_DELAY); | |
| 55 | + nvkm_mask(device, 0x612300 + soff, 0x00030000, 0x00010000); | |
| 56 | + nvkm_mask(device, 0x61c10c + loff, 0x00000003, 0x00000001); | |
| 57 | + | |
| 58 | + nvkm_mask(device, 0x61c10c + loff, 0x401f4000, dpctrl); | |
| 59 | + return 0; | |
| 60 | +} | |
| 61 | + | |
| 62 | +static void | |
| 63 | +ga102_sor_clock(struct nvkm_ior *sor) | |
| 64 | +{ | |
| 65 | + struct nvkm_device *device = sor->disp->engine.subdev.device; | |
| 66 | + u32 div2 = 0; | |
| 67 | + if (sor->asy.proto == TMDS) { | |
| 68 | + if (sor->tmds.high_speed) | |
| 69 | + div2 = 1; | |
| 70 | + } | |
| 71 | + nvkm_wr32(device, 0x00ec08 + (sor->id * 0x10), 0x00000000); | |
| 72 | + nvkm_wr32(device, 0x00ec04 + (sor->id * 0x10), div2); | |
| 73 | +} | |
| 74 | + | |
| 75 | +static const struct nvkm_ior_func | |
| 76 | +ga102_sor_hda = { | |
| 77 | + .route = { | |
| 78 | + .get = gm200_sor_route_get, | |
| 79 | + .set = gm200_sor_route_set, | |
| 80 | + }, | |
| 81 | + .state = gv100_sor_state, | |
| 82 | + .power = nv50_sor_power, | |
| 83 | + .clock = ga102_sor_clock, | |
| 84 | + .hdmi = { | |
| 85 | + .ctrl = gv100_hdmi_ctrl, | |
| 86 | + .scdc = gm200_hdmi_scdc, | |
| 87 | + }, | |
| 88 | + .dp = { | |
| 89 | + .lanes = { 0, 1, 2, 3 }, | |
| 90 | + .links = ga102_sor_dp_links, | |
| 91 | + .power = g94_sor_dp_power, | |
| 92 | + .pattern = gm107_sor_dp_pattern, | |
| 93 | + .drive = gm200_sor_dp_drive, | |
| 94 | + .vcpi = tu102_sor_dp_vcpi, | |
| 95 | + .audio = gv100_sor_dp_audio, | |
| 96 | + .audio_sym = gv100_sor_dp_audio_sym, | |
| 97 | + .watermark = gv100_sor_dp_watermark, | |
| 98 | + }, | |
| 99 | + .hda = { | |
| 100 | + .hpd = gf119_hda_hpd, | |
| 101 | + .eld = gf119_hda_eld, | |
| 102 | + .device_entry = gv100_hda_device_entry, | |
| 103 | + }, | |
| 104 | +}; | |
| 105 | + | |
| 106 | +static const struct nvkm_ior_func | |
| 107 | +ga102_sor = { | |
| 108 | + .route = { | |
| 109 | + .get = gm200_sor_route_get, | |
| 110 | + .set = gm200_sor_route_set, | |
| 111 | + }, | |
| 112 | + .state = gv100_sor_state, | |
| 113 | + .power = nv50_sor_power, | |
| 114 | + .clock = ga102_sor_clock, | |
| 115 | + .hdmi = { | |
| 116 | + .ctrl = gv100_hdmi_ctrl, | |
| 117 | + .scdc = gm200_hdmi_scdc, | |
| 118 | + }, | |
| 119 | + .dp = { | |
| 120 | + .lanes = { 0, 1, 2, 3 }, | |
| 121 | + .links = ga102_sor_dp_links, | |
| 122 | + .power = g94_sor_dp_power, | |
| 123 | + .pattern = gm107_sor_dp_pattern, | |
| 124 | + .drive = gm200_sor_dp_drive, | |
| 125 | + .vcpi = tu102_sor_dp_vcpi, | |
| 126 | + .audio = gv100_sor_dp_audio, | |
| 127 | + .audio_sym = gv100_sor_dp_audio_sym, | |
| 128 | + .watermark = gv100_sor_dp_watermark, | |
| 129 | + }, | |
| 130 | +}; | |
| 131 | + | |
| 132 | +int | |
| 133 | +ga102_sor_new(struct nvkm_disp *disp, int id) | |
| 134 | +{ | |
| 135 | + struct nvkm_device *device = disp->engine.subdev.device; | |
| 136 | + u32 hda = nvkm_rd32(device, 0x08a15c); | |
| 137 | + if (hda & BIT(id)) | |
| 138 | + return nvkm_ior_new_(&ga102_sor_hda, disp, SOR, id); | |
| 139 | + return nvkm_ior_new_(&ga102_sor, disp, SOR, id); | |
| 140 | +} | |
| @@ -23,7 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | #include <subdev/timer.h> |
| 25 | 25 | |
| 26 | −static void | |
| 26 | +void | |
| 27 | 27 | tu102_sor_dp_vcpi(struct nvkm_ior *sor, int head, |
| 28 | 28 | u8 slot, u8 slot_nr, u16 pbn, u16 aligned) |
| 29 | 29 | { |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <core/gpuobj.h> |
| 29 | 29 | #include <subdev/timer.h> |
| 30 | 30 | |
| 31 | −static int | |
| 31 | +int | |
| 32 | 32 | tu102_disp_init(struct nv50_disp *disp) |
| 33 | 33 | { |
| 34 | 34 | struct nvkm_device *device = disp->base.engine.subdev.device; |
| @@ -75,7 +75,7 @@ shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd) · 74 unmodified lines | ||
| 75 | 75 | nvkm_debug(subdev, "%08x: type %02x, %d bytes\n", |
| 76 | 76 | image.base, image.type, image.size); |
| 77 | 77 | |
| 78 | − if (!shadow_fetch(bios, mthd, image.size)) { | |
| 78 | + if (!shadow_fetch(bios, mthd, image.base + image.size)) { | |
| 79 | 79 | nvkm_debug(subdev, "%08x: fetch failed\n", image.base); |
| 80 | 80 | return 0; |
| 81 | 81 | } |
| @@ -64,6 +64,9 @@ pramin_init(struct nvkm_bios *bios, const char *name) · 63 unmodified lines | ||
| 64 | 64 | return NULL; |
| 65 | 65 | |
| 66 | 66 | /* we can't get the bios image pointer without PDISP */ |
| 67 | + if (device->card_type >= GA100) | |
| 68 | + addr = device->chipset == 0x170; /*XXX: find the fuse reg for this */ | |
| 69 | + else | |
| 67 | 70 | if (device->card_type >= GM100) |
| 68 | 71 | addr = nvkm_rd32(device, 0x021c04); |
| 69 | 72 | else |
| @@ -15,3 +15,4 @@ nvkm-y += nvkm/subdev/devinit/gm107.o · 14 unmodified lines | ||
| 15 | 15 | nvkm-y += nvkm/subdev/devinit/gm200.o |
| 16 | 16 | nvkm-y += nvkm/subdev/devinit/gv100.o |
| 17 | 17 | nvkm-y += nvkm/subdev/devinit/tu102.o |
| 18 | +nvkm-y += nvkm/subdev/devinit/ga100.o | |
| @@ -0,0 +1,76 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "nv50.h" | |
| 23 | + | |
| 24 | +#include <subdev/bios.h> | |
| 25 | +#include <subdev/bios/pll.h> | |
| 26 | +#include <subdev/clk/pll.h> | |
| 27 | + | |
| 28 | +static int | |
| 29 | +ga100_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq) | |
| 30 | +{ | |
| 31 | + struct nvkm_subdev *subdev = &init->subdev; | |
| 32 | + struct nvkm_device *device = subdev->device; | |
| 33 | + struct nvbios_pll info; | |
| 34 | + int head = type - PLL_VPLL0; | |
| 35 | + int N, fN, M, P; | |
| 36 | + int ret; | |
| 37 | + | |
| 38 | + ret = nvbios_pll_parse(device->bios, type, &info); | |
| 39 | + if (ret) | |
| 40 | + return ret; | |
| 41 | + | |
| 42 | + ret = gt215_pll_calc(subdev, &info, freq, &N, &fN, &M, &P); | |
| 43 | + if (ret < 0) | |
| 44 | + return ret; | |
| 45 | + | |
| 46 | + switch (info.type) { | |
| 47 | + case PLL_VPLL0: | |
| 48 | + case PLL_VPLL1: | |
| 49 | + case PLL_VPLL2: | |
| 50 | + case PLL_VPLL3: | |
| 51 | + nvkm_wr32(device, 0x00ef00 + (head * 0x40), 0x02080004); | |
| 52 | + nvkm_wr32(device, 0x00ef18 + (head * 0x40), (N << 16) | fN); | |
| 53 | + nvkm_wr32(device, 0x00ef04 + (head * 0x40), (P << 16) | M); | |
| 54 | + nvkm_wr32(device, 0x00e9c0 + (head * 0x04), 0x00000001); | |
| 55 | + break; | |
| 56 | + default: | |
| 57 | + nvkm_warn(subdev, "%08x/%dKhz unimplemented\n", type, freq); | |
| 58 | + ret = -EINVAL; | |
| 59 | + break; | |
| 60 | + } | |
| 61 | + | |
| 62 | + return ret; | |
| 63 | +} | |
| 64 | + | |
| 65 | +static const struct nvkm_devinit_func | |
| 66 | +ga100_devinit = { | |
| 67 | + .init = nv50_devinit_init, | |
| 68 | + .post = tu102_devinit_post, | |
| 69 | + .pll_set = ga100_devinit_pll_set, | |
| 70 | +}; | |
| 71 | + | |
| 72 | +int | |
| 73 | +ga100_devinit_new(struct nvkm_device *device, int index, struct nvkm_devinit **pinit) | |
| 74 | +{ | |
| 75 | + return nv50_devinit_new_(&ga100_devinit, device, index, pinit); | |
| 76 | +} | |
| @@ -19,4 +19,5 @@ void nvkm_devinit_ctor(const struct nvkm_devinit_func *, struct nvkm_device *, · 18 unmodified lines | ||
| 19 | 19 | int index, struct nvkm_devinit *); |
| 20 | 20 | |
| 21 | 21 | int nv04_devinit_post(struct nvkm_devinit *, bool); |
| 22 | +int tu102_devinit_post(struct nvkm_devinit *, bool); | |
| 22 | 23 | #endif |
| @@ -65,7 +65,7 @@ tu102_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq) · 64 unmodified lines | ||
| 65 | 65 | return ret; |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | −static int | |
| 68 | +int | |
| 69 | 69 | tu102_devinit_post(struct nvkm_devinit *base, bool post) |
| 70 | 70 | { |
| 71 | 71 | struct nv50_devinit *init = nv50_devinit(base); |
| @@ -32,6 +32,8 @@ nvkm-y += nvkm/subdev/fb/gp100.o · 31 unmodified lines | ||
| 32 | 32 | nvkm-y += nvkm/subdev/fb/gp102.o |
| 33 | 33 | nvkm-y += nvkm/subdev/fb/gp10b.o |
| 34 | 34 | nvkm-y += nvkm/subdev/fb/gv100.o |
| 35 | +nvkm-y += nvkm/subdev/fb/ga100.o | |
| 36 | +nvkm-y += nvkm/subdev/fb/ga102.o | |
| 35 | 37 | |
| 36 | 38 | nvkm-y += nvkm/subdev/fb/ram.o |
| 37 | 39 | nvkm-y += nvkm/subdev/fb/ramnv04.o |
| @@ -52,6 +54,7 @@ nvkm-y += nvkm/subdev/fb/ramgk104.o · 14 unmodified lines | ||
| 52 | 54 | nvkm-y += nvkm/subdev/fb/ramgm107.o |
| 53 | 55 | nvkm-y += nvkm/subdev/fb/ramgm200.o |
| 54 | 56 | nvkm-y += nvkm/subdev/fb/ramgp100.o |
| 57 | +nvkm-y += nvkm/subdev/fb/ramga102.o | |
| 55 | 58 | nvkm-y += nvkm/subdev/fb/sddr2.o |
| 56 | 59 | nvkm-y += nvkm/subdev/fb/sddr3.o |
| 57 | 60 | nvkm-y += nvkm/subdev/fb/gddr3.o |
| @@ -0,0 +1,40 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "gf100.h" | |
| 23 | +#include "ram.h" | |
| 24 | + | |
| 25 | +static const struct nvkm_fb_func | |
| 26 | +ga100_fb = { | |
| 27 | + .dtor = gf100_fb_dtor, | |
| 28 | + .oneinit = gf100_fb_oneinit, | |
| 29 | + .init = gp100_fb_init, | |
| 30 | + .init_page = gv100_fb_init_page, | |
| 31 | + .init_unkn = gp100_fb_init_unkn, | |
| 32 | + .ram_new = gp100_ram_new, | |
| 33 | + .default_bigpage = 16, | |
| 34 | +}; | |
| 35 | + | |
| 36 | +int | |
| 37 | +ga100_fb_new(struct nvkm_device *device, int index, struct nvkm_fb **pfb) | |
| 38 | +{ | |
| 39 | + return gp102_fb_new_(&ga100_fb, device, index, pfb); | |
| 40 | +} | |
| @@ -0,0 +1,40 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "gf100.h" | |
| 23 | +#include "ram.h" | |
| 24 | + | |
| 25 | +static const struct nvkm_fb_func | |
| 26 | +ga102_fb = { | |
| 27 | + .dtor = gf100_fb_dtor, | |
| 28 | + .oneinit = gf100_fb_oneinit, | |
| 29 | + .init = gp100_fb_init, | |
| 30 | + .init_page = gv100_fb_init_page, | |
| 31 | + .init_unkn = gp100_fb_init_unkn, | |
| 32 | + .ram_new = ga102_ram_new, | |
| 33 | + .default_bigpage = 16, | |
| 34 | +}; | |
| 35 | + | |
| 36 | +int | |
| 37 | +ga102_fb_new(struct nvkm_device *device, int index, struct nvkm_fb **pfb) | |
| 38 | +{ | |
| 39 | + return gp102_fb_new_(&ga102_fb, device, index, pfb); | |
| 40 | +} | |
| @@ -22,7 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include "gf100.h" |
| 23 | 23 | #include "ram.h" |
| 24 | 24 | |
| 25 | −static int | |
| 25 | +int | |
| 26 | 26 | gv100_fb_init_page(struct nvkm_fb *fb) |
| 27 | 27 | { |
| 28 | 28 | return (fb->page == 16) ? 0 : -EINVAL; |
| @@ -82,4 +82,6 @@ int gp102_fb_new_(const struct nvkm_fb_func *, struct nvkm_device *, int, · 81 unmodified lines | ||
| 82 | 82 | struct nvkm_fb **); |
| 83 | 83 | bool gp102_fb_vpr_scrub_required(struct nvkm_fb *); |
| 84 | 84 | int gp102_fb_vpr_scrub(struct nvkm_fb *); |
| 85 | + | |
| 86 | +int gv100_fb_init_page(struct nvkm_fb *); | |
| 85 | 87 | #endif |
| @@ -70,4 +70,5 @@ int gk104_ram_new(struct nvkm_fb *, struct nvkm_ram **); · 69 unmodified lines | ||
| 70 | 70 | int gm107_ram_new(struct nvkm_fb *, struct nvkm_ram **); |
| 71 | 71 | int gm200_ram_new(struct nvkm_fb *, struct nvkm_ram **); |
| 72 | 72 | int gp100_ram_new(struct nvkm_fb *, struct nvkm_ram **); |
| 73 | +int ga102_ram_new(struct nvkm_fb *, struct nvkm_ram **); | |
| 73 | 74 | #endif |
| @@ -0,0 +1,40 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "ram.h" | |
| 23 | + | |
| 24 | +#include <subdev/bios.h> | |
| 25 | +#include <subdev/bios/init.h> | |
| 26 | +#include <subdev/bios/rammap.h> | |
| 27 | + | |
| 28 | +static const struct nvkm_ram_func | |
| 29 | +ga102_ram = { | |
| 30 | +}; | |
| 31 | + | |
| 32 | +int | |
| 33 | +ga102_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) | |
| 34 | +{ | |
| 35 | + struct nvkm_device *device = fb->subdev.device; | |
| 36 | + enum nvkm_ram_type type = nvkm_fb_bios_memtype(device->bios); | |
| 37 | + u32 size = nvkm_rd32(device, 0x1183a4); | |
| 38 | + | |
| 39 | + return nvkm_ram_new_(&ga102_ram, fb, type, (u64)size << 20, pram); | |
| 40 | +} | |
| @@ -5,3 +5,4 @@ nvkm-y += nvkm/subdev/gpio/nv50.o · 4 unmodified lines | ||
| 5 | 5 | nvkm-y += nvkm/subdev/gpio/g94.o |
| 6 | 6 | nvkm-y += nvkm/subdev/gpio/gf119.o |
| 7 | 7 | nvkm-y += nvkm/subdev/gpio/gk104.o |
| 8 | +nvkm-y += nvkm/subdev/gpio/ga102.o | |
| @@ -0,0 +1,118 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "priv.h" | |
| 23 | + | |
| 24 | +static void | |
| 25 | +ga102_gpio_reset(struct nvkm_gpio *gpio, u8 match) | |
| 26 | +{ | |
| 27 | + struct nvkm_device *device = gpio->subdev.device; | |
| 28 | + struct nvkm_bios *bios = device->bios; | |
| 29 | + u8 ver, len; | |
| 30 | + u16 entry; | |
| 31 | + int ent = -1; | |
| 32 | + | |
| 33 | + while ((entry = dcb_gpio_entry(bios, 0, ++ent, &ver, &len))) { | |
| 34 | + u32 data = nvbios_rd32(bios, entry); | |
| 35 | + u8 line = (data & 0x0000003f); | |
| 36 | + u8 defs = !!(data & 0x00000080); | |
| 37 | + u8 func = (data & 0x0000ff00) >> 8; | |
| 38 | + u8 unk0 = (data & 0x00ff0000) >> 16; | |
| 39 | + u8 unk1 = (data & 0x1f000000) >> 24; | |
| 40 | + | |
| 41 | + if ( func == DCB_GPIO_UNUSED || | |
| 42 | + (match != DCB_GPIO_UNUSED && match != func)) | |
| 43 | + continue; | |
| 44 | + | |
| 45 | + nvkm_gpio_set(gpio, 0, func, line, defs); | |
| 46 | + | |
| 47 | + nvkm_mask(device, 0x021200 + (line * 4), 0xff, unk0); | |
| 48 | + if (unk1--) | |
| 49 | + nvkm_mask(device, 0x00d740 + (unk1 * 4), 0xff, line); | |
| 50 | + } | |
| 51 | +} | |
| 52 | + | |
| 53 | +static int | |
| 54 | +ga102_gpio_drive(struct nvkm_gpio *gpio, int line, int dir, int out) | |
| 55 | +{ | |
| 56 | + struct nvkm_device *device = gpio->subdev.device; | |
| 57 | + u32 data = ((dir ^ 1) << 13) | (out << 12); | |
| 58 | + nvkm_mask(device, 0x021200 + (line * 4), 0x00003000, data); | |
| 59 | + nvkm_mask(device, 0x00d604, 0x00000001, 0x00000001); /* update? */ | |
| 60 | + return 0; | |
| 61 | +} | |
| 62 | + | |
| 63 | +static int | |
| 64 | +ga102_gpio_sense(struct nvkm_gpio *gpio, int line) | |
| 65 | +{ | |
| 66 | + struct nvkm_device *device = gpio->subdev.device; | |
| 67 | + return !!(nvkm_rd32(device, 0x021200 + (line * 4)) & 0x00004000); | |
| 68 | +} | |
| 69 | + | |
| 70 | +static void | |
| 71 | +ga102_gpio_intr_stat(struct nvkm_gpio *gpio, u32 *hi, u32 *lo) | |
| 72 | +{ | |
| 73 | + struct nvkm_device *device = gpio->subdev.device; | |
| 74 | + u32 intr0 = nvkm_rd32(device, 0x021640); | |
| 75 | + u32 intr1 = nvkm_rd32(device, 0x02164c); | |
| 76 | + u32 stat0 = nvkm_rd32(device, 0x021648) & intr0; | |
| 77 | + u32 stat1 = nvkm_rd32(device, 0x021654) & intr1; | |
| 78 | + *lo = (stat1 & 0xffff0000) | (stat0 >> 16); | |
| 79 | + *hi = (stat1 << 16) | (stat0 & 0x0000ffff); | |
| 80 | + nvkm_wr32(device, 0x021640, intr0); | |
| 81 | + nvkm_wr32(device, 0x02164c, intr1); | |
| 82 | +} | |
| 83 | + | |
| 84 | +static void | |
| 85 | +ga102_gpio_intr_mask(struct nvkm_gpio *gpio, u32 type, u32 mask, u32 data) | |
| 86 | +{ | |
| 87 | + struct nvkm_device *device = gpio->subdev.device; | |
| 88 | + u32 inte0 = nvkm_rd32(device, 0x021648); | |
| 89 | + u32 inte1 = nvkm_rd32(device, 0x021654); | |
| 90 | + if (type & NVKM_GPIO_LO) | |
| 91 | + inte0 = (inte0 & ~(mask << 16)) | (data << 16); | |
| 92 | + if (type & NVKM_GPIO_HI) | |
| 93 | + inte0 = (inte0 & ~(mask & 0xffff)) | (data & 0xffff); | |
| 94 | + mask >>= 16; | |
| 95 | + data >>= 16; | |
| 96 | + if (type & NVKM_GPIO_LO) | |
| 97 | + inte1 = (inte1 & ~(mask << 16)) | (data << 16); | |
| 98 | + if (type & NVKM_GPIO_HI) | |
| 99 | + inte1 = (inte1 & ~mask) | data; | |
| 100 | + nvkm_wr32(device, 0x021648, inte0); | |
| 101 | + nvkm_wr32(device, 0x021654, inte1); | |
| 102 | +} | |
| 103 | + | |
| 104 | +static const struct nvkm_gpio_func | |
| 105 | +ga102_gpio = { | |
| 106 | + .lines = 32, | |
| 107 | + .intr_stat = ga102_gpio_intr_stat, | |
| 108 | + .intr_mask = ga102_gpio_intr_mask, | |
| 109 | + .drive = ga102_gpio_drive, | |
| 110 | + .sense = ga102_gpio_sense, | |
| 111 | + .reset = ga102_gpio_reset, | |
| 112 | +}; | |
| 113 | + | |
| 114 | +int | |
| 115 | +ga102_gpio_new(struct nvkm_device *device, int index, struct nvkm_gpio **pgpio) | |
| 116 | +{ | |
| 117 | + return nvkm_gpio_new_(&ga102_gpio, device, index, pgpio); | |
| 118 | +} | |
| @@ -7,6 +7,7 @@ nvkm-y += nvkm/subdev/i2c/g94.o · 6 unmodified lines | ||
| 7 | 7 | nvkm-y += nvkm/subdev/i2c/gf117.o |
| 8 | 8 | nvkm-y += nvkm/subdev/i2c/gf119.o |
| 9 | 9 | nvkm-y += nvkm/subdev/i2c/gk104.o |
| 10 | +nvkm-y += nvkm/subdev/i2c/gk110.o | |
| 10 | 11 | nvkm-y += nvkm/subdev/i2c/gm200.o |
| 11 | 12 | |
| 12 | 13 | nvkm-y += nvkm/subdev/i2c/pad.o |
| @@ -3,6 +3,13 @@ · 2 unmodified lines | ||
| 3 | 3 | #define __NVKM_I2C_AUX_H__ |
| 4 | 4 | #include "pad.h" |
| 5 | 5 | |
| 6 | +static inline void | |
| 7 | +nvkm_i2c_aux_autodpcd(struct nvkm_i2c *i2c, int aux, bool enable) | |
| 8 | +{ | |
| 9 | + if (i2c->func->aux_autodpcd) | |
| 10 | + i2c->func->aux_autodpcd(i2c, aux, false); | |
| 11 | +} | |
| 12 | + | |
| 6 | 13 | struct nvkm_i2c_aux_func { |
| 7 | 14 | bool address_only; |
| 8 | 15 | int (*xfer)(struct nvkm_i2c_aux *, bool retry, u8 type, |
| @@ -77,7 +77,8 @@ g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 76 unmodified lines | ||
| 77 | 77 | u8 type, u32 addr, u8 *data, u8 *size) |
| 78 | 78 | { |
| 79 | 79 | struct g94_i2c_aux *aux = g94_i2c_aux(obj); |
| 80 | − struct nvkm_device *device = aux->base.pad->i2c->subdev.device; | |
| 80 | + struct nvkm_i2c *i2c = aux->base.pad->i2c; | |
| 81 | + struct nvkm_device *device = i2c->subdev.device; | |
| 81 | 82 | const u32 base = aux->ch * 0x50; |
| 82 | 83 | u32 ctrl, stat, timeout, retries = 0; |
| 83 | 84 | u32 xbuf[4] = {}; |
| @@ -96,6 +97,8 @@ g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 12 unmodified lines | ||
| 96 | 97 | goto out; |
| 97 | 98 | } |
| 98 | 99 | |
| 100 | + nvkm_i2c_aux_autodpcd(i2c, aux->ch, false); | |
| 101 | + | |
| 99 | 102 | if (!(type & 1)) { |
| 100 | 103 | memcpy(xbuf, data, *size); |
| 101 | 104 | for (i = 0; i < 16; i += 4) { |
| @@ -128,7 +131,7 @@ g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 26 unmodified lines | ||
| 128 | 131 | if (!timeout--) { |
| 129 | 132 | AUX_ERR(&aux->base, "timeout %08x", ctrl); |
| 130 | 133 | ret = -EIO; |
| 131 | − goto out; | |
| 134 | + goto out_err; | |
| 132 | 135 | } |
| 133 | 136 | } while (ctrl & 0x00010000); |
| 134 | 137 | ret = 0; |
| @@ -154,7 +157,8 @@ g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 19 unmodified lines | ||
| 154 | 157 | memcpy(data, xbuf, *size); |
| 155 | 158 | *size = stat & 0x0000001f; |
| 156 | 159 | } |
| 157 | − | |
| 160 | +out_err: | |
| 161 | + nvkm_i2c_aux_autodpcd(i2c, aux->ch, true); | |
| 158 | 162 | out: |
| 159 | 163 | g94_i2c_aux_fini(aux); |
| 160 | 164 | return ret < 0 ? ret : (stat & 0x000f0000) >> 16; |
| @@ -33,7 +33,7 @@ static void · 32 unmodified lines | ||
| 33 | 33 | gm200_i2c_aux_fini(struct gm200_i2c_aux *aux) |
| 34 | 34 | { |
| 35 | 35 | struct nvkm_device *device = aux->base.pad->i2c->subdev.device; |
| 36 | − nvkm_mask(device, 0x00d954 + (aux->ch * 0x50), 0x00310000, 0x00000000); | |
| 36 | + nvkm_mask(device, 0x00d954 + (aux->ch * 0x50), 0x00710000, 0x00000000); | |
| 37 | 37 | } |
| 38 | 38 | |
| 39 | 39 | static int |
| @@ -54,10 +54,10 @@ gm200_i2c_aux_init(struct gm200_i2c_aux *aux) · 14 unmodified lines | ||
| 54 | 54 | AUX_ERR(&aux->base, "begin idle timeout %08x", ctrl); |
| 55 | 55 | return -EBUSY; |
| 56 | 56 | } |
| 57 | − } while (ctrl & 0x03010000); | |
| 57 | + } while (ctrl & 0x07010000); | |
| 58 | 58 | |
| 59 | 59 | /* set some magic, and wait up to 1ms for it to appear */ |
| 60 | − nvkm_mask(device, 0x00d954 + (aux->ch * 0x50), 0x00300000, ureq); | |
| 60 | + nvkm_mask(device, 0x00d954 + (aux->ch * 0x50), 0x00700000, ureq); | |
| 61 | 61 | timeout = 1000; |
| 62 | 62 | do { |
| 63 | 63 | ctrl = nvkm_rd32(device, 0x00d954 + (aux->ch * 0x50)); |
| @@ -67,7 +67,7 @@ gm200_i2c_aux_init(struct gm200_i2c_aux *aux) · 3 unmodified lines | ||
| 67 | 67 | gm200_i2c_aux_fini(aux); |
| 68 | 68 | return -EBUSY; |
| 69 | 69 | } |
| 70 | − } while ((ctrl & 0x03000000) != urep); | |
| 70 | + } while ((ctrl & 0x07000000) != urep); | |
| 71 | 71 | |
| 72 | 72 | return 0; |
| 73 | 73 | } |
| @@ -77,7 +77,8 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 3 unmodified lines | ||
| 77 | 77 | u8 type, u32 addr, u8 *data, u8 *size) |
| 78 | 78 | { |
| 79 | 79 | struct gm200_i2c_aux *aux = gm200_i2c_aux(obj); |
| 80 | − struct nvkm_device *device = aux->base.pad->i2c->subdev.device; | |
| 80 | + struct nvkm_i2c *i2c = aux->base.pad->i2c; | |
| 81 | + struct nvkm_device *device = i2c->subdev.device; | |
| 81 | 82 | const u32 base = aux->ch * 0x50; |
| 82 | 83 | u32 ctrl, stat, timeout, retries = 0; |
| 83 | 84 | u32 xbuf[4] = {}; |
| @@ -96,6 +97,8 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 12 unmodified lines | ||
| 96 | 97 | goto out; |
| 97 | 98 | } |
| 98 | 99 | |
| 100 | + nvkm_i2c_aux_autodpcd(i2c, aux->ch, false); | |
| 101 | + | |
| 99 | 102 | if (!(type & 1)) { |
| 100 | 103 | memcpy(xbuf, data, *size); |
| 101 | 104 | for (i = 0; i < 16; i += 4) { |
| @@ -128,7 +131,7 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 26 unmodified lines | ||
| 128 | 131 | if (!timeout--) { |
| 129 | 132 | AUX_ERR(&aux->base, "timeout %08x", ctrl); |
| 130 | 133 | ret = -EIO; |
| 131 | − goto out; | |
| 134 | + goto out_err; | |
| 132 | 135 | } |
| 133 | 136 | } while (ctrl & 0x00010000); |
| 134 | 137 | ret = 0; |
| @@ -155,6 +158,8 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 20 unmodified lines | ||
| 155 | 158 | *size = stat & 0x0000001f; |
| 156 | 159 | } |
| 157 | 160 | |
| 161 | +out_err: | |
| 162 | + nvkm_i2c_aux_autodpcd(i2c, aux->ch, true); | |
| 158 | 163 | out: |
| 159 | 164 | gm200_i2c_aux_fini(aux); |
| 160 | 165 | return ret < 0 ? ret : (stat & 0x000f0000) >> 16; |
| @@ -0,0 +1,45 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "priv.h" | |
| 23 | +#include "pad.h" | |
| 24 | + | |
| 25 | +static void | |
| 26 | +gk110_aux_autodpcd(struct nvkm_i2c *i2c, int aux, bool enable) | |
| 27 | +{ | |
| 28 | + nvkm_mask(i2c->subdev.device, 0x00e4f8 + (aux * 0x50), 0x00010000, enable << 16); | |
| 29 | +} | |
| 30 | + | |
| 31 | +static const struct nvkm_i2c_func | |
| 32 | +gk110_i2c = { | |
| 33 | + .pad_x_new = gf119_i2c_pad_x_new, | |
| 34 | + .pad_s_new = gf119_i2c_pad_s_new, | |
| 35 | + .aux = 4, | |
| 36 | + .aux_stat = gk104_aux_stat, | |
| 37 | + .aux_mask = gk104_aux_mask, | |
| 38 | + .aux_autodpcd = gk110_aux_autodpcd, | |
| 39 | +}; | |
| 40 | + | |
| 41 | +int | |
| 42 | +gk110_i2c_new(struct nvkm_device *device, int index, struct nvkm_i2c **pi2c) | |
| 43 | +{ | |
| 44 | + return nvkm_i2c_new_(&gk110_i2c, device, index, pi2c); | |
| 45 | +} | |
| @@ -24,6 +24,12 @@ · 23 unmodified lines | ||
| 24 | 24 | #include "priv.h" |
| 25 | 25 | #include "pad.h" |
| 26 | 26 | |
| 27 | +static void | |
| 28 | +gm200_aux_autodpcd(struct nvkm_i2c *i2c, int aux, bool enable) | |
| 29 | +{ | |
| 30 | + nvkm_mask(i2c->subdev.device, 0x00d968 + (aux * 0x50), 0x00010000, enable << 16); | |
| 31 | +} | |
| 32 | + | |
| 27 | 33 | static const struct nvkm_i2c_func |
| 28 | 34 | gm200_i2c = { |
| 29 | 35 | .pad_x_new = gf119_i2c_pad_x_new, |
| @@ -31,6 +37,7 @@ gm200_i2c = { · 1 unmodified line | ||
| 31 | 37 | .aux = 8, |
| 32 | 38 | .aux_stat = gk104_aux_stat, |
| 33 | 39 | .aux_mask = gk104_aux_mask, |
| 40 | + .aux_autodpcd = gm200_aux_autodpcd, | |
| 34 | 41 | }; |
| 35 | 42 | |
| 36 | 43 | int |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | /* SPDX-License-Identifier: MIT */ |
| 2 | 2 | #ifndef __NVKM_I2C_PAD_H__ |
| 3 | 3 | #define __NVKM_I2C_PAD_H__ |
| 4 | −#include <subdev/i2c.h> | |
| 4 | +#include "priv.h" | |
| 5 | 5 | |
| 6 | 6 | struct nvkm_i2c_pad { |
| 7 | 7 | const struct nvkm_i2c_pad_func *func; |
| @@ -23,6 +23,10 @@ struct nvkm_i2c_func { · 22 unmodified lines | ||
| 23 | 23 | /* mask on/off interrupt types for a given set of auxch |
| 24 | 24 | */ |
| 25 | 25 | void (*aux_mask)(struct nvkm_i2c *, u32, u32, u32); |
| 26 | + | |
| 27 | + /* enable/disable HW-initiated DPCD reads | |
| 28 | + */ | |
| 29 | + void (*aux_autodpcd)(struct nvkm_i2c *, int aux, bool enable); | |
| 26 | 30 | }; |
| 27 | 31 | |
| 28 | 32 | void g94_aux_stat(struct nvkm_i2c *, u32 *, u32 *, u32 *, u32 *); |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | * Authors: Ben Skeggs |
| 23 | 23 | */ |
| 24 | 24 | #include "priv.h" |
| 25 | +#include <subdev/timer.h> | |
| 25 | 26 | |
| 26 | 27 | static void |
| 27 | 28 | gf100_ibus_intr_hub(struct nvkm_subdev *ibus, int i) |
| @@ -31,7 +32,6 @@ gf100_ibus_intr_hub(struct nvkm_subdev *ibus, int i) · 3 unmodified lines | ||
| 31 | 32 | u32 data = nvkm_rd32(device, 0x122124 + (i * 0x0400)); |
| 32 | 33 | u32 stat = nvkm_rd32(device, 0x122128 + (i * 0x0400)); |
| 33 | 34 | nvkm_debug(ibus, "HUB%d: %06x %08x (%08x)\n", i, addr, data, stat); |
| 34 | − nvkm_mask(device, 0x122128 + (i * 0x0400), 0x00000200, 0x00000000); | |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | 37 | static void |
| @@ -42,7 +42,6 @@ gf100_ibus_intr_rop(struct nvkm_subdev *ibus, int i) · 4 unmodified lines | ||
| 42 | 42 | u32 data = nvkm_rd32(device, 0x124124 + (i * 0x0400)); |
| 43 | 43 | u32 stat = nvkm_rd32(device, 0x124128 + (i * 0x0400)); |
| 44 | 44 | nvkm_debug(ibus, "ROP%d: %06x %08x (%08x)\n", i, addr, data, stat); |
| 45 | − nvkm_mask(device, 0x124128 + (i * 0x0400), 0x00000200, 0x00000000); | |
| 46 | 45 | } |
| 47 | 46 | |
| 48 | 47 | static void |
| @@ -53,7 +52,6 @@ gf100_ibus_intr_gpc(struct nvkm_subdev *ibus, int i) · 4 unmodified lines | ||
| 53 | 52 | u32 data = nvkm_rd32(device, 0x128124 + (i * 0x0400)); |
| 54 | 53 | u32 stat = nvkm_rd32(device, 0x128128 + (i * 0x0400)); |
| 55 | 54 | nvkm_debug(ibus, "GPC%d: %06x %08x (%08x)\n", i, addr, data, stat); |
| 56 | − nvkm_mask(device, 0x128128 + (i * 0x0400), 0x00000200, 0x00000000); | |
| 57 | 55 | } |
| 58 | 56 | |
| 59 | 57 | void |
| @@ -90,6 +88,12 @@ gf100_ibus_intr(struct nvkm_subdev *ibus) · 30 unmodified lines | ||
| 90 | 88 | intr1 &= ~stat; |
| 91 | 89 | } |
| 92 | 90 | } |
| 91 | + | |
| 92 | + nvkm_mask(device, 0x121c4c, 0x0000003f, 0x00000002); | |
| 93 | + nvkm_msec(device, 2000, | |
| 94 | + if (!(nvkm_rd32(device, 0x121c4c) & 0x0000003f)) | |
| 95 | + break; | |
| 96 | + ); | |
| 93 | 97 | } |
| 94 | 98 | |
| 95 | 99 | static int |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | * Authors: Ben Skeggs |
| 23 | 23 | */ |
| 24 | 24 | #include "priv.h" |
| 25 | +#include <subdev/timer.h> | |
| 25 | 26 | |
| 26 | 27 | static void |
| 27 | 28 | gk104_ibus_intr_hub(struct nvkm_subdev *ibus, int i) |
| @@ -31,7 +32,6 @@ gk104_ibus_intr_hub(struct nvkm_subdev *ibus, int i) · 3 unmodified lines | ||
| 31 | 32 | u32 data = nvkm_rd32(device, 0x122124 + (i * 0x0800)); |
| 32 | 33 | u32 stat = nvkm_rd32(device, 0x122128 + (i * 0x0800)); |
| 33 | 34 | nvkm_debug(ibus, "HUB%d: %06x %08x (%08x)\n", i, addr, data, stat); |
| 34 | − nvkm_mask(device, 0x122128 + (i * 0x0800), 0x00000200, 0x00000000); | |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | 37 | static void |
| @@ -42,7 +42,6 @@ gk104_ibus_intr_rop(struct nvkm_subdev *ibus, int i) · 4 unmodified lines | ||
| 42 | 42 | u32 data = nvkm_rd32(device, 0x124124 + (i * 0x0800)); |
| 43 | 43 | u32 stat = nvkm_rd32(device, 0x124128 + (i * 0x0800)); |
| 44 | 44 | nvkm_debug(ibus, "ROP%d: %06x %08x (%08x)\n", i, addr, data, stat); |
| 45 | − nvkm_mask(device, 0x124128 + (i * 0x0800), 0x00000200, 0x00000000); | |
| 46 | 45 | } |
| 47 | 46 | |
| 48 | 47 | static void |
| @@ -53,7 +52,6 @@ gk104_ibus_intr_gpc(struct nvkm_subdev *ibus, int i) · 4 unmodified lines | ||
| 53 | 52 | u32 data = nvkm_rd32(device, 0x128124 + (i * 0x0800)); |
| 54 | 53 | u32 stat = nvkm_rd32(device, 0x128128 + (i * 0x0800)); |
| 55 | 54 | nvkm_debug(ibus, "GPC%d: %06x %08x (%08x)\n", i, addr, data, stat); |
| 56 | − nvkm_mask(device, 0x128128 + (i * 0x0800), 0x00000200, 0x00000000); | |
| 57 | 55 | } |
| 58 | 56 | |
| 59 | 57 | void |
| @@ -90,6 +88,12 @@ gk104_ibus_intr(struct nvkm_subdev *ibus) · 30 unmodified lines | ||
| 90 | 88 | intr1 &= ~stat; |
| 91 | 89 | } |
| 92 | 90 | } |
| 91 | + | |
| 92 | + nvkm_mask(device, 0x12004c, 0x0000003f, 0x00000002); | |
| 93 | + nvkm_msec(device, 2000, | |
| 94 | + if (!(nvkm_rd32(device, 0x12004c) & 0x0000003f)) | |
| 95 | + break; | |
| 96 | + ); | |
| 93 | 97 | } |
| 94 | 98 | |
| 95 | 99 | static int |
| @@ -14,3 +14,4 @@ nvkm-y += nvkm/subdev/mc/gk20a.o · 13 unmodified lines | ||
| 14 | 14 | nvkm-y += nvkm/subdev/mc/gp100.o |
| 15 | 15 | nvkm-y += nvkm/subdev/mc/gp10b.o |
| 16 | 16 | nvkm-y += nvkm/subdev/mc/tu102.o |
| 17 | +nvkm-y += nvkm/subdev/mc/ga100.o | |
| @@ -0,0 +1,74 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2021 Red Hat Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + */ | |
| 22 | +#include "priv.h" | |
| 23 | + | |
| 24 | +static void | |
| 25 | +ga100_mc_intr_unarm(struct nvkm_mc *mc) | |
| 26 | +{ | |
| 27 | + nvkm_wr32(mc->subdev.device, 0xb81610, 0x00000004); | |
| 28 | +} | |
| 29 | + | |
| 30 | +static void | |
| 31 | +ga100_mc_intr_rearm(struct nvkm_mc *mc) | |
| 32 | +{ | |
| 33 | + nvkm_wr32(mc->subdev.device, 0xb81608, 0x00000004); | |
| 34 | +} | |
| 35 | + | |
| 36 | +static void | |
| 37 | +ga100_mc_intr_mask(struct nvkm_mc *mc, u32 mask, u32 intr) | |
| 38 | +{ | |
| 39 | + nvkm_wr32(mc->subdev.device, 0xb81210, mask & intr ); | |
| 40 | + nvkm_wr32(mc->subdev.device, 0xb81410, mask & ~(mask & intr)); | |
| 41 | +} | |
| 42 | + | |
| 43 | +static u32 | |
| 44 | +ga100_mc_intr_stat(struct nvkm_mc *mc) | |
| 45 | +{ | |
| 46 | + u32 intr_top = nvkm_rd32(mc->subdev.device, 0xb81600), intr = 0x00000000; | |
| 47 | + if (intr_top & 0x00000004) | |
| 48 | + intr = nvkm_mask(mc->subdev.device, 0xb81010, 0x00000000, 0x00000000); | |
| 49 | + return intr; | |
| 50 | +} | |
| 51 | + | |
| 52 | +static void | |
| 53 | +ga100_mc_init(struct nvkm_mc *mc) | |
| 54 | +{ | |
| 55 | + nv50_mc_init(mc); | |
| 56 | + nvkm_wr32(mc->subdev.device, 0xb81210, 0xffffffff); | |
| 57 | +} | |
| 58 | + | |
| 59 | +static const struct nvkm_mc_func | |
| 60 | +ga100_mc = { | |
| 61 | + .init = ga100_mc_init, | |
| 62 | + .intr = gp100_mc_intr, | |
| 63 | + .intr_unarm = ga100_mc_intr_unarm, | |
| 64 | + .intr_rearm = ga100_mc_intr_rearm, | |
| 65 | + .intr_mask = ga100_mc_intr_mask, | |
| 66 | + .intr_stat = ga100_mc_intr_stat, | |
| 67 | + .reset = gk104_mc_reset, | |
| 68 | +}; | |
| 69 | + | |
| 70 | +int | |
| 71 | +ga100_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc) | |
| 72 | +{ | |
| 73 | + return nvkm_mc_new_(&ga100_mc, device, index, pmc); | |
| 74 | +} | |
| @@ -316,9 +316,9 @@ nvkm_mmu_vram(struct nvkm_mmu *mmu) · 315 unmodified lines | ||
| 316 | 316 | { |
| 317 | 317 | struct nvkm_device *device = mmu->subdev.device; |
| 318 | 318 | struct nvkm_mm *mm = &device->fb->ram->vram; |
| 319 | − const u32 sizeN = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NORMAL); | |
| 320 | − const u32 sizeU = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NOMAP); | |
| 321 | − const u32 sizeM = nvkm_mm_heap_size(mm, NVKM_RAM_MM_MIXED); | |
| 319 | + const u64 sizeN = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NORMAL); | |
| 320 | + const u64 sizeU = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NOMAP); | |
| 321 | + const u64 sizeM = nvkm_mm_heap_size(mm, NVKM_RAM_MM_MIXED); | |
| 322 | 322 | u8 type = NVKM_MEM_KIND * !!mmu->func->kind; |
| 323 | 323 | u8 heap = NVKM_MEM_VRAM; |
| 324 | 324 | int heapM, heapN, heapU; |
| @@ -730,9 +730,6 @@ int radeon_ttm_init(struct radeon_device *rdev) · 729 unmodified lines | ||
| 730 | 730 | } |
| 731 | 731 | rdev->mman.initialized = true; |
| 732 | 732 | |
| 733 | − ttm_pool_init(&rdev->mman.bdev.pool, rdev->dev, rdev->need_swiotlb, | |
| 734 | − dma_addressing_limited(&rdev->pdev->dev)); | |
| 735 | − | |
| 736 | 733 | r = radeon_ttm_init_vram(rdev); |
| 737 | 734 | if (r) { |
| 738 | 735 | DRM_ERROR("Failed initializing VRAM heap.\n"); |
| @@ -66,7 +66,7 @@ static struct ttm_pool_type global_uncached[MAX_ORDER]; · 65 unmodified lines | ||
| 66 | 66 | static struct ttm_pool_type global_dma32_write_combined[MAX_ORDER]; |
| 67 | 67 | static struct ttm_pool_type global_dma32_uncached[MAX_ORDER]; |
| 68 | 68 | |
| 69 | −static spinlock_t shrinker_lock; | |
| 69 | +static struct mutex shrinker_lock; | |
| 70 | 70 | static struct list_head shrinker_list; |
| 71 | 71 | static struct shrinker mm_shrinker; |
| 72 | 72 | |
| @@ -190,7 +190,7 @@ static int ttm_pool_map(struct ttm_pool *pool, unsigned int order, · 117 unmodified lines | ||
| 190 | 190 | size_t size = (1ULL << order) * PAGE_SIZE; |
| 191 | 191 | |
| 192 | 192 | addr = dma_map_page(pool->dev, p, 0, size, DMA_BIDIRECTIONAL); |
| 193 | − if (dma_mapping_error(pool->dev, **dma_addr)) | |
| 193 | + if (dma_mapping_error(pool->dev, addr)) | |
| 194 | 194 | return -EFAULT; |
| 195 | 195 | } |
| 196 | 196 | |
| @@ -249,9 +249,9 @@ static void ttm_pool_type_init(struct ttm_pool_type *pt, struct ttm_pool *pool, · 52 unmodified lines | ||
| 249 | 249 | spin_lock_init(&pt->lock); |
| 250 | 250 | INIT_LIST_HEAD(&pt->pages); |
| 251 | 251 | |
| 252 | − spin_lock(&shrinker_lock); | |
| 252 | + mutex_lock(&shrinker_lock); | |
| 253 | 253 | list_add_tail(&pt->shrinker_list, &shrinker_list); |
| 254 | − spin_unlock(&shrinker_lock); | |
| 254 | + mutex_unlock(&shrinker_lock); | |
| 255 | 255 | } |
| 256 | 256 | |
| 257 | 257 | /* Remove a pool_type from the global shrinker list and free all pages */ |
| @@ -259,9 +259,9 @@ static void ttm_pool_type_fini(struct ttm_pool_type *pt) · 1 unmodified line | ||
| 259 | 259 | { |
| 260 | 260 | struct page *p, *tmp; |
| 261 | 261 | |
| 262 | − spin_lock(&shrinker_lock); | |
| 262 | + mutex_lock(&shrinker_lock); | |
| 263 | 263 | list_del(&pt->shrinker_list); |
| 264 | − spin_unlock(&shrinker_lock); | |
| 264 | + mutex_unlock(&shrinker_lock); | |
| 265 | 265 | |
| 266 | 266 | list_for_each_entry_safe(p, tmp, &pt->pages, lru) |
| 267 | 267 | ttm_pool_free_page(pt->pool, pt->caching, pt->order, p); |
| @@ -302,7 +302,7 @@ static unsigned int ttm_pool_shrink(void) · 34 unmodified lines | ||
| 302 | 302 | unsigned int num_freed; |
| 303 | 303 | struct page *p; |
| 304 | 304 | |
| 305 | − spin_lock(&shrinker_lock); | |
| 305 | + mutex_lock(&shrinker_lock); | |
| 306 | 306 | pt = list_first_entry(&shrinker_list, typeof(*pt), shrinker_list); |
| 307 | 307 | |
| 308 | 308 | p = ttm_pool_type_take(pt); |
| @@ -314,7 +314,7 @@ static unsigned int ttm_pool_shrink(void) · 5 unmodified lines | ||
| 314 | 314 | } |
| 315 | 315 | |
| 316 | 316 | list_move_tail(&pt->shrinker_list, &shrinker_list); |
| 317 | − spin_unlock(&shrinker_lock); | |
| 317 | + mutex_unlock(&shrinker_lock); | |
| 318 | 318 | |
| 319 | 319 | return num_freed; |
| 320 | 320 | } |
| @@ -507,7 +507,6 @@ void ttm_pool_init(struct ttm_pool *pool, struct device *dev, · 186 unmodified lines | ||
| 507 | 507 | ttm_pool_type_init(&pool->caching[i].orders[j], |
| 508 | 508 | pool, i, j); |
| 509 | 509 | } |
| 510 | −EXPORT_SYMBOL(ttm_pool_init); | |
| 511 | 510 | |
| 512 | 511 | /** |
| 513 | 512 | * ttm_pool_fini - Cleanup a pool |
| @@ -525,7 +524,6 @@ void ttm_pool_fini(struct ttm_pool *pool) · 11 unmodified lines | ||
| 525 | 524 | for (j = 0; j < MAX_ORDER; ++j) |
| 526 | 525 | ttm_pool_type_fini(&pool->caching[i].orders[j]); |
| 527 | 526 | } |
| 528 | −EXPORT_SYMBOL(ttm_pool_fini); | |
| 529 | 527 | |
| 530 | 528 | #ifdef CONFIG_DEBUG_FS |
| 531 | 529 | /* Count the number of pages available in a pool_type */ |
| @@ -566,7 +564,7 @@ int ttm_pool_debugfs(struct ttm_pool *pool, struct seq_file *m) · 34 unmodified lines | ||
| 566 | 564 | { |
| 567 | 565 | unsigned int i; |
| 568 | 566 | |
| 569 | − spin_lock(&shrinker_lock); | |
| 567 | + mutex_lock(&shrinker_lock); | |
| 570 | 568 | |
| 571 | 569 | seq_puts(m, "\t "); |
| 572 | 570 | for (i = 0; i < MAX_ORDER; ++i) |
| @@ -602,7 +600,7 @@ int ttm_pool_debugfs(struct ttm_pool *pool, struct seq_file *m) · 29 unmodified lines | ||
| 602 | 600 | seq_printf(m, "\ntotal\t: %8lu of %8lu\n", |
| 603 | 601 | atomic_long_read(&allocated_pages), page_pool_size); |
| 604 | 602 | |
| 605 | − spin_unlock(&shrinker_lock); | |
| 603 | + mutex_unlock(&shrinker_lock); | |
| 606 | 604 | |
| 607 | 605 | return 0; |
| 608 | 606 | } |
| @@ -646,7 +644,7 @@ int ttm_pool_mgr_init(unsigned long num_pages) · 37 unmodified lines | ||
| 646 | 644 | if (!page_pool_size) |
| 647 | 645 | page_pool_size = num_pages; |
| 648 | 646 | |
| 649 | − spin_lock_init(&shrinker_lock); | |
| 647 | + mutex_init(&shrinker_lock); | |
| 650 | 648 | INIT_LIST_HEAD(&shrinker_list); |
| 651 | 649 | |
| 652 | 650 | for (i = 0; i < MAX_ORDER; ++i) { |
| @@ -899,6 +899,7 @@ config HID_SONY · 898 unmodified lines | ||
| 899 | 899 | depends on NEW_LEDS |
| 900 | 900 | depends on LEDS_CLASS |
| 901 | 901 | select POWER_SUPPLY |
| 902 | + select CRC32 | |
| 902 | 903 | help |
| 903 | 904 | Support for |
| 904 | 905 | |
| @@ -154,7 +154,7 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) · 153 unmodified lines | ||
| 154 | 154 | |
| 155 | 155 | for (i = 0; i < cl_data->num_hid_devices; i++) { |
| 156 | 156 | cl_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8, |
| 157 | − &cl_data->sensor_phys_addr[i], | |
| 157 | + &cl_data->sensor_dma_addr[i], | |
| 158 | 158 | GFP_KERNEL); |
| 159 | 159 | cl_data->sensor_sts[i] = 0; |
| 160 | 160 | cl_data->sensor_requested_cnt[i] = 0; |
| @@ -187,7 +187,7 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) · 26 unmodified lines | ||
| 187 | 187 | } |
| 188 | 188 | info.period = msecs_to_jiffies(AMD_SFH_IDLE_LOOP); |
| 189 | 189 | info.sensor_idx = cl_idx; |
| 190 | − info.phys_address = cl_data->sensor_phys_addr[i]; | |
| 190 | + info.dma_address = cl_data->sensor_dma_addr[i]; | |
| 191 | 191 | |
| 192 | 192 | cl_data->report_descr[i] = kzalloc(cl_data->report_descr_sz[i], GFP_KERNEL); |
| 193 | 193 | if (!cl_data->report_descr[i]) { |
| @@ -212,7 +212,7 @@ cleanup: · 18 unmodified lines | ||
| 212 | 212 | if (cl_data->sensor_virt_addr[i]) { |
| 213 | 213 | dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int), |
| 214 | 214 | cl_data->sensor_virt_addr[i], |
| 215 | − cl_data->sensor_phys_addr[i]); | |
| 215 | + cl_data->sensor_dma_addr[i]); | |
| 216 | 216 | } |
| 217 | 217 | kfree(cl_data->feature_report[i]); |
| 218 | 218 | kfree(cl_data->input_report[i]); |
| @@ -238,7 +238,7 @@ int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata) · 19 unmodified lines | ||
| 238 | 238 | if (cl_data->sensor_virt_addr[i]) { |
| 239 | 239 | dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int), |
| 240 | 240 | cl_data->sensor_virt_addr[i], |
| 241 | − cl_data->sensor_phys_addr[i]); | |
| 241 | + cl_data->sensor_dma_addr[i]); | |
| 242 | 242 | } |
| 243 | 243 | } |
| 244 | 244 | kfree(cl_data); |
| @@ -27,7 +27,7 @@ struct amdtp_cl_data { · 26 unmodified lines | ||
| 27 | 27 | int hid_descr_size[MAX_HID_DEVICES]; |
| 28 | 28 | phys_addr_t phys_addr_base; |
| 29 | 29 | u32 *sensor_virt_addr[MAX_HID_DEVICES]; |
| 30 | − phys_addr_t sensor_phys_addr[MAX_HID_DEVICES]; | |
| 30 | + dma_addr_t sensor_dma_addr[MAX_HID_DEVICES]; | |
| 31 | 31 | u32 sensor_sts[MAX_HID_DEVICES]; |
| 32 | 32 | u32 sensor_requested_cnt[MAX_HID_DEVICES]; |
| 33 | 33 | u8 report_type[MAX_HID_DEVICES]; |
| @@ -41,7 +41,7 @@ void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info i · 40 unmodified lines | ||
| 41 | 41 | cmd_param.s.buf_layout = 1; |
| 42 | 42 | cmd_param.s.buf_length = 16; |
| 43 | 43 | |
| 44 | − writeq(info.phys_address, privdata->mmio + AMD_C2P_MSG2); | |
| 44 | + writeq(info.dma_address, privdata->mmio + AMD_C2P_MSG2); | |
| 45 | 45 | writel(cmd_param.ul, privdata->mmio + AMD_C2P_MSG1); |
| 46 | 46 | writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0); |
| 47 | 47 | } |
| @@ -67,7 +67,7 @@ struct amd_mp2_dev { · 66 unmodified lines | ||
| 67 | 67 | struct amd_mp2_sensor_info { |
| 68 | 68 | u8 sensor_idx; |
| 69 | 69 | u32 period; |
| 70 | − phys_addr_t phys_address; | |
| 70 | + dma_addr_t dma_address; | |
| 71 | 71 | }; |
| 72 | 72 | |
| 73 | 73 | void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info); |
| @@ -389,6 +389,7 @@ · 388 unmodified lines | ||
| 389 | 389 | #define USB_DEVICE_ID_TOSHIBA_CLICK_L9W 0x0401 |
| 390 | 390 | #define USB_DEVICE_ID_HP_X2 0x074d |
| 391 | 391 | #define USB_DEVICE_ID_HP_X2_10_COVER 0x0755 |
| 392 | +#define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706 | |
| 392 | 393 | |
| 393 | 394 | #define USB_VENDOR_ID_ELECOM 0x056e |
| 394 | 395 | #define USB_DEVICE_ID_ELECOM_BM084 0x0061 |
| @@ -322,6 +322,8 @@ static const struct hid_device_id hid_battery_quirks[] = { · 321 unmodified lines | ||
| 322 | 322 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, |
| 323 | 323 | USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD), |
| 324 | 324 | HID_BATTERY_QUIRK_IGNORE }, |
| 325 | + { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN), | |
| 326 | + HID_BATTERY_QUIRK_IGNORE }, | |
| 325 | 327 | {} |
| 326 | 328 | }; |
| 327 | 329 | |
| @@ -1869,6 +1869,10 @@ static const struct hid_device_id logi_dj_receivers[] = { · 1868 unmodified lines | ||
| 1869 | 1869 | HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, |
| 1870 | 1870 | 0xc531), |
| 1871 | 1871 | .driver_data = recvr_type_gaming_hidpp}, |
| 1872 | + { /* Logitech G602 receiver (0xc537) */ | |
| 1873 | + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, | |
| 1874 | + 0xc537), | |
| 1875 | + .driver_data = recvr_type_gaming_hidpp}, | |
| 1872 | 1876 | { /* Logitech lightspeed receiver (0xc539) */ |
| 1873 | 1877 | HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, |
| 1874 | 1878 | USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1), |
| @@ -4053,6 +4053,8 @@ static const struct hid_device_id hidpp_devices[] = { · 4052 unmodified lines | ||
| 4053 | 4053 | { /* MX Master mouse over Bluetooth */ |
| 4054 | 4054 | HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb012), |
| 4055 | 4055 | .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, |
| 4056 | + { /* MX Ergo trackball over Bluetooth */ | |
| 4057 | + HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01d) }, | |
| 4056 | 4058 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01e), |
| 4057 | 4059 | .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, |
| 4058 | 4060 | { /* MX Master 3 mouse over Bluetooth */ |
| @@ -2054,6 +2054,10 @@ static const struct hid_device_id mt_devices[] = { · 2053 unmodified lines | ||
| 2054 | 2054 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, |
| 2055 | 2055 | USB_VENDOR_ID_SYNAPTICS, 0xce08) }, |
| 2056 | 2056 | |
| 2057 | + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, | |
| 2058 | + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, | |
| 2059 | + USB_VENDOR_ID_SYNAPTICS, 0xce09) }, | |
| 2060 | + | |
| 2057 | 2061 | /* TopSeed panels */ |
| 2058 | 2062 | { .driver_data = MT_CLS_TOPSEED, |
| 2059 | 2063 | MT_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, |
| @@ -90,7 +90,7 @@ static int uclogic_params_get_str_desc(__u8 **pbuf, struct hid_device *hdev, · 89 unmodified lines | ||
| 90 | 90 | goto cleanup; |
| 91 | 91 | } else if (rc < 0) { |
| 92 | 92 | hid_err(hdev, |
| 93 | − "failed retrieving string descriptor #%hhu: %d\n", | |
| 93 | + "failed retrieving string descriptor #%u: %d\n", | |
| 94 | 94 | idx, rc); |
| 95 | 95 | goto cleanup; |
| 96 | 96 | } |
| @@ -1482,7 +1482,7 @@ static void handler_return(struct wiimote_data *wdata, const __u8 *payload) · 1481 unmodified lines | ||
| 1482 | 1482 | wdata->state.cmd_err = err; |
| 1483 | 1483 | wiimote_cmd_complete(wdata); |
| 1484 | 1484 | } else if (err) { |
| 1485 | − hid_warn(wdata->hdev, "Remote error %hhu on req %hhu\n", err, | |
| 1485 | + hid_warn(wdata->hdev, "Remote error %u on req %u\n", err, | |
| 1486 | 1486 | cmd); |
| 1487 | 1487 | } |
| 1488 | 1488 | } |
| @@ -1270,6 +1270,37 @@ static int wacom_devm_sysfs_create_group(struct wacom *wacom, · 1269 unmodified lines | ||
| 1270 | 1270 | group); |
| 1271 | 1271 | } |
| 1272 | 1272 | |
| 1273 | +static void wacom_devm_kfifo_release(struct device *dev, void *res) | |
| 1274 | +{ | |
| 1275 | + struct kfifo_rec_ptr_2 *devres = res; | |
| 1276 | + | |
| 1277 | + kfifo_free(devres); | |
| 1278 | +} | |
| 1279 | + | |
| 1280 | +static int wacom_devm_kfifo_alloc(struct wacom *wacom) | |
| 1281 | +{ | |
| 1282 | + struct wacom_wac *wacom_wac = &wacom->wacom_wac; | |
| 1283 | + struct kfifo_rec_ptr_2 *pen_fifo = &wacom_wac->pen_fifo; | |
| 1284 | + int error; | |
| 1285 | + | |
| 1286 | + pen_fifo = devres_alloc(wacom_devm_kfifo_release, | |
| 1287 | + sizeof(struct kfifo_rec_ptr_2), | |
| 1288 | + GFP_KERNEL); | |
| 1289 | + | |
| 1290 | + if (!pen_fifo) | |
| 1291 | + return -ENOMEM; | |
| 1292 | + | |
| 1293 | + error = kfifo_alloc(pen_fifo, WACOM_PKGLEN_MAX, GFP_KERNEL); | |
| 1294 | + if (error) { | |
| 1295 | + devres_free(pen_fifo); | |
| 1296 | + return error; | |
| 1297 | + } | |
| 1298 | + | |
| 1299 | + devres_add(&wacom->hdev->dev, pen_fifo); | |
| 1300 | + | |
| 1301 | + return 0; | |
| 1302 | +} | |
| 1303 | + | |
| 1273 | 1304 | enum led_brightness wacom_leds_brightness_get(struct wacom_led *led) |
| 1274 | 1305 | { |
| 1275 | 1306 | struct wacom *wacom = led->wacom; |
| @@ -2724,7 +2755,7 @@ static int wacom_probe(struct hid_device *hdev, · 1448 unmodified lines | ||
| 2724 | 2755 | if (features->check_for_hid_type && features->hid_type != hdev->type) |
| 2725 | 2756 | return -ENODEV; |
| 2726 | 2757 | |
| 2727 | − error = kfifo_alloc(&wacom_wac->pen_fifo, WACOM_PKGLEN_MAX, GFP_KERNEL); | |
| 2758 | + error = wacom_devm_kfifo_alloc(wacom); | |
| 2728 | 2759 | if (error) |
| 2729 | 2760 | return error; |
| 2730 | 2761 | |
| @@ -2786,8 +2817,6 @@ static void wacom_remove(struct hid_device *hdev) · 55 unmodified lines | ||
| 2786 | 2817 | |
| 2787 | 2818 | if (wacom->wacom_wac.features.type != REMOTE) |
| 2788 | 2819 | wacom_release_resources(wacom); |
| 2789 | − | |
| 2790 | − kfifo_free(&wacom_wac->pen_fifo); | |
| 2791 | 2820 | } |
| 2792 | 2821 | |
| 2793 | 2822 | #ifdef CONFIG_PM |
| @@ -2550,7 +2550,6 @@ static void hv_kexec_handler(void) · 2549 unmodified lines | ||
| 2550 | 2550 | /* Make sure conn_state is set as hv_synic_cleanup checks for it */ |
| 2551 | 2551 | mb(); |
| 2552 | 2552 | cpuhp_remove_state(hyperv_cpuhp_online); |
| 2553 | − hyperv_cleanup(); | |
| 2554 | 2553 | }; |
| 2555 | 2554 | |
| 2556 | 2555 | static void hv_crash_handler(struct pt_regs *regs) |
| @@ -2566,7 +2565,6 @@ static void hv_crash_handler(struct pt_regs *regs) · 9 unmodified lines | ||
| 2566 | 2565 | cpu = smp_processor_id(); |
| 2567 | 2566 | hv_stimer_cleanup(cpu); |
| 2568 | 2567 | hv_synic_disable_regs(cpu); |
| 2569 | − hyperv_cleanup(); | |
| 2570 | 2568 | }; |
| 2571 | 2569 | |
| 2572 | 2570 | static int hv_synic_suspend(void) |
| @@ -222,7 +222,7 @@ static int amd_create_sensor(struct device *dev, · 221 unmodified lines | ||
| 222 | 222 | */ |
| 223 | 223 | cpus = num_present_cpus() / num_siblings; |
| 224 | 224 | |
| 225 | − s_config = devm_kcalloc(dev, cpus + sockets, | |
| 225 | + s_config = devm_kcalloc(dev, cpus + sockets + 1, | |
| 226 | 226 | sizeof(u32), GFP_KERNEL); |
| 227 | 227 | if (!s_config) |
| 228 | 228 | return -ENOMEM; |
| @@ -254,6 +254,7 @@ static int amd_create_sensor(struct device *dev, · 25 unmodified lines | ||
| 254 | 254 | scnprintf(label_l[i], 10, "Esocket%u", (i - cpus)); |
| 255 | 255 | } |
| 256 | 256 | |
| 257 | + s_config[i] = 0; | |
| 257 | 258 | return 0; |
| 258 | 259 | } |
| 259 | 260 | |
| @@ -334,8 +334,18 @@ static int pwm_fan_probe(struct platform_device *pdev) · 333 unmodified lines | ||
| 334 | 334 | |
| 335 | 335 | ctx->pwm_value = MAX_PWM; |
| 336 | 336 | |
| 337 | − /* Set duty cycle to maximum allowed and enable PWM output */ | |
| 338 | 337 | pwm_init_state(ctx->pwm, &state); |
| 338 | + /* | |
| 339 | + * __set_pwm assumes that MAX_PWM * (period - 1) fits into an unsigned | |
| 340 | + * long. Check this here to prevent the fan running at a too low | |
| 341 | + * frequency. | |
| 342 | + */ | |
| 343 | + if (state.period > ULONG_MAX / MAX_PWM + 1) { | |
| 344 | + dev_err(dev, "Configured period too big\n"); | |
| 345 | + return -EINVAL; | |
| 346 | + } | |
| 347 | + | |
| 348 | + /* Set duty cycle to maximum allowed and enable PWM output */ | |
| 339 | 349 | state.duty_cycle = ctx->pwm->args.period - 1; |
| 340 | 350 | state.enabled = true; |
| 341 | 351 | |
| @@ -1449,7 +1449,7 @@ static int i801_add_mux(struct i801_priv *priv) · 1448 unmodified lines | ||
| 1449 | 1449 | |
| 1450 | 1450 | /* Register GPIO descriptor lookup table */ |
| 1451 | 1451 | lookup = devm_kzalloc(dev, |
| 1452 | − struct_size(lookup, table, mux_config->n_gpios), | |
| 1452 | + struct_size(lookup, table, mux_config->n_gpios + 1), | |
| 1453 | 1453 | GFP_KERNEL); |
| 1454 | 1454 | if (!lookup) |
| 1455 | 1455 | return -ENOMEM; |
| @@ -38,6 +38,7 @@ · 37 unmodified lines | ||
| 38 | 38 | #define I2C_IO_CONFIG_OPEN_DRAIN 0x0003 |
| 39 | 39 | #define I2C_IO_CONFIG_PUSH_PULL 0x0000 |
| 40 | 40 | #define I2C_SOFT_RST 0x0001 |
| 41 | +#define I2C_HANDSHAKE_RST 0x0020 | |
| 41 | 42 | #define I2C_FIFO_ADDR_CLR 0x0001 |
| 42 | 43 | #define I2C_DELAY_LEN 0x0002 |
| 43 | 44 | #define I2C_TIME_CLR_VALUE 0x0000 |
| @@ -45,6 +46,7 @@ · 1 unmodified line | ||
| 45 | 46 | #define I2C_WRRD_TRANAC_VALUE 0x0002 |
| 46 | 47 | #define I2C_RD_TRANAC_VALUE 0x0001 |
| 47 | 48 | #define I2C_SCL_MIS_COMP_VALUE 0x0000 |
| 49 | +#define I2C_CHN_CLR_FLAG 0x0000 | |
| 48 | 50 | |
| 49 | 51 | #define I2C_DMA_CON_TX 0x0000 |
| 50 | 52 | #define I2C_DMA_CON_RX 0x0001 |
| @@ -54,7 +56,9 @@ · 3 unmodified lines | ||
| 54 | 56 | #define I2C_DMA_START_EN 0x0001 |
| 55 | 57 | #define I2C_DMA_INT_FLAG_NONE 0x0000 |
| 56 | 58 | #define I2C_DMA_CLR_FLAG 0x0000 |
| 59 | +#define I2C_DMA_WARM_RST 0x0001 | |
| 57 | 60 | #define I2C_DMA_HARD_RST 0x0002 |
| 61 | +#define I2C_DMA_HANDSHAKE_RST 0x0004 | |
| 58 | 62 | |
| 59 | 63 | #define MAX_SAMPLE_CNT_DIV 8 |
| 60 | 64 | #define MAX_STEP_CNT_DIV 64 |
| @@ -475,11 +479,24 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c) · 414 unmodified lines | ||
| 475 | 479 | { |
| 476 | 480 | u16 control_reg; |
| 477 | 481 | |
| 478 | − writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST); | |
| 479 | − udelay(50); | |
| 480 | − writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST); | |
| 481 | − | |
| 482 | − mtk_i2c_writew(i2c, I2C_SOFT_RST, OFFSET_SOFTRESET); | |
| 482 | + if (i2c->dev_comp->dma_sync) { | |
| 483 | + writel(I2C_DMA_WARM_RST, i2c->pdmabase + OFFSET_RST); | |
| 484 | + udelay(10); | |
| 485 | + writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST); | |
| 486 | + udelay(10); | |
| 487 | + writel(I2C_DMA_HANDSHAKE_RST | I2C_DMA_HARD_RST, | |
| 488 | + i2c->pdmabase + OFFSET_RST); | |
| 489 | + mtk_i2c_writew(i2c, I2C_HANDSHAKE_RST | I2C_SOFT_RST, | |
| 490 | + OFFSET_SOFTRESET); | |
| 491 | + udelay(10); | |
| 492 | + writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST); | |
| 493 | + mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG, OFFSET_SOFTRESET); | |
| 494 | + } else { | |
| 495 | + writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST); | |
| 496 | + udelay(50); | |
| 497 | + writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST); | |
| 498 | + mtk_i2c_writew(i2c, I2C_SOFT_RST, OFFSET_SOFTRESET); | |
| 499 | + } | |
| 483 | 500 | |
| 484 | 501 | /* Set ioconfig */ |
| 485 | 502 | if (i2c->use_push_pull) |
| @@ -72,6 +72,8 @@ · 71 unmodified lines | ||
| 72 | 72 | |
| 73 | 73 | /* timeout (ms) for pm runtime autosuspend */ |
| 74 | 74 | #define SPRD_I2C_PM_TIMEOUT 1000 |
| 75 | +/* timeout (ms) for transfer message */ | |
| 76 | +#define I2C_XFER_TIMEOUT 1000 | |
| 75 | 77 | |
| 76 | 78 | /* SPRD i2c data structure */ |
| 77 | 79 | struct sprd_i2c { |
| @@ -244,6 +246,7 @@ static int sprd_i2c_handle_msg(struct i2c_adapter *i2c_adap, · 166 unmodified lines | ||
| 244 | 246 | struct i2c_msg *msg, bool is_last_msg) |
| 245 | 247 | { |
| 246 | 248 | struct sprd_i2c *i2c_dev = i2c_adap->algo_data; |
| 249 | + unsigned long time_left; | |
| 247 | 250 | |
| 248 | 251 | i2c_dev->msg = msg; |
| 249 | 252 | i2c_dev->buf = msg->buf; |
| @@ -273,7 +276,10 @@ static int sprd_i2c_handle_msg(struct i2c_adapter *i2c_adap, · 23 unmodified lines | ||
| 273 | 276 | |
| 274 | 277 | sprd_i2c_opt_start(i2c_dev); |
| 275 | 278 | |
| 276 | − wait_for_completion(&i2c_dev->complete); | |
| 279 | + time_left = wait_for_completion_timeout(&i2c_dev->complete, | |
| 280 | + msecs_to_jiffies(I2C_XFER_TIMEOUT)); | |
| 281 | + if (!time_left) | |
| 282 | + return -ETIMEDOUT; | |
| 277 | 283 | |
| 278 | 284 | return i2c_dev->err; |
| 279 | 285 | } |
| @@ -223,7 +223,6 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq) · 222 unmodified lines | ||
| 223 | 223 | sense_rq->rq_disk = rq->rq_disk; |
| 224 | 224 | sense_rq->cmd_flags = REQ_OP_DRV_IN; |
| 225 | 225 | ide_req(sense_rq)->type = ATA_PRIV_SENSE; |
| 226 | − sense_rq->rq_flags |= RQF_PREEMPT; | |
| 227 | 226 | |
| 228 | 227 | req->cmd[0] = GPCMD_REQUEST_SENSE; |
| 229 | 228 | req->cmd[4] = cmd_len; |
| @@ -515,15 +515,10 @@ repeat: · 514 unmodified lines | ||
| 515 | 515 | * above to return us whatever is in the queue. Since we call |
| 516 | 516 | * ide_do_request() ourselves, we end up taking requests while |
| 517 | 517 | * the queue is blocked... |
| 518 | − * | |
| 519 | − * We let requests forced at head of queue with ide-preempt | |
| 520 | − * though. I hope that doesn't happen too much, hopefully not | |
| 521 | − * unless the subdriver triggers such a thing in its own PM | |
| 522 | − * state machine. | |
| 523 | 518 | */ |
| 524 | 519 | if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && |
| 525 | 520 | ata_pm_request(rq) == 0 && |
| 526 | − (rq->rq_flags & RQF_PREEMPT) == 0) { | |
| 521 | + (rq->rq_flags & RQF_PM) == 0) { | |
| 527 | 522 | /* there should be no pending command at this point */ |
| 528 | 523 | ide_unlock_port(hwif); |
| 529 | 524 | goto plug_device; |
| @@ -77,7 +77,7 @@ int generic_ide_resume(struct device *dev) · 76 unmodified lines | ||
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | memset(&rqpm, 0, sizeof(rqpm)); |
| 80 | − rq = blk_get_request(drive->queue, REQ_OP_DRV_IN, BLK_MQ_REQ_PREEMPT); | |
| 80 | + rq = blk_get_request(drive->queue, REQ_OP_DRV_IN, BLK_MQ_REQ_PM); | |
| 81 | 81 | ide_req(rq)->type = ATA_PRIV_PM_RESUME; |
| 82 | 82 | ide_req(rq)->special = &rqpm; |
| 83 | 83 | rqpm.pm_step = IDE_PM_START_RESUME; |
| @@ -963,6 +963,39 @@ static struct cpuidle_state dnv_cstates[] __initdata = { · 962 unmodified lines | ||
| 963 | 963 | .enter = NULL } |
| 964 | 964 | }; |
| 965 | 965 | |
| 966 | +/* | |
| 967 | + * Note, depending on HW and FW revision, SnowRidge SoC may or may not support | |
| 968 | + * C6, and this is indicated in the CPUID mwait leaf. | |
| 969 | + */ | |
| 970 | +static struct cpuidle_state snr_cstates[] __initdata = { | |
| 971 | + { | |
| 972 | + .name = "C1", | |
| 973 | + .desc = "MWAIT 0x00", | |
| 974 | + .flags = MWAIT2flg(0x00), | |
| 975 | + .exit_latency = 2, | |
| 976 | + .target_residency = 2, | |
| 977 | + .enter = &intel_idle, | |
| 978 | + .enter_s2idle = intel_idle_s2idle, }, | |
| 979 | + { | |
| 980 | + .name = "C1E", | |
| 981 | + .desc = "MWAIT 0x01", | |
| 982 | + .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, | |
| 983 | + .exit_latency = 15, | |
| 984 | + .target_residency = 25, | |
| 985 | + .enter = &intel_idle, | |
| 986 | + .enter_s2idle = intel_idle_s2idle, }, | |
| 987 | + { | |
| 988 | + .name = "C6", | |
| 989 | + .desc = "MWAIT 0x20", | |
| 990 | + .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, | |
| 991 | + .exit_latency = 130, | |
| 992 | + .target_residency = 500, | |
| 993 | + .enter = &intel_idle, | |
| 994 | + .enter_s2idle = intel_idle_s2idle, }, | |
| 995 | + { | |
| 996 | + .enter = NULL } | |
| 997 | +}; | |
| 998 | + | |
| 966 | 999 | static const struct idle_cpu idle_cpu_nehalem __initconst = { |
| 967 | 1000 | .state_table = nehalem_cstates, |
| 968 | 1001 | .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE, |
| @@ -1084,6 +1117,12 @@ static const struct idle_cpu idle_cpu_dnv __initconst = { · 115 unmodified lines | ||
| 1084 | 1117 | .use_acpi = true, |
| 1085 | 1118 | }; |
| 1086 | 1119 | |
| 1120 | +static const struct idle_cpu idle_cpu_snr __initconst = { | |
| 1121 | + .state_table = snr_cstates, | |
| 1122 | + .disable_promotion_to_c1e = true, | |
| 1123 | + .use_acpi = true, | |
| 1124 | +}; | |
| 1125 | + | |
| 1087 | 1126 | static const struct x86_cpu_id intel_idle_ids[] __initconst = { |
| 1088 | 1127 | X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EP, &idle_cpu_nhx), |
| 1089 | 1128 | X86_MATCH_INTEL_FAM6_MODEL(NEHALEM, &idle_cpu_nehalem), |
| @@ -1122,7 +1161,7 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = { · 32 unmodified lines | ||
| 1122 | 1161 | X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &idle_cpu_bxt), |
| 1123 | 1162 | X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS, &idle_cpu_bxt), |
| 1124 | 1163 | X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_D, &idle_cpu_dnv), |
| 1125 | − X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &idle_cpu_dnv), | |
| 1164 | + X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &idle_cpu_snr), | |
| 1126 | 1165 | {} |
| 1127 | 1166 | }; |
| 1128 | 1167 | |
| @@ -131,8 +131,10 @@ static ssize_t default_roce_mode_store(struct config_item *item, · 130 unmodified lines | ||
| 131 | 131 | return ret; |
| 132 | 132 | |
| 133 | 133 | gid_type = ib_cache_gid_parse_type_str(buf); |
| 134 | − if (gid_type < 0) | |
| 134 | + if (gid_type < 0) { | |
| 135 | + cma_configfs_params_put(cma_dev); | |
| 135 | 136 | return -EINVAL; |
| 137 | + } | |
| 136 | 138 | |
| 137 | 139 | ret = cma_set_default_gid_type(cma_dev, group->port_num, gid_type); |
| 138 | 140 | |
| @@ -254,6 +254,7 @@ void rdma_restrack_add(struct rdma_restrack_entry *res) · 253 unmodified lines | ||
| 254 | 254 | } else { |
| 255 | 255 | ret = xa_alloc_cyclic(&rt->xa, &res->id, res, xa_limit_32b, |
| 256 | 256 | &rt->next_id, GFP_KERNEL); |
| 257 | + ret = (ret < 0) ? ret : 0; | |
| 257 | 258 | } |
| 258 | 259 | |
| 259 | 260 | out: |
| @@ -95,8 +95,6 @@ struct ucma_context { · 94 unmodified lines | ||
| 95 | 95 | u64 uid; |
| 96 | 96 | |
| 97 | 97 | struct list_head list; |
| 98 | − /* sync between removal event and id destroy, protected by file mut */ | |
| 99 | − int destroying; | |
| 100 | 98 | struct work_struct close_work; |
| 101 | 99 | }; |
| 102 | 100 | |
| @@ -122,7 +120,7 @@ static DEFINE_XARRAY_ALLOC(ctx_table); · 19 unmodified lines | ||
| 122 | 120 | static DEFINE_XARRAY_ALLOC(multicast_table); |
| 123 | 121 | |
| 124 | 122 | static const struct file_operations ucma_fops; |
| 125 | −static int __destroy_id(struct ucma_context *ctx); | |
| 123 | +static int ucma_destroy_private_ctx(struct ucma_context *ctx); | |
| 126 | 124 | |
| 127 | 125 | static inline struct ucma_context *_ucma_find_context(int id, |
| 128 | 126 | struct ucma_file *file) |
| @@ -179,19 +177,14 @@ static void ucma_close_id(struct work_struct *work) · 50 unmodified lines | ||
| 179 | 177 | |
| 180 | 178 | /* once all inflight tasks are finished, we close all underlying |
| 181 | 179 | * resources. The context is still alive till its explicit destryoing |
| 182 | − * by its creator. | |
| 180 | + * by its creator. This puts back the xarray's reference. | |
| 183 | 181 | */ |
| 184 | 182 | ucma_put_ctx(ctx); |
| 185 | 183 | wait_for_completion(&ctx->comp); |
| 186 | 184 | /* No new events will be generated after destroying the id. */ |
| 187 | 185 | rdma_destroy_id(ctx->cm_id); |
| 188 | 186 | |
| 189 | − /* | |
| 190 | − * At this point ctx->ref is zero so the only place the ctx can be is in | |
| 191 | − * a uevent or in __destroy_id(). Since the former doesn't touch | |
| 192 | − * ctx->cm_id and the latter sync cancels this, there is no races with | |
| 193 | − * this store. | |
| 194 | − */ | |
| 187 | + /* Reading the cm_id without holding a positive ref is not allowed */ | |
| 195 | 188 | ctx->cm_id = NULL; |
| 196 | 189 | } |
| 197 | 190 | |
| @@ -204,7 +197,6 @@ static struct ucma_context *ucma_alloc_ctx(struct ucma_file *file) · 6 unmodified lines | ||
| 204 | 197 | return NULL; |
| 205 | 198 | |
| 206 | 199 | INIT_WORK(&ctx->close_work, ucma_close_id); |
| 207 | − refcount_set(&ctx->ref, 1); | |
| 208 | 200 | init_completion(&ctx->comp); |
| 209 | 201 | /* So list_del() will work if we don't do ucma_finish_ctx() */ |
| 210 | 202 | INIT_LIST_HEAD(&ctx->list); |
| @@ -218,6 +210,13 @@ static struct ucma_context *ucma_alloc_ctx(struct ucma_file *file) · 7 unmodified lines | ||
| 218 | 210 | return ctx; |
| 219 | 211 | } |
| 220 | 212 | |
| 213 | +static void ucma_set_ctx_cm_id(struct ucma_context *ctx, | |
| 214 | + struct rdma_cm_id *cm_id) | |
| 215 | +{ | |
| 216 | + refcount_set(&ctx->ref, 1); | |
| 217 | + ctx->cm_id = cm_id; | |
| 218 | +} | |
| 219 | + | |
| 221 | 220 | static void ucma_finish_ctx(struct ucma_context *ctx) |
| 222 | 221 | { |
| 223 | 222 | lockdep_assert_held(&ctx->file->mut); |
| @@ -303,7 +302,7 @@ static int ucma_connect_event_handler(struct rdma_cm_id *cm_id, · 79 unmodified lines | ||
| 303 | 302 | ctx = ucma_alloc_ctx(listen_ctx->file); |
| 304 | 303 | if (!ctx) |
| 305 | 304 | goto err_backlog; |
| 306 | − ctx->cm_id = cm_id; | |
| 305 | + ucma_set_ctx_cm_id(ctx, cm_id); | |
| 307 | 306 | |
| 308 | 307 | uevent = ucma_create_uevent(listen_ctx, event); |
| 309 | 308 | if (!uevent) |
| @@ -321,8 +320,7 @@ static int ucma_connect_event_handler(struct rdma_cm_id *cm_id, · 11 unmodified lines | ||
| 321 | 320 | return 0; |
| 322 | 321 | |
| 323 | 322 | err_alloc: |
| 324 | − xa_erase(&ctx_table, ctx->id); | |
| 325 | − kfree(ctx); | |
| 323 | + ucma_destroy_private_ctx(ctx); | |
| 326 | 324 | err_backlog: |
| 327 | 325 | atomic_inc(&listen_ctx->backlog); |
| 328 | 326 | /* Returning error causes the new ID to be destroyed */ |
| @@ -356,8 +354,12 @@ static int ucma_event_handler(struct rdma_cm_id *cm_id, · 27 unmodified lines | ||
| 356 | 354 | wake_up_interruptible(&ctx->file->poll_wait); |
| 357 | 355 | } |
| 358 | 356 | |
| 359 | − if (event->event == RDMA_CM_EVENT_DEVICE_REMOVAL && !ctx->destroying) | |
| 360 | − queue_work(system_unbound_wq, &ctx->close_work); | |
| 357 | + if (event->event == RDMA_CM_EVENT_DEVICE_REMOVAL) { | |
| 358 | + xa_lock(&ctx_table); | |
| 359 | + if (xa_load(&ctx_table, ctx->id) == ctx) | |
| 360 | + queue_work(system_unbound_wq, &ctx->close_work); | |
| 361 | + xa_unlock(&ctx_table); | |
| 362 | + } | |
| 361 | 363 | return 0; |
| 362 | 364 | } |
| 363 | 365 | |
| @@ -461,13 +463,12 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf, · 97 unmodified lines | ||
| 461 | 463 | ret = PTR_ERR(cm_id); |
| 462 | 464 | goto err1; |
| 463 | 465 | } |
| 464 | − ctx->cm_id = cm_id; | |
| 466 | + ucma_set_ctx_cm_id(ctx, cm_id); | |
| 465 | 467 | |
| 466 | 468 | resp.id = ctx->id; |
| 467 | 469 | if (copy_to_user(u64_to_user_ptr(cmd.response), |
| 468 | 470 | &resp, sizeof(resp))) { |
| 469 | − xa_erase(&ctx_table, ctx->id); | |
| 470 | − __destroy_id(ctx); | |
| 471 | + ucma_destroy_private_ctx(ctx); | |
| 471 | 472 | return -EFAULT; |
| 472 | 473 | } |
| 473 | 474 | |
| @@ -477,8 +478,7 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf, · 3 unmodified lines | ||
| 477 | 478 | return 0; |
| 478 | 479 | |
| 479 | 480 | err1: |
| 480 | − xa_erase(&ctx_table, ctx->id); | |
| 481 | − kfree(ctx); | |
| 481 | + ucma_destroy_private_ctx(ctx); | |
| 482 | 482 | return ret; |
| 483 | 483 | } |
| 484 | 484 | |
| @@ -516,68 +516,73 @@ static void ucma_cleanup_mc_events(struct ucma_multicast *mc) · 31 unmodified lines | ||
| 516 | 516 | rdma_unlock_handler(mc->ctx->cm_id); |
| 517 | 517 | } |
| 518 | 518 | |
| 519 | −/* | |
| 520 | − * ucma_free_ctx is called after the underlying rdma CM-ID is destroyed. At | |
| 521 | − * this point, no new events will be reported from the hardware. However, we | |
| 522 | − * still need to cleanup the UCMA context for this ID. Specifically, there | |
| 523 | − * might be events that have not yet been consumed by the user space software. | |
| 524 | − * mutex. After that we release them as needed. | |
| 525 | − */ | |
| 526 | −static int ucma_free_ctx(struct ucma_context *ctx) | |
| 519 | +static int ucma_cleanup_ctx_events(struct ucma_context *ctx) | |
| 527 | 520 | { |
| 528 | 521 | int events_reported; |
| 529 | 522 | struct ucma_event *uevent, *tmp; |
| 530 | 523 | LIST_HEAD(list); |
| 531 | 524 | |
| 532 | − ucma_cleanup_multicast(ctx); | |
| 533 | − | |
| 534 | − /* Cleanup events not yet reported to the user. */ | |
| 525 | + /* Cleanup events not yet reported to the user.*/ | |
| 535 | 526 | mutex_lock(&ctx->file->mut); |
| 536 | 527 | list_for_each_entry_safe(uevent, tmp, &ctx->file->event_list, list) { |
| 537 | − if (uevent->ctx == ctx || uevent->conn_req_ctx == ctx) | |
| 528 | + if (uevent->ctx != ctx) | |
| 529 | + continue; | |
| 530 | + | |
| 531 | + if (uevent->resp.event == RDMA_CM_EVENT_CONNECT_REQUEST && | |
| 532 | + xa_cmpxchg(&ctx_table, uevent->conn_req_ctx->id, | |
| 533 | + uevent->conn_req_ctx, XA_ZERO_ENTRY, | |
| 534 | + GFP_KERNEL) == uevent->conn_req_ctx) { | |
| 538 | 535 | list_move_tail(&uevent->list, &list); |
| 536 | + continue; | |
| 537 | + } | |
| 538 | + list_del(&uevent->list); | |
| 539 | + kfree(uevent); | |
| 539 | 540 | } |
| 540 | 541 | list_del(&ctx->list); |
| 541 | 542 | events_reported = ctx->events_reported; |
| 542 | 543 | mutex_unlock(&ctx->file->mut); |
| 543 | 544 | |
| 544 | 545 | /* |
| 545 | − * If this was a listening ID then any connections spawned from it | |
| 546 | − * that have not been delivered to userspace are cleaned up too. | |
| 547 | − * Must be done outside any locks. | |
| 546 | + * If this was a listening ID then any connections spawned from it that | |
| 547 | + * have not been delivered to userspace are cleaned up too. Must be done | |
| 548 | + * outside any locks. | |
| 548 | 549 | */ |
| 549 | 550 | list_for_each_entry_safe(uevent, tmp, &list, list) { |
| 550 | − list_del(&uevent->list); | |
| 551 | − if (uevent->resp.event == RDMA_CM_EVENT_CONNECT_REQUEST && | |
| 552 | − uevent->conn_req_ctx != ctx) | |
| 553 | − __destroy_id(uevent->conn_req_ctx); | |
| 551 | + ucma_destroy_private_ctx(uevent->conn_req_ctx); | |
| 554 | 552 | kfree(uevent); |
| 555 | 553 | } |
| 556 | − | |
| 557 | − mutex_destroy(&ctx->mutex); | |
| 558 | − kfree(ctx); | |
| 559 | 554 | return events_reported; |
| 560 | 555 | } |
| 561 | 556 | |
| 562 | −static int __destroy_id(struct ucma_context *ctx) | |
| 557 | +/* | |
| 558 | + * When this is called the xarray must have a XA_ZERO_ENTRY in the ctx->id (ie | |
| 559 | + * the ctx is not public to the user). This either because: | |
| 560 | + * - ucma_finish_ctx() hasn't been called | |
| 561 | + * - xa_cmpxchg() succeed to remove the entry (only one thread can succeed) | |
| 562 | + */ | |
| 563 | +static int ucma_destroy_private_ctx(struct ucma_context *ctx) | |
| 563 | 564 | { |
| 565 | + int events_reported; | |
| 566 | + | |
| 564 | 567 | /* |
| 565 | − * If the refcount is already 0 then ucma_close_id() has already | |
| 566 | − * destroyed the cm_id, otherwise holding the refcount keeps cm_id | |
| 567 | − * valid. Prevent queue_work() from being called. | |
| 568 | + * Destroy the underlying cm_id. New work queuing is prevented now by | |
| 569 | + * the removal from the xarray. Once the work is cancled ref will either | |
| 570 | + * be 0 because the work ran to completion and consumed the ref from the | |
| 571 | + * xarray, or it will be positive because we still have the ref from the | |
| 572 | + * xarray. This can also be 0 in cases where cm_id was never set | |
| 568 | 573 | */ |
| 569 | − if (refcount_inc_not_zero(&ctx->ref)) { | |
| 570 | − rdma_lock_handler(ctx->cm_id); | |
| 571 | − ctx->destroying = 1; | |
| 572 | − rdma_unlock_handler(ctx->cm_id); | |
| 573 | − ucma_put_ctx(ctx); | |
| 574 | − } | |
| 575 | − | |
| 576 | 574 | cancel_work_sync(&ctx->close_work); |
| 577 | − /* At this point it's guaranteed that there is no inflight closing task */ | |
| 578 | − if (ctx->cm_id) | |
| 575 | + if (refcount_read(&ctx->ref)) | |
| 579 | 576 | ucma_close_id(&ctx->close_work); |
| 580 | − return ucma_free_ctx(ctx); | |
| 577 | + | |
| 578 | + events_reported = ucma_cleanup_ctx_events(ctx); | |
| 579 | + ucma_cleanup_multicast(ctx); | |
| 580 | + | |
| 581 | + WARN_ON(xa_cmpxchg(&ctx_table, ctx->id, XA_ZERO_ENTRY, NULL, | |
| 582 | + GFP_KERNEL) != NULL); | |
| 583 | + mutex_destroy(&ctx->mutex); | |
| 584 | + kfree(ctx); | |
| 585 | + return events_reported; | |
| 581 | 586 | } |
| 582 | 587 | |
| 583 | 588 | static ssize_t ucma_destroy_id(struct ucma_file *file, const char __user *inbuf, |
| @@ -596,14 +601,17 @@ static ssize_t ucma_destroy_id(struct ucma_file *file, const char __user *inbuf, · 12 unmodified lines | ||
| 596 | 601 | |
| 597 | 602 | xa_lock(&ctx_table); |
| 598 | 603 | ctx = _ucma_find_context(cmd.id, file); |
| 599 | − if (!IS_ERR(ctx)) | |
| 600 | − __xa_erase(&ctx_table, ctx->id); | |
| 604 | + if (!IS_ERR(ctx)) { | |
| 605 | + if (__xa_cmpxchg(&ctx_table, ctx->id, ctx, XA_ZERO_ENTRY, | |
| 606 | + GFP_KERNEL) != ctx) | |
| 607 | + ctx = ERR_PTR(-ENOENT); | |
| 608 | + } | |
| 601 | 609 | xa_unlock(&ctx_table); |
| 602 | 610 | |
| 603 | 611 | if (IS_ERR(ctx)) |
| 604 | 612 | return PTR_ERR(ctx); |
| 605 | 613 | |
| 606 | − resp.events_reported = __destroy_id(ctx); | |
| 614 | + resp.events_reported = ucma_destroy_private_ctx(ctx); | |
| 607 | 615 | if (copy_to_user(u64_to_user_ptr(cmd.response), |
| 608 | 616 | &resp, sizeof(resp))) |
| 609 | 617 | ret = -EFAULT; |
| @@ -1777,15 +1785,16 @@ static int ucma_close(struct inode *inode, struct file *filp) · 1167 unmodified lines | ||
| 1777 | 1785 | * prevented by this being a FD release function. The list_add_tail() in |
| 1778 | 1786 | * ucma_connect_event_handler() can run concurrently, however it only |
| 1779 | 1787 | * adds to the list *after* a listening ID. By only reading the first of |
| 1780 | − * the list, and relying on __destroy_id() to block | |
| 1788 | + * the list, and relying on ucma_destroy_private_ctx() to block | |
| 1781 | 1789 | * ucma_connect_event_handler(), no additional locking is needed. |
| 1782 | 1790 | */ |
| 1783 | 1791 | while (!list_empty(&file->ctx_list)) { |
| 1784 | 1792 | struct ucma_context *ctx = list_first_entry( |
| 1785 | 1793 | &file->ctx_list, struct ucma_context, list); |
| 1786 | 1794 | |
| 1787 | − xa_erase(&ctx_table, ctx->id); | |
| 1788 | − __destroy_id(ctx); | |
| 1795 | + WARN_ON(xa_cmpxchg(&ctx_table, ctx->id, ctx, XA_ZERO_ENTRY, | |
| 1796 | + GFP_KERNEL) != ctx); | |
| 1797 | + ucma_destroy_private_ctx(ctx); | |
| 1789 | 1798 | } |
| 1790 | 1799 | kfree(file); |
| 1791 | 1800 | return 0; |
| @@ -135,7 +135,7 @@ unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem, · 134 unmodified lines | ||
| 135 | 135 | */ |
| 136 | 136 | if (mask) |
| 137 | 137 | pgsz_bitmap &= GENMASK(count_trailing_zeros(mask), 0); |
| 138 | − return rounddown_pow_of_two(pgsz_bitmap); | |
| 138 | + return pgsz_bitmap ? rounddown_pow_of_two(pgsz_bitmap) : 0; | |
| 139 | 139 | } |
| 140 | 140 | EXPORT_SYMBOL(ib_umem_find_best_pgsz); |
| 141 | 141 | |
| @@ -3956,7 +3956,7 @@ static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev) · 3955 unmodified lines | ||
| 3956 | 3956 | |
| 3957 | 3957 | err = set_has_smi_cap(dev); |
| 3958 | 3958 | if (err) |
| 3959 | − return err; | |
| 3959 | + goto err_mp; | |
| 3960 | 3960 | |
| 3961 | 3961 | if (!mlx5_core_mp_enabled(mdev)) { |
| 3962 | 3962 | for (i = 1; i <= dev->num_ports; i++) { |
| @@ -4319,7 +4319,7 @@ static int mlx5_ib_stage_bfrag_init(struct mlx5_ib_dev *dev) · 356 unmodified lines | ||
| 4319 | 4319 | |
| 4320 | 4320 | err = mlx5_alloc_bfreg(dev->mdev, &dev->fp_bfreg, false, true); |
| 4321 | 4321 | if (err) |
| 4322 | − mlx5_free_bfreg(dev->mdev, &dev->fp_bfreg); | |
| 4322 | + mlx5_free_bfreg(dev->mdev, &dev->bfreg); | |
| 4323 | 4323 | |
| 4324 | 4324 | return err; |
| 4325 | 4325 | } |
| @@ -434,9 +434,9 @@ static void ocrdma_dealloc_ucontext_pd(struct ocrdma_ucontext *uctx) · 433 unmodified lines | ||
| 434 | 434 | pr_err("%s(%d) Freeing in use pdid=0x%x.\n", |
| 435 | 435 | __func__, dev->id, pd->id); |
| 436 | 436 | } |
| 437 | − kfree(uctx->cntxt_pd); | |
| 438 | 437 | uctx->cntxt_pd = NULL; |
| 439 | 438 | _ocrdma_dealloc_pd(dev, pd); |
| 439 | + kfree(pd); | |
| 440 | 440 | } |
| 441 | 441 | |
| 442 | 442 | static struct ocrdma_pd *ocrdma_get_ucontext_pd(struct ocrdma_ucontext *uctx) |
| @@ -214,6 +214,7 @@ find_free_vf_and_create_qp_grp(struct usnic_ib_dev *us_ibdev, · 213 unmodified lines | ||
| 214 | 214 | |
| 215 | 215 | } |
| 216 | 216 | usnic_uiom_free_dev_list(dev_list); |
| 217 | + dev_list = NULL; | |
| 217 | 218 | } |
| 218 | 219 | |
| 219 | 220 | /* Try to find resources on an unused vf */ |
| @@ -239,6 +240,8 @@ find_free_vf_and_create_qp_grp(struct usnic_ib_dev *us_ibdev, · 19 unmodified lines | ||
| 239 | 240 | qp_grp_check: |
| 240 | 241 | if (IS_ERR_OR_NULL(qp_grp)) { |
| 241 | 242 | usnic_err("Failed to allocate qp_grp\n"); |
| 243 | + if (usnic_ib_share_vf) | |
| 244 | + usnic_uiom_free_dev_list(dev_list); | |
| 242 | 245 | return ERR_PTR(qp_grp ? PTR_ERR(qp_grp) : -ENOMEM); |
| 243 | 246 | } |
| 244 | 247 | return qp_grp; |
| @@ -96,9 +96,10 @@ static int imx_icc_node_init_qos(struct icc_provider *provider, · 95 unmodified lines | ||
| 96 | 96 | return -ENODEV; |
| 97 | 97 | } |
| 98 | 98 | /* Allow scaling to be disabled on a per-node basis */ |
| 99 | − if (!dn || !of_device_is_available(dn)) { | |
| 99 | + if (!of_device_is_available(dn)) { | |
| 100 | 100 | dev_warn(dev, "Missing property %s, skip scaling %s\n", |
| 101 | 101 | adj->phandle_name, node->name); |
| 102 | + of_node_put(dn); | |
| 102 | 103 | return 0; |
| 103 | 104 | } |
| 104 | 105 | |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | #include <linux/module.h> |
| 9 | 9 | #include <linux/platform_device.h> |
| 10 | +#include <linux/interconnect-provider.h> | |
| 10 | 11 | #include <dt-bindings/interconnect/imx8mq.h> |
| 11 | 12 | |
| 12 | 13 | #include "imx.h" |
| @@ -94,6 +95,7 @@ static struct platform_driver imx8mq_icc_driver = { · 81 unmodified lines | ||
| 94 | 95 | .remove = imx8mq_icc_remove, |
| 95 | 96 | .driver = { |
| 96 | 97 | .name = "imx8mq-interconnect", |
| 98 | + .sync_state = icc_sync_state, | |
| 97 | 99 | }, |
| 98 | 100 | }; |
| 99 | 101 | |
| @@ -42,13 +42,23 @@ config INTERCONNECT_QCOM_QCS404 · 41 unmodified lines | ||
| 42 | 42 | This is a driver for the Qualcomm Network-on-Chip on qcs404-based |
| 43 | 43 | platforms. |
| 44 | 44 | |
| 45 | +config INTERCONNECT_QCOM_RPMH_POSSIBLE | |
| 46 | + tristate | |
| 47 | + default INTERCONNECT_QCOM | |
| 48 | + depends on QCOM_RPMH || (COMPILE_TEST && !QCOM_RPMH) | |
| 49 | + depends on QCOM_COMMAND_DB || (COMPILE_TEST && !QCOM_COMMAND_DB) | |
| 50 | + depends on OF || COMPILE_TEST | |
| 51 | + help | |
| 52 | + Compile-testing RPMH drivers is possible on other platforms, | |
| 53 | + but in order to avoid link failures, drivers must not be built-in | |
| 54 | + when QCOM_RPMH or QCOM_COMMAND_DB are loadable modules | |
| 55 | + | |
| 45 | 56 | config INTERCONNECT_QCOM_RPMH |
| 46 | 57 | tristate |
| 47 | 58 | |
| 48 | 59 | config INTERCONNECT_QCOM_SC7180 |
| 49 | 60 | tristate "Qualcomm SC7180 interconnect driver" |
| 50 | − depends on INTERCONNECT_QCOM | |
| 51 | − depends on (QCOM_RPMH && QCOM_COMMAND_DB && OF) || COMPILE_TEST | |
| 61 | + depends on INTERCONNECT_QCOM_RPMH_POSSIBLE | |
| 52 | 62 | select INTERCONNECT_QCOM_RPMH |
| 53 | 63 | select INTERCONNECT_QCOM_BCM_VOTER |
| 54 | 64 | help |
| @@ -57,8 +67,7 @@ config INTERCONNECT_QCOM_SC7180 · 2 unmodified lines | ||
| 57 | 67 | |
| 58 | 68 | config INTERCONNECT_QCOM_SDM845 |
| 59 | 69 | tristate "Qualcomm SDM845 interconnect driver" |
| 60 | − depends on INTERCONNECT_QCOM | |
| 61 | − depends on (QCOM_RPMH && QCOM_COMMAND_DB && OF) || COMPILE_TEST | |
| 70 | + depends on INTERCONNECT_QCOM_RPMH_POSSIBLE | |
| 62 | 71 | select INTERCONNECT_QCOM_RPMH |
| 63 | 72 | select INTERCONNECT_QCOM_BCM_VOTER |
| 64 | 73 | help |
| @@ -67,8 +76,7 @@ config INTERCONNECT_QCOM_SDM845 · 2 unmodified lines | ||
| 67 | 76 | |
| 68 | 77 | config INTERCONNECT_QCOM_SM8150 |
| 69 | 78 | tristate "Qualcomm SM8150 interconnect driver" |
| 70 | − depends on INTERCONNECT_QCOM | |
| 71 | − depends on (QCOM_RPMH && QCOM_COMMAND_DB && OF) || COMPILE_TEST | |
| 79 | + depends on INTERCONNECT_QCOM_RPMH_POSSIBLE | |
| 72 | 80 | select INTERCONNECT_QCOM_RPMH |
| 73 | 81 | select INTERCONNECT_QCOM_BCM_VOTER |
| 74 | 82 | help |
| @@ -77,8 +85,7 @@ config INTERCONNECT_QCOM_SM8150 · 2 unmodified lines | ||
| 77 | 85 | |
| 78 | 86 | config INTERCONNECT_QCOM_SM8250 |
| 79 | 87 | tristate "Qualcomm SM8250 interconnect driver" |
| 80 | − depends on INTERCONNECT_QCOM | |
| 81 | − depends on (QCOM_RPMH && QCOM_COMMAND_DB && OF) || COMPILE_TEST | |
| 88 | + depends on INTERCONNECT_QCOM_RPMH_POSSIBLE | |
| 82 | 89 | select INTERCONNECT_QCOM_RPMH |
| 83 | 90 | select INTERCONNECT_QCOM_BCM_VOTER |
| 84 | 91 | help |
| @@ -1973,8 +1973,6 @@ static int iommu_setup_msi(struct amd_iommu *iommu) · 1972 unmodified lines | ||
| 1973 | 1973 | return r; |
| 1974 | 1974 | } |
| 1975 | 1975 | |
| 1976 | − iommu->int_enabled = true; | |
| 1977 | − | |
| 1978 | 1976 | return 0; |
| 1979 | 1977 | } |
| 1980 | 1978 | |
| @@ -2169,6 +2167,7 @@ static int iommu_init_irq(struct amd_iommu *iommu) · 188 unmodified lines | ||
| 2169 | 2167 | if (ret) |
| 2170 | 2168 | return ret; |
| 2171 | 2169 | |
| 2170 | + iommu->int_enabled = true; | |
| 2172 | 2171 | enable_faults: |
| 2173 | 2172 | iommu_feature_enable(iommu, CONTROL_EVT_INT_EN); |
| 2174 | 2173 | |
| @@ -3854,6 +3854,9 @@ static int irq_remapping_select(struct irq_domain *d, struct irq_fwspec *fwspec, · 3853 unmodified lines | ||
| 3854 | 3854 | struct amd_iommu *iommu; |
| 3855 | 3855 | int devid = -1; |
| 3856 | 3856 | |
| 3857 | + if (!amd_iommu_irq_remap) | |
| 3858 | + return 0; | |
| 3859 | + | |
| 3857 | 3860 | if (x86_fwspec_is_ioapic(fwspec)) |
| 3858 | 3861 | devid = get_ioapic_devid(fwspec->param[0]); |
| 3859 | 3862 | else if (x86_fwspec_is_hpet(fwspec)) |
| @@ -196,6 +196,8 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) · 195 unmodified lines | ||
| 196 | 196 | |
| 197 | 197 | set_bit(qsmmu->bypass_cbndx, smmu->context_map); |
| 198 | 198 | |
| 199 | + arm_smmu_cb_write(smmu, qsmmu->bypass_cbndx, ARM_SMMU_CB_SCTLR, 0); | |
| 200 | + | |
| 199 | 201 | reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, CBAR_TYPE_S1_TRANS_S2_BYPASS); |
| 200 | 202 | arm_smmu_gr1_write(smmu, ARM_SMMU_GR1_CBAR(qsmmu->bypass_cbndx), reg); |
| 201 | 203 | } |
| @@ -323,7 +325,9 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu, · 121 unmodified lines | ||
| 323 | 325 | } |
| 324 | 326 | |
| 325 | 327 | static const struct of_device_id __maybe_unused qcom_smmu_impl_of_match[] = { |
| 328 | + { .compatible = "qcom,msm8998-smmu-v2" }, | |
| 326 | 329 | { .compatible = "qcom,sc7180-smmu-500" }, |
| 330 | + { .compatible = "qcom,sdm630-smmu-v2" }, | |
| 327 | 331 | { .compatible = "qcom,sdm845-smmu-500" }, |
| 328 | 332 | { .compatible = "qcom,sm8150-smmu-500" }, |
| 329 | 333 | { .compatible = "qcom,sm8250-smmu-500" }, |
| @@ -863,33 +863,6 @@ static int __finalise_sg(struct device *dev, struct scatterlist *sg, int nents, · 862 unmodified lines | ||
| 863 | 863 | unsigned int cur_len = 0, max_len = dma_get_max_seg_size(dev); |
| 864 | 864 | int i, count = 0; |
| 865 | 865 | |
| 866 | − /* | |
| 867 | − * The Intel graphic driver is used to assume that the returned | |
| 868 | − * sg list is not combound. This blocks the efforts of converting | |
| 869 | − * Intel IOMMU driver to dma-iommu api's. Add this quirk to make the | |
| 870 | − * device driver work and should be removed once it's fixed in i915 | |
| 871 | − * driver. | |
| 872 | − */ | |
| 873 | − if (IS_ENABLED(CONFIG_DRM_I915) && dev_is_pci(dev) && | |
| 874 | − to_pci_dev(dev)->vendor == PCI_VENDOR_ID_INTEL && | |
| 875 | − (to_pci_dev(dev)->class >> 16) == PCI_BASE_CLASS_DISPLAY) { | |
| 876 | − for_each_sg(sg, s, nents, i) { | |
| 877 | − unsigned int s_iova_off = sg_dma_address(s); | |
| 878 | − unsigned int s_length = sg_dma_len(s); | |
| 879 | − unsigned int s_iova_len = s->length; | |
| 880 | − | |
| 881 | − s->offset += s_iova_off; | |
| 882 | − s->length = s_length; | |
| 883 | − sg_dma_address(s) = dma_addr + s_iova_off; | |
| 884 | − sg_dma_len(s) = s_length; | |
| 885 | − dma_addr += s_iova_len; | |
| 886 | − | |
| 887 | − pr_info_once("sg combining disabled due to i915 driver\n"); | |
| 888 | − } | |
| 889 | − | |
| 890 | − return nents; | |
| 891 | − } | |
| 892 | − | |
| 893 | 866 | for_each_sg(sg, s, nents, i) { |
| 894 | 867 | /* Restore this segment's original unaligned fields first */ |
| 895 | 868 | unsigned int s_iova_off = sg_dma_address(s); |
| @@ -1461,8 +1461,8 @@ void qi_flush_piotlb(struct intel_iommu *iommu, u16 did, u32 pasid, u64 addr, · 1460 unmodified lines | ||
| 1461 | 1461 | int mask = ilog2(__roundup_pow_of_two(npages)); |
| 1462 | 1462 | unsigned long align = (1ULL << (VTD_PAGE_SHIFT + mask)); |
| 1463 | 1463 | |
| 1464 | − if (WARN_ON_ONCE(!ALIGN(addr, align))) | |
| 1465 | − addr &= ~(align - 1); | |
| 1464 | + if (WARN_ON_ONCE(!IS_ALIGNED(addr, align))) | |
| 1465 | + addr = ALIGN_DOWN(addr, align); | |
| 1466 | 1466 | |
| 1467 | 1467 | desc.qw0 = QI_EIOTLB_PASID(pasid) | |
| 1468 | 1468 | QI_EIOTLB_DID(did) | |
| @@ -38,7 +38,6 @@ · 37 unmodified lines | ||
| 38 | 38 | #include <linux/dmi.h> |
| 39 | 39 | #include <linux/pci-ats.h> |
| 40 | 40 | #include <linux/memblock.h> |
| 41 | −#include <linux/dma-map-ops.h> | |
| 42 | 41 | #include <linux/dma-direct.h> |
| 43 | 42 | #include <linux/crash_dump.h> |
| 44 | 43 | #include <linux/numa.h> |
| @@ -719,6 +718,8 @@ static int domain_update_device_node(struct dmar_domain *domain) · 674 unmodified lines | ||
| 719 | 718 | return nid; |
| 720 | 719 | } |
| 721 | 720 | |
| 721 | +static void domain_update_iotlb(struct dmar_domain *domain); | |
| 722 | + | |
| 722 | 723 | /* Some capabilities may be different across iommus */ |
| 723 | 724 | static void domain_update_iommu_cap(struct dmar_domain *domain) |
| 724 | 725 | { |
| @@ -744,6 +745,8 @@ static void domain_update_iommu_cap(struct dmar_domain *domain) · 19 unmodified lines | ||
| 744 | 745 | domain->domain.geometry.aperture_end = __DOMAIN_MAX_ADDR(domain->gaw - 1); |
| 745 | 746 | else |
| 746 | 747 | domain->domain.geometry.aperture_end = __DOMAIN_MAX_ADDR(domain->gaw); |
| 748 | + | |
| 749 | + domain_update_iotlb(domain); | |
| 747 | 750 | } |
| 748 | 751 | |
| 749 | 752 | struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus, |
| @@ -1464,17 +1467,22 @@ static void domain_update_iotlb(struct dmar_domain *domain) · 714 unmodified lines | ||
| 1464 | 1467 | |
| 1465 | 1468 | assert_spin_locked(&device_domain_lock); |
| 1466 | 1469 | |
| 1467 | − list_for_each_entry(info, &domain->devices, link) { | |
| 1468 | − struct pci_dev *pdev; | |
| 1469 | − | |
| 1470 | − if (!info->dev || !dev_is_pci(info->dev)) | |
| 1471 | − continue; | |
| 1472 | − | |
| 1473 | − pdev = to_pci_dev(info->dev); | |
| 1474 | − if (pdev->ats_enabled) { | |
| 1470 | + list_for_each_entry(info, &domain->devices, link) | |
| 1471 | + if (info->ats_enabled) { | |
| 1475 | 1472 | has_iotlb_device = true; |
| 1476 | 1473 | break; |
| 1477 | 1474 | } |
| 1475 | + | |
| 1476 | + if (!has_iotlb_device) { | |
| 1477 | + struct subdev_domain_info *sinfo; | |
| 1478 | + | |
| 1479 | + list_for_each_entry(sinfo, &domain->subdevices, link_domain) { | |
| 1480 | + info = get_domain_info(sinfo->pdev); | |
| 1481 | + if (info && info->ats_enabled) { | |
| 1482 | + has_iotlb_device = true; | |
| 1483 | + break; | |
| 1484 | + } | |
| 1485 | + } | |
| 1478 | 1486 | } |
| 1479 | 1487 | |
| 1480 | 1488 | domain->has_iotlb_device = has_iotlb_device; |
| @@ -1555,25 +1563,37 @@ static void iommu_disable_dev_iotlb(struct device_domain_info *info) · 74 unmodified lines | ||
| 1555 | 1563 | #endif |
| 1556 | 1564 | } |
| 1557 | 1565 | |
| 1566 | +static void __iommu_flush_dev_iotlb(struct device_domain_info *info, | |
| 1567 | + u64 addr, unsigned int mask) | |
| 1568 | +{ | |
| 1569 | + u16 sid, qdep; | |
| 1570 | + | |
| 1571 | + if (!info || !info->ats_enabled) | |
| 1572 | + return; | |
| 1573 | + | |
| 1574 | + sid = info->bus << 8 | info->devfn; | |
| 1575 | + qdep = info->ats_qdep; | |
| 1576 | + qi_flush_dev_iotlb(info->iommu, sid, info->pfsid, | |
| 1577 | + qdep, addr, mask); | |
| 1578 | +} | |
| 1579 | + | |
| 1558 | 1580 | static void iommu_flush_dev_iotlb(struct dmar_domain *domain, |
| 1559 | 1581 | u64 addr, unsigned mask) |
| 1560 | 1582 | { |
| 1561 | − u16 sid, qdep; | |
| 1562 | 1583 | unsigned long flags; |
| 1563 | 1584 | struct device_domain_info *info; |
| 1585 | + struct subdev_domain_info *sinfo; | |
| 1564 | 1586 | |
| 1565 | 1587 | if (!domain->has_iotlb_device) |
| 1566 | 1588 | return; |
| 1567 | 1589 | |
| 1568 | 1590 | spin_lock_irqsave(&device_domain_lock, flags); |
| 1569 | − list_for_each_entry(info, &domain->devices, link) { | |
| 1570 | − if (!info->ats_enabled) | |
| 1571 | − continue; | |
| 1591 | + list_for_each_entry(info, &domain->devices, link) | |
| 1592 | + __iommu_flush_dev_iotlb(info, addr, mask); | |
| 1572 | 1593 | |
| 1573 | − sid = info->bus << 8 | info->devfn; | |
| 1574 | − qdep = info->ats_qdep; | |
| 1575 | − qi_flush_dev_iotlb(info->iommu, sid, info->pfsid, | |
| 1576 | − qdep, addr, mask); | |
| 1594 | + list_for_each_entry(sinfo, &domain->subdevices, link_domain) { | |
| 1595 | + info = get_domain_info(sinfo->pdev); | |
| 1596 | + __iommu_flush_dev_iotlb(info, addr, mask); | |
| 1577 | 1597 | } |
| 1578 | 1598 | spin_unlock_irqrestore(&device_domain_lock, flags); |
| 1579 | 1599 | } |
| @@ -1877,6 +1897,7 @@ static struct dmar_domain *alloc_domain(int flags) · 297 unmodified lines | ||
| 1877 | 1897 | domain->flags |= DOMAIN_FLAG_USE_FIRST_LEVEL; |
| 1878 | 1898 | domain->has_iotlb_device = false; |
| 1879 | 1899 | INIT_LIST_HEAD(&domain->devices); |
| 1900 | + INIT_LIST_HEAD(&domain->subdevices); | |
| 1880 | 1901 | |
| 1881 | 1902 | return domain; |
| 1882 | 1903 | } |
| @@ -2547,7 +2568,7 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu, · 664 unmodified lines | ||
| 2547 | 2568 | info->iommu = iommu; |
| 2548 | 2569 | info->pasid_table = NULL; |
| 2549 | 2570 | info->auxd_enabled = 0; |
| 2550 | − INIT_LIST_HEAD(&info->auxiliary_domains); | |
| 2571 | + INIT_LIST_HEAD(&info->subdevices); | |
| 2551 | 2572 | |
| 2552 | 2573 | if (dev && dev_is_pci(dev)) { |
| 2553 | 2574 | struct pci_dev *pdev = to_pci_dev(info->dev); |
| @@ -4475,33 +4496,61 @@ is_aux_domain(struct device *dev, struct iommu_domain *domain) · 1921 unmodified lines | ||
| 4475 | 4496 | domain->type == IOMMU_DOMAIN_UNMANAGED; |
| 4476 | 4497 | } |
| 4477 | 4498 | |
| 4478 | −static void auxiliary_link_device(struct dmar_domain *domain, | |
| 4479 | − struct device *dev) | |
| 4499 | +static inline struct subdev_domain_info * | |
| 4500 | +lookup_subdev_info(struct dmar_domain *domain, struct device *dev) | |
| 4501 | +{ | |
| 4502 | + struct subdev_domain_info *sinfo; | |
| 4503 | + | |
| 4504 | + if (!list_empty(&domain->subdevices)) { | |
| 4505 | + list_for_each_entry(sinfo, &domain->subdevices, link_domain) { | |
| 4506 | + if (sinfo->pdev == dev) | |
| 4507 | + return sinfo; | |
| 4508 | + } | |
| 4509 | + } | |
| 4510 | + | |
| 4511 | + return NULL; | |
| 4512 | +} | |
| 4513 | + | |
| 4514 | +static int auxiliary_link_device(struct dmar_domain *domain, | |
| 4515 | + struct device *dev) | |
| 4480 | 4516 | { |
| 4481 | 4517 | struct device_domain_info *info = get_domain_info(dev); |
| 4518 | + struct subdev_domain_info *sinfo = lookup_subdev_info(domain, dev); | |
| 4482 | 4519 | |
| 4483 | 4520 | assert_spin_locked(&device_domain_lock); |
| 4484 | 4521 | if (WARN_ON(!info)) |
| 4485 | − return; | |
| 4522 | + return -EINVAL; | |
| 4486 | 4523 | |
| 4487 | − domain->auxd_refcnt++; | |
| 4488 | − list_add(&domain->auxd, &info->auxiliary_domains); | |
| 4524 | + if (!sinfo) { | |
| 4525 | + sinfo = kzalloc(sizeof(*sinfo), GFP_ATOMIC); | |
| 4526 | + sinfo->domain = domain; | |
| 4527 | + sinfo->pdev = dev; | |
| 4528 | + list_add(&sinfo->link_phys, &info->subdevices); | |
| 4529 | + list_add(&sinfo->link_domain, &domain->subdevices); | |
| 4530 | + } | |
| 4531 | + | |
| 4532 | + return ++sinfo->users; | |
| 4489 | 4533 | } |
| 4490 | 4534 | |
| 4491 | −static void auxiliary_unlink_device(struct dmar_domain *domain, | |
| 4492 | − struct device *dev) | |
| 4535 | +static int auxiliary_unlink_device(struct dmar_domain *domain, | |
| 4536 | + struct device *dev) | |
| 4493 | 4537 | { |
| 4494 | 4538 | struct device_domain_info *info = get_domain_info(dev); |
| 4539 | + struct subdev_domain_info *sinfo = lookup_subdev_info(domain, dev); | |
| 4540 | + int ret; | |
| 4495 | 4541 | |
| 4496 | 4542 | assert_spin_locked(&device_domain_lock); |
| 4497 | − if (WARN_ON(!info)) | |
| 4498 | − return; | |
| 4543 | + if (WARN_ON(!info || !sinfo || sinfo->users <= 0)) | |
| 4544 | + return -EINVAL; | |
| 4499 | 4545 | |
| 4500 | − list_del(&domain->auxd); | |
| 4501 | − domain->auxd_refcnt--; | |
| 4546 | + ret = --sinfo->users; | |
| 4547 | + if (!ret) { | |
| 4548 | + list_del(&sinfo->link_phys); | |
| 4549 | + list_del(&sinfo->link_domain); | |
| 4550 | + kfree(sinfo); | |
| 4551 | + } | |
| 4502 | 4552 | |
| 4503 | − if (!domain->auxd_refcnt && domain->default_pasid > 0) | |
| 4504 | − ioasid_put(domain->default_pasid); | |
| 4553 | + return ret; | |
| 4505 | 4554 | } |
| 4506 | 4555 | |
| 4507 | 4556 | static int aux_domain_add_dev(struct dmar_domain *domain, |
| @@ -4530,6 +4579,19 @@ static int aux_domain_add_dev(struct dmar_domain *domain, · 22 unmodified lines | ||
| 4530 | 4579 | } |
| 4531 | 4580 | |
| 4532 | 4581 | spin_lock_irqsave(&device_domain_lock, flags); |
| 4582 | + ret = auxiliary_link_device(domain, dev); | |
| 4583 | + if (ret <= 0) | |
| 4584 | + goto link_failed; | |
| 4585 | + | |
| 4586 | + /* | |
| 4587 | + * Subdevices from the same physical device can be attached to the | |
| 4588 | + * same domain. For such cases, only the first subdevice attachment | |
| 4589 | + * needs to go through the full steps in this function. So if ret > | |
| 4590 | + * 1, just goto out. | |
| 4591 | + */ | |
| 4592 | + if (ret > 1) | |
| 4593 | + goto out; | |
| 4594 | + | |
| 4533 | 4595 | /* |
| 4534 | 4596 | * iommu->lock must be held to attach domain to iommu and setup the |
| 4535 | 4597 | * pasid entry for second level translation. |
| @@ -4548,10 +4610,9 @@ static int aux_domain_add_dev(struct dmar_domain *domain, · 12 unmodified lines | ||
| 4548 | 4610 | domain->default_pasid); |
| 4549 | 4611 | if (ret) |
| 4550 | 4612 | goto table_failed; |
| 4551 | − spin_unlock(&iommu->lock); | |
| 4552 | − | |
| 4553 | − auxiliary_link_device(domain, dev); | |
| 4554 | 4613 | |
| 4614 | + spin_unlock(&iommu->lock); | |
| 4615 | +out: | |
| 4555 | 4616 | spin_unlock_irqrestore(&device_domain_lock, flags); |
| 4556 | 4617 | |
| 4557 | 4618 | return 0; |
| @@ -4560,8 +4621,10 @@ table_failed: · 2 unmodified lines | ||
| 4560 | 4621 | domain_detach_iommu(domain, iommu); |
| 4561 | 4622 | attach_failed: |
| 4562 | 4623 | spin_unlock(&iommu->lock); |
| 4624 | + auxiliary_unlink_device(domain, dev); | |
| 4625 | +link_failed: | |
| 4563 | 4626 | spin_unlock_irqrestore(&device_domain_lock, flags); |
| 4564 | − if (!domain->auxd_refcnt && domain->default_pasid > 0) | |
| 4627 | + if (list_empty(&domain->subdevices) && domain->default_pasid > 0) | |
| 4565 | 4628 | ioasid_put(domain->default_pasid); |
| 4566 | 4629 | |
| 4567 | 4630 | return ret; |
| @@ -4581,14 +4644,18 @@ static void aux_domain_remove_dev(struct dmar_domain *domain, · 13 unmodified lines | ||
| 4581 | 4644 | info = get_domain_info(dev); |
| 4582 | 4645 | iommu = info->iommu; |
| 4583 | 4646 | |
| 4584 | − auxiliary_unlink_device(domain, dev); | |
| 4585 | − | |
| 4586 | − spin_lock(&iommu->lock); | |
| 4587 | − intel_pasid_tear_down_entry(iommu, dev, domain->default_pasid, false); | |
| 4588 | − domain_detach_iommu(domain, iommu); | |
| 4589 | − spin_unlock(&iommu->lock); | |
| 4647 | + if (!auxiliary_unlink_device(domain, dev)) { | |
| 4648 | + spin_lock(&iommu->lock); | |
| 4649 | + intel_pasid_tear_down_entry(iommu, dev, | |
| 4650 | + domain->default_pasid, false); | |
| 4651 | + domain_detach_iommu(domain, iommu); | |
| 4652 | + spin_unlock(&iommu->lock); | |
| 4653 | + } | |
| 4590 | 4654 | |
| 4591 | 4655 | spin_unlock_irqrestore(&device_domain_lock, flags); |
| 4656 | + | |
| 4657 | + if (list_empty(&domain->subdevices) && domain->default_pasid > 0) | |
| 4658 | + ioasid_put(domain->default_pasid); | |
| 4592 | 4659 | } |
| 4593 | 4660 | |
| 4594 | 4661 | static int prepare_domain_attach_device(struct iommu_domain *domain, |
| @@ -1353,6 +1353,8 @@ static int intel_irq_remapping_alloc(struct irq_domain *domain, · 1352 unmodified lines | ||
| 1353 | 1353 | irq_data = irq_domain_get_irq_data(domain, virq + i); |
| 1354 | 1354 | irq_cfg = irqd_cfg(irq_data); |
| 1355 | 1355 | if (!irq_data || !irq_cfg) { |
| 1356 | + if (!i) | |
| 1357 | + kfree(data); | |
| 1356 | 1358 | ret = -EINVAL; |
| 1357 | 1359 | goto out_free_data; |
| 1358 | 1360 | } |
| @@ -118,8 +118,10 @@ void intel_svm_check(struct intel_iommu *iommu) · 117 unmodified lines | ||
| 118 | 118 | iommu->flags |= VTD_FLAG_SVM_CAPABLE; |
| 119 | 119 | } |
| 120 | 120 | |
| 121 | −static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_dev *sdev, | |
| 122 | − unsigned long address, unsigned long pages, int ih) | |
| 121 | +static void __flush_svm_range_dev(struct intel_svm *svm, | |
| 122 | + struct intel_svm_dev *sdev, | |
| 123 | + unsigned long address, | |
| 124 | + unsigned long pages, int ih) | |
| 123 | 125 | { |
| 124 | 126 | struct qi_desc desc; |
| 125 | 127 | |
| @@ -142,7 +144,7 @@ static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_d · 16 unmodified lines | ||
| 142 | 144 | } |
| 143 | 145 | desc.qw2 = 0; |
| 144 | 146 | desc.qw3 = 0; |
| 145 | − qi_submit_sync(svm->iommu, &desc, 1, 0); | |
| 147 | + qi_submit_sync(sdev->iommu, &desc, 1, 0); | |
| 146 | 148 | |
| 147 | 149 | if (sdev->dev_iotlb) { |
| 148 | 150 | desc.qw0 = QI_DEV_EIOTLB_PASID(svm->pasid) | |
| @@ -166,7 +168,23 @@ static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_d · 17 unmodified lines | ||
| 166 | 168 | } |
| 167 | 169 | desc.qw2 = 0; |
| 168 | 170 | desc.qw3 = 0; |
| 169 | − qi_submit_sync(svm->iommu, &desc, 1, 0); | |
| 171 | + qi_submit_sync(sdev->iommu, &desc, 1, 0); | |
| 172 | + } | |
| 173 | +} | |
| 174 | + | |
| 175 | +static void intel_flush_svm_range_dev(struct intel_svm *svm, | |
| 176 | + struct intel_svm_dev *sdev, | |
| 177 | + unsigned long address, | |
| 178 | + unsigned long pages, int ih) | |
| 179 | +{ | |
| 180 | + unsigned long shift = ilog2(__roundup_pow_of_two(pages)); | |
| 181 | + unsigned long align = (1ULL << (VTD_PAGE_SHIFT + shift)); | |
| 182 | + unsigned long start = ALIGN_DOWN(address, align); | |
| 183 | + unsigned long end = ALIGN(address + (pages << VTD_PAGE_SHIFT), align); | |
| 184 | + | |
| 185 | + while (start < end) { | |
| 186 | + __flush_svm_range_dev(svm, sdev, start, align >> VTD_PAGE_SHIFT, ih); | |
| 187 | + start += align; | |
| 170 | 188 | } |
| 171 | 189 | } |
| 172 | 190 | |
| @@ -211,7 +229,7 @@ static void intel_mm_release(struct mmu_notifier *mn, struct mm_struct *mm) · 38 unmodified lines | ||
| 211 | 229 | */ |
| 212 | 230 | rcu_read_lock(); |
| 213 | 231 | list_for_each_entry_rcu(sdev, &svm->devs, list) |
| 214 | − intel_pasid_tear_down_entry(svm->iommu, sdev->dev, | |
| 232 | + intel_pasid_tear_down_entry(sdev->iommu, sdev->dev, | |
| 215 | 233 | svm->pasid, true); |
| 216 | 234 | rcu_read_unlock(); |
| 217 | 235 | |
| @@ -281,6 +299,7 @@ int intel_svm_bind_gpasid(struct iommu_domain *domain, struct device *dev, · 63 unmodified lines | ||
| 281 | 299 | struct dmar_domain *dmar_domain; |
| 282 | 300 | struct device_domain_info *info; |
| 283 | 301 | struct intel_svm *svm = NULL; |
| 302 | + unsigned long iflags; | |
| 284 | 303 | int ret = 0; |
| 285 | 304 | |
| 286 | 305 | if (WARN_ON(!iommu) || !data) |
| @@ -363,6 +382,7 @@ int intel_svm_bind_gpasid(struct iommu_domain *domain, struct device *dev, · 76 unmodified lines | ||
| 363 | 382 | } |
| 364 | 383 | sdev->dev = dev; |
| 365 | 384 | sdev->sid = PCI_DEVID(info->bus, info->devfn); |
| 385 | + sdev->iommu = iommu; | |
| 366 | 386 | |
| 367 | 387 | /* Only count users if device has aux domains */ |
| 368 | 388 | if (iommu_dev_feature_enabled(dev, IOMMU_DEV_FEAT_AUX)) |
| @@ -381,12 +401,12 @@ int intel_svm_bind_gpasid(struct iommu_domain *domain, struct device *dev, · 12 unmodified lines | ||
| 381 | 401 | * each bind of a new device even with an existing PASID, we need to |
| 382 | 402 | * call the nested mode setup function here. |
| 383 | 403 | */ |
| 384 | − spin_lock(&iommu->lock); | |
| 404 | + spin_lock_irqsave(&iommu->lock, iflags); | |
| 385 | 405 | ret = intel_pasid_setup_nested(iommu, dev, |
| 386 | 406 | (pgd_t *)(uintptr_t)data->gpgd, |
| 387 | 407 | data->hpasid, &data->vendor.vtd, dmar_domain, |
| 388 | 408 | data->addr_width); |
| 389 | − spin_unlock(&iommu->lock); | |
| 409 | + spin_unlock_irqrestore(&iommu->lock, iflags); | |
| 390 | 410 | if (ret) { |
| 391 | 411 | dev_err_ratelimited(dev, "Failed to set up PASID %llu in nested mode, Err %d\n", |
| 392 | 412 | data->hpasid, ret); |
| @@ -486,6 +506,7 @@ intel_svm_bind_mm(struct device *dev, unsigned int flags, · 93 unmodified lines | ||
| 486 | 506 | struct device_domain_info *info; |
| 487 | 507 | struct intel_svm_dev *sdev; |
| 488 | 508 | struct intel_svm *svm = NULL; |
| 509 | + unsigned long iflags; | |
| 489 | 510 | int pasid_max; |
| 490 | 511 | int ret; |
| 491 | 512 | |
| @@ -546,6 +567,7 @@ intel_svm_bind_mm(struct device *dev, unsigned int flags, · 54 unmodified lines | ||
| 546 | 567 | goto out; |
| 547 | 568 | } |
| 548 | 569 | sdev->dev = dev; |
| 570 | + sdev->iommu = iommu; | |
| 549 | 571 | |
| 550 | 572 | ret = intel_iommu_enable_pasid(iommu, dev); |
| 551 | 573 | if (ret) { |
| @@ -575,7 +597,6 @@ intel_svm_bind_mm(struct device *dev, unsigned int flags, · 23 unmodified lines | ||
| 575 | 597 | kfree(sdev); |
| 576 | 598 | goto out; |
| 577 | 599 | } |
| 578 | − svm->iommu = iommu; | |
| 579 | 600 | |
| 580 | 601 | if (pasid_max > intel_pasid_max_id) |
| 581 | 602 | pasid_max = intel_pasid_max_id; |
| @@ -605,14 +626,14 @@ intel_svm_bind_mm(struct device *dev, unsigned int flags, · 23 unmodified lines | ||
| 605 | 626 | } |
| 606 | 627 | } |
| 607 | 628 | |
| 608 | − spin_lock(&iommu->lock); | |
| 629 | + spin_lock_irqsave(&iommu->lock, iflags); | |
| 609 | 630 | ret = intel_pasid_setup_first_level(iommu, dev, |
| 610 | 631 | mm ? mm->pgd : init_mm.pgd, |
| 611 | 632 | svm->pasid, FLPT_DEFAULT_DID, |
| 612 | 633 | (mm ? 0 : PASID_FLAG_SUPERVISOR_MODE) | |
| 613 | 634 | (cpu_feature_enabled(X86_FEATURE_LA57) ? |
| 614 | 635 | PASID_FLAG_FL5LP : 0)); |
| 615 | − spin_unlock(&iommu->lock); | |
| 636 | + spin_unlock_irqrestore(&iommu->lock, iflags); | |
| 616 | 637 | if (ret) { |
| 617 | 638 | if (mm) |
| 618 | 639 | mmu_notifier_unregister(&svm->notifier, mm); |
| @@ -632,14 +653,14 @@ intel_svm_bind_mm(struct device *dev, unsigned int flags, · 13 unmodified lines | ||
| 632 | 653 | * Binding a new device with existing PASID, need to setup |
| 633 | 654 | * the PASID entry. |
| 634 | 655 | */ |
| 635 | − spin_lock(&iommu->lock); | |
| 656 | + spin_lock_irqsave(&iommu->lock, iflags); | |
| 636 | 657 | ret = intel_pasid_setup_first_level(iommu, dev, |
| 637 | 658 | mm ? mm->pgd : init_mm.pgd, |
| 638 | 659 | svm->pasid, FLPT_DEFAULT_DID, |
| 639 | 660 | (mm ? 0 : PASID_FLAG_SUPERVISOR_MODE) | |
| 640 | 661 | (cpu_feature_enabled(X86_FEATURE_LA57) ? |
| 641 | 662 | PASID_FLAG_FL5LP : 0)); |
| 642 | − spin_unlock(&iommu->lock); | |
| 663 | + spin_unlock_irqrestore(&iommu->lock, iflags); | |
| 643 | 664 | if (ret) { |
| 644 | 665 | kfree(sdev); |
| 645 | 666 | goto out; |
| @@ -358,7 +358,7 @@ static void private_free_iova(struct iova_domain *iovad, struct iova *iova) · 357 unmodified lines | ||
| 358 | 358 | * @iovad: - iova domain in question. |
| 359 | 359 | * @pfn: - page frame number |
| 360 | 360 | * This function finds and returns an iova belonging to the |
| 361 | − * given doamin which matches the given pfn. | |
| 361 | + * given domain which matches the given pfn. | |
| 362 | 362 | */ |
| 363 | 363 | struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn) |
| 364 | 364 | { |
| @@ -601,7 +601,7 @@ void queue_iova(struct iova_domain *iovad, · 236 unmodified lines | ||
| 601 | 601 | EXPORT_SYMBOL_GPL(queue_iova); |
| 602 | 602 | |
| 603 | 603 | /** |
| 604 | − * put_iova_domain - destroys the iova doamin | |
| 604 | + * put_iova_domain - destroys the iova domain | |
| 605 | 605 | * @iovad: - iova domain in question. |
| 606 | 606 | * All the iova's in that domain are destroyed. |
| 607 | 607 | */ |
| @@ -712,9 +712,9 @@ EXPORT_SYMBOL_GPL(reserve_iova); · 104 unmodified lines | ||
| 712 | 712 | |
| 713 | 713 | /** |
| 714 | 714 | * copy_reserved_iova - copies the reserved between domains |
| 715 | − * @from: - source doamin from where to copy | |
| 715 | + * @from: - source domain from where to copy | |
| 716 | 716 | * @to: - destination domin where to copy |
| 717 | − * This function copies reserved iova's from one doamin to | |
| 717 | + * This function copies reserved iova's from one domain to | |
| 718 | 718 | * other. |
| 719 | 719 | */ |
| 720 | 720 | void |
| @@ -13,6 +13,7 @@ if MISDN != n · 12 unmodified lines | ||
| 13 | 13 | config MISDN_DSP |
| 14 | 14 | tristate "Digital Audio Processing of transparent data" |
| 15 | 15 | depends on MISDN |
| 16 | + select BITREVERSE | |
| 16 | 17 | help |
| 17 | 18 | Enable support for digital audio processing capability. |
| 18 | 19 | |
| @@ -19,6 +19,7 @@ if NVM · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | config NVM_PBLK |
| 21 | 21 | tristate "Physical Block Device Open-Channel SSD target" |
| 22 | + select CRC32 | |
| 22 | 23 | help |
| 23 | 24 | Allows an open-channel SSD to be exposed as a block device to the |
| 24 | 25 | host. The target assumes the device exposes raw flash and must be |
| @@ -605,6 +605,7 @@ config DM_INTEGRITY · 604 unmodified lines | ||
| 605 | 605 | select BLK_DEV_INTEGRITY |
| 606 | 606 | select DM_BUFIO |
| 607 | 607 | select CRYPTO |
| 608 | + select CRYPTO_SKCIPHER | |
| 608 | 609 | select ASYNC_XOR |
| 609 | 610 | help |
| 610 | 611 | This device-mapper target emulates a block device that has |
| @@ -622,6 +623,7 @@ config DM_ZONED · 11 unmodified lines | ||
| 622 | 623 | tristate "Drive-managed zoned block device target support" |
| 623 | 624 | depends on BLK_DEV_DM |
| 624 | 625 | depends on BLK_DEV_ZONED |
| 626 | + select CRC32 | |
| 625 | 627 | help |
| 626 | 628 | This device-mapper target takes a host-managed or host-aware zoned |
| 627 | 629 | block device and exposes most of its capacity as a regular block |
| @@ -17,7 +17,7 @@ struct feature { · 16 unmodified lines | ||
| 17 | 17 | }; |
| 18 | 18 | |
| 19 | 19 | static struct feature feature_list[] = { |
| 20 | − {BCH_FEATURE_INCOMPAT, BCH_FEATURE_INCOMPAT_LARGE_BUCKET, | |
| 20 | + {BCH_FEATURE_INCOMPAT, BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE, | |
| 21 | 21 | "large_bucket"}, |
| 22 | 22 | {0, 0, 0 }, |
| 23 | 23 | }; |
| @@ -13,11 +13,15 @@ · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | /* Feature set definition */ |
| 15 | 15 | /* Incompat feature set */ |
| 16 | −#define BCH_FEATURE_INCOMPAT_LARGE_BUCKET 0x0001 /* 32bit bucket size */ | |
| 16 | +/* 32bit bucket size, obsoleted */ | |
| 17 | +#define BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET 0x0001 | |
| 18 | +/* real bucket size is (1 << bucket_size) */ | |
| 19 | +#define BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE 0x0002 | |
| 17 | 20 | |
| 18 | −#define BCH_FEATURE_COMPAT_SUUP 0 | |
| 19 | −#define BCH_FEATURE_RO_COMPAT_SUUP 0 | |
| 20 | −#define BCH_FEATURE_INCOMPAT_SUUP BCH_FEATURE_INCOMPAT_LARGE_BUCKET | |
| 21 | +#define BCH_FEATURE_COMPAT_SUPP 0 | |
| 22 | +#define BCH_FEATURE_RO_COMPAT_SUPP 0 | |
| 23 | +#define BCH_FEATURE_INCOMPAT_SUPP (BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET| \ | |
| 24 | + BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE) | |
| 21 | 25 | |
| 22 | 26 | #define BCH_HAS_COMPAT_FEATURE(sb, mask) \ |
| 23 | 27 | ((sb)->feature_compat & (mask)) |
| @@ -77,7 +81,23 @@ static inline void bch_clear_feature_##name(struct cache_sb *sb) \ · 53 unmodified lines | ||
| 77 | 81 | ~BCH##_FEATURE_INCOMPAT_##flagname; \ |
| 78 | 82 | } |
| 79 | 83 | |
| 80 | −BCH_FEATURE_INCOMPAT_FUNCS(large_bucket, LARGE_BUCKET); | |
| 84 | +BCH_FEATURE_INCOMPAT_FUNCS(obso_large_bucket, OBSO_LARGE_BUCKET); | |
| 85 | +BCH_FEATURE_INCOMPAT_FUNCS(large_bucket, LOG_LARGE_BUCKET_SIZE); | |
| 86 | + | |
| 87 | +static inline bool bch_has_unknown_compat_features(struct cache_sb *sb) | |
| 88 | +{ | |
| 89 | + return ((sb->feature_compat & ~BCH_FEATURE_COMPAT_SUPP) != 0); | |
| 90 | +} | |
| 91 | + | |
| 92 | +static inline bool bch_has_unknown_ro_compat_features(struct cache_sb *sb) | |
| 93 | +{ | |
| 94 | + return ((sb->feature_ro_compat & ~BCH_FEATURE_RO_COMPAT_SUPP) != 0); | |
| 95 | +} | |
| 96 | + | |
| 97 | +static inline bool bch_has_unknown_incompat_features(struct cache_sb *sb) | |
| 98 | +{ | |
| 99 | + return ((sb->feature_incompat & ~BCH_FEATURE_INCOMPAT_SUPP) != 0); | |
| 100 | +} | |
| 81 | 101 | |
| 82 | 102 | int bch_print_cache_set_feature_compat(struct cache_set *c, char *buf, int size); |
| 83 | 103 | int bch_print_cache_set_feature_ro_compat(struct cache_set *c, char *buf, int size); |
| @@ -64,9 +64,25 @@ static unsigned int get_bucket_size(struct cache_sb *sb, struct cache_sb_disk *s · 63 unmodified lines | ||
| 64 | 64 | { |
| 65 | 65 | unsigned int bucket_size = le16_to_cpu(s->bucket_size); |
| 66 | 66 | |
| 67 | − if (sb->version >= BCACHE_SB_VERSION_CDEV_WITH_FEATURES && | |
| 68 | − bch_has_feature_large_bucket(sb)) | |
| 69 | − bucket_size |= le16_to_cpu(s->bucket_size_hi) << 16; | |
| 67 | + if (sb->version >= BCACHE_SB_VERSION_CDEV_WITH_FEATURES) { | |
| 68 | + if (bch_has_feature_large_bucket(sb)) { | |
| 69 | + unsigned int max, order; | |
| 70 | + | |
| 71 | + max = sizeof(unsigned int) * BITS_PER_BYTE - 1; | |
| 72 | + order = le16_to_cpu(s->bucket_size); | |
| 73 | + /* | |
| 74 | + * bcache tool will make sure the overflow won't | |
| 75 | + * happen, an error message here is enough. | |
| 76 | + */ | |
| 77 | + if (order > max) | |
| 78 | + pr_err("Bucket size (1 << %u) overflows\n", | |
| 79 | + order); | |
| 80 | + bucket_size = 1 << order; | |
| 81 | + } else if (bch_has_feature_obso_large_bucket(sb)) { | |
| 82 | + bucket_size += | |
| 83 | + le16_to_cpu(s->obso_bucket_size_hi) << 16; | |
| 84 | + } | |
| 85 | + } | |
| 70 | 86 | |
| 71 | 87 | return bucket_size; |
| 72 | 88 | } |
| @@ -228,6 +244,20 @@ static const char *read_super(struct cache_sb *sb, struct block_device *bdev, · 155 unmodified lines | ||
| 228 | 244 | sb->feature_compat = le64_to_cpu(s->feature_compat); |
| 229 | 245 | sb->feature_incompat = le64_to_cpu(s->feature_incompat); |
| 230 | 246 | sb->feature_ro_compat = le64_to_cpu(s->feature_ro_compat); |
| 247 | + | |
| 248 | + /* Check incompatible features */ | |
| 249 | + err = "Unsupported compatible feature found"; | |
| 250 | + if (bch_has_unknown_compat_features(sb)) | |
| 251 | + goto err; | |
| 252 | + | |
| 253 | + err = "Unsupported read-only compatible feature found"; | |
| 254 | + if (bch_has_unknown_ro_compat_features(sb)) | |
| 255 | + goto err; | |
| 256 | + | |
| 257 | + err = "Unsupported incompatible feature found"; | |
| 258 | + if (bch_has_unknown_incompat_features(sb)) | |
| 259 | + goto err; | |
| 260 | + | |
| 231 | 261 | err = read_super_common(sb, bdev, s); |
| 232 | 262 | if (err) |
| 233 | 263 | goto err; |
| @@ -1302,6 +1332,12 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c, · 1068 unmodified lines | ||
| 1302 | 1332 | bcache_device_link(&dc->disk, c, "bdev"); |
| 1303 | 1333 | atomic_inc(&c->attached_dev_nr); |
| 1304 | 1334 | |
| 1335 | + if (bch_has_feature_obso_large_bucket(&(c->cache->sb))) { | |
| 1336 | + pr_err("The obsoleted large bucket layout is unsupported, set the bcache device into read-only\n"); | |
| 1337 | + pr_err("Please update to the latest bcache-tools to create the cache device\n"); | |
| 1338 | + set_disk_ro(dc->disk.disk, 1); | |
| 1339 | + } | |
| 1340 | + | |
| 1305 | 1341 | /* Allow the writeback thread to proceed */ |
| 1306 | 1342 | up_write(&dc->writeback_lock); |
| 1307 | 1343 | |
| @@ -1524,6 +1560,12 @@ static int flash_dev_run(struct cache_set *c, struct uuid_entry *u) · 216 unmodified lines | ||
| 1524 | 1560 | |
| 1525 | 1561 | bcache_device_link(d, c, "volume"); |
| 1526 | 1562 | |
| 1563 | + if (bch_has_feature_obso_large_bucket(&c->cache->sb)) { | |
| 1564 | + pr_err("The obsoleted large bucket layout is unsupported, set the bcache device into read-only\n"); | |
| 1565 | + pr_err("Please update to the latest bcache-tools to create the cache device\n"); | |
| 1566 | + set_disk_ro(d->disk, 1); | |
| 1567 | + } | |
| 1568 | + | |
| 1527 | 1569 | return 0; |
| 1528 | 1570 | err: |
| 1529 | 1571 | kobject_put(&d->kobj); |
| @@ -2083,6 +2125,9 @@ static int run_cache_set(struct cache_set *c) · 553 unmodified lines | ||
| 2083 | 2125 | c->cache->sb.last_mount = (u32)ktime_get_real_seconds(); |
| 2084 | 2126 | bcache_write_super(c); |
| 2085 | 2127 | |
| 2128 | + if (bch_has_feature_obso_large_bucket(&c->cache->sb)) | |
| 2129 | + pr_err("Detect obsoleted large bucket layout, all attached bcache device will be read-only\n"); | |
| 2130 | + | |
| 2086 | 2131 | list_for_each_entry_safe(dc, t, &uncached_devices, list) |
| 2087 | 2132 | bch_cached_dev_attach(dc, c, NULL); |
| 2088 | 2133 | |
| @@ -2644,8 +2689,8 @@ static ssize_t bch_pending_bdevs_cleanup(struct kobject *k, · 555 unmodified lines | ||
| 2644 | 2689 | } |
| 2645 | 2690 | |
| 2646 | 2691 | list_for_each_entry_safe(pdev, tpdev, &pending_devs, list) { |
| 2692 | + char *pdev_set_uuid = pdev->dc->sb.set_uuid; | |
| 2647 | 2693 | list_for_each_entry_safe(c, tc, &bch_cache_sets, list) { |
| 2648 | − char *pdev_set_uuid = pdev->dc->sb.set_uuid; | |
| 2649 | 2694 | char *set_uuid = c->set_uuid; |
| 2650 | 2695 | |
| 2651 | 2696 | if (!memcmp(pdev_set_uuid, set_uuid, 16)) { |
| @@ -1534,6 +1534,12 @@ sector_t dm_bufio_get_device_size(struct dm_bufio_client *c) · 1533 unmodified lines | ||
| 1534 | 1534 | } |
| 1535 | 1535 | EXPORT_SYMBOL_GPL(dm_bufio_get_device_size); |
| 1536 | 1536 | |
| 1537 | +struct dm_io_client *dm_bufio_get_dm_io_client(struct dm_bufio_client *c) | |
| 1538 | +{ | |
| 1539 | + return c->dm_io; | |
| 1540 | +} | |
| 1541 | +EXPORT_SYMBOL_GPL(dm_bufio_get_dm_io_client); | |
| 1542 | + | |
| 1537 | 1543 | sector_t dm_bufio_get_block_number(struct dm_buffer *b) |
| 1538 | 1544 | { |
| 1539 | 1545 | return b->block; |
| @@ -1454,13 +1454,16 @@ static int crypt_convert_block_skcipher(struct crypt_config *cc, · 1453 unmodified lines | ||
| 1454 | 1454 | static void kcryptd_async_done(struct crypto_async_request *async_req, |
| 1455 | 1455 | int error); |
| 1456 | 1456 | |
| 1457 | −static void crypt_alloc_req_skcipher(struct crypt_config *cc, | |
| 1457 | +static int crypt_alloc_req_skcipher(struct crypt_config *cc, | |
| 1458 | 1458 | struct convert_context *ctx) |
| 1459 | 1459 | { |
| 1460 | 1460 | unsigned key_index = ctx->cc_sector & (cc->tfms_count - 1); |
| 1461 | 1461 | |
| 1462 | − if (!ctx->r.req) | |
| 1463 | − ctx->r.req = mempool_alloc(&cc->req_pool, GFP_NOIO); | |
| 1462 | + if (!ctx->r.req) { | |
| 1463 | + ctx->r.req = mempool_alloc(&cc->req_pool, in_interrupt() ? GFP_ATOMIC : GFP_NOIO); | |
| 1464 | + if (!ctx->r.req) | |
| 1465 | + return -ENOMEM; | |
| 1466 | + } | |
| 1464 | 1467 | |
| 1465 | 1468 | skcipher_request_set_tfm(ctx->r.req, cc->cipher_tfm.tfms[key_index]); |
| 1466 | 1469 | |
| @@ -1471,13 +1474,18 @@ static void crypt_alloc_req_skcipher(struct crypt_config *cc, · 4 unmodified lines | ||
| 1471 | 1474 | skcipher_request_set_callback(ctx->r.req, |
| 1472 | 1475 | CRYPTO_TFM_REQ_MAY_BACKLOG, |
| 1473 | 1476 | kcryptd_async_done, dmreq_of_req(cc, ctx->r.req)); |
| 1477 | + | |
| 1478 | + return 0; | |
| 1474 | 1479 | } |
| 1475 | 1480 | |
| 1476 | −static void crypt_alloc_req_aead(struct crypt_config *cc, | |
| 1481 | +static int crypt_alloc_req_aead(struct crypt_config *cc, | |
| 1477 | 1482 | struct convert_context *ctx) |
| 1478 | 1483 | { |
| 1479 | − if (!ctx->r.req_aead) | |
| 1480 | − ctx->r.req_aead = mempool_alloc(&cc->req_pool, GFP_NOIO); | |
| 1484 | + if (!ctx->r.req) { | |
| 1485 | + ctx->r.req = mempool_alloc(&cc->req_pool, in_interrupt() ? GFP_ATOMIC : GFP_NOIO); | |
| 1486 | + if (!ctx->r.req) | |
| 1487 | + return -ENOMEM; | |
| 1488 | + } | |
| 1481 | 1489 | |
| 1482 | 1490 | aead_request_set_tfm(ctx->r.req_aead, cc->cipher_tfm.tfms_aead[0]); |
| 1483 | 1491 | |
| @@ -1488,15 +1496,17 @@ static void crypt_alloc_req_aead(struct crypt_config *cc, · 4 unmodified lines | ||
| 1488 | 1496 | aead_request_set_callback(ctx->r.req_aead, |
| 1489 | 1497 | CRYPTO_TFM_REQ_MAY_BACKLOG, |
| 1490 | 1498 | kcryptd_async_done, dmreq_of_req(cc, ctx->r.req_aead)); |
| 1499 | + | |
| 1500 | + return 0; | |
| 1491 | 1501 | } |
| 1492 | 1502 | |
| 1493 | −static void crypt_alloc_req(struct crypt_config *cc, | |
| 1503 | +static int crypt_alloc_req(struct crypt_config *cc, | |
| 1494 | 1504 | struct convert_context *ctx) |
| 1495 | 1505 | { |
| 1496 | 1506 | if (crypt_integrity_aead(cc)) |
| 1497 | − crypt_alloc_req_aead(cc, ctx); | |
| 1507 | + return crypt_alloc_req_aead(cc, ctx); | |
| 1498 | 1508 | else |
| 1499 | − crypt_alloc_req_skcipher(cc, ctx); | |
| 1509 | + return crypt_alloc_req_skcipher(cc, ctx); | |
| 1500 | 1510 | } |
| 1501 | 1511 | |
| 1502 | 1512 | static void crypt_free_req_skcipher(struct crypt_config *cc, |
| @@ -1529,17 +1539,28 @@ static void crypt_free_req(struct crypt_config *cc, void *req, struct bio *base_ · 26 unmodified lines | ||
| 1529 | 1539 | * Encrypt / decrypt data from one bio to another one (can be the same one) |
| 1530 | 1540 | */ |
| 1531 | 1541 | static blk_status_t crypt_convert(struct crypt_config *cc, |
| 1532 | − struct convert_context *ctx, bool atomic) | |
| 1542 | + struct convert_context *ctx, bool atomic, bool reset_pending) | |
| 1533 | 1543 | { |
| 1534 | 1544 | unsigned int tag_offset = 0; |
| 1535 | 1545 | unsigned int sector_step = cc->sector_size >> SECTOR_SHIFT; |
| 1536 | 1546 | int r; |
| 1537 | 1547 | |
| 1538 | − atomic_set(&ctx->cc_pending, 1); | |
| 1548 | + /* | |
| 1549 | + * if reset_pending is set we are dealing with the bio for the first time, | |
| 1550 | + * else we're continuing to work on the previous bio, so don't mess with | |
| 1551 | + * the cc_pending counter | |
| 1552 | + */ | |
| 1553 | + if (reset_pending) | |
| 1554 | + atomic_set(&ctx->cc_pending, 1); | |
| 1539 | 1555 | |
| 1540 | 1556 | while (ctx->iter_in.bi_size && ctx->iter_out.bi_size) { |
| 1541 | 1557 | |
| 1542 | − crypt_alloc_req(cc, ctx); | |
| 1558 | + r = crypt_alloc_req(cc, ctx); | |
| 1559 | + if (r) { | |
| 1560 | + complete(&ctx->restart); | |
| 1561 | + return BLK_STS_DEV_RESOURCE; | |
| 1562 | + } | |
| 1563 | + | |
| 1543 | 1564 | atomic_inc(&ctx->cc_pending); |
| 1544 | 1565 | |
| 1545 | 1566 | if (crypt_integrity_aead(cc)) |
| @@ -1553,7 +1574,25 @@ static blk_status_t crypt_convert(struct crypt_config *cc, · 7 unmodified lines | ||
| 1553 | 1574 | * but the driver request queue is full, let's wait. |
| 1554 | 1575 | */ |
| 1555 | 1576 | case -EBUSY: |
| 1556 | − wait_for_completion(&ctx->restart); | |
| 1577 | + if (in_interrupt()) { | |
| 1578 | + if (try_wait_for_completion(&ctx->restart)) { | |
| 1579 | + /* | |
| 1580 | + * we don't have to block to wait for completion, | |
| 1581 | + * so proceed | |
| 1582 | + */ | |
| 1583 | + } else { | |
| 1584 | + /* | |
| 1585 | + * we can't wait for completion without blocking | |
| 1586 | + * exit and continue processing in a workqueue | |
| 1587 | + */ | |
| 1588 | + ctx->r.req = NULL; | |
| 1589 | + ctx->cc_sector += sector_step; | |
| 1590 | + tag_offset++; | |
| 1591 | + return BLK_STS_DEV_RESOURCE; | |
| 1592 | + } | |
| 1593 | + } else { | |
| 1594 | + wait_for_completion(&ctx->restart); | |
| 1595 | + } | |
| 1557 | 1596 | reinit_completion(&ctx->restart); |
| 1558 | 1597 | fallthrough; |
| 1559 | 1598 | /* |
| @@ -1691,6 +1730,12 @@ static void crypt_inc_pending(struct dm_crypt_io *io) · 131 unmodified lines | ||
| 1691 | 1730 | atomic_inc(&io->io_pending); |
| 1692 | 1731 | } |
| 1693 | 1732 | |
| 1733 | +static void kcryptd_io_bio_endio(struct work_struct *work) | |
| 1734 | +{ | |
| 1735 | + struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work); | |
| 1736 | + bio_endio(io->base_bio); | |
| 1737 | +} | |
| 1738 | + | |
| 1694 | 1739 | /* |
| 1695 | 1740 | * One of the bios was finished. Check for completion of |
| 1696 | 1741 | * the whole request and correctly clean up the buffer. |
| @@ -1713,7 +1758,23 @@ static void crypt_dec_pending(struct dm_crypt_io *io) · 16 unmodified lines | ||
| 1713 | 1758 | kfree(io->integrity_metadata); |
| 1714 | 1759 | |
| 1715 | 1760 | base_bio->bi_status = error; |
| 1716 | − bio_endio(base_bio); | |
| 1761 | + | |
| 1762 | + /* | |
| 1763 | + * If we are running this function from our tasklet, | |
| 1764 | + * we can't call bio_endio() here, because it will call | |
| 1765 | + * clone_endio() from dm.c, which in turn will | |
| 1766 | + * free the current struct dm_crypt_io structure with | |
| 1767 | + * our tasklet. In this case we need to delay bio_endio() | |
| 1768 | + * execution to after the tasklet is done and dequeued. | |
| 1769 | + */ | |
| 1770 | + if (tasklet_trylock(&io->tasklet)) { | |
| 1771 | + tasklet_unlock(&io->tasklet); | |
| 1772 | + bio_endio(base_bio); | |
| 1773 | + return; | |
| 1774 | + } | |
| 1775 | + | |
| 1776 | + INIT_WORK(&io->work, kcryptd_io_bio_endio); | |
| 1777 | + queue_work(cc->io_queue, &io->work); | |
| 1717 | 1778 | } |
| 1718 | 1779 | |
| 1719 | 1780 | /* |
| @@ -1945,6 +2006,37 @@ static bool kcryptd_crypt_write_inline(struct crypt_config *cc, · 225 unmodified lines | ||
| 1945 | 2006 | } |
| 1946 | 2007 | } |
| 1947 | 2008 | |
| 2009 | +static void kcryptd_crypt_write_continue(struct work_struct *work) | |
| 2010 | +{ | |
| 2011 | + struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work); | |
| 2012 | + struct crypt_config *cc = io->cc; | |
| 2013 | + struct convert_context *ctx = &io->ctx; | |
| 2014 | + int crypt_finished; | |
| 2015 | + sector_t sector = io->sector; | |
| 2016 | + blk_status_t r; | |
| 2017 | + | |
| 2018 | + wait_for_completion(&ctx->restart); | |
| 2019 | + reinit_completion(&ctx->restart); | |
| 2020 | + | |
| 2021 | + r = crypt_convert(cc, &io->ctx, true, false); | |
| 2022 | + if (r) | |
| 2023 | + io->error = r; | |
| 2024 | + crypt_finished = atomic_dec_and_test(&ctx->cc_pending); | |
| 2025 | + if (!crypt_finished && kcryptd_crypt_write_inline(cc, ctx)) { | |
| 2026 | + /* Wait for completion signaled by kcryptd_async_done() */ | |
| 2027 | + wait_for_completion(&ctx->restart); | |
| 2028 | + crypt_finished = 1; | |
| 2029 | + } | |
| 2030 | + | |
| 2031 | + /* Encryption was already finished, submit io now */ | |
| 2032 | + if (crypt_finished) { | |
| 2033 | + kcryptd_crypt_write_io_submit(io, 0); | |
| 2034 | + io->sector = sector; | |
| 2035 | + } | |
| 2036 | + | |
| 2037 | + crypt_dec_pending(io); | |
| 2038 | +} | |
| 2039 | + | |
| 1948 | 2040 | static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) |
| 1949 | 2041 | { |
| 1950 | 2042 | struct crypt_config *cc = io->cc; |
| @@ -1973,7 +2065,17 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) · 22 unmodified lines | ||
| 1973 | 2065 | |
| 1974 | 2066 | crypt_inc_pending(io); |
| 1975 | 2067 | r = crypt_convert(cc, ctx, |
| 1976 | − test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags)); | |
| 2068 | + test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags), true); | |
| 2069 | + /* | |
| 2070 | + * Crypto API backlogged the request, because its queue was full | |
| 2071 | + * and we're in softirq context, so continue from a workqueue | |
| 2072 | + * (TODO: is it actually possible to be in softirq in the write path?) | |
| 2073 | + */ | |
| 2074 | + if (r == BLK_STS_DEV_RESOURCE) { | |
| 2075 | + INIT_WORK(&io->work, kcryptd_crypt_write_continue); | |
| 2076 | + queue_work(cc->crypt_queue, &io->work); | |
| 2077 | + return; | |
| 2078 | + } | |
| 1977 | 2079 | if (r) |
| 1978 | 2080 | io->error = r; |
| 1979 | 2081 | crypt_finished = atomic_dec_and_test(&ctx->cc_pending); |
| @@ -1998,6 +2100,25 @@ static void kcryptd_crypt_read_done(struct dm_crypt_io *io) · 18 unmodified lines | ||
| 1998 | 2100 | crypt_dec_pending(io); |
| 1999 | 2101 | } |
| 2000 | 2102 | |
| 2103 | +static void kcryptd_crypt_read_continue(struct work_struct *work) | |
| 2104 | +{ | |
| 2105 | + struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work); | |
| 2106 | + struct crypt_config *cc = io->cc; | |
| 2107 | + blk_status_t r; | |
| 2108 | + | |
| 2109 | + wait_for_completion(&io->ctx.restart); | |
| 2110 | + reinit_completion(&io->ctx.restart); | |
| 2111 | + | |
| 2112 | + r = crypt_convert(cc, &io->ctx, true, false); | |
| 2113 | + if (r) | |
| 2114 | + io->error = r; | |
| 2115 | + | |
| 2116 | + if (atomic_dec_and_test(&io->ctx.cc_pending)) | |
| 2117 | + kcryptd_crypt_read_done(io); | |
| 2118 | + | |
| 2119 | + crypt_dec_pending(io); | |
| 2120 | +} | |
| 2121 | + | |
| 2001 | 2122 | static void kcryptd_crypt_read_convert(struct dm_crypt_io *io) |
| 2002 | 2123 | { |
| 2003 | 2124 | struct crypt_config *cc = io->cc; |
| @@ -2009,7 +2130,16 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io) · 5 unmodified lines | ||
| 2009 | 2130 | io->sector); |
| 2010 | 2131 | |
| 2011 | 2132 | r = crypt_convert(cc, &io->ctx, |
| 2012 | − test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags)); | |
| 2133 | + test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags), true); | |
| 2134 | + /* | |
| 2135 | + * Crypto API backlogged the request, because its queue was full | |
| 2136 | + * and we're in softirq context, so continue from a workqueue | |
| 2137 | + */ | |
| 2138 | + if (r == BLK_STS_DEV_RESOURCE) { | |
| 2139 | + INIT_WORK(&io->work, kcryptd_crypt_read_continue); | |
| 2140 | + queue_work(cc->crypt_queue, &io->work); | |
| 2141 | + return; | |
| 2142 | + } | |
| 2013 | 2143 | if (r) |
| 2014 | 2144 | io->error = r; |
| 2015 | 2145 | |
| @@ -2091,8 +2221,12 @@ static void kcryptd_queue_crypt(struct dm_crypt_io *io) · 75 unmodified lines | ||
| 2091 | 2221 | |
| 2092 | 2222 | if ((bio_data_dir(io->base_bio) == READ && test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags)) || |
| 2093 | 2223 | (bio_data_dir(io->base_bio) == WRITE && test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags))) { |
| 2094 | − if (in_irq()) { | |
| 2095 | − /* Crypto API's "skcipher_walk_first() refuses to work in hard IRQ context */ | |
| 2224 | + /* | |
| 2225 | + * in_irq(): Crypto API's skcipher_walk_first() refuses to work in hard IRQ context. | |
| 2226 | + * irqs_disabled(): the kernel may run some IO completion from the idle thread, but | |
| 2227 | + * it is being executed with irqs disabled. | |
| 2228 | + */ | |
| 2229 | + if (in_irq() || irqs_disabled()) { | |
| 2096 | 2230 | tasklet_init(&io->tasklet, kcryptd_crypt_tasklet, (unsigned long)&io->work); |
| 2097 | 2231 | tasklet_schedule(&io->tasklet); |
| 2098 | 2232 | return; |
| @@ -3166,12 +3300,11 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) · 1067 unmodified lines | ||
| 3166 | 3300 | } |
| 3167 | 3301 | |
| 3168 | 3302 | if (test_bit(DM_CRYPT_SAME_CPU, &cc->flags)) |
| 3169 | − cc->crypt_queue = alloc_workqueue("kcryptd-%s", WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM, | |
| 3303 | + cc->crypt_queue = alloc_workqueue("kcryptd/%s", WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM, | |
| 3170 | 3304 | 1, devname); |
| 3171 | 3305 | else |
| 3172 | − cc->crypt_queue = alloc_workqueue("kcryptd-%s", | |
| 3173 | − WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM | | |
| 3174 | − WQ_UNBOUND | WQ_SYSFS, | |
| 3306 | + cc->crypt_queue = alloc_workqueue("kcryptd/%s", | |
| 3307 | + WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM | WQ_UNBOUND, | |
| 3175 | 3308 | num_online_cpus(), devname); |
| 3176 | 3309 | if (!cc->crypt_queue) { |
| 3177 | 3310 | ti->error = "Couldn't create kcryptd queue"; |
| @@ -1379,12 +1379,52 @@ thorough_test: · 1378 unmodified lines | ||
| 1379 | 1379 | #undef MAY_BE_HASH |
| 1380 | 1380 | } |
| 1381 | 1381 | |
| 1382 | −static void dm_integrity_flush_buffers(struct dm_integrity_c *ic) | |
| 1382 | +struct flush_request { | |
| 1383 | + struct dm_io_request io_req; | |
| 1384 | + struct dm_io_region io_reg; | |
| 1385 | + struct dm_integrity_c *ic; | |
| 1386 | + struct completion comp; | |
| 1387 | +}; | |
| 1388 | + | |
| 1389 | +static void flush_notify(unsigned long error, void *fr_) | |
| 1390 | +{ | |
| 1391 | + struct flush_request *fr = fr_; | |
| 1392 | + if (unlikely(error != 0)) | |
| 1393 | + dm_integrity_io_error(fr->ic, "flusing disk cache", -EIO); | |
| 1394 | + complete(&fr->comp); | |
| 1395 | +} | |
| 1396 | + | |
| 1397 | +static void dm_integrity_flush_buffers(struct dm_integrity_c *ic, bool flush_data) | |
| 1383 | 1398 | { |
| 1384 | 1399 | int r; |
| 1400 | + | |
| 1401 | + struct flush_request fr; | |
| 1402 | + | |
| 1403 | + if (!ic->meta_dev) | |
| 1404 | + flush_data = false; | |
| 1405 | + if (flush_data) { | |
| 1406 | + fr.io_req.bi_op = REQ_OP_WRITE, | |
| 1407 | + fr.io_req.bi_op_flags = REQ_PREFLUSH | REQ_SYNC, | |
| 1408 | + fr.io_req.mem.type = DM_IO_KMEM, | |
| 1409 | + fr.io_req.mem.ptr.addr = NULL, | |
| 1410 | + fr.io_req.notify.fn = flush_notify, | |
| 1411 | + fr.io_req.notify.context = &fr; | |
| 1412 | + fr.io_req.client = dm_bufio_get_dm_io_client(ic->bufio), | |
| 1413 | + fr.io_reg.bdev = ic->dev->bdev, | |
| 1414 | + fr.io_reg.sector = 0, | |
| 1415 | + fr.io_reg.count = 0, | |
| 1416 | + fr.ic = ic; | |
| 1417 | + init_completion(&fr.comp); | |
| 1418 | + r = dm_io(&fr.io_req, 1, &fr.io_reg, NULL); | |
| 1419 | + BUG_ON(r); | |
| 1420 | + } | |
| 1421 | + | |
| 1385 | 1422 | r = dm_bufio_write_dirty_buffers(ic->bufio); |
| 1386 | 1423 | if (unlikely(r)) |
| 1387 | 1424 | dm_integrity_io_error(ic, "writing tags", r); |
| 1425 | + | |
| 1426 | + if (flush_data) | |
| 1427 | + wait_for_completion(&fr.comp); | |
| 1388 | 1428 | } |
| 1389 | 1429 | |
| 1390 | 1430 | static void sleep_on_endio_wait(struct dm_integrity_c *ic) |
| @@ -2110,7 +2150,7 @@ offload_to_thread: · 719 unmodified lines | ||
| 2110 | 2150 | |
| 2111 | 2151 | if (unlikely(dio->op == REQ_OP_DISCARD) && likely(ic->mode != 'D')) { |
| 2112 | 2152 | integrity_metadata(&dio->work); |
| 2113 | − dm_integrity_flush_buffers(ic); | |
| 2153 | + dm_integrity_flush_buffers(ic, false); | |
| 2114 | 2154 | |
| 2115 | 2155 | dio->in_flight = (atomic_t)ATOMIC_INIT(1); |
| 2116 | 2156 | dio->completion = NULL; |
| @@ -2195,7 +2235,7 @@ static void integrity_commit(struct work_struct *w) · 78 unmodified lines | ||
| 2195 | 2235 | flushes = bio_list_get(&ic->flush_bio_list); |
| 2196 | 2236 | if (unlikely(ic->mode != 'J')) { |
| 2197 | 2237 | spin_unlock_irq(&ic->endio_wait.lock); |
| 2198 | − dm_integrity_flush_buffers(ic); | |
| 2238 | + dm_integrity_flush_buffers(ic, true); | |
| 2199 | 2239 | goto release_flush_bios; |
| 2200 | 2240 | } |
| 2201 | 2241 | |
| @@ -2409,7 +2449,7 @@ skip_io: · 207 unmodified lines | ||
| 2409 | 2449 | complete_journal_op(&comp); |
| 2410 | 2450 | wait_for_completion_io(&comp.comp); |
| 2411 | 2451 | |
| 2412 | − dm_integrity_flush_buffers(ic); | |
| 2452 | + dm_integrity_flush_buffers(ic, true); | |
| 2413 | 2453 | } |
| 2414 | 2454 | |
| 2415 | 2455 | static void integrity_writer(struct work_struct *w) |
| @@ -2451,7 +2491,7 @@ static void recalc_write_super(struct dm_integrity_c *ic) · 35 unmodified lines | ||
| 2451 | 2491 | { |
| 2452 | 2492 | int r; |
| 2453 | 2493 | |
| 2454 | − dm_integrity_flush_buffers(ic); | |
| 2494 | + dm_integrity_flush_buffers(ic, false); | |
| 2455 | 2495 | if (dm_integrity_failed(ic)) |
| 2456 | 2496 | return; |
| 2457 | 2497 | |
| @@ -2654,7 +2694,7 @@ static void bitmap_flush_work(struct work_struct *work) · 196 unmodified lines | ||
| 2654 | 2694 | unsigned long limit; |
| 2655 | 2695 | struct bio *bio; |
| 2656 | 2696 | |
| 2657 | − dm_integrity_flush_buffers(ic); | |
| 2697 | + dm_integrity_flush_buffers(ic, false); | |
| 2658 | 2698 | |
| 2659 | 2699 | range.logical_sector = 0; |
| 2660 | 2700 | range.n_sectors = ic->provided_data_sectors; |
| @@ -2663,9 +2703,7 @@ static void bitmap_flush_work(struct work_struct *work) · 2 unmodified lines | ||
| 2663 | 2703 | add_new_range_and_wait(ic, &range); |
| 2664 | 2704 | spin_unlock_irq(&ic->endio_wait.lock); |
| 2665 | 2705 | |
| 2666 | − dm_integrity_flush_buffers(ic); | |
| 2667 | − if (ic->meta_dev) | |
| 2668 | − blkdev_issue_flush(ic->dev->bdev, GFP_NOIO); | |
| 2706 | + dm_integrity_flush_buffers(ic, true); | |
| 2669 | 2707 | |
| 2670 | 2708 | limit = ic->provided_data_sectors; |
| 2671 | 2709 | if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)) { |
| @@ -2934,11 +2972,11 @@ static void dm_integrity_postsuspend(struct dm_target *ti) · 262 unmodified lines | ||
| 2934 | 2972 | if (ic->meta_dev) |
| 2935 | 2973 | queue_work(ic->writer_wq, &ic->writer_work); |
| 2936 | 2974 | drain_workqueue(ic->writer_wq); |
| 2937 | − dm_integrity_flush_buffers(ic); | |
| 2975 | + dm_integrity_flush_buffers(ic, true); | |
| 2938 | 2976 | } |
| 2939 | 2977 | |
| 2940 | 2978 | if (ic->mode == 'B') { |
| 2941 | − dm_integrity_flush_buffers(ic); | |
| 2979 | + dm_integrity_flush_buffers(ic, true); | |
| 2942 | 2980 | #if 1 |
| 2943 | 2981 | /* set to 0 to test bitmap replay code */ |
| 2944 | 2982 | init_journal(ic, 0, ic->journal_sections, 0); |
| @@ -3754,7 +3792,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) · 809 unmodified lines | ||
| 3754 | 3792 | unsigned extra_args; |
| 3755 | 3793 | struct dm_arg_set as; |
| 3756 | 3794 | static const struct dm_arg _args[] = { |
| 3757 | − {0, 9, "Invalid number of feature args"}, | |
| 3795 | + {0, 15, "Invalid number of feature args"}, | |
| 3758 | 3796 | }; |
| 3759 | 3797 | unsigned journal_sectors, interleave_sectors, buffer_sectors, journal_watermark, sync_msec; |
| 3760 | 3798 | bool should_write_sb; |
| @@ -3729,10 +3729,10 @@ static void raid_io_hints(struct dm_target *ti, struct queue_limits *limits) · 3728 unmodified lines | ||
| 3729 | 3729 | blk_limits_io_opt(limits, chunk_size_bytes * mddev_data_stripes(rs)); |
| 3730 | 3730 | |
| 3731 | 3731 | /* |
| 3732 | − * RAID1 and RAID10 personalities require bio splitting, | |
| 3733 | − * RAID0/4/5/6 don't and process large discard bios properly. | |
| 3732 | + * RAID0 and RAID10 personalities require bio splitting, | |
| 3733 | + * RAID1/4/5/6 don't and process large discard bios properly. | |
| 3734 | 3734 | */ |
| 3735 | − if (rs_is_raid1(rs) || rs_is_raid10(rs)) { | |
| 3735 | + if (rs_is_raid0(rs) || rs_is_raid10(rs)) { | |
| 3736 | 3736 | limits->discard_granularity = chunk_size_bytes; |
| 3737 | 3737 | limits->max_discard_sectors = rs->md.chunk_sectors; |
| 3738 | 3738 | } |
| @@ -141,6 +141,11 @@ struct dm_snapshot { · 140 unmodified lines | ||
| 141 | 141 | * for them to be committed. |
| 142 | 142 | */ |
| 143 | 143 | struct bio_list bios_queued_during_merge; |
| 144 | + | |
| 145 | + /* | |
| 146 | + * Flush data after merge. | |
| 147 | + */ | |
| 148 | + struct bio flush_bio; | |
| 144 | 149 | }; |
| 145 | 150 | |
| 146 | 151 | /* |
| @@ -1121,6 +1126,17 @@ shut: · 974 unmodified lines | ||
| 1121 | 1126 | |
| 1122 | 1127 | static void error_bios(struct bio *bio); |
| 1123 | 1128 | |
| 1129 | +static int flush_data(struct dm_snapshot *s) | |
| 1130 | +{ | |
| 1131 | + struct bio *flush_bio = &s->flush_bio; | |
| 1132 | + | |
| 1133 | + bio_reset(flush_bio); | |
| 1134 | + bio_set_dev(flush_bio, s->origin->bdev); | |
| 1135 | + flush_bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; | |
| 1136 | + | |
| 1137 | + return submit_bio_wait(flush_bio); | |
| 1138 | +} | |
| 1139 | + | |
| 1124 | 1140 | static void merge_callback(int read_err, unsigned long write_err, void *context) |
| 1125 | 1141 | { |
| 1126 | 1142 | struct dm_snapshot *s = context; |
| @@ -1134,6 +1150,11 @@ static void merge_callback(int read_err, unsigned long write_err, void *context) · 7 unmodified lines | ||
| 1134 | 1150 | goto shut; |
| 1135 | 1151 | } |
| 1136 | 1152 | |
| 1153 | + if (flush_data(s) < 0) { | |
| 1154 | + DMERR("Flush after merge failed: shutting down merge"); | |
| 1155 | + goto shut; | |
| 1156 | + } | |
| 1157 | + | |
| 1137 | 1158 | if (s->store->type->commit_merge(s->store, |
| 1138 | 1159 | s->num_merging_chunks) < 0) { |
| 1139 | 1160 | DMERR("Write error in exception store: shutting down merge"); |
| @@ -1318,6 +1339,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) · 178 unmodified lines | ||
| 1318 | 1339 | s->first_merging_chunk = 0; |
| 1319 | 1340 | s->num_merging_chunks = 0; |
| 1320 | 1341 | bio_list_init(&s->bios_queued_during_merge); |
| 1342 | + bio_init(&s->flush_bio, NULL, 0); | |
| 1321 | 1343 | |
| 1322 | 1344 | /* Allocate hash table for COW data */ |
| 1323 | 1345 | if (init_hash_tables(s)) { |
| @@ -1504,6 +1526,8 @@ static void snapshot_dtr(struct dm_target *ti) · 180 unmodified lines | ||
| 1504 | 1526 | |
| 1505 | 1527 | dm_exception_store_destroy(s->store); |
| 1506 | 1528 | |
| 1529 | + bio_uninit(&s->flush_bio); | |
| 1530 | + | |
| 1507 | 1531 | dm_put_device(ti, s->cow); |
| 1508 | 1532 | |
| 1509 | 1533 | dm_put_device(ti, s->origin); |
| @@ -562,7 +562,7 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode, · 561 unmodified lines | ||
| 562 | 562 | * subset of the parent bdev; require extra privileges. |
| 563 | 563 | */ |
| 564 | 564 | if (!capable(CAP_SYS_RAWIO)) { |
| 565 | − DMWARN_LIMIT( | |
| 565 | + DMDEBUG_LIMIT( | |
| 566 | 566 | "%s: sending ioctl %x to DM device without required privilege.", |
| 567 | 567 | current->comm, cmd); |
| 568 | 568 | r = -ENOIOCTLCMD; |
| @@ -472,8 +472,11 @@ static int allocate_cs(struct hl_device *hdev, struct hl_ctx *ctx, · 471 unmodified lines | ||
| 472 | 472 | cntr = &hdev->aggregated_cs_counters; |
| 473 | 473 | |
| 474 | 474 | cs = kzalloc(sizeof(*cs), GFP_ATOMIC); |
| 475 | − if (!cs) | |
| 475 | + if (!cs) { | |
| 476 | + atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt); | |
| 477 | + atomic64_inc(&cntr->out_of_mem_drop_cnt); | |
| 476 | 478 | return -ENOMEM; |
| 479 | + } | |
| 477 | 480 | |
| 478 | 481 | cs->ctx = ctx; |
| 479 | 482 | cs->submitted = false; |
| @@ -486,6 +489,8 @@ static int allocate_cs(struct hl_device *hdev, struct hl_ctx *ctx, · 6 unmodified lines | ||
| 486 | 489 | |
| 487 | 490 | cs_cmpl = kmalloc(sizeof(*cs_cmpl), GFP_ATOMIC); |
| 488 | 491 | if (!cs_cmpl) { |
| 492 | + atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt); | |
| 493 | + atomic64_inc(&cntr->out_of_mem_drop_cnt); | |
| 489 | 494 | rc = -ENOMEM; |
| 490 | 495 | goto free_cs; |
| 491 | 496 | } |
| @@ -513,6 +518,8 @@ static int allocate_cs(struct hl_device *hdev, struct hl_ctx *ctx, · 21 unmodified lines | ||
| 513 | 518 | cs->jobs_in_queue_cnt = kcalloc(hdev->asic_prop.max_queues, |
| 514 | 519 | sizeof(*cs->jobs_in_queue_cnt), GFP_ATOMIC); |
| 515 | 520 | if (!cs->jobs_in_queue_cnt) { |
| 521 | + atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt); | |
| 522 | + atomic64_inc(&cntr->out_of_mem_drop_cnt); | |
| 516 | 523 | rc = -ENOMEM; |
| 517 | 524 | goto free_fence; |
| 518 | 525 | } |
| @@ -562,7 +569,7 @@ void hl_cs_rollback_all(struct hl_device *hdev) · 43 unmodified lines | ||
| 562 | 569 | for (i = 0 ; i < hdev->asic_prop.completion_queues_count ; i++) |
| 563 | 570 | flush_workqueue(hdev->cq_wq[i]); |
| 564 | 571 | |
| 565 | − /* Make sure we don't have leftovers in the H/W queues mirror list */ | |
| 572 | + /* Make sure we don't have leftovers in the CS mirror list */ | |
| 566 | 573 | list_for_each_entry_safe(cs, tmp, &hdev->cs_mirror_list, mirror_node) { |
| 567 | 574 | cs_get(cs); |
| 568 | 575 | cs->aborted = true; |
| @@ -764,11 +771,14 @@ static int hl_cs_sanity_checks(struct hl_fpriv *hpriv, union hl_cs_args *args) · 195 unmodified lines | ||
| 764 | 771 | |
| 765 | 772 | static int hl_cs_copy_chunk_array(struct hl_device *hdev, |
| 766 | 773 | struct hl_cs_chunk **cs_chunk_array, |
| 767 | − void __user *chunks, u32 num_chunks) | |
| 774 | + void __user *chunks, u32 num_chunks, | |
| 775 | + struct hl_ctx *ctx) | |
| 768 | 776 | { |
| 769 | 777 | u32 size_to_copy; |
| 770 | 778 | |
| 771 | 779 | if (num_chunks > HL_MAX_JOBS_PER_CS) { |
| 780 | + atomic64_inc(&ctx->cs_counters.validation_drop_cnt); | |
| 781 | + atomic64_inc(&hdev->aggregated_cs_counters.validation_drop_cnt); | |
| 772 | 782 | dev_err(hdev->dev, |
| 773 | 783 | "Number of chunks can NOT be larger than %d\n", |
| 774 | 784 | HL_MAX_JOBS_PER_CS); |
| @@ -777,11 +787,16 @@ static int hl_cs_copy_chunk_array(struct hl_device *hdev, · 2 unmodified lines | ||
| 777 | 787 | |
| 778 | 788 | *cs_chunk_array = kmalloc_array(num_chunks, sizeof(**cs_chunk_array), |
| 779 | 789 | GFP_ATOMIC); |
| 780 | − if (!*cs_chunk_array) | |
| 790 | + if (!*cs_chunk_array) { | |
| 791 | + atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt); | |
| 792 | + atomic64_inc(&hdev->aggregated_cs_counters.out_of_mem_drop_cnt); | |
| 781 | 793 | return -ENOMEM; |
| 794 | + } | |
| 782 | 795 | |
| 783 | 796 | size_to_copy = num_chunks * sizeof(struct hl_cs_chunk); |
| 784 | 797 | if (copy_from_user(*cs_chunk_array, chunks, size_to_copy)) { |
| 798 | + atomic64_inc(&ctx->cs_counters.validation_drop_cnt); | |
| 799 | + atomic64_inc(&hdev->aggregated_cs_counters.validation_drop_cnt); | |
| 785 | 800 | dev_err(hdev->dev, "Failed to copy cs chunk array from user\n"); |
| 786 | 801 | kfree(*cs_chunk_array); |
| 787 | 802 | return -EFAULT; |
| @@ -797,6 +812,7 @@ static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks, · 9 unmodified lines | ||
| 797 | 812 | struct hl_device *hdev = hpriv->hdev; |
| 798 | 813 | struct hl_cs_chunk *cs_chunk_array; |
| 799 | 814 | struct hl_cs_counters_atomic *cntr; |
| 815 | + struct hl_ctx *ctx = hpriv->ctx; | |
| 800 | 816 | struct hl_cs_job *job; |
| 801 | 817 | struct hl_cs *cs; |
| 802 | 818 | struct hl_cb *cb; |
| @@ -805,7 +821,8 @@ static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks, · 2 unmodified lines | ||
| 805 | 821 | cntr = &hdev->aggregated_cs_counters; |
| 806 | 822 | *cs_seq = ULLONG_MAX; |
| 807 | 823 | |
| 808 | − rc = hl_cs_copy_chunk_array(hdev, &cs_chunk_array, chunks, num_chunks); | |
| 824 | + rc = hl_cs_copy_chunk_array(hdev, &cs_chunk_array, chunks, num_chunks, | |
| 825 | + hpriv->ctx); | |
| 809 | 826 | if (rc) |
| 810 | 827 | goto out; |
| 811 | 828 | |
| @@ -832,8 +849,8 @@ static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks, · 20 unmodified lines | ||
| 832 | 849 | rc = validate_queue_index(hdev, chunk, &queue_type, |
| 833 | 850 | &is_kernel_allocated_cb); |
| 834 | 851 | if (rc) { |
| 835 | − atomic64_inc(&hpriv->ctx->cs_counters.parsing_drop_cnt); | |
| 836 | − atomic64_inc(&cntr->parsing_drop_cnt); | |
| 852 | + atomic64_inc(&ctx->cs_counters.validation_drop_cnt); | |
| 853 | + atomic64_inc(&cntr->validation_drop_cnt); | |
| 837 | 854 | goto free_cs_object; |
| 838 | 855 | } |
| 839 | 856 | |
| @@ -841,8 +858,8 @@ static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks, · 1 unmodified line | ||
| 841 | 858 | cb = get_cb_from_cs_chunk(hdev, &hpriv->cb_mgr, chunk); |
| 842 | 859 | if (!cb) { |
| 843 | 860 | atomic64_inc( |
| 844 | − &hpriv->ctx->cs_counters.parsing_drop_cnt); | |
| 845 | − atomic64_inc(&cntr->parsing_drop_cnt); | |
| 861 | + &ctx->cs_counters.validation_drop_cnt); | |
| 862 | + atomic64_inc(&cntr->validation_drop_cnt); | |
| 846 | 863 | rc = -EINVAL; |
| 847 | 864 | goto free_cs_object; |
| 848 | 865 | } |
| @@ -856,8 +873,7 @@ static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks, · 7 unmodified lines | ||
| 856 | 873 | job = hl_cs_allocate_job(hdev, queue_type, |
| 857 | 874 | is_kernel_allocated_cb); |
| 858 | 875 | if (!job) { |
| 859 | − atomic64_inc( | |
| 860 | − &hpriv->ctx->cs_counters.out_of_mem_drop_cnt); | |
| 876 | + atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt); | |
| 861 | 877 | atomic64_inc(&cntr->out_of_mem_drop_cnt); |
| 862 | 878 | dev_err(hdev->dev, "Failed to allocate a new job\n"); |
| 863 | 879 | rc = -ENOMEM; |
| @@ -891,7 +907,7 @@ static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks, · 27 unmodified lines | ||
| 891 | 907 | |
| 892 | 908 | rc = cs_parser(hpriv, job); |
| 893 | 909 | if (rc) { |
| 894 | − atomic64_inc(&hpriv->ctx->cs_counters.parsing_drop_cnt); | |
| 910 | + atomic64_inc(&ctx->cs_counters.parsing_drop_cnt); | |
| 895 | 911 | atomic64_inc(&cntr->parsing_drop_cnt); |
| 896 | 912 | dev_err(hdev->dev, |
| 897 | 913 | "Failed to parse JOB %d.%llu.%d, err %d, rejecting the CS\n", |
| @@ -901,8 +917,8 @@ static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks, · 3 unmodified lines | ||
| 901 | 917 | } |
| 902 | 918 | |
| 903 | 919 | if (int_queues_only) { |
| 904 | − atomic64_inc(&hpriv->ctx->cs_counters.parsing_drop_cnt); | |
| 905 | − atomic64_inc(&cntr->parsing_drop_cnt); | |
| 920 | + atomic64_inc(&ctx->cs_counters.validation_drop_cnt); | |
| 921 | + atomic64_inc(&cntr->validation_drop_cnt); | |
| 906 | 922 | dev_err(hdev->dev, |
| 907 | 923 | "Reject CS %d.%llu because only internal queues jobs are present\n", |
| 908 | 924 | cs->ctx->asid, cs->sequence); |
| @@ -1042,7 +1058,7 @@ out: · 133 unmodified lines | ||
| 1042 | 1058 | } |
| 1043 | 1059 | |
| 1044 | 1060 | static int cs_ioctl_extract_signal_seq(struct hl_device *hdev, |
| 1045 | − struct hl_cs_chunk *chunk, u64 *signal_seq) | |
| 1061 | + struct hl_cs_chunk *chunk, u64 *signal_seq, struct hl_ctx *ctx) | |
| 1046 | 1062 | { |
| 1047 | 1063 | u64 *signal_seq_arr = NULL; |
| 1048 | 1064 | u32 size_to_copy, signal_seq_arr_len; |
| @@ -1052,6 +1068,8 @@ static int cs_ioctl_extract_signal_seq(struct hl_device *hdev, · 3 unmodified lines | ||
| 1052 | 1068 | |
| 1053 | 1069 | /* currently only one signal seq is supported */ |
| 1054 | 1070 | if (signal_seq_arr_len != 1) { |
| 1071 | + atomic64_inc(&ctx->cs_counters.validation_drop_cnt); | |
| 1072 | + atomic64_inc(&hdev->aggregated_cs_counters.validation_drop_cnt); | |
| 1055 | 1073 | dev_err(hdev->dev, |
| 1056 | 1074 | "Wait for signal CS supports only one signal CS seq\n"); |
| 1057 | 1075 | return -EINVAL; |
| @@ -1060,13 +1078,18 @@ static int cs_ioctl_extract_signal_seq(struct hl_device *hdev, · 2 unmodified lines | ||
| 1060 | 1078 | signal_seq_arr = kmalloc_array(signal_seq_arr_len, |
| 1061 | 1079 | sizeof(*signal_seq_arr), |
| 1062 | 1080 | GFP_ATOMIC); |
| 1063 | − if (!signal_seq_arr) | |
| 1081 | + if (!signal_seq_arr) { | |
| 1082 | + atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt); | |
| 1083 | + atomic64_inc(&hdev->aggregated_cs_counters.out_of_mem_drop_cnt); | |
| 1064 | 1084 | return -ENOMEM; |
| 1085 | + } | |
| 1065 | 1086 | |
| 1066 | 1087 | size_to_copy = chunk->num_signal_seq_arr * sizeof(*signal_seq_arr); |
| 1067 | 1088 | if (copy_from_user(signal_seq_arr, |
| 1068 | 1089 | u64_to_user_ptr(chunk->signal_seq_arr), |
| 1069 | 1090 | size_to_copy)) { |
| 1091 | + atomic64_inc(&ctx->cs_counters.validation_drop_cnt); | |
| 1092 | + atomic64_inc(&hdev->aggregated_cs_counters.validation_drop_cnt); | |
| 1070 | 1093 | dev_err(hdev->dev, |
| 1071 | 1094 | "Failed to copy signal seq array from user\n"); |
| 1072 | 1095 | rc = -EFAULT; |
| @@ -1153,6 +1176,7 @@ static int cs_ioctl_signal_wait(struct hl_fpriv *hpriv, enum hl_cs_type cs_type, · 80 unmodified lines | ||
| 1153 | 1176 | struct hl_device *hdev = hpriv->hdev; |
| 1154 | 1177 | struct hl_cs_compl *sig_waitcs_cmpl; |
| 1155 | 1178 | u32 q_idx, collective_engine_id = 0; |
| 1179 | + struct hl_cs_counters_atomic *cntr; | |
| 1156 | 1180 | struct hl_fence *sig_fence = NULL; |
| 1157 | 1181 | struct hl_ctx *ctx = hpriv->ctx; |
| 1158 | 1182 | enum hl_queue_type q_type; |
| @@ -1160,9 +1184,11 @@ static int cs_ioctl_signal_wait(struct hl_fpriv *hpriv, enum hl_cs_type cs_type, · 1 unmodified line | ||
| 1160 | 1184 | u64 signal_seq; |
| 1161 | 1185 | int rc; |
| 1162 | 1186 | |
| 1187 | + cntr = &hdev->aggregated_cs_counters; | |
| 1163 | 1188 | *cs_seq = ULLONG_MAX; |
| 1164 | 1189 | |
| 1165 | − rc = hl_cs_copy_chunk_array(hdev, &cs_chunk_array, chunks, num_chunks); | |
| 1190 | + rc = hl_cs_copy_chunk_array(hdev, &cs_chunk_array, chunks, num_chunks, | |
| 1191 | + ctx); | |
| 1166 | 1192 | if (rc) |
| 1167 | 1193 | goto out; |
| 1168 | 1194 | |
| @@ -1170,6 +1196,8 @@ static int cs_ioctl_signal_wait(struct hl_fpriv *hpriv, enum hl_cs_type cs_type, · 1 unmodified line | ||
| 1170 | 1196 | chunk = &cs_chunk_array[0]; |
| 1171 | 1197 | |
| 1172 | 1198 | if (chunk->queue_index >= hdev->asic_prop.max_queues) { |
| 1199 | + atomic64_inc(&ctx->cs_counters.validation_drop_cnt); | |
| 1200 | + atomic64_inc(&cntr->validation_drop_cnt); | |
| 1173 | 1201 | dev_err(hdev->dev, "Queue index %d is invalid\n", |
| 1174 | 1202 | chunk->queue_index); |
| 1175 | 1203 | rc = -EINVAL; |
| @@ -1181,6 +1209,8 @@ static int cs_ioctl_signal_wait(struct hl_fpriv *hpriv, enum hl_cs_type cs_type, · 5 unmodified lines | ||
| 1181 | 1209 | q_type = hw_queue_prop->type; |
| 1182 | 1210 | |
| 1183 | 1211 | if (!hw_queue_prop->supports_sync_stream) { |
| 1212 | + atomic64_inc(&ctx->cs_counters.validation_drop_cnt); | |
| 1213 | + atomic64_inc(&cntr->validation_drop_cnt); | |
| 1184 | 1214 | dev_err(hdev->dev, |
| 1185 | 1215 | "Queue index %d does not support sync stream operations\n", |
| 1186 | 1216 | q_idx); |
| @@ -1190,6 +1220,8 @@ static int cs_ioctl_signal_wait(struct hl_fpriv *hpriv, enum hl_cs_type cs_type, · 3 unmodified lines | ||
| 1190 | 1220 | |
| 1191 | 1221 | if (cs_type == CS_TYPE_COLLECTIVE_WAIT) { |
| 1192 | 1222 | if (!(hw_queue_prop->collective_mode == HL_COLLECTIVE_MASTER)) { |
| 1223 | + atomic64_inc(&ctx->cs_counters.validation_drop_cnt); | |
| 1224 | + atomic64_inc(&cntr->validation_drop_cnt); | |
| 1193 | 1225 | dev_err(hdev->dev, |
| 1194 | 1226 | "Queue index %d is invalid\n", q_idx); |
| 1195 | 1227 | rc = -EINVAL; |
| @@ -1200,12 +1232,14 @@ static int cs_ioctl_signal_wait(struct hl_fpriv *hpriv, enum hl_cs_type cs_type, · 4 unmodified lines | ||
| 1200 | 1232 | } |
| 1201 | 1233 | |
| 1202 | 1234 | if (cs_type == CS_TYPE_WAIT || cs_type == CS_TYPE_COLLECTIVE_WAIT) { |
| 1203 | − rc = cs_ioctl_extract_signal_seq(hdev, chunk, &signal_seq); | |
| 1235 | + rc = cs_ioctl_extract_signal_seq(hdev, chunk, &signal_seq, ctx); | |
| 1204 | 1236 | if (rc) |
| 1205 | 1237 | goto free_cs_chunk_array; |
| 1206 | 1238 | |
| 1207 | 1239 | sig_fence = hl_ctx_get_fence(ctx, signal_seq); |
| 1208 | 1240 | if (IS_ERR(sig_fence)) { |
| 1241 | + atomic64_inc(&ctx->cs_counters.validation_drop_cnt); | |
| 1242 | + atomic64_inc(&cntr->validation_drop_cnt); | |
| 1209 | 1243 | dev_err(hdev->dev, |
| 1210 | 1244 | "Failed to get signal CS with seq 0x%llx\n", |
| 1211 | 1245 | signal_seq); |
| @@ -1223,6 +1257,8 @@ static int cs_ioctl_signal_wait(struct hl_fpriv *hpriv, enum hl_cs_type cs_type, · 11 unmodified lines | ||
| 1223 | 1257 | container_of(sig_fence, struct hl_cs_compl, base_fence); |
| 1224 | 1258 | |
| 1225 | 1259 | if (sig_waitcs_cmpl->type != CS_TYPE_SIGNAL) { |
| 1260 | + atomic64_inc(&ctx->cs_counters.validation_drop_cnt); | |
| 1261 | + atomic64_inc(&cntr->validation_drop_cnt); | |
| 1226 | 1262 | dev_err(hdev->dev, |
| 1227 | 1263 | "CS seq 0x%llx is not of a signal CS\n", |
| 1228 | 1264 | signal_seq); |
| @@ -1270,8 +1306,11 @@ static int cs_ioctl_signal_wait(struct hl_fpriv *hpriv, enum hl_cs_type cs_type, · 41 unmodified lines | ||
| 1270 | 1306 | else if (cs_type == CS_TYPE_COLLECTIVE_WAIT) |
| 1271 | 1307 | rc = hdev->asic_funcs->collective_wait_create_jobs(hdev, ctx, |
| 1272 | 1308 | cs, q_idx, collective_engine_id); |
| 1273 | − else | |
| 1309 | + else { | |
| 1310 | + atomic64_inc(&ctx->cs_counters.validation_drop_cnt); | |
| 1311 | + atomic64_inc(&cntr->validation_drop_cnt); | |
| 1274 | 1312 | rc = -EINVAL; |
| 1313 | + } | |
| 1275 | 1314 | |
| 1276 | 1315 | if (rc) |
| 1277 | 1316 | goto free_cs_object; |
| @@ -17,12 +17,12 @@ enum hl_device_status hl_device_status(struct hl_device *hdev) · 16 unmodified lines | ||
| 17 | 17 | { |
| 18 | 18 | enum hl_device_status status; |
| 19 | 19 | |
| 20 | − if (hdev->disabled) | |
| 21 | − status = HL_DEVICE_STATUS_MALFUNCTION; | |
| 22 | − else if (atomic_read(&hdev->in_reset)) | |
| 20 | + if (atomic_read(&hdev->in_reset)) | |
| 23 | 21 | status = HL_DEVICE_STATUS_IN_RESET; |
| 24 | 22 | else if (hdev->needs_reset) |
| 25 | 23 | status = HL_DEVICE_STATUS_NEEDS_RESET; |
| 24 | + else if (hdev->disabled) | |
| 25 | + status = HL_DEVICE_STATUS_MALFUNCTION; | |
| 26 | 26 | else |
| 27 | 27 | status = HL_DEVICE_STATUS_OPERATIONAL; |
| 28 | 28 | |
| @@ -1092,6 +1092,7 @@ kill_processes: · 1063 unmodified lines | ||
| 1092 | 1092 | GFP_KERNEL); |
| 1093 | 1093 | if (!hdev->kernel_ctx) { |
| 1094 | 1094 | rc = -ENOMEM; |
| 1095 | + hl_mmu_fini(hdev); | |
| 1095 | 1096 | goto out_err; |
| 1096 | 1097 | } |
| 1097 | 1098 | |
| @@ -1103,6 +1104,7 @@ kill_processes: · 5 unmodified lines | ||
| 1103 | 1104 | "failed to init kernel ctx in hard reset\n"); |
| 1104 | 1105 | kfree(hdev->kernel_ctx); |
| 1105 | 1106 | hdev->kernel_ctx = NULL; |
| 1107 | + hl_mmu_fini(hdev); | |
| 1106 | 1108 | goto out_err; |
| 1107 | 1109 | } |
| 1108 | 1110 | } |
| @@ -627,25 +627,38 @@ int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg, · 626 unmodified lines | ||
| 627 | 627 | security_status = RREG32(cpu_security_boot_status_reg); |
| 628 | 628 | |
| 629 | 629 | /* We read security status multiple times during boot: |
| 630 | − * 1. preboot - we check if fw security feature is supported | |
| 631 | − * 2. boot cpu - we get boot cpu security status | |
| 632 | − * 3. FW application - we get FW application security status | |
| 630 | + * 1. preboot - a. Check whether the security status bits are valid | |
| 631 | + * b. Check whether fw security is enabled | |
| 632 | + * c. Check whether hard reset is done by preboot | |
| 633 | + * 2. boot cpu - a. Fetch boot cpu security status | |
| 634 | + * b. Check whether hard reset is done by boot cpu | |
| 635 | + * 3. FW application - a. Fetch fw application security status | |
| 636 | + * b. Check whether hard reset is done by fw app | |
| 633 | 637 | * |
| 634 | 638 | * Preboot: |
| 635 | 639 | * Check security status bit (CPU_BOOT_DEV_STS0_ENABLED), if it is set |
| 636 | 640 | * check security enabled bit (CPU_BOOT_DEV_STS0_SECURITY_EN) |
| 637 | 641 | */ |
| 638 | 642 | if (security_status & CPU_BOOT_DEV_STS0_ENABLED) { |
| 639 | − hdev->asic_prop.fw_security_status_valid = 1; | |
| 640 | − prop->fw_security_disabled = | |
| 641 | − !(security_status & CPU_BOOT_DEV_STS0_SECURITY_EN); | |
| 643 | + prop->fw_security_status_valid = 1; | |
| 644 | + | |
| 645 | + if (security_status & CPU_BOOT_DEV_STS0_SECURITY_EN) | |
| 646 | + prop->fw_security_disabled = false; | |
| 647 | + else | |
| 648 | + prop->fw_security_disabled = true; | |
| 649 | + | |
| 650 | + if (security_status & CPU_BOOT_DEV_STS0_FW_HARD_RST_EN) | |
| 651 | + prop->hard_reset_done_by_fw = true; | |
| 642 | 652 | } else { |
| 643 | − hdev->asic_prop.fw_security_status_valid = 0; | |
| 653 | + prop->fw_security_status_valid = 0; | |
| 644 | 654 | prop->fw_security_disabled = true; |
| 645 | 655 | } |
| 646 | 656 | |
| 657 | + dev_dbg(hdev->dev, "Firmware preboot hard-reset is %s\n", | |
| 658 | + prop->hard_reset_done_by_fw ? "enabled" : "disabled"); | |
| 659 | + | |
| 647 | 660 | dev_info(hdev->dev, "firmware-level security is %s\n", |
| 648 | − prop->fw_security_disabled ? "disabled" : "enabled"); | |
| 661 | + prop->fw_security_disabled ? "disabled" : "enabled"); | |
| 649 | 662 | |
| 650 | 663 | return 0; |
| 651 | 664 | } |
| @@ -655,6 +668,7 @@ int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg, · 3 unmodified lines | ||
| 655 | 668 | u32 cpu_security_boot_status_reg, u32 boot_err0_reg, |
| 656 | 669 | bool skip_bmc, u32 cpu_timeout, u32 boot_fit_timeout) |
| 657 | 670 | { |
| 671 | + struct asic_fixed_properties *prop = &hdev->asic_prop; | |
| 658 | 672 | u32 status; |
| 659 | 673 | int rc; |
| 660 | 674 | |
| @@ -723,11 +737,22 @@ int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg, · 62 unmodified lines | ||
| 723 | 737 | /* Read U-Boot version now in case we will later fail */ |
| 724 | 738 | hdev->asic_funcs->read_device_fw_version(hdev, FW_COMP_UBOOT); |
| 725 | 739 | |
| 740 | + /* Clear reset status since we need to read it again from boot CPU */ | |
| 741 | + prop->hard_reset_done_by_fw = false; | |
| 742 | + | |
| 726 | 743 | /* Read boot_cpu security bits */ |
| 727 | − if (hdev->asic_prop.fw_security_status_valid) | |
| 728 | − hdev->asic_prop.fw_boot_cpu_security_map = | |
| 744 | + if (prop->fw_security_status_valid) { | |
| 745 | + prop->fw_boot_cpu_security_map = | |
| 729 | 746 | RREG32(cpu_security_boot_status_reg); |
| 730 | 747 | |
| 748 | + if (prop->fw_boot_cpu_security_map & | |
| 749 | + CPU_BOOT_DEV_STS0_FW_HARD_RST_EN) | |
| 750 | + prop->hard_reset_done_by_fw = true; | |
| 751 | + } | |
| 752 | + | |
| 753 | + dev_dbg(hdev->dev, "Firmware boot CPU hard-reset is %s\n", | |
| 754 | + prop->hard_reset_done_by_fw ? "enabled" : "disabled"); | |
| 755 | + | |
| 731 | 756 | if (rc) { |
| 732 | 757 | detect_cpu_boot_status(hdev, status); |
| 733 | 758 | rc = -EIO; |
| @@ -796,18 +821,21 @@ int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg, · 62 unmodified lines | ||
| 796 | 821 | goto out; |
| 797 | 822 | } |
| 798 | 823 | |
| 824 | + /* Clear reset status since we need to read again from app */ | |
| 825 | + prop->hard_reset_done_by_fw = false; | |
| 826 | + | |
| 799 | 827 | /* Read FW application security bits */ |
| 800 | − if (hdev->asic_prop.fw_security_status_valid) { | |
| 801 | − hdev->asic_prop.fw_app_security_map = | |
| 828 | + if (prop->fw_security_status_valid) { | |
| 829 | + prop->fw_app_security_map = | |
| 802 | 830 | RREG32(cpu_security_boot_status_reg); |
| 803 | 831 | |
| 804 | − if (hdev->asic_prop.fw_app_security_map & | |
| 832 | + if (prop->fw_app_security_map & | |
| 805 | 833 | CPU_BOOT_DEV_STS0_FW_HARD_RST_EN) |
| 806 | − hdev->asic_prop.hard_reset_done_by_fw = true; | |
| 834 | + prop->hard_reset_done_by_fw = true; | |
| 807 | 835 | } |
| 808 | 836 | |
| 809 | − dev_dbg(hdev->dev, "Firmware hard-reset is %s\n", | |
| 810 | − hdev->asic_prop.hard_reset_done_by_fw ? "enabled" : "disabled"); | |
| 837 | + dev_dbg(hdev->dev, "Firmware application CPU hard-reset is %s\n", | |
| 838 | + prop->hard_reset_done_by_fw ? "enabled" : "disabled"); | |
| 811 | 839 | |
| 812 | 840 | dev_info(hdev->dev, "Successfully loaded firmware to device\n"); |
| 813 | 841 | |
| @@ -944,7 +944,7 @@ struct hl_asic_funcs { · 943 unmodified lines | ||
| 944 | 944 | u32 (*get_signal_cb_size)(struct hl_device *hdev); |
| 945 | 945 | u32 (*get_wait_cb_size)(struct hl_device *hdev); |
| 946 | 946 | u32 (*gen_signal_cb)(struct hl_device *hdev, void *data, u16 sob_id, |
| 947 | − u32 size); | |
| 947 | + u32 size, bool eb); | |
| 948 | 948 | u32 (*gen_wait_cb)(struct hl_device *hdev, |
| 949 | 949 | struct hl_gen_wait_properties *prop); |
| 950 | 950 | void (*reset_sob)(struct hl_device *hdev, void *data); |
| @@ -1000,6 +1000,7 @@ struct hl_va_range { · 49 unmodified lines | ||
| 1000 | 1000 | * @queue_full_drop_cnt: dropped due to queue full |
| 1001 | 1001 | * @device_in_reset_drop_cnt: dropped due to device in reset |
| 1002 | 1002 | * @max_cs_in_flight_drop_cnt: dropped due to maximum CS in-flight |
| 1003 | + * @validation_drop_cnt: dropped due to error in validation | |
| 1003 | 1004 | */ |
| 1004 | 1005 | struct hl_cs_counters_atomic { |
| 1005 | 1006 | atomic64_t out_of_mem_drop_cnt; |
| @@ -1007,6 +1008,7 @@ struct hl_cs_counters_atomic { · 1 unmodified line | ||
| 1007 | 1008 | atomic64_t queue_full_drop_cnt; |
| 1008 | 1009 | atomic64_t device_in_reset_drop_cnt; |
| 1009 | 1010 | atomic64_t max_cs_in_flight_drop_cnt; |
| 1011 | + atomic64_t validation_drop_cnt; | |
| 1010 | 1012 | }; |
| 1011 | 1013 | |
| 1012 | 1014 | /** |
| @@ -544,6 +544,7 @@ static struct pci_driver hl_pci_driver = { · 543 unmodified lines | ||
| 544 | 544 | .id_table = ids, |
| 545 | 545 | .probe = hl_pci_probe, |
| 546 | 546 | .remove = hl_pci_remove, |
| 547 | + .shutdown = hl_pci_remove, | |
| 547 | 548 | .driver.pm = &hl_pm_ops, |
| 548 | 549 | .err_handler = &hl_pci_err_handler, |
| 549 | 550 | }; |
| @@ -335,6 +335,8 @@ static int cs_counters_info(struct hl_fpriv *hpriv, struct hl_info_args *args) · 334 unmodified lines | ||
| 335 | 335 | atomic64_read(&cntr->device_in_reset_drop_cnt); |
| 336 | 336 | cs_counters.total_max_cs_in_flight_drop_cnt = |
| 337 | 337 | atomic64_read(&cntr->max_cs_in_flight_drop_cnt); |
| 338 | + cs_counters.total_validation_drop_cnt = | |
| 339 | + atomic64_read(&cntr->validation_drop_cnt); | |
| 338 | 340 | |
| 339 | 341 | if (hpriv->ctx) { |
| 340 | 342 | cs_counters.ctx_out_of_mem_drop_cnt = |
| @@ -352,6 +354,9 @@ static int cs_counters_info(struct hl_fpriv *hpriv, struct hl_info_args *args) · 11 unmodified lines | ||
| 352 | 354 | cs_counters.ctx_max_cs_in_flight_drop_cnt = |
| 353 | 355 | atomic64_read( |
| 354 | 356 | &hpriv->ctx->cs_counters.max_cs_in_flight_drop_cnt); |
| 357 | + cs_counters.ctx_validation_drop_cnt = | |
| 358 | + atomic64_read( | |
| 359 | + &hpriv->ctx->cs_counters.validation_drop_cnt); | |
| 355 | 360 | } |
| 356 | 361 | |
| 357 | 362 | return copy_to_user(out, &cs_counters, |
| @@ -406,7 +411,7 @@ static int total_energy_consumption_info(struct hl_fpriv *hpriv, · 48 unmodified lines | ||
| 406 | 411 | static int pll_frequency_info(struct hl_fpriv *hpriv, struct hl_info_args *args) |
| 407 | 412 | { |
| 408 | 413 | struct hl_device *hdev = hpriv->hdev; |
| 409 | − struct hl_pll_frequency_info freq_info = {0}; | |
| 414 | + struct hl_pll_frequency_info freq_info = { {0} }; | |
| 410 | 415 | u32 max_size = args->return_size; |
| 411 | 416 | void __user *out = (void __user *) (uintptr_t) args->return_pointer; |
| 412 | 417 | int rc; |
| @@ -418,8 +418,11 @@ static void init_signal_cs(struct hl_device *hdev, · 417 unmodified lines | ||
| 418 | 418 | "generate signal CB, sob_id: %d, sob val: 0x%x, q_idx: %d\n", |
| 419 | 419 | cs_cmpl->hw_sob->sob_id, cs_cmpl->sob_val, q_idx); |
| 420 | 420 | |
| 421 | + /* we set an EB since we must make sure all oeprations are done | |
| 422 | + * when sending the signal | |
| 423 | + */ | |
| 421 | 424 | hdev->asic_funcs->gen_signal_cb(hdev, job->patched_cb, |
| 422 | − cs_cmpl->hw_sob->sob_id, 0); | |
| 425 | + cs_cmpl->hw_sob->sob_id, 0, true); | |
| 423 | 426 | |
| 424 | 427 | kref_get(&hw_sob->kref); |
| 425 | 428 | |
| @@ -130,10 +130,8 @@ static int hl_pci_elbi_write(struct hl_device *hdev, u64 addr, u32 data) · 129 unmodified lines | ||
| 130 | 130 | if ((val & PCI_CONFIG_ELBI_STS_MASK) == PCI_CONFIG_ELBI_STS_DONE) |
| 131 | 131 | return 0; |
| 132 | 132 | |
| 133 | − if (val & PCI_CONFIG_ELBI_STS_ERR) { | |
| 134 | − dev_err(hdev->dev, "Error writing to ELBI\n"); | |
| 133 | + if (val & PCI_CONFIG_ELBI_STS_ERR) | |
| 135 | 134 | return -EIO; |
| 136 | − } | |
| 137 | 135 | |
| 138 | 136 | if (!(val & PCI_CONFIG_ELBI_STS_MASK)) { |
| 139 | 137 | dev_err(hdev->dev, "ELBI write didn't finish in time\n"); |
| @@ -160,8 +158,12 @@ int hl_pci_iatu_write(struct hl_device *hdev, u32 addr, u32 data) · 20 unmodified lines | ||
| 160 | 158 | |
| 161 | 159 | dbi_offset = addr & 0xFFF; |
| 162 | 160 | |
| 163 | − rc = hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr, 0x00300000); | |
| 164 | − rc |= hl_pci_elbi_write(hdev, prop->pcie_dbi_base_address + dbi_offset, | |
| 161 | + /* Ignore result of writing to pcie_aux_dbi_reg_addr as it could fail | |
| 162 | + * in case the firmware security is enabled | |
| 163 | + */ | |
| 164 | + hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr, 0x00300000); | |
| 165 | + | |
| 166 | + rc = hl_pci_elbi_write(hdev, prop->pcie_dbi_base_address + dbi_offset, | |
| 165 | 167 | data); |
| 166 | 168 | |
| 167 | 169 | if (rc) |
| @@ -244,9 +246,11 @@ int hl_pci_set_inbound_region(struct hl_device *hdev, u8 region, · 76 unmodified lines | ||
| 244 | 246 | |
| 245 | 247 | rc |= hl_pci_iatu_write(hdev, offset + 0x4, ctrl_reg_val); |
| 246 | 248 | |
| 247 | − /* Return the DBI window to the default location */ | |
| 248 | − rc |= hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr, 0); | |
| 249 | − rc |= hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr + 4, 0); | |
| 249 | + /* Return the DBI window to the default location | |
| 250 | + * Ignore result of writing to pcie_aux_dbi_reg_addr as it could fail | |
| 251 | + * in case the firmware security is enabled | |
| 252 | + */ | |
| 253 | + hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr, 0); | |
| 250 | 254 | |
| 251 | 255 | if (rc) |
| 252 | 256 | dev_err(hdev->dev, "failed to map bar %u to 0x%08llx\n", |
| @@ -294,9 +298,11 @@ int hl_pci_set_outbound_region(struct hl_device *hdev, · 41 unmodified lines | ||
| 294 | 298 | /* Enable */ |
| 295 | 299 | rc |= hl_pci_iatu_write(hdev, 0x004, 0x80000000); |
| 296 | 300 | |
| 297 | − /* Return the DBI window to the default location */ | |
| 298 | − rc |= hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr, 0); | |
| 299 | − rc |= hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr + 4, 0); | |
| 301 | + /* Return the DBI window to the default location | |
| 302 | + * Ignore result of writing to pcie_aux_dbi_reg_addr as it could fail | |
| 303 | + * in case the firmware security is enabled | |
| 304 | + */ | |
| 305 | + hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr, 0); | |
| 300 | 306 | |
| 301 | 307 | return rc; |
| 302 | 308 | } |
| @@ -151,19 +151,6 @@ static const u16 gaudi_packet_sizes[MAX_PACKET_ID] = { · 150 unmodified lines | ||
| 151 | 151 | [PACKET_LOAD_AND_EXE] = sizeof(struct packet_load_and_exe) |
| 152 | 152 | }; |
| 153 | 153 | |
| 154 | −static const u32 gaudi_pll_base_addresses[GAUDI_PLL_MAX] = { | |
| 155 | − [CPU_PLL] = mmPSOC_CPU_PLL_NR, | |
| 156 | − [PCI_PLL] = mmPSOC_PCI_PLL_NR, | |
| 157 | − [SRAM_PLL] = mmSRAM_W_PLL_NR, | |
| 158 | − [HBM_PLL] = mmPSOC_HBM_PLL_NR, | |
| 159 | − [NIC_PLL] = mmNIC0_PLL_NR, | |
| 160 | − [DMA_PLL] = mmDMA_W_PLL_NR, | |
| 161 | − [MESH_PLL] = mmMESH_W_PLL_NR, | |
| 162 | − [MME_PLL] = mmPSOC_MME_PLL_NR, | |
| 163 | − [TPC_PLL] = mmPSOC_TPC_PLL_NR, | |
| 164 | − [IF_PLL] = mmIF_W_PLL_NR | |
| 165 | −}; | |
| 166 | − | |
| 167 | 154 | static inline bool validate_packet_id(enum packet_id id) |
| 168 | 155 | { |
| 169 | 156 | switch (id) { |
| @@ -374,7 +361,7 @@ static int gaudi_cpucp_info_get(struct hl_device *hdev); · 204 unmodified lines | ||
| 374 | 361 | static void gaudi_disable_clock_gating(struct hl_device *hdev); |
| 375 | 362 | static void gaudi_mmu_prepare(struct hl_device *hdev, u32 asid); |
| 376 | 363 | static u32 gaudi_gen_signal_cb(struct hl_device *hdev, void *data, u16 sob_id, |
| 377 | − u32 size); | |
| 364 | + u32 size, bool eb); | |
| 378 | 365 | static u32 gaudi_gen_wait_cb(struct hl_device *hdev, |
| 379 | 366 | struct hl_gen_wait_properties *prop); |
| 380 | 367 | |
| @@ -667,12 +654,6 @@ static int gaudi_early_init(struct hl_device *hdev) · 286 unmodified lines | ||
| 667 | 654 | if (rc) |
| 668 | 655 | goto free_queue_props; |
| 669 | 656 | |
| 670 | − if (gaudi_get_hw_state(hdev) == HL_DEVICE_HW_STATE_DIRTY) { | |
| 671 | − dev_info(hdev->dev, | |
| 672 | − "H/W state is dirty, must reset before initializing\n"); | |
| 673 | − hdev->asic_funcs->hw_fini(hdev, true); | |
| 674 | − } | |
| 675 | − | |
| 676 | 657 | /* Before continuing in the initialization, we need to read the preboot |
| 677 | 658 | * version to determine whether we run with a security-enabled firmware |
| 678 | 659 | */ |
| @@ -685,6 +666,12 @@ static int gaudi_early_init(struct hl_device *hdev) · 6 unmodified lines | ||
| 685 | 666 | goto pci_fini; |
| 686 | 667 | } |
| 687 | 668 | |
| 669 | + if (gaudi_get_hw_state(hdev) == HL_DEVICE_HW_STATE_DIRTY) { | |
| 670 | + dev_info(hdev->dev, | |
| 671 | + "H/W state is dirty, must reset before initializing\n"); | |
| 672 | + hdev->asic_funcs->hw_fini(hdev, true); | |
| 673 | + } | |
| 674 | + | |
| 688 | 675 | return 0; |
| 689 | 676 | |
| 690 | 677 | pci_fini: |
| @@ -703,93 +690,60 @@ static int gaudi_early_fini(struct hl_device *hdev) · 12 unmodified lines | ||
| 703 | 690 | } |
| 704 | 691 | |
| 705 | 692 | /** |
| 706 | − * gaudi_fetch_pll_frequency - Fetch PLL frequency values | |
| 693 | + * gaudi_fetch_psoc_frequency - Fetch PSOC frequency values | |
| 707 | 694 | * |
| 708 | 695 | * @hdev: pointer to hl_device structure |
| 709 | − * @pll_index: index of the pll to fetch frequency from | |
| 710 | − * @pll_freq: pointer to store the pll frequency in MHz in each of the available | |
| 711 | − * outputs. if a certain output is not available a 0 will be set | |
| 712 | 696 | * |
| 713 | 697 | */ |
| 714 | −static int gaudi_fetch_pll_frequency(struct hl_device *hdev, | |
| 715 | − enum gaudi_pll_index pll_index, | |
| 716 | − u16 *pll_freq_arr) | |
| 698 | +static int gaudi_fetch_psoc_frequency(struct hl_device *hdev) | |
| 717 | 699 | { |
| 718 | − u32 nr = 0, nf = 0, od = 0, pll_clk = 0, div_fctr, div_sel, | |
| 719 | − pll_base_addr = gaudi_pll_base_addresses[pll_index]; | |
| 720 | − u16 freq = 0; | |
| 721 | − int i, rc; | |
| 722 | − | |
| 723 | − if (hdev->asic_prop.fw_security_status_valid && | |
| 724 | − (hdev->asic_prop.fw_app_security_map & | |
| 725 | − CPU_BOOT_DEV_STS0_PLL_INFO_EN)) { | |
| 726 | − rc = hl_fw_cpucp_pll_info_get(hdev, pll_index, pll_freq_arr); | |
| 700 | + struct asic_fixed_properties *prop = &hdev->asic_prop; | |
| 701 | + u32 nr = 0, nf = 0, od = 0, div_fctr = 0, pll_clk, div_sel; | |
| 702 | + u16 pll_freq_arr[HL_PLL_NUM_OUTPUTS], freq; | |
| 703 | + int rc; | |
| 727 | 704 | |
| 728 | − if (rc) | |
| 729 | − return rc; | |
| 730 | − } else if (hdev->asic_prop.fw_security_disabled) { | |
| 705 | + if (hdev->asic_prop.fw_security_disabled) { | |
| 731 | 706 | /* Backward compatibility */ |
| 732 | − nr = RREG32(pll_base_addr + PLL_NR_OFFSET); | |
| 733 | − nf = RREG32(pll_base_addr + PLL_NF_OFFSET); | |
| 734 | − od = RREG32(pll_base_addr + PLL_OD_OFFSET); | |
| 735 | − | |
| 736 | − for (i = 0; i < HL_PLL_NUM_OUTPUTS; i++) { | |
| 737 | − div_fctr = RREG32(pll_base_addr + | |
| 738 | − PLL_DIV_FACTOR_0_OFFSET + i * 4); | |
| 739 | − div_sel = RREG32(pll_base_addr + | |
| 740 | − PLL_DIV_SEL_0_OFFSET + i * 4); | |
| 707 | + div_fctr = RREG32(mmPSOC_CPU_PLL_DIV_FACTOR_2); | |
| 708 | + div_sel = RREG32(mmPSOC_CPU_PLL_DIV_SEL_2); | |
| 709 | + nr = RREG32(mmPSOC_CPU_PLL_NR); | |
| 710 | + nf = RREG32(mmPSOC_CPU_PLL_NF); | |
| 711 | + od = RREG32(mmPSOC_CPU_PLL_OD); | |
| 741 | 712 | |
| 742 | − if (div_sel == DIV_SEL_REF_CLK || | |
| 713 | + if (div_sel == DIV_SEL_REF_CLK || | |
| 743 | 714 | div_sel == DIV_SEL_DIVIDED_REF) { |
| 744 | − if (div_sel == DIV_SEL_REF_CLK) | |
| 745 | − freq = PLL_REF_CLK; | |
| 746 | − else | |
| 747 | − freq = PLL_REF_CLK / (div_fctr + 1); | |
| 748 | − } else if (div_sel == DIV_SEL_PLL_CLK || | |
| 749 | − div_sel == DIV_SEL_DIVIDED_PLL) { | |
| 750 | − pll_clk = PLL_REF_CLK * (nf + 1) / | |
| 751 | − ((nr + 1) * (od + 1)); | |
| 752 | − if (div_sel == DIV_SEL_PLL_CLK) | |
| 753 | − freq = pll_clk; | |
| 754 | − else | |
| 755 | − freq = pll_clk / (div_fctr + 1); | |
| 756 | − } else { | |
| 757 | − dev_warn(hdev->dev, | |
| 758 | − "Received invalid div select value: %d", | |
| 759 | − div_sel); | |
| 760 | − } | |
| 761 | − | |
| 762 | − pll_freq_arr[i] = freq; | |
| 715 | + if (div_sel == DIV_SEL_REF_CLK) | |
| 716 | + freq = PLL_REF_CLK; | |
| 717 | + else | |
| 718 | + freq = PLL_REF_CLK / (div_fctr + 1); | |
| 719 | + } else if (div_sel == DIV_SEL_PLL_CLK || | |
| 720 | + div_sel == DIV_SEL_DIVIDED_PLL) { | |
| 721 | + pll_clk = PLL_REF_CLK * (nf + 1) / | |
| 722 | + ((nr + 1) * (od + 1)); | |
| 723 | + if (div_sel == DIV_SEL_PLL_CLK) | |
| 724 | + freq = pll_clk; | |
| 725 | + else | |
| 726 | + freq = pll_clk / (div_fctr + 1); | |
| 727 | + } else { | |
| 728 | + dev_warn(hdev->dev, | |
| 729 | + "Received invalid div select value: %d", | |
| 730 | + div_sel); | |
| 731 | + freq = 0; | |
| 763 | 732 | } |
| 764 | 733 | } else { |
| 765 | − dev_err(hdev->dev, "Failed to fetch PLL frequency values\n"); | |
| 766 | − return -EIO; | |
| 767 | − } | |
| 734 | + rc = hl_fw_cpucp_pll_info_get(hdev, CPU_PLL, pll_freq_arr); | |
| 768 | 735 | |
| 769 | − return 0; | |
| 770 | −} | |
| 771 | − | |
| 772 | −/** | |
| 773 | − * gaudi_fetch_psoc_frequency - Fetch PSOC frequency values | |
| 774 | − * | |
| 775 | − * @hdev: pointer to hl_device structure | |
| 776 | − * | |
| 777 | − */ | |
| 778 | −static int gaudi_fetch_psoc_frequency(struct hl_device *hdev) | |
| 779 | −{ | |
| 780 | − struct asic_fixed_properties *prop = &hdev->asic_prop; | |
| 781 | − u16 pll_freq[HL_PLL_NUM_OUTPUTS]; | |
| 782 | − int rc; | |
| 736 | + if (rc) | |
| 737 | + return rc; | |
| 783 | 738 | |
| 784 | − rc = gaudi_fetch_pll_frequency(hdev, CPU_PLL, pll_freq); | |
| 785 | − if (rc) | |
| 786 | − return rc; | |
| 739 | + freq = pll_freq_arr[2]; | |
| 740 | + } | |
| 787 | 741 | |
| 788 | − prop->psoc_timestamp_frequency = pll_freq[2]; | |
| 789 | − prop->psoc_pci_pll_nr = 0; | |
| 790 | − prop->psoc_pci_pll_nf = 0; | |
| 791 | − prop->psoc_pci_pll_od = 0; | |
| 792 | − prop->psoc_pci_pll_div_factor = 0; | |
| 742 | + prop->psoc_timestamp_frequency = freq; | |
| 743 | + prop->psoc_pci_pll_nr = nr; | |
| 744 | + prop->psoc_pci_pll_nf = nf; | |
| 745 | + prop->psoc_pci_pll_od = od; | |
| 746 | + prop->psoc_pci_pll_div_factor = div_fctr; | |
| 793 | 747 | |
| 794 | 748 | return 0; |
| 795 | 749 | } |
| @@ -884,11 +838,17 @@ static int gaudi_init_tpc_mem(struct hl_device *hdev) · 88 unmodified lines | ||
| 884 | 838 | size_t fw_size; |
| 885 | 839 | void *cpu_addr; |
| 886 | 840 | dma_addr_t dma_handle; |
| 887 | − int rc; | |
| 841 | + int rc, count = 5; | |
| 888 | 842 | |
| 843 | +again: | |
| 889 | 844 | rc = request_firmware(&fw, GAUDI_TPC_FW_FILE, hdev->dev); |
| 845 | + if (rc == -EINTR && count-- > 0) { | |
| 846 | + msleep(50); | |
| 847 | + goto again; | |
| 848 | + } | |
| 849 | + | |
| 890 | 850 | if (rc) { |
| 891 | − dev_err(hdev->dev, "Firmware file %s is not found!\n", | |
| 851 | + dev_err(hdev->dev, "Failed to load firmware file %s\n", | |
| 892 | 852 | GAUDI_TPC_FW_FILE); |
| 893 | 853 | goto out; |
| 894 | 854 | } |
| @@ -1110,7 +1070,7 @@ static void gaudi_collective_slave_init_job(struct hl_device *hdev, · 215 unmodified lines | ||
| 1110 | 1070 | prop->collective_sob_id, queue_id); |
| 1111 | 1071 | |
| 1112 | 1072 | cb_size += gaudi_gen_signal_cb(hdev, job->user_cb, |
| 1113 | − prop->collective_sob_id, cb_size); | |
| 1073 | + prop->collective_sob_id, cb_size, false); | |
| 1114 | 1074 | } |
| 1115 | 1075 | |
| 1116 | 1076 | static void gaudi_collective_wait_init_cs(struct hl_cs *cs) |
| @@ -2449,8 +2409,6 @@ static void gaudi_init_golden_registers(struct hl_device *hdev) · 1332 unmodified lines | ||
| 2449 | 2409 | gaudi_init_e2e(hdev); |
| 2450 | 2410 | gaudi_init_hbm_cred(hdev); |
| 2451 | 2411 | |
| 2452 | − hdev->asic_funcs->disable_clock_gating(hdev); | |
| 2453 | − | |
| 2454 | 2412 | for (tpc_id = 0, tpc_offset = 0; |
| 2455 | 2413 | tpc_id < TPC_NUMBER_OF_ENGINES; |
| 2456 | 2414 | tpc_id++, tpc_offset += TPC_CFG_OFFSET) { |
| @@ -3462,6 +3420,9 @@ static void gaudi_set_clock_gating(struct hl_device *hdev) · 1005 unmodified lines | ||
| 3462 | 3420 | if (hdev->in_debug) |
| 3463 | 3421 | return; |
| 3464 | 3422 | |
| 3423 | + if (!hdev->asic_prop.fw_security_disabled) | |
| 3424 | + return; | |
| 3425 | + | |
| 3465 | 3426 | for (i = GAUDI_PCI_DMA_1, qman_offset = 0 ; i < GAUDI_HBM_DMA_1 ; i++) { |
| 3466 | 3427 | enable = !!(hdev->clock_gating_mask & |
| 3467 | 3428 | (BIT_ULL(gaudi_dma_assignment[i]))); |
| @@ -3513,7 +3474,7 @@ static void gaudi_disable_clock_gating(struct hl_device *hdev) · 45 unmodified lines | ||
| 3513 | 3474 | u32 qman_offset; |
| 3514 | 3475 | int i; |
| 3515 | 3476 | |
| 3516 | − if (!(gaudi->hw_cap_initialized & HW_CAP_CLK_GATE)) | |
| 3477 | + if (!hdev->asic_prop.fw_security_disabled) | |
| 3517 | 3478 | return; |
| 3518 | 3479 | |
| 3519 | 3480 | for (i = 0, qman_offset = 0 ; i < DMA_NUMBER_OF_CHANNELS ; i++) { |
| @@ -3806,7 +3767,7 @@ static int gaudi_init_cpu_queues(struct hl_device *hdev, u32 cpu_timeout) · 286 unmodified lines | ||
| 3806 | 3767 | static void gaudi_pre_hw_init(struct hl_device *hdev) |
| 3807 | 3768 | { |
| 3808 | 3769 | /* Perform read from the device to make sure device is up */ |
| 3809 | − RREG32(mmPCIE_DBI_DEVICE_ID_VENDOR_ID_REG); | |
| 3770 | + RREG32(mmHW_STATE); | |
| 3810 | 3771 | |
| 3811 | 3772 | if (hdev->asic_prop.fw_security_disabled) { |
| 3812 | 3773 | /* Set the access through PCI bars (Linux driver only) as |
| @@ -3847,6 +3808,13 @@ static int gaudi_hw_init(struct hl_device *hdev) · 34 unmodified lines | ||
| 3847 | 3808 | return rc; |
| 3848 | 3809 | } |
| 3849 | 3810 | |
| 3811 | + /* In case the clock gating was enabled in preboot we need to disable | |
| 3812 | + * it here before touching the MME/TPC registers. | |
| 3813 | + * There is no need to take clk gating mutex because when this function | |
| 3814 | + * runs, no other relevant code can run | |
| 3815 | + */ | |
| 3816 | + hdev->asic_funcs->disable_clock_gating(hdev); | |
| 3817 | + | |
| 3850 | 3818 | /* SRAM scrambler must be initialized after CPU is running from HBM */ |
| 3851 | 3819 | gaudi_init_scrambler_sram(hdev); |
| 3852 | 3820 | |
| @@ -3885,7 +3853,7 @@ static int gaudi_hw_init(struct hl_device *hdev) · 32 unmodified lines | ||
| 3885 | 3853 | } |
| 3886 | 3854 | |
| 3887 | 3855 | /* Perform read from the device to flush all configuration */ |
| 3888 | − RREG32(mmPCIE_DBI_DEVICE_ID_VENDOR_ID_REG); | |
| 3856 | + RREG32(mmHW_STATE); | |
| 3889 | 3857 | |
| 3890 | 3858 | return 0; |
| 3891 | 3859 | |
| @@ -3927,7 +3895,10 @@ static void gaudi_hw_fini(struct hl_device *hdev, bool hard_reset) · 35 unmodified lines | ||
| 3927 | 3895 | /* I don't know what is the state of the CPU so make sure it is |
| 3928 | 3896 | * stopped in any means necessary |
| 3929 | 3897 | */ |
| 3930 | − WREG32(mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU, KMD_MSG_GOTO_WFE); | |
| 3898 | + if (hdev->asic_prop.hard_reset_done_by_fw) | |
| 3899 | + WREG32(mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU, KMD_MSG_RST_DEV); | |
| 3900 | + else | |
| 3901 | + WREG32(mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU, KMD_MSG_GOTO_WFE); | |
| 3931 | 3902 | |
| 3932 | 3903 | WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR, GAUDI_EVENT_HALT_MACHINE); |
| 3933 | 3904 | |
| @@ -3971,11 +3942,15 @@ static void gaudi_hw_fini(struct hl_device *hdev, bool hard_reset) · 37 unmodified lines | ||
| 3971 | 3942 | |
| 3972 | 3943 | WREG32(mmPSOC_GLOBAL_CONF_SW_ALL_RST, |
| 3973 | 3944 | 1 << PSOC_GLOBAL_CONF_SW_ALL_RST_IND_SHIFT); |
| 3974 | − } | |
| 3975 | 3945 | |
| 3976 | − dev_info(hdev->dev, | |
| 3977 | − "Issued HARD reset command, going to wait %dms\n", | |
| 3978 | − reset_timeout_ms); | |
| 3946 | + dev_info(hdev->dev, | |
| 3947 | + "Issued HARD reset command, going to wait %dms\n", | |
| 3948 | + reset_timeout_ms); | |
| 3949 | + } else { | |
| 3950 | + dev_info(hdev->dev, | |
| 3951 | + "Firmware performs HARD reset, going to wait %dms\n", | |
| 3952 | + reset_timeout_ms); | |
| 3953 | + } | |
| 3979 | 3954 | |
| 3980 | 3955 | /* |
| 3981 | 3956 | * After hard reset, we can't poll the BTM_FSM register because the PSOC |
| @@ -7936,7 +7911,7 @@ static u32 gaudi_get_wait_cb_size(struct hl_device *hdev) · 3954 unmodified lines | ||
| 7936 | 7911 | } |
| 7937 | 7912 | |
| 7938 | 7913 | static u32 gaudi_gen_signal_cb(struct hl_device *hdev, void *data, u16 sob_id, |
| 7939 | − u32 size) | |
| 7914 | + u32 size, bool eb) | |
| 7940 | 7915 | { |
| 7941 | 7916 | struct hl_cb *cb = (struct hl_cb *) data; |
| 7942 | 7917 | struct packet_msg_short *pkt; |
| @@ -7953,7 +7928,7 @@ static u32 gaudi_gen_signal_cb(struct hl_device *hdev, void *data, u16 sob_id, · 10 unmodified lines | ||
| 7953 | 7928 | ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_OP_MASK, 0); /* write the value */ |
| 7954 | 7929 | ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_BASE_MASK, 3); /* W_S SOB base */ |
| 7955 | 7930 | ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_OPCODE_MASK, PACKET_MSG_SHORT); |
| 7956 | − ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_EB_MASK, 1); | |
| 7931 | + ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_EB_MASK, eb); | |
| 7957 | 7932 | ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_RB_MASK, 1); |
| 7958 | 7933 | ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_MB_MASK, 1); |
| 7959 | 7934 | |
| @@ -105,13 +105,6 @@ · 104 unmodified lines | ||
| 105 | 105 | #define MME_ACC_OFFSET (mmMME1_ACC_BASE - mmMME0_ACC_BASE) |
| 106 | 106 | #define SRAM_BANK_OFFSET (mmSRAM_Y0_X1_RTR_BASE - mmSRAM_Y0_X0_RTR_BASE) |
| 107 | 107 | |
| 108 | −#define PLL_NR_OFFSET 0 | |
| 109 | −#define PLL_NF_OFFSET (mmPSOC_CPU_PLL_NF - mmPSOC_CPU_PLL_NR) | |
| 110 | −#define PLL_OD_OFFSET (mmPSOC_CPU_PLL_OD - mmPSOC_CPU_PLL_NR) | |
| 111 | −#define PLL_DIV_FACTOR_0_OFFSET (mmPSOC_CPU_PLL_DIV_FACTOR_0 - \ | |
| 112 | − mmPSOC_CPU_PLL_NR) | |
| 113 | −#define PLL_DIV_SEL_0_OFFSET (mmPSOC_CPU_PLL_DIV_SEL_0 - mmPSOC_CPU_PLL_NR) | |
| 114 | − | |
| 115 | 108 | #define NUM_OF_SOB_IN_BLOCK \ |
| 116 | 109 | (((mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_2047 - \ |
| 117 | 110 | mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0) + 4) >> 2) |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #include "../include/gaudi/gaudi_coresight.h" |
| 10 | 10 | #include "../include/gaudi/asic_reg/gaudi_regs.h" |
| 11 | 11 | #include "../include/gaudi/gaudi_masks.h" |
| 12 | +#include "../include/gaudi/gaudi_reg_map.h" | |
| 12 | 13 | |
| 13 | 14 | #include <uapi/misc/habanalabs.h> |
| 14 | 15 | #define SPMU_SECTION_SIZE MME0_ACC_SPMU_MAX_OFFSET |
| @@ -874,7 +875,7 @@ int gaudi_debug_coresight(struct hl_device *hdev, void *data) · 859 unmodified lines | ||
| 874 | 875 | } |
| 875 | 876 | |
| 876 | 877 | /* Perform read from the device to flush all configuration */ |
| 877 | − RREG32(mmPCIE_DBI_DEVICE_ID_VENDOR_ID_REG); | |
| 878 | + RREG32(mmHW_STATE); | |
| 878 | 879 | |
| 879 | 880 | return rc; |
| 880 | 881 | } |
| @@ -613,12 +613,6 @@ static int goya_early_init(struct hl_device *hdev) · 612 unmodified lines | ||
| 613 | 613 | if (rc) |
| 614 | 614 | goto free_queue_props; |
| 615 | 615 | |
| 616 | − if (goya_get_hw_state(hdev) == HL_DEVICE_HW_STATE_DIRTY) { | |
| 617 | − dev_info(hdev->dev, | |
| 618 | − "H/W state is dirty, must reset before initializing\n"); | |
| 619 | − hdev->asic_funcs->hw_fini(hdev, true); | |
| 620 | − } | |
| 621 | − | |
| 622 | 616 | /* Before continuing in the initialization, we need to read the preboot |
| 623 | 617 | * version to determine whether we run with a security-enabled firmware |
| 624 | 618 | */ |
| @@ -631,6 +625,12 @@ static int goya_early_init(struct hl_device *hdev) · 6 unmodified lines | ||
| 631 | 625 | goto pci_fini; |
| 632 | 626 | } |
| 633 | 627 | |
| 628 | + if (goya_get_hw_state(hdev) == HL_DEVICE_HW_STATE_DIRTY) { | |
| 629 | + dev_info(hdev->dev, | |
| 630 | + "H/W state is dirty, must reset before initializing\n"); | |
| 631 | + hdev->asic_funcs->hw_fini(hdev, true); | |
| 632 | + } | |
| 633 | + | |
| 634 | 634 | if (!hdev->pldm) { |
| 635 | 635 | val = RREG32(mmPSOC_GLOBAL_CONF_BOOT_STRAP_PINS); |
| 636 | 636 | if (val & PSOC_GLOBAL_CONF_BOOT_STRAP_PINS_SRIOV_EN_MASK) |
| @@ -694,32 +694,47 @@ static void goya_qman0_set_security(struct hl_device *hdev, bool secure) · 57 unmodified lines | ||
| 694 | 694 | static void goya_fetch_psoc_frequency(struct hl_device *hdev) |
| 695 | 695 | { |
| 696 | 696 | struct asic_fixed_properties *prop = &hdev->asic_prop; |
| 697 | − u32 trace_freq = 0; | |
| 698 | − u32 pll_clk = 0; | |
| 699 | − u32 div_fctr = RREG32(mmPSOC_PCI_PLL_DIV_FACTOR_1); | |
| 700 | − u32 div_sel = RREG32(mmPSOC_PCI_PLL_DIV_SEL_1); | |
| 701 | − u32 nr = RREG32(mmPSOC_PCI_PLL_NR); | |
| 702 | − u32 nf = RREG32(mmPSOC_PCI_PLL_NF); | |
| 703 | − u32 od = RREG32(mmPSOC_PCI_PLL_OD); | |
| 704 | − | |
| 705 | − if (div_sel == DIV_SEL_REF_CLK || div_sel == DIV_SEL_DIVIDED_REF) { | |
| 706 | − if (div_sel == DIV_SEL_REF_CLK) | |
| 707 | − trace_freq = PLL_REF_CLK; | |
| 708 | − else | |
| 709 | − trace_freq = PLL_REF_CLK / (div_fctr + 1); | |
| 710 | − } else if (div_sel == DIV_SEL_PLL_CLK || | |
| 711 | − div_sel == DIV_SEL_DIVIDED_PLL) { | |
| 712 | − pll_clk = PLL_REF_CLK * (nf + 1) / ((nr + 1) * (od + 1)); | |
| 713 | − if (div_sel == DIV_SEL_PLL_CLK) | |
| 714 | − trace_freq = pll_clk; | |
| 715 | − else | |
| 716 | − trace_freq = pll_clk / (div_fctr + 1); | |
| 697 | + u32 nr = 0, nf = 0, od = 0, div_fctr = 0, pll_clk, div_sel; | |
| 698 | + u16 pll_freq_arr[HL_PLL_NUM_OUTPUTS], freq; | |
| 699 | + int rc; | |
| 700 | + | |
| 701 | + if (hdev->asic_prop.fw_security_disabled) { | |
| 702 | + div_fctr = RREG32(mmPSOC_PCI_PLL_DIV_FACTOR_1); | |
| 703 | + div_sel = RREG32(mmPSOC_PCI_PLL_DIV_SEL_1); | |
| 704 | + nr = RREG32(mmPSOC_PCI_PLL_NR); | |
| 705 | + nf = RREG32(mmPSOC_PCI_PLL_NF); | |
| 706 | + od = RREG32(mmPSOC_PCI_PLL_OD); | |
| 707 | + | |
| 708 | + if (div_sel == DIV_SEL_REF_CLK || | |
| 709 | + div_sel == DIV_SEL_DIVIDED_REF) { | |
| 710 | + if (div_sel == DIV_SEL_REF_CLK) | |
| 711 | + freq = PLL_REF_CLK; | |
| 712 | + else | |
| 713 | + freq = PLL_REF_CLK / (div_fctr + 1); | |
| 714 | + } else if (div_sel == DIV_SEL_PLL_CLK || | |
| 715 | + div_sel == DIV_SEL_DIVIDED_PLL) { | |
| 716 | + pll_clk = PLL_REF_CLK * (nf + 1) / | |
| 717 | + ((nr + 1) * (od + 1)); | |
| 718 | + if (div_sel == DIV_SEL_PLL_CLK) | |
| 719 | + freq = pll_clk; | |
| 720 | + else | |
| 721 | + freq = pll_clk / (div_fctr + 1); | |
| 722 | + } else { | |
| 723 | + dev_warn(hdev->dev, | |
| 724 | + "Received invalid div select value: %d", | |
| 725 | + div_sel); | |
| 726 | + freq = 0; | |
| 727 | + } | |
| 717 | 728 | } else { |
| 718 | − dev_warn(hdev->dev, | |
| 719 | − "Received invalid div select value: %d", div_sel); | |
| 729 | + rc = hl_fw_cpucp_pll_info_get(hdev, PCI_PLL, pll_freq_arr); | |
| 730 | + | |
| 731 | + if (rc) | |
| 732 | + return; | |
| 733 | + | |
| 734 | + freq = pll_freq_arr[1]; | |
| 720 | 735 | } |
| 721 | 736 | |
| 722 | − prop->psoc_timestamp_frequency = trace_freq; | |
| 737 | + prop->psoc_timestamp_frequency = freq; | |
| 723 | 738 | prop->psoc_pci_pll_nr = nr; |
| 724 | 739 | prop->psoc_pci_pll_nf = nf; |
| 725 | 740 | prop->psoc_pci_pll_od = od; |
| @@ -5324,7 +5339,7 @@ static u32 goya_get_wait_cb_size(struct hl_device *hdev) · 4598 unmodified lines | ||
| 5324 | 5339 | } |
| 5325 | 5340 | |
| 5326 | 5341 | static u32 goya_gen_signal_cb(struct hl_device *hdev, void *data, u16 sob_id, |
| 5327 | − u32 size) | |
| 5342 | + u32 size, bool eb) | |
| 5328 | 5343 | { |
| 5329 | 5344 | return 0; |
| 5330 | 5345 | } |
| @@ -145,11 +145,15 @@ · 144 unmodified lines | ||
| 145 | 145 | * implemented. This means that FW will |
| 146 | 146 | * perform hard reset procedure on |
| 147 | 147 | * receiving the halt-machine event. |
| 148 | − * Initialized in: linux | |
| 148 | + * Initialized in: preboot, u-boot, linux | |
| 149 | 149 | * |
| 150 | 150 | * CPU_BOOT_DEV_STS0_PLL_INFO_EN FW retrieval of PLL info is enabled. |
| 151 | 151 | * Initialized in: linux |
| 152 | 152 | * |
| 153 | + * CPU_BOOT_DEV_STS0_CLK_GATE_EN Clock Gating enabled. | |
| 154 | + * FW initialized Clock Gating. | |
| 155 | + * Initialized in: preboot | |
| 156 | + * | |
| 153 | 157 | * CPU_BOOT_DEV_STS0_ENABLED Device status register enabled. |
| 154 | 158 | * This is a main indication that the |
| 155 | 159 | * running FW populates the device status |
| @@ -171,6 +175,7 @@ · 15 unmodified lines | ||
| 171 | 175 | #define CPU_BOOT_DEV_STS0_DRAM_SCR_EN (1 << 9) |
| 172 | 176 | #define CPU_BOOT_DEV_STS0_FW_HARD_RST_EN (1 << 10) |
| 173 | 177 | #define CPU_BOOT_DEV_STS0_PLL_INFO_EN (1 << 11) |
| 178 | +#define CPU_BOOT_DEV_STS0_CLK_GATE_EN (1 << 13) | |
| 174 | 179 | #define CPU_BOOT_DEV_STS0_ENABLED (1 << 31) |
| 175 | 180 | |
| 176 | 181 | enum cpu_boot_status { |
| @@ -204,6 +209,8 @@ enum kmd_msg { · 27 unmodified lines | ||
| 204 | 209 | KMD_MSG_GOTO_WFE, |
| 205 | 210 | KMD_MSG_FIT_RDY, |
| 206 | 211 | KMD_MSG_SKIP_BMC, |
| 212 | + RESERVED, | |
| 213 | + KMD_MSG_RST_DEV, | |
| 207 | 214 | }; |
| 208 | 215 | |
| 209 | 216 | enum cpu_msg_status { |
| @@ -55,12 +55,23 @@ static int pvpanic_mmio_probe(struct platform_device *pdev) · 54 unmodified lines | ||
| 55 | 55 | struct resource *res; |
| 56 | 56 | |
| 57 | 57 | res = platform_get_mem_or_io(pdev, 0); |
| 58 | − if (res && resource_type(res) == IORESOURCE_IO) | |
| 58 | + if (!res) | |
| 59 | + return -EINVAL; | |
| 60 | + | |
| 61 | + switch (resource_type(res)) { | |
| 62 | + case IORESOURCE_IO: | |
| 59 | 63 | base = devm_ioport_map(dev, res->start, resource_size(res)); |
| 60 | − else | |
| 64 | + if (!base) | |
| 65 | + return -ENOMEM; | |
| 66 | + break; | |
| 67 | + case IORESOURCE_MEM: | |
| 61 | 68 | base = devm_ioremap_resource(dev, res); |
| 62 | − if (IS_ERR(base)) | |
| 63 | − return PTR_ERR(base); | |
| 69 | + if (IS_ERR(base)) | |
| 70 | + return PTR_ERR(base); | |
| 71 | + break; | |
| 72 | + default: | |
| 73 | + return -EINVAL; | |
| 74 | + } | |
| 64 | 75 | |
| 65 | 76 | atomic_notifier_chain_register(&panic_notifier_list, |
| 66 | 77 | &pvpanic_panic_nb); |
| @@ -380,7 +380,7 @@ static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev, · 379 unmodified lines | ||
| 380 | 380 | goto free_dst; |
| 381 | 381 | |
| 382 | 382 | min_headroom = LL_RESERVED_SPACE(dst->dev) + dst->header_len + |
| 383 | − BAREUDP_BASE_HLEN + info->options_len + sizeof(struct iphdr); | |
| 383 | + BAREUDP_BASE_HLEN + info->options_len + sizeof(struct ipv6hdr); | |
| 384 | 384 | |
| 385 | 385 | err = skb_cow_head(skb, min_headroom); |
| 386 | 386 | if (unlikely(err)) |
| @@ -534,6 +534,7 @@ static void bareudp_setup(struct net_device *dev) · 147 unmodified lines | ||
| 534 | 534 | SET_NETDEV_DEVTYPE(dev, &bareudp_type); |
| 535 | 535 | dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; |
| 536 | 536 | dev->features |= NETIF_F_RXCSUM; |
| 537 | + dev->features |= NETIF_F_LLTX; | |
| 537 | 538 | dev->features |= NETIF_F_GSO_SOFTWARE; |
| 538 | 539 | dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM; |
| 539 | 540 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; |
| @@ -644,11 +645,20 @@ static int bareudp_link_config(struct net_device *dev, · 104 unmodified lines | ||
| 644 | 645 | return 0; |
| 645 | 646 | } |
| 646 | 647 | |
| 648 | +static void bareudp_dellink(struct net_device *dev, struct list_head *head) | |
| 649 | +{ | |
| 650 | + struct bareudp_dev *bareudp = netdev_priv(dev); | |
| 651 | + | |
| 652 | + list_del(&bareudp->next); | |
| 653 | + unregister_netdevice_queue(dev, head); | |
| 654 | +} | |
| 655 | + | |
| 647 | 656 | static int bareudp_newlink(struct net *net, struct net_device *dev, |
| 648 | 657 | struct nlattr *tb[], struct nlattr *data[], |
| 649 | 658 | struct netlink_ext_ack *extack) |
| 650 | 659 | { |
| 651 | 660 | struct bareudp_conf conf; |
| 661 | + LIST_HEAD(list_kill); | |
| 652 | 662 | int err; |
| 653 | 663 | |
| 654 | 664 | err = bareudp2info(data, &conf, extack); |
| @@ -661,17 +671,14 @@ static int bareudp_newlink(struct net *net, struct net_device *dev, · 6 unmodified lines | ||
| 661 | 671 | |
| 662 | 672 | err = bareudp_link_config(dev, tb); |
| 663 | 673 | if (err) |
| 664 | − return err; | |
| 674 | + goto err_unconfig; | |
| 665 | 675 | |
| 666 | 676 | return 0; |
| 667 | −} | |
| 668 | − | |
| 669 | −static void bareudp_dellink(struct net_device *dev, struct list_head *head) | |
| 670 | −{ | |
| 671 | − struct bareudp_dev *bareudp = netdev_priv(dev); | |
| 672 | 677 | |
| 673 | − list_del(&bareudp->next); | |
| 674 | − unregister_netdevice_queue(dev, head); | |
| 678 | +err_unconfig: | |
| 679 | + bareudp_dellink(dev, &list_kill); | |
| 680 | + unregister_netdevice_many(&list_kill); | |
| 681 | + return err; | |
| 675 | 682 | } |
| 676 | 683 | |
| 677 | 684 | static size_t bareudp_get_size(const struct net_device *dev) |
| @@ -123,6 +123,7 @@ config CAN_JANZ_ICAN3 · 122 unmodified lines | ||
| 123 | 123 | config CAN_KVASER_PCIEFD |
| 124 | 124 | depends on PCI |
| 125 | 125 | tristate "Kvaser PCIe FD cards" |
| 126 | + select CRC32 | |
| 126 | 127 | help |
| 127 | 128 | This is a driver for the Kvaser PCI Express CAN FD family. |
| 128 | 129 | |
| @@ -1852,8 +1852,6 @@ EXPORT_SYMBOL_GPL(m_can_class_register); · 1851 unmodified lines | ||
| 1852 | 1852 | void m_can_class_unregister(struct m_can_classdev *cdev) |
| 1853 | 1853 | { |
| 1854 | 1854 | unregister_candev(cdev->net); |
| 1855 | − | |
| 1856 | − m_can_clk_stop(cdev); | |
| 1857 | 1855 | } |
| 1858 | 1856 | EXPORT_SYMBOL_GPL(m_can_class_unregister); |
| 1859 | 1857 | |
| @@ -131,30 +131,6 @@ static inline struct tcan4x5x_priv *cdev_to_priv(struct m_can_classdev *cdev) · 130 unmodified lines | ||
| 131 | 131 | |
| 132 | 132 | } |
| 133 | 133 | |
| 134 | −static struct can_bittiming_const tcan4x5x_bittiming_const = { | |
| 135 | − .name = DEVICE_NAME, | |
| 136 | − .tseg1_min = 2, | |
| 137 | − .tseg1_max = 31, | |
| 138 | − .tseg2_min = 2, | |
| 139 | − .tseg2_max = 16, | |
| 140 | − .sjw_max = 16, | |
| 141 | − .brp_min = 1, | |
| 142 | − .brp_max = 32, | |
| 143 | − .brp_inc = 1, | |
| 144 | −}; | |
| 145 | − | |
| 146 | −static struct can_bittiming_const tcan4x5x_data_bittiming_const = { | |
| 147 | − .name = DEVICE_NAME, | |
| 148 | − .tseg1_min = 1, | |
| 149 | − .tseg1_max = 32, | |
| 150 | − .tseg2_min = 1, | |
| 151 | − .tseg2_max = 16, | |
| 152 | − .sjw_max = 16, | |
| 153 | − .brp_min = 1, | |
| 154 | − .brp_max = 32, | |
| 155 | − .brp_inc = 1, | |
| 156 | −}; | |
| 157 | − | |
| 158 | 134 | static void tcan4x5x_check_wake(struct tcan4x5x_priv *priv) |
| 159 | 135 | { |
| 160 | 136 | int wake_state = 0; |
| @@ -469,8 +445,6 @@ static int tcan4x5x_can_probe(struct spi_device *spi) · 308 unmodified lines | ||
| 469 | 445 | mcan_class->dev = &spi->dev; |
| 470 | 446 | mcan_class->ops = &tcan4x5x_ops; |
| 471 | 447 | mcan_class->is_peripheral = true; |
| 472 | − mcan_class->bit_timing = &tcan4x5x_bittiming_const; | |
| 473 | − mcan_class->data_timing = &tcan4x5x_data_bittiming_const; | |
| 474 | 448 | mcan_class->net->irq = spi->irq; |
| 475 | 449 | |
| 476 | 450 | spi_set_drvdata(spi, priv); |
| @@ -1,10 +1,10 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | config CAN_RCAR |
| 3 | − tristate "Renesas R-Car CAN controller" | |
| 3 | + tristate "Renesas R-Car and RZ/G CAN controller" | |
| 4 | 4 | depends on ARCH_RENESAS || ARM |
| 5 | 5 | help |
| 6 | 6 | Say Y here if you want to use CAN controller found on Renesas R-Car |
| 7 | − SoCs. | |
| 7 | + or RZ/G SoCs. | |
| 8 | 8 | |
| 9 | 9 | To compile this driver as a module, choose M here: the module will |
| 10 | 10 | be called rcar_can. |
| @@ -1368,13 +1368,10 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) · 1367 unmodified lines | ||
| 1368 | 1368 | struct mcp251xfd_tx_ring *tx_ring = priv->tx; |
| 1369 | 1369 | struct spi_transfer *last_xfer; |
| 1370 | 1370 | |
| 1371 | − tx_ring->tail += len; | |
| 1372 | − | |
| 1373 | 1371 | /* Increment the TEF FIFO tail pointer 'len' times in |
| 1374 | 1372 | * a single SPI message. |
| 1375 | − */ | |
| 1376 | − | |
| 1377 | − /* Note: | |
| 1373 | + * | |
| 1374 | + * Note: | |
| 1378 | 1375 | * |
| 1379 | 1376 | * "cs_change == 1" on the last transfer results in an |
| 1380 | 1377 | * active chip select after the complete SPI |
| @@ -1391,6 +1388,8 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) · 10 unmodified lines | ||
| 1391 | 1388 | if (err) |
| 1392 | 1389 | return err; |
| 1393 | 1390 | |
| 1391 | + tx_ring->tail += len; | |
| 1392 | + | |
| 1394 | 1393 | err = mcp251xfd_check_tef_tail(priv); |
| 1395 | 1394 | if (err) |
| 1396 | 1395 | return err; |
| @@ -1492,7 +1491,7 @@ mcp251xfd_handle_rxif_one(struct mcp251xfd_priv *priv, · 95 unmodified lines | ||
| 1492 | 1491 | else |
| 1493 | 1492 | skb = alloc_can_skb(priv->ndev, (struct can_frame **)&cfd); |
| 1494 | 1493 | |
| 1495 | − if (!cfd) { | |
| 1494 | + if (!skb) { | |
| 1496 | 1495 | stats->rx_dropped++; |
| 1497 | 1496 | return 0; |
| 1498 | 1497 | } |
| @@ -1553,10 +1552,8 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv, · 54 unmodified lines | ||
| 1553 | 1552 | |
| 1554 | 1553 | /* Increment the RX FIFO tail pointer 'len' times in a |
| 1555 | 1554 | * single SPI message. |
| 1556 | − */ | |
| 1557 | − ring->tail += len; | |
| 1558 | − | |
| 1559 | − /* Note: | |
| 1555 | + * | |
| 1556 | + * Note: | |
| 1560 | 1557 | * |
| 1561 | 1558 | * "cs_change == 1" on the last transfer results in an |
| 1562 | 1559 | * active chip select after the complete SPI |
| @@ -1572,6 +1569,8 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv, · 9 unmodified lines | ||
| 1572 | 1569 | last_xfer->cs_change = 1; |
| 1573 | 1570 | if (err) |
| 1574 | 1571 | return err; |
| 1572 | + | |
| 1573 | + ring->tail += len; | |
| 1575 | 1574 | } |
| 1576 | 1575 | |
| 1577 | 1576 | return 0; |
| @@ -4,6 +4,7 @@ config NET_DSA_HIRSCHMANN_HELLCREEK · 3 unmodified lines | ||
| 4 | 4 | depends on HAS_IOMEM |
| 5 | 5 | depends on NET_DSA |
| 6 | 6 | depends on PTP_1588_CLOCK |
| 7 | + depends on LEDS_CLASS | |
| 7 | 8 | select NET_DSA_TAG_HELLCREEK |
| 8 | 9 | help |
| 9 | 10 | This driver adds support for Hirschmann Hellcreek TSN switches. |
| @@ -92,9 +92,7 @@ · 91 unmodified lines | ||
| 92 | 92 | GSWIP_MDIO_PHY_FDUP_MASK) |
| 93 | 93 | |
| 94 | 94 | /* GSWIP MII Registers */ |
| 95 | −#define GSWIP_MII_CFG0 0x00 | |
| 96 | −#define GSWIP_MII_CFG1 0x02 | |
| 97 | −#define GSWIP_MII_CFG5 0x04 | |
| 95 | +#define GSWIP_MII_CFGp(p) (0x2 * (p)) | |
| 98 | 96 | #define GSWIP_MII_CFG_EN BIT(14) |
| 99 | 97 | #define GSWIP_MII_CFG_LDCLKDIS BIT(12) |
| 100 | 98 | #define GSWIP_MII_CFG_MODE_MIIP 0x0 |
| @@ -392,17 +390,9 @@ static void gswip_mii_mask(struct gswip_priv *priv, u32 clear, u32 set, · 291 unmodified lines | ||
| 392 | 390 | static void gswip_mii_mask_cfg(struct gswip_priv *priv, u32 clear, u32 set, |
| 393 | 391 | int port) |
| 394 | 392 | { |
| 395 | − switch (port) { | |
| 396 | − case 0: | |
| 397 | − gswip_mii_mask(priv, clear, set, GSWIP_MII_CFG0); | |
| 398 | − break; | |
| 399 | − case 1: | |
| 400 | − gswip_mii_mask(priv, clear, set, GSWIP_MII_CFG1); | |
| 401 | − break; | |
| 402 | − case 5: | |
| 403 | − gswip_mii_mask(priv, clear, set, GSWIP_MII_CFG5); | |
| 404 | − break; | |
| 405 | − } | |
| 393 | + /* There's no MII_CFG register for the CPU port */ | |
| 394 | + if (!dsa_is_cpu_port(priv->ds, port)) | |
| 395 | + gswip_mii_mask(priv, clear, set, GSWIP_MII_CFGp(port)); | |
| 406 | 396 | } |
| 407 | 397 | |
| 408 | 398 | static void gswip_mii_mask_pcdu(struct gswip_priv *priv, u32 clear, u32 set, |
| @@ -822,9 +812,8 @@ static int gswip_setup(struct dsa_switch *ds) · 413 unmodified lines | ||
| 822 | 812 | gswip_mdio_mask(priv, 0xff, 0x09, GSWIP_MDIO_MDC_CFG1); |
| 823 | 813 | |
| 824 | 814 | /* Disable the xMII link */ |
| 825 | − gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, 0); | |
| 826 | − gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, 1); | |
| 827 | − gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, 5); | |
| 815 | + for (i = 0; i < priv->hw_info->max_ports; i++) | |
| 816 | + gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, i); | |
| 828 | 817 | |
| 829 | 818 | /* enable special tag insertion on cpu port */ |
| 830 | 819 | gswip_switch_mask(priv, 0, GSWIP_FDMA_PCTRL_STEN, |
| @@ -1447,11 +1436,12 @@ static void gswip_phylink_validate(struct dsa_switch *ds, int port, · 616 unmodified lines | ||
| 1447 | 1436 | phylink_set(mask, Pause); |
| 1448 | 1437 | phylink_set(mask, Asym_Pause); |
| 1449 | 1438 | |
| 1450 | − /* With the exclusion of MII and Reverse MII, we support Gigabit, | |
| 1451 | − * including Half duplex | |
| 1439 | + /* With the exclusion of MII, Reverse MII and Reduced MII, we | |
| 1440 | + * support Gigabit, including Half duplex | |
| 1452 | 1441 | */ |
| 1453 | 1442 | if (state->interface != PHY_INTERFACE_MODE_MII && |
| 1454 | − state->interface != PHY_INTERFACE_MODE_REVMII) { | |
| 1443 | + state->interface != PHY_INTERFACE_MODE_REVMII && | |
| 1444 | + state->interface != PHY_INTERFACE_MODE_RMII) { | |
| 1455 | 1445 | phylink_set(mask, 1000baseT_Full); |
| 1456 | 1446 | phylink_set(mask, 1000baseT_Half); |
| 1457 | 1447 | } |
| @@ -1541,9 +1531,7 @@ static void gswip_phylink_mac_link_up(struct dsa_switch *ds, int port, · 83 unmodified lines | ||
| 1541 | 1531 | { |
| 1542 | 1532 | struct gswip_priv *priv = ds->priv; |
| 1543 | 1533 | |
| 1544 | − /* Enable the xMII interface only for the external PHY */ | |
| 1545 | − if (interface != PHY_INTERFACE_MODE_INTERNAL) | |
| 1546 | − gswip_mii_mask_cfg(priv, 0, GSWIP_MII_CFG_EN, port); | |
| 1534 | + gswip_mii_mask_cfg(priv, 0, GSWIP_MII_CFG_EN, port); | |
| 1547 | 1535 | } |
| 1548 | 1536 | |
| 1549 | 1537 | static void gswip_get_strings(struct dsa_switch *ds, int port, u32 stringset, |
| @@ -19,7 +19,6 @@ if NET_VENDOR_AQUANTIA · 18 unmodified lines | ||
| 19 | 19 | config AQTION |
| 20 | 20 | tristate "aQuantia AQtion(tm) Support" |
| 21 | 21 | depends on PCI |
| 22 | − depends on X86_64 || ARM64 || COMPILE_TEST | |
| 23 | 22 | depends on MACSEC || MACSEC=n |
| 24 | 23 | help |
| 25 | 24 | This enables the support for the aQuantia AQtion(tm) Ethernet card. |
| @@ -2577,6 +2577,7 @@ static int bcm_sysport_probe(struct platform_device *pdev) · 2576 unmodified lines | ||
| 2577 | 2577 | NETIF_F_HW_VLAN_CTAG_TX; |
| 2578 | 2578 | dev->hw_features |= dev->features; |
| 2579 | 2579 | dev->vlan_features |= dev->features; |
| 2580 | + dev->max_mtu = UMAC_MAX_MTU_SIZE; | |
| 2580 | 2581 | |
| 2581 | 2582 | /* Request the WOL interrupt and advertise suspend if available */ |
| 2582 | 2583 | priv->wol_irq_disabled = 1; |
| @@ -6790,8 +6790,10 @@ static int bnxt_hwrm_func_backing_store_qcaps(struct bnxt *bp) · 6789 unmodified lines | ||
| 6790 | 6790 | ctx->tqm_fp_rings_count = resp->tqm_fp_rings_count; |
| 6791 | 6791 | if (!ctx->tqm_fp_rings_count) |
| 6792 | 6792 | ctx->tqm_fp_rings_count = bp->max_q; |
| 6793 | + else if (ctx->tqm_fp_rings_count > BNXT_MAX_TQM_FP_RINGS) | |
| 6794 | + ctx->tqm_fp_rings_count = BNXT_MAX_TQM_FP_RINGS; | |
| 6793 | 6795 | |
| 6794 | − tqm_rings = ctx->tqm_fp_rings_count + 1; | |
| 6796 | + tqm_rings = ctx->tqm_fp_rings_count + BNXT_MAX_TQM_SP_RINGS; | |
| 6795 | 6797 | ctx_pg = kcalloc(tqm_rings, sizeof(*ctx_pg), GFP_KERNEL); |
| 6796 | 6798 | if (!ctx_pg) { |
| 6797 | 6799 | kfree(ctx); |
| @@ -6925,7 +6927,8 @@ static int bnxt_hwrm_func_backing_store_cfg(struct bnxt *bp, u32 enables) · 127 unmodified lines | ||
| 6925 | 6927 | pg_attr = &req.tqm_sp_pg_size_tqm_sp_lvl, |
| 6926 | 6928 | pg_dir = &req.tqm_sp_page_dir, |
| 6927 | 6929 | ena = FUNC_BACKING_STORE_CFG_REQ_ENABLES_TQM_SP; |
| 6928 | − i < 9; i++, num_entries++, pg_attr++, pg_dir++, ena <<= 1) { | |
| 6930 | + i < BNXT_MAX_TQM_RINGS; | |
| 6931 | + i++, num_entries++, pg_attr++, pg_dir++, ena <<= 1) { | |
| 6929 | 6932 | if (!(enables & ena)) |
| 6930 | 6933 | continue; |
| 6931 | 6934 | |
| @@ -12887,10 +12890,10 @@ static pci_ers_result_t bnxt_io_error_detected(struct pci_dev *pdev, · 5955 unmodified lines | ||
| 12887 | 12890 | */ |
| 12888 | 12891 | static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev) |
| 12889 | 12892 | { |
| 12893 | + pci_ers_result_t result = PCI_ERS_RESULT_DISCONNECT; | |
| 12890 | 12894 | struct net_device *netdev = pci_get_drvdata(pdev); |
| 12891 | 12895 | struct bnxt *bp = netdev_priv(netdev); |
| 12892 | 12896 | int err = 0, off; |
| 12893 | − pci_ers_result_t result = PCI_ERS_RESULT_DISCONNECT; | |
| 12894 | 12897 | |
| 12895 | 12898 | netdev_info(bp->dev, "PCI Slot Reset\n"); |
| 12896 | 12899 | |
| @@ -12919,22 +12922,8 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev) · 22 unmodified lines | ||
| 12919 | 12922 | pci_save_state(pdev); |
| 12920 | 12923 | |
| 12921 | 12924 | err = bnxt_hwrm_func_reset(bp); |
| 12922 | − if (!err) { | |
| 12923 | − err = bnxt_hwrm_func_qcaps(bp); | |
| 12924 | − if (!err && netif_running(netdev)) | |
| 12925 | − err = bnxt_open(netdev); | |
| 12926 | − } | |
| 12927 | − bnxt_ulp_start(bp, err); | |
| 12928 | − if (!err) { | |
| 12929 | − bnxt_reenable_sriov(bp); | |
| 12925 | + if (!err) | |
| 12930 | 12926 | result = PCI_ERS_RESULT_RECOVERED; |
| 12931 | − } | |
| 12932 | − } | |
| 12933 | − | |
| 12934 | − if (result != PCI_ERS_RESULT_RECOVERED) { | |
| 12935 | − if (netif_running(netdev)) | |
| 12936 | − dev_close(netdev); | |
| 12937 | − pci_disable_device(pdev); | |
| 12938 | 12927 | } |
| 12939 | 12928 | |
| 12940 | 12929 | rtnl_unlock(); |
| @@ -12952,10 +12941,21 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev) · 11 unmodified lines | ||
| 12952 | 12941 | static void bnxt_io_resume(struct pci_dev *pdev) |
| 12953 | 12942 | { |
| 12954 | 12943 | struct net_device *netdev = pci_get_drvdata(pdev); |
| 12944 | + struct bnxt *bp = netdev_priv(netdev); | |
| 12945 | + int err; | |
| 12955 | 12946 | |
| 12947 | + netdev_info(bp->dev, "PCI Slot Resume\n"); | |
| 12956 | 12948 | rtnl_lock(); |
| 12957 | 12949 | |
| 12958 | − netif_device_attach(netdev); | |
| 12950 | + err = bnxt_hwrm_func_qcaps(bp); | |
| 12951 | + if (!err && netif_running(netdev)) | |
| 12952 | + err = bnxt_open(netdev); | |
| 12953 | + | |
| 12954 | + bnxt_ulp_start(bp, err); | |
| 12955 | + if (!err) { | |
| 12956 | + bnxt_reenable_sriov(bp); | |
| 12957 | + netif_device_attach(netdev); | |
| 12958 | + } | |
| 12959 | 12959 | |
| 12960 | 12960 | rtnl_unlock(); |
| 12961 | 12961 | } |
| @@ -1436,6 +1436,11 @@ struct bnxt_ctx_pg_info { · 1435 unmodified lines | ||
| 1436 | 1436 | struct bnxt_ctx_pg_info **ctx_pg_tbl; |
| 1437 | 1437 | }; |
| 1438 | 1438 | |
| 1439 | +#define BNXT_MAX_TQM_SP_RINGS 1 | |
| 1440 | +#define BNXT_MAX_TQM_FP_RINGS 8 | |
| 1441 | +#define BNXT_MAX_TQM_RINGS \ | |
| 1442 | + (BNXT_MAX_TQM_SP_RINGS + BNXT_MAX_TQM_FP_RINGS) | |
| 1443 | + | |
| 1439 | 1444 | struct bnxt_ctx_mem_info { |
| 1440 | 1445 | u32 qp_max_entries; |
| 1441 | 1446 | u16 qp_min_qp1_entries; |
| @@ -1474,7 +1479,7 @@ struct bnxt_ctx_mem_info { · 32 unmodified lines | ||
| 1474 | 1479 | struct bnxt_ctx_pg_info stat_mem; |
| 1475 | 1480 | struct bnxt_ctx_pg_info mrav_mem; |
| 1476 | 1481 | struct bnxt_ctx_pg_info tim_mem; |
| 1477 | − struct bnxt_ctx_pg_info *tqm_mem[9]; | |
| 1482 | + struct bnxt_ctx_pg_info *tqm_mem[BNXT_MAX_TQM_RINGS]; | |
| 1478 | 1483 | }; |
| 1479 | 1484 | |
| 1480 | 1485 | struct bnxt_fw_health { |
| @@ -2532,7 +2532,7 @@ int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware · 2531 unmodified lines | ||
| 2532 | 2532 | |
| 2533 | 2533 | if (rc && ((struct hwrm_err_output *)&resp)->cmd_err == |
| 2534 | 2534 | NVM_INSTALL_UPDATE_CMD_ERR_CODE_FRAG_ERR) { |
| 2535 | − install.flags |= | |
| 2535 | + install.flags = | |
| 2536 | 2536 | cpu_to_le16(NVM_INSTALL_UPDATE_REQ_FLAGS_ALLOWED_TO_DEFRAG); |
| 2537 | 2537 | |
| 2538 | 2538 | rc = _hwrm_send_message_silent(bp, &install, |
| @@ -2546,6 +2546,7 @@ int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware · 7 unmodified lines | ||
| 2546 | 2546 | * UPDATE directory and try the flash again |
| 2547 | 2547 | */ |
| 2548 | 2548 | defrag_attempted = true; |
| 2549 | + install.flags = 0; | |
| 2549 | 2550 | rc = __bnxt_flash_nvram(bp->dev, |
| 2550 | 2551 | BNX_DIR_TYPE_UPDATE, |
| 2551 | 2552 | BNX_DIR_ORDINAL_FIRST, |
| @@ -222,8 +222,12 @@ int bnxt_get_ulp_msix_base(struct bnxt *bp) · 221 unmodified lines | ||
| 222 | 222 | |
| 223 | 223 | int bnxt_get_ulp_stat_ctxs(struct bnxt *bp) |
| 224 | 224 | { |
| 225 | − if (bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) | |
| 226 | − return BNXT_MIN_ROCE_STAT_CTXS; | |
| 225 | + if (bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) { | |
| 226 | + struct bnxt_en_dev *edev = bp->edev; | |
| 227 | + | |
| 228 | + if (edev->ulp_tbl[BNXT_ROCE_ULP].msix_requested) | |
| 229 | + return BNXT_MIN_ROCE_STAT_CTXS; | |
| 230 | + } | |
| 227 | 231 | |
| 228 | 232 | return 0; |
| 229 | 233 | } |
| @@ -467,7 +467,7 @@ static void macb_set_tx_clk(struct macb *bp, int speed) · 466 unmodified lines | ||
| 467 | 467 | { |
| 468 | 468 | long ferr, rate, rate_rounded; |
| 469 | 469 | |
| 470 | − if (!bp->tx_clk || !(bp->caps & MACB_CAPS_CLK_HW_CHG)) | |
| 470 | + if (!bp->tx_clk || (bp->caps & MACB_CAPS_CLK_HW_CHG)) | |
| 471 | 471 | return; |
| 472 | 472 | |
| 473 | 473 | switch (speed) { |
| @@ -40,6 +40,13 @@ · 39 unmodified lines | ||
| 40 | 40 | #define TCB_L2T_IX_M 0xfffULL |
| 41 | 41 | #define TCB_L2T_IX_V(x) ((x) << TCB_L2T_IX_S) |
| 42 | 42 | |
| 43 | +#define TCB_T_FLAGS_W 1 | |
| 44 | +#define TCB_T_FLAGS_S 0 | |
| 45 | +#define TCB_T_FLAGS_M 0xffffffffffffffffULL | |
| 46 | +#define TCB_T_FLAGS_V(x) ((__u64)(x) << TCB_T_FLAGS_S) | |
| 47 | + | |
| 48 | +#define TCB_FIELD_COOKIE_TFLAG 1 | |
| 49 | + | |
| 43 | 50 | #define TCB_SMAC_SEL_W 0 |
| 44 | 51 | #define TCB_SMAC_SEL_S 24 |
| 45 | 52 | #define TCB_SMAC_SEL_M 0xffULL |
| @@ -575,7 +575,11 @@ int send_tx_flowc_wr(struct sock *sk, int compl, · 574 unmodified lines | ||
| 575 | 575 | void chtls_tcp_push(struct sock *sk, int flags); |
| 576 | 576 | int chtls_push_frames(struct chtls_sock *csk, int comp); |
| 577 | 577 | int chtls_set_tcb_tflag(struct sock *sk, unsigned int bit_pos, int val); |
| 578 | +void chtls_set_tcb_field_rpl_skb(struct sock *sk, u16 word, | |
| 579 | + u64 mask, u64 val, u8 cookie, | |
| 580 | + int through_l2t); | |
| 578 | 581 | int chtls_setkey(struct chtls_sock *csk, u32 keylen, u32 mode, int cipher_type); |
| 582 | +void chtls_set_quiesce_ctrl(struct sock *sk, int val); | |
| 579 | 583 | void skb_entail(struct sock *sk, struct sk_buff *skb, int flags); |
| 580 | 584 | unsigned int keyid_to_addr(int start_addr, int keyid); |
| 581 | 585 | void free_tls_keyid(struct sock *sk); |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | #include "chtls.h" |
| 33 | 33 | #include "chtls_cm.h" |
| 34 | 34 | #include "clip_tbl.h" |
| 35 | +#include "t4_tcb.h" | |
| 35 | 36 | |
| 36 | 37 | /* |
| 37 | 38 | * State transitions and actions for close. Note that if we are in SYN_SENT |
| @@ -267,7 +268,9 @@ static void chtls_send_reset(struct sock *sk, int mode, struct sk_buff *skb) · 229 unmodified lines | ||
| 267 | 268 | if (sk->sk_state != TCP_SYN_RECV) |
| 268 | 269 | chtls_send_abort(sk, mode, skb); |
| 269 | 270 | else |
| 270 | − goto out; | |
| 271 | + chtls_set_tcb_field_rpl_skb(sk, TCB_T_FLAGS_W, | |
| 272 | + TCB_T_FLAGS_V(TCB_T_FLAGS_M), 0, | |
| 273 | + TCB_FIELD_COOKIE_TFLAG, 1); | |
| 271 | 274 | |
| 272 | 275 | return; |
| 273 | 276 | out: |
| @@ -621,7 +624,7 @@ static void chtls_reset_synq(struct listen_ctx *listen_ctx) · 347 unmodified lines | ||
| 621 | 624 | |
| 622 | 625 | while (!skb_queue_empty(&listen_ctx->synq)) { |
| 623 | 626 | struct chtls_sock *csk = |
| 624 | − container_of((struct synq *)__skb_dequeue | |
| 627 | + container_of((struct synq *)skb_peek | |
| 625 | 628 | (&listen_ctx->synq), struct chtls_sock, synq); |
| 626 | 629 | struct sock *child = csk->sk; |
| 627 | 630 | |
| @@ -1109,6 +1112,7 @@ static struct sock *chtls_recv_sock(struct sock *lsk, · 481 unmodified lines | ||
| 1109 | 1112 | const struct cpl_pass_accept_req *req, |
| 1110 | 1113 | struct chtls_dev *cdev) |
| 1111 | 1114 | { |
| 1115 | + struct adapter *adap = pci_get_drvdata(cdev->pdev); | |
| 1112 | 1116 | struct neighbour *n = NULL; |
| 1113 | 1117 | struct inet_sock *newinet; |
| 1114 | 1118 | const struct iphdr *iph; |
| @@ -1118,9 +1122,10 @@ static struct sock *chtls_recv_sock(struct sock *lsk, · 3 unmodified lines | ||
| 1118 | 1122 | struct dst_entry *dst; |
| 1119 | 1123 | struct tcp_sock *tp; |
| 1120 | 1124 | struct sock *newsk; |
| 1125 | + bool found = false; | |
| 1121 | 1126 | u16 port_id; |
| 1122 | 1127 | int rxq_idx; |
| 1123 | − int step; | |
| 1128 | + int step, i; | |
| 1124 | 1129 | |
| 1125 | 1130 | iph = (const struct iphdr *)network_hdr; |
| 1126 | 1131 | newsk = tcp_create_openreq_child(lsk, oreq, cdev->askb); |
| @@ -1152,7 +1157,7 @@ static struct sock *chtls_recv_sock(struct sock *lsk, · 25 unmodified lines | ||
| 1152 | 1157 | n = dst_neigh_lookup(dst, &ip6h->saddr); |
| 1153 | 1158 | #endif |
| 1154 | 1159 | } |
| 1155 | − if (!n) | |
| 1160 | + if (!n || !n->dev) | |
| 1156 | 1161 | goto free_sk; |
| 1157 | 1162 | |
| 1158 | 1163 | ndev = n->dev; |
| @@ -1161,6 +1166,13 @@ static struct sock *chtls_recv_sock(struct sock *lsk, · 2 unmodified lines | ||
| 1161 | 1166 | if (is_vlan_dev(ndev)) |
| 1162 | 1167 | ndev = vlan_dev_real_dev(ndev); |
| 1163 | 1168 | |
| 1169 | + for_each_port(adap, i) | |
| 1170 | + if (cdev->ports[i] == ndev) | |
| 1171 | + found = true; | |
| 1172 | + | |
| 1173 | + if (!found) | |
| 1174 | + goto free_dst; | |
| 1175 | + | |
| 1164 | 1176 | port_id = cxgb4_port_idx(ndev); |
| 1165 | 1177 | |
| 1166 | 1178 | csk = chtls_sock_create(cdev); |
| @@ -1238,6 +1250,7 @@ static struct sock *chtls_recv_sock(struct sock *lsk, · 71 unmodified lines | ||
| 1238 | 1250 | free_csk: |
| 1239 | 1251 | chtls_sock_release(&csk->kref); |
| 1240 | 1252 | free_dst: |
| 1253 | + neigh_release(n); | |
| 1241 | 1254 | dst_release(dst); |
| 1242 | 1255 | free_sk: |
| 1243 | 1256 | inet_csk_prepare_forced_close(newsk); |
| @@ -1387,7 +1400,7 @@ static void chtls_pass_accept_request(struct sock *sk, · 143 unmodified lines | ||
| 1387 | 1400 | |
| 1388 | 1401 | newsk = chtls_recv_sock(sk, oreq, network_hdr, req, cdev); |
| 1389 | 1402 | if (!newsk) |
| 1390 | − goto free_oreq; | |
| 1403 | + goto reject; | |
| 1391 | 1404 | |
| 1392 | 1405 | if (chtls_get_module(newsk)) |
| 1393 | 1406 | goto reject; |
| @@ -1403,8 +1416,6 @@ static void chtls_pass_accept_request(struct sock *sk, · 9 unmodified lines | ||
| 1403 | 1416 | kfree_skb(skb); |
| 1404 | 1417 | return; |
| 1405 | 1418 | |
| 1406 | −free_oreq: | |
| 1407 | − chtls_reqsk_free(oreq); | |
| 1408 | 1419 | reject: |
| 1409 | 1420 | mk_tid_release(reply_skb, 0, tid); |
| 1410 | 1421 | cxgb4_ofld_send(cdev->lldi->ports[0], reply_skb); |
| @@ -1589,6 +1600,11 @@ static int chtls_pass_establish(struct chtls_dev *cdev, struct sk_buff *skb) · 178 unmodified lines | ||
| 1589 | 1600 | sk_wake_async(sk, 0, POLL_OUT); |
| 1590 | 1601 | |
| 1591 | 1602 | data = lookup_stid(cdev->tids, stid); |
| 1603 | + if (!data) { | |
| 1604 | + /* listening server close */ | |
| 1605 | + kfree_skb(skb); | |
| 1606 | + goto unlock; | |
| 1607 | + } | |
| 1592 | 1608 | lsk = ((struct listen_ctx *)data)->lsk; |
| 1593 | 1609 | |
| 1594 | 1610 | bh_lock_sock(lsk); |
| @@ -1936,6 +1952,8 @@ static void chtls_close_con_rpl(struct sock *sk, struct sk_buff *skb) · 341 unmodified lines | ||
| 1936 | 1952 | else if (tcp_sk(sk)->linger2 < 0 && |
| 1937 | 1953 | !csk_flag_nochk(csk, CSK_ABORT_SHUTDOWN)) |
| 1938 | 1954 | chtls_abort_conn(sk, skb); |
| 1955 | + else if (csk_flag_nochk(csk, CSK_TX_DATA_SENT)) | |
| 1956 | + chtls_set_quiesce_ctrl(sk, 0); | |
| 1939 | 1957 | break; |
| 1940 | 1958 | default: |
| 1941 | 1959 | pr_info("close_con_rpl in bad state %d\n", sk->sk_state); |
| @@ -1997,39 +2015,6 @@ static void t4_defer_reply(struct sk_buff *skb, struct chtls_dev *cdev, · 55 unmodified lines | ||
| 1997 | 2015 | spin_unlock_bh(&cdev->deferq.lock); |
| 1998 | 2016 | } |
| 1999 | 2017 | |
| 2000 | −static void send_abort_rpl(struct sock *sk, struct sk_buff *skb, | |
| 2001 | − struct chtls_dev *cdev, int status, int queue) | |
| 2002 | −{ | |
| 2003 | − struct cpl_abort_req_rss *req = cplhdr(skb); | |
| 2004 | − struct sk_buff *reply_skb; | |
| 2005 | − struct chtls_sock *csk; | |
| 2006 | − | |
| 2007 | − csk = rcu_dereference_sk_user_data(sk); | |
| 2008 | − | |
| 2009 | − reply_skb = alloc_skb(sizeof(struct cpl_abort_rpl), | |
| 2010 | − GFP_KERNEL); | |
| 2011 | − | |
| 2012 | − if (!reply_skb) { | |
| 2013 | − req->status = (queue << 1); | |
| 2014 | − t4_defer_reply(skb, cdev, send_defer_abort_rpl); | |
| 2015 | − return; | |
| 2016 | − } | |
| 2017 | − | |
| 2018 | − set_abort_rpl_wr(reply_skb, GET_TID(req), status); | |
| 2019 | − kfree_skb(skb); | |
| 2020 | − | |
| 2021 | − set_wr_txq(reply_skb, CPL_PRIORITY_DATA, queue); | |
| 2022 | − if (csk_conn_inline(csk)) { | |
| 2023 | − struct l2t_entry *e = csk->l2t_entry; | |
| 2024 | − | |
| 2025 | − if (e && sk->sk_state != TCP_SYN_RECV) { | |
| 2026 | − cxgb4_l2t_send(csk->egress_dev, reply_skb, e); | |
| 2027 | − return; | |
| 2028 | − } | |
| 2029 | − } | |
| 2030 | − cxgb4_ofld_send(cdev->lldi->ports[0], reply_skb); | |
| 2031 | −} | |
| 2032 | − | |
| 2033 | 2018 | static void chtls_send_abort_rpl(struct sock *sk, struct sk_buff *skb, |
| 2034 | 2019 | struct chtls_dev *cdev, |
| 2035 | 2020 | int status, int queue) |
| @@ -2078,9 +2063,9 @@ static void bl_abort_syn_rcv(struct sock *lsk, struct sk_buff *skb) · 42 unmodified lines | ||
| 2078 | 2063 | queue = csk->txq_idx; |
| 2079 | 2064 | |
| 2080 | 2065 | skb->sk = NULL; |
| 2066 | + chtls_send_abort_rpl(child, skb, BLOG_SKB_CB(skb)->cdev, | |
| 2067 | + CPL_ABORT_NO_RST, queue); | |
| 2081 | 2068 | do_abort_syn_rcv(child, lsk); |
| 2082 | − send_abort_rpl(child, skb, BLOG_SKB_CB(skb)->cdev, | |
| 2083 | − CPL_ABORT_NO_RST, queue); | |
| 2084 | 2069 | } |
| 2085 | 2070 | |
| 2086 | 2071 | static int abort_syn_rcv(struct sock *sk, struct sk_buff *skb) |
| @@ -2110,8 +2095,8 @@ static int abort_syn_rcv(struct sock *sk, struct sk_buff *skb) · 23 unmodified lines | ||
| 2110 | 2095 | if (!sock_owned_by_user(psk)) { |
| 2111 | 2096 | int queue = csk->txq_idx; |
| 2112 | 2097 | |
| 2098 | + chtls_send_abort_rpl(sk, skb, cdev, CPL_ABORT_NO_RST, queue); | |
| 2113 | 2099 | do_abort_syn_rcv(sk, psk); |
| 2114 | − send_abort_rpl(sk, skb, cdev, CPL_ABORT_NO_RST, queue); | |
| 2115 | 2100 | } else { |
| 2116 | 2101 | skb->sk = sk; |
| 2117 | 2102 | BLOG_SKB_CB(skb)->backlog_rcv = bl_abort_syn_rcv; |
| @@ -2129,9 +2114,6 @@ static void chtls_abort_req_rss(struct sock *sk, struct sk_buff *skb) · 11 unmodified lines | ||
| 2129 | 2114 | int queue = csk->txq_idx; |
| 2130 | 2115 | |
| 2131 | 2116 | if (is_neg_adv(req->status)) { |
| 2132 | − if (sk->sk_state == TCP_SYN_RECV) | |
| 2133 | − chtls_set_tcb_tflag(sk, 0, 0); | |
| 2134 | − | |
| 2135 | 2117 | kfree_skb(skb); |
| 2136 | 2118 | return; |
| 2137 | 2119 | } |
| @@ -2158,12 +2140,12 @@ static void chtls_abort_req_rss(struct sock *sk, struct sk_buff *skb) · 20 unmodified lines | ||
| 2158 | 2140 | if (sk->sk_state == TCP_SYN_RECV && !abort_syn_rcv(sk, skb)) |
| 2159 | 2141 | return; |
| 2160 | 2142 | |
| 2161 | − chtls_release_resources(sk); | |
| 2162 | − chtls_conn_done(sk); | |
| 2163 | 2143 | } |
| 2164 | 2144 | |
| 2165 | 2145 | chtls_send_abort_rpl(sk, skb, BLOG_SKB_CB(skb)->cdev, |
| 2166 | 2146 | rst_status, queue); |
| 2147 | + chtls_release_resources(sk); | |
| 2148 | + chtls_conn_done(sk); | |
| 2167 | 2149 | } |
| 2168 | 2150 | |
| 2169 | 2151 | static void chtls_abort_rpl_rss(struct sock *sk, struct sk_buff *skb) |
| @@ -2315,6 +2297,28 @@ static int chtls_wr_ack(struct chtls_dev *cdev, struct sk_buff *skb) · 145 unmodified lines | ||
| 2315 | 2297 | return 0; |
| 2316 | 2298 | } |
| 2317 | 2299 | |
| 2300 | +static int chtls_set_tcb_rpl(struct chtls_dev *cdev, struct sk_buff *skb) | |
| 2301 | +{ | |
| 2302 | + struct cpl_set_tcb_rpl *rpl = cplhdr(skb) + RSS_HDR; | |
| 2303 | + unsigned int hwtid = GET_TID(rpl); | |
| 2304 | + struct sock *sk; | |
| 2305 | + | |
| 2306 | + sk = lookup_tid(cdev->tids, hwtid); | |
| 2307 | + | |
| 2308 | + /* return EINVAL if socket doesn't exist */ | |
| 2309 | + if (!sk) | |
| 2310 | + return -EINVAL; | |
| 2311 | + | |
| 2312 | + /* Reusing the skb as size of cpl_set_tcb_field structure | |
| 2313 | + * is greater than cpl_abort_req | |
| 2314 | + */ | |
| 2315 | + if (TCB_COOKIE_G(rpl->cookie) == TCB_FIELD_COOKIE_TFLAG) | |
| 2316 | + chtls_send_abort(sk, CPL_ABORT_SEND_RST, NULL); | |
| 2317 | + | |
| 2318 | + kfree_skb(skb); | |
| 2319 | + return 0; | |
| 2320 | +} | |
| 2321 | + | |
| 2318 | 2322 | chtls_handler_func chtls_handlers[NUM_CPL_CMDS] = { |
| 2319 | 2323 | [CPL_PASS_OPEN_RPL] = chtls_pass_open_rpl, |
| 2320 | 2324 | [CPL_CLOSE_LISTSRV_RPL] = chtls_close_listsrv_rpl, |
| @@ -2327,5 +2331,6 @@ chtls_handler_func chtls_handlers[NUM_CPL_CMDS] = { · 6 unmodified lines | ||
| 2327 | 2331 | [CPL_CLOSE_CON_RPL] = chtls_conn_cpl, |
| 2328 | 2332 | [CPL_ABORT_REQ_RSS] = chtls_conn_cpl, |
| 2329 | 2333 | [CPL_ABORT_RPL_RSS] = chtls_conn_cpl, |
| 2330 | − [CPL_FW4_ACK] = chtls_wr_ack, | |
| 2334 | + [CPL_FW4_ACK] = chtls_wr_ack, | |
| 2335 | + [CPL_SET_TCB_RPL] = chtls_set_tcb_rpl, | |
| 2331 | 2336 | }; |
| @@ -88,6 +88,24 @@ static int chtls_set_tcb_field(struct sock *sk, u16 word, u64 mask, u64 val) · 87 unmodified lines | ||
| 88 | 88 | return ret < 0 ? ret : 0; |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | +void chtls_set_tcb_field_rpl_skb(struct sock *sk, u16 word, | |
| 92 | + u64 mask, u64 val, u8 cookie, | |
| 93 | + int through_l2t) | |
| 94 | +{ | |
| 95 | + struct sk_buff *skb; | |
| 96 | + unsigned int wrlen; | |
| 97 | + | |
| 98 | + wrlen = sizeof(struct cpl_set_tcb_field) + sizeof(struct ulptx_idata); | |
| 99 | + wrlen = roundup(wrlen, 16); | |
| 100 | + | |
| 101 | + skb = alloc_skb(wrlen, GFP_KERNEL | __GFP_NOFAIL); | |
| 102 | + if (!skb) | |
| 103 | + return; | |
| 104 | + | |
| 105 | + __set_tcb_field(sk, skb, word, mask, val, cookie, 0); | |
| 106 | + send_or_defer(sk, tcp_sk(sk), skb, through_l2t); | |
| 107 | +} | |
| 108 | + | |
| 91 | 109 | /* |
| 92 | 110 | * Set one of the t_flags bits in the TCB. |
| 93 | 111 | */ |
| @@ -113,6 +131,29 @@ static int chtls_set_tcb_quiesce(struct sock *sk, int val) · 19 unmodified lines | ||
| 113 | 131 | TF_RX_QUIESCE_V(val)); |
| 114 | 132 | } |
| 115 | 133 | |
| 134 | +void chtls_set_quiesce_ctrl(struct sock *sk, int val) | |
| 135 | +{ | |
| 136 | + struct chtls_sock *csk; | |
| 137 | + struct sk_buff *skb; | |
| 138 | + unsigned int wrlen; | |
| 139 | + int ret; | |
| 140 | + | |
| 141 | + wrlen = sizeof(struct cpl_set_tcb_field) + sizeof(struct ulptx_idata); | |
| 142 | + wrlen = roundup(wrlen, 16); | |
| 143 | + | |
| 144 | + skb = alloc_skb(wrlen, GFP_ATOMIC); | |
| 145 | + if (!skb) | |
| 146 | + return; | |
| 147 | + | |
| 148 | + csk = rcu_dereference_sk_user_data(sk); | |
| 149 | + | |
| 150 | + __set_tcb_field(sk, skb, 1, TF_RX_QUIESCE_V(1), 0, 0, 1); | |
| 151 | + set_wr_txq(skb, CPL_PRIORITY_CONTROL, csk->port_id); | |
| 152 | + ret = cxgb4_ofld_send(csk->egress_dev, skb); | |
| 153 | + if (ret < 0) | |
| 154 | + kfree_skb(skb); | |
| 155 | +} | |
| 156 | + | |
| 116 | 157 | /* TLS Key bitmap processing */ |
| 117 | 158 | int chtls_init_kmap(struct chtls_dev *cdev, struct cxgb4_lld_info *lldi) |
| 118 | 159 | { |
| @@ -1211,7 +1211,7 @@ static int ethoc_probe(struct platform_device *pdev) · 1210 unmodified lines | ||
| 1211 | 1211 | ret = mdiobus_register(priv->mdio); |
| 1212 | 1212 | if (ret) { |
| 1213 | 1213 | dev_err(&netdev->dev, "failed to register MDIO bus\n"); |
| 1214 | − goto free2; | |
| 1214 | + goto free3; | |
| 1215 | 1215 | } |
| 1216 | 1216 | |
| 1217 | 1217 | ret = ethoc_mdio_probe(netdev); |
| @@ -1243,6 +1243,7 @@ error2: · 25 unmodified lines | ||
| 1243 | 1243 | netif_napi_del(&priv->napi); |
| 1244 | 1244 | error: |
| 1245 | 1245 | mdiobus_unregister(priv->mdio); |
| 1246 | +free3: | |
| 1246 | 1247 | mdiobus_free(priv->mdio); |
| 1247 | 1248 | free2: |
| 1248 | 1249 | clk_disable_unprepare(priv->clk); |
| @@ -223,3 +223,4 @@ static struct platform_driver fs_enet_bb_mdio_driver = { · 222 unmodified lines | ||
| 223 | 223 | }; |
| 224 | 224 | |
| 225 | 225 | module_platform_driver(fs_enet_bb_mdio_driver); |
| 226 | +MODULE_LICENSE("GPL"); | |
| @@ -224,3 +224,4 @@ static struct platform_driver fs_enet_fec_mdio_driver = { · 223 unmodified lines | ||
| 224 | 224 | }; |
| 225 | 225 | |
| 226 | 226 | module_platform_driver(fs_enet_fec_mdio_driver); |
| 227 | +MODULE_LICENSE("GPL"); | |
| @@ -3889,6 +3889,7 @@ static int ucc_geth_probe(struct platform_device* ofdev) · 3888 unmodified lines | ||
| 3889 | 3889 | INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work); |
| 3890 | 3890 | netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, 64); |
| 3891 | 3891 | dev->mtu = 1500; |
| 3892 | + dev->max_mtu = 1518; | |
| 3892 | 3893 | |
| 3893 | 3894 | ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT); |
| 3894 | 3895 | ugeth->phy_interface = phy_interface; |
| @@ -3934,12 +3935,12 @@ static int ucc_geth_remove(struct platform_device* ofdev) · 39 unmodified lines | ||
| 3934 | 3935 | struct device_node *np = ofdev->dev.of_node; |
| 3935 | 3936 | |
| 3936 | 3937 | unregister_netdev(dev); |
| 3937 | − free_netdev(dev); | |
| 3938 | 3938 | ucc_geth_memclean(ugeth); |
| 3939 | 3939 | if (of_phy_is_fixed_link(np)) |
| 3940 | 3940 | of_phy_deregister_fixed_link(np); |
| 3941 | 3941 | of_node_put(ugeth->ug_info->tbi_node); |
| 3942 | 3942 | of_node_put(ugeth->ug_info->phy_node); |
| 3943 | + free_netdev(dev); | |
| 3943 | 3944 | |
| 3944 | 3945 | return 0; |
| 3945 | 3946 | } |
| @@ -575,7 +575,14 @@ struct ucc_geth_tx_global_pram { · 574 unmodified lines | ||
| 575 | 575 | u32 vtagtable[0x8]; /* 8 4-byte VLAN tags */ |
| 576 | 576 | u32 tqptr; /* a base pointer to the Tx Queues Memory |
| 577 | 577 | Region */ |
| 578 | − u8 res2[0x80 - 0x74]; | |
| 578 | + u8 res2[0x78 - 0x74]; | |
| 579 | + u64 snums_en; | |
| 580 | + u32 l2l3baseptr; /* top byte consists of a few other bit fields */ | |
| 581 | + | |
| 582 | + u16 mtu[8]; | |
| 583 | + u8 res3[0xa8 - 0x94]; | |
| 584 | + u32 wrrtablebase; /* top byte is reserved */ | |
| 585 | + u8 res4[0xc0 - 0xac]; | |
| 579 | 586 | } __packed; |
| 580 | 587 | |
| 581 | 588 | /* structure representing Extended Filtering Global Parameters in PRAM */ |
| @@ -415,6 +415,10 @@ static void __lb_other_process(struct hns_nic_ring_data *ring_data, · 414 unmodified lines | ||
| 415 | 415 | /* for mutl buffer*/ |
| 416 | 416 | new_skb = skb_copy(skb, GFP_ATOMIC); |
| 417 | 417 | dev_kfree_skb_any(skb); |
| 418 | + if (!new_skb) { | |
| 419 | + netdev_err(ndev, "skb alloc failed\n"); | |
| 420 | + return; | |
| 421 | + } | |
| 418 | 422 | skb = new_skb; |
| 419 | 423 | |
| 420 | 424 | check_ok = 0; |
| @@ -169,7 +169,7 @@ struct hclgevf_mbx_arq_ring { · 168 unmodified lines | ||
| 169 | 169 | #define hclge_mbx_ring_ptr_move_crq(crq) \ |
| 170 | 170 | (crq->next_to_use = (crq->next_to_use + 1) % crq->desc_num) |
| 171 | 171 | #define hclge_mbx_tail_ptr_move_arq(arq) \ |
| 172 | − (arq.tail = (arq.tail + 1) % HCLGE_MBX_MAX_ARQ_MSG_SIZE) | |
| 172 | + (arq.tail = (arq.tail + 1) % HCLGE_MBX_MAX_ARQ_MSG_NUM) | |
| 173 | 173 | #define hclge_mbx_head_ptr_move_arq(arq) \ |
| 174 | − (arq.head = (arq.head + 1) % HCLGE_MBX_MAX_ARQ_MSG_SIZE) | |
| 174 | + (arq.head = (arq.head + 1) % HCLGE_MBX_MAX_ARQ_MSG_NUM) | |
| 175 | 175 | #endif |
| @@ -752,7 +752,8 @@ static int hclge_get_sset_count(struct hnae3_handle *handle, int stringset) · 751 unmodified lines | ||
| 752 | 752 | handle->flags |= HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK; |
| 753 | 753 | handle->flags |= HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK; |
| 754 | 754 | |
| 755 | − if (hdev->hw.mac.phydev) { | |
| 755 | + if (hdev->hw.mac.phydev && hdev->hw.mac.phydev->drv && | |
| 756 | + hdev->hw.mac.phydev->drv->set_loopback) { | |
| 756 | 757 | count += 1; |
| 757 | 758 | handle->flags |= HNAE3_SUPPORT_PHY_LOOPBACK; |
| 758 | 759 | } |
| @@ -4537,8 +4538,8 @@ static int hclge_set_rss_tuple(struct hnae3_handle *handle, · 3778 unmodified lines | ||
| 4537 | 4538 | req->ipv4_sctp_en = tuple_sets; |
| 4538 | 4539 | break; |
| 4539 | 4540 | case SCTP_V6_FLOW: |
| 4540 | − if ((nfc->data & RXH_L4_B_0_1) || | |
| 4541 | − (nfc->data & RXH_L4_B_2_3)) | |
| 4541 | + if (hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 && | |
| 4542 | + (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3))) | |
| 4542 | 4543 | return -EINVAL; |
| 4543 | 4544 | |
| 4544 | 4545 | req->ipv6_sctp_en = tuple_sets; |
| @@ -4730,6 +4731,8 @@ static void hclge_rss_init_cfg(struct hclge_dev *hdev) · 185 unmodified lines | ||
| 4730 | 4731 | vport[i].rss_tuple_sets.ipv6_udp_en = |
| 4731 | 4732 | HCLGE_RSS_INPUT_TUPLE_OTHER; |
| 4732 | 4733 | vport[i].rss_tuple_sets.ipv6_sctp_en = |
| 4734 | + hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 ? | |
| 4735 | + HCLGE_RSS_INPUT_TUPLE_SCTP_NO_PORT : | |
| 4733 | 4736 | HCLGE_RSS_INPUT_TUPLE_SCTP; |
| 4734 | 4737 | vport[i].rss_tuple_sets.ipv6_fragment_en = |
| 4735 | 4738 | HCLGE_RSS_INPUT_TUPLE_OTHER; |
| @@ -107,6 +107,8 @@ · 106 unmodified lines | ||
| 107 | 107 | #define HCLGE_D_IP_BIT BIT(2) |
| 108 | 108 | #define HCLGE_S_IP_BIT BIT(3) |
| 109 | 109 | #define HCLGE_V_TAG_BIT BIT(4) |
| 110 | +#define HCLGE_RSS_INPUT_TUPLE_SCTP_NO_PORT \ | |
| 111 | + (HCLGE_D_IP_BIT | HCLGE_S_IP_BIT | HCLGE_V_TAG_BIT) | |
| 110 | 112 | |
| 111 | 113 | #define HCLGE_RSS_TC_SIZE_0 1 |
| 112 | 114 | #define HCLGE_RSS_TC_SIZE_1 2 |
| @@ -917,8 +917,8 @@ static int hclgevf_set_rss_tuple(struct hnae3_handle *handle, · 916 unmodified lines | ||
| 917 | 917 | req->ipv4_sctp_en = tuple_sets; |
| 918 | 918 | break; |
| 919 | 919 | case SCTP_V6_FLOW: |
| 920 | − if ((nfc->data & RXH_L4_B_0_1) || | |
| 921 | − (nfc->data & RXH_L4_B_2_3)) | |
| 920 | + if (hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 && | |
| 921 | + (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3))) | |
| 922 | 922 | return -EINVAL; |
| 923 | 923 | |
| 924 | 924 | req->ipv6_sctp_en = tuple_sets; |
| @@ -2502,7 +2502,10 @@ static void hclgevf_rss_init_cfg(struct hclgevf_dev *hdev) · 1577 unmodified lines | ||
| 2502 | 2502 | tuple_sets->ipv4_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; |
| 2503 | 2503 | tuple_sets->ipv6_tcp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; |
| 2504 | 2504 | tuple_sets->ipv6_udp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; |
| 2505 | − tuple_sets->ipv6_sctp_en = HCLGEVF_RSS_INPUT_TUPLE_SCTP; | |
| 2505 | + tuple_sets->ipv6_sctp_en = | |
| 2506 | + hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 ? | |
| 2507 | + HCLGEVF_RSS_INPUT_TUPLE_SCTP_NO_PORT : | |
| 2508 | + HCLGEVF_RSS_INPUT_TUPLE_SCTP; | |
| 2506 | 2509 | tuple_sets->ipv6_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; |
| 2507 | 2510 | } |
| 2508 | 2511 | |
| @@ -122,6 +122,8 @@ · 121 unmodified lines | ||
| 122 | 122 | #define HCLGEVF_D_IP_BIT BIT(2) |
| 123 | 123 | #define HCLGEVF_S_IP_BIT BIT(3) |
| 124 | 124 | #define HCLGEVF_V_TAG_BIT BIT(4) |
| 125 | +#define HCLGEVF_RSS_INPUT_TUPLE_SCTP_NO_PORT \ | |
| 126 | + (HCLGEVF_D_IP_BIT | HCLGEVF_S_IP_BIT | HCLGEVF_V_TAG_BIT) | |
| 125 | 127 | |
| 126 | 128 | #define HCLGEVF_STATS_TIMER_INTERVAL 36U |
| 127 | 129 | |
| @@ -955,6 +955,7 @@ static void release_resources(struct ibmvnic_adapter *adapter) · 954 unmodified lines | ||
| 955 | 955 | release_rx_pools(adapter); |
| 956 | 956 | |
| 957 | 957 | release_napi(adapter); |
| 958 | + release_login_buffer(adapter); | |
| 958 | 959 | release_login_rsp_buffer(adapter); |
| 959 | 960 | } |
| 960 | 961 | |
| @@ -2341,8 +2342,7 @@ static void __ibmvnic_reset(struct work_struct *work) · 1380 unmodified lines | ||
| 2341 | 2342 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 2342 | 2343 | schedule_timeout(60 * HZ); |
| 2343 | 2344 | } |
| 2344 | − } else if (!(rwi->reset_reason == VNIC_RESET_FATAL && | |
| 2345 | − adapter->from_passive_init)) { | |
| 2345 | + } else { | |
| 2346 | 2346 | rc = do_reset(adapter, rwi, reset_state); |
| 2347 | 2347 | } |
| 2348 | 2348 | kfree(rwi); |
| @@ -2981,9 +2981,7 @@ static int reset_one_sub_crq_queue(struct ibmvnic_adapter *adapter, · 632 unmodified lines | ||
| 2981 | 2981 | int rc; |
| 2982 | 2982 | |
| 2983 | 2983 | if (!scrq) { |
| 2984 | − netdev_dbg(adapter->netdev, | |
| 2985 | − "Invalid scrq reset. irq (%d) or msgs (%p).\n", | |
| 2986 | − scrq->irq, scrq->msgs); | |
| 2984 | + netdev_dbg(adapter->netdev, "Invalid scrq reset.\n"); | |
| 2987 | 2985 | return -EINVAL; |
| 2988 | 2986 | } |
| 2989 | 2987 | |
| @@ -3873,7 +3871,9 @@ static int send_login(struct ibmvnic_adapter *adapter) · 883 unmodified lines | ||
| 3873 | 3871 | return -1; |
| 3874 | 3872 | } |
| 3875 | 3873 | |
| 3874 | + release_login_buffer(adapter); | |
| 3876 | 3875 | release_login_rsp_buffer(adapter); |
| 3876 | + | |
| 3877 | 3877 | client_data_len = vnic_client_data_len(adapter); |
| 3878 | 3878 | |
| 3879 | 3879 | buffer_size = |
| @@ -436,6 +436,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca); · 435 unmodified lines | ||
| 436 | 436 | #define FLAG2_DFLT_CRC_STRIPPING BIT(12) |
| 437 | 437 | #define FLAG2_CHECK_RX_HWTSTAMP BIT(13) |
| 438 | 438 | #define FLAG2_CHECK_SYSTIM_OVERFLOW BIT(14) |
| 439 | +#define FLAG2_ENABLE_S0IX_FLOWS BIT(15) | |
| 439 | 440 | |
| 440 | 441 | #define E1000_RX_DESC_PS(R, i) \ |
| 441 | 442 | (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) |
| @@ -23,6 +23,13 @@ struct e1000_stats { · 22 unmodified lines | ||
| 23 | 23 | int stat_offset; |
| 24 | 24 | }; |
| 25 | 25 | |
| 26 | +static const char e1000e_priv_flags_strings[][ETH_GSTRING_LEN] = { | |
| 27 | +#define E1000E_PRIV_FLAGS_S0IX_ENABLED BIT(0) | |
| 28 | + "s0ix-enabled", | |
| 29 | +}; | |
| 30 | + | |
| 31 | +#define E1000E_PRIV_FLAGS_STR_LEN ARRAY_SIZE(e1000e_priv_flags_strings) | |
| 32 | + | |
| 26 | 33 | #define E1000_STAT(str, m) { \ |
| 27 | 34 | .stat_string = str, \ |
| 28 | 35 | .type = E1000_STATS, \ |
| @@ -1776,6 +1783,8 @@ static int e1000e_get_sset_count(struct net_device __always_unused *netdev, · 1747 unmodified lines | ||
| 1776 | 1783 | return E1000_TEST_LEN; |
| 1777 | 1784 | case ETH_SS_STATS: |
| 1778 | 1785 | return E1000_STATS_LEN; |
| 1786 | + case ETH_SS_PRIV_FLAGS: | |
| 1787 | + return E1000E_PRIV_FLAGS_STR_LEN; | |
| 1779 | 1788 | default: |
| 1780 | 1789 | return -EOPNOTSUPP; |
| 1781 | 1790 | } |
| @@ -2097,6 +2106,10 @@ static void e1000_get_strings(struct net_device __always_unused *netdev, · 315 unmodified lines | ||
| 2097 | 2106 | p += ETH_GSTRING_LEN; |
| 2098 | 2107 | } |
| 2099 | 2108 | break; |
| 2109 | + case ETH_SS_PRIV_FLAGS: | |
| 2110 | + memcpy(data, e1000e_priv_flags_strings, | |
| 2111 | + E1000E_PRIV_FLAGS_STR_LEN * ETH_GSTRING_LEN); | |
| 2112 | + break; | |
| 2100 | 2113 | } |
| 2101 | 2114 | } |
| 2102 | 2115 | |
| @@ -2305,6 +2318,37 @@ static int e1000e_get_ts_info(struct net_device *netdev, · 202 unmodified lines | ||
| 2305 | 2318 | return 0; |
| 2306 | 2319 | } |
| 2307 | 2320 | |
| 2321 | +static u32 e1000e_get_priv_flags(struct net_device *netdev) | |
| 2322 | +{ | |
| 2323 | + struct e1000_adapter *adapter = netdev_priv(netdev); | |
| 2324 | + u32 priv_flags = 0; | |
| 2325 | + | |
| 2326 | + if (adapter->flags2 & FLAG2_ENABLE_S0IX_FLOWS) | |
| 2327 | + priv_flags |= E1000E_PRIV_FLAGS_S0IX_ENABLED; | |
| 2328 | + | |
| 2329 | + return priv_flags; | |
| 2330 | +} | |
| 2331 | + | |
| 2332 | +static int e1000e_set_priv_flags(struct net_device *netdev, u32 priv_flags) | |
| 2333 | +{ | |
| 2334 | + struct e1000_adapter *adapter = netdev_priv(netdev); | |
| 2335 | + unsigned int flags2 = adapter->flags2; | |
| 2336 | + | |
| 2337 | + flags2 &= ~FLAG2_ENABLE_S0IX_FLOWS; | |
| 2338 | + if (priv_flags & E1000E_PRIV_FLAGS_S0IX_ENABLED) { | |
| 2339 | + struct e1000_hw *hw = &adapter->hw; | |
| 2340 | + | |
| 2341 | + if (hw->mac.type < e1000_pch_cnp) | |
| 2342 | + return -EINVAL; | |
| 2343 | + flags2 |= FLAG2_ENABLE_S0IX_FLOWS; | |
| 2344 | + } | |
| 2345 | + | |
| 2346 | + if (flags2 != adapter->flags2) | |
| 2347 | + adapter->flags2 = flags2; | |
| 2348 | + | |
| 2349 | + return 0; | |
| 2350 | +} | |
| 2351 | + | |
| 2308 | 2352 | static const struct ethtool_ops e1000_ethtool_ops = { |
| 2309 | 2353 | .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS, |
| 2310 | 2354 | .get_drvinfo = e1000_get_drvinfo, |
| @@ -2336,6 +2380,8 @@ static const struct ethtool_ops e1000_ethtool_ops = { · 25 unmodified lines | ||
| 2336 | 2380 | .set_eee = e1000e_set_eee, |
| 2337 | 2381 | .get_link_ksettings = e1000_get_link_ksettings, |
| 2338 | 2382 | .set_link_ksettings = e1000_set_link_ksettings, |
| 2383 | + .get_priv_flags = e1000e_get_priv_flags, | |
| 2384 | + .set_priv_flags = e1000e_set_priv_flags, | |
| 2339 | 2385 | }; |
| 2340 | 2386 | |
| 2341 | 2387 | void e1000e_set_ethtool_ops(struct net_device *netdev) |
| @@ -1240,6 +1240,9 @@ static s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force) · 1239 unmodified lines | ||
| 1240 | 1240 | return 0; |
| 1241 | 1241 | |
| 1242 | 1242 | if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) { |
| 1243 | + struct e1000_adapter *adapter = hw->adapter; | |
| 1244 | + bool firmware_bug = false; | |
| 1245 | + | |
| 1243 | 1246 | if (force) { |
| 1244 | 1247 | /* Request ME un-configure ULP mode in the PHY */ |
| 1245 | 1248 | mac_reg = er32(H2ME); |
| @@ -1248,16 +1251,24 @@ static s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force) · 2 unmodified lines | ||
| 1248 | 1251 | ew32(H2ME, mac_reg); |
| 1249 | 1252 | } |
| 1250 | 1253 | |
| 1251 | − /* Poll up to 300msec for ME to clear ULP_CFG_DONE. */ | |
| 1254 | + /* Poll up to 2.5 seconds for ME to clear ULP_CFG_DONE. | |
| 1255 | + * If this takes more than 1 second, show a warning indicating a | |
| 1256 | + * firmware bug | |
| 1257 | + */ | |
| 1252 | 1258 | while (er32(FWSM) & E1000_FWSM_ULP_CFG_DONE) { |
| 1253 | − if (i++ == 30) { | |
| 1259 | + if (i++ == 250) { | |
| 1254 | 1260 | ret_val = -E1000_ERR_PHY; |
| 1255 | 1261 | goto out; |
| 1256 | 1262 | } |
| 1263 | + if (i > 100 && !firmware_bug) | |
| 1264 | + firmware_bug = true; | |
| 1257 | 1265 | |
| 1258 | 1266 | usleep_range(10000, 11000); |
| 1259 | 1267 | } |
| 1260 | − e_dbg("ULP_CONFIG_DONE cleared after %dmsec\n", i * 10); | |
| 1268 | + if (firmware_bug) | |
| 1269 | + e_warn("ULP_CONFIG_DONE took %dmsec. This is a firmware bug\n", i * 10); | |
| 1270 | + else | |
| 1271 | + e_dbg("ULP_CONFIG_DONE cleared after %dmsec\n", i * 10); | |
| 1261 | 1272 | |
| 1262 | 1273 | if (force) { |
| 1263 | 1274 | mac_reg = er32(H2ME); |
| @@ -103,45 +103,6 @@ static const struct e1000_reg_info e1000_reg_info_tbl[] = { · 102 unmodified lines | ||
| 103 | 103 | {0, NULL} |
| 104 | 104 | }; |
| 105 | 105 | |
| 106 | −struct e1000e_me_supported { | |
| 107 | − u16 device_id; /* supported device ID */ | |
| 108 | −}; | |
| 109 | − | |
| 110 | −static const struct e1000e_me_supported me_supported[] = { | |
| 111 | − {E1000_DEV_ID_PCH_LPT_I217_LM}, | |
| 112 | − {E1000_DEV_ID_PCH_LPTLP_I218_LM}, | |
| 113 | − {E1000_DEV_ID_PCH_I218_LM2}, | |
| 114 | − {E1000_DEV_ID_PCH_I218_LM3}, | |
| 115 | − {E1000_DEV_ID_PCH_SPT_I219_LM}, | |
| 116 | − {E1000_DEV_ID_PCH_SPT_I219_LM2}, | |
| 117 | − {E1000_DEV_ID_PCH_LBG_I219_LM3}, | |
| 118 | − {E1000_DEV_ID_PCH_SPT_I219_LM4}, | |
| 119 | − {E1000_DEV_ID_PCH_SPT_I219_LM5}, | |
| 120 | − {E1000_DEV_ID_PCH_CNP_I219_LM6}, | |
| 121 | − {E1000_DEV_ID_PCH_CNP_I219_LM7}, | |
| 122 | − {E1000_DEV_ID_PCH_ICP_I219_LM8}, | |
| 123 | − {E1000_DEV_ID_PCH_ICP_I219_LM9}, | |
| 124 | − {E1000_DEV_ID_PCH_CMP_I219_LM10}, | |
| 125 | − {E1000_DEV_ID_PCH_CMP_I219_LM11}, | |
| 126 | − {E1000_DEV_ID_PCH_CMP_I219_LM12}, | |
| 127 | − {E1000_DEV_ID_PCH_TGP_I219_LM13}, | |
| 128 | − {E1000_DEV_ID_PCH_TGP_I219_LM14}, | |
| 129 | − {E1000_DEV_ID_PCH_TGP_I219_LM15}, | |
| 130 | − {0} | |
| 131 | −}; | |
| 132 | − | |
| 133 | −static bool e1000e_check_me(u16 device_id) | |
| 134 | −{ | |
| 135 | − struct e1000e_me_supported *id; | |
| 136 | − | |
| 137 | − for (id = (struct e1000e_me_supported *)me_supported; | |
| 138 | − id->device_id; id++) | |
| 139 | − if (device_id == id->device_id) | |
| 140 | − return true; | |
| 141 | − | |
| 142 | − return false; | |
| 143 | −} | |
| 144 | − | |
| 145 | 106 | /** |
| 146 | 107 | * __ew32_prepare - prepare to write to MAC CSR register on certain parts |
| 147 | 108 | * @hw: pointer to the HW structure |
| @@ -6962,7 +6923,6 @@ static __maybe_unused int e1000e_pm_suspend(struct device *dev) · 6814 unmodified lines | ||
| 6962 | 6923 | struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); |
| 6963 | 6924 | struct e1000_adapter *adapter = netdev_priv(netdev); |
| 6964 | 6925 | struct pci_dev *pdev = to_pci_dev(dev); |
| 6965 | − struct e1000_hw *hw = &adapter->hw; | |
| 6966 | 6926 | int rc; |
| 6967 | 6927 | |
| 6968 | 6928 | e1000e_flush_lpic(pdev); |
| @@ -6970,13 +6930,13 @@ static __maybe_unused int e1000e_pm_suspend(struct device *dev) · 1 unmodified line | ||
| 6970 | 6930 | e1000e_pm_freeze(dev); |
| 6971 | 6931 | |
| 6972 | 6932 | rc = __e1000_shutdown(pdev, false); |
| 6973 | − if (rc) | |
| 6933 | + if (rc) { | |
| 6974 | 6934 | e1000e_pm_thaw(dev); |
| 6975 | − | |
| 6976 | − /* Introduce S0ix implementation */ | |
| 6977 | − if (hw->mac.type >= e1000_pch_cnp && | |
| 6978 | − !e1000e_check_me(hw->adapter->pdev->device)) | |
| 6979 | − e1000e_s0ix_entry_flow(adapter); | |
| 6935 | + } else { | |
| 6936 | + /* Introduce S0ix implementation */ | |
| 6937 | + if (adapter->flags2 & FLAG2_ENABLE_S0IX_FLOWS) | |
| 6938 | + e1000e_s0ix_entry_flow(adapter); | |
| 6939 | + } | |
| 6980 | 6940 | |
| 6981 | 6941 | return rc; |
| 6982 | 6942 | } |
| @@ -6986,12 +6946,10 @@ static __maybe_unused int e1000e_pm_resume(struct device *dev) · 3 unmodified lines | ||
| 6986 | 6946 | struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); |
| 6987 | 6947 | struct e1000_adapter *adapter = netdev_priv(netdev); |
| 6988 | 6948 | struct pci_dev *pdev = to_pci_dev(dev); |
| 6989 | − struct e1000_hw *hw = &adapter->hw; | |
| 6990 | 6949 | int rc; |
| 6991 | 6950 | |
| 6992 | 6951 | /* Introduce S0ix implementation */ |
| 6993 | − if (hw->mac.type >= e1000_pch_cnp && | |
| 6994 | − !e1000e_check_me(hw->adapter->pdev->device)) | |
| 6952 | + if (adapter->flags2 & FLAG2_ENABLE_S0IX_FLOWS) | |
| 6995 | 6953 | e1000e_s0ix_exit_flow(adapter); |
| 6996 | 6954 | |
| 6997 | 6955 | rc = __e1000_resume(pdev); |
| @@ -7655,6 +7613,9 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 657 unmodified lines | ||
| 7655 | 7613 | if (!(adapter->flags & FLAG_HAS_AMT)) |
| 7656 | 7614 | e1000e_get_hw_control(adapter); |
| 7657 | 7615 | |
| 7616 | + if (hw->mac.type >= e1000_pch_cnp) | |
| 7617 | + adapter->flags2 |= FLAG2_ENABLE_S0IX_FLOWS; | |
| 7618 | + | |
| 7658 | 7619 | strlcpy(netdev->name, "eth%d", sizeof(netdev->name)); |
| 7659 | 7620 | err = register_netdev(netdev); |
| 7660 | 7621 | if (err) |
| @@ -120,6 +120,7 @@ enum i40e_state_t { · 119 unmodified lines | ||
| 120 | 120 | __I40E_RESET_INTR_RECEIVED, |
| 121 | 121 | __I40E_REINIT_REQUESTED, |
| 122 | 122 | __I40E_PF_RESET_REQUESTED, |
| 123 | + __I40E_PF_RESET_AND_REBUILD_REQUESTED, | |
| 123 | 124 | __I40E_CORE_RESET_REQUESTED, |
| 124 | 125 | __I40E_GLOBAL_RESET_REQUESTED, |
| 125 | 126 | __I40E_EMP_RESET_INTR_RECEIVED, |
| @@ -146,6 +147,8 @@ enum i40e_state_t { · 20 unmodified lines | ||
| 146 | 147 | }; |
| 147 | 148 | |
| 148 | 149 | #define I40E_PF_RESET_FLAG BIT_ULL(__I40E_PF_RESET_REQUESTED) |
| 150 | +#define I40E_PF_RESET_AND_REBUILD_FLAG \ | |
| 151 | + BIT_ULL(__I40E_PF_RESET_AND_REBUILD_REQUESTED) | |
| 149 | 152 | |
| 150 | 153 | /* VSI state flags */ |
| 151 | 154 | enum i40e_vsi_state_t { |
| @@ -36,6 +36,8 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf); · 35 unmodified lines | ||
| 36 | 36 | static void i40e_determine_queue_usage(struct i40e_pf *pf); |
| 37 | 37 | static int i40e_setup_pf_filter_control(struct i40e_pf *pf); |
| 38 | 38 | static void i40e_prep_for_reset(struct i40e_pf *pf, bool lock_acquired); |
| 39 | +static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit, | |
| 40 | + bool lock_acquired); | |
| 39 | 41 | static int i40e_reset(struct i40e_pf *pf); |
| 40 | 42 | static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired); |
| 41 | 43 | static int i40e_setup_misc_vector_for_recovery_mode(struct i40e_pf *pf); |
| @@ -8536,6 +8538,14 @@ void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags, bool lock_acquired) · 8494 unmodified lines | ||
| 8536 | 8538 | "FW LLDP is disabled\n" : |
| 8537 | 8539 | "FW LLDP is enabled\n"); |
| 8538 | 8540 | |
| 8541 | + } else if (reset_flags & I40E_PF_RESET_AND_REBUILD_FLAG) { | |
| 8542 | + /* Request a PF Reset | |
| 8543 | + * | |
| 8544 | + * Resets PF and reinitializes PFs VSI. | |
| 8545 | + */ | |
| 8546 | + i40e_prep_for_reset(pf, lock_acquired); | |
| 8547 | + i40e_reset_and_rebuild(pf, true, lock_acquired); | |
| 8548 | + | |
| 8539 | 8549 | } else if (reset_flags & BIT_ULL(__I40E_REINIT_REQUESTED)) { |
| 8540 | 8550 | int v; |
| 8541 | 8551 | |
| @@ -1772,7 +1772,7 @@ int i40e_pci_sriov_configure(struct pci_dev *pdev, int num_vfs) · 1771 unmodified lines | ||
| 1772 | 1772 | if (num_vfs) { |
| 1773 | 1773 | if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) { |
| 1774 | 1774 | pf->flags |= I40E_FLAG_VEB_MODE_ENABLED; |
| 1775 | − i40e_do_reset_safe(pf, I40E_PF_RESET_FLAG); | |
| 1775 | + i40e_do_reset_safe(pf, I40E_PF_RESET_AND_REBUILD_FLAG); | |
| 1776 | 1776 | } |
| 1777 | 1777 | ret = i40e_pci_sriov_enable(pdev, num_vfs); |
| 1778 | 1778 | goto sriov_configure_out; |
| @@ -1781,7 +1781,7 @@ int i40e_pci_sriov_configure(struct pci_dev *pdev, int num_vfs) · 2 unmodified lines | ||
| 1781 | 1781 | if (!pci_vfs_assigned(pf->pdev)) { |
| 1782 | 1782 | i40e_free_vfs(pf); |
| 1783 | 1783 | pf->flags &= ~I40E_FLAG_VEB_MODE_ENABLED; |
| 1784 | − i40e_do_reset_safe(pf, I40E_PF_RESET_FLAG); | |
| 1784 | + i40e_do_reset_safe(pf, I40E_PF_RESET_AND_REBUILD_FLAG); | |
| 1785 | 1785 | } else { |
| 1786 | 1786 | dev_warn(&pdev->dev, "Unable to free VFs because some are assigned to VMs.\n"); |
| 1787 | 1787 | ret = -EINVAL; |
| @@ -348,12 +348,12 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget) · 347 unmodified lines | ||
| 348 | 348 | * SBP is *not* set in PRT_SBPVSI (default not set). |
| 349 | 349 | */ |
| 350 | 350 | skb = i40e_construct_skb_zc(rx_ring, *bi); |
| 351 | − *bi = NULL; | |
| 352 | 351 | if (!skb) { |
| 353 | 352 | rx_ring->rx_stats.alloc_buff_failed++; |
| 354 | 353 | break; |
| 355 | 354 | } |
| 356 | 355 | |
| 356 | + *bi = NULL; | |
| 357 | 357 | cleaned_count++; |
| 358 | 358 | i40e_inc_ntc(rx_ring); |
| 359 | 359 | |
| @@ -1834,11 +1834,9 @@ static int iavf_init_get_resources(struct iavf_adapter *adapter) · 1833 unmodified lines | ||
| 1834 | 1834 | netif_tx_stop_all_queues(netdev); |
| 1835 | 1835 | if (CLIENT_ALLOWED(adapter)) { |
| 1836 | 1836 | err = iavf_lan_add_device(adapter); |
| 1837 | − if (err) { | |
| 1838 | − rtnl_unlock(); | |
| 1837 | + if (err) | |
| 1839 | 1838 | dev_info(&pdev->dev, "Failed to add VF to client API service list: %d\n", |
| 1840 | 1839 | err); |
| 1841 | − } | |
| 1842 | 1840 | } |
| 1843 | 1841 | dev_info(&pdev->dev, "MAC address: %pM\n", adapter->hw.mac.addr); |
| 1844 | 1842 | if (netdev->features & NETIF_F_GRO) |
| @@ -4432,7 +4432,7 @@ static int mvneta_xdp_setup(struct net_device *dev, struct bpf_prog *prog, · 4431 unmodified lines | ||
| 4432 | 4432 | struct bpf_prog *old_prog; |
| 4433 | 4433 | |
| 4434 | 4434 | if (prog && dev->mtu > MVNETA_MAX_RX_BUF_SIZE) { |
| 4435 | − NL_SET_ERR_MSG_MOD(extack, "Jumbo frames not supported on XDP"); | |
| 4435 | + NL_SET_ERR_MSG_MOD(extack, "MTU too large for XDP"); | |
| 4436 | 4436 | return -EOPNOTSUPP; |
| 4437 | 4437 | } |
| 4438 | 4438 | |
| @@ -5255,7 +5255,7 @@ static int mvneta_probe(struct platform_device *pdev) · 816 unmodified lines | ||
| 5255 | 5255 | err = mvneta_port_power_up(pp, pp->phy_interface); |
| 5256 | 5256 | if (err < 0) { |
| 5257 | 5257 | dev_err(&pdev->dev, "can't power up port\n"); |
| 5258 | − return err; | |
| 5258 | + goto err_netdev; | |
| 5259 | 5259 | } |
| 5260 | 5260 | |
| 5261 | 5261 | /* Armada3700 network controller does not support per-cpu |
| @@ -1231,7 +1231,7 @@ static void mvpp22_gop_init_rgmii(struct mvpp2_port *port) · 1230 unmodified lines | ||
| 1231 | 1231 | |
| 1232 | 1232 | regmap_read(priv->sysctrl_base, GENCONF_CTRL0, &val); |
| 1233 | 1233 | if (port->gop_id == 2) |
| 1234 | − val |= GENCONF_CTRL0_PORT0_RGMII | GENCONF_CTRL0_PORT1_RGMII; | |
| 1234 | + val |= GENCONF_CTRL0_PORT0_RGMII; | |
| 1235 | 1235 | else if (port->gop_id == 3) |
| 1236 | 1236 | val |= GENCONF_CTRL0_PORT1_RGMII_MII; |
| 1237 | 1237 | regmap_write(priv->sysctrl_base, GENCONF_CTRL0, val); |
| @@ -2370,17 +2370,18 @@ static void mvpp2_rx_pkts_coal_set(struct mvpp2_port *port, · 1132 unmodified lines | ||
| 2370 | 2370 | static void mvpp2_tx_pkts_coal_set(struct mvpp2_port *port, |
| 2371 | 2371 | struct mvpp2_tx_queue *txq) |
| 2372 | 2372 | { |
| 2373 | − unsigned int thread = mvpp2_cpu_to_thread(port->priv, get_cpu()); | |
| 2373 | + unsigned int thread; | |
| 2374 | 2374 | u32 val; |
| 2375 | 2375 | |
| 2376 | 2376 | if (txq->done_pkts_coal > MVPP2_TXQ_THRESH_MASK) |
| 2377 | 2377 | txq->done_pkts_coal = MVPP2_TXQ_THRESH_MASK; |
| 2378 | 2378 | |
| 2379 | 2379 | val = (txq->done_pkts_coal << MVPP2_TXQ_THRESH_OFFSET); |
| 2380 | − mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_NUM_REG, txq->id); | |
| 2381 | − mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_THRESH_REG, val); | |
| 2382 | − | |
| 2383 | − put_cpu(); | |
| 2380 | + /* PKT-coalescing registers are per-queue + per-thread */ | |
| 2381 | + for (thread = 0; thread < MVPP2_MAX_THREADS; thread++) { | |
| 2382 | + mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_NUM_REG, txq->id); | |
| 2383 | + mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_THRESH_REG, val); | |
| 2384 | + } | |
| 2384 | 2385 | } |
| 2385 | 2386 | |
| 2386 | 2387 | static u32 mvpp2_usec_to_cycles(u32 usec, unsigned long clk_hz) |
| @@ -5487,7 +5488,7 @@ static int mvpp2_port_init(struct mvpp2_port *port) · 3100 unmodified lines | ||
| 5487 | 5488 | struct mvpp2 *priv = port->priv; |
| 5488 | 5489 | struct mvpp2_txq_pcpu *txq_pcpu; |
| 5489 | 5490 | unsigned int thread; |
| 5490 | − int queue, err; | |
| 5491 | + int queue, err, val; | |
| 5491 | 5492 | |
| 5492 | 5493 | /* Checks for hardware constraints */ |
| 5493 | 5494 | if (port->first_rxq + port->nrxqs > |
| @@ -5501,6 +5502,18 @@ static int mvpp2_port_init(struct mvpp2_port *port) · 7 unmodified lines | ||
| 5501 | 5502 | mvpp2_egress_disable(port); |
| 5502 | 5503 | mvpp2_port_disable(port); |
| 5503 | 5504 | |
| 5505 | + if (mvpp2_is_xlg(port->phy_interface)) { | |
| 5506 | + val = readl(port->base + MVPP22_XLG_CTRL0_REG); | |
| 5507 | + val &= ~MVPP22_XLG_CTRL0_FORCE_LINK_PASS; | |
| 5508 | + val |= MVPP22_XLG_CTRL0_FORCE_LINK_DOWN; | |
| 5509 | + writel(val, port->base + MVPP22_XLG_CTRL0_REG); | |
| 5510 | + } else { | |
| 5511 | + val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG); | |
| 5512 | + val &= ~MVPP2_GMAC_FORCE_LINK_PASS; | |
| 5513 | + val |= MVPP2_GMAC_FORCE_LINK_DOWN; | |
| 5514 | + writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG); | |
| 5515 | + } | |
| 5516 | + | |
| 5504 | 5517 | port->tx_time_coal = MVPP2_TXDONE_COAL_USEC; |
| 5505 | 5518 | |
| 5506 | 5519 | port->txqs = devm_kcalloc(dev, port->ntxqs, sizeof(*port->txqs), |
| @@ -5869,8 +5882,6 @@ static void mvpp2_phylink_validate(struct phylink_config *config, · 362 unmodified lines | ||
| 5869 | 5882 | |
| 5870 | 5883 | phylink_set(mask, Autoneg); |
| 5871 | 5884 | phylink_set_port_modes(mask); |
| 5872 | − phylink_set(mask, Pause); | |
| 5873 | − phylink_set(mask, Asym_Pause); | |
| 5874 | 5885 | |
| 5875 | 5886 | switch (state->interface) { |
| 5876 | 5887 | case PHY_INTERFACE_MODE_10GBASER: |
| @@ -405,6 +405,38 @@ static int mvpp2_prs_tcam_first_free(struct mvpp2 *priv, unsigned char start, · 404 unmodified lines | ||
| 405 | 405 | return -EINVAL; |
| 406 | 406 | } |
| 407 | 407 | |
| 408 | +/* Drop flow control pause frames */ | |
| 409 | +static void mvpp2_prs_drop_fc(struct mvpp2 *priv) | |
| 410 | +{ | |
| 411 | + unsigned char da[ETH_ALEN] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x01 }; | |
| 412 | + struct mvpp2_prs_entry pe; | |
| 413 | + unsigned int len; | |
| 414 | + | |
| 415 | + memset(&pe, 0, sizeof(pe)); | |
| 416 | + | |
| 417 | + /* For all ports - drop flow control frames */ | |
| 418 | + pe.index = MVPP2_PE_FC_DROP; | |
| 419 | + mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC); | |
| 420 | + | |
| 421 | + /* Set match on DA */ | |
| 422 | + len = ETH_ALEN; | |
| 423 | + while (len--) | |
| 424 | + mvpp2_prs_tcam_data_byte_set(&pe, len, da[len], 0xff); | |
| 425 | + | |
| 426 | + mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DROP_MASK, | |
| 427 | + MVPP2_PRS_RI_DROP_MASK); | |
| 428 | + | |
| 429 | + mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1); | |
| 430 | + mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS); | |
| 431 | + | |
| 432 | + /* Mask all ports */ | |
| 433 | + mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); | |
| 434 | + | |
| 435 | + /* Update shadow table and hw entry */ | |
| 436 | + mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC); | |
| 437 | + mvpp2_prs_hw_write(priv, &pe); | |
| 438 | +} | |
| 439 | + | |
| 408 | 440 | /* Enable/disable dropping all mac da's */ |
| 409 | 441 | static void mvpp2_prs_mac_drop_all_set(struct mvpp2 *priv, int port, bool add) |
| 410 | 442 | { |
| @@ -1162,6 +1194,7 @@ static void mvpp2_prs_mac_init(struct mvpp2 *priv) · 751 unmodified lines | ||
| 1162 | 1194 | mvpp2_prs_hw_write(priv, &pe); |
| 1163 | 1195 | |
| 1164 | 1196 | /* Create dummy entries for drop all and promiscuous modes */ |
| 1197 | + mvpp2_prs_drop_fc(priv); | |
| 1165 | 1198 | mvpp2_prs_mac_drop_all_set(priv, 0, false); |
| 1166 | 1199 | mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_UNI_CAST, false); |
| 1167 | 1200 | mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_MULTI_CAST, false); |
| @@ -1647,8 +1680,9 @@ static int mvpp2_prs_pppoe_init(struct mvpp2 *priv) · 479 unmodified lines | ||
| 1647 | 1680 | mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6); |
| 1648 | 1681 | mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP6, |
| 1649 | 1682 | MVPP2_PRS_RI_L3_PROTO_MASK); |
| 1650 | − /* Skip eth_type + 4 bytes of IPv6 header */ | |
| 1651 | − mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 4, | |
| 1683 | + /* Jump to DIP of IPV6 header */ | |
| 1684 | + mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 8 + | |
| 1685 | + MVPP2_MAX_L3_ADDR_SIZE, | |
| 1652 | 1686 | MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); |
| 1653 | 1687 | /* Set L3 offset */ |
| 1654 | 1688 | mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, |
| @@ -129,7 +129,7 @@ · 128 unmodified lines | ||
| 129 | 129 | #define MVPP2_PE_VID_EDSA_FLTR_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 7) |
| 130 | 130 | #define MVPP2_PE_VLAN_DBL (MVPP2_PRS_TCAM_SRAM_SIZE - 6) |
| 131 | 131 | #define MVPP2_PE_VLAN_NONE (MVPP2_PRS_TCAM_SRAM_SIZE - 5) |
| 132 | −/* reserved */ | |
| 132 | +#define MVPP2_PE_FC_DROP (MVPP2_PRS_TCAM_SRAM_SIZE - 4) | |
| 133 | 133 | #define MVPP2_PE_MAC_MC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 3) |
| 134 | 134 | #define MVPP2_PE_MAC_UC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 2) |
| 135 | 135 | #define MVPP2_PE_MAC_NON_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 1) |
| @@ -871,8 +871,10 @@ static int cgx_lmac_init(struct cgx *cgx) · 870 unmodified lines | ||
| 871 | 871 | if (!lmac) |
| 872 | 872 | return -ENOMEM; |
| 873 | 873 | lmac->name = kcalloc(1, sizeof("cgx_fwi_xxx_yyy"), GFP_KERNEL); |
| 874 | − if (!lmac->name) | |
| 875 | − return -ENOMEM; | |
| 874 | + if (!lmac->name) { | |
| 875 | + err = -ENOMEM; | |
| 876 | + goto err_lmac_free; | |
| 877 | + } | |
| 876 | 878 | sprintf(lmac->name, "cgx_fwi_%d_%d", cgx->cgx_id, i); |
| 877 | 879 | lmac->lmac_id = i; |
| 878 | 880 | lmac->cgx = cgx; |
| @@ -883,7 +885,7 @@ static int cgx_lmac_init(struct cgx *cgx) · 4 unmodified lines | ||
| 883 | 885 | CGX_LMAC_FWI + i * 9), |
| 884 | 886 | cgx_fwi_event_handler, 0, lmac->name, lmac); |
| 885 | 887 | if (err) |
| 886 | − return err; | |
| 888 | + goto err_irq; | |
| 887 | 889 | |
| 888 | 890 | /* Enable interrupt */ |
| 889 | 891 | cgx_write(cgx, lmac->lmac_id, CGXX_CMRX_INT_ENA_W1S, |
| @@ -895,6 +897,12 @@ static int cgx_lmac_init(struct cgx *cgx) · 5 unmodified lines | ||
| 895 | 897 | } |
| 896 | 898 | |
| 897 | 899 | return cgx_lmac_verify_fwi_version(cgx); |
| 900 | + | |
| 901 | +err_irq: | |
| 902 | + kfree(lmac->name); | |
| 903 | +err_lmac_free: | |
| 904 | + kfree(lmac); | |
| 905 | + return err; | |
| 898 | 906 | } |
| 899 | 907 | |
| 900 | 908 | static int cgx_lmac_exit(struct cgx *cgx) |
| @@ -626,6 +626,11 @@ bool mlx5e_rep_tc_update_skb(struct mlx5_cqe64 *cqe, · 625 unmodified lines | ||
| 626 | 626 | if (!reg_c0) |
| 627 | 627 | return true; |
| 628 | 628 | |
| 629 | + /* If reg_c0 is not equal to the default flow tag then skb->mark | |
| 630 | + * is not supported and must be reset back to 0. | |
| 631 | + */ | |
| 632 | + skb->mark = 0; | |
| 633 | + | |
| 629 | 634 | priv = netdev_priv(skb->dev); |
| 630 | 635 | esw = priv->mdev->priv.eswitch; |
| 631 | 636 | |
| @@ -118,16 +118,17 @@ struct mlx5_ct_tuple { · 117 unmodified lines | ||
| 118 | 118 | u16 zone; |
| 119 | 119 | }; |
| 120 | 120 | |
| 121 | −struct mlx5_ct_shared_counter { | |
| 121 | +struct mlx5_ct_counter { | |
| 122 | 122 | struct mlx5_fc *counter; |
| 123 | 123 | refcount_t refcount; |
| 124 | + bool is_shared; | |
| 124 | 125 | }; |
| 125 | 126 | |
| 126 | 127 | struct mlx5_ct_entry { |
| 127 | 128 | struct rhash_head node; |
| 128 | 129 | struct rhash_head tuple_node; |
| 129 | 130 | struct rhash_head tuple_nat_node; |
| 130 | − struct mlx5_ct_shared_counter *shared_counter; | |
| 131 | + struct mlx5_ct_counter *counter; | |
| 131 | 132 | unsigned long cookie; |
| 132 | 133 | unsigned long restore_cookie; |
| 133 | 134 | struct mlx5_ct_tuple tuple; |
| @@ -394,13 +395,14 @@ mlx5_tc_ct_set_tuple_match(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, · 260 unmodified lines | ||
| 394 | 395 | } |
| 395 | 396 | |
| 396 | 397 | static void |
| 397 | −mlx5_tc_ct_shared_counter_put(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_entry *entry) | |
| 398 | +mlx5_tc_ct_counter_put(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_entry *entry) | |
| 398 | 399 | { |
| 399 | − if (!refcount_dec_and_test(&entry->shared_counter->refcount)) | |
| 400 | + if (entry->counter->is_shared && | |
| 401 | + !refcount_dec_and_test(&entry->counter->refcount)) | |
| 400 | 402 | return; |
| 401 | 403 | |
| 402 | − mlx5_fc_destroy(ct_priv->dev, entry->shared_counter->counter); | |
| 403 | − kfree(entry->shared_counter); | |
| 404 | + mlx5_fc_destroy(ct_priv->dev, entry->counter->counter); | |
| 405 | + kfree(entry->counter); | |
| 404 | 406 | } |
| 405 | 407 | |
| 406 | 408 | static void |
| @@ -699,7 +701,7 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv, · 292 unmodified lines | ||
| 699 | 701 | attr->dest_ft = ct_priv->post_ct; |
| 700 | 702 | attr->ft = nat ? ct_priv->ct_nat : ct_priv->ct; |
| 701 | 703 | attr->outer_match_level = MLX5_MATCH_L4; |
| 702 | − attr->counter = entry->shared_counter->counter; | |
| 704 | + attr->counter = entry->counter->counter; | |
| 703 | 705 | attr->flags |= MLX5_ESW_ATTR_FLAG_NO_IN_PORT; |
| 704 | 706 | |
| 705 | 707 | mlx5_tc_ct_set_tuple_match(netdev_priv(ct_priv->netdev), spec, flow_rule); |
| @@ -732,13 +734,34 @@ err_attr: · 26 unmodified lines | ||
| 732 | 734 | return err; |
| 733 | 735 | } |
| 734 | 736 | |
| 735 | −static struct mlx5_ct_shared_counter * | |
| 737 | +static struct mlx5_ct_counter * | |
| 738 | +mlx5_tc_ct_counter_create(struct mlx5_tc_ct_priv *ct_priv) | |
| 739 | +{ | |
| 740 | + struct mlx5_ct_counter *counter; | |
| 741 | + int ret; | |
| 742 | + | |
| 743 | + counter = kzalloc(sizeof(*counter), GFP_KERNEL); | |
| 744 | + if (!counter) | |
| 745 | + return ERR_PTR(-ENOMEM); | |
| 746 | + | |
| 747 | + counter->is_shared = false; | |
| 748 | + counter->counter = mlx5_fc_create(ct_priv->dev, true); | |
| 749 | + if (IS_ERR(counter->counter)) { | |
| 750 | + ct_dbg("Failed to create counter for ct entry"); | |
| 751 | + ret = PTR_ERR(counter->counter); | |
| 752 | + kfree(counter); | |
| 753 | + return ERR_PTR(ret); | |
| 754 | + } | |
| 755 | + | |
| 756 | + return counter; | |
| 757 | +} | |
| 758 | + | |
| 759 | +static struct mlx5_ct_counter * | |
| 736 | 760 | mlx5_tc_ct_shared_counter_get(struct mlx5_tc_ct_priv *ct_priv, |
| 737 | 761 | struct mlx5_ct_entry *entry) |
| 738 | 762 | { |
| 739 | 763 | struct mlx5_ct_tuple rev_tuple = entry->tuple; |
| 740 | − struct mlx5_ct_shared_counter *shared_counter; | |
| 741 | − struct mlx5_core_dev *dev = ct_priv->dev; | |
| 764 | + struct mlx5_ct_counter *shared_counter; | |
| 742 | 765 | struct mlx5_ct_entry *rev_entry; |
| 743 | 766 | __be16 tmp_port; |
| 744 | 767 | int ret; |
| @@ -767,25 +790,20 @@ mlx5_tc_ct_shared_counter_get(struct mlx5_tc_ct_priv *ct_priv, · 22 unmodified lines | ||
| 767 | 790 | rev_entry = rhashtable_lookup_fast(&ct_priv->ct_tuples_ht, &rev_tuple, |
| 768 | 791 | tuples_ht_params); |
| 769 | 792 | if (rev_entry) { |
| 770 | − if (refcount_inc_not_zero(&rev_entry->shared_counter->refcount)) { | |
| 793 | + if (refcount_inc_not_zero(&rev_entry->counter->refcount)) { | |
| 771 | 794 | mutex_unlock(&ct_priv->shared_counter_lock); |
| 772 | − return rev_entry->shared_counter; | |
| 795 | + return rev_entry->counter; | |
| 773 | 796 | } |
| 774 | 797 | } |
| 775 | 798 | mutex_unlock(&ct_priv->shared_counter_lock); |
| 776 | 799 | |
| 777 | − shared_counter = kzalloc(sizeof(*shared_counter), GFP_KERNEL); | |
| 778 | − if (!shared_counter) | |
| 779 | − return ERR_PTR(-ENOMEM); | |
| 780 | − | |
| 781 | − shared_counter->counter = mlx5_fc_create(dev, true); | |
| 782 | − if (IS_ERR(shared_counter->counter)) { | |
| 783 | − ct_dbg("Failed to create counter for ct entry"); | |
| 784 | − ret = PTR_ERR(shared_counter->counter); | |
| 785 | − kfree(shared_counter); | |
| 800 | + shared_counter = mlx5_tc_ct_counter_create(ct_priv); | |
| 801 | + if (IS_ERR(shared_counter)) { | |
| 802 | + ret = PTR_ERR(shared_counter); | |
| 786 | 803 | return ERR_PTR(ret); |
| 787 | 804 | } |
| 788 | 805 | |
| 806 | + shared_counter->is_shared = true; | |
| 789 | 807 | refcount_set(&shared_counter->refcount, 1); |
| 790 | 808 | return shared_counter; |
| 791 | 809 | } |
| @@ -798,10 +816,13 @@ mlx5_tc_ct_entry_add_rules(struct mlx5_tc_ct_priv *ct_priv, · 6 unmodified lines | ||
| 798 | 816 | { |
| 799 | 817 | int err; |
| 800 | 818 | |
| 801 | − entry->shared_counter = mlx5_tc_ct_shared_counter_get(ct_priv, entry); | |
| 802 | − if (IS_ERR(entry->shared_counter)) { | |
| 803 | − err = PTR_ERR(entry->shared_counter); | |
| 804 | − ct_dbg("Failed to create counter for ct entry"); | |
| 819 | + if (nf_ct_acct_enabled(dev_net(ct_priv->netdev))) | |
| 820 | + entry->counter = mlx5_tc_ct_counter_create(ct_priv); | |
| 821 | + else | |
| 822 | + entry->counter = mlx5_tc_ct_shared_counter_get(ct_priv, entry); | |
| 823 | + | |
| 824 | + if (IS_ERR(entry->counter)) { | |
| 825 | + err = PTR_ERR(entry->counter); | |
| 805 | 826 | return err; |
| 806 | 827 | } |
| 807 | 828 | |
| @@ -820,7 +841,7 @@ mlx5_tc_ct_entry_add_rules(struct mlx5_tc_ct_priv *ct_priv, · 12 unmodified lines | ||
| 820 | 841 | err_nat: |
| 821 | 842 | mlx5_tc_ct_entry_del_rule(ct_priv, entry, false); |
| 822 | 843 | err_orig: |
| 823 | − mlx5_tc_ct_shared_counter_put(ct_priv, entry); | |
| 844 | + mlx5_tc_ct_counter_put(ct_priv, entry); | |
| 824 | 845 | return err; |
| 825 | 846 | } |
| 826 | 847 | |
| @@ -918,7 +939,7 @@ mlx5_tc_ct_del_ft_entry(struct mlx5_tc_ct_priv *ct_priv, · 91 unmodified lines | ||
| 918 | 939 | rhashtable_remove_fast(&ct_priv->ct_tuples_ht, &entry->tuple_node, |
| 919 | 940 | tuples_ht_params); |
| 920 | 941 | mutex_unlock(&ct_priv->shared_counter_lock); |
| 921 | − mlx5_tc_ct_shared_counter_put(ct_priv, entry); | |
| 942 | + mlx5_tc_ct_counter_put(ct_priv, entry); | |
| 922 | 943 | |
| 923 | 944 | } |
| 924 | 945 | |
| @@ -956,7 +977,7 @@ mlx5_tc_ct_block_flow_offload_stats(struct mlx5_ct_ft *ft, · 31 unmodified lines | ||
| 956 | 977 | if (!entry) |
| 957 | 978 | return -ENOENT; |
| 958 | 979 | |
| 959 | − mlx5_fc_query_cached(entry->shared_counter->counter, &bytes, &packets, &lastuse); | |
| 980 | + mlx5_fc_query_cached(entry->counter->counter, &bytes, &packets, &lastuse); | |
| 960 | 981 | flow_stats_update(&f->stats, bytes, packets, 0, lastuse, |
| 961 | 982 | FLOW_ACTION_HW_STATS_DELAYED); |
| 962 | 983 | |
| @@ -371,6 +371,15 @@ struct mlx5e_swp_spec { · 370 unmodified lines | ||
| 371 | 371 | u8 tun_l4_proto; |
| 372 | 372 | }; |
| 373 | 373 | |
| 374 | +static inline void mlx5e_eseg_swp_offsets_add_vlan(struct mlx5_wqe_eth_seg *eseg) | |
| 375 | +{ | |
| 376 | + /* SWP offsets are in 2-bytes words */ | |
| 377 | + eseg->swp_outer_l3_offset += VLAN_HLEN / 2; | |
| 378 | + eseg->swp_outer_l4_offset += VLAN_HLEN / 2; | |
| 379 | + eseg->swp_inner_l3_offset += VLAN_HLEN / 2; | |
| 380 | + eseg->swp_inner_l4_offset += VLAN_HLEN / 2; | |
| 381 | +} | |
| 382 | + | |
| 374 | 383 | static inline void |
| 375 | 384 | mlx5e_set_eseg_swp(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg, |
| 376 | 385 | struct mlx5e_swp_spec *swp_spec) |
| @@ -51,7 +51,7 @@ static inline bool mlx5_geneve_tx_allowed(struct mlx5_core_dev *mdev) · 50 unmodified lines | ||
| 51 | 51 | } |
| 52 | 52 | |
| 53 | 53 | static inline void |
| 54 | −mlx5e_tx_tunnel_accel(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg) | |
| 54 | +mlx5e_tx_tunnel_accel(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg, u16 ihs) | |
| 55 | 55 | { |
| 56 | 56 | struct mlx5e_swp_spec swp_spec = {}; |
| 57 | 57 | unsigned int offset = 0; |
| @@ -85,6 +85,8 @@ mlx5e_tx_tunnel_accel(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg) · 27 unmodified lines | ||
| 85 | 85 | } |
| 86 | 86 | |
| 87 | 87 | mlx5e_set_eseg_swp(skb, eseg, &swp_spec); |
| 88 | + if (skb_vlan_tag_present(skb) && ihs) | |
| 89 | + mlx5e_eseg_swp_offsets_add_vlan(eseg); | |
| 88 | 90 | } |
| 89 | 91 | |
| 90 | 92 | #else |
| @@ -163,7 +165,7 @@ static inline unsigned int mlx5e_accel_tx_ids_len(struct mlx5e_txqsq *sq, · 72 unmodified lines | ||
| 163 | 165 | |
| 164 | 166 | static inline bool mlx5e_accel_tx_eseg(struct mlx5e_priv *priv, |
| 165 | 167 | struct sk_buff *skb, |
| 166 | − struct mlx5_wqe_eth_seg *eseg) | |
| 168 | + struct mlx5_wqe_eth_seg *eseg, u16 ihs) | |
| 167 | 169 | { |
| 168 | 170 | #ifdef CONFIG_MLX5_EN_IPSEC |
| 169 | 171 | if (xfrm_offload(skb)) |
| @@ -172,7 +174,7 @@ static inline bool mlx5e_accel_tx_eseg(struct mlx5e_priv *priv, · 2 unmodified lines | ||
| 172 | 174 | |
| 173 | 175 | #if IS_ENABLED(CONFIG_GENEVE) |
| 174 | 176 | if (skb->encapsulation) |
| 175 | − mlx5e_tx_tunnel_accel(skb, eseg); | |
| 177 | + mlx5e_tx_tunnel_accel(skb, eseg, ihs); | |
| 176 | 178 | #endif |
| 177 | 179 | |
| 178 | 180 | return true; |
| @@ -1010,6 +1010,22 @@ static int mlx5e_get_link_ksettings(struct net_device *netdev, · 1009 unmodified lines | ||
| 1010 | 1010 | return mlx5e_ethtool_get_link_ksettings(priv, link_ksettings); |
| 1011 | 1011 | } |
| 1012 | 1012 | |
| 1013 | +static int mlx5e_speed_validate(struct net_device *netdev, bool ext, | |
| 1014 | + const unsigned long link_modes, u8 autoneg) | |
| 1015 | +{ | |
| 1016 | + /* Extended link-mode has no speed limitations. */ | |
| 1017 | + if (ext) | |
| 1018 | + return 0; | |
| 1019 | + | |
| 1020 | + if ((link_modes & MLX5E_PROT_MASK(MLX5E_56GBASE_R4)) && | |
| 1021 | + autoneg != AUTONEG_ENABLE) { | |
| 1022 | + netdev_err(netdev, "%s: 56G link speed requires autoneg enabled\n", | |
| 1023 | + __func__); | |
| 1024 | + return -EINVAL; | |
| 1025 | + } | |
| 1026 | + return 0; | |
| 1027 | +} | |
| 1028 | + | |
| 1013 | 1029 | static u32 mlx5e_ethtool2ptys_adver_link(const unsigned long *link_modes) |
| 1014 | 1030 | { |
| 1015 | 1031 | u32 i, ptys_modes = 0; |
| @@ -1103,13 +1119,9 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, · 87 unmodified lines | ||
| 1103 | 1119 | link_modes = autoneg == AUTONEG_ENABLE ? ethtool2ptys_adver_func(adver) : |
| 1104 | 1120 | mlx5e_port_speed2linkmodes(mdev, speed, !ext); |
| 1105 | 1121 | |
| 1106 | − if ((link_modes & MLX5E_PROT_MASK(MLX5E_56GBASE_R4)) && | |
| 1107 | − autoneg != AUTONEG_ENABLE) { | |
| 1108 | − netdev_err(priv->netdev, "%s: 56G link speed requires autoneg enabled\n", | |
| 1109 | − __func__); | |
| 1110 | − err = -EINVAL; | |
| 1122 | + err = mlx5e_speed_validate(priv->netdev, ext, link_modes, autoneg); | |
| 1123 | + if (err) | |
| 1111 | 1124 | goto out; |
| 1112 | − } | |
| 1113 | 1125 | |
| 1114 | 1126 | link_modes = link_modes & eproto.cap; |
| 1115 | 1127 | if (!link_modes) { |
| @@ -942,6 +942,7 @@ static int mlx5e_create_ttc_table_groups(struct mlx5e_ttc_table *ttc, · 941 unmodified lines | ||
| 942 | 942 | in = kvzalloc(inlen, GFP_KERNEL); |
| 943 | 943 | if (!in) { |
| 944 | 944 | kfree(ft->g); |
| 945 | + ft->g = NULL; | |
| 945 | 946 | return -ENOMEM; |
| 946 | 947 | } |
| 947 | 948 | |
| @@ -1087,6 +1088,7 @@ static int mlx5e_create_inner_ttc_table_groups(struct mlx5e_ttc_table *ttc) · 139 unmodified lines | ||
| 1087 | 1088 | in = kvzalloc(inlen, GFP_KERNEL); |
| 1088 | 1089 | if (!in) { |
| 1089 | 1090 | kfree(ft->g); |
| 1091 | + ft->g = NULL; | |
| 1090 | 1092 | return -ENOMEM; |
| 1091 | 1093 | } |
| 1092 | 1094 | |
| @@ -1390,6 +1392,7 @@ err_destroy_groups: · 297 unmodified lines | ||
| 1390 | 1392 | ft->g[ft->num_groups] = NULL; |
| 1391 | 1393 | mlx5e_destroy_groups(ft); |
| 1392 | 1394 | kvfree(in); |
| 1395 | + kfree(ft->g); | |
| 1393 | 1396 | |
| 1394 | 1397 | return err; |
| 1395 | 1398 | } |
| @@ -3161,7 +3161,8 @@ static void mlx5e_modify_admin_state(struct mlx5_core_dev *mdev, · 3160 unmodified lines | ||
| 3161 | 3161 | |
| 3162 | 3162 | mlx5_set_port_admin_status(mdev, state); |
| 3163 | 3163 | |
| 3164 | − if (mlx5_eswitch_mode(mdev) != MLX5_ESWITCH_LEGACY) | |
| 3164 | + if (mlx5_eswitch_mode(mdev) == MLX5_ESWITCH_OFFLOADS || | |
| 3165 | + !MLX5_CAP_GEN(mdev, uplink_follow)) | |
| 3165 | 3166 | return; |
| 3166 | 3167 | |
| 3167 | 3168 | if (state == MLX5_PORT_UP) |
| @@ -682,9 +682,9 @@ void mlx5e_tx_mpwqe_ensure_complete(struct mlx5e_txqsq *sq) · 681 unmodified lines | ||
| 682 | 682 | |
| 683 | 683 | static bool mlx5e_txwqe_build_eseg(struct mlx5e_priv *priv, struct mlx5e_txqsq *sq, |
| 684 | 684 | struct sk_buff *skb, struct mlx5e_accel_tx_state *accel, |
| 685 | − struct mlx5_wqe_eth_seg *eseg) | |
| 685 | + struct mlx5_wqe_eth_seg *eseg, u16 ihs) | |
| 686 | 686 | { |
| 687 | − if (unlikely(!mlx5e_accel_tx_eseg(priv, skb, eseg))) | |
| 687 | + if (unlikely(!mlx5e_accel_tx_eseg(priv, skb, eseg, ihs))) | |
| 688 | 688 | return false; |
| 689 | 689 | |
| 690 | 690 | mlx5e_txwqe_build_eseg_csum(sq, skb, accel, eseg); |
| @@ -714,7 +714,8 @@ netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev) · 23 unmodified lines | ||
| 714 | 714 | if (mlx5e_tx_skb_supports_mpwqe(skb, &attr)) { |
| 715 | 715 | struct mlx5_wqe_eth_seg eseg = {}; |
| 716 | 716 | |
| 717 | − if (unlikely(!mlx5e_txwqe_build_eseg(priv, sq, skb, &accel, &eseg))) | |
| 717 | + if (unlikely(!mlx5e_txwqe_build_eseg(priv, sq, skb, &accel, &eseg, | |
| 718 | + attr.ihs))) | |
| 718 | 719 | return NETDEV_TX_OK; |
| 719 | 720 | |
| 720 | 721 | mlx5e_sq_xmit_mpwqe(sq, skb, &eseg, netdev_xmit_more()); |
| @@ -731,7 +732,7 @@ netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev) · 10 unmodified lines | ||
| 731 | 732 | /* May update the WQE, but may not post other WQEs. */ |
| 732 | 733 | mlx5e_accel_tx_finish(sq, wqe, &accel, |
| 733 | 734 | (struct mlx5_wqe_inline_seg *)(wqe->data + wqe_attr.ds_cnt_inl)); |
| 734 | − if (unlikely(!mlx5e_txwqe_build_eseg(priv, sq, skb, &accel, &wqe->eth))) | |
| 735 | + if (unlikely(!mlx5e_txwqe_build_eseg(priv, sq, skb, &accel, &wqe->eth, attr.ihs))) | |
| 735 | 736 | return NETDEV_TX_OK; |
| 736 | 737 | |
| 737 | 738 | mlx5e_sq_xmit_wqe(sq, skb, &attr, &wqe_attr, wqe, pi, netdev_xmit_more()); |
| @@ -95,22 +95,21 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw, · 94 unmodified lines | ||
| 95 | 95 | return 0; |
| 96 | 96 | } |
| 97 | 97 | |
| 98 | − if (!IS_ERR_OR_NULL(vport->egress.acl)) | |
| 99 | − return 0; | |
| 100 | − | |
| 101 | − vport->egress.acl = esw_acl_table_create(esw, vport->vport, | |
| 102 | − MLX5_FLOW_NAMESPACE_ESW_EGRESS, | |
| 103 | − table_size); | |
| 104 | − if (IS_ERR(vport->egress.acl)) { | |
| 105 | − err = PTR_ERR(vport->egress.acl); | |
| 106 | − vport->egress.acl = NULL; | |
| 107 | − goto out; | |
| 98 | + if (!vport->egress.acl) { | |
| 99 | + vport->egress.acl = esw_acl_table_create(esw, vport->vport, | |
| 100 | + MLX5_FLOW_NAMESPACE_ESW_EGRESS, | |
| 101 | + table_size); | |
| 102 | + if (IS_ERR(vport->egress.acl)) { | |
| 103 | + err = PTR_ERR(vport->egress.acl); | |
| 104 | + vport->egress.acl = NULL; | |
| 105 | + goto out; | |
| 106 | + } | |
| 107 | + | |
| 108 | + err = esw_acl_egress_lgcy_groups_create(esw, vport); | |
| 109 | + if (err) | |
| 110 | + goto out; | |
| 108 | 111 | } |
| 109 | 112 | |
| 110 | − err = esw_acl_egress_lgcy_groups_create(esw, vport); | |
| 111 | − if (err) | |
| 112 | − goto out; | |
| 113 | − | |
| 114 | 113 | esw_debug(esw->dev, |
| 115 | 114 | "vport[%d] configure egress rules, vlan(%d) qos(%d)\n", |
| 116 | 115 | vport->vport, vport->info.vlan, vport->info.qos); |
| @@ -564,7 +564,9 @@ void mlx5_lag_add(struct mlx5_core_dev *dev, struct net_device *netdev) · 563 unmodified lines | ||
| 564 | 564 | struct mlx5_core_dev *tmp_dev; |
| 565 | 565 | int i, err; |
| 566 | 566 | |
| 567 | − if (!MLX5_CAP_GEN(dev, vport_group_manager)) | |
| 567 | + if (!MLX5_CAP_GEN(dev, vport_group_manager) || | |
| 568 | + !MLX5_CAP_GEN(dev, lag_master) || | |
| 569 | + MLX5_CAP_GEN(dev, num_lag_ports) != MLX5_MAX_PORTS) | |
| 568 | 570 | return; |
| 569 | 571 | |
| 570 | 572 | tmp_dev = mlx5_get_next_phys_dev(dev); |
| @@ -582,12 +584,9 @@ void mlx5_lag_add(struct mlx5_core_dev *dev, struct net_device *netdev) · 11 unmodified lines | ||
| 582 | 584 | if (mlx5_lag_dev_add_pf(ldev, dev, netdev) < 0) |
| 583 | 585 | return; |
| 584 | 586 | |
| 585 | − for (i = 0; i < MLX5_MAX_PORTS; i++) { | |
| 586 | − tmp_dev = ldev->pf[i].dev; | |
| 587 | − if (!tmp_dev || !MLX5_CAP_GEN(tmp_dev, lag_master) || | |
| 588 | − MLX5_CAP_GEN(tmp_dev, num_lag_ports) != MLX5_MAX_PORTS) | |
| 587 | + for (i = 0; i < MLX5_MAX_PORTS; i++) | |
| 588 | + if (!ldev->pf[i].dev) | |
| 589 | 589 | break; |
| 590 | − } | |
| 591 | 590 | |
| 592 | 591 | if (i >= MLX5_MAX_PORTS) |
| 593 | 592 | ldev->flags |= MLX5_LAG_FLAG_READY; |
| @@ -1368,8 +1368,10 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *id) · 1367 unmodified lines | ||
| 1368 | 1368 | MLX5_COREDEV_VF : MLX5_COREDEV_PF; |
| 1369 | 1369 | |
| 1370 | 1370 | dev->priv.adev_idx = mlx5_adev_idx_alloc(); |
| 1371 | − if (dev->priv.adev_idx < 0) | |
| 1372 | − return dev->priv.adev_idx; | |
| 1371 | + if (dev->priv.adev_idx < 0) { | |
| 1372 | + err = dev->priv.adev_idx; | |
| 1373 | + goto adev_init_err; | |
| 1374 | + } | |
| 1373 | 1375 | |
| 1374 | 1376 | err = mlx5_mdev_init(dev, prof_sel); |
| 1375 | 1377 | if (err) |
| @@ -1403,6 +1405,7 @@ pci_init_err: · 27 unmodified lines | ||
| 1403 | 1405 | mlx5_mdev_uninit(dev); |
| 1404 | 1406 | mdev_init_err: |
| 1405 | 1407 | mlx5_adev_idx_free(dev->priv.adev_idx); |
| 1408 | +adev_init_err: | |
| 1406 | 1409 | mlx5_devlink_free(devlink); |
| 1407 | 1410 | |
| 1408 | 1411 | return err; |
| @@ -116,7 +116,7 @@ free: · 115 unmodified lines | ||
| 116 | 116 | static void mlx5_rdma_del_roce_addr(struct mlx5_core_dev *dev) |
| 117 | 117 | { |
| 118 | 118 | mlx5_core_roce_gid_set(dev, 0, 0, 0, |
| 119 | − NULL, NULL, false, 0, 0); | |
| 119 | + NULL, NULL, false, 0, 1); | |
| 120 | 120 | } |
| 121 | 121 | |
| 122 | 122 | static void mlx5_rdma_make_default_gid(struct mlx5_core_dev *dev, union ib_gid *gid) |
| @@ -19,7 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #define MLXSW_THERMAL_ASIC_TEMP_NORM 75000 /* 75C */ |
| 20 | 20 | #define MLXSW_THERMAL_ASIC_TEMP_HIGH 85000 /* 85C */ |
| 21 | 21 | #define MLXSW_THERMAL_ASIC_TEMP_HOT 105000 /* 105C */ |
| 22 | −#define MLXSW_THERMAL_ASIC_TEMP_CRIT 110000 /* 110C */ | |
| 22 | +#define MLXSW_THERMAL_ASIC_TEMP_CRIT 140000 /* 140C */ | |
| 23 | 23 | #define MLXSW_THERMAL_HYSTERESIS_TEMP 5000 /* 5C */ |
| 24 | 24 | #define MLXSW_THERMAL_MODULE_TEMP_SHIFT (MLXSW_THERMAL_HYSTERESIS_TEMP * 2) |
| 25 | 25 | #define MLXSW_THERMAL_ZONE_MAX_NAME 16 |
| @@ -176,6 +176,12 @@ mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core, · 150 unmodified lines | ||
| 176 | 176 | if (err) |
| 177 | 177 | return err; |
| 178 | 178 | |
| 179 | + if (crit_temp > emerg_temp) { | |
| 180 | + dev_warn(dev, "%s : Critical threshold %d is above emergency threshold %d\n", | |
| 181 | + tz->tzdev->type, crit_temp, emerg_temp); | |
| 182 | + return 0; | |
| 183 | + } | |
| 184 | + | |
| 179 | 185 | /* According to the system thermal requirements, the thermal zones are |
| 180 | 186 | * defined with four trip points. The critical and emergency |
| 181 | 187 | * temperature thresholds, provided by QSFP module are set as "active" |
| @@ -190,11 +196,8 @@ mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core, · 8 unmodified lines | ||
| 190 | 196 | tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp = crit_temp; |
| 191 | 197 | tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temp = crit_temp; |
| 192 | 198 | tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temp = emerg_temp; |
| 193 | − if (emerg_temp > crit_temp) | |
| 194 | − tz->trips[MLXSW_THERMAL_TEMP_TRIP_CRIT].temp = emerg_temp + | |
| 199 | + tz->trips[MLXSW_THERMAL_TEMP_TRIP_CRIT].temp = emerg_temp + | |
| 195 | 200 | MLXSW_THERMAL_MODULE_TEMP_SHIFT; |
| 196 | − else | |
| 197 | − tz->trips[MLXSW_THERMAL_TEMP_TRIP_CRIT].temp = emerg_temp; | |
| 198 | 201 | |
| 199 | 202 | return 0; |
| 200 | 203 | } |
| @@ -506,10 +506,14 @@ static int mac_sonic_platform_probe(struct platform_device *pdev) · 505 unmodified lines | ||
| 506 | 506 | |
| 507 | 507 | err = register_netdev(dev); |
| 508 | 508 | if (err) |
| 509 | − goto out; | |
| 509 | + goto undo_probe; | |
| 510 | 510 | |
| 511 | 511 | return 0; |
| 512 | 512 | |
| 513 | +undo_probe: | |
| 514 | + dma_free_coherent(lp->device, | |
| 515 | + SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), | |
| 516 | + lp->descriptors, lp->descriptors_laddr); | |
| 513 | 517 | out: |
| 514 | 518 | free_netdev(dev); |
| 515 | 519 | |
| @@ -584,12 +588,16 @@ static int mac_sonic_nubus_probe(struct nubus_board *board) · 68 unmodified lines | ||
| 584 | 588 | |
| 585 | 589 | err = register_netdev(ndev); |
| 586 | 590 | if (err) |
| 587 | − goto out; | |
| 591 | + goto undo_probe; | |
| 588 | 592 | |
| 589 | 593 | nubus_set_drvdata(board, ndev); |
| 590 | 594 | |
| 591 | 595 | return 0; |
| 592 | 596 | |
| 597 | +undo_probe: | |
| 598 | + dma_free_coherent(lp->device, | |
| 599 | + SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), | |
| 600 | + lp->descriptors, lp->descriptors_laddr); | |
| 593 | 601 | out: |
| 594 | 602 | free_netdev(ndev); |
| 595 | 603 | return err; |
| @@ -229,11 +229,14 @@ int xtsonic_probe(struct platform_device *pdev) · 228 unmodified lines | ||
| 229 | 229 | sonic_msg_init(dev); |
| 230 | 230 | |
| 231 | 231 | if ((err = register_netdev(dev))) |
| 232 | − goto out1; | |
| 232 | + goto undo_probe1; | |
| 233 | 233 | |
| 234 | 234 | return 0; |
| 235 | 235 | |
| 236 | −out1: | |
| 236 | +undo_probe1: | |
| 237 | + dma_free_coherent(lp->device, | |
| 238 | + SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), | |
| 239 | + lp->descriptors, lp->descriptors_laddr); | |
| 237 | 240 | release_region(dev->base_addr, SONIC_MEM_SIZE); |
| 238 | 241 | out: |
| 239 | 242 | free_netdev(dev); |
| @@ -337,7 +337,7 @@ void ionic_rx_fill(struct ionic_queue *q) · 336 unmodified lines | ||
| 337 | 337 | unsigned int i, j; |
| 338 | 338 | unsigned int len; |
| 339 | 339 | |
| 340 | − len = netdev->mtu + ETH_HLEN; | |
| 340 | + len = netdev->mtu + ETH_HLEN + VLAN_HLEN; | |
| 341 | 341 | nfrags = round_up(len, PAGE_SIZE) / PAGE_SIZE; |
| 342 | 342 | |
| 343 | 343 | for (i = ionic_q_space_avail(q); i; i--) { |
| @@ -78,6 +78,7 @@ config QED · 77 unmodified lines | ||
| 78 | 78 | depends on PCI |
| 79 | 79 | select ZLIB_INFLATE |
| 80 | 80 | select CRC8 |
| 81 | + select CRC32 | |
| 81 | 82 | select NET_DEVLINK |
| 82 | 83 | help |
| 83 | 84 | This enables the support for Marvell FastLinQ adapters family. |
| @@ -564,11 +564,6 @@ static const struct net_device_ops netxen_netdev_ops = { · 563 unmodified lines | ||
| 564 | 564 | .ndo_set_features = netxen_set_features, |
| 565 | 565 | }; |
| 566 | 566 | |
| 567 | −static inline bool netxen_function_zero(struct pci_dev *pdev) | |
| 568 | −{ | |
| 569 | − return (PCI_FUNC(pdev->devfn) == 0) ? true : false; | |
| 570 | −} | |
| 571 | − | |
| 572 | 567 | static inline void netxen_set_interrupt_mode(struct netxen_adapter *adapter, |
| 573 | 568 | u32 mode) |
| 574 | 569 | { |
| @@ -664,7 +659,7 @@ static int netxen_setup_intr(struct netxen_adapter *adapter) · 89 unmodified lines | ||
| 664 | 659 | netxen_initialize_interrupt_registers(adapter); |
| 665 | 660 | netxen_set_msix_bit(pdev, 0); |
| 666 | 661 | |
| 667 | − if (netxen_function_zero(pdev)) { | |
| 662 | + if (adapter->portnum == 0) { | |
| 668 | 663 | if (!netxen_setup_msi_interrupts(adapter, num_msix)) |
| 669 | 664 | netxen_set_interrupt_mode(adapter, NETXEN_MSI_MODE); |
| 670 | 665 | else |
| @@ -1799,6 +1799,11 @@ netdev_features_t qede_features_check(struct sk_buff *skb, · 1798 unmodified lines | ||
| 1799 | 1799 | ntohs(udp_hdr(skb)->dest) != gnv_port)) |
| 1800 | 1800 | return features & ~(NETIF_F_CSUM_MASK | |
| 1801 | 1801 | NETIF_F_GSO_MASK); |
| 1802 | + } else if (l4_proto == IPPROTO_IPIP) { | |
| 1803 | + /* IPIP tunnels are unknown to the device or at least unsupported natively, | |
| 1804 | + * offloads for them can't be done trivially, so disable them for such skb. | |
| 1805 | + */ | |
| 1806 | + return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); | |
| 1802 | 1807 | } |
| 1803 | 1808 | } |
| 1804 | 1809 | |
| @@ -2207,7 +2207,8 @@ static void rtl_pll_power_down(struct rtl8169_private *tp) · 2206 unmodified lines | ||
| 2207 | 2207 | } |
| 2208 | 2208 | |
| 2209 | 2209 | switch (tp->mac_version) { |
| 2210 | − case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_33: | |
| 2210 | + case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26: | |
| 2211 | + case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_33: | |
| 2211 | 2212 | case RTL_GIGA_MAC_VER_37: |
| 2212 | 2213 | case RTL_GIGA_MAC_VER_39: |
| 2213 | 2214 | case RTL_GIGA_MAC_VER_43: |
| @@ -2233,7 +2234,8 @@ static void rtl_pll_power_down(struct rtl8169_private *tp) · 19 unmodified lines | ||
| 2233 | 2234 | static void rtl_pll_power_up(struct rtl8169_private *tp) |
| 2234 | 2235 | { |
| 2235 | 2236 | switch (tp->mac_version) { |
| 2236 | − case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_33: | |
| 2237 | + case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26: | |
| 2238 | + case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_33: | |
| 2237 | 2239 | case RTL_GIGA_MAC_VER_37: |
| 2238 | 2240 | case RTL_GIGA_MAC_VER_39: |
| 2239 | 2241 | case RTL_GIGA_MAC_VER_43: |
| @@ -721,6 +721,8 @@ static SIMPLE_DEV_PM_OPS(intel_eth_pm_ops, intel_eth_pci_suspend, · 720 unmodified lines | ||
| 721 | 721 | #define PCI_DEVICE_ID_INTEL_EHL_PSE1_RGMII1G_ID 0x4bb0 |
| 722 | 722 | #define PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII1G_ID 0x4bb1 |
| 723 | 723 | #define PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII2G5_ID 0x4bb2 |
| 724 | +#define PCI_DEVICE_ID_INTEL_TGLH_SGMII1G_0_ID 0x43ac | |
| 725 | +#define PCI_DEVICE_ID_INTEL_TGLH_SGMII1G_1_ID 0x43a2 | |
| 724 | 726 | #define PCI_DEVICE_ID_INTEL_TGL_SGMII1G_ID 0xa0ac |
| 725 | 727 | |
| 726 | 728 | static const struct pci_device_id intel_eth_pci_id_table[] = { |
| @@ -735,6 +737,8 @@ static const struct pci_device_id intel_eth_pci_id_table[] = { · 8 unmodified lines | ||
| 735 | 737 | { PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII1G_ID, &ehl_pse1_sgmii1g_info) }, |
| 736 | 738 | { PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII2G5_ID, &ehl_pse1_sgmii1g_info) }, |
| 737 | 739 | { PCI_DEVICE_DATA(INTEL, TGL_SGMII1G_ID, &tgl_sgmii1g_info) }, |
| 740 | + { PCI_DEVICE_DATA(INTEL, TGLH_SGMII1G_0_ID, &tgl_sgmii1g_info) }, | |
| 741 | + { PCI_DEVICE_DATA(INTEL, TGLH_SGMII1G_1_ID, &tgl_sgmii1g_info) }, | |
| 738 | 742 | {} |
| 739 | 743 | }; |
| 740 | 744 | MODULE_DEVICE_TABLE(pci, intel_eth_pci_id_table); |
| @@ -135,7 +135,7 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac) · 134 unmodified lines | ||
| 135 | 135 | struct device *dev = dwmac->dev; |
| 136 | 136 | static const struct clk_parent_data mux_parents[] = { |
| 137 | 137 | { .fw_name = "clkin0", }, |
| 138 | − { .fw_name = "clkin1", }, | |
| 138 | + { .index = -1, }, | |
| 139 | 139 | }; |
| 140 | 140 | static const struct clk_div_table div_table[] = { |
| 141 | 141 | { .div = 2, .val = 2, }, |
| @@ -64,6 +64,7 @@ struct emac_variant { · 63 unmodified lines | ||
| 64 | 64 | * @variant: reference to the current board variant |
| 65 | 65 | * @regmap: regmap for using the syscon |
| 66 | 66 | * @internal_phy_powered: Does the internal PHY is enabled |
| 67 | + * @use_internal_phy: Is the internal PHY selected for use | |
| 67 | 68 | * @mux_handle: Internal pointer used by mdio-mux lib |
| 68 | 69 | */ |
| 69 | 70 | struct sunxi_priv_data { |
| @@ -74,6 +75,7 @@ struct sunxi_priv_data { · 4 unmodified lines | ||
| 74 | 75 | const struct emac_variant *variant; |
| 75 | 76 | struct regmap_field *regmap_field; |
| 76 | 77 | bool internal_phy_powered; |
| 78 | + bool use_internal_phy; | |
| 77 | 79 | void *mux_handle; |
| 78 | 80 | }; |
| 79 | 81 | |
| @@ -539,8 +541,11 @@ static const struct stmmac_dma_ops sun8i_dwmac_dma_ops = { · 459 unmodified lines | ||
| 539 | 541 | .dma_interrupt = sun8i_dwmac_dma_interrupt, |
| 540 | 542 | }; |
| 541 | 543 | |
| 544 | +static int sun8i_dwmac_power_internal_phy(struct stmmac_priv *priv); | |
| 545 | + | |
| 542 | 546 | static int sun8i_dwmac_init(struct platform_device *pdev, void *priv) |
| 543 | 547 | { |
| 548 | + struct net_device *ndev = platform_get_drvdata(pdev); | |
| 544 | 549 | struct sunxi_priv_data *gmac = priv; |
| 545 | 550 | int ret; |
| 546 | 551 | |
| @@ -554,13 +559,25 @@ static int sun8i_dwmac_init(struct platform_device *pdev, void *priv) · 7 unmodified lines | ||
| 554 | 559 | |
| 555 | 560 | ret = clk_prepare_enable(gmac->tx_clk); |
| 556 | 561 | if (ret) { |
| 557 | − if (gmac->regulator) | |
| 558 | − regulator_disable(gmac->regulator); | |
| 559 | 562 | dev_err(&pdev->dev, "Could not enable AHB clock\n"); |
| 560 | − return ret; | |
| 563 | + goto err_disable_regulator; | |
| 564 | + } | |
| 565 | + | |
| 566 | + if (gmac->use_internal_phy) { | |
| 567 | + ret = sun8i_dwmac_power_internal_phy(netdev_priv(ndev)); | |
| 568 | + if (ret) | |
| 569 | + goto err_disable_clk; | |
| 561 | 570 | } |
| 562 | 571 | |
| 563 | 572 | return 0; |
| 573 | + | |
| 574 | +err_disable_clk: | |
| 575 | + clk_disable_unprepare(gmac->tx_clk); | |
| 576 | +err_disable_regulator: | |
| 577 | + if (gmac->regulator) | |
| 578 | + regulator_disable(gmac->regulator); | |
| 579 | + | |
| 580 | + return ret; | |
| 564 | 581 | } |
| 565 | 582 | |
| 566 | 583 | static void sun8i_dwmac_core_init(struct mac_device_info *hw, |
| @@ -831,7 +848,6 @@ static int mdio_mux_syscon_switch_fn(int current_child, int desired_child, · 264 unmodified lines | ||
| 831 | 848 | struct sunxi_priv_data *gmac = priv->plat->bsp_priv; |
| 832 | 849 | u32 reg, val; |
| 833 | 850 | int ret = 0; |
| 834 | − bool need_power_ephy = false; | |
| 835 | 851 | |
| 836 | 852 | if (current_child ^ desired_child) { |
| 837 | 853 | regmap_field_read(gmac->regmap_field, ®); |
| @@ -839,13 +855,12 @@ static int mdio_mux_syscon_switch_fn(int current_child, int desired_child, · 1 unmodified line | ||
| 839 | 855 | case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID: |
| 840 | 856 | dev_info(priv->device, "Switch mux to internal PHY"); |
| 841 | 857 | val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SELECT; |
| 842 | − | |
| 843 | − need_power_ephy = true; | |
| 858 | + gmac->use_internal_phy = true; | |
| 844 | 859 | break; |
| 845 | 860 | case DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID: |
| 846 | 861 | dev_info(priv->device, "Switch mux to external PHY"); |
| 847 | 862 | val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SHUTDOWN; |
| 848 | − need_power_ephy = false; | |
| 863 | + gmac->use_internal_phy = false; | |
| 849 | 864 | break; |
| 850 | 865 | default: |
| 851 | 866 | dev_err(priv->device, "Invalid child ID %x\n", |
| @@ -853,7 +868,7 @@ static int mdio_mux_syscon_switch_fn(int current_child, int desired_child, · 1 unmodified line | ||
| 853 | 868 | return -EINVAL; |
| 854 | 869 | } |
| 855 | 870 | regmap_field_write(gmac->regmap_field, val); |
| 856 | − if (need_power_ephy) { | |
| 871 | + if (gmac->use_internal_phy) { | |
| 857 | 872 | ret = sun8i_dwmac_power_internal_phy(priv); |
| 858 | 873 | if (ret) |
| 859 | 874 | return ret; |
| @@ -883,22 +898,23 @@ static int sun8i_dwmac_register_mdio_mux(struct stmmac_priv *priv) · 23 unmodified lines | ||
| 883 | 898 | return ret; |
| 884 | 899 | } |
| 885 | 900 | |
| 886 | −static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) | |
| 901 | +static int sun8i_dwmac_set_syscon(struct device *dev, | |
| 902 | + struct plat_stmmacenet_data *plat) | |
| 887 | 903 | { |
| 888 | − struct sunxi_priv_data *gmac = priv->plat->bsp_priv; | |
| 889 | − struct device_node *node = priv->device->of_node; | |
| 904 | + struct sunxi_priv_data *gmac = plat->bsp_priv; | |
| 905 | + struct device_node *node = dev->of_node; | |
| 890 | 906 | int ret; |
| 891 | 907 | u32 reg, val; |
| 892 | 908 | |
| 893 | 909 | ret = regmap_field_read(gmac->regmap_field, &val); |
| 894 | 910 | if (ret) { |
| 895 | − dev_err(priv->device, "Fail to read from regmap field.\n"); | |
| 911 | + dev_err(dev, "Fail to read from regmap field.\n"); | |
| 896 | 912 | return ret; |
| 897 | 913 | } |
| 898 | 914 | |
| 899 | 915 | reg = gmac->variant->default_syscon_value; |
| 900 | 916 | if (reg != val) |
| 901 | − dev_warn(priv->device, | |
| 917 | + dev_warn(dev, | |
| 902 | 918 | "Current syscon value is not the default %x (expect %x)\n", |
| 903 | 919 | val, reg); |
| 904 | 920 | |
| @@ -911,9 +927,9 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) · 6 unmodified lines | ||
| 911 | 927 | /* Force EPHY xtal frequency to 24MHz. */ |
| 912 | 928 | reg |= H3_EPHY_CLK_SEL; |
| 913 | 929 | |
| 914 | − ret = of_mdio_parse_addr(priv->device, priv->plat->phy_node); | |
| 930 | + ret = of_mdio_parse_addr(dev, plat->phy_node); | |
| 915 | 931 | if (ret < 0) { |
| 916 | − dev_err(priv->device, "Could not parse MDIO addr\n"); | |
| 932 | + dev_err(dev, "Could not parse MDIO addr\n"); | |
| 917 | 933 | return ret; |
| 918 | 934 | } |
| 919 | 935 | /* of_mdio_parse_addr returns a valid (0 ~ 31) PHY |
| @@ -929,17 +945,17 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) · 9 unmodified lines | ||
| 929 | 945 | |
| 930 | 946 | if (!of_property_read_u32(node, "allwinner,tx-delay-ps", &val)) { |
| 931 | 947 | if (val % 100) { |
| 932 | − dev_err(priv->device, "tx-delay must be a multiple of 100\n"); | |
| 948 | + dev_err(dev, "tx-delay must be a multiple of 100\n"); | |
| 933 | 949 | return -EINVAL; |
| 934 | 950 | } |
| 935 | 951 | val /= 100; |
| 936 | − dev_dbg(priv->device, "set tx-delay to %x\n", val); | |
| 952 | + dev_dbg(dev, "set tx-delay to %x\n", val); | |
| 937 | 953 | if (val <= gmac->variant->tx_delay_max) { |
| 938 | 954 | reg &= ~(gmac->variant->tx_delay_max << |
| 939 | 955 | SYSCON_ETXDC_SHIFT); |
| 940 | 956 | reg |= (val << SYSCON_ETXDC_SHIFT); |
| 941 | 957 | } else { |
| 942 | − dev_err(priv->device, "Invalid TX clock delay: %d\n", | |
| 958 | + dev_err(dev, "Invalid TX clock delay: %d\n", | |
| 943 | 959 | val); |
| 944 | 960 | return -EINVAL; |
| 945 | 961 | } |
| @@ -947,17 +963,17 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) · 1 unmodified line | ||
| 947 | 963 | |
| 948 | 964 | if (!of_property_read_u32(node, "allwinner,rx-delay-ps", &val)) { |
| 949 | 965 | if (val % 100) { |
| 950 | − dev_err(priv->device, "rx-delay must be a multiple of 100\n"); | |
| 966 | + dev_err(dev, "rx-delay must be a multiple of 100\n"); | |
| 951 | 967 | return -EINVAL; |
| 952 | 968 | } |
| 953 | 969 | val /= 100; |
| 954 | − dev_dbg(priv->device, "set rx-delay to %x\n", val); | |
| 970 | + dev_dbg(dev, "set rx-delay to %x\n", val); | |
| 955 | 971 | if (val <= gmac->variant->rx_delay_max) { |
| 956 | 972 | reg &= ~(gmac->variant->rx_delay_max << |
| 957 | 973 | SYSCON_ERXDC_SHIFT); |
| 958 | 974 | reg |= (val << SYSCON_ERXDC_SHIFT); |
| 959 | 975 | } else { |
| 960 | − dev_err(priv->device, "Invalid RX clock delay: %d\n", | |
| 976 | + dev_err(dev, "Invalid RX clock delay: %d\n", | |
| 961 | 977 | val); |
| 962 | 978 | return -EINVAL; |
| 963 | 979 | } |
| @@ -968,7 +984,7 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) · 4 unmodified lines | ||
| 968 | 984 | if (gmac->variant->support_rmii) |
| 969 | 985 | reg &= ~SYSCON_RMII_EN; |
| 970 | 986 | |
| 971 | − switch (priv->plat->interface) { | |
| 987 | + switch (plat->interface) { | |
| 972 | 988 | case PHY_INTERFACE_MODE_MII: |
| 973 | 989 | /* default */ |
| 974 | 990 | break; |
| @@ -982,8 +998,8 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) · 7 unmodified lines | ||
| 982 | 998 | reg |= SYSCON_RMII_EN | SYSCON_ETCS_EXT_GMII; |
| 983 | 999 | break; |
| 984 | 1000 | default: |
| 985 | − dev_err(priv->device, "Unsupported interface mode: %s", | |
| 986 | − phy_modes(priv->plat->interface)); | |
| 1001 | + dev_err(dev, "Unsupported interface mode: %s", | |
| 1002 | + phy_modes(plat->interface)); | |
| 987 | 1003 | return -EINVAL; |
| 988 | 1004 | } |
| 989 | 1005 | |
| @@ -1004,17 +1020,10 @@ static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv) · 14 unmodified lines | ||
| 1004 | 1020 | struct sunxi_priv_data *gmac = priv; |
| 1005 | 1021 | |
| 1006 | 1022 | if (gmac->variant->soc_has_internal_phy) { |
| 1007 | − /* sun8i_dwmac_exit could be called with mdiomux uninit */ | |
| 1008 | − if (gmac->mux_handle) | |
| 1009 | − mdio_mux_uninit(gmac->mux_handle); | |
| 1010 | 1023 | if (gmac->internal_phy_powered) |
| 1011 | 1024 | sun8i_dwmac_unpower_internal_phy(gmac); |
| 1012 | 1025 | } |
| 1013 | 1026 | |
| 1014 | − sun8i_dwmac_unset_syscon(gmac); | |
| 1015 | − | |
| 1016 | − reset_control_put(gmac->rst_ephy); | |
| 1017 | − | |
| 1018 | 1027 | clk_disable_unprepare(gmac->tx_clk); |
| 1019 | 1028 | |
| 1020 | 1029 | if (gmac->regulator) |
| @@ -1049,16 +1058,11 @@ static struct mac_device_info *sun8i_dwmac_setup(void *ppriv) · 28 unmodified lines | ||
| 1049 | 1058 | { |
| 1050 | 1059 | struct mac_device_info *mac; |
| 1051 | 1060 | struct stmmac_priv *priv = ppriv; |
| 1052 | − int ret; | |
| 1053 | 1061 | |
| 1054 | 1062 | mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL); |
| 1055 | 1063 | if (!mac) |
| 1056 | 1064 | return NULL; |
| 1057 | 1065 | |
| 1058 | − ret = sun8i_dwmac_set_syscon(priv); | |
| 1059 | − if (ret) | |
| 1060 | − return NULL; | |
| 1061 | − | |
| 1062 | 1066 | mac->pcsr = priv->ioaddr; |
| 1063 | 1067 | mac->mac = &sun8i_dwmac_ops; |
| 1064 | 1068 | mac->dma = &sun8i_dwmac_dma_ops; |
| @@ -1134,10 +1138,6 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) · 69 unmodified lines | ||
| 1134 | 1138 | if (ret) |
| 1135 | 1139 | return ret; |
| 1136 | 1140 | |
| 1137 | − plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); | |
| 1138 | − if (IS_ERR(plat_dat)) | |
| 1139 | − return PTR_ERR(plat_dat); | |
| 1140 | − | |
| 1141 | 1141 | gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL); |
| 1142 | 1142 | if (!gmac) |
| 1143 | 1143 | return -ENOMEM; |
| @@ -1201,11 +1201,15 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) · 57 unmodified lines | ||
| 1201 | 1201 | ret = of_get_phy_mode(dev->of_node, &interface); |
| 1202 | 1202 | if (ret) |
| 1203 | 1203 | return -EINVAL; |
| 1204 | − plat_dat->interface = interface; | |
| 1204 | + | |
| 1205 | + plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); | |
| 1206 | + if (IS_ERR(plat_dat)) | |
| 1207 | + return PTR_ERR(plat_dat); | |
| 1205 | 1208 | |
| 1206 | 1209 | /* platform data specifying hardware features and callbacks. |
| 1207 | 1210 | * hardware features were copied from Allwinner drivers. |
| 1208 | 1211 | */ |
| 1212 | + plat_dat->interface = interface; | |
| 1209 | 1213 | plat_dat->rx_coe = STMMAC_RX_COE_TYPE2; |
| 1210 | 1214 | plat_dat->tx_coe = 1; |
| 1211 | 1215 | plat_dat->has_sun8i = true; |
| @@ -1214,9 +1218,13 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 1214 | 1218 | plat_dat->exit = sun8i_dwmac_exit; |
| 1215 | 1219 | plat_dat->setup = sun8i_dwmac_setup; |
| 1216 | 1220 | |
| 1221 | + ret = sun8i_dwmac_set_syscon(&pdev->dev, plat_dat); | |
| 1222 | + if (ret) | |
| 1223 | + goto dwmac_deconfig; | |
| 1224 | + | |
| 1217 | 1225 | ret = sun8i_dwmac_init(pdev, plat_dat->bsp_priv); |
| 1218 | 1226 | if (ret) |
| 1219 | − return ret; | |
| 1227 | + goto dwmac_syscon; | |
| 1220 | 1228 | |
| 1221 | 1229 | ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); |
| 1222 | 1230 | if (ret) |
| @@ -1230,7 +1238,7 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) · 7 unmodified lines | ||
| 1230 | 1238 | if (gmac->variant->soc_has_internal_phy) { |
| 1231 | 1239 | ret = get_ephy_nodes(priv); |
| 1232 | 1240 | if (ret) |
| 1233 | − goto dwmac_exit; | |
| 1241 | + goto dwmac_remove; | |
| 1234 | 1242 | ret = sun8i_dwmac_register_mdio_mux(priv); |
| 1235 | 1243 | if (ret) { |
| 1236 | 1244 | dev_err(&pdev->dev, "Failed to register mux\n"); |
| @@ -1239,15 +1247,42 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 1239 | 1247 | } else { |
| 1240 | 1248 | ret = sun8i_dwmac_reset(priv); |
| 1241 | 1249 | if (ret) |
| 1242 | − goto dwmac_exit; | |
| 1250 | + goto dwmac_remove; | |
| 1243 | 1251 | } |
| 1244 | 1252 | |
| 1245 | 1253 | return ret; |
| 1246 | 1254 | dwmac_mux: |
| 1247 | − sun8i_dwmac_unset_syscon(gmac); | |
| 1255 | + reset_control_put(gmac->rst_ephy); | |
| 1256 | + clk_put(gmac->ephy_clk); | |
| 1257 | +dwmac_remove: | |
| 1258 | + stmmac_dvr_remove(&pdev->dev); | |
| 1248 | 1259 | dwmac_exit: |
| 1260 | + sun8i_dwmac_exit(pdev, gmac); | |
| 1261 | +dwmac_syscon: | |
| 1262 | + sun8i_dwmac_unset_syscon(gmac); | |
| 1263 | +dwmac_deconfig: | |
| 1264 | + stmmac_remove_config_dt(pdev, plat_dat); | |
| 1265 | + | |
| 1266 | + return ret; | |
| 1267 | +} | |
| 1268 | + | |
| 1269 | +static int sun8i_dwmac_remove(struct platform_device *pdev) | |
| 1270 | +{ | |
| 1271 | + struct net_device *ndev = platform_get_drvdata(pdev); | |
| 1272 | + struct stmmac_priv *priv = netdev_priv(ndev); | |
| 1273 | + struct sunxi_priv_data *gmac = priv->plat->bsp_priv; | |
| 1274 | + | |
| 1275 | + if (gmac->variant->soc_has_internal_phy) { | |
| 1276 | + mdio_mux_uninit(gmac->mux_handle); | |
| 1277 | + sun8i_dwmac_unpower_internal_phy(gmac); | |
| 1278 | + reset_control_put(gmac->rst_ephy); | |
| 1279 | + clk_put(gmac->ephy_clk); | |
| 1280 | + } | |
| 1281 | + | |
| 1249 | 1282 | stmmac_pltfr_remove(pdev); |
| 1250 | −return ret; | |
| 1283 | + sun8i_dwmac_unset_syscon(gmac); | |
| 1284 | + | |
| 1285 | + return 0; | |
| 1251 | 1286 | } |
| 1252 | 1287 | |
| 1253 | 1288 | static const struct of_device_id sun8i_dwmac_match[] = { |
| @@ -1269,7 +1304,7 @@ MODULE_DEVICE_TABLE(of, sun8i_dwmac_match); · 15 unmodified lines | ||
| 1269 | 1304 | |
| 1270 | 1305 | static struct platform_driver sun8i_dwmac_driver = { |
| 1271 | 1306 | .probe = sun8i_dwmac_probe, |
| 1272 | − .remove = stmmac_pltfr_remove, | |
| 1307 | + .remove = sun8i_dwmac_remove, | |
| 1273 | 1308 | .driver = { |
| 1274 | 1309 | .name = "dwmac-sun8i", |
| 1275 | 1310 | .pm = &stmmac_pltfr_pm_ops, |
| @@ -568,68 +568,24 @@ static int dwmac5_est_write(void __iomem *ioaddr, u32 reg, u32 val, bool gcl) · 567 unmodified lines | ||
| 568 | 568 | int dwmac5_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg, |
| 569 | 569 | unsigned int ptp_rate) |
| 570 | 570 | { |
| 571 | − u32 speed, total_offset, offset, ctrl, ctr_low; | |
| 572 | − u32 extcfg = readl(ioaddr + GMAC_EXT_CONFIG); | |
| 573 | − u32 mac_cfg = readl(ioaddr + GMAC_CONFIG); | |
| 574 | 571 | int i, ret = 0x0; |
| 575 | − u64 total_ctr; | |
| 576 | − | |
| 577 | − if (extcfg & GMAC_CONFIG_EIPG_EN) { | |
| 578 | − offset = (extcfg & GMAC_CONFIG_EIPG) >> GMAC_CONFIG_EIPG_SHIFT; | |
| 579 | − offset = 104 + (offset * 8); | |
| 580 | − } else { | |
| 581 | − offset = (mac_cfg & GMAC_CONFIG_IPG) >> GMAC_CONFIG_IPG_SHIFT; | |
| 582 | − offset = 96 - (offset * 8); | |
| 583 | − } | |
| 584 | − | |
| 585 | − speed = mac_cfg & (GMAC_CONFIG_PS | GMAC_CONFIG_FES); | |
| 586 | − speed = speed >> GMAC_CONFIG_FES_SHIFT; | |
| 587 | − | |
| 588 | − switch (speed) { | |
| 589 | − case 0x0: | |
| 590 | − offset = offset * 1000; /* 1G */ | |
| 591 | − break; | |
| 592 | − case 0x1: | |
| 593 | − offset = offset * 400; /* 2.5G */ | |
| 594 | − break; | |
| 595 | − case 0x2: | |
| 596 | − offset = offset * 100000; /* 10M */ | |
| 597 | − break; | |
| 598 | − case 0x3: | |
| 599 | − offset = offset * 10000; /* 100M */ | |
| 600 | − break; | |
| 601 | − default: | |
| 602 | − return -EINVAL; | |
| 603 | − } | |
| 604 | − | |
| 605 | − offset = offset / 1000; | |
| 572 | + u32 ctrl; | |
| 606 | 573 | |
| 607 | 574 | ret |= dwmac5_est_write(ioaddr, BTR_LOW, cfg->btr[0], false); |
| 608 | 575 | ret |= dwmac5_est_write(ioaddr, BTR_HIGH, cfg->btr[1], false); |
| 609 | 576 | ret |= dwmac5_est_write(ioaddr, TER, cfg->ter, false); |
| 610 | 577 | ret |= dwmac5_est_write(ioaddr, LLR, cfg->gcl_size, false); |
| 578 | + ret |= dwmac5_est_write(ioaddr, CTR_LOW, cfg->ctr[0], false); | |
| 579 | + ret |= dwmac5_est_write(ioaddr, CTR_HIGH, cfg->ctr[1], false); | |
| 611 | 580 | if (ret) |
| 612 | 581 | return ret; |
| 613 | 582 | |
| 614 | − total_offset = 0; | |
| 615 | 583 | for (i = 0; i < cfg->gcl_size; i++) { |
| 616 | − ret = dwmac5_est_write(ioaddr, i, cfg->gcl[i] + offset, true); | |
| 584 | + ret = dwmac5_est_write(ioaddr, i, cfg->gcl[i], true); | |
| 617 | 585 | if (ret) |
| 618 | 586 | return ret; |
| 619 | − | |
| 620 | − total_offset += offset; | |
| 621 | 587 | } |
| 622 | 588 | |
| 623 | − total_ctr = cfg->ctr[0] + cfg->ctr[1] * 1000000000ULL; | |
| 624 | − total_ctr += total_offset; | |
| 625 | − | |
| 626 | − ctr_low = do_div(total_ctr, 1000000000); | |
| 627 | − | |
| 628 | − ret |= dwmac5_est_write(ioaddr, CTR_LOW, ctr_low, false); | |
| 629 | − ret |= dwmac5_est_write(ioaddr, CTR_HIGH, total_ctr, false); | |
| 630 | − if (ret) | |
| 631 | − return ret; | |
| 632 | − | |
| 633 | 589 | ctrl = readl(ioaddr + MTL_EST_CONTROL); |
| 634 | 590 | ctrl &= ~PTOV; |
| 635 | 591 | ctrl |= ((1000000000 / ptp_rate) * 6) << PTOV_SHIFT; |
| @@ -2184,7 +2184,7 @@ static int stmmac_napi_check(struct stmmac_priv *priv, u32 chan) · 2183 unmodified lines | ||
| 2184 | 2184 | spin_lock_irqsave(&ch->lock, flags); |
| 2185 | 2185 | stmmac_disable_dma_irq(priv, priv->ioaddr, chan, 1, 0); |
| 2186 | 2186 | spin_unlock_irqrestore(&ch->lock, flags); |
| 2187 | − __napi_schedule_irqoff(&ch->rx_napi); | |
| 2187 | + __napi_schedule(&ch->rx_napi); | |
| 2188 | 2188 | } |
| 2189 | 2189 | } |
| 2190 | 2190 | |
| @@ -2193,7 +2193,7 @@ static int stmmac_napi_check(struct stmmac_priv *priv, u32 chan) · 2 unmodified lines | ||
| 2193 | 2193 | spin_lock_irqsave(&ch->lock, flags); |
| 2194 | 2194 | stmmac_disable_dma_irq(priv, priv->ioaddr, chan, 0, 1); |
| 2195 | 2195 | spin_unlock_irqrestore(&ch->lock, flags); |
| 2196 | − __napi_schedule_irqoff(&ch->tx_napi); | |
| 2196 | + __napi_schedule(&ch->tx_napi); | |
| 2197 | 2197 | } |
| 2198 | 2198 | } |
| 2199 | 2199 | |
| @@ -4026,6 +4026,7 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu) · 1826 unmodified lines | ||
| 4026 | 4026 | { |
| 4027 | 4027 | struct stmmac_priv *priv = netdev_priv(dev); |
| 4028 | 4028 | int txfifosz = priv->plat->tx_fifo_size; |
| 4029 | + const int mtu = new_mtu; | |
| 4029 | 4030 | |
| 4030 | 4031 | if (txfifosz == 0) |
| 4031 | 4032 | txfifosz = priv->dma_cap.tx_fifo_size; |
| @@ -4043,7 +4044,7 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu) · 11 unmodified lines | ||
| 4043 | 4044 | if ((txfifosz < new_mtu) || (new_mtu > BUF_SIZE_16KiB)) |
| 4044 | 4045 | return -EINVAL; |
| 4045 | 4046 | |
| 4046 | − dev->mtu = new_mtu; | |
| 4047 | + dev->mtu = mtu; | |
| 4047 | 4048 | |
| 4048 | 4049 | netdev_update_features(dev); |
| 4049 | 4050 | |
| @@ -599,7 +599,8 @@ static int tc_setup_taprio(struct stmmac_priv *priv, · 598 unmodified lines | ||
| 599 | 599 | { |
| 600 | 600 | u32 size, wid = priv->dma_cap.estwid, dep = priv->dma_cap.estdep; |
| 601 | 601 | struct plat_stmmacenet_data *plat = priv->plat; |
| 602 | − struct timespec64 time; | |
| 602 | + struct timespec64 time, current_time; | |
| 603 | + ktime_t current_time_ns; | |
| 603 | 604 | bool fpe = false; |
| 604 | 605 | int i, ret = 0; |
| 605 | 606 | u64 ctr; |
| @@ -694,7 +695,22 @@ static int tc_setup_taprio(struct stmmac_priv *priv, · 88 unmodified lines | ||
| 694 | 695 | } |
| 695 | 696 | |
| 696 | 697 | /* Adjust for real system time */ |
| 697 | − time = ktime_to_timespec64(qopt->base_time); | |
| 698 | + priv->ptp_clock_ops.gettime64(&priv->ptp_clock_ops, ¤t_time); | |
| 699 | + current_time_ns = timespec64_to_ktime(current_time); | |
| 700 | + if (ktime_after(qopt->base_time, current_time_ns)) { | |
| 701 | + time = ktime_to_timespec64(qopt->base_time); | |
| 702 | + } else { | |
| 703 | + ktime_t base_time; | |
| 704 | + s64 n; | |
| 705 | + | |
| 706 | + n = div64_s64(ktime_sub_ns(current_time_ns, qopt->base_time), | |
| 707 | + qopt->cycle_time); | |
| 708 | + base_time = ktime_add_ns(qopt->base_time, | |
| 709 | + (n + 1) * qopt->cycle_time); | |
| 710 | + | |
| 711 | + time = ktime_to_timespec64(base_time); | |
| 712 | + } | |
| 713 | + | |
| 698 | 714 | priv->plat->est->btr[0] = (u32)time.tv_nsec; |
| 699 | 715 | priv->plat->est->btr[1] = (u32)time.tv_sec; |
| 700 | 716 | |
| @@ -599,6 +599,7 @@ void cpts_unregister(struct cpts *cpts) · 598 unmodified lines | ||
| 599 | 599 | |
| 600 | 600 | ptp_clock_unregister(cpts->clock); |
| 601 | 601 | cpts->clock = NULL; |
| 602 | + cpts->phc_index = -1; | |
| 602 | 603 | |
| 603 | 604 | cpts_write32(cpts, 0, int_enable); |
| 604 | 605 | cpts_write32(cpts, 0, control); |
| @@ -784,6 +785,7 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs, · 179 unmodified lines | ||
| 784 | 785 | cpts->cc.read = cpts_systim_read; |
| 785 | 786 | cpts->cc.mask = CLOCKSOURCE_MASK(32); |
| 786 | 787 | cpts->info = cpts_info; |
| 788 | + cpts->phc_index = -1; | |
| 787 | 789 | |
| 788 | 790 | if (n_ext_ts) |
| 789 | 791 | cpts->info.n_ext_ts = n_ext_ts; |
| @@ -326,8 +326,8 @@ gsi_evt_ring_state(struct gsi *gsi, u32 evt_ring_id) · 325 unmodified lines | ||
| 326 | 326 | } |
| 327 | 327 | |
| 328 | 328 | /* Issue an event ring command and wait for it to complete */ |
| 329 | −static int evt_ring_command(struct gsi *gsi, u32 evt_ring_id, | |
| 330 | − enum gsi_evt_cmd_opcode opcode) | |
| 329 | +static void evt_ring_command(struct gsi *gsi, u32 evt_ring_id, | |
| 330 | + enum gsi_evt_cmd_opcode opcode) | |
| 331 | 331 | { |
| 332 | 332 | struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id]; |
| 333 | 333 | struct completion *completion = &evt_ring->completion; |
| @@ -340,7 +340,13 @@ static int evt_ring_command(struct gsi *gsi, u32 evt_ring_id, · 6 unmodified lines | ||
| 340 | 340 | * is issued here. Only permit *this* event ring to trigger |
| 341 | 341 | * an interrupt, and only enable the event control IRQ type |
| 342 | 342 | * when we expect it to occur. |
| 343 | + * | |
| 344 | + * There's a small chance that a previous command completed | |
| 345 | + * after the interrupt was disabled, so make sure we have no | |
| 346 | + * pending interrupts before we enable them. | |
| 343 | 347 | */ |
| 348 | + iowrite32(~0, gsi->virt + GSI_CNTXT_SRC_EV_CH_IRQ_CLR_OFFSET); | |
| 349 | + | |
| 344 | 350 | val = BIT(evt_ring_id); |
| 345 | 351 | iowrite32(val, gsi->virt + GSI_CNTXT_SRC_EV_CH_IRQ_MSK_OFFSET); |
| 346 | 352 | gsi_irq_type_enable(gsi, GSI_EV_CTRL); |
| @@ -355,19 +361,16 @@ static int evt_ring_command(struct gsi *gsi, u32 evt_ring_id, · 8 unmodified lines | ||
| 355 | 361 | iowrite32(0, gsi->virt + GSI_CNTXT_SRC_EV_CH_IRQ_MSK_OFFSET); |
| 356 | 362 | |
| 357 | 363 | if (success) |
| 358 | − return 0; | |
| 364 | + return; | |
| 359 | 365 | |
| 360 | 366 | dev_err(dev, "GSI command %u for event ring %u timed out, state %u\n", |
| 361 | 367 | opcode, evt_ring_id, evt_ring->state); |
| 362 | − | |
| 363 | − return -ETIMEDOUT; | |
| 364 | 368 | } |
| 365 | 369 | |
| 366 | 370 | /* Allocate an event ring in NOT_ALLOCATED state */ |
| 367 | 371 | static int gsi_evt_ring_alloc_command(struct gsi *gsi, u32 evt_ring_id) |
| 368 | 372 | { |
| 369 | 373 | struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id]; |
| 370 | − int ret; | |
| 371 | 374 | |
| 372 | 375 | /* Get initial event ring state */ |
| 373 | 376 | evt_ring->state = gsi_evt_ring_state(gsi, evt_ring_id); |
| @@ -377,14 +380,16 @@ static int gsi_evt_ring_alloc_command(struct gsi *gsi, u32 evt_ring_id) · 3 unmodified lines | ||
| 377 | 380 | return -EINVAL; |
| 378 | 381 | } |
| 379 | 382 | |
| 380 | − ret = evt_ring_command(gsi, evt_ring_id, GSI_EVT_ALLOCATE); | |
| 381 | − if (!ret && evt_ring->state != GSI_EVT_RING_STATE_ALLOCATED) { | |
| 382 | − dev_err(gsi->dev, "event ring %u bad state %u after alloc\n", | |
| 383 | − evt_ring_id, evt_ring->state); | |
| 384 | − ret = -EIO; | |
| 385 | − } | |
| 383 | + evt_ring_command(gsi, evt_ring_id, GSI_EVT_ALLOCATE); | |
| 386 | 384 | |
| 387 | − return ret; | |
| 385 | + /* If successful the event ring state will have changed */ | |
| 386 | + if (evt_ring->state == GSI_EVT_RING_STATE_ALLOCATED) | |
| 387 | + return 0; | |
| 388 | + | |
| 389 | + dev_err(gsi->dev, "event ring %u bad state %u after alloc\n", | |
| 390 | + evt_ring_id, evt_ring->state); | |
| 391 | + | |
| 392 | + return -EIO; | |
| 388 | 393 | } |
| 389 | 394 | |
| 390 | 395 | /* Reset a GSI event ring in ALLOCATED or ERROR state. */ |
| @@ -392,7 +397,6 @@ static void gsi_evt_ring_reset_command(struct gsi *gsi, u32 evt_ring_id) · 1 unmodified line | ||
| 392 | 397 | { |
| 393 | 398 | struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id]; |
| 394 | 399 | enum gsi_evt_ring_state state = evt_ring->state; |
| 395 | − int ret; | |
| 396 | 400 | |
| 397 | 401 | if (state != GSI_EVT_RING_STATE_ALLOCATED && |
| 398 | 402 | state != GSI_EVT_RING_STATE_ERROR) { |
| @@ -401,17 +405,20 @@ static void gsi_evt_ring_reset_command(struct gsi *gsi, u32 evt_ring_id) · 2 unmodified lines | ||
| 401 | 405 | return; |
| 402 | 406 | } |
| 403 | 407 | |
| 404 | − ret = evt_ring_command(gsi, evt_ring_id, GSI_EVT_RESET); | |
| 405 | − if (!ret && evt_ring->state != GSI_EVT_RING_STATE_ALLOCATED) | |
| 406 | − dev_err(gsi->dev, "event ring %u bad state %u after reset\n", | |
| 407 | − evt_ring_id, evt_ring->state); | |
| 408 | + evt_ring_command(gsi, evt_ring_id, GSI_EVT_RESET); | |
| 409 | + | |
| 410 | + /* If successful the event ring state will have changed */ | |
| 411 | + if (evt_ring->state == GSI_EVT_RING_STATE_ALLOCATED) | |
| 412 | + return; | |
| 413 | + | |
| 414 | + dev_err(gsi->dev, "event ring %u bad state %u after reset\n", | |
| 415 | + evt_ring_id, evt_ring->state); | |
| 408 | 416 | } |
| 409 | 417 | |
| 410 | 418 | /* Issue a hardware de-allocation request for an allocated event ring */ |
| 411 | 419 | static void gsi_evt_ring_de_alloc_command(struct gsi *gsi, u32 evt_ring_id) |
| 412 | 420 | { |
| 413 | 421 | struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id]; |
| 414 | − int ret; | |
| 415 | 422 | |
| 416 | 423 | if (evt_ring->state != GSI_EVT_RING_STATE_ALLOCATED) { |
| 417 | 424 | dev_err(gsi->dev, "event ring %u state %u before dealloc\n", |
| @@ -419,10 +426,14 @@ static void gsi_evt_ring_de_alloc_command(struct gsi *gsi, u32 evt_ring_id) · 1 unmodified line | ||
| 419 | 426 | return; |
| 420 | 427 | } |
| 421 | 428 | |
| 422 | − ret = evt_ring_command(gsi, evt_ring_id, GSI_EVT_DE_ALLOC); | |
| 423 | − if (!ret && evt_ring->state != GSI_EVT_RING_STATE_NOT_ALLOCATED) | |
| 424 | − dev_err(gsi->dev, "event ring %u bad state %u after dealloc\n", | |
| 425 | − evt_ring_id, evt_ring->state); | |
| 429 | + evt_ring_command(gsi, evt_ring_id, GSI_EVT_DE_ALLOC); | |
| 430 | + | |
| 431 | + /* If successful the event ring state will have changed */ | |
| 432 | + if (evt_ring->state == GSI_EVT_RING_STATE_NOT_ALLOCATED) | |
| 433 | + return; | |
| 434 | + | |
| 435 | + dev_err(gsi->dev, "event ring %u bad state %u after dealloc\n", | |
| 436 | + evt_ring_id, evt_ring->state); | |
| 426 | 437 | } |
| 427 | 438 | |
| 428 | 439 | /* Fetch the current state of a channel from hardware */ |
| @@ -438,7 +449,7 @@ static enum gsi_channel_state gsi_channel_state(struct gsi_channel *channel) · 9 unmodified lines | ||
| 438 | 449 | } |
| 439 | 450 | |
| 440 | 451 | /* Issue a channel command and wait for it to complete */ |
| 441 | −static int | |
| 452 | +static void | |
| 442 | 453 | gsi_channel_command(struct gsi_channel *channel, enum gsi_ch_cmd_opcode opcode) |
| 443 | 454 | { |
| 444 | 455 | struct completion *completion = &channel->completion; |
| @@ -453,7 +464,13 @@ gsi_channel_command(struct gsi_channel *channel, enum gsi_ch_cmd_opcode opcode) · 8 unmodified lines | ||
| 453 | 464 | * issued here. So we only permit *this* channel to trigger |
| 454 | 465 | * an interrupt and only enable the channel control IRQ type |
| 455 | 466 | * when we expect it to occur. |
| 467 | + * | |
| 468 | + * There's a small chance that a previous command completed | |
| 469 | + * after the interrupt was disabled, so make sure we have no | |
| 470 | + * pending interrupts before we enable them. | |
| 456 | 471 | */ |
| 472 | + iowrite32(~0, gsi->virt + GSI_CNTXT_SRC_CH_IRQ_CLR_OFFSET); | |
| 473 | + | |
| 457 | 474 | val = BIT(channel_id); |
| 458 | 475 | iowrite32(val, gsi->virt + GSI_CNTXT_SRC_CH_IRQ_MSK_OFFSET); |
| 459 | 476 | gsi_irq_type_enable(gsi, GSI_CH_CTRL); |
| @@ -467,12 +484,10 @@ gsi_channel_command(struct gsi_channel *channel, enum gsi_ch_cmd_opcode opcode) · 7 unmodified lines | ||
| 467 | 484 | iowrite32(0, gsi->virt + GSI_CNTXT_SRC_CH_IRQ_MSK_OFFSET); |
| 468 | 485 | |
| 469 | 486 | if (success) |
| 470 | − return 0; | |
| 487 | + return; | |
| 471 | 488 | |
| 472 | 489 | dev_err(dev, "GSI command %u for channel %u timed out, state %u\n", |
| 473 | 490 | opcode, channel_id, gsi_channel_state(channel)); |
| 474 | − | |
| 475 | − return -ETIMEDOUT; | |
| 476 | 491 | } |
| 477 | 492 | |
| 478 | 493 | /* Allocate GSI channel in NOT_ALLOCATED state */ |
| @@ -481,7 +496,6 @@ static int gsi_channel_alloc_command(struct gsi *gsi, u32 channel_id) · 2 unmodified lines | ||
| 481 | 496 | struct gsi_channel *channel = &gsi->channel[channel_id]; |
| 482 | 497 | struct device *dev = gsi->dev; |
| 483 | 498 | enum gsi_channel_state state; |
| 484 | − int ret; | |
| 485 | 499 | |
| 486 | 500 | /* Get initial channel state */ |
| 487 | 501 | state = gsi_channel_state(channel); |
| @@ -491,17 +505,17 @@ static int gsi_channel_alloc_command(struct gsi *gsi, u32 channel_id) · 3 unmodified lines | ||
| 491 | 505 | return -EINVAL; |
| 492 | 506 | } |
| 493 | 507 | |
| 494 | − ret = gsi_channel_command(channel, GSI_CH_ALLOCATE); | |
| 508 | + gsi_channel_command(channel, GSI_CH_ALLOCATE); | |
| 495 | 509 | |
| 496 | − /* Channel state will normally have been updated */ | |
| 510 | + /* If successful the channel state will have changed */ | |
| 497 | 511 | state = gsi_channel_state(channel); |
| 498 | − if (!ret && state != GSI_CHANNEL_STATE_ALLOCATED) { | |
| 499 | − dev_err(dev, "channel %u bad state %u after alloc\n", | |
| 500 | − channel_id, state); | |
| 501 | − ret = -EIO; | |
| 502 | − } | |
| 512 | + if (state == GSI_CHANNEL_STATE_ALLOCATED) | |
| 513 | + return 0; | |
| 503 | 514 | |
| 504 | − return ret; | |
| 515 | + dev_err(dev, "channel %u bad state %u after alloc\n", | |
| 516 | + channel_id, state); | |
| 517 | + | |
| 518 | + return -EIO; | |
| 505 | 519 | } |
| 506 | 520 | |
| 507 | 521 | /* Start an ALLOCATED channel */ |
| @@ -509,7 +523,6 @@ static int gsi_channel_start_command(struct gsi_channel *channel) · 1 unmodified line | ||
| 509 | 523 | { |
| 510 | 524 | struct device *dev = channel->gsi->dev; |
| 511 | 525 | enum gsi_channel_state state; |
| 512 | − int ret; | |
| 513 | 526 | |
| 514 | 527 | state = gsi_channel_state(channel); |
| 515 | 528 | if (state != GSI_CHANNEL_STATE_ALLOCATED && |
| @@ -519,17 +532,17 @@ static int gsi_channel_start_command(struct gsi_channel *channel) · 3 unmodified lines | ||
| 519 | 532 | return -EINVAL; |
| 520 | 533 | } |
| 521 | 534 | |
| 522 | − ret = gsi_channel_command(channel, GSI_CH_START); | |
| 535 | + gsi_channel_command(channel, GSI_CH_START); | |
| 523 | 536 | |
| 524 | − /* Channel state will normally have been updated */ | |
| 537 | + /* If successful the channel state will have changed */ | |
| 525 | 538 | state = gsi_channel_state(channel); |
| 526 | − if (!ret && state != GSI_CHANNEL_STATE_STARTED) { | |
| 527 | − dev_err(dev, "channel %u bad state %u after start\n", | |
| 528 | − gsi_channel_id(channel), state); | |
| 529 | − ret = -EIO; | |
| 530 | − } | |
| 539 | + if (state == GSI_CHANNEL_STATE_STARTED) | |
| 540 | + return 0; | |
| 531 | 541 | |
| 532 | − return ret; | |
| 542 | + dev_err(dev, "channel %u bad state %u after start\n", | |
| 543 | + gsi_channel_id(channel), state); | |
| 544 | + | |
| 545 | + return -EIO; | |
| 533 | 546 | } |
| 534 | 547 | |
| 535 | 548 | /* Stop a GSI channel in STARTED state */ |
| @@ -537,7 +550,6 @@ static int gsi_channel_stop_command(struct gsi_channel *channel) · 1 unmodified line | ||
| 537 | 550 | { |
| 538 | 551 | struct device *dev = channel->gsi->dev; |
| 539 | 552 | enum gsi_channel_state state; |
| 540 | − int ret; | |
| 541 | 553 | |
| 542 | 554 | state = gsi_channel_state(channel); |
| 543 | 555 | |
| @@ -554,12 +566,12 @@ static int gsi_channel_stop_command(struct gsi_channel *channel) · 10 unmodified lines | ||
| 554 | 566 | return -EINVAL; |
| 555 | 567 | } |
| 556 | 568 | |
| 557 | − ret = gsi_channel_command(channel, GSI_CH_STOP); | |
| 569 | + gsi_channel_command(channel, GSI_CH_STOP); | |
| 558 | 570 | |
| 559 | − /* Channel state will normally have been updated */ | |
| 571 | + /* If successful the channel state will have changed */ | |
| 560 | 572 | state = gsi_channel_state(channel); |
| 561 | − if (ret || state == GSI_CHANNEL_STATE_STOPPED) | |
| 562 | − return ret; | |
| 573 | + if (state == GSI_CHANNEL_STATE_STOPPED) | |
| 574 | + return 0; | |
| 563 | 575 | |
| 564 | 576 | /* We may have to try again if stop is in progress */ |
| 565 | 577 | if (state == GSI_CHANNEL_STATE_STOP_IN_PROC) |
| @@ -576,7 +588,6 @@ static void gsi_channel_reset_command(struct gsi_channel *channel) · 10 unmodified lines | ||
| 576 | 588 | { |
| 577 | 589 | struct device *dev = channel->gsi->dev; |
| 578 | 590 | enum gsi_channel_state state; |
| 579 | − int ret; | |
| 580 | 591 | |
| 581 | 592 | msleep(1); /* A short delay is required before a RESET command */ |
| 582 | 593 | |
| @@ -590,11 +601,11 @@ static void gsi_channel_reset_command(struct gsi_channel *channel) · 7 unmodified lines | ||
| 590 | 601 | return; |
| 591 | 602 | } |
| 592 | 603 | |
| 593 | − ret = gsi_channel_command(channel, GSI_CH_RESET); | |
| 604 | + gsi_channel_command(channel, GSI_CH_RESET); | |
| 594 | 605 | |
| 595 | − /* Channel state will normally have been updated */ | |
| 606 | + /* If successful the channel state will have changed */ | |
| 596 | 607 | state = gsi_channel_state(channel); |
| 597 | − if (!ret && state != GSI_CHANNEL_STATE_ALLOCATED) | |
| 608 | + if (state != GSI_CHANNEL_STATE_ALLOCATED) | |
| 598 | 609 | dev_err(dev, "channel %u bad state %u after reset\n", |
| 599 | 610 | gsi_channel_id(channel), state); |
| 600 | 611 | } |
| @@ -605,7 +616,6 @@ static void gsi_channel_de_alloc_command(struct gsi *gsi, u32 channel_id) · 4 unmodified lines | ||
| 605 | 616 | struct gsi_channel *channel = &gsi->channel[channel_id]; |
| 606 | 617 | struct device *dev = gsi->dev; |
| 607 | 618 | enum gsi_channel_state state; |
| 608 | − int ret; | |
| 609 | 619 | |
| 610 | 620 | state = gsi_channel_state(channel); |
| 611 | 621 | if (state != GSI_CHANNEL_STATE_ALLOCATED) { |
| @@ -614,11 +624,12 @@ static void gsi_channel_de_alloc_command(struct gsi *gsi, u32 channel_id) · 2 unmodified lines | ||
| 614 | 624 | return; |
| 615 | 625 | } |
| 616 | 626 | |
| 617 | − ret = gsi_channel_command(channel, GSI_CH_DE_ALLOC); | |
| 627 | + gsi_channel_command(channel, GSI_CH_DE_ALLOC); | |
| 618 | 628 | |
| 619 | − /* Channel state will normally have been updated */ | |
| 629 | + /* If successful the channel state will have changed */ | |
| 620 | 630 | state = gsi_channel_state(channel); |
| 621 | − if (!ret && state != GSI_CHANNEL_STATE_NOT_ALLOCATED) | |
| 631 | + | |
| 632 | + if (state != GSI_CHANNEL_STATE_NOT_ALLOCATED) | |
| 622 | 633 | dev_err(dev, "channel %u bad state %u after dealloc\n", |
| 623 | 634 | channel_id, state); |
| 624 | 635 | } |
| @@ -115,13 +115,13 @@ static int ipa_interconnect_enable(struct ipa *ipa) · 114 unmodified lines | ||
| 115 | 115 | return ret; |
| 116 | 116 | |
| 117 | 117 | data = &clock->interconnect_data[IPA_INTERCONNECT_IMEM]; |
| 118 | − ret = icc_set_bw(clock->memory_path, data->average_rate, | |
| 118 | + ret = icc_set_bw(clock->imem_path, data->average_rate, | |
| 119 | 119 | data->peak_rate); |
| 120 | 120 | if (ret) |
| 121 | 121 | goto err_memory_path_disable; |
| 122 | 122 | |
| 123 | 123 | data = &clock->interconnect_data[IPA_INTERCONNECT_CONFIG]; |
| 124 | − ret = icc_set_bw(clock->memory_path, data->average_rate, | |
| 124 | + ret = icc_set_bw(clock->config_path, data->average_rate, | |
| 125 | 125 | data->peak_rate); |
| 126 | 126 | if (ret) |
| 127 | 127 | goto err_imem_path_disable; |
| @@ -216,6 +216,7 @@ int ipa_modem_start(struct ipa *ipa) · 215 unmodified lines | ||
| 216 | 216 | ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]->netdev = netdev; |
| 217 | 217 | ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]->netdev = netdev; |
| 218 | 218 | |
| 219 | + SET_NETDEV_DEV(netdev, &ipa->pdev->dev); | |
| 219 | 220 | priv = netdev_priv(netdev); |
| 220 | 221 | priv->ipa = ipa; |
| 221 | 222 | |
| @@ -317,7 +317,8 @@ static int smsc_phy_probe(struct phy_device *phydev) · 316 unmodified lines | ||
| 317 | 317 | /* Make clk optional to keep DTB backward compatibility. */ |
| 318 | 318 | priv->refclk = clk_get_optional(dev, NULL); |
| 319 | 319 | if (IS_ERR(priv->refclk)) |
| 320 | − dev_err_probe(dev, PTR_ERR(priv->refclk), "Failed to request clock\n"); | |
| 320 | + return dev_err_probe(dev, PTR_ERR(priv->refclk), | |
| 321 | + "Failed to request clock\n"); | |
| 321 | 322 | |
| 322 | 323 | ret = clk_prepare_enable(priv->refclk); |
| 323 | 324 | if (ret) |
| @@ -623,6 +623,7 @@ static int ppp_bridge_channels(struct channel *pch, struct channel *pchb) · 622 unmodified lines | ||
| 623 | 623 | write_unlock_bh(&pch->upl); |
| 624 | 624 | return -EALREADY; |
| 625 | 625 | } |
| 626 | + refcount_inc(&pchb->file.refcnt); | |
| 626 | 627 | rcu_assign_pointer(pch->bridge, pchb); |
| 627 | 628 | write_unlock_bh(&pch->upl); |
| 628 | 629 | |
| @@ -632,19 +633,24 @@ static int ppp_bridge_channels(struct channel *pch, struct channel *pchb) · 3 unmodified lines | ||
| 632 | 633 | write_unlock_bh(&pchb->upl); |
| 633 | 634 | goto err_unset; |
| 634 | 635 | } |
| 636 | + refcount_inc(&pch->file.refcnt); | |
| 635 | 637 | rcu_assign_pointer(pchb->bridge, pch); |
| 636 | 638 | write_unlock_bh(&pchb->upl); |
| 637 | 639 | |
| 638 | − refcount_inc(&pch->file.refcnt); | |
| 639 | − refcount_inc(&pchb->file.refcnt); | |
| 640 | − | |
| 641 | 640 | return 0; |
| 642 | 641 | |
| 643 | 642 | err_unset: |
| 644 | 643 | write_lock_bh(&pch->upl); |
| 644 | + /* Re-read pch->bridge with upl held in case it was modified concurrently */ | |
| 645 | + pchb = rcu_dereference_protected(pch->bridge, lockdep_is_held(&pch->upl)); | |
| 645 | 646 | RCU_INIT_POINTER(pch->bridge, NULL); |
| 646 | 647 | write_unlock_bh(&pch->upl); |
| 647 | 648 | synchronize_rcu(); |
| 649 | + | |
| 650 | + if (pchb) | |
| 651 | + if (refcount_dec_and_test(&pchb->file.refcnt)) | |
| 652 | + ppp_destroy_channel(pchb); | |
| 653 | + | |
| 648 | 654 | return -EALREADY; |
| 649 | 655 | } |
| 650 | 656 | |
| @@ -1365,7 +1365,7 @@ static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile, · 1364 unmodified lines | ||
| 1365 | 1365 | int i; |
| 1366 | 1366 | |
| 1367 | 1367 | if (it->nr_segs > MAX_SKB_FRAGS + 1) |
| 1368 | − return ERR_PTR(-ENOMEM); | |
| 1368 | + return ERR_PTR(-EMSGSIZE); | |
| 1369 | 1369 | |
| 1370 | 1370 | local_bh_disable(); |
| 1371 | 1371 | skb = napi_get_frags(&tfile->napi); |
| @@ -631,7 +631,6 @@ config USB_NET_AQC111 · 630 unmodified lines | ||
| 631 | 631 | config USB_RTL8153_ECM |
| 632 | 632 | tristate "RTL8153 ECM support" |
| 633 | 633 | depends on USB_NET_CDCETHER && (USB_RTL8152 || USB_RTL8152=n) |
| 634 | − default y | |
| 635 | 634 | help |
| 636 | 635 | This option supports ECM mode for RTL8153 ethernet adapter, when |
| 637 | 636 | CONFIG_USB_RTL8152 is not set, or the RTL8153 device is not |
| @@ -793,6 +793,13 @@ static const struct usb_device_id products[] = { · 792 unmodified lines | ||
| 793 | 793 | .driver_info = 0, |
| 794 | 794 | }, |
| 795 | 795 | |
| 796 | +/* Lenovo Powered USB-C Travel Hub (4X90S92381, based on Realtek RTL8153) */ | |
| 797 | +{ | |
| 798 | + USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x721e, USB_CLASS_COMM, | |
| 799 | + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), | |
| 800 | + .driver_info = 0, | |
| 801 | +}, | |
| 802 | + | |
| 796 | 803 | /* ThinkPad USB-C Dock Gen 2 (based on Realtek RTL8153) */ |
| 797 | 804 | { |
| 798 | 805 | USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0xa387, USB_CLASS_COMM, |
| @@ -1199,7 +1199,10 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) · 1198 unmodified lines | ||
| 1199 | 1199 | * accordingly. Otherwise, we should check here. |
| 1200 | 1200 | */ |
| 1201 | 1201 | if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) |
| 1202 | − delayed_ndp_size = ALIGN(ctx->max_ndp_size, ctx->tx_ndp_modulus); | |
| 1202 | + delayed_ndp_size = ctx->max_ndp_size + | |
| 1203 | + max_t(u32, | |
| 1204 | + ctx->tx_ndp_modulus, | |
| 1205 | + ctx->tx_modulus + ctx->tx_remainder) - 1; | |
| 1203 | 1206 | else |
| 1204 | 1207 | delayed_ndp_size = 0; |
| 1205 | 1208 | |
| @@ -1410,7 +1413,8 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) · 204 unmodified lines | ||
| 1410 | 1413 | if (!(dev->driver_info->flags & FLAG_SEND_ZLP) && |
| 1411 | 1414 | skb_out->len > ctx->min_tx_pkt) { |
| 1412 | 1415 | padding_count = ctx->tx_curr_size - skb_out->len; |
| 1413 | − skb_put_zero(skb_out, padding_count); | |
| 1416 | + if (!WARN_ON(padding_count > ctx->tx_curr_size)) | |
| 1417 | + skb_put_zero(skb_out, padding_count); | |
| 1414 | 1418 | } else if (skb_out->len < ctx->tx_curr_size && |
| 1415 | 1419 | (skb_out->len % dev->maxpacket) == 0) { |
| 1416 | 1420 | skb_put_u8(skb_out, 0); /* force short packet */ |
| @@ -1863,9 +1867,6 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) · 446 unmodified lines | ||
| 1863 | 1867 | * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be |
| 1864 | 1868 | * sent by device after USB_CDC_NOTIFY_SPEED_CHANGE. |
| 1865 | 1869 | */ |
| 1866 | − netif_info(dev, link, dev->net, | |
| 1867 | − "network connection: %sconnected\n", | |
| 1868 | − !!event->wValue ? "" : "dis"); | |
| 1869 | 1870 | usbnet_link_change(dev, !!event->wValue, 0); |
| 1870 | 1871 | break; |
| 1871 | 1872 | |
| @@ -1013,6 +1013,7 @@ static const struct usb_device_id products[] = { · 1012 unmodified lines | ||
| 1013 | 1013 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ |
| 1014 | 1014 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ |
| 1015 | 1015 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */ |
| 1016 | + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0620)}, /* Quectel EM160R-GL */ | |
| 1016 | 1017 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */ |
| 1017 | 1018 | |
| 1018 | 1019 | /* 3. Combined interface devices matching on interface number */ |
| @@ -6877,6 +6877,7 @@ static const struct usb_device_id rtl8152_table[] = { · 6876 unmodified lines | ||
| 6877 | 6877 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, |
| 6878 | 6878 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x720c)}, |
| 6879 | 6879 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214)}, |
| 6880 | + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x721e)}, | |
| 6880 | 6881 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0xa387)}, |
| 6881 | 6882 | {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)}, |
| 6882 | 6883 | {REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff)}, |
| @@ -122,12 +122,20 @@ static const struct driver_info r8153_info = { · 121 unmodified lines | ||
| 122 | 122 | }; |
| 123 | 123 | |
| 124 | 124 | static const struct usb_device_id products[] = { |
| 125 | +/* Realtek RTL8153 Based USB 3.0 Ethernet Adapters */ | |
| 125 | 126 | { |
| 126 | 127 | USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ID_REALTEK, 0x8153, USB_CLASS_COMM, |
| 127 | 128 | USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), |
| 128 | 129 | .driver_info = (unsigned long)&r8153_info, |
| 129 | 130 | }, |
| 130 | 131 | |
| 132 | +/* Lenovo Powered USB-C Travel Hub (4X90S92381, based on Realtek RTL8153) */ | |
| 133 | +{ | |
| 134 | + USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ID_LENOVO, 0x721e, USB_CLASS_COMM, | |
| 135 | + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), | |
| 136 | + .driver_info = (unsigned long)&r8153_info, | |
| 137 | +}, | |
| 138 | + | |
| 131 | 139 | { }, /* END */ |
| 132 | 140 | }; |
| 133 | 141 | MODULE_DEVICE_TABLE(usb, products); |
| @@ -387,7 +387,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) · 386 unmodified lines | ||
| 387 | 387 | reply_len = sizeof *phym; |
| 388 | 388 | retval = rndis_query(dev, intf, u.buf, |
| 389 | 389 | RNDIS_OID_GEN_PHYSICAL_MEDIUM, |
| 390 | − 0, (void **) &phym, &reply_len); | |
| 390 | + reply_len, (void **)&phym, &reply_len); | |
| 391 | 391 | if (retval != 0 || !phym) { |
| 392 | 392 | /* OID is optional so don't fail here. */ |
| 393 | 393 | phym_unspec = cpu_to_le32(RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED); |
| @@ -2093,14 +2093,16 @@ static int virtnet_set_channels(struct net_device *dev, · 2092 unmodified lines | ||
| 2093 | 2093 | |
| 2094 | 2094 | get_online_cpus(); |
| 2095 | 2095 | err = _virtnet_set_queues(vi, queue_pairs); |
| 2096 | − if (!err) { | |
| 2097 | − netif_set_real_num_tx_queues(dev, queue_pairs); | |
| 2098 | − netif_set_real_num_rx_queues(dev, queue_pairs); | |
| 2099 | − | |
| 2100 | − virtnet_set_affinity(vi); | |
| 2096 | + if (err) { | |
| 2097 | + put_online_cpus(); | |
| 2098 | + goto err; | |
| 2101 | 2099 | } |
| 2100 | + virtnet_set_affinity(vi); | |
| 2102 | 2101 | put_online_cpus(); |
| 2103 | 2102 | |
| 2103 | + netif_set_real_num_tx_queues(dev, queue_pairs); | |
| 2104 | + netif_set_real_num_rx_queues(dev, queue_pairs); | |
| 2105 | + err: | |
| 2104 | 2106 | return err; |
| 2105 | 2107 | } |
| 2106 | 2108 | |
| @@ -282,6 +282,7 @@ config SLIC_DS26522 · 281 unmodified lines | ||
| 282 | 282 | tristate "Slic Maxim ds26522 card support" |
| 283 | 283 | depends on SPI |
| 284 | 284 | depends on FSL_SOC || ARCH_MXC || ARCH_LAYERSCAPE || COMPILE_TEST |
| 285 | + select BITREVERSE | |
| 285 | 286 | help |
| 286 | 287 | This module initializes and configures the slic maxim card |
| 287 | 288 | in T1 or E1 mode. |
| @@ -569,6 +569,13 @@ static void ppp_timer(struct timer_list *t) · 568 unmodified lines | ||
| 569 | 569 | unsigned long flags; |
| 570 | 570 | |
| 571 | 571 | spin_lock_irqsave(&ppp->lock, flags); |
| 572 | + /* mod_timer could be called after we entered this function but | |
| 573 | + * before we got the lock. | |
| 574 | + */ | |
| 575 | + if (timer_pending(&proto->timer)) { | |
| 576 | + spin_unlock_irqrestore(&ppp->lock, flags); | |
| 577 | + return; | |
| 578 | + } | |
| 572 | 579 | switch (proto->state) { |
| 573 | 580 | case STOPPING: |
| 574 | 581 | case REQ_SENT: |
| @@ -185,7 +185,7 @@ int ath11k_core_suspend(struct ath11k_base *ab) · 184 unmodified lines | ||
| 185 | 185 | ath11k_hif_ce_irq_disable(ab); |
| 186 | 186 | |
| 187 | 187 | ret = ath11k_hif_suspend(ab); |
| 188 | − if (!ret) { | |
| 188 | + if (ret) { | |
| 189 | 189 | ath11k_warn(ab, "failed to suspend hif: %d\n", ret); |
| 190 | 190 | return ret; |
| 191 | 191 | } |
| @@ -2294,6 +2294,7 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc, · 2293 unmodified lines | ||
| 2294 | 2294 | { |
| 2295 | 2295 | u8 channel_num; |
| 2296 | 2296 | u32 center_freq; |
| 2297 | + struct ieee80211_channel *channel; | |
| 2297 | 2298 | |
| 2298 | 2299 | rx_status->freq = 0; |
| 2299 | 2300 | rx_status->rate_idx = 0; |
| @@ -2314,9 +2315,12 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc, · 14 unmodified lines | ||
| 2314 | 2315 | rx_status->band = NL80211_BAND_5GHZ; |
| 2315 | 2316 | } else { |
| 2316 | 2317 | spin_lock_bh(&ar->data_lock); |
| 2317 | − rx_status->band = ar->rx_channel->band; | |
| 2318 | − channel_num = | |
| 2319 | − ieee80211_frequency_to_channel(ar->rx_channel->center_freq); | |
| 2318 | + channel = ar->rx_channel; | |
| 2319 | + if (channel) { | |
| 2320 | + rx_status->band = channel->band; | |
| 2321 | + channel_num = | |
| 2322 | + ieee80211_frequency_to_channel(channel->center_freq); | |
| 2323 | + } | |
| 2320 | 2324 | spin_unlock_bh(&ar->data_lock); |
| 2321 | 2325 | ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "rx_desc: ", |
| 2322 | 2326 | rx_desc, sizeof(struct hal_rx_desc)); |
| @@ -3021,6 +3021,7 @@ static int ath11k_mac_station_add(struct ath11k *ar, · 3020 unmodified lines | ||
| 3021 | 3021 | } |
| 3022 | 3022 | |
| 3023 | 3023 | if (ab->hw_params.vdev_start_delay && |
| 3024 | + !arvif->is_started && | |
| 3024 | 3025 | arvif->vdev_type != WMI_VDEV_TYPE_AP) { |
| 3025 | 3026 | ret = ath11k_start_vdev_delay(ar->hw, vif); |
| 3026 | 3027 | if (ret) { |
| @@ -5284,7 +5285,8 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, · 2257 unmodified lines | ||
| 5284 | 5285 | /* for QCA6390 bss peer must be created before vdev_start */ |
| 5285 | 5286 | if (ab->hw_params.vdev_start_delay && |
| 5286 | 5287 | arvif->vdev_type != WMI_VDEV_TYPE_AP && |
| 5287 | − arvif->vdev_type != WMI_VDEV_TYPE_MONITOR) { | |
| 5288 | + arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && | |
| 5289 | + !ath11k_peer_find_by_vdev_id(ab, arvif->vdev_id)) { | |
| 5288 | 5290 | memcpy(&arvif->chanctx, ctx, sizeof(*ctx)); |
| 5289 | 5291 | ret = 0; |
| 5290 | 5292 | goto out; |
| @@ -5295,7 +5297,9 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, · 4 unmodified lines | ||
| 5295 | 5297 | goto out; |
| 5296 | 5298 | } |
| 5297 | 5299 | |
| 5298 | − if (ab->hw_params.vdev_start_delay) { | |
| 5300 | + if (ab->hw_params.vdev_start_delay && | |
| 5301 | + (arvif->vdev_type == WMI_VDEV_TYPE_AP || | |
| 5302 | + arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)) { | |
| 5299 | 5303 | param.vdev_id = arvif->vdev_id; |
| 5300 | 5304 | param.peer_type = WMI_PEER_TYPE_DEFAULT; |
| 5301 | 5305 | param.peer_addr = ar->mac_addr; |
| @@ -274,7 +274,7 @@ static int ath11k_pci_fix_l1ss(struct ath11k_base *ab) · 273 unmodified lines | ||
| 274 | 274 | PCIE_QSERDES_COM_SYSCLK_EN_SEL_REG, |
| 275 | 275 | PCIE_QSERDES_COM_SYSCLK_EN_SEL_VAL, |
| 276 | 276 | PCIE_QSERDES_COM_SYSCLK_EN_SEL_MSK); |
| 277 | − if (!ret) { | |
| 277 | + if (ret) { | |
| 278 | 278 | ath11k_warn(ab, "failed to set sysclk: %d\n", ret); |
| 279 | 279 | return ret; |
| 280 | 280 | } |
| @@ -283,7 +283,7 @@ static int ath11k_pci_fix_l1ss(struct ath11k_base *ab) · 2 unmodified lines | ||
| 283 | 283 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG1_REG, |
| 284 | 284 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG1_VAL, |
| 285 | 285 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK); |
| 286 | − if (!ret) { | |
| 286 | + if (ret) { | |
| 287 | 287 | ath11k_warn(ab, "failed to set dtct config1 error: %d\n", ret); |
| 288 | 288 | return ret; |
| 289 | 289 | } |
| @@ -292,7 +292,7 @@ static int ath11k_pci_fix_l1ss(struct ath11k_base *ab) · 2 unmodified lines | ||
| 292 | 292 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG2_REG, |
| 293 | 293 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG2_VAL, |
| 294 | 294 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK); |
| 295 | − if (!ret) { | |
| 295 | + if (ret) { | |
| 296 | 296 | ath11k_warn(ab, "failed to set dtct config2: %d\n", ret); |
| 297 | 297 | return ret; |
| 298 | 298 | } |
| @@ -301,7 +301,7 @@ static int ath11k_pci_fix_l1ss(struct ath11k_base *ab) · 2 unmodified lines | ||
| 301 | 301 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG4_REG, |
| 302 | 302 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG4_VAL, |
| 303 | 303 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK); |
| 304 | − if (!ret) { | |
| 304 | + if (ret) { | |
| 305 | 305 | ath11k_warn(ab, "failed to set dtct config4: %d\n", ret); |
| 306 | 306 | return ret; |
| 307 | 307 | } |
| @@ -886,6 +886,32 @@ static void ath11k_pci_free_region(struct ath11k_pci *ab_pci) · 578 unmodified lines | ||
| 886 | 886 | pci_disable_device(pci_dev); |
| 887 | 887 | } |
| 888 | 888 | |
| 889 | +static void ath11k_pci_aspm_disable(struct ath11k_pci *ab_pci) | |
| 890 | +{ | |
| 891 | + struct ath11k_base *ab = ab_pci->ab; | |
| 892 | + | |
| 893 | + pcie_capability_read_word(ab_pci->pdev, PCI_EXP_LNKCTL, | |
| 894 | + &ab_pci->link_ctl); | |
| 895 | + | |
| 896 | + ath11k_dbg(ab, ATH11K_DBG_PCI, "pci link_ctl 0x%04x L0s %d L1 %d\n", | |
| 897 | + ab_pci->link_ctl, | |
| 898 | + u16_get_bits(ab_pci->link_ctl, PCI_EXP_LNKCTL_ASPM_L0S), | |
| 899 | + u16_get_bits(ab_pci->link_ctl, PCI_EXP_LNKCTL_ASPM_L1)); | |
| 900 | + | |
| 901 | + /* disable L0s and L1 */ | |
| 902 | + pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL, | |
| 903 | + ab_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC); | |
| 904 | + | |
| 905 | + set_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags); | |
| 906 | +} | |
| 907 | + | |
| 908 | +static void ath11k_pci_aspm_restore(struct ath11k_pci *ab_pci) | |
| 909 | +{ | |
| 910 | + if (test_and_clear_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags)) | |
| 911 | + pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL, | |
| 912 | + ab_pci->link_ctl); | |
| 913 | +} | |
| 914 | + | |
| 889 | 915 | static int ath11k_pci_power_up(struct ath11k_base *ab) |
| 890 | 916 | { |
| 891 | 917 | struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); |
| @@ -895,6 +921,11 @@ static int ath11k_pci_power_up(struct ath11k_base *ab) · 3 unmodified lines | ||
| 895 | 921 | clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); |
| 896 | 922 | ath11k_pci_sw_reset(ab_pci->ab, true); |
| 897 | 923 | |
| 924 | + /* Disable ASPM during firmware download due to problems switching | |
| 925 | + * to AMSS state. | |
| 926 | + */ | |
| 927 | + ath11k_pci_aspm_disable(ab_pci); | |
| 928 | + | |
| 898 | 929 | ret = ath11k_mhi_start(ab_pci); |
| 899 | 930 | if (ret) { |
| 900 | 931 | ath11k_err(ab, "failed to start mhi: %d\n", ret); |
| @@ -908,6 +939,9 @@ static void ath11k_pci_power_down(struct ath11k_base *ab) · 7 unmodified lines | ||
| 908 | 939 | { |
| 909 | 940 | struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); |
| 910 | 941 | |
| 942 | + /* restore aspm in case firmware bootup fails */ | |
| 943 | + ath11k_pci_aspm_restore(ab_pci); | |
| 944 | + | |
| 911 | 945 | ath11k_pci_force_wake(ab_pci->ab); |
| 912 | 946 | ath11k_mhi_stop(ab_pci); |
| 913 | 947 | clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); |
| @@ -965,6 +999,8 @@ static int ath11k_pci_start(struct ath11k_base *ab) · 51 unmodified lines | ||
| 965 | 999 | |
| 966 | 1000 | set_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); |
| 967 | 1001 | |
| 1002 | + ath11k_pci_aspm_restore(ab_pci); | |
| 1003 | + | |
| 968 | 1004 | ath11k_pci_ce_irqs_enable(ab); |
| 969 | 1005 | ath11k_ce_rx_post_buf(ab); |
| 970 | 1006 | |
| @@ -63,6 +63,7 @@ struct ath11k_msi_config { · 62 unmodified lines | ||
| 63 | 63 | enum ath11k_pci_flags { |
| 64 | 64 | ATH11K_PCI_FLAG_INIT_DONE, |
| 65 | 65 | ATH11K_PCI_FLAG_IS_MSI_64, |
| 66 | + ATH11K_PCI_ASPM_RESTORE, | |
| 66 | 67 | }; |
| 67 | 68 | |
| 68 | 69 | struct ath11k_pci { |
| @@ -80,6 +81,7 @@ struct ath11k_pci { · 11 unmodified lines | ||
| 80 | 81 | |
| 81 | 82 | /* enum ath11k_pci_flags */ |
| 82 | 83 | unsigned long flags; |
| 84 | + u16 link_ctl; | |
| 83 | 85 | }; |
| 84 | 86 | |
| 85 | 87 | static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab) |
| @@ -76,6 +76,23 @@ struct ath11k_peer *ath11k_peer_find_by_id(struct ath11k_base *ab, · 75 unmodified lines | ||
| 76 | 76 | return NULL; |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | +struct ath11k_peer *ath11k_peer_find_by_vdev_id(struct ath11k_base *ab, | |
| 80 | + int vdev_id) | |
| 81 | +{ | |
| 82 | + struct ath11k_peer *peer; | |
| 83 | + | |
| 84 | + spin_lock_bh(&ab->base_lock); | |
| 85 | + | |
| 86 | + list_for_each_entry(peer, &ab->peers, list) { | |
| 87 | + if (vdev_id == peer->vdev_id) { | |
| 88 | + spin_unlock_bh(&ab->base_lock); | |
| 89 | + return peer; | |
| 90 | + } | |
| 91 | + } | |
| 92 | + spin_unlock_bh(&ab->base_lock); | |
| 93 | + return NULL; | |
| 94 | +} | |
| 95 | + | |
| 79 | 96 | void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id) |
| 80 | 97 | { |
| 81 | 98 | struct ath11k_peer *peer; |
| @@ -43,5 +43,7 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, · 42 unmodified lines | ||
| 43 | 43 | struct ieee80211_sta *sta, struct peer_create_params *param); |
| 44 | 44 | int ath11k_wait_for_peer_delete_done(struct ath11k *ar, u32 vdev_id, |
| 45 | 45 | const u8 *addr); |
| 46 | +struct ath11k_peer *ath11k_peer_find_by_vdev_id(struct ath11k_base *ab, | |
| 47 | + int vdev_id); | |
| 46 | 48 | |
| 47 | 49 | #endif /* _PEER_H_ */ |
| @@ -1660,6 +1660,7 @@ static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab) · 1659 unmodified lines | ||
| 1660 | 1660 | struct qmi_wlanfw_respond_mem_resp_msg_v01 resp; |
| 1661 | 1661 | struct qmi_txn txn = {}; |
| 1662 | 1662 | int ret = 0, i; |
| 1663 | + bool delayed; | |
| 1663 | 1664 | |
| 1664 | 1665 | req = kzalloc(sizeof(*req), GFP_KERNEL); |
| 1665 | 1666 | if (!req) |
| @@ -1672,11 +1673,13 @@ static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab) · 6 unmodified lines | ||
| 1672 | 1673 | * failure to FW and FW will then request mulitple blocks of small |
| 1673 | 1674 | * chunk size memory. |
| 1674 | 1675 | */ |
| 1675 | − if (!ab->bus_params.fixed_mem_region && ab->qmi.mem_seg_count <= 2) { | |
| 1676 | + if (!ab->bus_params.fixed_mem_region && ab->qmi.target_mem_delayed) { | |
| 1677 | + delayed = true; | |
| 1676 | 1678 | ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi delays mem_request %d\n", |
| 1677 | 1679 | ab->qmi.mem_seg_count); |
| 1678 | 1680 | memset(req, 0, sizeof(*req)); |
| 1679 | 1681 | } else { |
| 1682 | + delayed = false; | |
| 1680 | 1683 | req->mem_seg_len = ab->qmi.mem_seg_count; |
| 1681 | 1684 | |
| 1682 | 1685 | for (i = 0; i < req->mem_seg_len ; i++) { |
| @@ -1708,6 +1711,12 @@ static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab) · 25 unmodified lines | ||
| 1708 | 1711 | } |
| 1709 | 1712 | |
| 1710 | 1713 | if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { |
| 1714 | + /* the error response is expected when | |
| 1715 | + * target_mem_delayed is true. | |
| 1716 | + */ | |
| 1717 | + if (delayed && resp.resp.error == 0) | |
| 1718 | + goto out; | |
| 1719 | + | |
| 1711 | 1720 | ath11k_warn(ab, "Respond mem req failed, result: %d, err: %d\n", |
| 1712 | 1721 | resp.resp.result, resp.resp.error); |
| 1713 | 1722 | ret = -EINVAL; |
| @@ -1742,6 +1751,8 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab) · 28 unmodified lines | ||
| 1742 | 1751 | int i; |
| 1743 | 1752 | struct target_mem_chunk *chunk; |
| 1744 | 1753 | |
| 1754 | + ab->qmi.target_mem_delayed = false; | |
| 1755 | + | |
| 1745 | 1756 | for (i = 0; i < ab->qmi.mem_seg_count; i++) { |
| 1746 | 1757 | chunk = &ab->qmi.target_mem[i]; |
| 1747 | 1758 | chunk->vaddr = dma_alloc_coherent(ab->dev, |
| @@ -1749,6 +1760,15 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab) · 1 unmodified line | ||
| 1749 | 1760 | &chunk->paddr, |
| 1750 | 1761 | GFP_KERNEL); |
| 1751 | 1762 | if (!chunk->vaddr) { |
| 1763 | + if (ab->qmi.mem_seg_count <= 2) { | |
| 1764 | + ath11k_dbg(ab, ATH11K_DBG_QMI, | |
| 1765 | + "qmi dma allocation failed (%d B type %u), will try later with small size\n", | |
| 1766 | + chunk->size, | |
| 1767 | + chunk->type); | |
| 1768 | + ath11k_qmi_free_target_mem_chunk(ab); | |
| 1769 | + ab->qmi.target_mem_delayed = true; | |
| 1770 | + return 0; | |
| 1771 | + } | |
| 1752 | 1772 | ath11k_err(ab, "failed to alloc memory, size: 0x%x, type: %u\n", |
| 1753 | 1773 | chunk->size, |
| 1754 | 1774 | chunk->type); |
| @@ -2517,7 +2537,7 @@ static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl, · 762 unmodified lines | ||
| 2517 | 2537 | ret); |
| 2518 | 2538 | return; |
| 2519 | 2539 | } |
| 2520 | − } else if (msg->mem_seg_len > 2) { | |
| 2540 | + } else { | |
| 2521 | 2541 | ret = ath11k_qmi_alloc_target_mem_chunk(ab); |
| 2522 | 2542 | if (ret) { |
| 2523 | 2543 | ath11k_warn(ab, "qmi failed to alloc target memory: %d\n", |
| @@ -125,6 +125,7 @@ struct ath11k_qmi { · 124 unmodified lines | ||
| 125 | 125 | struct target_mem_chunk target_mem[ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01]; |
| 126 | 126 | u32 mem_seg_count; |
| 127 | 127 | u32 target_mem_mode; |
| 128 | + bool target_mem_delayed; | |
| 128 | 129 | u8 cal_done; |
| 129 | 130 | struct target_info target; |
| 130 | 131 | struct m3_mem_region m3_mem; |
| @@ -3460,6 +3460,9 @@ int ath11k_wmi_set_hw_mode(struct ath11k_base *ab, · 3459 unmodified lines | ||
| 3460 | 3460 | len = sizeof(*cmd); |
| 3461 | 3461 | |
| 3462 | 3462 | skb = ath11k_wmi_alloc_skb(wmi_ab, len); |
| 3463 | + if (!skb) | |
| 3464 | + return -ENOMEM; | |
| 3465 | + | |
| 3463 | 3466 | cmd = (struct wmi_pdev_set_hw_mode_cmd_param *)skb->data; |
| 3464 | 3467 | |
| 3465 | 3468 | cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_SET_HW_MODE_CMD) | |
| @@ -2,6 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | config WIL6210 |
| 3 | 3 | tristate "Wilocity 60g WiFi card wil6210 support" |
| 4 | 4 | select WANT_DEV_COREDUMP |
| 5 | + select CRC32 | |
| 5 | 6 | depends on CFG80211 |
| 6 | 7 | depends on PCI |
| 7 | 8 | default n |
| @@ -40,9 +40,9 @@ static const struct ieee80211_iface_limit if_limits[] = { · 39 unmodified lines | ||
| 40 | 40 | .types = BIT(NL80211_IFTYPE_ADHOC) |
| 41 | 41 | }, { |
| 42 | 42 | .max = 16, |
| 43 | − .types = BIT(NL80211_IFTYPE_AP) | | |
| 43 | + .types = BIT(NL80211_IFTYPE_AP) | |
| 44 | 44 | #ifdef CONFIG_MAC80211_MESH |
| 45 | − BIT(NL80211_IFTYPE_MESH_POINT) | |
| 45 | + | BIT(NL80211_IFTYPE_MESH_POINT) | |
| 46 | 46 | #endif |
| 47 | 47 | }, { |
| 48 | 48 | .max = MT7915_MAX_INTERFACES, |
| @@ -157,10 +157,14 @@ static void mt76s_net_worker(struct mt76_worker *w) · 156 unmodified lines | ||
| 157 | 157 | |
| 158 | 158 | static int mt76s_process_tx_queue(struct mt76_dev *dev, struct mt76_queue *q) |
| 159 | 159 | { |
| 160 | − bool wake, mcu = q == dev->q_mcu[MT_MCUQ_WM]; | |
| 161 | 160 | struct mt76_queue_entry entry; |
| 162 | 161 | int nframes = 0; |
| 162 | + bool mcu; | |
| 163 | 163 | |
| 164 | + if (!q) | |
| 165 | + return 0; | |
| 166 | + | |
| 167 | + mcu = q == dev->q_mcu[MT_MCUQ_WM]; | |
| 164 | 168 | while (q->queued > 0) { |
| 165 | 169 | if (!q->entry[q->tail].done) |
| 166 | 170 | break; |
| @@ -177,21 +181,12 @@ static int mt76s_process_tx_queue(struct mt76_dev *dev, struct mt76_queue *q) · 10 unmodified lines | ||
| 177 | 181 | nframes++; |
| 178 | 182 | } |
| 179 | 183 | |
| 180 | − wake = q->stopped && q->queued < q->ndesc - 8; | |
| 181 | − if (wake) | |
| 182 | − q->stopped = false; | |
| 183 | − | |
| 184 | 184 | if (!q->queued) |
| 185 | 185 | wake_up(&dev->tx_wait); |
| 186 | 186 | |
| 187 | − if (mcu) | |
| 188 | − goto out; | |
| 189 | − | |
| 190 | − mt76_txq_schedule(&dev->phy, q->qid); | |
| 187 | + if (!mcu) | |
| 188 | + mt76_txq_schedule(&dev->phy, q->qid); | |
| 191 | 189 | |
| 192 | − if (wake) | |
| 193 | − ieee80211_wake_queue(dev->hw, q->qid); | |
| 194 | −out: | |
| 195 | 190 | return nframes; |
| 196 | 191 | } |
| 197 | 192 | |
| @@ -811,11 +811,12 @@ static void mt76u_status_worker(struct mt76_worker *w) · 810 unmodified lines | ||
| 811 | 811 | struct mt76_dev *dev = container_of(usb, struct mt76_dev, usb); |
| 812 | 812 | struct mt76_queue_entry entry; |
| 813 | 813 | struct mt76_queue *q; |
| 814 | − bool wake; | |
| 815 | 814 | int i; |
| 816 | 815 | |
| 817 | 816 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
| 818 | 817 | q = dev->phy.q_tx[i]; |
| 818 | + if (!q) | |
| 819 | + continue; | |
| 819 | 820 | |
| 820 | 821 | while (q->queued > 0) { |
| 821 | 822 | if (!q->entry[q->tail].done) |
| @@ -827,10 +828,6 @@ static void mt76u_status_worker(struct mt76_worker *w) · 5 unmodified lines | ||
| 827 | 828 | mt76_queue_tx_complete(dev, q, &entry); |
| 828 | 829 | } |
| 829 | 830 | |
| 830 | − wake = q->stopped && q->queued < q->ndesc - 8; | |
| 831 | − if (wake) | |
| 832 | − q->stopped = false; | |
| 833 | − | |
| 834 | 831 | if (!q->queued) |
| 835 | 832 | wake_up(&dev->tx_wait); |
| 836 | 833 | |
| @@ -839,8 +836,6 @@ static void mt76u_status_worker(struct mt76_worker *w) · 2 unmodified lines | ||
| 839 | 836 | if (dev->drv->tx_status_data && |
| 840 | 837 | !test_and_set_bit(MT76_READING_STATS, &dev->phy.state)) |
| 841 | 838 | queue_work(dev->wq, &dev->usb.stat_work); |
| 842 | − if (wake) | |
| 843 | − ieee80211_wake_queue(dev->hw, i); | |
| 844 | 839 | } |
| 845 | 840 | } |
| 846 | 841 | |
| @@ -78,7 +78,6 @@ static void rtl_fw_do_work(const struct firmware *firmware, void *context, · 77 unmodified lines | ||
| 78 | 78 | |
| 79 | 79 | rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, |
| 80 | 80 | "Firmware callback routine entered!\n"); |
| 81 | − complete(&rtlpriv->firmware_loading_complete); | |
| 82 | 81 | if (!firmware) { |
| 83 | 82 | if (rtlpriv->cfg->alt_fw_name) { |
| 84 | 83 | err = request_firmware(&firmware, |
| @@ -91,13 +90,13 @@ static void rtl_fw_do_work(const struct firmware *firmware, void *context, · 6 unmodified lines | ||
| 91 | 90 | } |
| 92 | 91 | pr_err("Selected firmware is not available\n"); |
| 93 | 92 | rtlpriv->max_fw_size = 0; |
| 94 | − return; | |
| 93 | + goto exit; | |
| 95 | 94 | } |
| 96 | 95 | found_alt: |
| 97 | 96 | if (firmware->size > rtlpriv->max_fw_size) { |
| 98 | 97 | pr_err("Firmware is too big!\n"); |
| 99 | 98 | release_firmware(firmware); |
| 100 | − return; | |
| 99 | + goto exit; | |
| 101 | 100 | } |
| 102 | 101 | if (!is_wow) { |
| 103 | 102 | memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, |
| @@ -109,6 +108,9 @@ found_alt: · 5 unmodified lines | ||
| 109 | 108 | rtlpriv->rtlhal.wowlan_fwsize = firmware->size; |
| 110 | 109 | } |
| 111 | 110 | release_firmware(firmware); |
| 111 | + | |
| 112 | +exit: | |
| 113 | + complete(&rtlpriv->firmware_loading_complete); | |
| 112 | 114 | } |
| 113 | 115 | |
| 114 | 116 | void rtl_fw_cb(const struct firmware *firmware, void *context) |
| @@ -179,7 +179,7 @@ int nvme_reset_ctrl(struct nvme_ctrl *ctrl) · 178 unmodified lines | ||
| 179 | 179 | } |
| 180 | 180 | EXPORT_SYMBOL_GPL(nvme_reset_ctrl); |
| 181 | 181 | |
| 182 | −int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl) | |
| 182 | +static int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl) | |
| 183 | 183 | { |
| 184 | 184 | int ret; |
| 185 | 185 | |
| @@ -192,7 +192,6 @@ int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl) · 6 unmodified lines | ||
| 192 | 192 | |
| 193 | 193 | return ret; |
| 194 | 194 | } |
| 195 | −EXPORT_SYMBOL_GPL(nvme_reset_ctrl_sync); | |
| 196 | 195 | |
| 197 | 196 | static void nvme_do_delete_ctrl(struct nvme_ctrl *ctrl) |
| 198 | 197 | { |
| @@ -331,7 +330,7 @@ static inline void nvme_end_req(struct request *req) · 132 unmodified lines | ||
| 331 | 330 | req->__sector = nvme_lba_to_sect(req->q->queuedata, |
| 332 | 331 | le64_to_cpu(nvme_req(req)->result.u64)); |
| 333 | 332 | |
| 334 | − nvme_trace_bio_complete(req, status); | |
| 333 | + nvme_trace_bio_complete(req); | |
| 335 | 334 | blk_mq_end_request(req, status); |
| 336 | 335 | } |
| 337 | 336 | |
| @@ -578,7 +577,7 @@ struct request *nvme_alloc_request(struct request_queue *q, · 240 unmodified lines | ||
| 578 | 577 | } |
| 579 | 578 | EXPORT_SYMBOL_GPL(nvme_alloc_request); |
| 580 | 579 | |
| 581 | −struct request *nvme_alloc_request_qid(struct request_queue *q, | |
| 580 | +static struct request *nvme_alloc_request_qid(struct request_queue *q, | |
| 582 | 581 | struct nvme_command *cmd, blk_mq_req_flags_t flags, int qid) |
| 583 | 582 | { |
| 584 | 583 | struct request *req; |
| @@ -589,7 +588,6 @@ struct request *nvme_alloc_request_qid(struct request_queue *q, · 4 unmodified lines | ||
| 589 | 588 | nvme_init_request(req, cmd); |
| 590 | 589 | return req; |
| 591 | 590 | } |
| 592 | −EXPORT_SYMBOL_GPL(nvme_alloc_request_qid); | |
| 593 | 591 | |
| 594 | 592 | static int nvme_toggle_streams(struct nvme_ctrl *ctrl, bool enable) |
| 595 | 593 | { |
| @@ -2858,6 +2856,11 @@ static const struct attribute_group *nvme_subsys_attrs_groups[] = { · 2262 unmodified lines | ||
| 2858 | 2856 | NULL, |
| 2859 | 2857 | }; |
| 2860 | 2858 | |
| 2859 | +static inline bool nvme_discovery_ctrl(struct nvme_ctrl *ctrl) | |
| 2860 | +{ | |
| 2861 | + return ctrl->opts && ctrl->opts->discovery_nqn; | |
| 2862 | +} | |
| 2863 | + | |
| 2861 | 2864 | static bool nvme_validate_cntlid(struct nvme_subsystem *subsys, |
| 2862 | 2865 | struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) |
| 2863 | 2866 | { |
| @@ -2877,7 +2880,7 @@ static bool nvme_validate_cntlid(struct nvme_subsystem *subsys, · 13 unmodified lines | ||
| 2877 | 2880 | } |
| 2878 | 2881 | |
| 2879 | 2882 | if ((id->cmic & NVME_CTRL_CMIC_MULTI_CTRL) || |
| 2880 | − (ctrl->opts && ctrl->opts->discovery_nqn)) | |
| 2883 | + nvme_discovery_ctrl(ctrl)) | |
| 2881 | 2884 | continue; |
| 2882 | 2885 | |
| 2883 | 2886 | dev_err(ctrl->device, |
| @@ -3146,7 +3149,7 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) · 262 unmodified lines | ||
| 3146 | 3149 | goto out_free; |
| 3147 | 3150 | } |
| 3148 | 3151 | |
| 3149 | − if (!ctrl->opts->discovery_nqn && !ctrl->kas) { | |
| 3152 | + if (!nvme_discovery_ctrl(ctrl) && !ctrl->kas) { | |
| 3150 | 3153 | dev_err(ctrl->device, |
| 3151 | 3154 | "keep-alive support is mandatory for fabrics\n"); |
| 3152 | 3155 | ret = -EINVAL; |
| @@ -3186,7 +3189,7 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) · 33 unmodified lines | ||
| 3186 | 3189 | if (ret < 0) |
| 3187 | 3190 | return ret; |
| 3188 | 3191 | |
| 3189 | − if (!ctrl->identified) { | |
| 3192 | + if (!ctrl->identified && !nvme_discovery_ctrl(ctrl)) { | |
| 3190 | 3193 | ret = nvme_hwmon_init(ctrl); |
| 3191 | 3194 | if (ret < 0) |
| 3192 | 3195 | return ret; |
| @@ -166,6 +166,7 @@ struct nvme_fc_ctrl { · 165 unmodified lines | ||
| 166 | 166 | struct blk_mq_tag_set admin_tag_set; |
| 167 | 167 | struct blk_mq_tag_set tag_set; |
| 168 | 168 | |
| 169 | + struct work_struct ioerr_work; | |
| 169 | 170 | struct delayed_work connect_work; |
| 170 | 171 | |
| 171 | 172 | struct kref ref; |
| @@ -1888,6 +1889,15 @@ __nvme_fc_fcpop_chk_teardowns(struct nvme_fc_ctrl *ctrl, · 1716 unmodified lines | ||
| 1888 | 1889 | } |
| 1889 | 1890 | } |
| 1890 | 1891 | |
| 1892 | +static void | |
| 1893 | +nvme_fc_ctrl_ioerr_work(struct work_struct *work) | |
| 1894 | +{ | |
| 1895 | + struct nvme_fc_ctrl *ctrl = | |
| 1896 | + container_of(work, struct nvme_fc_ctrl, ioerr_work); | |
| 1897 | + | |
| 1898 | + nvme_fc_error_recovery(ctrl, "transport detected io error"); | |
| 1899 | +} | |
| 1900 | + | |
| 1891 | 1901 | static void |
| 1892 | 1902 | nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) |
| 1893 | 1903 | { |
| @@ -2046,7 +2056,7 @@ done: · 152 unmodified lines | ||
| 2046 | 2056 | |
| 2047 | 2057 | check_error: |
| 2048 | 2058 | if (terminate_assoc) |
| 2049 | − nvme_fc_error_recovery(ctrl, "transport detected io error"); | |
| 2059 | + queue_work(nvme_reset_wq, &ctrl->ioerr_work); | |
| 2050 | 2060 | } |
| 2051 | 2061 | |
| 2052 | 2062 | static int |
| @@ -3233,6 +3243,7 @@ nvme_fc_delete_ctrl(struct nvme_ctrl *nctrl) · 1180 unmodified lines | ||
| 3233 | 3243 | { |
| 3234 | 3244 | struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl); |
| 3235 | 3245 | |
| 3246 | + cancel_work_sync(&ctrl->ioerr_work); | |
| 3236 | 3247 | cancel_delayed_work_sync(&ctrl->connect_work); |
| 3237 | 3248 | /* |
| 3238 | 3249 | * kill the association on the link side. this will block |
| @@ -3449,6 +3460,7 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, · 210 unmodified lines | ||
| 3449 | 3460 | |
| 3450 | 3461 | INIT_WORK(&ctrl->ctrl.reset_work, nvme_fc_reset_ctrl_work); |
| 3451 | 3462 | INIT_DELAYED_WORK(&ctrl->connect_work, nvme_fc_connect_ctrl_work); |
| 3463 | + INIT_WORK(&ctrl->ioerr_work, nvme_fc_ctrl_ioerr_work); | |
| 3452 | 3464 | spin_lock_init(&ctrl->lock); |
| 3453 | 3465 | |
| 3454 | 3466 | /* io queue count */ |
| @@ -3540,6 +3552,7 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, · 85 unmodified lines | ||
| 3540 | 3552 | |
| 3541 | 3553 | fail_ctrl: |
| 3542 | 3554 | nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_DELETING); |
| 3555 | + cancel_work_sync(&ctrl->ioerr_work); | |
| 3543 | 3556 | cancel_work_sync(&ctrl->ctrl.reset_work); |
| 3544 | 3557 | cancel_delayed_work_sync(&ctrl->connect_work); |
| 3545 | 3558 | |
| @@ -610,8 +610,6 @@ void nvme_start_freeze(struct nvme_ctrl *ctrl); · 609 unmodified lines | ||
| 610 | 610 | #define NVME_QID_ANY -1 |
| 611 | 611 | struct request *nvme_alloc_request(struct request_queue *q, |
| 612 | 612 | struct nvme_command *cmd, blk_mq_req_flags_t flags); |
| 613 | −struct request *nvme_alloc_request_qid(struct request_queue *q, | |
| 614 | − struct nvme_command *cmd, blk_mq_req_flags_t flags, int qid); | |
| 615 | 613 | void nvme_cleanup_cmd(struct request *req); |
| 616 | 614 | blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req, |
| 617 | 615 | struct nvme_command *cmd); |
| @@ -630,7 +628,6 @@ int nvme_get_features(struct nvme_ctrl *dev, unsigned int fid, · 12 unmodified lines | ||
| 630 | 628 | int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count); |
| 631 | 629 | void nvme_stop_keep_alive(struct nvme_ctrl *ctrl); |
| 632 | 630 | int nvme_reset_ctrl(struct nvme_ctrl *ctrl); |
| 633 | −int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl); | |
| 634 | 631 | int nvme_try_sched_reset(struct nvme_ctrl *ctrl); |
| 635 | 632 | int nvme_delete_ctrl(struct nvme_ctrl *ctrl); |
| 636 | 633 | |
| @@ -675,8 +672,7 @@ static inline void nvme_mpath_check_last_path(struct nvme_ns *ns) · 38 unmodified lines | ||
| 675 | 672 | kblockd_schedule_work(&head->requeue_work); |
| 676 | 673 | } |
| 677 | 674 | |
| 678 | −static inline void nvme_trace_bio_complete(struct request *req, | |
| 679 | − blk_status_t status) | |
| 675 | +static inline void nvme_trace_bio_complete(struct request *req) | |
| 680 | 676 | { |
| 681 | 677 | struct nvme_ns *ns = req->q->queuedata; |
| 682 | 678 | |
| @@ -731,8 +727,7 @@ static inline void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl) · 48 unmodified lines | ||
| 731 | 727 | static inline void nvme_mpath_check_last_path(struct nvme_ns *ns) |
| 732 | 728 | { |
| 733 | 729 | } |
| 734 | −static inline void nvme_trace_bio_complete(struct request *req, | |
| 735 | − blk_status_t status) | |
| 730 | +static inline void nvme_trace_bio_complete(struct request *req) | |
| 736 | 731 | { |
| 737 | 732 | } |
| 738 | 733 | static inline int nvme_mpath_init(struct nvme_ctrl *ctrl, |
| @@ -967,6 +967,7 @@ static inline struct blk_mq_tags *nvme_queue_tagset(struct nvme_queue *nvmeq) · 966 unmodified lines | ||
| 967 | 967 | static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx) |
| 968 | 968 | { |
| 969 | 969 | struct nvme_completion *cqe = &nvmeq->cqes[idx]; |
| 970 | + __u16 command_id = READ_ONCE(cqe->command_id); | |
| 970 | 971 | struct request *req; |
| 971 | 972 | |
| 972 | 973 | /* |
| @@ -975,17 +976,17 @@ static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx) · 2 unmodified lines | ||
| 975 | 976 | * aborts. We don't even bother to allocate a struct request |
| 976 | 977 | * for them but rather special case them here. |
| 977 | 978 | */ |
| 978 | − if (unlikely(nvme_is_aen_req(nvmeq->qid, cqe->command_id))) { | |
| 979 | + if (unlikely(nvme_is_aen_req(nvmeq->qid, command_id))) { | |
| 979 | 980 | nvme_complete_async_event(&nvmeq->dev->ctrl, |
| 980 | 981 | cqe->status, &cqe->result); |
| 981 | 982 | return; |
| 982 | 983 | } |
| 983 | 984 | |
| 984 | − req = blk_mq_tag_to_rq(nvme_queue_tagset(nvmeq), cqe->command_id); | |
| 985 | + req = blk_mq_tag_to_rq(nvme_queue_tagset(nvmeq), command_id); | |
| 985 | 986 | if (unlikely(!req)) { |
| 986 | 987 | dev_warn(nvmeq->dev->ctrl.device, |
| 987 | 988 | "invalid id %d completed on queue %d\n", |
| 988 | − cqe->command_id, le16_to_cpu(cqe->sq_id)); | |
| 989 | + command_id, le16_to_cpu(cqe->sq_id)); | |
| 989 | 990 | return; |
| 990 | 991 | } |
| 991 | 992 | |
| @@ -3196,7 +3197,8 @@ static const struct pci_device_id nvme_id_table[] = { · 2204 unmodified lines | ||
| 3196 | 3197 | { PCI_DEVICE(0x144d, 0xa821), /* Samsung PM1725 */ |
| 3197 | 3198 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, |
| 3198 | 3199 | { PCI_DEVICE(0x144d, 0xa822), /* Samsung PM1725a */ |
| 3199 | − .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, | |
| 3200 | + .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | | |
| 3201 | + NVME_QUIRK_IGNORE_DEV_SUBNQN, }, | |
| 3200 | 3202 | { PCI_DEVICE(0x1d1d, 0x1f1f), /* LighNVM qemu device */ |
| 3201 | 3203 | .driver_data = NVME_QUIRK_LIGHTNVM, }, |
| 3202 | 3204 | { PCI_DEVICE(0x1d1d, 0x2807), /* CNEX WL */ |
| @@ -201,7 +201,7 @@ static inline size_t nvme_tcp_req_cur_offset(struct nvme_tcp_request *req) · 200 unmodified lines | ||
| 201 | 201 | |
| 202 | 202 | static inline size_t nvme_tcp_req_cur_length(struct nvme_tcp_request *req) |
| 203 | 203 | { |
| 204 | − return min_t(size_t, req->iter.bvec->bv_len - req->iter.iov_offset, | |
| 204 | + return min_t(size_t, iov_iter_single_seg_count(&req->iter), | |
| 205 | 205 | req->pdu_len - req->pdu_sent); |
| 206 | 206 | } |
| 207 | 207 | |
| @@ -262,6 +262,16 @@ static inline void nvme_tcp_advance_req(struct nvme_tcp_request *req, · 54 unmodified lines | ||
| 262 | 262 | } |
| 263 | 263 | } |
| 264 | 264 | |
| 265 | +static inline void nvme_tcp_send_all(struct nvme_tcp_queue *queue) | |
| 266 | +{ | |
| 267 | + int ret; | |
| 268 | + | |
| 269 | + /* drain the send queue as much as we can... */ | |
| 270 | + do { | |
| 271 | + ret = nvme_tcp_try_send(queue); | |
| 272 | + } while (ret > 0); | |
| 273 | +} | |
| 274 | + | |
| 265 | 275 | static inline void nvme_tcp_queue_request(struct nvme_tcp_request *req, |
| 266 | 276 | bool sync, bool last) |
| 267 | 277 | { |
| @@ -276,10 +286,10 @@ static inline void nvme_tcp_queue_request(struct nvme_tcp_request *req, · 8 unmodified lines | ||
| 276 | 286 | * directly, otherwise queue io_work. Also, only do that if we |
| 277 | 287 | * are on the same cpu, so we don't introduce contention. |
| 278 | 288 | */ |
| 279 | − if (queue->io_cpu == smp_processor_id() && | |
| 289 | + if (queue->io_cpu == __smp_processor_id() && | |
| 280 | 290 | sync && empty && mutex_trylock(&queue->send_mutex)) { |
| 281 | 291 | queue->more_requests = !last; |
| 282 | − nvme_tcp_try_send(queue); | |
| 292 | + nvme_tcp_send_all(queue); | |
| 283 | 293 | queue->more_requests = false; |
| 284 | 294 | mutex_unlock(&queue->send_mutex); |
| 285 | 295 | } else if (last) { |
| @@ -1501,7 +1501,8 @@ static ssize_t · 1500 unmodified lines | ||
| 1501 | 1501 | fcloop_set_cmd_drop(struct device *dev, struct device_attribute *attr, |
| 1502 | 1502 | const char *buf, size_t count) |
| 1503 | 1503 | { |
| 1504 | − int opcode, starting, amount; | |
| 1504 | + unsigned int opcode; | |
| 1505 | + int starting, amount; | |
| 1505 | 1506 | |
| 1506 | 1507 | if (sscanf(buf, "%x:%d:%d", &opcode, &starting, &amount) != 3) |
| 1507 | 1508 | return -EBADRQC; |
| @@ -1588,8 +1589,8 @@ out_destroy_class: · 80 unmodified lines | ||
| 1588 | 1589 | |
| 1589 | 1590 | static void __exit fcloop_exit(void) |
| 1590 | 1591 | { |
| 1591 | − struct fcloop_lport *lport; | |
| 1592 | − struct fcloop_nport *nport; | |
| 1592 | + struct fcloop_lport *lport = NULL; | |
| 1593 | + struct fcloop_nport *nport = NULL; | |
| 1593 | 1594 | struct fcloop_tport *tport; |
| 1594 | 1595 | struct fcloop_rport *rport; |
| 1595 | 1596 | unsigned long flags; |
| @@ -1220,6 +1220,14 @@ nvmet_rdma_find_get_device(struct rdma_cm_id *cm_id) · 1219 unmodified lines | ||
| 1220 | 1220 | } |
| 1221 | 1221 | ndev->inline_data_size = nport->inline_data_size; |
| 1222 | 1222 | ndev->inline_page_count = inline_page_count; |
| 1223 | + | |
| 1224 | + if (nport->pi_enable && !(cm_id->device->attrs.device_cap_flags & | |
| 1225 | + IB_DEVICE_INTEGRITY_HANDOVER)) { | |
| 1226 | + pr_warn("T10-PI is not supported by device %s. Disabling it\n", | |
| 1227 | + cm_id->device->name); | |
| 1228 | + nport->pi_enable = false; | |
| 1229 | + } | |
| 1230 | + | |
| 1223 | 1231 | ndev->device = cm_id->device; |
| 1224 | 1232 | kref_init(&ndev->ref); |
| 1225 | 1233 | |
| @@ -1641,6 +1649,16 @@ static void __nvmet_rdma_queue_disconnect(struct nvmet_rdma_queue *queue) · 415 unmodified lines | ||
| 1641 | 1649 | spin_lock_irqsave(&queue->state_lock, flags); |
| 1642 | 1650 | switch (queue->state) { |
| 1643 | 1651 | case NVMET_RDMA_Q_CONNECTING: |
| 1652 | + while (!list_empty(&queue->rsp_wait_list)) { | |
| 1653 | + struct nvmet_rdma_rsp *rsp; | |
| 1654 | + | |
| 1655 | + rsp = list_first_entry(&queue->rsp_wait_list, | |
| 1656 | + struct nvmet_rdma_rsp, | |
| 1657 | + wait_list); | |
| 1658 | + list_del(&rsp->wait_list); | |
| 1659 | + nvmet_rdma_put_rsp(rsp); | |
| 1660 | + } | |
| 1661 | + fallthrough; | |
| 1644 | 1662 | case NVMET_RDMA_Q_LIVE: |
| 1645 | 1663 | queue->state = NVMET_RDMA_Q_DISCONNECTING; |
| 1646 | 1664 | disconnect = true; |
| @@ -1845,14 +1863,6 @@ static int nvmet_rdma_enable_port(struct nvmet_rdma_port *port) · 198 unmodified lines | ||
| 1845 | 1863 | goto out_destroy_id; |
| 1846 | 1864 | } |
| 1847 | 1865 | |
| 1848 | − if (port->nport->pi_enable && | |
| 1849 | − !(cm_id->device->attrs.device_cap_flags & | |
| 1850 | − IB_DEVICE_INTEGRITY_HANDOVER)) { | |
| 1851 | − pr_err("T10-PI is not supported for %pISpcs\n", addr); | |
| 1852 | − ret = -EINVAL; | |
| 1853 | − goto out_destroy_id; | |
| 1854 | − } | |
| 1855 | − | |
| 1856 | 1866 | port->cm_id = cm_id; |
| 1857 | 1867 | return 0; |
| 1858 | 1868 | |
| @@ -1092,7 +1092,7 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index) · 1091 unmodified lines | ||
| 1092 | 1092 | if (IS_ERR(opp_table->clk)) { |
| 1093 | 1093 | ret = PTR_ERR(opp_table->clk); |
| 1094 | 1094 | if (ret == -EPROBE_DEFER) |
| 1095 | − goto err; | |
| 1095 | + goto remove_opp_dev; | |
| 1096 | 1096 | |
| 1097 | 1097 | dev_dbg(dev, "%s: Couldn't find clock: %d\n", __func__, ret); |
| 1098 | 1098 | } |
| @@ -1101,7 +1101,7 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index) · 2 unmodified lines | ||
| 1101 | 1101 | ret = dev_pm_opp_of_find_icc_paths(dev, opp_table); |
| 1102 | 1102 | if (ret) { |
| 1103 | 1103 | if (ret == -EPROBE_DEFER) |
| 1104 | − goto err; | |
| 1104 | + goto put_clk; | |
| 1105 | 1105 | |
| 1106 | 1106 | dev_warn(dev, "%s: Error finding interconnect paths: %d\n", |
| 1107 | 1107 | __func__, ret); |
| @@ -1113,6 +1113,11 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index) · 5 unmodified lines | ||
| 1113 | 1113 | |
| 1114 | 1114 | return opp_table; |
| 1115 | 1115 | |
| 1116 | +put_clk: | |
| 1117 | + if (!IS_ERR(opp_table->clk)) | |
| 1118 | + clk_put(opp_table->clk); | |
| 1119 | +remove_opp_dev: | |
| 1120 | + _remove_opp_dev(opp_dev, opp_table); | |
| 1116 | 1121 | err: |
| 1117 | 1122 | kfree(opp_table); |
| 1118 | 1123 | return ERR_PTR(ret); |
| @@ -726,11 +726,6 @@ static int armpmu_get_cpu_irq(struct arm_pmu *pmu, int cpu) · 725 unmodified lines | ||
| 726 | 726 | return per_cpu(hw_events->irq, cpu); |
| 727 | 727 | } |
| 728 | 728 | |
| 729 | −bool arm_pmu_irq_is_nmi(void) | |
| 730 | −{ | |
| 731 | − return has_nmi; | |
| 732 | −} | |
| 733 | − | |
| 734 | 729 | /* |
| 735 | 730 | * PMU hardware loses all context when a CPU goes offline. |
| 736 | 731 | * When a CPU is hotplugged back in, since some hardware registers are |
| @@ -64,6 +64,7 @@ config DP83640_PHY · 63 unmodified lines | ||
| 64 | 64 | depends on NETWORK_PHY_TIMESTAMPING |
| 65 | 65 | depends on PHYLIB |
| 66 | 66 | depends on PTP_1588_CLOCK |
| 67 | + select CRC32 | |
| 67 | 68 | help |
| 68 | 69 | Supports the DP83640 PHYTER with IEEE 1588 features. |
| 69 | 70 | |
| @@ -78,6 +79,7 @@ config DP83640_PHY · 8 unmodified lines | ||
| 78 | 79 | config PTP_1588_CLOCK_INES |
| 79 | 80 | tristate "ZHAW InES PTP time stamping IP core" |
| 80 | 81 | depends on NETWORK_PHY_TIMESTAMPING |
| 82 | + depends on HAS_IOMEM | |
| 81 | 83 | depends on PHYLIB |
| 82 | 84 | depends on PTP_1588_CLOCK |
| 83 | 85 | help |
| @@ -881,6 +881,7 @@ config REGULATOR_QCOM_RPM · 880 unmodified lines | ||
| 881 | 881 | config REGULATOR_QCOM_RPMH |
| 882 | 882 | tristate "Qualcomm Technologies, Inc. RPMh regulator driver" |
| 883 | 883 | depends on QCOM_RPMH || (QCOM_RPMH=n && COMPILE_TEST) |
| 884 | + depends on QCOM_COMMAND_DB || (QCOM_COMMAND_DB=n && COMPILE_TEST) | |
| 884 | 885 | help |
| 885 | 886 | This driver supports control of PMIC regulators via the RPMh hardware |
| 886 | 887 | block found on Qualcomm Technologies Inc. SoCs. RPMh regulator |
| @@ -15,6 +15,36 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/regulator/of_regulator.h> |
| 16 | 16 | #include <linux/slab.h> |
| 17 | 17 | |
| 18 | +/* Typical regulator startup times as per data sheet in uS */ | |
| 19 | +#define BD71847_BUCK1_STARTUP_TIME 144 | |
| 20 | +#define BD71847_BUCK2_STARTUP_TIME 162 | |
| 21 | +#define BD71847_BUCK3_STARTUP_TIME 162 | |
| 22 | +#define BD71847_BUCK4_STARTUP_TIME 240 | |
| 23 | +#define BD71847_BUCK5_STARTUP_TIME 270 | |
| 24 | +#define BD71847_BUCK6_STARTUP_TIME 200 | |
| 25 | +#define BD71847_LDO1_STARTUP_TIME 440 | |
| 26 | +#define BD71847_LDO2_STARTUP_TIME 370 | |
| 27 | +#define BD71847_LDO3_STARTUP_TIME 310 | |
| 28 | +#define BD71847_LDO4_STARTUP_TIME 400 | |
| 29 | +#define BD71847_LDO5_STARTUP_TIME 530 | |
| 30 | +#define BD71847_LDO6_STARTUP_TIME 400 | |
| 31 | + | |
| 32 | +#define BD71837_BUCK1_STARTUP_TIME 160 | |
| 33 | +#define BD71837_BUCK2_STARTUP_TIME 180 | |
| 34 | +#define BD71837_BUCK3_STARTUP_TIME 180 | |
| 35 | +#define BD71837_BUCK4_STARTUP_TIME 180 | |
| 36 | +#define BD71837_BUCK5_STARTUP_TIME 160 | |
| 37 | +#define BD71837_BUCK6_STARTUP_TIME 240 | |
| 38 | +#define BD71837_BUCK7_STARTUP_TIME 220 | |
| 39 | +#define BD71837_BUCK8_STARTUP_TIME 200 | |
| 40 | +#define BD71837_LDO1_STARTUP_TIME 440 | |
| 41 | +#define BD71837_LDO2_STARTUP_TIME 370 | |
| 42 | +#define BD71837_LDO3_STARTUP_TIME 310 | |
| 43 | +#define BD71837_LDO4_STARTUP_TIME 400 | |
| 44 | +#define BD71837_LDO5_STARTUP_TIME 310 | |
| 45 | +#define BD71837_LDO6_STARTUP_TIME 400 | |
| 46 | +#define BD71837_LDO7_STARTUP_TIME 530 | |
| 47 | + | |
| 18 | 48 | /* |
| 19 | 49 | * BD718(37/47/50) have two "enable control modes". ON/OFF can either be |
| 20 | 50 | * controlled by software - or by PMIC internal HW state machine. Whether |
| @@ -613,6 +643,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 592 unmodified lines | ||
| 613 | 643 | .vsel_mask = DVS_BUCK_RUN_MASK, |
| 614 | 644 | .enable_reg = BD718XX_REG_BUCK1_CTRL, |
| 615 | 645 | .enable_mask = BD718XX_BUCK_EN, |
| 646 | + .enable_time = BD71847_BUCK1_STARTUP_TIME, | |
| 616 | 647 | .owner = THIS_MODULE, |
| 617 | 648 | .of_parse_cb = buck_set_hw_dvs_levels, |
| 618 | 649 | }, |
| @@ -646,6 +677,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 27 unmodified lines | ||
| 646 | 677 | .vsel_mask = DVS_BUCK_RUN_MASK, |
| 647 | 678 | .enable_reg = BD718XX_REG_BUCK2_CTRL, |
| 648 | 679 | .enable_mask = BD718XX_BUCK_EN, |
| 680 | + .enable_time = BD71847_BUCK2_STARTUP_TIME, | |
| 649 | 681 | .owner = THIS_MODULE, |
| 650 | 682 | .of_parse_cb = buck_set_hw_dvs_levels, |
| 651 | 683 | }, |
| @@ -680,6 +712,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 28 unmodified lines | ||
| 680 | 712 | .linear_range_selectors = bd71847_buck3_volt_range_sel, |
| 681 | 713 | .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, |
| 682 | 714 | .enable_mask = BD718XX_BUCK_EN, |
| 715 | + .enable_time = BD71847_BUCK3_STARTUP_TIME, | |
| 683 | 716 | .owner = THIS_MODULE, |
| 684 | 717 | }, |
| 685 | 718 | .init = { |
| @@ -706,6 +739,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 20 unmodified lines | ||
| 706 | 739 | .vsel_range_mask = BD71847_BUCK4_RANGE_MASK, |
| 707 | 740 | .linear_range_selectors = bd71847_buck4_volt_range_sel, |
| 708 | 741 | .enable_mask = BD718XX_BUCK_EN, |
| 742 | + .enable_time = BD71847_BUCK4_STARTUP_TIME, | |
| 709 | 743 | .owner = THIS_MODULE, |
| 710 | 744 | }, |
| 711 | 745 | .init = { |
| @@ -727,6 +761,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 15 unmodified lines | ||
| 727 | 761 | .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK, |
| 728 | 762 | .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, |
| 729 | 763 | .enable_mask = BD718XX_BUCK_EN, |
| 764 | + .enable_time = BD71847_BUCK5_STARTUP_TIME, | |
| 730 | 765 | .owner = THIS_MODULE, |
| 731 | 766 | }, |
| 732 | 767 | .init = { |
| @@ -750,6 +785,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 17 unmodified lines | ||
| 750 | 785 | .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK, |
| 751 | 786 | .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, |
| 752 | 787 | .enable_mask = BD718XX_BUCK_EN, |
| 788 | + .enable_time = BD71847_BUCK6_STARTUP_TIME, | |
| 753 | 789 | .owner = THIS_MODULE, |
| 754 | 790 | }, |
| 755 | 791 | .init = { |
| @@ -775,6 +811,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 19 unmodified lines | ||
| 775 | 811 | .linear_range_selectors = bd718xx_ldo1_volt_range_sel, |
| 776 | 812 | .enable_reg = BD718XX_REG_LDO1_VOLT, |
| 777 | 813 | .enable_mask = BD718XX_LDO_EN, |
| 814 | + .enable_time = BD71847_LDO1_STARTUP_TIME, | |
| 778 | 815 | .owner = THIS_MODULE, |
| 779 | 816 | }, |
| 780 | 817 | .init = { |
| @@ -796,6 +833,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 15 unmodified lines | ||
| 796 | 833 | .n_voltages = ARRAY_SIZE(ldo_2_volts), |
| 797 | 834 | .enable_reg = BD718XX_REG_LDO2_VOLT, |
| 798 | 835 | .enable_mask = BD718XX_LDO_EN, |
| 836 | + .enable_time = BD71847_LDO2_STARTUP_TIME, | |
| 799 | 837 | .owner = THIS_MODULE, |
| 800 | 838 | }, |
| 801 | 839 | .init = { |
| @@ -818,6 +856,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 16 unmodified lines | ||
| 818 | 856 | .vsel_mask = BD718XX_LDO3_MASK, |
| 819 | 857 | .enable_reg = BD718XX_REG_LDO3_VOLT, |
| 820 | 858 | .enable_mask = BD718XX_LDO_EN, |
| 859 | + .enable_time = BD71847_LDO3_STARTUP_TIME, | |
| 821 | 860 | .owner = THIS_MODULE, |
| 822 | 861 | }, |
| 823 | 862 | .init = { |
| @@ -840,6 +879,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 16 unmodified lines | ||
| 840 | 879 | .vsel_mask = BD718XX_LDO4_MASK, |
| 841 | 880 | .enable_reg = BD718XX_REG_LDO4_VOLT, |
| 842 | 881 | .enable_mask = BD718XX_LDO_EN, |
| 882 | + .enable_time = BD71847_LDO4_STARTUP_TIME, | |
| 843 | 883 | .owner = THIS_MODULE, |
| 844 | 884 | }, |
| 845 | 885 | .init = { |
| @@ -865,6 +905,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 19 unmodified lines | ||
| 865 | 905 | .linear_range_selectors = bd71847_ldo5_volt_range_sel, |
| 866 | 906 | .enable_reg = BD718XX_REG_LDO5_VOLT, |
| 867 | 907 | .enable_mask = BD718XX_LDO_EN, |
| 908 | + .enable_time = BD71847_LDO5_STARTUP_TIME, | |
| 868 | 909 | .owner = THIS_MODULE, |
| 869 | 910 | }, |
| 870 | 911 | .init = { |
| @@ -889,6 +930,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 18 unmodified lines | ||
| 889 | 930 | .vsel_mask = BD718XX_LDO6_MASK, |
| 890 | 931 | .enable_reg = BD718XX_REG_LDO6_VOLT, |
| 891 | 932 | .enable_mask = BD718XX_LDO_EN, |
| 933 | + .enable_time = BD71847_LDO6_STARTUP_TIME, | |
| 892 | 934 | .owner = THIS_MODULE, |
| 893 | 935 | }, |
| 894 | 936 | .init = { |
| @@ -942,6 +984,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 47 unmodified lines | ||
| 942 | 984 | .vsel_mask = DVS_BUCK_RUN_MASK, |
| 943 | 985 | .enable_reg = BD718XX_REG_BUCK1_CTRL, |
| 944 | 986 | .enable_mask = BD718XX_BUCK_EN, |
| 987 | + .enable_time = BD71837_BUCK1_STARTUP_TIME, | |
| 945 | 988 | .owner = THIS_MODULE, |
| 946 | 989 | .of_parse_cb = buck_set_hw_dvs_levels, |
| 947 | 990 | }, |
| @@ -975,6 +1018,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 27 unmodified lines | ||
| 975 | 1018 | .vsel_mask = DVS_BUCK_RUN_MASK, |
| 976 | 1019 | .enable_reg = BD718XX_REG_BUCK2_CTRL, |
| 977 | 1020 | .enable_mask = BD718XX_BUCK_EN, |
| 1021 | + .enable_time = BD71837_BUCK2_STARTUP_TIME, | |
| 978 | 1022 | .owner = THIS_MODULE, |
| 979 | 1023 | .of_parse_cb = buck_set_hw_dvs_levels, |
| 980 | 1024 | }, |
| @@ -1005,6 +1049,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 24 unmodified lines | ||
| 1005 | 1049 | .vsel_mask = DVS_BUCK_RUN_MASK, |
| 1006 | 1050 | .enable_reg = BD71837_REG_BUCK3_CTRL, |
| 1007 | 1051 | .enable_mask = BD718XX_BUCK_EN, |
| 1052 | + .enable_time = BD71837_BUCK3_STARTUP_TIME, | |
| 1008 | 1053 | .owner = THIS_MODULE, |
| 1009 | 1054 | .of_parse_cb = buck_set_hw_dvs_levels, |
| 1010 | 1055 | }, |
| @@ -1033,6 +1078,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 22 unmodified lines | ||
| 1033 | 1078 | .vsel_mask = DVS_BUCK_RUN_MASK, |
| 1034 | 1079 | .enable_reg = BD71837_REG_BUCK4_CTRL, |
| 1035 | 1080 | .enable_mask = BD718XX_BUCK_EN, |
| 1081 | + .enable_time = BD71837_BUCK4_STARTUP_TIME, | |
| 1036 | 1082 | .owner = THIS_MODULE, |
| 1037 | 1083 | .of_parse_cb = buck_set_hw_dvs_levels, |
| 1038 | 1084 | }, |
| @@ -1065,6 +1111,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 26 unmodified lines | ||
| 1065 | 1111 | .linear_range_selectors = bd71837_buck5_volt_range_sel, |
| 1066 | 1112 | .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, |
| 1067 | 1113 | .enable_mask = BD718XX_BUCK_EN, |
| 1114 | + .enable_time = BD71837_BUCK5_STARTUP_TIME, | |
| 1068 | 1115 | .owner = THIS_MODULE, |
| 1069 | 1116 | }, |
| 1070 | 1117 | .init = { |
| @@ -1088,6 +1135,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 17 unmodified lines | ||
| 1088 | 1135 | .vsel_mask = BD71837_BUCK6_MASK, |
| 1089 | 1136 | .enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, |
| 1090 | 1137 | .enable_mask = BD718XX_BUCK_EN, |
| 1138 | + .enable_time = BD71837_BUCK6_STARTUP_TIME, | |
| 1091 | 1139 | .owner = THIS_MODULE, |
| 1092 | 1140 | }, |
| 1093 | 1141 | .init = { |
| @@ -1109,6 +1157,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 15 unmodified lines | ||
| 1109 | 1157 | .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK, |
| 1110 | 1158 | .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, |
| 1111 | 1159 | .enable_mask = BD718XX_BUCK_EN, |
| 1160 | + .enable_time = BD71837_BUCK7_STARTUP_TIME, | |
| 1112 | 1161 | .owner = THIS_MODULE, |
| 1113 | 1162 | }, |
| 1114 | 1163 | .init = { |
| @@ -1132,6 +1181,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 17 unmodified lines | ||
| 1132 | 1181 | .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK, |
| 1133 | 1182 | .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, |
| 1134 | 1183 | .enable_mask = BD718XX_BUCK_EN, |
| 1184 | + .enable_time = BD71837_BUCK8_STARTUP_TIME, | |
| 1135 | 1185 | .owner = THIS_MODULE, |
| 1136 | 1186 | }, |
| 1137 | 1187 | .init = { |
| @@ -1157,6 +1207,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 19 unmodified lines | ||
| 1157 | 1207 | .linear_range_selectors = bd718xx_ldo1_volt_range_sel, |
| 1158 | 1208 | .enable_reg = BD718XX_REG_LDO1_VOLT, |
| 1159 | 1209 | .enable_mask = BD718XX_LDO_EN, |
| 1210 | + .enable_time = BD71837_LDO1_STARTUP_TIME, | |
| 1160 | 1211 | .owner = THIS_MODULE, |
| 1161 | 1212 | }, |
| 1162 | 1213 | .init = { |
| @@ -1178,6 +1229,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 15 unmodified lines | ||
| 1178 | 1229 | .n_voltages = ARRAY_SIZE(ldo_2_volts), |
| 1179 | 1230 | .enable_reg = BD718XX_REG_LDO2_VOLT, |
| 1180 | 1231 | .enable_mask = BD718XX_LDO_EN, |
| 1232 | + .enable_time = BD71837_LDO2_STARTUP_TIME, | |
| 1181 | 1233 | .owner = THIS_MODULE, |
| 1182 | 1234 | }, |
| 1183 | 1235 | .init = { |
| @@ -1200,6 +1252,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 16 unmodified lines | ||
| 1200 | 1252 | .vsel_mask = BD718XX_LDO3_MASK, |
| 1201 | 1253 | .enable_reg = BD718XX_REG_LDO3_VOLT, |
| 1202 | 1254 | .enable_mask = BD718XX_LDO_EN, |
| 1255 | + .enable_time = BD71837_LDO3_STARTUP_TIME, | |
| 1203 | 1256 | .owner = THIS_MODULE, |
| 1204 | 1257 | }, |
| 1205 | 1258 | .init = { |
| @@ -1222,6 +1275,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 16 unmodified lines | ||
| 1222 | 1275 | .vsel_mask = BD718XX_LDO4_MASK, |
| 1223 | 1276 | .enable_reg = BD718XX_REG_LDO4_VOLT, |
| 1224 | 1277 | .enable_mask = BD718XX_LDO_EN, |
| 1278 | + .enable_time = BD71837_LDO4_STARTUP_TIME, | |
| 1225 | 1279 | .owner = THIS_MODULE, |
| 1226 | 1280 | }, |
| 1227 | 1281 | .init = { |
| @@ -1246,6 +1300,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 18 unmodified lines | ||
| 1246 | 1300 | .vsel_mask = BD71837_LDO5_MASK, |
| 1247 | 1301 | .enable_reg = BD718XX_REG_LDO5_VOLT, |
| 1248 | 1302 | .enable_mask = BD718XX_LDO_EN, |
| 1303 | + .enable_time = BD71837_LDO5_STARTUP_TIME, | |
| 1249 | 1304 | .owner = THIS_MODULE, |
| 1250 | 1305 | }, |
| 1251 | 1306 | .init = { |
| @@ -1272,6 +1327,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 20 unmodified lines | ||
| 1272 | 1327 | .vsel_mask = BD718XX_LDO6_MASK, |
| 1273 | 1328 | .enable_reg = BD718XX_REG_LDO6_VOLT, |
| 1274 | 1329 | .enable_mask = BD718XX_LDO_EN, |
| 1330 | + .enable_time = BD71837_LDO6_STARTUP_TIME, | |
| 1275 | 1331 | .owner = THIS_MODULE, |
| 1276 | 1332 | }, |
| 1277 | 1333 | .init = { |
| @@ -1296,6 +1352,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 18 unmodified lines | ||
| 1296 | 1352 | .vsel_mask = BD71837_LDO7_MASK, |
| 1297 | 1353 | .enable_reg = BD71837_REG_LDO7_VOLT, |
| 1298 | 1354 | .enable_mask = BD718XX_LDO_EN, |
| 1355 | + .enable_time = BD71837_LDO7_STARTUP_TIME, | |
| 1299 | 1356 | .owner = THIS_MODULE, |
| 1300 | 1357 | }, |
| 1301 | 1358 | .init = { |
| @@ -469,13 +469,17 @@ static int pf8x00_i2c_probe(struct i2c_client *client) · 468 unmodified lines | ||
| 469 | 469 | } |
| 470 | 470 | |
| 471 | 471 | static const struct of_device_id pf8x00_dt_ids[] = { |
| 472 | − { .compatible = "nxp,pf8x00",}, | |
| 472 | + { .compatible = "nxp,pf8100",}, | |
| 473 | + { .compatible = "nxp,pf8121a",}, | |
| 474 | + { .compatible = "nxp,pf8200",}, | |
| 473 | 475 | { } |
| 474 | 476 | }; |
| 475 | 477 | MODULE_DEVICE_TABLE(of, pf8x00_dt_ids); |
| 476 | 478 | |
| 477 | 479 | static const struct i2c_device_id pf8x00_i2c_id[] = { |
| 478 | − { "pf8x00", 0 }, | |
| 480 | + { "pf8100", 0 }, | |
| 481 | + { "pf8121a", 0 }, | |
| 482 | + { "pf8200", 0 }, | |
| 479 | 483 | {}, |
| 480 | 484 | }; |
| 481 | 485 | MODULE_DEVICE_TABLE(i2c, pf8x00_i2c_id); |
| @@ -726,7 +726,7 @@ static const struct rpmh_vreg_hw_data pmic5_ftsmps510 = { · 725 unmodified lines | ||
| 726 | 726 | static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = { |
| 727 | 727 | .regulator_type = VRM, |
| 728 | 728 | .ops = &rpmh_regulator_vrm_ops, |
| 729 | − .voltage_range = REGULATOR_LINEAR_RANGE(2800000, 0, 4, 1600), | |
| 729 | + .voltage_range = REGULATOR_LINEAR_RANGE(2800000, 0, 4, 16000), | |
| 730 | 730 | .n_voltages = 5, |
| 731 | 731 | .pmic_mode_map = pmic_mode_map_pmic5_smps, |
| 732 | 732 | .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode, |
| @@ -1079,7 +1079,8 @@ struct qeth_card *qeth_get_card_by_busid(char *bus_id); · 1078 unmodified lines | ||
| 1079 | 1079 | void qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads, |
| 1080 | 1080 | int clear_start_mask); |
| 1081 | 1081 | int qeth_threads_running(struct qeth_card *, unsigned long); |
| 1082 | −int qeth_set_offline(struct qeth_card *card, bool resetting); | |
| 1082 | +int qeth_set_offline(struct qeth_card *card, const struct qeth_discipline *disc, | |
| 1083 | + bool resetting); | |
| 1083 | 1084 | |
| 1084 | 1085 | int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, |
| 1085 | 1086 | int (*reply_cb) |
| @@ -5507,12 +5507,12 @@ out: · 5506 unmodified lines | ||
| 5507 | 5507 | return rc; |
| 5508 | 5508 | } |
| 5509 | 5509 | |
| 5510 | −static int qeth_set_online(struct qeth_card *card) | |
| 5510 | +static int qeth_set_online(struct qeth_card *card, | |
| 5511 | + const struct qeth_discipline *disc) | |
| 5511 | 5512 | { |
| 5512 | 5513 | bool carrier_ok; |
| 5513 | 5514 | int rc; |
| 5514 | 5515 | |
| 5515 | − mutex_lock(&card->discipline_mutex); | |
| 5516 | 5516 | mutex_lock(&card->conf_mutex); |
| 5517 | 5517 | QETH_CARD_TEXT(card, 2, "setonlin"); |
| 5518 | 5518 | |
| @@ -5529,7 +5529,7 @@ static int qeth_set_online(struct qeth_card *card) · 10 unmodified lines | ||
| 5529 | 5529 | /* no need for locking / error handling at this early stage: */ |
| 5530 | 5530 | qeth_set_real_num_tx_queues(card, qeth_tx_actual_queues(card)); |
| 5531 | 5531 | |
| 5532 | − rc = card->discipline->set_online(card, carrier_ok); | |
| 5532 | + rc = disc->set_online(card, carrier_ok); | |
| 5533 | 5533 | if (rc) |
| 5534 | 5534 | goto err_online; |
| 5535 | 5535 | |
| @@ -5537,7 +5537,6 @@ static int qeth_set_online(struct qeth_card *card) · 1 unmodified line | ||
| 5537 | 5537 | kobject_uevent(&card->gdev->dev.kobj, KOBJ_CHANGE); |
| 5538 | 5538 | |
| 5539 | 5539 | mutex_unlock(&card->conf_mutex); |
| 5540 | − mutex_unlock(&card->discipline_mutex); | |
| 5541 | 5540 | return 0; |
| 5542 | 5541 | |
| 5543 | 5542 | err_online: |
| @@ -5552,15 +5551,14 @@ err_hardsetup: · 8 unmodified lines | ||
| 5552 | 5551 | qdio_free(CARD_DDEV(card)); |
| 5553 | 5552 | |
| 5554 | 5553 | mutex_unlock(&card->conf_mutex); |
| 5555 | − mutex_unlock(&card->discipline_mutex); | |
| 5556 | 5554 | return rc; |
| 5557 | 5555 | } |
| 5558 | 5556 | |
| 5559 | −int qeth_set_offline(struct qeth_card *card, bool resetting) | |
| 5557 | +int qeth_set_offline(struct qeth_card *card, const struct qeth_discipline *disc, | |
| 5558 | + bool resetting) | |
| 5560 | 5559 | { |
| 5561 | 5560 | int rc, rc2, rc3; |
| 5562 | 5561 | |
| 5563 | − mutex_lock(&card->discipline_mutex); | |
| 5564 | 5562 | mutex_lock(&card->conf_mutex); |
| 5565 | 5563 | QETH_CARD_TEXT(card, 3, "setoffl"); |
| 5566 | 5564 | |
| @@ -5581,7 +5579,7 @@ int qeth_set_offline(struct qeth_card *card, bool resetting) · 14 unmodified lines | ||
| 5581 | 5579 | |
| 5582 | 5580 | cancel_work_sync(&card->rx_mode_work); |
| 5583 | 5581 | |
| 5584 | − card->discipline->set_offline(card); | |
| 5582 | + disc->set_offline(card); | |
| 5585 | 5583 | |
| 5586 | 5584 | qeth_qdio_clear_card(card, 0); |
| 5587 | 5585 | qeth_drain_output_queues(card); |
| @@ -5602,16 +5600,19 @@ int qeth_set_offline(struct qeth_card *card, bool resetting) · 14 unmodified lines | ||
| 5602 | 5600 | kobject_uevent(&card->gdev->dev.kobj, KOBJ_CHANGE); |
| 5603 | 5601 | |
| 5604 | 5602 | mutex_unlock(&card->conf_mutex); |
| 5605 | − mutex_unlock(&card->discipline_mutex); | |
| 5606 | 5603 | return 0; |
| 5607 | 5604 | } |
| 5608 | 5605 | EXPORT_SYMBOL_GPL(qeth_set_offline); |
| 5609 | 5606 | |
| 5610 | 5607 | static int qeth_do_reset(void *data) |
| 5611 | 5608 | { |
| 5609 | + const struct qeth_discipline *disc; | |
| 5612 | 5610 | struct qeth_card *card = data; |
| 5613 | 5611 | int rc; |
| 5614 | 5612 | |
| 5613 | + /* Lock-free, other users will block until we are done. */ | |
| 5614 | + disc = card->discipline; | |
| 5615 | + | |
| 5615 | 5616 | QETH_CARD_TEXT(card, 2, "recover1"); |
| 5616 | 5617 | if (!qeth_do_run_thread(card, QETH_RECOVER_THREAD)) |
| 5617 | 5618 | return 0; |
| @@ -5619,8 +5620,8 @@ static int qeth_do_reset(void *data) · 1 unmodified line | ||
| 5619 | 5620 | dev_warn(&card->gdev->dev, |
| 5620 | 5621 | "A recovery process has been started for the device\n"); |
| 5621 | 5622 | |
| 5622 | − qeth_set_offline(card, true); | |
| 5623 | − rc = qeth_set_online(card); | |
| 5623 | + qeth_set_offline(card, disc, true); | |
| 5624 | + rc = qeth_set_online(card, disc); | |
| 5624 | 5625 | if (!rc) { |
| 5625 | 5626 | dev_info(&card->gdev->dev, |
| 5626 | 5627 | "Device successfully recovered!\n"); |
| @@ -6584,6 +6585,7 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) · 957 unmodified lines | ||
| 6584 | 6585 | break; |
| 6585 | 6586 | default: |
| 6586 | 6587 | card->info.layer_enforced = true; |
| 6588 | + /* It's so early that we don't need the discipline_mutex yet. */ | |
| 6587 | 6589 | rc = qeth_core_load_discipline(card, enforced_disc); |
| 6588 | 6590 | if (rc) |
| 6589 | 6591 | goto err_load; |
| @@ -6616,10 +6618,12 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev) · 26 unmodified lines | ||
| 6616 | 6618 | |
| 6617 | 6619 | QETH_CARD_TEXT(card, 2, "removedv"); |
| 6618 | 6620 | |
| 6621 | + mutex_lock(&card->discipline_mutex); | |
| 6619 | 6622 | if (card->discipline) { |
| 6620 | 6623 | card->discipline->remove(gdev); |
| 6621 | 6624 | qeth_core_free_discipline(card); |
| 6622 | 6625 | } |
| 6626 | + mutex_unlock(&card->discipline_mutex); | |
| 6623 | 6627 | |
| 6624 | 6628 | qeth_free_qdio_queues(card); |
| 6625 | 6629 | |
| @@ -6634,6 +6638,7 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev) · 8 unmodified lines | ||
| 6634 | 6638 | int rc = 0; |
| 6635 | 6639 | enum qeth_discipline_id def_discipline; |
| 6636 | 6640 | |
| 6641 | + mutex_lock(&card->discipline_mutex); | |
| 6637 | 6642 | if (!card->discipline) { |
| 6638 | 6643 | def_discipline = IS_IQD(card) ? QETH_DISCIPLINE_LAYER3 : |
| 6639 | 6644 | QETH_DISCIPLINE_LAYER2; |
| @@ -6647,16 +6652,23 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev) · 7 unmodified lines | ||
| 6647 | 6652 | } |
| 6648 | 6653 | } |
| 6649 | 6654 | |
| 6650 | − rc = qeth_set_online(card); | |
| 6655 | + rc = qeth_set_online(card, card->discipline); | |
| 6656 | + | |
| 6651 | 6657 | err: |
| 6658 | + mutex_unlock(&card->discipline_mutex); | |
| 6652 | 6659 | return rc; |
| 6653 | 6660 | } |
| 6654 | 6661 | |
| 6655 | 6662 | static int qeth_core_set_offline(struct ccwgroup_device *gdev) |
| 6656 | 6663 | { |
| 6657 | 6664 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
| 6665 | + int rc; | |
| 6658 | 6666 | |
| 6659 | − return qeth_set_offline(card, false); | |
| 6667 | + mutex_lock(&card->discipline_mutex); | |
| 6668 | + rc = qeth_set_offline(card, card->discipline, false); | |
| 6669 | + mutex_unlock(&card->discipline_mutex); | |
| 6670 | + | |
| 6671 | + return rc; | |
| 6660 | 6672 | } |
| 6661 | 6673 | |
| 6662 | 6674 | static void qeth_core_shutdown(struct ccwgroup_device *gdev) |
| @@ -2208,7 +2208,7 @@ static void qeth_l2_remove_device(struct ccwgroup_device *gdev) · 2207 unmodified lines | ||
| 2208 | 2208 | wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); |
| 2209 | 2209 | |
| 2210 | 2210 | if (gdev->state == CCWGROUP_ONLINE) |
| 2211 | − qeth_set_offline(card, false); | |
| 2211 | + qeth_set_offline(card, card->discipline, false); | |
| 2212 | 2212 | |
| 2213 | 2213 | cancel_work_sync(&card->close_dev_work); |
| 2214 | 2214 | if (card->dev->reg_state == NETREG_REGISTERED) |
| @@ -1813,7 +1813,7 @@ static netdev_features_t qeth_l3_osa_features_check(struct sk_buff *skb, · 1812 unmodified lines | ||
| 1813 | 1813 | struct net_device *dev, |
| 1814 | 1814 | netdev_features_t features) |
| 1815 | 1815 | { |
| 1816 | − if (qeth_get_ip_version(skb) != 4) | |
| 1816 | + if (vlan_get_protocol(skb) != htons(ETH_P_IP)) | |
| 1817 | 1817 | features &= ~NETIF_F_HW_VLAN_CTAG_TX; |
| 1818 | 1818 | return qeth_features_check(skb, dev, features); |
| 1819 | 1819 | } |
| @@ -1971,7 +1971,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) · 151 unmodified lines | ||
| 1971 | 1971 | wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); |
| 1972 | 1972 | |
| 1973 | 1973 | if (cgdev->state == CCWGROUP_ONLINE) |
| 1974 | − qeth_set_offline(card, false); | |
| 1974 | + qeth_set_offline(card, card->discipline, false); | |
| 1975 | 1975 | |
| 1976 | 1976 | cancel_work_sync(&card->close_dev_work); |
| 1977 | 1977 | if (card->dev->reg_state == NETREG_REGISTERED) |
| @@ -4,6 +4,7 @@ config SCSI_CXGB4_ISCSI · 3 unmodified lines | ||
| 4 | 4 | depends on PCI && INET && (IPV6 || IPV6=n) |
| 5 | 5 | depends on THERMAL || !THERMAL |
| 6 | 6 | depends on ETHERNET |
| 7 | + depends on TLS || TLS=n | |
| 7 | 8 | select NET_VENDOR_CHELSIO |
| 8 | 9 | select CHELSIO_T4 |
| 9 | 10 | select CHELSIO_LIB |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/debugfs.h> |
| 15 | 15 | #include <linux/dmapool.h> |
| 16 | 16 | #include <linux/iopoll.h> |
| 17 | +#include <linux/irq.h> | |
| 17 | 18 | #include <linux/lcm.h> |
| 18 | 19 | #include <linux/libata.h> |
| 19 | 20 | #include <linux/mfd/syscon.h> |
| @@ -294,6 +295,7 @@ enum { · 274 unmodified lines | ||
| 294 | 295 | |
| 295 | 296 | struct hisi_sas_hw { |
| 296 | 297 | int (*hw_init)(struct hisi_hba *hisi_hba); |
| 298 | + int (*interrupt_preinit)(struct hisi_hba *hisi_hba); | |
| 297 | 299 | void (*setup_itct)(struct hisi_hba *hisi_hba, |
| 298 | 300 | struct hisi_sas_device *device); |
| 299 | 301 | int (*slot_index_alloc)(struct hisi_hba *hisi_hba, |
| @@ -393,6 +395,8 @@ struct hisi_hba { · 93 unmodified lines | ||
| 393 | 395 | u32 refclk_frequency_mhz; |
| 394 | 396 | u8 sas_addr[SAS_ADDR_SIZE]; |
| 395 | 397 | |
| 398 | + int *irq_map; /* v2 hw */ | |
| 399 | + | |
| 396 | 400 | int n_phy; |
| 397 | 401 | spinlock_t lock; |
| 398 | 402 | struct semaphore sem; |
| @@ -2614,6 +2614,13 @@ err_out: · 2613 unmodified lines | ||
| 2614 | 2614 | return NULL; |
| 2615 | 2615 | } |
| 2616 | 2616 | |
| 2617 | +static int hisi_sas_interrupt_preinit(struct hisi_hba *hisi_hba) | |
| 2618 | +{ | |
| 2619 | + if (hisi_hba->hw->interrupt_preinit) | |
| 2620 | + return hisi_hba->hw->interrupt_preinit(hisi_hba); | |
| 2621 | + return 0; | |
| 2622 | +} | |
| 2623 | + | |
| 2617 | 2624 | int hisi_sas_probe(struct platform_device *pdev, |
| 2618 | 2625 | const struct hisi_sas_hw *hw) |
| 2619 | 2626 | { |
| @@ -2671,6 +2678,10 @@ int hisi_sas_probe(struct platform_device *pdev, · 51 unmodified lines | ||
| 2671 | 2678 | sha->sas_port[i] = &hisi_hba->port[i].sas_port; |
| 2672 | 2679 | } |
| 2673 | 2680 | |
| 2681 | + rc = hisi_sas_interrupt_preinit(hisi_hba); | |
| 2682 | + if (rc) | |
| 2683 | + goto err_out_ha; | |
| 2684 | + | |
| 2674 | 2685 | rc = scsi_add_host(shost, &pdev->dev); |
| 2675 | 2686 | if (rc) |
| 2676 | 2687 | goto err_out_ha; |
| @@ -3302,6 +3302,28 @@ static irq_handler_t fatal_interrupts[HISI_SAS_FATAL_INT_NR] = { · 3301 unmodified lines | ||
| 3302 | 3302 | fatal_axi_int_v2_hw |
| 3303 | 3303 | }; |
| 3304 | 3304 | |
| 3305 | +#define CQ0_IRQ_INDEX (96) | |
| 3306 | + | |
| 3307 | +static int hisi_sas_v2_interrupt_preinit(struct hisi_hba *hisi_hba) | |
| 3308 | +{ | |
| 3309 | + struct platform_device *pdev = hisi_hba->platform_dev; | |
| 3310 | + struct Scsi_Host *shost = hisi_hba->shost; | |
| 3311 | + struct irq_affinity desc = { | |
| 3312 | + .pre_vectors = CQ0_IRQ_INDEX, | |
| 3313 | + .post_vectors = 16, | |
| 3314 | + }; | |
| 3315 | + int resv = desc.pre_vectors + desc.post_vectors, minvec = resv + 1, nvec; | |
| 3316 | + | |
| 3317 | + nvec = devm_platform_get_irqs_affinity(pdev, &desc, minvec, 128, | |
| 3318 | + &hisi_hba->irq_map); | |
| 3319 | + if (nvec < 0) | |
| 3320 | + return nvec; | |
| 3321 | + | |
| 3322 | + shost->nr_hw_queues = hisi_hba->cq_nvecs = nvec - resv; | |
| 3323 | + | |
| 3324 | + return 0; | |
| 3325 | +} | |
| 3326 | + | |
| 3305 | 3327 | /* |
| 3306 | 3328 | * There is a limitation in the hip06 chipset that we need |
| 3307 | 3329 | * to map in all mbigen interrupts, even if they are not used. |
| @@ -3310,14 +3332,11 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) · 2 unmodified lines | ||
| 3310 | 3332 | { |
| 3311 | 3333 | struct platform_device *pdev = hisi_hba->platform_dev; |
| 3312 | 3334 | struct device *dev = &pdev->dev; |
| 3313 | − int irq, rc = 0, irq_map[128]; | |
| 3335 | + int irq, rc = 0; | |
| 3314 | 3336 | int i, phy_no, fatal_no, queue_no; |
| 3315 | 3337 | |
| 3316 | − for (i = 0; i < 128; i++) | |
| 3317 | − irq_map[i] = platform_get_irq(pdev, i); | |
| 3318 | − | |
| 3319 | 3338 | for (i = 0; i < HISI_SAS_PHY_INT_NR; i++) { |
| 3320 | − irq = irq_map[i + 1]; /* Phy up/down is irq1 */ | |
| 3339 | + irq = hisi_hba->irq_map[i + 1]; /* Phy up/down is irq1 */ | |
| 3321 | 3340 | rc = devm_request_irq(dev, irq, phy_interrupts[i], 0, |
| 3322 | 3341 | DRV_NAME " phy", hisi_hba); |
| 3323 | 3342 | if (rc) { |
| @@ -3331,7 +3350,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) · 7 unmodified lines | ||
| 3331 | 3350 | for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { |
| 3332 | 3351 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
| 3333 | 3352 | |
| 3334 | − irq = irq_map[phy_no + 72]; | |
| 3353 | + irq = hisi_hba->irq_map[phy_no + 72]; | |
| 3335 | 3354 | rc = devm_request_irq(dev, irq, sata_int_v2_hw, 0, |
| 3336 | 3355 | DRV_NAME " sata", phy); |
| 3337 | 3356 | if (rc) { |
| @@ -3343,7 +3362,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) · 5 unmodified lines | ||
| 3343 | 3362 | } |
| 3344 | 3363 | |
| 3345 | 3364 | for (fatal_no = 0; fatal_no < HISI_SAS_FATAL_INT_NR; fatal_no++) { |
| 3346 | − irq = irq_map[fatal_no + 81]; | |
| 3365 | + irq = hisi_hba->irq_map[fatal_no + 81]; | |
| 3347 | 3366 | rc = devm_request_irq(dev, irq, fatal_interrupts[fatal_no], 0, |
| 3348 | 3367 | DRV_NAME " fatal", hisi_hba); |
| 3349 | 3368 | if (rc) { |
| @@ -3354,24 +3373,22 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) · 4 unmodified lines | ||
| 3354 | 3373 | } |
| 3355 | 3374 | } |
| 3356 | 3375 | |
| 3357 | − for (queue_no = 0; queue_no < hisi_hba->queue_count; queue_no++) { | |
| 3376 | + for (queue_no = 0; queue_no < hisi_hba->cq_nvecs; queue_no++) { | |
| 3358 | 3377 | struct hisi_sas_cq *cq = &hisi_hba->cq[queue_no]; |
| 3359 | 3378 | |
| 3360 | − cq->irq_no = irq_map[queue_no + 96]; | |
| 3379 | + cq->irq_no = hisi_hba->irq_map[queue_no + 96]; | |
| 3361 | 3380 | rc = devm_request_threaded_irq(dev, cq->irq_no, |
| 3362 | 3381 | cq_interrupt_v2_hw, |
| 3363 | 3382 | cq_thread_v2_hw, IRQF_ONESHOT, |
| 3364 | 3383 | DRV_NAME " cq", cq); |
| 3365 | 3384 | if (rc) { |
| 3366 | 3385 | dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n", |
| 3367 | − irq, rc); | |
| 3386 | + cq->irq_no, rc); | |
| 3368 | 3387 | rc = -ENOENT; |
| 3369 | 3388 | goto err_out; |
| 3370 | 3389 | } |
| 3390 | + cq->irq_mask = irq_get_affinity_mask(cq->irq_no); | |
| 3371 | 3391 | } |
| 3372 | − | |
| 3373 | − hisi_hba->cq_nvecs = hisi_hba->queue_count; | |
| 3374 | − | |
| 3375 | 3392 | err_out: |
| 3376 | 3393 | return rc; |
| 3377 | 3394 | } |
| @@ -3529,6 +3546,26 @@ static struct device_attribute *host_attrs_v2_hw[] = { · 151 unmodified lines | ||
| 3529 | 3546 | NULL |
| 3530 | 3547 | }; |
| 3531 | 3548 | |
| 3549 | +static int map_queues_v2_hw(struct Scsi_Host *shost) | |
| 3550 | +{ | |
| 3551 | + struct hisi_hba *hisi_hba = shost_priv(shost); | |
| 3552 | + struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; | |
| 3553 | + const struct cpumask *mask; | |
| 3554 | + unsigned int queue, cpu; | |
| 3555 | + | |
| 3556 | + for (queue = 0; queue < qmap->nr_queues; queue++) { | |
| 3557 | + mask = irq_get_affinity_mask(hisi_hba->irq_map[96 + queue]); | |
| 3558 | + if (!mask) | |
| 3559 | + continue; | |
| 3560 | + | |
| 3561 | + for_each_cpu(cpu, mask) | |
| 3562 | + qmap->mq_map[cpu] = qmap->queue_offset + queue; | |
| 3563 | + } | |
| 3564 | + | |
| 3565 | + return 0; | |
| 3566 | + | |
| 3567 | +} | |
| 3568 | + | |
| 3532 | 3569 | static struct scsi_host_template sht_v2_hw = { |
| 3533 | 3570 | .name = DRV_NAME, |
| 3534 | 3571 | .proc_name = DRV_NAME, |
| @@ -3553,10 +3590,13 @@ static struct scsi_host_template sht_v2_hw = { · 18 unmodified lines | ||
| 3553 | 3590 | #endif |
| 3554 | 3591 | .shost_attrs = host_attrs_v2_hw, |
| 3555 | 3592 | .host_reset = hisi_sas_host_reset, |
| 3593 | + .map_queues = map_queues_v2_hw, | |
| 3594 | + .host_tagset = 1, | |
| 3556 | 3595 | }; |
| 3557 | 3596 | |
| 3558 | 3597 | static const struct hisi_sas_hw hisi_sas_v2_hw = { |
| 3559 | 3598 | .hw_init = hisi_sas_v2_init, |
| 3599 | + .interrupt_preinit = hisi_sas_v2_interrupt_preinit, | |
| 3560 | 3600 | .setup_itct = setup_itct_v2_hw, |
| 3561 | 3601 | .slot_index_alloc = slot_index_alloc_quirk_v2_hw, |
| 3562 | 3602 | .alloc_dev = alloc_dev_quirk_v2_hw, |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | #include <linux/poll.h> |
| 38 | 38 | #include <linux/vmalloc.h> |
| 39 | 39 | #include <linux/irq_poll.h> |
| 40 | +#include <linux/blk-mq-pci.h> | |
| 40 | 41 | |
| 41 | 42 | #include <scsi/scsi.h> |
| 42 | 43 | #include <scsi/scsi_cmnd.h> |
| @@ -113,6 +114,10 @@ unsigned int enable_sdev_max_qd; · 70 unmodified lines | ||
| 113 | 114 | module_param(enable_sdev_max_qd, int, 0444); |
| 114 | 115 | MODULE_PARM_DESC(enable_sdev_max_qd, "Enable sdev max qd as can_queue. Default: 0"); |
| 115 | 116 | |
| 117 | +int host_tagset_enable = 1; | |
| 118 | +module_param(host_tagset_enable, int, 0444); | |
| 119 | +MODULE_PARM_DESC(host_tagset_enable, "Shared host tagset enable/disable Default: enable(1)"); | |
| 120 | + | |
| 116 | 121 | MODULE_LICENSE("GPL"); |
| 117 | 122 | MODULE_VERSION(MEGASAS_VERSION); |
| 118 | 123 | MODULE_AUTHOR("megaraidlinux.pdl@broadcom.com"); |
| @@ -3119,6 +3124,19 @@ megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev, · 3000 unmodified lines | ||
| 3119 | 3124 | return 0; |
| 3120 | 3125 | } |
| 3121 | 3126 | |
| 3127 | +static int megasas_map_queues(struct Scsi_Host *shost) | |
| 3128 | +{ | |
| 3129 | + struct megasas_instance *instance; | |
| 3130 | + | |
| 3131 | + instance = (struct megasas_instance *)shost->hostdata; | |
| 3132 | + | |
| 3133 | + if (shost->nr_hw_queues == 1) | |
| 3134 | + return 0; | |
| 3135 | + | |
| 3136 | + return blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT], | |
| 3137 | + instance->pdev, instance->low_latency_index_start); | |
| 3138 | +} | |
| 3139 | + | |
| 3122 | 3140 | static void megasas_aen_polling(struct work_struct *work); |
| 3123 | 3141 | |
| 3124 | 3142 | /** |
| @@ -3427,6 +3445,7 @@ static struct scsi_host_template megasas_template = { · 302 unmodified lines | ||
| 3427 | 3445 | .eh_timed_out = megasas_reset_timer, |
| 3428 | 3446 | .shost_attrs = megaraid_host_attrs, |
| 3429 | 3447 | .bios_param = megasas_bios_param, |
| 3448 | + .map_queues = megasas_map_queues, | |
| 3430 | 3449 | .change_queue_depth = scsi_change_queue_depth, |
| 3431 | 3450 | .max_segment_size = 0xffffffff, |
| 3432 | 3451 | }; |
| @@ -6808,6 +6827,26 @@ static int megasas_io_attach(struct megasas_instance *instance) · 3375 unmodified lines | ||
| 6808 | 6827 | host->max_lun = MEGASAS_MAX_LUN; |
| 6809 | 6828 | host->max_cmd_len = 16; |
| 6810 | 6829 | |
| 6830 | + /* Use shared host tagset only for fusion adaptors | |
| 6831 | + * if there are managed interrupts (smp affinity enabled case). | |
| 6832 | + * Single msix_vectors in kdump, so shared host tag is also disabled. | |
| 6833 | + */ | |
| 6834 | + | |
| 6835 | + host->host_tagset = 0; | |
| 6836 | + host->nr_hw_queues = 1; | |
| 6837 | + | |
| 6838 | + if ((instance->adapter_type != MFI_SERIES) && | |
| 6839 | + (instance->msix_vectors > instance->low_latency_index_start) && | |
| 6840 | + host_tagset_enable && | |
| 6841 | + instance->smp_affinity_enable) { | |
| 6842 | + host->host_tagset = 1; | |
| 6843 | + host->nr_hw_queues = instance->msix_vectors - | |
| 6844 | + instance->low_latency_index_start; | |
| 6845 | + } | |
| 6846 | + | |
| 6847 | + dev_info(&instance->pdev->dev, | |
| 6848 | + "Max firmware commands: %d shared with nr_hw_queues = %d\n", | |
| 6849 | + instance->max_fw_cmds, host->nr_hw_queues); | |
| 6811 | 6850 | /* |
| 6812 | 6851 | * Notify the mid-layer about the new controller |
| 6813 | 6852 | */ |
| @@ -359,24 +359,29 @@ megasas_get_msix_index(struct megasas_instance *instance, · 358 unmodified lines | ||
| 359 | 359 | { |
| 360 | 360 | int sdev_busy; |
| 361 | 361 | |
| 362 | − /* nr_hw_queue = 1 for MegaRAID */ | |
| 363 | − struct blk_mq_hw_ctx *hctx = | |
| 364 | − scmd->device->request_queue->queue_hw_ctx[0]; | |
| 365 | − | |
| 366 | − sdev_busy = atomic_read(&hctx->nr_active); | |
| 362 | + /* TBD - if sml remove device_busy in future, driver | |
| 363 | + * should track counter in internal structure. | |
| 364 | + */ | |
| 365 | + sdev_busy = atomic_read(&scmd->device->device_busy); | |
| 367 | 366 | |
| 368 | 367 | if (instance->perf_mode == MR_BALANCED_PERF_MODE && |
| 369 | − sdev_busy > (data_arms * MR_DEVICE_HIGH_IOPS_DEPTH)) | |
| 368 | + sdev_busy > (data_arms * MR_DEVICE_HIGH_IOPS_DEPTH)) { | |
| 370 | 369 | cmd->request_desc->SCSIIO.MSIxIndex = |
| 371 | 370 | mega_mod64((atomic64_add_return(1, &instance->high_iops_outstanding) / |
| 372 | 371 | MR_HIGH_IOPS_BATCH_COUNT), instance->low_latency_index_start); |
| 373 | − else if (instance->msix_load_balance) | |
| 372 | + } else if (instance->msix_load_balance) { | |
| 374 | 373 | cmd->request_desc->SCSIIO.MSIxIndex = |
| 375 | 374 | (mega_mod64(atomic64_add_return(1, &instance->total_io_count), |
| 376 | 375 | instance->msix_vectors)); |
| 377 | − else | |
| 376 | + } else if (instance->host->nr_hw_queues > 1) { | |
| 377 | + u32 tag = blk_mq_unique_tag(scmd->request); | |
| 378 | + | |
| 379 | + cmd->request_desc->SCSIIO.MSIxIndex = blk_mq_unique_tag_to_hwq(tag) + | |
| 380 | + instance->low_latency_index_start; | |
| 381 | + } else { | |
| 378 | 382 | cmd->request_desc->SCSIIO.MSIxIndex = |
| 379 | 383 | instance->reply_map[raw_smp_processor_id()]; |
| 384 | + } | |
| 380 | 385 | } |
| 381 | 386 | |
| 382 | 387 | /** |
| @@ -956,9 +961,6 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance) · 573 unmodified lines | ||
| 956 | 961 | if (megasas_alloc_cmdlist_fusion(instance)) |
| 957 | 962 | goto fail_exit; |
| 958 | 963 | |
| 959 | − dev_info(&instance->pdev->dev, "Configured max firmware commands: %d\n", | |
| 960 | − instance->max_fw_cmds); | |
| 961 | − | |
| 962 | 964 | /* The first 256 bytes (SMID 0) is not used. Don't add to the cmd list */ |
| 963 | 965 | io_req_base = fusion->io_request_frames + MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE; |
| 964 | 966 | io_req_base_phys = fusion->io_request_frames_phys + MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE; |
| @@ -1102,8 +1104,9 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) · 137 unmodified lines | ||
| 1102 | 1104 | MR_HIGH_IOPS_QUEUE_COUNT) && cur_intr_coalescing) |
| 1103 | 1105 | instance->perf_mode = MR_BALANCED_PERF_MODE; |
| 1104 | 1106 | |
| 1105 | − dev_info(&instance->pdev->dev, "Performance mode :%s\n", | |
| 1106 | − MEGASAS_PERF_MODE_2STR(instance->perf_mode)); | |
| 1107 | + dev_info(&instance->pdev->dev, "Performance mode :%s (latency index = %d)\n", | |
| 1108 | + MEGASAS_PERF_MODE_2STR(instance->perf_mode), | |
| 1109 | + instance->low_latency_index_start); | |
| 1107 | 1110 | |
| 1108 | 1111 | instance->fw_sync_cache_support = (scratch_pad_1 & |
| 1109 | 1112 | MR_CAN_HANDLE_SYNC_CACHE_OFFSET) ? 1 : 0; |
| @@ -79,5 +79,5 @@ config SCSI_MPT2SAS · 78 unmodified lines | ||
| 79 | 79 | select SCSI_MPT3SAS |
| 80 | 80 | depends on PCI && SCSI |
| 81 | 81 | help |
| 82 | − Dummy config option for backwards compatiblity: configure the MPT3SAS | |
| 82 | + Dummy config option for backwards compatibility: configure the MPT3SAS | |
| 83 | 83 | driver instead. |
| @@ -5034,7 +5034,7 @@ _base_check_for_trigger_pages_support(struct MPT3SAS_ADAPTER *ioc) · 5033 unmodified lines | ||
| 5034 | 5034 | static void |
| 5035 | 5035 | _base_get_diag_triggers(struct MPT3SAS_ADAPTER *ioc) |
| 5036 | 5036 | { |
| 5037 | − u16 trigger_flags; | |
| 5037 | + int trigger_flags; | |
| 5038 | 5038 | |
| 5039 | 5039 | /* |
| 5040 | 5040 | * Default setting of master trigger. |
| @@ -2245,7 +2245,7 @@ qedi_show_boot_tgt_info(struct qedi_ctx *qedi, int type, · 2244 unmodified lines | ||
| 2245 | 2245 | chap_name); |
| 2246 | 2246 | break; |
| 2247 | 2247 | case ISCSI_BOOT_TGT_CHAP_SECRET: |
| 2248 | − rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, | |
| 2248 | + rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN, | |
| 2249 | 2249 | chap_secret); |
| 2250 | 2250 | break; |
| 2251 | 2251 | case ISCSI_BOOT_TGT_REV_CHAP_NAME: |
| @@ -2253,7 +2253,7 @@ qedi_show_boot_tgt_info(struct qedi_ctx *qedi, int type, · 1 unmodified line | ||
| 2253 | 2253 | mchap_name); |
| 2254 | 2254 | break; |
| 2255 | 2255 | case ISCSI_BOOT_TGT_REV_CHAP_SECRET: |
| 2256 | − rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, | |
| 2256 | + rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN, | |
| 2257 | 2257 | mchap_secret); |
| 2258 | 2258 | break; |
| 2259 | 2259 | case ISCSI_BOOT_TGT_FLAGS: |
| @@ -6740,7 +6740,7 @@ static int __init scsi_debug_init(void) · 6739 unmodified lines | ||
| 6740 | 6740 | k = sdeb_zbc_model_str(sdeb_zbc_model_s); |
| 6741 | 6741 | if (k < 0) { |
| 6742 | 6742 | ret = k; |
| 6743 | − goto free_vm; | |
| 6743 | + goto free_q_arr; | |
| 6744 | 6744 | } |
| 6745 | 6745 | sdeb_zbc_model = k; |
| 6746 | 6746 | switch (sdeb_zbc_model) { |
| @@ -6753,7 +6753,8 @@ static int __init scsi_debug_init(void) · 6 unmodified lines | ||
| 6753 | 6753 | break; |
| 6754 | 6754 | default: |
| 6755 | 6755 | pr_err("Invalid ZBC model\n"); |
| 6756 | − return -EINVAL; | |
| 6756 | + ret = -EINVAL; | |
| 6757 | + goto free_q_arr; | |
| 6757 | 6758 | } |
| 6758 | 6759 | } |
| 6759 | 6760 | if (sdeb_zbc_model != BLK_ZONED_NONE) { |
| @@ -249,7 +249,8 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, · 248 unmodified lines | ||
| 249 | 249 | |
| 250 | 250 | req = blk_get_request(sdev->request_queue, |
| 251 | 251 | data_direction == DMA_TO_DEVICE ? |
| 252 | − REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, BLK_MQ_REQ_PREEMPT); | |
| 252 | + REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, | |
| 253 | + rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0); | |
| 253 | 254 | if (IS_ERR(req)) |
| 254 | 255 | return ret; |
| 255 | 256 | rq = scsi_req(req); |
| @@ -1206,6 +1207,8 @@ static blk_status_t · 950 unmodified lines | ||
| 1206 | 1207 | scsi_device_state_check(struct scsi_device *sdev, struct request *req) |
| 1207 | 1208 | { |
| 1208 | 1209 | switch (sdev->sdev_state) { |
| 1210 | + case SDEV_CREATED: | |
| 1211 | + return BLK_STS_OK; | |
| 1209 | 1212 | case SDEV_OFFLINE: |
| 1210 | 1213 | case SDEV_TRANSPORT_OFFLINE: |
| 1211 | 1214 | /* |
| @@ -1232,18 +1235,18 @@ scsi_device_state_check(struct scsi_device *sdev, struct request *req) · 20 unmodified lines | ||
| 1232 | 1235 | return BLK_STS_RESOURCE; |
| 1233 | 1236 | case SDEV_QUIESCE: |
| 1234 | 1237 | /* |
| 1235 | − * If the devices is blocked we defer normal commands. | |
| 1238 | + * If the device is blocked we only accept power management | |
| 1239 | + * commands. | |
| 1236 | 1240 | */ |
| 1237 | − if (req && !(req->rq_flags & RQF_PREEMPT)) | |
| 1241 | + if (req && WARN_ON_ONCE(!(req->rq_flags & RQF_PM))) | |
| 1238 | 1242 | return BLK_STS_RESOURCE; |
| 1239 | 1243 | return BLK_STS_OK; |
| 1240 | 1244 | default: |
| 1241 | 1245 | /* |
| 1242 | 1246 | * For any other not fully online state we only allow |
| 1243 | − * special commands. In particular any user initiated | |
| 1244 | − * command is not allowed. | |
| 1247 | + * power management commands. | |
| 1245 | 1248 | */ |
| 1246 | − if (req && !(req->rq_flags & RQF_PREEMPT)) | |
| 1249 | + if (req && !(req->rq_flags & RQF_PM)) | |
| 1247 | 1250 | return BLK_STS_IOERR; |
| 1248 | 1251 | return BLK_STS_OK; |
| 1249 | 1252 | } |
| @@ -2516,15 +2519,13 @@ void sdev_evt_send_simple(struct scsi_device *sdev, · 1266 unmodified lines | ||
| 2516 | 2519 | EXPORT_SYMBOL_GPL(sdev_evt_send_simple); |
| 2517 | 2520 | |
| 2518 | 2521 | /** |
| 2519 | − * scsi_device_quiesce - Block user issued commands. | |
| 2522 | + * scsi_device_quiesce - Block all commands except power management. | |
| 2520 | 2523 | * @sdev: scsi device to quiesce. |
| 2521 | 2524 | * |
| 2522 | 2525 | * This works by trying to transition to the SDEV_QUIESCE state |
| 2523 | 2526 | * (which must be a legal transition). When the device is in this |
| 2524 | − * state, only special requests will be accepted, all others will | |
| 2525 | − * be deferred. Since special requests may also be requeued requests, | |
| 2526 | − * a successful return doesn't guarantee the device will be | |
| 2527 | − * totally quiescent. | |
| 2527 | + * state, only power management requests will be accepted, all others will | |
| 2528 | + * be deferred. | |
| 2528 | 2529 | * |
| 2529 | 2530 | * Must be called with user context, may sleep. |
| 2530 | 2531 | * |
| @@ -2586,12 +2587,12 @@ void scsi_device_resume(struct scsi_device *sdev) · 55 unmodified lines | ||
| 2586 | 2587 | * device deleted during suspend) |
| 2587 | 2588 | */ |
| 2588 | 2589 | mutex_lock(&sdev->state_mutex); |
| 2590 | + if (sdev->sdev_state == SDEV_QUIESCE) | |
| 2591 | + scsi_device_set_state(sdev, SDEV_RUNNING); | |
| 2589 | 2592 | if (sdev->quiesced_by) { |
| 2590 | 2593 | sdev->quiesced_by = NULL; |
| 2591 | 2594 | blk_clear_pm_only(sdev->request_queue); |
| 2592 | 2595 | } |
| 2593 | − if (sdev->sdev_state == SDEV_QUIESCE) | |
| 2594 | − scsi_device_set_state(sdev, SDEV_RUNNING); | |
| 2595 | 2596 | mutex_unlock(&sdev->state_mutex); |
| 2596 | 2597 | } |
| 2597 | 2598 | EXPORT_SYMBOL(scsi_device_resume); |
| @@ -117,12 +117,16 @@ static int spi_execute(struct scsi_device *sdev, const void *cmd, · 116 unmodified lines | ||
| 117 | 117 | sshdr = &sshdr_tmp; |
| 118 | 118 | |
| 119 | 119 | for(i = 0; i < DV_RETRIES; i++) { |
| 120 | + /* | |
| 121 | + * The purpose of the RQF_PM flag below is to bypass the | |
| 122 | + * SDEV_QUIESCE state. | |
| 123 | + */ | |
| 120 | 124 | result = scsi_execute(sdev, cmd, dir, buffer, bufflen, sense, |
| 121 | 125 | sshdr, DV_TIMEOUT, /* retries */ 1, |
| 122 | 126 | REQ_FAILFAST_DEV | |
| 123 | 127 | REQ_FAILFAST_TRANSPORT | |
| 124 | 128 | REQ_FAILFAST_DRIVER, |
| 125 | − 0, NULL); | |
| 129 | + RQF_PM, NULL); | |
| 126 | 130 | if (driver_byte(result) != DRIVER_SENSE || |
| 127 | 131 | sshdr->sense_key != UNIT_ATTENTION) |
| 128 | 132 | break; |
| @@ -1005,23 +1009,26 @@ spi_dv_device(struct scsi_device *sdev) · 876 unmodified lines | ||
| 1005 | 1009 | */ |
| 1006 | 1010 | lock_system_sleep(); |
| 1007 | 1011 | |
| 1012 | + if (scsi_autopm_get_device(sdev)) | |
| 1013 | + goto unlock_system_sleep; | |
| 1014 | + | |
| 1008 | 1015 | if (unlikely(spi_dv_in_progress(starget))) |
| 1009 | − goto unlock; | |
| 1016 | + goto put_autopm; | |
| 1010 | 1017 | |
| 1011 | 1018 | if (unlikely(scsi_device_get(sdev))) |
| 1012 | − goto unlock; | |
| 1019 | + goto put_autopm; | |
| 1013 | 1020 | |
| 1014 | 1021 | spi_dv_in_progress(starget) = 1; |
| 1015 | 1022 | |
| 1016 | 1023 | buffer = kzalloc(len, GFP_KERNEL); |
| 1017 | 1024 | |
| 1018 | 1025 | if (unlikely(!buffer)) |
| 1019 | − goto out_put; | |
| 1026 | + goto put_sdev; | |
| 1020 | 1027 | |
| 1021 | 1028 | /* We need to verify that the actual device will quiesce; the |
| 1022 | 1029 | * later target quiesce is just a nice to have */ |
| 1023 | 1030 | if (unlikely(scsi_device_quiesce(sdev))) |
| 1024 | − goto out_free; | |
| 1031 | + goto free_buffer; | |
| 1025 | 1032 | |
| 1026 | 1033 | scsi_target_quiesce(starget); |
| 1027 | 1034 | |
| @@ -1041,12 +1048,16 @@ spi_dv_device(struct scsi_device *sdev) · 13 unmodified lines | ||
| 1041 | 1048 | |
| 1042 | 1049 | spi_initial_dv(starget) = 1; |
| 1043 | 1050 | |
| 1044 | − out_free: | |
| 1051 | +free_buffer: | |
| 1045 | 1052 | kfree(buffer); |
| 1046 | − out_put: | |
| 1053 | + | |
| 1054 | +put_sdev: | |
| 1047 | 1055 | spi_dv_in_progress(starget) = 0; |
| 1048 | 1056 | scsi_device_put(sdev); |
| 1049 | −unlock: | |
| 1057 | +put_autopm: | |
| 1058 | + scsi_autopm_put_device(sdev); | |
| 1059 | + | |
| 1060 | +unlock_system_sleep: | |
| 1050 | 1061 | unlock_system_sleep(); |
| 1051 | 1062 | } |
| 1052 | 1063 | EXPORT_SYMBOL(spi_dv_device); |
| @@ -984,8 +984,10 @@ static blk_status_t sd_setup_write_zeroes_cmnd(struct scsi_cmnd *cmd) · 983 unmodified lines | ||
| 984 | 984 | } |
| 985 | 985 | } |
| 986 | 986 | |
| 987 | − if (sdp->no_write_same) | |
| 987 | + if (sdp->no_write_same) { | |
| 988 | + rq->rq_flags |= RQF_QUIET; | |
| 988 | 989 | return BLK_STS_TARGET; |
| 990 | + } | |
| 989 | 991 | |
| 990 | 992 | if (sdkp->ws16 || lba > 0xffffffff || nr_blocks > 0xffff) |
| 991 | 993 | return sd_setup_write_same16_cmnd(cmd, false); |
| @@ -3510,10 +3512,8 @@ static int sd_probe(struct device *dev) · 2518 unmodified lines | ||
| 3510 | 3512 | static int sd_remove(struct device *dev) |
| 3511 | 3513 | { |
| 3512 | 3514 | struct scsi_disk *sdkp; |
| 3513 | − dev_t devt; | |
| 3514 | 3515 | |
| 3515 | 3516 | sdkp = dev_get_drvdata(dev); |
| 3516 | − devt = disk_devt(sdkp->disk); | |
| 3517 | 3517 | scsi_autopm_get_device(sdkp->device); |
| 3518 | 3518 | |
| 3519 | 3519 | async_synchronize_full_domain(&scsi_sd_pm_domain); |
| @@ -31,6 +31,6 @@ TRACE_EVENT(ufs_mtk_event, · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | #undef TRACE_INCLUDE_PATH |
| 33 | 33 | #undef TRACE_INCLUDE_FILE |
| 34 | −#define TRACE_INCLUDE_PATH . | |
| 34 | +#define TRACE_INCLUDE_PATH ../../drivers/scsi/ufs/ | |
| 35 | 35 | #define TRACE_INCLUDE_FILE ufs-mediatek-trace |
| 36 | 36 | #include <trace/define_trace.h> |
| @@ -70,6 +70,13 @@ static bool ufs_mtk_is_va09_supported(struct ufs_hba *hba) · 69 unmodified lines | ||
| 70 | 70 | return !!(host->caps & UFS_MTK_CAP_VA09_PWR_CTRL); |
| 71 | 71 | } |
| 72 | 72 | |
| 73 | +static bool ufs_mtk_is_broken_vcc(struct ufs_hba *hba) | |
| 74 | +{ | |
| 75 | + struct ufs_mtk_host *host = ufshcd_get_variant(hba); | |
| 76 | + | |
| 77 | + return !!(host->caps & UFS_MTK_CAP_BROKEN_VCC); | |
| 78 | +} | |
| 79 | + | |
| 73 | 80 | static void ufs_mtk_cfg_unipro_cg(struct ufs_hba *hba, bool enable) |
| 74 | 81 | { |
| 75 | 82 | u32 tmp; |
| @@ -514,6 +521,9 @@ static void ufs_mtk_init_host_caps(struct ufs_hba *hba) · 438 unmodified lines | ||
| 514 | 521 | if (of_property_read_bool(np, "mediatek,ufs-disable-ah8")) |
| 515 | 522 | host->caps |= UFS_MTK_CAP_DISABLE_AH8; |
| 516 | 523 | |
| 524 | + if (of_property_read_bool(np, "mediatek,ufs-broken-vcc")) | |
| 525 | + host->caps |= UFS_MTK_CAP_BROKEN_VCC; | |
| 526 | + | |
| 517 | 527 | dev_info(hba->dev, "caps: 0x%x", host->caps); |
| 518 | 528 | } |
| 519 | 529 | |
| @@ -1003,6 +1013,17 @@ static int ufs_mtk_apply_dev_quirks(struct ufs_hba *hba) · 483 unmodified lines | ||
| 1003 | 1013 | static void ufs_mtk_fixup_dev_quirks(struct ufs_hba *hba) |
| 1004 | 1014 | { |
| 1005 | 1015 | ufshcd_fixup_dev_quirks(hba, ufs_mtk_dev_fixups); |
| 1016 | + | |
| 1017 | + if (ufs_mtk_is_broken_vcc(hba) && hba->vreg_info.vcc && | |
| 1018 | + (hba->dev_quirks & UFS_DEVICE_QUIRK_DELAY_AFTER_LPM)) { | |
| 1019 | + hba->vreg_info.vcc->always_on = true; | |
| 1020 | + /* | |
| 1021 | + * VCC will be kept always-on thus we don't | |
| 1022 | + * need any delay during regulator operations | |
| 1023 | + */ | |
| 1024 | + hba->dev_quirks &= ~(UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM | | |
| 1025 | + UFS_DEVICE_QUIRK_DELAY_AFTER_LPM); | |
| 1026 | + } | |
| 1006 | 1027 | } |
| 1007 | 1028 | |
| 1008 | 1029 | static void ufs_mtk_event_notify(struct ufs_hba *hba, |
| @@ -81,6 +81,7 @@ enum ufs_mtk_host_caps { · 80 unmodified lines | ||
| 81 | 81 | UFS_MTK_CAP_BOOST_CRYPT_ENGINE = 1 << 0, |
| 82 | 82 | UFS_MTK_CAP_VA09_PWR_CTRL = 1 << 1, |
| 83 | 83 | UFS_MTK_CAP_DISABLE_AH8 = 1 << 2, |
| 84 | + UFS_MTK_CAP_BROKEN_VCC = 1 << 3, | |
| 84 | 85 | }; |
| 85 | 86 | |
| 86 | 87 | struct ufs_mtk_crypt_cfg { |
| @@ -330,7 +330,6 @@ enum { · 329 unmodified lines | ||
| 330 | 330 | UFS_DEV_WRITE_BOOSTER_SUP = BIT(8), |
| 331 | 331 | }; |
| 332 | 332 | |
| 333 | −#define POWER_DESC_MAX_SIZE 0x62 | |
| 334 | 333 | #define POWER_DESC_MAX_ACTV_ICC_LVLS 16 |
| 335 | 334 | |
| 336 | 335 | /* Attribute bActiveICCLevel parameter bit masks definitions */ |
| @@ -513,6 +512,7 @@ struct ufs_query_res { · 176 unmodified lines | ||
| 513 | 512 | struct ufs_vreg { |
| 514 | 513 | struct regulator *reg; |
| 515 | 514 | const char *name; |
| 515 | + bool always_on; | |
| 516 | 516 | bool enabled; |
| 517 | 517 | int min_uV; |
| 518 | 518 | int max_uV; |
| @@ -148,6 +148,8 @@ static int ufs_intel_common_init(struct ufs_hba *hba) · 147 unmodified lines | ||
| 148 | 148 | { |
| 149 | 149 | struct intel_host *host; |
| 150 | 150 | |
| 151 | + hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND; | |
| 152 | + | |
| 151 | 153 | host = devm_kzalloc(hba->dev, sizeof(*host), GFP_KERNEL); |
| 152 | 154 | if (!host) |
| 153 | 155 | return -ENOMEM; |
| @@ -163,6 +165,41 @@ static void ufs_intel_common_exit(struct ufs_hba *hba) · 9 unmodified lines | ||
| 163 | 165 | intel_ltr_hide(hba->dev); |
| 164 | 166 | } |
| 165 | 167 | |
| 168 | +static int ufs_intel_resume(struct ufs_hba *hba, enum ufs_pm_op op) | |
| 169 | +{ | |
| 170 | + /* | |
| 171 | + * To support S4 (suspend-to-disk) with spm_lvl other than 5, the base | |
| 172 | + * address registers must be restored because the restore kernel can | |
| 173 | + * have used different addresses. | |
| 174 | + */ | |
| 175 | + ufshcd_writel(hba, lower_32_bits(hba->utrdl_dma_addr), | |
| 176 | + REG_UTP_TRANSFER_REQ_LIST_BASE_L); | |
| 177 | + ufshcd_writel(hba, upper_32_bits(hba->utrdl_dma_addr), | |
| 178 | + REG_UTP_TRANSFER_REQ_LIST_BASE_H); | |
| 179 | + ufshcd_writel(hba, lower_32_bits(hba->utmrdl_dma_addr), | |
| 180 | + REG_UTP_TASK_REQ_LIST_BASE_L); | |
| 181 | + ufshcd_writel(hba, upper_32_bits(hba->utmrdl_dma_addr), | |
| 182 | + REG_UTP_TASK_REQ_LIST_BASE_H); | |
| 183 | + | |
| 184 | + if (ufshcd_is_link_hibern8(hba)) { | |
| 185 | + int ret = ufshcd_uic_hibern8_exit(hba); | |
| 186 | + | |
| 187 | + if (!ret) { | |
| 188 | + ufshcd_set_link_active(hba); | |
| 189 | + } else { | |
| 190 | + dev_err(hba->dev, "%s: hibern8 exit failed %d\n", | |
| 191 | + __func__, ret); | |
| 192 | + /* | |
| 193 | + * Force reset and restore. Any other actions can lead | |
| 194 | + * to an unrecoverable state. | |
| 195 | + */ | |
| 196 | + ufshcd_set_link_off(hba); | |
| 197 | + } | |
| 198 | + } | |
| 199 | + | |
| 200 | + return 0; | |
| 201 | +} | |
| 202 | + | |
| 166 | 203 | static int ufs_intel_ehl_init(struct ufs_hba *hba) |
| 167 | 204 | { |
| 168 | 205 | hba->quirks |= UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8; |
| @@ -174,6 +211,7 @@ static struct ufs_hba_variant_ops ufs_intel_cnl_hba_vops = { · 5 unmodified lines | ||
| 174 | 211 | .init = ufs_intel_common_init, |
| 175 | 212 | .exit = ufs_intel_common_exit, |
| 176 | 213 | .link_startup_notify = ufs_intel_link_startup_notify, |
| 214 | + .resume = ufs_intel_resume, | |
| 177 | 215 | }; |
| 178 | 216 | |
| 179 | 217 | static struct ufs_hba_variant_ops ufs_intel_ehl_hba_vops = { |
| @@ -181,6 +219,7 @@ static struct ufs_hba_variant_ops ufs_intel_ehl_hba_vops = { · 1 unmodified line | ||
| 181 | 219 | .init = ufs_intel_ehl_init, |
| 182 | 220 | .exit = ufs_intel_common_exit, |
| 183 | 221 | .link_startup_notify = ufs_intel_link_startup_notify, |
| 222 | + .resume = ufs_intel_resume, | |
| 184 | 223 | }; |
| 185 | 224 | |
| 186 | 225 | #ifdef CONFIG_PM_SLEEP |
| @@ -207,6 +246,30 @@ static int ufshcd_pci_resume(struct device *dev) · 20 unmodified lines | ||
| 207 | 246 | { |
| 208 | 247 | return ufshcd_system_resume(dev_get_drvdata(dev)); |
| 209 | 248 | } |
| 249 | + | |
| 250 | +/** | |
| 251 | + * ufshcd_pci_poweroff - suspend-to-disk poweroff function | |
| 252 | + * @dev: pointer to PCI device handle | |
| 253 | + * | |
| 254 | + * Returns 0 if successful | |
| 255 | + * Returns non-zero otherwise | |
| 256 | + */ | |
| 257 | +static int ufshcd_pci_poweroff(struct device *dev) | |
| 258 | +{ | |
| 259 | + struct ufs_hba *hba = dev_get_drvdata(dev); | |
| 260 | + int spm_lvl = hba->spm_lvl; | |
| 261 | + int ret; | |
| 262 | + | |
| 263 | + /* | |
| 264 | + * For poweroff we need to set the UFS device to PowerDown mode. | |
| 265 | + * Force spm_lvl to ensure that. | |
| 266 | + */ | |
| 267 | + hba->spm_lvl = 5; | |
| 268 | + ret = ufshcd_system_suspend(hba); | |
| 269 | + hba->spm_lvl = spm_lvl; | |
| 270 | + return ret; | |
| 271 | +} | |
| 272 | + | |
| 210 | 273 | #endif /* !CONFIG_PM_SLEEP */ |
| 211 | 274 | |
| 212 | 275 | #ifdef CONFIG_PM |
| @@ -302,8 +365,14 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 89 unmodified lines | ||
| 302 | 365 | } |
| 303 | 366 | |
| 304 | 367 | static const struct dev_pm_ops ufshcd_pci_pm_ops = { |
| 305 | − SET_SYSTEM_SLEEP_PM_OPS(ufshcd_pci_suspend, | |
| 306 | − ufshcd_pci_resume) | |
| 368 | +#ifdef CONFIG_PM_SLEEP | |
| 369 | + .suspend = ufshcd_pci_suspend, | |
| 370 | + .resume = ufshcd_pci_resume, | |
| 371 | + .freeze = ufshcd_pci_suspend, | |
| 372 | + .thaw = ufshcd_pci_resume, | |
| 373 | + .poweroff = ufshcd_pci_poweroff, | |
| 374 | + .restore = ufshcd_pci_resume, | |
| 375 | +#endif | |
| 307 | 376 | SET_RUNTIME_PM_OPS(ufshcd_pci_runtime_suspend, |
| 308 | 377 | ufshcd_pci_runtime_resume, |
| 309 | 378 | ufshcd_pci_runtime_idle) |
| @@ -225,6 +225,7 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba); · 224 unmodified lines | ||
| 225 | 225 | static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd); |
| 226 | 226 | static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag); |
| 227 | 227 | static void ufshcd_hba_exit(struct ufs_hba *hba); |
| 228 | +static int ufshcd_clear_ua_wluns(struct ufs_hba *hba); | |
| 228 | 229 | static int ufshcd_probe_hba(struct ufs_hba *hba, bool async); |
| 229 | 230 | static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on); |
| 230 | 231 | static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba); |
| @@ -288,7 +289,8 @@ static inline void ufshcd_wb_config(struct ufs_hba *hba) · 57 unmodified lines | ||
| 288 | 289 | if (ret) |
| 289 | 290 | dev_err(hba->dev, "%s: En WB flush during H8: failed: %d\n", |
| 290 | 291 | __func__, ret); |
| 291 | − ufshcd_wb_toggle_flush(hba, true); | |
| 292 | + if (!(hba->quirks & UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL)) | |
| 293 | + ufshcd_wb_toggle_flush(hba, true); | |
| 292 | 294 | } |
| 293 | 295 | |
| 294 | 296 | static void ufshcd_scsi_unblock_requests(struct ufs_hba *hba) |
| @@ -580,6 +582,23 @@ static void ufshcd_print_pwr_info(struct ufs_hba *hba) · 285 unmodified lines | ||
| 580 | 582 | hba->pwr_info.hs_rate); |
| 581 | 583 | } |
| 582 | 584 | |
| 585 | +static void ufshcd_device_reset(struct ufs_hba *hba) | |
| 586 | +{ | |
| 587 | + int err; | |
| 588 | + | |
| 589 | + err = ufshcd_vops_device_reset(hba); | |
| 590 | + | |
| 591 | + if (!err) { | |
| 592 | + ufshcd_set_ufs_dev_active(hba); | |
| 593 | + if (ufshcd_is_wb_allowed(hba)) { | |
| 594 | + hba->wb_enabled = false; | |
| 595 | + hba->wb_buf_flush_enabled = false; | |
| 596 | + } | |
| 597 | + } | |
| 598 | + if (err != -EOPNOTSUPP) | |
| 599 | + ufshcd_update_evt_hist(hba, UFS_EVT_DEV_RESET, err); | |
| 600 | +} | |
| 601 | + | |
| 583 | 602 | void ufshcd_delay_us(unsigned long us, unsigned long tolerance) |
| 584 | 603 | { |
| 585 | 604 | if (!us) |
| @@ -3665,7 +3684,7 @@ static int ufshcd_dme_enable(struct ufs_hba *hba) · 3079 unmodified lines | ||
| 3665 | 3684 | ret = ufshcd_send_uic_cmd(hba, &uic_cmd); |
| 3666 | 3685 | if (ret) |
| 3667 | 3686 | dev_err(hba->dev, |
| 3668 | − "dme-reset: error code %d\n", ret); | |
| 3687 | + "dme-enable: error code %d\n", ret); | |
| 3669 | 3688 | |
| 3670 | 3689 | return ret; |
| 3671 | 3690 | } |
| @@ -3964,7 +3983,7 @@ int ufshcd_link_recovery(struct ufs_hba *hba) · 292 unmodified lines | ||
| 3964 | 3983 | spin_unlock_irqrestore(hba->host->host_lock, flags); |
| 3965 | 3984 | |
| 3966 | 3985 | /* Reset the attached device */ |
| 3967 | − ufshcd_vops_device_reset(hba); | |
| 3986 | + ufshcd_device_reset(hba); | |
| 3968 | 3987 | |
| 3969 | 3988 | ret = ufshcd_host_reset_and_restore(hba); |
| 3970 | 3989 | |
| @@ -5418,9 +5437,6 @@ static int ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set) · 1447 unmodified lines | ||
| 5418 | 5437 | |
| 5419 | 5438 | static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable) |
| 5420 | 5439 | { |
| 5421 | − if (hba->quirks & UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL) | |
| 5422 | − return; | |
| 5423 | − | |
| 5424 | 5440 | if (enable) |
| 5425 | 5441 | ufshcd_wb_buf_flush_enable(hba); |
| 5426 | 5442 | else |
| @@ -6643,19 +6659,16 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd) · 1216 unmodified lines | ||
| 6643 | 6659 | { |
| 6644 | 6660 | struct Scsi_Host *host; |
| 6645 | 6661 | struct ufs_hba *hba; |
| 6646 | − unsigned int tag; | |
| 6647 | 6662 | u32 pos; |
| 6648 | 6663 | int err; |
| 6649 | − u8 resp = 0xF; | |
| 6650 | − struct ufshcd_lrb *lrbp; | |
| 6664 | + u8 resp = 0xF, lun; | |
| 6651 | 6665 | unsigned long flags; |
| 6652 | 6666 | |
| 6653 | 6667 | host = cmd->device->host; |
| 6654 | 6668 | hba = shost_priv(host); |
| 6655 | − tag = cmd->request->tag; | |
| 6656 | 6669 | |
| 6657 | − lrbp = &hba->lrb[tag]; | |
| 6658 | − err = ufshcd_issue_tm_cmd(hba, lrbp->lun, 0, UFS_LOGICAL_RESET, &resp); | |
| 6670 | + lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun); | |
| 6671 | + err = ufshcd_issue_tm_cmd(hba, lun, 0, UFS_LOGICAL_RESET, &resp); | |
| 6659 | 6672 | if (err || resp != UPIU_TASK_MANAGEMENT_FUNC_COMPL) { |
| 6660 | 6673 | if (!err) |
| 6661 | 6674 | err = resp; |
| @@ -6664,7 +6677,7 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd) · 2 unmodified lines | ||
| 6664 | 6677 | |
| 6665 | 6678 | /* clear the commands that were pending for corresponding LUN */ |
| 6666 | 6679 | for_each_set_bit(pos, &hba->outstanding_reqs, hba->nutrs) { |
| 6667 | − if (hba->lrb[pos].lun == lrbp->lun) { | |
| 6680 | + if (hba->lrb[pos].lun == lun) { | |
| 6668 | 6681 | err = ufshcd_clear_cmd(hba, pos); |
| 6669 | 6682 | if (err) |
| 6670 | 6683 | break; |
| @@ -6930,7 +6943,8 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba) · 259 unmodified lines | ||
| 6930 | 6943 | |
| 6931 | 6944 | /* Establish the link again and restore the device */ |
| 6932 | 6945 | err = ufshcd_probe_hba(hba, false); |
| 6933 | − | |
| 6946 | + if (!err) | |
| 6947 | + ufshcd_clear_ua_wluns(hba); | |
| 6934 | 6948 | out: |
| 6935 | 6949 | if (err) |
| 6936 | 6950 | dev_err(hba->dev, "%s: Host init failed %d\n", __func__, err); |
| @@ -6968,7 +6982,7 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba) · 31 unmodified lines | ||
| 6968 | 6982 | |
| 6969 | 6983 | do { |
| 6970 | 6984 | /* Reset the attached device */ |
| 6971 | − ufshcd_vops_device_reset(hba); | |
| 6985 | + ufshcd_device_reset(hba); | |
| 6972 | 6986 | |
| 6973 | 6987 | err = ufshcd_host_reset_and_restore(hba); |
| 6974 | 6988 | } while (err && --retries); |
| @@ -8045,7 +8059,7 @@ static int ufshcd_disable_vreg(struct device *dev, struct ufs_vreg *vreg) · 1070 unmodified lines | ||
| 8045 | 8059 | { |
| 8046 | 8060 | int ret = 0; |
| 8047 | 8061 | |
| 8048 | − if (!vreg || !vreg->enabled) | |
| 8062 | + if (!vreg || !vreg->enabled || vreg->always_on) | |
| 8049 | 8063 | goto out; |
| 8050 | 8064 | |
| 8051 | 8065 | ret = regulator_disable(vreg->reg); |
| @@ -8414,13 +8428,7 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba, · 362 unmodified lines | ||
| 8414 | 8428 | * handling context. |
| 8415 | 8429 | */ |
| 8416 | 8430 | hba->host->eh_noresume = 1; |
| 8417 | − if (hba->wlun_dev_clr_ua) { | |
| 8418 | − ret = ufshcd_send_request_sense(hba, sdp); | |
| 8419 | − if (ret) | |
| 8420 | − goto out; | |
| 8421 | − /* Unit attention condition is cleared now */ | |
| 8422 | − hba->wlun_dev_clr_ua = false; | |
| 8423 | − } | |
| 8431 | + ufshcd_clear_ua_wluns(hba); | |
| 8424 | 8432 | |
| 8425 | 8433 | cmd[4] = pwr_mode << 4; |
| 8426 | 8434 | |
| @@ -8441,7 +8449,7 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba, · 14 unmodified lines | ||
| 8441 | 8449 | |
| 8442 | 8450 | if (!ret) |
| 8443 | 8451 | hba->curr_dev_pwr_mode = pwr_mode; |
| 8444 | −out: | |
| 8452 | + | |
| 8445 | 8453 | scsi_device_put(sdp); |
| 8446 | 8454 | hba->host->eh_noresume = 0; |
| 8447 | 8455 | return ret; |
| @@ -8685,6 +8693,8 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) · 237 unmodified lines | ||
| 8685 | 8693 | ufshcd_wb_need_flush(hba)); |
| 8686 | 8694 | } |
| 8687 | 8695 | |
| 8696 | + flush_work(&hba->eeh_work); | |
| 8697 | + | |
| 8688 | 8698 | if (req_dev_pwr_mode != hba->curr_dev_pwr_mode) { |
| 8689 | 8699 | if (!ufshcd_is_runtime_pm(pm_op)) |
| 8690 | 8700 | /* ensure that bkops is disabled */ |
| @@ -8697,8 +8707,6 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) · 6 unmodified lines | ||
| 8697 | 8707 | } |
| 8698 | 8708 | } |
| 8699 | 8709 | |
| 8700 | − flush_work(&hba->eeh_work); | |
| 8701 | − | |
| 8702 | 8710 | /* |
| 8703 | 8711 | * In the case of DeepSleep, the device is expected to remain powered |
| 8704 | 8712 | * with the link off, so do not check for bkops. |
| @@ -8747,7 +8755,7 @@ set_link_active: · 42 unmodified lines | ||
| 8747 | 8755 | * further below. |
| 8748 | 8756 | */ |
| 8749 | 8757 | if (ufshcd_is_ufs_dev_deepsleep(hba)) { |
| 8750 | − ufshcd_vops_device_reset(hba); | |
| 8758 | + ufshcd_device_reset(hba); | |
| 8751 | 8759 | WARN_ON(!ufshcd_is_link_off(hba)); |
| 8752 | 8760 | } |
| 8753 | 8761 | if (ufshcd_is_link_hibern8(hba) && !ufshcd_uic_hibern8_exit(hba)) |
| @@ -8757,7 +8765,7 @@ set_link_active: · 3 unmodified lines | ||
| 8757 | 8765 | set_dev_active: |
| 8758 | 8766 | /* Can also get here needing to exit DeepSleep */ |
| 8759 | 8767 | if (ufshcd_is_ufs_dev_deepsleep(hba)) { |
| 8760 | − ufshcd_vops_device_reset(hba); | |
| 8768 | + ufshcd_device_reset(hba); | |
| 8761 | 8769 | ufshcd_host_reset_and_restore(hba); |
| 8762 | 8770 | } |
| 8763 | 8771 | if (!ufshcd_set_dev_pwr_mode(hba, UFS_ACTIVE_PWR_MODE)) |
| @@ -8925,7 +8933,8 @@ int ufshcd_system_suspend(struct ufs_hba *hba) · 161 unmodified lines | ||
| 8925 | 8933 | if ((ufs_get_pm_lvl_to_dev_pwr_mode(hba->spm_lvl) == |
| 8926 | 8934 | hba->curr_dev_pwr_mode) && |
| 8927 | 8935 | (ufs_get_pm_lvl_to_link_pwr_state(hba->spm_lvl) == |
| 8928 | − hba->uic_link_state)) | |
| 8936 | + hba->uic_link_state) && | |
| 8937 | + !hba->dev_info.b_rpm_dev_flush_capable) | |
| 8929 | 8938 | goto out; |
| 8930 | 8939 | |
| 8931 | 8940 | if (pm_runtime_suspended(hba->dev)) { |
| @@ -9353,7 +9362,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) · 421 unmodified lines | ||
| 9353 | 9362 | } |
| 9354 | 9363 | |
| 9355 | 9364 | /* Reset the attached device */ |
| 9356 | − ufshcd_vops_device_reset(hba); | |
| 9365 | + ufshcd_device_reset(hba); | |
| 9357 | 9366 | |
| 9358 | 9367 | ufshcd_init_crypto(hba); |
| 9359 | 9368 | |
| @@ -1218,16 +1218,12 @@ static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba) · 1217 unmodified lines | ||
| 1218 | 1218 | hba->vops->dbg_register_dump(hba); |
| 1219 | 1219 | } |
| 1220 | 1220 | |
| 1221 | −static inline void ufshcd_vops_device_reset(struct ufs_hba *hba) | |
| 1221 | +static inline int ufshcd_vops_device_reset(struct ufs_hba *hba) | |
| 1222 | 1222 | { |
| 1223 | − if (hba->vops && hba->vops->device_reset) { | |
| 1224 | − int err = hba->vops->device_reset(hba); | |
| 1225 | − | |
| 1226 | − if (!err) | |
| 1227 | − ufshcd_set_ufs_dev_active(hba); | |
| 1228 | − if (err != -EOPNOTSUPP) | |
| 1229 | − ufshcd_update_evt_hist(hba, UFS_EVT_DEV_RESET, err); | |
| 1230 | − } | |
| 1223 | + if (hba->vops && hba->vops->device_reset) | |
| 1224 | + return hba->vops->device_reset(hba); | |
| 1225 | + | |
| 1226 | + return -EOPNOTSUPP; | |
| 1231 | 1227 | } |
| 1232 | 1228 | |
| 1233 | 1229 | static inline void ufshcd_vops_config_scaling_param(struct ufs_hba *hba, |
| @@ -189,24 +189,26 @@ static int altera_spi_txrx(struct spi_master *master, · 188 unmodified lines | ||
| 189 | 189 | |
| 190 | 190 | /* send the first byte */ |
| 191 | 191 | altera_spi_tx_word(hw); |
| 192 | − } else { | |
| 193 | − while (hw->count < hw->len) { | |
| 194 | − altera_spi_tx_word(hw); | |
| 195 | 192 | |
| 196 | − for (;;) { | |
| 197 | − altr_spi_readl(hw, ALTERA_SPI_STATUS, &val); | |
| 198 | − if (val & ALTERA_SPI_STATUS_RRDY_MSK) | |
| 199 | − break; | |
| 193 | + return 1; | |
| 194 | + } | |
| 195 | + | |
| 196 | + while (hw->count < hw->len) { | |
| 197 | + altera_spi_tx_word(hw); | |
| 200 | 198 | |
| 201 | − cpu_relax(); | |
| 202 | − } | |
| 199 | + for (;;) { | |
| 200 | + altr_spi_readl(hw, ALTERA_SPI_STATUS, &val); | |
| 201 | + if (val & ALTERA_SPI_STATUS_RRDY_MSK) | |
| 202 | + break; | |
| 203 | 203 | |
| 204 | − altera_spi_rx_word(hw); | |
| 204 | + cpu_relax(); | |
| 205 | 205 | } |
| 206 | − spi_finalize_current_transfer(master); | |
| 206 | + | |
| 207 | + altera_spi_rx_word(hw); | |
| 207 | 208 | } |
| 209 | + spi_finalize_current_transfer(master); | |
| 208 | 210 | |
| 209 | − return t->len; | |
| 211 | + return 0; | |
| 210 | 212 | } |
| 211 | 213 | |
| 212 | 214 | static irqreturn_t altera_spi_irq(int irq, void *dev) |
| @@ -115,6 +115,7 @@ struct cdns_spi { · 114 unmodified lines | ||
| 115 | 115 | void __iomem *regs; |
| 116 | 116 | struct clk *ref_clk; |
| 117 | 117 | struct clk *pclk; |
| 118 | + unsigned int clk_rate; | |
| 118 | 119 | u32 speed_hz; |
| 119 | 120 | const u8 *txbuf; |
| 120 | 121 | u8 *rxbuf; |
| @@ -250,7 +251,7 @@ static void cdns_spi_config_clock_freq(struct spi_device *spi, · 129 unmodified lines | ||
| 250 | 251 | u32 ctrl_reg, baud_rate_val; |
| 251 | 252 | unsigned long frequency; |
| 252 | 253 | |
| 253 | − frequency = clk_get_rate(xspi->ref_clk); | |
| 254 | + frequency = xspi->clk_rate; | |
| 254 | 255 | |
| 255 | 256 | ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR); |
| 256 | 257 | |
| @@ -558,8 +559,9 @@ static int cdns_spi_probe(struct platform_device *pdev) · 301 unmodified lines | ||
| 558 | 559 | master->auto_runtime_pm = true; |
| 559 | 560 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
| 560 | 561 | |
| 562 | + xspi->clk_rate = clk_get_rate(xspi->ref_clk); | |
| 561 | 563 | /* Set to default valid value */ |
| 562 | − master->max_speed_hz = clk_get_rate(xspi->ref_clk) / 4; | |
| 564 | + master->max_speed_hz = xspi->clk_rate / 4; | |
| 563 | 565 | xspi->speed_hz = master->max_speed_hz; |
| 564 | 566 | |
| 565 | 567 | master->bits_per_word_mask = SPI_BPW_MASK(8); |
| @@ -115,14 +115,13 @@ static void fsl_spi_chipselect(struct spi_device *spi, int value) · 114 unmodified lines | ||
| 115 | 115 | { |
| 116 | 116 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); |
| 117 | 117 | struct fsl_spi_platform_data *pdata; |
| 118 | − bool pol = spi->mode & SPI_CS_HIGH; | |
| 119 | 118 | struct spi_mpc8xxx_cs *cs = spi->controller_state; |
| 120 | 119 | |
| 121 | 120 | pdata = spi->dev.parent->parent->platform_data; |
| 122 | 121 | |
| 123 | 122 | if (value == BITBANG_CS_INACTIVE) { |
| 124 | 123 | if (pdata->cs_control) |
| 125 | − pdata->cs_control(spi, !pol); | |
| 124 | + pdata->cs_control(spi, false); | |
| 126 | 125 | } |
| 127 | 126 | |
| 128 | 127 | if (value == BITBANG_CS_ACTIVE) { |
| @@ -134,7 +133,7 @@ static void fsl_spi_chipselect(struct spi_device *spi, int value) · 5 unmodified lines | ||
| 134 | 133 | fsl_spi_change_mode(spi); |
| 135 | 134 | |
| 136 | 135 | if (pdata->cs_control) |
| 137 | − pdata->cs_control(spi, pol); | |
| 136 | + pdata->cs_control(spi, true); | |
| 138 | 137 | } |
| 139 | 138 | } |
| 140 | 139 | |
| @@ -83,6 +83,7 @@ struct spi_geni_master { · 82 unmodified lines | ||
| 83 | 83 | spinlock_t lock; |
| 84 | 84 | int irq; |
| 85 | 85 | bool cs_flag; |
| 86 | + bool abort_failed; | |
| 86 | 87 | }; |
| 87 | 88 | |
| 88 | 89 | static int get_spi_clk_cfg(unsigned int speed_hz, |
| @@ -141,8 +142,49 @@ static void handle_fifo_timeout(struct spi_master *spi, · 52 unmodified lines | ||
| 141 | 142 | spin_unlock_irq(&mas->lock); |
| 142 | 143 | |
| 143 | 144 | time_left = wait_for_completion_timeout(&mas->abort_done, HZ); |
| 144 | − if (!time_left) | |
| 145 | + if (!time_left) { | |
| 145 | 146 | dev_err(mas->dev, "Failed to cancel/abort m_cmd\n"); |
| 147 | + | |
| 148 | + /* | |
| 149 | + * No need for a lock since SPI core has a lock and we never | |
| 150 | + * access this from an interrupt. | |
| 151 | + */ | |
| 152 | + mas->abort_failed = true; | |
| 153 | + } | |
| 154 | +} | |
| 155 | + | |
| 156 | +static bool spi_geni_is_abort_still_pending(struct spi_geni_master *mas) | |
| 157 | +{ | |
| 158 | + struct geni_se *se = &mas->se; | |
| 159 | + u32 m_irq, m_irq_en; | |
| 160 | + | |
| 161 | + if (!mas->abort_failed) | |
| 162 | + return false; | |
| 163 | + | |
| 164 | + /* | |
| 165 | + * The only known case where a transfer times out and then a cancel | |
| 166 | + * times out then an abort times out is if something is blocking our | |
| 167 | + * interrupt handler from running. Avoid starting any new transfers | |
| 168 | + * until that sorts itself out. | |
| 169 | + */ | |
| 170 | + spin_lock_irq(&mas->lock); | |
| 171 | + m_irq = readl(se->base + SE_GENI_M_IRQ_STATUS); | |
| 172 | + m_irq_en = readl(se->base + SE_GENI_M_IRQ_EN); | |
| 173 | + spin_unlock_irq(&mas->lock); | |
| 174 | + | |
| 175 | + if (m_irq & m_irq_en) { | |
| 176 | + dev_err(mas->dev, "Interrupts pending after abort: %#010x\n", | |
| 177 | + m_irq & m_irq_en); | |
| 178 | + return true; | |
| 179 | + } | |
| 180 | + | |
| 181 | + /* | |
| 182 | + * If we're here the problem resolved itself so no need to check more | |
| 183 | + * on future transfers. | |
| 184 | + */ | |
| 185 | + mas->abort_failed = false; | |
| 186 | + | |
| 187 | + return false; | |
| 146 | 188 | } |
| 147 | 189 | |
| 148 | 190 | static void spi_geni_set_cs(struct spi_device *slv, bool set_flag) |
| @@ -158,10 +200,21 @@ static void spi_geni_set_cs(struct spi_device *slv, bool set_flag) · 9 unmodified lines | ||
| 158 | 200 | if (set_flag == mas->cs_flag) |
| 159 | 201 | return; |
| 160 | 202 | |
| 161 | − mas->cs_flag = set_flag; | |
| 162 | − | |
| 163 | 203 | pm_runtime_get_sync(mas->dev); |
| 204 | + | |
| 205 | + if (spi_geni_is_abort_still_pending(mas)) { | |
| 206 | + dev_err(mas->dev, "Can't set chip select\n"); | |
| 207 | + goto exit; | |
| 208 | + } | |
| 209 | + | |
| 164 | 210 | spin_lock_irq(&mas->lock); |
| 211 | + if (mas->cur_xfer) { | |
| 212 | + dev_err(mas->dev, "Can't set CS when prev xfer running\n"); | |
| 213 | + spin_unlock_irq(&mas->lock); | |
| 214 | + goto exit; | |
| 215 | + } | |
| 216 | + | |
| 217 | + mas->cs_flag = set_flag; | |
| 165 | 218 | reinit_completion(&mas->cs_done); |
| 166 | 219 | if (set_flag) |
| 167 | 220 | geni_se_setup_m_cmd(se, SPI_CS_ASSERT, 0); |
| @@ -170,9 +223,12 @@ static void spi_geni_set_cs(struct spi_device *slv, bool set_flag) · 2 unmodified lines | ||
| 170 | 223 | spin_unlock_irq(&mas->lock); |
| 171 | 224 | |
| 172 | 225 | time_left = wait_for_completion_timeout(&mas->cs_done, HZ); |
| 173 | − if (!time_left) | |
| 226 | + if (!time_left) { | |
| 227 | + dev_warn(mas->dev, "Timeout setting chip select\n"); | |
| 174 | 228 | handle_fifo_timeout(spi, NULL); |
| 229 | + } | |
| 175 | 230 | |
| 231 | +exit: | |
| 176 | 232 | pm_runtime_put(mas->dev); |
| 177 | 233 | } |
| 178 | 234 | |
| @@ -280,6 +336,9 @@ static int spi_geni_prepare_message(struct spi_master *spi, · 101 unmodified lines | ||
| 280 | 336 | int ret; |
| 281 | 337 | struct spi_geni_master *mas = spi_master_get_devdata(spi); |
| 282 | 338 | |
| 339 | + if (spi_geni_is_abort_still_pending(mas)) | |
| 340 | + return -EBUSY; | |
| 341 | + | |
| 283 | 342 | ret = setup_fifo_params(spi_msg->spi, spi); |
| 284 | 343 | if (ret) |
| 285 | 344 | dev_err(mas->dev, "Couldn't select mode %d\n", ret); |
| @@ -354,6 +413,12 @@ static bool geni_spi_handle_tx(struct spi_geni_master *mas) · 68 unmodified lines | ||
| 354 | 413 | unsigned int bytes_per_fifo_word = geni_byte_per_fifo_word(mas); |
| 355 | 414 | unsigned int i = 0; |
| 356 | 415 | |
| 416 | + /* Stop the watermark IRQ if nothing to send */ | |
| 417 | + if (!mas->cur_xfer) { | |
| 418 | + writel(0, se->base + SE_GENI_TX_WATERMARK_REG); | |
| 419 | + return false; | |
| 420 | + } | |
| 421 | + | |
| 357 | 422 | max_bytes = (mas->tx_fifo_depth - mas->tx_wm) * bytes_per_fifo_word; |
| 358 | 423 | if (mas->tx_rem_bytes < max_bytes) |
| 359 | 424 | max_bytes = mas->tx_rem_bytes; |
| @@ -396,6 +461,14 @@ static void geni_spi_handle_rx(struct spi_geni_master *mas) · 36 unmodified lines | ||
| 396 | 461 | if (rx_last_byte_valid && rx_last_byte_valid < 4) |
| 397 | 462 | rx_bytes -= bytes_per_fifo_word - rx_last_byte_valid; |
| 398 | 463 | } |
| 464 | + | |
| 465 | + /* Clear out the FIFO and bail if nowhere to put it */ | |
| 466 | + if (!mas->cur_xfer) { | |
| 467 | + for (i = 0; i < DIV_ROUND_UP(rx_bytes, bytes_per_fifo_word); i++) | |
| 468 | + readl(se->base + SE_GENI_RX_FIFOn); | |
| 469 | + return; | |
| 470 | + } | |
| 471 | + | |
| 399 | 472 | if (mas->rx_rem_bytes < rx_bytes) |
| 400 | 473 | rx_bytes = mas->rx_rem_bytes; |
| 401 | 474 | |
| @@ -495,6 +568,9 @@ static int spi_geni_transfer_one(struct spi_master *spi, · 93 unmodified lines | ||
| 495 | 568 | { |
| 496 | 569 | struct spi_geni_master *mas = spi_master_get_devdata(spi); |
| 497 | 570 | |
| 571 | + if (spi_geni_is_abort_still_pending(mas)) | |
| 572 | + return -EBUSY; | |
| 573 | + | |
| 498 | 574 | /* Terminate and return success for 0 byte length transfer */ |
| 499 | 575 | if (!xfer->len) |
| 500 | 576 | return 0; |
| @@ -493,9 +493,9 @@ static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi, u32 xfer_len) · 492 unmodified lines | ||
| 493 | 493 | |
| 494 | 494 | /* align packet size with data registers access */ |
| 495 | 495 | if (spi->cur_bpw > 8) |
| 496 | − fthlv -= (fthlv % 2); /* multiple of 2 */ | |
| 496 | + fthlv += (fthlv % 2) ? 1 : 0; | |
| 497 | 497 | else |
| 498 | − fthlv -= (fthlv % 4); /* multiple of 4 */ | |
| 498 | + fthlv += (fthlv % 4) ? (4 - (fthlv % 4)) : 0; | |
| 499 | 499 | |
| 500 | 500 | if (!fthlv) |
| 501 | 501 | fthlv = 1; |
| @@ -1108,6 +1108,7 @@ static int spi_transfer_wait(struct spi_controller *ctlr, · 1107 unmodified lines | ||
| 1108 | 1108 | { |
| 1109 | 1109 | struct spi_statistics *statm = &ctlr->statistics; |
| 1110 | 1110 | struct spi_statistics *stats = &msg->spi->statistics; |
| 1111 | + u32 speed_hz = xfer->speed_hz; | |
| 1111 | 1112 | unsigned long long ms; |
| 1112 | 1113 | |
| 1113 | 1114 | if (spi_controller_is_slave(ctlr)) { |
| @@ -1116,8 +1117,11 @@ static int spi_transfer_wait(struct spi_controller *ctlr, · 2 unmodified lines | ||
| 1116 | 1117 | return -EINTR; |
| 1117 | 1118 | } |
| 1118 | 1119 | } else { |
| 1120 | + if (!speed_hz) | |
| 1121 | + speed_hz = 100000; | |
| 1122 | + | |
| 1119 | 1123 | ms = 8LL * 1000LL * xfer->len; |
| 1120 | − do_div(ms, xfer->speed_hz); | |
| 1124 | + do_div(ms, speed_hz); | |
| 1121 | 1125 | ms += ms + 200; /* some tolerance */ |
| 1122 | 1126 | |
| 1123 | 1127 | if (ms > UINT_MAX) |
| @@ -3378,8 +3382,9 @@ int spi_setup(struct spi_device *spi) · 2254 unmodified lines | ||
| 3378 | 3382 | if (status) |
| 3379 | 3383 | return status; |
| 3380 | 3384 | |
| 3381 | − if (!spi->max_speed_hz || | |
| 3382 | − spi->max_speed_hz > spi->controller->max_speed_hz) | |
| 3385 | + if (spi->controller->max_speed_hz && | |
| 3386 | + (!spi->max_speed_hz || | |
| 3387 | + spi->max_speed_hz > spi->controller->max_speed_hz)) | |
| 3383 | 3388 | spi->max_speed_hz = spi->controller->max_speed_hz; |
| 3384 | 3389 | |
| 3385 | 3390 | mutex_lock(&spi->controller->io_mutex); |
| @@ -2987,7 +2987,9 @@ static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32, · 2986 unmodified lines | ||
| 2987 | 2987 | v32.chanlist_len = cmd->chanlist_len; |
| 2988 | 2988 | v32.data = ptr_to_compat(cmd->data); |
| 2989 | 2989 | v32.data_len = cmd->data_len; |
| 2990 | − return copy_to_user(cmd32, &v32, sizeof(v32)); | |
| 2990 | + if (copy_to_user(cmd32, &v32, sizeof(v32))) | |
| 2991 | + return -EFAULT; | |
| 2992 | + return 0; | |
| 2991 | 2993 | } |
| 2992 | 2994 | |
| 2993 | 2995 | /* Handle 32-bit COMEDI_CMD ioctl. */ |
| @@ -278,21 +278,24 @@ static int spmi_controller_probe(struct platform_device *pdev) · 277 unmodified lines | ||
| 278 | 278 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 279 | 279 | if (!iores) { |
| 280 | 280 | dev_err(&pdev->dev, "can not get resource!\n"); |
| 281 | − return -EINVAL; | |
| 281 | + ret = -EINVAL; | |
| 282 | + goto err_put_controller; | |
| 282 | 283 | } |
| 283 | 284 | |
| 284 | 285 | spmi_controller->base = devm_ioremap(&pdev->dev, iores->start, |
| 285 | 286 | resource_size(iores)); |
| 286 | 287 | if (!spmi_controller->base) { |
| 287 | 288 | dev_err(&pdev->dev, "can not remap base addr!\n"); |
| 288 | − return -EADDRNOTAVAIL; | |
| 289 | + ret = -EADDRNOTAVAIL; | |
| 290 | + goto err_put_controller; | |
| 289 | 291 | } |
| 290 | 292 | |
| 291 | 293 | ret = of_property_read_u32(pdev->dev.of_node, "spmi-channel", |
| 292 | 294 | &spmi_controller->channel); |
| 293 | 295 | if (ret) { |
| 294 | 296 | dev_err(&pdev->dev, "can not get channel\n"); |
| 295 | − return -ENODEV; | |
| 297 | + ret = -ENODEV; | |
| 298 | + goto err_put_controller; | |
| 296 | 299 | } |
| 297 | 300 | |
| 298 | 301 | platform_set_drvdata(pdev, spmi_controller); |
| @@ -309,9 +312,15 @@ static int spmi_controller_probe(struct platform_device *pdev) · 10 unmodified lines | ||
| 309 | 312 | ctrl->write_cmd = spmi_write_cmd; |
| 310 | 313 | |
| 311 | 314 | ret = spmi_controller_add(ctrl); |
| 312 | − if (ret) | |
| 313 | − dev_err(&pdev->dev, "spmi_add_controller failed with error %d!\n", ret); | |
| 315 | + if (ret) { | |
| 316 | + dev_err(&pdev->dev, "spmi_controller_add failed with error %d!\n", ret); | |
| 317 | + goto err_put_controller; | |
| 318 | + } | |
| 319 | + | |
| 320 | + return 0; | |
| 314 | 321 | |
| 322 | +err_put_controller: | |
| 323 | + spmi_controller_put(ctrl); | |
| 315 | 324 | return ret; |
| 316 | 325 | } |
| 317 | 326 | |
| @@ -320,7 +329,7 @@ static int spmi_del_controller(struct platform_device *pdev) · 2 unmodified lines | ||
| 320 | 329 | struct spmi_controller *ctrl = platform_get_drvdata(pdev); |
| 321 | 330 | |
| 322 | 331 | spmi_controller_remove(ctrl); |
| 323 | − kfree(ctrl); | |
| 332 | + spmi_controller_put(ctrl); | |
| 324 | 333 | return 0; |
| 325 | 334 | } |
| 326 | 335 | |
| @@ -1062,26 +1062,6 @@ static const struct v4l2_ctrl_config ctrl_select_isp_version = { · 1061 unmodified lines | ||
| 1062 | 1062 | .def = 0, |
| 1063 | 1063 | }; |
| 1064 | 1064 | |
| 1065 | −#if 0 /* #ifdef CONFIG_ION */ | |
| 1066 | −/* | |
| 1067 | − * Control for ISP ion device fd | |
| 1068 | − * | |
| 1069 | − * userspace will open ion device and pass the fd to kernel. | |
| 1070 | − * this fd will be used to map shared fd to buffer. | |
| 1071 | − */ | |
| 1072 | −/* V4L2_CID_ATOMISP_ION_DEVICE_FD is not defined */ | |
| 1073 | −static const struct v4l2_ctrl_config ctrl_ion_dev_fd = { | |
| 1074 | − .ops = &ctrl_ops, | |
| 1075 | − .id = V4L2_CID_ATOMISP_ION_DEVICE_FD, | |
| 1076 | − .type = V4L2_CTRL_TYPE_INTEGER, | |
| 1077 | − .name = "Ion Device Fd", | |
| 1078 | − .min = -1, | |
| 1079 | − .max = 1024, | |
| 1080 | − .step = 1, | |
| 1081 | − .def = ION_FD_UNSET | |
| 1082 | −}; | |
| 1083 | −#endif | |
| 1084 | − | |
| 1085 | 1065 | static void atomisp_init_subdev_pipe(struct atomisp_sub_device *asd, |
| 1086 | 1066 | struct atomisp_video_pipe *pipe, enum v4l2_buf_type buf_type) |
| 1087 | 1067 | { |
| @@ -712,7 +712,7 @@ static int mtk_hsdma_probe(struct platform_device *pdev) · 711 unmodified lines | ||
| 712 | 712 | ret = dma_async_device_register(dd); |
| 713 | 713 | if (ret) { |
| 714 | 714 | dev_err(&pdev->dev, "failed to register dma device\n"); |
| 715 | − return ret; | |
| 715 | + goto err_uninit_hsdma; | |
| 716 | 716 | } |
| 717 | 717 | |
| 718 | 718 | ret = of_dma_controller_register(pdev->dev.of_node, |
| @@ -728,6 +728,8 @@ static int mtk_hsdma_probe(struct platform_device *pdev) · 9 unmodified lines | ||
| 728 | 728 | |
| 729 | 729 | err_unregister: |
| 730 | 730 | dma_async_device_unregister(dd); |
| 731 | +err_uninit_hsdma: | |
| 732 | + mtk_hsdma_uninit(hsdma); | |
| 731 | 733 | return ret; |
| 732 | 734 | } |
| 733 | 735 | |
| @@ -46,60 +46,83 @@ static int target_xcopy_gen_naa_ieee(struct se_device *dev, unsigned char *buf) · 45 unmodified lines | ||
| 46 | 46 | return 0; |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | −struct xcopy_dev_search_info { | |
| 50 | − const unsigned char *dev_wwn; | |
| 51 | − struct se_device *found_dev; | |
| 52 | −}; | |
| 53 | − | |
| 49 | +/** | |
| 50 | + * target_xcopy_locate_se_dev_e4_iter - compare XCOPY NAA device identifiers | |
| 51 | + * | |
| 52 | + * @se_dev: device being considered for match | |
| 53 | + * @dev_wwn: XCOPY requested NAA dev_wwn | |
| 54 | + * @return: 1 on match, 0 on no-match | |
| 55 | + */ | |
| 54 | 56 | static int target_xcopy_locate_se_dev_e4_iter(struct se_device *se_dev, |
| 55 | − void *data) | |
| 57 | + const unsigned char *dev_wwn) | |
| 56 | 58 | { |
| 57 | − struct xcopy_dev_search_info *info = data; | |
| 58 | 59 | unsigned char tmp_dev_wwn[XCOPY_NAA_IEEE_REGEX_LEN]; |
| 59 | 60 | int rc; |
| 60 | 61 | |
| 61 | − if (!se_dev->dev_attrib.emulate_3pc) | |
| 62 | + if (!se_dev->dev_attrib.emulate_3pc) { | |
| 63 | + pr_debug("XCOPY: emulate_3pc disabled on se_dev %p\n", se_dev); | |
| 62 | 64 | return 0; |
| 65 | + } | |
| 63 | 66 | |
| 64 | 67 | memset(&tmp_dev_wwn[0], 0, XCOPY_NAA_IEEE_REGEX_LEN); |
| 65 | 68 | target_xcopy_gen_naa_ieee(se_dev, &tmp_dev_wwn[0]); |
| 66 | 69 | |
| 67 | − rc = memcmp(&tmp_dev_wwn[0], info->dev_wwn, XCOPY_NAA_IEEE_REGEX_LEN); | |
| 68 | − if (rc != 0) | |
| 69 | − return 0; | |
| 70 | − | |
| 71 | − info->found_dev = se_dev; | |
| 72 | − pr_debug("XCOPY 0xe4: located se_dev: %p\n", se_dev); | |
| 73 | − | |
| 74 | − rc = target_depend_item(&se_dev->dev_group.cg_item); | |
| 70 | + rc = memcmp(&tmp_dev_wwn[0], dev_wwn, XCOPY_NAA_IEEE_REGEX_LEN); | |
| 75 | 71 | if (rc != 0) { |
| 76 | − pr_err("configfs_depend_item attempt failed: %d for se_dev: %p\n", | |
| 77 | − rc, se_dev); | |
| 78 | − return rc; | |
| 72 | + pr_debug("XCOPY: skip non-matching: %*ph\n", | |
| 73 | + XCOPY_NAA_IEEE_REGEX_LEN, tmp_dev_wwn); | |
| 74 | + return 0; | |
| 79 | 75 | } |
| 76 | + pr_debug("XCOPY 0xe4: located se_dev: %p\n", se_dev); | |
| 80 | 77 | |
| 81 | − pr_debug("Called configfs_depend_item for se_dev: %p se_dev->se_dev_group: %p\n", | |
| 82 | − se_dev, &se_dev->dev_group); | |
| 83 | 78 | return 1; |
| 84 | 79 | } |
| 85 | 80 | |
| 86 | −static int target_xcopy_locate_se_dev_e4(const unsigned char *dev_wwn, | |
| 87 | − struct se_device **found_dev) | |
| 81 | +static int target_xcopy_locate_se_dev_e4(struct se_session *sess, | |
| 82 | + const unsigned char *dev_wwn, | |
| 83 | + struct se_device **_found_dev, | |
| 84 | + struct percpu_ref **_found_lun_ref) | |
| 88 | 85 | { |
| 89 | − struct xcopy_dev_search_info info; | |
| 90 | − int ret; | |
| 91 | − | |
| 92 | − memset(&info, 0, sizeof(info)); | |
| 93 | − info.dev_wwn = dev_wwn; | |
| 94 | − | |
| 95 | − ret = target_for_each_device(target_xcopy_locate_se_dev_e4_iter, &info); | |
| 96 | − if (ret == 1) { | |
| 97 | − *found_dev = info.found_dev; | |
| 98 | − return 0; | |
| 99 | − } else { | |
| 100 | − pr_debug_ratelimited("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n"); | |
| 101 | − return -EINVAL; | |
| 86 | + struct se_dev_entry *deve; | |
| 87 | + struct se_node_acl *nacl; | |
| 88 | + struct se_lun *this_lun = NULL; | |
| 89 | + struct se_device *found_dev = NULL; | |
| 90 | + | |
| 91 | + /* cmd with NULL sess indicates no associated $FABRIC_MOD */ | |
| 92 | + if (!sess) | |
| 93 | + goto err_out; | |
| 94 | + | |
| 95 | + pr_debug("XCOPY 0xe4: searching for: %*ph\n", | |
| 96 | + XCOPY_NAA_IEEE_REGEX_LEN, dev_wwn); | |
| 97 | + | |
| 98 | + nacl = sess->se_node_acl; | |
| 99 | + rcu_read_lock(); | |
| 100 | + hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) { | |
| 101 | + struct se_device *this_dev; | |
| 102 | + int rc; | |
| 103 | + | |
| 104 | + this_lun = rcu_dereference(deve->se_lun); | |
| 105 | + this_dev = rcu_dereference_raw(this_lun->lun_se_dev); | |
| 106 | + | |
| 107 | + rc = target_xcopy_locate_se_dev_e4_iter(this_dev, dev_wwn); | |
| 108 | + if (rc) { | |
| 109 | + if (percpu_ref_tryget_live(&this_lun->lun_ref)) | |
| 110 | + found_dev = this_dev; | |
| 111 | + break; | |
| 112 | + } | |
| 102 | 113 | } |
| 114 | + rcu_read_unlock(); | |
| 115 | + if (found_dev == NULL) | |
| 116 | + goto err_out; | |
| 117 | + | |
| 118 | + pr_debug("lun_ref held for se_dev: %p se_dev->se_dev_group: %p\n", | |
| 119 | + found_dev, &found_dev->dev_group); | |
| 120 | + *_found_dev = found_dev; | |
| 121 | + *_found_lun_ref = &this_lun->lun_ref; | |
| 122 | + return 0; | |
| 123 | +err_out: | |
| 124 | + pr_debug_ratelimited("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n"); | |
| 125 | + return -EINVAL; | |
| 103 | 126 | } |
| 104 | 127 | |
| 105 | 128 | static int target_xcopy_parse_tiddesc_e4(struct se_cmd *se_cmd, struct xcopy_op *xop, |
| @@ -246,12 +269,16 @@ static int target_xcopy_parse_target_descriptors(struct se_cmd *se_cmd, · 140 unmodified lines | ||
| 246 | 269 | |
| 247 | 270 | switch (xop->op_origin) { |
| 248 | 271 | case XCOL_SOURCE_RECV_OP: |
| 249 | − rc = target_xcopy_locate_se_dev_e4(xop->dst_tid_wwn, | |
| 250 | − &xop->dst_dev); | |
| 272 | + rc = target_xcopy_locate_se_dev_e4(se_cmd->se_sess, | |
| 273 | + xop->dst_tid_wwn, | |
| 274 | + &xop->dst_dev, | |
| 275 | + &xop->remote_lun_ref); | |
| 251 | 276 | break; |
| 252 | 277 | case XCOL_DEST_RECV_OP: |
| 253 | − rc = target_xcopy_locate_se_dev_e4(xop->src_tid_wwn, | |
| 254 | − &xop->src_dev); | |
| 278 | + rc = target_xcopy_locate_se_dev_e4(se_cmd->se_sess, | |
| 279 | + xop->src_tid_wwn, | |
| 280 | + &xop->src_dev, | |
| 281 | + &xop->remote_lun_ref); | |
| 255 | 282 | break; |
| 256 | 283 | default: |
| 257 | 284 | pr_err("XCOPY CSCD descriptor IDs not found in CSCD list - " |
| @@ -391,18 +418,12 @@ static int xcopy_pt_get_cmd_state(struct se_cmd *se_cmd) · 133 unmodified lines | ||
| 391 | 418 | |
| 392 | 419 | static void xcopy_pt_undepend_remotedev(struct xcopy_op *xop) |
| 393 | 420 | { |
| 394 | − struct se_device *remote_dev; | |
| 395 | − | |
| 396 | 421 | if (xop->op_origin == XCOL_SOURCE_RECV_OP) |
| 397 | − remote_dev = xop->dst_dev; | |
| 422 | + pr_debug("putting dst lun_ref for %p\n", xop->dst_dev); | |
| 398 | 423 | else |
| 399 | − remote_dev = xop->src_dev; | |
| 400 | − | |
| 401 | − pr_debug("Calling configfs_undepend_item for" | |
| 402 | − " remote_dev: %p remote_dev->dev_group: %p\n", | |
| 403 | − remote_dev, &remote_dev->dev_group.cg_item); | |
| 424 | + pr_debug("putting src lun_ref for %p\n", xop->src_dev); | |
| 404 | 425 | |
| 405 | − target_undepend_item(&remote_dev->dev_group.cg_item); | |
| 426 | + percpu_ref_put(xop->remote_lun_ref); | |
| 406 | 427 | } |
| 407 | 428 | |
| 408 | 429 | static void xcopy_pt_release_cmd(struct se_cmd *se_cmd) |
| @@ -27,6 +27,7 @@ struct xcopy_op { · 26 unmodified lines | ||
| 27 | 27 | struct se_device *dst_dev; |
| 28 | 28 | unsigned char dst_tid_wwn[XCOPY_NAA_IEEE_REGEX_LEN]; |
| 29 | 29 | unsigned char local_dev_wwn[XCOPY_NAA_IEEE_REGEX_LEN]; |
| 30 | + struct percpu_ref *remote_lun_ref; | |
| 30 | 31 | |
| 31 | 32 | sector_t src_lba; |
| 32 | 33 | sector_t dst_lba; |
| @@ -401,6 +401,20 @@ config MIPS_EJTAG_FDC_KGDB_CHAN · 400 unmodified lines | ||
| 401 | 401 | help |
| 402 | 402 | FDC channel number to use for KGDB. |
| 403 | 403 | |
| 404 | +config NULL_TTY | |
| 405 | + tristate "NULL TTY driver" | |
| 406 | + help | |
| 407 | + Say Y here if you want a NULL TTY which simply discards messages. | |
| 408 | + | |
| 409 | + This is useful to allow userspace applications which expect a console | |
| 410 | + device to work without modifications even when no console is | |
| 411 | + available or desired. | |
| 412 | + | |
| 413 | + In order to use this driver, you should redirect the console to this | |
| 414 | + TTY, or boot the kernel with console=ttynull. | |
| 415 | + | |
| 416 | + If unsure, say N. | |
| 417 | + | |
| 404 | 418 | config TRACE_ROUTER |
| 405 | 419 | tristate "Trace data router for MIPI P1149.7 cJTAG standard" |
| 406 | 420 | depends on TRACE_SINK |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | obj-$(CONFIG_TTY) += tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \ |
| 3 | 3 | tty_buffer.o tty_port.o tty_mutex.o \ |
| 4 | 4 | tty_ldsem.o tty_baudrate.o tty_jobctrl.o \ |
| 5 | − n_null.o ttynull.o | |
| 5 | + n_null.o | |
| 6 | 6 | obj-$(CONFIG_LEGACY_PTYS) += pty.o |
| 7 | 7 | obj-$(CONFIG_UNIX98_PTYS) += pty.o |
| 8 | 8 | obj-$(CONFIG_AUDIT) += tty_audit.o |
| @@ -25,6 +25,7 @@ obj-$(CONFIG_ISI) += isicom.o · 16 unmodified lines | ||
| 25 | 25 | obj-$(CONFIG_MOXA_INTELLIO) += moxa.o |
| 26 | 26 | obj-$(CONFIG_MOXA_SMARTIO) += mxser.o |
| 27 | 27 | obj-$(CONFIG_NOZOMI) += nozomi.o |
| 28 | +obj-$(CONFIG_NULL_TTY) += ttynull.o | |
| 28 | 29 | obj-$(CONFIG_ROCKETPORT) += rocket.o |
| 29 | 30 | obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o |
| 30 | 31 | obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o |
| @@ -1000,6 +1000,7 @@ static int sifive_serial_probe(struct platform_device *pdev) · 999 unmodified lines | ||
| 1000 | 1000 | /* Set up clock divider */ |
| 1001 | 1001 | ssp->clkin_rate = clk_get_rate(ssp->clk); |
| 1002 | 1002 | ssp->baud_rate = SIFIVE_DEFAULT_BAUD_RATE; |
| 1003 | + ssp->port.uartclk = ssp->baud_rate * 16; | |
| 1003 | 1004 | __ssp_update_div(ssp); |
| 1004 | 1005 | |
| 1005 | 1006 | platform_set_drvdata(pdev, ssp); |
| @@ -2,13 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | /* |
| 3 | 3 | * Copyright (C) 2019 Axis Communications AB |
| 4 | 4 | * |
| 5 | − * The console is useful for userspace applications which expect a console | |
| 6 | − * device to work without modifications even when no console is available | |
| 7 | − * or desired. | |
| 8 | − * | |
| 9 | − * In order to use this driver, you should redirect the console to this | |
| 10 | − * TTY, or boot the kernel with console=ttynull. | |
| 11 | − * | |
| 12 | 5 | * Based on ttyprintk.c: |
| 13 | 6 | * Copyright (C) 2010 Samo Pogacnik |
| 14 | 7 | */ |
| @@ -66,17 +59,6 @@ static struct console ttynull_console = { · 51 unmodified lines | ||
| 66 | 59 | .device = ttynull_device, |
| 67 | 60 | }; |
| 68 | 61 | |
| 69 | −void __init register_ttynull_console(void) | |
| 70 | −{ | |
| 71 | − if (!ttynull_driver) | |
| 72 | − return; | |
| 73 | − | |
| 74 | − if (add_preferred_console(ttynull_console.name, 0, NULL)) | |
| 75 | − return; | |
| 76 | − | |
| 77 | − register_console(&ttynull_console); | |
| 78 | −} | |
| 79 | − | |
| 80 | 62 | static int __init ttynull_init(void) |
| 81 | 63 | { |
| 82 | 64 | struct tty_driver *driver; |
| @@ -139,9 +139,13 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev) · 138 unmodified lines | ||
| 139 | 139 | misc_pdev = of_find_device_by_node(args.np); |
| 140 | 140 | of_node_put(args.np); |
| 141 | 141 | |
| 142 | − if (!misc_pdev || !platform_get_drvdata(misc_pdev)) | |
| 142 | + if (!misc_pdev) | |
| 143 | 143 | return ERR_PTR(-EPROBE_DEFER); |
| 144 | 144 | |
| 145 | + if (!platform_get_drvdata(misc_pdev)) { | |
| 146 | + put_device(&misc_pdev->dev); | |
| 147 | + return ERR_PTR(-EPROBE_DEFER); | |
| 148 | + } | |
| 145 | 149 | data->dev = &misc_pdev->dev; |
| 146 | 150 | |
| 147 | 151 | /* |
| @@ -1895,6 +1895,10 @@ static const struct usb_device_id acm_ids[] = { · 1894 unmodified lines | ||
| 1895 | 1895 | { USB_DEVICE(0x04d8, 0xfd08), |
| 1896 | 1896 | .driver_info = IGNORE_DEVICE, |
| 1897 | 1897 | }, |
| 1898 | + | |
| 1899 | + { USB_DEVICE(0x04d8, 0xf58b), | |
| 1900 | + .driver_info = IGNORE_DEVICE, | |
| 1901 | + }, | |
| 1898 | 1902 | #endif |
| 1899 | 1903 | |
| 1900 | 1904 | /*Samsung phone in firmware update mode */ |
| @@ -465,13 +465,23 @@ static int service_outstanding_interrupt(struct wdm_device *desc) · 464 unmodified lines | ||
| 465 | 465 | if (!desc->resp_count || !--desc->resp_count) |
| 466 | 466 | goto out; |
| 467 | 467 | |
| 468 | + if (test_bit(WDM_DISCONNECTING, &desc->flags)) { | |
| 469 | + rv = -ENODEV; | |
| 470 | + goto out; | |
| 471 | + } | |
| 472 | + if (test_bit(WDM_RESETTING, &desc->flags)) { | |
| 473 | + rv = -EIO; | |
| 474 | + goto out; | |
| 475 | + } | |
| 476 | + | |
| 468 | 477 | set_bit(WDM_RESPONDING, &desc->flags); |
| 469 | 478 | spin_unlock_irq(&desc->iuspin); |
| 470 | 479 | rv = usb_submit_urb(desc->response, GFP_KERNEL); |
| 471 | 480 | spin_lock_irq(&desc->iuspin); |
| 472 | 481 | if (rv) { |
| 473 | − dev_err(&desc->intf->dev, | |
| 474 | − "usb_submit_urb failed with result %d\n", rv); | |
| 482 | + if (!test_bit(WDM_DISCONNECTING, &desc->flags)) | |
| 483 | + dev_err(&desc->intf->dev, | |
| 484 | + "usb_submit_urb failed with result %d\n", rv); | |
| 475 | 485 | |
| 476 | 486 | /* make sure the next notification trigger a submit */ |
| 477 | 487 | clear_bit(WDM_RESPONDING, &desc->flags); |
| @@ -1027,9 +1037,9 @@ static void wdm_disconnect(struct usb_interface *intf) · 549 unmodified lines | ||
| 1027 | 1037 | wake_up_all(&desc->wait); |
| 1028 | 1038 | mutex_lock(&desc->rlock); |
| 1029 | 1039 | mutex_lock(&desc->wlock); |
| 1030 | − kill_urbs(desc); | |
| 1031 | 1040 | cancel_work_sync(&desc->rxwork); |
| 1032 | 1041 | cancel_work_sync(&desc->service_outs_intr); |
| 1042 | + kill_urbs(desc); | |
| 1033 | 1043 | mutex_unlock(&desc->wlock); |
| 1034 | 1044 | mutex_unlock(&desc->rlock); |
| 1035 | 1045 | |
| @@ -274,8 +274,25 @@ static int usblp_ctrl_msg(struct usblp *usblp, int request, int type, int dir, i · 273 unmodified lines | ||
| 274 | 274 | #define usblp_reset(usblp)\ |
| 275 | 275 | usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_TYPE_CLASS, USB_DIR_OUT, USB_RECIP_OTHER, 0, NULL, 0) |
| 276 | 276 | |
| 277 | −#define usblp_hp_channel_change_request(usblp, channel, buffer) \ | |
| 278 | − usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE, channel, buffer, 1) | |
| 277 | +static int usblp_hp_channel_change_request(struct usblp *usblp, int channel, u8 *new_channel) | |
| 278 | +{ | |
| 279 | + u8 *buf; | |
| 280 | + int ret; | |
| 281 | + | |
| 282 | + buf = kzalloc(1, GFP_KERNEL); | |
| 283 | + if (!buf) | |
| 284 | + return -ENOMEM; | |
| 285 | + | |
| 286 | + ret = usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, | |
| 287 | + USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE, | |
| 288 | + channel, buf, 1); | |
| 289 | + if (ret == 0) | |
| 290 | + *new_channel = buf[0]; | |
| 291 | + | |
| 292 | + kfree(buf); | |
| 293 | + | |
| 294 | + return ret; | |
| 295 | +} | |
| 279 | 296 | |
| 280 | 297 | /* |
| 281 | 298 | * See the description for usblp_select_alts() below for the usage |
| @@ -1649,14 +1649,12 @@ static void __usb_hcd_giveback_urb(struct urb *urb) · 1648 unmodified lines | ||
| 1649 | 1649 | urb->status = status; |
| 1650 | 1650 | /* |
| 1651 | 1651 | * This function can be called in task context inside another remote |
| 1652 | − * coverage collection section, but KCOV doesn't support that kind of | |
| 1652 | + * coverage collection section, but kcov doesn't support that kind of | |
| 1653 | 1653 | * recursion yet. Only collect coverage in softirq context for now. |
| 1654 | 1654 | */ |
| 1655 | − if (in_serving_softirq()) | |
| 1656 | − kcov_remote_start_usb((u64)urb->dev->bus->busnum); | |
| 1655 | + kcov_remote_start_usb_softirq((u64)urb->dev->bus->busnum); | |
| 1657 | 1656 | urb->complete(urb); |
| 1658 | − if (in_serving_softirq()) | |
| 1659 | − kcov_remote_stop(); | |
| 1657 | + kcov_remote_stop_softirq(); | |
| 1660 | 1658 | |
| 1661 | 1659 | usb_anchor_resume_wakeups(anchor); |
| 1662 | 1660 | atomic_dec(&urb->use_count); |
| @@ -285,6 +285,7 @@ · 284 unmodified lines | ||
| 285 | 285 | |
| 286 | 286 | /* Global USB2 PHY Vendor Control Register */ |
| 287 | 287 | #define DWC3_GUSB2PHYACC_NEWREGREQ BIT(25) |
| 288 | +#define DWC3_GUSB2PHYACC_DONE BIT(24) | |
| 288 | 289 | #define DWC3_GUSB2PHYACC_BUSY BIT(23) |
| 289 | 290 | #define DWC3_GUSB2PHYACC_WRITE BIT(22) |
| 290 | 291 | #define DWC3_GUSB2PHYACC_ADDR(n) (n << 16) |
| @@ -754,7 +754,7 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev) · 753 unmodified lines | ||
| 754 | 754 | |
| 755 | 755 | ret = priv->drvdata->setup_regmaps(priv, base); |
| 756 | 756 | if (ret) |
| 757 | − return ret; | |
| 757 | + goto err_disable_clks; | |
| 758 | 758 | |
| 759 | 759 | if (priv->vbus) { |
| 760 | 760 | ret = regulator_enable(priv->vbus); |
| @@ -1763,6 +1763,8 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, · 1762 unmodified lines | ||
| 1763 | 1763 | list_for_each_entry_safe(r, t, &dep->started_list, list) |
| 1764 | 1764 | dwc3_gadget_move_cancelled_request(r); |
| 1765 | 1765 | |
| 1766 | + dep->flags &= ~DWC3_EP_WAIT_TRANSFER_COMPLETE; | |
| 1767 | + | |
| 1766 | 1768 | goto out; |
| 1767 | 1769 | } |
| 1768 | 1770 | } |
| @@ -2083,6 +2085,7 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend) · 314 unmodified lines | ||
| 2083 | 2085 | |
| 2084 | 2086 | static void dwc3_gadget_disable_irq(struct dwc3 *dwc); |
| 2085 | 2087 | static void __dwc3_gadget_stop(struct dwc3 *dwc); |
| 2088 | +static int __dwc3_gadget_start(struct dwc3 *dwc); | |
| 2086 | 2089 | |
| 2087 | 2090 | static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) |
| 2088 | 2091 | { |
| @@ -2145,6 +2148,8 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) · 56 unmodified lines | ||
| 2145 | 2148 | dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % |
| 2146 | 2149 | dwc->ev_buf->length; |
| 2147 | 2150 | } |
| 2151 | + } else { | |
| 2152 | + __dwc3_gadget_start(dwc); | |
| 2148 | 2153 | } |
| 2149 | 2154 | |
| 2150 | 2155 | ret = dwc3_gadget_run_stop(dwc, is_on, false); |
| @@ -2319,10 +2324,6 @@ static int dwc3_gadget_start(struct usb_gadget *g, · 168 unmodified lines | ||
| 2319 | 2324 | } |
| 2320 | 2325 | |
| 2321 | 2326 | dwc->gadget_driver = driver; |
| 2322 | − | |
| 2323 | − if (pm_runtime_active(dwc->dev)) | |
| 2324 | − __dwc3_gadget_start(dwc); | |
| 2325 | − | |
| 2326 | 2327 | spin_unlock_irqrestore(&dwc->lock, flags); |
| 2327 | 2328 | |
| 2328 | 2329 | return 0; |
| @@ -2348,13 +2349,6 @@ static int dwc3_gadget_stop(struct usb_gadget *g) · 19 unmodified lines | ||
| 2348 | 2349 | unsigned long flags; |
| 2349 | 2350 | |
| 2350 | 2351 | spin_lock_irqsave(&dwc->lock, flags); |
| 2351 | − | |
| 2352 | − if (pm_runtime_suspended(dwc->dev)) | |
| 2353 | − goto out; | |
| 2354 | − | |
| 2355 | − __dwc3_gadget_stop(dwc); | |
| 2356 | − | |
| 2357 | −out: | |
| 2358 | 2352 | dwc->gadget_driver = NULL; |
| 2359 | 2353 | spin_unlock_irqrestore(&dwc->lock, flags); |
| 2360 | 2354 | |
| @@ -7,6 +7,8 @@ · 6 unmodified lines | ||
| 7 | 7 | * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com> |
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | +#include <linux/delay.h> | |
| 11 | +#include <linux/time64.h> | |
| 10 | 12 | #include <linux/ulpi/regs.h> |
| 11 | 13 | |
| 12 | 14 | #include "core.h" |
| @@ -17,14 +19,28 @@ · 4 unmodified lines | ||
| 17 | 19 | DWC3_GUSB2PHYACC_ADDR(ULPI_ACCESS_EXTENDED) | \ |
| 18 | 20 | DWC3_GUSB2PHYACC_EXTEND_ADDR(a) : DWC3_GUSB2PHYACC_ADDR(a)) |
| 19 | 21 | |
| 20 | −static int dwc3_ulpi_busyloop(struct dwc3 *dwc) | |
| 22 | +#define DWC3_ULPI_BASE_DELAY DIV_ROUND_UP(NSEC_PER_SEC, 60000000L) | |
| 23 | + | |
| 24 | +static int dwc3_ulpi_busyloop(struct dwc3 *dwc, u8 addr, bool read) | |
| 21 | 25 | { |
| 22 | − unsigned int count = 1000; | |
| 26 | + unsigned long ns = 5L * DWC3_ULPI_BASE_DELAY; | |
| 27 | + unsigned int count = 10000; | |
| 23 | 28 | u32 reg; |
| 24 | 29 | |
| 30 | + if (addr >= ULPI_EXT_VENDOR_SPECIFIC) | |
| 31 | + ns += DWC3_ULPI_BASE_DELAY; | |
| 32 | + | |
| 33 | + if (read) | |
| 34 | + ns += DWC3_ULPI_BASE_DELAY; | |
| 35 | + | |
| 36 | + reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); | |
| 37 | + if (reg & DWC3_GUSB2PHYCFG_SUSPHY) | |
| 38 | + usleep_range(1000, 1200); | |
| 39 | + | |
| 25 | 40 | while (count--) { |
| 41 | + ndelay(ns); | |
| 26 | 42 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0)); |
| 27 | − if (!(reg & DWC3_GUSB2PHYACC_BUSY)) | |
| 43 | + if (reg & DWC3_GUSB2PHYACC_DONE) | |
| 28 | 44 | return 0; |
| 29 | 45 | cpu_relax(); |
| 30 | 46 | } |
| @@ -38,16 +54,10 @@ static int dwc3_ulpi_read(struct device *dev, u8 addr) · 7 unmodified lines | ||
| 38 | 54 | u32 reg; |
| 39 | 55 | int ret; |
| 40 | 56 | |
| 41 | − reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); | |
| 42 | − if (reg & DWC3_GUSB2PHYCFG_SUSPHY) { | |
| 43 | − reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; | |
| 44 | − dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); | |
| 45 | − } | |
| 46 | − | |
| 47 | 57 | reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); |
| 48 | 58 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); |
| 49 | 59 | |
| 50 | − ret = dwc3_ulpi_busyloop(dwc); | |
| 60 | + ret = dwc3_ulpi_busyloop(dwc, addr, true); | |
| 51 | 61 | if (ret) |
| 52 | 62 | return ret; |
| 53 | 63 | |
| @@ -61,17 +71,11 @@ static int dwc3_ulpi_write(struct device *dev, u8 addr, u8 val) · 7 unmodified lines | ||
| 61 | 71 | struct dwc3 *dwc = dev_get_drvdata(dev); |
| 62 | 72 | u32 reg; |
| 63 | 73 | |
| 64 | − reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); | |
| 65 | − if (reg & DWC3_GUSB2PHYCFG_SUSPHY) { | |
| 66 | − reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; | |
| 67 | − dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); | |
| 68 | − } | |
| 69 | − | |
| 70 | 74 | reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); |
| 71 | 75 | reg |= DWC3_GUSB2PHYACC_WRITE | val; |
| 72 | 76 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); |
| 73 | 77 | |
| 74 | − return dwc3_ulpi_busyloop(dwc); | |
| 78 | + return dwc3_ulpi_busyloop(dwc, addr, false); | |
| 75 | 79 | } |
| 76 | 80 | |
| 77 | 81 | static const struct ulpi_ops dwc3_ulpi_ops = { |
| @@ -265,6 +265,7 @@ config USB_CONFIGFS_NCM · 264 unmodified lines | ||
| 265 | 265 | depends on NET |
| 266 | 266 | select USB_U_ETHER |
| 267 | 267 | select USB_F_NCM |
| 268 | + select CRC32 | |
| 268 | 269 | help |
| 269 | 270 | NCM is an advanced protocol for Ethernet encapsulation, allows |
| 270 | 271 | grouping of several ethernet frames into one USB transfer and |
| @@ -314,6 +315,7 @@ config USB_CONFIGFS_EEM · 43 unmodified lines | ||
| 314 | 315 | depends on NET |
| 315 | 316 | select USB_U_ETHER |
| 316 | 317 | select USB_F_EEM |
| 318 | + select CRC32 | |
| 317 | 319 | help |
| 318 | 320 | CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM |
| 319 | 321 | and therefore can be supported by more hardware. Technically ECM and |
| @@ -392,8 +392,11 @@ int usb_function_deactivate(struct usb_function *function) · 391 unmodified lines | ||
| 392 | 392 | |
| 393 | 393 | spin_lock_irqsave(&cdev->lock, flags); |
| 394 | 394 | |
| 395 | − if (cdev->deactivations == 0) | |
| 395 | + if (cdev->deactivations == 0) { | |
| 396 | + spin_unlock_irqrestore(&cdev->lock, flags); | |
| 396 | 397 | status = usb_gadget_deactivate(cdev->gadget); |
| 398 | + spin_lock_irqsave(&cdev->lock, flags); | |
| 399 | + } | |
| 397 | 400 | if (status == 0) |
| 398 | 401 | cdev->deactivations++; |
| 399 | 402 | |
| @@ -424,8 +427,11 @@ int usb_function_activate(struct usb_function *function) · 24 unmodified lines | ||
| 424 | 427 | status = -EINVAL; |
| 425 | 428 | else { |
| 426 | 429 | cdev->deactivations--; |
| 427 | − if (cdev->deactivations == 0) | |
| 430 | + if (cdev->deactivations == 0) { | |
| 431 | + spin_unlock_irqrestore(&cdev->lock, flags); | |
| 428 | 432 | status = usb_gadget_activate(cdev->gadget); |
| 433 | + spin_lock_irqsave(&cdev->lock, flags); | |
| 434 | + } | |
| 429 | 435 | } |
| 430 | 436 | |
| 431 | 437 | spin_unlock_irqrestore(&cdev->lock, flags); |
| @@ -221,9 +221,16 @@ static ssize_t gadget_dev_desc_bcdUSB_store(struct config_item *item, · 220 unmodified lines | ||
| 221 | 221 | |
| 222 | 222 | static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page) |
| 223 | 223 | { |
| 224 | − char *udc_name = to_gadget_info(item)->composite.gadget_driver.udc_name; | |
| 224 | + struct gadget_info *gi = to_gadget_info(item); | |
| 225 | + char *udc_name; | |
| 226 | + int ret; | |
| 227 | + | |
| 228 | + mutex_lock(&gi->lock); | |
| 229 | + udc_name = gi->composite.gadget_driver.udc_name; | |
| 230 | + ret = sprintf(page, "%s\n", udc_name ?: ""); | |
| 231 | + mutex_unlock(&gi->lock); | |
| 225 | 232 | |
| 226 | − return sprintf(page, "%s\n", udc_name ?: ""); | |
| 233 | + return ret; | |
| 227 | 234 | } |
| 228 | 235 | |
| 229 | 236 | static int unregister_gadget(struct gadget_info *gi) |
| @@ -1248,9 +1255,9 @@ static void purge_configs_funcs(struct gadget_info *gi) · 1018 unmodified lines | ||
| 1248 | 1255 | |
| 1249 | 1256 | cfg = container_of(c, struct config_usb_cfg, c); |
| 1250 | 1257 | |
| 1251 | − list_for_each_entry_safe(f, tmp, &c->functions, list) { | |
| 1258 | + list_for_each_entry_safe_reverse(f, tmp, &c->functions, list) { | |
| 1252 | 1259 | |
| 1253 | − list_move_tail(&f->list, &cfg->func_list); | |
| 1260 | + list_move(&f->list, &cfg->func_list); | |
| 1254 | 1261 | if (f->unbind) { |
| 1255 | 1262 | dev_dbg(&gi->cdev.gadget->dev, |
| 1256 | 1263 | "unbind function '%s'/%p\n", |
| @@ -1536,7 +1543,7 @@ static const struct usb_gadget_driver configfs_driver_template = { · 279 unmodified lines | ||
| 1536 | 1543 | .suspend = configfs_composite_suspend, |
| 1537 | 1544 | .resume = configfs_composite_resume, |
| 1538 | 1545 | |
| 1539 | − .max_speed = USB_SPEED_SUPER, | |
| 1546 | + .max_speed = USB_SPEED_SUPER_PLUS, | |
| 1540 | 1547 | .driver = { |
| 1541 | 1548 | .owner = THIS_MODULE, |
| 1542 | 1549 | .name = "configfs-gadget", |
| @@ -1576,7 +1583,7 @@ static struct config_group *gadgets_make( · 33 unmodified lines | ||
| 1576 | 1583 | gi->composite.unbind = configfs_do_nothing; |
| 1577 | 1584 | gi->composite.suspend = NULL; |
| 1578 | 1585 | gi->composite.resume = NULL; |
| 1579 | − gi->composite.max_speed = USB_SPEED_SUPER; | |
| 1586 | + gi->composite.max_speed = USB_SPEED_SUPER_PLUS; | |
| 1580 | 1587 | |
| 1581 | 1588 | spin_lock_init(&gi->spinlock); |
| 1582 | 1589 | mutex_init(&gi->lock); |
| @@ -1162,6 +1162,7 @@ fail_tx_reqs: · 1161 unmodified lines | ||
| 1162 | 1162 | printer_req_free(dev->in_ep, req); |
| 1163 | 1163 | } |
| 1164 | 1164 | |
| 1165 | + usb_free_all_descriptors(f); | |
| 1165 | 1166 | return ret; |
| 1166 | 1167 | |
| 1167 | 1168 | } |
| @@ -271,7 +271,7 @@ static struct usb_endpoint_descriptor fs_epout_desc = { · 270 unmodified lines | ||
| 271 | 271 | |
| 272 | 272 | .bEndpointAddress = USB_DIR_OUT, |
| 273 | 273 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, |
| 274 | − .wMaxPacketSize = cpu_to_le16(1023), | |
| 274 | + /* .wMaxPacketSize = DYNAMIC */ | |
| 275 | 275 | .bInterval = 1, |
| 276 | 276 | }; |
| 277 | 277 | |
| @@ -280,7 +280,7 @@ static struct usb_endpoint_descriptor hs_epout_desc = { · 2 unmodified lines | ||
| 280 | 280 | .bDescriptorType = USB_DT_ENDPOINT, |
| 281 | 281 | |
| 282 | 282 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, |
| 283 | − .wMaxPacketSize = cpu_to_le16(1024), | |
| 283 | + /* .wMaxPacketSize = DYNAMIC */ | |
| 284 | 284 | .bInterval = 4, |
| 285 | 285 | }; |
| 286 | 286 | |
| @@ -348,7 +348,7 @@ static struct usb_endpoint_descriptor fs_epin_desc = { · 61 unmodified lines | ||
| 348 | 348 | |
| 349 | 349 | .bEndpointAddress = USB_DIR_IN, |
| 350 | 350 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, |
| 351 | − .wMaxPacketSize = cpu_to_le16(1023), | |
| 351 | + /* .wMaxPacketSize = DYNAMIC */ | |
| 352 | 352 | .bInterval = 1, |
| 353 | 353 | }; |
| 354 | 354 | |
| @@ -357,7 +357,7 @@ static struct usb_endpoint_descriptor hs_epin_desc = { · 2 unmodified lines | ||
| 357 | 357 | .bDescriptorType = USB_DT_ENDPOINT, |
| 358 | 358 | |
| 359 | 359 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, |
| 360 | − .wMaxPacketSize = cpu_to_le16(1024), | |
| 360 | + /* .wMaxPacketSize = DYNAMIC */ | |
| 361 | 361 | .bInterval = 4, |
| 362 | 362 | }; |
| 363 | 363 | |
| @@ -444,12 +444,28 @@ struct cntrl_range_lay3 { · 80 unmodified lines | ||
| 444 | 444 | __le32 dRES; |
| 445 | 445 | } __packed; |
| 446 | 446 | |
| 447 | −static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, | |
| 447 | +static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, | |
| 448 | 448 | struct usb_endpoint_descriptor *ep_desc, |
| 449 | − unsigned int factor, bool is_playback) | |
| 449 | + enum usb_device_speed speed, bool is_playback) | |
| 450 | 450 | { |
| 451 | 451 | int chmask, srate, ssize; |
| 452 | − u16 max_packet_size; | |
| 452 | + u16 max_size_bw, max_size_ep; | |
| 453 | + unsigned int factor; | |
| 454 | + | |
| 455 | + switch (speed) { | |
| 456 | + case USB_SPEED_FULL: | |
| 457 | + max_size_ep = 1023; | |
| 458 | + factor = 1000; | |
| 459 | + break; | |
| 460 | + | |
| 461 | + case USB_SPEED_HIGH: | |
| 462 | + max_size_ep = 1024; | |
| 463 | + factor = 8000; | |
| 464 | + break; | |
| 465 | + | |
| 466 | + default: | |
| 467 | + return -EINVAL; | |
| 468 | + } | |
| 453 | 469 | |
| 454 | 470 | if (is_playback) { |
| 455 | 471 | chmask = uac2_opts->p_chmask; |
| @@ -461,10 +477,12 @@ static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, · 5 unmodified lines | ||
| 461 | 477 | ssize = uac2_opts->c_ssize; |
| 462 | 478 | } |
| 463 | 479 | |
| 464 | − max_packet_size = num_channels(chmask) * ssize * | |
| 480 | + max_size_bw = num_channels(chmask) * ssize * | |
| 465 | 481 | DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))); |
| 466 | − ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_packet_size, | |
| 467 | − le16_to_cpu(ep_desc->wMaxPacketSize))); | |
| 482 | + ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw, | |
| 483 | + max_size_ep)); | |
| 484 | + | |
| 485 | + return 0; | |
| 468 | 486 | } |
| 469 | 487 | |
| 470 | 488 | /* Use macro to overcome line length limitation */ |
| @@ -670,10 +688,33 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) · 199 unmodified lines | ||
| 670 | 688 | } |
| 671 | 689 | |
| 672 | 690 | /* Calculate wMaxPacketSize according to audio bandwidth */ |
| 673 | − set_ep_max_packet_size(uac2_opts, &fs_epin_desc, 1000, true); | |
| 674 | − set_ep_max_packet_size(uac2_opts, &fs_epout_desc, 1000, false); | |
| 675 | − set_ep_max_packet_size(uac2_opts, &hs_epin_desc, 8000, true); | |
| 676 | − set_ep_max_packet_size(uac2_opts, &hs_epout_desc, 8000, false); | |
| 691 | + ret = set_ep_max_packet_size(uac2_opts, &fs_epin_desc, USB_SPEED_FULL, | |
| 692 | + true); | |
| 693 | + if (ret < 0) { | |
| 694 | + dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); | |
| 695 | + return ret; | |
| 696 | + } | |
| 697 | + | |
| 698 | + ret = set_ep_max_packet_size(uac2_opts, &fs_epout_desc, USB_SPEED_FULL, | |
| 699 | + false); | |
| 700 | + if (ret < 0) { | |
| 701 | + dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); | |
| 702 | + return ret; | |
| 703 | + } | |
| 704 | + | |
| 705 | + ret = set_ep_max_packet_size(uac2_opts, &hs_epin_desc, USB_SPEED_HIGH, | |
| 706 | + true); | |
| 707 | + if (ret < 0) { | |
| 708 | + dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); | |
| 709 | + return ret; | |
| 710 | + } | |
| 711 | + | |
| 712 | + ret = set_ep_max_packet_size(uac2_opts, &hs_epout_desc, USB_SPEED_HIGH, | |
| 713 | + false); | |
| 714 | + if (ret < 0) { | |
| 715 | + dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); | |
| 716 | + return ret; | |
| 717 | + } | |
| 677 | 718 | |
| 678 | 719 | if (EPOUT_EN(uac2_opts)) { |
| 679 | 720 | agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); |
| @@ -45,9 +45,10 @@ · 44 unmodified lines | ||
| 45 | 45 | #define UETH__VERSION "29-May-2008" |
| 46 | 46 | |
| 47 | 47 | /* Experiments show that both Linux and Windows hosts allow up to 16k |
| 48 | − * frame sizes. Set the max size to 15k+52 to prevent allocating 32k | |
| 48 | + * frame sizes. Set the max MTU size to 15k+52 to prevent allocating 32k | |
| 49 | 49 | * blocks and still have efficient handling. */ |
| 50 | −#define GETHER_MAX_ETH_FRAME_LEN 15412 | |
| 50 | +#define GETHER_MAX_MTU_SIZE 15412 | |
| 51 | +#define GETHER_MAX_ETH_FRAME_LEN (GETHER_MAX_MTU_SIZE + ETH_HLEN) | |
| 51 | 52 | |
| 52 | 53 | struct eth_dev { |
| 53 | 54 | /* lock is held while accessing port_usb |
| @@ -786,7 +787,7 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, · 732 unmodified lines | ||
| 786 | 787 | |
| 787 | 788 | /* MTU range: 14 - 15412 */ |
| 788 | 789 | net->min_mtu = ETH_HLEN; |
| 789 | − net->max_mtu = GETHER_MAX_ETH_FRAME_LEN; | |
| 790 | + net->max_mtu = GETHER_MAX_MTU_SIZE; | |
| 790 | 791 | |
| 791 | 792 | dev->gadget = g; |
| 792 | 793 | SET_NETDEV_DEV(net, &g->dev); |
| @@ -848,7 +849,7 @@ struct net_device *gether_setup_name_default(const char *netname) · 55 unmodified lines | ||
| 848 | 849 | |
| 849 | 850 | /* MTU range: 14 - 15412 */ |
| 850 | 851 | net->min_mtu = ETH_HLEN; |
| 851 | − net->max_mtu = GETHER_MAX_ETH_FRAME_LEN; | |
| 852 | + net->max_mtu = GETHER_MAX_MTU_SIZE; | |
| 852 | 853 | |
| 853 | 854 | return net; |
| 854 | 855 | } |
| @@ -200,8 +200,10 @@ static int acm_ms_bind(struct usb_composite_dev *cdev) · 199 unmodified lines | ||
| 200 | 200 | struct usb_descriptor_header *usb_desc; |
| 201 | 201 | |
| 202 | 202 | usb_desc = usb_otg_descriptor_alloc(gadget); |
| 203 | − if (!usb_desc) | |
| 203 | + if (!usb_desc) { | |
| 204 | + status = -ENOMEM; | |
| 204 | 205 | goto fail_string_ids; |
| 206 | + } | |
| 205 | 207 | usb_otg_descriptor_init(gadget, usb_desc); |
| 206 | 208 | otg_desc[0] = usb_desc; |
| 207 | 209 | otg_desc[1] = NULL; |
| @@ -90,7 +90,7 @@ config USB_BCM63XX_UDC · 89 unmodified lines | ||
| 90 | 90 | |
| 91 | 91 | config USB_FSL_USB2 |
| 92 | 92 | tristate "Freescale Highspeed USB DR Peripheral Controller" |
| 93 | − depends on FSL_SOC || ARCH_MXC | |
| 93 | + depends on FSL_SOC | |
| 94 | 94 | help |
| 95 | 95 | Some of Freescale PowerPC and i.MX processors have a High Speed |
| 96 | 96 | Dual-Role(DR) USB controller, which supports device mode. |
| @@ -23,7 +23,6 @@ obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o · 22 unmodified lines | ||
| 23 | 23 | obj-$(CONFIG_USB_BCM63XX_UDC) += bcm63xx_udc.o |
| 24 | 24 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o |
| 25 | 25 | fsl_usb2_udc-y := fsl_udc_core.o |
| 26 | −fsl_usb2_udc-$(CONFIG_ARCH_MXC) += fsl_mxc_udc.o | |
| 27 | 26 | obj-$(CONFIG_USB_TEGRA_XUDC) += tegra-xudc.o |
| 28 | 27 | obj-$(CONFIG_USB_M66592) += m66592-udc.o |
| 29 | 28 | obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o |
| @@ -659,8 +659,7 @@ EXPORT_SYMBOL_GPL(usb_gadget_vbus_disconnect); · 658 unmodified lines | ||
| 659 | 659 | * |
| 660 | 660 | * Enables the D+ (or potentially D-) pullup. The host will start |
| 661 | 661 | * enumerating this gadget when the pullup is active and a VBUS session |
| 662 | − * is active (the link is powered). This pullup is always enabled unless | |
| 663 | − * usb_gadget_disconnect() has been used to disable it. | |
| 662 | + * is active (the link is powered). | |
| 664 | 663 | * |
| 665 | 664 | * Returns zero on success, else negative errno. |
| 666 | 665 | */ |
| @@ -2118,9 +2118,21 @@ static int dummy_hub_control( · 2117 unmodified lines | ||
| 2118 | 2118 | dum_hcd->port_status &= ~USB_PORT_STAT_POWER; |
| 2119 | 2119 | set_link_state(dum_hcd); |
| 2120 | 2120 | break; |
| 2121 | − default: | |
| 2121 | + case USB_PORT_FEAT_ENABLE: | |
| 2122 | + case USB_PORT_FEAT_C_ENABLE: | |
| 2123 | + case USB_PORT_FEAT_C_SUSPEND: | |
| 2124 | + /* Not allowed for USB-3 */ | |
| 2125 | + if (hcd->speed == HCD_USB3) | |
| 2126 | + goto error; | |
| 2127 | + fallthrough; | |
| 2128 | + case USB_PORT_FEAT_C_CONNECTION: | |
| 2129 | + case USB_PORT_FEAT_C_RESET: | |
| 2122 | 2130 | dum_hcd->port_status &= ~(1 << wValue); |
| 2123 | 2131 | set_link_state(dum_hcd); |
| 2132 | + break; | |
| 2133 | + default: | |
| 2134 | + /* Disallow INDICATOR and C_OVER_CURRENT */ | |
| 2135 | + goto error; | |
| 2124 | 2136 | } |
| 2125 | 2137 | break; |
| 2126 | 2138 | case GetHubDescriptor: |
| @@ -2281,18 +2293,17 @@ static int dummy_hub_control( · 154 unmodified lines | ||
| 2281 | 2293 | */ |
| 2282 | 2294 | dum_hcd->re_timeout = jiffies + msecs_to_jiffies(50); |
| 2283 | 2295 | fallthrough; |
| 2296 | + case USB_PORT_FEAT_C_CONNECTION: | |
| 2297 | + case USB_PORT_FEAT_C_RESET: | |
| 2298 | + case USB_PORT_FEAT_C_ENABLE: | |
| 2299 | + case USB_PORT_FEAT_C_SUSPEND: | |
| 2300 | + /* Not allowed for USB-3, and ignored for USB-2 */ | |
| 2301 | + if (hcd->speed == HCD_USB3) | |
| 2302 | + goto error; | |
| 2303 | + break; | |
| 2284 | 2304 | default: |
| 2285 | − if (hcd->speed == HCD_USB3) { | |
| 2286 | − if ((dum_hcd->port_status & | |
| 2287 | − USB_SS_PORT_STAT_POWER) != 0) { | |
| 2288 | − dum_hcd->port_status |= (1 << wValue); | |
| 2289 | − } | |
| 2290 | − } else | |
| 2291 | − if ((dum_hcd->port_status & | |
| 2292 | − USB_PORT_STAT_POWER) != 0) { | |
| 2293 | − dum_hcd->port_status |= (1 << wValue); | |
| 2294 | − } | |
| 2295 | − set_link_state(dum_hcd); | |
| 2305 | + /* Disallow TEST, INDICATOR, and C_OVER_CURRENT */ | |
| 2306 | + goto error; | |
| 2296 | 2307 | } |
| 2297 | 2308 | break; |
| 2298 | 2309 | case GetPortErrorCount: |
| @@ -1,122 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0+ | |
| 2 | −/* | |
| 3 | − * Copyright (C) 2009 | |
| 4 | − * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de> | |
| 5 | − * | |
| 6 | − * Description: | |
| 7 | − * Helper routines for i.MX3x SoCs from Freescale, needed by the fsl_usb2_udc.c | |
| 8 | − * driver to function correctly on these systems. | |
| 9 | − */ | |
| 10 | −#include <linux/clk.h> | |
| 11 | −#include <linux/delay.h> | |
| 12 | −#include <linux/err.h> | |
| 13 | −#include <linux/fsl_devices.h> | |
| 14 | −#include <linux/mod_devicetable.h> | |
| 15 | −#include <linux/platform_device.h> | |
| 16 | −#include <linux/io.h> | |
| 17 | − | |
| 18 | −#include "fsl_usb2_udc.h" | |
| 19 | − | |
| 20 | −static struct clk *mxc_ahb_clk; | |
| 21 | −static struct clk *mxc_per_clk; | |
| 22 | −static struct clk *mxc_ipg_clk; | |
| 23 | − | |
| 24 | −/* workaround ENGcm09152 for i.MX35 */ | |
| 25 | −#define MX35_USBPHYCTRL_OFFSET 0x600 | |
| 26 | −#define USBPHYCTRL_OTGBASE_OFFSET 0x8 | |
| 27 | −#define USBPHYCTRL_EVDO (1 << 23) | |
| 28 | − | |
| 29 | −int fsl_udc_clk_init(struct platform_device *pdev) | |
| 30 | −{ | |
| 31 | − struct fsl_usb2_platform_data *pdata; | |
| 32 | − unsigned long freq; | |
| 33 | − int ret; | |
| 34 | − | |
| 35 | − pdata = dev_get_platdata(&pdev->dev); | |
| 36 | − | |
| 37 | − mxc_ipg_clk = devm_clk_get(&pdev->dev, "ipg"); | |
| 38 | − if (IS_ERR(mxc_ipg_clk)) { | |
| 39 | − dev_err(&pdev->dev, "clk_get(\"ipg\") failed\n"); | |
| 40 | − return PTR_ERR(mxc_ipg_clk); | |
| 41 | − } | |
| 42 | − | |
| 43 | − mxc_ahb_clk = devm_clk_get(&pdev->dev, "ahb"); | |
| 44 | − if (IS_ERR(mxc_ahb_clk)) { | |
| 45 | − dev_err(&pdev->dev, "clk_get(\"ahb\") failed\n"); | |
| 46 | − return PTR_ERR(mxc_ahb_clk); | |
| 47 | − } | |
| 48 | − | |
| 49 | − mxc_per_clk = devm_clk_get(&pdev->dev, "per"); | |
| 50 | − if (IS_ERR(mxc_per_clk)) { | |
| 51 | − dev_err(&pdev->dev, "clk_get(\"per\") failed\n"); | |
| 52 | − return PTR_ERR(mxc_per_clk); | |
| 53 | − } | |
| 54 | − | |
| 55 | − clk_prepare_enable(mxc_ipg_clk); | |
| 56 | − clk_prepare_enable(mxc_ahb_clk); | |
| 57 | − clk_prepare_enable(mxc_per_clk); | |
| 58 | − | |
| 59 | − /* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */ | |
| 60 | − if (!strcmp(pdev->id_entry->name, "imx-udc-mx27")) { | |
| 61 | − freq = clk_get_rate(mxc_per_clk); | |
| 62 | − if (pdata->phy_mode != FSL_USB2_PHY_ULPI && | |
| 63 | − (freq < 59999000 || freq > 60001000)) { | |
| 64 | − dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq); | |
| 65 | − ret = -EINVAL; | |
| 66 | − goto eclkrate; | |
| 67 | − } | |
| 68 | − } | |
| 69 | − | |
| 70 | − return 0; | |
| 71 | − | |
| 72 | −eclkrate: | |
| 73 | − clk_disable_unprepare(mxc_ipg_clk); | |
| 74 | − clk_disable_unprepare(mxc_ahb_clk); | |
| 75 | − clk_disable_unprepare(mxc_per_clk); | |
| 76 | − mxc_per_clk = NULL; | |
| 77 | − return ret; | |
| 78 | −} | |
| 79 | − | |
| 80 | −int fsl_udc_clk_finalize(struct platform_device *pdev) | |
| 81 | −{ | |
| 82 | − struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev); | |
| 83 | − int ret = 0; | |
| 84 | − | |
| 85 | − /* workaround ENGcm09152 for i.MX35 */ | |
| 86 | − if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) { | |
| 87 | − unsigned int v; | |
| 88 | − struct resource *res = platform_get_resource | |
| 89 | − (pdev, IORESOURCE_MEM, 0); | |
| 90 | − void __iomem *phy_regs = ioremap(res->start + | |
| 91 | − MX35_USBPHYCTRL_OFFSET, 512); | |
| 92 | − if (!phy_regs) { | |
| 93 | − dev_err(&pdev->dev, "ioremap for phy address fails\n"); | |
| 94 | − ret = -EINVAL; | |
| 95 | − goto ioremap_err; | |
| 96 | − } | |
| 97 | − | |
| 98 | − v = readl(phy_regs + USBPHYCTRL_OTGBASE_OFFSET); | |
| 99 | − writel(v | USBPHYCTRL_EVDO, | |
| 100 | − phy_regs + USBPHYCTRL_OTGBASE_OFFSET); | |
| 101 | − | |
| 102 | − iounmap(phy_regs); | |
| 103 | − } | |
| 104 | − | |
| 105 | − | |
| 106 | −ioremap_err: | |
| 107 | − /* ULPI transceivers don't need usbpll */ | |
| 108 | − if (pdata->phy_mode == FSL_USB2_PHY_ULPI) { | |
| 109 | − clk_disable_unprepare(mxc_per_clk); | |
| 110 | − mxc_per_clk = NULL; | |
| 111 | − } | |
| 112 | − | |
| 113 | − return ret; | |
| 114 | −} | |
| 115 | − | |
| 116 | −void fsl_udc_clk_release(void) | |
| 117 | −{ | |
| 118 | − if (mxc_per_clk) | |
| 119 | − clk_disable_unprepare(mxc_per_clk); | |
| 120 | − clk_disable_unprepare(mxc_ahb_clk); | |
| 121 | − clk_disable_unprepare(mxc_ipg_clk); | |
| 122 | −} | |
| @@ -4770,19 +4770,19 @@ static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci, · 4769 unmodified lines | ||
| 4770 | 4770 | { |
| 4771 | 4771 | unsigned long long timeout_ns; |
| 4772 | 4772 | |
| 4773 | + if (xhci->quirks & XHCI_INTEL_HOST) | |
| 4774 | + timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); | |
| 4775 | + else | |
| 4776 | + timeout_ns = udev->u1_params.sel; | |
| 4777 | + | |
| 4773 | 4778 | /* Prevent U1 if service interval is shorter than U1 exit latency */ |
| 4774 | 4779 | if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { |
| 4775 | − if (xhci_service_interval_to_ns(desc) <= udev->u1_params.mel) { | |
| 4780 | + if (xhci_service_interval_to_ns(desc) <= timeout_ns) { | |
| 4776 | 4781 | dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n"); |
| 4777 | 4782 | return USB3_LPM_DISABLED; |
| 4778 | 4783 | } |
| 4779 | 4784 | } |
| 4780 | 4785 | |
| 4781 | − if (xhci->quirks & XHCI_INTEL_HOST) | |
| 4782 | − timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); | |
| 4783 | − else | |
| 4784 | − timeout_ns = udev->u1_params.sel; | |
| 4785 | − | |
| 4786 | 4786 | /* The U1 timeout is encoded in 1us intervals. |
| 4787 | 4787 | * Don't return a timeout of zero, because that's USB3_LPM_DISABLED. |
| 4788 | 4788 | */ |
| @@ -4834,19 +4834,19 @@ static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci, · 45 unmodified lines | ||
| 4834 | 4834 | { |
| 4835 | 4835 | unsigned long long timeout_ns; |
| 4836 | 4836 | |
| 4837 | + if (xhci->quirks & XHCI_INTEL_HOST) | |
| 4838 | + timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc); | |
| 4839 | + else | |
| 4840 | + timeout_ns = udev->u2_params.sel; | |
| 4841 | + | |
| 4837 | 4842 | /* Prevent U2 if service interval is shorter than U2 exit latency */ |
| 4838 | 4843 | if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { |
| 4839 | − if (xhci_service_interval_to_ns(desc) <= udev->u2_params.mel) { | |
| 4844 | + if (xhci_service_interval_to_ns(desc) <= timeout_ns) { | |
| 4840 | 4845 | dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n"); |
| 4841 | 4846 | return USB3_LPM_DISABLED; |
| 4842 | 4847 | } |
| 4843 | 4848 | } |
| 4844 | 4849 | |
| 4845 | − if (xhci->quirks & XHCI_INTEL_HOST) | |
| 4846 | − timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc); | |
| 4847 | − else | |
| 4848 | − timeout_ns = udev->u2_params.sel; | |
| 4849 | − | |
| 4850 | 4850 | /* The U2 timeout is encoded in 256us intervals */ |
| 4851 | 4851 | timeout_ns = DIV_ROUND_UP_ULL(timeout_ns, 256 * 1000); |
| 4852 | 4852 | /* If the necessary timeout value is bigger than what we can set in the |
| @@ -496,6 +496,9 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer, · 495 unmodified lines | ||
| 496 | 496 | timeout = schedule_timeout(YUREX_WRITE_TIMEOUT); |
| 497 | 497 | finish_wait(&dev->waitq, &wait); |
| 498 | 498 | |
| 499 | + /* make sure URB is idle after timeout or (spurious) CMD_ACK */ | |
| 500 | + usb_kill_urb(dev->cntl_urb); | |
| 501 | + | |
| 499 | 502 | mutex_unlock(&dev->io_mutex); |
| 500 | 503 | |
| 501 | 504 | if (retval < 0) { |
| @@ -532,23 +532,29 @@ static int iuu_uart_flush(struct usb_serial_port *port) · 531 unmodified lines | ||
| 532 | 532 | struct device *dev = &port->dev; |
| 533 | 533 | int i; |
| 534 | 534 | int status; |
| 535 | − u8 rxcmd = IUU_UART_RX; | |
| 535 | + u8 *rxcmd; | |
| 536 | 536 | struct iuu_private *priv = usb_get_serial_port_data(port); |
| 537 | 537 | |
| 538 | 538 | if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0) |
| 539 | 539 | return -EIO; |
| 540 | 540 | |
| 541 | + rxcmd = kmalloc(1, GFP_KERNEL); | |
| 542 | + if (!rxcmd) | |
| 543 | + return -ENOMEM; | |
| 544 | + | |
| 545 | + rxcmd[0] = IUU_UART_RX; | |
| 546 | + | |
| 541 | 547 | for (i = 0; i < 2; i++) { |
| 542 | − status = bulk_immediate(port, &rxcmd, 1); | |
| 548 | + status = bulk_immediate(port, rxcmd, 1); | |
| 543 | 549 | if (status != IUU_OPERATION_OK) { |
| 544 | 550 | dev_dbg(dev, "%s - uart_flush_write error\n", __func__); |
| 545 | − return status; | |
| 551 | + goto out_free; | |
| 546 | 552 | } |
| 547 | 553 | |
| 548 | 554 | status = read_immediate(port, &priv->len, 1); |
| 549 | 555 | if (status != IUU_OPERATION_OK) { |
| 550 | 556 | dev_dbg(dev, "%s - uart_flush_read error\n", __func__); |
| 551 | − return status; | |
| 557 | + goto out_free; | |
| 552 | 558 | } |
| 553 | 559 | |
| 554 | 560 | if (priv->len > 0) { |
| @@ -556,12 +562,16 @@ static int iuu_uart_flush(struct usb_serial_port *port) · 1 unmodified line | ||
| 556 | 562 | status = read_immediate(port, priv->buf, priv->len); |
| 557 | 563 | if (status != IUU_OPERATION_OK) { |
| 558 | 564 | dev_dbg(dev, "%s - uart_flush_read error\n", __func__); |
| 559 | − return status; | |
| 565 | + goto out_free; | |
| 560 | 566 | } |
| 561 | 567 | } |
| 562 | 568 | } |
| 563 | 569 | dev_dbg(dev, "%s - uart_flush_read OK!\n", __func__); |
| 564 | 570 | iuu_led(port, 0, 0xF000, 0, 0xFF); |
| 571 | + | |
| 572 | +out_free: | |
| 573 | + kfree(rxcmd); | |
| 574 | + | |
| 565 | 575 | return status; |
| 566 | 576 | } |
| 567 | 577 | |
| @@ -1117,6 +1117,8 @@ static const struct usb_device_id option_ids[] = { · 1116 unmodified lines | ||
| 1117 | 1117 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), |
| 1118 | 1118 | .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, |
| 1119 | 1119 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, |
| 1120 | + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0xff, 0x30) }, /* EM160R-GL */ | |
| 1121 | + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0, 0) }, | |
| 1120 | 1122 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) }, |
| 1121 | 1123 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, |
| 1122 | 1124 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10), |
| @@ -2057,6 +2059,7 @@ static const struct usb_device_id option_ids[] = { · 934 unmodified lines | ||
| 2057 | 2059 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ |
| 2058 | 2060 | .driver_info = RSVD(6) }, |
| 2059 | 2061 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */ |
| 2062 | + { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ | |
| 2060 | 2063 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ |
| 2061 | 2064 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ |
| 2062 | 2065 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ |
| @@ -90,6 +90,13 @@ UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999, · 89 unmodified lines | ||
| 90 | 90 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 91 | 91 | US_FL_BROKEN_FUA), |
| 92 | 92 | |
| 93 | +/* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */ | |
| 94 | +UNUSUAL_DEV(0x154b, 0xf00b, 0x0000, 0x9999, | |
| 95 | + "PNY", | |
| 96 | + "Pro Elite SSD", | |
| 97 | + USB_SC_DEVICE, USB_PR_DEVICE, NULL, | |
| 98 | + US_FL_NO_ATA_1X), | |
| 99 | + | |
| 93 | 100 | /* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */ |
| 94 | 101 | UNUSUAL_DEV(0x154b, 0xf00d, 0x0000, 0x9999, |
| 95 | 102 | "PNY", |
| @@ -20,6 +20,6 @@ config TYPEC_NVIDIA_ALTMODE · 19 unmodified lines | ||
| 20 | 20 | to enable support for VirtualLink devices with NVIDIA GPUs. |
| 21 | 21 | |
| 22 | 22 | To compile this driver as a module, choose M here: the |
| 23 | − module will be called typec_displayport. | |
| 23 | + module will be called typec_nvidia. | |
| 24 | 24 | |
| 25 | 25 | endmenu |
| @@ -766,6 +766,7 @@ int typec_partner_set_num_altmodes(struct typec_partner *partner, int num_altmod · 765 unmodified lines | ||
| 766 | 766 | return ret; |
| 767 | 767 | |
| 768 | 768 | sysfs_notify(&partner->dev.kobj, NULL, "number_of_alternate_modes"); |
| 769 | + kobject_uevent(&partner->dev.kobj, KOBJ_CHANGE); | |
| 769 | 770 | |
| 770 | 771 | return 0; |
| 771 | 772 | } |
| @@ -923,6 +924,7 @@ int typec_plug_set_num_altmodes(struct typec_plug *plug, int num_altmodes) · 151 unmodified lines | ||
| 923 | 924 | return ret; |
| 924 | 925 | |
| 925 | 926 | sysfs_notify(&plug->dev.kobj, NULL, "number_of_alternate_modes"); |
| 927 | + kobject_uevent(&plug->dev.kobj, KOBJ_CHANGE); | |
| 926 | 928 | |
| 927 | 929 | return 0; |
| 928 | 930 | } |
| @@ -207,10 +207,21 @@ static int · 206 unmodified lines | ||
| 207 | 207 | pmc_usb_mux_dp_hpd(struct pmc_usb_port *port, struct typec_displayport_data *dp) |
| 208 | 208 | { |
| 209 | 209 | u8 msg[2] = { }; |
| 210 | + int ret; | |
| 210 | 211 | |
| 211 | 212 | msg[0] = PMC_USB_DP_HPD; |
| 212 | 213 | msg[0] |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT; |
| 213 | 214 | |
| 215 | + /* Configure HPD first if HPD,IRQ comes together */ | |
| 216 | + if (!IOM_PORT_HPD_ASSERTED(port->iom_status) && | |
| 217 | + dp->status & DP_STATUS_IRQ_HPD && | |
| 218 | + dp->status & DP_STATUS_HPD_STATE) { | |
| 219 | + msg[1] = PMC_USB_DP_HPD_LVL; | |
| 220 | + ret = pmc_usb_command(port, msg, sizeof(msg)); | |
| 221 | + if (ret) | |
| 222 | + return ret; | |
| 223 | + } | |
| 224 | + | |
| 214 | 225 | if (dp->status & DP_STATUS_IRQ_HPD) |
| 215 | 226 | msg[1] = PMC_USB_DP_HPD_IRQ; |
| 216 | 227 | |
| @@ -396,6 +396,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, · 395 unmodified lines | ||
| 396 | 396 | default: |
| 397 | 397 | usbip_dbg_vhci_rh(" ClearPortFeature: default %x\n", |
| 398 | 398 | wValue); |
| 399 | + if (wValue >= 32) | |
| 400 | + goto error; | |
| 399 | 401 | vhci_hcd->port_status[rhport] &= ~(1 << wValue); |
| 400 | 402 | break; |
| 401 | 403 | } |
| @@ -863,6 +863,7 @@ static void handle_tx_zerocopy(struct vhost_net *net, struct socket *sock) · 862 unmodified lines | ||
| 863 | 863 | size_t len, total_len = 0; |
| 864 | 864 | int err; |
| 865 | 865 | struct vhost_net_ubuf_ref *ubufs; |
| 866 | + struct ubuf_info *ubuf; | |
| 866 | 867 | bool zcopy_used; |
22 more lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 109 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 182 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 375 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 769 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 153 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 173 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 135 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 148 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 176 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 165 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 840 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 226 lines aren’t shown here.
This diff is large: its 295 lines aren’t shown here.
This diff is large: its 219 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 193 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 135 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 207 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.