To pick up fixes.
Unified · Split
| @@ -710,6 +710,10 @@ S: Las Cuevas 2385 - Bo Guemes · 709 unmodified lines | |||
| 710 | S: Las Heras, Mendoza CP 5539 | 710 | S: Las Heras, Mendoza CP 5539 |
| 711 | S: Argentina | 711 | S: Argentina |
| 712 | 712 | ||
| 713 | N: Jay Cliburn | ||
| 714 | E: jcliburn@gmail.com | ||
| 715 | D: ATLX Ethernet drivers | ||
| 716 | |||
| 713 | N: Steven P. Cole | 717 | N: Steven P. Cole |
| 714 | E: scole@lanl.gov | 718 | E: scole@lanl.gov |
| 715 | E: elenstev@mesatop.com | 719 | E: elenstev@mesatop.com |
| @@ -1284,6 +1288,10 @@ D: Major kbuild rework during the 2.5 cycle · 568 unmodified lines | |||
| 1284 | D: ISDN Maintainer | 1288 | D: ISDN Maintainer |
| 1285 | S: USA | 1289 | S: USA |
| 1286 | 1290 | ||
| 1291 | N: Gerrit Renker | ||
| 1292 | E: gerrit@erg.abdn.ac.uk | ||
| 1293 | D: DCCP protocol support. | ||
| 1294 | |||
| 1287 | N: Philip Gladstone | 1295 | N: Philip Gladstone |
| 1288 | E: philip@gladstonefamily.net | 1296 | E: philip@gladstonefamily.net |
| 1289 | D: Kernel / timekeeping stuff | 1297 | D: Kernel / timekeeping stuff |
| @@ -2138,6 +2146,10 @@ E: seasons@falcon.sch.bme.hu · 848 unmodified lines | |||
| 2138 | E: seasons@makosteszta.sote.hu | 2146 | E: seasons@makosteszta.sote.hu |
| 2139 | D: Original author of software suspend | 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 | N: Jaroslav Kysela | 2153 | N: Jaroslav Kysela |
| 2142 | E: perex@perex.cz | 2154 | E: perex@perex.cz |
| 2143 | W: https://www.perex.cz | 2155 | W: https://www.perex.cz |
| @@ -2696,6 +2708,10 @@ N: Wolfgang Muees · 552 unmodified lines | |||
| 2696 | E: wolfgang@iksw-muees.de | 2708 | E: wolfgang@iksw-muees.de |
| 2697 | D: Auerswald USB driver | 2709 | D: Auerswald USB driver |
| 2698 | 2710 | ||
| 2711 | N: Shrijeet Mukherjee | ||
| 2712 | E: shrijeet@gmail.com | ||
| 2713 | D: Network routing domains (VRF). | ||
| 2714 | |||
| 2699 | N: Paul Mundt | 2715 | N: Paul Mundt |
| 2700 | E: paul.mundt@gmail.com | 2716 | E: paul.mundt@gmail.com |
| 2701 | D: SuperH maintainer | 2717 | D: SuperH maintainer |
| @@ -4110,6 +4126,10 @@ S: B-1206 Jingmao Guojigongyu · 1408 unmodified lines | |||
| 4110 | S: 16 Baliqiao Nanjie, Beijing 101100 | 4126 | S: 16 Baliqiao Nanjie, Beijing 101100 |
| 4111 | S: People's Repulic of China | 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 | N: Victor Yodaiken | 4133 | N: Victor Yodaiken |
| 4114 | E: yodaiken@fsmlabs.com | 4134 | E: yodaiken@fsmlabs.com |
| 4115 | D: RTLinux (RealTime Linux) | 4135 | D: RTLinux (RealTime Linux) |
| @@ -4167,6 +4187,10 @@ S: 1507 145th Place SE #B5 · 51 unmodified lines | |||
| 4167 | S: Bellevue, Washington 98007 | 4187 | S: Bellevue, Washington 98007 |
| 4168 | S: USA | 4188 | S: USA |
| 4169 | 4189 | ||
| 4190 | N: Wensong Zhang | ||
| 4191 | E: wensong@linux-vs.org | ||
| 4192 | D: IP virtual server (IPVS). | ||
| 4193 | |||
| 4170 | N: Haojian Zhuang | 4194 | N: Haojian Zhuang |
| 4171 | E: haojian.zhuang@gmail.com | 4195 | E: haojian.zhuang@gmail.com |
| 4172 | D: MMP support | 4196 | D: MMP support |
| @@ -473,7 +473,7 @@ read-side critical sections that follow the idle period (the oval near · 472 unmodified lines | |||
| 473 | the bottom of the diagram above). | 473 | the bottom of the diagram above). |
| 474 | 474 | ||
| 475 | Plumbing this into the full grace-period execution is described | 475 | Plumbing this into the full grace-period execution is described |
| 476 | `below <#Forcing%20Quiescent%20States>`__. | 476 | `below <Forcing Quiescent States_>`__. |
| 477 | 477 | ||
| 478 | CPU-Hotplug Interface | 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 | grace period. | 494 | grace period. |
| 495 | 495 | ||
| 496 | Plumbing this into the full grace-period execution is described | 496 | Plumbing this into the full grace-period execution is described |
| 497 | `below <#Forcing%20Quiescent%20States>`__. | 497 | `below <Forcing Quiescent States_>`__. |
| 498 | 498 | ||
| 499 | Forcing Quiescent States | 499 | Forcing Quiescent States |
| 500 | ^^^^^^^^^^^^^^^^^^^^^^^^ | 500 | ^^^^^^^^^^^^^^^^^^^^^^^^ |
| @@ -532,7 +532,7 @@ from other CPUs. · 31 unmodified lines | |||
| 532 | | RCU. But this diagram is complex enough as it is, so simplicity | | 532 | | RCU. But this diagram is complex enough as it is, so simplicity | |
| 533 | | overrode accuracy. You can think of it as poetic license, or you can | | 533 | | overrode accuracy. You can think of it as poetic license, or you can | |
| 534 | | think of it as misdirection that is resolved in the | | 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 | Grace-Period Cleanup | 538 | Grace-Period Cleanup |
| @@ -596,7 +596,7 @@ maintain ordering. For example, if the callback function wakes up a task · 57 unmodified lines | |||
| 596 | that runs on some other CPU, proper ordering must in place in both the | 596 | that runs on some other CPU, proper ordering must in place in both the |
| 597 | callback function and the task being awakened. To see why this is | 597 | callback function and the task being awakened. To see why this is |
| 598 | important, consider the top half of the `grace-period | 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 | running on a CPU corresponding to the leftmost leaf ``rcu_node`` | 600 | running on a CPU corresponding to the leftmost leaf ``rcu_node`` |
| 601 | structure, and awaken a task that is to run on a CPU corresponding to | 601 | structure, and awaken a task that is to run on a CPU corresponding to |
| 602 | the rightmost leaf ``rcu_node`` structure, and the grace-period kernel | 602 | the rightmost leaf ``rcu_node`` structure, and the grace-period kernel |
| @@ -45,7 +45,7 @@ requirements: · 44 unmodified lines | |||
| 45 | #. `Other RCU Flavors`_ | 45 | #. `Other RCU Flavors`_ |
| 46 | #. `Possible Future Changes`_ | 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 | each quick quiz immediately follows the quiz. Select the big white space | 49 | each quick quiz immediately follows the quiz. Select the big white space |
| 50 | with your mouse to see the answer. | 50 | with your mouse to see the answer. |
| 51 | 51 | ||
| @@ -1096,7 +1096,7 @@ memory barriers. · 1044 unmodified lines | |||
| 1096 | | case, voluntary context switch) within an RCU read-side critical | | 1096 | | case, voluntary context switch) within an RCU read-side critical | |
| 1097 | | section. However, sleeping locks may be used within userspace RCU | | 1097 | | section. However, sleeping locks may be used within userspace RCU | |
| 1098 | | read-side critical sections, and also within Linux-kernel sleepable | | 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 | | addition, the -rt patchset turns spinlocks into a sleeping locks so | | 1100 | | addition, the -rt patchset turns spinlocks into a sleeping locks so | |
| 1101 | | that the corresponding critical sections can be preempted, which also | | 1101 | | that the corresponding critical sections can be preempted, which also | |
| 1102 | | means that these sleeplockified spinlocks (but not other sleeping | | 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 | RCU <https://lkml.kernel.org/g/20090113221724.GA15307@linux.vnet.ibm.com>`__ | 1186 | RCU <https://lkml.kernel.org/g/20090113221724.GA15307@linux.vnet.ibm.com>`__ |
| 1187 | was born. Josh Triplett has since taken over the small-memory banner | 1187 | was born. Josh Triplett has since taken over the small-memory banner |
| 1188 | with his `Linux kernel tinification <https://tiny.wiki.kernel.org/>`__ | 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 | for those kernels not needing it. | 1190 | for those kernels not needing it. |
| 1191 | 1191 | ||
| 1192 | The remaining performance requirements are, for the most part, | 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 | the relevant Kconfig options and kernel boot parameters. RCU currently | 1457 | the relevant Kconfig options and kernel boot parameters. RCU currently |
| 1458 | does not do much sanity checking of these parameters, so please use | 1458 | does not do much sanity checking of these parameters, so please use |
| 1459 | caution when changing them. Note that these forward-progress measures | 1459 | caution when changing them. Note that these forward-progress measures |
| 1460 | are provided only for RCU, not for `SRCU <#Sleepable%20RCU>`__ or `Tasks | 1460 | are provided only for RCU, not for `SRCU <Sleepable RCU_>`__ or `Tasks |
| 1461 | RCU <#Tasks%20RCU>`__. | 1461 | RCU`_. |
| 1462 | 1462 | ||
| 1463 | RCU takes the following steps in ``call_rcu()`` to encourage timely | 1463 | RCU takes the following steps in ``call_rcu()`` to encourage timely |
| 1464 | invocation of callbacks when any given non-\ ``rcu_nocbs`` CPU has | 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 | Again, these are default values when running at ``HZ=1000``, and can be | 1478 | Again, these are default values when running at ``HZ=1000``, and can be |
| 1479 | overridden. Again, these forward-progress measures are provided only for | 1479 | overridden. Again, these forward-progress measures are provided only for |
| 1480 | RCU, not for `SRCU <#Sleepable%20RCU>`__ or `Tasks | 1480 | RCU, not for `SRCU <Sleepable RCU_>`__ or `Tasks |
| 1481 | RCU <#Tasks%20RCU>`__. Even for RCU, callback-invocation forward | 1481 | RCU`_. Even for RCU, callback-invocation forward |
| 1482 | progress for ``rcu_nocbs`` CPUs is much less well-developed, in part | 1482 | progress for ``rcu_nocbs`` CPUs is much less well-developed, in part |
| 1483 | because workloads benefiting from ``rcu_nocbs`` CPUs tend to invoke | 1483 | because workloads benefiting from ``rcu_nocbs`` CPUs tend to invoke |
| 1484 | ``call_rcu()`` relatively infrequently. If workloads emerge that need | 1484 | ``call_rcu()`` relatively infrequently. If workloads emerge that need |
| @@ -1920,7 +1920,7 @@ Hotplug CPU · 435 unmodified lines | |||
| 1920 | 1920 | ||
| 1921 | The Linux kernel supports CPU hotplug, which means that CPUs can come | 1921 | The Linux kernel supports CPU hotplug, which means that CPUs can come |
| 1922 | and go. It is of course illegal to use any RCU API member from an | 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 | critical sections. This requirement was present from day one in | 1924 | critical sections. This requirement was present from day one in |
| 1925 | DYNIX/ptx, but on the other hand, the Linux kernel's CPU-hotplug | 1925 | DYNIX/ptx, but on the other hand, the Linux kernel's CPU-hotplug |
| 1926 | implementation is “interesting.” | 1926 | implementation is “interesting.” |
| @@ -2177,7 +2177,7 @@ handles these states differently: · 250 unmodified lines | |||
| 2177 | However, RCU must be reliably informed as to whether any given CPU is | 2177 | However, RCU must be reliably informed as to whether any given CPU is |
| 2178 | currently in the idle loop, and, for ``NO_HZ_FULL``, also whether that | 2178 | currently in the idle loop, and, for ``NO_HZ_FULL``, also whether that |
| 2179 | CPU is executing in usermode, as discussed | 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 | scheduling-clock interrupt be enabled when RCU needs it to be: | 2181 | scheduling-clock interrupt be enabled when RCU needs it to be: |
| 2182 | 2182 | ||
| 2183 | #. If a CPU is either idle or executing in usermode, and RCU believes it | 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 | Expanding on the `earlier | 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 | hot code paths in performance-critical portions of the Linux kernel's | 2298 | hot code paths in performance-critical portions of the Linux kernel's |
| 2299 | networking, security, virtualization, and scheduling code paths. RCU | 2299 | networking, security, virtualization, and scheduling code paths. RCU |
| 2300 | must therefore use efficient implementations, especially in its | 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 | - ``name`` | 24 | - ``name`` |
| 25 | is an identifier string. A new /proc file will be created with this | 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 | obvious reasons. | 27 | obvious reasons. |
| 28 | - ``type`` | 28 | - ``type`` |
| 29 | is the type of recognition. Give ``M`` for magic and ``E`` for extension. | 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 | ``F`` - fix binary | 83 | ``F`` - fix binary |
| 84 | The usual behaviour of binfmt_misc is to spawn the | 84 | The usual behaviour of binfmt_misc is to spawn the |
| 85 | binary lazily when the misc format file is invoked. However, | 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 | changeroots, so the ``F`` mode opens the binary as soon as the | 87 | changeroots, so the ``F`` mode opens the binary as soon as the |
| 88 | emulation is installed and uses the opened image to spawn the | 88 | emulation is installed and uses the opened image to spawn the |
| 89 | emulator, meaning it is always available once installed, | 89 | emulator, meaning it is always available once installed, |
| @@ -154,7 +154,7 @@ get the boot configuration data. · 153 unmodified lines | |||
| 154 | Because of this "piggyback" method, there is no need to change or | 154 | Because of this "piggyback" method, there is no need to change or |
| 155 | update the boot loader and the kernel image itself as long as the boot | 155 | update the boot loader and the kernel image itself as long as the boot |
| 156 | loader passes the correct initrd file size. If by any chance, the boot | 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 | To do this operation, Linux kernel provides "bootconfig" command under | 159 | To do this operation, Linux kernel provides "bootconfig" command under |
| 160 | tools/bootconfig, which allows admin to apply or delete the config file | 160 | tools/bootconfig, which allows admin to apply or delete the config file |
| @@ -3,8 +3,8 @@ · 2 unmodified lines | |||
| 3 | The kernel's command-line parameters | 3 | The kernel's command-line parameters |
| 4 | ==================================== | 4 | ==================================== |
| 5 | 5 | ||
| 6 | The following is a consolidated list of the kernel parameters as | 6 | The following is a consolidated list of the kernel parameters as implemented |
| 7 | implemented by the __setup(), core_param() and module_param() macros | 7 | by the __setup(), early_param(), core_param() and module_param() macros |
| 8 | and sorted into English Dictionary order (defined as ignoring all | 8 | and sorted into English Dictionary order (defined as ignoring all |
| 9 | punctuation and sorting digits before letters in a case insensitive | 9 | punctuation and sorting digits before letters in a case insensitive |
| 10 | manner), and with descriptions where known. | 10 | manner), and with descriptions where known. |
| @@ -1385,7 +1385,7 @@ · 1384 unmodified lines | |||
| 1385 | 1385 | ||
| 1386 | ftrace_filter=[function-list] | 1386 | ftrace_filter=[function-list] |
| 1387 | [FTRACE] Limit the functions traced by the function | 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 | list of functions. This list can be changed at run | 1389 | list of functions. This list can be changed at run |
| 1390 | time by the set_ftrace_filter file in the debugfs | 1390 | time by the set_ftrace_filter file in the debugfs |
| 1391 | tracing directory. | 1391 | tracing directory. |
| @@ -1399,13 +1399,13 @@ · 7 unmodified lines | |||
| 1399 | ftrace_graph_filter=[function-list] | 1399 | ftrace_graph_filter=[function-list] |
| 1400 | [FTRACE] Limit the top level callers functions traced | 1400 | [FTRACE] Limit the top level callers functions traced |
| 1401 | by the function graph tracer at boot up. | 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 | that can be changed at run time by the | 1403 | that can be changed at run time by the |
| 1404 | set_graph_function file in the debugfs tracing directory. | 1404 | set_graph_function file in the debugfs tracing directory. |
| 1405 | 1405 | ||
| 1406 | ftrace_graph_notrace=[function-list] | 1406 | ftrace_graph_notrace=[function-list] |
| 1407 | [FTRACE] Do not trace from the functions specified in | 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 | functions that can be changed at run time by the | 1409 | functions that can be changed at run time by the |
| 1410 | set_graph_notrace file in the debugfs tracing directory. | 1410 | set_graph_notrace file in the debugfs tracing directory. |
| 1411 | 1411 | ||
| @@ -2421,7 +2421,7 @@ · 1009 unmodified lines | |||
| 2421 | when set. | 2421 | when set. |
| 2422 | Format: <int> | 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 | separated list of "[ID:]VAL" where ID is | 2425 | separated list of "[ID:]VAL" where ID is |
| 2426 | PORT[.DEVICE]. PORT and DEVICE are decimal numbers | 2426 | PORT[.DEVICE]. PORT and DEVICE are decimal numbers |
| 2427 | matching port, link or device. Basically, it matches | 2427 | matching port, link or device. Basically, it matches |
| @@ -5145,7 +5145,7 @@ · 2717 unmodified lines | |||
| 5145 | 5145 | ||
| 5146 | stacktrace_filter=[function-list] | 5146 | stacktrace_filter=[function-list] |
| 5147 | [FTRACE] Limit the functions that the stack tracer | 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 | list of functions. This list can be changed at run | 5149 | list of functions. This list can be changed at run |
| 5150 | time by the stack_trace_filter file in the debugfs | 5150 | time by the stack_trace_filter file in the debugfs |
| 5151 | tracing directory. Note, this enables stack tracing | 5151 | tracing directory. Note, this enables stack tracing |
| @@ -5348,7 +5348,7 @@ · 196 unmodified lines | |||
| 5348 | trace_event=[event-list] | 5348 | trace_event=[event-list] |
| 5349 | [FTRACE] Set and start specified trace events in order | 5349 | [FTRACE] Set and start specified trace events in order |
| 5350 | to facilitate early boot debugging. The event-list is a | 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 | also Documentation/trace/events.rst | 5352 | also Documentation/trace/events.rst |
| 5353 | 5353 | ||
| 5354 | trace_options=[option-list] | 5354 | trace_options=[option-list] |
| @@ -5972,6 +5972,10 @@ · 617 unmodified lines | |||
| 5972 | This option is obsoleted by the "nopv" option, which | 5972 | This option is obsoleted by the "nopv" option, which |
| 5973 | has equivalent effect for XEN platform. | 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 | xen_scrub_pages= [XEN] | 5979 | xen_scrub_pages= [XEN] |
| 5976 | Boolean option to control scrubbing pages before giving them back | 5980 | Boolean option to control scrubbing pages before giving them back |
| 5977 | to Xen, for use by other domains. Can be also changed at runtime | 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 | of the system. When the system is not loaded, most of the memory is free | 184 | of the system. When the system is not loaded, most of the memory is free |
| 185 | and allocation requests will be satisfied immediately from the free | 185 | and allocation requests will be satisfied immediately from the free |
| 186 | pages supply. As the load increases, the amount of the free pages goes | 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 | allocation request will awaken the ``kswapd`` daemon. It will | 188 | allocation request will awaken the ``kswapd`` daemon. It will |
| 189 | asynchronously scan memory pages and either just free them if the data | 189 | asynchronously scan memory pages and either just free them if the data |
| 190 | they contain is available elsewhere, or evict to the backing storage | 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 | .. toctree:: | 53 | .. toctree:: |
| 54 | :maxdepth: 1 | 54 | :maxdepth: 1 |
| 55 | 55 | ||
| 56 | atomic_ops | ||
| 57 | refcount-vs-atomic | 56 | refcount-vs-atomic |
| 58 | irq/index | 57 | irq/index |
| 59 | local_ops | 58 | local_ops |
| @@ -1,4 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 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 | %YAML 1.2 | 4 | %YAML 1.2 |
| 3 | --- | 5 | --- |
| 4 | $id: http://devicetree.org/schemas/dma/ti/k3-bcdma.yaml# | 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 | title: Texas Instruments K3 DMSS BCDMA Device Tree Bindings | 9 | title: Texas Instruments K3 DMSS BCDMA Device Tree Bindings |
| 8 | 10 | ||
| 9 | maintainers: | 11 | maintainers: |
| 10 | - Peter Ujfalusi <peter.ujfalusi@ti.com> | 12 | - Peter Ujfalusi <peter.ujfalusi@gmail.com> |
| 11 | 13 | ||
| 12 | description: | | 14 | description: | |
| 13 | The Block Copy DMA (BCDMA) is intended to perform similar functions as the TR | 15 | The Block Copy DMA (BCDMA) is intended to perform similar functions as the TR |
| @@ -1,4 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 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 | %YAML 1.2 | 4 | %YAML 1.2 |
| 3 | --- | 5 | --- |
| 4 | $id: http://devicetree.org/schemas/dma/ti/k3-pktdma.yaml# | 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 | title: Texas Instruments K3 DMSS PKTDMA Device Tree Bindings | 9 | title: Texas Instruments K3 DMSS PKTDMA Device Tree Bindings |
| 8 | 10 | ||
| 9 | maintainers: | 11 | maintainers: |
| 10 | - Peter Ujfalusi <peter.ujfalusi@ti.com> | 12 | - Peter Ujfalusi <peter.ujfalusi@gmail.com> |
| 11 | 13 | ||
| 12 | description: | | 14 | description: | |
| 13 | The Packet DMA (PKTDMA) is intended to perform similar functions as the packet | 15 | The Packet DMA (PKTDMA) is intended to perform similar functions as the packet |
| @@ -1,4 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 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 | %YAML 1.2 | 4 | %YAML 1.2 |
| 3 | --- | 5 | --- |
| 4 | $id: http://devicetree.org/schemas/dma/ti/k3-udma.yaml# | 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 | title: Texas Instruments K3 NAVSS Unified DMA Device Tree Bindings | 9 | title: Texas Instruments K3 NAVSS Unified DMA Device Tree Bindings |
| 8 | 10 | ||
| 9 | maintainers: | 11 | maintainers: |
| 10 | - Peter Ujfalusi <peter.ujfalusi@ti.com> | 12 | - Peter Ujfalusi <peter.ujfalusi@gmail.com> |
| 11 | 13 | ||
| 12 | description: | | 14 | description: | |
| 13 | The UDMA-P is intended to perform similar (but significantly upgraded) | 15 | The UDMA-P is intended to perform similar (but significantly upgraded) |
| @@ -163,6 +163,7 @@ allOf: · 162 unmodified lines | |||
| 163 | enum: | 163 | enum: |
| 164 | - renesas,etheravb-r8a774a1 | 164 | - renesas,etheravb-r8a774a1 |
| 165 | - renesas,etheravb-r8a774b1 | 165 | - renesas,etheravb-r8a774b1 |
| 166 | - renesas,etheravb-r8a774e1 | ||
| 166 | - renesas,etheravb-r8a7795 | 167 | - renesas,etheravb-r8a7795 |
| 167 | - renesas,etheravb-r8a7796 | 168 | - renesas,etheravb-r8a7796 |
| 168 | - renesas,etheravb-r8a77961 | 169 | - renesas,etheravb-r8a77961 |
| @@ -161,7 +161,8 @@ properties: · 160 unmodified lines | |||
| 161 | * snps,route-dcbcp, DCB Control Packets | 161 | * snps,route-dcbcp, DCB Control Packets |
| 162 | * snps,route-up, Untagged Packets | 162 | * snps,route-up, Untagged Packets |
| 163 | * snps,route-multi-broad, Multicast & Broadcast Packets | 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 | snps,mtl-tx-config: | 167 | snps,mtl-tx-config: |
| 167 | $ref: /schemas/types.yaml#/definitions/phandle | 168 | $ref: /schemas/types.yaml#/definitions/phandle |
| @@ -188,7 +189,10 @@ properties: · 20 unmodified lines | |||
| 188 | * snps,idle_slope, unlock on WoL | 189 | * snps,idle_slope, unlock on WoL |
| 189 | * snps,high_credit, max write outstanding req. limit | 190 | * snps,high_credit, max write outstanding req. limit |
| 190 | * snps,low_credit, max read outstanding req. limit | 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 | snps,reset-gpio: | 197 | snps,reset-gpio: |
| 194 | deprecated: true | 198 | deprecated: true |
| @@ -19,7 +19,9 @@ description: | · 18 unmodified lines | |||
| 19 | properties: | 19 | properties: |
| 20 | compatible: | 20 | compatible: |
| 21 | enum: | 21 | enum: |
| 22 | - nxp,pf8x00 | 22 | - nxp,pf8100 |
| 23 | - nxp,pf8121a | ||
| 24 | - nxp,pf8200 | ||
| 23 | 25 | ||
| 24 | reg: | 26 | reg: |
| 25 | maxItems: 1 | 27 | maxItems: 1 |
| @@ -118,7 +120,7 @@ examples: · 92 unmodified lines | |||
| 118 | #size-cells = <0>; | 120 | #size-cells = <0>; |
| 119 | 121 | ||
| 120 | pmic@8 { | 122 | pmic@8 { |
| 121 | compatible = "nxp,pf8x00"; | 123 | compatible = "nxp,pf8100"; |
| 122 | reg = <0x08>; | 124 | reg = <0x08>; |
| 123 | 125 | ||
| 124 | regulators { | 126 | regulators { |
| @@ -44,6 +44,7 @@ First Level Nodes - PMIC · 43 unmodified lines | |||
| 44 | Definition: Must be one of below: | 44 | Definition: Must be one of below: |
| 45 | "qcom,pm8005-rpmh-regulators" | 45 | "qcom,pm8005-rpmh-regulators" |
| 46 | "qcom,pm8009-rpmh-regulators" | 46 | "qcom,pm8009-rpmh-regulators" |
| 47 | "qcom,pm8009-1-rpmh-regulators" | ||
| 47 | "qcom,pm8150-rpmh-regulators" | 48 | "qcom,pm8150-rpmh-regulators" |
| 48 | "qcom,pm8150l-rpmh-regulators" | 49 | "qcom,pm8150l-rpmh-regulators" |
| 49 | "qcom,pm8350-rpmh-regulators" | 50 | "qcom,pm8350-rpmh-regulators" |
| @@ -1,4 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 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 | %YAML 1.2 | 4 | %YAML 1.2 |
| 3 | --- | 5 | --- |
| 4 | $id: http://devicetree.org/schemas/sound/ti,j721e-cpb-audio.yaml# | 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 | title: Texas Instruments J721e Common Processor Board Audio Support | 9 | title: Texas Instruments J721e Common Processor Board Audio Support |
| 8 | 10 | ||
| 9 | maintainers: | 11 | maintainers: |
| 10 | - Peter Ujfalusi <peter.ujfalusi@ti.com> | 12 | - Peter Ujfalusi <peter.ujfalusi@gmail.com> |
| 11 | 13 | ||
| 12 | description: | | 14 | description: | |
| 13 | The audio support on the board is using pcm3168a codec connected to McASP10 | 15 | The audio support on the board is using pcm3168a codec connected to McASP10 |
| @@ -1,4 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 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 | %YAML 1.2 | 4 | %YAML 1.2 |
| 3 | --- | 5 | --- |
| 4 | $id: http://devicetree.org/schemas/sound/ti,j721e-cpb-ivi-audio.yaml# | 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 | title: Texas Instruments J721e Common Processor Board Audio Support | 9 | title: Texas Instruments J721e Common Processor Board Audio Support |
| 8 | 10 | ||
| 9 | maintainers: | 11 | maintainers: |
| 10 | - Peter Ujfalusi <peter.ujfalusi@ti.com> | 12 | - Peter Ujfalusi <peter.ujfalusi@gmail.com> |
| 11 | 13 | ||
| 12 | description: | | 14 | description: | |
| 13 | The Infotainment board plugs into the Common Processor Board, the support of the | 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 | properties: | 12 | properties: |
| 13 | compatible: | 13 | compatible: |
| 14 | items: | 14 | oneOf: |
| 15 | - const: ti,j721e-usb | 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 | reg: | 21 | reg: |
| 18 | description: module registers | 22 | description: module registers |
| @@ -48,12 +48,12 @@ or ``virtualenv``, depending on how your distribution packaged Python 3. · 47 unmodified lines | |||
| 48 | those versions, you should run ``pip install 'docutils==0.12'``. | 48 | those versions, you should run ``pip install 'docutils==0.12'``. |
| 49 | 49 | ||
| 50 | #) It is recommended to use the RTD theme for html output. Depending | 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 | with ``pip install sphinx_rtd_theme``. | 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 | those expressions are written using LaTeX notation. It needs texlive | 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 | In summary, if you want to install Sphinx version 1.7.9, you should do:: | 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 | The usual way to generate the documentation is to run ``make htmldocs`` or | 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 | section of ``make help``. The generated documentation is placed in | 132 | section of ``make help``. The generated documentation is placed in |
| 133 | format-specific subdirectories under ``Documentation/output``. | 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 | - head col 3 | 303 | - head col 3 |
| 304 | - head col 4 | 304 | - head col 4 |
| 305 | 305 | ||
| 306 | * - column 1 | 306 | * - row 1 |
| 307 | - field 1.1 | 307 | - field 1.1 |
| 308 | - field 1.2 with autospan | 308 | - field 1.2 with autospan |
| 309 | 309 | ||
| 310 | * - column 2 | 310 | * - row 2 |
| 311 | - field 2.1 | 311 | - field 2.1 |
| 312 | - :rspan:`1` :cspan:`1` field 2.2 - 3.3 | 312 | - :rspan:`1` :cspan:`1` field 2.2 - 3.3 |
| 313 | 313 | ||
| 314 | * .. _`last row`: | 314 | * .. _`last row`: |
| 315 | 315 | ||
| 316 | - column 3 | 316 | - row 3 |
| 317 | 317 | ||
| 318 | Rendered as: | 318 | Rendered as: |
| 319 | 319 | ||
| @@ -325,17 +325,17 @@ Rendered as: · 5 unmodified lines | |||
| 325 | - head col 3 | 325 | - head col 3 |
| 326 | - head col 4 | 326 | - head col 4 |
| 327 | 327 | ||
| 328 | * - column 1 | 328 | * - row 1 |
| 329 | - field 1.1 | 329 | - field 1.1 |
| 330 | - field 1.2 with autospan | 330 | - field 1.2 with autospan |
| 331 | 331 | ||
| 332 | * - column 2 | 332 | * - row 2 |
| 333 | - field 2.1 | 333 | - field 2.1 |
| 334 | - :rspan:`1` :cspan:`1` field 2.2 - 3.3 | 334 | - :rspan:`1` :cspan:`1` field 2.2 - 3.3 |
| 335 | 335 | ||
| 336 | * .. _`last row`: | 336 | * .. _`last row`: |
| 337 | 337 | ||
| 338 | - column 3 | 338 | - row 3 |
| 339 | 339 | ||
| 340 | Cross-referencing | 340 | Cross-referencing |
| 341 | ----------------- | 341 | ----------------- |
| @@ -361,7 +361,7 @@ Figures & Images · 19 unmodified lines | |||
| 361 | 361 | ||
| 362 | If you want to add an image, you should use the ``kernel-figure`` and | 362 | If you want to add an image, you should use the ``kernel-figure`` and |
| 363 | ``kernel-image`` directives. E.g. to insert a figure with a scalable | 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 | .. kernel-figure:: svg_image.svg | 366 | .. kernel-figure:: svg_image.svg |
| 367 | :alt: simple SVG image | 367 | :alt: simple SVG image |
| @@ -375,7 +375,7 @@ image format use SVG (:ref:`svg_image_example`):: · 7 unmodified lines | |||
| 375 | 375 | ||
| 376 | SVG image example | 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 | * DOT: http://graphviz.org/pdf/dotguide.pdf | 380 | * DOT: http://graphviz.org/pdf/dotguide.pdf |
| 381 | * Graphviz: http://www.graphviz.org/content/dot-language | 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 | DOT's hello world example | 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 | ``kernel-render`` directives.:: | 398 | ``kernel-render`` directives.:: |
| 399 | 399 | ||
| 400 | .. kernel-render:: DOT | 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 | How this will be rendered depends on the installed tools. If Graphviz is | 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 | *literal-block* (:ref:`hello_dot_render`). | 410 | *literal-block* (:ref:`hello_dot_render`). |
| 411 | 411 | ||
| 412 | .. _hello_dot_render: | 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 | The *render* directive has all the options known from the *figure* directive, | 422 | The *render* directive has all the options known from the *figure* directive, |
| 423 | plus option ``caption``. If ``caption`` has a value, a *figure* node is | 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 | 424 | inserted. If not, an *image* node is inserted. A ``caption`` is also needed, if |
| 425 | you want to refer it (:ref:`hello_svg_render`). | 425 | you want to refer to it (:ref:`hello_svg_render`). |
| 426 | 426 | ||
| 427 | Embedded **SVG**:: | 427 | Embedded **SVG**:: |
| 428 | 428 | ||
| @@ -50,8 +50,8 @@ The following files belong to it: · 49 unmodified lines | |||
| 50 | 0x00000010 Memory Uncorrectable non-fatal | 50 | 0x00000010 Memory Uncorrectable non-fatal |
| 51 | 0x00000020 Memory Uncorrectable fatal | 51 | 0x00000020 Memory Uncorrectable fatal |
| 52 | 0x00000040 PCI Express Correctable | 52 | 0x00000040 PCI Express Correctable |
| 53 | 0x00000080 PCI Express Uncorrectable fatal | 53 | 0x00000080 PCI Express Uncorrectable non-fatal |
| 54 | 0x00000100 PCI Express Uncorrectable non-fatal | 54 | 0x00000100 PCI Express Uncorrectable fatal |
| 55 | 0x00000200 Platform Correctable | 55 | 0x00000200 Platform Correctable |
| 56 | 0x00000400 Platform Uncorrectable non-fatal | 56 | 0x00000400 Platform Uncorrectable non-fatal |
| 57 | 0x00000800 Platform Uncorrectable fatal | 57 | 0x00000800 Platform Uncorrectable fatal |
| @@ -1,7 +1,7 @@ | |||
| 1 | .. SPDX-License-Identifier: GPL-2.0-or-later | 1 | .. SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | 2 | ||
| 3 | Kernel driver sbtsi_temp | 3 | Kernel driver sbtsi_temp |
| 4 | ================== | 4 | ======================== |
| 5 | 5 | ||
| 6 | Supported hardware: | 6 | Supported hardware: |
| 7 | 7 | ||
| @@ -598,7 +598,7 @@ more details, with real examples. · 597 unmodified lines | |||
| 598 | explicitly added to $(targets). | 598 | explicitly added to $(targets). |
| 599 | 599 | ||
| 600 | Assignments to $(targets) are without $(obj)/ prefix. if_changed may be | 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 | Note: It is a typical mistake to forget the FORCE prerequisite. | 603 | Note: It is a typical mistake to forget the FORCE prerequisite. |
| 604 | Another common pitfall is that whitespace is sometimes significant; for | 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 | your task will suspend itself, and be woken up when the mutex is | 118 | your task will suspend itself, and be woken up when the mutex is |
| 119 | released. This means the CPU can do something else while you are | 119 | released. This means the CPU can do something else while you are |
| 120 | waiting. There are many cases when you simply can't sleep (see | 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 | and so have to use a spinlock instead. | 122 | and so have to use a spinlock instead. |
| 123 | 123 | ||
| 124 | Neither type of lock is recursive: see | 124 | Neither type of lock is recursive: see |
| 125 | `Deadlock: Simple and Advanced <#deadlock>`__. | 125 | `Deadlock: Simple and Advanced`_. |
| 126 | 126 | ||
| 127 | Locks and Uniprocessor Kernels | 127 | Locks and Uniprocessor Kernels |
| 128 | ------------------------------ | 128 | ------------------------------ |
| @@ -179,7 +179,7 @@ perfect world). · 50 unmodified lines | |||
| 179 | 179 | ||
| 180 | Note that you can also use spin_lock_irq() or | 180 | Note that you can also use spin_lock_irq() or |
| 181 | spin_lock_irqsave() here, which stop hardware interrupts | 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 | This works perfectly for UP as well: the spin lock vanishes, and this | 184 | This works perfectly for UP as well: the spin lock vanishes, and this |
| 185 | macro simply becomes local_bh_disable() | 185 | macro simply becomes local_bh_disable() |
| @@ -230,7 +230,7 @@ The Same Softirq · 44 unmodified lines | |||
| 230 | ~~~~~~~~~~~~~~~~ | 230 | ~~~~~~~~~~~~~~~~ |
| 231 | 231 | ||
| 232 | The same softirq can run on the other CPUs: you can use a per-CPU array | 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 | going so far as to use a softirq, you probably care about scalable | 234 | going so far as to use a softirq, you probably care about scalable |
| 235 | performance enough to justify the extra complexity. | 235 | performance enough to justify the extra complexity. |
| 236 | 236 | ||
| @@ -164,46 +164,56 @@ Devlink health reporters · 163 unmodified lines | |||
| 164 | 164 | ||
| 165 | NPA Reporters | 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 | 1. GENERAL events | 169 | 1. GENERAL events |
| 170 | |||
| 169 | - Error due to operation of unmapped PF. | 171 | - Error due to operation of unmapped PF. |
| 170 | - Error due to disabled alloc/free for other HW blocks (NIX, SSO, TIM, DPI and AURA). | 172 | - Error due to disabled alloc/free for other HW blocks (NIX, SSO, TIM, DPI and AURA). |
| 173 | |||
| 171 | 2. ERROR events | 174 | 2. ERROR events |
| 175 | |||
| 172 | - Fault due to NPA_AQ_INST_S read or NPA_AQ_RES_S write. | 176 | - Fault due to NPA_AQ_INST_S read or NPA_AQ_RES_S write. |
| 173 | - AQ Doorbell Error. | 177 | - AQ Doorbell Error. |
| 178 | |||
| 174 | 3. RAS events | 179 | 3. RAS events |
| 180 | |||
| 175 | - RAS Error Reporting for NPA_AQ_INST_S/NPA_AQ_RES_S. | 181 | - RAS Error Reporting for NPA_AQ_INST_S/NPA_AQ_RES_S. |
| 182 | |||
| 176 | 4. RVU events | 183 | 4. RVU events |
| 184 | |||
| 177 | - Error due to unmapped slot. | 185 | - Error due to unmapped slot. |
| 178 | 186 | ||
| 179 | Sample Output | 187 | Sample Output:: |
| 180 | ------------- | 188 | |
| 181 | ~# devlink health | 189 | ~# devlink health |
| 182 | pci/0002:01:00.0: | 190 | pci/0002:01:00.0: |
| 183 | reporter hw_npa_intr | 191 | 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 | 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 |
| 185 | reporter hw_npa_gen | 193 | 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 | 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 |
| 187 | reporter hw_npa_err | 195 | 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 | 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 |
| 189 | reporter hw_npa_ras | 197 | 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 | 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 | Each reporter dumps the | 200 | Each reporter dumps the |
| 201 | |||
| 193 | - Error Type | 202 | - Error Type |
| 194 | - Error Register value | 203 | - Error Register value |
| 195 | - Reason in words | 204 | - Reason in words |
| 196 | 205 | ||
| 197 | For eg: | 206 | For example:: |
| 198 | ~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_gen | 207 | |
| 199 | NPA_AF_GENERAL: | 208 | ~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_gen |
| 200 | NPA General Interrupt Reg : 1 | 209 | NPA_AF_GENERAL: |
| 201 | NIX0: free disabled RX | 210 | NPA General Interrupt Reg : 1 |
| 202 | ~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_intr | 211 | NIX0: free disabled RX |
| 203 | NPA_AF_RVU: | 212 | ~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_intr |
| 204 | NPA RVU Interrupt Reg : 1 | 213 | NPA_AF_RVU: |
| 205 | Unmap Slot Error | 214 | NPA RVU Interrupt Reg : 1 |
| 206 | ~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_err | 215 | Unmap Slot Error |
| 207 | NPA_AF_ERR: | 216 | ~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_err |
| 208 | NPA Error Interrupt Reg : 4096 | 217 | NPA_AF_ERR: |
| 209 | AQ Doorbell Error | 218 | NPA Error Interrupt Reg : 4096 |
| 219 | AQ Doorbell Error | ||
| @@ -6,9 +6,9 @@ · 5 unmodified lines | |||
| 6 | netdev FAQ | 6 | netdev FAQ |
| 7 | ========== | 7 | ========== |
| 8 | 8 | ||
| 9 | Q: What is netdev? | 9 | What is netdev? |
| 10 | ------------------ | 10 | --------------- |
| 11 | A: It is a mailing list for all network-related Linux stuff. This | 11 | It is a mailing list for all network-related Linux stuff. This |
| 12 | includes anything found under net/ (i.e. core code like IPv6) and | 12 | includes anything found under net/ (i.e. core code like IPv6) and |
| 13 | drivers/net (i.e. hardware specific drivers) in the Linux source tree. | 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 | Linux development (i.e. RFC, review, comments, etc.) takes place on | 25 | Linux development (i.e. RFC, review, comments, etc.) takes place on |
| 26 | netdev. | 26 | netdev. |
| 27 | 27 | ||
| 28 | Q: How do the changes posted to netdev make their way into Linux? | 28 | How do the changes posted to netdev make their way into Linux? |
| 29 | ----------------------------------------------------------------- | 29 | -------------------------------------------------------------- |
| 30 | A: There are always two trees (git repositories) in play. Both are | 30 | There are always two trees (git repositories) in play. Both are |
| 31 | driven by David Miller, the main network maintainer. There is the | 31 | driven by David Miller, the main network maintainer. There is the |
| 32 | ``net`` tree, and the ``net-next`` tree. As you can probably guess from | 32 | ``net`` tree, and the ``net-next`` tree. As you can probably guess from |
| 33 | the names, the ``net`` tree is for fixes to existing code already in the | 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 | - https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git | 37 | - https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git |
| 38 | - https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git | 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? | 40 | How often do changes from these trees make it to the mainline Linus tree? |
| 41 | ---------------------------------------------------------------------------- | 41 | ------------------------------------------------------------------------- |
| 42 | A: To understand this, you need to know a bit of background information on | 42 | To understand this, you need to know a bit of background information on |
| 43 | the cadence of Linux development. Each new release starts off with a | 43 | the cadence of Linux development. Each new release starts off with a |
| 44 | two week "merge window" where the main maintainers feed their new stuff | 44 | two week "merge window" where the main maintainers feed their new stuff |
| 45 | to Linus for merging into the mainline tree. After the two weeks, the | 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 | Finally, the vX.Y gets released, and the whole cycle starts over. | 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 | Load the mainline (Linus) page here: | 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 | the dev cycle. If it was tagged rc7 a week ago, then a release is | 92 | the dev cycle. If it was tagged rc7 a week ago, then a release is |
| 92 | probably imminent. | 93 | probably imminent. |
| 93 | 94 | ||
| 94 | Q: How do I indicate which tree (net vs. net-next) my patch should be in? | 95 | How do I indicate which tree (net vs. net-next) my patch should be in? |
| 95 | ------------------------------------------------------------------------- | 96 | ---------------------------------------------------------------------- |
| 96 | A: Firstly, think whether you have a bug fix or new "next-like" content. | 97 | Firstly, think whether you have a bug fix or new "next-like" content. |
| 97 | Then once decided, assuming that you use git, use the prefix flag, i.e. | 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 | can manually change it yourself with whatever MUA you are comfortable | 106 | can manually change it yourself with whatever MUA you are comfortable |
| 106 | with. | 107 | with. |
| 107 | 108 | ||
| 108 | Q: I sent a patch and I'm wondering what happened to it? | 109 | I sent a patch and I'm wondering what happened to it - how can I tell whether it got merged? |
| 109 | -------------------------------------------------------- | 110 | -------------------------------------------------------------------------------------------- |
| 110 | Q: How can I tell whether it got merged? | 111 | Start by looking at the main patchworks queue for netdev: |
| 111 | A: Start by looking at the main patchworks queue for netdev: | ||
| 112 | 112 | ||
| 113 | https://patchwork.kernel.org/project/netdevbpf/list/ | 113 | https://patchwork.kernel.org/project/netdevbpf/list/ |
| 114 | 114 | ||
| 115 | The "State" field will tell you exactly where things are at with your | 115 | The "State" field will tell you exactly where things are at with your |
| 116 | patch. | 116 | patch. |
| 117 | 117 | ||
| 118 | Q: The above only says "Under Review". How can I find out more? | 118 | The above only says "Under Review". How can I find out more? |
| 119 | ---------------------------------------------------------------- | 119 | ------------------------------------------------------------- |
| 120 | A: Generally speaking, the patches get triaged quickly (in less than | 120 | Generally speaking, the patches get triaged quickly (in less than |
| 121 | 48h). So be patient. Asking the maintainer for status updates on your | 121 | 48h). So be patient. Asking the maintainer for status updates on your |
| 122 | patch is a good way to ensure your patch is ignored or pushed to the | 122 | patch is a good way to ensure your patch is ignored or pushed to the |
| 123 | bottom of the priority list. | 123 | bottom of the priority list. |
| 124 | 124 | ||
| 125 | Q: I submitted multiple versions of the patch series | 125 | I submitted multiple versions of the patch series. Should I directly update patchwork for the previous versions of these patch series? |
| 126 | ---------------------------------------------------- | 126 | -------------------------------------------------------------------------------------------------------------------------------------- |
| 127 | Q: should I directly update patchwork for the previous versions of these | 127 | No, please don't interfere with the patch status on patchwork, leave |
| 128 | patch series? | ||
| 129 | A: No, please don't interfere with the patch status on patchwork, leave | ||
| 130 | it to the maintainer to figure out what is the most recent and current | 128 | it to the maintainer to figure out what is the most recent and current |
| 131 | version that should be applied. If there is any doubt, the maintainer | 129 | version that should be applied. If there is any doubt, the maintainer |
| 132 | will reply and ask what should be done. | 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? | 132 | I made changes to only a few patches in a patch series should I resend only those changed? |
| 135 | --------------------------------------------------------------------------------------------- | 133 | ------------------------------------------------------------------------------------------ |
| 136 | A: No, please resend the entire patch series and make sure you do number your | 134 | No, please resend the entire patch series and make sure you do number your |
| 137 | patches such that it is clear this is the latest and greatest set of patches | 135 | patches such that it is clear this is the latest and greatest set of patches |
| 138 | that can be applied. | 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? | 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? |
| 141 | ------------------------------------------------------------------------------------------------------------------------------------------- | 139 | ---------------------------------------------------------------------------------------------------------------------------------------- |
| 142 | A: There is no revert possible, once it is pushed out, it stays like that. | 140 | There is no revert possible, once it is pushed out, it stays like that. |
| 143 | Please send incremental versions on top of what has been merged in order to fix | 141 | Please send incremental versions on top of what has been merged in order to fix |
| 144 | the patches the way they would look like if your latest patch series was to be | 142 | the patches the way they would look like if your latest patch series was to be |
| 145 | merged. | 143 | merged. |
| 146 | 144 | ||
| 147 | Q: How can I tell what patches are queued up for backporting to the various stable releases? | 145 | How can I tell what patches are queued up for backporting to the various stable releases? |
| 148 | -------------------------------------------------------------------------------------------- | 146 | ----------------------------------------------------------------------------------------- |
| 149 | A: Normally Greg Kroah-Hartman collects stable commits himself, but for | 147 | Normally Greg Kroah-Hartman collects stable commits himself, but for |
| 150 | networking, Dave collects up patches he deems critical for the | 148 | networking, Dave collects up patches he deems critical for the |
| 151 | networking subsystem, and then hands them off to Greg. | 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 | releases/3.9.8/ipv6-fix-possible-crashes-in-ip6_cork_release.patch | 167 | releases/3.9.8/ipv6-fix-possible-crashes-in-ip6_cork_release.patch |
| 170 | stable/stable-queue$ | 168 | stable/stable-queue$ |
| 171 | 169 | ||
| 172 | Q: I see a network patch and I think it should be backported to stable. | 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? |
| 173 | ----------------------------------------------------------------------- | 171 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 174 | Q: Should I request it via stable@vger.kernel.org like the references in | 172 | No, not for networking. Check the stable queues as per above first |
| 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 | ||
| 177 | to see if it is already queued. If not, then send a mail to netdev, | 173 | to see if it is already queued. If not, then send a mail to netdev, |
| 178 | listing the upstream commit ID and why you think it should be a stable | 174 | listing the upstream commit ID and why you think it should be a stable |
| 179 | candidate. | 175 | candidate. |
| @@ -190,11 +186,9 @@ mainline, the better the odds that it is an OK candidate for stable. So · 10 unmodified lines | |||
| 190 | scrambling to request a commit be added the day after it appears should | 186 | scrambling to request a commit be added the day after it appears should |
| 191 | be avoided. | 187 | be avoided. |
| 192 | 188 | ||
| 193 | Q: I have created a network patch and I think it should be backported to stable. | 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? |
| 194 | -------------------------------------------------------------------------------- | 190 | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 195 | Q: Should I add a Cc: stable@vger.kernel.org like the references in the | 191 | No. See above answer. In short, if you think it really belongs in |
| 196 | kernel's Documentation/ directory say? | ||
| 197 | A: No. See above answer. In short, if you think it really belongs in | ||
| 198 | stable, then ensure you write a decent commit log that describes who | 192 | stable, then ensure you write a decent commit log that describes who |
| 199 | gets impacted by the bug fix and how it manifests itself, and when the | 193 | gets impacted by the bug fix and how it manifests itself, and when the |
| 200 | bug was introduced. If you do that properly, then the commit will get | 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 | :ref:`Documentation/process/submitting-patches.rst <the_canonical_patch_format>` | 201 | :ref:`Documentation/process/submitting-patches.rst <the_canonical_patch_format>` |
| 208 | to temporarily embed that information into the patch that you send. | 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? | 204 | Are all networking bug fixes backported to all stable releases? |
| 211 | ------------------------------------------------------------------ | 205 | --------------------------------------------------------------- |
| 212 | A: Due to capacity, Dave could only take care of the backports for the | 206 | Due to capacity, Dave could only take care of the backports for the |
| 213 | last two stable releases. For earlier stable releases, each stable | 207 | last two stable releases. For earlier stable releases, each stable |
| 214 | branch maintainer is supposed to take care of them. If you find any | 208 | branch maintainer is supposed to take care of them. If you find any |
| 215 | patch is missing from an earlier stable branch, please notify | 209 | patch is missing from an earlier stable branch, please notify |
| 216 | stable@vger.kernel.org with either a commit ID or a formal patch | 210 | stable@vger.kernel.org with either a commit ID or a formal patch |
| 217 | backported, and CC Dave and other relevant networking developers. | 211 | backported, and CC Dave and other relevant networking developers. |
| 218 | 212 | ||
| 219 | Q: Is the comment style convention different for the networking content? | 213 | Is the comment style convention different for the networking content? |
| 220 | ------------------------------------------------------------------------ | 214 | --------------------------------------------------------------------- |
| 221 | A: Yes, in a largely trivial way. Instead of this:: | 215 | Yes, in a largely trivial way. Instead of this:: |
| 222 | 216 | ||
| 223 | /* | 217 | /* |
| 224 | * foobar blah blah blah | 218 | * foobar blah blah blah |
| @@ -231,32 +225,30 @@ it is requested that you make it look like this:: · 6 unmodified lines | |||
| 231 | * another line of text | 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. | 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? |
| 235 | -------------------------------------------------------------------------------------- | 229 | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| 236 | Q: Should I submit new code in the former style or the latter? | 230 | Make it the latter style, so that eventually all code in the domain |
| 237 | A: Make it the latter style, so that eventually all code in the domain | ||
| 238 | of netdev is of this format. | 231 | of netdev is of this format. |
| 239 | 232 | ||
| 240 | Q: I found a bug that might have possible security implications or similar. | 233 | I found a bug that might have possible security implications or similar. Should I mail the main netdev maintainer off-list? |
| 241 | --------------------------------------------------------------------------- | 234 | --------------------------------------------------------------------------------------------------------------------------- |
| 242 | Q: Should I mail the main netdev maintainer off-list?** | 235 | No. The current netdev maintainer has consistently requested that |
| 243 | A: No. The current netdev maintainer has consistently requested that | ||
| 244 | people use the mailing lists and not reach out directly. If you aren't | 236 | people use the mailing lists and not reach out directly. If you aren't |
| 245 | OK with that, then perhaps consider mailing security@kernel.org or | 237 | OK with that, then perhaps consider mailing security@kernel.org or |
| 246 | reading about http://oss-security.openwall.org/wiki/mailing-lists/distros | 238 | reading about http://oss-security.openwall.org/wiki/mailing-lists/distros |
| 247 | as possible alternative mechanisms. | 239 | as possible alternative mechanisms. |
| 248 | 240 | ||
| 249 | Q: What level of testing is expected before I submit my change? | 241 | What level of testing is expected before I submit my change? |
| 250 | --------------------------------------------------------------- | 242 | ------------------------------------------------------------ |
| 251 | A: If your changes are against ``net-next``, the expectation is that you | 243 | If your changes are against ``net-next``, the expectation is that you |
| 252 | have tested by layering your changes on top of ``net-next``. Ideally | 244 | have tested by layering your changes on top of ``net-next``. Ideally |
| 253 | you will have done run-time testing specific to your change, but at a | 245 | you will have done run-time testing specific to your change, but at a |
| 254 | minimum, your changes should survive an ``allyesconfig`` and an | 246 | minimum, your changes should survive an ``allyesconfig`` and an |
| 255 | ``allmodconfig`` build without new warnings or failures. | 247 | ``allmodconfig`` build without new warnings or failures. |
| 256 | 248 | ||
| 257 | Q: How do I post corresponding changes to user space components? | 249 | How do I post corresponding changes to user space components? |
| 258 | ---------------------------------------------------------------- | 250 | ------------------------------------------------------------- |
| 259 | A: User space code exercising kernel features should be posted | 251 | User space code exercising kernel features should be posted |
| 260 | alongside kernel patches. This gives reviewers a chance to see | 252 | alongside kernel patches. This gives reviewers a chance to see |
| 261 | how any new interface is used and how well it works. | 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 | Posting as one thread is discouraged because it confuses patchwork | 272 | Posting as one thread is discouraged because it confuses patchwork |
| 281 | (as of patchwork 2.2.2). | 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? | 275 | Any other tips to help ensure my net/net-next patch gets OK'd? |
| 284 | ----------------------------------------------------------------- | 276 | -------------------------------------------------------------- |
| 285 | A: Attention to detail. Re-read your own work as if you were the | 277 | Attention to detail. Re-read your own work as if you were the |
| 286 | reviewer. You can start with using ``checkpatch.pl``, perhaps even with | 278 | reviewer. You can start with using ``checkpatch.pl``, perhaps even with |
| 287 | the ``--strict`` flag. But do not be mindlessly robotic in doing so. | 279 | the ``--strict`` flag. But do not be mindlessly robotic in doing so. |
| 288 | If your change is a bug fix, make sure your commit log indicates the | 280 | If your change is a bug fix, make sure your commit log indicates the |
| @@ -10,18 +10,177 @@ Introduction · 9 unmodified lines | |||
| 10 | The following is a random collection of documentation regarding | 10 | The following is a random collection of documentation regarding |
| 11 | network devices. | 11 | network devices. |
| 12 | 12 | ||
| 13 | struct net_device allocation rules | 13 | struct net_device lifetime rules |
| 14 | ================================== | 14 | ================================ |
| 15 | Network device structures need to persist even after module is unloaded and | 15 | Network device structures need to persist even after module is unloaded and |
| 16 | must be allocated with alloc_netdev_mqs() and friends. | 16 | must be allocated with alloc_netdev_mqs() and friends. |
| 17 | If device has registered successfully, it will be freed on last use | 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 | 18 | by free_netdev(). This is required to handle the pathological case cleanly |
| 19 | (example: rmmod mydriver </sys/class/net/myeth/mtu ) | 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 | private data which gets freed when the network device is freed. If | 22 | private data which gets freed when the network device is freed. If |
| 23 | separately allocated data is attached to the network device | 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 | MTU | 185 | MTU |
| 27 | === | 186 | === |
| @@ -64,8 +223,8 @@ ndo_do_ioctl: · 36 unmodified lines | |||
| 64 | Context: process | 223 | Context: process |
| 65 | 224 | ||
| 66 | ndo_get_stats: | 225 | ndo_get_stats: |
| 67 | Synchronization: dev_base_lock rwlock. | 226 | Synchronization: rtnl_lock() semaphore, dev_base_lock rwlock, or RCU. |
| 68 | Context: nominally process, but don't sleep inside an rwlock | 227 | Context: atomic (can't sleep under rwlock or RCU) |
| 69 | 228 | ||
| 70 | ndo_start_xmit: | 229 | ndo_start_xmit: |
| 71 | Synchronization: __netif_tx_lock spinlock. | 230 | Synchronization: __netif_tx_lock spinlock. |
| @@ -8,7 +8,7 @@ Abstract · 7 unmodified lines | |||
| 8 | ======== | 8 | ======== |
| 9 | 9 | ||
| 10 | This file documents the mmap() facility available with the PACKET | 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 | i) capture network traffic with utilities like tcpdump, | 13 | i) capture network traffic with utilities like tcpdump, |
| 14 | ii) transmit network traffic, or any other that needs raw | 14 | ii) transmit network traffic, or any other that needs raw |
| @@ -25,12 +25,12 @@ Please send your comments to · 10 unmodified lines | |||
| 25 | Why use PACKET_MMAP | 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 | inefficient. It uses very limited buffers and requires one system call to | 29 | inefficient. It uses very limited buffers and requires one system call to |
| 30 | capture each packet, it requires two if you want to get packet's timestamp | 30 | capture each packet, it requires two if you want to get packet's timestamp |
| 31 | (like libpcap always does). | 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 | configurable circular buffer mapped in user space that can be used to either | 34 | configurable circular buffer mapped in user space that can be used to either |
| 35 | send or receive packets. This way reading packets just needs to wait for them, | 35 | send or receive packets. This way reading packets just needs to wait for them, |
| 36 | most of the time there is no need to issue a single system call. Concerning | 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 | In kernel versions prior to 2.4.26 (for the 2.4 branch) and 2.6.5 (2.6 branch), | 253 | In kernel versions prior to 2.4.26 (for the 2.4 branch) and 2.6.5 (2.6 branch), |
| 254 | the PACKET_MMAP buffer could hold only 32768 frames in a 32 bit architecture or | 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 | 255 | 16384 in a 64 bit architecture. |
| 256 | see http://pusa.uv.es/~ulisses/packet_mmap/packet_mmap.pre-2.4.26_2.6.5.txt | ||
| 257 | 256 | ||
| 258 | Block size limit | 257 | Block size limit |
| 259 | ---------------- | 258 | ---------------- |
| @@ -437,7 +436,7 @@ and the following flags apply: · 177 unmodified lines | |||
| 437 | Capture process | 436 | Capture process |
| 438 | ^^^^^^^^^^^^^^^ | 437 | ^^^^^^^^^^^^^^^ |
| 439 | 438 | ||
| 440 | from include/linux/if_packet.h | 439 | From include/linux/if_packet.h:: |
| 441 | 440 | ||
| 442 | #define TP_STATUS_COPY (1 << 1) | 441 | #define TP_STATUS_COPY (1 << 1) |
| 443 | #define TP_STATUS_LOSING (1 << 2) | 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 | offloads, old connections will remain active after flags are cleared. | 530 | offloads, old connections will remain active after flags are cleared. |
| 531 | 531 | ||
| 532 | TLS encryption cannot be offloaded to devices without checksum calculation | 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 | Disabling the latter implies clearing the former. Disabling TX checksum offload | 534 | Disabling the latter implies clearing the former. Disabling TX checksum offload |
| 535 | should not affect old connections, and drivers should make sure checksum | 535 | should not affect old connections, and drivers should make sure checksum |
| 536 | calculation does not break for them. | 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 | of these options should be turned on for any kernel used for development or | 249 | of these options should be turned on for any kernel used for development or |
| 250 | testing purposes. In particular, you should turn on: | 250 | testing purposes. In particular, you should turn on: |
| 251 | 251 | ||
| 252 | - ENABLE_MUST_CHECK and FRAME_WARN to get an | 252 | - FRAME_WARN to get warnings for stack frames larger than a given amount. |
| 253 | extra set of warnings for problems like the use of deprecated interfaces | 253 | The output generated can be verbose, but one need not worry about |
| 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 | ||
| 256 | warnings from other parts of the kernel. | 254 | warnings from other parts of the kernel. |
| 257 | 255 | ||
| 258 | - DEBUG_OBJECTS will add code to track the lifetime of various objects | 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 | This module supports multiple cards. | 1502 | This module supports multiple cards. |
| 1503 | Note: One miXart8 board will be represented as 4 alsa cards. | 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 | When the driver is compiled as a module and the hotplug firmware | 1506 | When the driver is compiled as a module and the hotplug firmware |
| 1507 | is supported, the firmware data is loaded via hotplug automatically. | 1507 | is supported, the firmware data is loaded via hotplug automatically. |
| @@ -71,7 +71,7 @@ core/oss · 70 unmodified lines | |||
| 71 | The codes for PCM and mixer OSS emulation modules are stored in this | 71 | The codes for PCM and mixer OSS emulation modules are stored in this |
| 72 | directory. The rawmidi OSS emulation is included in the ALSA rawmidi | 72 | directory. The rawmidi OSS emulation is included in the ALSA rawmidi |
| 73 | code since it's quite small. The sequencer code is stored in | 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 | core/seq | 76 | core/seq |
| 77 | ~~~~~~~~ | 77 | ~~~~~~~~ |
| @@ -382,7 +382,7 @@ where ``enable[dev]`` is the module option. · 304 unmodified lines | |||
| 382 | Each time the ``probe`` callback is called, check the availability of | 382 | Each time the ``probe`` callback is called, check the availability of |
| 383 | the device. If not available, simply increment the device index and | 383 | the device. If not available, simply increment the device index and |
| 384 | returns. dev will be incremented also later (`step 7 | 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 | 2) Create a card instance | 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 | 5) Create other components, such as mixer, MIDI, etc. | 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>`__, | 453 | Here you define the basic components such as `PCM <PCM Interface_>`__, |
| 454 | mixer (e.g. `AC97 <#API-for-AC97-Codec>`__), MIDI (e.g. | 454 | mixer (e.g. `AC97 <API for AC97 Codec_>`__), MIDI (e.g. |
| 455 | `MPU-401 <#MIDI-MPU401-UART-Interface>`__), and other interfaces. | 455 | `MPU-401 <MIDI (MPU401-UART) Interface_>`__), and other interfaces. |
| 456 | Also, if you want a `proc file <#Proc-Interface>`__, define it here, | 456 | Also, if you want a `proc file <Proc Interface_>`__, define it here, |
| 457 | too. | 457 | too. |
| 458 | 458 | ||
| 459 | 6) Register the card instance. | 459 | 6) Register the card instance. |
| @@ -941,7 +941,7 @@ The allocation of an interrupt source is done like this: · 481 unmodified lines | |||
| 941 | chip->irq = pci->irq; | 941 | chip->irq = pci->irq; |
| 942 | 942 | ||
| 943 | where :c:func:`snd_mychip_interrupt()` is the interrupt handler | 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 | ``chip->irq`` should be defined only when :c:func:`request_irq()` | 945 | ``chip->irq`` should be defined only when :c:func:`request_irq()` |
| 946 | succeeded. | 946 | succeeded. |
| 947 | 947 | ||
| @@ -3104,7 +3104,7 @@ processing the output stream in the irq handler. · 2156 unmodified lines | |||
| 3104 | 3104 | ||
| 3105 | If the MPU-401 interface shares its interrupt with the other logical | 3105 | If the MPU-401 interface shares its interrupt with the other logical |
| 3106 | devices on the card, set ``MPU401_INFO_IRQ_HOOK`` (see | 3106 | devices on the card, set ``MPU401_INFO_IRQ_HOOK`` (see |
| 3107 | `below <#MIDI-Interrupt-Handler>`__). | 3107 | `below <MIDI Interrupt Handler_>`__). |
| 3108 | 3108 | ||
| 3109 | Usually, the port address corresponds to the command port and port + 1 | 3109 | Usually, the port address corresponds to the command port and port + 1 |
| 3110 | corresponds to the data port. If not, you may change the ``cport`` | 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 | Errors: | 393 | Errors: |
| 394 | 394 | ||
| 395 | ===== ============================= | 395 | ======= ============================================================== |
| 396 | EINTR an unmasked signal is pending | 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 | This ioctl is used to run a guest virtual cpu. While there are no | 404 | This ioctl is used to run a guest virtual cpu. While there are no |
| 400 | explicit parameters, there is an implicit parameter block that can be | 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 | F: net/wireless/ | 203 | F: net/wireless/ |
| 204 | 204 | ||
| 205 | 8169 10/100/1000 GIGABIT ETHERNET DRIVER | 205 | 8169 10/100/1000 GIGABIT ETHERNET DRIVER |
| 206 | M: Realtek linux nic maintainers <nic_swsd@realtek.com> | ||
| 207 | M: Heiner Kallweit <hkallweit1@gmail.com> | 206 | M: Heiner Kallweit <hkallweit1@gmail.com> |
| 207 | M: nic_swsd@realtek.com | ||
| 208 | L: netdev@vger.kernel.org | 208 | L: netdev@vger.kernel.org |
| 209 | S: Maintained | 209 | S: Maintained |
| 210 | F: drivers/net/ethernet/realtek/r8169* | 210 | F: drivers/net/ethernet/realtek/r8169* |
| @@ -820,7 +820,6 @@ M: Netanel Belgazal <netanel@amazon.com> · 609 unmodified lines | |||
| 820 | M: Arthur Kiyanovski <akiyano@amazon.com> | 820 | M: Arthur Kiyanovski <akiyano@amazon.com> |
| 821 | R: Guy Tzalik <gtzalik@amazon.com> | 821 | R: Guy Tzalik <gtzalik@amazon.com> |
| 822 | R: Saeed Bishara <saeedb@amazon.com> | 822 | R: Saeed Bishara <saeedb@amazon.com> |
| 823 | R: Zorik Machulsky <zorik@amazon.com> | ||
| 824 | L: netdev@vger.kernel.org | 823 | L: netdev@vger.kernel.org |
| 825 | S: Supported | 824 | S: Supported |
| 826 | F: Documentation/networking/device_drivers/ethernet/amazon/ena.rst | 825 | F: Documentation/networking/device_drivers/ethernet/amazon/ena.rst |
| @@ -907,7 +906,7 @@ AMD KFD · 80 unmodified lines | |||
| 907 | M: Felix Kuehling <Felix.Kuehling@amd.com> | 906 | M: Felix Kuehling <Felix.Kuehling@amd.com> |
| 908 | L: amd-gfx@lists.freedesktop.org | 907 | L: amd-gfx@lists.freedesktop.org |
| 909 | S: Supported | 908 | S: Supported |
| 910 | T: git git://people.freedesktop.org/~agd5f/linux | 909 | T: git https://gitlab.freedesktop.org/agd5f/linux.git |
| 911 | F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd*.[ch] | 910 | F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd*.[ch] |
| 912 | F: drivers/gpu/drm/amd/amdkfd/ | 911 | F: drivers/gpu/drm/amd/amdkfd/ |
| 913 | F: drivers/gpu/drm/amd/include/cik_structs.h | 912 | F: drivers/gpu/drm/amd/include/cik_structs.h |
| @@ -2119,7 +2118,7 @@ N: atmel · 1205 unmodified lines | |||
| 2119 | ARM/Microchip Sparx5 SoC support | 2118 | ARM/Microchip Sparx5 SoC support |
| 2120 | M: Lars Povlsen <lars.povlsen@microchip.com> | 2119 | M: Lars Povlsen <lars.povlsen@microchip.com> |
| 2121 | M: Steen Hegelund <Steen.Hegelund@microchip.com> | 2120 | M: Steen Hegelund <Steen.Hegelund@microchip.com> |
| 2122 | M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | 2121 | M: UNGLinuxDriver@microchip.com |
| 2123 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 2122 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 2124 | S: Supported | 2123 | S: Supported |
| 2125 | T: git git://github.com/microchip-ung/linux-upstream.git | 2124 | T: git git://github.com/microchip-ung/linux-upstream.git |
| @@ -2942,7 +2941,6 @@ S: Maintained · 816 unmodified lines | |||
| 2942 | F: drivers/hwmon/asus_atk0110.c | 2941 | F: drivers/hwmon/asus_atk0110.c |
| 2943 | 2942 | ||
| 2944 | ATLX ETHERNET DRIVERS | 2943 | ATLX ETHERNET DRIVERS |
| 2945 | M: Jay Cliburn <jcliburn@gmail.com> | ||
| 2946 | M: Chris Snook <chris.snook@gmail.com> | 2944 | M: Chris Snook <chris.snook@gmail.com> |
| 2947 | L: netdev@vger.kernel.org | 2945 | L: netdev@vger.kernel.org |
| 2948 | S: Maintained | 2946 | S: Maintained |
| @@ -3556,7 +3554,7 @@ S: Supported · 607 unmodified lines | |||
| 3556 | F: drivers/net/ethernet/broadcom/bnxt/ | 3554 | F: drivers/net/ethernet/broadcom/bnxt/ |
| 3557 | 3555 | ||
| 3558 | BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER | 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 | M: Franky Lin <franky.lin@broadcom.com> | 3558 | M: Franky Lin <franky.lin@broadcom.com> |
| 3561 | M: Hante Meuleman <hante.meuleman@broadcom.com> | 3559 | M: Hante Meuleman <hante.meuleman@broadcom.com> |
| 3562 | M: Chi-hsien Lin <chi-hsien.lin@infineon.com> | 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 | CADENCE USB3 DRD IP DRIVER | 3881 | CADENCE USB3 DRD IP DRIVER |
| 3884 | M: Peter Chen <peter.chen@nxp.com> | 3882 | M: Peter Chen <peter.chen@nxp.com> |
| 3885 | M: Pawel Laszczak <pawell@cadence.com> | 3883 | M: Pawel Laszczak <pawell@cadence.com> |
| 3886 | M: Roger Quadros <rogerq@ti.com> | 3884 | R: Roger Quadros <rogerq@kernel.org> |
| 3887 | R: Aswath Govindraju <a-govindraju@ti.com> | 3885 | R: Aswath Govindraju <a-govindraju@ti.com> |
| 3888 | L: linux-usb@vger.kernel.org | 3886 | L: linux-usb@vger.kernel.org |
| 3889 | S: Maintained | 3887 | S: Maintained |
| @@ -3961,7 +3959,7 @@ F: net/can/ · 71 unmodified lines | |||
| 3961 | CAN-J1939 NETWORK LAYER | 3959 | CAN-J1939 NETWORK LAYER |
| 3962 | M: Robin van der Gracht <robin@protonic.nl> | 3960 | M: Robin van der Gracht <robin@protonic.nl> |
| 3963 | M: Oleksij Rempel <o.rempel@pengutronix.de> | 3961 | M: Oleksij Rempel <o.rempel@pengutronix.de> |
| 3964 | R: Pengutronix Kernel Team <kernel@pengutronix.de> | 3962 | R: kernel@pengutronix.de |
| 3965 | L: linux-can@vger.kernel.org | 3963 | L: linux-can@vger.kernel.org |
| 3966 | S: Maintained | 3964 | S: Maintained |
| 3967 | F: Documentation/networking/j1939.rst | 3965 | F: Documentation/networking/j1939.rst |
| @@ -4588,7 +4586,7 @@ B: https://bugzilla.kernel.org · 620 unmodified lines | |||
| 4588 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git | 4586 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git |
| 4589 | F: Documentation/admin-guide/pm/cpuidle.rst | 4587 | F: Documentation/admin-guide/pm/cpuidle.rst |
| 4590 | F: Documentation/driver-api/pm/cpuidle.rst | 4588 | F: Documentation/driver-api/pm/cpuidle.rst |
| 4591 | F: drivers/cpuidle/* | 4589 | F: drivers/cpuidle/ |
| 4592 | F: include/linux/cpuidle.h | 4590 | F: include/linux/cpuidle.h |
| 4593 | 4591 | ||
| 4594 | CPU POWER MONITORING SUBSYSTEM | 4592 | CPU POWER MONITORING SUBSYSTEM |
| @@ -4922,9 +4920,8 @@ F: Documentation/scsi/dc395x.rst · 327 unmodified lines | |||
| 4922 | F: drivers/scsi/dc395x.* | 4920 | F: drivers/scsi/dc395x.* |
| 4923 | 4921 | ||
| 4924 | DCCP PROTOCOL | 4922 | DCCP PROTOCOL |
| 4925 | M: Gerrit Renker <gerrit@erg.abdn.ac.uk> | ||
| 4926 | L: dccp@vger.kernel.org | 4923 | L: dccp@vger.kernel.org |
| 4927 | S: Maintained | 4924 | S: Orphan |
| 4928 | W: http://www.linuxfoundation.org/collaborate/workgroups/networking/dccp | 4925 | W: http://www.linuxfoundation.org/collaborate/workgroups/networking/dccp |
| 4929 | F: include/linux/dccp.h | 4926 | F: include/linux/dccp.h |
| 4930 | F: include/linux/tfrc.h | 4927 | F: include/linux/tfrc.h |
| @@ -7363,7 +7360,6 @@ L: linux-hardening@vger.kernel.org · 2432 unmodified lines | |||
| 7363 | S: Maintained | 7360 | S: Maintained |
| 7364 | F: Documentation/kbuild/gcc-plugins.rst | 7361 | F: Documentation/kbuild/gcc-plugins.rst |
| 7365 | F: scripts/Makefile.gcc-plugins | 7362 | F: scripts/Makefile.gcc-plugins |
| 7366 | F: scripts/gcc-plugin.sh | ||
| 7367 | F: scripts/gcc-plugins/ | 7363 | F: scripts/gcc-plugins/ |
| 7368 | 7364 | ||
| 7369 | GCOV BASED KERNEL PROFILING | 7365 | GCOV BASED KERNEL PROFILING |
| @@ -9240,7 +9236,7 @@ F: tools/testing/selftests/sgx/* · 1870 unmodified lines | |||
| 9240 | K: \bSGX_ | 9236 | K: \bSGX_ |
| 9241 | 9237 | ||
| 9242 | INTERCONNECT API | 9238 | INTERCONNECT API |
| 9243 | M: Georgi Djakov <georgi.djakov@linaro.org> | 9239 | M: Georgi Djakov <djakov@kernel.org> |
| 9244 | L: linux-pm@vger.kernel.org | 9240 | L: linux-pm@vger.kernel.org |
| 9245 | S: Maintained | 9241 | S: Maintained |
| 9246 | F: Documentation/devicetree/bindings/interconnect/ | 9242 | F: Documentation/devicetree/bindings/interconnect/ |
| @@ -9273,7 +9269,7 @@ F: drivers/net/ethernet/sgi/ioc3-eth.c · 26 unmodified lines | |||
| 9273 | 9269 | ||
| 9274 | IOMAP FILESYSTEM LIBRARY | 9270 | IOMAP FILESYSTEM LIBRARY |
| 9275 | M: Christoph Hellwig <hch@infradead.org> | 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 | M: linux-xfs@vger.kernel.org | 9273 | M: linux-xfs@vger.kernel.org |
| 9278 | M: linux-fsdevel@vger.kernel.org | 9274 | M: linux-fsdevel@vger.kernel.org |
| 9279 | L: linux-xfs@vger.kernel.org | 9275 | L: linux-xfs@vger.kernel.org |
| @@ -9327,7 +9323,6 @@ W: http://www.adaptec.com/ · 47 unmodified lines | |||
| 9327 | F: drivers/scsi/ips* | 9323 | F: drivers/scsi/ips* |
| 9328 | 9324 | ||
| 9329 | IPVS | 9325 | IPVS |
| 9330 | M: Wensong Zhang <wensong@linux-vs.org> | ||
| 9331 | M: Simon Horman <horms@verge.net.au> | 9326 | M: Simon Horman <horms@verge.net.au> |
| 9332 | M: Julian Anastasov <ja@ssi.bg> | 9327 | M: Julian Anastasov <ja@ssi.bg> |
| 9333 | L: netdev@vger.kernel.org | 9328 | L: netdev@vger.kernel.org |
| @@ -9776,7 +9771,7 @@ F: tools/testing/selftests/kvm/s390x/ · 442 unmodified lines | |||
| 9776 | 9771 | ||
| 9777 | KERNEL VIRTUAL MACHINE FOR X86 (KVM/x86) | 9772 | KERNEL VIRTUAL MACHINE FOR X86 (KVM/x86) |
| 9778 | M: Paolo Bonzini <pbonzini@redhat.com> | 9773 | M: Paolo Bonzini <pbonzini@redhat.com> |
| 9779 | R: Sean Christopherson <sean.j.christopherson@intel.com> | 9774 | R: Sean Christopherson <seanjc@google.com> |
| 9780 | R: Vitaly Kuznetsov <vkuznets@redhat.com> | 9775 | R: Vitaly Kuznetsov <vkuznets@redhat.com> |
| 9781 | R: Wanpeng Li <wanpengli@tencent.com> | 9776 | R: Wanpeng Li <wanpengli@tencent.com> |
| 9782 | R: Jim Mattson <jmattson@google.com> | 9777 | R: Jim Mattson <jmattson@google.com> |
| @@ -10260,7 +10255,6 @@ S: Supported · 477 unmodified lines | |||
| 10260 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev | 10255 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev |
| 10261 | F: Documentation/atomic_bitops.txt | 10256 | F: Documentation/atomic_bitops.txt |
| 10262 | F: Documentation/atomic_t.txt | 10257 | F: Documentation/atomic_t.txt |
| 10263 | F: Documentation/core-api/atomic_ops.rst | ||
| 10264 | F: Documentation/core-api/refcount-vs-atomic.rst | 10258 | F: Documentation/core-api/refcount-vs-atomic.rst |
| 10265 | F: Documentation/litmus-tests/ | 10259 | F: Documentation/litmus-tests/ |
| 10266 | F: Documentation/memory-barriers.txt | 10260 | F: Documentation/memory-barriers.txt |
| @@ -10847,7 +10841,7 @@ F: drivers/media/radio/radio-maxiradio* · 580 unmodified lines | |||
| 10847 | 10841 | ||
| 10848 | MCAN MMIO DEVICE DRIVER | 10842 | MCAN MMIO DEVICE DRIVER |
| 10849 | M: Dan Murphy <dmurphy@ti.com> | 10843 | M: Dan Murphy <dmurphy@ti.com> |
| 10850 | M: Sriram Dash <sriram.dash@samsung.com> | 10844 | M: Pankaj Sharma <pankj.sharma@samsung.com> |
| 10851 | L: linux-can@vger.kernel.org | 10845 | L: linux-can@vger.kernel.org |
| 10852 | S: Maintained | 10846 | S: Maintained |
| 10853 | F: Documentation/devicetree/bindings/net/can/bosch,m_can.yaml | 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 | MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER | 11662 | MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER |
| 11669 | M: Woojung Huh <woojung.huh@microchip.com> | 11663 | M: Woojung Huh <woojung.huh@microchip.com> |
| 11670 | M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | 11664 | M: UNGLinuxDriver@microchip.com |
| 11671 | L: netdev@vger.kernel.org | 11665 | L: netdev@vger.kernel.org |
| 11672 | S: Maintained | 11666 | S: Maintained |
| 11673 | F: Documentation/devicetree/bindings/net/dsa/microchip,ksz.yaml | 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 | MICROCHIP LAN743X ETHERNET DRIVER | 11672 | MICROCHIP LAN743X ETHERNET DRIVER |
| 11679 | M: Bryan Whitehead <bryan.whitehead@microchip.com> | 11673 | M: Bryan Whitehead <bryan.whitehead@microchip.com> |
| 11680 | M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | 11674 | M: UNGLinuxDriver@microchip.com |
| 11681 | L: netdev@vger.kernel.org | 11675 | L: netdev@vger.kernel.org |
| 11682 | S: Maintained | 11676 | S: Maintained |
| 11683 | F: drivers/net/ethernet/microchip/lan743x_* | 11677 | F: drivers/net/ethernet/microchip/lan743x_* |
| @@ -11771,7 +11765,7 @@ F: drivers/net/wireless/microchip/wilc1000/ · 87 unmodified lines | |||
| 11771 | 11765 | ||
| 11772 | MICROSEMI MIPS SOCS | 11766 | MICROSEMI MIPS SOCS |
| 11773 | M: Alexandre Belloni <alexandre.belloni@bootlin.com> | 11767 | M: Alexandre Belloni <alexandre.belloni@bootlin.com> |
| 11774 | M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | 11768 | M: UNGLinuxDriver@microchip.com |
| 11775 | L: linux-mips@vger.kernel.org | 11769 | L: linux-mips@vger.kernel.org |
| 11776 | S: Supported | 11770 | S: Supported |
| 11777 | F: Documentation/devicetree/bindings/mips/mscc.txt | 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 | NETWORKING [IPv4/IPv6] | 12413 | NETWORKING [IPv4/IPv6] |
| 12420 | M: "David S. Miller" <davem@davemloft.net> | 12414 | M: "David S. Miller" <davem@davemloft.net> |
| 12421 | M: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> | ||
| 12422 | M: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> | 12415 | M: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> |
| 12423 | L: netdev@vger.kernel.org | 12416 | L: netdev@vger.kernel.org |
| 12424 | S: Maintained | 12417 | S: Maintained |
| @@ -12475,7 +12468,6 @@ F: net/ipv6/tcp*.c · 50 unmodified lines | |||
| 12475 | 12468 | ||
| 12476 | NETWORKING [TLS] | 12469 | NETWORKING [TLS] |
| 12477 | M: Boris Pismenny <borisp@nvidia.com> | 12470 | M: Boris Pismenny <borisp@nvidia.com> |
| 12478 | M: Aviad Yehezkel <aviadye@nvidia.com> | ||
| 12479 | M: John Fastabend <john.fastabend@gmail.com> | 12471 | M: John Fastabend <john.fastabend@gmail.com> |
| 12480 | M: Daniel Borkmann <daniel@iogearbox.net> | 12472 | M: Daniel Borkmann <daniel@iogearbox.net> |
| 12481 | M: Jakub Kicinski <kuba@kernel.org> | 12473 | M: Jakub Kicinski <kuba@kernel.org> |
| @@ -12825,10 +12817,10 @@ F: tools/objtool/ · 343 unmodified lines | |||
| 12825 | F: include/linux/objtool.h | 12817 | F: include/linux/objtool.h |
| 12826 | 12818 | ||
| 12827 | OCELOT ETHERNET SWITCH DRIVER | 12819 | OCELOT ETHERNET SWITCH DRIVER |
| 12828 | M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | ||
| 12829 | M: Vladimir Oltean <vladimir.oltean@nxp.com> | 12820 | M: Vladimir Oltean <vladimir.oltean@nxp.com> |
| 12830 | M: Claudiu Manoil <claudiu.manoil@nxp.com> | 12821 | M: Claudiu Manoil <claudiu.manoil@nxp.com> |
| 12831 | M: Alexandre Belloni <alexandre.belloni@bootlin.com> | 12822 | M: Alexandre Belloni <alexandre.belloni@bootlin.com> |
| 12823 | M: UNGLinuxDriver@microchip.com | ||
| 12832 | L: netdev@vger.kernel.org | 12824 | L: netdev@vger.kernel.org |
| 12833 | S: Supported | 12825 | S: Supported |
| 12834 | F: drivers/net/dsa/ocelot/* | 12826 | F: drivers/net/dsa/ocelot/* |
| @@ -12850,7 +12842,7 @@ F: include/misc/ocxl* · 15 unmodified lines | |||
| 12850 | F: include/uapi/misc/ocxl.h | 12842 | F: include/uapi/misc/ocxl.h |
| 12851 | 12843 | ||
| 12852 | OMAP AUDIO SUPPORT | 12844 | OMAP AUDIO SUPPORT |
| 12853 | M: Peter Ujfalusi <peter.ujfalusi@ti.com> | 12845 | M: Peter Ujfalusi <peter.ujfalusi@gmail.com> |
| 12854 | M: Jarkko Nikula <jarkko.nikula@bitmer.com> | 12846 | M: Jarkko Nikula <jarkko.nikula@bitmer.com> |
| 12855 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 12847 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 12856 | L: linux-omap@vger.kernel.org | 12848 | L: linux-omap@vger.kernel.org |
| @@ -13890,7 +13882,7 @@ F: drivers/platform/x86/peaq-wmi.c · 1033 unmodified lines | |||
| 13890 | 13882 | ||
| 13891 | PENSANDO ETHERNET DRIVERS | 13883 | PENSANDO ETHERNET DRIVERS |
| 13892 | M: Shannon Nelson <snelson@pensando.io> | 13884 | M: Shannon Nelson <snelson@pensando.io> |
| 13893 | M: Pensando Drivers <drivers@pensando.io> | 13885 | M: drivers@pensando.io |
| 13894 | L: netdev@vger.kernel.org | 13886 | L: netdev@vger.kernel.org |
| 13895 | S: Supported | 13887 | S: Supported |
| 13896 | F: Documentation/networking/device_drivers/ethernet/pensando/ionic.rst | 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 | F: drivers/net/wireless/ath/ath11k/ | 14661 | F: drivers/net/wireless/ath/ath11k/ |
| 14670 | 14662 | ||
| 14671 | QUALCOMM ATHEROS ATH9K WIRELESS DRIVER | 14663 | QUALCOMM ATHEROS ATH9K WIRELESS DRIVER |
| 14672 | M: QCA ath9k Development <ath9k-devel@qca.qualcomm.com> | 14664 | M: ath9k-devel@qca.qualcomm.com |
| 14673 | L: linux-wireless@vger.kernel.org | 14665 | L: linux-wireless@vger.kernel.org |
| 14674 | S: Supported | 14666 | S: Supported |
| 14675 | W: https://wireless.wiki.kernel.org/en/users/Drivers/ath9k | 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 | M: Christian König <christian.koenig@amd.com> | 14812 | M: Christian König <christian.koenig@amd.com> |
| 14821 | L: amd-gfx@lists.freedesktop.org | 14813 | L: amd-gfx@lists.freedesktop.org |
| 14822 | S: Supported | 14814 | S: Supported |
| 14823 | T: git git://people.freedesktop.org/~agd5f/linux | 14815 | T: git https://gitlab.freedesktop.org/agd5f/linux.git |
| 14824 | F: drivers/gpu/drm/amd/ | 14816 | F: drivers/gpu/drm/amd/ |
| 14825 | F: drivers/gpu/drm/radeon/ | 14817 | F: drivers/gpu/drm/radeon/ |
| 14826 | F: include/uapi/drm/amdgpu_drm.h | 14818 | F: include/uapi/drm/amdgpu_drm.h |
| @@ -16321,6 +16313,7 @@ M: Pekka Enberg <penberg@kernel.org> · 1494 unmodified lines | |||
| 16321 | M: David Rientjes <rientjes@google.com> | 16313 | M: David Rientjes <rientjes@google.com> |
| 16322 | M: Joonsoo Kim <iamjoonsoo.kim@lge.com> | 16314 | M: Joonsoo Kim <iamjoonsoo.kim@lge.com> |
| 16323 | M: Andrew Morton <akpm@linux-foundation.org> | 16315 | M: Andrew Morton <akpm@linux-foundation.org> |
| 16316 | M: Vlastimil Babka <vbabka@suse.cz> | ||
| 16324 | L: linux-mm@kvack.org | 16317 | L: linux-mm@kvack.org |
| 16325 | S: Maintained | 16318 | S: Maintained |
| 16326 | F: include/linux/sl?b*.h | 16319 | F: include/linux/sl?b*.h |
| @@ -16710,6 +16703,8 @@ M: Samuel Thibault <samuel.thibault@ens-lyon.org> · 383 unmodified lines | |||
| 16710 | L: speakup@linux-speakup.org | 16703 | L: speakup@linux-speakup.org |
| 16711 | S: Odd Fixes | 16704 | S: Odd Fixes |
| 16712 | W: http://www.linux-speakup.org/ | 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 | F: drivers/accessibility/speakup/ | 16708 | F: drivers/accessibility/speakup/ |
| 16714 | 16709 | ||
| 16715 | SPEAR CLOCK FRAMEWORK SUPPORT | 16710 | SPEAR CLOCK FRAMEWORK SUPPORT |
| @@ -17541,7 +17536,7 @@ F: arch/xtensa/ · 825 unmodified lines | |||
| 17541 | F: drivers/irqchip/irq-xtensa-* | 17536 | F: drivers/irqchip/irq-xtensa-* |
| 17542 | 17537 | ||
| 17543 | TEXAS INSTRUMENTS ASoC DRIVERS | 17538 | TEXAS INSTRUMENTS ASoC DRIVERS |
| 17544 | M: Peter Ujfalusi <peter.ujfalusi@ti.com> | 17539 | M: Peter Ujfalusi <peter.ujfalusi@gmail.com> |
| 17545 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 17540 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 17546 | S: Maintained | 17541 | S: Maintained |
| 17547 | F: sound/soc/ti/ | 17542 | F: sound/soc/ti/ |
| @@ -17553,6 +17548,19 @@ S: Supported · 5 unmodified lines | |||
| 17553 | F: Documentation/devicetree/bindings/iio/dac/ti,dac7612.txt | 17548 | F: Documentation/devicetree/bindings/iio/dac/ti,dac7612.txt |
| 17554 | F: drivers/iio/dac/ti-dac7612.c | 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 | TEXAS INSTRUMENTS' SYSTEM CONTROL INTERFACE (TISCI) PROTOCOL DRIVER | 17564 | TEXAS INSTRUMENTS' SYSTEM CONTROL INTERFACE (TISCI) PROTOCOL DRIVER |
| 17557 | M: Nishanth Menon <nm@ti.com> | 17565 | M: Nishanth Menon <nm@ti.com> |
| 17558 | M: Tero Kristo <t-kristo@ti.com> | 17566 | M: Tero Kristo <t-kristo@ti.com> |
| @@ -17838,7 +17846,7 @@ F: Documentation/devicetree/bindings/net/nfc/trf7970a.txt · 279 unmodified lines | |||
| 17838 | F: drivers/nfc/trf7970a.c | 17846 | F: drivers/nfc/trf7970a.c |
| 17839 | 17847 | ||
| 17840 | TI TWL4030 SERIES SOC CODEC DRIVER | 17848 | TI TWL4030 SERIES SOC CODEC DRIVER |
| 17841 | M: Peter Ujfalusi <peter.ujfalusi@ti.com> | 17849 | M: Peter Ujfalusi <peter.ujfalusi@gmail.com> |
| 17842 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 17850 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 17843 | S: Maintained | 17851 | S: Maintained |
| 17844 | F: sound/soc/codecs/twl4030* | 17852 | F: sound/soc/codecs/twl4030* |
| @@ -18370,7 +18378,7 @@ F: include/linux/usb/isp116x.h · 525 unmodified lines | |||
| 18370 | 18378 | ||
| 18371 | USB LAN78XX ETHERNET DRIVER | 18379 | USB LAN78XX ETHERNET DRIVER |
| 18372 | M: Woojung Huh <woojung.huh@microchip.com> | 18380 | M: Woojung Huh <woojung.huh@microchip.com> |
| 18373 | M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | 18381 | M: UNGLinuxDriver@microchip.com |
| 18374 | L: netdev@vger.kernel.org | 18382 | L: netdev@vger.kernel.org |
| 18375 | S: Maintained | 18383 | S: Maintained |
| 18376 | F: Documentation/devicetree/bindings/net/microchip,lan78xx.txt | 18384 | F: Documentation/devicetree/bindings/net/microchip,lan78xx.txt |
| @@ -18484,7 +18492,7 @@ F: drivers/net/usb/smsc75xx.* · 107 unmodified lines | |||
| 18484 | 18492 | ||
| 18485 | USB SMSC95XX ETHERNET DRIVER | 18493 | USB SMSC95XX ETHERNET DRIVER |
| 18486 | M: Steve Glendinning <steve.glendinning@shawell.net> | 18494 | M: Steve Glendinning <steve.glendinning@shawell.net> |
| 18487 | M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> | 18495 | M: UNGLinuxDriver@microchip.com |
| 18488 | L: netdev@vger.kernel.org | 18496 | L: netdev@vger.kernel.org |
| 18489 | S: Maintained | 18497 | S: Maintained |
| 18490 | F: drivers/net/usb/smsc95xx.* | 18498 | F: drivers/net/usb/smsc95xx.* |
| @@ -19031,7 +19039,7 @@ F: drivers/input/mouse/vmmouse.h · 540 unmodified lines | |||
| 19031 | 19039 | ||
| 19032 | VMWARE VMXNET3 ETHERNET DRIVER | 19040 | VMWARE VMXNET3 ETHERNET DRIVER |
| 19033 | M: Ronak Doshi <doshir@vmware.com> | 19041 | M: Ronak Doshi <doshir@vmware.com> |
| 19034 | M: "VMware, Inc." <pv-drivers@vmware.com> | 19042 | M: pv-drivers@vmware.com |
| 19035 | L: netdev@vger.kernel.org | 19043 | L: netdev@vger.kernel.org |
| 19036 | S: Maintained | 19044 | S: Maintained |
| 19037 | F: drivers/net/vmxnet3/ | 19045 | F: drivers/net/vmxnet3/ |
| @@ -19058,7 +19066,6 @@ K: regulator_get_optional · 20 unmodified lines | |||
| 19058 | 19066 | ||
| 19059 | VRF | 19067 | VRF |
| 19060 | M: David Ahern <dsahern@kernel.org> | 19068 | M: David Ahern <dsahern@kernel.org> |
| 19061 | M: Shrijeet Mukherjee <shrijeet@gmail.com> | ||
| 19062 | L: netdev@vger.kernel.org | 19069 | L: netdev@vger.kernel.org |
| 19063 | S: Maintained | 19070 | S: Maintained |
| 19064 | F: Documentation/networking/vrf.rst | 19071 | F: Documentation/networking/vrf.rst |
| @@ -19505,7 +19512,7 @@ F: arch/x86/xen/*swiotlb* · 440 unmodified lines | |||
| 19505 | F: drivers/xen/*swiotlb* | 19512 | F: drivers/xen/*swiotlb* |
| 19506 | 19513 | ||
| 19507 | XFS FILESYSTEM | 19514 | XFS FILESYSTEM |
| 19508 | M: Darrick J. Wong <darrick.wong@oracle.com> | 19515 | M: Darrick J. Wong <djwong@kernel.org> |
| 19509 | M: linux-xfs@vger.kernel.org | 19516 | M: linux-xfs@vger.kernel.org |
| 19510 | L: linux-xfs@vger.kernel.org | 19517 | L: linux-xfs@vger.kernel.org |
| 19511 | S: Supported | 19518 | S: Supported |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 5 | 2 | VERSION = 5 |
| 3 | PATCHLEVEL = 11 | 3 | PATCHLEVEL = 11 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc1 | 5 | EXTRAVERSION = -rc4 |
| 6 | NAME = Kleptomaniac Octopus | 6 | NAME = Kleptomaniac Octopus |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -1105,6 +1105,12 @@ config HAVE_ARCH_PFN_VALID · 1104 unmodified lines | |||
| 1105 | config ARCH_SUPPORTS_DEBUG_PAGEALLOC | 1105 | config ARCH_SUPPORTS_DEBUG_PAGEALLOC |
| 1106 | bool | 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 | source "kernel/gcov/Kconfig" | 1114 | source "kernel/gcov/Kconfig" |
| 1109 | 1115 | ||
| 1110 | source "scripts/gcc-plugins/Kconfig" | 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 | boot := arch/arc/boot | 103 | boot := arch/arc/boot |
| 104 | 104 | ||
| 105 | #default target for make without any arguments. | 105 | boot_targets := uImage.bin uImage.gz uImage.lzma |
| 106 | KBUILD_IMAGE := $(boot)/bootpImage | ||
| 107 | |||
| 108 | all: bootpImage | ||
| 109 | bootpImage: vmlinux | ||
| 110 | |||
| 111 | boot_targets += uImage uImage.bin uImage.gz | ||
| 112 | 106 | ||
| 107 | PHONY += $(boot_targets) | ||
| 113 | $(boot_targets): vmlinux | 108 | $(boot_targets): vmlinux |
| 114 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ | 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 | archclean: | 122 | archclean: |
| 117 | $(Q)$(MAKE) $(clean)=$(boot) | 123 | $(Q)$(MAKE) $(clean)=$(boot) |
| @@ -1,5 +1,4 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | targets := vmlinux.bin vmlinux.bin.gz uImage | ||
| 3 | 2 | ||
| 4 | # uImage build relies on mkimage being availble on your host for ARC target | 3 | # uImage build relies on mkimage being availble on your host for ARC target |
| 5 | # You will need to build u-boot for ARC, rename mkimage to arc-elf32-mkimage | 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 | OBJCOPYFLAGS= -O binary -R .note -R .note.gnu.build-id -R .comment -S | 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 | grep "Entry point address" | grep -o 0x.*) | 10 | grep "Entry point address" | grep -o 0x.*) |
| 12 | 11 | ||
| 13 | UIMAGE_LOADADDR = $(CONFIG_LINUX_LINK_BASE) | 12 | UIMAGE_LOADADDR = $(CONFIG_LINUX_LINK_BASE) |
| 14 | UIMAGE_ENTRYADDR = $(LINUX_START_TEXT) | 13 | UIMAGE_ENTRYADDR = $(LINUX_START_TEXT) |
| 15 | 14 | ||
| 16 | suffix-y := bin | 15 | targets += vmlinux.bin |
| 17 | suffix-$(CONFIG_KERNEL_GZIP) := gz | 16 | targets += vmlinux.bin.gz |
| 18 | suffix-$(CONFIG_KERNEL_LZMA) := lzma | 17 | targets += vmlinux.bin.lzma |
| 19 | |||
| 20 | targets += uImage | ||
| 21 | targets += uImage.bin | 18 | targets += uImage.bin |
| 22 | targets += uImage.gz | 19 | targets += uImage.gz |
| 23 | targets += uImage.lzma | 20 | targets += uImage.lzma |
| 24 | extra-y += vmlinux.bin | ||
| 25 | extra-y += vmlinux.bin.gz | ||
| 26 | extra-y += vmlinux.bin.lzma | ||
| 27 | 21 | ||
| 28 | $(obj)/vmlinux.bin: vmlinux FORCE | 22 | $(obj)/vmlinux.bin: vmlinux FORCE |
| 29 | $(call if_changed,objcopy) | 23 | $(call if_changed,objcopy) |
| @@ -42,7 +36,3 @@ $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz FORCE · 12 unmodified lines | |||
| 42 | 36 | ||
| 43 | $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma FORCE | 37 | $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma FORCE |
| 44 | $(call if_changed,uimage,lzma) | 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 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | generic-y += extable.h | 2 | generic-y += extable.h |
| 3 | generic-y += kvm_para.h | 3 | generic-y += kvm_para.h |
| 4 | generic-y += local64.h | ||
| 5 | generic-y += mcs_spinlock.h | 4 | generic-y += mcs_spinlock.h |
| 6 | generic-y += parport.h | 5 | generic-y += parport.h |
| 7 | generic-y += user.h | 6 | generic-y += user.h |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | |||
| 10 | #ifndef __ASSEMBLY__ | 10 | #ifndef __ASSEMBLY__ |
| 11 | 11 | ||
| 12 | #define clear_page(paddr) memset((paddr), 0, PAGE_SIZE) | 12 | #define clear_page(paddr) memset((paddr), 0, PAGE_SIZE) |
| 13 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) | ||
| 13 | #define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) | 14 | #define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) |
| 14 | 15 | ||
| 15 | struct vm_area_struct; | 16 | struct vm_area_struct; |
| @@ -307,7 +307,7 @@ resume_user_mode_begin: · 306 unmodified lines | |||
| 307 | mov r0, sp ; pt_regs for arg to do_signal()/do_notify_resume() | 307 | mov r0, sp ; pt_regs for arg to do_signal()/do_notify_resume() |
| 308 | 308 | ||
| 309 | GET_CURR_THR_INFO_FLAGS r9 | 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 | bz .Lchk_notify_resume | 311 | bz .Lchk_notify_resume |
| 312 | 312 | ||
| 313 | ; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs | 313 | ; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs |
| @@ -7,6 +7,7 @@ menuconfig ARC_SOC_HSDK · 6 unmodified lines | |||
| 7 | depends on ISA_ARCV2 | 7 | depends on ISA_ARCV2 |
| 8 | select ARC_HAS_ACCL_REGS | 8 | select ARC_HAS_ACCL_REGS |
| 9 | select ARC_IRQ_NO_AUTOSAVE | 9 | select ARC_IRQ_NO_AUTOSAVE |
| 10 | select ARC_FPU_SAVE_RESTORE | ||
| 10 | select CLK_HSDK | 11 | select CLK_HSDK |
| 11 | select RESET_CONTROLLER | 12 | select RESET_CONTROLLER |
| 12 | select RESET_HSDK | 13 | select RESET_HSDK |
| @@ -494,3 +494,11 @@ · 493 unmodified lines | |||
| 494 | clock-names = "sysclk"; | 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 | emac: gem@30000 { | 45 | emac: gem@30000 { |
| 46 | compatible = "cadence,gem"; | 46 | compatible = "cadence,gem"; |
| 47 | reg = <0x30000 0x10000>; | 47 | reg = <0x30000 0x10000>; |
| 48 | interrupt-parent = <&vic0>; | ||
| 48 | interrupts = <31>; | 49 | interrupts = <31>; |
| 49 | }; | 50 | }; |
| 50 | 51 | ||
| 51 | dmac1: dmac@40000 { | 52 | dmac1: dmac@40000 { |
| 52 | compatible = "snps,dw-dmac"; | 53 | compatible = "snps,dw-dmac"; |
| 53 | reg = <0x40000 0x10000>; | 54 | reg = <0x40000 0x10000>; |
| 55 | interrupt-parent = <&vic0>; | ||
| 54 | interrupts = <25>; | 56 | interrupts = <25>; |
| 55 | }; | 57 | }; |
| 56 | 58 | ||
| 57 | dmac2: dmac@50000 { | 59 | dmac2: dmac@50000 { |
| 58 | compatible = "snps,dw-dmac"; | 60 | compatible = "snps,dw-dmac"; |
| 59 | reg = <0x50000 0x10000>; | 61 | reg = <0x50000 0x10000>; |
| 62 | interrupt-parent = <&vic0>; | ||
| 60 | interrupts = <26>; | 63 | interrupts = <26>; |
| 61 | }; | 64 | }; |
| 62 | 65 | ||
| @@ -233,6 +236,7 @@ · 170 unmodified lines | |||
| 233 | axi2pico@c0000000 { | 236 | axi2pico@c0000000 { |
| 234 | compatible = "picochip,axi2pico-pc3x2"; | 237 | compatible = "picochip,axi2pico-pc3x2"; |
| 235 | reg = <0xc0000000 0x10000>; | 238 | reg = <0xc0000000 0x10000>; |
| 239 | interrupt-parent = <&vic0>; | ||
| 236 | interrupts = <13 14 15 16 17 18 19 20 21>; | 240 | interrupts = <13 14 15 16 17 18 19 20 21>; |
| 237 | }; | 241 | }; |
| 238 | }; | 242 | }; |
| @@ -329,6 +329,7 @@ · 328 unmodified lines | |||
| 329 | panel@0 { | 329 | panel@0 { |
| 330 | compatible = "samsung,s6e63m0"; | 330 | compatible = "samsung,s6e63m0"; |
| 331 | reg = <0>; | 331 | reg = <0>; |
| 332 | max-brightness = <15>; | ||
| 332 | vdd3-supply = <&panel_reg_3v0>; | 333 | vdd3-supply = <&panel_reg_3v0>; |
| 333 | vci-supply = <&panel_reg_1v8>; | 334 | vci-supply = <&panel_reg_1v8>; |
| 334 | reset-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; | 335 | reset-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; |
| @@ -279,6 +279,7 @@ CONFIG_SERIAL_OMAP_CONSOLE=y · 278 unmodified lines | |||
| 279 | CONFIG_SERIAL_DEV_BUS=y | 279 | CONFIG_SERIAL_DEV_BUS=y |
| 280 | CONFIG_I2C_CHARDEV=y | 280 | CONFIG_I2C_CHARDEV=y |
| 281 | CONFIG_SPI=y | 281 | CONFIG_SPI=y |
| 282 | CONFIG_SPI_GPIO=m | ||
| 282 | CONFIG_SPI_OMAP24XX=y | 283 | CONFIG_SPI_OMAP24XX=y |
| 283 | CONFIG_SPI_TI_QSPI=m | 284 | CONFIG_SPI_TI_QSPI=m |
| 284 | CONFIG_HSI=m | 285 | CONFIG_HSI=m |
| @@ -296,7 +297,6 @@ CONFIG_GPIO_TWL4030=y · 11 unmodified lines | |||
| 296 | CONFIG_W1=m | 297 | CONFIG_W1=m |
| 297 | CONFIG_HDQ_MASTER_OMAP=m | 298 | CONFIG_HDQ_MASTER_OMAP=m |
| 298 | CONFIG_W1_SLAVE_DS250X=m | 299 | CONFIG_W1_SLAVE_DS250X=m |
| 299 | CONFIG_POWER_AVS=y | ||
| 300 | CONFIG_POWER_RESET=y | 300 | CONFIG_POWER_RESET=y |
| 301 | CONFIG_POWER_RESET_GPIO=y | 301 | CONFIG_POWER_RESET_GPIO=y |
| 302 | CONFIG_BATTERY_BQ27XXX=m | 302 | CONFIG_BATTERY_BQ27XXX=m |
| @@ -60,6 +60,7 @@ static void chacha_doneon(u32 *state, u8 *dst, const u8 *src, · 59 unmodified lines | |||
| 60 | chacha_block_xor_neon(state, d, s, nrounds); | 60 | chacha_block_xor_neon(state, d, s, nrounds); |
| 61 | if (d != dst) | 61 | if (d != dst) |
| 62 | memcpy(dst, buf, bytes); | 62 | memcpy(dst, buf, bytes); |
| 63 | state[12]++; | ||
| 63 | } | 64 | } |
| 64 | } | 65 | } |
| 65 | 66 | ||
| @@ -2,7 +2,6 @@ · 1 unmodified line | |||
| 2 | generic-y += early_ioremap.h | 2 | generic-y += early_ioremap.h |
| 3 | generic-y += extable.h | 3 | generic-y += extable.h |
| 4 | generic-y += flat.h | 4 | generic-y += flat.h |
| 5 | generic-y += local64.h | ||
| 6 | generic-y += parport.h | 5 | generic-y += parport.h |
| 7 | 6 | ||
| 8 | generated-y += mach-types.h | 7 | generated-y += mach-types.h |
| @@ -230,10 +230,12 @@ static int _omap_device_notifier_call(struct notifier_block *nb, · 229 unmodified lines | |||
| 230 | break; | 230 | break; |
| 231 | case BUS_NOTIFY_BIND_DRIVER: | 231 | case BUS_NOTIFY_BIND_DRIVER: |
| 232 | od = to_omap_device(pdev); | 232 | od = to_omap_device(pdev); |
| 233 | if (od && (od->_state == OMAP_DEVICE_STATE_ENABLED) && | 233 | if (od) { |
| 234 | pm_runtime_status_suspended(dev)) { | ||
| 235 | od->_driver_status = BUS_NOTIFY_BIND_DRIVER; | 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 | break; | 240 | break; |
| 239 | case BUS_NOTIFY_ADD_DEVICE: | 241 | case BUS_NOTIFY_ADD_DEVICE: |
| @@ -71,7 +71,7 @@ static struct omap_voltdm_pmic omap_cpcap_iva = { · 70 unmodified lines | |||
| 71 | .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN, | 71 | .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN, |
| 72 | .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX, | 72 | .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX, |
| 73 | .vddmin = 900000, | 73 | .vddmin = 900000, |
| 74 | .vddmax = 1350000, | 74 | .vddmax = 1375000, |
| 75 | .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US, | 75 | .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US, |
| 76 | .i2c_slave_addr = 0x44, | 76 | .i2c_slave_addr = 0x44, |
| 77 | .volt_reg_addr = 0x0, | 77 | .volt_reg_addr = 0x0, |
| @@ -371,7 +371,7 @@ static int __init xen_guest_init(void) · 370 unmodified lines | |||
| 371 | } | 371 | } |
| 372 | gnttab_init(); | 372 | gnttab_init(); |
| 373 | if (!xen_initial_domain()) | 373 | if (!xen_initial_domain()) |
| 374 | xenbus_probe(NULL); | 374 | xenbus_probe(); |
| 375 | 375 | ||
| 376 | /* | 376 | /* |
| 377 | * Making sure board specific code will not set up ops for | 377 | * Making sure board specific code will not set up ops for |
| @@ -174,8 +174,6 @@ config ARM64 · 173 unmodified lines | |||
| 174 | select HAVE_NMI | 174 | select HAVE_NMI |
| 175 | select HAVE_PATA_PLATFORM | 175 | select HAVE_PATA_PLATFORM |
| 176 | select HAVE_PERF_EVENTS | 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 | select HAVE_PERF_REGS | 177 | select HAVE_PERF_REGS |
| 180 | select HAVE_PERF_USER_STACK_DUMP | 178 | select HAVE_PERF_USER_STACK_DUMP |
| 181 | select HAVE_REGS_AND_STACK_ACCESS_API | 179 | select HAVE_REGS_AND_STACK_ACCESS_API |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | |||
| 10 | # | 10 | # |
| 11 | # Copyright (C) 1995-2001 by Russell King | 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 | ifeq ($(CONFIG_RELOCATABLE), y) | 15 | ifeq ($(CONFIG_RELOCATABLE), y) |
| 16 | # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour | 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 | CHECKFLAGS += -D__AARCH64EB__ | 115 | CHECKFLAGS += -D__AARCH64EB__ |
| 116 | # Prefer the baremetal ELF build target, but not all toolchains include | 116 | # Prefer the baremetal ELF build target, but not all toolchains include |
| 117 | # it so fall back to the standard linux version if needed. | 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 | UTS_MACHINE := aarch64_be | 119 | UTS_MACHINE := aarch64_be |
| 120 | else | 120 | else |
| 121 | KBUILD_CPPFLAGS += -mlittle-endian | 121 | KBUILD_CPPFLAGS += -mlittle-endian |
| 122 | CHECKFLAGS += -D__AARCH64EL__ | 122 | CHECKFLAGS += -D__AARCH64EL__ |
| 123 | # Same as above, prefer ELF but fall back to linux target if needed. | 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 | UTS_MACHINE := aarch64 | 125 | UTS_MACHINE := aarch64 |
| 126 | endif | 126 | endif |
| 127 | 127 | ||
| 128 | ifeq ($(CONFIG_LD_IS_LLD), y) | ||
| 129 | KBUILD_LDFLAGS += -z norelro | ||
| 130 | endif | ||
| 131 | |||
| 128 | CHECKFLAGS += -D__aarch64__ | 132 | CHECKFLAGS += -D__aarch64__ |
| 129 | 133 | ||
| 130 | ifeq ($(CONFIG_DYNAMIC_FTRACE_WITH_REGS),y) | 134 | ifeq ($(CONFIG_DYNAMIC_FTRACE_WITH_REGS),y) |
| @@ -127,7 +127,7 @@ · 126 unmodified lines | |||
| 127 | compatible = "snps,dw-apb-gpio-port"; | 127 | compatible = "snps,dw-apb-gpio-port"; |
| 128 | gpio-controller; | 128 | gpio-controller; |
| 129 | #gpio-cells = <2>; | 129 | #gpio-cells = <2>; |
| 130 | snps,nr-gpios = <32>; | 130 | ngpios = <32>; |
| 131 | reg = <0>; | 131 | reg = <0>; |
| 132 | interrupt-controller; | 132 | interrupt-controller; |
| 133 | #interrupt-cells = <2>; | 133 | #interrupt-cells = <2>; |
| @@ -145,7 +145,7 @@ · 11 unmodified lines | |||
| 145 | compatible = "snps,dw-apb-gpio-port"; | 145 | compatible = "snps,dw-apb-gpio-port"; |
| 146 | gpio-controller; | 146 | gpio-controller; |
| 147 | #gpio-cells = <2>; | 147 | #gpio-cells = <2>; |
| 148 | snps,nr-gpios = <32>; | 148 | ngpios = <32>; |
| 149 | reg = <0>; | 149 | reg = <0>; |
| 150 | interrupt-controller; | 150 | interrupt-controller; |
| 151 | #interrupt-cells = <2>; | 151 | #interrupt-cells = <2>; |
| @@ -163,7 +163,7 @@ · 11 unmodified lines | |||
| 163 | compatible = "snps,dw-apb-gpio-port"; | 163 | compatible = "snps,dw-apb-gpio-port"; |
| 164 | gpio-controller; | 164 | gpio-controller; |
| 165 | #gpio-cells = <2>; | 165 | #gpio-cells = <2>; |
| 166 | snps,nr-gpios = <8>; | 166 | ngpios = <8>; |
| 167 | reg = <0>; | 167 | reg = <0>; |
| 168 | interrupt-controller; | 168 | interrupt-controller; |
| 169 | #interrupt-cells = <2>; | 169 | #interrupt-cells = <2>; |
| @@ -1,6 +1,5 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | generic-y += early_ioremap.h | 2 | generic-y += early_ioremap.h |
| 3 | generic-y += local64.h | ||
| 4 | generic-y += mcs_spinlock.h | 3 | generic-y += mcs_spinlock.h |
| 5 | generic-y += qrwlock.h | 4 | generic-y += qrwlock.h |
| 6 | generic-y += qspinlock.h | 5 | generic-y += qspinlock.h |
| @@ -17,7 +17,7 @@ · 16 unmodified lines | |||
| 17 | #include <asm/lse.h> | 17 | #include <asm/lse.h> |
| 18 | 18 | ||
| 19 | #define ATOMIC_OP(op) \ | 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 | __lse_ll_sc_body(op, i, v); \ | 22 | __lse_ll_sc_body(op, i, v); \ |
| 23 | } | 23 | } |
| @@ -32,7 +32,7 @@ ATOMIC_OP(atomic_sub) · 8 unmodified lines | |||
| 32 | #undef ATOMIC_OP | 32 | #undef ATOMIC_OP |
| 33 | 33 | ||
| 34 | #define ATOMIC_FETCH_OP(name, op) \ | 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 | return __lse_ll_sc_body(op##name, i, v); \ | 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 | #undef ATOMIC_FETCH_OPS | 56 | #undef ATOMIC_FETCH_OPS |
| 57 | 57 | ||
| 58 | #define ATOMIC64_OP(op) \ | 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 | __lse_ll_sc_body(op, i, v); \ | 61 | __lse_ll_sc_body(op, i, v); \ |
| 62 | } | 62 | } |
| @@ -71,7 +71,7 @@ ATOMIC64_OP(atomic64_sub) · 8 unmodified lines | |||
| 71 | #undef ATOMIC64_OP | 71 | #undef ATOMIC64_OP |
| 72 | 72 | ||
| 73 | #define ATOMIC64_FETCH_OP(name, op) \ | 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 | return __lse_ll_sc_body(op##name, i, v); \ | 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 | #undef ATOMIC64_FETCH_OP | 94 | #undef ATOMIC64_FETCH_OP |
| 95 | #undef ATOMIC64_FETCH_OPS | 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 | return __lse_ll_sc_body(atomic64_dec_if_positive, v); | 99 | return __lse_ll_sc_body(atomic64_dec_if_positive, v); |
| 100 | } | 100 | } |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | |||
| 17 | #include <linux/jump_label.h> | 17 | #include <linux/jump_label.h> |
| 18 | #include <linux/kvm_types.h> | 18 | #include <linux/kvm_types.h> |
| 19 | #include <linux/percpu.h> | 19 | #include <linux/percpu.h> |
| 20 | #include <linux/psci.h> | ||
| 20 | #include <asm/arch_gicv3.h> | 21 | #include <asm/arch_gicv3.h> |
| 21 | #include <asm/barrier.h> | 22 | #include <asm/barrier.h> |
| 22 | #include <asm/cpufeature.h> | 23 | #include <asm/cpufeature.h> |
| @@ -240,6 +241,28 @@ struct kvm_host_data { · 217 unmodified lines | |||
| 240 | struct kvm_pmu_events pmu_events; | 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 | struct vcpu_reset_state { | 266 | struct vcpu_reset_state { |
| 244 | unsigned long pc; | 267 | unsigned long pc; |
| 245 | unsigned long r0; | 268 | unsigned long r0; |
| @@ -176,10 +176,21 @@ static inline void __uaccess_enable_hw_pan(void) · 175 unmodified lines | |||
| 176 | * The Tag check override (TCO) bit disables temporarily the tag checking | 176 | * The Tag check override (TCO) bit disables temporarily the tag checking |
| 177 | * preventing the issue. | 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 | asm volatile(ALTERNATIVE("nop", SET_PSTATE_TCO(0), | 181 | asm volatile(ALTERNATIVE("nop", SET_PSTATE_TCO(0), |
| 182 | ARM64_MTE, CONFIG_KASAN_HW_TAGS)); | 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 | if (uaccess_ttbr0_disable()) | 195 | if (uaccess_ttbr0_disable()) |
| 185 | return; | 196 | return; |
| @@ -189,8 +200,7 @@ static inline void uaccess_disable_privileged(void) · 3 unmodified lines | |||
| 189 | 200 | ||
| 190 | static inline void uaccess_enable_privileged(void) | 201 | static inline void uaccess_enable_privileged(void) |
| 191 | { | 202 | { |
| 192 | asm volatile(ALTERNATIVE("nop", SET_PSTATE_TCO(1), | 203 | __uaccess_enable_tco(); |
| 193 | ARM64_MTE, CONFIG_KASAN_HW_TAGS)); | ||
| 194 | 204 | ||
| 195 | if (uaccess_ttbr0_enable()) | 205 | if (uaccess_ttbr0_enable()) |
| 196 | return; | 206 | return; |
| @@ -75,7 +75,7 @@ int main(void) · 74 unmodified lines | |||
| 75 | DEFINE(S_SDEI_TTBR1, offsetof(struct pt_regs, sdei_ttbr1)); | 75 | DEFINE(S_SDEI_TTBR1, offsetof(struct pt_regs, sdei_ttbr1)); |
| 76 | DEFINE(S_PMR_SAVE, offsetof(struct pt_regs, pmr_save)); | 76 | DEFINE(S_PMR_SAVE, offsetof(struct pt_regs, pmr_save)); |
| 77 | DEFINE(S_STACKFRAME, offsetof(struct pt_regs, stackframe)); | 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 | BLANK(); | 79 | BLANK(); |
| 80 | #ifdef CONFIG_COMPAT | 80 | #ifdef CONFIG_COMPAT |
| 81 | DEFINE(COMPAT_SIGFRAME_REGS_OFFSET, offsetof(struct compat_sigframe, uc.uc_mcontext.arm_r0)); | 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 | int parange, ipa_max; | 2568 | int parange, ipa_max; |
| 2569 | unsigned int safe_vmid_bits, vmid_bits; | 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 | return; | 2572 | return; |
| 2573 | 2573 | ||
| 2574 | safe_mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1); | 2574 | safe_mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1); |
| @@ -35,7 +35,7 @@ · 34 unmodified lines | |||
| 35 | */ | 35 | */ |
| 36 | .macro ftrace_regs_entry, allregs=0 | 36 | .macro ftrace_regs_entry, allregs=0 |
| 37 | /* Make room for pt_regs, plus a callee frame */ | 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 | /* Save function arguments (and x9 for simplicity) */ | 40 | /* Save function arguments (and x9 for simplicity) */ |
| 41 | stp x0, x1, [sp, #S_X0] | 41 | stp x0, x1, [sp, #S_X0] |
| @@ -61,15 +61,15 @@ · 19 unmodified lines | |||
| 61 | .endif | 61 | .endif |
| 62 | 62 | ||
| 63 | /* Save the callsite's SP and LR */ | 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 | stp x9, x10, [sp, #S_LR] | 65 | stp x9, x10, [sp, #S_LR] |
| 66 | 66 | ||
| 67 | /* Save the PC after the ftrace callsite */ | 67 | /* Save the PC after the ftrace callsite */ |
| 68 | str x30, [sp, #S_PC] | 68 | str x30, [sp, #S_PC] |
| 69 | 69 | ||
| 70 | /* Create a frame record for the callsite above pt_regs */ | 70 | /* Create a frame record for the callsite above pt_regs */ |
| 71 | stp x29, x9, [sp, #S_FRAME_SIZE] | 71 | stp x29, x9, [sp, #PT_REGS_SIZE] |
| 72 | add x29, sp, #S_FRAME_SIZE | 72 | add x29, sp, #PT_REGS_SIZE |
| 73 | 73 | ||
| 74 | /* Create our frame record within pt_regs. */ | 74 | /* Create our frame record within pt_regs. */ |
| 75 | stp x29, x30, [sp, #S_STACKFRAME] | 75 | stp x29, x30, [sp, #S_STACKFRAME] |
| @@ -120,7 +120,7 @@ ftrace_common_return: · 44 unmodified lines | |||
| 120 | ldr x9, [sp, #S_PC] | 120 | ldr x9, [sp, #S_PC] |
| 121 | 121 | ||
| 122 | /* Restore the callsite's SP */ | 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 | ret x9 | 125 | ret x9 |
| 126 | SYM_CODE_END(ftrace_common) | 126 | SYM_CODE_END(ftrace_common) |
| @@ -130,7 +130,7 @@ SYM_CODE_START(ftrace_graph_caller) · 3 unmodified lines | |||
| 130 | ldr x0, [sp, #S_PC] | 130 | ldr x0, [sp, #S_PC] |
| 131 | sub x0, x0, #AARCH64_INSN_SIZE // ip (callsite's BL insn) | 131 | sub x0, x0, #AARCH64_INSN_SIZE // ip (callsite's BL insn) |
| 132 | add x1, sp, #S_LR // parent_ip (callsite's LR) | 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 | bl prepare_ftrace_return | 134 | bl prepare_ftrace_return |
| 135 | b ftrace_common_return | 135 | b ftrace_common_return |
| 136 | SYM_CODE_END(ftrace_graph_caller) | 136 | SYM_CODE_END(ftrace_graph_caller) |
| @@ -75,7 +75,7 @@ alternative_else_nop_endif · 74 unmodified lines | |||
| 75 | .endif | 75 | .endif |
| 76 | #endif | 76 | #endif |
| 77 | 77 | ||
| 78 | sub sp, sp, #S_FRAME_SIZE | 78 | sub sp, sp, #PT_REGS_SIZE |
| 79 | #ifdef CONFIG_VMAP_STACK | 79 | #ifdef CONFIG_VMAP_STACK |
| 80 | /* | 80 | /* |
| 81 | * Test whether the SP has overflowed, without corrupting a GPR. | 81 | * Test whether the SP has overflowed, without corrupting a GPR. |
| @@ -96,7 +96,7 @@ alternative_else_nop_endif · 14 unmodified lines | |||
| 96 | * userspace, and can clobber EL0 registers to free up GPRs. | 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 | msr tpidr_el0, x0 | 100 | msr tpidr_el0, x0 |
| 101 | 101 | ||
| 102 | /* Recover the original x0 value and stash it in tpidrro_el0 */ | 102 | /* Recover the original x0 value and stash it in tpidrro_el0 */ |
| @@ -182,7 +182,6 @@ alternative_else_nop_endif · 79 unmodified lines | |||
| 182 | mrs_s \tmp2, SYS_GCR_EL1 | 182 | mrs_s \tmp2, SYS_GCR_EL1 |
| 183 | bfi \tmp2, \tmp, #0, #16 | 183 | bfi \tmp2, \tmp, #0, #16 |
| 184 | msr_s SYS_GCR_EL1, \tmp2 | 184 | msr_s SYS_GCR_EL1, \tmp2 |
| 185 | isb | ||
| 186 | #endif | 185 | #endif |
| 187 | .endm | 186 | .endm |
| 188 | 187 | ||
| @@ -194,6 +193,7 @@ alternative_else_nop_endif · 5 unmodified lines | |||
| 194 | ldr_l \tmp, gcr_kernel_excl | 193 | ldr_l \tmp, gcr_kernel_excl |
| 195 | 194 | ||
| 196 | mte_set_gcr \tmp, \tmp2 | 195 | mte_set_gcr \tmp, \tmp2 |
| 196 | isb | ||
| 197 | 1: | 197 | 1: |
| 198 | #endif | 198 | #endif |
| 199 | .endm | 199 | .endm |
| @@ -253,7 +253,7 @@ alternative_else_nop_endif · 53 unmodified lines | |||
| 253 | 253 | ||
| 254 | scs_load tsk, x20 | 254 | scs_load tsk, x20 |
| 255 | .else | 255 | .else |
| 256 | add x21, sp, #S_FRAME_SIZE | 256 | add x21, sp, #PT_REGS_SIZE |
| 257 | get_current_task tsk | 257 | get_current_task tsk |
| 258 | .endif /* \el == 0 */ | 258 | .endif /* \el == 0 */ |
| 259 | mrs x22, elr_el1 | 259 | mrs x22, elr_el1 |
| @@ -377,7 +377,7 @@ alternative_else_nop_endif · 117 unmodified lines | |||
| 377 | ldp x26, x27, [sp, #16 * 13] | 377 | ldp x26, x27, [sp, #16 * 13] |
| 378 | ldp x28, x29, [sp, #16 * 14] | 378 | ldp x28, x29, [sp, #16 * 14] |
| 379 | ldr lr, [sp, #S_LR] | 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 | .if \el == 0 | 382 | .if \el == 0 |
| 383 | alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0 | 383 | alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0 |
| @@ -580,12 +580,12 @@ __bad_stack: · 196 unmodified lines | |||
| 580 | 580 | ||
| 581 | /* | 581 | /* |
| 582 | * Store the original GPRs to the new stack. The orginal SP (minus | 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 | kernel_entry 1 | 586 | kernel_entry 1 |
| 587 | mrs x0, tpidr_el0 | 587 | mrs x0, tpidr_el0 |
| 588 | add x0, x0, #S_FRAME_SIZE | 588 | add x0, x0, #PT_REGS_SIZE |
| 589 | str x0, [sp, #S_SP] | 589 | str x0, [sp, #S_SP] |
| 590 | 590 | ||
| 591 | /* Stash the regs for handle_bad_stack */ | 591 | /* Stash the regs for handle_bad_stack */ |
| @@ -23,8 +23,6 @@ · 22 unmodified lines | |||
| 23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 24 | #include <linux/sched_clock.h> | 24 | #include <linux/sched_clock.h> |
| 25 | #include <linux/smp.h> | 25 | #include <linux/smp.h> |
| 26 | #include <linux/nmi.h> | ||
| 27 | #include <linux/cpufreq.h> | ||
| 28 | 26 | ||
| 29 | /* ARMv8 Cortex-A53 specific event types. */ | 27 | /* ARMv8 Cortex-A53 specific event types. */ |
| 30 | #define ARMV8_A53_PERFCTR_PREF_LINEFILL 0xC2 | 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 | static int __init armv8_pmu_driver_init(void) | 1249 | static int __init armv8_pmu_driver_init(void) |
| 1252 | { | 1250 | { |
| 1253 | int ret; | ||
| 1254 | |||
| 1255 | if (acpi_disabled) | 1251 | if (acpi_disabled) |
| 1256 | ret = platform_driver_register(&armv8_pmu_driver); | 1252 | return platform_driver_register(&armv8_pmu_driver); |
| 1257 | else | 1253 | else |
| 1258 | ret = arm_pmu_acpi_probe(armv8_pmuv3_init); | 1254 | return 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; | ||
| 1268 | } | 1255 | } |
| 1269 | device_initcall(armv8_pmu_driver_init) | 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 | userpg->cap_user_time_zero = 1; | 1309 | userpg->cap_user_time_zero = 1; |
| 1323 | userpg->cap_user_time_short = 1; | 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 | stp x24, x25, [sp, #S_X24] | 25 | stp x24, x25, [sp, #S_X24] |
| 26 | stp x26, x27, [sp, #S_X26] | 26 | stp x26, x27, [sp, #S_X26] |
| 27 | stp x28, x29, [sp, #S_X28] | 27 | stp x28, x29, [sp, #S_X28] |
| 28 | add x0, sp, #S_FRAME_SIZE | 28 | add x0, sp, #PT_REGS_SIZE |
| 29 | stp lr, x0, [sp, #S_LR] | 29 | stp lr, x0, [sp, #S_LR] |
| 30 | /* | 30 | /* |
| 31 | * Construct a useful saved PSTATE | 31 | * Construct a useful saved PSTATE |
| @@ -62,7 +62,7 @@ · 30 unmodified lines | |||
| 62 | .endm | 62 | .endm |
| 63 | 63 | ||
| 64 | SYM_CODE_START(kretprobe_trampoline) | 64 | SYM_CODE_START(kretprobe_trampoline) |
| 65 | sub sp, sp, #S_FRAME_SIZE | 65 | sub sp, sp, #PT_REGS_SIZE |
| 66 | 66 | ||
| 67 | save_all_base_regs | 67 | save_all_base_regs |
| 68 | 68 | ||
| @@ -76,7 +76,7 @@ SYM_CODE_START(kretprobe_trampoline) · 7 unmodified lines | |||
| 76 | 76 | ||
| 77 | restore_all_base_regs | 77 | restore_all_base_regs |
| 78 | 78 | ||
| 79 | add sp, sp, #S_FRAME_SIZE | 79 | add sp, sp, #PT_REGS_SIZE |
| 80 | ret | 80 | ret |
| 81 | 81 | ||
| 82 | SYM_CODE_END(kretprobe_trampoline) | 82 | SYM_CODE_END(kretprobe_trampoline) |
| @@ -914,13 +914,6 @@ static void do_signal(struct pt_regs *regs) · 913 unmodified lines | |||
| 914 | asmlinkage void do_notify_resume(struct pt_regs *regs, | 914 | asmlinkage void do_notify_resume(struct pt_regs *regs, |
| 915 | unsigned long thread_flags) | 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 | do { | 917 | do { |
| 925 | if (thread_flags & _TIF_NEED_RESCHED) { | 918 | if (thread_flags & _TIF_NEED_RESCHED) { |
| 926 | /* Unmask Debug and SError for the next task */ | 919 | /* Unmask Debug and SError for the next task */ |
| @@ -434,7 +434,7 @@ static void __init hyp_mode_check(void) · 433 unmodified lines | |||
| 434 | "CPU: CPUs started in inconsistent modes"); | 434 | "CPU: CPUs started in inconsistent modes"); |
| 435 | else | 435 | else |
| 436 | pr_info("CPU: All CPU(s) started at EL1\n"); | 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 | kvm_compute_layout(); | 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 | unsigned int cpu, i; | 807 | unsigned int cpu, i; |
| 808 | 808 | ||
| 809 | for (i = 0; i < NR_IPI; i++) { | 809 | for (i = 0; i < NR_IPI; i++) { |
| 810 | unsigned int irq = irq_desc_get_irq(ipi_desc[i]); | ||
| 811 | seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i, | 810 | seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i, |
| 812 | prec >= 4 ? " " : ""); | 811 | prec >= 4 ? " " : ""); |
| 813 | for_each_online_cpu(cpu) | 812 | for_each_online_cpu(cpu) |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | #include <asm/daifflags.h> | 10 | #include <asm/daifflags.h> |
| 11 | #include <asm/debug-monitors.h> | 11 | #include <asm/debug-monitors.h> |
| 12 | #include <asm/exception.h> | ||
| 12 | #include <asm/fpsimd.h> | 13 | #include <asm/fpsimd.h> |
| 13 | #include <asm/syscall.h> | 14 | #include <asm/syscall.h> |
| 14 | #include <asm/thread_info.h> | 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 | if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) { | 166 | if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) { |
| 166 | local_daif_mask(); | 167 | local_daif_mask(); |
| 167 | flags = current_thread_info()->flags; | 168 | flags = current_thread_info()->flags; |
| 168 | if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) { | 169 | 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(); | ||
| 175 | return; | 170 | return; |
| 176 | } | ||
| 177 | local_daif_restore(DAIF_PROCCTX); | 171 | local_daif_restore(DAIF_PROCCTX); |
| 178 | } | 172 | } |
| 179 | 173 | ||
| @@ -42,7 +42,6 @@ · 41 unmodified lines | |||
| 42 | #include <asm/smp.h> | 42 | #include <asm/smp.h> |
| 43 | #include <asm/stack_pointer.h> | 43 | #include <asm/stack_pointer.h> |
| 44 | #include <asm/stacktrace.h> | 44 | #include <asm/stacktrace.h> |
| 45 | #include <asm/exception.h> | ||
| 46 | #include <asm/system_misc.h> | 45 | #include <asm/system_misc.h> |
| 47 | #include <asm/sysreg.h> | 46 | #include <asm/sysreg.h> |
| 48 | 47 | ||
| @@ -24,8 +24,7 @@ btildflags-$(CONFIG_ARM64_BTI_KERNEL) += -z force-bti · 23 unmodified lines | |||
| 24 | # routines, as x86 does (see 6f121e548f83 ("x86, vdso: Reimplement vdso.so | 24 | # routines, as x86 does (see 6f121e548f83 ("x86, vdso: Reimplement vdso.so |
| 25 | # preparation in build-time C")). | 25 | # preparation in build-time C")). |
| 26 | ldflags-y := -shared -nostdlib -soname=linux-vdso.so.1 --hash-style=sysv \ | 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 \ | 27 | -Bsymbolic --build-id=sha1 -n $(btildflags-y) -T |
| 28 | $(btildflags-y) -T | ||
| 29 | 28 | ||
| 30 | ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18 | 29 | ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18 |
| 31 | ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO | 30 | ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO |
| @@ -40,9 +40,6 @@ SECTIONS · 39 unmodified lines | |||
| 40 | PROVIDE (_etext = .); | 40 | PROVIDE (_etext = .); |
| 41 | PROVIDE (etext = .); | 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 | .dynamic : { *(.dynamic) } :text :dynamic | 43 | .dynamic : { *(.dynamic) } :text :dynamic |
| 47 | 44 | ||
| 48 | .rodata : { *(.rodata*) } :text | 45 | .rodata : { *(.rodata*) } :text |
| @@ -54,6 +51,7 @@ SECTIONS · 5 unmodified lines | |||
| 54 | *(.note.GNU-stack) | 51 | *(.note.GNU-stack) |
| 55 | *(.data .data.* .gnu.linkonce.d.* .sdata*) | 52 | *(.data .data.* .gnu.linkonce.d.* .sdata*) |
| 56 | *(.bss .sbss .dynbss .dynsbss) | 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 | text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ | 64 | text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ |
| 67 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ | 65 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ |
| 68 | note PT_NOTE FLAGS(4); /* PF_R */ | 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 | source "virt/kvm/Kconfig" | 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 | endif # KVM | 52 | endif # KVM |
| 61 | 53 | ||
| 62 | endif # VIRTUALIZATION | 54 | endif # VIRTUALIZATION |
| @@ -24,4 +24,4 @@ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \ · 23 unmodified lines | |||
| 24 | vgic/vgic-mmio-v3.o vgic/vgic-kvm-device.o \ | 24 | vgic/vgic-mmio-v3.o vgic/vgic-kvm-device.o \ |
| 25 | vgic/vgic-its.o vgic/vgic-debug.o | 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 | if (!irqchip_in_kernel(vcpu->kvm)) | 1129 | if (!irqchip_in_kernel(vcpu->kvm)) |
| 1130 | goto no_vgic; | 1130 | goto no_vgic; |
| 1131 | 1131 | ||
| 1132 | if (!vgic_initialized(vcpu->kvm)) | 1132 | /* |
| 1133 | return -ENODEV; | 1133 | * At this stage, we have the guarantee that the vgic is both |
| 1134 | 1134 | * available and initialized. | |
| 1135 | */ | ||
| 1135 | if (!timer_irqs_are_valid(vcpu)) { | 1136 | if (!timer_irqs_are_valid(vcpu)) { |
| 1136 | kvm_debug("incorrectly configured timer irqs\n"); | 1137 | kvm_debug("incorrectly configured timer irqs\n"); |
| 1137 | return -EINVAL; | 1138 | return -EINVAL; |
| @@ -65,10 +65,6 @@ static bool vgic_present; · 64 unmodified lines | |||
| 65 | static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled); | 65 | static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled); |
| 66 | DEFINE_STATIC_KEY_FALSE(userspace_irqchip_in_use); | 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 | int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) | 68 | int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) |
| 73 | { | 69 | { |
| 74 | return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE; | 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 | * Map the VGIC hardware resources before running a vcpu the | 580 | * Map the VGIC hardware resources before running a vcpu the |
| 585 | * first time on this VM. | 581 | * first time on this VM. |
| 586 | */ | 582 | */ |
| 587 | if (unlikely(!vgic_ready(kvm))) { | 583 | ret = kvm_vgic_map_resources(kvm); |
| 588 | ret = kvm_vgic_map_resources(kvm); | 584 | if (ret) |
| 589 | if (ret) | 585 | return ret; |
| 590 | return ret; | ||
| 591 | } | ||
| 592 | } else { | 586 | } else { |
| 593 | /* | 587 | /* |
| 594 | * Tell the rest of the code that there are userspace irqchip | 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 | .notifier_call = hyp_init_cpu_pm_notifier, | 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 | if (!is_protected_kvm_enabled()) | 1573 | if (!is_protected_kvm_enabled()) |
| 1580 | cpu_pm_register_notifier(&hyp_init_cpu_pm_nb); | 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 | if (!is_protected_kvm_enabled()) | 1578 | if (!is_protected_kvm_enabled()) |
| 1585 | cpu_pm_unregister_notifier(&hyp_init_cpu_pm_nb); | 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 | * allow any other CPUs from the `possible` set to boot. | 1598 | * allow any other CPUs from the `possible` set to boot. |
| 1605 | */ | 1599 | */ |
| 1606 | for_each_online_cpu(cpu) | 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 | static bool init_psci_relay(void) | 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 | return false; | 1615 | return false; |
| 1619 | } | 1616 | } |
| 1620 | 1617 | ||
| 1621 | kvm_nvhe_sym(kvm_host_psci_version) = psci_ops.get_version(); | 1618 | kvm_host_psci_config.version = psci_ops.get_version(); |
| 1622 | kvm_nvhe_sym(kvm_host_psci_0_1_function_ids) = get_psci_0_1_function_ids(); | 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 | return true; | 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 | #endif | 71 | #endif |
| @@ -157,11 +157,6 @@ static void default_host_smc_handler(struct kvm_cpu_context *host_ctxt) · 156 unmodified lines | |||
| 157 | __kvm_hyp_host_forward_smc(host_ctxt); | 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 | static void handle_host_smc(struct kvm_cpu_context *host_ctxt) | 160 | static void handle_host_smc(struct kvm_cpu_context *host_ctxt) |
| 166 | { | 161 | { |
| 167 | bool handled; | 162 | bool handled; |
| @@ -170,11 +165,8 @@ static void handle_host_smc(struct kvm_cpu_context *host_ctxt) · 2 unmodified lines | |||
| 170 | if (!handled) | 165 | if (!handled) |
| 171 | default_host_smc_handler(host_ctxt); | 166 | default_host_smc_handler(host_ctxt); |
| 172 | 167 | ||
| 173 | /* | 168 | /* SMC was trapped, move ELR past the current PC. */ |
| 174 | * Unlike HVC, the return address of an SMC is the instruction's PC. | 169 | kvm_skip_host_instr(); |
| 175 | * Move the return address past the instruction. | ||
| 176 | */ | ||
| 177 | skip_host_instruction(); | ||
| 178 | } | 170 | } |
| 179 | 171 | ||
| 180 | void handle_trap(struct kvm_cpu_context *host_ctxt) | 172 | void handle_trap(struct kvm_cpu_context *host_ctxt) |
| @@ -14,14 +14,14 @@ · 13 unmodified lines | |||
| 14 | * Other CPUs should not be allowed to boot because their features were | 14 | * Other CPUs should not be allowed to boot because their features were |
| 15 | * not checked against the finalized system capabilities. | 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 | u64 cpu_logical_map(unsigned int cpu) | 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 | hyp_panic(); | 22 | hyp_panic(); |
| 23 | 23 | ||
| 24 | return __cpu_logical_map[cpu]; | 24 | return hyp_cpu_logical_map[cpu]; |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | unsigned long __hyp_per_cpu_offset(unsigned int cpu) | 27 | unsigned long __hyp_per_cpu_offset(unsigned int cpu) |
| @@ -7,11 +7,8 @@ · 6 unmodified lines | |||
| 7 | #include <asm/kvm_asm.h> | 7 | #include <asm/kvm_asm.h> |
| 8 | #include <asm/kvm_hyp.h> | 8 | #include <asm/kvm_hyp.h> |
| 9 | #include <asm/kvm_mmu.h> | 9 | #include <asm/kvm_mmu.h> |
| 10 | #include <kvm/arm_hypercalls.h> | ||
| 11 | #include <linux/arm-smccc.h> | 10 | #include <linux/arm-smccc.h> |
| 12 | #include <linux/kvm_host.h> | 11 | #include <linux/kvm_host.h> |
| 13 | #include <linux/psci.h> | ||
| 14 | #include <kvm/arm_psci.h> | ||
| 15 | #include <uapi/linux/psci.h> | 12 | #include <uapi/linux/psci.h> |
| 16 | 13 | ||
| 17 | #include <nvhe/trap_handler.h> | 14 | #include <nvhe/trap_handler.h> |
| @@ -22,9 +19,8 @@ void kvm_hyp_cpu_resume(unsigned long r0); · 4 unmodified lines | |||
| 22 | void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt); | 19 | void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt); |
| 23 | 20 | ||
| 24 | /* Config options set by the host. */ | 21 | /* Config options set by the host. */ |
| 25 | __ro_after_init u32 kvm_host_psci_version; | 22 | struct kvm_host_psci_config __ro_after_init kvm_host_psci_config; |
| 26 | __ro_after_init struct psci_0_1_function_ids kvm_host_psci_0_1_function_ids; | 23 | s64 __ro_after_init hyp_physvirt_offset; |
| 27 | __ro_after_init s64 hyp_physvirt_offset; | ||
| 28 | 24 | ||
| 29 | #define __hyp_pa(x) ((phys_addr_t)((x)) + hyp_physvirt_offset) | 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 | static DEFINE_PER_CPU(struct psci_boot_args, cpu_on_args) = PSCI_BOOT_ARGS_INIT; | 43 | static DEFINE_PER_CPU(struct psci_boot_args, cpu_on_args) = PSCI_BOOT_ARGS_INIT; |
| 48 | static DEFINE_PER_CPU(struct psci_boot_args, suspend_args) = PSCI_BOOT_ARGS_INIT; | 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) | 46 | #define is_psci_0_1(what, func_id) \ |
| 51 | { | 47 | (kvm_host_psci_config.psci_0_1_ ## what ## _implemented && \ |
| 52 | DECLARE_REG(u64, func_id, host_ctxt, 0); | 48 | (func_id) == kvm_host_psci_config.function_ids_0_1.what) |
| 53 | |||
| 54 | return func_id; | ||
| 55 | } | ||
| 56 | 49 | ||
| 57 | static bool is_psci_0_1_call(u64 func_id) | 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) || | 52 | return (is_psci_0_1(cpu_suspend, func_id) || |
| 60 | (func_id == kvm_host_psci_0_1_function_ids.cpu_on) || | 53 | is_psci_0_1(cpu_on, func_id) || |
| 61 | (func_id == kvm_host_psci_0_1_function_ids.cpu_off) || | 54 | is_psci_0_1(cpu_off, func_id) || |
| 62 | (func_id == kvm_host_psci_0_1_function_ids.migrate); | 55 | is_psci_0_1(migrate, func_id)); |
| 63 | } | 56 | } |
| 64 | 57 | ||
| 65 | static bool is_psci_0_2_call(u64 func_id) | 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 | (PSCI_0_2_FN64(0) <= func_id && func_id <= PSCI_0_2_FN64(31)); | 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 | static unsigned long psci_call(unsigned long fn, unsigned long arg0, | 65 | static unsigned long psci_call(unsigned long fn, unsigned long arg0, |
| 83 | unsigned long arg1, unsigned long arg2) | 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 | static unsigned long psci_0_1_handler(u64 func_id, struct kvm_cpu_context *host_ctxt) | 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) || | 234 | if (is_psci_0_1(cpu_off, func_id) || is_psci_0_1(migrate, func_id)) |
| 252 | (func_id == kvm_host_psci_0_1_function_ids.migrate)) | ||
| 253 | return psci_forward(host_ctxt); | 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 | return psci_cpu_on(func_id, host_ctxt); | 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 | return psci_cpu_suspend(func_id, host_ctxt); | 239 | return psci_cpu_suspend(func_id, host_ctxt); |
| 258 | else | 240 | |
| 259 | return PSCI_RET_NOT_SUPPORTED; | 241 | return PSCI_RET_NOT_SUPPORTED; |
| 260 | } | 242 | } |
| 261 | 243 | ||
| 262 | static unsigned long psci_0_2_handler(u64 func_id, struct kvm_cpu_context *host_ctxt) | 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 | bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt) | 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 | unsigned long ret; | 284 | unsigned long ret; |
| 303 | 285 | ||
| 304 | if (!is_psci_call(func_id)) | 286 | switch (kvm_host_psci_config.version) { |
| 305 | return false; | ||
| 306 | |||
| 307 | switch (kvm_host_psci_version) { | ||
| 308 | case PSCI_VERSION(0, 1): | 287 | case PSCI_VERSION(0, 1): |
| 288 | if (!is_psci_0_1_call(func_id)) | ||
| 289 | return false; | ||
| 309 | ret = psci_0_1_handler(func_id, host_ctxt); | 290 | ret = psci_0_1_handler(func_id, host_ctxt); |
| 310 | break; | 291 | break; |
| 311 | case PSCI_VERSION(0, 2): | 292 | case PSCI_VERSION(0, 2): |
| 293 | if (!is_psci_0_2_call(func_id)) | ||
| 294 | return false; | ||
| 312 | ret = psci_0_2_handler(func_id, host_ctxt); | 295 | ret = psci_0_2_handler(func_id, host_ctxt); |
| 313 | break; | 296 | break; |
| 314 | default: | 297 | default: |
| 298 | if (!is_psci_0_2_call(func_id)) | ||
| 299 | return false; | ||
| 315 | ret = psci_1_0_handler(func_id, host_ctxt); | 300 | ret = psci_1_0_handler(func_id, host_ctxt); |
| 316 | break; | 301 | break; |
| 317 | } | 302 | } |
| @@ -850,8 +850,6 @@ int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu) · 849 unmodified lines | |||
| 850 | return -EINVAL; | 850 | return -EINVAL; |
| 851 | } | 851 | } |
| 852 | 852 | ||
| 853 | kvm_pmu_vcpu_reset(vcpu); | ||
| 854 | |||
| 855 | return 0; | 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 | u64 pmcr, val; | 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 | pmcr = read_sysreg(pmcr_el0); | 601 | pmcr = read_sysreg(pmcr_el0); |
| 598 | /* | 602 | /* |
| 599 | * Writable bits of PMCR_EL0 (ARMV8_PMU_PMCR_MASK) are reset to UNKNOWN | 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 | #define reg_to_encoding(x) \ | 924 | #define reg_to_encoding(x) \ |
| 921 | sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \ | 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 | /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */ | 928 | /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */ |
| 925 | #define DBG_BCR_BVR_WCR_WVR_EL1(n) \ | 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 | static void init_hyp_physvirt_offset(void) | 39 | static void init_hyp_physvirt_offset(void) |
| 40 | { | 40 | { |
| 41 | extern s64 kvm_nvhe_sym(hyp_physvirt_offset); | ||
| 42 | u64 kern_va, hyp_va; | 41 | u64 kern_va, hyp_va; |
| 43 | 42 | ||
| 44 | /* Compute the offset from the hyp VA and PA of a random symbol. */ | 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 | hyp_va = __early_kern_hyp_va(kern_va); | 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 | * Map the MMIO regions depending on the VGIC model exposed to the guest | 419 | * Map the MMIO regions depending on the VGIC model exposed to the guest |
| 420 | * called on the first VCPU run. | 420 | * called on the first VCPU run. |
| 421 | * Also map the virtual CPU interface into the VM. | 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 | * vgic_ready() returns true if this function has succeeded. | 424 | * vgic_ready() returns true if this function has succeeded. |
| 424 | * @kvm: kvm struct pointer | 425 | * @kvm: kvm struct pointer |
| 425 | */ | 426 | */ |
| @@ -428,7 +429,13 @@ int kvm_vgic_map_resources(struct kvm *kvm) · 2 unmodified lines | |||
| 428 | struct vgic_dist *dist = &kvm->arch.vgic; | 429 | struct vgic_dist *dist = &kvm->arch.vgic; |
| 429 | int ret = 0; | 430 | int ret = 0; |
| 430 | 431 | ||
| 432 | if (likely(vgic_ready(kvm))) | ||
| 433 | return 0; | ||
| 434 | |||
| 431 | mutex_lock(&kvm->lock); | 435 | mutex_lock(&kvm->lock); |
| 436 | if (vgic_ready(kvm)) | ||
| 437 | goto out; | ||
| 438 | |||
| 432 | if (!irqchip_in_kernel(kvm)) | 439 | if (!irqchip_in_kernel(kvm)) |
| 433 | goto out; | 440 | goto out; |
| 434 | 441 | ||
| @@ -439,6 +446,8 @@ int kvm_vgic_map_resources(struct kvm *kvm) · 4 unmodified lines | |||
| 439 | 446 | ||
| 440 | if (ret) | 447 | if (ret) |
| 441 | __kvm_vgic_destroy(kvm); | 448 | __kvm_vgic_destroy(kvm); |
| 449 | else | ||
| 450 | dist->ready = true; | ||
| 442 | 451 | ||
| 443 | out: | 452 | out: |
| 444 | mutex_unlock(&kvm->lock); | 453 | mutex_unlock(&kvm->lock); |
| @@ -306,20 +306,15 @@ int vgic_v2_map_resources(struct kvm *kvm) · 305 unmodified lines | |||
| 306 | struct vgic_dist *dist = &kvm->arch.vgic; | 306 | struct vgic_dist *dist = &kvm->arch.vgic; |
| 307 | int ret = 0; | 307 | int ret = 0; |
| 308 | 308 | ||
| 309 | if (vgic_ready(kvm)) | ||
| 310 | goto out; | ||
| 311 | |||
| 312 | if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base) || | 309 | if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base) || |
| 313 | IS_VGIC_ADDR_UNDEF(dist->vgic_cpu_base)) { | 310 | IS_VGIC_ADDR_UNDEF(dist->vgic_cpu_base)) { |
| 314 | kvm_err("Need to set vgic cpu and dist addresses first\n"); | 311 | kvm_err("Need to set vgic cpu and dist addresses first\n"); |
| 315 | ret = -ENXIO; | 312 | return -ENXIO; |
| 316 | goto out; | ||
| 317 | } | 313 | } |
| 318 | 314 | ||
| 319 | if (!vgic_v2_check_base(dist->vgic_dist_base, dist->vgic_cpu_base)) { | 315 | if (!vgic_v2_check_base(dist->vgic_dist_base, dist->vgic_cpu_base)) { |
| 320 | kvm_err("VGIC CPU and dist frames overlap\n"); | 316 | kvm_err("VGIC CPU and dist frames overlap\n"); |
| 321 | ret = -EINVAL; | 317 | return -EINVAL; |
| 322 | goto out; | ||
| 323 | } | 318 | } |
| 324 | 319 | ||
| 325 | /* | 320 | /* |
| @@ -329,13 +324,13 @@ int vgic_v2_map_resources(struct kvm *kvm) · 3 unmodified lines | |||
| 329 | ret = vgic_init(kvm); | 324 | ret = vgic_init(kvm); |
| 330 | if (ret) { | 325 | if (ret) { |
| 331 | kvm_err("Unable to initialize VGIC dynamic data structures\n"); | 326 | kvm_err("Unable to initialize VGIC dynamic data structures\n"); |
| 332 | goto out; | 327 | return ret; |
| 333 | } | 328 | } |
| 334 | 329 | ||
| 335 | ret = vgic_register_dist_iodev(kvm, dist->vgic_dist_base, VGIC_V2); | 330 | ret = vgic_register_dist_iodev(kvm, dist->vgic_dist_base, VGIC_V2); |
| 336 | if (ret) { | 331 | if (ret) { |
| 337 | kvm_err("Unable to register VGIC MMIO regions\n"); | 332 | kvm_err("Unable to register VGIC MMIO regions\n"); |
| 338 | goto out; | 333 | return ret; |
| 339 | } | 334 | } |
| 340 | 335 | ||
| 341 | if (!static_branch_unlikely(&vgic_v2_cpuif_trap)) { | 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 | KVM_VGIC_V2_CPU_SIZE, true); | 339 | KVM_VGIC_V2_CPU_SIZE, true); |
| 345 | if (ret) { | 340 | if (ret) { |
| 346 | kvm_err("Unable to remap VGIC CPU to VCPU\n"); | 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; | 346 | return 0; |
| 352 | |||
| 353 | out: | ||
| 354 | return ret; | ||
| 355 | } | 347 | } |
| 356 | 348 | ||
| 357 | DEFINE_STATIC_KEY_FALSE(vgic_v2_cpuif_trap); | 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 | int ret = 0; | 500 | int ret = 0; |
| 501 | int c; | 501 | int c; |
| 502 | 502 | ||
| 503 | if (vgic_ready(kvm)) | ||
| 504 | goto out; | ||
| 505 | |||
| 506 | kvm_for_each_vcpu(c, vcpu, kvm) { | 503 | kvm_for_each_vcpu(c, vcpu, kvm) { |
| 507 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | 504 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; |
| 508 | 505 | ||
| 509 | if (IS_VGIC_ADDR_UNDEF(vgic_cpu->rd_iodev.base_addr)) { | 506 | if (IS_VGIC_ADDR_UNDEF(vgic_cpu->rd_iodev.base_addr)) { |
| 510 | kvm_debug("vcpu %d redistributor base not set\n", c); | 507 | kvm_debug("vcpu %d redistributor base not set\n", c); |
| 511 | ret = -ENXIO; | 508 | return -ENXIO; |
| 512 | goto out; | ||
| 513 | } | 509 | } |
| 514 | } | 510 | } |
| 515 | 511 | ||
| 516 | if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base)) { | 512 | if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base)) { |
| 517 | kvm_err("Need to set vgic distributor addresses first\n"); | 513 | kvm_err("Need to set vgic distributor addresses first\n"); |
| 518 | ret = -ENXIO; | 514 | return -ENXIO; |
| 519 | goto out; | ||
| 520 | } | 515 | } |
| 521 | 516 | ||
| 522 | if (!vgic_v3_check_base(kvm)) { | 517 | if (!vgic_v3_check_base(kvm)) { |
| 523 | kvm_err("VGIC redist and dist frames overlap\n"); | 518 | kvm_err("VGIC redist and dist frames overlap\n"); |
| 524 | ret = -EINVAL; | 519 | return -EINVAL; |
| 525 | goto out; | ||
| 526 | } | 520 | } |
| 527 | 521 | ||
| 528 | /* | 522 | /* |
| @@ -530,22 +524,19 @@ int vgic_v3_map_resources(struct kvm *kvm) · 1 unmodified line | |||
| 530 | * the VGIC before we need to use it. | 524 | * the VGIC before we need to use it. |
| 531 | */ | 525 | */ |
| 532 | if (!vgic_initialized(kvm)) { | 526 | if (!vgic_initialized(kvm)) { |
| 533 | ret = -EBUSY; | 527 | return -EBUSY; |
| 534 | goto out; | ||
| 535 | } | 528 | } |
| 536 | 529 | ||
| 537 | ret = vgic_register_dist_iodev(kvm, dist->vgic_dist_base, VGIC_V3); | 530 | ret = vgic_register_dist_iodev(kvm, dist->vgic_dist_base, VGIC_V3); |
| 538 | if (ret) { | 531 | if (ret) { |
| 539 | kvm_err("Unable to register VGICv3 dist MMIO regions\n"); | 532 | kvm_err("Unable to register VGICv3 dist MMIO regions\n"); |
| 540 | goto out; | 533 | return ret; |
| 541 | } | 534 | } |
| 542 | 535 | ||
| 543 | if (kvm_vgic_global_state.has_gicv4_1) | 536 | if (kvm_vgic_global_state.has_gicv4_1) |
| 544 | vgic_v4_configure_vsgis(kvm); | 537 | vgic_v4_configure_vsgis(kvm); |
| 545 | dist->ready = true; | ||
| 546 | 538 | ||
| 547 | out: | 539 | return 0; |
| 548 | return ret; | ||
| 549 | } | 540 | } |
| 550 | 541 | ||
| 551 | DEFINE_STATIC_KEY_FALSE(vgic_v3_cpuif_trap); | 542 | DEFINE_STATIC_KEY_FALSE(vgic_v3_cpuif_trap); |
| @@ -53,13 +53,13 @@ s64 memstart_addr __ro_after_init = -1; · 52 unmodified lines | |||
| 53 | EXPORT_SYMBOL(memstart_addr); | 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 | 56 | * If the corresponding config options are enabled, we create both ZONE_DMA |
| 57 | * memory as some devices, namely the Raspberry Pi 4, have peripherals with | 57 | * and ZONE_DMA32. By default ZONE_DMA covers the 32-bit addressable memory |
| 58 | * this limited view of the memory. ZONE_DMA32 will cover the rest of the 32 | 58 | * unless restricted on specific platforms (e.g. 30-bit on Raspberry Pi 4). |
| 59 | * bit addressable memory area. | 59 | * In such case, ZONE_DMA32 covers the rest of the 32-bit addressable memory, |
| 60 | * otherwise it is empty. | ||
| 60 | */ | 61 | */ |
| 61 | phys_addr_t arm64_dma_phys_limit __ro_after_init; | 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 | #ifdef CONFIG_KEXEC_CORE | 64 | #ifdef CONFIG_KEXEC_CORE |
| 65 | /* | 65 | /* |
| @@ -84,7 +84,7 @@ static void __init reserve_crashkernel(void) · 18 unmodified lines | |||
| 84 | 84 | ||
| 85 | if (crash_base == 0) { | 85 | if (crash_base == 0) { |
| 86 | /* Current arm64 boot protocol requires 2MB alignment */ | 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 | crash_size, SZ_2M); | 88 | crash_size, SZ_2M); |
| 89 | if (crash_base == 0) { | 89 | if (crash_base == 0) { |
| 90 | pr_warn("cannot allocate crashkernel (size:0x%llx)\n", | 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 | unsigned long max_zone_pfns[MAX_NR_ZONES] = {0}; | 196 | unsigned long max_zone_pfns[MAX_NR_ZONES] = {0}; |
| 197 | unsigned int __maybe_unused acpi_zone_dma_bits; | 197 | unsigned int __maybe_unused acpi_zone_dma_bits; |
| 198 | unsigned int __maybe_unused dt_zone_dma_bits; | 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 | #ifdef CONFIG_ZONE_DMA | 201 | #ifdef CONFIG_ZONE_DMA |
| 201 | acpi_zone_dma_bits = fls64(acpi_iort_dma_get_max_cpu_address()); | 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 | max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit); | 206 | max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit); |
| 206 | #endif | 207 | #endif |
| 207 | #ifdef CONFIG_ZONE_DMA32 | 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 | #endif | 212 | #endif |
| 213 | if (!arm64_dma_phys_limit) | ||
| 214 | arm64_dma_phys_limit = PHYS_MASK + 1; | ||
| 210 | max_zone_pfns[ZONE_NORMAL] = max; | 215 | max_zone_pfns[ZONE_NORMAL] = max; |
| 211 | 216 | ||
| 212 | free_area_init(max_zone_pfns); | 217 | free_area_init(max_zone_pfns); |
| @@ -394,16 +399,9 @@ void __init arm64_memblock_init(void) · 181 unmodified lines | |||
| 394 | 399 | ||
| 395 | early_init_fdt_scan_reserved_mem(); | 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 | reserve_elfcorehdr(); | 402 | reserve_elfcorehdr(); |
| 403 | 403 | ||
| 404 | high_memory = __va(memblock_end_of_DRAM() - 1) + 1; | 404 | high_memory = __va(memblock_end_of_DRAM() - 1) + 1; |
| 405 | |||
| 406 | dma_contiguous_reserve(arm64_dma32_phys_limit); | ||
| 407 | } | 405 | } |
| 408 | 406 | ||
| 409 | void __init bootmem_init(void) | 407 | void __init bootmem_init(void) |
| @@ -438,6 +436,11 @@ void __init bootmem_init(void) · 28 unmodified lines | |||
| 438 | sparse_init(); | 436 | sparse_init(); |
| 439 | zone_sizes_init(min, max); | 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 | * request_standard_resources() depends on crashkernel's memory being | 445 | * request_standard_resources() depends on crashkernel's memory being |
| 443 | * reserved, so do it here. | 446 | * reserved, so do it here. |
| @@ -455,7 +458,7 @@ void __init bootmem_init(void) · 11 unmodified lines | |||
| 455 | void __init mem_init(void) | 458 | void __init mem_init(void) |
| 456 | { | 459 | { |
| 457 | if (swiotlb_force == SWIOTLB_FORCE || | 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 | swiotlb_init(1); | 462 | swiotlb_init(1); |
| 460 | else | 463 | else |
| 461 | swiotlb_force = SWIOTLB_NO_FORCE; | 464 | swiotlb_force = SWIOTLB_NO_FORCE; |
| @@ -46,7 +46,7 @@ · 45 unmodified lines | |||
| 46 | #endif | 46 | #endif |
| 47 | 47 | ||
| 48 | #ifdef CONFIG_KASAN_HW_TAGS | 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 | #else | 50 | #else |
| 51 | #define TCR_KASAN_HW_FLAGS 0 | 51 | #define TCR_KASAN_HW_FLAGS 0 |
| 52 | #endif | 52 | #endif |
| @@ -2,7 +2,6 @@ · 1 unmodified line | |||
| 2 | generic-y += asm-offsets.h | 2 | generic-y += asm-offsets.h |
| 3 | generic-y += gpio.h | 3 | generic-y += gpio.h |
| 4 | generic-y += kvm_para.h | 4 | generic-y += kvm_para.h |
| 5 | generic-y += local64.h | ||
| 6 | generic-y += qrwlock.h | 5 | generic-y += qrwlock.h |
| 7 | generic-y += user.h | 6 | generic-y += user.h |
| 8 | generic-y += vmlinux.lds.h | 7 | generic-y += vmlinux.lds.h |
| @@ -2,7 +2,6 @@ · 1 unmodified line | |||
| 2 | generic-y += asm-offsets.h | 2 | generic-y += asm-offsets.h |
| 3 | generic-y += extable.h | 3 | generic-y += extable.h |
| 4 | generic-y += kvm_para.h | 4 | generic-y += kvm_para.h |
| 5 | generic-y += local64.h | ||
| 6 | generic-y += mcs_spinlock.h | 5 | generic-y += mcs_spinlock.h |
| 7 | generic-y += parport.h | 6 | generic-y += parport.h |
| 8 | generic-y += spinlock.h | 7 | generic-y += spinlock.h |
| @@ -2,5 +2,4 @@ · 1 unmodified line | |||
| 2 | generic-y += extable.h | 2 | generic-y += extable.h |
| 3 | generic-y += iomap.h | 3 | generic-y += iomap.h |
| 4 | generic-y += kvm_para.h | 4 | generic-y += kvm_para.h |
| 5 | generic-y += local64.h | ||
| 6 | generic-y += mcs_spinlock.h | 5 | generic-y += mcs_spinlock.h |
| @@ -1 +0,0 @@ | |||
| 1 | #include <asm-generic/local64.h> | ||
| @@ -3,6 +3,7 @@ · 2 unmodified lines | |||
| 3 | #define _ASM_IA64_SPARSEMEM_H | 3 | #define _ASM_IA64_SPARSEMEM_H |
| 4 | 4 | ||
| 5 | #ifdef CONFIG_SPARSEMEM | 5 | #ifdef CONFIG_SPARSEMEM |
| 6 | #include <asm/page.h> | ||
| 6 | /* | 7 | /* |
| 7 | * SECTION_SIZE_BITS 2^N: how big each section will be | 8 | * SECTION_SIZE_BITS 2^N: how big each section will be |
| 8 | * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space | 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 | if (map_start < map_end) | 537 | if (map_start < map_end) |
| 538 | memmap_init_zone((unsigned long)(map_end - map_start), | 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 | MEMINIT_EARLY, NULL, MIGRATE_MOVABLE); | 540 | MEMINIT_EARLY, NULL, MIGRATE_MOVABLE); |
| 541 | return 0; | 541 | return 0; |
| 542 | } | 542 | } |
| @@ -546,7 +546,7 @@ memmap_init (unsigned long size, int nid, unsigned long zone, · 3 unmodified lines | |||
| 546 | unsigned long start_pfn) | 546 | unsigned long start_pfn) |
| 547 | { | 547 | { |
| 548 | if (!vmem_map) { | 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 | MEMINIT_EARLY, NULL, MIGRATE_MOVABLE); | 550 | MEMINIT_EARLY, NULL, MIGRATE_MOVABLE); |
| 551 | } else { | 551 | } else { |
| 552 | struct page *start; | 552 | struct page *start; |
| @@ -2,6 +2,5 @@ · 1 unmodified line | |||
| 2 | generated-y += syscall_table.h | 2 | generated-y += syscall_table.h |
| 3 | generic-y += extable.h | 3 | generic-y += extable.h |
| 4 | generic-y += kvm_para.h | 4 | generic-y += kvm_para.h |
| 5 | generic-y += local64.h | ||
| 6 | generic-y += mcs_spinlock.h | 5 | generic-y += mcs_spinlock.h |
| 7 | generic-y += spinlock.h | 6 | generic-y += spinlock.h |
| @@ -2,7 +2,6 @@ · 1 unmodified line | |||
| 2 | generated-y += syscall_table.h | 2 | generated-y += syscall_table.h |
| 3 | generic-y += extable.h | 3 | generic-y += extable.h |
| 4 | generic-y += kvm_para.h | 4 | generic-y += kvm_para.h |
| 5 | generic-y += local64.h | ||
| 6 | generic-y += mcs_spinlock.h | 5 | generic-y += mcs_spinlock.h |
| 7 | generic-y += parport.h | 6 | generic-y += parport.h |
| 8 | generic-y += syscalls.h | 7 | generic-y += syscalls.h |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <linux/libfdt.h> | 13 | #include <linux/libfdt.h> |
| 14 | 14 | ||
| 15 | #include <asm/addrspace.h> | 15 | #include <asm/addrspace.h> |
| 16 | #include <asm/unaligned.h> | ||
| 16 | 17 | ||
| 17 | /* | 18 | /* |
| 18 | * These two variables specify the free mem region | 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 | dtb_size = fdt_totalsize((void *)&__appended_dtb); | 118 | dtb_size = fdt_totalsize((void *)&__appended_dtb); |
| 118 | 119 | ||
| 119 | /* last four bytes is always image size in little endian */ | 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 | /* copy dtb to where the booted kernel will expect it */ | 123 | /* copy dtb to where the booted kernel will expect it */ |
| 123 | memcpy((void *)VMLINUX_LOAD_ADDRESS_ULL + image_size, | 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 | static int __init octeon_irq_init_ciu( | 1444 | static int __init octeon_irq_init_ciu( |
| 1445 | struct device_node *ciu_node, struct device_node *parent) | 1445 | struct device_node *ciu_node, struct device_node *parent) |
| 1446 | { | 1446 | { |
| 1447 | unsigned int i, r; | 1447 | int i, r; |
| 1448 | struct irq_chip *chip; | 1448 | struct irq_chip *chip; |
| 1449 | struct irq_chip *chip_edge; | 1449 | struct irq_chip *chip_edge; |
| 1450 | struct irq_chip *chip_mbox; | 1450 | struct irq_chip *chip_mbox; |
| @@ -6,7 +6,6 @@ generated-y += syscall_table_64_n64.h · 5 unmodified lines | |||
| 6 | generated-y += syscall_table_64_o32.h | 6 | generated-y += syscall_table_64_o32.h |
| 7 | generic-y += export.h | 7 | generic-y += export.h |
| 8 | generic-y += kvm_para.h | 8 | generic-y += kvm_para.h |
| 9 | generic-y += local64.h | ||
| 10 | generic-y += mcs_spinlock.h | 9 | generic-y += mcs_spinlock.h |
| 11 | generic-y += parport.h | 10 | generic-y += parport.h |
| 12 | generic-y += qrwlock.h | 11 | generic-y += qrwlock.h |
| @@ -103,4 +103,11 @@ jiffies_to_old_timeval32(unsigned long jiffies, struct old_timeval32 *value) · 102 unmodified lines | |||
| 103 | #undef ns_to_kernel_old_timeval | 103 | #undef ns_to_kernel_old_timeval |
| 104 | #define ns_to_kernel_old_timeval ns_to_old_timeval32 | 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 | #include "../../../fs/binfmt_elf.c" | 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 | #undef ns_to_kernel_old_timeval | 106 | #undef ns_to_kernel_old_timeval |
| 107 | #define ns_to_kernel_old_timeval ns_to_old_timeval32 | 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 | #include "../../../fs/binfmt_elf.c" | 116 | #include "../../../fs/binfmt_elf.c" |
| @@ -187,8 +187,14 @@ static int __init relocate_exception_table(long offset) · 186 unmodified lines | |||
| 187 | static inline __init unsigned long rotate_xor(unsigned long hash, | 187 | static inline __init unsigned long rotate_xor(unsigned long hash, |
| 188 | const void *area, size_t size) | 188 | const void *area, size_t size) |
| 189 | { | 189 | { |
| 190 | size_t i; | 190 | const typeof(hash) *ptr = PTR_ALIGN(area, sizeof(hash)); |
| 191 | unsigned long *ptr = (unsigned long *)area; | 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 | for (i = 0; i < size / sizeof(hash); i++) { | 199 | for (i = 0; i < size / sizeof(hash); i++) { |
| 194 | /* Rotate by odd number of bits and XOR. */ | 200 | /* Rotate by odd number of bits and XOR. */ |
| @@ -4,6 +4,5 @@ generic-y += cmpxchg.h · 3 unmodified lines | |||
| 4 | generic-y += export.h | 4 | generic-y += export.h |
| 5 | generic-y += gpio.h | 5 | generic-y += gpio.h |
| 6 | generic-y += kvm_para.h | 6 | generic-y += kvm_para.h |
| 7 | generic-y += local64.h | ||
| 8 | generic-y += parport.h | 7 | generic-y += parport.h |
| 9 | generic-y += user.h | 8 | generic-y += user.h |
| @@ -1,7 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | generic-y += extable.h | 2 | generic-y += extable.h |
| 3 | generic-y += kvm_para.h | 3 | generic-y += kvm_para.h |
| 4 | generic-y += local64.h | ||
| 5 | generic-y += mcs_spinlock.h | 4 | generic-y += mcs_spinlock.h |
| 6 | generic-y += qspinlock_types.h | 5 | generic-y += qspinlock_types.h |
| 7 | generic-y += qspinlock.h | 6 | generic-y += qspinlock.h |
| @@ -3,6 +3,5 @@ generated-y += syscall_table_32.h · 2 unmodified lines | |||
| 3 | generated-y += syscall_table_64.h | 3 | generated-y += syscall_table_64.h |
| 4 | generated-y += syscall_table_c32.h | 4 | generated-y += syscall_table_c32.h |
| 5 | generic-y += kvm_para.h | 5 | generic-y += kvm_para.h |
| 6 | generic-y += local64.h | ||
| 7 | generic-y += mcs_spinlock.h | 6 | generic-y += mcs_spinlock.h |
| 8 | generic-y += user.h | 7 | generic-y += user.h |
| @@ -5,7 +5,6 @@ generated-y += syscall_table_c32.h · 4 unmodified lines | |||
| 5 | generated-y += syscall_table_spu.h | 5 | generated-y += syscall_table_spu.h |
| 6 | generic-y += export.h | 6 | generic-y += export.h |
| 7 | generic-y += kvm_types.h | 7 | generic-y += kvm_types.h |
| 8 | generic-y += local64.h | ||
| 9 | generic-y += mcs_spinlock.h | 8 | generic-y += mcs_spinlock.h |
| 10 | generic-y += qrwlock.h | 9 | generic-y += qrwlock.h |
| 11 | generic-y += vtime.h | 10 | generic-y += vtime.h |
| @@ -103,6 +103,8 @@ int gettimeofday_fallback(struct __kernel_old_timeval *_tv, struct timezone *_tz · 102 unmodified lines | |||
| 103 | return do_syscall_2(__NR_gettimeofday, (unsigned long)_tv, (unsigned long)_tz); | 103 | return do_syscall_2(__NR_gettimeofday, (unsigned long)_tv, (unsigned long)_tz); |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | #ifdef __powerpc64__ | ||
| 107 | |||
| 106 | static __always_inline | 108 | static __always_inline |
| 107 | int clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) | 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 | return do_syscall_2(__NR_clock_getres, _clkid, (unsigned long)_ts); | 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 | #define BUILD_VDSO32 1 | 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 | static __always_inline | 136 | static __always_inline |
| 123 | int clock_gettime32_fallback(clockid_t _clkid, struct old_timespec32 *_ts) | 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 | MachineCheck: | 260 | MachineCheck: |
| 261 | EXCEPTION_PROLOG_0 | 261 | EXCEPTION_PROLOG_0 |
| 262 | #ifdef CONFIG_PPC_CHRP | 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 | mfspr r11, SPRN_SPRG_THREAD | 271 | mfspr r11, SPRN_SPRG_THREAD |
| 264 | lwz r11, RTAS_SP(r11) | 272 | lwz r11, RTAS_SP(r11) |
| 265 | cmpwi cr1, r11, 0 | 273 | cmpwi cr1, r11, 0 |
| 266 | bne cr1, 7f | 274 | bne cr1, 7f |
| 275 | #endif | ||
| 267 | #endif /* CONFIG_PPC_CHRP */ | 276 | #endif /* CONFIG_PPC_CHRP */ |
| 268 | EXCEPTION_PROLOG_1 for_rtas=1 | 277 | EXCEPTION_PROLOG_1 for_rtas=1 |
| 269 | 7: EXCEPTION_PROLOG_2 | 278 | 7: EXCEPTION_PROLOG_2 |
| @@ -85,7 +85,7 @@ SECTIONS · 84 unmodified lines | |||
| 85 | ALIGN_FUNCTION(); | 85 | ALIGN_FUNCTION(); |
| 86 | #endif | 86 | #endif |
| 87 | /* careful! __ftr_alt_* sections need to be close to .text */ | 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 | #ifdef CONFIG_PPC64 | 89 | #ifdef CONFIG_PPC64 |
| 90 | *(.tramp.ftrace.text); | 90 | *(.tramp.ftrace.text); |
| 91 | #endif | 91 | #endif |
| @@ -187,6 +187,12 @@ SECTIONS · 95 unmodified lines | |||
| 187 | .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { | 187 | .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { |
| 188 | _sinittext = .; | 188 | _sinittext = .; |
| 189 | INIT_TEXT | 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 | _einittext = .; | 196 | _einittext = .; |
| 191 | #ifdef CONFIG_PPC64 | 197 | #ifdef CONFIG_PPC64 |
| 192 | *(.tramp.ftrace.init); | 198 | *(.tramp.ftrace.init); |
| @@ -200,6 +206,8 @@ SECTIONS · 7 unmodified lines | |||
| 200 | EXIT_TEXT | 206 | EXIT_TEXT |
| 201 | } | 207 | } |
| 202 | 208 | ||
| 209 | . = ALIGN(PAGE_SIZE); | ||
| 210 | |||
| 203 | INIT_DATA_SECTION(16) | 211 | INIT_DATA_SECTION(16) |
| 204 | 212 | ||
| 205 | . = ALIGN(8); | 213 | . = ALIGN(8); |
| @@ -137,7 +137,7 @@ config PA_BITS · 136 unmodified lines | |||
| 137 | 137 | ||
| 138 | config PAGE_OFFSET | 138 | config PAGE_OFFSET |
| 139 | hex | 139 | hex |
| 140 | default 0xC0000000 if 32BIT && MAXPHYSMEM_2GB | 140 | default 0xC0000000 if 32BIT && MAXPHYSMEM_1GB |
| 141 | default 0x80000000 if 64BIT && !MMU | 141 | default 0x80000000 if 64BIT && !MMU |
| 142 | default 0xffffffff80000000 if 64BIT && MAXPHYSMEM_2GB | 142 | default 0xffffffff80000000 if 64BIT && MAXPHYSMEM_2GB |
| 143 | default 0xffffffe000000000 if 64BIT && MAXPHYSMEM_128GB | 143 | default 0xffffffe000000000 if 64BIT && MAXPHYSMEM_128GB |
| @@ -247,10 +247,12 @@ config MODULE_SECTIONS · 103 unmodified lines | |||
| 247 | 247 | ||
| 248 | choice | 248 | choice |
| 249 | prompt "Maximum Physical Memory" | 249 | prompt "Maximum Physical Memory" |
| 250 | default MAXPHYSMEM_2GB if 32BIT | 250 | default MAXPHYSMEM_1GB if 32BIT |
| 251 | default MAXPHYSMEM_2GB if 64BIT && CMODEL_MEDLOW | 251 | default MAXPHYSMEM_2GB if 64BIT && CMODEL_MEDLOW |
| 252 | default MAXPHYSMEM_128GB if 64BIT && CMODEL_MEDANY | 252 | default MAXPHYSMEM_128GB if 64BIT && CMODEL_MEDANY |
| 253 | 253 | ||
| 254 | config MAXPHYSMEM_1GB | ||
| 255 | bool "1GiB" | ||
| 254 | config MAXPHYSMEM_2GB | 256 | config MAXPHYSMEM_2GB |
| 255 | bool "2GiB" | 257 | bool "2GiB" |
| 256 | config MAXPHYSMEM_128GB | 258 | config MAXPHYSMEM_128GB |
| @@ -88,7 +88,9 @@ · 87 unmodified lines | |||
| 88 | phy-mode = "gmii"; | 88 | phy-mode = "gmii"; |
| 89 | phy-handle = <&phy0>; | 89 | phy-handle = <&phy0>; |
| 90 | phy0: ethernet-phy@0 { | 90 | phy0: ethernet-phy@0 { |
| 91 | compatible = "ethernet-phy-id0007.0771"; | ||
| 91 | reg = <0>; | 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 | CONFIG_HW_RANDOM_VIRTIO=y | 64 | CONFIG_HW_RANDOM_VIRTIO=y |
| 65 | CONFIG_SPI=y | 65 | CONFIG_SPI=y |
| 66 | CONFIG_SPI_SIFIVE=y | 66 | CONFIG_SPI_SIFIVE=y |
| 67 | CONFIG_GPIOLIB=y | ||
| 68 | CONFIG_GPIO_SIFIVE=y | ||
| 67 | # CONFIG_PTP_1588_CLOCK is not set | 69 | # CONFIG_PTP_1588_CLOCK is not set |
| 68 | CONFIG_POWER_RESET=y | 70 | CONFIG_POWER_RESET=y |
| 69 | CONFIG_DRM=y | 71 | CONFIG_DRM=y |
| @@ -3,6 +3,5 @@ generic-y += early_ioremap.h · 2 unmodified lines | |||
| 3 | generic-y += extable.h | 3 | generic-y += extable.h |
| 4 | generic-y += flat.h | 4 | generic-y += flat.h |
| 5 | generic-y += kvm_para.h | 5 | generic-y += kvm_para.h |
| 6 | generic-y += local64.h | ||
| 7 | generic-y += user.h | 6 | generic-y += user.h |
| 8 | generic-y += vmlinux.lds.h | 7 | generic-y += vmlinux.lds.h |
| @@ -99,7 +99,6 @@ · 98 unmodified lines | |||
| 99 | | _PAGE_DIRTY) | 99 | | _PAGE_DIRTY) |
| 100 | 100 | ||
| 101 | #define PAGE_KERNEL __pgprot(_PAGE_KERNEL) | 101 | #define PAGE_KERNEL __pgprot(_PAGE_KERNEL) |
| 102 | #define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL | _PAGE_EXEC) | ||
| 103 | #define PAGE_KERNEL_READ __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE) | 102 | #define PAGE_KERNEL_READ __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE) |
| 104 | #define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL | _PAGE_EXEC) | 103 | #define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL | _PAGE_EXEC) |
| 105 | #define PAGE_KERNEL_READ_EXEC __pgprot((_PAGE_KERNEL & ~_PAGE_WRITE) \ | 104 | #define PAGE_KERNEL_READ_EXEC __pgprot((_PAGE_KERNEL & ~_PAGE_WRITE) \ |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | |||
| 10 | 10 | ||
| 11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
| 12 | 12 | ||
| 13 | #ifndef GENERIC_TIME_VSYSCALL | 13 | #ifndef CONFIG_GENERIC_TIME_VSYSCALL |
| 14 | struct vdso_data { | 14 | struct vdso_data { |
| 15 | }; | 15 | }; |
| 16 | #endif | 16 | #endif |
| @@ -26,7 +26,16 @@ cache_get_priv_group(struct cacheinfo *this_leaf) · 25 unmodified lines | |||
| 26 | 26 | ||
| 27 | static struct cacheinfo *get_cacheinfo(u32 level, enum cache_type type) | 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 | struct cacheinfo *this_leaf; | 39 | struct cacheinfo *this_leaf; |
| 31 | int index; | 40 | int index; |
| 32 | 41 | ||
| @@ -124,15 +124,15 @@ skip_context_tracking: · 123 unmodified lines | |||
| 124 | REG_L a1, (a1) | 124 | REG_L a1, (a1) |
| 125 | jr a1 | 125 | jr a1 |
| 126 | 1: | 126 | 1: |
| 127 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
| 128 | call trace_hardirqs_on | ||
| 129 | #endif | ||
| 130 | /* | 127 | /* |
| 131 | * Exceptions run with interrupts enabled or disabled depending on the | 128 | * Exceptions run with interrupts enabled or disabled depending on the |
| 132 | * state of SR_PIE in m/sstatus. | 129 | * state of SR_PIE in m/sstatus. |
| 133 | */ | 130 | */ |
| 134 | andi t0, s1, SR_PIE | 131 | andi t0, s1, SR_PIE |
| 135 | beqz t0, 1f | 132 | beqz t0, 1f |
| 133 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
| 134 | call trace_hardirqs_on | ||
| 135 | #endif | ||
| 136 | csrs CSR_STATUS, SR_IE | 136 | csrs CSR_STATUS, SR_IE |
| 137 | 137 | ||
| 138 | 1: | 138 | 1: |
| @@ -155,6 +155,15 @@ skip_context_tracking: · 16 unmodified lines | |||
| 155 | tail do_trap_unknown | 155 | tail do_trap_unknown |
| 156 | 156 | ||
| 157 | handle_syscall: | 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 | #if defined(CONFIG_TRACE_IRQFLAGS) || defined(CONFIG_CONTEXT_TRACKING) | 167 | #if defined(CONFIG_TRACE_IRQFLAGS) || defined(CONFIG_CONTEXT_TRACKING) |
| 159 | /* Recover a0 - a7 for system calls */ | 168 | /* Recover a0 - a7 for system calls */ |
| 160 | REG_L a0, PT_A0(sp) | 169 | REG_L a0, PT_A0(sp) |
| @@ -186,14 +195,7 @@ check_syscall_nr: · 25 unmodified lines | |||
| 186 | * Syscall number held in a7. | 195 | * Syscall number held in a7. |
| 187 | * If syscall number is above allowed value, redirect to ni_syscall. | 196 | * If syscall number is above allowed value, redirect to ni_syscall. |
| 188 | */ | 197 | */ |
| 189 | bge a7, t0, 1f | 198 | bgeu 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 | ||
| 197 | /* Call syscall */ | 199 | /* Call syscall */ |
| 198 | la s0, sys_call_table | 200 | la s0, sys_call_table |
| 199 | slli t0, a7, RISCV_LGPTR | 201 | slli t0, a7, RISCV_LGPTR |
| @@ -127,7 +127,9 @@ static void __init init_resources(void) · 126 unmodified lines | |||
| 127 | { | 127 | { |
| 128 | struct memblock_region *region = NULL; | 128 | struct memblock_region *region = NULL; |
| 129 | struct resource *res = NULL; | 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 | code_res.start = __pa_symbol(_text); | 134 | code_res.start = __pa_symbol(_text); |
| 133 | code_res.end = __pa_symbol(_etext) - 1; | 135 | code_res.end = __pa_symbol(_etext) - 1; |
| @@ -145,16 +147,17 @@ static void __init init_resources(void) · 11 unmodified lines | |||
| 145 | bss_res.end = __pa_symbol(__bss_stop) - 1; | 147 | bss_res.end = __pa_symbol(__bss_stop) - 1; |
| 146 | bss_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; | 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 | * Start by adding the reserved regions, if they overlap | 155 | * Start by adding the reserved regions, if they overlap |
| 150 | * with /memory regions, insert_resource later on will take | 156 | * with /memory regions, insert_resource later on will take |
| 151 | * care of it. | 157 | * care of it. |
| 152 | */ | 158 | */ |
| 153 | for_each_reserved_mem_region(region) { | 159 | for_each_reserved_mem_region(region) { |
| 154 | res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES); | 160 | res = &mem_res[i++]; |
| 155 | if (!res) | ||
| 156 | panic("%s: Failed to allocate %zu bytes\n", __func__, | ||
| 157 | sizeof(struct resource)); | ||
| 158 | 161 | ||
| 159 | res->name = "Reserved"; | 162 | res->name = "Reserved"; |
| 160 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; | 163 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; |
| @@ -171,8 +174,10 @@ static void __init init_resources(void) · 10 unmodified lines | |||
| 171 | * Ignore any other reserved regions within | 174 | * Ignore any other reserved regions within |
| 172 | * system memory. | 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 | continue; | 179 | continue; |
| 180 | } | ||
| 176 | 181 | ||
| 177 | ret = add_resource(&iomem_resource, res); | 182 | ret = add_resource(&iomem_resource, res); |
| 178 | if (ret < 0) | 183 | if (ret < 0) |
| @@ -181,10 +186,7 @@ static void __init init_resources(void) · 2 unmodified lines | |||
| 181 | 186 | ||
| 182 | /* Add /memory regions to the resource tree */ | 187 | /* Add /memory regions to the resource tree */ |
| 183 | for_each_mem_region(region) { | 188 | for_each_mem_region(region) { |
| 184 | res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES); | 189 | res = &mem_res[i++]; |
| 185 | if (!res) | ||
| 186 | panic("%s: Failed to allocate %zu bytes\n", __func__, | ||
| 187 | sizeof(struct resource)); | ||
| 188 | 190 | ||
| 189 | if (unlikely(memblock_is_nomap(region))) { | 191 | if (unlikely(memblock_is_nomap(region))) { |
| 190 | res->name = "Reserved"; | 192 | res->name = "Reserved"; |
| @@ -205,9 +207,9 @@ static void __init init_resources(void) · 14 unmodified lines | |||
| 205 | return; | 207 | return; |
| 206 | 208 | ||
| 207 | error: | 209 | error: |
| 208 | memblock_free((phys_addr_t) res, sizeof(struct resource)); | ||
| 209 | /* Better an empty resource tree than an inconsistent one */ | 210 | /* Better an empty resource tree than an inconsistent one */ |
| 210 | release_child_resources(&iomem_resource); | 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 | #include <asm/stacktrace.h> | 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 | #ifdef CONFIG_FRAME_POINTER | 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 | sp = user_stack_pointer(regs); | 28 | sp = user_stack_pointer(regs); |
| 29 | pc = instruction_pointer(regs); | 29 | pc = instruction_pointer(regs); |
| 30 | } else if (task == NULL || task == current) { | 30 | } else if (task == NULL || task == current) { |
| 31 | const register unsigned long current_sp = sp_in_global; | ||
| 32 | fp = (unsigned long)__builtin_frame_address(0); | 31 | fp = (unsigned long)__builtin_frame_address(0); |
| 33 | sp = current_sp; | 32 | sp = sp_in_global; |
| 34 | pc = (unsigned long)walk_stackframe; | 33 | pc = (unsigned long)walk_stackframe; |
| 35 | } else { | 34 | } else { |
| 36 | /* task blocked in __switch_to */ | 35 | /* task blocked in __switch_to */ |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | * Copyright (C) 2017 SiFive | 4 | * Copyright (C) 2017 SiFive |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <linux/of_clk.h> | ||
| 7 | #include <linux/clocksource.h> | 8 | #include <linux/clocksource.h> |
| 8 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
| 9 | #include <asm/sbi.h> | 10 | #include <asm/sbi.h> |
| @@ -24,6 +25,8 @@ void __init time_init(void) · 14 unmodified lines | |||
| 24 | riscv_timebase = prop; | 25 | riscv_timebase = prop; |
| 25 | 26 | ||
| 26 | lpj_fine = riscv_timebase / HZ; | 27 | lpj_fine = riscv_timebase / HZ; |
| 28 | |||
| 29 | of_clk_init(NULL); | ||
| 27 | timer_probe(); | 30 | timer_probe(); |
| 28 | } | 31 | } |
| 29 | 32 | ||
| @@ -12,7 +12,7 @@ · 11 unmodified lines | |||
| 12 | #include <linux/binfmts.h> | 12 | #include <linux/binfmts.h> |
| 13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
| 14 | #include <asm/page.h> | 14 | #include <asm/page.h> |
| 15 | #ifdef GENERIC_TIME_VSYSCALL | 15 | #ifdef CONFIG_GENERIC_TIME_VSYSCALL |
| 16 | #include <vdso/datapage.h> | 16 | #include <vdso/datapage.h> |
| 17 | #else | 17 | #else |
| 18 | #include <asm/vdso.h> | 18 | #include <asm/vdso.h> |
| @@ -157,9 +157,10 @@ disable: · 156 unmodified lines | |||
| 157 | void __init setup_bootmem(void) | 157 | void __init setup_bootmem(void) |
| 158 | { | 158 | { |
| 159 | phys_addr_t mem_start = 0; | 159 | phys_addr_t mem_start = 0; |
| 160 | phys_addr_t start, end = 0; | 160 | phys_addr_t start, dram_end, end = 0; |
| 161 | phys_addr_t vmlinux_end = __pa_symbol(&_end); | 161 | phys_addr_t vmlinux_end = __pa_symbol(&_end); |
| 162 | phys_addr_t vmlinux_start = __pa_symbol(&_start); | 162 | phys_addr_t vmlinux_start = __pa_symbol(&_start); |
| 163 | phys_addr_t max_mapped_addr = __pa(~(ulong)0); | ||
| 163 | u64 i; | 164 | u64 i; |
| 164 | 165 | ||
| 165 | /* Find the memory region containing the kernel */ | 166 | /* Find the memory region containing the kernel */ |
| @@ -181,7 +182,18 @@ void __init setup_bootmem(void) · 15 unmodified lines | |||
| 181 | /* Reserve from the start of the kernel to the end of the kernel */ | 182 | /* Reserve from the start of the kernel to the end of the kernel */ |
| 182 | memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); | 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 | max_low_pfn = max_pfn; | 197 | max_low_pfn = max_pfn; |
| 186 | dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn)); | 198 | dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn)); |
| 187 | set_max_mapnr(max_low_pfn); | 199 | set_max_mapnr(max_low_pfn); |
| @@ -93,8 +93,8 @@ void __init kasan_init(void) · 92 unmodified lines | |||
| 93 | VMALLOC_END)); | 93 | VMALLOC_END)); |
| 94 | 94 | ||
| 95 | for_each_mem_range(i, &_start, &_end) { | 95 | for_each_mem_range(i, &_start, &_end) { |
| 96 | void *start = (void *)_start; | 96 | void *start = (void *)__va(_start); |
| 97 | void *end = (void *)_end; | 97 | void *end = (void *)__va(_end); |
| 98 | 98 | ||
| 99 | if (start >= end) | 99 | if (start >= end) |
| 100 | break; | 100 | break; |
| @@ -54,17 +54,23 @@ config KASAN_SHADOW_OFFSET · 53 unmodified lines | |||
| 54 | 54 | ||
| 55 | config S390 | 55 | config S390 |
| 56 | def_bool y | 56 | def_bool y |
| 57 | # | ||
| 58 | # Note: keep this list sorted alphabetically | ||
| 59 | # | ||
| 60 | imply IMA_SECURE_AND_OR_TRUSTED_BOOT | ||
| 57 | select ARCH_BINFMT_ELF_STATE | 61 | select ARCH_BINFMT_ELF_STATE |
| 58 | select ARCH_HAS_DEBUG_VM_PGTABLE | 62 | select ARCH_HAS_DEBUG_VM_PGTABLE |
| 59 | select ARCH_HAS_DEBUG_WX | 63 | select ARCH_HAS_DEBUG_WX |
| 60 | select ARCH_HAS_DEVMEM_IS_ALLOWED | 64 | select ARCH_HAS_DEVMEM_IS_ALLOWED |
| 61 | select ARCH_HAS_ELF_RANDOMIZE | 65 | select ARCH_HAS_ELF_RANDOMIZE |
| 66 | select ARCH_HAS_FORCE_DMA_UNENCRYPTED | ||
| 62 | select ARCH_HAS_FORTIFY_SOURCE | 67 | select ARCH_HAS_FORTIFY_SOURCE |
| 63 | select ARCH_HAS_GCOV_PROFILE_ALL | 68 | select ARCH_HAS_GCOV_PROFILE_ALL |
| 64 | select ARCH_HAS_GIGANTIC_PAGE | 69 | select ARCH_HAS_GIGANTIC_PAGE |
| 65 | select ARCH_HAS_KCOV | 70 | select ARCH_HAS_KCOV |
| 66 | select ARCH_HAS_MEM_ENCRYPT | 71 | select ARCH_HAS_MEM_ENCRYPT |
| 67 | select ARCH_HAS_PTE_SPECIAL | 72 | select ARCH_HAS_PTE_SPECIAL |
| 73 | select ARCH_HAS_SCALED_CPUTIME | ||
| 68 | select ARCH_HAS_SET_MEMORY | 74 | select ARCH_HAS_SET_MEMORY |
| 69 | select ARCH_HAS_STRICT_KERNEL_RWX | 75 | select ARCH_HAS_STRICT_KERNEL_RWX |
| 70 | select ARCH_HAS_STRICT_MODULE_RWX | 76 | select ARCH_HAS_STRICT_MODULE_RWX |
| @@ -111,8 +117,10 @@ config S390 · 40 unmodified lines | |||
| 111 | select ARCH_WANT_IPC_PARSE_VERSION | 117 | select ARCH_WANT_IPC_PARSE_VERSION |
| 112 | select BUILDTIME_TABLE_SORT | 118 | select BUILDTIME_TABLE_SORT |
| 113 | select CLONE_BACKWARDS2 | 119 | select CLONE_BACKWARDS2 |
| 120 | select CPU_NO_EFFICIENT_FFS if !HAVE_MARCH_Z9_109_FEATURES | ||
| 114 | select DMA_OPS if PCI | 121 | select DMA_OPS if PCI |
| 115 | select DYNAMIC_FTRACE if FUNCTION_TRACER | 122 | select DYNAMIC_FTRACE if FUNCTION_TRACER |
| 123 | select GENERIC_ALLOCATOR | ||
| 116 | select GENERIC_CPU_AUTOPROBE | 124 | select GENERIC_CPU_AUTOPROBE |
| 117 | select GENERIC_CPU_VULNERABILITIES | 125 | select GENERIC_CPU_VULNERABILITIES |
| 118 | select GENERIC_FIND_FIRST_BIT | 126 | select GENERIC_FIND_FIRST_BIT |
| @@ -126,22 +134,21 @@ config S390 · 7 unmodified lines | |||
| 126 | select HAVE_ARCH_JUMP_LABEL_RELATIVE | 134 | select HAVE_ARCH_JUMP_LABEL_RELATIVE |
| 127 | select HAVE_ARCH_KASAN | 135 | select HAVE_ARCH_KASAN |
| 128 | select HAVE_ARCH_KASAN_VMALLOC | 136 | select HAVE_ARCH_KASAN_VMALLOC |
| 129 | select CPU_NO_EFFICIENT_FFS if !HAVE_MARCH_Z9_109_FEATURES | ||
| 130 | select HAVE_ARCH_SECCOMP_FILTER | 137 | select HAVE_ARCH_SECCOMP_FILTER |
| 131 | select HAVE_ARCH_SOFT_DIRTY | 138 | select HAVE_ARCH_SOFT_DIRTY |
| 132 | select HAVE_ARCH_TRACEHOOK | 139 | select HAVE_ARCH_TRACEHOOK |
| 133 | select HAVE_ARCH_TRANSPARENT_HUGEPAGE | 140 | select HAVE_ARCH_TRANSPARENT_HUGEPAGE |
| 134 | select HAVE_ARCH_VMAP_STACK | 141 | select HAVE_ARCH_VMAP_STACK |
| 135 | select HAVE_ASM_MODVERSIONS | 142 | select HAVE_ASM_MODVERSIONS |
| 136 | select HAVE_EBPF_JIT if PACK_STACK && HAVE_MARCH_Z196_FEATURES | ||
| 137 | select HAVE_CMPXCHG_DOUBLE | 143 | select HAVE_CMPXCHG_DOUBLE |
| 138 | select HAVE_CMPXCHG_LOCAL | 144 | select HAVE_CMPXCHG_LOCAL |
| 139 | select HAVE_DEBUG_KMEMLEAK | 145 | select HAVE_DEBUG_KMEMLEAK |
| 140 | select HAVE_DMA_CONTIGUOUS | 146 | select HAVE_DMA_CONTIGUOUS |
| 141 | select HAVE_DYNAMIC_FTRACE | 147 | select HAVE_DYNAMIC_FTRACE |
| 142 | select HAVE_DYNAMIC_FTRACE_WITH_REGS | 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 | select HAVE_EFFICIENT_UNALIGNED_ACCESS | 150 | select HAVE_EFFICIENT_UNALIGNED_ACCESS |
| 151 | select HAVE_FAST_GUP | ||
| 145 | select HAVE_FENTRY | 152 | select HAVE_FENTRY |
| 146 | select HAVE_FTRACE_MCOUNT_RECORD | 153 | select HAVE_FTRACE_MCOUNT_RECORD |
| 147 | select HAVE_FUNCTION_ERROR_INJECTION | 154 | select HAVE_FUNCTION_ERROR_INJECTION |
| @@ -163,16 +170,15 @@ config S390 · 15 unmodified lines | |||
| 163 | select HAVE_KRETPROBES | 170 | select HAVE_KRETPROBES |
| 164 | select HAVE_KVM | 171 | select HAVE_KVM |
| 165 | select HAVE_LIVEPATCH | 172 | select HAVE_LIVEPATCH |
| 166 | select HAVE_PERF_REGS | ||
| 167 | select HAVE_PERF_USER_STACK_DUMP | ||
| 168 | select HAVE_MEMBLOCK_PHYS_MAP | 173 | select HAVE_MEMBLOCK_PHYS_MAP |
| 169 | select MMU_GATHER_NO_GATHER | ||
| 170 | select HAVE_MOD_ARCH_SPECIFIC | 174 | select HAVE_MOD_ARCH_SPECIFIC |
| 175 | select HAVE_NMI | ||
| 171 | select HAVE_NOP_MCOUNT | 176 | select HAVE_NOP_MCOUNT |
| 172 | select HAVE_OPROFILE | 177 | select HAVE_OPROFILE |
| 173 | select HAVE_PCI | 178 | select HAVE_PCI |
| 174 | select HAVE_PERF_EVENTS | 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 | select HAVE_REGS_AND_STACK_ACCESS_API | 182 | select HAVE_REGS_AND_STACK_ACCESS_API |
| 177 | select HAVE_RELIABLE_STACKTRACE | 183 | select HAVE_RELIABLE_STACKTRACE |
| 178 | select HAVE_RSEQ | 184 | select HAVE_RSEQ |
| @@ -181,6 +187,8 @@ config S390 · 2 unmodified lines | |||
| 181 | select HAVE_VIRT_CPU_ACCOUNTING_IDLE | 187 | select HAVE_VIRT_CPU_ACCOUNTING_IDLE |
| 182 | select IOMMU_HELPER if PCI | 188 | select IOMMU_HELPER if PCI |
| 183 | select IOMMU_SUPPORT if PCI | 189 | select IOMMU_SUPPORT if PCI |
| 190 | select MMU_GATHER_NO_GATHER | ||
| 191 | select MMU_GATHER_RCU_TABLE_FREE | ||
| 184 | select MODULES_USE_ELF_RELA | 192 | select MODULES_USE_ELF_RELA |
| 185 | select NEED_DMA_MAP_STATE if PCI | 193 | select NEED_DMA_MAP_STATE if PCI |
| 186 | select NEED_SG_DMA_LENGTH if PCI | 194 | select NEED_SG_DMA_LENGTH if PCI |
| @@ -190,17 +198,12 @@ config S390 · 3 unmodified lines | |||
| 190 | select PCI_MSI if PCI | 198 | select PCI_MSI if PCI |
| 191 | select PCI_MSI_ARCH_FALLBACKS if PCI_MSI | 199 | select PCI_MSI_ARCH_FALLBACKS if PCI_MSI |
| 192 | select SPARSE_IRQ | 200 | select SPARSE_IRQ |
| 201 | select SWIOTLB | ||
| 193 | select SYSCTL_EXCEPTION_TRACE | 202 | select SYSCTL_EXCEPTION_TRACE |
| 194 | select THREAD_INFO_IN_TASK | 203 | select THREAD_INFO_IN_TASK |
| 195 | select TTY | 204 | select TTY |
| 196 | select VIRT_CPU_ACCOUNTING | 205 | select VIRT_CPU_ACCOUNTING |
| 197 | select ARCH_HAS_SCALED_CPUTIME | 206 | # Note: keep the above list sorted alphabetically |
| 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 | |||
| 204 | 207 | ||
| 205 | config SCHED_OMIT_FRAME_POINTER | 208 | config SCHED_OMIT_FRAME_POINTER |
| 206 | def_bool y | 209 | def_bool y |
| @@ -61,7 +61,9 @@ CONFIG_OPROFILE=m · 60 unmodified lines | |||
| 61 | CONFIG_KPROBES=y | 61 | CONFIG_KPROBES=y |
| 62 | CONFIG_JUMP_LABEL=y | 62 | CONFIG_JUMP_LABEL=y |
| 63 | CONFIG_STATIC_KEYS_SELFTEST=y | 63 | CONFIG_STATIC_KEYS_SELFTEST=y |
| 64 | CONFIG_SECCOMP_CACHE_DEBUG=y | ||
| 64 | CONFIG_LOCK_EVENT_COUNTS=y | 65 | CONFIG_LOCK_EVENT_COUNTS=y |
| 66 | # CONFIG_GCC_PLUGINS is not set | ||
| 65 | CONFIG_MODULES=y | 67 | CONFIG_MODULES=y |
| 66 | CONFIG_MODULE_FORCE_LOAD=y | 68 | CONFIG_MODULE_FORCE_LOAD=y |
| 67 | CONFIG_MODULE_UNLOAD=y | 69 | CONFIG_MODULE_UNLOAD=y |
| @@ -410,12 +412,12 @@ CONFIG_SCSI_ENCLOSURE=m · 342 unmodified lines | |||
| 410 | CONFIG_SCSI_CONSTANTS=y | 412 | CONFIG_SCSI_CONSTANTS=y |
| 411 | CONFIG_SCSI_LOGGING=y | 413 | CONFIG_SCSI_LOGGING=y |
| 412 | CONFIG_SCSI_SPI_ATTRS=m | 414 | CONFIG_SCSI_SPI_ATTRS=m |
| 413 | CONFIG_SCSI_FC_ATTRS=y | 415 | CONFIG_SCSI_FC_ATTRS=m |
| 414 | CONFIG_SCSI_SAS_LIBSAS=m | 416 | CONFIG_SCSI_SAS_LIBSAS=m |
| 415 | CONFIG_SCSI_SRP_ATTRS=m | 417 | CONFIG_SCSI_SRP_ATTRS=m |
| 416 | CONFIG_ISCSI_TCP=m | 418 | CONFIG_ISCSI_TCP=m |
| 417 | CONFIG_SCSI_DEBUG=m | 419 | CONFIG_SCSI_DEBUG=m |
| 418 | CONFIG_ZFCP=y | 420 | CONFIG_ZFCP=m |
| 419 | CONFIG_SCSI_VIRTIO=m | 421 | CONFIG_SCSI_VIRTIO=m |
| 420 | CONFIG_SCSI_DH=y | 422 | CONFIG_SCSI_DH=y |
| 421 | CONFIG_SCSI_DH_RDAC=m | 423 | CONFIG_SCSI_DH_RDAC=m |
| @@ -444,6 +446,7 @@ CONFIG_DM_MULTIPATH=m · 22 unmodified lines | |||
| 444 | CONFIG_DM_MULTIPATH_QL=m | 446 | CONFIG_DM_MULTIPATH_QL=m |
| 445 | CONFIG_DM_MULTIPATH_ST=m | 447 | CONFIG_DM_MULTIPATH_ST=m |
| 446 | CONFIG_DM_MULTIPATH_HST=m | 448 | CONFIG_DM_MULTIPATH_HST=m |
| 449 | CONFIG_DM_MULTIPATH_IOA=m | ||
| 447 | CONFIG_DM_DELAY=m | 450 | CONFIG_DM_DELAY=m |
| 448 | CONFIG_DM_UEVENT=y | 451 | CONFIG_DM_UEVENT=y |
| 449 | CONFIG_DM_FLAKEY=m | 452 | CONFIG_DM_FLAKEY=m |
| @@ -542,7 +545,6 @@ CONFIG_INPUT_EVDEV=y · 92 unmodified lines | |||
| 542 | # CONFIG_INPUT_MOUSE is not set | 545 | # CONFIG_INPUT_MOUSE is not set |
| 543 | # CONFIG_SERIO is not set | 546 | # CONFIG_SERIO is not set |
| 544 | CONFIG_LEGACY_PTY_COUNT=0 | 547 | CONFIG_LEGACY_PTY_COUNT=0 |
| 545 | CONFIG_NULL_TTY=m | ||
| 546 | CONFIG_VIRTIO_CONSOLE=y | 548 | CONFIG_VIRTIO_CONSOLE=y |
| 547 | CONFIG_HW_RANDOM_VIRTIO=m | 549 | CONFIG_HW_RANDOM_VIRTIO=m |
| 548 | CONFIG_RAW_DRIVER=m | 550 | CONFIG_RAW_DRIVER=m |
| @@ -574,6 +576,7 @@ CONFIG_VIRTIO_BALLOON=m · 25 unmodified lines | |||
| 574 | CONFIG_VIRTIO_INPUT=y | 576 | CONFIG_VIRTIO_INPUT=y |
| 575 | CONFIG_VHOST_NET=m | 577 | CONFIG_VHOST_NET=m |
| 576 | CONFIG_VHOST_VSOCK=m | 578 | CONFIG_VHOST_VSOCK=m |
| 579 | # CONFIG_SURFACE_PLATFORMS is not set | ||
| 577 | CONFIG_S390_CCW_IOMMU=y | 580 | CONFIG_S390_CCW_IOMMU=y |
| 578 | CONFIG_S390_AP_IOMMU=y | 581 | CONFIG_S390_AP_IOMMU=y |
| 579 | CONFIG_EXT4_FS=y | 582 | CONFIG_EXT4_FS=y |
| @@ -655,6 +658,7 @@ CONFIG_CIFS_XATTR=y · 75 unmodified lines | |||
| 655 | CONFIG_CIFS_POSIX=y | 658 | CONFIG_CIFS_POSIX=y |
| 656 | # CONFIG_CIFS_DEBUG is not set | 659 | # CONFIG_CIFS_DEBUG is not set |
| 657 | CONFIG_CIFS_DFS_UPCALL=y | 660 | CONFIG_CIFS_DFS_UPCALL=y |
| 661 | CONFIG_CIFS_SWN_UPCALL=y | ||
| 658 | CONFIG_NLS_DEFAULT="utf8" | 662 | CONFIG_NLS_DEFAULT="utf8" |
| 659 | CONFIG_NLS_CODEPAGE_437=m | 663 | CONFIG_NLS_CODEPAGE_437=m |
| 660 | CONFIG_NLS_CODEPAGE_850=m | 664 | CONFIG_NLS_CODEPAGE_850=m |
| @@ -826,6 +830,8 @@ CONFIG_FTRACE_SYSCALLS=y · 165 unmodified lines | |||
| 826 | CONFIG_BLK_DEV_IO_TRACE=y | 830 | CONFIG_BLK_DEV_IO_TRACE=y |
| 827 | CONFIG_BPF_KPROBE_OVERRIDE=y | 831 | CONFIG_BPF_KPROBE_OVERRIDE=y |
| 828 | CONFIG_HIST_TRIGGERS=y | 832 | CONFIG_HIST_TRIGGERS=y |
| 833 | CONFIG_FTRACE_STARTUP_TEST=y | ||
| 834 | # CONFIG_EVENT_TRACE_STARTUP_TEST is not set | ||
| 829 | CONFIG_DEBUG_USER_ASCE=y | 835 | CONFIG_DEBUG_USER_ASCE=y |
| 830 | CONFIG_NOTIFIER_ERROR_INJECTION=m | 836 | CONFIG_NOTIFIER_ERROR_INJECTION=m |
| 831 | CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m | 837 | CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m |
| @@ -58,6 +58,7 @@ CONFIG_S390_UNWIND_SELFTEST=m · 57 unmodified lines | |||
| 58 | CONFIG_OPROFILE=m | 58 | CONFIG_OPROFILE=m |
| 59 | CONFIG_KPROBES=y | 59 | CONFIG_KPROBES=y |
| 60 | CONFIG_JUMP_LABEL=y | 60 | CONFIG_JUMP_LABEL=y |
| 61 | # CONFIG_GCC_PLUGINS is not set | ||
| 61 | CONFIG_MODULES=y | 62 | CONFIG_MODULES=y |
| 62 | CONFIG_MODULE_FORCE_LOAD=y | 63 | CONFIG_MODULE_FORCE_LOAD=y |
| 63 | CONFIG_MODULE_UNLOAD=y | 64 | CONFIG_MODULE_UNLOAD=y |
| @@ -95,7 +96,6 @@ CONFIG_ZSMALLOC_STAT=y · 31 unmodified lines | |||
| 95 | CONFIG_DEFERRED_STRUCT_PAGE_INIT=y | 96 | CONFIG_DEFERRED_STRUCT_PAGE_INIT=y |
| 96 | CONFIG_IDLE_PAGE_TRACKING=y | 97 | CONFIG_IDLE_PAGE_TRACKING=y |
| 97 | CONFIG_PERCPU_STATS=y | 98 | CONFIG_PERCPU_STATS=y |
| 98 | CONFIG_GUP_TEST=y | ||
| 99 | CONFIG_NET=y | 99 | CONFIG_NET=y |
| 100 | CONFIG_PACKET=y | 100 | CONFIG_PACKET=y |
| 101 | CONFIG_PACKET_DIAG=m | 101 | CONFIG_PACKET_DIAG=m |
| @@ -403,12 +403,12 @@ CONFIG_SCSI_ENCLOSURE=m · 301 unmodified lines | |||
| 403 | CONFIG_SCSI_CONSTANTS=y | 403 | CONFIG_SCSI_CONSTANTS=y |
| 404 | CONFIG_SCSI_LOGGING=y | 404 | CONFIG_SCSI_LOGGING=y |
| 405 | CONFIG_SCSI_SPI_ATTRS=m | 405 | CONFIG_SCSI_SPI_ATTRS=m |
| 406 | CONFIG_SCSI_FC_ATTRS=y | 406 | CONFIG_SCSI_FC_ATTRS=m |
| 407 | CONFIG_SCSI_SAS_LIBSAS=m | 407 | CONFIG_SCSI_SAS_LIBSAS=m |
| 408 | CONFIG_SCSI_SRP_ATTRS=m | 408 | CONFIG_SCSI_SRP_ATTRS=m |
| 409 | CONFIG_ISCSI_TCP=m | 409 | CONFIG_ISCSI_TCP=m |
| 410 | CONFIG_SCSI_DEBUG=m | 410 | CONFIG_SCSI_DEBUG=m |
| 411 | CONFIG_ZFCP=y | 411 | CONFIG_ZFCP=m |
| 412 | CONFIG_SCSI_VIRTIO=m | 412 | CONFIG_SCSI_VIRTIO=m |
| 413 | CONFIG_SCSI_DH=y | 413 | CONFIG_SCSI_DH=y |
| 414 | CONFIG_SCSI_DH_RDAC=m | 414 | CONFIG_SCSI_DH_RDAC=m |
| @@ -437,6 +437,7 @@ CONFIG_DM_MULTIPATH=m · 22 unmodified lines | |||
| 437 | CONFIG_DM_MULTIPATH_QL=m | 437 | CONFIG_DM_MULTIPATH_QL=m |
| 438 | CONFIG_DM_MULTIPATH_ST=m | 438 | CONFIG_DM_MULTIPATH_ST=m |
| 439 | CONFIG_DM_MULTIPATH_HST=m | 439 | CONFIG_DM_MULTIPATH_HST=m |
| 440 | CONFIG_DM_MULTIPATH_IOA=m | ||
| 440 | CONFIG_DM_DELAY=m | 441 | CONFIG_DM_DELAY=m |
| 441 | CONFIG_DM_UEVENT=y | 442 | CONFIG_DM_UEVENT=y |
| 442 | CONFIG_DM_FLAKEY=m | 443 | CONFIG_DM_FLAKEY=m |
| @@ -536,7 +537,6 @@ CONFIG_INPUT_EVDEV=y · 93 unmodified lines | |||
| 536 | # CONFIG_INPUT_MOUSE is not set | 537 | # CONFIG_INPUT_MOUSE is not set |
| 537 | # CONFIG_SERIO is not set | 538 | # CONFIG_SERIO is not set |
| 538 | CONFIG_LEGACY_PTY_COUNT=0 | 539 | CONFIG_LEGACY_PTY_COUNT=0 |
| 539 | CONFIG_NULL_TTY=m | ||
| 540 | CONFIG_VIRTIO_CONSOLE=y | 540 | CONFIG_VIRTIO_CONSOLE=y |
| 541 | CONFIG_HW_RANDOM_VIRTIO=m | 541 | CONFIG_HW_RANDOM_VIRTIO=m |
| 542 | CONFIG_RAW_DRIVER=m | 542 | CONFIG_RAW_DRIVER=m |
| @@ -568,6 +568,7 @@ CONFIG_VIRTIO_BALLOON=m · 25 unmodified lines | |||
| 568 | CONFIG_VIRTIO_INPUT=y | 568 | CONFIG_VIRTIO_INPUT=y |
| 569 | CONFIG_VHOST_NET=m | 569 | CONFIG_VHOST_NET=m |
| 570 | CONFIG_VHOST_VSOCK=m | 570 | CONFIG_VHOST_VSOCK=m |
| 571 | # CONFIG_SURFACE_PLATFORMS is not set | ||
| 571 | CONFIG_S390_CCW_IOMMU=y | 572 | CONFIG_S390_CCW_IOMMU=y |
| 572 | CONFIG_S390_AP_IOMMU=y | 573 | CONFIG_S390_AP_IOMMU=y |
| 573 | CONFIG_EXT4_FS=y | 574 | CONFIG_EXT4_FS=y |
| @@ -645,6 +646,7 @@ CONFIG_CIFS_XATTR=y · 71 unmodified lines | |||
| 645 | CONFIG_CIFS_POSIX=y | 646 | CONFIG_CIFS_POSIX=y |
| 646 | # CONFIG_CIFS_DEBUG is not set | 647 | # CONFIG_CIFS_DEBUG is not set |
| 647 | CONFIG_CIFS_DFS_UPCALL=y | 648 | CONFIG_CIFS_DFS_UPCALL=y |
| 649 | CONFIG_CIFS_SWN_UPCALL=y | ||
| 648 | CONFIG_NLS_DEFAULT="utf8" | 650 | CONFIG_NLS_DEFAULT="utf8" |
| 649 | CONFIG_NLS_CODEPAGE_437=m | 651 | CONFIG_NLS_CODEPAGE_437=m |
| 650 | CONFIG_NLS_CODEPAGE_850=m | 652 | CONFIG_NLS_CODEPAGE_850=m |
| @@ -778,6 +780,7 @@ CONFIG_FTRACE_SYSCALLS=y · 127 unmodified lines | |||
| 778 | CONFIG_BLK_DEV_IO_TRACE=y | 780 | CONFIG_BLK_DEV_IO_TRACE=y |
| 779 | CONFIG_BPF_KPROBE_OVERRIDE=y | 781 | CONFIG_BPF_KPROBE_OVERRIDE=y |
| 780 | CONFIG_HIST_TRIGGERS=y | 782 | CONFIG_HIST_TRIGGERS=y |
| 783 | CONFIG_DEBUG_USER_ASCE=y | ||
| 781 | CONFIG_LKDTM=m | 784 | CONFIG_LKDTM=m |
| 782 | CONFIG_PERCPU_TEST=m | 785 | CONFIG_PERCPU_TEST=m |
| 783 | CONFIG_ATOMIC64_SELFTEST=y | 786 | CONFIG_ATOMIC64_SELFTEST=y |
| @@ -22,6 +22,7 @@ CONFIG_CRASH_DUMP=y · 21 unmodified lines | |||
| 22 | # CONFIG_VIRTUALIZATION is not set | 22 | # CONFIG_VIRTUALIZATION is not set |
| 23 | # CONFIG_S390_GUEST is not set | 23 | # CONFIG_S390_GUEST is not set |
| 24 | # CONFIG_SECCOMP is not set | 24 | # CONFIG_SECCOMP is not set |
| 25 | # CONFIG_GCC_PLUGINS is not set | ||
| 25 | CONFIG_PARTITION_ADVANCED=y | 26 | CONFIG_PARTITION_ADVANCED=y |
| 26 | CONFIG_IBM_PARTITION=y | 27 | CONFIG_IBM_PARTITION=y |
| 27 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | 28 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set |
| @@ -58,6 +59,7 @@ CONFIG_RAW_DRIVER=y · 30 unmodified lines | |||
| 58 | # CONFIG_HID is not set | 59 | # CONFIG_HID is not set |
| 59 | # CONFIG_VIRTIO_MENU is not set | 60 | # CONFIG_VIRTIO_MENU is not set |
| 60 | # CONFIG_VHOST_MENU is not set | 61 | # CONFIG_VHOST_MENU is not set |
| 62 | # CONFIG_SURFACE_PLATFORMS is not set | ||
| 61 | # CONFIG_IOMMU_SUPPORT is not set | 63 | # CONFIG_IOMMU_SUPPORT is not set |
| 62 | # CONFIG_DNOTIFY is not set | 64 | # CONFIG_DNOTIFY is not set |
| 63 | # CONFIG_INOTIFY_USER is not set | 65 | # CONFIG_INOTIFY_USER is not set |
| @@ -7,5 +7,4 @@ generated-y += unistd_nr.h · 6 unmodified lines | |||
| 7 | generic-y += asm-offsets.h | 7 | generic-y += asm-offsets.h |
| 8 | generic-y += export.h | 8 | generic-y += export.h |
| 9 | generic-y += kvm_types.h | 9 | generic-y += kvm_types.h |
| 10 | generic-y += local64.h | ||
| 11 | generic-y += mcs_spinlock.h | 10 | generic-y += mcs_spinlock.h |
| @@ -1,6 +1,5 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | generated-y += syscall_table.h | 2 | generated-y += syscall_table.h |
| 3 | generic-y += kvm_para.h | 3 | generic-y += kvm_para.h |
| 4 | generic-y += local64.h | ||
| 5 | generic-y += mcs_spinlock.h | 4 | generic-y += mcs_spinlock.h |
| 6 | generic-y += parport.h | 5 | generic-y += parport.h |
| @@ -6,5 +6,4 @@ generated-y += syscall_table_64.h · 5 unmodified lines | |||
| 6 | generated-y += syscall_table_c32.h | 6 | generated-y += syscall_table_c32.h |
| 7 | generic-y += export.h | 7 | generic-y += export.h |
| 8 | generic-y += kvm_para.h | 8 | generic-y += kvm_para.h |
| 9 | generic-y += local64.h | ||
| 10 | generic-y += mcs_spinlock.h | 9 | generic-y += mcs_spinlock.h |
| @@ -19,6 +19,7 @@ config X86_32 · 18 unmodified lines | |||
| 19 | select KMAP_LOCAL | 19 | select KMAP_LOCAL |
| 20 | select MODULES_USE_ELF_REL | 20 | select MODULES_USE_ELF_REL |
| 21 | select OLD_SIGACTION | 21 | select OLD_SIGACTION |
| 22 | select ARCH_SPLIT_ARG64 | ||
| 22 | 23 | ||
| 23 | config X86_64 | 24 | config X86_64 |
| 24 | def_bool y | 25 | def_bool y |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | |||
| 16 | #include <asm/hyperv-tlfs.h> | 16 | #include <asm/hyperv-tlfs.h> |
| 17 | #include <asm/mshyperv.h> | 17 | #include <asm/mshyperv.h> |
| 18 | #include <asm/idtentry.h> | 18 | #include <asm/idtentry.h> |
| 19 | #include <linux/kexec.h> | ||
| 19 | #include <linux/version.h> | 20 | #include <linux/version.h> |
| 20 | #include <linux/vmalloc.h> | 21 | #include <linux/vmalloc.h> |
| 21 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
| @@ -26,6 +27,8 @@ · 4 unmodified lines | |||
| 26 | #include <linux/syscore_ops.h> | 27 | #include <linux/syscore_ops.h> |
| 27 | #include <clocksource/hyperv_timer.h> | 28 | #include <clocksource/hyperv_timer.h> |
| 28 | 29 | ||
| 30 | int hyperv_init_cpuhp; | ||
| 31 | |||
| 29 | void *hv_hypercall_pg; | 32 | void *hv_hypercall_pg; |
| 30 | EXPORT_SYMBOL_GPL(hv_hypercall_pg); | 33 | EXPORT_SYMBOL_GPL(hv_hypercall_pg); |
| 31 | 34 | ||
| @@ -312,6 +315,25 @@ static struct syscore_ops hv_syscore_ops = { · 280 unmodified lines | |||
| 312 | .resume = hv_resume, | 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 | * This function is to be invoked early in the boot sequence after the | 338 | * This function is to be invoked early in the boot sequence after the |
| 317 | * hypervisor has been detected. | 339 | * hypervisor has been detected. |
| @@ -390,10 +412,14 @@ void __init hyperv_init(void) · 72 unmodified lines | |||
| 390 | wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); | 412 | wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); |
| 391 | 413 | ||
| 392 | /* | 414 | /* |
| 393 | * Ignore any errors in setting up stimer clockevents | 415 | * hyperv_init() is called before LAPIC is initialized: see |
| 394 | * as we can run with the LAPIC timer as a fallback. | 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 | hv_apic_init(); | 424 | hv_apic_init(); |
| 399 | 425 | ||
| @@ -401,6 +427,7 @@ void __init hyperv_init(void) · 1 unmodified line | |||
| 401 | 427 | ||
| 402 | register_syscore_ops(&hv_syscore_ops); | 428 | register_syscore_ops(&hv_syscore_ops); |
| 403 | 429 | ||
| 430 | hyperv_init_cpuhp = cpuhp; | ||
| 404 | return; | 431 | return; |
| 405 | 432 | ||
| 406 | remove_cpuhp_state: | 433 | remove_cpuhp_state: |
| @@ -66,11 +66,17 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus, · 65 unmodified lines | |||
| 66 | if (!hv_hypercall_pg) | 66 | if (!hv_hypercall_pg) |
| 67 | goto do_native; | 67 | goto do_native; |
| 68 | 68 | ||
| 69 | if (cpumask_empty(cpus)) | ||
| 70 | return; | ||
| 71 | |||
| 72 | local_irq_save(flags); | 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 | flush_pcpu = (struct hv_tlb_flush **) | 80 | flush_pcpu = (struct hv_tlb_flush **) |
| 75 | this_cpu_ptr(hyperv_pcpu_input_arg); | 81 | this_cpu_ptr(hyperv_pcpu_input_arg); |
| 76 | 82 | ||
| @@ -1010,9 +1010,21 @@ struct kvm_arch { · 1009 unmodified lines | |||
| 1010 | */ | 1010 | */ |
| 1011 | bool tdp_mmu_enabled; | 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 | struct list_head tdp_mmu_roots; | 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 | struct list_head tdp_mmu_pages; | 1028 | struct list_head tdp_mmu_pages; |
| 1017 | }; | 1029 | }; |
| 1018 | 1030 | ||
| @@ -1287,6 +1299,8 @@ struct kvm_x86_ops { · 268 unmodified lines | |||
| 1287 | void (*migrate_timers)(struct kvm_vcpu *vcpu); | 1299 | void (*migrate_timers)(struct kvm_vcpu *vcpu); |
| 1288 | void (*msr_filter_changed)(struct kvm_vcpu *vcpu); | 1300 | void (*msr_filter_changed)(struct kvm_vcpu *vcpu); |
| 1289 | int (*complete_emulated_msr)(struct kvm_vcpu *vcpu, int err); | 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 | struct kvm_x86_nested_ops { | 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 | int kvm_emulate_cpuid(struct kvm_vcpu *vcpu); | 1482 | int kvm_emulate_cpuid(struct kvm_vcpu *vcpu); |
| 1469 | int kvm_emulate_halt(struct kvm_vcpu *vcpu); | 1483 | int kvm_emulate_halt(struct kvm_vcpu *vcpu); |
| 1470 | int kvm_vcpu_halt(struct kvm_vcpu *vcpu); | 1484 | int kvm_vcpu_halt(struct kvm_vcpu *vcpu); |
| 1485 | int kvm_emulate_ap_reset_hold(struct kvm_vcpu *vcpu); | ||
| 1471 | int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu); | 1486 | int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu); |
| 1472 | 1487 | ||
| 1473 | void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); | 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 | #if IS_ENABLED(CONFIG_HYPERV) | 76 | #if IS_ENABLED(CONFIG_HYPERV) |
| 77 | extern int hyperv_init_cpuhp; | ||
| 78 | |||
| 77 | extern void *hv_hypercall_pg; | 79 | extern void *hv_hypercall_pg; |
| 78 | extern void __percpu **hyperv_pcpu_input_arg; | 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 | if (kexec_in_progress && hv_kexec_handler) | 136 | if (kexec_in_progress && hv_kexec_handler) |
| 137 | hv_kexec_handler(); | 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 | native_machine_shutdown(); | 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 | static void hv_machine_crash_shutdown(struct pt_regs *regs) | 154 | static void hv_machine_crash_shutdown(struct pt_regs *regs) |
| 142 | { | 155 | { |
| 143 | if (hv_crash_handler) | 156 | if (hv_crash_handler) |
| 144 | hv_crash_handler(regs); | 157 | hv_crash_handler(regs); |
| 158 | |||
| 159 | /* The function calls crash_smp_send_stop(). */ | ||
| 145 | native_machine_crash_shutdown(regs); | 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 | #endif /* CONFIG_KEXEC_CORE */ | 165 | #endif /* CONFIG_KEXEC_CORE */ |
| 148 | #endif /* CONFIG_HYPERV */ | 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 | *repeat = 0; | 167 | *repeat = 0; |
| 168 | *uniform = 1; | 168 | *uniform = 1; |
| 169 | 169 | ||
| 170 | /* Make end inclusive instead of exclusive */ | ||
| 171 | end--; | ||
| 172 | |||
| 173 | prev_match = MTRR_TYPE_INVALID; | 170 | prev_match = MTRR_TYPE_INVALID; |
| 174 | for (i = 0; i < num_var_ranges; ++i) { | 171 | for (i = 0; i < num_var_ranges; ++i) { |
| 175 | unsigned short start_state, end_state, inclusive; | 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 | int repeat; | 258 | int repeat; |
| 262 | u64 partial_end; | 259 | u64 partial_end; |
| 263 | 260 | ||
| 261 | /* Make end inclusive instead of exclusive */ | ||
| 262 | end--; | ||
| 263 | |||
| 264 | if (!mtrr_state_set) | 264 | if (!mtrr_state_set) |
| 265 | return MTRR_TYPE_INVALID; | 265 | return MTRR_TYPE_INVALID; |
| 266 | 266 | ||
| @@ -525,89 +525,70 @@ static void rdtgroup_remove(struct rdtgroup *rdtgrp) · 524 unmodified lines | |||
| 525 | kfree(rdtgrp); | 525 | kfree(rdtgrp); |
| 526 | } | 526 | } |
| 527 | 527 | ||
| 528 | struct task_move_callback { | 528 | static void _update_task_closid_rmid(void *task) |
| 529 | struct callback_head work; | ||
| 530 | struct rdtgroup *rdtgrp; | ||
| 531 | }; | ||
| 532 | |||
| 533 | static void move_myself(struct callback_head *head) | ||
| 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 | 531 | * If the task is still current on this CPU, update PQR_ASSOC MSR. |
| 543 | * was invoked, then assign the task to root group and free the | 532 | * Otherwise, the MSR is updated when the task is scheduled in. |
| 544 | * resource group. | ||
| 545 | */ | 533 | */ |
| 546 | if (atomic_dec_and_test(&rdtgrp->waitcount) && | 534 | if (task == current) |
| 547 | (rdtgrp->flags & RDT_DELETED)) { | 535 | resctrl_sched_in(); |
| 548 | current->closid = 0; | 536 | } |
| 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(); | ||
| 560 | 537 | ||
| 561 | out: | 538 | static void update_task_closid_rmid(struct task_struct *t) |
| 562 | kfree(callback); | 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 | static int __rdtgroup_move_task(struct task_struct *tsk, | 546 | static int __rdtgroup_move_task(struct task_struct *tsk, |
| 566 | struct rdtgroup *rdtgrp) | 547 | struct rdtgroup *rdtgrp) |
| 567 | { | 548 | { |
| 568 | struct task_move_callback *callback; | 549 | /* If the task is already in rdtgrp, no need to move the task. */ |
| 569 | int ret; | 550 | if ((rdtgrp->type == RDTCTRL_GROUP && tsk->closid == rdtgrp->closid && |
| 570 | 551 | tsk->rmid == rdtgrp->mon.rmid) || | |
| 571 | callback = kzalloc(sizeof(*callback), GFP_KERNEL); | 552 | (rdtgrp->type == RDTMON_GROUP && tsk->rmid == rdtgrp->mon.rmid && |
| 572 | if (!callback) | 553 | tsk->closid == rdtgrp->mon.parent->closid)) |
| 573 | return -ENOMEM; | 554 | return 0; |
| 574 | callback->work.func = move_myself; | ||
| 575 | callback->rdtgrp = rdtgrp; | ||
| 576 | 555 | ||
| 577 | /* | 556 | /* |
| 578 | * Take a refcount, so rdtgrp cannot be freed before the | 557 | * Set the task's closid/rmid before the PQR_ASSOC MSR can be |
| 579 | * callback has been invoked. | 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); | 564 | |
| 582 | ret = task_work_add(tsk, &callback->work, TWA_RESUME); | 565 | if (rdtgrp->type == RDTCTRL_GROUP) { |
| 583 | if (ret) { | 566 | tsk->closid = rdtgrp->closid; |
| 584 | /* | 567 | tsk->rmid = rdtgrp->mon.rmid; |
| 585 | * Task is exiting. Drop the refcount and free the callback. | 568 | } else if (rdtgrp->type == RDTMON_GROUP) { |
| 586 | * No need to check the refcount as the group cannot be | 569 | if (rdtgrp->mon.parent->closid == tsk->closid) { |
| 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; | ||
| 600 | tsk->rmid = rdtgrp->mon.rmid; | 570 | tsk->rmid = rdtgrp->mon.rmid; |
| 601 | } else if (rdtgrp->type == RDTMON_GROUP) { | 571 | } else { |
| 602 | if (rdtgrp->mon.parent->closid == tsk->closid) { | 572 | rdt_last_cmd_puts("Can't move task to different control group\n"); |
| 603 | tsk->rmid = rdtgrp->mon.rmid; | 573 | return -EINVAL; |
| 604 | } else { | ||
| 605 | rdt_last_cmd_puts("Can't move task to different control group\n"); | ||
| 606 | ret = -EINVAL; | ||
| 607 | } | ||
| 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 | static bool is_closid_match(struct task_struct *t, struct rdtgroup *r) | 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 | case 0xe4: | 305 | case 0xe4: |
| 306 | case 0xe5: | 306 | case 0xe5: |
| 307 | *exitinfo |= IOIO_TYPE_IN; | 307 | *exitinfo |= IOIO_TYPE_IN; |
| 308 | *exitinfo |= (u64)insn->immediate.value << 16; | 308 | *exitinfo |= (u8)insn->immediate.value << 16; |
| 309 | break; | 309 | break; |
| 310 | 310 | ||
| 311 | /* OUT immediate opcodes */ | 311 | /* OUT immediate opcodes */ |
| 312 | case 0xe6: | 312 | case 0xe6: |
| 313 | case 0xe7: | 313 | case 0xe7: |
| 314 | *exitinfo |= IOIO_TYPE_OUT; | 314 | *exitinfo |= IOIO_TYPE_OUT; |
| 315 | *exitinfo |= (u64)insn->immediate.value << 16; | 315 | *exitinfo |= (u8)insn->immediate.value << 16; |
| 316 | break; | 316 | break; |
| 317 | 317 | ||
| 318 | /* IN register opcodes */ | 318 | /* IN register opcodes */ |
| @@ -674,7 +674,7 @@ static bool pv_eoi_get_pending(struct kvm_vcpu *vcpu) · 673 unmodified lines | |||
| 674 | (unsigned long long)vcpu->arch.pv_eoi.msr_val); | 674 | (unsigned long long)vcpu->arch.pv_eoi.msr_val); |
| 675 | return false; | 675 | return false; |
| 676 | } | 676 | } |
| 677 | return val & 0x1; | 677 | return val & KVM_PV_EOI_ENABLED; |
| 678 | } | 678 | } |
| 679 | 679 | ||
| 680 | static void pv_eoi_set_pending(struct kvm_vcpu *vcpu) | 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 | /* evaluate pending_events before reading the vector */ | 2898 | /* evaluate pending_events before reading the vector */ |
| 2899 | smp_rmb(); | 2899 | smp_rmb(); |
| 2900 | sipi_vector = apic->sipi_vector; | 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 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; | 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 | if (e < s) | 49 | if (e < s) |
| 50 | return 0; | 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 | void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 access_mask); | 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 | * Return the level of the lowest level SPTE added to sptes. | 3493 | * Return the level of the lowest level SPTE added to sptes. |
| 3494 | * That SPTE may be non-present. | 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 | struct kvm_shadow_walk_iterator iterator; | 3498 | struct kvm_shadow_walk_iterator iterator; |
| 3499 | int leaf = vcpu->arch.mmu->root_level; | 3499 | int leaf = -1; |
| 3500 | u64 spte; | 3500 | u64 spte; |
| 3501 | 3501 | ||
| 3502 | |||
| 3503 | walk_shadow_page_lockless_begin(vcpu); | 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 | shadow_walk_okay(&iterator); | 3506 | shadow_walk_okay(&iterator); |
| 3507 | __shadow_walk_next(&iterator, spte)) { | 3507 | __shadow_walk_next(&iterator, spte)) { |
| 3508 | leaf = iterator.level; | 3508 | leaf = iterator.level; |
| 3509 | spte = mmu_spte_get_lockless(iterator.sptep); | 3509 | spte = mmu_spte_get_lockless(iterator.sptep); |
| 3510 | 3510 | ||
| 3511 | sptes[leaf - 1] = spte; | 3511 | sptes[leaf] = spte; |
| 3512 | 3512 | ||
| 3513 | if (!is_shadow_present_pte(spte)) | 3513 | if (!is_shadow_present_pte(spte)) |
| 3514 | break; | 3514 | break; |
| 3515 | |||
| 3516 | } | 3515 | } |
| 3517 | 3516 | ||
| 3518 | walk_shadow_page_lockless_end(vcpu); | 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 | return leaf; | 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 | static bool get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr, u64 *sptep) | 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 | struct rsvd_bits_validate *rsvd_check; | 3526 | struct rsvd_bits_validate *rsvd_check; |
| 3528 | int root = vcpu->arch.mmu->shadow_root_level; | 3527 | int root, leaf, level; |
| 3529 | int leaf; | ||
| 3530 | int level; | ||
| 3531 | bool reserved = false; | 3528 | bool reserved = false; |
| 3532 | 3529 | ||
| 3533 | if (!VALID_PAGE(vcpu->arch.mmu->root_hpa)) { | 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 | if (is_tdp_mmu_root(vcpu->kvm, vcpu->arch.mmu->root_hpa)) | 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 | else | 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 | rsvd_check = &vcpu->arch.mmu->shadow_zero_check; | 3556 | rsvd_check = &vcpu->arch.mmu->shadow_zero_check; |
| 3544 | 3557 | ||
| 3545 | for (level = root; level >= leaf; level--) { | 3558 | for (level = root; level >= leaf; level--) |
| 3546 | if (!is_shadow_present_pte(sptes[level - 1])) | ||
| 3547 | break; | ||
| 3548 | /* | 3559 | /* |
| 3549 | * Use a bitwise-OR instead of a logical-OR to aggregate the | 3560 | * Use a bitwise-OR instead of a logical-OR to aggregate the |
| 3550 | * reserved bit and EPT's invalid memtype/XWR checks to avoid | 3561 | * reserved bit and EPT's invalid memtype/XWR checks to avoid |
| 3551 | * adding a Jcc in the loop. | 3562 | * adding a Jcc in the loop. |
| 3552 | */ | 3563 | */ |
| 3553 | reserved |= __is_bad_mt_xwr(rsvd_check, sptes[level - 1]) | | 3564 | reserved |= __is_bad_mt_xwr(rsvd_check, sptes[level]) | |
| 3554 | __is_rsvd_bits_set(rsvd_check, sptes[level - 1], | 3565 | __is_rsvd_bits_set(rsvd_check, sptes[level], level); |
| 3555 | level); | ||
| 3556 | } | ||
| 3557 | 3566 | ||
| 3558 | if (reserved) { | 3567 | if (reserved) { |
| 3559 | pr_err("%s: detect reserved bits on spte, addr 0x%llx, dump hierarchy:\n", | 3568 | pr_err("%s: detect reserved bits on spte, addr 0x%llx, dump hierarchy:\n", |
| 3560 | __func__, addr); | 3569 | __func__, addr); |
| 3561 | for (level = root; level >= leaf; level--) | 3570 | for (level = root; level >= leaf; level--) |
| 3562 | pr_err("------ spte 0x%llx level %d.\n", | 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 | return reserved; | 3575 | return reserved; |
| 3569 | } | 3576 | } |
| 3570 | 3577 | ||
| @@ -44,7 +44,48 @@ void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm) · 43 unmodified lines | |||
| 44 | WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots)); | 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 | list_for_each_entry(_root, &_kvm->arch.tdp_mmu_roots, link) | 89 | list_for_each_entry(_root, &_kvm->arch.tdp_mmu_roots, link) |
| 49 | 90 | ||
| 50 | bool is_tdp_mmu_root(struct kvm *kvm, hpa_t hpa) | 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 | struct kvm_mmu_page *root; | 488 | struct kvm_mmu_page *root; |
| 448 | bool flush = false; | 489 | bool flush = false; |
| 449 | 490 | ||
| 450 | for_each_tdp_mmu_root(kvm, root) { | 491 | for_each_tdp_mmu_root_yield_safe(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 | |||
| 457 | flush |= zap_gfn_range(kvm, root, start, end, true); | 492 | flush |= zap_gfn_range(kvm, root, start, end, true); |
| 458 | 493 | ||
| 459 | kvm_mmu_put_root(kvm, root); | ||
| 460 | } | ||
| 461 | |||
| 462 | return flush; | 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 | int ret = 0; | 651 | int ret = 0; |
| 620 | int as_id; | 652 | int as_id; |
| 621 | 653 | ||
| 622 | for_each_tdp_mmu_root(kvm, root) { | 654 | for_each_tdp_mmu_root_yield_safe(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 | |||
| 629 | as_id = kvm_mmu_page_as_id(root); | 655 | as_id = kvm_mmu_page_as_id(root); |
| 630 | slots = __kvm_memslots(kvm, as_id); | 656 | slots = __kvm_memslots(kvm, as_id); |
| 631 | kvm_for_each_memslot(memslot, slots) { | 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 | ret |= handler(kvm, memslot, root, gfn_start, | 673 | ret |= handler(kvm, memslot, root, gfn_start, |
| 648 | gfn_end, data); | 674 | gfn_end, data); |
| 649 | } | 675 | } |
| 650 | |||
| 651 | kvm_mmu_put_root(kvm, root); | ||
| 652 | } | 676 | } |
| 653 | 677 | ||
| 654 | return ret; | 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 | int root_as_id; | 862 | int root_as_id; |
| 839 | bool spte_set = false; | 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 | root_as_id = kvm_mmu_page_as_id(root); | 866 | root_as_id = kvm_mmu_page_as_id(root); |
| 843 | if (root_as_id != slot->as_id) | 867 | if (root_as_id != slot->as_id) |
| 844 | continue; | 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 | spte_set |= wrprot_gfn_range(kvm, root, slot->base_gfn, | 870 | spte_set |= wrprot_gfn_range(kvm, root, slot->base_gfn, |
| 853 | slot->base_gfn + slot->npages, min_level); | 871 | slot->base_gfn + slot->npages, min_level); |
| 854 | |||
| 855 | kvm_mmu_put_root(kvm, root); | ||
| 856 | } | 872 | } |
| 857 | 873 | ||
| 858 | return spte_set; | 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 | int root_as_id; | 922 | int root_as_id; |
| 907 | bool spte_set = false; | 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 | root_as_id = kvm_mmu_page_as_id(root); | 926 | root_as_id = kvm_mmu_page_as_id(root); |
| 911 | if (root_as_id != slot->as_id) | 927 | if (root_as_id != slot->as_id) |
| 912 | continue; | 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 | spte_set |= clear_dirty_gfn_range(kvm, root, slot->base_gfn, | 930 | spte_set |= clear_dirty_gfn_range(kvm, root, slot->base_gfn, |
| 921 | slot->base_gfn + slot->npages); | 931 | slot->base_gfn + slot->npages); |
| 922 | |||
| 923 | kvm_mmu_put_root(kvm, root); | ||
| 924 | } | 932 | } |
| 925 | 933 | ||
| 926 | return spte_set; | 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 | int root_as_id; | 1037 | int root_as_id; |
| 1030 | bool spte_set = false; | 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 | root_as_id = kvm_mmu_page_as_id(root); | 1041 | root_as_id = kvm_mmu_page_as_id(root); |
| 1034 | if (root_as_id != slot->as_id) | 1042 | if (root_as_id != slot->as_id) |
| 1035 | continue; | 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 | spte_set |= set_dirty_gfn_range(kvm, root, slot->base_gfn, | 1045 | spte_set |= set_dirty_gfn_range(kvm, root, slot->base_gfn, |
| 1044 | slot->base_gfn + slot->npages); | 1046 | slot->base_gfn + slot->npages); |
| 1045 | |||
| 1046 | kvm_mmu_put_root(kvm, root); | ||
| 1047 | } | 1047 | } |
| 1048 | return spte_set; | 1048 | return spte_set; |
| 1049 | } | 1049 | } |
| @@ -1089,21 +1089,13 @@ void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, · 39 unmodified lines | |||
| 1089 | struct kvm_mmu_page *root; | 1089 | struct kvm_mmu_page *root; |
| 1090 | int root_as_id; | 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 | root_as_id = kvm_mmu_page_as_id(root); | 1093 | root_as_id = kvm_mmu_page_as_id(root); |
| 1094 | if (root_as_id != slot->as_id) | 1094 | if (root_as_id != slot->as_id) |
| 1095 | continue; | 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 | zap_collapsible_spte_range(kvm, root, slot->base_gfn, | 1097 | zap_collapsible_spte_range(kvm, root, slot->base_gfn, |
| 1104 | slot->base_gfn + slot->npages); | 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 | * Return the level of the lowest level SPTE added to sptes. | 1152 | * Return the level of the lowest level SPTE added to sptes. |
| 1161 | * That SPTE may be non-present. | 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 | struct tdp_iter iter; | 1158 | struct tdp_iter iter; |
| 1166 | struct kvm_mmu *mmu = vcpu->arch.mmu; | 1159 | struct kvm_mmu *mmu = vcpu->arch.mmu; |
| 1167 | int leaf = vcpu->arch.mmu->shadow_root_level; | ||
| 1168 | gfn_t gfn = addr >> PAGE_SHIFT; | 1160 | gfn_t gfn = addr >> PAGE_SHIFT; |
| 1161 | int leaf = -1; | ||
| 1162 | |||
| 1163 | *root_level = vcpu->arch.mmu->shadow_root_level; | ||
| 1169 | 1164 | ||
| 1170 | tdp_mmu_for_each_pte(iter, mmu, gfn, gfn + 1) { | 1165 | tdp_mmu_for_each_pte(iter, mmu, gfn, gfn + 1) { |
| 1171 | leaf = iter.level; | 1166 | leaf = iter.level; |
| 1172 | sptes[leaf - 1] = iter.old_spte; | 1167 | sptes[leaf] = iter.old_spte; |
| 1173 | } | 1168 | } |
| 1174 | 1169 | ||
| 1175 | return leaf; | 1170 | return leaf; |
| @@ -44,5 +44,7 @@ void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, · 43 unmodified lines | |||
| 44 | bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, | 44 | bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, |
| 45 | struct kvm_memory_slot *slot, gfn_t gfn); | 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 | #endif /* __KVM_X86_MMU_TDP_MMU_H */ | 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 | static bool svm_get_nested_state_pages(struct kvm_vcpu *vcpu) | 199 | static bool svm_get_nested_state_pages(struct kvm_vcpu *vcpu) |
| 200 | { | 200 | { |
| 201 | struct vcpu_svm *svm = to_svm(vcpu); | 201 | struct vcpu_svm *svm = to_svm(vcpu); |
| 202 | |||
| 202 | if (!nested_svm_vmrun_msrpm(svm)) { | 203 | if (!nested_svm_vmrun_msrpm(svm)) { |
| 203 | vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | 204 | vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; |
| 204 | vcpu->run->internal.suberror = | 205 | vcpu->run->internal.suberror = |
| @@ -595,6 +596,8 @@ int nested_svm_vmexit(struct vcpu_svm *svm) · 390 unmodified lines | |||
| 595 | svm->nested.vmcb12_gpa = 0; | 596 | svm->nested.vmcb12_gpa = 0; |
| 596 | WARN_ON_ONCE(svm->nested.nested_run_pending); | 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 | /* in case we halted in L2 */ | 601 | /* in case we halted in L2 */ |
| 599 | svm->vcpu.arch.mp_state = KVM_MP_STATE_RUNNABLE; | 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 | leave_guest_mode(&svm->vcpu); | 757 | leave_guest_mode(&svm->vcpu); |
| 755 | copy_vmcb_control_area(&vmcb->control, &hsave->control); | 758 | copy_vmcb_control_area(&vmcb->control, &hsave->control); |
| 756 | nested_svm_uninit_mmu_context(&svm->vcpu); | 759 | nested_svm_uninit_mmu_context(&svm->vcpu); |
| 760 | vmcb_mark_all_dirty(svm->vmcb); | ||
| 757 | } | 761 | } |
| 758 | 762 | ||
| 759 | kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, &svm->vcpu); | 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 | * in the registers, the save area of the nested state instead | 1198 | * in the registers, the save area of the nested state instead |
| 1195 | * contains saved L1 state. | 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 | copy_vmcb_control_area(&hsave->control, &svm->vmcb->control); | 1205 | copy_vmcb_control_area(&hsave->control, &svm->vmcb->control); |
| 1198 | hsave->save = *save; | 1206 | hsave->save = *save; |
| 1199 | 1207 | ||
| @@ -1563,6 +1563,7 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) · 1562 unmodified lines | |||
| 1563 | goto vmgexit_err; | 1563 | goto vmgexit_err; |
| 1564 | break; | 1564 | break; |
| 1565 | case SVM_VMGEXIT_NMI_COMPLETE: | 1565 | case SVM_VMGEXIT_NMI_COMPLETE: |
| 1566 | case SVM_VMGEXIT_AP_HLT_LOOP: | ||
| 1566 | case SVM_VMGEXIT_AP_JUMP_TABLE: | 1567 | case SVM_VMGEXIT_AP_JUMP_TABLE: |
| 1567 | case SVM_VMGEXIT_UNSUPPORTED_EVENT: | 1568 | case SVM_VMGEXIT_UNSUPPORTED_EVENT: |
| 1568 | break; | 1569 | break; |
| @@ -1888,6 +1889,9 @@ int sev_handle_vmgexit(struct vcpu_svm *svm) · 319 unmodified lines | |||
| 1888 | case SVM_VMGEXIT_NMI_COMPLETE: | 1889 | case SVM_VMGEXIT_NMI_COMPLETE: |
| 1889 | ret = svm_invoke_exit_handler(svm, SVM_EXIT_IRET); | 1890 | ret = svm_invoke_exit_handler(svm, SVM_EXIT_IRET); |
| 1890 | break; | 1891 | break; |
| 1892 | case SVM_VMGEXIT_AP_HLT_LOOP: | ||
| 1893 | ret = kvm_emulate_ap_reset_hold(&svm->vcpu); | ||
| 1894 | break; | ||
| 1891 | case SVM_VMGEXIT_AP_JUMP_TABLE: { | 1895 | case SVM_VMGEXIT_AP_JUMP_TABLE: { |
| 1892 | struct kvm_sev_info *sev = &to_kvm_svm(svm->vcpu.kvm)->sev_info; | 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 | * of which one step is to perform a VMLOAD. Since hardware does not | 2005 | * of which one step is to perform a VMLOAD. Since hardware does not |
| 2002 | * perform a VMSAVE on VMRUN, the host savearea must be updated. | 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 | * Certain MSRs are restored on VMEXIT, only save ones that aren't | 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 | wrmsrl(host_save_user_msrs[i].index, svm->host_user_msrs[i]); | 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 | return EXIT_FASTPATH_NONE; | 3677 | return EXIT_FASTPATH_NONE; |
| 3678 | } | 3678 | } |
| 3679 | 3679 | ||
| 3680 | void __svm_vcpu_run(unsigned long vmcb_pa, unsigned long *regs); | ||
| 3681 | |||
| 3682 | static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu, | 3680 | static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu, |
| 3683 | struct vcpu_svm *svm) | 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 | (vmcb_is_intercept(&svm->vmcb->control, INTERCEPT_INIT)); | 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 | static void svm_vm_destroy(struct kvm *kvm) | 4393 | static void svm_vm_destroy(struct kvm *kvm) |
| 4388 | { | 4394 | { |
| 4389 | avic_vm_destroy(kvm); | 4395 | avic_vm_destroy(kvm); |
| @@ -4526,6 +4532,8 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { · 136 unmodified lines | |||
| 4526 | 4532 | ||
| 4527 | .msr_filter_changed = svm_msr_filter_changed, | 4533 | .msr_filter_changed = svm_msr_filter_changed, |
| 4528 | .complete_emulated_msr = svm_complete_emulated_msr, | 4534 | .complete_emulated_msr = svm_complete_emulated_msr, |
| 4535 | |||
| 4536 | .vcpu_deliver_sipi_vector = svm_vcpu_deliver_sipi_vector, | ||
| 4529 | }; | 4537 | }; |
| 4530 | 4538 | ||
| 4531 | static struct kvm_x86_init_ops svm_init_ops __initdata = { | 4539 | static struct kvm_x86_init_ops svm_init_ops __initdata = { |
| @@ -185,6 +185,7 @@ struct vcpu_svm { · 184 unmodified lines | |||
| 185 | struct vmcb_save_area *vmsa; | 185 | struct vmcb_save_area *vmsa; |
| 186 | struct ghcb *ghcb; | 186 | struct ghcb *ghcb; |
| 187 | struct kvm_host_map ghcb_map; | 187 | struct kvm_host_map ghcb_map; |
| 188 | bool received_first_sipi; | ||
| 188 | 189 | ||
| 189 | /* SEV-ES scratch area support */ | 190 | /* SEV-ES scratch area support */ |
| 190 | void *ghcb_sa; | 191 | void *ghcb_sa; |
| @@ -591,6 +592,7 @@ void sev_es_init_vmcb(struct vcpu_svm *svm); · 400 unmodified lines | |||
| 591 | void sev_es_create_vcpu(struct vcpu_svm *svm); | 592 | void sev_es_create_vcpu(struct vcpu_svm *svm); |
| 592 | void sev_es_vcpu_load(struct vcpu_svm *svm, int cpu); | 593 | void sev_es_vcpu_load(struct vcpu_svm *svm, int cpu); |
| 593 | void sev_es_vcpu_put(struct vcpu_svm *svm); | 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 | /* vmenter.S */ | 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 | /* trying to cancel vmlaunch/vmresume is a bug */ | 4442 | /* trying to cancel vmlaunch/vmresume is a bug */ |
| 4443 | WARN_ON_ONCE(vmx->nested.nested_run_pending); | 4443 | WARN_ON_ONCE(vmx->nested.nested_run_pending); |
| 4444 | 4444 | ||
| 4445 | kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu); | ||
| 4446 | |||
| 4445 | /* Service the TLB flush request for L2 before switching to L1. */ | 4447 | /* Service the TLB flush request for L2 before switching to L1. */ |
| 4446 | if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) | 4448 | if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) |
| 4447 | kvm_vcpu_flush_tlb_current(vcpu); | 4449 | kvm_vcpu_flush_tlb_current(vcpu); |
| @@ -7707,6 +7707,8 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { · 7706 unmodified lines | |||
| 7707 | .msr_filter_changed = vmx_msr_filter_changed, | 7707 | .msr_filter_changed = vmx_msr_filter_changed, |
| 7708 | .complete_emulated_msr = kvm_complete_insn_gp, | 7708 | .complete_emulated_msr = kvm_complete_insn_gp, |
| 7709 | .cpu_dirty_log_size = vmx_cpu_dirty_log_size, | 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 | static __init int hardware_setup(void) | 7714 | static __init int hardware_setup(void) |
| @@ -7976,17 +7976,22 @@ void kvm_arch_exit(void) · 7975 unmodified lines | |||
| 7976 | kmem_cache_destroy(x86_fpu_cache); | 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 | ++vcpu->stat.halt_exits; | 7981 | ++vcpu->stat.halt_exits; |
| 7982 | if (lapic_in_kernel(vcpu)) { | 7982 | if (lapic_in_kernel(vcpu)) { |
| 7983 | vcpu->arch.mp_state = KVM_MP_STATE_HALTED; | 7983 | vcpu->arch.mp_state = state; |
| 7984 | return 1; | 7984 | return 1; |
| 7985 | } else { | 7985 | } else { |
| 7986 | vcpu->run->exit_reason = KVM_EXIT_HLT; | 7986 | vcpu->run->exit_reason = reason; |
| 7987 | return 0; | 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 | EXPORT_SYMBOL_GPL(kvm_vcpu_halt); | 7995 | EXPORT_SYMBOL_GPL(kvm_vcpu_halt); |
| 7991 | 7996 | ||
| 7992 | int kvm_emulate_halt(struct kvm_vcpu *vcpu) | 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 | EXPORT_SYMBOL_GPL(kvm_emulate_halt); | 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 | #ifdef CONFIG_X86_64 | 8016 | #ifdef CONFIG_X86_64 |
| 8004 | static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr, | 8017 | static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr, |
| 8005 | unsigned long clock_type) | 8018 | unsigned long clock_type) |
| @@ -8789,7 +8802,9 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) · 783 unmodified lines | |||
| 8789 | 8802 | ||
| 8790 | if (kvm_request_pending(vcpu)) { | 8803 | if (kvm_request_pending(vcpu)) { |
| 8791 | if (kvm_check_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu)) { | 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 | r = 0; | 8808 | r = 0; |
| 8794 | goto out; | 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 | kvm_apic_accept_events(vcpu); | 9109 | kvm_apic_accept_events(vcpu); |
| 9095 | switch(vcpu->arch.mp_state) { | 9110 | switch(vcpu->arch.mp_state) { |
| 9096 | case KVM_MP_STATE_HALTED: | 9111 | case KVM_MP_STATE_HALTED: |
| 9112 | case KVM_MP_STATE_AP_RESET_HOLD: | ||
| 9097 | vcpu->arch.pv.pv_unhalted = false; | 9113 | vcpu->arch.pv.pv_unhalted = false; |
| 9098 | vcpu->arch.mp_state = | 9114 | vcpu->arch.mp_state = |
| 9099 | KVM_MP_STATE_RUNNABLE; | 9115 | KVM_MP_STATE_RUNNABLE; |
| @@ -9520,8 +9536,9 @@ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, · 420 unmodified lines | |||
| 9520 | kvm_load_guest_fpu(vcpu); | 9536 | kvm_load_guest_fpu(vcpu); |
| 9521 | 9537 | ||
| 9522 | kvm_apic_accept_events(vcpu); | 9538 | kvm_apic_accept_events(vcpu); |
| 9523 | if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED && | 9539 | if ((vcpu->arch.mp_state == KVM_MP_STATE_HALTED || |
| 9524 | vcpu->arch.pv.pv_unhalted) | 9540 | vcpu->arch.mp_state == KVM_MP_STATE_AP_RESET_HOLD) && |
| 9541 | vcpu->arch.pv.pv_unhalted) | ||
| 9525 | mp_state->mp_state = KVM_MP_STATE_RUNNABLE; | 9542 | mp_state->mp_state = KVM_MP_STATE_RUNNABLE; |
| 9526 | else | 9543 | else |
| 9527 | mp_state->mp_state = vcpu->arch.mp_state; | 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 | kvm_set_segment(vcpu, &cs, VCPU_SREG_CS); | 10169 | kvm_set_segment(vcpu, &cs, VCPU_SREG_CS); |
| 10153 | kvm_rip_write(vcpu, 0); | 10170 | kvm_rip_write(vcpu, 0); |
| 10154 | } | 10171 | } |
| 10172 | EXPORT_SYMBOL_GPL(kvm_vcpu_deliver_sipi_vector); | ||
| 10155 | 10173 | ||
| 10156 | int kvm_arch_hardware_enable(void) | 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 | free_page((unsigned long)pmd_sv); | 831 | free_page((unsigned long)pmd_sv); |
| 832 | |||
| 833 | pgtable_pmd_page_dtor(virt_to_page(pmd)); | ||
| 832 | free_page((unsigned long)pmd); | 834 | free_page((unsigned long)pmd); |
| 833 | 835 | ||
| 834 | return 1; | 836 | return 1; |
| @@ -164,10 +164,10 @@ static int xen_cpu_up_prepare_hvm(unsigned int cpu) · 163 unmodified lines | |||
| 164 | else | 164 | else |
| 165 | per_cpu(xen_vcpu_id, cpu) = cpu; | 165 | per_cpu(xen_vcpu_id, cpu) = cpu; |
| 166 | rc = xen_vcpu_setup(cpu); | 166 | rc = xen_vcpu_setup(cpu); |
| 167 | if (rc) | 167 | if (rc || !xen_have_vector_callback) |
| 168 | return rc; | 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 | xen_setup_timer(cpu); | 171 | xen_setup_timer(cpu); |
| 172 | 172 | ||
| 173 | rc = xen_smp_intr_init(cpu); | 173 | rc = xen_smp_intr_init(cpu); |
| @@ -188,6 +188,8 @@ static int xen_cpu_dead_hvm(unsigned int cpu) · 14 unmodified lines | |||
| 188 | return 0; | 188 | return 0; |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | static bool no_vector_callback __initdata; | ||
| 192 | |||
| 191 | static void __init xen_hvm_guest_init(void) | 193 | static void __init xen_hvm_guest_init(void) |
| 192 | { | 194 | { |
| 193 | if (xen_pv_domain()) | 195 | if (xen_pv_domain()) |
| @@ -207,7 +209,7 @@ static void __init xen_hvm_guest_init(void) · 13 unmodified lines | |||
| 207 | 209 | ||
| 208 | xen_panic_handler_init(); | 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 | xen_have_vector_callback = 1; | 213 | xen_have_vector_callback = 1; |
| 212 | 214 | ||
| 213 | xen_hvm_smp_init(); | 215 | xen_hvm_smp_init(); |
| @@ -233,6 +235,13 @@ static __init int xen_parse_nopv(char *arg) · 19 unmodified lines | |||
| 233 | } | 235 | } |
| 234 | early_param("xen_nopv", xen_parse_nopv); | 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 | bool __init xen_hvm_need_lapic(void) | 245 | bool __init xen_hvm_need_lapic(void) |
| 237 | { | 246 | { |
| 238 | if (xen_pv_domain()) | 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 | int cpu; | 33 | int cpu; |
| 34 | 34 | ||
| 35 | native_smp_prepare_cpus(max_cpus); | 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 | for_each_possible_cpu(cpu) { | 42 | for_each_possible_cpu(cpu) { |
| 41 | if (cpu == 0) | 43 | if (cpu == 0) |
| @@ -50,9 +52,11 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) · 8 unmodified lines | |||
| 50 | static void xen_hvm_cpu_die(unsigned int cpu) | 52 | static void xen_hvm_cpu_die(unsigned int cpu) |
| 51 | { | 53 | { |
| 52 | if (common_cpu_die(cpu) == 0) { | 54 | if (common_cpu_die(cpu) == 0) { |
| 53 | xen_smp_intr_free(cpu); | 55 | if (xen_have_vector_callback) { |
| 54 | xen_uninit_lock_cpu(cpu); | 56 | xen_smp_intr_free(cpu); |
| 55 | xen_teardown_timer(cpu); | 57 | xen_uninit_lock_cpu(cpu); |
| 58 | xen_teardown_timer(cpu); | ||
| 59 | } | ||
| 56 | } | 60 | } |
| 57 | } | 61 | } |
| 58 | #else | 62 | #else |
| @@ -64,14 +68,17 @@ static void xen_hvm_cpu_die(unsigned int cpu) · 5 unmodified lines | |||
| 64 | 68 | ||
| 65 | void __init xen_hvm_smp_init(void) | 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 | return; | 78 | return; |
| 79 | } | ||
| 69 | 80 | ||
| 70 | smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus; | ||
| 71 | smp_ops.smp_send_reschedule = xen_smp_send_reschedule; | 81 | smp_ops.smp_send_reschedule = xen_smp_send_reschedule; |
| 72 | smp_ops.cpu_die = xen_hvm_cpu_die; | ||
| 73 | smp_ops.send_call_func_ipi = xen_smp_send_call_function_ipi; | 82 | smp_ops.send_call_func_ipi = xen_smp_send_call_function_ipi; |
| 74 | smp_ops.send_call_func_single_ipi = xen_smp_send_call_function_single_ipi; | 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 | generated-y += syscall_table.h | 2 | generated-y += syscall_table.h |
| 3 | generic-y += extable.h | 3 | generic-y += extable.h |
| 4 | generic-y += kvm_para.h | 4 | generic-y += kvm_para.h |
| 5 | generic-y += local64.h | ||
| 6 | generic-y += mcs_spinlock.h | 5 | generic-y += mcs_spinlock.h |
| 7 | generic-y += param.h | 6 | generic-y += param.h |
| 8 | generic-y += qrwlock.h | 7 | generic-y += qrwlock.h |
| @@ -6332,13 +6332,13 @@ static unsigned int bfq_update_depths(struct bfq_data *bfqd, · 6331 unmodified lines | |||
| 6332 | * limit 'something'. | 6332 | * limit 'something'. |
| 6333 | */ | 6333 | */ |
| 6334 | /* no more than 50% of tags for async I/O */ | 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 | * no more than 75% of tags for sync writes (25% extra tags | 6337 | * no more than 75% of tags for sync writes (25% extra tags |
| 6338 | * w.r.t. async I/O, to prevent async I/O from starving sync | 6338 | * w.r.t. async I/O, to prevent async I/O from starving sync |
| 6339 | * writes) | 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 | * In-word depths in case some bfq_queue is being weight- | 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 | * shortage. | 6348 | * shortage. |
| 6349 | */ | 6349 | */ |
| 6350 | /* no more than ~18% of tags for async I/O */ | 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 | /* no more than ~37% of tags for sync writes (~20% extra tags) */ | 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 | for (i = 0; i < 2; i++) | 6355 | for (i = 0; i < 2; i++) |
| 6356 | for (j = 0; j < 2; j++) | 6356 | for (j = 0; j < 2; j++) |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | #include <linux/bio.h> | 18 | #include <linux/bio.h> |
| 19 | #include <linux/blkdev.h> | 19 | #include <linux/blkdev.h> |
| 20 | #include <linux/blk-mq.h> | 20 | #include <linux/blk-mq.h> |
| 21 | #include <linux/blk-pm.h> | ||
| 21 | #include <linux/highmem.h> | 22 | #include <linux/highmem.h> |
| 22 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
| 23 | #include <linux/pagemap.h> | 24 | #include <linux/pagemap.h> |
| @@ -424,11 +425,11 @@ EXPORT_SYMBOL(blk_cleanup_queue); · 400 unmodified lines | |||
| 424 | /** | 425 | /** |
| 425 | * blk_queue_enter() - try to increase q->q_usage_counter | 426 | * blk_queue_enter() - try to increase q->q_usage_counter |
| 426 | * @q: request queue pointer | 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 | int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags) | 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 | while (true) { | 434 | while (true) { |
| 434 | bool success = false; | 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 | * responsible for ensuring that that counter is | 441 | * responsible for ensuring that that counter is |
| 441 | * globally visible before the queue is unfrozen. | 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 | success = true; | 446 | success = true; |
| 445 | } else { | 447 | } else { |
| 446 | percpu_ref_put(&q->q_usage_counter); | 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 | wait_event(q->mq_freeze_wq, | 468 | wait_event(q->mq_freeze_wq, |
| 467 | (!q->mq_freeze_depth && | 469 | (!q->mq_freeze_depth && |
| 468 | (pm || (blk_pm_request_resume(q), | 470 | blk_pm_resume_queue(pm, q)) || |
| 469 | !blk_queue_pm_only(q)))) || | ||
| 470 | blk_queue_dying(q)); | 471 | blk_queue_dying(q)); |
| 471 | if (blk_queue_dying(q)) | 472 | if (blk_queue_dying(q)) |
| 472 | return -ENODEV; | 473 | return -ENODEV; |
| @@ -630,7 +631,7 @@ struct request *blk_get_request(struct request_queue *q, unsigned int op, · 157 unmodified lines | |||
| 630 | struct request *req; | 631 | struct request *req; |
| 631 | 632 | ||
| 632 | WARN_ON_ONCE(op & REQ_NOWAIT); | 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 | req = blk_mq_alloc_request(q, op, flags); | 636 | req = blk_mq_alloc_request(q, op, flags); |
| 636 | if (!IS_ERR(req) && q->mq_ops->initialize_rq_fn) | 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 | bool use_debt, ioc_locked; | 2551 | bool use_debt, ioc_locked; |
| 2552 | unsigned long flags; | 2552 | unsigned long flags; |
| 2553 | 2553 | ||
| 2554 | /* bypass IOs if disabled or for root cgroup */ | 2554 | /* bypass IOs if disabled, still initializing, or for root cgroup */ |
| 2555 | if (!ioc->enabled || !iocg->level) | 2555 | if (!ioc->enabled || !iocg || !iocg->level) |
| 2556 | return; | 2556 | return; |
| 2557 | 2557 | ||
| 2558 | /* calculate the absolute vtime cost */ | 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 | struct bio *bio) | 2679 | struct bio *bio) |
| 2680 | { | 2680 | { |
| 2681 | struct ioc_gq *iocg = blkg_to_iocg(bio->bi_blkg); | 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 | sector_t bio_end = bio_end_sector(bio); | 2683 | sector_t bio_end = bio_end_sector(bio); |
| 2684 | struct ioc_now now; | 2684 | struct ioc_now now; |
| 2685 | u64 vtime, abs_cost, cost; | 2685 | u64 vtime, abs_cost, cost; |
| 2686 | unsigned long flags; | 2686 | unsigned long flags; |
| 2687 | 2687 | ||
| 2688 | /* bypass if disabled or for root cgroup */ | 2688 | /* bypass if disabled, still initializing, or for root cgroup */ |
| 2689 | if (!ioc->enabled || !iocg->level) | 2689 | if (!ioc->enabled || !iocg || !iocg->level) |
| 2690 | return; | 2690 | return; |
| 2691 | 2691 | ||
| 2692 | abs_cost = calc_vtime_cost(bio, iocg, true); | 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 | ioc_refresh_params(ioc, true); | 2863 | ioc_refresh_params(ioc, true); |
| 2864 | spin_unlock_irq(&ioc->lock); | 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 | rq_qos_add(q, rqos); | 2872 | rq_qos_add(q, rqos); |
| 2867 | ret = blkcg_activate_policy(q, &blkcg_policy_iocost); | 2873 | ret = blkcg_activate_policy(q, &blkcg_policy_iocost); |
| 2868 | if (ret) { | 2874 | if (ret) { |
| @@ -129,6 +129,7 @@ static const char *const blk_queue_flag_name[] = { · 128 unmodified lines | |||
| 129 | QUEUE_FLAG_NAME(PCI_P2PDMA), | 129 | QUEUE_FLAG_NAME(PCI_P2PDMA), |
| 130 | QUEUE_FLAG_NAME(ZONE_RESETALL), | 130 | QUEUE_FLAG_NAME(ZONE_RESETALL), |
| 131 | QUEUE_FLAG_NAME(RQ_ALLOC_TIME), | 131 | QUEUE_FLAG_NAME(RQ_ALLOC_TIME), |
| 132 | QUEUE_FLAG_NAME(NOWAIT), | ||
| 132 | }; | 133 | }; |
| 133 | #undef QUEUE_FLAG_NAME | 134 | #undef QUEUE_FLAG_NAME |
| 134 | 135 | ||
| @@ -245,6 +246,7 @@ static const char *const hctx_flag_name[] = { · 110 unmodified lines | |||
| 245 | HCTX_FLAG_NAME(BLOCKING), | 246 | HCTX_FLAG_NAME(BLOCKING), |
| 246 | HCTX_FLAG_NAME(NO_SCHED), | 247 | HCTX_FLAG_NAME(NO_SCHED), |
| 247 | HCTX_FLAG_NAME(STACKING), | 248 | HCTX_FLAG_NAME(STACKING), |
| 249 | HCTX_FLAG_NAME(TAG_HCTX_SHARED), | ||
| 248 | }; | 250 | }; |
| 249 | #undef HCTX_FLAG_NAME | 251 | #undef HCTX_FLAG_NAME |
| 250 | 252 | ||
| @@ -297,7 +299,6 @@ static const char *const rqf_name[] = { · 46 unmodified lines | |||
| 297 | RQF_NAME(MIXED_MERGE), | 299 | RQF_NAME(MIXED_MERGE), |
| 298 | RQF_NAME(MQ_INFLIGHT), | 300 | RQF_NAME(MQ_INFLIGHT), |
| 299 | RQF_NAME(DONTPREP), | 301 | RQF_NAME(DONTPREP), |
| 300 | RQF_NAME(PREEMPT), | ||
| 301 | RQF_NAME(FAILED), | 302 | RQF_NAME(FAILED), |
| 302 | RQF_NAME(QUIET), | 303 | RQF_NAME(QUIET), |
| 303 | RQF_NAME(ELVPRIV), | 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 | rq->mq_hctx = data->hctx; | 294 | rq->mq_hctx = data->hctx; |
| 295 | rq->rq_flags = 0; | 295 | rq->rq_flags = 0; |
| 296 | rq->cmd_flags = data->cmd_flags; | 296 | rq->cmd_flags = data->cmd_flags; |
| 297 | if (data->flags & BLK_MQ_REQ_PREEMPT) | 297 | if (data->flags & BLK_MQ_REQ_PM) |
| 298 | rq->rq_flags |= RQF_PREEMPT; | 298 | rq->rq_flags |= RQF_PM; |
| 299 | if (blk_queue_io_stat(data->q)) | 299 | if (blk_queue_io_stat(data->q)) |
| 300 | rq->rq_flags |= RQF_IO_STAT; | 300 | rq->rq_flags |= RQF_IO_STAT; |
| 301 | INIT_LIST_HEAD(&rq->queuelist); | 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 | WARN_ON_ONCE(q->rpm_status != RPM_ACTIVE); | 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 | * Increase the pm_only counter before checking whether any | 75 | * Increase the pm_only counter before checking whether any |
| 72 | * non-PM blk_queue_enter() calls are in progress to avoid that any | 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 | /* Switch q_usage_counter back to per-cpu mode. */ | 93 | /* Switch q_usage_counter back to per-cpu mode. */ |
| 90 | blk_mq_unfreeze_queue(q); | 94 | blk_mq_unfreeze_queue(q); |
| 91 | 95 | ||
| 92 | spin_lock_irq(&q->queue_lock); | 96 | if (ret < 0) { |
| 93 | if (ret < 0) | 97 | spin_lock_irq(&q->queue_lock); |
| 98 | q->rpm_status = RPM_ACTIVE; | ||
| 94 | pm_runtime_mark_last_busy(q->dev); | 99 | pm_runtime_mark_last_busy(q->dev); |
| 95 | else | 100 | spin_unlock_irq(&q->queue_lock); |
| 96 | q->rpm_status = RPM_SUSPENDING; | ||
| 97 | spin_unlock_irq(&q->queue_lock); | ||
| 98 | 101 | ||
| 99 | if (ret) | ||
| 100 | blk_clear_pm_only(q); | 102 | blk_clear_pm_only(q); |
| 103 | } | ||
| 101 | 104 | ||
| 102 | return ret; | 105 | return ret; |
| 103 | } | 106 | } |
| @@ -6,11 +6,14 @@ · 5 unmodified lines | |||
| 6 | #include <linux/pm_runtime.h> | 6 | #include <linux/pm_runtime.h> |
| 7 | 7 | ||
| 8 | #ifdef CONFIG_PM | 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 || | 11 | if (!q->dev || !blk_queue_pm_only(q)) |
| 12 | q->rpm_status == RPM_SUSPENDING)) | 12 | return 1; /* Nothing to do */ |
| 13 | pm_request_resume(q->dev); | 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 | static inline void blk_pm_mark_last_busy(struct request *rq) | 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 | --rq->q->nr_pending; | 47 | --rq->q->nr_pending; |
| 45 | } | 48 | } |
| 46 | #else | 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 | static inline void blk_pm_mark_last_busy(struct request *rq) | 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 | part = rcu_dereference(ptbl->part[piter->idx]); | 246 | part = rcu_dereference(ptbl->part[piter->idx]); |
| 247 | if (!part) | 247 | if (!part) |
| 248 | continue; | 248 | continue; |
| 249 | piter->part = bdgrab(part); | ||
| 250 | if (!piter->part) | ||
| 251 | continue; | ||
| 249 | if (!bdev_nr_sectors(part) && | 252 | if (!bdev_nr_sectors(part) && |
| 250 | !(piter->flags & DISK_PITER_INCL_EMPTY) && | 253 | !(piter->flags & DISK_PITER_INCL_EMPTY) && |
| 251 | !(piter->flags & DISK_PITER_INCL_EMPTY_PART0 && | 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 | continue; | 258 | continue; |
| 259 | } | ||
| 254 | 260 | ||
| 255 | piter->part = bdgrab(part); | ||
| 256 | if (!piter->part) | ||
| 257 | continue; | ||
| 258 | piter->idx += inc; | 261 | piter->idx += inc; |
| 259 | break; | 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 | memcpy(cur, e, sizeof(e)); | 354 | memcpy(cur, e, sizeof(e)); |
| 355 | cur += sizeof(e); | 355 | cur += sizeof(e); |
| 356 | /* Zero parameters to satisfy set_pub_key ABI. */ | 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 | return cur - buf; | 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 | struct ecdh params; | 39 | struct ecdh params; |
| 40 | unsigned int ndigits; | 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 | return -EINVAL; | 44 | return -EINVAL; |
| 44 | 45 | ||
| 45 | ndigits = ecdh_supported_curve(params.curve_id); | 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 | preempt_enable(); | 107 | preempt_enable(); |
| 108 | 108 | ||
| 109 | // bytes/ns == GB/s, multiply by 1000 to get MB/s [not MiB/s] | 109 | // bytes/ns == GB/s, multiply by 1000 to get MB/s [not MiB/s] |
| 110 | if (!min) | ||
| 111 | min = 1; | ||
| 110 | speed = (1000 * REPS * BENCH_SIZE) / (unsigned int)ktime_to_ns(min); | 112 | speed = (1000 * REPS * BENCH_SIZE) / (unsigned int)ktime_to_ns(min); |
| 111 | tmpl->speed = speed; | 113 | tmpl->speed = speed; |
| 112 | 114 | ||
| @@ -395,9 +395,6 @@ config ACPI_CONTAINER · 394 unmodified lines | |||
| 395 | 395 | ||
| 396 | This helps support hotplug of nodes, CPUs, and memory. | 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 | config ACPI_HOTPLUG_MEMORY | 398 | config ACPI_HOTPLUG_MEMORY |
| 402 | bool "Memory Hotplug" | 399 | bool "Memory Hotplug" |
| 403 | depends on MEMORY_HOTPLUG | 400 | depends on MEMORY_HOTPLUG |
| @@ -411,9 +408,6 @@ config ACPI_HOTPLUG_MEMORY · 7 unmodified lines | |||
| 411 | removing memory devices at runtime, you need not enable | 408 | removing memory devices at runtime, you need not enable |
| 412 | this driver. | 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 | config ACPI_HOTPLUG_IOAPIC | 411 | config ACPI_HOTPLUG_IOAPIC |
| 418 | bool | 412 | bool |
| 419 | depends on PCI | 413 | depends on PCI |
| @@ -97,7 +97,7 @@ void acpi_scan_table_handler(u32 event, void *table, void *context); · 96 unmodified lines | |||
| 97 | extern struct list_head acpi_bus_id_list; | 97 | extern struct list_head acpi_bus_id_list; |
| 98 | 98 | ||
| 99 | struct acpi_device_bus_id { | 99 | struct acpi_device_bus_id { |
| 100 | char bus_id[15]; | 100 | const char *bus_id; |
| 101 | unsigned int instance_no; | 101 | unsigned int instance_no; |
| 102 | struct list_head node; | 102 | struct list_head node; |
| 103 | }; | 103 | }; |
| @@ -486,6 +486,7 @@ static void acpi_device_del(struct acpi_device *device) · 485 unmodified lines | |||
| 486 | acpi_device_bus_id->instance_no--; | 486 | acpi_device_bus_id->instance_no--; |
| 487 | else { | 487 | else { |
| 488 | list_del(&acpi_device_bus_id->node); | 488 | list_del(&acpi_device_bus_id->node); |
| 489 | kfree_const(acpi_device_bus_id->bus_id); | ||
| 489 | kfree(acpi_device_bus_id); | 490 | kfree(acpi_device_bus_id); |
| 490 | } | 491 | } |
| 491 | break; | 492 | break; |
| @@ -674,7 +675,14 @@ int acpi_device_add(struct acpi_device *device, · 182 unmodified lines | |||
| 674 | } | 675 | } |
| 675 | if (!found) { | 676 | if (!found) { |
| 676 | acpi_device_bus_id = new_bus_id; | 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 | acpi_device_bus_id->instance_no = 0; | 686 | acpi_device_bus_id->instance_no = 0; |
| 679 | list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); | 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 | if (device->parent) | 717 | if (device->parent) |
| 710 | list_del(&device->node); | 718 | list_del(&device->node); |
| 711 | list_del(&device->wakeup_list); | 719 | list_del(&device->wakeup_list); |
| 720 | |||
| 721 | err_free_new_bus_id: | ||
| 722 | if (!found) | ||
| 723 | kfree(new_bus_id); | ||
| 724 | |||
| 712 | mutex_unlock(&acpi_device_lock); | 725 | mutex_unlock(&acpi_device_lock); |
| 713 | 726 | ||
| 714 | err_detach: | 727 | err_detach: |
| @@ -105,18 +105,8 @@ static void lpi_device_get_constraints_amd(void) · 104 unmodified lines | |||
| 105 | 105 | ||
| 106 | for (i = 0; i < out_obj->package.count; i++) { | 106 | for (i = 0; i < out_obj->package.count; i++) { |
| 107 | union acpi_object *package = &out_obj->package.elements[i]; | 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) { | 109 | if (package->type == ACPI_TYPE_PACKAGE) { |
| 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) { | ||
| 120 | lpi_constraints_table = kcalloc(package->package.count, | 110 | lpi_constraints_table = kcalloc(package->package.count, |
| 121 | sizeof(*lpi_constraints_table), | 111 | sizeof(*lpi_constraints_table), |
| 122 | GFP_KERNEL); | 112 | GFP_KERNEL); |
| @@ -135,12 +125,10 @@ static void lpi_device_get_constraints_amd(void) · 12 unmodified lines | |||
| 135 | 125 | ||
| 136 | for (k = 0; k < info_obj->package.count; ++k) { | 126 | for (k = 0; k < info_obj->package.count; ++k) { |
| 137 | union acpi_object *obj = &info_obj->package.elements[k]; | 127 | union acpi_object *obj = &info_obj->package.elements[k]; |
| 138 | union acpi_object *obj_new; | ||
| 139 | 128 | ||
| 140 | list = &lpi_constraints_table[lpi_constraints_table_size]; | 129 | list = &lpi_constraints_table[lpi_constraints_table_size]; |
| 141 | list->min_dstate = -1; | 130 | list->min_dstate = -1; |
| 142 | 131 | ||
| 143 | obj_new = &obj[k]; | ||
| 144 | switch (k) { | 132 | switch (k) { |
| 145 | case 0: | 133 | case 0: |
| 146 | dev_info.enabled = obj->integer.value; | 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 | if ((err = dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32)))) { | 3608 | if ((err = dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32)))) { |
| 3609 | printk("idt77252: can't enable DMA for PCI device at %s\n", pci_name(pcidev)); | 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 | card = kzalloc(sizeof(struct idt77252_dev), GFP_KERNEL); | 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 | * Set the device's firmware node pointer to @fwnode, but if a secondary | 4415 | * Set the device's firmware node pointer to @fwnode, but if a secondary |
| 4416 | * firmware node of the device is present, preserve it. | 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 | void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) | 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 | } else { | 4438 | } else { |
| 4433 | if (fwnode_is_primary(fn)) { | 4439 | if (fwnode_is_primary(fn)) { |
| 4434 | dev->fwnode = fn->secondary; | 4440 | dev->fwnode = fn->secondary; |
| 4441 | /* Set fn->secondary = NULL, so fn remains the primary fwnode */ | ||
| 4435 | if (!(parent && fn == parent->fwnode)) | 4442 | if (!(parent && fn == parent->fwnode)) |
| 4436 | fn->secondary = ERR_PTR(-ENODEV); | 4443 | fn->secondary = NULL; |
| 4437 | } else { | 4444 | } else { |
| 4438 | dev->fwnode = NULL; | 4445 | dev->fwnode = NULL; |
| 4439 | } | 4446 | } |
| @@ -582,8 +582,12 @@ void regmap_debugfs_init(struct regmap *map) · 581 unmodified lines | |||
| 582 | devname = dev_name(map->dev); | 582 | devname = dev_name(map->dev); |
| 583 | 583 | ||
| 584 | if (name) { | 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 | devname, name); | 587 | devname, name); |
| 588 | if (!map->debugfs_name) | ||
| 589 | return; | ||
| 590 | } | ||
| 587 | name = map->debugfs_name; | 591 | name = map->debugfs_name; |
| 588 | } else { | 592 | } else { |
| 589 | name = devname; | 593 | name = devname; |
| @@ -591,9 +595,10 @@ void regmap_debugfs_init(struct regmap *map) · 1 unmodified line | |||
| 591 | 595 | ||
| 592 | if (!strcmp(name, "dummy")) { | 596 | if (!strcmp(name, "dummy")) { |
| 593 | kfree(map->debugfs_name); | 597 | kfree(map->debugfs_name); |
| 594 | |||
| 595 | map->debugfs_name = kasprintf(GFP_KERNEL, "dummy%d", | 598 | map->debugfs_name = kasprintf(GFP_KERNEL, "dummy%d", |
| 596 | dummy_index); | 599 | dummy_index); |
| 600 | if (!map->debugfs_name) | ||
| 601 | return; | ||
| 597 | name = map->debugfs_name; | 602 | name = map->debugfs_name; |
| 598 | dummy_index++; | 603 | dummy_index++; |
| 599 | } | 604 | } |
| @@ -445,6 +445,7 @@ config BLK_DEV_RBD · 444 unmodified lines | |||
| 445 | config BLK_DEV_RSXX | 445 | config BLK_DEV_RSXX |
| 446 | tristate "IBM Flash Adapter 900GB Full Height PCIe Device Driver" | 446 | tristate "IBM Flash Adapter 900GB Full Height PCIe Device Driver" |
| 447 | depends on PCI | 447 | depends on PCI |
| 448 | select CRC32 | ||
| 448 | help | 449 | help |
| 449 | Device driver for IBM's high speed PCIe SSD | 450 | Device driver for IBM's high speed PCIe SSD |
| 450 | storage device: Flash Adapter 900GB Full Height. | 451 | storage device: Flash Adapter 900GB Full Height. |
| @@ -7,6 +7,7 @@ config BLK_DEV_RNBD_CLIENT · 6 unmodified lines | |||
| 7 | tristate "RDMA Network Block Device driver client" | 7 | tristate "RDMA Network Block Device driver client" |
| 8 | depends on INFINIBAND_RTRS_CLIENT | 8 | depends on INFINIBAND_RTRS_CLIENT |
| 9 | select BLK_DEV_RNBD | 9 | select BLK_DEV_RNBD |
| 10 | select SG_POOL | ||
| 10 | help | 11 | help |
| 11 | RNBD client is a network block device driver using rdma transport. | 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 | Lutz Pogrell <lutz.pogrell@cloud.ionos.com> | 90 | Lutz Pogrell <lutz.pogrell@cloud.ionos.com> |
| 91 | Milind Dumbare <Milind.dumbare@gmail.com> | 91 | Milind Dumbare <Milind.dumbare@gmail.com> |
| 92 | Roman Penyaev <roman.penyaev@profitbricks.com> | 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 | init_waitqueue_head(&iu->comp.wait); | 375 | init_waitqueue_head(&iu->comp.wait); |
| 376 | iu->comp.errno = INT_MAX; | 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 | return iu; | 384 | return iu; |
| 379 | } | 385 | } |
| 380 | 386 | ||
| 381 | static void rnbd_put_iu(struct rnbd_clt_session *sess, struct rnbd_iu *iu) | 387 | static void rnbd_put_iu(struct rnbd_clt_session *sess, struct rnbd_iu *iu) |
| 382 | { | 388 | { |
| 383 | if (atomic_dec_and_test(&iu->refcount)) { | 389 | if (atomic_dec_and_test(&iu->refcount)) { |
| 390 | sg_free_table(&iu->sgt); | ||
| 384 | rnbd_put_permit(sess, iu->permit); | 391 | rnbd_put_permit(sess, iu->permit); |
| 385 | kfree(iu); | 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 | iu->buf = NULL; | 494 | iu->buf = NULL; |
| 488 | iu->dev = dev; | 495 | iu->dev = dev; |
| 489 | 496 | ||
| 490 | sg_alloc_table(&iu->sgt, 1, GFP_KERNEL); | ||
| 491 | |||
| 492 | msg.hdr.type = cpu_to_le16(RNBD_MSG_CLOSE); | 497 | msg.hdr.type = cpu_to_le16(RNBD_MSG_CLOSE); |
| 493 | msg.device_id = cpu_to_le32(device_id); | 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 | err = errno; | 507 | err = errno; |
| 503 | } | 508 | } |
| 504 | 509 | ||
| 505 | sg_free_table(&iu->sgt); | ||
| 506 | rnbd_put_iu(sess, iu); | 510 | rnbd_put_iu(sess, iu); |
| 507 | return err; | 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 | iu->buf = rsp; | 579 | iu->buf = rsp; |
| 576 | iu->dev = dev; | 580 | iu->dev = dev; |
| 577 | 581 | ||
| 578 | sg_alloc_table(&iu->sgt, 1, GFP_KERNEL); | ||
| 579 | sg_init_one(iu->sgt.sgl, rsp, sizeof(*rsp)); | 582 | sg_init_one(iu->sgt.sgl, rsp, sizeof(*rsp)); |
| 580 | 583 | ||
| 581 | msg.hdr.type = cpu_to_le16(RNBD_MSG_OPEN); | 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 | err = errno; | 597 | err = errno; |
| 595 | } | 598 | } |
| 596 | 599 | ||
| 597 | sg_free_table(&iu->sgt); | ||
| 598 | rnbd_put_iu(sess, iu); | 600 | rnbd_put_iu(sess, iu); |
| 599 | return err; | 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 | iu->buf = rsp; | 625 | iu->buf = rsp; |
| 624 | iu->sess = sess; | 626 | iu->sess = sess; |
| 625 | |||
| 626 | sg_alloc_table(&iu->sgt, 1, GFP_KERNEL); | ||
| 627 | sg_init_one(iu->sgt.sgl, rsp, sizeof(*rsp)); | 627 | sg_init_one(iu->sgt.sgl, rsp, sizeof(*rsp)); |
| 628 | 628 | ||
| 629 | msg.hdr.type = cpu_to_le16(RNBD_MSG_SESS_INFO); | 629 | msg.hdr.type = cpu_to_le16(RNBD_MSG_SESS_INFO); |
| @@ -650,7 +650,6 @@ put_iu: · 20 unmodified lines | |||
| 650 | } else { | 650 | } else { |
| 651 | err = errno; | 651 | err = errno; |
| 652 | } | 652 | } |
| 653 | sg_free_table(&iu->sgt); | ||
| 654 | rnbd_put_iu(sess, iu); | 653 | rnbd_put_iu(sess, iu); |
| 655 | return err; | 654 | return err; |
| 656 | } | 655 | } |
| @@ -1698,7 +1697,8 @@ static void rnbd_destroy_sessions(void) · 1041 unmodified lines | |||
| 1698 | */ | 1697 | */ |
| 1699 | 1698 | ||
| 1700 | list_for_each_entry_safe(sess, sn, &sess_list, list) { | 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 | close_rtrs(sess); | 1702 | close_rtrs(sess); |
| 1703 | list_for_each_entry_safe(dev, tn, &sess->devs_list, list) { | 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 | void rnbd_srv_sess_dev_force_close(struct rnbd_srv_sess_dev *sess_dev) | 339 | void rnbd_srv_sess_dev_force_close(struct rnbd_srv_sess_dev *sess_dev) |
| 340 | { | 340 | { |
| 341 | mutex_lock(&sess_dev->sess->lock); | 341 | struct rnbd_srv_session *sess = sess_dev->sess; |
| 342 | rnbd_srv_destroy_dev_session_sysfs(sess_dev); | 342 | |
| 343 | mutex_unlock(&sess_dev->sess->lock); | ||
| 344 | sess_dev->keep_id = true; | 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 | static int process_msg_close(struct rtrs_srv *rtrs, | 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 | { TEGRA30_CLK_I2S3_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, | 1256 | { TEGRA30_CLK_I2S3_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, |
| 1257 | { TEGRA30_CLK_I2S4_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, | 1257 | { TEGRA30_CLK_I2S4_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, |
| 1258 | { TEGRA30_CLK_VIMCLK_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, | 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 | /* must be the last entry */ | 1261 | /* must be the last entry */ |
| 1260 | { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 }, | 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 | return ret; | 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 | static inline u64 mul_ext_fp(u64 x, u64 y) | 79 | static inline u64 mul_ext_fp(u64 x, u64 y) |
| 85 | { | 80 | { |
| 86 | return (x * y) >> EXT_FRAC_BITS; | 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 | return div64_u64(x << EXT_FRAC_BITS, y); | 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 | * struct sample - Store performance sample | 90 | * struct sample - Store performance sample |
| 101 | * @core_avg_perf: Ratio of APERF/MPERF which is the actual average | 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 | unsigned long capacity) | 2643 | unsigned long capacity) |
| 2654 | { | 2644 | { |
| 2655 | struct cpudata *cpu = all_cpu_data[cpunum]; | 2645 | struct cpudata *cpu = all_cpu_data[cpunum]; |
| 2646 | u64 hwp_cap = READ_ONCE(cpu->hwp_cap_cached); | ||
| 2656 | int old_pstate = cpu->pstate.current_pstate; | 2647 | int old_pstate = cpu->pstate.current_pstate; |
| 2657 | int cap_pstate, min_pstate, max_pstate, target_pstate; | 2648 | int cap_pstate, min_pstate, max_pstate, target_pstate; |
| 2658 | 2649 | ||
| 2659 | update_turbo_state(); | 2650 | update_turbo_state(); |
| 2660 | cap_pstate = global.turbo_disabled ? cpu->pstate.max_pstate : | 2651 | cap_pstate = global.turbo_disabled ? HWP_GUARANTEED_PERF(hwp_cap) : |
| 2661 | cpu->pstate.turbo_pstate; | 2652 | HWP_HIGHEST_PERF(hwp_cap); |
| 2662 | 2653 | ||
| 2663 | /* Optimization: Avoid unnecessary divisions. */ | 2654 | /* Optimization: Avoid unnecessary divisions. */ |
| 2664 | 2655 | ||
| @@ -3086,7 +3077,6 @@ static int __init intel_pstate_init(void) · 421 unmodified lines | |||
| 3086 | intel_pstate.attr = hwp_cpufreq_attrs; | 3077 | intel_pstate.attr = hwp_cpufreq_attrs; |
| 3087 | intel_cpufreq.attr = hwp_cpufreq_attrs; | 3078 | intel_cpufreq.attr = hwp_cpufreq_attrs; |
| 3088 | intel_cpufreq.flags |= CPUFREQ_NEED_UPDATE_LIMITS; | 3079 | intel_cpufreq.flags |= CPUFREQ_NEED_UPDATE_LIMITS; |
| 3089 | intel_cpufreq.fast_switch = NULL; | ||
| 3090 | intel_cpufreq.adjust_perf = intel_cpufreq_adjust_perf; | 3080 | intel_cpufreq.adjust_perf = intel_cpufreq_adjust_perf; |
| 3091 | if (!default_driver) | 3081 | if (!default_driver) |
| 3092 | default_driver = &intel_pstate; | 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 | /* Take a frequency, and issue the fid/vid transition command */ | 879 | /* Take a frequency, and issue the fid/vid transition command */ |
| 880 | static int transition_frequency_fidvid(struct powernow_k8_data *data, | 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 | u32 fid = 0; | 884 | u32 fid = 0; |
| 885 | u32 vid = 0; | 885 | u32 vid = 0; |
| 886 | int res; | 886 | int res; |
| @@ -912,9 +912,6 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, · 25 unmodified lines | |||
| 912 | freqs.old = find_khz_freq_from_fid(data->currfid); | 912 | freqs.old = find_khz_freq_from_fid(data->currfid); |
| 913 | freqs.new = find_khz_freq_from_fid(fid); | 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 | cpufreq_freq_transition_begin(policy, &freqs); | 915 | cpufreq_freq_transition_begin(policy, &freqs); |
| 919 | res = transition_fid_vid(data, fid, vid); | 916 | res = transition_fid_vid(data, fid, vid); |
| 920 | cpufreq_freq_transition_end(policy, &freqs, res); | 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 | powernow_k8_acpi_pst_values(data, newstate); | 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 | if (ret) { | 971 | if (ret) { |
| 975 | pr_err("transition frequency failed\n"); | 972 | pr_err("transition frequency failed\n"); |
| @@ -366,6 +366,7 @@ if CRYPTO_DEV_OMAP · 365 unmodified lines | |||
| 366 | config CRYPTO_DEV_OMAP_SHAM | 366 | config CRYPTO_DEV_OMAP_SHAM |
| 367 | tristate "Support for OMAP MD5/SHA1/SHA2 hw accelerator" | 367 | tristate "Support for OMAP MD5/SHA1/SHA2 hw accelerator" |
| 368 | depends on ARCH_OMAP2PLUS | 368 | depends on ARCH_OMAP2PLUS |
| 369 | select CRYPTO_ENGINE | ||
| 369 | select CRYPTO_SHA1 | 370 | select CRYPTO_SHA1 |
| 370 | select CRYPTO_MD5 | 371 | select CRYPTO_MD5 |
| 371 | select CRYPTO_SHA256 | 372 | select CRYPTO_SHA256 |
| @@ -76,10 +76,6 @@ static void dma_buf_release(struct dentry *dentry) · 75 unmodified lines | |||
| 76 | 76 | ||
| 77 | dmabuf->ops->release(dmabuf); | 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 | if (dmabuf->resv == (struct dma_resv *)&dmabuf[1]) | 79 | if (dmabuf->resv == (struct dma_resv *)&dmabuf[1]) |
| 84 | dma_resv_fini(dmabuf->resv); | 80 | dma_resv_fini(dmabuf->resv); |
| 85 | 81 | ||
| @@ -88,6 +84,22 @@ static void dma_buf_release(struct dentry *dentry) · 2 unmodified lines | |||
| 88 | kfree(dmabuf); | 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 | static const struct dentry_operations dma_buf_dentry_ops = { | 103 | static const struct dentry_operations dma_buf_dentry_ops = { |
| 92 | .d_dname = dmabuffs_dname, | 104 | .d_dname = dmabuffs_dname, |
| 93 | .d_release = dma_buf_release, | 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 | static const struct file_operations dma_buf_fops = { | 427 | static const struct file_operations dma_buf_fops = { |
| 428 | .release = dma_buf_file_release, | ||
| 416 | .mmap = dma_buf_mmap_internal, | 429 | .mmap = dma_buf_mmap_internal, |
| 417 | .llseek = dma_buf_llseek, | 430 | .llseek = dma_buf_llseek, |
| 418 | .poll = dma_buf_poll, | 431 | .poll = dma_buf_poll, |
| @@ -251,6 +251,9 @@ static void cma_heap_dma_buf_release(struct dma_buf *dmabuf) · 250 unmodified lines | |||
| 251 | buffer->vaddr = NULL; | 251 | buffer->vaddr = NULL; |
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | /* free page list */ | ||
| 255 | kfree(buffer->pages); | ||
| 256 | /* release memory */ | ||
| 254 | cma_release(cma_heap->cma, buffer->cma_pages, buffer->pagecount); | 257 | cma_release(cma_heap->cma, buffer->cma_pages, buffer->pagecount); |
| 255 | kfree(buffer); | 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 | if (desc->chunk) { | 87 | if (desc->chunk) { |
| 88 | /* Create and add new element into the linked list */ | 88 | /* Create and add new element into the linked list */ |
| 89 | desc->chunks_alloc++; | ||
| 90 | list_add_tail(&chunk->list, &desc->chunk->list); | ||
| 91 | if (!dw_edma_alloc_burst(chunk)) { | 89 | if (!dw_edma_alloc_burst(chunk)) { |
| 92 | kfree(chunk); | 90 | kfree(chunk); |
| 93 | return NULL; | 91 | return NULL; |
| 94 | } | 92 | } |
| 93 | desc->chunks_alloc++; | ||
| 94 | list_add_tail(&chunk->list, &desc->chunk->list); | ||
| 95 | } else { | 95 | } else { |
| 96 | /* List head */ | 96 | /* List head */ |
| 97 | chunk->burst = NULL; | 97 | chunk->burst = NULL; |
| @@ -434,7 +434,7 @@ int idxd_register_driver(void) · 433 unmodified lines | |||
| 434 | return 0; | 434 | return 0; |
| 435 | 435 | ||
| 436 | drv_fail: | 436 | drv_fail: |
| 437 | for (; i > 0; i--) | 437 | while (--i >= 0) |
| 438 | driver_unregister(&idxd_drvs[i]->drv); | 438 | driver_unregister(&idxd_drvs[i]->drv); |
| 439 | return rc; | 439 | return rc; |
| 440 | } | 440 | } |
| @@ -1840,7 +1840,7 @@ int idxd_register_bus_type(void) · 1399 unmodified lines | |||
| 1840 | return 0; | 1840 | return 0; |
| 1841 | 1841 | ||
| 1842 | bus_err: | 1842 | bus_err: |
| 1843 | for (; i > 0; i--) | 1843 | while (--i >= 0) |
| 1844 | bus_unregister(idxd_bus_types[i]); | 1844 | bus_unregister(idxd_bus_types[i]); |
| 1845 | return rc; | 1845 | return rc; |
| 1846 | } | 1846 | } |
| @@ -1007,6 +1007,7 @@ static int mtk_hsdma_probe(struct platform_device *pdev) · 1006 unmodified lines | |||
| 1007 | return 0; | 1007 | return 0; |
| 1008 | 1008 | ||
| 1009 | err_free: | 1009 | err_free: |
| 1010 | mtk_hsdma_hw_deinit(hsdma); | ||
| 1010 | of_dma_controller_free(pdev->dev.of_node); | 1011 | of_dma_controller_free(pdev->dev.of_node); |
| 1011 | err_unregister: | 1012 | err_unregister: |
| 1012 | dma_async_device_unregister(dd); | 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 | ret = dma_async_device_register(ddev); | 351 | ret = dma_async_device_register(ddev); |
| 352 | if (ret) | 352 | if (ret) |
| 353 | return ret; | 353 | goto disable_xdmac; |
| 354 | 354 | ||
| 355 | ret = of_dma_controller_register(dev->of_node, | 355 | ret = of_dma_controller_register(dev->of_node, |
| 356 | of_dma_simple_xlate, mdev); | 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 | unregister_dmac: | 364 | unregister_dmac: |
| 365 | dma_async_device_unregister(ddev); | 365 | dma_async_device_unregister(ddev); |
| 366 | disable_xdmac: | ||
| 367 | disable_xdmac(mdev); | ||
| 366 | return ret; | 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 | GFP_NOWAIT); | 630 | GFP_NOWAIT); |
| 631 | 631 | ||
| 632 | if (!async_desc) | 632 | if (!async_desc) |
| 633 | goto err_out; | 633 | return NULL; |
| 634 | 634 | ||
| 635 | if (flags & DMA_PREP_FENCE) | 635 | if (flags & DMA_PREP_FENCE) |
| 636 | async_desc->flags |= DESC_FLAG_NWD; | 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 | return vchan_tx_prep(&bchan->vc, &async_desc->vd, flags); | 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 | len = 1 << bit; | 1416 | len = 1 << bit; |
| 1417 | ring->alloc_size = (len + (len - 1)); | 1417 | ring->alloc_size = (len + (len - 1)); |
| 1418 | dev_dbg(gpii->gpi_dev->dev, | 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 | elements, el_size, (elements * el_size), len, | 1420 | elements, el_size, (elements * el_size), len, |
| 1421 | ring->alloc_size); | 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 | ring->alloc_size, | 1424 | ring->alloc_size, |
| 1425 | &ring->dma_handle, GFP_KERNEL); | 1425 | &ring->dma_handle, GFP_KERNEL); |
| 1426 | if (!ring->pre_aligned) { | 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 | ring->alloc_size); | 1428 | ring->alloc_size); |
| 1429 | return -ENOMEM; | 1429 | return -ENOMEM; |
| 1430 | } | 1430 | } |
| @@ -1444,8 +1444,8 @@ static int gpi_alloc_ring(struct gpi_ring *ring, u32 elements, · 13 unmodified lines | |||
| 1444 | smp_wmb(); | 1444 | smp_wmb(); |
| 1445 | 1445 | ||
| 1446 | dev_dbg(gpii->gpi_dev->dev, | 1446 | dev_dbg(gpii->gpi_dev->dev, |
| 1447 | "phy_pre:0x%0llx phy_alig:0x%0llx len:%u el_size:%u elements:%u\n", | 1447 | "phy_pre:%pad phy_alig:%pa len:%u el_size:%u elements:%u\n", |
| 1448 | ring->dma_handle, ring->phys_addr, ring->len, | 1448 | &ring->dma_handle, &ring->phys_addr, ring->len, |
| 1449 | ring->el_size, ring->elements); | 1449 | ring->el_size, ring->elements); |
| 1450 | 1450 | ||
| 1451 | return 0; | 1451 | return 0; |
| @@ -1948,7 +1948,7 @@ static int gpi_ch_init(struct gchan *gchan) · 496 unmodified lines | |||
| 1948 | return ret; | 1948 | return ret; |
| 1949 | 1949 | ||
| 1950 | error_start_chan: | 1950 | error_start_chan: |
| 1951 | for (i = i - 1; i >= 0; i++) { | 1951 | for (i = i - 1; i >= 0; i--) { |
| 1952 | gpi_stop_chan(&gpii->gchan[i]); | 1952 | gpi_stop_chan(&gpii->gchan[i]); |
| 1953 | gpi_send_cmd(gpii, gchan, GPI_CH_CMD_RESET); | 1953 | gpi_send_cmd(gpii, gchan, GPI_CH_CMD_RESET); |
| 1954 | } | 1954 | } |
| @@ -199,7 +199,7 @@ · 198 unmodified lines | |||
| 199 | #define STM32_MDMA_MAX_CHANNELS 63 | 199 | #define STM32_MDMA_MAX_CHANNELS 63 |
| 200 | #define STM32_MDMA_MAX_REQUESTS 256 | 200 | #define STM32_MDMA_MAX_REQUESTS 256 |
| 201 | #define STM32_MDMA_MAX_BURST 128 | 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 | enum stm32_mdma_trigger_mode { | 204 | enum stm32_mdma_trigger_mode { |
| 205 | STM32_MDMA_BUFFER, | 205 | STM32_MDMA_BUFFER, |
| @@ -4698,9 +4698,9 @@ static int pktdma_setup_resources(struct udma_dev *ud) · 4697 unmodified lines | |||
| 4698 | ud->tchan_tpl.levels = 1; | 4698 | ud->tchan_tpl.levels = 1; |
| 4699 | } | 4699 | } |
| 4700 | 4700 | ||
| 4701 | ud->tchan_tpl.levels = ud->tchan_tpl.levels; | 4701 | ud->rchan_tpl.levels = ud->tchan_tpl.levels; |
| 4702 | ud->tchan_tpl.start_idx[0] = ud->tchan_tpl.start_idx[0]; | 4702 | ud->rchan_tpl.start_idx[0] = ud->tchan_tpl.start_idx[0]; |
| 4703 | ud->tchan_tpl.start_idx[1] = ud->tchan_tpl.start_idx[1]; | 4703 | ud->rchan_tpl.start_idx[1] = ud->tchan_tpl.start_idx[1]; |
| 4704 | 4704 | ||
| 4705 | ud->tchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tchan_cnt), | 4705 | ud->tchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tchan_cnt), |
| 4706 | sizeof(unsigned long), GFP_KERNEL); | 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 | has_dre = false; | 2781 | has_dre = false; |
| 2782 | 2782 | ||
| 2783 | if (!has_dre) | 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 | if (of_device_is_compatible(node, "xlnx,axi-vdma-mm2s-channel") || | 2786 | if (of_device_is_compatible(node, "xlnx,axi-vdma-mm2s-channel") || |
| 2787 | of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel") || | 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 | static int xilinx_dma_child_probe(struct xilinx_dma_device *xdev, | 2900 | static int xilinx_dma_child_probe(struct xilinx_dma_device *xdev, |
| 2901 | struct device_node *node) | 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 | ret = of_property_read_u32(node, "dma-channels", &nr_channels); | 2906 | ret = of_property_read_u32(node, "dma-channels", &nr_channels); |
| 2906 | if (xdev->dma_config->dmatype == XDMA_TYPE_AXIMCDMA && ret < 0) | 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 | /* Register the DMA engine with the core */ | 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 | err = of_dma_controller_register(node, of_dma_xilinx_xlate, | 3122 | err = of_dma_controller_register(node, of_dma_xilinx_xlate, |
| 3118 | xdev); | 3123 | xdev); |
| @@ -112,6 +112,7 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev) · 111 unmodified lines | |||
| 112 | union igp_info { | 112 | union igp_info { |
| 113 | struct atom_integrated_system_info_v1_11 v11; | 113 | struct atom_integrated_system_info_v1_11 v11; |
| 114 | struct atom_integrated_system_info_v1_12 v12; | 114 | struct atom_integrated_system_info_v1_12 v12; |
| 115 | struct atom_integrated_system_info_v2_1 v21; | ||
| 115 | }; | 116 | }; |
| 116 | 117 | ||
| 117 | union umc_info { | 118 | union umc_info { |
| @@ -209,24 +210,42 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev, · 91 unmodified lines | |||
| 209 | if (adev->flags & AMD_IS_APU) { | 210 | if (adev->flags & AMD_IS_APU) { |
| 210 | igp_info = (union igp_info *) | 211 | igp_info = (union igp_info *) |
| 211 | (mode_info->atom_context->bios + data_offset); | 212 | (mode_info->atom_context->bios + data_offset); |
| 212 | switch (crev) { | 213 | switch (frev) { |
| 213 | case 11: | 214 | case 1: |
| 214 | mem_channel_number = igp_info->v11.umachannelnumber; | 215 | switch (crev) { |
| 215 | /* channel width is 64 */ | 216 | case 11: |
| 216 | if (vram_width) | 217 | case 12: |
| 217 | *vram_width = mem_channel_number * 64; | 218 | mem_channel_number = igp_info->v11.umachannelnumber; |
| 218 | mem_type = igp_info->v11.memorytype; | 219 | if (!mem_channel_number) |
| 219 | if (vram_type) | 220 | mem_channel_number = 1; |
| 220 | *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); | 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 | break; | 231 | break; |
| 222 | case 12: | 232 | case 2: |
| 223 | mem_channel_number = igp_info->v12.umachannelnumber; | 233 | switch (crev) { |
| 224 | /* channel width is 64 */ | 234 | case 1: |
| 225 | if (vram_width) | 235 | case 2: |
| 226 | *vram_width = mem_channel_number * 64; | 236 | mem_channel_number = igp_info->v21.umachannelnumber; |
| 227 | mem_type = igp_info->v12.memorytype; | 237 | if (!mem_channel_number) |
| 228 | if (vram_type) | 238 | mem_channel_number = 1; |
| 229 | *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); | 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 | break; | 249 | break; |
| 231 | default: | 250 | default: |
| 232 | return -EINVAL; | 251 | return -EINVAL; |
| @@ -2548,11 +2548,11 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) · 2547 unmodified lines | |||
| 2548 | if (adev->gmc.xgmi.num_physical_nodes > 1) | 2548 | if (adev->gmc.xgmi.num_physical_nodes > 1) |
| 2549 | amdgpu_xgmi_remove_device(adev); | 2549 | amdgpu_xgmi_remove_device(adev); |
| 2550 | 2550 | ||
| 2551 | amdgpu_amdkfd_device_fini(adev); | ||
| 2552 | |||
| 2553 | amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE); | 2551 | amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE); |
| 2554 | amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE); | 2552 | amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE); |
| 2555 | 2553 | ||
| 2554 | amdgpu_amdkfd_device_fini(adev); | ||
| 2555 | |||
| 2556 | /* need to disable SMC first */ | 2556 | /* need to disable SMC first */ |
| 2557 | for (i = 0; i < adev->num_ip_blocks; i++) { | 2557 | for (i = 0; i < adev->num_ip_blocks; i++) { |
| 2558 | if (!adev->ip_blocks[i].status.hw) | 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 | #endif | 3034 | #endif |
| 3035 | default: | 3035 | default: |
| 3036 | if (amdgpu_dc > 0) | 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 | "but isn't supported by ASIC, ignoring\n"); | 3038 | "but isn't supported by ASIC, ignoring\n"); |
| 3039 | return false; | 3039 | return false; |
| 3040 | } | 3040 | } |
| @@ -1085,6 +1085,8 @@ static const struct pci_device_id pciidlist[] = { · 1084 unmodified lines | |||
| 1085 | 1085 | ||
| 1086 | /* Renoir */ | 1086 | /* Renoir */ |
| 1087 | {0x1002, 0x1636, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU}, | 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 | /* Navi12 */ | 1091 | /* Navi12 */ |
| 1090 | {0x1002, 0x7360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI12}, | 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 | * add workaround to bypass it for sriov now. | 563 | * add workaround to bypass it for sriov now. |
| 564 | * TODO: add version check to make it common | 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 | return 0; | 567 | return 0; |
| 568 | 568 | ||
| 569 | cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); | 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 | if (amdgpu_sriov_vf(psp->adev)) | 1315 | if (amdgpu_sriov_vf(psp->adev)) |
| 1316 | return 0; | 1316 | return 0; |
| 1317 | 1317 | ||
| 1318 | if (!psp->hdcp_context.hdcp_initialized) | 1318 | if (!psp->hdcp_context.hdcp_initialized) { |
| 1319 | return 0; | 1319 | if (psp->hdcp_context.hdcp_shared_buf) |
| 1320 | goto out; | ||
| 1321 | else | ||
| 1322 | return 0; | ||
| 1323 | } | ||
| 1320 | 1324 | ||
| 1321 | ret = psp_hdcp_unload(psp); | 1325 | ret = psp_hdcp_unload(psp); |
| 1322 | if (ret) | 1326 | if (ret) |
| @@ -1324,6 +1328,7 @@ static int psp_hdcp_terminate(struct psp_context *psp) · 1 unmodified line | |||
| 1324 | 1328 | ||
| 1325 | psp->hdcp_context.hdcp_initialized = false; | 1329 | psp->hdcp_context.hdcp_initialized = false; |
| 1326 | 1330 | ||
| 1331 | out: | ||
| 1327 | /* free hdcp shared memory */ | 1332 | /* free hdcp shared memory */ |
| 1328 | amdgpu_bo_free_kernel(&psp->hdcp_context.hdcp_shared_bo, | 1333 | amdgpu_bo_free_kernel(&psp->hdcp_context.hdcp_shared_bo, |
| 1329 | &psp->hdcp_context.hdcp_shared_mc_addr, | 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 | if (amdgpu_sriov_vf(psp->adev)) | 1467 | if (amdgpu_sriov_vf(psp->adev)) |
| 1463 | return 0; | 1468 | return 0; |
| 1464 | 1469 | ||
| 1465 | if (!psp->dtm_context.dtm_initialized) | 1470 | if (!psp->dtm_context.dtm_initialized) { |
| 1466 | return 0; | 1471 | if (psp->dtm_context.dtm_shared_buf) |
| 1472 | goto out; | ||
| 1473 | else | ||
| 1474 | return 0; | ||
| 1475 | } | ||
| 1467 | 1476 | ||
| 1468 | ret = psp_dtm_unload(psp); | 1477 | ret = psp_dtm_unload(psp); |
| 1469 | if (ret) | 1478 | if (ret) |
| @@ -1471,6 +1480,7 @@ static int psp_dtm_terminate(struct psp_context *psp) · 1 unmodified line | |||
| 1471 | 1480 | ||
| 1472 | psp->dtm_context.dtm_initialized = false; | 1481 | psp->dtm_context.dtm_initialized = false; |
| 1473 | 1482 | ||
| 1483 | out: | ||
| 1474 | /* free hdcp shared memory */ | 1484 | /* free hdcp shared memory */ |
| 1475 | amdgpu_bo_free_kernel(&psp->dtm_context.dtm_shared_bo, | 1485 | amdgpu_bo_free_kernel(&psp->dtm_context.dtm_shared_bo, |
| 1476 | &psp->dtm_context.dtm_shared_mc_addr, | 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 | switch (desc->fw_type) { | 2600 | switch (desc->fw_type) { |
| 2591 | case TA_FW_TYPE_PSP_ASD: | 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 | psp->asd_feature_version = le32_to_cpu(desc->fw_version); | 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 | psp->asd_start_addr = ucode_start_addr; | 2605 | psp->asd_start_addr = ucode_start_addr; |
| 2596 | psp->asd_fw = psp->ta_fw; | ||
| 2597 | break; | 2606 | break; |
| 2598 | case TA_FW_TYPE_PSP_XGMI: | 2607 | case TA_FW_TYPE_PSP_XGMI: |
| 2599 | psp->ta_xgmi_ucode_version = le32_to_cpu(desc->fw_version); | 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 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); | 1518 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
| 1519 | struct ras_err_handler_data *data; | 1519 | struct ras_err_handler_data *data; |
| 1520 | int i = 0; | 1520 | int i = 0; |
| 1521 | int ret = 0; | 1521 | int ret = 0, status; |
| 1522 | 1522 | ||
| 1523 | if (!con || !con->eh_data || !bps || !count) | 1523 | if (!con || !con->eh_data || !bps || !count) |
| 1524 | return -EINVAL; | 1524 | return -EINVAL; |
| @@ -1543,12 +1543,12 @@ static int amdgpu_ras_badpages_read(struct amdgpu_device *adev, · 18 unmodified lines | |||
| 1543 | .size = AMDGPU_GPU_PAGE_SIZE, | 1543 | .size = AMDGPU_GPU_PAGE_SIZE, |
| 1544 | .flags = AMDGPU_RAS_RETIRE_PAGE_RESERVED, | 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 | ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM), | 1547 | ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM), |
| 1548 | data->bps[i].retired_page); | 1548 | data->bps[i].retired_page); |
| 1549 | if (ret == -EBUSY) | 1549 | if (status == -EBUSY) |
| 1550 | (*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_PENDING; | 1550 | (*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_PENDING; |
| 1551 | else if (ret == -ENOENT) | 1551 | else if (status == -ENOENT) |
| 1552 | (*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_FAULT; | 1552 | (*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_FAULT; |
| 1553 | } | 1553 | } |
| 1554 | 1554 | ||
| @@ -30,6 +30,7 @@ · 29 unmodified lines | |||
| 30 | #define EEPROM_I2C_TARGET_ADDR_VEGA20 0xA0 | 30 | #define EEPROM_I2C_TARGET_ADDR_VEGA20 0xA0 |
| 31 | #define EEPROM_I2C_TARGET_ADDR_ARCTURUS 0xA8 | 31 | #define EEPROM_I2C_TARGET_ADDR_ARCTURUS 0xA8 |
| 32 | #define EEPROM_I2C_TARGET_ADDR_ARCTURUS_D342 0xA0 | 32 | #define EEPROM_I2C_TARGET_ADDR_ARCTURUS_D342 0xA0 |
| 33 | #define EEPROM_I2C_TARGET_ADDR_SIENNA_CICHLID 0xA0 | ||
| 33 | 34 | ||
| 34 | /* | 35 | /* |
| 35 | * The 2 macros bellow represent the actual size in bytes that | 36 | * The 2 macros bellow represent the actual size in bytes that |
| @@ -62,7 +63,8 @@ · 26 unmodified lines | |||
| 62 | static bool __is_ras_eeprom_supported(struct amdgpu_device *adev) | 63 | static bool __is_ras_eeprom_supported(struct amdgpu_device *adev) |
| 63 | { | 64 | { |
| 64 | if ((adev->asic_type == CHIP_VEGA20) || | 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 | return true; | 68 | return true; |
| 67 | 69 | ||
| 68 | return false; | 70 | return false; |
| @@ -100,6 +102,10 @@ static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev, · 31 unmodified lines | |||
| 100 | case CHIP_ARCTURUS: | 102 | case CHIP_ARCTURUS: |
| 101 | return __get_eeprom_i2c_addr_arct(adev, i2c_addr); | 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 | default: | 109 | default: |
| 104 | return false; | 110 | return false; |
| 105 | } | 111 | } |
| @@ -99,6 +99,10 @@ · 98 unmodified lines | |||
| 99 | #define mmGCR_GENERAL_CNTL_Sienna_Cichlid 0x1580 | 99 | #define mmGCR_GENERAL_CNTL_Sienna_Cichlid 0x1580 |
| 100 | #define mmGCR_GENERAL_CNTL_Sienna_Cichlid_BASE_IDX 0 | 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 | #define mmSPI_CONFIG_CNTL_1_Vangogh 0x2441 | 106 | #define mmSPI_CONFIG_CNTL_1_Vangogh 0x2441 |
| 103 | #define mmSPI_CONFIG_CNTL_1_Vangogh_BASE_IDX 1 | 107 | #define mmSPI_CONFIG_CNTL_1_Vangogh_BASE_IDX 1 |
| 104 | #define mmVGT_TF_MEMORY_BASE_HI_Vangogh 0x2261 | 108 | #define mmVGT_TF_MEMORY_BASE_HI_Vangogh 0x2261 |
| @@ -160,6 +164,9 @@ · 55 unmodified lines | |||
| 160 | #define mmGCVM_L2_CGTT_CLK_CTRL_Sienna_Cichlid 0x15db | 164 | #define mmGCVM_L2_CGTT_CLK_CTRL_Sienna_Cichlid 0x15db |
| 161 | #define mmGCVM_L2_CGTT_CLK_CTRL_Sienna_Cichlid_BASE_IDX 0 | 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 | MODULE_FIRMWARE("amdgpu/navi10_ce.bin"); | 170 | MODULE_FIRMWARE("amdgpu/navi10_ce.bin"); |
| 164 | MODULE_FIRMWARE("amdgpu/navi10_pfp.bin"); | 171 | MODULE_FIRMWARE("amdgpu/navi10_pfp.bin"); |
| 165 | MODULE_FIRMWARE("amdgpu/navi10_me.bin"); | 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 | static void gfx_v10_0_ring_emit_frame_cntl(struct amdgpu_ring *ring, bool start, bool secure); | 3331 | static void gfx_v10_0_ring_emit_frame_cntl(struct amdgpu_ring *ring, bool start, bool secure); |
| 3325 | static u32 gfx_v10_3_get_disabled_sa(struct amdgpu_device *adev); | 3332 | static u32 gfx_v10_3_get_disabled_sa(struct amdgpu_device *adev); |
| 3326 | static void gfx_v10_3_program_pbb_mode(struct amdgpu_device *adev); | 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 | static void gfx10_kiq_set_resources(struct amdgpu_ring *kiq_ring, uint64_t queue_mask) | 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 | if (adev->asic_type == CHIP_SIENNA_CICHLID) | 7200 | if (adev->asic_type == CHIP_SIENNA_CICHLID) |
| 7193 | gfx_v10_3_program_pbb_mode(adev); | 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 | return r; | 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 | amdgpu_gfx_off_ctrl(adev, false); | 7389 | amdgpu_gfx_off_ctrl(adev, false); |
| 7379 | mutex_lock(&adev->gfx.gpu_clock_mutex); | 7390 | mutex_lock(&adev->gfx.gpu_clock_mutex); |
| 7380 | clock = (uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER) | | 7391 | switch (adev->asic_type) { |
| 7381 | ((uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER) << 32ULL); | 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 | mutex_unlock(&adev->gfx.gpu_clock_mutex); | 7401 | mutex_unlock(&adev->gfx.gpu_clock_mutex); |
| 7383 | amdgpu_gfx_off_ctrl(adev, true); | 7402 | amdgpu_gfx_off_ctrl(adev, true); |
| 7384 | return clock; | 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 | const struct amdgpu_ip_block_version gfx_v10_0_ip_block = | 9216 | const struct amdgpu_ip_block_version gfx_v10_0_ip_block = |
| 9173 | { | 9217 | { |
| 9174 | .type = AMD_IP_BLOCK_TYPE_GFX, | 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 | /* Send no-retry XNACK on fault to suppress VM fault storm. */ | 310 | /* Send no-retry XNACK on fault to suppress VM fault storm. */ |
| 311 | tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, | 311 | tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, |
| 312 | RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, | 312 | RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, |
| 313 | !amdgpu_noretry); | 313 | !adev->gmc.noretry); |
| 314 | WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_CNTL, | 314 | WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_CNTL, |
| 315 | i * hub->ctx_distance, tmp); | 315 | i * hub->ctx_distance, tmp); |
| 316 | WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32, | 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 | GFX_CTRL_CMD_ID_DISABLE_INT = 0x00060000, /* disable PSP-to-Gfx interrupt */ | 47 | GFX_CTRL_CMD_ID_DISABLE_INT = 0x00060000, /* disable PSP-to-Gfx interrupt */ |
| 48 | GFX_CTRL_CMD_ID_MODE1_RST = 0x00070000, /* trigger the Mode 1 reset */ | 48 | GFX_CTRL_CMD_ID_MODE1_RST = 0x00070000, /* trigger the Mode 1 reset */ |
| 49 | GFX_CTRL_CMD_ID_GBR_IH_SET = 0x00080000, /* set Gbr IH_RB_CNTL registers */ | 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 | GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING = 0x000C0000, /* destroy GPCOM ring */ | 51 | GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING = 0x000C0000, /* destroy GPCOM ring */ |
| 52 | 52 | ||
| 53 | GFX_CTRL_CMD_ID_MAX = 0x000F0000, /* max command ID */ | 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 | break; | 1239 | break; |
| 1240 | case CHIP_RENOIR: | 1240 | case CHIP_RENOIR: |
| 1241 | adev->asic_funcs = &soc15_asic_funcs; | 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 | adev->apu_flags |= AMD_APU_IS_RENOIR; | 1244 | adev->apu_flags |= AMD_APU_IS_RENOIR; |
| 1244 | else | 1245 | else |
| 1245 | adev->apu_flags |= AMD_APU_IS_GREEN_SARDINE; | 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 | (struct crat_subtype_iolink *)sub_type_hdr); | 1040 | (struct crat_subtype_iolink *)sub_type_hdr); |
| 1041 | if (ret < 0) | 1041 | if (ret < 0) |
| 1042 | return ret; | 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 + | 1044 | if (entries) { |
| 1047 | sub_type_hdr->length * 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 | #else | 1051 | #else |
| 1049 | pr_info("IO link not available for non x86 platforms\n"); | 1052 | pr_info("IO link not available for non x86 platforms\n"); |
| 1050 | #endif | 1053 | #endif |
| @@ -6,7 +6,7 @@ config DRM_AMD_DC · 5 unmodified lines | |||
| 6 | bool "AMD DC - Enable new display engine" | 6 | bool "AMD DC - Enable new display engine" |
| 7 | default y | 7 | default y |
| 8 | select SND_HDA_COMPONENT if SND_HDA_CORE | 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 | help | 10 | help |
| 11 | Choose this option if you want to use the new display engine | 11 | Choose this option if you want to use the new display engine |
| 12 | support for AMDGPU. This adds required support for Vega and | 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 | #endif | 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 | static int amdgpu_dm_init(struct amdgpu_device *adev) | 942 | static int amdgpu_dm_init(struct amdgpu_device *adev) |
| 978 | { | 943 | { |
| 979 | struct dc_init_data init_data; | 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 | dc_init_callbacks(adev->dm.dc, &init_params); | 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 | #endif | 1088 | #endif |
| 1128 | if (amdgpu_dm_initialize_drm_device(adev)) { | 1089 | if (amdgpu_dm_initialize_drm_device(adev)) { |
| 1129 | DRM_ERROR( | 1090 | DRM_ERROR( |
| @@ -2386,8 +2347,7 @@ void amdgpu_dm_update_connector_after_detect( · 1256 unmodified lines | |||
| 2386 | 2347 | ||
| 2387 | drm_connector_update_edid_property(connector, | 2348 | drm_connector_update_edid_property(connector, |
| 2388 | aconnector->edid); | 2349 | aconnector->edid); |
| 2389 | aconnector->num_modes = drm_add_edid_modes(connector, aconnector->edid); | 2350 | drm_add_edid_modes(connector, aconnector->edid); |
| 2390 | drm_connector_list_update(connector); | ||
| 2391 | 2351 | ||
| 2392 | if (aconnector->dc_link->aux_mode) | 2352 | if (aconnector->dc_link->aux_mode) |
| 2393 | drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux, | 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 | state->crc_src = cur->crc_src; | 5294 | state->crc_src = cur->crc_src; |
| 5335 | state->cm_has_degamma = cur->cm_has_degamma; | 5295 | state->cm_has_degamma = cur->cm_has_degamma; |
| 5336 | state->cm_is_degamma_srgb = cur->cm_is_degamma_srgb; | 5296 | state->cm_is_degamma_srgb = cur->cm_is_degamma_srgb; |
| 5337 | #ifdef CONFIG_DEBUG_FS | 5297 | |
| 5338 | state->crc_window = cur->crc_window; | ||
| 5339 | #endif | ||
| 5340 | /* TODO Duplicate dc_stream after objects are stream object is flattened */ | 5298 | /* TODO Duplicate dc_stream after objects are stream object is flattened */ |
| 5341 | 5299 | ||
| 5342 | return &state->base; | 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 | static inline int dm_set_vupdate_irq(struct drm_crtc *crtc, bool enable) | 5303 | static inline int dm_set_vupdate_irq(struct drm_crtc *crtc, bool enable) |
| 5396 | { | 5304 | { |
| 5397 | enum dc_irq_source irq_source; | 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 | .enable_vblank = dm_enable_vblank, | 5366 | .enable_vblank = dm_enable_vblank, |
| 5459 | .disable_vblank = dm_disable_vblank, | 5367 | .disable_vblank = dm_disable_vblank, |
| 5460 | .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp, | 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 | static enum drm_connector_status | 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 | return 0; | 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 | static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, | 6570 | static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, |
| 6686 | struct drm_plane *plane, | 6571 | struct drm_plane *plane, |
| 6687 | uint32_t crtc_index) | 6572 | uint32_t crtc_index) |
| @@ -6729,9 +6614,7 @@ static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, · 41 unmodified lines | |||
| 6729 | drm_crtc_enable_color_mgmt(&acrtc->base, MAX_COLOR_LUT_ENTRIES, | 6614 | drm_crtc_enable_color_mgmt(&acrtc->base, MAX_COLOR_LUT_ENTRIES, |
| 6730 | true, MAX_COLOR_LUT_ENTRIES); | 6615 | true, MAX_COLOR_LUT_ENTRIES); |
| 6731 | drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES); | 6616 | drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES); |
| 6732 | #ifdef CONFIG_DEBUG_FS | 6617 | |
| 6733 | attach_crtc_crc_properties(dm, acrtc); | ||
| 6734 | #endif | ||
| 6735 | return 0; | 6618 | return 0; |
| 6736 | 6619 | ||
| 6737 | fail: | 6620 | fail: |
| @@ -8368,7 +8251,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 1630 unmodified lines | |||
| 8368 | */ | 8251 | */ |
| 8369 | for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { | 8252 | for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { |
| 8370 | struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); | 8253 | struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); |
| 8371 | bool configure_crc = false; | ||
| 8372 | 8254 | ||
| 8373 | dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); | 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 | dc_stream_retain(dm_new_crtc_state->stream); | 8260 | dc_stream_retain(dm_new_crtc_state->stream); |
| 8379 | acrtc->dm_irq_params.stream = dm_new_crtc_state->stream; | 8261 | acrtc->dm_irq_params.stream = dm_new_crtc_state->stream; |
| 8380 | manage_dm_interrupts(adev, acrtc, true); | 8262 | manage_dm_interrupts(adev, acrtc, true); |
| 8381 | } | 8263 | |
| 8382 | #ifdef CONFIG_DEBUG_FS | 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 | * Frontend may have changed so reapply the CRC capture | 8266 | * Frontend may have changed so reapply the CRC capture |
| 8387 | * settings for the stream. | 8267 | * settings for the stream. |
| 8388 | */ | 8268 | */ |
| 8389 | dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); | 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 | amdgpu_dm_crtc_configure_crc_source( | 8272 | amdgpu_dm_crtc_configure_crc_source( |
| 8402 | crtc, dm_new_crtc_state, dm_new_crtc_state->crc_src); | 8273 | crtc, dm_new_crtc_state, |
| 8403 | } | 8274 | dm_new_crtc_state->crc_src); |
| 8275 | } | ||
| 8404 | #endif | 8276 | #endif |
| 8277 | } | ||
| 8405 | } | 8278 | } |
| 8406 | 8279 | ||
| 8407 | for_each_new_crtc_in_state(state, crtc, new_crtc_state, j) | 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 | const struct gpu_info_soc_bounding_box_v1_0 *soc_bounding_box; | 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 | * @mst_encoders: | 340 | * @mst_encoders: |
| 367 | * | 341 | * |
| @@ -448,15 +422,6 @@ struct dm_plane_state { · 80 unmodified lines | |||
| 448 | struct dc_plane_state *dc_state; | 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 | struct dm_crtc_state { | 425 | struct dm_crtc_state { |
| 461 | struct drm_crtc_state base; | 426 | struct drm_crtc_state base; |
| 462 | struct dc_stream_state *stream; | 427 | struct dc_stream_state *stream; |
| @@ -479,9 +444,6 @@ struct dm_crtc_state { · 16 unmodified lines | |||
| 479 | struct dc_info_packet vrr_infopacket; | 444 | struct dc_info_packet vrr_infopacket; |
| 480 | 445 | ||
| 481 | int abm_level; | 446 | int abm_level; |
| 482 | #ifdef CONFIG_DEBUG_FS | ||
| 483 | struct crc_rec crc_window; | ||
| 484 | #endif | ||
| 485 | }; | 447 | }; |
| 486 | 448 | ||
| 487 | #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base) | 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 | return pipe_crc_sources; | 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 | int | 84 | int |
| 120 | amdgpu_dm_crtc_verify_crc_source(struct drm_crtc *crtc, const char *src_name, | 85 | amdgpu_dm_crtc_verify_crc_source(struct drm_crtc *crtc, const char *src_name, |
| 121 | size_t *values_cnt) | 86 | size_t *values_cnt) |
| @@ -140,7 +105,6 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, · 18 unmodified lines | |||
| 140 | struct dc_stream_state *stream_state = dm_crtc_state->stream; | 105 | struct dc_stream_state *stream_state = dm_crtc_state->stream; |
| 141 | bool enable = amdgpu_dm_is_valid_crc_source(source); | 106 | bool enable = amdgpu_dm_is_valid_crc_source(source); |
| 142 | int ret = 0; | 107 | int ret = 0; |
| 143 | struct crc_params *crc_window = NULL, tmp_window; | ||
| 144 | 108 | ||
| 145 | /* Configuration will be deferred to stream enable. */ | 109 | /* Configuration will be deferred to stream enable. */ |
| 146 | if (!stream_state) | 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 | /* Enable CRTC CRC generation if necessary. */ | 115 | /* Enable CRTC CRC generation if necessary. */ |
| 152 | if (dm_is_crc_source_crtc(source) || source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE) { | 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 | if (!dc_stream_configure_crc(stream_state->ctx->dc, | 117 | if (!dc_stream_configure_crc(stream_state->ctx->dc, |
| 170 | stream_state, crc_window, enable, enable)) { | 118 | stream_state, NULL, enable, enable)) { |
| 171 | ret = -EINVAL; | 119 | ret = -EINVAL; |
| 172 | goto unlock; | 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 | /* amdgpu_dm_crc.c */ | 48 | /* amdgpu_dm_crc.c */ |
| 49 | #ifdef CONFIG_DEBUG_FS | 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 | int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, | 50 | int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, |
| 54 | struct dm_crtc_state *dm_crtc_state, | 51 | struct dm_crtc_state *dm_crtc_state, |
| 55 | enum amdgpu_dm_pipe_crc_source source); | 52 | enum amdgpu_dm_pipe_crc_source source); |
| @@ -33,10 +33,6 @@ ifdef CONFIG_PPC64 · 32 unmodified lines | |||
| 33 | calcs_ccflags := -mhard-float -maltivec | 33 | calcs_ccflags := -mhard-float -maltivec |
| 34 | endif | 34 | endif |
| 35 | 35 | ||
| 36 | ifdef CONFIG_ARM64 | ||
| 37 | calcs_rcflags := -mgeneral-regs-only | ||
| 38 | endif | ||
| 39 | |||
| 40 | ifdef CONFIG_CC_IS_GCC | 36 | ifdef CONFIG_CC_IS_GCC |
| 41 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) | 37 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 42 | IS_OLD_GCC = 1 | 38 | IS_OLD_GCC = 1 |
| @@ -104,13 +104,6 @@ ifdef CONFIG_PPC64 · 103 unmodified lines | |||
| 104 | CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn21/rn_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) | 104 | CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn21/rn_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) |
| 105 | endif | 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 | AMD_DAL_CLK_MGR_DCN21 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn21/,$(CLK_MGR_DCN21)) | 107 | AMD_DAL_CLK_MGR_DCN21 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn21/,$(CLK_MGR_DCN21)) |
| 115 | 108 | ||
| 116 | AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21) | 109 | AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21) |
| @@ -125,13 +118,6 @@ ifdef CONFIG_PPC64 · 8 unmodified lines | |||
| 125 | CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn30/dcn30_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) | 118 | CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn30/dcn30_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) |
| 126 | endif | 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 | AMD_DAL_CLK_MGR_DCN30 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn30/,$(CLK_MGR_DCN30)) | 121 | AMD_DAL_CLK_MGR_DCN30 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn30/,$(CLK_MGR_DCN30)) |
| 136 | 122 | ||
| 137 | AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN30) | 123 | AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN30) |
| @@ -146,13 +132,6 @@ ifdef CONFIG_PPC64 · 8 unmodified lines | |||
| 146 | CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn301/vg_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) | 132 | CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn301/vg_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) |
| 147 | endif | 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 | AMD_DAL_CLK_MGR_DCN301 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn301/,$(CLK_MGR_DCN301)) | 135 | AMD_DAL_CLK_MGR_DCN301 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn301/,$(CLK_MGR_DCN301)) |
| 157 | 136 | ||
| 158 | AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN301) | 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 | static struct abm *get_abm_from_stream_res(const struct dc_link *link) | 2487 | static struct abm *get_abm_from_stream_res(const struct dc_link *link) |
| 2488 | { | 2488 | { |
| 2489 | int i; | 2489 | int i; |
| 2490 | struct dc *dc = link->ctx->dc; | 2490 | struct dc *dc = NULL; |
| 2491 | struct abm *abm = NULL; | 2491 | struct abm *abm = NULL; |
| 2492 | 2492 | ||
| 2493 | if (!link || !link->ctx) | ||
| 2494 | return NULL; | ||
| 2495 | |||
| 2496 | dc = link->ctx->dc; | ||
| 2497 | |||
| 2493 | for (i = 0; i < MAX_PIPES; i++) { | 2498 | for (i = 0; i < MAX_PIPES; i++) { |
| 2494 | struct pipe_ctx pipe_ctx = dc->current_state->res_ctx.pipe_ctx[i]; | 2499 | struct pipe_ctx pipe_ctx = dc->current_state->res_ctx.pipe_ctx[i]; |
| 2495 | struct dc_stream_state *stream = pipe_ctx.stream; | 2500 | struct dc_stream_state *stream = pipe_ctx.stream; |
| @@ -3992,7 +3992,7 @@ bool dc_link_dp_set_test_pattern( · 3991 unmodified lines | |||
| 3992 | unsigned int cust_pattern_size) | 3992 | unsigned int cust_pattern_size) |
| 3993 | { | 3993 | { |
| 3994 | struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx; | 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 | unsigned int lane; | 3996 | unsigned int lane; |
| 3997 | unsigned int i; | 3997 | unsigned int i; |
| 3998 | unsigned char link_qual_pattern[LANE_COUNT_DP_MAX] = {0}; | 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 | memset(&training_pattern, 0, sizeof(training_pattern)); | 4002 | memset(&training_pattern, 0, sizeof(training_pattern)); |
| 4003 | 4003 | ||
| 4004 | for (i = 0; i < MAX_PIPES; i++) { | 4004 | for (i = 0; i < MAX_PIPES; i++) { |
| 4005 | if (pipes[i].stream == NULL) | ||
| 4006 | continue; | ||
| 4007 | |||
| 4005 | if (pipes[i].stream->link == link && !pipes[i].top_pipe && !pipes[i].prev_odm_pipe) { | 4008 | if (pipes[i].stream->link == link && !pipes[i].top_pipe && !pipes[i].prev_odm_pipe) { |
| 4006 | pipe_ctx = &pipes[i]; | 4009 | pipe_ctx = &pipes[i]; |
| 4007 | break; | 4010 | break; |
| 4008 | } | 4011 | } |
| 4009 | } | 4012 | } |
| 4010 | 4013 | ||
| 4014 | if (pipe_ctx == NULL) | ||
| 4015 | return false; | ||
| 4016 | |||
| 4011 | /* Reset CRTC Test Pattern if it is currently running and request is VideoMode */ | 4017 | /* Reset CRTC Test Pattern if it is currently running and request is VideoMode */ |
| 4012 | if (link->test_pattern_enabled && test_pattern == | 4018 | if (link->test_pattern_enabled && test_pattern == |
| 4013 | DP_TEST_PATTERN_VIDEO_MODE) { | 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 | AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10)) | 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 | AMD_DISPLAY_FILES += $(AMD_DAL_DCN10) | 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 | unsigned int mpc1_get_mpc_out_mux(struct mpc *mpc, int opp_id) | 470 | unsigned int mpc1_get_mpc_out_mux(struct mpc *mpc, int opp_id) |
| 471 | { | 471 | { |
| 472 | struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); | 472 | struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); |
| 473 | uint32_t val = 0; | 473 | uint32_t val = 0xf; |
| 474 | 474 | ||
| 475 | if (opp_id < MAX_OPP && REG(MUX[opp_id])) | 475 | if (opp_id < MAX_OPP && REG(MUX[opp_id])) |
| 476 | REG_GET(MUX[opp_id], MPC_OUT_MUX, &val); | 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 | .disable_pplib_clock_request = false, | 608 | .disable_pplib_clock_request = false, |
| 609 | .disable_pplib_wm_range = false, | 609 | .disable_pplib_wm_range = false, |
| 610 | .pplib_wm_report_mode = WM_REPORT_DEFAULT, | 610 | .pplib_wm_report_mode = WM_REPORT_DEFAULT, |
| 611 | .pipe_split_policy = MPC_SPLIT_DYNAMIC, | 611 | .pipe_split_policy = MPC_SPLIT_AVOID, |
| 612 | .force_single_disp_pipe_split = true, | 612 | .force_single_disp_pipe_split = false, |
| 613 | .disable_dcc = DCC_ENABLE, | 613 | .disable_dcc = DCC_ENABLE, |
| 614 | .voltage_align_fclk = true, | 614 | .voltage_align_fclk = true, |
| 615 | .disable_stereo_support = true, | 615 | .disable_stereo_support = true, |
| @@ -1534,15 +1534,8 @@ static bool dcn10_resource_construct( · 918 unmodified lines | |||
| 1534 | memcpy(dc->dcn_ip, &dcn10_ip_defaults, sizeof(dcn10_ip_defaults)); | 1534 | memcpy(dc->dcn_ip, &dcn10_ip_defaults, sizeof(dcn10_ip_defaults)); |
| 1535 | memcpy(dc->dcn_soc, &dcn10_soc_defaults, sizeof(dcn10_soc_defaults)); | 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 | /* Other architectures we build for build this with soft-float */ | 1537 | /* Other architectures we build for build this with soft-float */ |
| 1544 | dcn10_resource_construct_fp(dc); | 1538 | dcn10_resource_construct_fp(dc); |
| 1545 | #endif | ||
| 1546 | 1539 | ||
| 1547 | pool->base.pp_smu = dcn10_pp_smu_create(ctx); | 1540 | pool->base.pp_smu = dcn10_pp_smu_create(ctx); |
| 1548 | 1541 | ||
| @@ -17,10 +17,6 @@ ifdef CONFIG_PPC64 · 16 unmodified lines | |||
| 17 | CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -mhard-float -maltivec | 17 | CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -mhard-float -maltivec |
| 18 | endif | 18 | endif |
| 19 | 19 | ||
| 20 | ifdef CONFIG_ARM64 | ||
| 21 | CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -mgeneral-regs-only | ||
| 22 | endif | ||
| 23 | |||
| 24 | ifdef CONFIG_CC_IS_GCC | 20 | ifdef CONFIG_CC_IS_GCC |
| 25 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) | 21 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 26 | IS_OLD_GCC = 1 | 22 | IS_OLD_GCC = 1 |
| @@ -13,10 +13,6 @@ ifdef CONFIG_PPC64 · 12 unmodified lines | |||
| 13 | CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mhard-float -maltivec | 13 | CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mhard-float -maltivec |
| 14 | endif | 14 | endif |
| 15 | 15 | ||
| 16 | ifdef CONFIG_ARM64 | ||
| 17 | CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mgeneral-regs-only | ||
| 18 | endif | ||
| 19 | |||
| 20 | ifdef CONFIG_CC_IS_GCC | 16 | ifdef CONFIG_CC_IS_GCC |
| 21 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) | 17 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 22 | IS_OLD_GCC = 1 | 18 | IS_OLD_GCC = 1 |
| @@ -41,11 +41,6 @@ CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -mhard-float -maltivec · 40 unmodified lines | |||
| 41 | CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -mhard-float -maltivec | 41 | CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -mhard-float -maltivec |
| 42 | endif | 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 | ifdef CONFIG_CC_IS_GCC | 44 | ifdef CONFIG_CC_IS_GCC |
| 50 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) | 45 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 51 | IS_OLD_GCC = 1 | 46 | IS_OLD_GCC = 1 |
| @@ -21,10 +21,6 @@ ifdef CONFIG_PPC64 · 20 unmodified lines | |||
| 21 | CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mhard-float -maltivec | 21 | CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mhard-float -maltivec |
| 22 | endif | 22 | endif |
| 23 | 23 | ||
| 24 | ifdef CONFIG_ARM64 | ||
| 25 | CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mgeneral-regs-only | ||
| 26 | endif | ||
| 27 | |||
| 28 | ifdef CONFIG_CC_IS_GCC | 24 | ifdef CONFIG_CC_IS_GCC |
| 29 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) | 25 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 30 | IS_OLD_GCC = 1 | 26 | IS_OLD_GCC = 1 |
| @@ -1731,6 +1731,7 @@ static struct resource_funcs dcn301_res_pool_funcs = { · 1730 unmodified lines | |||
| 1731 | .populate_dml_pipes = dcn30_populate_dml_pipes_from_context, | 1731 | .populate_dml_pipes = dcn30_populate_dml_pipes_from_context, |
| 1732 | .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer, | 1732 | .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer, |
| 1733 | .add_stream_to_ctx = dcn30_add_stream_to_ctx, | 1733 | .add_stream_to_ctx = dcn30_add_stream_to_ctx, |
| 1734 | .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource, | ||
| 1734 | .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, | 1735 | .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, |
| 1735 | .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context, | 1736 | .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context, |
| 1736 | .set_mcif_arb_params = dcn30_set_mcif_arb_params, | 1737 | .set_mcif_arb_params = dcn30_set_mcif_arb_params, |
| @@ -20,10 +20,6 @@ ifdef CONFIG_PPC64 · 19 unmodified lines | |||
| 20 | CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -mhard-float -maltivec | 20 | CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -mhard-float -maltivec |
| 21 | endif | 21 | endif |
| 22 | 22 | ||
| 23 | ifdef CONFIG_ARM64 | ||
| 24 | CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -mgeneral-regs-only | ||
| 25 | endif | ||
| 26 | |||
| 27 | ifdef CONFIG_CC_IS_GCC | 23 | ifdef CONFIG_CC_IS_GCC |
| 28 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) | 24 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 29 | IS_OLD_GCC = 1 | 25 | IS_OLD_GCC = 1 |
| @@ -33,10 +33,6 @@ ifdef CONFIG_PPC64 · 32 unmodified lines | |||
| 33 | dml_ccflags := -mhard-float -maltivec | 33 | dml_ccflags := -mhard-float -maltivec |
| 34 | endif | 34 | endif |
| 35 | 35 | ||
| 36 | ifdef CONFIG_ARM64 | ||
| 37 | dml_rcflags := -mgeneral-regs-only | ||
| 38 | endif | ||
| 39 | |||
| 40 | ifdef CONFIG_CC_IS_GCC | 36 | ifdef CONFIG_CC_IS_GCC |
| 41 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) | 37 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 42 | IS_OLD_GCC = 1 | 38 | IS_OLD_GCC = 1 |
| @@ -2635,14 +2635,15 @@ static void dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndP · 2634 unmodified lines | |||
| 2635 | } | 2635 | } |
| 2636 | 2636 | ||
| 2637 | if (mode_lib->vba.DRAMClockChangeSupportsVActive && | 2637 | if (mode_lib->vba.DRAMClockChangeSupportsVActive && |
| 2638 | mode_lib->vba.MinActiveDRAMClockChangeMargin > 60 && | 2638 | mode_lib->vba.MinActiveDRAMClockChangeMargin > 60) { |
| 2639 | mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 0) { | ||
| 2640 | mode_lib->vba.DRAMClockChangeWatermark += 25; | 2639 | mode_lib->vba.DRAMClockChangeWatermark += 25; |
| 2641 | 2640 | ||
| 2642 | for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { | 2641 | for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { |
| 2643 | if (mode_lib->vba.DRAMClockChangeWatermark > | 2642 | if (mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 0) { |
| 2644 | dml_max(mode_lib->vba.StutterEnterPlusExitWatermark, mode_lib->vba.UrgentWatermark)) | 2643 | if (mode_lib->vba.DRAMClockChangeWatermark > |
| 2645 | mode_lib->vba.MinTTUVBlank[k] += 25; | 2644 | dml_max(mode_lib->vba.StutterEnterPlusExitWatermark, mode_lib->vba.UrgentWatermark)) |
| 2645 | mode_lib->vba.MinTTUVBlank[k] += 25; | ||
| 2646 | } | ||
| 2646 | } | 2647 | } |
| 2647 | 2648 | ||
| 2648 | mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive; | 2649 | mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive; |
| @@ -10,10 +10,6 @@ ifdef CONFIG_PPC64 · 9 unmodified lines | |||
| 10 | dsc_ccflags := -mhard-float -maltivec | 10 | dsc_ccflags := -mhard-float -maltivec |
| 11 | endif | 11 | endif |
| 12 | 12 | ||
| 13 | ifdef CONFIG_ARM64 | ||
| 14 | dsc_rcflags := -mgeneral-regs-only | ||
| 15 | endif | ||
| 16 | |||
| 17 | ifdef CONFIG_CC_IS_GCC | 13 | ifdef CONFIG_CC_IS_GCC |
| 18 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) | 14 | ifeq ($(call cc-ifversion, -lt, 0701, y), y) |
| 19 | IS_OLD_GCC = 1 | 15 | IS_OLD_GCC = 1 |
| @@ -55,10 +55,6 @@ · 54 unmodified lines | |||
| 55 | #include <asm/fpu/api.h> | 55 | #include <asm/fpu/api.h> |
| 56 | #define DC_FP_START() kernel_fpu_begin() | 56 | #define DC_FP_START() kernel_fpu_begin() |
| 57 | #define DC_FP_END() kernel_fpu_end() | 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 | #elif defined(CONFIG_PPC64) | 58 | #elif defined(CONFIG_PPC64) |
| 63 | #include <asm/switch_to.h> | 59 | #include <asm/switch_to.h> |
| 64 | #include <asm/cputable.h> | 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 | smu10_data->gfx_actual_soft_min_freq = clock; | 251 | smu10_data->gfx_actual_soft_min_freq = clock; |
| 252 | smum_send_msg_to_smc_with_parameter(hwmgr, | 252 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 253 | PPSMC_MSG_SetHardMinGfxClk, | 253 | PPSMC_MSG_SetHardMinGfxClk, |
| 254 | smu10_data->gfx_actual_soft_min_freq, | 254 | clock, |
| 255 | NULL); | 255 | NULL); |
| 256 | } | 256 | } |
| 257 | return 0; | 257 | return 0; |
| @@ -558,7 +558,8 @@ static int smu10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) · 300 unmodified lines | |||
| 558 | 558 | ||
| 559 | /* enable the pp_od_clk_voltage sysfs file */ | 559 | /* enable the pp_od_clk_voltage sysfs file */ |
| 560 | hwmgr->od_enabled = 1; | 560 | hwmgr->od_enabled = 1; |
| 561 | 561 | /* disabled fine grain tuning function by default */ | |
| 562 | data->fine_grain_enabled = 0; | ||
| 562 | return result; | 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 | uint32_t min_mclk = hwmgr->display_config->min_mem_set_clock/100; | 598 | uint32_t min_mclk = hwmgr->display_config->min_mem_set_clock/100; |
| 598 | uint32_t index_fclk = data->clock_vol_info.vdd_dep_on_fclk->count - 1; | 599 | uint32_t index_fclk = data->clock_vol_info.vdd_dep_on_fclk->count - 1; |
| 599 | uint32_t index_socclk = data->clock_vol_info.vdd_dep_on_socclk->count - 1; | 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 | if (hwmgr->smu_version < 0x1E3700) { | 603 | if (hwmgr->smu_version < 0x1E3700) { |
| 602 | pr_info("smu firmware version too old, can not set dpm level\n"); | 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 | switch (level) { | 615 | switch (level) { |
| 614 | case AMD_DPM_FORCED_LEVEL_HIGH: | 616 | case AMD_DPM_FORCED_LEVEL_HIGH: |
| 615 | case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: | 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 | smum_send_msg_to_smc_with_parameter(hwmgr, | 626 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 617 | PPSMC_MSG_SetHardMinGfxClk, | 627 | PPSMC_MSG_SetHardMinGfxClk, |
| 618 | data->gfx_max_freq_limit/100, | 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 | NULL); | 658 | NULL); |
| 649 | break; | 659 | break; |
| 650 | case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: | 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 | smum_send_msg_to_smc_with_parameter(hwmgr, | 669 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 652 | PPSMC_MSG_SetHardMinGfxClk, | 670 | PPSMC_MSG_SetHardMinGfxClk, |
| 653 | min_sclk, | 671 | min_sclk, |
| @@ -658,6 +676,14 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 4 unmodified lines | |||
| 658 | NULL); | 676 | NULL); |
| 659 | break; | 677 | break; |
| 660 | case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: | 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 | smum_send_msg_to_smc_with_parameter(hwmgr, | 687 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 662 | PPSMC_MSG_SetHardMinFclkByFreq, | 688 | PPSMC_MSG_SetHardMinFclkByFreq, |
| 663 | min_mclk, | 689 | min_mclk, |
| @@ -668,6 +694,14 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 4 unmodified lines | |||
| 668 | NULL); | 694 | NULL); |
| 669 | break; | 695 | break; |
| 670 | case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: | 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 | smum_send_msg_to_smc_with_parameter(hwmgr, | 705 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 672 | PPSMC_MSG_SetHardMinGfxClk, | 706 | PPSMC_MSG_SetHardMinGfxClk, |
| 673 | SMU10_UMD_PSTATE_GFXCLK, | 707 | SMU10_UMD_PSTATE_GFXCLK, |
| @@ -703,6 +737,14 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 29 unmodified lines | |||
| 703 | NULL); | 737 | NULL); |
| 704 | break; | 738 | break; |
| 705 | case AMD_DPM_FORCED_LEVEL_AUTO: | 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 | smum_send_msg_to_smc_with_parameter(hwmgr, | 748 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 707 | PPSMC_MSG_SetHardMinGfxClk, | 749 | PPSMC_MSG_SetHardMinGfxClk, |
| 708 | min_sclk, | 750 | min_sclk, |
| @@ -741,6 +783,14 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, · 32 unmodified lines | |||
| 741 | NULL); | 783 | NULL); |
| 742 | break; | 784 | break; |
| 743 | case AMD_DPM_FORCED_LEVEL_LOW: | 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 | smum_send_msg_to_smc_with_parameter(hwmgr, | 794 | smum_send_msg_to_smc_with_parameter(hwmgr, |
| 745 | PPSMC_MSG_SetHardMinGfxClk, | 795 | PPSMC_MSG_SetHardMinGfxClk, |
| 746 | data->gfx_min_freq_limit/100, | 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 | NULL); | 809 | NULL); |
| 760 | break; | 810 | break; |
| 761 | case AMD_DPM_FORCED_LEVEL_MANUAL: | 811 | case AMD_DPM_FORCED_LEVEL_MANUAL: |
| 812 | data->fine_grain_enabled = 1; | ||
| 762 | case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT: | 813 | case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT: |
| 763 | default: | 814 | default: |
| 764 | break; | 815 | break; |
| @@ -948,6 +999,8 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, · 183 unmodified lines | |||
| 948 | struct smu10_voltage_dependency_table *mclk_table = | 999 | struct smu10_voltage_dependency_table *mclk_table = |
| 949 | data->clock_vol_info.vdd_dep_on_fclk; | 1000 | data->clock_vol_info.vdd_dep_on_fclk; |
| 950 | uint32_t i, now, size = 0; | 1001 | uint32_t i, now, size = 0; |
| 1002 | uint32_t min_freq, max_freq = 0; | ||
| 1003 | uint32_t ret = 0; | ||
| 951 | 1004 | ||
| 952 | switch (type) { | 1005 | switch (type) { |
| 953 | case PP_SCLK: | 1006 | case PP_SCLK: |
| @@ -983,18 +1036,28 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, · 29 unmodified lines | |||
| 983 | break; | 1036 | break; |
| 984 | case OD_SCLK: | 1037 | case OD_SCLK: |
| 985 | if (hwmgr->od_enabled) { | 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 | size += sprintf(buf + size, "0: %10uMhz\n", | 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); | 1048 | (data->gfx_actual_soft_min_freq > 0) ? data->gfx_actual_soft_min_freq : min_freq); |
| 990 | size += sprintf(buf + size, "1: %10uMhz\n", data->gfx_max_freq_limit/100); | 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 | break; | 1052 | break; |
| 993 | case OD_RANGE: | 1053 | case OD_RANGE: |
| 994 | if (hwmgr->od_enabled) { | 1054 | if (hwmgr->od_enabled) { |
| 995 | uint32_t min_freq, max_freq = 0; | 1055 | ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); |
| 996 | smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); | 1056 | if (ret) |
| 997 | smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); | 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 | size = sprintf(buf, "%s:\n", "OD_RANGE"); | 1062 | size = sprintf(buf, "%s:\n", "OD_RANGE"); |
| 1000 | size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n", | 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 | enum PP_OD_DPM_TABLE_COMMAND type, | 1477 | enum PP_OD_DPM_TABLE_COMMAND type, |
| 1415 | long *input, uint32_t size) | 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 | if (!hwmgr->od_enabled) { | 1484 | if (!hwmgr->od_enabled) { |
| 1418 | pr_err("Fine grain not support\n"); | 1485 | pr_err("Fine grain not support\n"); |
| 1419 | return -EINVAL; | 1486 | return -EINVAL; |
| 1420 | } | 1487 | } |
| 1421 | 1488 | ||
| 1422 | if (size != 2) { | 1489 | if (!smu10_data->fine_grain_enabled) { |
| 1423 | pr_err("Input parameter number not correct\n"); | 1490 | pr_err("Fine grain not started\n"); |
| 1424 | return -EINVAL; | 1491 | return -EINVAL; |
| 1425 | } | 1492 | } |
| 1426 | 1493 | ||
| 1427 | if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) { | 1494 | if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) { |
| 1428 | if (input[0] == 0) | 1495 | if (size != 2) { |
| 1429 | smu10_set_hard_min_gfxclk_by_freq(hwmgr, input[1]); | 1496 | pr_err("Input parameter number not correct\n"); |
| 1430 | else if (input[0] == 1) | ||
| 1431 | smu10_set_soft_max_gfxclk_by_freq(hwmgr, input[1]); | ||
| 1432 | else | ||
| 1433 | return -EINVAL; | 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 | return 0; | 1572 | return 0; |
| @@ -283,6 +283,7 @@ struct smu10_hwmgr { · 282 unmodified lines | |||
| 283 | uint32_t vclk_soft_min; | 283 | uint32_t vclk_soft_min; |
| 284 | uint32_t dclk_soft_min; | 284 | uint32_t dclk_soft_min; |
| 285 | uint32_t gfx_actual_soft_min_freq; | 285 | uint32_t gfx_actual_soft_min_freq; |
| 286 | uint32_t gfx_actual_soft_max_freq; | ||
| 286 | uint32_t gfx_min_freq_limit; | 287 | uint32_t gfx_min_freq_limit; |
| 287 | uint32_t gfx_max_freq_limit; /* in 10Khz*/ | 288 | uint32_t gfx_max_freq_limit; /* in 10Khz*/ |
| 288 | 289 | ||
| @@ -299,6 +300,8 @@ struct smu10_hwmgr { · 10 unmodified lines | |||
| 299 | bool need_min_deep_sleep_dcefclk; | 300 | bool need_min_deep_sleep_dcefclk; |
| 300 | uint32_t deep_sleep_dcefclk; | 301 | uint32_t deep_sleep_dcefclk; |
| 301 | uint32_t num_active_display; | 302 | uint32_t num_active_display; |
| 303 | |||
| 304 | bool fine_grain_enabled; | ||
| 302 | }; | 305 | }; |
| 303 | 306 | ||
| 304 | struct pp_hwmgr; | 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 | int i; | 2373 | int i; |
| 2374 | 2374 | ||
| 2375 | req->I2CcontrollerPort = 0; | 2375 | req->I2CcontrollerPort = 1; |
| 2376 | req->I2CSpeed = 2; | 2376 | req->I2CSpeed = 2; |
| 2377 | req->SlaveAddress = address; | 2377 | req->SlaveAddress = address; |
| 2378 | req->NumCmds = numbytes; | 2378 | req->NumCmds = numbytes; |
| @@ -252,7 +252,8 @@ static int vangogh_get_smu_metrics_data(struct smu_context *smu, · 251 unmodified lines | |||
| 252 | *value = metrics->UvdActivity; | 252 | *value = metrics->UvdActivity; |
| 253 | break; | 253 | break; |
| 254 | case METRICS_AVERAGE_SOCKETPOWER: | 254 | case METRICS_AVERAGE_SOCKETPOWER: |
| 255 | *value = metrics->CurrentSocketPower; | 255 | *value = (metrics->CurrentSocketPower << 8) / |
| 256 | 1000 ; | ||
| 256 | break; | 257 | break; |
| 257 | case METRICS_TEMPERATURE_EDGE: | 258 | case METRICS_TEMPERATURE_EDGE: |
| 258 | *value = metrics->GfxTemperature / 100 * | 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 | return -EINVAL; | 188 | return -EINVAL; |
| 189 | *freq = clk_table->SocClocks[dpm_level].Freq; | 189 | *freq = clk_table->SocClocks[dpm_level].Freq; |
| 190 | break; | 190 | break; |
| 191 | case SMU_UCLK: | ||
| 191 | case SMU_MCLK: | 192 | case SMU_MCLK: |
| 192 | if (dpm_level >= NUM_FCLK_DPM_LEVELS) | 193 | if (dpm_level >= NUM_FCLK_DPM_LEVELS) |
| 193 | return -EINVAL; | 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 | break; | 225 | break; |
| 226 | case SMU_FCLK: | 226 | case SMU_FCLK: |
| 227 | case SMU_MCLK: | 227 | case SMU_MCLK: |
| 228 | case SMU_UCLK: | ||
| 228 | ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinFclkByFreq, min, NULL); | 229 | ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinFclkByFreq, min, NULL); |
| 229 | if (ret) | 230 | if (ret) |
| 230 | return ret; | 231 | return ret; |
| @@ -1163,7 +1163,14 @@ retry: · 1162 unmodified lines | |||
| 1163 | if (ret) | 1163 | if (ret) |
| 1164 | goto out; | 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 | DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n"); | 1174 | DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n"); |
| 1168 | ret = -EINVAL; | 1175 | ret = -EINVAL; |
| 1169 | goto out; | 1176 | goto out; |
| @@ -38,6 +38,7 @@ i915-y += i915_drv.o \ · 37 unmodified lines | |||
| 38 | i915_config.o \ | 38 | i915_config.o \ |
| 39 | i915_irq.o \ | 39 | i915_irq.o \ |
| 40 | i915_getparam.o \ | 40 | i915_getparam.o \ |
| 41 | i915_mitigations.o \ | ||
| 41 | i915_params.o \ | 42 | i915_params.o \ |
| 42 | i915_pci.o \ | 43 | i915_pci.o \ |
| 43 | i915_scatterlist.o \ | 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 | get_dsi_io_power_domains(i915, | 1617 | get_dsi_io_power_domains(i915, |
| 1618 | enc_to_intel_dsi(encoder)); | 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 | static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, | 1621 | static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, |
| @@ -1436,6 +1436,9 @@ struct intel_dp { · 1435 unmodified lines | |||
| 1436 | bool ycbcr_444_to_420; | 1436 | bool ycbcr_444_to_420; |
| 1437 | } dfp; | 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 | /* Display stream compression testing */ | 1442 | /* Display stream compression testing */ |
| 1440 | bool force_dsc_en; | 1443 | bool force_dsc_en; |
| 1441 | 1444 | ||
| @@ -1489,7 +1489,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp, · 1488 unmodified lines | |||
| 1489 | * lowest possible wakeup latency and so prevent the cpu from going into | 1489 | * lowest possible wakeup latency and so prevent the cpu from going into |
| 1490 | * deep sleep states. | 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 | intel_dp_check_edp(intel_dp); | 1494 | intel_dp_check_edp(intel_dp); |
| 1495 | 1495 | ||
| @@ -1622,7 +1622,7 @@ done: · 126 unmodified lines | |||
| 1622 | 1622 | ||
| 1623 | ret = recv_bytes; | 1623 | ret = recv_bytes; |
| 1624 | out: | 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 | if (vdd) | 1627 | if (vdd) |
| 1628 | edp_panel_vdd_off(intel_dp, false); | 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 | static void | 1898 | static void |
| 1899 | intel_dp_aux_fini(struct intel_dp *intel_dp) | 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 | kfree(intel_dp->aux.name); | 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 | encoder->base.name); | 1953 | encoder->base.name); |
| 1951 | 1954 | ||
| 1952 | intel_dp->aux.transfer = intel_dp_aux_transfer; | 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 | bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp) | 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 | val = pch_get_backlight(connector); | 1650 | val = pch_get_backlight(connector); |
| 1651 | else | 1651 | else |
| 1652 | val = lpt_get_backlight(connector); | 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 | if (cpu_mode) { | 1654 | if (cpu_mode) { |
| 1658 | drm_dbg_kms(&dev_priv->drm, | 1655 | drm_dbg_kms(&dev_priv->drm, |
| 1659 | "CPU backlight register was enabled, switching to PCH override\n"); | 1656 | "CPU backlight register was enabled, switching to PCH override\n"); |
| 1660 | 1657 | ||
| 1661 | /* Write converted CPU PWM value to PCH override register */ | 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 | intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, | 1660 | intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, |
| 1664 | pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE); | 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 | cpu_ctl2 & ~BLM_PWM_ENABLE); | 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 | return 0; | 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 | intel_dsi_prepare(encoder, pipe_config); | 812 | intel_dsi_prepare(encoder, pipe_config); |
| 813 | 813 | ||
| 814 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_ON); | 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 */ | 816 | /* |
| 818 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); | 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 | if (IS_GEMINILAKE(dev_priv)) { | 830 | if (IS_GEMINILAKE(dev_priv)) { |
| 821 | glk_cold_boot = glk_dsi_enable_io(encoder); | 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 | GEM_BUG_ON(cache->rq_size >= obj->base.size / sizeof(u32)); | 1046 | GEM_BUG_ON(cache->rq_size >= obj->base.size / sizeof(u32)); |
| 1047 | cache->rq_cmd[cache->rq_size] = MI_BATCH_BUFFER_END; | 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 | i915_gem_object_unpin_map(obj); | 1050 | i915_gem_object_unpin_map(obj); |
| 1051 | 1051 | ||
| 1052 | intel_gt_chipset_flush(cache->rq->engine->gt); | 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 | goto err_pool; | 1296 | goto err_pool; |
| 1297 | } | 1297 | } |
| 1298 | 1298 | ||
| 1299 | memset32(cmd, 0, pool->obj->base.size / sizeof(u32)); | ||
| 1300 | |||
| 1299 | batch = i915_vma_instance(pool->obj, vma->vm, NULL); | 1301 | batch = i915_vma_instance(pool->obj, vma->vm, NULL); |
| 1300 | if (IS_ERR(batch)) { | 1302 | if (IS_ERR(batch)) { |
| 1301 | err = PTR_ERR(batch); | 1303 | err = PTR_ERR(batch); |
| @@ -7,8 +7,6 @@ · 6 unmodified lines | |||
| 7 | #include "i915_drv.h" | 7 | #include "i915_drv.h" |
| 8 | #include "intel_gpu_commands.h" | 8 | #include "intel_gpu_commands.h" |
| 9 | 9 | ||
| 10 | #define MAX_URB_ENTRIES 64 | ||
| 11 | #define STATE_SIZE (4 * 1024) | ||
| 12 | #define GT3_INLINE_DATA_DELAYS 0x1E00 | 10 | #define GT3_INLINE_DATA_DELAYS 0x1E00 |
| 13 | #define batch_advance(Y, CS) GEM_BUG_ON((Y)->end != (CS)) | 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 | struct batch_vals { | 34 | struct batch_vals { |
| 37 | u32 max_primitives; | 35 | u32 max_threads; |
| 38 | u32 max_urb_entries; | ||
| 39 | u32 cmd_size; | ||
| 40 | u32 state_size; | ||
| 41 | u32 state_start; | 36 | u32 state_start; |
| 42 | u32 batch_size; | 37 | u32 surface_start; |
| 43 | u32 surface_height; | 38 | u32 surface_height; |
| 44 | u32 surface_width; | 39 | u32 surface_width; |
| 45 | u32 scratch_size; | 40 | u32 size; |
| 46 | u32 max_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 | static void | 54 | static void |
| 50 | batch_get_defaults(struct drm_i915_private *i915, struct batch_vals *bv) | 55 | batch_get_defaults(struct drm_i915_private *i915, struct batch_vals *bv) |
| 51 | { | 56 | { |
| 52 | if (IS_HASWELL(i915)) { | 57 | if (IS_HASWELL(i915)) { |
| 53 | bv->max_primitives = 280; | 58 | switch (INTEL_INFO(i915)->gt) { |
| 54 | bv->max_urb_entries = MAX_URB_ENTRIES; | 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 | bv->surface_height = 16 * 16; | 70 | bv->surface_height = 16 * 16; |
| 56 | bv->surface_width = 32 * 2 * 16; | 71 | bv->surface_width = 32 * 2 * 16; |
| 57 | } else { | 72 | } else { |
| 58 | bv->max_primitives = 128; | 73 | switch (INTEL_INFO(i915)->gt) { |
| 59 | bv->max_urb_entries = MAX_URB_ENTRIES / 2; | 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 | bv->surface_height = 16 * 8; | 82 | bv->surface_height = 16 * 8; |
| 61 | bv->surface_width = 32 * 16; | 83 | bv->surface_width = 32 * 16; |
| 62 | } | 84 | } |
| 63 | bv->cmd_size = bv->max_primitives * 4096; | 85 | bv->state_start = round_up(SZ_1K + num_primitives(bv) * 64, SZ_4K); |
| 64 | bv->state_size = STATE_SIZE; | 86 | bv->surface_start = bv->state_start + SZ_4K; |
| 65 | bv->state_start = bv->cmd_size; | 87 | bv->size = bv->surface_start + bv->surface_height * bv->surface_width; |
| 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; | ||
| 69 | } | 88 | } |
| 70 | 89 | ||
| 71 | static void batch_init(struct batch_chunk *bc, | 90 | static void batch_init(struct batch_chunk *bc, |
| @@ -155,7 +174,8 @@ static u32 · 83 unmodified lines | |||
| 155 | gen7_fill_binding_table(struct batch_chunk *state, | 174 | gen7_fill_binding_table(struct batch_chunk *state, |
| 156 | const struct batch_vals *bv) | 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 | u32 *cs = batch_alloc_items(state, 32, 8); | 179 | u32 *cs = batch_alloc_items(state, 32, 8); |
| 160 | u32 offset = batch_offset(state, cs); | 180 | u32 offset = batch_offset(state, cs); |
| 161 | 181 | ||
| @@ -214,9 +234,9 @@ static void · 52 unmodified lines | |||
| 214 | gen7_emit_state_base_address(struct batch_chunk *batch, | 234 | gen7_emit_state_base_address(struct batch_chunk *batch, |
| 215 | u32 surface_state_base) | 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 | /* general */ | 240 | /* general */ |
| 221 | *cs++ = batch_addr(batch) | BASE_ADDRESS_MODIFY; | 241 | *cs++ = batch_addr(batch) | BASE_ADDRESS_MODIFY; |
| 222 | /* surface */ | 242 | /* surface */ |
| @@ -233,8 +253,6 @@ gen7_emit_state_base_address(struct batch_chunk *batch, · 10 unmodified lines | |||
| 233 | *cs++ = BASE_ADDRESS_MODIFY; | 253 | *cs++ = BASE_ADDRESS_MODIFY; |
| 234 | *cs++ = 0; | 254 | *cs++ = 0; |
| 235 | *cs++ = BASE_ADDRESS_MODIFY; | 255 | *cs++ = BASE_ADDRESS_MODIFY; |
| 236 | *cs++ = 0; | ||
| 237 | *cs++ = 0; | ||
| 238 | batch_advance(batch, cs); | 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 | u32 urb_size, u32 curbe_size, | 262 | u32 urb_size, u32 curbe_size, |
| 245 | u32 mode) | 263 | u32 mode) |
| 246 | { | 264 | { |
| 247 | u32 urb_entries = bv->max_urb_entries; | 265 | u32 threads = bv->max_threads - 1; |
| 248 | u32 threads = bv->max_primitives - 1; | ||
| 249 | u32 *cs = batch_alloc_items(batch, 32, 8); | 266 | u32 *cs = batch_alloc_items(batch, 32, 8); |
| 250 | 267 | ||
| 251 | *cs++ = MEDIA_VFE_STATE | (8 - 2); | 268 | *cs++ = MEDIA_VFE_STATE | (8 - 2); |
| @@ -254,7 +271,7 @@ gen7_emit_vfe_state(struct batch_chunk *batch, · 2 unmodified lines | |||
| 254 | *cs++ = 0; | 271 | *cs++ = 0; |
| 255 | 272 | ||
| 256 | /* number of threads & urb entries for GPGPU vs Media Mode */ | 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 | *cs++ = 0; | 276 | *cs++ = 0; |
| 260 | 277 | ||
| @@ -293,17 +310,12 @@ gen7_emit_media_object(struct batch_chunk *batch, · 32 unmodified lines | |||
| 293 | { | 310 | { |
| 294 | unsigned int x_offset = (media_object_index % 16) * 64; | 311 | unsigned int x_offset = (media_object_index % 16) * 64; |
| 295 | unsigned int y_offset = (media_object_index / 16) * 16; | 312 | unsigned int y_offset = (media_object_index / 16) * 16; |
| 296 | unsigned int inline_data_size; | 313 | unsigned int pkt = 6 + 3; |
| 297 | unsigned int media_batch_size; | ||
| 298 | unsigned int i; | ||
| 299 | u32 *cs; | 314 | u32 *cs; |
| 300 | 315 | ||
| 301 | inline_data_size = 112 * 8; | 316 | cs = batch_alloc_items(batch, 8, pkt); |
| 302 | media_batch_size = inline_data_size + 6; | ||
| 303 | |||
| 304 | cs = batch_alloc_items(batch, 8, media_batch_size); | ||
| 305 | 317 | ||
| 306 | *cs++ = MEDIA_OBJECT | (media_batch_size - 2); | 318 | *cs++ = MEDIA_OBJECT | (pkt - 2); |
| 307 | 319 | ||
| 308 | /* interface descriptor offset */ | 320 | /* interface descriptor offset */ |
| 309 | *cs++ = 0; | 321 | *cs++ = 0; |
| @@ -317,25 +329,44 @@ gen7_emit_media_object(struct batch_chunk *batch, · 7 unmodified lines | |||
| 317 | *cs++ = 0; | 329 | *cs++ = 0; |
| 318 | 330 | ||
| 319 | /* inline */ | 331 | /* inline */ |
| 320 | *cs++ = (y_offset << 16) | (x_offset); | 332 | *cs++ = y_offset << 16 | x_offset; |
| 321 | *cs++ = 0; | 333 | *cs++ = 0; |
| 322 | *cs++ = GT3_INLINE_DATA_DELAYS; | 334 | *cs++ = GT3_INLINE_DATA_DELAYS; |
| 323 | for (i = 3; i < inline_data_size; i++) | ||
| 324 | *cs++ = 0; | ||
| 325 | 335 | ||
| 326 | batch_advance(batch, cs); | 336 | batch_advance(batch, cs); |
| 327 | } | 337 | } |
| 328 | 338 | ||
| 329 | static void gen7_emit_pipeline_flush(struct batch_chunk *batch) | 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); | 343 | *cs++ = GFX_OP_PIPE_CONTROL(4); |
| 334 | *cs++ = PIPE_CONTROL_STATE_CACHE_INVALIDATE | | 344 | *cs++ = PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH | |
| 335 | PIPE_CONTROL_GLOBAL_GTT_IVB; | 345 | PIPE_CONTROL_DEPTH_CACHE_FLUSH | |
| 346 | PIPE_CONTROL_DC_FLUSH_ENABLE | | ||
| 347 | PIPE_CONTROL_CS_STALL; | ||
| 336 | *cs++ = 0; | 348 | *cs++ = 0; |
| 337 | *cs++ = 0; | 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 | *cs++ = 0; | 367 | *cs++ = 0; |
| 368 | *cs++ = 0; | ||
| 369 | |||
| 339 | batch_advance(batch, cs); | 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 | const struct batch_vals *bv) | 375 | const struct batch_vals *bv) |
| 345 | { | 376 | { |
| 346 | struct drm_i915_private *i915 = vma->vm->i915; | 377 | struct drm_i915_private *i915 = vma->vm->i915; |
| 347 | unsigned int desc_count = 64; | 378 | const unsigned int desc_count = 1; |
| 348 | const u32 urb_size = 112; | 379 | const unsigned int urb_size = 1; |
| 349 | struct batch_chunk cmds, state; | 380 | struct batch_chunk cmds, state; |
| 350 | u32 interface_descriptor; | 381 | u32 descriptors; |
| 351 | unsigned int i; | 382 | unsigned int i; |
| 352 | 383 | ||
| 353 | batch_init(&cmds, vma, start, 0, bv->cmd_size); | 384 | batch_init(&cmds, vma, start, 0, bv->state_start); |
| 354 | batch_init(&state, vma, start, bv->state_start, bv->state_size); | 385 | batch_init(&state, vma, start, bv->state_start, SZ_4K); |
| 355 | 386 | ||
| 356 | interface_descriptor = | 387 | descriptors = gen7_fill_interface_descriptor(&state, bv, |
| 357 | gen7_fill_interface_descriptor(&state, bv, | 388 | IS_HASWELL(i915) ? |
| 358 | IS_HASWELL(i915) ? | 389 | &cb_kernel_hsw : |
| 359 | &cb_kernel_hsw : | 390 | &cb_kernel_ivb, |
| 360 | &cb_kernel_ivb, | 391 | desc_count); |
| 361 | desc_count); | 392 | |
| 362 | gen7_emit_pipeline_flush(&cmds); | 393 | gen7_emit_pipeline_invalidate(&cmds); |
| 363 | batch_add(&cmds, PIPELINE_SELECT | PIPELINE_SELECT_MEDIA); | 394 | batch_add(&cmds, PIPELINE_SELECT | PIPELINE_SELECT_MEDIA); |
| 364 | batch_add(&cmds, MI_NOOP); | 395 | batch_add(&cmds, MI_NOOP); |
| 365 | gen7_emit_state_base_address(&cmds, interface_descriptor); | 396 | gen7_emit_pipeline_invalidate(&cmds); |
| 397 | |||
| 366 | gen7_emit_pipeline_flush(&cmds); | 398 | gen7_emit_pipeline_flush(&cmds); |
| 399 | gen7_emit_state_base_address(&cmds, descriptors); | ||
| 400 | gen7_emit_pipeline_invalidate(&cmds); | ||
| 367 | 401 | ||
| 368 | gen7_emit_vfe_state(&cmds, bv, urb_size - 1, 0, 0); | 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, | 405 | for (i = 0; i < num_primitives(bv); i++) |
| 371 | interface_descriptor, | ||
| 372 | desc_count); | ||
| 373 | |||
| 374 | for (i = 0; i < bv->max_primitives; i++) | ||
| 375 | gen7_emit_media_object(&cmds, i); | 406 | gen7_emit_media_object(&cmds, i); |
| 376 | 407 | ||
| 377 | batch_add(&cmds, MI_BATCH_BUFFER_END); | 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 | batch_get_defaults(engine->i915, &bv); | 417 | batch_get_defaults(engine->i915, &bv); |
| 387 | if (!vma) | 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 | batch = i915_gem_object_pin_map(vma->obj, I915_MAP_WC); | 423 | batch = i915_gem_object_pin_map(vma->obj, I915_MAP_WC); |
| 393 | if (IS_ERR(batch)) | 424 | if (IS_ERR(batch)) |
| 394 | return PTR_ERR(batch); | 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 | i915_gem_object_flush_map(vma->obj); | 429 | i915_gem_object_flush_map(vma->obj); |
| 399 | __i915_gem_object_release_map(vma->obj); | 430 | __i915_gem_object_release_map(vma->obj); |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | |||
| 32 | #include "gen6_ppgtt.h" | 32 | #include "gen6_ppgtt.h" |
| 33 | #include "gen7_renderclear.h" | 33 | #include "gen7_renderclear.h" |
| 34 | #include "i915_drv.h" | 34 | #include "i915_drv.h" |
| 35 | #include "i915_mitigations.h" | ||
| 35 | #include "intel_breadcrumbs.h" | 36 | #include "intel_breadcrumbs.h" |
| 36 | #include "intel_context.h" | 37 | #include "intel_context.h" |
| 37 | #include "intel_gt.h" | 38 | #include "intel_gt.h" |
| @@ -886,7 +887,8 @@ static int switch_context(struct i915_request *rq) · 848 unmodified lines | |||
| 886 | GEM_BUG_ON(HAS_EXECLISTS(engine->i915)); | 887 | GEM_BUG_ON(HAS_EXECLISTS(engine->i915)); |
| 887 | 888 | ||
| 888 | if (engine->wa_ctx.vma && ce != engine->kernel_context) { | 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 | ret = clear_residuals(rq); | 892 | ret = clear_residuals(rq); |
| 891 | if (ret) | 893 | if (ret) |
| 892 | return ret; | 894 | return ret; |
| @@ -1290,7 +1292,7 @@ int intel_ring_submission_setup(struct intel_engine_cs *engine) · 397 unmodified lines | |||
| 1290 | 1292 | ||
| 1291 | GEM_BUG_ON(timeline->hwsp_ggtt != engine->status_page.vma); | 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 | err = gen7_ctx_switch_bb_init(engine); | 1296 | err = gen7_ctx_switch_bb_init(engine); |
| 1295 | if (err) | 1297 | if (err) |
| 1296 | goto err_ring_unpin; | 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 | fw_def(ELKHARTLAKE, 0, guc_def(ehl, 49, 0, 1), huc_def(ehl, 9, 0, 0)) \ | 53 | fw_def(ELKHARTLAKE, 0, guc_def(ehl, 49, 0, 1), huc_def(ehl, 9, 0, 0)) \ |
| 54 | fw_def(ICELAKE, 0, guc_def(icl, 49, 0, 1), huc_def(icl, 9, 0, 0)) \ | 54 | fw_def(ICELAKE, 0, guc_def(icl, 49, 0, 1), huc_def(icl, 9, 0, 0)) \ |
| 55 | fw_def(COMETLAKE, 5, guc_def(cml, 49, 0, 1), huc_def(cml, 4, 0, 0)) \ | 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 | fw_def(COFFEELAKE, 0, guc_def(kbl, 49, 0, 1), huc_def(kbl, 4, 0, 0)) \ | 57 | fw_def(COFFEELAKE, 0, guc_def(kbl, 49, 0, 1), huc_def(kbl, 4, 0, 0)) \ |
| 57 | fw_def(GEMINILAKE, 0, guc_def(glk, 49, 0, 1), huc_def(glk, 4, 0, 0)) \ | 58 | fw_def(GEMINILAKE, 0, guc_def(glk, 49, 0, 1), huc_def(glk, 4, 0, 0)) \ |
| 58 | fw_def(KABYLAKE, 0, guc_def(kbl, 49, 0, 1), huc_def(kbl, 4, 0, 0)) \ | 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 | DDI_BUF_CTL_ENABLE); | 217 | DDI_BUF_CTL_ENABLE); |
| 218 | vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) |= DDI_BUF_IS_IDLE; | 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 | vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) &= ~(BIT(0) | BIT(1)); | 230 | vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) &= ~(BIT(0) | BIT(1)); |
| 222 | vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) &= | 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 | vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)) |= | 282 | vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)) |= |
| 274 | (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST | | 283 | (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST | |
| 275 | TRANS_DDI_FUNC_ENABLE); | 284 | TRANS_DDI_FUNC_ENABLE); |
| 285 | vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | ||
| 286 | PORTA_HOTPLUG_ENABLE; | ||
| 276 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= | 287 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= |
| 277 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_A); | 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 | (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST | | 312 | (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST | |
| 302 | (PORT_B << TRANS_DDI_PORT_SHIFT) | | 313 | (PORT_B << TRANS_DDI_PORT_SHIFT) | |
| 303 | TRANS_DDI_FUNC_ENABLE); | 314 | TRANS_DDI_FUNC_ENABLE); |
| 315 | vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | ||
| 316 | PORTB_HOTPLUG_ENABLE; | ||
| 304 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= | 317 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= |
| 305 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_B); | 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 | (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST | | 342 | (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST | |
| 330 | (PORT_B << TRANS_DDI_PORT_SHIFT) | | 343 | (PORT_B << TRANS_DDI_PORT_SHIFT) | |
| 331 | TRANS_DDI_FUNC_ENABLE); | 344 | TRANS_DDI_FUNC_ENABLE); |
| 345 | vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= | ||
| 346 | PORTC_HOTPLUG_ENABLE; | ||
| 332 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= | 347 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= |
| 333 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_C); | 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 | PORTD_HOTPLUG_STATUS_MASK; | 676 | PORTD_HOTPLUG_STATUS_MASK; |
| 662 | intel_vgpu_trigger_virtual_event(vgpu, DP_D_HOTPLUG); | 677 | intel_vgpu_trigger_virtual_event(vgpu, DP_D_HOTPLUG); |
| 663 | } else if (IS_BROXTON(i915)) { | 678 | } else if (IS_BROXTON(i915)) { |
| 664 | if (connected) { | 679 | if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) { |
| 665 | if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) { | 680 | if (connected) { |
| 666 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= | 681 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= |
| 667 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_A); | 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)) { | 687 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |= |
| 670 | vgpu_vreg_t(vgpu, SFUSE_STRAP) |= | 688 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_A); |
| 671 | SFUSE_STRAP_DDIB_DETECTED; | 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 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= | 697 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= |
| 673 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_B); | 698 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_B); |
| 674 | } | ||
| 675 | if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) { | ||
| 676 | vgpu_vreg_t(vgpu, SFUSE_STRAP) |= | 699 | vgpu_vreg_t(vgpu, SFUSE_STRAP) |= |
| 677 | SFUSE_STRAP_DDIC_DETECTED; | 700 | SFUSE_STRAP_DDIB_DETECTED; |
| 678 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= | 701 | } else { |
| 679 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_C); | ||
| 680 | } | ||
| 681 | } else { | ||
| 682 | if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) { | ||
| 683 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= | 702 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= |
| 684 | ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_A); | 703 | ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_B); |
| 685 | } | ||
| 686 | if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) { | ||
| 687 | vgpu_vreg_t(vgpu, SFUSE_STRAP) &= | 704 | vgpu_vreg_t(vgpu, SFUSE_STRAP) &= |
| 688 | ~SFUSE_STRAP_DDIB_DETECTED; | 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)) { | 707 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |= |
| 693 | vgpu_vreg_t(vgpu, SFUSE_STRAP) &= | 708 | GEN8_DE_PORT_HOTPLUG(HPD_PORT_B); |
| 694 | ~SFUSE_STRAP_DDIC_DETECTED; | 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 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= | 722 | vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= |
| 696 | ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_C); | 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 | if (ret) | 437 | if (ret) |
| 438 | goto out_clean_sched_policy; | 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 | ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_B); | 441 | ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_B); |
| 442 | /* FixMe: Re-enable APL/BXT once vfio_edid enabled */ | 442 | else |
| 443 | else if (!IS_BROXTON(dev_priv)) | ||
| 444 | ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_D); | 443 | ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_D); |
| 445 | if (ret) | 444 | if (ret) |
| 446 | goto out_clean_sched_policy; | 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 | if (IS_ERR(src)) { | 1168 | if (IS_ERR(src)) { |
| 1169 | unsigned long x, n; | 1169 | unsigned long x, n, remain; |
| 1170 | void *ptr; | 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 | * We don't care about copying too much here as we only | 1177 | * We don't care about copying too much here as we only |
| 1178 | * validate up to the end of the batch. | 1178 | * validate up to the end of the batch. |
| 1179 | */ | 1179 | */ |
| 1180 | remain = length; | ||
| 1180 | if (!(dst_obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)) | 1181 | if (!(dst_obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)) |
| 1181 | length = round_up(length, | 1182 | remain = round_up(remain, |
| 1182 | boot_cpu_data.x86_clflush_size); | 1183 | boot_cpu_data.x86_clflush_size); |
| 1183 | 1184 | ||
| 1184 | ptr = dst; | 1185 | ptr = dst; |
| 1185 | x = offset_in_page(offset); | 1186 | x = offset_in_page(offset); |
| 1186 | for (n = offset >> PAGE_SHIFT; length; n++) { | 1187 | for (n = offset >> PAGE_SHIFT; remain; n++) { |
| 1187 | int len = min(length, PAGE_SIZE - x); | 1188 | int len = min(remain, PAGE_SIZE - x); |
| 1188 | 1189 | ||
| 1189 | src = kmap_atomic(i915_gem_object_get_page(src_obj, n)); | 1190 | src = kmap_atomic(i915_gem_object_get_page(src_obj, n)); |
| 1190 | if (needs_clflush) | 1191 | if (needs_clflush) |
| @@ -1193,13 +1194,15 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, · 2 unmodified lines | |||
| 1193 | kunmap_atomic(src); | 1194 | kunmap_atomic(src); |
| 1194 | 1195 | ||
| 1195 | ptr += len; | 1196 | ptr += len; |
| 1196 | length -= len; | 1197 | remain -= len; |
| 1197 | x = 0; | 1198 | x = 0; |
| 1198 | } | 1199 | } |
| 1199 | } | 1200 | } |
| 1200 | 1201 | ||
| 1201 | i915_gem_object_unpin_pages(src_obj); | 1202 | i915_gem_object_unpin_pages(src_obj); |
| 1202 | 1203 | ||
| 1204 | memset32(dst + length, 0, (dst_obj->base.size - length) / sizeof(u32)); | ||
| 1205 | |||
| 1203 | /* dst_obj is returned with vmap pinned */ | 1206 | /* dst_obj is returned with vmap pinned */ |
| 1204 | return dst; | 1207 | return dst; |
| 1205 | } | 1208 | } |
| @@ -1392,11 +1395,6 @@ static unsigned long *alloc_whitelist(u32 batch_length) · 186 unmodified lines | |||
| 1392 | 1395 | ||
| 1393 | #define LENGTH_BIAS 2 | 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 | * intel_engine_cmd_parser() - parse a batch buffer for privilege violations | 1399 | * intel_engine_cmd_parser() - parse a batch buffer for privilege violations |
| 1402 | * @engine: the engine on which the batch is to execute | 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 | ret = 0; /* allow execution */ | 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)) { | 1541 | i915_gem_object_flush_map(shadow->obj); |
| 1547 | void *ptr = page_mask_bits(shadow->obj->mm.mapping); | ||
| 1548 | |||
| 1549 | drm_clflush_virt_range(ptr, (void *)(cmd + 1) - ptr); | ||
| 1550 | } | ||
| 1551 | 1542 | ||
| 1552 | if (!IS_ERR_OR_NULL(jump_whitelist)) | 1543 | if (!IS_ERR_OR_NULL(jump_whitelist)) |
| 1553 | kfree(jump_whitelist); | 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 | pci_set_master(pdev); | 579 | pci_set_master(pdev); |
| 580 | 580 | ||
| 581 | cpu_latency_qos_add_request(&dev_priv->pm_qos, PM_QOS_DEFAULT_VALUE); | ||
| 582 | |||
| 583 | intel_gt_init_workarounds(dev_priv); | 581 | intel_gt_init_workarounds(dev_priv); |
| 584 | 582 | ||
| 585 | /* On the 945G/GM, the chipset reports the MSI capability on the | 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 | err_msi: | 624 | err_msi: |
| 627 | if (pdev->msi_enabled) | 625 | if (pdev->msi_enabled) |
| 628 | pci_disable_msi(pdev); | 626 | pci_disable_msi(pdev); |
| 629 | cpu_latency_qos_remove_request(&dev_priv->pm_qos); | ||
| 630 | err_mem_regions: | 627 | err_mem_regions: |
| 631 | intel_memory_regions_driver_release(dev_priv); | 628 | intel_memory_regions_driver_release(dev_priv); |
| 632 | err_ggtt: | 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 | if (pdev->msi_enabled) | 646 | if (pdev->msi_enabled) |
| 650 | pci_disable_msi(pdev); | 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 | void i915_driver_shutdown(struct drm_i915_private *i915) | 1048 | void i915_driver_shutdown(struct drm_i915_private *i915) |
| 1054 | { | 1049 | { |
| 1050 | disable_rpm_wakeref_asserts(&i915->runtime_pm); | ||
| 1051 | |||
| 1055 | i915_gem_suspend(i915); | 1052 | i915_gem_suspend(i915); |
| 1056 | 1053 | ||
| 1057 | drm_kms_helper_poll_disable(&i915->drm); | 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 | intel_suspend_encoders(i915); | 1063 | intel_suspend_encoders(i915); |
| 1067 | intel_shutdown_encoders(i915); | 1064 | intel_shutdown_encoders(i915); |
| 1065 | |||
| 1066 | enable_rpm_wakeref_asserts(&i915->runtime_pm); | ||
| 1068 | } | 1067 | } |
| 1069 | 1068 | ||
| 1070 | static bool suspend_to_idle(struct drm_i915_private *dev_priv) | 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 | bool display_irqs_enabled; | 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 | /* Sideband mailbox protection */ | 894 | /* Sideband mailbox protection */ |
| 898 | struct mutex sb_lock; | 895 | struct mutex sb_lock; |
| 899 | struct pm_qos_request sb_qos; | 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 | if (!gpu->aspace) { | 535 | if (!gpu->aspace) { |
| 536 | dev_err(dev->dev, "No memory protection without MMU\n"); | 536 | dev_err(dev->dev, "No memory protection without MMU\n"); |
| 537 | ret = -ENXIO; | 537 | if (!allow_vram_carveout) { |
| 538 | goto fail; | 538 | ret = -ENXIO; |
| 539 | goto fail; | ||
| 540 | } | ||
| 539 | } | 541 | } |
| 540 | 542 | ||
| 541 | return gpu; | 543 | return gpu; |
| @@ -564,8 +564,10 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) · 563 unmodified lines | |||
| 564 | * implement a cmdstream validator. | 564 | * implement a cmdstream validator. |
| 565 | */ | 565 | */ |
| 566 | DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n"); | 566 | DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n"); |
| 567 | ret = -ENXIO; | 567 | if (!allow_vram_carveout) { |
| 568 | goto fail; | 568 | ret = -ENXIO; |
| 569 | goto fail; | ||
| 570 | } | ||
| 569 | } | 571 | } |
| 570 | 572 | ||
| 571 | icc_path = devm_of_icc_get(&pdev->dev, "gfx-mem"); | 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 | * implement a cmdstream validator. | 692 | * implement a cmdstream validator. |
| 693 | */ | 693 | */ |
| 694 | DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n"); | 694 | DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n"); |
| 695 | ret = -ENXIO; | 695 | if (!allow_vram_carveout) { |
| 696 | goto fail; | 696 | ret = -ENXIO; |
| 697 | goto fail; | ||
| 698 | } | ||
| 697 | } | 699 | } |
| 698 | 700 | ||
| 699 | icc_path = devm_of_icc_get(&pdev->dev, "gfx-mem"); | 701 | icc_path = devm_of_icc_get(&pdev->dev, "gfx-mem"); |
| @@ -18,6 +18,10 @@ bool snapshot_debugbus = false; · 17 unmodified lines | |||
| 18 | MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)"); | 18 | MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)"); |
| 19 | module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600); | 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 | static const struct adreno_info gpulist[] = { | 25 | static const struct adreno_info gpulist[] = { |
| 22 | { | 26 | { |
| 23 | .rev = ADRENO_REV(2, 0, 0, 0), | 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 | struct platform_device *pdev) | 191 | struct platform_device *pdev) |
| 192 | { | 192 | { |
| 193 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); | 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 | struct iommu_domain *iommu; | 194 | struct iommu_domain *iommu; |
| 197 | struct msm_mmu *mmu; | 195 | struct msm_mmu *mmu; |
| 198 | struct msm_gem_address_space *aspace; | 196 | struct msm_gem_address_space *aspace; |
| @@ -202,13 +200,18 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu, · 3 unmodified lines | |||
| 202 | if (!iommu) | 200 | if (!iommu) |
| 203 | return NULL; | 201 | return NULL; |
| 204 | 202 | ||
| 205 | /* | 203 | |
| 206 | * This allows GPU to set the bus attributes required to use system | 204 | if (adreno_is_a6xx(adreno_gpu)) { |
| 207 | * cache on behalf of the iommu page table walker. | 205 | struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); |
| 208 | */ | 206 | struct io_pgtable_domain_attr pgtbl_cfg; |
| 209 | if (!IS_ERR(a6xx_gpu->htw_llc_slice)) { | 207 | /* |
| 210 | pgtbl_cfg.quirks = IO_PGTABLE_QUIRK_ARM_OUTER_WBWA; | 208 | * This allows GPU to set the bus attributes required to use system |
| 211 | iommu_domain_set_attr(iommu, DOMAIN_ATTR_IO_PGTABLE_CFG, &pgtbl_cfg); | 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 | mmu = msm_iommu_new(&pdev->dev, iommu); | 217 | mmu = msm_iommu_new(&pdev->dev, iommu); |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | #include "adreno_pm4.xml.h" | 18 | #include "adreno_pm4.xml.h" |
| 19 | 19 | ||
| 20 | extern bool snapshot_debugbus; | 20 | extern bool snapshot_debugbus; |
| 21 | extern bool allow_vram_carveout; | ||
| 21 | 22 | ||
| 22 | enum { | 23 | enum { |
| 23 | ADRENO_FW_PM4 = 0, | 24 | ADRENO_FW_PM4 = 0, |
| @@ -211,6 +212,11 @@ static inline int adreno_is_a540(struct adreno_gpu *gpu) · 187 unmodified lines | |||
| 211 | return gpu->revn == 540; | 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 | static inline int adreno_is_a618(struct adreno_gpu *gpu) | 220 | static inline int adreno_is_a618(struct adreno_gpu *gpu) |
| 215 | { | 221 | { |
| 216 | return gpu->revn == 618; | 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 | return 0; | 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 | ret = dp_display_usbpd_attention_cb(&dp->pdev->dev); | 703 | ret = dp_display_usbpd_attention_cb(&dp->pdev->dev); |
| 697 | if (ret == -ECONNRESET) { /* cable unplugged */ | 704 | if (ret == -ECONNRESET) { /* cable unplugged */ |
| 698 | dp->core_initialized = false; | 705 | dp->core_initialized = false; |
| @@ -167,12 +167,18 @@ int dp_panel_read_sink_caps(struct dp_panel *dp_panel, · 166 unmodified lines | |||
| 167 | panel = container_of(dp_panel, struct dp_panel_private, dp_panel); | 167 | panel = container_of(dp_panel, struct dp_panel_private, dp_panel); |
| 168 | 168 | ||
| 169 | rc = dp_panel_read_dpcd(dp_panel); | 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 | bw_code = drm_dp_link_rate_to_bw_code(dp_panel->link_info.rate); | 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 | !is_lane_count_valid(dp_panel->link_info.num_lanes) || | 177 | !is_lane_count_valid(dp_panel->link_info.num_lanes) || |
| 173 | (bw_code > dp_panel->max_bw_code)) { | 178 | (bw_code > dp_panel->max_bw_code)) { |
| 174 | DRM_ERROR("read dpcd failed %d\n", rc); | 179 | DRM_ERROR("Illegal link rate=%d lane=%d\n", dp_panel->link_info.rate, |
| 175 | return rc; | 180 | dp_panel->link_info.num_lanes); |
| 181 | return -EINVAL; | ||
| 176 | } | 182 | } |
| 177 | 183 | ||
| 178 | if (dp_panel->dfp_present) { | 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 | drm_mode_config_init(ddev); | 458 | drm_mode_config_init(ddev); |
| 459 | 459 | ||
| 460 | /* Bind all our sub-components: */ | 460 | ret = msm_init_vram(ddev); |
| 461 | ret = component_bind_all(dev, ddev); | ||
| 462 | if (ret) | 461 | if (ret) |
| 463 | goto err_destroy_mdss; | 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 | if (ret) | 466 | if (ret) |
| 467 | goto err_msm_uninit; | 467 | goto err_destroy_mdss; |
| 468 | 468 | ||
| 469 | dma_set_max_seg_size(dev, UINT_MAX); | 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 | struct msm_gem_object *msm_obj = to_msm_bo(obj); | 97 | struct msm_gem_object *msm_obj = to_msm_bo(obj); |
| 98 | 98 | ||
| 99 | WARN_ON(!msm_gem_is_locked(obj)); | ||
| 100 | |||
| 99 | if (!msm_obj->pages) { | 101 | if (!msm_obj->pages) { |
| 100 | struct drm_device *dev = obj->dev; | 102 | struct drm_device *dev = obj->dev; |
| 101 | struct page **p; | 103 | struct page **p; |
| @@ -988,6 +990,8 @@ void msm_gem_free_object(struct drm_gem_object *obj) · 886 unmodified lines | |||
| 988 | if (msm_obj->pages) | 990 | if (msm_obj->pages) |
| 989 | kvfree(msm_obj->pages); | 991 | kvfree(msm_obj->pages); |
| 990 | 992 | ||
| 993 | put_iova_vmas(obj); | ||
| 994 | |||
| 991 | /* dma_buf_detach() grabs resv lock, so we need to unlock | 995 | /* dma_buf_detach() grabs resv lock, so we need to unlock |
| 992 | * prior to drm_prime_gem_destroy | 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 | } else { | 1001 | } else { |
| 998 | msm_gem_vunmap(obj); | 1002 | msm_gem_vunmap(obj); |
| 999 | put_pages(obj); | 1003 | put_pages(obj); |
| 1004 | put_iova_vmas(obj); | ||
| 1000 | msm_gem_unlock(obj); | 1005 | msm_gem_unlock(obj); |
| 1001 | } | 1006 | } |
| 1002 | 1007 | ||
| 1003 | put_iova_vmas(obj); | ||
| 1004 | |||
| 1005 | drm_gem_object_release(obj); | 1008 | drm_gem_object_release(obj); |
| 1006 | 1009 | ||
| 1007 | kfree(msm_obj); | 1010 | kfree(msm_obj); |
| @@ -1115,6 +1118,8 @@ static struct drm_gem_object *_msm_gem_new(struct drm_device *dev, · 107 unmodified lines | |||
| 1115 | struct msm_gem_vma *vma; | 1118 | struct msm_gem_vma *vma; |
| 1116 | struct page **pages; | 1119 | struct page **pages; |
| 1117 | 1120 | ||
| 1121 | drm_gem_private_object_init(dev, obj, size); | ||
| 1122 | |||
| 1118 | msm_gem_lock(obj); | 1123 | msm_gem_lock(obj); |
| 1119 | 1124 | ||
| 1120 | vma = add_vma(obj, NULL); | 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 | to_msm_bo(obj)->vram_node = &vma->node; | 1132 | to_msm_bo(obj)->vram_node = &vma->node; |
| 1128 | 1133 | ||
| 1129 | drm_gem_private_object_init(dev, obj, size); | 1134 | msm_gem_lock(obj); |
| 1130 | |||
| 1131 | pages = get_pages(obj); | 1135 | pages = get_pages(obj); |
| 1136 | msm_gem_unlock(obj); | ||
| 1132 | if (IS_ERR(pages)) { | 1137 | if (IS_ERR(pages)) { |
| 1133 | ret = PTR_ERR(pages); | 1138 | ret = PTR_ERR(pages); |
| 1134 | goto fail; | 1139 | goto fail; |
| @@ -37,6 +37,7 @@ nouveau-y += dispnv50/wimmc37b.o · 36 unmodified lines | |||
| 37 | nouveau-y += dispnv50/wndw.o | 37 | nouveau-y += dispnv50/wndw.o |
| 38 | nouveau-y += dispnv50/wndwc37e.o | 38 | nouveau-y += dispnv50/wndwc37e.o |
| 39 | nouveau-y += dispnv50/wndwc57e.o | 39 | nouveau-y += dispnv50/wndwc57e.o |
| 40 | nouveau-y += dispnv50/wndwc67e.o | ||
| 40 | 41 | ||
| 41 | nouveau-y += dispnv50/base.o | 42 | nouveau-y += dispnv50/base.o |
| 42 | nouveau-y += dispnv50/base507c.o | 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 | int version; | 42 | int version; |
| 43 | int (*new)(struct nouveau_drm *, s32, struct nv50_core **); | 43 | int (*new)(struct nouveau_drm *, s32, struct nv50_core **); |
| 44 | } cores[] = { | 44 | } cores[] = { |
| 45 | { GA102_DISP_CORE_CHANNEL_DMA, 0, corec57d_new }, | ||
| 45 | { TU102_DISP_CORE_CHANNEL_DMA, 0, corec57d_new }, | 46 | { TU102_DISP_CORE_CHANNEL_DMA, 0, corec57d_new }, |
| 46 | { GV100_DISP_CORE_CHANNEL_DMA, 0, corec37d_new }, | 47 | { GV100_DISP_CORE_CHANNEL_DMA, 0, corec37d_new }, |
| 47 | { GP102_DISP_CORE_CHANNEL_DMA, 0, core917d_new }, | 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 | int version; | 31 | int version; |
| 32 | int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); | 32 | int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); |
| 33 | } curses[] = { | 33 | } curses[] = { |
| 34 | { GA102_DISP_CURSOR, 0, cursc37a_new }, | ||
| 34 | { TU102_DISP_CURSOR, 0, cursc37a_new }, | 35 | { TU102_DISP_CURSOR, 0, cursc37a_new }, |
| 35 | { GV100_DISP_CURSOR, 0, cursc37a_new }, | 36 | { GV100_DISP_CURSOR, 0, cursc37a_new }, |
| 36 | { GK104_DISP_CURSOR, 0, curs907a_new }, | 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 | int | 223 | int |
| 224 | nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, | 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 | struct nv50_dmac *dmac) | 226 | struct nv50_dmac *dmac) |
| 227 | { | 227 | { |
| 228 | struct nouveau_cli *cli = (void *)device->object.client; | 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 | if (ret) | 271 | if (ret) |
| 272 | return ret; | 272 | return ret; |
| 273 | 273 | ||
| 274 | if (!syncbuf) | 274 | if (syncbuf < 0) |
| 275 | return 0; | 275 | return 0; |
| 276 | 276 | ||
| 277 | ret = nvif_object_ctor(&dmac->base.user, "kmsSyncCtxDma", NV50_DISP_HANDLE_SYNCBUF, | 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 | int nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, | 96 | int nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, |
| 97 | const s32 *oclass, u8 head, void *data, u32 size, | 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 | void nv50_dmac_destroy(struct nv50_dmac *); | 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 | int version; | 31 | int version; |
| 32 | int (*init)(struct nouveau_drm *, s32, struct nv50_wndw *); | 32 | int (*init)(struct nouveau_drm *, s32, struct nv50_wndw *); |
| 33 | } wimms[] = { | 33 | } wimms[] = { |
| 34 | { GA102_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, | ||
| 34 | { TU102_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, | 35 | { TU102_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, |
| 35 | { GV100_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, | 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 | int ret; | 76 | int ret; |
| 77 | 77 | ||
| 78 | ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, | 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 | &wndw->wimm); | 80 | &wndw->wimm); |
| 81 | if (ret) { | 81 | if (ret) { |
| 82 | NV_ERROR(drm, "wimm%04x allocation failed: %d\n", oclass, ret); | 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 | int (*new)(struct nouveau_drm *, enum drm_plane_type, | 784 | int (*new)(struct nouveau_drm *, enum drm_plane_type, |
| 785 | int, s32, struct nv50_wndw **); | 785 | int, s32, struct nv50_wndw **); |
| 786 | } wndws[] = { | 786 | } wndws[] = { |
| 787 | { GA102_DISP_WINDOW_CHANNEL_DMA, 0, wndwc67e_new }, | ||
| 787 | { TU102_DISP_WINDOW_CHANNEL_DMA, 0, wndwc57e_new }, | 788 | { TU102_DISP_WINDOW_CHANNEL_DMA, 0, wndwc57e_new }, |
| 788 | { GV100_DISP_WINDOW_CHANNEL_DMA, 0, wndwc37e_new }, | 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 | int wndwc57e_new(struct nouveau_drm *, enum drm_plane_type, int, s32, | 130 | int wndwc57e_new(struct nouveau_drm *, enum drm_plane_type, int, s32, |
| 131 | struct nv50_wndw **); | 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 | int nv50_wndw_new(struct nouveau_drm *, enum drm_plane_type, int index, | 141 | int nv50_wndw_new(struct nouveau_drm *, enum drm_plane_type, int index, |
| 134 | struct nv50_wndw **); | 142 | struct nv50_wndw **); |
| @@ -80,7 +80,7 @@ wndwc57e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) · 79 unmodified lines | |||
| 80 | return 0; | 80 | return 0; |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | static int | 83 | int |
| 84 | wndwc57e_csc_clr(struct nv50_wndw *wndw) | 84 | wndwc57e_csc_clr(struct nv50_wndw *wndw) |
| 85 | { | 85 | { |
| 86 | struct nvif_push *push = wndw->wndw.push; | 86 | struct nvif_push *push = wndw->wndw.push; |
| @@ -98,7 +98,7 @@ wndwc57e_csc_clr(struct nv50_wndw *wndw) · 11 unmodified lines | |||
| 98 | return 0; | 98 | return 0; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | static int | 101 | int |
| 102 | wndwc57e_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) | 102 | wndwc57e_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) |
| 103 | { | 103 | { |
| 104 | struct nvif_push *push = wndw->wndw.push; | 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 | return 0; | 111 | return 0; |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | static int | 114 | int |
| 115 | wndwc57e_ilut_clr(struct nv50_wndw *wndw) | 115 | wndwc57e_ilut_clr(struct nv50_wndw *wndw) |
| 116 | { | 116 | { |
| 117 | struct nvif_push *push = wndw->wndw.push; | 117 | struct nvif_push *push = wndw->wndw.push; |
| @@ -124,7 +124,7 @@ wndwc57e_ilut_clr(struct nv50_wndw *wndw) · 6 unmodified lines | |||
| 124 | return 0; | 124 | return 0; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | static int | 127 | int |
| 128 | wndwc57e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) | 128 | wndwc57e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) |
| 129 | { | 129 | { |
| 130 | struct nvif_push *push = wndw->wndw.push; | 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 | writew(readw(mem - 4), mem + 4); | 179 | writew(readw(mem - 4), mem + 4); |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | static bool | 182 | bool |
| 183 | wndwc57e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size) | 183 | wndwc57e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size) |
| 184 | { | 184 | { |
| 185 | if (size = size ? size : 1024, size != 256 && size != 1024) | 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 | #define NV_DEVICE_INFO_V0_PASCAL 0x0a | 33 | #define NV_DEVICE_INFO_V0_PASCAL 0x0a |
| 34 | #define NV_DEVICE_INFO_V0_VOLTA 0x0b | 34 | #define NV_DEVICE_INFO_V0_VOLTA 0x0b |
| 35 | #define NV_DEVICE_INFO_V0_TURING 0x0c | 35 | #define NV_DEVICE_INFO_V0_TURING 0x0c |
| 36 | #define NV_DEVICE_INFO_V0_AMPERE 0x0d | ||
| 36 | __u8 family; | 37 | __u8 family; |
| 37 | __u8 pad06[2]; | 38 | __u8 pad06[2]; |
| 38 | __u64 ram_size; | 39 | __u64 ram_size; |
| @@ -88,6 +88,7 @@ · 87 unmodified lines | |||
| 88 | #define GP102_DISP /* cl5070.h */ 0x00009870 | 88 | #define GP102_DISP /* cl5070.h */ 0x00009870 |
| 89 | #define GV100_DISP /* cl5070.h */ 0x0000c370 | 89 | #define GV100_DISP /* cl5070.h */ 0x0000c370 |
| 90 | #define TU102_DISP /* cl5070.h */ 0x0000c570 | 90 | #define TU102_DISP /* cl5070.h */ 0x0000c570 |
| 91 | #define GA102_DISP /* cl5070.h */ 0x0000c670 | ||
| 91 | 92 | ||
| 92 | #define GV100_DISP_CAPS 0x0000c373 | 93 | #define GV100_DISP_CAPS 0x0000c373 |
| 93 | 94 | ||
| @@ -103,6 +104,7 @@ · 9 unmodified lines | |||
| 103 | #define GK104_DISP_CURSOR /* cl507a.h */ 0x0000917a | 104 | #define GK104_DISP_CURSOR /* cl507a.h */ 0x0000917a |
| 104 | #define GV100_DISP_CURSOR /* cl507a.h */ 0x0000c37a | 105 | #define GV100_DISP_CURSOR /* cl507a.h */ 0x0000c37a |
| 105 | #define TU102_DISP_CURSOR /* cl507a.h */ 0x0000c57a | 106 | #define TU102_DISP_CURSOR /* cl507a.h */ 0x0000c57a |
| 107 | #define GA102_DISP_CURSOR /* cl507a.h */ 0x0000c67a | ||
| 106 | 108 | ||
| 107 | #define NV50_DISP_OVERLAY /* cl507b.h */ 0x0000507b | 109 | #define NV50_DISP_OVERLAY /* cl507b.h */ 0x0000507b |
| 108 | #define G82_DISP_OVERLAY /* cl507b.h */ 0x0000827b | 110 | #define G82_DISP_OVERLAY /* cl507b.h */ 0x0000827b |
| @@ -112,6 +114,7 @@ · 3 unmodified lines | |||
| 112 | 114 | ||
| 113 | #define GV100_DISP_WINDOW_IMM_CHANNEL_DMA /* clc37b.h */ 0x0000c37b | 115 | #define GV100_DISP_WINDOW_IMM_CHANNEL_DMA /* clc37b.h */ 0x0000c37b |
| 114 | #define TU102_DISP_WINDOW_IMM_CHANNEL_DMA /* clc37b.h */ 0x0000c57b | 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 | #define NV50_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000507c | 119 | #define NV50_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000507c |
| 117 | #define G82_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000827c | 120 | #define G82_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000827c |
| @@ -135,6 +138,7 @@ · 17 unmodified lines | |||
| 135 | #define GP102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000987d | 138 | #define GP102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000987d |
| 136 | #define GV100_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c37d | 139 | #define GV100_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c37d |
| 137 | #define TU102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c57d | 140 | #define TU102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c57d |
| 141 | #define GA102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c67d | ||
| 138 | 142 | ||
| 139 | #define NV50_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000507e | 143 | #define NV50_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000507e |
| 140 | #define G82_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000827e | 144 | #define G82_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000827e |
| @@ -145,6 +149,7 @@ · 4 unmodified lines | |||
| 145 | 149 | ||
| 146 | #define GV100_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c37e | 150 | #define GV100_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c37e |
| 147 | #define TU102_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c57e | 151 | #define TU102_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c57e |
| 152 | #define GA102_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c67e | ||
| 148 | 153 | ||
| 149 | #define NV50_TESLA 0x00005097 | 154 | #define NV50_TESLA 0x00005097 |
| 150 | #define G82_TESLA 0x00008297 | 155 | #define G82_TESLA 0x00008297 |
| @@ -120,6 +120,7 @@ struct nvkm_device { · 119 unmodified lines | |||
| 120 | GP100 = 0x130, | 120 | GP100 = 0x130, |
| 121 | GV100 = 0x140, | 121 | GV100 = 0x140, |
| 122 | TU100 = 0x160, | 122 | TU100 = 0x160, |
| 123 | GA100 = 0x170, | ||
| 123 | } card_type; | 124 | } card_type; |
| 124 | u32 chipset; | 125 | u32 chipset; |
| 125 | u8 chiprev; | 126 | u8 chiprev; |
| @@ -37,4 +37,5 @@ int gp100_disp_new(struct nvkm_device *, int, struct nvkm_disp **); · 36 unmodified lines | |||
| 37 | int gp102_disp_new(struct nvkm_device *, int, struct nvkm_disp **); | 37 | int gp102_disp_new(struct nvkm_device *, int, struct nvkm_disp **); |
| 38 | int gv100_disp_new(struct nvkm_device *, int, struct nvkm_disp **); | 38 | int gv100_disp_new(struct nvkm_device *, int, struct nvkm_disp **); |
| 39 | int tu102_disp_new(struct nvkm_device *, int, struct nvkm_disp **); | 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 | #endif | 41 | #endif |
| @@ -32,4 +32,5 @@ int gm107_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); · 31 unmodified lines | |||
| 32 | int gm200_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); | 32 | int gm200_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); |
| 33 | int gv100_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); | 33 | int gv100_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); |
| 34 | int tu102_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); | 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 | #endif | 36 | #endif |
| @@ -86,6 +86,8 @@ int gp100_fb_new(struct nvkm_device *, int, struct nvkm_fb **); · 85 unmodified lines | |||
| 86 | int gp102_fb_new(struct nvkm_device *, int, struct nvkm_fb **); | 86 | int gp102_fb_new(struct nvkm_device *, int, struct nvkm_fb **); |
| 87 | int gp10b_fb_new(struct nvkm_device *, int, struct nvkm_fb **); | 87 | int gp10b_fb_new(struct nvkm_device *, int, struct nvkm_fb **); |
| 88 | int gv100_fb_new(struct nvkm_device *, int, struct nvkm_fb **); | 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 | #include <subdev/bios.h> | 92 | #include <subdev/bios.h> |
| 91 | #include <subdev/bios/ramcfg.h> | 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 | int g94_gpio_new(struct nvkm_device *, int, struct nvkm_gpio **); | 37 | int g94_gpio_new(struct nvkm_device *, int, struct nvkm_gpio **); |
| 38 | int gf119_gpio_new(struct nvkm_device *, int, struct nvkm_gpio **); | 38 | int gf119_gpio_new(struct nvkm_device *, int, struct nvkm_gpio **); |
| 39 | int gk104_gpio_new(struct nvkm_device *, int, struct nvkm_gpio **); | 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 | #endif | 41 | #endif |
| @@ -92,6 +92,7 @@ int g94_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); · 91 unmodified lines | |||
| 92 | int gf117_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); | 92 | int gf117_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); |
| 93 | int gf119_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); | 93 | int gf119_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); |
| 94 | int gk104_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); | 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 | int gm200_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); | 96 | int gm200_i2c_new(struct nvkm_device *, int, struct nvkm_i2c **); |
| 96 | 97 | ||
| 97 | static inline int | 98 | static inline int |
| @@ -32,4 +32,5 @@ int gk20a_mc_new(struct nvkm_device *, int, struct nvkm_mc **); · 31 unmodified lines | |||
| 32 | int gp100_mc_new(struct nvkm_device *, int, struct nvkm_mc **); | 32 | int gp100_mc_new(struct nvkm_device *, int, struct nvkm_mc **); |
| 33 | int gp10b_mc_new(struct nvkm_device *, int, struct nvkm_mc **); | 33 | int gp10b_mc_new(struct nvkm_device *, int, struct nvkm_mc **); |
| 34 | int tu102_mc_new(struct nvkm_device *, int, struct nvkm_mc **); | 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 | #endif | 36 | #endif |
| @@ -256,6 +256,7 @@ nouveau_backlight_init(struct drm_connector *connector) · 255 unmodified lines | |||
| 256 | case NV_DEVICE_INFO_V0_PASCAL: | 256 | case NV_DEVICE_INFO_V0_PASCAL: |
| 257 | case NV_DEVICE_INFO_V0_VOLTA: | 257 | case NV_DEVICE_INFO_V0_VOLTA: |
| 258 | case NV_DEVICE_INFO_V0_TURING: | 258 | case NV_DEVICE_INFO_V0_TURING: |
| 259 | case NV_DEVICE_INFO_V0_AMPERE: //XXX: not confirmed | ||
| 259 | ret = nv50_backlight_init(nv_encoder, &props, &ops); | 260 | ret = nv50_backlight_init(nv_encoder, &props, &ops); |
| 260 | break; | 261 | break; |
| 261 | default: | 262 | default: |
| @@ -35,6 +35,7 @@ nvif_disp_ctor(struct nvif_device *device, const char *name, s32 oclass, · 34 unmodified lines | |||
| 35 | struct nvif_disp *disp) | 35 | struct nvif_disp *disp) |
| 36 | { | 36 | { |
| 37 | static const struct nvif_mclass disps[] = { | 37 | static const struct nvif_mclass disps[] = { |
| 38 | { GA102_DISP, -1 }, | ||
| 38 | { TU102_DISP, -1 }, | 39 | { TU102_DISP, -1 }, |
| 39 | { GV100_DISP, -1 }, | 40 | { GV100_DISP, -1 }, |
| 40 | { GP102_DISP, -1 }, | 41 | { GP102_DISP, -1 }, |
| @@ -1815,7 +1815,7 @@ nvf0_chipset = { · 1814 unmodified lines | |||
| 1815 | .fb = gk110_fb_new, | 1815 | .fb = gk110_fb_new, |
| 1816 | .fuse = gf100_fuse_new, | 1816 | .fuse = gf100_fuse_new, |
| 1817 | .gpio = gk104_gpio_new, | 1817 | .gpio = gk104_gpio_new, |
| 1818 | .i2c = gk104_i2c_new, | 1818 | .i2c = gk110_i2c_new, |
| 1819 | .ibus = gk104_ibus_new, | 1819 | .ibus = gk104_ibus_new, |
| 1820 | .iccsense = gf100_iccsense_new, | 1820 | .iccsense = gf100_iccsense_new, |
| 1821 | .imem = nv50_instmem_new, | 1821 | .imem = nv50_instmem_new, |
| @@ -1853,7 +1853,7 @@ nvf1_chipset = { · 31 unmodified lines | |||
| 1853 | .fb = gk110_fb_new, | 1853 | .fb = gk110_fb_new, |
| 1854 | .fuse = gf100_fuse_new, | 1854 | .fuse = gf100_fuse_new, |
| 1855 | .gpio = gk104_gpio_new, | 1855 | .gpio = gk104_gpio_new, |
| 1856 | .i2c = gk104_i2c_new, | 1856 | .i2c = gk110_i2c_new, |
| 1857 | .ibus = gk104_ibus_new, | 1857 | .ibus = gk104_ibus_new, |
| 1858 | .iccsense = gf100_iccsense_new, | 1858 | .iccsense = gf100_iccsense_new, |
| 1859 | .imem = nv50_instmem_new, | 1859 | .imem = nv50_instmem_new, |
| @@ -1891,7 +1891,7 @@ nv106_chipset = { · 31 unmodified lines | |||
| 1891 | .fb = gk110_fb_new, | 1891 | .fb = gk110_fb_new, |
| 1892 | .fuse = gf100_fuse_new, | 1892 | .fuse = gf100_fuse_new, |
| 1893 | .gpio = gk104_gpio_new, | 1893 | .gpio = gk104_gpio_new, |
| 1894 | .i2c = gk104_i2c_new, | 1894 | .i2c = gk110_i2c_new, |
| 1895 | .ibus = gk104_ibus_new, | 1895 | .ibus = gk104_ibus_new, |
| 1896 | .iccsense = gf100_iccsense_new, | 1896 | .iccsense = gf100_iccsense_new, |
| 1897 | .imem = nv50_instmem_new, | 1897 | .imem = nv50_instmem_new, |
| @@ -1929,7 +1929,7 @@ nv108_chipset = { · 31 unmodified lines | |||
| 1929 | .fb = gk110_fb_new, | 1929 | .fb = gk110_fb_new, |
| 1930 | .fuse = gf100_fuse_new, | 1930 | .fuse = gf100_fuse_new, |
| 1931 | .gpio = gk104_gpio_new, | 1931 | .gpio = gk104_gpio_new, |
| 1932 | .i2c = gk104_i2c_new, | 1932 | .i2c = gk110_i2c_new, |
| 1933 | .ibus = gk104_ibus_new, | 1933 | .ibus = gk104_ibus_new, |
| 1934 | .iccsense = gf100_iccsense_new, | 1934 | .iccsense = gf100_iccsense_new, |
| 1935 | .imem = nv50_instmem_new, | 1935 | .imem = nv50_instmem_new, |
| @@ -1967,7 +1967,7 @@ nv117_chipset = { · 31 unmodified lines | |||
| 1967 | .fb = gm107_fb_new, | 1967 | .fb = gm107_fb_new, |
| 1968 | .fuse = gm107_fuse_new, | 1968 | .fuse = gm107_fuse_new, |
| 1969 | .gpio = gk104_gpio_new, | 1969 | .gpio = gk104_gpio_new, |
| 1970 | .i2c = gk104_i2c_new, | 1970 | .i2c = gk110_i2c_new, |
| 1971 | .ibus = gk104_ibus_new, | 1971 | .ibus = gk104_ibus_new, |
| 1972 | .iccsense = gf100_iccsense_new, | 1972 | .iccsense = gf100_iccsense_new, |
| 1973 | .imem = nv50_instmem_new, | 1973 | .imem = nv50_instmem_new, |
| @@ -2003,7 +2003,7 @@ nv118_chipset = { · 29 unmodified lines | |||
| 2003 | .fb = gm107_fb_new, | 2003 | .fb = gm107_fb_new, |
| 2004 | .fuse = gm107_fuse_new, | 2004 | .fuse = gm107_fuse_new, |
| 2005 | .gpio = gk104_gpio_new, | 2005 | .gpio = gk104_gpio_new, |
| 2006 | .i2c = gk104_i2c_new, | 2006 | .i2c = gk110_i2c_new, |
| 2007 | .ibus = gk104_ibus_new, | 2007 | .ibus = gk104_ibus_new, |
| 2008 | .iccsense = gf100_iccsense_new, | 2008 | .iccsense = gf100_iccsense_new, |
| 2009 | .imem = nv50_instmem_new, | 2009 | .imem = nv50_instmem_new, |
| @@ -2652,6 +2652,61 @@ nv168_chipset = { · 642 unmodified lines | |||
| 2652 | .sec2 = tu102_sec2_new, | 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 | static int | 2710 | static int |
| 2656 | nvkm_device_event_ctor(struct nvkm_object *object, void *data, u32 size, | 2711 | nvkm_device_event_ctor(struct nvkm_object *object, void *data, u32 size, |
| 2657 | struct nvkm_notify *notify) | 2712 | struct nvkm_notify *notify) |
| @@ -3063,6 +3118,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, · 405 unmodified lines | |||
| 3063 | case 0x130: device->card_type = GP100; break; | 3118 | case 0x130: device->card_type = GP100; break; |
| 3064 | case 0x140: device->card_type = GV100; break; | 3119 | case 0x140: device->card_type = GV100; break; |
| 3065 | case 0x160: device->card_type = TU100; break; | 3120 | case 0x160: device->card_type = TU100; break; |
| 3121 | case 0x170: device->card_type = GA100; break; | ||
| 3066 | default: | 3122 | default: |
| 3067 | break; | 3123 | break; |
| 3068 | } | 3124 | } |
| @@ -3160,10 +3216,23 @@ nvkm_device_ctor(const struct nvkm_device_func *func, · 91 unmodified lines | |||
| 3160 | case 0x166: device->chip = &nv166_chipset; break; | 3216 | case 0x166: device->chip = &nv166_chipset; break; |
| 3161 | case 0x167: device->chip = &nv167_chipset; break; | 3217 | case 0x167: device->chip = &nv167_chipset; break; |
| 3162 | case 0x168: device->chip = &nv168_chipset; break; | 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 | default: | 3221 | default: |
| 3164 | nvdev_error(device, "unknown chipset (%08x)\n", boot0); | 3222 | if (nvkm_boolopt(device->cfgopt, "NvEnableUnsupportedChipsets", false)) { |
| 3165 | ret = -ENODEV; | 3223 | switch (device->chipset) { |
| 3166 | goto done; | 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 | nvdev_info(device, "NVIDIA %s (%08x)\n", | 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 | case GP100: args->v0.family = NV_DEVICE_INFO_V0_PASCAL; break; | 176 | case GP100: args->v0.family = NV_DEVICE_INFO_V0_PASCAL; break; |
| 177 | case GV100: args->v0.family = NV_DEVICE_INFO_V0_VOLTA; break; | 177 | case GV100: args->v0.family = NV_DEVICE_INFO_V0_VOLTA; break; |
| 178 | case TU100: args->v0.family = NV_DEVICE_INFO_V0_TURING; break; | 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 | default: | 180 | default: |
| 180 | args->v0.family = 0; | 181 | args->v0.family = 0; |
| 181 | break; | 182 | break; |
| @@ -17,6 +17,7 @@ nvkm-y += nvkm/engine/disp/gp100.o · 16 unmodified lines | |||
| 17 | nvkm-y += nvkm/engine/disp/gp102.o | 17 | nvkm-y += nvkm/engine/disp/gp102.o |
| 18 | nvkm-y += nvkm/engine/disp/gv100.o | 18 | nvkm-y += nvkm/engine/disp/gv100.o |
| 19 | nvkm-y += nvkm/engine/disp/tu102.o | 19 | nvkm-y += nvkm/engine/disp/tu102.o |
| 20 | nvkm-y += nvkm/engine/disp/ga102.o | ||
| 20 | nvkm-y += nvkm/engine/disp/vga.o | 21 | nvkm-y += nvkm/engine/disp/vga.o |
| 21 | 22 | ||
| 22 | nvkm-y += nvkm/engine/disp/head.o | 23 | nvkm-y += nvkm/engine/disp/head.o |
| @@ -42,6 +43,7 @@ nvkm-y += nvkm/engine/disp/sorgm200.o · 19 unmodified lines | |||
| 42 | nvkm-y += nvkm/engine/disp/sorgp100.o | 43 | nvkm-y += nvkm/engine/disp/sorgp100.o |
| 43 | nvkm-y += nvkm/engine/disp/sorgv100.o | 44 | nvkm-y += nvkm/engine/disp/sorgv100.o |
| 44 | nvkm-y += nvkm/engine/disp/sortu102.o | 45 | nvkm-y += nvkm/engine/disp/sortu102.o |
| 46 | nvkm-y += nvkm/engine/disp/sorga102.o | ||
| 45 | 47 | ||
| 46 | nvkm-y += nvkm/engine/disp/outp.o | 48 | nvkm-y += nvkm/engine/disp/outp.o |
| 47 | nvkm-y += nvkm/engine/disp/dp.o | 49 | nvkm-y += nvkm/engine/disp/dp.o |
| @@ -75,6 +77,7 @@ nvkm-y += nvkm/engine/disp/rootgp100.o · 27 unmodified lines | |||
| 75 | nvkm-y += nvkm/engine/disp/rootgp102.o | 77 | nvkm-y += nvkm/engine/disp/rootgp102.o |
| 76 | nvkm-y += nvkm/engine/disp/rootgv100.o | 78 | nvkm-y += nvkm/engine/disp/rootgv100.o |
| 77 | nvkm-y += nvkm/engine/disp/roottu102.o | 79 | nvkm-y += nvkm/engine/disp/roottu102.o |
| 80 | nvkm-y += nvkm/engine/disp/rootga102.o | ||
| 78 | 81 | ||
| 79 | nvkm-y += nvkm/engine/disp/capsgv100.o | 82 | nvkm-y += nvkm/engine/disp/capsgv100.o |
| 80 | 83 | ||
| @@ -33,6 +33,12 @@ · 32 unmodified lines | |||
| 33 | 33 | ||
| 34 | #include <nvif/event.h> | 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 | struct lt_state { | 42 | struct lt_state { |
| 37 | struct nvkm_dp *dp; | 43 | struct nvkm_dp *dp; |
| 38 | u8 stat[6]; | 44 | u8 stat[6]; |
| @@ -238,6 +244,19 @@ nvkm_dp_train_links(struct nvkm_dp *dp) · 199 unmodified lines | |||
| 238 | dp->dpcd[DPCD_RC02] &= ~DPCD_RC02_TPS3_SUPPORTED; | 244 | dp->dpcd[DPCD_RC02] &= ~DPCD_RC02_TPS3_SUPPORTED; |
| 239 | lt.pc2 = dp->dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED; | 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 | /* Set desired link configuration on the source. */ | 260 | /* Set desired link configuration on the source. */ |
| 242 | if ((lnkcmp = lt.dp->info.lnkcmp)) { | 261 | if ((lnkcmp = lt.dp->info.lnkcmp)) { |
| 243 | if (dp->version < 0x30) { | 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. */ | 338 | if (!AMPERE_IED_HACK(dp->outp.disp)) { |
| 320 | nvbios_init(&dp->outp.disp->engine.subdev, dp->info.script[0], | 339 | /* Execute BeforeLinkTraining script from DP Info table. */ |
| 321 | init.outp = &dp->outp.info; | 340 | nvbios_init(&dp->outp.disp->engine.subdev, dp->info.script[0], |
| 322 | init.or = dp->outp.ior->id; | 341 | init.outp = &dp->outp.info; |
| 323 | init.link = dp->outp.ior->asy.link; | 342 | init.or = dp->outp.ior->id; |
| 324 | ); | 343 | init.link = dp->outp.ior->asy.link; |
| 344 | ); | ||
| 345 | } | ||
| 325 | } | 346 | } |
| 326 | 347 | ||
| 327 | static const struct dp_rates { | 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 | void gv100_sor_dp_audio_sym(struct nvkm_ior *, int, u16, u32); | 150 | void gv100_sor_dp_audio_sym(struct nvkm_ior *, int, u16, u32); |
| 151 | void gv100_sor_dp_watermark(struct nvkm_ior *, int, u8); | 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 | void g84_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); | 155 | void g84_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); |
| 154 | void gt215_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); | 156 | void gt215_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); |
| 155 | void gf119_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); | 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 | int gv100_sor_new(struct nvkm_disp *, int); | 209 | int gv100_sor_new(struct nvkm_disp *, int); |
| 208 | 210 | ||
| 209 | int tu102_sor_new(struct nvkm_disp *, int); | 211 | int tu102_sor_new(struct nvkm_disp *, int); |
| 212 | |||
| 213 | int ga102_sor_new(struct nvkm_disp *, int); | ||
| 210 | #endif | 214 | #endif |
| @@ -86,6 +86,8 @@ void gv100_disp_intr(struct nv50_disp *); · 85 unmodified lines | |||
| 86 | void gv100_disp_super(struct work_struct *); | 86 | void gv100_disp_super(struct work_struct *); |
| 87 | int gv100_disp_wndw_cnt(struct nvkm_disp *, unsigned long *); | 87 | int gv100_disp_wndw_cnt(struct nvkm_disp *, unsigned long *); |
| 88 | 88 | ||
| 89 | int tu102_disp_init(struct nv50_disp *); | ||
| 90 | |||
| 89 | void nv50_disp_dptmds_war_2(struct nv50_disp *, struct dcb_output *); | 91 | void nv50_disp_dptmds_war_2(struct nv50_disp *, struct dcb_output *); |
| 90 | void nv50_disp_dptmds_war_3(struct nv50_disp *, struct dcb_output *); | 92 | void nv50_disp_dptmds_war_3(struct nv50_disp *, struct dcb_output *); |
| 91 | void nv50_disp_update_sppll1(struct nv50_disp *); | 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 | extern const struct nvkm_disp_oclass gp102_disp_root_oclass; | 41 | extern const struct nvkm_disp_oclass gp102_disp_root_oclass; |
| 42 | extern const struct nvkm_disp_oclass gv100_disp_root_oclass; | 42 | extern const struct nvkm_disp_oclass gv100_disp_root_oclass; |
| 43 | extern const struct nvkm_disp_oclass tu102_disp_root_oclass; | 43 | extern const struct nvkm_disp_oclass tu102_disp_root_oclass; |
| 44 | extern const struct nvkm_disp_oclass ga102_disp_root_oclass; | ||
| 44 | #endif | 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 | #include <subdev/timer.h> | 24 | #include <subdev/timer.h> |
| 25 | 25 | ||
| 26 | static void | 26 | void |
| 27 | tu102_sor_dp_vcpi(struct nvkm_ior *sor, int head, | 27 | tu102_sor_dp_vcpi(struct nvkm_ior *sor, int head, |
| 28 | u8 slot, u8 slot_nr, u16 pbn, u16 aligned) | 28 | u8 slot, u8 slot_nr, u16 pbn, u16 aligned) |
| 29 | { | 29 | { |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | |||
| 28 | #include <core/gpuobj.h> | 28 | #include <core/gpuobj.h> |
| 29 | #include <subdev/timer.h> | 29 | #include <subdev/timer.h> |
| 30 | 30 | ||
| 31 | static int | 31 | int |
| 32 | tu102_disp_init(struct nv50_disp *disp) | 32 | tu102_disp_init(struct nv50_disp *disp) |
| 33 | { | 33 | { |
| 34 | struct nvkm_device *device = disp->base.engine.subdev.device; | 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 | nvkm_debug(subdev, "%08x: type %02x, %d bytes\n", | 75 | nvkm_debug(subdev, "%08x: type %02x, %d bytes\n", |
| 76 | image.base, image.type, image.size); | 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 | nvkm_debug(subdev, "%08x: fetch failed\n", image.base); | 79 | nvkm_debug(subdev, "%08x: fetch failed\n", image.base); |
| 80 | return 0; | 80 | return 0; |
| 81 | } | 81 | } |
| @@ -64,6 +64,9 @@ pramin_init(struct nvkm_bios *bios, const char *name) · 63 unmodified lines | |||
| 64 | return NULL; | 64 | return NULL; |
| 65 | 65 | ||
| 66 | /* we can't get the bios image pointer without PDISP */ | 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 | if (device->card_type >= GM100) | 70 | if (device->card_type >= GM100) |
| 68 | addr = nvkm_rd32(device, 0x021c04); | 71 | addr = nvkm_rd32(device, 0x021c04); |
| 69 | else | 72 | else |
| @@ -15,3 +15,4 @@ nvkm-y += nvkm/subdev/devinit/gm107.o · 14 unmodified lines | |||
| 15 | nvkm-y += nvkm/subdev/devinit/gm200.o | 15 | nvkm-y += nvkm/subdev/devinit/gm200.o |
| 16 | nvkm-y += nvkm/subdev/devinit/gv100.o | 16 | nvkm-y += nvkm/subdev/devinit/gv100.o |
| 17 | nvkm-y += nvkm/subdev/devinit/tu102.o | 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 | int index, struct nvkm_devinit *); | 19 | int index, struct nvkm_devinit *); |
| 20 | 20 | ||
| 21 | int nv04_devinit_post(struct nvkm_devinit *, bool); | 21 | int nv04_devinit_post(struct nvkm_devinit *, bool); |
| 22 | int tu102_devinit_post(struct nvkm_devinit *, bool); | ||
| 22 | #endif | 23 | #endif |
| @@ -65,7 +65,7 @@ tu102_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq) · 64 unmodified lines | |||
| 65 | return ret; | 65 | return ret; |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | static int | 68 | int |
| 69 | tu102_devinit_post(struct nvkm_devinit *base, bool post) | 69 | tu102_devinit_post(struct nvkm_devinit *base, bool post) |
| 70 | { | 70 | { |
| 71 | struct nv50_devinit *init = nv50_devinit(base); | 71 | struct nv50_devinit *init = nv50_devinit(base); |
| @@ -32,6 +32,8 @@ nvkm-y += nvkm/subdev/fb/gp100.o · 31 unmodified lines | |||
| 32 | nvkm-y += nvkm/subdev/fb/gp102.o | 32 | nvkm-y += nvkm/subdev/fb/gp102.o |
| 33 | nvkm-y += nvkm/subdev/fb/gp10b.o | 33 | nvkm-y += nvkm/subdev/fb/gp10b.o |
| 34 | nvkm-y += nvkm/subdev/fb/gv100.o | 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 | nvkm-y += nvkm/subdev/fb/ram.o | 38 | nvkm-y += nvkm/subdev/fb/ram.o |
| 37 | nvkm-y += nvkm/subdev/fb/ramnv04.o | 39 | nvkm-y += nvkm/subdev/fb/ramnv04.o |
| @@ -52,6 +54,7 @@ nvkm-y += nvkm/subdev/fb/ramgk104.o · 14 unmodified lines | |||
| 52 | nvkm-y += nvkm/subdev/fb/ramgm107.o | 54 | nvkm-y += nvkm/subdev/fb/ramgm107.o |
| 53 | nvkm-y += nvkm/subdev/fb/ramgm200.o | 55 | nvkm-y += nvkm/subdev/fb/ramgm200.o |
| 54 | nvkm-y += nvkm/subdev/fb/ramgp100.o | 56 | nvkm-y += nvkm/subdev/fb/ramgp100.o |
| 57 | nvkm-y += nvkm/subdev/fb/ramga102.o | ||
| 55 | nvkm-y += nvkm/subdev/fb/sddr2.o | 58 | nvkm-y += nvkm/subdev/fb/sddr2.o |
| 56 | nvkm-y += nvkm/subdev/fb/sddr3.o | 59 | nvkm-y += nvkm/subdev/fb/sddr3.o |
| 57 | nvkm-y += nvkm/subdev/fb/gddr3.o | 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 | #include "gf100.h" | 22 | #include "gf100.h" |
| 23 | #include "ram.h" | 23 | #include "ram.h" |
| 24 | 24 | ||
| 25 | static int | 25 | int |
| 26 | gv100_fb_init_page(struct nvkm_fb *fb) | 26 | gv100_fb_init_page(struct nvkm_fb *fb) |
| 27 | { | 27 | { |
| 28 | return (fb->page == 16) ? 0 : -EINVAL; | 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 | struct nvkm_fb **); | 82 | struct nvkm_fb **); |
| 83 | bool gp102_fb_vpr_scrub_required(struct nvkm_fb *); | 83 | bool gp102_fb_vpr_scrub_required(struct nvkm_fb *); |
| 84 | int gp102_fb_vpr_scrub(struct nvkm_fb *); | 84 | int gp102_fb_vpr_scrub(struct nvkm_fb *); |
| 85 | |||
| 86 | int gv100_fb_init_page(struct nvkm_fb *); | ||
| 85 | #endif | 87 | #endif |
| @@ -70,4 +70,5 @@ int gk104_ram_new(struct nvkm_fb *, struct nvkm_ram **); · 69 unmodified lines | |||
| 70 | int gm107_ram_new(struct nvkm_fb *, struct nvkm_ram **); | 70 | int gm107_ram_new(struct nvkm_fb *, struct nvkm_ram **); |
| 71 | int gm200_ram_new(struct nvkm_fb *, struct nvkm_ram **); | 71 | int gm200_ram_new(struct nvkm_fb *, struct nvkm_ram **); |
| 72 | int gp100_ram_new(struct nvkm_fb *, struct nvkm_ram **); | 72 | int gp100_ram_new(struct nvkm_fb *, struct nvkm_ram **); |
| 73 | int ga102_ram_new(struct nvkm_fb *, struct nvkm_ram **); | ||
| 73 | #endif | 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 | nvkm-y += nvkm/subdev/gpio/g94.o | 5 | nvkm-y += nvkm/subdev/gpio/g94.o |
| 6 | nvkm-y += nvkm/subdev/gpio/gf119.o | 6 | nvkm-y += nvkm/subdev/gpio/gf119.o |
| 7 | nvkm-y += nvkm/subdev/gpio/gk104.o | 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 | nvkm-y += nvkm/subdev/i2c/gf117.o | 7 | nvkm-y += nvkm/subdev/i2c/gf117.o |
| 8 | nvkm-y += nvkm/subdev/i2c/gf119.o | 8 | nvkm-y += nvkm/subdev/i2c/gf119.o |
| 9 | nvkm-y += nvkm/subdev/i2c/gk104.o | 9 | nvkm-y += nvkm/subdev/i2c/gk104.o |
| 10 | nvkm-y += nvkm/subdev/i2c/gk110.o | ||
| 10 | nvkm-y += nvkm/subdev/i2c/gm200.o | 11 | nvkm-y += nvkm/subdev/i2c/gm200.o |
| 11 | 12 | ||
| 12 | nvkm-y += nvkm/subdev/i2c/pad.o | 13 | nvkm-y += nvkm/subdev/i2c/pad.o |
| @@ -3,6 +3,13 @@ · 2 unmodified lines | |||
| 3 | #define __NVKM_I2C_AUX_H__ | 3 | #define __NVKM_I2C_AUX_H__ |
| 4 | #include "pad.h" | 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 | struct nvkm_i2c_aux_func { | 13 | struct nvkm_i2c_aux_func { |
| 7 | bool address_only; | 14 | bool address_only; |
| 8 | int (*xfer)(struct nvkm_i2c_aux *, bool retry, u8 type, | 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 | u8 type, u32 addr, u8 *data, u8 *size) | 77 | u8 type, u32 addr, u8 *data, u8 *size) |
| 78 | { | 78 | { |
| 79 | struct g94_i2c_aux *aux = g94_i2c_aux(obj); | 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 | const u32 base = aux->ch * 0x50; | 82 | const u32 base = aux->ch * 0x50; |
| 82 | u32 ctrl, stat, timeout, retries = 0; | 83 | u32 ctrl, stat, timeout, retries = 0; |
| 83 | u32 xbuf[4] = {}; | 84 | u32 xbuf[4] = {}; |
| @@ -96,6 +97,8 @@ g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 12 unmodified lines | |||
| 96 | goto out; | 97 | goto out; |
| 97 | } | 98 | } |
| 98 | 99 | ||
| 100 | nvkm_i2c_aux_autodpcd(i2c, aux->ch, false); | ||
| 101 | |||
| 99 | if (!(type & 1)) { | 102 | if (!(type & 1)) { |
| 100 | memcpy(xbuf, data, *size); | 103 | memcpy(xbuf, data, *size); |
| 101 | for (i = 0; i < 16; i += 4) { | 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 | if (!timeout--) { | 131 | if (!timeout--) { |
| 129 | AUX_ERR(&aux->base, "timeout %08x", ctrl); | 132 | AUX_ERR(&aux->base, "timeout %08x", ctrl); |
| 130 | ret = -EIO; | 133 | ret = -EIO; |
| 131 | goto out; | 134 | goto out_err; |
| 132 | } | 135 | } |
| 133 | } while (ctrl & 0x00010000); | 136 | } while (ctrl & 0x00010000); |
| 134 | ret = 0; | 137 | ret = 0; |
| @@ -154,7 +157,8 @@ g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 19 unmodified lines | |||
| 154 | memcpy(data, xbuf, *size); | 157 | memcpy(data, xbuf, *size); |
| 155 | *size = stat & 0x0000001f; | 158 | *size = stat & 0x0000001f; |
| 156 | } | 159 | } |
| 157 | 160 | out_err: | |
| 161 | nvkm_i2c_aux_autodpcd(i2c, aux->ch, true); | ||
| 158 | out: | 162 | out: |
| 159 | g94_i2c_aux_fini(aux); | 163 | g94_i2c_aux_fini(aux); |
| 160 | return ret < 0 ? ret : (stat & 0x000f0000) >> 16; | 164 | return ret < 0 ? ret : (stat & 0x000f0000) >> 16; |
| @@ -33,7 +33,7 @@ static void · 32 unmodified lines | |||
| 33 | gm200_i2c_aux_fini(struct gm200_i2c_aux *aux) | 33 | gm200_i2c_aux_fini(struct gm200_i2c_aux *aux) |
| 34 | { | 34 | { |
| 35 | struct nvkm_device *device = aux->base.pad->i2c->subdev.device; | 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 | static int | 39 | static int |
| @@ -54,10 +54,10 @@ gm200_i2c_aux_init(struct gm200_i2c_aux *aux) · 14 unmodified lines | |||
| 54 | AUX_ERR(&aux->base, "begin idle timeout %08x", ctrl); | 54 | AUX_ERR(&aux->base, "begin idle timeout %08x", ctrl); |
| 55 | return -EBUSY; | 55 | return -EBUSY; |
| 56 | } | 56 | } |
| 57 | } while (ctrl & 0x03010000); | 57 | } while (ctrl & 0x07010000); |
| 58 | 58 | ||
| 59 | /* set some magic, and wait up to 1ms for it to appear */ | 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 | timeout = 1000; | 61 | timeout = 1000; |
| 62 | do { | 62 | do { |
| 63 | ctrl = nvkm_rd32(device, 0x00d954 + (aux->ch * 0x50)); | 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 | gm200_i2c_aux_fini(aux); | 67 | gm200_i2c_aux_fini(aux); |
| 68 | return -EBUSY; | 68 | return -EBUSY; |
| 69 | } | 69 | } |
| 70 | } while ((ctrl & 0x03000000) != urep); | 70 | } while ((ctrl & 0x07000000) != urep); |
| 71 | 71 | ||
| 72 | return 0; | 72 | return 0; |
| 73 | } | 73 | } |
| @@ -77,7 +77,8 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 3 unmodified lines | |||
| 77 | u8 type, u32 addr, u8 *data, u8 *size) | 77 | u8 type, u32 addr, u8 *data, u8 *size) |
| 78 | { | 78 | { |
| 79 | struct gm200_i2c_aux *aux = gm200_i2c_aux(obj); | 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 | const u32 base = aux->ch * 0x50; | 82 | const u32 base = aux->ch * 0x50; |
| 82 | u32 ctrl, stat, timeout, retries = 0; | 83 | u32 ctrl, stat, timeout, retries = 0; |
| 83 | u32 xbuf[4] = {}; | 84 | u32 xbuf[4] = {}; |
| @@ -96,6 +97,8 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 12 unmodified lines | |||
| 96 | goto out; | 97 | goto out; |
| 97 | } | 98 | } |
| 98 | 99 | ||
| 100 | nvkm_i2c_aux_autodpcd(i2c, aux->ch, false); | ||
| 101 | |||
| 99 | if (!(type & 1)) { | 102 | if (!(type & 1)) { |
| 100 | memcpy(xbuf, data, *size); | 103 | memcpy(xbuf, data, *size); |
| 101 | for (i = 0; i < 16; i += 4) { | 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 | if (!timeout--) { | 131 | if (!timeout--) { |
| 129 | AUX_ERR(&aux->base, "timeout %08x", ctrl); | 132 | AUX_ERR(&aux->base, "timeout %08x", ctrl); |
| 130 | ret = -EIO; | 133 | ret = -EIO; |
| 131 | goto out; | 134 | goto out_err; |
| 132 | } | 135 | } |
| 133 | } while (ctrl & 0x00010000); | 136 | } while (ctrl & 0x00010000); |
| 134 | ret = 0; | 137 | ret = 0; |
| @@ -155,6 +158,8 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, · 20 unmodified lines | |||
| 155 | *size = stat & 0x0000001f; | 158 | *size = stat & 0x0000001f; |
| 156 | } | 159 | } |
| 157 | 160 | ||
| 161 | out_err: | ||
| 162 | nvkm_i2c_aux_autodpcd(i2c, aux->ch, true); | ||
| 158 | out: | 163 | out: |
| 159 | gm200_i2c_aux_fini(aux); | 164 | gm200_i2c_aux_fini(aux); |
| 160 | return ret < 0 ? ret : (stat & 0x000f0000) >> 16; | 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 | #include "priv.h" | 24 | #include "priv.h" |
| 25 | #include "pad.h" | 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 | static const struct nvkm_i2c_func | 33 | static const struct nvkm_i2c_func |
| 28 | gm200_i2c = { | 34 | gm200_i2c = { |
| 29 | .pad_x_new = gf119_i2c_pad_x_new, | 35 | .pad_x_new = gf119_i2c_pad_x_new, |
| @@ -31,6 +37,7 @@ gm200_i2c = { · 1 unmodified line | |||
| 31 | .aux = 8, | 37 | .aux = 8, |
| 32 | .aux_stat = gk104_aux_stat, | 38 | .aux_stat = gk104_aux_stat, |
| 33 | .aux_mask = gk104_aux_mask, | 39 | .aux_mask = gk104_aux_mask, |
| 40 | .aux_autodpcd = gm200_aux_autodpcd, | ||
| 34 | }; | 41 | }; |
| 35 | 42 | ||
| 36 | int | 43 | int |
| @@ -1,7 +1,7 @@ | |||
| 1 | /* SPDX-License-Identifier: MIT */ | 1 | /* SPDX-License-Identifier: MIT */ |
| 2 | #ifndef __NVKM_I2C_PAD_H__ | 2 | #ifndef __NVKM_I2C_PAD_H__ |
| 3 | #define __NVKM_I2C_PAD_H__ | 3 | #define __NVKM_I2C_PAD_H__ |
| 4 | #include <subdev/i2c.h> | 4 | #include "priv.h" |
| 5 | 5 | ||
| 6 | struct nvkm_i2c_pad { | 6 | struct nvkm_i2c_pad { |
| 7 | const struct nvkm_i2c_pad_func *func; | 7 | const struct nvkm_i2c_pad_func *func; |
| @@ -23,6 +23,10 @@ struct nvkm_i2c_func { · 22 unmodified lines | |||
| 23 | /* mask on/off interrupt types for a given set of auxch | 23 | /* mask on/off interrupt types for a given set of auxch |
| 24 | */ | 24 | */ |
| 25 | void (*aux_mask)(struct nvkm_i2c *, u32, u32, u32); | 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 | void g94_aux_stat(struct nvkm_i2c *, u32 *, u32 *, u32 *, u32 *); | 32 | void g94_aux_stat(struct nvkm_i2c *, u32 *, u32 *, u32 *, u32 *); |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | |||
| 22 | * Authors: Ben Skeggs | 22 | * Authors: Ben Skeggs |
| 23 | */ | 23 | */ |
| 24 | #include "priv.h" | 24 | #include "priv.h" |
| 25 | #include <subdev/timer.h> | ||
| 25 | 26 | ||
| 26 | static void | 27 | static void |
| 27 | gf100_ibus_intr_hub(struct nvkm_subdev *ibus, int i) | 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 | u32 data = nvkm_rd32(device, 0x122124 + (i * 0x0400)); | 32 | u32 data = nvkm_rd32(device, 0x122124 + (i * 0x0400)); |
| 32 | u32 stat = nvkm_rd32(device, 0x122128 + (i * 0x0400)); | 33 | u32 stat = nvkm_rd32(device, 0x122128 + (i * 0x0400)); |
| 33 | nvkm_debug(ibus, "HUB%d: %06x %08x (%08x)\n", i, addr, data, stat); | 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 | static void | 37 | static void |
| @@ -42,7 +42,6 @@ gf100_ibus_intr_rop(struct nvkm_subdev *ibus, int i) · 4 unmodified lines | |||
| 42 | u32 data = nvkm_rd32(device, 0x124124 + (i * 0x0400)); | 42 | u32 data = nvkm_rd32(device, 0x124124 + (i * 0x0400)); |
| 43 | u32 stat = nvkm_rd32(device, 0x124128 + (i * 0x0400)); | 43 | u32 stat = nvkm_rd32(device, 0x124128 + (i * 0x0400)); |
| 44 | nvkm_debug(ibus, "ROP%d: %06x %08x (%08x)\n", i, addr, data, stat); | 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 | static void | 47 | static void |
| @@ -53,7 +52,6 @@ gf100_ibus_intr_gpc(struct nvkm_subdev *ibus, int i) · 4 unmodified lines | |||
| 53 | u32 data = nvkm_rd32(device, 0x128124 + (i * 0x0400)); | 52 | u32 data = nvkm_rd32(device, 0x128124 + (i * 0x0400)); |
| 54 | u32 stat = nvkm_rd32(device, 0x128128 + (i * 0x0400)); | 53 | u32 stat = nvkm_rd32(device, 0x128128 + (i * 0x0400)); |
| 55 | nvkm_debug(ibus, "GPC%d: %06x %08x (%08x)\n", i, addr, data, stat); | 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 | void | 57 | void |
| @@ -90,6 +88,12 @@ gf100_ibus_intr(struct nvkm_subdev *ibus) · 30 unmodified lines | |||
| 90 | intr1 &= ~stat; | 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 | static int | 99 | static int |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | |||
| 22 | * Authors: Ben Skeggs | 22 | * Authors: Ben Skeggs |
| 23 | */ | 23 | */ |
| 24 | #include "priv.h" | 24 | #include "priv.h" |
| 25 | #include <subdev/timer.h> | ||
| 25 | 26 | ||
| 26 | static void | 27 | static void |
| 27 | gk104_ibus_intr_hub(struct nvkm_subdev *ibus, int i) | 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 | u32 data = nvkm_rd32(device, 0x122124 + (i * 0x0800)); | 32 | u32 data = nvkm_rd32(device, 0x122124 + (i * 0x0800)); |
| 32 | u32 stat = nvkm_rd32(device, 0x122128 + (i * 0x0800)); | 33 | u32 stat = nvkm_rd32(device, 0x122128 + (i * 0x0800)); |
| 33 | nvkm_debug(ibus, "HUB%d: %06x %08x (%08x)\n", i, addr, data, stat); | 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 | static void | 37 | static void |
| @@ -42,7 +42,6 @@ gk104_ibus_intr_rop(struct nvkm_subdev *ibus, int i) · 4 unmodified lines | |||
| 42 | u32 data = nvkm_rd32(device, 0x124124 + (i * 0x0800)); | 42 | u32 data = nvkm_rd32(device, 0x124124 + (i * 0x0800)); |
| 43 | u32 stat = nvkm_rd32(device, 0x124128 + (i * 0x0800)); | 43 | u32 stat = nvkm_rd32(device, 0x124128 + (i * 0x0800)); |
| 44 | nvkm_debug(ibus, "ROP%d: %06x %08x (%08x)\n", i, addr, data, stat); | 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 | static void | 47 | static void |
| @@ -53,7 +52,6 @@ gk104_ibus_intr_gpc(struct nvkm_subdev *ibus, int i) · 4 unmodified lines | |||
| 53 | u32 data = nvkm_rd32(device, 0x128124 + (i * 0x0800)); | 52 | u32 data = nvkm_rd32(device, 0x128124 + (i * 0x0800)); |
| 54 | u32 stat = nvkm_rd32(device, 0x128128 + (i * 0x0800)); | 53 | u32 stat = nvkm_rd32(device, 0x128128 + (i * 0x0800)); |
| 55 | nvkm_debug(ibus, "GPC%d: %06x %08x (%08x)\n", i, addr, data, stat); | 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 | void | 57 | void |
| @@ -90,6 +88,12 @@ gk104_ibus_intr(struct nvkm_subdev *ibus) · 30 unmodified lines | |||
| 90 | intr1 &= ~stat; | 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 | static int | 99 | static int |
| @@ -14,3 +14,4 @@ nvkm-y += nvkm/subdev/mc/gk20a.o · 13 unmodified lines | |||
| 14 | nvkm-y += nvkm/subdev/mc/gp100.o | 14 | nvkm-y += nvkm/subdev/mc/gp100.o |
| 15 | nvkm-y += nvkm/subdev/mc/gp10b.o | 15 | nvkm-y += nvkm/subdev/mc/gp10b.o |
| 16 | nvkm-y += nvkm/subdev/mc/tu102.o | 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 | struct nvkm_device *device = mmu->subdev.device; | 317 | struct nvkm_device *device = mmu->subdev.device; |
| 318 | struct nvkm_mm *mm = &device->fb->ram->vram; | 318 | struct nvkm_mm *mm = &device->fb->ram->vram; |
| 319 | const u32 sizeN = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NORMAL); | 319 | const u64 sizeN = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NORMAL); |
| 320 | const u32 sizeU = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NOMAP); | 320 | const u64 sizeU = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NOMAP); |
| 321 | const u32 sizeM = nvkm_mm_heap_size(mm, NVKM_RAM_MM_MIXED); | 321 | const u64 sizeM = nvkm_mm_heap_size(mm, NVKM_RAM_MM_MIXED); |
| 322 | u8 type = NVKM_MEM_KIND * !!mmu->func->kind; | 322 | u8 type = NVKM_MEM_KIND * !!mmu->func->kind; |
| 323 | u8 heap = NVKM_MEM_VRAM; | 323 | u8 heap = NVKM_MEM_VRAM; |
| 324 | int heapM, heapN, heapU; | 324 | int heapM, heapN, heapU; |
| @@ -730,9 +730,6 @@ int radeon_ttm_init(struct radeon_device *rdev) · 729 unmodified lines | |||
| 730 | } | 730 | } |
| 731 | rdev->mman.initialized = true; | 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 | r = radeon_ttm_init_vram(rdev); | 733 | r = radeon_ttm_init_vram(rdev); |
| 737 | if (r) { | 734 | if (r) { |
| 738 | DRM_ERROR("Failed initializing VRAM heap.\n"); | 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 | static struct ttm_pool_type global_dma32_write_combined[MAX_ORDER]; | 66 | static struct ttm_pool_type global_dma32_write_combined[MAX_ORDER]; |
| 67 | static struct ttm_pool_type global_dma32_uncached[MAX_ORDER]; | 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 | static struct list_head shrinker_list; | 70 | static struct list_head shrinker_list; |
| 71 | static struct shrinker mm_shrinker; | 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 | size_t size = (1ULL << order) * PAGE_SIZE; | 190 | size_t size = (1ULL << order) * PAGE_SIZE; |
| 191 | 191 | ||
| 192 | addr = dma_map_page(pool->dev, p, 0, size, DMA_BIDIRECTIONAL); | 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 | return -EFAULT; | 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 | spin_lock_init(&pt->lock); | 249 | spin_lock_init(&pt->lock); |
| 250 | INIT_LIST_HEAD(&pt->pages); | 250 | INIT_LIST_HEAD(&pt->pages); |
| 251 | 251 | ||
| 252 | spin_lock(&shrinker_lock); | 252 | mutex_lock(&shrinker_lock); |
| 253 | list_add_tail(&pt->shrinker_list, &shrinker_list); | 253 | list_add_tail(&pt->shrinker_list, &shrinker_list); |
| 254 | spin_unlock(&shrinker_lock); | 254 | mutex_unlock(&shrinker_lock); |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | /* Remove a pool_type from the global shrinker list and free all pages */ | 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 | struct page *p, *tmp; | 260 | struct page *p, *tmp; |
| 261 | 261 | ||
| 262 | spin_lock(&shrinker_lock); | 262 | mutex_lock(&shrinker_lock); |
| 263 | list_del(&pt->shrinker_list); | 263 | list_del(&pt->shrinker_list); |
| 264 | spin_unlock(&shrinker_lock); | 264 | mutex_unlock(&shrinker_lock); |
| 265 | 265 | ||
| 266 | list_for_each_entry_safe(p, tmp, &pt->pages, lru) | 266 | list_for_each_entry_safe(p, tmp, &pt->pages, lru) |
| 267 | ttm_pool_free_page(pt->pool, pt->caching, pt->order, p); | 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 | unsigned int num_freed; | 302 | unsigned int num_freed; |
| 303 | struct page *p; | 303 | struct page *p; |
| 304 | 304 | ||
| 305 | spin_lock(&shrinker_lock); | 305 | mutex_lock(&shrinker_lock); |
| 306 | pt = list_first_entry(&shrinker_list, typeof(*pt), shrinker_list); | 306 | pt = list_first_entry(&shrinker_list, typeof(*pt), shrinker_list); |
| 307 | 307 | ||
| 308 | p = ttm_pool_type_take(pt); | 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 | list_move_tail(&pt->shrinker_list, &shrinker_list); | 316 | list_move_tail(&pt->shrinker_list, &shrinker_list); |
| 317 | spin_unlock(&shrinker_lock); | 317 | mutex_unlock(&shrinker_lock); |
| 318 | 318 | ||
| 319 | return num_freed; | 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 | ttm_pool_type_init(&pool->caching[i].orders[j], | 507 | ttm_pool_type_init(&pool->caching[i].orders[j], |
| 508 | pool, i, j); | 508 | pool, i, j); |
| 509 | } | 509 | } |
| 510 | EXPORT_SYMBOL(ttm_pool_init); | ||
| 511 | 510 | ||
| 512 | /** | 511 | /** |
| 513 | * ttm_pool_fini - Cleanup a pool | 512 | * ttm_pool_fini - Cleanup a pool |
| @@ -525,7 +524,6 @@ void ttm_pool_fini(struct ttm_pool *pool) · 11 unmodified lines | |||
| 525 | for (j = 0; j < MAX_ORDER; ++j) | 524 | for (j = 0; j < MAX_ORDER; ++j) |
| 526 | ttm_pool_type_fini(&pool->caching[i].orders[j]); | 525 | ttm_pool_type_fini(&pool->caching[i].orders[j]); |
| 527 | } | 526 | } |
| 528 | EXPORT_SYMBOL(ttm_pool_fini); | ||
| 529 | 527 | ||
| 530 | #ifdef CONFIG_DEBUG_FS | 528 | #ifdef CONFIG_DEBUG_FS |
| 531 | /* Count the number of pages available in a pool_type */ | 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 | unsigned int i; | 565 | unsigned int i; |
| 568 | 566 | ||
| 569 | spin_lock(&shrinker_lock); | 567 | mutex_lock(&shrinker_lock); |
| 570 | 568 | ||
| 571 | seq_puts(m, "\t "); | 569 | seq_puts(m, "\t "); |
| 572 | for (i = 0; i < MAX_ORDER; ++i) | 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 | seq_printf(m, "\ntotal\t: %8lu of %8lu\n", | 600 | seq_printf(m, "\ntotal\t: %8lu of %8lu\n", |
| 603 | atomic_long_read(&allocated_pages), page_pool_size); | 601 | atomic_long_read(&allocated_pages), page_pool_size); |
| 604 | 602 | ||
| 605 | spin_unlock(&shrinker_lock); | 603 | mutex_unlock(&shrinker_lock); |
| 606 | 604 | ||
| 607 | return 0; | 605 | return 0; |
| 608 | } | 606 | } |
| @@ -646,7 +644,7 @@ int ttm_pool_mgr_init(unsigned long num_pages) · 37 unmodified lines | |||
| 646 | if (!page_pool_size) | 644 | if (!page_pool_size) |
| 647 | page_pool_size = num_pages; | 645 | page_pool_size = num_pages; |
| 648 | 646 | ||
| 649 | spin_lock_init(&shrinker_lock); | 647 | mutex_init(&shrinker_lock); |
| 650 | INIT_LIST_HEAD(&shrinker_list); | 648 | INIT_LIST_HEAD(&shrinker_list); |
| 651 | 649 | ||
| 652 | for (i = 0; i < MAX_ORDER; ++i) { | 650 | for (i = 0; i < MAX_ORDER; ++i) { |
| @@ -899,6 +899,7 @@ config HID_SONY · 898 unmodified lines | |||
| 899 | depends on NEW_LEDS | 899 | depends on NEW_LEDS |
| 900 | depends on LEDS_CLASS | 900 | depends on LEDS_CLASS |
| 901 | select POWER_SUPPLY | 901 | select POWER_SUPPLY |
| 902 | select CRC32 | ||
| 902 | help | 903 | help |
| 903 | Support for | 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 | for (i = 0; i < cl_data->num_hid_devices; i++) { | 155 | for (i = 0; i < cl_data->num_hid_devices; i++) { |
| 156 | cl_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8, | 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 | GFP_KERNEL); | 158 | GFP_KERNEL); |
| 159 | cl_data->sensor_sts[i] = 0; | 159 | cl_data->sensor_sts[i] = 0; |
| 160 | cl_data->sensor_requested_cnt[i] = 0; | 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 | info.period = msecs_to_jiffies(AMD_SFH_IDLE_LOOP); | 188 | info.period = msecs_to_jiffies(AMD_SFH_IDLE_LOOP); |
| 189 | info.sensor_idx = cl_idx; | 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 | cl_data->report_descr[i] = kzalloc(cl_data->report_descr_sz[i], GFP_KERNEL); | 192 | cl_data->report_descr[i] = kzalloc(cl_data->report_descr_sz[i], GFP_KERNEL); |
| 193 | if (!cl_data->report_descr[i]) { | 193 | if (!cl_data->report_descr[i]) { |
| @@ -212,7 +212,7 @@ cleanup: · 18 unmodified lines | |||
| 212 | if (cl_data->sensor_virt_addr[i]) { | 212 | if (cl_data->sensor_virt_addr[i]) { |
| 213 | dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int), | 213 | dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int), |
| 214 | cl_data->sensor_virt_addr[i], | 214 | cl_data->sensor_virt_addr[i], |
| 215 | cl_data->sensor_phys_addr[i]); | 215 | cl_data->sensor_dma_addr[i]); |
| 216 | } | 216 | } |
| 217 | kfree(cl_data->feature_report[i]); | 217 | kfree(cl_data->feature_report[i]); |
| 218 | kfree(cl_data->input_report[i]); | 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 | if (cl_data->sensor_virt_addr[i]) { | 238 | if (cl_data->sensor_virt_addr[i]) { |
| 239 | dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int), | 239 | dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int), |
| 240 | cl_data->sensor_virt_addr[i], | 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 | kfree(cl_data); | 244 | kfree(cl_data); |
| @@ -27,7 +27,7 @@ struct amdtp_cl_data { · 26 unmodified lines | |||
| 27 | int hid_descr_size[MAX_HID_DEVICES]; | 27 | int hid_descr_size[MAX_HID_DEVICES]; |
| 28 | phys_addr_t phys_addr_base; | 28 | phys_addr_t phys_addr_base; |
| 29 | u32 *sensor_virt_addr[MAX_HID_DEVICES]; | 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 | u32 sensor_sts[MAX_HID_DEVICES]; | 31 | u32 sensor_sts[MAX_HID_DEVICES]; |
| 32 | u32 sensor_requested_cnt[MAX_HID_DEVICES]; | 32 | u32 sensor_requested_cnt[MAX_HID_DEVICES]; |
| 33 | u8 report_type[MAX_HID_DEVICES]; | 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 | cmd_param.s.buf_layout = 1; | 41 | cmd_param.s.buf_layout = 1; |
| 42 | cmd_param.s.buf_length = 16; | 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 | writel(cmd_param.ul, privdata->mmio + AMD_C2P_MSG1); | 45 | writel(cmd_param.ul, privdata->mmio + AMD_C2P_MSG1); |
| 46 | writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0); | 46 | writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0); |
| 47 | } | 47 | } |
| @@ -67,7 +67,7 @@ struct amd_mp2_dev { · 66 unmodified lines | |||
| 67 | struct amd_mp2_sensor_info { | 67 | struct amd_mp2_sensor_info { |
| 68 | u8 sensor_idx; | 68 | u8 sensor_idx; |
| 69 | u32 period; | 69 | u32 period; |
| 70 | phys_addr_t phys_address; | 70 | dma_addr_t dma_address; |
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| 73 | void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info); | 73 | void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info); |
| @@ -389,6 +389,7 @@ · 388 unmodified lines | |||
| 389 | #define USB_DEVICE_ID_TOSHIBA_CLICK_L9W 0x0401 | 389 | #define USB_DEVICE_ID_TOSHIBA_CLICK_L9W 0x0401 |
| 390 | #define USB_DEVICE_ID_HP_X2 0x074d | 390 | #define USB_DEVICE_ID_HP_X2 0x074d |
| 391 | #define USB_DEVICE_ID_HP_X2_10_COVER 0x0755 | 391 | #define USB_DEVICE_ID_HP_X2_10_COVER 0x0755 |
| 392 | #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706 | ||
| 392 | 393 | ||
| 393 | #define USB_VENDOR_ID_ELECOM 0x056e | 394 | #define USB_VENDOR_ID_ELECOM 0x056e |
| 394 | #define USB_DEVICE_ID_ELECOM_BM084 0x0061 | 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 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, | 322 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, |
| 323 | USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD), | 323 | USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD), |
| 324 | HID_BATTERY_QUIRK_IGNORE }, | 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 | HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, | 1869 | HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, |
| 1870 | 0xc531), | 1870 | 0xc531), |
| 1871 | .driver_data = recvr_type_gaming_hidpp}, | 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 | { /* Logitech lightspeed receiver (0xc539) */ | 1876 | { /* Logitech lightspeed receiver (0xc539) */ |
| 1873 | HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, | 1877 | HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, |
| 1874 | USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1), | 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 | { /* MX Master mouse over Bluetooth */ | 4053 | { /* MX Master mouse over Bluetooth */ |
| 4054 | HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb012), | 4054 | HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb012), |
| 4055 | .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | 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 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01e), | 4058 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01e), |
| 4057 | .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | 4059 | .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, |
| 4058 | { /* MX Master 3 mouse over Bluetooth */ | 4060 | { /* MX Master 3 mouse over Bluetooth */ |
| @@ -2054,6 +2054,10 @@ static const struct hid_device_id mt_devices[] = { · 2053 unmodified lines | |||
| 2054 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, | 2054 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, |
| 2055 | USB_VENDOR_ID_SYNAPTICS, 0xce08) }, | 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 | /* TopSeed panels */ | 2061 | /* TopSeed panels */ |
| 2058 | { .driver_data = MT_CLS_TOPSEED, | 2062 | { .driver_data = MT_CLS_TOPSEED, |
| 2059 | MT_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, | 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 | goto cleanup; | 90 | goto cleanup; |
| 91 | } else if (rc < 0) { | 91 | } else if (rc < 0) { |
| 92 | hid_err(hdev, | 92 | hid_err(hdev, |
| 93 | "failed retrieving string descriptor #%hhu: %d\n", | 93 | "failed retrieving string descriptor #%u: %d\n", |
| 94 | idx, rc); | 94 | idx, rc); |
| 95 | goto cleanup; | 95 | goto cleanup; |
| 96 | } | 96 | } |
| @@ -1482,7 +1482,7 @@ static void handler_return(struct wiimote_data *wdata, const __u8 *payload) · 1481 unmodified lines | |||
| 1482 | wdata->state.cmd_err = err; | 1482 | wdata->state.cmd_err = err; |
| 1483 | wiimote_cmd_complete(wdata); | 1483 | wiimote_cmd_complete(wdata); |
| 1484 | } else if (err) { | 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 | cmd); | 1486 | cmd); |
| 1487 | } | 1487 | } |
| 1488 | } | 1488 | } |
| @@ -1270,6 +1270,37 @@ static int wacom_devm_sysfs_create_group(struct wacom *wacom, · 1269 unmodified lines | |||
| 1270 | group); | 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 | enum led_brightness wacom_leds_brightness_get(struct wacom_led *led) | 1304 | enum led_brightness wacom_leds_brightness_get(struct wacom_led *led) |
| 1274 | { | 1305 | { |
| 1275 | struct wacom *wacom = led->wacom; | 1306 | struct wacom *wacom = led->wacom; |
| @@ -2724,7 +2755,7 @@ static int wacom_probe(struct hid_device *hdev, · 1448 unmodified lines | |||
| 2724 | if (features->check_for_hid_type && features->hid_type != hdev->type) | 2755 | if (features->check_for_hid_type && features->hid_type != hdev->type) |
| 2725 | return -ENODEV; | 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 | if (error) | 2759 | if (error) |
| 2729 | return error; | 2760 | return error; |
| 2730 | 2761 | ||
| @@ -2786,8 +2817,6 @@ static void wacom_remove(struct hid_device *hdev) · 55 unmodified lines | |||
| 2786 | 2817 | ||
| 2787 | if (wacom->wacom_wac.features.type != REMOTE) | 2818 | if (wacom->wacom_wac.features.type != REMOTE) |
| 2788 | wacom_release_resources(wacom); | 2819 | wacom_release_resources(wacom); |
| 2789 | |||
| 2790 | kfifo_free(&wacom_wac->pen_fifo); | ||
| 2791 | } | 2820 | } |
| 2792 | 2821 | ||
| 2793 | #ifdef CONFIG_PM | 2822 | #ifdef CONFIG_PM |
| @@ -2550,7 +2550,6 @@ static void hv_kexec_handler(void) · 2549 unmodified lines | |||
| 2550 | /* Make sure conn_state is set as hv_synic_cleanup checks for it */ | 2550 | /* Make sure conn_state is set as hv_synic_cleanup checks for it */ |
| 2551 | mb(); | 2551 | mb(); |
| 2552 | cpuhp_remove_state(hyperv_cpuhp_online); | 2552 | cpuhp_remove_state(hyperv_cpuhp_online); |
| 2553 | hyperv_cleanup(); | ||
| 2554 | }; | 2553 | }; |
| 2555 | 2554 | ||
| 2556 | static void hv_crash_handler(struct pt_regs *regs) | 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 | cpu = smp_processor_id(); | 2565 | cpu = smp_processor_id(); |
| 2567 | hv_stimer_cleanup(cpu); | 2566 | hv_stimer_cleanup(cpu); |
| 2568 | hv_synic_disable_regs(cpu); | 2567 | hv_synic_disable_regs(cpu); |
| 2569 | hyperv_cleanup(); | ||
| 2570 | }; | 2568 | }; |
| 2571 | 2569 | ||
| 2572 | static int hv_synic_suspend(void) | 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 | cpus = num_present_cpus() / num_siblings; | 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 | sizeof(u32), GFP_KERNEL); | 226 | sizeof(u32), GFP_KERNEL); |
| 227 | if (!s_config) | 227 | if (!s_config) |
| 228 | return -ENOMEM; | 228 | return -ENOMEM; |
| @@ -254,6 +254,7 @@ static int amd_create_sensor(struct device *dev, · 25 unmodified lines | |||
| 254 | scnprintf(label_l[i], 10, "Esocket%u", (i - cpus)); | 254 | scnprintf(label_l[i], 10, "Esocket%u", (i - cpus)); |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | s_config[i] = 0; | ||
| 257 | return 0; | 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 | ctx->pwm_value = MAX_PWM; | 335 | ctx->pwm_value = MAX_PWM; |
| 336 | 336 | ||
| 337 | /* Set duty cycle to maximum allowed and enable PWM output */ | ||
| 338 | pwm_init_state(ctx->pwm, &state); | 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 | state.duty_cycle = ctx->pwm->args.period - 1; | 349 | state.duty_cycle = ctx->pwm->args.period - 1; |
| 340 | state.enabled = true; | 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 | /* Register GPIO descriptor lookup table */ | 1450 | /* Register GPIO descriptor lookup table */ |
| 1451 | lookup = devm_kzalloc(dev, | 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 | GFP_KERNEL); | 1453 | GFP_KERNEL); |
| 1454 | if (!lookup) | 1454 | if (!lookup) |
| 1455 | return -ENOMEM; | 1455 | return -ENOMEM; |
| @@ -38,6 +38,7 @@ · 37 unmodified lines | |||
| 38 | #define I2C_IO_CONFIG_OPEN_DRAIN 0x0003 | 38 | #define I2C_IO_CONFIG_OPEN_DRAIN 0x0003 |
| 39 | #define I2C_IO_CONFIG_PUSH_PULL 0x0000 | 39 | #define I2C_IO_CONFIG_PUSH_PULL 0x0000 |
| 40 | #define I2C_SOFT_RST 0x0001 | 40 | #define I2C_SOFT_RST 0x0001 |
| 41 | #define I2C_HANDSHAKE_RST 0x0020 | ||
| 41 | #define I2C_FIFO_ADDR_CLR 0x0001 | 42 | #define I2C_FIFO_ADDR_CLR 0x0001 |
| 42 | #define I2C_DELAY_LEN 0x0002 | 43 | #define I2C_DELAY_LEN 0x0002 |
| 43 | #define I2C_TIME_CLR_VALUE 0x0000 | 44 | #define I2C_TIME_CLR_VALUE 0x0000 |
| @@ -45,6 +46,7 @@ · 1 unmodified line | |||
| 45 | #define I2C_WRRD_TRANAC_VALUE 0x0002 | 46 | #define I2C_WRRD_TRANAC_VALUE 0x0002 |
| 46 | #define I2C_RD_TRANAC_VALUE 0x0001 | 47 | #define I2C_RD_TRANAC_VALUE 0x0001 |
| 47 | #define I2C_SCL_MIS_COMP_VALUE 0x0000 | 48 | #define I2C_SCL_MIS_COMP_VALUE 0x0000 |
| 49 | #define I2C_CHN_CLR_FLAG 0x0000 | ||
| 48 | 50 | ||
| 49 | #define I2C_DMA_CON_TX 0x0000 | 51 | #define I2C_DMA_CON_TX 0x0000 |
| 50 | #define I2C_DMA_CON_RX 0x0001 | 52 | #define I2C_DMA_CON_RX 0x0001 |
| @@ -54,7 +56,9 @@ · 3 unmodified lines | |||
| 54 | #define I2C_DMA_START_EN 0x0001 | 56 | #define I2C_DMA_START_EN 0x0001 |
| 55 | #define I2C_DMA_INT_FLAG_NONE 0x0000 | 57 | #define I2C_DMA_INT_FLAG_NONE 0x0000 |
| 56 | #define I2C_DMA_CLR_FLAG 0x0000 | 58 | #define I2C_DMA_CLR_FLAG 0x0000 |
| 59 | #define I2C_DMA_WARM_RST 0x0001 | ||
| 57 | #define I2C_DMA_HARD_RST 0x0002 | 60 | #define I2C_DMA_HARD_RST 0x0002 |
| 61 | #define I2C_DMA_HANDSHAKE_RST 0x0004 | ||
| 58 | 62 | ||
| 59 | #define MAX_SAMPLE_CNT_DIV 8 | 63 | #define MAX_SAMPLE_CNT_DIV 8 |
| 60 | #define MAX_STEP_CNT_DIV 64 | 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 | u16 control_reg; | 480 | u16 control_reg; |
| 477 | 481 | ||
| 478 | writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST); | 482 | if (i2c->dev_comp->dma_sync) { |
| 479 | udelay(50); | 483 | writel(I2C_DMA_WARM_RST, i2c->pdmabase + OFFSET_RST); |
| 480 | writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST); | 484 | udelay(10); |
| 481 | 485 | writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST); | |
| 482 | mtk_i2c_writew(i2c, I2C_SOFT_RST, OFFSET_SOFTRESET); | 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 | /* Set ioconfig */ | 501 | /* Set ioconfig */ |
| 485 | if (i2c->use_push_pull) | 502 | if (i2c->use_push_pull) |
| @@ -72,6 +72,8 @@ · 71 unmodified lines | |||
| 72 | 72 | ||
| 73 | /* timeout (ms) for pm runtime autosuspend */ | 73 | /* timeout (ms) for pm runtime autosuspend */ |
| 74 | #define SPRD_I2C_PM_TIMEOUT 1000 | 74 | #define SPRD_I2C_PM_TIMEOUT 1000 |
| 75 | /* timeout (ms) for transfer message */ | ||
| 76 | #define I2C_XFER_TIMEOUT 1000 | ||
| 75 | 77 | ||
| 76 | /* SPRD i2c data structure */ | 78 | /* SPRD i2c data structure */ |
| 77 | struct sprd_i2c { | 79 | struct sprd_i2c { |
| @@ -244,6 +246,7 @@ static int sprd_i2c_handle_msg(struct i2c_adapter *i2c_adap, · 166 unmodified lines | |||
| 244 | struct i2c_msg *msg, bool is_last_msg) | 246 | struct i2c_msg *msg, bool is_last_msg) |
| 245 | { | 247 | { |
| 246 | struct sprd_i2c *i2c_dev = i2c_adap->algo_data; | 248 | struct sprd_i2c *i2c_dev = i2c_adap->algo_data; |
| 249 | unsigned long time_left; | ||
| 247 | 250 | ||
| 248 | i2c_dev->msg = msg; | 251 | i2c_dev->msg = msg; |
| 249 | i2c_dev->buf = msg->buf; | 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 | sprd_i2c_opt_start(i2c_dev); | 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 | return i2c_dev->err; | 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 | sense_rq->rq_disk = rq->rq_disk; | 223 | sense_rq->rq_disk = rq->rq_disk; |
| 224 | sense_rq->cmd_flags = REQ_OP_DRV_IN; | 224 | sense_rq->cmd_flags = REQ_OP_DRV_IN; |
| 225 | ide_req(sense_rq)->type = ATA_PRIV_SENSE; | 225 | ide_req(sense_rq)->type = ATA_PRIV_SENSE; |
| 226 | sense_rq->rq_flags |= RQF_PREEMPT; | ||
| 227 | 226 | ||
| 228 | req->cmd[0] = GPCMD_REQUEST_SENSE; | 227 | req->cmd[0] = GPCMD_REQUEST_SENSE; |
| 229 | req->cmd[4] = cmd_len; | 228 | req->cmd[4] = cmd_len; |
| @@ -515,15 +515,10 @@ repeat: · 514 unmodified lines | |||
| 515 | * above to return us whatever is in the queue. Since we call | 515 | * above to return us whatever is in the queue. Since we call |
| 516 | * ide_do_request() ourselves, we end up taking requests while | 516 | * ide_do_request() ourselves, we end up taking requests while |
| 517 | * the queue is blocked... | 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 | if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && | 519 | if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && |
| 525 | ata_pm_request(rq) == 0 && | 520 | ata_pm_request(rq) == 0 && |
| 526 | (rq->rq_flags & RQF_PREEMPT) == 0) { | 521 | (rq->rq_flags & RQF_PM) == 0) { |
| 527 | /* there should be no pending command at this point */ | 522 | /* there should be no pending command at this point */ |
| 528 | ide_unlock_port(hwif); | 523 | ide_unlock_port(hwif); |
| 529 | goto plug_device; | 524 | goto plug_device; |
| @@ -77,7 +77,7 @@ int generic_ide_resume(struct device *dev) · 76 unmodified lines | |||
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | memset(&rqpm, 0, sizeof(rqpm)); | 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 | ide_req(rq)->type = ATA_PRIV_PM_RESUME; | 81 | ide_req(rq)->type = ATA_PRIV_PM_RESUME; |
| 82 | ide_req(rq)->special = &rqpm; | 82 | ide_req(rq)->special = &rqpm; |
| 83 | rqpm.pm_step = IDE_PM_START_RESUME; | 83 | rqpm.pm_step = IDE_PM_START_RESUME; |
| @@ -963,6 +963,39 @@ static struct cpuidle_state dnv_cstates[] __initdata = { · 962 unmodified lines | |||
| 963 | .enter = NULL } | 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 | static const struct idle_cpu idle_cpu_nehalem __initconst = { | 999 | static const struct idle_cpu idle_cpu_nehalem __initconst = { |
| 967 | .state_table = nehalem_cstates, | 1000 | .state_table = nehalem_cstates, |
| 968 | .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE, | 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 | .use_acpi = true, | 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 | static const struct x86_cpu_id intel_idle_ids[] __initconst = { | 1126 | static const struct x86_cpu_id intel_idle_ids[] __initconst = { |
| 1088 | X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EP, &idle_cpu_nhx), | 1127 | X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EP, &idle_cpu_nhx), |
| 1089 | X86_MATCH_INTEL_FAM6_MODEL(NEHALEM, &idle_cpu_nehalem), | 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 | X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &idle_cpu_bxt), | 1161 | X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &idle_cpu_bxt), |
| 1123 | X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS, &idle_cpu_bxt), | 1162 | X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS, &idle_cpu_bxt), |
| 1124 | X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_D, &idle_cpu_dnv), | 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 | return ret; | 131 | return ret; |
| 132 | 132 | ||
| 133 | gid_type = ib_cache_gid_parse_type_str(buf); | 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 | return -EINVAL; | 136 | return -EINVAL; |
| 137 | } | ||
| 136 | 138 | ||
| 137 | ret = cma_set_default_gid_type(cma_dev, group->port_num, gid_type); | 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 | } else { | 254 | } else { |
| 255 | ret = xa_alloc_cyclic(&rt->xa, &res->id, res, xa_limit_32b, | 255 | ret = xa_alloc_cyclic(&rt->xa, &res->id, res, xa_limit_32b, |
| 256 | &rt->next_id, GFP_KERNEL); | 256 | &rt->next_id, GFP_KERNEL); |
| 257 | ret = (ret < 0) ? ret : 0; | ||
| 257 | } | 258 | } |
| 258 | 259 | ||
| 259 | out: | 260 | out: |
| @@ -95,8 +95,6 @@ struct ucma_context { · 94 unmodified lines | |||
| 95 | u64 uid; | 95 | u64 uid; |
| 96 | 96 | ||
| 97 | struct list_head list; | 97 | struct list_head list; |
| 98 | /* sync between removal event and id destroy, protected by file mut */ | ||
| 99 | int destroying; | ||
| 100 | struct work_struct close_work; | 98 | struct work_struct close_work; |
| 101 | }; | 99 | }; |
| 102 | 100 | ||
| @@ -122,7 +120,7 @@ static DEFINE_XARRAY_ALLOC(ctx_table); · 19 unmodified lines | |||
| 122 | static DEFINE_XARRAY_ALLOC(multicast_table); | 120 | static DEFINE_XARRAY_ALLOC(multicast_table); |
| 123 | 121 | ||
| 124 | static const struct file_operations ucma_fops; | 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 | static inline struct ucma_context *_ucma_find_context(int id, | 125 | static inline struct ucma_context *_ucma_find_context(int id, |
| 128 | struct ucma_file *file) | 126 | struct ucma_file *file) |
| @@ -179,19 +177,14 @@ static void ucma_close_id(struct work_struct *work) · 50 unmodified lines | |||
| 179 | 177 | ||
| 180 | /* once all inflight tasks are finished, we close all underlying | 178 | /* once all inflight tasks are finished, we close all underlying |
| 181 | * resources. The context is still alive till its explicit destryoing | 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 | ucma_put_ctx(ctx); | 182 | ucma_put_ctx(ctx); |
| 185 | wait_for_completion(&ctx->comp); | 183 | wait_for_completion(&ctx->comp); |
| 186 | /* No new events will be generated after destroying the id. */ | 184 | /* No new events will be generated after destroying the id. */ |
| 187 | rdma_destroy_id(ctx->cm_id); | 185 | rdma_destroy_id(ctx->cm_id); |
| 188 | 186 | ||
| 189 | /* | 187 | /* Reading the cm_id without holding a positive ref is not allowed */ |
| 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 | */ | ||
| 195 | ctx->cm_id = NULL; | 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 | return NULL; | 197 | return NULL; |
| 205 | 198 | ||
| 206 | INIT_WORK(&ctx->close_work, ucma_close_id); | 199 | INIT_WORK(&ctx->close_work, ucma_close_id); |
| 207 | refcount_set(&ctx->ref, 1); | ||
| 208 | init_completion(&ctx->comp); | 200 | init_completion(&ctx->comp); |
| 209 | /* So list_del() will work if we don't do ucma_finish_ctx() */ | 201 | /* So list_del() will work if we don't do ucma_finish_ctx() */ |
| 210 | INIT_LIST_HEAD(&ctx->list); | 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 | return ctx; | 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 | static void ucma_finish_ctx(struct ucma_context *ctx) | 220 | static void ucma_finish_ctx(struct ucma_context *ctx) |
| 222 | { | 221 | { |
| 223 | lockdep_assert_held(&ctx->file->mut); | 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 | ctx = ucma_alloc_ctx(listen_ctx->file); | 302 | ctx = ucma_alloc_ctx(listen_ctx->file); |
| 304 | if (!ctx) | 303 | if (!ctx) |
| 305 | goto err_backlog; | 304 | goto err_backlog; |
| 306 | ctx->cm_id = cm_id; | 305 | ucma_set_ctx_cm_id(ctx, cm_id); |
| 307 | 306 | ||
| 308 | uevent = ucma_create_uevent(listen_ctx, event); | 307 | uevent = ucma_create_uevent(listen_ctx, event); |
| 309 | if (!uevent) | 308 | if (!uevent) |
| @@ -321,8 +320,7 @@ static int ucma_connect_event_handler(struct rdma_cm_id *cm_id, · 11 unmodified lines | |||
| 321 | return 0; | 320 | return 0; |
| 322 | 321 | ||
| 323 | err_alloc: | 322 | err_alloc: |
| 324 | xa_erase(&ctx_table, ctx->id); | 323 | ucma_destroy_private_ctx(ctx); |
| 325 | kfree(ctx); | ||
| 326 | err_backlog: | 324 | err_backlog: |
| 327 | atomic_inc(&listen_ctx->backlog); | 325 | atomic_inc(&listen_ctx->backlog); |
| 328 | /* Returning error causes the new ID to be destroyed */ | 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 | wake_up_interruptible(&ctx->file->poll_wait); | 354 | wake_up_interruptible(&ctx->file->poll_wait); |
| 357 | } | 355 | } |
| 358 | 356 | ||
| 359 | if (event->event == RDMA_CM_EVENT_DEVICE_REMOVAL && !ctx->destroying) | 357 | if (event->event == RDMA_CM_EVENT_DEVICE_REMOVAL) { |
| 360 | queue_work(system_unbound_wq, &ctx->close_work); | 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 | return 0; | 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 | ret = PTR_ERR(cm_id); | 463 | ret = PTR_ERR(cm_id); |
| 462 | goto err1; | 464 | goto err1; |
| 463 | } | 465 | } |
| 464 | ctx->cm_id = cm_id; | 466 | ucma_set_ctx_cm_id(ctx, cm_id); |
| 465 | 467 | ||
| 466 | resp.id = ctx->id; | 468 | resp.id = ctx->id; |
| 467 | if (copy_to_user(u64_to_user_ptr(cmd.response), | 469 | if (copy_to_user(u64_to_user_ptr(cmd.response), |
| 468 | &resp, sizeof(resp))) { | 470 | &resp, sizeof(resp))) { |
| 469 | xa_erase(&ctx_table, ctx->id); | 471 | ucma_destroy_private_ctx(ctx); |
| 470 | __destroy_id(ctx); | ||
| 471 | return -EFAULT; | 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 | return 0; | 478 | return 0; |
| 478 | 479 | ||
| 479 | err1: | 480 | err1: |
| 480 | xa_erase(&ctx_table, ctx->id); | 481 | ucma_destroy_private_ctx(ctx); |
| 481 | kfree(ctx); | ||
| 482 | return ret; | 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 | rdma_unlock_handler(mc->ctx->cm_id); | 516 | rdma_unlock_handler(mc->ctx->cm_id); |
| 517 | } | 517 | } |
| 518 | 518 | ||
| 519 | /* | 519 | static int ucma_cleanup_ctx_events(struct ucma_context *ctx) |
| 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) | ||
| 527 | { | 520 | { |
| 528 | int events_reported; | 521 | int events_reported; |
| 529 | struct ucma_event *uevent, *tmp; | 522 | struct ucma_event *uevent, *tmp; |
| 530 | LIST_HEAD(list); | 523 | LIST_HEAD(list); |
| 531 | 524 | ||
| 532 | ucma_cleanup_multicast(ctx); | 525 | /* Cleanup events not yet reported to the user.*/ |
| 533 | |||
| 534 | /* Cleanup events not yet reported to the user. */ | ||
| 535 | mutex_lock(&ctx->file->mut); | 526 | mutex_lock(&ctx->file->mut); |
| 536 | list_for_each_entry_safe(uevent, tmp, &ctx->file->event_list, list) { | 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 | list_move_tail(&uevent->list, &list); | 535 | list_move_tail(&uevent->list, &list); |
| 536 | continue; | ||
| 537 | } | ||
| 538 | list_del(&uevent->list); | ||
| 539 | kfree(uevent); | ||
| 539 | } | 540 | } |
| 540 | list_del(&ctx->list); | 541 | list_del(&ctx->list); |
| 541 | events_reported = ctx->events_reported; | 542 | events_reported = ctx->events_reported; |
| 542 | mutex_unlock(&ctx->file->mut); | 543 | mutex_unlock(&ctx->file->mut); |
| 543 | 544 | ||
| 544 | /* | 545 | /* |
| 545 | * If this was a listening ID then any connections spawned from it | 546 | * If this was a listening ID then any connections spawned from it that |
| 546 | * that have not been delivered to userspace are cleaned up too. | 547 | * have not been delivered to userspace are cleaned up too. Must be done |
| 547 | * Must be done outside any locks. | 548 | * outside any locks. |
| 548 | */ | 549 | */ |
| 549 | list_for_each_entry_safe(uevent, tmp, &list, list) { | 550 | list_for_each_entry_safe(uevent, tmp, &list, list) { |
| 550 | list_del(&uevent->list); | 551 | ucma_destroy_private_ctx(uevent->conn_req_ctx); |
| 551 | if (uevent->resp.event == RDMA_CM_EVENT_CONNECT_REQUEST && | ||
| 552 | uevent->conn_req_ctx != ctx) | ||
| 553 | __destroy_id(uevent->conn_req_ctx); | ||
| 554 | kfree(uevent); | 552 | kfree(uevent); |
| 555 | } | 553 | } |
| 556 | |||
| 557 | mutex_destroy(&ctx->mutex); | ||
| 558 | kfree(ctx); | ||
| 559 | return events_reported; | 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 | 568 | * Destroy the underlying cm_id. New work queuing is prevented now by |
| 566 | * destroyed the cm_id, otherwise holding the refcount keeps cm_id | 569 | * the removal from the xarray. Once the work is cancled ref will either |
| 567 | * valid. Prevent queue_work() from being called. | 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 | cancel_work_sync(&ctx->close_work); | 574 | cancel_work_sync(&ctx->close_work); |
| 577 | /* At this point it's guaranteed that there is no inflight closing task */ | 575 | if (refcount_read(&ctx->ref)) |
| 578 | if (ctx->cm_id) | ||
| 579 | ucma_close_id(&ctx->close_work); | 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 | static ssize_t ucma_destroy_id(struct ucma_file *file, const char __user *inbuf, | 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 | xa_lock(&ctx_table); | 602 | xa_lock(&ctx_table); |
| 598 | ctx = _ucma_find_context(cmd.id, file); | 603 | ctx = _ucma_find_context(cmd.id, file); |
| 599 | if (!IS_ERR(ctx)) | 604 | if (!IS_ERR(ctx)) { |
| 600 | __xa_erase(&ctx_table, ctx->id); | 605 | if (__xa_cmpxchg(&ctx_table, ctx->id, ctx, XA_ZERO_ENTRY, |
| 606 | GFP_KERNEL) != ctx) | ||
| 607 | ctx = ERR_PTR(-ENOENT); | ||
| 608 | } | ||
| 601 | xa_unlock(&ctx_table); | 609 | xa_unlock(&ctx_table); |
| 602 | 610 | ||
| 603 | if (IS_ERR(ctx)) | 611 | if (IS_ERR(ctx)) |
| 604 | return PTR_ERR(ctx); | 612 | return PTR_ERR(ctx); |
| 605 | 613 | ||
| 606 | resp.events_reported = __destroy_id(ctx); | 614 | resp.events_reported = ucma_destroy_private_ctx(ctx); |
| 607 | if (copy_to_user(u64_to_user_ptr(cmd.response), | 615 | if (copy_to_user(u64_to_user_ptr(cmd.response), |
| 608 | &resp, sizeof(resp))) | 616 | &resp, sizeof(resp))) |
| 609 | ret = -EFAULT; | 617 | ret = -EFAULT; |
| @@ -1777,15 +1785,16 @@ static int ucma_close(struct inode *inode, struct file *filp) · 1167 unmodified lines | |||
| 1777 | * prevented by this being a FD release function. The list_add_tail() in | 1785 | * prevented by this being a FD release function. The list_add_tail() in |
| 1778 | * ucma_connect_event_handler() can run concurrently, however it only | 1786 | * ucma_connect_event_handler() can run concurrently, however it only |
| 1779 | * adds to the list *after* a listening ID. By only reading the first of | 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 | * ucma_connect_event_handler(), no additional locking is needed. | 1789 | * ucma_connect_event_handler(), no additional locking is needed. |
| 1782 | */ | 1790 | */ |
| 1783 | while (!list_empty(&file->ctx_list)) { | 1791 | while (!list_empty(&file->ctx_list)) { |
| 1784 | struct ucma_context *ctx = list_first_entry( | 1792 | struct ucma_context *ctx = list_first_entry( |
| 1785 | &file->ctx_list, struct ucma_context, list); | 1793 | &file->ctx_list, struct ucma_context, list); |
| 1786 | 1794 | ||
| 1787 | xa_erase(&ctx_table, ctx->id); | 1795 | WARN_ON(xa_cmpxchg(&ctx_table, ctx->id, ctx, XA_ZERO_ENTRY, |
| 1788 | __destroy_id(ctx); | 1796 | GFP_KERNEL) != ctx); |
| 1797 | ucma_destroy_private_ctx(ctx); | ||
| 1789 | } | 1798 | } |
| 1790 | kfree(file); | 1799 | kfree(file); |
| 1791 | return 0; | 1800 | return 0; |
| @@ -135,7 +135,7 @@ unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem, · 134 unmodified lines | |||
| 135 | */ | 135 | */ |
| 136 | if (mask) | 136 | if (mask) |
| 137 | pgsz_bitmap &= GENMASK(count_trailing_zeros(mask), 0); | 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 | EXPORT_SYMBOL(ib_umem_find_best_pgsz); | 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 | err = set_has_smi_cap(dev); | 3957 | err = set_has_smi_cap(dev); |
| 3958 | if (err) | 3958 | if (err) |
| 3959 | return err; | 3959 | goto err_mp; |
| 3960 | 3960 | ||
| 3961 | if (!mlx5_core_mp_enabled(mdev)) { | 3961 | if (!mlx5_core_mp_enabled(mdev)) { |
| 3962 | for (i = 1; i <= dev->num_ports; i++) { | 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 | err = mlx5_alloc_bfreg(dev->mdev, &dev->fp_bfreg, false, true); | 4320 | err = mlx5_alloc_bfreg(dev->mdev, &dev->fp_bfreg, false, true); |
| 4321 | if (err) | 4321 | if (err) |
| 4322 | mlx5_free_bfreg(dev->mdev, &dev->fp_bfreg); | 4322 | mlx5_free_bfreg(dev->mdev, &dev->bfreg); |
| 4323 | 4323 | ||
| 4324 | return err; | 4324 | return err; |
| 4325 | } | 4325 | } |
| @@ -434,9 +434,9 @@ static void ocrdma_dealloc_ucontext_pd(struct ocrdma_ucontext *uctx) · 433 unmodified lines | |||
| 434 | pr_err("%s(%d) Freeing in use pdid=0x%x.\n", | 434 | pr_err("%s(%d) Freeing in use pdid=0x%x.\n", |
| 435 | __func__, dev->id, pd->id); | 435 | __func__, dev->id, pd->id); |
| 436 | } | 436 | } |
| 437 | kfree(uctx->cntxt_pd); | ||
| 438 | uctx->cntxt_pd = NULL; | 437 | uctx->cntxt_pd = NULL; |
| 439 | _ocrdma_dealloc_pd(dev, pd); | 438 | _ocrdma_dealloc_pd(dev, pd); |
| 439 | kfree(pd); | ||
| 440 | } | 440 | } |
| 441 | 441 | ||
| 442 | static struct ocrdma_pd *ocrdma_get_ucontext_pd(struct ocrdma_ucontext *uctx) | 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 | usnic_uiom_free_dev_list(dev_list); | 216 | usnic_uiom_free_dev_list(dev_list); |
| 217 | dev_list = NULL; | ||
| 217 | } | 218 | } |
| 218 | 219 | ||
| 219 | /* Try to find resources on an unused vf */ | 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 | qp_grp_check: | 240 | qp_grp_check: |
| 240 | if (IS_ERR_OR_NULL(qp_grp)) { | 241 | if (IS_ERR_OR_NULL(qp_grp)) { |
| 241 | usnic_err("Failed to allocate qp_grp\n"); | 242 | usnic_err("Failed to allocate qp_grp\n"); |
| 243 | if (usnic_ib_share_vf) | ||
| 244 | usnic_uiom_free_dev_list(dev_list); | ||
| 242 | return ERR_PTR(qp_grp ? PTR_ERR(qp_grp) : -ENOMEM); | 245 | return ERR_PTR(qp_grp ? PTR_ERR(qp_grp) : -ENOMEM); |
| 243 | } | 246 | } |
| 244 | return qp_grp; | 247 | return qp_grp; |
| @@ -96,9 +96,10 @@ static int imx_icc_node_init_qos(struct icc_provider *provider, · 95 unmodified lines | |||
| 96 | return -ENODEV; | 96 | return -ENODEV; |
| 97 | } | 97 | } |
| 98 | /* Allow scaling to be disabled on a per-node basis */ | 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 | dev_warn(dev, "Missing property %s, skip scaling %s\n", | 100 | dev_warn(dev, "Missing property %s, skip scaling %s\n", |
| 101 | adj->phandle_name, node->name); | 101 | adj->phandle_name, node->name); |
| 102 | of_node_put(dn); | ||
| 102 | return 0; | 103 | return 0; |
| 103 | } | 104 | } |
| 104 | 105 | ||
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
| 9 | #include <linux/platform_device.h> | 9 | #include <linux/platform_device.h> |
| 10 | #include <linux/interconnect-provider.h> | ||
| 10 | #include <dt-bindings/interconnect/imx8mq.h> | 11 | #include <dt-bindings/interconnect/imx8mq.h> |
| 11 | 12 | ||
| 12 | #include "imx.h" | 13 | #include "imx.h" |
| @@ -94,6 +95,7 @@ static struct platform_driver imx8mq_icc_driver = { · 81 unmodified lines | |||
| 94 | .remove = imx8mq_icc_remove, | 95 | .remove = imx8mq_icc_remove, |
| 95 | .driver = { | 96 | .driver = { |
| 96 | .name = "imx8mq-interconnect", | 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 | This is a driver for the Qualcomm Network-on-Chip on qcs404-based | 42 | This is a driver for the Qualcomm Network-on-Chip on qcs404-based |
| 43 | platforms. | 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 | config INTERCONNECT_QCOM_RPMH | 56 | config INTERCONNECT_QCOM_RPMH |
| 46 | tristate | 57 | tristate |
| 47 | 58 | ||
| 48 | config INTERCONNECT_QCOM_SC7180 | 59 | config INTERCONNECT_QCOM_SC7180 |
| 49 | tristate "Qualcomm SC7180 interconnect driver" | 60 | tristate "Qualcomm SC7180 interconnect driver" |
| 50 | depends on INTERCONNECT_QCOM | 61 | depends on INTERCONNECT_QCOM_RPMH_POSSIBLE |
| 51 | depends on (QCOM_RPMH && QCOM_COMMAND_DB && OF) || COMPILE_TEST | ||
| 52 | select INTERCONNECT_QCOM_RPMH | 62 | select INTERCONNECT_QCOM_RPMH |
| 53 | select INTERCONNECT_QCOM_BCM_VOTER | 63 | select INTERCONNECT_QCOM_BCM_VOTER |
| 54 | help | 64 | help |
| @@ -57,8 +67,7 @@ config INTERCONNECT_QCOM_SC7180 · 2 unmodified lines | |||
| 57 | 67 | ||
| 58 | config INTERCONNECT_QCOM_SDM845 | 68 | config INTERCONNECT_QCOM_SDM845 |
| 59 | tristate "Qualcomm SDM845 interconnect driver" | 69 | tristate "Qualcomm SDM845 interconnect driver" |
| 60 | depends on INTERCONNECT_QCOM | 70 | depends on INTERCONNECT_QCOM_RPMH_POSSIBLE |
| 61 | depends on (QCOM_RPMH && QCOM_COMMAND_DB && OF) || COMPILE_TEST | ||
| 62 | select INTERCONNECT_QCOM_RPMH | 71 | select INTERCONNECT_QCOM_RPMH |
| 63 | select INTERCONNECT_QCOM_BCM_VOTER | 72 | select INTERCONNECT_QCOM_BCM_VOTER |
| 64 | help | 73 | help |
| @@ -67,8 +76,7 @@ config INTERCONNECT_QCOM_SDM845 · 2 unmodified lines | |||
| 67 | 76 | ||
| 68 | config INTERCONNECT_QCOM_SM8150 | 77 | config INTERCONNECT_QCOM_SM8150 |
| 69 | tristate "Qualcomm SM8150 interconnect driver" | 78 | tristate "Qualcomm SM8150 interconnect driver" |
| 70 | depends on INTERCONNECT_QCOM | 79 | depends on INTERCONNECT_QCOM_RPMH_POSSIBLE |
| 71 | depends on (QCOM_RPMH && QCOM_COMMAND_DB && OF) || COMPILE_TEST | ||
| 72 | select INTERCONNECT_QCOM_RPMH | 80 | select INTERCONNECT_QCOM_RPMH |
| 73 | select INTERCONNECT_QCOM_BCM_VOTER | 81 | select INTERCONNECT_QCOM_BCM_VOTER |
| 74 | help | 82 | help |
| @@ -77,8 +85,7 @@ config INTERCONNECT_QCOM_SM8150 · 2 unmodified lines | |||
| 77 | 85 | ||
| 78 | config INTERCONNECT_QCOM_SM8250 | 86 | config INTERCONNECT_QCOM_SM8250 |
| 79 | tristate "Qualcomm SM8250 interconnect driver" | 87 | tristate "Qualcomm SM8250 interconnect driver" |
| 80 | depends on INTERCONNECT_QCOM | 88 | depends on INTERCONNECT_QCOM_RPMH_POSSIBLE |
| 81 | depends on (QCOM_RPMH && QCOM_COMMAND_DB && OF) || COMPILE_TEST | ||
| 82 | select INTERCONNECT_QCOM_RPMH | 89 | select INTERCONNECT_QCOM_RPMH |
| 83 | select INTERCONNECT_QCOM_BCM_VOTER | 90 | select INTERCONNECT_QCOM_BCM_VOTER |
| 84 | help | 91 | help |
| @@ -1973,8 +1973,6 @@ static int iommu_setup_msi(struct amd_iommu *iommu) · 1972 unmodified lines | |||
| 1973 | return r; | 1973 | return r; |
| 1974 | } | 1974 | } |
| 1975 | 1975 | ||
| 1976 | iommu->int_enabled = true; | ||
| 1977 | |||
| 1978 | return 0; | 1976 | return 0; |
| 1979 | } | 1977 | } |
| 1980 | 1978 | ||
| @@ -2169,6 +2167,7 @@ static int iommu_init_irq(struct amd_iommu *iommu) · 188 unmodified lines | |||
| 2169 | if (ret) | 2167 | if (ret) |
| 2170 | return ret; | 2168 | return ret; |
| 2171 | 2169 | ||
| 2170 | iommu->int_enabled = true; | ||
| 2172 | enable_faults: | 2171 | enable_faults: |
| 2173 | iommu_feature_enable(iommu, CONTROL_EVT_INT_EN); | 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 | struct amd_iommu *iommu; | 3854 | struct amd_iommu *iommu; |
| 3855 | int devid = -1; | 3855 | int devid = -1; |
| 3856 | 3856 | ||
| 3857 | if (!amd_iommu_irq_remap) | ||
| 3858 | return 0; | ||
| 3859 | |||
| 3857 | if (x86_fwspec_is_ioapic(fwspec)) | 3860 | if (x86_fwspec_is_ioapic(fwspec)) |
| 3858 | devid = get_ioapic_devid(fwspec->param[0]); | 3861 | devid = get_ioapic_devid(fwspec->param[0]); |
| 3859 | else if (x86_fwspec_is_hpet(fwspec)) | 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 | set_bit(qsmmu->bypass_cbndx, smmu->context_map); | 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 | reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, CBAR_TYPE_S1_TRANS_S2_BYPASS); | 201 | reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, CBAR_TYPE_S1_TRANS_S2_BYPASS); |
| 200 | arm_smmu_gr1_write(smmu, ARM_SMMU_GR1_CBAR(qsmmu->bypass_cbndx), reg); | 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 | static const struct of_device_id __maybe_unused qcom_smmu_impl_of_match[] = { | 327 | static const struct of_device_id __maybe_unused qcom_smmu_impl_of_match[] = { |
| 328 | { .compatible = "qcom,msm8998-smmu-v2" }, | ||
| 326 | { .compatible = "qcom,sc7180-smmu-500" }, | 329 | { .compatible = "qcom,sc7180-smmu-500" }, |
| 330 | { .compatible = "qcom,sdm630-smmu-v2" }, | ||
| 327 | { .compatible = "qcom,sdm845-smmu-500" }, | 331 | { .compatible = "qcom,sdm845-smmu-500" }, |
| 328 | { .compatible = "qcom,sm8150-smmu-500" }, | 332 | { .compatible = "qcom,sm8150-smmu-500" }, |
| 329 | { .compatible = "qcom,sm8250-smmu-500" }, | 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 | unsigned int cur_len = 0, max_len = dma_get_max_seg_size(dev); | 863 | unsigned int cur_len = 0, max_len = dma_get_max_seg_size(dev); |
| 864 | int i, count = 0; | 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 | for_each_sg(sg, s, nents, i) { | 866 | for_each_sg(sg, s, nents, i) { |
| 894 | /* Restore this segment's original unaligned fields first */ | 867 | /* Restore this segment's original unaligned fields first */ |
| 895 | unsigned int s_iova_off = sg_dma_address(s); | 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 | int mask = ilog2(__roundup_pow_of_two(npages)); | 1461 | int mask = ilog2(__roundup_pow_of_two(npages)); |
| 1462 | unsigned long align = (1ULL << (VTD_PAGE_SHIFT + mask)); | 1462 | unsigned long align = (1ULL << (VTD_PAGE_SHIFT + mask)); |
| 1463 | 1463 | ||
| 1464 | if (WARN_ON_ONCE(!ALIGN(addr, align))) | 1464 | if (WARN_ON_ONCE(!IS_ALIGNED(addr, align))) |
| 1465 | addr &= ~(align - 1); | 1465 | addr = ALIGN_DOWN(addr, align); |
| 1466 | 1466 | ||
| 1467 | desc.qw0 = QI_EIOTLB_PASID(pasid) | | 1467 | desc.qw0 = QI_EIOTLB_PASID(pasid) | |
| 1468 | QI_EIOTLB_DID(did) | | 1468 | QI_EIOTLB_DID(did) | |
| @@ -38,7 +38,6 @@ · 37 unmodified lines | |||
| 38 | #include <linux/dmi.h> | 38 | #include <linux/dmi.h> |
| 39 | #include <linux/pci-ats.h> | 39 | #include <linux/pci-ats.h> |
| 40 | #include <linux/memblock.h> | 40 | #include <linux/memblock.h> |
| 41 | #include <linux/dma-map-ops.h> | ||
| 42 | #include <linux/dma-direct.h> | 41 | #include <linux/dma-direct.h> |
| 43 | #include <linux/crash_dump.h> | 42 | #include <linux/crash_dump.h> |
| 44 | #include <linux/numa.h> | 43 | #include <linux/numa.h> |
| @@ -719,6 +718,8 @@ static int domain_update_device_node(struct dmar_domain *domain) · 674 unmodified lines | |||
| 719 | return nid; | 718 | return nid; |
| 720 | } | 719 | } |
| 721 | 720 | ||
| 721 | static void domain_update_iotlb(struct dmar_domain *domain); | ||
| 722 | |||
| 722 | /* Some capabilities may be different across iommus */ | 723 | /* Some capabilities may be different across iommus */ |
| 723 | static void domain_update_iommu_cap(struct dmar_domain *domain) | 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 | domain->domain.geometry.aperture_end = __DOMAIN_MAX_ADDR(domain->gaw - 1); | 745 | domain->domain.geometry.aperture_end = __DOMAIN_MAX_ADDR(domain->gaw - 1); |
| 745 | else | 746 | else |
| 746 | domain->domain.geometry.aperture_end = __DOMAIN_MAX_ADDR(domain->gaw); | 747 | domain->domain.geometry.aperture_end = __DOMAIN_MAX_ADDR(domain->gaw); |
| 748 | |||
| 749 | domain_update_iotlb(domain); | ||
| 747 | } | 750 | } |
| 748 | 751 | ||
| 749 | struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus, | 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 | assert_spin_locked(&device_domain_lock); | 1468 | assert_spin_locked(&device_domain_lock); |
| 1466 | 1469 | ||
| 1467 | list_for_each_entry(info, &domain->devices, link) { | 1470 | list_for_each_entry(info, &domain->devices, link) |
| 1468 | struct pci_dev *pdev; | 1471 | if (info->ats_enabled) { |
| 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) { | ||
| 1475 | has_iotlb_device = true; | 1472 | has_iotlb_device = true; |
| 1476 | break; | 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 | domain->has_iotlb_device = has_iotlb_device; | 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 | #endif | 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 | static void iommu_flush_dev_iotlb(struct dmar_domain *domain, | 1580 | static void iommu_flush_dev_iotlb(struct dmar_domain *domain, |
| 1559 | u64 addr, unsigned mask) | 1581 | u64 addr, unsigned mask) |
| 1560 | { | 1582 | { |
| 1561 | u16 sid, qdep; | ||
| 1562 | unsigned long flags; | 1583 | unsigned long flags; |
| 1563 | struct device_domain_info *info; | 1584 | struct device_domain_info *info; |
| 1585 | struct subdev_domain_info *sinfo; | ||
| 1564 | 1586 | ||
| 1565 | if (!domain->has_iotlb_device) | 1587 | if (!domain->has_iotlb_device) |
| 1566 | return; | 1588 | return; |
| 1567 | 1589 | ||
| 1568 | spin_lock_irqsave(&device_domain_lock, flags); | 1590 | spin_lock_irqsave(&device_domain_lock, flags); |
| 1569 | list_for_each_entry(info, &domain->devices, link) { | 1591 | list_for_each_entry(info, &domain->devices, link) |
| 1570 | if (!info->ats_enabled) | 1592 | __iommu_flush_dev_iotlb(info, addr, mask); |
| 1571 | continue; | ||
| 1572 | 1593 | ||
| 1573 | sid = info->bus << 8 | info->devfn; | 1594 | list_for_each_entry(sinfo, &domain->subdevices, link_domain) { |
| 1574 | qdep = info->ats_qdep; | 1595 | info = get_domain_info(sinfo->pdev); |
| 1575 | qi_flush_dev_iotlb(info->iommu, sid, info->pfsid, | 1596 | __iommu_flush_dev_iotlb(info, addr, mask); |
| 1576 | qdep, addr, mask); | ||
| 1577 | } | 1597 | } |
| 1578 | spin_unlock_irqrestore(&device_domain_lock, flags); | 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 | domain->flags |= DOMAIN_FLAG_USE_FIRST_LEVEL; | 1897 | domain->flags |= DOMAIN_FLAG_USE_FIRST_LEVEL; |
| 1878 | domain->has_iotlb_device = false; | 1898 | domain->has_iotlb_device = false; |
| 1879 | INIT_LIST_HEAD(&domain->devices); | 1899 | INIT_LIST_HEAD(&domain->devices); |
| 1900 | INIT_LIST_HEAD(&domain->subdevices); | ||
| 1880 | 1901 | ||
| 1881 | return domain; | 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 | info->iommu = iommu; | 2568 | info->iommu = iommu; |
| 2548 | info->pasid_table = NULL; | 2569 | info->pasid_table = NULL; |
| 2549 | info->auxd_enabled = 0; | 2570 | info->auxd_enabled = 0; |
| 2550 | INIT_LIST_HEAD(&info->auxiliary_domains); | 2571 | INIT_LIST_HEAD(&info->subdevices); |
| 2551 | 2572 | ||
| 2552 | if (dev && dev_is_pci(dev)) { | 2573 | if (dev && dev_is_pci(dev)) { |
| 2553 | struct pci_dev *pdev = to_pci_dev(info->dev); | 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 | domain->type == IOMMU_DOMAIN_UNMANAGED; | 4496 | domain->type == IOMMU_DOMAIN_UNMANAGED; |
| 4476 | } | 4497 | } |
| 4477 | 4498 | ||
| 4478 | static void auxiliary_link_device(struct dmar_domain *domain, | 4499 | static inline struct subdev_domain_info * |
| 4479 | struct device *dev) | 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 | struct device_domain_info *info = get_domain_info(dev); | 4517 | struct device_domain_info *info = get_domain_info(dev); |
| 4518 | struct subdev_domain_info *sinfo = lookup_subdev_info(domain, dev); | ||
| 4482 | 4519 | ||
| 4483 | assert_spin_locked(&device_domain_lock); | 4520 | assert_spin_locked(&device_domain_lock); |
| 4484 | if (WARN_ON(!info)) | 4521 | if (WARN_ON(!info)) |
| 4485 | return; | 4522 | return -EINVAL; |
| 4486 | 4523 | ||
| 4487 | domain->auxd_refcnt++; | 4524 | if (!sinfo) { |
| 4488 | list_add(&domain->auxd, &info->auxiliary_domains); | 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, | 4535 | static int auxiliary_unlink_device(struct dmar_domain *domain, |
| 4492 | struct device *dev) | 4536 | struct device *dev) |
| 4493 | { | 4537 | { |
| 4494 | struct device_domain_info *info = get_domain_info(dev); | 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 | assert_spin_locked(&device_domain_lock); | 4542 | assert_spin_locked(&device_domain_lock); |
| 4497 | if (WARN_ON(!info)) | 4543 | if (WARN_ON(!info || !sinfo || sinfo->users <= 0)) |
| 4498 | return; | 4544 | return -EINVAL; |
| 4499 | 4545 | ||
| 4500 | list_del(&domain->auxd); | 4546 | ret = --sinfo->users; |
| 4501 | domain->auxd_refcnt--; | 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) | 4553 | return ret; |
| 4504 | ioasid_put(domain->default_pasid); | ||
| 4505 | } | 4554 | } |
| 4506 | 4555 | ||
| 4507 | static int aux_domain_add_dev(struct dmar_domain *domain, | 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 | spin_lock_irqsave(&device_domain_lock, flags); | 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 | * iommu->lock must be held to attach domain to iommu and setup the | 4596 | * iommu->lock must be held to attach domain to iommu and setup the |
| 4535 | * pasid entry for second level translation. | 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 | domain->default_pasid); | 4610 | domain->default_pasid); |
| 4549 | if (ret) | 4611 | if (ret) |
| 4550 | goto table_failed; | 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 | spin_unlock_irqrestore(&device_domain_lock, flags); | 4616 | spin_unlock_irqrestore(&device_domain_lock, flags); |
| 4556 | 4617 | ||
| 4557 | return 0; | 4618 | return 0; |
| @@ -4560,8 +4621,10 @@ table_failed: · 2 unmodified lines | |||
| 4560 | domain_detach_iommu(domain, iommu); | 4621 | domain_detach_iommu(domain, iommu); |
| 4561 | attach_failed: | 4622 | attach_failed: |
| 4562 | spin_unlock(&iommu->lock); | 4623 | spin_unlock(&iommu->lock); |
| 4624 | auxiliary_unlink_device(domain, dev); | ||
| 4625 | link_failed: | ||
| 4563 | spin_unlock_irqrestore(&device_domain_lock, flags); | 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 | ioasid_put(domain->default_pasid); | 4628 | ioasid_put(domain->default_pasid); |
| 4566 | 4629 | ||
| 4567 | return ret; | 4630 | return ret; |
| @@ -4581,14 +4644,18 @@ static void aux_domain_remove_dev(struct dmar_domain *domain, · 13 unmodified lines | |||
| 4581 | info = get_domain_info(dev); | 4644 | info = get_domain_info(dev); |
| 4582 | iommu = info->iommu; | 4645 | iommu = info->iommu; |
| 4583 | 4646 | ||
| 4584 | auxiliary_unlink_device(domain, dev); | 4647 | if (!auxiliary_unlink_device(domain, dev)) { |
| 4585 | 4648 | spin_lock(&iommu->lock); | |
| 4586 | spin_lock(&iommu->lock); | 4649 | intel_pasid_tear_down_entry(iommu, dev, |
| 4587 | intel_pasid_tear_down_entry(iommu, dev, domain->default_pasid, false); | 4650 | domain->default_pasid, false); |
| 4588 | domain_detach_iommu(domain, iommu); | 4651 | domain_detach_iommu(domain, iommu); |
| 4589 | spin_unlock(&iommu->lock); | 4652 | spin_unlock(&iommu->lock); |
| 4653 | } | ||
| 4590 | 4654 | ||
| 4591 | spin_unlock_irqrestore(&device_domain_lock, flags); | 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 | static int prepare_domain_attach_device(struct iommu_domain *domain, | 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 | irq_data = irq_domain_get_irq_data(domain, virq + i); | 1353 | irq_data = irq_domain_get_irq_data(domain, virq + i); |
| 1354 | irq_cfg = irqd_cfg(irq_data); | 1354 | irq_cfg = irqd_cfg(irq_data); |
| 1355 | if (!irq_data || !irq_cfg) { | 1355 | if (!irq_data || !irq_cfg) { |
| 1356 | if (!i) | ||
| 1357 | kfree(data); | ||
| 1356 | ret = -EINVAL; | 1358 | ret = -EINVAL; |
| 1357 | goto out_free_data; | 1359 | goto out_free_data; |
| 1358 | } | 1360 | } |
| @@ -118,8 +118,10 @@ void intel_svm_check(struct intel_iommu *iommu) · 117 unmodified lines | |||
| 118 | iommu->flags |= VTD_FLAG_SVM_CAPABLE; | 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, | 121 | static void __flush_svm_range_dev(struct intel_svm *svm, |
| 122 | unsigned long address, unsigned long pages, int ih) | 122 | struct intel_svm_dev *sdev, |
| 123 | unsigned long address, | ||
| 124 | unsigned long pages, int ih) | ||
| 123 | { | 125 | { |
| 124 | struct qi_desc desc; | 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 | desc.qw2 = 0; | 145 | desc.qw2 = 0; |
| 144 | desc.qw3 = 0; | 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 | if (sdev->dev_iotlb) { | 149 | if (sdev->dev_iotlb) { |
| 148 | desc.qw0 = QI_DEV_EIOTLB_PASID(svm->pasid) | | 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 | desc.qw2 = 0; | 169 | desc.qw2 = 0; |
| 168 | desc.qw3 = 0; | 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 | rcu_read_lock(); | 230 | rcu_read_lock(); |
| 213 | list_for_each_entry_rcu(sdev, &svm->devs, list) | 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 | svm->pasid, true); | 233 | svm->pasid, true); |
| 216 | rcu_read_unlock(); | 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 | struct dmar_domain *dmar_domain; | 299 | struct dmar_domain *dmar_domain; |
| 282 | struct device_domain_info *info; | 300 | struct device_domain_info *info; |
| 283 | struct intel_svm *svm = NULL; | 301 | struct intel_svm *svm = NULL; |
| 302 | unsigned long iflags; | ||
| 284 | int ret = 0; | 303 | int ret = 0; |
| 285 | 304 | ||
| 286 | if (WARN_ON(!iommu) || !data) | 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 | sdev->dev = dev; | 383 | sdev->dev = dev; |
| 365 | sdev->sid = PCI_DEVID(info->bus, info->devfn); | 384 | sdev->sid = PCI_DEVID(info->bus, info->devfn); |
| 385 | sdev->iommu = iommu; | ||
| 366 | 386 | ||
| 367 | /* Only count users if device has aux domains */ | 387 | /* Only count users if device has aux domains */ |
| 368 | if (iommu_dev_feature_enabled(dev, IOMMU_DEV_FEAT_AUX)) | 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 | * each bind of a new device even with an existing PASID, we need to | 401 | * each bind of a new device even with an existing PASID, we need to |
| 382 | * call the nested mode setup function here. | 402 | * call the nested mode setup function here. |
| 383 | */ | 403 | */ |
| 384 | spin_lock(&iommu->lock); | 404 | spin_lock_irqsave(&iommu->lock, iflags); |
| 385 | ret = intel_pasid_setup_nested(iommu, dev, | 405 | ret = intel_pasid_setup_nested(iommu, dev, |
| 386 | (pgd_t *)(uintptr_t)data->gpgd, | 406 | (pgd_t *)(uintptr_t)data->gpgd, |
| 387 | data->hpasid, &data->vendor.vtd, dmar_domain, | 407 | data->hpasid, &data->vendor.vtd, dmar_domain, |
| 388 | data->addr_width); | 408 | data->addr_width); |
| 389 | spin_unlock(&iommu->lock); | 409 | spin_unlock_irqrestore(&iommu->lock, iflags); |
| 390 | if (ret) { | 410 | if (ret) { |
| 391 | dev_err_ratelimited(dev, "Failed to set up PASID %llu in nested mode, Err %d\n", | 411 | dev_err_ratelimited(dev, "Failed to set up PASID %llu in nested mode, Err %d\n", |
| 392 | data->hpasid, ret); | 412 | data->hpasid, ret); |
| @@ -486,6 +506,7 @@ intel_svm_bind_mm(struct device *dev, unsigned int flags, · 93 unmodified lines | |||
| 486 | struct device_domain_info *info; | 506 | struct device_domain_info *info; |
| 487 | struct intel_svm_dev *sdev; | 507 | struct intel_svm_dev *sdev; |
| 488 | struct intel_svm *svm = NULL; | 508 | struct intel_svm *svm = NULL; |
| 509 | unsigned long iflags; | ||
| 489 | int pasid_max; | 510 | int pasid_max; |
| 490 | int ret; | 511 | int ret; |
| 491 | 512 | ||
| @@ -546,6 +567,7 @@ intel_svm_bind_mm(struct device *dev, unsigned int flags, · 54 unmodified lines | |||
| 546 | goto out; | 567 | goto out; |
| 547 | } | 568 | } |
| 548 | sdev->dev = dev; | 569 | sdev->dev = dev; |
| 570 | sdev->iommu = iommu; | ||
| 549 | 571 | ||
| 550 | ret = intel_iommu_enable_pasid(iommu, dev); | 572 | ret = intel_iommu_enable_pasid(iommu, dev); |
| 551 | if (ret) { | 573 | if (ret) { |
| @@ -575,7 +597,6 @@ intel_svm_bind_mm(struct device *dev, unsigned int flags, · 23 unmodified lines | |||
| 575 | kfree(sdev); | 597 | kfree(sdev); |
| 576 | goto out; | 598 | goto out; |
| 577 | } | 599 | } |
| 578 | svm->iommu = iommu; | ||
| 579 | 600 | ||
| 580 | if (pasid_max > intel_pasid_max_id) | 601 | if (pasid_max > intel_pasid_max_id) |
| 581 | pasid_max = intel_pasid_max_id; | 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 | ret = intel_pasid_setup_first_level(iommu, dev, | 630 | ret = intel_pasid_setup_first_level(iommu, dev, |
| 610 | mm ? mm->pgd : init_mm.pgd, | 631 | mm ? mm->pgd : init_mm.pgd, |
| 611 | svm->pasid, FLPT_DEFAULT_DID, | 632 | svm->pasid, FLPT_DEFAULT_DID, |
| 612 | (mm ? 0 : PASID_FLAG_SUPERVISOR_MODE) | | 633 | (mm ? 0 : PASID_FLAG_SUPERVISOR_MODE) | |
| 613 | (cpu_feature_enabled(X86_FEATURE_LA57) ? | 634 | (cpu_feature_enabled(X86_FEATURE_LA57) ? |
| 614 | PASID_FLAG_FL5LP : 0)); | 635 | PASID_FLAG_FL5LP : 0)); |
| 615 | spin_unlock(&iommu->lock); | 636 | spin_unlock_irqrestore(&iommu->lock, iflags); |
| 616 | if (ret) { | 637 | if (ret) { |
| 617 | if (mm) | 638 | if (mm) |
| 618 | mmu_notifier_unregister(&svm->notifier, mm); | 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 | * Binding a new device with existing PASID, need to setup | 653 | * Binding a new device with existing PASID, need to setup |
| 633 | * the PASID entry. | 654 | * the PASID entry. |
| 634 | */ | 655 | */ |
| 635 | spin_lock(&iommu->lock); | 656 | spin_lock_irqsave(&iommu->lock, iflags); |
| 636 | ret = intel_pasid_setup_first_level(iommu, dev, | 657 | ret = intel_pasid_setup_first_level(iommu, dev, |
| 637 | mm ? mm->pgd : init_mm.pgd, | 658 | mm ? mm->pgd : init_mm.pgd, |
| 638 | svm->pasid, FLPT_DEFAULT_DID, | 659 | svm->pasid, FLPT_DEFAULT_DID, |
| 639 | (mm ? 0 : PASID_FLAG_SUPERVISOR_MODE) | | 660 | (mm ? 0 : PASID_FLAG_SUPERVISOR_MODE) | |
| 640 | (cpu_feature_enabled(X86_FEATURE_LA57) ? | 661 | (cpu_feature_enabled(X86_FEATURE_LA57) ? |
| 641 | PASID_FLAG_FL5LP : 0)); | 662 | PASID_FLAG_FL5LP : 0)); |
| 642 | spin_unlock(&iommu->lock); | 663 | spin_unlock_irqrestore(&iommu->lock, iflags); |
| 643 | if (ret) { | 664 | if (ret) { |
| 644 | kfree(sdev); | 665 | kfree(sdev); |
| 645 | goto out; | 666 | goto out; |
| @@ -358,7 +358,7 @@ static void private_free_iova(struct iova_domain *iovad, struct iova *iova) · 357 unmodified lines | |||
| 358 | * @iovad: - iova domain in question. | 358 | * @iovad: - iova domain in question. |
| 359 | * @pfn: - page frame number | 359 | * @pfn: - page frame number |
| 360 | * This function finds and returns an iova belonging to the | 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 | struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn) | 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 | EXPORT_SYMBOL_GPL(queue_iova); | 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 | * @iovad: - iova domain in question. | 605 | * @iovad: - iova domain in question. |
| 606 | * All the iova's in that domain are destroyed. | 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 | * copy_reserved_iova - copies the reserved between domains | 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 | * @to: - destination domin where to copy | 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 | * other. | 718 | * other. |
| 719 | */ | 719 | */ |
| 720 | void | 720 | void |
| @@ -13,6 +13,7 @@ if MISDN != n · 12 unmodified lines | |||
| 13 | config MISDN_DSP | 13 | config MISDN_DSP |
| 14 | tristate "Digital Audio Processing of transparent data" | 14 | tristate "Digital Audio Processing of transparent data" |
| 15 | depends on MISDN | 15 | depends on MISDN |
| 16 | select BITREVERSE | ||
| 16 | help | 17 | help |
| 17 | Enable support for digital audio processing capability. | 18 | Enable support for digital audio processing capability. |
| 18 | 19 | ||
| @@ -19,6 +19,7 @@ if NVM · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | config NVM_PBLK | 20 | config NVM_PBLK |
| 21 | tristate "Physical Block Device Open-Channel SSD target" | 21 | tristate "Physical Block Device Open-Channel SSD target" |
| 22 | select CRC32 | ||
| 22 | help | 23 | help |
| 23 | Allows an open-channel SSD to be exposed as a block device to the | 24 | Allows an open-channel SSD to be exposed as a block device to the |
| 24 | host. The target assumes the device exposes raw flash and must be | 25 | host. The target assumes the device exposes raw flash and must be |
| @@ -605,6 +605,7 @@ config DM_INTEGRITY · 604 unmodified lines | |||
| 605 | select BLK_DEV_INTEGRITY | 605 | select BLK_DEV_INTEGRITY |
| 606 | select DM_BUFIO | 606 | select DM_BUFIO |
| 607 | select CRYPTO | 607 | select CRYPTO |
| 608 | select CRYPTO_SKCIPHER | ||
| 608 | select ASYNC_XOR | 609 | select ASYNC_XOR |
| 609 | help | 610 | help |
| 610 | This device-mapper target emulates a block device that has | 611 | This device-mapper target emulates a block device that has |
| @@ -622,6 +623,7 @@ config DM_ZONED · 11 unmodified lines | |||
| 622 | tristate "Drive-managed zoned block device target support" | 623 | tristate "Drive-managed zoned block device target support" |
| 623 | depends on BLK_DEV_DM | 624 | depends on BLK_DEV_DM |
| 624 | depends on BLK_DEV_ZONED | 625 | depends on BLK_DEV_ZONED |
| 626 | select CRC32 | ||
| 625 | help | 627 | help |
| 626 | This device-mapper target takes a host-managed or host-aware zoned | 628 | This device-mapper target takes a host-managed or host-aware zoned |
| 627 | block device and exposes most of its capacity as a regular block | 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 | static struct feature feature_list[] = { | 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 | "large_bucket"}, | 21 | "large_bucket"}, |
| 22 | {0, 0, 0 }, | 22 | {0, 0, 0 }, |
| 23 | }; | 23 | }; |
| @@ -13,11 +13,15 @@ · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | /* Feature set definition */ | 14 | /* Feature set definition */ |
| 15 | /* Incompat feature set */ | 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 | 21 | #define BCH_FEATURE_COMPAT_SUPP 0 |
| 19 | #define BCH_FEATURE_RO_COMPAT_SUUP 0 | 22 | #define BCH_FEATURE_RO_COMPAT_SUPP 0 |
| 20 | #define BCH_FEATURE_INCOMPAT_SUUP BCH_FEATURE_INCOMPAT_LARGE_BUCKET | 23 | #define BCH_FEATURE_INCOMPAT_SUPP (BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET| \ |
| 24 | BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE) | ||
| 21 | 25 | ||
| 22 | #define BCH_HAS_COMPAT_FEATURE(sb, mask) \ | 26 | #define BCH_HAS_COMPAT_FEATURE(sb, mask) \ |
| 23 | ((sb)->feature_compat & (mask)) | 27 | ((sb)->feature_compat & (mask)) |
| @@ -77,7 +81,23 @@ static inline void bch_clear_feature_##name(struct cache_sb *sb) \ · 53 unmodified lines | |||
| 77 | ~BCH##_FEATURE_INCOMPAT_##flagname; \ | 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 | int bch_print_cache_set_feature_compat(struct cache_set *c, char *buf, int size); | 102 | int bch_print_cache_set_feature_compat(struct cache_set *c, char *buf, int size); |
| 83 | int bch_print_cache_set_feature_ro_compat(struct cache_set *c, char *buf, int size); | 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 | unsigned int bucket_size = le16_to_cpu(s->bucket_size); | 65 | unsigned int bucket_size = le16_to_cpu(s->bucket_size); |
| 66 | 66 | ||
| 67 | if (sb->version >= BCACHE_SB_VERSION_CDEV_WITH_FEATURES && | 67 | if (sb->version >= BCACHE_SB_VERSION_CDEV_WITH_FEATURES) { |
| 68 | bch_has_feature_large_bucket(sb)) | 68 | if (bch_has_feature_large_bucket(sb)) { |
| 69 | bucket_size |= le16_to_cpu(s->bucket_size_hi) << 16; | 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 | return bucket_size; | 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 | sb->feature_compat = le64_to_cpu(s->feature_compat); | 244 | sb->feature_compat = le64_to_cpu(s->feature_compat); |
| 229 | sb->feature_incompat = le64_to_cpu(s->feature_incompat); | 245 | sb->feature_incompat = le64_to_cpu(s->feature_incompat); |
| 230 | sb->feature_ro_compat = le64_to_cpu(s->feature_ro_compat); | 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 | err = read_super_common(sb, bdev, s); | 261 | err = read_super_common(sb, bdev, s); |
| 232 | if (err) | 262 | if (err) |
| 233 | goto err; | 263 | goto err; |
| @@ -1302,6 +1332,12 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c, · 1068 unmodified lines | |||
| 1302 | bcache_device_link(&dc->disk, c, "bdev"); | 1332 | bcache_device_link(&dc->disk, c, "bdev"); |
| 1303 | atomic_inc(&c->attached_dev_nr); | 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 | /* Allow the writeback thread to proceed */ | 1341 | /* Allow the writeback thread to proceed */ |
| 1306 | up_write(&dc->writeback_lock); | 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 | bcache_device_link(d, c, "volume"); | 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 | return 0; | 1569 | return 0; |
| 1528 | err: | 1570 | err: |
| 1529 | kobject_put(&d->kobj); | 1571 | kobject_put(&d->kobj); |
| @@ -2083,6 +2125,9 @@ static int run_cache_set(struct cache_set *c) · 553 unmodified lines | |||
| 2083 | c->cache->sb.last_mount = (u32)ktime_get_real_seconds(); | 2125 | c->cache->sb.last_mount = (u32)ktime_get_real_seconds(); |
| 2084 | bcache_write_super(c); | 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 | list_for_each_entry_safe(dc, t, &uncached_devices, list) | 2131 | list_for_each_entry_safe(dc, t, &uncached_devices, list) |
| 2087 | bch_cached_dev_attach(dc, c, NULL); | 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 | list_for_each_entry_safe(pdev, tpdev, &pending_devs, list) { | 2691 | list_for_each_entry_safe(pdev, tpdev, &pending_devs, list) { |
| 2692 | char *pdev_set_uuid = pdev->dc->sb.set_uuid; | ||
| 2647 | list_for_each_entry_safe(c, tc, &bch_cache_sets, list) { | 2693 | list_for_each_entry_safe(c, tc, &bch_cache_sets, list) { |
| 2648 | char *pdev_set_uuid = pdev->dc->sb.set_uuid; | ||
| 2649 | char *set_uuid = c->set_uuid; | 2694 | char *set_uuid = c->set_uuid; |
| 2650 | 2695 | ||
| 2651 | if (!memcmp(pdev_set_uuid, set_uuid, 16)) { | 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 | EXPORT_SYMBOL_GPL(dm_bufio_get_device_size); | 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 | sector_t dm_bufio_get_block_number(struct dm_buffer *b) | 1543 | sector_t dm_bufio_get_block_number(struct dm_buffer *b) |
| 1538 | { | 1544 | { |
| 1539 | return b->block; | 1545 | return b->block; |
| @@ -1454,13 +1454,16 @@ static int crypt_convert_block_skcipher(struct crypt_config *cc, · 1453 unmodified lines | |||
| 1454 | static void kcryptd_async_done(struct crypto_async_request *async_req, | 1454 | static void kcryptd_async_done(struct crypto_async_request *async_req, |
| 1455 | int error); | 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 | struct convert_context *ctx) | 1458 | struct convert_context *ctx) |
| 1459 | { | 1459 | { |
| 1460 | unsigned key_index = ctx->cc_sector & (cc->tfms_count - 1); | 1460 | unsigned key_index = ctx->cc_sector & (cc->tfms_count - 1); |
| 1461 | 1461 | ||
| 1462 | if (!ctx->r.req) | 1462 | if (!ctx->r.req) { |
| 1463 | ctx->r.req = mempool_alloc(&cc->req_pool, GFP_NOIO); | 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 | skcipher_request_set_tfm(ctx->r.req, cc->cipher_tfm.tfms[key_index]); | 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 | skcipher_request_set_callback(ctx->r.req, | 1474 | skcipher_request_set_callback(ctx->r.req, |
| 1472 | CRYPTO_TFM_REQ_MAY_BACKLOG, | 1475 | CRYPTO_TFM_REQ_MAY_BACKLOG, |
| 1473 | kcryptd_async_done, dmreq_of_req(cc, ctx->r.req)); | 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 | struct convert_context *ctx) | 1482 | struct convert_context *ctx) |
| 1478 | { | 1483 | { |
| 1479 | if (!ctx->r.req_aead) | 1484 | if (!ctx->r.req) { |
| 1480 | ctx->r.req_aead = mempool_alloc(&cc->req_pool, GFP_NOIO); | 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 | aead_request_set_tfm(ctx->r.req_aead, cc->cipher_tfm.tfms_aead[0]); | 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 | aead_request_set_callback(ctx->r.req_aead, | 1496 | aead_request_set_callback(ctx->r.req_aead, |
| 1489 | CRYPTO_TFM_REQ_MAY_BACKLOG, | 1497 | CRYPTO_TFM_REQ_MAY_BACKLOG, |
| 1490 | kcryptd_async_done, dmreq_of_req(cc, ctx->r.req_aead)); | 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 | struct convert_context *ctx) | 1504 | struct convert_context *ctx) |
| 1495 | { | 1505 | { |
| 1496 | if (crypt_integrity_aead(cc)) | 1506 | if (crypt_integrity_aead(cc)) |
| 1497 | crypt_alloc_req_aead(cc, ctx); | 1507 | return crypt_alloc_req_aead(cc, ctx); |
| 1498 | else | 1508 | else |
| 1499 | crypt_alloc_req_skcipher(cc, ctx); | 1509 | return crypt_alloc_req_skcipher(cc, ctx); |
| 1500 | } | 1510 | } |
| 1501 | 1511 | ||
| 1502 | static void crypt_free_req_skcipher(struct crypt_config *cc, | 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 | * Encrypt / decrypt data from one bio to another one (can be the same one) | 1539 | * Encrypt / decrypt data from one bio to another one (can be the same one) |
| 1530 | */ | 1540 | */ |
| 1531 | static blk_status_t crypt_convert(struct crypt_config *cc, | 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 | unsigned int tag_offset = 0; | 1544 | unsigned int tag_offset = 0; |
| 1535 | unsigned int sector_step = cc->sector_size >> SECTOR_SHIFT; | 1545 | unsigned int sector_step = cc->sector_size >> SECTOR_SHIFT; |
| 1536 | int r; | 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 | while (ctx->iter_in.bi_size && ctx->iter_out.bi_size) { | 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 | atomic_inc(&ctx->cc_pending); | 1564 | atomic_inc(&ctx->cc_pending); |
| 1544 | 1565 | ||
| 1545 | if (crypt_integrity_aead(cc)) | 1566 | if (crypt_integrity_aead(cc)) |
| @@ -1553,7 +1574,25 @@ static blk_status_t crypt_convert(struct crypt_config *cc, · 7 unmodified lines | |||
| 1553 | * but the driver request queue is full, let's wait. | 1574 | * but the driver request queue is full, let's wait. |
| 1554 | */ | 1575 | */ |
| 1555 | case -EBUSY: | 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 | reinit_completion(&ctx->restart); | 1596 | reinit_completion(&ctx->restart); |
| 1558 | fallthrough; | 1597 | fallthrough; |
| 1559 | /* | 1598 | /* |
| @@ -1691,6 +1730,12 @@ static void crypt_inc_pending(struct dm_crypt_io *io) · 131 unmodified lines | |||
| 1691 | atomic_inc(&io->io_pending); | 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 | * One of the bios was finished. Check for completion of | 1740 | * One of the bios was finished. Check for completion of |
| 1696 | * the whole request and correctly clean up the buffer. | 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 | kfree(io->integrity_metadata); | 1758 | kfree(io->integrity_metadata); |
| 1714 | 1759 | ||
| 1715 | base_bio->bi_status = error; | 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 | static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) | 2040 | static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) |
| 1949 | { | 2041 | { |
| 1950 | struct crypt_config *cc = io->cc; | 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 | crypt_inc_pending(io); | 2066 | crypt_inc_pending(io); |
| 1975 | r = crypt_convert(cc, ctx, | 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 | if (r) | 2079 | if (r) |
| 1978 | io->error = r; | 2080 | io->error = r; |
| 1979 | crypt_finished = atomic_dec_and_test(&ctx->cc_pending); | 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 | crypt_dec_pending(io); | 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 | static void kcryptd_crypt_read_convert(struct dm_crypt_io *io) | 2122 | static void kcryptd_crypt_read_convert(struct dm_crypt_io *io) |
| 2002 | { | 2123 | { |
| 2003 | struct crypt_config *cc = io->cc; | 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 | io->sector); | 2130 | io->sector); |
| 2010 | 2131 | ||
| 2011 | r = crypt_convert(cc, &io->ctx, | 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 | if (r) | 2143 | if (r) |
| 2014 | io->error = r; | 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 | if ((bio_data_dir(io->base_bio) == READ && test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags)) || | 2222 | if ((bio_data_dir(io->base_bio) == READ && test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags)) || |
| 2093 | (bio_data_dir(io->base_bio) == WRITE && test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags))) { | 2223 | (bio_data_dir(io->base_bio) == WRITE && test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags))) { |
| 2094 | if (in_irq()) { | 2224 | /* |
| 2095 | /* Crypto API's "skcipher_walk_first() refuses to work in hard IRQ context */ | 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 | tasklet_init(&io->tasklet, kcryptd_crypt_tasklet, (unsigned long)&io->work); | 2230 | tasklet_init(&io->tasklet, kcryptd_crypt_tasklet, (unsigned long)&io->work); |
| 2097 | tasklet_schedule(&io->tasklet); | 2231 | tasklet_schedule(&io->tasklet); |
| 2098 | return; | 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 | if (test_bit(DM_CRYPT_SAME_CPU, &cc->flags)) | 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 | 1, devname); | 3304 | 1, devname); |
| 3171 | else | 3305 | else |
| 3172 | cc->crypt_queue = alloc_workqueue("kcryptd-%s", | 3306 | cc->crypt_queue = alloc_workqueue("kcryptd/%s", |
| 3173 | WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM | | 3307 | WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM | WQ_UNBOUND, |
| 3174 | WQ_UNBOUND | WQ_SYSFS, | ||
| 3175 | num_online_cpus(), devname); | 3308 | num_online_cpus(), devname); |
| 3176 | if (!cc->crypt_queue) { | 3309 | if (!cc->crypt_queue) { |
| 3177 | ti->error = "Couldn't create kcryptd queue"; | 3310 | ti->error = "Couldn't create kcryptd queue"; |
| @@ -1379,12 +1379,52 @@ thorough_test: · 1378 unmodified lines | |||
| 1379 | #undef MAY_BE_HASH | 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 | int r; | 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 | r = dm_bufio_write_dirty_buffers(ic->bufio); | 1422 | r = dm_bufio_write_dirty_buffers(ic->bufio); |
| 1386 | if (unlikely(r)) | 1423 | if (unlikely(r)) |
| 1387 | dm_integrity_io_error(ic, "writing tags", r); | 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 | static void sleep_on_endio_wait(struct dm_integrity_c *ic) | 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 | if (unlikely(dio->op == REQ_OP_DISCARD) && likely(ic->mode != 'D')) { | 2151 | if (unlikely(dio->op == REQ_OP_DISCARD) && likely(ic->mode != 'D')) { |
| 2112 | integrity_metadata(&dio->work); | 2152 | integrity_metadata(&dio->work); |
| 2113 | dm_integrity_flush_buffers(ic); | 2153 | dm_integrity_flush_buffers(ic, false); |
| 2114 | 2154 | ||
| 2115 | dio->in_flight = (atomic_t)ATOMIC_INIT(1); | 2155 | dio->in_flight = (atomic_t)ATOMIC_INIT(1); |
| 2116 | dio->completion = NULL; | 2156 | dio->completion = NULL; |
| @@ -2195,7 +2235,7 @@ static void integrity_commit(struct work_struct *w) · 78 unmodified lines | |||
| 2195 | flushes = bio_list_get(&ic->flush_bio_list); | 2235 | flushes = bio_list_get(&ic->flush_bio_list); |
| 2196 | if (unlikely(ic->mode != 'J')) { | 2236 | if (unlikely(ic->mode != 'J')) { |
| 2197 | spin_unlock_irq(&ic->endio_wait.lock); | 2237 | spin_unlock_irq(&ic->endio_wait.lock); |
| 2198 | dm_integrity_flush_buffers(ic); | 2238 | dm_integrity_flush_buffers(ic, true); |
| 2199 | goto release_flush_bios; | 2239 | goto release_flush_bios; |
| 2200 | } | 2240 | } |
| 2201 | 2241 | ||
| @@ -2409,7 +2449,7 @@ skip_io: · 207 unmodified lines | |||
| 2409 | complete_journal_op(&comp); | 2449 | complete_journal_op(&comp); |
| 2410 | wait_for_completion_io(&comp.comp); | 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 | static void integrity_writer(struct work_struct *w) | 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 | int r; | 2492 | int r; |
| 2453 | 2493 | ||
| 2454 | dm_integrity_flush_buffers(ic); | 2494 | dm_integrity_flush_buffers(ic, false); |
| 2455 | if (dm_integrity_failed(ic)) | 2495 | if (dm_integrity_failed(ic)) |
| 2456 | return; | 2496 | return; |
| 2457 | 2497 | ||
| @@ -2654,7 +2694,7 @@ static void bitmap_flush_work(struct work_struct *work) · 196 unmodified lines | |||
| 2654 | unsigned long limit; | 2694 | unsigned long limit; |
| 2655 | struct bio *bio; | 2695 | struct bio *bio; |
| 2656 | 2696 | ||
| 2657 | dm_integrity_flush_buffers(ic); | 2697 | dm_integrity_flush_buffers(ic, false); |
| 2658 | 2698 | ||
| 2659 | range.logical_sector = 0; | 2699 | range.logical_sector = 0; |
| 2660 | range.n_sectors = ic->provided_data_sectors; | 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 | add_new_range_and_wait(ic, &range); | 2703 | add_new_range_and_wait(ic, &range); |
| 2664 | spin_unlock_irq(&ic->endio_wait.lock); | 2704 | spin_unlock_irq(&ic->endio_wait.lock); |
| 2665 | 2705 | ||
| 2666 | dm_integrity_flush_buffers(ic); | 2706 | dm_integrity_flush_buffers(ic, true); |
| 2667 | if (ic->meta_dev) | ||
| 2668 | blkdev_issue_flush(ic->dev->bdev, GFP_NOIO); | ||
| 2669 | 2707 | ||
| 2670 | limit = ic->provided_data_sectors; | 2708 | limit = ic->provided_data_sectors; |
| 2671 | if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)) { | 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 | if (ic->meta_dev) | 2972 | if (ic->meta_dev) |
| 2935 | queue_work(ic->writer_wq, &ic->writer_work); | 2973 | queue_work(ic->writer_wq, &ic->writer_work); |
| 2936 | drain_workqueue(ic->writer_wq); | 2974 | drain_workqueue(ic->writer_wq); |
| 2937 | dm_integrity_flush_buffers(ic); | 2975 | dm_integrity_flush_buffers(ic, true); |
| 2938 | } | 2976 | } |
| 2939 | 2977 | ||
| 2940 | if (ic->mode == 'B') { | 2978 | if (ic->mode == 'B') { |
| 2941 | dm_integrity_flush_buffers(ic); | 2979 | dm_integrity_flush_buffers(ic, true); |
| 2942 | #if 1 | 2980 | #if 1 |
| 2943 | /* set to 0 to test bitmap replay code */ | 2981 | /* set to 0 to test bitmap replay code */ |
| 2944 | init_journal(ic, 0, ic->journal_sections, 0); | 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 | unsigned extra_args; | 3792 | unsigned extra_args; |
| 3755 | struct dm_arg_set as; | 3793 | struct dm_arg_set as; |
| 3756 | static const struct dm_arg _args[] = { | 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 | unsigned journal_sectors, interleave_sectors, buffer_sectors, journal_watermark, sync_msec; | 3797 | unsigned journal_sectors, interleave_sectors, buffer_sectors, journal_watermark, sync_msec; |
| 3760 | bool should_write_sb; | 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 | blk_limits_io_opt(limits, chunk_size_bytes * mddev_data_stripes(rs)); | 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, | 3732 | * RAID0 and RAID10 personalities require bio splitting, |
| 3733 | * RAID0/4/5/6 don't and process large discard bios properly. | 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 | limits->discard_granularity = chunk_size_bytes; | 3736 | limits->discard_granularity = chunk_size_bytes; |
| 3737 | limits->max_discard_sectors = rs->md.chunk_sectors; | 3737 | limits->max_discard_sectors = rs->md.chunk_sectors; |
| 3738 | } | 3738 | } |
| @@ -141,6 +141,11 @@ struct dm_snapshot { · 140 unmodified lines | |||
| 141 | * for them to be committed. | 141 | * for them to be committed. |
| 142 | */ | 142 | */ |
| 143 | struct bio_list bios_queued_during_merge; | 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 | static void error_bios(struct bio *bio); | 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 | static void merge_callback(int read_err, unsigned long write_err, void *context) | 1140 | static void merge_callback(int read_err, unsigned long write_err, void *context) |
| 1125 | { | 1141 | { |
| 1126 | struct dm_snapshot *s = context; | 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 | goto shut; | 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 | if (s->store->type->commit_merge(s->store, | 1158 | if (s->store->type->commit_merge(s->store, |
| 1138 | s->num_merging_chunks) < 0) { | 1159 | s->num_merging_chunks) < 0) { |
| 1139 | DMERR("Write error in exception store: shutting down merge"); | 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 | s->first_merging_chunk = 0; | 1339 | s->first_merging_chunk = 0; |
| 1319 | s->num_merging_chunks = 0; | 1340 | s->num_merging_chunks = 0; |
| 1320 | bio_list_init(&s->bios_queued_during_merge); | 1341 | bio_list_init(&s->bios_queued_during_merge); |
| 1342 | bio_init(&s->flush_bio, NULL, 0); | ||
| 1321 | 1343 | ||
| 1322 | /* Allocate hash table for COW data */ | 1344 | /* Allocate hash table for COW data */ |
| 1323 | if (init_hash_tables(s)) { | 1345 | if (init_hash_tables(s)) { |
| @@ -1504,6 +1526,8 @@ static void snapshot_dtr(struct dm_target *ti) · 180 unmodified lines | |||
| 1504 | 1526 | ||
| 1505 | dm_exception_store_destroy(s->store); | 1527 | dm_exception_store_destroy(s->store); |
| 1506 | 1528 | ||
| 1529 | bio_uninit(&s->flush_bio); | ||
| 1530 | |||
| 1507 | dm_put_device(ti, s->cow); | 1531 | dm_put_device(ti, s->cow); |
| 1508 | 1532 | ||
| 1509 | dm_put_device(ti, s->origin); | 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 | * subset of the parent bdev; require extra privileges. | 562 | * subset of the parent bdev; require extra privileges. |
| 563 | */ | 563 | */ |
| 564 | if (!capable(CAP_SYS_RAWIO)) { | 564 | if (!capable(CAP_SYS_RAWIO)) { |
| 565 | DMWARN_LIMIT( | 565 | DMDEBUG_LIMIT( |
| 566 | "%s: sending ioctl %x to DM device without required privilege.", | 566 | "%s: sending ioctl %x to DM device without required privilege.", |
| 567 | current->comm, cmd); | 567 | current->comm, cmd); |
| 568 | r = -ENOIOCTLCMD; | 568 | r = -ENOIOCTLCMD; |
| @@ -472,8 +472,11 @@ static int allocate_cs(struct hl_device *hdev, struct hl_ctx *ctx, · 471 unmodified lines | |||
| 472 | cntr = &hdev->aggregated_cs_counters; | 472 | cntr = &hdev->aggregated_cs_counters; |
| 473 | 473 | ||
| 474 | cs = kzalloc(sizeof(*cs), GFP_ATOMIC); | 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 | return -ENOMEM; | 478 | return -ENOMEM; |
| 479 | } | ||
| 477 | 480 | ||
| 478 | cs->ctx = ctx; | 481 | cs->ctx = ctx; |
| 479 | cs->submitted = false; | 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 | cs_cmpl = kmalloc(sizeof(*cs_cmpl), GFP_ATOMIC); | 490 | cs_cmpl = kmalloc(sizeof(*cs_cmpl), GFP_ATOMIC); |
| 488 | if (!cs_cmpl) { | 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 | rc = -ENOMEM; | 494 | rc = -ENOMEM; |
| 490 | goto free_cs; | 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 | cs->jobs_in_queue_cnt = kcalloc(hdev->asic_prop.max_queues, | 518 | cs->jobs_in_queue_cnt = kcalloc(hdev->asic_prop.max_queues, |
| 514 | sizeof(*cs->jobs_in_queue_cnt), GFP_ATOMIC); | 519 | sizeof(*cs->jobs_in_queue_cnt), GFP_ATOMIC); |
| 515 | if (!cs->jobs_in_queue_cnt) { | 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 | rc = -ENOMEM; | 523 | rc = -ENOMEM; |
| 517 | goto free_fence; | 524 | goto free_fence; |
| 518 | } | 525 | } |
| @@ -562,7 +569,7 @@ void hl_cs_rollback_all(struct hl_device *hdev) · 43 unmodified lines | |||
| 562 | for (i = 0 ; i < hdev->asic_prop.completion_queues_count ; i++) | 569 | for (i = 0 ; i < hdev->asic_prop.completion_queues_count ; i++) |
| 563 | flush_workqueue(hdev->cq_wq[i]); | 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 | list_for_each_entry_safe(cs, tmp, &hdev->cs_mirror_list, mirror_node) { | 573 | list_for_each_entry_safe(cs, tmp, &hdev->cs_mirror_list, mirror_node) { |
| 567 | cs_get(cs); | 574 | cs_get(cs); |
| 568 | cs->aborted = true; | 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 | static int hl_cs_copy_chunk_array(struct hl_device *hdev, | 772 | static int hl_cs_copy_chunk_array(struct hl_device *hdev, |
| 766 | struct hl_cs_chunk **cs_chunk_array, | 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 | u32 size_to_copy; | 777 | u32 size_to_copy; |
| 770 | 778 | ||
| 771 | if (num_chunks > HL_MAX_JOBS_PER_CS) { | 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 | dev_err(hdev->dev, | 782 | dev_err(hdev->dev, |
| 773 | "Number of chunks can NOT be larger than %d\n", | 783 | "Number of chunks can NOT be larger than %d\n", |
| 774 | HL_MAX_JOBS_PER_CS); | 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 | *cs_chunk_array = kmalloc_array(num_chunks, sizeof(**cs_chunk_array), | 788 | *cs_chunk_array = kmalloc_array(num_chunks, sizeof(**cs_chunk_array), |
| 779 | GFP_ATOMIC); | 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 | return -ENOMEM; | 793 | return -ENOMEM; |
| 794 | } | ||
| 782 | 795 | ||
| 783 | size_to_copy = num_chunks * sizeof(struct hl_cs_chunk); | 796 | size_to_copy = num_chunks * sizeof(struct hl_cs_chunk); |
| 784 | if (copy_from_user(*cs_chunk_array, chunks, size_to_copy)) { | 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 | dev_err(hdev->dev, "Failed to copy cs chunk array from user\n"); | 800 | dev_err(hdev->dev, "Failed to copy cs chunk array from user\n"); |
| 786 | kfree(*cs_chunk_array); | 801 | kfree(*cs_chunk_array); |
| 787 | return -EFAULT; | 802 | return -EFAULT; |
| @@ -797,6 +812,7 @@ static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks, · 9 unmodified lines | |||
| 797 | struct hl_device *hdev = hpriv->hdev; | 812 | struct hl_device *hdev = hpriv->hdev; |
| 798 | struct hl_cs_chunk *cs_chunk_array; | 813 | struct hl_cs_chunk *cs_chunk_array; |
| 799 | struct hl_cs_counters_atomic *cntr; | 814 | struct hl_cs_counters_atomic *cntr; |
| 815 | struct hl_ctx *ctx = hpriv->ctx; | ||
| 800 | struct hl_cs_job *job; | 816 | struct hl_cs_job *job; |
| 801 | struct hl_cs *cs; | 817 | struct hl_cs *cs; |
| 802 | struct hl_cb *cb; | 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 | cntr = &hdev->aggregated_cs_counters; | 821 | cntr = &hdev->aggregated_cs_counters; |
| 806 | *cs_seq = ULLONG_MAX; | 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 | if (rc) | 826 | if (rc) |
| 810 | goto out; | 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 | rc = validate_queue_index(hdev, chunk, &queue_type, | 849 | rc = validate_queue_index(hdev, chunk, &queue_type, |
| 833 | &is_kernel_allocated_cb); | 850 | &is_kernel_allocated_cb); |
| 834 | if (rc) { | 851 | if (rc) { |
| 835 | atomic64_inc(&hpriv->ctx->cs_counters.parsing_drop_cnt); | 852 | atomic64_inc(&ctx->cs_counters.validation_drop_cnt); |
| 836 | atomic64_inc(&cntr->parsing_drop_cnt); | 853 | atomic64_inc(&cntr->validation_drop_cnt); |
| 837 | goto free_cs_object; | 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 | cb = get_cb_from_cs_chunk(hdev, &hpriv->cb_mgr, chunk); | 858 | cb = get_cb_from_cs_chunk(hdev, &hpriv->cb_mgr, chunk); |
| 842 | if (!cb) { | 859 | if (!cb) { |
| 843 | atomic64_inc( | 860 | atomic64_inc( |
| 844 | &hpriv->ctx->cs_counters.parsing_drop_cnt); | 861 | &ctx->cs_counters.validation_drop_cnt); |
| 845 | atomic64_inc(&cntr->parsing_drop_cnt); | 862 | atomic64_inc(&cntr->validation_drop_cnt); |
| 846 | rc = -EINVAL; | 863 | rc = -EINVAL; |
| 847 | goto free_cs_object; | 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 | job = hl_cs_allocate_job(hdev, queue_type, | 873 | job = hl_cs_allocate_job(hdev, queue_type, |
| 857 | is_kernel_allocated_cb); | 874 | is_kernel_allocated_cb); |
| 858 | if (!job) { | 875 | if (!job) { |
| 859 | atomic64_inc( | 876 | atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt); |
| 860 | &hpriv->ctx->cs_counters.out_of_mem_drop_cnt); | ||
| 861 | atomic64_inc(&cntr->out_of_mem_drop_cnt); | 877 | atomic64_inc(&cntr->out_of_mem_drop_cnt); |
| 862 | dev_err(hdev->dev, "Failed to allocate a new job\n"); | 878 | dev_err(hdev->dev, "Failed to allocate a new job\n"); |
| 863 | rc = -ENOMEM; | 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 | rc = cs_parser(hpriv, job); | 908 | rc = cs_parser(hpriv, job); |
| 893 | if (rc) { | 909 | if (rc) { |
| 894 | atomic64_inc(&hpriv->ctx->cs_counters.parsing_drop_cnt); | 910 | atomic64_inc(&ctx->cs_counters.parsing_drop_cnt); |
| 895 | atomic64_inc(&cntr->parsing_drop_cnt); | 911 | atomic64_inc(&cntr->parsing_drop_cnt); |
| 896 | dev_err(hdev->dev, | 912 | dev_err(hdev->dev, |
| 897 | "Failed to parse JOB %d.%llu.%d, err %d, rejecting the CS\n", | 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 | if (int_queues_only) { | 919 | if (int_queues_only) { |
| 904 | atomic64_inc(&hpriv->ctx->cs_counters.parsing_drop_cnt); | 920 | atomic64_inc(&ctx->cs_counters.validation_drop_cnt); |
| 905 | atomic64_inc(&cntr->parsing_drop_cnt); | 921 | atomic64_inc(&cntr->validation_drop_cnt); |
| 906 | dev_err(hdev->dev, | 922 | dev_err(hdev->dev, |
| 907 | "Reject CS %d.%llu because only internal queues jobs are present\n", | 923 | "Reject CS %d.%llu because only internal queues jobs are present\n", |
| 908 | cs->ctx->asid, cs->sequence); | 924 | cs->ctx->asid, cs->sequence); |
| @@ -1042,7 +1058,7 @@ out: · 133 unmodified lines | |||
| 1042 | } | 1058 | } |
| 1043 | 1059 | ||
| 1044 | static int cs_ioctl_extract_signal_seq(struct hl_device *hdev, | 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 | u64 *signal_seq_arr = NULL; | 1063 | u64 *signal_seq_arr = NULL; |
| 1048 | u32 size_to_copy, signal_seq_arr_len; | 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 | /* currently only one signal seq is supported */ | 1069 | /* currently only one signal seq is supported */ |
| 1054 | if (signal_seq_arr_len != 1) { | 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 | dev_err(hdev->dev, | 1073 | dev_err(hdev->dev, |
| 1056 | "Wait for signal CS supports only one signal CS seq\n"); | 1074 | "Wait for signal CS supports only one signal CS seq\n"); |
| 1057 | return -EINVAL; | 1075 | return -EINVAL; |
| @@ -1060,13 +1078,18 @@ static int cs_ioctl_extract_signal_seq(struct hl_device *hdev, · 2 unmodified lines | |||
| 1060 | signal_seq_arr = kmalloc_array(signal_seq_arr_len, | 1078 | signal_seq_arr = kmalloc_array(signal_seq_arr_len, |
| 1061 | sizeof(*signal_seq_arr), | 1079 | sizeof(*signal_seq_arr), |
| 1062 | GFP_ATOMIC); | 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 | return -ENOMEM; | 1084 | return -ENOMEM; |
| 1085 | } | ||
| 1065 | 1086 | ||
| 1066 | size_to_copy = chunk->num_signal_seq_arr * sizeof(*signal_seq_arr); | 1087 | size_to_copy = chunk->num_signal_seq_arr * sizeof(*signal_seq_arr); |
| 1067 | if (copy_from_user(signal_seq_arr, | 1088 | if (copy_from_user(signal_seq_arr, |
| 1068 | u64_to_user_ptr(chunk->signal_seq_arr), | 1089 | u64_to_user_ptr(chunk->signal_seq_arr), |
| 1069 | size_to_copy)) { | 1090 | size_to_copy)) { |
| 1091 | atomic64_inc(&ctx->cs_counters.validation_drop_cnt); | ||
| 1092 | atomic64_inc(&hdev->aggregated_cs_counters.validation_drop_cnt); | ||
| 1070 | dev_err(hdev->dev, | 1093 | dev_err(hdev->dev, |
| 1071 | "Failed to copy signal seq array from user\n"); | 1094 | "Failed to copy signal seq array from user\n"); |
| 1072 | rc = -EFAULT; | 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 | struct hl_device *hdev = hpriv->hdev; | 1176 | struct hl_device *hdev = hpriv->hdev; |
| 1154 | struct hl_cs_compl *sig_waitcs_cmpl; | 1177 | struct hl_cs_compl *sig_waitcs_cmpl; |
| 1155 | u32 q_idx, collective_engine_id = 0; | 1178 | u32 q_idx, collective_engine_id = 0; |
| 1179 | struct hl_cs_counters_atomic *cntr; | ||
| 1156 | struct hl_fence *sig_fence = NULL; | 1180 | struct hl_fence *sig_fence = NULL; |
| 1157 | struct hl_ctx *ctx = hpriv->ctx; | 1181 | struct hl_ctx *ctx = hpriv->ctx; |
| 1158 | enum hl_queue_type q_type; | 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 | u64 signal_seq; | 1184 | u64 signal_seq; |
| 1161 | int rc; | 1185 | int rc; |
| 1162 | 1186 | ||
| 1187 | cntr = &hdev->aggregated_cs_counters; | ||
| 1163 | *cs_seq = ULLONG_MAX; | 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 | if (rc) | 1192 | if (rc) |
| 1167 | goto out; | 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 | chunk = &cs_chunk_array[0]; | 1196 | chunk = &cs_chunk_array[0]; |
| 1171 | 1197 | ||
| 1172 | if (chunk->queue_index >= hdev->asic_prop.max_queues) { | 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 | dev_err(hdev->dev, "Queue index %d is invalid\n", | 1201 | dev_err(hdev->dev, "Queue index %d is invalid\n", |
| 1174 | chunk->queue_index); | 1202 | chunk->queue_index); |
| 1175 | rc = -EINVAL; | 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 | q_type = hw_queue_prop->type; | 1209 | q_type = hw_queue_prop->type; |
| 1182 | 1210 | ||
| 1183 | if (!hw_queue_prop->supports_sync_stream) { | 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 | dev_err(hdev->dev, | 1214 | dev_err(hdev->dev, |
| 1185 | "Queue index %d does not support sync stream operations\n", | 1215 | "Queue index %d does not support sync stream operations\n", |
| 1186 | q_idx); | 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 | if (cs_type == CS_TYPE_COLLECTIVE_WAIT) { | 1221 | if (cs_type == CS_TYPE_COLLECTIVE_WAIT) { |
| 1192 | if (!(hw_queue_prop->collective_mode == HL_COLLECTIVE_MASTER)) { | 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 | dev_err(hdev->dev, | 1225 | dev_err(hdev->dev, |
| 1194 | "Queue index %d is invalid\n", q_idx); | 1226 | "Queue index %d is invalid\n", q_idx); |
| 1195 | rc = -EINVAL; | 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 | if (cs_type == CS_TYPE_WAIT || cs_type == CS_TYPE_COLLECTIVE_WAIT) { | 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 | if (rc) | 1236 | if (rc) |
| 1205 | goto free_cs_chunk_array; | 1237 | goto free_cs_chunk_array; |
| 1206 | 1238 | ||
| 1207 | sig_fence = hl_ctx_get_fence(ctx, signal_seq); | 1239 | sig_fence = hl_ctx_get_fence(ctx, signal_seq); |
| 1208 | if (IS_ERR(sig_fence)) { | 1240 | if (IS_ERR(sig_fence)) { |
| 1241 | atomic64_inc(&ctx->cs_counters.validation_drop_cnt); | ||
| 1242 | atomic64_inc(&cntr->validation_drop_cnt); | ||
| 1209 | dev_err(hdev->dev, | 1243 | dev_err(hdev->dev, |
| 1210 | "Failed to get signal CS with seq 0x%llx\n", | 1244 | "Failed to get signal CS with seq 0x%llx\n", |
| 1211 | signal_seq); | 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 | container_of(sig_fence, struct hl_cs_compl, base_fence); | 1257 | container_of(sig_fence, struct hl_cs_compl, base_fence); |
| 1224 | 1258 | ||
| 1225 | if (sig_waitcs_cmpl->type != CS_TYPE_SIGNAL) { | 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 | dev_err(hdev->dev, | 1262 | dev_err(hdev->dev, |
| 1227 | "CS seq 0x%llx is not of a signal CS\n", | 1263 | "CS seq 0x%llx is not of a signal CS\n", |
| 1228 | signal_seq); | 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 | else if (cs_type == CS_TYPE_COLLECTIVE_WAIT) | 1306 | else if (cs_type == CS_TYPE_COLLECTIVE_WAIT) |
| 1271 | rc = hdev->asic_funcs->collective_wait_create_jobs(hdev, ctx, | 1307 | rc = hdev->asic_funcs->collective_wait_create_jobs(hdev, ctx, |
| 1272 | cs, q_idx, collective_engine_id); | 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 | rc = -EINVAL; | 1312 | rc = -EINVAL; |
| 1313 | } | ||
| 1275 | 1314 | ||
| 1276 | if (rc) | 1315 | if (rc) |
| 1277 | goto free_cs_object; | 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 | enum hl_device_status status; | 18 | enum hl_device_status status; |
| 19 | 19 | ||
| 20 | if (hdev->disabled) | 20 | if (atomic_read(&hdev->in_reset)) |
| 21 | status = HL_DEVICE_STATUS_MALFUNCTION; | ||
| 22 | else if (atomic_read(&hdev->in_reset)) | ||
| 23 | status = HL_DEVICE_STATUS_IN_RESET; | 21 | status = HL_DEVICE_STATUS_IN_RESET; |
| 24 | else if (hdev->needs_reset) | 22 | else if (hdev->needs_reset) |
| 25 | status = HL_DEVICE_STATUS_NEEDS_RESET; | 23 | status = HL_DEVICE_STATUS_NEEDS_RESET; |
| 24 | else if (hdev->disabled) | ||
| 25 | status = HL_DEVICE_STATUS_MALFUNCTION; | ||
| 26 | else | 26 | else |
| 27 | status = HL_DEVICE_STATUS_OPERATIONAL; | 27 | status = HL_DEVICE_STATUS_OPERATIONAL; |
| 28 | 28 | ||
| @@ -1092,6 +1092,7 @@ kill_processes: · 1063 unmodified lines | |||
| 1092 | GFP_KERNEL); | 1092 | GFP_KERNEL); |
| 1093 | if (!hdev->kernel_ctx) { | 1093 | if (!hdev->kernel_ctx) { |
| 1094 | rc = -ENOMEM; | 1094 | rc = -ENOMEM; |
| 1095 | hl_mmu_fini(hdev); | ||
| 1095 | goto out_err; | 1096 | goto out_err; |
| 1096 | } | 1097 | } |
| 1097 | 1098 | ||
| @@ -1103,6 +1104,7 @@ kill_processes: · 5 unmodified lines | |||
| 1103 | "failed to init kernel ctx in hard reset\n"); | 1104 | "failed to init kernel ctx in hard reset\n"); |
| 1104 | kfree(hdev->kernel_ctx); | 1105 | kfree(hdev->kernel_ctx); |
| 1105 | hdev->kernel_ctx = NULL; | 1106 | hdev->kernel_ctx = NULL; |
| 1107 | hl_mmu_fini(hdev); | ||
| 1106 | goto out_err; | 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 | security_status = RREG32(cpu_security_boot_status_reg); | 627 | security_status = RREG32(cpu_security_boot_status_reg); |
| 628 | 628 | ||
| 629 | /* We read security status multiple times during boot: | 629 | /* We read security status multiple times during boot: |
| 630 | * 1. preboot - we check if fw security feature is supported | 630 | * 1. preboot - a. Check whether the security status bits are valid |
| 631 | * 2. boot cpu - we get boot cpu security status | 631 | * b. Check whether fw security is enabled |
| 632 | * 3. FW application - we get FW application security status | 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 | * Preboot: | 638 | * Preboot: |
| 635 | * Check security status bit (CPU_BOOT_DEV_STS0_ENABLED), if it is set | 639 | * Check security status bit (CPU_BOOT_DEV_STS0_ENABLED), if it is set |
| 636 | * check security enabled bit (CPU_BOOT_DEV_STS0_SECURITY_EN) | 640 | * check security enabled bit (CPU_BOOT_DEV_STS0_SECURITY_EN) |
| 637 | */ | 641 | */ |
| 638 | if (security_status & CPU_BOOT_DEV_STS0_ENABLED) { | 642 | if (security_status & CPU_BOOT_DEV_STS0_ENABLED) { |
| 639 | hdev->asic_prop.fw_security_status_valid = 1; | 643 | prop->fw_security_status_valid = 1; |
| 640 | prop->fw_security_disabled = | 644 | |
| 641 | !(security_status & CPU_BOOT_DEV_STS0_SECURITY_EN); | 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 | } else { | 652 | } else { |
| 643 | hdev->asic_prop.fw_security_status_valid = 0; | 653 | prop->fw_security_status_valid = 0; |
| 644 | prop->fw_security_disabled = true; | 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 | dev_info(hdev->dev, "firmware-level security is %s\n", | 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 | return 0; | 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 | u32 cpu_security_boot_status_reg, u32 boot_err0_reg, | 668 | u32 cpu_security_boot_status_reg, u32 boot_err0_reg, |
| 656 | bool skip_bmc, u32 cpu_timeout, u32 boot_fit_timeout) | 669 | bool skip_bmc, u32 cpu_timeout, u32 boot_fit_timeout) |
| 657 | { | 670 | { |
| 671 | struct asic_fixed_properties *prop = &hdev->asic_prop; | ||
| 658 | u32 status; | 672 | u32 status; |
| 659 | int rc; | 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 | /* Read U-Boot version now in case we will later fail */ | 737 | /* Read U-Boot version now in case we will later fail */ |
| 724 | hdev->asic_funcs->read_device_fw_version(hdev, FW_COMP_UBOOT); | 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 | /* Read boot_cpu security bits */ | 743 | /* Read boot_cpu security bits */ |
| 727 | if (hdev->asic_prop.fw_security_status_valid) | 744 | if (prop->fw_security_status_valid) { |
| 728 | hdev->asic_prop.fw_boot_cpu_security_map = | 745 | prop->fw_boot_cpu_security_map = |
| 729 | RREG32(cpu_security_boot_status_reg); | 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 | if (rc) { | 756 | if (rc) { |
| 732 | detect_cpu_boot_status(hdev, status); | 757 | detect_cpu_boot_status(hdev, status); |
| 733 | rc = -EIO; | 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 | goto out; | 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 | /* Read FW application security bits */ | 827 | /* Read FW application security bits */ |
| 800 | if (hdev->asic_prop.fw_security_status_valid) { | 828 | if (prop->fw_security_status_valid) { |
| 801 | hdev->asic_prop.fw_app_security_map = | 829 | prop->fw_app_security_map = |
| 802 | RREG32(cpu_security_boot_status_reg); | 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 | CPU_BOOT_DEV_STS0_FW_HARD_RST_EN) | 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", | 837 | dev_dbg(hdev->dev, "Firmware application CPU hard-reset is %s\n", |
| 810 | hdev->asic_prop.hard_reset_done_by_fw ? "enabled" : "disabled"); | 838 | prop->hard_reset_done_by_fw ? "enabled" : "disabled"); |
| 811 | 839 | ||
| 812 | dev_info(hdev->dev, "Successfully loaded firmware to device\n"); | 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 | u32 (*get_signal_cb_size)(struct hl_device *hdev); | 944 | u32 (*get_signal_cb_size)(struct hl_device *hdev); |
| 945 | u32 (*get_wait_cb_size)(struct hl_device *hdev); | 945 | u32 (*get_wait_cb_size)(struct hl_device *hdev); |
| 946 | u32 (*gen_signal_cb)(struct hl_device *hdev, void *data, u16 sob_id, | 946 | u32 (*gen_signal_cb)(struct hl_device *hdev, void *data, u16 sob_id, |
| 947 | u32 size); | 947 | u32 size, bool eb); |
| 948 | u32 (*gen_wait_cb)(struct hl_device *hdev, | 948 | u32 (*gen_wait_cb)(struct hl_device *hdev, |
| 949 | struct hl_gen_wait_properties *prop); | 949 | struct hl_gen_wait_properties *prop); |
| 950 | void (*reset_sob)(struct hl_device *hdev, void *data); | 950 | void (*reset_sob)(struct hl_device *hdev, void *data); |
| @@ -1000,6 +1000,7 @@ struct hl_va_range { · 49 unmodified lines | |||
| 1000 | * @queue_full_drop_cnt: dropped due to queue full | 1000 | * @queue_full_drop_cnt: dropped due to queue full |
| 1001 | * @device_in_reset_drop_cnt: dropped due to device in reset | 1001 | * @device_in_reset_drop_cnt: dropped due to device in reset |
| 1002 | * @max_cs_in_flight_drop_cnt: dropped due to maximum CS in-flight | 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 | struct hl_cs_counters_atomic { | 1005 | struct hl_cs_counters_atomic { |
| 1005 | atomic64_t out_of_mem_drop_cnt; | 1006 | atomic64_t out_of_mem_drop_cnt; |
| @@ -1007,6 +1008,7 @@ struct hl_cs_counters_atomic { · 1 unmodified line | |||
| 1007 | atomic64_t queue_full_drop_cnt; | 1008 | atomic64_t queue_full_drop_cnt; |
| 1008 | atomic64_t device_in_reset_drop_cnt; | 1009 | atomic64_t device_in_reset_drop_cnt; |
| 1009 | atomic64_t max_cs_in_flight_drop_cnt; | 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 | .id_table = ids, | 544 | .id_table = ids, |
| 545 | .probe = hl_pci_probe, | 545 | .probe = hl_pci_probe, |
| 546 | .remove = hl_pci_remove, | 546 | .remove = hl_pci_remove, |
| 547 | .shutdown = hl_pci_remove, | ||
| 547 | .driver.pm = &hl_pm_ops, | 548 | .driver.pm = &hl_pm_ops, |
| 548 | .err_handler = &hl_pci_err_handler, | 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 | atomic64_read(&cntr->device_in_reset_drop_cnt); | 335 | atomic64_read(&cntr->device_in_reset_drop_cnt); |
| 336 | cs_counters.total_max_cs_in_flight_drop_cnt = | 336 | cs_counters.total_max_cs_in_flight_drop_cnt = |
| 337 | atomic64_read(&cntr->max_cs_in_flight_drop_cnt); | 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 | if (hpriv->ctx) { | 341 | if (hpriv->ctx) { |
| 340 | cs_counters.ctx_out_of_mem_drop_cnt = | 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 | cs_counters.ctx_max_cs_in_flight_drop_cnt = | 354 | cs_counters.ctx_max_cs_in_flight_drop_cnt = |
| 353 | atomic64_read( | 355 | atomic64_read( |
| 354 | &hpriv->ctx->cs_counters.max_cs_in_flight_drop_cnt); | 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 | return copy_to_user(out, &cs_counters, | 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 | static int pll_frequency_info(struct hl_fpriv *hpriv, struct hl_info_args *args) | 411 | static int pll_frequency_info(struct hl_fpriv *hpriv, struct hl_info_args *args) |
| 407 | { | 412 | { |
| 408 | struct hl_device *hdev = hpriv->hdev; | 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 | u32 max_size = args->return_size; | 415 | u32 max_size = args->return_size; |
| 411 | void __user *out = (void __user *) (uintptr_t) args->return_pointer; | 416 | void __user *out = (void __user *) (uintptr_t) args->return_pointer; |
| 412 | int rc; | 417 | int rc; |
| @@ -418,8 +418,11 @@ static void init_signal_cs(struct hl_device *hdev, · 417 unmodified lines | |||
| 418 | "generate signal CB, sob_id: %d, sob val: 0x%x, q_idx: %d\n", | 418 | "generate signal CB, sob_id: %d, sob val: 0x%x, q_idx: %d\n", |
| 419 | cs_cmpl->hw_sob->sob_id, cs_cmpl->sob_val, q_idx); | 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 | hdev->asic_funcs->gen_signal_cb(hdev, job->patched_cb, | 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 | kref_get(&hw_sob->kref); | 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 | if ((val & PCI_CONFIG_ELBI_STS_MASK) == PCI_CONFIG_ELBI_STS_DONE) | 130 | if ((val & PCI_CONFIG_ELBI_STS_MASK) == PCI_CONFIG_ELBI_STS_DONE) |
| 131 | return 0; | 131 | return 0; |
| 132 | 132 | ||
| 133 | if (val & PCI_CONFIG_ELBI_STS_ERR) { | 133 | if (val & PCI_CONFIG_ELBI_STS_ERR) |
| 134 | dev_err(hdev->dev, "Error writing to ELBI\n"); | ||
| 135 | return -EIO; | 134 | return -EIO; |
| 136 | } | ||
| 137 | 135 | ||
| 138 | if (!(val & PCI_CONFIG_ELBI_STS_MASK)) { | 136 | if (!(val & PCI_CONFIG_ELBI_STS_MASK)) { |
| 139 | dev_err(hdev->dev, "ELBI write didn't finish in time\n"); | 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 | dbi_offset = addr & 0xFFF; | 159 | dbi_offset = addr & 0xFFF; |
| 162 | 160 | ||
| 163 | rc = hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr, 0x00300000); | 161 | /* Ignore result of writing to pcie_aux_dbi_reg_addr as it could fail |
| 164 | rc |= hl_pci_elbi_write(hdev, prop->pcie_dbi_base_address + dbi_offset, | 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 | data); | 167 | data); |
| 166 | 168 | ||
| 167 | if (rc) | 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 | rc |= hl_pci_iatu_write(hdev, offset + 0x4, ctrl_reg_val); | 247 | rc |= hl_pci_iatu_write(hdev, offset + 0x4, ctrl_reg_val); |
| 246 | 248 | ||
| 247 | /* Return the DBI window to the default location */ | 249 | /* Return the DBI window to the default location |
| 248 | rc |= hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr, 0); | 250 | * Ignore result of writing to pcie_aux_dbi_reg_addr as it could fail |
| 249 | rc |= hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr + 4, 0); | 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 | if (rc) | 255 | if (rc) |
| 252 | dev_err(hdev->dev, "failed to map bar %u to 0x%08llx\n", | 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 | /* Enable */ | 298 | /* Enable */ |
| 295 | rc |= hl_pci_iatu_write(hdev, 0x004, 0x80000000); | 299 | rc |= hl_pci_iatu_write(hdev, 0x004, 0x80000000); |
| 296 | 300 | ||
| 297 | /* Return the DBI window to the default location */ | 301 | /* Return the DBI window to the default location |
| 298 | rc |= hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr, 0); | 302 | * Ignore result of writing to pcie_aux_dbi_reg_addr as it could fail |
| 299 | rc |= hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr + 4, 0); | 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 | return rc; | 307 | return rc; |
| 302 | } | 308 | } |
| @@ -151,19 +151,6 @@ static const u16 gaudi_packet_sizes[MAX_PACKET_ID] = { · 150 unmodified lines | |||
| 151 | [PACKET_LOAD_AND_EXE] = sizeof(struct packet_load_and_exe) | 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 | static inline bool validate_packet_id(enum packet_id id) | 154 | static inline bool validate_packet_id(enum packet_id id) |
| 168 | { | 155 | { |
| 169 | switch (id) { | 156 | switch (id) { |
| @@ -374,7 +361,7 @@ static int gaudi_cpucp_info_get(struct hl_device *hdev); · 204 unmodified lines | |||
| 374 | static void gaudi_disable_clock_gating(struct hl_device *hdev); | 361 | static void gaudi_disable_clock_gating(struct hl_device *hdev); |
| 375 | static void gaudi_mmu_prepare(struct hl_device *hdev, u32 asid); | 362 | static void gaudi_mmu_prepare(struct hl_device *hdev, u32 asid); |
| 376 | static u32 gaudi_gen_signal_cb(struct hl_device *hdev, void *data, u16 sob_id, | 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 | static u32 gaudi_gen_wait_cb(struct hl_device *hdev, | 365 | static u32 gaudi_gen_wait_cb(struct hl_device *hdev, |
| 379 | struct hl_gen_wait_properties *prop); | 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 | if (rc) | 654 | if (rc) |
| 668 | goto free_queue_props; | 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 | /* Before continuing in the initialization, we need to read the preboot | 657 | /* Before continuing in the initialization, we need to read the preboot |
| 677 | * version to determine whether we run with a security-enabled firmware | 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 | goto pci_fini; | 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 | return 0; | 675 | return 0; |
| 689 | 676 | ||
| 690 | pci_fini: | 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 | * @hdev: pointer to hl_device structure | 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, | 698 | static int gaudi_fetch_psoc_frequency(struct hl_device *hdev) |
| 715 | enum gaudi_pll_index pll_index, | ||
| 716 | u16 *pll_freq_arr) | ||
| 717 | { | 699 | { |
| 718 | u32 nr = 0, nf = 0, od = 0, pll_clk = 0, div_fctr, div_sel, | 700 | struct asic_fixed_properties *prop = &hdev->asic_prop; |
| 719 | pll_base_addr = gaudi_pll_base_addresses[pll_index]; | 701 | u32 nr = 0, nf = 0, od = 0, div_fctr = 0, pll_clk, div_sel; |
| 720 | u16 freq = 0; | 702 | u16 pll_freq_arr[HL_PLL_NUM_OUTPUTS], freq; |
| 721 | int i, rc; | 703 | int 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); | ||
| 727 | 704 | ||
| 728 | if (rc) | 705 | if (hdev->asic_prop.fw_security_disabled) { |
| 729 | return rc; | ||
| 730 | } else if (hdev->asic_prop.fw_security_disabled) { | ||
| 731 | /* Backward compatibility */ | 706 | /* Backward compatibility */ |
| 732 | nr = RREG32(pll_base_addr + PLL_NR_OFFSET); | 707 | div_fctr = RREG32(mmPSOC_CPU_PLL_DIV_FACTOR_2); |
| 733 | nf = RREG32(pll_base_addr + PLL_NF_OFFSET); | 708 | div_sel = RREG32(mmPSOC_CPU_PLL_DIV_SEL_2); |
| 734 | od = RREG32(pll_base_addr + PLL_OD_OFFSET); | 709 | nr = RREG32(mmPSOC_CPU_PLL_NR); |
| 735 | 710 | nf = RREG32(mmPSOC_CPU_PLL_NF); | |
| 736 | for (i = 0; i < HL_PLL_NUM_OUTPUTS; i++) { | 711 | od = RREG32(mmPSOC_CPU_PLL_OD); |
| 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); | ||
| 741 | 712 | ||
| 742 | if (div_sel == DIV_SEL_REF_CLK || | 713 | if (div_sel == DIV_SEL_REF_CLK || |
| 743 | div_sel == DIV_SEL_DIVIDED_REF) { | 714 | div_sel == DIV_SEL_DIVIDED_REF) { |
| 744 | if (div_sel == DIV_SEL_REF_CLK) | 715 | if (div_sel == DIV_SEL_REF_CLK) |
| 745 | freq = PLL_REF_CLK; | 716 | freq = PLL_REF_CLK; |
| 746 | else | 717 | else |
| 747 | freq = PLL_REF_CLK / (div_fctr + 1); | 718 | freq = PLL_REF_CLK / (div_fctr + 1); |
| 748 | } else if (div_sel == DIV_SEL_PLL_CLK || | 719 | } else if (div_sel == DIV_SEL_PLL_CLK || |
| 749 | div_sel == DIV_SEL_DIVIDED_PLL) { | 720 | div_sel == DIV_SEL_DIVIDED_PLL) { |
| 750 | pll_clk = PLL_REF_CLK * (nf + 1) / | 721 | pll_clk = PLL_REF_CLK * (nf + 1) / |
| 751 | ((nr + 1) * (od + 1)); | 722 | ((nr + 1) * (od + 1)); |
| 752 | if (div_sel == DIV_SEL_PLL_CLK) | 723 | if (div_sel == DIV_SEL_PLL_CLK) |
| 753 | freq = pll_clk; | 724 | freq = pll_clk; |
| 754 | else | 725 | else |
| 755 | freq = pll_clk / (div_fctr + 1); | 726 | freq = pll_clk / (div_fctr + 1); |
| 756 | } else { | 727 | } else { |
| 757 | dev_warn(hdev->dev, | 728 | dev_warn(hdev->dev, |
| 758 | "Received invalid div select value: %d", | 729 | "Received invalid div select value: %d", |
| 759 | div_sel); | 730 | div_sel); |
| 760 | } | 731 | freq = 0; |
| 761 | |||
| 762 | pll_freq_arr[i] = freq; | ||
| 763 | } | 732 | } |
| 764 | } else { | 733 | } else { |
| 765 | dev_err(hdev->dev, "Failed to fetch PLL frequency values\n"); | 734 | rc = hl_fw_cpucp_pll_info_get(hdev, CPU_PLL, pll_freq_arr); |
| 766 | return -EIO; | ||
| 767 | } | ||
| 768 | 735 | ||
| 769 | return 0; | 736 | if (rc) |
| 770 | } | 737 | return rc; |
| 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; | ||
| 783 | 738 | ||
| 784 | rc = gaudi_fetch_pll_frequency(hdev, CPU_PLL, pll_freq); | 739 | freq = pll_freq_arr[2]; |
| 785 | if (rc) | 740 | } |
| 786 | return rc; | ||
| 787 | 741 | ||
| 788 | prop->psoc_timestamp_frequency = pll_freq[2]; | 742 | prop->psoc_timestamp_frequency = freq; |
| 789 | prop->psoc_pci_pll_nr = 0; | 743 | prop->psoc_pci_pll_nr = nr; |
| 790 | prop->psoc_pci_pll_nf = 0; | 744 | prop->psoc_pci_pll_nf = nf; |
| 791 | prop->psoc_pci_pll_od = 0; | 745 | prop->psoc_pci_pll_od = od; |
| 792 | prop->psoc_pci_pll_div_factor = 0; | 746 | prop->psoc_pci_pll_div_factor = div_fctr; |
| 793 | 747 | ||
| 794 | return 0; | 748 | return 0; |
| 795 | } | 749 | } |
| @@ -884,11 +838,17 @@ static int gaudi_init_tpc_mem(struct hl_device *hdev) · 88 unmodified lines | |||
| 884 | size_t fw_size; | 838 | size_t fw_size; |
| 885 | void *cpu_addr; | 839 | void *cpu_addr; |
| 886 | dma_addr_t dma_handle; | 840 | dma_addr_t dma_handle; |
| 887 | int rc; | 841 | int rc, count = 5; |
| 888 | 842 | ||
| 843 | again: | ||
| 889 | rc = request_firmware(&fw, GAUDI_TPC_FW_FILE, hdev->dev); | 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 | if (rc) { | 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 | GAUDI_TPC_FW_FILE); | 852 | GAUDI_TPC_FW_FILE); |
| 893 | goto out; | 853 | goto out; |
| 894 | } | 854 | } |
| @@ -1110,7 +1070,7 @@ static void gaudi_collective_slave_init_job(struct hl_device *hdev, · 215 unmodified lines | |||
| 1110 | prop->collective_sob_id, queue_id); | 1070 | prop->collective_sob_id, queue_id); |
| 1111 | 1071 | ||
| 1112 | cb_size += gaudi_gen_signal_cb(hdev, job->user_cb, | 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 | static void gaudi_collective_wait_init_cs(struct hl_cs *cs) | 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 | gaudi_init_e2e(hdev); | 2409 | gaudi_init_e2e(hdev); |
| 2450 | gaudi_init_hbm_cred(hdev); | 2410 | gaudi_init_hbm_cred(hdev); |
| 2451 | 2411 | ||
| 2452 | hdev->asic_funcs->disable_clock_gating(hdev); | ||
| 2453 | |||
| 2454 | for (tpc_id = 0, tpc_offset = 0; | 2412 | for (tpc_id = 0, tpc_offset = 0; |
| 2455 | tpc_id < TPC_NUMBER_OF_ENGINES; | 2413 | tpc_id < TPC_NUMBER_OF_ENGINES; |
| 2456 | tpc_id++, tpc_offset += TPC_CFG_OFFSET) { | 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 | if (hdev->in_debug) | 3420 | if (hdev->in_debug) |
| 3463 | return; | 3421 | return; |
| 3464 | 3422 | ||
| 3423 | if (!hdev->asic_prop.fw_security_disabled) | ||
| 3424 | return; | ||
| 3425 | |||
| 3465 | for (i = GAUDI_PCI_DMA_1, qman_offset = 0 ; i < GAUDI_HBM_DMA_1 ; i++) { | 3426 | for (i = GAUDI_PCI_DMA_1, qman_offset = 0 ; i < GAUDI_HBM_DMA_1 ; i++) { |
| 3466 | enable = !!(hdev->clock_gating_mask & | 3427 | enable = !!(hdev->clock_gating_mask & |
| 3467 | (BIT_ULL(gaudi_dma_assignment[i]))); | 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 | u32 qman_offset; | 3474 | u32 qman_offset; |
| 3514 | int i; | 3475 | int i; |
| 3515 | 3476 | ||
| 3516 | if (!(gaudi->hw_cap_initialized & HW_CAP_CLK_GATE)) | 3477 | if (!hdev->asic_prop.fw_security_disabled) |
| 3517 | return; | 3478 | return; |
| 3518 | 3479 | ||
| 3519 | for (i = 0, qman_offset = 0 ; i < DMA_NUMBER_OF_CHANNELS ; i++) { | 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 | static void gaudi_pre_hw_init(struct hl_device *hdev) | 3767 | static void gaudi_pre_hw_init(struct hl_device *hdev) |
| 3807 | { | 3768 | { |
| 3808 | /* Perform read from the device to make sure device is up */ | 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 | if (hdev->asic_prop.fw_security_disabled) { | 3772 | if (hdev->asic_prop.fw_security_disabled) { |
| 3812 | /* Set the access through PCI bars (Linux driver only) as | 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 | return rc; | 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 | /* SRAM scrambler must be initialized after CPU is running from HBM */ | 3818 | /* SRAM scrambler must be initialized after CPU is running from HBM */ |
| 3851 | gaudi_init_scrambler_sram(hdev); | 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 | /* Perform read from the device to flush all configuration */ | 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 | return 0; | 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 | /* I don't know what is the state of the CPU so make sure it is | 3895 | /* I don't know what is the state of the CPU so make sure it is |
| 3928 | * stopped in any means necessary | 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 | WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR, GAUDI_EVENT_HALT_MACHINE); | 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 | WREG32(mmPSOC_GLOBAL_CONF_SW_ALL_RST, | 3943 | WREG32(mmPSOC_GLOBAL_CONF_SW_ALL_RST, |
| 3973 | 1 << PSOC_GLOBAL_CONF_SW_ALL_RST_IND_SHIFT); | 3944 | 1 << PSOC_GLOBAL_CONF_SW_ALL_RST_IND_SHIFT); |
| 3974 | } | ||
| 3975 | 3945 | ||
| 3976 | dev_info(hdev->dev, | 3946 | dev_info(hdev->dev, |
| 3977 | "Issued HARD reset command, going to wait %dms\n", | 3947 | "Issued HARD reset command, going to wait %dms\n", |
| 3978 | reset_timeout_ms); | 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 | * After hard reset, we can't poll the BTM_FSM register because the PSOC | 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 | static u32 gaudi_gen_signal_cb(struct hl_device *hdev, void *data, u16 sob_id, | 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 | struct hl_cb *cb = (struct hl_cb *) data; | 7916 | struct hl_cb *cb = (struct hl_cb *) data; |
| 7942 | struct packet_msg_short *pkt; | 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 | ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_OP_MASK, 0); /* write the value */ | 7928 | ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_OP_MASK, 0); /* write the value */ |
| 7954 | ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_BASE_MASK, 3); /* W_S SOB base */ | 7929 | ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_BASE_MASK, 3); /* W_S SOB base */ |
| 7955 | ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_OPCODE_MASK, PACKET_MSG_SHORT); | 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 | ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_RB_MASK, 1); | 7932 | ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_RB_MASK, 1); |
| 7958 | ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_MB_MASK, 1); | 7933 | ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_MB_MASK, 1); |
| 7959 | 7934 | ||
| @@ -105,13 +105,6 @@ · 104 unmodified lines | |||
| 105 | #define MME_ACC_OFFSET (mmMME1_ACC_BASE - mmMME0_ACC_BASE) | 105 | #define MME_ACC_OFFSET (mmMME1_ACC_BASE - mmMME0_ACC_BASE) |
| 106 | #define SRAM_BANK_OFFSET (mmSRAM_Y0_X1_RTR_BASE - mmSRAM_Y0_X0_RTR_BASE) | 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 | #define NUM_OF_SOB_IN_BLOCK \ | 108 | #define NUM_OF_SOB_IN_BLOCK \ |
| 116 | (((mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_2047 - \ | 109 | (((mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_2047 - \ |
| 117 | mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0) + 4) >> 2) | 110 | mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0) + 4) >> 2) |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | #include "../include/gaudi/gaudi_coresight.h" | 9 | #include "../include/gaudi/gaudi_coresight.h" |
| 10 | #include "../include/gaudi/asic_reg/gaudi_regs.h" | 10 | #include "../include/gaudi/asic_reg/gaudi_regs.h" |
| 11 | #include "../include/gaudi/gaudi_masks.h" | 11 | #include "../include/gaudi/gaudi_masks.h" |
| 12 | #include "../include/gaudi/gaudi_reg_map.h" | ||
| 12 | 13 | ||
| 13 | #include <uapi/misc/habanalabs.h> | 14 | #include <uapi/misc/habanalabs.h> |
| 14 | #define SPMU_SECTION_SIZE MME0_ACC_SPMU_MAX_OFFSET | 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 | /* Perform read from the device to flush all configuration */ | 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 | return rc; | 880 | return rc; |
| 880 | } | 881 | } |
| @@ -613,12 +613,6 @@ static int goya_early_init(struct hl_device *hdev) · 612 unmodified lines | |||
| 613 | if (rc) | 613 | if (rc) |
| 614 | goto free_queue_props; | 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 | /* Before continuing in the initialization, we need to read the preboot | 616 | /* Before continuing in the initialization, we need to read the preboot |
| 623 | * version to determine whether we run with a security-enabled firmware | 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 | goto pci_fini; | 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 | if (!hdev->pldm) { | 634 | if (!hdev->pldm) { |
| 635 | val = RREG32(mmPSOC_GLOBAL_CONF_BOOT_STRAP_PINS); | 635 | val = RREG32(mmPSOC_GLOBAL_CONF_BOOT_STRAP_PINS); |
| 636 | if (val & PSOC_GLOBAL_CONF_BOOT_STRAP_PINS_SRIOV_EN_MASK) | 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 | static void goya_fetch_psoc_frequency(struct hl_device *hdev) | 694 | static void goya_fetch_psoc_frequency(struct hl_device *hdev) |
| 695 | { | 695 | { |
| 696 | struct asic_fixed_properties *prop = &hdev->asic_prop; | 696 | struct asic_fixed_properties *prop = &hdev->asic_prop; |
| 697 | u32 trace_freq = 0; | 697 | u32 nr = 0, nf = 0, od = 0, div_fctr = 0, pll_clk, div_sel; |
| 698 | u32 pll_clk = 0; | 698 | u16 pll_freq_arr[HL_PLL_NUM_OUTPUTS], freq; |
| 699 | u32 div_fctr = RREG32(mmPSOC_PCI_PLL_DIV_FACTOR_1); | 699 | int rc; |
| 700 | u32 div_sel = RREG32(mmPSOC_PCI_PLL_DIV_SEL_1); | 700 | |
| 701 | u32 nr = RREG32(mmPSOC_PCI_PLL_NR); | 701 | if (hdev->asic_prop.fw_security_disabled) { |
| 702 | u32 nf = RREG32(mmPSOC_PCI_PLL_NF); | 702 | div_fctr = RREG32(mmPSOC_PCI_PLL_DIV_FACTOR_1); |
| 703 | u32 od = RREG32(mmPSOC_PCI_PLL_OD); | 703 | div_sel = RREG32(mmPSOC_PCI_PLL_DIV_SEL_1); |
| 704 | 704 | nr = RREG32(mmPSOC_PCI_PLL_NR); | |
| 705 | if (div_sel == DIV_SEL_REF_CLK || div_sel == DIV_SEL_DIVIDED_REF) { | 705 | nf = RREG32(mmPSOC_PCI_PLL_NF); |
| 706 | if (div_sel == DIV_SEL_REF_CLK) | 706 | od = RREG32(mmPSOC_PCI_PLL_OD); |
| 707 | trace_freq = PLL_REF_CLK; | 707 | |
| 708 | else | 708 | if (div_sel == DIV_SEL_REF_CLK || |
| 709 | trace_freq = PLL_REF_CLK / (div_fctr + 1); | 709 | div_sel == DIV_SEL_DIVIDED_REF) { |
| 710 | } else if (div_sel == DIV_SEL_PLL_CLK || | 710 | if (div_sel == DIV_SEL_REF_CLK) |
| 711 | div_sel == DIV_SEL_DIVIDED_PLL) { | 711 | freq = PLL_REF_CLK; |
| 712 | pll_clk = PLL_REF_CLK * (nf + 1) / ((nr + 1) * (od + 1)); | 712 | else |
| 713 | if (div_sel == DIV_SEL_PLL_CLK) | 713 | freq = PLL_REF_CLK / (div_fctr + 1); |
| 714 | trace_freq = pll_clk; | 714 | } else if (div_sel == DIV_SEL_PLL_CLK || |
| 715 | else | 715 | div_sel == DIV_SEL_DIVIDED_PLL) { |
| 716 | trace_freq = pll_clk / (div_fctr + 1); | 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 | } else { | 728 | } else { |
| 718 | dev_warn(hdev->dev, | 729 | rc = hl_fw_cpucp_pll_info_get(hdev, PCI_PLL, pll_freq_arr); |
| 719 | "Received invalid div select value: %d", div_sel); | 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 | prop->psoc_pci_pll_nr = nr; | 738 | prop->psoc_pci_pll_nr = nr; |
| 724 | prop->psoc_pci_pll_nf = nf; | 739 | prop->psoc_pci_pll_nf = nf; |
| 725 | prop->psoc_pci_pll_od = od; | 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 | static u32 goya_gen_signal_cb(struct hl_device *hdev, void *data, u16 sob_id, | 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 | return 0; | 5344 | return 0; |
| 5330 | } | 5345 | } |
| @@ -145,11 +145,15 @@ · 144 unmodified lines | |||
| 145 | * implemented. This means that FW will | 145 | * implemented. This means that FW will |
| 146 | * perform hard reset procedure on | 146 | * perform hard reset procedure on |
| 147 | * receiving the halt-machine event. | 147 | * receiving the halt-machine event. |
| 148 | * Initialized in: linux | 148 | * Initialized in: preboot, u-boot, linux |
| 149 | * | 149 | * |
| 150 | * CPU_BOOT_DEV_STS0_PLL_INFO_EN FW retrieval of PLL info is enabled. | 150 | * CPU_BOOT_DEV_STS0_PLL_INFO_EN FW retrieval of PLL info is enabled. |
| 151 | * Initialized in: linux | 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 | * CPU_BOOT_DEV_STS0_ENABLED Device status register enabled. | 157 | * CPU_BOOT_DEV_STS0_ENABLED Device status register enabled. |
| 154 | * This is a main indication that the | 158 | * This is a main indication that the |
| 155 | * running FW populates the device status | 159 | * running FW populates the device status |
| @@ -171,6 +175,7 @@ · 15 unmodified lines | |||
| 171 | #define CPU_BOOT_DEV_STS0_DRAM_SCR_EN (1 << 9) | 175 | #define CPU_BOOT_DEV_STS0_DRAM_SCR_EN (1 << 9) |
| 172 | #define CPU_BOOT_DEV_STS0_FW_HARD_RST_EN (1 << 10) | 176 | #define CPU_BOOT_DEV_STS0_FW_HARD_RST_EN (1 << 10) |
| 173 | #define CPU_BOOT_DEV_STS0_PLL_INFO_EN (1 << 11) | 177 | #define CPU_BOOT_DEV_STS0_PLL_INFO_EN (1 << 11) |
| 178 | #define CPU_BOOT_DEV_STS0_CLK_GATE_EN (1 << 13) | ||
| 174 | #define CPU_BOOT_DEV_STS0_ENABLED (1 << 31) | 179 | #define CPU_BOOT_DEV_STS0_ENABLED (1 << 31) |
| 175 | 180 | ||
| 176 | enum cpu_boot_status { | 181 | enum cpu_boot_status { |
| @@ -204,6 +209,8 @@ enum kmd_msg { · 27 unmodified lines | |||
| 204 | KMD_MSG_GOTO_WFE, | 209 | KMD_MSG_GOTO_WFE, |
| 205 | KMD_MSG_FIT_RDY, | 210 | KMD_MSG_FIT_RDY, |
| 206 | KMD_MSG_SKIP_BMC, | 211 | KMD_MSG_SKIP_BMC, |
| 212 | RESERVED, | ||
| 213 | KMD_MSG_RST_DEV, | ||
| 207 | }; | 214 | }; |
| 208 | 215 | ||
| 209 | enum cpu_msg_status { | 216 | enum cpu_msg_status { |
| @@ -55,12 +55,23 @@ static int pvpanic_mmio_probe(struct platform_device *pdev) · 54 unmodified lines | |||
| 55 | struct resource *res; | 55 | struct resource *res; |
| 56 | 56 | ||
| 57 | res = platform_get_mem_or_io(pdev, 0); | 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 | base = devm_ioport_map(dev, res->start, resource_size(res)); | 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 | base = devm_ioremap_resource(dev, res); | 68 | base = devm_ioremap_resource(dev, res); |
| 62 | if (IS_ERR(base)) | 69 | if (IS_ERR(base)) |
| 63 | return PTR_ERR(base); | 70 | return PTR_ERR(base); |
| 71 | break; | ||
| 72 | default: | ||
| 73 | return -EINVAL; | ||
| 74 | } | ||
| 64 | 75 | ||
| 65 | atomic_notifier_chain_register(&panic_notifier_list, | 76 | atomic_notifier_chain_register(&panic_notifier_list, |
| 66 | &pvpanic_panic_nb); | 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 | goto free_dst; | 380 | goto free_dst; |
| 381 | 381 | ||
| 382 | min_headroom = LL_RESERVED_SPACE(dst->dev) + dst->header_len + | 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 | err = skb_cow_head(skb, min_headroom); | 385 | err = skb_cow_head(skb, min_headroom); |
| 386 | if (unlikely(err)) | 386 | if (unlikely(err)) |
| @@ -534,6 +534,7 @@ static void bareudp_setup(struct net_device *dev) · 147 unmodified lines | |||
| 534 | SET_NETDEV_DEVTYPE(dev, &bareudp_type); | 534 | SET_NETDEV_DEVTYPE(dev, &bareudp_type); |
| 535 | dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; | 535 | dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; |
| 536 | dev->features |= NETIF_F_RXCSUM; | 536 | dev->features |= NETIF_F_RXCSUM; |
| 537 | dev->features |= NETIF_F_LLTX; | ||
| 537 | dev->features |= NETIF_F_GSO_SOFTWARE; | 538 | dev->features |= NETIF_F_GSO_SOFTWARE; |
| 538 | dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM; | 539 | dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM; |
| 539 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; | 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 | return 0; | 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 | static int bareudp_newlink(struct net *net, struct net_device *dev, | 656 | static int bareudp_newlink(struct net *net, struct net_device *dev, |
| 648 | struct nlattr *tb[], struct nlattr *data[], | 657 | struct nlattr *tb[], struct nlattr *data[], |
| 649 | struct netlink_ext_ack *extack) | 658 | struct netlink_ext_ack *extack) |
| 650 | { | 659 | { |
| 651 | struct bareudp_conf conf; | 660 | struct bareudp_conf conf; |
| 661 | LIST_HEAD(list_kill); | ||
| 652 | int err; | 662 | int err; |
| 653 | 663 | ||
| 654 | err = bareudp2info(data, &conf, extack); | 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 | err = bareudp_link_config(dev, tb); | 672 | err = bareudp_link_config(dev, tb); |
| 663 | if (err) | 673 | if (err) |
| 664 | return err; | 674 | goto err_unconfig; |
| 665 | 675 | ||
| 666 | return 0; | 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); | 678 | err_unconfig: |
| 674 | unregister_netdevice_queue(dev, head); | 679 | bareudp_dellink(dev, &list_kill); |
| 680 | unregister_netdevice_many(&list_kill); | ||
| 681 | return err; | ||
| 675 | } | 682 | } |
| 676 | 683 | ||
| 677 | static size_t bareudp_get_size(const struct net_device *dev) | 684 | static size_t bareudp_get_size(const struct net_device *dev) |
| @@ -123,6 +123,7 @@ config CAN_JANZ_ICAN3 · 122 unmodified lines | |||
| 123 | config CAN_KVASER_PCIEFD | 123 | config CAN_KVASER_PCIEFD |
| 124 | depends on PCI | 124 | depends on PCI |
| 125 | tristate "Kvaser PCIe FD cards" | 125 | tristate "Kvaser PCIe FD cards" |
| 126 | select CRC32 | ||
| 126 | help | 127 | help |
| 127 | This is a driver for the Kvaser PCI Express CAN FD family. | 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 | void m_can_class_unregister(struct m_can_classdev *cdev) | 1852 | void m_can_class_unregister(struct m_can_classdev *cdev) |
| 1853 | { | 1853 | { |
| 1854 | unregister_candev(cdev->net); | 1854 | unregister_candev(cdev->net); |
| 1855 | |||
| 1856 | m_can_clk_stop(cdev); | ||
| 1857 | } | 1855 | } |
| 1858 | EXPORT_SYMBOL_GPL(m_can_class_unregister); | 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 | static void tcan4x5x_check_wake(struct tcan4x5x_priv *priv) | 134 | static void tcan4x5x_check_wake(struct tcan4x5x_priv *priv) |
| 159 | { | 135 | { |
| 160 | int wake_state = 0; | 136 | int wake_state = 0; |
| @@ -469,8 +445,6 @@ static int tcan4x5x_can_probe(struct spi_device *spi) · 308 unmodified lines | |||
| 469 | mcan_class->dev = &spi->dev; | 445 | mcan_class->dev = &spi->dev; |
| 470 | mcan_class->ops = &tcan4x5x_ops; | 446 | mcan_class->ops = &tcan4x5x_ops; |
| 471 | mcan_class->is_peripheral = true; | 447 | mcan_class->is_peripheral = true; |
| 472 | mcan_class->bit_timing = &tcan4x5x_bittiming_const; | ||
| 473 | mcan_class->data_timing = &tcan4x5x_data_bittiming_const; | ||
| 474 | mcan_class->net->irq = spi->irq; | 448 | mcan_class->net->irq = spi->irq; |
| 475 | 449 | ||
| 476 | spi_set_drvdata(spi, priv); | 450 | spi_set_drvdata(spi, priv); |
| @@ -1,10 +1,10 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | config CAN_RCAR | 2 | config CAN_RCAR |
| 3 | tristate "Renesas R-Car CAN controller" | 3 | tristate "Renesas R-Car and RZ/G CAN controller" |
| 4 | depends on ARCH_RENESAS || ARM | 4 | depends on ARCH_RENESAS || ARM |
| 5 | help | 5 | help |
| 6 | Say Y here if you want to use CAN controller found on Renesas R-Car | 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 | To compile this driver as a module, choose M here: the module will | 9 | To compile this driver as a module, choose M here: the module will |
| 10 | be called rcar_can. | 10 | be called rcar_can. |
| @@ -1368,13 +1368,10 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) · 1367 unmodified lines | |||
| 1368 | struct mcp251xfd_tx_ring *tx_ring = priv->tx; | 1368 | struct mcp251xfd_tx_ring *tx_ring = priv->tx; |
| 1369 | struct spi_transfer *last_xfer; | 1369 | struct spi_transfer *last_xfer; |
| 1370 | 1370 | ||
| 1371 | tx_ring->tail += len; | ||
| 1372 | |||
| 1373 | /* Increment the TEF FIFO tail pointer 'len' times in | 1371 | /* Increment the TEF FIFO tail pointer 'len' times in |
| 1374 | * a single SPI message. | 1372 | * a single SPI message. |
| 1375 | */ | 1373 | * |
| 1376 | 1374 | * Note: | |
| 1377 | /* Note: | ||
| 1378 | * | 1375 | * |
| 1379 | * "cs_change == 1" on the last transfer results in an | 1376 | * "cs_change == 1" on the last transfer results in an |
| 1380 | * active chip select after the complete SPI | 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 | if (err) | 1388 | if (err) |
| 1392 | return err; | 1389 | return err; |
| 1393 | 1390 | ||
| 1391 | tx_ring->tail += len; | ||
| 1392 | |||
| 1394 | err = mcp251xfd_check_tef_tail(priv); | 1393 | err = mcp251xfd_check_tef_tail(priv); |
| 1395 | if (err) | 1394 | if (err) |
| 1396 | return err; | 1395 | return err; |
| @@ -1492,7 +1491,7 @@ mcp251xfd_handle_rxif_one(struct mcp251xfd_priv *priv, · 95 unmodified lines | |||
| 1492 | else | 1491 | else |
| 1493 | skb = alloc_can_skb(priv->ndev, (struct can_frame **)&cfd); | 1492 | skb = alloc_can_skb(priv->ndev, (struct can_frame **)&cfd); |
| 1494 | 1493 | ||
| 1495 | if (!cfd) { | 1494 | if (!skb) { |
| 1496 | stats->rx_dropped++; | 1495 | stats->rx_dropped++; |
| 1497 | return 0; | 1496 | return 0; |
| 1498 | } | 1497 | } |
| @@ -1553,10 +1552,8 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv, · 54 unmodified lines | |||
| 1553 | 1552 | ||
| 1554 | /* Increment the RX FIFO tail pointer 'len' times in a | 1553 | /* Increment the RX FIFO tail pointer 'len' times in a |
| 1555 | * single SPI message. | 1554 | * single SPI message. |
| 1556 | */ | 1555 | * |
| 1557 | ring->tail += len; | 1556 | * Note: |
| 1558 | |||
| 1559 | /* Note: | ||
| 1560 | * | 1557 | * |
| 1561 | * "cs_change == 1" on the last transfer results in an | 1558 | * "cs_change == 1" on the last transfer results in an |
| 1562 | * active chip select after the complete SPI | 1559 | * active chip select after the complete SPI |
| @@ -1572,6 +1569,8 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv, · 9 unmodified lines | |||
| 1572 | last_xfer->cs_change = 1; | 1569 | last_xfer->cs_change = 1; |
| 1573 | if (err) | 1570 | if (err) |
| 1574 | return err; | 1571 | return err; |
| 1572 | |||
| 1573 | ring->tail += len; | ||
| 1575 | } | 1574 | } |
| 1576 | 1575 | ||
| 1577 | return 0; | 1576 | return 0; |
| @@ -4,6 +4,7 @@ config NET_DSA_HIRSCHMANN_HELLCREEK · 3 unmodified lines | |||
| 4 | depends on HAS_IOMEM | 4 | depends on HAS_IOMEM |
| 5 | depends on NET_DSA | 5 | depends on NET_DSA |
| 6 | depends on PTP_1588_CLOCK | 6 | depends on PTP_1588_CLOCK |
| 7 | depends on LEDS_CLASS | ||
| 7 | select NET_DSA_TAG_HELLCREEK | 8 | select NET_DSA_TAG_HELLCREEK |
| 8 | help | 9 | help |
| 9 | This driver adds support for Hirschmann Hellcreek TSN switches. | 10 | This driver adds support for Hirschmann Hellcreek TSN switches. |
| @@ -92,9 +92,7 @@ · 91 unmodified lines | |||
| 92 | GSWIP_MDIO_PHY_FDUP_MASK) | 92 | GSWIP_MDIO_PHY_FDUP_MASK) |
| 93 | 93 | ||
| 94 | /* GSWIP MII Registers */ | 94 | /* GSWIP MII Registers */ |
| 95 | #define GSWIP_MII_CFG0 0x00 | 95 | #define GSWIP_MII_CFGp(p) (0x2 * (p)) |
| 96 | #define GSWIP_MII_CFG1 0x02 | ||
| 97 | #define GSWIP_MII_CFG5 0x04 | ||
| 98 | #define GSWIP_MII_CFG_EN BIT(14) | 96 | #define GSWIP_MII_CFG_EN BIT(14) |
| 99 | #define GSWIP_MII_CFG_LDCLKDIS BIT(12) | 97 | #define GSWIP_MII_CFG_LDCLKDIS BIT(12) |
| 100 | #define GSWIP_MII_CFG_MODE_MIIP 0x0 | 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 | static void gswip_mii_mask_cfg(struct gswip_priv *priv, u32 clear, u32 set, | 390 | static void gswip_mii_mask_cfg(struct gswip_priv *priv, u32 clear, u32 set, |
| 393 | int port) | 391 | int port) |
| 394 | { | 392 | { |
| 395 | switch (port) { | 393 | /* There's no MII_CFG register for the CPU port */ |
| 396 | case 0: | 394 | if (!dsa_is_cpu_port(priv->ds, port)) |
| 397 | gswip_mii_mask(priv, clear, set, GSWIP_MII_CFG0); | 395 | gswip_mii_mask(priv, clear, set, GSWIP_MII_CFGp(port)); |
| 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 | } | ||
| 406 | } | 396 | } |
| 407 | 397 | ||
| 408 | static void gswip_mii_mask_pcdu(struct gswip_priv *priv, u32 clear, u32 set, | 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 | gswip_mdio_mask(priv, 0xff, 0x09, GSWIP_MDIO_MDC_CFG1); | 812 | gswip_mdio_mask(priv, 0xff, 0x09, GSWIP_MDIO_MDC_CFG1); |
| 823 | 813 | ||
| 824 | /* Disable the xMII link */ | 814 | /* Disable the xMII link */ |
| 825 | gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, 0); | 815 | for (i = 0; i < priv->hw_info->max_ports; i++) |
| 826 | gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, 1); | 816 | gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, i); |
| 827 | gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, 5); | ||
| 828 | 817 | ||
| 829 | /* enable special tag insertion on cpu port */ | 818 | /* enable special tag insertion on cpu port */ |
| 830 | gswip_switch_mask(priv, 0, GSWIP_FDMA_PCTRL_STEN, | 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 | phylink_set(mask, Pause); | 1436 | phylink_set(mask, Pause); |
| 1448 | phylink_set(mask, Asym_Pause); | 1437 | phylink_set(mask, Asym_Pause); |
| 1449 | 1438 | ||
| 1450 | /* With the exclusion of MII and Reverse MII, we support Gigabit, | 1439 | /* With the exclusion of MII, Reverse MII and Reduced MII, we |
| 1451 | * including Half duplex | 1440 | * support Gigabit, including Half duplex |
| 1452 | */ | 1441 | */ |
| 1453 | if (state->interface != PHY_INTERFACE_MODE_MII && | 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 | phylink_set(mask, 1000baseT_Full); | 1445 | phylink_set(mask, 1000baseT_Full); |
| 1456 | phylink_set(mask, 1000baseT_Half); | 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 | struct gswip_priv *priv = ds->priv; | 1532 | struct gswip_priv *priv = ds->priv; |
| 1543 | 1533 | ||
| 1544 | /* Enable the xMII interface only for the external PHY */ | 1534 | gswip_mii_mask_cfg(priv, 0, GSWIP_MII_CFG_EN, port); |
| 1545 | if (interface != PHY_INTERFACE_MODE_INTERNAL) | ||
| 1546 | gswip_mii_mask_cfg(priv, 0, GSWIP_MII_CFG_EN, port); | ||
| 1547 | } | 1535 | } |
| 1548 | 1536 | ||
| 1549 | static void gswip_get_strings(struct dsa_switch *ds, int port, u32 stringset, | 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 | config AQTION | 19 | config AQTION |
| 20 | tristate "aQuantia AQtion(tm) Support" | 20 | tristate "aQuantia AQtion(tm) Support" |
| 21 | depends on PCI | 21 | depends on PCI |
| 22 | depends on X86_64 || ARM64 || COMPILE_TEST | ||
| 23 | depends on MACSEC || MACSEC=n | 22 | depends on MACSEC || MACSEC=n |
| 24 | help | 23 | help |
| 25 | This enables the support for the aQuantia AQtion(tm) Ethernet card. | 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 | NETIF_F_HW_VLAN_CTAG_TX; | 2577 | NETIF_F_HW_VLAN_CTAG_TX; |
| 2578 | dev->hw_features |= dev->features; | 2578 | dev->hw_features |= dev->features; |
| 2579 | dev->vlan_features |= dev->features; | 2579 | dev->vlan_features |= dev->features; |
| 2580 | dev->max_mtu = UMAC_MAX_MTU_SIZE; | ||
| 2580 | 2581 | ||
| 2581 | /* Request the WOL interrupt and advertise suspend if available */ | 2582 | /* Request the WOL interrupt and advertise suspend if available */ |
| 2582 | priv->wol_irq_disabled = 1; | 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 | ctx->tqm_fp_rings_count = resp->tqm_fp_rings_count; | 6790 | ctx->tqm_fp_rings_count = resp->tqm_fp_rings_count; |
| 6791 | if (!ctx->tqm_fp_rings_count) | 6791 | if (!ctx->tqm_fp_rings_count) |
| 6792 | ctx->tqm_fp_rings_count = bp->max_q; | 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 | ctx_pg = kcalloc(tqm_rings, sizeof(*ctx_pg), GFP_KERNEL); | 6797 | ctx_pg = kcalloc(tqm_rings, sizeof(*ctx_pg), GFP_KERNEL); |
| 6796 | if (!ctx_pg) { | 6798 | if (!ctx_pg) { |
| 6797 | kfree(ctx); | 6799 | kfree(ctx); |
| @@ -6925,7 +6927,8 @@ static int bnxt_hwrm_func_backing_store_cfg(struct bnxt *bp, u32 enables) · 127 unmodified lines | |||
| 6925 | pg_attr = &req.tqm_sp_pg_size_tqm_sp_lvl, | 6927 | pg_attr = &req.tqm_sp_pg_size_tqm_sp_lvl, |
| 6926 | pg_dir = &req.tqm_sp_page_dir, | 6928 | pg_dir = &req.tqm_sp_page_dir, |
| 6927 | ena = FUNC_BACKING_STORE_CFG_REQ_ENABLES_TQM_SP; | 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 | if (!(enables & ena)) | 6932 | if (!(enables & ena)) |
| 6930 | continue; | 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 | static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev) | 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 | struct net_device *netdev = pci_get_drvdata(pdev); | 12894 | struct net_device *netdev = pci_get_drvdata(pdev); |
| 12891 | struct bnxt *bp = netdev_priv(netdev); | 12895 | struct bnxt *bp = netdev_priv(netdev); |
| 12892 | int err = 0, off; | 12896 | int err = 0, off; |
| 12893 | pci_ers_result_t result = PCI_ERS_RESULT_DISCONNECT; | ||
| 12894 | 12897 | ||
| 12895 | netdev_info(bp->dev, "PCI Slot Reset\n"); | 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 | pci_save_state(pdev); | 12922 | pci_save_state(pdev); |
| 12920 | 12923 | ||
| 12921 | err = bnxt_hwrm_func_reset(bp); | 12924 | err = bnxt_hwrm_func_reset(bp); |
| 12922 | if (!err) { | 12925 | 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); | ||
| 12930 | result = PCI_ERS_RESULT_RECOVERED; | 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 | rtnl_unlock(); | 12929 | rtnl_unlock(); |
| @@ -12952,10 +12941,21 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev) · 11 unmodified lines | |||
| 12952 | static void bnxt_io_resume(struct pci_dev *pdev) | 12941 | static void bnxt_io_resume(struct pci_dev *pdev) |
| 12953 | { | 12942 | { |
| 12954 | struct net_device *netdev = pci_get_drvdata(pdev); | 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 | rtnl_lock(); | 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 | rtnl_unlock(); | 12960 | rtnl_unlock(); |
| 12961 | } | 12961 | } |
| @@ -1436,6 +1436,11 @@ struct bnxt_ctx_pg_info { · 1435 unmodified lines | |||
| 1436 | struct bnxt_ctx_pg_info **ctx_pg_tbl; | 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 | struct bnxt_ctx_mem_info { | 1444 | struct bnxt_ctx_mem_info { |
| 1440 | u32 qp_max_entries; | 1445 | u32 qp_max_entries; |
| 1441 | u16 qp_min_qp1_entries; | 1446 | u16 qp_min_qp1_entries; |
| @@ -1474,7 +1479,7 @@ struct bnxt_ctx_mem_info { · 32 unmodified lines | |||
| 1474 | struct bnxt_ctx_pg_info stat_mem; | 1479 | struct bnxt_ctx_pg_info stat_mem; |
| 1475 | struct bnxt_ctx_pg_info mrav_mem; | 1480 | struct bnxt_ctx_pg_info mrav_mem; |
| 1476 | struct bnxt_ctx_pg_info tim_mem; | 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 | struct bnxt_fw_health { | 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 | if (rc && ((struct hwrm_err_output *)&resp)->cmd_err == | 2533 | if (rc && ((struct hwrm_err_output *)&resp)->cmd_err == |
| 2534 | NVM_INSTALL_UPDATE_CMD_ERR_CODE_FRAG_ERR) { | 2534 | NVM_INSTALL_UPDATE_CMD_ERR_CODE_FRAG_ERR) { |
| 2535 | install.flags |= | 2535 | install.flags = |
| 2536 | cpu_to_le16(NVM_INSTALL_UPDATE_REQ_FLAGS_ALLOWED_TO_DEFRAG); | 2536 | cpu_to_le16(NVM_INSTALL_UPDATE_REQ_FLAGS_ALLOWED_TO_DEFRAG); |
| 2537 | 2537 | ||
| 2538 | rc = _hwrm_send_message_silent(bp, &install, | 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 | * UPDATE directory and try the flash again | 2546 | * UPDATE directory and try the flash again |
| 2547 | */ | 2547 | */ |
| 2548 | defrag_attempted = true; | 2548 | defrag_attempted = true; |
| 2549 | install.flags = 0; | ||
| 2549 | rc = __bnxt_flash_nvram(bp->dev, | 2550 | rc = __bnxt_flash_nvram(bp->dev, |
| 2550 | BNX_DIR_TYPE_UPDATE, | 2551 | BNX_DIR_TYPE_UPDATE, |
| 2551 | BNX_DIR_ORDINAL_FIRST, | 2552 | BNX_DIR_ORDINAL_FIRST, |
| @@ -222,8 +222,12 @@ int bnxt_get_ulp_msix_base(struct bnxt *bp) · 221 unmodified lines | |||
| 222 | 222 | ||
| 223 | int bnxt_get_ulp_stat_ctxs(struct bnxt *bp) | 223 | int bnxt_get_ulp_stat_ctxs(struct bnxt *bp) |
| 224 | { | 224 | { |
| 225 | if (bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) | 225 | if (bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) { |
| 226 | return BNXT_MIN_ROCE_STAT_CTXS; | 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 | return 0; | 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 | long ferr, rate, rate_rounded; | 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 | return; | 471 | return; |
| 472 | 472 | ||
| 473 | switch (speed) { | 473 | switch (speed) { |
| @@ -40,6 +40,13 @@ · 39 unmodified lines | |||
| 40 | #define TCB_L2T_IX_M 0xfffULL | 40 | #define TCB_L2T_IX_M 0xfffULL |
| 41 | #define TCB_L2T_IX_V(x) ((x) << TCB_L2T_IX_S) | 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 | #define TCB_SMAC_SEL_W 0 | 50 | #define TCB_SMAC_SEL_W 0 |
| 44 | #define TCB_SMAC_SEL_S 24 | 51 | #define TCB_SMAC_SEL_S 24 |
| 45 | #define TCB_SMAC_SEL_M 0xffULL | 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 | void chtls_tcp_push(struct sock *sk, int flags); | 575 | void chtls_tcp_push(struct sock *sk, int flags); |
| 576 | int chtls_push_frames(struct chtls_sock *csk, int comp); | 576 | int chtls_push_frames(struct chtls_sock *csk, int comp); |
| 577 | int chtls_set_tcb_tflag(struct sock *sk, unsigned int bit_pos, int val); | 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 | int chtls_setkey(struct chtls_sock *csk, u32 keylen, u32 mode, int cipher_type); | 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 | void skb_entail(struct sock *sk, struct sk_buff *skb, int flags); | 583 | void skb_entail(struct sock *sk, struct sk_buff *skb, int flags); |
| 580 | unsigned int keyid_to_addr(int start_addr, int keyid); | 584 | unsigned int keyid_to_addr(int start_addr, int keyid); |
| 581 | void free_tls_keyid(struct sock *sk); | 585 | void free_tls_keyid(struct sock *sk); |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | |||
| 32 | #include "chtls.h" | 32 | #include "chtls.h" |
| 33 | #include "chtls_cm.h" | 33 | #include "chtls_cm.h" |
| 34 | #include "clip_tbl.h" | 34 | #include "clip_tbl.h" |
| 35 | #include "t4_tcb.h" | ||
| 35 | 36 | ||
| 36 | /* | 37 | /* |
| 37 | * State transitions and actions for close. Note that if we are in SYN_SENT | 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 | if (sk->sk_state != TCP_SYN_RECV) | 268 | if (sk->sk_state != TCP_SYN_RECV) |
| 268 | chtls_send_abort(sk, mode, skb); | 269 | chtls_send_abort(sk, mode, skb); |
| 269 | else | 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 | return; | 275 | return; |
| 273 | out: | 276 | out: |
| @@ -621,7 +624,7 @@ static void chtls_reset_synq(struct listen_ctx *listen_ctx) · 347 unmodified lines | |||
| 621 | 624 | ||
| 622 | while (!skb_queue_empty(&listen_ctx->synq)) { | 625 | while (!skb_queue_empty(&listen_ctx->synq)) { |
| 623 | struct chtls_sock *csk = | 626 | struct chtls_sock *csk = |
| 624 | container_of((struct synq *)__skb_dequeue | 627 | container_of((struct synq *)skb_peek |
| 625 | (&listen_ctx->synq), struct chtls_sock, synq); | 628 | (&listen_ctx->synq), struct chtls_sock, synq); |
| 626 | struct sock *child = csk->sk; | 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 | const struct cpl_pass_accept_req *req, | 1112 | const struct cpl_pass_accept_req *req, |
| 1110 | struct chtls_dev *cdev) | 1113 | struct chtls_dev *cdev) |
| 1111 | { | 1114 | { |
| 1115 | struct adapter *adap = pci_get_drvdata(cdev->pdev); | ||
| 1112 | struct neighbour *n = NULL; | 1116 | struct neighbour *n = NULL; |
| 1113 | struct inet_sock *newinet; | 1117 | struct inet_sock *newinet; |
| 1114 | const struct iphdr *iph; | 1118 | const struct iphdr *iph; |
| @@ -1118,9 +1122,10 @@ static struct sock *chtls_recv_sock(struct sock *lsk, · 3 unmodified lines | |||
| 1118 | struct dst_entry *dst; | 1122 | struct dst_entry *dst; |
| 1119 | struct tcp_sock *tp; | 1123 | struct tcp_sock *tp; |
| 1120 | struct sock *newsk; | 1124 | struct sock *newsk; |
| 1125 | bool found = false; | ||
| 1121 | u16 port_id; | 1126 | u16 port_id; |
| 1122 | int rxq_idx; | 1127 | int rxq_idx; |
| 1123 | int step; | 1128 | int step, i; |
| 1124 | 1129 | ||
| 1125 | iph = (const struct iphdr *)network_hdr; | 1130 | iph = (const struct iphdr *)network_hdr; |
| 1126 | newsk = tcp_create_openreq_child(lsk, oreq, cdev->askb); | 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 | n = dst_neigh_lookup(dst, &ip6h->saddr); | 1157 | n = dst_neigh_lookup(dst, &ip6h->saddr); |
| 1153 | #endif | 1158 | #endif |
| 1154 | } | 1159 | } |
| 1155 | if (!n) | 1160 | if (!n || !n->dev) |
| 1156 | goto free_sk; | 1161 | goto free_sk; |
| 1157 | 1162 | ||
| 1158 | ndev = n->dev; | 1163 | ndev = n->dev; |
| @@ -1161,6 +1166,13 @@ static struct sock *chtls_recv_sock(struct sock *lsk, · 2 unmodified lines | |||
| 1161 | if (is_vlan_dev(ndev)) | 1166 | if (is_vlan_dev(ndev)) |
| 1162 | ndev = vlan_dev_real_dev(ndev); | 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 | port_id = cxgb4_port_idx(ndev); | 1176 | port_id = cxgb4_port_idx(ndev); |
| 1165 | 1177 | ||
| 1166 | csk = chtls_sock_create(cdev); | 1178 | csk = chtls_sock_create(cdev); |
| @@ -1238,6 +1250,7 @@ static struct sock *chtls_recv_sock(struct sock *lsk, · 71 unmodified lines | |||
| 1238 | free_csk: | 1250 | free_csk: |
| 1239 | chtls_sock_release(&csk->kref); | 1251 | chtls_sock_release(&csk->kref); |
| 1240 | free_dst: | 1252 | free_dst: |
| 1253 | neigh_release(n); | ||
| 1241 | dst_release(dst); | 1254 | dst_release(dst); |
| 1242 | free_sk: | 1255 | free_sk: |
| 1243 | inet_csk_prepare_forced_close(newsk); | 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 | newsk = chtls_recv_sock(sk, oreq, network_hdr, req, cdev); | 1401 | newsk = chtls_recv_sock(sk, oreq, network_hdr, req, cdev); |
| 1389 | if (!newsk) | 1402 | if (!newsk) |
| 1390 | goto free_oreq; | 1403 | goto reject; |
| 1391 | 1404 | ||
| 1392 | if (chtls_get_module(newsk)) | 1405 | if (chtls_get_module(newsk)) |
| 1393 | goto reject; | 1406 | goto reject; |
| @@ -1403,8 +1416,6 @@ static void chtls_pass_accept_request(struct sock *sk, · 9 unmodified lines | |||
| 1403 | kfree_skb(skb); | 1416 | kfree_skb(skb); |
| 1404 | return; | 1417 | return; |
| 1405 | 1418 | ||
| 1406 | free_oreq: | ||
| 1407 | chtls_reqsk_free(oreq); | ||
| 1408 | reject: | 1419 | reject: |
| 1409 | mk_tid_release(reply_skb, 0, tid); | 1420 | mk_tid_release(reply_skb, 0, tid); |
| 1410 | cxgb4_ofld_send(cdev->lldi->ports[0], reply_skb); | 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 | sk_wake_async(sk, 0, POLL_OUT); | 1600 | sk_wake_async(sk, 0, POLL_OUT); |
| 1590 | 1601 | ||
| 1591 | data = lookup_stid(cdev->tids, stid); | 1602 | data = lookup_stid(cdev->tids, stid); |
| 1603 | if (!data) { | ||
| 1604 | /* listening server close */ | ||
| 1605 | kfree_skb(skb); | ||
| 1606 | goto unlock; | ||
| 1607 | } | ||
| 1592 | lsk = ((struct listen_ctx *)data)->lsk; | 1608 | lsk = ((struct listen_ctx *)data)->lsk; |
| 1593 | 1609 | ||
| 1594 | bh_lock_sock(lsk); | 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 | else if (tcp_sk(sk)->linger2 < 0 && | 1952 | else if (tcp_sk(sk)->linger2 < 0 && |
| 1937 | !csk_flag_nochk(csk, CSK_ABORT_SHUTDOWN)) | 1953 | !csk_flag_nochk(csk, CSK_ABORT_SHUTDOWN)) |
| 1938 | chtls_abort_conn(sk, skb); | 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 | break; | 1957 | break; |
| 1940 | default: | 1958 | default: |
| 1941 | pr_info("close_con_rpl in bad state %d\n", sk->sk_state); | 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 | spin_unlock_bh(&cdev->deferq.lock); | 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 | static void chtls_send_abort_rpl(struct sock *sk, struct sk_buff *skb, | 2018 | static void chtls_send_abort_rpl(struct sock *sk, struct sk_buff *skb, |
| 2034 | struct chtls_dev *cdev, | 2019 | struct chtls_dev *cdev, |
| 2035 | int status, int queue) | 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 | queue = csk->txq_idx; | 2063 | queue = csk->txq_idx; |
| 2079 | 2064 | ||
| 2080 | skb->sk = NULL; | 2065 | skb->sk = NULL; |
| 2066 | chtls_send_abort_rpl(child, skb, BLOG_SKB_CB(skb)->cdev, | ||
| 2067 | CPL_ABORT_NO_RST, queue); | ||
| 2081 | do_abort_syn_rcv(child, lsk); | 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 | static int abort_syn_rcv(struct sock *sk, struct sk_buff *skb) | 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 | if (!sock_owned_by_user(psk)) { | 2095 | if (!sock_owned_by_user(psk)) { |
| 2111 | int queue = csk->txq_idx; | 2096 | int queue = csk->txq_idx; |
| 2112 | 2097 | ||
| 2098 | chtls_send_abort_rpl(sk, skb, cdev, CPL_ABORT_NO_RST, queue); | ||
| 2113 | do_abort_syn_rcv(sk, psk); | 2099 | do_abort_syn_rcv(sk, psk); |
| 2114 | send_abort_rpl(sk, skb, cdev, CPL_ABORT_NO_RST, queue); | ||
| 2115 | } else { | 2100 | } else { |
| 2116 | skb->sk = sk; | 2101 | skb->sk = sk; |
| 2117 | BLOG_SKB_CB(skb)->backlog_rcv = bl_abort_syn_rcv; | 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 | int queue = csk->txq_idx; | 2114 | int queue = csk->txq_idx; |
| 2130 | 2115 | ||
| 2131 | if (is_neg_adv(req->status)) { | 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 | kfree_skb(skb); | 2117 | kfree_skb(skb); |
| 2136 | return; | 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 | if (sk->sk_state == TCP_SYN_RECV && !abort_syn_rcv(sk, skb)) | 2140 | if (sk->sk_state == TCP_SYN_RECV && !abort_syn_rcv(sk, skb)) |
| 2159 | return; | 2141 | return; |
| 2160 | 2142 | ||
| 2161 | chtls_release_resources(sk); | ||
| 2162 | chtls_conn_done(sk); | ||
| 2163 | } | 2143 | } |
| 2164 | 2144 | ||
| 2165 | chtls_send_abort_rpl(sk, skb, BLOG_SKB_CB(skb)->cdev, | 2145 | chtls_send_abort_rpl(sk, skb, BLOG_SKB_CB(skb)->cdev, |
| 2166 | rst_status, queue); | 2146 | rst_status, queue); |
| 2147 | chtls_release_resources(sk); | ||
| 2148 | chtls_conn_done(sk); | ||
| 2167 | } | 2149 | } |
| 2168 | 2150 | ||
| 2169 | static void chtls_abort_rpl_rss(struct sock *sk, struct sk_buff *skb) | 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 | return 0; | 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 | chtls_handler_func chtls_handlers[NUM_CPL_CMDS] = { | 2322 | chtls_handler_func chtls_handlers[NUM_CPL_CMDS] = { |
| 2319 | [CPL_PASS_OPEN_RPL] = chtls_pass_open_rpl, | 2323 | [CPL_PASS_OPEN_RPL] = chtls_pass_open_rpl, |
| 2320 | [CPL_CLOSE_LISTSRV_RPL] = chtls_close_listsrv_rpl, | 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 | [CPL_CLOSE_CON_RPL] = chtls_conn_cpl, | 2331 | [CPL_CLOSE_CON_RPL] = chtls_conn_cpl, |
| 2328 | [CPL_ABORT_REQ_RSS] = chtls_conn_cpl, | 2332 | [CPL_ABORT_REQ_RSS] = chtls_conn_cpl, |
| 2329 | [CPL_ABORT_RPL_RSS] = chtls_conn_cpl, | 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 | return ret < 0 ? ret : 0; | 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 | * Set one of the t_flags bits in the TCB. | 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 | TF_RX_QUIESCE_V(val)); | 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 | /* TLS Key bitmap processing */ | 157 | /* TLS Key bitmap processing */ |
| 117 | int chtls_init_kmap(struct chtls_dev *cdev, struct cxgb4_lld_info *lldi) | 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 | ret = mdiobus_register(priv->mdio); | 1211 | ret = mdiobus_register(priv->mdio); |
| 1212 | if (ret) { | 1212 | if (ret) { |
| 1213 | dev_err(&netdev->dev, "failed to register MDIO bus\n"); | 1213 | dev_err(&netdev->dev, "failed to register MDIO bus\n"); |
| 1214 | goto free2; | 1214 | goto free3; |
| 1215 | } | 1215 | } |
| 1216 | 1216 | ||
| 1217 | ret = ethoc_mdio_probe(netdev); | 1217 | ret = ethoc_mdio_probe(netdev); |
| @@ -1243,6 +1243,7 @@ error2: · 25 unmodified lines | |||
| 1243 | netif_napi_del(&priv->napi); | 1243 | netif_napi_del(&priv->napi); |
| 1244 | error: | 1244 | error: |
| 1245 | mdiobus_unregister(priv->mdio); | 1245 | mdiobus_unregister(priv->mdio); |
| 1246 | free3: | ||
| 1246 | mdiobus_free(priv->mdio); | 1247 | mdiobus_free(priv->mdio); |
| 1247 | free2: | 1248 | free2: |
| 1248 | clk_disable_unprepare(priv->clk); | 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 | module_platform_driver(fs_enet_bb_mdio_driver); | 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 | module_platform_driver(fs_enet_fec_mdio_driver); | 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 | INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work); | 3889 | INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work); |
| 3890 | netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, 64); | 3890 | netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, 64); |
| 3891 | dev->mtu = 1500; | 3891 | dev->mtu = 1500; |
| 3892 | dev->max_mtu = 1518; | ||
| 3892 | 3893 | ||
| 3893 | ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT); | 3894 | ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT); |
| 3894 | ugeth->phy_interface = phy_interface; | 3895 | ugeth->phy_interface = phy_interface; |
| @@ -3934,12 +3935,12 @@ static int ucc_geth_remove(struct platform_device* ofdev) · 39 unmodified lines | |||
| 3934 | struct device_node *np = ofdev->dev.of_node; | 3935 | struct device_node *np = ofdev->dev.of_node; |
| 3935 | 3936 | ||
| 3936 | unregister_netdev(dev); | 3937 | unregister_netdev(dev); |
| 3937 | free_netdev(dev); | ||
| 3938 | ucc_geth_memclean(ugeth); | 3938 | ucc_geth_memclean(ugeth); |
| 3939 | if (of_phy_is_fixed_link(np)) | 3939 | if (of_phy_is_fixed_link(np)) |
| 3940 | of_phy_deregister_fixed_link(np); | 3940 | of_phy_deregister_fixed_link(np); |
| 3941 | of_node_put(ugeth->ug_info->tbi_node); | 3941 | of_node_put(ugeth->ug_info->tbi_node); |
| 3942 | of_node_put(ugeth->ug_info->phy_node); | 3942 | of_node_put(ugeth->ug_info->phy_node); |
| 3943 | free_netdev(dev); | ||
| 3943 | 3944 | ||
| 3944 | return 0; | 3945 | return 0; |
| 3945 | } | 3946 | } |
| @@ -575,7 +575,14 @@ struct ucc_geth_tx_global_pram { · 574 unmodified lines | |||
| 575 | u32 vtagtable[0x8]; /* 8 4-byte VLAN tags */ | 575 | u32 vtagtable[0x8]; /* 8 4-byte VLAN tags */ |
| 576 | u32 tqptr; /* a base pointer to the Tx Queues Memory | 576 | u32 tqptr; /* a base pointer to the Tx Queues Memory |
| 577 | Region */ | 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 | } __packed; | 586 | } __packed; |
| 580 | 587 | ||
| 581 | /* structure representing Extended Filtering Global Parameters in PRAM */ | 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 | /* for mutl buffer*/ | 415 | /* for mutl buffer*/ |
| 416 | new_skb = skb_copy(skb, GFP_ATOMIC); | 416 | new_skb = skb_copy(skb, GFP_ATOMIC); |
| 417 | dev_kfree_skb_any(skb); | 417 | dev_kfree_skb_any(skb); |
| 418 | if (!new_skb) { | ||
| 419 | netdev_err(ndev, "skb alloc failed\n"); | ||
| 420 | return; | ||
| 421 | } | ||
| 418 | skb = new_skb; | 422 | skb = new_skb; |
| 419 | 423 | ||
| 420 | check_ok = 0; | 424 | check_ok = 0; |
| @@ -169,7 +169,7 @@ struct hclgevf_mbx_arq_ring { · 168 unmodified lines | |||
| 169 | #define hclge_mbx_ring_ptr_move_crq(crq) \ | 169 | #define hclge_mbx_ring_ptr_move_crq(crq) \ |
| 170 | (crq->next_to_use = (crq->next_to_use + 1) % crq->desc_num) | 170 | (crq->next_to_use = (crq->next_to_use + 1) % crq->desc_num) |
| 171 | #define hclge_mbx_tail_ptr_move_arq(arq) \ | 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 | #define hclge_mbx_head_ptr_move_arq(arq) \ | 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 | #endif | 175 | #endif |
| @@ -752,7 +752,8 @@ static int hclge_get_sset_count(struct hnae3_handle *handle, int stringset) · 751 unmodified lines | |||
| 752 | handle->flags |= HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK; | 752 | handle->flags |= HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK; |
| 753 | handle->flags |= HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK; | 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 | count += 1; | 757 | count += 1; |
| 757 | handle->flags |= HNAE3_SUPPORT_PHY_LOOPBACK; | 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 | req->ipv4_sctp_en = tuple_sets; | 4538 | req->ipv4_sctp_en = tuple_sets; |
| 4538 | break; | 4539 | break; |
| 4539 | case SCTP_V6_FLOW: | 4540 | case SCTP_V6_FLOW: |
| 4540 | if ((nfc->data & RXH_L4_B_0_1) || | 4541 | if (hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 && |
| 4541 | (nfc->data & RXH_L4_B_2_3)) | 4542 | (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3))) |
| 4542 | return -EINVAL; | 4543 | return -EINVAL; |
| 4543 | 4544 | ||
| 4544 | req->ipv6_sctp_en = tuple_sets; | 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 | vport[i].rss_tuple_sets.ipv6_udp_en = | 4731 | vport[i].rss_tuple_sets.ipv6_udp_en = |
| 4731 | HCLGE_RSS_INPUT_TUPLE_OTHER; | 4732 | HCLGE_RSS_INPUT_TUPLE_OTHER; |
| 4732 | vport[i].rss_tuple_sets.ipv6_sctp_en = | 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 | HCLGE_RSS_INPUT_TUPLE_SCTP; | 4736 | HCLGE_RSS_INPUT_TUPLE_SCTP; |
| 4734 | vport[i].rss_tuple_sets.ipv6_fragment_en = | 4737 | vport[i].rss_tuple_sets.ipv6_fragment_en = |
| 4735 | HCLGE_RSS_INPUT_TUPLE_OTHER; | 4738 | HCLGE_RSS_INPUT_TUPLE_OTHER; |
| @@ -107,6 +107,8 @@ · 106 unmodified lines | |||
| 107 | #define HCLGE_D_IP_BIT BIT(2) | 107 | #define HCLGE_D_IP_BIT BIT(2) |
| 108 | #define HCLGE_S_IP_BIT BIT(3) | 108 | #define HCLGE_S_IP_BIT BIT(3) |
| 109 | #define HCLGE_V_TAG_BIT BIT(4) | 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 | #define HCLGE_RSS_TC_SIZE_0 1 | 113 | #define HCLGE_RSS_TC_SIZE_0 1 |
| 112 | #define HCLGE_RSS_TC_SIZE_1 2 | 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 | req->ipv4_sctp_en = tuple_sets; | 917 | req->ipv4_sctp_en = tuple_sets; |
| 918 | break; | 918 | break; |
| 919 | case SCTP_V6_FLOW: | 919 | case SCTP_V6_FLOW: |
| 920 | if ((nfc->data & RXH_L4_B_0_1) || | 920 | if (hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 && |
| 921 | (nfc->data & RXH_L4_B_2_3)) | 921 | (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3))) |
| 922 | return -EINVAL; | 922 | return -EINVAL; |
| 923 | 923 | ||
| 924 | req->ipv6_sctp_en = tuple_sets; | 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 | tuple_sets->ipv4_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; | 2502 | tuple_sets->ipv4_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; |
| 2503 | tuple_sets->ipv6_tcp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; | 2503 | tuple_sets->ipv6_tcp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; |
| 2504 | tuple_sets->ipv6_udp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; | 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 | tuple_sets->ipv6_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; | 2509 | tuple_sets->ipv6_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; |
| 2507 | } | 2510 | } |
| 2508 | 2511 | ||
| @@ -122,6 +122,8 @@ · 121 unmodified lines | |||
| 122 | #define HCLGEVF_D_IP_BIT BIT(2) | 122 | #define HCLGEVF_D_IP_BIT BIT(2) |
| 123 | #define HCLGEVF_S_IP_BIT BIT(3) | 123 | #define HCLGEVF_S_IP_BIT BIT(3) |
| 124 | #define HCLGEVF_V_TAG_BIT BIT(4) | 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 | #define HCLGEVF_STATS_TIMER_INTERVAL 36U | 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 | release_rx_pools(adapter); | 955 | release_rx_pools(adapter); |
| 956 | 956 | ||
| 957 | release_napi(adapter); | 957 | release_napi(adapter); |
| 958 | release_login_buffer(adapter); | ||
| 958 | release_login_rsp_buffer(adapter); | 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 | set_current_state(TASK_UNINTERRUPTIBLE); | 2342 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 2342 | schedule_timeout(60 * HZ); | 2343 | schedule_timeout(60 * HZ); |
| 2343 | } | 2344 | } |
| 2344 | } else if (!(rwi->reset_reason == VNIC_RESET_FATAL && | 2345 | } else { |
| 2345 | adapter->from_passive_init)) { | ||
| 2346 | rc = do_reset(adapter, rwi, reset_state); | 2346 | rc = do_reset(adapter, rwi, reset_state); |
| 2347 | } | 2347 | } |
| 2348 | kfree(rwi); | 2348 | kfree(rwi); |
| @@ -2981,9 +2981,7 @@ static int reset_one_sub_crq_queue(struct ibmvnic_adapter *adapter, · 632 unmodified lines | |||
| 2981 | int rc; | 2981 | int rc; |
| 2982 | 2982 | ||
| 2983 | if (!scrq) { | 2983 | if (!scrq) { |
| 2984 | netdev_dbg(adapter->netdev, | 2984 | netdev_dbg(adapter->netdev, "Invalid scrq reset.\n"); |
| 2985 | "Invalid scrq reset. irq (%d) or msgs (%p).\n", | ||
| 2986 | scrq->irq, scrq->msgs); | ||
| 2987 | return -EINVAL; | 2985 | return -EINVAL; |
| 2988 | } | 2986 | } |
| 2989 | 2987 | ||
| @@ -3873,7 +3871,9 @@ static int send_login(struct ibmvnic_adapter *adapter) · 883 unmodified lines | |||
| 3873 | return -1; | 3871 | return -1; |
| 3874 | } | 3872 | } |
| 3875 | 3873 | ||
| 3874 | release_login_buffer(adapter); | ||
| 3876 | release_login_rsp_buffer(adapter); | 3875 | release_login_rsp_buffer(adapter); |
| 3876 | |||
| 3877 | client_data_len = vnic_client_data_len(adapter); | 3877 | client_data_len = vnic_client_data_len(adapter); |
| 3878 | 3878 | ||
| 3879 | buffer_size = | 3879 | buffer_size = |
| @@ -436,6 +436,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca); · 435 unmodified lines | |||
| 436 | #define FLAG2_DFLT_CRC_STRIPPING BIT(12) | 436 | #define FLAG2_DFLT_CRC_STRIPPING BIT(12) |
| 437 | #define FLAG2_CHECK_RX_HWTSTAMP BIT(13) | 437 | #define FLAG2_CHECK_RX_HWTSTAMP BIT(13) |
| 438 | #define FLAG2_CHECK_SYSTIM_OVERFLOW BIT(14) | 438 | #define FLAG2_CHECK_SYSTIM_OVERFLOW BIT(14) |
| 439 | #define FLAG2_ENABLE_S0IX_FLOWS BIT(15) | ||
| 439 | 440 | ||
| 440 | #define E1000_RX_DESC_PS(R, i) \ | 441 | #define E1000_RX_DESC_PS(R, i) \ |
| 441 | (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) | 442 | (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) |
| @@ -23,6 +23,13 @@ struct e1000_stats { · 22 unmodified lines | |||
| 23 | int stat_offset; | 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 | #define E1000_STAT(str, m) { \ | 33 | #define E1000_STAT(str, m) { \ |
| 27 | .stat_string = str, \ | 34 | .stat_string = str, \ |
| 28 | .type = E1000_STATS, \ | 35 | .type = E1000_STATS, \ |
| @@ -1776,6 +1783,8 @@ static int e1000e_get_sset_count(struct net_device __always_unused *netdev, · 1747 unmodified lines | |||
| 1776 | return E1000_TEST_LEN; | 1783 | return E1000_TEST_LEN; |
| 1777 | case ETH_SS_STATS: | 1784 | case ETH_SS_STATS: |
| 1778 | return E1000_STATS_LEN; | 1785 | return E1000_STATS_LEN; |
| 1786 | case ETH_SS_PRIV_FLAGS: | ||
| 1787 | return E1000E_PRIV_FLAGS_STR_LEN; | ||
| 1779 | default: | 1788 | default: |
| 1780 | return -EOPNOTSUPP; | 1789 | return -EOPNOTSUPP; |
| 1781 | } | 1790 | } |
| @@ -2097,6 +2106,10 @@ static void e1000_get_strings(struct net_device __always_unused *netdev, · 315 unmodified lines | |||
| 2097 | p += ETH_GSTRING_LEN; | 2106 | p += ETH_GSTRING_LEN; |
| 2098 | } | 2107 | } |
| 2099 | break; | 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 | return 0; | 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 | static const struct ethtool_ops e1000_ethtool_ops = { | 2352 | static const struct ethtool_ops e1000_ethtool_ops = { |
| 2309 | .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS, | 2353 | .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS, |
| 2310 | .get_drvinfo = e1000_get_drvinfo, | 2354 | .get_drvinfo = e1000_get_drvinfo, |
| @@ -2336,6 +2380,8 @@ static const struct ethtool_ops e1000_ethtool_ops = { · 25 unmodified lines | |||
| 2336 | .set_eee = e1000e_set_eee, | 2380 | .set_eee = e1000e_set_eee, |
| 2337 | .get_link_ksettings = e1000_get_link_ksettings, | 2381 | .get_link_ksettings = e1000_get_link_ksettings, |
| 2338 | .set_link_ksettings = e1000_set_link_ksettings, | 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 | void e1000e_set_ethtool_ops(struct net_device *netdev) | 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 | return 0; | 1240 | return 0; |
| 1241 | 1241 | ||
| 1242 | if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) { | 1242 | if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) { |
| 1243 | struct e1000_adapter *adapter = hw->adapter; | ||
| 1244 | bool firmware_bug = false; | ||
| 1245 | |||
| 1243 | if (force) { | 1246 | if (force) { |
| 1244 | /* Request ME un-configure ULP mode in the PHY */ | 1247 | /* Request ME un-configure ULP mode in the PHY */ |
| 1245 | mac_reg = er32(H2ME); | 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 | ew32(H2ME, mac_reg); | 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 | while (er32(FWSM) & E1000_FWSM_ULP_CFG_DONE) { | 1258 | while (er32(FWSM) & E1000_FWSM_ULP_CFG_DONE) { |
| 1253 | if (i++ == 30) { | 1259 | if (i++ == 250) { |
| 1254 | ret_val = -E1000_ERR_PHY; | 1260 | ret_val = -E1000_ERR_PHY; |
| 1255 | goto out; | 1261 | goto out; |
| 1256 | } | 1262 | } |
| 1263 | if (i > 100 && !firmware_bug) | ||
| 1264 | firmware_bug = true; | ||
| 1257 | 1265 | ||
| 1258 | usleep_range(10000, 11000); | 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 | if (force) { | 1273 | if (force) { |
| 1263 | mac_reg = er32(H2ME); | 1274 | mac_reg = er32(H2ME); |
| @@ -103,45 +103,6 @@ static const struct e1000_reg_info e1000_reg_info_tbl[] = { · 102 unmodified lines | |||
| 103 | {0, NULL} | 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 | * __ew32_prepare - prepare to write to MAC CSR register on certain parts | 107 | * __ew32_prepare - prepare to write to MAC CSR register on certain parts |
| 147 | * @hw: pointer to the HW structure | 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 | struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); | 6923 | struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); |
| 6963 | struct e1000_adapter *adapter = netdev_priv(netdev); | 6924 | struct e1000_adapter *adapter = netdev_priv(netdev); |
| 6964 | struct pci_dev *pdev = to_pci_dev(dev); | 6925 | struct pci_dev *pdev = to_pci_dev(dev); |
| 6965 | struct e1000_hw *hw = &adapter->hw; | ||
| 6966 | int rc; | 6926 | int rc; |
| 6967 | 6927 | ||
| 6968 | e1000e_flush_lpic(pdev); | 6928 | e1000e_flush_lpic(pdev); |
| @@ -6970,13 +6930,13 @@ static __maybe_unused int e1000e_pm_suspend(struct device *dev) · 1 unmodified line | |||
| 6970 | e1000e_pm_freeze(dev); | 6930 | e1000e_pm_freeze(dev); |
| 6971 | 6931 | ||
| 6972 | rc = __e1000_shutdown(pdev, false); | 6932 | rc = __e1000_shutdown(pdev, false); |
| 6973 | if (rc) | 6933 | if (rc) { |
| 6974 | e1000e_pm_thaw(dev); | 6934 | e1000e_pm_thaw(dev); |
| 6975 | 6935 | } else { | |
| 6976 | /* Introduce S0ix implementation */ | 6936 | /* Introduce S0ix implementation */ |
| 6977 | if (hw->mac.type >= e1000_pch_cnp && | 6937 | if (adapter->flags2 & FLAG2_ENABLE_S0IX_FLOWS) |
| 6978 | !e1000e_check_me(hw->adapter->pdev->device)) | 6938 | e1000e_s0ix_entry_flow(adapter); |
| 6979 | e1000e_s0ix_entry_flow(adapter); | 6939 | } |
| 6980 | 6940 | ||
| 6981 | return rc; | 6941 | return rc; |
| 6982 | } | 6942 | } |
| @@ -6986,12 +6946,10 @@ static __maybe_unused int e1000e_pm_resume(struct device *dev) · 3 unmodified lines | |||
| 6986 | struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); | 6946 | struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); |
| 6987 | struct e1000_adapter *adapter = netdev_priv(netdev); | 6947 | struct e1000_adapter *adapter = netdev_priv(netdev); |
| 6988 | struct pci_dev *pdev = to_pci_dev(dev); | 6948 | struct pci_dev *pdev = to_pci_dev(dev); |
| 6989 | struct e1000_hw *hw = &adapter->hw; | ||
| 6990 | int rc; | 6949 | int rc; |
| 6991 | 6950 | ||
| 6992 | /* Introduce S0ix implementation */ | 6951 | /* Introduce S0ix implementation */ |
| 6993 | if (hw->mac.type >= e1000_pch_cnp && | 6952 | if (adapter->flags2 & FLAG2_ENABLE_S0IX_FLOWS) |
| 6994 | !e1000e_check_me(hw->adapter->pdev->device)) | ||
| 6995 | e1000e_s0ix_exit_flow(adapter); | 6953 | e1000e_s0ix_exit_flow(adapter); |
| 6996 | 6954 | ||
| 6997 | rc = __e1000_resume(pdev); | 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 | if (!(adapter->flags & FLAG_HAS_AMT)) | 7613 | if (!(adapter->flags & FLAG_HAS_AMT)) |
| 7656 | e1000e_get_hw_control(adapter); | 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 | strlcpy(netdev->name, "eth%d", sizeof(netdev->name)); | 7619 | strlcpy(netdev->name, "eth%d", sizeof(netdev->name)); |
| 7659 | err = register_netdev(netdev); | 7620 | err = register_netdev(netdev); |
| 7660 | if (err) | 7621 | if (err) |
| @@ -120,6 +120,7 @@ enum i40e_state_t { · 119 unmodified lines | |||
| 120 | __I40E_RESET_INTR_RECEIVED, | 120 | __I40E_RESET_INTR_RECEIVED, |
| 121 | __I40E_REINIT_REQUESTED, | 121 | __I40E_REINIT_REQUESTED, |
| 122 | __I40E_PF_RESET_REQUESTED, | 122 | __I40E_PF_RESET_REQUESTED, |
| 123 | __I40E_PF_RESET_AND_REBUILD_REQUESTED, | ||
| 123 | __I40E_CORE_RESET_REQUESTED, | 124 | __I40E_CORE_RESET_REQUESTED, |
| 124 | __I40E_GLOBAL_RESET_REQUESTED, | 125 | __I40E_GLOBAL_RESET_REQUESTED, |
| 125 | __I40E_EMP_RESET_INTR_RECEIVED, | 126 | __I40E_EMP_RESET_INTR_RECEIVED, |
| @@ -146,6 +147,8 @@ enum i40e_state_t { · 20 unmodified lines | |||
| 146 | }; | 147 | }; |
| 147 | 148 | ||
| 148 | #define I40E_PF_RESET_FLAG BIT_ULL(__I40E_PF_RESET_REQUESTED) | 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 | /* VSI state flags */ | 153 | /* VSI state flags */ |
| 151 | enum i40e_vsi_state_t { | 154 | enum i40e_vsi_state_t { |
| @@ -36,6 +36,8 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf); · 35 unmodified lines | |||
| 36 | static void i40e_determine_queue_usage(struct i40e_pf *pf); | 36 | static void i40e_determine_queue_usage(struct i40e_pf *pf); |
| 37 | static int i40e_setup_pf_filter_control(struct i40e_pf *pf); | 37 | static int i40e_setup_pf_filter_control(struct i40e_pf *pf); |
| 38 | static void i40e_prep_for_reset(struct i40e_pf *pf, bool lock_acquired); | 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 | static int i40e_reset(struct i40e_pf *pf); | 41 | static int i40e_reset(struct i40e_pf *pf); |
| 40 | static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired); | 42 | static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired); |
| 41 | static int i40e_setup_misc_vector_for_recovery_mode(struct i40e_pf *pf); | 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 | "FW LLDP is disabled\n" : | 8538 | "FW LLDP is disabled\n" : |
| 8537 | "FW LLDP is enabled\n"); | 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 | } else if (reset_flags & BIT_ULL(__I40E_REINIT_REQUESTED)) { | 8549 | } else if (reset_flags & BIT_ULL(__I40E_REINIT_REQUESTED)) { |
| 8540 | int v; | 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 | if (num_vfs) { | 1772 | if (num_vfs) { |
| 1773 | if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) { | 1773 | if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) { |
| 1774 | pf->flags |= I40E_FLAG_VEB_MODE_ENABLED; | 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 | ret = i40e_pci_sriov_enable(pdev, num_vfs); | 1777 | ret = i40e_pci_sriov_enable(pdev, num_vfs); |
| 1778 | goto sriov_configure_out; | 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 | if (!pci_vfs_assigned(pf->pdev)) { | 1781 | if (!pci_vfs_assigned(pf->pdev)) { |
| 1782 | i40e_free_vfs(pf); | 1782 | i40e_free_vfs(pf); |
| 1783 | pf->flags &= ~I40E_FLAG_VEB_MODE_ENABLED; | 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 | } else { | 1785 | } else { |
| 1786 | dev_warn(&pdev->dev, "Unable to free VFs because some are assigned to VMs.\n"); | 1786 | dev_warn(&pdev->dev, "Unable to free VFs because some are assigned to VMs.\n"); |
| 1787 | ret = -EINVAL; | 1787 | ret = -EINVAL; |
| @@ -348,12 +348,12 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget) · 347 unmodified lines | |||
| 348 | * SBP is *not* set in PRT_SBPVSI (default not set). | 348 | * SBP is *not* set in PRT_SBPVSI (default not set). |
| 349 | */ | 349 | */ |
| 350 | skb = i40e_construct_skb_zc(rx_ring, *bi); | 350 | skb = i40e_construct_skb_zc(rx_ring, *bi); |
| 351 | *bi = NULL; | ||
| 352 | if (!skb) { | 351 | if (!skb) { |
| 353 | rx_ring->rx_stats.alloc_buff_failed++; | 352 | rx_ring->rx_stats.alloc_buff_failed++; |
| 354 | break; | 353 | break; |
| 355 | } | 354 | } |
| 356 | 355 | ||
| 356 | *bi = NULL; | ||
| 357 | cleaned_count++; | 357 | cleaned_count++; |
| 358 | i40e_inc_ntc(rx_ring); | 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 | netif_tx_stop_all_queues(netdev); | 1834 | netif_tx_stop_all_queues(netdev); |
| 1835 | if (CLIENT_ALLOWED(adapter)) { | 1835 | if (CLIENT_ALLOWED(adapter)) { |
| 1836 | err = iavf_lan_add_device(adapter); | 1836 | err = iavf_lan_add_device(adapter); |
| 1837 | if (err) { | 1837 | if (err) |
| 1838 | rtnl_unlock(); | ||
| 1839 | dev_info(&pdev->dev, "Failed to add VF to client API service list: %d\n", | 1838 | dev_info(&pdev->dev, "Failed to add VF to client API service list: %d\n", |
| 1840 | err); | 1839 | err); |
| 1841 | } | ||
| 1842 | } | 1840 | } |
| 1843 | dev_info(&pdev->dev, "MAC address: %pM\n", adapter->hw.mac.addr); | 1841 | dev_info(&pdev->dev, "MAC address: %pM\n", adapter->hw.mac.addr); |
| 1844 | if (netdev->features & NETIF_F_GRO) | 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 | struct bpf_prog *old_prog; | 4432 | struct bpf_prog *old_prog; |
| 4433 | 4433 | ||
| 4434 | if (prog && dev->mtu > MVNETA_MAX_RX_BUF_SIZE) { | 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 | return -EOPNOTSUPP; | 4436 | return -EOPNOTSUPP; |
| 4437 | } | 4437 | } |
| 4438 | 4438 | ||
| @@ -5255,7 +5255,7 @@ static int mvneta_probe(struct platform_device *pdev) · 816 unmodified lines | |||
| 5255 | err = mvneta_port_power_up(pp, pp->phy_interface); | 5255 | err = mvneta_port_power_up(pp, pp->phy_interface); |
| 5256 | if (err < 0) { | 5256 | if (err < 0) { |
| 5257 | dev_err(&pdev->dev, "can't power up port\n"); | 5257 | dev_err(&pdev->dev, "can't power up port\n"); |
| 5258 | return err; | 5258 | goto err_netdev; |
| 5259 | } | 5259 | } |
| 5260 | 5260 | ||
| 5261 | /* Armada3700 network controller does not support per-cpu | 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 | regmap_read(priv->sysctrl_base, GENCONF_CTRL0, &val); | 1232 | regmap_read(priv->sysctrl_base, GENCONF_CTRL0, &val); |
| 1233 | if (port->gop_id == 2) | 1233 | if (port->gop_id == 2) |
| 1234 | val |= GENCONF_CTRL0_PORT0_RGMII | GENCONF_CTRL0_PORT1_RGMII; | 1234 | val |= GENCONF_CTRL0_PORT0_RGMII; |
| 1235 | else if (port->gop_id == 3) | 1235 | else if (port->gop_id == 3) |
| 1236 | val |= GENCONF_CTRL0_PORT1_RGMII_MII; | 1236 | val |= GENCONF_CTRL0_PORT1_RGMII_MII; |
| 1237 | regmap_write(priv->sysctrl_base, GENCONF_CTRL0, val); | 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 | static void mvpp2_tx_pkts_coal_set(struct mvpp2_port *port, | 2370 | static void mvpp2_tx_pkts_coal_set(struct mvpp2_port *port, |
| 2371 | struct mvpp2_tx_queue *txq) | 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 | u32 val; | 2374 | u32 val; |
| 2375 | 2375 | ||
| 2376 | if (txq->done_pkts_coal > MVPP2_TXQ_THRESH_MASK) | 2376 | if (txq->done_pkts_coal > MVPP2_TXQ_THRESH_MASK) |
| 2377 | txq->done_pkts_coal = MVPP2_TXQ_THRESH_MASK; | 2377 | txq->done_pkts_coal = MVPP2_TXQ_THRESH_MASK; |
| 2378 | 2378 | ||
| 2379 | val = (txq->done_pkts_coal << MVPP2_TXQ_THRESH_OFFSET); | 2379 | val = (txq->done_pkts_coal << MVPP2_TXQ_THRESH_OFFSET); |
| 2380 | mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_NUM_REG, txq->id); | 2380 | /* PKT-coalescing registers are per-queue + per-thread */ |
| 2381 | mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_THRESH_REG, val); | 2381 | for (thread = 0; thread < MVPP2_MAX_THREADS; thread++) { |
| 2382 | 2382 | mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_NUM_REG, txq->id); | |
| 2383 | put_cpu(); | 2383 | mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_THRESH_REG, val); |
| 2384 | } | ||
| 2384 | } | 2385 | } |
| 2385 | 2386 | ||
| 2386 | static u32 mvpp2_usec_to_cycles(u32 usec, unsigned long clk_hz) | 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 | struct mvpp2 *priv = port->priv; | 5488 | struct mvpp2 *priv = port->priv; |
| 5488 | struct mvpp2_txq_pcpu *txq_pcpu; | 5489 | struct mvpp2_txq_pcpu *txq_pcpu; |
| 5489 | unsigned int thread; | 5490 | unsigned int thread; |
| 5490 | int queue, err; | 5491 | int queue, err, val; |
| 5491 | 5492 | ||
| 5492 | /* Checks for hardware constraints */ | 5493 | /* Checks for hardware constraints */ |
| 5493 | if (port->first_rxq + port->nrxqs > | 5494 | if (port->first_rxq + port->nrxqs > |
| @@ -5501,6 +5502,18 @@ static int mvpp2_port_init(struct mvpp2_port *port) · 7 unmodified lines | |||
| 5501 | mvpp2_egress_disable(port); | 5502 | mvpp2_egress_disable(port); |
| 5502 | mvpp2_port_disable(port); | 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 | port->tx_time_coal = MVPP2_TXDONE_COAL_USEC; | 5517 | port->tx_time_coal = MVPP2_TXDONE_COAL_USEC; |
| 5505 | 5518 | ||
| 5506 | port->txqs = devm_kcalloc(dev, port->ntxqs, sizeof(*port->txqs), | 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 | phylink_set(mask, Autoneg); | 5883 | phylink_set(mask, Autoneg); |
| 5871 | phylink_set_port_modes(mask); | 5884 | phylink_set_port_modes(mask); |
| 5872 | phylink_set(mask, Pause); | ||
| 5873 | phylink_set(mask, Asym_Pause); | ||
| 5874 | 5885 | ||
| 5875 | switch (state->interface) { | 5886 | switch (state->interface) { |
| 5876 | case PHY_INTERFACE_MODE_10GBASER: | 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 | return -EINVAL; | 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 | /* Enable/disable dropping all mac da's */ | 440 | /* Enable/disable dropping all mac da's */ |
| 409 | static void mvpp2_prs_mac_drop_all_set(struct mvpp2 *priv, int port, bool add) | 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 | mvpp2_prs_hw_write(priv, &pe); | 1194 | mvpp2_prs_hw_write(priv, &pe); |
| 1163 | 1195 | ||
| 1164 | /* Create dummy entries for drop all and promiscuous modes */ | 1196 | /* Create dummy entries for drop all and promiscuous modes */ |
| 1197 | mvpp2_prs_drop_fc(priv); | ||
| 1165 | mvpp2_prs_mac_drop_all_set(priv, 0, false); | 1198 | mvpp2_prs_mac_drop_all_set(priv, 0, false); |
| 1166 | mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_UNI_CAST, false); | 1199 | mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_UNI_CAST, false); |
| 1167 | mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_MULTI_CAST, false); | 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 | mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6); | 1680 | mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6); |
| 1648 | mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP6, | 1681 | mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP6, |
| 1649 | MVPP2_PRS_RI_L3_PROTO_MASK); | 1682 | MVPP2_PRS_RI_L3_PROTO_MASK); |
| 1650 | /* Skip eth_type + 4 bytes of IPv6 header */ | 1683 | /* Jump to DIP of IPV6 header */ |
| 1651 | mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 4, | 1684 | mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 8 + |
| 1685 | MVPP2_MAX_L3_ADDR_SIZE, | ||
| 1652 | MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); | 1686 | MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); |
| 1653 | /* Set L3 offset */ | 1687 | /* Set L3 offset */ |
| 1654 | mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, | 1688 | mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, |
| @@ -129,7 +129,7 @@ · 128 unmodified lines | |||
| 129 | #define MVPP2_PE_VID_EDSA_FLTR_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 7) | 129 | #define MVPP2_PE_VID_EDSA_FLTR_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 7) |
| 130 | #define MVPP2_PE_VLAN_DBL (MVPP2_PRS_TCAM_SRAM_SIZE - 6) | 130 | #define MVPP2_PE_VLAN_DBL (MVPP2_PRS_TCAM_SRAM_SIZE - 6) |
| 131 | #define MVPP2_PE_VLAN_NONE (MVPP2_PRS_TCAM_SRAM_SIZE - 5) | 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 | #define MVPP2_PE_MAC_MC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 3) | 133 | #define MVPP2_PE_MAC_MC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 3) |
| 134 | #define MVPP2_PE_MAC_UC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 2) | 134 | #define MVPP2_PE_MAC_UC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 2) |
| 135 | #define MVPP2_PE_MAC_NON_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 1) | 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 | if (!lmac) | 871 | if (!lmac) |
| 872 | return -ENOMEM; | 872 | return -ENOMEM; |
| 873 | lmac->name = kcalloc(1, sizeof("cgx_fwi_xxx_yyy"), GFP_KERNEL); | 873 | lmac->name = kcalloc(1, sizeof("cgx_fwi_xxx_yyy"), GFP_KERNEL); |
| 874 | if (!lmac->name) | 874 | if (!lmac->name) { |
| 875 | return -ENOMEM; | 875 | err = -ENOMEM; |
| 876 | goto err_lmac_free; | ||
| 877 | } | ||
| 876 | sprintf(lmac->name, "cgx_fwi_%d_%d", cgx->cgx_id, i); | 878 | sprintf(lmac->name, "cgx_fwi_%d_%d", cgx->cgx_id, i); |
| 877 | lmac->lmac_id = i; | 879 | lmac->lmac_id = i; |
| 878 | lmac->cgx = cgx; | 880 | lmac->cgx = cgx; |
| @@ -883,7 +885,7 @@ static int cgx_lmac_init(struct cgx *cgx) · 4 unmodified lines | |||
| 883 | CGX_LMAC_FWI + i * 9), | 885 | CGX_LMAC_FWI + i * 9), |
| 884 | cgx_fwi_event_handler, 0, lmac->name, lmac); | 886 | cgx_fwi_event_handler, 0, lmac->name, lmac); |
| 885 | if (err) | 887 | if (err) |
| 886 | return err; | 888 | goto err_irq; |
| 887 | 889 | ||
| 888 | /* Enable interrupt */ | 890 | /* Enable interrupt */ |
| 889 | cgx_write(cgx, lmac->lmac_id, CGXX_CMRX_INT_ENA_W1S, | 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 | return cgx_lmac_verify_fwi_version(cgx); | 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 | static int cgx_lmac_exit(struct cgx *cgx) | 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 | if (!reg_c0) | 626 | if (!reg_c0) |
| 627 | return true; | 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 | priv = netdev_priv(skb->dev); | 634 | priv = netdev_priv(skb->dev); |
| 630 | esw = priv->mdev->priv.eswitch; | 635 | esw = priv->mdev->priv.eswitch; |
| 631 | 636 | ||
| @@ -118,16 +118,17 @@ struct mlx5_ct_tuple { · 117 unmodified lines | |||
| 118 | u16 zone; | 118 | u16 zone; |
| 119 | }; | 119 | }; |
| 120 | 120 | ||
| 121 | struct mlx5_ct_shared_counter { | 121 | struct mlx5_ct_counter { |
| 122 | struct mlx5_fc *counter; | 122 | struct mlx5_fc *counter; |
| 123 | refcount_t refcount; | 123 | refcount_t refcount; |
| 124 | bool is_shared; | ||
| 124 | }; | 125 | }; |
| 125 | 126 | ||
| 126 | struct mlx5_ct_entry { | 127 | struct mlx5_ct_entry { |
| 127 | struct rhash_head node; | 128 | struct rhash_head node; |
| 128 | struct rhash_head tuple_node; | 129 | struct rhash_head tuple_node; |
| 129 | struct rhash_head tuple_nat_node; | 130 | struct rhash_head tuple_nat_node; |
| 130 | struct mlx5_ct_shared_counter *shared_counter; | 131 | struct mlx5_ct_counter *counter; |
| 131 | unsigned long cookie; | 132 | unsigned long cookie; |
| 132 | unsigned long restore_cookie; | 133 | unsigned long restore_cookie; |
| 133 | struct mlx5_ct_tuple tuple; | 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 | static void | 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 | return; | 402 | return; |
| 401 | 403 | ||
| 402 | mlx5_fc_destroy(ct_priv->dev, entry->shared_counter->counter); | 404 | mlx5_fc_destroy(ct_priv->dev, entry->counter->counter); |
| 403 | kfree(entry->shared_counter); | 405 | kfree(entry->counter); |
| 404 | } | 406 | } |
| 405 | 407 | ||
| 406 | static void | 408 | static void |
| @@ -699,7 +701,7 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv, · 292 unmodified lines | |||
| 699 | attr->dest_ft = ct_priv->post_ct; | 701 | attr->dest_ft = ct_priv->post_ct; |
| 700 | attr->ft = nat ? ct_priv->ct_nat : ct_priv->ct; | 702 | attr->ft = nat ? ct_priv->ct_nat : ct_priv->ct; |
| 701 | attr->outer_match_level = MLX5_MATCH_L4; | 703 | attr->outer_match_level = MLX5_MATCH_L4; |
| 702 | attr->counter = entry->shared_counter->counter; | 704 | attr->counter = entry->counter->counter; |
| 703 | attr->flags |= MLX5_ESW_ATTR_FLAG_NO_IN_PORT; | 705 | attr->flags |= MLX5_ESW_ATTR_FLAG_NO_IN_PORT; |
| 704 | 706 | ||
| 705 | mlx5_tc_ct_set_tuple_match(netdev_priv(ct_priv->netdev), spec, flow_rule); | 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 | return err; | 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 | mlx5_tc_ct_shared_counter_get(struct mlx5_tc_ct_priv *ct_priv, | 760 | mlx5_tc_ct_shared_counter_get(struct mlx5_tc_ct_priv *ct_priv, |
| 737 | struct mlx5_ct_entry *entry) | 761 | struct mlx5_ct_entry *entry) |
| 738 | { | 762 | { |
| 739 | struct mlx5_ct_tuple rev_tuple = entry->tuple; | 763 | struct mlx5_ct_tuple rev_tuple = entry->tuple; |
| 740 | struct mlx5_ct_shared_counter *shared_counter; | 764 | struct mlx5_ct_counter *shared_counter; |
| 741 | struct mlx5_core_dev *dev = ct_priv->dev; | ||
| 742 | struct mlx5_ct_entry *rev_entry; | 765 | struct mlx5_ct_entry *rev_entry; |
| 743 | __be16 tmp_port; | 766 | __be16 tmp_port; |
| 744 | int ret; | 767 | int ret; |
| @@ -767,25 +790,20 @@ mlx5_tc_ct_shared_counter_get(struct mlx5_tc_ct_priv *ct_priv, · 22 unmodified lines | |||
| 767 | rev_entry = rhashtable_lookup_fast(&ct_priv->ct_tuples_ht, &rev_tuple, | 790 | rev_entry = rhashtable_lookup_fast(&ct_priv->ct_tuples_ht, &rev_tuple, |
| 768 | tuples_ht_params); | 791 | tuples_ht_params); |
| 769 | if (rev_entry) { | 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 | mutex_unlock(&ct_priv->shared_counter_lock); | 794 | mutex_unlock(&ct_priv->shared_counter_lock); |
| 772 | return rev_entry->shared_counter; | 795 | return rev_entry->counter; |
| 773 | } | 796 | } |
| 774 | } | 797 | } |
| 775 | mutex_unlock(&ct_priv->shared_counter_lock); | 798 | mutex_unlock(&ct_priv->shared_counter_lock); |
| 776 | 799 | ||
| 777 | shared_counter = kzalloc(sizeof(*shared_counter), GFP_KERNEL); | 800 | shared_counter = mlx5_tc_ct_counter_create(ct_priv); |
| 778 | if (!shared_counter) | 801 | if (IS_ERR(shared_counter)) { |
| 779 | return ERR_PTR(-ENOMEM); | 802 | ret = PTR_ERR(shared_counter); |
| 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); | ||
| 786 | return ERR_PTR(ret); | 803 | return ERR_PTR(ret); |
| 787 | } | 804 | } |
| 788 | 805 | ||
| 806 | shared_counter->is_shared = true; | ||
| 789 | refcount_set(&shared_counter->refcount, 1); | 807 | refcount_set(&shared_counter->refcount, 1); |
| 790 | return shared_counter; | 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 | int err; | 817 | int err; |
| 800 | 818 | ||
| 801 | entry->shared_counter = mlx5_tc_ct_shared_counter_get(ct_priv, entry); | 819 | if (nf_ct_acct_enabled(dev_net(ct_priv->netdev))) |
| 802 | if (IS_ERR(entry->shared_counter)) { | 820 | entry->counter = mlx5_tc_ct_counter_create(ct_priv); |
| 803 | err = PTR_ERR(entry->shared_counter); | 821 | else |
| 804 | ct_dbg("Failed to create counter for ct entry"); | 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 | return err; | 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 | err_nat: | 841 | err_nat: |
| 821 | mlx5_tc_ct_entry_del_rule(ct_priv, entry, false); | 842 | mlx5_tc_ct_entry_del_rule(ct_priv, entry, false); |
| 822 | err_orig: | 843 | err_orig: |
| 823 | mlx5_tc_ct_shared_counter_put(ct_priv, entry); | 844 | mlx5_tc_ct_counter_put(ct_priv, entry); |
| 824 | return err; | 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 | rhashtable_remove_fast(&ct_priv->ct_tuples_ht, &entry->tuple_node, | 939 | rhashtable_remove_fast(&ct_priv->ct_tuples_ht, &entry->tuple_node, |
| 919 | tuples_ht_params); | 940 | tuples_ht_params); |
| 920 | mutex_unlock(&ct_priv->shared_counter_lock); | 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 | if (!entry) | 977 | if (!entry) |
| 957 | return -ENOENT; | 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 | flow_stats_update(&f->stats, bytes, packets, 0, lastuse, | 981 | flow_stats_update(&f->stats, bytes, packets, 0, lastuse, |
| 961 | FLOW_ACTION_HW_STATS_DELAYED); | 982 | FLOW_ACTION_HW_STATS_DELAYED); |
| 962 | 983 | ||
| @@ -371,6 +371,15 @@ struct mlx5e_swp_spec { · 370 unmodified lines | |||
| 371 | u8 tun_l4_proto; | 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 | static inline void | 383 | static inline void |
| 375 | mlx5e_set_eseg_swp(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg, | 384 | mlx5e_set_eseg_swp(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg, |
| 376 | struct mlx5e_swp_spec *swp_spec) | 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 | static inline void | 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 | struct mlx5e_swp_spec swp_spec = {}; | 56 | struct mlx5e_swp_spec swp_spec = {}; |
| 57 | unsigned int offset = 0; | 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 | mlx5e_set_eseg_swp(skb, eseg, &swp_spec); | 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 | #else | 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 | static inline bool mlx5e_accel_tx_eseg(struct mlx5e_priv *priv, | 166 | static inline bool mlx5e_accel_tx_eseg(struct mlx5e_priv *priv, |
| 165 | struct sk_buff *skb, | 167 | struct sk_buff *skb, |
| 166 | struct mlx5_wqe_eth_seg *eseg) | 168 | struct mlx5_wqe_eth_seg *eseg, u16 ihs) |
| 167 | { | 169 | { |
| 168 | #ifdef CONFIG_MLX5_EN_IPSEC | 170 | #ifdef CONFIG_MLX5_EN_IPSEC |
| 169 | if (xfrm_offload(skb)) | 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 | #if IS_ENABLED(CONFIG_GENEVE) | 175 | #if IS_ENABLED(CONFIG_GENEVE) |
| 174 | if (skb->encapsulation) | 176 | if (skb->encapsulation) |
| 175 | mlx5e_tx_tunnel_accel(skb, eseg); | 177 | mlx5e_tx_tunnel_accel(skb, eseg, ihs); |
| 176 | #endif | 178 | #endif |
| 177 | 179 | ||
| 178 | return true; | 180 | return true; |
| @@ -1010,6 +1010,22 @@ static int mlx5e_get_link_ksettings(struct net_device *netdev, · 1009 unmodified lines | |||
| 1010 | return mlx5e_ethtool_get_link_ksettings(priv, link_ksettings); | 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 | static u32 mlx5e_ethtool2ptys_adver_link(const unsigned long *link_modes) | 1029 | static u32 mlx5e_ethtool2ptys_adver_link(const unsigned long *link_modes) |
| 1014 | { | 1030 | { |
| 1015 | u32 i, ptys_modes = 0; | 1031 | u32 i, ptys_modes = 0; |
| @@ -1103,13 +1119,9 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, · 87 unmodified lines | |||
| 1103 | link_modes = autoneg == AUTONEG_ENABLE ? ethtool2ptys_adver_func(adver) : | 1119 | link_modes = autoneg == AUTONEG_ENABLE ? ethtool2ptys_adver_func(adver) : |
| 1104 | mlx5e_port_speed2linkmodes(mdev, speed, !ext); | 1120 | mlx5e_port_speed2linkmodes(mdev, speed, !ext); |
| 1105 | 1121 | ||
| 1106 | if ((link_modes & MLX5E_PROT_MASK(MLX5E_56GBASE_R4)) && | 1122 | err = mlx5e_speed_validate(priv->netdev, ext, link_modes, autoneg); |
| 1107 | autoneg != AUTONEG_ENABLE) { | 1123 | if (err) |
| 1108 | netdev_err(priv->netdev, "%s: 56G link speed requires autoneg enabled\n", | ||
| 1109 | __func__); | ||
| 1110 | err = -EINVAL; | ||
| 1111 | goto out; | 1124 | goto out; |
| 1112 | } | ||
| 1113 | 1125 | ||
| 1114 | link_modes = link_modes & eproto.cap; | 1126 | link_modes = link_modes & eproto.cap; |
| 1115 | if (!link_modes) { | 1127 | if (!link_modes) { |
| @@ -942,6 +942,7 @@ static int mlx5e_create_ttc_table_groups(struct mlx5e_ttc_table *ttc, · 941 unmodified lines | |||
| 942 | in = kvzalloc(inlen, GFP_KERNEL); | 942 | in = kvzalloc(inlen, GFP_KERNEL); |
| 943 | if (!in) { | 943 | if (!in) { |
| 944 | kfree(ft->g); | 944 | kfree(ft->g); |
| 945 | ft->g = NULL; | ||
| 945 | return -ENOMEM; | 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 | in = kvzalloc(inlen, GFP_KERNEL); | 1088 | in = kvzalloc(inlen, GFP_KERNEL); |
| 1088 | if (!in) { | 1089 | if (!in) { |
| 1089 | kfree(ft->g); | 1090 | kfree(ft->g); |
| 1091 | ft->g = NULL; | ||
| 1090 | return -ENOMEM; | 1092 | return -ENOMEM; |
| 1091 | } | 1093 | } |
| 1092 | 1094 | ||
| @@ -1390,6 +1392,7 @@ err_destroy_groups: · 297 unmodified lines | |||
| 1390 | ft->g[ft->num_groups] = NULL; | 1392 | ft->g[ft->num_groups] = NULL; |
| 1391 | mlx5e_destroy_groups(ft); | 1393 | mlx5e_destroy_groups(ft); |
| 1392 | kvfree(in); | 1394 | kvfree(in); |
| 1395 | kfree(ft->g); | ||
| 1393 | 1396 | ||
| 1394 | return err; | 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 | mlx5_set_port_admin_status(mdev, state); | 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 | return; | 3166 | return; |
| 3166 | 3167 | ||
| 3167 | if (state == MLX5_PORT_UP) | 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 | static bool mlx5e_txwqe_build_eseg(struct mlx5e_priv *priv, struct mlx5e_txqsq *sq, | 683 | static bool mlx5e_txwqe_build_eseg(struct mlx5e_priv *priv, struct mlx5e_txqsq *sq, |
| 684 | struct sk_buff *skb, struct mlx5e_accel_tx_state *accel, | 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 | return false; | 688 | return false; |
| 689 | 689 | ||
| 690 | mlx5e_txwqe_build_eseg_csum(sq, skb, accel, eseg); | 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 | if (mlx5e_tx_skb_supports_mpwqe(skb, &attr)) { | 714 | if (mlx5e_tx_skb_supports_mpwqe(skb, &attr)) { |
| 715 | struct mlx5_wqe_eth_seg eseg = {}; | 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 | return NETDEV_TX_OK; | 719 | return NETDEV_TX_OK; |
| 719 | 720 | ||
| 720 | mlx5e_sq_xmit_mpwqe(sq, skb, &eseg, netdev_xmit_more()); | 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 | /* May update the WQE, but may not post other WQEs. */ | 732 | /* May update the WQE, but may not post other WQEs. */ |
| 732 | mlx5e_accel_tx_finish(sq, wqe, &accel, | 733 | mlx5e_accel_tx_finish(sq, wqe, &accel, |
| 733 | (struct mlx5_wqe_inline_seg *)(wqe->data + wqe_attr.ds_cnt_inl)); | 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 | return NETDEV_TX_OK; | 736 | return NETDEV_TX_OK; |
| 736 | 737 | ||
| 737 | mlx5e_sq_xmit_wqe(sq, skb, &attr, &wqe_attr, wqe, pi, netdev_xmit_more()); | 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 | return 0; | 95 | return 0; |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | if (!IS_ERR_OR_NULL(vport->egress.acl)) | 98 | if (!vport->egress.acl) { |
| 99 | return 0; | 99 | vport->egress.acl = esw_acl_table_create(esw, vport->vport, |
| 100 | 100 | MLX5_FLOW_NAMESPACE_ESW_EGRESS, | |
| 101 | vport->egress.acl = esw_acl_table_create(esw, vport->vport, | 101 | table_size); |
| 102 | MLX5_FLOW_NAMESPACE_ESW_EGRESS, | 102 | if (IS_ERR(vport->egress.acl)) { |
| 103 | table_size); | 103 | err = PTR_ERR(vport->egress.acl); |
| 104 | if (IS_ERR(vport->egress.acl)) { | 104 | vport->egress.acl = NULL; |
| 105 | err = PTR_ERR(vport->egress.acl); | 105 | goto out; |
| 106 | vport->egress.acl = NULL; | 106 | } |
| 107 | goto out; | 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 | esw_debug(esw->dev, | 113 | esw_debug(esw->dev, |
| 115 | "vport[%d] configure egress rules, vlan(%d) qos(%d)\n", | 114 | "vport[%d] configure egress rules, vlan(%d) qos(%d)\n", |
| 116 | vport->vport, vport->info.vlan, vport->info.qos); | 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 | struct mlx5_core_dev *tmp_dev; | 564 | struct mlx5_core_dev *tmp_dev; |
| 565 | int i, err; | 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 | return; | 570 | return; |
| 569 | 571 | ||
| 570 | tmp_dev = mlx5_get_next_phys_dev(dev); | 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 | if (mlx5_lag_dev_add_pf(ldev, dev, netdev) < 0) | 584 | if (mlx5_lag_dev_add_pf(ldev, dev, netdev) < 0) |
| 583 | return; | 585 | return; |
| 584 | 586 | ||
| 585 | for (i = 0; i < MLX5_MAX_PORTS; i++) { | 587 | for (i = 0; i < MLX5_MAX_PORTS; i++) |
| 586 | tmp_dev = ldev->pf[i].dev; | 588 | if (!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) | ||
| 589 | break; | 589 | break; |
| 590 | } | ||
| 591 | 590 | ||
| 592 | if (i >= MLX5_MAX_PORTS) | 591 | if (i >= MLX5_MAX_PORTS) |
| 593 | ldev->flags |= MLX5_LAG_FLAG_READY; | 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 | MLX5_COREDEV_VF : MLX5_COREDEV_PF; | 1368 | MLX5_COREDEV_VF : MLX5_COREDEV_PF; |
| 1369 | 1369 | ||
| 1370 | dev->priv.adev_idx = mlx5_adev_idx_alloc(); | 1370 | dev->priv.adev_idx = mlx5_adev_idx_alloc(); |
| 1371 | if (dev->priv.adev_idx < 0) | 1371 | if (dev->priv.adev_idx < 0) { |
| 1372 | return dev->priv.adev_idx; | 1372 | err = dev->priv.adev_idx; |
| 1373 | goto adev_init_err; | ||
| 1374 | } | ||
| 1373 | 1375 | ||
| 1374 | err = mlx5_mdev_init(dev, prof_sel); | 1376 | err = mlx5_mdev_init(dev, prof_sel); |
| 1375 | if (err) | 1377 | if (err) |
| @@ -1403,6 +1405,7 @@ pci_init_err: · 27 unmodified lines | |||
| 1403 | mlx5_mdev_uninit(dev); | 1405 | mlx5_mdev_uninit(dev); |
| 1404 | mdev_init_err: | 1406 | mdev_init_err: |
| 1405 | mlx5_adev_idx_free(dev->priv.adev_idx); | 1407 | mlx5_adev_idx_free(dev->priv.adev_idx); |
| 1408 | adev_init_err: | ||
| 1406 | mlx5_devlink_free(devlink); | 1409 | mlx5_devlink_free(devlink); |
| 1407 | 1410 | ||
| 1408 | return err; | 1411 | return err; |
| @@ -116,7 +116,7 @@ free: · 115 unmodified lines | |||
| 116 | static void mlx5_rdma_del_roce_addr(struct mlx5_core_dev *dev) | 116 | static void mlx5_rdma_del_roce_addr(struct mlx5_core_dev *dev) |
| 117 | { | 117 | { |
| 118 | mlx5_core_roce_gid_set(dev, 0, 0, 0, | 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 | static void mlx5_rdma_make_default_gid(struct mlx5_core_dev *dev, union ib_gid *gid) | 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 | #define MLXSW_THERMAL_ASIC_TEMP_NORM 75000 /* 75C */ | 19 | #define MLXSW_THERMAL_ASIC_TEMP_NORM 75000 /* 75C */ |
| 20 | #define MLXSW_THERMAL_ASIC_TEMP_HIGH 85000 /* 85C */ | 20 | #define MLXSW_THERMAL_ASIC_TEMP_HIGH 85000 /* 85C */ |
| 21 | #define MLXSW_THERMAL_ASIC_TEMP_HOT 105000 /* 105C */ | 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 | #define MLXSW_THERMAL_HYSTERESIS_TEMP 5000 /* 5C */ | 23 | #define MLXSW_THERMAL_HYSTERESIS_TEMP 5000 /* 5C */ |
| 24 | #define MLXSW_THERMAL_MODULE_TEMP_SHIFT (MLXSW_THERMAL_HYSTERESIS_TEMP * 2) | 24 | #define MLXSW_THERMAL_MODULE_TEMP_SHIFT (MLXSW_THERMAL_HYSTERESIS_TEMP * 2) |
| 25 | #define MLXSW_THERMAL_ZONE_MAX_NAME 16 | 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 | if (err) | 176 | if (err) |
| 177 | return err; | 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 | /* According to the system thermal requirements, the thermal zones are | 185 | /* According to the system thermal requirements, the thermal zones are |
| 180 | * defined with four trip points. The critical and emergency | 186 | * defined with four trip points. The critical and emergency |
| 181 | * temperature thresholds, provided by QSFP module are set as "active" | 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 | tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp = crit_temp; | 196 | tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp = crit_temp; |
| 191 | tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temp = crit_temp; | 197 | tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temp = crit_temp; |
| 192 | tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temp = emerg_temp; | 198 | tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temp = emerg_temp; |
| 193 | if (emerg_temp > crit_temp) | 199 | tz->trips[MLXSW_THERMAL_TEMP_TRIP_CRIT].temp = emerg_temp + |
| 194 | tz->trips[MLXSW_THERMAL_TEMP_TRIP_CRIT].temp = emerg_temp + | ||
| 195 | MLXSW_THERMAL_MODULE_TEMP_SHIFT; | 200 | MLXSW_THERMAL_MODULE_TEMP_SHIFT; |
| 196 | else | ||
| 197 | tz->trips[MLXSW_THERMAL_TEMP_TRIP_CRIT].temp = emerg_temp; | ||
| 198 | 201 | ||
| 199 | return 0; | 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 | err = register_netdev(dev); | 507 | err = register_netdev(dev); |
| 508 | if (err) | 508 | if (err) |
| 509 | goto out; | 509 | goto undo_probe; |
| 510 | 510 | ||
| 511 | return 0; | 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 | out: | 517 | out: |
| 514 | free_netdev(dev); | 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 | err = register_netdev(ndev); | 589 | err = register_netdev(ndev); |
| 586 | if (err) | 590 | if (err) |
| 587 | goto out; | 591 | goto undo_probe; |
| 588 | 592 | ||
| 589 | nubus_set_drvdata(board, ndev); | 593 | nubus_set_drvdata(board, ndev); |
| 590 | 594 | ||
| 591 | return 0; | 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 | out: | 601 | out: |
| 594 | free_netdev(ndev); | 602 | free_netdev(ndev); |
| 595 | return err; | 603 | return err; |
| @@ -229,11 +229,14 @@ int xtsonic_probe(struct platform_device *pdev) · 228 unmodified lines | |||
| 229 | sonic_msg_init(dev); | 229 | sonic_msg_init(dev); |
| 230 | 230 | ||
| 231 | if ((err = register_netdev(dev))) | 231 | if ((err = register_netdev(dev))) |
| 232 | goto out1; | 232 | goto undo_probe1; |
| 233 | 233 | ||
| 234 | return 0; | 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 | release_region(dev->base_addr, SONIC_MEM_SIZE); | 240 | release_region(dev->base_addr, SONIC_MEM_SIZE); |
| 238 | out: | 241 | out: |
| 239 | free_netdev(dev); | 242 | free_netdev(dev); |
| @@ -337,7 +337,7 @@ void ionic_rx_fill(struct ionic_queue *q) · 336 unmodified lines | |||
| 337 | unsigned int i, j; | 337 | unsigned int i, j; |
| 338 | unsigned int len; | 338 | unsigned int len; |
| 339 | 339 | ||
| 340 | len = netdev->mtu + ETH_HLEN; | 340 | len = netdev->mtu + ETH_HLEN + VLAN_HLEN; |
| 341 | nfrags = round_up(len, PAGE_SIZE) / PAGE_SIZE; | 341 | nfrags = round_up(len, PAGE_SIZE) / PAGE_SIZE; |
| 342 | 342 | ||
| 343 | for (i = ionic_q_space_avail(q); i; i--) { | 343 | for (i = ionic_q_space_avail(q); i; i--) { |
| @@ -78,6 +78,7 @@ config QED · 77 unmodified lines | |||
| 78 | depends on PCI | 78 | depends on PCI |
| 79 | select ZLIB_INFLATE | 79 | select ZLIB_INFLATE |
| 80 | select CRC8 | 80 | select CRC8 |
| 81 | select CRC32 | ||
| 81 | select NET_DEVLINK | 82 | select NET_DEVLINK |
| 82 | help | 83 | help |
| 83 | This enables the support for Marvell FastLinQ adapters family. | 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 | .ndo_set_features = netxen_set_features, | 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 | static inline void netxen_set_interrupt_mode(struct netxen_adapter *adapter, | 567 | static inline void netxen_set_interrupt_mode(struct netxen_adapter *adapter, |
| 573 | u32 mode) | 568 | u32 mode) |
| 574 | { | 569 | { |
| @@ -664,7 +659,7 @@ static int netxen_setup_intr(struct netxen_adapter *adapter) · 89 unmodified lines | |||
| 664 | netxen_initialize_interrupt_registers(adapter); | 659 | netxen_initialize_interrupt_registers(adapter); |
| 665 | netxen_set_msix_bit(pdev, 0); | 660 | netxen_set_msix_bit(pdev, 0); |
| 666 | 661 | ||
| 667 | if (netxen_function_zero(pdev)) { | 662 | if (adapter->portnum == 0) { |
| 668 | if (!netxen_setup_msi_interrupts(adapter, num_msix)) | 663 | if (!netxen_setup_msi_interrupts(adapter, num_msix)) |
| 669 | netxen_set_interrupt_mode(adapter, NETXEN_MSI_MODE); | 664 | netxen_set_interrupt_mode(adapter, NETXEN_MSI_MODE); |
| 670 | else | 665 | else |
| @@ -1799,6 +1799,11 @@ netdev_features_t qede_features_check(struct sk_buff *skb, · 1798 unmodified lines | |||
| 1799 | ntohs(udp_hdr(skb)->dest) != gnv_port)) | 1799 | ntohs(udp_hdr(skb)->dest) != gnv_port)) |
| 1800 | return features & ~(NETIF_F_CSUM_MASK | | 1800 | return features & ~(NETIF_F_CSUM_MASK | |
| 1801 | NETIF_F_GSO_MASK); | 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 | switch (tp->mac_version) { | 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 | case RTL_GIGA_MAC_VER_37: | 2212 | case RTL_GIGA_MAC_VER_37: |
| 2212 | case RTL_GIGA_MAC_VER_39: | 2213 | case RTL_GIGA_MAC_VER_39: |
| 2213 | case RTL_GIGA_MAC_VER_43: | 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 | static void rtl_pll_power_up(struct rtl8169_private *tp) | 2234 | static void rtl_pll_power_up(struct rtl8169_private *tp) |
| 2234 | { | 2235 | { |
| 2235 | switch (tp->mac_version) { | 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 | case RTL_GIGA_MAC_VER_37: | 2239 | case RTL_GIGA_MAC_VER_37: |
| 2238 | case RTL_GIGA_MAC_VER_39: | 2240 | case RTL_GIGA_MAC_VER_39: |
| 2239 | case RTL_GIGA_MAC_VER_43: | 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 | #define PCI_DEVICE_ID_INTEL_EHL_PSE1_RGMII1G_ID 0x4bb0 | 721 | #define PCI_DEVICE_ID_INTEL_EHL_PSE1_RGMII1G_ID 0x4bb0 |
| 722 | #define PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII1G_ID 0x4bb1 | 722 | #define PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII1G_ID 0x4bb1 |
| 723 | #define PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII2G5_ID 0x4bb2 | 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 | #define PCI_DEVICE_ID_INTEL_TGL_SGMII1G_ID 0xa0ac | 726 | #define PCI_DEVICE_ID_INTEL_TGL_SGMII1G_ID 0xa0ac |
| 725 | 727 | ||
| 726 | static const struct pci_device_id intel_eth_pci_id_table[] = { | 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 | { PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII1G_ID, &ehl_pse1_sgmii1g_info) }, | 737 | { PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII1G_ID, &ehl_pse1_sgmii1g_info) }, |
| 736 | { PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII2G5_ID, &ehl_pse1_sgmii1g_info) }, | 738 | { PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII2G5_ID, &ehl_pse1_sgmii1g_info) }, |
| 737 | { PCI_DEVICE_DATA(INTEL, TGL_SGMII1G_ID, &tgl_sgmii1g_info) }, | 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 | MODULE_DEVICE_TABLE(pci, intel_eth_pci_id_table); | 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 | struct device *dev = dwmac->dev; | 135 | struct device *dev = dwmac->dev; |
| 136 | static const struct clk_parent_data mux_parents[] = { | 136 | static const struct clk_parent_data mux_parents[] = { |
| 137 | { .fw_name = "clkin0", }, | 137 | { .fw_name = "clkin0", }, |
| 138 | { .fw_name = "clkin1", }, | 138 | { .index = -1, }, |
| 139 | }; | 139 | }; |
| 140 | static const struct clk_div_table div_table[] = { | 140 | static const struct clk_div_table div_table[] = { |
| 141 | { .div = 2, .val = 2, }, | 141 | { .div = 2, .val = 2, }, |
| @@ -64,6 +64,7 @@ struct emac_variant { · 63 unmodified lines | |||
| 64 | * @variant: reference to the current board variant | 64 | * @variant: reference to the current board variant |
| 65 | * @regmap: regmap for using the syscon | 65 | * @regmap: regmap for using the syscon |
| 66 | * @internal_phy_powered: Does the internal PHY is enabled | 66 | * @internal_phy_powered: Does the internal PHY is enabled |
| 67 | * @use_internal_phy: Is the internal PHY selected for use | ||
| 67 | * @mux_handle: Internal pointer used by mdio-mux lib | 68 | * @mux_handle: Internal pointer used by mdio-mux lib |
| 68 | */ | 69 | */ |
| 69 | struct sunxi_priv_data { | 70 | struct sunxi_priv_data { |
| @@ -74,6 +75,7 @@ struct sunxi_priv_data { · 4 unmodified lines | |||
| 74 | const struct emac_variant *variant; | 75 | const struct emac_variant *variant; |
| 75 | struct regmap_field *regmap_field; | 76 | struct regmap_field *regmap_field; |
| 76 | bool internal_phy_powered; | 77 | bool internal_phy_powered; |
| 78 | bool use_internal_phy; | ||
| 77 | void *mux_handle; | 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 | .dma_interrupt = sun8i_dwmac_dma_interrupt, | 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 | static int sun8i_dwmac_init(struct platform_device *pdev, void *priv) | 546 | static int sun8i_dwmac_init(struct platform_device *pdev, void *priv) |
| 543 | { | 547 | { |
| 548 | struct net_device *ndev = platform_get_drvdata(pdev); | ||
| 544 | struct sunxi_priv_data *gmac = priv; | 549 | struct sunxi_priv_data *gmac = priv; |
| 545 | int ret; | 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 | ret = clk_prepare_enable(gmac->tx_clk); | 560 | ret = clk_prepare_enable(gmac->tx_clk); |
| 556 | if (ret) { | 561 | if (ret) { |
| 557 | if (gmac->regulator) | ||
| 558 | regulator_disable(gmac->regulator); | ||
| 559 | dev_err(&pdev->dev, "Could not enable AHB clock\n"); | 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 | return 0; | 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 | static void sun8i_dwmac_core_init(struct mac_device_info *hw, | 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 | struct sunxi_priv_data *gmac = priv->plat->bsp_priv; | 848 | struct sunxi_priv_data *gmac = priv->plat->bsp_priv; |
| 832 | u32 reg, val; | 849 | u32 reg, val; |
| 833 | int ret = 0; | 850 | int ret = 0; |
| 834 | bool need_power_ephy = false; | ||
| 835 | 851 | ||
| 836 | if (current_child ^ desired_child) { | 852 | if (current_child ^ desired_child) { |
| 837 | regmap_field_read(gmac->regmap_field, ®); | 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 | case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID: | 855 | case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID: |
| 840 | dev_info(priv->device, "Switch mux to internal PHY"); | 856 | dev_info(priv->device, "Switch mux to internal PHY"); |
| 841 | val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SELECT; | 857 | val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SELECT; |
| 842 | 858 | gmac->use_internal_phy = true; | |
| 843 | need_power_ephy = true; | ||
| 844 | break; | 859 | break; |
| 845 | case DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID: | 860 | case DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID: |
| 846 | dev_info(priv->device, "Switch mux to external PHY"); | 861 | dev_info(priv->device, "Switch mux to external PHY"); |
| 847 | val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SHUTDOWN; | 862 | val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SHUTDOWN; |
| 848 | need_power_ephy = false; | 863 | gmac->use_internal_phy = false; |
| 849 | break; | 864 | break; |
| 850 | default: | 865 | default: |
| 851 | dev_err(priv->device, "Invalid child ID %x\n", | 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 | return -EINVAL; | 868 | return -EINVAL; |
| 854 | } | 869 | } |
| 855 | regmap_field_write(gmac->regmap_field, val); | 870 | regmap_field_write(gmac->regmap_field, val); |
| 856 | if (need_power_ephy) { | 871 | if (gmac->use_internal_phy) { |
| 857 | ret = sun8i_dwmac_power_internal_phy(priv); | 872 | ret = sun8i_dwmac_power_internal_phy(priv); |
| 858 | if (ret) | 873 | if (ret) |
| 859 | return ret; | 874 | return ret; |
| @@ -883,22 +898,23 @@ static int sun8i_dwmac_register_mdio_mux(struct stmmac_priv *priv) · 23 unmodified lines | |||
| 883 | return ret; | 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; | 904 | struct sunxi_priv_data *gmac = plat->bsp_priv; |
| 889 | struct device_node *node = priv->device->of_node; | 905 | struct device_node *node = dev->of_node; |
| 890 | int ret; | 906 | int ret; |
| 891 | u32 reg, val; | 907 | u32 reg, val; |
| 892 | 908 | ||
| 893 | ret = regmap_field_read(gmac->regmap_field, &val); | 909 | ret = regmap_field_read(gmac->regmap_field, &val); |
| 894 | if (ret) { | 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 | return ret; | 912 | return ret; |
| 897 | } | 913 | } |
| 898 | 914 | ||
| 899 | reg = gmac->variant->default_syscon_value; | 915 | reg = gmac->variant->default_syscon_value; |
| 900 | if (reg != val) | 916 | if (reg != val) |
| 901 | dev_warn(priv->device, | 917 | dev_warn(dev, |
| 902 | "Current syscon value is not the default %x (expect %x)\n", | 918 | "Current syscon value is not the default %x (expect %x)\n", |
| 903 | val, reg); | 919 | val, reg); |
| 904 | 920 | ||
| @@ -911,9 +927,9 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) · 6 unmodified lines | |||
| 911 | /* Force EPHY xtal frequency to 24MHz. */ | 927 | /* Force EPHY xtal frequency to 24MHz. */ |
| 912 | reg |= H3_EPHY_CLK_SEL; | 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 | if (ret < 0) { | 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 | return ret; | 933 | return ret; |
| 918 | } | 934 | } |
| 919 | /* of_mdio_parse_addr returns a valid (0 ~ 31) PHY | 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 | if (!of_property_read_u32(node, "allwinner,tx-delay-ps", &val)) { | 946 | if (!of_property_read_u32(node, "allwinner,tx-delay-ps", &val)) { |
| 931 | if (val % 100) { | 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 | return -EINVAL; | 949 | return -EINVAL; |
| 934 | } | 950 | } |
| 935 | val /= 100; | 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 | if (val <= gmac->variant->tx_delay_max) { | 953 | if (val <= gmac->variant->tx_delay_max) { |
| 938 | reg &= ~(gmac->variant->tx_delay_max << | 954 | reg &= ~(gmac->variant->tx_delay_max << |
| 939 | SYSCON_ETXDC_SHIFT); | 955 | SYSCON_ETXDC_SHIFT); |
| 940 | reg |= (val << SYSCON_ETXDC_SHIFT); | 956 | reg |= (val << SYSCON_ETXDC_SHIFT); |
| 941 | } else { | 957 | } else { |
| 942 | dev_err(priv->device, "Invalid TX clock delay: %d\n", | 958 | dev_err(dev, "Invalid TX clock delay: %d\n", |
| 943 | val); | 959 | val); |
| 944 | return -EINVAL; | 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 | if (!of_property_read_u32(node, "allwinner,rx-delay-ps", &val)) { | 964 | if (!of_property_read_u32(node, "allwinner,rx-delay-ps", &val)) { |
| 949 | if (val % 100) { | 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 | return -EINVAL; | 967 | return -EINVAL; |
| 952 | } | 968 | } |
| 953 | val /= 100; | 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 | if (val <= gmac->variant->rx_delay_max) { | 971 | if (val <= gmac->variant->rx_delay_max) { |
| 956 | reg &= ~(gmac->variant->rx_delay_max << | 972 | reg &= ~(gmac->variant->rx_delay_max << |
| 957 | SYSCON_ERXDC_SHIFT); | 973 | SYSCON_ERXDC_SHIFT); |
| 958 | reg |= (val << SYSCON_ERXDC_SHIFT); | 974 | reg |= (val << SYSCON_ERXDC_SHIFT); |
| 959 | } else { | 975 | } else { |
| 960 | dev_err(priv->device, "Invalid RX clock delay: %d\n", | 976 | dev_err(dev, "Invalid RX clock delay: %d\n", |
| 961 | val); | 977 | val); |
| 962 | return -EINVAL; | 978 | return -EINVAL; |
| 963 | } | 979 | } |
| @@ -968,7 +984,7 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) · 4 unmodified lines | |||
| 968 | if (gmac->variant->support_rmii) | 984 | if (gmac->variant->support_rmii) |
| 969 | reg &= ~SYSCON_RMII_EN; | 985 | reg &= ~SYSCON_RMII_EN; |
| 970 | 986 | ||
| 971 | switch (priv->plat->interface) { | 987 | switch (plat->interface) { |
| 972 | case PHY_INTERFACE_MODE_MII: | 988 | case PHY_INTERFACE_MODE_MII: |
| 973 | /* default */ | 989 | /* default */ |
| 974 | break; | 990 | break; |
| @@ -982,8 +998,8 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) · 7 unmodified lines | |||
| 982 | reg |= SYSCON_RMII_EN | SYSCON_ETCS_EXT_GMII; | 998 | reg |= SYSCON_RMII_EN | SYSCON_ETCS_EXT_GMII; |
| 983 | break; | 999 | break; |
| 984 | default: | 1000 | default: |
| 985 | dev_err(priv->device, "Unsupported interface mode: %s", | 1001 | dev_err(dev, "Unsupported interface mode: %s", |
| 986 | phy_modes(priv->plat->interface)); | 1002 | phy_modes(plat->interface)); |
| 987 | return -EINVAL; | 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 | struct sunxi_priv_data *gmac = priv; | 1020 | struct sunxi_priv_data *gmac = priv; |
| 1005 | 1021 | ||
| 1006 | if (gmac->variant->soc_has_internal_phy) { | 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 | if (gmac->internal_phy_powered) | 1023 | if (gmac->internal_phy_powered) |
| 1011 | sun8i_dwmac_unpower_internal_phy(gmac); | 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 | clk_disable_unprepare(gmac->tx_clk); | 1027 | clk_disable_unprepare(gmac->tx_clk); |
| 1019 | 1028 | ||
| 1020 | if (gmac->regulator) | 1029 | if (gmac->regulator) |
| @@ -1049,16 +1058,11 @@ static struct mac_device_info *sun8i_dwmac_setup(void *ppriv) · 28 unmodified lines | |||
| 1049 | { | 1058 | { |
| 1050 | struct mac_device_info *mac; | 1059 | struct mac_device_info *mac; |
| 1051 | struct stmmac_priv *priv = ppriv; | 1060 | struct stmmac_priv *priv = ppriv; |
| 1052 | int ret; | ||
| 1053 | 1061 | ||
| 1054 | mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL); | 1062 | mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL); |
| 1055 | if (!mac) | 1063 | if (!mac) |
| 1056 | return NULL; | 1064 | return NULL; |
| 1057 | 1065 | ||
| 1058 | ret = sun8i_dwmac_set_syscon(priv); | ||
| 1059 | if (ret) | ||
| 1060 | return NULL; | ||
| 1061 | |||
| 1062 | mac->pcsr = priv->ioaddr; | 1066 | mac->pcsr = priv->ioaddr; |
| 1063 | mac->mac = &sun8i_dwmac_ops; | 1067 | mac->mac = &sun8i_dwmac_ops; |
| 1064 | mac->dma = &sun8i_dwmac_dma_ops; | 1068 | mac->dma = &sun8i_dwmac_dma_ops; |
| @@ -1134,10 +1138,6 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) · 69 unmodified lines | |||
| 1134 | if (ret) | 1138 | if (ret) |
| 1135 | return ret; | 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 | gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL); | 1141 | gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL); |
| 1142 | if (!gmac) | 1142 | if (!gmac) |
| 1143 | return -ENOMEM; | 1143 | return -ENOMEM; |
| @@ -1201,11 +1201,15 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) · 57 unmodified lines | |||
| 1201 | ret = of_get_phy_mode(dev->of_node, &interface); | 1201 | ret = of_get_phy_mode(dev->of_node, &interface); |
| 1202 | if (ret) | 1202 | if (ret) |
| 1203 | return -EINVAL; | 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 | /* platform data specifying hardware features and callbacks. | 1209 | /* platform data specifying hardware features and callbacks. |
| 1207 | * hardware features were copied from Allwinner drivers. | 1210 | * hardware features were copied from Allwinner drivers. |
| 1208 | */ | 1211 | */ |
| 1212 | plat_dat->interface = interface; | ||
| 1209 | plat_dat->rx_coe = STMMAC_RX_COE_TYPE2; | 1213 | plat_dat->rx_coe = STMMAC_RX_COE_TYPE2; |
| 1210 | plat_dat->tx_coe = 1; | 1214 | plat_dat->tx_coe = 1; |
| 1211 | plat_dat->has_sun8i = true; | 1215 | plat_dat->has_sun8i = true; |
| @@ -1214,9 +1218,13 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 1214 | plat_dat->exit = sun8i_dwmac_exit; | 1218 | plat_dat->exit = sun8i_dwmac_exit; |
| 1215 | plat_dat->setup = sun8i_dwmac_setup; | 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 | ret = sun8i_dwmac_init(pdev, plat_dat->bsp_priv); | 1225 | ret = sun8i_dwmac_init(pdev, plat_dat->bsp_priv); |
| 1218 | if (ret) | 1226 | if (ret) |
| 1219 | return ret; | 1227 | goto dwmac_syscon; |
| 1220 | 1228 | ||
| 1221 | ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); | 1229 | ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); |
| 1222 | if (ret) | 1230 | if (ret) |
| @@ -1230,7 +1238,7 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) · 7 unmodified lines | |||
| 1230 | if (gmac->variant->soc_has_internal_phy) { | 1238 | if (gmac->variant->soc_has_internal_phy) { |
| 1231 | ret = get_ephy_nodes(priv); | 1239 | ret = get_ephy_nodes(priv); |
| 1232 | if (ret) | 1240 | if (ret) |
| 1233 | goto dwmac_exit; | 1241 | goto dwmac_remove; |
| 1234 | ret = sun8i_dwmac_register_mdio_mux(priv); | 1242 | ret = sun8i_dwmac_register_mdio_mux(priv); |
| 1235 | if (ret) { | 1243 | if (ret) { |
| 1236 | dev_err(&pdev->dev, "Failed to register mux\n"); | 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 | } else { | 1247 | } else { |
| 1240 | ret = sun8i_dwmac_reset(priv); | 1248 | ret = sun8i_dwmac_reset(priv); |
| 1241 | if (ret) | 1249 | if (ret) |
| 1242 | goto dwmac_exit; | 1250 | goto dwmac_remove; |
| 1243 | } | 1251 | } |
| 1244 | 1252 | ||
| 1245 | return ret; | 1253 | return ret; |
| 1246 | dwmac_mux: | 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 | dwmac_exit: | 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 | stmmac_pltfr_remove(pdev); | 1282 | stmmac_pltfr_remove(pdev); |
| 1250 | return ret; | 1283 | sun8i_dwmac_unset_syscon(gmac); |
| 1284 | |||
| 1285 | return 0; | ||
| 1251 | } | 1286 | } |
| 1252 | 1287 | ||
| 1253 | static const struct of_device_id sun8i_dwmac_match[] = { | 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 | static struct platform_driver sun8i_dwmac_driver = { | 1305 | static struct platform_driver sun8i_dwmac_driver = { |
| 1271 | .probe = sun8i_dwmac_probe, | 1306 | .probe = sun8i_dwmac_probe, |
| 1272 | .remove = stmmac_pltfr_remove, | 1307 | .remove = sun8i_dwmac_remove, |
| 1273 | .driver = { | 1308 | .driver = { |
| 1274 | .name = "dwmac-sun8i", | 1309 | .name = "dwmac-sun8i", |
| 1275 | .pm = &stmmac_pltfr_pm_ops, | 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 | int dwmac5_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg, | 568 | int dwmac5_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg, |
| 569 | unsigned int ptp_rate) | 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 | int i, ret = 0x0; | 571 | int i, ret = 0x0; |
| 575 | u64 total_ctr; | 572 | u32 ctrl; |
| 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; | ||
| 606 | 573 | ||
| 607 | ret |= dwmac5_est_write(ioaddr, BTR_LOW, cfg->btr[0], false); | 574 | ret |= dwmac5_est_write(ioaddr, BTR_LOW, cfg->btr[0], false); |
| 608 | ret |= dwmac5_est_write(ioaddr, BTR_HIGH, cfg->btr[1], false); | 575 | ret |= dwmac5_est_write(ioaddr, BTR_HIGH, cfg->btr[1], false); |
| 609 | ret |= dwmac5_est_write(ioaddr, TER, cfg->ter, false); | 576 | ret |= dwmac5_est_write(ioaddr, TER, cfg->ter, false); |
| 610 | ret |= dwmac5_est_write(ioaddr, LLR, cfg->gcl_size, false); | 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 | if (ret) | 580 | if (ret) |
| 612 | return ret; | 581 | return ret; |
| 613 | 582 | ||
| 614 | total_offset = 0; | ||
| 615 | for (i = 0; i < cfg->gcl_size; i++) { | 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 | if (ret) | 585 | if (ret) |
| 618 | return ret; | 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 | ctrl = readl(ioaddr + MTL_EST_CONTROL); | 589 | ctrl = readl(ioaddr + MTL_EST_CONTROL); |
| 634 | ctrl &= ~PTOV; | 590 | ctrl &= ~PTOV; |
| 635 | ctrl |= ((1000000000 / ptp_rate) * 6) << PTOV_SHIFT; | 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 | spin_lock_irqsave(&ch->lock, flags); | 2184 | spin_lock_irqsave(&ch->lock, flags); |
| 2185 | stmmac_disable_dma_irq(priv, priv->ioaddr, chan, 1, 0); | 2185 | stmmac_disable_dma_irq(priv, priv->ioaddr, chan, 1, 0); |
| 2186 | spin_unlock_irqrestore(&ch->lock, flags); | 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 | spin_lock_irqsave(&ch->lock, flags); | 2193 | spin_lock_irqsave(&ch->lock, flags); |
| 2194 | stmmac_disable_dma_irq(priv, priv->ioaddr, chan, 0, 1); | 2194 | stmmac_disable_dma_irq(priv, priv->ioaddr, chan, 0, 1); |
| 2195 | spin_unlock_irqrestore(&ch->lock, flags); | 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 | struct stmmac_priv *priv = netdev_priv(dev); | 4027 | struct stmmac_priv *priv = netdev_priv(dev); |
| 4028 | int txfifosz = priv->plat->tx_fifo_size; | 4028 | int txfifosz = priv->plat->tx_fifo_size; |
| 4029 | const int mtu = new_mtu; | ||
| 4029 | 4030 | ||
| 4030 | if (txfifosz == 0) | 4031 | if (txfifosz == 0) |
| 4031 | txfifosz = priv->dma_cap.tx_fifo_size; | 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 | if ((txfifosz < new_mtu) || (new_mtu > BUF_SIZE_16KiB)) | 4044 | if ((txfifosz < new_mtu) || (new_mtu > BUF_SIZE_16KiB)) |
| 4044 | return -EINVAL; | 4045 | return -EINVAL; |
| 4045 | 4046 | ||
| 4046 | dev->mtu = new_mtu; | 4047 | dev->mtu = mtu; |
| 4047 | 4048 | ||
| 4048 | netdev_update_features(dev); | 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 | u32 size, wid = priv->dma_cap.estwid, dep = priv->dma_cap.estdep; | 600 | u32 size, wid = priv->dma_cap.estwid, dep = priv->dma_cap.estdep; |
| 601 | struct plat_stmmacenet_data *plat = priv->plat; | 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 | bool fpe = false; | 604 | bool fpe = false; |
| 604 | int i, ret = 0; | 605 | int i, ret = 0; |
| 605 | u64 ctr; | 606 | u64 ctr; |
| @@ -694,7 +695,22 @@ static int tc_setup_taprio(struct stmmac_priv *priv, · 88 unmodified lines | |||
| 694 | } | 695 | } |
| 695 | 696 | ||
| 696 | /* Adjust for real system time */ | 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 | priv->plat->est->btr[0] = (u32)time.tv_nsec; | 714 | priv->plat->est->btr[0] = (u32)time.tv_nsec; |
| 699 | priv->plat->est->btr[1] = (u32)time.tv_sec; | 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 | ptp_clock_unregister(cpts->clock); | 600 | ptp_clock_unregister(cpts->clock); |
| 601 | cpts->clock = NULL; | 601 | cpts->clock = NULL; |
| 602 | cpts->phc_index = -1; | ||
| 602 | 603 | ||
| 603 | cpts_write32(cpts, 0, int_enable); | 604 | cpts_write32(cpts, 0, int_enable); |
| 604 | cpts_write32(cpts, 0, control); | 605 | cpts_write32(cpts, 0, control); |
| @@ -784,6 +785,7 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs, · 179 unmodified lines | |||
| 784 | cpts->cc.read = cpts_systim_read; | 785 | cpts->cc.read = cpts_systim_read; |
| 785 | cpts->cc.mask = CLOCKSOURCE_MASK(32); | 786 | cpts->cc.mask = CLOCKSOURCE_MASK(32); |
| 786 | cpts->info = cpts_info; | 787 | cpts->info = cpts_info; |
| 788 | cpts->phc_index = -1; | ||
| 787 | 789 | ||
| 788 | if (n_ext_ts) | 790 | if (n_ext_ts) |
| 789 | cpts->info.n_ext_ts = n_ext_ts; | 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 | /* Issue an event ring command and wait for it to complete */ | 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, | 329 | static void evt_ring_command(struct gsi *gsi, u32 evt_ring_id, |
| 330 | enum gsi_evt_cmd_opcode opcode) | 330 | enum gsi_evt_cmd_opcode opcode) |
| 331 | { | 331 | { |
| 332 | struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id]; | 332 | struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id]; |
| 333 | struct completion *completion = &evt_ring->completion; | 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 | * is issued here. Only permit *this* event ring to trigger | 340 | * is issued here. Only permit *this* event ring to trigger |
| 341 | * an interrupt, and only enable the event control IRQ type | 341 | * an interrupt, and only enable the event control IRQ type |
| 342 | * when we expect it to occur. | 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 | val = BIT(evt_ring_id); | 350 | val = BIT(evt_ring_id); |
| 345 | iowrite32(val, gsi->virt + GSI_CNTXT_SRC_EV_CH_IRQ_MSK_OFFSET); | 351 | iowrite32(val, gsi->virt + GSI_CNTXT_SRC_EV_CH_IRQ_MSK_OFFSET); |
| 346 | gsi_irq_type_enable(gsi, GSI_EV_CTRL); | 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 | iowrite32(0, gsi->virt + GSI_CNTXT_SRC_EV_CH_IRQ_MSK_OFFSET); | 361 | iowrite32(0, gsi->virt + GSI_CNTXT_SRC_EV_CH_IRQ_MSK_OFFSET); |
| 356 | 362 | ||
| 357 | if (success) | 363 | if (success) |
| 358 | return 0; | 364 | return; |
| 359 | 365 | ||
| 360 | dev_err(dev, "GSI command %u for event ring %u timed out, state %u\n", | 366 | dev_err(dev, "GSI command %u for event ring %u timed out, state %u\n", |
| 361 | opcode, evt_ring_id, evt_ring->state); | 367 | opcode, evt_ring_id, evt_ring->state); |
| 362 | |||
| 363 | return -ETIMEDOUT; | ||
| 364 | } | 368 | } |
| 365 | 369 | ||
| 366 | /* Allocate an event ring in NOT_ALLOCATED state */ | 370 | /* Allocate an event ring in NOT_ALLOCATED state */ |
| 367 | static int gsi_evt_ring_alloc_command(struct gsi *gsi, u32 evt_ring_id) | 371 | static int gsi_evt_ring_alloc_command(struct gsi *gsi, u32 evt_ring_id) |
| 368 | { | 372 | { |
| 369 | struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id]; | 373 | struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id]; |
| 370 | int ret; | ||
| 371 | 374 | ||
| 372 | /* Get initial event ring state */ | 375 | /* Get initial event ring state */ |
| 373 | evt_ring->state = gsi_evt_ring_state(gsi, evt_ring_id); | 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 | return -EINVAL; | 380 | return -EINVAL; |
| 378 | } | 381 | } |
| 379 | 382 | ||
| 380 | ret = evt_ring_command(gsi, evt_ring_id, GSI_EVT_ALLOCATE); | 383 | 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 | } | ||
| 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 | /* Reset a GSI event ring in ALLOCATED or ERROR state. */ | 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 | struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id]; | 398 | struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id]; |
| 394 | enum gsi_evt_ring_state state = evt_ring->state; | 399 | enum gsi_evt_ring_state state = evt_ring->state; |
| 395 | int ret; | ||
| 396 | 400 | ||
| 397 | if (state != GSI_EVT_RING_STATE_ALLOCATED && | 401 | if (state != GSI_EVT_RING_STATE_ALLOCATED && |
| 398 | state != GSI_EVT_RING_STATE_ERROR) { | 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 | return; | 405 | return; |
| 402 | } | 406 | } |
| 403 | 407 | ||
| 404 | ret = evt_ring_command(gsi, evt_ring_id, GSI_EVT_RESET); | 408 | evt_ring_command(gsi, evt_ring_id, GSI_EVT_RESET); |
| 405 | if (!ret && evt_ring->state != GSI_EVT_RING_STATE_ALLOCATED) | 409 | |
| 406 | dev_err(gsi->dev, "event ring %u bad state %u after reset\n", | 410 | /* If successful the event ring state will have changed */ |
| 407 | evt_ring_id, evt_ring->state); | 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 | /* Issue a hardware de-allocation request for an allocated event ring */ | 418 | /* Issue a hardware de-allocation request for an allocated event ring */ |
| 411 | static void gsi_evt_ring_de_alloc_command(struct gsi *gsi, u32 evt_ring_id) | 419 | static void gsi_evt_ring_de_alloc_command(struct gsi *gsi, u32 evt_ring_id) |
| 412 | { | 420 | { |
| 413 | struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id]; | 421 | struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id]; |
| 414 | int ret; | ||
| 415 | 422 | ||
| 416 | if (evt_ring->state != GSI_EVT_RING_STATE_ALLOCATED) { | 423 | if (evt_ring->state != GSI_EVT_RING_STATE_ALLOCATED) { |
| 417 | dev_err(gsi->dev, "event ring %u state %u before dealloc\n", | 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 | return; | 426 | return; |
| 420 | } | 427 | } |
| 421 | 428 | ||
| 422 | ret = evt_ring_command(gsi, evt_ring_id, GSI_EVT_DE_ALLOC); | 429 | evt_ring_command(gsi, evt_ring_id, GSI_EVT_DE_ALLOC); |
| 423 | if (!ret && evt_ring->state != GSI_EVT_RING_STATE_NOT_ALLOCATED) | 430 | |
| 424 | dev_err(gsi->dev, "event ring %u bad state %u after dealloc\n", | 431 | /* If successful the event ring state will have changed */ |
| 425 | evt_ring_id, evt_ring->state); | 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 | /* Fetch the current state of a channel from hardware */ | 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 | /* Issue a channel command and wait for it to complete */ | 451 | /* Issue a channel command and wait for it to complete */ |
| 441 | static int | 452 | static void |
| 442 | gsi_channel_command(struct gsi_channel *channel, enum gsi_ch_cmd_opcode opcode) | 453 | gsi_channel_command(struct gsi_channel *channel, enum gsi_ch_cmd_opcode opcode) |
| 443 | { | 454 | { |
| 444 | struct completion *completion = &channel->completion; | 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 | * issued here. So we only permit *this* channel to trigger | 464 | * issued here. So we only permit *this* channel to trigger |
| 454 | * an interrupt and only enable the channel control IRQ type | 465 | * an interrupt and only enable the channel control IRQ type |
| 455 | * when we expect it to occur. | 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 | val = BIT(channel_id); | 474 | val = BIT(channel_id); |
| 458 | iowrite32(val, gsi->virt + GSI_CNTXT_SRC_CH_IRQ_MSK_OFFSET); | 475 | iowrite32(val, gsi->virt + GSI_CNTXT_SRC_CH_IRQ_MSK_OFFSET); |
| 459 | gsi_irq_type_enable(gsi, GSI_CH_CTRL); | 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 | iowrite32(0, gsi->virt + GSI_CNTXT_SRC_CH_IRQ_MSK_OFFSET); | 484 | iowrite32(0, gsi->virt + GSI_CNTXT_SRC_CH_IRQ_MSK_OFFSET); |
| 468 | 485 | ||
| 469 | if (success) | 486 | if (success) |
| 470 | return 0; | 487 | return; |
| 471 | 488 | ||
| 472 | dev_err(dev, "GSI command %u for channel %u timed out, state %u\n", | 489 | dev_err(dev, "GSI command %u for channel %u timed out, state %u\n", |
| 473 | opcode, channel_id, gsi_channel_state(channel)); | 490 | opcode, channel_id, gsi_channel_state(channel)); |
| 474 | |||
| 475 | return -ETIMEDOUT; | ||
| 476 | } | 491 | } |
| 477 | 492 | ||
| 478 | /* Allocate GSI channel in NOT_ALLOCATED state */ | 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 | struct gsi_channel *channel = &gsi->channel[channel_id]; | 496 | struct gsi_channel *channel = &gsi->channel[channel_id]; |
| 482 | struct device *dev = gsi->dev; | 497 | struct device *dev = gsi->dev; |
| 483 | enum gsi_channel_state state; | 498 | enum gsi_channel_state state; |
| 484 | int ret; | ||
| 485 | 499 | ||
| 486 | /* Get initial channel state */ | 500 | /* Get initial channel state */ |
| 487 | state = gsi_channel_state(channel); | 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 | return -EINVAL; | 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 | state = gsi_channel_state(channel); | 511 | state = gsi_channel_state(channel); |
| 498 | if (!ret && state != GSI_CHANNEL_STATE_ALLOCATED) { | 512 | if (state == GSI_CHANNEL_STATE_ALLOCATED) |
| 499 | dev_err(dev, "channel %u bad state %u after alloc\n", | 513 | return 0; |
| 500 | channel_id, state); | ||
| 501 | ret = -EIO; | ||
| 502 | } | ||
| 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 | /* Start an ALLOCATED channel */ | 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 | struct device *dev = channel->gsi->dev; | 524 | struct device *dev = channel->gsi->dev; |
| 511 | enum gsi_channel_state state; | 525 | enum gsi_channel_state state; |
| 512 | int ret; | ||
| 513 | 526 | ||
| 514 | state = gsi_channel_state(channel); | 527 | state = gsi_channel_state(channel); |
| 515 | if (state != GSI_CHANNEL_STATE_ALLOCATED && | 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 | return -EINVAL; | 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 | state = gsi_channel_state(channel); | 538 | state = gsi_channel_state(channel); |
| 526 | if (!ret && state != GSI_CHANNEL_STATE_STARTED) { | 539 | if (state == GSI_CHANNEL_STATE_STARTED) |
| 527 | dev_err(dev, "channel %u bad state %u after start\n", | 540 | return 0; |
| 528 | gsi_channel_id(channel), state); | ||
| 529 | ret = -EIO; | ||
| 530 | } | ||
| 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 | /* Stop a GSI channel in STARTED state */ | 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 | struct device *dev = channel->gsi->dev; | 551 | struct device *dev = channel->gsi->dev; |
| 539 | enum gsi_channel_state state; | 552 | enum gsi_channel_state state; |
| 540 | int ret; | ||
| 541 | 553 | ||
| 542 | state = gsi_channel_state(channel); | 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 | return -EINVAL; | 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 | state = gsi_channel_state(channel); | 572 | state = gsi_channel_state(channel); |
| 561 | if (ret || state == GSI_CHANNEL_STATE_STOPPED) | 573 | if (state == GSI_CHANNEL_STATE_STOPPED) |
| 562 | return ret; | 574 | return 0; |
| 563 | 575 | ||
| 564 | /* We may have to try again if stop is in progress */ | 576 | /* We may have to try again if stop is in progress */ |
| 565 | if (state == GSI_CHANNEL_STATE_STOP_IN_PROC) | 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 | struct device *dev = channel->gsi->dev; | 589 | struct device *dev = channel->gsi->dev; |
| 578 | enum gsi_channel_state state; | 590 | enum gsi_channel_state state; |
| 579 | int ret; | ||
| 580 | 591 | ||
| 581 | msleep(1); /* A short delay is required before a RESET command */ | 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 | return; | 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 | state = gsi_channel_state(channel); | 607 | state = gsi_channel_state(channel); |
| 597 | if (!ret && state != GSI_CHANNEL_STATE_ALLOCATED) | 608 | if (state != GSI_CHANNEL_STATE_ALLOCATED) |
| 598 | dev_err(dev, "channel %u bad state %u after reset\n", | 609 | dev_err(dev, "channel %u bad state %u after reset\n", |
| 599 | gsi_channel_id(channel), state); | 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 | struct gsi_channel *channel = &gsi->channel[channel_id]; | 616 | struct gsi_channel *channel = &gsi->channel[channel_id]; |
| 606 | struct device *dev = gsi->dev; | 617 | struct device *dev = gsi->dev; |
| 607 | enum gsi_channel_state state; | 618 | enum gsi_channel_state state; |
| 608 | int ret; | ||
| 609 | 619 | ||
| 610 | state = gsi_channel_state(channel); | 620 | state = gsi_channel_state(channel); |
| 611 | if (state != GSI_CHANNEL_STATE_ALLOCATED) { | 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 | return; | 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 | state = gsi_channel_state(channel); | 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 | dev_err(dev, "channel %u bad state %u after dealloc\n", | 633 | dev_err(dev, "channel %u bad state %u after dealloc\n", |
| 623 | channel_id, state); | 634 | channel_id, state); |
| 624 | } | 635 | } |
| @@ -115,13 +115,13 @@ static int ipa_interconnect_enable(struct ipa *ipa) · 114 unmodified lines | |||
| 115 | return ret; | 115 | return ret; |
| 116 | 116 | ||
| 117 | data = &clock->interconnect_data[IPA_INTERCONNECT_IMEM]; | 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 | data->peak_rate); | 119 | data->peak_rate); |
| 120 | if (ret) | 120 | if (ret) |
| 121 | goto err_memory_path_disable; | 121 | goto err_memory_path_disable; |
| 122 | 122 | ||
| 123 | data = &clock->interconnect_data[IPA_INTERCONNECT_CONFIG]; | 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 | data->peak_rate); | 125 | data->peak_rate); |
| 126 | if (ret) | 126 | if (ret) |
| 127 | goto err_imem_path_disable; | 127 | goto err_imem_path_disable; |
| @@ -216,6 +216,7 @@ int ipa_modem_start(struct ipa *ipa) · 215 unmodified lines | |||
| 216 | ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]->netdev = netdev; | 216 | ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]->netdev = netdev; |
| 217 | ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]->netdev = netdev; | 217 | ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]->netdev = netdev; |
| 218 | 218 | ||
| 219 | SET_NETDEV_DEV(netdev, &ipa->pdev->dev); | ||
| 219 | priv = netdev_priv(netdev); | 220 | priv = netdev_priv(netdev); |
| 220 | priv->ipa = ipa; | 221 | priv->ipa = ipa; |
| 221 | 222 | ||
| @@ -317,7 +317,8 @@ static int smsc_phy_probe(struct phy_device *phydev) · 316 unmodified lines | |||
| 317 | /* Make clk optional to keep DTB backward compatibility. */ | 317 | /* Make clk optional to keep DTB backward compatibility. */ |
| 318 | priv->refclk = clk_get_optional(dev, NULL); | 318 | priv->refclk = clk_get_optional(dev, NULL); |
| 319 | if (IS_ERR(priv->refclk)) | 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 | ret = clk_prepare_enable(priv->refclk); | 323 | ret = clk_prepare_enable(priv->refclk); |
| 323 | if (ret) | 324 | if (ret) |
| @@ -623,6 +623,7 @@ static int ppp_bridge_channels(struct channel *pch, struct channel *pchb) · 622 unmodified lines | |||
| 623 | write_unlock_bh(&pch->upl); | 623 | write_unlock_bh(&pch->upl); |
| 624 | return -EALREADY; | 624 | return -EALREADY; |
| 625 | } | 625 | } |
| 626 | refcount_inc(&pchb->file.refcnt); | ||
| 626 | rcu_assign_pointer(pch->bridge, pchb); | 627 | rcu_assign_pointer(pch->bridge, pchb); |
| 627 | write_unlock_bh(&pch->upl); | 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 | write_unlock_bh(&pchb->upl); | 633 | write_unlock_bh(&pchb->upl); |
| 633 | goto err_unset; | 634 | goto err_unset; |
| 634 | } | 635 | } |
| 636 | refcount_inc(&pch->file.refcnt); | ||
| 635 | rcu_assign_pointer(pchb->bridge, pch); | 637 | rcu_assign_pointer(pchb->bridge, pch); |
| 636 | write_unlock_bh(&pchb->upl); | 638 | write_unlock_bh(&pchb->upl); |
| 637 | 639 | ||
| 638 | refcount_inc(&pch->file.refcnt); | ||
| 639 | refcount_inc(&pchb->file.refcnt); | ||
| 640 | |||
| 641 | return 0; | 640 | return 0; |
| 642 | 641 | ||
| 643 | err_unset: | 642 | err_unset: |
| 644 | write_lock_bh(&pch->upl); | 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 | RCU_INIT_POINTER(pch->bridge, NULL); | 646 | RCU_INIT_POINTER(pch->bridge, NULL); |
| 646 | write_unlock_bh(&pch->upl); | 647 | write_unlock_bh(&pch->upl); |
| 647 | synchronize_rcu(); | 648 | synchronize_rcu(); |
| 649 | |||
| 650 | if (pchb) | ||
| 651 | if (refcount_dec_and_test(&pchb->file.refcnt)) | ||
| 652 | ppp_destroy_channel(pchb); | ||
| 653 | |||
| 648 | return -EALREADY; | 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 | int i; | 1365 | int i; |
| 1366 | 1366 | ||
| 1367 | if (it->nr_segs > MAX_SKB_FRAGS + 1) | 1367 | if (it->nr_segs > MAX_SKB_FRAGS + 1) |
| 1368 | return ERR_PTR(-ENOMEM); | 1368 | return ERR_PTR(-EMSGSIZE); |
| 1369 | 1369 | ||
| 1370 | local_bh_disable(); | 1370 | local_bh_disable(); |
| 1371 | skb = napi_get_frags(&tfile->napi); | 1371 | skb = napi_get_frags(&tfile->napi); |
| @@ -631,7 +631,6 @@ config USB_NET_AQC111 · 630 unmodified lines | |||
| 631 | config USB_RTL8153_ECM | 631 | config USB_RTL8153_ECM |
| 632 | tristate "RTL8153 ECM support" | 632 | tristate "RTL8153 ECM support" |
| 633 | depends on USB_NET_CDCETHER && (USB_RTL8152 || USB_RTL8152=n) | 633 | depends on USB_NET_CDCETHER && (USB_RTL8152 || USB_RTL8152=n) |
| 634 | default y | ||
| 635 | help | 634 | help |
| 636 | This option supports ECM mode for RTL8153 ethernet adapter, when | 635 | This option supports ECM mode for RTL8153 ethernet adapter, when |
| 637 | CONFIG_USB_RTL8152 is not set, or the RTL8153 device is not | 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 | .driver_info = 0, | 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 | /* ThinkPad USB-C Dock Gen 2 (based on Realtek RTL8153) */ | 803 | /* ThinkPad USB-C Dock Gen 2 (based on Realtek RTL8153) */ |
| 797 | { | 804 | { |
| 798 | USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0xa387, USB_CLASS_COMM, | 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 | * accordingly. Otherwise, we should check here. | 1199 | * accordingly. Otherwise, we should check here. |
| 1200 | */ | 1200 | */ |
| 1201 | if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) | 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 | else | 1206 | else |
| 1204 | delayed_ndp_size = 0; | 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 | if (!(dev->driver_info->flags & FLAG_SEND_ZLP) && | 1413 | if (!(dev->driver_info->flags & FLAG_SEND_ZLP) && |
| 1411 | skb_out->len > ctx->min_tx_pkt) { | 1414 | skb_out->len > ctx->min_tx_pkt) { |
| 1412 | padding_count = ctx->tx_curr_size - skb_out->len; | 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 | } else if (skb_out->len < ctx->tx_curr_size && | 1418 | } else if (skb_out->len < ctx->tx_curr_size && |
| 1415 | (skb_out->len % dev->maxpacket) == 0) { | 1419 | (skb_out->len % dev->maxpacket) == 0) { |
| 1416 | skb_put_u8(skb_out, 0); /* force short packet */ | 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 | * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be | 1867 | * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be |
| 1864 | * sent by device after USB_CDC_NOTIFY_SPEED_CHANGE. | 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 | usbnet_link_change(dev, !!event->wValue, 0); | 1870 | usbnet_link_change(dev, !!event->wValue, 0); |
| 1870 | break; | 1871 | break; |
| 1871 | 1872 | ||
| @@ -1013,6 +1013,7 @@ static const struct usb_device_id products[] = { · 1012 unmodified lines | |||
| 1013 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ | 1013 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ |
| 1014 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ | 1014 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ |
| 1015 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */ | 1015 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */ |
| 1016 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0620)}, /* Quectel EM160R-GL */ | ||
| 1016 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */ | 1017 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */ |
| 1017 | 1018 | ||
| 1018 | /* 3. Combined interface devices matching on interface number */ | 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 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, | 6877 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, |
| 6878 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x720c)}, | 6878 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x720c)}, |
| 6879 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214)}, | 6879 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214)}, |
| 6880 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x721e)}, | ||
| 6880 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0xa387)}, | 6881 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0xa387)}, |
| 6881 | {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)}, | 6882 | {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)}, |
| 6882 | {REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff)}, | 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 | static const struct usb_device_id products[] = { | 124 | static const struct usb_device_id products[] = { |
| 125 | /* Realtek RTL8153 Based USB 3.0 Ethernet Adapters */ | ||
| 125 | { | 126 | { |
| 126 | USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ID_REALTEK, 0x8153, USB_CLASS_COMM, | 127 | USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ID_REALTEK, 0x8153, USB_CLASS_COMM, |
| 127 | USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), | 128 | USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), |
| 128 | .driver_info = (unsigned long)&r8153_info, | 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 | { }, /* END */ | 139 | { }, /* END */ |
| 132 | }; | 140 | }; |
| 133 | MODULE_DEVICE_TABLE(usb, products); | 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 | reply_len = sizeof *phym; | 387 | reply_len = sizeof *phym; |
| 388 | retval = rndis_query(dev, intf, u.buf, | 388 | retval = rndis_query(dev, intf, u.buf, |
| 389 | RNDIS_OID_GEN_PHYSICAL_MEDIUM, | 389 | RNDIS_OID_GEN_PHYSICAL_MEDIUM, |
| 390 | 0, (void **) &phym, &reply_len); | 390 | reply_len, (void **)&phym, &reply_len); |
| 391 | if (retval != 0 || !phym) { | 391 | if (retval != 0 || !phym) { |
| 392 | /* OID is optional so don't fail here. */ | 392 | /* OID is optional so don't fail here. */ |
| 393 | phym_unspec = cpu_to_le32(RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED); | 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 | get_online_cpus(); | 2094 | get_online_cpus(); |
| 2095 | err = _virtnet_set_queues(vi, queue_pairs); | 2095 | err = _virtnet_set_queues(vi, queue_pairs); |
| 2096 | if (!err) { | 2096 | if (err) { |
| 2097 | netif_set_real_num_tx_queues(dev, queue_pairs); | 2097 | put_online_cpus(); |
| 2098 | netif_set_real_num_rx_queues(dev, queue_pairs); | 2098 | goto err; |
| 2099 | |||
| 2100 | virtnet_set_affinity(vi); | ||
| 2101 | } | 2099 | } |
| 2100 | virtnet_set_affinity(vi); | ||
| 2102 | put_online_cpus(); | 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 | return err; | 2106 | return err; |
| 2105 | } | 2107 | } |
| 2106 | 2108 | ||
| @@ -282,6 +282,7 @@ config SLIC_DS26522 · 281 unmodified lines | |||
| 282 | tristate "Slic Maxim ds26522 card support" | 282 | tristate "Slic Maxim ds26522 card support" |
| 283 | depends on SPI | 283 | depends on SPI |
| 284 | depends on FSL_SOC || ARCH_MXC || ARCH_LAYERSCAPE || COMPILE_TEST | 284 | depends on FSL_SOC || ARCH_MXC || ARCH_LAYERSCAPE || COMPILE_TEST |
| 285 | select BITREVERSE | ||
| 285 | help | 286 | help |
| 286 | This module initializes and configures the slic maxim card | 287 | This module initializes and configures the slic maxim card |
| 287 | in T1 or E1 mode. | 288 | in T1 or E1 mode. |
| @@ -569,6 +569,13 @@ static void ppp_timer(struct timer_list *t) · 568 unmodified lines | |||
| 569 | unsigned long flags; | 569 | unsigned long flags; |
| 570 | 570 | ||
| 571 | spin_lock_irqsave(&ppp->lock, flags); | 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 | switch (proto->state) { | 579 | switch (proto->state) { |
| 573 | case STOPPING: | 580 | case STOPPING: |
| 574 | case REQ_SENT: | 581 | case REQ_SENT: |
| @@ -185,7 +185,7 @@ int ath11k_core_suspend(struct ath11k_base *ab) · 184 unmodified lines | |||
| 185 | ath11k_hif_ce_irq_disable(ab); | 185 | ath11k_hif_ce_irq_disable(ab); |
| 186 | 186 | ||
| 187 | ret = ath11k_hif_suspend(ab); | 187 | ret = ath11k_hif_suspend(ab); |
| 188 | if (!ret) { | 188 | if (ret) { |
| 189 | ath11k_warn(ab, "failed to suspend hif: %d\n", ret); | 189 | ath11k_warn(ab, "failed to suspend hif: %d\n", ret); |
| 190 | return ret; | 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 | u8 channel_num; | 2295 | u8 channel_num; |
| 2296 | u32 center_freq; | 2296 | u32 center_freq; |
| 2297 | struct ieee80211_channel *channel; | ||
| 2297 | 2298 | ||
| 2298 | rx_status->freq = 0; | 2299 | rx_status->freq = 0; |
| 2299 | rx_status->rate_idx = 0; | 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 | rx_status->band = NL80211_BAND_5GHZ; | 2315 | rx_status->band = NL80211_BAND_5GHZ; |
| 2315 | } else { | 2316 | } else { |
| 2316 | spin_lock_bh(&ar->data_lock); | 2317 | spin_lock_bh(&ar->data_lock); |
| 2317 | rx_status->band = ar->rx_channel->band; | 2318 | channel = ar->rx_channel; |
| 2318 | channel_num = | 2319 | if (channel) { |
| 2319 | ieee80211_frequency_to_channel(ar->rx_channel->center_freq); | 2320 | rx_status->band = channel->band; |
| 2321 | channel_num = | ||
| 2322 | ieee80211_frequency_to_channel(channel->center_freq); | ||
| 2323 | } | ||
| 2320 | spin_unlock_bh(&ar->data_lock); | 2324 | spin_unlock_bh(&ar->data_lock); |
| 2321 | ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "rx_desc: ", | 2325 | ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "rx_desc: ", |
| 2322 | rx_desc, sizeof(struct hal_rx_desc)); | 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 | if (ab->hw_params.vdev_start_delay && | 3023 | if (ab->hw_params.vdev_start_delay && |
| 3024 | !arvif->is_started && | ||
| 3024 | arvif->vdev_type != WMI_VDEV_TYPE_AP) { | 3025 | arvif->vdev_type != WMI_VDEV_TYPE_AP) { |
| 3025 | ret = ath11k_start_vdev_delay(ar->hw, vif); | 3026 | ret = ath11k_start_vdev_delay(ar->hw, vif); |
| 3026 | if (ret) { | 3027 | if (ret) { |
| @@ -5284,7 +5285,8 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, · 2257 unmodified lines | |||
| 5284 | /* for QCA6390 bss peer must be created before vdev_start */ | 5285 | /* for QCA6390 bss peer must be created before vdev_start */ |
| 5285 | if (ab->hw_params.vdev_start_delay && | 5286 | if (ab->hw_params.vdev_start_delay && |
| 5286 | arvif->vdev_type != WMI_VDEV_TYPE_AP && | 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 | memcpy(&arvif->chanctx, ctx, sizeof(*ctx)); | 5290 | memcpy(&arvif->chanctx, ctx, sizeof(*ctx)); |
| 5289 | ret = 0; | 5291 | ret = 0; |
| 5290 | goto out; | 5292 | goto out; |
| @@ -5295,7 +5297,9 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, · 4 unmodified lines | |||
| 5295 | goto out; | 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 | param.vdev_id = arvif->vdev_id; | 5303 | param.vdev_id = arvif->vdev_id; |
| 5300 | param.peer_type = WMI_PEER_TYPE_DEFAULT; | 5304 | param.peer_type = WMI_PEER_TYPE_DEFAULT; |
| 5301 | param.peer_addr = ar->mac_addr; | 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 | PCIE_QSERDES_COM_SYSCLK_EN_SEL_REG, | 274 | PCIE_QSERDES_COM_SYSCLK_EN_SEL_REG, |
| 275 | PCIE_QSERDES_COM_SYSCLK_EN_SEL_VAL, | 275 | PCIE_QSERDES_COM_SYSCLK_EN_SEL_VAL, |
| 276 | PCIE_QSERDES_COM_SYSCLK_EN_SEL_MSK); | 276 | PCIE_QSERDES_COM_SYSCLK_EN_SEL_MSK); |
| 277 | if (!ret) { | 277 | if (ret) { |
| 278 | ath11k_warn(ab, "failed to set sysclk: %d\n", ret); | 278 | ath11k_warn(ab, "failed to set sysclk: %d\n", ret); |
| 279 | return ret; | 279 | return ret; |
| 280 | } | 280 | } |
| @@ -283,7 +283,7 @@ static int ath11k_pci_fix_l1ss(struct ath11k_base *ab) · 2 unmodified lines | |||
| 283 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG1_REG, | 283 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG1_REG, |
| 284 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG1_VAL, | 284 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG1_VAL, |
| 285 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK); | 285 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK); |
| 286 | if (!ret) { | 286 | if (ret) { |
| 287 | ath11k_warn(ab, "failed to set dtct config1 error: %d\n", ret); | 287 | ath11k_warn(ab, "failed to set dtct config1 error: %d\n", ret); |
| 288 | return ret; | 288 | return ret; |
| 289 | } | 289 | } |
| @@ -292,7 +292,7 @@ static int ath11k_pci_fix_l1ss(struct ath11k_base *ab) · 2 unmodified lines | |||
| 292 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG2_REG, | 292 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG2_REG, |
| 293 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG2_VAL, | 293 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG2_VAL, |
| 294 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK); | 294 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK); |
| 295 | if (!ret) { | 295 | if (ret) { |
| 296 | ath11k_warn(ab, "failed to set dtct config2: %d\n", ret); | 296 | ath11k_warn(ab, "failed to set dtct config2: %d\n", ret); |
| 297 | return ret; | 297 | return ret; |
| 298 | } | 298 | } |
| @@ -301,7 +301,7 @@ static int ath11k_pci_fix_l1ss(struct ath11k_base *ab) · 2 unmodified lines | |||
| 301 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG4_REG, | 301 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG4_REG, |
| 302 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG4_VAL, | 302 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG4_VAL, |
| 303 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK); | 303 | PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK); |
| 304 | if (!ret) { | 304 | if (ret) { |
| 305 | ath11k_warn(ab, "failed to set dtct config4: %d\n", ret); | 305 | ath11k_warn(ab, "failed to set dtct config4: %d\n", ret); |
| 306 | return ret; | 306 | return ret; |
| 307 | } | 307 | } |
| @@ -886,6 +886,32 @@ static void ath11k_pci_free_region(struct ath11k_pci *ab_pci) · 578 unmodified lines | |||
| 886 | pci_disable_device(pci_dev); | 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 | static int ath11k_pci_power_up(struct ath11k_base *ab) | 915 | static int ath11k_pci_power_up(struct ath11k_base *ab) |
| 890 | { | 916 | { |
| 891 | struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); | 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 | clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); | 921 | clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); |
| 896 | ath11k_pci_sw_reset(ab_pci->ab, true); | 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 | ret = ath11k_mhi_start(ab_pci); | 929 | ret = ath11k_mhi_start(ab_pci); |
| 899 | if (ret) { | 930 | if (ret) { |
| 900 | ath11k_err(ab, "failed to start mhi: %d\n", ret); | 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 | struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); | 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 | ath11k_pci_force_wake(ab_pci->ab); | 945 | ath11k_pci_force_wake(ab_pci->ab); |
| 912 | ath11k_mhi_stop(ab_pci); | 946 | ath11k_mhi_stop(ab_pci); |
| 913 | clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); | 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 | set_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); | 1000 | set_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); |
| 967 | 1001 | ||
| 1002 | ath11k_pci_aspm_restore(ab_pci); | ||
| 1003 | |||
| 968 | ath11k_pci_ce_irqs_enable(ab); | 1004 | ath11k_pci_ce_irqs_enable(ab); |
| 969 | ath11k_ce_rx_post_buf(ab); | 1005 | ath11k_ce_rx_post_buf(ab); |
| 970 | 1006 | ||
| @@ -63,6 +63,7 @@ struct ath11k_msi_config { · 62 unmodified lines | |||
| 63 | enum ath11k_pci_flags { | 63 | enum ath11k_pci_flags { |
| 64 | ATH11K_PCI_FLAG_INIT_DONE, | 64 | ATH11K_PCI_FLAG_INIT_DONE, |
| 65 | ATH11K_PCI_FLAG_IS_MSI_64, | 65 | ATH11K_PCI_FLAG_IS_MSI_64, |
| 66 | ATH11K_PCI_ASPM_RESTORE, | ||
| 66 | }; | 67 | }; |
| 67 | 68 | ||
| 68 | struct ath11k_pci { | 69 | struct ath11k_pci { |
| @@ -80,6 +81,7 @@ struct ath11k_pci { · 11 unmodified lines | |||
| 80 | 81 | ||
| 81 | /* enum ath11k_pci_flags */ | 82 | /* enum ath11k_pci_flags */ |
| 82 | unsigned long flags; | 83 | unsigned long flags; |
| 84 | u16 link_ctl; | ||
| 83 | }; | 85 | }; |
| 84 | 86 | ||
| 85 | static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab) | 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 | return NULL; | 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 | void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id) | 96 | void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id) |
| 80 | { | 97 | { |
| 81 | struct ath11k_peer *peer; | 98 | struct ath11k_peer *peer; |
| @@ -43,5 +43,7 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, · 42 unmodified lines | |||
| 43 | struct ieee80211_sta *sta, struct peer_create_params *param); | 43 | struct ieee80211_sta *sta, struct peer_create_params *param); |
| 44 | int ath11k_wait_for_peer_delete_done(struct ath11k *ar, u32 vdev_id, | 44 | int ath11k_wait_for_peer_delete_done(struct ath11k *ar, u32 vdev_id, |
| 45 | const u8 *addr); | 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 | #endif /* _PEER_H_ */ | 49 | #endif /* _PEER_H_ */ |
| @@ -1660,6 +1660,7 @@ static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab) · 1659 unmodified lines | |||
| 1660 | struct qmi_wlanfw_respond_mem_resp_msg_v01 resp; | 1660 | struct qmi_wlanfw_respond_mem_resp_msg_v01 resp; |
| 1661 | struct qmi_txn txn = {}; | 1661 | struct qmi_txn txn = {}; |
| 1662 | int ret = 0, i; | 1662 | int ret = 0, i; |
| 1663 | bool delayed; | ||
| 1663 | 1664 | ||
| 1664 | req = kzalloc(sizeof(*req), GFP_KERNEL); | 1665 | req = kzalloc(sizeof(*req), GFP_KERNEL); |
| 1665 | if (!req) | 1666 | if (!req) |
| @@ -1672,11 +1673,13 @@ static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab) · 6 unmodified lines | |||
| 1672 | * failure to FW and FW will then request mulitple blocks of small | 1673 | * failure to FW and FW will then request mulitple blocks of small |
| 1673 | * chunk size memory. | 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 | ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi delays mem_request %d\n", | 1678 | ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi delays mem_request %d\n", |
| 1677 | ab->qmi.mem_seg_count); | 1679 | ab->qmi.mem_seg_count); |
| 1678 | memset(req, 0, sizeof(*req)); | 1680 | memset(req, 0, sizeof(*req)); |
| 1679 | } else { | 1681 | } else { |
| 1682 | delayed = false; | ||
| 1680 | req->mem_seg_len = ab->qmi.mem_seg_count; | 1683 | req->mem_seg_len = ab->qmi.mem_seg_count; |
| 1681 | 1684 | ||
| 1682 | for (i = 0; i < req->mem_seg_len ; i++) { | 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 | if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { | 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 | ath11k_warn(ab, "Respond mem req failed, result: %d, err: %d\n", | 1720 | ath11k_warn(ab, "Respond mem req failed, result: %d, err: %d\n", |
| 1712 | resp.resp.result, resp.resp.error); | 1721 | resp.resp.result, resp.resp.error); |
| 1713 | ret = -EINVAL; | 1722 | ret = -EINVAL; |
| @@ -1742,6 +1751,8 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab) · 28 unmodified lines | |||
| 1742 | int i; | 1751 | int i; |
| 1743 | struct target_mem_chunk *chunk; | 1752 | struct target_mem_chunk *chunk; |
| 1744 | 1753 | ||
| 1754 | ab->qmi.target_mem_delayed = false; | ||
| 1755 | |||
| 1745 | for (i = 0; i < ab->qmi.mem_seg_count; i++) { | 1756 | for (i = 0; i < ab->qmi.mem_seg_count; i++) { |
| 1746 | chunk = &ab->qmi.target_mem[i]; | 1757 | chunk = &ab->qmi.target_mem[i]; |
| 1747 | chunk->vaddr = dma_alloc_coherent(ab->dev, | 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 | &chunk->paddr, | 1760 | &chunk->paddr, |
| 1750 | GFP_KERNEL); | 1761 | GFP_KERNEL); |
| 1751 | if (!chunk->vaddr) { | 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 | ath11k_err(ab, "failed to alloc memory, size: 0x%x, type: %u\n", | 1772 | ath11k_err(ab, "failed to alloc memory, size: 0x%x, type: %u\n", |
| 1753 | chunk->size, | 1773 | chunk->size, |
| 1754 | chunk->type); | 1774 | chunk->type); |
| @@ -2517,7 +2537,7 @@ static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl, · 762 unmodified lines | |||
| 2517 | ret); | 2537 | ret); |
| 2518 | return; | 2538 | return; |
| 2519 | } | 2539 | } |
| 2520 | } else if (msg->mem_seg_len > 2) { | 2540 | } else { |
| 2521 | ret = ath11k_qmi_alloc_target_mem_chunk(ab); | 2541 | ret = ath11k_qmi_alloc_target_mem_chunk(ab); |
| 2522 | if (ret) { | 2542 | if (ret) { |
| 2523 | ath11k_warn(ab, "qmi failed to alloc target memory: %d\n", | 2543 | ath11k_warn(ab, "qmi failed to alloc target memory: %d\n", |
| @@ -125,6 +125,7 @@ struct ath11k_qmi { · 124 unmodified lines | |||
| 125 | struct target_mem_chunk target_mem[ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01]; | 125 | struct target_mem_chunk target_mem[ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01]; |
| 126 | u32 mem_seg_count; | 126 | u32 mem_seg_count; |
| 127 | u32 target_mem_mode; | 127 | u32 target_mem_mode; |
| 128 | bool target_mem_delayed; | ||
| 128 | u8 cal_done; | 129 | u8 cal_done; |
| 129 | struct target_info target; | 130 | struct target_info target; |
| 130 | struct m3_mem_region m3_mem; | 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 | len = sizeof(*cmd); | 3460 | len = sizeof(*cmd); |
| 3461 | 3461 | ||
| 3462 | skb = ath11k_wmi_alloc_skb(wmi_ab, len); | 3462 | skb = ath11k_wmi_alloc_skb(wmi_ab, len); |
| 3463 | if (!skb) | ||
| 3464 | return -ENOMEM; | ||
| 3465 | |||
| 3463 | cmd = (struct wmi_pdev_set_hw_mode_cmd_param *)skb->data; | 3466 | cmd = (struct wmi_pdev_set_hw_mode_cmd_param *)skb->data; |
| 3464 | 3467 | ||
| 3465 | cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_SET_HW_MODE_CMD) | | 3468 | cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PDEV_SET_HW_MODE_CMD) | |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | config WIL6210 | 2 | config WIL6210 |
| 3 | tristate "Wilocity 60g WiFi card wil6210 support" | 3 | tristate "Wilocity 60g WiFi card wil6210 support" |
| 4 | select WANT_DEV_COREDUMP | 4 | select WANT_DEV_COREDUMP |
| 5 | select CRC32 | ||
| 5 | depends on CFG80211 | 6 | depends on CFG80211 |
| 6 | depends on PCI | 7 | depends on PCI |
| 7 | default n | 8 | default n |
| @@ -40,9 +40,9 @@ static const struct ieee80211_iface_limit if_limits[] = { · 39 unmodified lines | |||
| 40 | .types = BIT(NL80211_IFTYPE_ADHOC) | 40 | .types = BIT(NL80211_IFTYPE_ADHOC) |
| 41 | }, { | 41 | }, { |
| 42 | .max = 16, | 42 | .max = 16, |
| 43 | .types = BIT(NL80211_IFTYPE_AP) | | 43 | .types = BIT(NL80211_IFTYPE_AP) |
| 44 | #ifdef CONFIG_MAC80211_MESH | 44 | #ifdef CONFIG_MAC80211_MESH |
| 45 | BIT(NL80211_IFTYPE_MESH_POINT) | 45 | | BIT(NL80211_IFTYPE_MESH_POINT) |
| 46 | #endif | 46 | #endif |
| 47 | }, { | 47 | }, { |
| 48 | .max = MT7915_MAX_INTERFACES, | 48 | .max = MT7915_MAX_INTERFACES, |
| @@ -157,10 +157,14 @@ static void mt76s_net_worker(struct mt76_worker *w) · 156 unmodified lines | |||
| 157 | 157 | ||
| 158 | static int mt76s_process_tx_queue(struct mt76_dev *dev, struct mt76_queue *q) | 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 | struct mt76_queue_entry entry; | 160 | struct mt76_queue_entry entry; |
| 162 | int nframes = 0; | 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 | while (q->queued > 0) { | 168 | while (q->queued > 0) { |
| 165 | if (!q->entry[q->tail].done) | 169 | if (!q->entry[q->tail].done) |
| 166 | break; | 170 | break; |
| @@ -177,21 +181,12 @@ static int mt76s_process_tx_queue(struct mt76_dev *dev, struct mt76_queue *q) · 10 unmodified lines | |||
| 177 | nframes++; | 181 | nframes++; |
| 178 | } | 182 | } |
| 179 | 183 | ||
| 180 | wake = q->stopped && q->queued < q->ndesc - 8; | ||
| 181 | if (wake) | ||
| 182 | q->stopped = false; | ||
| 183 | |||
| 184 | if (!q->queued) | 184 | if (!q->queued) |
| 185 | wake_up(&dev->tx_wait); | 185 | wake_up(&dev->tx_wait); |
| 186 | 186 | ||
| 187 | if (mcu) | 187 | if (!mcu) |
| 188 | goto out; | 188 | mt76_txq_schedule(&dev->phy, q->qid); |
| 189 | |||
| 190 | mt76_txq_schedule(&dev->phy, q->qid); | ||
| 191 | 189 | ||
| 192 | if (wake) | ||
| 193 | ieee80211_wake_queue(dev->hw, q->qid); | ||
| 194 | out: | ||
| 195 | return nframes; | 190 | return nframes; |
| 196 | } | 191 | } |
| 197 | 192 | ||
| @@ -811,11 +811,12 @@ static void mt76u_status_worker(struct mt76_worker *w) · 810 unmodified lines | |||
| 811 | struct mt76_dev *dev = container_of(usb, struct mt76_dev, usb); | 811 | struct mt76_dev *dev = container_of(usb, struct mt76_dev, usb); |
| 812 | struct mt76_queue_entry entry; | 812 | struct mt76_queue_entry entry; |
| 813 | struct mt76_queue *q; | 813 | struct mt76_queue *q; |
| 814 | bool wake; | ||
| 815 | int i; | 814 | int i; |
| 816 | 815 | ||
| 817 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { | 816 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
| 818 | q = dev->phy.q_tx[i]; | 817 | q = dev->phy.q_tx[i]; |
| 818 | if (!q) | ||
| 819 | continue; | ||
| 819 | 820 | ||
| 820 | while (q->queued > 0) { | 821 | while (q->queued > 0) { |
| 821 | if (!q->entry[q->tail].done) | 822 | if (!q->entry[q->tail].done) |
| @@ -827,10 +828,6 @@ static void mt76u_status_worker(struct mt76_worker *w) · 5 unmodified lines | |||
| 827 | mt76_queue_tx_complete(dev, q, &entry); | 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 | if (!q->queued) | 831 | if (!q->queued) |
| 835 | wake_up(&dev->tx_wait); | 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 | if (dev->drv->tx_status_data && | 836 | if (dev->drv->tx_status_data && |
| 840 | !test_and_set_bit(MT76_READING_STATS, &dev->phy.state)) | 837 | !test_and_set_bit(MT76_READING_STATS, &dev->phy.state)) |
| 841 | queue_work(dev->wq, &dev->usb.stat_work); | 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 | rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, | 79 | rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, |
| 80 | "Firmware callback routine entered!\n"); | 80 | "Firmware callback routine entered!\n"); |
| 81 | complete(&rtlpriv->firmware_loading_complete); | ||
| 82 | if (!firmware) { | 81 | if (!firmware) { |
| 83 | if (rtlpriv->cfg->alt_fw_name) { | 82 | if (rtlpriv->cfg->alt_fw_name) { |
| 84 | err = request_firmware(&firmware, | 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 | pr_err("Selected firmware is not available\n"); | 91 | pr_err("Selected firmware is not available\n"); |
| 93 | rtlpriv->max_fw_size = 0; | 92 | rtlpriv->max_fw_size = 0; |
| 94 | return; | 93 | goto exit; |
| 95 | } | 94 | } |
| 96 | found_alt: | 95 | found_alt: |
| 97 | if (firmware->size > rtlpriv->max_fw_size) { | 96 | if (firmware->size > rtlpriv->max_fw_size) { |
| 98 | pr_err("Firmware is too big!\n"); | 97 | pr_err("Firmware is too big!\n"); |
| 99 | release_firmware(firmware); | 98 | release_firmware(firmware); |
| 100 | return; | 99 | goto exit; |
| 101 | } | 100 | } |
| 102 | if (!is_wow) { | 101 | if (!is_wow) { |
| 103 | memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, | 102 | memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, |
| @@ -109,6 +108,9 @@ found_alt: · 5 unmodified lines | |||
| 109 | rtlpriv->rtlhal.wowlan_fwsize = firmware->size; | 108 | rtlpriv->rtlhal.wowlan_fwsize = firmware->size; |
| 110 | } | 109 | } |
| 111 | release_firmware(firmware); | 110 | release_firmware(firmware); |
| 111 | |||
| 112 | exit: | ||
| 113 | complete(&rtlpriv->firmware_loading_complete); | ||
| 112 | } | 114 | } |
| 113 | 115 | ||
| 114 | void rtl_fw_cb(const struct firmware *firmware, void *context) | 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 | EXPORT_SYMBOL_GPL(nvme_reset_ctrl); | 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 | int ret; | 184 | int ret; |
| 185 | 185 | ||
| @@ -192,7 +192,6 @@ int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl) · 6 unmodified lines | |||
| 192 | 192 | ||
| 193 | return ret; | 193 | return ret; |
| 194 | } | 194 | } |
| 195 | EXPORT_SYMBOL_GPL(nvme_reset_ctrl_sync); | ||
| 196 | 195 | ||
| 197 | static void nvme_do_delete_ctrl(struct nvme_ctrl *ctrl) | 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 | req->__sector = nvme_lba_to_sect(req->q->queuedata, | 330 | req->__sector = nvme_lba_to_sect(req->q->queuedata, |
| 332 | le64_to_cpu(nvme_req(req)->result.u64)); | 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 | blk_mq_end_request(req, status); | 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 | EXPORT_SYMBOL_GPL(nvme_alloc_request); | 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 | struct nvme_command *cmd, blk_mq_req_flags_t flags, int qid) | 581 | struct nvme_command *cmd, blk_mq_req_flags_t flags, int qid) |
| 583 | { | 582 | { |
| 584 | struct request *req; | 583 | struct request *req; |
| @@ -589,7 +588,6 @@ struct request *nvme_alloc_request_qid(struct request_queue *q, · 4 unmodified lines | |||
| 589 | nvme_init_request(req, cmd); | 588 | nvme_init_request(req, cmd); |
| 590 | return req; | 589 | return req; |
| 591 | } | 590 | } |
| 592 | EXPORT_SYMBOL_GPL(nvme_alloc_request_qid); | ||
| 593 | 591 | ||
| 594 | static int nvme_toggle_streams(struct nvme_ctrl *ctrl, bool enable) | 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 | NULL, | 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 | static bool nvme_validate_cntlid(struct nvme_subsystem *subsys, | 2864 | static bool nvme_validate_cntlid(struct nvme_subsystem *subsys, |
| 2862 | struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) | 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 | if ((id->cmic & NVME_CTRL_CMIC_MULTI_CTRL) || | 2882 | if ((id->cmic & NVME_CTRL_CMIC_MULTI_CTRL) || |
| 2880 | (ctrl->opts && ctrl->opts->discovery_nqn)) | 2883 | nvme_discovery_ctrl(ctrl)) |
| 2881 | continue; | 2884 | continue; |
| 2882 | 2885 | ||
| 2883 | dev_err(ctrl->device, | 2886 | dev_err(ctrl->device, |
| @@ -3146,7 +3149,7 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) · 262 unmodified lines | |||
| 3146 | goto out_free; | 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 | dev_err(ctrl->device, | 3153 | dev_err(ctrl->device, |
| 3151 | "keep-alive support is mandatory for fabrics\n"); | 3154 | "keep-alive support is mandatory for fabrics\n"); |
| 3152 | ret = -EINVAL; | 3155 | ret = -EINVAL; |
| @@ -3186,7 +3189,7 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) · 33 unmodified lines | |||
| 3186 | if (ret < 0) | 3189 | if (ret < 0) |
| 3187 | return ret; | 3190 | return ret; |
| 3188 | 3191 | ||
| 3189 | if (!ctrl->identified) { | 3192 | if (!ctrl->identified && !nvme_discovery_ctrl(ctrl)) { |
| 3190 | ret = nvme_hwmon_init(ctrl); | 3193 | ret = nvme_hwmon_init(ctrl); |
| 3191 | if (ret < 0) | 3194 | if (ret < 0) |
| 3192 | return ret; | 3195 | return ret; |
| @@ -166,6 +166,7 @@ struct nvme_fc_ctrl { · 165 unmodified lines | |||
| 166 | struct blk_mq_tag_set admin_tag_set; | 166 | struct blk_mq_tag_set admin_tag_set; |
| 167 | struct blk_mq_tag_set tag_set; | 167 | struct blk_mq_tag_set tag_set; |
| 168 | 168 | ||
| 169 | struct work_struct ioerr_work; | ||
| 169 | struct delayed_work connect_work; | 170 | struct delayed_work connect_work; |
| 170 | 171 | ||
| 171 | struct kref ref; | 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 | static void | 1901 | static void |
| 1892 | nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) | 1902 | nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) |
| 1893 | { | 1903 | { |
| @@ -2046,7 +2056,7 @@ done: · 152 unmodified lines | |||
| 2046 | 2056 | ||
| 2047 | check_error: | 2057 | check_error: |
| 2048 | if (terminate_assoc) | 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 | static int | 2062 | static int |
| @@ -3233,6 +3243,7 @@ nvme_fc_delete_ctrl(struct nvme_ctrl *nctrl) · 1180 unmodified lines | |||
| 3233 | { | 3243 | { |
| 3234 | struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl); | 3244 | struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl); |
| 3235 | 3245 | ||
| 3246 | cancel_work_sync(&ctrl->ioerr_work); | ||
| 3236 | cancel_delayed_work_sync(&ctrl->connect_work); | 3247 | cancel_delayed_work_sync(&ctrl->connect_work); |
| 3237 | /* | 3248 | /* |
| 3238 | * kill the association on the link side. this will block | 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 | INIT_WORK(&ctrl->ctrl.reset_work, nvme_fc_reset_ctrl_work); | 3461 | INIT_WORK(&ctrl->ctrl.reset_work, nvme_fc_reset_ctrl_work); |
| 3451 | INIT_DELAYED_WORK(&ctrl->connect_work, nvme_fc_connect_ctrl_work); | 3462 | INIT_DELAYED_WORK(&ctrl->connect_work, nvme_fc_connect_ctrl_work); |
| 3463 | INIT_WORK(&ctrl->ioerr_work, nvme_fc_ctrl_ioerr_work); | ||
| 3452 | spin_lock_init(&ctrl->lock); | 3464 | spin_lock_init(&ctrl->lock); |
| 3453 | 3465 | ||
| 3454 | /* io queue count */ | 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 | fail_ctrl: | 3553 | fail_ctrl: |
| 3542 | nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_DELETING); | 3554 | nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_DELETING); |
| 3555 | cancel_work_sync(&ctrl->ioerr_work); | ||
| 3543 | cancel_work_sync(&ctrl->ctrl.reset_work); | 3556 | cancel_work_sync(&ctrl->ctrl.reset_work); |
| 3544 | cancel_delayed_work_sync(&ctrl->connect_work); | 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 | #define NVME_QID_ANY -1 | 610 | #define NVME_QID_ANY -1 |
| 611 | struct request *nvme_alloc_request(struct request_queue *q, | 611 | struct request *nvme_alloc_request(struct request_queue *q, |
| 612 | struct nvme_command *cmd, blk_mq_req_flags_t flags); | 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 | void nvme_cleanup_cmd(struct request *req); | 613 | void nvme_cleanup_cmd(struct request *req); |
| 616 | blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req, | 614 | blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req, |
| 617 | struct nvme_command *cmd); | 615 | struct nvme_command *cmd); |
| @@ -630,7 +628,6 @@ int nvme_get_features(struct nvme_ctrl *dev, unsigned int fid, · 12 unmodified lines | |||
| 630 | int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count); | 628 | int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count); |
| 631 | void nvme_stop_keep_alive(struct nvme_ctrl *ctrl); | 629 | void nvme_stop_keep_alive(struct nvme_ctrl *ctrl); |
| 632 | int nvme_reset_ctrl(struct nvme_ctrl *ctrl); | 630 | int nvme_reset_ctrl(struct nvme_ctrl *ctrl); |
| 633 | int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl); | ||
| 634 | int nvme_try_sched_reset(struct nvme_ctrl *ctrl); | 631 | int nvme_try_sched_reset(struct nvme_ctrl *ctrl); |
| 635 | int nvme_delete_ctrl(struct nvme_ctrl *ctrl); | 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 | kblockd_schedule_work(&head->requeue_work); | 672 | kblockd_schedule_work(&head->requeue_work); |
| 676 | } | 673 | } |
| 677 | 674 | ||
| 678 | static inline void nvme_trace_bio_complete(struct request *req, | 675 | static inline void nvme_trace_bio_complete(struct request *req) |
| 679 | blk_status_t status) | ||
| 680 | { | 676 | { |
| 681 | struct nvme_ns *ns = req->q->queuedata; | 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 | static inline void nvme_mpath_check_last_path(struct nvme_ns *ns) | 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, | 730 | static inline void nvme_trace_bio_complete(struct request *req) |
| 735 | blk_status_t status) | ||
| 736 | { | 731 | { |
| 737 | } | 732 | } |
| 738 | static inline int nvme_mpath_init(struct nvme_ctrl *ctrl, | 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 | static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx) | 967 | static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx) |
| 968 | { | 968 | { |
| 969 | struct nvme_completion *cqe = &nvmeq->cqes[idx]; | 969 | struct nvme_completion *cqe = &nvmeq->cqes[idx]; |
| 970 | __u16 command_id = READ_ONCE(cqe->command_id); | ||
| 970 | struct request *req; | 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 | * aborts. We don't even bother to allocate a struct request | 976 | * aborts. We don't even bother to allocate a struct request |
| 976 | * for them but rather special case them here. | 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 | nvme_complete_async_event(&nvmeq->dev->ctrl, | 980 | nvme_complete_async_event(&nvmeq->dev->ctrl, |
| 980 | cqe->status, &cqe->result); | 981 | cqe->status, &cqe->result); |
| 981 | return; | 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 | if (unlikely(!req)) { | 986 | if (unlikely(!req)) { |
| 986 | dev_warn(nvmeq->dev->ctrl.device, | 987 | dev_warn(nvmeq->dev->ctrl.device, |
| 987 | "invalid id %d completed on queue %d\n", | 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 | return; | 990 | return; |
| 990 | } | 991 | } |
| 991 | 992 | ||
| @@ -3196,7 +3197,8 @@ static const struct pci_device_id nvme_id_table[] = { · 2204 unmodified lines | |||
| 3196 | { PCI_DEVICE(0x144d, 0xa821), /* Samsung PM1725 */ | 3197 | { PCI_DEVICE(0x144d, 0xa821), /* Samsung PM1725 */ |
| 3197 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, | 3198 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, |
| 3198 | { PCI_DEVICE(0x144d, 0xa822), /* Samsung PM1725a */ | 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 | { PCI_DEVICE(0x1d1d, 0x1f1f), /* LighNVM qemu device */ | 3202 | { PCI_DEVICE(0x1d1d, 0x1f1f), /* LighNVM qemu device */ |
| 3201 | .driver_data = NVME_QUIRK_LIGHTNVM, }, | 3203 | .driver_data = NVME_QUIRK_LIGHTNVM, }, |
| 3202 | { PCI_DEVICE(0x1d1d, 0x2807), /* CNEX WL */ | 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 | static inline size_t nvme_tcp_req_cur_length(struct nvme_tcp_request *req) | 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 | req->pdu_len - req->pdu_sent); | 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 | static inline void nvme_tcp_queue_request(struct nvme_tcp_request *req, | 275 | static inline void nvme_tcp_queue_request(struct nvme_tcp_request *req, |
| 266 | bool sync, bool last) | 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 | * directly, otherwise queue io_work. Also, only do that if we | 286 | * directly, otherwise queue io_work. Also, only do that if we |
| 277 | * are on the same cpu, so we don't introduce contention. | 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 | sync && empty && mutex_trylock(&queue->send_mutex)) { | 290 | sync && empty && mutex_trylock(&queue->send_mutex)) { |
| 281 | queue->more_requests = !last; | 291 | queue->more_requests = !last; |
| 282 | nvme_tcp_try_send(queue); | 292 | nvme_tcp_send_all(queue); |
| 283 | queue->more_requests = false; | 293 | queue->more_requests = false; |
| 284 | mutex_unlock(&queue->send_mutex); | 294 | mutex_unlock(&queue->send_mutex); |
| 285 | } else if (last) { | 295 | } else if (last) { |
| @@ -1501,7 +1501,8 @@ static ssize_t · 1500 unmodified lines | |||
| 1501 | fcloop_set_cmd_drop(struct device *dev, struct device_attribute *attr, | 1501 | fcloop_set_cmd_drop(struct device *dev, struct device_attribute *attr, |
| 1502 | const char *buf, size_t count) | 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 | if (sscanf(buf, "%x:%d:%d", &opcode, &starting, &amount) != 3) | 1507 | if (sscanf(buf, "%x:%d:%d", &opcode, &starting, &amount) != 3) |
| 1507 | return -EBADRQC; | 1508 | return -EBADRQC; |
| @@ -1588,8 +1589,8 @@ out_destroy_class: · 80 unmodified lines | |||
| 1588 | 1589 | ||
| 1589 | static void __exit fcloop_exit(void) | 1590 | static void __exit fcloop_exit(void) |
| 1590 | { | 1591 | { |
| 1591 | struct fcloop_lport *lport; | 1592 | struct fcloop_lport *lport = NULL; |
| 1592 | struct fcloop_nport *nport; | 1593 | struct fcloop_nport *nport = NULL; |
| 1593 | struct fcloop_tport *tport; | 1594 | struct fcloop_tport *tport; |
| 1594 | struct fcloop_rport *rport; | 1595 | struct fcloop_rport *rport; |
| 1595 | unsigned long flags; | 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 | ndev->inline_data_size = nport->inline_data_size; | 1221 | ndev->inline_data_size = nport->inline_data_size; |
| 1222 | ndev->inline_page_count = inline_page_count; | 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 | ndev->device = cm_id->device; | 1231 | ndev->device = cm_id->device; |
| 1224 | kref_init(&ndev->ref); | 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 | spin_lock_irqsave(&queue->state_lock, flags); | 1649 | spin_lock_irqsave(&queue->state_lock, flags); |
| 1642 | switch (queue->state) { | 1650 | switch (queue->state) { |
| 1643 | case NVMET_RDMA_Q_CONNECTING: | 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 | case NVMET_RDMA_Q_LIVE: | 1662 | case NVMET_RDMA_Q_LIVE: |
| 1645 | queue->state = NVMET_RDMA_Q_DISCONNECTING; | 1663 | queue->state = NVMET_RDMA_Q_DISCONNECTING; |
| 1646 | disconnect = true; | 1664 | disconnect = true; |
| @@ -1845,14 +1863,6 @@ static int nvmet_rdma_enable_port(struct nvmet_rdma_port *port) · 198 unmodified lines | |||
| 1845 | goto out_destroy_id; | 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 | port->cm_id = cm_id; | 1866 | port->cm_id = cm_id; |
| 1857 | return 0; | 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 | if (IS_ERR(opp_table->clk)) { | 1092 | if (IS_ERR(opp_table->clk)) { |
| 1093 | ret = PTR_ERR(opp_table->clk); | 1093 | ret = PTR_ERR(opp_table->clk); |
| 1094 | if (ret == -EPROBE_DEFER) | 1094 | if (ret == -EPROBE_DEFER) |
| 1095 | goto err; | 1095 | goto remove_opp_dev; |
| 1096 | 1096 | ||
| 1097 | dev_dbg(dev, "%s: Couldn't find clock: %d\n", __func__, ret); | 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 | ret = dev_pm_opp_of_find_icc_paths(dev, opp_table); | 1101 | ret = dev_pm_opp_of_find_icc_paths(dev, opp_table); |
| 1102 | if (ret) { | 1102 | if (ret) { |
| 1103 | if (ret == -EPROBE_DEFER) | 1103 | if (ret == -EPROBE_DEFER) |
| 1104 | goto err; | 1104 | goto put_clk; |
| 1105 | 1105 | ||
| 1106 | dev_warn(dev, "%s: Error finding interconnect paths: %d\n", | 1106 | dev_warn(dev, "%s: Error finding interconnect paths: %d\n", |
| 1107 | __func__, ret); | 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 | return opp_table; | 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 | err: | 1121 | err: |
| 1117 | kfree(opp_table); | 1122 | kfree(opp_table); |
| 1118 | return ERR_PTR(ret); | 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 | return per_cpu(hw_events->irq, cpu); | 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 | * PMU hardware loses all context when a CPU goes offline. | 730 | * PMU hardware loses all context when a CPU goes offline. |
| 736 | * When a CPU is hotplugged back in, since some hardware registers are | 731 | * When a CPU is hotplugged back in, since some hardware registers are |
| @@ -64,6 +64,7 @@ config DP83640_PHY · 63 unmodified lines | |||
| 64 | depends on NETWORK_PHY_TIMESTAMPING | 64 | depends on NETWORK_PHY_TIMESTAMPING |
| 65 | depends on PHYLIB | 65 | depends on PHYLIB |
| 66 | depends on PTP_1588_CLOCK | 66 | depends on PTP_1588_CLOCK |
| 67 | select CRC32 | ||
| 67 | help | 68 | help |
| 68 | Supports the DP83640 PHYTER with IEEE 1588 features. | 69 | Supports the DP83640 PHYTER with IEEE 1588 features. |
| 69 | 70 | ||
| @@ -78,6 +79,7 @@ config DP83640_PHY · 8 unmodified lines | |||
| 78 | config PTP_1588_CLOCK_INES | 79 | config PTP_1588_CLOCK_INES |
| 79 | tristate "ZHAW InES PTP time stamping IP core" | 80 | tristate "ZHAW InES PTP time stamping IP core" |
| 80 | depends on NETWORK_PHY_TIMESTAMPING | 81 | depends on NETWORK_PHY_TIMESTAMPING |
| 82 | depends on HAS_IOMEM | ||
| 81 | depends on PHYLIB | 83 | depends on PHYLIB |
| 82 | depends on PTP_1588_CLOCK | 84 | depends on PTP_1588_CLOCK |
| 83 | help | 85 | help |
| @@ -881,6 +881,7 @@ config REGULATOR_QCOM_RPM · 880 unmodified lines | |||
| 881 | config REGULATOR_QCOM_RPMH | 881 | config REGULATOR_QCOM_RPMH |
| 882 | tristate "Qualcomm Technologies, Inc. RPMh regulator driver" | 882 | tristate "Qualcomm Technologies, Inc. RPMh regulator driver" |
| 883 | depends on QCOM_RPMH || (QCOM_RPMH=n && COMPILE_TEST) | 883 | depends on QCOM_RPMH || (QCOM_RPMH=n && COMPILE_TEST) |
| 884 | depends on QCOM_COMMAND_DB || (QCOM_COMMAND_DB=n && COMPILE_TEST) | ||
| 884 | help | 885 | help |
| 885 | This driver supports control of PMIC regulators via the RPMh hardware | 886 | This driver supports control of PMIC regulators via the RPMh hardware |
| 886 | block found on Qualcomm Technologies Inc. SoCs. RPMh regulator | 887 | block found on Qualcomm Technologies Inc. SoCs. RPMh regulator |
| @@ -15,6 +15,36 @@ · 14 unmodified lines | |||
| 15 | #include <linux/regulator/of_regulator.h> | 15 | #include <linux/regulator/of_regulator.h> |
| 16 | #include <linux/slab.h> | 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 | * BD718(37/47/50) have two "enable control modes". ON/OFF can either be | 49 | * BD718(37/47/50) have two "enable control modes". ON/OFF can either be |
| 20 | * controlled by software - or by PMIC internal HW state machine. Whether | 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 | .vsel_mask = DVS_BUCK_RUN_MASK, | 643 | .vsel_mask = DVS_BUCK_RUN_MASK, |
| 614 | .enable_reg = BD718XX_REG_BUCK1_CTRL, | 644 | .enable_reg = BD718XX_REG_BUCK1_CTRL, |
| 615 | .enable_mask = BD718XX_BUCK_EN, | 645 | .enable_mask = BD718XX_BUCK_EN, |
| 646 | .enable_time = BD71847_BUCK1_STARTUP_TIME, | ||
| 616 | .owner = THIS_MODULE, | 647 | .owner = THIS_MODULE, |
| 617 | .of_parse_cb = buck_set_hw_dvs_levels, | 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 | .vsel_mask = DVS_BUCK_RUN_MASK, | 677 | .vsel_mask = DVS_BUCK_RUN_MASK, |
| 647 | .enable_reg = BD718XX_REG_BUCK2_CTRL, | 678 | .enable_reg = BD718XX_REG_BUCK2_CTRL, |
| 648 | .enable_mask = BD718XX_BUCK_EN, | 679 | .enable_mask = BD718XX_BUCK_EN, |
| 680 | .enable_time = BD71847_BUCK2_STARTUP_TIME, | ||
| 649 | .owner = THIS_MODULE, | 681 | .owner = THIS_MODULE, |
| 650 | .of_parse_cb = buck_set_hw_dvs_levels, | 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 | .linear_range_selectors = bd71847_buck3_volt_range_sel, | 712 | .linear_range_selectors = bd71847_buck3_volt_range_sel, |
| 681 | .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, | 713 | .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, |
| 682 | .enable_mask = BD718XX_BUCK_EN, | 714 | .enable_mask = BD718XX_BUCK_EN, |
| 715 | .enable_time = BD71847_BUCK3_STARTUP_TIME, | ||
| 683 | .owner = THIS_MODULE, | 716 | .owner = THIS_MODULE, |
| 684 | }, | 717 | }, |
| 685 | .init = { | 718 | .init = { |
| @@ -706,6 +739,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 20 unmodified lines | |||
| 706 | .vsel_range_mask = BD71847_BUCK4_RANGE_MASK, | 739 | .vsel_range_mask = BD71847_BUCK4_RANGE_MASK, |
| 707 | .linear_range_selectors = bd71847_buck4_volt_range_sel, | 740 | .linear_range_selectors = bd71847_buck4_volt_range_sel, |
| 708 | .enable_mask = BD718XX_BUCK_EN, | 741 | .enable_mask = BD718XX_BUCK_EN, |
| 742 | .enable_time = BD71847_BUCK4_STARTUP_TIME, | ||
| 709 | .owner = THIS_MODULE, | 743 | .owner = THIS_MODULE, |
| 710 | }, | 744 | }, |
| 711 | .init = { | 745 | .init = { |
| @@ -727,6 +761,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 15 unmodified lines | |||
| 727 | .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK, | 761 | .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK, |
| 728 | .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, | 762 | .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, |
| 729 | .enable_mask = BD718XX_BUCK_EN, | 763 | .enable_mask = BD718XX_BUCK_EN, |
| 764 | .enable_time = BD71847_BUCK5_STARTUP_TIME, | ||
| 730 | .owner = THIS_MODULE, | 765 | .owner = THIS_MODULE, |
| 731 | }, | 766 | }, |
| 732 | .init = { | 767 | .init = { |
| @@ -750,6 +785,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 17 unmodified lines | |||
| 750 | .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK, | 785 | .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK, |
| 751 | .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, | 786 | .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, |
| 752 | .enable_mask = BD718XX_BUCK_EN, | 787 | .enable_mask = BD718XX_BUCK_EN, |
| 788 | .enable_time = BD71847_BUCK6_STARTUP_TIME, | ||
| 753 | .owner = THIS_MODULE, | 789 | .owner = THIS_MODULE, |
| 754 | }, | 790 | }, |
| 755 | .init = { | 791 | .init = { |
| @@ -775,6 +811,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 19 unmodified lines | |||
| 775 | .linear_range_selectors = bd718xx_ldo1_volt_range_sel, | 811 | .linear_range_selectors = bd718xx_ldo1_volt_range_sel, |
| 776 | .enable_reg = BD718XX_REG_LDO1_VOLT, | 812 | .enable_reg = BD718XX_REG_LDO1_VOLT, |
| 777 | .enable_mask = BD718XX_LDO_EN, | 813 | .enable_mask = BD718XX_LDO_EN, |
| 814 | .enable_time = BD71847_LDO1_STARTUP_TIME, | ||
| 778 | .owner = THIS_MODULE, | 815 | .owner = THIS_MODULE, |
| 779 | }, | 816 | }, |
| 780 | .init = { | 817 | .init = { |
| @@ -796,6 +833,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 15 unmodified lines | |||
| 796 | .n_voltages = ARRAY_SIZE(ldo_2_volts), | 833 | .n_voltages = ARRAY_SIZE(ldo_2_volts), |
| 797 | .enable_reg = BD718XX_REG_LDO2_VOLT, | 834 | .enable_reg = BD718XX_REG_LDO2_VOLT, |
| 798 | .enable_mask = BD718XX_LDO_EN, | 835 | .enable_mask = BD718XX_LDO_EN, |
| 836 | .enable_time = BD71847_LDO2_STARTUP_TIME, | ||
| 799 | .owner = THIS_MODULE, | 837 | .owner = THIS_MODULE, |
| 800 | }, | 838 | }, |
| 801 | .init = { | 839 | .init = { |
| @@ -818,6 +856,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 16 unmodified lines | |||
| 818 | .vsel_mask = BD718XX_LDO3_MASK, | 856 | .vsel_mask = BD718XX_LDO3_MASK, |
| 819 | .enable_reg = BD718XX_REG_LDO3_VOLT, | 857 | .enable_reg = BD718XX_REG_LDO3_VOLT, |
| 820 | .enable_mask = BD718XX_LDO_EN, | 858 | .enable_mask = BD718XX_LDO_EN, |
| 859 | .enable_time = BD71847_LDO3_STARTUP_TIME, | ||
| 821 | .owner = THIS_MODULE, | 860 | .owner = THIS_MODULE, |
| 822 | }, | 861 | }, |
| 823 | .init = { | 862 | .init = { |
| @@ -840,6 +879,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 16 unmodified lines | |||
| 840 | .vsel_mask = BD718XX_LDO4_MASK, | 879 | .vsel_mask = BD718XX_LDO4_MASK, |
| 841 | .enable_reg = BD718XX_REG_LDO4_VOLT, | 880 | .enable_reg = BD718XX_REG_LDO4_VOLT, |
| 842 | .enable_mask = BD718XX_LDO_EN, | 881 | .enable_mask = BD718XX_LDO_EN, |
| 882 | .enable_time = BD71847_LDO4_STARTUP_TIME, | ||
| 843 | .owner = THIS_MODULE, | 883 | .owner = THIS_MODULE, |
| 844 | }, | 884 | }, |
| 845 | .init = { | 885 | .init = { |
| @@ -865,6 +905,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 19 unmodified lines | |||
| 865 | .linear_range_selectors = bd71847_ldo5_volt_range_sel, | 905 | .linear_range_selectors = bd71847_ldo5_volt_range_sel, |
| 866 | .enable_reg = BD718XX_REG_LDO5_VOLT, | 906 | .enable_reg = BD718XX_REG_LDO5_VOLT, |
| 867 | .enable_mask = BD718XX_LDO_EN, | 907 | .enable_mask = BD718XX_LDO_EN, |
| 908 | .enable_time = BD71847_LDO5_STARTUP_TIME, | ||
| 868 | .owner = THIS_MODULE, | 909 | .owner = THIS_MODULE, |
| 869 | }, | 910 | }, |
| 870 | .init = { | 911 | .init = { |
| @@ -889,6 +930,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { · 18 unmodified lines | |||
| 889 | .vsel_mask = BD718XX_LDO6_MASK, | 930 | .vsel_mask = BD718XX_LDO6_MASK, |
| 890 | .enable_reg = BD718XX_REG_LDO6_VOLT, | 931 | .enable_reg = BD718XX_REG_LDO6_VOLT, |
| 891 | .enable_mask = BD718XX_LDO_EN, | 932 | .enable_mask = BD718XX_LDO_EN, |
| 933 | .enable_time = BD71847_LDO6_STARTUP_TIME, | ||
| 892 | .owner = THIS_MODULE, | 934 | .owner = THIS_MODULE, |
| 893 | }, | 935 | }, |
| 894 | .init = { | 936 | .init = { |
| @@ -942,6 +984,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 47 unmodified lines | |||
| 942 | .vsel_mask = DVS_BUCK_RUN_MASK, | 984 | .vsel_mask = DVS_BUCK_RUN_MASK, |
| 943 | .enable_reg = BD718XX_REG_BUCK1_CTRL, | 985 | .enable_reg = BD718XX_REG_BUCK1_CTRL, |
| 944 | .enable_mask = BD718XX_BUCK_EN, | 986 | .enable_mask = BD718XX_BUCK_EN, |
| 987 | .enable_time = BD71837_BUCK1_STARTUP_TIME, | ||
| 945 | .owner = THIS_MODULE, | 988 | .owner = THIS_MODULE, |
| 946 | .of_parse_cb = buck_set_hw_dvs_levels, | 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 | .vsel_mask = DVS_BUCK_RUN_MASK, | 1018 | .vsel_mask = DVS_BUCK_RUN_MASK, |
| 976 | .enable_reg = BD718XX_REG_BUCK2_CTRL, | 1019 | .enable_reg = BD718XX_REG_BUCK2_CTRL, |
| 977 | .enable_mask = BD718XX_BUCK_EN, | 1020 | .enable_mask = BD718XX_BUCK_EN, |
| 1021 | .enable_time = BD71837_BUCK2_STARTUP_TIME, | ||
| 978 | .owner = THIS_MODULE, | 1022 | .owner = THIS_MODULE, |
| 979 | .of_parse_cb = buck_set_hw_dvs_levels, | 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 | .vsel_mask = DVS_BUCK_RUN_MASK, | 1049 | .vsel_mask = DVS_BUCK_RUN_MASK, |
| 1006 | .enable_reg = BD71837_REG_BUCK3_CTRL, | 1050 | .enable_reg = BD71837_REG_BUCK3_CTRL, |
| 1007 | .enable_mask = BD718XX_BUCK_EN, | 1051 | .enable_mask = BD718XX_BUCK_EN, |
| 1052 | .enable_time = BD71837_BUCK3_STARTUP_TIME, | ||
| 1008 | .owner = THIS_MODULE, | 1053 | .owner = THIS_MODULE, |
| 1009 | .of_parse_cb = buck_set_hw_dvs_levels, | 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 | .vsel_mask = DVS_BUCK_RUN_MASK, | 1078 | .vsel_mask = DVS_BUCK_RUN_MASK, |
| 1034 | .enable_reg = BD71837_REG_BUCK4_CTRL, | 1079 | .enable_reg = BD71837_REG_BUCK4_CTRL, |
| 1035 | .enable_mask = BD718XX_BUCK_EN, | 1080 | .enable_mask = BD718XX_BUCK_EN, |
| 1081 | .enable_time = BD71837_BUCK4_STARTUP_TIME, | ||
| 1036 | .owner = THIS_MODULE, | 1082 | .owner = THIS_MODULE, |
| 1037 | .of_parse_cb = buck_set_hw_dvs_levels, | 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 | .linear_range_selectors = bd71837_buck5_volt_range_sel, | 1111 | .linear_range_selectors = bd71837_buck5_volt_range_sel, |
| 1066 | .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, | 1112 | .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, |
| 1067 | .enable_mask = BD718XX_BUCK_EN, | 1113 | .enable_mask = BD718XX_BUCK_EN, |
| 1114 | .enable_time = BD71837_BUCK5_STARTUP_TIME, | ||
| 1068 | .owner = THIS_MODULE, | 1115 | .owner = THIS_MODULE, |
| 1069 | }, | 1116 | }, |
| 1070 | .init = { | 1117 | .init = { |
| @@ -1088,6 +1135,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 17 unmodified lines | |||
| 1088 | .vsel_mask = BD71837_BUCK6_MASK, | 1135 | .vsel_mask = BD71837_BUCK6_MASK, |
| 1089 | .enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, | 1136 | .enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, |
| 1090 | .enable_mask = BD718XX_BUCK_EN, | 1137 | .enable_mask = BD718XX_BUCK_EN, |
| 1138 | .enable_time = BD71837_BUCK6_STARTUP_TIME, | ||
| 1091 | .owner = THIS_MODULE, | 1139 | .owner = THIS_MODULE, |
| 1092 | }, | 1140 | }, |
| 1093 | .init = { | 1141 | .init = { |
| @@ -1109,6 +1157,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 15 unmodified lines | |||
| 1109 | .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK, | 1157 | .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK, |
| 1110 | .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, | 1158 | .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, |
| 1111 | .enable_mask = BD718XX_BUCK_EN, | 1159 | .enable_mask = BD718XX_BUCK_EN, |
| 1160 | .enable_time = BD71837_BUCK7_STARTUP_TIME, | ||
| 1112 | .owner = THIS_MODULE, | 1161 | .owner = THIS_MODULE, |
| 1113 | }, | 1162 | }, |
| 1114 | .init = { | 1163 | .init = { |
| @@ -1132,6 +1181,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 17 unmodified lines | |||
| 1132 | .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK, | 1181 | .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK, |
| 1133 | .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, | 1182 | .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, |
| 1134 | .enable_mask = BD718XX_BUCK_EN, | 1183 | .enable_mask = BD718XX_BUCK_EN, |
| 1184 | .enable_time = BD71837_BUCK8_STARTUP_TIME, | ||
| 1135 | .owner = THIS_MODULE, | 1185 | .owner = THIS_MODULE, |
| 1136 | }, | 1186 | }, |
| 1137 | .init = { | 1187 | .init = { |
| @@ -1157,6 +1207,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 19 unmodified lines | |||
| 1157 | .linear_range_selectors = bd718xx_ldo1_volt_range_sel, | 1207 | .linear_range_selectors = bd718xx_ldo1_volt_range_sel, |
| 1158 | .enable_reg = BD718XX_REG_LDO1_VOLT, | 1208 | .enable_reg = BD718XX_REG_LDO1_VOLT, |
| 1159 | .enable_mask = BD718XX_LDO_EN, | 1209 | .enable_mask = BD718XX_LDO_EN, |
| 1210 | .enable_time = BD71837_LDO1_STARTUP_TIME, | ||
| 1160 | .owner = THIS_MODULE, | 1211 | .owner = THIS_MODULE, |
| 1161 | }, | 1212 | }, |
| 1162 | .init = { | 1213 | .init = { |
| @@ -1178,6 +1229,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 15 unmodified lines | |||
| 1178 | .n_voltages = ARRAY_SIZE(ldo_2_volts), | 1229 | .n_voltages = ARRAY_SIZE(ldo_2_volts), |
| 1179 | .enable_reg = BD718XX_REG_LDO2_VOLT, | 1230 | .enable_reg = BD718XX_REG_LDO2_VOLT, |
| 1180 | .enable_mask = BD718XX_LDO_EN, | 1231 | .enable_mask = BD718XX_LDO_EN, |
| 1232 | .enable_time = BD71837_LDO2_STARTUP_TIME, | ||
| 1181 | .owner = THIS_MODULE, | 1233 | .owner = THIS_MODULE, |
| 1182 | }, | 1234 | }, |
| 1183 | .init = { | 1235 | .init = { |
| @@ -1200,6 +1252,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 16 unmodified lines | |||
| 1200 | .vsel_mask = BD718XX_LDO3_MASK, | 1252 | .vsel_mask = BD718XX_LDO3_MASK, |
| 1201 | .enable_reg = BD718XX_REG_LDO3_VOLT, | 1253 | .enable_reg = BD718XX_REG_LDO3_VOLT, |
| 1202 | .enable_mask = BD718XX_LDO_EN, | 1254 | .enable_mask = BD718XX_LDO_EN, |
| 1255 | .enable_time = BD71837_LDO3_STARTUP_TIME, | ||
| 1203 | .owner = THIS_MODULE, | 1256 | .owner = THIS_MODULE, |
| 1204 | }, | 1257 | }, |
| 1205 | .init = { | 1258 | .init = { |
| @@ -1222,6 +1275,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 16 unmodified lines | |||
| 1222 | .vsel_mask = BD718XX_LDO4_MASK, | 1275 | .vsel_mask = BD718XX_LDO4_MASK, |
| 1223 | .enable_reg = BD718XX_REG_LDO4_VOLT, | 1276 | .enable_reg = BD718XX_REG_LDO4_VOLT, |
| 1224 | .enable_mask = BD718XX_LDO_EN, | 1277 | .enable_mask = BD718XX_LDO_EN, |
| 1278 | .enable_time = BD71837_LDO4_STARTUP_TIME, | ||
| 1225 | .owner = THIS_MODULE, | 1279 | .owner = THIS_MODULE, |
| 1226 | }, | 1280 | }, |
| 1227 | .init = { | 1281 | .init = { |
| @@ -1246,6 +1300,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 18 unmodified lines | |||
| 1246 | .vsel_mask = BD71837_LDO5_MASK, | 1300 | .vsel_mask = BD71837_LDO5_MASK, |
| 1247 | .enable_reg = BD718XX_REG_LDO5_VOLT, | 1301 | .enable_reg = BD718XX_REG_LDO5_VOLT, |
| 1248 | .enable_mask = BD718XX_LDO_EN, | 1302 | .enable_mask = BD718XX_LDO_EN, |
| 1303 | .enable_time = BD71837_LDO5_STARTUP_TIME, | ||
| 1249 | .owner = THIS_MODULE, | 1304 | .owner = THIS_MODULE, |
| 1250 | }, | 1305 | }, |
| 1251 | .init = { | 1306 | .init = { |
| @@ -1272,6 +1327,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 20 unmodified lines | |||
| 1272 | .vsel_mask = BD718XX_LDO6_MASK, | 1327 | .vsel_mask = BD718XX_LDO6_MASK, |
| 1273 | .enable_reg = BD718XX_REG_LDO6_VOLT, | 1328 | .enable_reg = BD718XX_REG_LDO6_VOLT, |
| 1274 | .enable_mask = BD718XX_LDO_EN, | 1329 | .enable_mask = BD718XX_LDO_EN, |
| 1330 | .enable_time = BD71837_LDO6_STARTUP_TIME, | ||
| 1275 | .owner = THIS_MODULE, | 1331 | .owner = THIS_MODULE, |
| 1276 | }, | 1332 | }, |
| 1277 | .init = { | 1333 | .init = { |
| @@ -1296,6 +1352,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { · 18 unmodified lines | |||
| 1296 | .vsel_mask = BD71837_LDO7_MASK, | 1352 | .vsel_mask = BD71837_LDO7_MASK, |
| 1297 | .enable_reg = BD71837_REG_LDO7_VOLT, | 1353 | .enable_reg = BD71837_REG_LDO7_VOLT, |
| 1298 | .enable_mask = BD718XX_LDO_EN, | 1354 | .enable_mask = BD718XX_LDO_EN, |
| 1355 | .enable_time = BD71837_LDO7_STARTUP_TIME, | ||
| 1299 | .owner = THIS_MODULE, | 1356 | .owner = THIS_MODULE, |
| 1300 | }, | 1357 | }, |
| 1301 | .init = { | 1358 | .init = { |
| @@ -469,13 +469,17 @@ static int pf8x00_i2c_probe(struct i2c_client *client) · 468 unmodified lines | |||
| 469 | } | 469 | } |
| 470 | 470 | ||
| 471 | static const struct of_device_id pf8x00_dt_ids[] = { | 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 | MODULE_DEVICE_TABLE(of, pf8x00_dt_ids); | 477 | MODULE_DEVICE_TABLE(of, pf8x00_dt_ids); |
| 476 | 478 | ||
| 477 | static const struct i2c_device_id pf8x00_i2c_id[] = { | 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 | MODULE_DEVICE_TABLE(i2c, pf8x00_i2c_id); | 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 | static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = { | 726 | static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = { |
| 727 | .regulator_type = VRM, | 727 | .regulator_type = VRM, |
| 728 | .ops = &rpmh_regulator_vrm_ops, | 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 | .n_voltages = 5, | 730 | .n_voltages = 5, |
| 731 | .pmic_mode_map = pmic_mode_map_pmic5_smps, | 731 | .pmic_mode_map = pmic_mode_map_pmic5_smps, |
| 732 | .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode, | 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 | void qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads, | 1079 | void qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads, |
| 1080 | int clear_start_mask); | 1080 | int clear_start_mask); |
| 1081 | int qeth_threads_running(struct qeth_card *, unsigned long); | 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 | int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, | 1085 | int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, |
| 1085 | int (*reply_cb) | 1086 | int (*reply_cb) |
| @@ -5507,12 +5507,12 @@ out: · 5506 unmodified lines | |||
| 5507 | return rc; | 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 | bool carrier_ok; | 5513 | bool carrier_ok; |
| 5513 | int rc; | 5514 | int rc; |
| 5514 | 5515 | ||
| 5515 | mutex_lock(&card->discipline_mutex); | ||
| 5516 | mutex_lock(&card->conf_mutex); | 5516 | mutex_lock(&card->conf_mutex); |
| 5517 | QETH_CARD_TEXT(card, 2, "setonlin"); | 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 | /* no need for locking / error handling at this early stage: */ | 5529 | /* no need for locking / error handling at this early stage: */ |
| 5530 | qeth_set_real_num_tx_queues(card, qeth_tx_actual_queues(card)); | 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 | if (rc) | 5533 | if (rc) |
| 5534 | goto err_online; | 5534 | goto err_online; |
| 5535 | 5535 | ||
| @@ -5537,7 +5537,6 @@ static int qeth_set_online(struct qeth_card *card) · 1 unmodified line | |||
| 5537 | kobject_uevent(&card->gdev->dev.kobj, KOBJ_CHANGE); | 5537 | kobject_uevent(&card->gdev->dev.kobj, KOBJ_CHANGE); |
| 5538 | 5538 | ||
| 5539 | mutex_unlock(&card->conf_mutex); | 5539 | mutex_unlock(&card->conf_mutex); |
| 5540 | mutex_unlock(&card->discipline_mutex); | ||
| 5541 | return 0; | 5540 | return 0; |
| 5542 | 5541 | ||
| 5543 | err_online: | 5542 | err_online: |
| @@ -5552,15 +5551,14 @@ err_hardsetup: · 8 unmodified lines | |||
| 5552 | qdio_free(CARD_DDEV(card)); | 5551 | qdio_free(CARD_DDEV(card)); |
| 5553 | 5552 | ||
| 5554 | mutex_unlock(&card->conf_mutex); | 5553 | mutex_unlock(&card->conf_mutex); |
| 5555 | mutex_unlock(&card->discipline_mutex); | ||
| 5556 | return rc; | 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 | int rc, rc2, rc3; | 5560 | int rc, rc2, rc3; |
| 5562 | 5561 | ||
| 5563 | mutex_lock(&card->discipline_mutex); | ||
| 5564 | mutex_lock(&card->conf_mutex); | 5562 | mutex_lock(&card->conf_mutex); |
| 5565 | QETH_CARD_TEXT(card, 3, "setoffl"); | 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 | cancel_work_sync(&card->rx_mode_work); | 5580 | cancel_work_sync(&card->rx_mode_work); |
| 5583 | 5581 | ||
| 5584 | card->discipline->set_offline(card); | 5582 | disc->set_offline(card); |
| 5585 | 5583 | ||
| 5586 | qeth_qdio_clear_card(card, 0); | 5584 | qeth_qdio_clear_card(card, 0); |
| 5587 | qeth_drain_output_queues(card); | 5585 | qeth_drain_output_queues(card); |
| @@ -5602,16 +5600,19 @@ int qeth_set_offline(struct qeth_card *card, bool resetting) · 14 unmodified lines | |||
| 5602 | kobject_uevent(&card->gdev->dev.kobj, KOBJ_CHANGE); | 5600 | kobject_uevent(&card->gdev->dev.kobj, KOBJ_CHANGE); |
| 5603 | 5601 | ||
| 5604 | mutex_unlock(&card->conf_mutex); | 5602 | mutex_unlock(&card->conf_mutex); |
| 5605 | mutex_unlock(&card->discipline_mutex); | ||
| 5606 | return 0; | 5603 | return 0; |
| 5607 | } | 5604 | } |
| 5608 | EXPORT_SYMBOL_GPL(qeth_set_offline); | 5605 | EXPORT_SYMBOL_GPL(qeth_set_offline); |
| 5609 | 5606 | ||
| 5610 | static int qeth_do_reset(void *data) | 5607 | static int qeth_do_reset(void *data) |
| 5611 | { | 5608 | { |
| 5609 | const struct qeth_discipline *disc; | ||
| 5612 | struct qeth_card *card = data; | 5610 | struct qeth_card *card = data; |
| 5613 | int rc; | 5611 | int rc; |
| 5614 | 5612 | ||
| 5613 | /* Lock-free, other users will block until we are done. */ | ||
| 5614 | disc = card->discipline; | ||
| 5615 | |||
| 5615 | QETH_CARD_TEXT(card, 2, "recover1"); | 5616 | QETH_CARD_TEXT(card, 2, "recover1"); |
| 5616 | if (!qeth_do_run_thread(card, QETH_RECOVER_THREAD)) | 5617 | if (!qeth_do_run_thread(card, QETH_RECOVER_THREAD)) |
| 5617 | return 0; | 5618 | return 0; |
| @@ -5619,8 +5620,8 @@ static int qeth_do_reset(void *data) · 1 unmodified line | |||
| 5619 | dev_warn(&card->gdev->dev, | 5620 | dev_warn(&card->gdev->dev, |
| 5620 | "A recovery process has been started for the device\n"); | 5621 | "A recovery process has been started for the device\n"); |
| 5621 | 5622 | ||
| 5622 | qeth_set_offline(card, true); | 5623 | qeth_set_offline(card, disc, true); |
| 5623 | rc = qeth_set_online(card); | 5624 | rc = qeth_set_online(card, disc); |
| 5624 | if (!rc) { | 5625 | if (!rc) { |
| 5625 | dev_info(&card->gdev->dev, | 5626 | dev_info(&card->gdev->dev, |
| 5626 | "Device successfully recovered!\n"); | 5627 | "Device successfully recovered!\n"); |
| @@ -6584,6 +6585,7 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) · 957 unmodified lines | |||
| 6584 | break; | 6585 | break; |
| 6585 | default: | 6586 | default: |
| 6586 | card->info.layer_enforced = true; | 6587 | card->info.layer_enforced = true; |
| 6588 | /* It's so early that we don't need the discipline_mutex yet. */ | ||
| 6587 | rc = qeth_core_load_discipline(card, enforced_disc); | 6589 | rc = qeth_core_load_discipline(card, enforced_disc); |
| 6588 | if (rc) | 6590 | if (rc) |
| 6589 | goto err_load; | 6591 | goto err_load; |
| @@ -6616,10 +6618,12 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev) · 26 unmodified lines | |||
| 6616 | 6618 | ||
| 6617 | QETH_CARD_TEXT(card, 2, "removedv"); | 6619 | QETH_CARD_TEXT(card, 2, "removedv"); |
| 6618 | 6620 | ||
| 6621 | mutex_lock(&card->discipline_mutex); | ||
| 6619 | if (card->discipline) { | 6622 | if (card->discipline) { |
| 6620 | card->discipline->remove(gdev); | 6623 | card->discipline->remove(gdev); |
| 6621 | qeth_core_free_discipline(card); | 6624 | qeth_core_free_discipline(card); |
| 6622 | } | 6625 | } |
| 6626 | mutex_unlock(&card->discipline_mutex); | ||
| 6623 | 6627 | ||
| 6624 | qeth_free_qdio_queues(card); | 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 | int rc = 0; | 6638 | int rc = 0; |
| 6635 | enum qeth_discipline_id def_discipline; | 6639 | enum qeth_discipline_id def_discipline; |
| 6636 | 6640 | ||
| 6641 | mutex_lock(&card->discipline_mutex); | ||
| 6637 | if (!card->discipline) { | 6642 | if (!card->discipline) { |
| 6638 | def_discipline = IS_IQD(card) ? QETH_DISCIPLINE_LAYER3 : | 6643 | def_discipline = IS_IQD(card) ? QETH_DISCIPLINE_LAYER3 : |
| 6639 | QETH_DISCIPLINE_LAYER2; | 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 | err: | 6657 | err: |
| 6658 | mutex_unlock(&card->discipline_mutex); | ||
| 6652 | return rc; | 6659 | return rc; |
| 6653 | } | 6660 | } |
| 6654 | 6661 | ||
| 6655 | static int qeth_core_set_offline(struct ccwgroup_device *gdev) | 6662 | static int qeth_core_set_offline(struct ccwgroup_device *gdev) |
| 6656 | { | 6663 | { |
| 6657 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 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 | static void qeth_core_shutdown(struct ccwgroup_device *gdev) | 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 | wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); | 2208 | wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); |
| 2209 | 2209 | ||
| 2210 | if (gdev->state == CCWGROUP_ONLINE) | 2210 | if (gdev->state == CCWGROUP_ONLINE) |
| 2211 | qeth_set_offline(card, false); | 2211 | qeth_set_offline(card, card->discipline, false); |
| 2212 | 2212 | ||
| 2213 | cancel_work_sync(&card->close_dev_work); | 2213 | cancel_work_sync(&card->close_dev_work); |
| 2214 | if (card->dev->reg_state == NETREG_REGISTERED) | 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 | struct net_device *dev, | 1813 | struct net_device *dev, |
| 1814 | netdev_features_t features) | 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 | features &= ~NETIF_F_HW_VLAN_CTAG_TX; | 1817 | features &= ~NETIF_F_HW_VLAN_CTAG_TX; |
| 1818 | return qeth_features_check(skb, dev, features); | 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 | wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); | 1971 | wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); |
| 1972 | 1972 | ||
| 1973 | if (cgdev->state == CCWGROUP_ONLINE) | 1973 | if (cgdev->state == CCWGROUP_ONLINE) |
| 1974 | qeth_set_offline(card, false); | 1974 | qeth_set_offline(card, card->discipline, false); |
| 1975 | 1975 | ||
| 1976 | cancel_work_sync(&card->close_dev_work); | 1976 | cancel_work_sync(&card->close_dev_work); |
| 1977 | if (card->dev->reg_state == NETREG_REGISTERED) | 1977 | if (card->dev->reg_state == NETREG_REGISTERED) |
| @@ -4,6 +4,7 @@ config SCSI_CXGB4_ISCSI · 3 unmodified lines | |||
| 4 | depends on PCI && INET && (IPV6 || IPV6=n) | 4 | depends on PCI && INET && (IPV6 || IPV6=n) |
| 5 | depends on THERMAL || !THERMAL | 5 | depends on THERMAL || !THERMAL |
| 6 | depends on ETHERNET | 6 | depends on ETHERNET |
| 7 | depends on TLS || TLS=n | ||
| 7 | select NET_VENDOR_CHELSIO | 8 | select NET_VENDOR_CHELSIO |
| 8 | select CHELSIO_T4 | 9 | select CHELSIO_T4 |
| 9 | select CHELSIO_LIB | 10 | select CHELSIO_LIB |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | |||
| 14 | #include <linux/debugfs.h> | 14 | #include <linux/debugfs.h> |
| 15 | #include <linux/dmapool.h> | 15 | #include <linux/dmapool.h> |
| 16 | #include <linux/iopoll.h> | 16 | #include <linux/iopoll.h> |
| 17 | #include <linux/irq.h> | ||
| 17 | #include <linux/lcm.h> | 18 | #include <linux/lcm.h> |
| 18 | #include <linux/libata.h> | 19 | #include <linux/libata.h> |
| 19 | #include <linux/mfd/syscon.h> | 20 | #include <linux/mfd/syscon.h> |
| @@ -294,6 +295,7 @@ enum { · 274 unmodified lines | |||
| 294 | 295 | ||
| 295 | struct hisi_sas_hw { | 296 | struct hisi_sas_hw { |
| 296 | int (*hw_init)(struct hisi_hba *hisi_hba); | 297 | int (*hw_init)(struct hisi_hba *hisi_hba); |
| 298 | int (*interrupt_preinit)(struct hisi_hba *hisi_hba); | ||
| 297 | void (*setup_itct)(struct hisi_hba *hisi_hba, | 299 | void (*setup_itct)(struct hisi_hba *hisi_hba, |
| 298 | struct hisi_sas_device *device); | 300 | struct hisi_sas_device *device); |
| 299 | int (*slot_index_alloc)(struct hisi_hba *hisi_hba, | 301 | int (*slot_index_alloc)(struct hisi_hba *hisi_hba, |
| @@ -393,6 +395,8 @@ struct hisi_hba { · 93 unmodified lines | |||
| 393 | u32 refclk_frequency_mhz; | 395 | u32 refclk_frequency_mhz; |
| 394 | u8 sas_addr[SAS_ADDR_SIZE]; | 396 | u8 sas_addr[SAS_ADDR_SIZE]; |
| 395 | 397 | ||
| 398 | int *irq_map; /* v2 hw */ | ||
| 399 | |||
| 396 | int n_phy; | 400 | int n_phy; |
| 397 | spinlock_t lock; | 401 | spinlock_t lock; |
| 398 | struct semaphore sem; | 402 | struct semaphore sem; |
| @@ -2614,6 +2614,13 @@ err_out: · 2613 unmodified lines | |||
| 2614 | return NULL; | 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 | int hisi_sas_probe(struct platform_device *pdev, | 2624 | int hisi_sas_probe(struct platform_device *pdev, |
| 2618 | const struct hisi_sas_hw *hw) | 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 | sha->sas_port[i] = &hisi_hba->port[i].sas_port; | 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 | rc = scsi_add_host(shost, &pdev->dev); | 2685 | rc = scsi_add_host(shost, &pdev->dev); |
| 2675 | if (rc) | 2686 | if (rc) |
| 2676 | goto err_out_ha; | 2687 | goto err_out_ha; |
| @@ -3302,6 +3302,28 @@ static irq_handler_t fatal_interrupts[HISI_SAS_FATAL_INT_NR] = { · 3301 unmodified lines | |||
| 3302 | fatal_axi_int_v2_hw | 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 | * There is a limitation in the hip06 chipset that we need | 3328 | * There is a limitation in the hip06 chipset that we need |
| 3307 | * to map in all mbigen interrupts, even if they are not used. | 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 | struct platform_device *pdev = hisi_hba->platform_dev; | 3333 | struct platform_device *pdev = hisi_hba->platform_dev; |
| 3312 | struct device *dev = &pdev->dev; | 3334 | struct device *dev = &pdev->dev; |
| 3313 | int irq, rc = 0, irq_map[128]; | 3335 | int irq, rc = 0; |
| 3314 | int i, phy_no, fatal_no, queue_no; | 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 | for (i = 0; i < HISI_SAS_PHY_INT_NR; i++) { | 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 | rc = devm_request_irq(dev, irq, phy_interrupts[i], 0, | 3340 | rc = devm_request_irq(dev, irq, phy_interrupts[i], 0, |
| 3322 | DRV_NAME " phy", hisi_hba); | 3341 | DRV_NAME " phy", hisi_hba); |
| 3323 | if (rc) { | 3342 | if (rc) { |
| @@ -3331,7 +3350,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) · 7 unmodified lines | |||
| 3331 | for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { | 3350 | for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { |
| 3332 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; | 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 | rc = devm_request_irq(dev, irq, sata_int_v2_hw, 0, | 3354 | rc = devm_request_irq(dev, irq, sata_int_v2_hw, 0, |
| 3336 | DRV_NAME " sata", phy); | 3355 | DRV_NAME " sata", phy); |
| 3337 | if (rc) { | 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 | for (fatal_no = 0; fatal_no < HISI_SAS_FATAL_INT_NR; fatal_no++) { | 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 | rc = devm_request_irq(dev, irq, fatal_interrupts[fatal_no], 0, | 3366 | rc = devm_request_irq(dev, irq, fatal_interrupts[fatal_no], 0, |
| 3348 | DRV_NAME " fatal", hisi_hba); | 3367 | DRV_NAME " fatal", hisi_hba); |
| 3349 | if (rc) { | 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 | struct hisi_sas_cq *cq = &hisi_hba->cq[queue_no]; | 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 | rc = devm_request_threaded_irq(dev, cq->irq_no, | 3380 | rc = devm_request_threaded_irq(dev, cq->irq_no, |
| 3362 | cq_interrupt_v2_hw, | 3381 | cq_interrupt_v2_hw, |
| 3363 | cq_thread_v2_hw, IRQF_ONESHOT, | 3382 | cq_thread_v2_hw, IRQF_ONESHOT, |
| 3364 | DRV_NAME " cq", cq); | 3383 | DRV_NAME " cq", cq); |
| 3365 | if (rc) { | 3384 | if (rc) { |
| 3366 | dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n", | 3385 | dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n", |
| 3367 | irq, rc); | 3386 | cq->irq_no, rc); |
| 3368 | rc = -ENOENT; | 3387 | rc = -ENOENT; |
| 3369 | goto err_out; | 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 | err_out: | 3392 | err_out: |
| 3376 | return rc; | 3393 | return rc; |
| 3377 | } | 3394 | } |
| @@ -3529,6 +3546,26 @@ static struct device_attribute *host_attrs_v2_hw[] = { · 151 unmodified lines | |||
| 3529 | NULL | 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 | static struct scsi_host_template sht_v2_hw = { | 3569 | static struct scsi_host_template sht_v2_hw = { |
| 3533 | .name = DRV_NAME, | 3570 | .name = DRV_NAME, |
| 3534 | .proc_name = DRV_NAME, | 3571 | .proc_name = DRV_NAME, |
| @@ -3553,10 +3590,13 @@ static struct scsi_host_template sht_v2_hw = { · 18 unmodified lines | |||
| 3553 | #endif | 3590 | #endif |
| 3554 | .shost_attrs = host_attrs_v2_hw, | 3591 | .shost_attrs = host_attrs_v2_hw, |
| 3555 | .host_reset = hisi_sas_host_reset, | 3592 | .host_reset = hisi_sas_host_reset, |
| 3593 | .map_queues = map_queues_v2_hw, | ||
| 3594 | .host_tagset = 1, | ||
| 3556 | }; | 3595 | }; |
| 3557 | 3596 | ||
| 3558 | static const struct hisi_sas_hw hisi_sas_v2_hw = { | 3597 | static const struct hisi_sas_hw hisi_sas_v2_hw = { |
| 3559 | .hw_init = hisi_sas_v2_init, | 3598 | .hw_init = hisi_sas_v2_init, |
| 3599 | .interrupt_preinit = hisi_sas_v2_interrupt_preinit, | ||
| 3560 | .setup_itct = setup_itct_v2_hw, | 3600 | .setup_itct = setup_itct_v2_hw, |
| 3561 | .slot_index_alloc = slot_index_alloc_quirk_v2_hw, | 3601 | .slot_index_alloc = slot_index_alloc_quirk_v2_hw, |
| 3562 | .alloc_dev = alloc_dev_quirk_v2_hw, | 3602 | .alloc_dev = alloc_dev_quirk_v2_hw, |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | |||
| 37 | #include <linux/poll.h> | 37 | #include <linux/poll.h> |
| 38 | #include <linux/vmalloc.h> | 38 | #include <linux/vmalloc.h> |
| 39 | #include <linux/irq_poll.h> | 39 | #include <linux/irq_poll.h> |
| 40 | #include <linux/blk-mq-pci.h> | ||
| 40 | 41 | ||
| 41 | #include <scsi/scsi.h> | 42 | #include <scsi/scsi.h> |
| 42 | #include <scsi/scsi_cmnd.h> | 43 | #include <scsi/scsi_cmnd.h> |
| @@ -113,6 +114,10 @@ unsigned int enable_sdev_max_qd; · 70 unmodified lines | |||
| 113 | module_param(enable_sdev_max_qd, int, 0444); | 114 | module_param(enable_sdev_max_qd, int, 0444); |
| 114 | MODULE_PARM_DESC(enable_sdev_max_qd, "Enable sdev max qd as can_queue. Default: 0"); | 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 | MODULE_LICENSE("GPL"); | 121 | MODULE_LICENSE("GPL"); |
| 117 | MODULE_VERSION(MEGASAS_VERSION); | 122 | MODULE_VERSION(MEGASAS_VERSION); |
| 118 | MODULE_AUTHOR("megaraidlinux.pdl@broadcom.com"); | 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 | return 0; | 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 | static void megasas_aen_polling(struct work_struct *work); | 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 | .eh_timed_out = megasas_reset_timer, | 3445 | .eh_timed_out = megasas_reset_timer, |
| 3428 | .shost_attrs = megaraid_host_attrs, | 3446 | .shost_attrs = megaraid_host_attrs, |
| 3429 | .bios_param = megasas_bios_param, | 3447 | .bios_param = megasas_bios_param, |
| 3448 | .map_queues = megasas_map_queues, | ||
| 3430 | .change_queue_depth = scsi_change_queue_depth, | 3449 | .change_queue_depth = scsi_change_queue_depth, |
| 3431 | .max_segment_size = 0xffffffff, | 3450 | .max_segment_size = 0xffffffff, |
| 3432 | }; | 3451 | }; |
| @@ -6808,6 +6827,26 @@ static int megasas_io_attach(struct megasas_instance *instance) · 3375 unmodified lines | |||
| 6808 | host->max_lun = MEGASAS_MAX_LUN; | 6827 | host->max_lun = MEGASAS_MAX_LUN; |
| 6809 | host->max_cmd_len = 16; | 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 | * Notify the mid-layer about the new controller | 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 | int sdev_busy; | 360 | int sdev_busy; |
| 361 | 361 | ||
| 362 | /* nr_hw_queue = 1 for MegaRAID */ | 362 | /* TBD - if sml remove device_busy in future, driver |
| 363 | struct blk_mq_hw_ctx *hctx = | 363 | * should track counter in internal structure. |
| 364 | scmd->device->request_queue->queue_hw_ctx[0]; | 364 | */ |
| 365 | 365 | sdev_busy = atomic_read(&scmd->device->device_busy); | |
| 366 | sdev_busy = atomic_read(&hctx->nr_active); | ||
| 367 | 366 | ||
| 368 | if (instance->perf_mode == MR_BALANCED_PERF_MODE && | 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 | cmd->request_desc->SCSIIO.MSIxIndex = | 369 | cmd->request_desc->SCSIIO.MSIxIndex = |
| 371 | mega_mod64((atomic64_add_return(1, &instance->high_iops_outstanding) / | 370 | mega_mod64((atomic64_add_return(1, &instance->high_iops_outstanding) / |
| 372 | MR_HIGH_IOPS_BATCH_COUNT), instance->low_latency_index_start); | 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 | cmd->request_desc->SCSIIO.MSIxIndex = | 373 | cmd->request_desc->SCSIIO.MSIxIndex = |
| 375 | (mega_mod64(atomic64_add_return(1, &instance->total_io_count), | 374 | (mega_mod64(atomic64_add_return(1, &instance->total_io_count), |
| 376 | instance->msix_vectors)); | 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 | cmd->request_desc->SCSIIO.MSIxIndex = | 382 | cmd->request_desc->SCSIIO.MSIxIndex = |
| 379 | instance->reply_map[raw_smp_processor_id()]; | 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 | if (megasas_alloc_cmdlist_fusion(instance)) | 961 | if (megasas_alloc_cmdlist_fusion(instance)) |
| 957 | goto fail_exit; | 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 | /* The first 256 bytes (SMID 0) is not used. Don't add to the cmd list */ | 964 | /* The first 256 bytes (SMID 0) is not used. Don't add to the cmd list */ |
| 963 | io_req_base = fusion->io_request_frames + MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE; | 965 | io_req_base = fusion->io_request_frames + MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE; |
| 964 | io_req_base_phys = fusion->io_request_frames_phys + MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE; | 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 | MR_HIGH_IOPS_QUEUE_COUNT) && cur_intr_coalescing) | 1104 | MR_HIGH_IOPS_QUEUE_COUNT) && cur_intr_coalescing) |
| 1103 | instance->perf_mode = MR_BALANCED_PERF_MODE; | 1105 | instance->perf_mode = MR_BALANCED_PERF_MODE; |
| 1104 | 1106 | ||
| 1105 | dev_info(&instance->pdev->dev, "Performance mode :%s\n", | 1107 | dev_info(&instance->pdev->dev, "Performance mode :%s (latency index = %d)\n", |
| 1106 | MEGASAS_PERF_MODE_2STR(instance->perf_mode)); | 1108 | MEGASAS_PERF_MODE_2STR(instance->perf_mode), |
| 1109 | instance->low_latency_index_start); | ||
| 1107 | 1110 | ||
| 1108 | instance->fw_sync_cache_support = (scratch_pad_1 & | 1111 | instance->fw_sync_cache_support = (scratch_pad_1 & |
| 1109 | MR_CAN_HANDLE_SYNC_CACHE_OFFSET) ? 1 : 0; | 1112 | MR_CAN_HANDLE_SYNC_CACHE_OFFSET) ? 1 : 0; |
| @@ -79,5 +79,5 @@ config SCSI_MPT2SAS · 78 unmodified lines | |||
| 79 | select SCSI_MPT3SAS | 79 | select SCSI_MPT3SAS |
| 80 | depends on PCI && SCSI | 80 | depends on PCI && SCSI |
| 81 | help | 81 | help |
| 82 | Dummy config option for backwards compatiblity: configure the MPT3SAS | 82 | Dummy config option for backwards compatibility: configure the MPT3SAS |
| 83 | driver instead. | 83 | driver instead. |
| @@ -5034,7 +5034,7 @@ _base_check_for_trigger_pages_support(struct MPT3SAS_ADAPTER *ioc) · 5033 unmodified lines | |||
| 5034 | static void | 5034 | static void |
| 5035 | _base_get_diag_triggers(struct MPT3SAS_ADAPTER *ioc) | 5035 | _base_get_diag_triggers(struct MPT3SAS_ADAPTER *ioc) |
| 5036 | { | 5036 | { |
| 5037 | u16 trigger_flags; | 5037 | int trigger_flags; |
| 5038 | 5038 | ||
| 5039 | /* | 5039 | /* |
| 5040 | * Default setting of master trigger. | 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 | chap_name); | 2245 | chap_name); |
| 2246 | break; | 2246 | break; |
| 2247 | case ISCSI_BOOT_TGT_CHAP_SECRET: | 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 | chap_secret); | 2249 | chap_secret); |
| 2250 | break; | 2250 | break; |
| 2251 | case ISCSI_BOOT_TGT_REV_CHAP_NAME: | 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 | mchap_name); | 2253 | mchap_name); |
| 2254 | break; | 2254 | break; |
| 2255 | case ISCSI_BOOT_TGT_REV_CHAP_SECRET: | 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 | mchap_secret); | 2257 | mchap_secret); |
| 2258 | break; | 2258 | break; |
| 2259 | case ISCSI_BOOT_TGT_FLAGS: | 2259 | case ISCSI_BOOT_TGT_FLAGS: |
| @@ -6740,7 +6740,7 @@ static int __init scsi_debug_init(void) · 6739 unmodified lines | |||
| 6740 | k = sdeb_zbc_model_str(sdeb_zbc_model_s); | 6740 | k = sdeb_zbc_model_str(sdeb_zbc_model_s); |
| 6741 | if (k < 0) { | 6741 | if (k < 0) { |
| 6742 | ret = k; | 6742 | ret = k; |
| 6743 | goto free_vm; | 6743 | goto free_q_arr; |
| 6744 | } | 6744 | } |
| 6745 | sdeb_zbc_model = k; | 6745 | sdeb_zbc_model = k; |
| 6746 | switch (sdeb_zbc_model) { | 6746 | switch (sdeb_zbc_model) { |
| @@ -6753,7 +6753,8 @@ static int __init scsi_debug_init(void) · 6 unmodified lines | |||
| 6753 | break; | 6753 | break; |
| 6754 | default: | 6754 | default: |
| 6755 | pr_err("Invalid ZBC model\n"); | 6755 | pr_err("Invalid ZBC model\n"); |
| 6756 | return -EINVAL; | 6756 | ret = -EINVAL; |
| 6757 | goto free_q_arr; | ||
| 6757 | } | 6758 | } |
| 6758 | } | 6759 | } |
| 6759 | if (sdeb_zbc_model != BLK_ZONED_NONE) { | 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 | req = blk_get_request(sdev->request_queue, | 250 | req = blk_get_request(sdev->request_queue, |
| 251 | data_direction == DMA_TO_DEVICE ? | 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 | if (IS_ERR(req)) | 254 | if (IS_ERR(req)) |
| 254 | return ret; | 255 | return ret; |
| 255 | rq = scsi_req(req); | 256 | rq = scsi_req(req); |
| @@ -1206,6 +1207,8 @@ static blk_status_t · 950 unmodified lines | |||
| 1206 | scsi_device_state_check(struct scsi_device *sdev, struct request *req) | 1207 | scsi_device_state_check(struct scsi_device *sdev, struct request *req) |
| 1207 | { | 1208 | { |
| 1208 | switch (sdev->sdev_state) { | 1209 | switch (sdev->sdev_state) { |
| 1210 | case SDEV_CREATED: | ||
| 1211 | return BLK_STS_OK; | ||
| 1209 | case SDEV_OFFLINE: | 1212 | case SDEV_OFFLINE: |
| 1210 | case SDEV_TRANSPORT_OFFLINE: | 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 | return BLK_STS_RESOURCE; | 1235 | return BLK_STS_RESOURCE; |
| 1233 | case SDEV_QUIESCE: | 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 | return BLK_STS_RESOURCE; | 1242 | return BLK_STS_RESOURCE; |
| 1239 | return BLK_STS_OK; | 1243 | return BLK_STS_OK; |
| 1240 | default: | 1244 | default: |
| 1241 | /* | 1245 | /* |
| 1242 | * For any other not fully online state we only allow | 1246 | * For any other not fully online state we only allow |
| 1243 | * special commands. In particular any user initiated | 1247 | * power management commands. |
| 1244 | * command is not allowed. | ||
| 1245 | */ | 1248 | */ |
| 1246 | if (req && !(req->rq_flags & RQF_PREEMPT)) | 1249 | if (req && !(req->rq_flags & RQF_PM)) |
| 1247 | return BLK_STS_IOERR; | 1250 | return BLK_STS_IOERR; |
| 1248 | return BLK_STS_OK; | 1251 | return BLK_STS_OK; |
| 1249 | } | 1252 | } |
| @@ -2516,15 +2519,13 @@ void sdev_evt_send_simple(struct scsi_device *sdev, · 1266 unmodified lines | |||
| 2516 | EXPORT_SYMBOL_GPL(sdev_evt_send_simple); | 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 | * @sdev: scsi device to quiesce. | 2523 | * @sdev: scsi device to quiesce. |
| 2521 | * | 2524 | * |
| 2522 | * This works by trying to transition to the SDEV_QUIESCE state | 2525 | * This works by trying to transition to the SDEV_QUIESCE state |
| 2523 | * (which must be a legal transition). When the device is in this | 2526 | * (which must be a legal transition). When the device is in this |
| 2524 | * state, only special requests will be accepted, all others will | 2527 | * state, only power management requests will be accepted, all others will |
| 2525 | * be deferred. Since special requests may also be requeued requests, | 2528 | * be deferred. |
| 2526 | * a successful return doesn't guarantee the device will be | ||
| 2527 | * totally quiescent. | ||
| 2528 | * | 2529 | * |
| 2529 | * Must be called with user context, may sleep. | 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 | * device deleted during suspend) | 2587 | * device deleted during suspend) |
| 2587 | */ | 2588 | */ |
| 2588 | mutex_lock(&sdev->state_mutex); | 2589 | mutex_lock(&sdev->state_mutex); |
| 2590 | if (sdev->sdev_state == SDEV_QUIESCE) | ||
| 2591 | scsi_device_set_state(sdev, SDEV_RUNNING); | ||
| 2589 | if (sdev->quiesced_by) { | 2592 | if (sdev->quiesced_by) { |
| 2590 | sdev->quiesced_by = NULL; | 2593 | sdev->quiesced_by = NULL; |
| 2591 | blk_clear_pm_only(sdev->request_queue); | 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 | mutex_unlock(&sdev->state_mutex); | 2596 | mutex_unlock(&sdev->state_mutex); |
| 2596 | } | 2597 | } |
| 2597 | EXPORT_SYMBOL(scsi_device_resume); | 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 | sshdr = &sshdr_tmp; | 117 | sshdr = &sshdr_tmp; |
| 118 | 118 | ||
| 119 | for(i = 0; i < DV_RETRIES; i++) { | 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 | result = scsi_execute(sdev, cmd, dir, buffer, bufflen, sense, | 124 | result = scsi_execute(sdev, cmd, dir, buffer, bufflen, sense, |
| 121 | sshdr, DV_TIMEOUT, /* retries */ 1, | 125 | sshdr, DV_TIMEOUT, /* retries */ 1, |
| 122 | REQ_FAILFAST_DEV | | 126 | REQ_FAILFAST_DEV | |
| 123 | REQ_FAILFAST_TRANSPORT | | 127 | REQ_FAILFAST_TRANSPORT | |
| 124 | REQ_FAILFAST_DRIVER, | 128 | REQ_FAILFAST_DRIVER, |
| 125 | 0, NULL); | 129 | RQF_PM, NULL); |
| 126 | if (driver_byte(result) != DRIVER_SENSE || | 130 | if (driver_byte(result) != DRIVER_SENSE || |
| 127 | sshdr->sense_key != UNIT_ATTENTION) | 131 | sshdr->sense_key != UNIT_ATTENTION) |
| 128 | break; | 132 | break; |
| @@ -1005,23 +1009,26 @@ spi_dv_device(struct scsi_device *sdev) · 876 unmodified lines | |||
| 1005 | */ | 1009 | */ |
| 1006 | lock_system_sleep(); | 1010 | lock_system_sleep(); |
| 1007 | 1011 | ||
| 1012 | if (scsi_autopm_get_device(sdev)) | ||
| 1013 | goto unlock_system_sleep; | ||
| 1014 | |||
| 1008 | if (unlikely(spi_dv_in_progress(starget))) | 1015 | if (unlikely(spi_dv_in_progress(starget))) |
| 1009 | goto unlock; | 1016 | goto put_autopm; |
| 1010 | 1017 | ||
| 1011 | if (unlikely(scsi_device_get(sdev))) | 1018 | if (unlikely(scsi_device_get(sdev))) |
| 1012 | goto unlock; | 1019 | goto put_autopm; |
| 1013 | 1020 | ||
| 1014 | spi_dv_in_progress(starget) = 1; | 1021 | spi_dv_in_progress(starget) = 1; |
| 1015 | 1022 | ||
| 1016 | buffer = kzalloc(len, GFP_KERNEL); | 1023 | buffer = kzalloc(len, GFP_KERNEL); |
| 1017 | 1024 | ||
| 1018 | if (unlikely(!buffer)) | 1025 | if (unlikely(!buffer)) |
| 1019 | goto out_put; | 1026 | goto put_sdev; |
| 1020 | 1027 | ||
| 1021 | /* We need to verify that the actual device will quiesce; the | 1028 | /* We need to verify that the actual device will quiesce; the |
| 1022 | * later target quiesce is just a nice to have */ | 1029 | * later target quiesce is just a nice to have */ |
| 1023 | if (unlikely(scsi_device_quiesce(sdev))) | 1030 | if (unlikely(scsi_device_quiesce(sdev))) |
| 1024 | goto out_free; | 1031 | goto free_buffer; |
| 1025 | 1032 | ||
| 1026 | scsi_target_quiesce(starget); | 1033 | scsi_target_quiesce(starget); |
| 1027 | 1034 | ||
| @@ -1041,12 +1048,16 @@ spi_dv_device(struct scsi_device *sdev) · 13 unmodified lines | |||
| 1041 | 1048 | ||
| 1042 | spi_initial_dv(starget) = 1; | 1049 | spi_initial_dv(starget) = 1; |
| 1043 | 1050 | ||
| 1044 | out_free: | 1051 | free_buffer: |
| 1045 | kfree(buffer); | 1052 | kfree(buffer); |
| 1046 | out_put: | 1053 | |
| 1054 | put_sdev: | ||
| 1047 | spi_dv_in_progress(starget) = 0; | 1055 | spi_dv_in_progress(starget) = 0; |
| 1048 | scsi_device_put(sdev); | 1056 | scsi_device_put(sdev); |
| 1049 | unlock: | 1057 | put_autopm: |
| 1058 | scsi_autopm_put_device(sdev); | ||
| 1059 | |||
| 1060 | unlock_system_sleep: | ||
| 1050 | unlock_system_sleep(); | 1061 | unlock_system_sleep(); |
| 1051 | } | 1062 | } |
| 1052 | EXPORT_SYMBOL(spi_dv_device); | 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 | return BLK_STS_TARGET; | 989 | return BLK_STS_TARGET; |
| 990 | } | ||
| 989 | 991 | ||
| 990 | if (sdkp->ws16 || lba > 0xffffffff || nr_blocks > 0xffff) | 992 | if (sdkp->ws16 || lba > 0xffffffff || nr_blocks > 0xffff) |
| 991 | return sd_setup_write_same16_cmnd(cmd, false); | 993 | return sd_setup_write_same16_cmnd(cmd, false); |
| @@ -3510,10 +3512,8 @@ static int sd_probe(struct device *dev) · 2518 unmodified lines | |||
| 3510 | static int sd_remove(struct device *dev) | 3512 | static int sd_remove(struct device *dev) |
| 3511 | { | 3513 | { |
| 3512 | struct scsi_disk *sdkp; | 3514 | struct scsi_disk *sdkp; |
| 3513 | dev_t devt; | ||
| 3514 | 3515 | ||
| 3515 | sdkp = dev_get_drvdata(dev); | 3516 | sdkp = dev_get_drvdata(dev); |
| 3516 | devt = disk_devt(sdkp->disk); | ||
| 3517 | scsi_autopm_get_device(sdkp->device); | 3517 | scsi_autopm_get_device(sdkp->device); |
| 3518 | 3518 | ||
| 3519 | async_synchronize_full_domain(&scsi_sd_pm_domain); | 3519 | async_synchronize_full_domain(&scsi_sd_pm_domain); |
| @@ -31,6 +31,6 @@ TRACE_EVENT(ufs_mtk_event, · 30 unmodified lines | |||
| 31 | 31 | ||
| 32 | #undef TRACE_INCLUDE_PATH | 32 | #undef TRACE_INCLUDE_PATH |
| 33 | #undef TRACE_INCLUDE_FILE | 33 | #undef TRACE_INCLUDE_FILE |
| 34 | #define TRACE_INCLUDE_PATH . | 34 | #define TRACE_INCLUDE_PATH ../../drivers/scsi/ufs/ |
| 35 | #define TRACE_INCLUDE_FILE ufs-mediatek-trace | 35 | #define TRACE_INCLUDE_FILE ufs-mediatek-trace |
| 36 | #include <trace/define_trace.h> | 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 | return !!(host->caps & UFS_MTK_CAP_VA09_PWR_CTRL); | 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 | static void ufs_mtk_cfg_unipro_cg(struct ufs_hba *hba, bool enable) | 80 | static void ufs_mtk_cfg_unipro_cg(struct ufs_hba *hba, bool enable) |
| 74 | { | 81 | { |
| 75 | u32 tmp; | 82 | u32 tmp; |
| @@ -514,6 +521,9 @@ static void ufs_mtk_init_host_caps(struct ufs_hba *hba) · 438 unmodified lines | |||
| 514 | if (of_property_read_bool(np, "mediatek,ufs-disable-ah8")) | 521 | if (of_property_read_bool(np, "mediatek,ufs-disable-ah8")) |
| 515 | host->caps |= UFS_MTK_CAP_DISABLE_AH8; | 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 | dev_info(hba->dev, "caps: 0x%x", host->caps); | 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 | static void ufs_mtk_fixup_dev_quirks(struct ufs_hba *hba) | 1013 | static void ufs_mtk_fixup_dev_quirks(struct ufs_hba *hba) |
| 1004 | { | 1014 | { |
| 1005 | ufshcd_fixup_dev_quirks(hba, ufs_mtk_dev_fixups); | 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 | static void ufs_mtk_event_notify(struct ufs_hba *hba, | 1029 | static void ufs_mtk_event_notify(struct ufs_hba *hba, |
| @@ -81,6 +81,7 @@ enum ufs_mtk_host_caps { · 80 unmodified lines | |||
| 81 | UFS_MTK_CAP_BOOST_CRYPT_ENGINE = 1 << 0, | 81 | UFS_MTK_CAP_BOOST_CRYPT_ENGINE = 1 << 0, |
| 82 | UFS_MTK_CAP_VA09_PWR_CTRL = 1 << 1, | 82 | UFS_MTK_CAP_VA09_PWR_CTRL = 1 << 1, |
| 83 | UFS_MTK_CAP_DISABLE_AH8 = 1 << 2, | 83 | UFS_MTK_CAP_DISABLE_AH8 = 1 << 2, |
| 84 | UFS_MTK_CAP_BROKEN_VCC = 1 << 3, | ||
| 84 | }; | 85 | }; |
| 85 | 86 | ||
| 86 | struct ufs_mtk_crypt_cfg { | 87 | struct ufs_mtk_crypt_cfg { |
| @@ -330,7 +330,6 @@ enum { · 329 unmodified lines | |||
| 330 | UFS_DEV_WRITE_BOOSTER_SUP = BIT(8), | 330 | UFS_DEV_WRITE_BOOSTER_SUP = BIT(8), |
| 331 | }; | 331 | }; |
| 332 | 332 | ||
| 333 | #define POWER_DESC_MAX_SIZE 0x62 | ||
| 334 | #define POWER_DESC_MAX_ACTV_ICC_LVLS 16 | 333 | #define POWER_DESC_MAX_ACTV_ICC_LVLS 16 |
| 335 | 334 | ||
| 336 | /* Attribute bActiveICCLevel parameter bit masks definitions */ | 335 | /* Attribute bActiveICCLevel parameter bit masks definitions */ |
| @@ -513,6 +512,7 @@ struct ufs_query_res { · 176 unmodified lines | |||
| 513 | struct ufs_vreg { | 512 | struct ufs_vreg { |
| 514 | struct regulator *reg; | 513 | struct regulator *reg; |
| 515 | const char *name; | 514 | const char *name; |
| 515 | bool always_on; | ||
| 516 | bool enabled; | 516 | bool enabled; |
| 517 | int min_uV; | 517 | int min_uV; |
| 518 | int max_uV; | 518 | int max_uV; |
| @@ -148,6 +148,8 @@ static int ufs_intel_common_init(struct ufs_hba *hba) · 147 unmodified lines | |||
| 148 | { | 148 | { |
| 149 | struct intel_host *host; | 149 | struct intel_host *host; |
| 150 | 150 | ||
| 151 | hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND; | ||
| 152 | |||
| 151 | host = devm_kzalloc(hba->dev, sizeof(*host), GFP_KERNEL); | 153 | host = devm_kzalloc(hba->dev, sizeof(*host), GFP_KERNEL); |
| 152 | if (!host) | 154 | if (!host) |
| 153 | return -ENOMEM; | 155 | return -ENOMEM; |
| @@ -163,6 +165,41 @@ static void ufs_intel_common_exit(struct ufs_hba *hba) · 9 unmodified lines | |||
| 163 | intel_ltr_hide(hba->dev); | 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 | static int ufs_intel_ehl_init(struct ufs_hba *hba) | 203 | static int ufs_intel_ehl_init(struct ufs_hba *hba) |
| 167 | { | 204 | { |
| 168 | hba->quirks |= UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8; | 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 | .init = ufs_intel_common_init, | 211 | .init = ufs_intel_common_init, |
| 175 | .exit = ufs_intel_common_exit, | 212 | .exit = ufs_intel_common_exit, |
| 176 | .link_startup_notify = ufs_intel_link_startup_notify, | 213 | .link_startup_notify = ufs_intel_link_startup_notify, |
| 214 | .resume = ufs_intel_resume, | ||
| 177 | }; | 215 | }; |
| 178 | 216 | ||
| 179 | static struct ufs_hba_variant_ops ufs_intel_ehl_hba_vops = { | 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 | .init = ufs_intel_ehl_init, | 219 | .init = ufs_intel_ehl_init, |
| 182 | .exit = ufs_intel_common_exit, | 220 | .exit = ufs_intel_common_exit, |
| 183 | .link_startup_notify = ufs_intel_link_startup_notify, | 221 | .link_startup_notify = ufs_intel_link_startup_notify, |
| 222 | .resume = ufs_intel_resume, | ||
| 184 | }; | 223 | }; |
| 185 | 224 | ||
| 186 | #ifdef CONFIG_PM_SLEEP | 225 | #ifdef CONFIG_PM_SLEEP |
| @@ -207,6 +246,30 @@ static int ufshcd_pci_resume(struct device *dev) · 20 unmodified lines | |||
| 207 | { | 246 | { |
| 208 | return ufshcd_system_resume(dev_get_drvdata(dev)); | 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 | #endif /* !CONFIG_PM_SLEEP */ | 273 | #endif /* !CONFIG_PM_SLEEP */ |
| 211 | 274 | ||
| 212 | #ifdef CONFIG_PM | 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 | static const struct dev_pm_ops ufshcd_pci_pm_ops = { | 367 | static const struct dev_pm_ops ufshcd_pci_pm_ops = { |
| 305 | SET_SYSTEM_SLEEP_PM_OPS(ufshcd_pci_suspend, | 368 | #ifdef CONFIG_PM_SLEEP |
| 306 | ufshcd_pci_resume) | 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 | SET_RUNTIME_PM_OPS(ufshcd_pci_runtime_suspend, | 376 | SET_RUNTIME_PM_OPS(ufshcd_pci_runtime_suspend, |
| 308 | ufshcd_pci_runtime_resume, | 377 | ufshcd_pci_runtime_resume, |
| 309 | ufshcd_pci_runtime_idle) | 378 | ufshcd_pci_runtime_idle) |
| @@ -225,6 +225,7 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba); · 224 unmodified lines | |||
| 225 | static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd); | 225 | static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd); |
| 226 | static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag); | 226 | static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag); |
| 227 | static void ufshcd_hba_exit(struct ufs_hba *hba); | 227 | static void ufshcd_hba_exit(struct ufs_hba *hba); |
| 228 | static int ufshcd_clear_ua_wluns(struct ufs_hba *hba); | ||
| 228 | static int ufshcd_probe_hba(struct ufs_hba *hba, bool async); | 229 | static int ufshcd_probe_hba(struct ufs_hba *hba, bool async); |
| 229 | static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on); | 230 | static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on); |
| 230 | static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba); | 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 | if (ret) | 289 | if (ret) |
| 289 | dev_err(hba->dev, "%s: En WB flush during H8: failed: %d\n", | 290 | dev_err(hba->dev, "%s: En WB flush during H8: failed: %d\n", |
| 290 | __func__, ret); | 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 | static void ufshcd_scsi_unblock_requests(struct ufs_hba *hba) | 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 | hba->pwr_info.hs_rate); | 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 | void ufshcd_delay_us(unsigned long us, unsigned long tolerance) | 602 | void ufshcd_delay_us(unsigned long us, unsigned long tolerance) |
| 584 | { | 603 | { |
| 585 | if (!us) | 604 | if (!us) |
| @@ -3665,7 +3684,7 @@ static int ufshcd_dme_enable(struct ufs_hba *hba) · 3079 unmodified lines | |||
| 3665 | ret = ufshcd_send_uic_cmd(hba, &uic_cmd); | 3684 | ret = ufshcd_send_uic_cmd(hba, &uic_cmd); |
| 3666 | if (ret) | 3685 | if (ret) |
| 3667 | dev_err(hba->dev, | 3686 | dev_err(hba->dev, |
| 3668 | "dme-reset: error code %d\n", ret); | 3687 | "dme-enable: error code %d\n", ret); |
| 3669 | 3688 | ||
| 3670 | return ret; | 3689 | return ret; |
| 3671 | } | 3690 | } |
| @@ -3964,7 +3983,7 @@ int ufshcd_link_recovery(struct ufs_hba *hba) · 292 unmodified lines | |||
| 3964 | spin_unlock_irqrestore(hba->host->host_lock, flags); | 3983 | spin_unlock_irqrestore(hba->host->host_lock, flags); |
| 3965 | 3984 | ||
| 3966 | /* Reset the attached device */ | 3985 | /* Reset the attached device */ |
| 3967 | ufshcd_vops_device_reset(hba); | 3986 | ufshcd_device_reset(hba); |
| 3968 | 3987 | ||
| 3969 | ret = ufshcd_host_reset_and_restore(hba); | 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 | static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable) | 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 | if (enable) | 5440 | if (enable) |
| 5425 | ufshcd_wb_buf_flush_enable(hba); | 5441 | ufshcd_wb_buf_flush_enable(hba); |
| 5426 | else | 5442 | else |
| @@ -6643,19 +6659,16 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd) · 1216 unmodified lines | |||
| 6643 | { | 6659 | { |
| 6644 | struct Scsi_Host *host; | 6660 | struct Scsi_Host *host; |
| 6645 | struct ufs_hba *hba; | 6661 | struct ufs_hba *hba; |
| 6646 | unsigned int tag; | ||
| 6647 | u32 pos; | 6662 | u32 pos; |
| 6648 | int err; | 6663 | int err; |
| 6649 | u8 resp = 0xF; | 6664 | u8 resp = 0xF, lun; |
| 6650 | struct ufshcd_lrb *lrbp; | ||
| 6651 | unsigned long flags; | 6665 | unsigned long flags; |
| 6652 | 6666 | ||
| 6653 | host = cmd->device->host; | 6667 | host = cmd->device->host; |
| 6654 | hba = shost_priv(host); | 6668 | hba = shost_priv(host); |
| 6655 | tag = cmd->request->tag; | ||
| 6656 | 6669 | ||
| 6657 | lrbp = &hba->lrb[tag]; | 6670 | lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun); |
| 6658 | err = ufshcd_issue_tm_cmd(hba, lrbp->lun, 0, UFS_LOGICAL_RESET, &resp); | 6671 | err = ufshcd_issue_tm_cmd(hba, lun, 0, UFS_LOGICAL_RESET, &resp); |
| 6659 | if (err || resp != UPIU_TASK_MANAGEMENT_FUNC_COMPL) { | 6672 | if (err || resp != UPIU_TASK_MANAGEMENT_FUNC_COMPL) { |
| 6660 | if (!err) | 6673 | if (!err) |
| 6661 | err = resp; | 6674 | err = resp; |
| @@ -6664,7 +6677,7 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd) · 2 unmodified lines | |||
| 6664 | 6677 | ||
| 6665 | /* clear the commands that were pending for corresponding LUN */ | 6678 | /* clear the commands that were pending for corresponding LUN */ |
| 6666 | for_each_set_bit(pos, &hba->outstanding_reqs, hba->nutrs) { | 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 | err = ufshcd_clear_cmd(hba, pos); | 6681 | err = ufshcd_clear_cmd(hba, pos); |
| 6669 | if (err) | 6682 | if (err) |
| 6670 | break; | 6683 | break; |
| @@ -6930,7 +6943,8 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba) · 259 unmodified lines | |||
| 6930 | 6943 | ||
| 6931 | /* Establish the link again and restore the device */ | 6944 | /* Establish the link again and restore the device */ |
| 6932 | err = ufshcd_probe_hba(hba, false); | 6945 | err = ufshcd_probe_hba(hba, false); |
| 6933 | 6946 | if (!err) | |
| 6947 | ufshcd_clear_ua_wluns(hba); | ||
| 6934 | out: | 6948 | out: |
| 6935 | if (err) | 6949 | if (err) |
| 6936 | dev_err(hba->dev, "%s: Host init failed %d\n", __func__, err); | 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 | do { | 6983 | do { |
| 6970 | /* Reset the attached device */ | 6984 | /* Reset the attached device */ |
| 6971 | ufshcd_vops_device_reset(hba); | 6985 | ufshcd_device_reset(hba); |
| 6972 | 6986 | ||
| 6973 | err = ufshcd_host_reset_and_restore(hba); | 6987 | err = ufshcd_host_reset_and_restore(hba); |
| 6974 | } while (err && --retries); | 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 | int ret = 0; | 8060 | int ret = 0; |
| 8047 | 8061 | ||
| 8048 | if (!vreg || !vreg->enabled) | 8062 | if (!vreg || !vreg->enabled || vreg->always_on) |
| 8049 | goto out; | 8063 | goto out; |
| 8050 | 8064 | ||
| 8051 | ret = regulator_disable(vreg->reg); | 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 | * handling context. | 8428 | * handling context. |
| 8415 | */ | 8429 | */ |
| 8416 | hba->host->eh_noresume = 1; | 8430 | hba->host->eh_noresume = 1; |
| 8417 | if (hba->wlun_dev_clr_ua) { | 8431 | ufshcd_clear_ua_wluns(hba); |
| 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 | } | ||
| 8424 | 8432 | ||
| 8425 | cmd[4] = pwr_mode << 4; | 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 | if (!ret) | 8450 | if (!ret) |
| 8443 | hba->curr_dev_pwr_mode = pwr_mode; | 8451 | hba->curr_dev_pwr_mode = pwr_mode; |
| 8444 | out: | 8452 | |
| 8445 | scsi_device_put(sdp); | 8453 | scsi_device_put(sdp); |
| 8446 | hba->host->eh_noresume = 0; | 8454 | hba->host->eh_noresume = 0; |
| 8447 | return ret; | 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 | ufshcd_wb_need_flush(hba)); | 8693 | ufshcd_wb_need_flush(hba)); |
| 8686 | } | 8694 | } |
| 8687 | 8695 | ||
| 8696 | flush_work(&hba->eeh_work); | ||
| 8697 | |||
| 8688 | if (req_dev_pwr_mode != hba->curr_dev_pwr_mode) { | 8698 | if (req_dev_pwr_mode != hba->curr_dev_pwr_mode) { |
| 8689 | if (!ufshcd_is_runtime_pm(pm_op)) | 8699 | if (!ufshcd_is_runtime_pm(pm_op)) |
| 8690 | /* ensure that bkops is disabled */ | 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 | * In the case of DeepSleep, the device is expected to remain powered | 8711 | * In the case of DeepSleep, the device is expected to remain powered |
| 8704 | * with the link off, so do not check for bkops. | 8712 | * with the link off, so do not check for bkops. |
| @@ -8747,7 +8755,7 @@ set_link_active: · 42 unmodified lines | |||
| 8747 | * further below. | 8755 | * further below. |
| 8748 | */ | 8756 | */ |
| 8749 | if (ufshcd_is_ufs_dev_deepsleep(hba)) { | 8757 | if (ufshcd_is_ufs_dev_deepsleep(hba)) { |
| 8750 | ufshcd_vops_device_reset(hba); | 8758 | ufshcd_device_reset(hba); |
| 8751 | WARN_ON(!ufshcd_is_link_off(hba)); | 8759 | WARN_ON(!ufshcd_is_link_off(hba)); |
| 8752 | } | 8760 | } |
| 8753 | if (ufshcd_is_link_hibern8(hba) && !ufshcd_uic_hibern8_exit(hba)) | 8761 | if (ufshcd_is_link_hibern8(hba) && !ufshcd_uic_hibern8_exit(hba)) |
| @@ -8757,7 +8765,7 @@ set_link_active: · 3 unmodified lines | |||
| 8757 | set_dev_active: | 8765 | set_dev_active: |
| 8758 | /* Can also get here needing to exit DeepSleep */ | 8766 | /* Can also get here needing to exit DeepSleep */ |
| 8759 | if (ufshcd_is_ufs_dev_deepsleep(hba)) { | 8767 | if (ufshcd_is_ufs_dev_deepsleep(hba)) { |
| 8760 | ufshcd_vops_device_reset(hba); | 8768 | ufshcd_device_reset(hba); |
| 8761 | ufshcd_host_reset_and_restore(hba); | 8769 | ufshcd_host_reset_and_restore(hba); |
| 8762 | } | 8770 | } |
| 8763 | if (!ufshcd_set_dev_pwr_mode(hba, UFS_ACTIVE_PWR_MODE)) | 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 | if ((ufs_get_pm_lvl_to_dev_pwr_mode(hba->spm_lvl) == | 8933 | if ((ufs_get_pm_lvl_to_dev_pwr_mode(hba->spm_lvl) == |
| 8926 | hba->curr_dev_pwr_mode) && | 8934 | hba->curr_dev_pwr_mode) && |
| 8927 | (ufs_get_pm_lvl_to_link_pwr_state(hba->spm_lvl) == | 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 | goto out; | 8938 | goto out; |
| 8930 | 8939 | ||
| 8931 | if (pm_runtime_suspended(hba->dev)) { | 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 | /* Reset the attached device */ | 9364 | /* Reset the attached device */ |
| 9356 | ufshcd_vops_device_reset(hba); | 9365 | ufshcd_device_reset(hba); |
| 9357 | 9366 | ||
| 9358 | ufshcd_init_crypto(hba); | 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 | hba->vops->dbg_register_dump(hba); | 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) { | 1223 | if (hba->vops && hba->vops->device_reset) |
| 1224 | int err = hba->vops->device_reset(hba); | 1224 | return hba->vops->device_reset(hba); |
| 1225 | 1225 | ||
| 1226 | if (!err) | 1226 | return -EOPNOTSUPP; |
| 1227 | ufshcd_set_ufs_dev_active(hba); | ||
| 1228 | if (err != -EOPNOTSUPP) | ||
| 1229 | ufshcd_update_evt_hist(hba, UFS_EVT_DEV_RESET, err); | ||
| 1230 | } | ||
| 1231 | } | 1227 | } |
| 1232 | 1228 | ||
| 1233 | static inline void ufshcd_vops_config_scaling_param(struct ufs_hba *hba, | 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 | /* send the first byte */ | 190 | /* send the first byte */ |
| 191 | altera_spi_tx_word(hw); | 191 | altera_spi_tx_word(hw); |
| 192 | } else { | ||
| 193 | while (hw->count < hw->len) { | ||
| 194 | altera_spi_tx_word(hw); | ||
| 195 | 192 | ||
| 196 | for (;;) { | 193 | return 1; |
| 197 | altr_spi_readl(hw, ALTERA_SPI_STATUS, &val); | 194 | } |
| 198 | if (val & ALTERA_SPI_STATUS_RRDY_MSK) | 195 | |
| 199 | break; | 196 | while (hw->count < hw->len) { |
| 197 | altera_spi_tx_word(hw); | ||
| 200 | 198 | ||
| 201 | cpu_relax(); | 199 | for (;;) { |
| 202 | } | 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 | static irqreturn_t altera_spi_irq(int irq, void *dev) | 214 | static irqreturn_t altera_spi_irq(int irq, void *dev) |
| @@ -115,6 +115,7 @@ struct cdns_spi { · 114 unmodified lines | |||
| 115 | void __iomem *regs; | 115 | void __iomem *regs; |
| 116 | struct clk *ref_clk; | 116 | struct clk *ref_clk; |
| 117 | struct clk *pclk; | 117 | struct clk *pclk; |
| 118 | unsigned int clk_rate; | ||
| 118 | u32 speed_hz; | 119 | u32 speed_hz; |
| 119 | const u8 *txbuf; | 120 | const u8 *txbuf; |
| 120 | u8 *rxbuf; | 121 | u8 *rxbuf; |
| @@ -250,7 +251,7 @@ static void cdns_spi_config_clock_freq(struct spi_device *spi, · 129 unmodified lines | |||
| 250 | u32 ctrl_reg, baud_rate_val; | 251 | u32 ctrl_reg, baud_rate_val; |
| 251 | unsigned long frequency; | 252 | unsigned long frequency; |
| 252 | 253 | ||
| 253 | frequency = clk_get_rate(xspi->ref_clk); | 254 | frequency = xspi->clk_rate; |
| 254 | 255 | ||
| 255 | ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR); | 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 | master->auto_runtime_pm = true; | 559 | master->auto_runtime_pm = true; |
| 559 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | 560 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
| 560 | 561 | ||
| 562 | xspi->clk_rate = clk_get_rate(xspi->ref_clk); | ||
| 561 | /* Set to default valid value */ | 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 | xspi->speed_hz = master->max_speed_hz; | 565 | xspi->speed_hz = master->max_speed_hz; |
| 564 | 566 | ||
| 565 | master->bits_per_word_mask = SPI_BPW_MASK(8); | 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 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); | 116 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); |
| 117 | struct fsl_spi_platform_data *pdata; | 117 | struct fsl_spi_platform_data *pdata; |
| 118 | bool pol = spi->mode & SPI_CS_HIGH; | ||
| 119 | struct spi_mpc8xxx_cs *cs = spi->controller_state; | 118 | struct spi_mpc8xxx_cs *cs = spi->controller_state; |
| 120 | 119 | ||
| 121 | pdata = spi->dev.parent->parent->platform_data; | 120 | pdata = spi->dev.parent->parent->platform_data; |
| 122 | 121 | ||
| 123 | if (value == BITBANG_CS_INACTIVE) { | 122 | if (value == BITBANG_CS_INACTIVE) { |
| 124 | if (pdata->cs_control) | 123 | if (pdata->cs_control) |
| 125 | pdata->cs_control(spi, !pol); | 124 | pdata->cs_control(spi, false); |
| 126 | } | 125 | } |
| 127 | 126 | ||
| 128 | if (value == BITBANG_CS_ACTIVE) { | 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 | fsl_spi_change_mode(spi); | 133 | fsl_spi_change_mode(spi); |
| 135 | 134 | ||
| 136 | if (pdata->cs_control) | 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 | spinlock_t lock; | 83 | spinlock_t lock; |
| 84 | int irq; | 84 | int irq; |
| 85 | bool cs_flag; | 85 | bool cs_flag; |
| 86 | bool abort_failed; | ||
| 86 | }; | 87 | }; |
| 87 | 88 | ||
| 88 | static int get_spi_clk_cfg(unsigned int speed_hz, | 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 | spin_unlock_irq(&mas->lock); | 142 | spin_unlock_irq(&mas->lock); |
| 142 | 143 | ||
| 143 | time_left = wait_for_completion_timeout(&mas->abort_done, HZ); | 144 | time_left = wait_for_completion_timeout(&mas->abort_done, HZ); |
| 144 | if (!time_left) | 145 | if (!time_left) { |
| 145 | dev_err(mas->dev, "Failed to cancel/abort m_cmd\n"); | 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 | static void spi_geni_set_cs(struct spi_device *slv, bool set_flag) | 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 | if (set_flag == mas->cs_flag) | 200 | if (set_flag == mas->cs_flag) |
| 159 | return; | 201 | return; |
| 160 | 202 | ||
| 161 | mas->cs_flag = set_flag; | ||
| 162 | |||
| 163 | pm_runtime_get_sync(mas->dev); | 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 | spin_lock_irq(&mas->lock); | 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 | reinit_completion(&mas->cs_done); | 218 | reinit_completion(&mas->cs_done); |
| 166 | if (set_flag) | 219 | if (set_flag) |
| 167 | geni_se_setup_m_cmd(se, SPI_CS_ASSERT, 0); | 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 | spin_unlock_irq(&mas->lock); | 223 | spin_unlock_irq(&mas->lock); |
| 171 | 224 | ||
| 172 | time_left = wait_for_completion_timeout(&mas->cs_done, HZ); | 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 | handle_fifo_timeout(spi, NULL); | 228 | handle_fifo_timeout(spi, NULL); |
| 229 | } | ||
| 175 | 230 | ||
| 231 | exit: | ||
| 176 | pm_runtime_put(mas->dev); | 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 | int ret; | 336 | int ret; |
| 281 | struct spi_geni_master *mas = spi_master_get_devdata(spi); | 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 | ret = setup_fifo_params(spi_msg->spi, spi); | 342 | ret = setup_fifo_params(spi_msg->spi, spi); |
| 284 | if (ret) | 343 | if (ret) |
| 285 | dev_err(mas->dev, "Couldn't select mode %d\n", ret); | 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 | unsigned int bytes_per_fifo_word = geni_byte_per_fifo_word(mas); | 413 | unsigned int bytes_per_fifo_word = geni_byte_per_fifo_word(mas); |
| 355 | unsigned int i = 0; | 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 | max_bytes = (mas->tx_fifo_depth - mas->tx_wm) * bytes_per_fifo_word; | 422 | max_bytes = (mas->tx_fifo_depth - mas->tx_wm) * bytes_per_fifo_word; |
| 358 | if (mas->tx_rem_bytes < max_bytes) | 423 | if (mas->tx_rem_bytes < max_bytes) |
| 359 | max_bytes = mas->tx_rem_bytes; | 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 | if (rx_last_byte_valid && rx_last_byte_valid < 4) | 461 | if (rx_last_byte_valid && rx_last_byte_valid < 4) |
| 397 | rx_bytes -= bytes_per_fifo_word - rx_last_byte_valid; | 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 | if (mas->rx_rem_bytes < rx_bytes) | 472 | if (mas->rx_rem_bytes < rx_bytes) |
| 400 | rx_bytes = mas->rx_rem_bytes; | 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 | struct spi_geni_master *mas = spi_master_get_devdata(spi); | 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 | /* Terminate and return success for 0 byte length transfer */ | 574 | /* Terminate and return success for 0 byte length transfer */ |
| 499 | if (!xfer->len) | 575 | if (!xfer->len) |
| 500 | return 0; | 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 | /* align packet size with data registers access */ | 494 | /* align packet size with data registers access */ |
| 495 | if (spi->cur_bpw > 8) | 495 | if (spi->cur_bpw > 8) |
| 496 | fthlv -= (fthlv % 2); /* multiple of 2 */ | 496 | fthlv += (fthlv % 2) ? 1 : 0; |
| 497 | else | 497 | else |
| 498 | fthlv -= (fthlv % 4); /* multiple of 4 */ | 498 | fthlv += (fthlv % 4) ? (4 - (fthlv % 4)) : 0; |
| 499 | 499 | ||
| 500 | if (!fthlv) | 500 | if (!fthlv) |
| 501 | fthlv = 1; | 501 | fthlv = 1; |
| @@ -1108,6 +1108,7 @@ static int spi_transfer_wait(struct spi_controller *ctlr, · 1107 unmodified lines | |||
| 1108 | { | 1108 | { |
| 1109 | struct spi_statistics *statm = &ctlr->statistics; | 1109 | struct spi_statistics *statm = &ctlr->statistics; |
| 1110 | struct spi_statistics *stats = &msg->spi->statistics; | 1110 | struct spi_statistics *stats = &msg->spi->statistics; |
| 1111 | u32 speed_hz = xfer->speed_hz; | ||
| 1111 | unsigned long long ms; | 1112 | unsigned long long ms; |
| 1112 | 1113 | ||
| 1113 | if (spi_controller_is_slave(ctlr)) { | 1114 | if (spi_controller_is_slave(ctlr)) { |
| @@ -1116,8 +1117,11 @@ static int spi_transfer_wait(struct spi_controller *ctlr, · 2 unmodified lines | |||
| 1116 | return -EINTR; | 1117 | return -EINTR; |
| 1117 | } | 1118 | } |
| 1118 | } else { | 1119 | } else { |
| 1120 | if (!speed_hz) | ||
| 1121 | speed_hz = 100000; | ||
| 1122 | |||
| 1119 | ms = 8LL * 1000LL * xfer->len; | 1123 | ms = 8LL * 1000LL * xfer->len; |
| 1120 | do_div(ms, xfer->speed_hz); | 1124 | do_div(ms, speed_hz); |
| 1121 | ms += ms + 200; /* some tolerance */ | 1125 | ms += ms + 200; /* some tolerance */ |
| 1122 | 1126 | ||
| 1123 | if (ms > UINT_MAX) | 1127 | if (ms > UINT_MAX) |
| @@ -3378,8 +3382,9 @@ int spi_setup(struct spi_device *spi) · 2254 unmodified lines | |||
| 3378 | if (status) | 3382 | if (status) |
| 3379 | return status; | 3383 | return status; |
| 3380 | 3384 | ||
| 3381 | if (!spi->max_speed_hz || | 3385 | if (spi->controller->max_speed_hz && |
| 3382 | spi->max_speed_hz > spi->controller->max_speed_hz) | 3386 | (!spi->max_speed_hz || |
| 3387 | spi->max_speed_hz > spi->controller->max_speed_hz)) | ||
| 3383 | spi->max_speed_hz = spi->controller->max_speed_hz; | 3388 | spi->max_speed_hz = spi->controller->max_speed_hz; |
| 3384 | 3389 | ||
| 3385 | mutex_lock(&spi->controller->io_mutex); | 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 | v32.chanlist_len = cmd->chanlist_len; | 2987 | v32.chanlist_len = cmd->chanlist_len; |
| 2988 | v32.data = ptr_to_compat(cmd->data); | 2988 | v32.data = ptr_to_compat(cmd->data); |
| 2989 | v32.data_len = cmd->data_len; | 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 | /* Handle 32-bit COMEDI_CMD ioctl. */ | 2995 | /* Handle 32-bit COMEDI_CMD ioctl. */ |
| @@ -278,21 +278,24 @@ static int spmi_controller_probe(struct platform_device *pdev) · 277 unmodified lines | |||
| 278 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 278 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 279 | if (!iores) { | 279 | if (!iores) { |
| 280 | dev_err(&pdev->dev, "can not get resource!\n"); | 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 | spmi_controller->base = devm_ioremap(&pdev->dev, iores->start, | 285 | spmi_controller->base = devm_ioremap(&pdev->dev, iores->start, |
| 285 | resource_size(iores)); | 286 | resource_size(iores)); |
| 286 | if (!spmi_controller->base) { | 287 | if (!spmi_controller->base) { |
| 287 | dev_err(&pdev->dev, "can not remap base addr!\n"); | 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 | ret = of_property_read_u32(pdev->dev.of_node, "spmi-channel", | 293 | ret = of_property_read_u32(pdev->dev.of_node, "spmi-channel", |
| 292 | &spmi_controller->channel); | 294 | &spmi_controller->channel); |
| 293 | if (ret) { | 295 | if (ret) { |
| 294 | dev_err(&pdev->dev, "can not get channel\n"); | 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 | platform_set_drvdata(pdev, spmi_controller); | 301 | platform_set_drvdata(pdev, spmi_controller); |
| @@ -309,9 +312,15 @@ static int spmi_controller_probe(struct platform_device *pdev) · 10 unmodified lines | |||
| 309 | ctrl->write_cmd = spmi_write_cmd; | 312 | ctrl->write_cmd = spmi_write_cmd; |
| 310 | 313 | ||
| 311 | ret = spmi_controller_add(ctrl); | 314 | ret = spmi_controller_add(ctrl); |
| 312 | if (ret) | 315 | if (ret) { |
| 313 | dev_err(&pdev->dev, "spmi_add_controller failed with error %d!\n", 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 | return ret; | 324 | return ret; |
| 316 | } | 325 | } |
| 317 | 326 | ||
| @@ -320,7 +329,7 @@ static int spmi_del_controller(struct platform_device *pdev) · 2 unmodified lines | |||
| 320 | struct spmi_controller *ctrl = platform_get_drvdata(pdev); | 329 | struct spmi_controller *ctrl = platform_get_drvdata(pdev); |
| 321 | 330 | ||
| 322 | spmi_controller_remove(ctrl); | 331 | spmi_controller_remove(ctrl); |
| 323 | kfree(ctrl); | 332 | spmi_controller_put(ctrl); |
| 324 | return 0; | 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 | .def = 0, | 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 | static void atomisp_init_subdev_pipe(struct atomisp_sub_device *asd, | 1065 | static void atomisp_init_subdev_pipe(struct atomisp_sub_device *asd, |
| 1086 | struct atomisp_video_pipe *pipe, enum v4l2_buf_type buf_type) | 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 | ret = dma_async_device_register(dd); | 712 | ret = dma_async_device_register(dd); |
| 713 | if (ret) { | 713 | if (ret) { |
| 714 | dev_err(&pdev->dev, "failed to register dma device\n"); | 714 | dev_err(&pdev->dev, "failed to register dma device\n"); |
| 715 | return ret; | 715 | goto err_uninit_hsdma; |
| 716 | } | 716 | } |
| 717 | 717 | ||
| 718 | ret = of_dma_controller_register(pdev->dev.of_node, | 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 | err_unregister: | 729 | err_unregister: |
| 730 | dma_async_device_unregister(dd); | 730 | dma_async_device_unregister(dd); |
| 731 | err_uninit_hsdma: | ||
| 732 | mtk_hsdma_uninit(hsdma); | ||
| 731 | return ret; | 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 | return 0; | 46 | return 0; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | struct xcopy_dev_search_info { | 49 | /** |
| 50 | const unsigned char *dev_wwn; | 50 | * target_xcopy_locate_se_dev_e4_iter - compare XCOPY NAA device identifiers |
| 51 | struct se_device *found_dev; | 51 | * |
| 52 | }; | 52 | * @se_dev: device being considered for match |
| 53 | 53 | * @dev_wwn: XCOPY requested NAA dev_wwn | |
| 54 | * @return: 1 on match, 0 on no-match | ||
| 55 | */ | ||
| 54 | static int target_xcopy_locate_se_dev_e4_iter(struct se_device *se_dev, | 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 | unsigned char tmp_dev_wwn[XCOPY_NAA_IEEE_REGEX_LEN]; | 59 | unsigned char tmp_dev_wwn[XCOPY_NAA_IEEE_REGEX_LEN]; |
| 59 | int rc; | 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 | return 0; | 64 | return 0; |
| 65 | } | ||
| 63 | 66 | ||
| 64 | memset(&tmp_dev_wwn[0], 0, XCOPY_NAA_IEEE_REGEX_LEN); | 67 | memset(&tmp_dev_wwn[0], 0, XCOPY_NAA_IEEE_REGEX_LEN); |
| 65 | target_xcopy_gen_naa_ieee(se_dev, &tmp_dev_wwn[0]); | 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); | 70 | rc = memcmp(&tmp_dev_wwn[0], 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); | ||
| 75 | if (rc != 0) { | 71 | if (rc != 0) { |
| 76 | pr_err("configfs_depend_item attempt failed: %d for se_dev: %p\n", | 72 | pr_debug("XCOPY: skip non-matching: %*ph\n", |
| 77 | rc, se_dev); | 73 | XCOPY_NAA_IEEE_REGEX_LEN, tmp_dev_wwn); |
| 78 | return rc; | 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 | return 1; | 78 | return 1; |
| 84 | } | 79 | } |
| 85 | 80 | ||
| 86 | static int target_xcopy_locate_se_dev_e4(const unsigned char *dev_wwn, | 81 | static int target_xcopy_locate_se_dev_e4(struct se_session *sess, |
| 87 | struct se_device **found_dev) | 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; | 86 | struct se_dev_entry *deve; |
| 90 | int ret; | 87 | struct se_node_acl *nacl; |
| 91 | 88 | struct se_lun *this_lun = NULL; | |
| 92 | memset(&info, 0, sizeof(info)); | 89 | struct se_device *found_dev = NULL; |
| 93 | info.dev_wwn = dev_wwn; | 90 | |
| 94 | 91 | /* cmd with NULL sess indicates no associated $FABRIC_MOD */ | |
| 95 | ret = target_for_each_device(target_xcopy_locate_se_dev_e4_iter, &info); | 92 | if (!sess) |
| 96 | if (ret == 1) { | 93 | goto err_out; |
| 97 | *found_dev = info.found_dev; | 94 | |
| 98 | return 0; | 95 | pr_debug("XCOPY 0xe4: searching for: %*ph\n", |
| 99 | } else { | 96 | XCOPY_NAA_IEEE_REGEX_LEN, dev_wwn); |
| 100 | pr_debug_ratelimited("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n"); | 97 | |
| 101 | return -EINVAL; | 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 | static int target_xcopy_parse_tiddesc_e4(struct se_cmd *se_cmd, struct xcopy_op *xop, | 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 | switch (xop->op_origin) { | 270 | switch (xop->op_origin) { |
| 248 | case XCOL_SOURCE_RECV_OP: | 271 | case XCOL_SOURCE_RECV_OP: |
| 249 | rc = target_xcopy_locate_se_dev_e4(xop->dst_tid_wwn, | 272 | rc = target_xcopy_locate_se_dev_e4(se_cmd->se_sess, |
| 250 | &xop->dst_dev); | 273 | xop->dst_tid_wwn, |
| 274 | &xop->dst_dev, | ||
| 275 | &xop->remote_lun_ref); | ||
| 251 | break; | 276 | break; |
| 252 | case XCOL_DEST_RECV_OP: | 277 | case XCOL_DEST_RECV_OP: |
| 253 | rc = target_xcopy_locate_se_dev_e4(xop->src_tid_wwn, | 278 | rc = target_xcopy_locate_se_dev_e4(se_cmd->se_sess, |
| 254 | &xop->src_dev); | 279 | xop->src_tid_wwn, |
| 280 | &xop->src_dev, | ||
| 281 | &xop->remote_lun_ref); | ||
| 255 | break; | 282 | break; |
| 256 | default: | 283 | default: |
| 257 | pr_err("XCOPY CSCD descriptor IDs not found in CSCD list - " | 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 | static void xcopy_pt_undepend_remotedev(struct xcopy_op *xop) | 419 | static void xcopy_pt_undepend_remotedev(struct xcopy_op *xop) |
| 393 | { | 420 | { |
| 394 | struct se_device *remote_dev; | ||
| 395 | |||
| 396 | if (xop->op_origin == XCOL_SOURCE_RECV_OP) | 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 | else | 423 | else |
| 399 | remote_dev = xop->src_dev; | 424 | pr_debug("putting src lun_ref for %p\n", 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); | ||
| 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 | static void xcopy_pt_release_cmd(struct se_cmd *se_cmd) | 429 | static void xcopy_pt_release_cmd(struct se_cmd *se_cmd) |
| @@ -27,6 +27,7 @@ struct xcopy_op { · 26 unmodified lines | |||
| 27 | struct se_device *dst_dev; | 27 | struct se_device *dst_dev; |
| 28 | unsigned char dst_tid_wwn[XCOPY_NAA_IEEE_REGEX_LEN]; | 28 | unsigned char dst_tid_wwn[XCOPY_NAA_IEEE_REGEX_LEN]; |
| 29 | unsigned char local_dev_wwn[XCOPY_NAA_IEEE_REGEX_LEN]; | 29 | unsigned char local_dev_wwn[XCOPY_NAA_IEEE_REGEX_LEN]; |
| 30 | struct percpu_ref *remote_lun_ref; | ||
| 30 | 31 | ||
| 31 | sector_t src_lba; | 32 | sector_t src_lba; |
| 32 | sector_t dst_lba; | 33 | sector_t dst_lba; |
| @@ -401,6 +401,20 @@ config MIPS_EJTAG_FDC_KGDB_CHAN · 400 unmodified lines | |||
| 401 | help | 401 | help |
| 402 | FDC channel number to use for KGDB. | 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 | config TRACE_ROUTER | 418 | config TRACE_ROUTER |
| 405 | tristate "Trace data router for MIPI P1149.7 cJTAG standard" | 419 | tristate "Trace data router for MIPI P1149.7 cJTAG standard" |
| 406 | depends on TRACE_SINK | 420 | depends on TRACE_SINK |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | obj-$(CONFIG_TTY) += tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \ | 2 | obj-$(CONFIG_TTY) += tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \ |
| 3 | tty_buffer.o tty_port.o tty_mutex.o \ | 3 | tty_buffer.o tty_port.o tty_mutex.o \ |
| 4 | tty_ldsem.o tty_baudrate.o tty_jobctrl.o \ | 4 | tty_ldsem.o tty_baudrate.o tty_jobctrl.o \ |
| 5 | n_null.o ttynull.o | 5 | n_null.o |
| 6 | obj-$(CONFIG_LEGACY_PTYS) += pty.o | 6 | obj-$(CONFIG_LEGACY_PTYS) += pty.o |
| 7 | obj-$(CONFIG_UNIX98_PTYS) += pty.o | 7 | obj-$(CONFIG_UNIX98_PTYS) += pty.o |
| 8 | obj-$(CONFIG_AUDIT) += tty_audit.o | 8 | obj-$(CONFIG_AUDIT) += tty_audit.o |
| @@ -25,6 +25,7 @@ obj-$(CONFIG_ISI) += isicom.o · 16 unmodified lines | |||
| 25 | obj-$(CONFIG_MOXA_INTELLIO) += moxa.o | 25 | obj-$(CONFIG_MOXA_INTELLIO) += moxa.o |
| 26 | obj-$(CONFIG_MOXA_SMARTIO) += mxser.o | 26 | obj-$(CONFIG_MOXA_SMARTIO) += mxser.o |
| 27 | obj-$(CONFIG_NOZOMI) += nozomi.o | 27 | obj-$(CONFIG_NOZOMI) += nozomi.o |
| 28 | obj-$(CONFIG_NULL_TTY) += ttynull.o | ||
| 28 | obj-$(CONFIG_ROCKETPORT) += rocket.o | 29 | obj-$(CONFIG_ROCKETPORT) += rocket.o |
| 29 | obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o | 30 | obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o |
| 30 | obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o | 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 | /* Set up clock divider */ | 1000 | /* Set up clock divider */ |
| 1001 | ssp->clkin_rate = clk_get_rate(ssp->clk); | 1001 | ssp->clkin_rate = clk_get_rate(ssp->clk); |
| 1002 | ssp->baud_rate = SIFIVE_DEFAULT_BAUD_RATE; | 1002 | ssp->baud_rate = SIFIVE_DEFAULT_BAUD_RATE; |
| 1003 | ssp->port.uartclk = ssp->baud_rate * 16; | ||
| 1003 | __ssp_update_div(ssp); | 1004 | __ssp_update_div(ssp); |
| 1004 | 1005 | ||
| 1005 | platform_set_drvdata(pdev, ssp); | 1006 | platform_set_drvdata(pdev, ssp); |
| @@ -2,13 +2,6 @@ · 1 unmodified line | |||
| 2 | /* | 2 | /* |
| 3 | * Copyright (C) 2019 Axis Communications AB | 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 | * Based on ttyprintk.c: | 5 | * Based on ttyprintk.c: |
| 13 | * Copyright (C) 2010 Samo Pogacnik | 6 | * Copyright (C) 2010 Samo Pogacnik |
| 14 | */ | 7 | */ |
| @@ -66,17 +59,6 @@ static struct console ttynull_console = { · 51 unmodified lines | |||
| 66 | .device = ttynull_device, | 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 | static int __init ttynull_init(void) | 62 | static int __init ttynull_init(void) |
| 81 | { | 63 | { |
| 82 | struct tty_driver *driver; | 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 | misc_pdev = of_find_device_by_node(args.np); | 139 | misc_pdev = of_find_device_by_node(args.np); |
| 140 | of_node_put(args.np); | 140 | of_node_put(args.np); |
| 141 | 141 | ||
| 142 | if (!misc_pdev || !platform_get_drvdata(misc_pdev)) | 142 | if (!misc_pdev) |
| 143 | return ERR_PTR(-EPROBE_DEFER); | 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 | data->dev = &misc_pdev->dev; | 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 | { USB_DEVICE(0x04d8, 0xfd08), | 1895 | { USB_DEVICE(0x04d8, 0xfd08), |
| 1896 | .driver_info = IGNORE_DEVICE, | 1896 | .driver_info = IGNORE_DEVICE, |
| 1897 | }, | 1897 | }, |
| 1898 | |||
| 1899 | { USB_DEVICE(0x04d8, 0xf58b), | ||
| 1900 | .driver_info = IGNORE_DEVICE, | ||
| 1901 | }, | ||
| 1898 | #endif | 1902 | #endif |
| 1899 | 1903 | ||
| 1900 | /*Samsung phone in firmware update mode */ | 1904 | /*Samsung phone in firmware update mode */ |
| @@ -465,13 +465,23 @@ static int service_outstanding_interrupt(struct wdm_device *desc) · 464 unmodified lines | |||
| 465 | if (!desc->resp_count || !--desc->resp_count) | 465 | if (!desc->resp_count || !--desc->resp_count) |
| 466 | goto out; | 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 | set_bit(WDM_RESPONDING, &desc->flags); | 477 | set_bit(WDM_RESPONDING, &desc->flags); |
| 469 | spin_unlock_irq(&desc->iuspin); | 478 | spin_unlock_irq(&desc->iuspin); |
| 470 | rv = usb_submit_urb(desc->response, GFP_KERNEL); | 479 | rv = usb_submit_urb(desc->response, GFP_KERNEL); |
| 471 | spin_lock_irq(&desc->iuspin); | 480 | spin_lock_irq(&desc->iuspin); |
| 472 | if (rv) { | 481 | if (rv) { |
| 473 | dev_err(&desc->intf->dev, | 482 | if (!test_bit(WDM_DISCONNECTING, &desc->flags)) |
| 474 | "usb_submit_urb failed with result %d\n", rv); | 483 | dev_err(&desc->intf->dev, |
| 484 | "usb_submit_urb failed with result %d\n", rv); | ||
| 475 | 485 | ||
| 476 | /* make sure the next notification trigger a submit */ | 486 | /* make sure the next notification trigger a submit */ |
| 477 | clear_bit(WDM_RESPONDING, &desc->flags); | 487 | clear_bit(WDM_RESPONDING, &desc->flags); |
| @@ -1027,9 +1037,9 @@ static void wdm_disconnect(struct usb_interface *intf) · 549 unmodified lines | |||
| 1027 | wake_up_all(&desc->wait); | 1037 | wake_up_all(&desc->wait); |
| 1028 | mutex_lock(&desc->rlock); | 1038 | mutex_lock(&desc->rlock); |
| 1029 | mutex_lock(&desc->wlock); | 1039 | mutex_lock(&desc->wlock); |
| 1030 | kill_urbs(desc); | ||
| 1031 | cancel_work_sync(&desc->rxwork); | 1040 | cancel_work_sync(&desc->rxwork); |
| 1032 | cancel_work_sync(&desc->service_outs_intr); | 1041 | cancel_work_sync(&desc->service_outs_intr); |
| 1042 | kill_urbs(desc); | ||
| 1033 | mutex_unlock(&desc->wlock); | 1043 | mutex_unlock(&desc->wlock); |
| 1034 | mutex_unlock(&desc->rlock); | 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 | #define usblp_reset(usblp)\ | 274 | #define usblp_reset(usblp)\ |
| 275 | usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_TYPE_CLASS, USB_DIR_OUT, USB_RECIP_OTHER, 0, NULL, 0) | 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) \ | 277 | static int usblp_hp_channel_change_request(struct usblp *usblp, int channel, u8 *new_channel) |
| 278 | usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE, channel, buffer, 1) | 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 | * See the description for usblp_select_alts() below for the usage | 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 | urb->status = status; | 1649 | urb->status = status; |
| 1650 | /* | 1650 | /* |
| 1651 | * This function can be called in task context inside another remote | 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 | * recursion yet. Only collect coverage in softirq context for now. | 1653 | * recursion yet. Only collect coverage in softirq context for now. |
| 1654 | */ | 1654 | */ |
| 1655 | if (in_serving_softirq()) | 1655 | kcov_remote_start_usb_softirq((u64)urb->dev->bus->busnum); |
| 1656 | kcov_remote_start_usb((u64)urb->dev->bus->busnum); | ||
| 1657 | urb->complete(urb); | 1656 | urb->complete(urb); |
| 1658 | if (in_serving_softirq()) | 1657 | kcov_remote_stop_softirq(); |
| 1659 | kcov_remote_stop(); | ||
| 1660 | 1658 | ||
| 1661 | usb_anchor_resume_wakeups(anchor); | 1659 | usb_anchor_resume_wakeups(anchor); |
| 1662 | atomic_dec(&urb->use_count); | 1660 | atomic_dec(&urb->use_count); |
| @@ -285,6 +285,7 @@ · 284 unmodified lines | |||
| 285 | 285 | ||
| 286 | /* Global USB2 PHY Vendor Control Register */ | 286 | /* Global USB2 PHY Vendor Control Register */ |
| 287 | #define DWC3_GUSB2PHYACC_NEWREGREQ BIT(25) | 287 | #define DWC3_GUSB2PHYACC_NEWREGREQ BIT(25) |
| 288 | #define DWC3_GUSB2PHYACC_DONE BIT(24) | ||
| 288 | #define DWC3_GUSB2PHYACC_BUSY BIT(23) | 289 | #define DWC3_GUSB2PHYACC_BUSY BIT(23) |
| 289 | #define DWC3_GUSB2PHYACC_WRITE BIT(22) | 290 | #define DWC3_GUSB2PHYACC_WRITE BIT(22) |
| 290 | #define DWC3_GUSB2PHYACC_ADDR(n) (n << 16) | 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 | ret = priv->drvdata->setup_regmaps(priv, base); | 755 | ret = priv->drvdata->setup_regmaps(priv, base); |
| 756 | if (ret) | 756 | if (ret) |
| 757 | return ret; | 757 | goto err_disable_clks; |
| 758 | 758 | ||
| 759 | if (priv->vbus) { | 759 | if (priv->vbus) { |
| 760 | ret = regulator_enable(priv->vbus); | 760 | ret = regulator_enable(priv->vbus); |
| @@ -1763,6 +1763,8 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, · 1762 unmodified lines | |||
| 1763 | list_for_each_entry_safe(r, t, &dep->started_list, list) | 1763 | list_for_each_entry_safe(r, t, &dep->started_list, list) |
| 1764 | dwc3_gadget_move_cancelled_request(r); | 1764 | dwc3_gadget_move_cancelled_request(r); |
| 1765 | 1765 | ||
| 1766 | dep->flags &= ~DWC3_EP_WAIT_TRANSFER_COMPLETE; | ||
| 1767 | |||
| 1766 | goto out; | 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 | static void dwc3_gadget_disable_irq(struct dwc3 *dwc); | 2086 | static void dwc3_gadget_disable_irq(struct dwc3 *dwc); |
| 2085 | static void __dwc3_gadget_stop(struct dwc3 *dwc); | 2087 | static void __dwc3_gadget_stop(struct dwc3 *dwc); |
| 2088 | static int __dwc3_gadget_start(struct dwc3 *dwc); | ||
| 2086 | 2089 | ||
| 2087 | static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) | 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 | dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % | 2148 | dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % |
| 2146 | dwc->ev_buf->length; | 2149 | dwc->ev_buf->length; |
| 2147 | } | 2150 | } |
| 2151 | } else { | ||
| 2152 | __dwc3_gadget_start(dwc); | ||
| 2148 | } | 2153 | } |
| 2149 | 2154 | ||
| 2150 | ret = dwc3_gadget_run_stop(dwc, is_on, false); | 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 | dwc->gadget_driver = driver; | 2326 | dwc->gadget_driver = driver; |
| 2322 | |||
| 2323 | if (pm_runtime_active(dwc->dev)) | ||
| 2324 | __dwc3_gadget_start(dwc); | ||
| 2325 | |||
| 2326 | spin_unlock_irqrestore(&dwc->lock, flags); | 2327 | spin_unlock_irqrestore(&dwc->lock, flags); |
| 2327 | 2328 | ||
| 2328 | return 0; | 2329 | return 0; |
| @@ -2348,13 +2349,6 @@ static int dwc3_gadget_stop(struct usb_gadget *g) · 19 unmodified lines | |||
| 2348 | unsigned long flags; | 2349 | unsigned long flags; |
| 2349 | 2350 | ||
| 2350 | spin_lock_irqsave(&dwc->lock, flags); | 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 | dwc->gadget_driver = NULL; | 2352 | dwc->gadget_driver = NULL; |
| 2359 | spin_unlock_irqrestore(&dwc->lock, flags); | 2353 | spin_unlock_irqrestore(&dwc->lock, flags); |
| 2360 | 2354 | ||
| @@ -7,6 +7,8 @@ · 6 unmodified lines | |||
| 7 | * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com> | 7 | * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com> |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/delay.h> | ||
| 11 | #include <linux/time64.h> | ||
| 10 | #include <linux/ulpi/regs.h> | 12 | #include <linux/ulpi/regs.h> |
| 11 | 13 | ||
| 12 | #include "core.h" | 14 | #include "core.h" |
| @@ -17,14 +19,28 @@ · 4 unmodified lines | |||
| 17 | DWC3_GUSB2PHYACC_ADDR(ULPI_ACCESS_EXTENDED) | \ | 19 | DWC3_GUSB2PHYACC_ADDR(ULPI_ACCESS_EXTENDED) | \ |
| 18 | DWC3_GUSB2PHYACC_EXTEND_ADDR(a) : DWC3_GUSB2PHYACC_ADDR(a)) | 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 | u32 reg; | 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 | while (count--) { | 40 | while (count--) { |
| 41 | ndelay(ns); | ||
| 26 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0)); | 42 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0)); |
| 27 | if (!(reg & DWC3_GUSB2PHYACC_BUSY)) | 43 | if (reg & DWC3_GUSB2PHYACC_DONE) |
| 28 | return 0; | 44 | return 0; |
| 29 | cpu_relax(); | 45 | cpu_relax(); |
| 30 | } | 46 | } |
| @@ -38,16 +54,10 @@ static int dwc3_ulpi_read(struct device *dev, u8 addr) · 7 unmodified lines | |||
| 38 | u32 reg; | 54 | u32 reg; |
| 39 | int ret; | 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 | reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); | 57 | reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); |
| 48 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); | 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 | if (ret) | 61 | if (ret) |
| 52 | return ret; | 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 | struct dwc3 *dwc = dev_get_drvdata(dev); | 71 | struct dwc3 *dwc = dev_get_drvdata(dev); |
| 62 | u32 reg; | 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 | reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); | 74 | reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); |
| 71 | reg |= DWC3_GUSB2PHYACC_WRITE | val; | 75 | reg |= DWC3_GUSB2PHYACC_WRITE | val; |
| 72 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); | 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 | static const struct ulpi_ops dwc3_ulpi_ops = { | 81 | static const struct ulpi_ops dwc3_ulpi_ops = { |
| @@ -265,6 +265,7 @@ config USB_CONFIGFS_NCM · 264 unmodified lines | |||
| 265 | depends on NET | 265 | depends on NET |
| 266 | select USB_U_ETHER | 266 | select USB_U_ETHER |
| 267 | select USB_F_NCM | 267 | select USB_F_NCM |
| 268 | select CRC32 | ||
| 268 | help | 269 | help |
| 269 | NCM is an advanced protocol for Ethernet encapsulation, allows | 270 | NCM is an advanced protocol for Ethernet encapsulation, allows |
| 270 | grouping of several ethernet frames into one USB transfer and | 271 | grouping of several ethernet frames into one USB transfer and |
| @@ -314,6 +315,7 @@ config USB_CONFIGFS_EEM · 43 unmodified lines | |||
| 314 | depends on NET | 315 | depends on NET |
| 315 | select USB_U_ETHER | 316 | select USB_U_ETHER |
| 316 | select USB_F_EEM | 317 | select USB_F_EEM |
| 318 | select CRC32 | ||
| 317 | help | 319 | help |
| 318 | CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM | 320 | CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM |
| 319 | and therefore can be supported by more hardware. Technically ECM and | 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 | spin_lock_irqsave(&cdev->lock, flags); | 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 | status = usb_gadget_deactivate(cdev->gadget); | 397 | status = usb_gadget_deactivate(cdev->gadget); |
| 398 | spin_lock_irqsave(&cdev->lock, flags); | ||
| 399 | } | ||
| 397 | if (status == 0) | 400 | if (status == 0) |
| 398 | cdev->deactivations++; | 401 | cdev->deactivations++; |
| 399 | 402 | ||
| @@ -424,8 +427,11 @@ int usb_function_activate(struct usb_function *function) · 24 unmodified lines | |||
| 424 | status = -EINVAL; | 427 | status = -EINVAL; |
| 425 | else { | 428 | else { |
| 426 | cdev->deactivations--; | 429 | cdev->deactivations--; |
| 427 | if (cdev->deactivations == 0) | 430 | if (cdev->deactivations == 0) { |
| 431 | spin_unlock_irqrestore(&cdev->lock, flags); | ||
| 428 | status = usb_gadget_activate(cdev->gadget); | 432 | status = usb_gadget_activate(cdev->gadget); |
| 433 | spin_lock_irqsave(&cdev->lock, flags); | ||
| 434 | } | ||
| 429 | } | 435 | } |
| 430 | 436 | ||
| 431 | spin_unlock_irqrestore(&cdev->lock, flags); | 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 | static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page) | 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 | static int unregister_gadget(struct gadget_info *gi) | 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 | cfg = container_of(c, struct config_usb_cfg, c); | 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 | if (f->unbind) { | 1261 | if (f->unbind) { |
| 1255 | dev_dbg(&gi->cdev.gadget->dev, | 1262 | dev_dbg(&gi->cdev.gadget->dev, |
| 1256 | "unbind function '%s'/%p\n", | 1263 | "unbind function '%s'/%p\n", |
| @@ -1536,7 +1543,7 @@ static const struct usb_gadget_driver configfs_driver_template = { · 279 unmodified lines | |||
| 1536 | .suspend = configfs_composite_suspend, | 1543 | .suspend = configfs_composite_suspend, |
| 1537 | .resume = configfs_composite_resume, | 1544 | .resume = configfs_composite_resume, |
| 1538 | 1545 | ||
| 1539 | .max_speed = USB_SPEED_SUPER, | 1546 | .max_speed = USB_SPEED_SUPER_PLUS, |
| 1540 | .driver = { | 1547 | .driver = { |
| 1541 | .owner = THIS_MODULE, | 1548 | .owner = THIS_MODULE, |
| 1542 | .name = "configfs-gadget", | 1549 | .name = "configfs-gadget", |
| @@ -1576,7 +1583,7 @@ static struct config_group *gadgets_make( · 33 unmodified lines | |||
| 1576 | gi->composite.unbind = configfs_do_nothing; | 1583 | gi->composite.unbind = configfs_do_nothing; |
| 1577 | gi->composite.suspend = NULL; | 1584 | gi->composite.suspend = NULL; |
| 1578 | gi->composite.resume = NULL; | 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 | spin_lock_init(&gi->spinlock); | 1588 | spin_lock_init(&gi->spinlock); |
| 1582 | mutex_init(&gi->lock); | 1589 | mutex_init(&gi->lock); |
| @@ -1162,6 +1162,7 @@ fail_tx_reqs: · 1161 unmodified lines | |||
| 1162 | printer_req_free(dev->in_ep, req); | 1162 | printer_req_free(dev->in_ep, req); |
| 1163 | } | 1163 | } |
| 1164 | 1164 | ||
| 1165 | usb_free_all_descriptors(f); | ||
| 1165 | return ret; | 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 | .bEndpointAddress = USB_DIR_OUT, | 272 | .bEndpointAddress = USB_DIR_OUT, |
| 273 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, | 273 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, |
| 274 | .wMaxPacketSize = cpu_to_le16(1023), | 274 | /* .wMaxPacketSize = DYNAMIC */ |
| 275 | .bInterval = 1, | 275 | .bInterval = 1, |
| 276 | }; | 276 | }; |
| 277 | 277 | ||
| @@ -280,7 +280,7 @@ static struct usb_endpoint_descriptor hs_epout_desc = { · 2 unmodified lines | |||
| 280 | .bDescriptorType = USB_DT_ENDPOINT, | 280 | .bDescriptorType = USB_DT_ENDPOINT, |
| 281 | 281 | ||
| 282 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, | 282 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, |
| 283 | .wMaxPacketSize = cpu_to_le16(1024), | 283 | /* .wMaxPacketSize = DYNAMIC */ |
| 284 | .bInterval = 4, | 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 | .bEndpointAddress = USB_DIR_IN, | 349 | .bEndpointAddress = USB_DIR_IN, |
| 350 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, | 350 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, |
| 351 | .wMaxPacketSize = cpu_to_le16(1023), | 351 | /* .wMaxPacketSize = DYNAMIC */ |
| 352 | .bInterval = 1, | 352 | .bInterval = 1, |
| 353 | }; | 353 | }; |
| 354 | 354 | ||
| @@ -357,7 +357,7 @@ static struct usb_endpoint_descriptor hs_epin_desc = { · 2 unmodified lines | |||
| 357 | .bDescriptorType = USB_DT_ENDPOINT, | 357 | .bDescriptorType = USB_DT_ENDPOINT, |
| 358 | 358 | ||
| 359 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, | 359 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, |
| 360 | .wMaxPacketSize = cpu_to_le16(1024), | 360 | /* .wMaxPacketSize = DYNAMIC */ |
| 361 | .bInterval = 4, | 361 | .bInterval = 4, |
| 362 | }; | 362 | }; |
| 363 | 363 | ||
| @@ -444,12 +444,28 @@ struct cntrl_range_lay3 { · 80 unmodified lines | |||
| 444 | __le32 dRES; | 444 | __le32 dRES; |
| 445 | } __packed; | 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 | struct usb_endpoint_descriptor *ep_desc, | 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 | int chmask, srate, ssize; | 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 | if (is_playback) { | 470 | if (is_playback) { |
| 455 | chmask = uac2_opts->p_chmask; | 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 | ssize = uac2_opts->c_ssize; | 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 | DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))); | 481 | DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))); |
| 466 | ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_packet_size, | 482 | ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw, |
| 467 | le16_to_cpu(ep_desc->wMaxPacketSize))); | 483 | max_size_ep)); |
| 484 | |||
| 485 | return 0; | ||
| 468 | } | 486 | } |
| 469 | 487 | ||
| 470 | /* Use macro to overcome line length limitation */ | 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 | /* Calculate wMaxPacketSize according to audio bandwidth */ | 690 | /* Calculate wMaxPacketSize according to audio bandwidth */ |
| 673 | set_ep_max_packet_size(uac2_opts, &fs_epin_desc, 1000, true); | 691 | ret = set_ep_max_packet_size(uac2_opts, &fs_epin_desc, USB_SPEED_FULL, |
| 674 | set_ep_max_packet_size(uac2_opts, &fs_epout_desc, 1000, false); | 692 | true); |
| 675 | set_ep_max_packet_size(uac2_opts, &hs_epin_desc, 8000, true); | 693 | if (ret < 0) { |
| 676 | set_ep_max_packet_size(uac2_opts, &hs_epout_desc, 8000, false); | 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 | if (EPOUT_EN(uac2_opts)) { | 719 | if (EPOUT_EN(uac2_opts)) { |
| 679 | agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); | 720 | agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); |
| @@ -45,9 +45,10 @@ · 44 unmodified lines | |||
| 45 | #define UETH__VERSION "29-May-2008" | 45 | #define UETH__VERSION "29-May-2008" |
| 46 | 46 | ||
| 47 | /* Experiments show that both Linux and Windows hosts allow up to 16k | 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 | * blocks and still have efficient handling. */ | 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 | struct eth_dev { | 53 | struct eth_dev { |
| 53 | /* lock is held while accessing port_usb | 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 | /* MTU range: 14 - 15412 */ | 788 | /* MTU range: 14 - 15412 */ |
| 788 | net->min_mtu = ETH_HLEN; | 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 | dev->gadget = g; | 792 | dev->gadget = g; |
| 792 | SET_NETDEV_DEV(net, &g->dev); | 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 | /* MTU range: 14 - 15412 */ | 850 | /* MTU range: 14 - 15412 */ |
| 850 | net->min_mtu = ETH_HLEN; | 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 | return net; | 854 | return net; |
| 854 | } | 855 | } |
| @@ -200,8 +200,10 @@ static int acm_ms_bind(struct usb_composite_dev *cdev) · 199 unmodified lines | |||
| 200 | struct usb_descriptor_header *usb_desc; | 200 | struct usb_descriptor_header *usb_desc; |
| 201 | 201 | ||
| 202 | usb_desc = usb_otg_descriptor_alloc(gadget); | 202 | usb_desc = usb_otg_descriptor_alloc(gadget); |
| 203 | if (!usb_desc) | 203 | if (!usb_desc) { |
| 204 | status = -ENOMEM; | ||
| 204 | goto fail_string_ids; | 205 | goto fail_string_ids; |
| 206 | } | ||
| 205 | usb_otg_descriptor_init(gadget, usb_desc); | 207 | usb_otg_descriptor_init(gadget, usb_desc); |
| 206 | otg_desc[0] = usb_desc; | 208 | otg_desc[0] = usb_desc; |
| 207 | otg_desc[1] = NULL; | 209 | otg_desc[1] = NULL; |
| @@ -90,7 +90,7 @@ config USB_BCM63XX_UDC · 89 unmodified lines | |||
| 90 | 90 | ||
| 91 | config USB_FSL_USB2 | 91 | config USB_FSL_USB2 |
| 92 | tristate "Freescale Highspeed USB DR Peripheral Controller" | 92 | tristate "Freescale Highspeed USB DR Peripheral Controller" |
| 93 | depends on FSL_SOC || ARCH_MXC | 93 | depends on FSL_SOC |
| 94 | help | 94 | help |
| 95 | Some of Freescale PowerPC and i.MX processors have a High Speed | 95 | Some of Freescale PowerPC and i.MX processors have a High Speed |
| 96 | Dual-Role(DR) USB controller, which supports device mode. | 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 | obj-$(CONFIG_USB_BCM63XX_UDC) += bcm63xx_udc.o | 23 | obj-$(CONFIG_USB_BCM63XX_UDC) += bcm63xx_udc.o |
| 24 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o | 24 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o |
| 25 | fsl_usb2_udc-y := fsl_udc_core.o | 25 | fsl_usb2_udc-y := fsl_udc_core.o |
| 26 | fsl_usb2_udc-$(CONFIG_ARCH_MXC) += fsl_mxc_udc.o | ||
| 27 | obj-$(CONFIG_USB_TEGRA_XUDC) += tegra-xudc.o | 26 | obj-$(CONFIG_USB_TEGRA_XUDC) += tegra-xudc.o |
| 28 | obj-$(CONFIG_USB_M66592) += m66592-udc.o | 27 | obj-$(CONFIG_USB_M66592) += m66592-udc.o |
| 29 | obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o | 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 | * Enables the D+ (or potentially D-) pullup. The host will start | 660 | * Enables the D+ (or potentially D-) pullup. The host will start |
| 661 | * enumerating this gadget when the pullup is active and a VBUS session | 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 | 662 | * is active (the link is powered). |
| 663 | * usb_gadget_disconnect() has been used to disable it. | ||
| 664 | * | 663 | * |
| 665 | * Returns zero on success, else negative errno. | 664 | * Returns zero on success, else negative errno. |
| 666 | */ | 665 | */ |
| @@ -2118,9 +2118,21 @@ static int dummy_hub_control( · 2117 unmodified lines | |||
| 2118 | dum_hcd->port_status &= ~USB_PORT_STAT_POWER; | 2118 | dum_hcd->port_status &= ~USB_PORT_STAT_POWER; |
| 2119 | set_link_state(dum_hcd); | 2119 | set_link_state(dum_hcd); |
| 2120 | break; | 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 | dum_hcd->port_status &= ~(1 << wValue); | 2130 | dum_hcd->port_status &= ~(1 << wValue); |
| 2123 | set_link_state(dum_hcd); | 2131 | set_link_state(dum_hcd); |
| 2132 | break; | ||
| 2133 | default: | ||
| 2134 | /* Disallow INDICATOR and C_OVER_CURRENT */ | ||
| 2135 | goto error; | ||
| 2124 | } | 2136 | } |
| 2125 | break; | 2137 | break; |
| 2126 | case GetHubDescriptor: | 2138 | case GetHubDescriptor: |
| @@ -2281,18 +2293,17 @@ static int dummy_hub_control( · 154 unmodified lines | |||
| 2281 | */ | 2293 | */ |
| 2282 | dum_hcd->re_timeout = jiffies + msecs_to_jiffies(50); | 2294 | dum_hcd->re_timeout = jiffies + msecs_to_jiffies(50); |
| 2283 | fallthrough; | 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 | default: | 2304 | default: |
| 2285 | if (hcd->speed == HCD_USB3) { | 2305 | /* Disallow TEST, INDICATOR, and C_OVER_CURRENT */ |
| 2286 | if ((dum_hcd->port_status & | 2306 | goto error; |
| 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); | ||
| 2296 | } | 2307 | } |
| 2297 | break; | 2308 | break; |
| 2298 | case GetPortErrorCount: | 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 | unsigned long long timeout_ns; | 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 | /* Prevent U1 if service interval is shorter than U1 exit latency */ | 4778 | /* Prevent U1 if service interval is shorter than U1 exit latency */ |
| 4774 | if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { | 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 | dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n"); | 4781 | dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n"); |
| 4777 | return USB3_LPM_DISABLED; | 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 | /* The U1 timeout is encoded in 1us intervals. | 4786 | /* The U1 timeout is encoded in 1us intervals. |
| 4787 | * Don't return a timeout of zero, because that's USB3_LPM_DISABLED. | 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 | unsigned long long timeout_ns; | 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 | /* Prevent U2 if service interval is shorter than U2 exit latency */ | 4842 | /* Prevent U2 if service interval is shorter than U2 exit latency */ |
| 4838 | if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { | 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 | dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n"); | 4845 | dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n"); |
| 4841 | return USB3_LPM_DISABLED; | 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 | /* The U2 timeout is encoded in 256us intervals */ | 4850 | /* The U2 timeout is encoded in 256us intervals */ |
| 4851 | timeout_ns = DIV_ROUND_UP_ULL(timeout_ns, 256 * 1000); | 4851 | timeout_ns = DIV_ROUND_UP_ULL(timeout_ns, 256 * 1000); |
| 4852 | /* If the necessary timeout value is bigger than what we can set in the | 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 | timeout = schedule_timeout(YUREX_WRITE_TIMEOUT); | 496 | timeout = schedule_timeout(YUREX_WRITE_TIMEOUT); |
| 497 | finish_wait(&dev->waitq, &wait); | 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 | mutex_unlock(&dev->io_mutex); | 502 | mutex_unlock(&dev->io_mutex); |
| 500 | 503 | ||
| 501 | if (retval < 0) { | 504 | if (retval < 0) { |
| @@ -532,23 +532,29 @@ static int iuu_uart_flush(struct usb_serial_port *port) · 531 unmodified lines | |||
| 532 | struct device *dev = &port->dev; | 532 | struct device *dev = &port->dev; |
| 533 | int i; | 533 | int i; |
| 534 | int status; | 534 | int status; |
| 535 | u8 rxcmd = IUU_UART_RX; | 535 | u8 *rxcmd; |
| 536 | struct iuu_private *priv = usb_get_serial_port_data(port); | 536 | struct iuu_private *priv = usb_get_serial_port_data(port); |
| 537 | 537 | ||
| 538 | if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0) | 538 | if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0) |
| 539 | return -EIO; | 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 | for (i = 0; i < 2; i++) { | 547 | for (i = 0; i < 2; i++) { |
| 542 | status = bulk_immediate(port, &rxcmd, 1); | 548 | status = bulk_immediate(port, rxcmd, 1); |
| 543 | if (status != IUU_OPERATION_OK) { | 549 | if (status != IUU_OPERATION_OK) { |
| 544 | dev_dbg(dev, "%s - uart_flush_write error\n", __func__); | 550 | dev_dbg(dev, "%s - uart_flush_write error\n", __func__); |
| 545 | return status; | 551 | goto out_free; |
| 546 | } | 552 | } |
| 547 | 553 | ||
| 548 | status = read_immediate(port, &priv->len, 1); | 554 | status = read_immediate(port, &priv->len, 1); |
| 549 | if (status != IUU_OPERATION_OK) { | 555 | if (status != IUU_OPERATION_OK) { |
| 550 | dev_dbg(dev, "%s - uart_flush_read error\n", __func__); | 556 | dev_dbg(dev, "%s - uart_flush_read error\n", __func__); |
| 551 | return status; | 557 | goto out_free; |
| 552 | } | 558 | } |
| 553 | 559 | ||
| 554 | if (priv->len > 0) { | 560 | if (priv->len > 0) { |
| @@ -556,12 +562,16 @@ static int iuu_uart_flush(struct usb_serial_port *port) · 1 unmodified line | |||
| 556 | status = read_immediate(port, priv->buf, priv->len); | 562 | status = read_immediate(port, priv->buf, priv->len); |
| 557 | if (status != IUU_OPERATION_OK) { | 563 | if (status != IUU_OPERATION_OK) { |
| 558 | dev_dbg(dev, "%s - uart_flush_read error\n", __func__); | 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 | dev_dbg(dev, "%s - uart_flush_read OK!\n", __func__); | 569 | dev_dbg(dev, "%s - uart_flush_read OK!\n", __func__); |
| 564 | iuu_led(port, 0, 0xF000, 0, 0xFF); | 570 | iuu_led(port, 0, 0xF000, 0, 0xFF); |
| 571 | |||
| 572 | out_free: | ||
| 573 | kfree(rxcmd); | ||
| 574 | |||
| 565 | return status; | 575 | return status; |
| 566 | } | 576 | } |
| 567 | 577 | ||
| @@ -1117,6 +1117,8 @@ static const struct usb_device_id option_ids[] = { · 1116 unmodified lines | |||
| 1117 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), | 1117 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), |
| 1118 | .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, | 1118 | .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, |
| 1119 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, | 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 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) }, | 1122 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) }, |
| 1121 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, | 1123 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, |
| 1122 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10), | 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 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ | 2059 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ |
| 2058 | .driver_info = RSVD(6) }, | 2060 | .driver_info = RSVD(6) }, |
| 2059 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */ | 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 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ | 2063 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ |
| 2061 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ | 2064 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ |
| 2062 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ | 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 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 90 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 91 | US_FL_BROKEN_FUA), | 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 | /* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */ | 100 | /* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */ |
| 94 | UNUSUAL_DEV(0x154b, 0xf00d, 0x0000, 0x9999, | 101 | UNUSUAL_DEV(0x154b, 0xf00d, 0x0000, 0x9999, |
| 95 | "PNY", | 102 | "PNY", |
| @@ -20,6 +20,6 @@ config TYPEC_NVIDIA_ALTMODE · 19 unmodified lines | |||
| 20 | to enable support for VirtualLink devices with NVIDIA GPUs. | 20 | to enable support for VirtualLink devices with NVIDIA GPUs. |
| 21 | 21 | ||
| 22 | To compile this driver as a module, choose M here: the | 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 | endmenu | 25 | endmenu |
| @@ -766,6 +766,7 @@ int typec_partner_set_num_altmodes(struct typec_partner *partner, int num_altmod · 765 unmodified lines | |||
| 766 | return ret; | 766 | return ret; |
| 767 | 767 | ||
| 768 | sysfs_notify(&partner->dev.kobj, NULL, "number_of_alternate_modes"); | 768 | sysfs_notify(&partner->dev.kobj, NULL, "number_of_alternate_modes"); |
| 769 | kobject_uevent(&partner->dev.kobj, KOBJ_CHANGE); | ||
| 769 | 770 | ||
| 770 | return 0; | 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 | return ret; | 924 | return ret; |
| 924 | 925 | ||
| 925 | sysfs_notify(&plug->dev.kobj, NULL, "number_of_alternate_modes"); | 926 | sysfs_notify(&plug->dev.kobj, NULL, "number_of_alternate_modes"); |
| 927 | kobject_uevent(&plug->dev.kobj, KOBJ_CHANGE); | ||
| 926 | 928 | ||
| 927 | return 0; | 929 | return 0; |
| 928 | } | 930 | } |
| @@ -207,10 +207,21 @@ static int · 206 unmodified lines | |||
| 207 | pmc_usb_mux_dp_hpd(struct pmc_usb_port *port, struct typec_displayport_data *dp) | 207 | pmc_usb_mux_dp_hpd(struct pmc_usb_port *port, struct typec_displayport_data *dp) |
| 208 | { | 208 | { |
| 209 | u8 msg[2] = { }; | 209 | u8 msg[2] = { }; |
| 210 | int ret; | ||
| 210 | 211 | ||
| 211 | msg[0] = PMC_USB_DP_HPD; | 212 | msg[0] = PMC_USB_DP_HPD; |
| 212 | msg[0] |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT; | 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 | if (dp->status & DP_STATUS_IRQ_HPD) | 225 | if (dp->status & DP_STATUS_IRQ_HPD) |
| 215 | msg[1] = PMC_USB_DP_HPD_IRQ; | 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 | default: | 396 | default: |
| 397 | usbip_dbg_vhci_rh(" ClearPortFeature: default %x\n", | 397 | usbip_dbg_vhci_rh(" ClearPortFeature: default %x\n", |
| 398 | wValue); | 398 | wValue); |
| 399 | if (wValue >= 32) | ||
| 400 | goto error; | ||
| 399 | vhci_hcd->port_status[rhport] &= ~(1 << wValue); | 401 | vhci_hcd->port_status[rhport] &= ~(1 << wValue); |
| 400 | break; | 402 | break; |
| 401 | } | 403 | } |
| @@ -863,6 +863,7 @@ static void handle_tx_zerocopy(struct vhost_net *net, struct socket *sock) · 862 unmodified lines | |||
| 863 | size_t len, total_len = 0; | 863 | size_t len, total_len = 0; |
| 864 | int err; | 864 | int err; |
| 865 | struct vhost_net_ubuf_ref *ubufs; | 865 | struct vhost_net_ubuf_ref *ubufs; |
| 866 | struct ubuf_info *ubuf; | ||
| 866 | bool zcopy_used; | 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.